Federation: read-only browsing of a peer instance's library (3.5)

Configure peers as [[remote]] entries (name, url, optional password) and
browse their libraries from this instance, read-only.

- remote.rs: RemoteClient (blocking reqwest + rustls + cookie jar). Fetches
  the peer's /api/library, logging in first if the peer has a password and
  retrying on a 401. Media is not proxied: the library JSON's media URLs
  (/files/, /music-files/, /api/transcode/, /api/sub-vtt/) are rewritten to
  absolute peer URLs with the peer's read-only feed token appended, so video
  streams straight from the peer to the browser/mpv while only the small JSON
  passes through us.
- web.rs: auth_middleware now also accepts the feed token for GET
  /api/transcode/ and /api/sub-vtt/ (read-only media, same class as /files/),
  so a transcoded peer streams remotely. New GET /api/remotes and
  /api/remotes/:id/library (the RemoteClient runs under spawn_blocking).
- web UI: a 🌐 Remotes sidebar switcher; remote mode is read-only (hides the
  download bar + per-card mutating actions, keeps Play).
- desktop: a 🌐 Remotes screen that fetches a peer's library off-thread and
  plays via mpv on the tokenized URL.
- config.rs: [[remote]] section list; reqwest dep added (rustls/blocking/
  cookies, no system OpenSSL).

Verified end-to-end against a second local instance, including a transcoded
stream returning HTTP 200 via the token. ROADMAP 3.5 + CLAUDE.md updated.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Luna 2026-06-10 17:51:44 -07:00
parent d797f2a698
commit 033572d3bd
10 changed files with 899 additions and 13 deletions

View file

@ -161,7 +161,10 @@ both the transcript indexer and the transcript viewers.
- `app.rs` and `web.rs` are large (~34k lines) because each owns a full UI; new
desktop code goes in `app.rs`, web handlers in `web.rs`, shared logic in the
focused modules (`downloader`, `database`, `library`, `platform`, `fingerprint`,
`vtt`, …).
`vtt`, `autotag`, `remote`, …). `autotag` suggests folder groups for unfiled
channels; `remote` is federation — a `RemoteClient` that browses a peer
instance's library read-only (media via the peer's feed token, see
`auth_middleware`).
- Tray (`ksni`) and the `rfd` xdg-portal dialog backend are Linux-only/no-GTK
by design (it's why packaging avoids a GTK dep). They're now **target-gated**
in `Cargo.toml` (`cfg(target_os = "linux")`); off Linux `rfd` uses its native