diff --git a/app/app.ejs b/app/app.ejs
index f30df0e..91becc3 100644
--- a/app/app.ejs
+++ b/app/app.ejs
@@ -1,6 +1,6 @@
-
+
Westeroscraft Launcher
@@ -43,5 +43,11 @@
+
\ No newline at end of file
diff --git a/app/assets/js/langloader.js b/app/assets/js/langloader.js
new file mode 100644
index 0000000..4e13d93
--- /dev/null
+++ b/app/assets/js/langloader.js
@@ -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}`)
+}
\ No newline at end of file
diff --git a/app/assets/js/preloader.js b/app/assets/js/preloader.js
index c6307b6..792c530 100644
--- a/app/assets/js/preloader.js
+++ b/app/assets/js/preloader.js
@@ -5,6 +5,7 @@ const path = require('path')
const ConfigManager = require('./configmanager')
const DistroManager = require('./distromanager')
+const LangLoader = require('./langloader')
const logger = require('./loggerutil')('%c[Preloader]', 'color: #a02d2a; font-weight: bold')
logger.log('Loading..')
@@ -12,6 +13,9 @@ logger.log('Loading..')
// Load ConfigManager
ConfigManager.load()
+// Load Strings
+LangLoader.loadLanguage('en_US')
+
function onDistroLoad(data){
if(data != null){
diff --git a/app/assets/js/scripts/landing.js b/app/assets/js/scripts/landing.js
index 5affa8b..247f635 100644
--- a/app/assets/js/scripts/landing.js
+++ b/app/assets/js/scripts/landing.js
@@ -92,7 +92,7 @@ document.getElementById('launch_button').addEventListener('click', function(e){
asyncSystemScan(mcVersion)
} else {
- setLaunchDetails('Please wait..')
+ setLaunchDetails(Lang.queryJS('landing.launch.pleaseWait'))
toggleLaunchArea(true)
setLaunchPercentage(0, 100)
diff --git a/app/assets/js/scripts/login.js b/app/assets/js/scripts/login.js
index 67e7a58..34078bd 100644
--- a/app/assets/js/scripts/login.js
+++ b/app/assets/js/scripts/login.js
@@ -56,7 +56,7 @@ function shakeError(element){
function validateEmail(value){
if(value){
if(!basicEmail.test(value) && !validUsername.test(value)){
- showError(loginEmailError, '* Invalid Value')
+ showError(loginEmailError, Lang.queryJS('login.error.invalidValue'))
loginDisabled(true)
lu = false
} else {
@@ -68,7 +68,7 @@ function validateEmail(value){
}
} else {
lu = false
- showError(loginEmailError, '* Required')
+ showError(loginEmailError, Lang.queryJS('login.error.requiredValue'))
loginDisabled(true)
}
}
@@ -87,7 +87,7 @@ function validatePassword(value){
}
} else {
lp = false
- showError(loginPasswordError, '* Required')
+ showError(loginPasswordError, Lang.queryJS('login.error.invalidValue'))
loginDisabled(true)
}
}
@@ -129,10 +129,10 @@ function loginDisabled(v){
function loginLoading(v){
if(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 {
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
if(err.cause != null && err.cause === 'UserMigratedException') {
return {
- title: 'Error During Login:
Invalid Credentials',
- desc: 'You\'ve attempted to login with a migrated account. Try again using the account email as the username.'
+ title: Lang.queryJS('login.error.userMigrated.title'),
+ desc: Lang.queryJS('login.error.userMigrated.desc')
}
} else {
if(err.error != null){
@@ -175,13 +175,13 @@ function resolveError(err){
if(err.errorMessage != null){
if(err.errorMessage === 'Invalid credentials. Invalid username or password.'){
return {
- title: 'Error During Login:
Invalid Credentials',
- desc: 'The email or password you\'ve entered is incorrect. Please try again.'
+ title: Lang.queryJS('login.error.invalidCredentials.title'),
+ desc: Lang.queryJS('login.error.invalidCredentials.desc')
}
} else if(err.errorMessage === 'Invalid credentials.'){
return {
- title: 'Error During Login:
Too Many Attempts',
- desc: 'There have been too many login attempts with this account recently. Please try again later.'
+ title: Lang.queryJS('login.error.rateLimit.title'),
+ desc: Lang.queryJS('login.error.rateLimit.desc')
}
}
}
@@ -192,14 +192,14 @@ function resolveError(err){
if(err.code === 'ENOENT'){
// No Internet.
return {
- title: 'Error During Login:
No Internet Connection',
- desc: 'You must be connected to the internet in order to login. Please connect and try again.'
+ title: Lang.queryJS('login.error.noInternet.title'),
+ desc: Lang.queryJS('login.error.noInternet.desc')
}
} else if(err.code === 'ENOTFOUND'){
// Could not reach server.
return {
- title: 'Error During Login:
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 Mojang\'s help portal.'
+ title: Lang.queryJS('login.error.authDown.title'),
+ desc: Lang.queryJS('login.error.authDown.desc')
}
}
}
@@ -208,13 +208,13 @@ function resolveError(err){
if(err.message != null){
if(err.message === 'NotPaidAccount'){
return {
- title: 'Error During Login:
Game Not Purchased',
- desc: 'The account you are trying to login with has not purchased a copy of Minecraft.
You may purchase a copy on Minecraft.net'
+ title: Lang.queryJS('login.error.notPaid.title'),
+ desc: Lang.queryJS('login.error.notPaid.desc')
}
} else {
// Unknown error with request.
return {
- title: 'Error During Login:
Unknown Error',
+ title: Lang.queryJS('login.error.unknown.title'),
desc: err.message
}
}
@@ -264,7 +264,7 @@ loginButton.addEventListener('click', () => {
AuthManager.addAccount(loginUsername.value, loginPassword.value).then((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')
$('.checkmark').toggle()
setTimeout(() => {
@@ -281,14 +281,14 @@ loginButton.addEventListener('click', () => {
$('.circle-loader').toggleClass('load-complete')
$('.checkmark').toggle()
loginLoading(false)
- loginButton.innerHTML = loginButton.innerHTML.replace('SUCCESS', 'LOGIN')
+ loginButton.innerHTML = loginButton.innerHTML.replace(Lang.queryJS('login.success'), Lang.queryJS('login.login'))
formDisabled(false)
})
}, 1000)
}).catch((err) => {
loginLoading(false)
const errF = resolveError(err)
- setOverlayContent(errF.title, errF.desc, 'Try Again')
+ setOverlayContent(errF.title, errF.desc, Lang.queryJS('login.tryAgain'))
setOverlayHandler(() => {
formDisabled(false)
toggleOverlay(false)
diff --git a/app/assets/js/scripts/uibinder.js b/app/assets/js/scripts/uibinder.js
index 78adddf..0b080d1 100644
--- a/app/assets/js/scripts/uibinder.js
+++ b/app/assets/js/scripts/uibinder.js
@@ -8,6 +8,7 @@ const path = require('path')
const AuthManager = require('./assets/js/authmanager')
const ConfigManager = require('./assets/js/configmanager')
const DistroManager = require('./assets/js/distromanager')
+const Lang = require('./assets/js/langloader')
let rscShouldLoad = false
let fatalStartupError = false
diff --git a/app/assets/lang/en_US.json b/app/assets/lang/en_US.json
new file mode 100644
index 0000000..46b5a3d
--- /dev/null
+++ b/app/assets/lang/en_US.json
@@ -0,0 +1,49 @@
+{
+ "html": {
+ "avatarOverlay": "Dankname"
+ },
+ "js": {
+ "login": {
+ "error": {
+ "invalidValue": "* Invalid Value",
+ "requiredValue": "* Required",
+ "userMigrated": {
+ "title": "Error During Login:
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:
Invalid Credentials",
+ "desc": "The email or password you've entered is incorrect. Please try again."
+ },
+ "rateLimit": {
+ "title": "Error During Login:
Too Many Attempts",
+ "desc": "There have been too many login attempts with this account recently. Please try again later."
+ },
+ "noInternet": {
+ "title": "Error During Login:
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:
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 Mojang's help portal."
+ },
+ "notPaid": {
+ "title": "Error During Login:
Game Not Purchased",
+ "desc": "The account you are trying to login with has not purchased a copy of Minecraft.
You may purchase a copy on Minecraft.net"
+ },
+ "unknown": {
+ "title": "Error During Login:
Unknown Error"
+ }
+ },
+ "login": "LOGIN",
+ "loggingIn": "LOGGING IN",
+ "success": "SUCCESS",
+ "tryAgain": "Try Again"
+ },
+ "landing": {
+ "launch": {
+ "pleaseWait": "Please wait.."
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/dev-app-update.yml b/dev-app-update.yml
index 60dd682..ba0abe7 100644
--- a/dev-app-update.yml
+++ b/dev-app-update.yml
@@ -1,3 +1,3 @@
-owner: WesterosCraftCode
+owner: dscalzi
repo: ElectronLauncher
provider: github