implemented the navigation to the manage auth spaces screen

# Conflicts:
#	ElementX/Sources/FlowCoordinators/RoomFlowCoordinator.swift
#	ElementX/Sources/FlowCoordinators/SpaceSettingsFlowCoordinator.swift
#	ElementX/Sources/Screens/SecurityAndPrivacyScreen/SecurityAndPrivacyScreenCoordinator.swift
#	ElementX/Sources/Screens/SecurityAndPrivacyScreen/SecurityAndPrivacyScreenModels.swift
This commit is contained in:
Mauro Romito
2025-11-27 17:36:34 +01:00
committed by Mauro
parent 2556eccc29
commit 0dcf1ffda2
15 changed files with 340 additions and 51 deletions
@@ -0,0 +1,53 @@
//
// 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.
//
// periphery:ignore:all - this is just a manageAuthorizedSpaces remove this comment once generating the final file
import Combine
import SwiftUI
struct ManageAuthorizedSpacesScreenCoordinatorParameters {
let authorizedSpacesSelection: AuthorizedSpacesSelection
let mediaProvider: MediaProviderProtocol
}
enum ManageAuthorizedSpacesScreenCoordinatorAction {
case dismiss
}
final class ManageAuthorizedSpacesScreenCoordinator: CoordinatorProtocol {
private let viewModel: ManageAuthorizedSpacesScreenViewModelProtocol
private var cancellables = Set<AnyCancellable>()
private let actionsSubject: PassthroughSubject<ManageAuthorizedSpacesScreenCoordinatorAction, Never> = .init()
var actionsPublisher: AnyPublisher<ManageAuthorizedSpacesScreenCoordinatorAction, Never> {
actionsSubject.eraseToAnyPublisher()
}
init(parameters: ManageAuthorizedSpacesScreenCoordinatorParameters) {
viewModel = ManageAuthorizedSpacesScreenViewModel(authorizedSpacesSelection: parameters.authorizedSpacesSelection,
mediaProvider: parameters.mediaProvider)
}
func start() {
viewModel.actionsPublisher.sink { [weak self] action in
MXLog.info("Coordinator: received view model action: \(action)")
guard let self else { return }
switch action {
case .dismiss:
actionsSubject.send(.dismiss)
}
}
.store(in: &cancellables)
}
func toPresentable() -> AnyView {
AnyView(ManageAuthorizedSpacesScreen(context: viewModel.context))
}
}
@@ -0,0 +1,34 @@
//
// 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 Foundation
enum ManageAuthorizedSpacesScreenViewModelAction {
case dismiss
}
struct ManageAuthorizedSpacesScreenViewState: BindableState {
let authorizedSpacesSelection: AuthorizedSpacesSelection
var desiredSelectedIDs: Set<String>
var hasChanges: Bool {
authorizedSpacesSelection.selectedIDs != desiredSelectedIDs
}
init(authorizedSpacesSelection: AuthorizedSpacesSelection) {
self.authorizedSpacesSelection = authorizedSpacesSelection
desiredSelectedIDs = authorizedSpacesSelection.selectedIDs
}
}
enum ManageAuthorizedSpacesScreenViewAction { }
struct AuthorizedSpacesSelection {
let joinedParentSpaces: [SpaceRoomProxyProtocol]
let unknownSpacesIDs: [String]
let selectedIDs: Set<String>
}
@@ -0,0 +1,30 @@
//
// 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 SwiftUI
typealias ManageAuthorizedSpacesScreenViewModelType = StateStoreViewModelV2<ManageAuthorizedSpacesScreenViewState, ManageAuthorizedSpacesScreenViewAction>
class ManageAuthorizedSpacesScreenViewModel: ManageAuthorizedSpacesScreenViewModelType, ManageAuthorizedSpacesScreenViewModelProtocol {
private let actionsSubject: PassthroughSubject<ManageAuthorizedSpacesScreenViewModelAction, Never> = .init()
var actionsPublisher: AnyPublisher<ManageAuthorizedSpacesScreenViewModelAction, Never> {
actionsSubject.eraseToAnyPublisher()
}
init(authorizedSpacesSelection: AuthorizedSpacesSelection,
mediaProvider: MediaProviderProtocol) {
super.init(initialViewState: ManageAuthorizedSpacesScreenViewState(authorizedSpacesSelection: authorizedSpacesSelection),
mediaProvider: mediaProvider)
}
// MARK: - Public
override func process(viewAction: ManageAuthorizedSpacesScreenViewAction) {
MXLog.info("View model: received view action: \(viewAction)")
}
}
@@ -0,0 +1,14 @@
//
// 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
@MainActor
protocol ManageAuthorizedSpacesScreenViewModelProtocol {
var actionsPublisher: AnyPublisher<ManageAuthorizedSpacesScreenViewModelAction, Never> { get }
var context: ManageAuthorizedSpacesScreenViewModelType.Context { get }
}
@@ -0,0 +1,36 @@
//
// 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 Compound
import SwiftUI
struct ManageAuthorizedSpacesScreen: View {
@Bindable var context: ManageAuthorizedSpacesScreenViewModel.Context
var body: some View {
Form { }
.compoundList()
.navigationTitle("Manage spaces")
}
}
// MARK: - Previews
struct ManageAuthorizedSpacesScreen_Previews: PreviewProvider, TestablePreview {
static let viewModel = ManageAuthorizedSpacesScreenViewModel(authorizedSpacesSelection: .init(joinedParentSpaces: .mockJoinedSpaces,
unknownSpacesIDs: ["!unknown-space-id-1",
"!unknown-space-id-2",
"!unknown-space-id-3"],
selectedIDs: ["space1",
"space3",
"!unknown-space-id-2"]),
mediaProvider: MediaProviderMock(configuration: .init()))
static var previews: some View {
ManageAuthorizedSpacesScreen(context: viewModel.context)
}
}