From 1a610363bb2f338b9344b97c81ce49bc782ab662 Mon Sep 17 00:00:00 2001 From: ramadhan sjamsani Date: Fri, 24 Apr 2026 11:58:05 +0800 Subject: [PATCH] iOS navigation fixes: deep-link pop fallback + back-button PopScope - notification_service: use GoRouter.go (not push) for terminal states (session_closing, session_expired) so the nav stack doesn't linger behind deep-linked screens - chat_screen: PopScope + canPop fallback in client_app so iOS back gestures fall back to /home when there is nothing to pop --- .../notifications/notification_service.dart | 3 +- .../features/chat/screens/chat_screen.dart | 62 ++++++++++++------- 2 files changed, 39 insertions(+), 26 deletions(-) diff --git a/client_app/lib/core/notifications/notification_service.dart b/client_app/lib/core/notifications/notification_service.dart index fbee897..a0516b8 100644 --- a/client_app/lib/core/notifications/notification_service.dart +++ b/client_app/lib/core/notifications/notification_service.dart @@ -89,9 +89,8 @@ class NotificationService { final type = data['type'] as String?; if (type == 'session_closing' || type == 'session_expired') { - // Navigate to the chat session — closure UI will show if (sessionId != null) { - _router!.push('/chat/session/$sessionId', extra: 'Bestie'); + _router!.go('/chat/session/$sessionId', extra: 'Bestie'); } } else if ((type == 'chat_message' || type == 'paired') && sessionId != null) { _router!.push('/chat/session/$sessionId', extra: 'Bestie'); diff --git a/client_app/lib/features/chat/screens/chat_screen.dart b/client_app/lib/features/chat/screens/chat_screen.dart index 504d1eb..c98a415 100644 --- a/client_app/lib/features/chat/screens/chat_screen.dart +++ b/client_app/lib/features/chat/screens/chat_screen.dart @@ -74,6 +74,14 @@ class _ChatScreenState extends ConsumerState { _scrollToBottom(); } + void _exitChat() { + if (context.canPop()) { + context.pop(); + } else { + context.go('/home'); + } + } + @override Widget build(BuildContext context) { final chatState = ref.watch(chatProvider); @@ -112,34 +120,40 @@ class _ChatScreenState extends ConsumerState { } }); - return Scaffold( - appBar: AppBar( - backgroundColor: Colors.white, - foregroundColor: Colors.black, - elevation: 0.5, - centerTitle: true, - leading: IconButton( - icon: const Icon(Icons.chevron_left, size: 28), - onPressed: () => context.pop(), - ), - title: Text(widget.mitraName), - actions: [ - if (chatState is ChatConnectedData && chatState.remainingSeconds != null) - Padding( - padding: const EdgeInsets.only(right: 16), - child: Center( - child: Text( - '${chatState.remainingSeconds}s', - style: TextStyle( - color: chatState.remainingSeconds! < 30 ? Colors.red : Colors.black, - fontWeight: FontWeight.bold, + return PopScope( + canPop: false, + onPopInvokedWithResult: (didPop, _) { + if (!didPop) _exitChat(); + }, + child: Scaffold( + appBar: AppBar( + backgroundColor: Colors.white, + foregroundColor: Colors.black, + elevation: 0.5, + centerTitle: true, + leading: IconButton( + icon: const Icon(Icons.chevron_left, size: 28), + onPressed: _exitChat, + ), + title: Text(widget.mitraName), + actions: [ + if (chatState is ChatConnectedData && chatState.remainingSeconds != null) + Padding( + padding: const EdgeInsets.only(right: 16), + child: Center( + child: Text( + '${chatState.remainingSeconds}s', + style: TextStyle( + color: chatState.remainingSeconds! < 30 ? Colors.red : Colors.black, + fontWeight: FontWeight.bold, + ), ), ), ), - ), - ], + ], + ), + body: _buildBody(chatState, closureState), ), - body: _buildBody(chatState, closureState), ); }