Commit c9a0f07

derdilla <82763757+NobodyForNothing@users.noreply.github.com>
2024-06-23 17:56:30
fix add entry dialoge
Signed-off-by: derdilla <82763757+NobodyForNothing@users.noreply.github.com>
1 parent af0df43
Changed files (2)
app
lib
components
test
app/lib/components/dialoges/add_measurement_dialoge.dart
@@ -53,7 +53,11 @@ class _AddEntryDialogeState extends State<AddEntryDialoge> {
   final diaFocusNode = FocusNode();
   final pulFocusNode = FocusNode();
   final noteFocusNode = FocusNode();
+
   late final TextEditingController sysController;
+  late final TextEditingController diaController;
+  late final TextEditingController pulController;
+  late final TextEditingController noteController;
 
   /// Currently selected time.
   late DateTime time;
@@ -98,15 +102,12 @@ class _AddEntryDialogeState extends State<AddEntryDialoge> {
   @override
   void initState() {
     super.initState();
-    time = widget.initialRecord?.time ?? DateTime.now();
-    final int? colorVal = widget.initialRecord?.color;
-    color = colorVal == null ? null : Color(colorVal);
-    // TODO: stop duplicating code like this
-    final sysValue = switch(widget.settings.preferredPressureUnit) {
-      PressureUnit.mmHg => widget.initialRecord?.sys?.mmHg,
-      PressureUnit.kPa => widget.initialRecord?.sys?.kPa.round(),
-    };
-    sysController = TextEditingController(text: sysValue?.toString() ?? '');
+    sysController = TextEditingController();
+    diaController = TextEditingController();
+    pulController = TextEditingController();
+    noteController = TextEditingController();
+    _loadFields(widget.initialRecord);
+
     if (widget.initialRecord != null) {
       _measurementFormActive = true;
     }
@@ -119,6 +120,10 @@ class _AddEntryDialogeState extends State<AddEntryDialoge> {
   @override
   void dispose() {
     sysController.dispose();
+    diaController.dispose();
+    pulController.dispose();
+    noteController.dispose();
+
     sysFocusNode.dispose();
     diaFocusNode.dispose();
     pulFocusNode.dispose();
@@ -127,6 +132,26 @@ class _AddEntryDialogeState extends State<AddEntryDialoge> {
     super.dispose();
   }
 
+  /// Sets fields to values in a [record].
+  void _loadFields(FullEntry? entry) {
+    _measurementFormActive = true;
+    time = entry?.time ?? DateTime.now();
+    final int? colorValue = entry?.color;
+    final sysValue = switch(widget.settings.preferredPressureUnit) {
+      PressureUnit.mmHg => entry?.sys?.mmHg,
+      PressureUnit.kPa => entry?.sys?.kPa.round(),
+    };
+    final diaValue = switch(widget.settings.preferredPressureUnit) {
+      PressureUnit.mmHg => entry?.dia?.mmHg,
+      PressureUnit.kPa => entry?.dia?.kPa.round(),
+    };
+    if (colorValue != null) color = Color(colorValue);
+    if (entry?.sys != null) sysController.text = sysValue.toString();
+    if (entry?.dia != null) diaController.text = diaValue.toString();
+    if (entry?.pul != null) pulController.text = entry!.pul!.toString();
+    if (entry?.note != null) noteController.text = entry!.note!;
+  }
+
   bool _onKey(KeyEvent event) {
     if (event is! KeyDownEvent) return false;
     final isBackspace = event.logicalKey.keyId == 0x00100000008;
@@ -172,51 +197,53 @@ class _AddEntryDialogeState extends State<AddEntryDialoge> {
 
   /// Build a input for values in the measurement form (sys, dia, pul).
   Widget _buildValueInput(AppLocalizations localizations, {
-    int? initialValue,
     String? labelText,
     void Function(String?)? onSaved,
     FocusNode? focusNode,
     TextEditingController? controller,
     String? Function(String?)? validator,
-  }) {
-    assert(initialValue == null || controller == null);
-    return Expanded(
-      child: TextFormField(
-        initialValue: initialValue?.toString(),
-        decoration: InputDecoration(
-          labelText: labelText,
-        ),
-        keyboardType: TextInputType.number,
-        focusNode: focusNode,
-        onSaved: onSaved,
-        controller: controller,
-        inputFormatters: [FilteringTextInputFormatter.digitsOnly],
-        onChanged: (String value) {
-          if (value.isNotEmpty) _measurementFormActive = true;
-          if (value.isNotEmpty
-              && (int.tryParse(value) ?? -1) > 40) {
-            FocusScope.of(context).nextFocus();
-          }
-        },
-        validator: (String? value) {
-          if (!widget.settings.allowMissingValues
-              && (value == null
-                  || value.isEmpty
-                  || int.tryParse(value) == null)) {
-            return localizations.errNaN;
-          } else if (widget.settings.validateInputs
-              && (int.tryParse(value ?? '') ?? -1) <= 30) {
-            return localizations.errLt30;
-          } else if (widget.settings.validateInputs
-              && (int.tryParse(value ?? '') ?? 0) >= 400) {
-            // https://pubmed.ncbi.nlm.nih.gov/7741618/
-            return localizations.errUnrealistic;
-          }
-          return validator?.call(value);
-        },
+  }) => Expanded(
+    child: TextFormField(
+      decoration: InputDecoration(
+        labelText: labelText,
       ),
-    );
-  }
+      keyboardType: TextInputType.number,
+      focusNode: focusNode,
+      onSaved: onSaved,
+      controller: controller,
+      inputFormatters: [FilteringTextInputFormatter.digitsOnly],
+      onChanged: (String value) {
+        if (value.isNotEmpty) _measurementFormActive = true;
+        if (value.isNotEmpty
+            && (int.tryParse(value) ?? -1) > 40) {
+          FocusScope.of(context).nextFocus();
+        }
+      },
+      validator: (String? value) {
+        if (sysController.text.isEmpty
+          && diaController.text.isEmpty
+          && pulController.text.isEmpty) {
+          // Make note only entries work
+          return null;
+        }
+
+        if (!widget.settings.allowMissingValues
+            && (value == null
+                || value.isEmpty
+                || int.tryParse(value) == null)) {
+          return localizations.errNaN;
+        } else if (widget.settings.validateInputs
+            && (int.tryParse(value ?? '') ?? -1) <= 30) {
+          return localizations.errLt30;
+        } else if (widget.settings.validateInputs
+            && (int.tryParse(value ?? '') ?? 0) >= 400) {
+          // https://pubmed.ncbi.nlm.nih.gov/7741618/
+          return localizations.errUnrealistic;
+        }
+        return validator?.call(value);
+      },
+    ),
+  );
 
   /// Build the border all fields have.
   RoundedRectangleBorder _buildShapeBorder([Color? color]) =>
@@ -236,8 +263,7 @@ class _AddEntryDialogeState extends State<AddEntryDialoge> {
         final List<MedicineIntake> intakes = [];
         if (_measurementFormActive && (recordFormKey.currentState?.validate() ?? false)) {
           recordFormKey.currentState?.save();
-          if (systolic != null || diastolic != null || pulse != null
-              || (notes?.isNotEmpty ?? false) || color != null) {
+          if (systolic != null || diastolic != null || pulse != null) {
             final pressureUnit = widget.settings.preferredPressureUnit;
             record = BloodPressureRecord(
               time: time,
@@ -245,6 +271,8 @@ class _AddEntryDialogeState extends State<AddEntryDialoge> {
               dia: diastolic == null ? null : pressureUnit.wrap(diastolic!),
               pul: pulse,
             );
+          }
+          if ((notes?.isNotEmpty ?? false) || color != null) {
             note = Note(
               time: time,
               note: (notes?.isEmpty ?? true) ? null: notes,
@@ -266,9 +294,12 @@ class _AddEntryDialogeState extends State<AddEntryDialoge> {
           }
         }
 
-        if ((record != null && intakes.isNotEmpty)
-            || (record == null && !_measurementFormActive && intakes.isNotEmpty)
-            || (record != null && intakes.isEmpty && selectedMed == null)) {
+        if (
+          (record != null && intakes.isNotEmpty)
+          || (record == null && note != null)
+          || (record == null && !_measurementFormActive && intakes.isNotEmpty)
+          || (record != null && intakes.isEmpty && selectedMed == null)
+        ) {
           record ??= BloodPressureRecord(time: time);
           note ??= Note(time: time);
           Navigator.pop(context, (record, note, intakes));
@@ -300,11 +331,7 @@ class _AddEntryDialogeState extends State<AddEntryDialoge> {
                       const SizedBox(width: 16,),
                       _buildValueInput(localizations,
                         labelText: localizations.diaLong,
-                        // TODO: stop duplicating code like this
-                        initialValue: switch(widget.settings.preferredPressureUnit) {
-                          PressureUnit.mmHg => widget.initialRecord?.dia?.mmHg,
-                          PressureUnit.kPa => widget.initialRecord?.dia?.kPa.round(),
-                        },
+                        controller: diaController,
                         onSaved: (value) =>
                             setState(() => diastolic = int.tryParse(value ?? '')),
                         focusNode: diaFocusNode,
@@ -321,7 +348,7 @@ class _AddEntryDialogeState extends State<AddEntryDialoge> {
                       const SizedBox(width: 16,),
                       _buildValueInput(localizations,
                         labelText: localizations.pulLong,
-                        initialValue: widget.initialRecord?.pul,
+                        controller: pulController,
                         focusNode: pulFocusNode,
                         onSaved: (value) =>
                             setState(() => pulse = int.tryParse(value ?? '')),
@@ -331,7 +358,7 @@ class _AddEntryDialogeState extends State<AddEntryDialoge> {
                   Padding(
                     padding: const EdgeInsets.symmetric(vertical: 16),
                     child: TextFormField(
-                      initialValue: widget.initialRecord?.note,
+                      controller: noteController,
                       focusNode: noteFocusNode,
                       decoration: InputDecoration(
                         labelText: localizations.addNote,
app/test/ui/components/add_measurement_dialoge_test.dart
@@ -245,10 +245,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(
-        allowMissingValues: true,
-        validateInputs: false,
-      ), medRepo(),),);
+      => result = await showAddEntryDialoge(context, Settings(), medRepo(),),);
       expect(find.byType(DropdownButton<Medicine?>), findsNothing, reason: 'No medication in settings.');
 
       final localizations = await AppLocalizations.delegate.load(const Locale('en'));