Commit 0985b42

derdilla <82763757+NobodyForNothing@users.noreply.github.com>
2024-06-26 08:54:39
fix tests by allowing settings in components
Signed-off-by: derdilla <82763757+NobodyForNothing@users.noreply.github.com>
1 parent 8671139
app/lib/components/dialoges/add_export_column_dialoge.dart
@@ -8,6 +8,7 @@ import 'package:flutter/material.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';
 
 /// Dialoge widget for creating and editing a [UserColumn].
 ///
@@ -16,7 +17,6 @@ class AddExportColumnDialoge extends StatefulWidget {
   /// Create a widget for creating and editing a [UserColumn].
   const AddExportColumnDialoge({super.key,
     this.initialColumn,
-    required this.settings,
   });
 
   /// Prefills the form to a submitted state.
@@ -24,9 +24,6 @@ class AddExportColumnDialoge extends StatefulWidget {
   /// When this is null it is assumed creating a new column is intended.
   final ExportColumn? initialColumn;
 
-  /// Settings to determine general behavior.
-  final Settings settings;
-
   @override
   State<AddExportColumnDialoge> createState() => _AddExportColumnDialogeState();
 }
@@ -67,7 +64,7 @@ class _AddExportColumnDialogeState extends State<AddExportColumnDialoge>
 
     _controller = AnimationController(
       value: (type == _FormatterType.record) ? 1 : 0,
-      duration: Duration(milliseconds: widget.settings.animationSpeed),
+      duration: Duration(milliseconds: context.watch<Settings>().animationSpeed),
       vsync: this,
     );
   }
