From 82c1e73b51538d0c56e5bb2d619a2952f2005391 Mon Sep 17 00:00:00 2001 From: Strycher Date: Sat, 18 Jul 2026 14:03:21 -0400 Subject: [PATCH] fix(#289): keep the bottom bar inside a channel so there is a way out An open channel had no exit on desktop. Two changes combined badly: the hamburger replaced the app bar's back arrow, and the chat screen carried no bottom bar. On phone system back still worked, but Windows has no system back button, so the channel was a dead end. - ChannelChatScreen now passes selectedIndex/onDestinationSelected to AppShell, so the bottom bar is present here as well. This also matches the decision that the bottom bar appears at every width. - Tapping Channels pops back to the channel list. Tapping Contacts or Map pops the chat first, then replaces the list, so the chat is not stranded beneath the destination. flutter analyze clean, dart format applied. Not yet run on hardware. --- lib/screens/channel_chat_screen.dart | 37 +++++++++++++++++++++++++--- 1 file changed, 34 insertions(+), 3 deletions(-) diff --git a/lib/screens/channel_chat_screen.dart b/lib/screens/channel_chat_screen.dart index 7ab72c6..de93025 100644 --- a/lib/screens/channel_chat_screen.dart +++ b/lib/screens/channel_chat_screen.dart @@ -28,6 +28,7 @@ import '../services/block_service.dart'; import '../services/chat_text_scale_service.dart'; import '../services/translation_service.dart'; import '../utils/emoji_utils.dart'; +import '../utils/route_transitions.dart'; import '../widgets/app_shell.dart'; import '../widgets/channel_drawer_list.dart'; import '../widgets/mention_autocomplete.dart'; @@ -43,6 +44,7 @@ import '../widgets/sync_progress_overlay.dart'; import '../widgets/translated_message_content.dart'; import '../widgets/unread_divider.dart'; import 'channel_message_path_screen.dart'; +import 'contacts_screen.dart'; import 'map_screen.dart'; class ChannelChatScreen extends StatefulWidget { @@ -285,6 +287,27 @@ class _ChannelChatScreenState extends State { ); } + /// Bottom-bar navigation out of an open channel. + /// + /// Tapping Channels returns to the channel list. Tapping Contacts or Map + /// leaves the channel entirely, so the chat is popped first rather than + /// stranding it under the destination. + void _handleQuickSwitch(int index) { + final navigator = Navigator.of(context); + if (index == 1) { + navigator.pop(); + return; + } + navigator.pop(); + navigator.pushReplacement( + buildQuickSwitchRoute( + index == 0 + ? const ContactsScreen(hideBackButton: true) + : const MapScreen(hideBackButton: true), + ), + ); + } + /// Switch to another channel picked from the nav panel. /// /// Swaps the conversation in place rather than pushing a route, so a pinned @@ -315,9 +338,17 @@ class _ChannelChatScreenState extends State { @override Widget build(BuildContext context) { return AppShell( - // No bottom bar: this is a pushed detail screen. The panel is still - // pinnable here, which is the wide-screen point - keeping the channel - // list and its unread counts visible while reading a channel. + // The bottom bar is present here too. Without it there is no way out of + // a channel on desktop, where there is no system back button and the + // hamburger has taken the back arrow's place. + selectedIndex: 1, + onDestinationSelected: _handleQuickSwitch, + contactsUnreadCount: context + .watch() + .getTotalContactsUnreadCount(), + channelsUnreadCount: context + .watch() + .getTotalChannelsUnreadCount(), drawerContent: ChannelDrawerList( currentChannelIndex: _currentChannel.index, onChannelSelected: _switchChannel,