mirror of
https://github.com/Novaloop-AG/element-x-ios.git
synced 2026-11-03 16:10:20 +00:00
Switch callbacks to combine (#1710)
* #750 - Convert the SoftLogoutScreen to combine * #750 - Convert the UserSessionFlowCoordinator to Combine * #750 - Convert the AnalyticsPromptScreen to Combine * #750 - Convert the LoginScreen to Combine * #750 - Convert the ServerSelectionScreen to Combine * #750 - Convert the EmojiPickerScreen to Combine * #750 - Convert the HomeScreen to Combine * #750 - Convert the MediaUploadPreviewScreen to Combine * #750 - Convert the OnboardingScreen to Combine * Rename `Onboarding` to `OnboardingScreen` * #750 - Convert the ReportContentScreen to Combine * #750 - Convert the RoomDetailsSscreen to Combine * #750 - Convert the RoomMemberDetailsScreen to Combine * #750 - Convert the RoomMembersListScreen to Combine * #750 - Convert the SessionVerificationScreen to Combine * #750 - Convert the SettingsScreen to Combine * #750 - Convert the AdvancedSettingsScreen to Combine * #750 - Convert the DeveloperOptionsScreen to Combine * Fix the unit tests * Use .sink action and the same cancellables constructor everywhere * Cleanup cancellables when setting up tests
This commit is contained in:
+7
-1
@@ -14,6 +14,7 @@
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
import Combine
|
||||
import SwiftUI
|
||||
|
||||
enum AdvancedSettingsScreenCoordinatorAction {
|
||||
@@ -23,7 +24,12 @@ enum AdvancedSettingsScreenCoordinatorAction {
|
||||
final class AdvancedSettingsScreenCoordinator: CoordinatorProtocol {
|
||||
private var viewModel: AdvancedSettingsScreenViewModelProtocol
|
||||
|
||||
var callback: ((AdvancedSettingsScreenCoordinatorAction) -> Void)?
|
||||
private let actionsSubject: PassthroughSubject<AdvancedSettingsScreenCoordinatorAction, Never> = .init()
|
||||
private var cancellables = Set<AnyCancellable>()
|
||||
|
||||
var actions: AnyPublisher<AdvancedSettingsScreenCoordinatorAction, Never> {
|
||||
actionsSubject.eraseToAnyPublisher()
|
||||
}
|
||||
|
||||
init() {
|
||||
viewModel = AdvancedSettingsScreenViewModel(advancedSettings: ServiceLocator.shared.settings)
|
||||
|
||||
+6
-1
@@ -14,12 +14,17 @@
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
import Combine
|
||||
import SwiftUI
|
||||
|
||||
typealias AdvancedSettingsScreenViewModelType = StateStoreViewModel<AdvancedSettingsScreenViewState, AdvancedSettingsScreenViewAction>
|
||||
|
||||
class AdvancedSettingsScreenViewModel: AdvancedSettingsScreenViewModelType, AdvancedSettingsScreenViewModelProtocol {
|
||||
var callback: ((AdvancedSettingsScreenViewModelAction) -> Void)?
|
||||
private var actionsSubject: PassthroughSubject<AdvancedSettingsScreenViewModelAction, Never> = .init()
|
||||
|
||||
var actions: AnyPublisher<AdvancedSettingsScreenViewModelAction, Never> {
|
||||
actionsSubject.eraseToAnyPublisher()
|
||||
}
|
||||
|
||||
init(advancedSettings: AdvancedSettingsProtocol) {
|
||||
let bindings = AdvancedSettingsScreenViewStateBindings(advancedSettings: advancedSettings)
|
||||
|
||||
+2
-2
@@ -14,10 +14,10 @@
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import Combine
|
||||
|
||||
@MainActor
|
||||
protocol AdvancedSettingsScreenViewModelProtocol {
|
||||
var callback: ((AdvancedSettingsScreenViewModelAction) -> Void)? { get set }
|
||||
var actions: AnyPublisher<AdvancedSettingsScreenViewModelAction, Never> { get }
|
||||
var context: AdvancedSettingsScreenViewModelType.Context { get }
|
||||
}
|
||||
|
||||
+18
-7
@@ -14,6 +14,7 @@
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
import Combine
|
||||
import SwiftUI
|
||||
|
||||
enum DeveloperOptionsScreenCoordinatorAction {
|
||||
@@ -23,18 +24,28 @@ enum DeveloperOptionsScreenCoordinatorAction {
|
||||
final class DeveloperOptionsScreenCoordinator: CoordinatorProtocol {
|
||||
private var viewModel: DeveloperOptionsScreenViewModelProtocol
|
||||
|
||||
var callback: ((DeveloperOptionsScreenCoordinatorAction) -> Void)?
|
||||
private let actionsSubject: PassthroughSubject<DeveloperOptionsScreenCoordinatorAction, Never> = .init()
|
||||
private var cancellables = Set<AnyCancellable>()
|
||||
|
||||
var actions: AnyPublisher<DeveloperOptionsScreenCoordinatorAction, Never> {
|
||||
actionsSubject.eraseToAnyPublisher()
|
||||
}
|
||||
|
||||
init() {
|
||||
viewModel = DeveloperOptionsScreenViewModel(developerOptions: ServiceLocator.shared.settings)
|
||||
viewModel.callback = { [weak self] action in
|
||||
switch action {
|
||||
case .clearCache:
|
||||
self?.callback?(.clearCache)
|
||||
|
||||
viewModel.actions
|
||||
.sink { [weak self] action in
|
||||
guard let self else { return }
|
||||
|
||||
switch action {
|
||||
case .clearCache:
|
||||
actionsSubject.send(.clearCache)
|
||||
}
|
||||
}
|
||||
}
|
||||
.store(in: &cancellables)
|
||||
}
|
||||
|
||||
|
||||
func toPresentable() -> AnyView {
|
||||
AnyView(DeveloperOptionsScreen(context: viewModel.context))
|
||||
}
|
||||
|
||||
+7
-2
@@ -14,12 +14,17 @@
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
import Combine
|
||||
import SwiftUI
|
||||
|
||||
typealias DeveloperOptionsScreenViewModelType = StateStoreViewModel<DeveloperOptionsScreenViewState, DeveloperOptionsScreenViewAction>
|
||||
|
||||
class DeveloperOptionsScreenViewModel: DeveloperOptionsScreenViewModelType, DeveloperOptionsScreenViewModelProtocol {
|
||||
var callback: ((DeveloperOptionsScreenViewModelAction) -> Void)?
|
||||
private var actionsSubject: PassthroughSubject<DeveloperOptionsScreenViewModelAction, Never> = .init()
|
||||
|
||||
var actions: AnyPublisher<DeveloperOptionsScreenViewModelAction, Never> {
|
||||
actionsSubject.eraseToAnyPublisher()
|
||||
}
|
||||
|
||||
init(developerOptions: DeveloperOptionsProtocol) {
|
||||
let bindings = DeveloperOptionsScreenViewStateBindings(developerOptions: developerOptions)
|
||||
@@ -31,7 +36,7 @@ class DeveloperOptionsScreenViewModel: DeveloperOptionsScreenViewModelType, Deve
|
||||
override func process(viewAction: DeveloperOptionsScreenViewAction) {
|
||||
switch viewAction {
|
||||
case .clearCache:
|
||||
callback?(.clearCache)
|
||||
actionsSubject.send(.clearCache)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+2
-2
@@ -14,10 +14,10 @@
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import Combine
|
||||
|
||||
@MainActor
|
||||
protocol DeveloperOptionsScreenViewModelProtocol {
|
||||
var callback: ((DeveloperOptionsScreenViewModelAction) -> Void)? { get set }
|
||||
var actions: AnyPublisher<DeveloperOptionsScreenViewModelAction, Never> { get }
|
||||
var context: DeveloperOptionsScreenViewModelType.Context { get }
|
||||
}
|
||||
|
||||
+1
-1
@@ -30,7 +30,7 @@ final class NotificationSettingsEditScreenCoordinator: CoordinatorProtocol {
|
||||
private let parameters: NotificationSettingsEditScreenCoordinatorParameters
|
||||
private var viewModel: NotificationSettingsEditScreenViewModelProtocol
|
||||
private let actionsSubject: PassthroughSubject<NotificationSettingsEditScreenCoordinatorAction, Never> = .init()
|
||||
private var cancellables: Set<AnyCancellable> = .init()
|
||||
private var cancellables = Set<AnyCancellable>()
|
||||
|
||||
var actions: AnyPublisher<NotificationSettingsEditScreenCoordinatorAction, Never> {
|
||||
actionsSubject.eraseToAnyPublisher()
|
||||
|
||||
+1
-1
@@ -33,7 +33,7 @@ final class NotificationSettingsScreenCoordinator: CoordinatorProtocol {
|
||||
private let parameters: NotificationSettingsScreenCoordinatorParameters
|
||||
private var viewModel: NotificationSettingsScreenViewModelProtocol
|
||||
private let actionsSubject: PassthroughSubject<NotificationSettingsScreenCoordinatorAction, Never> = .init()
|
||||
private var cancellables: Set<AnyCancellable> = .init()
|
||||
private var cancellables = Set<AnyCancellable>()
|
||||
|
||||
private var navigationStackCoordinator: NavigationStackCoordinator? {
|
||||
parameters.navigationStackCoordinator
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
import Combine
|
||||
import SwiftUI
|
||||
|
||||
struct SettingsScreenCoordinatorParameters {
|
||||
@@ -34,8 +35,13 @@ enum SettingsScreenCoordinatorAction {
|
||||
final class SettingsScreenCoordinator: CoordinatorProtocol {
|
||||
private let parameters: SettingsScreenCoordinatorParameters
|
||||
private var viewModel: SettingsScreenViewModelProtocol
|
||||
|
||||
var callback: ((SettingsScreenCoordinatorAction) -> Void)?
|
||||
|
||||
private let actionsSubject: PassthroughSubject<SettingsScreenCoordinatorAction, Never> = .init()
|
||||
private var cancellables = Set<AnyCancellable>()
|
||||
|
||||
var actions: AnyPublisher<SettingsScreenCoordinatorAction, Never> {
|
||||
actionsSubject.eraseToAnyPublisher()
|
||||
}
|
||||
|
||||
// MARK: - Setup
|
||||
|
||||
@@ -43,34 +49,37 @@ final class SettingsScreenCoordinator: CoordinatorProtocol {
|
||||
self.parameters = parameters
|
||||
|
||||
viewModel = SettingsScreenViewModel(userSession: parameters.userSession, appSettings: ServiceLocator.shared.settings)
|
||||
viewModel.callback = { [weak self] action in
|
||||
guard let self else { return }
|
||||
|
||||
switch action {
|
||||
case .close:
|
||||
callback?(.dismiss)
|
||||
case .accountProfile:
|
||||
presentAccountProfileURL()
|
||||
case .analytics:
|
||||
presentAnalyticsScreen()
|
||||
case .reportBug:
|
||||
presentBugReportScreen()
|
||||
case .about:
|
||||
presentLegalInformationScreen()
|
||||
case .sessionVerification:
|
||||
verifySession()
|
||||
case .accountSessionsList:
|
||||
presentAccountSessionsListURL()
|
||||
case .notifications:
|
||||
presentNotificationSettings()
|
||||
case .advancedSettings:
|
||||
self.presentAdvancedSettings()
|
||||
case .developerOptions:
|
||||
presentDeveloperOptions()
|
||||
case .logout:
|
||||
callback?(.logout)
|
||||
|
||||
viewModel.actions
|
||||
.sink { [weak self] action in
|
||||
guard let self else { return }
|
||||
|
||||
switch action {
|
||||
case .close:
|
||||
actionsSubject.send(.dismiss)
|
||||
case .accountProfile:
|
||||
presentAccountProfileURL()
|
||||
case .analytics:
|
||||
presentAnalyticsScreen()
|
||||
case .reportBug:
|
||||
presentBugReportScreen()
|
||||
case .about:
|
||||
presentLegalInformationScreen()
|
||||
case .sessionVerification:
|
||||
verifySession()
|
||||
case .accountSessionsList:
|
||||
presentAccountSessionsListURL()
|
||||
case .notifications:
|
||||
presentNotificationSettings()
|
||||
case .advancedSettings:
|
||||
self.presentAdvancedSettings()
|
||||
case .developerOptions:
|
||||
presentDeveloperOptions()
|
||||
case .logout:
|
||||
actionsSubject.send(.logout)
|
||||
}
|
||||
}
|
||||
}
|
||||
.store(in: &cancellables)
|
||||
}
|
||||
|
||||
// MARK: - Public
|
||||
@@ -152,10 +161,17 @@ final class SettingsScreenCoordinator: CoordinatorProtocol {
|
||||
let verificationParameters = SessionVerificationScreenCoordinatorParameters(sessionVerificationControllerProxy: sessionVerificationController)
|
||||
let coordinator = SessionVerificationScreenCoordinator(parameters: verificationParameters)
|
||||
|
||||
coordinator.callback = { [weak self] in
|
||||
self?.parameters.navigationStackCoordinator?.setSheetCoordinator(nil)
|
||||
}
|
||||
|
||||
coordinator.actions
|
||||
.sink { [weak self] action in
|
||||
guard let self else { return }
|
||||
|
||||
switch action {
|
||||
case .done:
|
||||
parameters.navigationStackCoordinator?.setSheetCoordinator(nil)
|
||||
}
|
||||
}
|
||||
.store(in: &cancellables)
|
||||
|
||||
parameters.navigationStackCoordinator?.setSheetCoordinator(coordinator) { [weak self] in
|
||||
self?.parameters.navigationStackCoordinator?.setSheetCoordinator(nil)
|
||||
}
|
||||
@@ -179,12 +195,16 @@ final class SettingsScreenCoordinator: CoordinatorProtocol {
|
||||
private func presentDeveloperOptions() {
|
||||
let coordinator = DeveloperOptionsScreenCoordinator()
|
||||
|
||||
coordinator.callback = { [weak self] action in
|
||||
switch action {
|
||||
case .clearCache:
|
||||
self?.callback?(.clearCache)
|
||||
coordinator.actions
|
||||
.sink { [weak self] action in
|
||||
guard let self else { return }
|
||||
|
||||
switch action {
|
||||
case .clearCache:
|
||||
actionsSubject.send(.clearCache)
|
||||
}
|
||||
}
|
||||
}
|
||||
.store(in: &cancellables)
|
||||
|
||||
parameters.navigationStackCoordinator?.push(coordinator)
|
||||
}
|
||||
|
||||
@@ -23,7 +23,11 @@ class SettingsScreenViewModel: SettingsScreenViewModelType, SettingsScreenViewMo
|
||||
private let userSession: UserSessionProtocol
|
||||
private let appSettings: AppSettings
|
||||
|
||||
var callback: ((SettingsScreenViewModelAction) -> Void)?
|
||||
private var actionsSubject: PassthroughSubject<SettingsScreenViewModelAction, Never> = .init()
|
||||
|
||||
var actions: AnyPublisher<SettingsScreenViewModelAction, Never> {
|
||||
actionsSubject.eraseToAnyPublisher()
|
||||
}
|
||||
|
||||
init(userSession: UserSessionProtocol, appSettings: AppSettings) {
|
||||
self.userSession = userSession
|
||||
@@ -74,27 +78,27 @@ class SettingsScreenViewModel: SettingsScreenViewModelType, SettingsScreenViewMo
|
||||
override func process(viewAction: SettingsScreenViewAction) {
|
||||
switch viewAction {
|
||||
case .close:
|
||||
callback?(.close)
|
||||
actionsSubject.send(.close)
|
||||
case .accountProfile:
|
||||
callback?(.accountProfile)
|
||||
actionsSubject.send(.accountProfile)
|
||||
case .analytics:
|
||||
callback?(.analytics)
|
||||
actionsSubject.send(.analytics)
|
||||
case .reportBug:
|
||||
callback?(.reportBug)
|
||||
actionsSubject.send(.reportBug)
|
||||
case .about:
|
||||
callback?(.about)
|
||||
actionsSubject.send(.about)
|
||||
case .logout:
|
||||
callback?(.logout)
|
||||
actionsSubject.send(.logout)
|
||||
case .sessionVerification:
|
||||
callback?(.sessionVerification)
|
||||
actionsSubject.send(.sessionVerification)
|
||||
case .notifications:
|
||||
callback?(.notifications)
|
||||
actionsSubject.send(.notifications)
|
||||
case .accountSessionsList:
|
||||
callback?(.accountSessionsList)
|
||||
actionsSubject.send(.accountSessionsList)
|
||||
case .advancedSettings:
|
||||
callback?(.advancedSettings)
|
||||
actionsSubject.send(.advancedSettings)
|
||||
case .developerOptions:
|
||||
callback?(.developerOptions)
|
||||
actionsSubject.send(.developerOptions)
|
||||
|
||||
case .updateWindow(let window):
|
||||
Task {
|
||||
|
||||
+2
-2
@@ -14,10 +14,10 @@
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import Combine
|
||||
|
||||
@MainActor
|
||||
protocol SettingsScreenViewModelProtocol {
|
||||
var callback: ((SettingsScreenViewModelAction) -> Void)? { get set }
|
||||
var actions: AnyPublisher<SettingsScreenViewModelAction, Never> { get }
|
||||
var context: SettingsScreenViewModelType.Context { get }
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user