calorimeter/lib/perdate/perdate_widget.dart
Marco a7a7f44050 Make scanned widgets appear in the list instead of putting the info into
the EnterFoodWidget.

1. Make scanned foods appear in the list of foods
2. Remove Controller for entering food

This commit removes the EnterFoodController that was used to put a
scanned food into the EnterFoodWidget.
This is now unnecessary because scanning a product will be distributed
via the FoodBLoC.
2024-09-24 14:41:42 +02:00

140 lines
5.0 KiB
Dart

import 'package:barcode_scan2/barcode_scan2.dart';
import 'package:calorimeter/utils/scan_food_floating_button.dart';
import 'package:calorimeter/utils/app_drawer.dart';
import 'package:calorimeter/food_entry/food_entry_bloc.dart';
import 'package:calorimeter/perdate/entry_list.dart';
import 'package:calorimeter/storage/storage.dart';
import 'package:calorimeter/utils/calendar_floating_button.dart';
import 'package:calorimeter/utils/rectangular_notch_shape.dart';
import 'package:calorimeter/utils/sum_widget.dart';
import 'package:calorimeter/utils/theme_switcher_button.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:intl/intl.dart';
import 'package:provider/provider.dart';
class PerDateWidget extends StatefulWidget {
final DateTime date;
const PerDateWidget({super.key, required this.date});
@override
State<PerDateWidget> createState() => _PerDateWidgetState();
}
class _PerDateWidgetState extends State<PerDateWidget> {
late FoodStorage storage;
late Future<List<FoodEntryState>> entriesFuture;
List<FoodEntryState> entries = [];
@override
void initState() {
storage = FoodStorage.getInstance();
entriesFuture = storage.getEntriesForDate(widget.date);
entriesFuture.then((val) {
entries = val;
});
super.initState();
}
@override
Widget build(BuildContext context) {
return FutureBuilder(
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>(
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()],
),
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) {
_onDateSelected(dateSelected);
},
),
]),
floatingActionButtonLocation:
FloatingActionButtonLocation.endDocked);
}),
);
});
}
void showNewSnackbarWith(BuildContext context, String text) {
var snackbar =
ErrorSnackbar(colorScheme: Theme.of(context).colorScheme, text: text);
ScaffoldMessenger.of(context)
..removeCurrentSnackBar()
..showSnackBar(snackbar);
}
void _onDateSelected(DateTime date) {
Navigator.of(context).push(
MaterialPageRoute(
builder: (context) {
return PerDateWidget(date: date);
},
),
).then((val) {
setState(
() {
entriesFuture = storage.getEntriesForDate(widget.date);
entriesFuture.then(
(val) {
entries = val;
},
);
},
);
});
}
}
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);
}