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 the unfocused one collapses to a title strip (tapping it also
switches) and the tabs are how you get back.
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.