claude fixed ts for me so kids can stop dming me
This commit is contained in:
@@ -54,7 +54,7 @@ jobs:
|
|||||||
env:
|
env:
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
run: |
|
run: |
|
||||||
gh release create Overlord-Desktop-v${{ env.VERSION }} "dist/Overlord Setup.exe" \
|
gh release create Overlord-Desktop-v${{ env.VERSION }} "dist/Overlord Setup.exe" "PLEASE_READ.txt" \
|
||||||
-t "Overlord Desktop v${{ env.VERSION }}" \
|
-t "Overlord Desktop v${{ env.VERSION }}" \
|
||||||
-n "Automated build release for Overlord Desktop v${{ env.VERSION }}" \
|
-n "Automated build release for Overlord Desktop v${{ env.VERSION }}" \
|
||||||
--draft=false \
|
--draft=false \
|
||||||
|
|||||||
@@ -0,0 +1,32 @@
|
|||||||
|
================================================================================
|
||||||
|
OVERLORD DESKTOP — PLEASE READ BEFORE USING
|
||||||
|
================================================================================
|
||||||
|
|
||||||
|
This application is a DESKTOP CLIENT ONLY. It does NOT include the server.
|
||||||
|
|
||||||
|
If you launch Overlord Desktop without a running Overlord server, it will
|
||||||
|
show a connection error and nothing will work. That is expected.
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
WHAT YOU NEED TO DO
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
1. Set up and start the Overlord server FIRST.
|
||||||
|
The server is a separate component that you must deploy yourself.
|
||||||
|
|
||||||
|
2. Full setup instructions are in the README:
|
||||||
|
https://github.com/vxaboveground/Overlord/blob/main/README.md
|
||||||
|
|
||||||
|
3. Once the server is running, open this desktop client and enter the
|
||||||
|
server's IP address (or hostname) and port on the connection screen.
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
QUICK SUMMARY
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
Overlord Desktop → connects TO a server
|
||||||
|
Overlord Server → must be running BEFORE you connect
|
||||||
|
|
||||||
|
Without the server, this client is useless.
|
||||||
|
|
||||||
|
================================================================================
|
||||||
@@ -10,7 +10,8 @@ function setStatus(msg, type = "info") {
|
|||||||
statusEl.innerHTML = msg;
|
statusEl.innerHTML = msg;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Load saved connection on startup
|
// Load saved connection on startup and surface any pending error from a
|
||||||
|
// previous session (e.g. the server dropped mid-session and we bounced back).
|
||||||
(async () => {
|
(async () => {
|
||||||
try {
|
try {
|
||||||
const saved = await window.overlord.getSavedConnection();
|
const saved = await window.overlord.getSavedConnection();
|
||||||
@@ -22,6 +23,13 @@ function setStatus(msg, type = "info") {
|
|||||||
} catch {
|
} catch {
|
||||||
// first run, no saved data
|
// first run, no saved data
|
||||||
}
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const err = await window.overlord.getPendingError();
|
||||||
|
if (err) setStatus(err, "error");
|
||||||
|
} catch {
|
||||||
|
// ignore
|
||||||
|
}
|
||||||
})();
|
})();
|
||||||
|
|
||||||
form.addEventListener("submit", async (e) => {
|
form.addEventListener("submit", async (e) => {
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
const { app, BrowserWindow, ipcMain } = require("electron");
|
const { app, BrowserWindow, ipcMain } = require("electron");
|
||||||
const path = require("path");
|
const path = require("path");
|
||||||
const fs = require("fs");
|
const fs = require("fs");
|
||||||
|
const https = require("https");
|
||||||
|
const http = require("http");
|
||||||
|
|
||||||
// ── Persistence ──────────────────────────────────────────────
|
// ── Persistence ──────────────────────────────────────────────
|
||||||
app.setAppUserModelId("com.overlord.desktop");
|
app.setAppUserModelId("com.overlord.desktop");
|
||||||
@@ -34,6 +36,24 @@ function saveConnection(conn) {
|
|||||||
// ── Window ───────────────────────────────────────────────────
|
// ── Window ───────────────────────────────────────────────────
|
||||||
let win;
|
let win;
|
||||||
let serverBaseUrl = null; // e.g. "https://1.2.3.4:5173"
|
let serverBaseUrl = null; // e.g. "https://1.2.3.4:5173"
|
||||||
|
let pendingError = null; // error message to show on the connect page after a failed load
|
||||||
|
|
||||||
|
// ── Server probe ─────────────────────────────────────────────
|
||||||
|
// Checks whether a server is reachable before telling Electron to navigate to it.
|
||||||
|
function probeServer(url) {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
const mod = url.startsWith("https") ? https : http;
|
||||||
|
const req = mod.get(url, { rejectUnauthorized: false, timeout: 8000 }, (res) => {
|
||||||
|
res.resume(); // drain so the socket can be reused
|
||||||
|
resolve();
|
||||||
|
});
|
||||||
|
req.on("timeout", () => {
|
||||||
|
req.destroy();
|
||||||
|
reject(new Error("timeout"));
|
||||||
|
});
|
||||||
|
req.on("error", reject);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
function createWindow() {
|
function createWindow() {
|
||||||
win = new BrowserWindow({
|
win = new BrowserWindow({
|
||||||
@@ -52,6 +72,21 @@ function createWindow() {
|
|||||||
|
|
||||||
// Allow self-signed certs on the target Overlord server
|
// Allow self-signed certs on the target Overlord server
|
||||||
win.webContents.session.setCertificateVerifyProc((_req, cb) => cb(0));
|
win.webContents.session.setCertificateVerifyProc((_req, cb) => cb(0));
|
||||||
|
|
||||||
|
// If the server URL fails to load mid-session (e.g. server stopped), bounce back
|
||||||
|
// to the connect screen with a helpful error instead of showing a white page.
|
||||||
|
win.webContents.on("did-fail-load", (_event, errorCode, _errorDescription, validatedURL) => {
|
||||||
|
// ERR_ABORTED (-3) fires on normal navigation cancellations – ignore it.
|
||||||
|
if (errorCode === -3) return;
|
||||||
|
if (serverBaseUrl && validatedURL && validatedURL.startsWith(serverBaseUrl)) {
|
||||||
|
pendingError =
|
||||||
|
"Lost connection to the Overlord server. " +
|
||||||
|
"Make sure the server is still running, then try connecting again. " +
|
||||||
|
"See the README if you need help starting the server.";
|
||||||
|
serverBaseUrl = null;
|
||||||
|
win.loadFile(path.join(__dirname, "connect", "index.html"));
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
app.whenReady().then(createWindow);
|
app.whenReady().then(createWindow);
|
||||||
@@ -69,7 +104,13 @@ ipcMain.handle("get-saved-connection", () => {
|
|||||||
return loadSavedConnection();
|
return loadSavedConnection();
|
||||||
});
|
});
|
||||||
|
|
||||||
ipcMain.handle("connect-to-server", (_event, { host, port, useTLS }) => {
|
ipcMain.handle("get-pending-error", () => {
|
||||||
|
const err = pendingError;
|
||||||
|
pendingError = null;
|
||||||
|
return err;
|
||||||
|
});
|
||||||
|
|
||||||
|
ipcMain.handle("connect-to-server", async (_event, { host, port, useTLS }) => {
|
||||||
if (!host || host.trim().length === 0) {
|
if (!host || host.trim().length === 0) {
|
||||||
return { success: false, error: "Host is required" };
|
return { success: false, error: "Host is required" };
|
||||||
}
|
}
|
||||||
@@ -80,6 +121,19 @@ ipcMain.handle("connect-to-server", (_event, { host, port, useTLS }) => {
|
|||||||
const protocol = useTLS ? "https" : "http";
|
const protocol = useTLS ? "https" : "http";
|
||||||
const url = `${protocol}://${host.trim()}:${port}`;
|
const url = `${protocol}://${host.trim()}:${port}`;
|
||||||
|
|
||||||
|
// Probe the server before navigating so we never end up on a white screen.
|
||||||
|
try {
|
||||||
|
await probeServer(url);
|
||||||
|
} catch {
|
||||||
|
return {
|
||||||
|
success: false,
|
||||||
|
error:
|
||||||
|
"Cannot reach the Overlord server at that address. " +
|
||||||
|
"Make sure the server is running before connecting — " +
|
||||||
|
"see the README for setup instructions.",
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
saveConnection({ host: host.trim(), port, useTLS });
|
saveConnection({ host: host.trim(), port, useTLS });
|
||||||
serverBaseUrl = url;
|
serverBaseUrl = url;
|
||||||
win.loadURL(url);
|
win.loadURL(url);
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ const { contextBridge, ipcRenderer } = require("electron");
|
|||||||
|
|
||||||
contextBridge.exposeInMainWorld("overlord", {
|
contextBridge.exposeInMainWorld("overlord", {
|
||||||
getSavedConnection: () => ipcRenderer.invoke("get-saved-connection"),
|
getSavedConnection: () => ipcRenderer.invoke("get-saved-connection"),
|
||||||
|
getPendingError: () => ipcRenderer.invoke("get-pending-error"),
|
||||||
connectToServer: (opts) => ipcRenderer.invoke("connect-to-server", opts),
|
connectToServer: (opts) => ipcRenderer.invoke("connect-to-server", opts),
|
||||||
goBackToConnect: () => ipcRenderer.invoke("go-back-to-connect"),
|
goBackToConnect: () => ipcRenderer.invoke("go-back-to-connect"),
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user