Commit 299e9fa

derdilla <derdilla06@gmail.com>
2023-06-21 16:06:27
add more option to export in iso format
1 parent 642b803
lib/l10n/app_de.arb
@@ -39,6 +39,7 @@
   "errPleaseSelect": "Bitte auswählen",
   "errNotCsvFormat": "Es können nur Dateien im csv Format importiert werden.",
   "errNeedHeadline": "Es können nur Dateien mit einer Überschrift importiert werden.",
+  "errNotImportable": "Diese Datei kann nicht importiert werden.",
 
 
   "btnCancel": "ABBRUCH",
lib/l10n/app_en.arb
@@ -40,6 +40,7 @@
   "errNotCsvFormat": "You can only import files in csv format.",
   "errNeedHeadline": "You can only import files with a headline.",
   "errCantReadFile": "The file contents can not be read",
+  "errNotImportable": "This file can't be imported",
 
   "btnCancel": "CANCEL",
   "btnSave": "SAVE",
lib/model/export_import.dart
@@ -40,6 +40,9 @@ class DataExporter {
             case 'timestampUnixMs':
               row.add(record.creationTime.millisecondsSinceEpoch);
               break;
+            case 'isoUTCTime':
+              row.add(record.creationTime.toIso8601String());
+              break;
             case 'systolic':
               row.add(record.systolic);
               break;
@@ -76,6 +79,7 @@ class DataExporter {
     final csvLines = converter.convert(fileContents);
     final attributes = csvLines.removeAt(0);
     var creationTimePos = -1;
+    var isoTimePos = -1;
     var sysPos = -1;
     var diaPos = -1;
     var pulPos = -1;
@@ -85,6 +89,9 @@ class DataExporter {
         case 'timestampUnixMs':
           creationTimePos = i;
           break;
+        case 'isoUTCTime':
+          isoTimePos = i;
+          break;
         case 'systolic':
           sysPos = i;
           break;
@@ -99,7 +106,7 @@ class DataExporter {
           break;
       }
     }
-    assert(creationTimePos >= 0);
+    assert(creationTimePos >= 0 || isoTimePos >= 0);
     assert(sysPos >= 0);
     assert(diaPos >= 0);
     assert(pulPos >= 0);
@@ -108,7 +115,7 @@ class DataExporter {
     for (final line in csvLines) {
       records.add(
           BloodPressureRecord(
-              DateTime.fromMillisecondsSinceEpoch(line[creationTimePos]),
+              (creationTimePos >= 0 ) ? DateTime.fromMillisecondsSinceEpoch(line[creationTimePos]) : DateTime.parse(line[isoTimePos]),
               line[sysPos],
               line[diaPos],
               line[pulPos],
lib/model/ram_only_implementations.dart
@@ -106,7 +106,7 @@ class RamSettings extends ChangeNotifier implements Settings {
   ExportFormat _exportFormat = ExportFormat.csv;
   String _csvFieldDelimiter = ',';
   String _csvTextDelimiter = '"';
-  List<String> _exportAddableItems = [];
+  List<String> _exportAddableItems = ['isoUTCTime'];
   bool _exportCsvHeadline = true;
   bool _exportCustomEntries = false;
   DateTimeRange _exportDataRange = DateTimeRange(start: DateTime.fromMillisecondsSinceEpoch(0), end: DateTime.fromMillisecondsSinceEpoch(0));
lib/model/settings_store.dart
@@ -365,7 +365,7 @@ class Settings extends ChangeNotifier {
   }
   
   List<String> get exportAddableItems {
-    return _prefs.getStringList('exportAddableItems') ?? [];
+    return _prefs.getStringList('exportAddableItems') ?? ['isoUTCTime'];
   }
 
   set exportAddableItems(List<String> value) {
lib/screens/subsettings/export_import_screen.dart
@@ -14,6 +14,7 @@ import 'package:intl/intl.dart';
 import 'package:provider/provider.dart';
 import 'package:share_plus/share_plus.dart';
 
+// FIXME: Export/import buttons overlap with content on snack bar
 class ExportImportScreen extends StatelessWidget {
   const ExportImportScreen({super.key});
 
@@ -222,15 +223,19 @@ class ExportImportScreen extends StatelessWidget {
                           content: Text(AppLocalizations.of(context)!.errCantReadFile)));
                       return;
                     }
-                    
-                    var fileContents = DataExporter(settings).parseCSVFile(binaryContent);
-                    ScaffoldMessenger.of(context).showSnackBar(SnackBar(
-                        content: Text(AppLocalizations.of(context)!.importSuccess(fileContents.length))));
-                    var model = Provider.of<BloodPressureModel>(context, listen: false);
-                    for (final e in fileContents) {
-                      model.add(e);
-                    }
 
+                    try {
+                      var fileContents = DataExporter(settings).parseCSVFile(binaryContent);
+                      ScaffoldMessenger.of(context).showSnackBar(SnackBar(
+                          content: Text(AppLocalizations.of(context)!.importSuccess(fileContents.length))));
+                      var model = Provider.of<BloodPressureModel>(context, listen: false);
+                      for (final e in fileContents) {
+                        model.add(e);
+                      }
+                    } catch (e) {
+                      ScaffoldMessenger.of(context).showSnackBar(SnackBar(
+                          content: Text(AppLocalizations.of(context)!.errNotImportable)));
+                    }
                   },
                 )
               ),
@@ -270,7 +275,7 @@ class CsvItemsOrderCreator extends StatelessWidget {
 
             settings.exportItems = exportItems;
           },
-          footer: (settings.exportAddableItems.isNotEmpty) ? InkWell(
+          footer: (settings.exportItems.length < 5) ? InkWell(
             onTap: () async {
               await showDialog(context: context,
                 builder: (context) {
test/model/settings_test.dart
@@ -44,7 +44,7 @@ void main() {
       expect(s.csvFieldDelimiter, ',');
       expect(s.csvTextDelimiter, '"');
       expect(s.exportItems, ['timestampUnixMs', 'systolic', 'diastolic', 'pulse', 'notes']);
-      expect(s.exportAddableItems, []);
+      expect(s.exportAddableItems, ['isoUTCTime']);
       expect(s.exportCsvHeadline, true);
       expect(s.exportDataRange.start.millisecondsSinceEpoch, 0);
       expect(s.exportLimitDataRange, false);
@@ -92,7 +92,7 @@ void main() {
       s.csvFieldDelimiter = '|';
       s.csvTextDelimiter = '\'';
       s.exportAddableItems = ['timestampUnixMs'];
-      s.exportItems = ['systolic', 'diastolic', 'pulse', 'notes'];
+      s.exportItems = ['systolic', 'diastolic', 'pulse', 'notes', 'isoUTCTime'];
       s.exportCsvHeadline = false;
       s.exportLimitDataRange = true;
       s.exportMimeType = MimeType.pdf;
@@ -118,7 +118,7 @@ void main() {
       expect(s.graphTitlesCount, 7);
       expect(s.csvFieldDelimiter, '|');
       expect(s.csvTextDelimiter, '\'');
-      expect(s.exportItems, ['systolic', 'diastolic', 'pulse', 'notes']);
+      expect(s.exportItems, ['systolic', 'diastolic', 'pulse', 'notes', 'isoUTCTime']);
       expect(s.exportAddableItems, ['timestampUnixMs']);
       expect(s.exportCsvHeadline, false);
       expect(s.exportLimitDataRange, true);
@@ -157,7 +157,7 @@ void main() {
       s.csvFieldDelimiter = '|';
       s.csvTextDelimiter = '\'';
       s.exportAddableItems = ['timestampUnixMs'];
-      s.exportItems = ['systolic', 'diastolic', 'pulse', 'notes'];
+      s.exportItems = ['systolic', 'diastolic', 'pulse', 'notes', 'isoUTCTime'];
       s.exportCsvHeadline = false;
       s.exportDataRange = DateTimeRange(start: DateTime.fromMillisecondsSinceEpoch(20), end: DateTime.now());
       s.exportLimitDataRange = true;
@@ -201,7 +201,7 @@ void main() {
       expect(s.csvFieldDelimiter, ',');
       expect(s.csvTextDelimiter, '"');
       expect(s.exportItems, ['timestampUnixMs', 'systolic', 'diastolic', 'pulse', 'notes']);
-      expect(s.exportAddableItems, []);
+      expect(s.exportAddableItems, ['isoUTCTime']);
       expect(s.exportCsvHeadline, true);
       expect(s.exportDataRange.start.millisecondsSinceEpoch, 0);
       expect(s.exportLimitDataRange, false);
@@ -249,7 +249,7 @@ void main() {
       s.csvFieldDelimiter = '|';
       s.csvTextDelimiter = '\'';
       s.exportAddableItems = ['timestampUnixMs'];
-      s.exportItems = ['systolic', 'diastolic', 'pulse', 'notes'];
+      s.exportItems = ['systolic', 'diastolic', 'pulse', 'notes', 'isoUTCTime'];
       s.exportCsvHeadline = false;
       s.exportLimitDataRange = true;
       s.exportMimeType = MimeType.pdf;
@@ -275,7 +275,7 @@ void main() {
       expect(s.graphTitlesCount, 7);
       expect(s.csvFieldDelimiter, '|');
       expect(s.csvTextDelimiter, '\'');
-      expect(s.exportItems, ['systolic', 'diastolic', 'pulse', 'notes']);
+      expect(s.exportItems, ['systolic', 'diastolic', 'pulse', 'notes', 'isoUTCTime']);
       expect(s.exportAddableItems, ['timestampUnixMs']);
       expect(s.exportCsvHeadline, false);
       expect(s.exportLimitDataRange, true);
@@ -314,7 +314,7 @@ void main() {
       s.csvFieldDelimiter = '|';
       s.csvTextDelimiter = '\'';
       s.exportAddableItems = ['timestampUnixMs'];
-      s.exportItems = ['systolic', 'diastolic', 'pulse', 'notes'];
+      s.exportItems = ['systolic', 'diastolic', 'pulse', 'notes', 'isoUTCTime'];
       s.exportCsvHeadline = false;
       s.exportDataRange = DateTimeRange(start: DateTime.fromMillisecondsSinceEpoch(20), end: DateTime.now());
       s.exportLimitDataRange = true;