mirror of
https://github.com/wger-project/flutter.git
synced 2026-02-18 00:17:48 +01:00
Merge pull request #89 from ThilinaTCH/master
Allow user to give meals a description #70
This commit is contained in:
@@ -36,6 +36,9 @@ class Meal {
|
||||
@JsonKey(toJson: timeToString, fromJson: stringToTime)
|
||||
TimeOfDay? time;
|
||||
|
||||
@JsonKey(name: 'name')
|
||||
late String name;
|
||||
|
||||
@JsonKey(ignore: true, name: 'meal_items', defaultValue: [])
|
||||
List<MealItem> mealItems = [];
|
||||
|
||||
@@ -43,6 +46,7 @@ class Meal {
|
||||
this.id,
|
||||
int? plan,
|
||||
TimeOfDay? time,
|
||||
String? name,
|
||||
List<MealItem>? mealItems,
|
||||
}) {
|
||||
if (plan != null) {
|
||||
@@ -52,10 +56,12 @@ class Meal {
|
||||
this.mealItems = mealItems ?? [];
|
||||
|
||||
this.time = time ?? TimeOfDay.now();
|
||||
this.name = name ?? '';
|
||||
}
|
||||
|
||||
// Boilerplate
|
||||
factory Meal.fromJson(Map<String, dynamic> json) => _$MealFromJson(json);
|
||||
|
||||
Map<String, dynamic> toJson() => _$MealToJson(this);
|
||||
|
||||
/// Calculations
|
||||
|
||||
@@ -10,6 +10,7 @@ Meal _$MealFromJson(Map<String, dynamic> json) {
|
||||
return Meal(
|
||||
id: json['id'] as int?,
|
||||
time: stringToTime(json['time'] as String?),
|
||||
name: json['name'] as String?,
|
||||
)..planId = json['plan'] as int;
|
||||
}
|
||||
|
||||
@@ -17,4 +18,5 @@ Map<String, dynamic> _$MealToJson(Meal instance) => <String, dynamic>{
|
||||
'id': instance.id,
|
||||
'plan': instance.planId,
|
||||
'time': timeToString(instance.time),
|
||||
'name': instance.name,
|
||||
};
|
||||
|
||||
@@ -36,10 +36,12 @@ class MealForm extends StatelessWidget {
|
||||
|
||||
final _form = GlobalKey<FormState>();
|
||||
final _timeController = TextEditingController();
|
||||
final _nameController = TextEditingController();
|
||||
|
||||
MealForm(this._planId, [meal]) {
|
||||
_meal = meal ?? Meal(plan: _planId);
|
||||
_timeController.text = timeToString(_meal.time)!;
|
||||
_nameController.text = _meal.name;
|
||||
}
|
||||
|
||||
@override
|
||||
@@ -71,6 +73,16 @@ class MealForm extends StatelessWidget {
|
||||
},
|
||||
onFieldSubmitted: (_) {},
|
||||
),
|
||||
TextFormField(
|
||||
maxLength: 25,
|
||||
key: Key('field-name'),
|
||||
decoration: InputDecoration(labelText: AppLocalizations.of(context).name),
|
||||
controller: _nameController,
|
||||
onSaved: (newValue) {
|
||||
_meal.name = newValue as String;
|
||||
},
|
||||
onFieldSubmitted: (_) {},
|
||||
),
|
||||
ElevatedButton(
|
||||
key: Key(SUBMIT_BUTTON_KEY_NAME),
|
||||
child: Text(AppLocalizations.of(context).save),
|
||||
@@ -82,8 +94,7 @@ class MealForm extends StatelessWidget {
|
||||
|
||||
try {
|
||||
_meal.id == null
|
||||
? Provider.of<NutritionPlansProvider>(context, listen: false)
|
||||
.addMeal(_meal, _planId)
|
||||
? Provider.of<NutritionPlansProvider>(context, listen: false).addMeal(_meal, _planId)
|
||||
: Provider.of<NutritionPlansProvider>(context, listen: false).editMeal(_meal);
|
||||
} on WgerHttpException catch (error) {
|
||||
showHttpExceptionErrorDialog(error, context);
|
||||
@@ -178,8 +189,7 @@ class MealItemForm extends StatelessWidget {
|
||||
_form.currentState!.save();
|
||||
|
||||
try {
|
||||
Provider.of<NutritionPlansProvider>(context, listen: false)
|
||||
.addMealItem(_mealItem, _meal);
|
||||
Provider.of<NutritionPlansProvider>(context, listen: false).addMealItem(_mealItem, _meal);
|
||||
} on WgerHttpException catch (error) {
|
||||
showHttpExceptionErrorDialog(error, context);
|
||||
} catch (error) {
|
||||
@@ -238,8 +248,7 @@ class PlanForm extends StatelessWidget {
|
||||
await Provider.of<NutritionPlansProvider>(context, listen: false).editPlan(_plan);
|
||||
Navigator.of(context).pop();
|
||||
} else {
|
||||
_plan = await Provider.of<NutritionPlansProvider>(context, listen: false)
|
||||
.addPlan(_plan);
|
||||
_plan = await Provider.of<NutritionPlansProvider>(context, listen: false).addPlan(_plan);
|
||||
Navigator.of(context).pushReplacementNamed(
|
||||
NutritionalPlanScreen.routeName,
|
||||
arguments: _plan,
|
||||
|
||||
@@ -41,6 +41,7 @@ class MealWidget extends StatefulWidget {
|
||||
|
||||
class _MealWidgetState extends State<MealWidget> {
|
||||
bool _expanded = false;
|
||||
|
||||
void _toggleExpanded() {
|
||||
setState(() {
|
||||
_expanded = !_expanded;
|
||||
@@ -63,8 +64,7 @@ class _MealWidgetState extends State<MealWidget> {
|
||||
IconButton(
|
||||
onPressed: () {
|
||||
// Delete the meal
|
||||
Provider.of<NutritionPlansProvider>(context, listen: false)
|
||||
.deleteMeal(widget._meal);
|
||||
Provider.of<NutritionPlansProvider>(context, listen: false).deleteMeal(widget._meal);
|
||||
|
||||
// and inform the user
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
@@ -88,8 +88,7 @@ class _MealWidgetState extends State<MealWidget> {
|
||||
icon: const Icon(Icons.history_edu),
|
||||
color: Colors.white,
|
||||
onPressed: () {
|
||||
Provider.of<NutritionPlansProvider>(context, listen: false)
|
||||
.logMealToDiary(widget._meal);
|
||||
Provider.of<NutritionPlansProvider>(context, listen: false).logMealToDiary(widget._meal);
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(
|
||||
content: Text(
|
||||
@@ -178,8 +177,7 @@ class MealItemWidget extends StatelessWidget {
|
||||
iconSize: ICON_SIZE_SMALL,
|
||||
onPressed: () {
|
||||
// Delete the meal item
|
||||
Provider.of<NutritionPlansProvider>(context, listen: false)
|
||||
.deleteMealItem(_item);
|
||||
Provider.of<NutritionPlansProvider>(context, listen: false).deleteMealItem(_item);
|
||||
|
||||
// and inform the user
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
@@ -221,20 +219,30 @@ class DismissibleMealHeader extends StatelessWidget {
|
||||
child: Container(
|
||||
padding: const EdgeInsets.all(10),
|
||||
decoration: BoxDecoration(color: Colors.white),
|
||||
child: Row(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Expanded(
|
||||
child: Text(
|
||||
_meal.time!.format(context),
|
||||
if (_meal.name != '')
|
||||
Text(
|
||||
_meal.name,
|
||||
style: Theme.of(context).textTheme.headline5,
|
||||
),
|
||||
),
|
||||
IconButton(
|
||||
visualDensity: VisualDensity.compact,
|
||||
icon: _expanded ? Icon(Icons.unfold_less) : Icon(Icons.unfold_more),
|
||||
onPressed: () {
|
||||
_toggle();
|
||||
},
|
||||
Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: Text(
|
||||
_meal.time!.format(context),
|
||||
style: Theme.of(context).textTheme.headline5,
|
||||
),
|
||||
),
|
||||
IconButton(
|
||||
visualDensity: VisualDensity.compact,
|
||||
icon: _expanded ? Icon(Icons.unfold_less) : Icon(Icons.unfold_more),
|
||||
onPressed: () {
|
||||
_toggle();
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
|
||||
@@ -72,7 +72,7 @@ void main() {
|
||||
await tester.pumpWidget(createHomeScreen(meal1));
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
expect(find.byType(TextFormField), findsOneWidget);
|
||||
expect(find.byType(TextFormField), findsNWidgets(2));
|
||||
expect(find.byType(ElevatedButton), findsOneWidget);
|
||||
expect(find.byKey(Key(SUBMIT_BUTTON_KEY_NAME)), findsOneWidget);
|
||||
});
|
||||
@@ -86,7 +86,15 @@ void main() {
|
||||
findsOneWidget,
|
||||
reason: 'Time of existing meal is filled in',
|
||||
);
|
||||
|
||||
expect(
|
||||
find.text(('Initial Name 1')),
|
||||
findsOneWidget,
|
||||
reason: 'Time of existing meal is filled in',
|
||||
);
|
||||
|
||||
await tester.enterText(find.byKey(Key('field-time')), '12:34');
|
||||
await tester.enterText(find.byKey(Key('field-name')), 'test meal');
|
||||
await tester.tap(find.byKey(Key(SUBMIT_BUTTON_KEY_NAME)));
|
||||
|
||||
// Correct method was called
|
||||
@@ -105,6 +113,7 @@ void main() {
|
||||
);
|
||||
|
||||
await tester.enterText(find.byKey(Key('field-time')), '08:00');
|
||||
await tester.enterText(find.byKey(Key('field-name')), 'test meal');
|
||||
await tester.tap(find.byKey(Key(SUBMIT_BUTTON_KEY_NAME)));
|
||||
|
||||
// Correct method was called
|
||||
|
||||
@@ -86,6 +86,7 @@ NutritionalPlan getNutritionalPlan() {
|
||||
id: 1,
|
||||
plan: 1,
|
||||
time: TimeOfDay(hour: 17, minute: 0),
|
||||
name: 'Initial Name 1',
|
||||
);
|
||||
meal1.mealItems = [mealItem1, mealItem2];
|
||||
|
||||
@@ -93,6 +94,7 @@ NutritionalPlan getNutritionalPlan() {
|
||||
id: 2,
|
||||
plan: 1,
|
||||
time: TimeOfDay(hour: 22, minute: 5),
|
||||
name: 'Initial Name 2',
|
||||
);
|
||||
meal2.mealItems = [mealItem3];
|
||||
|
||||
|
||||
Reference in New Issue
Block a user