Skip to content

Commit

Permalink
Delay handling inline notification replies until the user session is …
Browse files Browse the repository at this point in the history
…established
  • Loading branch information
stefanceriu committed Nov 22, 2024
1 parent e315451 commit 3f4bca4
Showing 1 changed file with 53 additions and 25 deletions.
78 changes: 53 additions & 25 deletions ElementX/Sources/Application/AppCoordinator.swift
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,7 @@ class AppCoordinator: AppCoordinatorProtocol, AuthenticationFlowCoordinatorDeleg
private var userSession: UserSessionProtocol? {
didSet {
userSessionObserver?.cancel()
if let userSession {
userSession.clientProxy.roomsToAwait = storedRoomsToAwait
if userSession != nil {
configureElementCallService()
configureNotificationManager()
observeUserSessionChanges()
Expand All @@ -55,8 +54,10 @@ class AppCoordinator: AppCoordinatorProtocol, AuthenticationFlowCoordinatorDeleg
let notificationManager: NotificationManagerProtocol

private let appRouteURLParser: AppRouteURLParser

@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) {
let appHooks = AppHooks()
Expand Down Expand Up @@ -313,40 +314,27 @@ class AppCoordinator: AppCoordinatorProtocol, AuthenticationFlowCoordinatorDeleg
if let userSession {
userSession.clientProxy.roomsToAwait.insert(roomID)
} else {
storedRoomsToAwait.insert(roomID)
storedRoomsToAwait = [roomID]
}
}

handleAppRoute(.room(roomID: roomID, via: []))
}

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
}

guard case let .joined(roomProxy) = await userSession.clientProxy.roomForIdentifier(roomID) else {
MXLog.error("Tried to reply in an unjoined room: \(roomID)")
if userSession == nil {
// Store the data so it can be used after the session is established
storedInlineReply = (roomID, replyText)
return
}

switch await roomProxy.timeline.sendMessage(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)
}
await processInlineReply(roomID: roomID, replyText: replyText)
}

// MARK: - Private
Expand Down Expand Up @@ -474,6 +462,24 @@ class AppCoordinator: AppCoordinatorProtocol, AuthenticationFlowCoordinatorDeleg

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() {
guard let userSession else {
Expand Down Expand Up @@ -554,9 +560,9 @@ class AppCoordinator: AppCoordinatorProtocol, AuthenticationFlowCoordinatorDeleg
userSessionFlowCoordinator.start()

self.userSessionFlowCoordinator = userSessionFlowCoordinator

if let storedAppRoute {
userSessionFlowCoordinator.handleAppRoute(storedAppRoute, animated: false)
Task {
await runPostSessionSetupTasks()
}
}

Expand Down Expand Up @@ -832,7 +838,29 @@ class AppCoordinator: AppCoordinatorProtocol, AuthenticationFlowCoordinatorDeleg
SentrySDK.close()
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

private static let loadingIndicatorIdentifier = "\(AppCoordinator.self)-Loading"
Expand Down

0 comments on commit 3f4bca4

Please sign in to comment.