Initial work on localization.

This commit is contained in:
Daniel Scalzi 2019-04-07 23:33:40 -04:00
parent a0520a9458
commit c141475404
No known key found for this signature in database
GPG Key ID: D18EA3FB4B142A57
8 changed files with 105 additions and 24 deletions

View File

@ -1,6 +1,6 @@
<html lang="en" xmlns="http://www.w3.org/1999/xhtml"> <html lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head> <head>
<meta charset="utf-8" http-equiv="Content-Security-Policy" content="script-src 'self'"/> <meta charset="utf-8" http-equiv="Content-Security-Policy" content="script-src 'self' 'sha256-In6B8teKZQll5heMl9bS7CESTbGvuAt3VVV86BUQBDk='"/>
<title>Westeroscraft Launcher</title> <title>Westeroscraft Launcher</title>
<script src="./assets/js/scripts/uicore.js"></script> <script src="./assets/js/scripts/uicore.js"></script>
<script src="./assets/js/scripts/uibinder.js"></script> <script src="./assets/js/scripts/uibinder.js"></script>
@ -43,5 +43,11 @@
</div> </div>
</div> </div>
</div> </div>
<script>
// Load language
for(let key of Object.keys(Lang.query('html'))){
document.getElementById(key).innerHTML = Lang.query(`html.${key}`)
}
</script>
</body> </body>
</html> </html>

View File

@ -0,0 +1,21 @@
const fs = require('fs-extra')
const path = require('path')
let lang
exports.loadLanguage = function(id){
lang = JSON.parse(fs.readFileSync(path.resolve('app', 'assets', 'lang', `${id}.json`))) || {}
}
exports.query = function(id){
let query = id.split('.')
let res = lang
for(let q of query){
res = res[q]
}
return res === lang ? {} : res
}
exports.queryJS = function(id){
return exports.query(`js.${id}`)
}

View File

