refactored the flows to use a state and an event for the transfer ownership screen
This commit is contained in:
@@ -168,7 +168,7 @@ class ChatsTabFlowCoordinator: FlowCoordinatorProtocol {
|
||||
if case .room(roomID) = stateMachine.state.detailState {
|
||||
roomFlowCoordinator?.handleAppRoute(appRoute, animated: animated)
|
||||
} else {
|
||||
stateMachine.processEvent(.selectRoom(roomID: roomID, via: [], entryPoint: .transferOwnership))
|
||||
stateMachine.processEvent(.presentTransferOwnershipScreen(roomID: roomID))
|
||||
}
|
||||
case .accountProvisioningLink, .settings, .chatBackupSettings, .call, .genericCallLink:
|
||||
break // These routes cannot be handled.
|
||||
@@ -251,6 +251,11 @@ class ChatsTabFlowCoordinator: FlowCoordinatorProtocol {
|
||||
case (.declineAndBlockUserScreen, .dismissedDeclineAndBlockScreen, .roomList):
|
||||
break
|
||||
|
||||
case (.roomList, .presentTransferOwnershipScreen(let roomID), .transferOwnershipScreen):
|
||||
Task { await self.presentTransferOwnershipScreen(roomID: roomID) }
|
||||
case (.transferOwnershipScreen, .dismissedTransferOwnershipScreen, .roomList):
|
||||
break
|
||||
|
||||
case (.roomList(let roomListSelectedRoomID), .showShareExtensionRoomList, .shareExtensionRoomList(let sharePayload)):
|
||||
Task {
|
||||
if roomListSelectedRoomID != nil {
|
||||
@@ -469,6 +474,34 @@ class ChatsTabFlowCoordinator: FlowCoordinatorProtocol {
|
||||
}
|
||||
}
|
||||
|
||||
private func presentTransferOwnershipScreen(roomID: String) async {
|
||||
guard case let .joined(roomProxy) = await userSession.clientProxy.roomForIdentifier(roomID) else {
|
||||
return
|
||||
}
|
||||
await roomProxy.subscribeForUpdates()
|
||||
|
||||
let parameters = RoomChangeRolesScreenCoordinatorParameters(mode: .owner,
|
||||
roomProxy: roomProxy,
|
||||
mediaProvider: userSession.mediaProvider,
|
||||
userIndicatorController: flowParameters.userIndicatorController,
|
||||
analytics: flowParameters.analytics)
|
||||
let stackCoordinator = NavigationStackCoordinator()
|
||||
let coordinator = RoomChangeRolesScreenCoordinator(parameters: parameters)
|
||||
coordinator.actionsPublisher.sink { [weak self] action in
|
||||
guard let self else { return }
|
||||
switch action {
|
||||
case .complete:
|
||||
navigationSplitCoordinator.setSheetCoordinator(nil)
|
||||
}
|
||||
}
|
||||
.store(in: &cancellables)
|
||||
|
||||
stackCoordinator.setRootCoordinator(coordinator)
|
||||
navigationSplitCoordinator.setSheetCoordinator(stackCoordinator) { [weak self] in
|
||||
self?.stateMachine.processEvent(.dismissedTransferOwnershipScreen)
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: Room Flow
|
||||
|
||||
private func startRoomFlow(roomID: String,
|
||||
|
||||
@@ -52,6 +52,8 @@ class ChatsTabFlowCoordinatorStateMachine {
|
||||
|
||||
case declineAndBlockUserScreen(detailState: DetailState?)
|
||||
|
||||
case transferOwnershipScreen(detailState: DetailState?)
|
||||
|
||||
/// The state of the currently selected room
|
||||
var detailState: DetailState? {
|
||||
switch self {
|
||||
@@ -65,6 +67,7 @@ class ChatsTabFlowCoordinatorStateMachine {
|
||||
.logoutConfirmationScreen(let detailState),
|
||||
.roomDirectorySearchScreen(let detailState),
|
||||
.reportRoomScreen(let detailState),
|
||||
.transferOwnershipScreen(let detailState),
|
||||
.declineAndBlockUserScreen(let detailState):
|
||||
detailState
|
||||
}
|
||||
@@ -134,6 +137,9 @@ class ChatsTabFlowCoordinatorStateMachine {
|
||||
|
||||
case presentDeclineAndBlockScreen(userID: String, roomID: String)
|
||||
case dismissedDeclineAndBlockScreen
|
||||
|
||||
case presentTransferOwnershipScreen(roomID: String)
|
||||
case dismissedTransferOwnershipScreen
|
||||
}
|
||||
|
||||
private let stateMachine: StateMachine<State, Event>
|
||||
@@ -208,6 +214,11 @@ class ChatsTabFlowCoordinatorStateMachine {
|
||||
case (.declineAndBlockUserScreen(let detailState), .dismissedDeclineAndBlockScreen):
|
||||
return .roomList(detailState: detailState)
|
||||
|
||||
case (.roomList(let detailState), .presentTransferOwnershipScreen):
|
||||
return .transferOwnershipScreen(detailState: detailState)
|
||||
case (.transferOwnershipScreen(let detailState), .dismissedTransferOwnershipScreen):
|
||||
return .roomList(detailState: detailState)
|
||||
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -214,7 +214,7 @@ class RoomFlowCoordinator: FlowCoordinatorProtocol {
|
||||
await storeAndSubscribeToRoomProxy(roomProxy)
|
||||
}
|
||||
|
||||
presentTransferOwnershipScreen()
|
||||
stateMachine.tryEvent(.presentTransferOwnershipScreen)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -274,7 +274,9 @@ class RoomFlowCoordinator: FlowCoordinatorProtocol {
|
||||
.store(in: &cancellables)
|
||||
|
||||
stackCoordinator.setRootCoordinator(coordinator)
|
||||
navigationStackCoordinator.setSheetCoordinator(stackCoordinator, animated: true)
|
||||
navigationStackCoordinator.setSheetCoordinator(stackCoordinator) { [weak self] in
|
||||
self?.stateMachine.tryEvent(.dismissedTransferOwnershipScreen)
|
||||
}
|
||||
}
|
||||
|
||||
private func handleRoomRoute(roomID: String, via: [String], presentationAction: PresentationAction? = nil, animated: Bool) async {
|
||||
@@ -531,6 +533,9 @@ class RoomFlowCoordinator: FlowCoordinatorProtocol {
|
||||
|
||||
case (_, .presentInviteUsersScreen, .inviteUsersScreen):
|
||||
presentInviteUsersScreen()
|
||||
|
||||
case (_, .presentTransferOwnershipScreen, .transferOwnershipScreen):
|
||||
presentTransferOwnershipScreen()
|
||||
|
||||
default:
|
||||
break
|
||||
@@ -937,7 +942,7 @@ class RoomFlowCoordinator: FlowCoordinatorProtocol {
|
||||
case .presentReportRoomScreen:
|
||||
stateMachine.tryEvent(.presentReportRoomScreen)
|
||||
case .transferOwnership:
|
||||
presentTransferOwnershipScreen()
|
||||
stateMachine.tryEvent(.presentTransferOwnershipScreen)
|
||||
}
|
||||
}
|
||||
.store(in: &cancellables)
|
||||
|
||||
@@ -83,6 +83,7 @@ extension RoomFlowCoordinator {
|
||||
case manageAuthorizedSpacesScreen(previousState: State)
|
||||
case reportRoom(previousState: State)
|
||||
case declineAndBlockScreen
|
||||
case transferOwnershipScreen(previousState: State)
|
||||
|
||||
/// A child flow is in progress.
|
||||
case presentingChild(childRoomID: String, previousState: State)
|
||||
@@ -185,6 +186,9 @@ extension RoomFlowCoordinator {
|
||||
case presentDeclineAndBlockScreen(userID: String)
|
||||
case dismissDeclineAndBlockScreen
|
||||
|
||||
case presentTransferOwnershipScreen
|
||||
case dismissedTransferOwnershipScreen
|
||||
|
||||
case startMembersFlow(entryPoint: RoomMembersFlowCoordinatorEntryPoint)
|
||||
case stopMembersFlow
|
||||
}
|
||||
@@ -392,6 +396,11 @@ extension RoomFlowCoordinator {
|
||||
return .inviteUsersScreen(previousState: fromState)
|
||||
case (.inviteUsersScreen(let previousState), .dismissInviteUsersScreen):
|
||||
return previousState
|
||||
|
||||
case (_, .presentTransferOwnershipScreen):
|
||||
return .transferOwnershipScreen(previousState: fromState)
|
||||
case (.transferOwnershipScreen(let previousState), .dismissedTransferOwnershipScreen):
|
||||
return previousState
|
||||
|
||||
default:
|
||||
return nil
|
||||
|
||||
@@ -69,9 +69,11 @@ class SpaceFlowCoordinator: FlowCoordinatorProtocol {
|
||||
case createChildRoomFlow
|
||||
|
||||
case leftSpace
|
||||
|
||||
case transferOwnership
|
||||
}
|
||||
|
||||
enum Event: EventType {
|
||||
enum Event: EventType, Equatable, Hashable {
|
||||
/// The flow is being started.
|
||||
case start
|
||||
/// The flow is being started for an unjoined space.
|
||||
@@ -108,6 +110,9 @@ class SpaceFlowCoordinator: FlowCoordinatorProtocol {
|
||||
|
||||
case startCreateChildRoomFlow
|
||||
case stopCreateChildRoomFlow
|
||||
|
||||
case presentTransferOwnership
|
||||
case dismissedTransferOwnership
|
||||
}
|
||||
|
||||
private let stateMachine: StateMachine<State, Event>
|
||||
@@ -179,6 +184,9 @@ class SpaceFlowCoordinator: FlowCoordinatorProtocol {
|
||||
case .createChildRoomFlow:
|
||||
navigationStackCoordinator.setSheetCoordinator(nil)
|
||||
clearRoute(animated: animated) // Re-run with the state machine back in the .space state.
|
||||
case .transferOwnership:
|
||||
navigationStackCoordinator.setSheetCoordinator(nil)
|
||||
clearRoute(animated: animated) // Re-run with the state machine back in the .space state.
|
||||
}
|
||||
}
|
||||
|
||||
@@ -206,6 +214,12 @@ class SpaceFlowCoordinator: FlowCoordinatorProtocol {
|
||||
}
|
||||
stateMachine.addRoutes(event: .dismissedAddRooms, transitions: [.addingRooms => .space])
|
||||
|
||||
stateMachine.addRoutes(event: .presentTransferOwnership, transitions: [.space => .transferOwnership]) { [weak self] context in
|
||||
guard let self, let roomProxy = context.userInfo as? JoinedRoomProxyProtocol else { return }
|
||||
self.presentTransferOwnershipScreen(roomProxy: roomProxy)
|
||||
}
|
||||
stateMachine.addRoutes(event: .dismissedTransferOwnership, transitions: [.transferOwnership => .space])
|
||||
|
||||
stateMachine.addRouteMapping { event, fromState, userInfo in
|
||||
guard event == .startChildFlow else { return nil }
|
||||
guard let childEntryPoint = userInfo as? SpaceFlowCoordinatorEntryPoint else { fatalError("An entry point must be provided.") }
|
||||
@@ -350,7 +364,7 @@ class SpaceFlowCoordinator: FlowCoordinatorProtocol {
|
||||
case .displayCreateChildRoomFlow(let space):
|
||||
stateMachine.tryEvent(.startCreateChildRoomFlow, userInfo: space)
|
||||
case .displayTransferOwnership(let roomProxy):
|
||||
presentTransferOwnershipScreen(roomProxy: roomProxy)
|
||||
stateMachine.tryEvent(.presentTransferOwnership, userInfo: roomProxy)
|
||||
}
|
||||
}
|
||||
.store(in: &cancellables)
|
||||
@@ -450,16 +464,17 @@ class SpaceFlowCoordinator: FlowCoordinatorProtocol {
|
||||
let stackCoordinator = NavigationStackCoordinator()
|
||||
let coordinator = RoomChangeRolesScreenCoordinator(parameters: parameters)
|
||||
coordinator.actionsPublisher.sink { [weak self] action in
|
||||
guard let self else { return }
|
||||
switch action {
|
||||
case .complete:
|
||||
navigationStackCoordinator.setSheetCoordinator(nil)
|
||||
self?.navigationStackCoordinator.setSheetCoordinator(nil)
|
||||
}
|
||||
}
|
||||
.store(in: &cancellables)
|
||||
|
||||
stackCoordinator.setRootCoordinator(coordinator)
|
||||
navigationStackCoordinator.setSheetCoordinator(stackCoordinator)
|
||||
navigationStackCoordinator.setSheetCoordinator(stackCoordinator) { [weak self] in
|
||||
self?.stateMachine.tryEvent(.dismissedTransferOwnership)
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Other flows
|
||||
|
||||
@@ -35,6 +35,8 @@ final class SpaceSettingsFlowCoordinator: FlowCoordinatorProtocol {
|
||||
case membersFlow
|
||||
|
||||
case manageAuthorizedSpacesScreen
|
||||
|
||||
case transferOwnership
|
||||
}
|
||||
|
||||
enum Event: EventType {
|
||||
@@ -60,6 +62,9 @@ final class SpaceSettingsFlowCoordinator: FlowCoordinatorProtocol {
|
||||
|
||||
case presentManageAuthorizedSpacesScreen
|
||||
case dismissedManageAuthorizedSpacesScreen
|
||||
|
||||
case presentTransferOwnership
|
||||
case dismissedTransferOwnership
|
||||
}
|
||||
|
||||
private let roomProxy: JoinedRoomProxyProtocol
|
||||
@@ -135,6 +140,11 @@ final class SpaceSettingsFlowCoordinator: FlowCoordinatorProtocol {
|
||||
return .manageAuthorizedSpacesScreen
|
||||
case (.manageAuthorizedSpacesScreen, .dismissedManageAuthorizedSpacesScreen):
|
||||
return .securityAndPrivacy
|
||||
|
||||
case (.spaceSettings, .presentTransferOwnership):
|
||||
return .transferOwnership
|
||||
case (.transferOwnership, .dismissedTransferOwnership):
|
||||
return .spaceSettings
|
||||
|
||||
case (.spaceSettings, .startMembersListFlow):
|
||||
return .membersFlow
|
||||
@@ -181,7 +191,12 @@ final class SpaceSettingsFlowCoordinator: FlowCoordinatorProtocol {
|
||||
presentManageAuthorizedSpacesScreen(selection: selection)
|
||||
case (.manageAuthorizedSpacesScreen, .dismissedManageAuthorizedSpacesScreen, .securityAndPrivacy):
|
||||
break
|
||||
|
||||
|
||||
case (.spaceSettings, .presentTransferOwnership, .transferOwnership):
|
||||
presentTransferOwnershipScreen()
|
||||
case (.transferOwnership, .dismissedTransferOwnership, .spaceSettings):
|
||||
break
|
||||
|
||||
case (.spaceSettings, .startMembersListFlow, .membersFlow):
|
||||
startMembersListFlow()
|
||||
case (.membersFlow, .stopMembersListFlow, .spaceSettings):
|
||||
@@ -223,7 +238,7 @@ final class SpaceSettingsFlowCoordinator: FlowCoordinatorProtocol {
|
||||
leftRoom = true
|
||||
navigationStackCoordinator.pop()
|
||||
case .transferOwnership:
|
||||
presentTransferOwnershipScreen()
|
||||
stateMachine.tryEvent(.presentTransferOwnership)
|
||||
case .presentRecipientDetails, .presentNotificationSettingsScreen, .presentReportRoomScreen,
|
||||
.presentInviteUsersScreen, .presentPollsHistory, .presentCall,
|
||||
.presentPinnedEventsTimeline, .presentMediaEventsTimeline, .presentKnockingRequestsListScreen:
|
||||
@@ -336,16 +351,17 @@ final class SpaceSettingsFlowCoordinator: FlowCoordinatorProtocol {
|
||||
let stackCoordinator = NavigationStackCoordinator()
|
||||
let coordinator = RoomChangeRolesScreenCoordinator(parameters: parameters)
|
||||
coordinator.actionsPublisher.sink { [weak self] action in
|
||||
guard let self else { return }
|
||||
switch action {
|
||||
case .complete:
|
||||
navigationStackCoordinator.setSheetCoordinator(nil)
|
||||
self?.navigationStackCoordinator.setSheetCoordinator(nil)
|
||||
}
|
||||
}
|
||||
.store(in: &cancellables)
|
||||
|
||||
stackCoordinator.setRootCoordinator(coordinator)
|
||||
navigationStackCoordinator.setSheetCoordinator(stackCoordinator, animated: true)
|
||||
navigationStackCoordinator.setSheetCoordinator(stackCoordinator) { [weak self] in
|
||||
self?.stateMachine.tryEvent(.dismissedTransferOwnership)
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Other flows
|
||||
|
||||
@@ -99,7 +99,7 @@ struct RoomChangeRolesScreen: View {
|
||||
.disabled(!context.viewState.hasChanges)
|
||||
}
|
||||
|
||||
if context.viewState.mode == .owner {
|
||||
if context.viewState.mode == .owner || context.viewState.hasChanges {
|
||||
ToolbarItem(placement: .cancellationAction) {
|
||||
ToolbarButton(role: .cancel) {
|
||||
context.send(viewAction: .cancel)
|
||||
|
||||
@@ -66,7 +66,7 @@ struct LeaveSpaceView: View {
|
||||
Section {
|
||||
ForEach(context.viewState.leaveHandle.rooms, id: \.spaceServiceRoom.id) { room in
|
||||
LeaveSpaceRoomDetailsCell(room: room,
|
||||
hideSelection: !context.viewState.leaveHandle.canLeave,
|
||||
hideSelection: !room.canLeave,
|
||||
mediaProvider: context.mediaProvider) {
|
||||
context.send(viewAction: .toggleRoom(roomID: room.spaceServiceRoom.id))
|
||||
}
|
||||
|
||||
@@ -79,7 +79,7 @@ final class SpaceScreenCoordinator: CoordinatorProtocol {
|
||||
actionsSubject.send(.addExistingChildren)
|
||||
case .displayCreateChildRoomFlow(let space):
|
||||
actionsSubject.send(.displayCreateChildRoomFlow(space: space))
|
||||
case .presentTransferOwnership(roomProxy: let roomProxy):
|
||||
case .presentTransferOwnership(let roomProxy):
|
||||
actionsSubject.send(.displayTransferOwnership(roomProxy: roomProxy))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -254,7 +254,7 @@ class SpaceScreenViewModel: SpaceScreenViewModelType, SpaceScreenViewModelProtoc
|
||||
state.bindings.leaveSpaceViewModel = nil
|
||||
case .presentRolesAndPermissions:
|
||||
guard let roomProxy = state.roomProxy else {
|
||||
fatalError("The space screen should always have a room proxy")
|
||||
fatalError("There should always be a room proxy available for joined spaces.")
|
||||
}
|
||||
state.bindings.leaveSpaceViewModel = nil
|
||||
actionsSubject.send(.presentRolesAndPermissions(roomProxy: roomProxy))
|
||||
@@ -263,7 +263,7 @@ class SpaceScreenViewModel: SpaceScreenViewModelType, SpaceScreenViewModelProtoc
|
||||
actionsSubject.send(.leftSpace)
|
||||
case .presentTransferOwnership:
|
||||
guard let roomProxy = state.roomProxy else {
|
||||
fatalError("The space screen should always have a room proxy")
|
||||
fatalError("There should always be a room proxy available for joined spaces.")
|
||||
}
|
||||
state.bindings.leaveSpaceViewModel = nil
|
||||
actionsSubject.send(.presentTransferOwnership(roomProxy: roomProxy))
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:c9ad306e0be48b82c3d289c1900afdf79b2efcf0403f3e86cbb09013e7705a16
|
||||
size 143185
|
||||
oid sha256:60e6e432817c3a55835ce744166ff3a9f9af6977109b98abb5c1103a88480ae1
|
||||
size 138961
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:153e608bd51747e151a6901bfc4214ef355d4f2b422e28c16e888948306c6c70
|
||||
size 166095
|
||||
oid sha256:3b6a5f02f6177dd4bb2ea2897365c20339082fdbd08d0851246662937e746afd
|
||||
size 162011
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:7c1946343246044027e21fc27989935ee7fa80768f76542fc8a56c9eca4db792
|
||||
size 93713
|
||||
oid sha256:5fcd4c08581c9c01569b6297e7122067e30bf29a5c82ad142f41269d58939fe9
|
||||
size 90649
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:6ed5e1592778ff49f919299c9f7fc2e530827890310f9af77133acdc12633a9f
|
||||
size 121020
|
||||
oid sha256:d386b1c14b44d784e78d1f52ade674d4118f3aefc865f83a5c66aaeaff2f5861
|
||||
size 118139
|
||||
|
||||
Reference in New Issue
Block a user