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

+13 -11
View File
@@ -1,3 +1,5 @@
import { t } from '../i18n/index.js';
/** Build the voice control independently of its connection backend. */
export function createVoiceControl({ reset = false } = {}) {
let root = document.getElementById('gev-voice-control');
@@ -12,14 +14,14 @@ export function createVoiceControl({ reset = false } = {}) {
root.dataset.speaker = 'idle';
root.innerHTML = `
<div class="gev-voice-heading">
<div class="gev-voice-kicker">AI AGENT</div>
<div id="gev-voice-status">OFF</div>
<div class="gev-voice-kicker">${t('setup.voice.kicker.agent')}</div>
<div id="gev-voice-status">${t('setup.voice.status.idle')}</div>
<div class="gev-voice-cost">
<button id="gev-voice-tier" class="gev-voice-tier-btn" type="button" aria-pressed="false" title="Voice model tier — applies next session">STD</button>
<span id="gev-voice-cost-value" class="gev-voice-cost-value" data-level="ok" title="Estimated session cost">~$0.00</span>
<button id="gev-voice-tier" class="gev-voice-tier-btn" type="button" aria-pressed="false" title="${t('setup.voice.tier.buttonTitle')}">STD</button>
<span id="gev-voice-cost-value" class="gev-voice-cost-value" data-level="ok" title="${t('setup.voice.cost.buttonTitle')}">~$0.00</span>
</div>
</div>
<button id="gev-voice-button" type="button" aria-label="Voice control — activate to toggle voice; hold Space to speak" aria-describedby="gev-voice-help">
<button id="gev-voice-button" type="button" aria-label="${t('setup.voice.button.ariaLabel')}" aria-describedby="gev-voice-help">
<span class="gev-mic-orbit"><img src="/mic.svg" alt="" /></span>
<span class="gev-mic-label">ON/OFF</span>
</button>
@@ -27,19 +29,19 @@ export function createVoiceControl({ reset = false } = {}) {
${Array.from({ length: 15 }, (_, index) => `<span style="--bar:${index}"></span>`).join('')}
</div>
<div class="gev-voice-readout">
<div id="gev-voice-detail">VOICE STANDBY</div>
<div id="gev-voice-detail">${t('setup.voice.detail.standby')}</div>
</div>
<div id="gev-voice-help" class="gev-voice-help-tray" role="tooltip">
<span class="gev-voice-help-kicker">VOICE CONTROL</span>
<span class="gev-voice-help-detail">Hold Space to speak · tap Space to activate focused controls</span>
<span class="gev-voice-help-kicker">${t('setup.voice.kicker.control')}</span>
<span class="gev-voice-help-detail">${t('setup.voice.hint.default')}</span>
</div>
<div class="gev-voice-error-tray" role="alert" aria-live="assertive">
<div class="gev-voice-error-header">
<span>VOICE SYSTEM ERROR</span>
<button class="gev-voice-error-dismiss" type="button">DISMISS</button>
<span>${t('setup.voice.error.trayTitle')}</span>
<button class="gev-voice-error-dismiss" type="button">${t('setup.voice.error.dismiss')}</button>
</div>
<div id="gev-voice-error-detail"></div>
<div class="gev-voice-error-hint">Check microphone permission and network access, then try again.</div>
<div class="gev-voice-error-hint">${t('setup.voice.error.hint')}</div>
</div>
`;
const commandDock = document.getElementById('command-dock');