mirror of
https://github.com/bilawalsidhu/gods-eye-view.git
synced 2026-11-05 19:04:02 +00:00
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:
1 parent
9f1e409193
commit
7db0abc396
16 files changed
+407
-111
No files matched your search
+29
-1
@@ -4,6 +4,10 @@
|
||||
// npm run i18n -- --prune also drop entries the code no longer uses
|
||||
// npm run i18n -- --missing ru print what ru lacks, as JSON to translate
|
||||
//
|
||||
// A translation identical to the English is reported too, unless it is
|
||||
// listed for that locale in src/i18n/same-as-english.json (codes, product
|
||||
// names, words spelled the same in both languages).
|
||||
//
|
||||
// Messages are the English literals passed to t(), tn() and msg() in src/,
|
||||
// plus the markup opted in with data-i18n* in src/ui/templates and index.html.
|
||||
// It also lists UI text that is not marked at all (see findUnmarked).
|
||||
@@ -14,6 +18,7 @@ import { fileURLToPath } from 'node:url';
|
||||
|
||||
const ROOT = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..');
|
||||
const LOCALES_DIR = path.join(ROOT, 'src/i18n/locales');
|
||||
const SAME_AS_ENGLISH = path.join(ROOT, 'src/i18n/same-as-english.json');
|
||||
|
||||
const STRING = String.raw`'(?:\\.|[^'\\\n])*'|"(?:\\.|[^"\\\n])*"|\`(?:\\.|[^\`\\$])*\``;
|
||||
const CALL = new RegExp(
|
||||
@@ -424,11 +429,26 @@ export function shippedLocales() {
|
||||
);
|
||||
}
|
||||
|
||||
/** Messages a locale keeps exactly as in English, on purpose. */
|
||||
export function readSameAsEnglish(locale) {
|
||||
const lists = JSON.parse(readFileSync(SAME_AS_ENGLISH, 'utf8'));
|
||||
return new Set(lists[locale] || []);
|
||||
}
|
||||
|
||||
/** The English a message shows: its text without the "context|" prefix. */
|
||||
const englishOf = (text) => text.slice(text.indexOf('|') + 1);
|
||||
|
||||
/**
|
||||
* Compare one catalog with the extracted messages.
|
||||
* @param {Set<string>} [sameAsEnglish] Messages allowed to read as English.
|
||||
* @returns {{missing: string[], stale: string[], errors: string[]}}
|
||||
*/
|
||||
export function checkCatalog(locale, catalog, messages) {
|
||||
export function checkCatalog(
|
||||
locale,
|
||||
catalog,
|
||||
messages,
|
||||
sameAsEnglish = readSameAsEnglish(locale),
|
||||
) {
|
||||
const categories = new Intl.PluralRules(locale).resolvedOptions()
|
||||
.pluralCategories;
|
||||
const missing = [];
|
||||
@@ -456,6 +476,14 @@ export function checkCatalog(locale, catalog, messages) {
|
||||
errors.push(`"${text}" must be a string`);
|
||||
} else if (placeholders(entry) !== placeholders(text)) {
|
||||
errors.push(`"${text}" placeholders differ: ${entry}`);
|
||||
} else if (
|
||||
entry === englishOf(text) &&
|
||||
/\p{L}{2}/u.test(entry.replace(/\{[^}]*\}/g, '')) &&
|
||||
!sameAsEnglish.has(text)
|
||||
) {
|
||||
errors.push(
|
||||
`"${text}" is still English: translate it, or list it under "${locale}" in src/i18n/same-as-english.json`,
|
||||
);
|
||||
}
|
||||
}
|
||||
const stale = Object.keys(catalog).filter((text) => !messages.has(text));
|
||||
|
||||
Reference in new issue
Block a user