Commit 9fe979c

derdilla <derdilla06@gmail.com>
2023-04-30 18:29:06
mobile layout
1 parent b6a2c51
lib/components/measurement_list.dart
@@ -2,9 +2,21 @@ import 'package:blood_pressure_app/model/blood_pressure.dart';
 import 'package:flutter/material.dart';
 import 'package:provider/provider.dart';
 import 'package:intl/intl.dart';
+import 'dart:io' show Platform;
 
 class MeasurementList extends StatelessWidget {
-  const MeasurementList({super.key});
+  late final _tableElementsSizes;
+  late final _sideFlex;
+
+  MeasurementList(BuildContext context, {super.key}) {
+    if (MediaQuery.of(context).size.width < 1000) {
+      _tableElementsSizes = [30,10,10,10,30];
+      _sideFlex = 1;
+    } else {
+      _tableElementsSizes = [9,7,7,7,60];
+      _sideFlex = 5;
+    }
+  }
 
   @override
   Widget build(BuildContext context) {
@@ -38,37 +50,37 @@ class MeasurementList extends StatelessWidget {
   }
 
   Widget buildListItem(BloodPressureRecord record) {
-    final DateFormat formater = DateFormat('yyyy-MM-dd H:mm:s');
+    final DateFormat formater = DateFormat('yy-MM-dd H:mm:s');
     return Container(
       margin: EdgeInsets.only(bottom: 5),
       child: Row(
           children: [
-            const Expanded(
-              flex: 5,
+            Expanded(
+              flex: _sideFlex,
               child: SizedBox(),
             ),
             Expanded(
-                flex: 9,
+                flex: _tableElementsSizes[0],
                 child: Text(formater.format(record.creationTime))
             ),
             Expanded(
-                flex: 7,
+                flex: _tableElementsSizes[1],
                 child: Text(record.systolic.toString())
             ),
             Expanded(
-                flex: 7,
+                flex: _tableElementsSizes[2],
                 child: Text(record.diastolic.toString())
             ),
             Expanded(
-                flex: 7,
+                flex: _tableElementsSizes[3],
                 child: Text(record.pulse.toString())
             ),
             Expanded(
-                flex: 60,
+                flex: _tableElementsSizes[4],
                 child: Text(record.notes)
             ),
-            const Expanded(
-              flex: 5,
+            Expanded(
+              flex: _sideFlex,
               child: SizedBox(),
             ),
           ]
@@ -82,33 +94,33 @@ class MeasurementList extends StatelessWidget {
       child: Column (
         children: [
           Row(
-          children: const [
+          children: [
             Expanded(
-              flex: 5,
+              flex: _sideFlex,
               child: SizedBox(),
             ),
             Expanded(
-                flex: 9,
-                child: Text("timestamp", style: TextStyle(fontWeight: FontWeight.bold))
+                flex: _tableElementsSizes[0],
+                child: Text("time", style: TextStyle(fontWeight: FontWeight.bold))
             ),
             Expanded(
-                flex: 7,
-                child: Text("systolic", style: TextStyle(fontWeight: FontWeight.bold))
+                flex: _tableElementsSizes[1],
+                child: Text("sys", style: TextStyle(fontWeight: FontWeight.bold))
             ),
             Expanded(
-                flex: 7,
-                child: Text("diastolic", style: TextStyle(fontWeight: FontWeight.bold))
+                flex: _tableElementsSizes[2],
+                child: Text("dia", style: TextStyle(fontWeight: FontWeight.bold))
             ),
             Expanded(
-                flex: 7,
-                child: Text("pulse", style: TextStyle(fontWeight: FontWeight.bold))
+                flex: _tableElementsSizes[3],
+                child: Text("pul", style: TextStyle(fontWeight: FontWeight.bold))
             ),
             Expanded(
-                flex: 60,
+                flex: _tableElementsSizes[4],
                 child: Text("notes", style: TextStyle(fontWeight: FontWeight.bold))
             ),
             Expanded(
-              flex: 5,
+              flex: _sideFlex,
               child: SizedBox(),
             ),
           ],
lib/model/blood_pressure.dart
@@ -1,9 +1,31 @@
 import 'dart:collection';
-
 import 'package:flutter/foundation.dart';
+import 'package:path/path.dart';
+import 'package:sqflite_common_ffi/sqflite_ffi.dart';
+import 'package:sqflite/sqflite.dart';
 
 class BloodPressureModel extends ChangeNotifier {
   final List<BloodPressureRecord> _allMeasurements = [];
+  late final Database _database;
+
+  BloodPressureModel._create();
+  Future<void> _asyncInit() async {
+    _database = await openDatabase(
+      join(await getDatabasesPath(), 'blood_pressure.db'),
+      // runs when the database is first created
+      onCreate: (db, version) {
+        return db.execute('CREATE TABLE bloodPressureModel(timestamp INTEGER(14) PRIMARY KEY, systolic INTEGER, diastolic INTEGER, pulse INTEGER, notes STRING)',
+      );
+    },
+    version: 1,
+    );
+  }
+  // factory method, to allow for async contructor
+  static Future<BloodPressureModel> create() async{
+    final component = BloodPressureModel._create();
+    await component._asyncInit();
+    return component;
+  }
 
   // All measurements (might get slow after some time)
   UnmodifiableListView<BloodPressureRecord> get allMeasurements => UnmodifiableListView(_allMeasurements);
@@ -11,7 +33,14 @@ class BloodPressureModel extends ChangeNotifier {
   /// 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) {
+  Future<void> add(BloodPressureRecord measurement) async {
+    assert(_database.isOpen);
+    final existingMeasurements = await _database.query('bloodPressureModel',
+          columns: ['timestamp'],
+          orderBy: 'timestamp'
+    );
+    print(existingMeasurements);
+
     if (_allMeasurements.isNotEmpty &&
         _allMeasurements.last.compareTo(measurement) >= 0) {
       // naive approach; change algorithm
@@ -24,6 +53,12 @@ class BloodPressureModel extends ChangeNotifier {
       }
     } else {
         _allMeasurements.add(measurement);
+        _database.rawInsert('INSERT INTO bloodPressureModel(timestamp, systolic, diastolic, pulse, notes) VALUES (?, ?, ?, ?, ?)', [
+            measurement.creationTime.millisecondsSinceEpoch,
+            measurement.systolic,
+            measurement.diastolic,
+            measurement.pulse,
+            measurement.notes]);
     }
     notifyListeners();
   }
@@ -38,8 +73,8 @@ class BloodPressureModel extends ChangeNotifier {
     }
     return UnmodifiableListView(lastMeasurements);
   }
-  
-  /* TODO:
+
+/* TODO:
   - bool deleteFromTime (timestamp)
   - bool changeAtTime (newRecord)
    */
lib/screens/home.dart
@@ -8,19 +8,26 @@ class AppHome extends StatelessWidget {
 
   @override
   Widget build(BuildContext context) {
+    double _padding;
+    if (MediaQuery.of(context).size.width < 1000) {
+      _padding = 10;
+    } else {
+      _padding = 80;
+    }
+
     return Scaffold(
       body: Center(
         child: Container(
-          padding: const EdgeInsets.all(80),
+          padding: EdgeInsets.all(_padding),
           child: Column(
-            children: const [
-              Expanded(
+            children: [
+              const Expanded(
                   flex: 40,
                   child: MeasurementGraph()
               ),
               Expanded(
                 flex: 60,
-                  child: MeasurementList()
+                  child: MeasurementList(context)
               ),
             ]
           ),
lib/main.dart
@@ -2,11 +2,25 @@ import 'package:flutter/material.dart';
 import 'package:provider/provider.dart';
 import 'package:blood_pressure_app/model/blood_pressure.dart';
 import 'package:blood_pressure_app/screens/home.dart';
+import 'dart:io' show Platform;
+import 'package:sqflite_common_ffi/sqflite_ffi.dart';
+import 'package:sqflite/sqflite.dart';
+
+void main() async {
+  WidgetsFlutterBinding.ensureInitialized();
+
+  if (Platform.isWindows || Platform.isLinux) {
+    // Initialize FFI
+    sqfliteFfiInit();
+    // Change the default factory
+    databaseFactory = databaseFactoryFfi;
+  }
+
+  final dataModel = await BloodPressureModel.create();
 
-void main() {
   runApp(
       ChangeNotifierProvider(
-        create: (context) => BloodPressureModel(),
+        create: (context) => dataModel,
         child: const AppRoot(),
       ),
   );
macos/Flutter/GeneratedPluginRegistrant.swift
@@ -5,6 +5,8 @@
 import FlutterMacOS
 import Foundation
 
+import sqflite
 
 func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
+  SqflitePlugin.register(with: registry.registrar(forPlugin: "SqflitePlugin"))
 }
pubspec.lock
@@ -57,6 +57,14 @@ packages:
       url: "https://pub.dev"
     source: hosted
     version: "1.3.1"
+  ffi:
+    dependency: transitive
+    description:
+      name: ffi
+      sha256: a38574032c5f1dd06c4aee541789906c12ccaab8ba01446e800d9c5b79c4a978
+      url: "https://pub.dev"
+    source: hosted
+    version: "2.0.1"
   flutter:
     dependency: "direct main"
     description: flutter
@@ -132,7 +140,7 @@ packages:
     source: hosted
     version: "1.0.0"
   path:
-    dependency: transitive
+    dependency: "direct main"
     description:
       name: path
       sha256: db9d4f58c908a4ba5953fcee2ae317c94889433e5024c27ce74a37f94267945b
@@ -160,6 +168,38 @@ packages:
       url: "https://pub.dev"
     source: hosted
     version: "1.9.1"
+  sqflite:
+    dependency: "direct main"
+    description:
+      name: sqflite
+      sha256: "8453780d1f703ead201a39673deb93decf85d543f359f750e2afc4908b55533f"
+      url: "https://pub.dev"
+    source: hosted
+    version: "2.2.8"
+  sqflite_common:
+    dependency: transitive
+    description:
+      name: sqflite_common
+      sha256: e77abf6ff961d69dfef41daccbb66b51e9983cdd5cb35bf30733598057401555
+      url: "https://pub.dev"
+    source: hosted
+    version: "2.4.5"
+  sqflite_common_ffi:
+    dependency: "direct dev"
+    description:
+      name: sqflite_common_ffi
+      sha256: f86de82d37403af491b21920a696b19f01465b596f545d1acd4d29a0a72418ad
+      url: "https://pub.dev"
+    source: hosted
+    version: "2.2.5"
+  sqlite3:
+    dependency: transitive
+    description:
+      name: sqlite3
+      sha256: a3ba4b66a7ab170ce7aa3f5ac43c19ee8d6637afbe7b7c95c94112b4f4d91566
+      url: "https://pub.dev"
+    source: hosted
+    version: "1.11.0"
   stack_trace:
     dependency: transitive
     description:
@@ -184,6 +224,14 @@ packages:
       url: "https://pub.dev"
     source: hosted
     version: "1.2.0"
+  synchronized:
+    dependency: transitive
+    description:
+      name: synchronized
+      sha256: "5fcbd27688af6082f5abd611af56ee575342c30e87541d0245f7ff99faa02c60"
+      url: "https://pub.dev"
+    source: hosted
+    version: "3.1.0"
   term_glyph:
     dependency: transitive
     description:
@@ -210,4 +258,4 @@ packages:
     version: "2.1.4"
 sdks:
   dart: ">=2.19.6 <3.0.0"
-  flutter: ">=1.16.0"
+  flutter: ">=3.3.0"
pubspec.yaml
@@ -31,6 +31,8 @@ dependencies:
   flutter:
     sdk: flutter
   provider: ^6.0.0
+  sqflite:
+  path:
 
 
   # The following adds the Cupertino Icons font to your application.
@@ -41,6 +43,7 @@ dependencies:
 dev_dependencies:
   flutter_test:
     sdk: flutter
+  sqflite_common_ffi:
 
   # The "flutter_lints" package below contains a set of recommended lints to
   # encourage good coding practices. The lint set provided by the package is