Bläddra i källkod

P2-21: meerkoloms Home geprobeerd en teruggedraaid + builderpatronen

Optie (a) uit P2-21 punt 3 uitgevoerd met Bob's akkoord: Home's
PagedListView omgezet naar GridView en daarna StaggeredView, met
responsieve crossAxisCount 1/1/2/3. Beide exportgeverifieerd (0 errors),
maar op een echt toestel rendert PagedMasonryGridView niets binnen de
SingleChildScrollView van home_widget.dart - leeg vlak, geen spinner,
geen foutmelding. Baseline-build met alleen dit component teruggezet
toonde op datzelfde toestel wel gewoon kaarten. Volledig teruggedraaid
en geverifieerd: 0 treffers op Masonry/Grid/crossAxisCount, PagedListView
weer intact, dart analyze 0 errors.

CLAUDE.md: recept om een lijst met paginering te Replacen, waarom
GridView noch StaggeredView hier werkt, twee versleepbare dialogen tegen
paneel-clipping, en de valkuil dat emulator-5554 niet vast de telefoon is.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
bob 1 vecka sedan
förälder
incheckning
f1b083fdde
2 ändrade filer med 122 tillägg och 43 borttagningar
  1. 76 0
      CLAUDE.md
  2. 46 43
      TASKS.md

+ 76 - 0
CLAUDE.md

@@ -345,6 +345,26 @@ export PATH="/home/bob/fvm/bin:$HOME/.pub-cache/bin:$PATH" && /home/bob/Projects
   `run_in_background: true`. Volg tot minimaal "All done!" én
   idealiter een succesvolle app-launch (`Launching lib/main.dart...`,
   geen nieuwe `EXCEPTION CAUGHT BY RENDERING LIBRARY`).