@@ -80,11 +77,12 @@ class _AddExportColumnDialogeState extends State<AddExportColumnDialoge>
 
   @override
   Widget build(BuildContext context) {
+    final settings = context.watch<Settings>();
     final localizations = AppLocalizations.of(context)!;
     return FullscreenDialoge(
       actionButtonText: localizations.btnSave,
       onActionButtonPressed: _saveForm,
-      bottomAppBar: widget.settings.bottomAppBars,
+      bottomAppBar: settings.bottomAppBars,
       body: GestureDetector(
         onHorizontalDragEnd: (details) {
           if (details.primaryVelocity == null) return;
@@ -163,8 +161,8 @@ class _AddExportColumnDialogeState extends State<AddExportColumnDialoge>
                 child: (){
                     final record = BloodPressureRecord(
                       time: DateTime.now(),
-                      sys: widget.settings.preferredPressureUnit.wrap(123),
-                      dia: widget.settings.preferredPressureUnit.wrap(78),
+                      sys: settings.preferredPressureUnit.wrap(123),
+                      dia: settings.preferredPressureUnit.wrap(78),
                       pul: 65,
                     );
                     final note = Note(
@@ -182,7 +180,6 @@ class _AddExportColumnDialogeState extends State<AddExportColumnDialoge>
                         if (type == _FormatterType.record)
                           MeasurementListRow(
                             data: (record, Note(time: record.time), []),
-                            settings: widget.settings,
                             onRequestEdit: () { }, // ignore
                           ) else Text(
                             DateFormat('MMM d, y - h:m.s')
@@ -336,14 +333,12 @@ enum _FormatterType {
 /// the CSV title. There is no check whether a userColumn
 /// with the generated title exists.
 Future<ExportColumn?> showAddExportColumnDialoge(
-  BuildContext context,
-  Settings settings, [
+  BuildContext context, [
     ExportColumn? initialColumn,
 ]) => showDialog<ExportColumn?>(context: context,
   builder: (context) => Dialog.fullscreen(
     child: AddExportColumnDialoge(
       initialColumn: initialColumn,
-      settings: settings,
     ),
   ),
 );
app/lib/components/dialoges/add_measurement_dialoge.dart
@@ -10,6 +10,7 @@ import 'package:flutter/material.dart';
 import 'package:flutter/services.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 {
@@ -17,14 +18,10 @@ class AddEntryDialoge extends StatefulWidget {
   /// 
   /// This is usually created through the [showAddEntryDialoge] function.
   const AddEntryDialoge({super.key,
-    required this.settings,
     required this.availableMeds,
     this.initialRecord,
   });
 
-  /// Settings are followed by the dialoge.
-  final Settings settings;
-
   /// Values that are prefilled.
   ///
   /// When this is null the timestamp is [DateTime.now] and the other fields
@@ -84,6 +81,7 @@ class _AddEntryDialogeState extends State<AddEntryDialoge> {
   /// Prefilled with default dosis of selected medicine.
   double? medicineDosis;
 
+  late Settings settings;
 
   @override
   void initState() {
@@ -94,6 +92,8 @@ class _AddEntryDialogeState extends State<AddEntryDialoge> {
     noteController = TextEditingController();
     _loadFields(widget.initialRecord);
 
+    settings = context.watch<Settings>();
+
     sysFocusNode.requestFocus();
     ServicesBinding.instance.keyboard.addHandler(_onKey);
   }
@@ -118,11 +118,11 @@ class _AddEntryDialogeState extends State<AddEntryDialoge> {
   void _loadFields(FullEntry? entry) {
     time = entry?.time ?? DateTime.now();
     final int? colorValue = entry?.color;
-    final sysValue = switch(widget.settings.preferredPressureUnit) {
+    final sysValue = switch(settings.preferredPressureUnit) {
       PressureUnit.mmHg => entry?.sys?.mmHg,
       PressureUnit.kPa => entry?.sys?.kPa.round(),
     };
-    final diaValue = switch(widget.settings.preferredPressureUnit) {
+    final diaValue = switch(settings.preferredPressureUnit) {
       PressureUnit.mmHg => entry?.dia?.mmHg,
       PressureUnit.kPa => entry?.dia?.kPa.round(),
     };
@@ -171,15 +171,15 @@ class _AddEntryDialogeState extends State<AddEntryDialoge> {
         }
       },
       validator: (String? value) {
-        if (!widget.settings.allowMissingValues
+        if (!settings.allowMissingValues
             && (value == null
                 || value.isEmpty
                 || int.tryParse(value) == null)) {
           return localizations.errNaN;
-        } else if (widget.settings.validateInputs
+        } else if (settings.validateInputs
             && (int.tryParse(value ?? '') ?? -1) <= 30) {
           return localizations.errLt30;
-        } else if (widget.settings.validateInputs
+        } else if (settings.validateInputs
             && (int.tryParse(value ?? '') ?? 0) >= 400) {
           // https://pubmed.ncbi.nlm.nih.gov/7741618/
           return localizations.errUnrealistic;
@@ -213,7 +213,7 @@ class _AddEntryDialogeState extends State<AddEntryDialoge> {
         if (shouldHaveRecord && (recordFormKey.currentState?.validate() ?? false)) {
           recordFormKey.currentState?.save();
           if (systolic != null || diastolic != null || pulse != null) {
-            final pressureUnit = widget.settings.preferredPressureUnit;
+            final pressureUnit = settings.preferredPressureUnit;
             record = BloodPressureRecord(
               time: time,
               sys: systolic == null ? null : pressureUnit.wrap(systolic!),
@@ -253,24 +253,23 @@ class _AddEntryDialogeState extends State<AddEntryDialoge> {
         }
       },
       actionButtonText: localizations.btnSave,
-      bottomAppBar: widget.settings.bottomAppBars,
+      bottomAppBar: settings.bottomAppBars,
       body: SizeChangedLayoutNotifier(
         child: ListView(
           padding: const EdgeInsets.symmetric(horizontal: 8),
           children: [
-            if (widget.settings.bleInput)
+            if (settings.bleInput)
               BluetoothInput(
-                settings: widget.settings,
                 onMeasurement: (record) => setState(
                   () => _loadFields((record, Note(time: record.time, note: noteController.text, color: color?.value), [])),
                 ),
               ),
-            if (widget.settings.allowManualTimeInput)
+            if (settings.allowManualTimeInput)
               ListTileTheme(
                 shape: _buildShapeBorder(),
                 child: DateTimeForm(
-                  validate: widget.settings.validateInputs,
-                  dateFormatString: widget.settings.dateFormatString,
+                  validate: settings.validateInputs,
+                  dateFormatString: settings.dateFormatString,
                   initialTime: time,
                   onTimeSelected: (newTime) => setState(() {
                     time = newTime;
@@ -300,7 +299,7 @@ class _AddEntryDialogeState extends State<AddEntryDialoge> {
                             setState(() => diastolic = int.tryParse(value ?? '')),
                         focusNode: diaFocusNode,
                         validator: (value) {
-                          if (widget.settings.validateInputs
+                          if (settings.validateInputs
                               && (int.tryParse(value ?? '') ?? 0)
                                   >= (int.tryParse(sysController.text) ?? 1)
                           ) {
@@ -422,7 +421,6 @@ class _AddEntryDialogeState extends State<AddEntryDialoge> {
 /// Shows a dialoge to input a blood pressure measurement or a medication.
 Future<FullEntry?> showAddEntryDialoge(
   BuildContext context,
-  Settings settings,
   MedicineRepository medRepo,
   [FullEntry? initialRecord,
 ]) async {
@@ -431,7 +429,6 @@ Future<FullEntry?> showAddEntryDialoge(
       context: context, builder: (context) =>
       Dialog.fullscreen(
         child: AddEntryDialoge(
-          settings: settings,
           initialRecord: initialRecord,
           availableMeds: meds,
         ),
app/lib/components/dialoges/add_medication_dialoge.dart
@@ -5,16 +5,12 @@ import 'package:flutter/material.dart';
 import 'package:flutter/services.dart';
 import 'package:flutter_gen/gen_l10n/app_localizations.dart';
 import 'package:health_data_store/health_data_store.dart';
+import 'package:provider/provider.dart';
 
 /// Dialoge to enter values for a [Medicine].
 class AddMedicationDialoge extends StatefulWidget {
   /// Create a dialoge to enter values for a [Medicine].
-  const AddMedicationDialoge({super.key,
-    required this.settings,
-  });
-
-  /// Settings that determine general behavior.
-  final Settings settings;
+  const AddMedicationDialoge({super.key});
 
   @override
   State<AddMedicationDialoge> createState() => _AddMedicationDialogeState();
@@ -38,6 +34,7 @@ class _AddMedicationDialogeState extends State<AddMedicationDialoge> {
   @override
   Widget build(BuildContext context) {
     final localizations = AppLocalizations.of(context)!;
+    final settings = context.watch<Settings>();
     return FullscreenDialoge(
       actionButtonText: localizations.btnSave,
       onActionButtonPressed: () {
@@ -48,7 +45,7 @@ class _AddMedicationDialogeState extends State<AddMedicationDialoge> {
           dosis: _defaultDosis == null ? null : Weight.mg(_defaultDosis!),
         ),);
       },
-      bottomAppBar: widget.settings.bottomAppBars,
+      bottomAppBar: settings.bottomAppBars,
       body: Form(
         key: formKey,
         child: ListView(
@@ -101,7 +98,7 @@ class _AddMedicationDialogeState extends State<AddMedicationDialoge> {
 /// Shows a full screen dialoge to input a medicine.
 ///
 /// The created medicine gets an index that was never in settings.
-Future<Medicine?> showAddMedicineDialoge(BuildContext context, Settings settings) =>
+Future<Medicine?> showAddMedicineDialoge(BuildContext context) =>
   showDialog<Medicine?>(context: context, builder: (context) => Dialog.fullscreen(
-    child: AddMedicationDialoge(settings: settings),
+    child: AddMedicationDialoge(),
   ),);
app/lib/components/measurement_list/measurement_list.dart
@@ -4,6 +4,7 @@ import 'package:blood_pressure_app/model/storage/settings_store.dart';
 import 'package:flutter/material.dart';
 import 'package:flutter_gen/gen_l10n/app_localizations.dart';
 import 'package:health_data_store/health_data_store.dart';
+import 'package:provider/provider.dart';
 
 /// List that renders measurements and medicine intakes.
 ///
@@ -11,19 +12,16 @@ import 'package:health_data_store/health_data_store.dart';
 class MeasurementList extends StatelessWidget {
   /// Create a list to display measurements and intakes.
   const MeasurementList({super.key,
-    required this.settings,
     required this.entries,
   });
 
-  /// Settings that determine general behavior.
-  final Settings settings;
-
   /// Entries sorted with newest comming first.
   final List<FullEntry> entries;
 
   @override
   Widget build(BuildContext context) {
     final localizations = AppLocalizations.of(context)!;
+    final settings = context.watch<Settings>();
     return Column(
       mainAxisSize: MainAxisSize.min,
       children: [
@@ -72,7 +70,6 @@ class MeasurementList extends StatelessWidget {
             itemCount: entries.length,
             itemBuilder: (context, idx) => MeasurementListRow(
               data: entries[idx],
-              settings: settings,
               onRequestEdit: () => context.createEntry(entries[idx]),
             ),
           ),
app/lib/components/measurement_list/measurement_list_entry.dart
@@ -14,22 +14,19 @@ class MeasurementListRow extends StatelessWidget {
   /// Create a display of a measurements.
   const MeasurementListRow({super.key,
     required this.data,
-    required this.settings,
     required this.onRequestEdit,
   });
 
   /// The measurement to display.
   final FullEntry data;
 
-  /// Settings that determine general behavior.
-  final Settings settings;
-
   /// Called when the user taps on the edit icon.
   final void Function() onRequestEdit; // TODO: consider removing in favor of context methods
 
   @override
   Widget build(BuildContext context) {
     final localizations = AppLocalizations.of(context)!;
+    final settings = context.watch<Settings>();
     final formatter = DateFormat(settings.dateFormatString);
     return ExpansionTile(
       // Leading color possible
app/lib/components/statistics/blood_pressure_distribution.dart
@@ -4,6 +4,7 @@ import 'package:collection/collection.dart';
 import 'package:flutter/material.dart';
 import 'package:flutter_gen/gen_l10n/app_localizations.dart';
 import 'package:health_data_store/health_data_store.dart';
+import 'package:provider/provider.dart';
 
 /// Viewer for [ValueDistribution]s from [BloodPressureRecord]s.
 ///
@@ -14,7 +15,6 @@ class BloodPressureDistribution extends StatefulWidget {
   const BloodPressureDistribution({
     super.key,
     required this.records,
-    required this.settings,
   });
 
   /// All records to include in statistics computations.
@@ -24,9 +24,6 @@ class BloodPressureDistribution extends StatefulWidget {
   /// is required.
   final Iterable<BloodPressureRecord> records;
 
-  /// Settings used to determine colors in the distributions.
-  final Settings settings;
-
   @override
   State<BloodPressureDistribution> createState() =>
       _BloodPressureDistributionState();
@@ -83,17 +80,17 @@ class _BloodPressureDistributionState extends State<BloodPressureDistribution>
               ValueDistribution(
                 key: const Key('sys-dist'),
                 values: widget.records.map((e) => e.sys?.mmHg).whereNotNull(),
-                color: widget.settings.sysColor,
+                color: context.select<Settings, Color>((s) => s.sysColor),
               ),
               ValueDistribution(
                 key: const Key('dia-dist'),
                 values: widget.records.map((e) => e.dia?.mmHg).whereNotNull(),
-                color: widget.settings.diaColor,
+                color: context.select<Settings, Color>((s) => s.diaColor),
               ),
               ValueDistribution(
                 key: const Key('pul-dist'),
                 values: widget.records.map((e) => e.pul).whereNotNull(),
-                color: widget.settings.pulColor,
+                color: context.select<Settings, Color>((s) => s.pulColor),
               ),
             ],
           ),
app/lib/components/bluetooth_input.dart
@@ -22,7 +22,6 @@ import 'package:health_data_store/health_data_store.dart';
 class BluetoothInput extends StatefulWidget {
   /// Create a measurement input through bluetooth.
   const BluetoothInput({super.key,
-    required this.settings,
     required this.onMeasurement,
     this.bluetoothCubit,
     this.deviceScanCubit,
@@ -30,9 +29,6 @@ class BluetoothInput extends StatefulWidget {
     this.flutterBluePlus,
   });
 
-  /// Settings to store known devices.
-  final Settings settings;
-
   /// Called when a measurement was received through bluetooth.
   final void Function(BloodPressureRecord data) onMeasurement;
 
@@ -108,9 +104,10 @@ class _BluetoothInputState extends State<BluetoothInput> {
         _returnToIdle();
       }
     });
+    final settings = context.watch<Settings>();
     _deviceScanCubit ??= widget.deviceScanCubit?.call() ?? DeviceScanCubit(
       service: serviceUUID,
-      settings: widget.settings,
+      settings: settings,
       flutterBluePlus: widget.flutterBluePlus,
     );
     return BlocBuilder<DeviceScanCubit, DeviceScanState>(
app/lib/model/entry_context.dart
@@ -20,11 +20,9 @@ extension EntryUtils on BuildContext {
       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,
       );
app/lib/screens/elements/legacy_measurement_list.dart
@@ -1,11 +1,11 @@
 import 'package:blood_pressure_app/components/nullable_text.dart';
+import 'package:blood_pressure_app/components/pressure_text.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';
 import 'package:health_data_store/health_data_store.dart';
 import 'package:intl/intl.dart';
-
-import '../../components/pressure_text.dart';
+import 'package:provider/provider.dart';
 
 /// A old more compact [BloodPressureRecord] list, that lacks some of the new
 /// features.
@@ -13,15 +13,11 @@ class LegacyMeasurementsList extends StatefulWidget {
   /// Create a more compact measurement list without all new features.
   LegacyMeasurementsList({super.key,
     required this.data,
-    required this.settings,
   });
 
   /// Entries sorted with newest ordered first.
   final List<FullEntry> data;
 
-  /// Settings that determine general behavior.
-  final Settings settings;
-
   @override
   State<LegacyMeasurementsList> createState() => _LegacyMeasurementsListState();
 }
@@ -43,13 +39,16 @@ class _LegacyMeasurementsListState extends State<LegacyMeasurementsList> {
         child: Text(AppLocalizations.of(context)!.time, style: const TextStyle(fontWeight: FontWeight.bold)),),
       Expanded(
         flex: _tableElementsSizes[1],
-        child: Text(AppLocalizations.of(context)!.sysShort, style: TextStyle(fontWeight: FontWeight.bold, color: widget.settings.sysColor)),),
+        child: Text(AppLocalizations.of(context)!.sysShort,
+          style: TextStyle(fontWeight: FontWeight.bold, color: context.select<Settings, Color>((s) => s.sysColor))),),
       Expanded(
         flex: _tableElementsSizes[2],
-        child: Text(AppLocalizations.of(context)!.diaShort, style: TextStyle(fontWeight: FontWeight.bold, color: widget.settings.diaColor)),),
+        child: Text(AppLocalizations.of(context)!.diaShort,
+          style: TextStyle(fontWeight: FontWeight.bold, color: context.select<Settings, Color>((s) => s.diaColor))),),
       Expanded(
         flex: _tableElementsSizes[3],
-        child: Text(AppLocalizations.of(context)!.pulShort, style: TextStyle(fontWeight: FontWeight.bold, color: widget.settings.pulColor)),),
+        child: Text(AppLocalizations.of(context)!.pulShort,
+          style: TextStyle(fontWeight: FontWeight.bold, color: context.select<Settings, Color>((s) => s.pulColor))),),
       Expanded(
         flex: _tableElementsSizes[4],
         child: Text(AppLocalizations.of(context)!.notes, style: const TextStyle(fontWeight: FontWeight.bold)),),
@@ -61,7 +60,7 @@ class _LegacyMeasurementsListState extends State<LegacyMeasurementsList> {
   );
 
   Widget _itemBuilder(context, int index) {
-    final formatter = DateFormat(widget.settings.dateFormatString);
+    final formatter = DateFormat(context.select<Settings, String>((s) => s.dateFormatString));
     return Column(
       children: [
         Dismissible(
app/lib/screens/subsettings/export_import/export_column_management_screen.dart
@@ -1,7 +1,6 @@
 import 'package:blood_pressure_app/components/dialoges/add_export_column_dialoge.dart';
 import 'package:blood_pressure_app/model/export_import/column.dart';
 import 'package:blood_pressure_app/model/storage/export_columns_store.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';
 import 'package:provider/provider.dart';
@@ -48,8 +47,7 @@ class ExportColumnsManagementScreen extends StatelessWidget {
                         IconButton(
                           icon: const Icon(Icons.edit),
                           onPressed: () async {
-                            final settings = Provider.of<Settings>(context, listen: false);
-                            final editedColumn = await showAddExportColumnDialoge(context, settings, column);
+                            final editedColumn = await showAddExportColumnDialoge(context, column);
                             if (editedColumn != null) {
                               columnsManager.addOrUpdate(editedColumn);
                             }
@@ -83,8 +81,7 @@ class ExportColumnsManagementScreen extends StatelessWidget {
                   leading: const Icon(Icons.add),
                   title: Text(localizations.addExportformat),
                   onTap: () async{
-                    final settings = Provider.of<Settings>(context, listen: false);
-                    ExportColumn? editedColumn = await showAddExportColumnDialoge(context, settings);
+                    ExportColumn? editedColumn = await showAddExportColumnDialoge(context);
                     if (editedColumn != null) {
                       while (columnsManager.userColumns.containsKey(editedColumn!.internalIdentifier)) {
                         if (editedColumn is UserColumn) {
@@ -105,5 +102,4 @@ class ExportColumnsManagementScreen extends StatelessWidget {
       ),
     );
   }
-
-}
\ No newline at end of file
+}
app/lib/screens/subsettings/medicine_manager_screen.dart
@@ -4,7 +4,6 @@ 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:provider/provider.dart';
 
 /// Screen to view and edit medications saved in [Settings].
 ///
@@ -45,8 +44,7 @@ class _MedicineManagerScreenState extends State<MedicineManagerScreen> {
                 title: Text(localizations.addMedication),
                 onTap: () async {
                   final medRepo = RepositoryProvider.of<MedicineRepository>(context);
-                  final settings = Provider.of<Settings>(context, listen: false);
-                  final medicine = await showAddMedicineDialoge(context, settings,);
+                  final medicine = await showAddMedicineDialoge(context);
                   if (medicine != null) {
                     setState(() {
                       medicines.add(medicine);
app/lib/screens/home_screen.dart
@@ -47,39 +47,35 @@ class AppHome extends StatelessWidget {
           child: Padding(
             padding: const EdgeInsets.only(top: 20),
             child: Consumer<IntervallStoreManager>(builder: (context, intervalls, child) =>
-              Consumer<Settings>(builder: (context, settings, child) =>
-                Column(children: [
-                  /*MeasurementListRow(
-                    settings: Settings(), data: (BloodPressureRecord(time: DateTime(2023),
-                    sys:Pressure.mmHg(1), dia: Pressure.mmHg(2), pul: 3), Note(time: DateTime(2023), note: 'testTxt',), [])),*/
-                  const MeasurementGraph(),
-                  Expanded(
-                    child: BloodPressureBuilder(
+              Column(children: [
+                /*MeasurementListRow(
+                  settings: Settings(), data: (BloodPressureRecord(time: DateTime(2023),
+                  sys:Pressure.mmHg(1), dia: Pressure.mmHg(2), pul: 3), Note(time: DateTime(2023), note: 'testTxt',), [])),*/
+                const MeasurementGraph(),
+                Expanded(
+                  child: BloodPressureBuilder(
+                    rangeType: IntervallStoreManagerLocation.mainPage,
+                    onData: (context, records) => RepositoryBuilder<MedicineIntake, MedicineIntakeRepository>(
                       rangeType: IntervallStoreManagerLocation.mainPage,
-                      onData: (context, records) => RepositoryBuilder<MedicineIntake, MedicineIntakeRepository>(
+                      onData: (BuildContext context, List<MedicineIntake> intakes) => RepositoryBuilder<Note, NoteRepository>(
                         rangeType: IntervallStoreManagerLocation.mainPage,
-                        onData: (BuildContext context, List<MedicineIntake> intakes) => RepositoryBuilder<Note, NoteRepository>(
-                          rangeType: IntervallStoreManagerLocation.mainPage,
-                          onData: (BuildContext context, List<Note> notes) {
-                            final entries = FullEntryList.merged(records, notes, intakes);
-                            entries.sort((a, b) => b.time.compareTo(a.time)); // newest first
-                            if (settings.compactList) {
-                              return LegacyMeasurementsList(
-                                data: entries,
-                                settings: settings,
-                              );
-                            }
-                            return MeasurementList(
-                              settings: settings,
-                              entries: entries,
+                        onData: (BuildContext context, List<Note> notes) {
+                          final entries = FullEntryList.merged(records, notes, intakes);
+                          entries.sort((a, b) => b.time.compareTo(a.time)); // newest first
+                          if (context.select<Settings, bool>((s) => s.compactList)) {
+                            return LegacyMeasurementsList(
+                              data: entries,
                             );
-                          },
-                        ),
+                          }
+                          return MeasurementList(
+                            entries: entries,
+                          );
+                        },
                       ),
                     ),
                   ),
-                ],),
-              ),),
+                ),
+              ],),),
             ),
         );
       },
app/lib/screens/statistics_screen.dart
@@ -26,99 +26,97 @@ class _StatisticsScreenState extends State<StatisticsScreen> {
       appBar: AppBar(
         title: Text(localizations.statistics),
       ),
-      body: Consumer<Settings>(
-        builder: (context, settings, child) => BloodPressureBuilder(
-          rangeType: IntervallStoreManagerLocation.statsPage,
-          onData: (context, data) {
-            final analyzer = BloodPressureAnalyser(data.toList());
-            return ListView(
-              children: [
-                _buildSubTitle(localizations.statistics,),
-                ListTile(
-                  title: Text(localizations.measurementCount),
-                  trailing: Text(
-                    data.length.toString(),
-                    style: Theme.of(context).textTheme.headlineSmall,
-                  ),
+      body: BloodPressureBuilder(
+        rangeType: IntervallStoreManagerLocation.statsPage,
+        onData: (context, data) {
+          final analyzer = BloodPressureAnalyser(data.toList());
+          return ListView(
+            children: [
+              _buildSubTitle(localizations.statistics,),
+              ListTile(
+                title: Text(localizations.measurementCount),
+                trailing: Text(
+                  data.length.toString(),
+                  style: Theme.of(context).textTheme.headlineSmall,
                 ),
-                ListTile(
-                  title: Text(localizations.measurementsPerDay),
-                  trailing: Text(
-                    analyzer.measurementsPerDay?.toString() ?? '-',
-                    style: Theme.of(context).textTheme.headlineSmall,
-                  ),
+              ),
+              ListTile(
+                title: Text(localizations.measurementsPerDay),
+                trailing: Text(
+                  analyzer.measurementsPerDay?.toString() ?? '-',
+                  style: Theme.of(context).textTheme.headlineSmall,
                 ),
-                _buildSubTitle(localizations.valueDistribution,),
-                Container(
-                  height: 260,
-                  padding: const EdgeInsets.symmetric(horizontal: 16.0),
-                  child: BloodPressureDistribution(
-                    records: data,
-                    settings: settings,
-                  ),
+              ),
+              _buildSubTitle(localizations.valueDistribution,),
+              Container(
+                height: 260,
+                padding: const EdgeInsets.symmetric(horizontal: 16.0),
+                child: BloodPressureDistribution(
+                  records: data,
                 ),
-                _buildSubTitle(localizations.timeResolvedMetrics),
-                () {
-                  final data = analyzer.allAvgsRelativeToDaytime;
-                  const opacity = 0.5;
-                  final helperLinesStyle = BorderSide(
-                    color: Theme.of(context).dividerColor,
-                    width: 2,
-                  );
-                  return Container(
-                    padding: const EdgeInsets.symmetric(horizontal: 16.0),
-                    height: MediaQuery.of(context).size.width,
-                    child: RadarChart(
-                      RadarChartData(
-                        radarShape: RadarShape.circle,
-                        gridBorderData: helperLinesStyle,
-                        tickBorderData: helperLinesStyle,
-                        ticksTextStyle: const TextStyle(
-                          color: Colors.transparent,
-                        ),
-                        tickCount: 5,
-                        titleTextStyle: const TextStyle(fontSize: 25),
-                        getTitle: (pos, value) {
-                          if (pos % 2 == 0) {
-                            return RadarChartTitle(
-                              text: '$pos',
-                              positionPercentageOffset: 0.05,
-                            );
-                          }
-                          return const RadarChartTitle(text: '');
-                        },
-                        dataSets: [
-                          RadarDataSet( // FIXME
-                            dataEntries: _intListToRadarEntry(data[0]),
-                            borderColor: settings.diaColor,
-                            fillColor: settings.diaColor.withOpacity(opacity),
-                            entryRadius: 0,
-                            borderWidth: settings.graphLineThickness,
-                          ),
-                          RadarDataSet(
-                            dataEntries: _intListToRadarEntry(data[1]),
-                            borderColor: settings.sysColor,
-                            fillColor: settings.sysColor.withOpacity(opacity),
-                            entryRadius: 0,
-                            borderWidth: settings.graphLineThickness,
-                          ),
-                          RadarDataSet(
-                            dataEntries: _intListToRadarEntry(data[2]),
-                            borderColor: settings.pulColor,
-                            fillColor: settings.pulColor.withOpacity(opacity),
-                            entryRadius: 0,
-                            borderWidth: settings.graphLineThickness,
-                          ),
-                        ],
+              ),
+              _buildSubTitle(localizations.timeResolvedMetrics),
+              () {
+                final data = analyzer.allAvgsRelativeToDaytime;
+                const opacity = 0.5;
+                final helperLinesStyle = BorderSide(
+                  color: Theme.of(context).dividerColor,
+                  width: 2,
+                );
+                final settings = context.watch<Settings>();
+                return Container(
+                  padding: const EdgeInsets.symmetric(horizontal: 16.0),
+                  height: MediaQuery.of(context).size.width,
+                  child: RadarChart(
+                    RadarChartData(
+                      radarShape: RadarShape.circle,
+                      gridBorderData: helperLinesStyle,
+                      tickBorderData: helperLinesStyle,
+                      ticksTextStyle: const TextStyle(
+                        color: Colors.transparent,
                       ),
+                      tickCount: 5,
+                      titleTextStyle: const TextStyle(fontSize: 25),
+                      getTitle: (pos, value) {
+                        if (pos % 2 == 0) {
+                          return RadarChartTitle(
+                            text: '$pos',
+                            positionPercentageOffset: 0.05,
+                          );
+                        }
+                        return const RadarChartTitle(text: '');
+                      },
+                      dataSets: [
+                        RadarDataSet(
+                          dataEntries: _intListToRadarEntry(data[0]),
+                          borderColor: settings.diaColor,
+                          fillColor: settings.diaColor.withOpacity(opacity),
+                          entryRadius: 0,
+                          borderWidth: settings.graphLineThickness,
+                        ),
+                        RadarDataSet(
+                          dataEntries: _intListToRadarEntry(data[1]),
+                          borderColor: settings.sysColor,
+                          fillColor: settings.sysColor.withOpacity(opacity),
+                          entryRadius: 0,
+                          borderWidth: settings.graphLineThickness,
+                        ),
+                        RadarDataSet(
+                          dataEntries: _intListToRadarEntry(data[2]),
+                          borderColor: settings.pulColor,
+                          fillColor: settings.pulColor.withOpacity(opacity),
+                          entryRadius: 0,
+                          borderWidth: settings.graphLineThickness,
+                        ),
+                      ],
                     ),
-                  );
-                }(),
-              ],
-            );
-          },
-        ),
-            ),
+                  ),
+                );
+              }(),
+            ],
+          );
+        },
+      ),
       bottomNavigationBar: Container(
         height: 70,
         margin: const EdgeInsets.only(top: 15, bottom: 5),
app/test/ui/components/measurement_list/measurement_list_entry_test.dart
@@ -1,5 +1,4 @@
 import 'package:blood_pressure_app/components/measurement_list/measurement_list_entry.dart';
-import 'package:blood_pressure_app/model/storage/settings_store.dart';
 import 'package:flutter/material.dart';
 import 'package:flutter_test/flutter_test.dart';
 import 'package:health_data_store/health_data_store.dart';
@@ -11,24 +10,20 @@ void main() {
   testWidgets('should initialize without errors', (tester) async {
     await tester.pumpWidget(materialApp(MeasurementListRow(
       onRequestEdit: () => fail('should not request edit'),
-      settings: Settings(),
       data: mockEntryPos(DateTime(2023), 123, 80, 60, 'test'),),),);
     expect(tester.takeException(), isNull);
     await tester.pumpWidget(materialApp(MeasurementListRow(
       onRequestEdit: () => fail('should not request edit'),
-      settings: Settings(),
       data: mockEntryPos(DateTime.fromMillisecondsSinceEpoch(31279811), null, null, null, 'null test'),),),);
     expect(tester.takeException(), isNull);
     await tester.pumpWidget(materialApp(MeasurementListRow(
-        onRequestEdit: () => fail('should not request edit'),
-      settings: Settings(),
+      onRequestEdit: () => fail('should not request edit'),
       data: mockEntryPos(DateTime(2023), 124, 85, 63, 'color',Colors.cyan))));
     expect(tester.takeException(), isNull);
   });
   testWidgets('should expand correctly', (tester) async {
     await tester.pumpWidget(materialApp(MeasurementListRow(
       onRequestEdit: () => fail('should not request edit'),
-        settings: Settings(),
         data: mockEntryPos(DateTime(2023), 123, 78, 56),),),);
     expect(find.byIcon(Icons.medication), findsNothing);
     expect(find.byIcon(Icons.expand_more), findsOneWidget);
@@ -41,7 +36,6 @@ void main() {
   testWidgets('should display correct information', (tester) async {
     await tester.pumpWidget(materialApp(MeasurementListRow(
         onRequestEdit: () => fail('should not request edit'),
-        settings: Settings(),
         data: mockEntryPos(DateTime(2023), 123, 78, 56, 'Test text'),),),);
     expect(find.text('123'), findsOneWidget);
     expect(find.text('78'), findsOneWidget);
@@ -66,7 +60,7 @@ void main() {
   testWidgets('should not display null values', (tester) async {
     await tester.pumpWidget(materialApp(MeasurementListRow(
       onRequestEdit: () => fail('should not request edit'),
-      settings: Settings(), data: mockEntry(time: DateTime(2023)),),),);
+      data: mockEntry(time: DateTime(2023)),),),);
     expect(find.text('null'), findsNothing);
     expect(find.byIcon(Icons.medication), findsNothing);
     expect(find.byIcon(Icons.expand_more), findsOneWidget);
@@ -77,7 +71,6 @@ void main() {
   testWidgets('should propagate edit request', (tester) async {
     int requestCount = 0;
     await tester.pumpWidget(materialApp(MeasurementListRow(
-      settings: Settings(),
       data: mockEntry(
         time: DateTime(2023),
         sys:1,
@@ -109,7 +102,6 @@ void main() {
   testWidgets('should indicate presence of intakes', (tester) async {
     await tester.pumpWidget(materialApp(MeasurementListRow(
       onRequestEdit: () => fail('should not request edit'),
-      settings: Settings(),
       data: mockEntry(
         time: DateTime(2023),
         intake: mockIntake(mockMedicine(designation: 'testMed', color: Colors.red), dosis: 12.0),
app/test/ui/components/measurement_list/measurement_list_test.dart
@@ -1,6 +1,8 @@
 import 'package:blood_pressure_app/components/measurement_list/measurement_list.dart';
 import 'package:blood_pressure_app/components/measurement_list/measurement_list_entry.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';
 import 'package:flutter_test/flutter_test.dart';
 
 import '../../../model/export_import/record_formatter_test.dart';
@@ -10,7 +12,6 @@ void main() {
   testWidgets('contains all elements in time range', (tester) async {
     await tester.pumpWidget(materialApp(
       MeasurementList(
-        settings: Settings(),
         entries: [
           mockEntry(time: DateTime(2020), sys: 2020),
           mockEntry(time: DateTime(2021), sys: 2021),
@@ -25,22 +26,58 @@ void main() {
     expect(find.text('2022'), findsOneWidget);
     expect(find.text('2023'), findsOneWidget);
   });
-  testWidgets('entries are ordered in reversed chronological order', (tester) async {
+  testWidgets('entries are ordered in reversed passed order', (tester) async {
     await tester.pumpWidget(materialApp(
       MeasurementList(
-        settings: Settings(),
         entries: [
-          mockEntry(time: DateTime.fromMillisecondsSinceEpoch(2000), sys: 2),
           mockEntry(time: DateTime.fromMillisecondsSinceEpoch(4000), sys: 1),
+          mockEntry(time: DateTime.fromMillisecondsSinceEpoch(2000), sys: 2),
           mockEntry(time: DateTime.fromMillisecondsSinceEpoch(1000), sys: 3),
         ],
       ),
     ));
     expect(find.byType(MeasurementListRow), findsNWidgets(3));
+    // coordinates starting at top left
     final top = await tester.getCenter(find.text('1')).dy;
     final center = await tester.getCenter(find.text('2')).dy;
     final bottom = await tester.getCenter(find.text('3')).dy;
     expect(bottom, greaterThan(center));
-    expect(center, greaterThan(top));
+    expect(top, lessThan(center));
+  });
+  testWidgets('entries are ordered in reversed chronological order', (tester) async {
+    final localizations = await AppLocalizations.delegate.load(const Locale('en'));
+    await tester.pumpWidget(materialApp(
+      MeasurementList(
+        entries: [
+          mockEntry(time: DateTime.fromMillisecondsSinceEpoch(2000), sys: 2),
+        ],
+      ),
+      settings: Settings(
+        sysColor: Colors.blue,
+        diaColor: Colors.purple,
+        pulColor: Colors.indigo,
+      )
+    ));
+    expect(
+      find.byWidgetPredicate((widget) =>
+        widget is Text
+        && widget.data == localizations.sysLong
+        && widget.style?.color == Colors.blue),
+      findsOneWidget,
+    );
+    expect(
+      find.byWidgetPredicate((widget) =>
+        widget is Text
+        && widget.data == localizations.diaLong
+        && widget.style?.color == Colors.purple),
+      findsOneWidget,
+    );
+    expect(
+      find.byWidgetPredicate((widget) =>
+        widget is Text
+        && widget.data == localizations.pulLong
+        && widget.style?.color == Colors.indigo),
+      findsOneWidget,
+    );
   });
 }
app/test/ui/components/statistics/blood_pressure_distribution_test.dart
@@ -10,10 +10,7 @@ import '../util.dart';
 
 void main() {
   testWidgets('should show allow navigation to view all widgets', (tester) async {
-    await tester.pumpWidget(materialApp(BloodPressureDistribution(
-      records: const [],
-      settings: Settings(),
-    ),),);
+    await tester.pumpWidget(materialApp(BloodPressureDistribution(records: [])));
 
     final localizations = await AppLocalizations.delegate.load(const Locale('en'));
 
@@ -38,21 +35,23 @@ void main() {
     expect(find.byKey(const Key('pul-dist')), findsOneWidget);
   });
   testWidgets('should report records to ValueDistribution', (tester) async {
-    await tester.pumpWidget(materialApp(BloodPressureDistribution(
-      records: [
-        mockRecord(sys: 123),
-        mockRecord(dia: 123),
-        mockRecord(dia: 124),
-        mockRecord(pul: 123),
-        mockRecord(pul: 124),
-        mockRecord(pul: 125),
-      ],
+    await tester.pumpWidget(materialApp(
+      BloodPressureDistribution(
+        records: [
+          mockRecord(sys: 123),
+          mockRecord(dia: 123),
+          mockRecord(dia: 124),
+          mockRecord(pul: 123),
+          mockRecord(pul: 124),
+          mockRecord(pul: 125),
+        ],
+      ),
       settings: Settings(
         sysColor: Colors.red,
         diaColor: Colors.green,
         pulColor: Colors.blue,
       ),
-    ),),);
+    ),);
 
     final localizations = await AppLocalizations.delegate.load(const Locale('en'));
 
app/test/ui/components/add_export_column_dialoge_test.dart
@@ -1,7 +1,6 @@
 import 'package:blood_pressure_app/components/dialoges/add_export_column_dialoge.dart';
 import 'package:blood_pressure_app/components/measurement_list/measurement_list_entry.dart';
 import 'package:blood_pressure_app/model/export_import/column.dart';
-import 'package:blood_pressure_app/model/storage/settings_store.dart';
 import 'package:blood_pressure_app/screens/subsettings/export_import/export_field_format_documentation_screen.dart';
 import 'package:flutter/material.dart';
 import 'package:flutter_gen/gen_l10n/app_localizations.dart';
@@ -12,7 +11,7 @@ import 'util.dart';
 void main() {
   group('AddExportColumnDialoge', () {
     testWidgets('should show everything on load', (tester) async {
-      await tester.pumpWidget(materialApp(AddExportColumnDialoge(settings: Settings(),)));
+      await tester.pumpWidget(materialApp(AddExportColumnDialoge()));
       expect(tester.takeException(), isNull);
 
       expect(find.text('SAVE'), findsOneWidget);
@@ -27,7 +26,7 @@ void main() {
     });
     testWidgets('should prefill values', (tester) async {
       await tester.pumpWidget(materialApp(
-          AddExportColumnDialoge(initialColumn: UserColumn('id', 'csvTitle', r'formatPattern$SYS'), settings: Settings(),),
+          AddExportColumnDialoge(initialColumn: UserColumn('id', 'csvTitle', r'formatPattern$SYS'),),
       ),);
       expect(tester.takeException(), isNull);
 
@@ -43,7 +42,7 @@ void main() {
     });
     testWidgets('should show preview', (tester) async {
       await tester.pumpWidget(materialApp(
-          AddExportColumnDialoge(initialColumn: UserColumn('id', 'csvTitle', r'formatPattern$SYS'), settings: Settings(),),
+          AddExportColumnDialoge(initialColumn: UserColumn('id', 'csvTitle', r'formatPattern$SYS'),),
       ),);
       await tester.pumpAndSettle();
 
@@ -53,7 +52,7 @@ void main() {
       expect(find.textContaining('RowDataFieldType.sys'), findsOneWidget);
     });
     testWidgets('should open format Info screen', (tester) async {
-      await tester.pumpWidget(materialApp(AddExportColumnDialoge(settings: Settings(),)));
+      await tester.pumpWidget(materialApp(AddExportColumnDialoge()));
 
       expect(find.byType(InformationScreen), findsNothing);
 
@@ -66,13 +65,13 @@ void main() {
   });
   group('showAddExportColumnDialoge', () {
     testWidgets('should open AddExportColumnDialoge', (tester) async {
-      await loadDialoge(tester, (context) => showAddExportColumnDialoge(context, Settings()));
+      await loadDialoge(tester, (context) => showAddExportColumnDialoge(context));
 
       expect(find.byType(AddExportColumnDialoge), findsOneWidget);
     });
     testWidgets('should return null on cancel', (tester) async {
       dynamic returnedValue = false;
-      await loadDialoge(tester, (context) async => returnedValue = await showAddExportColumnDialoge(context, Settings()));
+      await loadDialoge(tester, (context) async => returnedValue = await showAddExportColumnDialoge(context));
 
       expect(returnedValue, false);
       expect(find.byIcon(Icons.close), findsOneWidget);
@@ -84,7 +83,7 @@ void main() {
     });
     testWidgets('should save entered values', (tester) async {
       dynamic returnedValue = false;
-      await loadDialoge(tester, (context) async => returnedValue = await showAddExportColumnDialoge(context, Settings()));
+      await loadDialoge(tester, (context) async => returnedValue = await showAddExportColumnDialoge(context));
 
       final localizations = await AppLocalizations.delegate.load(const Locale('en'));
 
@@ -116,7 +115,7 @@ void main() {
 
       dynamic returnedValue = false;
       await loadDialoge(tester, (context) async => returnedValue =
-        await showAddExportColumnDialoge(context, Settings(),
+        await showAddExportColumnDialoge(context,
           UserColumn('initialInternalIdentifier', 'csvTitle', 'formatPattern'),
       ),);
 
app/test/ui/components/add_measurement_dialoge_test.dart
@@ -18,7 +18,6 @@ void main() {
       await tester.pumpWidget(materialApp(
         AddEntryDialoge(
           availableMeds: [],
-          settings: Settings(),
         ),
       ),);
       expect(tester.takeException(), isNull);
@@ -34,7 +33,6 @@ void main() {
     testWidgets('should prefill initialRecord values', (tester) async {
       await tester.pumpWidget(materialApp(
         AddEntryDialoge(
-          settings: Settings(),
           initialRecord: mockEntryPos(
             DateTime.now(), 123, 56, 43, 'Test note', Colors.teal,
           ),
@@ -55,7 +53,6 @@ void main() {
     testWidgets('should show medication picker when medications available', (tester) async {
       await tester.pumpWidget(materialApp(
         AddEntryDialoge(
-          settings: Settings(),
           availableMeds: [ mockMedicine(designation: 'testmed') ],
         ),
       ),);
@@ -74,7 +71,6 @@ void main() {
     testWidgets('should reveal dosis on medication selection', (tester) async {
       await tester.pumpWidget(materialApp(
         AddEntryDialoge(
-          settings: Settings(),
           availableMeds: [ mockMedicine(designation: 'testmed') ],
         ),
       ),);
@@ -104,7 +100,6 @@ void main() {
     testWidgets('should enter default dosis if available', (tester) async {
       await tester.pumpWidget(materialApp(
         AddEntryDialoge(
-          settings: Settings(),
           availableMeds: [ mockMedicine(designation: 'testmed', defaultDosis: 3.1415) ],
         ),
       ),);
@@ -121,7 +116,6 @@ void main() {
     testWidgets('should not quit when the measurement field is incorrectly filled, but a intake is added', (tester) async {
       await tester.pumpWidget(materialApp(
         AddEntryDialoge(
-          settings: Settings(),
           availableMeds: [ mockMedicine(designation: 'testmed', defaultDosis: 3.1415) ],
         ),
       ),);
@@ -154,9 +148,9 @@ void main() {
       );
       await tester.pumpWidget(materialApp(
         AddEntryDialoge(
-          settings: settings,
           availableMeds: [],
         ),
+        settings: settings,
       ),);
       await tester.pumpAndSettle();
       expect(find.byType(BluetoothInput, skipOffstage: false), findsOneWidget);
@@ -170,7 +164,7 @@ void main() {
     testWidgets('should return null on cancel', (tester) async {
       dynamic result = 'result before save';
       await loadDialoge(tester, (context) async
-      => result = await showAddEntryDialoge(context, Settings(),
+      => result = await showAddEntryDialoge(context,
         medRepo(),
         mockEntry(sys: 123, dia: 56, pul: 43, note: 'Test note', pin: Colors.teal),),);
       expect(find.byType(DropdownButton<Medicine?>), findsNothing, reason: 'No medication in settings.');
@@ -186,7 +180,7 @@ void main() {
       dynamic result = 'result before save';
       final record = mockEntry(sys: 123, dia: 56, pul: 43, note: 'Test note', pin: Colors.teal);
       await loadDialoge(tester, (context) async {
-        result = await showAddEntryDialoge(context, Settings(), medRepo(), record);
+        result = await showAddEntryDialoge(context, medRepo(), record);
       },);
       expect(find.byType(DropdownButton<Medicine?>), findsNothing, reason: 'No medication in settings.');
 
@@ -207,7 +201,7 @@ void main() {
     testWidgets('should be able to input records', (WidgetTester tester) async {
       dynamic result = 'result before save';
       await loadDialoge(tester, (context) async {
-        result = await showAddEntryDialoge(context, Settings(), medRepo(),);
+        result = await showAddEntryDialoge(context, medRepo(),);
       });
       expect(find.byType(DropdownButton<Medicine?>), findsNothing, reason: 'No medication in settings.');
 
@@ -236,7 +230,7 @@ void main() {
     testWidgets('should allow value only', (WidgetTester tester) async {
       dynamic result = 'result before save';
       await loadDialoge(tester, (context) async
-      => result = await showAddEntryDialoge(context, Settings(), medRepo(),),);
+      => result = await showAddEntryDialoge(context, medRepo(),),);
       expect(find.byType(DropdownButton<Medicine?>), findsNothing, reason: 'No medication in settings.');
       final localizations = await AppLocalizations.delegate.load(const Locale('en'));
 
@@ -262,7 +256,7 @@ void main() {
     testWidgets('should allow note only', (WidgetTester tester) async {
       dynamic result = 'result before save';
       await loadDialoge(tester, (context) async
-      => result = await showAddEntryDialoge(context, Settings(), medRepo(),),);
+      => result = await showAddEntryDialoge(context, medRepo(),),);
       expect(find.byType(DropdownButton<Medicine?>), findsNothing, reason: 'No medication in settings.');
 
       final localizations = await AppLocalizations.delegate.load(const Locale('en'));
@@ -286,7 +280,7 @@ void main() {
 
       dynamic result = 'result before save';
       await loadDialoge(tester, (context) async
-      => result = await showAddEntryDialoge(context, Settings(), medRepo([
+      => result = await showAddEntryDialoge(context, medRepo([
         mockMedicine(designation: 'medication1'),
         med2,
       ],),),);
@@ -330,7 +324,7 @@ void main() {
     });
     testWidgets('should not allow invalid values', (tester) async {
       final mRep = medRepo();
-      await loadDialoge(tester, (context) => showAddEntryDialoge(context, Settings(), mRep));
+      await loadDialoge(tester, (context) => showAddEntryDialoge(context, mRep));
       final localizations = await AppLocalizations.delegate.load(const Locale('en'));
 
       expect(find.byType(DropdownButton<Medicine?>), findsNothing, reason: 'No medication in settings.');
@@ -394,8 +388,9 @@ void main() {
     });
     testWidgets('should allow invalid values when setting is set', (tester) async {
       final mRep = medRepo();
-      await loadDialoge(tester, (context) =>
-          showAddEntryDialoge(context, Settings(validateInputs: false, allowMissingValues: true), mRep),);
+      await loadDialoge(tester, (context) => showAddEntryDialoge(context, mRep),
+        settings: Settings(validateInputs: false, allowMissingValues: true),
+      );
       expect(find.byType(DropdownButton<Medicine?>), findsNothing, reason: 'No medication in settings.');
 
       await tester.enterText(find.ancestor(of: find.text('Systolic').first, matching: find.byType(TextFormField)), '2');
@@ -406,8 +401,9 @@ void main() {
     });
     testWidgets('should respect settings.allowManualTimeInput', (tester) async {
       final mRep = medRepo();
-      await loadDialoge(tester, (context) =>
-          showAddEntryDialoge(context, Settings(allowManualTimeInput: false), mRep),);
+      await loadDialoge(tester, (context) => showAddEntryDialoge(context, mRep),
+        settings: Settings(allowManualTimeInput: false),
+      );
       expect(find.byType(DropdownButton<Medicine?>), findsNothing, reason: 'No medication in settings.');
 
       expect(find.byIcon(Icons.edit), findsNothing);
@@ -415,7 +411,7 @@ void main() {
     testWidgets('should start with sys input focused', (tester) async {
       final mRep = medRepo();
       await loadDialoge(tester, (context) =>
-          showAddEntryDialoge(context, Settings(), mRep, mockEntry(sys: 12)),);
+          showAddEntryDialoge(context, mRep, mockEntry(sys: 12)),);
       expect(find.byType(DropdownButton<Medicine?>), findsNothing, reason: 'No medication in settings.');
 
       final primaryFocus = FocusManager.instance.primaryFocus;
@@ -431,7 +427,7 @@ void main() {
     testWidgets('should focus next on input finished', (tester) async {
       final mRep = medRepo();
       await loadDialoge(tester, (context) =>
-          showAddEntryDialoge(context, Settings(), mRep, mockEntry(sys: 12, dia: 3, pul: 4, note: 'note')),);
+          showAddEntryDialoge(context, mRep, mockEntry(sys: 12, dia: 3, pul: 4, note: 'note')),);
       expect(find.byType(DropdownButton<Medicine?>), findsNothing, reason: 'No medication in settings.');
 
       await tester.enterText(find.ancestor(of: find.text('Systolic').first, matching: find.byType(TextFormField)), '123');
@@ -473,7 +469,7 @@ void main() {
     testWidgets('should focus last input field on backspace pressed in empty input field', (tester) async {
       final mRep = medRepo();
       await loadDialoge(tester, (context) =>
-          showAddEntryDialoge(context, Settings(), mRep, mockEntry(sys: 12, dia: 3, pul: 4, note: 'note')),);
+          showAddEntryDialoge(context, mRep, mockEntry(sys: 12, dia: 3, pul: 4, note: 'note')),);
       expect(find.byType(DropdownButton<Medicine?>), findsNothing, reason: 'No medication in settings.');
 
       await tester.enterText(find.ancestor(of: find.text('note').first, matching: find.byType(TextFormField)), '');
@@ -535,7 +531,7 @@ void main() {
       final mRep = medRepo([mockMedicine(designation: 'testmed')]);
       dynamic result;
       await loadDialoge(tester, (context) async =>
-        result = await showAddEntryDialoge(context, Settings(), mRep),
+        result = await showAddEntryDialoge(context, mRep),
       );
 
       await tester.tap(find.byType(DropdownButton<Medicine?>));
@@ -575,7 +571,7 @@ void main() {
       final mRep = medRepo([mockMedicine(designation: 'testmed')]);
       dynamic result;
       await loadDialoge(tester, (context) async =>
-        result = await showAddEntryDialoge(context, Settings(), mRep),
+        result = await showAddEntryDialoge(context, mRep),
       );
       final localizations = await AppLocalizations.delegate.load(const Locale('en'));
 
@@ -619,7 +615,7 @@ void main() {
     testWidgets('should not go back to last field when the current field is still filled', (tester) async {
       final mRep = medRepo([mockMedicine(designation: 'testmed')]);
       await loadDialoge(tester, (context) =>
-          showAddEntryDialoge(context, Settings(), mRep, mockEntry(sys: 12, dia: 3, pul: 4, note: 'note')),);
+          showAddEntryDialoge(context, mRep, mockEntry(sys: 12, dia: 3, pul: 4, note: 'note')),);
       expect(find.byType(DropdownButton<Medicine?>), findsNothing, reason: 'No medication in settings.');
 
       await tester.enterText(find.ancestor(
app/test/ui/components/bluetooth_input_test.dart
@@ -6,7 +6,6 @@ import 'package:blood_pressure_app/bluetooth/device_scan_cubit.dart';
 import 'package:blood_pressure_app/components/bluetooth_input.dart';
 import 'package:blood_pressure_app/components/bluetooth_input/closed_bluetooth_input.dart';
 import 'package:blood_pressure_app/components/bluetooth_input/measurement_success.dart';
-import 'package:blood_pressure_app/model/storage/storage.dart';
 import 'package:flutter/material.dart';
 import 'package:flutter_blue_plus/flutter_blue_plus.dart' hide BluetoothState;
 import 'package:flutter_test/flutter_test.dart';
@@ -47,7 +46,6 @@ void main() {
 
     final List<BloodPressureRecord> reads = [];
     await tester.pumpWidget(materialApp(BluetoothInput(
-      settings: Settings(),
       onMeasurement: reads.add,
       bluetoothCubit: () => bluetoothCubit,
       deviceScanCubit: () => deviceScanCubit,
@@ -59,11 +57,9 @@ void main() {
     expect(find.byType(ClosedBluetoothInput), findsNothing);
 
     expect(reads, hasLength(1));
-    expect(reads, contains(isA<BloodPressureRecord>()
-      .having((p) => p.sys, 'sys', 123)
-      .having((p) => p.dia, 'dia', 45)
-      .having((p) => p.pul, 'pul', isNull),
-    ));
+    expect(reads.first.sys?.mmHg, 123);
+    expect(reads.first.dia?.mmHg, 45);
+    expect(reads.first.pul, null);
   });
 
   testWidgets('allows closing after successful read', (WidgetTester tester) async {
@@ -91,7 +87,6 @@ void main() {
 
     final List<BloodPressureRecord> reads = [];
     await tester.pumpWidget(materialApp(BluetoothInput(
-      settings: Settings(),
       onMeasurement: reads.add,
       bluetoothCubit: () => bluetoothCubit,
       deviceScanCubit: () => deviceScanCubit,
app/test/ui/components/util.dart
@@ -8,11 +8,33 @@ import 'package:provider/provider.dart';
 import 'package:sqflite_common_ffi/sqflite_ffi.dart';
 
 /// Create a root material widget with localizations.
-Widget materialApp(Widget child) => MaterialApp(
-  localizationsDelegates: AppLocalizations.localizationsDelegates,
-  locale: const Locale('en'),
-  home: Scaffold(body:child),
-);
+Widget materialApp(Widget child, {
+  Settings? settings,
+  ExportSettings? exportSettings,
+  CsvExportSettings? csvExportSettings,
+  PdfExportSettings? pdfExportSettings,
+  IntervallStoreManager? intervallStoreManager,
+}) {
+  settings ??= Settings();
+  exportSettings ??= ExportSettings();
+  csvExportSettings ??= CsvExportSettings();
+  pdfExportSettings ??= PdfExportSettings();
+  intervallStoreManager ??= IntervallStoreManager(IntervallStorage(), IntervallStorage(), IntervallStorage());
+  return MultiProvider(
+    providers: [
+      ChangeNotifierProvider.value(value: settings),
+      ChangeNotifierProvider.value(value: exportSettings),
+      ChangeNotifierProvider.value(value: csvExportSettings),
+      ChangeNotifierProvider.value(value: pdfExportSettings),
+      ChangeNotifierProvider.value(value: intervallStoreManager),
+    ],
+    child: MaterialApp(
+      localizationsDelegates: AppLocalizations.localizationsDelegates,
+      locale: const Locale('en'),
+      home: Scaffold(body:child),
+    ),
+  );
+}
 
 /// Creates a the same App as the main method.
 Future<Widget> appBase(Widget child,  {
@@ -25,31 +47,25 @@ Future<Widget> appBase(Widget child,  {
   MedicineRepository? medRepo,
   MedicineIntakeRepository? intakeRepo,
 }) async {
-  settings ??= Settings();
-  exportSettings ??= ExportSettings();
-  csvExportSettings ??= CsvExportSettings();
-  pdfExportSettings ??= PdfExportSettings();
-  intervallStoreManager ??= IntervallStoreManager(IntervallStorage(), IntervallStorage(), IntervallStorage());
-
   HealthDataStore? db;
   if (bpRepo == null || medRepo == null || intakeRepo == null) {
     db = await _getHealthDateStore();
   }
 
-  return MultiProvider(providers: [
-    ChangeNotifierProvider(create: (_) => settings),
-    ChangeNotifierProvider(create: (_) => exportSettings),
-    ChangeNotifierProvider(create: (_) => csvExportSettings),
-    ChangeNotifierProvider(create: (_) => pdfExportSettings),
-    ChangeNotifierProvider(create: (_) => intervallStoreManager),
-  ], child: MultiRepositoryProvider(
+  return MultiRepositoryProvider(
     providers: [
       RepositoryProvider(create: (context) => bpRepo ?? db!.bpRepo),
       RepositoryProvider(create: (context) => medRepo ?? db!.medRepo),
       RepositoryProvider(create: (context) => intakeRepo ?? db!.intakeRepo),
     ],
-    child: materialApp(child),
-  ),);
+    child: materialApp(child,
+      settings: settings,
+      exportSettings: exportSettings,
+      csvExportSettings: csvExportSettings,
+      pdfExportSettings: pdfExportSettings,
+      intervallStoreManager: intervallStoreManager,
+    ),
+  );
 }
 
 /// Creates a the same App as the main method.
@@ -93,9 +109,14 @@ Future<Widget> appBaseWithData(Widget child,  {
 ///      UserColumn('initialInternalIdentifier', 'csvTitle', 'formatPattern')
 /// ));
 /// ```
-Future<void> loadDialoge(WidgetTester tester, void Function(BuildContext context) dialogeStarter, { String dialogeStarterText = 'X' }) async {
-  await tester.pumpWidget(materialApp(Builder(builder: (context) =>
-      TextButton(onPressed: () => dialogeStarter(context), child: Text(dialogeStarterText)),),),);
+Future<void> loadDialoge(WidgetTester tester, void Function(BuildContext context) dialogeStarter, {
+  String dialogeStarterText = 'X',
+  Settings? settings,
+}) async {
+  await tester.pumpWidget(materialApp(
+    Builder(builder: (context) => TextButton(onPressed: () => dialogeStarter(context), child: Text(dialogeStarterText)),),
+    settings: settings,
+  ),);
   await tester.tap(find.text(dialogeStarterText));
   await tester.pumpAndSettle();
 }
docs/codestyle.md
@@ -7,7 +7,7 @@ The goal of this style guideline is to make dart code maintainable and to reduce
 ### File structure
 
 - One class per file (exceptions: `StatefulWidget` and `sealed` classes).
-- Widgets in the `components` directory don't require any `Provider` as an ancestor.
+- Widgets in the `components` directory don't require any data repository as an ancestor.
 - Files with widgets that fill the whole screen are suffixed with either `_screen` or `_dialoge`. The corresponding widgets end in `Screen` or `Dialoge`
 - Closely related files are grouped in a subdirectory