4a5d4b0a711c42d02227416d2dbff6a67c7697e9
5
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
4a5d4b0a71 |
feat(web): the console follows the host's events instead of asking ten times a minute
The host has published every lifecycle transition on GET /api/v1/events since the API existed — client connect/disconnect, session and stream start/end, pairing decisions, display create/release, library, store and plugin changes — and nothing consumed a byte of it. The console instead polled ten endpoints on 1-5 s timers, so a change was up to 5 s stale and two pages could disagree while you looked at them. The Library page polled not at all: install a game in Steam and it never appeared until a full reload. The console now subscribes once and invalidates exactly the queries an event affects. Events never carry data into the cache — they only say "this is stale" — so an unknown future kind costs nothing and a missed event degrades to the polling that is still there underneath, now at a slow safety-net interval. The fast ticks that remain are the ones events cannot express: the live stream numbers while streaming, and a lingering display's teardown countdown. Four things had to be true for this to work, and none of them were. Each was found by measuring, not by reading: - Nitro's `localFetch` accumulates the response and only builds it when the handler returns, so nothing streams through the deployed Bun server. Three frames sent a second apart arrived together, three seconds late, when the upstream closed — and an SSE stream never closes, so nothing would ever have arrived. /api/v1/events gets its own route that hands back a web Response wrapping the upstream stream, which passes straight through. - Hydration mounts the app shell and discards it ~15 ms later. A subscription owned by that effect opened, closed, and never came back. It is a refcounted module singleton now, with a grace period so a remount re-attaches instead of reconnecting. - `getRouter()` runs more than once in the browser, and each call built its own QueryClient. The subscription held the first, the live pages read the second, and every invalidation went to a cache nobody was reading. One client per browser session; the server still gets a fresh one per request, which it must. - `invalidateQueries` only refetches queries that currently have an observer. An event means the HOST changed, so every cached copy is wrong whether or not something is watching it. Two features fall out of the same work: - **Automation** — a page for GET/PUT /api/v1/hooks. The host has run these hooks all along and the console never showed them, so the only way to see what your machine does when a stream starts was to open the config file. Writing one means writing a shell command the host will execute, so saving re-asks for the console password, like an update or an unreviewed install. - The Host page warns when another Moonlight-compatible server (Sunshine, Apollo) is running on the same machine. The host has detected this at startup for ages and reported it in /local/summary; nothing surfaced it. It is the most common reason a host looks installed and working but no client can reach it. Verified in a real browser against a mock host: three events drive three refetches of a query with no polling timer, the conflicts card names the intruder, the hook list and its dialog render, and the console reports no errors. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> |
||
|
|
bf9d101be8 |
fix(web): the approve button stops hiding off-canvas on portrait phones
The pending-devices table's four p-card cells overflow a 360-430 px viewport, and the actions cell - Approve - ended up past the right edge of an overflow-auto wrapper inside the page's overflow-x-hidden column: the button existed but could not be seen or reached (landscape is wide enough, which is why it "worked" there). The name cell now flexes and truncates, and the fingerprint/age columns collapse into a sub-line under the name on narrow screens instead of widening the row. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> |
||
|
|
7c0313a7cb |
fix(web): flush card content, so a full-bleed table stops doubling its inset
ci / web (push) Successful in 55s
ci / docs-site (push) Successful in 58s
apple / swift (push) Successful in 1m18s
ci / bench (push) Successful in 6m42s
apple / screenshots (push) Successful in 6m21s
ci / rust (push) Successful in 24m18s
android-screenshots / screenshots (push) Successful in 3m2s
decky / build-publish (push) Successful in 21s
docker / build-push (--build-arg FEDORA_VERSION=44, ci, ci/fedora-rpm.Dockerfile, punktfunk-fedora44-rpm) (push) Successful in 12s
android / android (push) Successful in 15m7s
docker / build-push (ci, ci/fedora-rpm.Dockerfile, punktfunk-fedora-rpm) (push) Successful in 10s
docker / build-push (ci, ci/rust-ci-noble.Dockerfile, punktfunk-rust-ci-noble) (push) Successful in 10s
docker / build-push (., web/Dockerfile, punktfunk-web) (push) Successful in 37s
docker / build-push (ci, ci/rust-ci.Dockerfile, punktfunk-rust-ci) (push) Successful in 12s
docker / build-push (docs-site, docs-site/Dockerfile, punktfunk-docs) (push) Successful in 9s
windows-host / package (push) Successful in 10m7s
release / apple (push) Successful in 10m12s
flatpak / build-publish (push) Successful in 6m55s
deb / build-publish (push) Successful in 11m44s
linux-client-screenshots / screenshots (push) Successful in 7m40s
docker / deploy-docs (push) Successful in 28s
windows-msix / package (arm64, C:\Users\Public\ffmpeg-arm64, --no-default-features, aarch64-pc-windows-msvc, C:\t-a64) (push) Successful in 3m22s
web-screenshots / screenshots (push) Successful in 3m27s
deb / build-publish-host (push) Successful in 12m25s
arch / build-publish (push) Successful in 15m42s
windows-msix / package (x64, C:\Users\Public\ffmpeg, , x86_64-pc-windows-msvc, C:\t) (push) Successful in 3m32s
rpm / build-publish (43, bazzite, punktfunk-fedora-rpm) (push) Successful in 15m48s
rpm / build-publish (44, fedora-44, punktfunk-fedora44-rpm) (push) Successful in 14m41s
`<CardContent className="p-0">` never removed the padding it looked like it removed: tailwind-merge resolves conflicts within a variant, so `p-0` cancels `p-4` but leaves `sm:p-6` standing. Every call site that used it nests a CardHeader inside, which brings its own `sm:p-6` — so at >=640px the title sat 24px further in than its neighbours'. Visible on the Plugins page as 'Installed plugins' not lining up with 'Plugin runner'. Give CardContent a `flush` prop that omits the padding outright, and use it at the three call sites (Store, Pairing, Stats) rather than fixing the symptom three times and leaving the footgun in place. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> |
||
|
|
75b3c94f60 |
fix(web): console sweep — pairing, displays, stats, logs, auth, i18n
ci / rust (push) Failing after 45s
ci / web (push) Successful in 52s
docker / build-push (--build-arg FEDORA_VERSION=44, ci, ci/fedora-rpm.Dockerfile, punktfunk-fedora44-rpm) (push) Successful in 10s
ci / docs-site (push) Successful in 1m6s
decky / build-publish (push) Successful in 33s
docker / build-push (., web/Dockerfile, punktfunk-web) (push) Successful in 30s
docker / build-push (docs-site, docs-site/Dockerfile, punktfunk-docs) (push) Successful in 10s
ci / bench (push) Successful in 6m1s
docker / build-push (ci, ci/rust-ci.Dockerfile, punktfunk-rust-ci) (push) Successful in 8m33s
docker / build-push (ci, ci/fedora-rpm.Dockerfile, punktfunk-fedora-rpm) (push) Successful in 9m40s
docker / deploy-docs (push) Successful in 26s
windows-host / package (push) Successful in 15m34s
rpm / build-publish (44, fedora-44, punktfunk-fedora44-rpm) (push) Successful in 13m24s
arch / build-publish (push) Successful in 20m32s
android / android (push) Successful in 20m50s
deb / build-publish (push) Successful in 20m33s
rpm / build-publish (43, bazzite, punktfunk-fedora-rpm) (push) Successful in 21m41s
apple / swift (push) Has been cancelled
apple / screenshots (push) Has been cancelled
Pairing: - Refresh the paired-devices list after a native PIN pairing (the happy path never invalidated it, so a newly paired device stayed hidden until remount). - Moonlight PIN: a 204 means "PIN delivered to the waiting handshake", NOT paired, so it now reads "PIN sent" instead of a false "Paired successfully". - Hide the Moonlight pairing card on native-only hosts (HostInfo.gamestream) — it could never receive a PIN there. - Per-row pending on unpair/approve/deny; PIN input maxLength 16 (was 8). Displays / Library: - "Arrange displays" save refreshes the settings card (it rewrites the policy), without clobbering unsaved Custom edits (re-seed only when the draft still matches the server). - Live-display list wrapped in QueryState so errors don't read as "no displays". - "Forever" keep-alive option in the custom editor; edit-game form round-trips the logo artwork (was dropped on save); per-card delete pending. Stats: - Distinct colour for the native "queue" latency stage (it collided with "capture"). - "Not measured on this path" note on the GameStream health chart; configured-bitrate target line on throughput; host-authoritative elapsed timer; LiveCard surfaces non-404 errors. Shell / auth / i18n: - SSR-stable locale: first client render matches the base-locale SSR (no hydration mismatch), then adopts the persisted/browser locale post-hydration. - BFF proxy maps an upstream (mgmt-token) 401 to 502 so a logged-in user isn't bounced into a post-login redirect loop. - Logout checks the POST result before navigating; logs dedup by seq (StrictMode); login "next" keeps query/hash; Dashboard shows the active-session count. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> |
||
|
|
ae51276a03 |
feat(web): consolidate paired devices, self-contained sections, docs + lint
Web console - Pairing/Library/Stats refactored into self-contained subsections that each own their own queries + mutations; a shared slot-based layout (view.tsx) is filled by the live page (containers) and Storybook (pure cards + fixtures) so the layout can't drift. - All paired devices in one list on Pairing with a protocol column (punktfunk/1 + Moonlight), routing each unpair to the right endpoint; the redundant Clients page is removed. - Library: overview grid split from the add/edit form into separate files. - Login screen links out to the docs. Docs - "Console login password" section on every host page (apt/RPM/Bazzite/SteamOS/Windows) plus a new "Forgot your Password?" troubleshooting page, linked from the login screen. - Console served as HTTP/1.1 over TLS (drop the unusable HTTP/3 advertising) across the Bun entry, launchers, systemd units, and packaging. Tooling - Biome now respects .gitignore (stops linting generated code), config migrated to 2.5.1; all lint issues fixed cleanly. Also includes this branch's in-progress host, Apple client, packaging, and CI changes. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> |