Commit fdd480f

derdilla <derdilla06@gmail.com>
2023-04-30 06:50:24
FEAT: show saved pressures in List
1 parent 0e1b3cb
lib/components/measurement_graph.dart
@@ -1,1 +1,11 @@
-// TODO
\ No newline at end of file
+import 'package:flutter/material.dart';
+
+class MeasurementGraph extends StatelessWidget {
+  const MeasurementGraph({super.key});
+
+  @override
+  Widget build(BuildContext context) {
+    // TODO: implement build
+    return Container();
+  }
+}
\ No newline at end of file
lib/components/measurement_list.dart
@@ -1,1 +1,65 @@
-// TODO
\ No newline at end of file
+import 'package:blood_pressure_app/model/blood_pressure.dart';
+import 'package:flutter/material.dart';
+import 'package:provider/provider.dart';
+
+class MeasurementList extends StatelessWidget {
+  const MeasurementList({super.key});
+
+  @override
+  Widget build(BuildContext context) {
+    // TODO: implement build
+    return Container(
+        child: Consumer<BloodPressureModel>(
+          builder: (context, model, child) {
+            List<BloodPressureRecord> items = model.getLastX(30);
+            if (items.isNotEmpty && items.first.diastolic > 0) {
+              return ListView.builder(
+                  itemCount: items.length,
+                  shrinkWrap: true,
+                  itemBuilder: (context, index) {
+                    return buildListItem(items[index]);
+                  }
+              );
+            } else {
+              return const Text('Es existieren noch keine Werte');
+            }
+        })
+    );
+  }
+
+  Widget buildListItem(BloodPressureRecord record) {
+    return Container(
+      child: Row(
+          children: [
+            Expanded(
+                flex: 10,
+                child: Text(record.systolic.toString())
+            ),
+            Expanded(
+                flex: 10,
+                child: Text(record.diastolic.toString())
+            ),
+            Expanded(
+                flex: 10,
+                child: Text(record.pulse.toString())
+            ),
+            Expanded(
+                flex: 70,
+                child: Text(record.notes)
+            ),
+          ]
+      ),
+    );
+  }
+
+  Widget buildColumnSeperator() {
+    return const SizedBox(
+      width: 8,
+    );
+  }
+}
+
+class _MeasuredValueListItem {
+
+
+}
lib/model/blood_pressure.dart
@@ -8,13 +8,38 @@ class BloodPressureModel extends ChangeNotifier {
   // All measurements (might get slow after some time)
   UnmodifiableListView<BloodPressureRecord> get allMeasurements => UnmodifiableListView(_allMeasurements);
 
+  /// Adds a new measurement at the correct chronological position in the List.
+  /// If the measurement was taken at exactly the same time as an existing
+  /// measurement, the existing measurement gets replaced.
   void add(BloodPressureRecord measurement) {
-    _allMeasurements.add(measurement);
+    if (_allMeasurements.isNotEmpty &&
+        _allMeasurements.last.compareTo(measurement) >= 0) {
+      // naive approach; change algorithm
+      for (int i = 0; i < _allMeasurements.length; i++) {
+        if (_allMeasurements[i].compareTo(measurement) == 0) {
+          _allMeasurements[i] = measurement;
+        } else if (_allMeasurements[i].compareTo(measurement) > 0) {
+          _allMeasurements.insert(i, measurement);
+        }
+      }
+    } else {
+        _allMeasurements.add(measurement);
+    }
     notifyListeners();
   }
+
+  /// Returns the
+  UnmodifiableListView<BloodPressureRecord> getLastX(int count) {
+    final List<BloodPressureRecord> lastMeasurements = [];
+    // example length = 30 (last index  29) count = 5 => 29, 28, 27, 26, 25 (5)
+    for (int i = _allMeasurements.length-1; i>=_allMeasurements.length-count &&
+            i>=0; i--) {
+      lastMeasurements.add(_allMeasurements[i]); // new list gets sorted high to low
+    }
+    return UnmodifiableListView(lastMeasurements);
+  }
   
   /* TODO:
-  - getLast (x)
   - bool deleteFromTime (timestamp)
   - bool changeAtTime (newRecord)
    */
@@ -32,4 +57,15 @@ class BloodPressureRecord {
 
   const BloodPressureRecord(
       this.creationTime, this.systolic, this.diastolic, this.pulse, this.notes);
+
+  @override
+  int compareTo(BloodPressureRecord other) {
+    if (creationTime.isBefore(other.creationTime)) {
+      return -1;
+    } else if (creationTime.isAfter(other.creationTime)) {
+      return 1;
+    } else {
+      return 0;
+    }
+  }
 }
\ No newline at end of file
lib/screens/add_measurement.dart
@@ -41,17 +41,13 @@ class _AddMeasurementPageState extends State<AddMeasurementPage> {
                   ],
                   validator: (String? value) {
                     if (value == null || value.isEmpty
-                        || (double.tryParse(value) == null)) {
+                        || (int.tryParse(value) == null)) {
                       return 'Please enter a Number';
+                    } else {
+                      _systolic = int.tryParse(value) ?? -1;
                     }
                     return null;
                   },
-                  onSaved: (String? value) {
-                    if (value != null && value.isNotEmpty
-                        || (double.tryParse(value ?? "-1") != null)) {
-                      _systolic = double.tryParse(value ?? "-1") as int;
-                    }
-                  },
                 ),
                 TextFormField(
                   decoration: const InputDecoration(
@@ -63,17 +59,13 @@ class _AddMeasurementPageState extends State<AddMeasurementPage> {
                   ],
                   validator: (String? value) {
                     if (value == null || value.isEmpty
-                        || (double.tryParse(value) == null)) {
+                        || (int.tryParse(value) == null)) {
                       return 'Please enter a Number';
+                    } else {
+                      _diastolic = int.tryParse(value) ?? -1;
                     }
                     return null;
                   },
-                  onSaved: (String? value) {
-                    if (value != null && value.isNotEmpty
-                        || (double.tryParse(value ?? "-1") != null)) {
-                      _diastolic = double.tryParse(value ?? "-1") as int;
-                    }
-                  },
                 ),
                 TextFormField(
                   decoration: const InputDecoration(
@@ -85,23 +77,19 @@ class _AddMeasurementPageState extends State<AddMeasurementPage> {
                   ],
                   validator: (String? value) {
                     if (value == null || value.isEmpty
-                        || (double.tryParse(value) == null)) {
+                        || (int.tryParse(value) == null)) {
                       return 'Please enter a Number';
+                    } else {
+                      _pulse = int.tryParse(value) ?? -1;
                     }
                     return null;
                   },
-                  onSaved: (String? value) {
-                    if (value != null && value.isNotEmpty
-                        || (double.tryParse(value ?? "-1") != null)) {
-                      _pulse = double.tryParse(value ?? "-1") as int;
-                    }
-                  },
                 ),
                 TextFormField(
                   decoration: const InputDecoration(
                       hintText: 'note (optional)'
                   ),
-                  onSaved: (String? value) {
+                  validator: (String? value) {
                     _note = value ?? "";
                   },
                 ),
lib/screens/home.dart
@@ -1,15 +1,30 @@
 import 'package:blood_pressure_app/screens/add_measurement.dart';
 import 'package:flutter/material.dart';
+import 'package:blood_pressure_app/components/measurement_graph.dart';
+import 'package:blood_pressure_app/components/measurement_list.dart';
 
 class AppHome extends StatelessWidget {
   const AppHome({super.key});
 
   @override
   Widget build(BuildContext context) {
-    // TODO: implement body
     return Scaffold(
-      body: ListView(
-
+      body: Center(
+        child: Container(
+          padding: const EdgeInsets.all(80),
+          child: Column(
+            children: const [
+              Expanded(
+                  flex: 40,
+                  child: MeasurementGraph()
+              ),
+              Expanded(
+                flex: 60,
+                  child: MeasurementList()
+              ),
+            ]
+          ),
+        ),
       ),
       floatingActionButton: Ink(
         decoration: ShapeDecoration(