calorimeter/lib/perdate/perdate_pageview_controller.dart
2024-12-07 13:39:11 +01:00

150 lines
5.1 KiB
Dart

/* SPDX-License-Identifier: GPL-3.0-or-later */
/* Copyright (C) 2024 Marco Groß <mgross@sw-gross.de> */
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<PageViewStateProvider>().backButtonWasPressed = true;
var visitedIndexes =
context.read<PageViewStateProvider>().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('de').format(
context.watch<PageViewStateProvider>().displayedDate));
}),
actions: const [ThemeSwitcherButton()],
),
bottomNavigationBar: BottomAppBar(
shape: const RectangularNotchShape(),
color: Theme.of(context).colorScheme.secondary,
child: Builder(builder: (context) {
return SumWidget(
date: context.watch<PageViewStateProvider>().displayedDate);
}),
),
drawer: const AppDrawer(),
floatingActionButton: OverflowBar(children: [
ScanFoodFAB(
onPressed: () {
var result = BarcodeScanner.scan();
context.read<FoodEntryBloc>().add(
BarcodeScanned(
scanResultFuture: result,
forDate: context
.read<PageViewStateProvider>()
.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<int> _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);
}
}