Selaa lähdekoodia

TASKS/CLAUDE: P2-1 afgerond + herlaadLijsten als herbruikbaar patroon vastgelegd

Corrigeert mijn eerdere conclusie dat alleen een volledige routeherlaad zou
werken: een custom action die na endOfFrame de element-tree afloopt en
refresh() aanroept op elke gemonteerde PagedMasonryGridView doet het zonder
paginaherlaad. Ook genoteerd bij P2-26, dat hetzelfde stuk kan hergebruiken.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
bob 14 tuntia sitten
vanhempi
commit
9b7be75adb
2 muutettua tiedostoa jossa 41 lisäystä ja 43 poistoa
  1. 15 5
      CLAUDE.md
  2. 26 38
      TASKS.md

+ 15 - 5
CLAUDE.md

@@ -1187,13 +1187,23 @@ probleem zou oplossen. De keten:
 `pagingController?.refresh()` aan, en dán staat de gefilterde lijst er meteen.
 Gebruik dat als test om databinding en refresh-trigger uit elkaar te trekken.
 **Er is géén builder-actie die dat `refresh()` genereert** — in dit hele project
-komt de aanroep uitsluitend uit `RefreshIndicator.onRefresh` voor. En een
+komt de aanroep verder uitsluitend uit `RefreshIndicator.onRefresh`. En een
 `Navigate To` naar dezelfde pagina helpt niet: `nav.dart` bouwt de page met
 `key: state.pageKey`, en die is voor hetzelfde pad identiek, dus go_router
-hergebruikt de `State` en het paginamodel. Wil je een gepagineerde lijst tóch
-op een filterwissel laten herladen, dan is de enige werkende route een echte
-herlaad van de route (`context.pushReplacement(...)` vanuit custom code, zie het
-punt over `go_router` elders) — met als prijs dat de hele pagina opnieuw opbouwt.
+hergebruikt de `State` en het paginamodel.
+**De werkende oplossing staat er sinds 2026-09-15 als custom action
+`herlaadLijsten`** (`lib/custom_code/actions/herlaad_lijsten.dart`, ~12 regels,
+geen argumenten): hij wacht met `await WidgetsBinding.instance.endOfFrame` op de
+rebuild die de nieuwe parameters doorgeeft — **die volgorde is essentieel**,
+want `setStaggeredViewController()` wordt pas tijdens die build met de nieuwe
+waarden aangeroepen; refresh je eerder, dan haal je de oude query op. Daarna
+loopt hij met een eigen stack (`element.visitChildren(stack.add)`, geen geneste
+closure) de element-tree af vanaf `WidgetsBinding.instance.rootElement` en roept
+`refresh()` aan op elke gemonteerde `PagedMasonryGridView`. Hang 'm als
+vólgende actie ná de Update App State. Kost geen paginaherlaad: de slider en de
+scrollpositie van de rest van de pagina blijven staan, en een al geladen andere
+tab ververst gewoon mee. Voor een nieuw filter op zo'n lijst (bv. het zoekveld
+van P2-26) is dit dus hergebruik, geen nieuw werk.
 
 **Een component-parameter aan een custom function binden: klik het kleine
 icoontje NAAST het parameterlabel, zoek op de VOLLEDIGE functienaam, en reken

+ 26 - 38
TASKS.md

@@ -307,9 +307,9 @@ tonen; alternatief is default "Amsterdam", te wisselen in dezelfde binding).
 Verifiëren op telefoonformaat (393 dp): hamburger + terugknop + logo + naam
 moeten op één regel passen, ook bij "'s-Hertogenbosch".
 
-**P2-1 · Datumfilter Vandaag / Dit weekend / Deze week · ⚠️ BIJNA AF —
-2026-09-15 (Drupal: Bob; app-kant: Claude, commit `f92c87c`). Alles staat en is
-gemeten; er is nóg één knoop door te hakken, zie het restpunt onderaan.**
+**P2-1 · Datumfilter Vandaag / Dit weekend / Deze week · ✅ AFGEROND 2026-09-15
+(Drupal: Bob; app-kant: Claude, commits `f92c87c` + `4de72eb`) — werkend getest
+op een toestel.**
 
 *Wat er staat, export-geverifieerd:*
 - Drupal: `datum_van` / `datum_tot` op alle zeven `flutterflowmobiel1`-displays,
