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 <noreply@anthropic.com>
31 lines
1.7 KiB
JavaScript
31 lines
1.7 KiB
JavaScript
import { create } from './tinyStore.js'
|
|
|
|
// Layout mode. "auto" = untouched grid: streams joining/leaving re-grid everything. The first manual move, resize
|
|
// or rename makes it "custom": the grid is left alone, leavers just close, joiners wait in the tray (with a ding)
|
|
// until dragged in. "Arrange" re-grids everything and goes back to auto.
|
|
export const layout = create({
|
|
custom: false,
|
|
pending: [], // streams live but not placed yet (custom mode)
|
|
markCustom() { return this.custom ? null : { custom: true } },
|
|
reset() { return { custom: false, pending: [] } },
|
|
addPending(s) { return this.pending.some(p => p.id === s.id) ? null : { pending: [...this.pending, s] } },
|
|
dropPending(id) { return this.pending.some(p => p.id === id) ? { pending: this.pending.filter(p => p.id !== id) } : null },
|
|
keepPending(ids) { const pending = this.pending.filter(p => ids.has(p.id)); return pending.length === this.pending.length ? null : { pending } },
|
|
})
|
|
|
|
// short two-note chime (WebAudio, no asset). Browsers need one prior click on the page to allow sound.
|
|
let ctx
|
|
export function ding() {
|
|
try {
|
|
ctx = ctx || new (window.AudioContext || window.webkitAudioContext)()
|
|
if (ctx.state === 'suspended') ctx.resume().catch(() => {})
|
|
const t0 = ctx.currentTime
|
|
for (const [i, f] of [[0, 880], [0.16, 1320]]) {
|
|
const o = ctx.createOscillator(), g = ctx.createGain()
|
|
o.type = 'sine'; o.frequency.value = f
|
|
g.gain.setValueAtTime(0, t0 + i); g.gain.linearRampToValueAtTime(0.25, t0 + i + 0.02); g.gain.exponentialRampToValueAtTime(0.001, t0 + i + 0.35)
|
|
o.connect(g).connect(ctx.destination); o.start(t0 + i); o.stop(t0 + i + 0.4)
|
|
}
|
|
} catch {}
|
|
}
|