feat: Add setting to disable map tab for battery savings

Add a new "Disable Map" toggle in settings that allows users to hide
the map tab entirely. This is useful for scenarios where the map is
not needed and battery conservation is a priority.

Changes:
- Add disableMap and disableMapDescription localized strings (all languages)
- Add isMapEnabled state to AppProvider with persistence
- Update HomeScreen to dynamically adjust tab count based on setting
- Make onNavigateToMap optional in MessagesTab and ContactsTab
- Add toggle switch in Settings screen under Interface section
This commit is contained in:
Janez Troha
2025-12-04 18:33:00 +01:00
parent 53aa8e57e2
commit 3e2e4aa4d9
19 changed files with 258 additions and 30 deletions

View File

@@ -47,20 +47,12 @@ class _HomeScreenState extends State<HomeScreen>
int _currentIndex = 0;
bool _isMapFullscreen = false;
bool _showRxTxIndicators = true;
bool _isMapEnabled = true;
@override
void initState() {
super.initState();
_tabController = TabController(length: 3, vsync: this);
_tabController.addListener(() {
setState(() {
_currentIndex = _tabController.index;
// Exit fullscreen when switching away from map tab
if (_currentIndex != 2) {
_isMapFullscreen = false;
}
});
});
_loadMapEnabledAndInitTabs();
_loadRxTxPreference();
// Show permission dialog after the first frame if needed
@@ -71,6 +63,63 @@ class _HomeScreenState extends State<HomeScreen>
}
}
Future<void> _loadMapEnabledAndInitTabs() async {
final prefs = await SharedPreferences.getInstance();
final mapEnabled = prefs.getBool('map_enabled') ?? true;
if (mapEnabled != _isMapEnabled) {
_isMapEnabled = mapEnabled;
}
_initTabController();
if (mounted) {
setState(() {});
}
}
void _initTabController() {
final tabCount = _isMapEnabled ? 3 : 2;
_tabController = TabController(length: tabCount, vsync: this);
_tabController.addListener(_onTabChanged);
}
void _onTabChanged() {
setState(() {
_currentIndex = _tabController.index;
// Exit fullscreen when switching away from map tab (only if map is enabled and is tab 2)
if (_isMapEnabled && _currentIndex != 2) {
_isMapFullscreen = false;
}
});
}
void _updateTabController(bool mapEnabled) {
if (_isMapEnabled == mapEnabled) return;
// Save current index before rebuilding
final oldIndex = _tabController.index;
// Remove old listener and dispose
_tabController.removeListener(_onTabChanged);
_tabController.dispose();
// Update state
_isMapEnabled = mapEnabled;
// Create new controller
final tabCount = mapEnabled ? 3 : 2;
_tabController = TabController(length: tabCount, vsync: this);
_tabController.addListener(_onTabChanged);
// Restore index (clamp to valid range)
if (oldIndex < tabCount) {
_tabController.index = oldIndex;
_currentIndex = oldIndex;
} else {
_currentIndex = tabCount - 1;
}
setState(() {});
}
Future<void> _loadRxTxPreference() async {
final prefs = await SharedPreferences.getInstance();
if (mounted) {
@@ -82,6 +131,7 @@ class _HomeScreenState extends State<HomeScreen>
@override
void dispose() {
_tabController.removeListener(_onTabChanged);
_tabController.dispose();
super.dispose();
}
@@ -225,8 +275,16 @@ class _HomeScreenState extends State<HomeScreen>
messagesProvider.setLocalizations(localizations);
}
// Check if map enabled setting changed and update tab controller
final appProvider = context.watch<AppProvider>();
if (_isMapEnabled != appProvider.isMapEnabled) {
WidgetsBinding.instance.addPostFrameCallback((_) {
_updateTabController(appProvider.isMapEnabled);
});
}
// Determine if we should hide the UI (only in fullscreen on map tab)
final shouldHideUI = _isMapFullscreen && _currentIndex == 2;
final shouldHideUI = _isMapEnabled && _isMapFullscreen && _currentIndex == 2;
return Scaffold(
appBar: shouldHideUI
@@ -308,16 +366,25 @@ class _HomeScreenState extends State<HomeScreen>
body: TabBarView(
controller: _tabController,
children: [
MessagesTab(onNavigateToMap: () => _tabController.animateTo(2)),
ContactsTab(onNavigateToMap: () => _tabController.animateTo(2)),
MapTab(
onFullscreenChanged: (isFullscreen) {
setState(() {
_isMapFullscreen = isFullscreen;
});
},
onNavigateToMessages: () => _tabController.animateTo(0),
MessagesTab(
onNavigateToMap: _isMapEnabled
? () => _tabController.animateTo(2)
: null,
),
ContactsTab(
onNavigateToMap: _isMapEnabled
? () => _tabController.animateTo(2)
: null,
),
if (_isMapEnabled)
MapTab(
onFullscreenChanged: (isFullscreen) {
setState(() {
_isMapFullscreen = isFullscreen;
});
},
onNavigateToMessages: () => _tabController.animateTo(0),
),
],
),
bottomNavigationBar: shouldHideUI
@@ -354,10 +421,11 @@ class _HomeScreenState extends State<HomeScreen>
),
text: AppLocalizations.of(context)!.contacts,
),
Tab(
icon: const Icon(Icons.map),
text: AppLocalizations.of(context)!.map,
),
if (_isMapEnabled)
Tab(
icon: const Icon(Icons.map),
text: AppLocalizations.of(context)!.map,
),
],
),
);