fix(#141): notification tap opens original session instead of new session (#147)

Co-authored-by: M57 <hy4ri@users.noreply.github.com>
This commit is contained in:
M57andM57 authored and GitHub committed 2026-06-20 10:10:10 +03:00
1 parent ae62b05e6d
commit f5edf1569c
4 files changed
+28 -9

No files matched your search

@@ -9,6 +9,7 @@ import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Surface import androidx.compose.material3.Surface
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import com.m57.hermescontrol.data.local.AuthManager import com.m57.hermescontrol.data.local.AuthManager
import com.m57.hermescontrol.notification.NotificationReplyReceiver
import com.m57.hermescontrol.theme.HermesControlTheme import com.m57.hermescontrol.theme.HermesControlTheme
class MainActivity : ComponentActivity() { class MainActivity : ComponentActivity() {
@@ -17,6 +18,9 @@ class MainActivity : ComponentActivity() {
AuthManager.init(this) AuthManager.init(this)
// Read notification tap sessionId (if any) from the intent that launched us
val notificationSessionId = intent?.getStringExtra(NotificationReplyReceiver.EXTRA_SESSION_ID)
enableEdgeToEdge() enableEdgeToEdge()
setContent { setContent {
// B6 (Jun 18 2026, kanban t_86e9be9b): read the stored theme // B6 (Jun 18 2026, kanban t_86e9be9b): read the stored theme
@@ -28,7 +32,7 @@ class MainActivity : ComponentActivity() {
modifier = Modifier.fillMaxSize(), modifier = Modifier.fillMaxSize(),
color = MaterialTheme.colorScheme.background, color = MaterialTheme.colorScheme.background,
) { ) {
MainNavigation() MainNavigation(sessionId = notificationSessionId)
} }
} }
} }
@@ -171,7 +171,7 @@ private val DRAWER_ENTRIES =
private val DRAWER_GESTURE_SCREENS: Set<NavKey> = ALL_NAV_ITEMS.map { it.key }.toSet() private val DRAWER_GESTURE_SCREENS: Set<NavKey> = ALL_NAV_ITEMS.map { it.key }.toSet()
@Composable @Composable
fun MainNavigation() { fun MainNavigation(sessionId: String? = null) {
val hasToken = !AuthManager.getToken().isNullOrBlank() val hasToken = !AuthManager.getToken().isNullOrBlank()
val startScreen: NavKey = if (hasToken) ChatScreen else ConnectScreen val startScreen: NavKey = if (hasToken) ChatScreen else ConnectScreen
@@ -315,7 +315,7 @@ fun MainNavigation() {
) { paddingValues -> ) { paddingValues ->
NavDisplay( NavDisplay(
backStack = backStack, backStack = backStack,
onBack = { backStack.removeLastOrNull() }, onBack = { NavigationController.goBack() },
entryProvider = entryProvider =
entryProvider { entryProvider {
entry<ConnectScreen> { entry<ConnectScreen> {
@@ -331,12 +331,13 @@ fun MainNavigation() {
entry<ChatScreen> { entry<ChatScreen> {
ChatScreenContent( ChatScreenContent(
onOpenDrawer = { openDrawer() }, onOpenDrawer = { openDrawer() },
sessionId = sessionId,
) )
} }
entry<SettingsScreen> { entry<SettingsScreen> {
SettingsScreenContent( SettingsScreenContent(
onBack = { backStack.removeLastOrNull() }, onBack = { NavigationController.goBack() },
) )
} }
@@ -103,7 +103,7 @@ class ChatNotificationService : Service() {
.setStyle(NotificationCompat.BigTextStyle().bigText(text)) .setStyle(NotificationCompat.BigTextStyle().bigText(text))
.setPriority(NotificationCompat.PRIORITY_HIGH) .setPriority(NotificationCompat.PRIORITY_HIGH)
.setAutoCancel(true) .setAutoCancel(true)
.setContentIntent(buildContentIntent()) .setContentIntent(buildContentIntent(sessionId))
if (!sessionId.isNullOrBlank()) { if (!sessionId.isNullOrBlank()) {
val replyLabel = "Type your reply..." val replyLabel = "Type your reply..."
@@ -142,13 +142,18 @@ class ChatNotificationService : Service() {
manager.notify(PENDING_NOTIFICATION_ID, builder.build()) manager.notify(PENDING_NOTIFICATION_ID, builder.build())
} }
private fun buildContentIntent(): PendingIntent = private fun buildContentIntent(sessionId: String?): PendingIntent {
PendingIntent.getActivity( val intent = Intent(this, MainActivity::class.java)
if (!sessionId.isNullOrBlank()) {
intent.putExtra(NotificationReplyReceiver.EXTRA_SESSION_ID, sessionId)
}
return PendingIntent.getActivity(
this, this,
0, sessionId?.hashCode() ?: 0,
Intent(this, MainActivity::class.java), intent,
PendingIntent.FLAG_IMMUTABLE or PendingIntent.FLAG_UPDATE_CURRENT, PendingIntent.FLAG_IMMUTABLE or PendingIntent.FLAG_UPDATE_CURRENT,
) )
}
private fun buildForegroundNotification(text: String): Notification = private fun buildForegroundNotification(text: String): Notification =
NotificationCompat NotificationCompat
@@ -101,6 +101,7 @@ import com.m57.hermescontrol.ui.common.HermesScaffold
fun ChatScreen( fun ChatScreen(
modifier: Modifier = Modifier, modifier: Modifier = Modifier,
onOpenDrawer: (() -> Unit)? = null, onOpenDrawer: (() -> Unit)? = null,
sessionId: String? = null,
viewModel: ChatViewModel = viewModel(), viewModel: ChatViewModel = viewModel(),
) { ) {
val state by viewModel.uiState.collectAsStateWithLifecycle() val state by viewModel.uiState.collectAsStateWithLifecycle()
@@ -111,6 +112,14 @@ fun ChatScreen(
val context = LocalContext.current val context = LocalContext.current
val lifecycleOwner = androidx.lifecycle.compose.LocalLifecycleOwner.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: // Manage notification foreground service lifecycle:
// - When app goes to background (ON_STOP), mark as not-foreground and // - When app goes to background (ON_STOP), mark as not-foreground and
// start the notification service so we can post reply notifications. // start the notification service so we can post reply notifications.