crabidy/docs/src/clients/web.md

3.8 KiB

Web client — cbd-web

cbd-web is a browser client with the same functionality as the terminal UI: library browsing, search terms, queue manipulation, playback control, saves (w), captures (W, with progress), and the live update stream. It is a Leptos application compiled to WebAssembly and rendered client-side in the browser — no terminal required, so phones, tablets, and guests can drive the server.

Every TUI binding has a clickable equivalent, and the familiar keyboard bindings (j/k/h/l, Tab, %, e, d, w, W, playback and queue keys, ? for help) also work on desktop browsers. That includes marks (s), visual mode (v/V) in both panes, and the register — y yanks, d/c/C fill it as they remove, and p/P paste it after or before the cursor (see the TUI's register section, which behaves identically here; the queue toolbar shows how many entries are waiting). Seek is there too — , and . move 15 seconds back and forward (< and > skip a whole track), as do the «/» buttons in the transport bar, and the progress bar is clickable — a click seeks to that point in the track. The / live filter is TUI-only for now.

A pair of library / queue tabs in the top bar switches panes and shows which one the keys go to — the same thing Tab does, reachable without a keyboard. It matters on a phone: below 700px the two panes cannot sit side by side, so only the focused one is rendered and the tabs are the way between them.

The volume slider spans the server's whole accepted range, ending at 110% — the server clamps there, so a slider that went further would have a dead stretch at its right end. Its tooltip reports the current level as a percentage; the TUI shows the same figure in its now-playing pane.

How it is served

The browser talks gRPC-web to the same service the TUI uses. There is no second API surface: the server wraps its existing gRPC service in a gRPC-web layer, so the browser calls the same /crabidy.v1.CrabidyService/… paths, including the streaming GetUpdateStream, from the same generated clients.

direction: right

browser: Browser {
  app: cbd-web (Leptos CSR wasm)
}

server: "crabidy-server :50051" {
  static: embedded cbd-web bundle
  grpcweb: gRPC-web layer
  rpc: CrabidyService
  grpcweb -> rpc
}

browser.app -> server.static: GET / and assets
browser.app -> server.grpcweb: gRPC-web (fetch)

Everything is served on the server's own address — gRPC for the TUI, gRPC-web for the browser, and the static app assets all share one port. Opening http://<server>:50051/ in a browser is the whole install story; there is no separate host to run.

Embedded in the server

cbd-web is not run directly. It is built to a WASM bundle and embedded into crabidy-server behind the web-ui cargo feature, which is on by default (and thus present in cbd too). A plain cargo build needs no WASM toolchain: until you build the bundle, the server embeds a "web UI not built" placeholder page. Building the bundle re-embeds it automatically on the next server build.

devenv shell -- build-web        # writes the cbd-web bundle
cargo build -p crabidy-server    # embeds it

Building the server with --no-default-features drops the feature for a headless, gRPC-only binary.

Auth and theme

The static app shell is public; every RPC behind it stays gated. When the server has auth configured, the client shows a login form on the first unauthorized RPC and sends the role name and password as basic-auth credentials — the same [auth] roles the TUI honors, enforced identically. Credentials and the theme choice are kept in the browser.

The interface offers a light and a dark theme with a manual toggle, following the browser's preference by default.