Commit bda38a8

derdilla <82763757+NobodyForNothing@users.noreply.github.com>
2023-11-04 08:33:32
rewrite change timeformat screen
Signed-off-by: derdilla <82763757+NobodyForNothing@users.noreply.github.com>
1 parent 68759a9
lib/l10n/app_de.arb
@@ -261,14 +261,6 @@
   "@warnAboutTxt2": {},
   "warnAboutTxt3": "Ändere die Werte nach Bedarf und stimme dich mit deinem Arzt ab.",
   "@warnAboutTxt3": {},
-  "enterTimeFormatTxt1": "Das Datumsformat besteht aus einer Mischung vordefinierter ICU-Strings sowie anderer Zeichen deiner Wahl.",
-  "@enterTimeFormatTxt1": {},
-  "enterTimeFormatTxt2": "Die vollständige Liste gültiger Formate findest du hier.",
-  "@enterTimeFormatTxt2": {},
-  "enterTimeFormatTxt3": "Bitte beachte, dass kürzere/längere Zeitformat-Strings nicht die Spaltenbreiten ändern. Sie führen eher zu unerwünschten Umbrüchen.",
-  "@enterTimeFormatTxt3": {},
-  "enterTimeFormatTxt4": "Voreingestellt: \"yy-MM-dd HH:mm\"",
-  "@enterTimeFormatTxt4": {},
   "enterTimeFormatString": "Zeitformat-String",
   "@enterTimeFormatString": {},
   "dateFormatting": "Datumsformat",
@@ -425,5 +417,7 @@
   "requiresAppRestart": "Erfordert Neustart der App",
   "@requiresAppRestart": {},
   "color": "Farbe",
-  "@color": {}
+  "@color": {},
+  "enterTimeFormatDesc": "Das Datumsformat besteht aus einer Mischung vordefinierter ICU-Strings sowie anderer Zeichen deiner Wahl.\n\n[Die vollständige Liste gültiger Formate findest du hier.](screen://TimeFormattingHelp)\n\nBitte beachte, dass kürzere/längere Zeitformat-Strings nicht die Spaltenbreiten ändern. Sie führen eher zu unerwünschten Umbrüchen.\n\nVoreingestellt: \"yy-MM-dd HH:mm\"",
+  "@enterTimeFormatDesc": {}
 }
lib/l10n/app_en.arb
@@ -274,14 +274,6 @@
   "@warnAboutTxt2": {},
   "warnAboutTxt3": "Feel free to change the values to suit your needs and follow the recommendations of your doctor.",
   "@warnAboutTxt3": {},
-  "enterTimeFormatTxt1": "A formatter string is a blend of predefined ICU/Skeleton strings and any additional text you''d like to include.",
-  "@enterTimeFormatTxt1": {},
-  "enterTimeFormatTxt2": "If you''re curious about the complete list of valid formats, you can find them right here.",
-  "@enterTimeFormatTxt2": {},
-  "enterTimeFormatTxt3": "Just a friendly reminder, using longer or shorter format Strings won''t magically alter the width of the table columns, which might lead to some awkward line breaks and text not showing.",
-  "@enterTimeFormatTxt3": {},
-  "enterTimeFormatTxt4": "default: \"yy-MM-dd HH:mm\"",
-  "@enterTimeFormatTxt4": {},
   "enterTimeFormatString": "time format",
   "@enterTimeFormatString": {},
   "dateFormatting": "Date formatting",
@@ -441,5 +433,7 @@
   "fileAlreadyDeleted": "File already deleted",
   "@fileAlreadyDeleted": {},
   "errExportColumnWithThisNameAlreadyExists": "Export column with this name already exists.",
-  "@errExportColumnWithThisNameAlreadyExists": {}
+  "@errExportColumnWithThisNameAlreadyExists": {},
+  "enterTimeFormatDesc": "A formatter string is a blend of predefined ICU/Skeleton strings and any additional text you''d like to include.\n\n[If you''re curious about the complete list of valid formats, you can find them right here.](screen://TimeFormattingHelp)\n\nJust a friendly reminder, using longer or shorter format Strings won''t magically alter the width of the table columns, which might lead to some awkward line breaks and text not showing.\n\ndefault: \"yy-MM-dd HH:mm\"",
+  "@enterTimeFormatDesc": {}
 }
