i18n: fix review findings and polish ru/es strings

Fixes the 51 P0–P2 findings from the full review of the i18n branch and
the issues found while checking every new string on screen in ru and es.

- Translate errors and statuses that still reached ru/es in English:
  feed and tile errors, provider statuses, the ALPR chip, the traffic
  mode chip, voice plan step labels, fire feed values, receiver bands,
  scene save reasons and the Cesium attribution link.
- Show preset city names in the UI language (src/ui/placeNames.js);
  data and everything sent to the model stay English.
- Share layer names between the layer panel, HUD and voice card
  (src/ui/layerNames.js).
- Keep long ru/es strings whole: voice card error lines, analyst
  titles, the voice tier status, the Nepal evidence button, the ALPR
  retry chip. English layout is unchanged.
- Ask before a language switch drops unsaved work.
- Catalog fixes: glossary terms (пуск, пресет), gender agreement and
  consistent "peticiones" in es, fewer calques in both languages.
- Fix English text that was itself wrong (e.g. "Exit cockpit to fly to
  a weather", raw tool ids in voice plan steps).

Catalogs: es/ru 2535 messages each, complete.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
German KhokhlovandClaude Opus 5.5 committed 2026-10-15 23:49:52 +04:00
1 parent 8029747b7e
commit 00704ddc89
212 files changed
+9871 -909

No files matched your search

+34 -4
View File
@@ -97,6 +97,35 @@ function presentStatus(state) {
: { text: t('OFF'), tone: '', pressed, title };
}
// Provider refusals with a number in them stay English data
// (providers/kartaview/source.js); they go back onto a placeholder here.
const ERROR_PATTERNS = [
[
/^KartaView answered HTTP (\d+)$/,
([, status]) => t('KartaView answered HTTP {status}', { status }),
],
[
/^KartaView refused the request \(code (-?\d+)\)$/,
([, code]) => t('KartaView refused the request (code {code})', { code }),
],
];
/**
* A provider or viewer error in the UI language. Exported for tests.
* @param {string} text English error text from a provider.
* @returns {string}
*/
export function translateStreetLevelError(text) {
if (typeof text !== 'string' || !text) return text;
const known = translateKnown(text);
if (known !== text) return known;
for (const [pattern, format] of ERROR_PATTERNS) {
const match = pattern.exec(text);
if (match) return format(match);
}
return text;
}
/** A chip is lit only while the layer and its provider are both on. */
function presentProviders(state) {
const enabled = state.enabled === true;
@@ -107,11 +136,11 @@ function presentProviders(state) {
? t('{name} imagery on', { name: provider.name })
: t('{name} imagery off', { name: provider.name });
if (provider.keyRejected && provider.error)
title = `${provider.name}: ${translateKnown(provider.error)}`;
title = `${provider.name}: ${translateStreetLevelError(provider.error)}`;
else if (keyRequired && provider.requiresKeyId)
title = `${provider.name}: ${keyRequirementText(provider.requiresKeyId)}`;
else if (provider.error)
title = `${provider.name}: ${translateKnown(provider.error)}`;
title = `${provider.name}: ${translateStreetLevelError(provider.error)}`;
return {
id: provider.id,
label: translateKnown(provider.label),
@@ -262,8 +291,9 @@ export function presentStreetLevelPanel(state, { now = Date.now() } = {}) {
providers: presentProviders(state),
error: keyMissing
? null
: translateKnown(state.street.error || state.coverage.error || '') ||
null,
: translateStreetLevelError(
state.street.error || state.coverage.error || '',
) || null,
filter: { pano: filter.pano, sinceDays: Number(filter.sinceDays) || 0 },
filterControls: {
pano: state.filterControls?.pano !== false,