Commit dbfa86e

derdilla <derdilla06@gmail.com>
2023-08-27 09:44:42
clean up settings screen
1 parent 141854e
lib/components/input_dialoge.dart
@@ -0,0 +1,76 @@
+import 'package:blood_pressure_app/model/settings_store.dart';
+import 'package:flutter/material.dart';
+import 'package:flutter/services.dart';
+import 'package:flutter_gen/gen_l10n/app_localizations.dart';
+import 'package:provider/provider.dart';
+
+class InputDialoge extends StatefulWidget {
+  final String hintText;
+  final void Function(String text) onSubmit;
+  final List<TextInputFormatter>? inputFormatters;
+  final TextInputType? keyboardType;
+
+  const InputDialoge({super.key, required this.hintText, required this.onSubmit, this.inputFormatters, this.keyboardType});
+
+  @override
+  State<InputDialoge> createState() => _InputDialogeState();
+}
+
+class _InputDialogeState extends State<InputDialoge> {
+  final formKey = GlobalKey<FormState>();
+  final controller = TextEditingController();
+
+  @override
+  void dispose() {
+    // Clean up the controller when the widget is disposed.
+    controller.dispose();
+    super.dispose();
+  }
+
+  @override
+  Widget build(BuildContext context) {
+    return AlertDialog(
+      content: TextFormField(
+        key: formKey,
+        controller: controller,
+        inputFormatters: widget.inputFormatters,
+        keyboardType: widget.keyboardType,
+        decoration: InputDecoration(hintText: widget.hintText),
+      ),
+      actions: [
+        Consumer<Settings>(builder: (context, settings, child) {
+          return ElevatedButton(
+              onPressed: () {
+                widget.onSubmit(controller.text);
+              },
+              child: Text(AppLocalizations.of(context)!.btnConfirm)
+          );
+        }),
+
+      ],
+    );
+  }
+}
+
+class NumberInputDialoge extends StatelessWidget {
+  final String hintText;
+  final void Function(int text) onParsableSubmit;
+
+  const NumberInputDialoge({super.key, required this.hintText, required this.onParsableSubmit});
+
+  @override
+  Widget build(BuildContext context) {
+    return InputDialoge(
+      hintText: hintText,
+      inputFormatters: [FilteringTextInputFormatter.digitsOnly],
+      keyboardType: TextInputType.number,
+      onSubmit: (text) {
+        if (text.isEmpty || (int.tryParse(text) == null)) {
+          return;
+        }
+        int value = int.parse(text);
+        onParsableSubmit(value);
+      }
+    );
+  }
+}
lib/model/ram_only_implementations.dart
@@ -508,6 +508,19 @@ class RamSettings extends ChangeNotifier implements Settings {
     notifyListeners();
   }
 
