"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; // 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(); const state = JSON.stringify( { w: bounds.width, h: bounds.height, x: position[0], y: position[1] } ); fs.writeFile('windowState.json', state, (err) => { if (err) throw err; return; }); } } // Do this on window mount. const onWindowMount = (): void => { console.log("BW:Adding window listeners. ") // Must tell initApp that window exists. backgroundMitt.emit('window-active', true); // Handle win nav-bar event. ipcMain.removeHandler("nav-bar") // avoid setting duplicate handlers ipcMain.handle("nav-bar", onNavBar); // Gateway for messages to the frontend. backgroundMitt.removeAllListeners('ipc-renderer') backgroundMitt.on('ipc-renderer', renderMessage); console.log("BW:Listeners created.") } // Do this on window dismount (close). const onWindowDismount = (): void => { console.log("BW:Window closed.") 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) => { console.log("BW:Creating browser window. ") // avoid creating duplicate windows. if (win) resolve(); // Load the saved window state. const state = JSON.parse(fs.readFileSync('windowState.json').toString()); // Define the browser window. win = new BrowserWindow({ width: state.w, height: state.h, x: state.x, y: state.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', () => { 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(); }); }); }