lib/l10n/app_fr.arb
@@ -71,10 +71,6 @@
   "@exportCustomEntries": {},
   "textDelimiter": "Délimiteur de texte",
   "@textDelimiter": {},
-  "enterTimeFormatTxt1": "Une chaine de formatage est un mélange de chaines ICU/Skeleton et de n''importe quel texte supplémentaire que vous souhaitez inclure.",
-  "@enterTimeFormatTxt1": {},
-  "enterTimeFormatTxt2": "Si vous souhaitez en savoir plus sur la liste complète des formats valides, tapez ici.",
-  "@enterTimeFormatTxt2": {},
   "success": "Réussite : {msg}",
   "@success": {
     "placeholders": {
@@ -276,8 +272,6 @@
   "@warnAboutTxt2": {},
   "warnAboutTxt3": "N''hésitez pas à modifier les valeurs pour qu''elles vous conviennent et suivent les recommandations de votre médecin.",
   "@warnAboutTxt3": {},
-  "enterTimeFormatTxt4": "valeur par défaut : \"yy-MM-dd HH:mm\"",
-  "@enterTimeFormatTxt4": {},
   "enterTimeFormatString": "format d''heure",
   "@enterTimeFormatString": {},
   "dateFormatting": "Formatage de date",
@@ -321,8 +315,6 @@
   "@last30Days": {},
   "allowMissingValues": "Autoriser les valeurs manquantes",
   "@allowMissingValues": {},
-  "enterTimeFormatTxt3": "Rappel amical : utiliser des chaines de formatage plus courtes ou plus longues ne modifieront pas la largeur des colonnes de table par magie, ce qui pourrait générer des retours à la ligne inattendus ou que du texte n''apparaisse pas.",
-  "@enterTimeFormatTxt3": {},
   "custom": "Personnalisé",
   "@custom": {},
   "language": "Langue",
@@ -415,5 +407,7 @@
   "exportPdfHeaderFontSize": "Taille de caractère de l''en-tête",
   "@exportPdfHeaderFontSize": {},
   "color": "Couleur",
-  "@color": {}
+  "@color": {},
+  "enterTimeFormatDesc": "Une chaine de formatage est un mélange de chaines ICU/Skeleton et de n''importe quel texte supplémentaire que vous souhaitez inclure.\n\n[Si vous souhaitez en savoir plus sur la liste complète des formats valides, tapez ici.](screen://TimeFormattingHelp)\n\nRappel amical : utiliser des chaines de formatage plus courtes ou plus longues ne modifieront pas la largeur des colonnes de table par magie, ce qui pourrait générer des retours à la ligne inattendus ou que du texte n''apparaisse pas.\n\nvaleur par défaut : \"yy-MM-dd HH:mm\"",
+  "@enterTimeFormatDesc": {}
 }
lib/l10n/app_it.arb
@@ -146,12 +146,6 @@
   "@errCantEditThis": {},
   "presets": "Programmate",
   "@presets": {},
-  "enterTimeFormatTxt1": "Una stringa di formattazione è un inseme di stringhe ICU/Skeleton predefinite e di qualsiasi testo aggiuntivo che si desidera aggiungere.",
-  "@enterTimeFormatTxt1": {},
-  "enterTimeFormatTxt2": "Qui è presente un elenco completo dei formati validi.",
-  "@enterTimeFormatTxt2": {},
-  "enterTimeFormatTxt3": "Avviso: l''uso di stringhe di formato più lungo o più corto non altera magicamente la larghezza delle colonne della tabella, il che potrebbe portare a problematiche interruzioni di riga e alla mancata visualizzazione del testo.",
-  "@enterTimeFormatTxt3": {},
   "lifetime": "Vita",
   "@lifetime": {},
   "confirmDeleteDesc": "Eliminare questa voce? (È possibile disabilitare questa richiesta di convalida nelle impostazioni.)",
@@ -347,8 +341,6 @@
       }
     }
   },
-  "enterTimeFormatTxt4": "predefinito: \"yy-MM-dd HH:mm\"",
-  "@enterTimeFormatTxt4": {},
   "confirmDelete": "Conferma eliminazione",
   "@confirmDelete": {},
   "day": "Giorno",
@@ -417,5 +409,7 @@
   "note": "Nota",
   "@note": {},
   "color": "Colore",
