i18n(ar): address code review findings

Mirror the dock trays and their pin, the compact Radio window and the
phone top-bar actions in right-to-left; keep the Cyber cockpit's Data
Layers stack on the left edge. Isolate the Space Missions counter,
landing coordinates and CCTV summary parts, format their numbers with
the locale's numerals, decide pack shot titles by the marker binding,
and place Bhote Koshi media cards between the panels on either side.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
German KhokhlovandClaude Opus 5.5 committed 2026-10-29 15:20:47 +04:00
1 parent 8c291d8a0c
commit 04481ef202
17 files changed
+313 -55

No files matched your search

+4 -1
View File
@@ -1,5 +1,5 @@
import { CCTV_AMBIENT_CARD_MAX } from '../../data/cctvLod.js';
import { t, translateKnown } from '../../i18n/index.js';
import { isolate, t, translateKnown } from '../../i18n/index.js';
import { ACTIVE_FRAME_REFRESH_MS, IDLE_FRAME_REFRESH_MS } from './policy.js';
import { headingHudToken, isHeadingEstimated } from './headingConfidence.js';
import {
@@ -60,6 +60,8 @@ export function createPresentation({
const health = layerState._healthById.get(active.camera.id) || null;
const calBadge = parts.calibration.deriveCalBadge(active.camera);
// Each part is isolated: in right-to-left text a code keeps its own value
// (FOV 44°) instead of trading it with its neighbour.
return [
t('{city} CCTV', {
city: active.camera.city.toUpperCase(),
@@ -107,6 +109,7 @@ export function createPresentation({
: null,
]
.filter(Boolean)
.map(isolate)
.join(' · ');
}
+7 -7
View File
@@ -1,5 +1,5 @@
import * as Cesium from 'cesium';
import { t } from '../../i18n/index.js';
import { formatNumber, isolate, t } from '../../i18n/index.js';
import {
MISSION_CLOSE_VIEW_RANGE_M,
MISSION_GLOBE_VIEW_RANGE_M,
@@ -232,7 +232,7 @@ export function createPanel({ state: layerState, services, parts, source }) {
? payload.operator
: null,
Number.isFinite(payload.massKg)
? `${payload.massKg.toLocaleString()} KG`
? `${formatNumber(payload.massKg)} KG`
: null,
]
.filter(Boolean)
@@ -260,10 +260,10 @@ export function createPanel({ state: layerState, services, parts, source }) {
? launch.launchSite
: t('UNAVAILABLE'));
const position = endpoint
? `${endpoint.lat.toFixed(2)}, ${endpoint.lon.toFixed(2)} · ${accuracyLabel(endpoint.accuracy)}`
? `${isolate(`${endpoint.lat.toFixed(2)}, ${endpoint.lon.toFixed(2)}`)} · ${accuracyLabel(endpoint.accuracy)}`
: stage.downrangeKm > 0
? t('{value} KM DOWNRANGE', {
value: stage.downrangeKm.toLocaleString(),
value: formatNumber(stage.downrangeKm),
})
: t('POSITION UNAVAILABLE');
const stageDetail = [
@@ -394,7 +394,7 @@ export function createPanel({ state: layerState, services, parts, source }) {
'[data-mission-distance]',
Number.isFinite(altitudeM)
? t('{value} KM', {
value: Math.max(0, altitudeM / 1000).toLocaleString(undefined, {
value: formatNumber(Math.max(0, altitudeM / 1000), {
maximumFractionDigits: 0,
}),
})
@@ -407,14 +407,14 @@ export function createPanel({ state: layerState, services, parts, source }) {
'[data-mission-speed]',
Number.isFinite(speedMps)
? t('{value} KM/S', {
value: (speedMps / 1000).toLocaleString(undefined, {
value: formatNumber(speedMps / 1000, {
minimumFractionDigits: 2,
maximumFractionDigits: 2,
}),
})
: null,
Number.isFinite(speedMps)
? `${(speedMps * 3.6).toLocaleString(undefined, { maximumFractionDigits: 0 })} km/h`
? `${formatNumber(speedMps * 3.6, { maximumFractionDigits: 0 })} km/h`
: '',
);
}