Commit 6ddfc9f

derdilla <derdilla06@gmail.com>
2023-07-12 22:37:08
make BloodPressureRecord fields nullable
1 parent 13c87be
lib/components/measurement_graph.dart
@@ -52,14 +52,20 @@ class _LineChartState extends State<_LineChart> {
                         int pulMax = 0;
                         int diaMax = 0;
                         int sysMax = 0;
-                        for (var element in data) {
-                          final x = element.creationTime.millisecondsSinceEpoch.toDouble();
-                          diastolicSpots.add(FlSpot(x, element.diastolic.toDouble()));
-                          systolicSpots.add(FlSpot(x, element.systolic.toDouble()));
-                          pulseSpots.add(FlSpot(x, element.pulse.toDouble()));
-                          pulMax = max(pulMax, element.pulse);
-                          diaMax = max(diaMax, element.diastolic);
-                          sysMax = max(sysMax, element.systolic);
+                        for (var e in data) {
+                          final x = e.creationTime.millisecondsSinceEpoch.toDouble();
+                          if (e.diastolic != null) {
+                            diastolicSpots.add(FlSpot(x, e.diastolic!.toDouble()));
+                            diaMax = max(diaMax, e.diastolic!);
+                          }
+                          if (e.systolic != null) {
+                            systolicSpots.add(FlSpot(x, e.systolic!.toDouble()));
+                            sysMax = max(sysMax, e.systolic!);
+                          }
+                          if (e.pulse != null) {
+                            pulseSpots.add(FlSpot(x, e.pulse!.toDouble()));
+                            pulMax = max(pulMax, e.pulse!);
+                          }
                         }
 
                         const noTitels = AxisTitles(sideTitles: SideTitles(reservedSize: 40, showTitles: false));
lib/components/measurement_list.dart
@@ -73,7 +73,7 @@ class MeasurementList extends StatelessWidget {
               return ConsistentFutureBuilder<UnmodifiableListView<BloodPressureRecord>>(
                 future: items,
                 onData: (context, data) {
-                  if (data.isNotEmpty && data.first.diastolic > 0) {
+                  if (data.isNotEmpty) {
                     return ListView.builder(
                         itemCount: data.length,
                         shrinkWrap: true,
@@ -93,10 +93,10 @@ class MeasurementList extends StatelessWidget {
                                       MaterialPageRoute(
                                           builder: (context) => AddMeasurementPage(
                                             initTime: data[index].creationTime,
-                                            initSys: data[index].systolic,
-                                            initDia: data[index].diastolic,
-                                            initPul: data[index].pulse,
-                                            initNote: data[index].notes,
+                                            initSys: data[index].systolic ?? -1,
+                                            initDia: data[index].diastolic ?? -1,
+                                            initPul: data[index].pulse ?? -1,
+                                            initNote: data[index].notes ?? '',
                                             isEdit: true,
                                           )),
                                     );
@@ -176,13 +176,17 @@ class MeasurementList extends StatelessWidget {
                                         flex: _tableElementsSizes[0],
                                         child: Text(formatter.format(data[index].creationTime))),
                                     Expanded(
-                                        flex: _tableElementsSizes[1], child: Text(data[index].systolic.toString())),
+                                        flex: _tableElementsSizes[1],
+                                        child: Text((data[index].systolic ?? '').toString())),
                                     Expanded(
                                         flex: _tableElementsSizes[2],
-                                        child: Text(data[index].diastolic.toString())),
+                                        child: Text((data[index].diastolic ?? '').toString())),
                                     Expanded(
-                                        flex: _tableElementsSizes[3], child: Text(data[index].pulse.toString())),
-                                    Expanded(flex: _tableElementsSizes[4], child: Text(data[index].notes)),
+                                        flex: _tableElementsSizes[3],
+                                        child: Text((data[index].pulse ?? '').toString())),
+                                    Expanded(
+                                        flex: _tableElementsSizes[4],
+                                        child: Text(data[index].notes ?? '')),
                                     Expanded(
                                       flex: _sideFlex,
                                       child: const SizedBox(),
lib/model/blood_pressure.dart
@@ -166,8 +166,8 @@ class BloodPressureModel extends ChangeNotifier {
   List<BloodPressureRecord> _convert(List<Map<String, Object?>> dbResult) {
     List<BloodPressureRecord> records = [];
     for (var e in dbResult) {
-      records.add(BloodPressureRecord(DateTime.fromMillisecondsSinceEpoch(e['timestamp'] as int), e['systolic'] as int,
-          e['diastolic'] as int, e['pulse'] as int, e['notes'].toString()));
+      records.add(BloodPressureRecord(DateTime.fromMillisecondsSinceEpoch(e['timestamp'] as int), e['systolic'] as int?,
+          e['diastolic'] as int?, e['pulse'] as int?, e['notes'].toString()));
     }
     return records;
   }
@@ -176,10 +176,10 @@ class BloodPressureModel extends ChangeNotifier {
 @immutable
 class BloodPressureRecord {
   final DateTime creationTime;
-  final int systolic;
-  final int diastolic;
-  final int pulse;
-  final String notes;
+  final int? systolic;
+  final int? diastolic;
+  final int? pulse;
+  final String? notes;
 
   const BloodPressureRecord(
       this.creationTime, this.systolic, this.diastolic, this.pulse, this.notes);
lib/model/blood_pressure_analyzer.dart
@@ -38,11 +38,11 @@ class BloodPressureAnalyser {
 
     // sort all data
     final dbRes = await _model.all;
-    for (var entry in dbRes) {
-      DateTime ts = DateTime.fromMillisecondsSinceEpoch(entry.creationTime.millisecondsSinceEpoch);
-      allDiaValuesRelativeToTime[ts.hour].add(entry.diastolic);
-      allSysValuesRelativeToTime[ts.hour].add(entry.systolic);
-      allPulValuesRelativeToTime[ts.hour].add(entry.pulse);
+    for (var e in dbRes) {
+      DateTime ts = DateTime.fromMillisecondsSinceEpoch(e.creationTime.millisecondsSinceEpoch);
+      if (e.diastolic != null) allDiaValuesRelativeToTime[ts.hour].add(e.diastolic!);
+      if (e.systolic != null)allSysValuesRelativeToTime[ts.hour].add(e.systolic!);
+      if (e.pulse != null)allPulValuesRelativeToTime[ts.hour].add(e.pulse!);
     }
     for (int i = 0; i < 24; i++) {
       if (allDiaValuesRelativeToTime[i].isEmpty) {
lib/model/export_import.dart
@@ -20,7 +20,7 @@ import 'package:sqflite/sqflite.dart';
 
 import 'blood_pressure.dart';
 
-class ExportFileCreator {
+class ExportFileCreator { // TODO: check result
   Settings settings;
 
   ExportFileCreator(this.settings);
@@ -186,10 +186,10 @@ class ExportFileCreator {
                     pw.TableRow(
                         children: [
                           pw.Text(entry.creationTime.toIso8601String()),
-                          pw.Text(entry.systolic.toString()),
-                          pw.Text(entry.diastolic.toString()),
-                          pw.Text(entry.pulse.toString()),
-                          pw.Text(entry.notes)
+                          pw.Text((entry.systolic ?? '').toString()),
+                          pw.Text((entry.diastolic ?? '').toString()),
+                          pw.Text((entry.pulse ?? '').toString()),
+                          pw.Text(entry.notes ?? '')
                         ]
                     )
                 ]
lib/model/ram_only_implementations.dart
@@ -1,4 +1,5 @@
 import 'dart:collection';
+import 'dart:math';
 
 import 'package:blood_pressure_app/model/blood_pressure.dart';
 import 'package:blood_pressure_app/model/export_import.dart';
@@ -38,31 +39,31 @@ class RamBloodPressureModel extends ChangeNotifier implements BloodPressureModel
   Future<int> get count async => _records.length;
 
   @override
-  Future<int> get avgDia async => _records.map((e) => e.diastolic).reduce((a, b) => a + b) ~/ _records.length;
+  Future<int> get avgDia async => _records.where((e) => e.diastolic!=null).map((e) => e.diastolic).reduce((a, b) => a! + b!)??0 ~/ _records.length;
 
   @override
-  Future<int> get avgPul async => _records.map((e) => e.pulse).reduce((a, b) => a + b) ~/ _records.length;
+  Future<int> get avgPul async => _records.where((e) => e.pulse!=null).map((e) => e.pulse).reduce((a, b) => a! + b!)??0 ~/ _records.length;
 
   @override
-  Future<int> get avgSys async => _records.map((e) => e.systolic).reduce((a, b) => a + b) ~/ _records.length;
+  Future<int> get avgSys async => _records.where((e) => e.systolic!=null).map((e) => e.systolic).reduce((a, b) => a! + b!)??0 ~/ _records.length;
 
   @override
-  Future<int> get maxDia async => _records.reduce((a, b) => (a.diastolic >= b.diastolic) ? a : b).diastolic;
+  Future<int> get maxDia async => _records.where((e) => e.diastolic!=null).map<int>((e) => e.diastolic!).reduce(max);
 
   @override
-  Future<int> get maxPul async => _records.reduce((a, b) => (a.pulse >= b.pulse) ? a : b).pulse;
+  Future<int> get maxPul async => _records.where((e) => e.pulse!=null).map<int>((e) => e.pulse!).reduce(max);
 
   @override
-  Future<int> get maxSys async => _records.reduce((a, b) => (a.systolic >= b.systolic) ? a : b).systolic;
+  Future<int> get maxSys async => _records.where((e) => e.systolic!=null).map<int>((e) => e.systolic!).reduce(max);
 
   @override
-  Future<int> get minDia async => _records.reduce((a, b) => (a.diastolic <= b.diastolic) ? a : b).diastolic;
+  Future<int> get minDia async => _records.where((e) => e.diastolic!=null).map<int>((e) => e.diastolic!).reduce(min);
 
   @override
-  Future<int> get minPul async => _records.reduce((a, b) => (a.pulse <= b.pulse) ? a : b).pulse;
+  Future<int> get minPul async => _records.where((e) => e.pulse!=null).map<int>((e) => e.pulse!).reduce(min);
 
   @override
-  Future<int> get minSys async => _records.reduce((a, b) => (a.systolic <= b.systolic) ? a : b).systolic;
+  Future<int> get minSys async => _records.where((e) => e.systolic!=null).map<int>((e) => e.systolic!).reduce(min);
 
   @override
   Future<DateTime> get firstDay async {
lib/model/settings_store.dart
@@ -437,7 +437,7 @@ class Settings extends ChangeNotifier {
   }
 }
 
-class TimeStep {
+class TimeStep { // TODO: replace with enum
   static const options = [0, 4, 1, 2, 3, 5, 6];
 
   static const day = 0;
lib/screens/add_measurement.dart
@@ -8,6 +8,7 @@ import 'package:flutter_gen/gen_l10n/app_localizations.dart';
 import 'package:intl/intl.dart';
 import 'package:provider/provider.dart';
 
+// TODO: rewrite; this can be far more compact and is way to monolithic
 class AddMeasurementPage extends StatefulWidget {
   final DateTime? initTime;
   final int initSys;
@@ -113,6 +114,11 @@ class _AddMeasurementPageState extends State<AddMeasurementPage> {
                         }
                       },
                       validator: (String? value) {
+                        // TMP TODO REMOVE
+                        _systolic = int.tryParse(value??'') ?? -1;
+                        return null;
+                        // TMP END
+
                         if (value == null || value.isEmpty || (int.tryParse(value) == null)) {
                           return AppLocalizations.of(context)?.errNaN;
                         } else if (settings.validateInputs && (int.tryParse(value) ?? -1) <= 30) {
@@ -141,6 +147,10 @@ class _AddMeasurementPageState extends State<AddMeasurementPage> {
                         }
                       },
                       validator: (String? value) {
+                        // TMP TODO REMOVE
+                        _diastolic = int.tryParse(value??'') ?? -1;
+                        return null;
+                        // TMP END
                         if (value == null || value.isEmpty || (int.tryParse(value) == null)) {
                           return AppLocalizations.of(context)?.errNaN;
                         } else if (settings.validateInputs && (int.tryParse(value) ?? -1) <= 30) {
@@ -171,6 +181,11 @@ class _AddMeasurementPageState extends State<AddMeasurementPage> {
                         }
                       },
                       validator: (String? value) {
+                        // TMP TODO REMOVE
+                        _pulse = int.tryParse(value??'') ?? -1;
+                        return null;
+                        // TMP END
+
                         if (value == null || value.isEmpty || (int.tryParse(value) == null)) {
                           return AppLocalizations.of(context)?.errNaN;
                         } else if (settings.validateInputs && (int.tryParse(value) ?? -1) <= 30) {
@@ -204,9 +219,9 @@ class _AddMeasurementPageState extends State<AddMeasurementPage> {
                             if (widget.isEdit) {
                               Provider.of<BloodPressureModel>(context, listen: false).add(BloodPressureRecord(
                                   widget.initTime ?? DateTime.now(),
-                                  widget.initSys,
-                                  widget.initDia,
-                                  widget.initPul,
+                                  _nullInvalidInt(widget.initSys),
+                                  _nullInvalidInt(widget.initDia),
+                                  _nullInvalidInt(widget.initPul),
                                   widget.initNote));
                             }
                             Navigator.of(context).pop();
@@ -223,7 +238,7 @@ class _AddMeasurementPageState extends State<AddMeasurementPage> {
                               final exporter = Exporter(context);
                               final navigator = Navigator.of(context);
 
-                              await model.add(BloodPressureRecord(_time, _systolic, _diastolic, _pulse, _note));
+                              await model.add(BloodPressureRecord(_time, _nullInvalidInt(_systolic), _nullInvalidInt(_diastolic), _nullInvalidInt(_pulse), _note));
                               if (settings.exportAfterEveryEntry) {
                                 exporter.export();
                               }
@@ -242,4 +257,8 @@ class _AddMeasurementPageState extends State<AddMeasurementPage> {
       ),
     );
   }
+
+  int? _nullInvalidInt(int i) {
+    return (i >= 0) ? i : null;
+  }
 }