-  "@color": {}
+  "@color": {},
+  "enterTimeFormatDesc": "Una stringa di formattazione è un inseme di stringhe ICU/Skeleton predefinite e di qualsiasi testo aggiuntivo che si desidera aggiungere.\n\n[Qui è presente un elenco completo dei formati validi.](screen://TimeFormattingHelp)\n\nAvviso: l''uso di stringhe di formato più lungo o più corto non altera magicamente la larghezza delle colonne della tabella, il che potrebbe portare a problematiche interruzioni di riga e alla mancata visualizzazione del testo.\n\npredefinito: \"yy-MM-dd HH:mm\"",
+  "@enterTimeFormatDesc": {}
 }
lib/l10n/app_nb.arb
@@ -237,10 +237,6 @@
   "@warnAboutTxt2": {},
   "warnAboutTxt3": "Endre gjerne verdiene, og følg anbefalingene din doktor gir deg.",
   "@warnAboutTxt3": {},
-  "enterTimeFormatTxt2": "En fullstendig liste over gyldige formater er å finne her.",
-  "@enterTimeFormatTxt2": {},
-  "enterTimeFormatTxt4": "forvalg: \"yy-MM-dd HH:mm\"",
-  "@enterTimeFormatTxt4": {},
   "confirmDeleteDesc": "Slett oppføringen? (Du kan skru av disse bekreftelsene i innstillingene.)",
   "@confirmDeleteDesc": {},
   "weekOfYear": "Uke {weekNum}, {year}",
@@ -306,10 +302,6 @@
       }
     }
   },
-  "enterTimeFormatTxt3": "Bruk av lengre eller kortere formatstrenger endrer ikke også bredden på tabellkolonnene, noe som fører til linjeskift og tekst som ikke vises.",
-  "@enterTimeFormatTxt3": {},
-  "enterTimeFormatTxt1": "En formateringsstreng er en miks av predefinert ICU/Skeleton -strenger og all annen tekst du vil inkludere.",
-  "@enterTimeFormatTxt1": {},
   "exportWarnConfigNotImportable": "Gjør eksportoppsettet importerbart ved å sette eksporttypen til \\\"CSV\\\", skru på overskrift, inkluder feltene ''diastolic'', ''systolic'', ''pulse'', ''notes'', sammen med ett av de tilgjengelige tidsformatene.",
   "@exportWarnConfigNotImportable": {},
   "allowMissingValues": "Tillat manglende verdier",
@@ -374,5 +366,7 @@
   "note": "Notat",
   "@note": {},
   "color": "Farge",
-  "@color": {}
+  "@color": {},
+  "enterTimeFormatDesc": "En formateringsstreng er en miks av predefinert ICU/Skeleton -strenger og all annen tekst du vil inkludere.\n\n[En fullstendig liste over gyldige formater er å finne her.](screen://TimeFormattingHelp)\n\nBruk av lengre eller kortere formatstrenger endrer ikke også bredden på tabellkolonnene, noe som fører til linjeskift og tekst som ikke vises.\n\nforvalg: \"yy-MM-dd HH:mm\"",
+  "@enterTimeFormatDesc": {}
 }
lib/l10n/app_ru.arb
@@ -330,12 +330,8 @@
   "@warnAboutTxt2": {},
   "warnAboutTxt3": "Не стесняйтесь изменять значения в соответствии с вашими потребностями и следуйте рекомендациям вашего врача.",
   "@warnAboutTxt3": {},
-  "enterTimeFormatTxt2": "Если вам интересен полный список допустимых форматов, вы можете найти их прямо здесь.",
-  "@enterTimeFormatTxt2": {},
   "warnValues": "Предупредительные значения",
   "@warnValues": {},
-  "enterTimeFormatTxt4": "по умолчанию: \"гг-ММ-дд ЧЧ:мм\"",
-  "@enterTimeFormatTxt4": {},
   "month": "Месяц",
   "@month": {},
   "weekOfYear": "Неделя {weekNum}, {year}",
@@ -349,10 +345,6 @@
       }
     }
   },
