Customizable OBS browser dock#37
Merged
Merged
Conversation
Rework the browser dock into a widget system the streamer arranges themselves, so a dock can be a delay controller, a destination switcher, an overlay picker, or a mini-dashboard. - Per-slot saved layout (?dock=<id>), persisted server-side as `dock.<id>=<json>` so it survives OBS wiping its browser cache, with a localStorage mirror for instant paint. - Widgets: status bar (phase chip + live pill, each on/off + chip/dot), delay number (inline +/-, S/M/L), buffer bar (thick/%), egress glance (dests/bitrate/codec), hint, destinations (rows/icons, confirm, per-row bitrate, active-only), delay profiles, health stats, auto behavior, settings, overlays (search + folders + open/copy), action (confirm-cut). - Editor: bottom-sheet with presets (Full/Minimal/Delay/Destinations/ Control/Dashboard), per-widget options, drag-to-reorder, density, accent color, and a dock-slot switcher. - Split dock logic into web/dock.js (served gzip like overlay-runtime.js). - New: POST /destinations/toggle (flips enabled only, preserves the destination's other fields), GET /docks + GET/POST /docks/<id>. Behavior/settings reuse the partial POST /config; profiles/overlays reuse existing GET endpoints. Adds a config dock-layout round-trip test; full suite (236) passes.
Sync - bring the dock up to dashboard parity: - Destination toggles made anywhere (dashboard or another dock) now refresh the strip immediately: the SSE state stream carries per-dest enabled/alive, so a fingerprint change triggers a fetch instead of waiting out the 4 s poll. - Same-slot layout sync: OBS docks share one browser profile, so a save in one instance reaches the others via the storage event and is applied live - two docks on ?dock=1 stay identical without reloads. - Profiles / overlays / server config refresh on focus/visibility, so edits made in the dashboard appear when the user clicks back into OBS. Visualization: - Health stats: Row / Tiles modes (tile grid with big numbers). - Delay profiles: Chips / List modes (full-width rows, seconds right). UX: - Reset action in the editor (two-tap confirm) restores the default layout when a dock gets into a bad arrangement.
Design-engineering pass over the dock UI: Alive signals - Live dot breathes while an encoder is connected. - The armed "Activate" button pulses a soft glow - the one moment the dock wants the streamer's eye. - Delay number pops (scale 1.04 + accent) when the value changes. - Staggered rise-in on first paint; the boot class comes off after one pass so saves/reorders never replay the entrance. Motion discipline - Every `transition: .15s` shorthand (= transition:all) replaced with property-specific transitions. - All press scales normalized to 0.96 (was a mix of .9/.92/.94/.98). - prefers-reduced-motion kills entrances and looping pulses. Smart & responsive - +/- nudges disable at the 0 / 600 s bounds. - Enter in the delay field presses the main button (keyboard-first arm). - Invisible hit halos on the gear, switches, and confirm buttons. - Keyboard-only focus ring (:focus-visible) in the accent color. - <=220 px docks shave padding and let the status/egress rows wrap. - Editor row radius fixed for concentric nesting inside the sheet.
User feedback: "the little buttons colored... color coded by platform". - Destinations get a "Platform colors" option (default on): the icon badge letter + live ring, the row's platform label + live dot, and the on-switch all take the platform's brand hue (Twitch purple, YouTube red, Kick green, Trovo green, Restream orange). Custom/sink stay neutral; the amber confirm state still overrides. - Delay number: "Accent number" tints the readout in the dock accent. - Buffer bar: "Accent bar" keeps one hue through fill/ready/active instead of the amber -> cyan -> green state ramp. Applied via a per-element --pc custom property so the CSS stays static.
The dashboard could schedule a safe cut and the dock would neither offer it nor show one counting down. The secondary CTA now schedules the cut while active, shows a live ~Ns countdown (tap to cancel), and a pending cut renders even with the option off since it may come from the dashboard. Also: dest strip under 'Active only' no longer claims no destinations exist.
…-side A delay bigger than the ring can hold at the current bitrate never fills - it stalls in arming forever, which reads as a hang. The dashboard already greyed out over-capacity profiles; the dock did not, and nothing stopped a scripted or stale client from asking for the impossible. - dock: port the capacity estimate (audio+overhead+headroom, bitrate peak-hold). Over-cap profile chips go dimmed/struck/disabled with a tooltip naming the MB needed; arm() and profileSet() refuse with a toast. - server: /arm rejects ms > capacity (409) using the same estimate it publishes as buffer_capacity_ms_est, bitrate floored at 2 Mbps so idle pre-arms stay generous. Defence in depth behind the client gate. - dashboard: arm() now surfaces the server's 409 message instead of falsely toasting 'Arming'.
Owner
Author
Update:
edit: Thanks "fashionxd" for your feedback and inspiration for this feature! |
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.
Customizable OBS browser dock
A composable, per-slot OBS browser dock for driving InstantClone from inside OBS without opening the full dashboard, so competitive streamers can keep the CPU free. Everything is a widget you can toggle, reorder, and restyle; layouts are saved server-side and survive restarts.
What's in it
?dock=<id>slots, each with its own saved layout. Copy-URL flows to spin up a second dock in OBS.dock.<id>=<json>), mirrored in localStorage for instant paint, reconciled from the server as source of truth./arm(defence in depth).Server changes
/docks/<id>GET/POST/list with size + charset validation;dock.<id>config lines (MAX_DOCKS,MAX_DOCK_LAYOUT_LEN)./destinations/toggleendpoint that flipsenabledonly, without the field-rebuild the upsert path does./armcapacity guard returning 409 with a plain message when a delay can't fill./dock.jsserved as an embedded gzip asset.Verification
node --check web/dock.jsclean,cargo buildclean, 236 tests pass (including a dock-layout round-trip through save/load).Not yet done