Files
MineGeo/desktop/main.cjs

176 lines
5.6 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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 =
'<!doctype html><html lang="en"><meta charset="utf-8"><meta http-equiv="Content-Security-Policy" content="default-src \'none\'; style-src \'unsafe-inline\'"><title>MineGeo · Connection interrupted</title><body style="background:#14201b;color:#f4f1e6;font:18px system-ui;padding:10vh 10vw"><h1>Let’s get you back to MineGeo.</h1><p>Check your internet connection, then choose Game → Retry connection (Ctrl+R).</p><p>Your account and saved games will be here when you reconnect.</p></body></html>';
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();
});