mirror of
https://github.com/Novaloop-AG/element-x-ios.git
synced 2026-11-04 19:44:05 +00:00
Move RoomFlowCoordinator state machine elements to a separate file.
This commit is contained in:
committed by
Stefan Ceriu
parent
210a0dba1a
commit
99c3cd7872
@@ -745,6 +745,7 @@
|
|||||||
8DCA1F05C3BA6ED826F1599D /* RoomSelectionScreenViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 83B4E3F1265581683E4997B8 /* RoomSelectionScreenViewModel.swift */; };
|
8DCA1F05C3BA6ED826F1599D /* RoomSelectionScreenViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 83B4E3F1265581683E4997B8 /* RoomSelectionScreenViewModel.swift */; };
|
||||||
8DCD9CC5361FF22A5B2C20F1 /* AppLockSetupSettingsScreenCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3D9FCE4D1E3A81AC1CC5CB91 /* AppLockSetupSettingsScreenCoordinator.swift */; };
|
8DCD9CC5361FF22A5B2C20F1 /* AppLockSetupSettingsScreenCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3D9FCE4D1E3A81AC1CC5CB91 /* AppLockSetupSettingsScreenCoordinator.swift */; };
|
||||||
8DDC6F28C797D8685F2F8E32 /* AnalyticsConsentState.swift in Sources */ = {isa = PBXBuildFile; fileRef = 57B6B383F1FD04CC0E7B60C6 /* AnalyticsConsentState.swift */; };
|
8DDC6F28C797D8685F2F8E32 /* AnalyticsConsentState.swift in Sources */ = {isa = PBXBuildFile; fileRef = 57B6B383F1FD04CC0E7B60C6 /* AnalyticsConsentState.swift */; };
|
||||||
|
8DF0EBD97753033C715D716E /* RoomFlowCoordinatorStateMachine.swift in Sources */ = {isa = PBXBuildFile; fileRef = 407C8DD85179D2DB896FC0FA /* RoomFlowCoordinatorStateMachine.swift */; };
|
||||||
8E650379587C31D7912ED67B /* UNNotification+Creator.swift in Sources */ = {isa = PBXBuildFile; fileRef = DC0AEA686E425F86F6BA0404 /* UNNotification+Creator.swift */; };
|
8E650379587C31D7912ED67B /* UNNotification+Creator.swift in Sources */ = {isa = PBXBuildFile; fileRef = DC0AEA686E425F86F6BA0404 /* UNNotification+Creator.swift */; };
|
||||||
8E7A902CA16E24928F83646C /* ElementCallServiceMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = E321E840DCC63790049984F4 /* ElementCallServiceMock.swift */; };
|
8E7A902CA16E24928F83646C /* ElementCallServiceMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = E321E840DCC63790049984F4 /* ElementCallServiceMock.swift */; };
|
||||||
8ED8AF57A06F5EE9978ED23F /* AuthenticationStartScreenViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8FB89DC7F9A4A91020037001 /* AuthenticationStartScreenViewModelTests.swift */; };
|
8ED8AF57A06F5EE9978ED23F /* AuthenticationStartScreenViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8FB89DC7F9A4A91020037001 /* AuthenticationStartScreenViewModelTests.swift */; };
|
||||||
@@ -1695,6 +1696,7 @@
|
|||||||
40316EFFEAC7B206EE9A55AE /* SecureBackupScreenViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SecureBackupScreenViewModelTests.swift; sourceTree = "<group>"; };
|
40316EFFEAC7B206EE9A55AE /* SecureBackupScreenViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SecureBackupScreenViewModelTests.swift; sourceTree = "<group>"; };
|
||||||
4048547AC50ADCF201684E87 /* EditRoomAddressScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EditRoomAddressScreen.swift; sourceTree = "<group>"; };
|
4048547AC50ADCF201684E87 /* EditRoomAddressScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EditRoomAddressScreen.swift; sourceTree = "<group>"; };
|
||||||
406C90AF8C3E98DF5D4E5430 /* ElementCallServiceConstants.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ElementCallServiceConstants.swift; sourceTree = "<group>"; };
|
406C90AF8C3E98DF5D4E5430 /* ElementCallServiceConstants.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ElementCallServiceConstants.swift; sourceTree = "<group>"; };
|
||||||
|
407C8DD85179D2DB896FC0FA /* RoomFlowCoordinatorStateMachine.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomFlowCoordinatorStateMachine.swift; sourceTree = "<group>"; };
|
||||||
40A66E8BC8D9AE4A08EFB2DF /* RoomInfoProxy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomInfoProxy.swift; sourceTree = "<group>"; };
|
40A66E8BC8D9AE4A08EFB2DF /* RoomInfoProxy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomInfoProxy.swift; sourceTree = "<group>"; };
|
||||||
40B21E611DADDEF00307E7AC /* String.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = String.swift; sourceTree = "<group>"; };
|
40B21E611DADDEF00307E7AC /* String.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = String.swift; sourceTree = "<group>"; };
|
||||||
4100DDE6BF3C566AB66B80CC /* MentionSuggestionItemView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MentionSuggestionItemView.swift; sourceTree = "<group>"; };
|
4100DDE6BF3C566AB66B80CC /* MentionSuggestionItemView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MentionSuggestionItemView.swift; sourceTree = "<group>"; };
|
||||||
@@ -4000,6 +4002,7 @@
|
|||||||
C3285BD95B564CA2A948E511 /* OnboardingFlowCoordinator.swift */,
|
C3285BD95B564CA2A948E511 /* OnboardingFlowCoordinator.swift */,
|
||||||
A54AAF72E821B4084B7E4298 /* PinnedEventsTimelineFlowCoordinator.swift */,
|
A54AAF72E821B4084B7E4298 /* PinnedEventsTimelineFlowCoordinator.swift */,
|
||||||
9A008E57D52B07B78DFAD1BB /* RoomFlowCoordinator.swift */,
|
9A008E57D52B07B78DFAD1BB /* RoomFlowCoordinator.swift */,
|
||||||
|
407C8DD85179D2DB896FC0FA /* RoomFlowCoordinatorStateMachine.swift */,
|
||||||
0833F51229E166BCA141D004 /* RoomRolesAndPermissionsFlowCoordinator.swift */,
|
0833F51229E166BCA141D004 /* RoomRolesAndPermissionsFlowCoordinator.swift */,
|
||||||
D28F7A6CEEA4A2815B0F0F55 /* SettingsFlowCoordinator.swift */,
|
D28F7A6CEEA4A2815B0F0F55 /* SettingsFlowCoordinator.swift */,
|
||||||
C99FDEEB71173C4C6FA2734C /* UserSessionFlowCoordinator.swift */,
|
C99FDEEB71173C4C6FA2734C /* UserSessionFlowCoordinator.swift */,
|
||||||
@@ -7529,6 +7532,7 @@
|
|||||||
1DC227816777A2F3A19657E5 /* RoomDirectorySearchScreenViewModel.swift in Sources */,
|
1DC227816777A2F3A19657E5 /* RoomDirectorySearchScreenViewModel.swift in Sources */,
|
||||||
42F1C8731166633E35A6D7E6 /* RoomEventStringBuilder.swift in Sources */,
|
42F1C8731166633E35A6D7E6 /* RoomEventStringBuilder.swift in Sources */,
|
||||||
D55AF9B5B55FEED04771A461 /* RoomFlowCoordinator.swift in Sources */,
|
D55AF9B5B55FEED04771A461 /* RoomFlowCoordinator.swift in Sources */,
|
||||||
|
8DF0EBD97753033C715D716E /* RoomFlowCoordinatorStateMachine.swift in Sources */,
|
||||||
9C63171267E22FEB288EC860 /* RoomHeaderView.swift in Sources */,
|
9C63171267E22FEB288EC860 /* RoomHeaderView.swift in Sources */,
|
||||||
5C8804B4F25903516E2DAB81 /* RoomInfoProxy.swift in Sources */,
|
5C8804B4F25903516E2DAB81 /* RoomInfoProxy.swift in Sources */,
|
||||||
8A83D715940378B9BA9F739E /* RoomInviterLabel.swift in Sources */,
|
8A83D715940378B9BA9F739E /* RoomInviterLabel.swift in Sources */,
|
||||||
|
|||||||
@@ -51,29 +51,6 @@ struct FocusEvent: Hashable {
|
|||||||
let shouldSetPin: Bool
|
let shouldSetPin: Bool
|
||||||
}
|
}
|
||||||
|
|
||||||
private enum PresentationAction: Hashable {
|
|
||||||
case eventFocus(FocusEvent)
|
|
||||||
case share(ShareExtensionPayload)
|
|
||||||
|
|
||||||
var focusedEvent: FocusEvent? {
|
|
||||||
switch self {
|
|
||||||
case .eventFocus(let focusEvent):
|
|
||||||
focusEvent
|
|
||||||
default:
|
|
||||||
nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var sharedText: String? {
|
|
||||||
switch self {
|
|
||||||
case .share(.text(_, let text)):
|
|
||||||
text
|
|
||||||
default:
|
|
||||||
nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// swiftlint:disable:next type_body_length
|
// swiftlint:disable:next type_body_length
|
||||||
class RoomFlowCoordinator: FlowCoordinatorProtocol {
|
class RoomFlowCoordinator: FlowCoordinatorProtocol {
|
||||||
private let roomID: String
|
private let roomID: String
|
||||||
@@ -290,163 +267,7 @@ class RoomFlowCoordinator: FlowCoordinatorProtocol {
|
|||||||
|
|
||||||
// swiftlint:disable:next function_body_length
|
// swiftlint:disable:next function_body_length
|
||||||
private func setupStateMachine() {
|
private func setupStateMachine() {
|
||||||
stateMachine.addRouteMapping { event, fromState, _ in
|
addRouteMapping(stateMachine: stateMachine)
|
||||||
switch (fromState, event) {
|
|
||||||
case (_, .presentJoinRoomScreen):
|
|
||||||
return .joinRoomScreen
|
|
||||||
case (_, .dismissJoinRoomScreen):
|
|
||||||
return .complete
|
|
||||||
|
|
||||||
case (_, .presentRoom):
|
|
||||||
return .room
|
|
||||||
case (_, .dismissFlow):
|
|
||||||
return .complete
|
|
||||||
|
|
||||||
case (_, .presentThread(let itemID)):
|
|
||||||
return .thread(itemID: itemID)
|
|
||||||
case (_, .dismissThread):
|
|
||||||
return .room
|
|
||||||
|
|
||||||
case (.initial, .presentRoomDetails):
|
|
||||||
return .roomDetails(isRoot: true)
|
|
||||||
case (.room, .presentRoomDetails):
|
|
||||||
return .roomDetails(isRoot: false)
|
|
||||||
case (.roomDetails, .dismissRoomDetails):
|
|
||||||
return .room
|
|
||||||
|
|
||||||
case (.roomDetails, .presentRoomDetailsEditScreen):
|
|
||||||
return .roomDetailsEditScreen
|
|
||||||
case (.roomDetailsEditScreen, .dismissRoomDetailsEditScreen):
|
|
||||||
return .roomDetails(isRoot: false)
|
|
||||||
|
|
||||||
case (.roomDetails, .presentNotificationSettingsScreen):
|
|
||||||
return .notificationSettings
|
|
||||||
case (.notificationSettings, .dismissNotificationSettingsScreen):
|
|
||||||
return .roomDetails(isRoot: false)
|
|
||||||
|
|
||||||
case (.notificationSettings, .presentGlobalNotificationSettingsScreen):
|
|
||||||
return .globalNotificationSettings
|
|
||||||
case (.globalNotificationSettings, .dismissGlobalNotificationSettingsScreen):
|
|
||||||
return .notificationSettings
|
|
||||||
|
|
||||||
case (.roomDetails, .presentRoomMembersList):
|
|
||||||
return .roomMembersList
|
|
||||||
case (.roomMembersList, .dismissRoomMembersList):
|
|
||||||
return .roomDetails(isRoot: false)
|
|
||||||
|
|
||||||
case (_, .presentRoomMemberDetails(userID: let userID)):
|
|
||||||
return .roomMemberDetails(userID: userID, previousState: fromState)
|
|
||||||
case (.roomMemberDetails(_, let previousState), .dismissRoomMemberDetails):
|
|
||||||
return previousState
|
|
||||||
|
|
||||||
case (.roomMemberDetails(_, let previousState), .presentUserProfile(let userID)):
|
|
||||||
return .userProfile(userID: userID, previousState: previousState)
|
|
||||||
case (.userProfile(_, let previousState), .dismissUserProfile):
|
|
||||||
return previousState
|
|
||||||
|
|
||||||
case (_, .presentInviteUsersScreen):
|
|
||||||
return .inviteUsersScreen(previousState: fromState)
|
|
||||||
case (.inviteUsersScreen(let previousState), .dismissInviteUsersScreen):
|
|
||||||
return previousState
|
|
||||||
|
|
||||||
case (.room, .presentReportContent(let itemID, let senderID)):
|
|
||||||
return .reportContent(itemID: itemID, senderID: senderID)
|
|
||||||
case (.reportContent, .dismissReportContent):
|
|
||||||
return .room
|
|
||||||
|
|
||||||
case (.room, .presentMediaUploadPicker(let source)):
|
|
||||||
return .mediaUploadPicker(source: source)
|
|
||||||
case (.mediaUploadPicker, .dismissMediaUploadPicker):
|
|
||||||
return .room
|
|
||||||
|
|
||||||
case (.mediaUploadPicker, .presentMediaUploadPreview(let fileURL)):
|
|
||||||
return .mediaUploadPreview(fileURL: fileURL)
|
|
||||||
case (.room, .presentMediaUploadPreview(let fileURL)):
|
|
||||||
return .mediaUploadPreview(fileURL: fileURL)
|
|
||||||
case (.mediaUploadPreview, .dismissMediaUploadPreview):
|
|
||||||
return .room
|
|
||||||
|
|
||||||
case (.room, .presentEmojiPicker(let itemID, let selectedEmoji)):
|
|
||||||
return .emojiPicker(itemID: itemID, selectedEmojis: selectedEmoji)
|
|
||||||
case (.emojiPicker, .dismissEmojiPicker):
|
|
||||||
return .room
|
|
||||||
|
|
||||||
case (.room, .presentMessageForwarding(let forwardingItem)):
|
|
||||||
return .messageForwarding(forwardingItem: forwardingItem)
|
|
||||||
case (.messageForwarding, .dismissMessageForwarding):
|
|
||||||
return .room
|
|
||||||
|
|
||||||
case (.room, .presentMapNavigator):
|
|
||||||
return .mapNavigator
|
|
||||||
case (.mapNavigator, .dismissMapNavigator):
|
|
||||||
return .room
|
|
||||||
|
|
||||||
case (.room, .presentPollForm):
|
|
||||||
return .pollForm
|
|
||||||
case (.pollForm, .dismissPollForm):
|
|
||||||
return .room
|
|
||||||
|
|
||||||
case (.room, .presentPinnedEventsTimeline):
|
|
||||||
return .pinnedEventsTimeline(previousState: fromState)
|
|
||||||
case (.roomDetails, .presentPinnedEventsTimeline):
|
|
||||||
return .pinnedEventsTimeline(previousState: fromState)
|
|
||||||
case (.pinnedEventsTimeline(let previousState), .dismissPinnedEventsTimeline):
|
|
||||||
return previousState
|
|
||||||
|
|
||||||
case (.roomDetails, .presentPollsHistory):
|
|
||||||
return .pollsHistory
|
|
||||||
case (.pollsHistory, .dismissPollsHistory):
|
|
||||||
return .roomDetails(isRoot: false)
|
|
||||||
|
|
||||||
case (.pollsHistory, .presentPollForm):
|
|
||||||
return .pollsHistoryForm
|
|
||||||
case (.pollsHistoryForm, .dismissPollForm):
|
|
||||||
return .pollsHistory
|
|
||||||
|
|
||||||
case (.roomDetails, .presentRolesAndPermissionsScreen):
|
|
||||||
return .rolesAndPermissions
|
|
||||||
case (.rolesAndPermissions, .dismissRolesAndPermissionsScreen):
|
|
||||||
return .roomDetails(isRoot: false)
|
|
||||||
|
|
||||||
case (.room, .presentResolveSendFailure):
|
|
||||||
return .resolveSendFailure
|
|
||||||
case (.resolveSendFailure, .dismissResolveSendFailure):
|
|
||||||
return .room
|
|
||||||
|
|
||||||
case (_, .startChildFlow(let roomID, _, _)):
|
|
||||||
return .presentingChild(childRoomID: roomID, previousState: fromState)
|
|
||||||
case (.presentingChild(_, let previousState), .dismissChildFlow):
|
|
||||||
return previousState
|
|
||||||
|
|
||||||
case (_, .presentKnockRequestsListScreen):
|
|
||||||
return .knockRequestsList(previousState: fromState)
|
|
||||||
case (.knockRequestsList(let previousState), .dismissKnockRequestsListScreen):
|
|
||||||
return previousState
|
|
||||||
|
|
||||||
case (.roomDetails, .presentMediaEventsTimeline):
|
|
||||||
return .mediaEventsTimeline(previousState: fromState)
|
|
||||||
case (.mediaEventsTimeline(let previousState), .dismissMediaEventsTimeline):
|
|
||||||
return previousState
|
|
||||||
|
|
||||||
case (.roomDetails, .presentSecurityAndPrivacyScreen):
|
|
||||||
return .securityAndPrivacy(previousState: fromState)
|
|
||||||
case (.securityAndPrivacy(let previousState), .dismissSecurityAndPrivacyScreen):
|
|
||||||
return previousState
|
|
||||||
|
|
||||||
case (.roomDetails, .presentReportRoomScreen):
|
|
||||||
return .reportRoom(previousState: fromState)
|
|
||||||
case (.reportRoom(let previousState), .dismissReportRoomScreen):
|
|
||||||
return previousState
|
|
||||||
|
|
||||||
case (.joinRoomScreen, .presentDeclineAndBlockScreen):
|
|
||||||
return .declineAndBlockScreen
|
|
||||||
case (.declineAndBlockScreen, .dismissDeclineAndBlockScreen):
|
|
||||||
return .joinRoomScreen
|
|
||||||
|
|
||||||
default:
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
stateMachine.addAnyHandler(.any => .any) { [weak self] context in
|
stateMachine.addAnyHandler(.any => .any) { [weak self] context in
|
||||||
guard let self else { return }
|
guard let self else { return }
|
||||||
@@ -1804,144 +1625,3 @@ class RoomFlowCoordinator: FlowCoordinatorProtocol {
|
|||||||
userIndicatorController.retractIndicatorWithId(Self.loadingIndicatorID)
|
userIndicatorController.retractIndicatorWithId(Self.loadingIndicatorID)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private extension RoomFlowCoordinator {
|
|
||||||
struct HashableRoomMemberWrapper: Hashable {
|
|
||||||
let value: RoomMemberProxyProtocol
|
|
||||||
|
|
||||||
static func == (lhs: HashableRoomMemberWrapper, rhs: HashableRoomMemberWrapper) -> Bool {
|
|
||||||
lhs.value.userID == rhs.value.userID
|
|
||||||
}
|
|
||||||
|
|
||||||
func hash(into hasher: inout Hasher) {
|
|
||||||
hasher.combine(value.userID)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
indirect enum State: StateType {
|
|
||||||
case initial
|
|
||||||
case joinRoomScreen
|
|
||||||
case room
|
|
||||||
case thread(itemID: TimelineItemIdentifier)
|
|
||||||
case roomDetails(isRoot: Bool)
|
|
||||||
case roomDetailsEditScreen
|
|
||||||
case notificationSettings
|
|
||||||
case globalNotificationSettings
|
|
||||||
case roomMembersList
|
|
||||||
case roomMemberDetails(userID: String, previousState: State)
|
|
||||||
case userProfile(userID: String, previousState: State)
|
|
||||||
case inviteUsersScreen(previousState: State)
|
|
||||||
case mediaUploadPicker(source: MediaPickerScreenSource)
|
|
||||||
case mediaUploadPreview(fileURL: URL)
|
|
||||||
case emojiPicker(itemID: TimelineItemIdentifier, selectedEmojis: Set<String>)
|
|
||||||
case mapNavigator
|
|
||||||
case messageForwarding(forwardingItem: MessageForwardingItem)
|
|
||||||
case reportContent(itemID: TimelineItemIdentifier, senderID: String)
|
|
||||||
case pollForm
|
|
||||||
case pollsHistory
|
|
||||||
case pollsHistoryForm
|
|
||||||
case rolesAndPermissions
|
|
||||||
case pinnedEventsTimeline(previousState: State)
|
|
||||||
case resolveSendFailure
|
|
||||||
case knockRequestsList(previousState: State)
|
|
||||||
case mediaEventsTimeline(previousState: State)
|
|
||||||
case securityAndPrivacy(previousState: State)
|
|
||||||
case reportRoom(previousState: State)
|
|
||||||
case declineAndBlockScreen
|
|
||||||
|
|
||||||
/// A child flow is in progress.
|
|
||||||
case presentingChild(childRoomID: String, previousState: State)
|
|
||||||
/// The flow is complete and is handing control of the stack back to its parent.
|
|
||||||
case complete
|
|
||||||
}
|
|
||||||
|
|
||||||
struct EventUserInfo {
|
|
||||||
let animated: Bool
|
|
||||||
}
|
|
||||||
|
|
||||||
enum Event: EventType {
|
|
||||||
case presentJoinRoomScreen(via: [String])
|
|
||||||
case dismissJoinRoomScreen
|
|
||||||
|
|
||||||
case presentRoom(presentationAction: PresentationAction?)
|
|
||||||
case dismissFlow
|
|
||||||
|
|
||||||
case presentThread(itemID: TimelineItemIdentifier)
|
|
||||||
case dismissThread
|
|
||||||
|
|
||||||
case presentReportContent(itemID: TimelineItemIdentifier, senderID: String)
|
|
||||||
case dismissReportContent
|
|
||||||
|
|
||||||
case presentRoomDetails
|
|
||||||
case dismissRoomDetails
|
|
||||||
|
|
||||||
case presentRoomDetailsEditScreen
|
|
||||||
case dismissRoomDetailsEditScreen
|
|
||||||
|
|
||||||
case presentNotificationSettingsScreen
|
|
||||||
case dismissNotificationSettingsScreen
|
|
||||||
|
|
||||||
case presentGlobalNotificationSettingsScreen
|
|
||||||
case dismissGlobalNotificationSettingsScreen
|
|
||||||
|
|
||||||
case presentRoomMembersList
|
|
||||||
case dismissRoomMembersList
|
|
||||||
|
|
||||||
case presentRoomMemberDetails(userID: String)
|
|
||||||
case dismissRoomMemberDetails
|
|
||||||
|
|
||||||
case presentUserProfile(userID: String)
|
|
||||||
case dismissUserProfile
|
|
||||||
|
|
||||||
case presentInviteUsersScreen
|
|
||||||
case dismissInviteUsersScreen
|
|
||||||
|
|
||||||
case presentMediaUploadPicker(source: MediaPickerScreenSource)
|
|
||||||
case dismissMediaUploadPicker
|
|
||||||
|
|
||||||
case presentMediaUploadPreview(fileURL: URL)
|
|
||||||
case dismissMediaUploadPreview
|
|
||||||
|
|
||||||
case presentEmojiPicker(itemID: TimelineItemIdentifier, selectedEmojis: Set<String>)
|
|
||||||
case dismissEmojiPicker
|
|
||||||
|
|
||||||
case presentMapNavigator(interactionMode: StaticLocationInteractionMode)
|
|
||||||
case dismissMapNavigator
|
|
||||||
|
|
||||||
case presentMessageForwarding(forwardingItem: MessageForwardingItem)
|
|
||||||
case dismissMessageForwarding
|
|
||||||
|
|
||||||
case presentPollForm(mode: PollFormMode)
|
|
||||||
case dismissPollForm
|
|
||||||
|
|
||||||
case presentPollsHistory
|
|
||||||
case dismissPollsHistory
|
|
||||||
|
|
||||||
case presentRolesAndPermissionsScreen
|
|
||||||
case dismissRolesAndPermissionsScreen
|
|
||||||
|
|
||||||
case presentPinnedEventsTimeline
|
|
||||||
case dismissPinnedEventsTimeline
|
|
||||||
|
|
||||||
case presentResolveSendFailure(failure: TimelineItemSendFailure.VerifiedUser, sendHandle: SendHandleProxy)
|
|
||||||
case dismissResolveSendFailure
|
|
||||||
|
|
||||||
case startChildFlow(roomID: String, via: [String], entryPoint: RoomFlowCoordinatorEntryPoint)
|
|
||||||
case dismissChildFlow
|
|
||||||
|
|
||||||
case presentKnockRequestsListScreen
|
|
||||||
case dismissKnockRequestsListScreen
|
|
||||||
|
|
||||||
case presentMediaEventsTimeline
|
|
||||||
case dismissMediaEventsTimeline
|
|
||||||
|
|
||||||
case presentSecurityAndPrivacyScreen
|
|
||||||
case dismissSecurityAndPrivacyScreen
|
|
||||||
|
|
||||||
case presentReportRoomScreen
|
|
||||||
case dismissReportRoomScreen
|
|
||||||
|
|
||||||
case presentDeclineAndBlockScreen(userID: String)
|
|
||||||
case dismissDeclineAndBlockScreen
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -0,0 +1,334 @@
|
|||||||
|
//
|
||||||
|
// Copyright 2025 New Vector 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
|
||||||
|
import SwiftState
|
||||||
|
|
||||||
|
extension RoomFlowCoordinator {
|
||||||
|
struct HashableRoomMemberWrapper: Hashable {
|
||||||
|
let value: RoomMemberProxyProtocol
|
||||||
|
|
||||||
|
static func == (lhs: HashableRoomMemberWrapper, rhs: HashableRoomMemberWrapper) -> Bool {
|
||||||
|
lhs.value.userID == rhs.value.userID
|
||||||
|
}
|
||||||
|
|
||||||
|
func hash(into hasher: inout Hasher) {
|
||||||
|
hasher.combine(value.userID)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
enum PresentationAction: Hashable {
|
||||||
|
case eventFocus(FocusEvent)
|
||||||
|
case share(ShareExtensionPayload)
|
||||||
|
|
||||||
|
var focusedEvent: FocusEvent? {
|
||||||
|
switch self {
|
||||||
|
case .eventFocus(let focusEvent):
|
||||||
|
focusEvent
|
||||||
|
default:
|
||||||
|
nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var sharedText: String? {
|
||||||
|
switch self {
|
||||||
|
case .share(.text(_, let text)):
|
||||||
|
text
|
||||||
|
default:
|
||||||
|
nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
indirect enum State: StateType {
|
||||||
|
case initial
|
||||||
|
case joinRoomScreen
|
||||||
|
case room
|
||||||
|
case thread(itemID: TimelineItemIdentifier)
|
||||||
|
case roomDetails(isRoot: Bool)
|
||||||
|
case roomDetailsEditScreen
|
||||||
|
case notificationSettings
|
||||||
|
case globalNotificationSettings
|
||||||
|
case roomMembersList
|
||||||
|
case roomMemberDetails(userID: String, previousState: State)
|
||||||
|
case userProfile(userID: String, previousState: State)
|
||||||
|
case inviteUsersScreen(previousState: State)
|
||||||
|
case mediaUploadPicker(source: MediaPickerScreenSource)
|
||||||
|
case mediaUploadPreview(fileURL: URL)
|
||||||
|
case emojiPicker(itemID: TimelineItemIdentifier, selectedEmojis: Set<String>)
|
||||||
|
case mapNavigator
|
||||||
|
case messageForwarding(forwardingItem: MessageForwardingItem)
|
||||||
|
case reportContent(itemID: TimelineItemIdentifier, senderID: String)
|
||||||
|
case pollForm
|
||||||
|
case pollsHistory
|
||||||
|
case pollsHistoryForm
|
||||||
|
case rolesAndPermissions
|
||||||
|
case pinnedEventsTimeline(previousState: State)
|
||||||
|
case resolveSendFailure
|
||||||
|
case knockRequestsList(previousState: State)
|
||||||
|
case mediaEventsTimeline(previousState: State)
|
||||||
|
case securityAndPrivacy(previousState: State)
|
||||||
|
case reportRoom(previousState: State)
|
||||||
|
case declineAndBlockScreen
|
||||||
|
|
||||||
|
/// A child flow is in progress.
|
||||||
|
case presentingChild(childRoomID: String, previousState: State)
|
||||||
|
/// The flow is complete and is handing control of the stack back to its parent.
|
||||||
|
case complete
|
||||||
|
}
|
||||||
|
|
||||||
|
struct EventUserInfo {
|
||||||
|
let animated: Bool
|
||||||
|
}
|
||||||
|
|
||||||
|
enum Event: EventType {
|
||||||
|
case presentJoinRoomScreen(via: [String])
|
||||||
|
case dismissJoinRoomScreen
|
||||||
|
|
||||||
|
case presentRoom(presentationAction: PresentationAction?)
|
||||||
|
case dismissFlow
|
||||||
|
|
||||||
|
case presentThread(itemID: TimelineItemIdentifier)
|
||||||
|
case dismissThread
|
||||||
|
|
||||||
|
case presentReportContent(itemID: TimelineItemIdentifier, senderID: String)
|
||||||
|
case dismissReportContent
|
||||||
|
|
||||||
|
case presentRoomDetails
|
||||||
|
case dismissRoomDetails
|
||||||
|
|
||||||
|
case presentRoomDetailsEditScreen
|
||||||
|
case dismissRoomDetailsEditScreen
|
||||||
|
|
||||||
|
case presentNotificationSettingsScreen
|
||||||
|
case dismissNotificationSettingsScreen
|
||||||
|
|
||||||
|
case presentGlobalNotificationSettingsScreen
|
||||||
|
case dismissGlobalNotificationSettingsScreen
|
||||||
|
|
||||||
|
case presentRoomMembersList
|
||||||
|
case dismissRoomMembersList
|
||||||
|
|
||||||
|
case presentRoomMemberDetails(userID: String)
|
||||||
|
case dismissRoomMemberDetails
|
||||||
|
|
||||||
|
case presentUserProfile(userID: String)
|
||||||
|
case dismissUserProfile
|
||||||
|
|
||||||
|
case presentInviteUsersScreen
|
||||||
|
case dismissInviteUsersScreen
|
||||||
|
|
||||||
|
case presentMediaUploadPicker(source: MediaPickerScreenSource)
|
||||||
|
case dismissMediaUploadPicker
|
||||||
|
|
||||||
|
case presentMediaUploadPreview(fileURL: URL)
|
||||||
|
case dismissMediaUploadPreview
|
||||||
|
|
||||||
|
case presentEmojiPicker(itemID: TimelineItemIdentifier, selectedEmojis: Set<String>)
|
||||||
|
case dismissEmojiPicker
|
||||||
|
|
||||||
|
case presentMapNavigator(interactionMode: StaticLocationInteractionMode)
|
||||||
|
case dismissMapNavigator
|
||||||
|
|
||||||
|
case presentMessageForwarding(forwardingItem: MessageForwardingItem)
|
||||||
|
case dismissMessageForwarding
|
||||||
|
|
||||||
|
case presentPollForm(mode: PollFormMode)
|
||||||
|
case dismissPollForm
|
||||||
|
|
||||||
|
case presentPollsHistory
|
||||||
|
case dismissPollsHistory
|
||||||
|
|
||||||
|
case presentRolesAndPermissionsScreen
|
||||||
|
case dismissRolesAndPermissionsScreen
|
||||||
|
|
||||||
|
case presentPinnedEventsTimeline
|
||||||
|
case dismissPinnedEventsTimeline
|
||||||
|
|
||||||
|
case presentResolveSendFailure(failure: TimelineItemSendFailure.VerifiedUser, sendHandle: SendHandleProxy)
|
||||||
|
case dismissResolveSendFailure
|
||||||
|
|
||||||
|
case startChildFlow(roomID: String, via: [String], entryPoint: RoomFlowCoordinatorEntryPoint)
|
||||||
|
case dismissChildFlow
|
||||||
|
|
||||||
|
case presentKnockRequestsListScreen
|
||||||
|
case dismissKnockRequestsListScreen
|
||||||
|
|
||||||
|
case presentMediaEventsTimeline
|
||||||
|
case dismissMediaEventsTimeline
|
||||||
|
|
||||||
|
case presentSecurityAndPrivacyScreen
|
||||||
|
case dismissSecurityAndPrivacyScreen
|
||||||
|
|
||||||
|
case presentReportRoomScreen
|
||||||
|
case dismissReportRoomScreen
|
||||||
|
|
||||||
|
case presentDeclineAndBlockScreen(userID: String)
|
||||||
|
case dismissDeclineAndBlockScreen
|
||||||
|
}
|
||||||
|
|
||||||
|
// swiftlint:disable:next function_body_length
|
||||||
|
func addRouteMapping(stateMachine: StateMachine<State, Event>) {
|
||||||
|
stateMachine.addRouteMapping { event, fromState, _ in
|
||||||
|
switch (fromState, event) {
|
||||||
|
case (_, .presentJoinRoomScreen):
|
||||||
|
return .joinRoomScreen
|
||||||
|
case (_, .dismissJoinRoomScreen):
|
||||||
|
return .complete
|
||||||
|
|
||||||
|
case (_, .presentRoom):
|
||||||
|
return .room
|
||||||
|
case (_, .dismissFlow):
|
||||||
|
return .complete
|
||||||
|
|
||||||
|
case (_, .presentThread(let itemID)):
|
||||||
|
return .thread(itemID: itemID)
|
||||||
|
case (_, .dismissThread):
|
||||||
|
return .room
|
||||||
|
|
||||||
|
case (.initial, .presentRoomDetails):
|
||||||
|
return .roomDetails(isRoot: true)
|
||||||
|
case (.room, .presentRoomDetails):
|
||||||
|
return .roomDetails(isRoot: false)
|
||||||
|
case (.roomDetails, .dismissRoomDetails):
|
||||||
|
return .room
|
||||||
|
|
||||||
|
case (.roomDetails, .presentRoomDetailsEditScreen):
|
||||||
|
return .roomDetailsEditScreen
|
||||||
|
case (.roomDetailsEditScreen, .dismissRoomDetailsEditScreen):
|
||||||
|
return .roomDetails(isRoot: false)
|
||||||
|
|
||||||
|
case (.roomDetails, .presentNotificationSettingsScreen):
|
||||||
|
return .notificationSettings
|
||||||
|
case (.notificationSettings, .dismissNotificationSettingsScreen):
|
||||||
|
return .roomDetails(isRoot: false)
|
||||||
|
|
||||||
|
case (.notificationSettings, .presentGlobalNotificationSettingsScreen):
|
||||||
|
return .globalNotificationSettings
|
||||||
|
case (.globalNotificationSettings, .dismissGlobalNotificationSettingsScreen):
|
||||||
|
return .notificationSettings
|
||||||
|
|
||||||
|
case (.roomDetails, .presentRoomMembersList):
|
||||||
|
return .roomMembersList
|
||||||
|
case (.roomMembersList, .dismissRoomMembersList):
|
||||||
|
return .roomDetails(isRoot: false)
|
||||||
|
|
||||||
|
case (_, .presentRoomMemberDetails(userID: let userID)):
|
||||||
|
return .roomMemberDetails(userID: userID, previousState: fromState)
|
||||||
|
case (.roomMemberDetails(_, let previousState), .dismissRoomMemberDetails):
|
||||||
|
return previousState
|
||||||
|
|
||||||
|
case (.roomMemberDetails(_, let previousState), .presentUserProfile(let userID)):
|
||||||
|
return .userProfile(userID: userID, previousState: previousState)
|
||||||
|
case (.userProfile(_, let previousState), .dismissUserProfile):
|
||||||
|
return previousState
|
||||||
|
|
||||||
|
case (_, .presentInviteUsersScreen):
|
||||||
|
return .inviteUsersScreen(previousState: fromState)
|
||||||
|
case (.inviteUsersScreen(let previousState), .dismissInviteUsersScreen):
|
||||||
|
return previousState
|
||||||
|
|
||||||
|
case (.room, .presentReportContent(let itemID, let senderID)):
|
||||||
|
return .reportContent(itemID: itemID, senderID: senderID)
|
||||||
|
case (.reportContent, .dismissReportContent):
|
||||||
|
return .room
|
||||||
|
|
||||||
|
case (.room, .presentMediaUploadPicker(let source)):
|
||||||
|
return .mediaUploadPicker(source: source)
|
||||||
|
case (.mediaUploadPicker, .dismissMediaUploadPicker):
|
||||||
|
return .room
|
||||||
|
|
||||||
|
case (.mediaUploadPicker, .presentMediaUploadPreview(let fileURL)):
|
||||||
|
return .mediaUploadPreview(fileURL: fileURL)
|
||||||
|
case (.room, .presentMediaUploadPreview(let fileURL)):
|
||||||
|
return .mediaUploadPreview(fileURL: fileURL)
|
||||||
|
case (.mediaUploadPreview, .dismissMediaUploadPreview):
|
||||||
|
return .room
|
||||||
|
|
||||||
|
case (.room, .presentEmojiPicker(let itemID, let selectedEmoji)):
|
||||||
|
return .emojiPicker(itemID: itemID, selectedEmojis: selectedEmoji)
|
||||||
|
case (.emojiPicker, .dismissEmojiPicker):
|
||||||
|
return .room
|
||||||
|
|
||||||
|
case (.room, .presentMessageForwarding(let forwardingItem)):
|
||||||
|
return .messageForwarding(forwardingItem: forwardingItem)
|
||||||
|
case (.messageForwarding, .dismissMessageForwarding):
|
||||||
|
return .room
|
||||||
|
|
||||||
|
case (.room, .presentMapNavigator):
|
||||||
|
return .mapNavigator
|
||||||
|
case (.mapNavigator, .dismissMapNavigator):
|
||||||
|
return .room
|
||||||
|
|
||||||
|
case (.room, .presentPollForm):
|
||||||
|
return .pollForm
|
||||||
|
case (.pollForm, .dismissPollForm):
|
||||||
|
return .room
|
||||||
|
|
||||||
|
case (.room, .presentPinnedEventsTimeline):
|
||||||
|
return .pinnedEventsTimeline(previousState: fromState)
|
||||||
|
case (.roomDetails, .presentPinnedEventsTimeline):
|
||||||
|
return .pinnedEventsTimeline(previousState: fromState)
|
||||||
|
case (.pinnedEventsTimeline(let previousState), .dismissPinnedEventsTimeline):
|
||||||
|
return previousState
|
||||||
|
|
||||||
|
case (.roomDetails, .presentPollsHistory):
|
||||||
|
return .pollsHistory
|
||||||
|
case (.pollsHistory, .dismissPollsHistory):
|
||||||
|
return .roomDetails(isRoot: false)
|
||||||
|
|
||||||
|
case (.pollsHistory, .presentPollForm):
|
||||||
|
return .pollsHistoryForm
|
||||||
|
case (.pollsHistoryForm, .dismissPollForm):
|
||||||
|
return .pollsHistory
|
||||||
|
|
||||||
|
case (.roomDetails, .presentRolesAndPermissionsScreen):
|
||||||
|
return .rolesAndPermissions
|
||||||
|
case (.rolesAndPermissions, .dismissRolesAndPermissionsScreen):
|
||||||
|
return .roomDetails(isRoot: false)
|
||||||
|
|
||||||
|
case (.room, .presentResolveSendFailure):
|
||||||
|
return .resolveSendFailure
|
||||||
|
case (.resolveSendFailure, .dismissResolveSendFailure):
|
||||||
|
return .room
|
||||||
|
|
||||||
|
case (_, .startChildFlow(let roomID, _, _)):
|
||||||
|
return .presentingChild(childRoomID: roomID, previousState: fromState)
|
||||||
|
case (.presentingChild(_, let previousState), .dismissChildFlow):
|
||||||
|
return previousState
|
||||||
|
|
||||||
|
case (_, .presentKnockRequestsListScreen):
|
||||||
|
return .knockRequestsList(previousState: fromState)
|
||||||
|
case (.knockRequestsList(let previousState), .dismissKnockRequestsListScreen):
|
||||||
|
return previousState
|
||||||
|
|
||||||
|
case (.roomDetails, .presentMediaEventsTimeline):
|
||||||
|
return .mediaEventsTimeline(previousState: fromState)
|
||||||
|
case (.mediaEventsTimeline(let previousState), .dismissMediaEventsTimeline):
|
||||||
|
return previousState
|
||||||
|
|
||||||
|
case (.roomDetails, .presentSecurityAndPrivacyScreen):
|
||||||
|
return .securityAndPrivacy(previousState: fromState)
|
||||||
|
case (.securityAndPrivacy(let previousState), .dismissSecurityAndPrivacyScreen):
|
||||||
|
return previousState
|
||||||
|
|
||||||
|
case (.roomDetails, .presentReportRoomScreen):
|
||||||
|
return .reportRoom(previousState: fromState)
|
||||||
|
case (.reportRoom(let previousState), .dismissReportRoomScreen):
|
||||||
|
return previousState
|
||||||
|
|
||||||
|
case (.joinRoomScreen, .presentDeclineAndBlockScreen):
|
||||||
|
return .declineAndBlockScreen
|
||||||
|
case (.declineAndBlockScreen, .dismissDeclineAndBlockScreen):
|
||||||
|
return .joinRoomScreen
|
||||||
|
|
||||||
|
default:
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user