crabidy/cbd-web/README.md

99 lines
4.1 KiB
Markdown

# cbd-web — the browser client
A [Leptos](https://leptos.dev) client-side WASM app with the same
functionality as `cbd-tui`, served by `crabidy-server` itself.
## How it works
- **Transport**: gRPC-web (`tonic-web-wasm-client`) over the *same*
generated client and proto types the TUI uses (`crabidy-core`). No
second API surface — feature parity is structural. The server wraps
its existing gRPC service in `tonic-web`, so the browser and the TUI
hit identical `/crabidy.v1.CrabidyService/…` paths, and the same role
auth layer gates both.
- **Serving**: the built bundle (`cbd-web/dist`) is embedded into
`crabidy-server` at compile time behind the default-on `web-ui`
feature and served as the fallback route on port 50051. gRPC and
static assets share one origin, so there is no CORS story.
- **Local-first**: pure client-side rendering, every asset in the
bundle (no CDN, no external fonts), library listings cached in memory
like the TUI, credentials and theme in `localStorage`, and the update
stream reconnects with backoff when the server disappears. There is
no CRDT layer — this is a remote control for one live server state,
not an offline-editing app (a deliberate departure from the
`web_client_example_workspace` template that informed the toolchain).
## Functionality
Everything the TUI does: browse the library (`j`/`k`/`h`/`l`, click), marks
and visual mode (`s`, `v`/`V`) in both panes, the one-slot register (`y`
yanks, `d`/`c`/`C` fill it as they remove, `p`/`P` paste), create/rename/
delete nodes (`%`/`e`/`d`), bookmark and capture (`w`/`W`, with live progress
lines and skipped-track marking), the full queue and playback controls,
seeking (`,`/`.` for 15 seconds, `<`/`>` for a whole track, or a click on the
progress bar), volume, shuffle/repeat, and a `?` help overlay listing the
keys. Keys mirror the TUI; every key also has a clickable control. The `/`
live filter is the one thing that is TUI-only so far.
Two layout details earn their own note:
- `library`/`queue` **tabs** in the top bar switch panes and show which one
the keys go to — what `Tab` does, reachable by thumb.
- Below 700px the panes cannot sit side by side, so **only the focused pane
is rendered**. It is not collapsed to a strip: a strip's truncated rows
still take taps, which sent them to the wrong pane.
A light/dark theme follows the OS and can be toggled (persisted). The accent
color is the crab orange-red.
When the server requires credentials, a login form collects the role
(`owner` / `queue-owner` / `queue-appender`) and password; they are
stored in `localStorage` and sent as the gRPC-web `authorization`
header on every request.
## Building
The WASM toolchain (trunk, wasm-bindgen, the `wasm32-unknown-unknown`
target) is provided by devenv. From the repo root:
```sh
devenv shell -- build-web # release bundle → cbd-web/dist
cargo build -p crabidy-server # embeds cbd-web/dist
```
`build-web` clears `RUSTFLAGS` first: the native toolchain sets the
mold linker, which `rust-lld` (the wasm linker) cannot parse.
Building `crabidy-server` without a `cbd-web/dist` present is fine — it
embeds a placeholder page telling you to run `build-web`. To drop the web
client (and the `tonic-web` layer) entirely, build the server without its
`web-ui` cargo feature — e.g. `--no-default-features --features
all-providers,opus,spectrum`; see `docs/src/build-features.md`.
## Dev loop
Run a server, then a live-reloading trunk server that proxies gRPC-web
to it:
```sh
cargo run -p crabidy-server # or `cbd`
devenv shell -- serve-web # trunk serve on http://127.0.0.1:8080
```
`Trunk.toml` proxies `/crabidy.v1.CrabidyService` to `127.0.0.1:50051`,
so the app behaves as if served from the server.
## Tests
The DOM-free logic (pane/selection state machines, the keymap, capture
progress formatting) lives in `src/state.rs` and `src/keymap.rs` and is
unit-tested on the native target:
```sh
cargo test -p cbd-web
```
Components in `src/app.rs` stay thin over that logic. The server-side
serving and the gRPC-web + auth routing are tested in `crabidy-server`
(`src/web.rs`, `tests/web_server.rs`).