@ -5,6 +5,7 @@ const path = require('path')
const ConfigManager = require('./configmanager') const ConfigManager = require('./configmanager')
const DistroManager = require('./distromanager') const DistroManager = require('./distromanager')
const LangLoader = require('./langloader')
const logger = require('./loggerutil')('%c[Preloader]', 'color: #a02d2a; font-weight: bold') const logger = require('./loggerutil')('%c[Preloader]', 'color: #a02d2a; font-weight: bold')
logger.log('Loading..') logger.log('Loading..')
@ -12,6 +13,9 @@ logger.log('Loading..')
// Load ConfigManager // Load ConfigManager
ConfigManager.load() ConfigManager.load()
// Load Strings
LangLoader.loadLanguage('en_US')
function onDistroLoad(data){ function onDistroLoad(data){
if(data != null){ if(data != null){

View File

@ -92,7 +92,7 @@ document.getElementById('launch_button').addEventListener('click', function(e){
asyncSystemScan(mcVersion) asyncSystemScan(mcVersion)
} else { } else {
setLaunchDetails('Please wait..') setLaunchDetails(Lang.queryJS('landing.launch.pleaseWait'))
toggleLaunchArea(true) toggleLaunchArea(true)
setLaunchPercentage(0, 100) setLaunchPercentage(0, 100)

View File

@ -56,7 +56,7 @@ function shakeError(element){
function validateEmail(value){ function validateEmail(value){
if(value){ if(value){
if(!basicEmail.test(value) && !validUsername.test(value)){ if(!basicEmail.test(value) && !validUsername.test(value)){
showError(loginEmailError, '* Invalid Value') showError(loginEmailError, Lang.queryJS('login.error.invalidValue'))
loginDisabled(true) loginDisabled(true)
lu = false lu = false
} else { } else {
@ -68,7 +68,7 @@ function validateEmail(value){
} }
} else { } else {
lu = false lu = false
showError(loginEmailError, '* Required') showError(loginEmailError, Lang.queryJS('login.error.requiredValue'))
loginDisabled(true) loginDisabled(true)
} }
} }
@ -87,7 +87,7 @@ function validatePassword(value){
} }
} else { } else {
lp = false lp = false
showError(loginPasswordError, '* Required') showError(loginPasswordError, Lang.queryJS('login.error.invalidValue'))
loginDisabled(true) loginDisabled(true)
} }
} }
@ -129,10 +129,10 @@ function loginDisabled(v){
function loginLoading(v){ function loginLoading(v){
if(v){ if(v){
loginButton.setAttribute('loading', v) loginButton.setAttribute('loading', v)
loginButton.innerHTML = loginButton.innerHTML.replace('LOGIN', 'LOGGING IN') loginButton.innerHTML = loginButton.innerHTML.replace(Lang.queryJS('login.login'), Lang.queryJS('login.loggingIn'))
} else { } else {
loginButton.removeAttribute('loading') loginButton.removeAttribute('loading')
loginButton.innerHTML = loginButton.innerHTML.replace('LOGGING IN', 'LOGIN') loginButton.innerHTML = loginButton.innerHTML.replace(Lang.queryJS('login.loggingIn'), Lang.queryJS('login.login'))
} }
} }
@ -166,8 +166,8 @@ function resolveError(err){
// Node error => err.code | err.message // Node error => err.code | err.message
if(err.cause != null && err.cause === 'UserMigratedException') { if(err.cause != null && err.cause === 'UserMigratedException') {
return { return {
title: 'Error During Login:<br>Invalid Credentials', title: Lang.queryJS('login.error.userMigrated.title'),
desc: 'You\'ve attempted to login with a migrated account. Try again using the account email as the username.' desc: Lang.queryJS('login.error.userMigrated.desc')
} }
} else { } else {
if(err.error != null){ if(err.error != null){
@ -175,13 +175,13 @@ function resolveError(err){
if(err.errorMessage != null){ if(err.errorMessage != null){
if(err.errorMessage === 'Invalid credentials. Invalid username or password.'){ if(err.errorMessage === 'Invalid credentials. Invalid username or password.'){
return { return {
title: 'Error During Login:<br>Invalid Credentials', title: Lang.queryJS('login.error.invalidCredentials.title'),
desc: 'The email or password you\'ve entered is incorrect. Please try again.' desc: Lang.queryJS('login.error.invalidCredentials.desc')
} }
} else if(err.errorMessage === 'Invalid credentials.'){ } else if(err.errorMessage === 'Invalid credentials.'){
return { return {
title: 'Error During Login:<br>Too Many Attempts', title: Lang.queryJS('login.error.rateLimit.title'),
desc: 'There have been too many login attempts with this account recently. Please try again later.' desc: Lang.queryJS('login.error.rateLimit.desc')
} }
} }
} }
@ -192,14 +192,14 @@ function resolveError(err){
if(err.code === 'ENOENT'){ if(err.code === 'ENOENT'){
// No Internet. // No Internet.
return { return {
title: 'Error During Login:<br>No Internet Connection', title: Lang.queryJS('login.error.noInternet.title'),
desc: 'You must be connected to the internet in order to login. Please connect and try again.' desc: Lang.queryJS('login.error.noInternet.desc')
} }
} else if(err.code === 'ENOTFOUND'){ } else if(err.code === 'ENOTFOUND'){
// Could not reach server. // Could not reach server.
return { return {
title: 'Error During Login:<br>Authentication Server Offline', title: Lang.queryJS('login.error.authDown.title'),
desc: 'Mojang\'s authentication server is currently offline or unreachable. Please wait a bit and try again. You can check the status of the server on <a href="https://help.mojang.com/">Mojang\'s help portal</a>.' desc: Lang.queryJS('login.error.authDown.desc')
} }
} }
} }
@ -208,13 +208,13 @@ function resolveError(err){
if(err.message != null){ if(err.message != null){
if(err.message === 'NotPaidAccount'){ if(err.message === 'NotPaidAccount'){
return { return {
title: 'Error During Login:<br>Game Not Purchased', title: Lang.queryJS('login.error.notPaid.title'),
desc: 'The account you are trying to login with has not purchased a copy of Minecraft.<br>You may purchase a copy on <a href="https://minecraft.net/">Minecraft.net</a>' desc: Lang.queryJS('login.error.notPaid.desc')
} }
} else { } else {
// Unknown error with request. // Unknown error with request.
return { return {
title: 'Error During Login:<br>Unknown Error', title: Lang.queryJS('login.error.unknown.title'),
desc: err.message desc: err.message
} }
} }
@ -264,7 +264,7 @@ loginButton.addEventListener('click', () => {
AuthManager.addAccount(loginUsername.value, loginPassword.value).then((value) => { AuthManager.addAccount(loginUsername.value, loginPassword.value).then((value) => {
updateSelectedAccount(value) updateSelectedAccount(value)
loginButton.innerHTML = loginButton.innerHTML.replace('LOGGING IN', 'SUCCESS') loginButton.innerHTML = loginButton.innerHTML.replace(Lang.queryJS('login.loggingIn'), Lang.queryJS('login.success'))
$('.circle-loader').toggleClass('load-complete') $('.circle-loader').toggleClass('load-complete')
$('.checkmark').toggle() $('.checkmark').toggle()
setTimeout(() => { setTimeout(() => {
@ -281,14 +281,14 @@ loginButton.addEventListener('click', () => {
$('.circle-loader').toggleClass('load-complete') $('.circle-loader').toggleClass('load-complete')
$('.checkmark').toggle() $('.checkmark').toggle()
loginLoading(false) loginLoading(false)
loginButton.innerHTML = loginButton.innerHTML.replace('SUCCESS', 'LOGIN') loginButton.innerHTML = loginButton.innerHTML.replace(Lang.queryJS('login.success'), Lang.queryJS('login.login'))
formDisabled(false) formDisabled(false)
}) })
}, 1000) }, 1000)
}).catch((err) => { }).catch((err) => {
loginLoading(false) loginLoading(false)
const errF = resolveError(err) const errF = resolveError(err)
setOverlayContent(errF.title, errF.desc, 'Try Again') setOverlayContent(errF.title, errF.desc, Lang.queryJS('login.tryAgain'))
setOverlayHandler(() => { setOverlayHandler(() => {
formDisabled(false) formDisabled(false)
toggleOverlay(false) toggleOverlay(false)

View File

@ -8,6 +8,7 @@ const path = require('path')
const AuthManager = require('./assets/js/authmanager') const AuthManager = require('./assets/js/authmanager')
const ConfigManager = require('./assets/js/configmanager') const ConfigManager = require('./assets/js/configmanager')
const DistroManager = require('./assets/js/distromanager') const DistroManager = require('./assets/js/distromanager')
const Lang = require('./assets/js/langloader')
let rscShouldLoad = false let rscShouldLoad = false
let fatalStartupError = false let fatalStartupError = false

View File

@ -0,0 +1,49 @@
{
"html": {
"avatarOverlay": "Dankname"
},
"js": {
"login": {
"error": {
"invalidValue": "* Invalid Value",
"requiredValue": "* Required",
"userMigrated": {
"title": "Error During Login:<br>Invalid Credentials",
"desc": "You've attempted to login with a migrated account. Try again using the account email as the username."
},
"invalidCredentials": {
"title": "Error During Login:<br>Invalid Credentials",
"desc": "The email or password you've entered is incorrect. Please try again."
},
"rateLimit": {
"title": "Error During Login:<br>Too Many Attempts",
"desc": "There have been too many login attempts with this account recently. Please try again later."
},
"noInternet": {
"title": "Error During Login:<br>No Internet Connection",
"desc": "You must be connected to the internet in order to login. Please connect and try again."
},
"authDown": {
"title": "Error During Login:<br>Authentication Server Offline",
"desc": "Mojang's authentication server is currently offline or unreachable. Please wait a bit and try again. You can check the status of the server on <a href=\"https://help.mojang.com/\">Mojang's help portal</a>."
},
"notPaid": {
"title": "Error During Login:<br>Game Not Purchased",
"desc": "The account you are trying to login with has not purchased a copy of Minecraft.<br>You may purchase a copy on <a href=\"https://minecraft.net/\">Minecraft.net</a>"
},
"unknown": {
"title": "Error During Login:<br>Unknown Error"
}
},
"login": "LOGIN",
"loggingIn": "LOGGING IN",
"success": "SUCCESS",
"tryAgain": "Try Again"
},
"landing": {
"launch": {
"pleaseWait": "Please wait.."
}
}
}
}

View File

@ -1,3 +1,3 @@
owner: WesterosCraftCode owner: dscalzi
repo: ElectronLauncher repo: ElectronLauncher
provider: github provider: github