+- **⚠️ `emulator-5554` is NIET vast de telefoon — de poort hangt af van
+  de opstartvolgorde, niet van het toestel.** Bevestigd 2026-09-01: na
+  een herstart van de tablet-service pakte de **tablet** poort 5554 en
+  de telefoon 5556, precies omgekeerd aan wat hieronder staat. De
+  AVD-namen kloppen ook niet meer met de oude notitie (de tablet heet
+  `Medium_Tablet_no-google`). **Controleer dus altijd eerst wélk toestel
+  je voor je hebt** met `adb -s <device> shell wm size` — tablet =
+  2560x1600 @ 320dpi, telefoon = 1080x1920 @ 420dpi — vóór je een test
+  of screenshot aan een device-id koppelt.
+- **Emulator weg uit `adb devices` terwijl de systemd-service "active"
+  meldt: kijk naar de luisterpoorten, niet naar de service.** Een
+  `ss -lnt | grep 555` laat zien of er überhaupt een console-poort
+  geopend is. Twee bekende faalvormen, beide 2026-09-01 gezien: (1) de
+  emulator crasht met `code=dumped, status=11/SEGV` (zie ook hieronder),
+  (2) bij het herstarten terwijl de andere emulator nog draait komt
+  `kvm_user_backed_ram_map: error registering slot: File exists` — dan
+  boot hij nooit af. **Fix voor (2): beide services stoppen, wachten tot
+  `pgrep qemu-system-x86` niets meer geeft, en dan één voor één starten.**
+  Onder zware geheugendruk (dit gebeurde bij ~47 GB swap in gebruik) is
+  dit extra waarschijnlijk.
 - **Testdevices (vanaf 2026-08-09): twee lokale AVD's, geen fysieke
   toestellen meer.** `emulator-5554` (`licht_avd`, telefoon-formaat,
   laag RAM-profiel) en `emulator-5556` (`tablet_avd`, tablet-
@@ -850,6 +870,62 @@ klikken.** Bevestigd 2026-08-31 (P1-33, 93 hardcoded hexen → 12, en die
   verschillende velden zijn — een hartje-op-wit-vlak zit in *Icon
   Color*, een hamburger-op-gekleurd-vlak in *Fill Color*.
 
+**Een lijstwidget met paginering omzetten naar een grid (Replace) —
+volledig recept, bevestigd 2026-09-01 op `HomeUitgaantabelKaartComponent`.**
+Rechtsklik → Replace weigert met "Can't replace a widget that has
+pagination enabled". De hele cyclus:
+1. Backend Query (3e icoontje) → **Edit** → **Enable Infinite Scroll uit**.
+2. De variabele die aan de paginering hing (hier `page`) wordt daardoor
+   **rood/ongeldig**, en Confirm wordt geweigerd met de toast
+   *"Current query is invalid. Please fix."* — je moet die binding dus
+   eerst weghalen: rij openklappen → potlood bij Value → in de
+   bronnenlijst het **prullenbak-icoon linksboven** ("Remove Variable")
+   → er verschijnt een vrij tekstveld → typ een tijdelijke `0` → Confirm.
+3. Rechtsklik de node in de **widget tree** → Replace Widget → kies.
+4. Daarna alles terugzetten: Infinite Scroll weer aan, en het
+   Value-icoontje naast de variabele → bron **"Next Page Index
+   (<WidgetNaam>)"** — dat is dezelfde bron die daarna weer als
+   *"Pagination - Next Page Number"* in beeld komt.
+**Let op wat een Replace stilletjes reset:** `Shrink Wrap` valt terug op
+uit (zet 'm handmatig terug als het origineel 'm aan had), en een
+GridView krijgt er een `Child Aspect Ratio` bij die een ListView niet
+had.
+
+**Een lijst met paginering binnen een `SingleChildScrollView` laat zich
+NIET omzetten naar een grid — live bewezen 2026-09-01, en weer
+teruggedraaid.** Home plaatst `HomeUitgaantabelKaartComponent` in een
+`SingleChildScrollView > Column` (`home_widget.dart`), dus in een
+context zonder begrensde hoogte. Daar werkt alleen `PagedListView`:
+- **`PagedMasonryGridView` (StaggeredView) rendert er niets** — geen
+  kaarten, geen laadspinner, geen foutmelding, geen overflow. Puur een
+  leeg vlak. Op telefoon- én tabletformaat getest, met een baseline-build
+  ernaast die wél gewoon kaarten toonde. De API leverde intussen keurig
+  44 KB data, dus het is zuiver een renderprobleem.
+- **`PagedGridView` is óók geen oplossing**, om een andere reden: een
+  GridView bepaalt de celhoogte via `childAspectRatio` (breedte/hoogte),
+  en dat kan een **vaste** kindhoogte principieel niet volgen — binnen
+  één breekpuntband varieert de schermbreedte, dus elke waarde geeft óf
+  overflow óf grote witruimte. De kaart hier heeft een vaste responsieve
+  hoogte (160/200/240/280 + 12px padding), en met de standaard
+  `childAspectRatio: 1.0` werd een cel op 411dp ruim 400dp hoog tegen
+  184dp benodigd.
+**Gevolg:** meerkoloms op tablet vraagt eerst een herstructurering van
+de ouder (de `SingleChildScrollView` eruit, de grid zelf laten scrollen)
+— niet alleen een Replace op het component. Begin daar niet aan zonder
+live test. StaggeredView ondersteunt overigens wél gewoon paginering
+(de "Enable Infinite Scroll"-toggle staat er en genereert
+`PagedMasonryGridView`); dat was niet de blokkade.
+
+**Twee dialogen zijn wél te vergroten/verplaatsen — dat lost een hoop
+clipping op.** Aanvulling op het doodlopende page-zoom-spoor hieronder:
+- De **Backend Query-dialoog** is **groter te slepen aan zijn onderrand**
+  (het "———"-greepje onderaan). Dat was nodig om het `Value`-veld van
+  een variabele te bereiken, dat er anders onder valt.
+- De **"Set from Variable"-dialoog** met een **Responsive Value**
+  (4-traps if/else) toont standaard maar 2 van de 4 takken; sleep 'm aan
+  zijn **bovenrand** omhoog, dan staan alle vier de waardevelden in beeld.
+Scrollen met het muiswiel werkt in beide gevallen niet — slepen wel.
+
 **Rechterpaneel-clipping: klik op een sectiekop om die dicht te
 klappen — dat is betrouwbaarder dan de "Search properties..."-zoekbalk.**
 Gevonden 2026-08-31: het paneel scrollt niet mee via muiswiel, en het

+ 46 - 43
TASKS.md

@@ -3511,10 +3511,8 @@ kaarttitels op afbreken/overlopen nakijken. Ook een legitieme uitkomst:
 niet doen — dan is de app herkenbaar op kleur maar mist hij de
 kranten-uitstraling.
 
-**P2-21 · Eigenaar: Claude — bezig (sessie 2026-09-01, Claude bouwt
-zelf in Bob's Chrome). Besluit van Bob (2026-09-01): bij punt 3 gaan we
-voor **optie (a) doorzetten**.** Tabletweergave herschikken
-i.p.v. uitrekken. Verifiëren op `emulator-5556` (tablet) én
+**P2-21 · Eigenaar: Bob (productbeslissing nodig, zie punt 3).**
+Tabletweergave herschikken i.p.v. uitrekken. Verifiëren op `emulator-5556` (tablet) én
 telefoonformaat. Staat los van P1-11 (labels/overflow, al afgerond).
 
 **Meetgegevens (2026-08-31, Claude).** Breekpunten staan in
@@ -3549,45 +3547,50 @@ met een verse export bevestigd byte-identiek aan het origineel. Let op
 bij een Replace: de **Scrollable**-instelling van de `Column` gaat
 verloren en moet handmatig terug.)*
 
-**3. BLOKKADE op stap 2 — besluit van Bob nodig.** Rechtsklik → Replace
-op de `ListView` weigert met een expliciete, informatieve melding:
-> "Can't replace a widget that has pagination enabled. Go to the
-> 'Backend Query' pane and remove pagination before proceeding."
-
-Pagination weghalen en weer opbouwen raakt het datapad van de
-startpagina. **Huidige configuratie, uitgelezen en hier vastgelegd
-zodat ze exact te herstellen is** (Backend Query-paneel + de export):
-- Query Type **API Call**, call **`homeTabel`**
-- **Enable Infinite Scroll: aan**; variabele `page` → Value =
-  **Next Page Number** (genereert
-  `HomeTabelCall.call(page: nextPageMarker.nextPageNumber)`)
-- **Enable Pull to Refresh: aan** (genereert `onRefresh` +
-  `waitForOnePageForListView()`)
-- Twee eigen laadindicatoren (first page én next page):
-  `SpinKitFadingCircle`, size **80**, in een `SizedBox` 80x80, kleur
-  **thema-token `primary`** — *gecorrigeerd 2026-09-01: de oude notitie
-  hier zei `#B1061E` (hardcoded), maar P1-33 heeft dat inmiddels aan
-  het token gehangen; de export toont
-  `FlutterFlowTheme.of(context).primary`.*
-- Verder: `shrinkWrap: true`, `reverse: false`, `Axis.vertical`
-
-Het risico zit niet in de grid-omzetting zelf maar in het opnieuw
-opbouwen van die vijf instellingen — vooral de twee custom
-laadindicatoren — op de live Home-datastroom. **Vangnet staat klaar:**
-`HomeUitgaantabelKaartComponentCopy` is een complete, onbeschadigde
-kopie van dit component (aangemaakt 2026-08-31, vóór alle wijzigingen).
-
-*Twee opties, aan Bob:*
-- **(a) doorzetten** — pagination uit, `ListView` → `GridView`,
-  `Cross Axis Count` responsief 1/1/2/3 (via het icoontje naast het
-  veld → Source **"Responsive Value"**; dat bouwt de 4-traps if/else
-  zelf, bevestigd werkend deze sessie), daarna alle vijf instellingen
-  hierboven terugzetten en met een verse export controleren dat
-  `PagedGridView` + `nextPageNumber` + beide `SpinKitFadingCircle`-
-  blokken er weer staan.
-- **(b) kleinere ingreep zonder pagination aan te raken** — de kaart
-  een maximumbreedte geven en centreren. Lost de onleesbaar lange
-  regels op, maar geeft geen twee kolommen.
+**3. UITGEVOERD EN TERUGGEDRAAID op 2026-09-01 (Claude, in Bob's
+Chrome, met Bob's expliciete akkoord voor optie (a)). Uitkomst: optie
+(a) is niet haalbaar op deze plek — Home staat weer op de oude,
+werkende `PagedListView`.**
+
+De hele omzetting is technisch gelukt en exportgeverifieerd, maar op een
+echt toestel bleek het resultaat kapot:
+- De pagination-blokkade bij Replace is gewoon te omzeilen (recept staat
+  nu in `CLAUDE.md`), en **StaggeredView ondersteunt wél paginering**
+  (`PagedMasonryGridView` + "Enable Infinite Scroll") — dat was dus niet
+  de belemmering.
+- **Maar `PagedMasonryGridView` rendert niets** binnen de
+  `SingleChildScrollView > Column` waarin `home_widget.dart` dit
+  component plaatst: geen kaarten, geen spinner, geen foutmelding, geen
+  overflow — een leeg vlak, op telefoon- én tabletformaat. Een
+  baseline-build met alleen dit component teruggezet toonde op datzelfde
+  toestel wél gewoon kaarten (Knisper, Westland Comedy Café Festival,
+  Micha Wertheim); de API leverde intussen 44 KB data. Zuiver een
+  renderprobleem dus.
+- **`PagedGridView` is evenmin bruikbaar**: die bepaalt de celhoogte via
+  `childAspectRatio`, en dat kan de **vaste** kaarthoogte
+  (160/200/240/280 + 12px padding) principieel niet volgen — binnen één
+  breekpuntband varieert de schermbreedte, dus elke waarde geeft óf
+  overflow óf grote witruimte (standaard `1.0` gaf een cel van ruim
+  400dp tegen 184dp benodigd op een 411dp-telefoon).
+
+**Alles is teruggedraaid en geverifieerd**: verse export bevat 0
+treffers op `MasonryGridView`/`PagedGridView`/`crossAxisCount`/
+`childAspectRatio`/`StaggeredView`, de `PagedListView` staat er weer met
+`shrinkWrap: true` / `reverse: false` / `Axis.vertical` /
+`nextPageNumber` / `RefreshIndicator` / beide `SpinKitFadingCircle`-
+indicatoren op thema-token `primary`; `dart analyze` 0 errors. Het enige
+resterende verschil met `git HEAD` in dit bestand is een verwijderde
+tekstschaduw — dat is P1-28-werk van een andere sessie, niet hiervan.
+
+**Wat er nu nog over is aan keuze voor Bob:** meerkoloms op tablet vraagt
+een herstructurering van de **ouder** — de `SingleChildScrollView` in
+`home_widget.dart` eruit en de grid zelf laten scrollen — niet alleen een
+Replace op het component. Dat raakt het scrollgedrag van de hele
+startpagina (inclusief de sliderband erboven, die nu meescrollt) en
+verdient een eigen sessie mét live test op een toestel. Het alternatief
+blijft **optie (b)**: pagination ongemoeid laten en de kaart een
+maximumbreedte geven + centreren — lost de onleesbaar lange regels op,
+geeft geen twee kolommen, en is risicoloos.
 
 **4. Favorieten — kleine correctie, los van het bovenstaande.**
 `favorieten_widget.dart:339` en `:663` hebben `crossAxisCount: 2`