[Bug] Sneltoetsteksten ontsnappen aan de vertaalpoort #803

Closed
opened 2026-07-24 15:46:40 +00:00 by brenno · 2 comments
Owner

De poort check-hardcoded-text mist twee plekken waar zichtbare tekst buiten l10n.d() om op het scherm komt. Beide gaan over sneltoetsaanduidingen, en ze zijn inconsistent met elkaar én met de vertaalbestanden.

1. Het achtervoegsel in het ⋮-menu. lib/widgets/app_shell_menu.dart (regel ~100):

'${l10n.d('Commandopalet')}  (Ctrl/Cmd+K)',

Het woord "Commandopalet" loopt netjes door d(), het achtervoegsel (Ctrl/Cmd+K) niet.

2. Het shortcut:-veld in het commandopalet. lib/widgets/shell/command_palette_actions.dart draagt losse literals: shortcut: 'Ctrl/Cmd+S', 'Ctrl/Cmd+H', 'Ctrl/Cmd+Z', 'Ctrl/Cmd+Shift+Z', 'Ctrl/Cmd+F' en meer.

Waarom de poort ze niet ziet. Dit kwam boven bij een refactor, niet bij een scan: zolang _menuItem een methode is, kan de datastroomanalyse de aanroep niet plaatsen en blijft de string onzichtbaar; als je diezelfde functie naar top-level tilt, ziet de poort hem meteen wél. Bij command_palette_actions.dart ontsnapt het via een veldsprong. De poort is dus niet fout, maar heeft een blinde vlek die van de vorm van de aanroeper afhangt — en dat betekent dat dit patroon ongemerkt kan groeien.

Waarom het niet alleen cosmetisch is. De vertaalbestanden doen het op de ándere manier: voor undo en saveShortcut staat de sneltoets wél ín de vertaalde tekst. Er leven dus twee patronen naast elkaar, en in sommige talen krijgt de gebruiker een half vertaalde regel.

Te beslissen bij het oppakken (dit is de eigenlijke vraag, niet 'even door d() halen'): is een sneltoets vertaalbare tekst of een identifier? Ctrl/Cmd+K is grotendeels universeel, maar niet overal — en de bestaande vertalingen behandelen het al als tekst. Kies één patroon en trek het door; zet sneltoetsen die identiek blijven op unchangedInAllLanguages in test/app_localizations_test.dart in plaats van de poort te omzeilen.

Los daarvan is het waard te kijken of de blinde vlek in tool/check_hardcoded_text.dart te dichten is, zodat een volgende ${...} losse tekst-samenstelling wél opvalt.

Herkomst: gevonden tijdens #772 (presentatie-import) door een refactor die _menuItem verplaatste; bewust niet daar opgelost, omdat het een eigen afweging is en een nieuwe bronstring in 31 talen zou betekenen op een tak die over import gaat.

De poort `check-hardcoded-text` mist twee plekken waar zichtbare tekst buiten `l10n.d()` om op het scherm komt. Beide gaan over sneltoetsaanduidingen, en ze zijn inconsistent met elkaar én met de vertaalbestanden. **1. Het achtervoegsel in het ⋮-menu.** `lib/widgets/app_shell_menu.dart` (regel ~100): ```dart '${l10n.d('Commandopalet')} (Ctrl/Cmd+K)', ``` Het woord "Commandopalet" loopt netjes door `d()`, het achtervoegsel ` (Ctrl/Cmd+K)` niet. **2. Het `shortcut:`-veld in het commandopalet.** `lib/widgets/shell/command_palette_actions.dart` draagt losse literals: `shortcut: 'Ctrl/Cmd+S'`, `'Ctrl/Cmd+H'`, `'Ctrl/Cmd+Z'`, `'Ctrl/Cmd+Shift+Z'`, `'Ctrl/Cmd+F'` en meer. **Waarom de poort ze niet ziet.** Dit kwam boven bij een refactor, niet bij een scan: zolang `_menuItem` een *methode* is, kan de datastroomanalyse de aanroep niet plaatsen en blijft de string onzichtbaar; als je diezelfde functie naar top-level tilt, ziet de poort hem meteen wél. Bij `command_palette_actions.dart` ontsnapt het via een veldsprong. De poort is dus niet fout, maar heeft een blinde vlek die van de vorm van de aanroeper afhangt — en dat betekent dat dit patroon ongemerkt kan groeien. **Waarom het niet alleen cosmetisch is.** De vertaalbestanden doen het op de ándere manier: voor `undo` en `saveShortcut` staat de sneltoets wél ín de vertaalde tekst. Er leven dus twee patronen naast elkaar, en in sommige talen krijgt de gebruiker een half vertaalde regel. **Te beslissen bij het oppakken** (dit is de eigenlijke vraag, niet 'even door `d()` halen'): is een sneltoets vertaalbare tekst of een identifier? `Ctrl/Cmd+K` is grotendeels universeel, maar niet overal — en de bestaande vertalingen behandelen het al als tekst. Kies één patroon en trek het door; zet sneltoetsen die identiek blijven op `unchangedInAllLanguages` in `test/app_localizations_test.dart` in plaats van de poort te omzeilen. Los daarvan is het waard te kijken of de blinde vlek in `tool/check_hardcoded_text.dart` te dichten is, zodat een volgende `${...} losse tekst`-samenstelling wél opvalt. **Herkomst:** gevonden tijdens #772 (presentatie-import) door een refactor die `_menuItem` verplaatste; bewust niet daar opgelost, omdat het een eigen afweging is en een nieuwe bronstring in 31 talen zou betekenen op een tak die over import gaat.
Author
Owner

