diff --git a/Btchap/SupportingFiles/Btchap-App-Common.xcconfig b/Btchap/SupportingFiles/Btchap-App-Common.xcconfig index 36a5963707..0c9357856d 100644 --- a/Btchap/SupportingFiles/Btchap-App-Common.xcconfig +++ b/Btchap/SupportingFiles/Btchap-App-Common.xcconfig @@ -24,6 +24,7 @@ BUNDLE_DISPLAY_NAME = Btchap BASE_BUNDLE_IDENTIFIER = fr.gouv.btchap APPLICATION_GROUP_IDENTIFIER = group.$(BASE_BUNDLE_IDENTIFIER) PRODUCT_BUNDLE_IDENTIFIER = $(BASE_BUNDLE_IDENTIFIER) +APPLICATION_SCHEME = tchap INFOPLIST_FILE = Btchap/SupportingFiles/Info.plist ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon diff --git a/Btchap/SupportingFiles/Info.plist b/Btchap/SupportingFiles/Info.plist index 5e06e305b9..262b052c3d 100644 --- a/Btchap/SupportingFiles/Info.plist +++ b/Btchap/SupportingFiles/Info.plist @@ -35,6 +35,19 @@ $(MARKETING_VERSION) CFBundleSignature ???? + CFBundleURLTypes + + + CFBundleTypeRole + Editor + CFBundleURLName + $(BASE_BUNDLE_IDENTIFIER) + CFBundleURLSchemes + + $(APPLICATION_SCHEME) + + + CFBundleVersion $(CURRENT_PROJECT_VERSION) ITSAppUsesNonExemptEncryption diff --git a/DevTchap/SupportingFiles/DevTchap-App-Common.xcconfig b/DevTchap/SupportingFiles/DevTchap-App-Common.xcconfig index 5fe20ec985..ae7b765ca3 100644 --- a/DevTchap/SupportingFiles/DevTchap-App-Common.xcconfig +++ b/DevTchap/SupportingFiles/DevTchap-App-Common.xcconfig @@ -24,6 +24,7 @@ BUNDLE_DISPLAY_NAME = DevTchap BASE_BUNDLE_IDENTIFIER = fr.gouv.tchap.dev APPLICATION_GROUP_IDENTIFIER = group.$(BASE_BUNDLE_IDENTIFIER) PRODUCT_BUNDLE_IDENTIFIER = $(BASE_BUNDLE_IDENTIFIER) +APPLICATION_SCHEME = tchap INFOPLIST_FILE = DevTchap/SupportingFiles/Info.plist ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon diff --git a/DevTchap/SupportingFiles/Info.plist b/DevTchap/SupportingFiles/Info.plist index 4303301c18..533722fc3c 100644 --- a/DevTchap/SupportingFiles/Info.plist +++ b/DevTchap/SupportingFiles/Info.plist @@ -35,6 +35,19 @@ $(MARKETING_VERSION) CFBundleSignature ???? + CFBundleURLTypes + + + CFBundleTypeRole + Editor + CFBundleURLName + $(BASE_BUNDLE_IDENTIFIER) + CFBundleURLSchemes + + $(APPLICATION_SCHEME) + + + CFBundleVersion $(CURRENT_PROJECT_VERSION) ITSAppUsesNonExemptEncryption diff --git a/Riot/Modules/Authentication/AuthenticationCoordinator.swift b/Riot/Modules/Authentication/AuthenticationCoordinator.swift index 295a591f73..b47c20b3bc 100644 --- a/Riot/Modules/Authentication/AuthenticationCoordinator.swift +++ b/Riot/Modules/Authentication/AuthenticationCoordinator.swift @@ -151,7 +151,9 @@ final class AuthenticationCoordinator: NSObject, AuthenticationCoordinatorProtoc if authenticationService.state.homeserver.needsRegistrationFallback { showFallback(for: flow) } else { - showRegistrationScreen() + // Tchap: force email registration mode +// showRegistrationScreen() + TchapShowVerifyEmailScreen() } case .login: if authenticationService.state.homeserver.needsLoginFallback { @@ -379,6 +381,38 @@ final class AuthenticationCoordinator: NSObject, AuthenticationCoordinatorProtoc } } + // Tchap: start Registration with VerifyEmail screen + /// Shows the login screen. + @MainActor private func TchapShowVerifyEmailScreen() { + MXLog.debug("[AuthenticationCoordinator] TchapShowVerifyEmailScreen") + + guard let registrationWizard = authenticationService.registrationWizard else { + MXLog.failure("[AuthenticationCoordinator] showStage: Missing the RegistrationWizard needed to complete the stage.") + displayError(message: VectorL10n.errorCommonMessage) + return + } + let homeserver = authenticationService.state.homeserver + + let parameters = AuthenticationVerifyEmailCoordinatorParameters(registrationWizard: registrationWizard, + homeserver: authenticationService.state.homeserver) + let coordinator = AuthenticationVerifyEmailCoordinator(parameters: parameters) + coordinator.callback = { [weak self] result in + self?.registrationStageDidComplete(with: result) + } + + coordinator.start() + add(childCoordinator: coordinator) + + if navigationRouter.modules.isEmpty { + navigationRouter.setRootModule(coordinator, popCompletion: nil) + } else { + navigationRouter.push(coordinator, animated: true) { [weak self] in + self?.remove(childCoordinator: coordinator) + } + } + } + + /// Displays the next view in the flow based on the result from the registration screen. @MainActor private func registrationCoordinator(_ coordinator: AuthenticationRegistrationCoordinator, didCallbackWith result: AuthenticationRegistrationCoordinatorResult) { diff --git a/Riot/Modules/Authentication/Legacy/AuthenticationViewController.m b/Riot/Modules/Authentication/Legacy/AuthenticationViewController.m index c0605d8131..687a534e27 100644 --- a/Riot/Modules/Authentication/Legacy/AuthenticationViewController.m +++ b/Riot/Modules/Authentication/Legacy/AuthenticationViewController.m @@ -138,10 +138,10 @@ - (void)viewDidLoad } else { - self.defaultHomeServerUrl = RiotSettings.shared.homeserverUrlString; +// self.defaultHomeServerUrl = RiotSettings.shared.homeserverUrlString; } - self.defaultIdentityServerUrl = RiotSettings.shared.identityServerUrlString; +// self.defaultIdentityServerUrl = RiotSettings.shared.identityServerUrlString; self.welcomeImageView.image = AssetSharedImages.horizontalLogo.image; diff --git a/Riot/Modules/Home/AllChats/AllChatsViewController.swift b/Riot/Modules/Home/AllChats/AllChatsViewController.swift index 0efb816e23..f7e4f51066 100644 --- a/Riot/Modules/Home/AllChats/AllChatsViewController.swift +++ b/Riot/Modules/Home/AllChats/AllChatsViewController.swift @@ -107,8 +107,6 @@ class AllChatsViewController: HomeViewController { // Reference to the current onboarding flow. It is always nil unless the flow is being presented. private(set) var onboardingCoordinatorBridgePresenter: OnboardingCoordinatorBridgePresenter? - // Tchap: Use welcomeCoordinator instead of onboardingCoordinator - private(set) var welcomeCoordinatorBridgePresenter: WelcomeCoordinatorBridgePresenter? // Tell whether the onboarding screen is preparing. private(set) var isOnboardingInProgress: Bool = false @@ -921,8 +919,7 @@ extension AllChatsViewController: SplitViewMasterViewControllerProtocol { // This method can be called after the user chooses to clear their data as the MXSession // is opened to call logout from. So we only set the credentials when authentication isn't // in progress to prevent a second soft logout screen being shown. - // Tchap: Use WelcomeCoordinatorBridgePresenter instead of OnboardingCoordinatorBridgePresenter - guard self.welcomeCoordinatorBridgePresenter == nil && !self.isOnboardingCoordinatorPreparing else { + guard self.self.onboardingCoordinatorBridgePresenter == nil && !self.isOnboardingCoordinatorPreparing else { return } @@ -1092,8 +1089,7 @@ extension AllChatsViewController: SplitViewMasterViewControllerProtocol { private func showOnboardingFlowAndResetSessionFlags(_ resetSessionFlags: Bool) { // Check whether an authentication screen is not already shown or preparing - // Tchap: Use WelcomeCoordinatorBridgePresenter instead of OnboardingCoordinatorBridgePresenter - guard self.welcomeCoordinatorBridgePresenter == nil && !self.isOnboardingCoordinatorPreparing else { + guard self.self.onboardingCoordinatorBridgePresenter == nil && !self.isOnboardingCoordinatorPreparing else { return } @@ -1117,36 +1113,36 @@ extension AllChatsViewController: SplitViewMasterViewControllerProtocol { MXLog.debug("[AllChatsViewController] presentOnboardingFlow") // Tchap: Use WelcomeCoordinatorBridgePresenter instead of OnboardingCoordinatorBridgePresenter - let welcomeCoordinatorBridgePresenter = WelcomeCoordinatorBridgePresenter() - welcomeCoordinatorBridgePresenter.completion = { [weak self] in - guard let self = self else { return } - - self.welcomeCoordinatorBridgePresenter?.dismiss(animated: true, completion: { - self.welcomeCoordinatorBridgePresenter = nil - }) - - self.isOnboardingInProgress = false // Must be set before calling didCompleteAuthentication - self.allChatsDelegate?.allChatsViewControllerDidCompleteAuthentication(self) - } - - welcomeCoordinatorBridgePresenter.present(from: self, animated: true) - self.welcomeCoordinatorBridgePresenter = welcomeCoordinatorBridgePresenter - - -// let onboardingCoordinatorBridgePresenter = OnboardingCoordinatorBridgePresenter() -// onboardingCoordinatorBridgePresenter.completion = { [weak self] in +// let welcomeCoordinatorBridgePresenter = WelcomeCoordinatorBridgePresenter() +// welcomeCoordinatorBridgePresenter.completion = { [weak self] in // guard let self = self else { return } -// -// self.onboardingCoordinatorBridgePresenter?.dismiss(animated: true, completion: { -// self.onboardingCoordinatorBridgePresenter = nil +// +// self.welcomeCoordinatorBridgePresenter?.dismiss(animated: true, completion: { +// self.welcomeCoordinatorBridgePresenter = nil // }) // // self.isOnboardingInProgress = false // Must be set before calling didCompleteAuthentication // self.allChatsDelegate?.allChatsViewControllerDidCompleteAuthentication(self) // } // -// onboardingCoordinatorBridgePresenter.present(from: self, animated: true) -// self.onboardingCoordinatorBridgePresenter = onboardingCoordinatorBridgePresenter +// welcomeCoordinatorBridgePresenter.present(from: self, animated: true) +// self.welcomeCoordinatorBridgePresenter = welcomeCoordinatorBridgePresenter + + + let onboardingCoordinatorBridgePresenter = OnboardingCoordinatorBridgePresenter() + onboardingCoordinatorBridgePresenter.completion = { [weak self] in + guard let self = self else { return } + + self.onboardingCoordinatorBridgePresenter?.dismiss(animated: true, completion: { + self.onboardingCoordinatorBridgePresenter = nil + }) + + self.isOnboardingInProgress = false // Must be set before calling didCompleteAuthentication + self.allChatsDelegate?.allChatsViewControllerDidCompleteAuthentication(self) + } + + onboardingCoordinatorBridgePresenter.present(from: self, animated: true) + self.onboardingCoordinatorBridgePresenter = onboardingCoordinatorBridgePresenter self.isOnboardingCoordinatorPreparing = false } diff --git a/Riot/Modules/Onboarding/OnboardingCoordinator.swift b/Riot/Modules/Onboarding/OnboardingCoordinator.swift index bce47443bb..3fb1d711a6 100644 --- a/Riot/Modules/Onboarding/OnboardingCoordinator.swift +++ b/Riot/Modules/Onboarding/OnboardingCoordinator.swift @@ -165,7 +165,7 @@ final class OnboardingCoordinator: NSObject, OnboardingCoordinatorProtocol { case .register: // Tchap: Bypass usecase selection screen // showUseCaseSelectionScreen() - MXLog.failure("[OnboardingCoordinator] splashScreenCoordinator register case should not happen !") + beginAuthentication(with: .registration, onStart: coordinator.stop) case .login: if BuildSettings.onboardingEnableNewAuthenticationFlow { diff --git a/Riot/Modules/SplitView/SplitViewCoordinator.swift b/Riot/Modules/SplitView/SplitViewCoordinator.swift index 61271f31bc..22172510cc 100644 --- a/Riot/Modules/SplitView/SplitViewCoordinator.swift +++ b/Riot/Modules/SplitView/SplitViewCoordinator.swift @@ -93,7 +93,9 @@ final class SplitViewCoordinator: NSObject, SplitViewCoordinatorType { self.splitViewController.delegate = self // Create primary controller - let masterCoordinator: SplitViewMasterCoordinatorProtocol = BuildSettings.newAppLayoutEnabled ? self.createAllChatsCoordinator() : self.createTabBarCoordinator() + // Tchap: force using AllChatsCoordinator because newLayout is always TRUE +// let masterCoordinator: SplitViewMasterCoordinatorProtocol = BuildSettings.newAppLayoutEnabled ? self.createAllChatsCoordinator() : self.createTabBarCoordinator() + let masterCoordinator: SplitViewMasterCoordinatorProtocol = self.createAllChatsCoordinator() masterCoordinator.splitViewMasterPresentableDelegate = self masterCoordinator.start(with: spaceId) @@ -182,14 +184,15 @@ final class SplitViewCoordinator: NSObject, SplitViewCoordinatorType { return coordinator } - private func createTabBarCoordinator() -> TabBarCoordinator { - - let coordinatorParameters = TabBarCoordinatorParameters(userSessionsService: self.parameters.userSessionsService, appNavigator: self.parameters.appNavigator) - - let tabBarCoordinator = TabBarCoordinator(parameters: coordinatorParameters) - tabBarCoordinator.delegate = self - return tabBarCoordinator - } + // Tchap: don't use TabBarCoordinator anymore now that newLayout is always TRUE +// private func createTabBarCoordinator() -> TabBarCoordinator { +// +// let coordinatorParameters = TabBarCoordinatorParameters(userSessionsService: self.parameters.userSessionsService, appNavigator: self.parameters.appNavigator) +// +// let tabBarCoordinator = TabBarCoordinator(parameters: coordinatorParameters) +// tabBarCoordinator.delegate = self +// return tabBarCoordinator +// } private func resetDetailNavigationControllerWithPlaceholder(animated: Bool) { guard let detailNavigationRouter = self.detailNavigationRouter else { diff --git a/Riot/Modules/TabBar/TabBarCoordinator.swift b/Riot/Modules/TabBar/TabBarCoordinator.swift index b3ce06ba84..bbee1ab268 100644 --- a/Riot/Modules/TabBar/TabBarCoordinator.swift +++ b/Riot/Modules/TabBar/TabBarCoordinator.swift @@ -639,13 +639,14 @@ final class TabBarCoordinator: NSObject, SplitViewMasterCoordinatorProtocol { } private func showWelcome(animated: Bool = false) { - let welcomeCoordinator = WelcomeCoordinator() - welcomeCoordinator.delegate = self - welcomeCoordinator.start() - self.add(childCoordinator: welcomeCoordinator) - DispatchQueue.main.asyncAfter(deadline: .now() + 0.5 , execute: { [weak self] in - self?.navigationRouter.present(welcomeCoordinator, animated: animated) - }) + // Tchap: remove calls to Welcome classes +// let welcomeCoordinator = WelcomeCoordinator() +// welcomeCoordinator.delegate = self +// welcomeCoordinator.start() +// self.add(childCoordinator: welcomeCoordinator) +// DispatchQueue.main.asyncAfter(deadline: .now() + 0.5 , execute: { [weak self] in +// self?.navigationRouter.present(welcomeCoordinator, animated: animated) +// }) } private func userDidLogin() -> Bool { @@ -1163,14 +1164,15 @@ extension TabBarCoordinator: SecureBackupSetupCoordinatorBridgePresenterDelegate } // MARK: - WelcomeCoordinatorDelegate -extension TabBarCoordinator: WelcomeCoordinatorDelegate { - func welcomeCoordinatorUserDidAuthenticate(_ coordinator: WelcomeCoordinatorType) { - // Check that the new account actually exists before removing the current coordinator - if userDidLogin() { - self.remove(childCoordinator: coordinator) - } - } -} +// Tchap: remove calls to Tchap Welcome classes +//extension TabBarCoordinator: WelcomeCoordinatorDelegate { +// func welcomeCoordinatorUserDidAuthenticate(_ coordinator: WelcomeCoordinatorType) { +// // Check that the new account actually exists before removing the current coordinator +// if userDidLogin() { +// self.remove(childCoordinator: coordinator) +// } +// } +//} // MARK: - RoomsViewControllerDelegate extension TabBarCoordinator: RoomsViewControllerDelegate { diff --git a/RiotSwiftUI/Modules/Onboarding/SplashScreen/View/OnboardingSplashScreen.swift b/RiotSwiftUI/Modules/Onboarding/SplashScreen/View/OnboardingSplashScreen.swift index b342398826..7bb7b80987 100644 --- a/RiotSwiftUI/Modules/Onboarding/SplashScreen/View/OnboardingSplashScreen.swift +++ b/RiotSwiftUI/Modules/Onboarding/SplashScreen/View/OnboardingSplashScreen.swift @@ -25,13 +25,14 @@ struct OnboardingSplashScreen: View { @Environment(\.theme) private var theme @Environment(\.layoutDirection) private var layoutDirection - private var isLeftToRight: Bool { layoutDirection == .leftToRight } - private var pageCount: Int { viewModel.viewState.content.count } - - /// A timer to automatically animate the pages. - @State private var pageTimer: Timer? - /// The amount of offset to apply when a drag gesture is in progress. - @State private var dragOffset: CGFloat = .zero + // Tchap: remove carousel +// private var isLeftToRight: Bool { layoutDirection == .leftToRight } +// private var pageCount: Int { viewModel.viewState.content.count } +// +// /// A timer to automatically animate the pages. +// @State private var pageTimer: Timer? +// /// The amount of offset to apply when a drag gesture is in progress. +// @State private var dragOffset: CGFloat = .zero // MARK: Public @@ -43,28 +44,41 @@ struct OnboardingSplashScreen: View { Spacer() .frame(height: OnboardingMetrics.spacerHeight(in: geometry)) - // The main content of the carousel - HStack(alignment: .top, spacing: 0) { - // Add a hidden page at the start of the carousel duplicating the content of the last page - OnboardingSplashScreenPage(content: viewModel.viewState.content[pageCount - 1]) - .frame(width: geometry.size.width) - - ForEach(0..