"use strict"; import { BrowserWindow, ipcMain } from "electron"; import { createProtocol } from "vue-cli-plugin-electron-builder/lib"; import { backgroundMitt } from './emitter'; import { RenderMessage } from "@/types/message/index"; import * as path from "path"; import fs from 'fs'; interface IpcRendererPayload { endpoint: string; message: RenderMessage | null; } let win: BrowserWindow | null; // Util function to handle window close & minimize. const navBarHandler = (_event, action: string): void => { switch(action) { case 'close': if (win) win.close(); break; case 'min': if (win) win.minimize(); break; } } // Util function to render message on ipc-renderer event. const renderMessage = (payload: IpcRendererPayload): void => { if (win) { win.webContents.send(payload.endpoint, { message: payload.message }); } } const onWindowSave = (_event, _s: string) => { if (win) { const bounds = win.getBounds(); const state = JSON.stringify({w: bounds.width, h: bounds.height}); fs.writeFile('windowstate.json', state, (err: Error) => { if (err) throw err; return; }); } } // Do this on window mount. const windowMount = (): void => { backgroundMitt.emit('window-active', true); // handle win nav-bar event. ipcMain.removeHandler('nav-bar'); // avoid setting duplicate handlers ipcMain.handle('nav-bar', navBarHandler); ipcMain.removeHandler('window-save'); // avoid setting duplicate handlers ipcMain.handle('window-save', onWindowSave); // render messages through ipc-renderer. backgroundMitt.on('ipc-renderer', renderMessage); } // do this on window dismount. const windowDismount = (): 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(); // read windowState from json. const rawData = fs.readFileSync('windowState.json'); const windowState = JSON.parse(rawData); win = new BrowserWindow({ width: windowState.w, height: windowState.h, resizable: true, backgroundColor: '#EBEBEB', frame: false, minWidth: 350, minHeight: 500, webPreferences: { // Use pluginOptions.nodeIntegration, leave this alone // See nklayman.github.io/vue-cli-plugin-electron-builder/guide/security.html#node-integration for more info nodeIntegration: (process.env .ELECTRON_NODE_INTEGRATION as unknown) as boolean, preload: path.join(__dirname, "preload.js") } }); if (process.env.WEBPACK_DEV_SERVER_URL) { // Load the url of the dev server if in development mode win.loadURL(process.env.WEBPACK_DEV_SERVER_URL as string); } else { createProtocol("app"); // Load the index.html when not in development win.loadURL("app://./index.html"); } // Handle window close. win.on("closed", windowDismount); win.once('ready-to-show', () => { if (win) win.show() }) win.webContents.on('did-finish-load', () => { if (win) win.webContents.send('window-ready', { message: true }); windowMount(); resolve(); }); }); }