Skip to content

feat(webui): serve the full React client from the engine over HTTP#171

Open
Twice6804 wants to merge 2 commits into
phantomptr:mainfrom
Twice6804:feat/web-ui
Open

feat(webui): serve the full React client from the engine over HTTP#171
Twice6804 wants to merge 2 commits into
phantomptr:mainfrom
Twice6804:feat/web-ui

Conversation

@Twice6804

Copy link
Copy Markdown
Contributor

Description

Phase 1 of browser-accessible ps5upload (#151): the engine can now serve
the complete React frontend directly over HTTP, so a NAS/Docker user can
manage their PS5 from any browser without the native Tauri client.

This phase requires zero new engine routes — it reuses the existing
HTTP proxy endpoints the Tauri commands already call.

Type of Change

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • Documentation update
  • Performance improvement
  • Code refactoring

Changes Made

  • client/src/state/engine.ts: in a browser (non-Tauri) context, the engine URL resolves to window.location.origin so every fetch call is same-origin.
  • client/src/lib/browserInvoke.ts (new): translates invoke(cmd, args) calls into fetch() requests against the engine's existing HTTP routes; unsupported (native-only) commands throw a typed BrowserUnsupportedError.
  • client/src/lib/invokeLogged.ts: branches on isTauriEnv() to route through browserInvoke instead of Tauri IPC when running in a plain browser.
  • Redirected ~14 modules that imported invoke directly from @tauri-apps/api/core to go through invokeLogged instead, so they pick up the browser shim.
  • engine/crates/ps5upload-engine: new webui Cargo feature (opt-in, default off) that embeds the built Vite dist/ via rust-embed and serves it with an SPA deep-link fallback (Router::fallback). Default (non-webui) builds are unchanged.
  • engine/Dockerfile.webui (new): multi-stage build — Node stage builds the React client, Rust stage compiles the engine with --features webui and embeds the dist/ output, final FROM scratch stage matches the existing minimal image.

Documentation Updates

Did you update the documentation? [ ] Yes [x] No

If no documentation updates: this is Phase 1 of a multi-phase rollout; the self-hosted README section documenting Dockerfile.webui and the PS5UPLOAD_ALLOW_IP requirement is planned for a follow-up PR once Phase 2 (remaining PS5-side screens) lands, so the docs describe the complete browser experience in one place rather than in installments.

Testing

  • npm run validate equivalent: ran typecheck, lint, and the full Vitest suite (72 files / 754 tests) individually — all green.
  • npm run coverage
  • Built PS5 payload successfully
  • Cross-platform CI target checks passed
  • Tested on real PS5 hardware
  • Tested desktop app
  • Verified all example commands in docs work — built and ran engine/Dockerfile.webui via Docker (local rustc is too old for direct cargo build), confirmed GET / serves the SPA, a client-side deep link (/library) correctly falls back to index.html, hashed assets serve with correct MIME types, and /api/version is unaffected.
  • Tested edge cases and error handling — confirmed the webui feature is fully opt-in (default build unaffected) and that the SPA fallback doesn't shadow existing /api/* routes.

Checklist

  • My code follows the project's style guidelines
  • I have performed a self-review of my own code
  • I have commented my code, particularly in hard-to-understand areas
  • I have updated the documentation to reflect my changes
  • My changes generate no new warnings
  • I have tested my changes on PS5 hardware (or simulated environment)
  • All example code in documentation has been tested and works

Additional Notes

This is Phase 1 of a larger plan (frontend transport shim + static serving only). Phase 2 will add thin engine routes for the remaining PS5-side screens (Saves, Screenshots, Processes, Power, user list, SMP) that currently call ps5upload-core in-process from the Tauri shell, plus capability gating to hide native-only affordances (host file pickers, local FS browse, payload send from a local file) when running in a browser. Access control for the browser UI reuses the existing PS5UPLOAD_ALLOW_IP allowlist — no new auth was introduced.

🤖 Generated with Claude Code

Twice6804 and others added 2 commits July 2, 2026 19:02
Mirrors the "Save to USB" feature (83ea617) with a "Restore from USB"
action (per-row + bulk) on the Saves screen. Reads the latest timestamped
zip from <savePath>/<title_id>/<timestamp>/<title_id>.zip on a USB /
extended-storage drive plugged into the PS5, validates and unzips it in
a host temp dir, then wipes and re-uploads the live save — no PC round-
trip needed.

Resolves "latest" by listing the title_id directory and picking the
lexically-greatest timestamp folder (the YYYY-MM-DD_HHMMSS format from
backupTimestamp() is documented as lexically sortable).

Per-row "Restore from USB" confirms with the resolved timestamp before
wiping. Bulk "Restore all from USB" confirms once up front; games with
no backup on the USB drive are skipped and reported in the summary
separately from failures.

Reuses all existing backend commands (transfer_download, save_archive_
unzip, save_archive_restore_prepare, fs_list_dir, fs_delete,
transfer_dir); no payload/engine changes required. Carries the same
stale-host guard as handleRestore to prevent wipes against the wrong
console if the user switches PS5 during the operation.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Phase 1 of browser-accessible ps5upload: adds a `webui` engine feature
that embeds the built React app (rust-embed) with SPA deep-link
fallback, and a browser-side invoke shim (`browserInvoke.ts`) that
translates Tauri IPC calls into `fetch()` against the same-origin
engine when not running inside the Tauri webview. No new engine
routes — Phase 1 reuses existing proxy endpoints.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@Twice6804 Twice6804 requested a review from phantomptr as a code owner July 3, 2026 18:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant