Add files via upload
This commit is contained in:
parent
6c0e851f2b
commit
bf8ecb8f8a
File diff suppressed because it is too large
Load Diff
@ -1,300 +1,300 @@
|
|||||||
/**
|
/**
|
||||||
* Script for login.ejs
|
* Script for login.ejs
|
||||||
*/
|
*/
|
||||||
// Validation Regexes.
|
// Validation Regexes.
|
||||||
const validUsername = /^[a-zA-Z0-9_]{1,16}$/
|
const validUsername = /^[a-zA-Z0-9_]{1,16}$/
|
||||||
const basicEmail = /^\S+@\S+\.\S+$/
|
const basicEmail = /^\S+@\S+\.\S+$/
|
||||||
//const validEmail = /^(([^<>()\[\]\.,;:\s@\"]+(\.[^<>()\[\]\.,;:\s@\"]+)*)|(\".+\"))@(([^<>()[\]\.,;:\s@\"]+\.)+[^<>()[\]\.,;:\s@\"]{2,})$/i
|
//const validEmail = /^(([^<>()\[\]\.,;:\s@\"]+(\.[^<>()\[\]\.,;:\s@\"]+)*)|(\".+\"))@(([^<>()[\]\.,;:\s@\"]+\.)+[^<>()[\]\.,;:\s@\"]{2,})$/i
|
||||||
|
|
||||||
// Login Elements
|
// Login Elements
|
||||||
const loginCancelContainer = document.getElementById('loginCancelContainer')
|
const loginCancelContainer = document.getElementById('loginCancelContainer')
|
||||||
const loginCancelButton = document.getElementById('loginCancelButton')
|
const loginCancelButton = document.getElementById('loginCancelButton')
|
||||||
const loginEmailError = document.getElementById('loginEmailError')
|
const loginEmailError = document.getElementById('loginEmailError')
|
||||||
const loginUsername = document.getElementById('loginUsername')
|
const loginUsername = document.getElementById('loginUsername')
|
||||||
const loginPasswordError = document.getElementById('loginPasswordError')
|
const loginPasswordError = document.getElementById('loginPasswordError')
|
||||||
const loginPassword = document.getElementById('loginPassword')
|
const loginPassword = document.getElementById('loginPassword')
|
||||||
const checkmarkContainer = document.getElementById('checkmarkContainer')
|
const checkmarkContainer = document.getElementById('checkmarkContainer')
|
||||||
const loginRememberOption = document.getElementById('loginRememberOption')
|
const loginRememberOption = document.getElementById('loginRememberOption')
|
||||||
const loginButton = document.getElementById('loginButton')
|
const loginButton = document.getElementById('loginButton')
|
||||||
const loginForm = document.getElementById('loginForm')
|
const loginForm = document.getElementById('loginForm')
|
||||||
|
|
||||||
// Control variables.
|
// Control variables.
|
||||||
let lu = false, lp = false
|
let lu = false, lp = false
|
||||||
|
|
||||||
const loggerLogin = LoggerUtil('%c[Login]', 'color: #000668; font-weight: bold')
|
const loggerLogin = LoggerUtil('%c[Login]', 'color: #000668; font-weight: bold')
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Show a login error.
|
* Show a login error.
|
||||||
*
|
*
|
||||||
* @param {HTMLElement} element The element on which to display the error.
|
* @param {HTMLElement} element The element on which to display the error.
|
||||||
* @param {string} value The error text.
|
* @param {string} value The error text.
|
||||||
*/
|
*/
|
||||||
function showError(element, value){
|
function showError(element, value){
|
||||||
element.innerHTML = value
|
element.innerHTML = value
|
||||||
element.style.opacity = 1
|
element.style.opacity = 1
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Shake a login error to add emphasis.
|
* Shake a login error to add emphasis.
|
||||||
*
|
*
|
||||||
* @param {HTMLElement} element The element to shake.
|
* @param {HTMLElement} element The element to shake.
|
||||||
*/
|
*/
|
||||||
function shakeError(element){
|
function shakeError(element){
|
||||||
if(element.style.opacity == 1){
|
if(element.style.opacity == 1){
|
||||||
element.classList.remove('shake')
|
element.classList.remove('shake')
|
||||||
void element.offsetWidth
|
void element.offsetWidth
|
||||||
element.classList.add('shake')
|
element.classList.add('shake')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Validate that an email field is neither empty nor invalid.
|
* Validate that an email field is neither empty nor invalid.
|
||||||
*
|
*
|
||||||
* @param {string} value The email value.
|
* @param {string} value The email value.
|
||||||
*/
|
*/
|
||||||
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, Lang.queryJS('login.error.invalidValue'))
|
showError(loginEmailError, Lang.queryJS('login.error.invalidValue'))
|
||||||
loginDisabled(true)
|
loginDisabled(true)
|
||||||
lu = false
|
lu = false
|
||||||
} else {
|
} else {
|
||||||
loginEmailError.style.opacity = 0
|
loginEmailError.style.opacity = 0
|
||||||
lu = true
|
lu = true
|
||||||
if(lp){
|
if(lp){
|
||||||
loginDisabled(false)
|
loginDisabled(false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
lu = false
|
lu = false
|
||||||
showError(loginEmailError, Lang.queryJS('login.error.requiredValue'))
|
showError(loginEmailError, Lang.queryJS('login.error.requiredValue'))
|
||||||
loginDisabled(true)
|
loginDisabled(true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Validate that the password field is not empty.
|
* Validate that the password field is not empty.
|
||||||
*
|
*
|
||||||
* @param {string} value The password value.
|
* @param {string} value The password value.
|
||||||
*/
|
*/
|
||||||
function validatePassword(value){
|
function validatePassword(value){
|
||||||
if(value){
|
if(value){
|
||||||
loginPasswordError.style.opacity = 0
|
loginPasswordError.style.opacity = 0
|
||||||
lp = true
|
lp = true
|
||||||
if(lu){
|
if(lu){
|
||||||
loginDisabled(false)
|
loginDisabled(false)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
lp = false
|
lp = false
|
||||||
showError(loginPasswordError, Lang.queryJS('login.error.invalidValue'))
|
showError(loginPasswordError, Lang.queryJS('login.error.invalidValue'))
|
||||||
loginDisabled(true)
|
loginDisabled(true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Emphasize errors with shake when focus is lost.
|
// Emphasize errors with shake when focus is lost.
|
||||||
loginUsername.addEventListener('focusout', (e) => {
|
loginUsername.addEventListener('focusout', (e) => {
|
||||||
validateEmail(e.target.value)
|
validateEmail(e.target.value)
|
||||||
shakeError(loginEmailError)
|
shakeError(loginEmailError)
|
||||||
})
|
})
|
||||||
loginPassword.addEventListener('focusout', (e) => {
|
loginPassword.addEventListener('focusout', (e) => {
|
||||||
validatePassword(e.target.value)
|
validatePassword(e.target.value)
|
||||||
shakeError(loginPasswordError)
|
shakeError(loginPasswordError)
|
||||||
})
|
})
|
||||||
|
|
||||||
// Validate input for each field.
|
// Validate input for each field.
|
||||||
loginUsername.addEventListener('input', (e) => {
|
loginUsername.addEventListener('input', (e) => {
|
||||||
validateEmail(e.target.value)
|
validateEmail(e.target.value)
|
||||||
})
|
})
|
||||||
loginPassword.addEventListener('input', (e) => {
|
loginPassword.addEventListener('input', (e) => {
|
||||||
validatePassword(e.target.value)
|
validatePassword(e.target.value)
|
||||||
})
|
})
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Enable or disable the login button.
|
* Enable or disable the login button.
|
||||||
*
|
*
|
||||||
* @param {boolean} v True to enable, false to disable.
|
* @param {boolean} v True to enable, false to disable.
|
||||||
*/
|
*/
|
||||||
function loginDisabled(v){
|
function loginDisabled(v){
|
||||||
if(loginButton.disabled !== v){
|
if(loginButton.disabled !== v){
|
||||||
loginButton.disabled = v
|
loginButton.disabled = v
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Enable or disable loading elements.
|
* Enable or disable loading elements.
|
||||||
*
|
*
|
||||||
* @param {boolean} v True to enable, false to disable.
|
* @param {boolean} v True to enable, false to disable.
|
||||||
*/
|
*/
|
||||||
function loginLoading(v){
|
function loginLoading(v){
|
||||||
if(v){
|
if(v){
|
||||||
loginButton.setAttribute('loading', v)
|
loginButton.setAttribute('loading', v)
|
||||||
loginButton.innerHTML = loginButton.innerHTML.replace(Lang.queryJS('login.login'), Lang.queryJS('login.loggingIn'))
|
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(Lang.queryJS('login.loggingIn'), Lang.queryJS('login.login'))
|
loginButton.innerHTML = loginButton.innerHTML.replace(Lang.queryJS('login.loggingIn'), Lang.queryJS('login.login'))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Enable or disable login form.
|
* Enable or disable login form.
|
||||||
*
|
*
|
||||||
* @param {boolean} v True to enable, false to disable.
|
* @param {boolean} v True to enable, false to disable.
|
||||||
*/
|
*/
|
||||||
function formDisabled(v){
|
function formDisabled(v){
|
||||||
loginDisabled(v)
|
loginDisabled(v)
|
||||||
loginCancelButton.disabled = v
|
loginCancelButton.disabled = v
|
||||||
loginUsername.disabled = v
|
loginUsername.disabled = v
|
||||||
loginPassword.disabled = v
|
loginPassword.disabled = v
|
||||||
if(v){
|
if(v){
|
||||||
checkmarkContainer.setAttribute('disabled', v)
|
checkmarkContainer.setAttribute('disabled', v)
|
||||||
} else {
|
} else {
|
||||||
checkmarkContainer.removeAttribute('disabled')
|
checkmarkContainer.removeAttribute('disabled')
|
||||||
}
|
}
|
||||||
loginRememberOption.disabled = v
|
loginRememberOption.disabled = v
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parses an error and returns a user-friendly title and description
|
* Parses an error and returns a user-friendly title and description
|
||||||
* for our error overlay.
|
* for our error overlay.
|
||||||
*
|
*
|
||||||
* @param {Error | {cause: string, error: string, errorMessage: string}} err A Node.js
|
* @param {Error | {cause: string, error: string, errorMessage: string}} err A Node.js
|
||||||
* error or Mojang error response.
|
* error or Mojang error response.
|
||||||
*/
|
*/
|
||||||
function resolveError(err){
|
function resolveError(err){
|
||||||
// Mojang Response => err.cause | err.error | err.errorMessage
|
// Mojang Response => err.cause | err.error | err.errorMessage
|
||||||
// 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: Lang.queryJS('login.error.userMigrated.title'),
|
title: Lang.queryJS('login.error.userMigrated.title'),
|
||||||
desc: Lang.queryJS('login.error.userMigrated.desc')
|
desc: Lang.queryJS('login.error.userMigrated.desc')
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if(err.error != null){
|
if(err.error != null){
|
||||||
if(err.error === 'ForbiddenOperationException'){
|
if(err.error === 'ForbiddenOperationException'){
|
||||||
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: Lang.queryJS('login.error.invalidCredentials.title'),
|
title: Lang.queryJS('login.error.invalidCredentials.title'),
|
||||||
desc: Lang.queryJS('login.error.invalidCredentials.desc')
|
desc: Lang.queryJS('login.error.invalidCredentials.desc')
|
||||||
}
|
}
|
||||||
} else if(err.errorMessage === 'Invalid credentials.'){
|
} else if(err.errorMessage === 'Invalid credentials.'){
|
||||||
return {
|
return {
|
||||||
title: Lang.queryJS('login.error.rateLimit.title'),
|
title: Lang.queryJS('login.error.rateLimit.title'),
|
||||||
desc: Lang.queryJS('login.error.rateLimit.desc')
|
desc: Lang.queryJS('login.error.rateLimit.desc')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Request errors (from Node).
|
// Request errors (from Node).
|
||||||
if(err.code != null){
|
if(err.code != null){
|
||||||
if(err.code === 'ENOENT'){
|
if(err.code === 'ENOENT'){
|
||||||
// No Internet.
|
// No Internet.
|
||||||
return {
|
return {
|
||||||
title: Lang.queryJS('login.error.noInternet.title'),
|
title: Lang.queryJS('login.error.noInternet.title'),
|
||||||
desc: Lang.queryJS('login.error.noInternet.desc')
|
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: Lang.queryJS('login.error.authDown.title'),
|
title: Lang.queryJS('login.error.authDown.title'),
|
||||||
desc: Lang.queryJS('login.error.authDown.desc')
|
desc: Lang.queryJS('login.error.authDown.desc')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(err.message != null){
|
if(err.message != null){
|
||||||
if(err.message === 'NotPaidAccount'){
|
if(err.message === 'NotPaidAccount'){
|
||||||
return {
|
return {
|
||||||
title: Lang.queryJS('login.error.notPaid.title'),
|
title: Lang.queryJS('login.error.notPaid.title'),
|
||||||
desc: Lang.queryJS('login.error.notPaid.desc')
|
desc: Lang.queryJS('login.error.notPaid.desc')
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Unknown error with request.
|
// Unknown error with request.
|
||||||
return {
|
return {
|
||||||
title: Lang.queryJS('login.error.unknown.title'),
|
title: Lang.queryJS('login.error.unknown.title'),
|
||||||
desc: err.message
|
desc: err.message
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Unknown Mojang error.
|
// Unknown Mojang error.
|
||||||
return {
|
return {
|
||||||
title: err.error,
|
title: err.error,
|
||||||
desc: err.errorMessage
|
desc: err.errorMessage
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let loginViewOnSuccess = VIEWS.landing
|
let loginViewOnSuccess = VIEWS.landing
|
||||||
let loginViewOnCancel = VIEWS.settings
|
let loginViewOnCancel = VIEWS.settings
|
||||||
let loginViewCancelHandler
|
let loginViewCancelHandler
|
||||||
|
|
||||||
function loginCancelEnabled(val){
|
function loginCancelEnabled(val){
|
||||||
if(val){
|
if(val){
|
||||||
$(loginCancelContainer).show()
|
$(loginCancelContainer).show()
|
||||||
} else {
|
} else {
|
||||||
$(loginCancelContainer).hide()
|
$(loginCancelContainer).hide()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
loginCancelButton.onclick = (e) => {
|
loginCancelButton.onclick = (e) => {
|
||||||
switchView(getCurrentView(), loginViewOnCancel, 500, 500, () => {
|
switchView(getCurrentView(), loginViewOnCancel, 500, 500, () => {
|
||||||
loginUsername.value = ''
|
loginUsername.value = ''
|
||||||
loginPassword.value = ''
|
loginPassword.value = ''
|
||||||
loginCancelEnabled(false)
|
loginCancelEnabled(false)
|
||||||
if(loginViewCancelHandler != null){
|
if(loginViewCancelHandler != null){
|
||||||
loginViewCancelHandler()
|
loginViewCancelHandler()
|
||||||
loginViewCancelHandler = null
|
loginViewCancelHandler = null
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// Disable default form behavior.
|
// Disable default form behavior.
|
||||||
loginForm.onsubmit = () => { return false }
|
loginForm.onsubmit = () => { return false }
|
||||||
|
|
||||||
// Bind login button behavior.
|
// Bind login button behavior.
|
||||||
loginButton.addEventListener('click', () => {
|
loginButton.addEventListener('click', () => {
|
||||||
// Disable form.
|
// Disable form.
|
||||||
formDisabled(true)
|
formDisabled(true)
|
||||||
|
|
||||||
// Show loading stuff.
|
// Show loading stuff.
|
||||||
loginLoading(true)
|
loginLoading(true)
|
||||||
|
|
||||||
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(Lang.queryJS('login.loggingIn'), Lang.queryJS('login.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(() => {
|
||||||
switchView(VIEWS.login, loginViewOnSuccess, 500, 500, () => {
|
switchView(VIEWS.login, loginViewOnSuccess, 500, 500, () => {
|
||||||
// Temporary workaround
|
// Temporary workaround
|
||||||
if(loginViewOnSuccess === VIEWS.settings){
|
if(loginViewOnSuccess === VIEWS.settings){
|
||||||
prepareSettings()
|
prepareSettings()
|
||||||
}
|
}
|
||||||
loginViewOnSuccess = VIEWS.landing // Reset this for good measure.
|
loginViewOnSuccess = VIEWS.landing // Reset this for good measure.
|
||||||
loginCancelEnabled(false) // Reset this for good measure.
|
loginCancelEnabled(false) // Reset this for good measure.
|
||||||
loginViewCancelHandler = null // Reset this for good measure.
|
loginViewCancelHandler = null // Reset this for good measure.
|
||||||
loginUsername.value = ''
|
loginUsername.value = ''
|
||||||
loginPassword.value = ''
|
loginPassword.value = ''
|
||||||
$('.circle-loader').toggleClass('load-complete')
|
$('.circle-loader').toggleClass('load-complete')
|
||||||
$('.checkmark').toggle()
|
$('.checkmark').toggle()
|
||||||
loginLoading(false)
|
loginLoading(false)
|
||||||
loginButton.innerHTML = loginButton.innerHTML.replace(Lang.queryJS('login.success'), Lang.queryJS('login.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, Lang.queryJS('login.tryAgain'))
|
setOverlayContent(errF.title, errF.desc, Lang.queryJS('login.tryAgain'))
|
||||||
setOverlayHandler(() => {
|
setOverlayHandler(() => {
|
||||||
formDisabled(false)
|
formDisabled(false)
|
||||||
toggleOverlay(false)
|
toggleOverlay(false)
|
||||||
})
|
})
|
||||||
toggleOverlay(true)
|
toggleOverlay(true)
|
||||||
loggerLogin.log('Error while logging in.', err)
|
loggerLogin.log('Error while logging in.', err)
|
||||||
})
|
})
|
||||||
|
|
||||||
})
|
})
|
@ -1,318 +1,318 @@
|
|||||||
/**
|
/**
|
||||||
* Script for overlay.ejs
|
* Script for overlay.ejs
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Overlay Wrapper Functions */
|
/* Overlay Wrapper Functions */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check to see if the overlay is visible.
|
* Check to see if the overlay is visible.
|
||||||
*
|
*
|
||||||
* @returns {boolean} Whether or not the overlay is visible.
|
* @returns {boolean} Whether or not the overlay is visible.
|
||||||
*/
|
*/
|
||||||
function isOverlayVisible(){
|
function isOverlayVisible(){
|
||||||
return document.getElementById('main').hasAttribute('overlay')
|
return document.getElementById('main').hasAttribute('overlay')
|
||||||
}
|
}
|
||||||
|
|
||||||
let overlayHandlerContent
|
let overlayHandlerContent
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Overlay keydown handler for a non-dismissable overlay.
|
* Overlay keydown handler for a non-dismissable overlay.
|
||||||
*
|
*
|
||||||
* @param {KeyboardEvent} e The keydown event.
|
* @param {KeyboardEvent} e The keydown event.
|
||||||
*/
|
*/
|
||||||
function overlayKeyHandler (e){
|
function overlayKeyHandler (e){
|
||||||
if(e.key === 'Enter' || e.key === 'Escape'){
|
if(e.key === 'Enter' || e.key === 'Escape'){
|
||||||
document.getElementById(overlayHandlerContent).getElementsByClassName('overlayKeybindEnter')[0].click()
|
document.getElementById(overlayHandlerContent).getElementsByClassName('overlayKeybindEnter')[0].click()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* Overlay keydown handler for a dismissable overlay.
|
* Overlay keydown handler for a dismissable overlay.
|
||||||
*
|
*
|
||||||
* @param {KeyboardEvent} e The keydown event.
|
* @param {KeyboardEvent} e The keydown event.
|
||||||
*/
|
*/
|
||||||
function overlayKeyDismissableHandler (e){
|
function overlayKeyDismissableHandler (e){
|
||||||
if(e.key === 'Enter'){
|
if(e.key === 'Enter'){
|
||||||
document.getElementById(overlayHandlerContent).getElementsByClassName('overlayKeybindEnter')[0].click()
|
document.getElementById(overlayHandlerContent).getElementsByClassName('overlayKeybindEnter')[0].click()
|
||||||
} else if(e.key === 'Escape'){
|
} else if(e.key === 'Escape'){
|
||||||
document.getElementById(overlayHandlerContent).getElementsByClassName('overlayKeybindEsc')[0].click()
|
document.getElementById(overlayHandlerContent).getElementsByClassName('overlayKeybindEsc')[0].click()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Bind overlay keydown listeners for escape and exit.
|
* Bind overlay keydown listeners for escape and exit.
|
||||||
*
|
*
|
||||||
* @param {boolean} state Whether or not to add new event listeners.
|
* @param {boolean} state Whether or not to add new event listeners.
|
||||||
* @param {string} content The overlay content which will be shown.
|
* @param {string} content The overlay content which will be shown.
|
||||||
* @param {boolean} dismissable Whether or not the overlay is dismissable
|
* @param {boolean} dismissable Whether or not the overlay is dismissable
|
||||||
*/
|
*/
|
||||||
function bindOverlayKeys(state, content, dismissable){
|
function bindOverlayKeys(state, content, dismissable){
|
||||||
overlayHandlerContent = content
|
overlayHandlerContent = content
|
||||||
document.removeEventListener('keydown', overlayKeyHandler)
|
document.removeEventListener('keydown', overlayKeyHandler)
|
||||||
document.removeEventListener('keydown', overlayKeyDismissableHandler)
|
document.removeEventListener('keydown', overlayKeyDismissableHandler)
|
||||||
if(state){
|
if(state){
|
||||||
if(dismissable){
|
if(dismissable){
|
||||||
document.addEventListener('keydown', overlayKeyDismissableHandler)
|
document.addEventListener('keydown', overlayKeyDismissableHandler)
|
||||||
} else {
|
} else {
|
||||||
document.addEventListener('keydown', overlayKeyHandler)
|
document.addEventListener('keydown', overlayKeyHandler)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Toggle the visibility of the overlay.
|
* Toggle the visibility of the overlay.
|
||||||
*
|
*
|
||||||
* @param {boolean} toggleState True to display, false to hide.
|
* @param {boolean} toggleState True to display, false to hide.
|
||||||
* @param {boolean} dismissable Optional. True to show the dismiss option, otherwise false.
|
* @param {boolean} dismissable Optional. True to show the dismiss option, otherwise false.
|
||||||
* @param {string} content Optional. The content div to be shown.
|
* @param {string} content Optional. The content div to be shown.
|
||||||
*/
|
*/
|
||||||
function toggleOverlay(toggleState, dismissable = false, content = 'overlayContent'){
|
function toggleOverlay(toggleState, dismissable = false, content = 'overlayContent'){
|
||||||
if(toggleState == null){
|
if(toggleState == null){
|
||||||
toggleState = !document.getElementById('main').hasAttribute('overlay')
|
toggleState = !document.getElementById('main').hasAttribute('overlay')
|
||||||
}
|
}
|
||||||
if(typeof dismissable === 'string'){
|
if(typeof dismissable === 'string'){
|
||||||
content = dismissable
|
content = dismissable
|
||||||
dismissable = false
|
dismissable = false
|
||||||
}
|
}
|
||||||
bindOverlayKeys(toggleState, content, dismissable)
|
bindOverlayKeys(toggleState, content, dismissable)
|
||||||
if(toggleState){
|
if(toggleState){
|
||||||
document.getElementById('main').setAttribute('overlay', true)
|
document.getElementById('main').setAttribute('overlay', true)
|
||||||
// Make things untabbable.
|
// Make things untabbable.
|
||||||
$('#main *').attr('tabindex', '-1')
|
$('#main *').attr('tabindex', '-1')
|
||||||
$('#' + content).parent().children().hide()
|
$('#' + content).parent().children().hide()
|
||||||
$('#' + content).show()
|
$('#' + content).show()
|
||||||
if(dismissable){
|
if(dismissable){
|
||||||
$('#overlayDismiss').show()
|
$('#overlayDismiss').show()
|
||||||
} else {
|
} else {
|
||||||
$('#overlayDismiss').hide()
|
$('#overlayDismiss').hide()
|
||||||
}
|
}
|
||||||
$('#overlayContainer').fadeIn({
|
$('#overlayContainer').fadeIn({
|
||||||
duration: 250,
|
duration: 250,
|
||||||
start: () => {
|
start: () => {
|
||||||
if(getCurrentView() === VIEWS.settings){
|
if(getCurrentView() === VIEWS.settings){
|
||||||
document.getElementById('settingsContainer').style.backgroundColor = 'transparent'
|
document.getElementById('settingsContainer').style.backgroundColor = 'transparent'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
document.getElementById('main').removeAttribute('overlay')
|
document.getElementById('main').removeAttribute('overlay')
|
||||||
// Make things tabbable.
|
// Make things tabbable.
|
||||||
$('#main *').removeAttr('tabindex')
|
$('#main *').removeAttr('tabindex')
|
||||||
$('#overlayContainer').fadeOut({
|
$('#overlayContainer').fadeOut({
|
||||||
duration: 250,
|
duration: 250,
|
||||||
start: () => {
|
start: () => {
|
||||||
if(getCurrentView() === VIEWS.settings){
|
if(getCurrentView() === VIEWS.settings){
|
||||||
document.getElementById('settingsContainer').style.backgroundColor = 'rgba(0, 0, 0, 0.50)'
|
document.getElementById('settingsContainer').style.backgroundColor = 'rgba(0, 0, 0, 0.50)'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
complete: () => {
|
complete: () => {
|
||||||
$('#' + content).parent().children().hide()
|
$('#' + content).parent().children().hide()
|
||||||
$('#' + content).show()
|
$('#' + content).show()
|
||||||
if(dismissable){
|
if(dismissable){
|
||||||
$('#overlayDismiss').show()
|
$('#overlayDismiss').show()
|
||||||
} else {
|
} else {
|
||||||
$('#overlayDismiss').hide()
|
$('#overlayDismiss').hide()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function toggleServerSelection(toggleState){
|
function toggleServerSelection(toggleState){
|
||||||
prepareServerSelectionList()
|
prepareServerSelectionList()
|
||||||
toggleOverlay(toggleState, true, 'serverSelectContent')
|
toggleOverlay(toggleState, true, 'serverSelectContent')
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the content of the overlay.
|
* Set the content of the overlay.
|
||||||
*
|
*
|
||||||
* @param {string} title Overlay title text.
|
* @param {string} title Overlay title text.
|
||||||
* @param {string} description Overlay description text.
|
* @param {string} description Overlay description text.
|
||||||
* @param {string} acknowledge Acknowledge button text.
|
* @param {string} acknowledge Acknowledge button text.
|
||||||
* @param {string} dismiss Dismiss button text.
|
* @param {string} dismiss Dismiss button text.
|
||||||
*/
|
*/
|
||||||
function setOverlayContent(title, description, acknowledge, dismiss = 'Dismiss'){
|
function setOverlayContent(title, description, acknowledge, dismiss = 'Dismiss'){
|
||||||
document.getElementById('overlayTitle').innerHTML = title
|
document.getElementById('overlayTitle').innerHTML = title
|
||||||
document.getElementById('overlayDesc').innerHTML = description
|
document.getElementById('overlayDesc').innerHTML = description
|
||||||
document.getElementById('overlayAcknowledge').innerHTML = acknowledge
|
document.getElementById('overlayAcknowledge').innerHTML = acknowledge
|
||||||
document.getElementById('overlayDismiss').innerHTML = dismiss
|
document.getElementById('overlayDismiss').innerHTML = dismiss
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the onclick handler of the overlay acknowledge button.
|
* Set the onclick handler of the overlay acknowledge button.
|
||||||
* If the handler is null, a default handler will be added.
|
* If the handler is null, a default handler will be added.
|
||||||
*
|
*
|
||||||
* @param {function} handler
|
* @param {function} handler
|
||||||
*/
|
*/
|
||||||
function setOverlayHandler(handler){
|
function setOverlayHandler(handler){
|
||||||
if(handler == null){
|
if(handler == null){
|
||||||
document.getElementById('overlayAcknowledge').onclick = () => {
|
document.getElementById('overlayAcknowledge').onclick = () => {
|
||||||
toggleOverlay(false)
|
toggleOverlay(false)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
document.getElementById('overlayAcknowledge').onclick = handler
|
document.getElementById('overlayAcknowledge').onclick = handler
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the onclick handler of the overlay dismiss button.
|
* Set the onclick handler of the overlay dismiss button.
|
||||||
* If the handler is null, a default handler will be added.
|
* If the handler is null, a default handler will be added.
|
||||||
*
|
*
|
||||||
* @param {function} handler
|
* @param {function} handler
|
||||||
*/
|
*/
|
||||||
function setDismissHandler(handler){
|
function setDismissHandler(handler){
|
||||||
if(handler == null){
|
if(handler == null){
|
||||||
document.getElementById('overlayDismiss').onclick = () => {
|
document.getElementById('overlayDismiss').onclick = () => {
|
||||||
toggleOverlay(false)
|
toggleOverlay(false)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
document.getElementById('overlayDismiss').onclick = handler
|
document.getElementById('overlayDismiss').onclick = handler
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Server Select View */
|
/* Server Select View */
|
||||||
|
|
||||||
document.getElementById('serverSelectConfirm').addEventListener('click', () => {
|
document.getElementById('serverSelectConfirm').addEventListener('click', () => {
|
||||||
const listings = document.getElementsByClassName('serverListing')
|
const listings = document.getElementsByClassName('serverListing')
|
||||||
for(let i=0; i<listings.length; i++){
|
for(let i=0; i<listings.length; i++){
|
||||||
if(listings[i].hasAttribute('selected')){
|
if(listings[i].hasAttribute('selected')){
|
||||||
const serv = DistroManager.getDistribution().getServer(listings[i].getAttribute('servid'))
|
const serv = DistroManager.getDistribution().getServer(listings[i].getAttribute('servid'))
|
||||||
updateSelectedServer(serv)
|
updateSelectedServer(serv)
|
||||||
refreshServerStatus(true)
|
refreshServerStatus(true)
|
||||||
toggleOverlay(false)
|
toggleOverlay(false)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// None are selected? Not possible right? Meh, handle it.
|
// None are selected? Not possible right? Meh, handle it.
|
||||||
if(listings.length > 0){
|
if(listings.length > 0){
|
||||||
const serv = DistroManager.getDistribution().getServer(listings[i].getAttribute('servid'))
|
const serv = DistroManager.getDistribution().getServer(listings[i].getAttribute('servid'))
|
||||||
updateSelectedServer(serv)
|
updateSelectedServer(serv)
|
||||||
toggleOverlay(false)
|
toggleOverlay(false)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
document.getElementById('accountSelectConfirm').addEventListener('click', () => {
|
document.getElementById('accountSelectConfirm').addEventListener('click', () => {
|
||||||
const listings = document.getElementsByClassName('accountListing')
|
const listings = document.getElementsByClassName('accountListing')
|
||||||
for(let i=0; i<listings.length; i++){
|
for(let i=0; i<listings.length; i++){
|
||||||
if(listings[i].hasAttribute('selected')){
|
if(listings[i].hasAttribute('selected')){
|
||||||
const authAcc = ConfigManager.setSelectedAccount(listings[i].getAttribute('uuid'))
|
const authAcc = ConfigManager.setSelectedAccount(listings[i].getAttribute('uuid'))
|
||||||
ConfigManager.save()
|
ConfigManager.save()
|
||||||
updateSelectedAccount(authAcc)
|
updateSelectedAccount(authAcc)
|
||||||
toggleOverlay(false)
|
toggleOverlay(false)
|
||||||
validateSelectedAccount()
|
validateSelectedAccount()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// None are selected? Not possible right? Meh, handle it.
|
// None are selected? Not possible right? Meh, handle it.
|
||||||
if(listings.length > 0){
|
if(listings.length > 0){
|
||||||
const authAcc = ConfigManager.setSelectedAccount(listings[0].getAttribute('uuid'))
|
const authAcc = ConfigManager.setSelectedAccount(listings[0].getAttribute('uuid'))
|
||||||
ConfigManager.save()
|
ConfigManager.save()
|
||||||
updateSelectedAccount(authAcc)
|
updateSelectedAccount(authAcc)
|
||||||
toggleOverlay(false)
|
toggleOverlay(false)
|
||||||
validateSelectedAccount()
|
validateSelectedAccount()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
// Bind server select cancel button.
|
// Bind server select cancel button.
|
||||||
document.getElementById('serverSelectCancel').addEventListener('click', () => {
|
document.getElementById('serverSelectCancel').addEventListener('click', () => {
|
||||||
toggleOverlay(false)
|
toggleOverlay(false)
|
||||||
})
|
})
|
||||||
|
|
||||||
document.getElementById('accountSelectCancel').addEventListener('click', () => {
|
document.getElementById('accountSelectCancel').addEventListener('click', () => {
|
||||||
$('#accountSelectContent').fadeOut(250, () => {
|
$('#accountSelectContent').fadeOut(250, () => {
|
||||||
$('#overlayContent').fadeIn(250)
|
$('#overlayContent').fadeIn(250)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
function setServerListingHandlers(){
|
function setServerListingHandlers(){
|
||||||
const listings = Array.from(document.getElementsByClassName('serverListing'))
|
const listings = Array.from(document.getElementsByClassName('serverListing'))
|
||||||
listings.map((val) => {
|
listings.map((val) => {
|
||||||
val.onclick = e => {
|
val.onclick = e => {
|
||||||
if(val.hasAttribute('selected')){
|
if(val.hasAttribute('selected')){
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
const cListings = document.getElementsByClassName('serverListing')
|
const cListings = document.getElementsByClassName('serverListing')
|
||||||
for(let i=0; i<cListings.length; i++){
|
for(let i=0; i<cListings.length; i++){
|
||||||
if(cListings[i].hasAttribute('selected')){
|
if(cListings[i].hasAttribute('selected')){
|
||||||
cListings[i].removeAttribute('selected')
|
cListings[i].removeAttribute('selected')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
val.setAttribute('selected', '')
|
val.setAttribute('selected', '')
|
||||||
document.activeElement.blur()
|
document.activeElement.blur()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
function setAccountListingHandlers(){
|
function setAccountListingHandlers(){
|
||||||
const listings = Array.from(document.getElementsByClassName('accountListing'))
|
const listings = Array.from(document.getElementsByClassName('accountListing'))
|
||||||
listings.map((val) => {
|
listings.map((val) => {
|
||||||
val.onclick = e => {
|
val.onclick = e => {
|
||||||
if(val.hasAttribute('selected')){
|
if(val.hasAttribute('selected')){
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
const cListings = document.getElementsByClassName('accountListing')
|
const cListings = document.getElementsByClassName('accountListing')
|
||||||
for(let i=0; i<cListings.length; i++){
|
for(let i=0; i<cListings.length; i++){
|
||||||
if(cListings[i].hasAttribute('selected')){
|
if(cListings[i].hasAttribute('selected')){
|
||||||
cListings[i].removeAttribute('selected')
|
cListings[i].removeAttribute('selected')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
val.setAttribute('selected', '')
|
val.setAttribute('selected', '')
|
||||||
document.activeElement.blur()
|
document.activeElement.blur()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
function populateServerListings(){
|
function populateServerListings(){
|
||||||
const distro = DistroManager.getDistribution()
|
const distro = DistroManager.getDistribution()
|
||||||
const giaSel = ConfigManager.getSelectedServer()
|
const giaSel = ConfigManager.getSelectedServer()
|
||||||
const servers = distro.getServers()
|
const servers = distro.getServers()
|
||||||
let htmlString = ''
|
let htmlString = ''
|
||||||
for(const serv of servers){
|
for(const serv of servers){
|
||||||
htmlString += `<button class="serverListing" servid="${serv.getID()}" ${serv.getID() === giaSel ? 'selected' : ''}>
|
htmlString += `<button class="serverListing" servid="${serv.getID()}" ${serv.getID() === giaSel ? 'selected' : ''}>
|
||||||
<img class="serverListingImg" src="${serv.getIcon()}"/>
|
<img class="serverListingImg" src="${serv.getIcon()}"/>
|
||||||
<div class="serverListingDetails">
|
<div class="serverListingDetails">
|
||||||
<span class="serverListingName">${serv.getName()}</span>
|
<span class="serverListingName">${serv.getName()}</span>
|
||||||
<span class="serverListingDescription">${serv.getDescription()}</span>
|
<span class="serverListingDescription">${serv.getDescription()}</span>
|
||||||
<div class="serverListingInfo">
|
<div class="serverListingInfo">
|
||||||
<div class="serverListingVersion">${serv.getMinecraftVersion()}</div>
|
<div class="serverListingVersion">${serv.getMinecraftVersion()}</div>
|
||||||
<div class="serverListingRevision">${serv.getVersion()}</div>
|
<div class="serverListingRevision">${serv.getVersion()}</div>
|
||||||
${serv.isMainServer() ? `<div class="serverListingStarWrapper">
|
${serv.isMainServer() ? `<div class="serverListingStarWrapper">
|
||||||
<svg id="Layer_1" viewBox="0 0 107.45 104.74" width="20px" height="20px">
|
<svg id="Layer_1" viewBox="0 0 107.45 104.74" width="20px" height="20px">
|
||||||
<defs>
|
<defs>
|
||||||
<style>.cls-1{fill:#fff;}.cls-2{fill:none;stroke:#fff;stroke-miterlimit:10;}</style>
|
<style>.cls-1{fill:#fff;}.cls-2{fill:none;stroke:#fff;stroke-miterlimit:10;}</style>
|
||||||
</defs>
|
</defs>
|
||||||
<path class="cls-1" d="M100.93,65.54C89,62,68.18,55.65,63.54,52.13c2.7-5.23,18.8-19.2,28-27.55C81.36,31.74,63.74,43.87,58.09,45.3c-2.41-5.37-3.61-26.52-4.37-39-.77,12.46-2,33.64-4.36,39-5.7-1.46-23.3-13.57-33.49-20.72,9.26,8.37,25.39,22.36,28,27.55C39.21,55.68,18.47,62,6.52,65.55c12.32-2,33.63-6.06,39.34-4.9-.16,5.87-8.41,26.16-13.11,37.69,6.1-10.89,16.52-30.16,21-33.9,4.5,3.79,14.93,23.09,21,34C70,86.84,61.73,66.48,61.59,60.65,67.36,59.49,88.64,63.52,100.93,65.54Z"/>
|
<path class="cls-1" d="M100.93,65.54C89,62,68.18,55.65,63.54,52.13c2.7-5.23,18.8-19.2,28-27.55C81.36,31.74,63.74,43.87,58.09,45.3c-2.41-5.37-3.61-26.52-4.37-39-.77,12.46-2,33.64-4.36,39-5.7-1.46-23.3-13.57-33.49-20.72,9.26,8.37,25.39,22.36,28,27.55C39.21,55.68,18.47,62,6.52,65.55c12.32-2,33.63-6.06,39.34-4.9-.16,5.87-8.41,26.16-13.11,37.69,6.1-10.89,16.52-30.16,21-33.9,4.5,3.79,14.93,23.09,21,34C70,86.84,61.73,66.48,61.59,60.65,67.36,59.49,88.64,63.52,100.93,65.54Z"/>
|
||||||
<circle class="cls-2" cx="53.73" cy="53.9" r="38"/>
|
<circle class="cls-2" cx="53.73" cy="53.9" r="38"/>
|
||||||
</svg>
|
</svg>
|
||||||
<span class="serverListingStarTooltip">Main Server</span>
|
<span class="serverListingStarTooltip">Main Server</span>
|
||||||
</div>` : ''}
|
</div>` : ''}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</button>`
|
</button>`
|
||||||
}
|
}
|
||||||
document.getElementById('serverSelectListScrollable').innerHTML = htmlString
|
document.getElementById('serverSelectListScrollable').innerHTML = htmlString
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function populateAccountListings(){
|
function populateAccountListings(){
|
||||||
const accountsObj = ConfigManager.getAuthAccounts()
|
const accountsObj = ConfigManager.getAuthAccounts()
|
||||||
const accounts = Array.from(Object.keys(accountsObj), v=>accountsObj[v])
|
const accounts = Array.from(Object.keys(accountsObj), v=>accountsObj[v])
|
||||||
let htmlString = ''
|
let htmlString = ''
|
||||||
for(let i=0; i<accounts.length; i++){
|
for(let i=0; i<accounts.length; i++){
|
||||||
htmlString += `<button class="accountListing" uuid="${accounts[i].uuid}" ${i===0 ? 'selected' : ''}>
|
htmlString += `<button class="accountListing" uuid="${accounts[i].uuid}" ${i===0 ? 'selected' : ''}>
|
||||||
<img src="https://crafatar.com/renders/head/${accounts[i].uuid}?scale=2&default=MHF_Steve&overlay">
|
<img src="https://crafatar.com/renders/head/${accounts[i].uuid}?scale=2&default=MHF_Steve&overlay">
|
||||||
<div class="accountListingName">${accounts[i].displayName}</div>
|
<div class="accountListingName">${accounts[i].displayName}</div>
|
||||||
</button>`
|
</button>`
|
||||||
}
|
}
|
||||||
document.getElementById('accountSelectListScrollable').innerHTML = htmlString
|
document.getElementById('accountSelectListScrollable').innerHTML = htmlString
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function prepareServerSelectionList(){
|
function prepareServerSelectionList(){
|
||||||
populateServerListings()
|
populateServerListings()
|
||||||
setServerListingHandlers()
|
setServerListingHandlers()
|
||||||
}
|
}
|
||||||
|
|
||||||
function prepareAccountSelectionList(){
|
function prepareAccountSelectionList(){
|
||||||
populateAccountListings()
|
populateAccountListings()
|
||||||
setAccountListingHandlers()
|
setAccountListingHandlers()
|
||||||
}
|
}
|
File diff suppressed because it is too large
Load Diff
@ -1,419 +1,419 @@
|
|||||||
/**
|
/**
|
||||||
* Initialize UI functions which depend on internal modules.
|
* Initialize UI functions which depend on internal modules.
|
||||||
* Loaded after core UI functions are initialized in uicore.js.
|
* Loaded after core UI functions are initialized in uicore.js.
|
||||||
*/
|
*/
|
||||||
// Requirements
|
// Requirements
|
||||||
const path = require('path')
|
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')
|
const Lang = require('./assets/js/langloader')
|
||||||
|
|
||||||
let rscShouldLoad = false
|
let rscShouldLoad = false
|
||||||
let fatalStartupError = false
|
let fatalStartupError = false
|
||||||
|
|
||||||
// Mapping of each view to their container IDs.
|
// Mapping of each view to their container IDs.
|
||||||
const VIEWS = {
|
const VIEWS = {
|
||||||
landing: '#landingContainer',
|
landing: '#landingContainer',
|
||||||
login: '#loginContainer',
|
login: '#loginContainer',
|
||||||
settings: '#settingsContainer',
|
settings: '#settingsContainer',
|
||||||
welcome: '#welcomeContainer'
|
welcome: '#welcomeContainer'
|
||||||
}
|
}
|
||||||
|
|
||||||
// The currently shown view container.
|
// The currently shown view container.
|
||||||
let currentView
|
let currentView
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Switch launcher views.
|
* Switch launcher views.
|
||||||
*
|
*
|
||||||
* @param {string} current The ID of the current view container.
|
* @param {string} current The ID of the current view container.
|
||||||
* @param {*} next The ID of the next view container.
|
* @param {*} next The ID of the next view container.
|
||||||
* @param {*} currentFadeTime Optional. The fade out time for the current view.
|
* @param {*} currentFadeTime Optional. The fade out time for the current view.
|
||||||
* @param {*} nextFadeTime Optional. The fade in time for the next view.
|
* @param {*} nextFadeTime Optional. The fade in time for the next view.
|
||||||
* @param {*} onCurrentFade Optional. Callback function to execute when the current
|
* @param {*} onCurrentFade Optional. Callback function to execute when the current
|
||||||
* view fades out.
|
* view fades out.
|
||||||
* @param {*} onNextFade Optional. Callback function to execute when the next view
|
* @param {*} onNextFade Optional. Callback function to execute when the next view
|
||||||
* fades in.
|
* fades in.
|
||||||
*/
|
*/
|
||||||
function switchView(current, next, currentFadeTime = 500, nextFadeTime = 500, onCurrentFade = () => {}, onNextFade = () => {}){
|
function switchView(current, next, currentFadeTime = 500, nextFadeTime = 500, onCurrentFade = () => {}, onNextFade = () => {}){
|
||||||
currentView = next
|
currentView = next
|
||||||
$(`${current}`).fadeOut(currentFadeTime, () => {
|
$(`${current}`).fadeOut(currentFadeTime, () => {
|
||||||
onCurrentFade()
|
onCurrentFade()
|
||||||
$(`${next}`).fadeIn(nextFadeTime, () => {
|
$(`${next}`).fadeIn(nextFadeTime, () => {
|
||||||
onNextFade()
|
onNextFade()
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the currently shown view container.
|
* Get the currently shown view container.
|
||||||
*
|
*
|
||||||
* @returns {string} The currently shown view container.
|
* @returns {string} The currently shown view container.
|
||||||
*/
|
*/
|
||||||
function getCurrentView(){
|
function getCurrentView(){
|
||||||
return currentView
|
return currentView
|
||||||
}
|
}
|
||||||
|
|
||||||
function showMainUI(data){
|
function showMainUI(data){
|
||||||
|
|
||||||
if(!isDev){
|
if(!isDev){
|
||||||
loggerAutoUpdater.log('Initializing..')
|
loggerAutoUpdater.log('Initializing..')
|
||||||
ipcRenderer.send('autoUpdateAction', 'initAutoUpdater', ConfigManager.getAllowPrerelease())
|
ipcRenderer.send('autoUpdateAction', 'initAutoUpdater', ConfigManager.getAllowPrerelease())
|
||||||
}
|
}
|
||||||
|
|
||||||
prepareSettings(true)
|
prepareSettings(true)
|
||||||
updateSelectedServer(data.getServer(ConfigManager.getSelectedServer()))
|
updateSelectedServer(data.getServer(ConfigManager.getSelectedServer()))
|
||||||
refreshServerStatus()
|
refreshServerStatus()
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
document.getElementById('frameBar').style.backgroundColor = 'rgba(0, 0, 0, 0.5)'
|
document.getElementById('frameBar').style.backgroundColor = 'rgba(0, 0, 0, 0.5)'
|
||||||
document.body.style.backgroundImage = `url('assets/images/backgrounds/${document.body.getAttribute('bkid')}.jpg')`
|
document.body.style.backgroundImage = `url('assets/images/backgrounds/${document.body.getAttribute('bkid')}.jpg')`
|
||||||
$('#main').show()
|
$('#main').show()
|
||||||
|
|
||||||
const isLoggedIn = Object.keys(ConfigManager.getAuthAccounts()).length > 0
|
const isLoggedIn = Object.keys(ConfigManager.getAuthAccounts()).length > 0
|
||||||
|
|
||||||
// If this is enabled in a development environment we'll get ratelimited.
|
// If this is enabled in a development environment we'll get ratelimited.
|
||||||
// The relaunch frequency is usually far too high.
|
// The relaunch frequency is usually far too high.
|
||||||
if(!isDev && isLoggedIn){
|
if(!isDev && isLoggedIn){
|
||||||
validateSelectedAccount()
|
validateSelectedAccount()
|
||||||
}
|
}
|
||||||
|
|
||||||
if(ConfigManager.isFirstLaunch()){
|
if(ConfigManager.isFirstLaunch()){
|
||||||
currentView = VIEWS.welcome
|
currentView = VIEWS.welcome
|
||||||
$(VIEWS.welcome).fadeIn(1000)
|
$(VIEWS.welcome).fadeIn(1000)
|
||||||
} else {
|
} else {
|
||||||
if(isLoggedIn){
|
if(isLoggedIn){
|
||||||
currentView = VIEWS.landing
|
currentView = VIEWS.landing
|
||||||
$(VIEWS.landing).fadeIn(1000)
|
$(VIEWS.landing).fadeIn(1000)
|
||||||
} else {
|
} else {
|
||||||
currentView = VIEWS.login
|
currentView = VIEWS.login
|
||||||
$(VIEWS.login).fadeIn(1000)
|
$(VIEWS.login).fadeIn(1000)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
$('#loadingContainer').fadeOut(500, () => {
|
$('#loadingContainer').fadeOut(500, () => {
|
||||||
$('#loadSpinnerImage').removeClass('rotating')
|
$('#loadSpinnerImage').removeClass('rotating')
|
||||||
})
|
})
|
||||||
}, 250)
|
}, 250)
|
||||||
|
|
||||||
}, 750)
|
}, 750)
|
||||||
// Disable tabbing to the news container.
|
// Disable tabbing to the news container.
|
||||||
initNews().then(() => {
|
initNews().then(() => {
|
||||||
$('#newsContainer *').attr('tabindex', '-1')
|
$('#newsContainer *').attr('tabindex', '-1')
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
function showFatalStartupError(){
|
function showFatalStartupError(){
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
$('#loadingContainer').fadeOut(250, () => {
|
$('#loadingContainer').fadeOut(250, () => {
|
||||||
document.getElementById('overlayContainer').style.background = 'none'
|
document.getElementById('overlayContainer').style.background = 'none'
|
||||||
setOverlayContent(
|
setOverlayContent(
|
||||||
'Fatal Error: Unable to Load Distribution Index',
|
'Fatal Error: Unable to Load Distribution Index',
|
||||||
'A connection could not be established to our servers to download the distribution index. No local copies were available to load. <br><br>The distribution index is an essential file which provides the latest server information. The launcher is unable to start without it. Ensure you are connected to the internet and relaunch the application.',
|
'A connection could not be established to our servers to download the distribution index. No local copies were available to load. <br><br>The distribution index is an essential file which provides the latest server information. The launcher is unable to start without it. Ensure you are connected to the internet and relaunch the application.',
|
||||||
'Close'
|
'Close'
|
||||||
)
|
)
|
||||||
setOverlayHandler(() => {
|
setOverlayHandler(() => {
|
||||||
const window = remote.getCurrentWindow()
|
const window = remote.getCurrentWindow()
|
||||||
window.close()
|
window.close()
|
||||||
})
|
})
|
||||||
toggleOverlay(true)
|
toggleOverlay(true)
|
||||||
})
|
})
|
||||||
}, 750)
|
}, 750)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Common functions to perform after refreshing the distro index.
|
* Common functions to perform after refreshing the distro index.
|
||||||
*
|
*
|
||||||
* @param {Object} data The distro index object.
|
* @param {Object} data The distro index object.
|
||||||
*/
|
*/
|
||||||
function onDistroRefresh(data){
|
function onDistroRefresh(data){
|
||||||
updateSelectedServer(data.getServer(ConfigManager.getSelectedServer()))
|
updateSelectedServer(data.getServer(ConfigManager.getSelectedServer()))
|
||||||
refreshServerStatus()
|
refreshServerStatus()
|
||||||
initNews()
|
initNews()
|
||||||
syncModConfigurations(data)
|
syncModConfigurations(data)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sync the mod configurations with the distro index.
|
* Sync the mod configurations with the distro index.
|
||||||
*
|
*
|
||||||
* @param {Object} data The distro index object.
|
* @param {Object} data The distro index object.
|
||||||
*/
|
*/
|
||||||
function syncModConfigurations(data){
|
function syncModConfigurations(data){
|
||||||
|
|
||||||
const syncedCfgs = []
|
const syncedCfgs = []
|
||||||
|
|
||||||
for(let serv of data.getServers()){
|
for(let serv of data.getServers()){
|
||||||
|
|
||||||
const id = serv.getID()
|
const id = serv.getID()
|
||||||
const mdls = serv.getModules()
|
const mdls = serv.getModules()
|
||||||
const cfg = ConfigManager.getModConfiguration(id)
|
const cfg = ConfigManager.getModConfiguration(id)
|
||||||
|
|
||||||
if(cfg != null){
|
if(cfg != null){
|
||||||
|
|
||||||
const modsOld = cfg.mods
|
const modsOld = cfg.mods
|
||||||
const mods = {}
|
const mods = {}
|
||||||
|
|
||||||
for(let mdl of mdls){
|
for(let mdl of mdls){
|
||||||
const type = mdl.getType()
|
const type = mdl.getType()
|
||||||
|
|
||||||
if(type === DistroManager.Types.ForgeMod || type === DistroManager.Types.LiteMod || type === DistroManager.Types.LiteLoader){
|
if(type === DistroManager.Types.ForgeMod || type === DistroManager.Types.LiteMod || type === DistroManager.Types.LiteLoader){
|
||||||
if(!mdl.getRequired().isRequired()){
|
if(!mdl.getRequired().isRequired()){
|
||||||
const mdlID = mdl.getVersionlessID()
|
const mdlID = mdl.getVersionlessID()
|
||||||
if(modsOld[mdlID] == null){
|
if(modsOld[mdlID] == null){
|
||||||
mods[mdlID] = scanOptionalSubModules(mdl.getSubModules(), mdl)
|
mods[mdlID] = scanOptionalSubModules(mdl.getSubModules(), mdl)
|
||||||
} else {
|
} else {
|
||||||
mods[mdlID] = mergeModConfiguration(modsOld[mdlID], scanOptionalSubModules(mdl.getSubModules(), mdl), false)
|
mods[mdlID] = mergeModConfiguration(modsOld[mdlID], scanOptionalSubModules(mdl.getSubModules(), mdl), false)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if(mdl.hasSubModules()){
|
if(mdl.hasSubModules()){
|
||||||
const mdlID = mdl.getVersionlessID()
|
const mdlID = mdl.getVersionlessID()
|
||||||
const v = scanOptionalSubModules(mdl.getSubModules(), mdl)
|
const v = scanOptionalSubModules(mdl.getSubModules(), mdl)
|
||||||
if(typeof v === 'object'){
|
if(typeof v === 'object'){
|
||||||
if(modsOld[mdlID] == null){
|
if(modsOld[mdlID] == null){
|
||||||
mods[mdlID] = v
|
mods[mdlID] = v
|
||||||
} else {
|
} else {
|
||||||
mods[mdlID] = mergeModConfiguration(modsOld[mdlID], v, true)
|
mods[mdlID] = mergeModConfiguration(modsOld[mdlID], v, true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
syncedCfgs.push({
|
syncedCfgs.push({
|
||||||
id,
|
id,
|
||||||
mods
|
mods
|
||||||
})
|
})
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
const mods = {}
|
const mods = {}
|
||||||
|
|
||||||
for(let mdl of mdls){
|
for(let mdl of mdls){
|
||||||
const type = mdl.getType()
|
const type = mdl.getType()
|
||||||
if(type === DistroManager.Types.ForgeMod || type === DistroManager.Types.LiteMod || type === DistroManager.Types.LiteLoader){
|
if(type === DistroManager.Types.ForgeMod || type === DistroManager.Types.LiteMod || type === DistroManager.Types.LiteLoader){
|
||||||
if(!mdl.getRequired().isRequired()){
|
if(!mdl.getRequired().isRequired()){
|
||||||
mods[mdl.getVersionlessID()] = scanOptionalSubModules(mdl.getSubModules(), mdl)
|
mods[mdl.getVersionlessID()] = scanOptionalSubModules(mdl.getSubModules(), mdl)
|
||||||
} else {
|
} else {
|
||||||
if(mdl.hasSubModules()){
|
if(mdl.hasSubModules()){
|
||||||
const v = scanOptionalSubModules(mdl.getSubModules(), mdl)
|
const v = scanOptionalSubModules(mdl.getSubModules(), mdl)
|
||||||
if(typeof v === 'object'){
|
if(typeof v === 'object'){
|
||||||
mods[mdl.getVersionlessID()] = v
|
mods[mdl.getVersionlessID()] = v
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
syncedCfgs.push({
|
syncedCfgs.push({
|
||||||
id,
|
id,
|
||||||
mods
|
mods
|
||||||
})
|
})
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ConfigManager.setModConfigurations(syncedCfgs)
|
ConfigManager.setModConfigurations(syncedCfgs)
|
||||||
ConfigManager.save()
|
ConfigManager.save()
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Recursively scan for optional sub modules. If none are found,
|
* Recursively scan for optional sub modules. If none are found,
|
||||||
* this function returns a boolean. If optional sub modules do exist,
|
* this function returns a boolean. If optional sub modules do exist,
|
||||||
* a recursive configuration object is returned.
|
* a recursive configuration object is returned.
|
||||||
*
|
*
|
||||||
* @returns {boolean | Object} The resolved mod configuration.
|
* @returns {boolean | Object} The resolved mod configuration.
|
||||||
*/
|
*/
|
||||||
function scanOptionalSubModules(mdls, origin){
|
function scanOptionalSubModules(mdls, origin){
|
||||||
if(mdls != null){
|
if(mdls != null){
|
||||||
const mods = {}
|
const mods = {}
|
||||||
|
|
||||||
for(let mdl of mdls){
|
for(let mdl of mdls){
|
||||||
const type = mdl.getType()
|
const type = mdl.getType()
|
||||||
// Optional types.
|
// Optional types.
|
||||||
if(type === DistroManager.Types.ForgeMod || type === DistroManager.Types.LiteMod || type === DistroManager.Types.LiteLoader){
|
if(type === DistroManager.Types.ForgeMod || type === DistroManager.Types.LiteMod || type === DistroManager.Types.LiteLoader){
|
||||||
// It is optional.
|
// It is optional.
|
||||||
if(!mdl.getRequired().isRequired()){
|
if(!mdl.getRequired().isRequired()){
|
||||||
mods[mdl.getVersionlessID()] = scanOptionalSubModules(mdl.getSubModules(), mdl)
|
mods[mdl.getVersionlessID()] = scanOptionalSubModules(mdl.getSubModules(), mdl)
|
||||||
} else {
|
} else {
|
||||||
if(mdl.hasSubModules()){
|
if(mdl.hasSubModules()){
|
||||||
const v = scanOptionalSubModules(mdl.getSubModules(), mdl)
|
const v = scanOptionalSubModules(mdl.getSubModules(), mdl)
|
||||||
if(typeof v === 'object'){
|
if(typeof v === 'object'){
|
||||||
mods[mdl.getVersionlessID()] = v
|
mods[mdl.getVersionlessID()] = v
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(Object.keys(mods).length > 0){
|
if(Object.keys(mods).length > 0){
|
||||||
const ret = {
|
const ret = {
|
||||||
mods
|
mods
|
||||||
}
|
}
|
||||||
if(!origin.getRequired().isRequired()){
|
if(!origin.getRequired().isRequired()){
|
||||||
ret.value = origin.getRequired().isDefault()
|
ret.value = origin.getRequired().isDefault()
|
||||||
}
|
}
|
||||||
return ret
|
return ret
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return origin.getRequired().isDefault()
|
return origin.getRequired().isDefault()
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Recursively merge an old configuration into a new configuration.
|
* Recursively merge an old configuration into a new configuration.
|
||||||
*
|
*
|
||||||
* @param {boolean | Object} o The old configuration value.
|
* @param {boolean | Object} o The old configuration value.
|
||||||
* @param {boolean | Object} n The new configuration value.
|
* @param {boolean | Object} n The new configuration value.
|
||||||
* @param {boolean} nReq If the new value is a required mod.
|
* @param {boolean} nReq If the new value is a required mod.
|
||||||
*
|
*
|
||||||
* @returns {boolean | Object} The merged configuration.
|
* @returns {boolean | Object} The merged configuration.
|
||||||
*/
|
*/
|
||||||
function mergeModConfiguration(o, n, nReq = false){
|
function mergeModConfiguration(o, n, nReq = false){
|
||||||
if(typeof o === 'boolean'){
|
if(typeof o === 'boolean'){
|
||||||
if(typeof n === 'boolean') return o
|
if(typeof n === 'boolean') return o
|
||||||
else if(typeof n === 'object'){
|
else if(typeof n === 'object'){
|
||||||
if(!nReq){
|
if(!nReq){
|
||||||
n.value = o
|
n.value = o
|
||||||
}
|
}
|
||||||
return n
|
return n
|
||||||
}
|
}
|
||||||
} else if(typeof o === 'object'){
|
} else if(typeof o === 'object'){
|
||||||
if(typeof n === 'boolean') return typeof o.value !== 'undefined' ? o.value : true
|
if(typeof n === 'boolean') return typeof o.value !== 'undefined' ? o.value : true
|
||||||
else if(typeof n === 'object'){
|
else if(typeof n === 'object'){
|
||||||
if(!nReq){
|
if(!nReq){
|
||||||
n.value = typeof o.value !== 'undefined' ? o.value : true
|
n.value = typeof o.value !== 'undefined' ? o.value : true
|
||||||
}
|
}
|
||||||
|
|
||||||
const newMods = Object.keys(n.mods)
|
const newMods = Object.keys(n.mods)
|
||||||
for(let i=0; i<newMods.length; i++){
|
for(let i=0; i<newMods.length; i++){
|
||||||
|
|
||||||
const mod = newMods[i]
|
const mod = newMods[i]
|
||||||
if(o.mods[mod] != null){
|
if(o.mods[mod] != null){
|
||||||
n.mods[mod] = mergeModConfiguration(o.mods[mod], n.mods[mod])
|
n.mods[mod] = mergeModConfiguration(o.mods[mod], n.mods[mod])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return n
|
return n
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// If for some reason we haven't been able to merge,
|
// If for some reason we haven't been able to merge,
|
||||||
// wipe the old value and use the new one. Just to be safe
|
// wipe the old value and use the new one. Just to be safe
|
||||||
return n
|
return n
|
||||||
}
|
}
|
||||||
|
|
||||||
function refreshDistributionIndex(remote, onSuccess, onError){
|
function refreshDistributionIndex(remote, onSuccess, onError){
|
||||||
if(remote){
|
if(remote){
|
||||||
DistroManager.pullRemote()
|
DistroManager.pullRemote()
|
||||||
.then(onSuccess)
|
.then(onSuccess)
|
||||||
.catch(onError)
|
.catch(onError)
|
||||||
} else {
|
} else {
|
||||||
DistroManager.pullLocal()
|
DistroManager.pullLocal()
|
||||||
.then(onSuccess)
|
.then(onSuccess)
|
||||||
.catch(onError)
|
.catch(onError)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function validateSelectedAccount(){
|
async function validateSelectedAccount(){
|
||||||
const selectedAcc = ConfigManager.getSelectedAccount()
|
const selectedAcc = ConfigManager.getSelectedAccount()
|
||||||
if(selectedAcc != null){
|
if(selectedAcc != null){
|
||||||
const val = await AuthManager.validateSelected()
|
const val = await AuthManager.validateSelected()
|
||||||
if(!val){
|
if(!val){
|
||||||
ConfigManager.removeAuthAccount(selectedAcc.uuid)
|
ConfigManager.removeAuthAccount(selectedAcc.uuid)
|
||||||
ConfigManager.save()
|
ConfigManager.save()
|
||||||
const accLen = Object.keys(ConfigManager.getAuthAccounts()).length
|
const accLen = Object.keys(ConfigManager.getAuthAccounts()).length
|
||||||
setOverlayContent(
|
setOverlayContent(
|
||||||
'Failed to Refresh Login',
|
'Failed to Refresh Login',
|
||||||
`We were unable to refresh the login for <strong>${selectedAcc.displayName}</strong>. Please ${accLen > 0 ? 'select another account or ' : ''} login again.`,
|
`We were unable to refresh the login for <strong>${selectedAcc.displayName}</strong>. Please ${accLen > 0 ? 'select another account or ' : ''} login again.`,
|
||||||
'Login',
|
'Login',
|
||||||
'Select Another Account'
|
'Select Another Account'
|
||||||
)
|
)
|
||||||
setOverlayHandler(() => {
|
setOverlayHandler(() => {
|
||||||
document.getElementById('loginUsername').value = selectedAcc.username
|
document.getElementById('loginUsername').value = selectedAcc.username
|
||||||
validateEmail(selectedAcc.username)
|
validateEmail(selectedAcc.username)
|
||||||
loginViewOnSuccess = getCurrentView()
|
loginViewOnSuccess = getCurrentView()
|
||||||
loginViewOnCancel = getCurrentView()
|
loginViewOnCancel = getCurrentView()
|
||||||
if(accLen > 0){
|
if(accLen > 0){
|
||||||
loginViewCancelHandler = () => {
|
loginViewCancelHandler = () => {
|
||||||
ConfigManager.addAuthAccount(selectedAcc.uuid, selectedAcc.accessToken, selectedAcc.username, selectedAcc.displayName)
|
ConfigManager.addAuthAccount(selectedAcc.uuid, selectedAcc.accessToken, selectedAcc.username, selectedAcc.displayName)
|
||||||
ConfigManager.save()
|
ConfigManager.save()
|
||||||
validateSelectedAccount()
|
validateSelectedAccount()
|
||||||
}
|
}
|
||||||
loginCancelEnabled(true)
|
loginCancelEnabled(true)
|
||||||
}
|
}
|
||||||
toggleOverlay(false)
|
toggleOverlay(false)
|
||||||
switchView(getCurrentView(), VIEWS.login)
|
switchView(getCurrentView(), VIEWS.login)
|
||||||
})
|
})
|
||||||
setDismissHandler(() => {
|
setDismissHandler(() => {
|
||||||
if(accLen > 1){
|
if(accLen > 1){
|
||||||
prepareAccountSelectionList()
|
prepareAccountSelectionList()
|
||||||
$('#overlayContent').fadeOut(250, () => {
|
$('#overlayContent').fadeOut(250, () => {
|
||||||
bindOverlayKeys(true, 'accountSelectContent', true)
|
bindOverlayKeys(true, 'accountSelectContent', true)
|
||||||
$('#accountSelectContent').fadeIn(250)
|
$('#accountSelectContent').fadeIn(250)
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
const accountsObj = ConfigManager.getAuthAccounts()
|
const accountsObj = ConfigManager.getAuthAccounts()
|
||||||
const accounts = Array.from(Object.keys(accountsObj), v => accountsObj[v])
|
const accounts = Array.from(Object.keys(accountsObj), v => accountsObj[v])
|
||||||
// This function validates the account switch.
|
// This function validates the account switch.
|
||||||
setSelectedAccount(accounts[0].uuid)
|
setSelectedAccount(accounts[0].uuid)
|
||||||
toggleOverlay(false)
|
toggleOverlay(false)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
toggleOverlay(true, accLen > 0)
|
toggleOverlay(true, accLen > 0)
|
||||||
} else {
|
} else {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Temporary function to update the selected account along
|
* Temporary function to update the selected account along
|
||||||
* with the relevent UI elements.
|
* with the relevent UI elements.
|
||||||
*
|
*
|
||||||
* @param {string} uuid The UUID of the account.
|
* @param {string} uuid The UUID of the account.
|
||||||
*/
|
*/
|
||||||
function setSelectedAccount(uuid){
|
function setSelectedAccount(uuid){
|
||||||
const authAcc = ConfigManager.setSelectedAccount(uuid)
|
const authAcc = ConfigManager.setSelectedAccount(uuid)
|
||||||
ConfigManager.save()
|
ConfigManager.save()
|
||||||
updateSelectedAccount(authAcc)
|
updateSelectedAccount(authAcc)
|
||||||
validateSelectedAccount()
|
validateSelectedAccount()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Synchronous Listener
|
// Synchronous Listener
|
||||||
document.addEventListener('readystatechange', function(){
|
document.addEventListener('readystatechange', function(){
|
||||||
|
|
||||||
if (document.readyState === 'interactive' || document.readyState === 'complete'){
|
if (document.readyState === 'interactive' || document.readyState === 'complete'){
|
||||||
if(rscShouldLoad){
|
if(rscShouldLoad){
|
||||||
rscShouldLoad = false
|
rscShouldLoad = false
|
||||||
if(!fatalStartupError){
|
if(!fatalStartupError){
|
||||||
const data = DistroManager.getDistribution()
|
const data = DistroManager.getDistribution()
|
||||||
showMainUI(data)
|
showMainUI(data)
|
||||||
} else {
|
} else {
|
||||||
showFatalStartupError()
|
showFatalStartupError()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}, false)
|
}, false)
|
||||||
|
|
||||||
// Actions that must be performed after the distribution index is downloaded.
|
// Actions that must be performed after the distribution index is downloaded.
|
||||||
ipcRenderer.on('distributionIndexDone', (event, res) => {
|
ipcRenderer.on('distributionIndexDone', (event, res) => {
|
||||||
if(res) {
|
if(res) {
|
||||||
const data = DistroManager.getDistribution()
|
const data = DistroManager.getDistribution()
|
||||||
syncModConfigurations(data)
|
syncModConfigurations(data)
|
||||||
if(document.readyState === 'interactive' || document.readyState === 'complete'){
|
if(document.readyState === 'interactive' || document.readyState === 'complete'){
|
||||||
showMainUI(data)
|
showMainUI(data)
|
||||||
} else {
|
} else {
|
||||||
rscShouldLoad = true
|
rscShouldLoad = true
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
fatalStartupError = true
|
fatalStartupError = true
|
||||||
if(document.readyState === 'interactive' || document.readyState === 'complete'){
|
if(document.readyState === 'interactive' || document.readyState === 'complete'){
|
||||||
showFatalStartupError()
|
showFatalStartupError()
|
||||||
} else {
|
} else {
|
||||||
rscShouldLoad = true
|
rscShouldLoad = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
@ -1,213 +1,213 @@
|
|||||||
/**
|
/**
|
||||||
* Core UI functions are initialized in this file. This prevents
|
* Core UI functions are initialized in this file. This prevents
|
||||||
* unexpected errors from breaking the core features. Specifically,
|
* unexpected errors from breaking the core features. Specifically,
|
||||||
* actions in this file should not require the usage of any internal
|
* actions in this file should not require the usage of any internal
|
||||||
* modules, excluding dependencies.
|
* modules, excluding dependencies.
|
||||||
*/
|
*/
|
||||||
// Requirements
|
// Requirements
|
||||||
const $ = require('jquery')
|
const $ = require('jquery')
|
||||||
const {ipcRenderer, remote, shell, webFrame} = require('electron')
|
const {ipcRenderer, remote, shell, webFrame} = require('electron')
|
||||||
const isDev = require('./assets/js/isdev')
|
const isDev = require('./assets/js/isdev')
|
||||||
const LoggerUtil = require('./assets/js/loggerutil')
|
const LoggerUtil = require('./assets/js/loggerutil')
|
||||||
|
|
||||||
const loggerUICore = LoggerUtil('%c[UICore]', 'color: #000668; font-weight: bold')
|
const loggerUICore = LoggerUtil('%c[UICore]', 'color: #000668; font-weight: bold')
|
||||||
const loggerAutoUpdater = LoggerUtil('%c[AutoUpdater]', 'color: #000668; font-weight: bold')
|
const loggerAutoUpdater = LoggerUtil('%c[AutoUpdater]', 'color: #000668; font-weight: bold')
|
||||||
const loggerAutoUpdaterSuccess = LoggerUtil('%c[AutoUpdater]', 'color: #209b07; font-weight: bold')
|
const loggerAutoUpdaterSuccess = LoggerUtil('%c[AutoUpdater]', 'color: #209b07; font-weight: bold')
|
||||||
|
|
||||||
// Log deprecation and process warnings.
|
// Log deprecation and process warnings.
|
||||||
process.traceProcessWarnings = true
|
process.traceProcessWarnings = true
|
||||||
process.traceDeprecation = true
|
process.traceDeprecation = true
|
||||||
|
|
||||||
// Disable eval function.
|
// Disable eval function.
|
||||||
// eslint-disable-next-line
|
// eslint-disable-next-line
|
||||||
window.eval = global.eval = function () {
|
window.eval = global.eval = function () {
|
||||||
throw new Error('Sorry, this app does not support window.eval().')
|
throw new Error('Sorry, this app does not support window.eval().')
|
||||||
}
|
}
|
||||||
|
|
||||||
// Display warning when devtools window is opened.
|
// Display warning when devtools window is opened.
|
||||||
remote.getCurrentWebContents().on('devtools-opened', () => {
|
remote.getCurrentWebContents().on('devtools-opened', () => {
|
||||||
console.log('%cThe console is dark and full of terrors.', 'color: white; -webkit-text-stroke: 4px #a02d2a; font-size: 60px; font-weight: bold')
|
console.log('%cThe console is dark and full of terrors.', 'color: white; -webkit-text-stroke: 4px #a02d2a; font-size: 60px; font-weight: bold')
|
||||||
console.log('%cIf you\'ve been told to paste something here, you\'re being scammed.', 'font-size: 16px')
|
console.log('%cIf you\'ve been told to paste something here, you\'re being scammed.', 'font-size: 16px')
|
||||||
console.log('%cUnless you know exactly what you\'re doing, close this window.', 'font-size: 16px')
|
console.log('%cUnless you know exactly what you\'re doing, close this window.', 'font-size: 16px')
|
||||||
})
|
})
|
||||||
|
|
||||||
// Disable zoom, needed for darwin.
|
// Disable zoom, needed for darwin.
|
||||||
webFrame.setZoomLevel(0)
|
webFrame.setZoomLevel(0)
|
||||||
webFrame.setVisualZoomLevelLimits(1, 1)
|
webFrame.setVisualZoomLevelLimits(1, 1)
|
||||||
|
|
||||||
// Initialize auto updates in production environments.
|
// Initialize auto updates in production environments.
|
||||||
let updateCheckListener
|
let updateCheckListener
|
||||||
if(!isDev){
|
if(!isDev){
|
||||||
ipcRenderer.on('autoUpdateNotification', (event, arg, info) => {
|
ipcRenderer.on('autoUpdateNotification', (event, arg, info) => {
|
||||||
switch(arg){
|
switch(arg){
|
||||||
case 'checking-for-update':
|
case 'checking-for-update':
|
||||||
loggerAutoUpdater.log('Checking for update..')
|
loggerAutoUpdater.log('Checking for update..')
|
||||||
settingsUpdateButtonStatus('Checking for Updates..', true)
|
settingsUpdateButtonStatus('Checking for Updates..', true)
|
||||||
break
|
break
|
||||||
case 'update-available':
|
case 'update-available':
|
||||||
loggerAutoUpdaterSuccess.log('New update available', info.version)
|
loggerAutoUpdaterSuccess.log('New update available', info.version)
|
||||||
|
|
||||||
if(process.platform === 'darwin'){
|
if(process.platform === 'darwin'){
|
||||||
info.darwindownload = `https://github.com/dscalzi/HeliosLauncher/releases/download/v${info.version}/helioslauncher-setup-${info.version}.dmg`
|
info.darwindownload = `https://github.com/MastermDEV/NemesisMC-Launcher/releases/download/v${info.version}/nemesismclauncher-setup${info.version}.dmg`
|
||||||
showUpdateUI(info)
|
showUpdateUI(info)
|
||||||
}
|
}
|
||||||
|
|
||||||
populateSettingsUpdateInformation(info)
|
populateSettingsUpdateInformation(info)
|
||||||
break
|
break
|
||||||
case 'update-downloaded':
|
case 'update-downloaded':
|
||||||
loggerAutoUpdaterSuccess.log('Update ' + info.version + ' ready to be installed.')
|
loggerAutoUpdaterSuccess.log('Update ' + info.version + ' ready to be installed.')
|
||||||
settingsUpdateButtonStatus('Install Now', false, () => {
|
settingsUpdateButtonStatus('Install Now', false, () => {
|
||||||
if(!isDev){
|
if(!isDev){
|
||||||
ipcRenderer.send('autoUpdateAction', 'installUpdateNow')
|
ipcRenderer.send('autoUpdateAction', 'installUpdateNow')
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
showUpdateUI(info)
|
showUpdateUI(info)
|
||||||
break
|
break
|
||||||
case 'update-not-available':
|
case 'update-not-available':
|
||||||
loggerAutoUpdater.log('No new update found.')
|
loggerAutoUpdater.log('No new update found.')
|
||||||
settingsUpdateButtonStatus('Check for Updates')
|
settingsUpdateButtonStatus('Check for Updates')
|
||||||
break
|
break
|
||||||
case 'ready':
|
case 'ready':
|
||||||
updateCheckListener = setInterval(() => {
|
updateCheckListener = setInterval(() => {
|
||||||
ipcRenderer.send('autoUpdateAction', 'checkForUpdate')
|
ipcRenderer.send('autoUpdateAction', 'checkForUpdate')
|
||||||
}, 1800000)
|
}, 1800000)
|
||||||
ipcRenderer.send('autoUpdateAction', 'checkForUpdate')
|
ipcRenderer.send('autoUpdateAction', 'checkForUpdate')
|
||||||
break
|
break
|
||||||
case 'realerror':
|
case 'realerror':
|
||||||
if(info != null && info.code != null){
|
if(info != null && info.code != null){
|
||||||
if(info.code === 'ERR_UPDATER_INVALID_RELEASE_FEED'){
|
if(info.code === 'ERR_UPDATER_INVALID_RELEASE_FEED'){
|
||||||
loggerAutoUpdater.log('No suitable releases found.')
|
loggerAutoUpdater.log('No suitable releases found.')
|
||||||
} else if(info.code === 'ERR_XML_MISSED_ELEMENT'){
|
} else if(info.code === 'ERR_XML_MISSED_ELEMENT'){
|
||||||
loggerAutoUpdater.log('No releases found.')
|
loggerAutoUpdater.log('No releases found.')
|
||||||
} else {
|
} else {
|
||||||
loggerAutoUpdater.error('Error during update check..', info)
|
loggerAutoUpdater.error('Error during update check..', info)
|
||||||
loggerAutoUpdater.debug('Error Code:', info.code)
|
loggerAutoUpdater.debug('Error Code:', info.code)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break
|
break
|
||||||
default:
|
default:
|
||||||
loggerAutoUpdater.log('Unknown argument', arg)
|
loggerAutoUpdater.log('Unknown argument', arg)
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Send a notification to the main process changing the value of
|
* Send a notification to the main process changing the value of
|
||||||
* allowPrerelease. If we are running a prerelease version, then
|
* allowPrerelease. If we are running a prerelease version, then
|
||||||
* this will always be set to true, regardless of the current value
|
* this will always be set to true, regardless of the current value
|
||||||
* of val.
|
* of val.
|
||||||
*
|
*
|
||||||
* @param {boolean} val The new allow prerelease value.
|
* @param {boolean} val The new allow prerelease value.
|
||||||
*/
|
*/
|
||||||
function changeAllowPrerelease(val){
|
function changeAllowPrerelease(val){
|
||||||
ipcRenderer.send('autoUpdateAction', 'allowPrereleaseChange', val)
|
ipcRenderer.send('autoUpdateAction', 'allowPrereleaseChange', val)
|
||||||
}
|
}
|
||||||
|
|
||||||
function showUpdateUI(info){
|
function showUpdateUI(info){
|
||||||
//TODO Make this message a bit more informative `${info.version}`
|
//TODO Make this message a bit more informative `${info.version}`
|
||||||
document.getElementById('image_seal_container').setAttribute('update', true)
|
document.getElementById('image_seal_container').setAttribute('update', true)
|
||||||
document.getElementById('image_seal_container').onclick = () => {
|
document.getElementById('image_seal_container').onclick = () => {
|
||||||
/*setOverlayContent('Update Available', 'A new update for the launcher is available. Would you like to install now?', 'Install', 'Later')
|
/*setOverlayContent('Update Available', 'A new update for the launcher is available. Would you like to install now?', 'Install', 'Later')
|
||||||
setOverlayHandler(() => {
|
setOverlayHandler(() => {
|
||||||
if(!isDev){
|
if(!isDev){
|
||||||
ipcRenderer.send('autoUpdateAction', 'installUpdateNow')
|
ipcRenderer.send('autoUpdateAction', 'installUpdateNow')
|
||||||
} else {
|
} else {
|
||||||
console.error('Cannot install updates in development environment.')
|
console.error('Cannot install updates in development environment.')
|
||||||
toggleOverlay(false)
|
toggleOverlay(false)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
setDismissHandler(() => {
|
setDismissHandler(() => {
|
||||||
toggleOverlay(false)
|
toggleOverlay(false)
|
||||||
})
|
})
|
||||||
toggleOverlay(true, true)*/
|
toggleOverlay(true, true)*/
|
||||||
switchView(getCurrentView(), VIEWS.settings, 500, 500, () => {
|
switchView(getCurrentView(), VIEWS.settings, 500, 500, () => {
|
||||||
settingsNavItemListener(document.getElementById('settingsNavUpdate'), false)
|
settingsNavItemListener(document.getElementById('settingsNavUpdate'), false)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* jQuery Example
|
/* jQuery Example
|
||||||
$(function(){
|
$(function(){
|
||||||
loggerUICore.log('UICore Initialized');
|
loggerUICore.log('UICore Initialized');
|
||||||
})*/
|
})*/
|
||||||
|
|
||||||
document.addEventListener('readystatechange', function () {
|
document.addEventListener('readystatechange', function () {
|
||||||
if (document.readyState === 'interactive'){
|
if (document.readyState === 'interactive'){
|
||||||
loggerUICore.log('UICore Initializing..')
|
loggerUICore.log('UICore Initializing..')
|
||||||
|
|
||||||
// Bind close button.
|
// Bind close button.
|
||||||
Array.from(document.getElementsByClassName('fCb')).map((val) => {
|
Array.from(document.getElementsByClassName('fCb')).map((val) => {
|
||||||
val.addEventListener('click', e => {
|
val.addEventListener('click', e => {
|
||||||
const window = remote.getCurrentWindow()
|
const window = remote.getCurrentWindow()
|
||||||
window.close()
|
window.close()
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
// Bind restore down button.
|
// Bind restore down button.
|
||||||
Array.from(document.getElementsByClassName('fRb')).map((val) => {
|
Array.from(document.getElementsByClassName('fRb')).map((val) => {
|
||||||
val.addEventListener('click', e => {
|
val.addEventListener('click', e => {
|
||||||
const window = remote.getCurrentWindow()
|
const window = remote.getCurrentWindow()
|
||||||
if(window.isMaximized()){
|
if(window.isMaximized()){
|
||||||
window.unmaximize()
|
window.unmaximize()
|
||||||
} else {
|
} else {
|
||||||
window.maximize()
|
window.maximize()
|
||||||
}
|
}
|
||||||
document.activeElement.blur()
|
document.activeElement.blur()
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
// Bind minimize button.
|
// Bind minimize button.
|
||||||
Array.from(document.getElementsByClassName('fMb')).map((val) => {
|
Array.from(document.getElementsByClassName('fMb')).map((val) => {
|
||||||
val.addEventListener('click', e => {
|
val.addEventListener('click', e => {
|
||||||
const window = remote.getCurrentWindow()
|
const window = remote.getCurrentWindow()
|
||||||
window.minimize()
|
window.minimize()
|
||||||
document.activeElement.blur()
|
document.activeElement.blur()
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
// Remove focus from social media buttons once they're clicked.
|
// Remove focus from social media buttons once they're clicked.
|
||||||
Array.from(document.getElementsByClassName('mediaURL')).map(val => {
|
Array.from(document.getElementsByClassName('mediaURL')).map(val => {
|
||||||
val.addEventListener('click', e => {
|
val.addEventListener('click', e => {
|
||||||
document.activeElement.blur()
|
document.activeElement.blur()
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
} else if(document.readyState === 'complete'){
|
} else if(document.readyState === 'complete'){
|
||||||
|
|
||||||
//266.01
|
//266.01
|
||||||
//170.8
|
//170.8
|
||||||
//53.21
|
//53.21
|
||||||
// Bind progress bar length to length of bot wrapper
|
// Bind progress bar length to length of bot wrapper
|
||||||
//const targetWidth = document.getElementById("launch_content").getBoundingClientRect().width
|
//const targetWidth = document.getElementById("launch_content").getBoundingClientRect().width
|
||||||
//const targetWidth2 = document.getElementById("server_selection").getBoundingClientRect().width
|
//const targetWidth2 = document.getElementById("server_selection").getBoundingClientRect().width
|
||||||
//const targetWidth3 = document.getElementById("launch_button").getBoundingClientRect().width
|
//const targetWidth3 = document.getElementById("launch_button").getBoundingClientRect().width
|
||||||
|
|
||||||
document.getElementById('launch_details').style.maxWidth = 266.01
|
document.getElementById('launch_details').style.maxWidth = 266.01
|
||||||
document.getElementById('launch_progress').style.width = 170.8
|
document.getElementById('launch_progress').style.width = 170.8
|
||||||
document.getElementById('launch_details_right').style.maxWidth = 170.8
|
document.getElementById('launch_details_right').style.maxWidth = 170.8
|
||||||
document.getElementById('launch_progress_label').style.width = 53.21
|
document.getElementById('launch_progress_label').style.width = 53.21
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}, false)
|
}, false)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Open web links in the user's default browser.
|
* Open web links in the user's default browser.
|
||||||
*/
|
*/
|
||||||
$(document).on('click', 'a[href^="http"]', function(event) {
|
$(document).on('click', 'a[href^="http"]', function(event) {
|
||||||
event.preventDefault()
|
event.preventDefault()
|
||||||
shell.openExternal(this.href)
|
shell.openExternal(this.href)
|
||||||
})
|
})
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Opens DevTools window if you hold (ctrl + shift + i).
|
* Opens DevTools window if you hold (ctrl + shift + i).
|
||||||
* This will crash the program if you are using multiple
|
* This will crash the program if you are using multiple
|
||||||
* DevTools, for example the chrome debugger in VS Code.
|
* DevTools, for example the chrome debugger in VS Code.
|
||||||
*/
|
*/
|
||||||
document.addEventListener('keydown', function (e) {
|
document.addEventListener('keydown', function (e) {
|
||||||
if((e.key === 'I' || e.key === 'i') && e.ctrlKey && e.shiftKey){
|
if((e.key === 'I' || e.key === 'i') && e.ctrlKey && e.shiftKey){
|
||||||
let window = remote.getCurrentWindow()
|
let window = remote.getCurrentWindow()
|
||||||
window.toggleDevTools()
|
window.toggleDevTools()
|
||||||
}
|
}
|
||||||
})
|
})
|
@ -1,6 +1,6 @@
|
|||||||
/**
|
/**
|
||||||
* Script for welcome.ejs
|
* Script for welcome.ejs
|
||||||
*/
|
*/
|
||||||
document.getElementById('welcomeButton').addEventListener('click', e => {
|
document.getElementById('welcomeButton').addEventListener('click', e => {
|
||||||
switchView(VIEWS.welcome, VIEWS.login)
|
switchView(VIEWS.welcome, VIEWS.login)
|
||||||
})
|
})
|
Loading…
Reference in New Issue
Block a user