feat(i18n): presentation extraction — t() call sites, data-i18n templates, locale selector

Route every application-owned presentation string through the i18n
core: t() call sites across the app/layers/ui/data/voice surfaces,
data-i18n* attributes in the src/ui/templates/*.html markup (applied at
boot by applyDocumentTranslations from src/standalone/application.js),
and the dock locale selector (runtime-rendered from the offered pair —
a single EN button while only English ships).

Rebased onto current main, where the extraction follows the module
splits: the shell wiring now lands in the owner modules
(panelChrome, visualSettings, locationNavigation, shareRestoration,
shellFeedback, applicationShell) and the voice status corpus in the
realtime* modules; scene status lives in director.js +
playbackAdapter.js.

Modules shared with the node runtime (loadingFeedback,
installationFeedback, regionalModel, keySetupCore, vessels ingestion)
stay environment-neutral English and localize at their browser render
sites (chip maps in shellFeedback/installations controls, the weather
table in cockpitBriefing, keySetupRequirementEnvVars compositions), so
the package-boundary graph stays clean; the browser boundary groups
now own the i18n modules they reach (scripts/package-boundaries.json).
This commit is contained in:
Meir Michanie committed 2026-10-01 12:41:20 +02:00
1 parent bde1e430ef
commit 284c4d4601
98 files changed
+3474 -1625

No files matched your search

+32 -3
View File
@@ -1,6 +1,19 @@
import { locationMiniStatus } from '../locationStatus.js';
import { t } from '../i18n/index.js';
const POI_KEYS = ['Q', 'W', 'E', 'R', 'T'];
/**
* locationStatus.js sentinel outputs used as localized-rewrite triggers for
* the collapsed LOCATION mini-status. Built by calling the module with no
* real data, so the comparisons track that module's copy without restating
* English strings here. Resolved destinations (place names) stay verbatim.
*/
const LOCATION_MINI_EMPTY = Object.freeze(locationMiniStatus());
const LOCATION_MINI_SEARCHED_PLACEHOLDER = Object.freeze(
locationMiniStatus({ searchedLabel: '·' }),
);
/** Location DOM, keyboard handling and pending row animation over supplied actions. */
export class LocationControls {
constructor({
@@ -133,8 +146,24 @@ export class LocationControls {
if (this.destroyed || !this.elements.statusCity || !this.elements.statusPoi)
return;
const lines = locationMiniStatus(state);
this.elements.statusCity.textContent = lines.city;
this.elements.statusPoi.textContent = lines.poi;
// The initial/placeholder states get catalog keys at the writer so a
// non-English boot never leaks the English sentinels back over the
// localized static readout (resolved place names stay verbatim data).
this.elements.statusCity.textContent =
lines.city === LOCATION_MINI_EMPTY.city
? t('cockpit.location.miniCityInitial')
: lines.city;
if (lines.poi === LOCATION_MINI_EMPTY.poi) {
this.elements.statusPoi.textContent = t(
'cockpit.location.miniPoiInitial',
);
} else if (lines.poi === LOCATION_MINI_SEARCHED_PLACEHOLDER.poi) {
this.elements.statusPoi.textContent = t(
'cockpit.location.miniSearchedPlaceholder',
);
} else {
this.elements.statusPoi.textContent = lines.poi;
}
}
createOrbitIndicator() {
if (this.destroyed) return null;
@@ -144,7 +173,7 @@ export class LocationControls {
const icon = this.doc.createElement('span');
icon.className = 'orbit-icon';
icon.textContent = '↻';
this.orbitIndicator.append(icon, ' ORBIT');
this.orbitIndicator.append(icon, ` ${t('cockpit.location.orbitLabel')}`);
this.doc.body.appendChild(this.orbitIndicator);
}
return this.orbitIndicator;