fix: bestandskiezer-poort van 7 naar 0, plus een live webbug (#528) #565

Merged
brenno merged 2 commits from fix/filepicker-poort-in-de-dialoog into main 2026-07-22 15:23:20 +00:00
Owner

filePickerPathBaseline van 7 naar 0.

De issue vroeg om elke regel apart te wegen en niet te batchen. Dat is gebeurd,
en het leverde drie verschillende uitkomsten op — plus één ontdekking die de
issue zelf verkeerd had.

De vier "gepoort bij de aanroeper"

open_presentation_dialog, slide_finder_dialog, import_slides_dialog,
save_destination_dialog. Deze waren vandaag correct, en dát was het bezwaar:
het bestand kon zijn eigen garantie niet bewijzen, dus verdwijnt die bij de
eerstvolgende nieuwe aanroeper. De poort staat nu in de methode zelf, zoals
#506 het bij de logokiezer deed.

image_service — geen baseline-regel maar een live bug

De issue vroeg terecht om éérst vast te stellen wat er op web gebeurt: "dead on
web, or a live blob:-URL leak". Het is geen van beide.

PlatformFile.path gooit op web een kale String (file_picker 5.5.0,
platform_file.dart regel 37). Geen null, geen blob:-URL. Wie in de webversie
op "Bestand kiezen" drukte bij een video- of audiodia, kreeg dus een onafgevangen
fout — en geen van de vier aanroepers poortte.

Dat verschil is niet academisch: een blob:-URL faalt stil en verkeerd, een
worp vliegt ongevangen omhoog. Twee plekken in check_conventions.dart
beweerden het blob-verhaal — in de kop van de regel én in de foutmelding die een
ontwikkelaar te zien krijgt. Allebei gecorrigeerd, met de datum en de vindplaats
erbij.

De vier knoppen zijn nu verborgen op web (er is daar geen projectmap om in te
importeren; video via URL werkt er wél), en de dienst poort daarnaast defensief.

settings_dialog en file_service

Zelfde patroon als de vier dialogen. Maar hier liep ik tegen de klassenratchet:
beide klassen stonden tegen hun plafond, dus tien regels commentaar erbij liet
make check vallen.

Dat bleek een aanwijzing in plaats van een obstakel. De poort hoorde niet zes
keer te staan maar één keer per bibliotheek, in een top-level functie buiten de
klasse: _pickDirectoryGated, _pickPathGated, _pickBytes. Gedrag uit de
klasse halen is precies wat die ratchet vraagt — netto FileService 2885 → 2879,
vastgezet in de baseline.

De kiezers wonen in file_service_import.dart en niet in een eigen part: een
nieuw bestand met alleen kiezer-code haalt in tests nul dekking, en dan koop je
een groene klassenratchet af met een gele dekkingspoort.

Bewijs

Een test kan dit niet vangen — kIsWeb is onder flutter test altijd false, en
dat is precies waarom deze poort statisch is. Het bewijs is dat de lijst leeg is
en dat make check-conventions een verouderde regel zelf meldt (dat deed hij
onderweg ook, drie keer, en dat is hoe ik wist dat elke reparatie echt landde).

filePickerPathBaseline blijft als lege lijst staan, met de reden erbij: een
nieuwe regel is geen boekhouding maar een besluit.

make check groen.

Closes #528

`filePickerPathBaseline` van **7 naar 0**. De issue vroeg om elke regel apart te wegen en niet te batchen. Dat is gebeurd, en het leverde drie verschillende uitkomsten op — plus één ontdekking die de issue zelf verkeerd had. ## De vier "gepoort bij de aanroeper" `open_presentation_dialog`, `slide_finder_dialog`, `import_slides_dialog`, `save_destination_dialog`. Deze waren vandaag correct, en dát was het bezwaar: het bestand kon zijn eigen garantie niet bewijzen, dus verdwijnt die bij de eerstvolgende nieuwe aanroeper. De poort staat nu in de methode zelf, zoals #506 het bij de logokiezer deed. ## `image_service` — geen baseline-regel maar een live bug De issue vroeg terecht om éérst vast te stellen wat er op web gebeurt: "dead on web, or a live blob:-URL leak". Het is geen van beide. `PlatformFile.path` **gooit** op web een kale String (file_picker 5.5.0, `platform_file.dart` regel 37). Geen null, geen `blob:`-URL. Wie in de webversie op "Bestand kiezen" drukte bij een video- of audiodia, kreeg dus een onafgevangen fout — en geen van de vier aanroepers poortte. Dat verschil is niet academisch: een `blob:`-URL faalt stil en verkeerd, een worp vliegt ongevangen omhoog. Twee plekken in `check_conventions.dart` beweerden het blob-verhaal — in de kop van de regel én in de foutmelding die een ontwikkelaar te zien krijgt. Allebei gecorrigeerd, met de datum en de vindplaats erbij. De vier knoppen zijn nu verborgen op web (er is daar geen projectmap om in te importeren; video via URL werkt er wél), en de dienst poort daarnaast defensief. ## `settings_dialog` en `file_service` Zelfde patroon als de vier dialogen. Maar hier liep ik tegen de klassenratchet: beide klassen stonden tegen hun plafond, dus tien regels commentaar erbij liet `make check` vallen. Dat bleek een aanwijzing in plaats van een obstakel. De poort hoorde niet zes keer te staan maar één keer per bibliotheek, in een top-level functie buiten de klasse: `_pickDirectoryGated`, `_pickPathGated`, `_pickBytes`. Gedrag uit de klasse halen is precies wat die ratchet vraagt — netto `FileService` 2885 → 2879, vastgezet in de baseline. De kiezers wonen in `file_service_import.dart` en niet in een eigen `part`: een nieuw bestand met alleen kiezer-code haalt in tests nul dekking, en dan koop je een groene klassenratchet af met een gele dekkingspoort. ## Bewijs Een test kan dit niet vangen — `kIsWeb` is onder `flutter test` altijd false, en dat is precies waarom deze poort statisch is. Het bewijs is dat de lijst leeg is en dat `make check-conventions` een verouderde regel zelf meldt (dat deed hij onderweg ook, drie keer, en dat is hoe ik wist dat elke reparatie echt landde). `filePickerPathBaseline` blijft als lege lijst staan, met de reden erbij: een nieuwe regel is geen boekhouding maar een besluit. `make check` groen. Closes #528
Vier dialogen stonden in filePickerPathBaseline als "gepoort bij de
aanroeper". Dat klopte, en dat was precies het bezwaar: het bestand kon zijn
eigen garantie niet bewijzen, dus verdwijnt die bij de eerstvolgende nieuwe
aanroeper. De poort staat nu in de methode zelf, zoals #506 het bij de
logokiezer deed.

pickVideo en pickAudio waren geen baseline-regel maar een LIVE BUG. Bij het
vaststellen wat er op web gebeurt bleek het geen van beide dingen die de issue
noemde: `PlatformFile.path` geeft daar geen null en geen blob:-URL, hij GOOIT
een kale String (file_picker 5.5.0, platform_file.dart). Wie in de webversie op
"Bestand kiezen" drukte, kreeg dus een ongevangen fout. De vier knoppen zijn nu
verborgen op web — er is daar geen projectmap om in te importeren — en de
dienst poort daarnaast defensief, zodat het bestand zijn eigen belofte
waarmaakt.

Twee plekken in check_conventions.dart beweerden dat blob:-verhaal, in de kop
en in de foutmelding. Allebei gecorrigeerd met de datum erbij: het verschil is
niet academisch, want een blob-URL faalt stil en verkeerd terwijl een worp
ongevangen omhoog vliegt.

Het bewijs is het krimpen van de lijst zelf: 7 -> 2. Een test kan dit niet
vangen — kIsWeb is onder `flutter test` altijd false — en dat is nu juist de
reden dat deze poort statisch is.

Refs #528
fix(web): poort de laatste twee bestandskiezers, basislijn naar 0
Some checks failed
CI / Gate (Linux) · Format · Analyze · Coverage (push) Failing after 4s
CI / Web hardening (push) Failing after 4s
CI / Docs links (push) Failing after 4s
CI / Supply-chain (Trivy · advisory) (push) Failing after 5s
CI / Gate (Linux) · Format · Analyze · Coverage (pull_request) Failing after 4s
CI / Web hardening (pull_request) Failing after 5s
CI / Docs links (pull_request) Failing after 4s
CI / Supply-chain (Trivy · advisory) (pull_request) Failing after 5s
CI / Test (macos-latest) (push) Has been cancelled
CI / Test (windows-latest) (push) Has been cancelled
CI / Test (macos-latest) (pull_request) Has been cancelled
CI / Test (windows-latest) (pull_request) Has been cancelled
b74f36fa4c
settings_dialog en file_service waren de laatste twee regels in
filePickerPathBaseline. Allebei gepoort bij hun aanroeper, allebei niet in
staat dat zelf te bewijzen — dezelfde broosheid als de vier dialogen hiervoor.

De poort staat nu één keer per bibliotheek in plaats van per kiezer, in een
top-level functie buiten de klasse: `_pickDirectoryGated` (settings_dialog) en
`_pickPathGated` / `_pickBytes` (file_service). Dat was ook nodig, want beide
klassen stonden tegen hun plafond: gedrag eruit halen is precies wat die
ratchet vraagt, en het leverde 2885 -> 2879 op.

De kiezers wonen in file_service_import.dart en niet in een eigen part: een
nieuw bestand met alleen kiezer-code haalt in tests nul dekking, en dan koop je
een groene klassenratchet af met een gele dekkingspoort.

filePickerPathBaseline is nu leeg. De lijst blijft staan met de reden erbij:
een nieuwe regel is geen boekhouding maar een besluit.

Closes #528
brenno merged commit 68ca3cd22b into main 2026-07-22 15:23:20 +00:00
Sign in to join this conversation.
No description provided.