Skip to content

Commit

Permalink
Merge pull request #130 from doktormerlin/feature/copy-meals-without-…
Browse files Browse the repository at this point in the history
…appname-change

Feature: Copy meals to today from Diary
  • Loading branch information
simonoppowa authored Dec 19, 2024
2 parents 5b2942c + 8a9e8a8 commit 0637043
Show file tree
Hide file tree
Showing 11 changed files with 263 additions and 13 deletions.
55 changes: 55 additions & 0 deletions lib/core/presentation/widgets/copy_dialog.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import 'package:flutter/material.dart';
import 'package:opennutritracker/features/add_meal/presentation/add_meal_type.dart';
import 'package:opennutritracker/generated/l10n.dart';

class CopyDialog extends StatefulWidget {
const CopyDialog({super.key});
@override
State<StatefulWidget> createState() {
return CopyDialogState();
}
}

class CopyDialogState extends State<CopyDialog> {
AddMealType _selectedValue = AddMealType.breakfastType;
AddMealType get selectedMealType => _selectedValue;

@override
void initState() {
super.initState();
}

@override
Widget build(
BuildContext context,
) {
return AlertDialog(
title: Text(S.of(context).copyDialogTitle),
content: DropdownButton<AddMealType>(
value: _selectedValue,
onChanged: (AddMealType? addMealType) {
if (addMealType != null) {
setState(() {
_selectedValue = addMealType;
});
}
},
items: AddMealType.values.map((AddMealType addMealType) {
return DropdownMenuItem(
value: addMealType,
child: Text(addMealType.getTypeName(context)));
}).toList()),
actions: [
TextButton(
onPressed: () {
Navigator.of(context).pop(_selectedValue);
},
child: Text(S.of(context).dialogOKLabel)),
TextButton(
onPressed: () {
Navigator.of(context).pop();
},
child: Text(S.of(context).dialogCancelLabel))
]);
}
}
26 changes: 26 additions & 0 deletions lib/core/presentation/widgets/copy_or_delete_dialog.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import 'package:flutter/material.dart';
import 'package:opennutritracker/generated/l10n.dart';

class CopyOrDeleteDialog extends StatelessWidget {
const CopyOrDeleteDialog({super.key});

@override
Widget build(BuildContext context) {
return AlertDialog(
title: Text(S.of(context).copyOrDeleteTimeDialogTitle),
content: Text(S.of(context).copyOrDeleteTimeDialogContent),
actions: [
TextButton(
onPressed: () {
Navigator.of(context).pop(true);
},
child: Text(S.of(context).dialogCopyLabel)),
TextButton(
onPressed: () {
Navigator.of(context).pop(false);
},
child: Text(S.of(context).dialogDeleteLabel))
],
);
}
}
31 changes: 31 additions & 0 deletions lib/features/diary/diary_page.dart
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,16 @@ import 'package:opennutritracker/core/domain/entity/intake_entity.dart';
import 'package:opennutritracker/core/domain/entity/tracked_day_entity.dart';
import 'package:opennutritracker/core/domain/entity/user_activity_entity.dart';
import 'package:opennutritracker/core/utils/locator.dart';
import 'package:opennutritracker/features/add_meal/presentation/add_meal_type.dart';
import 'package:opennutritracker/features/diary/presentation/bloc/calendar_day_bloc.dart';
import 'package:opennutritracker/features/diary/presentation/bloc/diary_bloc.dart';
import 'package:opennutritracker/features/diary/presentation/widgets/diary_table_calendar.dart';
import 'package:opennutritracker/features/diary/presentation/widgets/day_info_widget.dart';
import 'package:opennutritracker/features/meal_detail/presentation/bloc/meal_detail_bloc.dart';
import 'package:opennutritracker/generated/l10n.dart';

import '../../core/domain/entity/intake_type_entity.dart';

