From e54d80b219fec10c8f98b8ebb508cae2986728cb Mon Sep 17 00:00:00 2001 From: Doug Date: Thu, 29 Aug 2024 11:50:06 +0100 Subject: [PATCH 1/5] Adopt sliding sync versions for client Restoration. --- .../Mocks/Generated/GeneratedMocks.swift | 22 + .../Mocks/Generated/SDKGeneratedMocks.swift | 479 +++++++++++------- .../Sources/Services/Client/ClientProxy.swift | 10 + .../Services/Client/ClientProxyProtocol.swift | 5 +- .../UserSession/RestorationToken.swift | 13 +- .../UserSession/UserSessionStore.swift | 2 +- .../NotificationServiceExtension.swift | 1 - NSE/Sources/Other/NSESettingsProtocol.swift | 1 - NSE/Sources/Other/NSEUserSession.swift | 4 +- .../Sources/KeychainControllerTests.swift | 10 +- UnitTests/Sources/RestorationTokenTests.swift | 6 +- 11 files changed, 349 insertions(+), 204 deletions(-) diff --git a/ElementX/Sources/Mocks/Generated/GeneratedMocks.swift b/ElementX/Sources/Mocks/Generated/GeneratedMocks.swift index fac3902160..8aaaa2eb75 100644 --- a/ElementX/Sources/Mocks/Generated/GeneratedMocks.swift +++ b/ElementX/Sources/Mocks/Generated/GeneratedMocks.swift @@ -1925,6 +1925,28 @@ class ClientProxyMock: ClientProxyProtocol { set(value) { underlyingHomeserver = value } } var underlyingHomeserver: String! + var slidingSyncVersion: SlidingSyncVersion { + get { return underlyingSlidingSyncVersion } + set(value) { underlyingSlidingSyncVersion = value } + } + var underlyingSlidingSyncVersion: SlidingSyncVersion! + var availableSlidingSyncVersionsCallsCount = 0 + var availableSlidingSyncVersionsCalled: Bool { + return availableSlidingSyncVersionsCallsCount > 0 + } + + var availableSlidingSyncVersions: [SlidingSyncVersion] { + get async { + availableSlidingSyncVersionsCallsCount += 1 + if let availableSlidingSyncVersionsClosure = availableSlidingSyncVersionsClosure { + return await availableSlidingSyncVersionsClosure() + } else { + return underlyingAvailableSlidingSyncVersions + } + } + } + var underlyingAvailableSlidingSyncVersions: [SlidingSyncVersion]! + var availableSlidingSyncVersionsClosure: (() async -> [SlidingSyncVersion])? var userIDServerName: String? var userDisplayNamePublisher: CurrentValuePublisher { get { return underlyingUserDisplayNamePublisher } diff --git a/ElementX/Sources/Mocks/Generated/SDKGeneratedMocks.swift b/ElementX/Sources/Mocks/Generated/SDKGeneratedMocks.swift index 673559d1e6..8d2c52a05b 100644 --- a/ElementX/Sources/Mocks/Generated/SDKGeneratedMocks.swift +++ b/ElementX/Sources/Mocks/Generated/SDKGeneratedMocks.swift @@ -207,6 +207,71 @@ open class ClientSDKMock: MatrixRustSDK.Client { } } + //MARK: - availableSlidingSyncVersions + + var availableSlidingSyncVersionsUnderlyingCallsCount = 0 + open var availableSlidingSyncVersionsCallsCount: Int { + get { + if Thread.isMainThread { + return availableSlidingSyncVersionsUnderlyingCallsCount + } else { + var returnValue: Int? = nil + DispatchQueue.main.sync { + returnValue = availableSlidingSyncVersionsUnderlyingCallsCount + } + + return returnValue! + } + } + set { + if Thread.isMainThread { + availableSlidingSyncVersionsUnderlyingCallsCount = newValue + } else { + DispatchQueue.main.sync { + availableSlidingSyncVersionsUnderlyingCallsCount = newValue + } + } + } + } + open var availableSlidingSyncVersionsCalled: Bool { + return availableSlidingSyncVersionsCallsCount > 0 + } + + var availableSlidingSyncVersionsUnderlyingReturnValue: [SlidingSyncVersion]! + open var availableSlidingSyncVersionsReturnValue: [SlidingSyncVersion]! { + get { + if Thread.isMainThread { + return availableSlidingSyncVersionsUnderlyingReturnValue + } else { + var returnValue: [SlidingSyncVersion]? = nil + DispatchQueue.main.sync { + returnValue = availableSlidingSyncVersionsUnderlyingReturnValue + } + + return returnValue! + } + } + set { + if Thread.isMainThread { + availableSlidingSyncVersionsUnderlyingReturnValue = newValue + } else { + DispatchQueue.main.sync { + availableSlidingSyncVersionsUnderlyingReturnValue = newValue + } + } + } + } + open var availableSlidingSyncVersionsClosure: (() async -> [SlidingSyncVersion])? + + open override func availableSlidingSyncVersions() async -> [SlidingSyncVersion] { + availableSlidingSyncVersionsCallsCount += 1 + if let availableSlidingSyncVersionsClosure = availableSlidingSyncVersionsClosure { + return await availableSlidingSyncVersionsClosure() + } else { + return availableSlidingSyncVersionsReturnValue + } + } + //MARK: - avatarUrl open var avatarUrlThrowableError: Error? @@ -1955,6 +2020,52 @@ open class ClientSDKMock: MatrixRustSDK.Client { try await loginUsernamePasswordInitialDeviceNameDeviceIdClosure?(username, password, initialDeviceName, deviceId) } + //MARK: - loginWithEmail + + open var loginWithEmailEmailPasswordInitialDeviceNameDeviceIdThrowableError: Error? + var loginWithEmailEmailPasswordInitialDeviceNameDeviceIdUnderlyingCallsCount = 0 + open var loginWithEmailEmailPasswordInitialDeviceNameDeviceIdCallsCount: Int { + get { + if Thread.isMainThread { + return loginWithEmailEmailPasswordInitialDeviceNameDeviceIdUnderlyingCallsCount + } else { + var returnValue: Int? = nil + DispatchQueue.main.sync { + returnValue = loginWithEmailEmailPasswordInitialDeviceNameDeviceIdUnderlyingCallsCount + } + + return returnValue! + } + } + set { + if Thread.isMainThread { + loginWithEmailEmailPasswordInitialDeviceNameDeviceIdUnderlyingCallsCount = newValue + } else { + DispatchQueue.main.sync { + loginWithEmailEmailPasswordInitialDeviceNameDeviceIdUnderlyingCallsCount = newValue + } + } + } + } + open var loginWithEmailEmailPasswordInitialDeviceNameDeviceIdCalled: Bool { + return loginWithEmailEmailPasswordInitialDeviceNameDeviceIdCallsCount > 0 + } + open var loginWithEmailEmailPasswordInitialDeviceNameDeviceIdReceivedArguments: (email: String, password: String, initialDeviceName: String?, deviceId: String?)? + open var loginWithEmailEmailPasswordInitialDeviceNameDeviceIdReceivedInvocations: [(email: String, password: String, initialDeviceName: String?, deviceId: String?)] = [] + open var loginWithEmailEmailPasswordInitialDeviceNameDeviceIdClosure: ((String, String, String?, String?) async throws -> Void)? + + open override func loginWithEmail(email: String, password: String, initialDeviceName: String?, deviceId: String?) async throws { + if let error = loginWithEmailEmailPasswordInitialDeviceNameDeviceIdThrowableError { + throw error + } + loginWithEmailEmailPasswordInitialDeviceNameDeviceIdCallsCount += 1 + loginWithEmailEmailPasswordInitialDeviceNameDeviceIdReceivedArguments = (email: email, password: password, initialDeviceName: initialDeviceName, deviceId: deviceId) + DispatchQueue.main.async { + self.loginWithEmailEmailPasswordInitialDeviceNameDeviceIdReceivedInvocations.append((email: email, password: password, initialDeviceName: initialDeviceName, deviceId: deviceId)) + } + try await loginWithEmailEmailPasswordInitialDeviceNameDeviceIdClosure?(email, password, initialDeviceName, deviceId) + } + //MARK: - loginWithOidcCallback open var loginWithOidcCallbackAuthorizationDataCallbackUrlThrowableError: Error? @@ -2829,6 +2940,71 @@ open class ClientSDKMock: MatrixRustSDK.Client { try await setPusherIdentifiersKindAppDisplayNameDeviceDisplayNameProfileTagLangClosure?(identifiers, kind, appDisplayName, deviceDisplayName, profileTag, lang) } + //MARK: - slidingSyncVersion + + var slidingSyncVersionUnderlyingCallsCount = 0 + open var slidingSyncVersionCallsCount: Int { + get { + if Thread.isMainThread { + return slidingSyncVersionUnderlyingCallsCount + } else { + var returnValue: Int? = nil + DispatchQueue.main.sync { + returnValue = slidingSyncVersionUnderlyingCallsCount + } + + return returnValue! + } + } + set { + if Thread.isMainThread { + slidingSyncVersionUnderlyingCallsCount = newValue + } else { + DispatchQueue.main.sync { + slidingSyncVersionUnderlyingCallsCount = newValue + } + } + } + } + open var slidingSyncVersionCalled: Bool { + return slidingSyncVersionCallsCount > 0 + } + + var slidingSyncVersionUnderlyingReturnValue: SlidingSyncVersion! + open var slidingSyncVersionReturnValue: SlidingSyncVersion! { + get { + if Thread.isMainThread { + return slidingSyncVersionUnderlyingReturnValue + } else { + var returnValue: SlidingSyncVersion? = nil + DispatchQueue.main.sync { + returnValue = slidingSyncVersionUnderlyingReturnValue + } + + return returnValue! + } + } + set { + if Thread.isMainThread { + slidingSyncVersionUnderlyingReturnValue = newValue + } else { + DispatchQueue.main.sync { + slidingSyncVersionUnderlyingReturnValue = newValue + } + } + } + } + open var slidingSyncVersionClosure: (() -> SlidingSyncVersion)? + + open override func slidingSyncVersion() -> SlidingSyncVersion { + slidingSyncVersionCallsCount += 1 + if let slidingSyncVersionClosure = slidingSyncVersionClosure { + return slidingSyncVersionClosure() + } else { + return slidingSyncVersionReturnValue + } + } + //MARK: - startSsoLogin open var startSsoLoginRedirectUrlIdpIdThrowableError: Error? @@ -4526,71 +4702,6 @@ open class ClientBuilderSDKMock: MatrixRustSDK.ClientBuilder { } } - //MARK: - requiresSlidingSync - - var requiresSlidingSyncUnderlyingCallsCount = 0 - open var requiresSlidingSyncCallsCount: Int { - get { - if Thread.isMainThread { - return requiresSlidingSyncUnderlyingCallsCount - } else { - var returnValue: Int? = nil - DispatchQueue.main.sync { - returnValue = requiresSlidingSyncUnderlyingCallsCount - } - - return returnValue! - } - } - set { - if Thread.isMainThread { - requiresSlidingSyncUnderlyingCallsCount = newValue - } else { - DispatchQueue.main.sync { - requiresSlidingSyncUnderlyingCallsCount = newValue - } - } - } - } - open var requiresSlidingSyncCalled: Bool { - return requiresSlidingSyncCallsCount > 0 - } - - var requiresSlidingSyncUnderlyingReturnValue: ClientBuilder! - open var requiresSlidingSyncReturnValue: ClientBuilder! { - get { - if Thread.isMainThread { - return requiresSlidingSyncUnderlyingReturnValue - } else { - var returnValue: ClientBuilder? = nil - DispatchQueue.main.sync { - returnValue = requiresSlidingSyncUnderlyingReturnValue - } - - return returnValue! - } - } - set { - if Thread.isMainThread { - requiresSlidingSyncUnderlyingReturnValue = newValue - } else { - DispatchQueue.main.sync { - requiresSlidingSyncUnderlyingReturnValue = newValue - } - } - } - } - open var requiresSlidingSyncClosure: (() -> ClientBuilder)? - - open override func requiresSlidingSync() -> ClientBuilder { - requiresSlidingSyncCallsCount += 1 - if let requiresSlidingSyncClosure = requiresSlidingSyncClosure { - return requiresSlidingSyncClosure() - } else { - return requiresSlidingSyncReturnValue - } - } - //MARK: - roomKeyRecipientStrategy var roomKeyRecipientStrategyStrategyUnderlyingCallsCount = 0 @@ -4833,8 +4944,8 @@ open class ClientBuilderSDKMock: MatrixRustSDK.ClientBuilder { open var sessionPathsDataPathCachePathCalled: Bool { return sessionPathsDataPathCachePathCallsCount > 0 } - open var sessionPathsDataPathCachePathReceivedArguments: (dataPath: String, cachePath: String?)? - open var sessionPathsDataPathCachePathReceivedInvocations: [(dataPath: String, cachePath: String?)] = [] + open var sessionPathsDataPathCachePathReceivedArguments: (dataPath: String, cachePath: String)? + open var sessionPathsDataPathCachePathReceivedInvocations: [(dataPath: String, cachePath: String)] = [] var sessionPathsDataPathCachePathUnderlyingReturnValue: ClientBuilder! open var sessionPathsDataPathCachePathReturnValue: ClientBuilder! { @@ -4860,9 +4971,9 @@ open class ClientBuilderSDKMock: MatrixRustSDK.ClientBuilder { } } } - open var sessionPathsDataPathCachePathClosure: ((String, String?) -> ClientBuilder)? + open var sessionPathsDataPathCachePathClosure: ((String, String) -> ClientBuilder)? - open override func sessionPaths(dataPath: String, cachePath: String?) -> ClientBuilder { + open override func sessionPaths(dataPath: String, cachePath: String) -> ClientBuilder { sessionPathsDataPathCachePathCallsCount += 1 sessionPathsDataPathCachePathReceivedArguments = (dataPath: dataPath, cachePath: cachePath) DispatchQueue.main.async { @@ -4946,88 +5057,17 @@ open class ClientBuilderSDKMock: MatrixRustSDK.ClientBuilder { } } - //MARK: - simplifiedSlidingSync - - var simplifiedSlidingSyncEnableUnderlyingCallsCount = 0 - open var simplifiedSlidingSyncEnableCallsCount: Int { - get { - if Thread.isMainThread { - return simplifiedSlidingSyncEnableUnderlyingCallsCount - } else { - var returnValue: Int? = nil - DispatchQueue.main.sync { - returnValue = simplifiedSlidingSyncEnableUnderlyingCallsCount - } - - return returnValue! - } - } - set { - if Thread.isMainThread { - simplifiedSlidingSyncEnableUnderlyingCallsCount = newValue - } else { - DispatchQueue.main.sync { - simplifiedSlidingSyncEnableUnderlyingCallsCount = newValue - } - } - } - } - open var simplifiedSlidingSyncEnableCalled: Bool { - return simplifiedSlidingSyncEnableCallsCount > 0 - } - open var simplifiedSlidingSyncEnableReceivedEnable: Bool? - open var simplifiedSlidingSyncEnableReceivedInvocations: [Bool] = [] - - var simplifiedSlidingSyncEnableUnderlyingReturnValue: ClientBuilder! - open var simplifiedSlidingSyncEnableReturnValue: ClientBuilder! { - get { - if Thread.isMainThread { - return simplifiedSlidingSyncEnableUnderlyingReturnValue - } else { - var returnValue: ClientBuilder? = nil - DispatchQueue.main.sync { - returnValue = simplifiedSlidingSyncEnableUnderlyingReturnValue - } - - return returnValue! - } - } - set { - if Thread.isMainThread { - simplifiedSlidingSyncEnableUnderlyingReturnValue = newValue - } else { - DispatchQueue.main.sync { - simplifiedSlidingSyncEnableUnderlyingReturnValue = newValue - } - } - } - } - open var simplifiedSlidingSyncEnableClosure: ((Bool) -> ClientBuilder)? - - open override func simplifiedSlidingSync(enable: Bool) -> ClientBuilder { - simplifiedSlidingSyncEnableCallsCount += 1 - simplifiedSlidingSyncEnableReceivedEnable = enable - DispatchQueue.main.async { - self.simplifiedSlidingSyncEnableReceivedInvocations.append(enable) - } - if let simplifiedSlidingSyncEnableClosure = simplifiedSlidingSyncEnableClosure { - return simplifiedSlidingSyncEnableClosure(enable) - } else { - return simplifiedSlidingSyncEnableReturnValue - } - } + //MARK: - slidingSyncVersionBuilder - //MARK: - slidingSyncProxy - - var slidingSyncProxySlidingSyncProxyUnderlyingCallsCount = 0 - open var slidingSyncProxySlidingSyncProxyCallsCount: Int { + var slidingSyncVersionBuilderVersionBuilderUnderlyingCallsCount = 0 + open var slidingSyncVersionBuilderVersionBuilderCallsCount: Int { get { if Thread.isMainThread { - return slidingSyncProxySlidingSyncProxyUnderlyingCallsCount + return slidingSyncVersionBuilderVersionBuilderUnderlyingCallsCount } else { var returnValue: Int? = nil DispatchQueue.main.sync { - returnValue = slidingSyncProxySlidingSyncProxyUnderlyingCallsCount + returnValue = slidingSyncVersionBuilderVersionBuilderUnderlyingCallsCount } return returnValue! @@ -5035,29 +5075,29 @@ open class ClientBuilderSDKMock: MatrixRustSDK.ClientBuilder { } set { if Thread.isMainThread { - slidingSyncProxySlidingSyncProxyUnderlyingCallsCount = newValue + slidingSyncVersionBuilderVersionBuilderUnderlyingCallsCount = newValue } else { DispatchQueue.main.sync { - slidingSyncProxySlidingSyncProxyUnderlyingCallsCount = newValue + slidingSyncVersionBuilderVersionBuilderUnderlyingCallsCount = newValue } } } } - open var slidingSyncProxySlidingSyncProxyCalled: Bool { - return slidingSyncProxySlidingSyncProxyCallsCount > 0 + open var slidingSyncVersionBuilderVersionBuilderCalled: Bool { + return slidingSyncVersionBuilderVersionBuilderCallsCount > 0 } - open var slidingSyncProxySlidingSyncProxyReceivedSlidingSyncProxy: String? - open var slidingSyncProxySlidingSyncProxyReceivedInvocations: [String?] = [] + open var slidingSyncVersionBuilderVersionBuilderReceivedVersionBuilder: SlidingSyncVersionBuilder? + open var slidingSyncVersionBuilderVersionBuilderReceivedInvocations: [SlidingSyncVersionBuilder] = [] - var slidingSyncProxySlidingSyncProxyUnderlyingReturnValue: ClientBuilder! - open var slidingSyncProxySlidingSyncProxyReturnValue: ClientBuilder! { + var slidingSyncVersionBuilderVersionBuilderUnderlyingReturnValue: ClientBuilder! + open var slidingSyncVersionBuilderVersionBuilderReturnValue: ClientBuilder! { get { if Thread.isMainThread { - return slidingSyncProxySlidingSyncProxyUnderlyingReturnValue + return slidingSyncVersionBuilderVersionBuilderUnderlyingReturnValue } else { var returnValue: ClientBuilder? = nil DispatchQueue.main.sync { - returnValue = slidingSyncProxySlidingSyncProxyUnderlyingReturnValue + returnValue = slidingSyncVersionBuilderVersionBuilderUnderlyingReturnValue } return returnValue! @@ -5065,26 +5105,26 @@ open class ClientBuilderSDKMock: MatrixRustSDK.ClientBuilder { } set { if Thread.isMainThread { - slidingSyncProxySlidingSyncProxyUnderlyingReturnValue = newValue + slidingSyncVersionBuilderVersionBuilderUnderlyingReturnValue = newValue } else { DispatchQueue.main.sync { - slidingSyncProxySlidingSyncProxyUnderlyingReturnValue = newValue + slidingSyncVersionBuilderVersionBuilderUnderlyingReturnValue = newValue } } } } - open var slidingSyncProxySlidingSyncProxyClosure: ((String?) -> ClientBuilder)? + open var slidingSyncVersionBuilderVersionBuilderClosure: ((SlidingSyncVersionBuilder) -> ClientBuilder)? - open override func slidingSyncProxy(slidingSyncProxy: String?) -> ClientBuilder { - slidingSyncProxySlidingSyncProxyCallsCount += 1 - slidingSyncProxySlidingSyncProxyReceivedSlidingSyncProxy = slidingSyncProxy + open override func slidingSyncVersionBuilder(versionBuilder: SlidingSyncVersionBuilder) -> ClientBuilder { + slidingSyncVersionBuilderVersionBuilderCallsCount += 1 + slidingSyncVersionBuilderVersionBuilderReceivedVersionBuilder = versionBuilder DispatchQueue.main.async { - self.slidingSyncProxySlidingSyncProxyReceivedInvocations.append(slidingSyncProxy) + self.slidingSyncVersionBuilderVersionBuilderReceivedInvocations.append(versionBuilder) } - if let slidingSyncProxySlidingSyncProxyClosure = slidingSyncProxySlidingSyncProxyClosure { - return slidingSyncProxySlidingSyncProxyClosure(slidingSyncProxy) + if let slidingSyncVersionBuilderVersionBuilderClosure = slidingSyncVersionBuilderVersionBuilderClosure { + return slidingSyncVersionBuilderVersionBuilderClosure(versionBuilder) } else { - return slidingSyncProxySlidingSyncProxyReturnValue + return slidingSyncVersionBuilderVersionBuilderReturnValue } } @@ -7546,17 +7586,17 @@ open class HomeserverLoginDetailsSDKMock: MatrixRustSDK.HomeserverLoginDetails { fileprivate var pointer: UnsafeMutableRawPointer! - //MARK: - slidingSyncProxy + //MARK: - slidingSyncVersion - var slidingSyncProxyUnderlyingCallsCount = 0 - open var slidingSyncProxyCallsCount: Int { + var slidingSyncVersionUnderlyingCallsCount = 0 + open var slidingSyncVersionCallsCount: Int { get { if Thread.isMainThread { - return slidingSyncProxyUnderlyingCallsCount + return slidingSyncVersionUnderlyingCallsCount } else { var returnValue: Int? = nil DispatchQueue.main.sync { - returnValue = slidingSyncProxyUnderlyingCallsCount + returnValue = slidingSyncVersionUnderlyingCallsCount } return returnValue! @@ -7564,27 +7604,27 @@ open class HomeserverLoginDetailsSDKMock: MatrixRustSDK.HomeserverLoginDetails { } set { if Thread.isMainThread { - slidingSyncProxyUnderlyingCallsCount = newValue + slidingSyncVersionUnderlyingCallsCount = newValue } else { DispatchQueue.main.sync { - slidingSyncProxyUnderlyingCallsCount = newValue + slidingSyncVersionUnderlyingCallsCount = newValue } } } } - open var slidingSyncProxyCalled: Bool { - return slidingSyncProxyCallsCount > 0 + open var slidingSyncVersionCalled: Bool { + return slidingSyncVersionCallsCount > 0 } - var slidingSyncProxyUnderlyingReturnValue: String? - open var slidingSyncProxyReturnValue: String? { + var slidingSyncVersionUnderlyingReturnValue: SlidingSyncVersion! + open var slidingSyncVersionReturnValue: SlidingSyncVersion! { get { if Thread.isMainThread { - return slidingSyncProxyUnderlyingReturnValue + return slidingSyncVersionUnderlyingReturnValue } else { - var returnValue: String?? = nil + var returnValue: SlidingSyncVersion? = nil DispatchQueue.main.sync { - returnValue = slidingSyncProxyUnderlyingReturnValue + returnValue = slidingSyncVersionUnderlyingReturnValue } return returnValue! @@ -7592,22 +7632,22 @@ open class HomeserverLoginDetailsSDKMock: MatrixRustSDK.HomeserverLoginDetails { } set { if Thread.isMainThread { - slidingSyncProxyUnderlyingReturnValue = newValue + slidingSyncVersionUnderlyingReturnValue = newValue } else { DispatchQueue.main.sync { - slidingSyncProxyUnderlyingReturnValue = newValue + slidingSyncVersionUnderlyingReturnValue = newValue } } } } - open var slidingSyncProxyClosure: (() -> String?)? + open var slidingSyncVersionClosure: (() -> SlidingSyncVersion)? - open override func slidingSyncProxy() -> String? { - slidingSyncProxyCallsCount += 1 - if let slidingSyncProxyClosure = slidingSyncProxyClosure { - return slidingSyncProxyClosure() + open override func slidingSyncVersion() -> SlidingSyncVersion { + slidingSyncVersionCallsCount += 1 + if let slidingSyncVersionClosure = slidingSyncVersionClosure { + return slidingSyncVersionClosure() } else { - return slidingSyncProxyReturnValue + return slidingSyncVersionReturnValue } } @@ -20676,6 +20716,71 @@ open class TimelineDiffSDKMock: MatrixRustSDK.TimelineDiff { return setReturnValue } } + + //MARK: - truncate + + var truncateUnderlyingCallsCount = 0 + open var truncateCallsCount: Int { + get { + if Thread.isMainThread { + return truncateUnderlyingCallsCount + } else { + var returnValue: Int? = nil + DispatchQueue.main.sync { + returnValue = truncateUnderlyingCallsCount + } + + return returnValue! + } + } + set { + if Thread.isMainThread { + truncateUnderlyingCallsCount = newValue + } else { + DispatchQueue.main.sync { + truncateUnderlyingCallsCount = newValue + } + } + } + } + open var truncateCalled: Bool { + return truncateCallsCount > 0 + } + + var truncateUnderlyingReturnValue: UInt32? + open var truncateReturnValue: UInt32? { + get { + if Thread.isMainThread { + return truncateUnderlyingReturnValue + } else { + var returnValue: UInt32?? = nil + DispatchQueue.main.sync { + returnValue = truncateUnderlyingReturnValue + } + + return returnValue! + } + } + set { + if Thread.isMainThread { + truncateUnderlyingReturnValue = newValue + } else { + DispatchQueue.main.sync { + truncateUnderlyingReturnValue = newValue + } + } + } + } + open var truncateClosure: (() -> UInt32?)? + + open override func truncate() -> UInt32? { + truncateCallsCount += 1 + if let truncateClosure = truncateClosure { + return truncateClosure() + } else { + return truncateReturnValue + } + } } open class TimelineEventSDKMock: MatrixRustSDK.TimelineEvent { init() { diff --git a/ElementX/Sources/Services/Client/ClientProxy.swift b/ElementX/Sources/Services/Client/ClientProxy.swift index c5c946f1f0..819059b94f 100644 --- a/ElementX/Sources/Services/Client/ClientProxy.swift +++ b/ElementX/Sources/Services/Client/ClientProxy.swift @@ -210,6 +210,16 @@ class ClientProxy: ClientProxyProtocol { client.homeserver() } + var slidingSyncVersion: SlidingSyncVersion { + client.slidingSyncVersion() + } + + var availableSlidingSyncVersions: [SlidingSyncVersion] { + get async { + await client.availableSlidingSyncVersions() + } + } + var userIDServerName: String? { do { return try client.userIdServerName() diff --git a/ElementX/Sources/Services/Client/ClientProxyProtocol.swift b/ElementX/Sources/Services/Client/ClientProxyProtocol.swift index e041e06d53..246149795b 100644 --- a/ElementX/Sources/Services/Client/ClientProxyProtocol.swift +++ b/ElementX/Sources/Services/Client/ClientProxyProtocol.swift @@ -104,8 +104,11 @@ protocol ClientProxyProtocol: AnyObject, MediaLoaderProtocol { var homeserver: String { get } + var slidingSyncVersion: SlidingSyncVersion { get } + var availableSlidingSyncVersions: [SlidingSyncVersion] { get async } + var userIDServerName: String? { get } - + var userDisplayNamePublisher: CurrentValuePublisher { get } var userAvatarURLPublisher: CurrentValuePublisher { get } diff --git a/ElementX/Sources/Services/UserSession/RestorationToken.swift b/ElementX/Sources/Services/UserSession/RestorationToken.swift index 96955feb38..c0d7b7dde4 100644 --- a/ElementX/Sources/Services/UserSession/RestorationToken.swift +++ b/ElementX/Sources/Services/UserSession/RestorationToken.swift @@ -54,14 +54,14 @@ extension RestorationToken: Codable { extension MatrixRustSDK.Session: Codable { public init(from decoder: Decoder) throws { let container = try decoder.container(keyedBy: CodingKeys.self) + let slidingSyncVersion: SlidingSyncVersion = try container.decodeIfPresent(String.self, forKey: .slidingSyncProxy).map { .proxy(url: $0) } ?? .native self = try .init(accessToken: container.decode(String.self, forKey: .accessToken), refreshToken: container.decodeIfPresent(String.self, forKey: .refreshToken), userId: container.decode(String.self, forKey: .userId), deviceId: container.decode(String.self, forKey: .deviceId), homeserverUrl: container.decode(String.self, forKey: .homeserverUrl), oidcData: container.decodeIfPresent(String.self, forKey: .oidcData), - // Note: the proxy is optional now that we support Simplified Sliding Sync. - slidingSyncProxy: container.decodeIfPresent(String.self, forKey: .slidingSyncProxy)) + slidingSyncVersion: slidingSyncVersion) } public func encode(to encoder: Encoder) throws { @@ -72,10 +72,17 @@ extension MatrixRustSDK.Session: Codable { try container.encode(deviceId, forKey: .deviceId) try container.encode(homeserverUrl, forKey: .homeserverUrl) try container.encode(oidcData, forKey: .oidcData) - try container.encode(slidingSyncProxy, forKey: .slidingSyncProxy) + try container.encode(slidingSyncVersion.proxyURL, forKey: .slidingSyncProxy) } enum CodingKeys: String, CodingKey { case accessToken, refreshToken, userId, deviceId, homeserverUrl, oidcData, slidingSyncProxy } } + +private extension SlidingSyncVersion { + var proxyURL: String? { + guard case let .proxy(url) = self else { return nil } + return url + } +} diff --git a/ElementX/Sources/Services/UserSession/UserSessionStore.swift b/ElementX/Sources/Services/UserSession/UserSessionStore.swift index 5dd5470a04..8014714e8f 100644 --- a/ElementX/Sources/Services/UserSession/UserSessionStore.swift +++ b/ElementX/Sources/Services/UserSession/UserSessionStore.swift @@ -131,7 +131,7 @@ class UserSessionStore: UserSessionStoreProtocol { let builder = ClientBuilder .baseBuilder(httpProxy: URL(string: homeserverURL)?.globalProxy, - slidingSync: appSettings.simplifiedSlidingSyncEnabled ? .simplified : .restored, + slidingSync: .restored, sessionDelegate: keychainController, appHooks: appHooks) .sessionPaths(dataPath: credentials.restorationToken.sessionDirectory.path(percentEncoded: false), diff --git a/NSE/Sources/NotificationServiceExtension.swift b/NSE/Sources/NotificationServiceExtension.swift index a2f24a354e..88b8c41a2f 100644 --- a/NSE/Sources/NotificationServiceExtension.swift +++ b/NSE/Sources/NotificationServiceExtension.swift @@ -88,7 +88,6 @@ class NotificationServiceExtension: UNNotificationServiceExtension { do { Self.userSession = try await NSEUserSession(credentials: credentials, clientSessionDelegate: keychainController, - simplifiedSlidingSyncEnabled: settings.simplifiedSlidingSyncEnabled, appHooks: appHooks) } catch { MXLog.error("Failed creating user session with error: \(error)") diff --git a/NSE/Sources/Other/NSESettingsProtocol.swift b/NSE/Sources/Other/NSESettingsProtocol.swift index c693acc3ba..943b1fe5a0 100644 --- a/NSE/Sources/Other/NSESettingsProtocol.swift +++ b/NSE/Sources/Other/NSESettingsProtocol.swift @@ -18,7 +18,6 @@ import Foundation protocol NSESettingsProtocol { var logLevel: TracingConfiguration.LogLevel { get } - var simplifiedSlidingSyncEnabled: Bool { get } } extension AppSettings: NSESettingsProtocol { } diff --git a/NSE/Sources/Other/NSEUserSession.swift b/NSE/Sources/Other/NSEUserSession.swift index 736713532b..62eda341a7 100644 --- a/NSE/Sources/Other/NSEUserSession.swift +++ b/NSE/Sources/Other/NSEUserSession.swift @@ -26,7 +26,7 @@ final class NSEUserSession { networkMonitor: nil) private let delegateHandle: TaskHandle? - init(credentials: KeychainCredentials, clientSessionDelegate: ClientSessionDelegate, simplifiedSlidingSyncEnabled: Bool, appHooks: AppHooks) async throws { + init(credentials: KeychainCredentials, clientSessionDelegate: ClientSessionDelegate, appHooks: AppHooks) async throws { userID = credentials.userID if credentials.restorationToken.passphrase != nil { MXLog.info("Restoring client with encrypted store.") @@ -36,7 +36,7 @@ final class NSEUserSession { let clientBuilder = ClientBuilder .baseBuilder(setupEncryption: false, httpProxy: URL(string: homeserverURL)?.globalProxy, - slidingSync: simplifiedSlidingSyncEnabled ? .simplified : .restored, + slidingSync: .restored, sessionDelegate: clientSessionDelegate, appHooks: appHooks) .sessionPaths(dataPath: credentials.restorationToken.sessionDirectory.path(percentEncoded: false), diff --git a/UnitTests/Sources/KeychainControllerTests.swift b/UnitTests/Sources/KeychainControllerTests.swift index b65cf436a9..975114cf72 100644 --- a/UnitTests/Sources/KeychainControllerTests.swift +++ b/UnitTests/Sources/KeychainControllerTests.swift @@ -39,7 +39,7 @@ class KeychainControllerTests: XCTestCase { deviceId: "deviceId", homeserverUrl: "homeserverUrl", oidcData: "oidcData", - slidingSyncProxy: "https://my.sync.proxy"), + slidingSyncVersion: .proxy(url: "https://my.sync.proxy")), sessionDirectory: .homeDirectory.appending(component: UUID().uuidString), cacheDirectory: .homeDirectory.appending(component: UUID().uuidString), passphrase: "passphrase", @@ -59,7 +59,7 @@ class KeychainControllerTests: XCTestCase { deviceId: "deviceId", homeserverUrl: "homeserverUrl", oidcData: "oidcData", - slidingSyncProxy: "https://my.sync.proxy"), + slidingSyncVersion: .proxy(url: "https://my.sync.proxy")), sessionDirectory: .homeDirectory.appending(component: UUID().uuidString), cacheDirectory: .homeDirectory.appending(component: UUID().uuidString), passphrase: "passphrase", @@ -85,7 +85,7 @@ class KeychainControllerTests: XCTestCase { deviceId: "deviceId", homeserverUrl: "homeserverUrl", oidcData: "oidcData", - slidingSyncProxy: "https://my.sync.proxy"), + slidingSyncVersion: .proxy(url: "https://my.sync.proxy")), sessionDirectory: .homeDirectory.appending(component: UUID().uuidString), cacheDirectory: .homeDirectory.appending(component: UUID().uuidString), passphrase: "passphrase", @@ -110,7 +110,7 @@ class KeychainControllerTests: XCTestCase { deviceId: "deviceId", homeserverUrl: "homeserverUrl", oidcData: "oidcData", - slidingSyncProxy: "https://my.sync.proxy"), + slidingSyncVersion: .proxy(url: "https://my.sync.proxy")), sessionDirectory: .homeDirectory.appending(component: UUID().uuidString), cacheDirectory: .homeDirectory.appending(component: UUID().uuidString), passphrase: "passphrase", @@ -143,7 +143,7 @@ class KeychainControllerTests: XCTestCase { deviceId: "deviceId", homeserverUrl: "homeserverUrl", oidcData: "oidcData", - slidingSyncProxy: nil), + slidingSyncVersion: .native), sessionDirectory: .homeDirectory.appending(component: UUID().uuidString), cacheDirectory: .homeDirectory.appending(component: UUID().uuidString), passphrase: "passphrase", diff --git a/UnitTests/Sources/RestorationTokenTests.swift b/UnitTests/Sources/RestorationTokenTests.swift index f6936f73d5..6f982ebfb4 100644 --- a/UnitTests/Sources/RestorationTokenTests.swift +++ b/UnitTests/Sources/RestorationTokenTests.swift @@ -28,7 +28,7 @@ class RestorationTokenTests: XCTestCase { deviceId: "D3V1C3", homeserverUrl: "https://matrix.example.com", oidcData: nil, - slidingSyncProxy: "https://sync.example.com")) + slidingSyncVersion: .proxy(url: "https://sync.example.com"))) let data = try JSONEncoder().encode(originalToken) // When decoding the data to the current restoration token format. @@ -53,7 +53,7 @@ class RestorationTokenTests: XCTestCase { deviceId: "D3V1C3", homeserverUrl: "https://matrix.example.com", oidcData: "data-from-mas", - slidingSyncProxy: "https://sync.example.com"), + slidingSyncVersion: .proxy(url: "https://sync.example.com")), sessionDirectory: .sessionsBaseDirectory.appending(component: sessionDirectoryName), passphrase: "passphrase", pusherNotificationClientIdentifier: "pusher-identifier") @@ -81,7 +81,7 @@ class RestorationTokenTests: XCTestCase { deviceId: "D3V1C3", homeserverUrl: "https://matrix.example.com", oidcData: "data-from-mas", - slidingSyncProxy: nil), + slidingSyncVersion: .native), sessionDirectory: .sessionsBaseDirectory.appending(component: sessionDirectoryName), cacheDirectory: .cachesBaseDirectory.appending(component: sessionDirectoryName), passphrase: "passphrase", From a11adfc0c49da33104f042f302de07155d35efc8 Mon Sep 17 00:00:00 2001 From: Doug Date: Thu, 29 Aug 2024 12:23:08 +0100 Subject: [PATCH 2/5] Adopt sliding sync discovery for authentication. --- ElementX.xcodeproj/project.pbxproj | 4 + .../Sources/Application/AppSettings.swift | 15 ++-- .../SettingsFlowCoordinator.swift | 4 +- .../Other/Extensions/ClientBuilder.swift | 15 ++-- .../DeveloperOptionsScreenCoordinator.swift | 9 +- .../DeveloperOptionsScreenModels.swift | 9 +- .../DeveloperOptionsScreenViewModel.swift | 14 +-- .../View/DeveloperOptionsScreen.swift | 16 ++-- .../AuthenticationClientBuilder.swift | 88 +++++++++++++++++++ .../AuthenticationService.swift | 24 +++-- .../Services/QRCode/QRCodeLoginService.swift | 21 ++--- 11 files changed, 148 insertions(+), 71 deletions(-) create mode 100644 ElementX/Sources/Services/Authentication/AuthenticationClientBuilder.swift diff --git a/ElementX.xcodeproj/project.pbxproj b/ElementX.xcodeproj/project.pbxproj index e22b121631..47d5b6e063 100644 --- a/ElementX.xcodeproj/project.pbxproj +++ b/ElementX.xcodeproj/project.pbxproj @@ -615,6 +615,7 @@ 89B909AC66B96FA054EF3C14 /* InvitedRoomProxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E95B3BDB80531C85CD50AE6 /* InvitedRoomProxy.swift */; }; 8A0BD60CA4A6004DB06B5403 /* MediaUploadingPreprocessor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 669F35C505ACE1110589F875 /* MediaUploadingPreprocessor.swift */; }; 8A5064CAC8E5F3B18645621D /* CallNotificationRoomTimelineView.swift in Sources */ = {isa = PBXBuildFile; fileRef = AD6E082B0507FB28F966516A /* CallNotificationRoomTimelineView.swift */; }; + 8A6CB15C8FC68F557750BF54 /* AuthenticationClientBuilder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0F569CFB77E0D40BD82203D9 /* AuthenticationClientBuilder.swift */; }; 8A83D715940378B9BA9F739E /* RoomInviterLabel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7EB58E4E8D6D634C246AD5C2 /* RoomInviterLabel.swift */; }; 8AA84EF202F2EFC8453A97BD /* SecureBackupRecoveryKeyScreenModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = 645E027C112740573D27765C /* SecureBackupRecoveryKeyScreenModels.swift */; }; 8AB8ED1051216546CB35FA0E /* UserSession.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6E5E9C044BEB7C70B1378E91 /* UserSession.swift */; }; @@ -1248,6 +1249,7 @@ 0E95B3BDB80531C85CD50AE6 /* InvitedRoomProxy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InvitedRoomProxy.swift; sourceTree = ""; }; 0EE9EAF0309A2A1D67D8FAF5 /* sv */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = sv; path = sv.lproj/Localizable.stringsdict; sourceTree = ""; }; 0F5567A7EF6F2AB9473236F6 /* DocumentPicker.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DocumentPicker.swift; sourceTree = ""; }; + 0F569CFB77E0D40BD82203D9 /* AuthenticationClientBuilder.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AuthenticationClientBuilder.swift; sourceTree = ""; }; 0F64447FF544298A6A3BEF85 /* NotificationSettingsScreenModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationSettingsScreenModels.swift; sourceTree = ""; }; 0FA60F848D1C14F873F9621A /* RoomMemberDetailsScreenCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomMemberDetailsScreenCoordinator.swift; sourceTree = ""; }; 105429F29096729EDD3152CF /* ru */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ru; path = ru.lproj/SAS.strings; sourceTree = ""; }; @@ -4586,6 +4588,7 @@ AAFDD509929A0CCF8BCE51EB /* Authentication */ = { isa = PBXGroup; children = ( + 0F569CFB77E0D40BD82203D9 /* AuthenticationClientBuilder.swift */, F3A1AB5A84D843B6AC8D5F1E /* AuthenticationService.swift */, 5E75948AA1FE1D1A7809931F /* AuthenticationServiceProtocol.swift */, 65C2B80DD0BF6F10BB5FA922 /* MockAuthenticationServiceProxy.swift */, @@ -6181,6 +6184,7 @@ 88F348E2CB14FF71CBBB665D /* AudioRoomTimelineItemContent.swift in Sources */, 7BD2123144A32F082CECC108 /* AudioRoomTimelineView.swift in Sources */, 9278EC51D24E57445B290521 /* AudioSessionProtocol.swift in Sources */, + 8A6CB15C8FC68F557750BF54 /* AuthenticationClientBuilder.swift in Sources */, 67E9926C4572C54F59FCA91A /* AuthenticationFlowCoordinator.swift in Sources */, 9847B056C1A216C314D21E68 /* AuthenticationService.swift in Sources */, 56DACDD379A86A1F5DEFE7BE /* AuthenticationServiceProtocol.swift in Sources */, diff --git a/ElementX/Sources/Application/AppSettings.swift b/ElementX/Sources/Application/AppSettings.swift index 2ac15cdd76..1de3fd83ca 100644 --- a/ElementX/Sources/Application/AppSettings.swift +++ b/ElementX/Sources/Application/AppSettings.swift @@ -43,7 +43,7 @@ final class AppSettings { case elementCallEncryptionEnabled // Feature flags - case simplifiedSlidingSyncEnabled + case slidingSyncDiscovery case publicSearchEnabled case fuzzyRoomListSearchEnabled case pinningEnabled @@ -106,10 +106,6 @@ final class AppSettings { /// so that it can be passed to Rust as a ServerName for well-known discovery. private(set) var defaultHomeserverAddress = "matrix.org" - /// An override of the homeserver's Sliding Sync proxy URL. This allows development against servers - /// that don't yet have an officially trusted proxy configured in their well-known. - let slidingSyncProxyURL: URL? = nil - /// The task identifier used for background app refresh. Also used in main target's the Info.plist let backgroundAppRefreshTaskIdentifier = "io.element.elementx.background.refresh" @@ -284,6 +280,10 @@ final class AppSettings { @UserPreference(key: UserDefaultsKeys.pinningEnabled, defaultValue: false, storageType: .userDefaults(store)) var pinningEnabled + + enum SlidingSyncDiscovery: Codable { case proxy, native, forceNative } + @UserPreference(key: UserDefaultsKeys.slidingSyncDiscovery, defaultValue: .proxy, storageType: .userDefaults(store)) + var slidingSyncDiscovery: SlidingSyncDiscovery #endif @@ -291,9 +291,4 @@ final class AppSettings { @UserPreference(key: UserDefaultsKeys.logLevel, defaultValue: TracingConfiguration.LogLevel.info, storageType: .userDefaults(store)) var logLevel - - // MARK: Shared Feature Flags - - @UserPreference(key: UserDefaultsKeys.simplifiedSlidingSyncEnabled, defaultValue: false, storageType: .userDefaults(store)) - var simplifiedSlidingSyncEnabled } diff --git a/ElementX/Sources/FlowCoordinators/SettingsFlowCoordinator.swift b/ElementX/Sources/FlowCoordinators/SettingsFlowCoordinator.swift index 07489230e5..78c3b4b01b 100644 --- a/ElementX/Sources/FlowCoordinators/SettingsFlowCoordinator.swift +++ b/ElementX/Sources/FlowCoordinators/SettingsFlowCoordinator.swift @@ -232,7 +232,7 @@ class SettingsFlowCoordinator: FlowCoordinatorProtocol { } private func presentDeveloperOptions() { - let coordinator = DeveloperOptionsScreenCoordinator() + let coordinator = DeveloperOptionsScreenCoordinator(isUsingNativeSlidingSync: parameters.userSession.clientProxy.slidingSyncVersion == .native) coordinator.actions .sink { [weak self] action in @@ -241,8 +241,6 @@ class SettingsFlowCoordinator: FlowCoordinatorProtocol { switch action { case .clearCache: actionsSubject.send(.clearCache) - case .forceLogout: - actionsSubject.send(.forceLogout) } } .store(in: &cancellables) diff --git a/ElementX/Sources/Other/Extensions/ClientBuilder.swift b/ElementX/Sources/Other/Extensions/ClientBuilder.swift index b395f2f33e..665896c910 100644 --- a/ElementX/Sources/Other/Extensions/ClientBuilder.swift +++ b/ElementX/Sources/Other/Extensions/ClientBuilder.swift @@ -22,19 +22,18 @@ extension ClientBuilder { static func baseBuilder(setupEncryption: Bool = true, httpProxy: String? = nil, slidingSync: ClientBuilderSlidingSync, - slidingSyncProxy: URL? = nil, sessionDelegate: ClientSessionDelegate, appHooks: AppHooks) -> ClientBuilder { var builder = ClientBuilder() - .slidingSyncProxy(slidingSyncProxy: slidingSyncProxy?.absoluteString) .enableCrossProcessRefreshLock(processId: InfoPlistReader.main.bundleIdentifier, sessionDelegate: sessionDelegate) .userAgent(userAgent: UserAgentBuilder.makeASCIIUserAgent()) .requestConfig(config: .init(retryLimit: 0, timeout: 30000, maxConcurrentRequests: nil, retryTimeout: nil)) builder = switch slidingSync { case .restored: builder - case .discovered: builder.requiresSlidingSync() - case .simplified: builder.simplifiedSlidingSync(enable: true) + case .discoverProxy: builder.slidingSyncVersionBuilder(versionBuilder: .discoverProxy) + case .discoverNative: builder.slidingSyncVersionBuilder(versionBuilder: .discoverNative) + case .forceNative: builder.slidingSyncVersionBuilder(versionBuilder: .native) } if setupEncryption { @@ -56,7 +55,9 @@ enum ClientBuilderSlidingSync { /// The proxy will be supplied when restoring the Session. case restored /// A proxy must be discovered whilst building the session. - case discovered - /// Use Simplified Sliding Sync (discovery isn't a thing yet). - case simplified + case discoverProxy + /// Native sliding sync must be discovered whilst building the session. + case discoverNative + /// Forces native sliding sync without discovering it. + case forceNative } diff --git a/ElementX/Sources/Screens/Settings/DeveloperOptionsScreen/DeveloperOptionsScreenCoordinator.swift b/ElementX/Sources/Screens/Settings/DeveloperOptionsScreen/DeveloperOptionsScreenCoordinator.swift index 57df849963..cb97cd7ae0 100644 --- a/ElementX/Sources/Screens/Settings/DeveloperOptionsScreen/DeveloperOptionsScreenCoordinator.swift +++ b/ElementX/Sources/Screens/Settings/DeveloperOptionsScreen/DeveloperOptionsScreenCoordinator.swift @@ -19,8 +19,6 @@ import SwiftUI enum DeveloperOptionsScreenCoordinatorAction { case clearCache - /// Logout without a confirmation to avoid losing keys when trying SSS. - case forceLogout } final class DeveloperOptionsScreenCoordinator: CoordinatorProtocol { @@ -33,9 +31,10 @@ final class DeveloperOptionsScreenCoordinator: CoordinatorProtocol { actionsSubject.eraseToAnyPublisher() } - init() { + init(isUsingNativeSlidingSync: Bool) { viewModel = DeveloperOptionsScreenViewModel(developerOptions: ServiceLocator.shared.settings, - elementCallBaseURL: ServiceLocator.shared.settings.elementCallBaseURL) + elementCallBaseURL: ServiceLocator.shared.settings.elementCallBaseURL, + isUsingNativeSlidingSync: isUsingNativeSlidingSync) viewModel.actions .sink { [weak self] action in @@ -44,8 +43,6 @@ final class DeveloperOptionsScreenCoordinator: CoordinatorProtocol { switch action { case .clearCache: actionsSubject.send(.clearCache) - case .forceLogout: - actionsSubject.send(.forceLogout) } } .store(in: &cancellables) diff --git a/ElementX/Sources/Screens/Settings/DeveloperOptionsScreen/DeveloperOptionsScreenModels.swift b/ElementX/Sources/Screens/Settings/DeveloperOptionsScreen/DeveloperOptionsScreenModels.swift index ba618ad297..2a04944c20 100644 --- a/ElementX/Sources/Screens/Settings/DeveloperOptionsScreen/DeveloperOptionsScreenModels.swift +++ b/ElementX/Sources/Screens/Settings/DeveloperOptionsScreen/DeveloperOptionsScreenModels.swift @@ -18,13 +18,16 @@ import Foundation enum DeveloperOptionsScreenViewModelAction { case clearCache - /// Logout without a confirmation to avoid losing keys when trying SSS. - case forceLogout } struct DeveloperOptionsScreenViewState: BindableState { let elementCallBaseURL: URL + let isUsingNativeSlidingSync: Bool var bindings: DeveloperOptionsScreenViewStateBindings + + var slidingSyncFooter: String { + "The method used to configure sliding sync when signing in. Changing this setting has no effect until you sign out.\n\nYour current session is using \(isUsingNativeSlidingSync ? "native sliding sync." : "a sliding sync proxy.")" + } } // periphery: ignore - subscripts are seen as false positive @@ -48,7 +51,7 @@ enum DeveloperOptionsScreenViewAction { protocol DeveloperOptionsProtocol: AnyObject { var logLevel: TracingConfiguration.LogLevel { get set } - var simplifiedSlidingSyncEnabled: Bool { get set } + var slidingSyncDiscovery: AppSettings.SlidingSyncDiscovery { get set } var hideUnreadMessagesBadge: Bool { get set } var elementCallBaseURLOverride: URL? { get set } var fuzzyRoomListSearchEnabled: Bool { get set } diff --git a/ElementX/Sources/Screens/Settings/DeveloperOptionsScreen/DeveloperOptionsScreenViewModel.swift b/ElementX/Sources/Screens/Settings/DeveloperOptionsScreen/DeveloperOptionsScreenViewModel.swift index e6450adc3c..fb62f2af1d 100644 --- a/ElementX/Sources/Screens/Settings/DeveloperOptionsScreen/DeveloperOptionsScreenViewModel.swift +++ b/ElementX/Sources/Screens/Settings/DeveloperOptionsScreen/DeveloperOptionsScreenViewModel.swift @@ -26,21 +26,11 @@ class DeveloperOptionsScreenViewModel: DeveloperOptionsScreenViewModelType, Deve actionsSubject.eraseToAnyPublisher() } - init(developerOptions: DeveloperOptionsProtocol, elementCallBaseURL: URL) { + init(developerOptions: DeveloperOptionsProtocol, elementCallBaseURL: URL, isUsingNativeSlidingSync: Bool) { let bindings = DeveloperOptionsScreenViewStateBindings(developerOptions: developerOptions) - let state = DeveloperOptionsScreenViewState(elementCallBaseURL: elementCallBaseURL, bindings: bindings) + let state = DeveloperOptionsScreenViewState(elementCallBaseURL: elementCallBaseURL, isUsingNativeSlidingSync: isUsingNativeSlidingSync, bindings: bindings) super.init(initialViewState: state) - - context.$viewState - .map(\.bindings.simplifiedSlidingSyncEnabled) - .removeDuplicates() - .dropFirst() // Ignore the initial value received when opening the screen. - .sink { [weak self] isEnabled in - MXLog.error("Toggled simplifiedSlidingSyncEnabled: \(isEnabled). Signing out.") - self?.actionsSubject.send(.forceLogout) - } - .store(in: &cancellables) } override func process(viewAction: DeveloperOptionsScreenViewAction) { diff --git a/ElementX/Sources/Screens/Settings/DeveloperOptionsScreen/View/DeveloperOptionsScreen.swift b/ElementX/Sources/Screens/Settings/DeveloperOptionsScreen/View/DeveloperOptionsScreen.swift index 3f3ed9eb16..e1c1ee4965 100644 --- a/ElementX/Sources/Screens/Settings/DeveloperOptionsScreen/View/DeveloperOptionsScreen.swift +++ b/ElementX/Sources/Screens/Settings/DeveloperOptionsScreen/View/DeveloperOptionsScreen.swift @@ -32,11 +32,16 @@ struct DeveloperOptionsScreen: View { LogLevelConfigurationView(logLevel: $context.logLevel) } - Section("Sliding Sync") { - Toggle(isOn: $context.simplifiedSlidingSyncEnabled) { - Text("Simplified Sliding Sync") - Text("When toggled you'll be logged out of the app and will need to log in again.") + Section { + Picker("Discovery", selection: $context.slidingSyncDiscovery) { + Text("Proxy only").tag(AppSettings.SlidingSyncDiscovery.proxy) + Text("Automatic").tag(AppSettings.SlidingSyncDiscovery.native) + Text("Force Native ⚠️").tag(AppSettings.SlidingSyncDiscovery.forceNative) } + } header: { + Text("Sliding Sync") + } footer: { + Text(context.viewState.slidingSyncFooter) } Section("Message Pinning") { @@ -174,7 +179,8 @@ private struct LogLevelConfigurationView: View { struct DeveloperOptionsScreen_Previews: PreviewProvider { static let viewModel = DeveloperOptionsScreenViewModel(developerOptions: ServiceLocator.shared.settings, - elementCallBaseURL: ServiceLocator.shared.settings.elementCallBaseURL) + elementCallBaseURL: ServiceLocator.shared.settings.elementCallBaseURL, + isUsingNativeSlidingSync: true) static var previews: some View { NavigationStack { DeveloperOptionsScreen(context: viewModel.context) diff --git a/ElementX/Sources/Services/Authentication/AuthenticationClientBuilder.swift b/ElementX/Sources/Services/Authentication/AuthenticationClientBuilder.swift new file mode 100644 index 0000000000..42555699f0 --- /dev/null +++ b/ElementX/Sources/Services/Authentication/AuthenticationClientBuilder.swift @@ -0,0 +1,88 @@ +// +// Copyright 2024 New Vector Ltd +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +import Foundation +import MatrixRustSDK + +/// A wrapper around `ClientBuilder` to share reusable code between Normal and QR logins. +struct AuthenticationClientBuilder { + let sessionDirectories: SessionDirectories + let passphrase: String + let clientSessionDelegate: ClientSessionDelegate + + let appSettings: AppSettings + let appHooks: AppHooks + + /// Builds a Client for login using OIDC or password authentication. + func build(homeserverAddress: String) async throws -> Client { + if appSettings.slidingSyncDiscovery == .forceNative { + return try await makeClientBuilder(slidingSync: .forceNative).serverNameOrHomeserverUrl(serverNameOrUrl: homeserverAddress).build() + } + + if appSettings.slidingSyncDiscovery == .native { + do { + return try await makeClientBuilder(slidingSync: .discoverNative).serverNameOrHomeserverUrl(serverNameOrUrl: homeserverAddress).build() + } catch { + MXLog.warning("Native sliding sync not available: \(error)") + MXLog.info("Falling back to a sliding sync proxy.") + } + } + + return try await makeClientBuilder(slidingSync: .discoverProxy).serverNameOrHomeserverUrl(serverNameOrUrl: homeserverAddress).build() + } + + /// Builds a Client, authenticating with the given QR code data. + func buildWithQRCode(qrCodeData: QrCodeData, + oidcConfiguration: OIDCConfigurationProxy, + progressListener: QrLoginProgressListenerProxy) async throws -> Client { + if appSettings.slidingSyncDiscovery == .forceNative { + return try await makeClientBuilder(slidingSync: .forceNative).buildWithQrCode(qrCodeData: qrCodeData, + oidcConfiguration: oidcConfiguration.rustValue, + progressListener: progressListener) + } + + if appSettings.slidingSyncDiscovery == .native { + do { + return try await makeClientBuilder(slidingSync: .discoverNative).buildWithQrCode(qrCodeData: qrCodeData, + oidcConfiguration: oidcConfiguration.rustValue, + progressListener: progressListener) + } catch HumanQrLoginError.SlidingSyncNotAvailable { + MXLog.warning("Native sliding sync not available") + MXLog.info("Falling back to a sliding sync proxy.") + } catch { + throw error + } + } + + return try await makeClientBuilder(slidingSync: .discoverProxy).buildWithQrCode(qrCodeData: qrCodeData, + oidcConfiguration: oidcConfiguration.rustValue, + progressListener: progressListener) + } + + // MARK: - Private + + /// The base builder configuration used for authentication within the app. + private func makeClientBuilder(slidingSync: ClientBuilderSlidingSync) -> ClientBuilder { + ClientBuilder + .baseBuilder(httpProxy: appSettings.websiteURL.globalProxy, + slidingSync: slidingSync, + sessionDelegate: clientSessionDelegate, + appHooks: appHooks) + .sessionPaths(dataPath: sessionDirectories.dataPath, + cachePath: sessionDirectories.cachePath) + .passphrase(passphrase: passphrase) + } +} diff --git a/ElementX/Sources/Services/Authentication/AuthenticationService.swift b/ElementX/Sources/Services/Authentication/AuthenticationService.swift index 956435d038..ee5682d210 100644 --- a/ElementX/Sources/Services/Authentication/AuthenticationService.swift +++ b/ElementX/Sources/Services/Authentication/AuthenticationService.swift @@ -47,9 +47,11 @@ class AuthenticationService: AuthenticationServiceProtocol { do { var homeserver = LoginHomeserver(address: homeserverAddress, loginMode: .unknown) - let client = try await makeClientBuilder().serverNameOrHomeserverUrl(serverNameOrUrl: homeserverAddress).build() + let client = try await makeClientBuilder().build(homeserverAddress: homeserverAddress) let loginDetails = await client.homeserverLoginDetails() + MXLog.info("Sliding sync: \(client.slidingSyncVersion())") + if loginDetails.supportsOidcLogin() { homeserver.loginMode = .oidc } else if loginDetails.supportsPasswordLogin() { @@ -64,8 +66,8 @@ class AuthenticationService: AuthenticationServiceProtocol { } catch ClientBuildError.WellKnownDeserializationError(let error) { MXLog.error("The user entered a server with an invalid well-known file: \(error)") return .failure(.invalidWellKnown(error)) - } catch ClientBuildError.SlidingSyncNotAvailable { - MXLog.info("User entered a homeserver that isn't configured for sliding sync.") + } catch ClientBuildError.SlidingSyncVersion(let error) { + MXLog.info("User entered a homeserver that isn't configured for sliding sync: \(error)") return .failure(.slidingSyncNotAvailable) } catch { MXLog.error("Failed configuring a server: \(error)") @@ -138,20 +140,16 @@ class AuthenticationService: AuthenticationServiceProtocol { // MARK: - Private - private func makeClientBuilder() -> ClientBuilder { + private func makeClientBuilder() -> AuthenticationClientBuilder { // Use a fresh session directory each time the user enters a different server // so that caches (e.g. server versions) are always fresh for the new server. rotateSessionDirectory() - return ClientBuilder - .baseBuilder(httpProxy: appSettings.websiteURL.globalProxy, - slidingSync: appSettings.simplifiedSlidingSyncEnabled ? .simplified : .discovered, - slidingSyncProxy: appSettings.slidingSyncProxyURL, - sessionDelegate: userSessionStore.clientSessionDelegate, - appHooks: appHooks) - .sessionPaths(dataPath: sessionDirectories.dataPath, - cachePath: sessionDirectories.cachePath) - .passphrase(passphrase: passphrase) + return AuthenticationClientBuilder(sessionDirectories: sessionDirectories, + passphrase: passphrase, + clientSessionDelegate: userSessionStore.clientSessionDelegate, + appSettings: appSettings, + appHooks: appHooks) } private func rotateSessionDirectory() { diff --git a/ElementX/Sources/Services/QRCode/QRCodeLoginService.swift b/ElementX/Sources/Services/QRCode/QRCodeLoginService.swift index e9dee279a4..aa54f17bbc 100644 --- a/ElementX/Sources/Services/QRCode/QRCodeLoginService.swift +++ b/ElementX/Sources/Services/QRCode/QRCodeLoginService.swift @@ -57,9 +57,10 @@ final class QRCodeLoginService: QRCodeLoginServiceProtocol { } do { - let client = try await makeClientBuilder().buildWithQrCode(qrCodeData: qrData, - oidcConfiguration: appSettings.oidcConfiguration.rustValue, + let client = try await makeClientBuilder().buildWithQRCode(qrCodeData: qrData, + oidcConfiguration: appSettings.oidcConfiguration, progressListener: listener) + MXLog.info("Sliding sync: \(client.slidingSyncVersion())") return await userSession(for: client) } catch let error as HumanQrLoginError { MXLog.error("QRCode login error: \(error)") @@ -72,20 +73,16 @@ final class QRCodeLoginService: QRCodeLoginServiceProtocol { // MARK: - Private - private func makeClientBuilder() -> ClientBuilder { + private func makeClientBuilder() -> AuthenticationClientBuilder { // Use a fresh session directory each time the user scans a QR code to ensure caches // (e.g. server versions) are always fresh in case a different server is used. rotateSessionDirectory() - return ClientBuilder - .baseBuilder(httpProxy: appSettings.websiteURL.globalProxy, - slidingSync: appSettings.simplifiedSlidingSyncEnabled ? .simplified : .discovered, - slidingSyncProxy: appSettings.slidingSyncProxyURL, - sessionDelegate: userSessionStore.clientSessionDelegate, - appHooks: appHooks) - .sessionPaths(dataPath: sessionDirectories.dataPath, - cachePath: sessionDirectories.cachePath) - .passphrase(passphrase: passphrase) + return AuthenticationClientBuilder(sessionDirectories: sessionDirectories, + passphrase: passphrase, + clientSessionDelegate: userSessionStore.clientSessionDelegate, + appSettings: appSettings, + appHooks: appHooks) } private func rotateSessionDirectory() { From 0b22144b21c44b3973a90f8cf3102d34d583fbcb Mon Sep 17 00:00:00 2001 From: Doug Date: Thu, 29 Aug 2024 14:39:49 +0100 Subject: [PATCH 3/5] Update the SDK. --- ElementX.xcodeproj/project.pbxproj | 2 +- .../xcshareddata/swiftpm/Package.resolved | 4 +- .../Mocks/Generated/GeneratedMocks.swift | 14 +-- .../Mocks/Generated/SDKGeneratedMocks.swift | 112 +++--------------- .../RoomTimelineController.swift | 8 +- .../Services/Timeline/TimelineProxy.swift | 10 +- .../Timeline/TimelineProxyProtocol.swift | 2 +- project.yml | 2 +- 8 files changed, 37 insertions(+), 117 deletions(-) diff --git a/ElementX.xcodeproj/project.pbxproj b/ElementX.xcodeproj/project.pbxproj index 47d5b6e063..e10abb65b2 100644 --- a/ElementX.xcodeproj/project.pbxproj +++ b/ElementX.xcodeproj/project.pbxproj @@ -7683,7 +7683,7 @@ repositoryURL = "https://github.com/element-hq/matrix-rust-components-swift"; requirement = { kind = exactVersion; - version = 1.0.42; + version = 1.0.43; }; }; 701C7BEF8F70F7A83E852DCC /* XCRemoteSwiftPackageReference "GZIP" */ = { diff --git a/ElementX.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/ElementX.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved index 74f7fd10e2..30a9e245c0 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" : "ccae0615642728bbadcd051e4851d96ab298bab2", - "version" : "1.0.42" + "revision" : "4acde0099d719f9f176d0df3594efd3e34ffa431", + "version" : "1.0.43" } }, { diff --git a/ElementX/Sources/Mocks/Generated/GeneratedMocks.swift b/ElementX/Sources/Mocks/Generated/GeneratedMocks.swift index 8aaaa2eb75..064d992c0a 100644 --- a/ElementX/Sources/Mocks/Generated/GeneratedMocks.swift +++ b/ElementX/Sources/Mocks/Generated/GeneratedMocks.swift @@ -13854,8 +13854,8 @@ class TimelineProxyMock: TimelineProxyProtocol { var toggleReactionToCalled: Bool { return toggleReactionToCallsCount > 0 } - var toggleReactionToReceivedArguments: (reaction: String, eventID: String)? - var toggleReactionToReceivedInvocations: [(reaction: String, eventID: String)] = [] + var toggleReactionToReceivedArguments: (reaction: String, itemID: TimelineItemIdentifier)? + var toggleReactionToReceivedInvocations: [(reaction: String, itemID: TimelineItemIdentifier)] = [] var toggleReactionToUnderlyingReturnValue: Result! var toggleReactionToReturnValue: Result! { @@ -13881,16 +13881,16 @@ class TimelineProxyMock: TimelineProxyProtocol { } } } - var toggleReactionToClosure: ((String, String) async -> Result)? + var toggleReactionToClosure: ((String, TimelineItemIdentifier) async -> Result)? - func toggleReaction(_ reaction: String, to eventID: String) async -> Result { + func toggleReaction(_ reaction: String, to itemID: TimelineItemIdentifier) async -> Result { toggleReactionToCallsCount += 1 - toggleReactionToReceivedArguments = (reaction: reaction, eventID: eventID) + toggleReactionToReceivedArguments = (reaction: reaction, itemID: itemID) DispatchQueue.main.async { - self.toggleReactionToReceivedInvocations.append((reaction: reaction, eventID: eventID)) + self.toggleReactionToReceivedInvocations.append((reaction: reaction, itemID: itemID)) } if let toggleReactionToClosure = toggleReactionToClosure { - return await toggleReactionToClosure(reaction, eventID) + return await toggleReactionToClosure(reaction, itemID) } else { return toggleReactionToReturnValue } diff --git a/ElementX/Sources/Mocks/Generated/SDKGeneratedMocks.swift b/ElementX/Sources/Mocks/Generated/SDKGeneratedMocks.swift index 8d2c52a05b..80c231d0f7 100644 --- a/ElementX/Sources/Mocks/Generated/SDKGeneratedMocks.swift +++ b/ElementX/Sources/Mocks/Generated/SDKGeneratedMocks.swift @@ -9974,82 +9974,6 @@ open class NotificationSettingsSDKMock: MatrixRustSDK.NotificationSettings { try await unmuteRoomRoomIdIsEncryptedIsOneToOneClosure?(roomId, isEncrypted, isOneToOne) } } -open class OidcAuthorizationDataSDKMock: MatrixRustSDK.OidcAuthorizationData { - init() { - super.init(noPointer: .init()) - } - - public required init(unsafeFromRawPointer pointer: UnsafeMutableRawPointer) { - fatalError("init(unsafeFromRawPointer:) has not been implemented") - } - - fileprivate var pointer: UnsafeMutableRawPointer! - - //MARK: - loginUrl - - var loginUrlUnderlyingCallsCount = 0 - open var loginUrlCallsCount: Int { - get { - if Thread.isMainThread { - return loginUrlUnderlyingCallsCount - } else { - var returnValue: Int? = nil - DispatchQueue.main.sync { - returnValue = loginUrlUnderlyingCallsCount - } - - return returnValue! - } - } - set { - if Thread.isMainThread { - loginUrlUnderlyingCallsCount = newValue - } else { - DispatchQueue.main.sync { - loginUrlUnderlyingCallsCount = newValue - } - } - } - } - open var loginUrlCalled: Bool { - return loginUrlCallsCount > 0 - } - - var loginUrlUnderlyingReturnValue: String! - open var loginUrlReturnValue: String! { - get { - if Thread.isMainThread { - return loginUrlUnderlyingReturnValue - } else { - var returnValue: String? = nil - DispatchQueue.main.sync { - returnValue = loginUrlUnderlyingReturnValue - } - - return returnValue! - } - } - set { - if Thread.isMainThread { - loginUrlUnderlyingReturnValue = newValue - } else { - DispatchQueue.main.sync { - loginUrlUnderlyingReturnValue = newValue - } - } - } - } - open var loginUrlClosure: (() -> String)? - - open override func loginUrl() -> String { - loginUrlCallsCount += 1 - if let loginUrlClosure = loginUrlClosure { - return loginUrlClosure() - } else { - return loginUrlReturnValue - } - } -} open class QrCodeDataSDKMock: MatrixRustSDK.QrCodeData { init() { super.init(noPointer: .init()) @@ -20067,16 +19991,16 @@ open class TimelineSDKMock: MatrixRustSDK.Timeline { //MARK: - toggleReaction - open var toggleReactionEventIdKeyThrowableError: Error? - var toggleReactionEventIdKeyUnderlyingCallsCount = 0 - open var toggleReactionEventIdKeyCallsCount: Int { + open var toggleReactionUniqueIdKeyThrowableError: Error? + var toggleReactionUniqueIdKeyUnderlyingCallsCount = 0 + open var toggleReactionUniqueIdKeyCallsCount: Int { get { if Thread.isMainThread { - return toggleReactionEventIdKeyUnderlyingCallsCount + return toggleReactionUniqueIdKeyUnderlyingCallsCount } else { var returnValue: Int? = nil DispatchQueue.main.sync { - returnValue = toggleReactionEventIdKeyUnderlyingCallsCount + returnValue = toggleReactionUniqueIdKeyUnderlyingCallsCount } return returnValue! @@ -20084,31 +20008,31 @@ open class TimelineSDKMock: MatrixRustSDK.Timeline { } set { if Thread.isMainThread { - toggleReactionEventIdKeyUnderlyingCallsCount = newValue + toggleReactionUniqueIdKeyUnderlyingCallsCount = newValue } else { DispatchQueue.main.sync { - toggleReactionEventIdKeyUnderlyingCallsCount = newValue + toggleReactionUniqueIdKeyUnderlyingCallsCount = newValue } } } } - open var toggleReactionEventIdKeyCalled: Bool { - return toggleReactionEventIdKeyCallsCount > 0 + open var toggleReactionUniqueIdKeyCalled: Bool { + return toggleReactionUniqueIdKeyCallsCount > 0 } - open var toggleReactionEventIdKeyReceivedArguments: (eventId: String, key: String)? - open var toggleReactionEventIdKeyReceivedInvocations: [(eventId: String, key: String)] = [] - open var toggleReactionEventIdKeyClosure: ((String, String) async throws -> Void)? + open var toggleReactionUniqueIdKeyReceivedArguments: (uniqueId: String, key: String)? + open var toggleReactionUniqueIdKeyReceivedInvocations: [(uniqueId: String, key: String)] = [] + open var toggleReactionUniqueIdKeyClosure: ((String, String) async throws -> Void)? - open override func toggleReaction(eventId: String, key: String) async throws { - if let error = toggleReactionEventIdKeyThrowableError { + open override func toggleReaction(uniqueId: String, key: String) async throws { + if let error = toggleReactionUniqueIdKeyThrowableError { throw error } - toggleReactionEventIdKeyCallsCount += 1 - toggleReactionEventIdKeyReceivedArguments = (eventId: eventId, key: key) + toggleReactionUniqueIdKeyCallsCount += 1 + toggleReactionUniqueIdKeyReceivedArguments = (uniqueId: uniqueId, key: key) DispatchQueue.main.async { - self.toggleReactionEventIdKeyReceivedInvocations.append((eventId: eventId, key: key)) + self.toggleReactionUniqueIdKeyReceivedInvocations.append((uniqueId: uniqueId, key: key)) } - try await toggleReactionEventIdKeyClosure?(eventId, key) + try await toggleReactionUniqueIdKeyClosure?(uniqueId, key) } //MARK: - unpinEvent diff --git a/ElementX/Sources/Services/Timeline/TimelineController/RoomTimelineController.swift b/ElementX/Sources/Services/Timeline/TimelineController/RoomTimelineController.swift index bebbf93481..c3b783d0c5 100644 --- a/ElementX/Sources/Services/Timeline/TimelineController/RoomTimelineController.swift +++ b/ElementX/Sources/Services/Timeline/TimelineController/RoomTimelineController.swift @@ -178,12 +178,8 @@ class RoomTimelineController: RoomTimelineControllerProtocol { func toggleReaction(_ reaction: String, to itemID: TimelineItemIdentifier) async { MXLog.info("Toggle reaction in \(roomID)") - guard let eventID = itemID.eventID else { - MXLog.error("Failed toggling reaction: missing eventID") - return - } - - switch await activeTimeline.toggleReaction(reaction, to: eventID) { + + switch await activeTimeline.toggleReaction(reaction, to: itemID) { case .success: MXLog.info("Finished toggling reaction") case .failure(let error): diff --git a/ElementX/Sources/Services/Timeline/TimelineProxy.swift b/ElementX/Sources/Services/Timeline/TimelineProxy.swift index 75cb650bae..8ae0d9ab39 100644 --- a/ElementX/Sources/Services/Timeline/TimelineProxy.swift +++ b/ElementX/Sources/Services/Timeline/TimelineProxy.swift @@ -430,15 +430,15 @@ final class TimelineProxy: TimelineProxyProtocol { } } - func toggleReaction(_ reaction: String, to eventID: String) async -> Result { - MXLog.info("Toggling reaction for eventID: \(eventID)") + func toggleReaction(_ reaction: String, to itemID: TimelineItemIdentifier) async -> Result { + MXLog.info("Toggling reaction for event: \(itemID)") do { - try await timeline.toggleReaction(eventId: eventID, key: reaction) - MXLog.info("Finished toggling reaction for eventID: \(eventID)") + try await timeline.toggleReaction(uniqueId: itemID.timelineID, key: reaction) + MXLog.info("Finished toggling reaction for event: \(itemID)") return .success(()) } catch { - MXLog.error("Failed toggling reaction for eventID: \(eventID)") + MXLog.error("Failed toggling reaction for event: \(itemID)") return .failure(.sdkError(error)) } } diff --git a/ElementX/Sources/Services/Timeline/TimelineProxyProtocol.swift b/ElementX/Sources/Services/Timeline/TimelineProxyProtocol.swift index 8c98bb3e6f..3ea98bd680 100644 --- a/ElementX/Sources/Services/Timeline/TimelineProxyProtocol.swift +++ b/ElementX/Sources/Services/Timeline/TimelineProxyProtocol.swift @@ -101,7 +101,7 @@ protocol TimelineProxyProtocol { inReplyTo eventID: String?, intentionalMentions: IntentionalMentions) async -> Result - func toggleReaction(_ reaction: String, to eventID: String) async -> Result + func toggleReaction(_ reaction: String, to itemID: TimelineItemIdentifier) async -> Result // Polls func createPoll(question: String, answers: [String], pollKind: Poll.Kind) async -> Result diff --git a/project.yml b/project.yml index df67f7256e..9a7d7c2c9f 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.42 + exactVersion: 1.0.43 # path: ../matrix-rust-sdk Compound: url: https://github.com/element-hq/compound-ios From 36bfe2cf5e97b5c3900a1ab1e3609093159086ad Mon Sep 17 00:00:00 2001 From: Doug Date: Thu, 29 Aug 2024 15:02:39 +0100 Subject: [PATCH 4/5] SonarCloud: Remove redundant rethrow. --- .../Services/Authentication/AuthenticationClientBuilder.swift | 2 -- 1 file changed, 2 deletions(-) diff --git a/ElementX/Sources/Services/Authentication/AuthenticationClientBuilder.swift b/ElementX/Sources/Services/Authentication/AuthenticationClientBuilder.swift index 42555699f0..bc37907ff8 100644 --- a/ElementX/Sources/Services/Authentication/AuthenticationClientBuilder.swift +++ b/ElementX/Sources/Services/Authentication/AuthenticationClientBuilder.swift @@ -62,8 +62,6 @@ struct AuthenticationClientBuilder { } catch HumanQrLoginError.SlidingSyncNotAvailable { MXLog.warning("Native sliding sync not available") MXLog.info("Falling back to a sliding sync proxy.") - } catch { - throw error } } From e47e76c3cb5105a2d37dcc3a5441f4bc153a7889 Mon Sep 17 00:00:00 2001 From: Doug Date: Fri, 30 Aug 2024 12:07:55 +0100 Subject: [PATCH 5/5] Default to native sliding sync discovery. --- ElementX/Sources/Application/AppSettings.swift | 2 +- ElementX/Sources/Services/UserSession/RestorationToken.swift | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/ElementX/Sources/Application/AppSettings.swift b/ElementX/Sources/Application/AppSettings.swift index 1de3fd83ca..f83830d5da 100644 --- a/ElementX/Sources/Application/AppSettings.swift +++ b/ElementX/Sources/Application/AppSettings.swift @@ -282,7 +282,7 @@ final class AppSettings { var pinningEnabled enum SlidingSyncDiscovery: Codable { case proxy, native, forceNative } - @UserPreference(key: UserDefaultsKeys.slidingSyncDiscovery, defaultValue: .proxy, storageType: .userDefaults(store)) + @UserPreference(key: UserDefaultsKeys.slidingSyncDiscovery, defaultValue: .native, storageType: .userDefaults(store)) var slidingSyncDiscovery: SlidingSyncDiscovery #endif diff --git a/ElementX/Sources/Services/UserSession/RestorationToken.swift b/ElementX/Sources/Services/UserSession/RestorationToken.swift index c0d7b7dde4..482173e657 100644 --- a/ElementX/Sources/Services/UserSession/RestorationToken.swift +++ b/ElementX/Sources/Services/UserSession/RestorationToken.swift @@ -54,14 +54,14 @@ extension RestorationToken: Codable { extension MatrixRustSDK.Session: Codable { public init(from decoder: Decoder) throws { let container = try decoder.container(keyedBy: CodingKeys.self) - let slidingSyncVersion: SlidingSyncVersion = try container.decodeIfPresent(String.self, forKey: .slidingSyncProxy).map { .proxy(url: $0) } ?? .native + let slidingSyncProxy = try container.decodeIfPresent(String.self, forKey: .slidingSyncProxy) self = try .init(accessToken: container.decode(String.self, forKey: .accessToken), refreshToken: container.decodeIfPresent(String.self, forKey: .refreshToken), userId: container.decode(String.self, forKey: .userId), deviceId: container.decode(String.self, forKey: .deviceId), homeserverUrl: container.decode(String.self, forKey: .homeserverUrl), oidcData: container.decodeIfPresent(String.self, forKey: .oidcData), - slidingSyncVersion: slidingSyncVersion) + slidingSyncVersion: slidingSyncProxy.map { .proxy(url: $0) } ?? .native) } public func encode(to encoder: Encoder) throws {