Compare commits

...

6 Commits

Author SHA1 Message Date
a3eb907a8e Merge pull request 'Change behavior of global state' (#11) from fix-global-state into master
Reviewed-on: #11
2025-01-12 16:24:34 +00:00
7728ec3b66 Change behavior of global state
Until now, FoodEntryBloc (which is holding the global state  for every
day) would cause a change in every widget in the tree. For example, when
an entry for one day gets added, all other entries in opened days would
also be rebuilt.

Now, the GlobalState will be emitted with an additional date, which
signals, which date caused the state change.
With this information, I selectively only build the EntryLists that
needs to be rebuilt.

Additionally, the calendar FAB will push a new route instead of
navigating to a new day by utilizing the pageController.
2025-01-12 17:23:59 +01:00
7126b1b593 Remove go_router 2025-01-05 19:29:28 +01:00
e1fdefe979 Merge pull request 'Prepare v1.0.5' (#10) from prepare_v1.0.5 into master
Reviewed-on: #10
2025-01-05 16:33:27 +00:00
435ad4e618 Prepare v1.0.5 2025-01-05 17:31:17 +01:00
0aca111cb5 Merge pull request 'Overhaul ui and remove BackButtonListener' (#9) from home-button-in-drawer into master
Reviewed-on: #9
2025-01-05 16:27:57 +00:00
12 changed files with 39 additions and 29 deletions

2
.gitignore vendored
View File

@ -42,3 +42,5 @@ app.*.map.json
/android/app/profile /android/app/profile
/android/app/release /android/app/release
assets/icon_base.xcf assets/icon_base.xcf
/metadata/**/*.xcf

View File

@ -34,8 +34,8 @@ android {
applicationId = "de.swgross.calorimeter" applicationId = "de.swgross.calorimeter"
minSdk = flutter.minSdkVersion minSdk = flutter.minSdkVersion
targetSdk = flutter.targetSdkVersion targetSdk = flutter.targetSdkVersion
versionCode = 4 versionCode = 5
versionName = "1.0.4" versionName = "1.0.5"
} }
signingConfigs { signingConfigs {

View File

@ -27,7 +27,8 @@ class FoodEntryBloc extends Bloc<FoodEvent, GlobalEntryState> {
var newList = await storage.getEntriesForDate(event.forDate); var newList = await storage.getEntriesForDate(event.forDate);
state.foodEntries.addAll({event.forDate: newList}); state.foodEntries.addAll({event.forDate: newList});
emit(GlobalEntryState(foodEntries: state.foodEntries)); emit(GlobalEntryState(
foodEntries: state.foodEntries, stateChangedForDate: event.forDate));
} }
void handleFoodEntryEvent( void handleFoodEntryEvent(
@ -43,7 +44,8 @@ class FoodEntryBloc extends Bloc<FoodEvent, GlobalEntryState> {
var newFoodEntries = state.foodEntries; var newFoodEntries = state.foodEntries;
newFoodEntries.addAll({event.forDate: entriesForDate}); newFoodEntries.addAll({event.forDate: entriesForDate});
emit(GlobalEntryState(foodEntries: newFoodEntries)); emit(GlobalEntryState(
foodEntries: newFoodEntries, stateChangedForDate: event.forDate));
} }
void handleFoodChangedEvent( void handleFoodChangedEvent(
@ -64,7 +66,8 @@ class FoodEntryBloc extends Bloc<FoodEvent, GlobalEntryState> {
var newFoodEntries = state.foodEntries; var newFoodEntries = state.foodEntries;
newFoodEntries.addAll({event.forDate: entriesForDate}); newFoodEntries.addAll({event.forDate: entriesForDate});
emit(GlobalEntryState(foodEntries: newFoodEntries)); emit(GlobalEntryState(
foodEntries: newFoodEntries, stateChangedForDate: event.forDate));
} }
void handleDeleteFoodEvent( void handleDeleteFoodEvent(
@ -79,7 +82,8 @@ class FoodEntryBloc extends Bloc<FoodEvent, GlobalEntryState> {
var newFoodEntries = state.foodEntries; var newFoodEntries = state.foodEntries;
newFoodEntries.addAll({event.forDate: entriesForDate}); newFoodEntries.addAll({event.forDate: entriesForDate});
emit(GlobalEntryState(foodEntries: newFoodEntries)); emit(GlobalEntryState(
foodEntries: newFoodEntries, stateChangedForDate: event.forDate));
} }
void handleBarcodeScannedEvent( void handleBarcodeScannedEvent(
@ -91,6 +95,7 @@ class FoodEntryBloc extends Bloc<FoodEvent, GlobalEntryState> {
if (e.code == BarcodeScanner.cameraAccessDenied) { if (e.code == BarcodeScanner.cameraAccessDenied) {
emit(GlobalEntryState( emit(GlobalEntryState(
foodEntries: state.foodEntries, foodEntries: state.foodEntries,
stateChangedForDate: event.forDate,
appError: appError:
GlobalAppError(GlobalAppErrorType.errCameraPermissionDenied))); GlobalAppError(GlobalAppErrorType.errCameraPermissionDenied)));
} }
@ -107,6 +112,7 @@ class FoodEntryBloc extends Bloc<FoodEvent, GlobalEntryState> {
if (scanResult.type == ResultType.Error) { if (scanResult.type == ResultType.Error) {
emit(GlobalEntryState( emit(GlobalEntryState(
foodEntries: state.foodEntries, foodEntries: state.foodEntries,
stateChangedForDate: event.forDate,
appError: GlobalAppError(GlobalAppErrorType.errGeneralError))); appError: GlobalAppError(GlobalAppErrorType.errGeneralError)));
return; return;
} }
@ -122,7 +128,10 @@ class FoodEntryBloc extends Bloc<FoodEvent, GlobalEntryState> {
entriesForDate.add(newEntryWaiting); entriesForDate.add(newEntryWaiting);
state.foodEntries.addAll({event.forDate: entriesForDate}); state.foodEntries.addAll({event.forDate: entriesForDate});
emit(GlobalEntryState(foodEntries: state.foodEntries)); emit(GlobalEntryState(
foodEntries: state.foodEntries,
stateChangedForDate: event.forDate,
));
await responseFuture.then((response) async { await responseFuture.then((response) async {
var index = entriesForDate var index = entriesForDate
@ -140,6 +149,7 @@ class FoodEntryBloc extends Bloc<FoodEvent, GlobalEntryState> {
emit(GlobalEntryState( emit(GlobalEntryState(
foodEntries: newFoodEntries, foodEntries: newFoodEntries,
stateChangedForDate: event.forDate,
appError: GlobalAppError(GlobalAppErrorType.errbarcodeNotFound))); appError: GlobalAppError(GlobalAppErrorType.errbarcodeNotFound)));
return; return;
} }
@ -151,6 +161,7 @@ class FoodEntryBloc extends Bloc<FoodEvent, GlobalEntryState> {
emit(GlobalEntryState( emit(GlobalEntryState(
foodEntries: newFoodEntries, foodEntries: newFoodEntries,
stateChangedForDate: event.forDate,
appError: appError:
GlobalAppError(GlobalAppErrorType.errServerNotReachable))); GlobalAppError(GlobalAppErrorType.errServerNotReachable)));
return; return;
@ -173,7 +184,8 @@ class FoodEntryBloc extends Bloc<FoodEvent, GlobalEntryState> {
var newFoodEntries = state.foodEntries; var newFoodEntries = state.foodEntries;
newFoodEntries.addAll({event.forDate: entriesForDate}); newFoodEntries.addAll({event.forDate: entriesForDate});
emit(GlobalEntryState(foodEntries: newFoodEntries)); emit(GlobalEntryState(
foodEntries: newFoodEntries, stateChangedForDate: event.forDate));
}); });
} }
@ -194,7 +206,8 @@ class FoodEntryBloc extends Bloc<FoodEvent, GlobalEntryState> {
selectedEntry.isSelected = !oldStateOfTappedEntry; selectedEntry.isSelected = !oldStateOfTappedEntry;
emit(GlobalEntryState(foodEntries: state.foodEntries)); emit(GlobalEntryState(
foodEntries: state.foodEntries, stateChangedForDate: event.forDate));
} }
} }
@ -240,12 +253,17 @@ class PermissionException extends FoodEvent {
PermissionException({required super.forDate}); PermissionException({required super.forDate});
} }
/// This is the state for one date/page class PageEntryState {}
class GlobalEntryState { class GlobalEntryState {
final Map<DateTime, List<FoodEntryState>> foodEntries; final Map<DateTime, List<FoodEntryState>> foodEntries;
final GlobalAppError? appError; final GlobalAppError? appError;
GlobalEntryState({required this.foodEntries, this.appError}); //we use this to only redraw pages whose entries changed
final DateTime? stateChangedForDate;
GlobalEntryState(
{required this.foodEntries, this.stateChangedForDate, this.appError});
factory GlobalEntryState.init() { factory GlobalEntryState.init() {
return GlobalEntryState(foodEntries: {}); return GlobalEntryState(foodEntries: {});

View File

@ -92,10 +92,9 @@ class PerDatePageViewController extends StatelessWidget {
onDateSelected: (dateSelected) { onDateSelected: (dateSelected) {
if (dateSelected == null) return; if (dateSelected == null) return;
var dateDiff = dateSelected.difference(initialDate).inDays; Navigator.of(context).push(MaterialPageRoute(
builder: (context) =>
log("dateDiff = $dateDiff"); PerDatePageViewController(initialDate: dateSelected)));
pageController.jumpToPage(initialOffset - dateDiff);
}, },
), ),
], ],

View File

@ -33,6 +33,11 @@ class _PerDateWidgetState extends State<PerDateWidget>
showNewSnackbarWith(context, pageState.appError!); showNewSnackbarWith(context, pageState.appError!);
} }
}, },
buildWhen: (previous, current) {
if (current.stateChangedForDate == null) return true;
if (current.stateChangedForDate == widget.date) return true;
return false;
},
builder: (context, pageState) { builder: (context, pageState) {
return FoodEntryList( return FoodEntryList(
entries: pageState.foodEntries[widget.date] ?? [], entries: pageState.foodEntries[widget.date] ?? [],

Binary file not shown.

After

Width:  |  Height:  |  Size: 93 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 94 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 98 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 97 KiB

View File

@ -290,11 +290,6 @@ packages:
description: flutter description: flutter
source: sdk source: sdk
version: "0.0.0" version: "0.0.0"
flutter_web_plugins:
dependency: transitive
description: flutter
source: sdk
version: "0.0.0"
frontend_server_client: frontend_server_client:
dependency: transitive dependency: transitive
description: description:
@ -316,14 +311,6 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.1.2" version: "2.1.2"
go_router:
dependency: "direct main"
description:
name: go_router
sha256: "2fd11229f59e23e967b0775df8d5948a519cd7e1e8b6e849729e010587b46539"
url: "https://pub.dev"
source: hosted
version: "14.6.2"
graphs: graphs:
dependency: transitive dependency: transitive
description: description:

View File

@ -19,7 +19,6 @@ dependencies:
barcode_scan2: ^4.3.3 barcode_scan2: ^4.3.3
provider: ^6.1.2 provider: ^6.1.2
test: ^1.25.7 test: ^1.25.7
go_router: ^14.6.2
path_provider_platform_interface: ^2.1.2 path_provider_platform_interface: ^2.1.2
plugin_platform_interface: ^2.1.8 plugin_platform_interface: ^2.1.8
http: ^1.2.2 http: ^1.2.2