diff --git a/ElementX.xcodeproj/project.pbxproj b/ElementX.xcodeproj/project.pbxproj index a95290ac7..6f6e6de7f 100644 --- a/ElementX.xcodeproj/project.pbxproj +++ b/ElementX.xcodeproj/project.pbxproj @@ -3,7 +3,7 @@ archiveVersion = 1; classes = { }; - objectVersion = 52; + objectVersion = 51; objects = { /* Begin PBXBuildFile section */ @@ -110,6 +110,7 @@ 41DFDD212D1BE57CA50D783B /* SwiftyBeaver in Frameworks */ = {isa = PBXBuildFile; productRef = FD43A50D9B75C9D6D30F006B /* SwiftyBeaver */; }; 438FB9BC535BC95948AA5F34 /* SettingsViewModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B2F9D5C39A4494D19F33E38 /* SettingsViewModelProtocol.swift */; }; 43FD77998F33C32718C51450 /* TemplateCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBD460ED7ED1E03B85DEA25C /* TemplateCoordinator.swift */; }; + 440123E29E2F9B001A775BBE /* TimelineItemProxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D505843AB66822EB91F0DF0 /* TimelineItemProxy.swift */; }; 447E8580A0A2569E32529E17 /* MockRoomTimelineProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8D6094DEAAEB388E1AE118C6 /* MockRoomTimelineProvider.swift */; }; 462813B93C39DF93B1249403 /* RoundedToastView.swift in Sources */ = {isa = PBXBuildFile; fileRef = AFABDF2E19D349DAAAC18C65 /* RoundedToastView.swift */; }; 46562110EE202E580A5FFD9C /* RoomScreenViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 93CF7B19FFCF8EFBE0A8696A /* RoomScreenViewModelTests.swift */; }; @@ -137,7 +138,6 @@ 54C774874BED4A8FAD1F22FE /* AnalyticsConfiguration.swift in Sources */ = {isa = PBXBuildFile; fileRef = D77B3D4950F1707E66E4A45A /* AnalyticsConfiguration.swift */; }; 563A05B43207D00A6B698211 /* OIDCService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9010EE0CC913D095887EF36E /* OIDCService.swift */; }; 56F0A22972A3BB519DA2261C /* HomeScreenViewModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 24F5530B2212862FA4BEFF2D /* HomeScreenViewModelProtocol.swift */; }; - 5706B6600CCCFE254F7D2495 /* Task.swift in Sources */ = {isa = PBXBuildFile; fileRef = FA2CA6D7090404B1074E887F /* Task.swift */; }; 59C41313AED7566C3AC51163 /* RoomSummary.swift in Sources */ = {isa = PBXBuildFile; fileRef = 29A953B6C0C431DBF4DD00B4 /* RoomSummary.swift */; }; 5B2C4C17888FC095ED6880B2 /* SplashViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 48971F1FFD7FC5C466889FC7 /* SplashViewController.xib */; }; 5C8AFBF168A41E20835F3B86 /* LoginScreenUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1DB34B0C74CD242FED9DD069 /* LoginScreenUITests.swift */; }; @@ -245,7 +245,6 @@ 9E8AE387FD03E4F1C1B8815A /* SessionVerificationStateMachine.swift in Sources */ = {isa = PBXBuildFile; fileRef = C06FCD42EEFEFC220F14EAC5 /* SessionVerificationStateMachine.swift */; }; A00DFC1DD3567B1EDC9F8D16 /* SplashScreenUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 325A2B3278875554DDEB8A9B /* SplashScreenUITests.swift */; }; A0A0D2A9564BDA3FDE2E360F /* FormattedBodyText.swift in Sources */ = {isa = PBXBuildFile; fileRef = F73FF1A33198F5FAE9D34B1F /* FormattedBodyText.swift */; }; - A0A26E4F713596856470EF1A /* RoomTimelineProviderItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9ABAECB0CA5FF8F8E6F10DD7 /* RoomTimelineProviderItem.swift */; }; A32517FB1CA0BBCE2BC75249 /* BugReportCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = AD6C07DA7D3FF193F7419F55 /* BugReportCoordinator.swift */; }; A371629728E597C5FCA3C2B2 /* Analytics.swift in Sources */ = {isa = PBXBuildFile; fileRef = 73FC861755C6388F62B9280A /* Analytics.swift */; }; A37EED79941AD3B7140B3822 /* UIDevice.swift in Sources */ = {isa = PBXBuildFile; fileRef = 287FC98AF2664EAD79C0D902 /* UIDevice.swift */; }; @@ -322,6 +321,7 @@ E01373F2043E76393A0CE073 /* AnalyticsPromptViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = A11B74ACE8D71747E1044A9C /* AnalyticsPromptViewModel.swift */; }; E0A4DCA633D174EB43AD599F /* BackgroundTaskProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2CA028DCD4157F9A1F999827 /* BackgroundTaskProtocol.swift */; }; E1DF24D085572A55C9758A2D /* Bundle.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6E89E530A8E92EC44301CA1 /* Bundle.swift */; }; + E290C78E7F09F47FD2662986 /* Task.swift in Sources */ = {isa = PBXBuildFile; fileRef = A40C19719687984FD9478FBE /* Task.swift */; }; E3CA565A4B9704F191B191F0 /* JoinedRoomSize+MemberCount.swift in Sources */ = {isa = PBXBuildFile; fileRef = CBF9AEA706926DD0DA2B954C /* JoinedRoomSize+MemberCount.swift */; }; E47CD939D8480657D4B706C6 /* AnalyticsPromptCheckmarkItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = BA7B2E9CC5DC3B76ADC35A43 /* AnalyticsPromptCheckmarkItem.swift */; }; E481C8FDCB6C089963C95344 /* DTCoreText in Frameworks */ = {isa = PBXBuildFile; productRef = 527578916BD388A09F5A8036 /* DTCoreText */; }; @@ -459,6 +459,7 @@ 2CCBDE671A613B3EB70794C4 /* SoftLogoutScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SoftLogoutScreen.swift; sourceTree = ""; }; 2CF9FE7E0CF9F40D1509E63A /* bg */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = bg; path = bg.lproj/Localizable.stringsdict; sourceTree = ""; }; 2D256FEE2F1AF1E51D39B622 /* LoginTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoginTests.swift; sourceTree = ""; }; + 2D505843AB66822EB91F0DF0 /* TimelineItemProxy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimelineItemProxy.swift; sourceTree = ""; }; 2EEB64CC6F3DF5B68736A6B4 /* AlertInfo.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AlertInfo.swift; sourceTree = ""; }; 2F1B28C596DE541DA0AFD16C /* lo */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = lo; path = lo.lproj/Localizable.stringsdict; sourceTree = ""; }; 31B01468022EC826CB2FD2C0 /* LoginModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoginModels.swift; sourceTree = ""; }; @@ -628,7 +629,7 @@ 8D6094DEAAEB388E1AE118C6 /* MockRoomTimelineProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MockRoomTimelineProvider.swift; sourceTree = ""; }; 8D8169443E5AC5FF71BFB3DB /* cs */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = cs; path = cs.lproj/Localizable.strings; sourceTree = ""; }; 8DC2C9E0E15C79BBDA80F0A2 /* TimelineStyle.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimelineStyle.swift; sourceTree = ""; }; - 8E088F2A1B9EC529D3221931 /* UITests.xctestplan */ = {isa = PBXFileReference; lastKnownFileType = text; path = UITests.xctestplan; sourceTree = ""; }; + 8E088F2A1B9EC529D3221931 /* UITests.xctestplan */ = {isa = PBXFileReference; path = UITests.xctestplan; sourceTree = ""; }; 8F7D42E66E939B709C1EC390 /* MockRoomSummaryProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MockRoomSummaryProvider.swift; sourceTree = ""; }; 9010EE0CC913D095887EF36E /* OIDCService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OIDCService.swift; sourceTree = ""; }; 90733775209F4D4D366A268F /* RootRouterType.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RootRouterType.swift; sourceTree = ""; }; @@ -651,7 +652,6 @@ 997783054A2E95F9E624217E /* kaa */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = kaa; path = kaa.lproj/Localizable.strings; sourceTree = ""; }; 99DE232F24EAD72A3DF7EF1A /* kab */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = kab; path = kab.lproj/Localizable.stringsdict; sourceTree = ""; }; 9A68BCE6438873D2661D93D0 /* BugReportServiceProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BugReportServiceProtocol.swift; sourceTree = ""; }; - 9ABAECB0CA5FF8F8E6F10DD7 /* RoomTimelineProviderItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomTimelineProviderItem.swift; sourceTree = ""; }; 9B577F829C693B8DFB7014FD /* RedactedRoomTimelineItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RedactedRoomTimelineItem.swift; sourceTree = ""; }; 9C4048041C1A6B20CB97FD18 /* TestMeasurementParser.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TestMeasurementParser.swift; sourceTree = ""; }; 9C5E81214D27A6B898FC397D /* ElementX.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = ElementX.entitlements; sourceTree = ""; }; @@ -667,6 +667,7 @@ A1ED7E89865201EE7D53E6DA /* SeparatorRoomTimelineItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SeparatorRoomTimelineItem.swift; sourceTree = ""; }; A2B6433F516F1E6DFA0E2D89 /* vls */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = vls; path = vls.lproj/Localizable.strings; sourceTree = ""; }; A30A1758E2B73EF38E7C42F8 /* ServerSelectionModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ServerSelectionModels.swift; sourceTree = ""; }; + A40C19719687984FD9478FBE /* Task.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Task.swift; sourceTree = ""; }; A436057DBEA1A23CA8CB1FD7 /* UIFont+AttributedStringBuilder.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "UIFont+AttributedStringBuilder.h"; sourceTree = ""; }; A443FAE2EE820A5790C35C8D /* et */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = et; path = et.lproj/Localizable.strings; sourceTree = ""; }; A4756C5A8C8649AD6C10C615 /* MockUserSession.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MockUserSession.swift; sourceTree = ""; }; @@ -820,7 +821,6 @@ F77C060C2ACC4CB7336A29E7 /* EmoteRoomTimelineItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EmoteRoomTimelineItem.swift; sourceTree = ""; }; F9E785D5137510481733A3E8 /* TextRoomTimelineView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TextRoomTimelineView.swift; sourceTree = ""; }; FA154570F693D93513E584C1 /* RoomMessageFactory.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomMessageFactory.swift; sourceTree = ""; }; - FA2CA6D7090404B1074E887F /* Task.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Task.swift; sourceTree = ""; }; FAB10E673916D2B8D21FD197 /* TemplateModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TemplateModels.swift; sourceTree = ""; }; FDB9C37196A4C79F24CE80C6 /* KeychainControllerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KeychainControllerTests.swift; sourceTree = ""; }; /* End PBXFileReference section */ @@ -1092,9 +1092,9 @@ children = ( B6E89E530A8E92EC44301CA1 /* Bundle.swift */, A9FAFE1C2149E6AC8156ED2B /* Collection.swift */, - FA2CA6D7090404B1074E887F /* Task.swift */, E26747B3154A5DBC3A7E24A5 /* Image.swift */, 40B21E611DADDEF00307E7AC /* String.swift */, + A40C19719687984FD9478FBE /* Task.swift */, 287FC98AF2664EAD79C0D902 /* UIDevice.swift */, 227AC5D71A4CE43512062243 /* URL.swift */, ); @@ -1862,8 +1862,8 @@ 24B0C97D2F560BCB72BE73B1 /* RoomTimelineController.swift */, CC7CCC6DE5FA623E31BA8546 /* RoomTimelineControllerProtocol.swift */, 66F2402D738694F98729A441 /* RoomTimelineProvider.swift */, - 9ABAECB0CA5FF8F8E6F10DD7 /* RoomTimelineProviderItem.swift */, 095AED4CF56DFF3EB7BB84C8 /* RoomTimelineProviderProtocol.swift */, + 2D505843AB66822EB91F0DF0 /* TimelineItemProxy.swift */, 5A7A7D6D373D411C8C48B881 /* TimeLineItemContent */, 95BE1C7CB2C80344FF0BE724 /* TimelineItems */, ); @@ -2347,7 +2347,6 @@ DCB781BD227CA958809AFADF /* Coordinator.swift in Sources */, C4F69156C31A447FEFF2A47C /* DTHTMLElement+AttributedStringBuilder.swift in Sources */, EE8491AD81F47DF3C192497B /* DecorationTimelineItemProtocol.swift in Sources */, - 5706B6600CCCFE254F7D2495 /* Task.swift in Sources */, FE4593FC2A02AAF92E089565 /* ElementAnimations.swift in Sources */, 06E93B2E3B32740B40F47CC5 /* ElementNavigationController.swift in Sources */, 9738F894DB1BD383BE05767A /* ElementSettings.swift in Sources */, @@ -2444,7 +2443,6 @@ C8E82786DE1B6A400DA9BA25 /* RoomTimelineItemProperties.swift in Sources */, 1AE4AEA0FA8DEF52671832E0 /* RoomTimelineItemProtocol.swift in Sources */, 9BD3A773186291560DF92B62 /* RoomTimelineProvider.swift in Sources */, - A0A26E4F713596856470EF1A /* RoomTimelineProviderItem.swift in Sources */, 77D7DAA41AAB36800C1F2E2D /* RoomTimelineProviderProtocol.swift in Sources */, 5D430CDE11EAC3E8E6B80A66 /* RoomTimelineViewFactory.swift in Sources */, 297CD0A27C87B0C50FF192EE /* RoomTimelineViewFactoryProtocol.swift in Sources */, @@ -2491,6 +2489,7 @@ 2F94054F50E312AF30BE07F3 /* String.swift in Sources */, A7D48E44D485B143AADDB77D /* Strings+Untranslated.swift in Sources */, 066A1E9B94723EE9F3038044 /* Strings.swift in Sources */, + E290C78E7F09F47FD2662986 /* Task.swift in Sources */, 43FD77998F33C32718C51450 /* TemplateCoordinator.swift in Sources */, 63C9AF0FB8278AF1C0388A0C /* TemplateModels.swift in Sources */, 1555A7643D85187D4851040C /* TemplateScreen.swift in Sources */, @@ -2503,6 +2502,7 @@ 01CB8ACFA5E143E89C168CA8 /* TimelineItemContextMenu.swift in Sources */, 4D970CB606276717B43E2332 /* TimelineItemList.swift in Sources */, F508683B76EF7B23BB2CBD6D /* TimelineItemPlainStylerView.swift in Sources */, + 440123E29E2F9B001A775BBE /* TimelineItemProxy.swift in Sources */, 9B582B3EEFEA615D4A6FBF1A /* TimelineReactionsView.swift in Sources */, ABF3FAB234AD3565B214309B /* TimelineSenderAvatarView.swift in Sources */, 69BCBB4FB2DC3D61A28D3FD8 /* TimelineStyle.swift in Sources */, diff --git a/ElementX/Sources/Services/Room/RoomMessageFactory.swift b/ElementX/Sources/Services/Room/RoomMessageFactory.swift index 5ce7467c6..2d6d8f9e7 100644 --- a/ElementX/Sources/Services/Room/RoomMessageFactory.swift +++ b/ElementX/Sources/Services/Room/RoomMessageFactory.swift @@ -25,7 +25,10 @@ struct SomeRoomMessage: RoomMessageProtocol { } struct RoomMessageFactory: RoomMessageFactoryProtocol { - func buildRoomMessageFrom(_ eventItem: EventTimelineItem) -> RoomMessageProtocol { - SomeRoomMessage(id: eventItem.id, body: eventItem.body ?? "", sender: eventItem.sender, originServerTs: eventItem.originServerTs) + func buildRoomMessageFrom(_ eventItemProxy: EventTimelineItemProxy) -> RoomMessageProtocol { + SomeRoomMessage(id: eventItemProxy.id, + body: eventItemProxy.body ?? "", + sender: eventItemProxy.sender, + originServerTs: eventItemProxy.originServerTs) } } diff --git a/ElementX/Sources/Services/Room/RoomMessageFactoryProtocol.swift b/ElementX/Sources/Services/Room/RoomMessageFactoryProtocol.swift index 07003d714..a6421d42c 100644 --- a/ElementX/Sources/Services/Room/RoomMessageFactoryProtocol.swift +++ b/ElementX/Sources/Services/Room/RoomMessageFactoryProtocol.swift @@ -18,5 +18,5 @@ import Foundation import MatrixRustSDK protocol RoomMessageFactoryProtocol { - func buildRoomMessageFrom(_ message: EventTimelineItem) -> RoomMessageProtocol + func buildRoomMessageFrom(_ eventItemProxy: EventTimelineItemProxy) -> RoomMessageProtocol } diff --git a/ElementX/Sources/Services/Room/RoomSummary/RoomSummaryProvider.swift b/ElementX/Sources/Services/Room/RoomSummary/RoomSummaryProvider.swift index ac8b4fbb0..e0bf51b65 100644 --- a/ElementX/Sources/Services/Room/RoomSummary/RoomSummaryProvider.swift +++ b/ElementX/Sources/Services/Room/RoomSummary/RoomSummaryProvider.swift @@ -163,7 +163,7 @@ class RoomSummaryProvider: RoomSummaryProviderProtocol { var attributedLastMessage: AttributedString? var lastMessageTimestamp: Date? if let latestRoomMessage = room.latestRoomMessage() { - let lastMessage = roomMessageFactory.buildRoomMessageFrom(EventTimelineItem(item: latestRoomMessage)) + let lastMessage = roomMessageFactory.buildRoomMessageFrom(EventTimelineItemProxy(item: latestRoomMessage)) if let lastMessageSender = try? AttributedString(markdown: "**\(lastMessage.sender)**") { // Don't include the message body in the markdown otherwise it makes tappable links. attributedLastMessage = lastMessageSender + ": " + AttributedString(lastMessage.body) diff --git a/ElementX/Sources/Services/Timeline/MockRoomTimelineProvider.swift b/ElementX/Sources/Services/Timeline/MockRoomTimelineProvider.swift index 88f68b2f4..e8036f102 100644 --- a/ElementX/Sources/Services/Timeline/MockRoomTimelineProvider.swift +++ b/ElementX/Sources/Services/Timeline/MockRoomTimelineProvider.swift @@ -18,7 +18,7 @@ import Combine struct MockRoomTimelineProvider: RoomTimelineProviderProtocol { var callbacks = PassthroughSubject() - var items = [RoomTimelineProviderItem]() + var itemProxies = [TimelineItemProxy]() func paginateBackwards(_ count: UInt) async -> Result { .failure(.failedPaginatingBackwards) diff --git a/ElementX/Sources/Services/Timeline/RoomTimelineController.swift b/ElementX/Sources/Services/Timeline/RoomTimelineController.swift index 0e25b8b17..900dd057d 100644 --- a/ElementX/Sources/Services/Timeline/RoomTimelineController.swift +++ b/ElementX/Sources/Services/Timeline/RoomTimelineController.swift @@ -134,21 +134,21 @@ class RoomTimelineController: RoomTimelineControllerProtocol { private func asyncUpdateTimelineItems() async { var newTimelineItems = [RoomTimelineItemProtocol]() - for (index, item) in timelineProvider.items.enumerated() { + for (index, itemProxy) in timelineProvider.itemProxies.enumerated() { if Task.isCancelled { return } - let previousItem = timelineProvider.items[safe: index - 1] - let nextItem = timelineProvider.items[safe: index + 1] + let previousItemProxy = timelineProvider.itemProxies[safe: index - 1] + let nextItemProxy = timelineProvider.itemProxies[safe: index + 1] - let inGroupState = inGroupState(for: item, previousItem: previousItem, nextItem: nextItem) + let inGroupState = inGroupState(for: itemProxy, previousItemProxy: previousItemProxy, nextItemProxy: nextItemProxy) - switch item { + switch itemProxy { case .event(let eventItem): guard eventItem.isMessage || eventItem.isRedacted else { break } // To be handled in the future - newTimelineItems.append(await timelineItemFactory.buildTimelineItemFor(eventItem: eventItem, + newTimelineItems.append(await timelineItemFactory.buildTimelineItemFor(eventItemProxy: eventItem, showSenderDetails: inGroupState.shouldShowSenderDetails, inGroupState: inGroupState)) case .virtual: @@ -172,16 +172,16 @@ class RoomTimelineController: RoomTimelineControllerProtocol { callbacks.send(.updatedTimelineItems) } - private func inGroupState(for item: RoomTimelineProviderItem, - previousItem: RoomTimelineProviderItem?, - nextItem: RoomTimelineProviderItem?) -> TimelineItemInGroupState { - guard let previousItem = previousItem else { + private func inGroupState(for itemProxy: TimelineItemProxy, + previousItemProxy: TimelineItemProxy?, + nextItemProxy: TimelineItemProxy?) -> TimelineItemInGroupState { + guard let previousItem = previousItemProxy else { // no previous item, check next item - guard let nextItem = nextItem else { + guard let nextItem = nextItemProxy else { // no next item neither, this is single return .single } - guard nextItem.canBeGrouped(with: item) else { + guard nextItem.canBeGrouped(with: itemProxy) else { // there is a next item but can't be grouped, this is single return .single } @@ -189,9 +189,9 @@ class RoomTimelineController: RoomTimelineControllerProtocol { return .beginning } - guard let nextItem = nextItem else { + guard let nextItem = nextItemProxy else { // no next item - guard item.canBeGrouped(with: previousItem) else { + guard itemProxy.canBeGrouped(with: previousItem) else { // there is a previous item but can't be grouped, this is single return .single } @@ -199,8 +199,8 @@ class RoomTimelineController: RoomTimelineControllerProtocol { return .end } - guard item.canBeGrouped(with: previousItem) else { - guard nextItem.canBeGrouped(with: item) else { + guard itemProxy.canBeGrouped(with: previousItem) else { + guard nextItem.canBeGrouped(with: itemProxy) else { // there is a next item but can't be grouped, this is single return .single } @@ -208,7 +208,7 @@ class RoomTimelineController: RoomTimelineControllerProtocol { return .beginning } - guard nextItem.canBeGrouped(with: item) else { + guard nextItem.canBeGrouped(with: itemProxy) else { // there is a next item but can't be grouped, this is the end return .end } diff --git a/ElementX/Sources/Services/Timeline/RoomTimelineProvider.swift b/ElementX/Sources/Services/Timeline/RoomTimelineProvider.swift index 25e061ac2..37aa6e1a6 100644 --- a/ElementX/Sources/Services/Timeline/RoomTimelineProvider.swift +++ b/ElementX/Sources/Services/Timeline/RoomTimelineProvider.swift @@ -36,11 +36,11 @@ class RoomTimelineProvider: RoomTimelineProviderProtocol { let callbacks = PassthroughSubject() - private(set) var items: [RoomTimelineProviderItem] + private(set) var itemProxies: [TimelineItemProxy] init(roomProxy: RoomProxyProtocol) { self.roomProxy = roomProxy - items = [] + itemProxies = [] } func paginateBackwards(_ count: UInt) async -> Result { @@ -103,41 +103,41 @@ private extension RoomTimelineProvider { private func replaceItems(_ items: [MatrixRustSDK.TimelineItem]?) { guard let items = items else { return } - self.items = items.map(RoomTimelineProviderItem.init) + itemProxies = items.map(TimelineItemProxy.init) } private func insertItem(_ data: InsertAtData?) { guard let data = data else { return } - let item = RoomTimelineProviderItem(item: data.item) - items.insert(item, at: Int(data.index)) + let itemProxy = TimelineItemProxy(item: data.item) + itemProxies.insert(itemProxy, at: Int(data.index)) } private func updateItem(_ data: UpdateAtData?) { guard let data = data else { return } - let item = RoomTimelineProviderItem(item: data.item) - items[Int(data.index)] = item + let itemProxy = TimelineItemProxy(item: data.item) + itemProxies[Int(data.index)] = itemProxy } private func removeItem(at index: UInt32?) { guard let index = index else { return } - items.remove(at: Int(index)) + itemProxies.remove(at: Int(index)) } private func moveItem(_ data: MoveData?) { guard let data = data else { return } - items.move(fromOffsets: IndexSet(integer: Int(data.oldIndex)), toOffset: Int(data.newIndex)) + itemProxies.move(fromOffsets: IndexSet(integer: Int(data.oldIndex)), toOffset: Int(data.newIndex)) } private func pushItem(_ item: MatrixRustSDK.TimelineItem?) { guard let item = item else { return } - items.append(RoomTimelineProviderItem(item: item)) + itemProxies.append(TimelineItemProxy(item: item)) } private func popItem() { - items.removeLast() + itemProxies.removeLast() } private func clearAllItems() { - items.removeAll() + itemProxies.removeAll() } } diff --git a/ElementX/Sources/Services/Timeline/RoomTimelineProviderProtocol.swift b/ElementX/Sources/Services/Timeline/RoomTimelineProviderProtocol.swift index 547650c62..0480e5f07 100644 --- a/ElementX/Sources/Services/Timeline/RoomTimelineProviderProtocol.swift +++ b/ElementX/Sources/Services/Timeline/RoomTimelineProviderProtocol.swift @@ -32,7 +32,7 @@ enum RoomTimelineProviderError: Error { protocol RoomTimelineProviderProtocol { var callbacks: PassthroughSubject { get } - var items: [RoomTimelineProviderItem] { get } + var itemProxies: [TimelineItemProxy] { get } func paginateBackwards(_ count: UInt) async -> Result diff --git a/ElementX/Sources/Services/Timeline/RoomTimelineProviderItem.swift b/ElementX/Sources/Services/Timeline/TimelineItemProxy.swift similarity index 79% rename from ElementX/Sources/Services/Timeline/RoomTimelineProviderItem.swift rename to ElementX/Sources/Services/Timeline/TimelineItemProxy.swift index 73d8d9068..0d4dc634f 100644 --- a/ElementX/Sources/Services/Timeline/RoomTimelineProviderItem.swift +++ b/ElementX/Sources/Services/Timeline/TimelineItemProxy.swift @@ -16,15 +16,15 @@ import MatrixRustSDK -/// A light wrapper around timeline items returned from Rust for use in `RoomTimelineProvider`. -enum RoomTimelineProviderItem { - case event(EventTimelineItem) +/// A light wrapper around timeline items returned from Rust. +enum TimelineItemProxy { + case event(EventTimelineItemProxy) case virtual(MatrixRustSDK.VirtualTimelineItem) case other(MatrixRustSDK.TimelineItem) init(item: MatrixRustSDK.TimelineItem) { if let eventItem = item.asEvent() { - self = .event(EventTimelineItem(item: eventItem)) + self = .event(EventTimelineItemProxy(item: eventItem)) } else if let virtualItem = item.asVirtual() { self = .virtual(virtualItem) } else { @@ -32,17 +32,17 @@ enum RoomTimelineProviderItem { } } - func canBeGrouped(with prevItem: RoomTimelineProviderItem) -> Bool { - guard case let .event(selfEventItem) = self, case let .event(prevEventItem) = prevItem else { + func canBeGrouped(with previousItemProxy: TimelineItemProxy) -> Bool { + guard case let .event(selfEventItemProxy) = self, case let .event(previousEventItemProxy) = previousItemProxy else { return false } // can be improved by adding a date threshold - return prevEventItem.reactions.isEmpty && selfEventItem.sender == prevEventItem.sender + return previousEventItemProxy.reactions.isEmpty && selfEventItemProxy.sender == previousEventItemProxy.sender } } -/// A light wrapper around event timeline items returned from Rust, used in `RoomTimelineProviderItem`. -struct EventTimelineItem { +/// A light wrapper around event timeline items returned from Rust. +struct EventTimelineItemProxy { let item: MatrixRustSDK.EventTimelineItem init(item: MatrixRustSDK.EventTimelineItem) { diff --git a/ElementX/Sources/Services/Timeline/TimelineItems/RoomTimelineItemFactory.swift b/ElementX/Sources/Services/Timeline/TimelineItems/RoomTimelineItemFactory.swift index cbb2f05ef..8c6a6725c 100644 --- a/ElementX/Sources/Services/Timeline/TimelineItems/RoomTimelineItemFactory.swift +++ b/ElementX/Sources/Services/Timeline/TimelineItems/RoomTimelineItemFactory.swift @@ -35,35 +35,35 @@ struct RoomTimelineItemFactory: RoomTimelineItemFactoryProtocol { self.attributedStringBuilder = attributedStringBuilder } - func buildTimelineItemFor(eventItem: EventTimelineItem, + func buildTimelineItemFor(eventItemProxy: EventTimelineItemProxy, showSenderDetails: Bool, inGroupState: TimelineItemInGroupState) async -> RoomTimelineItemProtocol { - let displayName = roomProxy.displayNameForUserId(eventItem.sender) - let avatarURL = roomProxy.avatarURLStringForUserId(eventItem.sender) + let displayName = roomProxy.displayNameForUserId(eventItemProxy.sender) + let avatarURL = roomProxy.avatarURLStringForUserId(eventItemProxy.sender) let avatarImage = mediaProvider.imageFromURLString(avatarURL, size: MediaProviderDefaultAvatarSize) - let isOutgoing = eventItem.isOwn + let isOutgoing = eventItemProxy.isOwn - if eventItem.isRedacted { - return buildRedactedTimelineItemFromEvent(eventItem, isOutgoing, showSenderDetails, inGroupState, displayName, avatarImage) + if eventItemProxy.isRedacted { + return buildRedactedTimelineItem(eventItemProxy, isOutgoing, showSenderDetails, inGroupState, displayName, avatarImage) } - guard let messageContent = eventItem.content.asMessage() else { fatalError("Must be a message for now.") } + guard let messageContent = eventItemProxy.content.asMessage() else { fatalError("Must be a message for now.") } switch messageContent.msgtype() { case .text(content: let content): - let message = MessageTimelineItem(item: eventItem.item, content: content) + let message = MessageTimelineItem(item: eventItemProxy.item, content: content) return await buildTextTimelineItemFromMessage(message, isOutgoing, showSenderDetails, inGroupState, displayName, avatarImage) case .image(content: let content): - let message = MessageTimelineItem(item: eventItem.item, content: content) + let message = MessageTimelineItem(item: eventItemProxy.item, content: content) return await buildImageTimelineItemFromMessage(message, isOutgoing, showSenderDetails, inGroupState, displayName, avatarImage) case .notice(content: let content): - let message = MessageTimelineItem(item: eventItem.item, content: content) + let message = MessageTimelineItem(item: eventItemProxy.item, content: content) return await buildNoticeTimelineItemFromMessage(message, isOutgoing, showSenderDetails, inGroupState, displayName, avatarImage) case .emote(content: let content): - let message = MessageTimelineItem(item: eventItem.item, content: content) + let message = MessageTimelineItem(item: eventItemProxy.item, content: content) return await buildEmoteTimelineItemFromMessage(message, isOutgoing, showSenderDetails, inGroupState, displayName, avatarImage) case .none: - return await buildFallbackTimelineItem(eventItem, isOutgoing, showSenderDetails, inGroupState, displayName, avatarImage) + return await buildFallbackTimelineItem(eventItemProxy, isOutgoing, showSenderDetails, inGroupState, displayName, avatarImage) } } @@ -71,45 +71,45 @@ struct RoomTimelineItemFactory: RoomTimelineItemFactoryProtocol { // swiftformat:disable function_parameter_count // swiftlint:disable function_parameter_count - private func buildRedactedTimelineItemFromEvent(_ event: EventTimelineItem, - _ isOutgoing: Bool, - _ showSenderDetails: Bool, - _ inGroupState: TimelineItemInGroupState, - _ displayName: String?, - _ avatarImage: UIImage?) -> RoomTimelineItemProtocol { - RedactedRoomTimelineItem(id: event.id, + private func buildRedactedTimelineItem(_ eventItemProxy: EventTimelineItemProxy, + _ isOutgoing: Bool, + _ showSenderDetails: Bool, + _ inGroupState: TimelineItemInGroupState, + _ displayName: String?, + _ avatarImage: UIImage?) -> RoomTimelineItemProtocol { + RedactedRoomTimelineItem(id: eventItemProxy.id, text: ElementL10n.eventRedacted, - timestamp: event.originServerTs.formatted(date: .omitted, time: .shortened), + timestamp: eventItemProxy.originServerTs.formatted(date: .omitted, time: .shortened), shouldShowSenderDetails: showSenderDetails, inGroupState: inGroupState, isOutgoing: isOutgoing, - senderId: event.sender, + senderId: eventItemProxy.sender, senderDisplayName: displayName, senderAvatar: avatarImage, properties: RoomTimelineItemProperties()) } - private func buildFallbackTimelineItem(_ item: EventTimelineItem, + private func buildFallbackTimelineItem(_ eventItemProxy: EventTimelineItemProxy, _ isOutgoing: Bool, _ showSenderDetails: Bool, _ inGroupState: TimelineItemInGroupState, _ displayName: String?, _ avatarImage: UIImage?) async -> RoomTimelineItemProtocol { - let attributedText = await attributedStringBuilder.fromPlain(item.body) + let attributedText = await attributedStringBuilder.fromPlain(eventItemProxy.body) let attributedComponents = attributedStringBuilder.blockquoteCoalescedComponentsFrom(attributedText) - return TextRoomTimelineItem(id: item.id, - text: item.body ?? "", + return TextRoomTimelineItem(id: eventItemProxy.id, + text: eventItemProxy.body ?? "", attributedComponents: attributedComponents, - timestamp: item.originServerTs.formatted(date: .omitted, time: .shortened), + timestamp: eventItemProxy.originServerTs.formatted(date: .omitted, time: .shortened), shouldShowSenderDetails: showSenderDetails, inGroupState: inGroupState, isOutgoing: isOutgoing, - senderId: item.sender, + senderId: eventItemProxy.sender, senderDisplayName: displayName, senderAvatar: avatarImage, - properties: RoomTimelineItemProperties(isEdited: item.content.asMessage()?.isEdited() ?? false, - reactions: aggregateReactions(item.reactions))) + properties: RoomTimelineItemProperties(isEdited: eventItemProxy.content.asMessage()?.isEdited() ?? false, + reactions: aggregateReactions(eventItemProxy.reactions))) } private func buildTextTimelineItemFromMessage(_ message: MessageTimelineItem, diff --git a/ElementX/Sources/Services/Timeline/TimelineItems/RoomTimelineItemFactoryProtocol.swift b/ElementX/Sources/Services/Timeline/TimelineItems/RoomTimelineItemFactoryProtocol.swift index ff40761d0..eb8a8cf9c 100644 --- a/ElementX/Sources/Services/Timeline/TimelineItems/RoomTimelineItemFactoryProtocol.swift +++ b/ElementX/Sources/Services/Timeline/TimelineItems/RoomTimelineItemFactoryProtocol.swift @@ -18,7 +18,7 @@ import Foundation @MainActor protocol RoomTimelineItemFactoryProtocol { - func buildTimelineItemFor(eventItem: EventTimelineItem, + func buildTimelineItemFor(eventItemProxy: EventTimelineItemProxy, showSenderDetails: Bool, inGroupState: TimelineItemInGroupState) async -> RoomTimelineItemProtocol } diff --git a/changelog.d/162.change b/changelog.d/162.change new file mode 100644 index 000000000..0bb45e2a4 --- /dev/null +++ b/changelog.d/162.change @@ -0,0 +1 @@ +Rename RoomTimelineProviderItem to TimelineItemProxy for clarity.