-  "enterTimeFormatTxt1": "Строка форматирования - это смесь предопределенных строк ICU/Skeleton и любого дополнительного текста, который вы хотели бы включить.",
-  "@enterTimeFormatTxt1": {},
-  "enterTimeFormatTxt3": "Просто дружеское напоминание: использование более длинных или более коротких строк формата волшебным образом не изменит ширину столбцов таблицы, что может привести к некоторым неудобным разрывам строк и не отображению текста.",
-  "@enterTimeFormatTxt3": {},
   "enterTimeFormatString": "формат времени",
   "@enterTimeFormatString": {},
   "year": "Год",
@@ -372,5 +364,7 @@
   "confirmDelete": "Подтвердите удаление",
   "@confirmDelete": {},
   "errTimeAfterNow": "Выбранное время было сброшено, так как оно находится в будущем и ещё не наступило. Вы можете отключить эту проверку в настройках.",
-  "@errTimeAfterNow": {}
+  "@errTimeAfterNow": {},
+  "enterTimeFormatDesc": "Строка форматирования - это смесь предопределенных строк ICU/Skeleton и любого дополнительного текста, который вы хотели бы включить.\n\n[Если вам интересен полный список допустимых форматов, вы можете найти их прямо здесь.](screen://TimeFormattingHelp)\n\nПросто дружеское напоминание: использование более длинных или более коротких строк формата волшебным образом не изменит ширину столбцов таблицы, что может привести к некоторым неудобным разрывам строк и не отображению текста.\n\nпо умолчанию: \"yy-MM-dd HH:mm\"",
+  "@enterTimeFormatDesc": {}
 }
lib/l10n/app_tr.arb
@@ -58,16 +58,12 @@
   "@btnConfirm": {},
   "addMeasurement": "Ölçüm ekle",
   "@addMeasurement": {},
-  "enterTimeFormatTxt3": "Bir hatırlatma, uzun ya da kısa biçim String kullanmak tablodaki sütunların genişliğini değiştirmeyecek, ki bu da garip satır atlamalarına ve metnin gözükmemesine yol açabilir.",
-  "@enterTimeFormatTxt3": {},
   "startWithAddMeasurementPageDescription": "Uygulamanın açılışında, ölçüm giriş ekranı gösterilir.",
   "@startWithAddMeasurementPageDescription": {},
   "animationSpeed": "Animasyon süresi",
   "@animationSpeed": {},
   "licenses": "3. taraf lisanslar",
   "@licenses": {},
-  "enterTimeFormatTxt1": "Biçim stringi önceden tanımladan ICU/Skeleton stringlerinin ve eklemek istediğiniz herhangi başka metinin birleşimidir.",
-  "@enterTimeFormatTxt1": {},
   "exportPdfExportData": "Veri tablosu",
   "@exportPdfExportData": {},
   "allowManualTimeInput": "Elle süre girmeye izin ver",
@@ -188,8 +184,6 @@
   "@errNoValue": {},
   "other": "diğer",
   "@other": {},
-  "enterTimeFormatTxt2": "Tanımlanan biçimlerin bütünün bir listesini merak ettiyseniz burada bulabilirsiniz.",
-  "@enterTimeFormatTxt2": {},
   "exportWarnConfigNotImportable": "Hey! Sana dostça bir uyarı: Şu anki dışa aktarma ayarlarıyla içe aktarmak mümkün olmayacak. Bunu düzeltmek için dışa aktarma türünün CSV olduğuna emin olun, başlığı etkenliştirin ve uygun zaman biçimlerinden birini dahil edin.",
   "@exportWarnConfigNotImportable": {},
   "timestamp": "Zaman damgası",
@@ -381,8 +375,6 @@
   "@diaLong": {},
   "time": "Zaman",
   "@time": {},
-  "enterTimeFormatTxt4": "varsayılan: \"yy-MM-dd HH:mm\"",
-  "@enterTimeFormatTxt4": {},
   "custom": "Özel",
   "@custom": {},
   "day": "Gün",
@@ -415,5 +407,7 @@
   "confirmDeleteDesc": "Bu girişi sil? (Bu onaylama mesajını ayarlardan kapatabilirsiniz.)",
   "@confirmDeleteDesc": {},
   "errNoFileOpened": "herhangi bir dosya açılmadı",
