From fb104a4077586c39e22b97c47bfc53ee37eb4806 Mon Sep 17 00:00:00 2001 From: Doug <6060466+pixlwave@users.noreply.github.com> Date: Wed, 16 Apr 2025 08:36:57 +0100 Subject: [PATCH] Refactor SecureBackupControllerListener into SDKListener and use it everywhere. (#4030) --- ElementX.xcodeproj/project.pbxproj | 4 + .../Mocks/Generated/GeneratedMocks.swift | 8 +- ElementX/Sources/Other/SDKListener.swift | 101 ++++++++++++++++++ .../AuthenticationClientBuilder.swift | 4 +- .../Sources/Services/Client/ClientProxy.swift | 56 +--------- .../Services/QRCode/QRCodeLoginService.swift | 14 +-- .../RoomSummary/RoomSummaryProvider.swift | 28 +---- .../RoomDirectorySearchProxy.swift | 14 +-- .../SecureBackup/SecureBackupController.swift | 25 +---- .../Services/Timeline/TimelineProvider.swift | 14 +-- .../Services/Timeline/TimelineProxy.swift | 28 +---- 11 files changed, 125 insertions(+), 171 deletions(-) create mode 100644 ElementX/Sources/Other/SDKListener.swift diff --git a/ElementX.xcodeproj/project.pbxproj b/ElementX.xcodeproj/project.pbxproj index 994e12c1e..56c677b60 100644 --- a/ElementX.xcodeproj/project.pbxproj +++ b/ElementX.xcodeproj/project.pbxproj @@ -324,6 +324,7 @@ 3ED2725734568F6B8CC87544 /* AttributedStringBuilder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2A5C6FBF97B6EED3D4FA5EFF /* AttributedStringBuilder.swift */; }; 3F2148F11164C7C5609984EB /* GZIP in Frameworks */ = {isa = PBXBuildFile; productRef = 2B788C81F6369D164ADEB917 /* GZIP */; }; 3F327A62D233933F54F0F33A /* SwiftOGG in Frameworks */ = {isa = PBXBuildFile; productRef = 3FE40E79C36E7903121E6E3B /* SwiftOGG */; }; + 3F55721B5C08E8D9F1295592 /* SDKListener.swift in Sources */ = {isa = PBXBuildFile; fileRef = FE5CD2993048222B64C45006 /* SDKListener.swift */; }; 3F70E237CE4C3FAB02FC227F /* NotificationConstants.swift in Sources */ = {isa = PBXBuildFile; fileRef = C830A64609CBD152F06E0457 /* NotificationConstants.swift */; }; 401BB28CD6B7DD6B4E7863E7 /* ServerConfirmationScreenModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9342F5D6729627B6393AF853 /* ServerConfirmationScreenModels.swift */; }; 407DCE030E0F9B7C9861D38A /* LoremSwiftum in Frameworks */ = {isa = PBXBuildFile; productRef = 1A6B622CCFDEFB92D9CF1CA5 /* LoremSwiftum */; }; @@ -2578,6 +2579,7 @@ FDEDD4D2DE0646DA724985D5 /* QRCodeLoginScreenModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = QRCodeLoginScreenModels.swift; sourceTree = ""; }; FDF73F49E6B6683F7E2D26F0 /* SecureBackupScreenCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SecureBackupScreenCoordinator.swift; sourceTree = ""; }; FE1E6FAA3719E9B7A2D5510B /* FormattingToolbar.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FormattingToolbar.swift; sourceTree = ""; }; + FE5CD2993048222B64C45006 /* SDKListener.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SDKListener.swift; sourceTree = ""; }; FF720BA68256297680980481 /* zh-Hans */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hans"; path = "zh-Hans.lproj/InfoPlist.strings"; sourceTree = ""; }; FFECCE59967018204876D0A5 /* LocationMarkerView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LocationMarkerView.swift; sourceTree = ""; }; /* End PBXFileReference section */ @@ -5367,6 +5369,7 @@ 6A580295A56B55A856CC4084 /* InfoPlistReader.swift */, 6AD1A853D605C2146B0DC028 /* MatrixEntityRegex.swift */, 53482ECA4B6633961EC224F5 /* ScrollViewAdapter.swift */, + FE5CD2993048222B64C45006 /* SDKListener.swift */, 4481799F455B3DA243BDA2AC /* ShareToMapsAppActivity.swift */, B1E227F34BE43B08E098796E /* TestablePreview.swift */, 1F2529D434C750ED78ADF1ED /* UserAgentBuilder.swift */, @@ -7549,6 +7552,7 @@ 41CE5E1289C8768FC5B6490C /* RoomTimelineItemViewState.swift in Sources */, B2F8E01ABA1BA30265B4ECBE /* RoundedCornerShape.swift in Sources */, D43F0503EF2CBC55272538FE /* SDKGeneratedMocks.swift in Sources */, + 3F55721B5C08E8D9F1295592 /* SDKListener.swift in Sources */, 88CBF1595E39CE697928DE48 /* SFNumberedListView.swift in Sources */, FB595EC9C00AB32F39034055 /* SceneDelegate.swift in Sources */, 0437765FF480249486893CC7 /* ScreenTrackerViewModifier.swift in Sources */, diff --git a/ElementX/Sources/Mocks/Generated/GeneratedMocks.swift b/ElementX/Sources/Mocks/Generated/GeneratedMocks.swift index 064b4bb09..7801677cc 100644 --- a/ElementX/Sources/Mocks/Generated/GeneratedMocks.swift +++ b/ElementX/Sources/Mocks/Generated/GeneratedMocks.swift @@ -2002,8 +2002,8 @@ class AuthenticationClientBuilderMock: AuthenticationClientBuilderProtocol, @unc var buildWithQRCodeQrCodeDataOidcConfigurationProgressListenerCalled: Bool { return buildWithQRCodeQrCodeDataOidcConfigurationProgressListenerCallsCount > 0 } - var buildWithQRCodeQrCodeDataOidcConfigurationProgressListenerReceivedArguments: (qrCodeData: QrCodeData, oidcConfiguration: OIDCConfigurationProxy, progressListener: QrLoginProgressListenerProxy)? - var buildWithQRCodeQrCodeDataOidcConfigurationProgressListenerReceivedInvocations: [(qrCodeData: QrCodeData, oidcConfiguration: OIDCConfigurationProxy, progressListener: QrLoginProgressListenerProxy)] = [] + var buildWithQRCodeQrCodeDataOidcConfigurationProgressListenerReceivedArguments: (qrCodeData: QrCodeData, oidcConfiguration: OIDCConfigurationProxy, progressListener: SDKListener)? + var buildWithQRCodeQrCodeDataOidcConfigurationProgressListenerReceivedInvocations: [(qrCodeData: QrCodeData, oidcConfiguration: OIDCConfigurationProxy, progressListener: SDKListener)] = [] var buildWithQRCodeQrCodeDataOidcConfigurationProgressListenerUnderlyingReturnValue: ClientProtocol! var buildWithQRCodeQrCodeDataOidcConfigurationProgressListenerReturnValue: ClientProtocol! { @@ -2029,9 +2029,9 @@ class AuthenticationClientBuilderMock: AuthenticationClientBuilderProtocol, @unc } } } - var buildWithQRCodeQrCodeDataOidcConfigurationProgressListenerClosure: ((QrCodeData, OIDCConfigurationProxy, QrLoginProgressListenerProxy) async throws -> ClientProtocol)? + var buildWithQRCodeQrCodeDataOidcConfigurationProgressListenerClosure: ((QrCodeData, OIDCConfigurationProxy, SDKListener) async throws -> ClientProtocol)? - func buildWithQRCode(qrCodeData: QrCodeData, oidcConfiguration: OIDCConfigurationProxy, progressListener: QrLoginProgressListenerProxy) async throws -> ClientProtocol { + func buildWithQRCode(qrCodeData: QrCodeData, oidcConfiguration: OIDCConfigurationProxy, progressListener: SDKListener) async throws -> ClientProtocol { if let error = buildWithQRCodeQrCodeDataOidcConfigurationProgressListenerThrowableError { throw error } diff --git a/ElementX/Sources/Other/SDKListener.swift b/ElementX/Sources/Other/SDKListener.swift new file mode 100644 index 000000000..34e605924 --- /dev/null +++ b/ElementX/Sources/Other/SDKListener.swift @@ -0,0 +1,101 @@ +// +// Copyright 2025 New Vector Ltd. +// +// SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial +// Please see LICENSE files in the repository root for full details. +// + +import Foundation +import MatrixRustSDK + +/// A helper class that can be passed as this listener for SDK callbacks. +/// +/// To use this you'll need to add a conformance to the required listener +/// protocol with a specialisation for the type it listens for. +final class SDKListener { + private let onUpdateClosure: (T) -> Void + + /// Creates a new listener. + /// - Parameter onUpdateClosure: A closure that will be called whenever a new value is available. + init(_ onUpdateClosure: @escaping (T) -> Void) { + self.onUpdateClosure = onUpdateClosure + } +} + +// MARK: QRCodeLoginService + +extension SDKListener: QrLoginProgressListener where T == QrLoginProgress { + func onUpdate(state: QrLoginProgress) { onUpdateClosure(state) } +} + +// MARK: ClientProxy + +extension SDKListener: SyncServiceStateObserver where T == SyncServiceState { + func onUpdate(state: SyncServiceState) { onUpdateClosure(state) } +} + +extension SDKListener: RoomListServiceStateListener where T == RoomListServiceState { + func onUpdate(state: RoomListServiceState) { onUpdateClosure(state) } +} + +extension SDKListener: RoomListServiceSyncIndicatorListener where T == RoomListServiceSyncIndicator { + func onUpdate(syncIndicator: RoomListServiceSyncIndicator) { onUpdateClosure(syncIndicator) } +} + +extension SDKListener: VerificationStateListener where T == VerificationState { + func onUpdate(status: VerificationState) { onUpdateClosure(status) } +} + +// MARK: SecureBackupController + +extension SDKListener: BackupStateListener where T == BackupState { + func onUpdate(status: BackupState) { onUpdateClosure(status) } +} + +extension SDKListener: RecoveryStateListener where T == RecoveryState { + func onUpdate(status: RecoveryState) { onUpdateClosure(status) } +} + +extension SDKListener: EnableRecoveryProgressListener where T == EnableRecoveryProgress { + func onUpdate(status: EnableRecoveryProgress) { onUpdateClosure(status) } +} + +extension SDKListener: BackupSteadyStateListener where T == BackupUploadState { + func onUpdate(status: BackupUploadState) { onUpdateClosure(status) } +} + +// MARK: RoomSummaryProvider + +extension SDKListener: RoomListEntriesListener where T == [RoomListEntriesUpdate] { + func onUpdate(roomEntriesUpdate: [RoomListEntriesUpdate]) { onUpdateClosure(roomEntriesUpdate) } +} + +extension SDKListener: RoomListLoadingStateListener where T == RoomListLoadingState { + func onUpdate(state: RoomListLoadingState) { onUpdateClosure(state) } +} + +// MARK: TimelineProxy + +extension SDKListener: PaginationStatusListener where T == RoomPaginationStatus { + func onUpdate(status: RoomPaginationStatus) { onUpdateClosure(status) } +} + +extension SDKListener: ProgressWatcher where T == Double { + func transmissionProgress(progress: TransmissionProgress) { + DispatchQueue.main.async { [weak self] in + self?.onUpdateClosure(Double(progress.current) / Double(progress.total)) + } + } +} + +// MARK: TimelineProvider + +extension SDKListener: TimelineListener where T == [TimelineDiff] { + func onUpdate(diff: [TimelineDiff]) { onUpdateClosure(diff) } +} + +// MARK: RoomDirectorySearchProxy + +extension SDKListener: RoomDirectorySearchEntriesListener where T == [RoomDirectorySearchEntryUpdate] { + func onUpdate(roomEntriesUpdate: [RoomDirectorySearchEntryUpdate]) { onUpdateClosure(roomEntriesUpdate) } +} diff --git a/ElementX/Sources/Services/Authentication/AuthenticationClientBuilder.swift b/ElementX/Sources/Services/Authentication/AuthenticationClientBuilder.swift index 1d52551f6..11d95e30a 100644 --- a/ElementX/Sources/Services/Authentication/AuthenticationClientBuilder.swift +++ b/ElementX/Sources/Services/Authentication/AuthenticationClientBuilder.swift @@ -13,7 +13,7 @@ protocol AuthenticationClientBuilderProtocol { func build(homeserverAddress: String) async throws -> ClientProtocol func buildWithQRCode(qrCodeData: QrCodeData, oidcConfiguration: OIDCConfigurationProxy, - progressListener: QrLoginProgressListenerProxy) async throws -> ClientProtocol + progressListener: SDKListener) async throws -> ClientProtocol } /// A wrapper around `ClientBuilder` to share reusable code between Normal and QR logins. @@ -33,7 +33,7 @@ struct AuthenticationClientBuilder: AuthenticationClientBuilderProtocol { /// Builds a Client, authenticating with the given QR code data. func buildWithQRCode(qrCodeData: QrCodeData, oidcConfiguration: OIDCConfigurationProxy, - progressListener: QrLoginProgressListenerProxy) async throws -> ClientProtocol { + progressListener: SDKListener) async throws -> ClientProtocol { try await makeClientBuilder().buildWithQrCode(qrCodeData: qrCodeData, oidcConfiguration: oidcConfiguration.rustValue, progressListener: progressListener) diff --git a/ElementX/Sources/Services/Client/ClientProxy.swift b/ElementX/Sources/Services/Client/ClientProxy.swift index 18881fb62..ffa1e9f90 100644 --- a/ElementX/Sources/Services/Client/ClientProxy.swift +++ b/ElementX/Sources/Services/Client/ClientProxy.swift @@ -192,7 +192,7 @@ class ClientProxy: ClientProxyProtocol { await updateVerificationState(client.encryption().verificationState()) - verificationStateListenerTaskHandle = client.encryption().verificationStateListener(listener: VerificationStateListenerProxy { [weak self] verificationState in + verificationStateListenerTaskHandle = client.encryption().verificationStateListener(listener: SDKListener { [weak self] verificationState in Task { await self?.updateVerificationState(verificationState) } }) @@ -838,7 +838,7 @@ class ClientProxy: ClientProxyProtocol { } private func createSyncServiceStateObserver(_ syncService: SyncService) -> TaskHandle { - syncService.state(listener: SyncServiceStateObserverProxy { [weak self] state in + syncService.state(listener: SDKListener { [weak self] state in guard let self else { return } MXLog.info("Received sync service update: \(state)") @@ -856,7 +856,7 @@ class ClientProxy: ClientProxyProtocol { } private func createRoomListServiceObserver(_ roomListService: RoomListService) -> TaskHandle { - roomListService.state(listener: RoomListStateListenerProxy { [weak self] state in + roomListService.state(listener: SDKListener { [weak self] state in guard let self else { return } MXLog.info("Received room list update: \(state)") @@ -877,7 +877,7 @@ class ClientProxy: ClientProxyProtocol { } private func createRoomListLoadingStateUpdateObserver(_ roomListService: RoomListService) -> TaskHandle { - roomListService.syncIndicator(delayBeforeShowingInMs: 1000, delayBeforeHidingInMs: 0, listener: RoomListServiceSyncIndicatorListenerProxy { [weak self] state in + roomListService.syncIndicator(delayBeforeShowingInMs: 1000, delayBeforeHidingInMs: 0, listener: SDKListener { [weak self] state in guard let self else { return } switch state { @@ -1039,54 +1039,6 @@ extension ClientProxy: MediaLoaderProtocol { } } -private class SyncServiceStateObserverProxy: SyncServiceStateObserver { - private let onUpdateClosure: (SyncServiceState) -> Void - - init(onUpdateClosure: @escaping (SyncServiceState) -> Void) { - self.onUpdateClosure = onUpdateClosure - } - - func onUpdate(state: SyncServiceState) { - onUpdateClosure(state) - } -} - -private class RoomListStateListenerProxy: RoomListServiceStateListener { - private let onUpdateClosure: (RoomListServiceState) -> Void - - init(onUpdateClosure: @escaping (RoomListServiceState) -> Void) { - self.onUpdateClosure = onUpdateClosure - } - - func onUpdate(state: RoomListServiceState) { - onUpdateClosure(state) - } -} - -private class RoomListServiceSyncIndicatorListenerProxy: RoomListServiceSyncIndicatorListener { - private let onUpdateClosure: (RoomListServiceSyncIndicator) -> Void - - init(onUpdateClosure: @escaping (RoomListServiceSyncIndicator) -> Void) { - self.onUpdateClosure = onUpdateClosure - } - - func onUpdate(syncIndicator: RoomListServiceSyncIndicator) { - onUpdateClosure(syncIndicator) - } -} - -private class VerificationStateListenerProxy: VerificationStateListener { - private let onUpdateClosure: (VerificationState) -> Void - - init(onUpdateClosure: @escaping (VerificationState) -> Void) { - self.onUpdateClosure = onUpdateClosure - } - - func onUpdate(status: VerificationState) { - onUpdateClosure(status) - } -} - private class ClientDelegateWrapper: ClientDelegate { private let authErrorCallback: (Bool) -> Void diff --git a/ElementX/Sources/Services/QRCode/QRCodeLoginService.swift b/ElementX/Sources/Services/QRCode/QRCodeLoginService.swift index 48f002e5c..fb83e3200 100644 --- a/ElementX/Sources/Services/QRCode/QRCodeLoginService.swift +++ b/ElementX/Sources/Services/QRCode/QRCodeLoginService.swift @@ -43,7 +43,7 @@ final class QRCodeLoginService: QRCodeLoginServiceProtocol { return .failure(.invalidQRCode) } - let listener = QrLoginProgressListenerProxy { [weak self] progress in + let listener = SDKListener { [weak self] progress in self?.qrLoginProgressSubject.send(progress) } @@ -92,18 +92,6 @@ final class QRCodeLoginService: QRCodeLoginServiceProtocol { } } -final class QrLoginProgressListenerProxy: QrLoginProgressListener { - private let onUpdateClosure: (QrLoginProgress) -> Void - - init(onUpdateClosure: @escaping (QrLoginProgress) -> Void) { - self.onUpdateClosure = onUpdateClosure - } - - func onUpdate(state: QrLoginProgress) { - onUpdateClosure(state) - } -} - private extension HumanQrLoginError { var serviceError: QRCodeLoginServiceError { switch self { diff --git a/ElementX/Sources/Services/Room/RoomSummary/RoomSummaryProvider.swift b/ElementX/Sources/Services/Room/RoomSummary/RoomSummaryProvider.swift index 14e949ca9..7559bbf96 100644 --- a/ElementX/Sources/Services/Room/RoomSummary/RoomSummaryProvider.swift +++ b/ElementX/Sources/Services/Room/RoomSummary/RoomSummaryProvider.swift @@ -89,7 +89,7 @@ class RoomSummaryProvider: RoomSummaryProviderProtocol { self.roomList = roomList do { - listUpdatesSubscriptionResult = roomList.entriesWithDynamicAdapters(pageSize: UInt32(roomListPageSize), listener: RoomListEntriesListenerProxy { [weak self] updates in + listUpdatesSubscriptionResult = roomList.entriesWithDynamicAdapters(pageSize: UInt32(roomListPageSize), listener: SDKListener { [weak self] updates in guard let self else { return } diffsPublisher.send(updates) }) @@ -97,7 +97,7 @@ class RoomSummaryProvider: RoomSummaryProviderProtocol { // Forces the listener above to be called with the current state setFilter(.all(filters: [])) - let stateUpdatesSubscriptionResult = try roomList.loadingState(listener: RoomListStateObserver { [weak self] state in + let stateUpdatesSubscriptionResult = try roomList.loadingState(listener: SDKListener { [weak self] state in guard let self else { return } MXLog.info("\(name): Received state update: \(state)") stateSubject.send(RoomSummaryProviderState(roomListState: state)) @@ -383,27 +383,3 @@ extension RoomSummaryProviderState { } } } - -private class RoomListEntriesListenerProxy: RoomListEntriesListener { - private let onUpdateClosure: ([RoomListEntriesUpdate]) -> Void - - init(_ onUpdateClosure: @escaping ([RoomListEntriesUpdate]) -> Void) { - self.onUpdateClosure = onUpdateClosure - } - - func onUpdate(roomEntriesUpdate: [RoomListEntriesUpdate]) { - onUpdateClosure(roomEntriesUpdate) - } -} - -private class RoomListStateObserver: RoomListLoadingStateListener { - private let onUpdateClosure: (RoomListLoadingState) -> Void - - init(_ onUpdateClosure: @escaping (RoomListLoadingState) -> Void) { - self.onUpdateClosure = onUpdateClosure - } - - func onUpdate(state: RoomListLoadingState) { - onUpdateClosure(state) - } -} diff --git a/ElementX/Sources/Services/RoomDirectorySearch/RoomDirectorySearchProxy.swift b/ElementX/Sources/Services/RoomDirectorySearch/RoomDirectorySearchProxy.swift index dca4f9a4a..810ccfd55 100644 --- a/ElementX/Sources/Services/RoomDirectorySearch/RoomDirectorySearchProxy.swift +++ b/ElementX/Sources/Services/RoomDirectorySearch/RoomDirectorySearchProxy.swift @@ -42,7 +42,7 @@ final class RoomDirectorySearchProxy: RoomDirectorySearchProxyProtocol { .store(in: &cancellables) Task { - searchEntriesSubscription = await roomDirectorySearch.results(listener: RoomDirectorySearchEntriesListenerProxy { [weak self] updates in + searchEntriesSubscription = await roomDirectorySearch.results(listener: SDKListener { [weak self] updates in self?.diffsPublisher.send(updates) }) } @@ -152,15 +152,3 @@ final class RoomDirectorySearchProxy: RoomDirectorySearchProxyProtocol { canBeJoined: value.joinRule == .public || (appSettings.knockingEnabled && value.joinRule == .knock)) } } - -private final class RoomDirectorySearchEntriesListenerProxy: RoomDirectorySearchEntriesListener { - private let onUpdateClosure: ([RoomDirectorySearchEntryUpdate]) -> Void - - func onUpdate(roomEntriesUpdate: [RoomDirectorySearchEntryUpdate]) { - onUpdateClosure(roomEntriesUpdate) - } - - init(_ onUpdateClosure: @escaping (([RoomDirectorySearchEntryUpdate]) -> Void)) { - self.onUpdateClosure = onUpdateClosure - } -} diff --git a/ElementX/Sources/Services/SecureBackup/SecureBackupController.swift b/ElementX/Sources/Services/SecureBackup/SecureBackupController.swift index ea350296b..cf0dba381 100644 --- a/ElementX/Sources/Services/SecureBackup/SecureBackupController.swift +++ b/ElementX/Sources/Services/SecureBackup/SecureBackupController.swift @@ -35,7 +35,7 @@ class SecureBackupController: SecureBackupControllerProtocol { init(encryption: Encryption) { self.encryption = encryption - backupStateListenerTaskHandle = encryption.backupStateListener(listener: SecureBackupControllerListener { [weak self] state in + backupStateListenerTaskHandle = encryption.backupStateListener(listener: SDKListener { [weak self] state in guard let self else { return } switch state { @@ -62,7 +62,7 @@ class SecureBackupController: SecureBackupControllerProtocol { } }) - recoveryStateListenerTaskHandle = encryption.recoveryStateListener(listener: SecureBackupControllerListener { [weak self] state in + recoveryStateListenerTaskHandle = encryption.recoveryStateListener(listener: SDKListener { [weak self] state in guard let self else { return } switch state { @@ -121,7 +121,7 @@ class SecureBackupController: SecureBackupControllerProtocol { MXLog.info("Enabling recovery") var keyUploadErrored = false - let recoveryKey = try await encryption.enableRecovery(waitForBackupsToUpload: false, passphrase: nil, progressListener: SecureBackupControllerListener { [weak self] state in + let recoveryKey = try await encryption.enableRecovery(waitForBackupsToUpload: false, passphrase: nil, progressListener: SDKListener { [weak self] state in guard let self else { return } switch state { @@ -157,7 +157,7 @@ class SecureBackupController: SecureBackupControllerProtocol { func waitForKeyBackupUpload(uploadStateSubject: CurrentValueSubject) async -> Result { do { MXLog.info("Waiting for backup upload steady state") - try await encryption.waitForBackupUploadSteadyState(progressListener: SecureBackupControllerListener { state in + try await encryption.waitForBackupUploadSteadyState(progressListener: SDKListener { state in let uploadState: SecureBackupSteadyState = switch state { case .waiting: .waiting case .uploading(let backedUpCount, let totalCount): .uploading(uploadedKeyCount: Int(backedUpCount), totalKeyCount: Int(totalCount)) @@ -210,20 +210,3 @@ class SecureBackupController: SecureBackupControllerProtocol { } } } - -private final class SecureBackupControllerListener { - private let onUpdateClosure: (T) -> Void - - init(_ onUpdateClosure: @escaping (T) -> Void) { - self.onUpdateClosure = onUpdateClosure - } - - func onUpdate(status: T) { - onUpdateClosure(status) - } -} - -extension SecureBackupControllerListener: BackupStateListener where T == BackupState { } -extension SecureBackupControllerListener: RecoveryStateListener where T == RecoveryState { } -extension SecureBackupControllerListener: EnableRecoveryProgressListener where T == EnableRecoveryProgress { } -extension SecureBackupControllerListener: BackupSteadyStateListener where T == BackupUploadState { } diff --git a/ElementX/Sources/Services/Timeline/TimelineProvider.swift b/ElementX/Sources/Services/Timeline/TimelineProvider.swift index 956e8e32e..2fe37fb41 100644 --- a/ElementX/Sources/Services/Timeline/TimelineProvider.swift +++ b/ElementX/Sources/Services/Timeline/TimelineProvider.swift @@ -57,7 +57,7 @@ class TimelineProvider: TimelineProviderProtocol { .store(in: &cancellables) Task { - roomTimelineObservationToken = await timeline.addListener(listener: RoomTimelineListener { [weak self] timelineDiffs in + roomTimelineObservationToken = await timeline.addListener(listener: SDKListener { [weak self] timelineDiffs in self?.serialDispatchQueue.sync { self?.updateItemsWithDiffs(timelineDiffs) } @@ -215,18 +215,6 @@ private extension VirtualTimelineItem { } } -private final class RoomTimelineListener: TimelineListener { - private let onUpdateClosure: ([TimelineDiff]) -> Void - - init(_ onUpdateClosure: @escaping ([TimelineDiff]) -> Void) { - self.onUpdateClosure = onUpdateClosure - } - - func onUpdate(diff: [TimelineDiff]) { - onUpdateClosure(diff) - } -} - private extension Array where Element == TimelineDiff { var debugDescription: String { "[" + map(\.debugDescription).joined(separator: ",") + "]" diff --git a/ElementX/Sources/Services/Timeline/TimelineProxy.swift b/ElementX/Sources/Services/Timeline/TimelineProxy.swift index fa3cc8471..494bdfde5 100644 --- a/ElementX/Sources/Services/Timeline/TimelineProxy.swift +++ b/ElementX/Sources/Services/Timeline/TimelineProxy.swift @@ -577,7 +577,7 @@ final class TimelineProxy: TimelineProxyProtocol { private func subscribeToPagination() async { switch kind { case .live: - let backPaginationListener = RoomPaginationStatusListener { [weak self] status in + let backPaginationListener = SDKListener { [weak self] status in guard let self else { return } @@ -610,32 +610,6 @@ final class TimelineProxy: TimelineProxyProtocol { } } -private final class RoomPaginationStatusListener: PaginationStatusListener { - private let onUpdateClosure: (RoomPaginationStatus) -> Void - - init(_ onUpdateClosure: @escaping (RoomPaginationStatus) -> Void) { - self.onUpdateClosure = onUpdateClosure - } - - func onUpdate(status: RoomPaginationStatus) { - onUpdateClosure(status) - } -} - -private final class UploadProgressListener: ProgressWatcher { - private let onUpdateClosure: (Double) -> Void - - init(_ onUpdateClosure: @escaping (Double) -> Void) { - self.onUpdateClosure = onUpdateClosure - } - - func transmissionProgress(progress: TransmissionProgress) { - DispatchQueue.main.async { [weak self] in - self?.onUpdateClosure(Double(progress.current) / Double(progress.total)) - } - } -} - private extension MatrixRustSDK.PollKind { init(pollKind: Poll.Kind) { switch pollKind {