Beam/ElementX/Sources/Application/AppCoordinator.swift

709 lines
28 KiB
Swift
Raw Normal View History

2022-02-14 18:05:21 +02:00
//
// Copyright 2022 New Vector Ltd
2022-02-14 18:05:21 +02:00
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
2022-02-14 18:05:21 +02:00
//
import BackgroundTasks
import Combine
import MatrixRustSDK
import SwiftUI
import Version
2022-02-14 18:05:21 +02:00
class AppCoordinator: AppCoordinatorProtocol, AuthenticationCoordinatorDelegate, NotificationManagerDelegate {
private let stateMachine: AppCoordinatorStateMachine
Fixes #317 - Adopt a split layout for iPad and Mac apps Rename navigation components: SplitScreenCoordinator -> NavigationSplitCoordinator, StackScreenCoordinator -> NavigationStackCoordinator and SingleScreenCoordinator -> NavigationRootCoordinator [0c161039] Tweak navigation logging [826c19cf] Move the navigation dismissal callbacks to the NavigationModule, add SingleScreenCoordinator tests [b8830d9c] Add tests [252ad119] Merge the StackScreenCoordinator and SplitScreenCoordinators into a single file and stop publicly exposing their internal workings. Add more documentation. [37671699] Cleanup navigation logging [51406184] Use the parent SplitScreenCoordinator to present embedded StackScreenCoordinator sheets [b94b04c9] Retract the room "syncing" indicator when dismissing a room [1467b0ac] Correctly move to the no room selected state when popping in compact layouts [10bf2ad8] Allow nilling root coordinators, replace present/dismiss sheet with setSheetCoordinator(?) [33716784] Add single screen coordinator fade transition animation [3cbe65e7] Prevent the timeline table view from being reused between different rooms [9c94c50b] Move files around [c10b6bc5] Adapt the user session state machine to the split layout [7115a319] Fix unit and UI tests [1ece59e8] Fix login flows [6884dc3b] Use modules everywhere the underlying object is a NavigationModule [ab08d44c] Rename navigation components to: SingleScreenCoordinator, SplitScreenCoordinator and StackScreenCoordinator [ada2be57] Add SplitNavigationController * Remove the navigationRootCoordinator from the UserSessionFlowCoordinator
2022-12-12 12:31:27 +02:00
private let navigationRootCoordinator: NavigationRootCoordinator
private let userSessionStore: UserSessionStoreProtocol
/// Common background task to continue long-running tasks in the background.
private var backgroundTask: BackgroundTaskProtocol?
private var isSuspended = false
2022-02-14 18:05:21 +02:00
private var userSession: UserSessionProtocol? {
Log out (#174) * Expose logout method from SDK * Use logout from SDK, refactor logging out states * Add some strings * Introduce `initialDisplayName` on `UIDevice` * Implement soft logout screen * Add `softLogout` test screen identifier * Add new fields into the client proxy and implement new delegate methods * Add new fields into the user session and observe new client callbacks * Implement updated login method * Add remote logout state and event into the state machine * Implement refreshing restore token on `UserSessionStore` * Update app coordinator with new states and display soft logout screen when appropriate * Add reference screenshots for soft logout screen * Disable auto requesting photos access on screenshot detection * Make initial device name optional, generate project file * Add changelog * Use logout from SDK, refactor logging out states * Implement soft logout screen * Implement updated login method * Make initial device name optional, generate project file * Fix renamed event * Fix logout race * Remove redundant strings * Reuse existing strings * Confirm clear all data * Expose logout method from SDK * Use logout from SDK, refactor logging out states * Add some strings * Introduce `initialDisplayName` on `UIDevice` * Implement soft logout screen * Add `softLogout` test screen identifier * Add new fields into the client proxy and implement new delegate methods * Add new fields into the user session and observe new client callbacks * Implement updated login method * Add remote logout state and event into the state machine * Implement refreshing restore token on `UserSessionStore` * Update app coordinator with new states and display soft logout screen when appropriate * Add reference screenshots for soft logout screen * Disable auto requesting photos access on screenshot detection * Make initial device name optional, generate project file * Add changelog * Use logout from SDK, refactor logging out states * Implement soft logout screen * Implement updated login method * Make initial device name optional, generate project file * Fix renamed event * Fix logout race * Remove redundant strings * Reuse existing strings * Confirm clear all data * Comment out new apis for now * Make the PR compile
2022-09-15 12:41:37 +03:00
didSet {
userSessionObserver?.cancel()
if userSession != nil {
2022-11-21 19:37:13 +03:00
configureNotificationManager()
Log out (#174) * Expose logout method from SDK * Use logout from SDK, refactor logging out states * Add some strings * Introduce `initialDisplayName` on `UIDevice` * Implement soft logout screen * Add `softLogout` test screen identifier * Add new fields into the client proxy and implement new delegate methods * Add new fields into the user session and observe new client callbacks * Implement updated login method * Add remote logout state and event into the state machine * Implement refreshing restore token on `UserSessionStore` * Update app coordinator with new states and display soft logout screen when appropriate * Add reference screenshots for soft logout screen * Disable auto requesting photos access on screenshot detection * Make initial device name optional, generate project file * Add changelog * Use logout from SDK, refactor logging out states * Implement soft logout screen * Implement updated login method * Make initial device name optional, generate project file * Fix renamed event * Fix logout race * Remove redundant strings * Reuse existing strings * Confirm clear all data * Expose logout method from SDK * Use logout from SDK, refactor logging out states * Add some strings * Introduce `initialDisplayName` on `UIDevice` * Implement soft logout screen * Add `softLogout` test screen identifier * Add new fields into the client proxy and implement new delegate methods * Add new fields into the user session and observe new client callbacks * Implement updated login method * Add remote logout state and event into the state machine * Implement refreshing restore token on `UserSessionStore` * Update app coordinator with new states and display soft logout screen when appropriate * Add reference screenshots for soft logout screen * Disable auto requesting photos access on screenshot detection * Make initial device name optional, generate project file * Add changelog * Use logout from SDK, refactor logging out states * Implement soft logout screen * Implement updated login method * Make initial device name optional, generate project file * Fix renamed event * Fix logout race * Remove redundant strings * Reuse existing strings * Confirm clear all data * Comment out new apis for now * Make the PR compile
2022-09-15 12:41:37 +03:00
observeUserSessionChanges()
startSync()
Log out (#174) * Expose logout method from SDK * Use logout from SDK, refactor logging out states * Add some strings * Introduce `initialDisplayName` on `UIDevice` * Implement soft logout screen * Add `softLogout` test screen identifier * Add new fields into the client proxy and implement new delegate methods * Add new fields into the user session and observe new client callbacks * Implement updated login method * Add remote logout state and event into the state machine * Implement refreshing restore token on `UserSessionStore` * Update app coordinator with new states and display soft logout screen when appropriate * Add reference screenshots for soft logout screen * Disable auto requesting photos access on screenshot detection * Make initial device name optional, generate project file * Add changelog * Use logout from SDK, refactor logging out states * Implement soft logout screen * Implement updated login method * Make initial device name optional, generate project file * Fix renamed event * Fix logout race * Remove redundant strings * Reuse existing strings * Confirm clear all data * Expose logout method from SDK * Use logout from SDK, refactor logging out states * Add some strings * Introduce `initialDisplayName` on `UIDevice` * Implement soft logout screen * Add `softLogout` test screen identifier * Add new fields into the client proxy and implement new delegate methods * Add new fields into the user session and observe new client callbacks * Implement updated login method * Add remote logout state and event into the state machine * Implement refreshing restore token on `UserSessionStore` * Update app coordinator with new states and display soft logout screen when appropriate * Add reference screenshots for soft logout screen * Disable auto requesting photos access on screenshot detection * Make initial device name optional, generate project file * Add changelog * Use logout from SDK, refactor logging out states * Implement soft logout screen * Implement updated login method * Make initial device name optional, generate project file * Fix renamed event * Fix logout race * Remove redundant strings * Reuse existing strings * Confirm clear all data * Comment out new apis for now * Make the PR compile
2022-09-15 12:41:37 +03:00
}
}
}
private var userSessionFlowCoordinator: UserSessionFlowCoordinator?
private var authenticationCoordinator: AuthenticationCoordinator?
private let backgroundTaskService: BackgroundTaskServiceProtocol
2022-06-06 12:38:07 +03:00
private var appDelegateObserver: AnyCancellable?
private var userSessionObserver: AnyCancellable?
private var clientProxyObserver: AnyCancellable?
private var networkMonitorObserver: AnyCancellable?
let notificationManager: NotificationManagerProtocol
@Consumable private var storedAppRoute: AppRoute?
2022-11-21 19:37:13 +03:00
2022-02-14 18:05:21 +02:00
init() {
MXLog.configure()
Fixes #317 - Adopt a split layout for iPad and Mac apps Rename navigation components: SplitScreenCoordinator -> NavigationSplitCoordinator, StackScreenCoordinator -> NavigationStackCoordinator and SingleScreenCoordinator -> NavigationRootCoordinator [0c161039] Tweak navigation logging [826c19cf] Move the navigation dismissal callbacks to the NavigationModule, add SingleScreenCoordinator tests [b8830d9c] Add tests [252ad119] Merge the StackScreenCoordinator and SplitScreenCoordinators into a single file and stop publicly exposing their internal workings. Add more documentation. [37671699] Cleanup navigation logging [51406184] Use the parent SplitScreenCoordinator to present embedded StackScreenCoordinator sheets [b94b04c9] Retract the room "syncing" indicator when dismissing a room [1467b0ac] Correctly move to the no room selected state when popping in compact layouts [10bf2ad8] Allow nilling root coordinators, replace present/dismiss sheet with setSheetCoordinator(?) [33716784] Add single screen coordinator fade transition animation [3cbe65e7] Prevent the timeline table view from being reused between different rooms [9c94c50b] Move files around [c10b6bc5] Adapt the user session state machine to the split layout [7115a319] Fix unit and UI tests [1ece59e8] Fix login flows [6884dc3b] Use modules everywhere the underlying object is a NavigationModule [ab08d44c] Rename navigation components to: SingleScreenCoordinator, SplitScreenCoordinator and StackScreenCoordinator [ada2be57] Add SplitNavigationController * Remove the navigationRootCoordinator from the UserSessionFlowCoordinator
2022-12-12 12:31:27 +02:00
navigationRootCoordinator = NavigationRootCoordinator()
Self.setupServiceLocator(navigationRootCoordinator: navigationRootCoordinator)
2022-06-06 12:38:07 +03:00
ServiceLocator.shared.analytics.startIfEnabled()
stateMachine = AppCoordinatorStateMachine()
Fixes #317 - Adopt a split layout for iPad and Mac apps Rename navigation components: SplitScreenCoordinator -> NavigationSplitCoordinator, StackScreenCoordinator -> NavigationStackCoordinator and SingleScreenCoordinator -> NavigationRootCoordinator [0c161039] Tweak navigation logging [826c19cf] Move the navigation dismissal callbacks to the NavigationModule, add SingleScreenCoordinator tests [b8830d9c] Add tests [252ad119] Merge the StackScreenCoordinator and SplitScreenCoordinators into a single file and stop publicly exposing their internal workings. Add more documentation. [37671699] Cleanup navigation logging [51406184] Use the parent SplitScreenCoordinator to present embedded StackScreenCoordinator sheets [b94b04c9] Retract the room "syncing" indicator when dismissing a room [1467b0ac] Correctly move to the no room selected state when popping in compact layouts [10bf2ad8] Allow nilling root coordinators, replace present/dismiss sheet with setSheetCoordinator(?) [33716784] Add single screen coordinator fade transition animation [3cbe65e7] Prevent the timeline table view from being reused between different rooms [9c94c50b] Move files around [c10b6bc5] Adapt the user session state machine to the split layout [7115a319] Fix unit and UI tests [1ece59e8] Fix login flows [6884dc3b] Use modules everywhere the underlying object is a NavigationModule [ab08d44c] Rename navigation components to: SingleScreenCoordinator, SplitScreenCoordinator and StackScreenCoordinator [ada2be57] Add SplitNavigationController * Remove the navigationRootCoordinator from the UserSessionFlowCoordinator
2022-12-12 12:31:27 +02:00
navigationRootCoordinator.setRootCoordinator(SplashScreenCoordinator())
2022-11-21 19:37:13 +03:00
backgroundTaskService = UIKitBackgroundTaskService {
UIApplication.shared
}
2022-11-21 19:37:13 +03:00
userSessionStore = UserSessionStore(backgroundTaskService: backgroundTaskService)
notificationManager = NotificationManager(notificationCenter: UNUserNotificationCenter.current(),
appSettings: ServiceLocator.shared.settings)
notificationManager.delegate = self
notificationManager.start()
guard let currentVersion = Version(InfoPlistReader(bundle: .main).bundleShortVersionString) else {
fatalError("The app's version number **must** use semver for migration purposes.")
}
if let previousVersion = ServiceLocator.shared.settings.lastVersionLaunched.flatMap(Version.init) {
performMigrationsIfNecessary(from: previousVersion, to: currentVersion)
} else {
// The app has been deleted since the previous run. Reset everything.
wipeUserData(includingSettings: true)
}
ServiceLocator.shared.settings.lastVersionLaunched = currentVersion.description
setupStateMachine()
observeApplicationState()
observeNetworkState()
registerBackgroundAppRefresh()
2022-02-14 18:05:21 +02:00
}
func start() {
guard stateMachine.state == .initial else {
MXLog.error("Received a start request when already started")
return
}
stateMachine.processEvent(userSessionStore.hasSessions ? .startWithExistingSession : .startWithAuthentication)
2022-02-14 18:05:21 +02:00
}
Log out (#174) * Expose logout method from SDK * Use logout from SDK, refactor logging out states * Add some strings * Introduce `initialDisplayName` on `UIDevice` * Implement soft logout screen * Add `softLogout` test screen identifier * Add new fields into the client proxy and implement new delegate methods * Add new fields into the user session and observe new client callbacks * Implement updated login method * Add remote logout state and event into the state machine * Implement refreshing restore token on `UserSessionStore` * Update app coordinator with new states and display soft logout screen when appropriate * Add reference screenshots for soft logout screen * Disable auto requesting photos access on screenshot detection * Make initial device name optional, generate project file * Add changelog * Use logout from SDK, refactor logging out states * Implement soft logout screen * Implement updated login method * Make initial device name optional, generate project file * Fix renamed event * Fix logout race * Remove redundant strings * Reuse existing strings * Confirm clear all data * Expose logout method from SDK * Use logout from SDK, refactor logging out states * Add some strings * Introduce `initialDisplayName` on `UIDevice` * Implement soft logout screen * Add `softLogout` test screen identifier * Add new fields into the client proxy and implement new delegate methods * Add new fields into the user session and observe new client callbacks * Implement updated login method * Add remote logout state and event into the state machine * Implement refreshing restore token on `UserSessionStore` * Update app coordinator with new states and display soft logout screen when appropriate * Add reference screenshots for soft logout screen * Disable auto requesting photos access on screenshot detection * Make initial device name optional, generate project file * Add changelog * Use logout from SDK, refactor logging out states * Implement soft logout screen * Implement updated login method * Make initial device name optional, generate project file * Fix renamed event * Fix logout race * Remove redundant strings * Reuse existing strings * Confirm clear all data * Comment out new apis for now * Make the PR compile
2022-09-15 12:41:37 +03:00
func stop() {
hideLoadingIndicator()
}
func toPresentable() -> AnyView {
AnyView(
ServiceLocator.shared.userIndicatorController.toPresentable()
.environment(\.analyticsService, ServiceLocator.shared.analytics)
)
}
// MARK: - AuthenticationCoordinatorDelegate
func authenticationCoordinator(_ authenticationCoordinator: AuthenticationCoordinator, didLoginWithSession userSession: UserSessionProtocol) {
self.userSession = userSession
stateMachine.processEvent(.createdUserSession)
}
// MARK: - NotificationManagerDelegate
func registerForRemoteNotifications() {
UIApplication.shared.registerForRemoteNotifications()
}
func unregisterForRemoteNotifications() {
UIApplication.shared.unregisterForRemoteNotifications()
}
func shouldDisplayInAppNotification(_ service: NotificationManagerProtocol, content: UNNotificationContent) -> Bool {
guard let roomID = content.roomID else {
return true
}
guard let userSessionFlowCoordinator else {
// there is not a user session yet
return false
}
return !userSessionFlowCoordinator.isDisplayingRoomScreen(withRoomID: roomID)
}
func notificationTapped(_ service: NotificationManagerProtocol, content: UNNotificationContent) async {
MXLog.info("[AppCoordinator] tappedNotification")
guard let roomID = content.roomID,
content.receiverID != nil else {
return
}
// Handle here the account switching when available
switch content.categoryIdentifier {
case NotificationConstants.Category.message:
handleAppRoute(.room(roomID: roomID))
case NotificationConstants.Category.invite:
handleAppRoute(.invites)
default:
break
}
}
func handleInlineReply(_ service: NotificationManagerProtocol, content: UNNotificationContent, replyText: String) async {
guard let userSession else {
fatalError("User session not setup")
}
MXLog.info("[AppCoordinator] handle notification reply")
guard let roomID = content.userInfo[NotificationConstants.UserInfoKey.roomIdentifier] as? String else {
return
}
let roomProxy = await userSession.clientProxy.roomForIdentifier(roomID)
switch await roomProxy?.sendMessage(replyText) {
case .success:
break
default:
// error or no room proxy
await service.showLocalNotification(with: "⚠️ " + L10n.commonError,
subtitle: L10n.errorSomeMessagesHaveNotBeenSent)
}
}
// MARK: - Private
private static func setupServiceLocator(navigationRootCoordinator: NavigationRootCoordinator) {
if ProcessInfo.processInfo.environment["RESET_APP_SETTINGS"].map(Bool.init) == true {
AppSettings.reset()
}
ServiceLocator.shared.register(userIndicatorController: UserIndicatorController(rootCoordinator: navigationRootCoordinator))
ServiceLocator.shared.register(appSettings: AppSettings())
ServiceLocator.shared.register(networkMonitor: NetworkMonitor())
ServiceLocator.shared.register(bugReportService: BugReportService(withBaseURL: ServiceLocator.shared.settings.bugReportServiceBaseURL,
sentryURL: ServiceLocator.shared.settings.bugReportSentryURL,
applicationId: ServiceLocator.shared.settings.bugReportApplicationId,
sdkGitSHA: sdkGitSha(),
maxUploadSize: ServiceLocator.shared.settings.bugReportMaxUploadSize))
ServiceLocator.shared.register(analytics: AnalyticsService(client: PostHogAnalyticsClient(),
appSettings: ServiceLocator.shared.settings,
bugReportService: ServiceLocator.shared.bugReportService))
}
/// Perform any required migrations for the app to function correctly.
private func performMigrationsIfNecessary(from oldVersion: Version, to newVersion: Version) {
guard oldVersion != newVersion else { return }
if oldVersion < Version(1, 1, 0) {
MXLog.info("Migrating to v1.1.0, signing out the user.")
// Version 1.1.0 switched the Rust crypto store to SQLite
// There are no migrations in place so we need to reset everything
wipeUserData()
}
if oldVersion < Version(1, 1, 7) {
MXLog.info("Migrating to v1.1.0, marking accounts as migrated.")
for userID in userSessionStore.userIDs {
ServiceLocator.shared.settings.migratedAccounts[userID] = true
}
}
}
/// Clears the keychain, app support directory etc ready for a fresh use.
/// - Parameter includingSettings: Whether to additionally wipe the user's app settings too.
private func wipeUserData(includingSettings: Bool = false) {
if includingSettings {
AppSettings.reset()
}
userSessionStore.reset()
}
private func setupStateMachine() {
stateMachine.addTransitionHandler { [weak self] context in
guard let self else { return }
switch (context.fromState, context.event, context.toState) {
case (.initial, .startWithAuthentication, .signedOut):
self.startAuthentication()
case (.signedOut, .createdUserSession, .signedIn):
self.setupUserSession()
case (.initial, .startWithExistingSession, .restoringSession):
self.restoreUserSession()
case (.restoringSession, .failedRestoringSession, .signedOut):
self.showLoginErrorToast()
self.presentSplashScreen()
case (.restoringSession, .createdUserSession, .signedIn):
self.setupUserSession()
case (.signingOut, .signOut, .signingOut):
// We can ignore signOut when already in the process of signing out,
// such as the SDK sending an authError due to token invalidation.
break
case (_, .signOut(let isSoft), .signingOut):
self.logout(isSoft: isSoft)
case (.signingOut, .completedSigningOut(let isSoft), .signedOut):
self.presentSplashScreen(isSoftLogout: isSoft)
case (.signedIn, .clearCache, .initial):
self.clearCache()
default:
fatalError("Unknown transition: \(context)")
}
}
stateMachine.addErrorHandler { context in
fatalError("Failed transition with context: \(context)")
}
}
private func restoreUserSession() {
Task {
switch await userSessionStore.restoreUserSession() {
case .success(let userSession):
self.userSession = userSession
stateMachine.processEvent(.createdUserSession)
case .failure:
MXLog.error("Failed to restore an existing session.")
stateMachine.processEvent(.failedRestoringSession)
}
}
}
private func startAuthentication() {
Fixes #317 - Adopt a split layout for iPad and Mac apps Rename navigation components: SplitScreenCoordinator -> NavigationSplitCoordinator, StackScreenCoordinator -> NavigationStackCoordinator and SingleScreenCoordinator -> NavigationRootCoordinator [0c161039] Tweak navigation logging [826c19cf] Move the navigation dismissal callbacks to the NavigationModule, add SingleScreenCoordinator tests [b8830d9c] Add tests [252ad119] Merge the StackScreenCoordinator and SplitScreenCoordinators into a single file and stop publicly exposing their internal workings. Add more documentation. [37671699] Cleanup navigation logging [51406184] Use the parent SplitScreenCoordinator to present embedded StackScreenCoordinator sheets [b94b04c9] Retract the room "syncing" indicator when dismissing a room [1467b0ac] Correctly move to the no room selected state when popping in compact layouts [10bf2ad8] Allow nilling root coordinators, replace present/dismiss sheet with setSheetCoordinator(?) [33716784] Add single screen coordinator fade transition animation [3cbe65e7] Prevent the timeline table view from being reused between different rooms [9c94c50b] Move files around [c10b6bc5] Adapt the user session state machine to the split layout [7115a319] Fix unit and UI tests [1ece59e8] Fix login flows [6884dc3b] Use modules everywhere the underlying object is a NavigationModule [ab08d44c] Rename navigation components to: SingleScreenCoordinator, SplitScreenCoordinator and StackScreenCoordinator [ada2be57] Add SplitNavigationController * Remove the navigationRootCoordinator from the UserSessionFlowCoordinator
2022-12-12 12:31:27 +02:00
let authenticationNavigationStackCoordinator = NavigationStackCoordinator()
let authenticationService = AuthenticationServiceProxy(userSessionStore: userSessionStore, appSettings: ServiceLocator.shared.settings)
authenticationCoordinator = AuthenticationCoordinator(authenticationService: authenticationService,
navigationStackCoordinator: authenticationNavigationStackCoordinator,
appSettings: ServiceLocator.shared.settings,
analytics: ServiceLocator.shared.analytics,
userIndicatorController: ServiceLocator.shared.userIndicatorController)
authenticationCoordinator?.delegate = self
authenticationCoordinator?.start()
Fixes #317 - Adopt a split layout for iPad and Mac apps Rename navigation components: SplitScreenCoordinator -> NavigationSplitCoordinator, StackScreenCoordinator -> NavigationStackCoordinator and SingleScreenCoordinator -> NavigationRootCoordinator [0c161039] Tweak navigation logging [826c19cf] Move the navigation dismissal callbacks to the NavigationModule, add SingleScreenCoordinator tests [b8830d9c] Add tests [252ad119] Merge the StackScreenCoordinator and SplitScreenCoordinators into a single file and stop publicly exposing their internal workings. Add more documentation. [37671699] Cleanup navigation logging [51406184] Use the parent SplitScreenCoordinator to present embedded StackScreenCoordinator sheets [b94b04c9] Retract the room "syncing" indicator when dismissing a room [1467b0ac] Correctly move to the no room selected state when popping in compact layouts [10bf2ad8] Allow nilling root coordinators, replace present/dismiss sheet with setSheetCoordinator(?) [33716784] Add single screen coordinator fade transition animation [3cbe65e7] Prevent the timeline table view from being reused between different rooms [9c94c50b] Move files around [c10b6bc5] Adapt the user session state machine to the split layout [7115a319] Fix unit and UI tests [1ece59e8] Fix login flows [6884dc3b] Use modules everywhere the underlying object is a NavigationModule [ab08d44c] Rename navigation components to: SingleScreenCoordinator, SplitScreenCoordinator and StackScreenCoordinator [ada2be57] Add SplitNavigationController * Remove the navigationRootCoordinator from the UserSessionFlowCoordinator
2022-12-12 12:31:27 +02:00
navigationRootCoordinator.setRootCoordinator(authenticationNavigationStackCoordinator)
2022-02-14 18:05:21 +02:00
}
Log out (#174) * Expose logout method from SDK * Use logout from SDK, refactor logging out states * Add some strings * Introduce `initialDisplayName` on `UIDevice` * Implement soft logout screen * Add `softLogout` test screen identifier * Add new fields into the client proxy and implement new delegate methods * Add new fields into the user session and observe new client callbacks * Implement updated login method * Add remote logout state and event into the state machine * Implement refreshing restore token on `UserSessionStore` * Update app coordinator with new states and display soft logout screen when appropriate * Add reference screenshots for soft logout screen * Disable auto requesting photos access on screenshot detection * Make initial device name optional, generate project file * Add changelog * Use logout from SDK, refactor logging out states * Implement soft logout screen * Implement updated login method * Make initial device name optional, generate project file * Fix renamed event * Fix logout race * Remove redundant strings * Reuse existing strings * Confirm clear all data * Expose logout method from SDK * Use logout from SDK, refactor logging out states * Add some strings * Introduce `initialDisplayName` on `UIDevice` * Implement soft logout screen * Add `softLogout` test screen identifier * Add new fields into the client proxy and implement new delegate methods * Add new fields into the user session and observe new client callbacks * Implement updated login method * Add remote logout state and event into the state machine * Implement refreshing restore token on `UserSessionStore` * Update app coordinator with new states and display soft logout screen when appropriate * Add reference screenshots for soft logout screen * Disable auto requesting photos access on screenshot detection * Make initial device name optional, generate project file * Add changelog * Use logout from SDK, refactor logging out states * Implement soft logout screen * Implement updated login method * Make initial device name optional, generate project file * Fix renamed event * Fix logout race * Remove redundant strings * Reuse existing strings * Confirm clear all data * Comment out new apis for now * Make the PR compile
2022-09-15 12:41:37 +03:00
private func startAuthenticationSoftLogout() {
guard let userSession else {
fatalError("User session not setup")
}
Log out (#174) * Expose logout method from SDK * Use logout from SDK, refactor logging out states * Add some strings * Introduce `initialDisplayName` on `UIDevice` * Implement soft logout screen * Add `softLogout` test screen identifier * Add new fields into the client proxy and implement new delegate methods * Add new fields into the user session and observe new client callbacks * Implement updated login method * Add remote logout state and event into the state machine * Implement refreshing restore token on `UserSessionStore` * Update app coordinator with new states and display soft logout screen when appropriate * Add reference screenshots for soft logout screen * Disable auto requesting photos access on screenshot detection * Make initial device name optional, generate project file * Add changelog * Use logout from SDK, refactor logging out states * Implement soft logout screen * Implement updated login method * Make initial device name optional, generate project file * Fix renamed event * Fix logout race * Remove redundant strings * Reuse existing strings * Confirm clear all data * Expose logout method from SDK * Use logout from SDK, refactor logging out states * Add some strings * Introduce `initialDisplayName` on `UIDevice` * Implement soft logout screen * Add `softLogout` test screen identifier * Add new fields into the client proxy and implement new delegate methods * Add new fields into the user session and observe new client callbacks * Implement updated login method * Add remote logout state and event into the state machine * Implement refreshing restore token on `UserSessionStore` * Update app coordinator with new states and display soft logout screen when appropriate * Add reference screenshots for soft logout screen * Disable auto requesting photos access on screenshot detection * Make initial device name optional, generate project file * Add changelog * Use logout from SDK, refactor logging out states * Implement soft logout screen * Implement updated login method * Make initial device name optional, generate project file * Fix renamed event * Fix logout race * Remove redundant strings * Reuse existing strings * Confirm clear all data * Comment out new apis for now * Make the PR compile
2022-09-15 12:41:37 +03:00
Task {
var displayName = ""
if case .success(let name) = await userSession.clientProxy.loadUserDisplayName() {
displayName = name
}
2023-06-26 18:26:20 +01:00
let credentials = SoftLogoutScreenCredentials(userID: userSession.userID,
homeserverName: userSession.homeserver,
userDisplayName: displayName,
2023-06-26 18:26:20 +01:00
deviceID: userSession.deviceID)
let authenticationService = AuthenticationServiceProxy(userSessionStore: userSessionStore, appSettings: ServiceLocator.shared.settings)
Log out (#174) * Expose logout method from SDK * Use logout from SDK, refactor logging out states * Add some strings * Introduce `initialDisplayName` on `UIDevice` * Implement soft logout screen * Add `softLogout` test screen identifier * Add new fields into the client proxy and implement new delegate methods * Add new fields into the user session and observe new client callbacks * Implement updated login method * Add remote logout state and event into the state machine * Implement refreshing restore token on `UserSessionStore` * Update app coordinator with new states and display soft logout screen when appropriate * Add reference screenshots for soft logout screen * Disable auto requesting photos access on screenshot detection * Make initial device name optional, generate project file * Add changelog * Use logout from SDK, refactor logging out states * Implement soft logout screen * Implement updated login method * Make initial device name optional, generate project file * Fix renamed event * Fix logout race * Remove redundant strings * Reuse existing strings * Confirm clear all data * Expose logout method from SDK * Use logout from SDK, refactor logging out states * Add some strings * Introduce `initialDisplayName` on `UIDevice` * Implement soft logout screen * Add `softLogout` test screen identifier * Add new fields into the client proxy and implement new delegate methods * Add new fields into the user session and observe new client callbacks * Implement updated login method * Add remote logout state and event into the state machine * Implement refreshing restore token on `UserSessionStore` * Update app coordinator with new states and display soft logout screen when appropriate * Add reference screenshots for soft logout screen * Disable auto requesting photos access on screenshot detection * Make initial device name optional, generate project file * Add changelog * Use logout from SDK, refactor logging out states * Implement soft logout screen * Implement updated login method * Make initial device name optional, generate project file * Fix renamed event * Fix logout race * Remove redundant strings * Reuse existing strings * Confirm clear all data * Comment out new apis for now * Make the PR compile
2022-09-15 12:41:37 +03:00
_ = await authenticationService.configure(for: userSession.homeserver)
let parameters = SoftLogoutScreenCoordinatorParameters(authenticationService: authenticationService,
credentials: credentials,
keyBackupNeeded: false,
userIndicatorController: ServiceLocator.shared.userIndicatorController)
let coordinator = SoftLogoutScreenCoordinator(parameters: parameters)
Log out (#174) * Expose logout method from SDK * Use logout from SDK, refactor logging out states * Add some strings * Introduce `initialDisplayName` on `UIDevice` * Implement soft logout screen * Add `softLogout` test screen identifier * Add new fields into the client proxy and implement new delegate methods * Add new fields into the user session and observe new client callbacks * Implement updated login method * Add remote logout state and event into the state machine * Implement refreshing restore token on `UserSessionStore` * Update app coordinator with new states and display soft logout screen when appropriate * Add reference screenshots for soft logout screen * Disable auto requesting photos access on screenshot detection * Make initial device name optional, generate project file * Add changelog * Use logout from SDK, refactor logging out states * Implement soft logout screen * Implement updated login method * Make initial device name optional, generate project file * Fix renamed event * Fix logout race * Remove redundant strings * Reuse existing strings * Confirm clear all data * Expose logout method from SDK * Use logout from SDK, refactor logging out states * Add some strings * Introduce `initialDisplayName` on `UIDevice` * Implement soft logout screen * Add `softLogout` test screen identifier * Add new fields into the client proxy and implement new delegate methods * Add new fields into the user session and observe new client callbacks * Implement updated login method * Add remote logout state and event into the state machine * Implement refreshing restore token on `UserSessionStore` * Update app coordinator with new states and display soft logout screen when appropriate * Add reference screenshots for soft logout screen * Disable auto requesting photos access on screenshot detection * Make initial device name optional, generate project file * Add changelog * Use logout from SDK, refactor logging out states * Implement soft logout screen * Implement updated login method * Make initial device name optional, generate project file * Fix renamed event * Fix logout race * Remove redundant strings * Reuse existing strings * Confirm clear all data * Comment out new apis for now * Make the PR compile
2022-09-15 12:41:37 +03:00
coordinator.callback = { result in
switch result {
case .signedIn(let session):
self.userSession = session
self.stateMachine.processEvent(.createdUserSession)
Log out (#174) * Expose logout method from SDK * Use logout from SDK, refactor logging out states * Add some strings * Introduce `initialDisplayName` on `UIDevice` * Implement soft logout screen * Add `softLogout` test screen identifier * Add new fields into the client proxy and implement new delegate methods * Add new fields into the user session and observe new client callbacks * Implement updated login method * Add remote logout state and event into the state machine * Implement refreshing restore token on `UserSessionStore` * Update app coordinator with new states and display soft logout screen when appropriate * Add reference screenshots for soft logout screen * Disable auto requesting photos access on screenshot detection * Make initial device name optional, generate project file * Add changelog * Use logout from SDK, refactor logging out states * Implement soft logout screen * Implement updated login method * Make initial device name optional, generate project file * Fix renamed event * Fix logout race * Remove redundant strings * Reuse existing strings * Confirm clear all data * Expose logout method from SDK * Use logout from SDK, refactor logging out states * Add some strings * Introduce `initialDisplayName` on `UIDevice` * Implement soft logout screen * Add `softLogout` test screen identifier * Add new fields into the client proxy and implement new delegate methods * Add new fields into the user session and observe new client callbacks * Implement updated login method * Add remote logout state and event into the state machine * Implement refreshing restore token on `UserSessionStore` * Update app coordinator with new states and display soft logout screen when appropriate * Add reference screenshots for soft logout screen * Disable auto requesting photos access on screenshot detection * Make initial device name optional, generate project file * Add changelog * Use logout from SDK, refactor logging out states * Implement soft logout screen * Implement updated login method * Make initial device name optional, generate project file * Fix renamed event * Fix logout race * Remove redundant strings * Reuse existing strings * Confirm clear all data * Comment out new apis for now * Make the PR compile
2022-09-15 12:41:37 +03:00
case .clearAllData:
self.stateMachine.processEvent(.signOut(isSoft: false))
Log out (#174) * Expose logout method from SDK * Use logout from SDK, refactor logging out states * Add some strings * Introduce `initialDisplayName` on `UIDevice` * Implement soft logout screen * Add `softLogout` test screen identifier * Add new fields into the client proxy and implement new delegate methods * Add new fields into the user session and observe new client callbacks * Implement updated login method * Add remote logout state and event into the state machine * Implement refreshing restore token on `UserSessionStore` * Update app coordinator with new states and display soft logout screen when appropriate * Add reference screenshots for soft logout screen * Disable auto requesting photos access on screenshot detection * Make initial device name optional, generate project file * Add changelog * Use logout from SDK, refactor logging out states * Implement soft logout screen * Implement updated login method * Make initial device name optional, generate project file * Fix renamed event * Fix logout race * Remove redundant strings * Reuse existing strings * Confirm clear all data * Expose logout method from SDK * Use logout from SDK, refactor logging out states * Add some strings * Introduce `initialDisplayName` on `UIDevice` * Implement soft logout screen * Add `softLogout` test screen identifier * Add new fields into the client proxy and implement new delegate methods * Add new fields into the user session and observe new client callbacks * Implement updated login method * Add remote logout state and event into the state machine * Implement refreshing restore token on `UserSessionStore` * Update app coordinator with new states and display soft logout screen when appropriate * Add reference screenshots for soft logout screen * Disable auto requesting photos access on screenshot detection * Make initial device name optional, generate project file * Add changelog * Use logout from SDK, refactor logging out states * Implement soft logout screen * Implement updated login method * Make initial device name optional, generate project file * Fix renamed event * Fix logout race * Remove redundant strings * Reuse existing strings * Confirm clear all data * Comment out new apis for now * Make the PR compile
2022-09-15 12:41:37 +03:00
}
}
Fixes #317 - Adopt a split layout for iPad and Mac apps Rename navigation components: SplitScreenCoordinator -> NavigationSplitCoordinator, StackScreenCoordinator -> NavigationStackCoordinator and SingleScreenCoordinator -> NavigationRootCoordinator [0c161039] Tweak navigation logging [826c19cf] Move the navigation dismissal callbacks to the NavigationModule, add SingleScreenCoordinator tests [b8830d9c] Add tests [252ad119] Merge the StackScreenCoordinator and SplitScreenCoordinators into a single file and stop publicly exposing their internal workings. Add more documentation. [37671699] Cleanup navigation logging [51406184] Use the parent SplitScreenCoordinator to present embedded StackScreenCoordinator sheets [b94b04c9] Retract the room "syncing" indicator when dismissing a room [1467b0ac] Correctly move to the no room selected state when popping in compact layouts [10bf2ad8] Allow nilling root coordinators, replace present/dismiss sheet with setSheetCoordinator(?) [33716784] Add single screen coordinator fade transition animation [3cbe65e7] Prevent the timeline table view from being reused between different rooms [9c94c50b] Move files around [c10b6bc5] Adapt the user session state machine to the split layout [7115a319] Fix unit and UI tests [1ece59e8] Fix login flows [6884dc3b] Use modules everywhere the underlying object is a NavigationModule [ab08d44c] Rename navigation components to: SingleScreenCoordinator, SplitScreenCoordinator and StackScreenCoordinator [ada2be57] Add SplitNavigationController * Remove the navigationRootCoordinator from the UserSessionFlowCoordinator
2022-12-12 12:31:27 +02:00
navigationRootCoordinator.setRootCoordinator(coordinator)
Log out (#174) * Expose logout method from SDK * Use logout from SDK, refactor logging out states * Add some strings * Introduce `initialDisplayName` on `UIDevice` * Implement soft logout screen * Add `softLogout` test screen identifier * Add new fields into the client proxy and implement new delegate methods * Add new fields into the user session and observe new client callbacks * Implement updated login method * Add remote logout state and event into the state machine * Implement refreshing restore token on `UserSessionStore` * Update app coordinator with new states and display soft logout screen when appropriate * Add reference screenshots for soft logout screen * Disable auto requesting photos access on screenshot detection * Make initial device name optional, generate project file * Add changelog * Use logout from SDK, refactor logging out states * Implement soft logout screen * Implement updated login method * Make initial device name optional, generate project file * Fix renamed event * Fix logout race * Remove redundant strings * Reuse existing strings * Confirm clear all data * Expose logout method from SDK * Use logout from SDK, refactor logging out states * Add some strings * Introduce `initialDisplayName` on `UIDevice` * Implement soft logout screen * Add `softLogout` test screen identifier * Add new fields into the client proxy and implement new delegate methods * Add new fields into the user session and observe new client callbacks * Implement updated login method * Add remote logout state and event into the state machine * Implement refreshing restore token on `UserSessionStore` * Update app coordinator with new states and display soft logout screen when appropriate * Add reference screenshots for soft logout screen * Disable auto requesting photos access on screenshot detection * Make initial device name optional, generate project file * Add changelog * Use logout from SDK, refactor logging out states * Implement soft logout screen * Implement updated login method * Make initial device name optional, generate project file * Fix renamed event * Fix logout race * Remove redundant strings * Reuse existing strings * Confirm clear all data * Comment out new apis for now * Make the PR compile
2022-09-15 12:41:37 +03:00
}
}
2022-02-14 18:05:21 +02:00
private func setupUserSession() {
guard let userSession else {
fatalError("User session not setup")
}
let navigationSplitCoordinator = NavigationSplitCoordinator(placeholderCoordinator: PlaceholderScreenCoordinator())
let userSessionFlowCoordinator = UserSessionFlowCoordinator(userSession: userSession,
Fixes #317 - Adopt a split layout for iPad and Mac apps Rename navigation components: SplitScreenCoordinator -> NavigationSplitCoordinator, StackScreenCoordinator -> NavigationStackCoordinator and SingleScreenCoordinator -> NavigationRootCoordinator [0c161039] Tweak navigation logging [826c19cf] Move the navigation dismissal callbacks to the NavigationModule, add SingleScreenCoordinator tests [b8830d9c] Add tests [252ad119] Merge the StackScreenCoordinator and SplitScreenCoordinators into a single file and stop publicly exposing their internal workings. Add more documentation. [37671699] Cleanup navigation logging [51406184] Use the parent SplitScreenCoordinator to present embedded StackScreenCoordinator sheets [b94b04c9] Retract the room "syncing" indicator when dismissing a room [1467b0ac] Correctly move to the no room selected state when popping in compact layouts [10bf2ad8] Allow nilling root coordinators, replace present/dismiss sheet with setSheetCoordinator(?) [33716784] Add single screen coordinator fade transition animation [3cbe65e7] Prevent the timeline table view from being reused between different rooms [9c94c50b] Move files around [c10b6bc5] Adapt the user session state machine to the split layout [7115a319] Fix unit and UI tests [1ece59e8] Fix login flows [6884dc3b] Use modules everywhere the underlying object is a NavigationModule [ab08d44c] Rename navigation components to: SingleScreenCoordinator, SplitScreenCoordinator and StackScreenCoordinator [ada2be57] Add SplitNavigationController * Remove the navigationRootCoordinator from the UserSessionFlowCoordinator
2022-12-12 12:31:27 +02:00
navigationSplitCoordinator: navigationSplitCoordinator,
bugReportService: ServiceLocator.shared.bugReportService,
roomTimelineControllerFactory: RoomTimelineControllerFactory(),
appSettings: ServiceLocator.shared.settings,
analytics: ServiceLocator.shared.analytics)
userSessionFlowCoordinator.callback = { [weak self] action in
switch action {
case .signOut:
self?.stateMachine.processEvent(.signOut(isSoft: false))
case .clearCache:
self?.stateMachine.processEvent(.clearCache)
}
}
userSessionFlowCoordinator.start()
self.userSessionFlowCoordinator = userSessionFlowCoordinator
Fixes #317 - Adopt a split layout for iPad and Mac apps Rename navigation components: SplitScreenCoordinator -> NavigationSplitCoordinator, StackScreenCoordinator -> NavigationStackCoordinator and SingleScreenCoordinator -> NavigationRootCoordinator [0c161039] Tweak navigation logging [826c19cf] Move the navigation dismissal callbacks to the NavigationModule, add SingleScreenCoordinator tests [b8830d9c] Add tests [252ad119] Merge the StackScreenCoordinator and SplitScreenCoordinators into a single file and stop publicly exposing their internal workings. Add more documentation. [37671699] Cleanup navigation logging [51406184] Use the parent SplitScreenCoordinator to present embedded StackScreenCoordinator sheets [b94b04c9] Retract the room "syncing" indicator when dismissing a room [1467b0ac] Correctly move to the no room selected state when popping in compact layouts [10bf2ad8] Allow nilling root coordinators, replace present/dismiss sheet with setSheetCoordinator(?) [33716784] Add single screen coordinator fade transition animation [3cbe65e7] Prevent the timeline table view from being reused between different rooms [9c94c50b] Move files around [c10b6bc5] Adapt the user session state machine to the split layout [7115a319] Fix unit and UI tests [1ece59e8] Fix login flows [6884dc3b] Use modules everywhere the underlying object is a NavigationModule [ab08d44c] Rename navigation components to: SingleScreenCoordinator, SplitScreenCoordinator and StackScreenCoordinator [ada2be57] Add SplitNavigationController * Remove the navigationRootCoordinator from the UserSessionFlowCoordinator
2022-12-12 12:31:27 +02:00
navigationRootCoordinator.setRootCoordinator(navigationSplitCoordinator)
if let storedAppRoute {
userSessionFlowCoordinator.handleAppRoute(storedAppRoute, animated: false)
}
}
private func logout(isSoft: Bool) {
guard let userSession else {
fatalError("User session not setup")
}
showLoadingIndicator()
stopSync()
userSessionFlowCoordinator?.stop()
Sliding Sync + New Timeline API (#189) * Begin adopting new Timeline API. * Add edited indicator and reactions. * vector-im/element-x-ios/issues/65 - Sliding sync support * Fix missing room display name, wrong placeholder avatar text color and various other warnings that would fail the build on the CI * Various tweaks: * using release version of the demo branch of the sdk * enabled home screen last room messages * switched debug mode rust logging to warn * enabled redactions * enabled new logout flows and soft logout * enabled replies * Fix room member display name and avatar crashes / race condition, fix unit tests * Make the ClientProxy and the UserSession MainActors * Remove unused MatrixRustSDK imports, we should strive to keep these only in top level services and proxies * Don't start either of the syncs while in soft logout * #181: Style the session verification banner to match Figma. * #181: Update verification modal. * #181: Update snapshot tests. * Make session verification state machine less pedantic * Remove unnecessary weak selfs * Various tweaks following code review: * add start and stop sync client proxy methods * move ss proxy url the build settings * made media provider load results discardable * added publishers for the roomSummaryProvider's total number of rooms and state * Fix when sender details are shown * Disable sync v2, causes duplicates in the timeline (as expected) * Move ClientProxy media loading off the main queue and into a detached task * Another attempt at moving image loading off the main queue * Moved home screen diffing and latest room fetching to the background * Prevent the timeline composer from becoming the first responder when not needed * Bump to a newer version of the RustSDK * Fixes vector-im/element-x-ios/issues/107 - New home screen design * Implement thumbnail loading instead of full image avatars. * Revert "Disable sync v2, causes duplicates in the timeline (as expected)" * Add support for local echoes, dispatching detached tasks to a concurrenc GCD queue * Move the session verification banner to a List Section to avoid UI glitches * Optimise room mapping after sliding sync updates and thumbnail fetching * Replace home screen List with a LazyVStack in an attempt to fix performance. Moved move summary provider room updating to a background thread * Fixes vector-im/element-x-ios/issues/177 - New Bubbles Design * Define in group state for timeline items * Add replies into the bubble * Add timeline width environment value * Add `RoundedCorner` shape with specific corners rounding * Add in group state for previews * Implement bubble grouping logic * Timeline avatar layout changes * Fix placeholder avatars for dark mode * New bubbles design * Update mock timeline items * Update timeline separator design * Update room screen reference screenshots * Add changelog * Formatting fixes * Add some space before single or beginning outgoing items * Redesign the message composer * Handle the msgtype enum. * Update room name label line limit and incoming bubble background. Disabled syncv2, ss withCommonExtensions and session verification controller checking * Increase default back pagination limit. * Stop parsing links and tidy up composer button. * Also fix the frame of an image whilst loading. * Bump SDK package version. * Remove app states about settings * Add strings * Use colors on placeholder avatars * Tiny changes for placeholder avatars * Update settings screen design * Provide a user display name from the mock client * Settings screen presentation logic * Add changelog * Update reference screenshots Co-authored-by: Doug <douglase@element.io> Co-authored-by: ismailgulek <ismailgulek@users.noreply.github.com> Co-authored-by: ismailgulek <ismailg@matrix.org>
2022-09-21 11:21:58 +03:00
guard !isSoft else {
stateMachine.processEvent(.completedSigningOut(isSoft: isSoft))
hideLoadingIndicator()
return
Log out (#174) * Expose logout method from SDK * Use logout from SDK, refactor logging out states * Add some strings * Introduce `initialDisplayName` on `UIDevice` * Implement soft logout screen * Add `softLogout` test screen identifier * Add new fields into the client proxy and implement new delegate methods * Add new fields into the user session and observe new client callbacks * Implement updated login method * Add remote logout state and event into the state machine * Implement refreshing restore token on `UserSessionStore` * Update app coordinator with new states and display soft logout screen when appropriate * Add reference screenshots for soft logout screen * Disable auto requesting photos access on screenshot detection * Make initial device name optional, generate project file * Add changelog * Use logout from SDK, refactor logging out states * Implement soft logout screen * Implement updated login method * Make initial device name optional, generate project file * Fix renamed event * Fix logout race * Remove redundant strings * Reuse existing strings * Confirm clear all data * Expose logout method from SDK * Use logout from SDK, refactor logging out states * Add some strings * Introduce `initialDisplayName` on `UIDevice` * Implement soft logout screen * Add `softLogout` test screen identifier * Add new fields into the client proxy and implement new delegate methods * Add new fields into the user session and observe new client callbacks * Implement updated login method * Add remote logout state and event into the state machine * Implement refreshing restore token on `UserSessionStore` * Update app coordinator with new states and display soft logout screen when appropriate * Add reference screenshots for soft logout screen * Disable auto requesting photos access on screenshot detection * Make initial device name optional, generate project file * Add changelog * Use logout from SDK, refactor logging out states * Implement soft logout screen * Implement updated login method * Make initial device name optional, generate project file * Fix renamed event * Fix logout race * Remove redundant strings * Reuse existing strings * Confirm clear all data * Comment out new apis for now * Make the PR compile
2022-09-15 12:41:37 +03:00
}
Sliding Sync + New Timeline API (#189) * Begin adopting new Timeline API. * Add edited indicator and reactions. * vector-im/element-x-ios/issues/65 - Sliding sync support * Fix missing room display name, wrong placeholder avatar text color and various other warnings that would fail the build on the CI * Various tweaks: * using release version of the demo branch of the sdk * enabled home screen last room messages * switched debug mode rust logging to warn * enabled redactions * enabled new logout flows and soft logout * enabled replies * Fix room member display name and avatar crashes / race condition, fix unit tests * Make the ClientProxy and the UserSession MainActors * Remove unused MatrixRustSDK imports, we should strive to keep these only in top level services and proxies * Don't start either of the syncs while in soft logout * #181: Style the session verification banner to match Figma. * #181: Update verification modal. * #181: Update snapshot tests. * Make session verification state machine less pedantic * Remove unnecessary weak selfs * Various tweaks following code review: * add start and stop sync client proxy methods * move ss proxy url the build settings * made media provider load results discardable * added publishers for the roomSummaryProvider's total number of rooms and state * Fix when sender details are shown * Disable sync v2, causes duplicates in the timeline (as expected) * Move ClientProxy media loading off the main queue and into a detached task * Another attempt at moving image loading off the main queue * Moved home screen diffing and latest room fetching to the background * Prevent the timeline composer from becoming the first responder when not needed * Bump to a newer version of the RustSDK * Fixes vector-im/element-x-ios/issues/107 - New home screen design * Implement thumbnail loading instead of full image avatars. * Revert "Disable sync v2, causes duplicates in the timeline (as expected)" * Add support for local echoes, dispatching detached tasks to a concurrenc GCD queue * Move the session verification banner to a List Section to avoid UI glitches * Optimise room mapping after sliding sync updates and thumbnail fetching * Replace home screen List with a LazyVStack in an attempt to fix performance. Moved move summary provider room updating to a background thread * Fixes vector-im/element-x-ios/issues/177 - New Bubbles Design * Define in group state for timeline items * Add replies into the bubble * Add timeline width environment value * Add `RoundedCorner` shape with specific corners rounding * Add in group state for previews * Implement bubble grouping logic * Timeline avatar layout changes * Fix placeholder avatars for dark mode * New bubbles design * Update mock timeline items * Update timeline separator design * Update room screen reference screenshots * Add changelog * Formatting fixes * Add some space before single or beginning outgoing items * Redesign the message composer * Handle the msgtype enum. * Update room name label line limit and incoming bubble background. Disabled syncv2, ss withCommonExtensions and session verification controller checking * Increase default back pagination limit. * Stop parsing links and tidy up composer button. * Also fix the frame of an image whilst loading. * Bump SDK package version. * Remove app states about settings * Add strings * Use colors on placeholder avatars * Tiny changes for placeholder avatars * Update settings screen design * Provide a user display name from the mock client * Settings screen presentation logic * Add changelog * Update reference screenshots Co-authored-by: Doug <douglase@element.io> Co-authored-by: ismailgulek <ismailgulek@users.noreply.github.com> Co-authored-by: ismailgulek <ismailg@matrix.org>
2022-09-21 11:21:58 +03:00
Task {
// first log out from the server
_ = await userSession.clientProxy.logout()
// regardless of the result, clear user data
userSessionStore.logout(userSession: userSession)
tearDownUserSession()
// reset analytics
ServiceLocator.shared.analytics.optOut()
ServiceLocator.shared.analytics.resetConsentState()
stateMachine.processEvent(.completedSigningOut(isSoft: isSoft))
hideLoadingIndicator()
}
Log out (#174) * Expose logout method from SDK * Use logout from SDK, refactor logging out states * Add some strings * Introduce `initialDisplayName` on `UIDevice` * Implement soft logout screen * Add `softLogout` test screen identifier * Add new fields into the client proxy and implement new delegate methods * Add new fields into the user session and observe new client callbacks * Implement updated login method * Add remote logout state and event into the state machine * Implement refreshing restore token on `UserSessionStore` * Update app coordinator with new states and display soft logout screen when appropriate * Add reference screenshots for soft logout screen * Disable auto requesting photos access on screenshot detection * Make initial device name optional, generate project file * Add changelog * Use logout from SDK, refactor logging out states * Implement soft logout screen * Implement updated login method * Make initial device name optional, generate project file * Fix renamed event * Fix logout race * Remove redundant strings * Reuse existing strings * Confirm clear all data * Expose logout method from SDK * Use logout from SDK, refactor logging out states * Add some strings * Introduce `initialDisplayName` on `UIDevice` * Implement soft logout screen * Add `softLogout` test screen identifier * Add new fields into the client proxy and implement new delegate methods * Add new fields into the user session and observe new client callbacks * Implement updated login method * Add remote logout state and event into the state machine * Implement refreshing restore token on `UserSessionStore` * Update app coordinator with new states and display soft logout screen when appropriate * Add reference screenshots for soft logout screen * Disable auto requesting photos access on screenshot detection * Make initial device name optional, generate project file * Add changelog * Use logout from SDK, refactor logging out states * Implement soft logout screen * Implement updated login method * Make initial device name optional, generate project file * Fix renamed event * Fix logout race * Remove redundant strings * Reuse existing strings * Confirm clear all data * Comment out new apis for now * Make the PR compile
2022-09-15 12:41:37 +03:00
}
private func tearDownUserSession() {
ServiceLocator.shared.userIndicatorController.retractAllIndicators()
userSession = nil
userSessionFlowCoordinator = nil
Log out (#174) * Expose logout method from SDK * Use logout from SDK, refactor logging out states * Add some strings * Introduce `initialDisplayName` on `UIDevice` * Implement soft logout screen * Add `softLogout` test screen identifier * Add new fields into the client proxy and implement new delegate methods * Add new fields into the user session and observe new client callbacks * Implement updated login method * Add remote logout state and event into the state machine * Implement refreshing restore token on `UserSessionStore` * Update app coordinator with new states and display soft logout screen when appropriate * Add reference screenshots for soft logout screen * Disable auto requesting photos access on screenshot detection * Make initial device name optional, generate project file * Add changelog * Use logout from SDK, refactor logging out states * Implement soft logout screen * Implement updated login method * Make initial device name optional, generate project file * Fix renamed event * Fix logout race * Remove redundant strings * Reuse existing strings * Confirm clear all data * Expose logout method from SDK * Use logout from SDK, refactor logging out states * Add some strings * Introduce `initialDisplayName` on `UIDevice` * Implement soft logout screen * Add `softLogout` test screen identifier * Add new fields into the client proxy and implement new delegate methods * Add new fields into the user session and observe new client callbacks * Implement updated login method * Add remote logout state and event into the state machine * Implement refreshing restore token on `UserSessionStore` * Update app coordinator with new states and display soft logout screen when appropriate * Add reference screenshots for soft logout screen * Disable auto requesting photos access on screenshot detection * Make initial device name optional, generate project file * Add changelog * Use logout from SDK, refactor logging out states * Implement soft logout screen * Implement updated login method * Make initial device name optional, generate project file * Fix renamed event * Fix logout race * Remove redundant strings * Reuse existing strings * Confirm clear all data * Comment out new apis for now * Make the PR compile
2022-09-15 12:41:37 +03:00
notificationManager.setUserSession(nil)
}
Log out (#174) * Expose logout method from SDK * Use logout from SDK, refactor logging out states * Add some strings * Introduce `initialDisplayName` on `UIDevice` * Implement soft logout screen * Add `softLogout` test screen identifier * Add new fields into the client proxy and implement new delegate methods * Add new fields into the user session and observe new client callbacks * Implement updated login method * Add remote logout state and event into the state machine * Implement refreshing restore token on `UserSessionStore` * Update app coordinator with new states and display soft logout screen when appropriate * Add reference screenshots for soft logout screen * Disable auto requesting photos access on screenshot detection * Make initial device name optional, generate project file * Add changelog * Use logout from SDK, refactor logging out states * Implement soft logout screen * Implement updated login method * Make initial device name optional, generate project file * Fix renamed event * Fix logout race * Remove redundant strings * Reuse existing strings * Confirm clear all data * Expose logout method from SDK * Use logout from SDK, refactor logging out states * Add some strings * Introduce `initialDisplayName` on `UIDevice` * Implement soft logout screen * Add `softLogout` test screen identifier * Add new fields into the client proxy and implement new delegate methods * Add new fields into the user session and observe new client callbacks * Implement updated login method * Add remote logout state and event into the state machine * Implement refreshing restore token on `UserSessionStore` * Update app coordinator with new states and display soft logout screen when appropriate * Add reference screenshots for soft logout screen * Disable auto requesting photos access on screenshot detection * Make initial device name optional, generate project file * Add changelog * Use logout from SDK, refactor logging out states * Implement soft logout screen * Implement updated login method * Make initial device name optional, generate project file * Fix renamed event * Fix logout race * Remove redundant strings * Reuse existing strings * Confirm clear all data * Comment out new apis for now * Make the PR compile
2022-09-15 12:41:37 +03:00
private func presentSplashScreen(isSoftLogout: Bool = false) {
Fixes #317 - Adopt a split layout for iPad and Mac apps Rename navigation components: SplitScreenCoordinator -> NavigationSplitCoordinator, StackScreenCoordinator -> NavigationStackCoordinator and SingleScreenCoordinator -> NavigationRootCoordinator [0c161039] Tweak navigation logging [826c19cf] Move the navigation dismissal callbacks to the NavigationModule, add SingleScreenCoordinator tests [b8830d9c] Add tests [252ad119] Merge the StackScreenCoordinator and SplitScreenCoordinators into a single file and stop publicly exposing their internal workings. Add more documentation. [37671699] Cleanup navigation logging [51406184] Use the parent SplitScreenCoordinator to present embedded StackScreenCoordinator sheets [b94b04c9] Retract the room "syncing" indicator when dismissing a room [1467b0ac] Correctly move to the no room selected state when popping in compact layouts [10bf2ad8] Allow nilling root coordinators, replace present/dismiss sheet with setSheetCoordinator(?) [33716784] Add single screen coordinator fade transition animation [3cbe65e7] Prevent the timeline table view from being reused between different rooms [9c94c50b] Move files around [c10b6bc5] Adapt the user session state machine to the split layout [7115a319] Fix unit and UI tests [1ece59e8] Fix login flows [6884dc3b] Use modules everywhere the underlying object is a NavigationModule [ab08d44c] Rename navigation components to: SingleScreenCoordinator, SplitScreenCoordinator and StackScreenCoordinator [ada2be57] Add SplitNavigationController * Remove the navigationRootCoordinator from the UserSessionFlowCoordinator
2022-12-12 12:31:27 +02:00
navigationRootCoordinator.setRootCoordinator(SplashScreenCoordinator())
Log out (#174) * Expose logout method from SDK * Use logout from SDK, refactor logging out states * Add some strings * Introduce `initialDisplayName` on `UIDevice` * Implement soft logout screen * Add `softLogout` test screen identifier * Add new fields into the client proxy and implement new delegate methods * Add new fields into the user session and observe new client callbacks * Implement updated login method * Add remote logout state and event into the state machine * Implement refreshing restore token on `UserSessionStore` * Update app coordinator with new states and display soft logout screen when appropriate * Add reference screenshots for soft logout screen * Disable auto requesting photos access on screenshot detection * Make initial device name optional, generate project file * Add changelog * Use logout from SDK, refactor logging out states * Implement soft logout screen * Implement updated login method * Make initial device name optional, generate project file * Fix renamed event * Fix logout race * Remove redundant strings * Reuse existing strings * Confirm clear all data * Expose logout method from SDK * Use logout from SDK, refactor logging out states * Add some strings * Introduce `initialDisplayName` on `UIDevice` * Implement soft logout screen * Add `softLogout` test screen identifier * Add new fields into the client proxy and implement new delegate methods * Add new fields into the user session and observe new client callbacks * Implement updated login method * Add remote logout state and event into the state machine * Implement refreshing restore token on `UserSessionStore` * Update app coordinator with new states and display soft logout screen when appropriate * Add reference screenshots for soft logout screen * Disable auto requesting photos access on screenshot detection * Make initial device name optional, generate project file * Add changelog * Use logout from SDK, refactor logging out states * Implement soft logout screen * Implement updated login method * Make initial device name optional, generate project file * Fix renamed event * Fix logout race * Remove redundant strings * Reuse existing strings * Confirm clear all data * Comment out new apis for now * Make the PR compile
2022-09-15 12:41:37 +03:00
if isSoftLogout {
startAuthenticationSoftLogout()
} else {
startAuthentication()
}
2022-02-14 18:05:21 +02:00
}
2022-11-21 19:37:13 +03:00
private func configureNotificationManager() {
notificationManager.setUserSession(userSession)
notificationManager.requestAuthorization()
if let appDelegate = AppDelegate.shared {
appDelegateObserver = appDelegate.callbacks
.receive(on: DispatchQueue.main)
.sink { [weak self] callback in
switch callback {
case .registeredNotifications(let deviceToken):
Task { await self?.notificationManager.register(with: deviceToken) }
case .failedToRegisteredNotifications(let error):
self?.notificationManager.registrationFailed(with: error)
2022-11-21 19:37:13 +03:00
}
}
} else {
MXLog.error("Couldn't register to AppDelegate callbacks")
2022-11-21 19:37:13 +03:00
}
}
2022-02-14 18:05:21 +02:00
Log out (#174) * Expose logout method from SDK * Use logout from SDK, refactor logging out states * Add some strings * Introduce `initialDisplayName` on `UIDevice` * Implement soft logout screen * Add `softLogout` test screen identifier * Add new fields into the client proxy and implement new delegate methods * Add new fields into the user session and observe new client callbacks * Implement updated login method * Add remote logout state and event into the state machine * Implement refreshing restore token on `UserSessionStore` * Update app coordinator with new states and display soft logout screen when appropriate * Add reference screenshots for soft logout screen * Disable auto requesting photos access on screenshot detection * Make initial device name optional, generate project file * Add changelog * Use logout from SDK, refactor logging out states * Implement soft logout screen * Implement updated login method * Make initial device name optional, generate project file * Fix renamed event * Fix logout race * Remove redundant strings * Reuse existing strings * Confirm clear all data * Expose logout method from SDK * Use logout from SDK, refactor logging out states * Add some strings * Introduce `initialDisplayName` on `UIDevice` * Implement soft logout screen * Add `softLogout` test screen identifier * Add new fields into the client proxy and implement new delegate methods * Add new fields into the user session and observe new client callbacks * Implement updated login method * Add remote logout state and event into the state machine * Implement refreshing restore token on `UserSessionStore` * Update app coordinator with new states and display soft logout screen when appropriate * Add reference screenshots for soft logout screen * Disable auto requesting photos access on screenshot detection * Make initial device name optional, generate project file * Add changelog * Use logout from SDK, refactor logging out states * Implement soft logout screen * Implement updated login method * Make initial device name optional, generate project file * Fix renamed event * Fix logout race * Remove redundant strings * Reuse existing strings * Confirm clear all data * Comment out new apis for now * Make the PR compile
2022-09-15 12:41:37 +03:00
private func observeUserSessionChanges() {
guard let userSession else {
fatalError("User session not setup")
}
userSessionObserver = userSession.callbacks
Log out (#174) * Expose logout method from SDK * Use logout from SDK, refactor logging out states * Add some strings * Introduce `initialDisplayName` on `UIDevice` * Implement soft logout screen * Add `softLogout` test screen identifier * Add new fields into the client proxy and implement new delegate methods * Add new fields into the user session and observe new client callbacks * Implement updated login method * Add remote logout state and event into the state machine * Implement refreshing restore token on `UserSessionStore` * Update app coordinator with new states and display soft logout screen when appropriate * Add reference screenshots for soft logout screen * Disable auto requesting photos access on screenshot detection * Make initial device name optional, generate project file * Add changelog * Use logout from SDK, refactor logging out states * Implement soft logout screen * Implement updated login method * Make initial device name optional, generate project file * Fix renamed event * Fix logout race * Remove redundant strings * Reuse existing strings * Confirm clear all data * Expose logout method from SDK * Use logout from SDK, refactor logging out states * Add some strings * Introduce `initialDisplayName` on `UIDevice` * Implement soft logout screen * Add `softLogout` test screen identifier * Add new fields into the client proxy and implement new delegate methods * Add new fields into the user session and observe new client callbacks * Implement updated login method * Add remote logout state and event into the state machine * Implement refreshing restore token on `UserSessionStore` * Update app coordinator with new states and display soft logout screen when appropriate * Add reference screenshots for soft logout screen * Disable auto requesting photos access on screenshot detection * Make initial device name optional, generate project file * Add changelog * Use logout from SDK, refactor logging out states * Implement soft logout screen * Implement updated login method * Make initial device name optional, generate project file * Fix renamed event * Fix logout race * Remove redundant strings * Reuse existing strings * Confirm clear all data * Comment out new apis for now * Make the PR compile
2022-09-15 12:41:37 +03:00
.receive(on: DispatchQueue.main)
.sink { [weak self] callback in
guard let self else { return }
Log out (#174) * Expose logout method from SDK * Use logout from SDK, refactor logging out states * Add some strings * Introduce `initialDisplayName` on `UIDevice` * Implement soft logout screen * Add `softLogout` test screen identifier * Add new fields into the client proxy and implement new delegate methods * Add new fields into the user session and observe new client callbacks * Implement updated login method * Add remote logout state and event into the state machine * Implement refreshing restore token on `UserSessionStore` * Update app coordinator with new states and display soft logout screen when appropriate * Add reference screenshots for soft logout screen * Disable auto requesting photos access on screenshot detection * Make initial device name optional, generate project file * Add changelog * Use logout from SDK, refactor logging out states * Implement soft logout screen * Implement updated login method * Make initial device name optional, generate project file * Fix renamed event * Fix logout race * Remove redundant strings * Reuse existing strings * Confirm clear all data * Expose logout method from SDK * Use logout from SDK, refactor logging out states * Add some strings * Introduce `initialDisplayName` on `UIDevice` * Implement soft logout screen * Add `softLogout` test screen identifier * Add new fields into the client proxy and implement new delegate methods * Add new fields into the user session and observe new client callbacks * Implement updated login method * Add remote logout state and event into the state machine * Implement refreshing restore token on `UserSessionStore` * Update app coordinator with new states and display soft logout screen when appropriate * Add reference screenshots for soft logout screen * Disable auto requesting photos access on screenshot detection * Make initial device name optional, generate project file * Add changelog * Use logout from SDK, refactor logging out states * Implement soft logout screen * Implement updated login method * Make initial device name optional, generate project file * Fix renamed event * Fix logout race * Remove redundant strings * Reuse existing strings * Confirm clear all data * Comment out new apis for now * Make the PR compile
2022-09-15 12:41:37 +03:00
switch callback {
case .didReceiveAuthError(let isSoftLogout):
stateMachine.processEvent(.signOut(isSoft: isSoftLogout))
case .updateRestorationToken:
userSessionStore.refreshRestorationToken(for: userSession)
Log out (#174) * Expose logout method from SDK * Use logout from SDK, refactor logging out states * Add some strings * Introduce `initialDisplayName` on `UIDevice` * Implement soft logout screen * Add `softLogout` test screen identifier * Add new fields into the client proxy and implement new delegate methods * Add new fields into the user session and observe new client callbacks * Implement updated login method * Add remote logout state and event into the state machine * Implement refreshing restore token on `UserSessionStore` * Update app coordinator with new states and display soft logout screen when appropriate * Add reference screenshots for soft logout screen * Disable auto requesting photos access on screenshot detection * Make initial device name optional, generate project file * Add changelog * Use logout from SDK, refactor logging out states * Implement soft logout screen * Implement updated login method * Make initial device name optional, generate project file * Fix renamed event * Fix logout race * Remove redundant strings * Reuse existing strings * Confirm clear all data * Expose logout method from SDK * Use logout from SDK, refactor logging out states * Add some strings * Introduce `initialDisplayName` on `UIDevice` * Implement soft logout screen * Add `softLogout` test screen identifier * Add new fields into the client proxy and implement new delegate methods * Add new fields into the user session and observe new client callbacks * Implement updated login method * Add remote logout state and event into the state machine * Implement refreshing restore token on `UserSessionStore` * Update app coordinator with new states and display soft logout screen when appropriate * Add reference screenshots for soft logout screen * Disable auto requesting photos access on screenshot detection * Make initial device name optional, generate project file * Add changelog * Use logout from SDK, refactor logging out states * Implement soft logout screen * Implement updated login method * Make initial device name optional, generate project file * Fix renamed event * Fix logout race * Remove redundant strings * Reuse existing strings * Confirm clear all data * Comment out new apis for now * Make the PR compile
2022-09-15 12:41:37 +03:00
default:
break
}
}
Log out (#174) * Expose logout method from SDK * Use logout from SDK, refactor logging out states * Add some strings * Introduce `initialDisplayName` on `UIDevice` * Implement soft logout screen * Add `softLogout` test screen identifier * Add new fields into the client proxy and implement new delegate methods * Add new fields into the user session and observe new client callbacks * Implement updated login method * Add remote logout state and event into the state machine * Implement refreshing restore token on `UserSessionStore` * Update app coordinator with new states and display soft logout screen when appropriate * Add reference screenshots for soft logout screen * Disable auto requesting photos access on screenshot detection * Make initial device name optional, generate project file * Add changelog * Use logout from SDK, refactor logging out states * Implement soft logout screen * Implement updated login method * Make initial device name optional, generate project file * Fix renamed event * Fix logout race * Remove redundant strings * Reuse existing strings * Confirm clear all data * Expose logout method from SDK * Use logout from SDK, refactor logging out states * Add some strings * Introduce `initialDisplayName` on `UIDevice` * Implement soft logout screen * Add `softLogout` test screen identifier * Add new fields into the client proxy and implement new delegate methods * Add new fields into the user session and observe new client callbacks * Implement updated login method * Add remote logout state and event into the state machine * Implement refreshing restore token on `UserSessionStore` * Update app coordinator with new states and display soft logout screen when appropriate * Add reference screenshots for soft logout screen * Disable auto requesting photos access on screenshot detection * Make initial device name optional, generate project file * Add changelog * Use logout from SDK, refactor logging out states * Implement soft logout screen * Implement updated login method * Make initial device name optional, generate project file * Fix renamed event * Fix logout race * Remove redundant strings * Reuse existing strings * Confirm clear all data * Comment out new apis for now * Make the PR compile
2022-09-15 12:41:37 +03:00
}
2022-02-14 18:05:21 +02:00
private func observeNetworkState() {
let reachabilityNotificationIdentifier = "io.element.elementx.reachability.notification"
networkMonitorObserver = ServiceLocator.shared.networkMonitor
.reachabilityPublisher
.removeDuplicates()
.sink { reachability in
MXLog.info("Reachability changed to \(reachability)")
if reachability == .reachable {
ServiceLocator.shared.userIndicatorController.retractIndicatorWithId(reachabilityNotificationIdentifier)
} else {
ServiceLocator.shared.userIndicatorController.submitIndicator(.init(id: reachabilityNotificationIdentifier,
title: L10n.commonOffline,
persistent: true))
}
}
}
private func handleAppRoute(_ appRoute: AppRoute) {
if let userSessionFlowCoordinator {
userSessionFlowCoordinator.handleAppRoute(appRoute, animated: UIApplication.shared.applicationState == .active)
} else {
storedAppRoute = appRoute
}
}
private func clearCache() {
guard let userSession else {
fatalError("User session not setup")
}
showLoadingIndicator()
2023-07-21 14:22:09 +01:00
navigationRootCoordinator.setRootCoordinator(PlaceholderScreenCoordinator())
stopSync()
userSessionFlowCoordinator?.stop()
let userID = userSession.userID
tearDownUserSession()
// Allow for everything to deallocate properly
Task {
2023-05-12 18:41:11 +02:00
try? await Task.sleep(for: .seconds(2))
userSessionStore.clearCache(for: userID)
stateMachine.processEvent(.startWithExistingSession)
hideLoadingIndicator()
}
}
// MARK: Toasts and loading indicators
private static let loadingIndicatorIdentifier = "AppCoordinatorLoading"
private func showLoadingIndicator() {
ServiceLocator.shared.userIndicatorController.submitIndicator(UserIndicator(id: Self.loadingIndicatorIdentifier,
type: .modal,
title: L10n.commonLoading,
persistent: true))
}
private func hideLoadingIndicator() {
ServiceLocator.shared.userIndicatorController.retractIndicatorWithId(Self.loadingIndicatorIdentifier)
}
private func showLoginErrorToast() {
ServiceLocator.shared.userIndicatorController.submitIndicator(UserIndicator(title: "Failed logging in"))
}
// MARK: - Application State
private func stopSync() {
userSession?.clientProxy.stopSync()
clientProxyObserver = nil
}
private func startSync() {
guard let userSession else { return }
ServiceLocator.shared.analytics.signpost.beginSync()
userSession.clientProxy.startSync()
let identifier = "StaleDataIndicator"
func showLoadingIndicator() {
ServiceLocator.shared.userIndicatorController.submitIndicator(.init(id: identifier, type: .toast(progress: .indeterminate), title: L10n.commonSyncing, persistent: true))
}
// Prevent the syncing indicator from showing over the offline one
if ServiceLocator.shared.networkMonitor.reachabilityPublisher.value == .reachable {
showLoadingIndicator()
}
clientProxyObserver = userSession.clientProxy
.callbacks
.receive(on: DispatchQueue.main)
.sink { action in
switch action {
case .startedUpdating:
showLoadingIndicator()
case .receivedSyncUpdate:
ServiceLocator.shared.analytics.signpost.endSync()
ServiceLocator.shared.userIndicatorController.retractIndicatorWithId(identifier)
default:
break
}
}
}
private func observeApplicationState() {
NotificationCenter.default.addObserver(self,
selector: #selector(applicationWillResignActive),
name: UIApplication.willResignActiveNotification,
object: nil)
NotificationCenter.default.addObserver(self,
selector: #selector(applicationDidBecomeActive),
name: UIApplication.didBecomeActiveNotification,
object: nil)
NotificationCenter.default.addObserver(self,
selector: #selector(applicationWillTerminate),
name: UIApplication.willTerminateNotification,
object: nil)
NotificationCenter.default.addObserver(self,
selector: #selector(didChangeContentSizeCategory),
name: UIContentSizeCategory.didChangeNotification,
object: nil)
}
@objc
private func didChangeContentSizeCategory() {
AttributedStringBuilder.invalidateCache()
}
@objc
private func applicationWillTerminate() {
userSession?.clientProxy.stopSync()
}
@objc
private func applicationWillResignActive() {
MXLog.info("Application will resign active")
guard backgroundTask == nil else {
return
}
backgroundTask = backgroundTaskService.startBackgroundTask(withName: "SuspendApp: \(UUID().uuidString)") { [weak self] in
guard let self else { return }
userSession?.clientProxy.stopSync()
backgroundTask?.stop()
backgroundTask = nil
}
isSuspended = true
// This does seem to work if scheduled from the background task above
// Schedule it here instead but with an earliest being date of 30 seconds
scheduleBackgroundAppRefresh()
}
@objc
private func applicationDidBecomeActive() {
MXLog.info("Application did become active")
backgroundTask?.stop()
backgroundTask = nil
if isSuspended {
startSync()
}
isSuspended = false
}
// MARK: Background app refresh
private func registerBackgroundAppRefresh() {
let result = BGTaskScheduler.shared.register(forTaskWithIdentifier: ServiceLocator.shared.settings.backgroundAppRefreshTaskIdentifier, using: .main) { [weak self] task in
guard let task = task as? BGAppRefreshTask else {
MXLog.error("Invalid background app refresh configuration")
return
}
self?.handleBackgroundAppRefresh(task)
}
MXLog.info("Register background app refresh with result: \(result)")
}
private func scheduleBackgroundAppRefresh() {
let request = BGAppRefreshTaskRequest(identifier: ServiceLocator.shared.settings.backgroundAppRefreshTaskIdentifier)
// We have other background tasks that keep the app alive
request.earliestBeginDate = Date(timeIntervalSinceNow: 30)
do {
try BGTaskScheduler.shared.submit(request)
MXLog.info("Successfully scheduled background app refresh task")
} catch {
MXLog.error("Failed scheduling background app refresh with error :\(error)")
}
}
private var backgroundRefreshSyncObserver: AnyCancellable?
private func handleBackgroundAppRefresh(_ task: BGAppRefreshTask) {
MXLog.info("Started background app refresh")
// This is important for the app to keep refreshing in the background
scheduleBackgroundAppRefresh()
task.expirationHandler = {
MXLog.info("Background app refresh task expired")
task.setTaskCompleted(success: true)
2022-11-21 19:37:13 +03:00
}
guard let userSession else {
return
}
startSync()
// Be a good citizen, run for a max of 10 SS responses or 10 seconds
// An SS request will time out after 30 seconds if no new data is available
backgroundRefreshSyncObserver = userSession.clientProxy
.callbacks
.filter(\.isSyncUpdate)
.collect(.byTimeOrCount(DispatchQueue.main, .seconds(10), 10))
.sink(receiveValue: { [weak self] _ in
guard let self else { return }
MXLog.info("Background app refresh finished")
backgroundRefreshSyncObserver?.cancel()
task.setTaskCompleted(success: true)
})
2022-11-21 19:37:13 +03:00
}
}