mirror of
https://github.com/Novaloop-AG/element-x-ios.git
synced 2026-11-03 16:10:20 +00:00
Tidy up the naming of spaces a bit more. (#4955)
* Rename SpaceListScreen to SpacesScreen To avoid confusion with the SpaceRoomListProxy. * Rename SpaceExplorerFlowCoordinator to SpacesTabFlowCoordinator and ChatsFlowCoordinator to ChatsTabFlowCoordinator.
This commit is contained in:
+10
-10
@@ -11,7 +11,7 @@ import Combine
|
||||
import MatrixRustSDK
|
||||
import SwiftUI
|
||||
|
||||
enum ChatsFlowCoordinatorAction {
|
||||
enum ChatsTabFlowCoordinatorAction {
|
||||
case switchToChatsTab
|
||||
case showSettings
|
||||
case showChatBackupSettings
|
||||
@@ -21,13 +21,13 @@ enum ChatsFlowCoordinatorAction {
|
||||
case logout
|
||||
}
|
||||
|
||||
class ChatsFlowCoordinator: FlowCoordinatorProtocol {
|
||||
class ChatsTabFlowCoordinator: FlowCoordinatorProtocol {
|
||||
private let navigationSplitCoordinator: NavigationSplitCoordinator
|
||||
private let flowParameters: CommonFlowParameters
|
||||
|
||||
private var userSession: UserSessionProtocol { flowParameters.userSession }
|
||||
|
||||
private let stateMachine: ChatsFlowCoordinatorStateMachine
|
||||
private let stateMachine: ChatsTabFlowCoordinatorStateMachine
|
||||
|
||||
// periphery:ignore - retaining purpose
|
||||
private var roomFlowCoordinator: RoomFlowCoordinator?
|
||||
@@ -50,15 +50,15 @@ class ChatsFlowCoordinator: FlowCoordinatorProtocol {
|
||||
|
||||
private let selectedRoomSubject = CurrentValueSubject<String?, Never>(nil)
|
||||
|
||||
private let actionsSubject: PassthroughSubject<ChatsFlowCoordinatorAction, Never> = .init()
|
||||
var actionsPublisher: AnyPublisher<ChatsFlowCoordinatorAction, Never> {
|
||||
private let actionsSubject: PassthroughSubject<ChatsTabFlowCoordinatorAction, Never> = .init()
|
||||
var actionsPublisher: AnyPublisher<ChatsTabFlowCoordinatorAction, Never> {
|
||||
actionsSubject.eraseToAnyPublisher()
|
||||
}
|
||||
|
||||
init(isNewLogin: Bool,
|
||||
navigationSplitCoordinator: NavigationSplitCoordinator,
|
||||
flowParameters: CommonFlowParameters) {
|
||||
stateMachine = flowParameters.stateMachineFactory.makeChatsFlowStateMachine()
|
||||
stateMachine = flowParameters.stateMachineFactory.makeChatsTabFlowStateMachine()
|
||||
self.navigationSplitCoordinator = navigationSplitCoordinator
|
||||
self.flowParameters = flowParameters
|
||||
|
||||
@@ -188,7 +188,7 @@ class ChatsFlowCoordinator: FlowCoordinatorProtocol {
|
||||
stateMachine.addTransitionHandler { [weak self] context in
|
||||
guard let self else { return }
|
||||
|
||||
let userInfo = context.userInfo as? ChatsFlowCoordinatorStateMachine.EventUserInfo
|
||||
let userInfo = context.userInfo as? ChatsTabFlowCoordinatorStateMachine.EventUserInfo
|
||||
let animated = userInfo?.animated ?? true
|
||||
|
||||
switch (context.fromState, context.event, context.toState) {
|
||||
@@ -289,7 +289,7 @@ class ChatsFlowCoordinator: FlowCoordinatorProtocol {
|
||||
}
|
||||
}
|
||||
|
||||
private func handleSelectRoomTransition(roomID: String, via: [String], entryPoint: RoomFlowCoordinatorEntryPoint, detailState: ChatsFlowCoordinatorStateMachine.DetailState?, animated: Bool) {
|
||||
private func handleSelectRoomTransition(roomID: String, via: [String], entryPoint: RoomFlowCoordinatorEntryPoint, detailState: ChatsTabFlowCoordinatorStateMachine.DetailState?, animated: Bool) {
|
||||
if case .room(roomID) = detailState,
|
||||
!entryPoint.isEventID, // Don't reuse the existing room so the live timeline is hidden while the detached timeline is loading.
|
||||
let roomFlowCoordinator {
|
||||
@@ -798,8 +798,8 @@ class ChatsFlowCoordinator: FlowCoordinatorProtocol {
|
||||
|
||||
// MARK: Toasts and loading indicators
|
||||
|
||||
private static let loadingIndicatorIdentifier = "\(ChatsFlowCoordinator.self)-Loading"
|
||||
private static let failureIndicatorIdentifier = "\(ChatsFlowCoordinator.self)-Failure"
|
||||
private static let loadingIndicatorIdentifier = "\(ChatsTabFlowCoordinator.self)-Loading"
|
||||
private static let failureIndicatorIdentifier = "\(ChatsTabFlowCoordinator.self)-Failure"
|
||||
|
||||
private func showLoadingIndicator(delay: Duration? = nil) {
|
||||
flowParameters.userIndicatorController.submitIndicator(UserIndicator(id: Self.loadingIndicatorIdentifier,
|
||||
+2
-2
@@ -10,7 +10,7 @@ import Combine
|
||||
import Foundation
|
||||
import SwiftState
|
||||
|
||||
class ChatsFlowCoordinatorStateMachine {
|
||||
class ChatsTabFlowCoordinatorStateMachine {
|
||||
enum DetailState: Hashable {
|
||||
case room(roomID: String)
|
||||
case space
|
||||
@@ -138,7 +138,7 @@ class ChatsFlowCoordinatorStateMachine {
|
||||
|
||||
private let stateMachine: StateMachine<State, Event>
|
||||
|
||||
var state: ChatsFlowCoordinatorStateMachine.State {
|
||||
var state: ChatsTabFlowCoordinatorStateMachine.State {
|
||||
stateMachine.state
|
||||
}
|
||||
|
||||
+18
-18
@@ -10,13 +10,13 @@ import Combine
|
||||
import Foundation
|
||||
import SwiftState
|
||||
|
||||
enum SpaceExplorerFlowCoordinatorAction {
|
||||
enum SpacesTabFlowCoordinatorAction {
|
||||
case showSettings
|
||||
case presentCallScreen(roomProxy: JoinedRoomProxyProtocol)
|
||||
case verifyUser(userID: String)
|
||||
}
|
||||
|
||||
class SpaceExplorerFlowCoordinator: FlowCoordinatorProtocol {
|
||||
class SpacesTabFlowCoordinator: FlowCoordinatorProtocol {
|
||||
private let userSession: UserSessionProtocol
|
||||
|
||||
private var flowParameters: CommonFlowParameters
|
||||
@@ -30,7 +30,7 @@ class SpaceExplorerFlowCoordinator: FlowCoordinatorProtocol {
|
||||
/// The state machine hasn't started.
|
||||
case initial
|
||||
/// The root screen for this flow.
|
||||
case spaceList(selectedSpaceID: String?)
|
||||
case spacesScreen(selectedSpaceID: String?)
|
||||
}
|
||||
|
||||
enum Event: EventType {
|
||||
@@ -49,8 +49,8 @@ class SpaceExplorerFlowCoordinator: FlowCoordinatorProtocol {
|
||||
|
||||
private let selectedSpaceSubject = CurrentValueSubject<String?, Never>(nil)
|
||||
|
||||
private let actionsSubject: PassthroughSubject<SpaceExplorerFlowCoordinatorAction, Never> = .init()
|
||||
var actionsPublisher: AnyPublisher<SpaceExplorerFlowCoordinatorAction, Never> {
|
||||
private let actionsSubject: PassthroughSubject<SpacesTabFlowCoordinatorAction, Never> = .init()
|
||||
var actionsPublisher: AnyPublisher<SpacesTabFlowCoordinatorAction, Never> {
|
||||
actionsSubject.eraseToAnyPublisher()
|
||||
}
|
||||
|
||||
@@ -79,7 +79,7 @@ class SpaceExplorerFlowCoordinator: FlowCoordinatorProtocol {
|
||||
|
||||
func clearRoute(animated: Bool) {
|
||||
switch stateMachine.state {
|
||||
case .initial, .spaceList:
|
||||
case .initial, .spacesScreen:
|
||||
break
|
||||
}
|
||||
}
|
||||
@@ -87,22 +87,22 @@ class SpaceExplorerFlowCoordinator: FlowCoordinatorProtocol {
|
||||
// MARK: - Private
|
||||
|
||||
private func configureStateMachine() {
|
||||
stateMachine.addRoutes(event: .start, transitions: [.initial => .spaceList(selectedSpaceID: nil)]) { [weak self] _ in
|
||||
self?.presentSpaceList()
|
||||
stateMachine.addRoutes(event: .start, transitions: [.initial => .spacesScreen(selectedSpaceID: nil)]) { [weak self] _ in
|
||||
self?.presentSpacesScreen()
|
||||
}
|
||||
|
||||
stateMachine.addRouteMapping { event, fromState, userInfo in
|
||||
guard event == .selectSpace, case .spaceList = fromState else { return nil }
|
||||
guard event == .selectSpace, case .spacesScreen = fromState else { return nil }
|
||||
guard let spaceRoomListProxy = userInfo as? SpaceRoomListProxyProtocol else { fatalError("A space proxy must be provided.") }
|
||||
return .spaceList(selectedSpaceID: spaceRoomListProxy.id)
|
||||
return .spacesScreen(selectedSpaceID: spaceRoomListProxy.id)
|
||||
} handler: { [weak self] context in
|
||||
guard let self, let spaceRoomListProxy = context.userInfo as? SpaceRoomListProxyProtocol else { return }
|
||||
startSpaceFlow(spaceRoomListProxy: spaceRoomListProxy)
|
||||
}
|
||||
|
||||
stateMachine.addRouteMapping { event, fromState, _ in
|
||||
guard event == .deselectSpace, case .spaceList(.some) = fromState else { return nil }
|
||||
return .spaceList(selectedSpaceID: nil)
|
||||
guard event == .deselectSpace, case .spacesScreen(.some) = fromState else { return nil }
|
||||
return .spacesScreen(selectedSpaceID: nil)
|
||||
} handler: { [weak self] _ in
|
||||
guard let self else { return }
|
||||
navigationSplitCoordinator.setDetailCoordinator(nil) // If we forget to do this, the tab bar remains hidden.
|
||||
@@ -115,12 +115,12 @@ class SpaceExplorerFlowCoordinator: FlowCoordinatorProtocol {
|
||||
}
|
||||
}
|
||||
|
||||
private func presentSpaceList() {
|
||||
let parameters = SpaceListScreenCoordinatorParameters(userSession: userSession,
|
||||
selectedSpacePublisher: selectedSpaceSubject.asCurrentValuePublisher(),
|
||||
appSettings: flowParameters.appSettings,
|
||||
userIndicatorController: flowParameters.userIndicatorController)
|
||||
let coordinator = SpaceListScreenCoordinator(parameters: parameters)
|
||||
private func presentSpacesScreen() {
|
||||
let parameters = SpacesScreenCoordinatorParameters(userSession: userSession,
|
||||
selectedSpacePublisher: selectedSpaceSubject.asCurrentValuePublisher(),
|
||||
appSettings: flowParameters.appSettings,
|
||||
userIndicatorController: flowParameters.userIndicatorController)
|
||||
let coordinator = SpacesScreenCoordinator(parameters: parameters)
|
||||
coordinator.actionsPublisher
|
||||
.sink { [weak self] action in
|
||||
guard let self else { return }
|
||||
@@ -31,9 +31,9 @@ class UserSessionFlowCoordinator: FlowCoordinatorProtocol {
|
||||
|
||||
private let onboardingFlowCoordinator: OnboardingFlowCoordinator
|
||||
private let onboardingStackCoordinator: NavigationStackCoordinator
|
||||
private let chatsFlowCoordinator: ChatsFlowCoordinator
|
||||
private let chatsTabFlowCoordinator: ChatsTabFlowCoordinator
|
||||
private let chatsTabDetails: NavigationTabCoordinator<HomeTab>.TabDetails
|
||||
private let spaceExplorerFlowCoordinator: SpaceExplorerFlowCoordinator
|
||||
private let spacesTabFlowCoordinator: SpacesTabFlowCoordinator
|
||||
private let spacesTabDetails: NavigationTabCoordinator<HomeTab>.TabDetails
|
||||
|
||||
// periphery:ignore - retaining purpose
|
||||
@@ -78,15 +78,15 @@ class UserSessionFlowCoordinator: FlowCoordinatorProtocol {
|
||||
navigationRootCoordinator.setRootCoordinator(navigationTabCoordinator)
|
||||
|
||||
let chatsSplitCoordinator = NavigationSplitCoordinator(placeholderCoordinator: PlaceholderScreenCoordinator(hideBrandChrome: flowParameters.appSettings.hideBrandChrome))
|
||||
chatsFlowCoordinator = ChatsFlowCoordinator(isNewLogin: isNewLogin,
|
||||
navigationSplitCoordinator: chatsSplitCoordinator,
|
||||
flowParameters: flowParameters)
|
||||
chatsTabFlowCoordinator = ChatsTabFlowCoordinator(isNewLogin: isNewLogin,
|
||||
navigationSplitCoordinator: chatsSplitCoordinator,
|
||||
flowParameters: flowParameters)
|
||||
chatsTabDetails = .init(tag: HomeTab.chats, title: L10n.screenHomeTabChats, icon: \.chat, selectedIcon: \.chatSolid)
|
||||
chatsTabDetails.navigationSplitCoordinator = chatsSplitCoordinator
|
||||
|
||||
let spacesSplitCoordinator = NavigationSplitCoordinator(placeholderCoordinator: PlaceholderScreenCoordinator(hideBrandChrome: flowParameters.appSettings.hideBrandChrome))
|
||||
spaceExplorerFlowCoordinator = SpaceExplorerFlowCoordinator(navigationSplitCoordinator: spacesSplitCoordinator,
|
||||
flowParameters: flowParameters)
|
||||
spacesTabFlowCoordinator = SpacesTabFlowCoordinator(navigationSplitCoordinator: spacesSplitCoordinator,
|
||||
flowParameters: flowParameters)
|
||||
spacesTabDetails = .init(tag: HomeTab.spaces, title: L10n.screenHomeTabSpaces, icon: \.space, selectedIcon: \.spaceSolid)
|
||||
spacesTabDetails.navigationSplitCoordinator = spacesSplitCoordinator
|
||||
|
||||
@@ -112,7 +112,7 @@ class UserSessionFlowCoordinator: FlowCoordinatorProtocol {
|
||||
}
|
||||
|
||||
func stop() {
|
||||
chatsFlowCoordinator.stop()
|
||||
chatsTabFlowCoordinator.stop()
|
||||
}
|
||||
|
||||
func handleAppRoute(_ appRoute: AppRoute, animated: Bool) {
|
||||
@@ -133,7 +133,7 @@ class UserSessionFlowCoordinator: FlowCoordinatorProtocol {
|
||||
.event, .eventOnRoomAlias, .childEvent, .childEventOnRoomAlias,
|
||||
.share, .transferOwnership, .thread:
|
||||
clearPresentedSheets(animated: animated) // Make sure the presented route is visible.
|
||||
chatsFlowCoordinator.handleAppRoute(appRoute, animated: animated)
|
||||
chatsTabFlowCoordinator.handleAppRoute(appRoute, animated: animated)
|
||||
if navigationTabCoordinator.selectedTab != .chats {
|
||||
navigationTabCoordinator.selectedTab = .chats
|
||||
}
|
||||
@@ -142,7 +142,7 @@ class UserSessionFlowCoordinator: FlowCoordinatorProtocol {
|
||||
|
||||
func clearRoute(animated: Bool) {
|
||||
clearPresentedSheets(animated: animated)
|
||||
chatsFlowCoordinator.clearRoute(animated: animated)
|
||||
chatsTabFlowCoordinator.clearRoute(animated: animated)
|
||||
}
|
||||
|
||||
// Clearing routes is more complicated than it first seems. When passing routes
|
||||
@@ -162,7 +162,7 @@ class UserSessionFlowCoordinator: FlowCoordinatorProtocol {
|
||||
|
||||
func isDisplayingRoomScreen(withRoomID roomID: String) -> Bool {
|
||||
guard navigationTabCoordinator.selectedTab == .chats else { return false }
|
||||
return chatsFlowCoordinator.isDisplayingRoomScreen(withRoomID: roomID)
|
||||
return chatsTabFlowCoordinator.isDisplayingRoomScreen(withRoomID: roomID)
|
||||
}
|
||||
|
||||
// MARK: - Private
|
||||
@@ -171,8 +171,8 @@ class UserSessionFlowCoordinator: FlowCoordinatorProtocol {
|
||||
stateMachine.addRoutes(event: .start, transitions: [.initial => .tabBar]) { [weak self] _ in
|
||||
guard let self else { return }
|
||||
|
||||
chatsFlowCoordinator.start()
|
||||
spaceExplorerFlowCoordinator.start()
|
||||
chatsTabFlowCoordinator.start()
|
||||
spacesTabFlowCoordinator.start()
|
||||
attemptStartingOnboarding()
|
||||
}
|
||||
|
||||
@@ -189,7 +189,7 @@ class UserSessionFlowCoordinator: FlowCoordinatorProtocol {
|
||||
}
|
||||
|
||||
private func setupObservers() {
|
||||
chatsFlowCoordinator.actionsPublisher
|
||||
chatsTabFlowCoordinator.actionsPublisher
|
||||
.sink { [weak self] action in
|
||||
guard let self else { return }
|
||||
switch action {
|
||||
@@ -211,7 +211,7 @@ class UserSessionFlowCoordinator: FlowCoordinatorProtocol {
|
||||
}
|
||||
.store(in: &cancellables)
|
||||
|
||||
spaceExplorerFlowCoordinator.actionsPublisher
|
||||
spacesTabFlowCoordinator.actionsPublisher
|
||||
.sink { [weak self] action in
|
||||
guard let self else { return }
|
||||
switch action {
|
||||
@@ -499,7 +499,7 @@ class UserSessionFlowCoordinator: FlowCoordinatorProtocol {
|
||||
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)
|
||||
self?.chatsTabFlowCoordinator.handleAppRoute(.chatBackupSettings, animated: true)
|
||||
})
|
||||
return
|
||||
}
|
||||
@@ -511,7 +511,7 @@ class UserSessionFlowCoordinator: FlowCoordinatorProtocol {
|
||||
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)
|
||||
self?.chatsTabFlowCoordinator.handleAppRoute(.chatBackupSettings, animated: true)
|
||||
})
|
||||
return
|
||||
}
|
||||
@@ -540,7 +540,7 @@ class UserSessionFlowCoordinator: FlowCoordinatorProtocol {
|
||||
case .cancel:
|
||||
navigationTabCoordinator.setSheetCoordinator(nil)
|
||||
case .settings:
|
||||
chatsFlowCoordinator.handleAppRoute(.chatBackupSettings, animated: true)
|
||||
chatsTabFlowCoordinator.handleAppRoute(.chatBackupSettings, animated: true)
|
||||
navigationTabCoordinator.setSheetCoordinator(nil)
|
||||
case .logout:
|
||||
actionsSubject.send(.logout)
|
||||
|
||||
@@ -44,7 +44,7 @@ enum A11yIdentifiers {
|
||||
static let pollFormScreen = PollFormScreen()
|
||||
static let roomPollsHistoryScreen = RoomPollsHistoryScreen()
|
||||
static let manageRoomMemberSheet = ManageRoomMemberSheet()
|
||||
static let spaceListScreen = SpaceListScreen()
|
||||
static let spacesScreen = SpacesScreen()
|
||||
static let linkNewDeviceScreen = LinkNewDeviceScreen()
|
||||
|
||||
struct AlertInfo {
|
||||
@@ -307,10 +307,10 @@ enum A11yIdentifiers {
|
||||
let viewProfile = "manage_room_member_sheet-view_profile"
|
||||
}
|
||||
|
||||
struct SpaceListScreen {
|
||||
let userAvatar = "space_list_screen-user_avatar"
|
||||
struct SpacesScreen {
|
||||
let userAvatar = "spaces_screen-user_avatar"
|
||||
|
||||
let roomNamePrefix = "space_list_screen-room_name"
|
||||
let roomNamePrefix = "spaces_screen-room_name"
|
||||
func spaceRoomName(_ name: String) -> String {
|
||||
"\(roomNamePrefix):\(name)"
|
||||
}
|
||||
|
||||
@@ -167,11 +167,11 @@ enum TestablePreviewsDictionary {
|
||||
"SpaceAddRoomsScreen_Previews" : SpaceAddRoomsScreen_Previews.self,
|
||||
"SpaceHeaderTopicSheetView_Previews" : SpaceHeaderTopicSheetView_Previews.self,
|
||||
"SpaceHeaderView_Previews" : SpaceHeaderView_Previews.self,
|
||||
"SpaceListScreen_Previews" : SpaceListScreen_Previews.self,
|
||||
"SpaceRoomCell_Previews" : SpaceRoomCell_Previews.self,
|
||||
"SpaceScreen_Previews" : SpaceScreen_Previews.self,
|
||||
"SpaceSettingsScreen_Previews" : SpaceSettingsScreen_Previews.self,
|
||||
"SpacesAnnouncementSheetView_Previews" : SpacesAnnouncementSheetView_Previews.self,
|
||||
"SpacesScreen_Previews" : SpacesScreen_Previews.self,
|
||||
"SplashScreen_Previews" : SplashScreen_Previews.self,
|
||||
"StackedAvatarsView_Previews" : StackedAvatarsView_Previews.self,
|
||||
"StartChatScreen_Previews" : StartChatScreen_Previews.self,
|
||||
|
||||
@@ -74,7 +74,7 @@ struct SpaceRoomCell: View {
|
||||
.accessibilityElement(children: .combine)
|
||||
}
|
||||
.buttonStyle(SpaceRoomCellButtonStyle(isSelected: isSelected))
|
||||
.accessibilityIdentifier(A11yIdentifiers.spaceListScreen.spaceRoomName(spaceServiceRoom.name))
|
||||
.accessibilityIdentifier(A11yIdentifiers.spacesScreen.spaceRoomName(spaceServiceRoom.name))
|
||||
}
|
||||
|
||||
@ViewBuilder @MainActor
|
||||
|
||||
+13
-15
@@ -6,41 +6,39 @@
|
||||
// Please see LICENSE files in the repository root for full details.
|
||||
//
|
||||
|
||||
// periphery:ignore:all - this is just a spaceList remove this comment once generating the final file
|
||||
|
||||
import Combine
|
||||
import SwiftUI
|
||||
|
||||
struct SpaceListScreenCoordinatorParameters {
|
||||
struct SpacesScreenCoordinatorParameters {
|
||||
let userSession: UserSessionProtocol
|
||||
let selectedSpacePublisher: CurrentValuePublisher<String?, Never>
|
||||
let appSettings: AppSettings
|
||||
let userIndicatorController: UserIndicatorControllerProtocol
|
||||
}
|
||||
|
||||
enum SpaceListScreenCoordinatorAction {
|
||||
enum SpacesScreenCoordinatorAction {
|
||||
case selectSpace(SpaceRoomListProxyProtocol)
|
||||
case showSettings
|
||||
}
|
||||
|
||||
final class SpaceListScreenCoordinator: CoordinatorProtocol {
|
||||
private let parameters: SpaceListScreenCoordinatorParameters
|
||||
private let viewModel: SpaceListScreenViewModelProtocol
|
||||
final class SpacesScreenCoordinator: CoordinatorProtocol {
|
||||
private let parameters: SpacesScreenCoordinatorParameters
|
||||
private let viewModel: SpacesScreenViewModelProtocol
|
||||
|
||||
private var cancellables = Set<AnyCancellable>()
|
||||
|
||||
private let actionsSubject: PassthroughSubject<SpaceListScreenCoordinatorAction, Never> = .init()
|
||||
var actionsPublisher: AnyPublisher<SpaceListScreenCoordinatorAction, Never> {
|
||||
private let actionsSubject: PassthroughSubject<SpacesScreenCoordinatorAction, Never> = .init()
|
||||
var actionsPublisher: AnyPublisher<SpacesScreenCoordinatorAction, Never> {
|
||||
actionsSubject.eraseToAnyPublisher()
|
||||
}
|
||||
|
||||
init(parameters: SpaceListScreenCoordinatorParameters) {
|
||||
init(parameters: SpacesScreenCoordinatorParameters) {
|
||||
self.parameters = parameters
|
||||
|
||||
viewModel = SpaceListScreenViewModel(userSession: parameters.userSession,
|
||||
selectedSpacePublisher: parameters.selectedSpacePublisher,
|
||||
appSettings: parameters.appSettings,
|
||||
userIndicatorController: parameters.userIndicatorController)
|
||||
viewModel = SpacesScreenViewModel(userSession: parameters.userSession,
|
||||
selectedSpacePublisher: parameters.selectedSpacePublisher,
|
||||
appSettings: parameters.appSettings,
|
||||
userIndicatorController: parameters.userIndicatorController)
|
||||
}
|
||||
|
||||
func start() {
|
||||
@@ -59,6 +57,6 @@ final class SpaceListScreenCoordinator: CoordinatorProtocol {
|
||||
}
|
||||
|
||||
func toPresentable() -> AnyView {
|
||||
AnyView(SpaceListScreen(context: viewModel.context))
|
||||
AnyView(SpacesScreen(context: viewModel.context))
|
||||
}
|
||||
}
|
||||
+5
-5
@@ -8,12 +8,12 @@
|
||||
|
||||
import Foundation
|
||||
|
||||
enum SpaceListScreenViewModelAction {
|
||||
enum SpacesScreenViewModelAction {
|
||||
case selectSpace(SpaceRoomListProxyProtocol)
|
||||
case showSettings
|
||||
}
|
||||
|
||||
struct SpaceListScreenViewState: BindableState {
|
||||
struct SpacesScreenViewState: BindableState {
|
||||
let userID: String
|
||||
var userDisplayName: String?
|
||||
var userAvatarURL: URL?
|
||||
@@ -23,14 +23,14 @@ struct SpaceListScreenViewState: BindableState {
|
||||
|
||||
var isCreateSpaceEnabled: Bool
|
||||
|
||||
var bindings: SpaceListScreenViewStateBindings
|
||||
var bindings: SpacesScreenViewStateBindings
|
||||
}
|
||||
|
||||
struct SpaceListScreenViewStateBindings {
|
||||
struct SpacesScreenViewStateBindings {
|
||||
var isPresentingFeatureAnnouncement = false
|
||||
}
|
||||
|
||||
enum SpaceListScreenViewAction {
|
||||
enum SpacesScreenViewAction {
|
||||
case spaceAction(SpaceRoomCell.Action)
|
||||
case showSettings
|
||||
case screenAppeared
|
||||
+9
-9
@@ -9,15 +9,15 @@
|
||||
import Combine
|
||||
import SwiftUI
|
||||
|
||||
typealias SpaceListScreenViewModelType = StateStoreViewModelV2<SpaceListScreenViewState, SpaceListScreenViewAction>
|
||||
typealias SpacesScreenViewModelType = StateStoreViewModelV2<SpacesScreenViewState, SpacesScreenViewAction>
|
||||
|
||||
class SpaceListScreenViewModel: SpaceListScreenViewModelType, SpaceListScreenViewModelProtocol {
|
||||
class SpacesScreenViewModel: SpacesScreenViewModelType, SpacesScreenViewModelProtocol {
|
||||
private let spaceServiceProxy: SpaceServiceProxyProtocol
|
||||
private let appSettings: AppSettings
|
||||
private let userIndicatorController: UserIndicatorControllerProtocol
|
||||
|
||||
private let actionsSubject: PassthroughSubject<SpaceListScreenViewModelAction, Never> = .init()
|
||||
var actionsPublisher: AnyPublisher<SpaceListScreenViewModelAction, Never> {
|
||||
private let actionsSubject: PassthroughSubject<SpacesScreenViewModelAction, Never> = .init()
|
||||
var actionsPublisher: AnyPublisher<SpacesScreenViewModelAction, Never> {
|
||||
actionsSubject.eraseToAnyPublisher()
|
||||
}
|
||||
|
||||
@@ -29,10 +29,10 @@ class SpaceListScreenViewModel: SpaceListScreenViewModelType, SpaceListScreenVie
|
||||
self.appSettings = appSettings
|
||||
self.userIndicatorController = userIndicatorController
|
||||
|
||||
super.init(initialViewState: SpaceListScreenViewState(userID: userSession.clientProxy.userID,
|
||||
topLevelSpaces: spaceServiceProxy.topLevelSpacesPublisher.value,
|
||||
isCreateSpaceEnabled: appSettings.createSpaceEnabled,
|
||||
bindings: .init()),
|
||||
super.init(initialViewState: SpacesScreenViewState(userID: userSession.clientProxy.userID,
|
||||
topLevelSpaces: spaceServiceProxy.topLevelSpacesPublisher.value,
|
||||
isCreateSpaceEnabled: appSettings.createSpaceEnabled,
|
||||
bindings: .init()),
|
||||
mediaProvider: userSession.mediaProvider)
|
||||
|
||||
spaceServiceProxy.topLevelSpacesPublisher
|
||||
@@ -61,7 +61,7 @@ class SpaceListScreenViewModel: SpaceListScreenViewModelType, SpaceListScreenVie
|
||||
|
||||
// MARK: - Public
|
||||
|
||||
override func process(viewAction: SpaceListScreenViewAction) {
|
||||
override func process(viewAction: SpacesScreenViewAction) {
|
||||
MXLog.info("View model: received view action: \(viewAction)")
|
||||
|
||||
switch viewAction {
|
||||
+3
-3
@@ -9,7 +9,7 @@
|
||||
import Combine
|
||||
|
||||
@MainActor
|
||||
protocol SpaceListScreenViewModelProtocol {
|
||||
var actionsPublisher: AnyPublisher<SpaceListScreenViewModelAction, Never> { get }
|
||||
var context: SpaceListScreenViewModelType.Context { get }
|
||||
protocol SpacesScreenViewModelProtocol {
|
||||
var actionsPublisher: AnyPublisher<SpacesScreenViewModelAction, Never> { get }
|
||||
var context: SpacesScreenViewModelType.Context { get }
|
||||
}
|
||||
+5
-5
@@ -12,7 +12,7 @@ import SwiftUI
|
||||
struct SpacesAnnouncementSheetView: View {
|
||||
@Environment(\.dismiss) private var dismiss
|
||||
|
||||
let context: SpaceListScreenViewModel.Context
|
||||
let context: SpacesScreenViewModel.Context
|
||||
|
||||
var body: some View {
|
||||
FullscreenDialog(topPadding: 44, horizontalPadding: 24) {
|
||||
@@ -105,10 +105,10 @@ struct SpacesAnnouncementSheetView: View {
|
||||
// MARK: - Previews
|
||||
|
||||
struct SpacesAnnouncementSheetView_Previews: PreviewProvider, TestablePreview {
|
||||
static let viewModel = SpaceListScreenViewModel(userSession: UserSessionMock(.init()),
|
||||
selectedSpacePublisher: .init(nil),
|
||||
appSettings: ServiceLocator.shared.settings,
|
||||
userIndicatorController: UserIndicatorControllerMock())
|
||||
static let viewModel = SpacesScreenViewModel(userSession: UserSessionMock(.init()),
|
||||
selectedSpacePublisher: .init(nil),
|
||||
appSettings: ServiceLocator.shared.settings,
|
||||
userIndicatorController: UserIndicatorControllerMock())
|
||||
|
||||
static var previews: some View {
|
||||
SpacesAnnouncementSheetView(context: viewModel.context)
|
||||
+10
-10
@@ -9,8 +9,8 @@
|
||||
import Compound
|
||||
import SwiftUI
|
||||
|
||||
struct SpaceListScreen: View {
|
||||
@Bindable var context: SpaceListScreenViewModel.Context
|
||||
struct SpacesScreen: View {
|
||||
@Bindable var context: SpacesScreenViewModel.Context
|
||||
|
||||
var body: some View {
|
||||
mainContent
|
||||
@@ -134,22 +134,22 @@ struct SpaceListScreen: View {
|
||||
|
||||
// MARK: - Previews
|
||||
|
||||
struct SpaceListScreen_Previews: PreviewProvider, TestablePreview {
|
||||
struct SpacesScreen_Previews: PreviewProvider, TestablePreview {
|
||||
static let viewModel = makeViewModel()
|
||||
static let emptyViewModel = makeViewModel(isEmpty: true)
|
||||
|
||||
static var previews: some View {
|
||||
NavigationStack {
|
||||
SpaceListScreen(context: viewModel.context)
|
||||
SpacesScreen(context: viewModel.context)
|
||||
}
|
||||
|
||||
NavigationStack {
|
||||
SpaceListScreen(context: emptyViewModel.context)
|
||||
SpacesScreen(context: emptyViewModel.context)
|
||||
}
|
||||
.previewDisplayName("Empty")
|
||||
}
|
||||
|
||||
static func makeViewModel(isEmpty: Bool = false) -> SpaceListScreenViewModel {
|
||||
static func makeViewModel(isEmpty: Bool = false) -> SpacesScreenViewModel {
|
||||
AppSettings.resetAllSettings()
|
||||
let appSettings = AppSettings()
|
||||
appSettings.createSpaceEnabled = true
|
||||
@@ -158,10 +158,10 @@ struct SpaceListScreen_Previews: PreviewProvider, TestablePreview {
|
||||
let clientProxy = ClientProxyMock(.init())
|
||||
clientProxy.spaceService = SpaceServiceProxyMock(.init(topLevelSpaces: isEmpty ? [] : .mockJoinedSpaces))
|
||||
|
||||
let viewModel = SpaceListScreenViewModel(userSession: UserSessionMock(.init(clientProxy: clientProxy)),
|
||||
selectedSpacePublisher: .init(nil),
|
||||
appSettings: appSettings,
|
||||
userIndicatorController: UserIndicatorControllerMock())
|
||||
let viewModel = SpacesScreenViewModel(userSession: UserSessionMock(.init(clientProxy: clientProxy)),
|
||||
selectedSpacePublisher: .init(nil),
|
||||
appSettings: appSettings,
|
||||
userIndicatorController: UserIndicatorControllerMock())
|
||||
|
||||
return viewModel
|
||||
}
|
||||
@@ -12,7 +12,7 @@ import SwiftState
|
||||
|
||||
protocol StateMachineFactoryProtocol {
|
||||
func makeUserSessionFlowStateMachine(state: UserSessionFlowCoordinator.State) -> StateMachine<UserSessionFlowCoordinator.State, UserSessionFlowCoordinator.Event>
|
||||
func makeChatsFlowStateMachine() -> ChatsFlowCoordinatorStateMachine
|
||||
func makeChatsTabFlowStateMachine() -> ChatsTabFlowCoordinatorStateMachine
|
||||
func makeMembersFlowStateMachine(state: RoomMembersFlowCoordinator.State) -> StateMachine<RoomMembersFlowCoordinator.State, RoomMembersFlowCoordinator.Event>
|
||||
}
|
||||
|
||||
@@ -21,7 +21,7 @@ struct StateMachineFactory: StateMachineFactoryProtocol {
|
||||
.init(state: state)
|
||||
}
|
||||
|
||||
func makeChatsFlowStateMachine() -> ChatsFlowCoordinatorStateMachine {
|
||||
func makeChatsTabFlowStateMachine() -> ChatsTabFlowCoordinatorStateMachine {
|
||||
.init()
|
||||
}
|
||||
|
||||
@@ -45,13 +45,13 @@ class PublishedStateMachineFactory: StateMachineFactoryProtocol {
|
||||
return stateMachine
|
||||
}
|
||||
|
||||
// MARK: ChatsFlowCoordinator
|
||||
// MARK: ChatsTabFlowCoordinator
|
||||
|
||||
let chatsFlowStatePublisher = PassthroughSubject<ChatsFlowCoordinatorStateMachine.State, Never>()
|
||||
let chatsTabFlowStatePublisher = PassthroughSubject<ChatsTabFlowCoordinatorStateMachine.State, Never>()
|
||||
|
||||
func makeChatsFlowStateMachine() -> ChatsFlowCoordinatorStateMachine {
|
||||
let stateMachine = baseFactory.makeChatsFlowStateMachine()
|
||||
stateMachine.addTransitionHandler { [weak self] in self?.chatsFlowStatePublisher.send($0.toState) }
|
||||
func makeChatsTabFlowStateMachine() -> ChatsTabFlowCoordinatorStateMachine {
|
||||
let stateMachine = baseFactory.makeChatsTabFlowStateMachine()
|
||||
stateMachine.addTransitionHandler { [weak self] in self?.chatsTabFlowStatePublisher.send($0.toState) }
|
||||
return stateMachine
|
||||
}
|
||||
|
||||
|
||||
@@ -800,21 +800,21 @@ class MockScreen: Identifiable {
|
||||
mediaProvider: MediaProviderMock(configuration: .init()),
|
||||
appSettings: ServiceLocator.shared.settings)
|
||||
|
||||
let flowCoordinator = ChatsFlowCoordinator(isNewLogin: false,
|
||||
navigationSplitCoordinator: navigationSplitCoordinator,
|
||||
flowParameters: CommonFlowParameters(userSession: UserSessionMock(.init(clientProxy: clientProxy)),
|
||||
bugReportService: BugReportServiceMock(.init()),
|
||||
elementCallService: ElementCallServiceMock(.init()),
|
||||
timelineControllerFactory: TimelineControllerFactoryMock(.init(timelineController: timelineController)),
|
||||
emojiProvider: EmojiProvider(appSettings: appSettings),
|
||||
linkMetadataProvider: LinkMetadataProvider(),
|
||||
appMediator: AppMediatorMock.default,
|
||||
appSettings: appSettings,
|
||||
appHooks: AppHooks(),
|
||||
analytics: ServiceLocator.shared.analytics,
|
||||
userIndicatorController: UserIndicatorControllerMock(),
|
||||
notificationManager: NotificationManagerMock(),
|
||||
stateMachineFactory: StateMachineFactory()))
|
||||
let flowCoordinator = ChatsTabFlowCoordinator(isNewLogin: false,
|
||||
navigationSplitCoordinator: navigationSplitCoordinator,
|
||||
flowParameters: CommonFlowParameters(userSession: UserSessionMock(.init(clientProxy: clientProxy)),
|
||||
bugReportService: BugReportServiceMock(.init()),
|
||||
elementCallService: ElementCallServiceMock(.init()),
|
||||
timelineControllerFactory: TimelineControllerFactoryMock(.init(timelineController: timelineController)),
|
||||
emojiProvider: EmojiProvider(appSettings: appSettings),
|
||||
linkMetadataProvider: LinkMetadataProvider(),
|
||||
appMediator: AppMediatorMock.default,
|
||||
appSettings: appSettings,
|
||||
appHooks: AppHooks(),
|
||||
analytics: ServiceLocator.shared.analytics,
|
||||
userIndicatorController: UserIndicatorControllerMock(),
|
||||
notificationManager: NotificationManagerMock(),
|
||||
stateMachineFactory: StateMachineFactory()))
|
||||
|
||||
flowCoordinator.start()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user