mirror of
https://github.com/Novaloop-AG/element-x-ios.git
synced 2026-11-04 01:20:12 +00:00
Render replies to gallery items (#5942)
This commit is contained in:
@@ -60,6 +60,8 @@ struct TimelineReplyView: View {
|
|||||||
case .image(let content): return content.imageInfo.source
|
case .image(let content): return content.imageInfo.source
|
||||||
case .video(let content): return content.videoInfo.source
|
case .video(let content): return content.videoInfo.source
|
||||||
case .voice(let content): return content.source
|
case .voice(let content): return content.source
|
||||||
|
// Only the first item is scanned as it's the only one the reply previews.
|
||||||
|
case .gallery(let content): return content.items.first?.mediaSource
|
||||||
default: return nil
|
default: return nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -75,6 +77,7 @@ struct TimelineReplyView: View {
|
|||||||
case .file(let content): return content.thumbnailSource
|
case .file(let content): return content.thumbnailSource
|
||||||
case .image(let content): return content.thumbnailInfo?.source
|
case .image(let content): return content.thumbnailInfo?.source
|
||||||
case .video(let content): return content.thumbnailInfo?.source
|
case .video(let content): return content.thumbnailInfo?.source
|
||||||
|
case .gallery(let content): return content.items.first?.thumbnailSource
|
||||||
default: return nil
|
default: return nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -130,12 +133,7 @@ struct TimelineReplyView: View {
|
|||||||
formattedBody: nil,
|
formattedBody: nil,
|
||||||
icon: .init(kind: .icon(\.locationPin)))
|
icon: .init(kind: .icon(\.locationPin)))
|
||||||
case .gallery(let content):
|
case .gallery(let content):
|
||||||
ReplyView(sender: sender,
|
GalleryReplyView(sender: sender, content: content)
|
||||||
plainBody: content.caption ?? content.body,
|
|
||||||
formattedBody: content.formattedCaption,
|
|
||||||
icon: content.items.first?.thumbnailSource.map { .init(kind: .mediaSource($0)) }
|
|
||||||
?? content.items.first?.mediaSource.map { .init(kind: .mediaSource($0)) }
|
|
||||||
?? .init(kind: .icon(\.attachment)))
|
|
||||||
}
|
}
|
||||||
case .poll(let question):
|
case .poll(let question):
|
||||||
ReplyView(sender: sender,
|
ReplyView(sender: sender,
|
||||||
@@ -159,6 +157,47 @@ struct TimelineReplyView: View {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// A gallery previews its first attachment as though it had been sent on its own, counting its
|
||||||
|
/// media when they're all images/videos and its attachments otherwise.
|
||||||
|
private struct GalleryReplyView: View {
|
||||||
|
let sender: TimelineItemSender
|
||||||
|
let content: GalleryRoomTimelineItemContent
|
||||||
|
|
||||||
|
private var caption: String? {
|
||||||
|
content.caption?.isBlank == false ? content.caption : nil
|
||||||
|
}
|
||||||
|
|
||||||
|
private var isMediaGallery: Bool {
|
||||||
|
content.items.allSatisfy { $0.isImage || $0.isVideo }
|
||||||
|
}
|
||||||
|
|
||||||
|
private var placeholder: String {
|
||||||
|
if isMediaGallery {
|
||||||
|
L10n.commonGalleryReplyMediaItems(content.items.count)
|
||||||
|
} else {
|
||||||
|
L10n.commonGalleryReplyAttachments(content.items.count)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private var icon: ReplyView.Icon? {
|
||||||
|
guard let item = content.items.first else { return nil }
|
||||||
|
|
||||||
|
return switch item {
|
||||||
|
case .image(_, let itemContent): .init(kind: .mediaSource(itemContent.thumbnailInfo?.source ?? itemContent.imageInfo.source))
|
||||||
|
case .video(_, let itemContent): itemContent.thumbnailInfo.map { .init(kind: .mediaSource($0.source)) }
|
||||||
|
case .audio: .init(kind: .icon(\.audio))
|
||||||
|
case .file, .other: .init(kind: .icon(\.attachment))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var body: some View {
|
||||||
|
ReplyView(sender: sender,
|
||||||
|
plainBody: caption ?? placeholder,
|
||||||
|
formattedBody: caption == nil ? nil : content.formattedCaption,
|
||||||
|
icon: icon)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private struct LoadingReplyView: View {
|
private struct LoadingReplyView: View {
|
||||||
var body: some View {
|
var body: some View {
|
||||||
ReplyView(sender: .init(id: "@alice:matrix.org"), plainBody: "Hello world", formattedBody: nil)
|
ReplyView(sender: .init(id: "@alice:matrix.org"), plainBody: "Hello world", formattedBody: nil)
|
||||||
@@ -402,6 +441,22 @@ struct TimelineReplyView_Previews: PreviewProvider, TestablePreview {
|
|||||||
timelineItemReplyDetails: .loaded(sender: .init(id: "", displayName: "Bob"),
|
timelineItemReplyDetails: .loaded(sender: .init(id: "", displayName: "Bob"),
|
||||||
eventID: "123",
|
eventID: "123",
|
||||||
eventContent: .message(.notice(.init(body: "", formattedBody: attributedStringWithEventOnRoomAliasMention))))),
|
eventContent: .message(.notice(.init(body: "", formattedBody: attributedStringWithEventOnRoomAliasMention))))),
|
||||||
|
TimelineReplyView(placement: .timeline,
|
||||||
|
timelineItemReplyDetails: .loaded(sender: .init(id: "", displayName: "Alice"),
|
||||||
|
eventID: "123",
|
||||||
|
eventContent: .message(.gallery(.init(body: "Gallery",
|
||||||
|
items: [.mockImage(index: 0),
|
||||||
|
.mockVideo(index: 1)]))))),
|
||||||
|
|
||||||
|
TimelineReplyView(placement: .timeline,
|
||||||
|
timelineItemReplyDetails: .loaded(sender: .init(id: "", displayName: "Alice"),
|
||||||
|
eventID: "123",
|
||||||
|
eventContent: .message(.gallery(.init(body: "Gallery",
|
||||||
|
caption: "A trip to remember 🌅",
|
||||||
|
items: [.mockImage(index: 0),
|
||||||
|
.mockVideo(index: 1),
|
||||||
|
.mockImage(index: 2)]))))),
|
||||||
|
|
||||||
TimelineReplyView(placement: .timeline,
|
TimelineReplyView(placement: .timeline,
|
||||||
timelineItemReplyDetails: .loaded(sender: .init(id: "", displayName: "Bob"),
|
timelineItemReplyDetails: .loaded(sender: .init(id: "", displayName: "Bob"),
|
||||||
eventID: "123",
|
eventID: "123",
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:90589b29a858d016ef4e9b22951f58b7cc1e91b101d1190891e557fa8ceb9547
|
oid sha256:48e2c170447a62a56f085126489c5ed819ee3377e2efc29502da4e7741bf3288
|
||||||
size 271039
|
size 330696
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:a119dbafa20c81937c68f725af6d4f0029647cd043264e6bf912cb0a10b0c0a7
|
oid sha256:b30099d8d6e152af0c21f127bafe0f67ecb6552c983cafcaf3a942ad306b2ea5
|
||||||
size 280754
|
size 345232
|
||||||
|
|||||||
+2
-2
@@ -1,3 +1,3 @@
|
|||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:0f4a10b76481e53d8f58810df4c2073f2ad71041712d10efbd2cff6cc67a548f
|
oid sha256:4ee06e1dc82d0d4261ddce83611fa44275e87bee6117a5e4e1474e9165af5df3
|
||||||
size 192308
|
size 242630
|
||||||
|
|||||||
+2
-2
@@ -1,3 +1,3 @@
|
|||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:fd00fd4e7354c7e840b67cce353ad4a157eea52060b80f7bac6e00aabf32936c
|
oid sha256:bc701056fe46fe1c5f3c12e9698a2f95b79057d931b29060603b13bd2233df46
|
||||||
size 192329
|
size 245641
|
||||||
|
|||||||
Reference in New Issue
Block a user