feat(#269): keep-screen-awake setting

Adds a KeepScreenAwake controller that holds a wakelock_plus lock while the
setting is on and the app is foregrounded, releasing on background, on toggle
off, and on dispose. Toggle lives in App Settings > Battery (power tradeoff),
defaults OFF, persisted as keep_screen_awake. Strings added for all 18 locales.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
pull/419/head
Strycher 2 months ago
parent 480d6a8e27
commit 8b7f0a3d2c

@ -216,6 +216,8 @@
"appSettings_batteryNmc": "18650 NMC (3.0-4.2V)",
"appSettings_batteryLifepo4": "Литиево желязо фосфат (2.6-3.65V)",
"appSettings_batteryLipo": "Литиев полимер (3.0-4.2V)",
"appSettings_keepScreenAwake": "Поддържане на екрана включен",
"appSettings_keepScreenAwakeSubtitle": "Екранът няма да изгасва, докато приложението е отворено. Изразходва повече батерия.",
"appSettings_mapDisplay": "Карта за показване",
"appSettings_showRepeaters": "Показване на повторители",
"appSettings_showRepeatersSubtitle": "Показване на възпроизвеждащи се възли на картата",

@ -216,6 +216,8 @@
"appSettings_batteryNmc": "18650 NMC (3,0–4,2 V)",
"appSettings_batteryLifepo4": "LiFePO4 (2,6–3,65 V)",
"appSettings_batteryLipo": "LiPo (3,0–4,2V)",
"appSettings_keepScreenAwake": "Bildschirm anlassen",
"appSettings_keepScreenAwakeSubtitle": "Verhindert, dass sich das Display ausschaltet, während die App geöffnet ist. Verbraucht mehr Akku.",
"appSettings_mapDisplay": "Kartendarstellung",
"appSettings_showRepeaters": "Zeige Repeater",
"appSettings_showRepeatersSubtitle": "Zeige Repeater-Knoten auf der Karte an",

@ -350,6 +350,8 @@
"appSettings_batteryNmc": "18650 NMC (3.0-4.2V)",
"appSettings_batteryLifepo4": "LiFePO4 (2.6-3.65V)",
"appSettings_batteryLipo": "LiPo (3.0-4.2V)",
"appSettings_keepScreenAwake": "Keep screen awake",
"appSettings_keepScreenAwakeSubtitle": "Prevent the display from sleeping while the app is open. Uses more battery.",
"appSettings_mapDisplay": "Map Display",
"appSettings_showRepeaters": "Show Repeaters",
"appSettings_showRepeatersSubtitle": "Display repeater nodes on the map",

@ -216,6 +216,8 @@
"appSettings_batteryNmc": "18650 NMC (3,0-4,2 V)",
"appSettings_batteryLifepo4": "LiFePO4 (2.6-3.65 V)",
"appSettings_batteryLipo": "LiPo (3.0-4.2V)",
"appSettings_keepScreenAwake": "Mantener la pantalla encendida",
"appSettings_keepScreenAwakeSubtitle": "Evita que la pantalla se apague mientras la aplicación está abierta. Consume más batería.",
"appSettings_mapDisplay": "Visualización del Mapa",
"appSettings_showRepeaters": "Mostrar Repetidores",
"appSettings_showRepeatersSubtitle": "Mostrar nodos de repetidor en el mapa",

@ -216,6 +216,8 @@
"appSettings_batteryNmc": "18650 NMC (3,0-4,2V)",
"appSettings_batteryLifepo4": "LiFePO4 (2,6-3,65V)",
"appSettings_batteryLipo": "LiPo (3,0-4,2V)",
"appSettings_keepScreenAwake": "Garder l'écran allumé",
"appSettings_keepScreenAwakeSubtitle": "Empêche l'écran de s'éteindre lorsque l'application est ouverte. Consomme plus de batterie.",
"appSettings_mapDisplay": "Affichage de la carte",
"appSettings_showRepeaters": "Afficher les répéteurs",
"appSettings_showRepeatersSubtitle": "Afficher les nœuds répéteurs sur la carte",

@ -308,6 +308,8 @@
"appSettings_batteryNmc": "18650 NMC (3,0-4,2 V)",
"appSettings_batteryLifepo4": "LiFePO4 (2,6–3,65 V)",
"appSettings_batteryLipo": "LiPo (3,0-4,2 V)",
"appSettings_keepScreenAwake": "Képernyő ébren tartása",
"appSettings_keepScreenAwakeSubtitle": "Megakadályozza a képernyő elalvását, amíg az alkalmazás nyitva van. Több akkumulátort fogyaszt.",
"appSettings_mapDisplay": "Térkép megjelenítése",
"appSettings_showRepeaters": "Megismétlés",
"appSettings_showRepeatersSubtitle": "A térképen megjelenítsük a repeater-eket.",

@ -216,6 +216,8 @@
"appSettings_batteryNmc": "18650 NMC (3,0-4,2V)",
"appSettings_batteryLifepo4": "LiFePO4 (2,6-3,65V)",
"appSettings_batteryLipo": "LiPo (3,0-4,2V)",
"appSettings_keepScreenAwake": "Mantieni lo schermo acceso",
"appSettings_keepScreenAwakeSubtitle": "Impedisce allo schermo di spegnersi mentre l'app è aperta. Consuma più batteria.",
"appSettings_mapDisplay": "Visualizzazione Mappa",
"appSettings_showRepeaters": "Mostra Ripetitori",
"appSettings_showRepeatersSubtitle": "Mostra i nodi ripetitori sulla mappa",

@ -308,6 +308,8 @@
"appSettings_batteryNmc": "18650型 NMC (3.0-4.2V)",
"appSettings_batteryLifepo4": "LiFePO4 (2.6-3.65V)",
"appSettings_batteryLipo": "LiPo (3.0-4.2V)",
"appSettings_keepScreenAwake": "画面をスリープさせない",
"appSettings_keepScreenAwakeSubtitle": "アプリを開いている間、画面が消灯しないようにします。バッテリーの消費が増えます。",
"appSettings_mapDisplay": "地図の表示",
"appSettings_showRepeaters": "繰り返し再生機能",
"appSettings_showRepeatersSubtitle": "地図上にリピーターノードを表示する",

@ -308,6 +308,8 @@
"appSettings_batteryNmc": "18650 NMC (3.0-4.2V)",
"appSettings_batteryLifepo4": "LiFePO4 (2.6-3.65V)",
"appSettings_batteryLipo": "리튬 폴리머 (3.0-4.2V)",
"appSettings_keepScreenAwake": "화면 켜짐 유지",
"appSettings_keepScreenAwakeSubtitle": "앱이 열려 있는 동안 화면이 꺼지지 않도록 합니다. 배터리를 더 소모합니다.",
"appSettings_mapDisplay": "지도 표시",
"appSettings_showRepeaters": "반복 기능 표시",
"appSettings_showRepeatersSubtitle": "지도에 반복자 노드를 표시",

@ -1714,6 +1714,18 @@ abstract class AppLocalizations {
/// **'LiPo (3.0-4.2V)'**
String get appSettings_batteryLipo;
/// No description provided for @appSettings_keepScreenAwake.
///
/// In en, this message translates to:
/// **'Keep screen awake'**
String get appSettings_keepScreenAwake;
/// No description provided for @appSettings_keepScreenAwakeSubtitle.
///
/// In en, this message translates to:
/// **'Prevent the display from sleeping while the app is open. Uses more battery.'**
String get appSettings_keepScreenAwakeSubtitle;
/// No description provided for @appSettings_mapDisplay.
///
/// In en, this message translates to:

@ -895,6 +895,13 @@ class AppLocalizationsBg extends AppLocalizations {
@override
String get appSettings_batteryLipo => 'Литиев полимер (3.0-4.2V)';
@override
String get appSettings_keepScreenAwake => 'Поддържане на екрана включен';
@override
String get appSettings_keepScreenAwakeSubtitle =>
'Екранът няма да изгасва, докато приложението е отворено. Изразходва повече батерия.';
@override
String get appSettings_mapDisplay => 'Карта за показване';

@ -891,6 +891,13 @@ class AppLocalizationsDe extends AppLocalizations {
@override
String get appSettings_batteryLipo => 'LiPo (3,0–4,2V)';
@override
String get appSettings_keepScreenAwake => 'Bildschirm anlassen';
@override
String get appSettings_keepScreenAwakeSubtitle =>
'Verhindert, dass sich das Display ausschaltet, während die App geöffnet ist. Verbraucht mehr Akku.';
@override
String get appSettings_mapDisplay => 'Kartendarstellung';

@ -876,6 +876,13 @@ class AppLocalizationsEn extends AppLocalizations {
@override
String get appSettings_batteryLipo => 'LiPo (3.0-4.2V)';
@override
String get appSettings_keepScreenAwake => 'Keep screen awake';
@override
String get appSettings_keepScreenAwakeSubtitle =>
'Prevent the display from sleeping while the app is open. Uses more battery.';
@override
String get appSettings_mapDisplay => 'Map Display';

@ -890,6 +890,13 @@ class AppLocalizationsEs extends AppLocalizations {
@override
String get appSettings_batteryLipo => 'LiPo (3.0-4.2V)';
@override
String get appSettings_keepScreenAwake => 'Mantener la pantalla encendida';
@override
String get appSettings_keepScreenAwakeSubtitle =>
'Evita que la pantalla se apague mientras la aplicación está abierta. Consume más batería.';
@override
String get appSettings_mapDisplay => 'Visualización del Mapa';

@ -896,6 +896,13 @@ class AppLocalizationsFr extends AppLocalizations {
@override
String get appSettings_batteryLipo => 'LiPo (3,0-4,2V)';
@override
String get appSettings_keepScreenAwake => 'Garder l\'écran allumé';
@override
String get appSettings_keepScreenAwakeSubtitle =>
'Empêche l\'écran de s\'éteindre lorsque l\'application est ouverte. Consomme plus de batterie.';
@override
String get appSettings_mapDisplay => 'Affichage de la carte';

@ -894,6 +894,13 @@ class AppLocalizationsHu extends AppLocalizations {
@override
String get appSettings_batteryLipo => 'LiPo (3,0-4,2 V)';
@override
String get appSettings_keepScreenAwake => 'Képernyő ébren tartása';
@override
String get appSettings_keepScreenAwakeSubtitle =>
'Megakadályozza a képernyő elalvását, amíg az alkalmazás nyitva van. Több akkumulátort fogyaszt.';
@override
String get appSettings_mapDisplay => 'Térkép megjelenítése';

@ -893,6 +893,13 @@ class AppLocalizationsIt extends AppLocalizations {
@override
String get appSettings_batteryLipo => 'LiPo (3,0-4,2V)';
@override
String get appSettings_keepScreenAwake => 'Mantieni lo schermo acceso';
@override
String get appSettings_keepScreenAwakeSubtitle =>
'Impedisce allo schermo di spegnersi mentre l\'app è aperta. Consuma più batteria.';
@override
String get appSettings_mapDisplay => 'Visualizzazione Mappa';

@ -849,6 +849,13 @@ class AppLocalizationsJa extends AppLocalizations {
@override
String get appSettings_batteryLipo => 'LiPo (3.0-4.2V)';
@override
String get appSettings_keepScreenAwake => '画面をスリープさせない';
@override
String get appSettings_keepScreenAwakeSubtitle =>
'アプリを開いている間、画面が消灯しないようにします。バッテリーの消費が増えます。';
@override
String get appSettings_mapDisplay => '地図の表示';

@ -847,6 +847,13 @@ class AppLocalizationsKo extends AppLocalizations {
@override
String get appSettings_batteryLipo => '리튬 폴리머 (3.0-4.2V)';
@override
String get appSettings_keepScreenAwake => '화면 켜짐 유지';
@override
String get appSettings_keepScreenAwakeSubtitle =>
'앱이 열려 있는 동안 화면이 꺼지지 않도록 합니다. 배터리를 더 소모합니다.';
@override
String get appSettings_mapDisplay => '지도 표시';

@ -885,6 +885,13 @@ class AppLocalizationsNl extends AppLocalizations {
@override
String get appSettings_batteryLipo => 'LiPo (3,0-4,2V)';
@override
String get appSettings_keepScreenAwake => 'Scherm aan houden';
@override
String get appSettings_keepScreenAwakeSubtitle =>
'Voorkomt dat het scherm in slaapstand gaat terwijl de app open is. Verbruikt meer batterij.';
@override
String get appSettings_mapDisplay => 'Kaartweergave';

@ -895,6 +895,13 @@ class AppLocalizationsPl extends AppLocalizations {
@override
String get appSettings_batteryLipo => 'LiPo (3,0-4,2V)';
@override
String get appSettings_keepScreenAwake => 'Nie wygaszaj ekranu';
@override
String get appSettings_keepScreenAwakeSubtitle =>
'Zapobiega wygaszaniu ekranu, gdy aplikacja jest otwarta. Zużywa więcej baterii.';
@override
String get appSettings_mapDisplay => 'Wyświetlanie mapy';

@ -892,6 +892,13 @@ class AppLocalizationsPt extends AppLocalizations {
@override
String get appSettings_batteryLipo => 'LiPo (3,0-4,2V)';
@override
String get appSettings_keepScreenAwake => 'Manter a tela ligada';
@override
String get appSettings_keepScreenAwakeSubtitle =>
'Impede que a tela desligue enquanto o app está aberto. Consome mais bateria.';
@override
String get appSettings_mapDisplay => 'Exibição do Mapa';

@ -894,6 +894,13 @@ class AppLocalizationsRu extends AppLocalizations {
@override
String get appSettings_batteryLipo => 'LiPo (3.0–4.2 В)';
@override
String get appSettings_keepScreenAwake => 'Не выключать экран';
@override
String get appSettings_keepScreenAwakeSubtitle =>
'Экран не будет гаснуть, пока приложение открыто. Расходует больше заряда.';
@override
String get appSettings_mapDisplay => 'Отображение карты';

@ -881,6 +881,13 @@ class AppLocalizationsSk extends AppLocalizations {
@override
String get appSettings_batteryLipo => 'LiPo (3,0-4,2V)';
@override
String get appSettings_keepScreenAwake => 'Nechať obrazovku zapnutú';
@override
String get appSettings_keepScreenAwakeSubtitle =>
'Zabráni vypnutiu obrazovky, kým je aplikácia otvorená. Spotrebuje viac batérie.';
@override
String get appSettings_mapDisplay => 'Zobrazenie mapy';

@ -882,6 +882,13 @@ class AppLocalizationsSl extends AppLocalizations {
@override
String get appSettings_batteryLipo => 'LiPo (3,0-4,2V)';
@override
String get appSettings_keepScreenAwake => 'Ohrani zaslon prižgan';
@override
String get appSettings_keepScreenAwakeSubtitle =>
'Prepreči, da bi zaslon ugasnil, medtem ko je aplikacija odprta. Porabi več baterije.';
@override
String get appSettings_mapDisplay => 'Prikaz zemljevida';

@ -876,6 +876,13 @@ class AppLocalizationsSv extends AppLocalizations {
@override
String get appSettings_batteryLipo => 'LiPo (3,0-4,2V)';
@override
String get appSettings_keepScreenAwake => 'Håll skärmen tänd';
@override
String get appSettings_keepScreenAwakeSubtitle =>
'Hindrar skärmen från att slockna medan appen är öppen. Drar mer batteri.';
@override
String get appSettings_mapDisplay => 'Kartvisning';

@ -888,6 +888,13 @@ class AppLocalizationsUk extends AppLocalizations {
@override
String get appSettings_batteryLipo => 'LiPo (3.0-4.2В)';
@override
String get appSettings_keepScreenAwake => 'Не вимикати екран';
@override
String get appSettings_keepScreenAwakeSubtitle =>
'Екран не гаснутиме, доки застосунок відкрито. Витрачає більше заряду.';
@override
String get appSettings_mapDisplay => 'Відображення карти';

@ -833,6 +833,12 @@ class AppLocalizationsZh extends AppLocalizations {
@override
String get appSettings_batteryLipo => '锂聚合物电池 (3.0-4.2V)';
@override
String get appSettings_keepScreenAwake => '保持屏幕常亮';
@override
String get appSettings_keepScreenAwakeSubtitle => '应用打开时防止屏幕休眠。会更耗电。';
@override
String get appSettings_mapDisplay => '地图显示';

@ -216,6 +216,8 @@
"appSettings_batteryNmc": "18650 NMC (3,0-4,2V)",
"appSettings_batteryLifepo4": "LiFePO4 (2,6-3,65V)",
"appSettings_batteryLipo": "LiPo (3,0-4,2V)",
"appSettings_keepScreenAwake": "Scherm aan houden",
"appSettings_keepScreenAwakeSubtitle": "Voorkomt dat het scherm in slaapstand gaat terwijl de app open is. Verbruikt meer batterij.",
"appSettings_mapDisplay": "Kaartweergave",
"appSettings_showRepeaters": "Toon Repeaters",
"appSettings_showRepeatersSubtitle": "Toon repeaternodes op de kaart",

@ -216,6 +216,8 @@
"appSettings_batteryNmc": "18650 NMC (3,0-4,2V)",
"appSettings_batteryLifepo4": "LiFePO4 (2,6-3,65 V)",
"appSettings_batteryLipo": "LiPo (3,0-4,2V)",
"appSettings_keepScreenAwake": "Nie wygaszaj ekranu",
"appSettings_keepScreenAwakeSubtitle": "Zapobiega wygaszaniu ekranu, gdy aplikacja jest otwarta. Zużywa więcej baterii.",
"appSettings_mapDisplay": "Wyświetlanie mapy",
"appSettings_showRepeaters": "Pokaż przekaźniki",
"appSettings_showRepeatersSubtitle": "Wyświetl węzły przekaźników na mapie",

@ -216,6 +216,8 @@
"appSettings_batteryNmc": "18650 NMC (3,0-4,2V)",
"appSettings_batteryLifepo4": "LiFePO4 (2,6-3,65V)",
"appSettings_batteryLipo": "LiPo (3,0-4,2V)",
"appSettings_keepScreenAwake": "Manter a tela ligada",
"appSettings_keepScreenAwakeSubtitle": "Impede que a tela desligue enquanto o app está aberto. Consome mais bateria.",
"appSettings_mapDisplay": "Exibição do Mapa",
"appSettings_showRepeaters": "Mostrar Repetidores",
"appSettings_showRepeatersSubtitle": "Exibir nós de repetidor no mapa",

@ -173,6 +173,8 @@
"appSettings_batteryNmc": "18650 NMC (3.0–4.2 В)",
"appSettings_batteryLifepo4": "LiFePO4 (2.6–3.65 В)",
"appSettings_batteryLipo": "LiPo (3.0–4.2 В)",
"appSettings_keepScreenAwake": "Не выключать экран",
"appSettings_keepScreenAwakeSubtitle": "Экран не будет гаснуть, пока приложение открыто. Расходует больше заряда.",
"appSettings_mapDisplay": "Отображение карты",
"appSettings_showRepeaters": "Показывать репитеры",
"appSettings_showRepeatersSubtitle": "Отображать репитеры на карте",

@ -216,6 +216,8 @@
"appSettings_batteryNmc": "18650 NMC (3,0-4,2V)",
"appSettings_batteryLifepo4": "LiFePO4 (2,6–3,65V)",
"appSettings_batteryLipo": "LiPo (3,0-4,2V)",
"appSettings_keepScreenAwake": "Nechať obrazovku zapnutú",
"appSettings_keepScreenAwakeSubtitle": "Zabráni vypnutiu obrazovky, kým je aplikácia otvorená. Spotrebuje viac batérie.",
"appSettings_mapDisplay": "Zobrazenie mapy",
"appSettings_showRepeaters": "Zobraziť opakovače",
"appSettings_showRepeatersSubtitle": "Zobraziť opakujúce sa uzly na mape",

@ -216,6 +216,8 @@
"appSettings_batteryNmc": "18650 NMC (3,0-4,2V)",
"appSettings_batteryLifepo4": "LiFePO4 (2,6–3,65 V)",
"appSettings_batteryLipo": "LiPo (3,0-4,2V)",
"appSettings_keepScreenAwake": "Ohrani zaslon prižgan",
"appSettings_keepScreenAwakeSubtitle": "Prepreči, da bi zaslon ugasnil, medtem ko je aplikacija odprta. Porabi več baterije.",
"appSettings_mapDisplay": "Prikaz zemljevida",
"appSettings_showRepeaters": "Prikaži repetitorje",
"appSettings_showRepeatersSubtitle": "Prikaži repetitorje na mapi",

@ -216,6 +216,8 @@
"appSettings_batteryNmc": "18650 NMC (3,0-4,2V)",
"appSettings_batteryLifepo4": "LiFePO4 (2,6–3,65V)",
"appSettings_batteryLipo": "LiPo (3,0-4,2V)",
"appSettings_keepScreenAwake": "Håll skärmen tänd",
"appSettings_keepScreenAwakeSubtitle": "Hindrar skärmen från att slockna medan appen är öppen. Drar mer batteri.",
"appSettings_mapDisplay": "Kartvisning",
"appSettings_showRepeaters": "Visa återuppslag",
"appSettings_showRepeatersSubtitle": "Visa återspelsnoder på kartan",

@ -218,6 +218,8 @@
"appSettings_batteryNmc": "18650 NMC (3.0-4.2В)",
"appSettings_batteryLifepo4": "LiFePO4 (2.6-3.65В)",
"appSettings_batteryLipo": "LiPo (3.0-4.2В)",
"appSettings_keepScreenAwake": "Не вимикати екран",
"appSettings_keepScreenAwakeSubtitle": "Екран не гаснутиме, доки застосунок відкрито. Витрачає більше заряду.",
"appSettings_mapDisplay": "Відображення карти",
"appSettings_showRepeaters": "Показувати ретранслятори",
"appSettings_showRepeatersSubtitle": "Відображати вузли-ретранслятори на карті",

@ -230,6 +230,8 @@
"appSettings_batteryNmc": "18650 NMC 电池 (3.0-4.2V)",
"appSettings_batteryLifepo4": "磷酸铁锂 (2.6-3.65V)",
"appSettings_batteryLipo": "锂聚合物电池 (3.0-4.2V)",
"appSettings_keepScreenAwake": "保持屏幕常亮",
"appSettings_keepScreenAwakeSubtitle": "应用打开时防止屏幕休眠。会更耗电。",
"appSettings_mapDisplay": "地图显示",
"appSettings_showRepeaters": "显示转发节点",
"appSettings_showRepeatersSubtitle": "在地图上显示转发节点",

@ -34,6 +34,7 @@ import 'storage/drift/blob_store.dart';
import 'widgets/storage_unavailable_banner.dart';
import 'storage/prefs_manager.dart';
import 'utils/app_logger.dart';
import 'widgets/keep_screen_awake.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
@ -279,10 +280,12 @@ class MeshCoreApp extends StatelessWidget {
NotificationService().setLocale(locale);
return AnnotatedRegion<SystemUiOverlayStyle>(
value: _systemUiOverlayStyle(context),
child: Consumer<StorageHealthService>(
builder: (context, health, _) => StorageUnavailableBanner(
show: !health.available,
child: child ?? const SizedBox.shrink(),
child: KeepScreenAwake(
child: Consumer<StorageHealthService>(
builder: (context, health, _) => StorageUnavailableBanner(
show: !health.available,
child: child ?? const SizedBox.shrink(),
),
),
),
);

@ -121,6 +121,7 @@ class AppSettings {
final bool mapShowMarkers;
final bool mapShowGuessedLocations;
final bool enableMessageTracing;
final bool keepScreenAwake;
final ClockFormat clockFormat;
final Map<String, double>? mapCacheBounds;
final int mapCacheMinZoom;
@ -198,6 +199,7 @@ class AppSettings {
this.mapShowMarkers = true,
this.mapShowGuessedLocations = true,
this.enableMessageTracing = false,
this.keepScreenAwake = false,
this.clockFormat = ClockFormat.system,
this.mapCacheBounds,
this.mapCacheMinZoom = 10,
@ -263,6 +265,7 @@ class AppSettings {
'map_show_markers': mapShowMarkers,
'map_show_guessed_locations': mapShowGuessedLocations,
'enable_message_tracing': enableMessageTracing,
'keep_screen_awake': keepScreenAwake,
'clock_format': clockFormat.value,
'map_cache_bounds': mapCacheBounds,
'map_cache_min_zoom': mapCacheMinZoom,
@ -352,6 +355,7 @@ class AppSettings {
mapShowGuessedLocations:
json['map_show_guessed_locations'] as bool? ?? true,
enableMessageTracing: json['enable_message_tracing'] as bool? ?? false,
keepScreenAwake: json['keep_screen_awake'] as bool? ?? false,
clockFormat: parseClockFormat(json['clock_format']),
mapCacheBounds: (json['map_cache_bounds'] as Map?)?.map(
(key, value) => MapEntry(key.toString(), (value as num).toDouble()),
@ -475,6 +479,7 @@ class AppSettings {
bool? mapShowMarkers,
bool? mapShowGuessedLocations,
bool? enableMessageTracing,
bool? keepScreenAwake,
ClockFormat? clockFormat,
Object? mapCacheBounds = _unset,
int? mapCacheMinZoom,
@ -525,6 +530,7 @@ class AppSettings {
mapShowGuessedLocations:
mapShowGuessedLocations ?? this.mapShowGuessedLocations,
enableMessageTracing: enableMessageTracing ?? this.enableMessageTracing,
keepScreenAwake: keepScreenAwake ?? this.keepScreenAwake,
clockFormat: clockFormat ?? this.clockFormat,
mapCacheBounds: mapCacheBounds == _unset
? this.mapCacheBounds

@ -557,6 +557,20 @@ class AppSettingsView extends StatelessWidget {
],
),
),
const Divider(height: 1),
SwitchListTile(
secondary: const Icon(Icons.screen_lock_portrait_outlined),
title: Text(context.l10n.appSettings_keepScreenAwake),
subtitle: Text(context.l10n.appSettings_keepScreenAwakeSubtitle),
value: settingsService.settings.keepScreenAwake,
onChanged: (value) {
persistSetting(
context,
() => settingsService.setKeepScreenAwake(value),
);
},
),
],
),
);

@ -104,6 +104,10 @@ class AppSettingsService extends ChangeNotifier {
await updateSettings(_settings.copyWith(enableMessageTracing: value));
}
Future<void> setKeepScreenAwake(bool value) async {
await updateSettings(_settings.copyWith(keepScreenAwake: value));
}
Future<void> setClockFormat(ClockFormat value) async {
await updateSettings(_settings.copyWith(clockFormat: value));
}

@ -0,0 +1,80 @@
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:wakelock_plus/wakelock_plus.dart';
import '../services/app_settings_service.dart';
/// Holds a screen wakelock while [AppSettings.keepScreenAwake] is enabled and
/// the app is foregrounded (#269).
///
/// The lock is released when the setting is turned off, when the app leaves the
/// foreground, and on dispose — so normal display sleep resumes and the
/// background foreground-service behaviour is untouched.
class KeepScreenAwake extends StatefulWidget {
const KeepScreenAwake({super.key, required this.child});
final Widget child;
@override
State<KeepScreenAwake> createState() => _KeepScreenAwakeState();
}
class _KeepScreenAwakeState extends State<KeepScreenAwake>
with WidgetsBindingObserver {
AppSettingsService? _service;
bool _foreground = true;
bool _held = false;
@override
void initState() {
super.initState();
WidgetsBinding.instance.addObserver(this);
}
@override
void didChangeDependencies() {
super.didChangeDependencies();
final service = context.read<AppSettingsService>();
if (!identical(service, _service)) {
_service?.removeListener(_sync);
_service = service..addListener(_sync);
}
_sync();
}
@override
void didChangeAppLifecycleState(AppLifecycleState state) {
_foreground = state == AppLifecycleState.resumed;
_sync();
}
/// Drives the platform wakelock toward the desired state. Failures are
/// logged and leave the tracked state released, never swallowed.
Future<void> _sync() async {
final want = (_service?.settings.keepScreenAwake ?? false) && _foreground;
if (want == _held) return;
try {
await WakelockPlus.toggle(enable: want);
_held = want;
} catch (e) {
_held = false;
debugPrint('[KeepScreenAwake] failed to set wakelock to $want: $e');
}
}
@override
void dispose() {
_service?.removeListener(_sync);
WidgetsBinding.instance.removeObserver(this);
if (_held) {
WakelockPlus.disable().catchError(
(Object e) =>
debugPrint('[KeepScreenAwake] failed to release on dispose: $e'),
);
}
super.dispose();
}
@override
Widget build(BuildContext context) => widget.child;
}

@ -13,6 +13,7 @@ import share_plus
import shared_preferences_foundation
import sqflite_darwin
import url_launcher_macos
import wakelock_plus
func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
FlutterBluePlusPlugin.register(with: registry.registrar(forPlugin: "FlutterBluePlusPlugin"))
@ -23,4 +24,5 @@ func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin"))
SqflitePlugin.register(with: registry.registrar(forPlugin: "SqflitePlugin"))
UrlLauncherPlugin.register(with: registry.registrar(forPlugin: "UrlLauncherPlugin"))
WakelockPlusMacosPlugin.register(with: registry.registrar(forPlugin: "WakelockPlusMacosPlugin"))
}

@ -55,6 +55,7 @@ dependencies:
cached_network_image: ^3.4.1
flutter_cache_manager: ^3.4.1
flutter_foreground_task: ^9.2.0
wakelock_plus: ^1.2.8 # Keep-screen-awake setting (#269)
characters: ^1.4.0
package_info_plus: ^9.0.0
mobile_scanner: ^7.1.4 # QR/barcode scanning

Loading…
Cancel
Save

Powered by TurnKey Linux.