import path from "path"; import { BrowserWindow, app, ipcMain, screen, Menu } from "electron"; import { createBarcodeHandler, parseUserId } from "../utils/barcodeHandler"; import createBrowserWindowTemplate from "../utils/createBrowserWindowTemplate"; import openDevToolsWindow from "../utils/openDevToolsWindow"; const isDev = process.env.NODE_ENV === "development"; const kInformingChannel = "informing"; const kInputEventChannel = "input-event"; let connectionStatus = false; export default async function initInformingChannel(mainWindow) { const route = "informing"; let url = `file:///${app .getAppPath() .replace(/\\/g, "/")}/dist/renderer/index.html#/${route}`; if (isDev) { url = `http://localhost:4000/#/${route}`; } const win = new BrowserWindow({ show: false, alwaysOnTop: true, movable: true, resizable: true, minimizable: false, backgroundColor: "lightblue", hasShadow: false, webPreferences: { preload: path.join(app.getAppPath(), "./dist/preload.js"), nodeIntegration: true, contextIsolation: false, backgroundThrottling: true, devTools: isDev, additionalArguments: [route], }, }); win.setMenu(null); win.setAlwaysOnTop(true, "pop-up-menu"); win.setFocusable(false); win.loadURL(url); const barcodeProcessor = (barcode) => { const userId = parseUserId(barcode); if (userId) win.webContents.send(kInputEventChannel, userId); }; const barcodeHandler = createBarcodeHandler(barcodeProcessor, 200, 4); const inputEventCallback = (message) => { if (message.event === "key-down") { const { char } = message.data; barcodeHandler(char); } }; win.on("show", () => { setTimeout(() => win.focus(), 200); ipcMain.on(kInputEventChannel, inputEventCallback); }); win.on("close", (e) => { e.preventDefault(); win.hide(); ipcMain.removeListener(kInputEventChannel, inputEventCallback); win.webContents.send(kInformingChannel, { event: "hidden" }); }); win.webContents.on("will-navigate", (e, navUrl) => { // preventDefault and url check exists because "will-navigate" emits with undefined url after rxdb indexedDB.deleteDatabase recreated // navUrl compared with url to prevent open while dev hot reload if (navUrl && navUrl !== url) { e.preventDefault(); let externalWin = new BrowserWindow({ alwaysOnTop: true, center: true, }); externalWin.setMenu( Menu.buildFromTemplate( createBrowserWindowTemplate(externalWin, "informing external url") ) ); externalWin.on("closed", () => { externalWin = null; }); externalWin.loadURL(url); } }); ipcMain.handle(kInformingChannel, async (_e, { event, data }) => { switch (event) { case "show": { const { isOverlay } = data; const { width: screenWidth, height: screenHeight } = screen.getPrimaryDisplay().size; if (isOverlay) { const { height: winh } = win.getBounds(); const { height: winContentH } = win.getContentBounds(); const titleH = Math.floor(winh - winContentH) - 8; win.unmaximize(); // setBounds doesnt work on maximized win win.setOpacity(0.8); win.setBounds({ x: 0, y: 0 - titleH, // y with offset to hide title width: Math.floor(screenWidth), height: Math.floor(screenHeight / 5), }); win.setIgnoreMouseEvents(true); win.show(); } else { win.setOpacity(1); win.setIgnoreMouseEvents(false); // reset size win.setSize( Math.floor(screenWidth / 1.5), Math.floor(screenHeight / 1.5) ); win.center(); win.maximize(); } return true; } case "hide": win.hide(); return true; case "set-closable": win.setClosable(data); return true; case "open-devtools": openDevToolsWindow({ window: win, title: "Informing window" }); return true; case "connection-status": return connectionStatus; case "connection-changed": connectionStatus = data; mainWindow.webContents.send(kInformingChannel, { event: "connection-changed", data, }); return true; default: break; } return false; }); }