From cb7d11fd134e87472c7ca631fcca99c211855a35 Mon Sep 17 00:00:00 2001 From: Doug Date: Wed, 27 Aug 2025 16:05:49 +0100 Subject: [PATCH] Remove all uses of the ServiceLocator from within Coordinators and View Models. It is still used for mocks in tests, previews etc, and still used in the AppCoordinator. --- .../Sources/Application/AppCoordinator.swift | 5 +- .../ChatsFlowCoordinator.swift | 8 ++- .../EncryptionResetFlowCoordinator.swift | 7 ++- .../MediaEventsTimelineFlowCoordinator.swift | 2 + .../OnboardingFlowCoordinator.swift | 1 + .../PinnedEventsTimelineFlowCoordinator.swift | 5 +- .../RoomFlowCoordinator.swift | 17 ++++-- .../SettingsFlowCoordinator.swift | 9 ++- .../SoftLogoutScreenCoordinator.swift | 3 +- .../CallScreen/CallScreenCoordinator.swift | 6 +- .../CreateRoom/CreateRoomCoordinator.swift | 6 +- ...MediaEventsTimelineScreenCoordinator.swift | 14 +++-- ...innedEventsTimelineScreenCoordinator.swift | 11 ++-- ...rifiedUserSendFailureScreenViewModel.swift | 8 +-- .../RoomDetailsScreenCoordinator.swift | 3 +- .../RoomPollsHistoryScreenCoordinator.swift | 3 +- .../RoomScreen/RoomScreenCoordinator.swift | 12 ++-- .../OIDCAccountSettingsPresenter.swift | 4 +- .../DeveloperOptionsScreenCoordinator.swift | 6 +- ...otificationSettingsScreenCoordinator.swift | 3 +- .../StartChatScreenCoordinator.swift | 9 ++- .../ThreadTimelineScreenCoordinator.swift | 8 ++- .../UITests/UITestsAppCoordinator.swift | 57 +++++++++++++------ 23 files changed, 138 insertions(+), 69 deletions(-) diff --git a/ElementX/Sources/Application/AppCoordinator.swift b/ElementX/Sources/Application/AppCoordinator.swift index a225fe842..4df113964 100644 --- a/ElementX/Sources/Application/AppCoordinator.swift +++ b/ElementX/Sources/Application/AppCoordinator.swift @@ -612,6 +612,7 @@ class AppCoordinator: AppCoordinatorProtocol, AuthenticationFlowCoordinatorDeleg let parameters = SoftLogoutScreenCoordinatorParameters(authenticationService: authenticationService, credentials: credentials, keyBackupNeeded: false, + appSettings: appSettings, userIndicatorController: ServiceLocator.shared.userIndicatorController) let coordinator = SoftLogoutScreenCoordinator(parameters: parameters) self.softLogoutCoordinator = coordinator @@ -769,7 +770,9 @@ class AppCoordinator: AppCoordinatorProtocol, AuthenticationFlowCoordinatorDeleg let callScreenCoordinator = CallScreenCoordinator(parameters: .init(elementCallService: elementCallService, configuration: configuration, allowPictureInPicture: false, - appHooks: appHooks)) + appSettings: appSettings, + appHooks: appHooks, + analytics: ServiceLocator.shared.analytics)) callScreenCoordinator.actions .sink { [weak self] action in diff --git a/ElementX/Sources/FlowCoordinators/ChatsFlowCoordinator.swift b/ElementX/Sources/FlowCoordinators/ChatsFlowCoordinator.swift index e6758418c..5ade3a7bc 100644 --- a/ElementX/Sources/FlowCoordinators/ChatsFlowCoordinator.swift +++ b/ElementX/Sources/FlowCoordinators/ChatsFlowCoordinator.swift @@ -518,7 +518,8 @@ class ChatsFlowCoordinator: FlowCoordinatorProtocol { navigationStackCoordinator: startChatNavigationStackCoordinator, userDiscoveryService: userDiscoveryService, mediaUploadingPreprocessor: MediaUploadingPreprocessor(appSettings: flowParameters.appSettings), - appSettings: flowParameters.appSettings) + appSettings: flowParameters.appSettings, + analytics: flowParameters.analytics) let coordinator = StartChatScreenCoordinator(parameters: parameters) coordinator.actions.sink { [weak self] action in @@ -578,7 +579,9 @@ class ChatsFlowCoordinator: FlowCoordinatorProtocol { let callScreenCoordinator = CallScreenCoordinator(parameters: .init(elementCallService: flowParameters.elementCallService, configuration: configuration, allowPictureInPicture: true, - appHooks: flowParameters.appHooks)) + appSettings: flowParameters.appSettings, + appHooks: flowParameters.appHooks, + analytics: flowParameters.analytics)) callScreenCoordinator.actions .sink { [weak self] action in @@ -652,6 +655,7 @@ class ChatsFlowCoordinator: FlowCoordinatorProtocol { private func startEncryptionResetFlow(animated: Bool) { let sheetNavigationStackCoordinator = NavigationStackCoordinator() let parameters = EncryptionResetFlowCoordinatorParameters(userSession: userSession, + appSettings: flowParameters.appSettings, userIndicatorController: flowParameters.userIndicatorController, navigationStackCoordinator: sheetNavigationStackCoordinator, windowManger: flowParameters.windowManager) diff --git a/ElementX/Sources/FlowCoordinators/EncryptionResetFlowCoordinator.swift b/ElementX/Sources/FlowCoordinators/EncryptionResetFlowCoordinator.swift index 0dce057d0..709420ca0 100644 --- a/ElementX/Sources/FlowCoordinators/EncryptionResetFlowCoordinator.swift +++ b/ElementX/Sources/FlowCoordinators/EncryptionResetFlowCoordinator.swift @@ -18,6 +18,7 @@ enum EncryptionResetFlowCoordinatorAction: Equatable { struct EncryptionResetFlowCoordinatorParameters { let userSession: UserSessionProtocol + let appSettings: AppSettings let userIndicatorController: UserIndicatorControllerProtocol let navigationStackCoordinator: NavigationStackCoordinator let windowManger: WindowManagerProtocol @@ -25,6 +26,7 @@ struct EncryptionResetFlowCoordinatorParameters { class EncryptionResetFlowCoordinator: FlowCoordinatorProtocol { private let userSession: UserSessionProtocol + private let appSettings: AppSettings private let userIndicatorController: UserIndicatorControllerProtocol private let navigationStackCoordinator: NavigationStackCoordinator @@ -59,6 +61,7 @@ class EncryptionResetFlowCoordinator: FlowCoordinatorProtocol { init(parameters: EncryptionResetFlowCoordinatorParameters) { userSession = parameters.userSession + appSettings = parameters.appSettings userIndicatorController = parameters.userIndicatorController navigationStackCoordinator = parameters.navigationStackCoordinator windowManager = parameters.windowManger @@ -152,7 +155,9 @@ class EncryptionResetFlowCoordinator: FlowCoordinatorProtocol { private func presentOIDCAuthorization(for url: URL) { // Note to anyone in the future if you come back here to make this open in Safari instead of a WAS. // As of iOS 16, there is an issue on the simulator with accessing the cookie but it works on a device. 🤷‍♂️ - accountSettingsPresenter = OIDCAccountSettingsPresenter(accountURL: url, presentationAnchor: windowManager.mainWindow) + accountSettingsPresenter = OIDCAccountSettingsPresenter(accountURL: url, + presentationAnchor: windowManager.mainWindow, + appSettings: appSettings) accountSettingsPresenter?.start() } } diff --git a/ElementX/Sources/FlowCoordinators/MediaEventsTimelineFlowCoordinator.swift b/ElementX/Sources/FlowCoordinators/MediaEventsTimelineFlowCoordinator.swift index 6fe225823..d06ee50da 100644 --- a/ElementX/Sources/FlowCoordinators/MediaEventsTimelineFlowCoordinator.swift +++ b/ElementX/Sources/FlowCoordinators/MediaEventsTimelineFlowCoordinator.swift @@ -81,6 +81,8 @@ class MediaEventsTimelineFlowCoordinator: FlowCoordinatorProtocol { mediaPlayerProvider: MediaPlayerProvider(), voiceMessageMediaManager: userSession.voiceMessageMediaManager, appMediator: flowParameters.appMediator, + appSettings: flowParameters.appSettings, + analytics: flowParameters.analytics, emojiProvider: flowParameters.emojiProvider, userIndicatorController: flowParameters.userIndicatorController, timelineControllerFactory: flowParameters.timelineControllerFactory, diff --git a/ElementX/Sources/FlowCoordinators/OnboardingFlowCoordinator.swift b/ElementX/Sources/FlowCoordinators/OnboardingFlowCoordinator.swift index ea7f1dada..b6fb1e821 100644 --- a/ElementX/Sources/FlowCoordinators/OnboardingFlowCoordinator.swift +++ b/ElementX/Sources/FlowCoordinators/OnboardingFlowCoordinator.swift @@ -313,6 +313,7 @@ class OnboardingFlowCoordinator: FlowCoordinatorProtocol { private func startEncryptionResetFlow() { let resetNavigationStackCoordinator = NavigationStackCoordinator() let coordinator = EncryptionResetFlowCoordinator(parameters: .init(userSession: userSession, + appSettings: appSettings, userIndicatorController: userIndicatorController, navigationStackCoordinator: resetNavigationStackCoordinator, windowManger: windowManager)) diff --git a/ElementX/Sources/FlowCoordinators/PinnedEventsTimelineFlowCoordinator.swift b/ElementX/Sources/FlowCoordinators/PinnedEventsTimelineFlowCoordinator.swift index a42750d35..6694267a8 100644 --- a/ElementX/Sources/FlowCoordinators/PinnedEventsTimelineFlowCoordinator.swift +++ b/ElementX/Sources/FlowCoordinators/PinnedEventsTimelineFlowCoordinator.swift @@ -67,9 +67,12 @@ class PinnedEventsTimelineFlowCoordinator: FlowCoordinatorProtocol { mediaPlayerProvider: MediaPlayerProvider(), voiceMessageMediaManager: userSession.voiceMessageMediaManager, appMediator: flowParameters.appMediator, + appSettings: flowParameters.appSettings, + analytics: flowParameters.analytics, emojiProvider: flowParameters.emojiProvider, timelineControllerFactory: flowParameters.timelineControllerFactory, - clientProxy: userSession.clientProxy)) + clientProxy: userSession.clientProxy, + userIndicatorController: flowParameters.userIndicatorController)) coordinator.actions .sink { [weak self] action in diff --git a/ElementX/Sources/FlowCoordinators/RoomFlowCoordinator.swift b/ElementX/Sources/FlowCoordinators/RoomFlowCoordinator.swift index a54888d56..48c0324bc 100644 --- a/ElementX/Sources/FlowCoordinators/RoomFlowCoordinator.swift +++ b/ElementX/Sources/FlowCoordinators/RoomFlowCoordinator.swift @@ -558,8 +558,10 @@ class RoomFlowCoordinator: FlowCoordinatorProtocol { appMediator: flowParameters.appMediator, appSettings: flowParameters.appSettings, appHooks: flowParameters.appHooks, + analytics: flowParameters.analytics, composerDraftService: composerDraftService, - timelineControllerFactory: flowParameters.timelineControllerFactory) + timelineControllerFactory: flowParameters.timelineControllerFactory, + userIndicatorController: flowParameters.userIndicatorController) let coordinator = RoomScreenCoordinator(parameters: parameters) coordinator.actions @@ -652,8 +654,10 @@ class RoomFlowCoordinator: FlowCoordinatorProtocol { completionSuggestionService: completionSuggestionService, appMediator: flowParameters.appMediator, appSettings: flowParameters.appSettings, + analytics: flowParameters.analytics, composerDraftService: composerDraftService, - timelineControllerFactory: flowParameters.timelineControllerFactory)) + timelineControllerFactory: flowParameters.timelineControllerFactory, + userIndicatorController: flowParameters.userIndicatorController)) coordinator.actions.sink { [weak self] action in guard let self else { return } @@ -779,7 +783,8 @@ class RoomFlowCoordinator: FlowCoordinatorProtocol { userIndicatorController: flowParameters.userIndicatorController, notificationSettings: userSession.clientProxy.notificationSettings, attributedStringBuilder: AttributedStringBuilder(mentionBuilder: MentionBuilder()), - appMediator: flowParameters.appMediator) + appMediator: flowParameters.appMediator, + appSettings: flowParameters.appSettings) let coordinator = RoomDetailsScreenCoordinator(parameters: params) coordinator.actions.sink { [weak self] action in guard let self else { return } @@ -1185,7 +1190,8 @@ class RoomFlowCoordinator: FlowCoordinatorProtocol { let parameters = RoomPollsHistoryScreenCoordinatorParameters(pollInteractionHandler: PollInteractionHandler(analyticsService: flowParameters.analytics, timelineController: timelineController), - timelineController: timelineController) + timelineController: timelineController, + userIndicatorController: flowParameters.userIndicatorController) let coordinator = RoomPollsHistoryScreenCoordinator(parameters: parameters) coordinator.actions .sink { [weak self] action in @@ -1322,7 +1328,8 @@ class RoomFlowCoordinator: FlowCoordinatorProtocol { let parameters = NotificationSettingsScreenCoordinatorParameters(navigationStackCoordinator: stackCoordinator, userSession: userSession, userNotificationCenter: UNUserNotificationCenter.current(), - isModallyPresented: true) + isModallyPresented: true, + appSettings: flowParameters.appSettings) let coordinator = NotificationSettingsScreenCoordinator(parameters: parameters) coordinator.actions.sink { [weak self] action in switch action { diff --git a/ElementX/Sources/FlowCoordinators/SettingsFlowCoordinator.swift b/ElementX/Sources/FlowCoordinators/SettingsFlowCoordinator.swift index 34549eb28..3cc7c06c8 100644 --- a/ElementX/Sources/FlowCoordinators/SettingsFlowCoordinator.swift +++ b/ElementX/Sources/FlowCoordinators/SettingsFlowCoordinator.swift @@ -185,7 +185,8 @@ class SettingsFlowCoordinator: FlowCoordinatorProtocol { let notificationParameters = NotificationSettingsScreenCoordinatorParameters(navigationStackCoordinator: navigationStackCoordinator, userSession: flowParameters.userSession, userNotificationCenter: UNUserNotificationCenter.current(), - isModallyPresented: false) + isModallyPresented: false, + appSettings: flowParameters.appSettings) let coordinator = NotificationSettingsScreenCoordinator(parameters: notificationParameters) navigationStackCoordinator.push(coordinator) } @@ -199,7 +200,7 @@ class SettingsFlowCoordinator: FlowCoordinatorProtocol { } private func presentDeveloperOptions() { - let coordinator = DeveloperOptionsScreenCoordinator() + let coordinator = DeveloperOptionsScreenCoordinator(appSettings: flowParameters.appSettings) coordinator.actions .sink { [weak self] action in @@ -240,7 +241,9 @@ class SettingsFlowCoordinator: FlowCoordinatorProtocol { private func presentAccountManagementURL(_ url: URL) { // Note to anyone in the future if you come back here to make this open in Safari instead of a WAS. // As of iOS 16, there is an issue on the simulator with accessing the cookie but it works on a device. 🤷‍♂️ - accountSettingsPresenter = OIDCAccountSettingsPresenter(accountURL: url, presentationAnchor: flowParameters.windowManager.mainWindow) + accountSettingsPresenter = OIDCAccountSettingsPresenter(accountURL: url, + presentationAnchor: flowParameters.windowManager.mainWindow, + appSettings: flowParameters.appSettings) accountSettingsPresenter?.start() } } diff --git a/ElementX/Sources/Screens/Authentication/SoftLogoutScreen/SoftLogoutScreenCoordinator.swift b/ElementX/Sources/Screens/Authentication/SoftLogoutScreen/SoftLogoutScreenCoordinator.swift index 9fccb0d0a..2c9a5eed3 100644 --- a/ElementX/Sources/Screens/Authentication/SoftLogoutScreen/SoftLogoutScreenCoordinator.swift +++ b/ElementX/Sources/Screens/Authentication/SoftLogoutScreen/SoftLogoutScreenCoordinator.swift @@ -12,6 +12,7 @@ struct SoftLogoutScreenCoordinatorParameters { let authenticationService: AuthenticationServiceProtocol let credentials: SoftLogoutScreenCredentials let keyBackupNeeded: Bool + let appSettings: AppSettings let userIndicatorController: UserIndicatorControllerProtocol } @@ -142,7 +143,7 @@ final class SoftLogoutScreenCoordinator: CoordinatorProtocol { stopLoading() let presenter = OIDCAuthenticationPresenter(authenticationService: parameters.authenticationService, - oidcRedirectURL: ServiceLocator.shared.settings.oidcRedirectURL, + oidcRedirectURL: parameters.appSettings.oidcRedirectURL, presentationAnchor: presentationAnchor, userIndicatorController: parameters.userIndicatorController) self.oidcPresenter = presenter diff --git a/ElementX/Sources/Screens/CallScreen/CallScreenCoordinator.swift b/ElementX/Sources/Screens/CallScreen/CallScreenCoordinator.swift index 7c42d2470..da67f967e 100644 --- a/ElementX/Sources/Screens/CallScreen/CallScreenCoordinator.swift +++ b/ElementX/Sources/Screens/CallScreen/CallScreenCoordinator.swift @@ -13,7 +13,9 @@ struct CallScreenCoordinatorParameters { let elementCallService: ElementCallServiceProtocol let configuration: ElementCallConfiguration let allowPictureInPicture: Bool + let appSettings: AppSettings let appHooks: AppHooks + let analytics: AnalyticsService } enum CallScreenCoordinatorAction { @@ -44,8 +46,8 @@ final class CallScreenCoordinator: CoordinatorProtocol { configuration: parameters.configuration, allowPictureInPicture: parameters.allowPictureInPicture, appHooks: parameters.appHooks, - appSettings: ServiceLocator.shared.settings, - analyticsService: ServiceLocator.shared.analytics) + appSettings: parameters.appSettings, + analyticsService: parameters.analytics) } func start() { diff --git a/ElementX/Sources/Screens/CreateRoom/CreateRoomCoordinator.swift b/ElementX/Sources/Screens/CreateRoom/CreateRoomCoordinator.swift index 0c5ba961d..c32dfbc8d 100644 --- a/ElementX/Sources/Screens/CreateRoom/CreateRoomCoordinator.swift +++ b/ElementX/Sources/Screens/CreateRoom/CreateRoomCoordinator.swift @@ -13,6 +13,8 @@ struct CreateRoomCoordinatorParameters { let userIndicatorController: UserIndicatorControllerProtocol let createRoomParameters: CurrentValuePublisher let selectedUsers: CurrentValuePublisher<[UserProfileProxy], Never> + let appSettings: AppSettings + let analytics: AnalyticsService } enum CreateRoomCoordinatorAction { @@ -36,9 +38,9 @@ final class CreateRoomCoordinator: CoordinatorProtocol { viewModel = CreateRoomViewModel(userSession: parameters.userSession, createRoomParameters: parameters.createRoomParameters, selectedUsers: parameters.selectedUsers, - analytics: ServiceLocator.shared.analytics, + analytics: parameters.analytics, userIndicatorController: parameters.userIndicatorController, - appSettings: ServiceLocator.shared.settings) + appSettings: parameters.appSettings) } func start() { diff --git a/ElementX/Sources/Screens/MediaEventsTimelineScreen/MediaEventsTimelineScreenCoordinator.swift b/ElementX/Sources/Screens/MediaEventsTimelineScreen/MediaEventsTimelineScreenCoordinator.swift index 2bef55beb..a8f438cbf 100644 --- a/ElementX/Sources/Screens/MediaEventsTimelineScreen/MediaEventsTimelineScreenCoordinator.swift +++ b/ElementX/Sources/Screens/MediaEventsTimelineScreen/MediaEventsTimelineScreenCoordinator.swift @@ -16,6 +16,8 @@ struct MediaEventsTimelineScreenCoordinatorParameters { let mediaPlayerProvider: MediaPlayerProviderProtocol let voiceMessageMediaManager: VoiceMessageMediaManagerProtocol let appMediator: AppMediatorProtocol + let appSettings: AppSettings + let analytics: AnalyticsService let emojiProvider: EmojiProviderProtocol let userIndicatorController: UserIndicatorControllerProtocol let timelineControllerFactory: TimelineControllerFactoryProtocol @@ -45,10 +47,10 @@ final class MediaEventsTimelineScreenCoordinator: CoordinatorProtocol { mediaProvider: parameters.mediaProvider, mediaPlayerProvider: parameters.mediaPlayerProvider, voiceMessageMediaManager: parameters.voiceMessageMediaManager, - userIndicatorController: ServiceLocator.shared.userIndicatorController, + userIndicatorController: parameters.userIndicatorController, appMediator: parameters.appMediator, - appSettings: ServiceLocator.shared.settings, - analyticsService: ServiceLocator.shared.analytics, + appSettings: parameters.appSettings, + analyticsService: parameters.analytics, emojiProvider: parameters.emojiProvider, timelineControllerFactory: parameters.timelineControllerFactory, clientProxy: parameters.clientProxy) @@ -58,10 +60,10 @@ final class MediaEventsTimelineScreenCoordinator: CoordinatorProtocol { mediaProvider: parameters.mediaProvider, mediaPlayerProvider: parameters.mediaPlayerProvider, voiceMessageMediaManager: parameters.voiceMessageMediaManager, - userIndicatorController: ServiceLocator.shared.userIndicatorController, + userIndicatorController: parameters.userIndicatorController, appMediator: parameters.appMediator, - appSettings: ServiceLocator.shared.settings, - analyticsService: ServiceLocator.shared.analytics, + appSettings: parameters.appSettings, + analyticsService: parameters.analytics, emojiProvider: parameters.emojiProvider, timelineControllerFactory: parameters.timelineControllerFactory, clientProxy: parameters.clientProxy) diff --git a/ElementX/Sources/Screens/PinnedEventsTimelineScreen/PinnedEventsTimelineScreenCoordinator.swift b/ElementX/Sources/Screens/PinnedEventsTimelineScreen/PinnedEventsTimelineScreenCoordinator.swift index ecb606ca4..2c3ccd10d 100644 --- a/ElementX/Sources/Screens/PinnedEventsTimelineScreen/PinnedEventsTimelineScreenCoordinator.swift +++ b/ElementX/Sources/Screens/PinnedEventsTimelineScreen/PinnedEventsTimelineScreenCoordinator.swift @@ -15,9 +15,12 @@ struct PinnedEventsTimelineScreenCoordinatorParameters { let mediaPlayerProvider: MediaPlayerProviderProtocol let voiceMessageMediaManager: VoiceMessageMediaManagerProtocol let appMediator: AppMediatorProtocol + let appSettings: AppSettings + let analytics: AnalyticsService let emojiProvider: EmojiProviderProtocol let timelineControllerFactory: TimelineControllerFactoryProtocol let clientProxy: ClientProxyProtocol + let userIndicatorController: UserIndicatorControllerProtocol } enum PinnedEventsTimelineScreenCoordinatorAction { @@ -43,16 +46,16 @@ final class PinnedEventsTimelineScreenCoordinator: CoordinatorProtocol { init(parameters: PinnedEventsTimelineScreenCoordinatorParameters) { self.parameters = parameters - viewModel = PinnedEventsTimelineScreenViewModel(analyticsService: ServiceLocator.shared.analytics) + viewModel = PinnedEventsTimelineScreenViewModel(analyticsService: parameters.analytics) timelineViewModel = TimelineViewModel(roomProxy: parameters.roomProxy, timelineController: parameters.timelineController, mediaProvider: parameters.mediaProvider, mediaPlayerProvider: parameters.mediaPlayerProvider, voiceMessageMediaManager: parameters.voiceMessageMediaManager, - userIndicatorController: ServiceLocator.shared.userIndicatorController, + userIndicatorController: parameters.userIndicatorController, appMediator: parameters.appMediator, - appSettings: ServiceLocator.shared.settings, - analyticsService: ServiceLocator.shared.analytics, + appSettings: parameters.appSettings, + analyticsService: parameters.analytics, emojiProvider: parameters.emojiProvider, timelineControllerFactory: parameters.timelineControllerFactory, clientProxy: parameters.clientProxy) diff --git a/ElementX/Sources/Screens/ResolveVerifiedUserSendFailureScreen/ResolveVerifiedUserSendFailureScreenViewModel.swift b/ElementX/Sources/Screens/ResolveVerifiedUserSendFailureScreen/ResolveVerifiedUserSendFailureScreenViewModel.swift index 256c14353..947b0b2f3 100644 --- a/ElementX/Sources/Screens/ResolveVerifiedUserSendFailureScreen/ResolveVerifiedUserSendFailureScreenViewModel.swift +++ b/ElementX/Sources/Screens/ResolveVerifiedUserSendFailureScreen/ResolveVerifiedUserSendFailureScreenViewModel.swift @@ -101,10 +101,10 @@ class ResolveVerifiedUserSendFailureScreenViewModel: ResolveVerifiedUserSendFail private static let failureIndicatorIdentifier = "\(ResolveVerifiedUserSendFailureScreenViewModel.self)-Failure" private func showFailureIndicator() { - ServiceLocator.shared.userIndicatorController.submitIndicator(UserIndicator(id: Self.failureIndicatorIdentifier, - type: .toast, - title: L10n.errorUnknown, - iconName: "xmark")) + userIndicatorController.submitIndicator(UserIndicator(id: Self.failureIndicatorIdentifier, + type: .toast, + title: L10n.errorUnknown, + iconName: "xmark")) } } diff --git a/ElementX/Sources/Screens/RoomDetailsScreen/RoomDetailsScreenCoordinator.swift b/ElementX/Sources/Screens/RoomDetailsScreen/RoomDetailsScreenCoordinator.swift index 0de434286..05916386b 100644 --- a/ElementX/Sources/Screens/RoomDetailsScreen/RoomDetailsScreenCoordinator.swift +++ b/ElementX/Sources/Screens/RoomDetailsScreen/RoomDetailsScreenCoordinator.swift @@ -17,6 +17,7 @@ struct RoomDetailsScreenCoordinatorParameters { let notificationSettings: NotificationSettingsProxyProtocol let attributedStringBuilder: AttributedStringBuilderProtocol let appMediator: AppMediatorProtocol + let appSettings: AppSettings } enum RoomDetailsScreenCoordinatorAction { @@ -56,7 +57,7 @@ final class RoomDetailsScreenCoordinator: CoordinatorProtocol { notificationSettingsProxy: parameters.notificationSettings, attributedStringBuilder: parameters.attributedStringBuilder, appMediator: parameters.appMediator, - appSettings: ServiceLocator.shared.settings) + appSettings: parameters.appSettings) } // MARK: - Public diff --git a/ElementX/Sources/Screens/RoomPollsHistoryScreen/RoomPollsHistoryScreenCoordinator.swift b/ElementX/Sources/Screens/RoomPollsHistoryScreen/RoomPollsHistoryScreenCoordinator.swift index e3ef4ac18..db717c3c9 100644 --- a/ElementX/Sources/Screens/RoomPollsHistoryScreen/RoomPollsHistoryScreenCoordinator.swift +++ b/ElementX/Sources/Screens/RoomPollsHistoryScreen/RoomPollsHistoryScreenCoordinator.swift @@ -11,6 +11,7 @@ import SwiftUI struct RoomPollsHistoryScreenCoordinatorParameters { let pollInteractionHandler: PollInteractionHandlerProtocol let timelineController: TimelineControllerProtocol + let userIndicatorController: UserIndicatorControllerProtocol } enum RoomPollsHistoryScreenCoordinatorAction { @@ -29,7 +30,7 @@ final class RoomPollsHistoryScreenCoordinator: CoordinatorProtocol { init(parameters: RoomPollsHistoryScreenCoordinatorParameters) { viewModel = RoomPollsHistoryScreenViewModel(pollInteractionHandler: parameters.pollInteractionHandler, timelineController: parameters.timelineController, - userIndicatorController: ServiceLocator.shared.userIndicatorController) + userIndicatorController: parameters.userIndicatorController) } func start() { diff --git a/ElementX/Sources/Screens/RoomScreen/RoomScreenCoordinator.swift b/ElementX/Sources/Screens/RoomScreen/RoomScreenCoordinator.swift index 584cc129e..99e41b376 100644 --- a/ElementX/Sources/Screens/RoomScreen/RoomScreenCoordinator.swift +++ b/ElementX/Sources/Screens/RoomScreen/RoomScreenCoordinator.swift @@ -26,8 +26,10 @@ struct RoomScreenCoordinatorParameters { let appMediator: AppMediatorProtocol let appSettings: AppSettings let appHooks: AppHooks + let analytics: AnalyticsService let composerDraftService: ComposerDraftServiceProtocol let timelineControllerFactory: TimelineControllerFactoryProtocol + let userIndicatorController: UserIndicatorControllerProtocol } enum RoomScreenCoordinatorAction { @@ -75,8 +77,8 @@ final class RoomScreenCoordinator: CoordinatorProtocol { appMediator: parameters.appMediator, appSettings: parameters.appSettings, appHooks: parameters.appHooks, - analyticsService: ServiceLocator.shared.analytics, - userIndicatorController: ServiceLocator.shared.userIndicatorController) + analyticsService: parameters.analytics, + userIndicatorController: parameters.userIndicatorController) timelineViewModel = TimelineViewModel(roomProxy: parameters.roomProxy, focussedEventID: parameters.focussedEvent?.eventID, @@ -84,10 +86,10 @@ final class RoomScreenCoordinator: CoordinatorProtocol { mediaProvider: parameters.mediaProvider, mediaPlayerProvider: parameters.mediaPlayerProvider, voiceMessageMediaManager: parameters.voiceMessageMediaManager, - userIndicatorController: ServiceLocator.shared.userIndicatorController, + userIndicatorController: parameters.userIndicatorController, appMediator: parameters.appMediator, appSettings: parameters.appSettings, - analyticsService: ServiceLocator.shared.analytics, + analyticsService: parameters.analytics, emojiProvider: parameters.emojiProvider, timelineControllerFactory: parameters.timelineControllerFactory, clientProxy: parameters.clientProxy) @@ -103,7 +105,7 @@ final class RoomScreenCoordinator: CoordinatorProtocol { mediaProvider: parameters.mediaProvider, mentionDisplayHelper: ComposerMentionDisplayHelper(timelineContext: timelineViewModel.context), appSettings: parameters.appSettings, - analyticsService: ServiceLocator.shared.analytics, + analyticsService: parameters.analytics, composerDraftService: parameters.composerDraftService) self.composerViewModel = composerViewModel } diff --git a/ElementX/Sources/Screens/Settings/AccountSettings/OIDCAccountSettingsPresenter.swift b/ElementX/Sources/Screens/Settings/AccountSettings/OIDCAccountSettingsPresenter.swift index b0af707ba..f4e1505b0 100644 --- a/ElementX/Sources/Screens/Settings/AccountSettings/OIDCAccountSettingsPresenter.swift +++ b/ElementX/Sources/Screens/Settings/AccountSettings/OIDCAccountSettingsPresenter.swift @@ -19,10 +19,10 @@ class OIDCAccountSettingsPresenter: NSObject { private let presentationAnchor: UIWindow private let oidcRedirectURL: URL - init(accountURL: URL, presentationAnchor: UIWindow) { + init(accountURL: URL, presentationAnchor: UIWindow, appSettings: AppSettings) { self.accountURL = accountURL self.presentationAnchor = presentationAnchor - oidcRedirectURL = ServiceLocator.shared.settings.oidcRedirectURL + oidcRedirectURL = appSettings.oidcRedirectURL super.init() } diff --git a/ElementX/Sources/Screens/Settings/DeveloperOptionsScreen/DeveloperOptionsScreenCoordinator.swift b/ElementX/Sources/Screens/Settings/DeveloperOptionsScreen/DeveloperOptionsScreenCoordinator.swift index 415b47d5c..22c2a5aa2 100644 --- a/ElementX/Sources/Screens/Settings/DeveloperOptionsScreen/DeveloperOptionsScreenCoordinator.swift +++ b/ElementX/Sources/Screens/Settings/DeveloperOptionsScreen/DeveloperOptionsScreenCoordinator.swift @@ -22,9 +22,9 @@ final class DeveloperOptionsScreenCoordinator: CoordinatorProtocol { actionsSubject.eraseToAnyPublisher() } - init() { - viewModel = DeveloperOptionsScreenViewModel(developerOptions: ServiceLocator.shared.settings, - elementCallBaseURL: ServiceLocator.shared.settings.elementCallBaseURL) + init(appSettings: AppSettings) { + viewModel = DeveloperOptionsScreenViewModel(developerOptions: appSettings, + elementCallBaseURL: appSettings.elementCallBaseURL) viewModel.actions .sink { [weak self] action in diff --git a/ElementX/Sources/Screens/Settings/NotificationSettingsScreen/NotificationSettingsScreenCoordinator.swift b/ElementX/Sources/Screens/Settings/NotificationSettingsScreen/NotificationSettingsScreenCoordinator.swift index 48fcda51a..97ba4ac99 100644 --- a/ElementX/Sources/Screens/Settings/NotificationSettingsScreen/NotificationSettingsScreenCoordinator.swift +++ b/ElementX/Sources/Screens/Settings/NotificationSettingsScreen/NotificationSettingsScreenCoordinator.swift @@ -13,6 +13,7 @@ struct NotificationSettingsScreenCoordinatorParameters { let userSession: UserSessionProtocol let userNotificationCenter: UserNotificationCenterProtocol let isModallyPresented: Bool + let appSettings: AppSettings } enum NotificationSettingsScreenCoordinatorAction { @@ -36,7 +37,7 @@ final class NotificationSettingsScreenCoordinator: CoordinatorProtocol { init(parameters: NotificationSettingsScreenCoordinatorParameters) { self.parameters = parameters - viewModel = NotificationSettingsScreenViewModel(appSettings: ServiceLocator.shared.settings, + viewModel = NotificationSettingsScreenViewModel(appSettings: parameters.appSettings, userNotificationCenter: parameters.userNotificationCenter, notificationSettingsProxy: parameters.userSession.clientProxy.notificationSettings, isModallyPresented: parameters.isModallyPresented) diff --git a/ElementX/Sources/Screens/StartChatScreen/StartChatScreenCoordinator.swift b/ElementX/Sources/Screens/StartChatScreen/StartChatScreenCoordinator.swift index 78fb3e416..bdee4a4e4 100644 --- a/ElementX/Sources/Screens/StartChatScreen/StartChatScreenCoordinator.swift +++ b/ElementX/Sources/Screens/StartChatScreen/StartChatScreenCoordinator.swift @@ -16,6 +16,7 @@ struct StartChatScreenCoordinatorParameters { let userDiscoveryService: UserDiscoveryServiceProtocol let mediaUploadingPreprocessor: MediaUploadingPreprocessor let appSettings: AppSettings + let analytics: AnalyticsService } enum StartChatScreenCoordinatorAction { @@ -48,10 +49,10 @@ final class StartChatScreenCoordinator: CoordinatorProtocol { self.parameters = parameters viewModel = StartChatScreenViewModel(userSession: parameters.userSession, - analytics: ServiceLocator.shared.analytics, + analytics: parameters.analytics, userIndicatorController: parameters.userIndicatorController, userDiscoveryService: parameters.userDiscoveryService, - appSettings: ServiceLocator.shared.settings) + appSettings: parameters.appSettings) } func start() { @@ -114,7 +115,9 @@ final class StartChatScreenCoordinator: CoordinatorProtocol { let createParameters = CreateRoomCoordinatorParameters(userSession: parameters.userSession, userIndicatorController: parameters.userIndicatorController, createRoomParameters: createRoomParametersPublisher, - selectedUsers: selectedUsersPublisher) + selectedUsers: selectedUsersPublisher, + appSettings: parameters.appSettings, + analytics: parameters.analytics) let coordinator = CreateRoomCoordinator(parameters: createParameters) coordinator.actions.sink { [weak self] action in guard let self else { return } diff --git a/ElementX/Sources/Screens/ThreadTimelineScreen/ThreadTimelineScreenCoordinator.swift b/ElementX/Sources/Screens/ThreadTimelineScreen/ThreadTimelineScreenCoordinator.swift index 74e16f74c..4afa181b7 100644 --- a/ElementX/Sources/Screens/ThreadTimelineScreen/ThreadTimelineScreenCoordinator.swift +++ b/ElementX/Sources/Screens/ThreadTimelineScreen/ThreadTimelineScreenCoordinator.swift @@ -21,8 +21,10 @@ struct ThreadTimelineScreenCoordinatorParameters { let completionSuggestionService: CompletionSuggestionServiceProtocol let appMediator: AppMediatorProtocol let appSettings: AppSettings + let analytics: AnalyticsService let composerDraftService: ComposerDraftServiceProtocol let timelineControllerFactory: TimelineControllerFactoryProtocol + let userIndicatorController: UserIndicatorControllerProtocol } enum ThreadTimelineScreenCoordinatorAction { @@ -61,10 +63,10 @@ final class ThreadTimelineScreenCoordinator: CoordinatorProtocol { mediaProvider: parameters.mediaProvider, mediaPlayerProvider: parameters.mediaPlayerProvider, voiceMessageMediaManager: parameters.voiceMessageMediaManager, - userIndicatorController: ServiceLocator.shared.userIndicatorController, + userIndicatorController: parameters.userIndicatorController, appMediator: parameters.appMediator, appSettings: parameters.appSettings, - analyticsService: ServiceLocator.shared.analytics, + analyticsService: parameters.analytics, emojiProvider: parameters.emojiProvider, timelineControllerFactory: parameters.timelineControllerFactory, clientProxy: parameters.clientProxy) @@ -81,7 +83,7 @@ final class ThreadTimelineScreenCoordinator: CoordinatorProtocol { mediaProvider: parameters.mediaProvider, mentionDisplayHelper: ComposerMentionDisplayHelper(timelineContext: timelineViewModel.context), appSettings: parameters.appSettings, - analyticsService: ServiceLocator.shared.analytics, + analyticsService: parameters.analytics, composerDraftService: parameters.composerDraftService) } diff --git a/ElementX/Sources/UITests/UITestsAppCoordinator.swift b/ElementX/Sources/UITests/UITestsAppCoordinator.swift index 4e7e17de5..05e1aaeaf 100644 --- a/ElementX/Sources/UITests/UITestsAppCoordinator.swift +++ b/ElementX/Sources/UITests/UITestsAppCoordinator.swift @@ -272,8 +272,10 @@ class MockScreen: Identifiable { appMediator: AppMediatorMock.default, appSettings: ServiceLocator.shared.settings, appHooks: AppHooks(), + analytics: ServiceLocator.shared.analytics, composerDraftService: ComposerDraftServiceMock(.init()), - timelineControllerFactory: TimelineControllerFactoryMock(.init())) + timelineControllerFactory: TimelineControllerFactoryMock(.init()), + userIndicatorController: UserIndicatorControllerMock()) let coordinator = RoomScreenCoordinator(parameters: parameters) navigationStackCoordinator.setRootCoordinator(coordinator) return navigationStackCoordinator @@ -293,8 +295,10 @@ class MockScreen: Identifiable { appMediator: AppMediatorMock.default, appSettings: ServiceLocator.shared.settings, appHooks: AppHooks(), + analytics: ServiceLocator.shared.analytics, composerDraftService: ComposerDraftServiceMock(.init()), - timelineControllerFactory: TimelineControllerFactoryMock(.init())) + timelineControllerFactory: TimelineControllerFactoryMock(.init()), + userIndicatorController: UserIndicatorControllerMock()) let coordinator = RoomScreenCoordinator(parameters: parameters) navigationStackCoordinator.setRootCoordinator(coordinator) return navigationStackCoordinator @@ -314,8 +318,9 @@ class MockScreen: Identifiable { appMediator: AppMediatorMock.default, appSettings: ServiceLocator.shared.settings, appHooks: AppHooks(), + analytics: ServiceLocator.shared.analytics, composerDraftService: ComposerDraftServiceMock(.init()), - timelineControllerFactory: TimelineControllerFactoryMock(.init())) + timelineControllerFactory: TimelineControllerFactoryMock(.init()), userIndicatorController: UserIndicatorControllerMock()) let coordinator = RoomScreenCoordinator(parameters: parameters) navigationStackCoordinator.setRootCoordinator(coordinator) return navigationStackCoordinator @@ -335,8 +340,9 @@ class MockScreen: Identifiable { appMediator: AppMediatorMock.default, appSettings: ServiceLocator.shared.settings, appHooks: AppHooks(), + analytics: ServiceLocator.shared.analytics, composerDraftService: ComposerDraftServiceMock(.init()), - timelineControllerFactory: TimelineControllerFactoryMock(.init())) + timelineControllerFactory: TimelineControllerFactoryMock(.init()), userIndicatorController: UserIndicatorControllerMock()) let coordinator = RoomScreenCoordinator(parameters: parameters) navigationStackCoordinator.setRootCoordinator(coordinator) return navigationStackCoordinator @@ -359,8 +365,9 @@ class MockScreen: Identifiable { appMediator: AppMediatorMock.default, appSettings: ServiceLocator.shared.settings, appHooks: AppHooks(), + analytics: ServiceLocator.shared.analytics, composerDraftService: ComposerDraftServiceMock(.init()), - timelineControllerFactory: TimelineControllerFactoryMock(.init())) + timelineControllerFactory: TimelineControllerFactoryMock(.init()), userIndicatorController: UserIndicatorControllerMock()) let coordinator = RoomScreenCoordinator(parameters: parameters) navigationStackCoordinator.setRootCoordinator(coordinator) @@ -383,8 +390,8 @@ class MockScreen: Identifiable { appMediator: AppMediatorMock.default, appSettings: ServiceLocator.shared.settings, appHooks: AppHooks(), - composerDraftService: ComposerDraftServiceMock(.init()), - timelineControllerFactory: TimelineControllerFactoryMock(.init())) + analytics: ServiceLocator.shared.analytics, + composerDraftService: ComposerDraftServiceMock(.init()), timelineControllerFactory: TimelineControllerFactoryMock(.init()), userIndicatorController: UserIndicatorControllerMock()) let coordinator = RoomScreenCoordinator(parameters: parameters) navigationStackCoordinator.setRootCoordinator(coordinator) @@ -407,8 +414,9 @@ class MockScreen: Identifiable { appMediator: AppMediatorMock.default, appSettings: ServiceLocator.shared.settings, appHooks: AppHooks(), + analytics: ServiceLocator.shared.analytics, composerDraftService: ComposerDraftServiceMock(.init()), - timelineControllerFactory: TimelineControllerFactoryMock(.init())) + timelineControllerFactory: TimelineControllerFactoryMock(.init()), userIndicatorController: UserIndicatorControllerMock()) let coordinator = RoomScreenCoordinator(parameters: parameters) navigationStackCoordinator.setRootCoordinator(coordinator) @@ -432,8 +440,9 @@ class MockScreen: Identifiable { appMediator: AppMediatorMock.default, appSettings: ServiceLocator.shared.settings, appHooks: AppHooks(), + analytics: ServiceLocator.shared.analytics, composerDraftService: ComposerDraftServiceMock(.init()), - timelineControllerFactory: TimelineControllerFactoryMock(.init())) + timelineControllerFactory: TimelineControllerFactoryMock(.init()), userIndicatorController: UserIndicatorControllerMock()) let coordinator = RoomScreenCoordinator(parameters: parameters) navigationStackCoordinator.setRootCoordinator(coordinator) @@ -456,8 +465,9 @@ class MockScreen: Identifiable { appMediator: AppMediatorMock.default, appSettings: ServiceLocator.shared.settings, appHooks: AppHooks(), + analytics: ServiceLocator.shared.analytics, composerDraftService: ComposerDraftServiceMock(.init()), - timelineControllerFactory: TimelineControllerFactoryMock(.init())) + timelineControllerFactory: TimelineControllerFactoryMock(.init()), userIndicatorController: UserIndicatorControllerMock()) let coordinator = RoomScreenCoordinator(parameters: parameters) navigationStackCoordinator.setRootCoordinator(coordinator) @@ -479,8 +489,9 @@ class MockScreen: Identifiable { appMediator: AppMediatorMock.default, appSettings: ServiceLocator.shared.settings, appHooks: AppHooks(), + analytics: ServiceLocator.shared.analytics, composerDraftService: ComposerDraftServiceMock(.init()), - timelineControllerFactory: TimelineControllerFactoryMock(.init())) + timelineControllerFactory: TimelineControllerFactoryMock(.init()), userIndicatorController: UserIndicatorControllerMock()) let coordinator = RoomScreenCoordinator(parameters: parameters) navigationStackCoordinator.setRootCoordinator(coordinator) @@ -516,8 +527,9 @@ class MockScreen: Identifiable { appMediator: AppMediatorMock.default, appSettings: ServiceLocator.shared.settings, appHooks: AppHooks(), + analytics: ServiceLocator.shared.analytics, composerDraftService: ComposerDraftServiceMock(.init()), - timelineControllerFactory: TimelineControllerFactoryMock(.init())) + timelineControllerFactory: TimelineControllerFactoryMock(.init()), userIndicatorController: UserIndicatorControllerMock()) let coordinator = RoomScreenCoordinator(parameters: parameters) navigationStackCoordinator.setRootCoordinator(coordinator) @@ -540,8 +552,9 @@ class MockScreen: Identifiable { appMediator: AppMediatorMock.default, appSettings: ServiceLocator.shared.settings, appHooks: AppHooks(), + analytics: ServiceLocator.shared.analytics, composerDraftService: ComposerDraftServiceMock(.init()), - timelineControllerFactory: TimelineControllerFactoryMock(.init())) + timelineControllerFactory: TimelineControllerFactoryMock(.init()), userIndicatorController: UserIndicatorControllerMock()) let coordinator = RoomScreenCoordinator(parameters: parameters) navigationStackCoordinator.setRootCoordinator(coordinator) @@ -564,8 +577,9 @@ class MockScreen: Identifiable { appMediator: AppMediatorMock.default, appSettings: ServiceLocator.shared.settings, appHooks: AppHooks(), + analytics: ServiceLocator.shared.analytics, composerDraftService: ComposerDraftServiceMock(.init()), - timelineControllerFactory: TimelineControllerFactoryMock(.init())) + timelineControllerFactory: TimelineControllerFactoryMock(.init()), userIndicatorController: UserIndicatorControllerMock()) let coordinator = RoomScreenCoordinator(parameters: parameters) navigationStackCoordinator.setRootCoordinator(coordinator) @@ -647,7 +661,8 @@ class MockScreen: Identifiable { navigationStackCoordinator: navigationStackCoordinator, userDiscoveryService: userDiscoveryMock, mediaUploadingPreprocessor: MediaUploadingPreprocessor(appSettings: ServiceLocator.shared.settings), - appSettings: ServiceLocator.shared.settings) + appSettings: ServiceLocator.shared.settings, + analytics: ServiceLocator.shared.analytics) let coordinator = StartChatScreenCoordinator(parameters: parameters) navigationStackCoordinator.setRootCoordinator(coordinator) return navigationStackCoordinator @@ -663,7 +678,8 @@ class MockScreen: Identifiable { navigationStackCoordinator: navigationStackCoordinator, userDiscoveryService: userDiscoveryMock, mediaUploadingPreprocessor: MediaUploadingPreprocessor(appSettings: ServiceLocator.shared.settings), - appSettings: ServiceLocator.shared.settings)) + appSettings: ServiceLocator.shared.settings, + analytics: ServiceLocator.shared.analytics)) navigationStackCoordinator.setRootCoordinator(coordinator) return navigationStackCoordinator case .createRoom: @@ -675,7 +691,9 @@ class MockScreen: Identifiable { let parameters = CreateRoomCoordinatorParameters(userSession: mockUserSession, userIndicatorController: UserIndicatorControllerMock(), createRoomParameters: .init(createRoomParameters), - selectedUsers: .init(selectedUsers)) + selectedUsers: .init(selectedUsers), + appSettings: ServiceLocator.shared.settings, + analytics: ServiceLocator.shared.analytics) let coordinator = CreateRoomCoordinator(parameters: parameters) navigationStackCoordinator.setRootCoordinator(coordinator) return navigationStackCoordinator @@ -687,7 +705,9 @@ class MockScreen: Identifiable { let parameters = CreateRoomCoordinatorParameters(userSession: mockUserSession, userIndicatorController: UserIndicatorControllerMock(), createRoomParameters: .init(createRoomParameters), - selectedUsers: .init([])) + selectedUsers: .init([]), + appSettings: ServiceLocator.shared.settings, + analytics: ServiceLocator.shared.analytics) let coordinator = CreateRoomCoordinator(parameters: parameters) navigationStackCoordinator.setRootCoordinator(coordinator) return navigationStackCoordinator @@ -722,6 +742,7 @@ class MockScreen: Identifiable { let navigationStackCoordinator = NavigationStackCoordinator() let coordinator = EncryptionResetFlowCoordinator(parameters: .init(userSession: userSession, + appSettings: ServiceLocator.shared.settings, userIndicatorController: userIndicatorController, navigationStackCoordinator: navigationStackCoordinator, windowManger: windowManager))