From f5edf1569ca333aa8a78967c4d3aa1f78997f0d5 Mon Sep 17 00:00:00 2001 From: M57 <41645758+Hy4ri@users.noreply.github.com> Date: Sat, 20 Jun 2026 10:10:10 +0300 Subject: [PATCH] fix(#141): notification tap opens original session instead of new session (#147) Co-authored-by: M57 --- .../java/com/m57/hermescontrol/MainActivity.kt | 6 +++++- .../main/java/com/m57/hermescontrol/Navigation.kt | 7 ++++--- .../notification/ChatNotificationService.kt | 15 ++++++++++----- .../com/m57/hermescontrol/ui/chat/ChatScreen.kt | 9 +++++++++ 4 files changed, 28 insertions(+), 9 deletions(-) diff --git a/app/src/main/java/com/m57/hermescontrol/MainActivity.kt b/app/src/main/java/com/m57/hermescontrol/MainActivity.kt index c87e88bd..8b2bba08 100644 --- a/app/src/main/java/com/m57/hermescontrol/MainActivity.kt +++ b/app/src/main/java/com/m57/hermescontrol/MainActivity.kt @@ -9,6 +9,7 @@ import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Surface import androidx.compose.ui.Modifier import com.m57.hermescontrol.data.local.AuthManager +import com.m57.hermescontrol.notification.NotificationReplyReceiver import com.m57.hermescontrol.theme.HermesControlTheme class MainActivity : ComponentActivity() { @@ -17,6 +18,9 @@ class MainActivity : ComponentActivity() { AuthManager.init(this) + // Read notification tap sessionId (if any) from the intent that launched us + val notificationSessionId = intent?.getStringExtra(NotificationReplyReceiver.EXTRA_SESSION_ID) + enableEdgeToEdge() setContent { // B6 (Jun 18 2026, kanban t_86e9be9b): read the stored theme @@ -28,7 +32,7 @@ class MainActivity : ComponentActivity() { modifier = Modifier.fillMaxSize(), color = MaterialTheme.colorScheme.background, ) { - MainNavigation() + MainNavigation(sessionId = notificationSessionId) } } } diff --git a/app/src/main/java/com/m57/hermescontrol/Navigation.kt b/app/src/main/java/com/m57/hermescontrol/Navigation.kt index 75470e23..a995a987 100644 --- a/app/src/main/java/com/m57/hermescontrol/Navigation.kt +++ b/app/src/main/java/com/m57/hermescontrol/Navigation.kt @@ -171,7 +171,7 @@ private val DRAWER_ENTRIES = private val DRAWER_GESTURE_SCREENS: Set = ALL_NAV_ITEMS.map { it.key }.toSet() @Composable -fun MainNavigation() { +fun MainNavigation(sessionId: String? = null) { val hasToken = !AuthManager.getToken().isNullOrBlank() val startScreen: NavKey = if (hasToken) ChatScreen else ConnectScreen @@ -315,7 +315,7 @@ fun MainNavigation() { ) { paddingValues -> NavDisplay( backStack = backStack, - onBack = { backStack.removeLastOrNull() }, + onBack = { NavigationController.goBack() }, entryProvider = entryProvider { entry { @@ -331,12 +331,13 @@ fun MainNavigation() { entry { ChatScreenContent( onOpenDrawer = { openDrawer() }, + sessionId = sessionId, ) } entry { SettingsScreenContent( - onBack = { backStack.removeLastOrNull() }, + onBack = { NavigationController.goBack() }, ) } diff --git a/app/src/main/java/com/m57/hermescontrol/notification/ChatNotificationService.kt b/app/src/main/java/com/m57/hermescontrol/notification/ChatNotificationService.kt index dbd62d44..8669cfa3 100644 --- a/app/src/main/java/com/m57/hermescontrol/notification/ChatNotificationService.kt +++ b/app/src/main/java/com/m57/hermescontrol/notification/ChatNotificationService.kt @@ -103,7 +103,7 @@ class ChatNotificationService : Service() { .setStyle(NotificationCompat.BigTextStyle().bigText(text)) .setPriority(NotificationCompat.PRIORITY_HIGH) .setAutoCancel(true) - .setContentIntent(buildContentIntent()) + .setContentIntent(buildContentIntent(sessionId)) if (!sessionId.isNullOrBlank()) { val replyLabel = "Type your reply..." @@ -142,13 +142,18 @@ class ChatNotificationService : Service() { manager.notify(PENDING_NOTIFICATION_ID, builder.build()) } - private fun buildContentIntent(): PendingIntent = - PendingIntent.getActivity( + private fun buildContentIntent(sessionId: String?): PendingIntent { + val intent = Intent(this, MainActivity::class.java) + if (!sessionId.isNullOrBlank()) { + intent.putExtra(NotificationReplyReceiver.EXTRA_SESSION_ID, sessionId) + } + return PendingIntent.getActivity( this, - 0, - Intent(this, MainActivity::class.java), + sessionId?.hashCode() ?: 0, + intent, PendingIntent.FLAG_IMMUTABLE or PendingIntent.FLAG_UPDATE_CURRENT, ) + } private fun buildForegroundNotification(text: String): Notification = NotificationCompat diff --git a/app/src/main/java/com/m57/hermescontrol/ui/chat/ChatScreen.kt b/app/src/main/java/com/m57/hermescontrol/ui/chat/ChatScreen.kt index 04e22d10..a0e3fd1e 100644 --- a/app/src/main/java/com/m57/hermescontrol/ui/chat/ChatScreen.kt +++ b/app/src/main/java/com/m57/hermescontrol/ui/chat/ChatScreen.kt @@ -101,6 +101,7 @@ import com.m57.hermescontrol.ui.common.HermesScaffold fun ChatScreen( modifier: Modifier = Modifier, onOpenDrawer: (() -> Unit)? = null, + sessionId: String? = null, viewModel: ChatViewModel = viewModel(), ) { val state by viewModel.uiState.collectAsStateWithLifecycle() @@ -111,6 +112,14 @@ fun ChatScreen( val context = LocalContext.current val lifecycleOwner = androidx.lifecycle.compose.LocalLifecycleOwner.current + // Switch to the session from a notification tap when provided. + // Runs once per sessionId value (re-runs if a different notification taps in). + LaunchedEffect(sessionId) { + if (!sessionId.isNullOrBlank()) { + viewModel.switchSession(sessionId) + } + } + // Manage notification foreground service lifecycle: // - When app goes to background (ON_STOP), mark as not-foreground and // start the notification service so we can post reply notifications.