diff --git a/front/src/Components/Menu/SettingsSubMenu.svelte b/front/src/Components/Menu/SettingsSubMenu.svelte index 53503902..776acbbe 100644 --- a/front/src/Components/Menu/SettingsSubMenu.svelte +++ b/front/src/Components/Menu/SettingsSubMenu.svelte @@ -4,7 +4,7 @@ import { HtmlUtils } from "../../WebRtc/HtmlUtils"; import { isMobile } from "../../Enum/EnvironmentVariable"; import { menuVisiblilityStore } from "../../Stores/MenuStore"; -import { translator } from "../../Translator/Translator"; + import { languages, translator } from "../../Translator/Translator"; let fullscreen: boolean = localUserStore.getFullscreen(); let notification: boolean = localUserStore.getNotification() === "granted"; @@ -12,14 +12,18 @@ import { translator } from "../../Translator/Translator"; let ignoreFollowRequests: boolean = localUserStore.getIgnoreFollowRequests(); let valueGame: number = localUserStore.getGameQualityValue(); let valueVideo: number = localUserStore.getVideoQualityValue(); + let valueLanguage: string = translator.getStringByLanguage(translator.getCurrentLanguage()) ?? "en-US"; let previewValueGame = valueGame; let previewValueVideo = valueVideo; + let previewValueLanguage = valueLanguage; function saveSetting() { - if (valueGame !== previewValueGame) { - previewValueGame = valueGame; - localUserStore.setGameQualityValue(valueGame); - window.location.reload(); + let change = false; + + if (valueLanguage !== previewValueLanguage) { + previewValueLanguage = valueLanguage; + translator.switchLanguage(previewValueLanguage); + change = true; } if (valueVideo !== previewValueVideo) { @@ -27,6 +31,16 @@ import { translator } from "../../Translator/Translator"; videoConstraintStore.setFrameRate(valueVideo); } + if (valueGame !== previewValueGame) { + previewValueGame = valueGame; + localUserStore.setGameQualityValue(valueGame); + change = true; + } + + if (change) { + window.location.reload(); + } + closeMenu(); } @@ -127,6 +141,17 @@ import { translator } from "../../Translator/Translator"; + + {translator._("menu.settings.language.title")} + + + + {#each languages as language} + {`${language.language} (${language.country})`} + {/each} + + + {translator._("menu.settings.save.warning")} | undefined) => { const files = fs.readdirSync(dirPath); languages = languages || new Array(); @@ -25,10 +20,18 @@ const getAllLanguagesByFiles = (dirPath: string, languages: Array const rawData = fs.readFileSync(dirPath + "/" + file, "utf-8"); const languageObject = JSON.parse(rawData); - languages?.push({ - id: parts[1], - default: languageObject.default !== undefined && languageObject.default, - }); + if ( + "language" in languageObject && typeof languageObject.language === "string" && + "country" in languageObject && typeof languageObject.country === "string" && + "default" in languageObject && typeof languageObject.default === "boolean" + ) { + languages?.push({ + id: parts[1], + language: languageObject.language, + country: languageObject.country, + default: languageObject.default + }); + } } }); @@ -57,16 +60,5 @@ const getFallbackLanguageObject = (dirPath: string, languageObject: Object | und return languageObject; }; -const languagesToObject = () => { - const object: { [key: string]: boolean } = {}; - - languages.forEach((language) => { - object[language.id] = false; - }); - - return object; -}; - export const languages = getAllLanguagesByFiles(translationsBasePath, undefined); -export const languagesObject = languagesToObject(); export const fallbackLanguageObject = getFallbackLanguageObject(translationsBasePath, undefined); diff --git a/front/src/Translator/Translator.ts b/front/src/Translator/Translator.ts index 7cae4c5f..df1539dc 100644 --- a/front/src/Translator/Translator.ts +++ b/front/src/Translator/Translator.ts @@ -77,6 +77,15 @@ class Translator { }); } + /** + * TypeGuard to check if is a LanguageObject + * @param {unknown} object Presume LanguageObject + * @returns {boolean} Is a LanguageObject or not + */ + private isLanguageObject(object: unknown): object is LanguageObject { + return typeof object === "object"; + } + /** * Get from the Phase cache the current language object and promise to load it * @param {Phaser.Cache.CacheManager} cacheManager Phaser CacheManager @@ -92,7 +101,11 @@ class Translator { return reject(new Error("Language not found in cache")); } - this.currentLanguageObject = languageObject as LanguageObject; + if (!this.isLanguageObject(languageObject)) { + throw new Error("Cannot load a bad language object"); + } + + this.currentLanguageObject = languageObject; return resolve(); }); } @@ -109,11 +122,9 @@ class Translator { let languageFound = undefined; - const languages: { [key: string]: boolean } = LANGUAGES as { [key: string]: boolean }; - - for (const language in languages) { - if (language.startsWith(languageString) && languages[language]) { - languageFound = this.getLanguageByString(language); + for (const language of LANGUAGES) { + if (language.id.startsWith(languageString) && language.default) { + languageFound = this.getLanguageByString(language.id); break; } } @@ -129,6 +140,12 @@ class Translator { return this.currentLanguage; } + public switchLanguage(languageString: string) { + if (this.getLanguageByString(languageString)) { + localStorage.setItem("language", languageString); + } + } + /** * Define the current language by the navigator or a cookie */ @@ -232,4 +249,5 @@ class Translator { } } +export const languages: LanguageFound[] = LANGUAGES; export const translator = new Translator(); diff --git a/front/src/define-plugin.d.ts b/front/src/define-plugin.d.ts index 679cf2e0..b43443ec 100644 --- a/front/src/define-plugin.d.ts +++ b/front/src/define-plugin.d.ts @@ -1,2 +1,13 @@ -declare const FALLBACK_LANGUAGE_OBJECT: Object; -declare const LANGUAGES: Object; +type LanguageObject = { + [key: string]: string | LanguageObject; +}; + +type LanguageFound = { + id: string; + language: string; + country: string; + default: boolean; +}; + +declare const FALLBACK_LANGUAGE_OBJECT: LanguageObject; +declare const LANGUAGES: LanguageFound[]; diff --git a/front/translations/en-US/menu.en-US.json b/front/translations/en-US/menu.en-US.json index f6170423..c0375ebe 100644 --- a/front/translations/en-US/menu.en-US.json +++ b/front/translations/en-US/menu.en-US.json @@ -53,6 +53,9 @@ "small": "Small video quality (5 fps)" } }, + "language": { + "title": "Language" + }, "save": { "warning": "(Saving these settings will restart the game)", "button": "Save" diff --git a/front/translations/fr-FR/menu.fr-FR.json b/front/translations/fr-FR/menu.fr-FR.json index 83490bc5..4f009543 100644 --- a/front/translations/fr-FR/menu.fr-FR.json +++ b/front/translations/fr-FR/menu.fr-FR.json @@ -53,6 +53,9 @@ "small": "Reduite (5 fps)" } }, + "language": { + "title": "Langage" + }, "save": { "warning": "(La sauvegarde de ces paramètres redémarre le jeu)", "button": "Sauvegarder" diff --git a/front/webpack.config.ts b/front/webpack.config.ts index b407adb9..498499cd 100644 --- a/front/webpack.config.ts +++ b/front/webpack.config.ts @@ -7,8 +7,7 @@ import sveltePreprocess from "svelte-preprocess"; import type { Configuration } from "webpack"; import webpack from "webpack"; import type WebpackDevServer from "webpack-dev-server"; -import type { LanguageFound } from "./src/Translator/TranslationCompiler"; -import { fallbackLanguageObject, languages, languagesObject } from "./src/Translator/TranslationCompiler"; +import { fallbackLanguageObject, languages } from "./src/Translator/TranslationCompiler"; const MergeJsonWebpackPlugin = require("merge-jsons-webpack-plugin"); @@ -223,7 +222,7 @@ module.exports = { }), new webpack.DefinePlugin({ FALLBACK_LANGUAGE_OBJECT: JSON.stringify(fallbackLanguageObject), - LANGUAGES: JSON.stringify(languagesObject), + LANGUAGES: JSON.stringify(languages), }), new MergeJsonWebpackPlugin({ output: {
{translator._("menu.settings.save.warning")}