1
0
mirror of https://github.com/tobspr/shapez.io.git synced 2025-12-11 09:11:50 +00:00

Ensure proper code splitting for translations

Make updateApplicationLanguage load translations asynchronously as
separate chunks in a slightly hacky way. Also implement a workaround for
old translation overrides registry ModInterface API.
This commit is contained in:
Даниїл Григор'єв 2025-06-14 05:36:55 +03:00
parent 06cfc3d29a
commit 713169a3eb
No known key found for this signature in database
GPG Key ID: B890DF16341D8C1D
4 changed files with 44 additions and 78 deletions

View File

@ -1,35 +1,13 @@
import ar from "./built-temp/base-ar.json"; export interface Language {
import cz from "./built-temp/base-cz.json"; name: string;
import da from "./built-temp/base-da.json"; code: string;
import de from "./built-temp/base-de.json"; region: string;
import es from "./built-temp/base-es.json"; overrides?: object;
import fi from "./built-temp/base-fi.json"; }
import fr from "./built-temp/base-fr.json";
import he from "./built-temp/base-he.json";
import hu from "./built-temp/base-hu.json";
import it from "./built-temp/base-it.json";
import ja from "./built-temp/base-ja.json";
import kor from "./built-temp/base-kor.json";
import nl from "./built-temp/base-nl.json";
import no from "./built-temp/base-no.json";
import pl from "./built-temp/base-pl.json";
import pt_BR from "./built-temp/base-pt-BR.json";
import pt_PT from "./built-temp/base-pt-PT.json";
import ro from "./built-temp/base-ro.json";
import ru from "./built-temp/base-ru.json";
import sv from "./built-temp/base-sv.json";
import tr from "./built-temp/base-tr.json";
import uk from "./built-temp/base-uk.json";
import zh_CN from "./built-temp/base-zh-CN.json";
import zh_TW from "./built-temp/base-zh-TW.json";
/** export const LANGUAGES: Record<string, Language> = {
* @type {Object<string, {name: string, data: any, code: string, region: string}>}
*/
export const LANGUAGES = {
"en": { "en": {
name: "English", name: "English",
data: null,
code: "en", code: "en",
region: "", region: "",
}, },
@ -37,7 +15,6 @@ export const LANGUAGES = {
"zh-CN": { "zh-CN": {
// simplified chinese // simplified chinese
name: "简体中文", name: "简体中文",
data: zh_CN,
code: "zh", code: "zh",
region: "CN", region: "CN",
}, },
@ -45,7 +22,6 @@ export const LANGUAGES = {
"zh-TW": { "zh-TW": {
// traditional chinese // traditional chinese
name: "繁體中文", name: "繁體中文",
data: zh_TW,
code: "zh", code: "zh",
region: "TW", region: "TW",
}, },
@ -53,7 +29,6 @@ export const LANGUAGES = {
"ja": { "ja": {
// japanese // japanese
name: "日本語", name: "日本語",
data: ja,
code: "ja", code: "ja",
region: "", region: "",
}, },
@ -61,7 +36,6 @@ export const LANGUAGES = {
"kor": { "kor": {
// korean // korean
name: "한국어", name: "한국어",
data: kor,
code: "ko", code: "ko",
region: "", region: "",
}, },
@ -69,7 +43,6 @@ export const LANGUAGES = {
"cs": { "cs": {
// czech // czech
name: "Čeština", name: "Čeština",
data: cz,
code: "cs", code: "cs",
region: "", region: "",
}, },
@ -77,7 +50,6 @@ export const LANGUAGES = {
"da": { "da": {
// danish // danish
name: "Dansk", name: "Dansk",
data: da,
code: "da", code: "da",
region: "", region: "",
}, },
@ -85,7 +57,6 @@ export const LANGUAGES = {
"de": { "de": {
// german // german
name: "Deutsch", name: "Deutsch",
data: de,
code: "de", code: "de",
region: "", region: "",
}, },
@ -93,7 +64,6 @@ export const LANGUAGES = {
"es-419": { "es-419": {
// spanish // spanish
name: "Español", name: "Español",
data: es,
code: "es", code: "es",
region: "", region: "",
}, },
@ -101,7 +71,6 @@ export const LANGUAGES = {
"fr": { "fr": {
// french // french
name: "Français", name: "Français",
data: fr,
code: "fr", code: "fr",
region: "", region: "",
}, },
@ -109,7 +78,6 @@ export const LANGUAGES = {
"it": { "it": {
// italian // italian
name: "Italiano", name: "Italiano",
data: it,
code: "it", code: "it",
region: "", region: "",
}, },
@ -117,7 +85,6 @@ export const LANGUAGES = {
"hu": { "hu": {
// hungarian // hungarian
name: "Magyar", name: "Magyar",
data: hu,
code: "hu", code: "hu",
region: "", region: "",
}, },
@ -125,7 +92,6 @@ export const LANGUAGES = {
"nl": { "nl": {
// dutch // dutch
name: "Nederlands", name: "Nederlands",
data: nl,
code: "nl", code: "nl",
region: "", region: "",
}, },
@ -133,7 +99,6 @@ export const LANGUAGES = {
"no": { "no": {
// norwegian // norwegian
name: "Norsk", name: "Norsk",
data: no,
code: "no", code: "no",
region: "", region: "",
}, },
@ -141,7 +106,6 @@ export const LANGUAGES = {
"pl": { "pl": {
// polish // polish
name: "Polski", name: "Polski",
data: pl,
code: "pl", code: "pl",
region: "", region: "",
}, },
@ -149,7 +113,6 @@ export const LANGUAGES = {
"pt-PT": { "pt-PT": {
// portuguese // portuguese
name: "Português", name: "Português",
data: pt_PT,
code: "pt", code: "pt",
region: "PT", region: "PT",
}, },
@ -157,7 +120,6 @@ export const LANGUAGES = {
"pt-BR": { "pt-BR": {
// portuguese _ brazil // portuguese _ brazil
name: "Português - Brasil", name: "Português - Brasil",
data: pt_BR,
code: "pt", code: "pt",
region: "BR", region: "BR",
}, },
@ -165,7 +127,6 @@ export const LANGUAGES = {
"ro": { "ro": {
// romanian // romanian
name: "Română", name: "Română",
data: ro,
code: "ro", code: "ro",
region: "", region: "",
}, },
@ -173,7 +134,6 @@ export const LANGUAGES = {
"ru": { "ru": {
// russian // russian
name: "Русский", name: "Русский",
data: ru,
code: "ru", code: "ru",
region: "", region: "",
}, },
@ -181,7 +141,6 @@ export const LANGUAGES = {
"fi": { "fi": {
// finish // finish
name: "Suomi", name: "Suomi",
data: fi,
code: "fi", code: "fi",
region: "", region: "",
}, },
@ -189,7 +148,6 @@ export const LANGUAGES = {
"sv": { "sv": {
// swedish // swedish
name: "Svenska", name: "Svenska",
data: sv,
code: "sv", code: "sv",
region: "", region: "",
}, },
@ -197,7 +155,6 @@ export const LANGUAGES = {
"tr": { "tr": {
// turkish // turkish
name: "Türkçe", name: "Türkçe",
data: tr,
code: "tr", code: "tr",
region: "", region: "",
}, },
@ -205,7 +162,6 @@ export const LANGUAGES = {
"uk": { "uk": {
// ukrainian // ukrainian
name: "Українська", name: "Українська",
data: uk,
code: "uk", code: "uk",
region: "", region: "",
}, },
@ -213,7 +169,6 @@ export const LANGUAGES = {
"he": { "he": {
// hebrew // hebrew
name: "עברית", name: "עברית",
data: he,
code: "he", code: "he",
region: "", region: "",
}, },
@ -221,7 +176,6 @@ export const LANGUAGES = {
"ar": { "ar": {
// arabic // arabic
name: "العربية", name: "العربية",
data: ar,
code: "ar", code: "ar",
region: "", region: "",
}, },

View File

@ -1,35 +1,35 @@
/* typehints:start */ /* typehints:start */
import { ModLoader } from "./modloader";
import { GameSystem } from "../game/game_system";
import { Component } from "../game/component"; import { Component } from "../game/component";
import { GameSystem } from "../game/game_system";
import { MetaBuilding } from "../game/meta_building"; import { MetaBuilding } from "../game/meta_building";
import { ModLoader } from "./modloader";
/* typehints:end */ /* typehints:end */
import { defaultBuildingVariant } from "../game/meta_building"; import { gComponentRegistry, gItemRegistry, gMetaBuildingRegistry } from "../core/global_registries";
import { Loader } from "../core/loader";
import { AtlasSprite, SpriteAtlasLink } from "../core/sprites"; import { AtlasSprite, SpriteAtlasLink } from "../core/sprites";
import { Vector } from "../core/vector";
import { BaseItem } from "../game/base_item";
import { gBuildingVariants, registerBuildingVariant } from "../game/building_codes";
import { MODS_ADDITIONAL_SYSTEMS } from "../game/game_system_manager";
import { BaseHUDPart } from "../game/hud/base_hud_part";
import { HUDModalDialogs } from "../game/hud/parts/modal_dialogs";
import { MODS_ADDITIONAL_ITEMS } from "../game/item_resolver";
import { KEYMAPPINGS } from "../game/key_action_mapper";
import { MODS_ADDITIONAL_SHAPE_MAP_WEIGHTS } from "../game/map_chunk";
import { MOD_CHUNK_DRAW_HOOKS } from "../game/map_chunk_view";
import { defaultBuildingVariant } from "../game/meta_building";
import { GameRoot } from "../game/root";
import { import {
enumShortcodeToSubShape, enumShortcodeToSubShape,
enumSubShape, enumSubShape,
enumSubShapeToShortcode, enumSubShapeToShortcode,
MODS_ADDITIONAL_SUB_SHAPE_DRAWERS, MODS_ADDITIONAL_SUB_SHAPE_DRAWERS,
} from "../game/shape_definition"; } from "../game/shape_definition";
import { Loader } from "../core/loader"; import { THEMES } from "../game/theme";
import { LANGUAGES } from "../languages"; import { LANGUAGES } from "../languages";
import { matchDataRecursive, T } from "../translations"; import { matchDataRecursive, T } from "../translations";
import { gBuildingVariants, registerBuildingVariant } from "../game/building_codes";
import { gComponentRegistry, gItemRegistry, gMetaBuildingRegistry } from "../core/global_registries";
import { MODS_ADDITIONAL_SHAPE_MAP_WEIGHTS } from "../game/map_chunk";
import { MODS_ADDITIONAL_SYSTEMS } from "../game/game_system_manager";
import { MOD_CHUNK_DRAW_HOOKS } from "../game/map_chunk_view";
import { KEYMAPPINGS } from "../game/key_action_mapper";
import { HUDModalDialogs } from "../game/hud/parts/modal_dialogs";
import { THEMES } from "../game/theme";
import { ModMetaBuilding } from "./mod_meta_building"; import { ModMetaBuilding } from "./mod_meta_building";
import { BaseHUDPart } from "../game/hud/base_hud_part";
import { Vector } from "../core/vector";
import { GameRoot } from "../game/root";
import { BaseItem } from "../game/base_item";
import { MODS_ADDITIONAL_ITEMS } from "../game/item_resolver";
/** /**
* @typedef {{new(...args: any[]): any, prototype: any}} constructable * @typedef {{new(...args: any[]): any, prototype: any}} constructable
@ -186,10 +186,7 @@ export class ModInterface {
throw new Error("Unknown language: " + language); throw new Error("Unknown language: " + language);
} }
matchDataRecursive(data.data, translations, true); matchDataRecursive((data.overrides ??= {}), translations, true);
if (language === "en") {
matchDataRecursive(T, translations, true);
}
} }
/** /**

View File

@ -88,7 +88,7 @@ export class PreloadState extends GameState {
.then(() => { .then(() => {
const language = this.app.settings.getLanguage(); const language = this.app.settings.getLanguage();
updateApplicationLanguage(language); return updateApplicationLanguage(language);
}) })
.then(() => this.setStatus("Initializing sounds", 30)) .then(() => this.setStatus("Initializing sounds", 30))

View File

@ -81,6 +81,16 @@ export function autoDetectLanguageId() {
return "en"; return "en";
} }
/**
* Loads translation data for the specified language
* @param {string} code
* @param {string | ""} region
*/
export async function loadTranslationData(code, region) {
const locale = code + (region === "" ? "" : `-${region}`);
return (await import(`./built-temp/base-${locale}.json`)).default;
}
export function matchDataRecursive(dest, src, addNewKeys = false) { export function matchDataRecursive(dest, src, addNewKeys = false) {
if (typeof dest !== "object" || typeof src !== "object") { if (typeof dest !== "object" || typeof src !== "object") {
return; return;
@ -113,7 +123,7 @@ export function matchDataRecursive(dest, src, addNewKeys = false) {
} }
} }
export function updateApplicationLanguage(id) { export async function updateApplicationLanguage(id) {
logger.log("Setting application language:", id); logger.log("Setting application language:", id);
const data = LANGUAGES[id]; const data = LANGUAGES[id];
@ -123,8 +133,13 @@ export function updateApplicationLanguage(id) {
return; return;
} }
if (data.data) { if (id !== "en") {
logger.log("Applying translations ..."); logger.log("Applying translations ...");
matchDataRecursive(T, data.data); const translations = await loadTranslationData(data.code, data.region);
matchDataRecursive(T, translations);
} }
// Translation overrides are used by mods
matchDataRecursive(T, data.overrides, true);
} }