diff --git a/lib/app_state.dart b/lib/app_state.dart index a593c18..c59cebb 100644 --- a/lib/app_state.dart +++ b/lib/app_state.dart @@ -156,6 +156,7 @@ class AppState extends ChangeNotifier { int get maxNodes => _settingsState.maxNodes; UploadMode get uploadMode => _settingsState.uploadMode; FollowMeMode get followMeMode => _settingsState.followMeMode; + bool get keepScreenAwake => _settingsState.keepScreenAwake; bool get proximityAlertsEnabled => _settingsState.proximityAlertsEnabled; int get proximityAlertDistance => _settingsState.proximityAlertDistance; @@ -172,7 +173,6 @@ class AppState extends ChangeNotifier { TileType? get selectedTileType => _settingsState.selectedTileType; TileProvider? get selectedTileProvider => _settingsState.selectedTileProvider; - // Upload queue state int get pendingCount => _uploadQueueState.pendingCount; @@ -678,6 +678,10 @@ class AppState extends ChangeNotifier { } } + Future setKeepScreenAwake(bool enabled) async { + await _settingsState.setKeepScreenAwake(enabled); + } + Future setPauseQueueProcessing(bool enabled) async { await _settingsState.setPauseQueueProcessing(enabled); if (!enabled) { diff --git a/lib/localizations/de.json b/lib/localizations/de.json index 9b56d6e..580496d 100644 --- a/lib/localizations/de.json +++ b/lib/localizations/de.json @@ -74,8 +74,13 @@ "advancedSettings": "Erweiterte Einstellungen", "advancedSettingsSubtitle": "Leistungs-, Warnungs- und Kachelanbieter-Einstellungen", "proximityAlerts": "Näherungswarnungen", + "keepScreenAwake": "Bildschirm Aktiv Lassen", "networkStatusIndicator": "Netzwerkstatus-Anzeige" }, + "keepScreenAwake": { + "title": "Bildschirm während der App-Nutzung aktiv lassen", + "subtitle": "Verhindert, dass sich der Bildschirm während der Nutzung der App automatisch ausschaltet" + }, "proximityAlerts": { "getNotified": "Benachrichtigung erhalten beim Annähern an Überwachungsgeräte", "batteryUsage": "Verbraucht zusätzlich Batterie für kontinuierliche Standortüberwachung", diff --git a/lib/localizations/en.json b/lib/localizations/en.json index b8d9ce6..423a52c 100644 --- a/lib/localizations/en.json +++ b/lib/localizations/en.json @@ -111,7 +111,12 @@ "advancedSettings": "Advanced Settings", "advancedSettingsSubtitle": "Performance, alerts, and tile provider settings", "proximityAlerts": "Proximity Alerts", - "networkStatusIndicator": "Network Status Indicator" + "networkStatusIndicator": "Network Status Indicator", + "keepScreenAwake": "Keep Screen Awake" + }, + "keepScreenAwake": { + "title": "Keep screen awake while using app", + "subtitle": "Prevents the screen from turning off automatically while using the app" }, "proximityAlerts": { "getNotified": "Get notified when approaching surveillance devices", diff --git a/lib/localizations/es.json b/lib/localizations/es.json index 8d8a95f..eb8e035 100644 --- a/lib/localizations/es.json +++ b/lib/localizations/es.json @@ -111,8 +111,13 @@ "advancedSettings": "Configuración Avanzada", "advancedSettingsSubtitle": "Configuración de rendimiento, alertas y proveedores de teselas", "proximityAlerts": "Alertas de Proximidad", + "keepScreenAwake": "Mantener la Pantalla Encendida", "networkStatusIndicator": "Indicador de Estado de Red" }, + "keepScreenAwake": { + "title": "Mantener la pantalla encendida mientras se usa la app", + "subtitle": "Evita que la pantalla se apague automáticamente mientras se usa la app" + }, "proximityAlerts": { "getNotified": "Recibe notificaciones al acercarte a dispositivos de vigilancia", "batteryUsage": "Usa batería extra para monitoreo continuo de ubicación", diff --git a/lib/localizations/fr.json b/lib/localizations/fr.json index df0c186..c68f1f4 100644 --- a/lib/localizations/fr.json +++ b/lib/localizations/fr.json @@ -111,8 +111,13 @@ "advancedSettings": "Paramètres Avancés", "advancedSettingsSubtitle": "Paramètres de performance, alertes et fournisseurs de tuiles", "proximityAlerts": "Alertes de Proximité", + "keepScreenAwake": "Maintenir l'écran Allumé", "networkStatusIndicator": "Indicateur de Statut Réseau" }, + "keepScreenAwake": { + "title": "Maintenir l'écran allumé lors de l'utilisation de l'application", + "subtitle": "Empêche l'écran de s'éteindre automatiquement pendant l'utilisation de l'application" + }, "proximityAlerts": { "getNotified": "Recevoir des notifications en s'approchant de dispositifs de surveillance", "batteryUsage": "Utilise de la batterie supplémentaire pour la surveillance continue de la localisation", diff --git a/lib/localizations/it.json b/lib/localizations/it.json index ee8c6d6..51888bf 100644 --- a/lib/localizations/it.json +++ b/lib/localizations/it.json @@ -111,8 +111,13 @@ "advancedSettings": "Impostazioni Avanzate", "advancedSettingsSubtitle": "Impostazioni di prestazioni, avvisi e fornitori di tessere", "proximityAlerts": "Avvisi di Prossimità", + "keepScreenAwake": "Mantieni lo Schermo Attivo", "networkStatusIndicator": "Indicatore di Stato di Rete" }, + "keepScreenAwake": { + "title": "Mantieni lo schermo attivo durante l'utilizzo dell'app", + "subtitle": "Impedisce allo schermo di spegnersi automaticamente durante l'utilizzo dell'app" + }, "proximityAlerts": { "getNotified": "Ricevi notifiche quando ti avvicini a dispositivi di sorveglianza", "batteryUsage": "Utilizza batteria extra per il monitoraggio continuo della posizione", diff --git a/lib/localizations/nl.json b/lib/localizations/nl.json index 1212c3a..54f88e5 100644 --- a/lib/localizations/nl.json +++ b/lib/localizations/nl.json @@ -111,8 +111,13 @@ "advancedSettings": "Geavanceerde Instellingen", "advancedSettingsSubtitle": "Prestaties, waarschuwingen en tile provider instellingen", "proximityAlerts": "Nabijheids Waarschuwingen", + "keepScreenAwake": "Scherm Actief Houden", "networkStatusIndicator": "Netwerk Status Indicator" }, + "keepScreenAwake": { + "title": "Houd het scherm actief tijdens het gebruik van de app", + "subtitle": "Voorkomt dat het scherm automatisch uitschakelt tijdens het gebruik van de app" + }, "proximityAlerts": { "getNotified": "Krijg meldingen wanneer u surveillance apparaten nadert", "batteryUsage": "Gebruikt extra batterij voor continue locatie monitoring", diff --git a/lib/localizations/pl.json b/lib/localizations/pl.json index 9b4c0c6..1c62056 100644 --- a/lib/localizations/pl.json +++ b/lib/localizations/pl.json @@ -111,8 +111,13 @@ "advancedSettings": "Ustawienia Zaawansowane", "advancedSettingsSubtitle": "Wydajność, alerty i ustawienia dostawców kafelków", "proximityAlerts": "Alerty Bliskości", + "keepScreenAwake": "Nie Wygaszaj Ekranu", "networkStatusIndicator": "Wskaźnik Stanu Sieci" }, + "keepScreenAwake": { + "title": "Nie wygaszaj ekranu podczas korzystania z aplikacji", + "subtitle": "Zapobiega automatycznemu wygaszaniu ekranu podczas korzystania z aplikacji" + }, "proximityAlerts": { "getNotified": "Otrzymuj powiadomienia przy zbliżaniu się do urządzeń nadzoru", "batteryUsage": "Używa dodatkowej baterii do ciągłego monitorowania lokalizacji", diff --git a/lib/localizations/pt.json b/lib/localizations/pt.json index b146c23..9f83132 100644 --- a/lib/localizations/pt.json +++ b/lib/localizations/pt.json @@ -111,8 +111,13 @@ "advancedSettings": "Configurações Avançadas", "advancedSettingsSubtitle": "Configurações de desempenho, alertas e provedores de mapas", "proximityAlerts": "Alertas de Proximidade", + "keepScreenAwake": "Manter Ecrã Ativa", "networkStatusIndicator": "Indicador de Status de Rede" }, + "keepScreenAwake": { + "title": "Manter o ecrã ativo durante o uso do app", + "subtitle": "Impede que o ecrã se desligue automaticamente enquanto a app estiver em uso" + }, "proximityAlerts": { "getNotified": "Receba notificações ao se aproximar de dispositivos de vigilância", "batteryUsage": "Usa bateria extra para monitoramento contínuo de localização", diff --git a/lib/localizations/tr.json b/lib/localizations/tr.json index 09a9e70..74a1d52 100644 --- a/lib/localizations/tr.json +++ b/lib/localizations/tr.json @@ -111,8 +111,13 @@ "advancedSettings": "Gelişmiş Ayarlar", "advancedSettingsSubtitle": "Performans, uyarılar ve döşeme sağlayıcı ayarları", "proximityAlerts": "Yakınlık Uyarıları", + "keepScreenAwake": "Ekranı Açık Tut", "networkStatusIndicator": "Ağ Durumu Göstergesi" }, + "keepScreenAwake": { + "title": "Uygulamayı kullanırken ekranı açık tut", + "subtitle": "Uygulamayı kullanırken ekranın otomatik olarak kapanmasını engeller" + }, "proximityAlerts": { "getNotified": "Gözetleme cihazlarına yaklaşırken bildirim al", "batteryUsage": "Sürekli konum izleme için ekstra batarya kullanır", diff --git a/lib/localizations/uk.json b/lib/localizations/uk.json index 68aacbb..c588cd5 100644 --- a/lib/localizations/uk.json +++ b/lib/localizations/uk.json @@ -111,8 +111,13 @@ "advancedSettings": "Розширені Налаштування", "advancedSettingsSubtitle": "Продуктивність, сповіщення та налаштування постачальників плиток", "proximityAlerts": "Сповіщення Про Близькість", + "keepScreenAwake": "Тримати екран активним", "networkStatusIndicator": "Індикатор Стану Мережі" }, + "keepScreenAwake": { + "title": "Тримати екран активним під час використання програми", + "subtitle": "Запобігає автоматичному вимкненню екрана під час використання програми" + }, "proximityAlerts": { "getNotified": "Отримувати сповіщення при наближенні до пристроїв спостереження", "batteryUsage": "Використовує додаткову батарею для безперервного моніторингу місцезнаходження", diff --git a/lib/localizations/zh.json b/lib/localizations/zh.json index 045af80..d73750d 100644 --- a/lib/localizations/zh.json +++ b/lib/localizations/zh.json @@ -111,8 +111,13 @@ "advancedSettings": "高级设置", "advancedSettingsSubtitle": "性能、警报和地图提供商设置", "proximityAlerts": "邻近警报", + "keepScreenAwake": "保持屏幕常亮", "networkStatusIndicator": "网络状态指示器" }, + "keepScreenAwake": { + "title": "使用应用时保持屏幕常亮", + "subtitle": "防止在使用应用期间屏幕自动熄灭" + }, "proximityAlerts": { "getNotified": "接近监控设备时接收通知", "batteryUsage": "使用额外电量进行连续位置监控", diff --git a/lib/screens/advanced_settings_screen.dart b/lib/screens/advanced_settings_screen.dart index b5630a4..275f11a 100644 --- a/lib/screens/advanced_settings_screen.dart +++ b/lib/screens/advanced_settings_screen.dart @@ -3,6 +3,7 @@ import 'settings/sections/max_nodes_section.dart'; import 'settings/sections/proximity_alerts_section.dart'; import 'settings/sections/suspected_locations_section.dart'; import 'settings/sections/tile_provider_section.dart'; +import 'settings/sections/keep_screen_awake_section.dart'; import '../services/localization_service.dart'; class AdvancedSettingsScreen extends StatelessWidget { @@ -32,6 +33,8 @@ class AdvancedSettingsScreen extends StatelessWidget { Divider(), SuspectedLocationsSection(), Divider(), + KeepScreenAwakeSection(), + Divider(), // NetworkStatusSection(), // Commented out - network status indicator now defaults to enabled // Divider(), TileProviderSection(), diff --git a/lib/screens/settings/sections/keep_screen_awake_section.dart b/lib/screens/settings/sections/keep_screen_awake_section.dart new file mode 100644 index 0000000..9eec268 --- /dev/null +++ b/lib/screens/settings/sections/keep_screen_awake_section.dart @@ -0,0 +1,46 @@ +import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; +import '../../../app_state.dart'; +import '../../../services/localization_service.dart'; + +class KeepScreenAwakeSection extends StatelessWidget { + const KeepScreenAwakeSection({super.key}); + + @override + Widget build(BuildContext context) { + // Standard Pattern: Use AnimatedBuilder to respond to language/localization changes + return AnimatedBuilder( + animation: LocalizationService.instance, + builder: (context, child) { + final locService = LocalizationService.instance; + final appState = context.watch(); + + return Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + // Bold Section Header (matches Max Nodes, Proximity, etc.) + Text( + locService.t('settings.keepScreenAwake'), + style: Theme.of(context).textTheme.titleMedium, + ), + const SizedBox(height: 8), + + // The Functional Toggle + SwitchListTile( + contentPadding: EdgeInsets.zero, // Aligns switch text with the bold header + title: Text(locService.t('keepScreenAwake.title')), + subtitle: Text( + locService.t('keepScreenAwake.subtitle'), + style: const TextStyle(fontSize: 12), + ), + value: appState.keepScreenAwake, + onChanged: (bool value) { + appState.setKeepScreenAwake(value); + }, + ), + ], + ); + }, + ); + } +} \ No newline at end of file diff --git a/lib/state/settings_state.dart b/lib/state/settings_state.dart index e884086..9fa1268 100644 --- a/lib/state/settings_state.dart +++ b/lib/state/settings_state.dart @@ -39,9 +39,11 @@ class SettingsState extends ChangeNotifier { static const String _pauseQueueProcessingPrefsKey = 'pause_queue_processing'; static const String _navigationAvoidanceDistancePrefsKey = 'navigation_avoidance_distance'; static const String _distanceUnitPrefsKey = 'distance_unit'; + static const String _keepScreenAwakePrefsKey = 'keep_screen_awake'; bool _offlineMode = false; bool _pauseQueueProcessing = false; + bool _keepScreenAwake = false; int _maxNodes = kDefaultMaxNodes; // Default must account for missing secrets (preview builds) even before init() runs UploadMode _uploadMode = (kEnableDevelopmentModes || !kHasOsmSecrets) ? UploadMode.simulate : UploadMode.production; @@ -65,6 +67,7 @@ class SettingsState extends ChangeNotifier { int get proximityAlertDistance => _proximityAlertDistance; bool get networkStatusIndicatorEnabled => _networkStatusIndicatorEnabled; int get suspectedLocationMinDistance => _suspectedLocationMinDistance; + bool get keepScreenAwake => _keepScreenAwake; List get tileProviders => List.unmodifiable(_tileProviders); String get selectedTileTypeId => _selectedTileTypeId; int get navigationAvoidanceDistance => _navigationAvoidanceDistance; @@ -138,6 +141,9 @@ class SettingsState extends ChangeNotifier { // Load suspected location minimum distance _suspectedLocationMinDistance = prefs.getInt(_suspectedLocationMinDistancePrefsKey) ?? 100; + + // Load keep screen awake setting + _keepScreenAwake = prefs.getBool(_keepScreenAwakePrefsKey) ?? false; // Load upload mode (including migration from old test_mode bool) if (prefs.containsKey(_uploadModePrefsKey)) { @@ -397,7 +403,17 @@ class SettingsState extends ChangeNotifier { } } - // Set distance for avoidance of nodes during navigation + /// Set keep screen awake enabled/disabled + Future setKeepScreenAwake(bool enabled) async { + if (_keepScreenAwake != enabled) { + _keepScreenAwake = enabled; + final prefs = await SharedPreferences.getInstance(); + await prefs.setBool(_keepScreenAwakePrefsKey, enabled); + notifyListeners(); + } + } + + /// Set distance for avoidance of nodes during navigation Future setNavigationAvoidanceDistance(int distance) async { if (_navigationAvoidanceDistance != distance) { _navigationAvoidanceDistance = distance; diff --git a/lib/widgets/map_view.dart b/lib/widgets/map_view.dart index 1c817a4..2f2e015 100644 --- a/lib/widgets/map_view.dart +++ b/lib/widgets/map_view.dart @@ -3,6 +3,7 @@ import 'package:flutter_map/flutter_map.dart'; import 'package:flutter_map_animations/flutter_map_animations.dart'; import 'package:latlong2/latlong.dart'; import 'package:provider/provider.dart'; +import 'package:wakelock_plus/wakelock_plus.dart'; import '../app_state.dart' show AppState, FollowMeMode; import '../services/offline_area_service.dart'; @@ -84,7 +85,20 @@ class MapViewState extends State { // Track active pointers to suppress follow-me animations during touch int _activePointers = 0; + bool _isWakelockEnabled = false; + void _updateWakelock(bool shouldBeAwake) { + if (_isWakelockEnabled != shouldBeAwake) { + _isWakelockEnabled = shouldBeAwake; + WidgetsBinding.instance.addPostFrameCallback((_) { + if (shouldBeAwake) { + WakelockPlus.enable(); + } else { + WakelockPlus.disable(); + } + }); + } + } @override void initState() { @@ -213,6 +227,7 @@ class MapViewState extends State { _nodeController.dispose(); _tileManager.dispose(); _gpsController.dispose(); + WakelockPlus.disable(); // PrefetchAreaService no longer used - replaced with NodeDataManager super.dispose(); } @@ -278,6 +293,9 @@ class MapViewState extends State { final session = appState.session; final editSession = appState.editSession; + // Keep screen awake based on user setting + _updateWakelock(appState.keepScreenAwake); + // Check if enabled profiles changed and refresh nodes if needed _nodeController.checkAndHandleProfileChanges( currentEnabledProfiles: appState.enabledProfiles, diff --git a/pubspec.yaml b/pubspec.yaml index ac3484d..cd7d423 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -38,6 +38,7 @@ dependencies: package_info_plus: ^9.0.0 csv: ^6.0.0 collection: ^1.18.0 + wakelock_plus: ^1.5.2 dev_dependencies: flutter_test: