fix objectbox meta model, update todo list, add date picker to log entry
This commit is contained in:
parent
f7d727e070
commit
ab0839bff3
36
TODO
36
TODO
@ -1,7 +1,37 @@
|
|||||||
|
General/Framework:
|
||||||
Todo:
|
|
||||||
☐ add active/deleted flag to all data models
|
☐ add active/deleted flag to all data models
|
||||||
☐ account for deleted/disabled elements in dropdowns
|
☐ account for deleted/disabled elements in dropdowns
|
||||||
☐ place dropdown items right below their input
|
☐ place dropdown items right below their input
|
||||||
✔ use local database instead of back4app @done(21-11-07 18:53)
|
✔ use local database instead of back4app @done(21-11-07 18:53)
|
||||||
|
☐ find a general way to deal with duration fields
|
||||||
|
☐ add explanations to each section
|
||||||
|
☐ use ids instead of passing entities around where possible
|
||||||
|
|
||||||
|
Accuracies:
|
||||||
|
☐ implement reordering
|
||||||
|
|
||||||
|
Basal/Bolus:
|
||||||
|
☐ create distinct visual mode for picking the active profile
|
||||||
|
|
||||||
|
Meal:
|
||||||
|
none
|
||||||
|
|
||||||
|
Log Overview:
|
||||||
|
☐ add active events view
|
||||||
|
☐ adjust/debug active events view
|
||||||
|
☐ display more information
|
||||||
|
☐ apply target color settings to glucose
|
||||||
|
☐ total bolus and carbs per entry
|
||||||
|
|
||||||
|
Log Entry:
|
||||||
|
☐ add tab for bolus overview
|
||||||
|
☐ calculate bolus suggestions according to active profile
|
||||||
|
☐ add time picker for entry date/time
|
||||||
|
|
||||||
|
Event Types:
|
||||||
|
☐ add option to change bolus/basal profile for event duration
|
||||||
|
|
||||||
|
Settings:
|
||||||
|
☐ add objectbox class and use instead of shared preferences
|
||||||
|
☐ add fields for date and time formats
|
||||||
|
☐ add fields for glucose target
|
@ -1,43 +0,0 @@
|
|||||||
import 'package:flutter/material.dart';
|
|
||||||
|
|
||||||
abstract class DataTableContent {
|
|
||||||
bool selected = false;
|
|
||||||
List<DataCell> asDataTableCells(List<Widget> actions) => [];
|
|
||||||
static List<DataColumn> asDataTableColumns() => [];
|
|
||||||
}
|
|
||||||
|
|
||||||
class DataTableSourceBuilder extends DataTableSource {
|
|
||||||
final List<DataTableContent> data;
|
|
||||||
final BuildContext context;
|
|
||||||
|
|
||||||
DataTableSourceBuilder(this.context, this.data);
|
|
||||||
|
|
||||||
@override
|
|
||||||
bool get isRowCountApproximate => false;
|
|
||||||
|
|
||||||
@override
|
|
||||||
int get rowCount => data.length;
|
|
||||||
|
|
||||||
@override
|
|
||||||
int get selectedRowCount {
|
|
||||||
int count = 0;
|
|
||||||
for (var element in data) {
|
|
||||||
if (element.selected) {
|
|
||||||
count++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return count;
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
DataRow? getRow(int index) {
|
|
||||||
assert(index >= 0);
|
|
||||||
if (index >= data.length) return null;
|
|
||||||
final rowData = data[index];
|
|
||||||
return DataRow.byIndex(
|
|
||||||
index: index,
|
|
||||||
selected: rowData.selected,
|
|
||||||
cells: rowData.asDataTableCells([]),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,19 +1,18 @@
|
|||||||
import 'package:diameter/components/progress_indicator.dart';
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
class StyledForm extends StatefulWidget {
|
class FormWrapper extends StatefulWidget {
|
||||||
final List<Widget>? fields;
|
final List<Widget>? fields;
|
||||||
final List<Widget>? buttons;
|
final List<Widget>? buttons;
|
||||||
final GlobalKey<FormState>? formState;
|
final GlobalKey<FormState>? formState;
|
||||||
|
|
||||||
const StyledForm({Key? key, this.formState, this.fields, this.buttons})
|
const FormWrapper({Key? key, this.formState, this.fields, this.buttons})
|
||||||
: super(key: key);
|
: super(key: key);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
_StyledFormState createState() => _StyledFormState();
|
_FormWrapperState createState() => _FormWrapperState();
|
||||||
}
|
}
|
||||||
|
|
||||||
class _StyledFormState extends State<StyledForm> {
|
class _FormWrapperState extends State<FormWrapper> {
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Padding(
|
return Padding(
|
||||||
@ -45,13 +44,13 @@ class _StyledFormState extends State<StyledForm> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class StyledBooleanFormField extends StatefulWidget {
|
class BooleanFormField extends StatefulWidget {
|
||||||
final bool value;
|
final bool value;
|
||||||
final String label;
|
final String label;
|
||||||
final void Function(bool) onChanged;
|
final void Function(bool) onChanged;
|
||||||
final bool? enabled;
|
final bool? enabled;
|
||||||
|
|
||||||
const StyledBooleanFormField(
|
const BooleanFormField(
|
||||||
{Key? key,
|
{Key? key,
|
||||||
required this.value,
|
required this.value,
|
||||||
required this.label,
|
required this.label,
|
||||||
@ -60,10 +59,10 @@ class StyledBooleanFormField extends StatefulWidget {
|
|||||||
: super(key: key);
|
: super(key: key);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
_StyledBooleanFormFieldState createState() => _StyledBooleanFormFieldState();
|
_BooleanFormFieldState createState() => _BooleanFormFieldState();
|
||||||
}
|
}
|
||||||
|
|
||||||
class _StyledBooleanFormFieldState extends State<StyledBooleanFormField> {
|
class _BooleanFormFieldState extends State<BooleanFormField> {
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return FormField<bool>(builder: (context) {
|
return FormField<bool>(builder: (context) {
|
||||||
@ -80,13 +79,58 @@ class _StyledBooleanFormFieldState extends State<StyledBooleanFormField> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class StyledTimeOfDayFormField extends StatefulWidget {
|
class DateTimeFormField extends StatefulWidget {
|
||||||
|
final DateTime date;
|
||||||
|
final DateTime? minDate;
|
||||||
|
final DateTime? maxDate;
|
||||||
|
final TextEditingController controller;
|
||||||
|
final String label;
|
||||||
|
final void Function(DateTime?) onChanged;
|
||||||
|
|
||||||
|
const DateTimeFormField(
|
||||||
|
{Key? key,
|
||||||
|
required this.date,
|
||||||
|
this.minDate,
|
||||||
|
this.maxDate,
|
||||||
|
required this.controller,
|
||||||
|
required this.label,
|
||||||
|
required this.onChanged})
|
||||||
|
: super(key: key);
|
||||||
|
|
||||||
|
@override
|
||||||
|
_DateTimeFormFieldState createState() =>
|
||||||
|
_DateTimeFormFieldState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _DateTimeFormFieldState extends State<DateTimeFormField> {
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return TextFormField(
|
||||||
|
readOnly: true,
|
||||||
|
controller: widget.controller,
|
||||||
|
decoration: InputDecoration(
|
||||||
|
labelText: widget.label,
|
||||||
|
),
|
||||||
|
onTap: () async {
|
||||||
|
final newTime = await showDatePicker(
|
||||||
|
context: context,
|
||||||
|
initialDate: widget.date,
|
||||||
|
firstDate: widget.minDate ?? DateTime(2000,1,1),
|
||||||
|
lastDate: widget.maxDate ?? DateTime.now(),
|
||||||
|
);
|
||||||
|
widget.onChanged(newTime);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class TimeOfDayFormField extends StatefulWidget {
|
||||||
final TimeOfDay time;
|
final TimeOfDay time;
|
||||||
final TextEditingController controller;
|
final TextEditingController controller;
|
||||||
final String label;
|
final String label;
|
||||||
final void Function(TimeOfDay?) onChanged;
|
final void Function(TimeOfDay?) onChanged;
|
||||||
|
|
||||||
const StyledTimeOfDayFormField(
|
const TimeOfDayFormField(
|
||||||
{Key? key,
|
{Key? key,
|
||||||
required this.time,
|
required this.time,
|
||||||
required this.controller,
|
required this.controller,
|
||||||
@ -95,11 +139,11 @@ class StyledTimeOfDayFormField extends StatefulWidget {
|
|||||||
: super(key: key);
|
: super(key: key);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
_StyledTimeOfDayFormFieldState createState() =>
|
_TimeOfDayFormFieldState createState() =>
|
||||||
_StyledTimeOfDayFormFieldState();
|
_TimeOfDayFormFieldState();
|
||||||
}
|
}
|
||||||
|
|
||||||
class _StyledTimeOfDayFormFieldState extends State<StyledTimeOfDayFormField> {
|
class _TimeOfDayFormFieldState extends State<TimeOfDayFormField> {
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return TextFormField(
|
return TextFormField(
|
||||||
@ -119,14 +163,14 @@ class _StyledTimeOfDayFormFieldState extends State<StyledTimeOfDayFormField> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class StyledDropdownButton<T> extends StatefulWidget {
|
class LabeledDropdownButton<T> extends StatefulWidget {
|
||||||
final String label;
|
final String label;
|
||||||
final T? selectedItem;
|
final T? selectedItem;
|
||||||
final List<T> items;
|
final List<T> items;
|
||||||
final Widget Function(T item) renderItem;
|
final Widget Function(T item) renderItem;
|
||||||
final void Function(T? value) onChanged;
|
final void Function(T? value) onChanged;
|
||||||
|
|
||||||
const StyledDropdownButton(
|
const LabeledDropdownButton(
|
||||||
{Key? key,
|
{Key? key,
|
||||||
this.selectedItem,
|
this.selectedItem,
|
||||||
required this.label,
|
required this.label,
|
||||||
@ -136,10 +180,10 @@ class StyledDropdownButton<T> extends StatefulWidget {
|
|||||||
: super(key: key);
|
: super(key: key);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
_StyledDropdownButtonState<T> createState() => _StyledDropdownButtonState();
|
_LabeledDropdownButtonState<T> createState() => _LabeledDropdownButtonState();
|
||||||
}
|
}
|
||||||
|
|
||||||
class _StyledDropdownButtonState<T> extends State<StyledDropdownButton<T>> {
|
class _LabeledDropdownButtonState<T> extends State<LabeledDropdownButton<T>> {
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return DropdownButtonFormField<T>(
|
return DropdownButtonFormField<T>(
|
||||||
@ -158,65 +202,3 @@ class _StyledDropdownButtonState<T> extends State<StyledDropdownButton<T>> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class StyledFutureDropdownButton<T> extends StatefulWidget {
|
|
||||||
final String label;
|
|
||||||
final String? selectedItem;
|
|
||||||
final Future<List<T>> items;
|
|
||||||
final String? Function(T item) getItemValue;
|
|
||||||
final Widget Function(T item) renderItem;
|
|
||||||
final void Function(String? value) onChanged;
|
|
||||||
|
|
||||||
const StyledFutureDropdownButton(
|
|
||||||
{Key? key,
|
|
||||||
this.selectedItem,
|
|
||||||
required this.label,
|
|
||||||
required this.items,
|
|
||||||
required this.getItemValue,
|
|
||||||
required this.renderItem,
|
|
||||||
required this.onChanged})
|
|
||||||
: super(key: key);
|
|
||||||
|
|
||||||
@override
|
|
||||||
_StyledFutureDropdownButtonState<T> createState() =>
|
|
||||||
_StyledFutureDropdownButtonState();
|
|
||||||
}
|
|
||||||
|
|
||||||
class _StyledFutureDropdownButtonState<T>
|
|
||||||
extends State<StyledFutureDropdownButton<T>> {
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return FutureBuilder<List<T>>(
|
|
||||||
future: widget.items,
|
|
||||||
builder: (context, snapshot) {
|
|
||||||
return ViewWithProgressIndicator(
|
|
||||||
snapshot: snapshot,
|
|
||||||
padding: const EdgeInsets.all(10.0),
|
|
||||||
progressIndicatorSize: 44,
|
|
||||||
child: snapshot.data == null || snapshot.data!.isEmpty
|
|
||||||
? Row(
|
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
|
||||||
children: const [
|
|
||||||
Padding(
|
|
||||||
padding: EdgeInsets.all(10.0),
|
|
||||||
child: Text('No Meal Sources'),
|
|
||||||
)
|
|
||||||
],
|
|
||||||
)
|
|
||||||
: DropdownButtonFormField<String>(
|
|
||||||
decoration: InputDecoration(
|
|
||||||
labelText: widget.label,
|
|
||||||
),
|
|
||||||
value: widget.selectedItem,
|
|
||||||
onChanged: widget.onChanged,
|
|
||||||
items: snapshot.data!
|
|
||||||
.map((item) => DropdownMenuItem<String>(
|
|
||||||
value: widget.getItemValue(item),
|
|
||||||
child: widget.renderItem(item),
|
|
||||||
))
|
|
||||||
.toList(),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -1,65 +0,0 @@
|
|||||||
import 'package:flutter/material.dart';
|
|
||||||
// import 'package:flutter/widgets.dart';
|
|
||||||
|
|
||||||
class ViewWithProgressIndicator extends StatefulWidget {
|
|
||||||
final AsyncSnapshot snapshot;
|
|
||||||
final Widget child;
|
|
||||||
final double progressIndicatorSize;
|
|
||||||
final EdgeInsets padding;
|
|
||||||
|
|
||||||
const ViewWithProgressIndicator(
|
|
||||||
{Key? key,
|
|
||||||
required this.snapshot,
|
|
||||||
required this.child,
|
|
||||||
this.progressIndicatorSize = 100,
|
|
||||||
this.padding = const EdgeInsets.all(0)})
|
|
||||||
: super(key: key);
|
|
||||||
|
|
||||||
@override
|
|
||||||
_ViewWithProgressIndicatorState createState() =>
|
|
||||||
_ViewWithProgressIndicatorState();
|
|
||||||
}
|
|
||||||
|
|
||||||
class _ViewWithProgressIndicatorState extends State<ViewWithProgressIndicator> {
|
|
||||||
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
switch (widget.snapshot.connectionState) {
|
|
||||||
case ConnectionState.none:
|
|
||||||
case ConnectionState.waiting:
|
|
||||||
return Container(
|
|
||||||
alignment: Alignment.center,
|
|
||||||
padding: widget.padding,
|
|
||||||
child: Center(
|
|
||||||
child: SizedBox(
|
|
||||||
width: widget.progressIndicatorSize,
|
|
||||||
height: widget.progressIndicatorSize,
|
|
||||||
child: FutureBuilder(
|
|
||||||
future: Future.delayed(const Duration(seconds: 1)),
|
|
||||||
builder: (context, wait) {
|
|
||||||
if (wait.connectionState != ConnectionState.waiting) {
|
|
||||||
return const CircularProgressIndicator();
|
|
||||||
}
|
|
||||||
return Container();
|
|
||||||
}
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
default:
|
|
||||||
if (widget.snapshot.hasError) {
|
|
||||||
return Center(
|
|
||||||
child: Text(widget.snapshot.error.toString()),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
if (!widget.snapshot.hasData) {
|
|
||||||
return const Center(
|
|
||||||
child: Text("No data"),
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
return widget.child;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -21,7 +21,7 @@ import 'package:flutter/material.dart';
|
|||||||
import 'package:parse_server_sdk_flutter/parse_server_sdk.dart';
|
import 'package:parse_server_sdk_flutter/parse_server_sdk.dart';
|
||||||
import 'package:diameter/screens/accuracy_list.dart';
|
import 'package:diameter/screens/accuracy_list.dart';
|
||||||
import 'package:diameter/config.dart';
|
import 'package:diameter/config.dart';
|
||||||
import 'package:diameter/screens/basal/basal_profiles_list.dart';
|
import 'package:diameter/screens/basal/basal_profile_list.dart';
|
||||||
import 'package:diameter/screens/bolus/bolus_profile_list.dart';
|
import 'package:diameter/screens/bolus/bolus_profile_list.dart';
|
||||||
import 'package:diameter/navigation.dart';
|
import 'package:diameter/navigation.dart';
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import 'package:diameter/main.dart';
|
import 'package:diameter/main.dart';
|
||||||
import 'package:diameter/objectbox.g.dart';
|
import 'package:diameter/objectbox.g.dart';
|
||||||
|
|
||||||
@Entity()
|
@Entity(uid: 3095978685310268382)
|
||||||
class Accuracy {
|
class Accuracy {
|
||||||
static final Box<Accuracy> box = objectBox.store.box<Accuracy>();
|
static final Box<Accuracy> box = objectBox.store.box<Accuracy>();
|
||||||
|
|
||||||
|
@ -2,7 +2,7 @@ import 'package:diameter/main.dart';
|
|||||||
import 'package:diameter/models/basal_profile.dart';
|
import 'package:diameter/models/basal_profile.dart';
|
||||||
import 'package:diameter/objectbox.g.dart';
|
import 'package:diameter/objectbox.g.dart';
|
||||||
|
|
||||||
@Entity()
|
@Entity(uid: 1467758525778521891)
|
||||||
class Basal {
|
class Basal {
|
||||||
static final Box<Basal> box = objectBox.store.box<Basal>();
|
static final Box<Basal> box = objectBox.store.box<Basal>();
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import 'package:diameter/main.dart';
|
import 'package:diameter/main.dart';
|
||||||
import 'package:diameter/objectbox.g.dart';
|
import 'package:diameter/objectbox.g.dart';
|
||||||
|
|
||||||
@Entity()
|
@Entity(uid: 3613736032926903785)
|
||||||
class BasalProfile {
|
class BasalProfile {
|
||||||
static final Box<BasalProfile> box = objectBox.store.box<BasalProfile>();
|
static final Box<BasalProfile> box = objectBox.store.box<BasalProfile>();
|
||||||
|
|
||||||
|
@ -2,7 +2,7 @@ import 'package:diameter/main.dart';
|
|||||||
import 'package:diameter/models/bolus_profile.dart';
|
import 'package:diameter/models/bolus_profile.dart';
|
||||||
import 'package:diameter/objectbox.g.dart';
|
import 'package:diameter/objectbox.g.dart';
|
||||||
|
|
||||||
@Entity()
|
@Entity(uid: 3417770529060202389)
|
||||||
class Bolus {
|
class Bolus {
|
||||||
static final Box<Bolus> box = objectBox.store.box<Bolus>();
|
static final Box<Bolus> box = objectBox.store.box<Bolus>();
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import 'package:diameter/main.dart';
|
import 'package:diameter/main.dart';
|
||||||
import 'package:diameter/objectbox.g.dart';
|
import 'package:diameter/objectbox.g.dart';
|
||||||
|
|
||||||
@Entity()
|
@Entity(uid: 8812452529027052317)
|
||||||
class BolusProfile {
|
class BolusProfile {
|
||||||
static final Box<BolusProfile> box = objectBox.store.box<BolusProfile>();
|
static final Box<BolusProfile> box = objectBox.store.box<BolusProfile>();
|
||||||
|
|
||||||
|
@ -2,9 +2,8 @@ import 'package:diameter/main.dart';
|
|||||||
import 'package:diameter/models/log_event.dart';
|
import 'package:diameter/models/log_event.dart';
|
||||||
import 'package:diameter/models/log_meal.dart';
|
import 'package:diameter/models/log_meal.dart';
|
||||||
import 'package:diameter/objectbox.g.dart';
|
import 'package:diameter/objectbox.g.dart';
|
||||||
import 'package:objectbox/objectbox.dart';
|
|
||||||
|
|
||||||
@Entity()
|
@Entity(uid: 752131069307970560)
|
||||||
class LogEntry {
|
class LogEntry {
|
||||||
static final Box<LogEntry> box = objectBox.store.box<LogEntry>();
|
static final Box<LogEntry> box = objectBox.store.box<LogEntry>();
|
||||||
|
|
||||||
|
@ -3,7 +3,7 @@ import 'package:diameter/models/log_entry.dart';
|
|||||||
import 'package:diameter/models/log_event_type.dart';
|
import 'package:diameter/models/log_event_type.dart';
|
||||||
import 'package:diameter/objectbox.g.dart';
|
import 'package:diameter/objectbox.g.dart';
|
||||||
|
|
||||||
@Entity()
|
@Entity(uid: 4303325892753185970)
|
||||||
class LogEvent {
|
class LogEvent {
|
||||||
static final Box<LogEvent> box = objectBox.store.box<LogEvent>();
|
static final Box<LogEvent> box = objectBox.store.box<LogEvent>();
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import 'package:diameter/main.dart';
|
import 'package:diameter/main.dart';
|
||||||
import 'package:objectbox/objectbox.dart';
|
import 'package:objectbox/objectbox.dart';
|
||||||
|
|
||||||
@Entity()
|
@Entity(uid: 8362795406595606110)
|
||||||
class LogEventType {
|
class LogEventType {
|
||||||
static final Box<LogEventType> box = objectBox.store.box<LogEventType>();
|
static final Box<LogEventType> box = objectBox.store.box<LogEventType>();
|
||||||
|
|
||||||
|
@ -7,7 +7,7 @@ import 'package:diameter/models/meal_source.dart';
|
|||||||
import 'package:diameter/models/accuracy.dart';
|
import 'package:diameter/models/accuracy.dart';
|
||||||
import 'package:objectbox/objectbox.dart';
|
import 'package:objectbox/objectbox.dart';
|
||||||
|
|
||||||
@Entity()
|
@Entity(uid: 411177866700467286)
|
||||||
class LogMeal {
|
class LogMeal {
|
||||||
static final Box<LogMeal> box = objectBox.store.box<LogMeal>();
|
static final Box<LogMeal> box = objectBox.store.box<LogMeal>();
|
||||||
|
|
||||||
|
@ -7,7 +7,7 @@ import 'package:objectbox/objectbox.dart';
|
|||||||
|
|
||||||
enum PortionCarbsParameter { carbsRatio, portionSize, carbsPerPortion }
|
enum PortionCarbsParameter { carbsRatio, portionSize, carbsPerPortion }
|
||||||
|
|
||||||
@Entity()
|
@Entity(uid: 382130101578692012)
|
||||||
class Meal {
|
class Meal {
|
||||||
static final Box<Meal> box = objectBox.store.box<Meal>();
|
static final Box<Meal> box = objectBox.store.box<Meal>();
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import 'package:diameter/main.dart';
|
import 'package:diameter/main.dart';
|
||||||
import 'package:objectbox/objectbox.dart';
|
import 'package:objectbox/objectbox.dart';
|
||||||
|
|
||||||
@Entity()
|
@Entity(uid: 3158200688796904913)
|
||||||
class MealCategory {
|
class MealCategory {
|
||||||
static final Box<MealCategory> box = objectBox.store.box<MealCategory>();
|
static final Box<MealCategory> box = objectBox.store.box<MealCategory>();
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import 'package:diameter/main.dart';
|
import 'package:diameter/main.dart';
|
||||||
import 'package:objectbox/objectbox.dart';
|
import 'package:objectbox/objectbox.dart';
|
||||||
|
|
||||||
@Entity()
|
@Entity(uid: 2111511899235985637)
|
||||||
class MealPortionType {
|
class MealPortionType {
|
||||||
static final Box<MealPortionType> box = objectBox.store.box<MealPortionType>();
|
static final Box<MealPortionType> box = objectBox.store.box<MealPortionType>();
|
||||||
|
|
||||||
|
@ -4,7 +4,7 @@ import 'package:diameter/models/meal_category.dart';
|
|||||||
import 'package:diameter/models/meal_portion_type.dart';
|
import 'package:diameter/models/meal_portion_type.dart';
|
||||||
import 'package:objectbox/objectbox.dart';
|
import 'package:objectbox/objectbox.dart';
|
||||||
|
|
||||||
@Entity()
|
@Entity(uid: 1283034494527412242)
|
||||||
class MealSource {
|
class MealSource {
|
||||||
static final Box<MealSource> box = objectBox.store.box<MealSource>();
|
static final Box<MealSource> box = objectBox.store.box<MealSource>();
|
||||||
|
|
||||||
|
@ -2,7 +2,7 @@ import 'package:diameter/screens/accuracy_detail.dart';
|
|||||||
import 'package:diameter/screens/accuracy_list.dart';
|
import 'package:diameter/screens/accuracy_list.dart';
|
||||||
import 'package:diameter/screens/basal/basal_detail.dart';
|
import 'package:diameter/screens/basal/basal_detail.dart';
|
||||||
import 'package:diameter/screens/basal/basal_profile_detail.dart';
|
import 'package:diameter/screens/basal/basal_profile_detail.dart';
|
||||||
import 'package:diameter/screens/basal/basal_profiles_list.dart';
|
import 'package:diameter/screens/basal/basal_profile_list.dart';
|
||||||
import 'package:diameter/screens/bolus/bolus_detail.dart';
|
import 'package:diameter/screens/bolus/bolus_detail.dart';
|
||||||
import 'package:diameter/screens/bolus/bolus_profile_detail.dart';
|
import 'package:diameter/screens/bolus/bolus_profile_detail.dart';
|
||||||
import 'package:diameter/screens/bolus/bolus_profile_list.dart';
|
import 'package:diameter/screens/bolus/bolus_profile_list.dart';
|
||||||
|
@ -665,8 +665,8 @@ Future<Store> openStore(
|
|||||||
ModelDefinition getObjectBoxModel() {
|
ModelDefinition getObjectBoxModel() {
|
||||||
final model = ModelInfo(
|
final model = ModelInfo(
|
||||||
entities: _entities,
|
entities: _entities,
|
||||||
lastEntityId: const IdUid(18, 1283034494527412242),
|
lastEntityId: const IdUid(13, 1283034494527412242),
|
||||||
lastIndexId: const IdUid(25, 1931330716440762729),
|
lastIndexId: const IdUid(21, 1931330716440762729),
|
||||||
lastRelationId: const IdUid(0, 0),
|
lastRelationId: const IdUid(0, 0),
|
||||||
lastSequenceId: const IdUid(0, 0),
|
lastSequenceId: const IdUid(0, 0),
|
||||||
retiredEntityUids: const [],
|
retiredEntityUids: const [],
|
||||||
|
@ -108,7 +108,7 @@ class _AccuracyDetailScreenState extends State<AccuracyDetailScreen> {
|
|||||||
child: Column(
|
child: Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
StyledForm(
|
FormWrapper(
|
||||||
formState: _accuracyForm,
|
formState: _accuracyForm,
|
||||||
fields: [
|
fields: [
|
||||||
TextFormField(
|
TextFormField(
|
||||||
@ -123,7 +123,7 @@ class _AccuracyDetailScreenState extends State<AccuracyDetailScreen> {
|
|||||||
return null;
|
return null;
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
StyledBooleanFormField(
|
BooleanFormField(
|
||||||
value: _forCarbsRatio,
|
value: _forCarbsRatio,
|
||||||
label: 'for carbs ratio',
|
label: 'for carbs ratio',
|
||||||
onChanged: (value) {
|
onChanged: (value) {
|
||||||
@ -132,7 +132,7 @@ class _AccuracyDetailScreenState extends State<AccuracyDetailScreen> {
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
StyledBooleanFormField(
|
BooleanFormField(
|
||||||
value: _forPortionSize,
|
value: _forPortionSize,
|
||||||
label: 'for portion size',
|
label: 'for portion size',
|
||||||
onChanged: (value) {
|
onChanged: (value) {
|
||||||
|
@ -105,6 +105,7 @@ class _AccuracyListScreenState extends State<AccuracyListScreen> {
|
|||||||
IconButton(
|
IconButton(
|
||||||
icon: const Icon(Icons.reorder),
|
icon: const Icon(Icons.reorder),
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
|
// ignore: todo
|
||||||
// TODO: implement reordering
|
// TODO: implement reordering
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
@ -85,8 +85,6 @@ class _BasalDetailScreenState extends State<BasalDetailScreen> {
|
|||||||
String? error;
|
String? error;
|
||||||
List<Basal> basalRates = Basal.getAllForProfile(widget.basalProfileId);
|
List<Basal> basalRates = Basal.getAllForProfile(widget.basalProfileId);
|
||||||
|
|
||||||
// TODO use a query for the following checks instead?
|
|
||||||
// check for duplicates
|
|
||||||
if (basalRates
|
if (basalRates
|
||||||
.where((other) =>
|
.where((other) =>
|
||||||
(widget.id != other.id) &&
|
(widget.id != other.id) &&
|
||||||
@ -187,7 +185,7 @@ class _BasalDetailScreenState extends State<BasalDetailScreen> {
|
|||||||
drawer: const Navigation(currentLocation: BasalDetailScreen.routeName),
|
drawer: const Navigation(currentLocation: BasalDetailScreen.routeName),
|
||||||
body: Column(
|
body: Column(
|
||||||
children: [
|
children: [
|
||||||
StyledForm(
|
FormWrapper(
|
||||||
formState: _basalForm,
|
formState: _basalForm,
|
||||||
fields: [
|
fields: [
|
||||||
Row(
|
Row(
|
||||||
@ -195,7 +193,7 @@ class _BasalDetailScreenState extends State<BasalDetailScreen> {
|
|||||||
Expanded(
|
Expanded(
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: const EdgeInsets.only(right: 5),
|
padding: const EdgeInsets.only(right: 5),
|
||||||
child: StyledTimeOfDayFormField(
|
child: TimeOfDayFormField(
|
||||||
label: 'Start Time',
|
label: 'Start Time',
|
||||||
controller: _startTimeController,
|
controller: _startTimeController,
|
||||||
time: _startTime,
|
time: _startTime,
|
||||||
@ -213,7 +211,7 @@ class _BasalDetailScreenState extends State<BasalDetailScreen> {
|
|||||||
Expanded(
|
Expanded(
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: const EdgeInsets.only(left: 5),
|
padding: const EdgeInsets.only(left: 5),
|
||||||
child: StyledTimeOfDayFormField(
|
child: TimeOfDayFormField(
|
||||||
label: 'End Time',
|
label: 'End Time',
|
||||||
controller: _endTimeController,
|
controller: _endTimeController,
|
||||||
time: _endTime,
|
time: _endTime,
|
||||||
|
@ -72,7 +72,6 @@ class _BasalListScreenState extends State<BasalListScreen> {
|
|||||||
List<Basal> basalRates = widget.basalRates;
|
List<Basal> basalRates = widget.basalRates;
|
||||||
Basal basal = basalRates[index];
|
Basal basal = basalRates[index];
|
||||||
|
|
||||||
// TODO: use queries for all this
|
|
||||||
// check for gaps
|
// check for gaps
|
||||||
if (index == 0 &&
|
if (index == 0 &&
|
||||||
(basal.startTime.hour != 0 || basal.startTime.minute != 0)) {
|
(basal.startTime.hour != 0 || basal.startTime.minute != 0)) {
|
||||||
|
@ -27,7 +27,6 @@ class _BasalProfileDetailScreenState extends State<BasalProfileDetailScreen> {
|
|||||||
BasalProfile? _basalProfile;
|
BasalProfile? _basalProfile;
|
||||||
List<Basal> _basalRates = [];
|
List<Basal> _basalRates = [];
|
||||||
bool _isNew = true;
|
bool _isNew = true;
|
||||||
bool _isSaving = false;
|
|
||||||
|
|
||||||
final GlobalKey<FormState> _basalProfileForm = GlobalKey<FormState>();
|
final GlobalKey<FormState> _basalProfileForm = GlobalKey<FormState>();
|
||||||
|
|
||||||
@ -35,6 +34,7 @@ class _BasalProfileDetailScreenState extends State<BasalProfileDetailScreen> {
|
|||||||
late IconButton refreshButton;
|
late IconButton refreshButton;
|
||||||
late IconButton closeButton;
|
late IconButton closeButton;
|
||||||
late DetailBottomRow detailBottomRow;
|
late DetailBottomRow detailBottomRow;
|
||||||
|
late DetailBottomRow detailBottomRowWhileSaving;
|
||||||
|
|
||||||
FloatingActionButton? actionButton;
|
FloatingActionButton? actionButton;
|
||||||
List<Widget> appBarActions = [];
|
List<Widget> appBarActions = [];
|
||||||
@ -77,7 +77,12 @@ class _BasalProfileDetailScreenState extends State<BasalProfileDetailScreen> {
|
|||||||
|
|
||||||
detailBottomRow = DetailBottomRow(
|
detailBottomRow = DetailBottomRow(
|
||||||
onCancel: handleCancelAction,
|
onCancel: handleCancelAction,
|
||||||
onSave: _isSaving ? null : handleSaveAction,
|
onSave: handleSaveAction,
|
||||||
|
);
|
||||||
|
|
||||||
|
detailBottomRowWhileSaving = DetailBottomRow(
|
||||||
|
onCancel: handleCancelAction,
|
||||||
|
onSave: null,
|
||||||
);
|
);
|
||||||
|
|
||||||
actionButton = null;
|
actionButton = null;
|
||||||
@ -146,7 +151,7 @@ class _BasalProfileDetailScreenState extends State<BasalProfileDetailScreen> {
|
|||||||
});
|
});
|
||||||
} else if (!_active &&
|
} else if (!_active &&
|
||||||
((_isNew && _activeCount == 0) ||
|
((_isNew && _activeCount == 0) ||
|
||||||
(_activeCount == 1 && _basalProfile!.active))) {
|
(!_isNew && _activeCount == 1 && _basalProfile!.active))) {
|
||||||
await showDialog(
|
await showDialog(
|
||||||
context: context,
|
context: context,
|
||||||
builder: (BuildContext context) {
|
builder: (BuildContext context) {
|
||||||
@ -214,7 +219,7 @@ class _BasalProfileDetailScreenState extends State<BasalProfileDetailScreen> {
|
|||||||
|
|
||||||
void handleSaveAction() async {
|
void handleSaveAction() async {
|
||||||
setState(() {
|
setState(() {
|
||||||
_isSaving = true;
|
bottomNav = detailBottomRowWhileSaving;
|
||||||
});
|
});
|
||||||
if (_basalProfileForm.currentState!.validate()) {
|
if (_basalProfileForm.currentState!.validate()) {
|
||||||
await checkActiveProfiles();
|
await checkActiveProfiles();
|
||||||
@ -227,7 +232,7 @@ class _BasalProfileDetailScreenState extends State<BasalProfileDetailScreen> {
|
|||||||
Navigator.pop(context, '${_isNew ? 'New' : ''} Basal Profile saved');
|
Navigator.pop(context, '${_isNew ? 'New' : ''} Basal Profile saved');
|
||||||
}
|
}
|
||||||
setState(() {
|
setState(() {
|
||||||
_isSaving = false;
|
bottomNav = detailBottomRow;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -283,7 +288,7 @@ class _BasalProfileDetailScreenState extends State<BasalProfileDetailScreen> {
|
|||||||
child: Column(
|
child: Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||||
children: [
|
children: [
|
||||||
StyledForm(
|
FormWrapper(
|
||||||
formState: _basalProfileForm,
|
formState: _basalProfileForm,
|
||||||
fields: [
|
fields: [
|
||||||
TextFormField(
|
TextFormField(
|
||||||
@ -307,7 +312,7 @@ class _BasalProfileDetailScreenState extends State<BasalProfileDetailScreen> {
|
|||||||
alignLabelWithHint: true,
|
alignLabelWithHint: true,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
StyledBooleanFormField(
|
BooleanFormField(
|
||||||
value: _active,
|
value: _active,
|
||||||
onChanged: (value) {
|
onChanged: (value) {
|
||||||
setState(() {
|
setState(() {
|
||||||
|
@ -93,9 +93,7 @@ class _BolusDetailScreenState extends State<BolusDetailScreen> {
|
|||||||
Future<String?> validateTimePeriod() async {
|
Future<String?> validateTimePeriod() async {
|
||||||
String? error;
|
String? error;
|
||||||
List<Bolus> bolusRates = Bolus.getAllForProfile(widget.bolusProfileId);
|
List<Bolus> bolusRates = Bolus.getAllForProfile(widget.bolusProfileId);
|
||||||
// BolusProfile.get(widget.bolusProfileId)?.bolusRates ?? [];
|
|
||||||
|
|
||||||
// TODO use a query for the following checks instead?
|
|
||||||
// check for duplicates
|
// check for duplicates
|
||||||
if (bolusRates
|
if (bolusRates
|
||||||
.where((other) =>
|
.where((other) =>
|
||||||
@ -238,7 +236,7 @@ class _BolusDetailScreenState extends State<BolusDetailScreen> {
|
|||||||
body: SingleChildScrollView(
|
body: SingleChildScrollView(
|
||||||
child: Column(
|
child: Column(
|
||||||
children: [
|
children: [
|
||||||
StyledForm(
|
FormWrapper(
|
||||||
formState: _bolusForm,
|
formState: _bolusForm,
|
||||||
fields: [
|
fields: [
|
||||||
Row(
|
Row(
|
||||||
@ -246,7 +244,7 @@ class _BolusDetailScreenState extends State<BolusDetailScreen> {
|
|||||||
Expanded(
|
Expanded(
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: const EdgeInsets.only(right: 5),
|
padding: const EdgeInsets.only(right: 5),
|
||||||
child: StyledTimeOfDayFormField(
|
child: TimeOfDayFormField(
|
||||||
label: 'Start Time',
|
label: 'Start Time',
|
||||||
controller: _startTimeController,
|
controller: _startTimeController,
|
||||||
time: _startTime,
|
time: _startTime,
|
||||||
@ -264,7 +262,7 @@ class _BolusDetailScreenState extends State<BolusDetailScreen> {
|
|||||||
Expanded(
|
Expanded(
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: const EdgeInsets.only(left: 5),
|
padding: const EdgeInsets.only(left: 5),
|
||||||
child: StyledTimeOfDayFormField(
|
child: TimeOfDayFormField(
|
||||||
label: 'End Time',
|
label: 'End Time',
|
||||||
controller: _endTimeController,
|
controller: _endTimeController,
|
||||||
time: _endTime,
|
time: _endTime,
|
||||||
|
@ -70,8 +70,6 @@ class _BolusListScreenState extends State<BolusListScreen> {
|
|||||||
List<Bolus> bolusRates = widget.bolusRates;
|
List<Bolus> bolusRates = widget.bolusRates;
|
||||||
Bolus bolus = bolusRates[index];
|
Bolus bolus = bolusRates[index];
|
||||||
|
|
||||||
// TODO: use queries for all this
|
|
||||||
// check for gaps
|
|
||||||
if (index == 0 &&
|
if (index == 0 &&
|
||||||
(bolus.startTime.toLocal().hour != 0 || bolus.startTime.minute != 0)) {
|
(bolus.startTime.toLocal().hour != 0 || bolus.startTime.minute != 0)) {
|
||||||
return 'First Bolus of the day needs to start at 00:00';
|
return 'First Bolus of the day needs to start at 00:00';
|
||||||
|
@ -26,7 +26,6 @@ class _BolusProfileDetailScreenState extends State<BolusProfileDetailScreen> {
|
|||||||
BolusProfile? _bolusProfile;
|
BolusProfile? _bolusProfile;
|
||||||
List<Bolus> _bolusRates = [];
|
List<Bolus> _bolusRates = [];
|
||||||
bool _isNew = true;
|
bool _isNew = true;
|
||||||
bool _isSaving = false;
|
|
||||||
|
|
||||||
final GlobalKey<FormState> _bolusProfileForm = GlobalKey<FormState>();
|
final GlobalKey<FormState> _bolusProfileForm = GlobalKey<FormState>();
|
||||||
|
|
||||||
@ -34,6 +33,7 @@ class _BolusProfileDetailScreenState extends State<BolusProfileDetailScreen> {
|
|||||||
late IconButton refreshButton;
|
late IconButton refreshButton;
|
||||||
late IconButton closeButton;
|
late IconButton closeButton;
|
||||||
late DetailBottomRow detailBottomRow;
|
late DetailBottomRow detailBottomRow;
|
||||||
|
late DetailBottomRow detailBottomRowWhileSaving;
|
||||||
|
|
||||||
FloatingActionButton? actionButton;
|
FloatingActionButton? actionButton;
|
||||||
List<Widget> appBarActions = [];
|
List<Widget> appBarActions = [];
|
||||||
@ -73,10 +73,14 @@ class _BolusProfileDetailScreenState extends State<BolusProfileDetailScreen> {
|
|||||||
icon: const Icon(Icons.close),
|
icon: const Icon(Icons.close),
|
||||||
);
|
);
|
||||||
|
|
||||||
// TODO: fix (saving button doesnt get disabled)
|
|
||||||
detailBottomRow = DetailBottomRow(
|
detailBottomRow = DetailBottomRow(
|
||||||
onCancel: handleCancelAction,
|
onCancel: handleCancelAction,
|
||||||
onSave: _isSaving ? null : handleSaveAction,
|
onSave: handleSaveAction,
|
||||||
|
);
|
||||||
|
|
||||||
|
detailBottomRowWhileSaving = DetailBottomRow(
|
||||||
|
onCancel: handleCancelAction,
|
||||||
|
onSave: null,
|
||||||
);
|
);
|
||||||
|
|
||||||
actionButton = null;
|
actionButton = null;
|
||||||
@ -144,7 +148,7 @@ class _BolusProfileDetailScreenState extends State<BolusProfileDetailScreen> {
|
|||||||
});
|
});
|
||||||
} else if (!_active &&
|
} else if (!_active &&
|
||||||
((_isNew && _activeCount == 0) ||
|
((_isNew && _activeCount == 0) ||
|
||||||
(_activeCount == 1 && _bolusProfile!.active))) {
|
(!_isNew && _activeCount == 1 && _bolusProfile!.active))) {
|
||||||
await showDialog(
|
await showDialog(
|
||||||
context: context,
|
context: context,
|
||||||
builder: (BuildContext context) {
|
builder: (BuildContext context) {
|
||||||
@ -212,7 +216,7 @@ class _BolusProfileDetailScreenState extends State<BolusProfileDetailScreen> {
|
|||||||
|
|
||||||
void handleSaveAction() async {
|
void handleSaveAction() async {
|
||||||
setState(() {
|
setState(() {
|
||||||
_isSaving = true;
|
bottomNav = detailBottomRowWhileSaving;
|
||||||
});
|
});
|
||||||
|
|
||||||
if (_bolusProfileForm.currentState!.validate()) {
|
if (_bolusProfileForm.currentState!.validate()) {
|
||||||
@ -229,9 +233,9 @@ class _BolusProfileDetailScreenState extends State<BolusProfileDetailScreen> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
setState(() {
|
setState(() {
|
||||||
_isSaving = false;
|
bottomNav = detailBottomRow;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void handleCancelAction() {
|
void handleCancelAction() {
|
||||||
if (showConfirmationDialogOnCancel &&
|
if (showConfirmationDialogOnCancel &&
|
||||||
@ -286,7 +290,7 @@ class _BolusProfileDetailScreenState extends State<BolusProfileDetailScreen> {
|
|||||||
child: Column(
|
child: Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||||
children: [
|
children: [
|
||||||
StyledForm(
|
FormWrapper(
|
||||||
formState: _bolusProfileForm,
|
formState: _bolusProfileForm,
|
||||||
fields: [
|
fields: [
|
||||||
TextFormField(
|
TextFormField(
|
||||||
@ -309,7 +313,7 @@ class _BolusProfileDetailScreenState extends State<BolusProfileDetailScreen> {
|
|||||||
controller: _notesController,
|
controller: _notesController,
|
||||||
keyboardType: TextInputType.multiline,
|
keyboardType: TextInputType.multiline,
|
||||||
),
|
),
|
||||||
StyledBooleanFormField(
|
BooleanFormField(
|
||||||
value: _active,
|
value: _active,
|
||||||
onChanged: (value) {
|
onChanged: (value) {
|
||||||
setState(() {
|
setState(() {
|
||||||
@ -326,8 +330,10 @@ class _BolusProfileDetailScreenState extends State<BolusProfileDetailScreen> {
|
|||||||
];
|
];
|
||||||
|
|
||||||
if (!_isNew) {
|
if (!_isNew) {
|
||||||
tabs.add(
|
tabs.add(BolusListScreen(
|
||||||
BolusListScreen(bolusProfile: _bolusProfile!, bolusRates: _bolusRates, reload: reload));
|
bolusProfile: _bolusProfile!,
|
||||||
|
bolusRates: _bolusRates,
|
||||||
|
reload: reload));
|
||||||
}
|
}
|
||||||
|
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
|
@ -165,7 +165,6 @@ class _BolusProfileListScreenState extends State<BolusProfileListScreen> {
|
|||||||
? Colors.green.shade100
|
? Colors.green.shade100
|
||||||
: null,
|
: null,
|
||||||
onTap: () {
|
onTap: () {
|
||||||
// TODO: make pick active profile visually distinct
|
|
||||||
pickActiveProfileMode
|
pickActiveProfileMode
|
||||||
? onPickActive(bolusProfile)
|
? onPickActive(bolusProfile)
|
||||||
: onEdit(bolusProfile);
|
: onEdit(bolusProfile);
|
||||||
|
@ -96,7 +96,6 @@ class _ActiveLogEventListScreenState extends State<ActiveLogEventListScreen> {
|
|||||||
padding: const EdgeInsets.only(top: 10.0),
|
padding: const EdgeInsets.only(top: 10.0),
|
||||||
child: Column(
|
child: Column(
|
||||||
children: [
|
children: [
|
||||||
// TODO: make action button instead of appbar
|
|
||||||
AppBar(
|
AppBar(
|
||||||
title: const Text('Active Events'),
|
title: const Text('Active Events'),
|
||||||
primary: false,
|
primary: false,
|
||||||
|
@ -107,8 +107,8 @@ class _LogScreenState extends State<LogScreen> {
|
|||||||
title: Text(
|
title: Text(
|
||||||
DateTimeUtils.displayTime(
|
DateTimeUtils.displayTime(
|
||||||
logEntry.time)),
|
logEntry.time)),
|
||||||
// TODO: add additional fields (event icons...)
|
// ignore: todo
|
||||||
// TODO: display glucose in colors according to target settings
|
// TODO: add more data (event, glucose color...)
|
||||||
subtitle: Text(logEntry
|
subtitle: Text(logEntry
|
||||||
.mgPerDl !=
|
.mgPerDl !=
|
||||||
null
|
null
|
||||||
@ -141,6 +141,7 @@ class _LogScreenState extends State<LogScreen> {
|
|||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
// ignore: todo
|
||||||
// TODO: add button for active events
|
// TODO: add button for active events
|
||||||
floatingActionButton: FloatingActionButton(
|
floatingActionButton: FloatingActionButton(
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
|
@ -1,13 +1,16 @@
|
|||||||
import 'package:diameter/components/detail.dart';
|
import 'package:diameter/components/detail.dart';
|
||||||
import 'package:diameter/components/dialogs.dart';
|
import 'package:diameter/components/dialogs.dart';
|
||||||
|
import 'package:diameter/components/forms.dart';
|
||||||
import 'package:diameter/config.dart';
|
import 'package:diameter/config.dart';
|
||||||
import 'package:diameter/models/log_entry.dart';
|
import 'package:diameter/models/log_entry.dart';
|
||||||
import 'package:diameter/navigation.dart';
|
import 'package:diameter/navigation.dart';
|
||||||
import 'package:diameter/screens/log/log_entry_form.dart';
|
|
||||||
import 'package:diameter/screens/log/log_event_detail.dart';
|
import 'package:diameter/screens/log/log_event_detail.dart';
|
||||||
import 'package:diameter/screens/log/log_event_list.dart';
|
import 'package:diameter/screens/log/log_event_list.dart';
|
||||||
import 'package:diameter/screens/log/log_meal_detail.dart';
|
import 'package:diameter/screens/log/log_meal_detail.dart';
|
||||||
import 'package:diameter/screens/log/log_meal_list.dart';
|
import 'package:diameter/screens/log/log_meal_list.dart';
|
||||||
|
import 'package:diameter/settings.dart';
|
||||||
|
import 'package:diameter/utils/date_time_utils.dart';
|
||||||
|
import 'package:diameter/utils/utils.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
class LogEntryScreen extends StatefulWidget {
|
class LogEntryScreen extends StatefulWidget {
|
||||||
@ -27,6 +30,17 @@ class _LogEntryScreenState extends State<LogEntryScreen> {
|
|||||||
|
|
||||||
final GlobalKey<FormState> logEntryForm = GlobalKey<FormState>();
|
final GlobalKey<FormState> logEntryForm = GlobalKey<FormState>();
|
||||||
|
|
||||||
|
DateTime _time = DateTime.now();
|
||||||
|
|
||||||
|
final _timeController = TextEditingController(text: '');
|
||||||
|
final _dateController = TextEditingController(text: '');
|
||||||
|
final _mgPerDlController = TextEditingController(text: '');
|
||||||
|
final _mmolPerLController = TextEditingController(text: '');
|
||||||
|
final _bolusGlucoseController = TextEditingController(text: '');
|
||||||
|
final _delayedBolusRateController = TextEditingController(text: '');
|
||||||
|
final _delayedBolusDurationController = TextEditingController(text: '');
|
||||||
|
final _notesController = TextEditingController(text: '');
|
||||||
|
|
||||||
late FloatingActionButton addMealButton;
|
late FloatingActionButton addMealButton;
|
||||||
late FloatingActionButton addEventButton;
|
late FloatingActionButton addEventButton;
|
||||||
late IconButton refreshButton;
|
late IconButton refreshButton;
|
||||||
@ -37,39 +51,12 @@ class _LogEntryScreenState extends State<LogEntryScreen> {
|
|||||||
List<Widget> appBarActions = [];
|
List<Widget> appBarActions = [];
|
||||||
DetailBottomRow? bottomNav;
|
DetailBottomRow? bottomNav;
|
||||||
|
|
||||||
final formDataControllers = <String, TextEditingController>{
|
|
||||||
'time': TextEditingController(text: ''),
|
|
||||||
'mgPerDl': TextEditingController(text: ''),
|
|
||||||
'mmolPerL': TextEditingController(text: ''),
|
|
||||||
'bolusGlucose': TextEditingController(text: ''),
|
|
||||||
'delayedBolusRate': TextEditingController(text: ''),
|
|
||||||
'delayedBolusDuration': TextEditingController(text: ''),
|
|
||||||
'notes': TextEditingController(text: ''),
|
|
||||||
};
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
super.initState();
|
super.initState();
|
||||||
|
|
||||||
reload();
|
reload();
|
||||||
|
|
||||||
if (_logEntry != null) {
|
|
||||||
formDataControllers['time']!.text = _logEntry!.time.toString();
|
|
||||||
formDataControllers['mgPerDl']!.text =
|
|
||||||
(_logEntry!.mgPerDl ?? '').toString();
|
|
||||||
formDataControllers['mmolPerL']!.text =
|
|
||||||
(_logEntry!.mmolPerL ?? '').toString();
|
|
||||||
formDataControllers['bolusGlucose']!.text =
|
|
||||||
(_logEntry!.bolusGlucose ?? '').toString();
|
|
||||||
formDataControllers['delayedBolusRate']!.text =
|
|
||||||
(_logEntry!.delayedBolusRate ?? '').toString();
|
|
||||||
formDataControllers['delayedBolusDuration']!.text =
|
|
||||||
(_logEntry!.delayedBolusDuration ?? '').toString();
|
|
||||||
formDataControllers['notes']!.text = _logEntry!.notes ?? '';
|
|
||||||
} else {
|
|
||||||
formDataControllers['time']!.text = DateTime.now().toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
addMealButton = FloatingActionButton(
|
addMealButton = FloatingActionButton(
|
||||||
onPressed: handleAddNewMeal,
|
onPressed: handleAddNewMeal,
|
||||||
child: const Icon(Icons.add),
|
child: const Icon(Icons.add),
|
||||||
@ -98,6 +85,20 @@ class _LogEntryScreenState extends State<LogEntryScreen> {
|
|||||||
actionButton = null;
|
actionButton = null;
|
||||||
appBarActions = [closeButton];
|
appBarActions = [closeButton];
|
||||||
bottomNav = detailBottomRow;
|
bottomNav = detailBottomRow;
|
||||||
|
|
||||||
|
if (_logEntry != null) {
|
||||||
|
_time = _logEntry!.time;
|
||||||
|
_mgPerDlController.text = (_logEntry!.mgPerDl ?? '').toString();
|
||||||
|
_mmolPerLController.text = (_logEntry!.mmolPerL ?? '').toString();
|
||||||
|
_bolusGlucoseController.text = (_logEntry!.bolusGlucose ?? '').toString();
|
||||||
|
_delayedBolusRateController.text =
|
||||||
|
(_logEntry!.delayedBolusRate ?? '').toString();
|
||||||
|
_delayedBolusDurationController.text =
|
||||||
|
(_logEntry!.delayedBolusDuration ?? '').toString();
|
||||||
|
_notesController.text = _logEntry!.notes ?? '';
|
||||||
|
}
|
||||||
|
|
||||||
|
updateTime();
|
||||||
}
|
}
|
||||||
|
|
||||||
void reload({String? message}) {
|
void reload({String? message}) {
|
||||||
@ -121,6 +122,95 @@ class _LogEntryScreenState extends State<LogEntryScreen> {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void updateTime() {
|
||||||
|
_timeController.text = DateTimeUtils.displayTime(_time);
|
||||||
|
_dateController.text = DateTimeUtils.displayDate(_time);
|
||||||
|
}
|
||||||
|
|
||||||
|
void convertBetweenMgPerDlAndMmolPerL({GlucoseMeasurement? calculateFrom}) {
|
||||||
|
int? mgPerDl;
|
||||||
|
double? mmolPerL;
|
||||||
|
|
||||||
|
if (calculateFrom != GlucoseMeasurement.mmolPerL &&
|
||||||
|
_mgPerDlController.text != '') {
|
||||||
|
mgPerDl = int.tryParse(_mgPerDlController.text);
|
||||||
|
}
|
||||||
|
if (calculateFrom != GlucoseMeasurement.mgPerDl &&
|
||||||
|
_mmolPerLController.text != '') {
|
||||||
|
mmolPerL = double.tryParse(_mmolPerLController.text);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mgPerDl != null && mmolPerL == null) {
|
||||||
|
setState(() {
|
||||||
|
_mmolPerLController.text =
|
||||||
|
Utils.convertMgPerDlToMmolPerL(mgPerDl!).toString();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (mmolPerL != null && mgPerDl == null) {
|
||||||
|
setState(() {
|
||||||
|
_mgPerDlController.text =
|
||||||
|
Utils.convertMmolPerLToMgPerDl(mmolPerL!).toString();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void handleSaveAction() async {
|
||||||
|
setState(() {
|
||||||
|
_isSaving = true;
|
||||||
|
});
|
||||||
|
if (logEntryForm.currentState!.validate()) {
|
||||||
|
LogEntry.put(LogEntry(
|
||||||
|
id: widget.id,
|
||||||
|
time: _time,
|
||||||
|
mgPerDl: int.tryParse(_mgPerDlController.text),
|
||||||
|
mmolPerL: double.tryParse(_mmolPerLController.text),
|
||||||
|
bolusGlucose: double.tryParse(_bolusGlucoseController.text),
|
||||||
|
delayedBolusDuration:
|
||||||
|
int.tryParse(_delayedBolusDurationController.text),
|
||||||
|
delayedBolusRate: double.tryParse(_delayedBolusRateController.text),
|
||||||
|
notes: _notesController.text,
|
||||||
|
));
|
||||||
|
Navigator.pushReplacementNamed(context, '/log',
|
||||||
|
arguments: '${_isNew ? 'New' : ''} Log Entry Saved');
|
||||||
|
}
|
||||||
|
setState(() {
|
||||||
|
_isSaving = false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void handleCancelAction() {
|
||||||
|
if (showConfirmationDialogOnCancel &&
|
||||||
|
((_isNew &&
|
||||||
|
(int.tryParse(_mgPerDlController.text) != null ||
|
||||||
|
double.tryParse(_mmolPerLController.text) != null ||
|
||||||
|
double.tryParse(_bolusGlucoseController.text) != null ||
|
||||||
|
int.tryParse(_delayedBolusDurationController.text) !=
|
||||||
|
null ||
|
||||||
|
double.tryParse(_delayedBolusRateController.text) != null ||
|
||||||
|
_notesController.text != '')) ||
|
||||||
|
(!_isNew &&
|
||||||
|
(int.tryParse(_mgPerDlController.text) != _logEntry!.mgPerDl ||
|
||||||
|
double.tryParse(_mmolPerLController.text) !=
|
||||||
|
_logEntry!.mmolPerL ||
|
||||||
|
double.tryParse(_bolusGlucoseController.text) !=
|
||||||
|
_logEntry!.bolusGlucose ||
|
||||||
|
int.tryParse(_delayedBolusDurationController.text) !=
|
||||||
|
_logEntry!.delayedBolusDuration ||
|
||||||
|
double.tryParse(_delayedBolusRateController.text) !=
|
||||||
|
_logEntry!.delayedBolusRate ||
|
||||||
|
_notesController.text != (_logEntry!.notes ?? ''))))) {
|
||||||
|
Dialogs.showCancelConfirmationDialog(
|
||||||
|
context: context,
|
||||||
|
isNew: _isNew,
|
||||||
|
onSave: handleSaveAction,
|
||||||
|
onDiscard: (context) => Navigator.pushReplacementNamed(context, '/log'),
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
Navigator.pushReplacementNamed(context, '/log',
|
||||||
|
arguments: '${_isNew ? 'New' : ''} Log Entry Saved');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void handleAddNewMeal() async {
|
void handleAddNewMeal() async {
|
||||||
Navigator.push(
|
Navigator.push(
|
||||||
context,
|
context,
|
||||||
@ -143,73 +233,6 @@ class _LogEntryScreenState extends State<LogEntryScreen> {
|
|||||||
).then((message) => reload(message: message));
|
).then((message) => reload(message: message));
|
||||||
}
|
}
|
||||||
|
|
||||||
void handleSaveAction() async {
|
|
||||||
setState(() {
|
|
||||||
_isSaving = true;
|
|
||||||
});
|
|
||||||
if (logEntryForm.currentState!.validate()) {
|
|
||||||
LogEntry.put(LogEntry(
|
|
||||||
id: widget.id,
|
|
||||||
time: DateTime.parse(formDataControllers['time']!.text),
|
|
||||||
mgPerDl: int.tryParse(formDataControllers['mgPerDl']!.text),
|
|
||||||
mmolPerL: double.tryParse(formDataControllers['mmolPerL']!.text),
|
|
||||||
bolusGlucose:
|
|
||||||
double.tryParse(formDataControllers['delayedBolusRate']!.text),
|
|
||||||
delayedBolusDuration:
|
|
||||||
int.tryParse(formDataControllers['delayedBolusDuration']!.text),
|
|
||||||
delayedBolusRate:
|
|
||||||
double.tryParse(formDataControllers['delayedBolusRate']!.text),
|
|
||||||
notes: formDataControllers['notes']!.text,
|
|
||||||
));
|
|
||||||
Navigator.pushReplacementNamed(context, '/log',
|
|
||||||
arguments: '${_isNew ? 'New' : ''} Log Entry Saved');
|
|
||||||
}
|
|
||||||
setState(() {
|
|
||||||
_isSaving = false;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
void handleCancelAction() {
|
|
||||||
if (showConfirmationDialogOnCancel &&
|
|
||||||
((_isNew &&
|
|
||||||
(int.tryParse(formDataControllers['mgPerDl']?.text ?? '') !=
|
|
||||||
null ||
|
|
||||||
double.tryParse(formDataControllers['mmolPerL']?.text ?? '') !=
|
|
||||||
null ||
|
|
||||||
double.tryParse(formDataControllers['bolusGlucose']?.text ?? '') !=
|
|
||||||
null ||
|
|
||||||
int.tryParse(formDataControllers['delayedBolusDuration']?.text ?? '') !=
|
|
||||||
null ||
|
|
||||||
double.tryParse(formDataControllers['delayedBolusRate']?.text ?? '') !=
|
|
||||||
null ||
|
|
||||||
formDataControllers['notes']?.text != '')) ||
|
|
||||||
(!_isNew &&
|
|
||||||
(int.tryParse(formDataControllers['mgPerDl']?.text ?? '') !=
|
|
||||||
_logEntry!.mgPerDl ||
|
|
||||||
double.tryParse(formDataControllers['mmolPerL']?.text ?? '') !=
|
|
||||||
_logEntry!.mmolPerL ||
|
|
||||||
double.tryParse(formDataControllers['bolusGlucose']?.text ?? '') !=
|
|
||||||
_logEntry!.bolusGlucose ||
|
|
||||||
int.tryParse(
|
|
||||||
formDataControllers['delayedBolusDuration']?.text ??
|
|
||||||
'') !=
|
|
||||||
_logEntry!.delayedBolusDuration ||
|
|
||||||
double.tryParse(formDataControllers['delayedBolusRate']?.text ?? '') !=
|
|
||||||
_logEntry!.delayedBolusRate ||
|
|
||||||
formDataControllers['notes']?.text !=
|
|
||||||
(_logEntry!.notes ?? ''))))) {
|
|
||||||
Dialogs.showCancelConfirmationDialog(
|
|
||||||
context: context,
|
|
||||||
isNew: _isNew,
|
|
||||||
onSave: handleSaveAction,
|
|
||||||
onDiscard: (context) => Navigator.pushReplacementNamed(context, '/log'),
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
Navigator.pushReplacementNamed(context, '/log',
|
|
||||||
arguments: '${_isNew ? 'New' : ''} Log Entry Saved');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void renderTabButtons(index) {
|
void renderTabButtons(index) {
|
||||||
if (_logEntry != null) {
|
if (_logEntry != null) {
|
||||||
setState(() {
|
setState(() {
|
||||||
@ -243,8 +266,189 @@ class _LogEntryScreenState extends State<LogEntryScreen> {
|
|||||||
renderTabButtons(tabController.index);
|
renderTabButtons(tabController.index);
|
||||||
});
|
});
|
||||||
List<Widget> tabs = [
|
List<Widget> tabs = [
|
||||||
LogEntryForm(
|
SingleChildScrollView(
|
||||||
formState: logEntryForm, controllers: formDataControllers),
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||||
|
children: <Widget>[
|
||||||
|
FormWrapper(
|
||||||
|
formState: logEntryForm,
|
||||||
|
fields: [
|
||||||
|
Row(
|
||||||
|
children: [
|
||||||
|
Expanded(
|
||||||
|
child: Padding(
|
||||||
|
padding: const EdgeInsets.only(right: 5),
|
||||||
|
child: DateTimeFormField(
|
||||||
|
date: _time,
|
||||||
|
label: 'Date',
|
||||||
|
controller: _dateController,
|
||||||
|
onChanged: (newTime) {
|
||||||
|
if (newTime != null) {
|
||||||
|
setState(() {
|
||||||
|
_time = DateTime(
|
||||||
|
newTime.year,
|
||||||
|
newTime.month,
|
||||||
|
newTime.day,
|
||||||
|
_time.hour,
|
||||||
|
_time.minute);
|
||||||
|
});
|
||||||
|
updateTime();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Expanded(
|
||||||
|
child: Padding(
|
||||||
|
padding: const EdgeInsets.only(left: 5),
|
||||||
|
child: TimeOfDayFormField(
|
||||||
|
time: TimeOfDay.fromDateTime(_time),
|
||||||
|
label: 'Time',
|
||||||
|
controller: _timeController,
|
||||||
|
onChanged: (newTime) {
|
||||||
|
if (newTime != null) {
|
||||||
|
setState(() {
|
||||||
|
_time = DateTime(
|
||||||
|
_time.year,
|
||||||
|
_time.month,
|
||||||
|
_time.day,
|
||||||
|
newTime.hour,
|
||||||
|
newTime.minute);
|
||||||
|
});
|
||||||
|
updateTime();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
Row(
|
||||||
|
children: [
|
||||||
|
glucoseMeasurement == GlucoseMeasurement.mgPerDl ||
|
||||||
|
glucoseDisplayMode ==
|
||||||
|
GlucoseDisplayMode.both ||
|
||||||
|
glucoseDisplayMode ==
|
||||||
|
GlucoseDisplayMode.bothForDetail
|
||||||
|
? Expanded(
|
||||||
|
child: TextFormField(
|
||||||
|
decoration: const InputDecoration(
|
||||||
|
labelText: 'mg/dl',
|
||||||
|
suffixText: 'mg/dl',
|
||||||
|
),
|
||||||
|
controller: _mgPerDlController,
|
||||||
|
onChanged: (_) =>
|
||||||
|
convertBetweenMgPerDlAndMmolPerL(
|
||||||
|
calculateFrom:
|
||||||
|
GlucoseMeasurement.mgPerDl),
|
||||||
|
keyboardType:
|
||||||
|
const TextInputType.numberWithOptions(),
|
||||||
|
validator: (value) {
|
||||||
|
if (value!.trim().isEmpty &&
|
||||||
|
_mmolPerLController.text
|
||||||
|
.trim()
|
||||||
|
.isEmpty) {
|
||||||
|
return 'How many mg/dl or mmol/l does the rate make up for?';
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
},
|
||||||
|
),
|
||||||
|
)
|
||||||
|
: Container(),
|
||||||
|
glucoseDisplayMode == GlucoseDisplayMode.both ||
|
||||||
|
glucoseDisplayMode ==
|
||||||
|
GlucoseDisplayMode.bothForDetail
|
||||||
|
? IconButton(
|
||||||
|
onPressed: () =>
|
||||||
|
convertBetweenMgPerDlAndMmolPerL(
|
||||||
|
calculateFrom:
|
||||||
|
GlucoseMeasurement.mmolPerL),
|
||||||
|
icon: const Icon(Icons.calculate),
|
||||||
|
)
|
||||||
|
: Container(),
|
||||||
|
glucoseMeasurement == GlucoseMeasurement.mmolPerL ||
|
||||||
|
glucoseDisplayMode ==
|
||||||
|
GlucoseDisplayMode.both ||
|
||||||
|
glucoseDisplayMode ==
|
||||||
|
GlucoseDisplayMode.bothForDetail
|
||||||
|
? Expanded(
|
||||||
|
child: TextFormField(
|
||||||
|
decoration: const InputDecoration(
|
||||||
|
labelText: 'mmol/l',
|
||||||
|
suffixText: 'mmol/l',
|
||||||
|
),
|
||||||
|
controller: _mmolPerLController,
|
||||||
|
onChanged: (_) =>
|
||||||
|
convertBetweenMgPerDlAndMmolPerL(
|
||||||
|
calculateFrom:
|
||||||
|
GlucoseMeasurement.mmolPerL),
|
||||||
|
keyboardType:
|
||||||
|
const TextInputType.numberWithOptions(
|
||||||
|
decimal: true),
|
||||||
|
validator: (value) {
|
||||||
|
if (value!.trim().isEmpty &&
|
||||||
|
_mgPerDlController.text
|
||||||
|
.trim()
|
||||||
|
.isEmpty) {
|
||||||
|
return 'How many mg/dl or mmol/l does rhe rate make up for?';
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
},
|
||||||
|
),
|
||||||
|
)
|
||||||
|
: Container(),
|
||||||
|
glucoseDisplayMode == GlucoseDisplayMode.both ||
|
||||||
|
glucoseDisplayMode ==
|
||||||
|
GlucoseDisplayMode.bothForDetail
|
||||||
|
? IconButton(
|
||||||
|
onPressed: () =>
|
||||||
|
convertBetweenMgPerDlAndMmolPerL(
|
||||||
|
calculateFrom:
|
||||||
|
GlucoseMeasurement.mgPerDl),
|
||||||
|
icon: const Icon(Icons.calculate),
|
||||||
|
)
|
||||||
|
: Container(),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
TextFormField(
|
||||||
|
decoration: const InputDecoration(
|
||||||
|
labelText: 'Bolus Units',
|
||||||
|
suffixText: 'U',
|
||||||
|
),
|
||||||
|
controller: _bolusGlucoseController,
|
||||||
|
keyboardType: const TextInputType.numberWithOptions(
|
||||||
|
decimal: true),
|
||||||
|
),
|
||||||
|
// ignore: todo
|
||||||
|
// TODO: change field functionality according to time format
|
||||||
|
TextFormField(
|
||||||
|
decoration: const InputDecoration(
|
||||||
|
labelText: 'Delayed Bolus Duration',
|
||||||
|
suffixText: ' min',
|
||||||
|
),
|
||||||
|
controller: _delayedBolusDurationController,
|
||||||
|
keyboardType: TextInputType.number,
|
||||||
|
),
|
||||||
|
TextFormField(
|
||||||
|
decoration: const InputDecoration(
|
||||||
|
labelText: 'Delayed Bolus Units',
|
||||||
|
),
|
||||||
|
controller: _delayedBolusRateController,
|
||||||
|
keyboardType: const TextInputType.numberWithOptions(
|
||||||
|
decimal: true),
|
||||||
|
),
|
||||||
|
TextFormField(
|
||||||
|
controller: _notesController,
|
||||||
|
decoration: const InputDecoration(
|
||||||
|
labelText: 'Notes',
|
||||||
|
alignLabelWithHint: true,
|
||||||
|
),
|
||||||
|
keyboardType: TextInputType.multiline,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
]),
|
||||||
|
),
|
||||||
];
|
];
|
||||||
|
|
||||||
if (!_isNew) {
|
if (!_isNew) {
|
||||||
@ -272,8 +476,7 @@ class _LogEntryScreenState extends State<LogEntryScreen> {
|
|||||||
),
|
),
|
||||||
bottomNavigationBar: bottomNav,
|
bottomNavigationBar: bottomNav,
|
||||||
floatingActionButton: actionButton,
|
floatingActionButton: actionButton,
|
||||||
floatingActionButtonLocation:
|
floatingActionButtonLocation: FloatingActionButtonLocation.endFloat,
|
||||||
FloatingActionButtonLocation.endFloat,
|
|
||||||
);
|
);
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
@ -1,185 +0,0 @@
|
|||||||
import 'package:diameter/components/forms.dart';
|
|
||||||
import 'package:diameter/config.dart';
|
|
||||||
import 'package:diameter/settings.dart';
|
|
||||||
import 'package:diameter/utils/utils.dart';
|
|
||||||
import 'package:flutter/material.dart';
|
|
||||||
|
|
||||||
class LogEntryForm extends StatefulWidget {
|
|
||||||
final GlobalKey<FormState> formState;
|
|
||||||
final Map<String, TextEditingController> controllers;
|
|
||||||
|
|
||||||
const LogEntryForm(
|
|
||||||
{Key? key, required this.formState, required this.controllers})
|
|
||||||
: super(key: key);
|
|
||||||
|
|
||||||
@override
|
|
||||||
_LogEntryFormState createState() => _LogEntryFormState();
|
|
||||||
}
|
|
||||||
|
|
||||||
class _LogEntryFormState extends State<LogEntryForm> {
|
|
||||||
void convertBetweenMgPerDlAndMmolPerL({GlucoseMeasurement? calculateFrom}) {
|
|
||||||
int? mgPerDl;
|
|
||||||
double? mmolPerL;
|
|
||||||
final _mgPerDlController = widget.controllers['mgPerDl'];
|
|
||||||
final _mmolPerLController = widget.controllers['mmolPerL'];
|
|
||||||
|
|
||||||
if (calculateFrom != GlucoseMeasurement.mmolPerL &&
|
|
||||||
_mgPerDlController!.text != '') {
|
|
||||||
mgPerDl = int.tryParse(_mgPerDlController.text);
|
|
||||||
}
|
|
||||||
if (calculateFrom != GlucoseMeasurement.mgPerDl &&
|
|
||||||
_mmolPerLController!.text != '') {
|
|
||||||
mmolPerL = double.tryParse(_mmolPerLController.text);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mgPerDl != null && mmolPerL == null) {
|
|
||||||
setState(() {
|
|
||||||
_mmolPerLController!.text =
|
|
||||||
Utils.convertMgPerDlToMmolPerL(mgPerDl!).toString();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
if (mmolPerL != null && mgPerDl == null) {
|
|
||||||
setState(() {
|
|
||||||
_mgPerDlController!.text =
|
|
||||||
Utils.convertMmolPerLToMgPerDl(mmolPerL!).toString();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
// final _timeController = widget.controllers['time'];
|
|
||||||
final _mgPerDlController = widget.controllers['mgPerDl'];
|
|
||||||
final _mmolPerLController = widget.controllers['mmolPerL'];
|
|
||||||
final _bolusGlucoseController = widget.controllers['bolusGlucose'];
|
|
||||||
final _delayedBolusRateController = widget.controllers['delayedBolusRate'];
|
|
||||||
final _delayedBolusDurationController =
|
|
||||||
widget.controllers['delayedBolusDuration'];
|
|
||||||
final _notesController = widget.controllers['notes'];
|
|
||||||
|
|
||||||
return SingleChildScrollView(
|
|
||||||
child: Column(crossAxisAlignment: CrossAxisAlignment.stretch, children: <
|
|
||||||
Widget>[
|
|
||||||
StyledForm(
|
|
||||||
formState: widget.formState,
|
|
||||||
fields: [
|
|
||||||
// TODO: insert time picker
|
|
||||||
// Expanded(
|
|
||||||
// child: StyledTimeOfDayFormField(
|
|
||||||
// label: 'Time',
|
|
||||||
// controller: _timeController,
|
|
||||||
// onChanged: (newEndTime) {
|
|
||||||
// if (newEndTime != null) {
|
|
||||||
// setState(() {
|
|
||||||
// _endTime = newEndTime;
|
|
||||||
// });
|
|
||||||
// updateEndTime();
|
|
||||||
// }
|
|
||||||
//),
|
|
||||||
Row(
|
|
||||||
children: [
|
|
||||||
glucoseMeasurement == GlucoseMeasurement.mgPerDl ||
|
|
||||||
glucoseDisplayMode == GlucoseDisplayMode.both ||
|
|
||||||
glucoseDisplayMode == GlucoseDisplayMode.bothForDetail
|
|
||||||
? Expanded(
|
|
||||||
child: TextFormField(
|
|
||||||
decoration: const InputDecoration(
|
|
||||||
labelText: 'mg/dl',
|
|
||||||
suffixText: 'mg/dl',
|
|
||||||
),
|
|
||||||
controller: _mgPerDlController,
|
|
||||||
onChanged: (_) => convertBetweenMgPerDlAndMmolPerL(
|
|
||||||
calculateFrom: GlucoseMeasurement.mgPerDl),
|
|
||||||
keyboardType: const TextInputType.numberWithOptions(),
|
|
||||||
validator: (value) {
|
|
||||||
if (value!.trim().isEmpty &&
|
|
||||||
_mmolPerLController!.text.trim().isEmpty) {
|
|
||||||
return 'How many mg/dl or mmol/l does the rate make up for?';
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
},
|
|
||||||
),
|
|
||||||
)
|
|
||||||
: Container(),
|
|
||||||
glucoseDisplayMode == GlucoseDisplayMode.both ||
|
|
||||||
glucoseDisplayMode == GlucoseDisplayMode.bothForDetail
|
|
||||||
? IconButton(
|
|
||||||
onPressed: () => convertBetweenMgPerDlAndMmolPerL(
|
|
||||||
calculateFrom: GlucoseMeasurement.mmolPerL),
|
|
||||||
icon: const Icon(Icons.calculate),
|
|
||||||
)
|
|
||||||
: Container(),
|
|
||||||
glucoseMeasurement == GlucoseMeasurement.mmolPerL ||
|
|
||||||
glucoseDisplayMode == GlucoseDisplayMode.both ||
|
|
||||||
glucoseDisplayMode == GlucoseDisplayMode.bothForDetail
|
|
||||||
? Expanded(
|
|
||||||
child: TextFormField(
|
|
||||||
decoration: const InputDecoration(
|
|
||||||
labelText: 'mmol/l',
|
|
||||||
suffixText: 'mmol/l',
|
|
||||||
),
|
|
||||||
controller: _mmolPerLController,
|
|
||||||
onChanged: (_) => convertBetweenMgPerDlAndMmolPerL(
|
|
||||||
calculateFrom: GlucoseMeasurement.mmolPerL),
|
|
||||||
keyboardType: const TextInputType.numberWithOptions(
|
|
||||||
decimal: true),
|
|
||||||
validator: (value) {
|
|
||||||
if (value!.trim().isEmpty &&
|
|
||||||
_mgPerDlController!.text.trim().isEmpty) {
|
|
||||||
return 'How many mg/dl or mmol/l does rhe rate make up for?';
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
},
|
|
||||||
),
|
|
||||||
)
|
|
||||||
: Container(),
|
|
||||||
glucoseDisplayMode == GlucoseDisplayMode.both ||
|
|
||||||
glucoseDisplayMode == GlucoseDisplayMode.bothForDetail
|
|
||||||
? IconButton(
|
|
||||||
onPressed: () => convertBetweenMgPerDlAndMmolPerL(
|
|
||||||
calculateFrom: GlucoseMeasurement.mgPerDl),
|
|
||||||
icon: const Icon(Icons.calculate),
|
|
||||||
)
|
|
||||||
: Container(),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
TextFormField(
|
|
||||||
decoration: const InputDecoration(
|
|
||||||
labelText: 'Bolus Units',
|
|
||||||
suffixText: 'U',
|
|
||||||
),
|
|
||||||
controller: _bolusGlucoseController,
|
|
||||||
keyboardType:
|
|
||||||
const TextInputType.numberWithOptions(decimal: true),
|
|
||||||
),
|
|
||||||
// TODO: change field functionality according to time format
|
|
||||||
TextFormField(
|
|
||||||
decoration: const InputDecoration(
|
|
||||||
labelText: 'Delayed Bolus Duration',
|
|
||||||
suffixText: ' min',
|
|
||||||
),
|
|
||||||
controller: _delayedBolusDurationController,
|
|
||||||
keyboardType: TextInputType.number,
|
|
||||||
),
|
|
||||||
TextFormField(
|
|
||||||
decoration: const InputDecoration(
|
|
||||||
labelText: 'Delayed Bolus Units',
|
|
||||||
),
|
|
||||||
controller: _delayedBolusRateController,
|
|
||||||
keyboardType:
|
|
||||||
const TextInputType.numberWithOptions(decimal: true),
|
|
||||||
),
|
|
||||||
TextFormField(
|
|
||||||
controller: _notesController,
|
|
||||||
decoration: const InputDecoration(
|
|
||||||
labelText: 'Notes',
|
|
||||||
alignLabelWithHint: true,
|
|
||||||
),
|
|
||||||
keyboardType: TextInputType.multiline,
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
]),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
@ -114,10 +114,10 @@ class _LogEventDetailScreenState extends State<LogEventDetailScreen> {
|
|||||||
child: Column(
|
child: Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
StyledForm(
|
FormWrapper(
|
||||||
formState: _logEventForm,
|
formState: _logEventForm,
|
||||||
fields: [
|
fields: [
|
||||||
StyledDropdownButton<LogEventType>(
|
LabeledDropdownButton<LogEventType>(
|
||||||
selectedItem: _eventType,
|
selectedItem: _eventType,
|
||||||
label: 'Event Type',
|
label: 'Event Type',
|
||||||
items: _logEventTypes,
|
items: _logEventTypes,
|
||||||
@ -128,26 +128,14 @@ class _LogEventDetailScreenState extends State<LogEventDetailScreen> {
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
// StyledFutureDropdownButton<LogEventType>(
|
BooleanFormField(
|
||||||
// selectedItem: _eventType,
|
|
||||||
// label: 'Event Type',
|
|
||||||
// items: _logEventTypes,
|
|
||||||
// getItemValue: (item) => item.objectId,
|
|
||||||
// renderItem: (item) => Text(item.value),
|
|
||||||
// onChanged: (value) {
|
|
||||||
// setState(() {
|
|
||||||
// _eventType = value;
|
|
||||||
// });
|
|
||||||
// },
|
|
||||||
// ),
|
|
||||||
StyledBooleanFormField(
|
|
||||||
value: _hasEndTime,
|
value: _hasEndTime,
|
||||||
onChanged: (value) {
|
onChanged: (value) {
|
||||||
setState(() {
|
setState(() {
|
||||||
_hasEndTime = value;
|
_hasEndTime = value;
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
label: 'active',
|
label: 'has end time',
|
||||||
),
|
),
|
||||||
TextFormField(
|
TextFormField(
|
||||||
controller: _notesController,
|
controller: _notesController,
|
||||||
|
@ -68,7 +68,6 @@ class _LogEventListScreenState extends State<LogEventListScreen> {
|
|||||||
return Column(
|
return Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.center,
|
crossAxisAlignment: CrossAxisAlignment.center,
|
||||||
children: [
|
children: [
|
||||||
// TODO: add button for active events
|
|
||||||
Expanded(
|
Expanded(
|
||||||
child: (widget.logEntry.events.isNotEmpty || widget.logEntry.endedEvents.isNotEmpty)
|
child: (widget.logEntry.events.isNotEmpty || widget.logEntry.endedEvents.isNotEmpty)
|
||||||
? ListView.builder(
|
? ListView.builder(
|
||||||
|
@ -45,22 +45,6 @@ class _LogEventTypeDetailScreenState extends State<LogEventTypeDetailScreen> {
|
|||||||
});
|
});
|
||||||
if (_logEventTypeForm.currentState!.validate()) {
|
if (_logEventTypeForm.currentState!.validate()) {
|
||||||
bool isNew = widget.logEventType == null;
|
bool isNew = widget.logEventType == null;
|
||||||
// isNew
|
|
||||||
// ? await LogEventType.save(
|
|
||||||
// value: _valueController.text,
|
|
||||||
// notes: _notesController.text,
|
|
||||||
// defaultReminderDuration:
|
|
||||||
// int.tryParse(_defaultReminderDurationController.text),
|
|
||||||
// hasEndTime: _hasEndTime,
|
|
||||||
// )
|
|
||||||
// : await LogEventType.update(
|
|
||||||
// widget.logEventType!.objectId!,
|
|
||||||
// value: _valueController.text,
|
|
||||||
// notes: _notesController.text,
|
|
||||||
// defaultReminderDuration:
|
|
||||||
// int.tryParse(_defaultReminderDurationController.text),
|
|
||||||
// hasEndTime: _hasEndTime,
|
|
||||||
// );
|
|
||||||
LogEventType.put(LogEventType(
|
LogEventType.put(LogEventType(
|
||||||
id: widget.logEventType?.id ?? 0,
|
id: widget.logEventType?.id ?? 0,
|
||||||
value: _valueController.text,
|
value: _valueController.text,
|
||||||
@ -115,7 +99,7 @@ class _LogEventTypeDetailScreenState extends State<LogEventTypeDetailScreen> {
|
|||||||
child: Column(
|
child: Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
StyledForm(
|
FormWrapper(
|
||||||
formState: _logEventTypeForm,
|
formState: _logEventTypeForm,
|
||||||
fields: [
|
fields: [
|
||||||
TextFormField(
|
TextFormField(
|
||||||
@ -131,7 +115,7 @@ class _LogEventTypeDetailScreenState extends State<LogEventTypeDetailScreen> {
|
|||||||
return null;
|
return null;
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
StyledBooleanFormField(
|
BooleanFormField(
|
||||||
value: _hasEndTime,
|
value: _hasEndTime,
|
||||||
label: 'has end time',
|
label: 'has end time',
|
||||||
onChanged: (value) {
|
onChanged: (value) {
|
||||||
|
@ -315,7 +315,7 @@ class _LogMealDetailScreenState extends State<LogMealDetailScreen> {
|
|||||||
child: Column(
|
child: Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
StyledForm(
|
FormWrapper(
|
||||||
formState: _logMealForm,
|
formState: _logMealForm,
|
||||||
fields: [
|
fields: [
|
||||||
TextFormField(
|
TextFormField(
|
||||||
@ -330,7 +330,7 @@ class _LogMealDetailScreenState extends State<LogMealDetailScreen> {
|
|||||||
return null;
|
return null;
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
StyledDropdownButton<Meal>(
|
LabeledDropdownButton<Meal>(
|
||||||
selectedItem: _meal,
|
selectedItem: _meal,
|
||||||
label: 'Meal',
|
label: 'Meal',
|
||||||
items: _meals,
|
items: _meals,
|
||||||
@ -342,7 +342,7 @@ class _LogMealDetailScreenState extends State<LogMealDetailScreen> {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
StyledDropdownButton<MealSource>(
|
LabeledDropdownButton<MealSource>(
|
||||||
selectedItem: _mealSource,
|
selectedItem: _mealSource,
|
||||||
label: 'Meal Source',
|
label: 'Meal Source',
|
||||||
items: _mealSources,
|
items: _mealSources,
|
||||||
@ -354,7 +354,7 @@ class _LogMealDetailScreenState extends State<LogMealDetailScreen> {
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
StyledDropdownButton<MealCategory>(
|
LabeledDropdownButton<MealCategory>(
|
||||||
selectedItem: _mealCategory,
|
selectedItem: _mealCategory,
|
||||||
label: 'Meal Category',
|
label: 'Meal Category',
|
||||||
items: _mealCategories,
|
items: _mealCategories,
|
||||||
@ -366,7 +366,7 @@ class _LogMealDetailScreenState extends State<LogMealDetailScreen> {
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
StyledDropdownButton<MealPortionType>(
|
LabeledDropdownButton<MealPortionType>(
|
||||||
selectedItem: _mealPortionType,
|
selectedItem: _mealPortionType,
|
||||||
label: 'Meal Portion Type',
|
label: 'Meal Portion Type',
|
||||||
items: _mealPortionTypes,
|
items: _mealPortionTypes,
|
||||||
@ -434,7 +434,7 @@ class _LogMealDetailScreenState extends State<LogMealDetailScreen> {
|
|||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
StyledDropdownButton<Accuracy>(
|
LabeledDropdownButton<Accuracy>(
|
||||||
selectedItem: _portionSizeAccuracy,
|
selectedItem: _portionSizeAccuracy,
|
||||||
label: 'Portion Size Accuracy',
|
label: 'Portion Size Accuracy',
|
||||||
items: _portionSizeAccuracies,
|
items: _portionSizeAccuracies,
|
||||||
@ -488,7 +488,7 @@ class _LogMealDetailScreenState extends State<LogMealDetailScreen> {
|
|||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
StyledDropdownButton<Accuracy>(
|
LabeledDropdownButton<Accuracy>(
|
||||||
selectedItem: _carbsRatioAccuracy,
|
selectedItem: _carbsRatioAccuracy,
|
||||||
label: 'Carbs Ratio Accuracy',
|
label: 'Carbs Ratio Accuracy',
|
||||||
items: _carbsRatioAccuracies,
|
items: _carbsRatioAccuracies,
|
||||||
|
@ -78,7 +78,7 @@ class _MealCategoryDetailScreenState extends State<MealCategoryDetailScreen> {
|
|||||||
child: Column(
|
child: Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
StyledForm(
|
FormWrapper(
|
||||||
formState: _mealCategoryForm,
|
formState: _mealCategoryForm,
|
||||||
fields: [
|
fields: [
|
||||||
TextFormField(
|
TextFormField(
|
||||||
|
@ -266,7 +266,7 @@ class _MealDetailScreenState extends State<MealDetailScreen> {
|
|||||||
child: Column(
|
child: Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
StyledForm(
|
FormWrapper(
|
||||||
formState: _mealForm,
|
formState: _mealForm,
|
||||||
fields: [
|
fields: [
|
||||||
TextFormField(
|
TextFormField(
|
||||||
@ -281,7 +281,7 @@ class _MealDetailScreenState extends State<MealDetailScreen> {
|
|||||||
return null;
|
return null;
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
StyledDropdownButton<MealSource>(
|
LabeledDropdownButton<MealSource>(
|
||||||
selectedItem: _mealSource,
|
selectedItem: _mealSource,
|
||||||
label: 'Meal Source',
|
label: 'Meal Source',
|
||||||
items: _mealSources,
|
items: _mealSources,
|
||||||
@ -293,7 +293,7 @@ class _MealDetailScreenState extends State<MealDetailScreen> {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
StyledDropdownButton<MealCategory>(
|
LabeledDropdownButton<MealCategory>(
|
||||||
selectedItem: _mealCategory,
|
selectedItem: _mealCategory,
|
||||||
label: 'Meal Category',
|
label: 'Meal Category',
|
||||||
items: _mealCategories,
|
items: _mealCategories,
|
||||||
@ -305,7 +305,7 @@ class _MealDetailScreenState extends State<MealDetailScreen> {
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
StyledDropdownButton<MealPortionType>(
|
LabeledDropdownButton<MealPortionType>(
|
||||||
selectedItem: _mealPortionType,
|
selectedItem: _mealPortionType,
|
||||||
label: 'Meal Portion Type',
|
label: 'Meal Portion Type',
|
||||||
items: _mealPortionTypes,
|
items: _mealPortionTypes,
|
||||||
@ -373,7 +373,7 @@ class _MealDetailScreenState extends State<MealDetailScreen> {
|
|||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
StyledDropdownButton<Accuracy>(
|
LabeledDropdownButton<Accuracy>(
|
||||||
selectedItem: _portionSizeAccuracy,
|
selectedItem: _portionSizeAccuracy,
|
||||||
label: 'Portion Size Accuracy',
|
label: 'Portion Size Accuracy',
|
||||||
items: _portionSizeAccuracies,
|
items: _portionSizeAccuracies,
|
||||||
@ -385,18 +385,6 @@ class _MealDetailScreenState extends State<MealDetailScreen> {
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
// StyledFutureDropdownButton<Accuracy>(
|
|
||||||
// selectedItem: _portionSizeAccuracy,
|
|
||||||
// label: 'Portion Size Accuracy',
|
|
||||||
// items: _portionSizeAccuracies,
|
|
||||||
// getItemValue: (item) => item.objectId,
|
|
||||||
// renderItem: (item) => Text(item.value),
|
|
||||||
// onChanged: (value) {
|
|
||||||
// setState(() {
|
|
||||||
// _portionSizeAccuracy = value;
|
|
||||||
// });
|
|
||||||
// },
|
|
||||||
// ),
|
|
||||||
Row(
|
Row(
|
||||||
children: [
|
children: [
|
||||||
Expanded(
|
Expanded(
|
||||||
@ -427,7 +415,7 @@ class _MealDetailScreenState extends State<MealDetailScreen> {
|
|||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
StyledDropdownButton<Accuracy>(
|
LabeledDropdownButton<Accuracy>(
|
||||||
selectedItem: _carbsRatioAccuracy,
|
selectedItem: _carbsRatioAccuracy,
|
||||||
label: 'Carbs Ratio Accuracy',
|
label: 'Carbs Ratio Accuracy',
|
||||||
items: _carbsRatioAccuracies,
|
items: _carbsRatioAccuracies,
|
||||||
@ -439,18 +427,7 @@ class _MealDetailScreenState extends State<MealDetailScreen> {
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
// StyledFutureDropdownButton<Accuracy>(
|
// ignore: todo
|
||||||
// selectedItem: _carbsRatioAccuracy,
|
|
||||||
// label: 'Carbs Ratio Accuracy',
|
|
||||||
// items: _carbsRatioAccuracies,
|
|
||||||
// getItemValue: (item) => item.objectId,
|
|
||||||
// renderItem: (item) => Text(item.value),
|
|
||||||
// onChanged: (value) {
|
|
||||||
// setState(() {
|
|
||||||
// _carbsRatioAccuracy = value;
|
|
||||||
// });
|
|
||||||
// },
|
|
||||||
// ),
|
|
||||||
// TODO: display according to time format
|
// TODO: display according to time format
|
||||||
TextFormField(
|
TextFormField(
|
||||||
decoration: const InputDecoration(
|
decoration: const InputDecoration(
|
||||||
|
@ -89,7 +89,7 @@ class _MealPortionTypeDetailScreenState
|
|||||||
child: Column(
|
child: Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
StyledForm(
|
FormWrapper(
|
||||||
formState: _mealPortionTypeForm,
|
formState: _mealPortionTypeForm,
|
||||||
fields: [
|
fields: [
|
||||||
TextFormField(
|
TextFormField(
|
||||||
|
@ -145,7 +145,7 @@ class _MealSourceDetailScreenState extends State<MealSourceDetailScreen> {
|
|||||||
child: Column(
|
child: Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
StyledForm(
|
FormWrapper(
|
||||||
formState: _mealSourceForm,
|
formState: _mealSourceForm,
|
||||||
fields: [
|
fields: [
|
||||||
TextFormField(
|
TextFormField(
|
||||||
@ -160,7 +160,7 @@ class _MealSourceDetailScreenState extends State<MealSourceDetailScreen> {
|
|||||||
return null;
|
return null;
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
StyledDropdownButton<Accuracy>(
|
LabeledDropdownButton<Accuracy>(
|
||||||
selectedItem: _defaultCarbsRatioAccuracy,
|
selectedItem: _defaultCarbsRatioAccuracy,
|
||||||
label: 'Default Carbs Ratio Accuracy',
|
label: 'Default Carbs Ratio Accuracy',
|
||||||
items: _carbsRatioAccuracies,
|
items: _carbsRatioAccuracies,
|
||||||
@ -171,7 +171,7 @@ class _MealSourceDetailScreenState extends State<MealSourceDetailScreen> {
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
StyledDropdownButton<Accuracy>(
|
LabeledDropdownButton<Accuracy>(
|
||||||
selectedItem: _defaultPortionSizeAccuracy,
|
selectedItem: _defaultPortionSizeAccuracy,
|
||||||
label: 'Default Portion Size Accuracy',
|
label: 'Default Portion Size Accuracy',
|
||||||
items: _portionSizeAccuracies,
|
items: _portionSizeAccuracies,
|
||||||
@ -206,7 +206,7 @@ class _MealSourceDetailScreenState extends State<MealSourceDetailScreen> {
|
|||||||
// });
|
// });
|
||||||
// },
|
// },
|
||||||
// ),
|
// ),
|
||||||
StyledDropdownButton<MealCategory>(
|
LabeledDropdownButton<MealCategory>(
|
||||||
selectedItem: _defaultMealCategory,
|
selectedItem: _defaultMealCategory,
|
||||||
label: 'Default Meal Category',
|
label: 'Default Meal Category',
|
||||||
items: _mealCategories,
|
items: _mealCategories,
|
||||||
@ -218,7 +218,7 @@ class _MealSourceDetailScreenState extends State<MealSourceDetailScreen> {
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
StyledDropdownButton<MealPortionType>(
|
LabeledDropdownButton<MealPortionType>(
|
||||||
selectedItem: _defaultMealPortionType,
|
selectedItem: _defaultMealPortionType,
|
||||||
label: 'Default Meal Portion Type',
|
label: 'Default Meal Portion Type',
|
||||||
items: _mealPortionTypes,
|
items: _mealPortionTypes,
|
||||||
|
@ -127,10 +127,10 @@ class _SettingsScreenState extends State<SettingsScreen> {
|
|||||||
child: Column(
|
child: Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
StyledForm(
|
FormWrapper(
|
||||||
formState: _settingsForm,
|
formState: _settingsForm,
|
||||||
fields: [
|
fields: [
|
||||||
StyledDropdownButton<NutritionMeasurement>(
|
LabeledDropdownButton<NutritionMeasurement>(
|
||||||
selectedItem: nutritionMeasurement,
|
selectedItem: nutritionMeasurement,
|
||||||
label: 'Preferred Nutrition Measurement',
|
label: 'Preferred Nutrition Measurement',
|
||||||
items: NutritionMeasurement.values,
|
items: NutritionMeasurement.values,
|
||||||
@ -144,7 +144,7 @@ class _SettingsScreenState extends State<SettingsScreen> {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
StyledDropdownButton<GlucoseMeasurement>(
|
LabeledDropdownButton<GlucoseMeasurement>(
|
||||||
selectedItem: glucoseMeasurement,
|
selectedItem: glucoseMeasurement,
|
||||||
label: 'Preferred Glucose Measurement',
|
label: 'Preferred Glucose Measurement',
|
||||||
items: GlucoseMeasurement.values,
|
items: GlucoseMeasurement.values,
|
||||||
@ -158,7 +158,7 @@ class _SettingsScreenState extends State<SettingsScreen> {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
StyledBooleanFormField(
|
BooleanFormField(
|
||||||
value: glucoseDisplayMode == GlucoseDisplayMode.activeOnly,
|
value: glucoseDisplayMode == GlucoseDisplayMode.activeOnly,
|
||||||
label: 'only display active glucose measurement',
|
label: 'only display active glucose measurement',
|
||||||
onChanged: (_) {
|
onChanged: (_) {
|
||||||
@ -172,7 +172,7 @@ class _SettingsScreenState extends State<SettingsScreen> {
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
StyledBooleanFormField(
|
BooleanFormField(
|
||||||
value: glucoseDisplayMode == GlucoseDisplayMode.both ||
|
value: glucoseDisplayMode == GlucoseDisplayMode.both ||
|
||||||
glucoseDisplayMode == GlucoseDisplayMode.bothForDetail,
|
glucoseDisplayMode == GlucoseDisplayMode.bothForDetail,
|
||||||
enabled: glucoseDisplayMode != GlucoseDisplayMode.activeOnly,
|
enabled: glucoseDisplayMode != GlucoseDisplayMode.activeOnly,
|
||||||
@ -190,7 +190,7 @@ class _SettingsScreenState extends State<SettingsScreen> {
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
StyledBooleanFormField(
|
BooleanFormField(
|
||||||
value: glucoseDisplayMode == GlucoseDisplayMode.both ||
|
value: glucoseDisplayMode == GlucoseDisplayMode.both ||
|
||||||
glucoseDisplayMode == GlucoseDisplayMode.bothForList,
|
glucoseDisplayMode == GlucoseDisplayMode.bothForList,
|
||||||
enabled: glucoseDisplayMode != GlucoseDisplayMode.activeOnly,
|
enabled: glucoseDisplayMode != GlucoseDisplayMode.activeOnly,
|
||||||
@ -208,8 +208,6 @@ class _SettingsScreenState extends State<SettingsScreen> {
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
// TODO: add fields for date and time formats
|
|
||||||
// TODO: add fields for glucose target
|
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
Loading…
Reference in New Issue
Block a user