Commit 8671139

derdilla <82763757+NobodyForNothing@users.noreply.github.com>
2024-06-26 07:59:10
extract context utils and fix unit conversion
Signed-off-by: derdilla <82763757+NobodyForNothing@users.noreply.github.com>
1 parent 1fe74bc
Changed files (10)
app
health_data_store
lib
src
types
test
src
types
app/lib/components/dialoges/add_measurement_dialoge.dart
@@ -6,13 +6,10 @@ import 'package:blood_pressure_app/components/forms/date_time_form.dart';
 import 'package:blood_pressure_app/components/settings/color_picker_list_tile.dart';
 import 'package:blood_pressure_app/model/blood_pressure/pressure_unit.dart';
 import 'package:blood_pressure_app/model/storage/storage.dart';
-import 'package:blood_pressure_app/screens/subsettings/export_import/export_button_bar.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';
-import 'package:provider/provider.dart';
 
 /// Input mask for entering measurements.
 class AddEntryDialoge extends StatefulWidget {
@@ -441,38 +438,3 @@ Future<FullEntry?> showAddEntryDialoge(
       ),
   );
 }
-
-/// Allow correctly saving entries in the contexts repositories.
-extension AddEntries on BuildContext {
-  /// Open the [AddEntryDialoge] and save received entries.
-  ///
-  /// Follows [ExportSettings.exportAfterEveryEntry]. When [initial] is not null
-  /// the dialoge will be opened in edit mode.
-  Future<void> createEntry([FullEntry? initial]) async {
-    final recordRepo = RepositoryProvider.of<BloodPressureRepository>(this);
-    final noteRepo = RepositoryProvider.of<NoteRepository>(this);
-    final intakeRepo = RepositoryProvider.of<MedicineIntakeRepository>(this);
-    final settings = Provider.of<Settings>(this, listen: false);
-    final exportSettings = Provider.of<ExportSettings>(this, listen: false);
-
-    final entry = await showAddEntryDialoge(this,
-      settings,
-      RepositoryProvider.of<MedicineRepository>(this),
-      initial,
-    );
-    if (entry != null) {
-      if (entry.sys != null || entry.dia != null || entry.pul != null) {
-        await recordRepo.add(entry.$1);
-      }
-      if (entry.note != null || entry.color != null) {
-        await noteRepo.add(entry.$2);
-      }
-      for (final intake in entry.$3) {
-        await intakeRepo.add(intake);
-      }
-      if (mounted && exportSettings.exportAfterEveryEntry) {
-        performExport(this, AppLocalizations.of(this)!);
-      }
-    }
-  }
-}
app/lib/components/measurement_list/measurement_list.dart
@@ -1,5 +1,5 @@
-import 'package:blood_pressure_app/components/dialoges/add_measurement_dialoge.dart';
 import 'package:blood_pressure_app/components/measurement_list/measurement_list_entry.dart';
+import 'package:blood_pressure_app/model/entry_context.dart';
 import 'package:blood_pressure_app/model/storage/settings_store.dart';
 import 'package:flutter/material.dart';
 import 'package:flutter_gen/gen_l10n/app_localizations.dart';
app/lib/components/measurement_list/measurement_list_entry.dart
@@ -1,13 +1,13 @@
 import 'package:blood_pressure_app/components/dialoges/confirm_deletion_dialoge.dart';
 import 'package:blood_pressure_app/components/nullable_text.dart';
 import 'package:blood_pressure_app/components/pressure_text.dart';
+import 'package:blood_pressure_app/model/entry_context.dart';
 import 'package:blood_pressure_app/model/storage/storage.dart';
 import 'package:flutter/material.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';
 import 'package:intl/intl.dart';
-import 'package:provider/provider.dart';
 
 /// Display of a blood pressure measurement data.
 class MeasurementListRow extends StatelessWidget {
@@ -114,35 +114,3 @@ class MeasurementListRow extends StatelessWidget {
     ],
   );
 }
