diff --git a/ElementX.xcodeproj/project.pbxproj b/ElementX.xcodeproj/project.pbxproj index c4c8ffe5a..29406d27a 100644 --- a/ElementX.xcodeproj/project.pbxproj +++ b/ElementX.xcodeproj/project.pbxproj @@ -137,7 +137,6 @@ 1B8E30B35BF8F541C1318F19 /* SecureBackupScreenViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 40316EFFEAC7B206EE9A55AE /* SecureBackupScreenViewModelTests.swift */; }; 1BA04D05EBC6646958B1BE60 /* PlaceholderScreenCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF34A2FD6797535C95AC918D /* PlaceholderScreenCoordinator.swift */; }; 1C409A26A99F0371C47AFA51 /* UserDiscoveryServiceProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7F615A00DB223FF3280204D2 /* UserDiscoveryServiceProtocol.swift */; }; - 1C815DD79B401DEBA2914773 /* TimelineItemMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = A4A1003A0F7A1DFB47F4E2D0 /* TimelineItemMock.swift */; }; 1C8BC70A18060677E295A846 /* ShareToMapsAppActivity.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4481799F455B3DA243BDA2AC /* ShareToMapsAppActivity.swift */; }; 1C9BB74711E5F24C77B7FED0 /* RoomMembersListScreenCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5AEA0B743847CFA5B3C38EE4 /* RoomMembersListScreenCoordinator.swift */; }; 1D5DC685CED904386C89B7DA /* NSRegularExpresion.swift in Sources */ = {isa = PBXBuildFile; fileRef = 95BAC0F6C9644336E9567EE6 /* NSRegularExpresion.swift */; }; @@ -211,6 +210,7 @@ 2DD9D0FE7CB5CFC80D071451 /* AppLockScreenModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3C3E67E09FE5A35D73818C39 /* AppLockScreenModels.swift */; }; 2E43A3D221BE9587BC19C3F1 /* MatrixEntityRegexTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = F31F59030205A6F65B057E1A /* MatrixEntityRegexTests.swift */; }; 2E8C6672D0EE7D5B1BEDB8E2 /* ServerConfirmationScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = F7478623CECC9438014244BA /* ServerConfirmationScreen.swift */; }; + 2F09DF0CB213CAE86A3E3B67 /* EventTimelineItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1B10423B9102086A2D9BFCBA /* EventTimelineItem.swift */; }; 2F1CF90A3460C153154427F0 /* RoomScreenUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 086B997409328F091EBA43CE /* RoomScreenUITests.swift */; }; 2F6207CB5C4715FE313B1E95 /* TimelineViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6509708F54FC883604DFDC95 /* TimelineViewModelTests.swift */; }; 2F623DA1122140A987B34D08 /* NotificationSettingsEditScreenViewModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = FA7BB497B2F539C17E88F6B7 /* NotificationSettingsEditScreenViewModelProtocol.swift */; }; @@ -407,7 +407,6 @@ 5AE6404C4FD4848ACCFF9EDC /* SecureBackupLogoutConfirmationScreenCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = E1573D28C8A9FB6399D0EEFB /* SecureBackupLogoutConfirmationScreenCoordinator.swift */; }; 5B6E5AD224509E6C0B520D6E /* RoomMemberDetailsScreenViewModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7DDF49CEBC0DFC59C308335F /* RoomMemberDetailsScreenViewModelProtocol.swift */; }; 5B7D24A318AFF75AD611A026 /* RoomDirectorySearchScreenScreenViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE6BFF453838CF6C3982C5A3 /* RoomDirectorySearchScreenScreenViewModelTests.swift */; }; - 5BBDF9926CB645DE2F7BC258 /* EventTimelineItemSDKMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = B86D447D771CEF6194348F5F /* EventTimelineItemSDKMock.swift */; }; 5BC6C4ADFE7F2A795ECDE130 /* SecureBackupKeyBackupScreenCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B2D4EEBE8C098BBADD10939 /* SecureBackupKeyBackupScreenCoordinator.swift */; }; 5C02841B2A86327B2C377682 /* NotificationConstants.swift in Sources */ = {isa = PBXBuildFile; fileRef = C830A64609CBD152F06E0457 /* NotificationConstants.swift */; }; 5C164551F7D26E24F09083D3 /* StaticLocationScreenViewModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = C616D90B1E2F033CAA325439 /* StaticLocationScreenViewModelProtocol.swift */; }; @@ -1309,6 +1308,7 @@ 1A4D29F2683F5772AC72406F /* MapTilerStaticMap.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MapTilerStaticMap.swift; sourceTree = ""; }; 1A7ED2EF5BDBAD2A7DBC4636 /* GeoURITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GeoURITests.swift; sourceTree = ""; }; 1B065EC39C99C1303A101C1C /* WebRegistrationScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WebRegistrationScreen.swift; sourceTree = ""; }; + 1B10423B9102086A2D9BFCBA /* EventTimelineItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EventTimelineItem.swift; sourceTree = ""; }; 1B2AC540DE619B36832A5DB5 /* LocationRoomTimelineItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LocationRoomTimelineItem.swift; sourceTree = ""; }; 1B53D6C5C0D14B04D3AB3F6E /* PillAttachmentViewProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PillAttachmentViewProvider.swift; sourceTree = ""; }; 1B564D748B67A156F413CD97 /* NotificationSettingsEditScreenModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationSettingsEditScreenModels.swift; sourceTree = ""; }; @@ -1904,7 +1904,6 @@ A433BE28B40D418237BE37B5 /* ReportContentScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ReportContentScreen.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 = ""; }; - A4A1003A0F7A1DFB47F4E2D0 /* TimelineItemMock.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimelineItemMock.swift; sourceTree = ""; }; A54AAF72E821B4084B7E4298 /* PinnedEventsTimelineFlowCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PinnedEventsTimelineFlowCoordinator.swift; sourceTree = ""; }; A58E93D91DE3288010390DEE /* EmojiDetectionTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EmojiDetectionTests.swift; sourceTree = ""; }; A6702BC84D3CC2421D78CD4E /* WebRegistrationScreenViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WebRegistrationScreenViewModel.swift; sourceTree = ""; }; @@ -2003,7 +2002,6 @@ B81B6170DB690013CEB646F4 /* MapLibreModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MapLibreModels.swift; sourceTree = ""; }; B8516302ACCA94A0E680AB3B /* VoiceMessageButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VoiceMessageButton.swift; sourceTree = ""; }; B858A61F2A570DFB8DE570A7 /* AggregratedReaction.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AggregratedReaction.swift; sourceTree = ""; }; - B86D447D771CEF6194348F5F /* EventTimelineItemSDKMock.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EventTimelineItemSDKMock.swift; sourceTree = ""; }; B8A3B7637DDBD6AA97AC2545 /* CameraPicker.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CameraPicker.swift; sourceTree = ""; }; B8F28602AC7AC881AED37EBA /* NavigationCoordinators.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NavigationCoordinators.swift; sourceTree = ""; }; B902EA6CD3296B0E10EE432B /* HomeScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HomeScreen.swift; sourceTree = ""; }; @@ -2899,6 +2897,7 @@ E2F96CCBEAAA7F2185BFA354 /* ClientProxyMock.swift */, 4E600B315B920B9687F8EE1B /* ComposerDraftServiceMock.swift */, E321E840DCC63790049984F4 /* ElementCallServiceMock.swift */, + 1B10423B9102086A2D9BFCBA /* EventTimelineItem.swift */, 867DC9530C42F7B5176BE465 /* JoinedRoomProxyMock.swift */, 8DA1E8F287680C8ED25EDBAC /* NetworkMonitorMock.swift */, 382B50F7E379B3DBBD174364 /* NotificationSettingsProxyMock.swift */, @@ -2911,7 +2910,6 @@ D479DF730528153665E5782E /* RoomTimelineControllerFactoryMock.swift */, F74532E01B317C56C1BE8FA8 /* RoomTimelineProviderMock.swift */, 248649EBA5BC33DB93698734 /* SessionVerificationControllerProxyMock.swift */, - A4A1003A0F7A1DFB47F4E2D0 /* TimelineItemMock.swift */, 7893780A1FD6E3F38B3E9049 /* UserIndicatorControllerMock.swift */, AAD01F7FC2BBAC7351948595 /* UserProfile+Mock.swift */, F4469F6AE311BDC439B3A5EC /* UserSessionMock.swift */, @@ -5257,7 +5255,6 @@ isa = PBXGroup; children = ( 8EAF4A49F3ACD8BB8B0D2371 /* ClientSDKMock.swift */, - B86D447D771CEF6194348F5F /* EventTimelineItemSDKMock.swift */, ); path = SDK; sourceTree = ""; @@ -6449,7 +6446,7 @@ 50539366B408780B232C1910 /* EstimatedWaveformView.swift in Sources */, F78BAD28482A467287A9A5A3 /* EventBasedMessageTimelineItemProtocol.swift in Sources */, 02D8DF8EB7537EB4E9019DDB /* EventBasedTimelineItemProtocol.swift in Sources */, - 5BBDF9926CB645DE2F7BC258 /* EventTimelineItemSDKMock.swift in Sources */, + 2F09DF0CB213CAE86A3E3B67 /* EventTimelineItem.swift in Sources */, 63E46D18B91D08E15FC04125 /* ExpiringTaskRunner.swift in Sources */, 5F06AD3C66884CE793AE6119 /* FileManager.swift in Sources */, D33AC79A50DFC26D2498DD28 /* FileRoomTimelineItem.swift in Sources */, @@ -6933,7 +6930,6 @@ 6C98153D60FF9B648C166C27 /* TimelineItemMenu.swift in Sources */, AE07F215EBC2B9CBF17AA54B /* TimelineItemMenuAction.swift in Sources */, 12CD8B5CC30A05061228BF9E /* TimelineItemMenuActionProvider.swift in Sources */, - 1C815DD79B401DEBA2914773 /* TimelineItemMock.swift in Sources */, 440123E29E2F9B001A775BBE /* TimelineItemProxy.swift in Sources */, 9586E90A447C4896C0CA3A8E /* TimelineItemReplyDetails.swift in Sources */, F3ECA377FF77E81A4F1FA062 /* TimelineItemSendInfoLabel.swift in Sources */, @@ -7799,7 +7795,7 @@ repositoryURL = "https://github.com/element-hq/matrix-rust-components-swift"; requirement = { kind = exactVersion; - version = 1.0.52; + version = 1.0.53; }; }; 701C7BEF8F70F7A83E852DCC /* XCRemoteSwiftPackageReference "GZIP" */ = { diff --git a/ElementX.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/ElementX.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved index dfbedefd5..eba7ed56a 100644 --- a/ElementX.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/ElementX.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -149,8 +149,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/element-hq/matrix-rust-components-swift", "state" : { - "revision" : "11c6d99d62035b02f4c448daebff4d63c962da20", - "version" : "1.0.52" + "revision" : "83abbdc8485340c20f27148153ff62f690ca210b", + "version" : "1.0.53" } }, { diff --git a/ElementX/Sources/Application/AppMediatorProtocol.swift b/ElementX/Sources/Application/AppMediatorProtocol.swift index d7043f298..090dffba5 100644 --- a/ElementX/Sources/Application/AppMediatorProtocol.swift +++ b/ElementX/Sources/Application/AppMediatorProtocol.swift @@ -29,7 +29,7 @@ protocol AppMediatorProtocol { func requestAuthorizationIfNeeded() async -> Bool } -extension UIApplication.State: CustomStringConvertible { +extension UIApplication.State: @retroactive CustomStringConvertible { public var description: String { switch self { case .active: @@ -44,7 +44,7 @@ extension UIApplication.State: CustomStringConvertible { } } -extension UIUserInterfaceActiveAppearance: CustomStringConvertible { +extension UIUserInterfaceActiveAppearance: @retroactive CustomStringConvertible { public var description: String { switch self { case .active: diff --git a/ElementX/Sources/Mocks/EventTimelineItem.swift b/ElementX/Sources/Mocks/EventTimelineItem.swift new file mode 100644 index 000000000..010e040a5 --- /dev/null +++ b/ElementX/Sources/Mocks/EventTimelineItem.swift @@ -0,0 +1,56 @@ +// +// Copyright 2024 New Vector Ltd. +// +// SPDX-License-Identifier: AGPL-3.0-only +// Please see LICENSE in the repository root for full details. +// + +import Foundation +import LoremSwiftum +import MatrixRustSDK + +struct EventTimelineItemSDKMockConfiguration { + var eventID: String = UUID().uuidString + var sender = "" + var isOwn = false + var content: TimelineItemContent = .redactedMessage +} + +extension EventTimelineItem { + init(configuration: EventTimelineItemSDKMockConfiguration) { + self.init(isLocal: false, + isRemote: true, + eventOrTransactionId: .eventId(eventId: configuration.eventID), + sender: configuration.sender, + senderProfile: .pending, + isOwn: configuration.isOwn, + isEditable: false, + content: configuration.content, + timestamp: 0, + reactions: [], + debugInfoProvider: EventTimelineItemDebugInfoProviderSDKMock(), + localSendState: nil, + readReceipts: [:], + origin: nil, + canBeRepliedTo: false, + shieldsProvider: EventShieldsProviderSDKMock()) + } + + static var mockMessage: EventTimelineItem { + let body = Lorem.sentences(Int.random(in: 1...5)) + let messageType = MessageType.text(content: .init(body: body, formatted: nil)) + + let content = TimelineItemContent.message(content: .init(msgType: messageType, + body: body, + inReplyTo: nil, + threadRoot: nil, + isEdited: false, + mentions: nil)) + + return .init(configuration: .init(content: content)) + } + + static func mockCallInvite(sender: String) -> EventTimelineItem { + .init(configuration: .init(sender: sender, content: .callInvite)) + } +} diff --git a/ElementX/Sources/Mocks/Generated/SDKGeneratedMocks.swift b/ElementX/Sources/Mocks/Generated/SDKGeneratedMocks.swift index 152c0940c..4cd45da02 100644 --- a/ElementX/Sources/Mocks/Generated/SDKGeneratedMocks.swift +++ b/ElementX/Sources/Mocks/Generated/SDKGeneratedMocks.swift @@ -5949,16 +5949,16 @@ open class EncryptionSDKMock: MatrixRustSDK.Encryption { //MARK: - enableRecovery - open var enableRecoveryWaitForBackupsToUploadProgressListenerThrowableError: Error? - var enableRecoveryWaitForBackupsToUploadProgressListenerUnderlyingCallsCount = 0 - open var enableRecoveryWaitForBackupsToUploadProgressListenerCallsCount: Int { + open var enableRecoveryWaitForBackupsToUploadPassphraseProgressListenerThrowableError: Error? + var enableRecoveryWaitForBackupsToUploadPassphraseProgressListenerUnderlyingCallsCount = 0 + open var enableRecoveryWaitForBackupsToUploadPassphraseProgressListenerCallsCount: Int { get { if Thread.isMainThread { - return enableRecoveryWaitForBackupsToUploadProgressListenerUnderlyingCallsCount + return enableRecoveryWaitForBackupsToUploadPassphraseProgressListenerUnderlyingCallsCount } else { var returnValue: Int? = nil DispatchQueue.main.sync { - returnValue = enableRecoveryWaitForBackupsToUploadProgressListenerUnderlyingCallsCount + returnValue = enableRecoveryWaitForBackupsToUploadPassphraseProgressListenerUnderlyingCallsCount } return returnValue! @@ -5966,29 +5966,29 @@ open class EncryptionSDKMock: MatrixRustSDK.Encryption { } set { if Thread.isMainThread { - enableRecoveryWaitForBackupsToUploadProgressListenerUnderlyingCallsCount = newValue + enableRecoveryWaitForBackupsToUploadPassphraseProgressListenerUnderlyingCallsCount = newValue } else { DispatchQueue.main.sync { - enableRecoveryWaitForBackupsToUploadProgressListenerUnderlyingCallsCount = newValue + enableRecoveryWaitForBackupsToUploadPassphraseProgressListenerUnderlyingCallsCount = newValue } } } } - open var enableRecoveryWaitForBackupsToUploadProgressListenerCalled: Bool { - return enableRecoveryWaitForBackupsToUploadProgressListenerCallsCount > 0 + open var enableRecoveryWaitForBackupsToUploadPassphraseProgressListenerCalled: Bool { + return enableRecoveryWaitForBackupsToUploadPassphraseProgressListenerCallsCount > 0 } - open var enableRecoveryWaitForBackupsToUploadProgressListenerReceivedArguments: (waitForBackupsToUpload: Bool, progressListener: EnableRecoveryProgressListener)? - open var enableRecoveryWaitForBackupsToUploadProgressListenerReceivedInvocations: [(waitForBackupsToUpload: Bool, progressListener: EnableRecoveryProgressListener)] = [] + open var enableRecoveryWaitForBackupsToUploadPassphraseProgressListenerReceivedArguments: (waitForBackupsToUpload: Bool, passphrase: String?, progressListener: EnableRecoveryProgressListener)? + open var enableRecoveryWaitForBackupsToUploadPassphraseProgressListenerReceivedInvocations: [(waitForBackupsToUpload: Bool, passphrase: String?, progressListener: EnableRecoveryProgressListener)] = [] - var enableRecoveryWaitForBackupsToUploadProgressListenerUnderlyingReturnValue: String! - open var enableRecoveryWaitForBackupsToUploadProgressListenerReturnValue: String! { + var enableRecoveryWaitForBackupsToUploadPassphraseProgressListenerUnderlyingReturnValue: String! + open var enableRecoveryWaitForBackupsToUploadPassphraseProgressListenerReturnValue: String! { get { if Thread.isMainThread { - return enableRecoveryWaitForBackupsToUploadProgressListenerUnderlyingReturnValue + return enableRecoveryWaitForBackupsToUploadPassphraseProgressListenerUnderlyingReturnValue } else { var returnValue: String? = nil DispatchQueue.main.sync { - returnValue = enableRecoveryWaitForBackupsToUploadProgressListenerUnderlyingReturnValue + returnValue = enableRecoveryWaitForBackupsToUploadPassphraseProgressListenerUnderlyingReturnValue } return returnValue! @@ -5996,29 +5996,29 @@ open class EncryptionSDKMock: MatrixRustSDK.Encryption { } set { if Thread.isMainThread { - enableRecoveryWaitForBackupsToUploadProgressListenerUnderlyingReturnValue = newValue + enableRecoveryWaitForBackupsToUploadPassphraseProgressListenerUnderlyingReturnValue = newValue } else { DispatchQueue.main.sync { - enableRecoveryWaitForBackupsToUploadProgressListenerUnderlyingReturnValue = newValue + enableRecoveryWaitForBackupsToUploadPassphraseProgressListenerUnderlyingReturnValue = newValue } } } } - open var enableRecoveryWaitForBackupsToUploadProgressListenerClosure: ((Bool, EnableRecoveryProgressListener) async throws -> String)? + open var enableRecoveryWaitForBackupsToUploadPassphraseProgressListenerClosure: ((Bool, String?, EnableRecoveryProgressListener) async throws -> String)? - open override func enableRecovery(waitForBackupsToUpload: Bool, progressListener: EnableRecoveryProgressListener) async throws -> String { - if let error = enableRecoveryWaitForBackupsToUploadProgressListenerThrowableError { + open override func enableRecovery(waitForBackupsToUpload: Bool, passphrase: String?, progressListener: EnableRecoveryProgressListener) async throws -> String { + if let error = enableRecoveryWaitForBackupsToUploadPassphraseProgressListenerThrowableError { throw error } - enableRecoveryWaitForBackupsToUploadProgressListenerCallsCount += 1 - enableRecoveryWaitForBackupsToUploadProgressListenerReceivedArguments = (waitForBackupsToUpload: waitForBackupsToUpload, progressListener: progressListener) + enableRecoveryWaitForBackupsToUploadPassphraseProgressListenerCallsCount += 1 + enableRecoveryWaitForBackupsToUploadPassphraseProgressListenerReceivedArguments = (waitForBackupsToUpload: waitForBackupsToUpload, passphrase: passphrase, progressListener: progressListener) DispatchQueue.main.async { - self.enableRecoveryWaitForBackupsToUploadProgressListenerReceivedInvocations.append((waitForBackupsToUpload: waitForBackupsToUpload, progressListener: progressListener)) + self.enableRecoveryWaitForBackupsToUploadPassphraseProgressListenerReceivedInvocations.append((waitForBackupsToUpload: waitForBackupsToUpload, passphrase: passphrase, progressListener: progressListener)) } - if let enableRecoveryWaitForBackupsToUploadProgressListenerClosure = enableRecoveryWaitForBackupsToUploadProgressListenerClosure { - return try await enableRecoveryWaitForBackupsToUploadProgressListenerClosure(waitForBackupsToUpload, progressListener) + if let enableRecoveryWaitForBackupsToUploadPassphraseProgressListenerClosure = enableRecoveryWaitForBackupsToUploadPassphraseProgressListenerClosure { + return try await enableRecoveryWaitForBackupsToUploadPassphraseProgressListenerClosure(waitForBackupsToUpload, passphrase, progressListener) } else { - return enableRecoveryWaitForBackupsToUploadProgressListenerReturnValue + return enableRecoveryWaitForBackupsToUploadPassphraseProgressListenerReturnValue } } @@ -6704,7 +6704,7 @@ open class EncryptionSDKMock: MatrixRustSDK.Encryption { await waitForE2eeInitializationTasksClosure?() } } -open class EventTimelineItemSDKMock: MatrixRustSDK.EventTimelineItem { +open class EventShieldsProviderSDKMock: MatrixRustSDK.EventShieldsProvider { init() { super.init(noPointer: .init()) } @@ -6715,17 +6715,17 @@ open class EventTimelineItemSDKMock: MatrixRustSDK.EventTimelineItem { fileprivate var pointer: UnsafeMutableRawPointer! - //MARK: - canBeRepliedTo + //MARK: - getShields - var canBeRepliedToUnderlyingCallsCount = 0 - open var canBeRepliedToCallsCount: Int { + var getShieldsStrictUnderlyingCallsCount = 0 + open var getShieldsStrictCallsCount: Int { get { if Thread.isMainThread { - return canBeRepliedToUnderlyingCallsCount + return getShieldsStrictUnderlyingCallsCount } else { var returnValue: Int? = nil DispatchQueue.main.sync { - returnValue = canBeRepliedToUnderlyingCallsCount + returnValue = getShieldsStrictUnderlyingCallsCount } return returnValue! @@ -6733,289 +6733,29 @@ open class EventTimelineItemSDKMock: MatrixRustSDK.EventTimelineItem { } set { if Thread.isMainThread { - canBeRepliedToUnderlyingCallsCount = newValue + getShieldsStrictUnderlyingCallsCount = newValue } else { DispatchQueue.main.sync { - canBeRepliedToUnderlyingCallsCount = newValue + getShieldsStrictUnderlyingCallsCount = newValue } } } } - open var canBeRepliedToCalled: Bool { - return canBeRepliedToCallsCount > 0 + open var getShieldsStrictCalled: Bool { + return getShieldsStrictCallsCount > 0 } + open var getShieldsStrictReceivedStrict: Bool? + open var getShieldsStrictReceivedInvocations: [Bool] = [] - var canBeRepliedToUnderlyingReturnValue: Bool! - open var canBeRepliedToReturnValue: Bool! { + var getShieldsStrictUnderlyingReturnValue: ShieldState? + open var getShieldsStrictReturnValue: ShieldState? { get { if Thread.isMainThread { - return canBeRepliedToUnderlyingReturnValue - } else { - var returnValue: Bool? = nil - DispatchQueue.main.sync { - returnValue = canBeRepliedToUnderlyingReturnValue - } - - return returnValue! - } - } - set { - if Thread.isMainThread { - canBeRepliedToUnderlyingReturnValue = newValue - } else { - DispatchQueue.main.sync { - canBeRepliedToUnderlyingReturnValue = newValue - } - } - } - } - open var canBeRepliedToClosure: (() -> Bool)? - - open override func canBeRepliedTo() -> Bool { - canBeRepliedToCallsCount += 1 - if let canBeRepliedToClosure = canBeRepliedToClosure { - return canBeRepliedToClosure() - } else { - return canBeRepliedToReturnValue - } - } - - //MARK: - content - - var contentUnderlyingCallsCount = 0 - open var contentCallsCount: Int { - get { - if Thread.isMainThread { - return contentUnderlyingCallsCount - } else { - var returnValue: Int? = nil - DispatchQueue.main.sync { - returnValue = contentUnderlyingCallsCount - } - - return returnValue! - } - } - set { - if Thread.isMainThread { - contentUnderlyingCallsCount = newValue - } else { - DispatchQueue.main.sync { - contentUnderlyingCallsCount = newValue - } - } - } - } - open var contentCalled: Bool { - return contentCallsCount > 0 - } - - var contentUnderlyingReturnValue: TimelineItemContent! - open var contentReturnValue: TimelineItemContent! { - get { - if Thread.isMainThread { - return contentUnderlyingReturnValue - } else { - var returnValue: TimelineItemContent? = nil - DispatchQueue.main.sync { - returnValue = contentUnderlyingReturnValue - } - - return returnValue! - } - } - set { - if Thread.isMainThread { - contentUnderlyingReturnValue = newValue - } else { - DispatchQueue.main.sync { - contentUnderlyingReturnValue = newValue - } - } - } - } - open var contentClosure: (() -> TimelineItemContent)? - - open override func content() -> TimelineItemContent { - contentCallsCount += 1 - if let contentClosure = contentClosure { - return contentClosure() - } else { - return contentReturnValue - } - } - - //MARK: - debugInfo - - var debugInfoUnderlyingCallsCount = 0 - open var debugInfoCallsCount: Int { - get { - if Thread.isMainThread { - return debugInfoUnderlyingCallsCount - } else { - var returnValue: Int? = nil - DispatchQueue.main.sync { - returnValue = debugInfoUnderlyingCallsCount - } - - return returnValue! - } - } - set { - if Thread.isMainThread { - debugInfoUnderlyingCallsCount = newValue - } else { - DispatchQueue.main.sync { - debugInfoUnderlyingCallsCount = newValue - } - } - } - } - open var debugInfoCalled: Bool { - return debugInfoCallsCount > 0 - } - - var debugInfoUnderlyingReturnValue: EventTimelineItemDebugInfo! - open var debugInfoReturnValue: EventTimelineItemDebugInfo! { - get { - if Thread.isMainThread { - return debugInfoUnderlyingReturnValue - } else { - var returnValue: EventTimelineItemDebugInfo? = nil - DispatchQueue.main.sync { - returnValue = debugInfoUnderlyingReturnValue - } - - return returnValue! - } - } - set { - if Thread.isMainThread { - debugInfoUnderlyingReturnValue = newValue - } else { - DispatchQueue.main.sync { - debugInfoUnderlyingReturnValue = newValue - } - } - } - } - open var debugInfoClosure: (() -> EventTimelineItemDebugInfo)? - - open override func debugInfo() -> EventTimelineItemDebugInfo { - debugInfoCallsCount += 1 - if let debugInfoClosure = debugInfoClosure { - return debugInfoClosure() - } else { - return debugInfoReturnValue - } - } - - //MARK: - eventId - - var eventIdUnderlyingCallsCount = 0 - open var eventIdCallsCount: Int { - get { - if Thread.isMainThread { - return eventIdUnderlyingCallsCount - } else { - var returnValue: Int? = nil - DispatchQueue.main.sync { - returnValue = eventIdUnderlyingCallsCount - } - - return returnValue! - } - } - set { - if Thread.isMainThread { - eventIdUnderlyingCallsCount = newValue - } else { - DispatchQueue.main.sync { - eventIdUnderlyingCallsCount = newValue - } - } - } - } - open var eventIdCalled: Bool { - return eventIdCallsCount > 0 - } - - var eventIdUnderlyingReturnValue: String? - open var eventIdReturnValue: String? { - get { - if Thread.isMainThread { - return eventIdUnderlyingReturnValue - } else { - var returnValue: String?? = nil - DispatchQueue.main.sync { - returnValue = eventIdUnderlyingReturnValue - } - - return returnValue! - } - } - set { - if Thread.isMainThread { - eventIdUnderlyingReturnValue = newValue - } else { - DispatchQueue.main.sync { - eventIdUnderlyingReturnValue = newValue - } - } - } - } - open var eventIdClosure: (() -> String?)? - - open override func eventId() -> String? { - eventIdCallsCount += 1 - if let eventIdClosure = eventIdClosure { - return eventIdClosure() - } else { - return eventIdReturnValue - } - } - - //MARK: - getShield - - var getShieldStrictUnderlyingCallsCount = 0 - open var getShieldStrictCallsCount: Int { - get { - if Thread.isMainThread { - return getShieldStrictUnderlyingCallsCount - } else { - var returnValue: Int? = nil - DispatchQueue.main.sync { - returnValue = getShieldStrictUnderlyingCallsCount - } - - return returnValue! - } - } - set { - if Thread.isMainThread { - getShieldStrictUnderlyingCallsCount = newValue - } else { - DispatchQueue.main.sync { - getShieldStrictUnderlyingCallsCount = newValue - } - } - } - } - open var getShieldStrictCalled: Bool { - return getShieldStrictCallsCount > 0 - } - open var getShieldStrictReceivedStrict: Bool? - open var getShieldStrictReceivedInvocations: [Bool] = [] - - var getShieldStrictUnderlyingReturnValue: ShieldState? - open var getShieldStrictReturnValue: ShieldState? { - get { - if Thread.isMainThread { - return getShieldStrictUnderlyingReturnValue + return getShieldsStrictUnderlyingReturnValue } else { var returnValue: ShieldState?? = nil DispatchQueue.main.sync { - returnValue = getShieldStrictUnderlyingReturnValue + returnValue = getShieldsStrictUnderlyingReturnValue } return returnValue! @@ -7023,40 +6763,51 @@ open class EventTimelineItemSDKMock: MatrixRustSDK.EventTimelineItem { } set { if Thread.isMainThread { - getShieldStrictUnderlyingReturnValue = newValue + getShieldsStrictUnderlyingReturnValue = newValue } else { DispatchQueue.main.sync { - getShieldStrictUnderlyingReturnValue = newValue + getShieldsStrictUnderlyingReturnValue = newValue } } } } - open var getShieldStrictClosure: ((Bool) -> ShieldState?)? + open var getShieldsStrictClosure: ((Bool) -> ShieldState?)? - open override func getShield(strict: Bool) -> ShieldState? { - getShieldStrictCallsCount += 1 - getShieldStrictReceivedStrict = strict + open override func getShields(strict: Bool) -> ShieldState? { + getShieldsStrictCallsCount += 1 + getShieldsStrictReceivedStrict = strict DispatchQueue.main.async { - self.getShieldStrictReceivedInvocations.append(strict) + self.getShieldsStrictReceivedInvocations.append(strict) } - if let getShieldStrictClosure = getShieldStrictClosure { - return getShieldStrictClosure(strict) + if let getShieldsStrictClosure = getShieldsStrictClosure { + return getShieldsStrictClosure(strict) } else { - return getShieldStrictReturnValue + return getShieldsStrictReturnValue } } +} +open class EventTimelineItemDebugInfoProviderSDKMock: MatrixRustSDK.EventTimelineItemDebugInfoProvider { + init() { + super.init(noPointer: .init()) + } - //MARK: - isEditable + public required init(unsafeFromRawPointer pointer: UnsafeMutableRawPointer) { + fatalError("init(unsafeFromRawPointer:) has not been implemented") + } - var isEditableUnderlyingCallsCount = 0 - open var isEditableCallsCount: Int { + fileprivate var pointer: UnsafeMutableRawPointer! + + //MARK: - get + + var getUnderlyingCallsCount = 0 + open var getCallsCount: Int { get { if Thread.isMainThread { - return isEditableUnderlyingCallsCount + return getUnderlyingCallsCount } else { var returnValue: Int? = nil DispatchQueue.main.sync { - returnValue = isEditableUnderlyingCallsCount + returnValue = getUnderlyingCallsCount } return returnValue! @@ -7064,27 +6815,27 @@ open class EventTimelineItemSDKMock: MatrixRustSDK.EventTimelineItem { } set { if Thread.isMainThread { - isEditableUnderlyingCallsCount = newValue + getUnderlyingCallsCount = newValue } else { DispatchQueue.main.sync { - isEditableUnderlyingCallsCount = newValue + getUnderlyingCallsCount = newValue } } } } - open var isEditableCalled: Bool { - return isEditableCallsCount > 0 + open var getCalled: Bool { + return getCallsCount > 0 } - var isEditableUnderlyingReturnValue: Bool! - open var isEditableReturnValue: Bool! { + var getUnderlyingReturnValue: EventTimelineItemDebugInfo! + open var getReturnValue: EventTimelineItemDebugInfo! { get { if Thread.isMainThread { - return isEditableUnderlyingReturnValue + return getUnderlyingReturnValue } else { - var returnValue: Bool? = nil + var returnValue: EventTimelineItemDebugInfo? = nil DispatchQueue.main.sync { - returnValue = isEditableUnderlyingReturnValue + returnValue = getUnderlyingReturnValue } return returnValue! @@ -7092,737 +6843,22 @@ open class EventTimelineItemSDKMock: MatrixRustSDK.EventTimelineItem { } set { if Thread.isMainThread { - isEditableUnderlyingReturnValue = newValue + getUnderlyingReturnValue = newValue } else { DispatchQueue.main.sync { - isEditableUnderlyingReturnValue = newValue + getUnderlyingReturnValue = newValue } } } } - open var isEditableClosure: (() -> Bool)? + open var getClosure: (() -> EventTimelineItemDebugInfo)? - open override func isEditable() -> Bool { - isEditableCallsCount += 1 - if let isEditableClosure = isEditableClosure { - return isEditableClosure() + open override func get() -> EventTimelineItemDebugInfo { + getCallsCount += 1 + if let getClosure = getClosure { + return getClosure() } else { - return isEditableReturnValue - } - } - - //MARK: - isLocal - - var isLocalUnderlyingCallsCount = 0 - open var isLocalCallsCount: Int { - get { - if Thread.isMainThread { - return isLocalUnderlyingCallsCount - } else { - var returnValue: Int? = nil - DispatchQueue.main.sync { - returnValue = isLocalUnderlyingCallsCount - } - - return returnValue! - } - } - set { - if Thread.isMainThread { - isLocalUnderlyingCallsCount = newValue - } else { - DispatchQueue.main.sync { - isLocalUnderlyingCallsCount = newValue - } - } - } - } - open var isLocalCalled: Bool { - return isLocalCallsCount > 0 - } - - var isLocalUnderlyingReturnValue: Bool! - open var isLocalReturnValue: Bool! { - get { - if Thread.isMainThread { - return isLocalUnderlyingReturnValue - } else { - var returnValue: Bool? = nil - DispatchQueue.main.sync { - returnValue = isLocalUnderlyingReturnValue - } - - return returnValue! - } - } - set { - if Thread.isMainThread { - isLocalUnderlyingReturnValue = newValue - } else { - DispatchQueue.main.sync { - isLocalUnderlyingReturnValue = newValue - } - } - } - } - open var isLocalClosure: (() -> Bool)? - - open override func isLocal() -> Bool { - isLocalCallsCount += 1 - if let isLocalClosure = isLocalClosure { - return isLocalClosure() - } else { - return isLocalReturnValue - } - } - - //MARK: - isOwn - - var isOwnUnderlyingCallsCount = 0 - open var isOwnCallsCount: Int { - get { - if Thread.isMainThread { - return isOwnUnderlyingCallsCount - } else { - var returnValue: Int? = nil - DispatchQueue.main.sync { - returnValue = isOwnUnderlyingCallsCount - } - - return returnValue! - } - } - set { - if Thread.isMainThread { - isOwnUnderlyingCallsCount = newValue - } else { - DispatchQueue.main.sync { - isOwnUnderlyingCallsCount = newValue - } - } - } - } - open var isOwnCalled: Bool { - return isOwnCallsCount > 0 - } - - var isOwnUnderlyingReturnValue: Bool! - open var isOwnReturnValue: Bool! { - get { - if Thread.isMainThread { - return isOwnUnderlyingReturnValue - } else { - var returnValue: Bool? = nil - DispatchQueue.main.sync { - returnValue = isOwnUnderlyingReturnValue - } - - return returnValue! - } - } - set { - if Thread.isMainThread { - isOwnUnderlyingReturnValue = newValue - } else { - DispatchQueue.main.sync { - isOwnUnderlyingReturnValue = newValue - } - } - } - } - open var isOwnClosure: (() -> Bool)? - - open override func isOwn() -> Bool { - isOwnCallsCount += 1 - if let isOwnClosure = isOwnClosure { - return isOwnClosure() - } else { - return isOwnReturnValue - } - } - - //MARK: - isRemote - - var isRemoteUnderlyingCallsCount = 0 - open var isRemoteCallsCount: Int { - get { - if Thread.isMainThread { - return isRemoteUnderlyingCallsCount - } else { - var returnValue: Int? = nil - DispatchQueue.main.sync { - returnValue = isRemoteUnderlyingCallsCount - } - - return returnValue! - } - } - set { - if Thread.isMainThread { - isRemoteUnderlyingCallsCount = newValue - } else { - DispatchQueue.main.sync { - isRemoteUnderlyingCallsCount = newValue - } - } - } - } - open var isRemoteCalled: Bool { - return isRemoteCallsCount > 0 - } - - var isRemoteUnderlyingReturnValue: Bool! - open var isRemoteReturnValue: Bool! { - get { - if Thread.isMainThread { - return isRemoteUnderlyingReturnValue - } else { - var returnValue: Bool? = nil - DispatchQueue.main.sync { - returnValue = isRemoteUnderlyingReturnValue - } - - return returnValue! - } - } - set { - if Thread.isMainThread { - isRemoteUnderlyingReturnValue = newValue - } else { - DispatchQueue.main.sync { - isRemoteUnderlyingReturnValue = newValue - } - } - } - } - open var isRemoteClosure: (() -> Bool)? - - open override func isRemote() -> Bool { - isRemoteCallsCount += 1 - if let isRemoteClosure = isRemoteClosure { - return isRemoteClosure() - } else { - return isRemoteReturnValue - } - } - - //MARK: - localSendState - - var localSendStateUnderlyingCallsCount = 0 - open var localSendStateCallsCount: Int { - get { - if Thread.isMainThread { - return localSendStateUnderlyingCallsCount - } else { - var returnValue: Int? = nil - DispatchQueue.main.sync { - returnValue = localSendStateUnderlyingCallsCount - } - - return returnValue! - } - } - set { - if Thread.isMainThread { - localSendStateUnderlyingCallsCount = newValue - } else { - DispatchQueue.main.sync { - localSendStateUnderlyingCallsCount = newValue - } - } - } - } - open var localSendStateCalled: Bool { - return localSendStateCallsCount > 0 - } - - var localSendStateUnderlyingReturnValue: EventSendState? - open var localSendStateReturnValue: EventSendState? { - get { - if Thread.isMainThread { - return localSendStateUnderlyingReturnValue - } else { - var returnValue: EventSendState?? = nil - DispatchQueue.main.sync { - returnValue = localSendStateUnderlyingReturnValue - } - - return returnValue! - } - } - set { - if Thread.isMainThread { - localSendStateUnderlyingReturnValue = newValue - } else { - DispatchQueue.main.sync { - localSendStateUnderlyingReturnValue = newValue - } - } - } - } - open var localSendStateClosure: (() -> EventSendState?)? - - open override func localSendState() -> EventSendState? { - localSendStateCallsCount += 1 - if let localSendStateClosure = localSendStateClosure { - return localSendStateClosure() - } else { - return localSendStateReturnValue - } - } - - //MARK: - origin - - var originUnderlyingCallsCount = 0 - open var originCallsCount: Int { - get { - if Thread.isMainThread { - return originUnderlyingCallsCount - } else { - var returnValue: Int? = nil - DispatchQueue.main.sync { - returnValue = originUnderlyingCallsCount - } - - return returnValue! - } - } - set { - if Thread.isMainThread { - originUnderlyingCallsCount = newValue - } else { - DispatchQueue.main.sync { - originUnderlyingCallsCount = newValue - } - } - } - } - open var originCalled: Bool { - return originCallsCount > 0 - } - - var originUnderlyingReturnValue: EventItemOrigin? - open var originReturnValue: EventItemOrigin? { - get { - if Thread.isMainThread { - return originUnderlyingReturnValue - } else { - var returnValue: EventItemOrigin?? = nil - DispatchQueue.main.sync { - returnValue = originUnderlyingReturnValue - } - - return returnValue! - } - } - set { - if Thread.isMainThread { - originUnderlyingReturnValue = newValue - } else { - DispatchQueue.main.sync { - originUnderlyingReturnValue = newValue - } - } - } - } - open var originClosure: (() -> EventItemOrigin?)? - - open override func origin() -> EventItemOrigin? { - originCallsCount += 1 - if let originClosure = originClosure { - return originClosure() - } else { - return originReturnValue - } - } - - //MARK: - reactions - - var reactionsUnderlyingCallsCount = 0 - open var reactionsCallsCount: Int { - get { - if Thread.isMainThread { - return reactionsUnderlyingCallsCount - } else { - var returnValue: Int? = nil - DispatchQueue.main.sync { - returnValue = reactionsUnderlyingCallsCount - } - - return returnValue! - } - } - set { - if Thread.isMainThread { - reactionsUnderlyingCallsCount = newValue - } else { - DispatchQueue.main.sync { - reactionsUnderlyingCallsCount = newValue - } - } - } - } - open var reactionsCalled: Bool { - return reactionsCallsCount > 0 - } - - var reactionsUnderlyingReturnValue: [Reaction]! - open var reactionsReturnValue: [Reaction]! { - get { - if Thread.isMainThread { - return reactionsUnderlyingReturnValue - } else { - var returnValue: [Reaction]? = nil - DispatchQueue.main.sync { - returnValue = reactionsUnderlyingReturnValue - } - - return returnValue! - } - } - set { - if Thread.isMainThread { - reactionsUnderlyingReturnValue = newValue - } else { - DispatchQueue.main.sync { - reactionsUnderlyingReturnValue = newValue - } - } - } - } - open var reactionsClosure: (() -> [Reaction])? - - open override func reactions() -> [Reaction] { - reactionsCallsCount += 1 - if let reactionsClosure = reactionsClosure { - return reactionsClosure() - } else { - return reactionsReturnValue - } - } - - //MARK: - readReceipts - - var readReceiptsUnderlyingCallsCount = 0 - open var readReceiptsCallsCount: Int { - get { - if Thread.isMainThread { - return readReceiptsUnderlyingCallsCount - } else { - var returnValue: Int? = nil - DispatchQueue.main.sync { - returnValue = readReceiptsUnderlyingCallsCount - } - - return returnValue! - } - } - set { - if Thread.isMainThread { - readReceiptsUnderlyingCallsCount = newValue - } else { - DispatchQueue.main.sync { - readReceiptsUnderlyingCallsCount = newValue - } - } - } - } - open var readReceiptsCalled: Bool { - return readReceiptsCallsCount > 0 - } - - var readReceiptsUnderlyingReturnValue: [String: Receipt]! - open var readReceiptsReturnValue: [String: Receipt]! { - get { - if Thread.isMainThread { - return readReceiptsUnderlyingReturnValue - } else { - var returnValue: [String: Receipt]? = nil - DispatchQueue.main.sync { - returnValue = readReceiptsUnderlyingReturnValue - } - - return returnValue! - } - } - set { - if Thread.isMainThread { - readReceiptsUnderlyingReturnValue = newValue - } else { - DispatchQueue.main.sync { - readReceiptsUnderlyingReturnValue = newValue - } - } - } - } - open var readReceiptsClosure: (() -> [String: Receipt])? - - open override func readReceipts() -> [String: Receipt] { - readReceiptsCallsCount += 1 - if let readReceiptsClosure = readReceiptsClosure { - return readReceiptsClosure() - } else { - return readReceiptsReturnValue - } - } - - //MARK: - sender - - var senderUnderlyingCallsCount = 0 - open var senderCallsCount: Int { - get { - if Thread.isMainThread { - return senderUnderlyingCallsCount - } else { - var returnValue: Int? = nil - DispatchQueue.main.sync { - returnValue = senderUnderlyingCallsCount - } - - return returnValue! - } - } - set { - if Thread.isMainThread { - senderUnderlyingCallsCount = newValue - } else { - DispatchQueue.main.sync { - senderUnderlyingCallsCount = newValue - } - } - } - } - open var senderCalled: Bool { - return senderCallsCount > 0 - } - - var senderUnderlyingReturnValue: String! - open var senderReturnValue: String! { - get { - if Thread.isMainThread { - return senderUnderlyingReturnValue - } else { - var returnValue: String? = nil - DispatchQueue.main.sync { - returnValue = senderUnderlyingReturnValue - } - - return returnValue! - } - } - set { - if Thread.isMainThread { - senderUnderlyingReturnValue = newValue - } else { - DispatchQueue.main.sync { - senderUnderlyingReturnValue = newValue - } - } - } - } - open var senderClosure: (() -> String)? - - open override func sender() -> String { - senderCallsCount += 1 - if let senderClosure = senderClosure { - return senderClosure() - } else { - return senderReturnValue - } - } - - //MARK: - senderProfile - - var senderProfileUnderlyingCallsCount = 0 - open var senderProfileCallsCount: Int { - get { - if Thread.isMainThread { - return senderProfileUnderlyingCallsCount - } else { - var returnValue: Int? = nil - DispatchQueue.main.sync { - returnValue = senderProfileUnderlyingCallsCount - } - - return returnValue! - } - } - set { - if Thread.isMainThread { - senderProfileUnderlyingCallsCount = newValue - } else { - DispatchQueue.main.sync { - senderProfileUnderlyingCallsCount = newValue - } - } - } - } - open var senderProfileCalled: Bool { - return senderProfileCallsCount > 0 - } - - var senderProfileUnderlyingReturnValue: ProfileDetails! - open var senderProfileReturnValue: ProfileDetails! { - get { - if Thread.isMainThread { - return senderProfileUnderlyingReturnValue - } else { - var returnValue: ProfileDetails? = nil - DispatchQueue.main.sync { - returnValue = senderProfileUnderlyingReturnValue - } - - return returnValue! - } - } - set { - if Thread.isMainThread { - senderProfileUnderlyingReturnValue = newValue - } else { - DispatchQueue.main.sync { - senderProfileUnderlyingReturnValue = newValue - } - } - } - } - open var senderProfileClosure: (() -> ProfileDetails)? - - open override func senderProfile() -> ProfileDetails { - senderProfileCallsCount += 1 - if let senderProfileClosure = senderProfileClosure { - return senderProfileClosure() - } else { - return senderProfileReturnValue - } - } - - //MARK: - timestamp - - var timestampUnderlyingCallsCount = 0 - open var timestampCallsCount: Int { - get { - if Thread.isMainThread { - return timestampUnderlyingCallsCount - } else { - var returnValue: Int? = nil - DispatchQueue.main.sync { - returnValue = timestampUnderlyingCallsCount - } - - return returnValue! - } - } - set { - if Thread.isMainThread { - timestampUnderlyingCallsCount = newValue - } else { - DispatchQueue.main.sync { - timestampUnderlyingCallsCount = newValue - } - } - } - } - open var timestampCalled: Bool { - return timestampCallsCount > 0 - } - - var timestampUnderlyingReturnValue: UInt64! - open var timestampReturnValue: UInt64! { - get { - if Thread.isMainThread { - return timestampUnderlyingReturnValue - } else { - var returnValue: UInt64? = nil - DispatchQueue.main.sync { - returnValue = timestampUnderlyingReturnValue - } - - return returnValue! - } - } - set { - if Thread.isMainThread { - timestampUnderlyingReturnValue = newValue - } else { - DispatchQueue.main.sync { - timestampUnderlyingReturnValue = newValue - } - } - } - } - open var timestampClosure: (() -> UInt64)? - - open override func timestamp() -> UInt64 { - timestampCallsCount += 1 - if let timestampClosure = timestampClosure { - return timestampClosure() - } else { - return timestampReturnValue - } - } - - //MARK: - transactionId - - var transactionIdUnderlyingCallsCount = 0 - open var transactionIdCallsCount: Int { - get { - if Thread.isMainThread { - return transactionIdUnderlyingCallsCount - } else { - var returnValue: Int? = nil - DispatchQueue.main.sync { - returnValue = transactionIdUnderlyingCallsCount - } - - return returnValue! - } - } - set { - if Thread.isMainThread { - transactionIdUnderlyingCallsCount = newValue - } else { - DispatchQueue.main.sync { - transactionIdUnderlyingCallsCount = newValue - } - } - } - } - open var transactionIdCalled: Bool { - return transactionIdCallsCount > 0 - } - - var transactionIdUnderlyingReturnValue: String? - open var transactionIdReturnValue: String? { - get { - if Thread.isMainThread { - return transactionIdUnderlyingReturnValue - } else { - var returnValue: String?? = nil - DispatchQueue.main.sync { - returnValue = transactionIdUnderlyingReturnValue - } - - return returnValue! - } - } - set { - if Thread.isMainThread { - transactionIdUnderlyingReturnValue = newValue - } else { - DispatchQueue.main.sync { - transactionIdUnderlyingReturnValue = newValue - } - } - } - } - open var transactionIdClosure: (() -> String?)? - - open override func transactionId() -> String? { - transactionIdCallsCount += 1 - if let transactionIdClosure = transactionIdClosure { - return transactionIdClosure() - } else { - return transactionIdReturnValue + return getReturnValue } } } @@ -8255,6 +7291,147 @@ open class IdentityResetHandleSDKMock: MatrixRustSDK.IdentityResetHandle { try await resetAuthClosure?(auth) } } +open class InReplyToDetailsSDKMock: MatrixRustSDK.InReplyToDetails { + init() { + super.init(noPointer: .init()) + } + + public required init(unsafeFromRawPointer pointer: UnsafeMutableRawPointer) { + fatalError("init(unsafeFromRawPointer:) has not been implemented") + } + + fileprivate var pointer: UnsafeMutableRawPointer! + + //MARK: - event + + var eventUnderlyingCallsCount = 0 + open var eventCallsCount: Int { + get { + if Thread.isMainThread { + return eventUnderlyingCallsCount + } else { + var returnValue: Int? = nil + DispatchQueue.main.sync { + returnValue = eventUnderlyingCallsCount + } + + return returnValue! + } + } + set { + if Thread.isMainThread { + eventUnderlyingCallsCount = newValue + } else { + DispatchQueue.main.sync { + eventUnderlyingCallsCount = newValue + } + } + } + } + open var eventCalled: Bool { + return eventCallsCount > 0 + } + + var eventUnderlyingReturnValue: RepliedToEventDetails! + open var eventReturnValue: RepliedToEventDetails! { + get { + if Thread.isMainThread { + return eventUnderlyingReturnValue + } else { + var returnValue: RepliedToEventDetails? = nil + DispatchQueue.main.sync { + returnValue = eventUnderlyingReturnValue + } + + return returnValue! + } + } + set { + if Thread.isMainThread { + eventUnderlyingReturnValue = newValue + } else { + DispatchQueue.main.sync { + eventUnderlyingReturnValue = newValue + } + } + } + } + open var eventClosure: (() -> RepliedToEventDetails)? + + open override func event() -> RepliedToEventDetails { + eventCallsCount += 1 + if let eventClosure = eventClosure { + return eventClosure() + } else { + return eventReturnValue + } + } + + //MARK: - eventId + + var eventIdUnderlyingCallsCount = 0 + open var eventIdCallsCount: Int { + get { + if Thread.isMainThread { + return eventIdUnderlyingCallsCount + } else { + var returnValue: Int? = nil + DispatchQueue.main.sync { + returnValue = eventIdUnderlyingCallsCount + } + + return returnValue! + } + } + set { + if Thread.isMainThread { + eventIdUnderlyingCallsCount = newValue + } else { + DispatchQueue.main.sync { + eventIdUnderlyingCallsCount = newValue + } + } + } + } + open var eventIdCalled: Bool { + return eventIdCallsCount > 0 + } + + var eventIdUnderlyingReturnValue: String! + open var eventIdReturnValue: String! { + get { + if Thread.isMainThread { + return eventIdUnderlyingReturnValue + } else { + var returnValue: String? = nil + DispatchQueue.main.sync { + returnValue = eventIdUnderlyingReturnValue + } + + return returnValue! + } + } + set { + if Thread.isMainThread { + eventIdUnderlyingReturnValue = newValue + } else { + DispatchQueue.main.sync { + eventIdUnderlyingReturnValue = newValue + } + } + } + } + open var eventIdClosure: (() -> String)? + + open override func eventId() -> String { + eventIdCallsCount += 1 + if let eventIdClosure = eventIdClosure { + return eventIdClosure() + } else { + return eventIdReturnValue + } + } +} open class MediaFileHandleSDKMock: MatrixRustSDK.MediaFileHandle { init() { super.init(noPointer: .init()) @@ -8554,407 +7731,6 @@ open class MediaSourceSDKMock: MatrixRustSDK.MediaSource { } } } -open class MessageSDKMock: MatrixRustSDK.Message { - init() { - super.init(noPointer: .init()) - } - - public required init(unsafeFromRawPointer pointer: UnsafeMutableRawPointer) { - fatalError("init(unsafeFromRawPointer:) has not been implemented") - } - - fileprivate var pointer: UnsafeMutableRawPointer! - - //MARK: - body - - var bodyUnderlyingCallsCount = 0 - open var bodyCallsCount: Int { - get { - if Thread.isMainThread { - return bodyUnderlyingCallsCount - } else { - var returnValue: Int? = nil - DispatchQueue.main.sync { - returnValue = bodyUnderlyingCallsCount - } - - return returnValue! - } - } - set { - if Thread.isMainThread { - bodyUnderlyingCallsCount = newValue - } else { - DispatchQueue.main.sync { - bodyUnderlyingCallsCount = newValue - } - } - } - } - open var bodyCalled: Bool { - return bodyCallsCount > 0 - } - - var bodyUnderlyingReturnValue: String! - open var bodyReturnValue: String! { - get { - if Thread.isMainThread { - return bodyUnderlyingReturnValue - } else { - var returnValue: String? = nil - DispatchQueue.main.sync { - returnValue = bodyUnderlyingReturnValue - } - - return returnValue! - } - } - set { - if Thread.isMainThread { - bodyUnderlyingReturnValue = newValue - } else { - DispatchQueue.main.sync { - bodyUnderlyingReturnValue = newValue - } - } - } - } - open var bodyClosure: (() -> String)? - - open override func body() -> String { - bodyCallsCount += 1 - if let bodyClosure = bodyClosure { - return bodyClosure() - } else { - return bodyReturnValue - } - } - - //MARK: - content - - var contentUnderlyingCallsCount = 0 - open var contentCallsCount: Int { - get { - if Thread.isMainThread { - return contentUnderlyingCallsCount - } else { - var returnValue: Int? = nil - DispatchQueue.main.sync { - returnValue = contentUnderlyingCallsCount - } - - return returnValue! - } - } - set { - if Thread.isMainThread { - contentUnderlyingCallsCount = newValue - } else { - DispatchQueue.main.sync { - contentUnderlyingCallsCount = newValue - } - } - } - } - open var contentCalled: Bool { - return contentCallsCount > 0 - } - - var contentUnderlyingReturnValue: RoomMessageEventContentWithoutRelation! - open var contentReturnValue: RoomMessageEventContentWithoutRelation! { - get { - if Thread.isMainThread { - return contentUnderlyingReturnValue - } else { - var returnValue: RoomMessageEventContentWithoutRelation? = nil - DispatchQueue.main.sync { - returnValue = contentUnderlyingReturnValue - } - - return returnValue! - } - } - set { - if Thread.isMainThread { - contentUnderlyingReturnValue = newValue - } else { - DispatchQueue.main.sync { - contentUnderlyingReturnValue = newValue - } - } - } - } - open var contentClosure: (() -> RoomMessageEventContentWithoutRelation)? - - open override func content() -> RoomMessageEventContentWithoutRelation { - contentCallsCount += 1 - if let contentClosure = contentClosure { - return contentClosure() - } else { - return contentReturnValue - } - } - - //MARK: - inReplyTo - - var inReplyToUnderlyingCallsCount = 0 - open var inReplyToCallsCount: Int { - get { - if Thread.isMainThread { - return inReplyToUnderlyingCallsCount - } else { - var returnValue: Int? = nil - DispatchQueue.main.sync { - returnValue = inReplyToUnderlyingCallsCount - } - - return returnValue! - } - } - set { - if Thread.isMainThread { - inReplyToUnderlyingCallsCount = newValue - } else { - DispatchQueue.main.sync { - inReplyToUnderlyingCallsCount = newValue - } - } - } - } - open var inReplyToCalled: Bool { - return inReplyToCallsCount > 0 - } - - var inReplyToUnderlyingReturnValue: InReplyToDetails? - open var inReplyToReturnValue: InReplyToDetails? { - get { - if Thread.isMainThread { - return inReplyToUnderlyingReturnValue - } else { - var returnValue: InReplyToDetails?? = nil - DispatchQueue.main.sync { - returnValue = inReplyToUnderlyingReturnValue - } - - return returnValue! - } - } - set { - if Thread.isMainThread { - inReplyToUnderlyingReturnValue = newValue - } else { - DispatchQueue.main.sync { - inReplyToUnderlyingReturnValue = newValue - } - } - } - } - open var inReplyToClosure: (() -> InReplyToDetails?)? - - open override func inReplyTo() -> InReplyToDetails? { - inReplyToCallsCount += 1 - if let inReplyToClosure = inReplyToClosure { - return inReplyToClosure() - } else { - return inReplyToReturnValue - } - } - - //MARK: - isEdited - - var isEditedUnderlyingCallsCount = 0 - open var isEditedCallsCount: Int { - get { - if Thread.isMainThread { - return isEditedUnderlyingCallsCount - } else { - var returnValue: Int? = nil - DispatchQueue.main.sync { - returnValue = isEditedUnderlyingCallsCount - } - - return returnValue! - } - } - set { - if Thread.isMainThread { - isEditedUnderlyingCallsCount = newValue - } else { - DispatchQueue.main.sync { - isEditedUnderlyingCallsCount = newValue - } - } - } - } - open var isEditedCalled: Bool { - return isEditedCallsCount > 0 - } - - var isEditedUnderlyingReturnValue: Bool! - open var isEditedReturnValue: Bool! { - get { - if Thread.isMainThread { - return isEditedUnderlyingReturnValue - } else { - var returnValue: Bool? = nil - DispatchQueue.main.sync { - returnValue = isEditedUnderlyingReturnValue - } - - return returnValue! - } - } - set { - if Thread.isMainThread { - isEditedUnderlyingReturnValue = newValue - } else { - DispatchQueue.main.sync { - isEditedUnderlyingReturnValue = newValue - } - } - } - } - open var isEditedClosure: (() -> Bool)? - - open override func isEdited() -> Bool { - isEditedCallsCount += 1 - if let isEditedClosure = isEditedClosure { - return isEditedClosure() - } else { - return isEditedReturnValue - } - } - - //MARK: - isThreaded - - var isThreadedUnderlyingCallsCount = 0 - open var isThreadedCallsCount: Int { - get { - if Thread.isMainThread { - return isThreadedUnderlyingCallsCount - } else { - var returnValue: Int? = nil - DispatchQueue.main.sync { - returnValue = isThreadedUnderlyingCallsCount - } - - return returnValue! - } - } - set { - if Thread.isMainThread { - isThreadedUnderlyingCallsCount = newValue - } else { - DispatchQueue.main.sync { - isThreadedUnderlyingCallsCount = newValue - } - } - } - } - open var isThreadedCalled: Bool { - return isThreadedCallsCount > 0 - } - - var isThreadedUnderlyingReturnValue: Bool! - open var isThreadedReturnValue: Bool! { - get { - if Thread.isMainThread { - return isThreadedUnderlyingReturnValue - } else { - var returnValue: Bool? = nil - DispatchQueue.main.sync { - returnValue = isThreadedUnderlyingReturnValue - } - - return returnValue! - } - } - set { - if Thread.isMainThread { - isThreadedUnderlyingReturnValue = newValue - } else { - DispatchQueue.main.sync { - isThreadedUnderlyingReturnValue = newValue - } - } - } - } - open var isThreadedClosure: (() -> Bool)? - - open override func isThreaded() -> Bool { - isThreadedCallsCount += 1 - if let isThreadedClosure = isThreadedClosure { - return isThreadedClosure() - } else { - return isThreadedReturnValue - } - } - - //MARK: - msgtype - - var msgtypeUnderlyingCallsCount = 0 - open var msgtypeCallsCount: Int { - get { - if Thread.isMainThread { - return msgtypeUnderlyingCallsCount - } else { - var returnValue: Int? = nil - DispatchQueue.main.sync { - returnValue = msgtypeUnderlyingCallsCount - } - - return returnValue! - } - } - set { - if Thread.isMainThread { - msgtypeUnderlyingCallsCount = newValue - } else { - DispatchQueue.main.sync { - msgtypeUnderlyingCallsCount = newValue - } - } - } - } - open var msgtypeCalled: Bool { - return msgtypeCallsCount > 0 - } - - var msgtypeUnderlyingReturnValue: MessageType! - open var msgtypeReturnValue: MessageType! { - get { - if Thread.isMainThread { - return msgtypeUnderlyingReturnValue - } else { - var returnValue: MessageType? = nil - DispatchQueue.main.sync { - returnValue = msgtypeUnderlyingReturnValue - } - - return returnValue! - } - } - set { - if Thread.isMainThread { - msgtypeUnderlyingReturnValue = newValue - } else { - DispatchQueue.main.sync { - msgtypeUnderlyingReturnValue = newValue - } - } - } - } - open var msgtypeClosure: (() -> MessageType)? - - open override func msgtype() -> MessageType { - msgtypeCallsCount += 1 - if let msgtypeClosure = msgtypeClosure { - return msgtypeClosure() - } else { - return msgtypeReturnValue - } - } -} open class NotificationClientSDKMock: MatrixRustSDK.NotificationClient { init() { super.init(noPointer: .init()) @@ -18861,6 +17637,77 @@ open class TimelineSDKMock: MatrixRustSDK.Timeline { } } + //MARK: - createMessageContent + + var createMessageContentMsgTypeUnderlyingCallsCount = 0 + open var createMessageContentMsgTypeCallsCount: Int { + get { + if Thread.isMainThread { + return createMessageContentMsgTypeUnderlyingCallsCount + } else { + var returnValue: Int? = nil + DispatchQueue.main.sync { + returnValue = createMessageContentMsgTypeUnderlyingCallsCount + } + + return returnValue! + } + } + set { + if Thread.isMainThread { + createMessageContentMsgTypeUnderlyingCallsCount = newValue + } else { + DispatchQueue.main.sync { + createMessageContentMsgTypeUnderlyingCallsCount = newValue + } + } + } + } + open var createMessageContentMsgTypeCalled: Bool { + return createMessageContentMsgTypeCallsCount > 0 + } + open var createMessageContentMsgTypeReceivedMsgType: MessageType? + open var createMessageContentMsgTypeReceivedInvocations: [MessageType] = [] + + var createMessageContentMsgTypeUnderlyingReturnValue: RoomMessageEventContentWithoutRelation? + open var createMessageContentMsgTypeReturnValue: RoomMessageEventContentWithoutRelation? { + get { + if Thread.isMainThread { + return createMessageContentMsgTypeUnderlyingReturnValue + } else { + var returnValue: RoomMessageEventContentWithoutRelation?? = nil + DispatchQueue.main.sync { + returnValue = createMessageContentMsgTypeUnderlyingReturnValue + } + + return returnValue! + } + } + set { + if Thread.isMainThread { + createMessageContentMsgTypeUnderlyingReturnValue = newValue + } else { + DispatchQueue.main.sync { + createMessageContentMsgTypeUnderlyingReturnValue = newValue + } + } + } + } + open var createMessageContentMsgTypeClosure: ((MessageType) -> RoomMessageEventContentWithoutRelation?)? + + open override func createMessageContent(msgType: MessageType) -> RoomMessageEventContentWithoutRelation? { + createMessageContentMsgTypeCallsCount += 1 + createMessageContentMsgTypeReceivedMsgType = msgType + DispatchQueue.main.async { + self.createMessageContentMsgTypeReceivedInvocations.append(msgType) + } + if let createMessageContentMsgTypeClosure = createMessageContentMsgTypeClosure { + return createMessageContentMsgTypeClosure(msgType) + } else { + return createMessageContentMsgTypeReturnValue + } + } + //MARK: - createPoll open var createPollQuestionAnswersMaxSelectionsPollKindThrowableError: Error? @@ -18909,16 +17756,16 @@ open class TimelineSDKMock: MatrixRustSDK.Timeline { //MARK: - edit - open var editItemNewContentThrowableError: Error? - var editItemNewContentUnderlyingCallsCount = 0 - open var editItemNewContentCallsCount: Int { + open var editEventOrTransactionIdNewContentThrowableError: Error? + var editEventOrTransactionIdNewContentUnderlyingCallsCount = 0 + open var editEventOrTransactionIdNewContentCallsCount: Int { get { if Thread.isMainThread { - return editItemNewContentUnderlyingCallsCount + return editEventOrTransactionIdNewContentUnderlyingCallsCount } else { var returnValue: Int? = nil DispatchQueue.main.sync { - returnValue = editItemNewContentUnderlyingCallsCount + returnValue = editEventOrTransactionIdNewContentUnderlyingCallsCount } return returnValue! @@ -18926,29 +17773,29 @@ open class TimelineSDKMock: MatrixRustSDK.Timeline { } set { if Thread.isMainThread { - editItemNewContentUnderlyingCallsCount = newValue + editEventOrTransactionIdNewContentUnderlyingCallsCount = newValue } else { DispatchQueue.main.sync { - editItemNewContentUnderlyingCallsCount = newValue + editEventOrTransactionIdNewContentUnderlyingCallsCount = newValue } } } } - open var editItemNewContentCalled: Bool { - return editItemNewContentCallsCount > 0 + open var editEventOrTransactionIdNewContentCalled: Bool { + return editEventOrTransactionIdNewContentCallsCount > 0 } - open var editItemNewContentReceivedArguments: (item: EventTimelineItem, newContent: EditedContent)? - open var editItemNewContentReceivedInvocations: [(item: EventTimelineItem, newContent: EditedContent)] = [] + open var editEventOrTransactionIdNewContentReceivedArguments: (eventOrTransactionId: EventOrTransactionId, newContent: EditedContent)? + open var editEventOrTransactionIdNewContentReceivedInvocations: [(eventOrTransactionId: EventOrTransactionId, newContent: EditedContent)] = [] - var editItemNewContentUnderlyingReturnValue: Bool! - open var editItemNewContentReturnValue: Bool! { + var editEventOrTransactionIdNewContentUnderlyingReturnValue: Bool! + open var editEventOrTransactionIdNewContentReturnValue: Bool! { get { if Thread.isMainThread { - return editItemNewContentUnderlyingReturnValue + return editEventOrTransactionIdNewContentUnderlyingReturnValue } else { var returnValue: Bool? = nil DispatchQueue.main.sync { - returnValue = editItemNewContentUnderlyingReturnValue + returnValue = editEventOrTransactionIdNewContentUnderlyingReturnValue } return returnValue! @@ -18956,44 +17803,44 @@ open class TimelineSDKMock: MatrixRustSDK.Timeline { } set { if Thread.isMainThread { - editItemNewContentUnderlyingReturnValue = newValue + editEventOrTransactionIdNewContentUnderlyingReturnValue = newValue } else { DispatchQueue.main.sync { - editItemNewContentUnderlyingReturnValue = newValue + editEventOrTransactionIdNewContentUnderlyingReturnValue = newValue } } } } - open var editItemNewContentClosure: ((EventTimelineItem, EditedContent) async throws -> Bool)? + open var editEventOrTransactionIdNewContentClosure: ((EventOrTransactionId, EditedContent) async throws -> Bool)? - open override func edit(item: EventTimelineItem, newContent: EditedContent) async throws -> Bool { - if let error = editItemNewContentThrowableError { + open override func edit(eventOrTransactionId: EventOrTransactionId, newContent: EditedContent) async throws -> Bool { + if let error = editEventOrTransactionIdNewContentThrowableError { throw error } - editItemNewContentCallsCount += 1 - editItemNewContentReceivedArguments = (item: item, newContent: newContent) + editEventOrTransactionIdNewContentCallsCount += 1 + editEventOrTransactionIdNewContentReceivedArguments = (eventOrTransactionId: eventOrTransactionId, newContent: newContent) DispatchQueue.main.async { - self.editItemNewContentReceivedInvocations.append((item: item, newContent: newContent)) + self.editEventOrTransactionIdNewContentReceivedInvocations.append((eventOrTransactionId: eventOrTransactionId, newContent: newContent)) } - if let editItemNewContentClosure = editItemNewContentClosure { - return try await editItemNewContentClosure(item, newContent) + if let editEventOrTransactionIdNewContentClosure = editEventOrTransactionIdNewContentClosure { + return try await editEventOrTransactionIdNewContentClosure(eventOrTransactionId, newContent) } else { - return editItemNewContentReturnValue + return editEventOrTransactionIdNewContentReturnValue } } //MARK: - endPoll - open var endPollPollStartIdTextThrowableError: Error? - var endPollPollStartIdTextUnderlyingCallsCount = 0 - open var endPollPollStartIdTextCallsCount: Int { + open var endPollPollStartEventIdTextThrowableError: Error? + var endPollPollStartEventIdTextUnderlyingCallsCount = 0 + open var endPollPollStartEventIdTextCallsCount: Int { get { if Thread.isMainThread { - return endPollPollStartIdTextUnderlyingCallsCount + return endPollPollStartEventIdTextUnderlyingCallsCount } else { var returnValue: Int? = nil DispatchQueue.main.sync { - returnValue = endPollPollStartIdTextUnderlyingCallsCount + returnValue = endPollPollStartEventIdTextUnderlyingCallsCount } return returnValue! @@ -19001,31 +17848,31 @@ open class TimelineSDKMock: MatrixRustSDK.Timeline { } set { if Thread.isMainThread { - endPollPollStartIdTextUnderlyingCallsCount = newValue + endPollPollStartEventIdTextUnderlyingCallsCount = newValue } else { DispatchQueue.main.sync { - endPollPollStartIdTextUnderlyingCallsCount = newValue + endPollPollStartEventIdTextUnderlyingCallsCount = newValue } } } } - open var endPollPollStartIdTextCalled: Bool { - return endPollPollStartIdTextCallsCount > 0 + open var endPollPollStartEventIdTextCalled: Bool { + return endPollPollStartEventIdTextCallsCount > 0 } - open var endPollPollStartIdTextReceivedArguments: (pollStartId: String, text: String)? - open var endPollPollStartIdTextReceivedInvocations: [(pollStartId: String, text: String)] = [] - open var endPollPollStartIdTextClosure: ((String, String) throws -> Void)? + open var endPollPollStartEventIdTextReceivedArguments: (pollStartEventId: String, text: String)? + open var endPollPollStartEventIdTextReceivedInvocations: [(pollStartEventId: String, text: String)] = [] + open var endPollPollStartEventIdTextClosure: ((String, String) throws -> Void)? - open override func endPoll(pollStartId: String, text: String) throws { - if let error = endPollPollStartIdTextThrowableError { + open override func endPoll(pollStartEventId: String, text: String) throws { + if let error = endPollPollStartEventIdTextThrowableError { throw error } - endPollPollStartIdTextCallsCount += 1 - endPollPollStartIdTextReceivedArguments = (pollStartId: pollStartId, text: text) + endPollPollStartEventIdTextCallsCount += 1 + endPollPollStartEventIdTextReceivedArguments = (pollStartEventId: pollStartEventId, text: text) DispatchQueue.main.async { - self.endPollPollStartIdTextReceivedInvocations.append((pollStartId: pollStartId, text: text)) + self.endPollPollStartEventIdTextReceivedInvocations.append((pollStartEventId: pollStartEventId, text: text)) } - try endPollPollStartIdTextClosure?(pollStartId, text) + try endPollPollStartEventIdTextClosure?(pollStartEventId, text) } //MARK: - fetchDetailsForEvent @@ -19608,16 +18455,16 @@ open class TimelineSDKMock: MatrixRustSDK.Timeline { //MARK: - redactEvent - open var redactEventItemReasonThrowableError: Error? - var redactEventItemReasonUnderlyingCallsCount = 0 - open var redactEventItemReasonCallsCount: Int { + open var redactEventEventOrTransactionIdReasonThrowableError: Error? + var redactEventEventOrTransactionIdReasonUnderlyingCallsCount = 0 + open var redactEventEventOrTransactionIdReasonCallsCount: Int { get { if Thread.isMainThread { - return redactEventItemReasonUnderlyingCallsCount + return redactEventEventOrTransactionIdReasonUnderlyingCallsCount } else { var returnValue: Int? = nil DispatchQueue.main.sync { - returnValue = redactEventItemReasonUnderlyingCallsCount + returnValue = redactEventEventOrTransactionIdReasonUnderlyingCallsCount } return returnValue! @@ -19625,60 +18472,31 @@ open class TimelineSDKMock: MatrixRustSDK.Timeline { } set { if Thread.isMainThread { - redactEventItemReasonUnderlyingCallsCount = newValue + redactEventEventOrTransactionIdReasonUnderlyingCallsCount = newValue } else { DispatchQueue.main.sync { - redactEventItemReasonUnderlyingCallsCount = newValue + redactEventEventOrTransactionIdReasonUnderlyingCallsCount = newValue } } } } - open var redactEventItemReasonCalled: Bool { - return redactEventItemReasonCallsCount > 0 + open var redactEventEventOrTransactionIdReasonCalled: Bool { + return redactEventEventOrTransactionIdReasonCallsCount > 0 } - open var redactEventItemReasonReceivedArguments: (item: EventTimelineItem, reason: String?)? - open var redactEventItemReasonReceivedInvocations: [(item: EventTimelineItem, reason: String?)] = [] + open var redactEventEventOrTransactionIdReasonReceivedArguments: (eventOrTransactionId: EventOrTransactionId, reason: String?)? + open var redactEventEventOrTransactionIdReasonReceivedInvocations: [(eventOrTransactionId: EventOrTransactionId, reason: String?)] = [] + open var redactEventEventOrTransactionIdReasonClosure: ((EventOrTransactionId, String?) async throws -> Void)? - var redactEventItemReasonUnderlyingReturnValue: Bool! - open var redactEventItemReasonReturnValue: Bool! { - get { - if Thread.isMainThread { - return redactEventItemReasonUnderlyingReturnValue - } else { - var returnValue: Bool? = nil - DispatchQueue.main.sync { - returnValue = redactEventItemReasonUnderlyingReturnValue - } - - return returnValue! - } - } - set { - if Thread.isMainThread { - redactEventItemReasonUnderlyingReturnValue = newValue - } else { - DispatchQueue.main.sync { - redactEventItemReasonUnderlyingReturnValue = newValue - } - } - } - } - open var redactEventItemReasonClosure: ((EventTimelineItem, String?) async throws -> Bool)? - - open override func redactEvent(item: EventTimelineItem, reason: String?) async throws -> Bool { - if let error = redactEventItemReasonThrowableError { + open override func redactEvent(eventOrTransactionId: EventOrTransactionId, reason: String?) async throws { + if let error = redactEventEventOrTransactionIdReasonThrowableError { throw error } - redactEventItemReasonCallsCount += 1 - redactEventItemReasonReceivedArguments = (item: item, reason: reason) + redactEventEventOrTransactionIdReasonCallsCount += 1 + redactEventEventOrTransactionIdReasonReceivedArguments = (eventOrTransactionId: eventOrTransactionId, reason: reason) DispatchQueue.main.async { - self.redactEventItemReasonReceivedInvocations.append((item: item, reason: reason)) - } - if let redactEventItemReasonClosure = redactEventItemReasonClosure { - return try await redactEventItemReasonClosure(item, reason) - } else { - return redactEventItemReasonReturnValue + self.redactEventEventOrTransactionIdReasonReceivedInvocations.append((eventOrTransactionId: eventOrTransactionId, reason: reason)) } + try await redactEventEventOrTransactionIdReasonClosure?(eventOrTransactionId, reason) } //MARK: - retryDecryption @@ -20055,16 +18873,16 @@ open class TimelineSDKMock: MatrixRustSDK.Timeline { //MARK: - sendPollResponse - open var sendPollResponsePollStartIdAnswersThrowableError: Error? - var sendPollResponsePollStartIdAnswersUnderlyingCallsCount = 0 - open var sendPollResponsePollStartIdAnswersCallsCount: Int { + open var sendPollResponsePollStartEventIdAnswersThrowableError: Error? + var sendPollResponsePollStartEventIdAnswersUnderlyingCallsCount = 0 + open var sendPollResponsePollStartEventIdAnswersCallsCount: Int { get { if Thread.isMainThread { - return sendPollResponsePollStartIdAnswersUnderlyingCallsCount + return sendPollResponsePollStartEventIdAnswersUnderlyingCallsCount } else { var returnValue: Int? = nil DispatchQueue.main.sync { - returnValue = sendPollResponsePollStartIdAnswersUnderlyingCallsCount + returnValue = sendPollResponsePollStartEventIdAnswersUnderlyingCallsCount } return returnValue! @@ -20072,31 +18890,31 @@ open class TimelineSDKMock: MatrixRustSDK.Timeline { } set { if Thread.isMainThread { - sendPollResponsePollStartIdAnswersUnderlyingCallsCount = newValue + sendPollResponsePollStartEventIdAnswersUnderlyingCallsCount = newValue } else { DispatchQueue.main.sync { - sendPollResponsePollStartIdAnswersUnderlyingCallsCount = newValue + sendPollResponsePollStartEventIdAnswersUnderlyingCallsCount = newValue } } } } - open var sendPollResponsePollStartIdAnswersCalled: Bool { - return sendPollResponsePollStartIdAnswersCallsCount > 0 + open var sendPollResponsePollStartEventIdAnswersCalled: Bool { + return sendPollResponsePollStartEventIdAnswersCallsCount > 0 } - open var sendPollResponsePollStartIdAnswersReceivedArguments: (pollStartId: String, answers: [String])? - open var sendPollResponsePollStartIdAnswersReceivedInvocations: [(pollStartId: String, answers: [String])] = [] - open var sendPollResponsePollStartIdAnswersClosure: ((String, [String]) async throws -> Void)? + open var sendPollResponsePollStartEventIdAnswersReceivedArguments: (pollStartEventId: String, answers: [String])? + open var sendPollResponsePollStartEventIdAnswersReceivedInvocations: [(pollStartEventId: String, answers: [String])] = [] + open var sendPollResponsePollStartEventIdAnswersClosure: ((String, [String]) async throws -> Void)? - open override func sendPollResponse(pollStartId: String, answers: [String]) async throws { - if let error = sendPollResponsePollStartIdAnswersThrowableError { + open override func sendPollResponse(pollStartEventId: String, answers: [String]) async throws { + if let error = sendPollResponsePollStartEventIdAnswersThrowableError { throw error } - sendPollResponsePollStartIdAnswersCallsCount += 1 - sendPollResponsePollStartIdAnswersReceivedArguments = (pollStartId: pollStartId, answers: answers) + sendPollResponsePollStartEventIdAnswersCallsCount += 1 + sendPollResponsePollStartEventIdAnswersReceivedArguments = (pollStartEventId: pollStartEventId, answers: answers) DispatchQueue.main.async { - self.sendPollResponsePollStartIdAnswersReceivedInvocations.append((pollStartId: pollStartId, answers: answers)) + self.sendPollResponsePollStartEventIdAnswersReceivedInvocations.append((pollStartEventId: pollStartEventId, answers: answers)) } - try await sendPollResponsePollStartIdAnswersClosure?(pollStartId, answers) + try await sendPollResponsePollStartEventIdAnswersClosure?(pollStartEventId, answers) } //MARK: - sendReadReceipt @@ -21685,147 +20503,6 @@ open class TimelineItemSDKMock: MatrixRustSDK.TimelineItem { } } } -open class TimelineItemContentSDKMock: MatrixRustSDK.TimelineItemContent { - init() { - super.init(noPointer: .init()) - } - - public required init(unsafeFromRawPointer pointer: UnsafeMutableRawPointer) { - fatalError("init(unsafeFromRawPointer:) has not been implemented") - } - - fileprivate var pointer: UnsafeMutableRawPointer! - - //MARK: - asMessage - - var asMessageUnderlyingCallsCount = 0 - open var asMessageCallsCount: Int { - get { - if Thread.isMainThread { - return asMessageUnderlyingCallsCount - } else { - var returnValue: Int? = nil - DispatchQueue.main.sync { - returnValue = asMessageUnderlyingCallsCount - } - - return returnValue! - } - } - set { - if Thread.isMainThread { - asMessageUnderlyingCallsCount = newValue - } else { - DispatchQueue.main.sync { - asMessageUnderlyingCallsCount = newValue - } - } - } - } - open var asMessageCalled: Bool { - return asMessageCallsCount > 0 - } - - var asMessageUnderlyingReturnValue: Message? - open var asMessageReturnValue: Message? { - get { - if Thread.isMainThread { - return asMessageUnderlyingReturnValue - } else { - var returnValue: Message?? = nil - DispatchQueue.main.sync { - returnValue = asMessageUnderlyingReturnValue - } - - return returnValue! - } - } - set { - if Thread.isMainThread { - asMessageUnderlyingReturnValue = newValue - } else { - DispatchQueue.main.sync { - asMessageUnderlyingReturnValue = newValue - } - } - } - } - open var asMessageClosure: (() -> Message?)? - - open override func asMessage() -> Message? { - asMessageCallsCount += 1 - if let asMessageClosure = asMessageClosure { - return asMessageClosure() - } else { - return asMessageReturnValue - } - } - - //MARK: - kind - - var kindUnderlyingCallsCount = 0 - open var kindCallsCount: Int { - get { - if Thread.isMainThread { - return kindUnderlyingCallsCount - } else { - var returnValue: Int? = nil - DispatchQueue.main.sync { - returnValue = kindUnderlyingCallsCount - } - - return returnValue! - } - } - set { - if Thread.isMainThread { - kindUnderlyingCallsCount = newValue - } else { - DispatchQueue.main.sync { - kindUnderlyingCallsCount = newValue - } - } - } - } - open var kindCalled: Bool { - return kindCallsCount > 0 - } - - var kindUnderlyingReturnValue: TimelineItemContentKind! - open var kindReturnValue: TimelineItemContentKind! { - get { - if Thread.isMainThread { - return kindUnderlyingReturnValue - } else { - var returnValue: TimelineItemContentKind? = nil - DispatchQueue.main.sync { - returnValue = kindUnderlyingReturnValue - } - - return returnValue! - } - } - set { - if Thread.isMainThread { - kindUnderlyingReturnValue = newValue - } else { - DispatchQueue.main.sync { - kindUnderlyingReturnValue = newValue - } - } - } - } - open var kindClosure: (() -> TimelineItemContentKind)? - - open override func kind() -> TimelineItemContentKind { - kindCallsCount += 1 - if let kindClosure = kindClosure { - return kindClosure() - } else { - return kindReturnValue - } - } -} open class UnreadNotificationsCountSDKMock: MatrixRustSDK.UnreadNotificationsCount { init() { super.init(noPointer: .init()) diff --git a/ElementX/Sources/Mocks/PollMock.swift b/ElementX/Sources/Mocks/PollMock.swift index cc3322871..0da15ef33 100644 --- a/ElementX/Sources/Mocks/PollMock.swift +++ b/ElementX/Sources/Mocks/PollMock.swift @@ -82,7 +82,7 @@ extension Poll.Option { extension PollRoomTimelineItem { static func mock(poll: Poll, isOutgoing: Bool = true, isEditable: Bool = false) -> Self { - .init(id: .init(timelineID: UUID().uuidString, eventID: UUID().uuidString), + .init(id: .random, poll: poll, body: "poll", timestamp: "Now", diff --git a/ElementX/Sources/Mocks/RoomTimelineProviderMock.swift b/ElementX/Sources/Mocks/RoomTimelineProviderMock.swift index 0e671fcfe..12a1e4806 100644 --- a/ElementX/Sources/Mocks/RoomTimelineProviderMock.swift +++ b/ElementX/Sources/Mocks/RoomTimelineProviderMock.swift @@ -35,7 +35,12 @@ class AutoUpdatingRoomTimelineProviderMock: RoomTimelineProvider { let diff = TimelineDiffSDKMock() diff.changeReturnValue = .append - diff.appendReturnValue = [TimelineItemFixtures.messageTimelineItem] + + let timelineItem = TimelineItemSDKMock() + timelineItem.asEventReturnValue = EventTimelineItem.mockMessage + timelineItem.uniqueIdReturnValue = UUID().uuidString + + diff.appendReturnValue = [timelineItem] await Self.timelineListener?.onUpdate(diff: [diff]) } diff --git a/ElementX/Sources/Mocks/SDK/EventTimelineItemSDKMock.swift b/ElementX/Sources/Mocks/SDK/EventTimelineItemSDKMock.swift deleted file mode 100644 index fbeea26eb..000000000 --- a/ElementX/Sources/Mocks/SDK/EventTimelineItemSDKMock.swift +++ /dev/null @@ -1,29 +0,0 @@ -// -// Copyright 2024 New Vector Ltd. -// -// SPDX-License-Identifier: AGPL-3.0-only -// Please see LICENSE in the repository root for full details. -// - -import Foundation - -struct EventTimelineItemSDKMockConfiguration { - var eventID: String = UUID().uuidString -} - -extension EventTimelineItemSDKMock { - convenience init(configuration: EventTimelineItemSDKMockConfiguration) { - self.init() - eventIdReturnValue = configuration.eventID - isOwnReturnValue = false - timestampReturnValue = 0 - isEditableReturnValue = false - canBeRepliedToReturnValue = false - senderReturnValue = "" - senderProfileReturnValue = .pending - - let timelineItemContent = TimelineItemContentSDKMock() - timelineItemContent.kindReturnValue = .redactedMessage - contentReturnValue = timelineItemContent - } -} diff --git a/ElementX/Sources/Mocks/TimelineItemMock.swift b/ElementX/Sources/Mocks/TimelineItemMock.swift deleted file mode 100644 index 82138364e..000000000 --- a/ElementX/Sources/Mocks/TimelineItemMock.swift +++ /dev/null @@ -1,66 +0,0 @@ -// -// Copyright 2024 New Vector Ltd. -// -// SPDX-License-Identifier: AGPL-3.0-only -// Please see LICENSE in the repository root for full details. -// - -import Combine -import Foundation -import LoremSwiftum -import MatrixRustSDK - -enum TimelineItemFixtures { - static var callInviteTimelineItem: TimelineItem { - let eventTimelineItem = EventTimelineItemSDKMock() - eventTimelineItem.isOwnReturnValue = true - eventTimelineItem.timestampReturnValue = 0 - eventTimelineItem.isEditableReturnValue = false - eventTimelineItem.canBeRepliedToReturnValue = false - eventTimelineItem.senderReturnValue = "@bob:matrix.org" - eventTimelineItem.senderProfileReturnValue = .pending - - let timelineItemContent = TimelineItemContentSDKMock() - timelineItemContent.kindReturnValue = .callInvite - eventTimelineItem.contentReturnValue = timelineItemContent - - let timelineItem = TimelineItemSDKMock() - timelineItem.asEventReturnValue = eventTimelineItem - - return timelineItem - } - - static var messageTimelineItem: TimelineItem { - let eventTimelineItem = EventTimelineItemSDKMock() - eventTimelineItem.eventIdReturnValue = UUID().uuidString - eventTimelineItem.isOwnReturnValue = true - eventTimelineItem.timestampReturnValue = 0 - eventTimelineItem.isEditableReturnValue = false - eventTimelineItem.canBeRepliedToReturnValue = false - eventTimelineItem.senderReturnValue = "@bob:matrix.org" - eventTimelineItem.senderProfileReturnValue = .pending - eventTimelineItem.reactionsReturnValue = [] - eventTimelineItem.readReceiptsReturnValue = [:] - - let timelineItemContent = TimelineItemContentSDKMock() - - timelineItemContent.kindReturnValue = .message - - let message = MessageSDKMock() - - let textMessageContent = TextMessageContent(body: Lorem.sentences(Int.random(in: 1...5)), formatted: nil) - message.msgtypeReturnValue = .text(content: textMessageContent) - message.isThreadedReturnValue = false - message.isEditedReturnValue = false - - timelineItemContent.asMessageReturnValue = message - - eventTimelineItem.contentReturnValue = timelineItemContent - - let timelineItem = TimelineItemSDKMock() - timelineItem.asEventReturnValue = eventTimelineItem - timelineItem.uniqueIdReturnValue = UUID().uuidString - - return timelineItem - } -} diff --git a/ElementX/Sources/Other/Extensions/Array.swift b/ElementX/Sources/Other/Extensions/Array.swift index 7622916e8..a5fd0fd0a 100644 --- a/ElementX/Sources/Other/Extensions/Array.swift +++ b/ElementX/Sources/Other/Extensions/Array.swift @@ -61,6 +61,6 @@ extension Array { extension Array where Element == RoomTimelineItemProtocol { func firstUsingStableID(_ id: TimelineItemIdentifier) -> Element? { - first { $0.id.timelineID == id.timelineID } + first { $0.id.uniqueID == id.uniqueID } } } diff --git a/ElementX/Sources/Other/Extensions/ProposedViewSize.swift b/ElementX/Sources/Other/Extensions/ProposedViewSize.swift index 17067d58c..a9995015e 100644 --- a/ElementX/Sources/Other/Extensions/ProposedViewSize.swift +++ b/ElementX/Sources/Other/Extensions/ProposedViewSize.swift @@ -7,7 +7,7 @@ import SwiftUI -extension ProposedViewSize: Hashable { +extension ProposedViewSize: @retroactive Hashable { public func hash(into hasher: inout Hasher) { hasher.combine(width) hasher.combine(height) diff --git a/ElementX/Sources/Other/Extensions/URL.swift b/ElementX/Sources/Other/Extensions/URL.swift index e23d72aea..3506d46c5 100644 --- a/ElementX/Sources/Other/Extensions/URL.swift +++ b/ElementX/Sources/Other/Extensions/URL.swift @@ -7,7 +7,7 @@ import Foundation -extension URL: ExpressibleByStringLiteral { +extension URL: @retroactive ExpressibleByStringLiteral { public init(stringLiteral value: StaticString) { guard let url = URL(string: "\(value)") else { fatalError("The static string used to create this URL is invalid") diff --git a/ElementX/Sources/Screens/MessageForwardingScreen/View/MessageForwardingScreen.swift b/ElementX/Sources/Screens/MessageForwardingScreen/View/MessageForwardingScreen.swift index cb1fec8ea..5975bfaba 100644 --- a/ElementX/Sources/Screens/MessageForwardingScreen/View/MessageForwardingScreen.swift +++ b/ElementX/Sources/Screens/MessageForwardingScreen/View/MessageForwardingScreen.swift @@ -93,7 +93,7 @@ private struct MessageForwardingListRow: View { struct MessageForwardingScreen_Previews: PreviewProvider, TestablePreview { static var previews: some View { let summaryProvider = RoomSummaryProviderMock(.init(state: .loaded(.mockRooms))) - let viewModel = MessageForwardingScreenViewModel(forwardingItem: .init(id: .init(timelineID: ""), + let viewModel = MessageForwardingScreenViewModel(forwardingItem: .init(id: .init(uniqueID: ""), roomID: "", content: .init(noPointer: .init())), clientProxy: ClientProxyMock(.init()), diff --git a/ElementX/Sources/Screens/RoomScreen/ComposerToolbar/ComposerToolbarViewModel.swift b/ElementX/Sources/Screens/RoomScreen/ComposerToolbar/ComposerToolbarViewModel.swift index f9bad3c7d..970ee05be 100644 --- a/ElementX/Sources/Screens/RoomScreen/ComposerToolbar/ComposerToolbarViewModel.swift +++ b/ElementX/Sources/Screens/RoomScreen/ComposerToolbar/ComposerToolbarViewModel.swift @@ -258,9 +258,9 @@ final class ComposerToolbarViewModel: ComposerToolbarViewModelType, ComposerTool case .newMessage: set(mode: .default) case .edit(let eventID): - set(mode: .edit(originalItemId: .init(timelineID: "", eventID: eventID))) + set(mode: .edit(originalItemId: .init(uniqueID: "", eventOrTransactionID: .eventId(eventId: eventID)))) case .reply(let eventID): - set(mode: .reply(itemID: .init(timelineID: "", eventID: eventID), replyDetails: .loading(eventID: eventID), isThread: false)) + set(mode: .reply(itemID: .init(uniqueID: "", eventOrTransactionID: .eventId(eventId: eventID)), replyDetails: .loading(eventID: eventID), isThread: false)) replyLoadingTask = Task { let reply = switch await draftService.getReply(eventID: eventID) { case .success(let reply): @@ -273,7 +273,7 @@ final class ComposerToolbarViewModel: ComposerToolbarViewModelType, ComposerTool return } - set(mode: .reply(itemID: .init(timelineID: "", eventID: eventID), replyDetails: reply.details, isThread: reply.isThreaded)) + set(mode: .reply(itemID: .init(uniqueID: "", eventOrTransactionID: .eventId(eventId: eventID)), replyDetails: reply.details, isThread: reply.isThreaded)) } } } diff --git a/ElementX/Sources/Screens/RoomScreen/ComposerToolbar/View/ComposerToolbar.swift b/ElementX/Sources/Screens/RoomScreen/ComposerToolbar/View/ComposerToolbar.swift index bf6185866..0c463ad1e 100644 --- a/ElementX/Sources/Screens/RoomScreen/ComposerToolbar/View/ComposerToolbar.swift +++ b/ElementX/Sources/Screens/RoomScreen/ComposerToolbar/View/ComposerToolbar.swift @@ -415,10 +415,10 @@ extension ComposerToolbar { mentionDisplayHelper: ComposerMentionDisplayHelper.mock, analyticsService: ServiceLocator.shared.analytics, composerDraftService: ComposerDraftServiceMock()) - model.state.composerMode = isLoading ? .reply(itemID: .init(timelineID: ""), + model.state.composerMode = isLoading ? .reply(itemID: .init(uniqueID: ""), replyDetails: .loading(eventID: ""), isThread: false) : - .reply(itemID: .init(timelineID: ""), + .reply(itemID: .init(uniqueID: ""), replyDetails: .loaded(sender: .init(id: "", displayName: "Test"), eventID: "", eventContent: .message(.text(.init(body: "Hello World!")))), isThread: false) diff --git a/ElementX/Sources/Screens/Timeline/TimelineModels.swift b/ElementX/Sources/Screens/Timeline/TimelineModels.swift index fc6430721..ab7229015 100644 --- a/ElementX/Sources/Screens/Timeline/TimelineModels.swift +++ b/ElementX/Sources/Screens/Timeline/TimelineModels.swift @@ -203,7 +203,7 @@ struct TimelineState { var itemsDictionary = OrderedDictionary() - var timelineIDs: [String] { + var uniqueIDs: [String] { itemsDictionary.keys.elements } diff --git a/ElementX/Sources/Screens/Timeline/TimelineTableViewController.swift b/ElementX/Sources/Screens/Timeline/TimelineTableViewController.swift index b85fbb3fd..6b32e9c74 100644 --- a/ElementX/Sources/Screens/Timeline/TimelineTableViewController.swift +++ b/ElementX/Sources/Screens/Timeline/TimelineTableViewController.swift @@ -401,8 +401,8 @@ class TimelineTableViewController: UIViewController { // These are already in reverse order because the table view is flipped for indexPath in visibleIndexPaths { - if let visibleItemTimelineID = dataSource?.itemIdentifier(for: indexPath), - let visibleItemID = timelineItemsDictionary[visibleItemTimelineID]?.identifier { + if let visibleItemUniqueID = dataSource?.itemIdentifier(for: indexPath), + let visibleItemID = timelineItemsDictionary[visibleItemUniqueID]?.identifier { coordinator.send(viewAction: .sendReadReceiptIfNeeded(visibleItemID)) return } @@ -488,7 +488,7 @@ extension TimelineTableViewController { /// The current layout of the table, based on the newest timeline item. private func snapshotLayout() -> Layout? { guard let newestItemID = newestVisibleItemID(), - let newestCellFrame = cellFrame(for: newestItemID.timelineID) else { + let newestCellFrame = cellFrame(for: newestItemID.uniqueID) else { return nil } return Layout(id: newestItemID, frame: newestCellFrame) @@ -496,12 +496,12 @@ extension TimelineTableViewController { /// Restores the timeline's layout from an old snapshot. private func restoreLayout(_ layout: Layout) { - if let indexPath = dataSource?.indexPath(for: layout.id.timelineID) { + if let indexPath = dataSource?.indexPath(for: layout.id.uniqueID) { // Scroll the item into view. tableView.scrollToRow(at: indexPath, at: .top, animated: false) // Remove any unwanted offset that was added by scrollToRow. - if let frame = cellFrame(for: layout.id.timelineID) { + if let frame = cellFrame(for: layout.id.uniqueID) { let deltaY = frame.maxY - layout.frame.maxY if deltaY != 0 { tableView.contentOffset.y -= deltaY @@ -511,8 +511,8 @@ extension TimelineTableViewController { } /// Returns the frame of the cell for a particular timeline item. - private func cellFrame(for id: String) -> CGRect? { - guard let timelineCell = tableView.visibleCells.first(where: { ($0 as? TimelineItemCell)?.item?.id == id }) else { + private func cellFrame(for uniqueID: String) -> CGRect? { + guard let timelineCell = tableView.visibleCells.first(where: { ($0 as? TimelineItemCell)?.item?.identifier.uniqueID == uniqueID }) else { return nil } diff --git a/ElementX/Sources/Screens/Timeline/TimelineViewModel.swift b/ElementX/Sources/Screens/Timeline/TimelineViewModel.swift index ffc0386f2..e6d37a7df 100644 --- a/ElementX/Sources/Screens/Timeline/TimelineViewModel.swift +++ b/ElementX/Sources/Screens/Timeline/TimelineViewModel.swift @@ -659,19 +659,19 @@ class TimelineViewModel: TimelineViewModelType, TimelineViewModelProtocol { if itemGroup.count == 1 { if let firstItem = itemGroup.first { timelineItemsDictionary.updateValue(updateViewState(item: firstItem, groupStyle: .single), - forKey: firstItem.id.timelineID) + forKey: firstItem.id.uniqueID) } } else { for (index, item) in itemGroup.enumerated() { if index == 0 { timelineItemsDictionary.updateValue(updateViewState(item: item, groupStyle: state.isPinnedEventsTimeline ? .single : .first), - forKey: item.id.timelineID) + forKey: item.id.uniqueID) } else if index == itemGroup.count - 1 { timelineItemsDictionary.updateValue(updateViewState(item: item, groupStyle: state.isPinnedEventsTimeline ? .single : .last), - forKey: item.id.timelineID) + forKey: item.id.uniqueID) } else { timelineItemsDictionary.updateValue(updateViewState(item: item, groupStyle: state.isPinnedEventsTimeline ? .single : .middle), - forKey: item.id.timelineID) + forKey: item.id.uniqueID) } } } @@ -685,7 +685,7 @@ class TimelineViewModel: TimelineViewModelType, TimelineViewModelProtocol { } private func updateViewState(item: RoomTimelineItemProtocol, groupStyle: TimelineGroupStyle) -> RoomTimelineItemViewState { - if let timelineItemViewState = state.timelineViewState.itemsDictionary[item.id.timelineID] { + if let timelineItemViewState = state.timelineViewState.itemsDictionary[item.id.uniqueID] { timelineItemViewState.groupStyle = groupStyle timelineItemViewState.type = .init(item: item) return timelineItemViewState diff --git a/ElementX/Sources/Screens/Timeline/View/Style/SwipeToReplyView.swift b/ElementX/Sources/Screens/Timeline/View/Style/SwipeToReplyView.swift index fb4520621..47b611a66 100644 --- a/ElementX/Sources/Screens/Timeline/View/Style/SwipeToReplyView.swift +++ b/ElementX/Sources/Screens/Timeline/View/Style/SwipeToReplyView.swift @@ -19,7 +19,7 @@ struct SwipeToReplyView: View { } struct SwipeToReplyView_Previews: PreviewProvider, TestablePreview { - static let timelineItem = TextRoomTimelineItem(id: .init(timelineID: ""), + static let timelineItem = TextRoomTimelineItem(id: .init(uniqueID: ""), timestamp: "", isOutgoing: true, isEditable: true, diff --git a/ElementX/Sources/Screens/Timeline/View/Style/TimelineItemBubbledStylerView.swift b/ElementX/Sources/Screens/Timeline/View/Style/TimelineItemBubbledStylerView.swift index 49ca3828b..894d9ef52 100644 --- a/ElementX/Sources/Screens/Timeline/View/Style/TimelineItemBubbledStylerView.swift +++ b/ElementX/Sources/Screens/Timeline/View/Style/TimelineItemBubbledStylerView.swift @@ -388,7 +388,7 @@ struct TimelineItemBubbledStylerView_Previews: PreviewProvider, TestablePreview // These always include a reply static var threads: some View { ScrollView { - RoomTimelineItemView(viewState: .init(item: TextRoomTimelineItem(id: .init(timelineID: ""), + RoomTimelineItemView(viewState: .init(item: TextRoomTimelineItem(id: .init(uniqueID: ""), timestamp: "10:42", isOutgoing: true, isEditable: false, @@ -401,7 +401,7 @@ struct TimelineItemBubbledStylerView_Previews: PreviewProvider, TestablePreview eventContent: .message(.text(.init(body: "Short"))))), groupStyle: .single)) - AudioRoomTimelineView(timelineItem: .init(id: .init(timelineID: ""), + AudioRoomTimelineView(timelineItem: .init(id: .init(uniqueID: ""), timestamp: "10:42", isOutgoing: true, isEditable: false, @@ -417,7 +417,7 @@ struct TimelineItemBubbledStylerView_Previews: PreviewProvider, TestablePreview eventID: "123", eventContent: .message(.text(.init(body: "Short")))))) - FileRoomTimelineView(timelineItem: .init(id: .init(timelineID: ""), + FileRoomTimelineView(timelineItem: .init(id: .init(uniqueID: ""), timestamp: "10:42", isOutgoing: false, isEditable: false, @@ -431,7 +431,7 @@ struct TimelineItemBubbledStylerView_Previews: PreviewProvider, TestablePreview replyDetails: .loaded(sender: .init(id: "", displayName: "Alice"), eventID: "123", eventContent: .message(.text(.init(body: "Short")))))) - ImageRoomTimelineView(timelineItem: .init(id: .init(timelineID: ""), + ImageRoomTimelineView(timelineItem: .init(id: .init(uniqueID: ""), timestamp: "10:42", isOutgoing: true, isEditable: true, @@ -469,7 +469,7 @@ struct TimelineItemBubbledStylerView_Previews: PreviewProvider, TestablePreview eventID: "123", eventContent: .message(.text(.init(body: "Short")))))) - VoiceMessageRoomTimelineView(timelineItem: .init(id: .init(timelineID: ""), + VoiceMessageRoomTimelineView(timelineItem: .init(id: .init(uniqueID: ""), timestamp: "10:42", isOutgoing: true, isEditable: false, @@ -505,7 +505,7 @@ struct TimelineItemBubbledStylerView_Previews: PreviewProvider, TestablePreview static var replies: some View { VStack(spacing: 0) { - RoomTimelineItemView(viewState: .init(item: TextRoomTimelineItem(id: .init(timelineID: ""), + RoomTimelineItemView(viewState: .init(item: TextRoomTimelineItem(id: .init(uniqueID: ""), timestamp: "10:42", isOutgoing: true, isEditable: false, @@ -518,7 +518,7 @@ struct TimelineItemBubbledStylerView_Previews: PreviewProvider, TestablePreview eventContent: .message(.text(.init(body: "Short"))))), groupStyle: .single)) - RoomTimelineItemView(viewState: .init(item: TextRoomTimelineItem(id: .init(timelineID: ""), + RoomTimelineItemView(viewState: .init(item: TextRoomTimelineItem(id: .init(uniqueID: ""), timestamp: "10:42", isOutgoing: true, isEditable: false, @@ -536,7 +536,7 @@ struct TimelineItemBubbledStylerView_Previews: PreviewProvider, TestablePreview static var encryptionAuthenticity: some View { VStack(spacing: 0) { - RoomTimelineItemView(viewState: .init(item: TextRoomTimelineItem(id: .init(timelineID: ""), + RoomTimelineItemView(viewState: .init(item: TextRoomTimelineItem(id: .init(uniqueID: ""), timestamp: "10:42", isOutgoing: true, isEditable: false, @@ -547,7 +547,7 @@ struct TimelineItemBubbledStylerView_Previews: PreviewProvider, TestablePreview properties: RoomTimelineItemProperties(encryptionAuthenticity: .unsignedDevice(color: .red))), groupStyle: .single)) - RoomTimelineItemView(viewState: .init(item: TextRoomTimelineItem(id: .init(timelineID: ""), + RoomTimelineItemView(viewState: .init(item: TextRoomTimelineItem(id: .init(uniqueID: ""), timestamp: "10:42", isOutgoing: true, isEditable: false, @@ -559,7 +559,7 @@ struct TimelineItemBubbledStylerView_Previews: PreviewProvider, TestablePreview encryptionAuthenticity: .unsignedDevice(color: .red))), groupStyle: .single)) - RoomTimelineItemView(viewState: .init(item: TextRoomTimelineItem(id: .init(timelineID: ""), + RoomTimelineItemView(viewState: .init(item: TextRoomTimelineItem(id: .init(uniqueID: ""), timestamp: "10:42", isOutgoing: false, isEditable: false, @@ -570,7 +570,7 @@ struct TimelineItemBubbledStylerView_Previews: PreviewProvider, TestablePreview properties: RoomTimelineItemProperties(encryptionAuthenticity: .unknownDevice(color: .red))), groupStyle: .first)) - RoomTimelineItemView(viewState: .init(item: TextRoomTimelineItem(id: .init(timelineID: ""), + RoomTimelineItemView(viewState: .init(item: TextRoomTimelineItem(id: .init(uniqueID: ""), timestamp: "10:42", isOutgoing: false, isEditable: false, @@ -592,7 +592,7 @@ struct TimelineItemBubbledStylerView_Previews: PreviewProvider, TestablePreview properties: RoomTimelineItemProperties(encryptionAuthenticity: .notGuaranteed(color: .gray)))) - VoiceMessageRoomTimelineView(timelineItem: .init(id: .init(timelineID: ""), + VoiceMessageRoomTimelineView(timelineItem: .init(id: .init(uniqueID: ""), timestamp: "10:42", isOutgoing: true, isEditable: false, @@ -615,7 +615,7 @@ struct TimelineItemBubbledStylerView_Previews: PreviewProvider, TestablePreview static var pinned: some View { ScrollView { - RoomTimelineItemView(viewState: .init(item: TextRoomTimelineItem(id: .init(timelineID: "", eventID: ""), + RoomTimelineItemView(viewState: .init(item: TextRoomTimelineItem(id: .init(uniqueID: "", eventOrTransactionID: .eventId(eventId: "")), timestamp: "10:42", isOutgoing: true, isEditable: false, @@ -626,7 +626,7 @@ struct TimelineItemBubbledStylerView_Previews: PreviewProvider, TestablePreview replyDetails: nil), groupStyle: .single)) - AudioRoomTimelineView(timelineItem: .init(id: .init(timelineID: "", eventID: ""), + AudioRoomTimelineView(timelineItem: .init(id: .init(uniqueID: "", eventOrTransactionID: .eventId(eventId: "")), timestamp: "10:42", isOutgoing: true, isEditable: false, @@ -640,7 +640,7 @@ struct TimelineItemBubbledStylerView_Previews: PreviewProvider, TestablePreview contentType: nil), replyDetails: nil)) - FileRoomTimelineView(timelineItem: .init(id: .init(timelineID: "", eventID: ""), + FileRoomTimelineView(timelineItem: .init(id: .init(uniqueID: "", eventOrTransactionID: .eventId(eventId: "")), timestamp: "10:42", isOutgoing: false, isEditable: false, @@ -652,7 +652,7 @@ struct TimelineItemBubbledStylerView_Previews: PreviewProvider, TestablePreview thumbnailSource: nil, contentType: nil), replyDetails: nil)) - ImageRoomTimelineView(timelineItem: .init(id: .init(timelineID: "", eventID: ""), + ImageRoomTimelineView(timelineItem: .init(id: .init(uniqueID: "", eventOrTransactionID: .eventId(eventId: "")), timestamp: "10:42", isOutgoing: true, isEditable: true, @@ -661,7 +661,7 @@ struct TimelineItemBubbledStylerView_Previews: PreviewProvider, TestablePreview sender: .init(id: ""), content: .init(body: "Some image", source: MediaSourceProxy(url: .picturesDirectory, mimeType: "image/png"), thumbnailSource: nil), replyDetails: nil)) - LocationRoomTimelineView(timelineItem: .init(id: .init(timelineID: "", eventID: ""), + LocationRoomTimelineView(timelineItem: .init(id: .init(uniqueID: "", eventOrTransactionID: .eventId(eventId: "")), timestamp: "Now", isOutgoing: false, isEditable: false, @@ -673,7 +673,7 @@ struct TimelineItemBubbledStylerView_Previews: PreviewProvider, TestablePreview longitude: 12.496366), description: "Location description description description description description description description description"), replyDetails: nil)) - LocationRoomTimelineView(timelineItem: .init(id: .init(timelineID: "", eventID: ""), + LocationRoomTimelineView(timelineItem: .init(id: .init(uniqueID: "", eventOrTransactionID: .eventId(eventId: "")), timestamp: "Now", isOutgoing: false, isEditable: false, @@ -684,7 +684,7 @@ struct TimelineItemBubbledStylerView_Previews: PreviewProvider, TestablePreview geoURI: .init(latitude: 41.902782, longitude: 12.496366), description: nil), replyDetails: nil)) - VoiceMessageRoomTimelineView(timelineItem: .init(id: .init(timelineID: "", eventID: ""), + VoiceMessageRoomTimelineView(timelineItem: .init(id: .init(uniqueID: "", eventOrTransactionID: .eventId(eventId: "")), timestamp: "10:42", isOutgoing: true, isEditable: false, diff --git a/ElementX/Sources/Screens/Timeline/View/Style/TimelineStyler.swift b/ElementX/Sources/Screens/Timeline/View/Style/TimelineStyler.swift index 4d09e9216..ac7dc5d59 100644 --- a/ElementX/Sources/Screens/Timeline/View/Style/TimelineStyler.swift +++ b/ElementX/Sources/Screens/Timeline/View/Style/TimelineStyler.swift @@ -79,8 +79,8 @@ 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), + let id = viewModel.state.timelineViewState.uniqueIDs.last ?? UUID().uuidString + var result = TextRoomTimelineItem(id: .init(uniqueID: id), timestamp: "Now", isOutgoing: true, isEditable: false, @@ -99,8 +99,8 @@ 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), + let id = viewModel.state.timelineViewState.uniqueIDs.last ?? UUID().uuidString + let result = TextRoomTimelineItem(id: .init(uniqueID: id), timestamp: "Now", isOutgoing: true, isEditable: false, diff --git a/ElementX/Sources/Screens/Timeline/View/Supplementary/TimelineItemStatusView.swift b/ElementX/Sources/Screens/Timeline/View/Supplementary/TimelineItemStatusView.swift index 071351cc5..1729d149d 100644 --- a/ElementX/Sources/Screens/Timeline/View/Supplementary/TimelineItemStatusView.swift +++ b/ElementX/Sources/Screens/Timeline/View/Supplementary/TimelineItemStatusView.swift @@ -14,7 +14,7 @@ struct TimelineItemStatusView: View { @EnvironmentObject private var context: TimelineViewModel.Context private var isLastOutgoingMessage: Bool { - timelineItem.isOutgoing && context.viewState.timelineViewState.timelineIDs.last == timelineItem.id.timelineID + timelineItem.isOutgoing && context.viewState.timelineViewState.uniqueIDs.last == timelineItem.id.uniqueID } var body: some View { diff --git a/ElementX/Sources/Screens/Timeline/View/Supplementary/TimelineReactionsView.swift b/ElementX/Sources/Screens/Timeline/View/Supplementary/TimelineReactionsView.swift index 50b2459e1..f8656fdf2 100644 --- a/ElementX/Sources/Screens/Timeline/View/Supplementary/TimelineReactionsView.swift +++ b/ElementX/Sources/Screens/Timeline/View/Supplementary/TimelineReactionsView.swift @@ -196,20 +196,20 @@ struct TimelineReactionViewPreviewsContainer: View { var body: some View { VStack(spacing: 8) { TimelineReactionsView(context: TimelineViewModel.mock.context, - itemID: .init(timelineID: "1"), + itemID: .init(uniqueID: "1"), reactions: [AggregatedReaction.mockReactionWithLongText, AggregatedReaction.mockReactionWithLongTextRTL]) Divider() TimelineReactionsView(context: TimelineViewModel.mock.context, - itemID: .init(timelineID: "2"), + itemID: .init(uniqueID: "2"), reactions: Array(AggregatedReaction.mockReactions.prefix(3))) Divider() TimelineReactionsView(context: TimelineViewModel.mock.context, - itemID: .init(timelineID: "3"), + itemID: .init(uniqueID: "3"), reactions: AggregatedReaction.mockReactions) Divider() TimelineReactionsView(context: TimelineViewModel.mock.context, - itemID: .init(timelineID: "4"), + itemID: .init(uniqueID: "4"), reactions: AggregatedReaction.mockReactions, isLayoutRTL: true) } diff --git a/ElementX/Sources/Screens/Timeline/View/TimelineItemViews/CollapsibleRoomTimelineView.swift b/ElementX/Sources/Screens/Timeline/View/TimelineItemViews/CollapsibleRoomTimelineView.swift index 9e03a8179..fd50654fe 100644 --- a/ElementX/Sources/Screens/Timeline/View/TimelineItemViews/CollapsibleRoomTimelineView.swift +++ b/ElementX/Sources/Screens/Timeline/View/TimelineItemViews/CollapsibleRoomTimelineView.swift @@ -52,8 +52,8 @@ struct CollapsibleRoomTimelineView: View { struct CollapsibleRoomTimelineView_Previews: PreviewProvider, TestablePreview { static let item = CollapsibleTimelineItem(items: [ - SeparatorRoomTimelineItem(id: .init(timelineID: "First separator"), text: "This is a separator"), - SeparatorRoomTimelineItem(id: .init(timelineID: "Second separator"), text: "This is another separator") + SeparatorRoomTimelineItem(id: .init(uniqueID: "First separator"), text: "This is a separator"), + SeparatorRoomTimelineItem(id: .init(uniqueID: "Second separator"), text: "This is another separator") ]) static var previews: some View { diff --git a/ElementX/Sources/Screens/Timeline/View/TimelineItemViews/ReadMarkerRoomTimelineView.swift b/ElementX/Sources/Screens/Timeline/View/TimelineItemViews/ReadMarkerRoomTimelineView.swift index 5c6f5c58b..71a3b1a0f 100644 --- a/ElementX/Sources/Screens/Timeline/View/TimelineItemViews/ReadMarkerRoomTimelineView.swift +++ b/ElementX/Sources/Screens/Timeline/View/TimelineItemViews/ReadMarkerRoomTimelineView.swift @@ -29,12 +29,12 @@ struct ReadMarkerRoomTimelineView: View { struct ReadMarkerRoomTimelineView_Previews: PreviewProvider, TestablePreview { static let viewModel = TimelineViewModel.mock - static let item = ReadMarkerRoomTimelineItem(id: .init(timelineID: .init(UUID().uuidString))) + static let item = ReadMarkerRoomTimelineItem(id: .init(uniqueID: .init(UUID().uuidString))) static var previews: some View { VStack(alignment: .leading, spacing: 0) { - RoomTimelineItemView(viewState: .init(type: .separator(.init(id: .init(timelineID: "Separator"), text: "Today")), groupStyle: .single)) - RoomTimelineItemView(viewState: .init(type: .text(.init(id: .init(timelineID: ""), + RoomTimelineItemView(viewState: .init(type: .separator(.init(id: .init(uniqueID: "Separator"), text: "Today")), groupStyle: .single)) + RoomTimelineItemView(viewState: .init(type: .text(.init(id: .random, timestamp: "", isOutgoing: true, isEditable: false, @@ -45,8 +45,8 @@ struct ReadMarkerRoomTimelineView_Previews: PreviewProvider, TestablePreview { ReadMarkerRoomTimelineView(timelineItem: item) - RoomTimelineItemView(viewState: .init(type: .separator(.init(id: .init(timelineID: "Separator"), text: "Today")), groupStyle: .single)) - RoomTimelineItemView(viewState: .init(type: .text(.init(id: .init(timelineID: ""), + RoomTimelineItemView(viewState: .init(type: .separator(.init(id: .init(uniqueID: "Separator"), text: "Today")), groupStyle: .single)) + RoomTimelineItemView(viewState: .init(type: .text(.init(id: .random, timestamp: "", isOutgoing: false, isEditable: false, diff --git a/ElementX/Sources/Screens/Timeline/View/TimelineItemViews/SeparatorRoomTimelineView.swift b/ElementX/Sources/Screens/Timeline/View/TimelineItemViews/SeparatorRoomTimelineView.swift index 0f7407907..13c506814 100644 --- a/ElementX/Sources/Screens/Timeline/View/TimelineItemViews/SeparatorRoomTimelineView.swift +++ b/ElementX/Sources/Screens/Timeline/View/TimelineItemViews/SeparatorRoomTimelineView.swift @@ -23,7 +23,7 @@ struct SeparatorRoomTimelineView: View { struct SeparatorRoomTimelineView_Previews: PreviewProvider, TestablePreview { static var previews: some View { - let item = SeparatorRoomTimelineItem(id: .init(timelineID: "Separator"), text: "This is a separator") + let item = SeparatorRoomTimelineItem(id: .init(uniqueID: "Separator"), text: "This is a separator") SeparatorRoomTimelineView(timelineItem: item) } } diff --git a/ElementX/Sources/Services/Authentication/AuthenticationServiceProtocol.swift b/ElementX/Sources/Services/Authentication/AuthenticationServiceProtocol.swift index e762e27cb..0159b7502 100644 --- a/ElementX/Sources/Services/Authentication/AuthenticationServiceProtocol.swift +++ b/ElementX/Sources/Services/Authentication/AuthenticationServiceProtocol.swift @@ -79,7 +79,7 @@ struct OIDCAuthorizationDataProxy: Equatable { } } -extension OidcAuthorizationData: Equatable { +extension OidcAuthorizationData: @retroactive Equatable { public static func == (lhs: MatrixRustSDK.OidcAuthorizationData, rhs: MatrixRustSDK.OidcAuthorizationData) -> Bool { lhs.loginUrl() == rhs.loginUrl() } diff --git a/ElementX/Sources/Services/Room/RoomSummary/RoomEventStringBuilder.swift b/ElementX/Sources/Services/Room/RoomSummary/RoomEventStringBuilder.swift index beed3f206..55a05efd2 100644 --- a/ElementX/Sources/Services/Room/RoomSummary/RoomEventStringBuilder.swift +++ b/ElementX/Sources/Services/Room/RoomSummary/RoomEventStringBuilder.swift @@ -23,7 +23,7 @@ struct RoomEventStringBuilder { sender.displayName ?? sender.id } - switch eventItemProxy.content.kind() { + switch eventItemProxy.content { case .unableToDecrypt(let encryptedMessage): let errorMessage = switch encryptedMessage { case .megolmV1AesSha2(_, .membership): L10n.commonUnableToDecryptNoAccess @@ -41,13 +41,8 @@ struct RoomEventStringBuilder { return prefix(L10n.commonSticker, with: displayName) case .failedToParseMessageLike, .failedToParseState: return prefix(L10n.commonUnsupportedEvent, with: displayName) - case .message: - guard let messageContent = eventItemProxy.content.asMessage() else { - fatalError("Invalid message timeline item: \(eventItemProxy)") - } - - let messageType = messageContent.msgtype() - return messageEventStringBuilder.buildAttributedString(for: messageType, senderDisplayName: displayName) + case .message(let messageContent): + return messageEventStringBuilder.buildAttributedString(for: messageContent.msgType, senderDisplayName: displayName) case .state(_, let state): return stateEventStringBuilder .buildString(for: state, sender: sender, isOutgoing: isOutgoing) diff --git a/ElementX/Sources/Services/Room/RoomSummary/RoomSummaryProvider.swift b/ElementX/Sources/Services/Room/RoomSummary/RoomSummaryProvider.swift index 0d9921a70..7c66bbc28 100644 --- a/ElementX/Sources/Services/Room/RoomSummary/RoomSummaryProvider.swift +++ b/ElementX/Sources/Services/Room/RoomSummary/RoomSummaryProvider.swift @@ -246,7 +246,7 @@ class RoomSummaryProvider: RoomSummaryProviderProtocol { var lastMessageFormattedTimestamp: String? if let latestRoomMessage = roomDetails.latestEvent { - let lastMessage = EventTimelineItemProxy(item: latestRoomMessage, id: "0") + let lastMessage = EventTimelineItemProxy(item: latestRoomMessage, uniqueID: "0") lastMessageFormattedTimestamp = lastMessage.timestamp.formattedMinimal() attributedLastMessage = eventStringBuilder.buildAttributedString(for: lastMessage) } diff --git a/ElementX/Sources/Services/SecureBackup/SecureBackupController.swift b/ElementX/Sources/Services/SecureBackup/SecureBackupController.swift index fc6c81256..ab514800d 100644 --- a/ElementX/Sources/Services/SecureBackup/SecureBackupController.swift +++ b/ElementX/Sources/Services/SecureBackup/SecureBackupController.swift @@ -121,7 +121,7 @@ class SecureBackupController: SecureBackupControllerProtocol { MXLog.info("Enabling recovery") var keyUploadErrored = false - let recoveryKey = try await encryption.enableRecovery(waitForBackupsToUpload: false, progressListener: SecureBackupEnableRecoveryProgressListener { [weak self] state in + let recoveryKey = try await encryption.enableRecovery(waitForBackupsToUpload: false, passphrase: nil, progressListener: SecureBackupEnableRecoveryProgressListener { [weak self] state in guard let self else { return } switch state { diff --git a/ElementX/Sources/Services/Timeline/Fixtures/RoomTimelineItemFixtures.swift b/ElementX/Sources/Services/Timeline/Fixtures/RoomTimelineItemFixtures.swift index c994d8a82..62cad3cd3 100644 --- a/ElementX/Sources/Services/Timeline/Fixtures/RoomTimelineItemFixtures.swift +++ b/ElementX/Sources/Services/Timeline/Fixtures/RoomTimelineItemFixtures.swift @@ -10,9 +10,9 @@ import Foundation enum RoomTimelineItemFixtures { /// The default timeline items used in Xcode previews etc. static var `default`: [RoomTimelineItemProtocol] = [ - SeparatorRoomTimelineItem(id: .init(timelineID: "Yesterday"), text: "Yesterday"), - TextRoomTimelineItem(id: .init(timelineID: ".RoomTimelineItemFixtures.default.0", - eventID: "RoomTimelineItemFixtures.default.0"), + SeparatorRoomTimelineItem(id: .init(uniqueID: "Yesterday"), text: "Yesterday"), + TextRoomTimelineItem(id: .init(uniqueID: ".RoomTimelineItemFixtures.default.0", + eventOrTransactionID: .eventId(eventId: "RoomTimelineItemFixtures.default.0")), timestamp: "10:10 AM", isOutgoing: false, isEditable: false, @@ -21,8 +21,8 @@ enum RoomTimelineItemFixtures { sender: .init(id: "", displayName: "Jacob"), content: .init(body: "That looks so good!"), properties: RoomTimelineItemProperties(isEdited: true)), - TextRoomTimelineItem(id: .init(timelineID: "RoomTimelineItemFixtures.default.1", - eventID: "RoomTimelineItemFixtures.default.1"), + TextRoomTimelineItem(id: .init(uniqueID: "RoomTimelineItemFixtures.default.1", + eventOrTransactionID: .eventId(eventId: "RoomTimelineItemFixtures.default.1")), timestamp: "10:11 AM", isOutgoing: false, isEditable: false, @@ -33,8 +33,8 @@ enum RoomTimelineItemFixtures { properties: RoomTimelineItemProperties(reactions: [ AggregatedReaction(accountOwnerID: "me", key: "🙌", senders: [ReactionSender(id: "me", timestamp: Date())]) ])), - TextRoomTimelineItem(id: .init(timelineID: "RoomTimelineItemFixtures.default.2", - eventID: "RoomTimelineItemFixtures.default.2"), + TextRoomTimelineItem(id: .init(uniqueID: "RoomTimelineItemFixtures.default.2", + eventOrTransactionID: .eventId(eventId: "RoomTimelineItemFixtures.default.2")), timestamp: "10:11 AM", isOutgoing: false, isEditable: false, @@ -52,9 +52,9 @@ enum RoomTimelineItemFixtures { ReactionSender(id: "jacob", timestamp: Date()) ]) ])), - SeparatorRoomTimelineItem(id: .init(timelineID: "Today"), text: "Today"), - TextRoomTimelineItem(id: .init(timelineID: "RoomTimelineItemFixtures.default.3", - eventID: "RoomTimelineItemFixtures.default.3"), + SeparatorRoomTimelineItem(id: .init(uniqueID: "Today"), text: "Today"), + TextRoomTimelineItem(id: .init(uniqueID: "RoomTimelineItemFixtures.default.3", + eventOrTransactionID: .eventId(eventId: "RoomTimelineItemFixtures.default.3")), timestamp: "5 PM", isOutgoing: false, isEditable: false, @@ -63,8 +63,8 @@ enum RoomTimelineItemFixtures { 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!"), properties: RoomTimelineItemProperties(orderedReadReceipts: [ReadReceipt(userID: "alice", formattedTimestamp: nil)])), - TextRoomTimelineItem(id: .init(timelineID: "RoomTimelineItemFixtures.default.4", - eventID: "RoomTimelineItemFixtures.default.4"), + TextRoomTimelineItem(id: .init(uniqueID: "RoomTimelineItemFixtures.default.4", + eventOrTransactionID: .eventId(eventId: "RoomTimelineItemFixtures.default.4")), timestamp: "5 PM", isOutgoing: true, isEditable: true, @@ -72,8 +72,8 @@ enum RoomTimelineItemFixtures { isThreaded: false, sender: .init(id: "", displayName: "Bob"), content: .init(body: "And John's speech was amazing!")), - TextRoomTimelineItem(id: .init(timelineID: "RoomTimelineItemFixtures.default.5", - eventID: "RoomTimelineItemFixtures.default.5"), + TextRoomTimelineItem(id: .init(uniqueID: "RoomTimelineItemFixtures.default.5", + eventOrTransactionID: .eventId(eventId: "RoomTimelineItemFixtures.default.5")), timestamp: "5 PM", isOutgoing: true, isEditable: true, @@ -86,8 +86,8 @@ enum RoomTimelineItemFixtures { ReadReceipt(userID: "bob", formattedTimestamp: nil), ReadReceipt(userID: "charlie", formattedTimestamp: nil), ReadReceipt(userID: "dan", formattedTimestamp: nil)])), - TextRoomTimelineItem(id: .init(timelineID: "RoomTimelineItemFixtures.default.6", - eventID: "RoomTimelineItemFixtures.default.6"), + TextRoomTimelineItem(id: .init(uniqueID: "RoomTimelineItemFixtures.default.6", + eventOrTransactionID: .eventId(eventId: "RoomTimelineItemFixtures.default.6")), timestamp: "5 PM", isOutgoing: false, isEditable: false, @@ -242,7 +242,7 @@ enum RoomTimelineItemFixtures { static var permalinkChunk: [RoomTimelineItemProtocol] { (1...20).map { index in - TextRoomTimelineItem(id: .init(timelineID: "\(index)", eventID: "$\(index)"), + TextRoomTimelineItem(id: .init(uniqueID: "\(index)", eventOrTransactionID: .eventId(eventId: "$\(index)")), text: "Message ID \(index)", senderDisplayName: index > 10 ? "Alice" : "Bob") } diff --git a/ElementX/Sources/Services/Timeline/RoomTimelineProvider.swift b/ElementX/Sources/Services/Timeline/RoomTimelineProvider.swift index ce7c96fa3..e446a40ee 100644 --- a/ElementX/Sources/Services/Timeline/RoomTimelineProvider.swift +++ b/ElementX/Sources/Services/Timeline/RoomTimelineProvider.swift @@ -184,38 +184,11 @@ class RoomTimelineProvider: RoomTimelineProviderProtocol { } } -private extension TimelineItem { - var debugIdentifier: DebugIdentifier { - if let virtualTimelineItem = asVirtual() { - return .virtual(timelineID: String(uniqueId()), dscription: virtualTimelineItem.description) - } else if let eventTimelineItem = asEvent() { - return .event(timelineID: String(uniqueId()), - eventID: eventTimelineItem.eventId(), - transactionID: eventTimelineItem.transactionId()) - } - - return .unknown(timelineID: String(uniqueId())) - } -} - private extension TimelineItemProxy { - var debugIdentifier: DebugIdentifier { - switch self { - case .event(let eventTimelineItem): - return .event(timelineID: eventTimelineItem.id.timelineID, - eventID: eventTimelineItem.id.eventID, - transactionID: eventTimelineItem.id.transactionID) - case .virtual(let virtualTimelineItem, let timelineID): - return .virtual(timelineID: timelineID, dscription: virtualTimelineItem.description) - case .unknown(let item): - return .unknown(timelineID: String(item.uniqueId())) - } - } - var isMembershipChange: Bool { switch self { case .event(let eventTimelineItemProxy): - switch eventTimelineItemProxy.content.kind() { + switch eventTimelineItemProxy.content { case .roomMembership: true default: @@ -238,12 +211,6 @@ private extension VirtualTimelineItem { } } -enum DebugIdentifier { - case event(timelineID: String, eventID: String?, transactionID: String?) - case virtual(timelineID: String, dscription: String) - case unknown(timelineID: String) -} - private final class RoomTimelineListener: TimelineListener { private let onUpdateClosure: ([TimelineDiff]) -> Void diff --git a/ElementX/Sources/Services/Timeline/TimelineController/RoomTimelineController.swift b/ElementX/Sources/Services/Timeline/TimelineController/RoomTimelineController.swift index 457020d50..cf0381f3a 100644 --- a/ElementX/Sources/Services/Timeline/TimelineController/RoomTimelineController.swift +++ b/ElementX/Sources/Services/Timeline/TimelineController/RoomTimelineController.swift @@ -186,7 +186,7 @@ class RoomTimelineController: RoomTimelineControllerProtocol { MXLog.info("Editing timeline item: \(timelineItemID)") let editMode: EditMode - if !timelineItemID.timelineID.isEmpty, + if !timelineItemID.uniqueID.isEmpty, let timelineItem = liveTimelineProvider.itemProxies.firstEventTimelineItemUsingStableID(timelineItemID) { editMode = .byEvent(timelineItem) } else if let eventID = timelineItemID.eventID { @@ -392,15 +392,15 @@ class RoomTimelineController: RoomTimelineControllerProtocol { } return timelineItem - case .virtual(let virtualItem, let timelineID): + case .virtual(let virtualItem, let uniqueID): switch virtualItem { case .dayDivider(let timestamp): let date = Date(timeIntervalSince1970: TimeInterval(timestamp / 1000)) let dateString = date.formatted(date: .complete, time: .omitted) - return SeparatorRoomTimelineItem(id: .init(timelineID: dateString), text: dateString) + return SeparatorRoomTimelineItem(id: .init(uniqueID: dateString), text: dateString) case .readMarker: - return ReadMarkerRoomTimelineItem(id: .init(timelineID: timelineID)) + return ReadMarkerRoomTimelineItem(id: .init(uniqueID: uniqueID)) } case .unknown: return nil @@ -409,7 +409,7 @@ class RoomTimelineController: RoomTimelineControllerProtocol { private func isItemCollapsible(_ item: TimelineItemProxy) -> Bool { if case let .event(eventItem) = item { - switch eventItem.content.kind() { + switch eventItem.content { case .profileChange, .roomMembership, .state: return true default: diff --git a/ElementX/Sources/Services/Timeline/TimelineItemContent/CustomStringConvertible.swift b/ElementX/Sources/Services/Timeline/TimelineItemContent/CustomStringConvertible.swift index 5017baaa5..bb4799a11 100644 --- a/ElementX/Sources/Services/Timeline/TimelineItemContent/CustomStringConvertible.swift +++ b/ElementX/Sources/Services/Timeline/TimelineItemContent/CustomStringConvertible.swift @@ -9,43 +9,43 @@ import MatrixRustSDK // MARK: Redact message content from logs -extension EmoteMessageContent: CustomStringConvertible { +extension EmoteMessageContent: @retroactive CustomStringConvertible { public var description: String { String(describing: Self.self) } } -extension FileMessageContent: CustomStringConvertible { +extension FileMessageContent: @retroactive CustomStringConvertible { public var description: String { String(describing: Self.self) } } -extension ImageMessageContent: CustomStringConvertible { +extension ImageMessageContent: @retroactive CustomStringConvertible { public var description: String { String(describing: Self.self) } } -extension NoticeMessageContent: CustomStringConvertible { +extension NoticeMessageContent: @retroactive CustomStringConvertible { public var description: String { String(describing: Self.self) } } -extension TextMessageContent: CustomStringConvertible { +extension TextMessageContent: @retroactive CustomStringConvertible { public var description: String { String(describing: Self.self) } } -extension VideoMessageContent: CustomStringConvertible { +extension VideoMessageContent: @retroactive CustomStringConvertible { public var description: String { String(describing: Self.self) } } -extension AudioMessageContent: CustomStringConvertible { +extension AudioMessageContent: @retroactive CustomStringConvertible { public var description: String { String(describing: Self.self) } diff --git a/ElementX/Sources/Services/Timeline/TimelineItemProxy.swift b/ElementX/Sources/Services/Timeline/TimelineItemProxy.swift index 6a94a3614..b775a8865 100644 --- a/ElementX/Sources/Services/Timeline/TimelineItemProxy.swift +++ b/ElementX/Sources/Services/Timeline/TimelineItemProxy.swift @@ -11,35 +11,48 @@ import MatrixRustSDK struct TimelineItemIdentifier: Hashable { /// Stable id across state changes of the timeline item, it uniquely identifies an item in a timeline. /// It's value is consistent only per timeline instance, it should **not** be used to identify an item across timeline instances. - let timelineID: String - - /// Uniquely identifies the timeline item from the server side. - /// Only available for EventTimelineItem and only when the item is returned by the server. - var eventID: String? - - /// Uniquely identifies the local echo of the timeline item. - /// Only available for sent EventTimelineItem that have not been returned by the server yet. - var transactionID: String? + let uniqueID: String + + /// Contains the 2 possible identifiers of an event, either it has a remote event id or a local transaction id, never both or none. + var eventOrTransactionID: EventOrTransactionId? + + var eventID: String? { + switch eventOrTransactionID { + case .eventId(let eventId): + return eventId + default: + return nil + } + } + + var transactionID: String? { + switch eventOrTransactionID { + case .transactionId(let transactionId): + return transactionId + default: + return nil + } + } } extension TimelineItemIdentifier { /// Use only for mocks/tests static var random: Self { - .init(timelineID: UUID().uuidString, eventID: UUID().uuidString) + .init(uniqueID: UUID().uuidString, eventOrTransactionID: .eventId(eventId: UUID().uuidString)) } } /// A light wrapper around timeline items returned from Rust. enum TimelineItemProxy { case event(EventTimelineItemProxy) - case virtual(MatrixRustSDK.VirtualTimelineItem, timelineID: String) + case virtual(MatrixRustSDK.VirtualTimelineItem, uniqueID: String) case unknown(MatrixRustSDK.TimelineItem) init(item: MatrixRustSDK.TimelineItem) { if let eventItem = item.asEvent() { - self = .event(EventTimelineItemProxy(item: eventItem, id: String(item.uniqueId()))) + self = .event(EventTimelineItemProxy(item: eventItem, uniqueID: String(item.uniqueId()))) } else if let virtualItem = item.asVirtual() { - self = .virtual(virtualItem, timelineID: String(item.uniqueId())) + self = .virtual(virtualItem, uniqueID: String(item.uniqueId())) } else { self = .unknown(item) } @@ -92,13 +105,14 @@ class EventTimelineItemProxy { let item: MatrixRustSDK.EventTimelineItem let id: TimelineItemIdentifier - init(item: MatrixRustSDK.EventTimelineItem, id: String) { + init(item: MatrixRustSDK.EventTimelineItem, uniqueID: String) { self.item = item - self.id = TimelineItemIdentifier(timelineID: id, eventID: item.eventId(), transactionID: item.transactionId()) + + id = TimelineItemIdentifier(uniqueID: uniqueID, eventOrTransactionID: item.eventOrTransactionId) } lazy var deliveryStatus: TimelineItemDeliveryStatus? = { - guard let localSendState = item.localSendState() else { + guard let localSendState = item.localSendState else { return nil } @@ -118,43 +132,43 @@ class EventTimelineItemProxy { } }() - lazy var canBeRepliedTo = item.canBeRepliedTo() + lazy var canBeRepliedTo = item.canBeRepliedTo - lazy var content = item.content() + lazy var content = item.content - lazy var isOwn = item.isOwn() + lazy var isOwn = item.isOwn - lazy var isEditable = item.isEditable() + lazy var isEditable = item.isEditable lazy var sender: TimelineItemSender = { - let profile = item.senderProfile() + let profile = item.senderProfile switch profile { case let .ready(displayName, isDisplayNameAmbiguous, avatarUrl): - return .init(id: item.sender(), + return .init(id: item.sender, displayName: displayName, isDisplayNameAmbiguous: isDisplayNameAmbiguous, avatarURL: avatarUrl.flatMap(URL.init(string:))) default: - return .init(id: item.sender(), + return .init(id: item.sender, displayName: nil, isDisplayNameAmbiguous: false, avatarURL: nil) } }() - lazy var reactions = item.reactions() + lazy var reactions = item.reactions - lazy var timestamp = Date(timeIntervalSince1970: TimeInterval(item.timestamp() / 1000)) + lazy var timestamp = Date(timeIntervalSince1970: TimeInterval(item.timestamp / 1000)) lazy var debugInfo: TimelineItemDebugInfo = { - let debugInfo = item.debugInfo() + let debugInfo = item.debugInfoProvider.get() return TimelineItemDebugInfo(model: debugInfo.model, originalJSON: debugInfo.originalJson, latestEditJSON: debugInfo.latestEditJson) }() - lazy var shieldState = item.getShield(strict: false) + lazy var shieldState = item.shieldsProvider.getShields(strict: false) - lazy var readReceipts = item.readReceipts() + lazy var readReceipts = item.readReceipts } struct TimelineItemDebugInfo: Identifiable, CustomStringConvertible { diff --git a/ElementX/Sources/Services/Timeline/TimelineItems/Items/Virtual/PaginationIndicatorRoomTimelineItem.swift b/ElementX/Sources/Services/Timeline/TimelineItems/Items/Virtual/PaginationIndicatorRoomTimelineItem.swift index af817de16..837798cb4 100644 --- a/ElementX/Sources/Services/Timeline/TimelineItems/Items/Virtual/PaginationIndicatorRoomTimelineItem.swift +++ b/ElementX/Sources/Services/Timeline/TimelineItems/Items/Virtual/PaginationIndicatorRoomTimelineItem.swift @@ -22,6 +22,6 @@ struct PaginationIndicatorRoomTimelineItem: DecorationTimelineItemProtocol, Equa } init(position: Position) { - id = TimelineItemIdentifier(timelineID: position.id) + id = TimelineItemIdentifier(uniqueID: position.id) } } diff --git a/ElementX/Sources/Services/Timeline/TimelineItems/Items/Virtual/TimelineStartRoomTimelineItem.swift b/ElementX/Sources/Services/Timeline/TimelineItems/Items/Virtual/TimelineStartRoomTimelineItem.swift index 3aab2b6ba..17435d9cc 100644 --- a/ElementX/Sources/Services/Timeline/TimelineItems/Items/Virtual/TimelineStartRoomTimelineItem.swift +++ b/ElementX/Sources/Services/Timeline/TimelineItems/Items/Virtual/TimelineStartRoomTimelineItem.swift @@ -8,6 +8,6 @@ import Foundation struct TimelineStartRoomTimelineItem: DecorationTimelineItemProtocol, Equatable { - let id = TimelineItemIdentifier(timelineID: UUID().uuidString) + let id = TimelineItemIdentifier(uniqueID: UUID().uuidString) let name: String? } diff --git a/ElementX/Sources/Services/Timeline/TimelineItems/RoomTimelineItemFactory.swift b/ElementX/Sources/Services/Timeline/TimelineItems/RoomTimelineItemFactory.swift index 018f47b83..75c1cfdd3 100644 --- a/ElementX/Sources/Services/Timeline/TimelineItems/RoomTimelineItemFactory.swift +++ b/ElementX/Sources/Services/Timeline/TimelineItems/RoomTimelineItemFactory.swift @@ -27,7 +27,7 @@ struct RoomTimelineItemFactory: RoomTimelineItemFactoryProtocol { func buildTimelineItem(for eventItemProxy: EventTimelineItemProxy, isDM: Bool) -> RoomTimelineItemProtocol? { let isOutgoing = eventItemProxy.isOwn - switch eventItemProxy.content.kind() { + switch eventItemProxy.content { case .unableToDecrypt(let encryptedMessage): return buildEncryptedTimelineItem(eventItemProxy, encryptedMessage, isOutgoing) case .redactedMessage: @@ -43,8 +43,8 @@ struct RoomTimelineItemFactory: RoomTimelineItemFactoryProtocol { return buildUnsupportedTimelineItem(eventItemProxy, eventType, error, isOutgoing) case .failedToParseState(let eventType, _, let error): return buildUnsupportedTimelineItem(eventItemProxy, eventType, error, isOutgoing) - case .message: - return buildMessageTimelineItem(eventItemProxy, isOutgoing) + case .message(let messageContent): + return buildMessageTimelineItem(eventItemProxy, messageContent, isOutgoing) case .state(_, let content): if isDM, content == .roomCreate { return nil @@ -72,34 +72,29 @@ struct RoomTimelineItemFactory: RoomTimelineItemFactoryProtocol { } // MARK: - Message Events - - private func buildMessageTimelineItem(_ eventItemProxy: EventTimelineItemProxy, _ isOutgoing: Bool) -> RoomTimelineItemProtocol? { - guard let messageTimelineItem = eventItemProxy.content.asMessage() else { - fatalError("Invalid message timeline item: \(eventItemProxy)") - } - - let isThreaded = messageTimelineItem.isThreaded() - switch messageTimelineItem.msgtype() { - case .text(content: let content): - return buildTextTimelineItem(for: eventItemProxy, messageTimelineItem, content, isOutgoing, isThreaded) - case .image(content: let content): - return buildImageTimelineItem(for: eventItemProxy, messageTimelineItem, content, isOutgoing, isThreaded) - case .video(let content): - return buildVideoTimelineItem(for: eventItemProxy, messageTimelineItem, content, isOutgoing, isThreaded) - case .file(let content): - return buildFileTimelineItem(for: eventItemProxy, messageTimelineItem, content, isOutgoing, isThreaded) - case .notice(content: let content): - return buildNoticeTimelineItem(for: eventItemProxy, messageTimelineItem, content, isOutgoing, isThreaded) - case .emote(content: let content): - return buildEmoteTimelineItem(for: eventItemProxy, messageTimelineItem, content, isOutgoing, isThreaded) - case .audio(let content): - if content.voice != nil { - return buildVoiceTimelineItem(for: eventItemProxy, messageTimelineItem, content, isOutgoing, isThreaded) + + private func buildMessageTimelineItem(_ eventItemProxy: EventTimelineItemProxy, _ messageContent: MessageContent, _ isOutgoing: Bool) -> RoomTimelineItemProtocol? { + switch messageContent.msgType { + case .text(content: let textMessageContent): + return buildTextTimelineItem(for: eventItemProxy, messageContent, textMessageContent, isOutgoing) + case .image(content: let imageMessageContent): + return buildImageTimelineItem(for: eventItemProxy, messageContent, imageMessageContent, isOutgoing) + case .video(let videoMessageContent): + return buildVideoTimelineItem(for: eventItemProxy, messageContent, videoMessageContent, isOutgoing) + case .file(let fileMessageContent): + return buildFileTimelineItem(for: eventItemProxy, messageContent, fileMessageContent, isOutgoing) + case .notice(content: let noticeMessageContent): + return buildNoticeTimelineItem(for: eventItemProxy, messageContent, noticeMessageContent, isOutgoing) + case .emote(content: let emoteMessageContent): + return buildEmoteTimelineItem(for: eventItemProxy, messageContent, emoteMessageContent, isOutgoing) + case .audio(let audioMessageContent): + if audioMessageContent.voice != nil { + return buildVoiceTimelineItem(for: eventItemProxy, messageContent, audioMessageContent, isOutgoing) } else { - return buildAudioTimelineItem(for: eventItemProxy, messageTimelineItem, content, isOutgoing, isThreaded) + return buildAudioTimelineItem(for: eventItemProxy, messageContent, audioMessageContent, isOutgoing) } - case .location(let content): - return buildLocationTimelineItem(for: eventItemProxy, messageTimelineItem, content, isOutgoing, isThreaded) + case .location(let locationMessageContent): + return buildLocationTimelineItem(for: eventItemProxy, messageContent, locationMessageContent, isOutgoing) case .other: return nil } @@ -196,20 +191,19 @@ struct RoomTimelineItemFactory: RoomTimelineItemFactoryProtocol { } private func buildTextTimelineItem(for eventItemProxy: EventTimelineItemProxy, - _ messageTimelineItem: Message, - _ messageContent: TextMessageContent, - _ isOutgoing: Bool, - _ isThreaded: Bool) -> RoomTimelineItemProtocol { + _ messageContent: MessageContent, + _ textMessageContent: TextMessageContent, + _ isOutgoing: Bool) -> RoomTimelineItemProtocol { TextRoomTimelineItem(id: eventItemProxy.id, timestamp: eventItemProxy.timestamp.formatted(date: .omitted, time: .shortened), isOutgoing: isOutgoing, isEditable: eventItemProxy.isEditable, canBeRepliedTo: eventItemProxy.canBeRepliedTo, - isThreaded: isThreaded, + isThreaded: messageContent.threadRoot != nil, sender: eventItemProxy.sender, - content: buildTextTimelineItemContent(messageContent), - replyDetails: buildReplyToDetailsFromDetailsIfAvailable(details: messageTimelineItem.inReplyTo()), - properties: RoomTimelineItemProperties(isEdited: messageTimelineItem.isEdited(), + content: buildTextTimelineItemContent(textMessageContent), + replyDetails: buildReplyToDetailsFromDetailsIfAvailable(details: messageContent.inReplyTo), + properties: RoomTimelineItemProperties(isEdited: messageContent.isEdited, reactions: aggregateReactions(eventItemProxy.reactions), deliveryStatus: eventItemProxy.deliveryStatus, orderedReadReceipts: orderReadReceipts(eventItemProxy.readReceipts), @@ -217,20 +211,19 @@ struct RoomTimelineItemFactory: RoomTimelineItemFactoryProtocol { } private func buildImageTimelineItem(for eventItemProxy: EventTimelineItemProxy, - _ messageTimelineItem: Message, - _ messageContent: ImageMessageContent, - _ isOutgoing: Bool, - _ isThreaded: Bool) -> RoomTimelineItemProtocol { + _ messageContent: MessageContent, + _ imageMessageContent: ImageMessageContent, + _ isOutgoing: Bool) -> RoomTimelineItemProtocol { ImageRoomTimelineItem(id: eventItemProxy.id, timestamp: eventItemProxy.timestamp.formatted(date: .omitted, time: .shortened), isOutgoing: isOutgoing, isEditable: eventItemProxy.isEditable, canBeRepliedTo: eventItemProxy.canBeRepliedTo, - isThreaded: isThreaded, + isThreaded: messageContent.threadRoot != nil, sender: eventItemProxy.sender, - content: buildImageTimelineItemContent(messageContent), - replyDetails: buildReplyToDetailsFromDetailsIfAvailable(details: messageTimelineItem.inReplyTo()), - properties: RoomTimelineItemProperties(isEdited: messageTimelineItem.isEdited(), + content: buildImageTimelineItemContent(imageMessageContent), + replyDetails: buildReplyToDetailsFromDetailsIfAvailable(details: messageContent.inReplyTo), + properties: RoomTimelineItemProperties(isEdited: messageContent.isEdited, reactions: aggregateReactions(eventItemProxy.reactions), deliveryStatus: eventItemProxy.deliveryStatus, orderedReadReceipts: orderReadReceipts(eventItemProxy.readReceipts), @@ -238,20 +231,19 @@ struct RoomTimelineItemFactory: RoomTimelineItemFactoryProtocol { } private func buildVideoTimelineItem(for eventItemProxy: EventTimelineItemProxy, - _ messageTimelineItem: Message, - _ messageContent: VideoMessageContent, - _ isOutgoing: Bool, - _ isThreaded: Bool) -> RoomTimelineItemProtocol { + _ messageContent: MessageContent, + _ videoMessageContent: VideoMessageContent, + _ isOutgoing: Bool) -> RoomTimelineItemProtocol { VideoRoomTimelineItem(id: eventItemProxy.id, timestamp: eventItemProxy.timestamp.formatted(date: .omitted, time: .shortened), isOutgoing: isOutgoing, isEditable: eventItemProxy.isEditable, canBeRepliedTo: eventItemProxy.canBeRepliedTo, - isThreaded: isThreaded, + isThreaded: messageContent.threadRoot != nil, sender: eventItemProxy.sender, - content: buildVideoTimelineItemContent(messageContent), - replyDetails: buildReplyToDetailsFromDetailsIfAvailable(details: messageTimelineItem.inReplyTo()), - properties: RoomTimelineItemProperties(isEdited: messageTimelineItem.isEdited(), + content: buildVideoTimelineItemContent(videoMessageContent), + replyDetails: buildReplyToDetailsFromDetailsIfAvailable(details: messageContent.inReplyTo), + properties: RoomTimelineItemProperties(isEdited: messageContent.isEdited, reactions: aggregateReactions(eventItemProxy.reactions), deliveryStatus: eventItemProxy.deliveryStatus, orderedReadReceipts: orderReadReceipts(eventItemProxy.readReceipts), @@ -259,20 +251,19 @@ struct RoomTimelineItemFactory: RoomTimelineItemFactoryProtocol { } private func buildAudioTimelineItem(for eventItemProxy: EventTimelineItemProxy, - _ messageTimelineItem: Message, - _ messageContent: AudioMessageContent, - _ isOutgoing: Bool, - _ isThreaded: Bool) -> RoomTimelineItemProtocol { + _ messageContent: MessageContent, + _ audioMessageContent: AudioMessageContent, + _ isOutgoing: Bool) -> RoomTimelineItemProtocol { AudioRoomTimelineItem(id: eventItemProxy.id, timestamp: eventItemProxy.timestamp.formatted(date: .omitted, time: .shortened), isOutgoing: isOutgoing, isEditable: eventItemProxy.isEditable, canBeRepliedTo: eventItemProxy.canBeRepliedTo, - isThreaded: isThreaded, + isThreaded: messageContent.threadRoot != nil, sender: eventItemProxy.sender, - content: buildAudioTimelineItemContent(messageContent), - replyDetails: buildReplyToDetailsFromDetailsIfAvailable(details: messageTimelineItem.inReplyTo()), - properties: RoomTimelineItemProperties(isEdited: messageTimelineItem.isEdited(), + content: buildAudioTimelineItemContent(audioMessageContent), + replyDetails: buildReplyToDetailsFromDetailsIfAvailable(details: messageContent.inReplyTo), + properties: RoomTimelineItemProperties(isEdited: messageContent.isEdited, reactions: aggregateReactions(eventItemProxy.reactions), deliveryStatus: eventItemProxy.deliveryStatus, orderedReadReceipts: orderReadReceipts(eventItemProxy.readReceipts), @@ -280,20 +271,19 @@ struct RoomTimelineItemFactory: RoomTimelineItemFactoryProtocol { } private func buildVoiceTimelineItem(for eventItemProxy: EventTimelineItemProxy, - _ messageTimelineItem: Message, - _ messageContent: AudioMessageContent, - _ isOutgoing: Bool, - _ isThreaded: Bool) -> RoomTimelineItemProtocol { + _ messageContent: MessageContent, + _ audioMessageContent: AudioMessageContent, + _ isOutgoing: Bool) -> RoomTimelineItemProtocol { VoiceMessageRoomTimelineItem(id: eventItemProxy.id, timestamp: eventItemProxy.timestamp.formatted(date: .omitted, time: .shortened), isOutgoing: isOutgoing, isEditable: eventItemProxy.isEditable, canBeRepliedTo: eventItemProxy.canBeRepliedTo, - isThreaded: isThreaded, + isThreaded: messageContent.threadRoot != nil, sender: eventItemProxy.sender, - content: buildAudioTimelineItemContent(messageContent), - replyDetails: buildReplyToDetailsFromDetailsIfAvailable(details: messageTimelineItem.inReplyTo()), - properties: RoomTimelineItemProperties(isEdited: messageTimelineItem.isEdited(), + content: buildAudioTimelineItemContent(audioMessageContent), + replyDetails: buildReplyToDetailsFromDetailsIfAvailable(details: messageContent.inReplyTo), + properties: RoomTimelineItemProperties(isEdited: messageContent.isEdited, reactions: aggregateReactions(eventItemProxy.reactions), deliveryStatus: eventItemProxy.deliveryStatus, orderedReadReceipts: orderReadReceipts(eventItemProxy.readReceipts), @@ -301,20 +291,19 @@ struct RoomTimelineItemFactory: RoomTimelineItemFactoryProtocol { } private func buildFileTimelineItem(for eventItemProxy: EventTimelineItemProxy, - _ messageTimelineItem: Message, - _ messageContent: FileMessageContent, - _ isOutgoing: Bool, - _ isThreaded: Bool) -> RoomTimelineItemProtocol { + _ messageContent: MessageContent, + _ fileMessageContent: FileMessageContent, + _ isOutgoing: Bool) -> RoomTimelineItemProtocol { FileRoomTimelineItem(id: eventItemProxy.id, timestamp: eventItemProxy.timestamp.formatted(date: .omitted, time: .shortened), isOutgoing: isOutgoing, isEditable: eventItemProxy.isEditable, canBeRepliedTo: eventItemProxy.canBeRepliedTo, - isThreaded: isThreaded, + isThreaded: messageContent.threadRoot != nil, sender: eventItemProxy.sender, - content: buildFileTimelineItemContent(messageContent), - replyDetails: buildReplyToDetailsFromDetailsIfAvailable(details: messageTimelineItem.inReplyTo()), - properties: RoomTimelineItemProperties(isEdited: messageTimelineItem.isEdited(), + content: buildFileTimelineItemContent(fileMessageContent), + replyDetails: buildReplyToDetailsFromDetailsIfAvailable(details: messageContent.inReplyTo), + properties: RoomTimelineItemProperties(isEdited: messageContent.isEdited, reactions: aggregateReactions(eventItemProxy.reactions), deliveryStatus: eventItemProxy.deliveryStatus, orderedReadReceipts: orderReadReceipts(eventItemProxy.readReceipts), @@ -322,20 +311,19 @@ struct RoomTimelineItemFactory: RoomTimelineItemFactoryProtocol { } private func buildNoticeTimelineItem(for eventItemProxy: EventTimelineItemProxy, - _ messageTimelineItem: Message, - _ messageContent: NoticeMessageContent, - _ isOutgoing: Bool, - _ isThreaded: Bool) -> RoomTimelineItemProtocol { + _ messageContent: MessageContent, + _ noticeMessageContent: NoticeMessageContent, + _ isOutgoing: Bool) -> RoomTimelineItemProtocol { NoticeRoomTimelineItem(id: eventItemProxy.id, timestamp: eventItemProxy.timestamp.formatted(date: .omitted, time: .shortened), isOutgoing: isOutgoing, isEditable: eventItemProxy.isEditable, canBeRepliedTo: eventItemProxy.canBeRepliedTo, - isThreaded: isThreaded, + isThreaded: messageContent.threadRoot != nil, sender: eventItemProxy.sender, - content: buildNoticeTimelineItemContent(messageContent), - replyDetails: buildReplyToDetailsFromDetailsIfAvailable(details: messageTimelineItem.inReplyTo()), - properties: RoomTimelineItemProperties(isEdited: messageTimelineItem.isEdited(), + content: buildNoticeTimelineItemContent(noticeMessageContent), + replyDetails: buildReplyToDetailsFromDetailsIfAvailable(details: messageContent.inReplyTo), + properties: RoomTimelineItemProperties(isEdited: messageContent.isEdited, reactions: aggregateReactions(eventItemProxy.reactions), deliveryStatus: eventItemProxy.deliveryStatus, orderedReadReceipts: orderReadReceipts(eventItemProxy.readReceipts), @@ -343,20 +331,19 @@ struct RoomTimelineItemFactory: RoomTimelineItemFactoryProtocol { } private func buildEmoteTimelineItem(for eventItemProxy: EventTimelineItemProxy, - _ messageTimelineItem: Message, - _ messageContent: EmoteMessageContent, - _ isOutgoing: Bool, - _ isThreaded: Bool) -> RoomTimelineItemProtocol { + _ messageContent: MessageContent, + _ emoteMessageContent: EmoteMessageContent, + _ isOutgoing: Bool) -> RoomTimelineItemProtocol { EmoteRoomTimelineItem(id: eventItemProxy.id, timestamp: eventItemProxy.timestamp.formatted(date: .omitted, time: .shortened), isOutgoing: isOutgoing, isEditable: eventItemProxy.isEditable, canBeRepliedTo: eventItemProxy.canBeRepliedTo, - isThreaded: isThreaded, + isThreaded: messageContent.threadRoot != nil, sender: eventItemProxy.sender, - content: buildEmoteTimelineItemContent(senderDisplayName: eventItemProxy.sender.displayName, senderID: eventItemProxy.sender.id, messageContent: messageContent), - replyDetails: buildReplyToDetailsFromDetailsIfAvailable(details: messageTimelineItem.inReplyTo()), - properties: RoomTimelineItemProperties(isEdited: messageTimelineItem.isEdited(), + content: buildEmoteTimelineItemContent(senderDisplayName: eventItemProxy.sender.displayName, senderID: eventItemProxy.sender.id, messageContent: emoteMessageContent), + replyDetails: buildReplyToDetailsFromDetailsIfAvailable(details: messageContent.inReplyTo), + properties: RoomTimelineItemProperties(isEdited: messageContent.isEdited, reactions: aggregateReactions(eventItemProxy.reactions), deliveryStatus: eventItemProxy.deliveryStatus, orderedReadReceipts: orderReadReceipts(eventItemProxy.readReceipts), @@ -364,20 +351,19 @@ struct RoomTimelineItemFactory: RoomTimelineItemFactoryProtocol { } private func buildLocationTimelineItem(for eventItemProxy: EventTimelineItemProxy, - _ messageTimelineItem: Message, - _ messageContent: LocationContent, - _ isOutgoing: Bool, - _ isThreaded: Bool) -> RoomTimelineItemProtocol { + _ messageContent: MessageContent, + _ locationMessageContent: LocationContent, + _ isOutgoing: Bool) -> RoomTimelineItemProtocol { LocationRoomTimelineItem(id: eventItemProxy.id, timestamp: eventItemProxy.timestamp.formatted(date: .omitted, time: .shortened), isOutgoing: isOutgoing, isEditable: eventItemProxy.isEditable, canBeRepliedTo: eventItemProxy.canBeRepliedTo, - isThreaded: isThreaded, + isThreaded: messageContent.threadRoot != nil, sender: eventItemProxy.sender, - content: buildLocationTimelineItemContent(messageContent), - replyDetails: buildReplyToDetailsFromDetailsIfAvailable(details: messageTimelineItem.inReplyTo()), - properties: RoomTimelineItemProperties(isEdited: messageTimelineItem.isEdited(), + content: buildLocationTimelineItemContent(locationMessageContent), + replyDetails: buildReplyToDetailsFromDetailsIfAvailable(details: messageContent.inReplyTo), + properties: RoomTimelineItemProperties(isEdited: messageContent.isEdited, reactions: aggregateReactions(eventItemProxy.reactions), deliveryStatus: eventItemProxy.deliveryStatus, orderedReadReceipts: orderReadReceipts(eventItemProxy.readReceipts), @@ -652,12 +638,12 @@ struct RoomTimelineItemFactory: RoomTimelineItemFactoryProtocol { // MARK: - Reply details func buildReply(details: InReplyToDetails) -> TimelineItemReply { - let isThreaded = details.event.isThreaded - switch details.event { + let isThreaded = details.event().isThreaded + switch details.event() { case .unavailable: - return .init(details: .notLoaded(eventID: details.eventId), isThreaded: isThreaded) + return .init(details: .notLoaded(eventID: details.eventId()), isThreaded: isThreaded) case .pending: - return .init(details: .loading(eventID: details.eventId), isThreaded: isThreaded) + return .init(details: .loading(eventID: details.eventId()), isThreaded: isThreaded) case let .ready(timelineItem, senderID, senderProfile): let sender: TimelineItemSender switch senderProfile { @@ -675,9 +661,9 @@ struct RoomTimelineItemFactory: RoomTimelineItemFactoryProtocol { let replyContent: TimelineEventContent - switch timelineItem.kind() { - case .message: - return .init(details: timelineItemReplyDetails(sender: sender, eventID: details.eventId, messageType: timelineItem.asMessage()?.msgtype()), isThreaded: isThreaded) + switch timelineItem { + case .message(let messageContent): + return .init(details: timelineItemReplyDetails(sender: sender, eventID: details.eventId(), messageType: messageContent.msgType), isThreaded: isThreaded) case .poll(let question, _, _, _, _, _, _): replyContent = .poll(question: question) case .sticker(let body, _, _): @@ -688,9 +674,9 @@ struct RoomTimelineItemFactory: RoomTimelineItemFactoryProtocol { replyContent = .message(.text(.init(body: L10n.commonUnsupportedEvent))) } - return .init(details: .loaded(sender: sender, eventID: details.eventId, eventContent: replyContent), isThreaded: isThreaded) + return .init(details: .loaded(sender: sender, eventID: details.eventId(), eventContent: replyContent), isThreaded: isThreaded) case let .error(message): - return .init(details: .error(eventID: details.eventId, message: message), isThreaded: isThreaded) + return .init(details: .error(eventID: details.eventId(), message: message), isThreaded: isThreaded) } } @@ -751,7 +737,11 @@ private extension RepliedToEventDetails { var isThreaded: Bool { switch self { case .ready(let content, _, _): - return content.asMessage()?.isThreaded() ?? false + guard case let .message(content) = content else { + return false + } + + return content.threadRoot != nil default: return false } diff --git a/ElementX/Sources/Services/Timeline/TimelineItems/RoomTimelineItemViewState.swift b/ElementX/Sources/Services/Timeline/TimelineItems/RoomTimelineItemViewState.swift index d3ae94828..5d5322a4d 100644 --- a/ElementX/Sources/Services/Timeline/TimelineItems/RoomTimelineItemViewState.swift +++ b/ElementX/Sources/Services/Timeline/TimelineItems/RoomTimelineItemViewState.swift @@ -8,23 +8,14 @@ import Foundation final class RoomTimelineItemViewState: Identifiable, Equatable, ObservableObject { - static func == (lhs: RoomTimelineItemViewState, rhs: RoomTimelineItemViewState) -> Bool { - lhs.type == rhs.type && lhs.groupStyle == rhs.groupStyle - } - @Published var type: RoomTimelineItemType @Published var groupStyle: TimelineGroupStyle - /// Contains all the identification info of the item, `timelineID`, `eventID` and `transactionID` + /// Contains all the identification info of the item, `uniqueID`, `eventID` and `transactionID` var identifier: TimelineItemIdentifier { type.id } - /// The `timelineID` of the item, used for the timeline view level identification, do not use for any business logic use `identifier` instead - var id: String { - identifier.timelineID - } - init(type: RoomTimelineItemType, groupStyle: TimelineGroupStyle) { self.type = type self.groupStyle = groupStyle @@ -33,6 +24,19 @@ final class RoomTimelineItemViewState: Identifiable, Equatable, ObservableObject convenience init(item: RoomTimelineItemProtocol, groupStyle: TimelineGroupStyle) { self.init(type: .init(item: item), groupStyle: groupStyle) } + + // MARK: - Equatable + + static func == (lhs: RoomTimelineItemViewState, rhs: RoomTimelineItemViewState) -> Bool { + lhs.type == rhs.type && lhs.groupStyle == rhs.groupStyle + } + + // MARK: Identifiable + + /// The `timelineID` of the item, used for the timeline view level identification, do not use for any business logic use `identifier` instead + var id: String { + identifier.uniqueID + } } enum RoomTimelineItemType: Equatable { diff --git a/ElementX/Sources/Services/Timeline/TimelineProxy.swift b/ElementX/Sources/Services/Timeline/TimelineProxy.swift index a3bee43fd..3d7c7ee80 100644 --- a/ElementX/Sources/Services/Timeline/TimelineProxy.swift +++ b/ElementX/Sources/Services/Timeline/TimelineProxy.swift @@ -72,7 +72,17 @@ final class TimelineProxy: TimelineProxyProtocol { } func messageEventContent(for timelineItemID: TimelineItemIdentifier) async -> RoomMessageEventContentWithoutRelation? { - await timelineProvider.itemProxies.firstEventTimelineItemUsingStableID(timelineItemID)?.content().asMessage()?.content() + guard let content = await timelineProvider.itemProxies.firstEventTimelineItemUsingStableID(timelineItemID)?.content, + case let .message(messageContent) = content else { + return nil + } + + do { + return try contentWithoutRelationFromMessage(message: messageContent) + } catch { + MXLog.error("Failed retrieving message event content for timelineItemID=\(timelineItemID)") + return nil + } } func paginateBackwards(requestSize: UInt16) async -> Result { @@ -156,15 +166,15 @@ final class TimelineProxy: TimelineProxyProtocol { func edit(_ timelineItem: EventTimelineItem, newContent: RoomMessageEventContentWithoutRelation) async -> Result { do { - guard try await timeline.edit(item: timelineItem, newContent: .roomMessage(content: newContent)) == true else { + guard try await timeline.edit(eventOrTransactionId: timelineItem.eventOrTransactionId, newContent: .roomMessage(content: newContent)) == true else { return .failure(.failedEditing) } - MXLog.info("Finished editing timeline item: \(timelineItem.eventId() ?? timelineItem.transactionId() ?? "unknown")") + MXLog.info("Finished editing timeline item: \(timelineItem.eventOrTransactionId)") return .success(()) } catch { - MXLog.error("Failed editing timeline item: \(timelineItem.eventId() ?? timelineItem.transactionId() ?? "unknown") with error: \(error)") + MXLog.error("Failed editing timeline item: \(timelineItem.eventOrTransactionId) with error: \(error)") return .failure(.sdkError(error)) } } @@ -172,18 +182,13 @@ final class TimelineProxy: TimelineProxyProtocol { func redact(_ timelineItemID: TimelineItemIdentifier, reason: String?) async -> Result { MXLog.info("Redacting timeline item: \(timelineItemID)") - guard let eventTimelineItem = await timelineProvider.itemProxies.firstEventTimelineItemUsingStableID(timelineItemID) else { + guard let eventOrTransactionID = await timelineProvider.itemProxies.firstEventTimelineItemUsingStableID(timelineItemID)?.eventOrTransactionId else { MXLog.error("Unknown timeline item: \(timelineItemID)") return .failure(.failedRedacting) } do { - let success = try await timeline.redactEvent(item: eventTimelineItem, reason: reason) - - guard success else { - MXLog.error("Failed redacting timeline item: \(timelineItemID)") - return .failure(.failedRedacting) - } + try await timeline.redactEvent(eventOrTransactionId: eventOrTransactionID, reason: reason) MXLog.info("Redacted timeline item: \(timelineItemID)") @@ -425,7 +430,7 @@ final class TimelineProxy: TimelineProxyProtocol { MXLog.info("Toggling reaction for event: \(itemID)") do { - try await timeline.toggleReaction(uniqueId: itemID.timelineID, key: reaction) + try await timeline.toggleReaction(uniqueId: itemID.uniqueID, key: reaction) MXLog.info("Finished toggling reaction for event: \(itemID)") return .success(()) } catch { @@ -460,7 +465,7 @@ final class TimelineProxy: TimelineProxyProtocol { do { let originalEvent = try await timeline.getEventTimelineItemByEventId(eventId: eventID) - guard try await timeline.edit(item: originalEvent, + guard try await timeline.edit(eventOrTransactionId: originalEvent.eventOrTransactionId, newContent: .pollStart(pollData: .init(question: question, answers: answers, maxSelections: 1, @@ -482,7 +487,7 @@ final class TimelineProxy: TimelineProxyProtocol { return await Task.dispatch(on: .global()) { do { - try self.timeline.endPoll(pollStartId: pollStartID, text: text) + try self.timeline.endPoll(pollStartEventId: pollStartID, text: text) MXLog.info("Finished ending poll with eventID: \(pollStartID)") @@ -498,7 +503,7 @@ final class TimelineProxy: TimelineProxyProtocol { MXLog.info("Sending response for poll with eventID: \(pollStartID)") do { - try await timeline.sendPollResponse(pollStartId: pollStartID, answers: answers) + try await timeline.sendPollResponse(pollStartEventId: pollStartID, answers: answers) MXLog.info("Finished sending response for poll with eventID: \(pollStartID)") @@ -618,7 +623,7 @@ extension Array where Element == TimelineItemProxy { func firstEventTimelineItemUsingStableID(_ id: TimelineItemIdentifier) -> EventTimelineItem? { for item in self { if case let .event(eventTimelineItem) = item { - if eventTimelineItem.id.timelineID == id.timelineID { + if eventTimelineItem.id.uniqueID == id.uniqueID { return eventTimelineItem.item } } diff --git a/UITests/Sources/PollFormScreenUITests.swift b/UITests/Sources/PollFormScreenUITests.swift index b2587b748..fa02f72b9 100644 --- a/UITests/Sources/PollFormScreenUITests.swift +++ b/UITests/Sources/PollFormScreenUITests.swift @@ -17,15 +17,15 @@ class PollFormScreenUITests: XCTestCase { func testFilledPoll() async throws { let app = Application.launch(.createPoll) let questionTextField = app.textViews[A11yIdentifiers.pollFormScreen.question] - questionTextField.forceTap() + questionTextField.tapCenter() questionTextField.typeText("Do you like polls?") let option1TextField = app.textViews[A11yIdentifiers.pollFormScreen.optionID(0)] - option1TextField.forceTap() + option1TextField.tapCenter() option1TextField.typeText("Yes") let option2TextField = app.textViews[A11yIdentifiers.pollFormScreen.optionID(1)] - option2TextField.forceTap() + option2TextField.tapCenter() option2TextField.typeText("No") // Dismiss the keyboard diff --git a/UITests/Sources/UserSessionScreenTests.swift b/UITests/Sources/UserSessionScreenTests.swift index bb8d05177..942dae1fd 100644 --- a/UITests/Sources/UserSessionScreenTests.swift +++ b/UITests/Sources/UserSessionScreenTests.swift @@ -20,7 +20,7 @@ class UserSessionScreenTests: XCTestCase { try await Task.sleep(for: .seconds(1)) try await app.assertScreenshot(.userSessionScreen, step: 2) - app.buttons[A11yIdentifiers.roomScreen.composerToolbar.openComposeOptions].forceTap() + app.buttons[A11yIdentifiers.roomScreen.composerToolbar.openComposeOptions].tapCenter() try await app.assertScreenshot(.userSessionScreen, step: 3) } diff --git a/UnitTests/Sources/ComposerToolbarViewModelTests.swift b/UnitTests/Sources/ComposerToolbarViewModelTests.swift index d78853488..d4bf5fae0 100644 --- a/UnitTests/Sources/ComposerToolbarViewModelTests.swift +++ b/UnitTests/Sources/ComposerToolbarViewModelTests.swift @@ -41,14 +41,14 @@ class ComposerToolbarViewModelTests: XCTestCase { } func testComposerFocus() { - viewModel.process(timelineAction: .setMode(mode: .edit(originalItemId: TimelineItemIdentifier(timelineID: "mock")))) + viewModel.process(timelineAction: .setMode(mode: .edit(originalItemId: TimelineItemIdentifier(uniqueID: "mock")))) XCTAssertTrue(viewModel.state.bindings.composerFocused) viewModel.process(timelineAction: .removeFocus) XCTAssertFalse(viewModel.state.bindings.composerFocused) } func testComposerMode() { - let mode: ComposerMode = .edit(originalItemId: TimelineItemIdentifier(timelineID: "mock")) + let mode: ComposerMode = .edit(originalItemId: TimelineItemIdentifier(uniqueID: "mock")) viewModel.process(timelineAction: .setMode(mode: mode)) XCTAssertEqual(viewModel.state.composerMode, mode) viewModel.process(timelineAction: .clear) @@ -56,7 +56,7 @@ class ComposerToolbarViewModelTests: XCTestCase { } func testComposerModeIsPublished() { - let mode: ComposerMode = .edit(originalItemId: TimelineItemIdentifier(timelineID: "mock")) + let mode: ComposerMode = .edit(originalItemId: TimelineItemIdentifier(uniqueID: "mock")) let expectation = expectation(description: "Composer mode is published") let cancellable = viewModel .context @@ -236,7 +236,7 @@ class ComposerToolbarViewModelTests: XCTestCase { } viewModel.context.composerFormattingEnabled = false - viewModel.process(timelineAction: .setMode(mode: .edit(originalItemId: .init(timelineID: "", eventID: "testID")))) + viewModel.process(timelineAction: .setMode(mode: .edit(originalItemId: .init(uniqueID: "", eventOrTransactionID: .eventId(eventId: "testID"))))) viewModel.context.plainComposerText = .init(string: "Hello world!") viewModel.saveDraft() @@ -257,12 +257,11 @@ class ComposerToolbarViewModelTests: XCTestCase { } viewModel.context.composerFormattingEnabled = false - viewModel.process(timelineAction: .setMode(mode: .reply(itemID: .init(timelineID: "", - eventID: "testID"), - replyDetails: .loaded(sender: .init(id: ""), - eventID: "testID", - eventContent: .message(.text(.init(body: "reply text")))), - isThread: false))) + viewModel.process(timelineAction: .setMode(mode: .reply(itemID: .init(uniqueID: "", eventOrTransactionID: .eventId(eventId: "testID")), + replyDetails: .loaded(sender: .init(id: ""), + eventID: "testID", + eventContent: .message(.text(.init(body: "reply text")))), + isThread: false))) viewModel.context.plainComposerText = .init(string: "Hello world!") viewModel.saveDraft() @@ -283,12 +282,11 @@ class ComposerToolbarViewModelTests: XCTestCase { } viewModel.context.composerFormattingEnabled = false - viewModel.process(timelineAction: .setMode(mode: .reply(itemID: .init(timelineID: "", - eventID: "testID"), - replyDetails: .loaded(sender: .init(id: ""), - eventID: "testID", - eventContent: .message(.text(.init(body: "reply text")))), - isThread: false))) + viewModel.process(timelineAction: .setMode(mode: .reply(itemID: .init(uniqueID: "", eventOrTransactionID: .eventId(eventId: "testID")), + replyDetails: .loaded(sender: .init(id: ""), + eventID: "testID", + eventContent: .message(.text(.init(body: "reply text")))), + isThread: false))) viewModel.saveDraft() await fulfillment(of: [expectation], timeout: 10) @@ -397,7 +395,7 @@ class ComposerToolbarViewModelTests: XCTestCase { await fulfillment(of: [expectation], timeout: 10) XCTAssertFalse(viewModel.context.composerFormattingEnabled) - XCTAssertEqual(viewModel.state.composerMode, .edit(originalItemId: .init(timelineID: "", eventID: "testID"))) + XCTAssertEqual(viewModel.state.composerMode, .edit(originalItemId: .init(uniqueID: "", eventOrTransactionID: .eventId(eventId: "testID")))) XCTAssertEqual(viewModel.context.plainComposerText, NSAttributedString(string: "Hello world!")) } @@ -431,13 +429,13 @@ class ComposerToolbarViewModelTests: XCTestCase { await fulfillment(of: [draftExpectation], timeout: 10) XCTAssertFalse(viewModel.context.composerFormattingEnabled) // Testing the loading state first - XCTAssertEqual(viewModel.state.composerMode, .reply(itemID: .init(timelineID: "", eventID: testEventID), + XCTAssertEqual(viewModel.state.composerMode, .reply(itemID: .init(uniqueID: "", eventOrTransactionID: .eventId(eventId: testEventID)), replyDetails: .loading(eventID: testEventID), isThread: false)) XCTAssertEqual(viewModel.context.plainComposerText, NSAttributedString(string: text)) await fulfillment(of: [loadReplyExpectation], timeout: 10) - XCTAssertEqual(viewModel.state.composerMode, .reply(itemID: .init(timelineID: "", eventID: testEventID), + XCTAssertEqual(viewModel.state.composerMode, .reply(itemID: .init(uniqueID: "", eventOrTransactionID: .eventId(eventId: testEventID)), replyDetails: loadedReply, isThread: true)) } @@ -445,8 +443,7 @@ class ComposerToolbarViewModelTests: XCTestCase { func testRestoreReplyAndCancelReplyMode() async { let testEventID = "testID" let text = "Hello world!" - let loadedReply = TimelineItemReplyDetails.loaded(sender: .init(id: "userID", - displayName: "Username"), + let loadedReply = TimelineItemReplyDetails.loaded(sender: .init(id: "userID", displayName: "Username"), eventID: testEventID, eventContent: .message(.text(.init(body: "Reply text")))) @@ -472,7 +469,7 @@ class ComposerToolbarViewModelTests: XCTestCase { await fulfillment(of: [draftExpectation], timeout: 10) XCTAssertFalse(viewModel.context.composerFormattingEnabled) // Testing the loading state first - XCTAssertEqual(viewModel.state.composerMode, .reply(itemID: .init(timelineID: "", eventID: testEventID), + XCTAssertEqual(viewModel.state.composerMode, .reply(itemID: .init(uniqueID: "", eventOrTransactionID: .eventId(eventId: testEventID)), replyDetails: .loading(eventID: testEventID), isThread: false)) XCTAssertEqual(viewModel.context.plainComposerText, NSAttributedString(string: text)) diff --git a/UnitTests/Sources/LoggingTests.swift b/UnitTests/Sources/LoggingTests.swift index df701300a..99019ac58 100644 --- a/UnitTests/Sources/LoggingTests.swift +++ b/UnitTests/Sources/LoggingTests.swift @@ -142,7 +142,7 @@ class LoggingTests: XCTestCase { isThreaded: false, sender: .init(id: "sender"), content: .init(body: "EmoteString", formattedBody: AttributedString(emoteAttributedString))) - let imageMessage = ImageRoomTimelineItem(id: .init(timelineID: "myimagemessage"), + let imageMessage = ImageRoomTimelineItem(id: .init(uniqueID: "myimagemessage"), timestamp: "", isOutgoing: false, isEditable: false, @@ -184,25 +184,25 @@ class LoggingTests: XCTestCase { } let content = try String(contentsOf: logFile) - XCTAssertTrue(content.contains(textMessage.id.timelineID)) + XCTAssertTrue(content.contains(textMessage.id.uniqueID)) XCTAssertFalse(content.contains(textMessage.body)) XCTAssertFalse(content.contains(textAttributedString)) - XCTAssertTrue(content.contains(noticeMessage.id.timelineID)) + XCTAssertTrue(content.contains(noticeMessage.id.uniqueID)) XCTAssertFalse(content.contains(noticeMessage.body)) XCTAssertFalse(content.contains(noticeAttributedString)) - XCTAssertTrue(content.contains(emoteMessage.id.timelineID)) + XCTAssertTrue(content.contains(emoteMessage.id.uniqueID)) XCTAssertFalse(content.contains(emoteMessage.body)) XCTAssertFalse(content.contains(emoteAttributedString)) - XCTAssertTrue(content.contains(imageMessage.id.timelineID)) + XCTAssertTrue(content.contains(imageMessage.id.uniqueID)) XCTAssertFalse(content.contains(imageMessage.body)) - XCTAssertTrue(content.contains(videoMessage.id.timelineID)) + XCTAssertTrue(content.contains(videoMessage.id.uniqueID)) XCTAssertFalse(content.contains(videoMessage.body)) - XCTAssertTrue(content.contains(fileMessage.id.timelineID)) + XCTAssertTrue(content.contains(fileMessage.id.uniqueID)) XCTAssertFalse(content.contains(fileMessage.body)) } diff --git a/UnitTests/Sources/MessageForwardingScreenViewModelTests.swift b/UnitTests/Sources/MessageForwardingScreenViewModelTests.swift index 292d85d1f..e1705b388 100644 --- a/UnitTests/Sources/MessageForwardingScreenViewModelTests.swift +++ b/UnitTests/Sources/MessageForwardingScreenViewModelTests.swift @@ -12,7 +12,7 @@ import XCTest @MainActor class MessageForwardingScreenViewModelTests: XCTestCase { - let forwardingItem = MessageForwardingItem(id: .init(timelineID: "t1", eventID: "t1"), + let forwardingItem = MessageForwardingItem(id: .init(uniqueID: "t1", eventOrTransactionID: .eventId(eventId: "t1")), roomID: "1", content: .init(noPointer: .init())) var viewModel: MessageForwardingScreenViewModelProtocol! diff --git a/UnitTests/Sources/RoomScreenViewModelTests.swift b/UnitTests/Sources/RoomScreenViewModelTests.swift index ab52a3cd1..20207bf01 100644 --- a/UnitTests/Sources/RoomScreenViewModelTests.swift +++ b/UnitTests/Sources/RoomScreenViewModelTests.swift @@ -6,6 +6,7 @@ // @testable import ElementX +import MatrixRustSDK import Combine import XCTest @@ -66,8 +67,8 @@ class RoomScreenViewModelTests: XCTestCase { let providerUpdateSubject = PassthroughSubject<([TimelineItemProxy], PaginationState), Never>() pinnedTimelineProviderMock.underlyingUpdatePublisher = providerUpdateSubject.eraseToAnyPublisher() pinnedTimelineMock.timelineProvider = pinnedTimelineProviderMock - pinnedTimelineProviderMock.itemProxies = [.event(.init(item: EventTimelineItemSDKMock(configuration: .init(eventID: "test1")), id: "1")), - .event(.init(item: EventTimelineItemSDKMock(configuration: .init(eventID: "test2")), id: "2"))] + pinnedTimelineProviderMock.itemProxies = [.event(.init(item: EventTimelineItem(configuration: .init(eventID: "test1")), uniqueID: "1")), + .event(.init(item: EventTimelineItem(configuration: .init(eventID: "test2")), uniqueID: "2"))] // check if the banner is now in a loaded state and is showing the counter deferred = deferFulfillment(viewModel.context.$viewState) { viewState in @@ -83,9 +84,9 @@ class RoomScreenViewModelTests: XCTestCase { deferred = deferFulfillment(viewModel.context.$viewState) { viewState in viewState.pinnedEventsBannerState.count == 3 } - providerUpdateSubject.send(([.event(.init(item: EventTimelineItemSDKMock(configuration: .init(eventID: "test1")), id: "1")), - .event(.init(item: EventTimelineItemSDKMock(configuration: .init(eventID: "test2")), id: "2")), - .event(.init(item: EventTimelineItemSDKMock(configuration: .init(eventID: "test3")), id: "3"))], .initial)) + providerUpdateSubject.send(([.event(.init(item: EventTimelineItem(configuration: .init(eventID: "test1")), uniqueID: "1")), + .event(.init(item: EventTimelineItem(configuration: .init(eventID: "test2")), uniqueID: "2")), + .event(.init(item: EventTimelineItem(configuration: .init(eventID: "test3")), uniqueID: "3"))], .initial)) try await deferred.fulfill() XCTAssertFalse(viewModel.context.viewState.pinnedEventsBannerState.isLoading) XCTAssertTrue(viewModel.context.viewState.shouldShowPinnedEventsBanner) @@ -106,9 +107,9 @@ class RoomScreenViewModelTests: XCTestCase { let pinnedTimelineProviderMock = RoomTimelineProviderMock() pinnedTimelineMock.timelineProvider = pinnedTimelineProviderMock pinnedTimelineProviderMock.underlyingUpdatePublisher = Empty<([TimelineItemProxy], PaginationState), Never>().eraseToAnyPublisher() - pinnedTimelineProviderMock.itemProxies = [.event(.init(item: EventTimelineItemSDKMock(configuration: .init(eventID: "test1")), id: "1")), - .event(.init(item: EventTimelineItemSDKMock(configuration: .init(eventID: "test2")), id: "2")), - .event(.init(item: EventTimelineItemSDKMock(configuration: .init(eventID: "test3")), id: "3"))] + pinnedTimelineProviderMock.itemProxies = [.event(.init(item: EventTimelineItem(configuration: .init(eventID: "test1")), uniqueID: "1")), + .event(.init(item: EventTimelineItem(configuration: .init(eventID: "test2")), uniqueID: "2")), + .event(.init(item: EventTimelineItem(configuration: .init(eventID: "test3")), uniqueID: "3"))] roomProxyMock.underlyingPinnedEventsTimeline = pinnedTimelineMock let viewModel = RoomScreenViewModel(roomProxy: roomProxyMock, initialSelectedPinnedEventID: "test1", diff --git a/UnitTests/Sources/TimelineItemFactoryTests.swift b/UnitTests/Sources/TimelineItemFactoryTests.swift index ec352957e..0ca14f8fa 100644 --- a/UnitTests/Sources/TimelineItemFactoryTests.swift +++ b/UnitTests/Sources/TimelineItemFactoryTests.swift @@ -6,6 +6,8 @@ // @testable import ElementX +import MatrixRustSDK + import XCTest @MainActor @@ -18,19 +20,9 @@ class TimelineItemFactoryTests: XCTestCase { attributedStringBuilder: AttributedStringBuilder(mentionBuilder: MentionBuilder()), stateEventStringBuilder: RoomStateEventStringBuilder(userID: ownUserID)) - let eventTimelineItem = EventTimelineItemSDKMock() - eventTimelineItem.isOwnReturnValue = true - eventTimelineItem.timestampReturnValue = 0 - eventTimelineItem.isEditableReturnValue = false - eventTimelineItem.canBeRepliedToReturnValue = false - eventTimelineItem.senderReturnValue = senderUserID - eventTimelineItem.senderProfileReturnValue = .pending + let eventTimelineItem = EventTimelineItem.mockCallInvite(sender: senderUserID) - let timelineItemContent = TimelineItemContentSDKMock() - timelineItemContent.kindReturnValue = .callInvite - eventTimelineItem.contentReturnValue = timelineItemContent - - let eventTimelineItemProxy = EventTimelineItemProxy(item: eventTimelineItem, id: "0") + let eventTimelineItemProxy = EventTimelineItemProxy(item: eventTimelineItem, uniqueID: "0") let item = factory.buildTimelineItem(for: eventTimelineItemProxy, isDM: false) diff --git a/UnitTests/Sources/TimelineViewModelTests.swift b/UnitTests/Sources/TimelineViewModelTests.swift index 1243d5291..062aff86c 100644 --- a/UnitTests/Sources/TimelineViewModelTests.swift +++ b/UnitTests/Sources/TimelineViewModelTests.swift @@ -258,9 +258,9 @@ class TimelineViewModelTests: XCTestCase { func testSendReadReceiptWithoutEvents() async throws { // Given a room with only virtual items. - let items = [SeparatorRoomTimelineItem(timelineID: "v1"), - SeparatorRoomTimelineItem(timelineID: "v2"), - SeparatorRoomTimelineItem(timelineID: "v3")] + let items = [SeparatorRoomTimelineItem(uniqueID: "v1"), + SeparatorRoomTimelineItem(uniqueID: "v2"), + SeparatorRoomTimelineItem(uniqueID: "v3")] let (viewModel, _, timelineProxy, _) = readReceiptsConfiguration(with: items) // When sending a read receipt for the last item. @@ -275,7 +275,7 @@ class TimelineViewModelTests: XCTestCase { // Given a room where the last event is a virtual item. let items: [RoomTimelineItemProtocol] = [TextRoomTimelineItem(eventID: "t1"), TextRoomTimelineItem(eventID: "t2"), - SeparatorRoomTimelineItem(timelineID: "v3")] + SeparatorRoomTimelineItem(uniqueID: "v3")] let (viewModel, _, _, _) = readReceiptsConfiguration(with: items) // When sending a read receipt for the last item. @@ -436,14 +436,14 @@ private extension TextRoomTimelineItem { } private extension SeparatorRoomTimelineItem { - init(timelineID: String) { - self.init(id: .init(timelineID: timelineID), text: "") + init(uniqueID: String) { + self.init(id: .init(uniqueID: uniqueID), text: "") } } private extension TextRoomTimelineItem { init(eventID: String) { - self.init(id: .init(timelineID: UUID().uuidString, eventID: eventID), + self.init(id: .init(uniqueID: UUID().uuidString, eventOrTransactionID: .eventId(eventId: eventID)), timestamp: "", isOutgoing: false, isEditable: false, diff --git a/project.yml b/project.yml index 281902718..cc0087e34 100644 --- a/project.yml +++ b/project.yml @@ -60,7 +60,7 @@ packages: # Element/Matrix dependencies MatrixRustSDK: url: https://github.com/element-hq/matrix-rust-components-swift - exactVersion: 1.0.52 + exactVersion: 1.0.53 # path: ../matrix-rust-sdk Compound: url: https://github.com/element-hq/compound-ios