class DiaryPage extends StatefulWidget {
const DiaryPage({super.key});

Expand All @@ -23,6 +27,7 @@ class _DiaryPageState extends State<DiaryPage> with WidgetsBindingObserver {

late DiaryBloc _diaryBloc;
late CalendarDayBloc _calendarDayBloc;
late MealDetailBloc _mealDetailBloc;

static const _calendarDurationDays = Duration(days: 356);
final _currentDate = DateTime.now();
Expand All @@ -34,6 +39,7 @@ class _DiaryPageState extends State<DiaryPage> with WidgetsBindingObserver {
WidgetsBinding.instance.addObserver(this);
_diaryBloc = locator<DiaryBloc>();
_calendarDayBloc = locator<CalendarDayBloc>();
_mealDetailBloc = locator<MealDetailBloc>();
super.initState();
}

Expand Down Expand Up @@ -103,6 +109,8 @@ class _DiaryPageState extends State<DiaryPage> with WidgetsBindingObserver {
snackIntake: state.snackIntakeList,
onDeleteIntake: _onDeleteIntakeItem,
onDeleteActivity: _onDeleteActivityItem,
onCopyIntake: _onCopyIntakeItem,
onCopyActivity: _onCopyActivityItem,
);
}
return const SizedBox();
Expand Down Expand Up @@ -138,6 +146,29 @@ class _DiaryPageState extends State<DiaryPage> with WidgetsBindingObserver {
}
}

void _onCopyIntakeItem(IntakeEntity intakeEntity,
TrackedDayEntity? trackedDayEntity, AddMealType? type) async {
IntakeTypeEntity finalType;
if (type == null) {
finalType = intakeEntity.type;
} else {
finalType = type.getIntakeType();
}
_mealDetailBloc.addIntake(
context,
intakeEntity.unit,
intakeEntity.amount.toString(),
finalType,
intakeEntity.meal,
DateTime.now());
_diaryBloc.updateHomePage();
}

void _onCopyActivityItem(UserActivityEntity userActivityEntity,
TrackedDayEntity? trackedDayEntity) async {
log.info("Should copy activity");
}

void _onDateSelected(
DateTime newDate, Map<String, TrackedDayEntity> trackedDaysMap) {
setState(() {
Expand Down
66 changes: 53 additions & 13 deletions lib/features/diary/presentation/widgets/day_info_widget.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,15 @@ import 'package:opennutritracker/core/domain/entity/intake_entity.dart';
import 'package:opennutritracker/core/domain/entity/tracked_day_entity.dart';
import 'package:opennutritracker/core/domain/entity/user_activity_entity.dart';
import 'package:opennutritracker/core/presentation/widgets/activity_vertial_list.dart';
import 'package:opennutritracker/core/presentation/widgets/copy_dialog.dart';
import 'package:opennutritracker/core/presentation/widgets/delete_dialog.dart';
import 'package:opennutritracker/core/utils/custom_icons.dart';
import 'package:opennutritracker/features/add_meal/presentation/add_meal_type.dart';
import 'package:opennutritracker/features/home/presentation/widgets/intake_vertical_list.dart';
import 'package:opennutritracker/generated/l10n.dart';

import '../../../../core/presentation/widgets/copy_or_delete_dialog.dart';

class DayInfoWidget extends StatelessWidget {
final DateTime selectedDay;
final TrackedDayEntity? trackedDayEntity;
Expand All @@ -22,18 +25,25 @@ class DayInfoWidget extends StatelessWidget {
onDeleteIntake;
final Function(UserActivityEntity userActivityEntity,
TrackedDayEntity? trackedDayEntity) onDeleteActivity;
final Function(IntakeEntity intake, TrackedDayEntity? trackedDayEntity,
AddMealType? type) onCopyIntake;
final Function(UserActivityEntity userActivityEntity,
TrackedDayEntity? trackedDayEntity) onCopyActivity;

const DayInfoWidget(
{super.key,
required this.selectedDay,
required this.trackedDayEntity,
required this.userActivities,
required this.breakfastIntake,
required this.lunchIntake,
required this.dinnerIntake,
required this.snackIntake,
required this.onDeleteIntake,
required this.onDeleteActivity});
const DayInfoWidget({
super.key,
required this.selectedDay,
required this.trackedDayEntity,
required this.userActivities,
required this.breakfastIntake,
required this.lunchIntake,
required this.dinnerIntake,
required this.snackIntake,
required this.onDeleteIntake,
required this.onDeleteActivity,
required this.onCopyIntake,
required this.onCopyActivity,
});

@override
Widget build(BuildContext context) {
Expand Down Expand Up @@ -171,16 +181,46 @@ class DayInfoWidget extends StatelessWidget {
return 'Carbs: $carbsTracked/${carbsGoal}g, Fat: $fatTracked/${fatGoal}g, Protein: $proteinTracked/${proteinGoal}g';
}

void onIntakeItemLongPressed(
void showCopyOrDeleteIntakeDialog(
BuildContext context, IntakeEntity intakeEntity) async {
final copyOrDelete = await showDialog<bool>(
context: context, builder: (context) => const CopyOrDeleteDialog());
if (context.mounted) {
if (copyOrDelete != null && !copyOrDelete) {
showDeleteIntakeDialog(context, intakeEntity);
} else if (copyOrDelete != null && copyOrDelete) {
showCopyDialog(context, intakeEntity);
}
}
}

void showCopyDialog(BuildContext context, IntakeEntity intakeEntity) async {
const copyDialog = CopyDialog();
final selectedMealType = await showDialog<AddMealType>(
context: context, builder: (context) => copyDialog);
if (selectedMealType != null) {
onCopyIntake(intakeEntity, null, selectedMealType);
}
}

void showDeleteIntakeDialog(
BuildContext context, IntakeEntity intakeEntity) async {
final shouldDeleteIntake = await showDialog<bool>(
context: context, builder: (context) => const DeleteDialog());

if (shouldDeleteIntake != null) {
onDeleteIntake(intakeEntity, trackedDayEntity);
}
}

void onIntakeItemLongPressed(
BuildContext context, IntakeEntity intakeEntity) async {
if (DateUtils.isSameDay(selectedDay, DateTime.now())) {
showDeleteIntakeDialog(context, intakeEntity);
} else {
showCopyOrDeleteIntakeDialog(context, intakeEntity);
}
}

void onActivityItemLongPressed(
BuildContext context, UserActivityEntity activityEntity) async {
final shouldDeleteActivity = await showDialog<bool>(
Expand Down
9 changes: 9 additions & 0 deletions lib/generated/intl/messages_de.dart
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,12 @@ class MessageLookup extends MessageLookupByLibrary {
"chooseWeightGoalLabel":
MessageLookupByLibrary.simpleMessage("Gewichtsziel wählen"),
"cmLabel": MessageLookupByLibrary.simpleMessage("cm"),
"copyDialogTitle": MessageLookupByLibrary.simpleMessage(
"Zu welcher Mahlzeit hinzufügen?"),
"copyOrDeleteTimeDialogContent": MessageLookupByLibrary.simpleMessage(
"Auf \"Nach heute kopieren\" klicken, um die Mahlzeit nach heute zu kopieren. Mit \"Löschen\" kann die Mahlzeit entfernt werden"),
"copyOrDeleteTimeDialogTitle":
MessageLookupByLibrary.simpleMessage("Was soll getan werden?"),
"createCustomDialogContent": MessageLookupByLibrary.simpleMessage(
"Möchten Sie einen benutzerdefinierte Mahlzeit erstellen?"),
"createCustomDialogTitle": MessageLookupByLibrary.simpleMessage(
Expand All @@ -95,6 +101,9 @@ class MessageLookup extends MessageLookupByLibrary {
"deleteTimeDialogTitle":
MessageLookupByLibrary.simpleMessage("Eintrag löschen?"),
"dialogCancelLabel": MessageLookupByLibrary.simpleMessage("ABBRECHEN"),
"dialogCopyLabel":
MessageLookupByLibrary.simpleMessage("NACH HEUTE KOPIEREN"),
"dialogDeleteLabel": MessageLookupByLibrary.simpleMessage("LÖSCHEN"),
"dialogOKLabel": MessageLookupByLibrary.simpleMessage("OK"),
"diaryLabel": MessageLookupByLibrary.simpleMessage("Tagebuch"),
"dinnerExample": MessageLookupByLibrary.simpleMessage(
Expand Down
9 changes: 9 additions & 0 deletions lib/generated/intl/messages_en.dart
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,12 @@ class MessageLookup extends MessageLookupByLibrary {
"chooseWeightGoalLabel":
MessageLookupByLibrary.simpleMessage("Choose Weight Goal"),
"cmLabel": MessageLookupByLibrary.simpleMessage("cm"),
"copyDialogTitle": MessageLookupByLibrary.simpleMessage(
"Which meal type do you want to copy to?"),
"copyOrDeleteTimeDialogContent": MessageLookupByLibrary.simpleMessage(
"With \"Copy to today\" you can copy the meal to today. With \"Delete\" you can delete the meal."),
"copyOrDeleteTimeDialogTitle":
MessageLookupByLibrary.simpleMessage("What do you want to do?"),
"createCustomDialogContent": MessageLookupByLibrary.simpleMessage(
"Do you want create a custom meal item?"),
"createCustomDialogTitle":
Expand All @@ -95,6 +101,9 @@ class MessageLookup extends MessageLookupByLibrary {
"deleteTimeDialogTitle":
MessageLookupByLibrary.simpleMessage("Delete Item?"),
"dialogCancelLabel": MessageLookupByLibrary.simpleMessage("CANCEL"),
"dialogCopyLabel":
MessageLookupByLibrary.simpleMessage("COPY TO TODAY"),
"dialogDeleteLabel": MessageLookupByLibrary.simpleMessage("DELETE"),
"dialogOKLabel": MessageLookupByLibrary.simpleMessage("OK"),
"diaryLabel": MessageLookupByLibrary.simpleMessage("Diary"),
"dinnerExample": MessageLookupByLibrary.simpleMessage(
Expand Down
9 changes: 9 additions & 0 deletions lib/generated/intl/messages_tr.dart
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,12 @@ class MessageLookup extends MessageLookupByLibrary {
"chooseWeightGoalLabel":
MessageLookupByLibrary.simpleMessage("Kilo Hedefi Seçin"),
"cmLabel": MessageLookupByLibrary.simpleMessage("cm"),
"copyDialogTitle": MessageLookupByLibrary.simpleMessage(
"Hangi öğüne eklemek istiyorsunuz?"),
"copyOrDeleteTimeDialogContent": MessageLookupByLibrary.simpleMessage(
"\"Bugüne kopyala\" seçeneğine tıklayarak öğünü bugüne kopyalayabilirsiniz. \"Sil\" seçeneği ile öğün kaldırılabilir."),
"copyOrDeleteTimeDialogTitle":
MessageLookupByLibrary.simpleMessage("Ne yapılmalı?"),
"createCustomDialogContent": MessageLookupByLibrary.simpleMessage(
"Özel bir yemek öğesi oluşturmak istiyor musunuz?"),
"createCustomDialogTitle": MessageLookupByLibrary.simpleMessage(
Expand All @@ -93,6 +99,9 @@ class MessageLookup extends MessageLookupByLibrary {
"deleteTimeDialogTitle":
MessageLookupByLibrary.simpleMessage("Öğe Silinsin mi?"),
"dialogCancelLabel": MessageLookupByLibrary.simpleMessage("İPTAL"),
"dialogCopyLabel":
MessageLookupByLibrary.simpleMessage("BUGÜNE KOPYALA"),
"dialogDeleteLabel": MessageLookupByLibrary.simpleMessage("SİL"),
"dialogOKLabel": MessageLookupByLibrary.simpleMessage("TAMAM"),
"diaryLabel": MessageLookupByLibrary.simpleMessage("Günlük"),
"dinnerExample": MessageLookupByLibrary.simpleMessage(
Expand Down
50 changes: 50 additions & 0 deletions lib/generated/l10n.dart

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 7 additions & 0 deletions lib/l10n/intl_de.arb
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,13 @@
"deleteTimeDialogContent": "Möchten Sie den ausgewählten Eintrag löschen?",
"itemDeletedSnackbar": "Eintrag gelöscht",

"copyDialogTitle": "Zu welcher Mahlzeit hinzufügen?",

"copyOrDeleteTimeDialogTitle": "Was soll getan werden?",
"copyOrDeleteTimeDialogContent": "Auf \"Nach heute kopieren\" klicken, um die Mahlzeit nach heute zu kopieren. Mit \"Löschen\" kann die Mahlzeit entfernt werden",
"dialogCopyLabel": "NACH HEUTE KOPIEREN",
"dialogDeleteLabel": "LÖSCHEN",

"suppliedLabel": "zugeführt",
"burnedLabel": "verbrannt",
"kcalLeftLabel": "kcal übrig",
Expand Down
Loading

0 comments on commit 0637043

Please sign in to comment.