diff --git a/ElementX/Sources/FlowCoordinators/UserSessionFlowCoordinator.swift b/ElementX/Sources/FlowCoordinators/UserSessionFlowCoordinator.swift index 2bde7f7b58..6d5c5001f7 100644 --- a/ElementX/Sources/FlowCoordinators/UserSessionFlowCoordinator.swift +++ b/ElementX/Sources/FlowCoordinators/UserSessionFlowCoordinator.swift @@ -278,8 +278,12 @@ class UserSessionFlowCoordinator: FlowCoordinatorProtocol { break case (.roomList, .showRoomDirectorySearchScreen, .roomDirectorySearchScreen): presentRoomDirectorySearch() - case (.roomDirectorySearchScreen, .dismissedRoomDirectorySearchScreen, .roomList): - dismissRoomDirectorySearch() + // Tchap: handle dismissing mode for dismissedRoomDirectorySearchScreen +// case (.roomDirectorySearchScreen, .dismissedRoomDirectorySearchScreen, .roomList): +// dismissRoomDirectorySearch() + case (.roomDirectorySearchScreen, .dismissedRoomDirectorySearchScreen(let isPresentedInFullScreenMode), .roomList), + (.roomList, .dismissedRoomDirectorySearchScreen(let isPresentedInFullScreenMode), .roomList): + dismissRoomDirectorySearch(isPresentedInFullScreenMode: isPresentedInFullScreenMode) case (_, .showUserProfileScreen(let userID), .userProfileScreen): presentUserProfileScreen(userID: userID, animated: animated) case (.userProfileScreen, .dismissedUserProfileScreen, .roomList): @@ -608,6 +612,8 @@ class UserSessionFlowCoordinator: FlowCoordinatorProtocol { case .openRoom(let roomID): self.navigationSplitCoordinator.setSheetCoordinator(nil) self.stateMachine.processEvent(.selectRoom(roomID: roomID, via: [], entryPoint: .room)) + case .joinForum: // Tchap: handle `joinForum` action + presentRoomDirectorySearch(inFullScreenMode: false) } } .store(in: &cancellables) @@ -820,7 +826,12 @@ class UserSessionFlowCoordinator: FlowCoordinatorProtocol { // MARK: Room Directory Search - private func presentRoomDirectorySearch() { + // Tchap: add a flag to present the view fullscreen or in sheet. + // Because in Tchap, it is called from am already fullScreenCover view. + // And the system can't stack 2 fullScreenCover views. + // Sp, present it in a sheet for Tchap "Start Chat" view. +// private func presentRoomDirectorySearch() { + private func presentRoomDirectorySearch(inFullScreenMode: Bool = true) { let coordinator = RoomDirectorySearchScreenCoordinator(parameters: .init(clientProxy: userSession.clientProxy, mediaProvider: userSession.mediaProvider, userIndicatorController: ServiceLocator.shared.userIndicatorController)) @@ -830,24 +841,45 @@ class UserSessionFlowCoordinator: FlowCoordinatorProtocol { switch action { case .selectAlias(let alias): - stateMachine.processEvent(.dismissedRoomDirectorySearchScreen) + // Tchap: handle presentation mode to dismiss the view in the correct way. +// stateMachine.processEvent(.dismissedRoomDirectorySearchScreen) + stateMachine.processEvent(.dismissedRoomDirectorySearchScreen(isPresentedInFullScreenMode: inFullScreenMode)) handleAppRoute(.roomAlias(alias), animated: true) case .selectRoomID(let roomID): - stateMachine.processEvent(.dismissedRoomDirectorySearchScreen) + // Tchap: handle presentation mode to dismiss the view in the correct way. +// stateMachine.processEvent(.dismissedRoomDirectorySearchScreen) + stateMachine.processEvent(.dismissedRoomDirectorySearchScreen(isPresentedInFullScreenMode: inFullScreenMode)) handleAppRoute(.room(roomID: roomID, via: []), animated: true) case .dismiss: - stateMachine.processEvent(.dismissedRoomDirectorySearchScreen) + // Tchap: handle presentation mode to dismiss the view in the correct way. +// stateMachine.processEvent(.dismissedRoomDirectorySearchScreen) + stateMachine.processEvent(.dismissedRoomDirectorySearchScreen(isPresentedInFullScreenMode: inFullScreenMode)) } } .store(in: &cancellables) - navigationSplitCoordinator.setFullScreenCoverCoordinator(coordinator) + // Tchap: handle presentation mode. +// navigationSplitCoordinator.setFullScreenCoverCoordinator(coordinator) + if inFullScreenMode { + navigationSplitCoordinator.setFullScreenCoverCoordinator(coordinator) + } else { + navigationSplitCoordinator.setSheetCoordinator(coordinator) + } } - private func dismissRoomDirectorySearch() { - navigationSplitCoordinator.setFullScreenCoverCoordinator(nil) + // Tchap: add a flag to dismiss the view in correct presentation mode: fullscreen or in sheet. +// private func dismissRoomDirectorySearch() { +// navigationSplitCoordinator.setFullScreenCoverCoordinator(nil) +// } +// + private func dismissRoomDirectorySearch(isPresentedInFullScreenMode: Bool = true) { + if isPresentedInFullScreenMode { + navigationSplitCoordinator.setFullScreenCoverCoordinator(nil) + } else { + navigationSplitCoordinator.setSheetCoordinator(nil) + } } - + // MARK: User Profile private func presentUserProfileScreen(userID: String, animated: Bool) { diff --git a/ElementX/Sources/FlowCoordinators/UserSessionFlowCoordinatorStateMachine.swift b/ElementX/Sources/FlowCoordinators/UserSessionFlowCoordinatorStateMachine.swift index 1c482c1286..99bb687d4a 100644 --- a/ElementX/Sources/FlowCoordinators/UserSessionFlowCoordinatorStateMachine.swift +++ b/ElementX/Sources/FlowCoordinators/UserSessionFlowCoordinatorStateMachine.swift @@ -110,8 +110,10 @@ class UserSessionFlowCoordinatorStateMachine { /// Request presentation of the room directory search screen. case showRoomDirectorySearchScreen /// The room directory search screen has been dismissed. - case dismissedRoomDirectorySearchScreen - + // Tchap: add a flag to present the view fullscreen or in sheet. +// case dismissedRoomDirectorySearchScreen + case dismissedRoomDirectorySearchScreen(isPresentedInFullScreenMode: Bool) + /// Request presentation of the user profile screen. case showUserProfileScreen(userID: String) /// The user profile screen has been dismissed. @@ -184,9 +186,15 @@ class UserSessionFlowCoordinatorStateMachine { case (.roomList(let selectedRoomID), .showRoomDirectorySearchScreen): return .roomDirectorySearchScreen(selectedRoomID: selectedRoomID) + // Tchap: handle presentation mode for dismissedRoomDirectorySearchScreen. +// case (.roomDirectorySearchScreen(let selectedRoomID), .dismissedRoomDirectorySearchScreen): case (.roomDirectorySearchScreen(let selectedRoomID), .dismissedRoomDirectorySearchScreen): return .roomList(selectedRoomID: selectedRoomID) + // Tchap: handle presentation mode for dismissedRoomDirectorySearchScreen. + case (.roomList(let selectedRoomID), .dismissedRoomDirectorySearchScreen): + return .roomList(selectedRoomID: selectedRoomID) + case (_, .showUserProfileScreen): return .userProfileScreen diff --git a/ElementX/Sources/Screens/StartChatScreen/StartChatScreenCoordinator.swift b/ElementX/Sources/Screens/StartChatScreen/StartChatScreenCoordinator.swift index 2bc682ef4e..bd8102fc35 100644 --- a/ElementX/Sources/Screens/StartChatScreen/StartChatScreenCoordinator.swift +++ b/ElementX/Sources/Screens/StartChatScreen/StartChatScreenCoordinator.swift @@ -20,6 +20,7 @@ struct StartChatScreenCoordinatorParameters { enum StartChatScreenCoordinatorAction { case close case openRoom(withIdentifier: String) + case joinForum // Tchap: add `join Forum` action to `StartChat` screen } final class StartChatScreenCoordinator: CoordinatorProtocol { @@ -62,6 +63,8 @@ final class StartChatScreenCoordinator: CoordinatorProtocol { presentInviteUsersScreen() case .openRoom(let identifier): actionsSubject.send(.openRoom(withIdentifier: identifier)) + case .joinForum: // Tchap: add `join Forum` action to `StartChat` screen + actionsSubject.send(.joinForum) } } .store(in: &cancellables) @@ -104,7 +107,7 @@ final class StartChatScreenCoordinator: CoordinatorProtocol { self?.selectedUsers.send([]) } } - + private func openCreateRoomScreen() { let createParameters = CreateRoomCoordinatorParameters(userSession: parameters.userSession, userIndicatorController: parameters.userIndicatorController, diff --git a/ElementX/Sources/Screens/StartChatScreen/StartChatScreenModels.swift b/ElementX/Sources/Screens/StartChatScreen/StartChatScreenModels.swift index 6113180dc8..ebc5d7171e 100644 --- a/ElementX/Sources/Screens/StartChatScreen/StartChatScreenModels.swift +++ b/ElementX/Sources/Screens/StartChatScreen/StartChatScreenModels.swift @@ -16,6 +16,7 @@ enum StartChatScreenViewModelAction { case close case createRoom case openRoom(withIdentifier: String) + case joinForum // Tchap: add `join Forum` action to `StartChat` screen } struct StartChatScreenViewState: BindableState { @@ -43,4 +44,5 @@ enum StartChatScreenViewAction { case close case createRoom case selectUser(UserProfileProxy) + case joinForum // Tchap: add `join Forum` action to `StartChat` screen } diff --git a/ElementX/Sources/Screens/StartChatScreen/StartChatScreenViewModel.swift b/ElementX/Sources/Screens/StartChatScreen/StartChatScreenViewModel.swift index ef64b2e5d7..e2f88be760 100644 --- a/ElementX/Sources/Screens/StartChatScreen/StartChatScreenViewModel.swift +++ b/ElementX/Sources/Screens/StartChatScreen/StartChatScreenViewModel.swift @@ -68,6 +68,8 @@ class StartChatScreenViewModel: StartChatScreenViewModelType, StartChatScreenVie self.displayError() } } + case .joinForum: // Tchap: handle `joinForum` action + actionsSubject.send(.joinForum) } } diff --git a/ElementX/Sources/Screens/StartChatScreen/View/StartChatScreen.swift b/ElementX/Sources/Screens/StartChatScreen/View/StartChatScreen.swift index 48a06919af..7ab102da30 100644 --- a/ElementX/Sources/Screens/StartChatScreen/View/StartChatScreen.swift +++ b/ElementX/Sources/Screens/StartChatScreen/View/StartChatScreen.swift @@ -39,6 +39,7 @@ struct StartChatScreen: View { @ViewBuilder private var mainContent: some View { createRoomSection + joinForumSection // Tchap: Join a forum inviteFriendsSection usersSection } @@ -74,6 +75,16 @@ struct StartChatScreen: View { } } + // Tchap: Join a forum (add section without chevron) + private var joinForumSection: some View { + Section { + ListRow(label: .default(title: TchapL10n.joinForum, + icon: \.listBulleted), + kind: .button { context.send(viewAction: .joinForum) }) + .accessibilityIdentifier(TchapA11yIdentifiers.startChatScreen.joinForum) + } + } + @ViewBuilder private var usersSection: some View { if !context.viewState.usersSection.users.isEmpty { diff --git a/TchapX/main/Resources/Localizations/en.lproj/TchapLocalizable.strings b/TchapX/main/Resources/Localizations/en.lproj/TchapLocalizable.strings index 60aa89f927..134cadde03 100644 --- a/TchapX/main/Resources/Localizations/en.lproj/TchapLocalizable.strings +++ b/TchapX/main/Resources/Localizations/en.lproj/TchapLocalizable.strings @@ -6,3 +6,4 @@ Copyright © 2024 Tchap. All rights reserved. */ +"join_forum" = "Join a forum"; diff --git a/TchapX/main/Resources/Localizations/fr.lproj/TchapLocalizable.strings b/TchapX/main/Resources/Localizations/fr.lproj/TchapLocalizable.strings index 60aa89f927..d1976f577d 100644 --- a/TchapX/main/Resources/Localizations/fr.lproj/TchapLocalizable.strings +++ b/TchapX/main/Resources/Localizations/fr.lproj/TchapLocalizable.strings @@ -6,3 +6,4 @@ Copyright © 2024 Tchap. All rights reserved. */ +"join_forum" = "Rejoindre un forum"; diff --git a/TchapX/main/Sources/Other/AccessibilityIdentifiers+Tchap.swift b/TchapX/main/Sources/Other/AccessibilityIdentifiers+Tchap.swift new file mode 100644 index 0000000000..7f767c370f --- /dev/null +++ b/TchapX/main/Sources/Other/AccessibilityIdentifiers+Tchap.swift @@ -0,0 +1,17 @@ +// +// AccessibilityIdentifiers+Tchap.swift +// ElementX +// +// Created by Nicolas Buquet on 18/11/2024. +// Copyright © 2024 Tchap. All rights reserved. +// + +import Foundation + +enum TchapA11yIdentifiers { + static let startChatScreen = TchapA11yIdentifiers.StartChatScreen() + + struct StartChatScreen { + let joinForum = "start_chat-join-forum" + } +}