const ModPackage = require('./ModPackage') const constants = require('./util/constants.json'), promisify = require('./util/promisify') const create = (name, ...children) => { let classList = name.split('.') ele = document.createElement(classList.shift() || 'div') if(classList) ele.classList = classList.join(' ') children.forEach(child => typeof(child) == 'string' ? ele.innerText += child : ele.appendChild(child) ) return ele } const openAsync = promisify($file.open) class Launcher { constructor(app) { const self = this console.log(this) const options = { title: 'Xash3D Launcher', // html: app.bundle.openSync('./launcher.html', 'String'), bodyClass: 'skin_inset xash3d_launcher', width: 350, height: 400, // TODO: center the version maybe lol onready() { this.el.footer.children[0].appendChild(self.renderFooterControls() ) self.modList = this.el.body.appendChild(create('ul') ) self.loadMods() }, footer: `v${app.version}` } this.app = app this.window = $window(options) } async loadMods() { let { modPath } = constants.paths, files = $io.obj.getPath(window.le._files, modPath, '/'), mods = [] if(files) { for(let name in files) if(files[name] == 0 && this.isModFilename(name)) { let path = modPath + name, promise = openAsync(path, 'ArrayBuffer') .then(async buffer => ({ name, path, size: buffer.byteLength, manifest: await ModPackage.unpack(buffer, true) .then(data => JSON.parse(data.manifestString) ) })) mods.push(promise) } } else { let readme = await this.app.bundle.open('/texts/README.txt', 'String') $file.save($fs.utils.resolvePath(modPath + '/README.txt'), readme) } if(mods.length === 0) { this.displayNoModsNotice() } mods = await Promise.all(mods) mods .map(mod => this.renderMod(mod)) .map(ele => this.modList.appendChild(ele) ) } isModFilename(name) { switch($fs.utils.getExt(name) ) { case 'asar': return true // case 'gz': // return $fs.utils.getFileName(name).endsWith('.asar.gz') default: return false } } async refreshMods () { this.modList.innerText = '' await this.loadMods() } renderMod(mod) { // const mod = document.createElement('div'), // header = document.createElement('header'), // info = document.createElement('div') // modName = document.createElement('h5'), // modInfo = document.createElement('span'), // launch = document.createElement('div') // header.appendChild(modName) // header.appendChild(modInfo) // mod.appendChild('header') let self = this, launch, element = create('li.mod.skin_outset', create('header', create('.info', create('h4', mod.manifest.name), create('span', `${mod.name} | ${parseInt(mod.size / 1_000_000)}mb`) ), launch = create('.launch') ) ) launch.onclick = () => { self.app.launch(mod.path) self.window.destroy() } return element } displayNoModsNotice() { let element = create('li.notice.skin_outset', create('h3', constants.messages.noMods.header), create('p', constants.messages.noMods.content) ) this.modList.appendChild(element) } renderFooterControls() { let openModsButton let refreshButton let controls = create('span.controls', openModsButton = create('button', 'Open Mods Folder'), refreshButton = create('button', 'Refresh') ) openModsButton.addEventListener('click', () => { $exe(constants.paths.modPath) }) refreshButton.addEventListener('click', () => { this.refreshMods() }) return controls } } module.exports = Launcher