+  Iterable<int> _horizontalGraphLines = [];
+
+  @override
+  Iterable<int> get horizontalGraphLines {
+    return _horizontalGraphLines;
+  }
+
+  @override
+  set horizontalGraphLines(Iterable<int> value) {
+    _horizontalGraphLines = value;
+    notifyListeners();
+  }
+
   @override
   void changeStepSize(TimeStep value) {
     graphStepSize = value;
lib/model/settings_store.dart
@@ -614,6 +614,16 @@ class Settings extends ChangeNotifier {
     _prefs.setStringList('exportItemsPdf', value);
     notifyListeners();
   }
+
+  Iterable<int> get horizontalGraphLines {
+    final linesStr = _prefs.getStringList('horizontalGraphLines') ?? [];
+    return linesStr.map((e) => int.parse(e));
+  }
+
+  set horizontalGraphLines(Iterable<int> value) {
+    _prefs.setStringList('horizontalGraphLines', value.map((e) => e.toString()).toList());
+    notifyListeners();
+  }
 }
 
 enum TimeStep {
lib/screens/subsettings/graph_markings.dart
@@ -0,0 +1,61 @@
+import 'package:blood_pressure_app/components/input_dialoge.dart';
+import 'package:flutter/material.dart';
+import 'package:provider/provider.dart';
+
+import '../../model/settings_store.dart';
+
+class GraphMarkingsScreen extends StatelessWidget {
+  const GraphMarkingsScreen({super.key});
+
+  @override
+  Widget build(BuildContext context) {
+    return Scaffold(
+      appBar: AppBar(
+        backgroundColor: Theme.of(context).primaryColor,
+      ),
+      body: Center(child: Consumer<Settings>(
+        builder: (context, settings, child) {
+          final lines = settings.horizontalGraphLines.toList();
+          return Container(
+            padding: const EdgeInsets.all(20.0),
+            child: ListView.builder(
+              itemCount: lines.length+1,
+              itemBuilder: (context, i) {
+                if(i == 0) {
+                  return Row(
+                  children: [
+                    Text('Horizontal Lines'), // TODO localize, implement
+                    const Spacer(),
+                    IconButton(
+                      icon: const Icon(Icons.add),
+                      onPressed: () {
+                        showDialog(
+                          context: context,
+                          builder: (context) => NumberInputDialoge(
+                              hintText: 'hintText',
+                              onParsableSubmit: (value) {
+                                lines.add(value);
+                                Navigator.of(context).pop();
+                              }
+                          ),
+                        );
+                      },
+                    )
+                  ],
+                );
+                }
+                return Row(
+                  children: [
+                    Text(lines[i-1].toString()),
+                    Spacer(),
+                    Icon(Icons.delete)
+                  ],
+                );
+              }
+            )
+          );
+        }),
+      ),
+    );
+  }
+}
lib/screens/add_measurement.dart
@@ -135,7 +135,7 @@ class _AddMeasurementPageState extends State<AddMeasurementPage> {
                           key: const Key('txtPul'),
                           initialValue: (_pulse ?? '').toString(),
                           minLines: 1,
-                          maxLines: 4,
+                          maxLines: 4, // TODO: check if this shouldn't be part of note input
                           hintText: AppLocalizations.of(context)!.pulLong,
                           basicValidation: !settings.allowMissingValues,
                           preValidation: (v) => _pulse = int.tryParse(v ?? ''),
lib/screens/settings.dart
@@ -1,10 +1,12 @@
 import 'package:blood_pressure_app/components/consistent_future_builder.dart';
+import 'package:blood_pressure_app/components/input_dialoge.dart';
 import 'package:blood_pressure_app/components/settings_widgets.dart';
 import 'package:blood_pressure_app/model/blood_pressure.dart';
 import 'package:blood_pressure_app/model/iso_lang_names.dart';
 import 'package:blood_pressure_app/model/settings_store.dart';
 import 'package:blood_pressure_app/screens/subsettings/enter_timeformat.dart';
 import 'package:blood_pressure_app/screens/subsettings/export_import_screen.dart';
+import 'package:blood_pressure_app/screens/subsettings/graph_markings.dart';
 import 'package:blood_pressure_app/screens/subsettings/version.dart';
 import 'package:blood_pressure_app/screens/subsettings/warn_about.dart';
 import 'package:flutter/material.dart';
@@ -28,22 +30,11 @@ class SettingsPage extends StatelessWidget {
         return ListView(
           children: [
             SettingsSection(title: Text(AppLocalizations.of(context)!.layout), children: [
-              SwitchSettingsTile(
-                  key: const Key('allowManualTimeInput'),
-                  initialValue: settings.allowManualTimeInput,
-                  onToggle: (value) {
-                    settings.allowManualTimeInput = value;
-                  },
-                  leading: const Icon(Icons.details),
-                  title: Text(AppLocalizations.of(context)!.allowManualTimeInput)),
               SettingsTile(
                 key: const Key('EnterTimeFormatScreen'),
                 title: Text(AppLocalizations.of(context)!.enterTimeFormatScreen),
                 leading: const Icon(Icons.schedule),
-                trailing: Icon(
-                  Icons.arrow_forward_ios,
-                  color: Theme.of(context).highlightColor,
-                ),
+                trailing: const Icon(Icons.arrow_forward_ios),
                 description: Text(settings.dateFormatString),
                 onPressed: (context) {
                   Navigator.push(
@@ -80,6 +71,11 @@ class SettingsPage extends StatelessWidget {
                   }
                 },
               ),
+              ColorSelectionSettingsTile(
+                key: const Key('accentColor'),
+                onMainColorChanged: (color) => settings.accentColor = createMaterialColor((color ?? Colors.teal).value),
+                initialColor: settings.accentColor,
+                title: Text(AppLocalizations.of(context)!.accentColor)),
               DropDownSettingsTile<Locale?>(
                 key: const Key('language'),
                 leading: const Icon(Icons.language),
@@ -143,52 +139,55 @@ class SettingsPage extends StatelessWidget {
                 stepSize: 1,
               ),
               ColorSelectionSettingsTile(
-                  key: const Key('accentColor'),
-                  onMainColorChanged: (color) =>
-                      settings.accentColor = createMaterialColor((color ?? Colors.teal).value),
-                  initialColor: settings.accentColor,
-                  title: Text(AppLocalizations.of(context)!.accentColor)),
-              ColorSelectionSettingsTile(
-                  key: const Key('sysColor'),
-                  onMainColorChanged: (color) => settings.sysColor = createMaterialColor((color ?? Colors.green).value),
-                  initialColor: settings.sysColor,
+                key: const Key('sysColor'),
+                onMainColorChanged: (color) => settings.sysColor = createMaterialColor((color ?? Colors.green).value),
+                initialColor: settings.sysColor,
                   title: Text(AppLocalizations.of(context)!.sysColor)),
               ColorSelectionSettingsTile(
-                  key: const Key('diaColor'),
-                  onMainColorChanged: (color) => settings.diaColor = createMaterialColor((color ?? Colors.teal).value),
-                  initialColor: settings.diaColor,
-                  title: Text(AppLocalizations.of(context)!.diaColor)),
+                key: const Key('diaColor'),
+                onMainColorChanged: (color) => settings.diaColor = createMaterialColor((color ?? Colors.teal).value),
+                initialColor: settings.diaColor,
+                title: Text(AppLocalizations.of(context)!.diaColor)),
               ColorSelectionSettingsTile(
-                  key: const Key('pulColor'),
-                  onMainColorChanged: (color) => settings.pulColor = createMaterialColor((color ?? Colors.red).value),
-                  initialColor: settings.pulColor,
-                  title: Text(AppLocalizations.of(context)!.pulColor)),
+                key: const Key('pulColor'),
+                onMainColorChanged: (color) => settings.pulColor = createMaterialColor((color ?? Colors.red).value),
+                initialColor: settings.pulColor,
+                title: Text(AppLocalizations.of(context)!.pulColor)),
             ]),
+
             SettingsSection(title: Text(AppLocalizations.of(context)!.behavior), children: [
               SwitchSettingsTile(
-                  key: const Key('validateInputs'),
-                  initialValue: settings.validateInputs,
-                  title: Text(AppLocalizations.of(context)!.validateInputs),
-                  leading: const Icon(Icons.edit),
-                  onToggle: (value) {
-                    settings.validateInputs = value;
-                  }),
+                key: const Key('allowManualTimeInput'),
+                initialValue: settings.allowManualTimeInput,
+                onToggle: (value) {
+                  settings.allowManualTimeInput = value;
+                },
+                leading: const Icon(Icons.details),
+                title: Text(AppLocalizations.of(context)!.allowManualTimeInput)),
+              SwitchSettingsTile(
+                key: const Key('validateInputs'),
+                initialValue: settings.validateInputs,
+                title: Text(AppLocalizations.of(context)!.validateInputs),
+                leading: const Icon(Icons.edit),
+                onToggle: (value) {
+                  settings.validateInputs = value;
+                }),
               SwitchSettingsTile(
-                  key: const Key('allowMissingValues'),
-                  initialValue: settings.allowMissingValues,
-                  title: Text(AppLocalizations.of(context)!.allowMissingValues),
-                  leading: const Icon(Icons.report_off_outlined),
-                  onToggle: (value) {
-                    settings.allowMissingValues = value;
-                  }),
+                key: const Key('allowMissingValues'),
+                initialValue: settings.allowMissingValues,
+                title: Text(AppLocalizations.of(context)!.allowMissingValues),
+                leading: const Icon(Icons.report_off_outlined),
+                onToggle: (value) {
+                  settings.allowMissingValues = value;
+                }),
               SwitchSettingsTile(
-                  key: const Key('confirmDeletion'),
-                  initialValue: settings.confirmDeletion,
-                  title: Text(AppLocalizations.of(context)!.confirmDeletion),
-                  leading: const Icon(Icons.check),
-                  onToggle: (value) {
-                    settings.confirmDeletion = value;
-                  }),
+                key: const Key('confirmDeletion'),
+                initialValue: settings.confirmDeletion,
+                title: Text(AppLocalizations.of(context)!.confirmDeletion),
+                leading: const Icon(Icons.check),
+                onToggle: (value) {
+                  settings.confirmDeletion = value;
+                }),
               InputSettingsTile(
                 key: const Key('sysWarn'),
                 title: Text(AppLocalizations.of(context)!.sysWarn),
@@ -228,7 +227,19 @@ class SettingsPage extends StatelessWidget {
                 onPressed: (context) {
                   showDialog(
                     context: context,
-                    builder: (context) => const DetermineAgeValues(),
+                    builder: (context) => NumberInputDialoge(
+                      hintText: AppLocalizations.of(context)!.age,
+                      onParsableSubmit: (age) {
+                        settings.sysWarn = BloodPressureWarnValues.getUpperSysWarnValue(age);
+                        settings.diaWarn = BloodPressureWarnValues.getUpperDiaWarnValue(age);
+                        Navigator.of(context).pop();
+                        Navigator.of(context).pop();
+                        Navigator.push(
+                          context,
+                          MaterialPageRoute(builder: (context) => const SettingsPage()),
+                        );
+                      },
+                    )
                   );
                 },
               ),
@@ -237,6 +248,7 @@ class SettingsPage extends StatelessWidget {
                 title: Text(AppLocalizations.of(context)!.aboutWarnValuesScreen),
                 description: Text(AppLocalizations.of(context)!.aboutWarnValuesScreenDesc),
                 leading: const Icon(Icons.info_outline),
+                trailing: const Icon(Icons.arrow_forward_ios),
                 onPressed: (context) {
                   Navigator.push(
                     context,
@@ -244,6 +256,19 @@ class SettingsPage extends StatelessWidget {
                   );
                 }
               ),
+              SettingsTile(
+                key: const Key('GraphMarkingsScreen'),
+                title: Text(AppLocalizations.of(context)!.text),
+                description: Text(AppLocalizations.of(context)!.text), // TODO desc u title
+                leading: const Icon(Icons.legend_toggle_outlined),
+                trailing: const Icon(Icons.arrow_forward_ios),
+                onPressed: (context) {
+                  Navigator.push(
+                    context,
+                    MaterialPageRoute(builder: (context) => const GraphMarkingsScreen()),
+                  );
+                }
+              ),
               SwitchSettingsTile(
                 title: Text(AppLocalizations.of(context)!.drawRegressionLines),
                 leading: const Icon(Icons.trending_down_outlined),
@@ -315,10 +340,7 @@ class SettingsPage extends StatelessWidget {
                 key: const Key('licenses'),
                 title: Text(AppLocalizations.of(context)!.licenses),
                 leading: const Icon(Icons.policy_outlined),
-                trailing: Icon(
-                  Icons.arrow_forward_ios,
-                  color: Theme.of(context).highlightColor,
-                ),
+                trailing: const Icon(Icons.arrow_forward_ios),
                 onPressed: (context) {
                   showLicensePage(context: context);
                 },
@@ -330,56 +352,3 @@ class SettingsPage extends StatelessWidget {
     );
   }
 }
-
-class DetermineAgeValues extends StatefulWidget {
-  const DetermineAgeValues({super.key});
-
-  @override
-  State<DetermineAgeValues> createState() => _DetermineAgeValuesState();
-}
-
-class _DetermineAgeValuesState extends State<DetermineAgeValues> {
-  final formKey = GlobalKey<FormState>();
-  final controller = TextEditingController();
-
-  @override
-  void dispose() {
-    // Clean up the controller when the widget is disposed.
-    controller.dispose();
-    super.dispose();
-  }
-
-  @override
-  Widget build(BuildContext context) {
-    return AlertDialog(
-      content: TextFormField(
-        key: formKey,
-        controller: controller,
-        inputFormatters: [FilteringTextInputFormatter.digitsOnly],
-        decoration: InputDecoration(hintText: AppLocalizations.of(context)!.age),
-      ),
-      actions: [
-        Consumer<Settings>(builder: (context, settings, child) {
-          return ElevatedButton(
-              onPressed: () {
-                if (controller.text.isEmpty || (int.tryParse(controller.text) == null)) {
-                  return;
-                }
-                int age = int.parse(controller.text);
-                settings.sysWarn = BloodPressureWarnValues.getUpperSysWarnValue(age);
-                settings.diaWarn = BloodPressureWarnValues.getUpperDiaWarnValue(age);
-                Navigator.of(context).pop();
-                Navigator.of(context).pop();
-                Navigator.push(
-                  context,
-                  MaterialPageRoute(builder: (context) => const SettingsPage()),
-                );
-              },
-              child: Text(AppLocalizations.of(context)!.btnConfirm)
-          );
-        }),
-
-      ],
-    );
-  }
-}