Commit ac14227

derdilla <derdilla06@gmail.com>
2023-08-03 15:38:30
add export configurations
1 parent 2795ad7
Changed files (5)
lib/components/export_item_order.dart
@@ -5,6 +5,7 @@ import 'package:badges/badges.dart' as badges;
 import 'package:blood_pressure_app/components/consistent_future_builder.dart';
 import 'package:blood_pressure_app/model/export_options.dart';
 import 'package:blood_pressure_app/screens/subsettings/export_column_data.dart';
+import 'package:blood_pressure_app/screens/subsettings/export_fields_presets_list.dart';
 import 'package:flutter/material.dart';
 import 'package:flutter_gen/gen_l10n/app_localizations.dart';
 import 'package:provider/provider.dart';
@@ -33,68 +34,111 @@ class _ExportItemsCustomizerState extends State<ExportItemsCustomizer> {
     return ConsistentFutureBuilder(
       future: _future!,
       onData: (BuildContext context, ExportConfigurationModel result) {
-        return badges.Badge(
-          badgeStyle: badges.BadgeStyle(
-            badgeColor: Theme.of(context).colorScheme.background,
-            padding: const EdgeInsets.all(10)
-          ),
-          position: badges.BadgePosition.bottomEnd(bottom: 3, end: 3),
-          badgeContent: Container(
-            decoration: BoxDecoration(
-                border: Border.all(color: Theme.of(context).colorScheme.onBackground),
-                shape: BoxShape.circle
-            ),
-            child: IconButton(
-              tooltip: AppLocalizations.of(context)!.addExportformat,
-              onPressed:() {
-                Navigator.of(context).push(MaterialPageRoute(builder: (context) =>
-                  EditExportColumnPage(onValidSubmit: (value) {
-                    result.addOrUpdate(value);
-                  },)
-                ));
-              },
-              icon: const Icon(Icons.add),
-            ),
-          ),
-          child: Container(
-            margin: const EdgeInsets.all(25),
-            padding: const EdgeInsets.all(20),
-            height: 420,
-            decoration: BoxDecoration(
-              border: Border.all(color: Theme.of(context).textTheme.labelLarge?.color ?? Colors.teal),
-              borderRadius: const BorderRadius.all(Radius.circular(10)),
-            ),
-            clipBehavior: Clip.hardEdge,
-            child: ReorderableListView(
-              shrinkWrap: true,
-              onReorder: _onReorderList,
-              children: <Widget>[
-                for (int i = 0; i < widget.shownItems.length; i += 1)
-                  ListTile(
-                    key: Key('l_${widget.shownItems[i].internalName}'),
-                    title: Text(widget.shownItems[i].columnTitle),
-                    trailing: _buildListItemTrailing( context, widget.shownItems[i]),
-                    contentPadding: EdgeInsets.zero
-                  ),
-                _buildListSectionDivider(context),
-                for (int i = 0; i < widget.hiddenItems.length; i += 1)
-                  ListTile(
-                    key: Key('ul_${widget.hiddenItems[i].internalName}'),
-                    title: Opacity(
-                      opacity: 0.7,
-                      child: Text(widget.hiddenItems[i].columnTitle),
-                    ),
-                    trailing: _buildListItemTrailing(context, widget.hiddenItems[i]),
-                    contentPadding: EdgeInsets.zero
-                  ),
-              ],
-            ),
-          ),
+        return _buildAddItemBadge(context, result,
+          child: _buildManagePresetsBadge(context, result,
+            child:_buildList(context))
         );
       },
     );
   }
 
+  Container _buildList(BuildContext context) {
+    return Container(
+        margin: const EdgeInsets.all(25),
+        padding: const EdgeInsets.all(20),
+        height: 420,
+        decoration: BoxDecoration(
+          border: Border.all(color: Theme.of(context).textTheme.labelLarge?.color ?? Colors.teal),
+          borderRadius: const BorderRadius.all(Radius.circular(10)),
+        ),
+        clipBehavior: Clip.hardEdge,
+        child: ReorderableListView(
+          shrinkWrap: true,
+          onReorder: _onReorderList,
+          children: <Widget>[
+            for (int i = 0; i < widget.shownItems.length; i += 1)
+              ListTile(
+                  key: Key('l_${widget.shownItems[i].internalName}'),
+                  title: Text(widget.shownItems[i].columnTitle),
+                  trailing: _buildListItemTrailing( context, widget.shownItems[i]),
+                  contentPadding: EdgeInsets.zero
+              ),
+            _buildListSectionDivider(context),
+            for (int i = 0; i < widget.hiddenItems.length; i += 1)
+              ListTile(
+                  key: Key('ul_${widget.hiddenItems[i].internalName}'),
+                  title: Opacity(
+                    opacity: 0.7,
+                    child: Text(widget.hiddenItems[i].columnTitle),
+                  ),
+                  trailing: _buildListItemTrailing(context, widget.hiddenItems[i]),
+                  contentPadding: EdgeInsets.zero
+              ),
+          ],
+        ),
+      );
+  }
+
+  Widget _buildAddItemBadge(BuildContext context, ExportConfigurationModel result, {required Widget child}) {
+    return badges.Badge(
+      badgeStyle: badges.BadgeStyle(
+        badgeColor: Theme.of(context).colorScheme.background,
+        padding: const EdgeInsets.all(10)
+      ),
+      position: badges.BadgePosition.bottomEnd(bottom: 3, end: 3),
+      badgeContent: Container(
+        decoration: BoxDecoration(
+          border: Border.all(color: Theme.of(context).colorScheme.onBackground),
+          shape: BoxShape.circle
+        ),
+        child: IconButton(
+          tooltip: AppLocalizations.of(context)!.addExportformat,
+          onPressed:() {
+            Navigator.of(context).push(MaterialPageRoute(builder: (context) =>
+              EditExportColumnPage(onValidSubmit: (value) {
+                result.addOrUpdate(value);
+              },)
+            ));
+          },
+          icon: const Icon(Icons.add),
+        ),
+      ),
+      child: child,
+    );
+  }
+
+  Widget _buildManagePresetsBadge(BuildContext context, ExportConfigurationModel result, {required Widget child}) {
+    final localizations = AppLocalizations.of(context)!;
+    return badges.Badge(
+      position: badges.BadgePosition.topEnd(top: 3, end: 3),
+      badgeStyle: badges.BadgeStyle(
+        badgeColor: Theme.of(context).colorScheme.background,
+        padding: const EdgeInsets.all(5)
+      ),
+      badgeContent: PopupMenuButton<int>(
+        icon: const Icon(Icons.collections_bookmark),
+        itemBuilder: (BuildContext context) {
+          return [
+            PopupMenuItem<int>(value: 0, child: Text(localizations.default_)),
+            const PopupMenuItem<int>(value: 1, child: Text('"My Heart" export'))
+          ];
+        },
+        onSelected: (value) {
+          switch (value) {
+            case 0:
+              result.settings.exportItems = ['timestampUnixMs', 'systolic', 'diastolic', 'pulse', 'notes'];
+              return;
+            case 1:
+              result.settings.exportItems = ['DATUM', 'SYSTOLE', 'DIASTOLE', 'PULS', 'Beschreibung', 'Tags', 'Gewicht', 'Sauerstoffsättigung'];
+              return;
+          }
+          assert(false);
+        },
+      ),
+      child: child,
+    );
+  }
+
   Widget _buildListItemTrailing(BuildContext context, ExportColumn data) {
     return Row(
       mainAxisSize: MainAxisSize.min,
lib/l10n/app_en.arb
@@ -381,5 +381,9 @@
   "delete": "Delete",
   "@delete": {},
   "exportFieldFormatDocumentation": "'## Variables\nThe export field format support inserting values for the following placeholders:\n- `$TIMESTAMP:` Represents the time since the Unix epoch in milliseconds.\n- `$SYS:` Provides a value if available; otherwise, it defaults to -1.\n- `$DIA:` Provides a value if available; otherwise, it defaults to -1.\n- `$PUL:` Provides a value if available; otherwise, it defaults to -1.\n- `$NOTE:` Provides a value if available; otherwise, it defaults to -1.\n\nIf any of the placeholders mentioned above are not present in the blood pressure record, they will be replaced with -1.\n\n## Math\nYou can use basic mathematics inside double brackets (\"`{{}}`\").\n\nThe following mathematical operations are supported:\n- Operations: +, -, *, /, %, ^\n- One-parameter functions: abs, acos, asin, atan, ceil, cos, cosh, cot, coth, csc, csch, exp, floor, ln, log, round sec, sech, sin, sinh, sqrt, tan, tanh \n- Two-parameter functions: log, nrt, pow\n- Constants: e, pi, ln2, ln10, log2e, log10e, sqrt1_2, sqrt2\nFor the full math interpreter specification, you can refer to the [function_tree](https://pub.dev/documentation/function_tree/latest#interpreter) specification\n\n## Time\nTo format a timestamp, use the following syntax: `$FORMAT{<timestamp>,<formatString>}`. The `<formatString>` supports the same format as described on the ICU/Skeleton string [documentation page](screen://TimeFormattingHelp).\n\n## Processing order\n1. variable replacement\n2. Math\n3. Date format'",
-  "@exportFieldFormatDocumentation": {}
+  "@exportFieldFormatDocumentation": {},
+  "presets": "Presets",
+  "@presets": {},
+  "default_": "Default",
+  "@default_": {}
 }
lib/model/export_import.dart
@@ -68,7 +68,7 @@ class ExportFileCreator {
     if (settings.exportCustomEntries) {
       exportItems = exportColumnsConfig.getActiveExportColumns();
     } else {
-      exportItems = exportColumnsConfig.getDefaultFormates();
+      exportItems = exportColumnsConfig.getDefaultFormates().where((e) => ['timestampUnixMs','systolic','diastolic','pulse','notes'].contains(e.internalName)).toList();
     }
 
     var csvHead = '';
lib/model/export_options.dart
@@ -56,14 +56,23 @@ class ExportConfigurationModel {
     return activeFields;
   }
   
-  List<ExportColumn> getDefaultFormates() => [
+  List<ExportColumn> getDefaultFormates() => [ // TODO: hidde fields unless user wants to explicitly see them
     ExportColumn(internalName: 'timestampUnixMs', columnTitle: localizations.unixTimestamp, formatPattern: r'$TIMESTAMP', editable: false),
     ExportColumn(internalName: 'formattedTimestamp', columnTitle: localizations.time, formatPattern: '\$FORMAT{\$TIMESTAMP,${settings.dateFormatString}}', editable: false),
     ExportColumn(internalName: 'systolic', columnTitle: localizations.sysLong, formatPattern: r'$SYS', editable: false),
     ExportColumn(internalName: 'diastolic', columnTitle: localizations.diaLong, formatPattern: r'$DIA', editable: false),
     ExportColumn(internalName: 'pulse', columnTitle: localizations.pulLong, formatPattern: r'$PUL', editable: false),
     ExportColumn(internalName: 'notes', columnTitle: localizations.notes, formatPattern: r'$NOTE', editable: false),
-    ExportColumn(internalName: 'pulsePressure', columnTitle: localizations.pulsePressure, formatPattern: r'{{$SYS-$DIA}}', editable: false)
+    ExportColumn(internalName: 'pulsePressure', columnTitle: localizations.pulsePressure, formatPattern: r'{{$SYS-$DIA}}', editable: false),
+
+    ExportColumn(internalName: 'DATUM', columnTitle: '"My Heart" export time', formatPattern: r'$FORMAT{$TIMESTAMP,yyyy-mm-dd HH:mm:ss}', editable: false),
+    ExportColumn(internalName: 'SYSTOLE', columnTitle: '"My Heart" export sys', formatPattern: r'$SYS', editable: false),
+    ExportColumn(internalName: 'DIASTOLE', columnTitle: '"My Heart" export dia', formatPattern: r'$DIA', editable: false),
+    ExportColumn(internalName: 'PULS', columnTitle: '"My Heart" export pul', formatPattern: r'$PUL', editable: false),
+    ExportColumn(internalName: 'Beschreibung', columnTitle: '"My Heart" export description', formatPattern: r'null', editable: false),
+    ExportColumn(internalName: 'Tags', columnTitle: '"My Heart" export tags', formatPattern: r'', editable: false),
+    ExportColumn(internalName: 'Gewicht', columnTitle: '"My Heart" export weight', formatPattern: r'0.0', editable: false),
+    ExportColumn(internalName: 'Sauerstoffsättigung', columnTitle: '"My Heart" export oxygen', formatPattern: r'0', editable: false),
   ];
 
   void addOrUpdate(ExportColumn format) {
lib/screens/subsettings/export_import_screen.dart
@@ -214,7 +214,7 @@ class _ExportWarnBannerState extends State<ExportWarnBanner> {
     return Consumer<Settings>(builder: (context, settings, child) {
       if (_showWarnBanner && ![ExportFormat.csv, ExportFormat.db].contains(settings.exportFormat) ||
           settings.exportCsvHeadline == false ||
-          settings.exportCustomEntries && !(['timestampUnixMs','isoUTCTime'].any((i) => settings.exportItems.contains(i))) ||
+          settings.exportCustomEntries && !(['timestampUnixMs'].any((i) => settings.exportItems.contains(i))) ||
           ![',', '|'].contains(settings.csvFieldDelimiter) ||
           !['"', '\''].contains(settings.csvTextDelimiter)
       ) {