From 645f4470158545da43a3e307c0fe84ff9728f2aa Mon Sep 17 00:00:00 2001 From: Brandyn / Techy Date: Sun, 1 Nov 2026 14:36:01 -0600 Subject: [PATCH] =?UTF-8?q?Live=20portal:=20custom=20layouts=20are=20left?= =?UTF-8?q?=20alone=20=E2=80=94=20new=20streams=20chime=20and=20wait=20in?= =?UTF-8?q?=20a=20draggable=20tray;=20Arrange=20re-grids=20and=20returns?= =?UTF-8?q?=20to=20auto?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit layout store (auto/custom + pending), marked custom on manual move (onDidMovePanel outside arrange), sash drag, stream/group rename. Tray chips: HTML5 drag accepted via onUnhandledDragOver/onDidDrop (position -> direction), click = new column. WebAudio two-note chime. Gateway page instructions updated. Verified headless (custom vs auto). Co-Authored-By: Claude Fable 5.1 --- STATUS.md | 2 +- about/index.html | 3 ++- live/src/App.jsx | 57 ++++++++++++++++++++++++++++++++++------- live/src/GroupLabel.jsx | 3 ++- live/src/Tab.jsx | 3 ++- live/src/Tray.jsx | 23 +++++++++++++++++ live/src/layout.js | 30 ++++++++++++++++++++++ live/src/styles.css | 7 +++++ 8 files changed, 115 insertions(+), 13 deletions(-) create mode 100644 live/src/Tray.jsx create mode 100644 live/src/layout.js diff --git a/STATUS.md b/STATUS.md index ccb7feb..f50e133 100644 --- a/STATUS.md +++ b/STATUS.md @@ -31,7 +31,7 @@ Source of truth: this repo, `techy/Media-Server-Setup` on the stack's own Gitea | Streamer | One-time: dock → Timecode band → "Add band + clock source" (OBS) or leave the Go Live checkbox on — gives editors frame-accurate timecode | OBS dock / Go Live | live | | Streamer | Type a title (live preview + naming rules), Go Live, Stop. "Dump tonight" if it was junk (3-day undo). Manual-setup accordion with endpoints and a hidden token | OBS browser dock `https://live.…/dock/` | Discord login in the dock; dock mints a 12 h token per Go Live — **no passwords, verified live** | | Gamer | Self-serve pairing (paste Syncthing Device ID → folder + share created); then nothing, clips save where they always did | `https://clips.…/` + Syncthing | Discord (any server member) | -| Viewer | Live portal lays streams out as an even grid automatically when one joins or leaves ("Arrange" button redoes it after manual moves); audio follows the focused window; double-click a tab to rename a stream (kept in that browser), double-click the slot at the left of a tab bar to name the group (session) | `https://live.…/` | Discord | +| Viewer | Live portal lays streams out as an even grid automatically when one joins or leaves ("Arrange" button redoes it after manual moves); audio follows the focused window; double-click a tab to rename a stream (kept in that browser), double-click the slot at the left of a tab bar to name the group (session); once the viewer has moved/resized/renamed anything the layout is left alone: new streams chime and wait as draggable chips in a tray, "Arrange" re-grids and returns to auto | `https://live.…/` | Discord | | Everyone | Landing page with role-aware links and instructions | `https://media.…/` | Discord | | Editor | Multicam: drop clips on a timeline, sync by the embedded timecode track (frame-accurate when the band was on), cross-check with voice audio; files are already at game resolution (band removed by the sweep) | Resolve / Premiere | — | | Editor | Browse by streamer/title, scrub in browser, download originals (zip/tar for folders), upload finals | copyparty `https://files.…/` | Discord (Authentik); rights by group `editors` / `media-admins` | diff --git a/about/index.html b/about/index.html index 8f3e10c..43598df 100644 --- a/about/index.html +++ b/about/index.html @@ -42,7 +42,8 @@
Live page: windows, groups, names
    -
  • Layout. Windows arrange themselves into an even grid whenever someone goes live or stops. Drag a tab to move a window, drag the bars between windows to resize, drop a tab onto another window to stack them as tabs. Arrange (top bar) snaps everything back to the grid.
  • +
  • Layout. Until you touch it, windows arrange themselves into an even grid whenever someone goes live or stops. Drag a tab to move a window, drag the bars between windows to resize, drop a tab onto another window to stack them as tabs.
  • +
  • Your layout stays yours. The moment you move, resize or rename anything, the page stops rearranging. Streams that end just close. New streams do not barge in: a chime plays and a blinking chip appears in a thin tray under the top bar. Drag the chip onto any window edge, onto a tab bar to stack it, or to the page edge; or click it to add it as a new column on the right. Arrange (top bar) places everything in an even grid and switches automatic layout back on.
  • Audio. Sound follows the window you click. The speaker button pins a window's audio on even when you click elsewhere; Mute all silences everything until you click a window; Follow focus clears pins.
  • Rename a stream. Double-click its tab, type a name, Enter. Escape cancels; an empty name goes back to user · title. Names stay in your browser and come back the next time that streamer uses the same title.
  • Name a group. Every tab bar starts with a + name slot. Double-click it, type, Enter. Group names last until you reload the page.
  • diff --git a/live/src/App.jsx b/live/src/App.jsx index f7e8cf2..716a933 100644 --- a/live/src/App.jsx +++ b/live/src/App.jsx @@ -1,5 +1,5 @@ import React, { useCallback, useEffect, useRef, useState } from 'react' -import { DockviewReact } from 'dockview-react' +import { DockviewReact, positionToDirection } from 'dockview-react' import Player from './Player.jsx' import { fetchStreams } from './api.js' import { audio } from './useAudio.js' @@ -8,6 +8,8 @@ import Tab from './Tab.jsx' import GroupLabel from './GroupLabel.jsx' import GroupActions from './GroupActions.jsx' import { streamLabel } from './names.js' +import { layout, ding } from './layout.js' +import Tray, { STREAM_MIME } from './Tray.jsx' const components = { player: Player } const tabComponents = { player: Tab } @@ -16,7 +18,16 @@ const POLL_MS = 3000 // Lay every panel out as a grid (cols = ceil(sqrt(n)), row-major in stream-start order) and equalize sizes. // Moves the existing panels (dockview keeps the React component and its