import { ipcMain, BrowserWindow, app, screen } from "electron"; import path from "path"; import _ from "lodash"; import settings from "../settings"; import { createBarcodeHandler, parseUserId } from "../utils/barcodeHandler"; import { findWindow } from "../utils/winapi/getWindowData"; import openDevToolsWindow from "../utils/openDevToolsWindow"; const isDev = process.env.NODE_ENV === "development"; const kInputEventChannel = "input-event"; const kHelpdeskChannel = "helpdesk-channel"; const kSupportWindow = "openSupportWindow"; const kOverlayWindow = "openOverlayWindow"; const kHelpdeskRoute = "helpdesk"; const kHelpdeskOverlayRoute = "helpdesk-overlay"; const kOpenIssues = "open-issues"; const readIssuesFromSettings = () => { const array = settings.get(kOpenIssues); return ( array?.map((id) => { return { id }; }) || [] ); }; const saveIssueToSettings = (issues) => { return settings.set( kOpenIssues, issues.map((i) => i.id) ); }; export default async function initHelpdeskChannel(mainWindow) { //* Handle support window let supportWin; let overlayWin; let supportDevToolsWin; let overlayDevToolsWin; const cachedOpenIssues = readIssuesFromSettings(); // Open Helpdesk window ipcMain.handle(kSupportWindow, async () => { if (supportWin) { supportWin.focus(); return; } mainWindow.webContents.send(kHelpdeskChannel, { event: "helpdesk-form-opened", }); const { height: screenHeight } = isDev ? screen.getPrimaryDisplay().workAreaSize : screen.getPrimaryDisplay().size; let width = 900; let height = 700; if (screenHeight <= 600) { width = 700; height = 500; } else if (screenHeight <= 768) { width = 800; height = 600; } const win = new BrowserWindow({ width, height, center: true, show: true, alwaysOnTop: false, resizable: isDev, minimizable: false, maximizable: false, backgroundColor: "#2e2c29", webPreferences: { preload: path.join(app.getAppPath(), "./dist/preload.js"), nodeIntegration: true, contextIsolation: false, backgroundThrottling: false, devTools: isDev, additionalArguments: ["helpdesk-form"], }, }); win.setMenu(null); supportWin = win; 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); } }; ipcMain.on(kInputEventChannel, inputEventCallback); win.on("close", () => { supportWin = null; if (!supportDevToolsWin?.isDestroyed()) supportDevToolsWin?.close(); supportDevToolsWin = null; ipcMain.removeListener(kInputEventChannel, inputEventCallback); mainWindow.webContents.send(kHelpdeskChannel, { event: "helpdesk-form-closed", }); }); win.once("ready-to-show", () => { win.title = "Helpdesk"; win.setAlwaysOnTop(true, "screen-saver"); // prevents from overlapping in some cases }); if (isDev) { win.loadURL(`http://localhost:4000#/${kHelpdeskRoute}`); supportDevToolsWin = openDevToolsWindow({ window: win, title: "Helpdesk form", }); } else { win.loadURL( `file://${app.getAppPath()}/dist/renderer/index.html#/${kHelpdeskRoute}` ); } }); // Open helpdesk overlay window ipcMain.on(kOverlayWindow, () => { if (overlayWin) { overlayWin.focus(); return; } const { width: screenW, height: screenH } = screen.getPrimaryDisplay().workAreaSize; let ratio = 5; if (screenW <= 1600) ratio = 4; if (screenW <= 1280) ratio = 3.5; if (screenW <= 1024) ratio = 3; const winWidth = Math.round(screenW / ratio); const winHeight = screenH; const winX = Math.round(screenW - winWidth); const winY = 0; const win = new BrowserWindow({ x: winX, y: winY, width: winWidth, height: winHeight, show: false, alwaysOnTop: true, skipTaskbar: true, transparent: true, frame: false, resizable: false, minimizable: false, maximizable: false, webPreferences: { preload: path.join(app.getAppPath(), "./dist/preload.js"), nodeIntegration: true, contextIsolation: false, backgroundThrottling: false, devTools: isDev, additionalArguments: ["helpdesk-overlay"], }, }); win.setMenu(null); overlayWin = win; win.once("ready-to-show", () => { win.setAlwaysOnTop(true, "screen-saver"); win.showInactive(); setTimeout(() => win.setIgnoreMouseEvents(true), 500); }); win.on("close", () => { if (!overlayDevToolsWin?.isDestroyed()) overlayDevToolsWin?.close(); overlayWin = null; overlayDevToolsWin = null; }); if (isDev) { win.loadURL(`http://localhost:4000#/${kHelpdeskOverlayRoute}`); overlayDevToolsWin = openDevToolsWindow({ window: win, title: "Helpdesk overlay", }); } else { win.loadURL( `file://${app.getAppPath()}/dist/renderer/index.html#/${kHelpdeskOverlayRoute}` ); } }); // Handle helpdesk actions ipcMain.handle(kHelpdeskChannel, async (_e, { event, data }) => { if (event === "add-issue") { cachedOpenIssues.push(data); saveIssueToSettings(cachedOpenIssues); if (overlayWin) { overlayWin.webContents.send(kHelpdeskChannel, { event: "overlay-add-issue", data, }); } else { ipcMain.emit(kOverlayWindow); } return cachedOpenIssues; } if (event === "remove-issue-id") { _.remove(cachedOpenIssues, (i) => i.id === data); saveIssueToSettings(cachedOpenIssues); return cachedOpenIssues; } if (event === "remove-all-issues") { settings.set(kOpenIssues, []); cachedOpenIssues.splice(0, cachedOpenIssues.length); if (overlayWin) overlayWin.close(); } if (event === "get-open-issues") { return readIssuesFromSettings(); } if (event === "get-winkhmman-path") { const result = findWindow({ exeName: "WinKHM.exe" }, () => {}); if (result) { return path.join(path.dirname(result.path), "WinKHMMan.exe"); } } if (event === "helpdesk-form-close") { supportWin.close(); } if (event === "helpdesk-form-show") { supportWin.show(); return true; } if (event === "helpdesk-form-hide") { supportWin.hide(); return true; } return null; }); if (!_.isEmpty(cachedOpenIssues)) setTimeout(() => ipcMain.emit(kOverlayWindow), 10_000); }