mirror of
https://github.com/tobspr/shapez.io.git
synced 2025-06-13 13:04:03 +00:00
Merge e801bab0be
into 93f9d7ae23
This commit is contained in:
commit
b0ddc754bc
@ -94,6 +94,7 @@
|
||||
"sass-unused": "^0.3.0",
|
||||
"strip-json-comments": "^3.0.1",
|
||||
"trim": "^0.0.1",
|
||||
"yaml-loader": "^0.6.0",
|
||||
"yarn": "^1.22.4"
|
||||
}
|
||||
}
|
||||
|
@ -1,113 +0,0 @@
|
||||
/**
|
||||
* @type {Object<string, {name: string, data: any, code: string, region: string}>}
|
||||
*/
|
||||
export const LANGUAGES = {
|
||||
"en": {
|
||||
name: "English",
|
||||
data: null,
|
||||
code: "en",
|
||||
region: "",
|
||||
},
|
||||
"de": {
|
||||
name: "Deutsch",
|
||||
data: require("./built-temp/base-de.json"),
|
||||
code: "de",
|
||||
region: "",
|
||||
},
|
||||
"fr": {
|
||||
name: "Français",
|
||||
data: require("./built-temp/base-fr.json"),
|
||||
code: "fr",
|
||||
region: "",
|
||||
},
|
||||
"ja": {
|
||||
name: "日本語",
|
||||
data: require("./built-temp/base-ja.json"),
|
||||
code: "ja",
|
||||
region: "",
|
||||
},
|
||||
"pt-PT": {
|
||||
name: "Português (Portugal)",
|
||||
data: require("./built-temp/base-pt-PT.json"),
|
||||
code: "pt",
|
||||
region: "PT",
|
||||
},
|
||||
"pt-BR": {
|
||||
name: "Português (Brasil)",
|
||||
data: require("./built-temp/base-pt-BR.json"),
|
||||
code: "pt",
|
||||
region: "BR",
|
||||
},
|
||||
"ru": {
|
||||
name: "Русский",
|
||||
data: require("./built-temp/base-ru.json"),
|
||||
code: "ru",
|
||||
region: "",
|
||||
},
|
||||
"cs": {
|
||||
name: "Čeština",
|
||||
data: require("./built-temp/base-cz.json"),
|
||||
code: "cs",
|
||||
region: "",
|
||||
},
|
||||
"es-419": {
|
||||
name: "Español",
|
||||
data: require("./built-temp/base-es.json"),
|
||||
code: "es",
|
||||
region: "",
|
||||
},
|
||||
"pl": {
|
||||
name: "Polski",
|
||||
data: require("./built-temp/base-pl.json"),
|
||||
code: "pl",
|
||||
region: "",
|
||||
},
|
||||
"kor": {
|
||||
name: "한국어",
|
||||
data: require("./built-temp/base-kor.json"),
|
||||
code: "kor",
|
||||
region: "",
|
||||
},
|
||||
"nl": {
|
||||
name: "Nederlands",
|
||||
data: require("./built-temp/base-nl.json"),
|
||||
code: "nl",
|
||||
region: "",
|
||||
},
|
||||
"no": {
|
||||
name: "Norsk",
|
||||
data: require("./built-temp/base-no.json"),
|
||||
code: "no",
|
||||
region: "",
|
||||
},
|
||||
|
||||
"tr": {
|
||||
name: "Türkçe",
|
||||
data: require("./built-temp/base-tr.json"),
|
||||
code: "tr",
|
||||
region: "",
|
||||
},
|
||||
|
||||
"zh-CN": {
|
||||
// simplified
|
||||
name: "中文简体",
|
||||
data: require("./built-temp/base-zh-CN.json"),
|
||||
code: "zh",
|
||||
region: "CN",
|
||||
},
|
||||
|
||||
"zh-TW": {
|
||||
// traditional
|
||||
name: "中文繁體",
|
||||
data: require("./built-temp/base-zh-TW.json"),
|
||||
code: "zh",
|
||||
region: "TW",
|
||||
},
|
||||
|
||||
"sv": {
|
||||
name: "Svenska",
|
||||
data: require("./built-temp/base-sv.json"),
|
||||
code: "sv",
|
||||
region: "",
|
||||
},
|
||||
};
|
@ -6,10 +6,14 @@ import { ReadWriteProxy } from "../core/read_write_proxy";
|
||||
import { BoolSetting, EnumSetting, BaseSetting } from "./setting_types";
|
||||
import { createLogger } from "../core/logging";
|
||||
import { ExplainedResult } from "../core/explained_result";
|
||||
import { THEMES, THEME, applyGameTheme } from "../game/theme";
|
||||
import { THEMES, applyGameTheme } from "../game/theme";
|
||||
import { IS_DEMO } from "../core/config";
|
||||
import { T } from "../translations";
|
||||
import { LANGUAGES } from "../languages";
|
||||
import languageMap, { isLanguageTag, languageTags } from "../translations/languages";
|
||||
|
||||
/**
|
||||
* @typedef {import("../translations/languages").LanguageTag} LanguageTag
|
||||
**/
|
||||
|
||||
const logger = createLogger("application_settings");
|
||||
|
||||
@ -126,9 +130,9 @@ export const autosaveIntervals = [
|
||||
/** @type {Array<BaseSetting>} */
|
||||
export const allApplicationSettings = [
|
||||
new EnumSetting("language", {
|
||||
options: Object.keys(LANGUAGES),
|
||||
valueGetter: key => key,
|
||||
textGetter: key => LANGUAGES[key].name,
|
||||
options: languageTags,
|
||||
valueGetter: languageTag => languageTag,
|
||||
textGetter: languageTag => languageMap[languageTag].name,
|
||||
category: enumCategories.general,
|
||||
restartRequired: true,
|
||||
changeCb: (app, id) => null,
|
||||
@ -279,6 +283,7 @@ class SettingsStorage {
|
||||
this.refreshRate = "60";
|
||||
this.scrollWheelSensitivity = "regular";
|
||||
this.movementSpeed = "regular";
|
||||
/** @type {LanguageTag | "auto-detect"} **/
|
||||
this.language = "auto-detect";
|
||||
this.autosaveInterval = "two_minutes";
|
||||
|
||||
@ -413,10 +418,12 @@ export class ApplicationSettings extends ReadWriteProxy {
|
||||
}
|
||||
|
||||
// Setters
|
||||
|
||||
updateLanguage(id) {
|
||||
assert(LANGUAGES[id], "Language not known: " + id);
|
||||
return this.updateSetting("language", id);
|
||||
/**
|
||||
* @param {LanguageTag} languageTag
|
||||
**/
|
||||
updateLanguage(languageTag) {
|
||||
assert(isLanguageTag(languageTag), "Language not known: " + languageTag);
|
||||
return this.updateSetting("language", languageTag);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { BaseSavegameInterface } from "../savegame_interface.js";
|
||||
import { BaseSavegameInterface } from "../savegame_interface";
|
||||
|
||||
const schema = require("./1000.json");
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { SavegameInterface_V1000 } from "./1000.js";
|
||||
import { createLogger } from "../../core/logging.js";
|
||||
import { T } from "../../translations.js";
|
||||
import { TypeVector, TypeNumber, TypeString, TypeNullable } from "../serialization_data_types.js";
|
||||
import { SavegameInterface_V1000 } from "./1000";
|
||||
import { createLogger } from "../../core/logging";
|
||||
import { T } from "../../translations";
|
||||
import { TypeVector, TypeNumber } from "../serialization_data_types";
|
||||
|
||||
const schema = require("./1001.json");
|
||||
|
||||
|
@ -1,6 +1,5 @@
|
||||
import { createLogger } from "../../core/logging.js";
|
||||
import { T } from "../../translations.js";
|
||||
import { SavegameInterface_V1001 } from "./1001.js";
|
||||
import { createLogger } from "../../core/logging";
|
||||
import { SavegameInterface_V1001 } from "./1001";
|
||||
|
||||
const schema = require("./1002.json");
|
||||
const logger = createLogger("savegame_interface/1002");
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { createLogger } from "../../core/logging.js";
|
||||
import { SavegameInterface_V1002 } from "./1002.js";
|
||||
import { createLogger } from "../../core/logging";
|
||||
import { SavegameInterface_V1002 } from "./1002";
|
||||
|
||||
const schema = require("./1003.json");
|
||||
const logger = createLogger("savegame_interface/1003");
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { createLogger } from "../../core/logging.js";
|
||||
import { SavegameInterface_V1003 } from "./1003.js";
|
||||
import { createLogger } from "../../core/logging";
|
||||
import { SavegameInterface_V1003 } from "./1003";
|
||||
|
||||
const schema = require("./1004.json");
|
||||
const logger = createLogger("savegame_interface/1004");
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { createLogger } from "../../core/logging.js";
|
||||
import { SavegameInterface_V1004 } from "./1004.js";
|
||||
import { createLogger } from "../../core/logging";
|
||||
import { SavegameInterface_V1004 } from "./1004";
|
||||
|
||||
const schema = require("./1005.json");
|
||||
const logger = createLogger("savegame_interface/1005");
|
||||
|
@ -4,6 +4,7 @@ import { findNiceValue } from "../core/utils";
|
||||
import { cachebust } from "../core/cachebust";
|
||||
import { PlatformWrapperImplBrowser } from "../platform/browser/wrapper";
|
||||
import { T, autoDetectLanguageId, updateApplicationLanguage } from "../translations";
|
||||
import { isLanguageTag } from "../translations/languages";
|
||||
import { HUDModalDialogs } from "../game/hud/parts/modal_dialogs";
|
||||
import { CHANGELOG } from "../changelog";
|
||||
import { globalConfig } from "../core/config";
|
||||
@ -125,7 +126,9 @@ export class PreloadState extends GameState {
|
||||
})
|
||||
.then(() => {
|
||||
const language = this.app.settings.getLanguage();
|
||||
if (isLanguageTag(language)) {
|
||||
updateApplicationLanguage(language);
|
||||
}
|
||||
})
|
||||
|
||||
.then(() => this.setStatus("Initializing sounds"))
|
||||
|
@ -1,135 +0,0 @@
|
||||
import { globalConfig } from "./core/config";
|
||||
import { createLogger } from "./core/logging";
|
||||
import { LANGUAGES } from "./languages";
|
||||
|
||||
const logger = createLogger("translations");
|
||||
|
||||
// @ts-ignore
|
||||
const baseTranslations = require("./built-temp/base-en.json");
|
||||
|
||||
export let T = baseTranslations;
|
||||
|
||||
if (G_IS_DEV && globalConfig.debug.testTranslations) {
|
||||
// Replaces all translations by fake translations to see whats translated and what not
|
||||
const mapTranslations = obj => {
|
||||
for (const key in obj) {
|
||||
const value = obj[key];
|
||||
if (typeof value === "string") {
|
||||
obj[key] = value.replace(/[a-z]/gi, "x");
|
||||
} else {
|
||||
mapTranslations(value);
|
||||
}
|
||||
}
|
||||
};
|
||||
mapTranslations(T);
|
||||
}
|
||||
|
||||
export function applyLanguage(languageCode) {
|
||||
logger.log("Applying language:", languageCode);
|
||||
const data = LANGUAGES[languageCode];
|
||||
if (!data) {
|
||||
logger.error("Language not found:", languageCode);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Language key is something like de-DE or en or en-US
|
||||
function mapLanguageCodeToId(languageKey) {
|
||||
const key = languageKey.toLowerCase();
|
||||
const shortKey = key.split("-")[0];
|
||||
|
||||
// Try to match by key or short key
|
||||
for (const id in LANGUAGES) {
|
||||
const data = LANGUAGES[id];
|
||||
const code = data.code.toLowerCase();
|
||||
if (code === key) {
|
||||
console.log("-> Match", languageKey, "->", id);
|
||||
return id;
|
||||
}
|
||||
if (code === shortKey) {
|
||||
console.log("-> Match by short key", languageKey, "->", id);
|
||||
return id;
|
||||
}
|
||||
}
|
||||
|
||||
// If none found, try to find a better alternative by using the base language at least
|
||||
for (const id in LANGUAGES) {
|
||||
const data = LANGUAGES[id];
|
||||
const code = data.code.toLowerCase();
|
||||
const shortCode = code.split("-")[0];
|
||||
|
||||
if (shortCode === key) {
|
||||
console.log("-> Desperate Match", languageKey, "->", id);
|
||||
return id;
|
||||
}
|
||||
if (shortCode === shortKey) {
|
||||
console.log("-> Desperate Match by short key", languageKey, "->", id);
|
||||
return id;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tries to auto-detect a language
|
||||
* @returns {string}
|
||||
*/
|
||||
export function autoDetectLanguageId() {
|
||||
let languages = [];
|
||||
if (navigator.languages) {
|
||||
languages = navigator.languages.slice();
|
||||
} else if (navigator.language) {
|
||||
languages = [navigator.language];
|
||||
} else {
|
||||
logger.warn("Navigator has no languages prop");
|
||||
}
|
||||
|
||||
for (let i = 0; i < languages.length; ++i) {
|
||||
logger.log("Trying to find language target for", languages[i]);
|
||||
const trans = mapLanguageCodeToId(languages[i]);
|
||||
if (trans) {
|
||||
return trans;
|
||||
}
|
||||
}
|
||||
|
||||
// Fallback
|
||||
return "en";
|
||||
}
|
||||
|
||||
function matchDataRecursive(dest, src) {
|
||||
if (typeof dest !== "object" || typeof src !== "object") {
|
||||
return;
|
||||
}
|
||||
|
||||
for (const key in dest) {
|
||||
if (src[key]) {
|
||||
// console.log("copy", key);
|
||||
const data = dest[key];
|
||||
if (typeof data === "object") {
|
||||
matchDataRecursive(dest[key], src[key]);
|
||||
} else if (typeof data === "string" || typeof data === "number") {
|
||||
// console.log("match string", key);
|
||||
dest[key] = src[key];
|
||||
} else {
|
||||
logger.log("Unknown type:", typeof data, "in key", key);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export function updateApplicationLanguage(id) {
|
||||
logger.log("Setting application language:", id);
|
||||
|
||||
const data = LANGUAGES[id];
|
||||
|
||||
if (!data) {
|
||||
logger.error("Unknown language:", id);
|
||||
return;
|
||||
}
|
||||
|
||||
if (data.data) {
|
||||
logger.log("Applying translations ...");
|
||||
matchDataRecursive(T, data.data);
|
||||
}
|
||||
}
|
115
src/js/translations/index.js
Normal file
115
src/js/translations/index.js
Normal file
@ -0,0 +1,115 @@
|
||||
import { globalConfig } from "../core/config";
|
||||
import { createLogger } from "../core/logging";
|
||||
import languageMap, { isLanguageTag, languageTags } from "./languages";
|
||||
|
||||
/**
|
||||
* @typedef {import("./languages").LanguageTag} LanguageTag
|
||||
**/
|
||||
|
||||
const logger = createLogger("translations");
|
||||
|
||||
export const T = languageMap.en.data;
|
||||
|
||||
if (G_IS_DEV && globalConfig.debug.testTranslations) {
|
||||
// Replaces all translations by fake translations to see whats translated and what not
|
||||
const mapTranslations = obj => {
|
||||
for (const key in obj) {
|
||||
const value = obj[key];
|
||||
if (typeof value === "string") {
|
||||
obj[key] = value.replace(/[a-z]/gi, "x");
|
||||
} else {
|
||||
mapTranslations(value);
|
||||
}
|
||||
}
|
||||
};
|
||||
mapTranslations(T);
|
||||
}
|
||||
|
||||
/** tag should be a language code, like de-DE or en or en-US
|
||||
* @param {string} tag
|
||||
* @returns {LanguageTag | null}
|
||||
**/
|
||||
function mapLanguageCodeToId(tag) {
|
||||
if (isLanguageTag(tag)) {
|
||||
return tag;
|
||||
}
|
||||
|
||||
const [code] = tag.split("-");
|
||||
|
||||
// Try to match by tag or code
|
||||
for (const languageTag of languageTags) {
|
||||
const { code: c } = languageMap[languageTag];
|
||||
if (tag === c) {
|
||||
console.log("-> Match", tag, "->", languageTag);
|
||||
return languageTag;
|
||||
}
|
||||
if (code === c) {
|
||||
console.log("-> Match by short key", tag, "->", languageTag);
|
||||
return languageTag;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tries to auto-detect a language
|
||||
* @returns {LanguageTag}
|
||||
*/
|
||||
export function autoDetectLanguageId() {
|
||||
let languages = [];
|
||||
if (navigator.languages) {
|
||||
languages = navigator.languages.slice();
|
||||
} else if (navigator.language) {
|
||||
languages = [navigator.language];
|
||||
} else {
|
||||
logger.warn("Navigator has no languages prop");
|
||||
}
|
||||
|
||||
for (let i = 0; i < languages.length; ++i) {
|
||||
logger.log("Trying to find language target for", languages[i]);
|
||||
const trans = mapLanguageCodeToId(languages[i]);
|
||||
if (trans) {
|
||||
return trans;
|
||||
}
|
||||
}
|
||||
|
||||
// Fallback
|
||||
return "en";
|
||||
}
|
||||
|
||||
function matchDataRecursive(dest, src) {
|
||||
if (typeof dest !== "object" || typeof src !== "object") {
|
||||
return;
|
||||
}
|
||||
|
||||
for (const key in dest) {
|
||||
if (src[key]) {
|
||||
const data = dest[key];
|
||||
if (typeof data === "object") {
|
||||
matchDataRecursive(dest[key], src[key]);
|
||||
} else if (typeof data === "string" || typeof data === "number") {
|
||||
dest[key] = src[key];
|
||||
} else {
|
||||
logger.log("Unknown type:", typeof data, "in key", key);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {LanguageTag} languageTag
|
||||
**/
|
||||
export function updateApplicationLanguage(languageTag) {
|
||||
logger.log("Setting application language:", languageTag);
|
||||
|
||||
if (!languageMap.hasOwnProperty(languageTag)) {
|
||||
logger.error("Unknown language:", languageTag);
|
||||
return;
|
||||
}
|
||||
|
||||
const { data } = languageMap[languageTag];
|
||||
|
||||
logger.log("Applying translations ...");
|
||||
matchDataRecursive(T, data);
|
||||
}
|
7
src/js/translations/languages/cs.js
Normal file
7
src/js/translations/languages/cs.js
Normal file
@ -0,0 +1,7 @@
|
||||
import data from "yaml-loader!../../../../translations/base-cs.yaml";
|
||||
|
||||
/** @type {"cs"} **/
|
||||
const code = "cs";
|
||||
const name = "Čeština";
|
||||
|
||||
export default { code, data, name };
|
7
src/js/translations/languages/de.js
Normal file
7
src/js/translations/languages/de.js
Normal file
@ -0,0 +1,7 @@
|
||||
import data from "yaml-loader!../../../../translations/base-de.yaml";
|
||||
|
||||
/** @type {"de"} **/
|
||||
const code = "de";
|
||||
const name = "Deutsch";
|
||||
|
||||
export default { code, data, name };
|
7
src/js/translations/languages/en.js
Normal file
7
src/js/translations/languages/en.js
Normal file
@ -0,0 +1,7 @@
|
||||
import data from "yaml-loader!../../../../translations/base-en.yaml";
|
||||
|
||||
/** @type {"en"} **/
|
||||
const code = "en";
|
||||
const name = "English";
|
||||
|
||||
export default { code, data, name };
|
7
src/js/translations/languages/es-419.js
Normal file
7
src/js/translations/languages/es-419.js
Normal file
@ -0,0 +1,7 @@
|
||||
import data from "yaml-loader!../../../../translations/base-es-419.yaml";
|
||||
|
||||
/** @type {"es"} **/
|
||||
const code = "es";
|
||||
const name = "Español";
|
||||
|
||||
export default { code, data, name };
|
7
src/js/translations/languages/fr.js
Normal file
7
src/js/translations/languages/fr.js
Normal file
@ -0,0 +1,7 @@
|
||||
import data from "yaml-loader!../../../../translations/base-fr.yaml";
|
||||
|
||||
/** @type {"fr"} **/
|
||||
const code = "fr";
|
||||
const name = "Français";
|
||||
|
||||
export default { code, data, name };
|
99
src/js/translations/languages/index.js
Normal file
99
src/js/translations/languages/index.js
Normal file
@ -0,0 +1,99 @@
|
||||
import cs from "./cs";
|
||||
import de from "./de";
|
||||
import en from "./en";
|
||||
import es419 from "./es-419";
|
||||
import fr from "./fr";
|
||||
import ja from "./ja";
|
||||
import kor from "./kor";
|
||||
import nl from "./nl";
|
||||
import no from "./no";
|
||||
import pl from "./pl";
|
||||
import ptPT from "./pt-PT";
|
||||
import ptBR from "./pt-BR";
|
||||
import ru from "./ru";
|
||||
import sv from "./sv";
|
||||
import tr from "./tr";
|
||||
import zhCN from "./zh-CN";
|
||||
import zhTW from "./zh-TW";
|
||||
|
||||
/**
|
||||
* @typedef {"en" | "de" | "fr" | "ja" | "pt-PT" | "pt-BR" | "ru" | "cs" | "es-419" | "pl" | "kor" | "nl" | "no" | "tr" | "zh-CN" | "zh-TW" | "sv"} LanguageTag
|
||||
*/
|
||||
|
||||
/** @type {LanguageTag[]} **/
|
||||
export const languageTags = [
|
||||
"en",
|
||||
"de",
|
||||
"fr",
|
||||
"ja",
|
||||
"pt-PT",
|
||||
"pt-BR",
|
||||
"ru",
|
||||
"cs",
|
||||
"es-419",
|
||||
"pl",
|
||||
"kor",
|
||||
"nl",
|
||||
"no",
|
||||
"tr",
|
||||
"zh-CN",
|
||||
"zh-TW",
|
||||
"sv",
|
||||
];
|
||||
|
||||
/**
|
||||
* @param {unknown} value
|
||||
* @returns {value is LanguageTag}
|
||||
**/
|
||||
export function isLanguageTag(value) {
|
||||
return languageTags.includes(/** @type {LanguageTag} **/ (value));
|
||||
}
|
||||
|
||||
/** @typedef {"en" | "de" | "fr" | "ja" | "pt" | "ru" | "cs" | "es" | "pl" | "kor" | "nl" | "no" | "tr" | "zh" | "sv"} LanguageCode
|
||||
*/
|
||||
|
||||
/** @type {LanguageCode[]} **/
|
||||
const languageCodes = [
|
||||
"en",
|
||||
"de",
|
||||
"fr",
|
||||
"ja",
|
||||
"pt",
|
||||
"ru",
|
||||
"cs",
|
||||
"es",
|
||||
"pl",
|
||||
"kor",
|
||||
"nl",
|
||||
"no",
|
||||
"tr",
|
||||
"zh",
|
||||
"sv",
|
||||
];
|
||||
|
||||
/** @typedef {"PT" | "BR" | "CN" | "TW"} LanguageRegion **/
|
||||
/** @type {LanguageRegion[]} **/
|
||||
const languageRegions = ["PT", "BR", "CN", "TW"];
|
||||
|
||||
/**
|
||||
* @type {Record<LanguageTag, {name: string, data: Translations, code: LanguageCode, region?: LanguageRegion}>}
|
||||
*/
|
||||
export default {
|
||||
cs,
|
||||
de,
|
||||
en,
|
||||
"es-419": es419,
|
||||
fr,
|
||||
ja,
|
||||
kor,
|
||||
nl,
|
||||
no,
|
||||
pl,
|
||||
"pt-BR": ptBR,
|
||||
"pt-PT": ptPT,
|
||||
ru,
|
||||
sv,
|
||||
tr,
|
||||
"zh-CN": zhCN,
|
||||
"zh-TW": zhTW,
|
||||
};
|
7
src/js/translations/languages/ja.js
Normal file
7
src/js/translations/languages/ja.js
Normal file
@ -0,0 +1,7 @@
|
||||
import data from "yaml-loader!../../../../translations/base-ja.yaml";
|
||||
|
||||
/** @type {"ja"} **/
|
||||
const code = "ja";
|
||||
const name = "日本語";
|
||||
|
||||
export default { code, data, name };
|
7
src/js/translations/languages/kor.js
Normal file
7
src/js/translations/languages/kor.js
Normal file
@ -0,0 +1,7 @@
|
||||
import data from "yaml-loader!../../../../translations/base-kor.yaml";
|
||||
|
||||
/** @type {"kor"} **/
|
||||
const code = "kor";
|
||||
const name = "한국어";
|
||||
|
||||
export default { code, data, name };
|
7
src/js/translations/languages/nl.js
Normal file
7
src/js/translations/languages/nl.js
Normal file
@ -0,0 +1,7 @@
|
||||
import data from "yaml-loader!../../../../translations/base-nl.yaml";
|
||||
|
||||
/** @type {"nl"} **/
|
||||
const code = "nl";
|
||||
const name = "Nederlands";
|
||||
|
||||
export default { code, data, name };
|
7
src/js/translations/languages/no.js
Normal file
7
src/js/translations/languages/no.js
Normal file
@ -0,0 +1,7 @@
|
||||
import data from "yaml-loader!../../../../translations/base-no.yaml";
|
||||
|
||||
/** @type {"no"} **/
|
||||
const code = "no";
|
||||
const name = "Norsk";
|
||||
|
||||
export default { code, data, name };
|
7
src/js/translations/languages/pl.js
Normal file
7
src/js/translations/languages/pl.js
Normal file
@ -0,0 +1,7 @@
|
||||
import data from "yaml-loader!../../../../translations/base-pl.yaml";
|
||||
|
||||
/** @type {"pl"} **/
|
||||
const code = "pl";
|
||||
const name = "Polski";
|
||||
|
||||
export default { code, data, name };
|
8
src/js/translations/languages/pt-BR.js
Normal file
8
src/js/translations/languages/pt-BR.js
Normal file
@ -0,0 +1,8 @@
|
||||
import data from "yaml-loader!../../../../translations/base-pt-BR.yaml";
|
||||
|
||||
/** @type {"pt"} **/
|
||||
const code = "pt";
|
||||
const name = "Português (Brasil)";
|
||||
const region = "BR";
|
||||
|
||||
export default { code, data, name, region };
|
8
src/js/translations/languages/pt-PT.js
Normal file
8
src/js/translations/languages/pt-PT.js
Normal file
@ -0,0 +1,8 @@
|
||||
import data from "yaml-loader!../../../../translations/base-pt-PT.yaml";
|
||||
|
||||
/** @type {"pt"} **/
|
||||
const code = "pt";
|
||||
const name = "Português (Portugal)";
|
||||
const region = "PT";
|
||||
|
||||
export default { code, data, name, region };
|
7
src/js/translations/languages/ru.js
Normal file
7
src/js/translations/languages/ru.js
Normal file
@ -0,0 +1,7 @@
|
||||
import data from "yaml-loader!../../../../translations/base-ru.yaml";
|
||||
|
||||
/** @type {"ru"} **/
|
||||
const code = "ru";
|
||||
const name = "Русский";
|
||||
|
||||
export default { code, data, name };
|
7
src/js/translations/languages/sv.js
Normal file
7
src/js/translations/languages/sv.js
Normal file
@ -0,0 +1,7 @@
|
||||
import data from "yaml-loader!../../../../translations/base-sv.yaml";
|
||||
|
||||
/** @type {"sv"} **/
|
||||
const code = "sv";
|
||||
const name = "Svenska";
|
||||
|
||||
export default { code, data, name };
|
7
src/js/translations/languages/tr.js
Normal file
7
src/js/translations/languages/tr.js
Normal file
@ -0,0 +1,7 @@
|
||||
import data from "yaml-loader!../../../../translations/base-tr.yaml";
|
||||
|
||||
/** @type {"tr"} **/
|
||||
const code = "tr";
|
||||
const name = "Türkçe";
|
||||
|
||||
export default { code, data, name };
|
8
src/js/translations/languages/zh-CN.js
Normal file
8
src/js/translations/languages/zh-CN.js
Normal file
@ -0,0 +1,8 @@
|
||||
import data from "yaml-loader!../../../../translations/base-zh-CN.yaml";
|
||||
|
||||
/** @type {"zh"} **/
|
||||
const code = "zh";
|
||||
const name = "中文简体";
|
||||
const region = "CN";
|
||||
|
||||
export default { code, data, name, region };
|
8
src/js/translations/languages/zh-TW.js
Normal file
8
src/js/translations/languages/zh-TW.js
Normal file
@ -0,0 +1,8 @@
|
||||
import data from "yaml-loader!../../../../translations/base-zh-TW.yaml";
|
||||
|
||||
/** @type {"zh"} **/
|
||||
const code = "zh";
|
||||
const name = "中文繁體";
|
||||
const region = "TW";
|
||||
|
||||
export default { code, data, name, region };
|
344
src/js/translations/types.d.ts
vendored
Normal file
344
src/js/translations/types.d.ts
vendored
Normal file
@ -0,0 +1,344 @@
|
||||
declare type Translation<T extends string, U = string> = Record<T, U>;
|
||||
|
||||
declare type BeltVariant = "default";
|
||||
declare type WireVariant = "default" | "chainable";
|
||||
declare type UndergroundBeltVariant = "default" | "tier2";
|
||||
declare type SplitterVariant = "default" | "compact" | "compact-inverse";
|
||||
declare type CutterVariant = "default" | "quad";
|
||||
declare type AdvancedProcessorVariant = "default";
|
||||
declare type RotaterVariant = "default" | "ccw" | "fl";
|
||||
declare type StackerVariant = "default";
|
||||
declare type MixerVariant = "default";
|
||||
declare type PainterVariant = "default" | "mirrored" | "double" | "quad";
|
||||
declare type TrashVariant = "default" | "storage";
|
||||
declare type EnergyGeneratorVariant = "default";
|
||||
declare type WireCrossingsVariant = "default" | "merger";
|
||||
|
||||
declare type BuildingVariantMap = {
|
||||
belt: BeltVariant;
|
||||
wire: WireVariant;
|
||||
underground_belt: UndergroundBeltVariant;
|
||||
splitter: SplitterVariant;
|
||||
cutter: CutterVariant;
|
||||
advanced_processor: AdvancedProcessorVariant;
|
||||
rotater: RotaterVariant;
|
||||
stacker: StackerVariant;
|
||||
mixer: MixerVariant;
|
||||
painter: PainterVariant;
|
||||
trash: TrashVariant;
|
||||
energy_generator: EnergyGeneratorVariant;
|
||||
wire_crossings: WireCrossingsVariant;
|
||||
};
|
||||
|
||||
declare type BuildingVariant<V extends keyof BuildingVariantMap> = BuildingVariantMap[V];
|
||||
|
||||
declare type Building = keyof BuildingVariantMap;
|
||||
declare type Color =
|
||||
| "red"
|
||||
| "green"
|
||||
| "blue"
|
||||
| "yellow"
|
||||
| "purple"
|
||||
| "cyan"
|
||||
| "white"
|
||||
| "uncolored"
|
||||
| "black";
|
||||
declare type Environment = "dev" | "prod" | "staging";
|
||||
declare type Interval =
|
||||
| "one_minute"
|
||||
| "two_minutes"
|
||||
| "five_minutes"
|
||||
| "ten_minutes"
|
||||
| "twenty_minutes"
|
||||
| "disabled";
|
||||
declare type Scale = "super_small" | "small" | "regular" | "large" | "huge";
|
||||
declare type Sensitivity = "super_slow" | "slow" | "regular" | "fast" | "super_fast";
|
||||
declare type Speed = "super_slow" | "slow" | "regular" | "fast" | "super_fast" | "extremely_fast";
|
||||
declare type Theme = "dark" | "light";
|
||||
|
||||
declare type Rewards =
|
||||
| "reward_cutter_and_trash"
|
||||
| "reward_rotater"
|
||||
| "reward_painter"
|
||||
| "reward_mixer"
|
||||
| "reward_stacker"
|
||||
| "reward_splitter"
|
||||
| "reward_tunnel"
|
||||
| "reward_rotater_ccw"
|
||||
| "reward_miner_chainable"
|
||||
| "reward_underground_belt_tier_2"
|
||||
| "reward_splitter_compact"
|
||||
| "reward_cutter_quad"
|
||||
| "reward_painter_double"
|
||||
| "reward_painter_quad"
|
||||
| "reward_storage"
|
||||
| "reward_freeplay"
|
||||
| "reward_blueprints"
|
||||
| "no_reward"
|
||||
| "no_reward_freeplay";
|
||||
|
||||
declare type TitleAndText = Translation<"title" | "text">;
|
||||
declare type TitleAndDesc = Translation<"title" | "desc">;
|
||||
declare type TitleAndDescription = Translation<"title" | "description">;
|
||||
declare type NameAndDescription = Translation<"name" | "description">;
|
||||
|
||||
declare type SteamPage = Translation<"shortText" | "discordLink" | "longText">;
|
||||
|
||||
declare type Global = Translation<
|
||||
"loading" | "error" | "thousandsDivider" | "decimalSeparator" | "infinite"
|
||||
> & {
|
||||
suffix: Translation<"thousands" | "millions" | "billions" | "trillions">;
|
||||
time: Translation<
|
||||
| "oneSecondAgo"
|
||||
| "xSecondsAgo"
|
||||
| "oneMinuteAgo"
|
||||
| "xMinutesAgo"
|
||||
| "oneHourAgo"
|
||||
| "xHoursAgo"
|
||||
| "oneDayAgo"
|
||||
| "xDaysAgo"
|
||||
| "secondsShort"
|
||||
| "minutesAndSecondsShort"
|
||||
| "hoursAndMinutesShort"
|
||||
| "xMinutes"
|
||||
>;
|
||||
keys: Translation<"tab" | "control" | "alt" | "escape" | "shift" | "space">;
|
||||
};
|
||||
|
||||
declare type DemoBanners = Translation<"title" | "intro">;
|
||||
|
||||
declare type MainMenu = Translation<
|
||||
| "play"
|
||||
| "continue"
|
||||
| "newGame"
|
||||
| "changelog"
|
||||
| "subreddit"
|
||||
| "importSavegame"
|
||||
| "openSourceHint"
|
||||
| "discordLink"
|
||||
| "helpTranslate"
|
||||
| "madeBy"
|
||||
| "browserWarning"
|
||||
| "savegameLevel"
|
||||
| "savegameLevelUnknown"
|
||||
>;
|
||||
|
||||
declare type Dialogs = Translation<
|
||||
| "importSavegameError"
|
||||
| "importSavegameSuccess"
|
||||
| "gameLoadFailure"
|
||||
| "confirmSavegameDelete"
|
||||
| "savegameDeletionError"
|
||||
| "restartRequired",
|
||||
TitleAndText
|
||||
> &
|
||||
Translation<
|
||||
| "editKeybinding"
|
||||
| "resetKeybindingsConfirmation"
|
||||
| "keybindingsResetOk"
|
||||
| "featureRestriction"
|
||||
| "oneSavegameLimit"
|
||||
| "updateSummary"
|
||||
| "upgradesIntroduction"
|
||||
| "massDeleteConfirm"
|
||||
| "massCutConfirm"
|
||||
| "massCutInsufficientConfirm"
|
||||
| "blueprintsNotUnlocked"
|
||||
| "keybindingsIntroduction"
|
||||
| "exportScreenshotWarning",
|
||||
TitleAndDesc
|
||||
> & {
|
||||
createMarker: TitleAndDesc & Translation<"titleEdit">;
|
||||
markerDemoLimit: Translation<"desc">;
|
||||
} & {
|
||||
buttons: Translation<
|
||||
| "ok"
|
||||
| "delete"
|
||||
| "cancel"
|
||||
| "later"
|
||||
| "restart"
|
||||
| "reset"
|
||||
| "getStandalone"
|
||||
| "deleteGame"
|
||||
| "viewUpdate"
|
||||
| "showUpgrades"
|
||||
| "showKeybindings"
|
||||
>;
|
||||
};
|
||||
|
||||
declare type Ingame = {
|
||||
keybindingsOverlay: Translation<
|
||||
| "moveMap"
|
||||
| "selectBuildings"
|
||||
| "stopPlacement"
|
||||
| "rotateBuilding"
|
||||
| "placeMultiple"
|
||||
| "reverseOrientation"
|
||||
| "disableAutoOrientation"
|
||||
| "toggleHud"
|
||||
| "placeBuilding"
|
||||
| "createMarker"
|
||||
| "delete"
|
||||
| "pasteLastBlueprint"
|
||||
| "lockBeltDirection"
|
||||
| "plannerSwitchSide"
|
||||
| "cutSelection"
|
||||
| "copySelection"
|
||||
| "clearSelection"
|
||||
| "pipette"
|
||||
| "switchLayers"
|
||||
>;
|
||||
colors: Translation<Color>;
|
||||
buildingPlacement: Translation<"cycleBuildingVariants" | "hotkeyLabel"> & {
|
||||
infoTexts: Translation<
|
||||
| "speed"
|
||||
| "range"
|
||||
| "storage"
|
||||
| "oneItemPerSecond"
|
||||
| "itemsPerSecond"
|
||||
| "itemsPerSecondDouble"
|
||||
| "tiles"
|
||||
>;
|
||||
};
|
||||
levelCompleteNotification: Translation<"levelTitle" | "completed" | "unlockText" | "buttonNextLevel">;
|
||||
notifications: Translation<"newUpgrade" | "gameSaved">;
|
||||
shop: Translation<"title" | "buttonUnlock" | "tier" | "maximumLevel"> & {
|
||||
tierLabels: [string, string, string, string, string, string, string, string, string, string];
|
||||
};
|
||||
statistics: Translation<"title" | "noShapesProduced" | "shapesPerMinute"> & {
|
||||
dataSources: Translation<"stored" | "produced" | "delivered", TitleAndDescription>;
|
||||
};
|
||||
settingsMenu: Translation<"playtime" | "buildingsPlaced" | "beltsPlaced"> & {
|
||||
buttons: Translation<"continue" | "settings" | "menu">;
|
||||
};
|
||||
tutorialHints: Translation<"title" | "showHint" | "hideHint">;
|
||||
blueprintPlacer: Translation<"cost">;
|
||||
waypoints: Translation<"waypoints" | "hub" | "description" | "creationSuccessNotification">;
|
||||
shapeViewer: Translation<"title" | "empty" | "copyKey">;
|
||||
interactiveTutorial: Translation<"title"> & {
|
||||
hints: Translation<"1_1_extractor" | "1_2_conveyor" | "1_3_expand">;
|
||||
};
|
||||
};
|
||||
|
||||
declare type ShopUpgrades = Record<"belt" | "miner" | "processors" | "painting", NameAndDescription>;
|
||||
|
||||
declare type Buildings = { [Key in Building]: Translation<BuildingVariant<Key>, NameAndDescription> } & {
|
||||
hub: Translation<"deliver" | "toUnlock" | "levelShortcut">;
|
||||
energy_generator: Translation<"deliver" | "toGenerateEnergy">;
|
||||
};
|
||||
|
||||
declare type StoryRewards = Translation<Rewards, TitleAndDesc>;
|
||||
|
||||
declare type Settings = Translation<"title" | "buildDate"> & {
|
||||
categories: Translation<"general" | "userInterface" | "advanced">;
|
||||
versionBadges: Translation<Environment>;
|
||||
labels: Translation<
|
||||
| "language"
|
||||
| "enableColorBlindHelper"
|
||||
| "fullscreen"
|
||||
| "soundsMuted"
|
||||
| "musicMuted"
|
||||
| "refreshRate"
|
||||
| "alwaysMultiplace"
|
||||
| "offerHints"
|
||||
| "enableTunnelSmartplace"
|
||||
| "vignette"
|
||||
| "rotationByBuilding"
|
||||
| "compactBuildingInfo"
|
||||
| "disableCutDeleteWarnings",
|
||||
TitleAndDescription
|
||||
> & {
|
||||
autosaveInterval: TitleAndDescription & { intervals: Translation<Interval> };
|
||||
movementSpeed: TitleAndDescription & { speeds: Translation<Speed> };
|
||||
scrollWheelSensitivity: TitleAndDescription & { sensitivity: Translation<Sensitivity> };
|
||||
theme: TitleAndDescription & { themes: Translation<Theme> };
|
||||
uiScale: TitleAndDescription & { scales: Translation<Scale> };
|
||||
};
|
||||
};
|
||||
|
||||
declare type KeyBindings = Translation<"title" | "hint" | "resetKeybindings" | "categoryLabels"> & {
|
||||
categoryLabels: Translation<
|
||||
"general" | "ingame" | "navigation" | "placement" | "massSelect" | "buildings" | "placementModifiers"
|
||||
>;
|
||||
mappings: Translation<
|
||||
| "confirm"
|
||||
| "back"
|
||||
| "mapMoveUp"
|
||||
| "mapMoveRight"
|
||||
| "mapMoveDown"
|
||||
| "mapMoveLeft"
|
||||
| "mapMoveFaster"
|
||||
| "centerMap"
|
||||
| "mapZoomIn"
|
||||
| "mapZoomOut"
|
||||
| "createMarker"
|
||||
| "menuOpenShop"
|
||||
| "menuOpenStats"
|
||||
| "menuClose"
|
||||
| "toggleHud"
|
||||
| "toggleFPSInfo"
|
||||
| "switchLayers"
|
||||
| "exportScreenshot"
|
||||
| "belt"
|
||||
| "splitter"
|
||||
| "underground_belt"
|
||||
| "miner"
|
||||
| "cutter"
|
||||
| "advanced_processor"
|
||||
| "rotater"
|
||||
| "stacker"
|
||||
| "mixer"
|
||||
| "energy_generator"
|
||||
| "painter"
|
||||
| "trash"
|
||||
| "wire"
|
||||
| "pipette"
|
||||
| "rotateWhilePlacing"
|
||||
| "rotateInverseModifier"
|
||||
| "cycleBuildingVariants"
|
||||
| "confirmMassDelete"
|
||||
| "pasteLastBlueprint"
|
||||
| "cycleBuildings"
|
||||
| "lockBeltDirection"
|
||||
| "switchDirectionLockSide"
|
||||
| "massSelectStart"
|
||||
| "massSelectSelectMultiple"
|
||||
| "massSelectCopy"
|
||||
| "massSelectCut"
|
||||
| "placementDisableAutoOrientation"
|
||||
| "placeMultiple"
|
||||
| "placeInverse"
|
||||
>;
|
||||
};
|
||||
|
||||
declare type About = Translation<"title" | "body">;
|
||||
|
||||
declare type Changelog = Translation<"title">;
|
||||
|
||||
declare type Demo = Translation<"settingNotAvailable"> & {
|
||||
features: Translation<
|
||||
"restoringGames" | "importingGames" | "oneGameLimit" | "customizeKeybindings" | "exportingBase"
|
||||
>;
|
||||
};
|
||||
|
||||
declare interface Translations {
|
||||
steamPage: SteamPage;
|
||||
global: Global;
|
||||
demoBanners: DemoBanners;
|
||||
mainMenu: MainMenu;
|
||||
dialogs: Dialogs;
|
||||
ingame: Ingame;
|
||||
shopUpgrades: ShopUpgrades;
|
||||
buildings: Buildings;
|
||||
storyRewards: StoryRewards;
|
||||
settings: Settings;
|
||||
keybindings: KeyBindings;
|
||||
about: About;
|
||||
changelog: Changelog;
|
||||
demo: Demo;
|
||||
}
|
||||
|
||||
declare module "yaml-loader!*" {
|
||||
const content: Translations;
|
||||
export default content;
|
||||
}
|
10
yarn.lock
10
yarn.lock
@ -8555,7 +8555,15 @@ yaml-js@^0.1.3:
|
||||
resolved "https://registry.yarnpkg.com/yaml-js/-/yaml-js-0.1.5.tgz#a01369010b3558d8aaed2394615dfd0780fd8fac"
|
||||
integrity sha1-oBNpAQs1WNiq7SOUYV39B4D9j6w=
|
||||
|
||||
yaml@^1.10.0:
|
||||
yaml-loader@^0.6.0:
|
||||
version "0.6.0"
|
||||
resolved "https://registry.yarnpkg.com/yaml-loader/-/yaml-loader-0.6.0.tgz#fe1c48b9f4803dace55a59a1474e790ba6ab1b48"
|
||||
integrity sha512-1bNiLelumURyj+zvVHOv8Y3dpCri0F2S+DCcmps0pA1zWRLjS+FhZQg4o3aUUDYESh73+pKZNI18bj7stpReow==
|
||||
dependencies:
|
||||
loader-utils "^1.4.0"
|
||||
yaml "^1.8.3"
|
||||
|
||||
yaml@^1.10.0, yaml@^1.8.3:
|
||||
version "1.10.0"
|
||||
resolved "https://registry.yarnpkg.com/yaml/-/yaml-1.10.0.tgz#3b593add944876077d4d683fee01081bd9fff31e"
|
||||
integrity sha512-yr2icI4glYaNG+KWONODapy2/jDdMSDnrONSjblABjD9B4Z5LgiircSt8m8sRZFNi08kG9Sm0uSHtEmP3zaEGg==
|
||||
|
Loading…
Reference in New Issue
Block a user