An Electron client for the desktop store
The desktop store put the catalog on ordinary computers, and then asked people to open a terminal — which on Windows is not even a workable ask, because the installer is `curl … | sh`. This is the window: a grid of cards, one click to install a title into the application menu, one to play it, one to remove it. The CLI stays the product. Every action runs `desktop_store.py --json`, so there is one catalog logic, one state file and one delete guard; the window never touches the filesystem itself. That is also why the engine grew `--json` first rather than this app growing a parser for prose. It doubles as the Windows install path: with no store on the machine, the app downloads the engine, the shared core and a config into the same folder the shell installer would use — Node's https, no curl. An engine older than 1.1.0 cannot be driven from a window, so the client checks the version and offers to refresh it instead of failing on the first call. Deliberate choices worth knowing: - No renderer framework and no build step. Plain HTML, CSS and JS, one runtime dependency. The whole UI is readable in one sitting. - `contextIsolation` on, `nodeIntegration` off, `sandbox` on, a CSP that permits only the app's own script and stylesheet plus images over HTTPS. The renderer can do exactly what preload.js exposes and nothing else. - English and Hungarian, following the system language. The CLIs and the docs stay English; this is the one end-user surface where that is not enough. - `ENGINES` is a list with one entry. The RetroArch store has the same command shape, so adding it is an entry, not a rewrite. Two ways to test it without a working installation in the way: `npm run smoke` drives the bridge with no window at all, and `npm run uitest` loads the window once and reports what rendered — the only way a renderer error would otherwise be noticed, since the main process log stays empty. Both accept a sandbox store through STORE_ROOT / SMOKE_HOME. Verified on macOS arm64, including the packaged .app: the store is found, ten titles list, a sync installs three, and the window renders them as installed with their Play and Remove buttons. Linux and Windows are unproven, as they are for the CLI itself. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,49 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<!-- Nothing is loaded from the network except box art, and no inline code
|
||||
runs: the app ships its own script and stylesheet. -->
|
||||
<meta http-equiv="Content-Security-Policy"
|
||||
content="default-src 'none'; script-src 'self'; style-src 'self'; img-src 'self' https: data:; font-src 'self'; connect-src 'none'">
|
||||
<title>WarpEngine Store</title>
|
||||
<link rel="stylesheet" href="style.css">
|
||||
</head>
|
||||
<body>
|
||||
<header class="bar">
|
||||
<div class="bar-title">
|
||||
<span class="logo" aria-hidden="true">▚</span>
|
||||
<span id="app-name">WarpEngine Store</span>
|
||||
<span class="store-id" id="store-id"></span>
|
||||
</div>
|
||||
<div class="bar-actions">
|
||||
<span class="progress" id="progress" hidden></span>
|
||||
<button id="sync-all" class="btn btn-primary" disabled></button>
|
||||
<button id="refresh" class="btn" disabled></button>
|
||||
<select id="locale" class="select" aria-label="Language"></select>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<!-- Shown instead of the grid when there is nothing to drive yet. -->
|
||||
<section id="gate" class="gate" hidden>
|
||||
<h1 id="gate-title"></h1>
|
||||
<p id="gate-body"></p>
|
||||
<div class="gate-actions">
|
||||
<button id="gate-action" class="btn btn-primary" hidden></button>
|
||||
<a id="gate-link" class="link" href="#" hidden></a>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<main id="grid" class="grid" hidden></main>
|
||||
|
||||
<section id="empty" class="empty" hidden></section>
|
||||
|
||||
<footer class="log">
|
||||
<button id="log-toggle" class="log-toggle" aria-expanded="false"></button>
|
||||
<div class="log-lines" id="log-lines" hidden></div>
|
||||
<div class="log-paths" id="log-paths"></div>
|
||||
</footer>
|
||||
|
||||
<script src="app.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user