Commit 5a568f8
Changed files (2)
lib
model
blood_pressure
medicine
lib/model/blood_pressure/medicine/intake_history.dart
@@ -1,3 +1,4 @@
+import 'package:blood_pressure_app/model/blood_pressure/medicine/medicine.dart';
import 'package:blood_pressure_app/model/blood_pressure/medicine/medicine_intake.dart';
import 'package:collection/collection.dart';
import 'package:flutter/material.dart';
@@ -5,11 +6,30 @@ import 'package:flutter/material.dart';
/// Model of all medicine intakes that allows fast access of data.
///
/// Internally maintains a sorted list of intakes to allow for binary search.
-class IntakeHistory {
+///
+/// Intake history does not implement database support, as operations performed
+/// are
+class IntakeHistory extends ChangeNotifier {
/// Create a intake history from an unsorted list of intakes.
IntakeHistory(List<MedicineIntake> medicineIntakes):
_medicineIntakes = medicineIntakes.sorted((p0, p1) => p0.compareTo(p1));
+ /// Creates a intake history from a sorted list of intakes.
+ IntakeHistory._sorted(this._medicineIntakes);
+
+ /// Restores a intake history from a [serialize] generated string.
+ factory IntakeHistory.deserialize(String serialized, List<Medicine> availableMedicines) =>
+ IntakeHistory._sorted(
+ serialized
+ .split('\n')
+ .map((e) => MedicineIntake.deserialize(e, availableMedicines))
+ .toList()
+ );
+
+ /// Serializes the current state of the object into a string.
+ String serialize() => _medicineIntakes.map((e) => e.serialize()).join('\n');
+ // TODO test serialization
+
/// List of all medicine intakes sorted in ascending order.
///
/// Can contain multiple medicine intakes at the same time.
@@ -32,6 +52,36 @@ class IntakeHistory {
return UnmodifiableListView(_medicineIntakes.getRange(start, end));
}
+ /// Save a medicine intake.
+ ///
+ /// Inserts the intake at the upper bound of intakes that are bigger or equal.
+ /// When no smaller bigger intake is available insert to the end of the list.
+ ///
+ /// Uses binary search to determine the bound.
+ void addIntake(MedicineIntake intake) {
+ int index = _findUpperBound(_medicineIntakes, intake.timestamp);
+
+ if (index == -1) {
+ _medicineIntakes.add(intake);
+ } else {
+ _medicineIntakes.insert(index, intake);
+ }
+ notifyListeners();
+ }
+
+ /// Attempts to delete a medicine intake.
+ ///
+ /// When finding multiple intakes with the same timestamp, medicine
+ /// and dosis all instances will get deleted.
+ void deleteIntake(MedicineIntake intake) {
+ int idx = binarySearch(_medicineIntakes, intake);
+ while (idx >= 0) {
+ _medicineIntakes.removeAt(idx);
+ idx = binarySearch(_medicineIntakes, intake);
+ }
+ notifyListeners();
+ }
+
/// Use binary search to determine the first index in [list] before which all
/// values that are before or at the same time as [t].
int _findUpperBound(List<MedicineIntake> list, DateTime t) {
@@ -75,32 +125,4 @@ class IntakeHistory {
return idx + 1;
}
-
- /// Save a medicine intake.
- ///
- /// Inserts the intake at the upper bound of intakes that are bigger or equal.
- /// When no smaller bigger intake is available insert to the end of the list.
- ///
- /// Uses binary search to determine the bound.
- void addIntake(MedicineIntake intake) {
- int index = _findUpperBound(_medicineIntakes, intake.timestamp);
-
- if (index == -1) {
- _medicineIntakes.add(intake);
- } else {
- _medicineIntakes.insert(index, intake);
- }
- }
-
- /// Attempts to delete a medicine intake.
- ///
- /// When finding multiple intakes with the same timestamp, medicine
- /// and dosis all instances will get deleted.
- void deleteIntake(MedicineIntake intake) {
- int idx = binarySearch(_medicineIntakes, intake);
- while (idx >= 0) {
- _medicineIntakes.removeAt(idx);
- idx = binarySearch(_medicineIntakes, intake);
- }
- }
}
\ No newline at end of file
lib/main.dart
@@ -1,4 +1,7 @@
+import 'dart:io';
+
import 'package:blood_pressure_app/components/consistent_future_builder.dart';
+import 'package:blood_pressure_app/model/blood_pressure/medicine/intake_history.dart';
import 'package:blood_pressure_app/model/blood_pressure/model.dart';
import 'package:blood_pressure_app/model/storage/db/config_dao.dart';
import 'package:blood_pressure_app/model/storage/db/config_db.dart';
@@ -12,7 +15,9 @@ import 'package:flutter_gen/gen_l10n/app_localizations.dart';
import 'package:flutter_localizations/flutter_localizations.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:package_info_plus/package_info_plus.dart';
+import 'package:path/path.dart';
import 'package:provider/provider.dart';
+import 'package:sqflite/sqflite.dart';
late final ConfigDB _database;
late final BloodPressureModel _bloodPressureModel;
@@ -41,6 +46,23 @@ Future<Widget> _loadApp() async {
final intervalStorageManager = await IntervallStoreManager.load(configDao, 0);
final exportColumnsManager = await configDao.loadExportColumnsManager(0);
+ // TODO: unify with blood pressure model (#257)
+ late final IntakeHistory intakeHistory;
+ try {
+ if (settings.medications.isNotEmpty) {
+ final intakeString = File(join(await getDatabasesPath(), 'medicine.intakes')).readAsStringSync();
+ intakeHistory = IntakeHistory.deserialize(intakeString, settings.medications);
+ } else {
+ intakeHistory = IntakeHistory([]);
+ }
+ } catch (e) {
+ assert(false, e.toString());
+ intakeHistory = IntakeHistory([]);
+ }
+ intakeHistory.addListener(() async {
+ File(join(await getDatabasesPath(), 'medicine.intakes')).writeAsStringSync(intakeHistory.serialize());
+ });
+
// update logic
if (settings.lastVersion == 0) {
await updateLegacySettings(settings, exportSettings, csvExportSettings, pdfExportSettings, intervalStorageManager);
@@ -66,6 +88,7 @@ Future<Widget> _loadApp() async {
ChangeNotifierProvider(create: (context) => pdfExportSettings),
ChangeNotifierProvider(create: (context) => intervalStorageManager),
ChangeNotifierProvider(create: (context) => exportColumnsManager),
+ ChangeNotifierProvider(create: (context) => intakeHistory),
], child: const AppRoot());
}