Introduce flow parameters to simplify dependencies for child flows. (#4448)

This commit is contained in:
Doug
2025-08-27 13:56:06 +01:00
committed by GitHub
parent c140209e0c
commit dfb2425240
22 changed files with 456 additions and 586 deletions
@@ -19,21 +19,15 @@ enum ChatsFlowCoordinatorAction {
}
class ChatsFlowCoordinator: FlowCoordinatorProtocol {
private let userSession: UserSessionProtocol
private let navigationSplitCoordinator: NavigationSplitCoordinator
private let bugReportService: BugReportServiceProtocol
private let elementCallService: ElementCallServiceProtocol
private let appMediator: AppMediatorProtocol
private let appSettings: AppSettings
private let appHooks: AppHooks
private let analytics: AnalyticsService
private let notificationManager: NotificationManagerProtocol
private let flowParameters: CommonFlowParameters
private var userSession: UserSessionProtocol { flowParameters.userSession }
private let stateMachine: ChatsFlowCoordinatorStateMachine
// periphery:ignore - retaining purpose
private var roomFlowCoordinator: RoomFlowCoordinator?
private let timelineControllerFactory: TimelineControllerFactoryProtocol
// periphery:ignore - retaining purpose
private var bugReportFlowCoordinator: BugReportFlowCoordinator?
@@ -56,30 +50,12 @@ class ChatsFlowCoordinator: FlowCoordinatorProtocol {
actionsSubject.eraseToAnyPublisher()
}
init(userSession: UserSessionProtocol,
isNewLogin: Bool,
init(isNewLogin: Bool,
navigationSplitCoordinator: NavigationSplitCoordinator,
appLockService: AppLockServiceProtocol,
bugReportService: BugReportServiceProtocol,
elementCallService: ElementCallServiceProtocol,
timelineControllerFactory: TimelineControllerFactoryProtocol,
appMediator: AppMediatorProtocol,
appSettings: AppSettings,
appHooks: AppHooks,
analytics: AnalyticsService,
notificationManager: NotificationManagerProtocol,
stateMachineFactory: StateMachineFactoryProtocol) {
stateMachine = stateMachineFactory.makeChatsFlowStateMachine()
self.userSession = userSession
flowParameters: CommonFlowParameters) {
stateMachine = flowParameters.stateMachineFactory.makeChatsFlowStateMachine()
self.navigationSplitCoordinator = navigationSplitCoordinator
self.bugReportService = bugReportService
self.elementCallService = elementCallService
self.timelineControllerFactory = timelineControllerFactory
self.appMediator = appMediator
self.appSettings = appSettings
self.appHooks = appHooks
self.analytics = analytics
self.notificationManager = notificationManager
self.flowParameters = flowParameters
sidebarNavigationStackCoordinator = NavigationStackCoordinator(navigationSplitCoordinator: navigationSplitCoordinator)
detailNavigationStackCoordinator = NavigationStackCoordinator(navigationSplitCoordinator: navigationSplitCoordinator)
@@ -230,8 +206,8 @@ class ChatsFlowCoordinator: FlowCoordinatorProtocol {
case (.roomList, .feedbackScreen, .feedbackScreen):
bugReportFlowCoordinator = BugReportFlowCoordinator(parameters: .init(presentationMode: .sheet(sidebarNavigationStackCoordinator),
userIndicatorController: ServiceLocator.shared.userIndicatorController,
bugReportService: bugReportService,
userIndicatorController: flowParameters.userIndicatorController,
bugReportService: flowParameters.bugReportService,
userSession: userSession))
bugReportFlowCoordinator?.start()
case (.feedbackScreen, .dismissedFeedbackScreen, .roomList):
@@ -319,7 +295,7 @@ class ChatsFlowCoordinator: FlowCoordinatorProtocol {
case .receivedSyncUpdate:
Task {
let roomSummaries = self.userSession.clientProxy.staticRoomSummaryProvider.roomListPublisher.value
await self.notificationManager.removeDeliveredNotificationsForFullyReadRooms(roomSummaries)
await self.flowParameters.notificationManager.removeDeliveredNotificationsForFullyReadRooms(roomSummaries)
}
default:
break
@@ -327,7 +303,7 @@ class ChatsFlowCoordinator: FlowCoordinatorProtocol {
}
.store(in: &cancellables)
elementCallService.actions
flowParameters.elementCallService.actions
.receive(on: DispatchQueue.main)
.sink { [weak self] action in
switch action {
@@ -358,25 +334,25 @@ class ChatsFlowCoordinator: FlowCoordinatorProtocol {
case .withheldBySender: .OlmKeysNotSentError
}
analytics.trackError(context: nil,
domain: .E2EE,
name: errorName,
timeToDecryptMillis: timeToDecryptMs,
eventLocalAgeMillis: Int(truncatingIfNeeded: info.eventLocalAgeMillis),
isFederated: info.ownHomeserver != info.senderHomeserver,
isMatrixDotOrg: info.ownHomeserver == "matrix.org",
userTrustsOwnIdentity: info.userTrustsOwnIdentity,
wasVisibleToUser: nil)
flowParameters.analytics.trackError(context: nil,
domain: .E2EE,
name: errorName,
timeToDecryptMillis: timeToDecryptMs,
eventLocalAgeMillis: Int(truncatingIfNeeded: info.eventLocalAgeMillis),
isFederated: info.ownHomeserver != info.senderHomeserver,
isMatrixDotOrg: info.ownHomeserver == "matrix.org",
userTrustsOwnIdentity: info.userTrustsOwnIdentity,
wasVisibleToUser: nil)
}
private func presentHomeScreen() {
let parameters = HomeScreenCoordinatorParameters(userSession: userSession,
bugReportService: bugReportService,
bugReportService: flowParameters.bugReportService,
selectedRoomPublisher: selectedRoomSubject.asCurrentValuePublisher(),
appSettings: appSettings,
analyticsService: analytics,
notificationManager: notificationManager,
userIndicatorController: ServiceLocator.shared.userIndicatorController)
appSettings: flowParameters.appSettings,
analyticsService: flowParameters.analytics,
notificationManager: flowParameters.notificationManager,
userIndicatorController: flowParameters.userIndicatorController)
let coordinator = HomeScreenCoordinator(parameters: parameters)
coordinator.actions
@@ -431,7 +407,7 @@ class ChatsFlowCoordinator: FlowCoordinatorProtocol {
let navigationStackCoordinator = NavigationStackCoordinator()
let coordinator = ReportRoomScreenCoordinator(parameters: .init(roomProxy: roomProxy,
userIndicatorController: ServiceLocator.shared.userIndicatorController))
userIndicatorController: flowParameters.userIndicatorController))
coordinator.actionsPublisher.sink { [weak self] action in
guard let self else { return }
switch action {
@@ -456,7 +432,7 @@ class ChatsFlowCoordinator: FlowCoordinatorProtocol {
let coordinator = DeclineAndBlockScreenCoordinator(parameters: .init(userID: userID,
roomID: roomID,
clientProxy: userSession.clientProxy,
userIndicatorController: ServiceLocator.shared.userIndicatorController))
userIndicatorController: flowParameters.userIndicatorController))
coordinator.actionsPublisher.sink { [weak self] action in
guard let self else { return }
@@ -480,17 +456,9 @@ class ChatsFlowCoordinator: FlowCoordinatorProtocol {
entryPoint: RoomFlowCoordinatorEntryPoint,
animated: Bool) {
let coordinator = RoomFlowCoordinator(roomID: roomID,
userSession: userSession,
isChildFlow: false,
timelineControllerFactory: timelineControllerFactory,
navigationStackCoordinator: detailNavigationStackCoordinator,
emojiProvider: EmojiProvider(appSettings: appSettings),
ongoingCallRoomIDPublisher: elementCallService.ongoingCallRoomIDPublisher,
appMediator: appMediator,
appSettings: appSettings,
appHooks: appHooks,
analytics: analytics,
userIndicatorController: ServiceLocator.shared.userIndicatorController)
flowParameters: flowParameters)
coordinator.actions.sink { [weak self] action in
guard let self else { return }
@@ -528,7 +496,7 @@ class ChatsFlowCoordinator: FlowCoordinatorProtocol {
Task {
let _ = await userSession.clientProxy.trackRecentlyVisitedRoom(roomID)
await notificationManager.removeDeliveredMessageNotifications(for: roomID)
await flowParameters.notificationManager.removeDeliveredMessageNotifications(for: roomID)
}
}
@@ -544,13 +512,13 @@ class ChatsFlowCoordinator: FlowCoordinatorProtocol {
let startChatNavigationStackCoordinator = NavigationStackCoordinator()
let userDiscoveryService = UserDiscoveryService(clientProxy: userSession.clientProxy)
let parameters = StartChatScreenCoordinatorParameters(orientationManager: appMediator.windowManager,
let parameters = StartChatScreenCoordinatorParameters(orientationManager: flowParameters.windowManager,
userSession: userSession,
userIndicatorController: ServiceLocator.shared.userIndicatorController,
userIndicatorController: flowParameters.userIndicatorController,
navigationStackCoordinator: startChatNavigationStackCoordinator,
userDiscoveryService: userDiscoveryService,
mediaUploadingPreprocessor: MediaUploadingPreprocessor(appSettings: appSettings),
appSettings: appSettings)
mediaUploadingPreprocessor: MediaUploadingPreprocessor(appSettings: flowParameters.appSettings),
appSettings: flowParameters.appSettings)
let coordinator = StartChatScreenCoordinator(parameters: parameters)
coordinator.actions.sink { [weak self] action in
@@ -590,27 +558,27 @@ class ChatsFlowCoordinator: FlowCoordinatorProtocol {
}
private func presentCallScreen(roomProxy: JoinedRoomProxyProtocol) {
let colorScheme: ColorScheme = appMediator.windowManager.mainWindow.traitCollection.userInterfaceStyle == .light ? .light : .dark
let colorScheme: ColorScheme = flowParameters.windowManager.mainWindow.traitCollection.userInterfaceStyle == .light ? .light : .dark
presentCallScreen(configuration: .init(roomProxy: roomProxy,
clientProxy: userSession.clientProxy,
clientID: InfoPlistReader.main.bundleIdentifier,
elementCallBaseURL: appSettings.elementCallBaseURL,
elementCallBaseURLOverride: appSettings.elementCallBaseURLOverride,
elementCallBaseURL: flowParameters.appSettings.elementCallBaseURL,
elementCallBaseURLOverride: flowParameters.appSettings.elementCallBaseURLOverride,
colorScheme: colorScheme))
}
private var callScreenPictureInPictureController: AVPictureInPictureController?
private func presentCallScreen(configuration: ElementCallConfiguration) {
guard elementCallService.ongoingCallRoomIDPublisher.value != configuration.callRoomID else {
guard flowParameters.ongoingCallRoomIDPublisher.value != configuration.callRoomID else {
MXLog.info("Returning to existing call.")
callScreenPictureInPictureController?.stopPictureInPicture()
return
}
let callScreenCoordinator = CallScreenCoordinator(parameters: .init(elementCallService: elementCallService,
let callScreenCoordinator = CallScreenCoordinator(parameters: .init(elementCallService: flowParameters.elementCallService,
configuration: configuration,
allowPictureInPicture: true,
appHooks: appHooks))
appHooks: flowParameters.appHooks))
callScreenCoordinator.actions
.sink { [weak self] action in
@@ -633,7 +601,7 @@ class ChatsFlowCoordinator: FlowCoordinatorProtocol {
navigationSplitCoordinator.setOverlayCoordinator(callScreenCoordinator, animated: true)
analytics.track(screen: .RoomCall)
flowParameters.analytics.track(screen: .RoomCall)
}
private func hideCallScreenOverlay() {
@@ -661,7 +629,7 @@ class ChatsFlowCoordinator: FlowCoordinatorProtocol {
private func presentRecoveryKeyScreen(animated: Bool) {
let sheetNavigationStackCoordinator = NavigationStackCoordinator()
let parameters = SecureBackupRecoveryKeyScreenCoordinatorParameters(secureBackupController: userSession.clientProxy.secureBackupController,
userIndicatorController: ServiceLocator.shared.userIndicatorController,
userIndicatorController: flowParameters.userIndicatorController,
isModallyPresented: true)
let coordinator = SecureBackupRecoveryKeyScreenCoordinator(parameters: parameters)
@@ -684,9 +652,9 @@ class ChatsFlowCoordinator: FlowCoordinatorProtocol {
private func startEncryptionResetFlow(animated: Bool) {
let sheetNavigationStackCoordinator = NavigationStackCoordinator()
let parameters = EncryptionResetFlowCoordinatorParameters(userSession: userSession,
userIndicatorController: ServiceLocator.shared.userIndicatorController,
userIndicatorController: flowParameters.userIndicatorController,
navigationStackCoordinator: sheetNavigationStackCoordinator,
windowManger: appMediator.windowManager)
windowManger: flowParameters.windowManager)
let coordinator = EncryptionResetFlowCoordinator(parameters: parameters)
coordinator.actionsPublisher.sink { [weak self] action in
@@ -736,14 +704,14 @@ class ChatsFlowCoordinator: FlowCoordinatorProtocol {
let hostingController = UIHostingController(rootView: coordinator.toPresentable())
hostingController.view.backgroundColor = .clear
appMediator.windowManager.globalSearchWindow.rootViewController = hostingController
flowParameters.windowManager.globalSearchWindow.rootViewController = hostingController
appMediator.windowManager.showGlobalSearch()
flowParameters.windowManager.showGlobalSearch()
}
private func dismissGlobalSearch() {
appMediator.windowManager.globalSearchWindow.rootViewController = nil
appMediator.windowManager.hideGlobalSearch()
flowParameters.windowManager.globalSearchWindow.rootViewController = nil
flowParameters.windowManager.hideGlobalSearch()
globalSearchScreenCoordinator = nil
}
@@ -753,7 +721,7 @@ class ChatsFlowCoordinator: FlowCoordinatorProtocol {
private func presentRoomDirectorySearch() {
let coordinator = RoomDirectorySearchScreenCoordinator(parameters: .init(clientProxy: userSession.clientProxy,
mediaProvider: userSession.mediaProvider,
userIndicatorController: ServiceLocator.shared.userIndicatorController))
userIndicatorController: flowParameters.userIndicatorController))
coordinator.actionsPublisher.sink { [weak self] action in
guard let self else { return }
@@ -788,8 +756,8 @@ class ChatsFlowCoordinator: FlowCoordinatorProtocol {
isPresentedModally: true,
clientProxy: userSession.clientProxy,
mediaProvider: userSession.mediaProvider,
userIndicatorController: ServiceLocator.shared.userIndicatorController,
analytics: analytics)
userIndicatorController: flowParameters.userIndicatorController,
analytics: flowParameters.analytics)
let coordinator = UserProfileScreenCoordinator(parameters: parameters)
coordinator.actionsPublisher.sink { [weak self] action in
guard let self else { return }
@@ -864,21 +832,21 @@ class ChatsFlowCoordinator: FlowCoordinatorProtocol {
private static let failureIndicatorIdentifier = "\(ChatsFlowCoordinator.self)-Failure"
private func showLoadingIndicator(delay: Duration? = nil) {
ServiceLocator.shared.userIndicatorController.submitIndicator(UserIndicator(id: Self.loadingIndicatorIdentifier,
type: .modal,
title: L10n.commonLoading,
persistent: true),
delay: delay)
flowParameters.userIndicatorController.submitIndicator(UserIndicator(id: Self.loadingIndicatorIdentifier,
type: .modal,
title: L10n.commonLoading,
persistent: true),
delay: delay)
}
private func hideLoadingIndicator() {
ServiceLocator.shared.userIndicatorController.retractIndicatorWithId(Self.loadingIndicatorIdentifier)
flowParameters.userIndicatorController.retractIndicatorWithId(Self.loadingIndicatorIdentifier)
}
private func showFailureIndicator() {
ServiceLocator.shared.userIndicatorController.submitIndicator(UserIndicator(id: Self.failureIndicatorIdentifier,
type: .toast,
title: L10n.errorUnknown,
iconName: "xmark"))
flowParameters.userIndicatorController.submitIndicator(UserIndicator(id: Self.failureIndicatorIdentifier,
type: .toast,
title: L10n.errorUnknown,
iconName: "xmark"))
}
}
@@ -14,13 +14,11 @@ enum MediaEventsTimelineFlowCoordinatorAction {
}
class MediaEventsTimelineFlowCoordinator: FlowCoordinatorProtocol {
private let navigationStackCoordinator: NavigationStackCoordinator
private let userSession: UserSessionProtocol
private let timelineControllerFactory: TimelineControllerFactoryProtocol
private let roomProxy: JoinedRoomProxyProtocol
private let userIndicatorController: UserIndicatorControllerProtocol
private let appMediator: AppMediatorProtocol
private let emojiProvider: EmojiProviderProtocol
private let navigationStackCoordinator: NavigationStackCoordinator
private let flowParameters: CommonFlowParameters
private var userSession: UserSessionProtocol { flowParameters.userSession }
private let actionsSubject: PassthroughSubject<MediaEventsTimelineFlowCoordinatorAction, Never> = .init()
var actionsPublisher: AnyPublisher<MediaEventsTimelineFlowCoordinatorAction, Never> {
@@ -29,20 +27,12 @@ class MediaEventsTimelineFlowCoordinator: FlowCoordinatorProtocol {
private var cancellables = Set<AnyCancellable>()
init(navigationStackCoordinator: NavigationStackCoordinator,
userSession: UserSessionProtocol,
timelineControllerFactory: TimelineControllerFactoryProtocol,
roomProxy: JoinedRoomProxyProtocol,
userIndicatorController: UserIndicatorControllerProtocol,
appMediator: AppMediatorProtocol,
emojiProvider: EmojiProviderProtocol) {
self.navigationStackCoordinator = navigationStackCoordinator
self.userSession = userSession
self.timelineControllerFactory = timelineControllerFactory
init(roomProxy: JoinedRoomProxyProtocol,
navigationStackCoordinator: NavigationStackCoordinator,
flowParameters: CommonFlowParameters) {
self.roomProxy = roomProxy
self.userIndicatorController = userIndicatorController
self.appMediator = appMediator
self.emojiProvider = emojiProvider
self.navigationStackCoordinator = navigationStackCoordinator
self.flowParameters = flowParameters
}
func start() {
@@ -64,22 +54,22 @@ class MediaEventsTimelineFlowCoordinator: FlowCoordinatorProtocol {
attributedStringBuilder: AttributedStringBuilder(mentionBuilder: MentionBuilder()),
stateEventStringBuilder: RoomStateEventStringBuilder(userID: userSession.clientProxy.userID))
guard case let .success(mediaTimelineController) = await timelineControllerFactory.buildMessageFilteredTimelineController(focus: .live,
allowedMessageTypes: [.image, .video],
presentation: .mediaFilesScreen,
roomProxy: roomProxy,
timelineItemFactory: timelineItemFactory,
mediaProvider: userSession.mediaProvider) else {
guard case let .success(mediaTimelineController) = await flowParameters.timelineControllerFactory.buildMessageFilteredTimelineController(focus: .live,
allowedMessageTypes: [.image, .video],
presentation: .mediaFilesScreen,
roomProxy: roomProxy,
timelineItemFactory: timelineItemFactory,
mediaProvider: userSession.mediaProvider) else {
MXLog.error("Failed presenting media timeline")
return
}
guard case let .success(filesTimelineController) = await timelineControllerFactory.buildMessageFilteredTimelineController(focus: .live,
allowedMessageTypes: [.file, .audio],
presentation: .mediaFilesScreen,
roomProxy: roomProxy,
timelineItemFactory: timelineItemFactory,
mediaProvider: userSession.mediaProvider) else {
guard case let .success(filesTimelineController) = await flowParameters.timelineControllerFactory.buildMessageFilteredTimelineController(focus: .live,
allowedMessageTypes: [.file, .audio],
presentation: .mediaFilesScreen,
roomProxy: roomProxy,
timelineItemFactory: timelineItemFactory,
mediaProvider: userSession.mediaProvider) else {
MXLog.error("Failed presenting media timeline")
return
}
@@ -90,10 +80,10 @@ class MediaEventsTimelineFlowCoordinator: FlowCoordinatorProtocol {
mediaProvider: userSession.mediaProvider,
mediaPlayerProvider: MediaPlayerProvider(),
voiceMessageMediaManager: userSession.voiceMessageMediaManager,
appMediator: appMediator,
emojiProvider: emojiProvider,
userIndicatorController: userIndicatorController,
timelineControllerFactory: timelineControllerFactory,
appMediator: flowParameters.appMediator,
emojiProvider: flowParameters.emojiProvider,
userIndicatorController: flowParameters.userIndicatorController,
timelineControllerFactory: flowParameters.timelineControllerFactory,
clientProxy: userSession.clientProxy)
let coordinator = MediaEventsTimelineScreenCoordinator(parameters: parameters)
@@ -57,23 +57,18 @@ class OnboardingFlowCoordinator: FlowCoordinatorProtocol {
private var verificationStateCancellable: AnyCancellable?
init(userSession: UserSessionProtocol,
init(isNewLogin: Bool,
appLockService: AppLockServiceProtocol,
analyticsService: AnalyticsService,
appSettings: AppSettings,
notificationManager: NotificationManagerProtocol,
navigationStackCoordinator: NavigationStackCoordinator,
userIndicatorController: UserIndicatorControllerProtocol,
windowManager: WindowManagerProtocol,
isNewLogin: Bool) {
self.userSession = userSession
self.appLockService = appLockService
self.analyticsService = analyticsService
self.appSettings = appSettings
self.notificationManager = notificationManager
self.userIndicatorController = userIndicatorController
self.windowManager = windowManager
flowParameters: CommonFlowParameters) {
self.isNewLogin = isNewLogin
userSession = flowParameters.userSession
self.appLockService = appLockService
analyticsService = flowParameters.analytics
appSettings = flowParameters.appSettings
notificationManager = flowParameters.notificationManager
userIndicatorController = flowParameters.userIndicatorController
windowManager = flowParameters.windowManager
self.navigationStackCoordinator = navigationStackCoordinator
@@ -298,7 +293,7 @@ class OnboardingFlowCoordinator: FlowCoordinatorProtocol {
private func presentRecoveryKeyScreen() {
let parameters = SecureBackupRecoveryKeyScreenCoordinatorParameters(secureBackupController: userSession.clientProxy.secureBackupController,
userIndicatorController: ServiceLocator.shared.userIndicatorController,
userIndicatorController: userIndicatorController,
isModallyPresented: false)
let coordinator = SecureBackupRecoveryKeyScreenCoordinator(parameters: parameters)
@@ -16,14 +16,11 @@ enum PinnedEventsTimelineFlowCoordinatorAction {
}
class PinnedEventsTimelineFlowCoordinator: FlowCoordinatorProtocol {
private let navigationStackCoordinator: NavigationStackCoordinator
private let userSession: UserSessionProtocol
private let timelineControllerFactory: TimelineControllerFactoryProtocol
private let roomProxy: JoinedRoomProxyProtocol
private let userIndicatorController: UserIndicatorControllerProtocol
private let appSettings: AppSettings
private let appMediator: AppMediatorProtocol
private let emojiProvider: EmojiProviderProtocol
private let navigationStackCoordinator: NavigationStackCoordinator
private let flowParameters: CommonFlowParameters
private var userSession: UserSessionProtocol { flowParameters.userSession }
private let actionsSubject: PassthroughSubject<PinnedEventsTimelineFlowCoordinatorAction, Never> = .init()
var actionsPublisher: AnyPublisher<PinnedEventsTimelineFlowCoordinatorAction, Never> {
@@ -32,22 +29,12 @@ class PinnedEventsTimelineFlowCoordinator: FlowCoordinatorProtocol {
private var cancellables = Set<AnyCancellable>()
init(navigationStackCoordinator: NavigationStackCoordinator,
userSession: UserSessionProtocol,
timelineControllerFactory: TimelineControllerFactoryProtocol,
roomProxy: JoinedRoomProxyProtocol,
userIndicatorController: UserIndicatorControllerProtocol,
appSettings: AppSettings,
appMediator: AppMediatorProtocol,
emojiProvider: EmojiProviderProtocol) {
self.navigationStackCoordinator = navigationStackCoordinator
self.userSession = userSession
self.timelineControllerFactory = timelineControllerFactory
init(roomProxy: JoinedRoomProxyProtocol,
navigationStackCoordinator: NavigationStackCoordinator,
flowParameters: CommonFlowParameters) {
self.roomProxy = roomProxy
self.userIndicatorController = userIndicatorController
self.appSettings = appSettings
self.appMediator = appMediator
self.emojiProvider = emojiProvider
self.navigationStackCoordinator = navigationStackCoordinator
self.flowParameters = flowParameters
}
func start() {
@@ -68,9 +55,9 @@ class PinnedEventsTimelineFlowCoordinator: FlowCoordinatorProtocol {
attributedStringBuilder: AttributedStringBuilder(mentionBuilder: MentionBuilder()),
stateEventStringBuilder: RoomStateEventStringBuilder(userID: userID))
guard case let .success(timelineController) = await timelineControllerFactory.buildPinnedEventsTimelineController(roomProxy: roomProxy,
timelineItemFactory: timelineItemFactory,
mediaProvider: userSession.mediaProvider) else {
guard case let .success(timelineController) = await flowParameters.timelineControllerFactory.buildPinnedEventsTimelineController(roomProxy: roomProxy,
timelineItemFactory: timelineItemFactory,
mediaProvider: userSession.mediaProvider) else {
fatalError("This can never fail because we allow this view to be presented only when the timeline is fully loaded and not nil")
}
@@ -79,9 +66,9 @@ class PinnedEventsTimelineFlowCoordinator: FlowCoordinatorProtocol {
mediaProvider: userSession.mediaProvider,
mediaPlayerProvider: MediaPlayerProvider(),
voiceMessageMediaManager: userSession.voiceMessageMediaManager,
appMediator: appMediator,
emojiProvider: emojiProvider,
timelineControllerFactory: timelineControllerFactory,
appMediator: flowParameters.appMediator,
emojiProvider: flowParameters.emojiProvider,
timelineControllerFactory: flowParameters.timelineControllerFactory,
clientProxy: userSession.clientProxy))
coordinator.actions
@@ -110,8 +97,8 @@ class PinnedEventsTimelineFlowCoordinator: FlowCoordinatorProtocol {
let stackCoordinator = NavigationStackCoordinator()
let params = StaticLocationScreenCoordinatorParameters(interactionMode: .viewOnly(geoURI: geoURI, description: description),
mapURLBuilder: appSettings.mapTilerConfiguration,
appMediator: appMediator)
mapURLBuilder: flowParameters.appSettings.mapTilerConfiguration,
appMediator: flowParameters.appMediator)
let coordinator = StaticLocationScreenCoordinator(parameters: params)
coordinator.actions.sink { [weak self] action in
@@ -140,7 +127,7 @@ class PinnedEventsTimelineFlowCoordinator: FlowCoordinatorProtocol {
clientProxy: userSession.clientProxy,
roomSummaryProvider: roomSummaryProvider,
mediaProvider: userSession.mediaProvider,
userIndicatorController: userIndicatorController)
userIndicatorController: flowParameters.userIndicatorController)
let coordinator = MessageForwardingScreenCoordinator(parameters: parameters)
coordinator.actions.sink { [weak self] action in
@@ -56,17 +56,11 @@ struct FocusEvent: Hashable {
// swiftlint:disable:next type_body_length
class RoomFlowCoordinator: FlowCoordinatorProtocol {
private let roomID: String
private let userSession: UserSessionProtocol
private let isChildFlow: Bool
private let timelineControllerFactory: TimelineControllerFactoryProtocol
private let navigationStackCoordinator: NavigationStackCoordinator
private let emojiProvider: EmojiProviderProtocol
private let ongoingCallRoomIDPublisher: CurrentValuePublisher<String?, Never>
private let appMediator: AppMediatorProtocol
private let appSettings: AppSettings
private let appHooks: AppHooks
private let analytics: AnalyticsService
private let userIndicatorController: UserIndicatorControllerProtocol
private let flowParameters: CommonFlowParameters
private var userSession: UserSessionProtocol { flowParameters.userSession }
private var roomProxy: JoinedRoomProxyProtocol!
@@ -94,33 +88,17 @@ class RoomFlowCoordinator: FlowCoordinatorProtocol {
private var timelineController: TimelineControllerProtocol?
init(roomID: String,
userSession: UserSessionProtocol,
isChildFlow: Bool,
timelineControllerFactory: TimelineControllerFactoryProtocol,
navigationStackCoordinator: NavigationStackCoordinator,
emojiProvider: EmojiProviderProtocol,
ongoingCallRoomIDPublisher: CurrentValuePublisher<String?, Never>,
appMediator: AppMediatorProtocol,
appSettings: AppSettings,
appHooks: AppHooks,
analytics: AnalyticsService,
userIndicatorController: UserIndicatorControllerProtocol) {
flowParameters: CommonFlowParameters) {
self.roomID = roomID
self.userSession = userSession
self.isChildFlow = isChildFlow
self.timelineControllerFactory = timelineControllerFactory
self.navigationStackCoordinator = navigationStackCoordinator
self.emojiProvider = emojiProvider
self.ongoingCallRoomIDPublisher = ongoingCallRoomIDPublisher
self.appMediator = appMediator
self.appSettings = appSettings
self.appHooks = appHooks
self.analytics = analytics
self.userIndicatorController = userIndicatorController
self.flowParameters = flowParameters
setupStateMachine()
analytics.signpost.beginRoomFlow(roomID)
flowParameters.analytics.signpost.beginRoomFlow(roomID)
}
// MARK: - FlowCoordinatorProtocol
@@ -220,8 +198,8 @@ class RoomFlowCoordinator: FlowCoordinatorProtocol {
let parameters = RoomChangeRolesScreenCoordinatorParameters(mode: .owner,
roomProxy: roomProxy,
mediaProvider: userSession.mediaProvider,
userIndicatorController: userIndicatorController,
analytics: analytics)
userIndicatorController: flowParameters.userIndicatorController,
analytics: flowParameters.analytics)
let stackCoordinator = NavigationStackCoordinator()
let coordinator = RoomChangeRolesScreenCoordinator(parameters: parameters)
coordinator.actionsPublisher.sink { [weak self] action in
@@ -519,7 +497,7 @@ class RoomFlowCoordinator: FlowCoordinatorProtocol {
// Flag the room as read on entering, the timeline will take care of the read receipts
Task { await roomProxy.flagAsUnread(false) }
analytics.trackViewRoom(isDM: roomProxy.infoPublisher.value.isDirect, isSpace: roomProxy.infoPublisher.value.isSpace)
flowParameters.analytics.trackViewRoom(isDM: roomProxy.infoPublisher.value.isDirect, isSpace: roomProxy.infoPublisher.value.isSpace)
let coordinator = makeRoomScreenCoordinator(presentationAction: presentationAction, animated: animated)
roomScreenCoordinator = coordinator
@@ -554,10 +532,10 @@ class RoomFlowCoordinator: FlowCoordinatorProtocol {
let timelineItemFactory = RoomTimelineItemFactory(userID: userID,
attributedStringBuilder: AttributedStringBuilder(mentionBuilder: MentionBuilder()),
stateEventStringBuilder: RoomStateEventStringBuilder(userID: userID))
let timelineController = timelineControllerFactory.buildTimelineController(roomProxy: roomProxy,
initialFocussedEventID: presentationAction?.focusedEvent?.eventID,
timelineItemFactory: timelineItemFactory,
mediaProvider: userSession.mediaProvider)
let timelineController = flowParameters.timelineControllerFactory.buildTimelineController(roomProxy: roomProxy,
initialFocussedEventID: presentationAction?.focusedEvent?.eventID,
timelineItemFactory: timelineItemFactory,
mediaProvider: userSession.mediaProvider)
self.timelineController = timelineController
let completionSuggestionService = CompletionSuggestionService(roomProxy: roomProxy,
@@ -574,14 +552,14 @@ class RoomFlowCoordinator: FlowCoordinatorProtocol {
mediaProvider: userSession.mediaProvider,
mediaPlayerProvider: MediaPlayerProvider(),
voiceMessageMediaManager: userSession.voiceMessageMediaManager,
emojiProvider: emojiProvider,
emojiProvider: flowParameters.emojiProvider,
completionSuggestionService: completionSuggestionService,
ongoingCallRoomIDPublisher: ongoingCallRoomIDPublisher,
appMediator: appMediator,
appSettings: appSettings,
appHooks: appHooks,
ongoingCallRoomIDPublisher: flowParameters.ongoingCallRoomIDPublisher,
appMediator: flowParameters.appMediator,
appSettings: flowParameters.appSettings,
appHooks: flowParameters.appHooks,
composerDraftService: composerDraftService,
timelineControllerFactory: timelineControllerFactory)
timelineControllerFactory: flowParameters.timelineControllerFactory)
let coordinator = RoomScreenCoordinator(parameters: parameters)
coordinator.actions
@@ -650,10 +628,10 @@ class RoomFlowCoordinator: FlowCoordinatorProtocol {
fatalError("Invalid thread event ID")
}
guard case let .success(timelineController) = await timelineControllerFactory.buildThreadTimelineController(eventID: threadRootEventID,
roomProxy: roomProxy,
timelineItemFactory: timelineItemFactory,
mediaProvider: userSession.mediaProvider) else {
guard case let .success(timelineController) = await flowParameters.timelineControllerFactory.buildThreadTimelineController(eventID: threadRootEventID,
roomProxy: roomProxy,
timelineItemFactory: timelineItemFactory,
mediaProvider: userSession.mediaProvider) else {
MXLog.error("Failed presenting media timeline")
return
}
@@ -670,12 +648,12 @@ class RoomFlowCoordinator: FlowCoordinatorProtocol {
mediaProvider: userSession.mediaProvider,
mediaPlayerProvider: MediaPlayerProvider(),
voiceMessageMediaManager: userSession.voiceMessageMediaManager,
emojiProvider: emojiProvider,
emojiProvider: flowParameters.emojiProvider,
completionSuggestionService: completionSuggestionService,
appMediator: appMediator,
appSettings: appSettings,
appMediator: flowParameters.appMediator,
appSettings: flowParameters.appSettings,
composerDraftService: composerDraftService,
timelineControllerFactory: timelineControllerFactory))
timelineControllerFactory: flowParameters.timelineControllerFactory))
coordinator.actions.sink { [weak self] action in
guard let self else { return }
@@ -723,8 +701,8 @@ class RoomFlowCoordinator: FlowCoordinatorProtocol {
via: via,
clientProxy: userSession.clientProxy,
mediaProvider: userSession.mediaProvider,
userIndicatorController: userIndicatorController,
appSettings: appSettings))
userIndicatorController: flowParameters.userIndicatorController,
appSettings: flowParameters.appSettings))
joinRoomScreenCoordinator = coordinator
@@ -742,9 +720,9 @@ class RoomFlowCoordinator: FlowCoordinatorProtocol {
await storeAndSubscribeToRoomProxy(roomProxy)
stateMachine.tryEvent(.presentRoom(presentationAction: nil), userInfo: EventUserInfo(animated: animated))
analytics.trackJoinedRoom(isDM: roomProxy.infoPublisher.value.isDirect,
isSpace: roomProxy.infoPublisher.value.isSpace,
activeMemberCount: UInt(roomProxy.infoPublisher.value.activeMembersCount))
flowParameters.analytics.trackJoinedRoom(isDM: roomProxy.infoPublisher.value.isDirect,
isSpace: roomProxy.infoPublisher.value.isSpace,
activeMemberCount: UInt(roomProxy.infoPublisher.value.activeMembersCount))
} else {
stateMachine.tryEvent(.dismissFlow, userInfo: EventUserInfo(animated: animated))
}
@@ -790,18 +768,18 @@ class RoomFlowCoordinator: FlowCoordinatorProtocol {
timelineController = nil
actionsSubject.send(.finished)
analytics.signpost.endRoomFlow()
flowParameters.analytics.signpost.endRoomFlow()
}
private func presentRoomDetails(isRoot: Bool, animated: Bool) async {
let params = RoomDetailsScreenCoordinatorParameters(roomProxy: roomProxy,
clientProxy: userSession.clientProxy,
mediaProvider: userSession.mediaProvider,
analyticsService: analytics,
userIndicatorController: userIndicatorController,
analyticsService: flowParameters.analytics,
userIndicatorController: flowParameters.userIndicatorController,
notificationSettings: userSession.clientProxy.notificationSettings,
attributedStringBuilder: AttributedStringBuilder(mentionBuilder: MentionBuilder()),
appMediator: appMediator)
appMediator: flowParameters.appMediator)
let coordinator = RoomDetailsScreenCoordinator(parameters: params)
coordinator.actions.sink { [weak self] action in
guard let self else { return }
@@ -862,8 +840,8 @@ class RoomFlowCoordinator: FlowCoordinatorProtocol {
let parameters = RoomMembersListScreenCoordinatorParameters(clientProxy: userSession.clientProxy,
roomProxy: roomProxy,
mediaProvider: userSession.mediaProvider,
userIndicatorController: userIndicatorController,
analytics: analytics)
userIndicatorController: flowParameters.userIndicatorController,
analytics: flowParameters.analytics)
let coordinator = RoomMembersListScreenCoordinator(parameters: parameters)
coordinator.actions
@@ -887,7 +865,7 @@ class RoomFlowCoordinator: FlowCoordinatorProtocol {
private func presentKnockRequestsList() {
let parameters = KnockRequestsListScreenCoordinatorParameters(roomProxy: roomProxy,
mediaProvider: userSession.mediaProvider,
userIndicatorController: userIndicatorController)
userIndicatorController: flowParameters.userIndicatorController)
let coordinator = KnockRequestsListScreenCoordinator(parameters: parameters)
navigationStackCoordinator.push(coordinator) { [weak self] in
@@ -901,11 +879,11 @@ class RoomFlowCoordinator: FlowCoordinatorProtocol {
let roomDetailsEditParameters = RoomDetailsEditScreenCoordinatorParameters(roomProxy: roomProxy,
clientProxy: userSession.clientProxy,
mediaProvider: userSession.mediaProvider,
mediaUploadingPreprocessor: MediaUploadingPreprocessor(appSettings: appSettings),
mediaUploadingPreprocessor: MediaUploadingPreprocessor(appSettings: flowParameters.appSettings),
navigationStackCoordinator: stackCoordinator,
userIndicatorController: userIndicatorController,
orientationManager: appMediator.windowManager,
appSettings: appSettings)
userIndicatorController: flowParameters.userIndicatorController,
orientationManager: flowParameters.appMediator.windowManager,
appSettings: flowParameters.appSettings)
let roomDetailsEditCoordinator = RoomDetailsEditScreenCoordinator(parameters: roomDetailsEditParameters)
roomDetailsEditCoordinator.actions.sink { [weak self] action in
@@ -933,7 +911,7 @@ class RoomFlowCoordinator: FlowCoordinatorProtocol {
senderID: senderID,
roomProxy: roomProxy,
clientProxy: userSession.clientProxy,
userIndicatorController: userIndicatorController)
userIndicatorController: flowParameters.userIndicatorController)
let coordinator = ReportContentScreenCoordinator(parameters: parameters)
coordinator.actions
@@ -946,7 +924,7 @@ class RoomFlowCoordinator: FlowCoordinatorProtocol {
case .cancel:
break
case .finish:
userIndicatorController.submitIndicator(UserIndicator(title: L10n.commonReportSubmitted, iconName: "checkmark"))
flowParameters.userIndicatorController.submitIndicator(UserIndicator(title: L10n.commonReportSubmitted, iconName: "checkmark"))
}
}
.store(in: &cancellables)
@@ -963,8 +941,8 @@ class RoomFlowCoordinator: FlowCoordinatorProtocol {
let stackCoordinator = NavigationStackCoordinator()
let mediaPickerCoordinator = MediaPickerScreenCoordinator(mode: mode,
userIndicatorController: userIndicatorController,
orientationManager: appMediator.windowManager) { [weak self] action in
userIndicatorController: flowParameters.userIndicatorController,
orientationManager: flowParameters.appMediator.windowManager) { [weak self] action in
guard let self else {
return
}
@@ -1000,11 +978,11 @@ class RoomFlowCoordinator: FlowCoordinatorProtocol {
let parameters = MediaUploadPreviewScreenCoordinatorParameters(mediaURLs: mediaURLs,
title: title,
isRoomEncrypted: roomProxy.infoPublisher.value.isEncrypted,
shouldShowCaptionWarning: appSettings.shouldShowMediaCaptionWarning,
mediaUploadingPreprocessor: MediaUploadingPreprocessor(appSettings: appSettings),
shouldShowCaptionWarning: flowParameters.appSettings.shouldShowMediaCaptionWarning,
mediaUploadingPreprocessor: MediaUploadingPreprocessor(appSettings: flowParameters.appSettings),
timelineController: timelineController,
clientProxy: userSession.clientProxy,
userIndicatorController: userIndicatorController)
userIndicatorController: flowParameters.userIndicatorController)
let mediaUploadPreviewScreenCoordinator = MediaUploadPreviewScreenCoordinator(parameters: parameters)
@@ -1030,7 +1008,7 @@ class RoomFlowCoordinator: FlowCoordinatorProtocol {
selectedEmoji: Set<String>,
timelineController: TimelineControllerProtocol,
animated: Bool) {
let params = EmojiPickerScreenCoordinatorParameters(emojiProvider: emojiProvider,
let params = EmojiPickerScreenCoordinatorParameters(emojiProvider: flowParameters.emojiProvider,
itemID: itemID, selectedEmojis: selectedEmoji)
let coordinator = EmojiPickerScreenCoordinator(parameters: params)
@@ -1065,8 +1043,8 @@ class RoomFlowCoordinator: FlowCoordinatorProtocol {
let stackCoordinator = NavigationStackCoordinator()
let params = StaticLocationScreenCoordinatorParameters(interactionMode: interactionMode,
mapURLBuilder: appSettings.mapTilerConfiguration,
appMediator: appMediator)
mapURLBuilder: flowParameters.appSettings.mapTilerConfiguration,
appMediator: flowParameters.appMediator)
let coordinator = StaticLocationScreenCoordinator(parameters: params)
coordinator.actions.sink { [weak self] action in
@@ -1082,11 +1060,11 @@ class RoomFlowCoordinator: FlowCoordinatorProtocol {
self.navigationStackCoordinator.setSheetCoordinator(nil)
}
self.analytics.trackComposer(inThread: false,
isEditing: false,
isReply: false,
messageType: isUserLocation ? .LocationUser : .LocationPin,
startsThread: nil)
self.flowParameters.analytics.trackComposer(inThread: false,
isEditing: false,
isReply: false,
messageType: isUserLocation ? .LocationUser : .LocationPin,
startsThread: nil)
case .close:
self.navigationStackCoordinator.setSheetCoordinator(nil)
}
@@ -1145,19 +1123,19 @@ class RoomFlowCoordinator: FlowCoordinatorProtocol {
Task {
let result = await timelineController.createPoll(question: question, answers: options, pollKind: pollKind)
self.analytics.trackComposer(inThread: false,
isEditing: false,
isReply: false,
messageType: .Poll,
startsThread: nil)
self.flowParameters.analytics.trackComposer(inThread: false,
isEditing: false,
isReply: false,
messageType: .Poll,
startsThread: nil)
self.analytics.trackPollCreated(isUndisclosed: pollKind == .undisclosed, numberOfAnswers: options.count)
self.flowParameters.analytics.trackPollCreated(isUndisclosed: pollKind == .undisclosed, numberOfAnswers: options.count)
switch result {
case .success:
break
case .failure:
self.userIndicatorController.submitIndicator(UserIndicator(title: L10n.errorUnknown))
self.flowParameters.userIndicatorController.submitIndicator(UserIndicator(title: L10n.errorUnknown))
}
}
}
@@ -1170,7 +1148,7 @@ class RoomFlowCoordinator: FlowCoordinatorProtocol {
case .success:
break
case .failure:
self.userIndicatorController.submitIndicator(UserIndicator(title: L10n.errorUnknown))
self.flowParameters.userIndicatorController.submitIndicator(UserIndicator(title: L10n.errorUnknown))
}
}
}
@@ -1178,7 +1156,7 @@ class RoomFlowCoordinator: FlowCoordinatorProtocol {
private func deletePoll(mode: PollFormMode) {
Task {
guard case .edit(let pollStartID, _) = mode else {
self.userIndicatorController.submitIndicator(UserIndicator(title: L10n.errorUnknown))
self.flowParameters.userIndicatorController.submitIndicator(UserIndicator(title: L10n.errorUnknown))
return
}
@@ -1188,7 +1166,7 @@ class RoomFlowCoordinator: FlowCoordinatorProtocol {
case .success:
break
case .failure:
self.userIndicatorController.submitIndicator(UserIndicator(title: L10n.errorUnknown))
self.flowParameters.userIndicatorController.submitIndicator(UserIndicator(title: L10n.errorUnknown))
}
}
}
@@ -1200,12 +1178,12 @@ class RoomFlowCoordinator: FlowCoordinatorProtocol {
attributedStringBuilder: AttributedStringBuilder(mentionBuilder: MentionBuilder()),
stateEventStringBuilder: RoomStateEventStringBuilder(userID: userID))
let timelineController = timelineControllerFactory.buildTimelineController(roomProxy: roomProxy,
initialFocussedEventID: nil,
timelineItemFactory: timelineItemFactory,
mediaProvider: userSession.mediaProvider)
let timelineController = flowParameters.timelineControllerFactory.buildTimelineController(roomProxy: roomProxy,
initialFocussedEventID: nil,
timelineItemFactory: timelineItemFactory,
mediaProvider: userSession.mediaProvider)
let parameters = RoomPollsHistoryScreenCoordinatorParameters(pollInteractionHandler: PollInteractionHandler(analyticsService: analytics,
let parameters = RoomPollsHistoryScreenCoordinatorParameters(pollInteractionHandler: PollInteractionHandler(analyticsService: flowParameters.analytics,
timelineController: timelineController),
timelineController: timelineController)
let coordinator = RoomPollsHistoryScreenCoordinator(parameters: parameters)
@@ -1231,8 +1209,8 @@ class RoomFlowCoordinator: FlowCoordinatorProtocol {
roomProxy: roomProxy,
clientProxy: userSession.clientProxy,
mediaProvider: userSession.mediaProvider,
userIndicatorController: userIndicatorController,
analytics: analytics)
userIndicatorController: flowParameters.userIndicatorController,
analytics: flowParameters.analytics)
let coordinator = RoomMemberDetailsScreenCoordinator(parameters: params)
coordinator.actions.sink { [weak self] action in
@@ -1260,8 +1238,8 @@ class RoomFlowCoordinator: FlowCoordinatorProtocol {
isPresentedModally: false,
clientProxy: userSession.clientProxy,
mediaProvider: userSession.mediaProvider,
userIndicatorController: userIndicatorController,
analytics: analytics)
userIndicatorController: flowParameters.userIndicatorController,
analytics: flowParameters.analytics)
let coordinator = UserProfileScreenCoordinator(parameters: parameters)
coordinator.actionsPublisher.sink { [weak self] action in
guard let self else { return }
@@ -1296,7 +1274,7 @@ class RoomFlowCoordinator: FlowCoordinatorProtocol {
clientProxy: userSession.clientProxy,
roomSummaryProvider: roomSummaryProvider,
mediaProvider: userSession.mediaProvider,
userIndicatorController: userIndicatorController)
userIndicatorController: flowParameters.userIndicatorController)
let coordinator = MessageForwardingScreenCoordinator(parameters: parameters)
coordinator.actions.sink { [weak self] action in
@@ -1344,7 +1322,6 @@ class RoomFlowCoordinator: FlowCoordinatorProtocol {
let parameters = NotificationSettingsScreenCoordinatorParameters(navigationStackCoordinator: stackCoordinator,
userSession: userSession,
userNotificationCenter: UNUserNotificationCenter.current(),
notificationSettings: userSession.clientProxy.notificationSettings,
isModallyPresented: true)
let coordinator = NotificationSettingsScreenCoordinator(parameters: parameters)
coordinator.actions.sink { [weak self] action in
@@ -1370,7 +1347,7 @@ class RoomFlowCoordinator: FlowCoordinatorProtocol {
roomType: .room(roomProxy: roomProxy),
mediaProvider: userSession.mediaProvider,
userDiscoveryService: UserDiscoveryService(clientProxy: userSession.clientProxy),
userIndicatorController: userIndicatorController)
userIndicatorController: flowParameters.userIndicatorController)
let coordinator = InviteUsersScreenCoordinator(parameters: inviteParameters)
stackCoordinator.setRootCoordinator(coordinator)
@@ -1424,9 +1401,9 @@ class RoomFlowCoordinator: FlowCoordinatorProtocol {
return
}
userIndicatorController.alertInfo = .init(id: .init(),
title: L10n.commonUnableToInviteTitle,
message: L10n.commonUnableToInviteMessage)
flowParameters.userIndicatorController.alertInfo = .init(id: .init(),
title: L10n.commonUnableToInviteTitle,
message: L10n.commonUnableToInviteMessage)
}
}
@@ -1434,8 +1411,8 @@ class RoomFlowCoordinator: FlowCoordinatorProtocol {
let parameters = RoomRolesAndPermissionsFlowCoordinatorParameters(roomProxy: roomProxy,
mediaProvider: userSession.mediaProvider,
navigationStackCoordinator: navigationStackCoordinator,
userIndicatorController: userIndicatorController,
analytics: analytics)
userIndicatorController: flowParameters.userIndicatorController,
analytics: flowParameters.analytics)
let coordinator = RoomRolesAndPermissionsFlowCoordinator(parameters: parameters)
coordinator.actionsPublisher.sink { [weak self] action in
switch action {
@@ -1453,7 +1430,7 @@ class RoomFlowCoordinator: FlowCoordinatorProtocol {
let coordinator = ResolveVerifiedUserSendFailureScreenCoordinator(parameters: .init(failure: failure,
sendHandle: sendHandle,
roomProxy: roomProxy,
userIndicatorController: userIndicatorController))
userIndicatorController: flowParameters.userIndicatorController))
coordinator.actionsPublisher.sink { [weak self] action in
guard let self else { return }
@@ -1472,7 +1449,7 @@ class RoomFlowCoordinator: FlowCoordinatorProtocol {
private func presentSecurityAndPrivacyScreen() {
let coordinator = SecurityAndPrivacyScreenCoordinator(parameters: .init(roomProxy: roomProxy,
clientProxy: userSession.clientProxy,
userIndicatorController: userIndicatorController))
userIndicatorController: flowParameters.userIndicatorController))
coordinator.actionsPublisher.sink { [weak self] action in
guard let self else { return }
@@ -1493,7 +1470,7 @@ class RoomFlowCoordinator: FlowCoordinatorProtocol {
let stackCoordinator = NavigationStackCoordinator()
let coordinator = EditRoomAddressScreenCoordinator(parameters: .init(roomProxy: roomProxy,
clientProxy: userSession.clientProxy,
userIndicatorController: userIndicatorController))
userIndicatorController: flowParameters.userIndicatorController))
coordinator.actionsPublisher.sink { [weak self] action in
switch action {
@@ -1510,7 +1487,7 @@ class RoomFlowCoordinator: FlowCoordinatorProtocol {
private func presentReportRoom() {
let stackCoordinator = NavigationStackCoordinator()
let coordinator = ReportRoomScreenCoordinator(parameters: .init(roomProxy: roomProxy,
userIndicatorController: userIndicatorController))
userIndicatorController: flowParameters.userIndicatorController))
coordinator.actionsPublisher.sink { [weak self] action in
guard let self else { return }
@@ -1535,7 +1512,7 @@ class RoomFlowCoordinator: FlowCoordinatorProtocol {
let coordinator = DeclineAndBlockScreenCoordinator(parameters: .init(userID: userID,
roomID: roomID,
clientProxy: userSession.clientProxy,
userIndicatorController: userIndicatorController))
userIndicatorController: flowParameters.userIndicatorController))
coordinator.actionsPublisher.sink { [weak self] action in
guard let self else { return }
switch action {
@@ -1558,17 +1535,9 @@ class RoomFlowCoordinator: FlowCoordinatorProtocol {
private func startChildFlow(for roomID: String, via: [String], entryPoint: RoomFlowCoordinatorEntryPoint) {
let coordinator = RoomFlowCoordinator(roomID: roomID,
userSession: userSession,
isChildFlow: true,
timelineControllerFactory: timelineControllerFactory,
navigationStackCoordinator: navigationStackCoordinator,
emojiProvider: emojiProvider,
ongoingCallRoomIDPublisher: ongoingCallRoomIDPublisher,
appMediator: appMediator,
appSettings: appSettings,
appHooks: appHooks,
analytics: analytics,
userIndicatorController: userIndicatorController)
flowParameters: flowParameters)
coordinator.actions.sink { [weak self] action in
guard let self else { return }
@@ -1601,14 +1570,9 @@ class RoomFlowCoordinator: FlowCoordinatorProtocol {
private func startPinnedEventsTimelineFlow() {
let stackCoordinator = NavigationStackCoordinator()
let flowCoordinator = PinnedEventsTimelineFlowCoordinator(navigationStackCoordinator: stackCoordinator,
userSession: userSession,
timelineControllerFactory: timelineControllerFactory,
roomProxy: roomProxy,
userIndicatorController: userIndicatorController,
appSettings: appSettings,
appMediator: appMediator,
emojiProvider: emojiProvider)
let flowCoordinator = PinnedEventsTimelineFlowCoordinator(roomProxy: roomProxy,
navigationStackCoordinator: stackCoordinator,
flowParameters: flowParameters)
flowCoordinator.actionsPublisher.sink { [weak self] action in
guard let self else {
@@ -1641,13 +1605,9 @@ class RoomFlowCoordinator: FlowCoordinatorProtocol {
}
private func startMediaEventsTimelineFlow() async {
let flowCoordinator = MediaEventsTimelineFlowCoordinator(navigationStackCoordinator: navigationStackCoordinator,
userSession: userSession,
timelineControllerFactory: timelineControllerFactory,
roomProxy: roomProxy,
userIndicatorController: userIndicatorController,
appMediator: appMediator,
emojiProvider: emojiProvider)
let flowCoordinator = MediaEventsTimelineFlowCoordinator(roomProxy: roomProxy,
navigationStackCoordinator: navigationStackCoordinator,
flowParameters: flowParameters)
flowCoordinator.actionsPublisher.sink { [weak self] action in
guard let self else { return }
@@ -1674,15 +1634,15 @@ class RoomFlowCoordinator: FlowCoordinatorProtocol {
private static let loadingIndicatorID = "\(RoomFlowCoordinator.self)-Loading"
private func showLoadingIndicator(delay: Duration? = nil) {
userIndicatorController.submitIndicator(.init(id: Self.loadingIndicatorID,
type: .modal(progress: .indeterminate,
interactiveDismissDisabled: false,
allowsInteraction: false),
title: L10n.commonLoading, persistent: true),
delay: delay)
flowParameters.userIndicatorController.submitIndicator(.init(id: Self.loadingIndicatorID,
type: .modal(progress: .indeterminate,
interactiveDismissDisabled: false,
allowsInteraction: false),
title: L10n.commonLoading, persistent: true),
delay: delay)
}
private func hideLoadingIndicator() {
userIndicatorController.retractIndicatorWithId(Self.loadingIndicatorID)
flowParameters.userIndicatorController.retractIndicatorWithId(Self.loadingIndicatorID)
}
}
@@ -16,22 +16,10 @@ enum SettingsFlowCoordinatorAction {
case forceLogout
}
struct SettingsFlowCoordinatorParameters {
let userSession: UserSessionProtocol
let windowManager: WindowManagerProtocol
let appLockService: AppLockServiceProtocol
let bugReportService: BugReportServiceProtocol
let notificationSettings: NotificationSettingsProxyProtocol
let secureBackupController: SecureBackupControllerProtocol
let appSettings: AppSettings
let navigationStackCoordinator: NavigationStackCoordinator
let userIndicatorController: UserIndicatorControllerProtocol
let analytics: AnalyticsService
}
class SettingsFlowCoordinator: FlowCoordinatorProtocol {
private let parameters: SettingsFlowCoordinatorParameters
private var navigationStackCoordinator: NavigationStackCoordinator { parameters.navigationStackCoordinator }
private let appLockService: AppLockServiceProtocol
private let navigationStackCoordinator: NavigationStackCoordinator
private let flowParameters: CommonFlowParameters
// periphery:ignore - retaining purpose
private var appLockSetupFlowCoordinator: AppLockSetupFlowCoordinator?
@@ -47,8 +35,12 @@ class SettingsFlowCoordinator: FlowCoordinatorProtocol {
actionsSubject.eraseToAnyPublisher()
}
init(parameters: SettingsFlowCoordinatorParameters) {
self.parameters = parameters
init(appLockService: AppLockServiceProtocol,
navigationStackCoordinator: NavigationStackCoordinator,
flowParameters: CommonFlowParameters) {
self.appLockService = appLockService
self.navigationStackCoordinator = navigationStackCoordinator
self.flowParameters = flowParameters
}
func start() {
@@ -73,9 +65,9 @@ class SettingsFlowCoordinator: FlowCoordinatorProtocol {
// MARK: - Private
private func presentSettingsScreen(animated: Bool) {
let settingsScreenCoordinator = SettingsScreenCoordinator(parameters: .init(userSession: parameters.userSession,
appSettings: parameters.appSettings,
isBugReportServiceEnabled: parameters.bugReportService.isEnabled))
let settingsScreenCoordinator = SettingsScreenCoordinator(parameters: .init(userSession: flowParameters.userSession,
appSettings: flowParameters.appSettings,
isBugReportServiceEnabled: flowParameters.bugReportService.isEnabled))
settingsScreenCoordinator.actions
.sink { [weak self] action in
@@ -98,9 +90,9 @@ class SettingsFlowCoordinator: FlowCoordinatorProtocol {
presentAppLockSetupFlow()
case .bugReport:
bugReportFlowCoordinator = BugReportFlowCoordinator(parameters: .init(presentationMode: .push(navigationStackCoordinator),
userIndicatorController: parameters.userIndicatorController,
bugReportService: parameters.bugReportService,
userSession: parameters.userSession))
userIndicatorController: flowParameters.userIndicatorController,
bugReportService: flowParameters.bugReportService,
userSession: flowParameters.userSession))
bugReportFlowCoordinator?.start()
case .about:
presentLegalInformationScreen()
@@ -122,9 +114,9 @@ class SettingsFlowCoordinator: FlowCoordinatorProtocol {
}
private func startEncryptionSettingsFlow(animated: Bool) {
let coordinator = EncryptionSettingsFlowCoordinator(parameters: .init(userSession: parameters.userSession,
appSettings: parameters.appSettings,
userIndicatorController: parameters.userIndicatorController,
let coordinator = EncryptionSettingsFlowCoordinator(parameters: .init(userSession: flowParameters.userSession,
appSettings: flowParameters.appSettings,
userIndicatorController: flowParameters.userIndicatorController,
navigationStackCoordinator: navigationStackCoordinator))
coordinator.actionsPublisher.sink { [weak self] action in
switch action {
@@ -140,26 +132,26 @@ class SettingsFlowCoordinator: FlowCoordinatorProtocol {
}
private func presentUserDetailsEditScreen() {
let coordinator = UserDetailsEditScreenCoordinator(parameters: .init(orientationManager: parameters.windowManager,
clientProxy: parameters.userSession.clientProxy,
mediaProvider: parameters.userSession.mediaProvider,
mediaUploadingPreprocessor: MediaUploadingPreprocessor(appSettings: parameters.appSettings),
let coordinator = UserDetailsEditScreenCoordinator(parameters: .init(orientationManager: flowParameters.windowManager,
clientProxy: flowParameters.userSession.clientProxy,
mediaProvider: flowParameters.userSession.mediaProvider,
mediaUploadingPreprocessor: MediaUploadingPreprocessor(appSettings: flowParameters.appSettings),
navigationStackCoordinator: navigationStackCoordinator,
userIndicatorController: parameters.userIndicatorController,
appSettings: parameters.appSettings))
userIndicatorController: flowParameters.userIndicatorController,
appSettings: flowParameters.appSettings))
navigationStackCoordinator.push(coordinator)
}
private func presentAnalyticsScreen() {
let coordinator = AnalyticsSettingsScreenCoordinator(parameters: .init(appSettings: parameters.appSettings,
analytics: parameters.analytics))
let coordinator = AnalyticsSettingsScreenCoordinator(parameters: .init(appSettings: flowParameters.appSettings,
analytics: flowParameters.analytics))
navigationStackCoordinator.push(coordinator)
}
private func presentAppLockSetupFlow() {
let coordinator = AppLockSetupFlowCoordinator(presentingFlow: .settings,
appLockService: parameters.appLockService,
appLockService: appLockService,
navigationStackCoordinator: navigationStackCoordinator)
coordinator.actions.sink { [weak self] action in
guard let self else { return }
@@ -178,32 +170,31 @@ class SettingsFlowCoordinator: FlowCoordinatorProtocol {
}
private func presentLegalInformationScreen() {
navigationStackCoordinator.push(LegalInformationScreenCoordinator(appSettings: parameters.appSettings))
navigationStackCoordinator.push(LegalInformationScreenCoordinator(appSettings: flowParameters.appSettings))
}
private func presentBlockedUsersScreen() {
let coordinator = BlockedUsersScreenCoordinator(parameters: .init(hideProfiles: parameters.appSettings.hideIgnoredUserProfiles,
clientProxy: parameters.userSession.clientProxy,
mediaProvider: parameters.userSession.mediaProvider,
userIndicatorController: parameters.userIndicatorController))
let coordinator = BlockedUsersScreenCoordinator(parameters: .init(hideProfiles: flowParameters.appSettings.hideIgnoredUserProfiles,
clientProxy: flowParameters.userSession.clientProxy,
mediaProvider: flowParameters.userSession.mediaProvider,
userIndicatorController: flowParameters.userIndicatorController))
navigationStackCoordinator.push(coordinator)
}
private func presentNotificationSettings() {
let notificationParameters = NotificationSettingsScreenCoordinatorParameters(navigationStackCoordinator: navigationStackCoordinator,
userSession: parameters.userSession,
userSession: flowParameters.userSession,
userNotificationCenter: UNUserNotificationCenter.current(),
notificationSettings: parameters.notificationSettings,
isModallyPresented: false)
let coordinator = NotificationSettingsScreenCoordinator(parameters: notificationParameters)
navigationStackCoordinator.push(coordinator)
}
private func presentAdvancedSettings() {
let coordinator = AdvancedSettingsScreenCoordinator(parameters: .init(appSettings: parameters.appSettings,
analytics: parameters.analytics,
clientProxy: parameters.userSession.clientProxy,
userIndicatorController: parameters.userIndicatorController))
let coordinator = AdvancedSettingsScreenCoordinator(parameters: .init(appSettings: flowParameters.appSettings,
analytics: flowParameters.analytics,
clientProxy: flowParameters.userSession.clientProxy,
userIndicatorController: flowParameters.userIndicatorController))
navigationStackCoordinator.push(coordinator)
}
@@ -225,8 +216,8 @@ class SettingsFlowCoordinator: FlowCoordinatorProtocol {
}
private func presentDeactivateAccount() {
let parameters = DeactivateAccountScreenCoordinatorParameters(clientProxy: parameters.userSession.clientProxy,
userIndicatorController: parameters.userIndicatorController)
let parameters = DeactivateAccountScreenCoordinatorParameters(clientProxy: flowParameters.userSession.clientProxy,
userIndicatorController: flowParameters.userIndicatorController)
let coordinator = DeactivateAccountScreenCoordinator(parameters: parameters)
coordinator.actionsPublisher
@@ -249,7 +240,7 @@ 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: parameters.windowManager.mainWindow)
accountSettingsPresenter = OIDCAccountSettingsPresenter(accountURL: url, presentationAnchor: flowParameters.windowManager.mainWindow)
accountSettingsPresenter?.start()
}
}
@@ -16,12 +16,11 @@ enum SpaceExplorerFlowCoordinatorAction: Equatable {
class SpaceExplorerFlowCoordinator: FlowCoordinatorProtocol {
private let userSession: UserSessionProtocol
private var flowParameters: CommonFlowParameters
private let navigationSplitCoordinator: NavigationSplitCoordinator
private let sidebarNavigationStackCoordinator: NavigationStackCoordinator
private let detailNavigationStackCoordinator: NavigationStackCoordinator
private let userIndicatorController: UserIndicatorControllerProtocol
private var spaceFlowCoordinator: SpaceFlowCoordinator?
enum State: StateType {
@@ -52,12 +51,10 @@ class SpaceExplorerFlowCoordinator: FlowCoordinatorProtocol {
actionsSubject.eraseToAnyPublisher()
}
init(userSession: UserSessionProtocol,
navigationSplitCoordinator: NavigationSplitCoordinator,
userIndicatorController: UserIndicatorControllerProtocol) {
self.userSession = userSession
init(navigationSplitCoordinator: NavigationSplitCoordinator, flowParameters: CommonFlowParameters) {
userSession = flowParameters.userSession
self.navigationSplitCoordinator = navigationSplitCoordinator
self.userIndicatorController = userIndicatorController
self.flowParameters = flowParameters
sidebarNavigationStackCoordinator = NavigationStackCoordinator(navigationSplitCoordinator: navigationSplitCoordinator)
detailNavigationStackCoordinator = NavigationStackCoordinator(navigationSplitCoordinator: navigationSplitCoordinator)
@@ -117,7 +114,7 @@ class SpaceExplorerFlowCoordinator: FlowCoordinatorProtocol {
private func presentSpaceList() {
let parameters = SpaceListScreenCoordinatorParameters(userSession: userSession,
selectedSpaceSubject: selectedSpaceSubject.asCurrentValuePublisher(),
userIndicatorController: userIndicatorController)
userIndicatorController: flowParameters.userIndicatorController)
let coordinator = SpaceListScreenCoordinator(parameters: parameters)
coordinator.actionsPublisher
.sink { [weak self] action in
@@ -138,9 +135,8 @@ class SpaceExplorerFlowCoordinator: FlowCoordinatorProtocol {
let coordinator = SpaceFlowCoordinator(spaceRoomListProxy: spaceRoomListProxy,
spaceServiceProxy: userSession.clientProxy.spaceService,
isChildFlow: false,
mediaProvider: userSession.mediaProvider,
navigationStackCoordinator: detailNavigationStackCoordinator,
userIndicatorController: userIndicatorController)
flowParameters: flowParameters)
coordinator.actionsPublisher
.sink { [weak self] action in
@@ -18,13 +18,12 @@ class SpaceFlowCoordinator: FlowCoordinatorProtocol {
private let spaceServiceProxy: SpaceServiceProxyProtocol
private let isChildFlow: Bool
private let mediaProvider: MediaProviderProtocol
private let navigationStackCoordinator: NavigationStackCoordinator
private let userIndicatorController: UserIndicatorControllerProtocol
private var childSpaceFlowCoordinator: SpaceFlowCoordinator?
private let flowParameters: CommonFlowParameters
indirect enum State: StateType {
/// The state machine hasn't started.
case initial
@@ -57,17 +56,14 @@ class SpaceFlowCoordinator: FlowCoordinatorProtocol {
init(spaceRoomListProxy: SpaceRoomListProxyProtocol,
spaceServiceProxy: SpaceServiceProxyProtocol,
isChildFlow: Bool,
mediaProvider: MediaProviderProtocol,
navigationStackCoordinator: NavigationStackCoordinator,
userIndicatorController: UserIndicatorControllerProtocol) {
flowParameters: CommonFlowParameters) {
self.spaceRoomListProxy = spaceRoomListProxy
self.spaceServiceProxy = spaceServiceProxy
self.isChildFlow = isChildFlow
self.mediaProvider = mediaProvider
self.flowParameters = flowParameters
self.navigationStackCoordinator = navigationStackCoordinator
self.userIndicatorController = userIndicatorController
stateMachine = .init(state: .initial)
configureStateMachine()
@@ -130,8 +126,8 @@ class SpaceFlowCoordinator: FlowCoordinatorProtocol {
private func presentSpace() {
let parameters = SpaceScreenCoordinatorParameters(spaceRoomListProxy: spaceRoomListProxy,
spaceServiceProxy: spaceServiceProxy,
mediaProvider: mediaProvider,
userIndicatorController: userIndicatorController)
mediaProvider: flowParameters.userSession.mediaProvider,
userIndicatorController: flowParameters.userIndicatorController)
let coordinator = SpaceScreenCoordinator(parameters: parameters)
coordinator.actionsPublisher
.sink { [weak self] action in
@@ -160,9 +156,8 @@ class SpaceFlowCoordinator: FlowCoordinatorProtocol {
let coordinator = SpaceFlowCoordinator(spaceRoomListProxy: spaceRoomListProxy,
spaceServiceProxy: spaceServiceProxy,
isChildFlow: true,
mediaProvider: mediaProvider,
navigationStackCoordinator: navigationStackCoordinator,
userIndicatorController: userIndicatorController)
flowParameters: flowParameters)
coordinator.actionsPublisher
.sink { [weak self] action in
@@ -21,14 +21,12 @@ enum UserSessionFlowCoordinatorAction {
class UserSessionFlowCoordinator: FlowCoordinatorProtocol {
enum HomeTab: Hashable { case chats, spaces }
private let userSession: UserSessionProtocol
private let navigationRootCoordinator: NavigationRootCoordinator
private let navigationTabCoordinator: NavigationTabCoordinator<HomeTab>
private let appLockService: AppLockServiceProtocol
private let bugReportService: BugReportServiceProtocol
private let appMediator: AppMediatorProtocol
private let appSettings: AppSettings
private let analytics: AnalyticsService
private let flowParameters: CommonFlowParameters
private var userSession: UserSessionProtocol { flowParameters.userSession }
private let onboardingFlowCoordinator: OnboardingFlowCoordinator
private let onboardingStackCoordinator: NavigationStackCoordinator
@@ -67,75 +65,46 @@ class UserSessionFlowCoordinator: FlowCoordinatorProtocol {
actionsSubject.eraseToAnyPublisher()
}
init(userSession: UserSessionProtocol,
isNewLogin: Bool,
init(isNewLogin: Bool,
navigationRootCoordinator: NavigationRootCoordinator,
appLockService: AppLockServiceProtocol,
bugReportService: BugReportServiceProtocol,
elementCallService: ElementCallServiceProtocol,
timelineControllerFactory: TimelineControllerFactoryProtocol,
appMediator: AppMediatorProtocol,
appSettings: AppSettings,
appHooks: AppHooks,
analytics: AnalyticsService,
notificationManager: NotificationManagerProtocol,
stateMachineFactory: StateMachineFactoryProtocol) {
self.userSession = userSession
flowParameters: CommonFlowParameters) {
self.navigationRootCoordinator = navigationRootCoordinator
self.appLockService = appLockService
self.bugReportService = bugReportService
self.appMediator = appMediator
self.appSettings = appSettings
self.analytics = analytics
self.flowParameters = flowParameters
navigationTabCoordinator = NavigationTabCoordinator()
navigationRootCoordinator.setRootCoordinator(navigationTabCoordinator)
let chatsSplitCoordinator = NavigationSplitCoordinator(placeholderCoordinator: PlaceholderScreenCoordinator())
chatsFlowCoordinator = ChatsFlowCoordinator(userSession: userSession,
isNewLogin: isNewLogin,
chatsFlowCoordinator = ChatsFlowCoordinator(isNewLogin: isNewLogin,
navigationSplitCoordinator: chatsSplitCoordinator,
appLockService: appLockService,
bugReportService: bugReportService,
elementCallService: elementCallService,
timelineControllerFactory: timelineControllerFactory,
appMediator: appMediator,
appSettings: appSettings,
appHooks: appHooks,
analytics: analytics,
notificationManager: notificationManager,
stateMachineFactory: stateMachineFactory)
flowParameters: flowParameters)
chatsTabDetails = .init(tag: HomeTab.chats, title: L10n.screenHomeTabChats, icon: \.chat, selectedIcon: \.chatSolid)
chatsTabDetails.navigationSplitCoordinator = chatsSplitCoordinator
if !appSettings.spacesEnabled {
if !flowParameters.appSettings.spacesEnabled {
chatsTabDetails.barVisibilityOverride = .hidden
}
let spacesSplitCoordinator = NavigationSplitCoordinator(placeholderCoordinator: PlaceholderScreenCoordinator())
spaceExplorerFlowCoordinator = SpaceExplorerFlowCoordinator(userSession: userSession,
navigationSplitCoordinator: spacesSplitCoordinator,
userIndicatorController: ServiceLocator.shared.userIndicatorController)
spaceExplorerFlowCoordinator = SpaceExplorerFlowCoordinator(navigationSplitCoordinator: spacesSplitCoordinator,
flowParameters: flowParameters)
spacesTabDetails = .init(tag: HomeTab.spaces, title: L10n.screenHomeTabSpaces, icon: \.space, selectedIcon: \.spaceSolid)
spacesTabDetails.navigationSplitCoordinator = spacesSplitCoordinator
onboardingStackCoordinator = NavigationStackCoordinator()
onboardingFlowCoordinator = OnboardingFlowCoordinator(userSession: userSession,
onboardingFlowCoordinator = OnboardingFlowCoordinator(isNewLogin: isNewLogin,
appLockService: appLockService,
analyticsService: analytics,
appSettings: appSettings,
notificationManager: notificationManager,
navigationStackCoordinator: onboardingStackCoordinator,
userIndicatorController: ServiceLocator.shared.userIndicatorController,
windowManager: appMediator.windowManager,
isNewLogin: isNewLogin)
flowParameters: flowParameters)
navigationTabCoordinator.setTabs([
.init(coordinator: chatsSplitCoordinator, details: chatsTabDetails),
.init(coordinator: spacesSplitCoordinator, details: spacesTabDetails)
])
stateMachine = stateMachineFactory.makeUserSessionFlowStateMachine(state: .initial)
stateMachine = flowParameters.stateMachineFactory.makeUserSessionFlowStateMachine(state: .initial)
configureStateMachine()
setupObservers()
@@ -272,7 +241,7 @@ class UserSessionFlowCoordinator: FlowCoordinatorProtocol {
}
.store(in: &cancellables)
appSettings.$spacesEnabled
flowParameters.appSettings.$spacesEnabled
.combineLatest(userSession.clientProxy.spaceService.joinedSpacesPublisher)
.map { $0 && !$1.isEmpty ? nil : .hidden }
.weakAssign(to: \.chatsTabDetails.barVisibilityOverride, on: self)
@@ -294,16 +263,9 @@ class UserSessionFlowCoordinator: FlowCoordinatorProtocol {
private func startSettingsFlow() {
let navigationStackCoordinator = NavigationStackCoordinator()
let coordinator = SettingsFlowCoordinator(parameters: .init(userSession: userSession,
windowManager: appMediator.windowManager,
appLockService: appLockService,
bugReportService: bugReportService,
notificationSettings: userSession.clientProxy.notificationSettings,
secureBackupController: userSession.clientProxy.secureBackupController,
appSettings: appSettings,
navigationStackCoordinator: navigationStackCoordinator,
userIndicatorController: ServiceLocator.shared.userIndicatorController,
analytics: analytics))
let coordinator = SettingsFlowCoordinator(appLockService: appLockService,
navigationStackCoordinator: navigationStackCoordinator,
flowParameters: flowParameters)
coordinator.actions.sink { [weak self] action in
guard let self else { return }
@@ -365,7 +327,7 @@ class UserSessionFlowCoordinator: FlowCoordinatorProtocol {
let parameters = SessionVerificationScreenCoordinatorParameters(sessionVerificationControllerProxy: sessionVerificationController,
flow: flow,
appSettings: appSettings,
appSettings: flowParameters.appSettings,
mediaProvider: userSession.mediaProvider)
let coordinator = SessionVerificationScreenCoordinator(parameters: parameters)
@@ -390,7 +352,7 @@ class UserSessionFlowCoordinator: FlowCoordinatorProtocol {
let secureBackupController = userSession.clientProxy.secureBackupController
guard case let .success(isLastDevice) = await userSession.clientProxy.isOnlyDeviceLeft() else {
ServiceLocator.shared.userIndicatorController.alertInfo = .init(id: .init())
flowParameters.userIndicatorController.alertInfo = .init(id: .init())
return
}
@@ -400,26 +362,26 @@ class UserSessionFlowCoordinator: FlowCoordinatorProtocol {
}
guard secureBackupController.recoveryState.value == .enabled else {
ServiceLocator.shared.userIndicatorController.alertInfo = .init(id: .init(),
title: L10n.screenSignoutRecoveryDisabledTitle,
message: L10n.screenSignoutRecoveryDisabledSubtitle,
primaryButton: .init(title: L10n.screenSignoutConfirmationDialogSubmit, role: .destructive) { [weak self] in
self?.actionsSubject.send(.logout)
}, secondaryButton: .init(title: L10n.commonSettings, role: .cancel) { [weak self] in
self?.chatsFlowCoordinator.handleAppRoute(.chatBackupSettings, animated: true)
})
flowParameters.userIndicatorController.alertInfo = .init(id: .init(),
title: L10n.screenSignoutRecoveryDisabledTitle,
message: L10n.screenSignoutRecoveryDisabledSubtitle,
primaryButton: .init(title: L10n.screenSignoutConfirmationDialogSubmit, role: .destructive) { [weak self] in
self?.actionsSubject.send(.logout)
}, secondaryButton: .init(title: L10n.commonSettings, role: .cancel) { [weak self] in
self?.chatsFlowCoordinator.handleAppRoute(.chatBackupSettings, animated: true)
})
return
}
guard secureBackupController.keyBackupState.value == .enabled else {
ServiceLocator.shared.userIndicatorController.alertInfo = .init(id: .init(),
title: L10n.screenSignoutKeyBackupDisabledTitle,
message: L10n.screenSignoutKeyBackupDisabledSubtitle,
primaryButton: .init(title: L10n.screenSignoutConfirmationDialogSubmit, role: .destructive) { [weak self] in
self?.actionsSubject.send(.logout)
}, secondaryButton: .init(title: L10n.commonSettings, role: .cancel) { [weak self] in
self?.chatsFlowCoordinator.handleAppRoute(.chatBackupSettings, animated: true)
})
flowParameters.userIndicatorController.alertInfo = .init(id: .init(),
title: L10n.screenSignoutKeyBackupDisabledTitle,
message: L10n.screenSignoutKeyBackupDisabledSubtitle,
primaryButton: .init(title: L10n.screenSignoutConfirmationDialogSubmit, role: .destructive) { [weak self] in
self?.actionsSubject.send(.logout)
}, secondaryButton: .init(title: L10n.commonSettings, role: .cancel) { [weak self] in
self?.chatsFlowCoordinator.handleAppRoute(.chatBackupSettings, animated: true)
})
return
}
@@ -427,17 +389,17 @@ class UserSessionFlowCoordinator: FlowCoordinatorProtocol {
}
private func logout() {
ServiceLocator.shared.userIndicatorController.alertInfo = .init(id: .init(),
title: L10n.screenSignoutConfirmationDialogTitle,
message: L10n.screenSignoutConfirmationDialogContent,
primaryButton: .init(title: L10n.screenSignoutConfirmationDialogSubmit, role: .destructive) { [weak self] in
self?.actionsSubject.send(.logout)
})
flowParameters.userIndicatorController.alertInfo = .init(id: .init(),
title: L10n.screenSignoutConfirmationDialogTitle,
message: L10n.screenSignoutConfirmationDialogContent,
primaryButton: .init(title: L10n.screenSignoutConfirmationDialogSubmit, role: .destructive) { [weak self] in
self?.actionsSubject.send(.logout)
})
}
private func presentSecureBackupLogoutConfirmationScreen() {
let coordinator = SecureBackupLogoutConfirmationScreenCoordinator(parameters: .init(secureBackupController: userSession.clientProxy.secureBackupController,
appMediator: appMediator))
appMediator: flowParameters.appMediator))
coordinator.actions
.sink { [weak self] action in