fix(i18n): Spanish review fixes; report translations left in English

A screenshot review of the Spanish UI found:

- Text left in English. Catalog entries copied from English (Bloom,
  Cyber, Pin, NEWS, SITE, ON/OFF, RANGE, PITCH, HGT…) and the radio
  music genres, which never went through t(). The genres are translated
  in es and ru now.
- Wording: gender agreement, calques of the English, hints that name
  buttons that do not exist, and one concept worded two ways.
- Layout: the DESACTIVADO pill squeezed layer names until words broke
  mid-word; the scene and camera selects showed one word; a collapsed
  rail title pushed its button out of the card; the image slot line and
  a comparison readout were cut or split.

The layout fixes are scoped to languages other than English, so English
stays pixel-identical. Visual-style slider values now use the locale's
decimal separator (0,85).

npm run i18n now reports a translation that is identical to the
English, unless src/i18n/same-as-english.json lists it for that language
(codes, product names, words spelled the same).

Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
German KhokhlovandClaude Opus 5.5 committed 2026-10-13 21:53:57 +04:00
1 parent 9f1e409193
commit 7db0abc396
16 files changed
+407 -111

No files matched your search

+2 -2
View File
@@ -70,7 +70,7 @@ export function createCategories({
function buildRadioCategories(stations) {
const rows = Array.isArray(stations) ? stations : [];
const categories = [
{ id: 'all', label: t('All') },
{ id: 'all', label: t('All', { context: 'radio tag' }) },
{ id: 'news', label: t('News') },
{ id: 'talk', label: t('Talk') },
{ id: 'weather', label: t('Weather / Emergency') },
@@ -89,7 +89,7 @@ export function createCategories({
for (const [genre, label] of MUSIC_GENRES) {
const id = `genre:${genre}`;
if (rows.some((station) => stationMatchesRadioCategory(station, id))) {
categories.push({ id, label });
categories.push({ id, label: t(label) });
}
}
categories.push({ id: 'other', label: t('Other') });
+29 -25
View File
@@ -62,32 +62,36 @@ export const DEFAULT_RADIO_FILTER = 'all';
export const GLOBAL_RADIO_ALTITUDE_M = 2_000_000;
// Genre labels are marked for i18n extraction; categories.js translates them.
// Kept local so this module stays free of the i18n import.
const msg = (text) => text;
export const MUSIC_GENRES = Object.freeze([
['alternative', 'Alternative'],
['ambient', 'Ambient'],
['blues', 'Blues'],
['classical', 'Classical'],
['country', 'Country'],
['dance', 'Dance'],
['electronic', 'Electronic'],
['folk', 'Folk'],
['funk', 'Funk'],
['hip hop', 'Hip-Hop'],
['house', 'House'],
['indie', 'Indie'],
['jazz', 'Jazz'],
['latin', 'Latin'],
['metal', 'Metal'],
['oldies', 'Oldies'],
['pop', 'Pop'],
['punk', 'Punk'],
['r&b', 'R&B'],
['reggae', 'Reggae'],
['rock', 'Rock'],
['soul', 'Soul'],
['techno', 'Techno'],
['trance', 'Trance'],
['world', 'World'],
['alternative', msg('Alternative')],
['ambient', msg('Ambient')],
['blues', msg('Blues')],
['classical', msg('Classical')],
['country', msg('Country')],
['dance', msg('Dance')],
['electronic', msg('Electronic')],
['folk', msg('Folk')],
['funk', msg('Funk')],
['hip hop', msg('Hip-Hop')],
['house', msg('House')],
['indie', msg('Indie')],
['jazz', msg('Jazz')],
['latin', msg('Latin')],
['metal', msg('Metal')],
['oldies', msg('Oldies')],
['pop', msg('Pop')],
['punk', msg('Punk')],
['r&b', msg('R&B')],
['reggae', msg('Reggae')],
['rock', msg('Rock')],
['soul', msg('Soul')],
['techno', msg('Techno')],
['trance', msg('Trance')],
['world', msg('World')],
]);
export const CATEGORY_MATCHERS = Object.freeze({