Add language switcher on settings

This commit is contained in:
Nolway 2022-01-07 01:50:47 +01:00 committed by Alexis Faizeau
parent 6ff4d6d634
commit 54ae3bf215
7 changed files with 91 additions and 36 deletions

View File

@ -4,7 +4,7 @@
import { HtmlUtils } from "../../WebRtc/HtmlUtils"; import { HtmlUtils } from "../../WebRtc/HtmlUtils";
import { isMobile } from "../../Enum/EnvironmentVariable"; import { isMobile } from "../../Enum/EnvironmentVariable";
import { menuVisiblilityStore } from "../../Stores/MenuStore"; import { menuVisiblilityStore } from "../../Stores/MenuStore";
import { translator } from "../../Translator/Translator"; import { languages, translator } from "../../Translator/Translator";
let fullscreen: boolean = localUserStore.getFullscreen(); let fullscreen: boolean = localUserStore.getFullscreen();
let notification: boolean = localUserStore.getNotification() === "granted"; let notification: boolean = localUserStore.getNotification() === "granted";
@ -12,14 +12,18 @@ import { translator } from "../../Translator/Translator";
let ignoreFollowRequests: boolean = localUserStore.getIgnoreFollowRequests(); let ignoreFollowRequests: boolean = localUserStore.getIgnoreFollowRequests();
let valueGame: number = localUserStore.getGameQualityValue(); let valueGame: number = localUserStore.getGameQualityValue();
let valueVideo: number = localUserStore.getVideoQualityValue(); let valueVideo: number = localUserStore.getVideoQualityValue();
let valueLanguage: string = translator.getStringByLanguage(translator.getCurrentLanguage()) ?? "en-US";
let previewValueGame = valueGame; let previewValueGame = valueGame;
let previewValueVideo = valueVideo; let previewValueVideo = valueVideo;
let previewValueLanguage = valueLanguage;
function saveSetting() { function saveSetting() {
if (valueGame !== previewValueGame) { let change = false;
previewValueGame = valueGame;
localUserStore.setGameQualityValue(valueGame); if (valueLanguage !== previewValueLanguage) {
window.location.reload(); previewValueLanguage = valueLanguage;
translator.switchLanguage(previewValueLanguage);
change = true;
} }
if (valueVideo !== previewValueVideo) { if (valueVideo !== previewValueVideo) {
@ -27,6 +31,16 @@ import { translator } from "../../Translator/Translator";
videoConstraintStore.setFrameRate(valueVideo); videoConstraintStore.setFrameRate(valueVideo);
} }
if (valueGame !== previewValueGame) {
previewValueGame = valueGame;
localUserStore.setGameQualityValue(valueGame);
change = true;
}
if (change) {
window.location.reload();
}
closeMenu(); closeMenu();
} }
@ -127,6 +141,17 @@ import { translator } from "../../Translator/Translator";
</select> </select>
</div> </div>
</section> </section>
<section>
<h3>{translator._("menu.settings.language.title")}</h3>
<div class="nes-select is-dark">
<select class="languages-switcher" bind:value={valueLanguage}>
<!-- svelte-ignore missing-declaration -->
{#each languages as language}
<option value={language.id}>{`${language.language} (${language.country})`}</option>
{/each}
</select>
</div>
</section>
<section class="settings-section-save"> <section class="settings-section-save">
<p>{translator._("menu.settings.save.warning")}</p> <p>{translator._("menu.settings.save.warning")}</p>
<button type="button" class="nes-btn is-primary" on:click|preventDefault={saveSetting} <button type="button" class="nes-btn is-primary" on:click|preventDefault={saveSetting}
@ -205,6 +230,10 @@ import { translator } from "../../Translator/Translator";
margin: 0 0 15px; margin: 0 0 15px;
} }
} }
.languages-switcher option {
text-transform: capitalize;
}
} }
@media only screen and (max-width: 800px), only screen and (max-height: 800px) { @media only screen and (max-width: 800px), only screen and (max-height: 800px) {

View File

@ -3,11 +3,6 @@ import fs from "fs";
const translationsBasePath = "./translations"; const translationsBasePath = "./translations";
const fallbackLanguage = process.env.FALLBACK_LANGUAGE || "en-US"; const fallbackLanguage = process.env.FALLBACK_LANGUAGE || "en-US";
export type LanguageFound = {
id: string;
default: boolean;
};
const getAllLanguagesByFiles = (dirPath: string, languages: Array<LanguageFound> | undefined) => { const getAllLanguagesByFiles = (dirPath: string, languages: Array<LanguageFound> | undefined) => {
const files = fs.readdirSync(dirPath); const files = fs.readdirSync(dirPath);
languages = languages || new Array<LanguageFound>(); languages = languages || new Array<LanguageFound>();
@ -25,10 +20,18 @@ const getAllLanguagesByFiles = (dirPath: string, languages: Array<LanguageFound>
const rawData = fs.readFileSync(dirPath + "/" + file, "utf-8"); const rawData = fs.readFileSync(dirPath + "/" + file, "utf-8");
const languageObject = JSON.parse(rawData); const languageObject = JSON.parse(rawData);
languages?.push({ if (
id: parts[1], "language" in languageObject && typeof languageObject.language === "string" &&
default: languageObject.default !== undefined && languageObject.default, "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; 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 languages = getAllLanguagesByFiles(translationsBasePath, undefined);
export const languagesObject = languagesToObject();
export const fallbackLanguageObject = getFallbackLanguageObject(translationsBasePath, undefined); export const fallbackLanguageObject = getFallbackLanguageObject(translationsBasePath, undefined);

View File

@ -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 * Get from the Phase cache the current language object and promise to load it
* @param {Phaser.Cache.CacheManager} cacheManager Phaser CacheManager * @param {Phaser.Cache.CacheManager} cacheManager Phaser CacheManager
@ -92,7 +101,11 @@ class Translator {
return reject(new Error("Language not found in cache")); 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(); return resolve();
}); });
} }
@ -109,11 +122,9 @@ class Translator {
let languageFound = undefined; let languageFound = undefined;
const languages: { [key: string]: boolean } = LANGUAGES as { [key: string]: boolean }; for (const language of LANGUAGES) {
if (language.id.startsWith(languageString) && language.default) {
for (const language in languages) { languageFound = this.getLanguageByString(language.id);
if (language.startsWith(languageString) && languages[language]) {
languageFound = this.getLanguageByString(language);
break; break;
} }
} }
@ -129,6 +140,12 @@ class Translator {
return this.currentLanguage; 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 * 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(); export const translator = new Translator();

View File

@ -1,2 +1,13 @@
declare const FALLBACK_LANGUAGE_OBJECT: Object; type LanguageObject = {
declare const LANGUAGES: Object; [key: string]: string | LanguageObject;
};
type LanguageFound = {
id: string;
language: string;
country: string;
default: boolean;
};
declare const FALLBACK_LANGUAGE_OBJECT: LanguageObject;
declare const LANGUAGES: LanguageFound[];

View File

@ -53,6 +53,9 @@
"small": "Small video quality (5 fps)" "small": "Small video quality (5 fps)"
} }
}, },
"language": {
"title": "Language"
},
"save": { "save": {
"warning": "(Saving these settings will restart the game)", "warning": "(Saving these settings will restart the game)",
"button": "Save" "button": "Save"

View File

@ -53,6 +53,9 @@
"small": "Reduite (5 fps)" "small": "Reduite (5 fps)"
} }
}, },
"language": {
"title": "Langage"
},
"save": { "save": {
"warning": "(La sauvegarde de ces paramètres redémarre le jeu)", "warning": "(La sauvegarde de ces paramètres redémarre le jeu)",
"button": "Sauvegarder" "button": "Sauvegarder"

View File

@ -7,8 +7,7 @@ import sveltePreprocess from "svelte-preprocess";
import type { Configuration } from "webpack"; import type { Configuration } from "webpack";
import webpack from "webpack"; import webpack from "webpack";
import type WebpackDevServer from "webpack-dev-server"; import type WebpackDevServer from "webpack-dev-server";
import type { LanguageFound } from "./src/Translator/TranslationCompiler"; import { fallbackLanguageObject, languages } from "./src/Translator/TranslationCompiler";
import { fallbackLanguageObject, languages, languagesObject } from "./src/Translator/TranslationCompiler";
const MergeJsonWebpackPlugin = require("merge-jsons-webpack-plugin"); const MergeJsonWebpackPlugin = require("merge-jsons-webpack-plugin");
@ -223,7 +222,7 @@ module.exports = {
}), }),
new webpack.DefinePlugin({ new webpack.DefinePlugin({
FALLBACK_LANGUAGE_OBJECT: JSON.stringify(fallbackLanguageObject), FALLBACK_LANGUAGE_OBJECT: JSON.stringify(fallbackLanguageObject),
LANGUAGES: JSON.stringify(languagesObject), LANGUAGES: JSON.stringify(languages),
}), }),
new MergeJsonWebpackPlugin({ new MergeJsonWebpackPlugin({
output: { output: {