Browse Source

Taak 65: eerste release-build — app draait schoon, maar lokale build draagt het Flutter-standaardicoon

Bevindingen uit de eerste echte --release-build (emulator-5556, flags=0x0):
- app start zonder FATAL/E-flutter, data laadt, alle iconen renderen incl. het
  tree-shaken FontAwesome-vlaggetje; 0 dynamische IconData in de code
- BLOKKEREND: flutter build draait flutter_launcher_icons niet, dus een lokaal
  gebouwde APK draagt het Flutter-vogeltje; fix is een losse generator-run
- adaptive icon snijdt de merknaam af tot "itgaanskrant.co" (JPEG-foreground
  zonder alpha)
- CLAUDE.md-bewering dat de mipmaps tijdens de build vervangen worden: gecorrigeerd

Bevat ook de TASKS.md-tekst van taak 89 uit een gelijktijdige sessie.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
bob 7 hours ago
parent
commit
81652b7f29
2 changed files with 145 additions and 3 deletions
  1. 22 3
      CLAUDE.md
  2. 123 0
      TASKS.md

+ 22 - 3
CLAUDE.md

@@ -2486,15 +2486,34 @@ ten onrechte als "niet doorgekomen" gemeten werd:
 - **Icoon:** FlutterFlow zet het niet in `mipmap-*/ic_launcher.png`, maar configureert
   `flutter_launcher_icons` in `pubspec.yaml` met
   `image_path: 'assets/images/app_launcher_icon.jpg'` (+ `adaptive_icon_foreground`).
-  Die mipmap-PNG's worden pas **tijdens de build** vervangen, dus hun md5 blijft
-  eeuwig `57838d52…` (de Flutter-default). **Juiste check:** exporteer mét
-  `--include-assets` en kijk naar `assets/images/app_launcher_icon.jpg` zelf.
+  **Juiste check:** exporteer mét `--include-assets` en kijk naar
+  `assets/images/app_launcher_icon.jpg` zelf.
+  ⚠️ **Correctie 2026-09-18 (gemeten op een echte `--release`-APK): die mipmaps
+  worden NIET "tijdens de build" vervangen — `flutter build` draait
+  `flutter_launcher_icons` helemaal niet.** Een verse export heeft
+  `android:icon="@mipmap/ic_launcher"`, alleen de default `ic_launcher.png`
+  (md5 `57838d52…`), géén `mipmap-anydpi-v26/` en géén `values/colors.xml`. Bouw
+  je daaruit lokaal een APK, dan draagt hij **het blauwe Flutter-vogeltje** —
+  geverifieerd door het icoon uit de APK te vergelijken met het bronplaatje
+  (`#40c0e0`/31 % dekking tegenover `#a00000`/100 %). **Draai daarom altijd eerst
+  `fvm flutter pub run flutter_launcher_icons` in de exportmap**; dat herschrijft
+  het manifest naar `@mipmap/launcher_icon` en genereert de merkiconen, de
+  adaptive-XML en `colors.xml` (daarna geeft `aapt2 dump badging` een
+  `res/*.xml` als `application-icon`, niet een PNG — dát is de check dat het
+  goed staat). Onbekend en te verifiëren op het echte upload-artefact: of
+  FlutterFlow's eigen Deploy-pipeline die stap wél zet.
 - **Let op de adaptive icon:** FlutterFlow zet standaard
   `adaptive_icon_background: '#00000000'` (transparant) en gebruikt hetzelfde
   volvlakse plaatje als foreground. Android toont van die foreground alleen de
   middelste ~66%, dus een logo met tekst wordt afgesneden en er zit geen kleur
   onder. Zet een vaste achtergrondkleur en gebruik als foreground een **PNG met
   transparantie** waarin alleen het beeldmerk op ±60% van het vlak staat.
+  *Gemeten voorbeeld 2026-09-18:* met een **JPEG** als foreground (kan per
+  definitie geen alpha) is de gegenereerde `ic_launcher_foreground.png` 0 %
+  transparant en de buitenste 17 % 100 % ondoorzichtig — de achtergrondkleur is
+  dan onzichtbaar en van "Uitgaanskrant.com" blijft op het toestel
+  **"itgaanskrant.co"** over. Een `adaptive_icon_background` die wél goed staat
+  (hier `#9a141d`) helpt daar niets tegen.
 - **Splash:** ook niet in `launch_background.xml` (dat blijft
   `?android:colorBackground`), maar aan de Flutter-kant in **`nav.dart`**:
   `appStateNotifier.loading ? Image.asset('assets/images/<logo>', fit: BoxFit.cover)`.

+ 123 - 0
TASKS.md

@@ -42,6 +42,129 @@ half af** — node 220276 geeft 404, alleen de dblog-telling staat nog open.
    2026-09-18 op Bob's vraag, zie het uitgeschreven blok verderop. Feature, dus
    geen livegang-blokker; Claude kan dit zelf in de builder doen.
 
