/* SPDX-License-Identifier: GPL-3.0-or-later */ /* Copyright (C) 2024 Marco Groß */ 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 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(); pageController.jumpToPage(visitedIndexes.last); return true; }, child: Scaffold( appBar: AppBar( title: Builder(builder: (context) { return Text(DateFormat.yMMMMd( Localizations.localeOf(context).toString()) .format( context.watch().displayedDate)); }), actions: const [ThemeSwitcherButton()], ), bottomNavigationBar: BottomAppBar( 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, forDate: context .read() .displayedDate, ), ); }, ), 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; final List _visitedIndexes; bool _backButtonWasPressed = false; PageViewStateProvider({required DateTime initialDate, int initialOffset = 0}) : _displayedDate = initialDate, _visitedIndexes = [] { _visitedIndexes.add(initialOffset); } set backButtonWasPressed(val) => _backButtonWasPressed = val; get backButtonWasPressed => _backButtonWasPressed; get displayedDate => _displayedDate; void setDisplayedDate(date) { _displayedDate = date; notifyListeners(); } get visitedIndexes => _visitedIndexes; void addVisitedIndex(int index) { _visitedIndexes.add(index); } void addVisitedindexIfNotVisitedByBackButton(int index) { if (_backButtonWasPressed) { _backButtonWasPressed = false; return; } addVisitedIndex(index); } }