2024-09-07 23:57:40 +00:00
|
|
|
import 'package:barcode_scan2/barcode_scan2.dart';
|
2024-09-06 23:38:03 +00:00
|
|
|
import 'package:calorimeter/utils/scan_food_floating_button.dart';
|
2024-09-06 16:51:24 +00:00
|
|
|
import 'package:calorimeter/utils/app_drawer.dart';
|
2024-09-06 17:00:25 +00:00
|
|
|
import 'package:calorimeter/food_entry/food_entry_bloc.dart';
|
2024-09-06 16:51:24 +00:00
|
|
|
import 'package:calorimeter/perdate/entry_list.dart';
|
2024-09-06 17:00:25 +00:00
|
|
|
import 'package:calorimeter/storage/storage.dart';
|
2024-09-06 16:51:24 +00:00
|
|
|
import 'package:calorimeter/utils/calendar_floating_button.dart';
|
|
|
|
import 'package:calorimeter/utils/rectangular_notch_shape.dart';
|
2024-09-06 17:00:25 +00:00
|
|
|
import 'package:calorimeter/utils/sum_widget.dart';
|
|
|
|
import 'package:calorimeter/utils/theme_switcher_button.dart';
|
2024-09-06 11:48:56 +00:00
|
|
|
import 'package:flutter/material.dart';
|
|
|
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
|
|
|
import 'package:intl/intl.dart';
|
2024-09-06 22:02:01 +00:00
|
|
|
import 'package:provider/provider.dart';
|
2024-09-06 11:48:56 +00:00
|
|
|
|
|
|
|
class PerDateWidget extends StatefulWidget {
|
|
|
|
final DateTime date;
|
2024-10-03 21:21:13 +00:00
|
|
|
final Function(DateTime?) onDateSelected;
|
|
|
|
const PerDateWidget(
|
|
|
|
{super.key, required this.date, required this.onDateSelected});
|
2024-09-06 11:48:56 +00:00
|
|
|
|
|
|
|
@override
|
|
|
|
State<PerDateWidget> createState() => _PerDateWidgetState();
|
|
|
|
}
|
|
|
|
|
2024-10-03 21:21:13 +00:00
|
|
|
class _PerDateWidgetState extends State<PerDateWidget>
|
|
|
|
with AutomaticKeepAliveClientMixin<PerDateWidget> {
|
2024-09-06 11:48:56 +00:00
|
|
|
late FoodStorage storage;
|
2024-09-09 20:41:48 +00:00
|
|
|
late Future<List<FoodEntryState>> entriesFuture;
|
|
|
|
List<FoodEntryState> entries = [];
|
2024-09-06 11:48:56 +00:00
|
|
|
|
|
|
|
@override
|
|
|
|
void initState() {
|
|
|
|
storage = FoodStorage.getInstance();
|
|
|
|
entriesFuture = storage.getEntriesForDate(widget.date);
|
|
|
|
entriesFuture.then((val) {
|
|
|
|
entries = val;
|
|
|
|
});
|
|
|
|
super.initState();
|
|
|
|
}
|
|
|
|
|
2024-10-03 21:21:13 +00:00
|
|
|
@override
|
|
|
|
void dispose() {
|
|
|
|
super.dispose();
|
|
|
|
}
|
|
|
|
|
2024-09-06 11:48:56 +00:00
|
|
|
@override
|
|
|
|
Widget build(BuildContext context) {
|
2024-10-03 21:21:13 +00:00
|
|
|
super.build(context);
|
|
|
|
|
2024-09-06 11:48:56 +00:00
|
|
|
return FutureBuilder(
|
2024-09-09 20:41:48 +00:00
|
|
|
future: entriesFuture,
|
|
|
|
builder: (context, snapshot) {
|
|
|
|
return snapshot.connectionState != ConnectionState.done
|
|
|
|
? const Center(child: CircularProgressIndicator())
|
|
|
|
: MultiProvider(
|
|
|
|
providers: [
|
|
|
|
BlocProvider(
|
|
|
|
create: (context) => FoodEntryBloc(
|
|
|
|
initialState: PageState(foodEntries: entries),
|
|
|
|
storage: storage,
|
|
|
|
forDate: widget.date,
|
|
|
|
),
|
|
|
|
)
|
|
|
|
],
|
|
|
|
child: BlocConsumer<FoodEntryBloc, PageState>(
|
2024-09-24 15:23:01 +00:00
|
|
|
listener: (context, pageState) {
|
|
|
|
if (pageState.errorString != null) {
|
|
|
|
showNewSnackbarWith(context, pageState.errorString!);
|
|
|
|
}
|
|
|
|
},
|
|
|
|
builder: (context, pageState) {
|
|
|
|
return Scaffold(
|
|
|
|
appBar: AppBar(
|
|
|
|
title: Text(
|
|
|
|
DateFormat.yMMMMd('de').format(widget.date)),
|
|
|
|
actions: const [ThemeSwitcherButton()],
|
2024-09-09 20:41:48 +00:00
|
|
|
),
|
2024-09-24 15:23:01 +00:00
|
|
|
body: FoodEntryList(entries: pageState.foodEntries),
|
|
|
|
bottomNavigationBar: BottomAppBar(
|
|
|
|
shape: const RectangularNotchShape(),
|
|
|
|
color: Theme.of(context).colorScheme.secondary,
|
|
|
|
child: SumWidget(
|
|
|
|
foodEntries: pageState.foodEntries)),
|
|
|
|
drawer: const AppDrawer(),
|
|
|
|
floatingActionButton: OverflowBar(children: [
|
|
|
|
ScanFoodFloatingButton(
|
|
|
|
onPressed: () {
|
|
|
|
var result = BarcodeScanner.scan();
|
|
|
|
context.read<FoodEntryBloc>().add(
|
|
|
|
BarcodeScanned(scanResultFuture: result));
|
|
|
|
},
|
|
|
|
),
|
|
|
|
const SizedBox(width: 8),
|
|
|
|
CalendarFloatingButton(
|
|
|
|
startFromDate: widget.date,
|
|
|
|
onDateSelected: (dateSelected) {
|
2024-10-03 21:21:13 +00:00
|
|
|
widget.onDateSelected(dateSelected);
|
2024-09-24 15:23:01 +00:00
|
|
|
},
|
|
|
|
),
|
|
|
|
]),
|
|
|
|
floatingActionButtonLocation:
|
|
|
|
FloatingActionButtonLocation.endDocked);
|
|
|
|
},
|
|
|
|
),
|
2024-09-09 20:41:48 +00:00
|
|
|
);
|
|
|
|
});
|
2024-09-06 11:48:56 +00:00
|
|
|
}
|
2024-09-06 22:02:01 +00:00
|
|
|
|
2024-09-08 13:07:39 +00:00
|
|
|
void showNewSnackbarWith(BuildContext context, String text) {
|
|
|
|
var snackbar =
|
|
|
|
ErrorSnackbar(colorScheme: Theme.of(context).colorScheme, text: text);
|
2024-09-06 22:02:01 +00:00
|
|
|
|
2024-09-13 14:49:38 +00:00
|
|
|
ScaffoldMessenger.of(context)
|
|
|
|
..removeCurrentSnackBar()
|
|
|
|
..showSnackBar(snackbar);
|
|
|
|
}
|
|
|
|
|
2024-10-03 21:21:13 +00:00
|
|
|
@override
|
|
|
|
bool get wantKeepAlive => true;
|
2024-09-06 22:02:01 +00:00
|
|
|
}
|
2024-09-08 13:07:39 +00:00
|
|
|
|
|
|
|
class ErrorSnackbar extends SnackBar {
|
|
|
|
final String text;
|
|
|
|
final ColorScheme colorScheme;
|
|
|
|
ErrorSnackbar({
|
|
|
|
required this.text,
|
|
|
|
required this.colorScheme,
|
|
|
|
super.key,
|
|
|
|
}) : super(
|
|
|
|
content: Text(text, style: TextStyle(color: colorScheme.onError)),
|
|
|
|
backgroundColor: colorScheme.error);
|
|
|
|
}
|