Add portable Windows desktop downloads and release uploads
This commit is contained in:
175
desktop/main.cjs
Normal file
175
desktop/main.cjs
Normal 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();
|
||||
});
|
||||
Reference in New Issue
Block a user