Commit 46c6eda
Changed files (5)
app
lib
components
dialoges
measurement_list
model
blood_pressure
medicine
screens
app/lib/components/dialoges/add_measurement_dialoge.dart
@@ -3,14 +3,14 @@ import 'dart:math';
import 'package:blood_pressure_app/components/date_time_picker.dart';
import 'package:blood_pressure_app/components/dialoges/fullscreen_dialoge.dart';
import 'package:blood_pressure_app/components/settings/settings_widgets.dart';
-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:blood_pressure_app/model/blood_pressure/needle_pin.dart';
import 'package:blood_pressure_app/model/blood_pressure/record.dart';
import 'package:blood_pressure_app/model/storage/storage.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
+import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
+import 'package:health_data_store/health_data_store.dart' hide BloodPressureRecord;
import 'package:intl/intl.dart';
/// Input mask for entering measurements.
@@ -49,6 +49,10 @@ class _AddEntryDialogeState extends State<AddEntryDialoge> {
final noteFocusNode = FocusNode();
late final TextEditingController sysController;
+ /// List of medicines.
+ ///
+ /// Filled after fetching from repo is complete.
+ List<Medicine> availableMeds = [];
/// Currently selected time.
late DateTime time;
@@ -68,15 +72,15 @@ class _AddEntryDialogeState extends State<AddEntryDialoge> {
/// Last [FormState.save]d note.
String? notes;
- /// Index of the selected medicine in non hidden medications.
- ///
- /// Non hidden medications are obtained at the start of the build method.
- int? medicineId;
+ /// Medicine to save.
+ Medicine? selectedMed;
/// Whether to show the medication dosis input
bool _showMedicineDosisInput = false;
/// Entered dosis of medication.
+ ///
+ /// Prefilled with default dosis of selected medicine.
double? medicineDosis;
/// Newlines in the note field.
@@ -102,6 +106,9 @@ class _AddEntryDialogeState extends State<AddEntryDialoge> {
_measurementFormActive = true;
}
+ RepositoryProvider.of<MedicineRepository>(context).getAll()
+ .then((value) => setState(() => availableMeds.addAll(value)));
+
sysFocusNode.requestFocus();
ServicesBinding.instance.keyboard.addHandler(_onKey);
}
@@ -219,7 +226,6 @@ class _AddEntryDialogeState extends State<AddEntryDialoge> {
@override
Widget build(BuildContext context) {
- final medications = widget.settings.medications.where((e) => !e.hidden);
final localizations = AppLocalizations.of(context)!;
return FullscreenDialoge(
onActionButtonPressed: () {
@@ -238,12 +244,11 @@ class _AddEntryDialogeState extends State<AddEntryDialoge> {
&& (medicationFormKey.currentState?.validate() ?? false)) {
medicationFormKey.currentState?.save();
if (medicineDosis != null
- && medicineId != null) {
+ && selectedMed != null) {
intake = MedicineIntake(
- timestamp: time,
- medicine: medications
- .where((e) => e.id == medicineId).first,
- dosis: medicineDosis!,
+ time: time,
+ medicine: selectedMed!,
+ dosis: Weight.mg(medicineDosis!),
);
}
}
@@ -254,7 +259,7 @@ class _AddEntryDialogeState extends State<AddEntryDialoge> {
if (record == null && !_measurementFormActive && intake != null) {
Navigator.pop(context, (record, intake));
}
- if (record != null && intake == null && medicineId == null) {
+ if (record != null && intake == null && selectedMed == null) {
Navigator.pop(context, (record, intake));
}
},
@@ -346,7 +351,7 @@ class _AddEntryDialogeState extends State<AddEntryDialoge> {
],
),
),
- if (medications.isNotEmpty && widget.initialRecord == null)
+ if (availableMeds.isNotEmpty && widget.initialRecord == null)
Form(
key: medicationFormKey,
child: Padding(
@@ -356,10 +361,9 @@ class _AddEntryDialogeState extends State<AddEntryDialoge> {
Expanded(
child: DropdownButtonFormField<Medicine?>(
isExpanded: true,
- value: medications
- .where((e) => e.id == medicineId).firstOrNull,
+ value: selectedMed,
items: [
- for (final e in medications)
+ for (final e in availableMeds)
DropdownMenuItem(
value: e,
child: Text(e.designation),
@@ -367,16 +371,16 @@ class _AddEntryDialogeState extends State<AddEntryDialoge> {
DropdownMenuItem(
child: Text(localizations.noMedication),
),
- ], // TODO: auto select dosis on pick
+ ],
onChanged: (v) {
setState(() {
if (v != null) {
_showMedicineDosisInput = true;
- medicineId = v.id;
- medicineDosis = v.defaultDosis;
+ selectedMed = v;
+ medicineDosis = v.dosis?.mg;
} else {
_showMedicineDosisInput = false;
- medicineId = null;
+ selectedMed = null;
}
});
},
app/lib/components/measurement_list/intake_list_entry.dart
@@ -1,9 +1,9 @@
import 'dart:async';
import 'package:blood_pressure_app/components/measurement_list/measurement_list_entry.dart';
-import 'package:blood_pressure_app/model/blood_pressure/medicine/medicine_intake.dart';
import 'package:blood_pressure_app/model/storage/settings_store.dart';
import 'package:flutter/material.dart';
+import 'package:health_data_store/health_data_store.dart';
import 'package:intl/intl.dart';
/// Medicine intake to display in a list.
@@ -31,7 +31,7 @@ class IntakeListEntry extends StatelessWidget {
@override
Widget build(BuildContext context) => ListTile(
title: Text(intake.medicine.designation),
- subtitle: Text(DateFormat(settings.dateFormatString).format(intake.timestamp)),
+ subtitle: Text(DateFormat(settings.dateFormatString).format(intake.time)),
trailing: Row(
mainAxisSize: MainAxisSize.min,
children: [
@@ -50,7 +50,7 @@ class IntakeListEntry extends StatelessWidget {
],
),
leading: const Icon(Icons.medication),
- iconColor: intake.medicine.color,
+ iconColor: intake.medicine.color == null ? null : Color(intake.medicine.color!),
);
app/lib/components/measurement_list/measurement_list.dart
@@ -1,12 +1,11 @@
import 'package:blood_pressure_app/components/measurement_list/intake_list_entry.dart';
import 'package:blood_pressure_app/components/measurement_list/measurement_list_entry.dart';
-import 'package:blood_pressure_app/model/blood_pressure/medicine/intake_history.dart';
-import 'package:blood_pressure_app/model/blood_pressure/medicine/medicine_intake.dart';
import 'package:blood_pressure_app/model/blood_pressure/record.dart';
import 'package:blood_pressure_app/model/storage/settings_store.dart';
import 'package:flutter/material.dart';
+import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
-import 'package:provider/provider.dart';
+import 'package:health_data_store/health_data_store.dart' show MedicineIntake, MedicineIntakeRepository;
/// List that renders measurements and medicine intakes.
///
@@ -38,9 +37,9 @@ class MeasurementList extends StatelessWidget {
entries.addAll(intakes);
entries.sort((e1, e2) {
if (e2 is BloodPressureRecord && e1 is BloodPressureRecord) return e2.creationTime.compareTo(e1.creationTime);
- if (e2 is BloodPressureRecord && e1 is MedicineIntake) return e2.creationTime.compareTo(e1.timestamp);
- if (e2 is MedicineIntake && e1 is BloodPressureRecord) return e2.timestamp.compareTo(e1.creationTime);
- if (e2 is MedicineIntake && e1 is MedicineIntake) return e2.timestamp.compareTo(e1.timestamp);
+ if (e2 is BloodPressureRecord && e1 is MedicineIntake) return e2.creationTime.compareTo(e1.time);
+ if (e2 is MedicineIntake && e1 is BloodPressureRecord) return e2.time.compareTo(e1.creationTime);
+ if (e2 is MedicineIntake && e1 is MedicineIntake) return e2.time.compareTo(e1.time);
assert(false);
return 0;
});
@@ -102,9 +101,8 @@ class MeasurementList extends StatelessWidget {
intake: entries[idx],
settings: settings,
delete: () {
- // TODO: move out of model
- final history = Provider.of<IntakeHistory>(context, listen: false);
- history.deleteIntake(entries[idx]);
+ final repo = RepositoryProvider.of<MedicineIntakeRepository>(context);
+ repo.remove(entries[idx]);
},
);
}
app/lib/model/blood_pressure/medicine/medicine_intake.dart
@@ -4,6 +4,7 @@ import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
/// Instance of a medicine intake.
+@deprecated
class MedicineIntake implements Comparable<Object> {
/// Create a intake from a String created by [serialize].
///
app/lib/screens/home_screen.dart
@@ -12,7 +12,9 @@ import 'package:blood_pressure_app/screens/statistics_screen.dart';
import 'package:flutter/material.dart';
import 'package:flutter/scheduler.dart';
import 'package:flutter/services.dart';
+import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
+import 'package:health_data_store/health_data_store.dart' show MedicineIntakeRepository, MedicineRepository;
import 'package:provider/provider.dart';
/// Is true during the first [AppHome.build] before creating the widget.
@@ -32,7 +34,7 @@ class AppHome extends StatelessWidget {
if (Provider.of<Settings>(context, listen: false).startWithAddMeasurementPage) {
SchedulerBinding.instance.addPostFrameCallback((_) async {
final model = Provider.of<BloodPressureModel>(context, listen: false);
- final intakes = Provider.of<IntakeHistory>(context, listen: false);
+ final intakes = RepositoryProvider.of<MedicineIntakeRepository>(context);
final measurement = await showAddEntryDialoge(context, Provider.of<Settings>(context, listen: false));
if (measurement == null) return;
if (measurement.$1 != null) {
@@ -43,7 +45,7 @@ class AppHome extends StatelessWidget {
}
}
if (measurement.$2 != null) {
- intakes.addIntake(measurement.$2!);
+ intakes.add(measurement.$2!);
}
});
}
@@ -61,8 +63,7 @@ class AppHome extends StatelessWidget {
return Center(
child: Padding(
padding: const EdgeInsets.only(top: 20),
- child: Consumer<IntakeHistory>(builder: (context, intakeHistory, child) =>
- Consumer<IntervallStoreManager>(builder: (context, intervalls, child) =>
+ child: Consumer<IntervallStoreManager>(builder: (context, intervalls, child) =>
Consumer<Settings>(builder: (context, settings, child) =>
Column(children: [
const MeasurementGraph(),
@@ -71,10 +72,15 @@ class AppHome extends StatelessWidget {
LegacyMeasurementsList(context) :
BloodPressureBuilder(
rangeType: IntervallStoreManagerLocation.mainPage,
- onData: (context, records) => MeasurementList(
- settings: settings,
- records: records,
- intakes: intakeHistory.getIntakes(intervalls.mainPage.currentRange),
+ onData: (context, records) => StreamBuilder(
+ stream: RepositoryProvider.of<MedicineRepository>(context).,
+ builder: (context, snapshot) {
+ return MeasurementList(
+ settings: settings,
+ records: records,
+ intakes: intakeHistory.getIntakes(intervalls.mainPage.currentRange),
+ );
+ },
),
),
),
@@ -104,7 +110,7 @@ class AppHome extends StatelessWidget {
autofocus: true,
onPressed: () async {
final model = Provider.of<BloodPressureModel>(context, listen: false);
- final intakes = Provider.of<IntakeHistory>(context, listen: false);
+ final intakes = RepositoryProvider.of<MedicineIntakeRepository>(context);
final measurement = await showAddEntryDialoge(context, Provider.of<Settings>(context, listen: false));
if (measurement == null) return;
if (measurement.$1 != null) {
@@ -115,7 +121,7 @@ class AppHome extends StatelessWidget {
}
}
if (measurement.$2 != null) {
- intakes.addIntake(measurement.$2!);
+ intakes.add(measurement.$2!);
}
},
child: const Icon(Icons.add,),
@@ -156,15 +162,15 @@ class AppHome extends StatelessWidget {
// TODO: consider removing duration override that only occurs in one on home.
void _buildTransition(BuildContext context, Widget page, int duration) {
Navigator.push(context,
- TimedMaterialPageRouter(
+ _TimedMaterialPageRouter(
transitionDuration: Duration(milliseconds: duration),
builder: (context) => page,
),
);
}
-class TimedMaterialPageRouter extends MaterialPageRoute {
- TimedMaterialPageRouter({
+class _TimedMaterialPageRouter extends MaterialPageRoute {
+ _TimedMaterialPageRouter({
required super.builder,
required this.transitionDuration,});