All checks were successful
Deploy MineGeo to Dokploy / deploy (push) Successful in 5m57s
176 lines
5.6 KiB
JavaScript
176 lines
5.6 KiB
JavaScript
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.site. 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();
|
||
});
|