From c518a00d76435093d9bde196734f22a4c85b8935 Mon Sep 17 00:00:00 2001 From: Stefan Ceriu Date: Thu, 21 Sep 2023 13:28:08 +0300 Subject: [PATCH] Add support for replying to events different than room messages --- ElementX/Sources/Mocks/PollMock.swift | 1 + .../RoomScreen/RoomScreenViewModel.swift | 11 ++- .../View/Style/SwipeToReplyView.swift | 4 +- .../Style/TimelineItemBubbledStylerView.swift | 9 +++ .../Style/TimelineItemPlainStylerView.swift | 7 ++ .../View/Style/TimelineStyler.swift | 79 ++++++++++++++++--- .../TimelineReadReceiptsView.swift | 1 + .../View/Timeline/AudioRoomTimelineView.swift | 1 + .../View/Timeline/EmoteRoomTimelineView.swift | 1 + .../Timeline/EncryptedRoomTimelineView.swift | 1 + .../View/Timeline/FileRoomTimelineView.swift | 3 + .../View/Timeline/ImageRoomTimelineView.swift | 3 + .../Timeline/LocationRoomTimelineView.swift | 3 + .../Timeline/NoticeRoomTimelineView.swift | 1 + .../Timeline/ReadMarkerRoomTimelineView.swift | 2 + .../Timeline/RedactedRoomTimelineView.swift | 1 + .../View/Timeline/StateRoomTimelineView.swift | 1 + .../Timeline/StickerRoomTimelineView.swift | 3 + .../View/Timeline/TextRoomTimelineView.swift | 1 + .../UnsupportedRoomTimelineView.swift | 1 + .../View/Timeline/VideoRoomTimelineView.swift | 3 + .../Fixtures/RoomTimelineItemFixtures.swift | 8 ++ .../Services/Timeline/TimelineItemProxy.swift | 2 + .../EventBasedTimelineItemProtocol.swift | 1 + .../Messages/AudioRoomTimelineItem.swift | 1 + .../Messages/EmoteRoomTimelineItem.swift | 1 + .../Items/Messages/FileRoomTimelineItem.swift | 1 + .../Messages/ImageRoomTimelineItem.swift | 1 + .../Messages/LocationRoomTimelineItem.swift | 1 + .../Messages/NoticeRoomTimelineItem.swift | 1 + .../Items/Messages/TextRoomTimelineItem.swift | 1 + .../Messages/VideoRoomTimelineItem.swift | 1 + .../VoiceMessages/VoiceRoomTimelineView.swift | 1 + .../Messages/VoiceRoomTimelineItem.swift | 1 + .../Other/EncryptedRoomTimelineItem.swift | 1 + .../Items/Other/PollRoomTimelineItem.swift | 1 + .../Other/RedactedRoomTimelineItem.swift | 1 + .../Items/Other/StateRoomTimelineItem.swift | 1 + .../Items/Other/StickerRoomTimelineItem.swift | 1 + .../Other/UnsupportedRoomTimelineItem.swift | 1 + .../RoomTimelineItemFactory.swift | 69 ++++++++++------ 41 files changed, 199 insertions(+), 34 deletions(-) diff --git a/ElementX/Sources/Mocks/PollMock.swift b/ElementX/Sources/Mocks/PollMock.swift index f69c8f888..e194f218f 100644 --- a/ElementX/Sources/Mocks/PollMock.swift +++ b/ElementX/Sources/Mocks/PollMock.swift @@ -88,6 +88,7 @@ extension PollRoomTimelineItem { timestamp: "Now", isOutgoing: isOutgoing, isEditable: false, + canBeRepliedTo: true, sender: .init(id: "userID"), properties: .init()) } diff --git a/ElementX/Sources/Screens/RoomScreen/RoomScreenViewModel.swift b/ElementX/Sources/Screens/RoomScreen/RoomScreenViewModel.swift index 2ab81b5c7..137e883df 100644 --- a/ElementX/Sources/Screens/RoomScreen/RoomScreenViewModel.swift +++ b/ElementX/Sources/Screens/RoomScreen/RoomScreenViewModel.swift @@ -539,8 +539,15 @@ class RoomScreenViewModel: RoomScreenViewModelType, RoomScreenViewModelProtocol var actions: [TimelineItemMenuAction] = [] - if let messageItem = item as? EventBasedMessageTimelineItemProtocol, messageItem.isRemoteMessage { - actions.append(.reply(isThread: messageItem.isThreaded)) + if item.canBeRepliedTo { + if let messageItem = item as? EventBasedMessageTimelineItemProtocol { + actions.append(.reply(isThread: messageItem.isThreaded)) + } else { + actions.append(.reply(isThread: false)) + } + } + + if item.isRemoteMessage { actions.append(.forward(itemID: itemID)) } diff --git a/ElementX/Sources/Screens/RoomScreen/View/Style/SwipeToReplyView.swift b/ElementX/Sources/Screens/RoomScreen/View/Style/SwipeToReplyView.swift index b7973b65a..d514650f4 100644 --- a/ElementX/Sources/Screens/RoomScreen/View/Style/SwipeToReplyView.swift +++ b/ElementX/Sources/Screens/RoomScreen/View/Style/SwipeToReplyView.swift @@ -31,7 +31,9 @@ struct SwipeToReplyView_Previews: PreviewProvider, TestablePreview { timestamp: "", isOutgoing: true, isEditable: true, - isThreaded: false, sender: .init(id: ""), + canBeRepliedTo: true, + isThreaded: false, + sender: .init(id: ""), content: .init(body: "")) static var previews: some View { diff --git a/ElementX/Sources/Screens/RoomScreen/View/Style/TimelineItemBubbledStylerView.swift b/ElementX/Sources/Screens/RoomScreen/View/Style/TimelineItemBubbledStylerView.swift index fe8188cf8..c2fe4610c 100644 --- a/ElementX/Sources/Screens/RoomScreen/View/Style/TimelineItemBubbledStylerView.swift +++ b/ElementX/Sources/Screens/RoomScreen/View/Style/TimelineItemBubbledStylerView.swift @@ -421,6 +421,7 @@ struct TimelineItemBubbledStylerView_Previews: PreviewProvider, TestablePreview timestamp: "10:42", isOutgoing: true, isEditable: false, + canBeRepliedTo: true, isThreaded: true, sender: .init(id: "whoever"), content: .init(body: "A long message that should be on multiple lines."), @@ -431,6 +432,7 @@ struct TimelineItemBubbledStylerView_Previews: PreviewProvider, TestablePreview timestamp: "10:42", isOutgoing: true, isEditable: false, + canBeRepliedTo: true, isThreaded: true, sender: .init(id: ""), content: .init(body: "audio.ogg", @@ -445,6 +447,7 @@ struct TimelineItemBubbledStylerView_Previews: PreviewProvider, TestablePreview timestamp: "10:42", isOutgoing: false, isEditable: false, + canBeRepliedTo: true, isThreaded: true, sender: .init(id: ""), content: .init(body: "File", @@ -457,6 +460,7 @@ struct TimelineItemBubbledStylerView_Previews: PreviewProvider, TestablePreview timestamp: "10:42", isOutgoing: true, isEditable: true, + canBeRepliedTo: true, isThreaded: true, sender: .init(id: ""), content: .init(body: "Some image", source: MediaSourceProxy(url: .picturesDirectory, mimeType: "image/png"), thumbnailSource: nil), @@ -466,6 +470,7 @@ struct TimelineItemBubbledStylerView_Previews: PreviewProvider, TestablePreview timestamp: "Now", isOutgoing: false, isEditable: false, + canBeRepliedTo: true, isThreaded: true, sender: .init(id: "Bob"), content: .init(body: "Fallback geo uri description", @@ -478,6 +483,7 @@ struct TimelineItemBubbledStylerView_Previews: PreviewProvider, TestablePreview timestamp: "Now", isOutgoing: false, isEditable: false, + canBeRepliedTo: true, isThreaded: true, sender: .init(id: "Bob"), content: .init(body: "Fallback geo uri description", @@ -489,6 +495,7 @@ struct TimelineItemBubbledStylerView_Previews: PreviewProvider, TestablePreview timestamp: "10:42", isOutgoing: true, isEditable: false, + canBeRepliedTo: true, isThreaded: true, sender: .init(id: ""), content: .init(body: "audio.ogg", @@ -523,6 +530,7 @@ struct TimelineItemBubbledStylerView_Previews: PreviewProvider, TestablePreview timestamp: "10:42", isOutgoing: true, isEditable: false, + canBeRepliedTo: true, isThreaded: false, sender: .init(id: "whoever"), content: .init(body: "A long message that should be on multiple lines."), @@ -533,6 +541,7 @@ struct TimelineItemBubbledStylerView_Previews: PreviewProvider, TestablePreview timestamp: "10:42", isOutgoing: true, isEditable: false, + canBeRepliedTo: true, isThreaded: false, sender: .init(id: "whoever"), content: .init(body: "Short message"), diff --git a/ElementX/Sources/Screens/RoomScreen/View/Style/TimelineItemPlainStylerView.swift b/ElementX/Sources/Screens/RoomScreen/View/Style/TimelineItemPlainStylerView.swift index 0917cba86..d5255f0df 100644 --- a/ElementX/Sources/Screens/RoomScreen/View/Style/TimelineItemPlainStylerView.swift +++ b/ElementX/Sources/Screens/RoomScreen/View/Style/TimelineItemPlainStylerView.swift @@ -150,6 +150,7 @@ struct TimelineItemPlainStylerView_Previews: PreviewProvider, TestablePreview { timestamp: "10:42", isOutgoing: true, isEditable: false, + canBeRepliedTo: true, isThreaded: true, sender: .init(id: "whoever"), content: .init(body: "A long message that should be on multiple lines."), @@ -160,6 +161,7 @@ struct TimelineItemPlainStylerView_Previews: PreviewProvider, TestablePreview { timestamp: "10:42", isOutgoing: true, isEditable: false, + canBeRepliedTo: true, isThreaded: true, sender: .init(id: ""), content: .init(body: "audio.ogg", @@ -173,6 +175,7 @@ struct TimelineItemPlainStylerView_Previews: PreviewProvider, TestablePreview { timestamp: "10:42", isOutgoing: false, isEditable: false, + canBeRepliedTo: true, isThreaded: true, sender: .init(id: ""), content: .init(body: "File", @@ -185,6 +188,7 @@ struct TimelineItemPlainStylerView_Previews: PreviewProvider, TestablePreview { timestamp: "10:42", isOutgoing: true, isEditable: true, + canBeRepliedTo: true, isThreaded: true, sender: .init(id: ""), content: .init(body: "Some image", source: MediaSourceProxy(url: .picturesDirectory, mimeType: "image/png"), thumbnailSource: nil), @@ -194,6 +198,7 @@ struct TimelineItemPlainStylerView_Previews: PreviewProvider, TestablePreview { timestamp: "Now", isOutgoing: false, isEditable: false, + canBeRepliedTo: true, isThreaded: true, sender: .init(id: "Bob"), content: .init(body: "Fallback geo uri description", @@ -206,6 +211,7 @@ struct TimelineItemPlainStylerView_Previews: PreviewProvider, TestablePreview { timestamp: "Now", isOutgoing: false, isEditable: false, + canBeRepliedTo: true, isThreaded: true, sender: .init(id: "Bob"), content: .init(body: "Fallback geo uri description", @@ -216,6 +222,7 @@ struct TimelineItemPlainStylerView_Previews: PreviewProvider, TestablePreview { timestamp: "10:42", isOutgoing: true, isEditable: false, + canBeRepliedTo: true, isThreaded: true, sender: .init(id: ""), content: .init(body: "audio.ogg", diff --git a/ElementX/Sources/Screens/RoomScreen/View/Style/TimelineStyler.swift b/ElementX/Sources/Screens/RoomScreen/View/Style/TimelineStyler.swift index 218d1c5f1..7abb9eb28 100644 --- a/ElementX/Sources/Screens/RoomScreen/View/Style/TimelineStyler.swift +++ b/ElementX/Sources/Screens/RoomScreen/View/Style/TimelineStyler.swift @@ -38,7 +38,14 @@ struct TimelineStyler: View { struct TimelineItemStyler_Previews: PreviewProvider, TestablePreview { static let viewModel = RoomScreenViewModel.mock - static let base = TextRoomTimelineItem(id: .random, timestamp: "Now", isOutgoing: true, isEditable: false, isThreaded: false, sender: .test, content: .init(body: "Test")) + static let base = TextRoomTimelineItem(id: .random, + timestamp: "Now", + isOutgoing: true, + isEditable: false, + canBeRepliedTo: true, + isThreaded: false, + sender: .test, + content: .init(body: "Test")) static let sentNonLast: TextRoomTimelineItem = { var result = base @@ -54,7 +61,14 @@ struct TimelineItemStyler_Previews: PreviewProvider, TestablePreview { static let sendingLast: TextRoomTimelineItem = { let id = viewModel.state.timelineViewState.timelineIDs.last ?? UUID().uuidString - var result = TextRoomTimelineItem(id: .init(timelineID: id), timestamp: "Now", isOutgoing: true, isEditable: false, isThreaded: false, sender: .test, content: .init(body: "Test")) + var result = TextRoomTimelineItem(id: .init(timelineID: id), + timestamp: "Now", + isOutgoing: true, + isEditable: false, + canBeRepliedTo: true, + isThreaded: false, + sender: .test, + content: .init(body: "Test")) result.properties.deliveryStatus = .sending return result }() @@ -67,21 +81,68 @@ struct TimelineItemStyler_Previews: PreviewProvider, TestablePreview { static let sentLast: TextRoomTimelineItem = { let id = viewModel.state.timelineViewState.timelineIDs.last ?? UUID().uuidString - let result = TextRoomTimelineItem(id: .init(timelineID: id), timestamp: "Now", isOutgoing: true, isEditable: false, isThreaded: false, sender: .test, content: .init(body: "Test")) + let result = TextRoomTimelineItem(id: .init(timelineID: id), + timestamp: "Now", + isOutgoing: true, + isEditable: false, + canBeRepliedTo: true, + isThreaded: false, + sender: .test, + content: .init(body: "Test")) return result }() - static let ltrString = TextRoomTimelineItem(id: .random, timestamp: "Now", isOutgoing: true, isEditable: false, isThreaded: false, sender: .test, content: .init(body: "house!")) + static let ltrString = TextRoomTimelineItem(id: .random, + timestamp: "Now", + isOutgoing: true, + isEditable: false, + canBeRepliedTo: true, + isThreaded: false, + sender: .test, content: .init(body: "house!")) - static let rtlString = TextRoomTimelineItem(id: .random, timestamp: "Now", isOutgoing: true, isEditable: false, isThreaded: false, sender: .test, content: .init(body: "באמת!")) + static let rtlString = TextRoomTimelineItem(id: .random, + timestamp: "Now", + isOutgoing: true, + isEditable: false, + canBeRepliedTo: true, + isThreaded: false, + sender: .test, content: .init(body: "באמת!")) - static let ltrStringThatContainsRtl = TextRoomTimelineItem(id: .random, timestamp: "Now", isOutgoing: true, isEditable: false, isThreaded: false, sender: .test, content: .init(body: "house! -- באמת‏! -- house!")) + static let ltrStringThatContainsRtl = TextRoomTimelineItem(id: .random, + timestamp: "Now", + isOutgoing: true, + isEditable: false, + canBeRepliedTo: true, + isThreaded: false, + sender: .test, + content: .init(body: "house! -- באמת‏! -- house!")) - static let rtlStringThatContainsLtr = TextRoomTimelineItem(id: .random, timestamp: "Now", isOutgoing: true, isEditable: false, isThreaded: false, sender: .test, content: .init(body: "באמת‏! -- house! -- באמת!")) + static let rtlStringThatContainsLtr = TextRoomTimelineItem(id: .random, + timestamp: "Now", + isOutgoing: true, + isEditable: false, + canBeRepliedTo: true, + isThreaded: false, + sender: .test, + content: .init(body: "באמת‏! -- house! -- באמת!")) - static let ltrStringThatFinishesInRtl = TextRoomTimelineItem(id: .random, timestamp: "Now", isOutgoing: true, isEditable: false, isThreaded: false, sender: .test, content: .init(body: "house! -- באמת!")) + static let ltrStringThatFinishesInRtl = TextRoomTimelineItem(id: .random, + timestamp: "Now", + isOutgoing: true, + isEditable: false, + canBeRepliedTo: true, + isThreaded: false, + sender: .test, + content: .init(body: "house! -- באמת!")) - static let rtlStringThatFinishesInLtr = TextRoomTimelineItem(id: .random, timestamp: "Now", isOutgoing: true, isEditable: false, isThreaded: false, sender: .test, content: .init(body: "באמת‏! -- house!")) + static let rtlStringThatFinishesInLtr = TextRoomTimelineItem(id: .random, + timestamp: "Now", + isOutgoing: true, + isEditable: false, + canBeRepliedTo: true, + isThreaded: false, + sender: .test, + content: .init(body: "באמת‏! -- house!")) static var testView: some View { VStack { diff --git a/ElementX/Sources/Screens/RoomScreen/View/Supplementary/TimelineReadReceiptsView.swift b/ElementX/Sources/Screens/RoomScreen/View/Supplementary/TimelineReadReceiptsView.swift index eda73de83..666472109 100644 --- a/ElementX/Sources/Screens/RoomScreen/View/Supplementary/TimelineReadReceiptsView.swift +++ b/ElementX/Sources/Screens/RoomScreen/View/Supplementary/TimelineReadReceiptsView.swift @@ -82,6 +82,7 @@ struct TimelineReadReceiptsView_Previews: PreviewProvider, TestablePreview { timestamp: "Now", isOutgoing: true, isEditable: false, + canBeRepliedTo: true, isThreaded: false, sender: .init(id: UUID().uuidString), content: .init(body: "Test"), properties: .init(orderedReadReceipts: receipts)) diff --git a/ElementX/Sources/Screens/RoomScreen/View/Timeline/AudioRoomTimelineView.swift b/ElementX/Sources/Screens/RoomScreen/View/Timeline/AudioRoomTimelineView.swift index 9cf6d2f14..18494038d 100644 --- a/ElementX/Sources/Screens/RoomScreen/View/Timeline/AudioRoomTimelineView.swift +++ b/ElementX/Sources/Screens/RoomScreen/View/Timeline/AudioRoomTimelineView.swift @@ -50,6 +50,7 @@ struct AudioRoomTimelineView_Previews: PreviewProvider, TestablePreview { timestamp: "Now", isOutgoing: false, isEditable: false, + canBeRepliedTo: true, isThreaded: false, sender: .init(id: "Bob"), content: .init(body: "audio.ogg", duration: 300, waveform: nil, source: nil, contentType: nil))) diff --git a/ElementX/Sources/Screens/RoomScreen/View/Timeline/EmoteRoomTimelineView.swift b/ElementX/Sources/Screens/RoomScreen/View/Timeline/EmoteRoomTimelineView.swift index 4261124a8..9a9d5c3ba 100644 --- a/ElementX/Sources/Screens/RoomScreen/View/Timeline/EmoteRoomTimelineView.swift +++ b/ElementX/Sources/Screens/RoomScreen/View/Timeline/EmoteRoomTimelineView.swift @@ -59,6 +59,7 @@ struct EmoteRoomTimelineView_Previews: PreviewProvider, TestablePreview { timestamp: timestamp, isOutgoing: false, isEditable: false, + canBeRepliedTo: true, isThreaded: false, sender: .init(id: senderId), content: .init(body: text)) diff --git a/ElementX/Sources/Screens/RoomScreen/View/Timeline/EncryptedRoomTimelineView.swift b/ElementX/Sources/Screens/RoomScreen/View/Timeline/EncryptedRoomTimelineView.swift index f7af23609..5b3cc1144 100644 --- a/ElementX/Sources/Screens/RoomScreen/View/Timeline/EncryptedRoomTimelineView.swift +++ b/ElementX/Sources/Screens/RoomScreen/View/Timeline/EncryptedRoomTimelineView.swift @@ -78,6 +78,7 @@ struct EncryptedRoomTimelineView_Previews: PreviewProvider, TestablePreview { timestamp: timestamp, isOutgoing: isOutgoing, isEditable: false, + canBeRepliedTo: false, sender: .init(id: senderId)) } } diff --git a/ElementX/Sources/Screens/RoomScreen/View/Timeline/FileRoomTimelineView.swift b/ElementX/Sources/Screens/RoomScreen/View/Timeline/FileRoomTimelineView.swift index a651838c8..f0ad65268 100644 --- a/ElementX/Sources/Screens/RoomScreen/View/Timeline/FileRoomTimelineView.swift +++ b/ElementX/Sources/Screens/RoomScreen/View/Timeline/FileRoomTimelineView.swift @@ -51,6 +51,7 @@ struct FileRoomTimelineView_Previews: PreviewProvider, TestablePreview { timestamp: "Now", isOutgoing: false, isEditable: false, + canBeRepliedTo: true, isThreaded: false, sender: .init(id: "Bob"), content: .init(body: "document.pdf", source: nil, thumbnailSource: nil, contentType: nil))) @@ -59,6 +60,7 @@ struct FileRoomTimelineView_Previews: PreviewProvider, TestablePreview { timestamp: "Now", isOutgoing: false, isEditable: false, + canBeRepliedTo: true, isThreaded: false, sender: .init(id: "Bob"), content: .init(body: "document.docx", source: nil, thumbnailSource: nil, contentType: nil))) @@ -67,6 +69,7 @@ struct FileRoomTimelineView_Previews: PreviewProvider, TestablePreview { timestamp: "Now", isOutgoing: false, isEditable: false, + canBeRepliedTo: true, isThreaded: false, sender: .init(id: "Bob"), content: .init(body: "document.txt", source: nil, thumbnailSource: nil, contentType: nil))) diff --git a/ElementX/Sources/Screens/RoomScreen/View/Timeline/ImageRoomTimelineView.swift b/ElementX/Sources/Screens/RoomScreen/View/Timeline/ImageRoomTimelineView.swift index 543810e1d..7bf5c43ca 100644 --- a/ElementX/Sources/Screens/RoomScreen/View/Timeline/ImageRoomTimelineView.swift +++ b/ElementX/Sources/Screens/RoomScreen/View/Timeline/ImageRoomTimelineView.swift @@ -72,6 +72,7 @@ struct ImageRoomTimelineView_Previews: PreviewProvider, TestablePreview { timestamp: "Now", isOutgoing: false, isEditable: false, + canBeRepliedTo: true, isThreaded: false, sender: .init(id: "Bob"), content: .init(body: "Some image", source: MediaSourceProxy(url: .picturesDirectory, mimeType: "image/png"), thumbnailSource: nil))) @@ -80,6 +81,7 @@ struct ImageRoomTimelineView_Previews: PreviewProvider, TestablePreview { timestamp: "Now", isOutgoing: false, isEditable: false, + canBeRepliedTo: true, isThreaded: false, sender: .init(id: "Bob"), content: .init(body: "Some other image", source: MediaSourceProxy(url: .picturesDirectory, mimeType: "image/png"), thumbnailSource: nil))) @@ -88,6 +90,7 @@ struct ImageRoomTimelineView_Previews: PreviewProvider, TestablePreview { timestamp: "Now", isOutgoing: false, isEditable: false, + canBeRepliedTo: true, isThreaded: false, sender: .init(id: "Bob"), content: .init(body: "Blurhashed image", diff --git a/ElementX/Sources/Screens/RoomScreen/View/Timeline/LocationRoomTimelineView.swift b/ElementX/Sources/Screens/RoomScreen/View/Timeline/LocationRoomTimelineView.swift index ca9a10f27..7191596ec 100644 --- a/ElementX/Sources/Screens/RoomScreen/View/Timeline/LocationRoomTimelineView.swift +++ b/ElementX/Sources/Screens/RoomScreen/View/Timeline/LocationRoomTimelineView.swift @@ -112,6 +112,7 @@ struct LocationRoomTimelineView_Previews: PreviewProvider, TestablePreview { timestamp: "Now", isOutgoing: false, isEditable: false, + canBeRepliedTo: true, isThreaded: false, sender: .init(id: "Bob"), content: .init(body: "Fallback geo uri description"))) @@ -120,6 +121,7 @@ struct LocationRoomTimelineView_Previews: PreviewProvider, TestablePreview { timestamp: "Now", isOutgoing: false, isEditable: false, + canBeRepliedTo: true, isThreaded: false, sender: .init(id: "Bob"), content: .init(body: "Fallback geo uri description", @@ -128,6 +130,7 @@ struct LocationRoomTimelineView_Previews: PreviewProvider, TestablePreview { timestamp: "Now", isOutgoing: false, isEditable: false, + canBeRepliedTo: true, isThreaded: true, sender: .init(id: "Bob"), content: .init(body: "Fallback geo uri description", diff --git a/ElementX/Sources/Screens/RoomScreen/View/Timeline/NoticeRoomTimelineView.swift b/ElementX/Sources/Screens/RoomScreen/View/Timeline/NoticeRoomTimelineView.swift index cf23b01d2..d72aa7094 100644 --- a/ElementX/Sources/Screens/RoomScreen/View/Timeline/NoticeRoomTimelineView.swift +++ b/ElementX/Sources/Screens/RoomScreen/View/Timeline/NoticeRoomTimelineView.swift @@ -70,6 +70,7 @@ struct NoticeRoomTimelineView_Previews: PreviewProvider, TestablePreview { timestamp: timestamp, isOutgoing: false, isEditable: false, + canBeRepliedTo: true, isThreaded: false, sender: .init(id: senderId), content: .init(body: text)) diff --git a/ElementX/Sources/Screens/RoomScreen/View/Timeline/ReadMarkerRoomTimelineView.swift b/ElementX/Sources/Screens/RoomScreen/View/Timeline/ReadMarkerRoomTimelineView.swift index 409d7ca83..94bf8d49e 100644 --- a/ElementX/Sources/Screens/RoomScreen/View/Timeline/ReadMarkerRoomTimelineView.swift +++ b/ElementX/Sources/Screens/RoomScreen/View/Timeline/ReadMarkerRoomTimelineView.swift @@ -47,6 +47,7 @@ struct ReadMarkerRoomTimelineView_Previews: PreviewProvider, TestablePreview { timestamp: "", isOutgoing: true, isEditable: false, + canBeRepliedTo: true, isThreaded: false, sender: .init(id: "1", displayName: "Bob"), content: .init(body: "This is another message"))), groupStyle: .single)) @@ -58,6 +59,7 @@ struct ReadMarkerRoomTimelineView_Previews: PreviewProvider, TestablePreview { timestamp: "", isOutgoing: false, isEditable: false, + canBeRepliedTo: true, isThreaded: false, sender: .init(id: "", displayName: "Alice"), content: .init(body: "This is a message"))), groupStyle: .single)) diff --git a/ElementX/Sources/Screens/RoomScreen/View/Timeline/RedactedRoomTimelineView.swift b/ElementX/Sources/Screens/RoomScreen/View/Timeline/RedactedRoomTimelineView.swift index f35220f4c..2da86ab36 100644 --- a/ElementX/Sources/Screens/RoomScreen/View/Timeline/RedactedRoomTimelineView.swift +++ b/ElementX/Sources/Screens/RoomScreen/View/Timeline/RedactedRoomTimelineView.swift @@ -47,6 +47,7 @@ struct RedactedRoomTimelineView_Previews: PreviewProvider, TestablePreview { timestamp: timestamp, isOutgoing: false, isEditable: false, + canBeRepliedTo: false, sender: .init(id: senderId)) } } diff --git a/ElementX/Sources/Screens/RoomScreen/View/Timeline/StateRoomTimelineView.swift b/ElementX/Sources/Screens/RoomScreen/View/Timeline/StateRoomTimelineView.swift index b211aac6e..a0b81889c 100644 --- a/ElementX/Sources/Screens/RoomScreen/View/Timeline/StateRoomTimelineView.swift +++ b/ElementX/Sources/Screens/RoomScreen/View/Timeline/StateRoomTimelineView.swift @@ -46,5 +46,6 @@ struct StateRoomTimelineView_Previews: PreviewProvider, TestablePreview { timestamp: "Now", isOutgoing: false, isEditable: false, + canBeRepliedTo: true, sender: .init(id: "")) } diff --git a/ElementX/Sources/Screens/RoomScreen/View/Timeline/StickerRoomTimelineView.swift b/ElementX/Sources/Screens/RoomScreen/View/Timeline/StickerRoomTimelineView.swift index 807bdd59c..a8db13446 100644 --- a/ElementX/Sources/Screens/RoomScreen/View/Timeline/StickerRoomTimelineView.swift +++ b/ElementX/Sources/Screens/RoomScreen/View/Timeline/StickerRoomTimelineView.swift @@ -64,6 +64,7 @@ struct StickerRoomTimelineView_Previews: PreviewProvider, TestablePreview { timestamp: "Now", isOutgoing: false, isEditable: false, + canBeRepliedTo: true, sender: .init(id: "Bob"), imageURL: URL.picturesDirectory)) @@ -72,6 +73,7 @@ struct StickerRoomTimelineView_Previews: PreviewProvider, TestablePreview { timestamp: "Now", isOutgoing: false, isEditable: false, + canBeRepliedTo: true, sender: .init(id: "Bob"), imageURL: URL.picturesDirectory)) @@ -80,6 +82,7 @@ struct StickerRoomTimelineView_Previews: PreviewProvider, TestablePreview { timestamp: "Now", isOutgoing: false, isEditable: false, + canBeRepliedTo: true, sender: .init(id: "Bob"), imageURL: URL.picturesDirectory, aspectRatio: 0.7, diff --git a/ElementX/Sources/Screens/RoomScreen/View/Timeline/TextRoomTimelineView.swift b/ElementX/Sources/Screens/RoomScreen/View/Timeline/TextRoomTimelineView.swift index 076414568..0007664c8 100644 --- a/ElementX/Sources/Screens/RoomScreen/View/Timeline/TextRoomTimelineView.swift +++ b/ElementX/Sources/Screens/RoomScreen/View/Timeline/TextRoomTimelineView.swift @@ -75,6 +75,7 @@ struct TextRoomTimelineView_Previews: PreviewProvider, TestablePreview { timestamp: timestamp, isOutgoing: isOutgoing, isEditable: isOutgoing, + canBeRepliedTo: true, isThreaded: false, sender: .init(id: senderId), content: .init(body: text)) diff --git a/ElementX/Sources/Screens/RoomScreen/View/Timeline/UnsupportedRoomTimelineView.swift b/ElementX/Sources/Screens/RoomScreen/View/Timeline/UnsupportedRoomTimelineView.swift index 8a375b179..ea90d53ba 100644 --- a/ElementX/Sources/Screens/RoomScreen/View/Timeline/UnsupportedRoomTimelineView.swift +++ b/ElementX/Sources/Screens/RoomScreen/View/Timeline/UnsupportedRoomTimelineView.swift @@ -70,6 +70,7 @@ struct UnsupportedRoomTimelineView_Previews: PreviewProvider, TestablePreview { timestamp: timestamp, isOutgoing: isOutgoing, isEditable: false, + canBeRepliedTo: true, sender: .init(id: senderId)) } } diff --git a/ElementX/Sources/Screens/RoomScreen/View/Timeline/VideoRoomTimelineView.swift b/ElementX/Sources/Screens/RoomScreen/View/Timeline/VideoRoomTimelineView.swift index b211bf8c4..45badf506 100644 --- a/ElementX/Sources/Screens/RoomScreen/View/Timeline/VideoRoomTimelineView.swift +++ b/ElementX/Sources/Screens/RoomScreen/View/Timeline/VideoRoomTimelineView.swift @@ -83,6 +83,7 @@ struct VideoRoomTimelineView_Previews: PreviewProvider, TestablePreview { timestamp: "Now", isOutgoing: false, isEditable: false, + canBeRepliedTo: true, isThreaded: false, sender: .init(id: "Bob"), content: .init(body: "Some video", duration: 21, source: nil, thumbnailSource: nil))) @@ -91,6 +92,7 @@ struct VideoRoomTimelineView_Previews: PreviewProvider, TestablePreview { timestamp: "Now", isOutgoing: false, isEditable: false, + canBeRepliedTo: true, isThreaded: false, sender: .init(id: "Bob"), content: .init(body: "Some other video", duration: 22, source: nil, thumbnailSource: nil))) @@ -99,6 +101,7 @@ struct VideoRoomTimelineView_Previews: PreviewProvider, TestablePreview { timestamp: "Now", isOutgoing: false, isEditable: false, + canBeRepliedTo: true, isThreaded: false, sender: .init(id: "Bob"), content: .init(body: "Blurhashed video", duration: 23, source: nil, thumbnailSource: nil, aspectRatio: 0.7, blurhash: "L%KUc%kqS$RP?Ks,WEf8OlrqaekW"))) diff --git a/ElementX/Sources/Services/Timeline/Fixtures/RoomTimelineItemFixtures.swift b/ElementX/Sources/Services/Timeline/Fixtures/RoomTimelineItemFixtures.swift index 719a6a620..9cb3860ac 100644 --- a/ElementX/Sources/Services/Timeline/Fixtures/RoomTimelineItemFixtures.swift +++ b/ElementX/Sources/Services/Timeline/Fixtures/RoomTimelineItemFixtures.swift @@ -24,6 +24,7 @@ enum RoomTimelineItemFixtures { timestamp: "10:10 AM", isOutgoing: false, isEditable: false, + canBeRepliedTo: true, isThreaded: false, sender: .init(id: "", displayName: "Jacob"), content: .init(body: "That looks so good!"), @@ -32,6 +33,7 @@ enum RoomTimelineItemFixtures { timestamp: "10:11 AM", isOutgoing: false, isEditable: false, + canBeRepliedTo: true, isThreaded: false, sender: .init(id: "", displayName: "Helena"), content: .init(body: "Let’s get lunch soon! New salad place opened up 🥗. When are y’all free? 🤗"), @@ -42,6 +44,7 @@ enum RoomTimelineItemFixtures { timestamp: "10:11 AM", isOutgoing: false, isEditable: false, + canBeRepliedTo: true, isThreaded: false, sender: .init(id: "", displayName: "Helena"), content: .init(body: "I can be around on Wednesday. How about some 🌮 instead? Like https://www.tortilla.co.uk/"), @@ -60,6 +63,7 @@ enum RoomTimelineItemFixtures { timestamp: "5 PM", isOutgoing: false, isEditable: false, + canBeRepliedTo: true, isThreaded: false, sender: .init(id: "", displayName: "Helena"), content: .init(body: "Wow, cool. Ok, lets go the usual place tomorrow?! Is that too soon? Here’s the menu, let me know what you want it’s on me!"), @@ -68,6 +72,7 @@ enum RoomTimelineItemFixtures { timestamp: "5 PM", isOutgoing: true, isEditable: true, + canBeRepliedTo: true, isThreaded: false, sender: .init(id: "", displayName: "Bob"), content: .init(body: "And John's speech was amazing!")), @@ -75,6 +80,7 @@ enum RoomTimelineItemFixtures { timestamp: "5 PM", isOutgoing: true, isEditable: true, + canBeRepliedTo: true, isThreaded: false, sender: .init(id: "", displayName: "Bob"), content: .init(body: "New home office set up!"), @@ -87,6 +93,7 @@ enum RoomTimelineItemFixtures { timestamp: "5 PM", isOutgoing: false, isEditable: false, + canBeRepliedTo: true, isThreaded: false, sender: .init(id: "", displayName: "Helena"), content: .init(body: "", @@ -241,6 +248,7 @@ private extension TextRoomTimelineItem { timestamp: "10:47 am", isOutgoing: senderDisplayName == "Alice", isEditable: false, + canBeRepliedTo: true, isThreaded: false, sender: .init(id: "", displayName: senderDisplayName), content: .init(body: text)) diff --git a/ElementX/Sources/Services/Timeline/TimelineItemProxy.swift b/ElementX/Sources/Services/Timeline/TimelineItemProxy.swift index 4996dcf0a..5b5744945 100644 --- a/ElementX/Sources/Services/Timeline/TimelineItemProxy.swift +++ b/ElementX/Sources/Services/Timeline/TimelineItemProxy.swift @@ -87,6 +87,8 @@ class EventTimelineItemProxy { return .sent } }() + + lazy var canBeRepliedTo = item.canBeRepliedTo() lazy var isRoomState = content.kind().isRoomState diff --git a/ElementX/Sources/Services/Timeline/TimelineItems/EventBasedTimelineItemProtocol.swift b/ElementX/Sources/Services/Timeline/TimelineItems/EventBasedTimelineItemProtocol.swift index f2f188f2f..c2f14ce90 100644 --- a/ElementX/Sources/Services/Timeline/TimelineItems/EventBasedTimelineItemProtocol.swift +++ b/ElementX/Sources/Services/Timeline/TimelineItems/EventBasedTimelineItemProtocol.swift @@ -21,6 +21,7 @@ protocol EventBasedTimelineItemProtocol: RoomTimelineItemProtocol, CustomStringC var timestamp: String { get } var isOutgoing: Bool { get } var isEditable: Bool { get } + var canBeRepliedTo: Bool { get } var sender: TimelineItemSender { get } diff --git a/ElementX/Sources/Services/Timeline/TimelineItems/Items/Messages/AudioRoomTimelineItem.swift b/ElementX/Sources/Services/Timeline/TimelineItems/Items/Messages/AudioRoomTimelineItem.swift index 8ef97f8dd..9ab40821b 100644 --- a/ElementX/Sources/Services/Timeline/TimelineItems/Items/Messages/AudioRoomTimelineItem.swift +++ b/ElementX/Sources/Services/Timeline/TimelineItems/Items/Messages/AudioRoomTimelineItem.swift @@ -21,6 +21,7 @@ struct AudioRoomTimelineItem: EventBasedMessageTimelineItemProtocol, Equatable { let timestamp: String let isOutgoing: Bool let isEditable: Bool + let canBeRepliedTo: Bool let isThreaded: Bool let sender: TimelineItemSender diff --git a/ElementX/Sources/Services/Timeline/TimelineItems/Items/Messages/EmoteRoomTimelineItem.swift b/ElementX/Sources/Services/Timeline/TimelineItems/Items/Messages/EmoteRoomTimelineItem.swift index 426d27c10..7abe830f2 100644 --- a/ElementX/Sources/Services/Timeline/TimelineItems/Items/Messages/EmoteRoomTimelineItem.swift +++ b/ElementX/Sources/Services/Timeline/TimelineItems/Items/Messages/EmoteRoomTimelineItem.swift @@ -21,6 +21,7 @@ struct EmoteRoomTimelineItem: TextBasedRoomTimelineItem, Equatable { let timestamp: String let isOutgoing: Bool let isEditable: Bool + let canBeRepliedTo: Bool let isThreaded: Bool let sender: TimelineItemSender diff --git a/ElementX/Sources/Services/Timeline/TimelineItems/Items/Messages/FileRoomTimelineItem.swift b/ElementX/Sources/Services/Timeline/TimelineItems/Items/Messages/FileRoomTimelineItem.swift index 2b7e24919..c87e95c83 100644 --- a/ElementX/Sources/Services/Timeline/TimelineItems/Items/Messages/FileRoomTimelineItem.swift +++ b/ElementX/Sources/Services/Timeline/TimelineItems/Items/Messages/FileRoomTimelineItem.swift @@ -22,6 +22,7 @@ struct FileRoomTimelineItem: EventBasedMessageTimelineItemProtocol, Equatable { let timestamp: String let isOutgoing: Bool let isEditable: Bool + let canBeRepliedTo: Bool let isThreaded: Bool diff --git a/ElementX/Sources/Services/Timeline/TimelineItems/Items/Messages/ImageRoomTimelineItem.swift b/ElementX/Sources/Services/Timeline/TimelineItems/Items/Messages/ImageRoomTimelineItem.swift index 10be9873b..91ae1276e 100644 --- a/ElementX/Sources/Services/Timeline/TimelineItems/Items/Messages/ImageRoomTimelineItem.swift +++ b/ElementX/Sources/Services/Timeline/TimelineItems/Items/Messages/ImageRoomTimelineItem.swift @@ -22,6 +22,7 @@ struct ImageRoomTimelineItem: EventBasedMessageTimelineItemProtocol, Equatable { let timestamp: String let isOutgoing: Bool let isEditable: Bool + let canBeRepliedTo: Bool let isThreaded: Bool let sender: TimelineItemSender diff --git a/ElementX/Sources/Services/Timeline/TimelineItems/Items/Messages/LocationRoomTimelineItem.swift b/ElementX/Sources/Services/Timeline/TimelineItems/Items/Messages/LocationRoomTimelineItem.swift index 8a9ad2031..f21ec5aac 100644 --- a/ElementX/Sources/Services/Timeline/TimelineItems/Items/Messages/LocationRoomTimelineItem.swift +++ b/ElementX/Sources/Services/Timeline/TimelineItems/Items/Messages/LocationRoomTimelineItem.swift @@ -20,6 +20,7 @@ struct LocationRoomTimelineItem: EventBasedMessageTimelineItemProtocol, Equatabl let timestamp: String let isOutgoing: Bool let isEditable: Bool + let canBeRepliedTo: Bool let isThreaded: Bool let sender: TimelineItemSender diff --git a/ElementX/Sources/Services/Timeline/TimelineItems/Items/Messages/NoticeRoomTimelineItem.swift b/ElementX/Sources/Services/Timeline/TimelineItems/Items/Messages/NoticeRoomTimelineItem.swift index b2720cd5e..183353809 100644 --- a/ElementX/Sources/Services/Timeline/TimelineItems/Items/Messages/NoticeRoomTimelineItem.swift +++ b/ElementX/Sources/Services/Timeline/TimelineItems/Items/Messages/NoticeRoomTimelineItem.swift @@ -21,6 +21,7 @@ struct NoticeRoomTimelineItem: TextBasedRoomTimelineItem, Equatable { let timestamp: String let isOutgoing: Bool let isEditable: Bool + let canBeRepliedTo: Bool let isThreaded: Bool let sender: TimelineItemSender diff --git a/ElementX/Sources/Services/Timeline/TimelineItems/Items/Messages/TextRoomTimelineItem.swift b/ElementX/Sources/Services/Timeline/TimelineItems/Items/Messages/TextRoomTimelineItem.swift index 8d212dfda..10e5b7099 100644 --- a/ElementX/Sources/Services/Timeline/TimelineItems/Items/Messages/TextRoomTimelineItem.swift +++ b/ElementX/Sources/Services/Timeline/TimelineItems/Items/Messages/TextRoomTimelineItem.swift @@ -22,6 +22,7 @@ struct TextRoomTimelineItem: TextBasedRoomTimelineItem, Equatable { let timestamp: String let isOutgoing: Bool let isEditable: Bool + let canBeRepliedTo: Bool let isThreaded: Bool diff --git a/ElementX/Sources/Services/Timeline/TimelineItems/Items/Messages/VideoRoomTimelineItem.swift b/ElementX/Sources/Services/Timeline/TimelineItems/Items/Messages/VideoRoomTimelineItem.swift index c36b5375a..dd5f831c9 100644 --- a/ElementX/Sources/Services/Timeline/TimelineItems/Items/Messages/VideoRoomTimelineItem.swift +++ b/ElementX/Sources/Services/Timeline/TimelineItems/Items/Messages/VideoRoomTimelineItem.swift @@ -22,6 +22,7 @@ struct VideoRoomTimelineItem: EventBasedMessageTimelineItemProtocol, Equatable { let timestamp: String let isOutgoing: Bool let isEditable: Bool + let canBeRepliedTo: Bool let isThreaded: Bool let sender: TimelineItemSender diff --git a/ElementX/Sources/Services/Timeline/TimelineItems/Items/Messages/VoiceMessages/VoiceRoomTimelineView.swift b/ElementX/Sources/Services/Timeline/TimelineItems/Items/Messages/VoiceMessages/VoiceRoomTimelineView.swift index 3b037e8f3..161ca0dcd 100644 --- a/ElementX/Sources/Services/Timeline/TimelineItems/Items/Messages/VoiceMessages/VoiceRoomTimelineView.swift +++ b/ElementX/Sources/Services/Timeline/TimelineItems/Items/Messages/VoiceMessages/VoiceRoomTimelineView.swift @@ -64,6 +64,7 @@ struct VoiceRoomTimelineView_Previews: PreviewProvider, TestablePreview { timestamp: "Now", isOutgoing: false, isEditable: false, + canBeRepliedTo: true, isThreaded: false, sender: .init(id: "Bob"), content: .init(body: "audio.ogg", diff --git a/ElementX/Sources/Services/Timeline/TimelineItems/Items/Messages/VoiceRoomTimelineItem.swift b/ElementX/Sources/Services/Timeline/TimelineItems/Items/Messages/VoiceRoomTimelineItem.swift index 7b9cce464..29f08c7d7 100644 --- a/ElementX/Sources/Services/Timeline/TimelineItems/Items/Messages/VoiceRoomTimelineItem.swift +++ b/ElementX/Sources/Services/Timeline/TimelineItems/Items/Messages/VoiceRoomTimelineItem.swift @@ -21,6 +21,7 @@ struct VoiceRoomTimelineItem: EventBasedMessageTimelineItemProtocol, Equatable { let timestamp: String let isOutgoing: Bool let isEditable: Bool + let canBeRepliedTo: Bool let isThreaded: Bool let sender: TimelineItemSender diff --git a/ElementX/Sources/Services/Timeline/TimelineItems/Items/Other/EncryptedRoomTimelineItem.swift b/ElementX/Sources/Services/Timeline/TimelineItems/Items/Other/EncryptedRoomTimelineItem.swift index 2276ee45e..a253acf40 100644 --- a/ElementX/Sources/Services/Timeline/TimelineItems/Items/Other/EncryptedRoomTimelineItem.swift +++ b/ElementX/Sources/Services/Timeline/TimelineItems/Items/Other/EncryptedRoomTimelineItem.swift @@ -29,6 +29,7 @@ struct EncryptedRoomTimelineItem: EventBasedTimelineItemProtocol, Equatable { let timestamp: String let isOutgoing: Bool let isEditable: Bool + let canBeRepliedTo: Bool let sender: TimelineItemSender diff --git a/ElementX/Sources/Services/Timeline/TimelineItems/Items/Other/PollRoomTimelineItem.swift b/ElementX/Sources/Services/Timeline/TimelineItems/Items/Other/PollRoomTimelineItem.swift index e203ab170..41e9ee956 100644 --- a/ElementX/Sources/Services/Timeline/TimelineItems/Items/Other/PollRoomTimelineItem.swift +++ b/ElementX/Sources/Services/Timeline/TimelineItems/Items/Other/PollRoomTimelineItem.swift @@ -23,6 +23,7 @@ struct PollRoomTimelineItem: Equatable, EventBasedTimelineItemProtocol { let timestamp: String let isOutgoing: Bool let isEditable: Bool + let canBeRepliedTo: Bool let sender: TimelineItemSender var properties: RoomTimelineItemProperties } diff --git a/ElementX/Sources/Services/Timeline/TimelineItems/Items/Other/RedactedRoomTimelineItem.swift b/ElementX/Sources/Services/Timeline/TimelineItems/Items/Other/RedactedRoomTimelineItem.swift index 779dad201..7e71d9278 100644 --- a/ElementX/Sources/Services/Timeline/TimelineItems/Items/Other/RedactedRoomTimelineItem.swift +++ b/ElementX/Sources/Services/Timeline/TimelineItems/Items/Other/RedactedRoomTimelineItem.swift @@ -23,6 +23,7 @@ struct RedactedRoomTimelineItem: EventBasedTimelineItemProtocol, Equatable { let timestamp: String let isOutgoing: Bool let isEditable: Bool + let canBeRepliedTo: Bool let sender: TimelineItemSender diff --git a/ElementX/Sources/Services/Timeline/TimelineItems/Items/Other/StateRoomTimelineItem.swift b/ElementX/Sources/Services/Timeline/TimelineItems/Items/Other/StateRoomTimelineItem.swift index 49aa4a790..48787675f 100644 --- a/ElementX/Sources/Services/Timeline/TimelineItems/Items/Other/StateRoomTimelineItem.swift +++ b/ElementX/Sources/Services/Timeline/TimelineItems/Items/Other/StateRoomTimelineItem.swift @@ -22,6 +22,7 @@ struct StateRoomTimelineItem: EventBasedTimelineItemProtocol, Equatable { let timestamp: String let isOutgoing: Bool let isEditable: Bool + let canBeRepliedTo: Bool let sender: TimelineItemSender diff --git a/ElementX/Sources/Services/Timeline/TimelineItems/Items/Other/StickerRoomTimelineItem.swift b/ElementX/Sources/Services/Timeline/TimelineItems/Items/Other/StickerRoomTimelineItem.swift index 5069846d1..55b377133 100644 --- a/ElementX/Sources/Services/Timeline/TimelineItems/Items/Other/StickerRoomTimelineItem.swift +++ b/ElementX/Sources/Services/Timeline/TimelineItems/Items/Other/StickerRoomTimelineItem.swift @@ -22,6 +22,7 @@ struct StickerRoomTimelineItem: EventBasedTimelineItemProtocol, Equatable { let timestamp: String let isOutgoing: Bool let isEditable: Bool + let canBeRepliedTo: Bool let sender: TimelineItemSender diff --git a/ElementX/Sources/Services/Timeline/TimelineItems/Items/Other/UnsupportedRoomTimelineItem.swift b/ElementX/Sources/Services/Timeline/TimelineItems/Items/Other/UnsupportedRoomTimelineItem.swift index 5f1636149..ff02f075f 100644 --- a/ElementX/Sources/Services/Timeline/TimelineItems/Items/Other/UnsupportedRoomTimelineItem.swift +++ b/ElementX/Sources/Services/Timeline/TimelineItems/Items/Other/UnsupportedRoomTimelineItem.swift @@ -26,6 +26,7 @@ struct UnsupportedRoomTimelineItem: EventBasedTimelineItemProtocol, Equatable { let timestamp: String let isOutgoing: Bool let isEditable: Bool + let canBeRepliedTo: Bool let sender: TimelineItemSender diff --git a/ElementX/Sources/Services/Timeline/TimelineItems/RoomTimelineItemFactory.swift b/ElementX/Sources/Services/Timeline/TimelineItems/RoomTimelineItemFactory.swift index fe3d07063..92aa6a6c9 100644 --- a/ElementX/Sources/Services/Timeline/TimelineItems/RoomTimelineItemFactory.swift +++ b/ElementX/Sources/Services/Timeline/TimelineItems/RoomTimelineItemFactory.swift @@ -121,6 +121,7 @@ struct RoomTimelineItemFactory: RoomTimelineItemFactoryProtocol { timestamp: eventItemProxy.timestamp.formatted(date: .omitted, time: .shortened), isOutgoing: isOutgoing, isEditable: eventItemProxy.isEditable, + canBeRepliedTo: eventItemProxy.canBeRepliedTo, sender: eventItemProxy.sender, properties: RoomTimelineItemProperties()) } @@ -142,6 +143,7 @@ struct RoomTimelineItemFactory: RoomTimelineItemFactoryProtocol { timestamp: eventItemProxy.timestamp.formatted(date: .omitted, time: .shortened), isOutgoing: isOutgoing, isEditable: eventItemProxy.isEditable, + canBeRepliedTo: eventItemProxy.canBeRepliedTo, sender: eventItemProxy.sender, imageURL: imageURL, width: width, @@ -172,6 +174,7 @@ struct RoomTimelineItemFactory: RoomTimelineItemFactoryProtocol { timestamp: eventItemProxy.timestamp.formatted(date: .omitted, time: .shortened), isOutgoing: isOutgoing, isEditable: eventItemProxy.isEditable, + canBeRepliedTo: eventItemProxy.canBeRepliedTo, sender: eventItemProxy.sender, properties: RoomTimelineItemProperties()) } @@ -183,6 +186,7 @@ struct RoomTimelineItemFactory: RoomTimelineItemFactoryProtocol { timestamp: eventItemProxy.timestamp.formatted(date: .omitted, time: .shortened), isOutgoing: isOutgoing, isEditable: eventItemProxy.isEditable, + canBeRepliedTo: eventItemProxy.canBeRepliedTo, sender: eventItemProxy.sender, properties: RoomTimelineItemProperties()) } @@ -196,6 +200,7 @@ struct RoomTimelineItemFactory: RoomTimelineItemFactoryProtocol { timestamp: eventItemProxy.timestamp.formatted(date: .omitted, time: .shortened), isOutgoing: isOutgoing, isEditable: eventItemProxy.isEditable, + canBeRepliedTo: eventItemProxy.canBeRepliedTo, isThreaded: isThreaded, sender: eventItemProxy.sender, content: buildTextTimelineItemContent(messageContent), @@ -215,6 +220,7 @@ struct RoomTimelineItemFactory: RoomTimelineItemFactoryProtocol { timestamp: eventItemProxy.timestamp.formatted(date: .omitted, time: .shortened), isOutgoing: isOutgoing, isEditable: eventItemProxy.isEditable, + canBeRepliedTo: eventItemProxy.canBeRepliedTo, isThreaded: isThreaded, sender: eventItemProxy.sender, content: buildImageTimelineItemContent(messageContent), @@ -234,6 +240,7 @@ struct RoomTimelineItemFactory: RoomTimelineItemFactoryProtocol { timestamp: eventItemProxy.timestamp.formatted(date: .omitted, time: .shortened), isOutgoing: isOutgoing, isEditable: eventItemProxy.isEditable, + canBeRepliedTo: eventItemProxy.canBeRepliedTo, isThreaded: isThreaded, sender: eventItemProxy.sender, content: buildVideoTimelineItemContent(messageContent), @@ -253,6 +260,7 @@ struct RoomTimelineItemFactory: RoomTimelineItemFactoryProtocol { timestamp: eventItemProxy.timestamp.formatted(date: .omitted, time: .shortened), isOutgoing: isOutgoing, isEditable: eventItemProxy.isEditable, + canBeRepliedTo: eventItemProxy.canBeRepliedTo, isThreaded: isThreaded, sender: eventItemProxy.sender, content: buildAudioTimelineItemContent(messageContent), @@ -272,6 +280,7 @@ struct RoomTimelineItemFactory: RoomTimelineItemFactoryProtocol { timestamp: eventItemProxy.timestamp.formatted(date: .omitted, time: .shortened), isOutgoing: isOutgoing, isEditable: eventItemProxy.isEditable, + canBeRepliedTo: eventItemProxy.canBeRepliedTo, isThreaded: isThreaded, sender: eventItemProxy.sender, content: buildAudioTimelineItemContent(messageContent), @@ -291,6 +300,7 @@ struct RoomTimelineItemFactory: RoomTimelineItemFactoryProtocol { timestamp: eventItemProxy.timestamp.formatted(date: .omitted, time: .shortened), isOutgoing: isOutgoing, isEditable: eventItemProxy.isEditable, + canBeRepliedTo: eventItemProxy.canBeRepliedTo, isThreaded: isThreaded, sender: eventItemProxy.sender, content: buildFileTimelineItemContent(messageContent), @@ -310,6 +320,7 @@ struct RoomTimelineItemFactory: RoomTimelineItemFactoryProtocol { timestamp: eventItemProxy.timestamp.formatted(date: .omitted, time: .shortened), isOutgoing: isOutgoing, isEditable: eventItemProxy.isEditable, + canBeRepliedTo: eventItemProxy.canBeRepliedTo, isThreaded: isThreaded, sender: eventItemProxy.sender, content: buildNoticeTimelineItemContent(messageContent), @@ -329,6 +340,7 @@ struct RoomTimelineItemFactory: RoomTimelineItemFactoryProtocol { timestamp: eventItemProxy.timestamp.formatted(date: .omitted, time: .shortened), isOutgoing: isOutgoing, isEditable: eventItemProxy.isEditable, + canBeRepliedTo: eventItemProxy.canBeRepliedTo, isThreaded: isThreaded, sender: eventItemProxy.sender, content: buildEmoteTimelineItemContent(senderDisplayName: eventItemProxy.sender.displayName, senderID: eventItemProxy.sender.id, messageContent: messageContent), @@ -348,6 +360,7 @@ struct RoomTimelineItemFactory: RoomTimelineItemFactoryProtocol { timestamp: eventItemProxy.timestamp.formatted(date: .omitted, time: .shortened), isOutgoing: isOutgoing, isEditable: eventItemProxy.isEditable, + canBeRepliedTo: eventItemProxy.canBeRepliedTo, isThreaded: isThreaded, sender: eventItemProxy.sender, content: buildLocationTimelineItemContent(messageContent), @@ -398,6 +411,7 @@ struct RoomTimelineItemFactory: RoomTimelineItemFactoryProtocol { timestamp: eventItemProxy.timestamp.formatted(date: .omitted, time: .shortened), isOutgoing: isOutgoing, isEditable: eventItemProxy.isEditable, + canBeRepliedTo: eventItemProxy.canBeRepliedTo, sender: eventItemProxy.sender, properties: RoomTimelineItemProperties(isEdited: false, reactions: aggregateReactions(eventItemProxy.reactions), @@ -587,6 +601,7 @@ struct RoomTimelineItemFactory: RoomTimelineItemFactoryProtocol { timestamp: eventItemProxy.timestamp.formatted(date: .omitted, time: .shortened), isOutgoing: isOutgoing, isEditable: false, + canBeRepliedTo: eventItemProxy.canBeRepliedTo, sender: eventItemProxy.sender) } @@ -614,29 +629,39 @@ struct RoomTimelineItemFactory: RoomTimelineItemFactoryProtocol { } let replyContent: EventBasedMessageTimelineItemContentType - switch timelineItem.asMessage()?.msgtype() { - case .audio(let content): - if appSettings.voiceMessageEnabled, content.voice != nil { - replyContent = .voice(buildAudioTimelineItemContent(content)) - } else { - replyContent = .audio(buildAudioTimelineItemContent(content)) + + switch timelineItem.kind() { + case .message: + switch timelineItem.asMessage()?.msgtype() { + case .audio(let content): + if appSettings.voiceMessageEnabled, content.voice != nil { + replyContent = .voice(buildAudioTimelineItemContent(content)) + } else { + replyContent = .audio(buildAudioTimelineItemContent(content)) + } + case .emote(let content): + replyContent = .emote(buildEmoteTimelineItemContent(senderDisplayName: sender.displayName, senderID: sender.id, messageContent: content)) + case .file(let content): + replyContent = .file(buildFileTimelineItemContent(content)) + case .image(let content): + replyContent = .image(buildImageTimelineItemContent(content)) + case .notice(let content): + replyContent = .notice(buildNoticeTimelineItemContent(content)) + case .text(let content): + replyContent = .text(buildTextTimelineItemContent(content)) + case .video(let content): + replyContent = .video(buildVideoTimelineItemContent(content)) + case .location(let content): + replyContent = .location(buildLocationTimelineItemContent(content)) + case .none: + replyContent = .text(.init(body: L10n.commonUnsupportedEvent)) } - case .emote(let content): - replyContent = .emote(buildEmoteTimelineItemContent(senderDisplayName: sender.displayName, senderID: sender.id, messageContent: content)) - case .file(let content): - replyContent = .file(buildFileTimelineItemContent(content)) - case .image(let content): - replyContent = .image(buildImageTimelineItemContent(content)) - case .notice(let content): - replyContent = .notice(buildNoticeTimelineItemContent(content)) - case .text(let content): - replyContent = .text(buildTextTimelineItemContent(content)) - case .video(let content): - replyContent = .video(buildVideoTimelineItemContent(content)) - case .location(let content): - replyContent = .location(buildLocationTimelineItemContent(content)) - case .none: - return nil + case .poll(let question, _, _, _, _, _): + replyContent = .text(.init(body: question)) + case .sticker(let body, _, _): + replyContent = .text(.init(body: body)) + default: + replyContent = .text(.init(body: L10n.commonUnsupportedEvent)) } return .loaded(sender: sender, contentType: replyContent)