diff --git a/lib/l10n/app_en.arb b/lib/l10n/app_en.arb index f4a2de7b4..65007b5d8 100644 --- a/lib/l10n/app_en.arb +++ b/lib/l10n/app_en.arb @@ -798,5 +798,11 @@ "none__bodyweight_exercise_": "none (bodyweight exercise)", "@none__bodyweight_exercise_": { "description": "Generated entry for translation for server strings" - } + }, + "editSchedule": "Edit schedule", + "log": "Log", + "@log": { + "description": "Log a specific meal" + }, + "done": "Done" } diff --git a/lib/widgets/nutrition/meal.dart b/lib/widgets/nutrition/meal.dart index 381ef006c..2002c0ae8 100644 --- a/lib/widgets/nutrition/meal.dart +++ b/lib/widgets/nutrition/meal.dart @@ -43,11 +43,18 @@ class MealWidget extends StatefulWidget { } class _MealWidgetState extends State { - bool _expanded = false; + bool _showingDetails = false; + bool _editing = false; - void _toggleExpanded() { + void _toggleEditing() { setState(() { - _expanded = !_expanded; + _editing = !_editing; + }); + } + + void _toggleDetails() { + setState(() { + _showingDetails = !_showingDetails; }); } @@ -57,85 +64,72 @@ class _MealWidgetState extends State { padding: const EdgeInsets.all(3), child: Card( child: Column( + crossAxisAlignment: CrossAxisAlignment.start, children: [ - DismissibleMealHeader(_expanded, _toggleExpanded, meal: widget._meal), - if (_expanded) - Row( - mainAxisSize: MainAxisSize.max, - mainAxisAlignment: MainAxisAlignment.spaceAround, - children: [ - IconButton( - onPressed: () { - // Delete the meal - Provider.of(context, listen: false) - .deleteMeal(widget._meal); - - // and inform the user - ScaffoldMessenger.of(context).showSnackBar( - SnackBar( - content: Text( - AppLocalizations.of(context).successfullyDeleted, - textAlign: TextAlign.center, - ), - ), - ); - }, - icon: const Icon(Icons.delete), - ), - if (widget._meal.mealItems.isNotEmpty) - Ink( - decoration: ShapeDecoration( - color: Theme.of(context).primaryColor, //wgerPrimaryButtonColor, - shape: const CircleBorder(), + MealHeader( + editing: _editing, + toggleEditing: _toggleEditing, + showingDetails: _showingDetails, + toggleDetails: _toggleDetails, + meal: widget._meal), + if (_editing) + Padding( + padding: const EdgeInsets.symmetric(vertical: 8), + child: Wrap( + spacing: 8, + children: [ + TextButton.icon( + icon: const Icon(Icons.add), + label: Text(AppLocalizations.of(context).addIngredient), + onPressed: () { + Navigator.pushNamed( + context, + FormScreen.routeName, + arguments: FormScreenArguments( + AppLocalizations.of(context).addIngredient, + MealItemForm(widget._meal, widget._listMealItems), + hasListView: true, + ), + ); + }, ), - child: IconButton( - icon: const Icon(Icons.history_edu), - color: Colors.white, + TextButton.icon( + label: Text(AppLocalizations.of(context).editSchedule), onPressed: () { - Provider.of(context, listen: false) - .logMealToDiary(widget._meal); - ScaffoldMessenger.of(context).showSnackBar( - SnackBar( - content: Text( - AppLocalizations.of(context).mealLogged, - textAlign: TextAlign.center, - ), + Navigator.pushNamed( + context, + FormScreen.routeName, + arguments: FormScreenArguments( + AppLocalizations.of(context).edit, + MealForm(widget._meal.planId, widget._meal), ), ); }, + icon: const Icon(Icons.timer), ), - ), - IconButton( - onPressed: () { - Navigator.pushNamed( - context, - FormScreen.routeName, - arguments: FormScreenArguments( - AppLocalizations.of(context).edit, - MealForm(widget._meal.planId, widget._meal), - ), - ); - }, - icon: const Icon(Icons.edit), - ), - ], - ), - if (_expanded) const Divider(), - ...widget._meal.mealItems.map((item) => MealItemWidget(item, _expanded)), - OutlinedButton( - child: Text(AppLocalizations.of(context).addIngredient), - onPressed: () { - Navigator.pushNamed( - context, - FormScreen.routeName, - arguments: FormScreenArguments( - AppLocalizations.of(context).addIngredient, - MealItemForm(widget._meal, widget._listMealItems), - hasListView: true, - ), - ); - }, - ), + TextButton.icon( + onPressed: () { + // Delete the meal + Provider.of(context, listen: false) + .deleteMeal(widget._meal); + + // and inform the user + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: Text( + AppLocalizations.of(context).successfullyDeleted, + textAlign: TextAlign.center, + ), + ), + ); + }, + label: Text(AppLocalizations.of(context).delete), + icon: const Icon(Icons.delete)), + ], + )), + const Divider(), + ...widget._meal.mealItems + .map((item) => MealItemWidget(item, _showingDetails, _editing)), ], ), ), @@ -144,10 +138,11 @@ class _MealWidgetState extends State { } class MealItemWidget extends StatelessWidget { - final bool _expanded; + final bool _editing; + final bool _showingDetails; final MealItem _item; - const MealItemWidget(this._item, this._expanded); + const MealItemWidget(this._item, this._showingDetails, this._editing); @override Widget build(BuildContext context) { @@ -180,11 +175,12 @@ class MealItemWidget extends StatelessWidget { ), subtitle: Column( crossAxisAlignment: CrossAxisAlignment.start, - children: [if (_expanded) ...getMutedNutritionalValues(values, context)], + children: [if (_showingDetails) ...getMutedNutritionalValues(values, context)], ), - trailing: _expanded + trailing: _editing ? IconButton( icon: const Icon(Icons.delete), + tooltip: AppLocalizations.of(context).delete, iconSize: ICON_SIZE_SMALL, onPressed: () { // Delete the meal item @@ -205,87 +201,95 @@ class MealItemWidget extends StatelessWidget { } } -class DismissibleMealHeader extends StatelessWidget { - final bool _expanded; - final Function _toggle; +class MealHeader extends StatelessWidget { + final bool _editing; + final bool _showingDetails; + final Function _toggleEditing; + final Function _toggleDetails; - const DismissibleMealHeader( - this._expanded, - this._toggle, { + const MealHeader({ required Meal meal, - }) : _meal = meal; + required bool editing, + required Function toggleEditing, + required bool showingDetails, + required Function toggleDetails, + }) : _toggleDetails = toggleDetails, + _toggleEditing = toggleEditing, + _showingDetails = showingDetails, + _editing = editing, + _meal = meal; final Meal _meal; @override Widget build(BuildContext context) { - return Dismissible( - key: Key(_meal.id.toString()), - direction: DismissDirection.startToEnd, - background: Container( - color: Theme.of(context).primaryColor, //wgerPrimaryButtonColor, - alignment: Alignment.centerLeft, - padding: const EdgeInsets.only(left: 10), - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Text( - AppLocalizations.of(context).logMeal, - style: const TextStyle(color: Colors.white), + return Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + ListTile( + contentPadding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8), + title: Row(children: [ + Expanded( + child: (_meal.name != '') + ? Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + _meal.name, + style: Theme.of(context).textTheme.titleMedium, + ), + Text( + _meal.time!.format(context), + style: Theme.of(context).textTheme.headlineSmall, + ) + ], + ) + : Text( + _meal.time!.format(context), + style: Theme.of(context).textTheme.headlineSmall, + ), ), - const Icon( - Icons.history_edu, - color: Colors.white, + Text( + AppLocalizations.of(context).log, + style: Theme.of(context) + .textTheme + .labelLarge + ?.copyWith(color: Theme.of(context).colorScheme.primary), ), - ], - ), - ), - confirmDismiss: (direction) async { - // Delete - if (direction == DismissDirection.startToEnd) { - Provider.of(context, listen: false).logMealToDiary(_meal); - ScaffoldMessenger.of(context).showSnackBar( - SnackBar( - content: Text( - AppLocalizations.of(context).mealLogged, - textAlign: TextAlign.center, - ), + const SizedBox(width: 26), + const SizedBox(height: 40, width: 1, child: VerticalDivider()), + ]), + trailing: Row(mainAxisSize: MainAxisSize.min, children: [ + IconButton( + icon: _showingDetails ? const Icon(Icons.info) : const Icon(Icons.info_outline), + onPressed: () { + _toggleDetails(); + }, + tooltip: AppLocalizations.of(context).toggleDetails, ), - ); - } - return false; - }, - child: Container( - padding: const EdgeInsets.all(10), - decoration: BoxDecoration(color: Theme.of(context).colorScheme.inversePrimary), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - if (_meal.name != '') - Text( - _meal.name, - style: Theme.of(context).textTheme.headlineSmall, - ), - Row( - children: [ - Expanded( - child: Text( - _meal.time!.format(context), - style: Theme.of(context).textTheme.headlineSmall, - ), - ), - IconButton( - visualDensity: VisualDensity.compact, - icon: _expanded ? const Icon(Icons.unfold_less) : const Icon(Icons.unfold_more), - onPressed: () { - _toggle(); - }, + const SizedBox(width: 5), + IconButton( + icon: _editing ? const Icon(Icons.done) : const Icon(Icons.edit), + tooltip: + _editing ? AppLocalizations.of(context).done : AppLocalizations.of(context).edit, + onPressed: () { + _toggleEditing(); + }, + ) + ]), + onTap: () { + Provider.of(context, listen: false).logMealToDiary(_meal); + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: Text( + AppLocalizations.of(context).mealLogged, + textAlign: TextAlign.center, ), - ], - ), - ], + ), + ); + }, ), - ), + ], ); } } diff --git a/lib/widgets/nutrition/nutritional_diary_detail.dart b/lib/widgets/nutrition/nutritional_diary_detail.dart index af07c2911..d1080e4fd 100644 --- a/lib/widgets/nutrition/nutritional_diary_detail.dart +++ b/lib/widgets/nutrition/nutritional_diary_detail.dart @@ -195,6 +195,7 @@ class NutritionalDiaryDetailWidget extends StatelessWidget { ), ), IconButton( + tooltip: AppLocalizations.of(context).delete, onPressed: () { Provider.of(context, listen: false) .deleteLog(log.id!, _nutritionalPlan.id!); diff --git a/lib/widgets/nutrition/nutritional_plans_list.dart b/lib/widgets/nutrition/nutritional_plans_list.dart index 58b112108..3377a6c93 100644 --- a/lib/widgets/nutrition/nutritional_plans_list.dart +++ b/lib/widgets/nutrition/nutritional_plans_list.dart @@ -39,78 +39,70 @@ class NutritionalPlansList extends StatelessWidget { itemCount: _nutritionProvider.items.length, itemBuilder: (context, index) { final currentPlan = _nutritionProvider.items[index]; - return Dismissible( - key: Key(currentPlan.id.toString()), - confirmDismiss: (direction) async { - // Delete workout from DB - final bool? res = await showDialog( - context: context, - builder: (BuildContext contextDialog) { - return AlertDialog( - content: Text( - AppLocalizations.of(context).confirmDelete(currentPlan.description), - ), - actions: [ - TextButton( - child: Text(MaterialLocalizations.of(context).cancelButtonLabel), - onPressed: () => Navigator.of(contextDialog).pop(), - ), - TextButton( - child: Text( - AppLocalizations.of(context).delete, - style: TextStyle(color: Theme.of(context).colorScheme.error), - ), - onPressed: () { - // Confirmed, delete the workout - _nutritionProvider.deletePlan(currentPlan.id!); + return Card( + child: ListTile( + onTap: () { + Navigator.of(context).pushNamed( + NutritionalPlanScreen.routeName, + arguments: currentPlan, + ); + }, + title: Text(currentPlan.getLabel(context)), + subtitle: Text( + DateFormat.yMd(Localizations.localeOf(context).languageCode) + .format(currentPlan.creationDate), + ), + trailing: Row(mainAxisSize: MainAxisSize.min, children: [ + const VerticalDivider(), + IconButton( + icon: const Icon(Icons.delete), + tooltip: AppLocalizations.of(context).delete, + onPressed: () async { + // Delete workout from DB + await showDialog( + context: context, + builder: (BuildContext contextDialog) { + return AlertDialog( + content: Text( + AppLocalizations.of(context) + .confirmDelete(currentPlan.description), + ), + actions: [ + TextButton( + child: + Text(MaterialLocalizations.of(context).cancelButtonLabel), + onPressed: () => Navigator.of(contextDialog).pop(), + ), + TextButton( + child: Text( + AppLocalizations.of(context).delete, + style: + TextStyle(color: Theme.of(context).colorScheme.error), + ), + onPressed: () { + // Confirmed, delete the workout + _nutritionProvider.deletePlan(currentPlan.id!); - // Close the popup - Navigator.of(contextDialog).pop(); + // Close the popup + Navigator.of(contextDialog).pop(); - // and inform the user - ScaffoldMessenger.of(context).showSnackBar( - SnackBar( - content: Text( - AppLocalizations.of(context).successfullyDeleted, - textAlign: TextAlign.center, - ), + // and inform the user + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: Text( + AppLocalizations.of(context).successfullyDeleted, + textAlign: TextAlign.center, + ), + ), + ); + }, ), - ); - }, - ), - ], - ); - }); - return res; - }, - background: Container( - color: Theme.of(context).colorScheme.error, - alignment: Alignment.centerRight, - padding: const EdgeInsets.only(right: 20), - margin: const EdgeInsets.symmetric( - horizontal: 4, - vertical: 4, - ), - child: const Icon( - Icons.delete, - color: Colors.white, - ), - ), - direction: DismissDirection.endToStart, - child: Card( - child: ListTile( - onTap: () { - Navigator.of(context).pushNamed( - NutritionalPlanScreen.routeName, - arguments: currentPlan, - ); - }, - title: Text(currentPlan.getLabel(context)), - subtitle: Text( - DateFormat.yMd(Localizations.localeOf(context).languageCode) - .format(currentPlan.creationDate), - ), - ), + ], + ); + }); + }, + ) + ]), ), ); }, diff --git a/lib/widgets/workouts/day.dart b/lib/widgets/workouts/day.dart index dbd923dcc..0229df1c2 100644 --- a/lib/widgets/workouts/day.dart +++ b/lib/widgets/workouts/day.dart @@ -97,7 +97,7 @@ class WorkoutDayWidget extends StatefulWidget { } class _WorkoutDayWidgetState extends State { - bool _expanded = false; + bool _editing = false; late List _sets; @override @@ -109,20 +109,21 @@ class _WorkoutDayWidgetState extends State { void _toggleExpanded() { setState(() { - _expanded = !_expanded; + _editing = !_editing; }); } Widget getSetRow(Set set, int index) { return Row( key: ValueKey(set.id), - crossAxisAlignment: CrossAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.center, children: [ - if (_expanded) + if (_editing) IconButton( visualDensity: VisualDensity.compact, icon: const Icon(Icons.delete), iconSize: ICON_SIZE_SMALL, + tooltip: AppLocalizations.of(context).delete, onPressed: () { Provider.of(context, listen: false).deleteSet(set); }, @@ -131,21 +132,19 @@ class _WorkoutDayWidgetState extends State { child: Column( children: [ if (set.comment != '') MutedText(set.comment), - ...set.settingsFiltered - .map( - (setting) => SettingWidget( - set: set, - setting: setting, - expanded: _expanded, - toggle: _toggleExpanded, - ), - ) - , + ...set.settingsFiltered.map( + (setting) => SettingWidget( + set: set, + setting: setting, + expanded: _editing, + toggle: _toggleExpanded, + ), + ), const Divider(), ], ), ), - if (_expanded) + if (_editing) ReorderableDragStartListener( index: index, child: const IconButton( @@ -164,62 +163,65 @@ class _WorkoutDayWidgetState extends State { child: Card( margin: EdgeInsets.zero, child: Column( + crossAxisAlignment: CrossAxisAlignment.start, children: [ - DayHeaderDismissible( + DayHeader( day: widget._day, - expanded: _expanded, + expanded: _editing, toggle: _toggleExpanded, ), - if (_expanded) - Row( - mainAxisSize: MainAxisSize.max, - mainAxisAlignment: MainAxisAlignment.spaceAround, - children: [ - IconButton( - onPressed: () { - Provider.of(context, listen: false).deleteDay( - widget._day, - ); - }, - icon: const Icon(Icons.delete), - ), - if (widget._day.sets.isNotEmpty) - Ink( - decoration: ShapeDecoration( - color: Theme.of(context).primaryColor, - shape: const CircleBorder(), + if (_editing) + Padding( + padding: const EdgeInsets.symmetric(vertical: 8), + child: Wrap( + spacing: 8, + children: [ + TextButton.icon( + label: Text(AppLocalizations.of(context).addSet), + icon: const Icon(Icons.add), + onPressed: () { + Navigator.pushNamed( + context, + FormScreen.routeName, + arguments: FormScreenArguments( + AppLocalizations.of(context).newSet, + SetFormWidget(widget._day), + hasListView: true, + padding: EdgeInsets.zero, + ), + ); + }, ), - child: IconButton( - icon: const Icon(Icons.play_arrow), - color: Colors.white, + TextButton.icon( + icon: const Icon(Icons.calendar_month), + label: Text(AppLocalizations.of(context).editSchedule), onPressed: () { - Navigator.of(context).pushNamed( - GymModeScreen.routeName, - arguments: widget._day, + Navigator.pushNamed( + context, + FormScreen.routeName, + arguments: FormScreenArguments( + AppLocalizations.of(context).edit, + DayFormWidget( + Provider.of(context, listen: false) + .findById(widget._day.workoutId), + widget._day), + hasListView: true, + ), ); }, ), - ), - IconButton( - onPressed: () { - Navigator.pushNamed( - context, - FormScreen.routeName, - arguments: FormScreenArguments( - AppLocalizations.of(context).edit, - DayFormWidget( - Provider.of(context, listen: false) - .findById(widget._day.workoutId), - widget._day), - hasListView: true, - ), - ); - }, - icon: const Icon(Icons.edit), - ), - ], - ), - if (_expanded) const Divider(), + TextButton.icon( + icon: const Icon(Icons.delete), + label: Text(AppLocalizations.of(context).delete), + onPressed: () { + Provider.of(context, listen: false).deleteDay( + widget._day, + ); + }, + ), + ], + )), + const Divider(), ReorderableListView( physics: const NeverScrollableScrollPhysics(), shrinkWrap: true, @@ -242,21 +244,6 @@ class _WorkoutDayWidgetState extends State { for (var i = 0; i < widget._day.sets.length; i++) getSetRow(widget._day.sets[i], i), ], ), - OutlinedButton( - child: Text(AppLocalizations.of(context).addSet), - onPressed: () { - Navigator.pushNamed( - context, - FormScreen.routeName, - arguments: FormScreenArguments( - AppLocalizations.of(context).newSet, - SetFormWidget(widget._day), - hasListView: true, - padding: EdgeInsets.zero, - ), - ); - }, - ), ], ), ), @@ -264,77 +251,48 @@ class _WorkoutDayWidgetState extends State { } } -class DayHeaderDismissible extends StatelessWidget { +class DayHeader extends StatelessWidget { final Day _day; - final bool _expanded; + final bool _editing; final Function _toggle; - const DayHeaderDismissible({ + const DayHeader({ required Day day, required bool expanded, required Function toggle, }) : _day = day, - _expanded = expanded, + _editing = expanded, _toggle = toggle; @override Widget build(BuildContext context) { - return Dismissible( - key: Key(_day.id.toString()), - direction: DismissDirection.startToEnd, - background: Container( - color: Theme.of(context).primaryColor, - alignment: Alignment.centerLeft, - padding: const EdgeInsets.only(left: 10), - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Text( - AppLocalizations.of(context).gymMode, - style: const TextStyle(color: Colors.white), - ), - const Icon( - Icons.play_arrow, - color: Colors.white, - ), - ], - ), + return ListTile( + contentPadding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8), + title: Text( + _day.description, + style: Theme.of(context).textTheme.headlineSmall, + overflow: TextOverflow.ellipsis, ), - confirmDismiss: (direction) async { - // Delete day - if (direction == DismissDirection.startToEnd) { - Navigator.of(context).pushNamed(GymModeScreen.routeName, arguments: _day); - } - return false; + subtitle: Text(_day.getDaysTextTranslated(Localizations.localeOf(context).languageCode)), + leading: const Icon(Icons.play_arrow), + minLeadingWidth: 8, + trailing: Row(mainAxisSize: MainAxisSize.min, children: [ + const SizedBox(height: 40, width: 1, child: VerticalDivider()), + const SizedBox(width: 10), + IconButton( + icon: _editing ? const Icon(Icons.done) : const Icon(Icons.edit), + tooltip: _editing ? AppLocalizations.of(context).done : AppLocalizations.of(context).edit, + onPressed: () { + _toggle(); + }, + ) + ]), + onTap: () { + Navigator.of(context).pushNamed( + GymModeScreen.routeName, + arguments: _day, + ); }, - child: Container( - padding: const EdgeInsets.all(10), - decoration: BoxDecoration(color: Theme.of(context).colorScheme.inversePrimary), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Expanded( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( - _day.description, - style: Theme.of(context).textTheme.headlineSmall, - overflow: TextOverflow.ellipsis, - ), - Text(_day.getDaysTextTranslated(Localizations.localeOf(context).languageCode)), - ], - ), - ), - IconButton( - icon: _expanded ? const Icon(Icons.unfold_less) : const Icon(Icons.unfold_more), - onPressed: () { - _toggle(); - }, - ), - ], - ), - ), ); } } diff --git a/lib/widgets/workouts/workout_plans_list.dart b/lib/widgets/workouts/workout_plans_list.dart index d2bc3d7ec..d7443bdac 100644 --- a/lib/widgets/workouts/workout_plans_list.dart +++ b/lib/widgets/workouts/workout_plans_list.dart @@ -40,81 +40,71 @@ class WorkoutPlansList extends StatelessWidget { itemCount: _workoutProvider.items.length, itemBuilder: (context, index) { final currentWorkout = _workoutProvider.items[index]; - return Dismissible( - key: Key(currentWorkout.id.toString()), - confirmDismiss: (direction) async { - // Delete workout from DB - final res = await showDialog( - context: context, - builder: (BuildContext contextDialog) { - return AlertDialog( - content: Text( - AppLocalizations.of(context).confirmDelete(currentWorkout.name), - ), - actions: [ - TextButton( - child: Text(MaterialLocalizations.of(context).cancelButtonLabel), - onPressed: () => Navigator.of(contextDialog).pop(), - ), - TextButton( - child: Text( - AppLocalizations.of(context).delete, - style: TextStyle(color: Theme.of(context).colorScheme.error), - ), - onPressed: () { - // Confirmed, delete the workout - Provider.of(context, listen: false) - .deleteWorkout(currentWorkout.id!); - // Close the popup - Navigator.of(contextDialog).pop(); + return Card( + child: ListTile( + onTap: () { + _workoutProvider.setCurrentPlan(currentWorkout.id!); - // and inform the user - ScaffoldMessenger.of(context).showSnackBar( - SnackBar( - content: Text( - AppLocalizations.of(context).successfullyDeleted, - textAlign: TextAlign.center, - ), - ), - ); - }, - ), - ], - ); - }); - return res; + Navigator.of(context) + .pushNamed(WorkoutPlanScreen.routeName, arguments: currentWorkout); }, - background: Container( - color: Theme.of(context).colorScheme.error, - alignment: Alignment.centerRight, - padding: const EdgeInsets.only(right: 20), - margin: const EdgeInsets.symmetric( - horizontal: 4, - vertical: 4, - ), - child: const Icon( - Icons.delete, - color: Colors.white, - ), + title: Text(currentWorkout.name), + subtitle: Text( + DateFormat.yMd(Localizations.localeOf(context).languageCode) + .format(currentWorkout.creationDate), ), - direction: DismissDirection.endToStart, - child: Card( - child: ListTile( - onTap: () { - _workoutProvider.setCurrentPlan(currentWorkout.id!); + trailing: Row(mainAxisSize: MainAxisSize.min, children: [ + const VerticalDivider(), + IconButton( + icon: const Icon(Icons.delete), + tooltip: AppLocalizations.of(context).delete, + onPressed: () async { + // Delete workout from DB + await showDialog( + context: context, + builder: (BuildContext contextDialog) { + return AlertDialog( + content: Text( + AppLocalizations.of(context).confirmDelete(currentWorkout.name), + ), + actions: [ + TextButton( + child: + Text(MaterialLocalizations.of(context).cancelButtonLabel), + onPressed: () => Navigator.of(contextDialog).pop(), + ), + TextButton( + child: Text( + AppLocalizations.of(context).delete, + style: TextStyle(color: Theme.of(context).colorScheme.error), + ), + onPressed: () { + // Confirmed, delete the workout + Provider.of(context, listen: false) + .deleteWorkout(currentWorkout.id!); - Navigator.of(context) - .pushNamed(WorkoutPlanScreen.routeName, arguments: currentWorkout); + // Close the popup + Navigator.of(contextDialog).pop(); + + // and inform the user + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: Text( + AppLocalizations.of(context).successfullyDeleted, + textAlign: TextAlign.center, + ), + ), + ); + }, + ), + ], + ); + }); }, - title: Text(currentWorkout.name), - subtitle: Text( - DateFormat.yMd(Localizations.localeOf(context).languageCode) - .format(currentWorkout.creationDate), - ), - ), - ), - ); + ) + ]), + )); }, ), ); diff --git a/test/nutrition/nutritional_plan_screen_test.dart b/test/nutrition/nutritional_plan_screen_test.dart index af66d0056..cea4afb8c 100644 --- a/test/nutrition/nutritional_plan_screen_test.dart +++ b/test/nutrition/nutritional_plan_screen_test.dart @@ -80,7 +80,7 @@ void main() { expect(find.text('75g Burger soup'), findsOneWidget); expect(find.text('300g Broccoli cake'), findsOneWidget); - expect(find.byType(Dismissible), findsNWidgets(2)); + expect(find.byType(Card), findsNWidgets(2)); expect(find.byType(FlNutritionalDiaryChartWidget), findsNothing); }); diff --git a/test/nutrition/nutritional_plans_screen_test.dart b/test/nutrition/nutritional_plans_screen_test.dart index b7fd34dcd..df5828334 100644 --- a/test/nutrition/nutritional_plans_screen_test.dart +++ b/test/nutrition/nutritional_plans_screen_test.dart @@ -86,14 +86,15 @@ void main() { //debugDumpApp(); expect(find.text('Nutritional plans'), findsOneWidget); - expect(find.byType(Dismissible), findsNWidgets(2)); + expect(find.byType(Card), findsNWidgets(2)); expect(find.byType(ListTile), findsNWidgets(2)); }); - testWidgets('Test deleting an item by dragging the dismissible', (WidgetTester tester) async { + testWidgets('Test deleting an item using the Delete button', (WidgetTester tester) async { await tester.pumpWidget(createHomeScreen()); - await tester.drag(find.byKey(const Key('1')), const Offset(-500.0, 0.0)); + await tester.tap(find.byIcon(Icons.delete).first); + await tester.pumpAndSettle(); // Confirmation dialog diff --git a/test/workout/workout_plan_screen_test.dart b/test/workout/workout_plan_screen_test.dart index 838e7d414..cd9febcc8 100644 --- a/test/workout/workout_plan_screen_test.dart +++ b/test/workout/workout_plan_screen_test.dart @@ -67,7 +67,7 @@ void main() { expect(find.text('3 day workout'), findsOneWidget); expect(find.text('chest, shoulders'), findsOneWidget); expect(find.text('legs'), findsOneWidget); - expect(find.byType(Dismissible), findsNWidgets(2)); + expect(find.byType(Card), findsNWidgets(2)); }); testWidgets('Tests the localization of times - EN', (WidgetTester tester) async { diff --git a/test/workout/workout_plans_screen_test.dart b/test/workout/workout_plans_screen_test.dart index 45ee48797..5fe146c7e 100644 --- a/test/workout/workout_plans_screen_test.dart +++ b/test/workout/workout_plans_screen_test.dart @@ -78,14 +78,15 @@ void main() { //debugDumpApp(); expect(find.text('Workout plans'), findsOneWidget); - expect(find.byType(Dismissible), findsNWidgets(2)); + expect(find.byType(Card), findsNWidgets(2)); expect(find.byType(ListTile), findsNWidgets(2)); }); - testWidgets('Test deleting an item by dragging the dismissible', (WidgetTester tester) async { + testWidgets('Test deleting an item using the Delete button', (WidgetTester tester) async { await tester.pumpWidget(createHomeScreen()); - await tester.drag(find.byKey(const Key('1')), const Offset(-500.0, 0.0)); + await tester.tap(find.byIcon(Icons.delete).first); + await tester.pumpAndSettle(); // Confirmation dialog