@@ -335,40 +335,26 @@ gemeten; er is nóg één knoop door te hakken, zie het restpunt onderaan.**
 - `homeCopy` staat als vangnet klaar (Bob's verzoek vóór het Home-werk).
   **Opruimen mag zodra je tevreden bent — dat is een taak voor Bob.**
 
-⚠️ **RESTPUNT — Bob koos optie 2 (2026-09-15). Eigenaar: Claude — bezig.** Op de
-telefoon-emulator getest met een profile-build: de chips wisselen, App State
-wisselt, de parameters gaan goed mee... **maar de lijst herlaadt niet vanzelf.**
-Trek je de lijst omlaag (pull-to-refresh), dan staat het weekendresultaat er
-meteen — *zaterdag 19 sep* bovenaan i.p.v. dinsdag 15 sep. De hele keten klopt
-dus; alleen de automatische herlaad-trigger ontbreekt.
-
-*Waarom de Value Key dit niet oplost (nagelezen in de gegenereerde code):* het
-model van het component is een veld op het **pagina**model en wordt via
-`wrapWithModel` doorgegeven met `disposeOnWidgetDisposal = false`. Een nieuwe
-key bouwt wel een nieuwe `State`, maar die pakt via `createModel` hetzelfde
-model terug — inclusief de `pagingController` met alle al geladen pagina's.
-Er bestaat géén builder-actie die `pagingController.refresh()` genereert (in dit
-project komt die aanroep alleen uit de `RefreshIndicator`), en een `Navigate To`
-naar `home` helpt ook niet: `nav.dart` gebruikt `key: state.pageKey` en die is
-voor hetzelfde pad identiek, dus go_router hergebruikt de pagina.
-
-*Drie routes, kies er één:*
-1. **Custom action die de route echt herlaadt**
-   (`context.pushReplacement(GoRouterState.of(context).uri.toString())` — dat
-   patroon staat al als werkend in `CLAUDE.md`). Kleinste ingreep, werkt zeker.
-   Prijs: de héle Home-pagina bouwt opnieuw op bij elke chip-tik (slider +
-   actieve tab, ±1-2 s). Vraagt er één extra ding bij: de chips moeten hun
-   selectie ná de herlaad terugkrijgen, dus **Initial Option Value** binden aan
-   `datumFilter` (met een mini-functie die leeg → `Alles` vertaalt).
-2. **Custom action die de gemonteerde `PagedMasonryGridView`s opzoekt in de
-   element-tree en er `refresh()` op aanroept.** Geen paginaherlaad, de slider
-   blijft staan, chips houden hun selectie. Prijs: ±20 regels custom code die
-   op FlutterFlow-interne widgets leunt.
-3. **Laten zoals het nu is** en pull-to-refresh als de manier accepteren. Kost
-   niets, maar niemand ontdekt dat uit zichzelf — feitelijk werkt het filter dan
-   niet voor een gewone gebruiker.
-
-Mijn advies: **2**, met **1** als veilige terugval. Zeg welke, dan bouw ik 'm af.
+**Het herladen bij een filterwissel is opgelost met een custom action**
+(`herlaadLijsten`, commit `4de72eb`). Nodig omdat een Value Key op de
+component-instantie de `pagingController` níét reset — het componentmodel is
+pagina-eigendom (`wrapWithModel` + `disposeOnWidgetDisposal = false`), dus een
+nieuwe `State` pakt hetzelfde model met alle al geladen pagina's terug. Er is
+geen builder-actie die `pagingController.refresh()` genereert, en een
+`Navigate To` naar dezelfde pagina helpt niet (`nav.dart` gebruikt
+`key: state.pageKey`). De action wacht op de rebuild die de nieuwe
+`datumVan`/`datumTot` doorgeeft, loopt dan de element-tree af en roept
+`refresh()` aan op elke gemonteerde `PagedMasonryGridView`. Hij staat als
+tweede actie op de ChoiceChips, ná de Update App State.
+
+*Op de telefoon-emulator getest met een profile-build:* Alles → Dit weekend
+geeft meteen zaterdag 19 sep, Vandaag geeft dinsdag 15 sep, en een al geladen
+tab (Activiteiten) ververst ook in plaats. De slider blijft staan en er is geen
+paginaherlaad. Activiteiten/Vandaag is terecht leeg — nagemeten: `services_4`
+geeft vandaag 0 items, `services_3` er 9.
+
+*Losse opmerking, geen taak:* `homeCopy` staat er nog als vangnet; weg mag
+zodra je tevreden bent (Claude gooit niets weg).
 
 **P2-26 · Zoekveld op de evenementenlijsten · ⚠️ HERZIEN 2026-09-15 (Claude,
 gemeten) — het horeca-patroon kan hier NIET, dit begint bij jou in Drupal.**
@@ -384,7 +370,9 @@ begaanbare weg, en het zou de paginering die er nu netjes staat weggooien.
 (zelfde soort ingreep als de twee datumfilters van P2-1, dus goed samen op te
 pakken). Geef het een eigen filter-identifier (bv. `zoek`); daarna is de
 app-kant klein: één query-variabele op de API Call + een `TextField` boven de
-lijst dat bij On Change de page state zet en de pagingController ververst.
+lijst dat bij On Change de page state zet, gevolgd door de bestaande custom
+action **`herlaadLijsten`** (gebouwd voor P2-1) — die ververst de
+`pagingController`, dus dat stuk hoeft niet opnieuw bedacht te worden.
 Let op de 2000 ms `EasyDebounce` op On Change (bekend, niet instelbaar) — bij
 een server-side zoekopdracht is die vertraging juist prettig.