diff --git a/lib/screens/main_screen.dart b/lib/screens/main_screen.dart index 0bc8493c..03448520 100644 --- a/lib/screens/main_screen.dart +++ b/lib/screens/main_screen.dart @@ -99,6 +99,20 @@ bool shouldRenderMainScreenOffline({ return providerOffline || (startupOfflineUntilConnected && !hasVisibleConnectedServers); } +@visibleForTesting +List mainScreenBottomNavigationTabs({ + required List visibleTabs, + required bool isMobile, + required bool isOffline, + required NavigationTabId currentTab, +}) { + if (!isMobile) return visibleTabs; + return visibleTabs.where((tab) { + if (tab.id != NavigationTabId.settings) return true; + return isOffline || currentTab == NavigationTabId.settings; + }).toList(); +} + @visibleForTesting bool shouldPassTvosMenuToSystem({ required bool isAppleTV, @@ -1494,9 +1508,12 @@ class _MainScreenState extends State } List _getBottomNavigationTabs(BuildContext context) { - final tabs = _getVisibleTabs(_isOffline); - if (!PlatformDetector.isMobile(context)) return tabs; - return tabs.where((tab) => tab.id != NavigationTabId.settings).toList(); + return mainScreenBottomNavigationTabs( + visibleTabs: _getVisibleTabs(_isOffline), + isMobile: PlatformDetector.isMobile(context), + isOffline: _isOffline, + currentTab: _currentTab, + ); } /// Get the GlobalKey for a given tab. diff --git a/test/screens/startup_bind_recovery_test.dart b/test/screens/startup_bind_recovery_test.dart index 71b5d7e1..729962ec 100644 --- a/test/screens/startup_bind_recovery_test.dart +++ b/test/screens/startup_bind_recovery_test.dart @@ -1,7 +1,10 @@ import 'package:flutter_test/flutter_test.dart'; import 'package:plezy/main.dart'; +import 'package:plezy/navigation/navigation_tabs.dart'; import 'package:plezy/screens/main_screen.dart'; +List _ids(List tabs) => tabs.map((tab) => tab.id).toList(); + void main() { group('startup bind recovery', () { test('enters offline mode only when initial bind failed with no online servers', () { @@ -85,4 +88,53 @@ void main() { ); }); }); + + group('main screen bottom navigation tabs', () { + test('mobile online hides Settings when another tab is active', () { + final tabs = mainScreenBottomNavigationTabs( + visibleTabs: allNavigationTabs, + isMobile: true, + isOffline: false, + currentTab: NavigationTabId.discover, + ); + + expect(_ids(tabs), isNot(contains(NavigationTabId.settings))); + }); + + test('mobile offline includes Downloads and Settings', () { + final offlineTabs = allNavigationTabs + .where((tab) => tab.id == NavigationTabId.downloads || tab.id == NavigationTabId.settings) + .toList(); + final tabs = mainScreenBottomNavigationTabs( + visibleTabs: offlineTabs, + isMobile: true, + isOffline: true, + currentTab: NavigationTabId.downloads, + ); + + expect(_ids(tabs), [NavigationTabId.downloads, NavigationTabId.settings]); + }); + + test('mobile online keeps Settings visible when it is selected', () { + final tabs = mainScreenBottomNavigationTabs( + visibleTabs: allNavigationTabs, + isMobile: true, + isOffline: false, + currentTab: NavigationTabId.settings, + ); + + expect(_ids(tabs), contains(NavigationTabId.settings)); + }); + + test('non-mobile returns all visible tabs unchanged', () { + final tabs = mainScreenBottomNavigationTabs( + visibleTabs: allNavigationTabs, + isMobile: false, + isOffline: false, + currentTab: NavigationTabId.discover, + ); + + expect(tabs, same(allNavigationTabs)); + }); + }); }