Add portable Windows desktop downloads and release uploads

This commit is contained in:
2026-10-11 11:44:27 +05:00
parent fc6da6756d
commit a54a3e7705
24 changed files with 4159 additions and 5 deletions

175
desktop/main.cjs Normal file
View File

@@ -0,0 +1,175 @@
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();
});