mirror of
https://github.com/Novaloop-AG/element-x-ios.git
synced 2026-11-04 19:44:05 +00:00
Add a service and flow coordinator for the LinkNewDevice feature. (#4859)
* Add a LinkNewDeviceService that exposes the SDK's grant QR code login methods. * Add a flow coordinator for linking a new device. Changes the presentation too.
This commit is contained in:
@@ -0,0 +1,64 @@
|
||||
//
|
||||
// Copyright 2025 Element Creations Ltd.
|
||||
//
|
||||
// SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial.
|
||||
// Please see LICENSE files in the repository root for full details.
|
||||
//
|
||||
|
||||
import Combine
|
||||
import Foundation
|
||||
|
||||
enum LinkNewDeviceFlowCoordinatorAction {
|
||||
case requestOIDCAuthorisation(URL)
|
||||
case dismiss
|
||||
}
|
||||
|
||||
class LinkNewDeviceFlowCoordinator: FlowCoordinatorProtocol {
|
||||
private let navigationStackCoordinator: NavigationStackCoordinator
|
||||
private let flowParameters: CommonFlowParameters
|
||||
|
||||
private var cancellables = Set<AnyCancellable>()
|
||||
|
||||
private let actionsSubject: PassthroughSubject<LinkNewDeviceFlowCoordinatorAction, Never> = .init()
|
||||
var actionsPublisher: AnyPublisher<LinkNewDeviceFlowCoordinatorAction, Never> {
|
||||
actionsSubject.eraseToAnyPublisher()
|
||||
}
|
||||
|
||||
init(navigationStackCoordinator: NavigationStackCoordinator,
|
||||
flowParameters: CommonFlowParameters) {
|
||||
self.navigationStackCoordinator = navigationStackCoordinator
|
||||
self.flowParameters = flowParameters
|
||||
}
|
||||
|
||||
func start(animated: Bool) {
|
||||
presentLinkNewDeviceScreen()
|
||||
}
|
||||
|
||||
func handleAppRoute(_ appRoute: AppRoute, animated: Bool) {
|
||||
fatalError()
|
||||
}
|
||||
|
||||
func clearRoute(animated: Bool) {
|
||||
fatalError()
|
||||
}
|
||||
|
||||
private func presentLinkNewDeviceScreen() {
|
||||
let coordinator = LinkNewDeviceScreenCoordinator(parameters: .init(clientProxy: flowParameters.userSession.clientProxy))
|
||||
coordinator.actionsPublisher
|
||||
.sink { [weak self] action in
|
||||
guard let self else { return }
|
||||
|
||||
switch action {
|
||||
case .linkMobileDevice(let progressPublisher):
|
||||
break
|
||||
case .linkDesktopComputer:
|
||||
break
|
||||
case .dismiss:
|
||||
actionsSubject.send(.dismiss)
|
||||
}
|
||||
}
|
||||
.store(in: &cancellables)
|
||||
|
||||
navigationStackCoordinator.setRootCoordinator(coordinator)
|
||||
}
|
||||
}
|
||||
@@ -28,6 +28,8 @@ class SettingsFlowCoordinator: FlowCoordinatorProtocol {
|
||||
private var bugReportFlowCoordinator: BugReportFlowCoordinator?
|
||||
// periphery:ignore - retaining purpose
|
||||
private var encryptionSettingsFlowCoordinator: EncryptionSettingsFlowCoordinator?
|
||||
// periphery:ignore - retaining purpose
|
||||
private var linkNewDeviceFlowCoordinator: LinkNewDeviceFlowCoordinator?
|
||||
|
||||
private var cancellables = Set<AnyCancellable>()
|
||||
|
||||
@@ -84,7 +86,7 @@ class SettingsFlowCoordinator: FlowCoordinatorProtocol {
|
||||
case .userDetails:
|
||||
presentUserDetailsEditScreen()
|
||||
case .linkNewDevice:
|
||||
presentLinkNewDeviceScreen()
|
||||
startLinkNewDeviceFlow()
|
||||
case let .manageAccount(url):
|
||||
presentAccountManagementURL(url)
|
||||
case .analytics:
|
||||
@@ -169,6 +171,31 @@ class SettingsFlowCoordinator: FlowCoordinatorProtocol {
|
||||
navigationStackCoordinator.push(coordinator)
|
||||
}
|
||||
|
||||
private func startLinkNewDeviceFlow() {
|
||||
let stackCoordinator = NavigationStackCoordinator()
|
||||
let flowCoordinator = LinkNewDeviceFlowCoordinator(navigationStackCoordinator: stackCoordinator,
|
||||
flowParameters: flowParameters)
|
||||
flowCoordinator.actionsPublisher
|
||||
.sink { [weak self] action in
|
||||
guard let self else { return }
|
||||
|
||||
switch action {
|
||||
case .dismiss:
|
||||
navigationStackCoordinator.setSheetCoordinator(nil)
|
||||
case .requestOIDCAuthorisation(let url):
|
||||
presentAccountManagementURL(url)
|
||||
}
|
||||
}
|
||||
.store(in: &cancellables)
|
||||
|
||||
linkNewDeviceFlowCoordinator = flowCoordinator
|
||||
flowCoordinator.start()
|
||||
|
||||
navigationStackCoordinator.setSheetCoordinator(stackCoordinator) { [weak self] in
|
||||
self?.linkNewDeviceFlowCoordinator = nil
|
||||
}
|
||||
}
|
||||
|
||||
private func presentAnalyticsScreen() {
|
||||
let coordinator = AnalyticsSettingsScreenCoordinator(parameters: .init(appSettings: flowParameters.appSettings,
|
||||
analytics: flowParameters.analytics))
|
||||
@@ -259,9 +286,9 @@ class SettingsFlowCoordinator: FlowCoordinatorProtocol {
|
||||
|
||||
navigationStackCoordinator.push(coordinator)
|
||||
}
|
||||
|
||||
|
||||
// MARK: OIDC Account Management
|
||||
|
||||
|
||||
private var accountSettingsPresenter: OIDCAccountSettingsPresenter?
|
||||
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.
|
||||
@@ -271,27 +298,4 @@ class SettingsFlowCoordinator: FlowCoordinatorProtocol {
|
||||
appSettings: flowParameters.appSettings)
|
||||
accountSettingsPresenter?.start()
|
||||
}
|
||||
|
||||
// MARK: - Link New Device
|
||||
|
||||
private func presentLinkNewDeviceScreen() {
|
||||
let parameters = LinkNewDeviceScreenCoordinatorParameters(clientProxy: flowParameters.userSession.clientProxy)
|
||||
let coordinator = LinkNewDeviceScreenCoordinator(parameters: parameters)
|
||||
coordinator.actionsPublisher
|
||||
.sink { [weak self] action in
|
||||
guard let self else { return }
|
||||
|
||||
switch action {
|
||||
case .linkMobileDevice:
|
||||
break
|
||||
case .linkDesktopComputer:
|
||||
break
|
||||
case .dismiss:
|
||||
navigationStackCoordinator.pop()
|
||||
}
|
||||
}
|
||||
.store(in: &cancellables)
|
||||
|
||||
navigationStackCoordinator.push(coordinator)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user