-  "@errNoFileOpened": {}
+  "@errNoFileOpened": {},
+  "enterTimeFormatDesc": "Biçim stringi önceden tanımladan ICU/Skeleton stringlerinin ve eklemek istediğiniz herhangi başka metinin birleşimidir.\n\n[Tanımlanan biçimlerin bütünün bir listesini merak ettiyseniz burada bulabilirsiniz.](screen://TimeFormattingHelp)\n\nBir hatırlatma, uzun ya da kısa biçim String kullanmak tablodaki sütunların genişliğini değiştirmeyecek, ki bu da garip satır atlamalarına ve metnin gözükmemesine yol açabilir.\n\nvarsayılan: \"yy-MM-dd HH:mm\"",
+  "@enterTimeFormatDesc": {}
 }
lib/l10n/app_zh.arb
@@ -261,14 +261,6 @@
   "@warnAboutTxt2": {},
   "warnAboutTxt3": "您可以按需随意修改此值,请遵从医生的建议。",
   "@warnAboutTxt3": {},
-  "enterTimeFormatTxt1": "格式化字符串是一个预定义的ICU/Skeleton字符串和您想要包含的其他文字的混合体。",
-  "@enterTimeFormatTxt1": {},
-  "enterTimeFormatTxt2": "点击即可查看可用的格式化字符串的完整列表。",
-  "@enterTimeFormatTxt2": {},
-  "enterTimeFormatTxt3": " 友情提示:使用更长或更短的格式字符串不会改变表的列宽,还可能导致意外的换行和文字显示不全。",
-  "@enterTimeFormatTxt3": {},
-  "enterTimeFormatTxt4": "默认:\"yy-MM-dd HH:mm\"",
-  "@enterTimeFormatTxt4": {},
   "enterTimeFormatString": "时间格式",
   "@enterTimeFormatString": {},
   "dateFormatting": "日期格式",
@@ -305,5 +297,7 @@
         "type": "int"
       }
     }
-  }
+  },
+  "enterTimeFormatDesc": "格式化字符串是一个预定义的ICU/Skeleton字符串和您想要包含的其他文字的混合体。\n\n[点击即可查看可用的格式化字符串的完整列表。](screen://TimeFormattingHelp)\n\n友情提示:使用更长或更短的格式字符串不会改变表的列宽,还可能导致意外的换行和文字显示不全。\n\n默认:\"yy-MM-dd HH:mm\"",
+  "@enterTimeFormatDesc": {}
 }
lib/screens/subsettings/enter_timeformat.dart
@@ -1,110 +1,98 @@
-import 'package:blood_pressure_app/model/storage/settings_store.dart';
-import 'package:blood_pressure_app/screens/subsettings/time_formats_explainer.dart';
+import 'package:blood_pressure_app/screens/subsettings/export_field_format_documentation.dart';
 import 'package:flutter/material.dart';
 import 'package:flutter_gen/gen_l10n/app_localizations.dart';
-import 'package:provider/provider.dart';
+import 'package:flutter_markdown/flutter_markdown.dart';
+import 'package:intl/intl.dart';
 
