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
This commit is contained in:
2026-04-24 11:58:05 +08:00
parent 3a25ddc41d
commit 1a610363bb
2 changed files with 39 additions and 26 deletions

View File

@@ -89,9 +89,8 @@ class NotificationService {
final type = data['type'] as String?; final type = data['type'] as String?;
if (type == 'session_closing' || type == 'session_expired') { if (type == 'session_closing' || type == 'session_expired') {
// Navigate to the chat session — closure UI will show
if (sessionId != null) { 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) { } else if ((type == 'chat_message' || type == 'paired') && sessionId != null) {
_router!.push('/chat/session/$sessionId', extra: 'Bestie'); _router!.push('/chat/session/$sessionId', extra: 'Bestie');

View File

@@ -74,6 +74,14 @@ class _ChatScreenState extends ConsumerState<ChatScreen> {
_scrollToBottom(); _scrollToBottom();
} }
void _exitChat() {
if (context.canPop()) {
context.pop();
} else {
context.go('/home');
}
}
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final chatState = ref.watch(chatProvider); final chatState = ref.watch(chatProvider);
@@ -112,34 +120,40 @@ class _ChatScreenState extends ConsumerState<ChatScreen> {
} }
}); });
return Scaffold( return PopScope(
appBar: AppBar( canPop: false,
backgroundColor: Colors.white, onPopInvokedWithResult: (didPop, _) {
foregroundColor: Colors.black, if (!didPop) _exitChat();
elevation: 0.5, },
centerTitle: true, child: Scaffold(
leading: IconButton( appBar: AppBar(
icon: const Icon(Icons.chevron_left, size: 28), backgroundColor: Colors.white,
onPressed: () => context.pop(), foregroundColor: Colors.black,
), elevation: 0.5,
title: Text(widget.mitraName), centerTitle: true,
actions: [ leading: IconButton(
if (chatState is ChatConnectedData && chatState.remainingSeconds != null) icon: const Icon(Icons.chevron_left, size: 28),
Padding( onPressed: _exitChat,
padding: const EdgeInsets.only(right: 16), ),
child: Center( title: Text(widget.mitraName),
child: Text( actions: [
'${chatState.remainingSeconds}s', if (chatState is ChatConnectedData && chatState.remainingSeconds != null)
style: TextStyle( Padding(
color: chatState.remainingSeconds! < 30 ? Colors.red : Colors.black, padding: const EdgeInsets.only(right: 16),
fontWeight: FontWeight.bold, 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),
); );
} }