initial i18n implementation
This commit is contained in:
parent
1f89ed75c1
commit
746b7fc018
36
dist/index.html
vendored
36
dist/index.html
vendored
|
|
@ -55,13 +55,13 @@
|
||||||
<div class="collapse navbar-collapse" id="navbarNav">
|
<div class="collapse navbar-collapse" id="navbarNav">
|
||||||
<ul class="navbar-nav">
|
<ul class="navbar-nav">
|
||||||
<li class="nav-item">
|
<li class="nav-item">
|
||||||
<a id="homeBtn" href="#" class="nav-link active" aria-current="page"><i class="fa-solid fa-house"></i> Home</a>
|
<a id="homeBtn" href="#" class="nav-link active" aria-current="page"><i class="fa-solid fa-house"></i><span id="homeText">Home</span></a>
|
||||||
</li>
|
</li>
|
||||||
<li class="nav-item">
|
<li class="nav-item">
|
||||||
<a href="https://computernewb.com/collab-vm/faq/" class="nav-link"><i class="fa-solid fa-circle-question"></i> FAQ</a>
|
<a href="https://computernewb.com/collab-vm/faq/" class="nav-link"><i class="fa-solid fa-circle-question"></i><span id="faqLink">FAQ</span></a>
|
||||||
</li>
|
</li>
|
||||||
<li class="nav-item">
|
<li class="nav-item">
|
||||||
<a href="https://computernewb.com/collab-vm/rules" class="nav-link"><i class="fa-solid fa-clipboard-check"></i> Rules</a>
|
<a href="https://computernewb.com/collab-vm/rules" class="nav-link"><i class="fa-solid fa-clipboard-check"></i><span id="rulesLink">Rules</span></a>
|
||||||
</li>
|
</li>
|
||||||
<li class="nav-item">
|
<li class="nav-item">
|
||||||
<a href="https://discord.gg/a4kqb4mGyX" class="nav-link"><i class="fa-brands fa-discord"></i> Discord</a>
|
<a href="https://discord.gg/a4kqb4mGyX" class="nav-link"><i class="fa-brands fa-discord"></i> Discord</a>
|
||||||
|
|
@ -72,6 +72,18 @@
|
||||||
<li class="nav-item">
|
<li class="nav-item">
|
||||||
<a href="https://computernewb.com/collab-vm/user-vm" class="nav-link"><i class="fa-solid fa-user"></i> UserVM</a>
|
<a href="https://computernewb.com/collab-vm/user-vm" class="nav-link"><i class="fa-solid fa-user"></i> UserVM</a>
|
||||||
</li>
|
</li>
|
||||||
|
<li class="nav-item dropdown">
|
||||||
|
<a href="#" class="nav-link dropdown-toggle" role="button" href="#" data-bs-toggle="dropdown" id="navbarDropdown"><i class="fa-solid fa-globe"></i> Languages</a>
|
||||||
|
<ul class="dropdown-menu" aria-labelledby="navbarDropdown">
|
||||||
|
<li><a class="dropdown-item" href="#" onclick='window.i18n.change("sa")'><img src="//computernewb.com/vncresolver/flags/sa.png"> اللغة العربية (جزئية)</a></li>
|
||||||
|
<li><a class="dropdown-item" href="#" onclick='window.i18n.change("de")'><img src="//computernewb.com/vncresolver/flags/de.png"> Deutsch</a></li>
|
||||||
|
<li><a class="dropdown-item" href="#" onclick='window.i18n.change("en")'><img src="//computernewb.com/vncresolver/flags/gb.png"> English</a></li>
|
||||||
|
<li><a class="dropdown-item" href="#" onclick='window.i18n.change("es")'><img src="https://computernewb.com/vncresolver/flags/es.png"> Español</a></li>
|
||||||
|
<li><a class="dropdown-item" href="#" onclick='window.i18n.change("jp")'><img src="//computernewb.com/vncresolver/flags/jp.png"> 日本語</a></li>
|
||||||
|
<li><a class="dropdown-item" href="#" onclick='window.i18n.change("pl")'><img src="//computernewb.com/vncresolver/flags/pl.png"> Polski</a></li>
|
||||||
|
<li><a class="dropdown-item" href="#" onclick='window.i18n.change("ru")'><img src="//computernewb.com/vncresolver/flags/ru.png"> Русский</a></li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -83,19 +95,19 @@
|
||||||
<canvas id="display" height="0" width="0" tabindex="-1"></canvas>
|
<canvas id="display" height="0" width="0" tabindex="-1"></canvas>
|
||||||
<p id="turnstatus" class="text-light"></p>
|
<p id="turnstatus" class="text-light"></p>
|
||||||
<div id="voteResetPanel" class="bg-dark text-light" style="display:none;">
|
<div id="voteResetPanel" class="bg-dark text-light" style="display:none;">
|
||||||
Do you want to reset the vm?<br/>
|
<span id="voteResetText">Do you want to reset the vm?</span><br/>
|
||||||
<button class="btn btn-success" id="voteYesBtn"><i class="fa-solid fa-check"></i> Yes<span class="badge bg-secondary" id="voteYesLabel"></span></button> <button class="btn btn-danger" id="voteNoBtn"><i class="fa-solid fa-ban"></i> No<span class="badge bg-secondary" id="voteNoLabel"></span></button><br/>
|
<button class="btn btn-success" id="voteYesBtn"><i class="fa-solid fa-check"></i><span id="voteYesText">Yes</span><span class="badge bg-secondary" id="voteYesLabel"></span></button> <button class="btn btn-danger" id="voteNoBtn"><i class="fa-solid fa-ban"></i><span id="voteNoText">No</span><span class="badge bg-secondary" id="voteNoLabel"></span></button><br/>
|
||||||
Vote ends in <span id="votetime"></span> seconds<br/>
|
Vote ends in <span id="votetime"></span> seconds<br/>
|
||||||
<div id="forceVotePanel">
|
<div id="forceVotePanel">
|
||||||
<button class="btn btn-info" id="forceVoteYesBtn"><i class="fa-solid fa-check"></i> Pass Vote</button>
|
<button class="btn btn-info" id="forceVoteYesBtn"><i class="fa-solid fa-check"></i><span id="passVoteButtonText">Pass Vote</span></button>
|
||||||
<button class="btn btn-info" id="forceVoteNoBtn"><i class="fa-solid fa-ban"></i> Cancel Vote</button>
|
<button class="btn btn-info" id="forceVoteNoBtn"><i class="fa-solid fa-ban"></i><span id="cancelVoteButtonText">Cancel Vote</span></button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div id="btns">
|
<div id="btns">
|
||||||
<button class="btn btn-secondary" id="takeTurnBtn"><i class="fa-solid fa-computer-mouse"></i> Take Turn</button>
|
<button class="btn btn-secondary" id="takeTurnBtn"><i class="fa-solid fa-computer-mouse"></i><span id="takeTurnButtonText">Take Turn</span></button>
|
||||||
<button class="btn btn-secondary" id="changeUsernameBtn"><i class="fa-solid fa-signature"></i> Change Username</button>
|
<button class="btn btn-secondary" id="changeUsernameBtn"><i class="fa-solid fa-signature"></i><span id="changeUsernameButtonText">Change Username</span></button>
|
||||||
<button class="btn btn-secondary" id="voteResetButton"><i class="fa-solid fa-rotate-left"></i> Vote for Reset</button>
|
<button class="btn btn-secondary" id="voteResetButton"><i class="fa-solid fa-rotate-left"></i><span id="voteResetButtonText">Vote for Reset</span></button>
|
||||||
<button class="btn btn-secondary" id="screenshotButton"><i class="fa-solid fa-camera"></i> Screenshot</button>
|
<button class="btn btn-secondary" id="screenshotButton"><i class="fa-solid fa-camera"></i><span id="screenshotButtonText">Screenshot</span></button>
|
||||||
<button class="btn btn-secondary" id="ctrlAltDelBtn"><i class="fa-solid fa-gear"></i>Ctrl+Alt+Del</button>
|
<button class="btn btn-secondary" id="ctrlAltDelBtn"><i class="fa-solid fa-gear"></i>Ctrl+Alt+Del</button>
|
||||||
<div id="staffbtns">
|
<div id="staffbtns">
|
||||||
<button class="btn btn-secondary" id="restoreBtn"><i class="fa-solid fa-rotate-left"></i> Restore</button>
|
<button class="btn btn-secondary" id="restoreBtn"><i class="fa-solid fa-rotate-left"></i> Restore</button>
|
||||||
|
|
@ -111,7 +123,7 @@
|
||||||
<div class="table-responsive username-table">
|
<div class="table-responsive username-table">
|
||||||
<table class="table table-hover table-dark table-borderless">
|
<table class="table table-hover table-dark table-borderless">
|
||||||
<thead>
|
<thead>
|
||||||
<th><i class="fa-solid fa-user"></i> Users Online (<span id="onlineusercount"></span>)</th>
|
<th><i class="fa-solid fa-user"></i><span id="onlineUserText">Users Online</span> (<span id="onlineusercount"></span>)</th>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody id="userlist"></tbody>
|
<tbody id="userlist"></tbody>
|
||||||
</table>
|
</table>
|
||||||
|
|
|
||||||
22
dist/translations/de.json
vendored
Normal file
22
dist/translations/de.json
vendored
Normal file
|
|
@ -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."
|
||||||
|
}
|
||||||
22
dist/translations/en.json
vendored
Normal file
22
dist/translations/en.json
vendored
Normal file
|
|
@ -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"
|
||||||
|
}
|
||||||
91
src/i18n.js
Normal file
91
src/i18n.js
Normal file
|
|
@ -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)})`)
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
24
src/index.js
24
src/index.js
|
|
@ -4,6 +4,14 @@ import { GetKeysym } from "./keyboard";
|
||||||
import { createNanoEvents } from "nanoevents";
|
import { createNanoEvents } from "nanoevents";
|
||||||
import { makeperms } from "./permissions";
|
import { makeperms } from "./permissions";
|
||||||
import doCaptcha from "./captcha";
|
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
|
// None = -1
|
||||||
// Has turn = 0
|
// Has turn = 0
|
||||||
// In queue = <queue position>
|
// In queue = <queue position>
|
||||||
|
|
@ -275,7 +283,7 @@ class CollabVMClient {
|
||||||
curr.turn = -1;
|
curr.turn = -1;
|
||||||
curr.element.classList = "";
|
curr.element.classList = "";
|
||||||
});
|
});
|
||||||
buttons.takeTurn.innerHTML = "<i class=\"fa-solid fa-computer-mouse\"></i> Take Turn";
|
buttons.takeTurn.innerHTML = `<i class=\"fa-solid fa-computer-mouse\"></i><span id="takeTurnButtonText"> ${window.i18n.get("Take Turn")}</span>`;
|
||||||
turn = -1;
|
turn = -1;
|
||||||
if (!msgArr.includes(username))
|
if (!msgArr.includes(username))
|
||||||
turnstatus.innerText = "";
|
turnstatus.innerText = "";
|
||||||
|
|
@ -296,7 +304,7 @@ class CollabVMClient {
|
||||||
secs--;
|
secs--;
|
||||||
if (secs === 0)
|
if (secs === 0)
|
||||||
clearInterval(turninterval);
|
clearInterval(turninterval);
|
||||||
turnstatus.innerText = `Turn expires in ${secs} seconds.`;
|
turnstatus.innerText = `${window.i18n.get("Turn expires in # seconds.").replace("#", secs)}`;
|
||||||
}
|
}
|
||||||
turnUpdate();
|
turnUpdate();
|
||||||
turninterval = setInterval(turnUpdate, 1000);
|
turninterval = setInterval(turnUpdate, 1000);
|
||||||
|
|
@ -312,7 +320,7 @@ class CollabVMClient {
|
||||||
secs--;
|
secs--;
|
||||||
if (secs === 0)
|
if (secs === 0)
|
||||||
clearInterval(turninterval);
|
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);
|
turninterval = setInterval(turnUpdate, 1000);
|
||||||
turnUpdate();
|
turnUpdate();
|
||||||
|
|
@ -324,9 +332,9 @@ class CollabVMClient {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (turn === -1) {
|
if (turn === -1) {
|
||||||
buttons.takeTurn.innerHTML = "<i class=\"fa-solid fa-computer-mouse\"></i> Take Turn";
|
buttons.takeTurn.innerHTML = `<i class=\"fa-solid fa-computer-mouse\"></i><span id="takeTurnButtonText"> ${window.i18n.get("Take Turn")}</span>`;
|
||||||
} else {
|
} else {
|
||||||
buttons.takeTurn.innerHTML = "<i class=\"fa-solid fa-computer-mouse\"></i> End Turn";
|
buttons.takeTurn.innerHTML = `<i class=\"fa-solid fa-computer-mouse\"></i><span id="takeTurnButtonText"> ${window.i18n.get("End Turn")}</span>`;
|
||||||
}
|
}
|
||||||
this.reloadUsers();
|
this.reloadUsers();
|
||||||
break;
|
break;
|
||||||
|
|
@ -356,8 +364,8 @@ class CollabVMClient {
|
||||||
voteresetpanel.style.display = "none";
|
voteresetpanel.style.display = "none";
|
||||||
break;
|
break;
|
||||||
case "3":
|
case "3":
|
||||||
// too soon dumbass
|
// Vote is on cooldown
|
||||||
window.alert(`Please wait ${msgArr[2]} seconds before starting another vote.`);
|
window.alert(`${window.i18n.get("Please wait # seconds before starting another vote.").replace("#", msgArr[2])}`);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
@ -820,7 +828,7 @@ function sendChat() {
|
||||||
chatinput.value = "";
|
chatinput.value = "";
|
||||||
}
|
}
|
||||||
buttons.changeUsername.addEventListener('click', () => {
|
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;
|
if (newuser == null) return;
|
||||||
vm.rename(newuser);
|
vm.rename(newuser);
|
||||||
});
|
});
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user