Delay handling inline notification replies until the user session is established

This commit is contained in:
Stefan Ceriu 2024-11-21 10:18:14 +02:00 committed by Stefan Ceriu
parent e315451448
commit 3f4bca48b1

View File

@ -30,8 +30,7 @@ class AppCoordinator: AppCoordinatorProtocol, AuthenticationFlowCoordinatorDeleg
private var userSession: UserSessionProtocol? { private var userSession: UserSessionProtocol? {
didSet { didSet {
userSessionObserver?.cancel() userSessionObserver?.cancel()
if let userSession { if userSession != nil {
userSession.clientProxy.roomsToAwait = storedRoomsToAwait
configureElementCallService() configureElementCallService()
configureNotificationManager() configureNotificationManager()
observeUserSessionChanges() observeUserSessionChanges()
@ -55,8 +54,10 @@ class AppCoordinator: AppCoordinatorProtocol, AuthenticationFlowCoordinatorDeleg
let notificationManager: NotificationManagerProtocol let notificationManager: NotificationManagerProtocol
private let appRouteURLParser: AppRouteURLParser private let appRouteURLParser: AppRouteURLParser
@Consumable private var storedAppRoute: AppRoute? @Consumable private var storedAppRoute: AppRoute?
private var storedRoomsToAwait: Set<String> = [] @Consumable private var storedInlineReply: (roomID: String, message: String)?
@Consumable private var storedRoomsToAwait: Set<String>?
init(appDelegate: AppDelegate) { init(appDelegate: AppDelegate) {
let appHooks = AppHooks() let appHooks = AppHooks()
@ -313,7 +314,7 @@ class AppCoordinator: AppCoordinatorProtocol, AuthenticationFlowCoordinatorDeleg
if let userSession { if let userSession {
userSession.clientProxy.roomsToAwait.insert(roomID) userSession.clientProxy.roomsToAwait.insert(roomID)
} else { } else {
storedRoomsToAwait.insert(roomID) storedRoomsToAwait = [roomID]
} }
} }
@ -321,32 +322,19 @@ class AppCoordinator: AppCoordinatorProtocol, AuthenticationFlowCoordinatorDeleg
} }
func handleInlineReply(_ service: NotificationManagerProtocol, content: UNNotificationContent, replyText: String) async { func handleInlineReply(_ service: NotificationManagerProtocol, content: UNNotificationContent, replyText: String) async {
guard let userSession else {
fatalError("User session not setup")
}
MXLog.info("[AppCoordinator] handle notification reply") MXLog.info("[AppCoordinator] handle notification reply")
guard let roomID = content.userInfo[NotificationConstants.UserInfoKey.roomIdentifier] as? String else { guard let roomID = content.userInfo[NotificationConstants.UserInfoKey.roomIdentifier] as? String else {
return return
} }
guard case let .joined(roomProxy) = await userSession.clientProxy.roomForIdentifier(roomID) else { if userSession == nil {
MXLog.error("Tried to reply in an unjoined room: \(roomID)") // Store the data so it can be used after the session is established
storedInlineReply = (roomID, replyText)
return return
} }
switch await roomProxy.timeline.sendMessage(replyText, await processInlineReply(roomID: roomID, replyText: replyText)
html: nil,
inReplyToEventID: nil,
intentionalMentions: .empty) {
case .success:
break
default:
// error or no room proxy
await service.showLocalNotification(with: "⚠️ " + L10n.commonError,
subtitle: L10n.errorSomeMessagesHaveNotBeenSent)
}
} }
// MARK: - Private // MARK: - Private
@ -474,6 +462,24 @@ class AppCoordinator: AppCoordinatorProtocol, AuthenticationFlowCoordinatorDeleg
authenticationFlowCoordinator?.start() authenticationFlowCoordinator?.start()
} }
private func runPostSessionSetupTasks() async {
guard let userSession, let userSessionFlowCoordinator else {
fatalError("User session not setup")
}
if let storedRoomsToAwait {
userSession.clientProxy.roomsToAwait = storedRoomsToAwait
}
if let storedAppRoute {
userSessionFlowCoordinator.handleAppRoute(storedAppRoute, animated: false)
}
if let storedInlineReply {
await processInlineReply(roomID: storedInlineReply.roomID, replyText: storedInlineReply.message)
}
}
private func startAuthenticationSoftLogout() { private func startAuthenticationSoftLogout() {
guard let userSession else { guard let userSession else {
@ -554,9 +560,9 @@ class AppCoordinator: AppCoordinatorProtocol, AuthenticationFlowCoordinatorDeleg
userSessionFlowCoordinator.start() userSessionFlowCoordinator.start()
self.userSessionFlowCoordinator = userSessionFlowCoordinator self.userSessionFlowCoordinator = userSessionFlowCoordinator
if let storedAppRoute { Task {
userSessionFlowCoordinator.handleAppRoute(storedAppRoute, animated: false) await runPostSessionSetupTasks()
} }
} }
@ -832,7 +838,29 @@ class AppCoordinator: AppCoordinatorProtocol, AuthenticationFlowCoordinatorDeleg
SentrySDK.close() SentrySDK.close()
MXLog.info("SentrySDK stopped") MXLog.info("SentrySDK stopped")
} }
private func processInlineReply(roomID: String, replyText: String) async {
guard let userSession else {
fatalError("User session not setup")
}
guard case let .joined(roomProxy) = await userSession.clientProxy.roomForIdentifier(roomID) else {
MXLog.error("Tried to reply in an unjoined room: \(roomID)")
return
}
switch await roomProxy.timeline.sendMessage(replyText,
html: nil,
inReplyToEventID: nil,
intentionalMentions: .empty) {
case .success:
break
default:
await notificationManager.showLocalNotification(with: "⚠️ " + L10n.commonError,
subtitle: L10n.errorSomeMessagesHaveNotBeenSent)
}
}
// MARK: Toasts and loading indicators // MARK: Toasts and loading indicators
private static let loadingIndicatorIdentifier = "\(AppCoordinator.self)-Loading" private static let loadingIndicatorIdentifier = "\(AppCoordinator.self)-Loading"