Commit 299e9fa
Changed files (7)
lib
screens
subsettings
test
model
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;