diff --git a/src/i18n/locales/es.json b/src/i18n/locales/es.json index d9d0315e2..7d36002ee 100644 --- a/src/i18n/locales/es.json +++ b/src/i18n/locales/es.json @@ -2779,5 +2779,10 @@ "Show the complete infrared image; 0% filter strength": "Muestra la imagen infrarroja completa; intensidad del filtro 0%", "FILTER": "FILTRO", "Cloud filter strength": "Intensidad del filtro de nubes", - "Panoramax answered HTTP {status}": "Panoramax respondió HTTP {status}" + "Panoramax answered HTTP {status}": "Panoramax respondió HTTP {status}", + "{n} sequences in view · click a line for its nearest photo": { + "one": "{n} secuencia a la vista · haz clic en una línea para su foto más cercana", + "many": "{n} secuencias a la vista · haz clic en una línea para su foto más cercana", + "other": "{n} secuencias a la vista · haz clic en una línea para su foto más cercana" + } } diff --git a/src/i18n/locales/ru.json b/src/i18n/locales/ru.json index ab61f56cc..918edac62 100644 --- a/src/i18n/locales/ru.json +++ b/src/i18n/locales/ru.json @@ -2836,5 +2836,11 @@ "Show the complete infrared image; 0% filter strength": "Показать полное ИК-изображение; сила фильтра 0%", "FILTER": "ФИЛЬТР", "Cloud filter strength": "Сила фильтра облаков", - "Panoramax answered HTTP {status}": "Panoramax ответил: HTTP {status}" + "Panoramax answered HTTP {status}": "Panoramax ответил: HTTP {status}", + "{n} sequences in view · click a line for its nearest photo": { + "one": "{n} съёмка в кадре · щёлкните линию, чтобы открыть ближайшую фотографию", + "few": "{n} съёмки в кадре · щёлкните линию, чтобы открыть ближайшую фотографию", + "many": "{n} съёмок в кадре · щёлкните линию, чтобы открыть ближайшую фотографию", + "other": "{n} съёмки в кадре · щёлкните линию, чтобы открыть ближайшую фотографию" + } } diff --git a/src/ui/streetLevelPresentation.js b/src/ui/streetLevelPresentation.js index 579452336..0f468edd6 100644 --- a/src/ui/streetLevelPresentation.js +++ b/src/ui/streetLevelPresentation.js @@ -257,29 +257,45 @@ function presentMeta(state) { ); const hint = translateHint(state.coverage.hint); if (state.coverage.count > 0) { - // A provider whose lines are not sequences carries its wording as data - // (coverageLabel); its count line needs its own tn pair so every language - // gets real plural forms. New wording: add a pair here and to the catalogs. - const count = state.coverage.count; - const countLine = - state.coverage.label?.noun === 'streets' - ? tn( - count, - '{n} street in view · click a line for its nearest photo', - '{n} streets in view · click a line for its nearest photo', - { n: formatNumber(count) }, - ) - : tn( - count, - '{n} sequence in view · click a line for its photos', - '{n} sequences in view · click a line for its photos', - { n: formatNumber(count) }, - ); + const countLine = coverageCountLine(state.coverage); return [countLine, hint].filter(Boolean).join(' · '); } return hint; } +/** + * The coverage count line. Providers carry their wording as data + * (coverageLabel noun/action); each combination needs its own literal tn + * pair so every language gets real plural forms — the noun cannot inflect + * through a placeholder in Russian. New wording: add a pair here and to the + * catalogs (es.json/ru.json). + * @param {{count: number, label?: {noun?: string, action?: string}|null}} coverage + */ +function coverageCountLine(coverage) { + const count = coverage.count; + const values = { n: formatNumber(count) }; + if (coverage.label?.action === 'click a line for its nearest photo') + return coverage.label.noun === 'streets' + ? tn( + count, + '{n} street in view · click a line for its nearest photo', + '{n} streets in view · click a line for its nearest photo', + values, + ) + : tn( + count, + '{n} sequence in view · click a line for its nearest photo', + '{n} sequences in view · click a line for its nearest photo', + values, + ); + return tn( + count, + '{n} sequence in view · click a line for its photos', + '{n} sequences in view · click a line for its photos', + values, + ); +} + /** @param {{now?: number}} [options] Clock for the SINCE readout. */ export function presentStreetLevelPanel(state, { now = Date.now() } = {}) { const enabled = state.enabled === true;