"use strict"; import { BrowserWindow, ipcMain } from "electron"; import { createProtocol } from "vue-cli-plugin-electron-builder/lib"; import { backgroundMitt } from '@/modules/emitter'; import { RenderMessage, WindowState } from "@/types"; import { loadWinState, saveToJson } from "./helpers"; import * as path from "path"; const { autoUpdater } = require('electron-updater'); interface IpcRendererPayload { endpoint: string; message: RenderMessage | null; } let win: BrowserWindow | null; let winState: WindowState; // Called when a NavBar button is pressed. const onNavBar = (_event: any, action: string): void => { if (win) { if (action === "close") { win.close() } else { win.minimize() } } } // Util function to render message on ipc-renderer event. const renderMessage = (payload: IpcRendererPayload): void => { if (win) { win.webContents.send(payload.endpoint, { message: payload.message }); } } // Write a json with position and size of window. const saveWindowState = () => { if (win) { const bounds = win.getBounds(); const position = win.getPosition(); if (winState) { winState.width = bounds.width; winState.height = bounds.height; winState.x = position[0]; winState.y = position[1] saveToJson("window.json", winState) } } } // Do this on window mount. const onWindowMount = (): void => { // Must tell initApp that window exists. backgroundMitt.emit('window-active', true); // Handle win nav-bar event. ipcMain.removeAllListeners("nav-bar") // avoid setting duplicate handlers ipcMain.on("nav-bar", onNavBar); // Gateway for messages to the frontend. backgroundMitt.removeAllListeners("ipc-renderer") backgroundMitt.on("ipc-renderer", renderMessage); } // Do this on window dismount (close). const onWindowDismount = (): void => { win = null; backgroundMitt.emit('window-active', false); } // function used by run.ts to create the main window. export async function createWindow(): Promise { return new Promise((resolve, _reject) => { // avoid creating duplicate windows. if (win) resolve(); // Load the saved window state. winState = loadWinState("window.json") // Define the browser window. win = new BrowserWindow({ width: winState.width, height: winState.height, x: winState.x, y: winState.y, resizable: true, backgroundColor: '#EBEBEB', frame: false, minWidth: 350, minHeight: 500, webPreferences: { nodeIntegration: (process.env.ELECTRON_NODE_INTEGRATION as unknown) as boolean, preload: path.join(__dirname, "preload.js") } }); // Load the URL. if (process.env.WEBPACK_DEV_SERVER_URL) { win.loadURL(process.env.WEBPACK_DEV_SERVER_URL as string); // dev } else { createProtocol("app"); win.loadURL("app://./index.html"); // prod } // Handle window close. win.on("closed", onWindowDismount); // Save window state on resize and move. win.on("moved", saveWindowState); win.on("resize", saveWindowState); win.once('ready-to-show', () => { autoUpdater.checkForUpdatesAndNotify(); if (win) win.show() }) // For showing/hiding the splash screen. win.webContents.on('did-finish-load', () => { if (win) win.webContents.send('window-ready', { message: true }); onWindowMount(); resolve(); }); }); } autoUpdater.on('update-available', () => { if (win) win.webContents.send('update_available'); }); autoUpdater.on('update-downloaded', () => { if (win) win.webContents.send('update_downloaded'); });