Opgepakt. Tak: fix/sneltoetsen-vertaalpoort-803.

Verwachte reikwijdte:

  • lib/widgets/app_shell_menu.dart (achtervoegsel Commandopalet)
  • lib/widgets/shell/command_palette_actions.dart (shortcut:-literals)
  • lib/widgets/app_shell_main_layout.dart (tooltips undo/redo/saveShortcut)
  • nieuw: lib/utils/shortcut_label.dart + test
  • tool/check_hardcoded_text.dart (blinde vlek: aanroep zonder doel binnen een extension)
  • lib/l10n/translations/*.dart, test/app_localizations_test.dart
Opgepakt. Tak: fix/sneltoetsen-vertaalpoort-803. Verwachte reikwijdte: - lib/widgets/app_shell_menu.dart (achtervoegsel Commandopalet) - lib/widgets/shell/command_palette_actions.dart (shortcut:-literals) - lib/widgets/app_shell_main_layout.dart (tooltips undo/redo/saveShortcut) - nieuw: lib/utils/shortcut_label.dart + test - tool/check_hardcoded_text.dart (blinde vlek: aanroep zonder doel binnen een extension) - lib/l10n/translations/*.dart, test/app_localizations_test.dart
Author
Owner

Gemerged als 7f07d042 (PR #810), op main geverifieerd.

Het besluit: een sneltoets is allebei — de toets is een identifier (hangt aan een LogicalKeyboardKey, verandert niet met de taal), de modificatietoets is tekst (Duits leest Strg, Frans Maj) en de bestaande vertalingen deden dat al. Alleen dat deel loopt door d(); lib/utils/shortcut_label.dart stelt de rest samen. Kosten: twee bronstrings in plaats van één per sneltoets, dus de volgende sneltoets kost geen 31 vertalingen. undo, redo en saveShortcut konden weg — dat wás het tweede patroon.

De blinde vlek is gedicht en was eerst bevestigd met een proef: een kale literal in _menuItem(…) liet de poort groen. Oorzaak was smaller dan gedacht en tegelijk breder — een aanroep zonder doel binnen extension _X on _YState werd geknoopt aan de naam van de extension, terwijl de declaratie onder de klasse staat. Dat patroon draagt in deze repo elk gesplitst widgetbestand. Twee fixture-tests staan rood zonder de fix.

Het dichten legde negen onvertaalde regels in het Over-venster bloot (adres, e-mail, KvK, IBAN, BIC, bank, pilot-domein) — die zaten er al en zijn meegenomen.

Onderweg gevonden: de toetsenlegenda beloofde Ctrl+N en Ctrl+W terwijl beide bindings control || meta zijn. Op een Mac stond daar dus al het verkeerde.

Wat er níét in zat: de veldsprong via PaletteCommand.shortcut. Die is wél gemeten — dichtbaar langs dezelfde weg, maar hij legt 23 échte overtredingen bloot, waaronder standard.bundled in reference_standards.dart: Nederlandse proza die met een kale Text() in 31 talen blijft staan. Dat vraagt eerst een productbeslissing, dus staat het als #809 met de werkende patch erbij. Tot die tijd draagt test/shortcut_label_test.dart dat halve gat met een wacht die geen enkel bestand in lib/ nog zelf een sneltoets laat schrijven.

Gemerged als 7f07d042 (PR #810), op main geverifieerd. **Het besluit:** een sneltoets is allebei — de toets is een identifier (hangt aan een `LogicalKeyboardKey`, verandert niet met de taal), de modificatietoets is tekst (Duits leest Strg, Frans Maj) en de bestaande vertalingen deden dat al. Alleen dat deel loopt door `d()`; `lib/utils/shortcut_label.dart` stelt de rest samen. Kosten: twee bronstrings in plaats van één per sneltoets, dus de volgende sneltoets kost geen 31 vertalingen. `undo`, `redo` en `saveShortcut` konden weg — dat wás het tweede patroon. **De blinde vlek** is gedicht en was eerst bevestigd met een proef: een kale literal in `_menuItem(…)` liet de poort groen. Oorzaak was smaller dan gedacht en tegelijk breder — een aanroep zonder doel binnen `extension _X on _YState` werd geknoopt aan de naam van de extension, terwijl de declaratie onder de klasse staat. Dat patroon draagt in deze repo elk gesplitst widgetbestand. Twee fixture-tests staan rood zonder de fix. Het dichten legde negen onvertaalde regels in het Over-venster bloot (adres, e-mail, KvK, IBAN, BIC, bank, pilot-domein) — die zaten er al en zijn meegenomen. **Onderweg gevonden:** de toetsenlegenda beloofde `Ctrl+N` en `Ctrl+W` terwijl beide bindings `control || meta` zijn. Op een Mac stond daar dus al het verkeerde. **Wat er níét in zat:** de veldsprong via `PaletteCommand.shortcut`. Die is wél gemeten — dichtbaar langs dezelfde weg, maar hij legt 23 échte overtredingen bloot, waaronder `standard.bundled` in `reference_standards.dart`: Nederlandse proza die met een kale `Text()` in 31 talen blijft staan. Dat vraagt eerst een productbeslissing, dus staat het als #809 met de werkende patch erbij. Tot die tijd draagt `test/shortcut_label_test.dart` dat halve gat met een wacht die geen enkel bestand in `lib/` nog zelf een sneltoets laat schrijven.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
LibreKAT/Ocideck#803
No description provided.