Skip to content

Customizable OBS browser dock#37

Merged
Soulhackzlol merged 10 commits into
mainfrom
feat/system-obs-quick-launch
Jul 6, 2026
Merged

Customizable OBS browser dock#37
Soulhackzlol merged 10 commits into
mainfrom
feat/system-obs-quick-launch

Conversation

@Soulhackzlol

Copy link
Copy Markdown
Owner

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

  • Widget system with presets (Full / Minimal / Delay only / Destinations / Control / Dashboard) and an in-dock bottom-sheet editor (drag to reorder, per-widget options, density, six accent themes).
  • Multiple docks via ?dock=<id> slots, each with its own saved layout. Copy-URL flows to spin up a second dock in OBS.
  • Durable persistence: layout saved to the config file (dock.<id>=<json>), mirrored in localStorage for instant paint, reconciled from the server as source of truth.
  • Live sync on par with the dashboard: SSE state stream, instant destination refresh on a state fingerprint, cross-dock layout sync via storage events, focus/visibility aux refresh.
  • Widgets: status bar (phase chip + live pill), delay number (editable setter that retires to a clean readout when engaged), buffer bar, egress glance, hint text, destinations (rows/icons, platform-coded colors, two-tap misclick guard), delay profiles, health stats (CPU/RAM/reconnects/backpressure), auto-behavior toggles, live-safe settings, overlays picker with search + folders, and the action button.
  • Safe cut ("cut after this airs") parity with the dashboard: schedule from the dock, live countdown, cancellable; a cut scheduled anywhere shows on every dock.
  • Buffer-capacity gate: profiles/delays too big for the ring at the current bitrate are greyed out and refused, with a tooltip naming the buffer size needed. Enforced client-side on both dock and dashboard, and server-side on /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/toggle endpoint that flips enabled only, without the field-rebuild the upsert path does.
  • /arm capacity guard returning 409 with a plain message when a delay can't fill.
  • /dock.js served as an embedded gzip asset.

Verification

  • node --check web/dock.js clean, cargo build clean, 236 tests pass (including a dock-layout round-trip through save/load).
  • Live smoke tests: restart-durable layout persistence, destination toggle field preservation, safe-cut 409-when-idle, and the capacity guard (a 50 MB buffer arms 100s but rejects 300s with a clear message).

Not yet done

  • Opened as draft pending an in-OBS verification pass (platform colors on the dark panel, safe-cut countdown, cross-dock sync, capacity gating). Promote to Ready once that checks out.

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'.
@Soulhackzlol Soulhackzlol added the enhancement New feature or request label Jul 6, 2026
@Soulhackzlol Soulhackzlol self-assigned this Jul 6, 2026
@Soulhackzlol
Soulhackzlol marked this pull request as ready for review July 6, 2026 10:52
@Soulhackzlol

Soulhackzlol commented Jul 6, 2026

Copy link
Copy Markdown
Owner Author

Update:

  • Manually tweaked and tested.
  • Bumped to 0.1.10 as a full new release.
  • Feedback is expected

edit: Thanks "fashionxd" for your feedback and inspiration for this feature!

@Soulhackzlol
Soulhackzlol merged commit 5019b6d into main Jul 6, 2026
4 checks passed
@Soulhackzlol
Soulhackzlol deleted the feat/system-obs-quick-launch branch July 6, 2026 11:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant