const { app, BrowserWindow, Menu, dialog, shell } = require("electron"); const path = require("node:path"); const { SITE_URL, isInternal, isExternal } = require("./navigation.cjs"); let mainWindow; const smokeTest = process.argv.includes("--smoke-test"); app.setAppUserModelId("app.minegeo.desktop"); if (!app.requestSingleInstanceLock()) app.quit(); else { app.on("second-instance", () => { if (!mainWindow) return; if (mainWindow.isMinimized()) mainWindow.restore(); mainWindow.show(); mainWindow.focus(); }); app.whenReady().then(createWindow); } function openExternal(url) { if (isExternal(url)) shell.openExternal(url).catch(() => {}); } function createWindow() { mainWindow = new BrowserWindow({ width: 1360, height: 900, minWidth: 800, minHeight: 600, title: "MineGeo", backgroundColor: "#14201b", show: false, icon: path.join(__dirname, "assets/icon.png"), webPreferences: { nodeIntegration: false, contextIsolation: true, sandbox: true, webSecurity: true, allowRunningInsecureContent: false, partition: "persist:minegeo", }, }); const contents = mainWindow.webContents; contents.session.setPermissionRequestHandler((_wc, _permission, callback) => callback(false), ); contents.session.setPermissionCheckHandler(() => false); contents.on("will-attach-webview", (event) => event.preventDefault()); for (const eventName of ["will-navigate", "will-redirect"]) { contents.on(eventName, (event, url) => { if (!isInternal(url)) { event.preventDefault(); openExternal(url); } }); } contents.setWindowOpenHandler(({ url }) => { if (isInternal(url)) contents.loadURL(url).catch(() => {}); else openExternal(url); return { action: "deny" }; }); contents.on( "did-fail-load", (_event, code, _description, _url, isMainFrame) => { if (!isMainFrame || code === -3) return; if (smokeTest) { console.error("MineGeo smoke test: load failed", code); app.exit(1); return; } const html = '
Check your internet connection, then choose Game → Retry connection (Ctrl+R).
Your account and saved games will be here when you reconnect.
'; contents .loadURL("data:text/html;charset=utf-8," + encodeURIComponent(html)) .catch(() => {}); mainWindow.show(); }, ); mainWindow.once("ready-to-show", () => mainWindow.show()); contents.on("did-finish-load", () => { if (smokeTest && isInternal(contents.getURL())) { console.log( "MineGeo smoke test: production site loaded with sandbox enabled", ); app.exit(0); } }); contents.session.on("will-download", (_event, item) => { item.once("done", (_downloadEvent, state) => { if (state === "interrupted" && !mainWindow.isDestroyed()) dialog.showMessageBox(mainWindow, { type: "error", title: "Download interrupted", message: "Please check your connection and try downloading again.", }); }); }); Menu.setApplicationMenu( Menu.buildFromTemplate([ { label: "Game", submenu: [ { label: "Home", accelerator: "Alt+Home", click: () => contents.loadURL(SITE_URL).catch(() => {}), }, { label: "Back", accelerator: "Alt+Left", click: () => { if (contents.navigationHistory.canGoBack()) contents.navigationHistory.goBack(); }, }, { label: "Retry connection", accelerator: "CmdOrCtrl+R", click: () => { if (isInternal(contents.getURL())) contents.reload(); else contents.loadURL(SITE_URL).catch(() => {}); }, }, { type: "separator" }, { role: "quit" }, ], }, { label: "Edit", submenu: [ { role: "undo" }, { role: "redo" }, { type: "separator" }, { role: "cut" }, { role: "copy" }, { role: "paste" }, { role: "selectAll" }, ], }, { label: "View", submenu: [ { role: "resetZoom" }, { role: "zoomIn" }, { role: "zoomOut" }, { type: "separator" }, { role: "togglefullscreen" }, ], }, { label: "Help", submenu: [ { label: "Open in browser", click: () => openExternal(SITE_URL) }, { label: "About MineGeo", click: () => dialog.showMessageBox(mainWindow, { title: "MineGeo", message: `MineGeo Desktop ${app.getVersion()}`, detail: "Play at minegeo.vercel.app. Requires an internet connection.", }), }, ], }, ]), ); contents.loadURL(SITE_URL).catch(() => {}); if (smokeTest) setTimeout(() => app.exit(1), 60000).unref(); mainWindow.on("closed", () => { mainWindow = null; }); } app.on("window-all-closed", () => { if (process.platform !== "darwin") app.quit(); }); app.on("activate", () => { if (BrowserWindow.getAllWindows().length === 0) createWindow(); });