diff --git a/lib/base/localization/l10n/app_de.arb b/lib/base/localization/l10n/app_de.arb index d25ea4b5..a7247fad 100644 --- a/lib/base/localization/l10n/app_de.arb +++ b/lib/base/localization/l10n/app_de.arb @@ -200,6 +200,7 @@ }, "noRoomsFound":"Keine Räume gefunden", "noMealPlanFound":"Kein Essensplan gefunden", + "mealPlan": "Essensplan", "noEntriesFoundSearch":"Keine {searchCategory} gefunden", "@noEntriesFoundSearch":{ "description":"Title of Search Category", diff --git a/lib/base/localization/l10n/app_en.arb b/lib/base/localization/l10n/app_en.arb index 65896e18..bba939b5 100644 --- a/lib/base/localization/l10n/app_en.arb +++ b/lib/base/localization/l10n/app_en.arb @@ -200,6 +200,7 @@ }, "noRoomsFound":"No Rooms Found", "noMealPlanFound":"No Meal Plan Found", + "mealPlan": "Meal Plan", "noEntriesFoundSearch":"No {searchCategory} Found", "@noEntriesFoundSearch":{ "description":"Title of Search Category", diff --git a/lib/placesComponent/services/mealplan_service.dart b/lib/placesComponent/services/mealplan_service.dart index c1660025..157986ab 100644 --- a/lib/placesComponent/services/mealplan_service.dart +++ b/lib/placesComponent/services/mealplan_service.dart @@ -1,3 +1,5 @@ +import 'dart:developer'; + import 'package:campus_flutter/base/extensions/date_time_week_number.dart'; import 'package:campus_flutter/base/networking/apis/eatApi/eat_api.dart'; import 'package:campus_flutter/base/networking/apis/eatApi/eat_api_service.dart'; @@ -8,23 +10,24 @@ import 'package:campus_flutter/placesComponent/model/cafeterias/dish.dart'; import 'package:campus_flutter/placesComponent/model/cafeterias/meal_plan.dart'; import 'package:campus_flutter/placesComponent/model/cafeterias/mensa_menu.dart'; import 'package:campus_flutter/providers_get_it.dart'; +import 'package:dio/dio.dart'; class MealPlanService { static Future<(DateTime?, List)> getCafeteriaMenu( bool forcedRefresh, Cafeteria cafeteria) async { MainApi mainApi = getIt(); final today = DateTime.now(); - final response = await mainApi.makeRequest( - EatApi(EatApiServiceMenu( - location: cafeteria.id, - year: today.year, - week: today.weekNumber())), - MealPlan.fromJson, - forcedRefresh); + try { + final response = await mainApi.makeRequest( + EatApi(EatApiServiceMenu( + location: cafeteria.id, + year: today.year, + week: today.weekNumber())), + MealPlan.fromJson, + forcedRefresh); - final List thisWeekMenu = _getMenuPerDay(response.data); + final List thisWeekMenu = _getMenuPerDay(response.data); - try { final nextWeek = today.add(const Duration(days: 7)); final nextWeekResponse = await mainApi.makeRequest( @@ -41,8 +44,12 @@ class MealPlanService { thisWeekMenu.addAll(nextWeekMenu); return (response.saved, thisWeekMenu); - } catch (_) { - return (response.saved, thisWeekMenu); + } catch (e) { + if (e is DioException) { + return (DateTime.now(), []); + } else { + rethrow; + } } } diff --git a/lib/placesComponent/viewModels/cafeterias_viewmodel.dart b/lib/placesComponent/viewModels/cafeterias_viewmodel.dart index 1424c700..409e804a 100644 --- a/lib/placesComponent/viewModels/cafeterias_viewmodel.dart +++ b/lib/placesComponent/viewModels/cafeterias_viewmodel.dart @@ -21,7 +21,7 @@ class CafeteriasViewModel { BehaviorSubject>?> campusCafeterias = BehaviorSubject.seeded(null); - BehaviorSubject<(Cafeteria, CafeteriaMenu)?> closestCafeteria = + BehaviorSubject<(Cafeteria, CafeteriaMenu?)?> closestCafeteria = BehaviorSubject.seeded(null); setClosestCafeteria(String id) { @@ -30,7 +30,7 @@ class CafeteriasViewModel { } List cafeterias = []; - List<(Cafeteria, CafeteriaMenu)> closestCafeterias = []; + List<(Cafeteria, CafeteriaMenu?)> closestCafeterias = []; DateTime? lastFetched; Future fetch(bool forcedRefresh) async { @@ -88,25 +88,27 @@ class CafeteriasViewModel { 250); List errors = []; - List<(Cafeteria, CafeteriaMenu)> data = []; + List<(Cafeteria, CafeteriaMenu?)> data = []; for (final cafeteria in cafeteriasInRadius) { await fetchCafeteriaMenu(false, cafeteria).then((value) { if (value.isNotEmpty) { data.add((cafeteria, value.first)); } else { - errors.add(Error()); + data.add((cafeteria, null)); } }, onError: (error) => errors.add(error)); } - if (data.isEmpty && errors.isNotEmpty) { - closestCafeteria.addError("Could not fetch closest cafeteria!"); + if (data.isEmpty || errors.isNotEmpty) { + closestCafeteria + .addError(CustomException("Could not fetch closest Cafeteria!")); } else { closestCafeterias = data; closestCafeteria.add(data.first); } } else { - closestCafeteria.addError("Could not fetch closest cafeteria!"); + closestCafeteria + .addError(CustomException("Could not fetch closest Cafeteria!")); } } diff --git a/lib/placesComponent/views/cafeterias/cafeteria_view.dart b/lib/placesComponent/views/cafeterias/cafeteria_view.dart index 66431450..47146bcb 100644 --- a/lib/placesComponent/views/cafeterias/cafeteria_view.dart +++ b/lib/placesComponent/views/cafeterias/cafeteria_view.dart @@ -188,48 +188,54 @@ class _CafeteriaViewState extends ConsumerState { .read(cafeteriasViewModel) .fetchCafeteriaMenu(false, widget.cafeteria), builder: (context, snapshot) { - if (snapshot.hasData && snapshot.data!.isNotEmpty) { - final menu = snapshot.data!; - final todayMeals = ref.read(cafeteriasViewModel).getTodayDishes( - menu.firstWhereOrNull((element) => - element.date.isAtSameMomentAs(selectedDate) || - element.date.isAfter(selectedDate))); - return Column( - children: [ - Padding( - padding: EdgeInsets.all(context.padding), - child: SizedBox( - height: 80, - child: SfDateRangePicker( - headerHeight: 0, - toggleDaySelection: false, - enablePastDates: false, - allowViewNavigation: false, - initialSelectedDate: menu.first.date, - minDate: menu.first.date, - maxDate: menu.last.date, - monthViewSettings: - const DateRangePickerMonthViewSettings( - numberOfWeeksInView: 1, firstDayOfWeek: 1), - onSelectionChanged: (args) => setState(() { - selectedDate = args.value as DateTime; - }), - selectableDayPredicate: (date) { - return date.weekday != DateTime.saturday && - date.weekday != DateTime.sunday; - }, - ))), - if (todayMeals.isNotEmpty) - DishSlider( - dishes: todayMeals, - //inverted: true, - ), - if (todayMeals.isEmpty) - Center( - child: Text(context.localizations.noMealPlanFound), - ) - ], - ); + if (snapshot.hasData) { + if (snapshot.data!.isEmpty) { + return Center( + child: Text(context.localizations.noMealPlanFound), + ); + } else { + final menu = snapshot.data!; + final todayMeals = ref.read(cafeteriasViewModel).getTodayDishes( + menu.firstWhereOrNull((element) => + element.date.isAtSameMomentAs(selectedDate) || + element.date.isAfter(selectedDate))); + return Column( + children: [ + Padding( + padding: EdgeInsets.all(context.padding), + child: SizedBox( + height: 80, + child: SfDateRangePicker( + headerHeight: 0, + toggleDaySelection: false, + enablePastDates: false, + allowViewNavigation: false, + initialSelectedDate: menu.first.date, + minDate: menu.first.date, + maxDate: menu.last.date, + monthViewSettings: + const DateRangePickerMonthViewSettings( + numberOfWeeksInView: 1, firstDayOfWeek: 1), + onSelectionChanged: (args) => setState(() { + selectedDate = args.value as DateTime; + }), + selectableDayPredicate: (date) { + return date.weekday != DateTime.saturday && + date.weekday != DateTime.sunday; + }, + ))), + if (todayMeals.isNotEmpty) + DishSlider( + dishes: todayMeals, + //inverted: true, + ), + if (todayMeals.isEmpty) + Center( + child: Text(context.localizations.noMealPlanFound), + ) + ], + ); + } } else if (snapshot.hasError) { return ErrorHandlingView( error: snapshot.error!, diff --git a/lib/placesComponent/views/homeWidget/cafeteria_widget_view.dart b/lib/placesComponent/views/homeWidget/cafeteria_widget_view.dart index ff39708f..1d8e370d 100644 --- a/lib/placesComponent/views/homeWidget/cafeteria_widget_view.dart +++ b/lib/placesComponent/views/homeWidget/cafeteria_widget_view.dart @@ -93,7 +93,7 @@ class _CafeteriaWidgetViewState extends ConsumerState { } } - Widget _dynamicContent(AsyncSnapshot<(Cafeteria, CafeteriaMenu)?> snapshot) { + Widget _dynamicContent(AsyncSnapshot<(Cafeteria, CafeteriaMenu?)?> snapshot) { if (snapshot.hasData) { final dishes = ref.watch(cafeteriasViewModel).getTodayDishes(snapshot.data!.$2); @@ -108,16 +108,21 @@ class _CafeteriaWidgetViewState extends ConsumerState { } } else if (snapshot.hasError) { return Card( - child: SizedBox( - height: 150, - child: ErrorHandlingView( - error: snapshot.error!, - errorHandlingViewType: ErrorHandlingViewType.descriptionOnly, - retry: ref.read(cafeteriasViewModel).fetchClosestCafeteria))); + child: SizedBox( + height: 150, + child: ErrorHandlingView( + error: snapshot.error!, + errorHandlingViewType: ErrorHandlingViewType.descriptionOnly, + retry: ref.read(cafeteriasViewModel).fetchClosestCafeteria), + ), + ); } else { - return const Card( - child: SizedBox( - height: 150, child: DelayedLoadingIndicator(name: "Mealplan"))); + return Card( + child: SizedBox( + height: 150, + child: DelayedLoadingIndicator(name: context.localizations.mealPlan), + ), + ); } } }