feat(webui): serve the full React client from the engine over HTTP#171
Open
Twice6804 wants to merge 2 commits into
Open
feat(webui): serve the full React client from the engine over HTTP#171Twice6804 wants to merge 2 commits into
Twice6804 wants to merge 2 commits into
Conversation
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>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
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
Changes Made
client/src/state/engine.ts: in a browser (non-Tauri) context, the engine URL resolves towindow.location.originso every fetch call is same-origin.client/src/lib/browserInvoke.ts(new): translatesinvoke(cmd, args)calls intofetch()requests against the engine's existing HTTP routes; unsupported (native-only) commands throw a typedBrowserUnsupportedError.client/src/lib/invokeLogged.ts: branches onisTauriEnv()to route throughbrowserInvokeinstead of Tauri IPC when running in a plain browser.invokedirectly from@tauri-apps/api/coreto go throughinvokeLoggedinstead, so they pick up the browser shim.engine/crates/ps5upload-engine: newwebuiCargo feature (opt-in, default off) that embeds the built Vitedist/viarust-embedand 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 webuiand embeds thedist/output, finalFROM scratchstage 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.webuiand thePS5UPLOAD_ALLOW_IPrequirement 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 validateequivalent: rantypecheck,lint, and the full Vitest suite (72 files / 754 tests) individually — all green.npm run coverageengine/Dockerfile.webuivia Docker (local rustc is too old for directcargo build), confirmedGET /serves the SPA, a client-side deep link (/library) correctly falls back toindex.html, hashed assets serve with correct MIME types, and/api/versionis unaffected.webuifeature is fully opt-in (default build unaffected) and that the SPA fallback doesn't shadow existing/api/*routes.Checklist
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-corein-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 existingPS5UPLOAD_ALLOW_IPallowlist — no new auth was introduced.🤖 Generated with Claude Code