From d35ef8162270e97bbd8a3f0bd9928fae4461e161 Mon Sep 17 00:00:00 2001 From: Nucleus Date: Mon, 18 Dec 2023 22:46:32 +0100 Subject: [PATCH 01/61] replace the old notification settings with improved one. You can now select a warningLevel for every WarningSource. Added the needed widgets, enums and classes to handle the new data. --- lib/class/class_notificationPreferences.dart | 22 ++ lib/class/class_userPreferences.dart | 10 + lib/enums/NotificationLevel.dart | 15 ++ lib/enums/WarningSource.dart | 23 ++ ...NotificationPreferencesListTileWidget.dart | 235 ++++++++++++++++++ 5 files changed, 305 insertions(+) create mode 100644 lib/class/class_notificationPreferences.dart create mode 100644 lib/enums/NotificationLevel.dart create mode 100644 lib/enums/WarningSource.dart create mode 100644 lib/widgets/NotificationPreferencesListTileWidget.dart diff --git a/lib/class/class_notificationPreferences.dart b/lib/class/class_notificationPreferences.dart new file mode 100644 index 00000000..93e5f1f6 --- /dev/null +++ b/lib/class/class_notificationPreferences.dart @@ -0,0 +1,22 @@ +import 'package:foss_warn/enums/NotificationLevel.dart'; +import 'package:foss_warn/enums/WarningSource.dart'; +/// to store the chosen notificationLevel for a warningSource +class NotificationPreferences { + NotificationLevel notificationLevel; + WarningSource warningSource; + + NotificationPreferences( + {required this.warningSource, required this.notificationLevel}); + + factory NotificationPreferences.fromJson(Map json) { + return NotificationPreferences( + warningSource: WarningSource.fromJson(json['warningSource']), + notificationLevel: + NotificationLevel.fromJson(json['notificationLevel'])); + } + + Map toJson() => { + 'notificationLevel': notificationLevel.toJson(), + 'warningSource': warningSource.toJson(), + }; +} diff --git a/lib/class/class_userPreferences.dart b/lib/class/class_userPreferences.dart index 3c89f426..6608e81e 100644 --- a/lib/class/class_userPreferences.dart +++ b/lib/class/class_userPreferences.dart @@ -1,19 +1,29 @@ import 'package:flutter/material.dart'; import 'package:foss_warn/themes/themes.dart'; +import 'class_notificationPreferences.dart'; + /// handle user preferences. The values written here are default values /// the correct values are loaded in loadSettings() from sharedPreferences class UserPreferences { + @deprecated bool notificationWithExtreme = true; + @deprecated bool notificationWithSevere = true; + @deprecated bool notificationWithModerate = true; + @deprecated bool notificationWithMinor = false; bool shouldNotifyGeneral = true; bool showStatusNotification = true; + @deprecated Map notificationEventsSettings = new Map(); + // to save the user settings for which source + // the user would like to be notified + List notificationSourceSettings = []; bool showExtendedMetaData = false; // show more tags in WarningDetailView ThemeMode selectedThemeMode = ThemeMode.system; diff --git a/lib/enums/NotificationLevel.dart b/lib/enums/NotificationLevel.dart new file mode 100644 index 00000000..94f85ba2 --- /dev/null +++ b/lib/enums/NotificationLevel.dart @@ -0,0 +1,15 @@ +// represents the settings for the notification per sourcee +// getUpToMinor: You receive all warnings up to minor warnings +// getUpToModerate: You receive all warnings up to moderate warnings. For minor +// warnings you wont receive a notification +// etc. +enum NotificationLevel { + getUpToMinor, + getUpToModerate, + getUpToSevere, + getUpToExtreme, + disabled; + + String toJson() => name; + static NotificationLevel fromJson(String json) => values.byName(json); +} diff --git a/lib/enums/WarningSource.dart b/lib/enums/WarningSource.dart new file mode 100644 index 00000000..00307564 --- /dev/null +++ b/lib/enums/WarningSource.dart @@ -0,0 +1,23 @@ +enum WarningSource { + mowas, + biwapp, + katwarn, + dwd, + lhp, + alertSwiss, + other; + + String toJson() => name; + static WarningSource fromJson(String json) => values.byName(json); + + static WarningSource fromString(String name) { + switch (name) { + case "Alert Swiss": return WarningSource.alertSwiss; + case "mowas" : return WarningSource.mowas; + case "katwarn": return WarningSource.katwarn; + case "dwd": return WarningSource.dwd; + case "lhp": return WarningSource.lhp; + default: return WarningSource.other; + } + } +} \ No newline at end of file diff --git a/lib/widgets/NotificationPreferencesListTileWidget.dart b/lib/widgets/NotificationPreferencesListTileWidget.dart new file mode 100644 index 00000000..c439cb99 --- /dev/null +++ b/lib/widgets/NotificationPreferencesListTileWidget.dart @@ -0,0 +1,235 @@ +import 'package:flutter/material.dart'; +import '../class/class_notificationPreferences.dart'; +import '../enums/NotificationLevel.dart'; +import '../enums/WarningSource.dart'; +import 'package:flutter_gen/gen_l10n/app_localizations.dart'; + +import '../services/saveAndLoadSharedPreferences.dart'; + +class NotificationPreferencesListTileWidget extends StatefulWidget { + final NotificationPreferences notificationPreferences; + const NotificationPreferencesListTileWidget( + {super.key, required this.notificationPreferences}); + + @override + State createState() => + _NotificationPreferencesListTileWidgetState(); +} + +class _NotificationPreferencesListTileWidgetState + extends State { + final EdgeInsets settingsTileListPadding = EdgeInsets.fromLTRB(25, 2, 25, 2); + + // return the label for the given value + String getLabelForWarningSeverity(double sliderValue) { + switch (sliderValue.toInt()) { + case 3: + return AppLocalizations.of(context)! + .notification_settings_notify_by_minor; + case 2: + return AppLocalizations.of(context)! + .notification_settings_notify_by_moderate; + case 1: + return AppLocalizations.of(context)! + .notification_settings_notify_by_severe; + case 0: + return AppLocalizations.of(context)! + .notification_settings_notify_by_extreme; + default: + return "Error"; + } + } + + /// return the description for the given source + String getDescriptionForEventSetting(WarningSource source) { + switch (source) { + case WarningSource.dwd: + return AppLocalizations.of(context)!.source_dwd_description; + case WarningSource.mowas: + return AppLocalizations.of(context)!.source_mowas_description; + case WarningSource.biwapp: + return AppLocalizations.of(context)!.source_biwapp_description; + case WarningSource.katwarn: + return AppLocalizations.of(context)!.source_katwarn_description; + case WarningSource.lhp: + return AppLocalizations.of(context)!.source_lhp_description; + case WarningSource.alertSwiss: + return AppLocalizations.of(context)!.source_alertswiss_description; + case WarningSource.other: + return "Generelle Einstellung, die verwendet wird, wenn keine" + " genauere Einstellung getroffen wurde."; + default: + return "Error"; + } + } + + /// decide if a source can be disable + bool SourceCanBeDisabled(WarningSource source) { + switch (source) { + case WarningSource.dwd: + return true; + case WarningSource.mowas: + return false; + case WarningSource.biwapp: + return false; + case WarningSource.katwarn: + return false; + case WarningSource.lhp: + return true; + case WarningSource.other: + return false; + default: + return false; + } + } + + /// translate notification preferences into slider value + double getValueForWarningLevel(NotificationLevel notificationPreferences) { + switch (notificationPreferences) { + case NotificationLevel.getUpToMinor: + return 3; + case NotificationLevel.getUpToModerate: + return 2; + case NotificationLevel.getUpToSevere: + return 1; + case NotificationLevel.getUpToExtreme: + return 0; + default: + return 3; + } + } + + /// translate slider value into notification preferences + NotificationLevel getNotificationPreferencesForValue(double value) { + switch (value.toInt()) { + case 0: + return NotificationLevel.getUpToExtreme; + case 1: + return NotificationLevel.getUpToSevere; + case 2: + return NotificationLevel.getUpToModerate; + case 3: + return NotificationLevel.getUpToMinor; + default: + return NotificationLevel.disabled; + } + } + + @override + Widget build(BuildContext context) { + return ListTile( + contentPadding: settingsTileListPadding, + title: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text( + widget.notificationPreferences.warningSource.name.toUpperCase(), + style: Theme.of(context).textTheme.titleMedium, + ), + // show a switch when source can be disabled + SourceCanBeDisabled(widget.notificationPreferences.warningSource) + ? Switch( + value: widget.notificationPreferences.notificationLevel != + NotificationLevel.disabled, + onChanged: (value) { + // if source is enabled, set notificationLevel to getUpToMinor + // if source is disabled set notification level to disabled, + // the slider will be hidden when notification + // level is set to disabled + if (value) { + setState(() { + widget.notificationPreferences.notificationLevel = + NotificationLevel.getUpToMinor; + }); + } else { + setState(() { + widget.notificationPreferences.notificationLevel = + NotificationLevel.disabled; + }); + } + saveSettings(); + }, + ) + : SizedBox(), + ], + ), + subtitle: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + getDescriptionForEventSetting( + widget.notificationPreferences.warningSource), + style: Theme.of(context).textTheme.bodyMedium), + // hide the slider when source is disabled + SourceCanBeDisabled(widget.notificationPreferences.warningSource) && + widget.notificationPreferences.notificationLevel == + NotificationLevel.disabled + ? Container( + padding: EdgeInsets.only(top: 5), + child: Text( + "Source disabled - you won't get a notification"), //@todo translate + ) + : Column( + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + mainAxisSize: MainAxisSize.max, + children: [ + Icon( + Icons.notifications_active, + color: Colors.red, + ), + Flexible( + child: Slider( + label: getLabelForWarningSeverity( + getValueForWarningLevel(widget + .notificationPreferences + .notificationLevel)), + divisions: 3, + min: 0, + max: 3, + value: getValueForWarningLevel(widget + .notificationPreferences.notificationLevel), + onChanged: (value) { + setState( + () { + print(widget.notificationPreferences + .warningSource.name); + // update notification level with slider value + widget.notificationPreferences + .notificationLevel = + getNotificationPreferencesForValue(value); + }, + ); + }, + onChangeEnd: (value) { + // save settings, after change is complete + saveSettings(); + }, + ), + ), + Icon( + Icons.notifications, + color: Colors.orangeAccent, + ), + ], + ), + Padding( + padding: const EdgeInsets.only(left: 30, right: 30), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text("Extrem"), // @todo translation + Text("Schwer"), + Text("Mittel"), + Text("Gering"), + ], + ), + ) + ], + ), + ], + ), + ); + } +} From c77e28cd9345a15fed0ca2ba29147ded85ca66d9 Mon Sep 17 00:00:00 2001 From: Nucleus Date: Mon, 18 Dec 2023 23:01:38 +0100 Subject: [PATCH 02/61] add a check if the text field is in focus because the onTapOutside methode is executed too often. Fix bug of to often executed API call. Remove deprecated notification settings --- lib/views/SettingsView.dart | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/lib/views/SettingsView.dart b/lib/views/SettingsView.dart index 62194268..10495ecc 100644 --- a/lib/views/SettingsView.dart +++ b/lib/views/SettingsView.dart @@ -106,6 +106,7 @@ class _SettingsState extends State { AppLocalizations.of(context)!.settings_background_service), trailing: Switch( value: userPreferences.shouldNotifyGeneral, + //@todo maybe we should add a confirmation dialog to prevent accidentally disabled background updates onChanged: (value) { setState(() { userPreferences.shouldNotifyGeneral = value; @@ -116,12 +117,6 @@ class _SettingsState extends State { AlarmManager().registerBackgroundTask(); } else { AlarmManager().cancelBackgroundTask(); - setState(() { - userPreferences.notificationWithExtreme = false; - userPreferences.notificationWithSevere = false; - userPreferences.notificationWithModerate = false; - userPreferences.notificationWithMinor = false; - }); print("background notification disabled"); } }), @@ -167,11 +162,17 @@ class _SettingsState extends State { } }, onTapOutside: (e) { - FocusScope.of(context).unfocus(); - saveSettings(); - AlarmManager().cancelBackgroundTask(); - AlarmManager().registerBackgroundTask(); - callAPI(); // call api and update notification + // Check whether the text field is in focus, + // because this method is executed every time + // you tap somewhere in the settings, even + // if the text field is not in focus at all + if (FocusScope.of(context).isFirstFocus) { + FocusScope.of(context).unfocus(); + saveSettings(); + AlarmManager().cancelBackgroundTask(); + AlarmManager().registerBackgroundTask(); + callAPI(); // call api and update notification + } }, onEditingComplete: () { FocusScope.of(context).unfocus(); From c6c12a9005da7a4072051b5be259fd4a931bda8c Mon Sep 17 00:00:00 2001 From: Nucleus Date: Mon, 18 Dec 2023 23:02:09 +0100 Subject: [PATCH 03/61] migrate WarningSource to enum --- lib/widgets/WarningWidget.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/widgets/WarningWidget.dart b/lib/widgets/WarningWidget.dart index e0daa45b..3640e8c3 100644 --- a/lib/widgets/WarningWidget.dart +++ b/lib/widgets/WarningWidget.dart @@ -179,7 +179,7 @@ class WarningWidget extends StatelessWidget { width: 20, ), Text( - _warnMessage.source, + _warnMessage.source.name, style: TextStyle(fontSize: 12), ) ], From 9451fc1a095126feb237e649261e049537874bb4 Mon Sep 17 00:00:00 2001 From: Nucleus Date: Mon, 18 Dec 2023 23:03:57 +0100 Subject: [PATCH 04/61] save new notification settings and mark old methode as deprecated --- .../saveAndLoadSharedPreferences.dart | 21 ++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/lib/services/saveAndLoadSharedPreferences.dart b/lib/services/saveAndLoadSharedPreferences.dart index 617fbf6f..0a1a954d 100644 --- a/lib/services/saveAndLoadSharedPreferences.dart +++ b/lib/services/saveAndLoadSharedPreferences.dart @@ -1,4 +1,5 @@ import 'dart:convert'; +import 'package:foss_warn/class/class_notificationPreferences.dart'; import 'package:shared_preferences/shared_preferences.dart'; import 'package:flutter/material.dart'; @@ -100,8 +101,8 @@ saveSettings() async { userPreferences.availableDarkThemes .indexOf(userPreferences.selectedDarkTheme)); preferences.setBool("showAllWarnings", userPreferences.showAllWarnings); - preferences.setString("notificationEventsSettings", - jsonEncode(userPreferences.notificationEventsSettings)); + preferences.setString("notificationSourceSettings", + jsonEncode(userPreferences.notificationSourceSettings)); preferences.setBool("activateAlertSwiss", userPreferences.activateAlertSwiss); print("Settings saved"); } @@ -159,7 +160,7 @@ loadSettings() async { if (preferences.containsKey("warningFontSize")) { userPreferences.warningFontSize = preferences.getDouble("warningFontSize")!; } else { - saveSettings(); + saveSettings(); //@todo remove? loadSettings(); } if (preferences.containsKey("showWelcomeScreen")) { @@ -223,10 +224,14 @@ loadSettings() async { if (preferences.containsKey("showAllWarnings")) { userPreferences.showAllWarnings = preferences.getBool("showAllWarnings")!; } - if (preferences.containsKey("notificationEventsSettings")) { - String temp = preferences.getString("notificationEventsSettings")!; - userPreferences.notificationEventsSettings = - Map.from(jsonDecode(temp)); + if (preferences.containsKey("notificationSourceSettings")) { + List data = + jsonDecode(preferences.getString("notificationSourceSettings")!); + userPreferences.notificationSourceSettings.clear(); + for (int i = 0; i < data.length; i++) { + userPreferences.notificationSourceSettings + .add(NotificationPreferences.fromJson(data[i])); + } } if (preferences.containsKey("activateAlertSwiss")) { userPreferences.activateAlertSwiss = @@ -234,6 +239,7 @@ loadSettings() async { } } +@deprecated saveNotificationSettingsImportanceList() async { print("Save saveNotificationSettingsImportanceList"); notificationSettingsImportance.clear(); @@ -256,6 +262,7 @@ saveNotificationSettingsImportanceList() async { print(notificationSettingsImportance); } +@deprecated loadNotificationSettingsImportanceList() async { SharedPreferences preferences = await SharedPreferences.getInstance(); //check if notificationSettingsImportance already exists From f5581799f5b22de8b6b60bba606f7e56dfef6f4f Mon Sep 17 00:00:00 2001 From: Nucleus Date: Mon, 18 Dec 2023 23:05:11 +0100 Subject: [PATCH 05/61] new notification settings view --- lib/views/NotificationSettingsView.dart | 234 +++++------------------- 1 file changed, 46 insertions(+), 188 deletions(-) diff --git a/lib/views/NotificationSettingsView.dart b/lib/views/NotificationSettingsView.dart index d716101c..83d24005 100644 --- a/lib/views/NotificationSettingsView.dart +++ b/lib/views/NotificationSettingsView.dart @@ -1,9 +1,11 @@ import 'package:flutter/material.dart'; import 'package:flutter_gen/gen_l10n/app_localizations.dart'; +import 'package:foss_warn/class/class_notificationPreferences.dart'; +import 'package:foss_warn/enums/NotificationLevel.dart'; +import 'package:foss_warn/enums/WarningSource.dart'; +import 'package:foss_warn/widgets/NotificationPreferencesListTileWidget.dart'; -import '../class/class_alarmManager.dart'; import '../main.dart'; -import '../services/saveAndLoadSharedPreferences.dart'; class NotificationSettingsView extends StatefulWidget { const NotificationSettingsView({Key? key}) : super(key: key); @@ -15,8 +17,36 @@ class NotificationSettingsView extends StatefulWidget { class _NotificationSettingsViewState extends State { final EdgeInsets settingsTileListPadding = EdgeInsets.fromLTRB(25, 2, 25, 2); + @override Widget build(BuildContext context) { + // fill notificationSourceSettings with init data if empty + if (userPreferences.notificationSourceSettings.isEmpty) { + userPreferences.notificationSourceSettings.clear(); + print("User Preferences notificationSourceSettings is empty"); + userPreferences.notificationSourceSettings.add(NotificationPreferences( + warningSource: WarningSource.other, + notificationLevel: NotificationLevel.getUpToMinor)); + userPreferences.notificationSourceSettings.add(NotificationPreferences( + warningSource: WarningSource.mowas, + notificationLevel: NotificationLevel.getUpToMinor)); + userPreferences.notificationSourceSettings.add(NotificationPreferences( + warningSource: WarningSource.biwapp, + notificationLevel: NotificationLevel.getUpToMinor)); + userPreferences.notificationSourceSettings.add(NotificationPreferences( + warningSource: WarningSource.katwarn, + notificationLevel: NotificationLevel.getUpToMinor)); + userPreferences.notificationSourceSettings.add(NotificationPreferences( + warningSource: WarningSource.dwd, + notificationLevel: NotificationLevel.getUpToSevere)); + userPreferences.notificationSourceSettings.add(NotificationPreferences( + warningSource: WarningSource.lhp, + notificationLevel: NotificationLevel.getUpToSevere)); + userPreferences.notificationSourceSettings.add(NotificationPreferences( + warningSource: WarningSource.alertSwiss, + notificationLevel: NotificationLevel.getUpToMinor)); + } + return Scaffold( appBar: AppBar( title: @@ -28,200 +58,28 @@ class _NotificationSettingsViewState extends State { child: Column( crossAxisAlignment: CrossAxisAlignment.center, children: [ - SizedBox(height: 10), - Text( - AppLocalizations.of(context)!.notification_settings_notify_by, - style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold), - ), - ListTile( - contentPadding: settingsTileListPadding, - title: Text(AppLocalizations.of(context) - !.notification_settings_notify_by_extreme), - trailing: Switch( - value: userPreferences.notificationWithExtreme, - onChanged: (value) { - if (userPreferences.shouldNotifyGeneral) { - setState(() { - userPreferences.notificationWithExtreme = value; - saveNotificationSettingsImportanceList(); - AlarmManager().cancelBackgroundTask(); - AlarmManager().registerBackgroundTask(); - }); - } else { - print("Background notification is disabled"); - } - }), - ), - ListTile( - contentPadding: settingsTileListPadding, - title: Text(AppLocalizations.of(context) - !.notification_settings_notify_by_severe), - trailing: Switch( - value: userPreferences.notificationWithSevere, - onChanged: (value) { - if (userPreferences.shouldNotifyGeneral) { - setState(() { - userPreferences.notificationWithSevere = value; - saveNotificationSettingsImportanceList(); - AlarmManager().cancelBackgroundTask(); - AlarmManager().registerBackgroundTask(); - }); - } else { - print("Background notification is disabled"); - } - }), - ), - ListTile( - contentPadding: settingsTileListPadding, - title: Text(AppLocalizations.of(context) - !.notification_settings_notify_by_moderate), - trailing: Switch( - value: userPreferences.notificationWithModerate, - onChanged: (value) { - if (userPreferences.shouldNotifyGeneral) { - setState(() { - userPreferences.notificationWithModerate = value; - saveNotificationSettingsImportanceList(); - AlarmManager().cancelBackgroundTask(); - AlarmManager().registerBackgroundTask(); - }); - } else { - print("Background notification is disabled"); - } - }), - ), - ListTile( - contentPadding: settingsTileListPadding, - title: Text(AppLocalizations.of(context) - !.notification_settings_notify_by_minor), - trailing: Switch( - value: userPreferences.notificationWithMinor, - onChanged: (value) { - if (userPreferences.shouldNotifyGeneral) { - setState(() { - userPreferences.notificationWithMinor = value; - saveNotificationSettingsImportanceList(); - AlarmManager().cancelBackgroundTask(); - AlarmManager().registerBackgroundTask(); - }); - } else { - print("Background notification is disabled"); - } - }), - ), - SizedBox( - height: 10, - ), - Text( - "DWD", - style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold), - ), - ListTile( - contentPadding: settingsTileListPadding, - title: Text(AppLocalizations.of(context) - !.notification_settings_thunderstorm), - trailing: Switch( - value: userPreferences.notificationEventsSettings[ - "STARKES GEWITTER"] != - null - ? userPreferences - .notificationEventsSettings["STARKES GEWITTER"]! - : true, - onChanged: (value) { - setState(() { - userPreferences.notificationEventsSettings - .putIfAbsent("STARKES GEWITTER", () => value); - userPreferences.notificationEventsSettings - .update("STARKES GEWITTER", (newValue) => value); - }); - saveSettings(); - print(userPreferences.notificationEventsSettings); - })), - ListTile( - contentPadding: settingsTileListPadding, - title: Text(AppLocalizations.of(context) - !.notification_settings_strong_weather), - trailing: Switch( - value: userPreferences.notificationEventsSettings[ - "STARKES WETTER"] != - null - ? userPreferences - .notificationEventsSettings["STARKES WETTER"]! - : true, - onChanged: (value) { - setState(() { - userPreferences.notificationEventsSettings - .putIfAbsent("STARKES WETTER", () => value); - userPreferences.notificationEventsSettings - .update("STARKES WETTER", (newValue) => value); - }); - saveSettings(); - })), - ListTile( - contentPadding: settingsTileListPadding, - title: Text(AppLocalizations.of(context) - !.notification_settings_everything_else), - trailing: Switch( - value: true, - onChanged: null)), SizedBox( height: 10, ), - Text( - "Mowas", - style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold), - ), - ListTile( - contentPadding: settingsTileListPadding, - title: Text(AppLocalizations.of(context) - !.notification_settings_everything), - trailing: Switch( - value: true, - onChanged: null)), - SizedBox( - height: 10, - ), - Text( - "BIWAPP", - style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold), - ), - ListTile( - contentPadding: settingsTileListPadding, - title: Text(AppLocalizations.of(context) - !.notification_settings_everything), - trailing: Switch( - value: true, - onChanged: null), - ), - SizedBox( - height: 10, - ), - Text( - "KATWARN", - style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold), - ), - ListTile( - contentPadding: settingsTileListPadding, - title: Text(AppLocalizations.of(context) - !.notification_settings_everything), - trailing: Switch( - value: true, - onChanged: null), + Container( + padding: settingsTileListPadding, + child: Text( + "Hier können Sie einstellen, ab welcher Warnstufe Sie für" + " welche Warnquelle eine Benachrichtigung erhalten möchten. "), ), SizedBox( height: 10, ), - Text( - "LHP", - style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold), + Padding( + padding: settingsTileListPadding, + child: Divider(), ), - ListTile( - contentPadding: settingsTileListPadding, - title: Text(AppLocalizations.of(context) - !.notification_settings_everything), - trailing: Switch( - value: true, - onChanged: null)), + // generate the settings tiles + ...userPreferences.notificationSourceSettings + .map((element) => NotificationPreferencesListTileWidget( + notificationPreferences: element, + )) + .toList(), ], ), ), From d1ed81164e485efdca36fbd5c42237b6857a65ca Mon Sep 17 00:00:00 2001 From: Nucleus Date: Mon, 18 Dec 2023 23:05:57 +0100 Subject: [PATCH 06/61] migrate WarningSource to enum --- lib/services/getData.dart | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/lib/services/getData.dart b/lib/services/getData.dart index 05558b23..6de5fe8e 100644 --- a/lib/services/getData.dart +++ b/lib/services/getData.dart @@ -1,5 +1,6 @@ import 'dart:convert'; import 'package:foss_warn/enums/DataFetchStatus.dart'; +import 'package:foss_warn/enums/WarningSource.dart'; import 'package:foss_warn/services/alertSwiss.dart'; import '../enums/Certainty.dart'; @@ -82,7 +83,7 @@ Future getData(bool useEtag) async { } WarnMessage tempWarnMessage = WarnMessage( - source: "MOWAS", + source: WarningSource.mowas, identifier: _data[i]["identifier"] ?? "?", sender: _data[i]["sender"] ?? "?", sent: _data[i]["sent"] ?? "?", @@ -178,7 +179,7 @@ Future getData(bool useEtag) async { } WarnMessage tempWarnMessage = WarnMessage( - source: "KATWARN", + source: WarningSource.katwarn, identifier: _data[i]["identifier"] ?? "?", sender: _data[i]["sender"] ?? "?", sent: _data[i]["sent"] ?? "?", @@ -276,7 +277,7 @@ Future getData(bool useEtag) async { } WarnMessage tempWarnMessage = WarnMessage( - source: "BIWAPP", + source: WarningSource.biwapp, identifier: _data[i]["identifier"] ?? "?", sender: _data[i]["sender"] ?? "?", sent: _data[i]["sent"] ?? "?", @@ -376,7 +377,7 @@ Future getData(bool useEtag) async { } WarnMessage tempWarnMessage = WarnMessage( - source: "DWD", + source: WarningSource.dwd, identifier: _data[i]["identifier"] ?? "?", sender: _data[i]["sender"] ?? "?", sent: _data[i]["sent"] ?? "?", @@ -472,7 +473,7 @@ Future getData(bool useEtag) async { } WarnMessage tempWarnMessage = WarnMessage( - source: "LHP", + source: WarningSource.lhp, identifier: _data[i]["identifier"] ?? "?", sender: _data[i]["sender"] ?? "?", sent: _data[i]["sent"] ?? "?", From d5d4867d553b5bcd49ff04ad3dfa56a4b97927ba Mon Sep 17 00:00:00 2001 From: Nucleus Date: Mon, 18 Dec 2023 23:07:59 +0100 Subject: [PATCH 07/61] migrate to new notification settings --- lib/class/abstract_Place.dart | 61 +++++++++++++++++++++++------------ 1 file changed, 41 insertions(+), 20 deletions(-) diff --git a/lib/class/abstract_Place.dart b/lib/class/abstract_Place.dart index cffc2038..6947c7d0 100644 --- a/lib/class/abstract_Place.dart +++ b/lib/class/abstract_Place.dart @@ -1,7 +1,10 @@ import 'package:flutter/material.dart'; +import 'package:foss_warn/enums/NotificationLevel.dart'; +import 'package:foss_warn/enums/WarningSource.dart'; import 'package:foss_warn/services/saveAndLoadSharedPreferences.dart'; import 'package:provider/provider.dart'; +import '../enums/Severity.dart'; import '../main.dart'; import '../services/listHandler.dart'; import '../services/updateProvider.dart'; @@ -13,17 +16,23 @@ abstract class Place { List _warnings = []; String eTag = ""; - Place({required String name, required List warnings, required String eTag}) : _warnings = warnings, _name = name { + Place( + {required String name, + required List warnings, + required String eTag}) + : _warnings = warnings, + _name = name { eTag = eTag; } String get name => _name; - int get countWarnings=> this.warnings.length; + int get countWarnings => this.warnings.length; List get warnings => _warnings; // control the list for warnings void addWarningToList(WarnMessage warnMessage) => _warnings.add(warnMessage); - void removeWarningFromList(WarnMessage warnMessage) => _warnings.remove(warnMessage); + void removeWarningFromList(WarnMessage warnMessage) => + _warnings.remove(warnMessage); // check if all warnings in `warnings` are // also in the alreadyReadWarnings list @@ -55,13 +64,16 @@ abstract class Place { Future sendNotificationForWarnings() async { for (WarnMessage myWarnMessage in _warnings) { print(myWarnMessage.headline); - print("Read: " + myWarnMessage.read.toString() + " notified " + myWarnMessage.notified.toString()); - print("should notify? :" + + //print("Read: " + myWarnMessage.read.toString() + " notified " + myWarnMessage.notified.toString()); + /*print("should notify? :" + ((!myWarnMessage.read && !myWarnMessage.notified) && - _checkIfEventShouldBeNotified(myWarnMessage.event)) - .toString()); + _checkIfEventShouldBeNotified( + myWarnMessage.source, myWarnMessage.severity)) + .toString());*/ + if ((!myWarnMessage.read && !myWarnMessage.notified) && - _checkIfEventShouldBeNotified(myWarnMessage.event)) { + _checkIfEventShouldBeNotified( + myWarnMessage.source, myWarnMessage.severity)) { // Alert is not already read or shown as notification // set notified to true to avoid sending notification twice myWarnMessage.notified = true; @@ -105,18 +117,27 @@ abstract class Place { saveMyPlacesList(); } - /// return [true] or false if the warning should be irgnored or not - /// The event could be listed in the map notificationEventsSettings. - /// if it is listed in the map, return the stored value for the event - /// If not return as default true - bool _checkIfEventShouldBeNotified(String event) { - if (userPreferences.notificationEventsSettings[event] != null) { - print(event + " " + userPreferences.notificationEventsSettings[event]!.toString()); - return userPreferences.notificationEventsSettings[event]!; - } else { - return true; + /// return [true] or false if the warning should be ignored or not + /// The source should be listed in the List notificationSourceSettings. + /// check if the user wants to be notified for + /// the given source and the given severity + bool _checkIfEventShouldBeNotified(WarningSource source, Severity severity) { + NotificationLevel? notificationPreferences = userPreferences + .notificationSourceSettings + .firstWhere((element) => element.warningSource == source) + .notificationLevel; + + switch (severity) { + case Severity.minor: + return notificationPreferences == NotificationLevel.getUpToMinor; + case Severity.moderate: + return notificationPreferences == NotificationLevel.getUpToModerate; + case Severity.severe: + return notificationPreferences == NotificationLevel.getUpToSevere; + case Severity.extreme: + return notificationPreferences == NotificationLevel.getUpToExtreme; + default: + return true; } } - - Map toJson(); } From b3bc5ceef9aad4de78e48c61b781b95112345567 Mon Sep 17 00:00:00 2001 From: Nucleus Date: Mon, 18 Dec 2023 23:08:42 +0100 Subject: [PATCH 08/61] remove unused parameter --- lib/class/class_alarmManager.dart | 2 +- lib/services/checkForMyPlacesWarnings.dart | 3 +-- lib/views/AllWarningsView.dart | 2 +- lib/views/DevSettingsView.dart | 2 +- 4 files changed, 4 insertions(+), 5 deletions(-) diff --git a/lib/class/class_alarmManager.dart b/lib/class/class_alarmManager.dart index cfa1166e..fae5036c 100644 --- a/lib/class/class_alarmManager.dart +++ b/lib/class/class_alarmManager.dart @@ -22,7 +22,7 @@ class AlarmManager { final int isolateId = Isolate.current.hashCode; print("[$now] Call APIs! isolate=$isolateId function='$callback'"); - await checkForMyPlacesWarnings(true, true); + await checkForMyPlacesWarnings(true); print("Call APIs executed"); } diff --git a/lib/services/checkForMyPlacesWarnings.dart b/lib/services/checkForMyPlacesWarnings.dart index 70d8864a..74348ad7 100644 --- a/lib/services/checkForMyPlacesWarnings.dart +++ b/lib/services/checkForMyPlacesWarnings.dart @@ -7,8 +7,7 @@ import 'saveAndLoadSharedPreferences.dart'; /// check all warnings if one of them is of a myPlace and if yes send a notification
/// [true] if there are/is a warning - false if not
-/// [useEtag]: if the etags should be used while calling the API -Future checkForMyPlacesWarnings(bool useEtag, bool loadManually) async { +Future checkForMyPlacesWarnings(bool loadManually) async { bool _returnValue = true; print("check for warnings"); // get data first diff --git a/lib/views/AllWarningsView.dart b/lib/views/AllWarningsView.dart index 8c43cf4c..650d4a3b 100644 --- a/lib/views/AllWarningsView.dart +++ b/lib/views/AllWarningsView.dart @@ -51,7 +51,7 @@ class _AllWarningsViewState extends State { // call (new) api just for my places/ alert swiss await callAPI(); } - checkForMyPlacesWarnings(false, true); + checkForMyPlacesWarnings(true); sortWarnings(allWarnMessageList); loadNotificationSettingsImportanceList(); setState(() { diff --git a/lib/views/DevSettingsView.dart b/lib/views/DevSettingsView.dart index 86bd93dd..77217c7a 100644 --- a/lib/views/DevSettingsView.dart +++ b/lib/views/DevSettingsView.dart @@ -37,7 +37,7 @@ class _DevSettingsState extends State { subtitle: Text(AppLocalizations.of(context) !.dev_settings_test_notification_text), onTap: () { - checkForMyPlacesWarnings(false, true); + checkForMyPlacesWarnings(true); bool thereIsNoWarning = true; for (Place myPlace in myPlaceList) { //check if there are warning and if it they are important enough From 08a343f6ad0bb3c1380f3ec291a9fbd2bedd6220 Mon Sep 17 00:00:00 2001 From: Nucleus Date: Mon, 18 Dec 2023 23:09:17 +0100 Subject: [PATCH 09/61] migrate WarningSource to enum --- lib/class/class_WarnMessage.dart | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/lib/class/class_WarnMessage.dart b/lib/class/class_WarnMessage.dart index d5938393..4f547e89 100644 --- a/lib/class/class_WarnMessage.dart +++ b/lib/class/class_WarnMessage.dart @@ -1,3 +1,5 @@ +import 'package:foss_warn/enums/WarningSource.dart'; + import '../enums/Certainty.dart'; import '../enums/Severity.dart'; import 'class_Area.dart'; @@ -6,7 +8,7 @@ import '../services/createAreaListFromJson.dart'; class WarnMessage { final String identifier; final String publisher; - final String source; + final WarningSource source; final String sender; final String sent; final String status; @@ -62,7 +64,7 @@ class WarnMessage { return WarnMessage( identifier: json['identifier'], publisher: json['publisher'], - source: json['source'], + source: WarningSource.fromJson(json['source']), sender: json['sender'], sent: json['sent'], status: json['status'], @@ -94,7 +96,7 @@ class WarnMessage { String publisher, List areaList) { print("Neue WarnMessage wird angelegt..."); return WarnMessage( - source: provider, + source: WarningSource.fromString(provider), identifier: json["identifier"] ?? "?", sender: json["sender"] ?? "?", sent: json["sent"] ?? "?", @@ -126,7 +128,7 @@ class WarnMessage { factory WarnMessage.fromJsonAlertSwiss(Map json, List areaList, String instructions, String license) { return WarnMessage( - source: "Alert Swiss", + source: WarningSource.alertSwiss, identifier: json["identifier"] ?? "?", sender: json["sender"] ?? "?", sent: json["sent"] ?? "?", From d09145bf224e37cc198beed21b058fe2f9be70e4 Mon Sep 17 00:00:00 2001 From: Nucleus Date: Mon, 18 Dec 2023 23:09:45 +0100 Subject: [PATCH 10/61] update dependencies --- pubspec.lock | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/pubspec.lock b/pubspec.lock index a245d7dd..d63474d7 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -53,10 +53,10 @@ packages: dependency: transitive description: name: collection - sha256: f092b211a4319e98e5ff58223576de6c2803db36221657b46c82574721240687 + sha256: ee67cb0715911d28db6bf4af1026078bd6f0128b07a5f66fb2ed94ec6783c09a url: "https://pub.dev" source: hosted - version: "1.17.2" + version: "1.18.0" cross_file: dependency: transitive description: @@ -201,10 +201,10 @@ packages: dependency: transitive description: name: meta - sha256: "3c74dbf8763d36539f114c799d8a2d87343b5067e9d796ca22b5eb8437090ee3" + sha256: a6e590c838b18133bb482a2745ad77c5bb7715fb0451209e1a7567d416678b8e url: "https://pub.dev" source: hosted - version: "1.9.1" + version: "1.10.0" mime: dependency: transitive description: @@ -414,18 +414,18 @@ packages: dependency: transitive description: name: stack_trace - sha256: c3c7d8edb15bee7f0f74debd4b9c5f3c2ea86766fe4178eb2a18eb30a0bdaed5 + sha256: "73713990125a6d93122541237550ee3352a2d84baad52d375a4cad2eb9b7ce0b" url: "https://pub.dev" source: hosted - version: "1.11.0" + version: "1.11.1" stream_channel: dependency: transitive description: name: stream_channel - sha256: "83615bee9045c1d322bbbd1ba209b7a749c2cbcdcb3fdd1df8eb488b3279c1c8" + sha256: ba2aa5d8cc609d96bbb2899c28934f9e1af5cddbd60a827822ea467161eb54e7 url: "https://pub.dev" source: hosted - version: "2.1.1" + version: "2.1.2" string_scanner: dependency: transitive description: @@ -446,10 +446,10 @@ packages: dependency: transitive description: name: test_api - sha256: "75760ffd7786fffdfb9597c35c5b27eaeec82be8edfb6d71d32651128ed7aab8" + sha256: "5c2f730018264d276c20e4f1503fd1308dfbbae39ec8ee63c5236311ac06954b" url: "https://pub.dev" source: hosted - version: "0.6.0" + version: "0.6.1" timezone: dependency: transitive description: @@ -550,10 +550,10 @@ packages: dependency: transitive description: name: web - sha256: dc8ccd225a2005c1be616fe02951e2e342092edf968cf0844220383757ef8f10 + sha256: afe077240a270dcfd2aafe77602b4113645af95d0ad31128cc02bce5ac5d5152 url: "https://pub.dev" source: hosted - version: "0.1.4-beta" + version: "0.3.0" win32: dependency: transitive description: @@ -579,5 +579,5 @@ packages: source: hosted version: "6.3.0" sdks: - dart: ">=3.1.0 <3.13.3" + dart: ">=3.2.0-194.0.dev <3.13.3" flutter: ">=3.13.0" From 5ee10ba57907ff600f67488a0e55000476abe1f4 Mon Sep 17 00:00:00 2001 From: Nucleus Date: Tue, 19 Dec 2023 00:12:24 +0100 Subject: [PATCH 11/61] fix spelling --- lib/enums/WarningSource.dart | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/lib/enums/WarningSource.dart b/lib/enums/WarningSource.dart index 00307564..1d581267 100644 --- a/lib/enums/WarningSource.dart +++ b/lib/enums/WarningSource.dart @@ -11,12 +11,12 @@ enum WarningSource { static WarningSource fromJson(String json) => values.byName(json); static WarningSource fromString(String name) { - switch (name) { - case "Alert Swiss": return WarningSource.alertSwiss; - case "mowas" : return WarningSource.mowas; - case "katwarn": return WarningSource.katwarn; - case "dwd": return WarningSource.dwd; - case "lhp": return WarningSource.lhp; + switch (name.toUpperCase()) { + case "ALERT SWISS": return WarningSource.alertSwiss; + case "MOWAS" : return WarningSource.mowas; + case "KATWARN": return WarningSource.katwarn; + case "DWD": return WarningSource.dwd; + case "LHP": return WarningSource.lhp; default: return WarningSource.other; } } From fe8a9575302724a1a7604b59a902b907d1e3ebef Mon Sep 17 00:00:00 2001 From: Nucleus Date: Tue, 19 Dec 2023 22:36:04 +0100 Subject: [PATCH 12/61] Fix logic error in the notification logic --- lib/class/abstract_Place.dart | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/lib/class/abstract_Place.dart b/lib/class/abstract_Place.dart index 6947c7d0..cbd59b0c 100644 --- a/lib/class/abstract_Place.dart +++ b/lib/class/abstract_Place.dart @@ -6,7 +6,6 @@ import 'package:provider/provider.dart'; import '../enums/Severity.dart'; import '../main.dart'; -import '../services/listHandler.dart'; import '../services/updateProvider.dart'; import 'class_NotificationService.dart'; import 'class_WarnMessage.dart'; @@ -52,7 +51,7 @@ abstract class Place { bool checkIfThereIsAWarningToNotify() { for (WarnMessage myWarning in _warnings) { if (!myWarning.notified && - notificationSettingsImportance.contains(myWarning.severity)) { + _checkIfEventShouldBeNotified(myWarning.source, myWarning.severity)) { // there is min. one warning without notification return true; } @@ -66,10 +65,10 @@ abstract class Place { print(myWarnMessage.headline); //print("Read: " + myWarnMessage.read.toString() + " notified " + myWarnMessage.notified.toString()); /*print("should notify? :" + - ((!myWarnMessage.read && !myWarnMessage.notified) && - _checkIfEventShouldBeNotified( - myWarnMessage.source, myWarnMessage.severity)) - .toString());*/ + (_checkIfEventShouldBeNotified( + myWarnMessage.source, myWarnMessage.severity)) + .toString());c*/ + //(!myWarnMessage.read && !myWarnMessage.notified) && if ((!myWarnMessage.read && !myWarnMessage.notified) && _checkIfEventShouldBeNotified( @@ -131,11 +130,17 @@ abstract class Place { case Severity.minor: return notificationPreferences == NotificationLevel.getUpToMinor; case Severity.moderate: - return notificationPreferences == NotificationLevel.getUpToModerate; + return notificationPreferences == NotificationLevel.getUpToModerate || + notificationPreferences == NotificationLevel.getUpToMinor; case Severity.severe: - return notificationPreferences == NotificationLevel.getUpToSevere; + return notificationPreferences == NotificationLevel.getUpToMinor || + notificationPreferences == NotificationLevel.getUpToModerate || + notificationPreferences == NotificationLevel.getUpToSevere; case Severity.extreme: - return notificationPreferences == NotificationLevel.getUpToExtreme; + return notificationPreferences == NotificationLevel.getUpToMinor || + notificationPreferences == NotificationLevel.getUpToModerate || + notificationPreferences == NotificationLevel.getUpToSevere || + notificationPreferences == NotificationLevel.getUpToExtreme; default: return true; } From fff69ff40db0ee2538049368dc2787fe849a2278 Mon Sep 17 00:00:00 2001 From: Nucleus Date: Tue, 19 Dec 2023 22:37:08 +0100 Subject: [PATCH 13/61] display the snackbar if there is no warning and not if there is a warning --- lib/views/DevSettingsView.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/views/DevSettingsView.dart b/lib/views/DevSettingsView.dart index 77217c7a..e936d13d 100644 --- a/lib/views/DevSettingsView.dart +++ b/lib/views/DevSettingsView.dart @@ -41,7 +41,7 @@ class _DevSettingsState extends State { bool thereIsNoWarning = true; for (Place myPlace in myPlaceList) { //check if there are warning and if it they are important enough - thereIsNoWarning = myPlace.checkIfThereIsAWarningToNotify(); + thereIsNoWarning = !(myPlace.checkIfThereIsAWarningToNotify()); } if (thereIsNoWarning) { final snackBar = SnackBar( From 2ca2d9135eccb0dca2599c97024e31deb95f5160 Mon Sep 17 00:00:00 2001 From: Nucleus Date: Tue, 19 Dec 2023 22:44:43 +0100 Subject: [PATCH 14/61] remove deprecated notification settings --- lib/services/checkForMyPlacesWarnings.dart | 5 ----- 1 file changed, 5 deletions(-) diff --git a/lib/services/checkForMyPlacesWarnings.dart b/lib/services/checkForMyPlacesWarnings.dart index 74348ad7..260a3efe 100644 --- a/lib/services/checkForMyPlacesWarnings.dart +++ b/lib/services/checkForMyPlacesWarnings.dart @@ -12,11 +12,6 @@ Future checkForMyPlacesWarnings(bool loadManually) async { print("check for warnings"); // get data first await callAPI(); - if (notificationSettingsImportance.isEmpty) { - print("notificationSettingsImportanceList is empty"); - await loadNotificationSettingsImportanceList(); - print(notificationSettingsImportance); - } if (myPlaceList.isEmpty) { print("myPlaceList is empty - load list"); await loadMyPlacesList(); From 79ca6980d69032a41a971b3d9a99ccc75d6a2f01 Mon Sep 17 00:00:00 2001 From: Nucleus Date: Wed, 20 Dec 2023 23:33:35 +0100 Subject: [PATCH 15/61] hide alert swiss settings, if disabled --- ...NotificationPreferencesListTileWidget.dart | 233 +++++++++--------- 1 file changed, 122 insertions(+), 111 deletions(-) diff --git a/lib/widgets/NotificationPreferencesListTileWidget.dart b/lib/widgets/NotificationPreferencesListTileWidget.dart index c439cb99..d64c5ae6 100644 --- a/lib/widgets/NotificationPreferencesListTileWidget.dart +++ b/lib/widgets/NotificationPreferencesListTileWidget.dart @@ -1,4 +1,5 @@ import 'package:flutter/material.dart'; +import 'package:foss_warn/main.dart'; import '../class/class_notificationPreferences.dart'; import '../enums/NotificationLevel.dart'; import '../enums/WarningSource.dart'; @@ -117,119 +118,129 @@ class _NotificationPreferencesListTileWidgetState @override Widget build(BuildContext context) { - return ListTile( - contentPadding: settingsTileListPadding, - title: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Text( - widget.notificationPreferences.warningSource.name.toUpperCase(), - style: Theme.of(context).textTheme.titleMedium, - ), - // show a switch when source can be disabled - SourceCanBeDisabled(widget.notificationPreferences.warningSource) - ? Switch( - value: widget.notificationPreferences.notificationLevel != - NotificationLevel.disabled, - onChanged: (value) { - // if source is enabled, set notificationLevel to getUpToMinor - // if source is disabled set notification level to disabled, - // the slider will be hidden when notification - // level is set to disabled - if (value) { - setState(() { - widget.notificationPreferences.notificationLevel = - NotificationLevel.getUpToMinor; - }); - } else { - setState(() { - widget.notificationPreferences.notificationLevel = - NotificationLevel.disabled; - }); - } - saveSettings(); - }, - ) - : SizedBox(), - ], - ), - subtitle: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( - getDescriptionForEventSetting( - widget.notificationPreferences.warningSource), - style: Theme.of(context).textTheme.bodyMedium), - // hide the slider when source is disabled - SourceCanBeDisabled(widget.notificationPreferences.warningSource) && - widget.notificationPreferences.notificationLevel == - NotificationLevel.disabled - ? Container( - padding: EdgeInsets.only(top: 5), - child: Text( - "Source disabled - you won't get a notification"), //@todo translate - ) - : Column( - children: [ - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - mainAxisSize: MainAxisSize.max, - children: [ - Icon( - Icons.notifications_active, - color: Colors.red, - ), - Flexible( - child: Slider( - label: getLabelForWarningSeverity( - getValueForWarningLevel(widget - .notificationPreferences - .notificationLevel)), - divisions: 3, - min: 0, - max: 3, - value: getValueForWarningLevel(widget - .notificationPreferences.notificationLevel), - onChanged: (value) { - setState( - () { - print(widget.notificationPreferences - .warningSource.name); - // update notification level with slider value - widget.notificationPreferences - .notificationLevel = - getNotificationPreferencesForValue(value); - }, - ); - }, - onChangeEnd: (value) { - // save settings, after change is complete - saveSettings(); - }, - ), - ), - Icon( - Icons.notifications, - color: Colors.orangeAccent, - ), - ], - ), - Padding( - padding: const EdgeInsets.only(left: 30, right: 30), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, + return widget.notificationPreferences.warningSource == + WarningSource.alertSwiss && + !userPreferences.activateAlertSwiss + ? SizedBox() // hide alert swiss if not activated + : ListTile( + contentPadding: settingsTileListPadding, + title: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text( + widget.notificationPreferences.warningSource.name + .toUpperCase(), + style: Theme.of(context).textTheme.titleMedium, + ), + // show a switch when source can be disabled + SourceCanBeDisabled( + widget.notificationPreferences.warningSource) + ? Switch( + value: + widget.notificationPreferences.notificationLevel != + NotificationLevel.disabled, + onChanged: (value) { + // if source is enabled, set notificationLevel to getUpToMinor + // if source is disabled set notification level to disabled, + // the slider will be hidden when notification + // level is set to disabled + if (value) { + setState(() { + widget.notificationPreferences.notificationLevel = + NotificationLevel.getUpToMinor; + }); + } else { + setState(() { + widget.notificationPreferences.notificationLevel = + NotificationLevel.disabled; + }); + } + saveSettings(); + }, + ) + : SizedBox(), + ], + ), + subtitle: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + getDescriptionForEventSetting( + widget.notificationPreferences.warningSource), + style: Theme.of(context).textTheme.bodyMedium), + // hide the slider when source is disabled + SourceCanBeDisabled( + widget.notificationPreferences.warningSource) && + widget.notificationPreferences.notificationLevel == + NotificationLevel.disabled + ? Container( + padding: EdgeInsets.only(top: 5), + child: Text( + "Source disabled - you won't get a notification"), //@todo translate + ) + : Column( children: [ - Text("Extrem"), // @todo translation - Text("Schwer"), - Text("Mittel"), - Text("Gering"), + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + mainAxisSize: MainAxisSize.max, + children: [ + Icon( + Icons.notifications_active, + color: Colors.red, + ), + Flexible( + child: Slider( + label: getLabelForWarningSeverity( + getValueForWarningLevel(widget + .notificationPreferences + .notificationLevel)), + divisions: 3, + min: 0, + max: 3, + value: getValueForWarningLevel(widget + .notificationPreferences + .notificationLevel), + onChanged: (value) { + setState( + () { + print(widget.notificationPreferences + .warningSource.name); + // update notification level with slider value + widget.notificationPreferences + .notificationLevel = + getNotificationPreferencesForValue( + value); + }, + ); + }, + onChangeEnd: (value) { + // save settings, after change is complete + saveSettings(); + }, + ), + ), + Icon( + Icons.notifications, + color: Colors.orangeAccent, + ), + ], + ), + Padding( + padding: const EdgeInsets.only(left: 30, right: 30), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text("Extrem"), // @todo translation + Text("Schwer"), + Text("Mittel"), + Text("Gering"), + ], + ), + ) ], ), - ) - ], - ), - ], - ), - ); + ], + ), + ); } } From d14b1a303e5543404504f55506b5de018942fab3 Mon Sep 17 00:00:00 2001 From: Nucleus Date: Wed, 20 Dec 2023 23:35:02 +0100 Subject: [PATCH 16/61] hide frequency update slider if background updates are deactivated --- lib/views/SettingsView.dart | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/views/SettingsView.dart b/lib/views/SettingsView.dart index 10495ecc..edfca3c5 100644 --- a/lib/views/SettingsView.dart +++ b/lib/views/SettingsView.dart @@ -121,6 +121,7 @@ class _SettingsState extends State { } }), ), + userPreferences.shouldNotifyGeneral ? ListTile( title: Row( mainAxisSize: MainAxisSize.max, @@ -218,7 +219,7 @@ class _SettingsState extends State { ), ], ), - ), + ) : SizedBox(), Divider( height: 50, indent: 15.0, From a0bda26f05a8b18eaf7621c3dfd6ef5cc04b1bb4 Mon Sep 17 00:00:00 2001 From: MatsG23 Date: Sat, 23 Dec 2023 17:08:50 +0100 Subject: [PATCH 17/61] Simplified code --- lib/class/abstract_Place.dart | 26 +----- lib/class/class_WarnMessage.dart | 2 +- lib/class/class_notificationPreferences.dart | 14 +-- lib/class/class_userPreferences.dart | 22 ++++- lib/enums/NotificationLevel.dart | 15 ---- lib/enums/Severity.dart | 17 +++- lib/enums/WarningSource.dart | 21 +++-- lib/services/sortWarnings.dart | 1 - lib/views/NotificationSettingsView.dart | 30 ------- ...NotificationPreferencesListTileWidget.dart | 87 +++++-------------- lib/widgets/WarningWidget.dart | 2 +- pubspec.lock | 26 +++--- 12 files changed, 100 insertions(+), 163 deletions(-) delete mode 100644 lib/enums/NotificationLevel.dart diff --git a/lib/class/abstract_Place.dart b/lib/class/abstract_Place.dart index cbd59b0c..5e37fc93 100644 --- a/lib/class/abstract_Place.dart +++ b/lib/class/abstract_Place.dart @@ -1,5 +1,5 @@ import 'package:flutter/material.dart'; -import 'package:foss_warn/enums/NotificationLevel.dart'; +import 'package:foss_warn/class/class_notificationPreferences.dart'; import 'package:foss_warn/enums/WarningSource.dart'; import 'package:foss_warn/services/saveAndLoadSharedPreferences.dart'; import 'package:provider/provider.dart'; @@ -121,28 +121,10 @@ abstract class Place { /// check if the user wants to be notified for /// the given source and the given severity bool _checkIfEventShouldBeNotified(WarningSource source, Severity severity) { - NotificationLevel? notificationPreferences = userPreferences + NotificationPreferences notificationSourceSetting = userPreferences .notificationSourceSettings - .firstWhere((element) => element.warningSource == source) - .notificationLevel; + .firstWhere((element) => element.warningSource == source); - switch (severity) { - case Severity.minor: - return notificationPreferences == NotificationLevel.getUpToMinor; - case Severity.moderate: - return notificationPreferences == NotificationLevel.getUpToModerate || - notificationPreferences == NotificationLevel.getUpToMinor; - case Severity.severe: - return notificationPreferences == NotificationLevel.getUpToMinor || - notificationPreferences == NotificationLevel.getUpToModerate || - notificationPreferences == NotificationLevel.getUpToSevere; - case Severity.extreme: - return notificationPreferences == NotificationLevel.getUpToMinor || - notificationPreferences == NotificationLevel.getUpToModerate || - notificationPreferences == NotificationLevel.getUpToSevere || - notificationPreferences == NotificationLevel.getUpToExtreme; - default: - return true; - } + return notificationSourceSetting.disabled == false && getIndexFromSeverity(notificationSourceSetting.notificationLevel) >= getIndexFromSeverity(severity); } } diff --git a/lib/class/class_WarnMessage.dart b/lib/class/class_WarnMessage.dart index 4f547e89..3417ca53 100644 --- a/lib/class/class_WarnMessage.dart +++ b/lib/class/class_WarnMessage.dart @@ -64,7 +64,7 @@ class WarnMessage { return WarnMessage( identifier: json['identifier'], publisher: json['publisher'], - source: WarningSource.fromJson(json['source']), + source: WarningSource.fromString(json['source'].toString()), sender: json['sender'], sent: json['sent'], status: json['status'], diff --git a/lib/class/class_notificationPreferences.dart b/lib/class/class_notificationPreferences.dart index 93e5f1f6..8d19227b 100644 --- a/lib/class/class_notificationPreferences.dart +++ b/lib/class/class_notificationPreferences.dart @@ -1,22 +1,26 @@ -import 'package:foss_warn/enums/NotificationLevel.dart'; +import 'package:foss_warn/enums/Severity.dart'; import 'package:foss_warn/enums/WarningSource.dart'; + /// to store the chosen notificationLevel for a warningSource class NotificationPreferences { - NotificationLevel notificationLevel; + Severity notificationLevel; + bool disabled; WarningSource warningSource; NotificationPreferences( - {required this.warningSource, required this.notificationLevel}); + {required this.warningSource, required this.notificationLevel, this.disabled = false}); factory NotificationPreferences.fromJson(Map json) { return NotificationPreferences( - warningSource: WarningSource.fromJson(json['warningSource']), + warningSource: WarningSource.fromString(json['warningSource'].toString()), + disabled: json['disabled'] == "true", // @todo is there a better way to deserialize a boolean? notificationLevel: - NotificationLevel.fromJson(json['notificationLevel'])); + Severity.fromJson(json['notificationLevel'])); } Map toJson() => { 'notificationLevel': notificationLevel.toJson(), + 'disabled': disabled, 'warningSource': warningSource.toJson(), }; } diff --git a/lib/class/class_userPreferences.dart b/lib/class/class_userPreferences.dart index 6608e81e..e8384cbe 100644 --- a/lib/class/class_userPreferences.dart +++ b/lib/class/class_userPreferences.dart @@ -1,6 +1,8 @@ import 'package:flutter/material.dart'; import 'package:foss_warn/themes/themes.dart'; +import '../enums/Severity.dart'; +import '../enums/WarningSource.dart'; import 'class_notificationPreferences.dart'; /// handle user preferences. The values written here are default values @@ -23,7 +25,25 @@ class UserPreferences { Map notificationEventsSettings = new Map(); // to save the user settings for which source // the user would like to be notified - List notificationSourceSettings = []; + List notificationSourceSettings = _getDefaultValueForNotificationSourceSettings(); + + static List _getDefaultValueForNotificationSourceSettings() { + List temp = []; + + for(WarningSource source in WarningSource.values) { + if(source == WarningSource.dwd || source == WarningSource.lhp) { + temp.add(NotificationPreferences( + warningSource: source, + notificationLevel: Severity.severe)); + } else { + temp.add(NotificationPreferences( + warningSource: source, + notificationLevel: Severity.minor)); + } + } + + return temp; + } bool showExtendedMetaData = false; // show more tags in WarningDetailView ThemeMode selectedThemeMode = ThemeMode.system; diff --git a/lib/enums/NotificationLevel.dart b/lib/enums/NotificationLevel.dart deleted file mode 100644 index 94f85ba2..00000000 --- a/lib/enums/NotificationLevel.dart +++ /dev/null @@ -1,15 +0,0 @@ -// represents the settings for the notification per sourcee -// getUpToMinor: You receive all warnings up to minor warnings -// getUpToModerate: You receive all warnings up to moderate warnings. For minor -// warnings you wont receive a notification -// etc. -enum NotificationLevel { - getUpToMinor, - getUpToModerate, - getUpToSevere, - getUpToExtreme, - disabled; - - String toJson() => name; - static NotificationLevel fromJson(String json) => values.byName(json); -} diff --git a/lib/enums/Severity.dart b/lib/enums/Severity.dart index b5fc9e15..4298f0e4 100644 --- a/lib/enums/Severity.dart +++ b/lib/enums/Severity.dart @@ -1,9 +1,8 @@ enum Severity { minor, moderate, - extreme, severe, - other; + extreme; String toJson() => name; static Severity fromJson(String json) => values.byName(json); @@ -16,5 +15,17 @@ Severity getSeverity(String severity) { return sev; } } - return Severity.other; + + return Severity.minor; +} + +double getIndexFromSeverity(Severity notificationLevel) { + final severities = Severity.values; + for (int i = 0; i < severities.length; i++) { + if (severities[i] == notificationLevel) { + return i.toDouble(); + } + } + + return 0; } diff --git a/lib/enums/WarningSource.dart b/lib/enums/WarningSource.dart index 1d581267..1c3043f1 100644 --- a/lib/enums/WarningSource.dart +++ b/lib/enums/WarningSource.dart @@ -8,16 +8,21 @@ enum WarningSource { other; String toJson() => name; - static WarningSource fromJson(String json) => values.byName(json); static WarningSource fromString(String name) { switch (name.toUpperCase()) { - case "ALERT SWISS": return WarningSource.alertSwiss; - case "MOWAS" : return WarningSource.mowas; - case "KATWARN": return WarningSource.katwarn; - case "DWD": return WarningSource.dwd; - case "LHP": return WarningSource.lhp; - default: return WarningSource.other; + case "ALERT SWISS": + return WarningSource.alertSwiss; + case "MOWAS": + return WarningSource.mowas; + case "KATWARN": + return WarningSource.katwarn; + case "DWD": + return WarningSource.dwd; + case "LHP": + return WarningSource.lhp; + default: + return WarningSource.other; } } -} \ No newline at end of file +} diff --git a/lib/services/sortWarnings.dart b/lib/services/sortWarnings.dart index 5b36a857..d558ca8b 100644 --- a/lib/services/sortWarnings.dart +++ b/lib/services/sortWarnings.dart @@ -7,7 +7,6 @@ import '../main.dart'; int convertSeverityToInt(Severity severity) { switch (severity) { case Severity.minor: - case Severity.other: return 0; case Severity.moderate: return 1; diff --git a/lib/views/NotificationSettingsView.dart b/lib/views/NotificationSettingsView.dart index 83d24005..0721b4a3 100644 --- a/lib/views/NotificationSettingsView.dart +++ b/lib/views/NotificationSettingsView.dart @@ -1,8 +1,5 @@ import 'package:flutter/material.dart'; import 'package:flutter_gen/gen_l10n/app_localizations.dart'; -import 'package:foss_warn/class/class_notificationPreferences.dart'; -import 'package:foss_warn/enums/NotificationLevel.dart'; -import 'package:foss_warn/enums/WarningSource.dart'; import 'package:foss_warn/widgets/NotificationPreferencesListTileWidget.dart'; import '../main.dart'; @@ -20,33 +17,6 @@ class _NotificationSettingsViewState extends State { @override Widget build(BuildContext context) { - // fill notificationSourceSettings with init data if empty - if (userPreferences.notificationSourceSettings.isEmpty) { - userPreferences.notificationSourceSettings.clear(); - print("User Preferences notificationSourceSettings is empty"); - userPreferences.notificationSourceSettings.add(NotificationPreferences( - warningSource: WarningSource.other, - notificationLevel: NotificationLevel.getUpToMinor)); - userPreferences.notificationSourceSettings.add(NotificationPreferences( - warningSource: WarningSource.mowas, - notificationLevel: NotificationLevel.getUpToMinor)); - userPreferences.notificationSourceSettings.add(NotificationPreferences( - warningSource: WarningSource.biwapp, - notificationLevel: NotificationLevel.getUpToMinor)); - userPreferences.notificationSourceSettings.add(NotificationPreferences( - warningSource: WarningSource.katwarn, - notificationLevel: NotificationLevel.getUpToMinor)); - userPreferences.notificationSourceSettings.add(NotificationPreferences( - warningSource: WarningSource.dwd, - notificationLevel: NotificationLevel.getUpToSevere)); - userPreferences.notificationSourceSettings.add(NotificationPreferences( - warningSource: WarningSource.lhp, - notificationLevel: NotificationLevel.getUpToSevere)); - userPreferences.notificationSourceSettings.add(NotificationPreferences( - warningSource: WarningSource.alertSwiss, - notificationLevel: NotificationLevel.getUpToMinor)); - } - return Scaffold( appBar: AppBar( title: diff --git a/lib/widgets/NotificationPreferencesListTileWidget.dart b/lib/widgets/NotificationPreferencesListTileWidget.dart index d64c5ae6..52ddfbb4 100644 --- a/lib/widgets/NotificationPreferencesListTileWidget.dart +++ b/lib/widgets/NotificationPreferencesListTileWidget.dart @@ -1,7 +1,7 @@ import 'package:flutter/material.dart'; +import 'package:foss_warn/enums/Severity.dart'; import 'package:foss_warn/main.dart'; import '../class/class_notificationPreferences.dart'; -import '../enums/NotificationLevel.dart'; import '../enums/WarningSource.dart'; import 'package:flutter_gen/gen_l10n/app_localizations.dart'; @@ -24,16 +24,16 @@ class _NotificationPreferencesListTileWidgetState // return the label for the given value String getLabelForWarningSeverity(double sliderValue) { switch (sliderValue.toInt()) { - case 3: + case 0: return AppLocalizations.of(context)! .notification_settings_notify_by_minor; - case 2: + case 1: return AppLocalizations.of(context)! .notification_settings_notify_by_moderate; - case 1: + case 2: return AppLocalizations.of(context)! .notification_settings_notify_by_severe; - case 0: + case 3: return AppLocalizations.of(context)! .notification_settings_notify_by_extreme; default: @@ -64,8 +64,8 @@ class _NotificationPreferencesListTileWidgetState } } - /// decide if a source can be disable - bool SourceCanBeDisabled(WarningSource source) { + /// decide if a source can be disabled + bool isTogglableSource(WarningSource source) { switch (source) { case WarningSource.dwd: return true; @@ -84,38 +84,6 @@ class _NotificationPreferencesListTileWidgetState } } - /// translate notification preferences into slider value - double getValueForWarningLevel(NotificationLevel notificationPreferences) { - switch (notificationPreferences) { - case NotificationLevel.getUpToMinor: - return 3; - case NotificationLevel.getUpToModerate: - return 2; - case NotificationLevel.getUpToSevere: - return 1; - case NotificationLevel.getUpToExtreme: - return 0; - default: - return 3; - } - } - - /// translate slider value into notification preferences - NotificationLevel getNotificationPreferencesForValue(double value) { - switch (value.toInt()) { - case 0: - return NotificationLevel.getUpToExtreme; - case 1: - return NotificationLevel.getUpToSevere; - case 2: - return NotificationLevel.getUpToModerate; - case 3: - return NotificationLevel.getUpToMinor; - default: - return NotificationLevel.disabled; - } - } - @override Widget build(BuildContext context) { return widget.notificationPreferences.warningSource == @@ -133,26 +101,19 @@ class _NotificationPreferencesListTileWidgetState style: Theme.of(context).textTheme.titleMedium, ), // show a switch when source can be disabled - SourceCanBeDisabled( - widget.notificationPreferences.warningSource) + isTogglableSource(widget.notificationPreferences.warningSource) ? Switch( value: - widget.notificationPreferences.notificationLevel != - NotificationLevel.disabled, + widget.notificationPreferences.disabled, onChanged: (value) { - // if source is enabled, set notificationLevel to getUpToMinor - // if source is disabled set notification level to disabled, - // the slider will be hidden when notification - // level is set to disabled + // the slider will be hidden when source is disabled if (value) { setState(() { - widget.notificationPreferences.notificationLevel = - NotificationLevel.getUpToMinor; + widget.notificationPreferences.disabled = false; }); } else { setState(() { - widget.notificationPreferences.notificationLevel = - NotificationLevel.disabled; + widget.notificationPreferences.disabled = true; }); } saveSettings(); @@ -169,10 +130,8 @@ class _NotificationPreferencesListTileWidgetState widget.notificationPreferences.warningSource), style: Theme.of(context).textTheme.bodyMedium), // hide the slider when source is disabled - SourceCanBeDisabled( - widget.notificationPreferences.warningSource) && - widget.notificationPreferences.notificationLevel == - NotificationLevel.disabled + isTogglableSource(widget.notificationPreferences.warningSource) && + widget.notificationPreferences.disabled ? Container( padding: EdgeInsets.only(top: 5), child: Text( @@ -191,25 +150,27 @@ class _NotificationPreferencesListTileWidgetState Flexible( child: Slider( label: getLabelForWarningSeverity( - getValueForWarningLevel(widget + getIndexFromSeverity(widget .notificationPreferences .notificationLevel)), divisions: 3, min: 0, max: 3, - value: getValueForWarningLevel(widget + value: getIndexFromSeverity(widget .notificationPreferences .notificationLevel), onChanged: (value) { setState( () { + final notificationLevel = Severity.values[value.toInt()]; + print(widget.notificationPreferences - .warningSource.name); + .warningSource.name + ":" + notificationLevel.toString()); + // update notification level with slider value widget.notificationPreferences .notificationLevel = - getNotificationPreferencesForValue( - value); + notificationLevel; }, ); }, @@ -230,10 +191,10 @@ class _NotificationPreferencesListTileWidgetState child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - Text("Extrem"), // @todo translation - Text("Schwer"), + Text("Gering"), // @todo translation Text("Mittel"), - Text("Gering"), + Text("Schwer"), + Text("Extrem"), ], ), ) diff --git a/lib/widgets/WarningWidget.dart b/lib/widgets/WarningWidget.dart index 3640e8c3..69176d53 100644 --- a/lib/widgets/WarningWidget.dart +++ b/lib/widgets/WarningWidget.dart @@ -179,7 +179,7 @@ class WarningWidget extends StatelessWidget { width: 20, ), Text( - _warnMessage.source.name, + _warnMessage.source.name.toUpperCase(), style: TextStyle(fontSize: 12), ) ], diff --git a/pubspec.lock b/pubspec.lock index d63474d7..a245d7dd 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -53,10 +53,10 @@ packages: dependency: transitive description: name: collection - sha256: ee67cb0715911d28db6bf4af1026078bd6f0128b07a5f66fb2ed94ec6783c09a + sha256: f092b211a4319e98e5ff58223576de6c2803db36221657b46c82574721240687 url: "https://pub.dev" source: hosted - version: "1.18.0" + version: "1.17.2" cross_file: dependency: transitive description: @@ -201,10 +201,10 @@ packages: dependency: transitive description: name: meta - sha256: a6e590c838b18133bb482a2745ad77c5bb7715fb0451209e1a7567d416678b8e + sha256: "3c74dbf8763d36539f114c799d8a2d87343b5067e9d796ca22b5eb8437090ee3" url: "https://pub.dev" source: hosted - version: "1.10.0" + version: "1.9.1" mime: dependency: transitive description: @@ -414,18 +414,18 @@ packages: dependency: transitive description: name: stack_trace - sha256: "73713990125a6d93122541237550ee3352a2d84baad52d375a4cad2eb9b7ce0b" + sha256: c3c7d8edb15bee7f0f74debd4b9c5f3c2ea86766fe4178eb2a18eb30a0bdaed5 url: "https://pub.dev" source: hosted - version: "1.11.1" + version: "1.11.0" stream_channel: dependency: transitive description: name: stream_channel - sha256: ba2aa5d8cc609d96bbb2899c28934f9e1af5cddbd60a827822ea467161eb54e7 + sha256: "83615bee9045c1d322bbbd1ba209b7a749c2cbcdcb3fdd1df8eb488b3279c1c8" url: "https://pub.dev" source: hosted - version: "2.1.2" + version: "2.1.1" string_scanner: dependency: transitive description: @@ -446,10 +446,10 @@ packages: dependency: transitive description: name: test_api - sha256: "5c2f730018264d276c20e4f1503fd1308dfbbae39ec8ee63c5236311ac06954b" + sha256: "75760ffd7786fffdfb9597c35c5b27eaeec82be8edfb6d71d32651128ed7aab8" url: "https://pub.dev" source: hosted - version: "0.6.1" + version: "0.6.0" timezone: dependency: transitive description: @@ -550,10 +550,10 @@ packages: dependency: transitive description: name: web - sha256: afe077240a270dcfd2aafe77602b4113645af95d0ad31128cc02bce5ac5d5152 + sha256: dc8ccd225a2005c1be616fe02951e2e342092edf968cf0844220383757ef8f10 url: "https://pub.dev" source: hosted - version: "0.3.0" + version: "0.1.4-beta" win32: dependency: transitive description: @@ -579,5 +579,5 @@ packages: source: hosted version: "6.3.0" sdks: - dart: ">=3.2.0-194.0.dev <3.13.3" + dart: ">=3.1.0 <3.13.3" flutter: ">=3.13.0" From 17c120624ceb792124b3fe7ed4534ae12c1afe9f Mon Sep 17 00:00:00 2001 From: MatsG23 Date: Sat, 23 Dec 2023 17:33:49 +0100 Subject: [PATCH 18/61] Remove duplicated code and restore old Severity values order --- lib/enums/Severity.dart | 4 ++-- lib/services/sortWarnings.dart | 19 ++----------------- ...NotificationPreferencesListTileWidget.dart | 4 ++-- 3 files changed, 6 insertions(+), 21 deletions(-) diff --git a/lib/enums/Severity.dart b/lib/enums/Severity.dart index 4298f0e4..77472cb0 100644 --- a/lib/enums/Severity.dart +++ b/lib/enums/Severity.dart @@ -1,8 +1,8 @@ enum Severity { minor, moderate, - severe, - extreme; + extreme, + severe; String toJson() => name; static Severity fromJson(String json) => values.byName(json); diff --git a/lib/services/sortWarnings.dart b/lib/services/sortWarnings.dart index d558ca8b..d6f203e7 100644 --- a/lib/services/sortWarnings.dart +++ b/lib/services/sortWarnings.dart @@ -2,21 +2,6 @@ import '../class/class_WarnMessage.dart'; import '../enums/Severity.dart'; import '../main.dart'; -/// used to sort warning -/// returns an int corresponding to the severity -int convertSeverityToInt(Severity severity) { - switch (severity) { - case Severity.minor: - return 0; - case Severity.moderate: - return 1; - case Severity.extreme: - return 2; - case Severity.severe: - return 3; - } -} - /// used to sort warning int convertSourceToInt(String source) { switch (source) { @@ -34,8 +19,8 @@ int convertSourceToInt(String source) { void sortWarnings(List list) { if (userPreferences.sortWarningsBy == "severity") { - list.sort((a, b) => convertSeverityToInt(b.severity) - .compareTo(convertSeverityToInt(a.severity))); + list.sort((a, b) => getIndexFromSeverity(b.severity) + .compareTo(getIndexFromSeverity(a.severity))); } else if (userPreferences.sortWarningsBy == "date") { list.sort((a, b) => b.sent.compareTo(a.sent)); } else if (userPreferences.sortWarningsBy == "source") { diff --git a/lib/widgets/NotificationPreferencesListTileWidget.dart b/lib/widgets/NotificationPreferencesListTileWidget.dart index 52ddfbb4..96da9f0a 100644 --- a/lib/widgets/NotificationPreferencesListTileWidget.dart +++ b/lib/widgets/NotificationPreferencesListTileWidget.dart @@ -193,8 +193,8 @@ class _NotificationPreferencesListTileWidgetState children: [ Text("Gering"), // @todo translation Text("Mittel"), - Text("Schwer"), - Text("Extrem"), + Text("extreme"), + Text("severe") ], ), ) From c703f5a21d75154ec01a0301bb58483f982acd17 Mon Sep 17 00:00:00 2001 From: Nucleus Date: Wed, 27 Dec 2023 17:51:55 +0100 Subject: [PATCH 19/61] extend documentation --- lib/class/abstract_Place.dart | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/lib/class/abstract_Place.dart b/lib/class/abstract_Place.dart index 5e37fc93..5e232e28 100644 --- a/lib/class/abstract_Place.dart +++ b/lib/class/abstract_Place.dart @@ -105,7 +105,7 @@ abstract class Place { /// set the read and notified status from all warnings to false /// used for debug purpose - /// @context to update view + /// [@context] to update view void resetReadAndNotificationStatusForAllWarnings(BuildContext context) { for (WarnMessage myWarnMessage in _warnings) { myWarnMessage.read = false; @@ -116,15 +116,25 @@ abstract class Place { saveMyPlacesList(); } - /// return [true] or false if the warning should be ignored or not + /// Return [true] if the user wants a notification - [false] if not. + /// /// The source should be listed in the List notificationSourceSettings. /// check if the user wants to be notified for /// the given source and the given severity + /// + /// example: + /// + /// Warning severity | Notification setting | notification?
+ /// Moderate (2) | Minor (3) | 3 >= 2 => true
+ /// Minor (3) | Moderate (2) | 2 >= 3 => false bool _checkIfEventShouldBeNotified(WarningSource source, Severity severity) { NotificationPreferences notificationSourceSetting = userPreferences .notificationSourceSettings .firstWhere((element) => element.warningSource == source); - return notificationSourceSetting.disabled == false && getIndexFromSeverity(notificationSourceSetting.notificationLevel) >= getIndexFromSeverity(severity); + return notificationSourceSetting.disabled == false && + Severity.getIndexFromSeverity( + notificationSourceSetting.notificationLevel) >= + Severity.getIndexFromSeverity(severity); } } From e7d5967b37e6a070625ad57ffb764b0b21671048 Mon Sep 17 00:00:00 2001 From: Nucleus Date: Wed, 27 Dec 2023 17:52:52 +0100 Subject: [PATCH 20/61] move getSeverity() to Severity enum --- lib/class/class_WarnMessage.dart | 4 ++-- lib/enums/Severity.dart | 41 ++++++++++++++++++-------------- lib/services/getData.dart | 10 ++++---- lib/services/sortWarnings.dart | 4 ++-- 4 files changed, 32 insertions(+), 27 deletions(-) diff --git a/lib/class/class_WarnMessage.dart b/lib/class/class_WarnMessage.dart index 3417ca53..cda0ea2b 100644 --- a/lib/class/class_WarnMessage.dart +++ b/lib/class/class_WarnMessage.dart @@ -106,7 +106,7 @@ class WarnMessage { category: json["info"][0]["category"][0] ?? "?", event: json["info"][0]["event"] ?? "?", urgency: json["info"][0]["urgency"] ?? "?", - severity: getSeverity(json["info"][0]["severity"].toString().toLowerCase()), + severity: Severity.getSeverity(json["info"][0]["severity"].toString().toLowerCase()), certainty: getCertainty(json["info"][0]["certainty"].toString().toLowerCase()), effective: json["info"][0]["effective"] ?? "", onset: json["info"][0]["onset"] ?? "", @@ -138,7 +138,7 @@ class WarnMessage { category: json["event"] ?? "?", // missing event: json["event"] ?? "?", urgency: "?", - severity: getSeverity(json["severity"]), + severity: Severity.getSeverity(json["severity"]), certainty: getCertainty(""), // missing effective: "", // missing onset: json["onset"] ?? "", // m diff --git a/lib/enums/Severity.dart b/lib/enums/Severity.dart index 77472cb0..647fbd05 100644 --- a/lib/enums/Severity.dart +++ b/lib/enums/Severity.dart @@ -1,31 +1,36 @@ enum Severity { - minor, - moderate, extreme, - severe; + severe, + moderate, + minor; String toJson() => name; static Severity fromJson(String json) => values.byName(json); -} -/// extract the severity from the string and return the corresponding enum -Severity getSeverity(String severity) { - for (Severity sev in Severity.values) { - if (sev.name == severity) { - return sev; + static double getIndexFromSeverity(Severity notificationLevel) { + final severities = Severity.values; + for (int i = 0; i < severities.length; i++) { + if (severities[i] == notificationLevel) { + return i.toDouble(); + } } - } - return Severity.minor; -} + return 0; + } -double getIndexFromSeverity(Severity notificationLevel) { - final severities = Severity.values; - for (int i = 0; i < severities.length; i++) { - if (severities[i] == notificationLevel) { - return i.toDouble(); + /// extract the severity from the string and return the corresponding enum + static Severity getSeverity(String severity) { + for (Severity sev in Severity.values) { + if (sev.name == severity) { + return sev; + } } + + return Severity.minor; } - return 0; } + + + + diff --git a/lib/services/getData.dart b/lib/services/getData.dart index 6de5fe8e..e99f7d81 100644 --- a/lib/services/getData.dart +++ b/lib/services/getData.dart @@ -93,7 +93,7 @@ Future getData(bool useEtag) async { category: _data[i]["info"][0]["category"][0] ?? "?", event: _data[i]["info"][0]["event"] ?? "?", urgency: _data[i]["info"][0]["urgency"] ?? "?", - severity: getSeverity( + severity: Severity.getSeverity( _data[i]["info"][0]["severity"].toString().toLowerCase()), certainty: getCertainty( _data[i]["info"][0]["certainty"].toString().toLowerCase()), @@ -189,7 +189,7 @@ Future getData(bool useEtag) async { category: _data[i]["info"][0]["category"][0] ?? "?", event: _data[i]["info"][0]["event"] ?? "?", urgency: _data[i]["info"][0]["urgency"] ?? "?", - severity: getSeverity( + severity: Severity.getSeverity( _data[i]["info"][0]["severity"].toString().toLowerCase()), certainty: getCertainty( _data[i]["info"][0]["certainty"].toString().toLowerCase()), @@ -287,7 +287,7 @@ Future getData(bool useEtag) async { category: _data[i]["info"][0]["category"][0] ?? "?", event: _data[i]["info"][0]["event"] ?? "?", urgency: _data[i]["info"][0]["urgency"] ?? "?", - severity: getSeverity( + severity: Severity.getSeverity( _data[i]["info"][0]["severity"].toString().toLowerCase()), certainty: getCertainty( _data[i]["info"][0]["certainty"].toString().toLowerCase()), @@ -387,7 +387,7 @@ Future getData(bool useEtag) async { category: _data[i]["info"][0]["category"][0] ?? "?", event: _data[i]["info"][0]["event"] ?? "?", urgency: _data[i]["info"][0]["urgency"] ?? "?", - severity: getSeverity( + severity: Severity.getSeverity( _data[i]["info"][0]["severity"].toString().toLowerCase()), certainty: getCertainty( _data[i]["info"][0]["certainty"].toString().toLowerCase()), @@ -483,7 +483,7 @@ Future getData(bool useEtag) async { category: _data[i]["info"][0]["category"][0] ?? "?", event: _data[i]["info"][0]["event"] ?? "?", urgency: _data[i]["info"][0]["urgency"] ?? "?", - severity: getSeverity( + severity: Severity.getSeverity( _data[i]["info"][0]["severity"].toString().toLowerCase()), certainty: getCertainty( _data[i]["info"][0]["certainty"].toString().toLowerCase()), diff --git a/lib/services/sortWarnings.dart b/lib/services/sortWarnings.dart index d6f203e7..1797f7c3 100644 --- a/lib/services/sortWarnings.dart +++ b/lib/services/sortWarnings.dart @@ -19,8 +19,8 @@ int convertSourceToInt(String source) { void sortWarnings(List list) { if (userPreferences.sortWarningsBy == "severity") { - list.sort((a, b) => getIndexFromSeverity(b.severity) - .compareTo(getIndexFromSeverity(a.severity))); + list.sort((a, b) => Severity.getIndexFromSeverity(b.severity) + .compareTo(Severity.getIndexFromSeverity(a.severity))); } else if (userPreferences.sortWarningsBy == "date") { list.sort((a, b) => b.sent.compareTo(a.sent)); } else if (userPreferences.sortWarningsBy == "source") { From 1c53c2f016417db6c071c60cf312199863431b20 Mon Sep 17 00:00:00 2001 From: Nucleus Date: Wed, 27 Dec 2023 17:55:34 +0100 Subject: [PATCH 21/61] Change the label of the slider to obtain a descending order of the notification settings --- ...NotificationPreferencesListTileWidget.dart | 236 +++++++++--------- 1 file changed, 117 insertions(+), 119 deletions(-) diff --git a/lib/widgets/NotificationPreferencesListTileWidget.dart b/lib/widgets/NotificationPreferencesListTileWidget.dart index 96da9f0a..bacc5949 100644 --- a/lib/widgets/NotificationPreferencesListTileWidget.dart +++ b/lib/widgets/NotificationPreferencesListTileWidget.dart @@ -26,23 +26,23 @@ class _NotificationPreferencesListTileWidgetState switch (sliderValue.toInt()) { case 0: return AppLocalizations.of(context)! - .notification_settings_notify_by_minor; + .notification_settings_notify_by_extreme; case 1: return AppLocalizations.of(context)! - .notification_settings_notify_by_moderate; + .notification_settings_notify_by_severe; case 2: return AppLocalizations.of(context)! - .notification_settings_notify_by_severe; + .notification_settings_notify_by_moderate; case 3: return AppLocalizations.of(context)! - .notification_settings_notify_by_extreme; + .notification_settings_notify_by_minor; default: return "Error"; } } /// return the description for the given source - String getDescriptionForEventSetting(WarningSource source) { + String _getDescriptionForEventSetting(WarningSource source) { switch (source) { case WarningSource.dwd: return AppLocalizations.of(context)!.source_dwd_description; @@ -65,7 +65,7 @@ class _NotificationPreferencesListTileWidgetState } /// decide if a source can be disabled - bool isTogglableSource(WarningSource source) { + bool _isTogglableSource(WarningSource source) { switch (source) { case WarningSource.dwd: return true; @@ -86,122 +86,120 @@ class _NotificationPreferencesListTileWidgetState @override Widget build(BuildContext context) { - return widget.notificationPreferences.warningSource == - WarningSource.alertSwiss && - !userPreferences.activateAlertSwiss - ? SizedBox() // hide alert swiss if not activated - : ListTile( - contentPadding: settingsTileListPadding, - title: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Text( - widget.notificationPreferences.warningSource.name - .toUpperCase(), - style: Theme.of(context).textTheme.titleMedium, - ), - // show a switch when source can be disabled - isTogglableSource(widget.notificationPreferences.warningSource) - ? Switch( - value: - widget.notificationPreferences.disabled, - onChanged: (value) { - // the slider will be hidden when source is disabled - if (value) { - setState(() { - widget.notificationPreferences.disabled = false; - }); - } else { - setState(() { - widget.notificationPreferences.disabled = true; - }); - } - saveSettings(); - }, - ) - : SizedBox(), - ], + if (widget.notificationPreferences.warningSource == + WarningSource.alertSwiss && + !userPreferences.activateAlertSwiss) { + return SizedBox(); + } else { + return ListTile( + contentPadding: settingsTileListPadding, + title: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text( + widget.notificationPreferences.warningSource.name.toUpperCase(), + style: Theme.of(context).textTheme.titleMedium, ), - subtitle: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( - getDescriptionForEventSetting( - widget.notificationPreferences.warningSource), - style: Theme.of(context).textTheme.bodyMedium), - // hide the slider when source is disabled - isTogglableSource(widget.notificationPreferences.warningSource) && - widget.notificationPreferences.disabled - ? Container( - padding: EdgeInsets.only(top: 5), - child: Text( - "Source disabled - you won't get a notification"), //@todo translate - ) - : Column( - children: [ - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - mainAxisSize: MainAxisSize.max, - children: [ - Icon( - Icons.notifications_active, - color: Colors.red, - ), - Flexible( - child: Slider( - label: getLabelForWarningSeverity( - getIndexFromSeverity(widget - .notificationPreferences - .notificationLevel)), - divisions: 3, - min: 0, - max: 3, - value: getIndexFromSeverity(widget - .notificationPreferences - .notificationLevel), - onChanged: (value) { - setState( - () { - final notificationLevel = Severity.values[value.toInt()]; + // show a switch when source can be disabled + if (_isTogglableSource( + widget.notificationPreferences.warningSource)) + Switch( + value: !widget.notificationPreferences.disabled, + onChanged: (value) { + // the slider will be hidden when source is disabled + setState(() { + widget.notificationPreferences.disabled = !value; + }); + saveSettings(); + }, + ) + else + SizedBox(), + ], + ), + subtitle: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + _getDescriptionForEventSetting( + widget.notificationPreferences.warningSource), + style: Theme.of(context).textTheme.bodyMedium), + // hide the slider when source is disabled + if (_isTogglableSource( + widget.notificationPreferences.warningSource) && + widget.notificationPreferences.disabled) + Container( + padding: EdgeInsets.only(top: 5), + child: Text( + "Source disabled - you won't get a notification"), //@todo translate + ) + else + Column( + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + mainAxisSize: MainAxisSize.max, + children: [ + Icon( + Icons.notifications_active, + color: Colors.red, + ), + Flexible( + child: Slider( + label: getLabelForWarningSeverity( + Severity.getIndexFromSeverity(widget + .notificationPreferences.notificationLevel)), + divisions: 3, + min: 0, + max: 3, + value: Severity.getIndexFromSeverity( + widget.notificationPreferences.notificationLevel), + onChanged: (value) { + setState( + () { + final notificationLevel = + Severity.values[value.toInt()]; - print(widget.notificationPreferences - .warningSource.name + ":" + notificationLevel.toString()); + print(widget.notificationPreferences + .warningSource.name + + ":" + + notificationLevel.toString()); - // update notification level with slider value - widget.notificationPreferences - .notificationLevel = - notificationLevel; - }, - ); - }, - onChangeEnd: (value) { - // save settings, after change is complete - saveSettings(); - }, - ), - ), - Icon( - Icons.notifications, - color: Colors.orangeAccent, - ), - ], - ), - Padding( - padding: const EdgeInsets.only(left: 30, right: 30), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Text("Gering"), // @todo translation - Text("Mittel"), - Text("extreme"), - Text("severe") - ], - ), - ) - ], + // update notification level with slider value + widget.notificationPreferences + .notificationLevel = notificationLevel; + }, + ); + }, + onChangeEnd: (value) { + // save settings, after change is complete + saveSettings(); + }, + ), ), - ], - ), - ); + Icon( + Icons.notifications, + color: Colors.orangeAccent, + ), + ], + ), + Padding( + padding: const EdgeInsets.only(left: 30, right: 30), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text("extreme"), // @todo translation + Text("severe"), + Text("moderate"), + Text("minor"), + ], + ), + ) + ], + ), + ], + ), + ); + } } } From 11fb26b0a7642dd231c242131ea4ee90b9481dd2 Mon Sep 17 00:00:00 2001 From: Nucleus Date: Wed, 27 Dec 2023 20:13:21 +0100 Subject: [PATCH 22/61] move getIndexFromWarningSource to enum --- lib/enums/WarningSource.dart | 11 +++++++++++ lib/services/sortWarnings.dart | 20 +++----------------- 2 files changed, 14 insertions(+), 17 deletions(-) diff --git a/lib/enums/WarningSource.dart b/lib/enums/WarningSource.dart index 1c3043f1..c50bc077 100644 --- a/lib/enums/WarningSource.dart +++ b/lib/enums/WarningSource.dart @@ -25,4 +25,15 @@ enum WarningSource { return WarningSource.other; } } + + /// used to sort warning + static int getIndexFromWarningSource(WarningSource source) { + final sources = WarningSource.values; + for (int i = 0; i < sources.length; i++) { + if (sources[i] == source) { + return i.toInt(); + } + } + return 0; + } } diff --git a/lib/services/sortWarnings.dart b/lib/services/sortWarnings.dart index 1797f7c3..9e67b993 100644 --- a/lib/services/sortWarnings.dart +++ b/lib/services/sortWarnings.dart @@ -1,22 +1,8 @@ +import 'package:foss_warn/enums/WarningSource.dart'; import '../class/class_WarnMessage.dart'; import '../enums/Severity.dart'; import '../main.dart'; -/// used to sort warning -int convertSourceToInt(String source) { - switch (source) { - case "MOWAS": - return 0; - case "KATWARN": - return 1; - case "BIWAPP": - return 2; - case "DWD": - return 3; - } - return 0; -} - void sortWarnings(List list) { if (userPreferences.sortWarningsBy == "severity") { list.sort((a, b) => Severity.getIndexFromSeverity(b.severity) @@ -24,7 +10,7 @@ void sortWarnings(List list) { } else if (userPreferences.sortWarningsBy == "date") { list.sort((a, b) => b.sent.compareTo(a.sent)); } else if (userPreferences.sortWarningsBy == "source") { - list.sort((a, b) => convertSourceToInt(b.publisher) - .compareTo(convertSourceToInt(a.publisher))); + list.sort((a, b) => WarningSource.getIndexFromWarningSource(b.source) + .compareTo(WarningSource.getIndexFromWarningSource(a.source))); } } From f6b08c4fad278b7d3b851eaec31794fbed74fdff Mon Sep 17 00:00:00 2001 From: Mats Date: Thu, 28 Dec 2023 15:04:22 +0100 Subject: [PATCH 23/61] Reorder WarningSource enum and fix default index --- lib/enums/WarningSource.dart | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/lib/enums/WarningSource.dart b/lib/enums/WarningSource.dart index c50bc077..edca864d 100644 --- a/lib/enums/WarningSource.dart +++ b/lib/enums/WarningSource.dart @@ -1,10 +1,10 @@ enum WarningSource { - mowas, + alertSwiss, biwapp, - katwarn, dwd, + katwarn, lhp, - alertSwiss, + mowas other; String toJson() => name; @@ -13,14 +13,14 @@ enum WarningSource { switch (name.toUpperCase()) { case "ALERT SWISS": return WarningSource.alertSwiss; - case "MOWAS": - return WarningSource.mowas; - case "KATWARN": - return WarningSource.katwarn; case "DWD": return WarningSource.dwd; + case "KATWARN": + return WarningSource.katwarn; case "LHP": - return WarningSource.lhp; + return WarningSource.lhp; + case "MOWAS": + return WarningSource.mowas; default: return WarningSource.other; } @@ -34,6 +34,8 @@ enum WarningSource { return i.toInt(); } } - return 0; + + // default return value: index of WarningSource.other + return 6; } } From 730544a076442284cc76e01d010b582eff05455c Mon Sep 17 00:00:00 2001 From: Mats Date: Thu, 28 Dec 2023 15:05:57 +0100 Subject: [PATCH 24/61] Fix default index in Severity --- lib/enums/Severity.dart | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/enums/Severity.dart b/lib/enums/Severity.dart index 647fbd05..5253e949 100644 --- a/lib/enums/Severity.dart +++ b/lib/enums/Severity.dart @@ -15,7 +15,8 @@ enum Severity { } } - return 0; + // default return value: index of Severity.minor + return 3; } /// extract the severity from the string and return the corresponding enum From 2b3625182c1372d7cea9ecd747175b84f77cb1f5 Mon Sep 17 00:00:00 2001 From: Nucleus Date: Thu, 28 Dec 2023 15:41:05 +0100 Subject: [PATCH 25/61] use unique IDs, use groups and add description to channels --- lib/class/class_NotificationService.dart | 101 +++++++++++++++++------ 1 file changed, 76 insertions(+), 25 deletions(-) diff --git a/lib/class/class_NotificationService.dart b/lib/class/class_NotificationService.dart index fc9cfb65..04ee0a79 100644 --- a/lib/class/class_NotificationService.dart +++ b/lib/class/class_NotificationService.dart @@ -2,6 +2,7 @@ import 'package:flutter_local_notifications/flutter_local_notifications.dart'; import 'package:foss_warn/services/translateAndColorizeWarning.dart'; import 'package:rxdart/rxdart.dart'; import 'package:flutter/material.dart'; + /// /// ID 2: Status notification /// ID 3: No Places selected warning @@ -14,16 +15,13 @@ class NotificationService { static Future _notificationsDetails(String channel) async { return NotificationDetails( android: AndroidNotificationDetails( - 'foss_warn_notifications_' + channel.trim().toLowerCase(), + 'de.nucleus.foss_warn.notifications_' + channel.trim().toLowerCase(), "Warnstufe: " + translateWarningSeverity(channel), - channelDescription: - 'FOSS Warn notifications for ' + channel.trim().toLowerCase(), groupKey: "FossWarnWarnings", - category: AndroidNotificationCategory.alarm, - importance: Importance.max, + category: AndroidNotificationCategory.message, priority: Priority.max, - //enable multiline notification + // enable multiline notification styleInformation: BigTextStyleInformation(''), color: Colors.red, // makes the icon red, ledColor: Colors.red, @@ -36,7 +34,7 @@ class NotificationService { static Future _statusNotificationsDetails() async { return NotificationDetails( android: AndroidNotificationDetails( - 'foss_warn_status', + 'de.nucleus.foss_warn.notifications_state', 'Statusanzeige', channelDescription: 'Status der Hintergrund Updates', groupKey: "FossWarnService", @@ -141,21 +139,74 @@ class NotificationService { // init the different notifications channels try { - await androidNotificationPlugin.createNotificationChannel( - AndroidNotificationChannel( - "foss_warn_notifications_minor", "Warnstufe: Gering")); + await androidNotificationPlugin.createNotificationChannelGroup( + AndroidNotificationChannelGroup( + "de.nucleus.foss_warn.notifications_emergency_information", + "Gefahreninformationen", + description: "Benachrichtigungen zu Gefahrenmeldungen")); - await androidNotificationPlugin.createNotificationChannel( - AndroidNotificationChannel( - "foss_warn_notifications_moderate", "Warnstufe: Mittel")); + await androidNotificationPlugin.createNotificationChannelGroup( + AndroidNotificationChannelGroup( + "de.nucleus.foss_warn.notifications_other", "Sonstiges", + description: "Sonstige Benachrichtigungen")); - await androidNotificationPlugin.createNotificationChannel( - AndroidNotificationChannel( - "foss_warn_notifications_severe", "Warnstufe: Schwer")); + await androidNotificationPlugin + .createNotificationChannel(AndroidNotificationChannel( + "de.nucleus.foss_warn.notifications_minor", + "Warnstufe: Gering", + description: + "Warnung vor einer Beeinträchtigung des normalen Tagesablaufs.", + groupId: "de.nucleus.foss_warn.notifications_emergency_information", + importance: Importance.max, + )); - await androidNotificationPlugin.createNotificationChannel( - AndroidNotificationChannel( - "foss_warn_notifications_extreme", "Warnstufe: Extrem")); + await androidNotificationPlugin + .createNotificationChannel(AndroidNotificationChannel( + "de.nucleus.foss_warn.notifications_moderate", + "Warnstufe: Mittel", + description: + "Eine Warnung vor einer starken Beeinträchtigung des normalen Tagesablaufs.", + groupId: "de.nucleus.foss_warn.notifications_emergency_information", + importance: Importance.max, + )); + + await androidNotificationPlugin + .createNotificationChannel(AndroidNotificationChannel( + "de.nucleus.foss_warn.notifications_severe", + "Warnstufe: Schwer", + description: + "Eine Warnung vor einer Gefahr, die ihre Gesundheit, ihr Eigentum und/oder öffentliche Infrastruktur beeinträchtigen kann.", + groupId: "de.nucleus.foss_warn.notifications_emergency_information", + importance: Importance.max, + )); + + await androidNotificationPlugin + .createNotificationChannel(AndroidNotificationChannel( + "de.nucleus.foss_warn.notifications_extreme", + "Warnstufe: Extrem", + description: + "Eine Warnung vor einer Gefahr, die sich kurzfristig signifikant auf ihre Gesundheit, ihr Eigentum und/oder öffentliche Infrastruktur auswirken kann.", + groupId: "de.nucleus.foss_warn.notifications_emergency_information", + importance: Importance.max, + )); + + await androidNotificationPlugin + .createNotificationChannel(AndroidNotificationChannel( + "de.nucleus.foss_warn.notifications_state", + "Statusanzeige", + description: "Zeit den aktuellen Status der Hintergrundupdates an.", + groupId: "de.nucleus.foss_warn.notifications_other", + importance: Importance.max, + )); + + await androidNotificationPlugin + .createNotificationChannel(AndroidNotificationChannel( + "de.nucleus.foss_warn.notifications_other", + "Sonstiges", + description: "Sonstige Benachrichtigungen", + groupId: "de.nucleus.foss_warn.notifications_other", + importance: Importance.max, + )); } catch (e) { print("Error while creating notification channels: " + e.toString()); } @@ -179,12 +230,12 @@ class NotificationService { Future cleanUpNotificationChannels() async { List channelIds = []; - channelIds.add("foss_warn_notifications_minor"); - channelIds.add("foss_warn_notifications_severe"); - channelIds.add("foss_warn_notifications_moderate"); - channelIds.add("foss_warn_notifications_extreme"); - channelIds.add("foss_warn_status"); - channelIds.add("foss_warn_notifications_other"); + channelIds.add("de.nucleus.foss_warn.notifications_minor"); + channelIds.add("de.nucleus.foss_warn.notifications_moderate"); + channelIds.add("de.nucleus.foss_warn.notifications_severe"); + channelIds.add("de.nucleus.foss_warn.notifications_extreme"); + channelIds.add("de.nucleus.foss_warn.notifications_state"); + channelIds.add("de.nucleus.foss_warn.notifications_other"); print("[android notification channels]"); List? temp = From 82a9d9f1060e5d17a08b83f3736482b04aa3bfb8 Mon Sep 17 00:00:00 2001 From: Nucleus Date: Thu, 28 Dec 2023 15:41:37 +0100 Subject: [PATCH 26/61] rename methode from getSeverity to fromString --- lib/class/class_WarnMessage.dart | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/class/class_WarnMessage.dart b/lib/class/class_WarnMessage.dart index cda0ea2b..6203ae79 100644 --- a/lib/class/class_WarnMessage.dart +++ b/lib/class/class_WarnMessage.dart @@ -106,7 +106,7 @@ class WarnMessage { category: json["info"][0]["category"][0] ?? "?", event: json["info"][0]["event"] ?? "?", urgency: json["info"][0]["urgency"] ?? "?", - severity: Severity.getSeverity(json["info"][0]["severity"].toString().toLowerCase()), + severity: Severity.fromString(json["info"][0]["severity"].toString().toLowerCase()), certainty: getCertainty(json["info"][0]["certainty"].toString().toLowerCase()), effective: json["info"][0]["effective"] ?? "", onset: json["info"][0]["onset"] ?? "", @@ -138,7 +138,7 @@ class WarnMessage { category: json["event"] ?? "?", // missing event: json["event"] ?? "?", urgency: "?", - severity: Severity.getSeverity(json["severity"]), + severity: Severity.fromString(json["severity"]), certainty: getCertainty(""), // missing effective: "", // missing onset: json["onset"] ?? "", // m From d22f0b4500196959f3f208e67f8722fd2bb0926a Mon Sep 17 00:00:00 2001 From: Nucleus Date: Thu, 28 Dec 2023 15:41:41 +0100 Subject: [PATCH 27/61] rename methode from getSeverity to fromString --- lib/services/getData.dart | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/lib/services/getData.dart b/lib/services/getData.dart index e99f7d81..a0e6a8cc 100644 --- a/lib/services/getData.dart +++ b/lib/services/getData.dart @@ -93,7 +93,7 @@ Future getData(bool useEtag) async { category: _data[i]["info"][0]["category"][0] ?? "?", event: _data[i]["info"][0]["event"] ?? "?", urgency: _data[i]["info"][0]["urgency"] ?? "?", - severity: Severity.getSeverity( + severity: Severity.fromString( _data[i]["info"][0]["severity"].toString().toLowerCase()), certainty: getCertainty( _data[i]["info"][0]["certainty"].toString().toLowerCase()), @@ -189,7 +189,7 @@ Future getData(bool useEtag) async { category: _data[i]["info"][0]["category"][0] ?? "?", event: _data[i]["info"][0]["event"] ?? "?", urgency: _data[i]["info"][0]["urgency"] ?? "?", - severity: Severity.getSeverity( + severity: Severity.fromString( _data[i]["info"][0]["severity"].toString().toLowerCase()), certainty: getCertainty( _data[i]["info"][0]["certainty"].toString().toLowerCase()), @@ -287,7 +287,7 @@ Future getData(bool useEtag) async { category: _data[i]["info"][0]["category"][0] ?? "?", event: _data[i]["info"][0]["event"] ?? "?", urgency: _data[i]["info"][0]["urgency"] ?? "?", - severity: Severity.getSeverity( + severity: Severity.fromString( _data[i]["info"][0]["severity"].toString().toLowerCase()), certainty: getCertainty( _data[i]["info"][0]["certainty"].toString().toLowerCase()), @@ -387,7 +387,7 @@ Future getData(bool useEtag) async { category: _data[i]["info"][0]["category"][0] ?? "?", event: _data[i]["info"][0]["event"] ?? "?", urgency: _data[i]["info"][0]["urgency"] ?? "?", - severity: Severity.getSeverity( + severity: Severity.fromString( _data[i]["info"][0]["severity"].toString().toLowerCase()), certainty: getCertainty( _data[i]["info"][0]["certainty"].toString().toLowerCase()), @@ -483,7 +483,7 @@ Future getData(bool useEtag) async { category: _data[i]["info"][0]["category"][0] ?? "?", event: _data[i]["info"][0]["event"] ?? "?", urgency: _data[i]["info"][0]["urgency"] ?? "?", - severity: Severity.getSeverity( + severity: Severity.fromString( _data[i]["info"][0]["severity"].toString().toLowerCase()), certainty: getCertainty( _data[i]["info"][0]["certainty"].toString().toLowerCase()), From 744650cfcaf145e4adb6c6e6a92931c7fbefc75a Mon Sep 17 00:00:00 2001 From: Nucleus Date: Thu, 28 Dec 2023 15:41:45 +0100 Subject: [PATCH 28/61] rename methode from getSeverity to fromString --- lib/enums/Severity.dart | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/lib/enums/Severity.dart b/lib/enums/Severity.dart index 647fbd05..28364110 100644 --- a/lib/enums/Severity.dart +++ b/lib/enums/Severity.dart @@ -7,6 +7,16 @@ enum Severity { String toJson() => name; static Severity fromJson(String json) => values.byName(json); + /// extract the severity from the string and return the corresponding enum + static Severity fromString(String severity) { + for (Severity sev in Severity.values) { + if (sev.name == severity) { + return sev; + } + } + return Severity.minor; + } + static double getIndexFromSeverity(Severity notificationLevel) { final severities = Severity.values; for (int i = 0; i < severities.length; i++) { @@ -17,18 +27,6 @@ enum Severity { return 0; } - - /// extract the severity from the string and return the corresponding enum - static Severity getSeverity(String severity) { - for (Severity sev in Severity.values) { - if (sev.name == severity) { - return sev; - } - } - - return Severity.minor; - } - } From 421c88b26faf384c2425144772a3a2aa42cd32f0 Mon Sep 17 00:00:00 2001 From: Nucleus Date: Thu, 28 Dec 2023 15:42:12 +0100 Subject: [PATCH 29/61] add missing biwapp source --- lib/enums/WarningSource.dart | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/lib/enums/WarningSource.dart b/lib/enums/WarningSource.dart index c50bc077..dc0fc49f 100644 --- a/lib/enums/WarningSource.dart +++ b/lib/enums/WarningSource.dart @@ -9,8 +9,8 @@ enum WarningSource { String toJson() => name; - static WarningSource fromString(String name) { - switch (name.toUpperCase()) { + static WarningSource fromString(String source) { + switch (source.toUpperCase()) { case "ALERT SWISS": return WarningSource.alertSwiss; case "MOWAS": @@ -19,6 +19,8 @@ enum WarningSource { return WarningSource.katwarn; case "DWD": return WarningSource.dwd; + case "BIWAPP": + return WarningSource.biwapp; case "LHP": return WarningSource.lhp; default: From b3612483f65d3262cbe7e05bf474f5db2db11f9f Mon Sep 17 00:00:00 2001 From: Nucleus Date: Thu, 28 Dec 2023 15:49:55 +0100 Subject: [PATCH 30/61] return index 6 as default --- lib/enums/WarningSource.dart | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/enums/WarningSource.dart b/lib/enums/WarningSource.dart index b302547f..cad00bde 100644 --- a/lib/enums/WarningSource.dart +++ b/lib/enums/WarningSource.dart @@ -36,6 +36,7 @@ enum WarningSource { return i.toInt(); } } - return 0; + // default return value: index of WarningSource.other + return 6; } } From fecb5bbca7c3df3c3885a78ac5bc37f94f9d5411 Mon Sep 17 00:00:00 2001 From: Mats Date: Thu, 28 Dec 2023 16:00:26 +0100 Subject: [PATCH 31/61] Reorder WarningSource values alphabetically --- lib/enums/WarningSource.dart | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/lib/enums/WarningSource.dart b/lib/enums/WarningSource.dart index cad00bde..b8ac5aba 100644 --- a/lib/enums/WarningSource.dart +++ b/lib/enums/WarningSource.dart @@ -13,22 +13,21 @@ enum WarningSource { switch (source.toUpperCase()) { case "ALERT SWISS": return WarningSource.alertSwiss; - case "MOWAS": - return WarningSource.mowas; - case "KATWARN": - return WarningSource.katwarn; + case "BIWAPP": + return WarningSource.biwapp; case "DWD": return WarningSource.dwd; - case "BIWAPP": - return WarningSource.biwapp; + case "KATWARN": + return WarningSource.katwarn; case "LHP": - return WarningSource.lhp; + return WarningSource.lhp; + case "MOWAS": + return WarningSource.mowas; default: return WarningSource.other; } } - /// used to sort warning static int getIndexFromWarningSource(WarningSource source) { final sources = WarningSource.values; for (int i = 0; i < sources.length; i++) { @@ -36,6 +35,7 @@ enum WarningSource { return i.toInt(); } } + // default return value: index of WarningSource.other return 6; } From c1e9074bdcc38b72071ed57033567247903c8b7f Mon Sep 17 00:00:00 2001 From: Nucleus Date: Thu, 28 Dec 2023 16:59:48 +0100 Subject: [PATCH 32/61] fix wrong channel importance --- lib/class/class_NotificationService.dart | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/class/class_NotificationService.dart b/lib/class/class_NotificationService.dart index 04ee0a79..77b7f115 100644 --- a/lib/class/class_NotificationService.dart +++ b/lib/class/class_NotificationService.dart @@ -196,7 +196,7 @@ class NotificationService { "Statusanzeige", description: "Zeit den aktuellen Status der Hintergrundupdates an.", groupId: "de.nucleus.foss_warn.notifications_other", - importance: Importance.max, + importance: Importance.low, )); await androidNotificationPlugin @@ -205,7 +205,7 @@ class NotificationService { "Sonstiges", description: "Sonstige Benachrichtigungen", groupId: "de.nucleus.foss_warn.notifications_other", - importance: Importance.max, + importance: Importance.defaultImportance, )); } catch (e) { print("Error while creating notification channels: " + e.toString()); From 9df4843dcbe68e6038faa76de9f5b044b044f5b9 Mon Sep 17 00:00:00 2001 From: Anonymous Date: Fri, 29 Dec 2023 16:06:38 +0000 Subject: [PATCH 33/61] Translated using Weblate (English) Currently translated at 100.0% (220 of 220 strings) Translation: FOSS Warn/FOSS Warn-App Translate-URL: https://hosted.weblate.org/projects/foss-warn/foss-warn-app/en/ --- lib/l10n/app_en.arb | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/lib/l10n/app_en.arb b/lib/l10n/app_en.arb index 2e7cfabd..2ea39f8d 100644 --- a/lib/l10n/app_en.arb +++ b/lib/l10n/app_en.arb @@ -428,5 +428,15 @@ "legacy_warning_dialog_title": "Version updated to", "@legacy_warning_dialog_title": {}, "legacy_warning_dialog_text": "FOSS Warn has been updated to a new version improving the internal structure of the app. The shift has caused all settings and your saved locations to be reset. Please check your settings and add back your wanted locations.\n\nWe apologize for any inconvenience.", - "@legacy_warning_dialog_text": {} + "@legacy_warning_dialog_text": {}, + "notification_settings_slidervalue_extreme": "extreme", + "@notification_settings_slidervalue_extreme": {}, + "notification_settings_slidervalue_moderate": "moderate", + "@notification_settings_slidervalue_moderate": {}, + "notification_settings_source_disabled": "Source disabled - you won't get a notification", + "@notification_settings_source_disabled": {}, + "notification_settings_slidervalue_severe": "severe", + "@notification_settings_slidervalue_severe": {}, + "notification_settings_slidervalue_minor": "minor", + "@notification_settings_slidervalue_minor": {} } From 055294e6f8069bf27df633b6837de6abbb5525ba Mon Sep 17 00:00:00 2001 From: Nucleus Date: Thu, 28 Dec 2023 15:41:05 +0000 Subject: [PATCH 34/61] Translated using Weblate (German) Currently translated at 100.0% (220 of 220 strings) Translation: FOSS Warn/FOSS Warn-App Translate-URL: https://hosted.weblate.org/projects/foss-warn/foss-warn-app/de/ --- lib/l10n/app_de.arb | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/lib/l10n/app_de.arb b/lib/l10n/app_de.arb index 66dacf5a..1a6248a8 100644 --- a/lib/l10n/app_de.arb +++ b/lib/l10n/app_de.arb @@ -428,5 +428,15 @@ "legacy_warning_dialog_title": "Version aktualisiert auf", "@legacy_warning_dialog_title": {}, "legacy_warning_dialog_text": "FOSS Warn wurde auf eine neue Version aktualisiert, die größere Verbesserungen in der inneren Struktur enthält. Dadurch mussten wir deine Appeinstellungen und gespeicherten Orte zurücksetzen. Bitte prüfe deine Einstellungen und füge deine Orte wieder neu hinzu.\n\nWir entschuldigen uns für den notwendigen Umstand.", - "@legacy_warning_dialog_text": {} + "@legacy_warning_dialog_text": {}, + "notification_settings_slidervalue_extreme": "Extrem", + "@notification_settings_slidervalue_extreme": {}, + "notification_settings_slidervalue_moderate": "Moderat", + "@notification_settings_slidervalue_moderate": {}, + "notification_settings_source_disabled": "Quellen deaktiviert - Du bekommst keine Benachrichtigungen", + "@notification_settings_source_disabled": {}, + "notification_settings_slidervalue_severe": "Schwer", + "@notification_settings_slidervalue_severe": {}, + "notification_settings_slidervalue_minor": "Gering", + "@notification_settings_slidervalue_minor": {} } From 835d6ffff9a8ae6dbc38815d4f06a00d377cd390 Mon Sep 17 00:00:00 2001 From: Nucleus Date: Thu, 28 Dec 2023 15:46:05 +0000 Subject: [PATCH 35/61] Translated using Weblate (French) Currently translated at 100.0% (220 of 220 strings) Translation: FOSS Warn/FOSS Warn-App Translate-URL: https://hosted.weblate.org/projects/foss-warn/foss-warn-app/fr/ --- lib/l10n/app_fr.arb | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/lib/l10n/app_fr.arb b/lib/l10n/app_fr.arb index ed8ca088..847eeba0 100644 --- a/lib/l10n/app_fr.arb +++ b/lib/l10n/app_fr.arb @@ -428,5 +428,15 @@ "legacy_warning_dialog_title": "Version mise à jour à", "@legacy_warning_dialog_title": {}, "legacy_warning_dialog_text": "FOSS Warn a été mis à jour vers une nouvelle version améliorant la structure interne de l'application. Ce changement a entraîné la réinitialisation de tous les paramètres et des emplacements sauvegardés. Veuillez vérifier vos paramètres et ajouter à nouveau vos emplacements souhaités.\n\nNous nous excusons pour tout inconvénient.", - "@legacy_warning_dialog_text": {} + "@legacy_warning_dialog_text": {}, + "notification_settings_slidervalue_extreme": "extrême", + "@notification_settings_slidervalue_extreme": {}, + "notification_settings_slidervalue_moderate": "modéré", + "@notification_settings_slidervalue_moderate": {}, + "notification_settings_source_disabled": "Source désactivée - vous ne recevrez pas de notification", + "@notification_settings_source_disabled": {}, + "notification_settings_slidervalue_severe": "sévères", + "@notification_settings_slidervalue_severe": {}, + "notification_settings_slidervalue_minor": "mineurs", + "@notification_settings_slidervalue_minor": {} } From fb18f39b33652bea5d4bac0d0c4536a39d55b7bf Mon Sep 17 00:00:00 2001 From: Anonymous Date: Mon, 1 Jan 2024 17:43:18 +0000 Subject: [PATCH 36/61] Translated using Weblate (English) Currently translated at 100.0% (223 of 223 strings) Translation: FOSS Warn/FOSS Warn-App Translate-URL: https://hosted.weblate.org/projects/foss-warn/foss-warn-app/en/ --- lib/l10n/app_en.arb | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/lib/l10n/app_en.arb b/lib/l10n/app_en.arb index 2ea39f8d..ddbe1cf8 100644 --- a/lib/l10n/app_en.arb +++ b/lib/l10n/app_en.arb @@ -438,5 +438,11 @@ "notification_settings_slidervalue_severe": "severe", "@notification_settings_slidervalue_severe": {}, "notification_settings_slidervalue_minor": "minor", - "@notification_settings_slidervalue_minor": {} + "@notification_settings_slidervalue_minor": {}, + "source_other_description": "General setting that is used if no more precise setting has been made.", + "@source_other_description": {}, + "source_other_title": "Other", + "@source_other_title": {}, + "notification_settings_open_sverity_explanation": "Explanation of the degree of severity", + "@notification_settings_open_sverity_explanation": {} } From 767313da1513253fb616d29d203d26f6da8846db Mon Sep 17 00:00:00 2001 From: Nucleus Date: Mon, 1 Jan 2024 18:43:18 +0100 Subject: [PATCH 37/61] Translated using Weblate (English) Currently translated at 100.0% (223 of 223 strings) Translation: FOSS Warn/FOSS Warn-App Translate-URL: https://hosted.weblate.org/projects/foss-warn/foss-warn-app/en/ --- lib/l10n/app_en.arb | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/lib/l10n/app_en.arb b/lib/l10n/app_en.arb index ddbe1cf8..13070358 100644 --- a/lib/l10n/app_en.arb +++ b/lib/l10n/app_en.arb @@ -442,7 +442,5 @@ "source_other_description": "General setting that is used if no more precise setting has been made.", "@source_other_description": {}, "source_other_title": "Other", - "@source_other_title": {}, - "notification_settings_open_sverity_explanation": "Explanation of the degree of severity", - "@notification_settings_open_sverity_explanation": {} + "@source_other_title": {} } From ddc3bc122a0ab1a56f0b8ec4fbd33ca43a1abdd0 Mon Sep 17 00:00:00 2001 From: Anonymous Date: Mon, 1 Jan 2024 17:59:13 +0000 Subject: [PATCH 38/61] Translated using Weblate (English) Currently translated at 100.0% (227 of 227 strings) Translation: FOSS Warn/FOSS Warn-App Translate-URL: https://hosted.weblate.org/projects/foss-warn/foss-warn-app/en/ --- lib/l10n/app_en.arb | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/lib/l10n/app_en.arb b/lib/l10n/app_en.arb index 13070358..ed486d8a 100644 --- a/lib/l10n/app_en.arb +++ b/lib/l10n/app_en.arb @@ -442,5 +442,15 @@ "source_other_description": "General setting that is used if no more precise setting has been made.", "@source_other_description": {}, "source_other_title": "Other", - "@source_other_title": {} + "@source_other_title": {}, + "warning _severity_explanation_dialog_headline": "Severity", + "@warning _severity_explanation_dialog_headline": {}, + "notification_settings_open_severity_explanation": "Explanations of the degree of severity", + "@notification_settings_open_severity_explanation": {}, + "notification_settings_description": "This allows you to set the alert level at which you want to receive an alert and for which alert source.", + "@notification_settings_description": {}, + "warning_severity_explanation_dialog_extrem_description": "Extraordinary threat to life or property. May have a significant short-term impact on your health, property and/or public infrastructure.", + "@warning_severity_explanation_dialog_extrem_description": {}, + "warning_severity_explanation_dialog_severe_description": "Significant threat to life or property. May affect your health, property and/or public infrastructure.", + "@warning_severity_explanation_dialog_severe_description": {} } From 54c6968116853311195a3e8d2eca767556be74d1 Mon Sep 17 00:00:00 2001 From: Nucleus Date: Mon, 1 Jan 2024 18:59:13 +0100 Subject: [PATCH 39/61] Translated using Weblate (English) Currently translated at 100.0% (227 of 227 strings) Translation: FOSS Warn/FOSS Warn-App Translate-URL: https://hosted.weblate.org/projects/foss-warn/foss-warn-app/en/ --- lib/l10n/app_en.arb | 2 -- 1 file changed, 2 deletions(-) diff --git a/lib/l10n/app_en.arb b/lib/l10n/app_en.arb index ed486d8a..60d296da 100644 --- a/lib/l10n/app_en.arb +++ b/lib/l10n/app_en.arb @@ -449,8 +449,6 @@ "@notification_settings_open_severity_explanation": {}, "notification_settings_description": "This allows you to set the alert level at which you want to receive an alert and for which alert source.", "@notification_settings_description": {}, - "warning_severity_explanation_dialog_extrem_description": "Extraordinary threat to life or property. May have a significant short-term impact on your health, property and/or public infrastructure.", - "@warning_severity_explanation_dialog_extrem_description": {}, "warning_severity_explanation_dialog_severe_description": "Significant threat to life or property. May affect your health, property and/or public infrastructure.", "@warning_severity_explanation_dialog_severe_description": {} } From 0e909b6094633dae268bbd61b6e687717cfbea1d Mon Sep 17 00:00:00 2001 From: Nucleus Date: Mon, 1 Jan 2024 19:04:32 +0100 Subject: [PATCH 40/61] Add information about the different severity levels --- .../dialogs/WarningSeverityExplanation.dart | 76 +++++++++++++++++++ 1 file changed, 76 insertions(+) create mode 100644 lib/widgets/dialogs/WarningSeverityExplanation.dart diff --git a/lib/widgets/dialogs/WarningSeverityExplanation.dart b/lib/widgets/dialogs/WarningSeverityExplanation.dart new file mode 100644 index 00000000..8a9fd331 --- /dev/null +++ b/lib/widgets/dialogs/WarningSeverityExplanation.dart @@ -0,0 +1,76 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_gen/gen_l10n/app_localizations.dart'; + +class WarningSeverityExplanation extends StatefulWidget { + const WarningSeverityExplanation({Key? key}) : super(key: key); + + @override + _WarningSeverityExplanationState createState() => _WarningSeverityExplanationState(); +} + +class _WarningSeverityExplanationState extends State { + @override + Widget build(BuildContext context) { + return AlertDialog( + title: + Text("Schweregrade"), //warning _severity_explanation_dialog_headline + content: Container( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisSize: MainAxisSize.min, + children: [ + RichText( + text: TextSpan( + text: '', + style: Theme.of(context) + .textTheme + .bodyMedium, //DefaultTextStyle.of(context).style, + children: const [ + TextSpan( + text: 'Extrem:', + style: TextStyle(fontWeight: FontWeight.bold)), + TextSpan(text: '\n'), + TextSpan( + text: //warning_severity_explanation_dialog_extreme_description + 'Außerordentliche Bedrohung für Leben oder Eigentum. Kann sich kurzfristig signifikant auf ihre Gesundheit, ihr Eigentum und/oder öffentliche Infrastruktur auswirken.'), + TextSpan(text: '\n\n'), + TextSpan( + text: 'Schwer:', + style: TextStyle(fontWeight: FontWeight.bold)), + TextSpan(text: '\n'), + TextSpan( + text: //warning_severity_explanation_dialog_severe_description + 'Erhebliche Bedrohung für Leben oder Eigentum. Kann ihre Gesundheit, ihr Eigentum und/oder öffentliche Infrastruktur beeinträchtigen.'), + TextSpan(text: '\n\n'), + TextSpan( + text: 'Moderat:', + style: TextStyle(fontWeight: FontWeight.bold)), + TextSpan(text: '\n'), + TextSpan( + text: //warning_severity_explanation_dialog_moderate_description + 'Eine Warnung vor einer möglichen Bedrohung von Leben oder Eigentum. Kann den normeln Tagesablauf stark beeinträchtigen.'), + TextSpan(text: '\n\n'), + TextSpan( + text: 'Gering:', + style: TextStyle(fontWeight: FontWeight.bold)), + TextSpan(text: '\n'), + TextSpan( + text: //warning_severity_explanation_dialog_minor_description + 'Minimale bis keine bekannte Bedrohung für Leben oder Eigentum. Kann den normalen Tagesablauf beeinträchtigen.'), + ], + ), + ), + ], + ), + ), + actions: [ + TextButton( + onPressed: () { + Navigator.of(context).pop(); + }, + child: Text(AppLocalizations.of(context)!.main_dialog_close), + ), + ], + ); + } +} From 6785572562490e066815444ab5db1f22c5f3315c Mon Sep 17 00:00:00 2001 From: Nucleus Date: Mon, 1 Jan 2024 19:05:46 +0100 Subject: [PATCH 41/61] open severity explanation dialog when pressed on the severity tag --- lib/views/WarningDetailView.dart | 158 +++++++++++++++++++------------ 1 file changed, 96 insertions(+), 62 deletions(-) diff --git a/lib/views/WarningDetailView.dart b/lib/views/WarningDetailView.dart index 81d4d664..8ef072be 100644 --- a/lib/views/WarningDetailView.dart +++ b/lib/views/WarningDetailView.dart @@ -11,9 +11,13 @@ import '../services/translateAndColorizeWarning.dart'; import 'package:share_plus/share_plus.dart'; +import '../widgets/dialogs/WarningSeverityExplanation.dart'; + class DetailScreen extends StatefulWidget { final WarnMessage _warnMessage; - const DetailScreen({Key? key, required WarnMessage warnMessage}) : _warnMessage = warnMessage, super(key: key); + const DetailScreen({Key? key, required WarnMessage warnMessage}) + : _warnMessage = warnMessage, + super(key: key); @override _DetailScreenState createState() => _DetailScreenState(); @@ -188,8 +192,8 @@ class _DetailScreenState extends State { launchUrlInBrowser(url); }, child: Text( - AppLocalizations.of(context) - !.warning_open_picture_with_browser, + AppLocalizations.of(context)! + .warning_open_picture_with_browser, style: TextStyle(color: Colors.white), ), style: TextButton.styleFrom(backgroundColor: Colors.blue))); @@ -266,37 +270,37 @@ class _DetailScreenState extends State { title: Text(widget._warnMessage.headline), actions: [ IconButton( - tooltip: AppLocalizations.of(context)!.warning_share, - onPressed: () { - final String shareText = widget._warnMessage.headline + - "\n\n" + - AppLocalizations.of(context)!.warning_from + - ": " + - formatSentDate(widget._warnMessage.sent) + - "\n\n" + - AppLocalizations.of(context)!.warning_region + - ": " + - generateAreaDescList(-1).toString().substring( - 1, generateAreaDescList(-1).toString().length - 1) + - "\n\n" + - AppLocalizations.of(context)!.warning_description + - ":\n" + - replaceHTMLTags(widget._warnMessage.description) + - " \n\n" + - AppLocalizations.of(context)!.warning_recommended_action + - ":\n" + - replaceHTMLTags(widget._warnMessage.instruction) + - "\n\n" + - AppLocalizations.of(context)!.warning_source + - ":\n" + - widget._warnMessage.publisher + - "\n\n-- " + - AppLocalizations.of(context)!.warning_shared_by_foss_warn + - " --"; - final String shareSubject = widget._warnMessage.headline; - shareWarning(context, shareText, shareSubject); - }, - icon: Icon(Icons.share), + tooltip: AppLocalizations.of(context)!.warning_share, + onPressed: () { + final String shareText = widget._warnMessage.headline + + "\n\n" + + AppLocalizations.of(context)!.warning_from + + ": " + + formatSentDate(widget._warnMessage.sent) + + "\n\n" + + AppLocalizations.of(context)!.warning_region + + ": " + + generateAreaDescList(-1).toString().substring( + 1, generateAreaDescList(-1).toString().length - 1) + + "\n\n" + + AppLocalizations.of(context)!.warning_description + + ":\n" + + replaceHTMLTags(widget._warnMessage.description) + + " \n\n" + + AppLocalizations.of(context)!.warning_recommended_action + + ":\n" + + replaceHTMLTags(widget._warnMessage.instruction) + + "\n\n" + + AppLocalizations.of(context)!.warning_source + + ":\n" + + widget._warnMessage.publisher + + "\n\n-- " + + AppLocalizations.of(context)!.warning_shared_by_foss_warn + + " --"; + final String shareSubject = widget._warnMessage.headline; + shareWarning(context, shareText, shareSubject); + }, + icon: Icon(Icons.share), ), ], ), @@ -318,7 +322,8 @@ class _DetailScreenState extends State { ": " + formatSentDate(widget._warnMessage.sent), style: TextStyle( - fontSize: userPreferences.warningFontSize, fontWeight: FontWeight.bold), + fontSize: userPreferences.warningFontSize, + fontWeight: FontWeight.bold), ), widget._warnMessage.effective != "" ? Padding( @@ -391,9 +396,11 @@ class _DetailScreenState extends State { child: Text( AppLocalizations.of(context)!.warning_event + ": " + - translateWarningCategory(widget._warnMessage.event, context), + translateWarningCategory( + widget._warnMessage.event, context), style: TextStyle( - color: Colors.white, fontSize: userPreferences.warningFontSize), + color: Colors.white, + fontSize: userPreferences.warningFontSize), ), ), Container( @@ -410,7 +417,8 @@ class _DetailScreenState extends State { translateWarningType( widget._warnMessage.messageType, context), style: TextStyle( - color: Colors.white, fontSize: userPreferences.warningFontSize), + color: Colors.white, + fontSize: userPreferences.warningFontSize), ), ), Container( @@ -421,12 +429,24 @@ class _DetailScreenState extends State { color: chooseWarningSeverityColor( widget._warnMessage.severity.name), ), - child: Text( - AppLocalizations.of(context)!.warning_severity + - ": " + - translateWarningSeverity(widget._warnMessage.severity.name), - style: TextStyle( - color: Colors.white, fontSize: userPreferences.warningFontSize), + child: InkWell( + onTap: () { + showDialog( + context: context, + builder: (BuildContext context) { + return WarningSeverityExplanation(); + }, + ); + }, + child: Text( + AppLocalizations.of(context)!.warning_severity + + ": " + + translateWarningSeverity( + widget._warnMessage.severity.name), + style: TextStyle( + color: Colors.white, + fontSize: userPreferences.warningFontSize), + ), ), ), userPreferences.showExtendedMetaData @@ -482,7 +502,8 @@ class _DetailScreenState extends State { AppLocalizations.of(context)!.warning_scope + ": " + widget._warnMessage.scope, - style: TextStyle(fontSize: userPreferences.warningFontSize), + style: TextStyle( + fontSize: userPreferences.warningFontSize), ), ), SizedBox( @@ -499,7 +520,8 @@ class _DetailScreenState extends State { AppLocalizations.of(context)!.warning_identifier + ": " + widget._warnMessage.identifier, - style: TextStyle(fontSize: userPreferences.warningFontSize), + style: TextStyle( + fontSize: userPreferences.warningFontSize), ), ), SizedBox( @@ -516,7 +538,8 @@ class _DetailScreenState extends State { AppLocalizations.of(context)!.warning_sender + ": " + widget._warnMessage.sender, - style: TextStyle(fontSize: userPreferences.warningFontSize), + style: TextStyle( + fontSize: userPreferences.warningFontSize), ), ), SizedBox( @@ -534,7 +557,8 @@ class _DetailScreenState extends State { ": " + translateWarningStatus( widget._warnMessage.status), - style: TextStyle(fontSize: userPreferences.warningFontSize), + style: TextStyle( + fontSize: userPreferences.warningFontSize), ), ), SizedBox( @@ -586,7 +610,8 @@ class _DetailScreenState extends State { fontWeight: FontWeight.bold, color: Colors.red), ) - : Text(AppLocalizations.of(context)!.warning_show_more, + : Text( + AppLocalizations.of(context)!.warning_show_more, style: TextStyle( fontWeight: FontWeight.bold, color: Colors.green)), @@ -627,12 +652,14 @@ class _DetailScreenState extends State { ? SelectableText( generateGeocodeNameList(-1).toString().substring( 1, generateGeocodeNameList(-1).toString().length - 1), - style: TextStyle(fontSize: userPreferences.warningFontSize), + style: + TextStyle(fontSize: userPreferences.warningFontSize), ) : SelectableText( generateGeocodeNameList(10).toString().substring( 1, generateGeocodeNameList(10).toString().length - 1), - style: TextStyle(fontSize: userPreferences.warningFontSize), + style: + TextStyle(fontSize: userPreferences.warningFontSize), ), generateGeocodeNameList(-1).length > 10 ? InkWell( @@ -643,7 +670,8 @@ class _DetailScreenState extends State { fontWeight: FontWeight.bold, color: Colors.red), ) - : Text(AppLocalizations.of(context)!.warning_show_more, + : Text( + AppLocalizations.of(context)!.warning_show_more, style: TextStyle( fontWeight: FontWeight.bold, color: Colors.green)), @@ -678,9 +706,10 @@ class _DetailScreenState extends State { ), SelectableText.rich( TextSpan( - children: - generateDescriptionBody(widget._warnMessage.description), - style: TextStyle(fontSize: userPreferences.warningFontSize)), + children: generateDescriptionBody( + widget._warnMessage.description), + style: + TextStyle(fontSize: userPreferences.warningFontSize)), ), SizedBox( height: 5, @@ -699,7 +728,8 @@ class _DetailScreenState extends State { ":", style: TextStyle( fontWeight: FontWeight.bold, - fontSize: userPreferences.warningFontSize + 5), + fontSize: + userPreferences.warningFontSize + 5), ), ], ), @@ -731,12 +761,13 @@ class _DetailScreenState extends State { width: 5, ), Text( - AppLocalizations.of(context) - !.warning_recommended_action + + AppLocalizations.of(context)! + .warning_recommended_action + ":", style: TextStyle( fontWeight: FontWeight.bold, - fontSize: userPreferences.warningFontSize + 5), + fontSize: + userPreferences.warningFontSize + 5), ), ], ), @@ -751,7 +782,8 @@ class _DetailScreenState extends State { TextSpan( children: generateDescriptionBody( widget._warnMessage.instruction), - style: TextStyle(fontSize: userPreferences.warningFontSize)), + style: TextStyle( + fontSize: userPreferences.warningFontSize)), ) : SizedBox(), SizedBox( @@ -786,7 +818,8 @@ class _DetailScreenState extends State { width: 5, ), Text( - AppLocalizations.of(context)!.warning_contact_website + + AppLocalizations.of(context)! + .warning_contact_website + ":", style: TextStyle( fontWeight: FontWeight.bold, @@ -806,7 +839,8 @@ class _DetailScreenState extends State { ":", style: TextStyle( fontWeight: FontWeight.bold, - fontSize: userPreferences.warningFontSize + 5), + fontSize: + userPreferences.warningFontSize + 5), ), ], ) From 473370decb432c6277c3532ff6f0062ed314c265 Mon Sep 17 00:00:00 2001 From: Nucleus Date: Mon, 1 Jan 2024 19:06:39 +0100 Subject: [PATCH 42/61] add button to open the severity explanation dialog and prepare translation --- lib/views/NotificationSettingsView.dart | 28 ++++++++++++++++++++++--- 1 file changed, 25 insertions(+), 3 deletions(-) diff --git a/lib/views/NotificationSettingsView.dart b/lib/views/NotificationSettingsView.dart index 0721b4a3..fe2116e7 100644 --- a/lib/views/NotificationSettingsView.dart +++ b/lib/views/NotificationSettingsView.dart @@ -1,6 +1,7 @@ import 'package:flutter/material.dart'; import 'package:flutter_gen/gen_l10n/app_localizations.dart'; import 'package:foss_warn/widgets/NotificationPreferencesListTileWidget.dart'; +import 'package:foss_warn/widgets/dialogs/WarningSeverityExplanation.dart'; import '../main.dart'; @@ -35,14 +36,35 @@ class _NotificationSettingsViewState extends State { padding: settingsTileListPadding, child: Text( "Hier können Sie einstellen, ab welcher Warnstufe Sie für" - " welche Warnquelle eine Benachrichtigung erhalten möchten. "), + " welche Warnquelle eine Benachrichtigung erhalten möchten."), //notification_settings_description ), SizedBox( height: 10, ), - Padding( + Container( padding: settingsTileListPadding, - child: Divider(), + child: TextButton( + onPressed: () { + showDialog( + context: context, + builder: (BuildContext context) { + return WarningSeverityExplanation(); + }, + ); + }, + child: Row( + children: [ + Icon(Icons.info), + SizedBox( + width: 10, + ), + Text( + "Erklärung zu den Warnstufen"), // notification_settings_open_severity_explanation + ], + )), + ), + SizedBox( + height: 10, ), // generate the settings tiles ...userPreferences.notificationSourceSettings From dc0b3c934c97bab1a847e751a64eafe6e37c4b24 Mon Sep 17 00:00:00 2001 From: Nucleus Date: Mon, 1 Jan 2024 19:06:56 +0100 Subject: [PATCH 43/61] prepare translation --- ...NotificationPreferencesListTileWidget.dart | 211 +++++++++--------- 1 file changed, 110 insertions(+), 101 deletions(-) diff --git a/lib/widgets/NotificationPreferencesListTileWidget.dart b/lib/widgets/NotificationPreferencesListTileWidget.dart index bacc5949..68709436 100644 --- a/lib/widgets/NotificationPreferencesListTileWidget.dart +++ b/lib/widgets/NotificationPreferencesListTileWidget.dart @@ -58,7 +58,7 @@ class _NotificationPreferencesListTileWidgetState return AppLocalizations.of(context)!.source_alertswiss_description; case WarningSource.other: return "Generelle Einstellung, die verwendet wird, wenn keine" - " genauere Einstellung getroffen wurde."; + " genauere Einstellung getroffen wurde."; //source_other_description default: return "Error"; } @@ -91,114 +91,123 @@ class _NotificationPreferencesListTileWidgetState !userPreferences.activateAlertSwiss) { return SizedBox(); } else { - return ListTile( - contentPadding: settingsTileListPadding, - title: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Text( - widget.notificationPreferences.warningSource.name.toUpperCase(), - style: Theme.of(context).textTheme.titleMedium, + return Column( + children: [ + Padding( + padding: settingsTileListPadding, + child: Divider(), + ), + ListTile( + contentPadding: settingsTileListPadding, + title: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text( + widget.notificationPreferences.warningSource.name.toUpperCase(), + style: Theme.of(context).textTheme.titleMedium, + ), + // show a switch when source can be disabled + if (_isTogglableSource( + widget.notificationPreferences.warningSource)) + Switch( + value: !widget.notificationPreferences.disabled, + onChanged: (value) { + // the slider will be hidden when source is disabled + setState(() { + widget.notificationPreferences.disabled = !value; + }); + saveSettings(); + }, + ) + else + SizedBox(), + ], ), - // show a switch when source can be disabled - if (_isTogglableSource( - widget.notificationPreferences.warningSource)) - Switch( - value: !widget.notificationPreferences.disabled, - onChanged: (value) { - // the slider will be hidden when source is disabled - setState(() { - widget.notificationPreferences.disabled = !value; - }); - saveSettings(); - }, - ) - else - SizedBox(), - ], - ), - subtitle: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( - _getDescriptionForEventSetting( - widget.notificationPreferences.warningSource), - style: Theme.of(context).textTheme.bodyMedium), - // hide the slider when source is disabled - if (_isTogglableSource( - widget.notificationPreferences.warningSource) && - widget.notificationPreferences.disabled) - Container( - padding: EdgeInsets.only(top: 5), - child: Text( - "Source disabled - you won't get a notification"), //@todo translate - ) - else - Column( - children: [ - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - mainAxisSize: MainAxisSize.max, + subtitle: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + _getDescriptionForEventSetting( + widget.notificationPreferences.warningSource), + style: Theme.of(context).textTheme.bodyMedium), + // hide the slider when source is disabled + if (_isTogglableSource( + widget.notificationPreferences.warningSource) && + widget.notificationPreferences.disabled) + Container( + padding: EdgeInsets.only(top: 5), + child: Text( + "Source disabled - you won't get a notification"), //@todo translate + ) + else + Column( children: [ - Icon( - Icons.notifications_active, - color: Colors.red, - ), - Flexible( - child: Slider( - label: getLabelForWarningSeverity( - Severity.getIndexFromSeverity(widget - .notificationPreferences.notificationLevel)), - divisions: 3, - min: 0, - max: 3, - value: Severity.getIndexFromSeverity( - widget.notificationPreferences.notificationLevel), - onChanged: (value) { - setState( - () { - final notificationLevel = - Severity.values[value.toInt()]; + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + mainAxisSize: MainAxisSize.max, + children: [ + Icon( + Icons.notifications_active, + color: Colors.red, + ), + Flexible( + child: Slider( + label: getLabelForWarningSeverity( + Severity.getIndexFromSeverity(widget + .notificationPreferences.notificationLevel)), + divisions: 3, + min: 0, + max: 3, + value: Severity.getIndexFromSeverity( + widget.notificationPreferences.notificationLevel), + onChanged: (value) { + setState( + () { + final notificationLevel = + Severity.values[value.toInt()]; - print(widget.notificationPreferences - .warningSource.name + - ":" + - notificationLevel.toString()); + print(widget.notificationPreferences + .warningSource.name + + ":" + + notificationLevel.toString()); - // update notification level with slider value - widget.notificationPreferences - .notificationLevel = notificationLevel; + // update notification level with slider value + widget.notificationPreferences + .notificationLevel = notificationLevel; + }, + ); }, - ); - }, - onChangeEnd: (value) { - // save settings, after change is complete - saveSettings(); - }, - ), - ), - Icon( - Icons.notifications, - color: Colors.orangeAccent, + onChangeEnd: (value) { + // save settings, after change is complete + saveSettings(); + }, + ), + ), + Icon( + Icons.notifications, + color: Colors.orangeAccent, + ), + ], ), + Padding( + padding: const EdgeInsets.only(left: 30, right: 30), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + //@todo translation + Text("extreme"), // notification_settings_slidervalue_extreme + Text("severe"), // notification_settings_slidervalue_severe + Text("moderate"), // notification_settings_slidervalue_moderate + Text("minor"), // notification_settings_slidervalue_minor + ], + ), + ) ], ), - Padding( - padding: const EdgeInsets.only(left: 30, right: 30), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Text("extreme"), // @todo translation - Text("severe"), - Text("moderate"), - Text("minor"), - ], - ), - ) - ], - ), - ], - ), + ], + ), + ), + ], ); } } From 834610fcd74594dc38274c4090260a0da69b01e1 Mon Sep 17 00:00:00 2001 From: Anonymous Date: Mon, 1 Jan 2024 18:11:46 +0000 Subject: [PATCH 44/61] Translated using Weblate (English) Currently translated at 100.0% (229 of 229 strings) Translation: FOSS Warn/FOSS Warn-App Translate-URL: https://hosted.weblate.org/projects/foss-warn/foss-warn-app/en/ --- lib/l10n/app_en.arb | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/lib/l10n/app_en.arb b/lib/l10n/app_en.arb index 60d296da..5794136d 100644 --- a/lib/l10n/app_en.arb +++ b/lib/l10n/app_en.arb @@ -450,5 +450,11 @@ "notification_settings_description": "This allows you to set the alert level at which you want to receive an alert and for which alert source.", "@notification_settings_description": {}, "warning_severity_explanation_dialog_severe_description": "Significant threat to life or property. May affect your health, property and/or public infrastructure.", - "@warning_severity_explanation_dialog_severe_description": {} + "@warning_severity_explanation_dialog_severe_description": {}, + "warning_severity_explanation_dialog_moderate_description": "A warning of a possible threat to life or property. Can severely disrupt normal daily routines.", + "@warning_severity_explanation_dialog_moderate_description": {}, + "warning_severity_explanation_dialog_minor_description": "Minimal to no known threat to life or property. May interfere with normal daily activities.", + "@warning_severity_explanation_dialog_minor_description": {}, + "warning_severity_explanation_dialog_extreme_description": "Extraordinary threat to life or property. May have a significant short-term impact on your health, property and/or public infrastructure.", + "@warning_severity_explanation_dialog_extreme_description": {} } From 591428e59a5c9960b507782cc6429b578b6f34fb Mon Sep 17 00:00:00 2001 From: Nucleus Date: Tue, 2 Jan 2024 01:32:40 +0100 Subject: [PATCH 45/61] fix double Other entry in notificationSettings because of wrong json decoding --- lib/enums/WarningSource.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/enums/WarningSource.dart b/lib/enums/WarningSource.dart index b8ac5aba..bc814c42 100644 --- a/lib/enums/WarningSource.dart +++ b/lib/enums/WarningSource.dart @@ -11,7 +11,7 @@ enum WarningSource { static WarningSource fromString(String source) { switch (source.toUpperCase()) { - case "ALERT SWISS": + case "ALERTSWISS": case "ALERT SWISS": return WarningSource.alertSwiss; case "BIWAPP": return WarningSource.biwapp; From 50bafd510e7cee9f33cc6561ebcfa49091d3c837 Mon Sep 17 00:00:00 2001 From: Nucleus Date: Tue, 2 Jan 2024 01:34:31 +0100 Subject: [PATCH 46/61] fix broken json parsing of alert swiss due to a changed structure --- lib/class/class_WarnMessage.dart | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/class/class_WarnMessage.dart b/lib/class/class_WarnMessage.dart index 6203ae79..9e5c86e9 100644 --- a/lib/class/class_WarnMessage.dart +++ b/lib/class/class_WarnMessage.dart @@ -143,11 +143,11 @@ class WarnMessage { effective: "", // missing onset: json["onset"] ?? "", // m expires: json["expires"] ?? "", // m - headline: json["title"] ?? "?", - description: json["description"] ?? "", + headline: json["title"]["title"] ?? "?", + description: json["description"]["description"] ?? "", instruction: instructions, publisher: license, - contact: json["contact"] ?? "", + contact: json["contact"]["contact"] ?? "", web: json["link"] ?? "", areaList: areaList, notified: false, From f7f9e9039d1b4893a20590a4fe1cbe8a8e662ef1 Mon Sep 17 00:00:00 2001 From: Nucleus Date: Tue, 2 Jan 2024 16:00:48 +0100 Subject: [PATCH 47/61] fix json parsing --- lib/services/alertSwiss.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/services/alertSwiss.dart b/lib/services/alertSwiss.dart index 143b55a5..6c3dedcd 100644 --- a/lib/services/alertSwiss.dart +++ b/lib/services/alertSwiss.dart @@ -82,7 +82,7 @@ WarnMessage? createWarning(var data) { for (int i = 0; i < data.length; i++) { tempAreaList.add( Area( - areaDesc: data[i]["description"], + areaDesc: data[i]["description"]["description"], geocodeList: [ Geocode( geocodeName: data[i]["regions"][0]["region"], From d138542eeb6c5f79bf75c79cd8bbe061f15a2f33 Mon Sep 17 00:00:00 2001 From: Nucleus Date: Tue, 2 Jan 2024 17:00:59 +0100 Subject: [PATCH 48/61] fix json parsing. The boolean value is not stored as string. --- lib/class/class_notificationPreferences.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/class/class_notificationPreferences.dart b/lib/class/class_notificationPreferences.dart index 8d19227b..4854035b 100644 --- a/lib/class/class_notificationPreferences.dart +++ b/lib/class/class_notificationPreferences.dart @@ -13,7 +13,7 @@ class NotificationPreferences { factory NotificationPreferences.fromJson(Map json) { return NotificationPreferences( warningSource: WarningSource.fromString(json['warningSource'].toString()), - disabled: json['disabled'] == "true", // @todo is there a better way to deserialize a boolean? + disabled: json['disabled'], notificationLevel: Severity.fromJson(json['notificationLevel'])); } From 6bf002e2718474b0a509dc69d2aed8cf47abcba7 Mon Sep 17 00:00:00 2001 From: Nucleus Date: Tue, 2 Jan 2024 18:07:42 +0100 Subject: [PATCH 49/61] cancel notification if warning is read or marked as read --- lib/class/abstract_Place.dart | 1 + lib/class/class_NotificationService.dart | 2 +- lib/views/WarningDetailView.dart | 3 +++ 3 files changed, 5 insertions(+), 1 deletion(-) diff --git a/lib/class/abstract_Place.dart b/lib/class/abstract_Place.dart index 5e232e28..237714e9 100644 --- a/lib/class/abstract_Place.dart +++ b/lib/class/abstract_Place.dart @@ -97,6 +97,7 @@ abstract class Place { void markAllWarningsAsRead(BuildContext context) { for (WarnMessage myWarnMessage in _warnings) { myWarnMessage.read = true; + NotificationService.cancelOneNotification(myWarnMessage.identifier.hashCode); } final updater = Provider.of(context, listen: false); updater.updateReadStatusInList(); diff --git a/lib/class/class_NotificationService.dart b/lib/class/class_NotificationService.dart index 77b7f115..185028bd 100644 --- a/lib/class/class_NotificationService.dart +++ b/lib/class/class_NotificationService.dart @@ -280,7 +280,7 @@ class NotificationService { if (activeNotifications!.length == 2 && activeNotifications - .any((element) => element.channelId == "foss_warn_status")) { + .any((element) => element.channelId == "de.nucleus.foss_warn.notifications_state")) { if (activeNotifications[0].id == 0) { // summery notification has id 0 cancelOneNotification(0); diff --git a/lib/views/WarningDetailView.dart b/lib/views/WarningDetailView.dart index 8ef072be..bb4061c7 100644 --- a/lib/views/WarningDetailView.dart +++ b/lib/views/WarningDetailView.dart @@ -1,6 +1,7 @@ import 'package:flutter/gestures.dart'; import 'package:flutter/material.dart'; import 'package:flutter_gen/gen_l10n/app_localizations.dart'; +import 'package:foss_warn/class/class_NotificationService.dart'; import '../class/class_WarnMessage.dart'; import '../class/class_Area.dart'; import '../class/class_Geocode.dart'; @@ -216,6 +217,8 @@ class _DetailScreenState extends State { }); // save places List to store new read state saveMyPlacesList(); + // cancel the notification + NotificationService.cancelOneNotification(widget._warnMessage.identifier.hashCode); List generateAreaDescList(int length) { List tempList = []; From 99e587fc53371ea60daa30295c1b19f2b89e302c Mon Sep 17 00:00:00 2001 From: Nucleus Date: Tue, 2 Jan 2024 17:15:32 +0000 Subject: [PATCH 50/61] Translated using Weblate (English) Currently translated at 100.0% (229 of 229 strings) Translation: FOSS Warn/FOSS Warn-App Translate-URL: https://hosted.weblate.org/projects/foss-warn/foss-warn-app/en/ --- lib/l10n/app_en.arb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/l10n/app_en.arb b/lib/l10n/app_en.arb index 5794136d..9098d7ed 100644 --- a/lib/l10n/app_en.arb +++ b/lib/l10n/app_en.arb @@ -447,7 +447,7 @@ "@warning _severity_explanation_dialog_headline": {}, "notification_settings_open_severity_explanation": "Explanations of the degree of severity", "@notification_settings_open_severity_explanation": {}, - "notification_settings_description": "This allows you to set the alert level at which you want to receive an alert and for which alert source.", + "notification_settings_description": "Here you can set the warning level for each source for which you want to receive a warning.", "@notification_settings_description": {}, "warning_severity_explanation_dialog_severe_description": "Significant threat to life or property. May affect your health, property and/or public infrastructure.", "@warning_severity_explanation_dialog_severe_description": {}, From 76a29f0422e6d2775f24a81ba53cf84378212c0e Mon Sep 17 00:00:00 2001 From: Nucleus Date: Tue, 2 Jan 2024 17:13:13 +0000 Subject: [PATCH 51/61] Translated using Weblate (German) Currently translated at 100.0% (229 of 229 strings) Translation: FOSS Warn/FOSS Warn-App Translate-URL: https://hosted.weblate.org/projects/foss-warn/foss-warn-app/de/ --- lib/l10n/app_de.arb | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/lib/l10n/app_de.arb b/lib/l10n/app_de.arb index 1a6248a8..ca2a3f8e 100644 --- a/lib/l10n/app_de.arb +++ b/lib/l10n/app_de.arb @@ -438,5 +438,23 @@ "notification_settings_slidervalue_severe": "Schwer", "@notification_settings_slidervalue_severe": {}, "notification_settings_slidervalue_minor": "Gering", - "@notification_settings_slidervalue_minor": {} + "@notification_settings_slidervalue_minor": {}, + "warning _severity_explanation_dialog_headline": "Schweregrad", + "@warning _severity_explanation_dialog_headline": {}, + "notification_settings_open_severity_explanation": "Erklärungen zum Schweregrad", + "@notification_settings_open_severity_explanation": {}, + "warning_severity_explanation_dialog_moderate_description": "Eine Warnung vor einer möglichen Bedrohung von Leben oder Eigentum. Kann den normalen Tagesablauf stark beeinträchtigen.", + "@warning_severity_explanation_dialog_moderate_description": {}, + "source_other_description": "Allgemeine Einstellung, die verwendet wird, wenn keine genauere Einstellung vorgenommen wurde.", + "@source_other_description": {}, + "warning_severity_explanation_dialog_minor_description": "Minimale bis keine bekannte Bedrohung für Leben oder Eigentum. Kann den normalen Tagesablauf beeinträchtigen.", + "@warning_severity_explanation_dialog_minor_description": {}, + "notification_settings_description": "Hier können Sie die Warnstufe für jede Quelle festlegen, bei der Sie eine Warnung erhalten möchten.", + "@notification_settings_description": {}, + "source_other_title": "Sonstige", + "@source_other_title": {}, + "warning_severity_explanation_dialog_extreme_description": "Außerordentliche Bedrohung für Leben oder Eigentum. Kann sich kurzfristig signifikant auf ihre Gesundheit, ihr Eigentum und/oder öffentliche Infrastruktur auswirken.", + "@warning_severity_explanation_dialog_extreme_description": {}, + "warning_severity_explanation_dialog_severe_description": "Erhebliche Bedrohung für Leben oder Eigentum. Kann ihre Gesundheit, ihr Eigentum und/oder öffentliche Infrastruktur beeinträchtigen.", + "@warning_severity_explanation_dialog_severe_description": {} } From 013c952a30f7c852b9d3eac73ab6d8cc448f7dc8 Mon Sep 17 00:00:00 2001 From: Nucleus Date: Tue, 2 Jan 2024 17:18:25 +0000 Subject: [PATCH 52/61] Translated using Weblate (French) Currently translated at 100.0% (229 of 229 strings) Translation: FOSS Warn/FOSS Warn-App Translate-URL: https://hosted.weblate.org/projects/foss-warn/foss-warn-app/fr/ --- lib/l10n/app_fr.arb | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/lib/l10n/app_fr.arb b/lib/l10n/app_fr.arb index 847eeba0..d110d9ba 100644 --- a/lib/l10n/app_fr.arb +++ b/lib/l10n/app_fr.arb @@ -438,5 +438,23 @@ "notification_settings_slidervalue_severe": "sévères", "@notification_settings_slidervalue_severe": {}, "notification_settings_slidervalue_minor": "mineurs", - "@notification_settings_slidervalue_minor": {} + "@notification_settings_slidervalue_minor": {}, + "warning _severity_explanation_dialog_headline": "Sévérité", + "@warning _severity_explanation_dialog_headline": {}, + "notification_settings_open_severity_explanation": "Explications sur le degré de gravité", + "@notification_settings_open_severity_explanation": {}, + "warning_severity_explanation_dialog_moderate_description": "Avertissement d'une menace possible pour la vie ou les biens. Peut gravement perturber les activités quotidiennes normales.", + "@warning_severity_explanation_dialog_moderate_description": {}, + "source_other_description": "Réglage général qui est utilisé si aucun réglage plus précis n'a été effectué.", + "@source_other_description": {}, + "warning_severity_explanation_dialog_minor_description": "Risque minime ou inexistant de menace pour la vie ou les biens. Peut interférer avec les activités quotidiennes normales.", + "@warning_severity_explanation_dialog_minor_description": {}, + "notification_settings_description": "Vous pouvez ici définir le niveau d'avertissement pour chaque source pour laquelle vous souhaitez recevoir un avertissement.", + "@notification_settings_description": {}, + "source_other_title": "Autres", + "@source_other_title": {}, + "warning_severity_explanation_dialog_extreme_description": "Menace extraordinaire pour la vie ou les biens. Peut avoir un impact significatif à court terme sur votre santé, vos biens et/ou les infrastructures publiques.", + "@warning_severity_explanation_dialog_extreme_description": {}, + "warning_severity_explanation_dialog_severe_description": "Menace importante pour la vie ou les biens. Peut affecter votre santé, vos biens et/ou les infrastructures publiques.", + "@warning_severity_explanation_dialog_severe_description": {} } From 6397a5f34888cd8c6fa18f744a2f8af72ff66cc9 Mon Sep 17 00:00:00 2001 From: Nucleus Date: Tue, 2 Jan 2024 18:24:31 +0100 Subject: [PATCH 53/61] Translated using Weblate (German) Currently translated at 100.0% (229 of 229 strings) Translation: FOSS Warn/FOSS Warn-App Translate-URL: https://hosted.weblate.org/projects/foss-warn/foss-warn-app/de/ --- lib/l10n/app_de.arb | 2 -- 1 file changed, 2 deletions(-) diff --git a/lib/l10n/app_de.arb b/lib/l10n/app_de.arb index ca2a3f8e..1e517de7 100644 --- a/lib/l10n/app_de.arb +++ b/lib/l10n/app_de.arb @@ -439,8 +439,6 @@ "@notification_settings_slidervalue_severe": {}, "notification_settings_slidervalue_minor": "Gering", "@notification_settings_slidervalue_minor": {}, - "warning _severity_explanation_dialog_headline": "Schweregrad", - "@warning _severity_explanation_dialog_headline": {}, "notification_settings_open_severity_explanation": "Erklärungen zum Schweregrad", "@notification_settings_open_severity_explanation": {}, "warning_severity_explanation_dialog_moderate_description": "Eine Warnung vor einer möglichen Bedrohung von Leben oder Eigentum. Kann den normalen Tagesablauf stark beeinträchtigen.", From 5948c34482f6ee7ffd053b057a48623d31c549e3 Mon Sep 17 00:00:00 2001 From: Nucleus Date: Tue, 2 Jan 2024 18:24:31 +0100 Subject: [PATCH 54/61] Translated using Weblate (French) Currently translated at 100.0% (229 of 229 strings) Translation: FOSS Warn/FOSS Warn-App Translate-URL: https://hosted.weblate.org/projects/foss-warn/foss-warn-app/fr/ --- lib/l10n/app_fr.arb | 2 -- 1 file changed, 2 deletions(-) diff --git a/lib/l10n/app_fr.arb b/lib/l10n/app_fr.arb index d110d9ba..10ace924 100644 --- a/lib/l10n/app_fr.arb +++ b/lib/l10n/app_fr.arb @@ -439,8 +439,6 @@ "@notification_settings_slidervalue_severe": {}, "notification_settings_slidervalue_minor": "mineurs", "@notification_settings_slidervalue_minor": {}, - "warning _severity_explanation_dialog_headline": "Sévérité", - "@warning _severity_explanation_dialog_headline": {}, "notification_settings_open_severity_explanation": "Explications sur le degré de gravité", "@notification_settings_open_severity_explanation": {}, "warning_severity_explanation_dialog_moderate_description": "Avertissement d'une menace possible pour la vie ou les biens. Peut gravement perturber les activités quotidiennes normales.", From 80a95aff09f4f55cc7befcaf957ecf3ba13d5d3d Mon Sep 17 00:00:00 2001 From: Nucleus Date: Tue, 2 Jan 2024 18:24:31 +0100 Subject: [PATCH 55/61] Translated using Weblate (English) Currently translated at 100.0% (229 of 229 strings) Translation: FOSS Warn/FOSS Warn-App Translate-URL: https://hosted.weblate.org/projects/foss-warn/foss-warn-app/en/ --- lib/l10n/app_en.arb | 2 -- 1 file changed, 2 deletions(-) diff --git a/lib/l10n/app_en.arb b/lib/l10n/app_en.arb index 9098d7ed..36d35dc6 100644 --- a/lib/l10n/app_en.arb +++ b/lib/l10n/app_en.arb @@ -443,8 +443,6 @@ "@source_other_description": {}, "source_other_title": "Other", "@source_other_title": {}, - "warning _severity_explanation_dialog_headline": "Severity", - "@warning _severity_explanation_dialog_headline": {}, "notification_settings_open_severity_explanation": "Explanations of the degree of severity", "@notification_settings_open_severity_explanation": {}, "notification_settings_description": "Here you can set the warning level for each source for which you want to receive a warning.", From 511909a99a4ec55bf8c3e0f6433f73b40b2731a6 Mon Sep 17 00:00:00 2001 From: Anonymous Date: Tue, 2 Jan 2024 17:26:14 +0000 Subject: [PATCH 56/61] Translated using Weblate (English) Currently translated at 100.0% (229 of 229 strings) Translation: FOSS Warn/FOSS Warn-App Translate-URL: https://hosted.weblate.org/projects/foss-warn/foss-warn-app/en/ --- lib/l10n/app_en.arb | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/l10n/app_en.arb b/lib/l10n/app_en.arb index 36d35dc6..899cd8b4 100644 --- a/lib/l10n/app_en.arb +++ b/lib/l10n/app_en.arb @@ -454,5 +454,7 @@ "warning_severity_explanation_dialog_minor_description": "Minimal to no known threat to life or property. May interfere with normal daily activities.", "@warning_severity_explanation_dialog_minor_description": {}, "warning_severity_explanation_dialog_extreme_description": "Extraordinary threat to life or property. May have a significant short-term impact on your health, property and/or public infrastructure.", - "@warning_severity_explanation_dialog_extreme_description": {} + "@warning_severity_explanation_dialog_extreme_description": {}, + "warning_severity_explanation_dialog_headline": "Severity", + "@warning_severity_explanation_dialog_headline": {} } From 3c3da61d0fbea80421530e6ca4577e381193bf03 Mon Sep 17 00:00:00 2001 From: Nucleus Date: Tue, 2 Jan 2024 17:25:49 +0000 Subject: [PATCH 57/61] Translated using Weblate (German) Currently translated at 100.0% (229 of 229 strings) Translation: FOSS Warn/FOSS Warn-App Translate-URL: https://hosted.weblate.org/projects/foss-warn/foss-warn-app/de/ --- lib/l10n/app_de.arb | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/l10n/app_de.arb b/lib/l10n/app_de.arb index 1e517de7..be4b1fe5 100644 --- a/lib/l10n/app_de.arb +++ b/lib/l10n/app_de.arb @@ -454,5 +454,7 @@ "warning_severity_explanation_dialog_extreme_description": "Außerordentliche Bedrohung für Leben oder Eigentum. Kann sich kurzfristig signifikant auf ihre Gesundheit, ihr Eigentum und/oder öffentliche Infrastruktur auswirken.", "@warning_severity_explanation_dialog_extreme_description": {}, "warning_severity_explanation_dialog_severe_description": "Erhebliche Bedrohung für Leben oder Eigentum. Kann ihre Gesundheit, ihr Eigentum und/oder öffentliche Infrastruktur beeinträchtigen.", - "@warning_severity_explanation_dialog_severe_description": {} + "@warning_severity_explanation_dialog_severe_description": {}, + "warning_severity_explanation_dialog_headline": "Schweregrad", + "@warning_severity_explanation_dialog_headline": {} } From 990efa36e5e46d25be526c53cf28cad7486b59b7 Mon Sep 17 00:00:00 2001 From: Nucleus Date: Tue, 2 Jan 2024 17:26:08 +0000 Subject: [PATCH 58/61] Translated using Weblate (French) Currently translated at 100.0% (229 of 229 strings) Translation: FOSS Warn/FOSS Warn-App Translate-URL: https://hosted.weblate.org/projects/foss-warn/foss-warn-app/fr/ --- lib/l10n/app_fr.arb | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/l10n/app_fr.arb b/lib/l10n/app_fr.arb index 10ace924..3e97faf1 100644 --- a/lib/l10n/app_fr.arb +++ b/lib/l10n/app_fr.arb @@ -454,5 +454,7 @@ "warning_severity_explanation_dialog_extreme_description": "Menace extraordinaire pour la vie ou les biens. Peut avoir un impact significatif à court terme sur votre santé, vos biens et/ou les infrastructures publiques.", "@warning_severity_explanation_dialog_extreme_description": {}, "warning_severity_explanation_dialog_severe_description": "Menace importante pour la vie ou les biens. Peut affecter votre santé, vos biens et/ou les infrastructures publiques.", - "@warning_severity_explanation_dialog_severe_description": {} + "@warning_severity_explanation_dialog_severe_description": {}, + "warning_severity_explanation_dialog_headline": "Gravité", + "@warning_severity_explanation_dialog_headline": {} } From 7ce44fdae35d074aad8884be49f5bb6c459663de Mon Sep 17 00:00:00 2001 From: Nucleus Date: Tue, 2 Jan 2024 18:39:48 +0100 Subject: [PATCH 59/61] add translation --- lib/views/NotificationSettingsView.dart | 5 ++--- ...NotificationPreferencesListTileWidget.dart | 14 ++++++------- .../dialogs/WarningSeverityExplanation.dart | 20 +++++++++---------- 3 files changed, 18 insertions(+), 21 deletions(-) diff --git a/lib/views/NotificationSettingsView.dart b/lib/views/NotificationSettingsView.dart index fe2116e7..ba92b5ef 100644 --- a/lib/views/NotificationSettingsView.dart +++ b/lib/views/NotificationSettingsView.dart @@ -35,8 +35,7 @@ class _NotificationSettingsViewState extends State { Container( padding: settingsTileListPadding, child: Text( - "Hier können Sie einstellen, ab welcher Warnstufe Sie für" - " welche Warnquelle eine Benachrichtigung erhalten möchten."), //notification_settings_description + AppLocalizations.of(context)!.notification_settings_description), // ), SizedBox( height: 10, @@ -59,7 +58,7 @@ class _NotificationSettingsViewState extends State { width: 10, ), Text( - "Erklärung zu den Warnstufen"), // notification_settings_open_severity_explanation + AppLocalizations.of(context)!.notification_settings_open_severity_explanation), // ], )), ), diff --git a/lib/widgets/NotificationPreferencesListTileWidget.dart b/lib/widgets/NotificationPreferencesListTileWidget.dart index 68709436..bd1e6fea 100644 --- a/lib/widgets/NotificationPreferencesListTileWidget.dart +++ b/lib/widgets/NotificationPreferencesListTileWidget.dart @@ -57,8 +57,7 @@ class _NotificationPreferencesListTileWidgetState case WarningSource.alertSwiss: return AppLocalizations.of(context)!.source_alertswiss_description; case WarningSource.other: - return "Generelle Einstellung, die verwendet wird, wenn keine" - " genauere Einstellung getroffen wurde."; //source_other_description + return AppLocalizations.of(context)!.source_other_description; default: return "Error"; } @@ -137,7 +136,7 @@ class _NotificationPreferencesListTileWidgetState Container( padding: EdgeInsets.only(top: 5), child: Text( - "Source disabled - you won't get a notification"), //@todo translate + AppLocalizations.of(context)!.notification_settings_source_disabled), ) else Column( @@ -194,11 +193,10 @@ class _NotificationPreferencesListTileWidgetState child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - //@todo translation - Text("extreme"), // notification_settings_slidervalue_extreme - Text("severe"), // notification_settings_slidervalue_severe - Text("moderate"), // notification_settings_slidervalue_moderate - Text("minor"), // notification_settings_slidervalue_minor + Text(AppLocalizations.of(context)!.notification_settings_slidervalue_extreme), + Text(AppLocalizations.of(context)!.notification_settings_slidervalue_severe), + Text(AppLocalizations.of(context)!.notification_settings_slidervalue_moderate), + Text(AppLocalizations.of(context)!.notification_settings_slidervalue_minor), ], ), ) diff --git a/lib/widgets/dialogs/WarningSeverityExplanation.dart b/lib/widgets/dialogs/WarningSeverityExplanation.dart index 8a9fd331..da1e3f7a 100644 --- a/lib/widgets/dialogs/WarningSeverityExplanation.dart +++ b/lib/widgets/dialogs/WarningSeverityExplanation.dart @@ -13,7 +13,7 @@ class _WarningSeverityExplanationState extends State Widget build(BuildContext context) { return AlertDialog( title: - Text("Schweregrade"), //warning _severity_explanation_dialog_headline + Text(AppLocalizations.of(context)!.warning_severity_explanation_dialog_headline), content: Container( child: Column( crossAxisAlignment: CrossAxisAlignment.start, @@ -25,38 +25,38 @@ class _WarningSeverityExplanationState extends State style: Theme.of(context) .textTheme .bodyMedium, //DefaultTextStyle.of(context).style, - children: const [ + children: [ TextSpan( - text: 'Extrem:', + text: AppLocalizations.of(context)!.notification_settings_slidervalue_extreme, style: TextStyle(fontWeight: FontWeight.bold)), TextSpan(text: '\n'), TextSpan( text: //warning_severity_explanation_dialog_extreme_description - 'Außerordentliche Bedrohung für Leben oder Eigentum. Kann sich kurzfristig signifikant auf ihre Gesundheit, ihr Eigentum und/oder öffentliche Infrastruktur auswirken.'), + AppLocalizations.of(context)!.warning_severity_explanation_dialog_extreme_description), TextSpan(text: '\n\n'), TextSpan( - text: 'Schwer:', + text: AppLocalizations.of(context)!.notification_settings_slidervalue_severe, style: TextStyle(fontWeight: FontWeight.bold)), TextSpan(text: '\n'), TextSpan( text: //warning_severity_explanation_dialog_severe_description - 'Erhebliche Bedrohung für Leben oder Eigentum. Kann ihre Gesundheit, ihr Eigentum und/oder öffentliche Infrastruktur beeinträchtigen.'), + AppLocalizations.of(context)!.warning_severity_explanation_dialog_severe_description), TextSpan(text: '\n\n'), TextSpan( - text: 'Moderat:', + text: AppLocalizations.of(context)!.notification_settings_slidervalue_moderate, style: TextStyle(fontWeight: FontWeight.bold)), TextSpan(text: '\n'), TextSpan( text: //warning_severity_explanation_dialog_moderate_description - 'Eine Warnung vor einer möglichen Bedrohung von Leben oder Eigentum. Kann den normeln Tagesablauf stark beeinträchtigen.'), + AppLocalizations.of(context)!.warning_severity_explanation_dialog_moderate_description), TextSpan(text: '\n\n'), TextSpan( - text: 'Gering:', + text: AppLocalizations.of(context)!.notification_settings_slidervalue_minor, style: TextStyle(fontWeight: FontWeight.bold)), TextSpan(text: '\n'), TextSpan( text: //warning_severity_explanation_dialog_minor_description - 'Minimale bis keine bekannte Bedrohung für Leben oder Eigentum. Kann den normalen Tagesablauf beeinträchtigen.'), + AppLocalizations.of(context)!.warning_severity_explanation_dialog_minor_description), ], ), ), From 05aeb8a71d69341e6b5307e6e1a2b01d2a0eb5ff Mon Sep 17 00:00:00 2001 From: Nucleus Date: Tue, 2 Jan 2024 18:47:48 +0100 Subject: [PATCH 60/61] Changing the translation of moderate for a uniform name --- lib/class/class_NotificationService.dart | 2 +- lib/services/translateAndColorizeWarning.dart | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/class/class_NotificationService.dart b/lib/class/class_NotificationService.dart index 185028bd..02d92973 100644 --- a/lib/class/class_NotificationService.dart +++ b/lib/class/class_NotificationService.dart @@ -163,7 +163,7 @@ class NotificationService { await androidNotificationPlugin .createNotificationChannel(AndroidNotificationChannel( "de.nucleus.foss_warn.notifications_moderate", - "Warnstufe: Mittel", + "Warnstufe: Moderat", description: "Eine Warnung vor einer starken Beeinträchtigung des normalen Tagesablaufs.", groupId: "de.nucleus.foss_warn.notifications_emergency_information", diff --git a/lib/services/translateAndColorizeWarning.dart b/lib/services/translateAndColorizeWarning.dart index a76dd1ef..086199e1 100644 --- a/lib/services/translateAndColorizeWarning.dart +++ b/lib/services/translateAndColorizeWarning.dart @@ -136,7 +136,7 @@ String translateWarningSeverity(String severity) { case "minor": return "Gering"; case "moderate": - return "Mittel"; + return "Moderat"; case "extreme": return "Extrem"; case "severe": From f373fe563e40ec51fa6ac7a8f23f23197b51ca21 Mon Sep 17 00:00:00 2001 From: Nucleus Date: Tue, 2 Jan 2024 18:57:51 +0100 Subject: [PATCH 61/61] bump version number and add changelog --- lib/class/class_userPreferences.dart | 2 +- lib/widgets/dialogs/ChangeLogDialog.dart | 7 +++++++ pubspec.yaml | 2 +- 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/lib/class/class_userPreferences.dart b/lib/class/class_userPreferences.dart index e8384cbe..c932d7a4 100644 --- a/lib/class/class_userPreferences.dart +++ b/lib/class/class_userPreferences.dart @@ -59,7 +59,7 @@ class UserPreferences { bool showAllWarnings = false; bool areWarningsFromCache = false; - String versionNumber = "0.6.2"; // shown in the about view + String versionNumber = "0.7.0"; // shown in the about view bool activateAlertSwiss = false; bool isFirstStart = true; diff --git a/lib/widgets/dialogs/ChangeLogDialog.dart b/lib/widgets/dialogs/ChangeLogDialog.dart index 77de8f86..264ea505 100644 --- a/lib/widgets/dialogs/ChangeLogDialog.dart +++ b/lib/widgets/dialogs/ChangeLogDialog.dart @@ -13,6 +13,13 @@ class ChangeLogDialog extends StatelessWidget { crossAxisAlignment: CrossAxisAlignment.start, mainAxisSize: MainAxisSize.min, children: [ + Text( + "0.7.0 (beta)", + style: TextStyle(fontSize: 15, fontWeight: FontWeight.bold), + ), + Text("* Neues Design mit Material 3 \n" + "* Neue Benachrichtigungseinstellungen \n" + "* Fehlerbehebungen \n"), Text( "0.6.1 (beta)", style: TextStyle(fontSize: 15, fontWeight: FontWeight.bold), diff --git a/pubspec.yaml b/pubspec.yaml index b869db93..58f6f4c0 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,7 +1,7 @@ name: foss_warn description: Eine FOSS Umsetzung von NINA publish_to: 'none' -version: 0.6.1+29 +version: 0.7.0+30 environment: sdk: ">=2.17.0 <3.13.3"