initial i18n implementation
This commit is contained in:
parent
1f89ed75c1
commit
746b7fc018
38
dist/index.html
vendored
38
dist/index.html
vendored
|
|
@ -55,13 +55,13 @@
|
|||
<div class="collapse navbar-collapse" id="navbarNav">
|
||||
<ul class="navbar-nav">
|
||||
<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 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 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 class="nav-item">
|
||||
<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">
|
||||
<a href="https://computernewb.com/collab-vm/user-vm" class="nav-link"><i class="fa-solid fa-user"></i> UserVM</a>
|
||||
</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>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -83,20 +95,20 @@
|
|||
<canvas id="display" height="0" width="0" tabindex="-1"></canvas>
|
||||
<p id="turnstatus" class="text-light"></p>
|
||||
<div id="voteResetPanel" class="bg-dark text-light" style="display:none;">
|
||||
Do you want to reset the vm?<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/>
|
||||
<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><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/>
|
||||
<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="forceVoteNoBtn"><i class="fa-solid fa-ban"></i> Cancel 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><span id="cancelVoteButtonText">Cancel Vote</span></button>
|
||||
</div>
|
||||
</div>
|
||||
<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="changeUsernameBtn"><i class="fa-solid fa-signature"></i> Change Username</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="screenshotButton"><i class="fa-solid fa-camera"></i> Screenshot</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="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><span id="changeUsernameButtonText">Change Username</span></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><span id="screenshotButtonText">Screenshot</span></button>
|
||||
<button class="btn btn-secondary" id="ctrlAltDelBtn"><i class="fa-solid fa-gear"></i>Ctrl+Alt+Del</button>
|
||||
<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="rebootBtn"><i class="fa-solid fa-power-off"></i> Reboot</button>
|
||||
|
|
@ -111,7 +123,7 @@
|
|||
<div class="table-responsive username-table">
|
||||
<table class="table table-hover table-dark table-borderless">
|
||||
<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>
|
||||
<tbody id="userlist"></tbody>
|
||||
</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 { 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 = <queue position>
|
||||
|
|
@ -275,7 +283,7 @@ class CollabVMClient {
|
|||
curr.turn = -1;
|
||||
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;
|
||||
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 = "<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 {
|
||||
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();
|
||||
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);
|
||||
});
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user