From a33c4ddac57582f68529f6a2e493bd4890ca5c95 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Elias=20M=C3=BCller?= <elias@elias-mueller.com>
Date: Mon, 27 May 2024 22:28:42 +0200
Subject: [PATCH] wip: fixed state not updating correctly

---
 .../modules/holidays/bloc/holidays_bloc.dart  |   7 +-
 .../modules/holidays/view/holidays_view.dart  | 100 ++++++++----------
 lib/widget/list_view_util.dart                |   9 ++
 3 files changed, 60 insertions(+), 56 deletions(-)
 create mode 100644 lib/widget/list_view_util.dart

diff --git a/lib/state/app/modules/holidays/bloc/holidays_bloc.dart b/lib/state/app/modules/holidays/bloc/holidays_bloc.dart
index cd369f0..033be9e 100644
--- a/lib/state/app/modules/holidays/bloc/holidays_bloc.dart
+++ b/lib/state/app/modules/holidays/bloc/holidays_bloc.dart
@@ -9,8 +9,8 @@ import 'holidays_state.dart';
 class HolidaysBloc extends LoadableHydratedBloc<HolidaysEvent, HolidaysState, HolidaysRepository> {
   HolidaysBloc() {
     on<SetPastHolidaysVisible>((event, emit) {
-      log('set pastholidays: ${event.shouldBeVisible.toString()}');
-      add(Emit((state) => state.copyWith(showPastHolidays: state.showPastHolidays)));
+      log('SetPastHolidaysVisible: ${event.shouldBeVisible.toString()}');
+      add(Emit((state) => state.copyWith(showPastHolidays: event.shouldBeVisible)));
     });
 
     on<DisclaimerDismissed>((event, emit) => add(
@@ -19,6 +19,9 @@ class HolidaysBloc extends LoadableHydratedBloc<HolidaysEvent, HolidaysState, Ho
   }
 
   bool showPastHolidays() => innerState?.showPastHolidays ?? false;
+  List<Holiday>? getHolidays() => innerState?.holidays.where(
+    (element) => showPastHolidays() || DateTime.parse(element.end).isAfter(DateTime.now())
+  ).toList();
 
   @override
   fromNothing() => const HolidaysState(showPastHolidays: false, holidays: [], showDisclaimer: true);
diff --git a/lib/state/app/modules/holidays/view/holidays_view.dart b/lib/state/app/modules/holidays/view/holidays_view.dart
index 3b40f4e..45b0b7f 100644
--- a/lib/state/app/modules/holidays/view/holidays_view.dart
+++ b/lib/state/app/modules/holidays/view/holidays_view.dart
@@ -1,13 +1,11 @@
-import 'dart:developer';
-
 import 'package:flutter/material.dart';
 import 'package:jiffy/jiffy.dart';
 
 import '../../../../../view/pages/more/holidays/holidays.dart';
 import '../../../../../widget/animatedTime.dart';
+import '../../../../../widget/list_view_util.dart';
 import '../../../../../widget/centeredLeading.dart';
 import '../../../../../widget/debug/debugTile.dart';
-import '../../../infrastructure/loadableState/loadable_state.dart';
 import '../../../infrastructure/loadableState/view/loadable_state_consumer.dart';
 import '../../../infrastructure/utilityWidgets/bloc_module.dart';
 import '../bloc/holidays_bloc.dart';
@@ -18,18 +16,17 @@ class HolidaysView extends StatelessWidget {
   const HolidaysView({super.key});
 
   @override
-  Widget build(BuildContext context) => BlocModule<HolidaysBloc, LoadableState<HolidaysState>>(
-    create: (contet) => HolidaysBloc(),
+  Widget build(BuildContext context) => BlocModule(
+    create: (context) => HolidaysBloc(),
     autoRebuild: true,
     child: (context, bloc, state) {
-      log(state.toString());
       void showDisclaimer() {
         showDialog(context: context, builder: (context) => AlertDialog(
           title: const Text('Richtigkeit und Bereitstellung der Daten'),
           content: const Text(''
-            'Sämtliche Datumsangaben sind ohne Gewähr.\n'
-            'Ich übernehme weder Verantwortung für die Richtigkeit der Daten noch hafte ich für wirtschaftliche Schäden die aus der Verwendung dieser Daten entstehen können.\n\n'
-            'Die Daten stammen von https://ferien-api.de/'),
+              'Sämtliche Datumsangaben sind ohne Gewähr.\n'
+              'Ich übernehme weder Verantwortung für die Richtigkeit der Daten noch hafte ich für wirtschaftliche Schäden die aus der Verwendung dieser Daten entstehen können.\n\n'
+              'Die Daten stammen von https://ferien-api.de/'),
           actions: [
             TextButton(child: const Text('Okay'), onPressed: () {
               bloc.add(DisclaimerDismissed());
@@ -38,7 +35,7 @@ class HolidaysView extends StatelessWidget {
           ],
         ));
       }
-      
+
       return Scaffold(
         appBar: AppBar(
           title: const Text('Schulferien in Hessen'),
@@ -66,53 +63,48 @@ class HolidaysView extends StatelessWidget {
           ],
         ),
         body: LoadableStateConsumer<HolidaysBloc, HolidaysState>(
-          child: (state, loading) => ListView.builder(
-            itemCount: state.holidays.length,
-            itemBuilder: (context, index) {
-              var holiday = state.holidays[index];
-              var holidayType = holiday.name.split(' ').first.capitalize();
+          child: (state, loading) => ListViewUtil.fromList<Holiday>(bloc.getHolidays(), (holiday) {
+            var holidayType = holiday.name.split(' ').first.capitalize();
+            String formatDate(String enDate) => Jiffy.parse(enDate).format(pattern: 'dd.MM.yyyy');
 
-              String formatDate(String enDate) => Jiffy.parse(enDate).format(pattern: 'dd.MM.yyyy');
-              
-              return ListTile(
-                leading: const CenteredLeading(Icon(Icons.calendar_month)),
-                title: Text('$holidayType ab ${formatDate(holiday.start)}'),
-                subtitle: Text('bis ${formatDate(holiday.end)}'),
-                onTap: () => showDialog(context: context, builder: (context) => SimpleDialog(
-                  title: Text('$holidayType ${holiday.year} in Hessen'),
-                  children: [
-                    ListTile(
-                      leading: const CenteredLeading(Icon(Icons.signpost_outlined)),
-                      title: Text(holiday.name),
-                      subtitle: Text(holiday.slug),
+            return ListTile(
+              leading: const CenteredLeading(Icon(Icons.calendar_month)),
+              title: Text('${state.showPastHolidays}$holidayType ab ${formatDate(holiday.start)}'),
+              subtitle: Text('bis ${formatDate(holiday.end)}'),
+              onTap: () => showDialog(context: context, builder: (context) => SimpleDialog(
+                title: Text('$holidayType ${holiday.year} in Hessen'),
+                children: [
+                  ListTile(
+                    leading: const CenteredLeading(Icon(Icons.signpost_outlined)),
+                    title: Text(holiday.name),
+                    subtitle: Text(holiday.slug),
+                  ),
+                  ListTile(
+                    leading: const Icon(Icons.arrow_forward),
+                    title: Text('vom ${formatDate(holiday.start)}'),
+                  ),
+                  ListTile(
+                    leading: const Icon(Icons.arrow_back),
+                    title: Text('bis zum ${formatDate(holiday.end)}'),
+                  ),
+                  Visibility(
+                    visible: !DateTime.parse(holiday.start).difference(DateTime.now()).isNegative,
+                    replacement: ListTile(
+                      leading: const CenteredLeading(Icon(Icons.content_paste_search_outlined)),
+                      title: Text(Jiffy.parse(holiday.start).fromNow()),
                     ),
-                    ListTile(
-                      leading: const Icon(Icons.arrow_forward),
-                      title: Text('vom ${formatDate(holiday.start)}'),
+                    child: ListTile(
+                      leading: const CenteredLeading(Icon(Icons.timer_outlined)),
+                      title: AnimatedTime(callback: () => DateTime.parse(holiday.start).difference(DateTime.now())),
+                      subtitle: Text(Jiffy.parse(holiday.start).fromNow()),
                     ),
-                    ListTile(
-                      leading: const Icon(Icons.arrow_back),
-                      title: Text('bis zum ${formatDate(holiday.end)}'),
-                    ),
-                    Visibility(
-                      visible: !DateTime.parse(holiday.start).difference(DateTime.now()).isNegative,
-                      replacement: ListTile(
-                        leading: const CenteredLeading(Icon(Icons.content_paste_search_outlined)),
-                        title: Text(Jiffy.parse(holiday.start).fromNow()),
-                      ),
-                      child: ListTile(
-                        leading: const CenteredLeading(Icon(Icons.timer_outlined)),
-                        title: AnimatedTime(callback: () => DateTime.parse(holiday.start).difference(DateTime.now())),
-                        subtitle: Text(Jiffy.parse(holiday.start).fromNow()),
-                      ),
-                    ),
-                    DebugTile(context).jsonData(holiday.toJson()),
-                  ],
-                )),
-                trailing: const Icon(Icons.arrow_right),
-              );
-            },
-          ),
+                  ),
+                  DebugTile(context).jsonData(holiday.toJson()),
+                ],
+              )),
+              trailing: const Icon(Icons.arrow_right),
+            );
+          }),
         ),
       );
     },
diff --git a/lib/widget/list_view_util.dart b/lib/widget/list_view_util.dart
new file mode 100644
index 0000000..468ae95
--- /dev/null
+++ b/lib/widget/list_view_util.dart
@@ -0,0 +1,9 @@
+
+import 'package:flutter/material.dart';
+
+class ListViewUtil {
+  static ListView fromList<T>(List<T>? items, Widget Function(T item) map) => ListView.builder(
+      itemCount: items?.length ?? 0,
+      itemBuilder: (context, index) => items != null ? map(items[index]) : null,
+    );
+}