Marco
b83f547f6b
Now, an on-the-fly food lookup is created from existing entries on startup. Those entries are used to make suggestions when the user is typing to enter new food entries.
133 lines
4.3 KiB
Dart
133 lines
4.3 KiB
Dart
import 'dart:developer';
|
|
|
|
import 'package:calodiary/storage/storage.dart';
|
|
import 'package:flutter/material.dart';
|
|
import 'package:calodiary/food_entry_bloc.dart';
|
|
import 'package:calodiary/row_with_spacers_widget.dart';
|
|
|
|
class EnterFoodWidget extends StatefulWidget {
|
|
final Function(BuildContext context, FoodEntry entry) onAdd;
|
|
|
|
const EnterFoodWidget({super.key, required this.onAdd});
|
|
|
|
@override
|
|
State<EnterFoodWidget> createState() => _EnterFoodWidgetState();
|
|
}
|
|
|
|
class _EnterFoodWidgetState extends State<EnterFoodWidget> {
|
|
String perFoodresult = "dings";
|
|
TextEditingController nameController = TextEditingController();
|
|
TextEditingController massController = TextEditingController();
|
|
TextEditingController kcalPerMassController = TextEditingController();
|
|
Map<String, double> suggestions = {};
|
|
|
|
@override
|
|
void initState() {
|
|
suggestions = FoodStorage.getInstance().getFoodEntryLookupDatabase;
|
|
super.initState();
|
|
}
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
var nameWidget = Autocomplete<String>(
|
|
optionsViewOpenDirection: OptionsViewOpenDirection.down,
|
|
fieldViewBuilder: (context, controller, focusNode, onSubmitted) {
|
|
nameController = controller;
|
|
return TextFormField(
|
|
controller: controller,
|
|
focusNode: focusNode,
|
|
decoration: const InputDecoration(label: Text("Name")));
|
|
},
|
|
optionsBuilder: (TextEditingValue textEditingValue) {
|
|
if (textEditingValue.text == '') {
|
|
return const Iterable<String>.empty();
|
|
}
|
|
|
|
return suggestions.keys.where(
|
|
(name) {
|
|
return name
|
|
.toLowerCase()
|
|
.contains(textEditingValue.text.toLowerCase());
|
|
},
|
|
);
|
|
},
|
|
onSelected: (selectedFood) {
|
|
double kcalPerMassForSelectedFood = suggestions[selectedFood]!;
|
|
setState(() {
|
|
kcalPerMassController.text = kcalPerMassForSelectedFood.toString();
|
|
});
|
|
});
|
|
|
|
var massWidget = TextField(
|
|
decoration: const InputDecoration(label: Text("Menge")),
|
|
keyboardType: TextInputType.number,
|
|
controller: massController,
|
|
);
|
|
|
|
var kcalPerMassWidget = TextField(
|
|
decoration: const InputDecoration(label: Text("kcal pro")),
|
|
keyboardType: TextInputType.number,
|
|
controller: kcalPerMassController);
|
|
|
|
var enterButton = ElevatedButton(
|
|
style: ElevatedButton.styleFrom(
|
|
padding: EdgeInsets.zero,
|
|
),
|
|
onPressed: () {
|
|
double massAsNumber = 0.0;
|
|
double kcalPerMassAsNumber = 0.0;
|
|
|
|
try {
|
|
massAsNumber =
|
|
double.parse(massController.text.replaceAll(",", "."));
|
|
} catch (e) {
|
|
var snackbar =
|
|
const SnackBar(content: Text("Menge muss eine Zahl sein"));
|
|
ScaffoldMessenger.of(context).clearSnackBars();
|
|
ScaffoldMessenger.of(context).showSnackBar(snackbar);
|
|
return;
|
|
}
|
|
|
|
try {
|
|
kcalPerMassAsNumber =
|
|
double.parse(kcalPerMassController.text.replaceAll(",", "."));
|
|
} catch (e) {
|
|
var snackbar = const SnackBar(
|
|
content: Text("'kcal pro 100g' muss eine Zahl sein"));
|
|
ScaffoldMessenger.of(context).clearSnackBars();
|
|
ScaffoldMessenger.of(context).showSnackBar(snackbar);
|
|
return;
|
|
}
|
|
try {
|
|
massAsNumber =
|
|
double.parse(massController.text.replaceAll(",", "."));
|
|
} catch (e) {
|
|
var snackbar =
|
|
const SnackBar(content: Text("Menge muss eine Zahl sein"));
|
|
ScaffoldMessenger.of(context).clearSnackBars();
|
|
ScaffoldMessenger.of(context).showSnackBar(snackbar);
|
|
return;
|
|
}
|
|
|
|
var entry = FoodEntry(
|
|
name: nameController.text,
|
|
mass: massAsNumber,
|
|
kcalPerMass: kcalPerMassAsNumber);
|
|
|
|
widget.onAdd(context, entry);
|
|
},
|
|
child: const Icon(Icons.add));
|
|
|
|
return Padding(
|
|
padding: const EdgeInsets.only(left: 8.0, right: 4.0),
|
|
child: RowWidget(
|
|
nameWidget,
|
|
massWidget,
|
|
kcalPerMassWidget,
|
|
null,
|
|
enterButton,
|
|
),
|
|
);
|
|
}
|
|
}
|