-class EnterTimeFormatScreen extends StatefulWidget {
-  const EnterTimeFormatScreen({super.key});
+/// Dialoge that explains the time format and pops the context with either null or a time format string.
+class EnterTimeFormatDialoge extends StatefulWidget {
+  const EnterTimeFormatDialoge({super.key, required this.initialValue});
+
+  /// Text that is initially in time format field.
+  final String initialValue;
 
   @override
-  State<EnterTimeFormatScreen> createState() => _EnterTimeFormatScreenState();
+  State<EnterTimeFormatDialoge> createState() => _EnterTimeFormatDialogeState();
 }
 
-class _EnterTimeFormatScreenState extends State<EnterTimeFormatScreen> {
-  final GlobalKey<FormState> _formKey = GlobalKey<FormState>();
-  final _firstNode = FocusNode();
-  late String _newVal;
+class _EnterTimeFormatDialogeState extends State<EnterTimeFormatDialoge> {
+  final timeFormatFieldController = TextEditingController();
+  final focusNode = FocusNode();
+
+  @override
+  void initState() {
+    super.initState();
+    timeFormatFieldController.text = widget.initialValue;
+    timeFormatFieldController.addListener(() => setState(() {}));
+    focusNode.requestFocus();
+  }
+
+  @override
+  void dispose() {
+    timeFormatFieldController.dispose();
+    focusNode.dispose();
+    super.dispose();
+  }
 
   @override
   Widget build(BuildContext context) {
-    _firstNode.requestFocus();
+    final localizations = AppLocalizations.of(context)!;
     return Scaffold(
-      body: Center(
-        child: Form(
-          key: _formKey,
-          child: SingleChildScrollView(
-            child: Container(
-              padding: const EdgeInsets.all(60.0),
-              child: Column(
-                mainAxisAlignment: MainAxisAlignment.center,
-                crossAxisAlignment: CrossAxisAlignment.start,
-                children: [
-                  Text(AppLocalizations.of(context)!.enterTimeFormatTxt1),
-                  InkWell(
-                    onTap: () async {
-                      Navigator.push(
-                          context,
-                          MaterialPageRoute(
-                              builder: (context) =>
-                                  const TimeFormattingHelp()));
-                    },
-                    child: SizedBox(
-                      height: 65,
-                      child: Center(
-                        child: Text(
-                          AppLocalizations.of(context)!.enterTimeFormatTxt2,
-                          style: const TextStyle(color: Colors.blue),
-                        ),
-                      ),
-                    ),
-                  ),
-                  Text(AppLocalizations.of(context)!.enterTimeFormatTxt3),
-                  const SizedBox(
-                    height: 7,
-                  ),
-                  Text(AppLocalizations.of(context)!.enterTimeFormatTxt4),
-                  const SizedBox(
-                    height: 10,
-                  ),
-                  Consumer<Settings>(builder: (context, settings, child) {
-                    _newVal = settings.dateFormatString;
-                    return TextFormField(
-                      initialValue: _newVal,
-                      decoration: InputDecoration(
-                          hintText: AppLocalizations.of(context)!
-                              .enterTimeFormatString),
-                      validator: (String? value) {
-                        if (value == null || value.isEmpty) {
-                          return AppLocalizations.of(context)!.errNoValue;
-                        } else {
-                          _newVal = value;
-                        }
-                        return null;
-                      },
-                    );
-                  }),
-                  const SizedBox(
-                    height: 25,
+      appBar: AppBar(
+        forceMaterialTransparency: true,
+        leading: IconButton(
+          onPressed: () {
+            Navigator.of(context).pop(null);
+          },
+          icon: const Icon(Icons.close)
+        ),
+        actions: [
+          TextButton(
+            onPressed: () {
+              if(timeFormatFieldController.text.isNotEmpty) {
+                Navigator.of(context).pop(timeFormatFieldController.text);
+              }
+            },
+            child: Text(localizations.btnSave)
+          )
+        ],
+      ),
+      body: SingleChildScrollView(
+        child: Padding(
+          padding: const EdgeInsets.all(24),
+          child: Column(
+            children: [
+              Markdown(
+                shrinkWrap: true,
+                onTapLink: getLinkTapHandler(context),
+                physics: const NeverScrollableScrollPhysics(),
+                data: localizations.enterTimeFormatDesc
+              ),
+              Text(DateFormat(timeFormatFieldController.text).format(DateTime.now())),
+              Padding(
+                padding: const EdgeInsets.all(12),
+                child: TextField(
+                  controller: timeFormatFieldController,
+                  focusNode: focusNode,
+                  decoration: InputDecoration(
+                    border: const OutlineInputBorder(),
+                    labelText: localizations.enterTimeFormatString,
+                    errorText: timeFormatFieldController.text.isEmpty ? localizations.errNoValue : null,
                   ),
-                  Row(
-                    children: [
-                      TextButton(
-                          onPressed: () {
-                            Navigator.of(context).pop();
-                          },
-                          child: Text(AppLocalizations.of(context)!.btnCancel)),
-                      const Spacer(),
-                      FilledButton.icon(
-                          key: const Key('btnSave'),
-                          icon: const Icon(Icons.save),
-                          label: Text(AppLocalizations.of(context)!.btnSave),
-                          onPressed: () {
-                            if (_formKey.currentState!.validate()) {
-                              Provider.of<Settings>(context, listen: false)
-                                  .dateFormatString = _newVal;
-                              Navigator.of(context).pop();
-                            }
-                          },
-                      ),
-                    ],
-                  )
-                ],
+                ),
               ),
-            ),
+            ],
           ),
-        ),
+        )
       ),
     );
   }
 }
+
+/// Shows a dialoge that explains the ICU DateTime format and allows editing [initialTimeFormat] with a preview.
+///
+/// When canceled null is returned.
+Future<String?> showTimeFormatPickerDialoge(BuildContext context, String initialTimeFormat) =>
+    showDialog<String?>(context: context, builder: (context) => Dialog.fullscreen(
+        child: EnterTimeFormatDialoge(initialValue: initialTimeFormat),
+    ));
\ No newline at end of file
lib/screens/subsettings/export_field_format_documentation.dart
@@ -1,3 +1,5 @@
+import 'dart:async';
+
 import 'package:blood_pressure_app/screens/subsettings/time_formats_explainer.dart';
 import 'package:flutter/material.dart';
 import 'package:flutter_markdown/flutter_markdown.dart';
@@ -18,28 +20,32 @@ class InformationScreen extends StatelessWidget {
           padding: const EdgeInsets.all(10),
           child: Markdown(
             selectable: true,
-              onTapLink: (text, destination, title) async {
-                if (destination == null) {
-                  return;
-                }
-                if (destination.startsWith('http://') || destination.startsWith('https://')) {
-                  final url = Uri.tryParse(destination);
-                  if (url != null && await canLaunchUrl(url)) {
-                    launchUrl(url);
-                    return;
-                  }
-                } else if (destination.startsWith('screen://')) {
-                  switch (destination.split('//')[1]) {
-                    case 'TimeFormattingHelp':
-                      Navigator.of(context).push(MaterialPageRoute(builder: (context) => const TimeFormattingHelp()));
-                      return;
-                  }
-                }
-                assert(false, 'Markdown contains invalid URL');
-              },
+            onTapLink: getLinkTapHandler(context),
             data: text
           ),
         )
     );
   }
-}
\ No newline at end of file
+}
+
+typedef LinkTapHandler = FutureOr<void> Function(String, String?, String)?;
+
+LinkTapHandler getLinkTapHandler(BuildContext context) => (String text, String? destination, String title) async {
+  if (destination == null) {
+    return;
+  }
+  if (destination.startsWith('http://') || destination.startsWith('https://')) {
+    final url = Uri.tryParse(destination);
+    if (url != null && await canLaunchUrl(url)) {
+      launchUrl(url);
+      return;
+    }
+  } else if (destination.startsWith('screen://')) {
+    switch (destination.split('//')[1]) {
+      case 'TimeFormattingHelp':
+        Navigator.of(context).push(MaterialPageRoute(builder: (context) => const TimeFormattingHelp()));
+        return;
+    }
+  }
+  assert(false, 'Markdown contains invalid URL');
+};
\ No newline at end of file
lib/screens/settings.dart
@@ -45,11 +45,11 @@ class SettingsPage extends StatelessWidget {
                 leading: const Icon(Icons.schedule),
                 trailing: const Icon(Icons.arrow_forward_ios),
                 description: Text(settings.dateFormatString),
-                onPressed: (context) {
-                  Navigator.push(
-                    context,
-                    MaterialPageRoute(builder: (context) => const EnterTimeFormatScreen()),
-                  );
+                onPressed: (context) async {
+                  final pickedFormat = await showTimeFormatPickerDialoge(context, settings.dateFormatString);
+                  if (pickedFormat != null) {
+                    settings.dateFormatString = pickedFormat;
+                  }
                 },
               ),
               DropDownSettingsTile<ThemeMode>(
test/ui/navigation_test.dart
@@ -70,18 +70,18 @@ void main() {
       await widgetTester.pumpAndSettle();
 
       expect(find.byType(SettingsPage), findsOneWidget);
-      expect(find.byType(EnterTimeFormatScreen), findsNothing);
+      expect(find.byType(EnterTimeFormatDialoge), findsNothing);
       expect(find.byKey(const Key('EnterTimeFormatScreen')), findsOneWidget);
       await widgetTester.tap(find.byKey(const Key('EnterTimeFormatScreen')));
       await widgetTester.pumpAndSettle();
 
-      expect(find.byType(EnterTimeFormatScreen), findsOneWidget);
+      expect(find.byType(EnterTimeFormatDialoge), findsOneWidget);
     });
     // ...
   });
 }
 
-/// Creates a the same App as the main method 
+/// Creates a the same App as the main method.
 Future<void> pumpAppRoot(WidgetTester widgetTester, {
   Settings? settings,
   ExportSettings? exportSettings,