import 'package:diameter/components/detail.dart'; import 'package:diameter/components/forms/boolean_form_field.dart'; import 'package:diameter/components/forms/number_form_field.dart'; import 'package:diameter/utils/dialog_utils.dart'; import 'package:diameter/models/settings.dart'; import 'package:diameter/navigation.dart'; import 'package:flutter/material.dart'; import 'package:diameter/components/forms/form_wrapper.dart'; import 'package:diameter/models/accuracy.dart'; class AccuracyDetailScreen extends StatefulWidget { static const String routeName = '/accuracy'; final int id; const AccuracyDetailScreen({Key? key, this.id = 0}) : super(key: key); @override _AccuracyDetailScreenState createState() => _AccuracyDetailScreenState(); } class _AccuracyDetailScreenState extends State { Accuracy? _accuracy; bool _isNew = true; bool _isSaving = false; final GlobalKey _accuracyForm = GlobalKey(); final ScrollController _scrollController = ScrollController(); final _valueController = TextEditingController(text: ''); final _notesController = TextEditingController(text: ''); final _confidenceRatingController = TextEditingController(text: Accuracy.getAll().length.toString()); bool _forCarbsRatio = true; bool _forPortionSize = true; @override void initState() { super.initState(); reload(); if (_accuracy != null) { _valueController.text = _accuracy!.value; _forCarbsRatio = _accuracy!.forCarbsRatio; _forPortionSize = _accuracy!.forPortionSize; _confidenceRatingController.text = (_accuracy!.confidenceRating ?? Accuracy.getAll().length).toString(); _notesController.text = _accuracy!.notes ?? ''; } } @override void dispose() { _scrollController.dispose(); _valueController.dispose(); _notesController.dispose(); _confidenceRatingController.dispose(); super.dispose(); } void reload({String? message}) { if (widget.id != 0) { setState(() { _accuracy = Accuracy.get(widget.id); }); } _isNew = _accuracy == null; setState(() { if (message != null) { var snackBar = SnackBar( content: Text(message), duration: const Duration(seconds: 2), ); ScaffoldMessenger.of(context) ..removeCurrentSnackBar() ..showSnackBar(snackBar); } }); } void handleSaveAction() async { setState(() { _isSaving = true; }); if (_accuracyForm.currentState!.validate()) { Accuracy accuracy = Accuracy( id: widget.id, value: _valueController.text, forCarbsRatio: _forCarbsRatio, forPortionSize: _forPortionSize, notes: _notesController.text, ); Accuracy.put(accuracy); Accuracy.reorder( accuracy, int.tryParse(_confidenceRatingController.text)); Navigator.pop( context, ['${_isNew ? 'New' : ''} Accuracy saved', accuracy]); } setState(() { _isSaving = false; }); } void handleCancelAction() { if (Settings.get().showConfirmationDialogOnCancel && (_isNew && (!_forCarbsRatio || !_forPortionSize || _valueController.text != '' || int.tryParse(_confidenceRatingController.text) != Accuracy.getAll().length || _notesController.text != '')) || (!_isNew && (_forCarbsRatio != _accuracy!.forCarbsRatio || _forPortionSize != _accuracy!.forPortionSize || _accuracy!.value != _valueController.text || int.tryParse(_confidenceRatingController.text) != _accuracy!.confidenceRating || (_accuracy!.notes ?? '') != _notesController.text))) { DialogUtils.showCancelConfirmationDialog( context: context, isNew: _isNew, onSave: handleSaveAction, ); } else { Navigator.pop(context); } } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text(_isNew ? 'New Accuracy' : _accuracy!.value), ), drawer: const Navigation(currentLocation: AccuracyDetailScreen.routeName), body: Scrollbar( controller: _scrollController, child: SingleChildScrollView( controller: _scrollController, child: Column( crossAxisAlignment: CrossAxisAlignment.stretch, children: [ FormWrapper( formState: _accuracyForm, fields: [ TextFormField( controller: _valueController, decoration: const InputDecoration( labelText: 'Name', ), validator: (value) { if (value!.trim().isEmpty) { return 'Empty name'; } return null; }, ), BooleanFormField( icon: const Icon(Icons.square_foot), value: _forPortionSize, label: 'for portion size', onChanged: (value) { setState(() { _forPortionSize = value; }); }, ), BooleanFormField( icon: const Icon(Icons.pie_chart), value: _forCarbsRatio, label: 'for carbs ratio', onChanged: (value) { setState(() { _forCarbsRatio = value; }); }, ), NumberFormField( controller: _confidenceRatingController, label: 'Confidence Rating', onChanged: (value) { setState(() { _confidenceRatingController.text = (value ?? 0).toInt().toString(); }); }, ), TextFormField( controller: _notesController, keyboardType: TextInputType.multiline, decoration: const InputDecoration( labelText: 'Notes', ), minLines: 2, maxLines: 5, ), ], ), ], ), ), ), bottomNavigationBar: DetailBottomRow( onCancel: handleCancelAction, onAction: _isSaving ? null : handleSaveAction, ), ); } }