diff --git a/dist/index.html b/dist/index.html index e4de32c..724c2cc 100644 --- a/dist/index.html +++ b/dist/index.html @@ -55,13 +55,13 @@ @@ -83,20 +95,20 @@

- - - - - + + + + +
@@ -111,7 +123,7 @@
- +
Users Online ()Users Online ()
diff --git a/dist/translations/de.json b/dist/translations/de.json new file mode 100644 index 0000000..717f53a --- /dev/null +++ b/dist/translations/de.json @@ -0,0 +1,22 @@ +{ + "Control Collaborative Virtual Machines!": "Steuern Sie kollaborative virtuelle Maschinen!", + "Home": "Hauptseite", + "FAQ": "FAQ", + "Rules": "Regeln", + "Do you want to reset the vm?": "Möchten Sie die VM zurücksetzen?", + "Yes": "Ja", + "No": "Nein", + "Vote ends in # seconds": "Abstimmung endet in # Sekunden", + "Pass Vote": "Abstimmung bestehen", + "Cancel Vote": "Abstimmung abbrechen", + "Take Turn": "In Reihe stellen.", + "Change Username": "Nutzername ändern", + "Vote for Reset": "Für Zurücksetzung abstimmen", + "Screenshot": "Screenshot", + "Users Online": "Nutzer online", + "End Turn": "Aus der Reihe kommen", + "Turn expires in # seconds.": "Ihre Zeit läuft in # Sekunden aus.", + "Waiting for turn in # seconds.": "In der Reihe warten für # Sekunden.", + "Please wait # seconds before starting another vote.": "Bitte warten Sie # Sekunden bevor Sie noch eine Abstimmung starten.", + "Enter new username": "Geben Sie Ihren neuen Nutzername ein." +} \ No newline at end of file diff --git a/dist/translations/en.json b/dist/translations/en.json new file mode 100644 index 0000000..765a1a5 --- /dev/null +++ b/dist/translations/en.json @@ -0,0 +1,22 @@ +{ + "Control Collaborative Virtual Machines!": "Control Collaborative Virtual Machines!", + "Home": "Home", + "FAQ": "FAQ", + "Rules": "Rules", + "Do you want to reset the vm?": "Do you want to reset the vm?", + "Yes": "Yes", + "No": "No", + "Vote ends in # seconds": "Vote ends in # seconds", + "Pass Vote": "Pass Vote", + "Cancel Vote": "Cancel Vote", + "Take Turn": "Take Turn", + "Change Username": "Change Username", + "Vote for Reset": "Vote for Reset", + "Screenshot": "Screenshot", + "Users Online": "Users Online", + "End Turn": "End Turn", + "Turn expires in # seconds.": "Turn expires in # seconds.", + "Waiting for turn in # seconds.": "Waiting for turn in # seconds.", + "Please wait # seconds before starting another vote.": "Please wait # seconds before starting another vote.", + "Enter new username": "Enter new username" +} \ No newline at end of file diff --git a/src/i18n.js b/src/i18n.js new file mode 100644 index 0000000..2b75b83 --- /dev/null +++ b/src/i18n.js @@ -0,0 +1,91 @@ +export default class i18n { + lang; + data; + error; + + constructor(lang) { + this.lang = lang; + } + + async init() { + return new Promise(async (resolve, reject) => { + this.load(this.lang).then(res => { + this.error = false; + this.data = res; + return resolve(); + }).catch(() => { + this.error = true; + alert(`i18n error: Failed to load language file for ${lang}. Alert a site administrator!`); + return reject(); + }); + }); + } + + load(lang) { + return new Promise(async (res, rej) => { + await fetch(`translations/${lang}.json`).then(response => { + if (!response.ok) { return rej(); } + return res(response.json()); + }); + }); + } + + get(key) { + + // If we failed to load the translations earlier, return the original input. + if (this.error) { + return key; + } + + const value = this.data[key]; + + // If the translation does not exist in the currently loaded language, return the original input. + if (!value) { + return key; + } + + return value; + } + + change(lang) { + if (this.lang == lang) return; + + this.load(lang).then(res => { + this.lang = lang; + this.data = res; + this.replaceAllInDOM(); + }).catch((e) => { + console.log(e); + return alert(`i18n error: Failed to load language file for ${lang}. Alert a site administrator!`); + }); + } + + replaceAllInDOM() { + document.title = this.get("Control Collaborative Virtual Machines!"); + + var elements = [ + { id: "homeText", key: "Home" }, + { id: "faqLink", key: "FAQ" }, + { id: "rulesLink", key: "Rules" }, + { id: "onlineUserText", key: "Users Online" }, + { id: "voteResetText", key: "Do you want to reset the vm?" }, + { id: "voteYesText", key: "Yes" }, + { id: "voteNoText", key: "No" }, + { id: "passVoteButtonText", key: "Pass Vote" }, + { id: "cancelVoteButtonText", key: "Cancel Vote" }, + { id: "takeTurnButtonText", key: "Take Turn" }, + { id: "changeUsernameButtonText", key: "Change Username" }, + { id: "voteResetButtonText", key: "Vote for Reset" }, + { id: "screenshotButtonText", key: "Screenshot" } + ]; + + elements.forEach(el => { + var element = document.getElementById(el.id); + if (element != null) { + element.innerText = ` ${this.get(el.key)}`; + } else { + console.warn(`${el.id} was null (would have assigned ${this.get(el.key)})`) + } + }); + } +} \ No newline at end of file diff --git a/src/index.js b/src/index.js index 01cc935..c31d59c 100644 --- a/src/index.js +++ b/src/index.js @@ -4,6 +4,14 @@ import { GetKeysym } from "./keyboard"; import { createNanoEvents } from "nanoevents"; import { makeperms } from "./permissions"; import doCaptcha from "./captcha"; +import i18n from "./i18n"; + +// i18n +window.i18n = new i18n(navigator.language.split("-")[0]); +window.i18n.init().then(() => { + window.i18n.replaceAllInDOM(); +}); + // None = -1 // Has turn = 0 // In queue = @@ -275,7 +283,7 @@ class CollabVMClient { curr.turn = -1; curr.element.classList = ""; }); - buttons.takeTurn.innerHTML = " Take Turn"; + buttons.takeTurn.innerHTML = ` ${window.i18n.get("Take Turn")}`; turn = -1; if (!msgArr.includes(username)) turnstatus.innerText = ""; @@ -296,7 +304,7 @@ class CollabVMClient { secs--; if (secs === 0) clearInterval(turninterval); - turnstatus.innerText = `Turn expires in ${secs} seconds.`; + turnstatus.innerText = `${window.i18n.get("Turn expires in # seconds.").replace("#", secs)}`; } turnUpdate(); turninterval = setInterval(turnUpdate, 1000); @@ -312,7 +320,7 @@ class CollabVMClient { secs--; if (secs === 0) clearInterval(turninterval); - turnstatus.innerText = `Waiting for turn in ${secs} seconds.`; + turnstatus.innerText = `${window.i18n.get("Waiting for turn in # seconds.").replace("#", secs)}`; } turninterval = setInterval(turnUpdate, 1000); turnUpdate(); @@ -324,9 +332,9 @@ class CollabVMClient { } } if (turn === -1) { - buttons.takeTurn.innerHTML = " Take Turn"; + buttons.takeTurn.innerHTML = ` ${window.i18n.get("Take Turn")}`; } else { - buttons.takeTurn.innerHTML = " End Turn"; + buttons.takeTurn.innerHTML = ` ${window.i18n.get("End Turn")}`; } this.reloadUsers(); break; @@ -356,8 +364,8 @@ class CollabVMClient { voteresetpanel.style.display = "none"; break; case "3": - // too soon dumbass - window.alert(`Please wait ${msgArr[2]} seconds before starting another vote.`); + // Vote is on cooldown + window.alert(`${window.i18n.get("Please wait # seconds before starting another vote.").replace("#", msgArr[2])}`); break; } break; @@ -820,7 +828,7 @@ function sendChat() { chatinput.value = ""; } buttons.changeUsername.addEventListener('click', () => { - var newuser = window.prompt("Enter new username", window.username); + var newuser = window.prompt(window.i18n.get("Enter new username"), window.username); if (newuser == null) return; vm.rename(newuser); });