fix(i18n): keep values the AI tools read in English

- Satellite class in analyst records and voice payloads stays English
  ("STATION", "COMMS"), so voice filters on the class work in every
  language; cards and the legend still show the translated label.
- Layer source names (OSM routing, ALPR sources) stay English in layer
  state; the layer row translates them.
- New translateKnown(): catalog text when there is an entry, the given text
  otherwise, with no warning. The layer row uses it for loading labels and
  errors, Recent Imagery for its notices.
- Mark the remaining Recent Imagery and wind messages.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
German KhokhlovandClaude Opus 5.5 committed 2026-10-13 20:09:45 +04:00
1 parent 0c647a791b
commit 2c74057b5e
13 files changed
+60 -20

No files matched your search

+2 -1
View File
@@ -294,7 +294,8 @@ export function createAlprCamerasLayer({ source, services } = {}) {
id: LAYER_ID,
name: 'ALPR Cameras',
icon: '📷',
source: t(source.label || msg('Mapped camera locations')),
// English in layer state; the layer row translates it.
source: source.label || msg('Mapped camera locations'),
updateInterval: 0,
statsRefreshInterval: 1000,
init(viewer) {
+2 -1
View File
@@ -557,7 +557,8 @@ export function directionsStats(state) {
armed,
pointerBlocked,
} = state;
const source = t('OSM routing');
// English in layer state; the layer row translates it.
const source = 'OSM routing'; // i18n-ignore: source name, translated by layerPanel
if (pointerBlocked) {
return {
count: route?.steps.length || 0,
+1 -1
View File
@@ -47,7 +47,7 @@ export const SPLIT_PUBLISH_MS = 400;
/** The three modes, in share-link order (`m` = index). */
export const MODES = Object.freeze(['image', 'basemap', 'ab']);
const COMPARISON_IN_USE = 'Comparison in use by another scene';
const COMPARISON_IN_USE = msg('Comparison in use by another scene');
// Kept English in the snapshot (AI tools read it); the card translates them.
const COMPARISON_UNAVAILABLE = msg('Esri map unavailable · no swipe');
const COMPARISON_NEEDS_GLOBE = msg('Swipe needs a globe map');
+3 -1
View File
@@ -37,7 +37,9 @@ export function mapAnalystRecord(raw) {
// Empty records stay class-less; the class table's fallback is VISUAL and
// must not leak onto a row that has no satellite identity.
satelliteClass:
noradId || group ? satelliteClassLabel(group, { isIss }) : null,
noradId || group
? satelliteClassLabel(group, { isIss, localize: false })
: null,
group,
};
}
+4 -1
View File
@@ -239,7 +239,10 @@ export function createTracking({ state: layerState, services, parts, source }) {
name,
operator: '',
noradId: String(noradId),
class: satelliteClassLabel(sat.group, { isIss: noradId === ISS_NORAD }),
class: satelliteClassLabel(sat.group, {
isIss: noradId === ISS_NORAD,
localize: false,
}),
altitude:
altitudeKm === null ? '' : `${altitudeKm.toLocaleString('en-US')} km`,
},
+2 -1
View File
@@ -65,8 +65,9 @@ export function inspectWindAtCenter(
model,
validTime,
status,
explanation:
explanation: msg(
'A location reading needs a loaded forecast and the Earth at the center of the view.',
),
};
const location = cesium.Cartographic.fromCartesian(point, ellipsoid);
const lon = cesium.Math.toDegrees(location.longitude);