-
-extension DeleteEntry on BuildContext {
-  /// Delete record and note of an entry from the repositories.
-  Future<void> deleteEntry(FullEntry entry) async {
-    final localizations = AppLocalizations.of(this)!;
-    final settings = Provider.of<Settings>(this, listen: false);
-    final bpRepo = RepositoryProvider.of<BloodPressureRepository>(this);
-    final noteRepo = RepositoryProvider.of<NoteRepository>(this);
-    final messenger = ScaffoldMessenger.of(this);
-
-    bool confirmedDeletion = true;
-    if (settings.confirmDeletion) {
-      confirmedDeletion = await showConfirmDeletionDialoge(this);
-    }
-
-    if (confirmedDeletion) {
-      await bpRepo.remove(entry.$1);
-      await noteRepo.remove(entry.$2);
-      messenger.removeCurrentSnackBar();
-      messenger.showSnackBar(SnackBar(
-        content: Text(localizations.deletionConfirmed),
-        action: SnackBarAction(
-          label: localizations.btnUndo,
-          onPressed: () async {
-            await bpRepo.add(entry.$1);
-            await noteRepo.add(entry.$2);
-          },
-        ),
-      ),);
-    }
-  }
-}
app/lib/components/pressure_text.dart
@@ -19,7 +19,7 @@ class PressureText extends StatelessWidget {
   Widget build(BuildContext context) => NullableText(
     switch (context.watch<Settings>().preferredPressureUnit) {
       PressureUnit.mmHg => pressure?.mmHg,
-      PressureUnit.kPa => pressure?.kPa,
+      PressureUnit.kPa => pressure?.kPa.toStringAsFixed(1),
     }?.toString(),
   );
 }
app/lib/model/entry_context.dart
@@ -0,0 +1,83 @@
+import 'package:blood_pressure_app/components/dialoges/add_measurement_dialoge.dart';
+import 'package:blood_pressure_app/components/dialoges/confirm_deletion_dialoge.dart';
+import 'package:blood_pressure_app/logging.dart';
+import 'package:blood_pressure_app/model/storage/storage.dart';
+import 'package:blood_pressure_app/screens/subsettings/export_import/export_button_bar.dart';
+import 'package:flutter/material.dart';
+import 'package:flutter_bloc/flutter_bloc.dart' hide ProviderNotFoundException;
+import 'package:flutter_gen/gen_l10n/app_localizations.dart';
+import 'package:health_data_store/health_data_store.dart';
+import 'package:provider/provider.dart';
+
+/// Allow high level operations on the repositories in context.
+extension EntryUtils on BuildContext {
+  /// Open the [AddEntryDialoge] and save received entries.
+  ///
+  /// Follows [ExportSettings.exportAfterEveryEntry]. When [initial] is not null
+  /// the dialoge will be opened in edit mode.
+  Future<void> createEntry([FullEntry? initial]) async {
+    try {
+      final recordRepo = RepositoryProvider.of<BloodPressureRepository>(this);
+      final noteRepo = RepositoryProvider.of<NoteRepository>(this);
+      final intakeRepo = RepositoryProvider.of<MedicineIntakeRepository>(this);
+      final settings = Provider.of<Settings>(this, listen: false);
+      final exportSettings = Provider.of<ExportSettings>(this, listen: false);
+
+      final entry = await showAddEntryDialoge(this,
+        settings,
+        RepositoryProvider.of<MedicineRepository>(this),
+        initial,
+      );
+      if (entry != null) {
+        if (entry.sys != null || entry.dia != null || entry.pul != null) {
+          await recordRepo.add(entry.$1);
+        }
+        if (entry.note != null || entry.color != null) {
+          await noteRepo.add(entry.$2);
+        }
+        for (final intake in entry.$3) {
+          await intakeRepo.add(intake);
+        }
+        if (mounted && exportSettings.exportAfterEveryEntry) {
+          performExport(this, AppLocalizations.of(this)!);
+        }
+      }
+    } on ProviderNotFoundException {
+      Log.err('createEntry($initial) was called from a context without Provider.');
+    }
+  }
+
+  /// Delete record and note of an entry from the repositories.
+  Future<void> deleteEntry(FullEntry entry) async {
+    try {
+      final localizations = AppLocalizations.of(this)!;
+      final settings = Provider.of<Settings>(this, listen: false);
+      final bpRepo = RepositoryProvider.of<BloodPressureRepository>(this);
+      final noteRepo = RepositoryProvider.of<NoteRepository>(this);
+      final messenger = ScaffoldMessenger.of(this);
+
+      bool confirmedDeletion = true;
+      if (settings.confirmDeletion) {
+        confirmedDeletion = await showConfirmDeletionDialoge(this);
+      }
+
+      if (confirmedDeletion) {
+        await bpRepo.remove(entry.$1);
+        await noteRepo.remove(entry.$2);
+        messenger.removeCurrentSnackBar();
+        messenger.showSnackBar(SnackBar(
+          content: Text(localizations.deletionConfirmed),
+          action: SnackBarAction(
+            label: localizations.btnUndo,
+            onPressed: () async {
+              await bpRepo.add(entry.$1);
+              await noteRepo.add(entry.$2);
+            },
+          ),
+        ),);
+      }
+    } on ProviderNotFoundException {
+      Log.err('deleteEntry($entry) was called from a context without Provider.');
+    }
+  }
+}
app/lib/screens/subsettings/export_import/export_button_bar.dart
@@ -137,7 +137,7 @@ class ExportButtonBar extends StatelessWidget {
 }
 
 /// Perform a full export according to the configuration in [context].
