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), + ), + ); + }, + ); + }); } }