From 713169a3ebc097350540113d5c4bca88535ec577 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=94=D0=B0=D0=BD=D0=B8=D1=97=D0=BB=20=D0=93=D1=80=D0=B8?= =?UTF-8?q?=D0=B3=D0=BE=D1=80=27=D1=94=D0=B2?= Date: Sat, 14 Jun 2025 05:36:55 +0300 Subject: [PATCH] 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. --- src/js/{languages.js => languages.ts} | 60 ++++----------------------- src/js/mods/mod_interface.js | 39 ++++++++--------- src/js/states/preload.js | 2 +- src/js/translations.js | 21 ++++++++-- 4 files changed, 44 insertions(+), 78 deletions(-) rename src/js/{languages.js => languages.ts} (61%) diff --git a/src/js/languages.js b/src/js/languages.ts similarity index 61% rename from src/js/languages.js rename to src/js/languages.ts index 23762e9f..acd94358 100644 --- a/src/js/languages.js +++ b/src/js/languages.ts @@ -1,35 +1,13 @@ -import ar from "./built-temp/base-ar.json"; -import cz from "./built-temp/base-cz.json"; -import da from "./built-temp/base-da.json"; -import de from "./built-temp/base-de.json"; -import es from "./built-temp/base-es.json"; -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 interface Language { + name: string; + code: string; + region: string; + overrides?: object; +} -/** - * @type {Object} - */ -export const LANGUAGES = { +export const LANGUAGES: Record = { "en": { name: "English", - data: null, code: "en", region: "", }, @@ -37,7 +15,6 @@ export const LANGUAGES = { "zh-CN": { // simplified chinese name: "简体中文", - data: zh_CN, code: "zh", region: "CN", }, @@ -45,7 +22,6 @@ export const LANGUAGES = { "zh-TW": { // traditional chinese name: "繁體中文", - data: zh_TW, code: "zh", region: "TW", }, @@ -53,7 +29,6 @@ export const LANGUAGES = { "ja": { // japanese name: "日本語", - data: ja, code: "ja", region: "", }, @@ -61,7 +36,6 @@ export const LANGUAGES = { "kor": { // korean name: "한국어", - data: kor, code: "ko", region: "", }, @@ -69,7 +43,6 @@ export const LANGUAGES = { "cs": { // czech name: "Čeština", - data: cz, code: "cs", region: "", }, @@ -77,7 +50,6 @@ export const LANGUAGES = { "da": { // danish name: "Dansk", - data: da, code: "da", region: "", }, @@ -85,7 +57,6 @@ export const LANGUAGES = { "de": { // german name: "Deutsch", - data: de, code: "de", region: "", }, @@ -93,7 +64,6 @@ export const LANGUAGES = { "es-419": { // spanish name: "Español", - data: es, code: "es", region: "", }, @@ -101,7 +71,6 @@ export const LANGUAGES = { "fr": { // french name: "Français", - data: fr, code: "fr", region: "", }, @@ -109,7 +78,6 @@ export const LANGUAGES = { "it": { // italian name: "Italiano", - data: it, code: "it", region: "", }, @@ -117,7 +85,6 @@ export const LANGUAGES = { "hu": { // hungarian name: "Magyar", - data: hu, code: "hu", region: "", }, @@ -125,7 +92,6 @@ export const LANGUAGES = { "nl": { // dutch name: "Nederlands", - data: nl, code: "nl", region: "", }, @@ -133,7 +99,6 @@ export const LANGUAGES = { "no": { // norwegian name: "Norsk", - data: no, code: "no", region: "", }, @@ -141,7 +106,6 @@ export const LANGUAGES = { "pl": { // polish name: "Polski", - data: pl, code: "pl", region: "", }, @@ -149,7 +113,6 @@ export const LANGUAGES = { "pt-PT": { // portuguese name: "Português", - data: pt_PT, code: "pt", region: "PT", }, @@ -157,7 +120,6 @@ export const LANGUAGES = { "pt-BR": { // portuguese _ brazil name: "Português - Brasil", - data: pt_BR, code: "pt", region: "BR", }, @@ -165,7 +127,6 @@ export const LANGUAGES = { "ro": { // romanian name: "Română", - data: ro, code: "ro", region: "", }, @@ -173,7 +134,6 @@ export const LANGUAGES = { "ru": { // russian name: "Русский", - data: ru, code: "ru", region: "", }, @@ -181,7 +141,6 @@ export const LANGUAGES = { "fi": { // finish name: "Suomi", - data: fi, code: "fi", region: "", }, @@ -189,7 +148,6 @@ export const LANGUAGES = { "sv": { // swedish name: "Svenska", - data: sv, code: "sv", region: "", }, @@ -197,7 +155,6 @@ export const LANGUAGES = { "tr": { // turkish name: "Türkçe", - data: tr, code: "tr", region: "", }, @@ -205,7 +162,6 @@ export const LANGUAGES = { "uk": { // ukrainian name: "Українська", - data: uk, code: "uk", region: "", }, @@ -213,7 +169,6 @@ export const LANGUAGES = { "he": { // hebrew name: "עברית", - data: he, code: "he", region: "", }, @@ -221,7 +176,6 @@ export const LANGUAGES = { "ar": { // arabic name: "العربية", - data: ar, code: "ar", region: "", }, diff --git a/src/js/mods/mod_interface.js b/src/js/mods/mod_interface.js index 8130dc5a..a63cc9a8 100644 --- a/src/js/mods/mod_interface.js +++ b/src/js/mods/mod_interface.js @@ -1,35 +1,35 @@ /* typehints:start */ -import { ModLoader } from "./modloader"; -import { GameSystem } from "../game/game_system"; import { Component } from "../game/component"; +import { GameSystem } from "../game/game_system"; import { MetaBuilding } from "../game/meta_building"; +import { ModLoader } from "./modloader"; /* 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 { 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 { enumShortcodeToSubShape, enumSubShape, enumSubShapeToShortcode, MODS_ADDITIONAL_SUB_SHAPE_DRAWERS, } from "../game/shape_definition"; -import { Loader } from "../core/loader"; +import { THEMES } from "../game/theme"; import { LANGUAGES } from "../languages"; 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 { 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 @@ -186,10 +186,7 @@ export class ModInterface { throw new Error("Unknown language: " + language); } - matchDataRecursive(data.data, translations, true); - if (language === "en") { - matchDataRecursive(T, translations, true); - } + matchDataRecursive((data.overrides ??= {}), translations, true); } /** diff --git a/src/js/states/preload.js b/src/js/states/preload.js index 9fd27725..56c8f1ca 100644 --- a/src/js/states/preload.js +++ b/src/js/states/preload.js @@ -88,7 +88,7 @@ export class PreloadState extends GameState { .then(() => { const language = this.app.settings.getLanguage(); - updateApplicationLanguage(language); + return updateApplicationLanguage(language); }) .then(() => this.setStatus("Initializing sounds", 30)) diff --git a/src/js/translations.js b/src/js/translations.js index c6630497..9599665e 100644 --- a/src/js/translations.js +++ b/src/js/translations.js @@ -81,6 +81,16 @@ export function autoDetectLanguageId() { 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) { if (typeof dest !== "object" || typeof src !== "object") { 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); const data = LANGUAGES[id]; @@ -123,8 +133,13 @@ export function updateApplicationLanguage(id) { return; } - if (data.data) { + if (id !== "en") { 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); }