-void performExport(BuildContext context, [AppLocalizations? localizations]) async {
+void performExport(BuildContext context, [AppLocalizations? localizations]) async { // TODO: extract
   localizations ??= AppLocalizations.of(context);
   final exportSettings = Provider.of<ExportSettings>(context, listen: false);
   final filename = 'blood_press_${DateTime.now().toIso8601String()}';
app/lib/screens/home_screen.dart
@@ -1,6 +1,6 @@
-import 'package:blood_pressure_app/components/dialoges/add_measurement_dialoge.dart';
 import 'package:blood_pressure_app/components/measurement_list/measurement_list.dart';
 import 'package:blood_pressure_app/components/repository_builder.dart';
+import 'package:blood_pressure_app/model/entry_context.dart';
 import 'package:blood_pressure_app/model/storage/intervall_store.dart';
 import 'package:blood_pressure_app/model/storage/settings_store.dart';
 import 'package:blood_pressure_app/screens/elements/blood_pressure_builder.dart';
app/lib/app.dart
@@ -147,14 +147,18 @@ class _AppState extends State<App> {
         RepositoryProvider.value(value: noteRepo),
         RepositoryProvider.value(value: medRepo),
         RepositoryProvider.value(value: intakeRepo),
-        ChangeNotifierProvider.value(value: _settings!),
-        ChangeNotifierProvider.value(value: _exportSettings!),
-        ChangeNotifierProvider.value(value: _csvExportSettings!),
-        ChangeNotifierProvider.value(value: _pdfExportSettings!),
-        ChangeNotifierProvider.value(value: _intervallStorageManager!),
-        ChangeNotifierProvider.value(value: _exportColumnsManager!),
       ],
-      child: _buildAppRoot(),
+      child: MultiProvider(
+        providers: [
+          ChangeNotifierProvider.value(value: _settings!),
+          ChangeNotifierProvider.value(value: _exportSettings!),
+          ChangeNotifierProvider.value(value: _csvExportSettings!),
+          ChangeNotifierProvider.value(value: _pdfExportSettings!),
+          ChangeNotifierProvider.value(value: _intervallStorageManager!),
+          ChangeNotifierProvider.value(value: _exportColumnsManager!),
+        ],
+        child: _buildAppRoot(),
+      ),
     );
 
     return _loadedChild!;
health_data_store/lib/src/types/units/pressure.dart
@@ -1,19 +1,19 @@
 /// Class representing and converting [pressure](https://en.wikipedia.org/wiki/Pressure).
 class Pressure {
   /// Create pressure from kilopascal. 
-  Pressure.kPa(double value): _valPa = value / 1000;
+  Pressure.kPa(double value): _valPa = value * 1000;
 
   /// Create pressure from [Millimetre of mercury](https://en.wikipedia.org/wiki/Millimetre_of_mercury).
-  Pressure.mmHg(int value): _valPa = value / 133.322;
+  Pressure.mmHg(int value): _valPa = value * 133.322;
 
   /// Currently stored value in pascal.
   double _valPa;
   
   /// Get value in kilopascal.
-  double get kPa => _valPa * 1000;
+  double get kPa => _valPa / 1000;
 
   /// Get value in [Millimetre of mercury](https://en.wikipedia.org/wiki/Millimetre_of_mercury).
-  int get mmHg => (_valPa * 133.322).round();
+  int get mmHg => (_valPa / 133.322).round();
 
   @override
   bool operator ==(Object other) =>
health_data_store/test/src/types/units/pressure_test.dart
@@ -0,0 +1,19 @@
+import 'package:health_data_store/health_data_store.dart';
+import 'package:test/expect.dart';
+import 'package:test/scaffolding.dart';
+
+void main() {
+  test('returns values the same as passed in', () {
+    expect(Pressure.mmHg(120).mmHg, 120);
+    expect(Pressure.mmHg(80).mmHg, 80);
+    expect(Pressure.kPa(15.5).kPa, 15.5);
+    expect(Pressure.kPa(10.0).kPa, 10.0);
+  });
+
+  test('converts values correctly', () {
+    expect(Pressure.mmHg(120).kPa, inInclusiveRange(15.998, 15.999));
+    expect(Pressure.mmHg(80).kPa, inInclusiveRange(10.665, 10.666));
+    expect(Pressure.kPa(15.9987).mmHg, 120);
+    expect(Pressure.kPa(10.0).mmHg, 75);
+  });
+}