feat(meetings): de vergaderschil — aanbieder-neutrale UI plus vertalingen #983

Merged
brenno merged 12 commits from feat/vergaderschil into main 2026-07-30 05:07:22 +00:00
Owner

De aanbieder-neutrale schil voor onlinevergaderingen, plus de bijbehorende
vertalingen — het vervolg op de domeinlaag (#971).

Wat er in zit

  • De schil (lib/widgets/meetings/): deelnamedialoog met linkherkenning
    tijdens het typen, meeting_shell_chrome.dart (startpunt in de tabbalk,
    statuslampje, wachtstrip, waker die het gespreksvenster bij toelating opent),
    gespreksvenster met knoppen uit de capabilities, en meeting_failure_text.dart.
  • De nep-adapter en de modulepoort (ModuleId.meetings, standaard uit).
  • Vertalingen: alle zichtbare schil-teksten gaan door l10n.d('…') en zijn
    nu in alle 31 talen gevuld (90 bronstrings × 31 talen, via make add-l10n).
    De vergaderrol 'moderator' is een leenwoord dat in het Engels samenvalt met de
    bron; op de unchangedInEnglish-witlijst gezet, de dertig andere talen
    vertalen het wél en die dekking blijft bewaakt.
  • Fixes op de gast-waarschuwing (volgt de adapter) en op annuleren (annuleert
    echt, geen tweede gespreksvenster).

Grens

Nog géén echte aanbieder en geen netwerkroute — bewaakt door een bronscan-test
(meeting_privacy_boundary_test.dart): niets onder lib/meetings/ mag een
netwerk- of platformlaag importeren.

Bewaker

Overgeslagen: de wijziging raakt geen bestandsformaat, opslag, afhankelijkheid,
uitgaand verkeer of publieke belofte — de netwerkgrens is juist afwezig en met
een test vastgelegd. Het toegevoegde werk is UI-schil + vertalingen.

Poort

make l10n-check groen. make check draait; merge volgt pas als die groen is.

🤖 Generated with Claude Code

De aanbieder-neutrale schil voor onlinevergaderingen, plus de bijbehorende vertalingen — het vervolg op de domeinlaag (#971). ## Wat er in zit - **De schil** (`lib/widgets/meetings/`): deelnamedialoog met linkherkenning tijdens het typen, `meeting_shell_chrome.dart` (startpunt in de tabbalk, statuslampje, wachtstrip, waker die het gespreksvenster bij toelating opent), gespreksvenster met knoppen uit de capabilities, en `meeting_failure_text.dart`. - **De nep-adapter** en de modulepoort (`ModuleId.meetings`, standaard uit). - **Vertalingen**: alle zichtbare schil-teksten gaan door `l10n.d('…')` en zijn nu in alle 31 talen gevuld (90 bronstrings × 31 talen, via `make add-l10n`). De vergaderrol 'moderator' is een leenwoord dat in het Engels samenvalt met de bron; op de `unchangedInEnglish`-witlijst gezet, de dertig andere talen vertalen het wél en die dekking blijft bewaakt. - Fixes op de gast-waarschuwing (volgt de adapter) en op annuleren (annuleert echt, geen tweede gespreksvenster). ## Grens Nog géén echte aanbieder en geen netwerkroute — bewaakt door een bronscan-test (`meeting_privacy_boundary_test.dart`): niets onder `lib/meetings/` mag een netwerk- of platformlaag importeren. ## Bewaker Overgeslagen: de wijziging raakt geen bestandsformaat, opslag, afhankelijkheid, uitgaand verkeer of publieke belofte — de netwerkgrens is juist afwezig en met een test vastgelegd. Het toegevoegde werk is UI-schil + vertalingen. ## Poort `make l10n-check` groen. `make check` draait; merge volgt pas als die groen is. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
De schil van T14/T15 op het fundament van #971:

- meeting_join_dialog: link plakken met herkenning terwijl je typt (lokaal,
  gratis, raakt geen dienst aan), naam, en de egress-bekendmaking van §6.2
  stap 4 vóór de knop — opgebouwd uit de feiten van de preflight, niet uit
  een zelfverzonnen zin. De dienst wordt pas aangeraakt bij Controleren (T8).
- meeting_shell_chrome: het startpunt in de tabbalk (werkt met een leeg
  OciDeck, §6.1), het statuslampje dat per fase in kleur, pictogram én tekst
  verschilt en beperkte beweging respecteert, de niet-modale wachtstrip met
  Verlaten, en de waker die het gespreksvenster bij toelating zelf opent.
- meeting_workspace: knoppen uitsluitend uit MeetingCapabilities (T12),
  Verlaten altijd (§17), blijvende opname/uitschrijf-banier (§15) en de
  toestemmingsvraag met weigeren als gelijkwaardige keuze.
- meeting_failure_text: per MeetingFailureKind een vertaalde uitleg die zegt
  wat er misging én wat de gebruiker nu kan doen — geen adapter die een
  Engelse servermelding op het scherm krijgt.

De bestandsgrootte-ratchet stond exact op de omvang van app_shell.dart, dus
elke regel erbij viel. Daarom zijn de module-ontdekkingsbanieren (twee
modules, één patroon, 189 regels) verhuisd naar shell/module_prompts.dart en
staat de basislijn nu op 855 in plaats van 1042: de winst vastgezet.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Twintig tests over de schil: dat herkennen tijdens het typen de sessie niet
aanraakt (een halve link is geen mislukte vergadering), dat de bekendmaking
vóór de knop staat, dat wachten in de omlijsting gebeurt en in pictogram
verschilt van verbonden, dat een ingetrokken recht de knop weghaalt zonder
het gesprek te beëindigen, en dat elke faalsoort een eigen uitleg heeft die
geen leverancier noemt.

Twee vondsten onderweg. Het statuslampje knippert met opzet eindeloos (T15),
dus pumpAndSettle komt daar nooit klaar — de tests pompen begrensd, met de
reden erbij. En de nep-adapter kon geen recht intrekken tijdens een gesprek,
terwijl COLLABORATION.md §7.1.1 dat pad uitdrukkelijk eist; changeCapabilities
en changeRole vullen dat gat.

COLLABORATION.md §7.1.6 krijgt de moeilijkste ontwerpvraag van deze functie op
papier: een Jitsi-URL is structureel niet van een gewone webpagina te
onderscheiden, dus herkennen kan niet uit de link volgen. Vastgelegd: geen
probing, geen blanket-claim, geen auto-besluit op vorm; wel drie trappen van
vertrouwen met de gebruiker als bron van het ene feit dat geen URL draagt. Plus
de fragment-val: Jitsi honoreert #config-overrides, dus het strippen van het
fragment is een beveiligingseigenschap en geen netheid.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
USER_GUIDE beschrijft de vier stappen van het venster, dat wachten het
scherm niet overneemt, en dat knoppen alleen verschijnen wanneer de
vergadering ze toestaat — met de eerlijke stand erbij: geen dienst
aangesloten, dus meedoen kan nog niet. SOURCE_MAP krijgt de sectie
lib/widgets/meetings/ bestand voor bestand, plus shell/module_prompts.dart
met de reden waarom het bestaat.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Bevinding van de kernwaardenbewaker: de hint onder het naamveld beweerde
onvoorwaardelijk 'de anderen zien u als gast; niemand controleert deze naam',
terwijl het identiteitsmodel in dezelfde wijziging al serviceAppGuest,
hostSponsored en account kent. Bij zo'n adapter zouden er twee elkaar
tegensprekende beweringen boven dezelfde Meedoen-knop staan — en de kop van
het bestand eist juist dat bekendmakingstekst uit de feiten van de adapter
komt en niet uit een hier verzonnen zin.

De regel is nu een losse pure functie (showsUnverifiedNameHint), zoals de
faalteksten: zonder feiten van een adapter blijft de gastaanname staan, want
dat is waar deze functie voor bestaat (T2); zodra er een echte identiteit
gemeld wordt verdwijnt de waarschuwing en zegt de bekendmaking wat er wél
geldt. Een losse functie omdat geen enkele bestaande adapter de andere vier
identiteiten meldt — zo is het toch per soort te toetsen.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
De format-poort op main staat rood: PR #972 (dekkingsvloer naar 34%)
bracht vijf tests mee die dart format nog wilde herschrijven. Deze tak
raakt ze verder niet aan; alleen de opmaak, zodat make check weer kan
spreken over het eigenlijke werk.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Dezelfde vijf tests die ongeformatteerd op main kwamen, halen ook de
analyzer niet: een lege catch in de carousel-teardown en twee
ongebruikte imports in de klembordtest. De catch krijgt het waarom
(best-effort opruimen), de imports gaan weg.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Twee gebreken uit de review, plus de testgaten die ze konden verbergen.

**Annuleren was een doodlopende weg.** Op Controleren legt de notifier de
uitnodiging vast en gaat de fase naar validating; daarmee geldt de sessie als
actief. Sloot de gebruiker daarna het venster, dan bleef dat staan: het
startpunt in de tabbalk verbergt zich (er loopt al een vergadering) terwijl
de wachtstrip zich in díe fase niet laat zien — er was geen knop meer om
ergens uit te komen, alleen een herstart hielp. Empirisch nagegaan vóór de
reparatie. Het opruimen zit nu in MeetingJoinDialog.show, ná de await: daar
komen de knop, Escape en een tik naast het venster alle drie langs. Niet in
dispose, want Riverpod verbiedt het wijzigen van een provider tijdens het
afbreken van de boom (ook nagegaan: het werkte, maar met een fout).

**Twee gespreksvensters konden stapelen.** Het lampje opent er een en de
toelatingswaker even later nog een; Verlaten liet dan het onderste staan. Er is
één gesprek, dus één venster: show() is nu idempotent, met de rem in een
finally zodat Escape hem niet laat hangen — plus een testreset, want een test
die eindigt met het venster open laat die rem anders staan en dan hangt de
volgende test van de testvolgorde af.

**De testgaten die de reviewer aanwees, gedicht en met mutaties getoetst.** De
toelatingswaker had geen enkele test, terwijl hij het énige signaal is dat de
gebruiker bij toelating krijgt; de gelukte deelname (naam typen, Meedoen,
sessie) liep in geen enkele test. Drie mutaties overleefden de suite en falen
nu alle drie: de waker leeg maken, onChanged van het naamveld weghalen (knop
blijft grijs, meedoen onmogelijk), en de fasen van §6.2 overslaan (join ketst
stil af op de fasepoort).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
De dialoog, wachtstrip, het gespreksvenster en de faalteksten van de
onlinevergaderingen-schil gingen door l10n.d('…') maar stonden nog nergens
vertaald; make l10n-check viel op ~90 onvertaalde bronstrings. Via
make add-l10n de overlays gevuld — 90 strings × 31 talen.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
De vergaderrol-labels gaan door d(); 'moderator' is een leenwoord dat
Nederlands en Engels identiek schrijven, dus viel de Engelse fallback samen
met de bronstring en tripte de fallback-poort. Op de unchangedInEnglish-witlijst
gezet; de dertig andere talen vertalen het woord wél en die dekking blijft
bewaakt.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Merge remote-tracking branch 'origin/main' into feat/vergaderschil
All checks were successful
scans / scans (pull_request) Successful in 3m30s
fd5ea96321
# Conflicts:
#	test/image_carousel_picker_actions_test.dart
docs(meetings): herstel SOURCE_MAP-secties na de merge
All checks were successful
scans / scans (pull_request) Successful in 3m26s
c387c4704e
De 3-weg-merge met main wrong het meetings-blok middenin de dialogs-sectie,
waardoor de dialoog-entries erna onder de meetings-kop vielen en naar
niet-bestaande lib/widgets/meetings/-paden wezen. Blok naar ná de dialogs-sectie
verplaatst. En de module_prompts.dart-entry stond onder lib/state/ met een
relatief pad dat naar lib/state/shell/ resolveerde; naar de lib/widgets/shell/-
sectie verhuisd bij tab_bar.dart, met een kaal pad. source_map_coverage_test groen.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
brenno merged commit a79afc34b7 into main 2026-07-30 05:07:22 +00:00
brenno deleted branch feat/vergaderschil 2026-07-30 05:07:23 +00:00
Sign in to join this conversation.
No description provided.