diff --git a/ElementX.xcodeproj/project.pbxproj b/ElementX.xcodeproj/project.pbxproj index ed9fca40d..ad6dc1bac 100644 --- a/ElementX.xcodeproj/project.pbxproj +++ b/ElementX.xcodeproj/project.pbxproj @@ -16,13 +16,18 @@ 1850256F27B6A135002E6B18 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1850256527B6A135002E6B18 /* AppDelegate.swift */; }; 1850257027B6A135002E6B18 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 1850256827B6A135002E6B18 /* Assets.xcassets */; }; 1850257127B6A135002E6B18 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 1850256927B6A135002E6B18 /* LaunchScreen.storyboard */; }; - 1859CF5527D7A6FF00E86E4E /* MatrixRustSDK in Frameworks */ = {isa = PBXBuildFile; productRef = 1859CF5427D7A6FF00E86E4E /* MatrixRustSDK */; }; 1863A3FC27BA5A9100B52E4D /* KeychainAccess in Frameworks */ = {isa = PBXBuildFile; productRef = 1863A3FB27BA5A9100B52E4D /* KeychainAccess */; }; 1863A40627BA6DFC00B52E4D /* SwiftyBeaver in Frameworks */ = {isa = PBXBuildFile; productRef = 1863A40527BA6DFC00B52E4D /* SwiftyBeaver */; }; 18A318DD27DA42C9000867CD /* RoomTimelineViewProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 18A318DB27DA42C9000867CD /* RoomTimelineViewProvider.swift */; }; - 18F2BAD727D25B4000DD1988 /* RoomProxyProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 18F2BA7327D25B4000DD1988 /* RoomProxyProtocol.swift */; }; - 18F2BAD827D25B4000DD1988 /* RoomProxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 18F2BA7427D25B4000DD1988 /* RoomProxy.swift */; }; - 18F2BAD927D25B4000DD1988 /* MockRoomProxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 18F2BA7527D25B4000DD1988 /* MockRoomProxy.swift */; }; + 18C5744627E11F1900D70937 /* MatrixRustSDK in Frameworks */ = {isa = PBXBuildFile; productRef = 18C5744527E11F1900D70937 /* MatrixRustSDK */; }; + 18C5744C27E1D84000D70937 /* RoomProxyProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 18C5744827E1D84000D70937 /* RoomProxyProtocol.swift */; }; + 18C5744D27E1D84000D70937 /* RoomProxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 18C5744A27E1D84000D70937 /* RoomProxy.swift */; }; + 18C5744E27E1D84000D70937 /* MockRoomProxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 18C5744B27E1D84000D70937 /* MockRoomProxy.swift */; }; + 18C5745027E1D87800D70937 /* RoomMessageProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 18C5744F27E1D87800D70937 /* RoomMessageProtocol.swift */; }; + 18C5745227E1D88600D70937 /* ImageRoomMessage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 18C5745127E1D88600D70937 /* ImageRoomMessage.swift */; }; + 18C5745427E1D88E00D70937 /* TextRoomMessage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 18C5745327E1D88E00D70937 /* TextRoomMessage.swift */; }; + 18C5745627E1DCA800D70937 /* RoomMessageFactory.swift in Sources */ = {isa = PBXBuildFile; fileRef = 18C5745527E1DCA800D70937 /* RoomMessageFactory.swift */; }; + 18C5745827E1EB6E00D70937 /* TimelineItemFactory.swift in Sources */ = {isa = PBXBuildFile; fileRef = 18C5745727E1EB6E00D70937 /* TimelineItemFactory.swift */; }; 18F2BADA27D25B4000DD1988 /* RoomTimelineProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 18F2BA7727D25B4000DD1988 /* RoomTimelineProvider.swift */; }; 18F2BADB27D25B4000DD1988 /* AuthenticationCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 18F2BA7927D25B4000DD1988 /* AuthenticationCoordinator.swift */; }; 18F2BADC27D25B4000DD1988 /* UserSession.swift in Sources */ = {isa = PBXBuildFile; fileRef = 18F2BA7A27D25B4000DD1988 /* UserSession.swift */; }; @@ -106,6 +111,7 @@ /* End PBXContainerItemProxy section */ /* Begin PBXFileReference section */ + 181716DC27E11EF1002B8E3F /* matrix-rust-components-swift */ = {isa = PBXFileReference; lastKnownFileType = wrapper; name = "matrix-rust-components-swift"; path = "../matrix-rust-components-swift"; sourceTree = ""; }; 1850252427B6918C002E6B18 /* ElementX.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = ElementX.app; sourceTree = BUILT_PRODUCTS_DIR; }; 1850253A27B6918D002E6B18 /* ElementXTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = ElementXTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 1850253E27B6918D002E6B18 /* ElementXTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ElementXTests.swift; sourceTree = ""; }; @@ -118,9 +124,14 @@ 1850256827B6A135002E6B18 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 1850256A27B6A135002E6B18 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 18A318DB27DA42C9000867CD /* RoomTimelineViewProvider.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RoomTimelineViewProvider.swift; sourceTree = ""; }; - 18F2BA7327D25B4000DD1988 /* RoomProxyProtocol.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RoomProxyProtocol.swift; sourceTree = ""; }; - 18F2BA7427D25B4000DD1988 /* RoomProxy.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RoomProxy.swift; sourceTree = ""; }; - 18F2BA7527D25B4000DD1988 /* MockRoomProxy.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MockRoomProxy.swift; sourceTree = ""; }; + 18C5744827E1D84000D70937 /* RoomProxyProtocol.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RoomProxyProtocol.swift; sourceTree = ""; }; + 18C5744A27E1D84000D70937 /* RoomProxy.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RoomProxy.swift; sourceTree = ""; }; + 18C5744B27E1D84000D70937 /* MockRoomProxy.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MockRoomProxy.swift; sourceTree = ""; }; + 18C5744F27E1D87800D70937 /* RoomMessageProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomMessageProtocol.swift; sourceTree = ""; }; + 18C5745127E1D88600D70937 /* ImageRoomMessage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ImageRoomMessage.swift; sourceTree = ""; }; + 18C5745327E1D88E00D70937 /* TextRoomMessage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TextRoomMessage.swift; sourceTree = ""; }; + 18C5745527E1DCA800D70937 /* RoomMessageFactory.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomMessageFactory.swift; sourceTree = ""; }; + 18C5745727E1EB6E00D70937 /* TimelineItemFactory.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimelineItemFactory.swift; sourceTree = ""; }; 18F2BA7727D25B4000DD1988 /* RoomTimelineProvider.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RoomTimelineProvider.swift; sourceTree = ""; }; 18F2BA7927D25B4000DD1988 /* AuthenticationCoordinator.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AuthenticationCoordinator.swift; sourceTree = ""; }; 18F2BA7A27D25B4000DD1988 /* UserSession.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UserSession.swift; sourceTree = ""; }; @@ -194,8 +205,8 @@ files = ( 182BC48127C4EBBB00A30C33 /* Kingfisher in Frameworks */, 1863A3FC27BA5A9100B52E4D /* KeychainAccess in Frameworks */, + 18C5744627E11F1900D70937 /* MatrixRustSDK in Frameworks */, 184B31DF27D898960075A669 /* Introspect in Frameworks */, - 1859CF5527D7A6FF00E86E4E /* MatrixRustSDK in Frameworks */, 1863A40627BA6DFC00B52E4D /* SwiftyBeaver in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; @@ -220,10 +231,12 @@ 1850251B27B6918C002E6B18 = { isa = PBXGroup; children = ( + 181716DC27E11EF1002B8E3F /* matrix-rust-components-swift */, 1850252627B6918C002E6B18 /* ElementX */, 1850253D27B6918D002E6B18 /* ElementXTests */, 1850254727B6918D002E6B18 /* ElementXUITests */, 1850252527B6918C002E6B18 /* Products */, + 18C5744427E11F1900D70937 /* Frameworks */, ); sourceTree = ""; }; @@ -289,6 +302,7 @@ 18A318D927DA42C9000867CD /* TimelineItems */ = { isa = PBXGroup; children = ( + 18C5745727E1EB6E00D70937 /* TimelineItemFactory.swift */, 18A318DB27DA42C9000867CD /* RoomTimelineViewProvider.swift */, 18F9889727DB7473002F48B4 /* ImageRoomTimelineItem.swift */, 18F9889D27DB752B002F48B4 /* ImageRoomTimelineView.swift */, @@ -300,14 +314,41 @@ path = TimelineItems; sourceTree = ""; }; + 18C5744427E11F1900D70937 /* Frameworks */ = { + isa = PBXGroup; + children = ( + ); + name = Frameworks; + sourceTree = ""; + }; + 18C5744727E1D84000D70937 /* Room */ = { + isa = PBXGroup; + children = ( + 18C5744927E1D84000D70937 /* Messages */, + 18C5744827E1D84000D70937 /* RoomProxyProtocol.swift */, + 18C5744A27E1D84000D70937 /* RoomProxy.swift */, + 18C5744B27E1D84000D70937 /* MockRoomProxy.swift */, + ); + path = Room; + sourceTree = ""; + }; + 18C5744927E1D84000D70937 /* Messages */ = { + isa = PBXGroup; + children = ( + 18C5745527E1DCA800D70937 /* RoomMessageFactory.swift */, + 18C5744F27E1D87800D70937 /* RoomMessageProtocol.swift */, + 18C5745327E1D88E00D70937 /* TextRoomMessage.swift */, + 18C5745127E1D88600D70937 /* ImageRoomMessage.swift */, + ); + path = Messages; + sourceTree = ""; + }; 18F2BA7227D25B4000DD1988 /* Services */ = { isa = PBXGroup; children = ( 18F2BA7827D25B4000DD1988 /* Authentication */, + 18C5744727E1D84000D70937 /* Room */, 18F2BA7627D25B4000DD1988 /* Timeline */, - 18F2BA7327D25B4000DD1988 /* RoomProxyProtocol.swift */, - 18F2BA7427D25B4000DD1988 /* RoomProxy.swift */, - 18F2BA7527D25B4000DD1988 /* MockRoomProxy.swift */, ); path = Services; sourceTree = ""; @@ -603,8 +644,8 @@ 1863A3FB27BA5A9100B52E4D /* KeychainAccess */, 1863A40527BA6DFC00B52E4D /* SwiftyBeaver */, 182BC48027C4EBBB00A30C33 /* Kingfisher */, - 1859CF5427D7A6FF00E86E4E /* MatrixRustSDK */, 184B31DE27D898960075A669 /* Introspect */, + 18C5744527E11F1900D70937 /* MatrixRustSDK */, ); productName = ElementX; productReference = 1850252427B6918C002E6B18 /* ElementX.app */; @@ -683,7 +724,6 @@ 1863A3FA27BA5A9100B52E4D /* XCRemoteSwiftPackageReference "KeychainAccess" */, 1863A40427BA6DFC00B52E4D /* XCRemoteSwiftPackageReference "SwiftyBeaver" */, 182BC47F27C4EBBB00A30C33 /* XCRemoteSwiftPackageReference "Kingfisher" */, - 1859CF5327D7A6FF00E86E4E /* XCRemoteSwiftPackageReference "matrix-rust-components-swift" */, 184B31DD27D898960075A669 /* XCRemoteSwiftPackageReference "SwiftUI-Introspect" */, ); productRefGroup = 1850252527B6918C002E6B18 /* Products */; @@ -750,6 +790,7 @@ buildActionMask = 2147483647; files = ( 18F2BADE27D25B4000DD1988 /* KeychainControllerProtocol.swift in Sources */, + 18C5745027E1D87800D70937 /* RoomMessageProtocol.swift in Sources */, 18F2BAED27D25B4000DD1988 /* FullscreenLoadingActivityPresenter.swift in Sources */, 18F2BB0F27D25B4000DD1988 /* RoomScreen.swift in Sources */, 18F2BAFF27D25B4000DD1988 /* HomeScreenModels.swift in Sources */, @@ -761,7 +802,6 @@ 18F2BAE327D25B4000DD1988 /* RootRouter.swift in Sources */, 18F2BAE527D25B4000DD1988 /* NavigationModule.swift in Sources */, 18F2BB1227D25B4000DD1988 /* LoginScreenViewModel.swift in Sources */, - 18F2BAD927D25B4000DD1988 /* MockRoomProxy.swift in Sources */, 18F2BAE727D25B4000DD1988 /* RoundedToastView.swift in Sources */, 18F2BAF227D25B4000DD1988 /* WeakDictionaryKeyReference.swift in Sources */, 18F988A027DB7532002F48B4 /* TextRoomTimelineView.swift in Sources */, @@ -774,16 +814,15 @@ 18F2BAF127D25B4000DD1988 /* MXLog.swift in Sources */, 18F2BAF727D25B4000DD1988 /* StateStoreViewModel.swift in Sources */, 18F2BAF427D25B4000DD1988 /* WeakDictionary.swift in Sources */, + 18C5745627E1DCA800D70937 /* RoomMessageFactory.swift in Sources */, 18F2BB1127D25B4000DD1988 /* RoomScreenModels.swift in Sources */, 18F2BADB27D25B4000DD1988 /* AuthenticationCoordinator.swift in Sources */, 1850256F27B6A135002E6B18 /* AppDelegate.swift in Sources */, 18F2BAE627D25B4000DD1988 /* NavigationRouterType.swift in Sources */, 18F2BAE927D25B4000DD1988 /* ActivityPresentable.swift in Sources */, 18F2BAF827D25B4000DD1988 /* BindableState.swift in Sources */, - 18F2BAD827D25B4000DD1988 /* RoomProxy.swift in Sources */, 18F2BB1827D25B4000DD1988 /* LoginScreen.swift in Sources */, 18F2BAE227D25B4000DD1988 /* NavigationRouterStoreProtocol.swift in Sources */, - 18F2BAD727D25B4000DD1988 /* RoomProxyProtocol.swift in Sources */, 18F2BB1727D25B4000DD1988 /* LoginScreenCoordinator.swift in Sources */, 18F2BAF527D25B4000DD1988 /* WeakKeyDictionary.swift in Sources */, 18F2BADF27D25B4000DD1988 /* NavigationRouterStore.swift in Sources */, @@ -792,6 +831,7 @@ 18F2BB1627D25B4000DD1988 /* LoginScreenModels.swift in Sources */, 18F9889E27DB752B002F48B4 /* ImageRoomTimelineView.swift in Sources */, 18F2BADA27D25B4000DD1988 /* RoomTimelineProvider.swift in Sources */, + 18C5744D27E1D84000D70937 /* RoomProxy.swift in Sources */, 18F9889827DB7473002F48B4 /* ImageRoomTimelineItem.swift in Sources */, 18F2BB0027D25B4000DD1988 /* HomeScreen.swift in Sources */, 18F2BB2827D2647A00DD1988 /* MockRoomTimelineController.swift in Sources */, @@ -804,11 +844,16 @@ 18F2BB0E27D25B4000DD1988 /* RoomScreenViewModelProtocol.swift in Sources */, 18F2BB0D27D25B4000DD1988 /* RoomScreenViewModel.swift in Sources */, 18F988A227DB753B002F48B4 /* SeparatorRoomTimelineView.swift in Sources */, + 18C5745427E1D88E00D70937 /* TextRoomMessage.swift in Sources */, + 18C5745227E1D88600D70937 /* ImageRoomMessage.swift in Sources */, 18F2BAE127D25B4000DD1988 /* RootRouterType.swift in Sources */, 1850256C27B6A135002E6B18 /* AppCoordinator.swift in Sources */, 18F9889A27DB747B002F48B4 /* TextRoomTimelineItem.swift in Sources */, + 18C5744C27E1D84000D70937 /* RoomProxyProtocol.swift in Sources */, + 18C5744E27E1D84000D70937 /* MockRoomProxy.swift in Sources */, 18F2BADC27D25B4000DD1988 /* UserSession.swift in Sources */, 18F2BAEF27D25B4000DD1988 /* ActivityRequest.swift in Sources */, + 18C5745827E1EB6E00D70937 /* TimelineItemFactory.swift in Sources */, 18F2BAEE27D25B4000DD1988 /* Activity.swift in Sources */, 18F2BAEC27D25B4000DD1988 /* ToastActivityPresenter.swift in Sources */, ); @@ -1176,14 +1221,6 @@ kind = branch; }; }; - 1859CF5327D7A6FF00E86E4E /* XCRemoteSwiftPackageReference "matrix-rust-components-swift" */ = { - isa = XCRemoteSwiftPackageReference; - repositoryURL = "https://github.com/matrix-org/matrix-rust-components-swift.git"; - requirement = { - branch = main; - kind = branch; - }; - }; 1863A3FA27BA5A9100B52E4D /* XCRemoteSwiftPackageReference "KeychainAccess" */ = { isa = XCRemoteSwiftPackageReference; repositoryURL = "https://github.com/kishikawakatsumi/KeychainAccess"; @@ -1213,11 +1250,6 @@ package = 184B31DD27D898960075A669 /* XCRemoteSwiftPackageReference "SwiftUI-Introspect" */; productName = Introspect; }; - 1859CF5427D7A6FF00E86E4E /* MatrixRustSDK */ = { - isa = XCSwiftPackageProductDependency; - package = 1859CF5327D7A6FF00E86E4E /* XCRemoteSwiftPackageReference "matrix-rust-components-swift" */; - productName = MatrixRustSDK; - }; 1863A3FB27BA5A9100B52E4D /* KeychainAccess */ = { isa = XCSwiftPackageProductDependency; package = 1863A3FA27BA5A9100B52E4D /* XCRemoteSwiftPackageReference "KeychainAccess" */; @@ -1228,6 +1260,10 @@ package = 1863A40427BA6DFC00B52E4D /* XCRemoteSwiftPackageReference "SwiftyBeaver" */; productName = SwiftyBeaver; }; + 18C5744527E11F1900D70937 /* MatrixRustSDK */ = { + isa = XCSwiftPackageProductDependency; + productName = MatrixRustSDK; + }; /* End XCSwiftPackageProductDependency section */ }; rootObject = 1850251C27B6918C002E6B18 /* Project object */; diff --git a/ElementX.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/ElementX.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved index 9c38438b5..d7bd6ea04 100644 --- a/ElementX.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/ElementX.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -19,15 +19,6 @@ "version": "7.2.0" } }, - { - "package": "MatrixRustSDK", - "repositoryURL": "https://github.com/matrix-org/matrix-rust-components-swift.git", - "state": { - "branch": "main", - "revision": "6741f728fedbceb53154c043486dc1790ed37811", - "version": null - } - }, { "package": "Introspect", "repositoryURL": "https://github.com/siteline/SwiftUI-Introspect.git", diff --git a/ElementX/Sources/Screens/HomeScreen/HomeScreenViewModel.swift b/ElementX/Sources/Screens/HomeScreen/HomeScreenViewModel.swift index 00006ab65..5dfd9f1ed 100644 --- a/ElementX/Sources/Screens/HomeScreen/HomeScreenViewModel.swift +++ b/ElementX/Sources/Screens/HomeScreen/HomeScreenViewModel.swift @@ -177,7 +177,7 @@ class HomeScreenViewModel: HomeScreenViewModelType, HomeScreenViewModelProtocol return } - self.updateLastMessage(lastMessage.content(), forRoomWithIdentifier: roomIdentifier) + self.updateLastMessage(lastMessage.content, forRoomWithIdentifier: roomIdentifier) default: break } diff --git a/ElementX/Sources/Services/Authentication/UserSession.swift b/ElementX/Sources/Services/Authentication/UserSession.swift index 4dc7e7483..402dcc294 100644 --- a/ElementX/Sources/Services/Authentication/UserSession.swift +++ b/ElementX/Sources/Services/Authentication/UserSession.swift @@ -110,7 +110,7 @@ class UserSession: ClientDelegate { func fetchRoomList(_ completion: @escaping ([RoomProxy]) -> Void) { DispatchQueue.global(qos: .background).async { let rooms = self.client.conversations().map { - return RoomProxy(room: $0) + return RoomProxy(room: $0, messageFactory: RoomMessageFactory()) } DispatchQueue.main.async { diff --git a/ElementX/Sources/Services/Room/Messages/ImageRoomMessage.swift b/ElementX/Sources/Services/Room/Messages/ImageRoomMessage.swift new file mode 100644 index 000000000..c7e2f3d6d --- /dev/null +++ b/ElementX/Sources/Services/Room/Messages/ImageRoomMessage.swift @@ -0,0 +1,34 @@ +// +// ImageRoomMessage.swift +// ElementX +// +// Created by Stefan Ceriu on 16/03/2022. +// Copyright © 2022 Element. All rights reserved. +// + +import Foundation +import MatrixRustSDK + +struct ImageRoomMessage: RoomMessageProtocol { + private let message: MatrixRustSDK.ImageMessage + + init(message: MatrixRustSDK.ImageMessage) { + self.message = message + } + + var id: String { + message.baseMessage().id() + } + + var content: String { + message.baseMessage().content() + } + + var sender: String { + message.baseMessage().sender() + } + + var originServerTs: Date { + Date(timeIntervalSince1970: TimeInterval(message.baseMessage().originServerTs())) + } +} diff --git a/ElementX/Sources/Services/Room/Messages/RoomMessageFactory.swift b/ElementX/Sources/Services/Room/Messages/RoomMessageFactory.swift new file mode 100644 index 000000000..5a95dfc4f --- /dev/null +++ b/ElementX/Sources/Services/Room/Messages/RoomMessageFactory.swift @@ -0,0 +1,22 @@ +// +// RoomMessageFactory.swift +// ElementX +// +// Created by Stefan Ceriu on 16/03/2022. +// Copyright © 2022 Element. All rights reserved. +// + +import Foundation +import MatrixRustSDK + +struct RoomMessageFactory { + func buildRoomMessageFrom(_ message: AnyMessage) -> RoomMessageProtocol { + if let textMessage = message.text() { + return TextRoomMessage(message: textMessage) + } else if let imageMessage = message.image() { + return ImageRoomMessage(message: imageMessage) + } else { + fatalError("One of these must exist") + } + } +} diff --git a/ElementX/Sources/Services/Room/Messages/RoomMessageProtocol.swift b/ElementX/Sources/Services/Room/Messages/RoomMessageProtocol.swift new file mode 100644 index 000000000..13c97b5ad --- /dev/null +++ b/ElementX/Sources/Services/Room/Messages/RoomMessageProtocol.swift @@ -0,0 +1,16 @@ +// +// RoomMessageProtocol.swift +// ElementX +// +// Created by Stefan Ceriu on 16/03/2022. +// Copyright © 2022 Element. All rights reserved. +// + +import Foundation + +protocol RoomMessageProtocol { + var id: String { get } + var content: String { get } + var sender: String { get } + var originServerTs: Date { get } +} diff --git a/ElementX/Sources/Services/Room/Messages/TextRoomMessage.swift b/ElementX/Sources/Services/Room/Messages/TextRoomMessage.swift new file mode 100644 index 000000000..0622860d7 --- /dev/null +++ b/ElementX/Sources/Services/Room/Messages/TextRoomMessage.swift @@ -0,0 +1,35 @@ +// +// TextRoomMessage.swift +// ElementX +// +// Created by Stefan Ceriu on 16/03/2022. +// Copyright © 2022 Element. All rights reserved. +// + +import Foundation +import UIKit +import MatrixRustSDK + +struct TextRoomMessage: RoomMessageProtocol { + private let message: MatrixRustSDK.TextMessage + + init(message: MatrixRustSDK.TextMessage) { + self.message = message + } + + var id: String { + message.baseMessage().id() + } + + var content: String { + message.baseMessage().content() + } + + var sender: String { + message.baseMessage().sender() + } + + var originServerTs: Date { + Date(timeIntervalSince1970: TimeInterval(message.baseMessage().originServerTs())) + } +} diff --git a/ElementX/Sources/Services/MockRoomProxy.swift b/ElementX/Sources/Services/Room/MockRoomProxy.swift similarity index 90% rename from ElementX/Sources/Services/MockRoomProxy.swift rename to ElementX/Sources/Services/Room/MockRoomProxy.swift index d53eea733..933469ebe 100644 --- a/ElementX/Sources/Services/MockRoomProxy.swift +++ b/ElementX/Sources/Services/Room/MockRoomProxy.swift @@ -39,7 +39,7 @@ struct MockRoomProxy: RoomProxyProtocol { } - func paginateBackwards(count: UInt, callback: ((Result<[Message], Error>) -> Void)?) { + func paginateBackwards(count: UInt, callback: ((Result<[RoomMessageProtocol], Error>) -> Void)?) { } } diff --git a/ElementX/Sources/Services/RoomProxy.swift b/ElementX/Sources/Services/Room/RoomProxy.swift similarity index 83% rename from ElementX/Sources/Services/RoomProxy.swift rename to ElementX/Sources/Services/Room/RoomProxy.swift index cf3586846..068902a66 100644 --- a/ElementX/Sources/Services/RoomProxy.swift +++ b/ElementX/Sources/Services/Room/RoomProxy.swift @@ -26,7 +26,7 @@ private class WeakRoomProxyWrapper: RoomDelegate { // MARK: - RoomDelegate - func didReceiveMessage(message: Message) { + func didReceiveMessage(message: AnyMessage) { DispatchQueue.main.async { self.roomProxy?.appendMessage(message) } @@ -35,14 +35,16 @@ private class WeakRoomProxyWrapper: RoomDelegate { class RoomProxy: RoomProxyProtocol, Equatable { private let room: Room + private let messageFactory: RoomMessageFactory private let processingQueue: DispatchQueue private var backwardStream: BackwardsStreamProtocol? let callbacks = PassthroughSubject() - init(room: Room) { + init(room: Room, messageFactory: RoomMessageFactory) { self.room = room + self.messageFactory = messageFactory processingQueue = DispatchQueue(label: "RoomProxyProcessingQueue") processingQueue.async { @@ -130,7 +132,8 @@ class RoomProxy: RoomProxyProtocol, Equatable { } } - func paginateBackwards(count: UInt, callback: ((Result<[Message], Error>) -> Void)?) { + func paginateBackwards(count: UInt, callback: ((Result<[RoomMessageProtocol], Error>) -> Void)?) { + MXLog.debug("Started backpaginating") processingQueue.async { guard let backwardStream = self.backwardStream else { DispatchQueue.main.async { @@ -139,13 +142,16 @@ class RoomProxy: RoomProxyProtocol, Equatable { return } - let messages = backwardStream.paginateBackwards(count: UInt64(count)) + let messages = backwardStream.paginateBackwards(count: UInt64(count)).map { message in + self.messageFactory.buildRoomMessageFrom(message) + } + + MXLog.debug("Finished backpaginating") DispatchQueue.main.async { callback?(.success(messages)) - if self.lastMessage == nil { - self.lastMessage = messages.last?.content() ?? "" + self.lastMessage = messages.last?.content ?? "" } } } @@ -159,12 +165,9 @@ class RoomProxy: RoomProxyProtocol, Equatable { // MARK: - Private - fileprivate func preprendMessages(_ messages: [Message]) { - - } - - fileprivate func appendMessage(_ message: Message) { - lastMessage = message.content() + fileprivate func appendMessage(_ message: AnyMessage) { + let message = self.messageFactory.buildRoomMessageFrom(message) + lastMessage = message.content callbacks.send(.addedMessage(message)) } diff --git a/ElementX/Sources/Services/RoomProxyProtocol.swift b/ElementX/Sources/Services/Room/RoomProxyProtocol.swift similarity index 84% rename from ElementX/Sources/Services/RoomProxyProtocol.swift rename to ElementX/Sources/Services/Room/RoomProxyProtocol.swift index 6dd360095..18becfd48 100644 --- a/ElementX/Sources/Services/RoomProxyProtocol.swift +++ b/ElementX/Sources/Services/Room/RoomProxyProtocol.swift @@ -10,7 +10,7 @@ import Combine import MatrixRustSDK enum RoomProxyCallback { - case addedMessage(Message) + case addedMessage(RoomMessageProtocol) case updatedLastMessage } @@ -31,7 +31,7 @@ protocol RoomProxyProtocol { func loadDisplayName(_ completion: @escaping (Result) -> Void) func loadAvatar(_ completion: @escaping (Result) -> Void) - func paginateBackwards(count: UInt, callback: ((Result<[Message], Error>) -> Void)?) + func paginateBackwards(count: UInt, callback: ((Result<[RoomMessageProtocol], Error>) -> Void)?) var callbacks: PassthroughSubject { get } } diff --git a/ElementX/Sources/Services/Timeline/RoomTimelineController.swift b/ElementX/Sources/Services/Timeline/RoomTimelineController.swift index 8119dbade..2b9f63926 100644 --- a/ElementX/Sources/Services/Timeline/RoomTimelineController.swift +++ b/ElementX/Sources/Services/Timeline/RoomTimelineController.swift @@ -48,27 +48,25 @@ class RoomTimelineController: RoomTimelineControllerProtocol { private func rebuildTimeline() { var newTimelineItems = [RoomTimelineViewProvider]() - var previousMessage: Message? + var previousMessage: RoomMessageProtocol? for message in self.timelineProvider.messages { - let timestamp = Date(timeIntervalSince1970: TimeInterval(message.originServerTs())) - let areMessagesFromTheSameDay = self.haveSameDay(lhs: previousMessage, rhs: message) let shouldAddSectionHeader = !areMessagesFromTheSameDay if shouldAddSectionHeader { - let item = SeparatorRoomTimelineItem(id: timestamp.ISO8601Format(), - text: timestamp.formatted(date: .long, time: .omitted)) + let item = SeparatorRoomTimelineItem(id: message.originServerTs.ISO8601Format(), + text: message.originServerTs.formatted(date: .long, time: .omitted)) newTimelineItems.append(RoomTimelineViewProvider.separator(item)) } - let areMessagesFromTheSameSender = (previousMessage?.sender() == message.sender()) + let areMessagesFromTheSameSender = (previousMessage?.sender == message.sender) let shouldShowSenderDetails = !areMessagesFromTheSameSender || !areMessagesFromTheSameDay - let item = TextRoomTimelineItem(id: message.id(), - senderDisplayName: message.sender(), - text: message.content(), - timestamp: timestamp.formatted(date: .omitted, time: .shortened), + let item = TextRoomTimelineItem(id: message.id, + senderDisplayName: message.sender, + text: message.content, + timestamp: message.originServerTs.formatted(date: .omitted, time: .shortened), shouldShowSenderDetails: shouldShowSenderDetails) newTimelineItems.append(RoomTimelineViewProvider.text(item)) @@ -81,15 +79,11 @@ class RoomTimelineController: RoomTimelineControllerProtocol { self.callbacks.send(.updatedTimelineItems) } - private func haveSameDay(lhs: Message?, rhs: Message?) -> Bool { + private func haveSameDay(lhs: RoomMessageProtocol?, rhs: RoomMessageProtocol?) -> Bool { guard let lhs = lhs, let rhs = rhs else { return false } - let lhsTimestamp = Date(timeIntervalSince1970: TimeInterval(lhs.originServerTs())) - let rhsTimestamp = Date(timeIntervalSince1970: TimeInterval(rhs.originServerTs())) - - return Calendar.current.isDate(lhsTimestamp, inSameDayAs: rhsTimestamp) - + return Calendar.current.isDate(lhs.originServerTs, inSameDayAs: rhs.originServerTs) } } diff --git a/ElementX/Sources/Services/Timeline/RoomTimelineProvider.swift b/ElementX/Sources/Services/Timeline/RoomTimelineProvider.swift index 9794afd1a..6f16911b1 100644 --- a/ElementX/Sources/Services/Timeline/RoomTimelineProvider.swift +++ b/ElementX/Sources/Services/Timeline/RoomTimelineProvider.swift @@ -23,7 +23,7 @@ class RoomTimelineProvider { private var cancellables = Set() let callbacks = PassthroughSubject() - private(set) var messages = [Message]() + private(set) var messages = [RoomMessageProtocol]() init(roomProxy: RoomProxyProtocol) { self.roomProxy = roomProxy @@ -41,7 +41,7 @@ class RoomTimelineProvider { }.store(in: &cancellables) } - func paginateBackwards(_ count: UInt, callback: ((Result<([Message]), RoomTimelineError>) -> Void)?) { + func paginateBackwards(_ count: UInt, callback: ((Result<([RoomMessageProtocol]), RoomTimelineError>) -> Void)?) { self.roomProxy.paginateBackwards(count: count) { result in switch result { case .success(let messages): diff --git a/ElementX/Sources/Services/Timeline/TimelineItems/TimelineItemFactory.swift b/ElementX/Sources/Services/Timeline/TimelineItems/TimelineItemFactory.swift new file mode 100644 index 000000000..1ecb8854e --- /dev/null +++ b/ElementX/Sources/Services/Timeline/TimelineItems/TimelineItemFactory.swift @@ -0,0 +1,15 @@ +// +// TimelineItemFactory.swift +// ElementX +// +// Created by Stefan Ceriu on 16/03/2022. +// Copyright © 2022 Element. All rights reserved. +// + +import Foundation + +struct TimelineItemFactory { + func buildTimelineItemFor(_ message: RoomMessageProtocol) { + + } +}