2024-12-07 12:29:34 +00:00
|
|
|
/* SPDX-License-Identifier: GPL-3.0-or-later */
|
2024-12-07 12:39:11 +00:00
|
|
|
/* Copyright (C) 2024 Marco Groß <mgross@sw-gross.de> */
|
2024-10-06 23:44:19 +00:00
|
|
|
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) {
|
2024-10-18 00:44:43 +00:00
|
|
|
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(
|
2024-10-06 23:44:19 +00:00
|
|
|
appBar: AppBar(
|
|
|
|
title: Builder(builder: (context) {
|
2024-12-10 21:37:13 +00:00
|
|
|
return Text(DateFormat.yMMMMd(
|
|
|
|
Localizations.localeOf(context).toString())
|
|
|
|
.format(
|
|
|
|
context.watch<PageViewStateProvider>().displayedDate));
|
2024-10-06 23:44:19 +00:00
|
|
|
}),
|
|
|
|
actions: const [ThemeSwitcherButton()],
|
|
|
|
),
|
|
|
|
bottomNavigationBar: BottomAppBar(
|
2024-10-18 00:44:43 +00:00
|
|
|
shape: const RectangularNotchShape(),
|
|
|
|
color: Theme.of(context).colorScheme.secondary,
|
|
|
|
child: Builder(builder: (context) {
|
|
|
|
return SumWidget(
|
|
|
|
date: context.watch<PageViewStateProvider>().displayedDate);
|
|
|
|
}),
|
|
|
|
),
|
2024-10-06 23:44:19 +00:00
|
|
|
drawer: const AppDrawer(),
|
|
|
|
floatingActionButton: OverflowBar(children: [
|
|
|
|
ScanFoodFAB(
|
|
|
|
onPressed: () {
|
|
|
|
var result = BarcodeScanner.scan();
|
2024-10-18 00:44:43 +00:00
|
|
|
context.read<FoodEntryBloc>().add(
|
|
|
|
BarcodeScanned(
|
|
|
|
scanResultFuture: result,
|
|
|
|
forDate: context
|
|
|
|
.read<PageViewStateProvider>()
|
|
|
|
.displayedDate,
|
|
|
|
),
|
|
|
|
);
|
2024-10-06 23:44:19 +00:00
|
|
|
},
|
|
|
|
),
|
|
|
|
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,
|
|
|
|
),
|
2024-10-18 00:44:43 +00:00
|
|
|
),
|
|
|
|
);
|
|
|
|
}),
|
2024-10-06 23:44:19 +00:00
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
class PageViewStateProvider with ChangeNotifier {
|
|
|
|
DateTime _displayedDate;
|
2024-10-18 00:44:43 +00:00
|
|
|
final List<int> _visitedIndexes;
|
2024-10-06 23:44:19 +00:00
|
|
|
bool _backButtonWasPressed = false;
|
|
|
|
|
|
|
|
PageViewStateProvider({required DateTime initialDate, int initialOffset = 0})
|
2024-10-18 00:44:43 +00:00
|
|
|
: _displayedDate = initialDate,
|
|
|
|
_visitedIndexes = [] {
|
|
|
|
_visitedIndexes.add(initialOffset);
|
2024-10-06 23:44:19 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
set backButtonWasPressed(val) => _backButtonWasPressed = val;
|
|
|
|
get backButtonWasPressed => _backButtonWasPressed;
|
|
|
|
|
|
|
|
get displayedDate => _displayedDate;
|
|
|
|
void setDisplayedDate(date) {
|
|
|
|
_displayedDate = date;
|
|
|
|
notifyListeners();
|
|
|
|
}
|
|
|
|
|
2024-10-18 00:44:43 +00:00
|
|
|
get visitedIndexes => _visitedIndexes;
|
|
|
|
|
|
|
|
void addVisitedIndex(int index) {
|
|
|
|
_visitedIndexes.add(index);
|
|
|
|
}
|
|
|
|
|
|
|
|
void addVisitedindexIfNotVisitedByBackButton(int index) {
|
|
|
|
if (_backButtonWasPressed) {
|
|
|
|
_backButtonWasPressed = false;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
addVisitedIndex(index);
|
2024-10-06 23:44:19 +00:00
|
|
|
}
|
|
|
|
}
|