calorimeter/lib/food_entry/enter_food_widget.dart

144 lines
4.9 KiB
Dart
Raw Normal View History

import 'package:calorimeter/perdate/perdate_widget.dart';
2024-09-06 17:00:25 +00:00
import 'package:calorimeter/storage/storage.dart';
import 'package:flutter/material.dart';
2024-09-06 17:00:25 +00:00
import 'package:calorimeter/food_entry/food_entry_bloc.dart';
2024-09-06 16:51:24 +00:00
import 'package:calorimeter/utils/row_with_spacers_widget.dart';
import 'package:provider/provider.dart';
class EnterFoodWidget extends StatefulWidget {
2024-06-09 17:06:10 +00:00
final Function(BuildContext context, FoodEntry entry) onAdd;
const EnterFoodWidget({super.key, required this.onAdd});
@override
State<EnterFoodWidget> createState() => _EnterFoodWidgetState();
}
class _EnterFoodWidgetState extends State<EnterFoodWidget> {
late TextEditingController nameController;
late TextEditingController massController;
late TextEditingController kcalPerMassController;
late Map<String, double> suggestions;
@override
void initState() {
nameController = TextEditingController();
massController = TextEditingController();
kcalPerMassController = TextEditingController();
suggestions = FoodStorage.getInstance().getFoodEntryLookupDatabase;
super.initState();
}
2024-06-01 10:41:58 +00:00
@override
Widget build(BuildContext context) {
return Consumer<EnterFoodController>(
builder: (context, food, child) {
nameController.text = food.name;
kcalPerMassController.text = food.kcalPer100g;
return Padding(
padding: const EdgeInsets.symmetric(horizontal: 8.0),
child: RowWidget(
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]!;
context
.read<EnterFoodController>()
.set(selectedFood, kcalPerMassForSelectedFood.toString());
}),
TextField(
textAlign: TextAlign.end,
decoration: const InputDecoration(
label: Align(
alignment: Alignment.centerRight, child: Text("Menge")),
),
keyboardType: TextInputType.number,
controller: massController,
onSubmitted: (value) => onSubmitAction(),
),
TextField(
textAlign: TextAlign.end,
decoration: const InputDecoration(
label: Align(
alignment: Alignment.centerRight,
child: Text("kcal pro"))),
keyboardType: TextInputType.number,
controller: kcalPerMassController,
onSubmitted: (value) => onSubmitAction(),
),
Padding(
padding: const EdgeInsets.only(left: 16.0),
child: ElevatedButton(
style: ElevatedButton.styleFrom(
padding: EdgeInsets.zero,
),
onPressed: () => onSubmitAction(),
child: const Icon(Icons.add)),
),
),
);
},
);
}
void onSubmitAction() {
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;
}
var entry = FoodEntry(
name: nameController.text,
mass: massAsNumber,
kcalPerMass: kcalPerMassAsNumber);
widget.onAdd(context, entry);
context.read<EnterFoodController>().set("", "");
}
}