From 3faf5295b150f551ce98c1e6eb2049348a95f30a Mon Sep 17 00:00:00 2001 From: Marco Date: Mon, 7 Oct 2024 01:44:19 +0200 Subject: [PATCH 1/2] Trying to fix bottom bar --- lib/main.dart | 12 +- lib/perdate/perdate_pageview.dart | 94 +++++--------- lib/perdate/perdate_pageview_controller.dart | 126 +++++++++++++++++++ lib/perdate/perdate_widget.dart | 90 +++++-------- lib/storage/storage.dart | 3 +- lib/utils/calendar_floating_button.dart | 16 +-- lib/utils/date_time_helper.dart | 12 ++ lib/utils/scan_food_floating_button.dart | 4 +- lib/utils/scan_food_notifier.dart | 48 +++++++ 9 files changed, 266 insertions(+), 139 deletions(-) create mode 100644 lib/perdate/perdate_pageview_controller.dart create mode 100644 lib/utils/date_time_helper.dart create mode 100644 lib/utils/scan_food_notifier.dart diff --git a/lib/main.dart b/lib/main.dart index 7166f6a..55a36b4 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -1,6 +1,8 @@ import 'package:calorimeter/food_entry/food_entry_bloc.dart'; import 'package:calorimeter/perdate/perdate_pageview.dart'; +import 'package:calorimeter/perdate/perdate_pageview_controller.dart'; import 'package:calorimeter/storage/storage.dart'; +import 'package:calorimeter/utils/date_time_helper.dart'; import 'package:calorimeter/utils/settings_bloc.dart'; import 'package:calorimeter/utils/theme_bloc.dart'; import 'package:flutter/material.dart'; @@ -87,14 +89,8 @@ class MainApp extends StatelessWidget { GoRoute( path: '/', builder: (context, state) { - return PerDatePageview( - initalDate: DateTime.now().copyWith( - hour: 0, - minute: 0, - second: 0, - millisecond: 0, - microsecond: 0, - ), + return PerDatePageViewController( + initialDate: DateTimeHelper.now(), ); }, ), diff --git a/lib/perdate/perdate_pageview.dart b/lib/perdate/perdate_pageview.dart index f076012..41fe57f 100644 --- a/lib/perdate/perdate_pageview.dart +++ b/lib/perdate/perdate_pageview.dart @@ -1,76 +1,46 @@ +import 'dart:developer'; + +import 'package:calorimeter/perdate/perdate_pageview_controller.dart'; import 'package:calorimeter/perdate/perdate_widget.dart'; import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; -class PerDatePageview extends StatefulWidget { +class PerDatePageView extends StatelessWidget { // this is the date for which the PerDate widget will be shown on screen // left of it will be yesterday's PerDate widget // right of it will be tomorrow's PerDate widget - final DateTime initalDate; - const PerDatePageview({required this.initalDate, super.key}); + final DateTime initialDate; + final PageController pageController; - @override - State createState() => _PerDatePageviewState(); -} - -class _PerDatePageviewState extends State { - late PageController pageController; - late DateTime displayedDate; - late List visitedIndexes = []; - final int initialOffset = 36500000; - - //TODO: that is just ugly - bool backButtonWasPressed = false; - - @override - void initState() { - super.initState(); - pageController = PageController(initialPage: initialOffset); - displayedDate = widget.initalDate; - visitedIndexes.add(initialOffset); - } + const PerDatePageView({ + required this.initialDate, + required this.pageController, + super.key, + }); @override Widget build(BuildContext context) { - return BackButtonListener( - onBackButtonPressed: () async { - if (visitedIndexes.length == 1) { - return false; - } + log("PerDatePageView's build()"); + return PageView.builder( + reverse: true, + controller: pageController, + onPageChanged: (value) { + log("onPageChanged() with value $value"); - visitedIndexes.removeLast(); + var diff = value - pageController.initialPage; + var newDate = initialDate.subtract(Duration(days: diff)); + log("newDate = $newDate"); + context.read().setDisplayedDate(newDate); + }, + itemBuilder: (context, index) { + log("itemBuilder() called with index $index"); + var dateToBuildWidgetFor = initialDate + .subtract(Duration(days: index - pageController.initialPage)); - backButtonWasPressed = true; - pageController.jumpToPage(visitedIndexes.last); - - return true; - }, - child: PageView.builder( - reverse: true, - controller: pageController, - onPageChanged: (value) { - if (backButtonWasPressed) { - backButtonWasPressed = false; - return; - } - - visitedIndexes.add(value); - }, - itemBuilder: (context, index) { - var dateToBuildWidgetFor = - displayedDate.subtract(Duration(days: index - initialOffset)); - - return PerDateWidget( - key: ValueKey(dateToBuildWidgetFor.toString()), - date: dateToBuildWidgetFor.copyWith(isUtc: true), - onDateSelected: (dateSelected) { - if (dateSelected == null) return; - - var diff = dateSelected.difference(dateToBuildWidgetFor); - var newIndex = index - diff.inDays; - - pageController.jumpToPage(newIndex); - }); - }), - ); + return PerDateWidget( + key: ValueKey(dateToBuildWidgetFor.toString()), + date: dateToBuildWidgetFor, + ); + }); } } diff --git a/lib/perdate/perdate_pageview_controller.dart b/lib/perdate/perdate_pageview_controller.dart new file mode 100644 index 0000000..770ce44 --- /dev/null +++ b/lib/perdate/perdate_pageview_controller.dart @@ -0,0 +1,126 @@ +import 'dart:developer'; + +import 'package:barcode_scan2/barcode_scan2.dart'; +import 'package:calorimeter/food_entry/food_entry_bloc.dart'; +import 'package:calorimeter/perdate/perdate_pageview.dart'; +import 'package:calorimeter/utils/app_drawer.dart'; +import 'package:calorimeter/utils/calendar_floating_button.dart'; +import 'package:calorimeter/utils/date_time_helper.dart'; +import 'package:calorimeter/utils/rectangular_notch_shape.dart'; +import 'package:calorimeter/utils/scan_food_floating_button.dart'; +import 'package:calorimeter/utils/sum_widget.dart'; +import 'package:calorimeter/utils/theme_switcher_button.dart'; +import 'package:flutter/material.dart'; +import 'package:intl/intl.dart'; +import 'package:provider/provider.dart'; + +class PerDatePageViewController extends StatelessWidget { + // this is the date for which the PerDate widget will be shown on screen + // left of it will be yesterday's PerDate widget + // right of it will be tomorrow's PerDate widget + final DateTime initialDate; + final PageController pageController; + static final int initialOffset = 36500000; + + const PerDatePageViewController._( + {required this.initialDate, required this.pageController}); + + factory PerDatePageViewController({required initialDate}) { + return PerDatePageViewController._( + initialDate: initialDate, + pageController: PageController(initialPage: initialOffset)); + } + + @override + Widget build(BuildContext context) { + return BackButtonListener( + onBackButtonPressed: () async { + var visitedIndexes = + context.read().visitedIndexes; + if (visitedIndexes.length == 1) { + return false; + } + + visitedIndexes.removeLast(); + + pageController.jumpToPage(visitedIndexes.last); + + return true; + }, + child: ChangeNotifierProvider( + create: (context) => PageViewStateProvider( + initialDate: initialDate, + initialOffset: initialOffset, + ), + child: Builder(builder: (context) { + return Scaffold( + appBar: AppBar( + title: Builder(builder: (context) { + return Text(DateFormat.yMMMMd('de').format( + context.watch().displayedDate)); + }), + actions: const [ThemeSwitcherButton()], + ), + bottomNavigationBar: BottomAppBar( + shape: const RectangularNotchShape(), + color: Theme.of(context).colorScheme.secondary, + child: SumWidget(foodEntries: [])), + drawer: const AppDrawer(), + floatingActionButton: OverflowBar(children: [ + ScanFoodFAB( + onPressed: () { + var result = BarcodeScanner.scan(); + context + .read() + .add(BarcodeScanned(scanResultFuture: result)); + }, + ), + const SizedBox(width: 8), + CalendarFAB( + startFromDate: DateTimeHelper.now(), + onDateSelected: (dateSelected) { + if (dateSelected == null) return; + + var dateDiff = dateSelected.difference(initialDate).inDays; + + log("dateDiff = $dateDiff"); + pageController.jumpToPage(initialOffset - dateDiff); + }, + ), + ]), + floatingActionButtonLocation: + FloatingActionButtonLocation.endDocked, + body: PerDatePageView( + pageController: pageController, + initialDate: initialDate, + ), + ); + }), + ), + ); + } +} + +class PageViewStateProvider with ChangeNotifier { + DateTime _displayedDate; + List visitedIndexes = []; + bool _backButtonWasPressed = false; + + PageViewStateProvider({required DateTime initialDate, int initialOffset = 0}) + : _displayedDate = initialDate { + visitedIndexes.add(initialOffset); + } + + set backButtonWasPressed(val) => _backButtonWasPressed = val; + get backButtonWasPressed => _backButtonWasPressed; + + get displayedDate => _displayedDate; + void setDisplayedDate(date) { + _displayedDate = date; + notifyListeners(); + } + + void addVisitedindex(int index) { + visitedIndexes.add(index); + } +} diff --git a/lib/perdate/perdate_widget.dart b/lib/perdate/perdate_widget.dart index e5437c4..12c6156 100644 --- a/lib/perdate/perdate_widget.dart +++ b/lib/perdate/perdate_widget.dart @@ -1,22 +1,13 @@ -import 'package:barcode_scan2/barcode_scan2.dart'; -import 'package:calorimeter/utils/scan_food_floating_button.dart'; -import 'package:calorimeter/utils/app_drawer.dart'; import 'package:calorimeter/food_entry/food_entry_bloc.dart'; import 'package:calorimeter/perdate/entry_list.dart'; import 'package:calorimeter/storage/storage.dart'; -import 'package:calorimeter/utils/calendar_floating_button.dart'; -import 'package:calorimeter/utils/rectangular_notch_shape.dart'; -import 'package:calorimeter/utils/sum_widget.dart'; -import 'package:calorimeter/utils/theme_switcher_button.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; -import 'package:intl/intl.dart'; +import 'package:provider/provider.dart'; class PerDateWidget extends StatefulWidget { final DateTime date; - final Function(DateTime?) onDateSelected; - const PerDateWidget( - {super.key, required this.date, required this.onDateSelected}); + const PerDateWidget({super.key, required this.date}); @override State createState() => _PerDateWidgetState(); @@ -25,13 +16,16 @@ class PerDateWidget extends StatefulWidget { class _PerDateWidgetState extends State with AutomaticKeepAliveClientMixin { late FoodStorage storage; + late Future> entriesFuture; List entries = []; @override void initState() { - context - .read() - .add(PageBeingInitialized(forDate: widget.date)); + storage = FoodStorage.getInstance(); + entriesFuture = storage.getEntriesForDate(widget.date); + entriesFuture.then((val) { + entries = val; + }); super.initState(); } @@ -44,51 +38,29 @@ class _PerDateWidgetState extends State Widget build(BuildContext context) { super.build(context); - return BlocConsumer( - listener: (context, pageState) { - if (pageState.errorString != null) { - showNewSnackbarWith(context, pageState.errorString!); - } - }, - builder: (context, globalState) { - return Scaffold( - appBar: AppBar( - title: Text(DateFormat.yMMMMd('de').format(widget.date)), - actions: const [ThemeSwitcherButton()], - ), - body: FoodEntryList( - entries: globalState.foodEntries[widget.date] ?? [], - date: widget.date), - bottomNavigationBar: BottomAppBar( - shape: const RectangularNotchShape(), - color: Theme.of(context).colorScheme.secondary, - child: SumWidget( - foodEntries: globalState.foodEntries[widget.date] ?? [])), - drawer: const AppDrawer(), - floatingActionButton: OverflowBar(children: [ - ScanFoodFloatingButton( - onPressed: () { - var result = BarcodeScanner.scan(); - context.read().add( - BarcodeScanned( - scanResultFuture: result, - forDate: widget.date, - ), - ); - }, - ), - const SizedBox(width: 8), - CalendarFloatingButton( - startFromDate: widget.date, - onDateSelected: (dateSelected) { - widget.onDateSelected(dateSelected); - }, - ), - ]), - floatingActionButtonLocation: - FloatingActionButtonLocation.endDocked); - }, - ); + return FutureBuilder( + future: entriesFuture, + builder: (context, snapshot) { + return snapshot.connectionState != ConnectionState.done + ? const Center(child: CircularProgressIndicator()) + : BlocProvider( + create: (context) => FoodEntryBloc( + initialState: PageState(foodEntries: entries), + storage: storage, + forDate: widget.date, + ), + child: BlocConsumer( + listener: (context, pageState) { + if (pageState.errorString != null) { + showNewSnackbarWith(context, pageState.errorString!); + } + }, + builder: (context, pageState) { + return FoodEntryList(entries: pageState.foodEntries); + }, + ), + ); + }); } void showNewSnackbarWith(BuildContext context, String text) { diff --git a/lib/storage/storage.dart b/lib/storage/storage.dart index 4b72eeb..b536135 100644 --- a/lib/storage/storage.dart +++ b/lib/storage/storage.dart @@ -1,6 +1,7 @@ import 'dart:io'; import 'package:calorimeter/food_entry/food_entry_bloc.dart'; +import 'package:calorimeter/utils/date_time_helper.dart'; import 'package:path_provider/path_provider.dart'; import 'package:universal_platform/universal_platform.dart'; @@ -157,7 +158,7 @@ class FoodStorage { // get a list of dates of the last 365 days var dates = List.generate(365, (idx) { var durationToPast = Duration(days: idx); - return DateTime.now().subtract(durationToPast); + return DateTimeHelper.now().subtract(durationToPast); }); for (var date in dates.reversed) { diff --git a/lib/utils/calendar_floating_button.dart b/lib/utils/calendar_floating_button.dart index 032cb5d..15de917 100644 --- a/lib/utils/calendar_floating_button.dart +++ b/lib/utils/calendar_floating_button.dart @@ -1,10 +1,11 @@ +import 'package:calorimeter/utils/date_time_helper.dart'; import 'package:flutter/material.dart'; -class CalendarFloatingButton extends StatelessWidget { +class CalendarFAB extends StatelessWidget { final DateTime startFromDate; final Function(DateTime?) onDateSelected; - const CalendarFloatingButton( + const CalendarFAB( {super.key, required this.startFromDate, required this.onDateSelected}); @override @@ -15,17 +16,18 @@ class CalendarFloatingButton extends StatelessWidget { locale: const Locale('de'), context: context, initialDate: startFromDate, - currentDate: DateTime.now(), - firstDate: DateTime.now().subtract(const Duration(days: 365 * 10)), - lastDate: DateTime.now().add(const Duration(days: 365 * 10)), + currentDate: DateTimeHelper.now(), + firstDate: + DateTimeHelper.now().subtract(const Duration(days: 365 * 10)), + lastDate: DateTimeHelper.now().add(const Duration(days: 365 * 10)), ); if (!context.mounted) return; - onDateSelected(datePicked); + onDateSelected(datePicked?.copyWith(isUtc: true)); }, heroTag: "calendarFAB", - child: const Icon(Icons.today), + child: const Icon(Icons.date_range), ); } } diff --git a/lib/utils/date_time_helper.dart b/lib/utils/date_time_helper.dart new file mode 100644 index 0000000..d87bec1 --- /dev/null +++ b/lib/utils/date_time_helper.dart @@ -0,0 +1,12 @@ +class DateTimeHelper { + static DateTime now() { + return DateTime.now().copyWith( + isUtc: true, + hour: 0, + minute: 0, + second: 0, + millisecond: 0, + microsecond: 0, + ); + } +} diff --git a/lib/utils/scan_food_floating_button.dart b/lib/utils/scan_food_floating_button.dart index 95b7695..cdb1667 100644 --- a/lib/utils/scan_food_floating_button.dart +++ b/lib/utils/scan_food_floating_button.dart @@ -1,8 +1,8 @@ import 'package:flutter/material.dart'; -class ScanFoodFloatingButton extends StatelessWidget { +class ScanFoodFAB extends StatelessWidget { final Function() onPressed; - const ScanFoodFloatingButton({super.key, required this.onPressed}); + const ScanFoodFAB({super.key, required this.onPressed}); @override Widget build(BuildContext context) { diff --git a/lib/utils/scan_food_notifier.dart b/lib/utils/scan_food_notifier.dart new file mode 100644 index 0000000..b1b6237 --- /dev/null +++ b/lib/utils/scan_food_notifier.dart @@ -0,0 +1,48 @@ +import 'package:barcode_scan2/barcode_scan2.dart'; +import 'package:calorimeter/food_entry/food_entry_bloc.dart'; +import 'package:calorimeter/food_scan/food_fact_lookup.dart'; +import 'package:flutter/material.dart'; + +class ScanFoodNotifier with ChangeNotifier { + void handleBarcodeScannedEvent(BarcodeScanned barcode) async { + var client = FoodFactLookupClient(); + var scanResult = await barcode.scanResultFuture; + + if (scanResult.type == ResultType.Cancelled) { + return; + } + if (scanResult.type == ResultType.Error) { + return; + } + var responseFuture = client.retrieveFoodInfo(scanResult.rawContent); + + var newEntryWaiting = FoodEntryState( + kcalPer100: 0, + name: "", + mass: 0, + waitingForNetwork: true, + isSelected: false, + ); + + await responseFuture.then((response) async { + if (response.status == + FoodFactResponseStatus.foodFactServerNotReachable) { + return; + } + + var newEntryFinishedWaiting = FoodEntryState( + name: response.food?.name ?? "", + mass: response.food?.mass ?? 0, + kcalPer100: response.food?.kcalPer100g ?? 0, + waitingForNetwork: false, + isSelected: false, + ); + }); + } +} + +class BarcodeScanned { + final Future scanResultFuture; + + BarcodeScanned({required this.scanResultFuture}); +} From cdabd1ee947a6fc49b1b3bc7d81234465e20b331 Mon Sep 17 00:00:00 2001 From: Marco Date: Fri, 18 Oct 2024 02:44:43 +0200 Subject: [PATCH 2/2] Fix back button when going back after swiping --- lib/main.dart | 9 +- lib/perdate/perdate_pageview.dart | 4 + lib/perdate/perdate_pageview_controller.dart | 87 ++++++++++++-------- lib/perdate/perdate_widget.dart | 54 ++++-------- lib/utils/scan_food_notifier.dart | 48 ----------- lib/utils/sum_widget.dart | 86 ++++++++++--------- 6 files changed, 119 insertions(+), 169 deletions(-) delete mode 100644 lib/utils/scan_food_notifier.dart diff --git a/lib/main.dart b/lib/main.dart index 55a36b4..7dcad6a 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -1,5 +1,4 @@ import 'package:calorimeter/food_entry/food_entry_bloc.dart'; -import 'package:calorimeter/perdate/perdate_pageview.dart'; import 'package:calorimeter/perdate/perdate_pageview_controller.dart'; import 'package:calorimeter/storage/storage.dart'; import 'package:calorimeter/utils/date_time_helper.dart'; @@ -20,14 +19,8 @@ void main() async { var storage = await FoodStorage.create(); await storage.buildFoodLookupDatabase(); - timeNow = DateTime.now().copyWith( - hour: 0, - isUtc: true, - minute: 0, - second: 0, - millisecond: 0, - microsecond: 0); + timeNow = DateTimeHelper.now(); entriesForToday = await storage.getEntriesForDate(timeNow); var kcalLimit = await storage.readLimit(); diff --git a/lib/perdate/perdate_pageview.dart b/lib/perdate/perdate_pageview.dart index 41fe57f..ed07217 100644 --- a/lib/perdate/perdate_pageview.dart +++ b/lib/perdate/perdate_pageview.dart @@ -30,6 +30,10 @@ class PerDatePageView extends StatelessWidget { var diff = value - pageController.initialPage; var newDate = initialDate.subtract(Duration(days: diff)); log("newDate = $newDate"); + + context + .read() + .addVisitedindexIfNotVisitedByBackButton(value); context.read().setDisplayedDate(newDate); }, itemBuilder: (context, index) { diff --git a/lib/perdate/perdate_pageview_controller.dart b/lib/perdate/perdate_pageview_controller.dart index 770ce44..c40bbb7 100644 --- a/lib/perdate/perdate_pageview_controller.dart +++ b/lib/perdate/perdate_pageview_controller.dart @@ -33,27 +33,27 @@ class PerDatePageViewController extends StatelessWidget { @override Widget build(BuildContext context) { - return BackButtonListener( - onBackButtonPressed: () async { - var visitedIndexes = - context.read().visitedIndexes; - if (visitedIndexes.length == 1) { - return false; - } + return ChangeNotifierProvider( + create: (context) => PageViewStateProvider( + initialDate: initialDate, + initialOffset: initialOffset, + ), + child: Builder(builder: (context) { + return BackButtonListener( + onBackButtonPressed: () async { + context.read().backButtonWasPressed = true; + var visitedIndexes = + context.read().visitedIndexes; + if (visitedIndexes.length == 1) { + return false; + } - visitedIndexes.removeLast(); + visitedIndexes.removeLast(); + pageController.jumpToPage(visitedIndexes.last); - pageController.jumpToPage(visitedIndexes.last); - - return true; - }, - child: ChangeNotifierProvider( - create: (context) => PageViewStateProvider( - initialDate: initialDate, - initialOffset: initialOffset, - ), - child: Builder(builder: (context) { - return Scaffold( + return true; + }, + child: Scaffold( appBar: AppBar( title: Builder(builder: (context) { return Text(DateFormat.yMMMMd('de').format( @@ -62,17 +62,26 @@ class PerDatePageViewController extends StatelessWidget { actions: const [ThemeSwitcherButton()], ), bottomNavigationBar: BottomAppBar( - shape: const RectangularNotchShape(), - color: Theme.of(context).colorScheme.secondary, - child: SumWidget(foodEntries: [])), + shape: const RectangularNotchShape(), + color: Theme.of(context).colorScheme.secondary, + child: Builder(builder: (context) { + return SumWidget( + date: context.watch().displayedDate); + }), + ), drawer: const AppDrawer(), floatingActionButton: OverflowBar(children: [ ScanFoodFAB( onPressed: () { var result = BarcodeScanner.scan(); - context - .read() - .add(BarcodeScanned(scanResultFuture: result)); + context.read().add( + BarcodeScanned( + scanResultFuture: result, + forDate: context + .read() + .displayedDate, + ), + ); }, ), const SizedBox(width: 8), @@ -94,21 +103,22 @@ class PerDatePageViewController extends StatelessWidget { pageController: pageController, initialDate: initialDate, ), - ); - }), - ), + ), + ); + }), ); } } class PageViewStateProvider with ChangeNotifier { DateTime _displayedDate; - List visitedIndexes = []; + final List _visitedIndexes; bool _backButtonWasPressed = false; PageViewStateProvider({required DateTime initialDate, int initialOffset = 0}) - : _displayedDate = initialDate { - visitedIndexes.add(initialOffset); + : _displayedDate = initialDate, + _visitedIndexes = [] { + _visitedIndexes.add(initialOffset); } set backButtonWasPressed(val) => _backButtonWasPressed = val; @@ -120,7 +130,18 @@ class PageViewStateProvider with ChangeNotifier { notifyListeners(); } - void addVisitedindex(int index) { - visitedIndexes.add(index); + get visitedIndexes => _visitedIndexes; + + void addVisitedIndex(int index) { + _visitedIndexes.add(index); + } + + void addVisitedindexIfNotVisitedByBackButton(int index) { + if (_backButtonWasPressed) { + _backButtonWasPressed = false; + return; + } + + addVisitedIndex(index); } } diff --git a/lib/perdate/perdate_widget.dart b/lib/perdate/perdate_widget.dart index 12c6156..4ccee06 100644 --- a/lib/perdate/perdate_widget.dart +++ b/lib/perdate/perdate_widget.dart @@ -1,9 +1,7 @@ import 'package:calorimeter/food_entry/food_entry_bloc.dart'; import 'package:calorimeter/perdate/entry_list.dart'; -import 'package:calorimeter/storage/storage.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; -import 'package:provider/provider.dart'; class PerDateWidget extends StatefulWidget { final DateTime date; @@ -15,52 +13,30 @@ class PerDateWidget extends StatefulWidget { class _PerDateWidgetState extends State with AutomaticKeepAliveClientMixin { - late FoodStorage storage; - late Future> entriesFuture; - List entries = []; - @override void initState() { - storage = FoodStorage.getInstance(); - entriesFuture = storage.getEntriesForDate(widget.date); - entriesFuture.then((val) { - entries = val; - }); + context + .read() + .add(PageBeingInitialized(forDate: widget.date)); super.initState(); } - @override - void dispose() { - super.dispose(); - } - @override Widget build(BuildContext context) { super.build(context); - return FutureBuilder( - future: entriesFuture, - builder: (context, snapshot) { - return snapshot.connectionState != ConnectionState.done - ? const Center(child: CircularProgressIndicator()) - : BlocProvider( - create: (context) => FoodEntryBloc( - initialState: PageState(foodEntries: entries), - storage: storage, - forDate: widget.date, - ), - child: BlocConsumer( - listener: (context, pageState) { - if (pageState.errorString != null) { - showNewSnackbarWith(context, pageState.errorString!); - } - }, - builder: (context, pageState) { - return FoodEntryList(entries: pageState.foodEntries); - }, - ), - ); - }); + return BlocConsumer( + listener: (context, pageState) { + if (pageState.errorString != null) { + showNewSnackbarWith(context, pageState.errorString!); + } + }, + builder: (context, pageState) { + return FoodEntryList( + entries: pageState.foodEntries[widget.date] ?? [], + date: widget.date); + }, + ); } void showNewSnackbarWith(BuildContext context, String text) { diff --git a/lib/utils/scan_food_notifier.dart b/lib/utils/scan_food_notifier.dart deleted file mode 100644 index b1b6237..0000000 --- a/lib/utils/scan_food_notifier.dart +++ /dev/null @@ -1,48 +0,0 @@ -import 'package:barcode_scan2/barcode_scan2.dart'; -import 'package:calorimeter/food_entry/food_entry_bloc.dart'; -import 'package:calorimeter/food_scan/food_fact_lookup.dart'; -import 'package:flutter/material.dart'; - -class ScanFoodNotifier with ChangeNotifier { - void handleBarcodeScannedEvent(BarcodeScanned barcode) async { - var client = FoodFactLookupClient(); - var scanResult = await barcode.scanResultFuture; - - if (scanResult.type == ResultType.Cancelled) { - return; - } - if (scanResult.type == ResultType.Error) { - return; - } - var responseFuture = client.retrieveFoodInfo(scanResult.rawContent); - - var newEntryWaiting = FoodEntryState( - kcalPer100: 0, - name: "", - mass: 0, - waitingForNetwork: true, - isSelected: false, - ); - - await responseFuture.then((response) async { - if (response.status == - FoodFactResponseStatus.foodFactServerNotReachable) { - return; - } - - var newEntryFinishedWaiting = FoodEntryState( - name: response.food?.name ?? "", - mass: response.food?.mass ?? 0, - kcalPer100: response.food?.kcalPer100g ?? 0, - waitingForNetwork: false, - isSelected: false, - ); - }); - } -} - -class BarcodeScanned { - final Future scanResultFuture; - - BarcodeScanned({required this.scanResultFuture}); -} diff --git a/lib/utils/sum_widget.dart b/lib/utils/sum_widget.dart index 8e08e0d..ca444e2 100644 --- a/lib/utils/sum_widget.dart +++ b/lib/utils/sum_widget.dart @@ -4,53 +4,57 @@ import 'package:calorimeter/food_entry/food_entry_bloc.dart'; import 'package:calorimeter/utils/settings_bloc.dart'; class SumWidget extends StatelessWidget { - final List foodEntries; - const SumWidget({required this.foodEntries, super.key}); + final DateTime date; + + const SumWidget({super.key, required this.date}); @override Widget build(BuildContext context) { - return BlocBuilder( - builder: (context, state) { - var sum = 0.0; - for (var entry in foodEntries) { - sum += entry.kcalPer100 / 100 * entry.mass; - } - var diff = state.kcalLimit - sum; - var diffLimit = state.kcalLimit ~/ 4; + return BlocBuilder( + builder: (context, entryState) { + return BlocBuilder( + builder: (context, settingsState) { + var sum = 0.0; + for (var entry in entryState.foodEntries[date] ?? []) { + sum += entry.kcalPer100 / 100 * entry.mass; + } + var diff = settingsState.kcalLimit - sum; + var diffLimit = settingsState.kcalLimit ~/ 4; - var textColor = Theme.of(context).colorScheme.onSecondary; - var newTextColor = textColor; - var brightness = Theme.of(context).brightness; + var textColor = Theme.of(context).colorScheme.onSecondary; + var newTextColor = textColor; + var brightness = Theme.of(context).brightness; - switch (brightness) { - case Brightness.dark: - if (diff < 0) { - newTextColor = Colors.red[900]!; - } else if (diff < diffLimit) { - newTextColor = Colors.orange[900]!; - } - break; + switch (brightness) { + case Brightness.dark: + if (diff < 0) { + newTextColor = Colors.red[900]!; + } else if (diff < diffLimit) { + newTextColor = Colors.orange[900]!; + } + break; - case Brightness.light: - if (diff < 0) { - newTextColor = Colors.redAccent; - } else if (diff < diffLimit) { - newTextColor = Colors.orangeAccent; - } - break; - } + case Brightness.light: + if (diff < 0) { + newTextColor = Colors.redAccent; + } else if (diff < diffLimit) { + newTextColor = Colors.orangeAccent; + } + break; + } - return Align( - alignment: Alignment.centerLeft, - child: Text( - 'kcal heute: ${sum.ceil().toString()}/${state.kcalLimit.ceil()}', - style: Theme.of(context) - .textTheme - .bodyLarge! - .copyWith(color: newTextColor), - ), - ); - }, - ); + return Align( + alignment: Alignment.centerLeft, + child: Text( + 'kcal heute: ${sum.ceil().toString()}/${settingsState.kcalLimit.ceil()}', + style: Theme.of(context) + .textTheme + .bodyLarge! + .copyWith(color: newTextColor), + ), + ); + }, + ); + }); } }