diff --git a/resources/index.html b/resources/index.html
index 9766e00..2a19427 100644
--- a/resources/index.html
+++ b/resources/index.html
@@ -5,7 +5,10 @@
+
+
+
diff --git a/resources/js/helpers.js b/resources/js/helpers.js
new file mode 100644
index 0000000..bfd99d3
--- /dev/null
+++ b/resources/js/helpers.js
@@ -0,0 +1,89 @@
+/**
+ * Get configuration
+ *
+ * @returns {Promise}
+ */
+ async function getCfg() {
+ const defaultConf = {
+ genshinImpactFolder: '',
+ serverFolder: '',
+ lastConnect: '',
+ enableKillswitch: false,
+ serverLaunchPanel: false,
+ language: 'en'
+ }
+ const cfgStr = await Neutralino.storage.getData('config').catch(e => {
+ // The data isn't set, so this is our first time opening
+ Neutralino.storage.setData('config', JSON.stringify(defaultConf))
+
+ // Show the first time notice if there is no config
+ document.querySelector('#firstTimeNotice').style.display = 'block'
+ })
+
+ const config = cfgStr ? JSON.parse(cfgStr) : defaultConf
+
+ return config
+}
+
+/**
+ * Get the list of favorite IPs
+ *
+ * @returns {Promise}
+ */
+ async function getFavIps() {
+ const ipStr = await Neutralino.storage.getData('favorites').catch(e => {
+ // The data isn't set, so this is our first time opening
+ Neutralino.storage.setData('favorites', JSON.stringify([]))
+ })
+
+ const ipArr = ipStr ? JSON.parse(ipStr) : []
+
+ return ipArr
+}
+
+async function proxyIsInstalled() {
+ // Check if the proxy server is installed
+ const curDirList = await filesystem.readDirectory(NL_CWD)
+
+ if (curDirList.find(f => f.entry === 'ext')) {
+ const extFiles = await filesystem.readDirectory(NL_CWD + '/ext')
+
+ if (extFiles.find(f => f.entry === 'mitmdump.exe')) {
+ return true
+ }
+ }
+
+ return false
+}
+
+/**
+ * Get the name of the game executable
+ *
+ * @returns {Promise}
+ */
+ async function getGenshinExecName() {
+ // Scan genshin dir
+ const config = await getCfg()
+ const genshinDir = await filesystem.readDirectory(config.genshinImpactFolder)
+
+ // Find the executable
+ const genshinExec = genshinDir.find(file => file.entry.endsWith('.exe'))
+
+ return genshinExec.entry
+}
+
+/**
+ * Minimize the window
+ */
+ function minimizeWin() {
+ console.log('min')
+ Neutralino.window.minimize()
+}
+
+/**
+ * Close the window
+ */
+function closeWin() {
+ console.log('close')
+ Neutralino.app.exit()
+}
diff --git a/resources/js/index.js b/resources/js/index.js
index 128377b..edc4bd8 100644
--- a/resources/js/index.js
+++ b/resources/js/index.js
@@ -3,127 +3,6 @@ Neutralino.init();
let localeObj;
const filesystem = Neutralino.filesystem
-/**
- * Every autofill, such as backgrounds and the game folder,
- * should be done here to ensure DOM contents are loaded.
- */
-document.addEventListener('DOMContentLoaded', async () => {
- setBackgroundImage();
- displayGenshinFolder();
- displayServerFolder();
-
- // Set title version
- document.querySelector('#version').innerHTML = NL_APPVERSION
-
- const config = await getCfg()
- const ipArr = await getFavIps()
-
- if (config.serverLaunchPanel) {
- displayServerLaunchSection()
- }
-
- // Set last connect
- document.querySelector('#ip').value = config.lastConnect
-
- if (ipArr.includes(config.lastConnect)) {
- document.querySelector('#star').src = 'icons/star_filled.svg'
- }
-
- // Disable private game launch if proxy IP or proxy server is not found
- const playPriv = document.querySelector('#playPrivate')
-
- if (!(await proxyIsInstalled())) {
- playPriv.classList.add('disabled')
- playPriv.disabled = true
- }
-
- // Exit favorites list and settings panel when clicking outside of it
- window.addEventListener("click", function(e) {
- const favList = document.querySelector('#ipList')
- const settingsPanel = document.querySelector('#settingsPanel')
-
- // This will close the favorites list no matter what is clicked
- if (favList.style.display !== 'none') {
- favList.style.display = 'none'
- favList.style.transform = ''
- }
-
- // This will close the settings panel no matter what is clicked
- let settingCheckElm = e.target
-
- while(settingCheckElm.tagName !== 'BODY') {
- if (settingCheckElm.id === 'settingsPanel'
- || settingCheckElm.id === 'settingsBtn') {
- return
- }
-
- settingCheckElm = settingCheckElm.parentElement
- }
-
- // We travelled through the parents, so if we are at the body, we clicked outside of the settings panel
- if (settingCheckElm.tagName === 'BODY') {
- // This will close the settings panel only when something outside of it is clicked
- if (settingsPanel.style.display !== 'none') {
- settingsPanel.style.display = 'none'
- }
- }
- });
-
- // Ensure we do the translation at the very end, after everything else has loaded
- await doTranslation()
-
- if (!config.genshinImpactFolder) {
- handleGenshinFolderNotSet()
- }
-
- if (!config.serverFolder) {
- handleServerNotSet()
- }
-})
-
-/**
- * Get the list of favorite IPs
- *
- * @returns {Promise}
- */
-async function getFavIps() {
- const ipStr = await Neutralino.storage.getData('favorites').catch(e => {
- // The data isn't set, so this is our first time opening
- Neutralino.storage.setData('favorites', JSON.stringify([]))
- })
-
- const ipArr = ipStr ? JSON.parse(ipStr) : []
-
- return ipArr
-}
-
-/**
- * Get configuration
- *
- * @returns {Promise}
- */
-async function getCfg() {
- const defaultConf = {
- genshinImpactFolder: '',
- serverFolder: '',
- lastConnect: '',
- enableKillswitch: false,
- serverLaunchPanel: false,
- language: 'en'
- }
- const cfgStr = await Neutralino.storage.getData('config').catch(e => {
- // The data isn't set, so this is our first time opening
- Neutralino.storage.setData('config', JSON.stringify(defaultConf))
-
- // Show the first time notice if there is no config
- document.querySelector('#firstTimeNotice').style.display = 'block'
- })
-
- const config = cfgStr ? JSON.parse(cfgStr) : defaultConf
-
- return config
-}
-
/**
* Enable play buttons
*/
@@ -186,21 +65,6 @@ async function handleServerNotSet() {
privBtn.disabled = true
}
-async function proxyIsInstalled() {
- // Check if the proxy server is installed
- const curDirList = await filesystem.readDirectory(NL_CWD)
-
- if (curDirList.find(f => f.entry === 'ext')) {
- const extFiles = await filesystem.readDirectory(NL_CWD + '/ext')
-
- if (extFiles.find(f => f.entry === 'mitmdump.exe')) {
- return true
- }
- }
-
- return false
-}
-
/**
* Show the game folder under the select button
*/
@@ -366,35 +230,6 @@ async function handleFavoriteList() {
}
}
-/**
- * Add the current value of the IP input to the favorites list
- * OR
- * Remove the current value of the IP input from the favorites list
- */
-async function setFavorite() {
- const ip = document.querySelector('#ip').value
- const ipArr = await getFavIps()
-
- // Set star icon
- const star = document.querySelector('#star')
-
- if (star.src.includes('filled') && ip) {
- star.src = 'icons/star_empty.svg'
-
- // remove from list
- ipArr.splice(ipArr.indexOf(ip), 1)
- } else {
- star.src = 'icons/star_filled.svg'
-
- // add to list
- if (ip && !ipArr.includes(ip)) {
- ipArr.push(ip)
- }
- }
-
- Neutralino.storage.setData('favorites', JSON.stringify(ipArr))
-}
-
async function openSettings() {
const settings = document.querySelector('#settingsPanel')
const config = await getCfg()
@@ -432,15 +267,6 @@ async function closeSettings() {
}
}
-async function toggleKillSwitch() {
- const killSwitch = document.querySelector('#killswitchOption')
- const config = await getCfg()
-
- config.enableKillswitch = killSwitch.checked
-
- Neutralino.storage.setData('config', JSON.stringify(config))
-}
-
async function closeFirstTimePopup() {
const firstTimePopup = document.querySelector('#firstTimeNotice')
firstTimePopup.style.display = 'none'
@@ -485,55 +311,6 @@ async function displayServerLaunchSection() {
}
}
-async function toggleServerLaunchSection() {
- const config = await getCfg()
-
- displayServerLaunchSection()
-
- // Save setting
- config.serverLaunchPanel = !config.serverLaunchPanel
- Neutralino.storage.setData('config', JSON.stringify(config))
-}
-
-async function getLanguages() {
- const languageFiles = (await filesystem.readDirectory(`${NL_CWD}/languages`)).filter(file => file.entry.endsWith('.json'))
- const config = await getCfg()
-
- // Clear language options
- const languageSelect = document.querySelector('#languageSelect')
- languageSelect.innerHTML = ''
-
- // Load all languages as options
- for (const file of languageFiles) {
- const fullLanguageName = JSON.parse(await filesystem.readFile(`${NL_CWD}/languages/${file.entry}`)).fullLangName
- const lang = file.entry.split('.json')[0]
-
- const option = document.createElement('option')
- option.value = lang
- option.innerHTML = fullLanguageName
-
- // Set language selected to config language
- if (lang === config.language) {
- option.selected = true
- }
-
- document.querySelector('#languageSelect').appendChild(option)
- }
-
-}
-
-async function handleLanguageChange(elm) {
- const list = elm
- const config = await getCfg()
-
- // Set language in config
- config.language = list.value
- Neutralino.storage.setData('config', JSON.stringify(config))
-
- // Force refresh of application, no need for restart!
- window.location.reload()
-}
-
/**
* Set the game folder by opening a folder picker
*/
@@ -579,22 +356,6 @@ async function setGrassCutterFolder() {
enableServerButton()
}
-/**
- * Get the name of the game executable
- *
- * @returns {Promise}
- */
-async function getGenshinExecName() {
- // Scan genshin dir
- const config = await getCfg()
- const genshinDir = await filesystem.readDirectory(config.genshinImpactFolder)
-
- // Find the executable
- const genshinExec = genshinDir.find(file => file.entry.endsWith('.exe'))
-
- return genshinExec.entry
-}
-
/**
* Launch the game with no modifications nor proxy
*/
@@ -627,19 +388,3 @@ async function launchLocalServer() {
Neutralino.os.execCommand(`${NL_CWD}/scripts/local_server_launch.cmd "${config.serverFolder}"`).catch(e => console.log(e))
}
-
-/**
- * Minimize the window
- */
-function minimizeWin() {
- console.log('min')
- Neutralino.window.minimize()
-}
-
-/**
- * Close the window
- */
-function closeWin() {
- console.log('close')
- Neutralino.app.exit()
-}
\ No newline at end of file
diff --git a/resources/js/onLoad.js b/resources/js/onLoad.js
new file mode 100644
index 0000000..3224bb6
--- /dev/null
+++ b/resources/js/onLoad.js
@@ -0,0 +1,78 @@
+
+/**
+ * Every autofill, such as backgrounds and the game folder,
+ * should be done here to ensure DOM contents are loaded.
+ */
+ document.addEventListener('DOMContentLoaded', async () => {
+ setBackgroundImage();
+ displayGenshinFolder();
+ displayServerFolder();
+
+ // Set title version
+ document.querySelector('#version').innerHTML = NL_APPVERSION
+
+ const config = await getCfg()
+ const ipArr = await getFavIps()
+
+ if (config.serverLaunchPanel) {
+ displayServerLaunchSection()
+ }
+
+ // Set last connect
+ document.querySelector('#ip').value = config.lastConnect
+
+ if (ipArr.includes(config.lastConnect)) {
+ document.querySelector('#star').src = 'icons/star_filled.svg'
+ }
+
+ // Disable private game launch if proxy IP or proxy server is not found
+ const playPriv = document.querySelector('#playPrivate')
+
+ if (!(await proxyIsInstalled())) {
+ playPriv.classList.add('disabled')
+ playPriv.disabled = true
+ }
+
+ // Exit favorites list and settings panel when clicking outside of it
+ window.addEventListener("click", function(e) {
+ const favList = document.querySelector('#ipList')
+ const settingsPanel = document.querySelector('#settingsPanel')
+
+ // This will close the favorites list no matter what is clicked
+ if (favList.style.display !== 'none') {
+ favList.style.display = 'none'
+ favList.style.transform = ''
+ }
+
+ // This will close the settings panel no matter what is clicked
+ let settingCheckElm = e.target
+
+ while(settingCheckElm.tagName !== 'BODY') {
+ if (settingCheckElm.id === 'settingsPanel'
+ || settingCheckElm.id === 'settingsBtn') {
+ return
+ }
+
+ settingCheckElm = settingCheckElm.parentElement
+ }
+
+ // We travelled through the parents, so if we are at the body, we clicked outside of the settings panel
+ if (settingCheckElm.tagName === 'BODY') {
+ // This will close the settings panel only when something outside of it is clicked
+ if (settingsPanel.style.display !== 'none') {
+ settingsPanel.style.display = 'none'
+ }
+ }
+ });
+
+ // Ensure we do the translation at the very end, after everything else has loaded
+ await doTranslation()
+
+ if (!config.genshinImpactFolder) {
+ handleGenshinFolderNotSet()
+ }
+
+ if (!config.serverFolder) {
+ handleServerNotSet()
+ }
+})
diff --git a/resources/js/options.js b/resources/js/options.js
new file mode 100644
index 0000000..65eb8a1
--- /dev/null
+++ b/resources/js/options.js
@@ -0,0 +1,100 @@
+/**
+ * Toggle the killswitch script
+ */
+async function toggleKillSwitch() {
+ const killSwitch = document.querySelector('#killswitchOption')
+ const config = await getCfg()
+
+ config.enableKillswitch = killSwitch.checked
+
+ Neutralino.storage.setData('config', JSON.stringify(config))
+}
+
+/**
+ * Toggles the server launching panel
+ */
+async function toggleServerLaunchSection() {
+ const config = await getCfg()
+
+ displayServerLaunchSection()
+
+ // Save setting
+ config.serverLaunchPanel = !config.serverLaunchPanel
+ Neutralino.storage.setData('config', JSON.stringify(config))
+}
+
+/**
+ * Get all languages for the language selector
+ */
+async function getLanguages() {
+ const languageFiles = (await filesystem.readDirectory(`${NL_CWD}/languages`)).filter(file => file.entry.endsWith('.json'))
+ const config = await getCfg()
+
+ // Clear language options
+ const languageSelect = document.querySelector('#languageSelect')
+ languageSelect.innerHTML = ''
+
+ // Load all languages as options
+ for (const file of languageFiles) {
+ const fullLanguageName = JSON.parse(await filesystem.readFile(`${NL_CWD}/languages/${file.entry}`)).fullLangName
+ const lang = file.entry.split('.json')[0]
+
+ const option = document.createElement('option')
+ option.value = lang
+ option.innerHTML = fullLanguageName
+
+ // Set language selected to config language
+ if (lang === config.language) {
+ option.selected = true
+ }
+
+ document.querySelector('#languageSelect').appendChild(option)
+ }
+}
+
+/**
+ * Save lang, refresh to apply
+ *
+ * @param {DOMElement} elm
+ */
+async function handleLanguageChange(elm) {
+ const list = elm
+ const config = await getCfg()
+
+ // Set language in config
+ config.language = list.value
+ Neutralino.storage.setData('config', JSON.stringify(config))
+
+ // Force refresh of application, no need for restart!
+ window.location.reload()
+}
+
+
+/**
+ * Add the current value of the IP input to the favorites list
+ * OR
+ * Remove the current value of the IP input from the favorites list
+ */
+ async function setFavorite() {
+ const ip = document.querySelector('#ip').value
+ const ipArr = await getFavIps()
+
+ // Set star icon
+ const star = document.querySelector('#star')
+
+ if (star.src.includes('filled') && ip) {
+ star.src = 'icons/star_empty.svg'
+
+ // remove from list
+ ipArr.splice(ipArr.indexOf(ip), 1)
+ } else {
+ star.src = 'icons/star_filled.svg'
+
+ // add to list
+ if (ip && !ipArr.includes(ip)) {
+ ipArr.push(ip)
+ }
+ }
+
+ Neutralino.storage.setData('favorites', JSON.stringify(ipArr))
+}