HeliosLauncher/src/main/main.ts

250 lines
7.6 KiB
TypeScript

import { ipcMain, app, BrowserWindow, Menu, MenuItem } from "electron"
import { prerelease } from "semver"
import { join } from "path"
import { readdirSync } from "fs-extra"
import { format } from "url"
import { autoUpdater } from 'electron-updater'
import isdev from "./isdev"
const installExtensions = async () => {
const installer = require('electron-devtools-installer');
const forceDownload = !!process.env.UPGRADE_EXTENSIONS;
const extensions = ['REACT_DEVELOPER_TOOLS', 'REDUX_DEVTOOLS'];
return Promise.all(
extensions.map(name => installer.default(installer[name], forceDownload))
).catch(console.log); // eslint-disable-line no-console
};
// Setup auto updater.
function initAutoUpdater(event: any, data: any) {
if(data){
autoUpdater.allowPrerelease = true
} else {
// Defaults to true if application version contains prerelease components (e.g. 0.12.1-alpha.1)
// autoUpdater.allowPrerelease = true
}
if(isdev){
autoUpdater.autoInstallOnAppQuit = false
autoUpdater.updateConfigPath = join(__dirname, '..', 'dev-app-update.yml')
}
if(process.platform === 'darwin'){
autoUpdater.autoDownload = false
}
autoUpdater.on('update-available', (info) => {
event.sender.send('autoUpdateNotification', 'update-available', info)
})
autoUpdater.on('update-downloaded', (info) => {
event.sender.send('autoUpdateNotification', 'update-downloaded', info)
})
autoUpdater.on('update-not-available', (info) => {
event.sender.send('autoUpdateNotification', 'update-not-available', info)
})
autoUpdater.on('checking-for-update', () => {
event.sender.send('autoUpdateNotification', 'checking-for-update')
})
autoUpdater.on('error', (err) => {
event.sender.send('autoUpdateNotification', 'realerror', err)
})
}
// Open channel to listen for update actions.
ipcMain.on('autoUpdateAction', (event, arg, data) => {
switch(arg){
case 'initAutoUpdater':
console.log('Initializing auto updater.')
initAutoUpdater(event, data)
event.sender.send('autoUpdateNotification', 'ready')
break
case 'checkForUpdate':
autoUpdater.checkForUpdates()
.catch(err => {
event.sender.send('autoUpdateNotification', 'realerror', err)
})
break
case 'allowPrereleaseChange':
if(!data){
const preRelComp = prerelease(app.getVersion())
if(preRelComp != null && preRelComp.length > 0){
autoUpdater.allowPrerelease = true
} else {
autoUpdater.allowPrerelease = data
}
} else {
autoUpdater.allowPrerelease = data
}
break
case 'installUpdateNow':
autoUpdater.quitAndInstall()
break
default:
console.log('Unknown argument', arg)
break
}
})
// Redirect distribution index event from preloader to renderer.
ipcMain.on('distributionIndexDone', (event, res) => {
event.sender.send('distributionIndexDone', res)
})
// Disable hardware acceleration.
// https://electronjs.org/docs/tutorial/offscreen-rendering
app.disableHardwareAcceleration()
// Keep a global reference of the window object, if you don't, the window will
// be closed automatically when the JavaScript object is garbage collected.
let win: BrowserWindow | null
async function createWindow() {
if (process.env.NODE_ENV !== 'production') {
await installExtensions();
}
win = new BrowserWindow({
width: 980,
height: 552,
icon: getPlatformIcon('SealCircle'),
frame: false,
webPreferences: {
preload: join(__dirname, '..', 'out', 'preloader.js'),
nodeIntegration: true,
contextIsolation: false
},
backgroundColor: '#171614'
})
// ejse.data('bkid', Math.floor((Math.random() * readdirSync(join(__dirname, '..', 'assets', 'images', 'backgrounds')).length)))
win.loadURL(format({
pathname: join(__dirname, 'index.html'),
protocol: 'file:',
slashes: true
}))
/*win.once('ready-to-show', () => {
win.show()
})*/
win.removeMenu()
win.resizable = true
if (process.env.NODE_ENV !== 'production') {
// Open DevTools, see https://github.com/electron/electron/issues/12438 for why we wait for dom-ready
win.webContents.once('dom-ready', () => {
win!.webContents.openDevTools();
});
}
win.on('closed', () => {
win = null
})
}
function createMenu() {
if(process.platform === 'darwin') {
// Extend default included application menu to continue support for quit keyboard shortcut
let applicationSubMenu = new MenuItem({
label: 'Application',
submenu: [{
label: 'About Application',
role: 'about'
}, {
type: 'separator'
}, {
label: 'Quit',
accelerator: 'Command+Q',
role: 'quit',
click: () => {
app.quit()
}
}]
})
// New edit menu adds support for text-editing keyboard shortcuts
let editSubMenu = new MenuItem({
label: 'Edit',
submenu: [
{
label: 'Undo',
accelerator: 'CmdOrCtrl+Z',
role: 'undo'
},
{
label: 'Redo',
accelerator: 'Shift+CmdOrCtrl+Z',
role: 'redo'
},
{
type: 'separator'
},
{
label: 'Cut',
accelerator: 'CmdOrCtrl+X',
role: 'cut'
},
{
label: 'Copy',
accelerator: 'CmdOrCtrl+C',
role: 'copy'
},
{
label: 'Paste',
accelerator: 'CmdOrCtrl+V',
role: 'paste'
},
{
label: 'Select All',
accelerator: 'CmdOrCtrl+A',
role: 'selectAll'
}
]
})
// Bundle submenus into a single template and build a menu object with it
let menuTemplate: MenuItem[] = [applicationSubMenu, editSubMenu]
let menuObject = Menu.buildFromTemplate(menuTemplate)
// Assign it to the application
Menu.setApplicationMenu(menuObject)
}
}
function getPlatformIcon(filename: string){
const opSys = process.platform
if (opSys === 'darwin') {
filename = filename + '.icns'
} else if (opSys === 'win32') {
filename = filename + '.ico'
} else {
filename = filename + '.png'
}
return join(__dirname, '..', 'assets', 'images', filename)
}
app.on('ready', createWindow)
app.on('ready', createMenu)
app.on('window-all-closed', () => {
// On macOS it is common for applications and their menu bar
// to stay active until the user quits explicitly with Cmd + Q
if (process.platform !== 'darwin') {
app.quit()
}
})
app.on('activate', () => {
// On macOS it's common to re-create a window in the app when the
// dock icon is clicked and there are no other windows open.
if (win === null) {
createWindow()
}
})