mirror of
https://github.com/Novaloop-AG/element-x-ios.git
synced 2026-11-02 12:07:55 +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 .video(let content): return content.videoInfo.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
|
||||
}
|
||||
}
|
||||
@@ -75,6 +77,7 @@ struct TimelineReplyView: View {
|
||||
case .file(let content): return content.thumbnailSource
|
||||
case .image(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
|
||||
}
|
||||
}
|
||||
@@ -130,12 +133,7 @@ struct TimelineReplyView: View {
|
||||
formattedBody: nil,
|
||||
icon: .init(kind: .icon(\.locationPin)))
|
||||
case .gallery(let content):
|
||||
ReplyView(sender: sender,
|
||||
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)))
|
||||
GalleryReplyView(sender: sender, content: content)
|
||||
}
|
||||
case .poll(let question):
|
||||
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 {
|
||||
var body: some View {
|
||||
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"),
|
||||
eventID: "123",
|
||||
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,
|
||||
timelineItemReplyDetails: .loaded(sender: .init(id: "", displayName: "Bob"),
|
||||
eventID: "123",
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:90589b29a858d016ef4e9b22951f58b7cc1e91b101d1190891e557fa8ceb9547
|
||||
size 271039
|
||||
oid sha256:48e2c170447a62a56f085126489c5ed819ee3377e2efc29502da4e7741bf3288
|
||||
size 330696
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:a119dbafa20c81937c68f725af6d4f0029647cd043264e6bf912cb0a10b0c0a7
|
||||
size 280754
|
||||
oid sha256:b30099d8d6e152af0c21f127bafe0f67ecb6552c983cafcaf3a942ad306b2ea5
|
||||
size 345232
|
||||
|
||||
+2
-2
@@ -1,3 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:0f4a10b76481e53d8f58810df4c2073f2ad71041712d10efbd2cff6cc67a548f
|
||||
size 192308
|
||||
oid sha256:4ee06e1dc82d0d4261ddce83611fa44275e87bee6117a5e4e1474e9165af5df3
|
||||
size 242630
|
||||
|
||||
+2
-2
@@ -1,3 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:fd00fd4e7354c7e840b67cce353ad4a157eea52060b80f7bac6e00aabf32936c
|
||||
size 192329
|
||||
oid sha256:bc701056fe46fe1c5f3c12e9698a2f95b79057d931b29060603b13bd2233df46
|
||||
size 245641
|
||||
|
||||
Reference in New Issue
Block a user