+11. **89 · logo boven de gemeentenaam in de gedeelde header** — nieuw
+   2026-09-18 (Bob: *"bij groot scherm moet in de header de foto boven de
+   plaats"*). Eén ingreep in `HeaderButtonsComponent`, zie het blok hieronder.
+
+### ✅/🔴 65 · P1-59 · Release-build gedaan 2026-09-18 (Claude, browserloos) — app draait, MAAR het app-icoon is fout
+
+Eerste echte `--release`-build ooit, uit een verse export mét `--include-assets`
+(`/tmp/ff-rel`, `fvm use 3.35.7 -f`, `dart analyze` **0 errors**), geïnstalleerd op
+**emulator-5556** (telefoon; 5554 was bezet door de sessie van taak 89).
+`dumpsys` bevestigt `flags=0x0` — geen `DEBUGGABLE`, dus een echte release.
+
+**✅ Wat goed gaat.** De app start schoon op: **0 `FATAL`, 0 `E/flutter`** in
+logcat over de hele sessie. Data laadt (Amsterdam, slider, kaarten met foto's),
+Nederlandse locale klopt, zoekveld + datumchips + vijf tabs staan er, en **alle
+iconen renderen** — óók het enige FontAwesome-icoon (`flagCheckered` bij
+*Activiteiten* in het menu), dat de tree-shaking dus overleeft. Het
+tree-shaking-risico uit de oorspronkelijke taakomschrijving is hiermee van tafel:
+er zijn **0 dynamisch opgebouwde `IconData(`** in de hele levende code, en
+`fa-solid-900.ttf` krimpt netjes van 419 KB naar 1248 bytes.
+Screenshots: `scratchpad/rel-home.png`, `rel-menu.png`.
+
+**🔴 BLOKKEREND — een lokaal gebouwde release draagt het Flutter-standaardicoon.**
+Het blauwe Flutter-vogeltje, niet het rode merkicoon. Hard aangetoond, niet
+afgeleid: het icoon uit `app-release.apk` is pixel-identiek aan de
+Flutter-default (68 % `#40c0e0`, 31 % dekking) terwijl `app_launcher_icon.jpg`
+83 % `#a00000` en 100 % dekking heeft; visueel bevestigd, het is letterlijk het
+Flutter-logo.
+
+*Oorzaak.* Een **verse export** heeft `android:icon="@mipmap/ic_launcher"`, alleen
+de default `ic_launcher.png` (md5 `57838d52…`), **geen** `mipmap-anydpi-v26/` en
+**geen** `values/colors.xml`. Het blok `flutter_launcher_icons:` in `pubspec.yaml`
+is wél correct ingevuld (`image_path`, `adaptive_icon_background: '#9a141d'`),
+maar **niemand voert die generator uit** — `flutter build` doet dat niet.
+
+*Fix, één commando in de exportmap vóór het bouwen:*
+```
+fvm flutter pub run flutter_launcher_icons
+```
+Dat herschrijft het manifest naar `@mipmap/launcher_icon`, genereert de
+merkiconen, `mipmap-anydpi-v26/launcher_icon.xml` en `colors.xml`. Na die stap
+opnieuw gebouwd en geverifieerd: `aapt2 dump badging` geeft dan
+`application-icon-640:'res/IO.xml'` (een adaptive icon) i.p.v. een PNG.
+
+⚠️ **Open vraag die iemand met Play-toegang moet beantwoorden:** doet
+FlutterFlow's eigen Deploy-pipeline (de AAB die je daar downloadt) deze stap wél?
+Waarschijnlijk, maar niet te meten vanaf hier. **Controleer het icoon dus op het
+artefact dat je daadwerkelijk uploadt**, niet op dit lokale experiment. Bouw je
+lokaal, dan is de generator-stap verplicht.
+
+**🟠 Het adaptive icon snijdt de merknaam af — "itgaanskrant.co".** Ook ná de
+generator. `adaptive_icon_foreground` wijst naar een **JPEG** (1408×1408), en een
+JPEG kan geen transparantie hebben: de gegenereerde
+`drawable-xxxhdpi/ic_launcher_foreground.png` is 432×432 met **0 % transparante
+pixels** en de buitenste 17 % is **100 % ondoorzichtig**. Android toont van een
+foreground alleen de middelste ~66 % en maskeert die rond. Gevolg: de
+achtergrondkleur `#9a141d` is nooit zichtbaar (de foreground dekt alles af) en de
+witte pil met de naam loopt aan beide kanten van het icoon af — de **U** en de
+**m** vallen weg. Gerenderde preview: `scratchpad/adaptive-zoals-android-toont.png`
+naast `icoon-bron.png`.
+*Fix:* lever als `adaptive_icon_foreground` een **PNG met transparantie** waarin
+alleen het beeldmerk op ±60 % van het vlak staat, gecentreerd; de rest
+transparant. `image_path` (het gewone icoon) mag het huidige volvlakse plaatje
+blijven. Hoort bij dezelfde ronde als taak 79.
+
+**Kleine waarnemingen, geen actie nodig tenzij je wilt:**
+- APK is **95,6 MB**. Voor Play upload je een AAB, die splitst per architectuur en
+  wordt fors kleiner — maar het is groot genoeg om even naar te kijken.
+- Het manifest van de gebouwde app bevat naast de vier eigen permissies ook
+  `ACCESS_NETWORK_STATE`, `WAKE_LOCK`, `FOREGROUND_SERVICE`, `AD_ID` en drie
+  `ACCESS_ADSERVICES_*` — die komen uit AdMob/Firebase. Relevant voor taak 63(h):
+  **Advertising ID → ja** is dus verplicht, dat klopt met wat daar staat.
+- De **UMP-consent-SDK van AdMob zit al in de build** (logcat probeert
+  `fundingchoicesmessages.google.com` te bereiken). Raakt P1-50 — de SDK is er,
+  alleen de flow niet.
+- **Crashlytics initialiseert echt**: haalt zijn settings op met `status:
+  activated` en het juiste `bundle_id`. Dat is nog geen bewezen crashrapport
+  (P1-60), maar de koppeling leeft.
+- Cosmetisch: het logo boven in het **menu (Drawer)** staat deels ónder de
+  statusbalk — de klok valt erachter. Zie `rel-menu.png`.
+
+**Wat nog niet gedaan is van deze taak:** de volledige functionele doorloop
+(zaakpagina, hartje, login, Favorieten, evenement aanmaken, vliegtuigmodus,
+Engels) en Bob's Xiaomi. De app is daarvoor blijven staan op emulator-5556.
+
+### 🆕 89 · Logo boven de gemeentenaam in de gedeelde header · Eigenaar: Claude — bezig
+
+Bob 2026-09-18: *"bij groot scherm moet in de header de foto boven de plaats."*
+Gekozen eindbeeld (Bob, zelfde dag): **☰ en ← blijven links; rechts daarvan het
+logo op regel 1 met de gemeentenaam eronder** — dus niet alles gecentreerd
+gestapeld en geen groter logo.
+
+**Waar:** `HeaderButtonsComponent` (`lib/components/header_buttons_component_widget.dart`),
+de gedeelde header op **11 levende pagina's**. Nu is het één horizontale `Wrap`
+met vier kinderen naast elkaar: hamburger (40) → terugknop (50, alleen als
+`showBackButton`) → `Image.asset('assets/images/logo800px.png', 150×22)` →
+`Text(gemeenteSelectNaam)` → `VerbindingsBanner` (2×2).
+
+**De ingreep:** logo + gemeentenaam samen in één `Column` (Main Axis Size *min*,
+Cross Axis Alignment *start*) als één kind van die Wrap. De knoppen en de
+`VerbindingsBanner` blijven ongemoeid.
+
+**Hoogte — het enige echte risico.** De header zit in een
+`FlexibleSpaceBar.background` met een vaste hoogte (gemeten op de tablet-AVD:
+~72 dp inclusief de 28 dp top-padding van het component, dus ~44 dp voor de
+inhoud). De Wrap-regelhoogte wordt nu al bepaald door de knoppen (40 zonder,
+50 mét terugknop); de gestapelde kolom wordt logo 22 + tekst ~20 ≈ 42 dp en is
+dus **niet hoger dan de knoppen** — de header hoeft daarom niet mee te groeien.
+Op een pagina zónder terugknop (bv. Home, regelhoogte 40) is de marge 2 dp, dus
+**na de bouw screenshotten op zowel telefoon- als tabletformaat** en op een
+overflow-melding letten. Wordt het wél te hoog: de tekststijl een maat kleiner,
+of de top-padding van 28 naar 24.
+
+**Let op:** wrap de Wrap zélf nooit in een `Column` — dat is het bekende patroon
+dat de hamburger stil van álle pagina's laat verdwijnen (zie `CLAUDE.md`).
+
+**Bewust besluit:** de kolom geldt op élk schermformaat, niet alleen op tablet.
+Een breekpunt-variant zou logo + tekst (inclusief tap-actie naar
+`Selectprovinciegemeente` en de vertaalsleutel) dubbel in de tree zetten. Op de
+telefoon past de rij nu net; bij een langere gemeentenaam (bv. "Bergen op Zoom
+(gemeente)") breekt de Wrap daar toch al naar een tweede regel, en stapelen is
+dan juist voorspelbaarder. Wil Bob het tóch alleen op tablet: zeg het, dan wordt
+het twee varianten met responsive Visibility.
+
 ### 🆕 88 · "Mijn aanmeldingen" + kloonknop · Eigenaar: Bob (Drupal, deel A), Claude (app, deel B)
 
 Bob 2026-09-18: *"Ziet een horecagelegenheid-eigenaar of stadsrechten-eigenaar ook