The updater now resolves the newest non-draft desktop-v* release through the Gitea API at check time (J621_UPDATE_REPO, lowercase because the API path is case-sensitive), picks the platform's latest*.yml asset and uses that release as a generic electron-updater feed; J621_UPDATE_URL still overrides everything. Verified against the live API: release picked, yml fetched, artifact HEAD 200. electron-builder's publish.url is now metadata only (still needed so the build emits latest*.yml). Docs updated: CD release assets are the feed, the website /desktop/ feed only matters for installs before 0.1.2.
120 lines
4.8 KiB
Markdown
120 lines
4.8 KiB
Markdown
# J621 desktop (Electron)
|
|
|
|
An Electron shell around the web build. The main process serves the SPA from
|
|
the privileged `app://j621` scheme — a real origin, so `localStorage`, OPFS,
|
|
Web Workers and WebCodecs all behave exactly like they do in Chrome — and the
|
|
SPA keeps its normal first-run flow: on launch it asks where the backend is
|
|
(or runs in local mode with no backend at all).
|
|
|
|
The renderer code is not forked: the shell loads `frontend/dist` as built by
|
|
`npm run build` in `frontend/`.
|
|
|
|
Licensed under the Jake Labs Non-Commercial Software Licence — see
|
|
`../LICENSE`.
|
|
|
|
## Layout
|
|
|
|
```
|
|
src/main.ts window, app:// protocol handler, menu, external links
|
|
src/preload.ts window.j621Desktop bridge
|
|
electron-builder.yml deb + pacman + nsis packaging
|
|
```
|
|
|
|
The main process attaches a `Referer` to requests for e621 hosts: Chromium
|
|
sends no referrer from a custom-scheme page, and e621's CDN answers
|
|
cross-site image loads without one with a 403 (which Chromium then blocks as
|
|
ORB). API calls work either way.
|
|
|
|
## Development
|
|
|
|
```bash
|
|
# terminal 1: the SPA with its /api proxy (needs the backend for library pages)
|
|
cd frontend && npm run dev
|
|
|
|
# terminal 2
|
|
cd desktop && npm run dev
|
|
```
|
|
|
|
`npm run dev` builds the main process and points the window at
|
|
`http://localhost:5173` (`J621_DEV_SERVER`). Without the dev server,
|
|
`npm start` builds both halves and serves the bundled SPA over `app://j621`.
|
|
|
|
## Builds
|
|
|
|
```bash
|
|
npm run dist:linux # release/j621-desktop_0.1.0_amd64.deb + j621-desktop-0.1.0.pkg.tar.zst
|
|
npm run dist:win # release/J621 Setup 0.1.0.exe (cross-built with wine; untested)
|
|
npm run dist:all
|
|
```
|
|
|
|
`deploy/build_desktop.sh` wraps the same commands, installs dependencies on
|
|
first run and prints sizes plus SHA-256 sums for release notes. Nothing is
|
|
published by it; the CD workflow attaches the artifacts to the Gitea release,
|
|
which is also the update feed.
|
|
|
|
The Arch package can be installed and removed with pacman:
|
|
|
|
```bash
|
|
sudo pacman -U release/j621-desktop-*.pkg.tar.zst
|
|
sudo pacman -R j621-desktop
|
|
```
|
|
|
|
It installs to `/opt/J621` with a `/usr/bin/j621-desktop` symlink and a
|
|
`io.j621.desktop` launcher entry (`StartupWMClass` matches the shell's
|
|
`desktopName`). The Windows installer is a per-user NSIS build, so no admin
|
|
rights are needed to install or update it — but it is unsigned, so SmartScreen
|
|
will warn, and it has not been smoke-tested on real Windows.
|
|
|
|
## Updates
|
|
|
|
The app checks only when asked (**J621 → Check for updates…** in the menu):
|
|
Linux packages install through pacman/dpkg, which needs administrator rights,
|
|
and the Windows build is unsigned, so nothing installs silently.
|
|
|
|
The check resolves the feed itself: it asks the Gitea API for the newest
|
|
non-draft `desktop-v*` release (`J621_UPDATE_REPO`, default
|
|
`https://gitea.rainbow-herring.ts.net/jakebreath/j621` — lowercase on purpose,
|
|
the API path is case-sensitive), picks the `latest-linux.yml` / `latest.yml`
|
|
asset for the platform and uses that release as an electron-updater generic
|
|
feed. The baked `publish.url` in `electron-builder.yml` is metadata only.
|
|
`J621_UPDATE_URL` overrides the whole lookup (the smoke test uses this).
|
|
|
|
Publishing a release:
|
|
|
|
1. Bump `version` in `desktop/package.json` — that is what the updater compares.
|
|
2. Run the manual CD workflow, which builds the packages and attaches them
|
|
plus both channel files to the Gitea release `desktop-v<version>`.
|
|
`./deploy/push_desktop.sh --win` does the same build locally (and can also
|
|
copy the files to the website feed, which is optional now).
|
|
3. Existing installs find the new version on their next manual check.
|
|
|
|
Note for the 0.1.1 → 0.1.2 step: 0.1.1 only knows the old `/desktop/` feed, so
|
|
publish 0.1.2 there once (`./deploy/push_desktop.sh --no-build`, or install it
|
|
manually). From 0.1.2 on, updates come from Gitea.
|
|
|
|
`package-type` in the app resources tells electron-updater whether to run
|
|
`pacman -U` or `dpkg -i` (both via pkexec/sudo); the per-user NSIS install
|
|
updates without elevation.
|
|
|
|
## Smoke test
|
|
|
|
`npm run smoke` builds everything, runs Electron headless through `xvfb-run`
|
|
and checks that the bundled SPA loads over `app://j621`: the SPA fallback, an
|
|
asset fetch, `localStorage`, OPFS, WebCodecs and the preload bridge. It exits
|
|
non-zero on failure. With `J621_UPDATE_URL` set it also checks that the feed
|
|
reports the expected version. Pointing `J621_DEV_SERVER` at the Vite dev
|
|
server checks the development path instead of the bundled one.
|
|
|
|
## Backend CORS
|
|
|
|
A desktop app is cross-origin to the backend, exactly like the frontend-only
|
|
Docker deployment. Add the shell's origin to the backend:
|
|
|
|
```
|
|
CORS_ALLOWED_ORIGINS=app://j621
|
|
```
|
|
|
|
The setup screen shows this hint (with the actual origin) when the connection
|
|
test fails. Without a backend, choose "Continue without a backend" — the
|
|
e621-facing pages work the same as in the browser.
|