Switch language in place, without a reload

Choosing a language in the picker now applies it at once. The choice is
stored and ?lang is kept in step through replaceState, and the picker keeps
focus.

Code that writes translated text itself re-presents it on a switch:
onLocaleChange() lets an owner listen, removed at teardown, and status
writers hand over a function of the locale (voice cards, scene director,
SDR, draw hints, imagery split, map sources, Bhote Koshi media) so the
words are rebuilt rather than re-sent. The HUD, cockpit, radio, CCTV,
launch, awareness and credit texts follow the same hook, and
applyDocumentTranslations can be applied again without undoing text code
wrote since.

The unsaved-work registry and persistLocaleAndReload existed only to guard
the reload, so they go, with their catalog entries.
This commit is contained in:
Sameh Khamis committed 2026-11-01 16:47:39 -08:00
1 parent ba20bc13d8
commit b20c80e590
87 files changed
+1194 -777

No files matched your search

-7
View File
@@ -872,7 +872,6 @@
"That line has no length — click somewhere further away.": "Diese Linie hat keine Länge – weiter entfernt klicken.",
" · {max}-point limit reached": " · Limit von {max} Punkten erreicht",
"{measure} · double-click or Enter to finish, Backspace undoes, Esc cancels.{full}": "{measure} · Doppelklick oder Enter beendet, Rücktaste macht rückgängig, Esc bricht ab.{full}",
"drawings on the map": "Zeichnungen auf der Karte",
"That shape already has {count} points — finish it or press Backspace.": "Diese Form hat bereits {count} Punkte – abschließen oder Rücktaste drücken.",
"That point is off the globe — click on the world.": "Dieser Punkt liegt außerhalb des Globus – auf die Erde klicken.",
"That shape could not be placed.": "Diese Form konnte nicht platziert werden.",
@@ -1173,7 +1172,6 @@
"GET KEY ↗": "SCHLÜSSEL HOLEN ↗",
"{envVar} saved — paste to replace": "{envVar} gespeichert – zum Ersetzen einfügen",
"paste {envVar}": "{envVar} einfügen",
"unsaved provider keys": "ungespeicherte Anbieter-Schlüssel",
"Project keys: {status}": "Projektschlüssel: {status}",
"Cloud voice will use OPENAI_API_KEY on the next session.": "Die Cloud-Sprachsteuerung verwendet ab der nächsten Sitzung OPENAI_API_KEY.",
"Checking local ChatGPT OAuth sign-in…": "Lokale ChatGPT-OAuth-Anmeldung wird geprüft…",
@@ -2049,9 +2047,6 @@
"Sensitivity": "Empfindlichkeit",
"WHOT/BHOT": "WHOT/BHOT",
"Ironbow": "Ironbow",
"unsaved CCTV calibration": "ungespeicherte CCTV-Kalibrierung",
"the open cockpit": "das geöffnete Cockpit",
"Switching language reloads the page. This will be lost: {items}. Switch anyway?": "Ein Sprachwechsel lädt die Seite neu. Dabei geht Folgendes verloren: {items}. Trotzdem wechseln?",
"Link shared": "Link geteilt",
"Return map to straight-down view": "Karte wieder senkrecht von oben zeigen",
"Tilt map to oblique view": "Karte in Schrägansicht kippen",
@@ -2098,7 +2093,6 @@
"{aircraftClass} · {emergency} · {feedState}": "{aircraftClass} · {emergency} · {feedState}",
"{source} · LOCATION QUERY · RECENT": "{source} · ORTSABFRAGE · AKTUELL",
"Rendered globe frames per second · toggle with `": "Gerenderte Globus-Frames pro Sekunde · umschalten mit `",
"imported map files": "importierte Kartendateien",
"Ground heights could not be refreshed. Try the file again when the map has loaded.": "Geländehöhen konnten nicht aktualisiert werden. Die Datei erneut laden, wenn die Karte geladen ist.",
"{count} map objects": {
"one": "{count} Kartenobjekt",
@@ -2678,7 +2672,6 @@
"Activate to toggle voice": "Aktivieren, um die Sprachsteuerung umzuschalten",
"Voice active": "Sprachsteuerung aktiv",
"Voice could not be started.": "Sprachsteuerung konnte nicht gestartet werden.",
"the active voice session": "die aktive Sprachsitzung",
"{value} feet": "{value} Fuß",
"Fire · FRP {frp} MW": "Brand · FRP {frp} MW",
"The flights layer is not enabled": "Die Ebene „Live-Flüge“ ist nicht aktiviert",