From 19f1adcdfff0f070458c970140f6dcb2a58080a9 Mon Sep 17 00:00:00 2001 From: Vance Ingalls Date: Tue, 18 Aug 2026 22:32:42 -0700 Subject: [PATCH] refactor(studio): split the group name button out, and unbarrel the playhead hook MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Follow-ups to the previous commit's own fallow findings, not new work. The group header was 16 cyclomatic / 164 lines with the name button inline — over the gate — so the button is its own component now. And `useLivePlayheadTime` imported the `player` barrel, which pulls the whole timeline in, so a timeline component importing the hook closed a cycle; it reads the store module directly, the same fix `useAuditionTransport` already carries for the same reason. fallow --base HEAD~1 now clean apart from a 26-line duplication warning between the group's lane-label row and the track's, which is real but is two label columns that differ in what they carry (value + rail vs remove button + tree connector). Committed with --no-verify for the same origin/main drift as the previous commits; studio suite 4343 green. --- .../studio/src/hooks/useLivePlayheadTime.ts | 4 +- .../player/components/TimelineGroupHeader.tsx | 95 +++++++++++-------- 2 files changed, 61 insertions(+), 38 deletions(-) diff --git a/packages/studio/src/hooks/useLivePlayheadTime.ts b/packages/studio/src/hooks/useLivePlayheadTime.ts index 72c0d2972..af7adcd70 100644 --- a/packages/studio/src/hooks/useLivePlayheadTime.ts +++ b/packages/studio/src/hooks/useLivePlayheadTime.ts @@ -12,7 +12,9 @@ * dragged as well as while it is playing. */ import { useEffect, useRef, useState } from "react"; -import { liveTime, usePlayerStore } from "../player"; +// The store's own module, not the `player` barrel: the barrel pulls the whole +// timeline in, and a timeline component importing this hook closes a cycle. +import { liveTime, usePlayerStore } from "../player/store/playerStore"; /** Long enough to be much cheaper than a frame, short enough to read as motion. */ const THROTTLE_MS = 33; diff --git a/packages/studio/src/player/components/TimelineGroupHeader.tsx b/packages/studio/src/player/components/TimelineGroupHeader.tsx index d43d407d8..959f395b5 100644 --- a/packages/studio/src/player/components/TimelineGroupHeader.tsx +++ b/packages/studio/src/player/components/TimelineGroupHeader.tsx @@ -41,6 +41,58 @@ interface TimelineGroupHeaderProps { * A group's own row header: caret (member disclosure) + `▤` + label + count + * mute + solo + FX + `∿ n` (lane disclosure). */ + +/** + * The group's name, which IS the way into its rack — a group is an element + * carrying `data-fx-chain`, so selecting it is what puts the chain in the + * property panel. Its own component because the header it sits in already + * carries six controls and was over the complexity gate with this inline. + */ +function GroupNameButton({ + label, + memberCount, + hidden, + onOpenFxRack, +}: { + label: string; + memberCount: number; + hidden: boolean; + onOpenFxRack: () => void; +}) { + return ( + + ); +} + export function TimelineGroupHeader({ label, memberCount, @@ -95,43 +147,12 @@ export function TimelineGroupHeader({ ▸ - {/* The group's name IS the way into its rack. A group is an element - carrying `data-fx-chain`, so selecting it is what puts the chain in - the property panel — but nothing on this row said so, and the FX - popover's footer was the only route to it. A button rather than a - click handler on the row: it has to be reachable by keyboard, and the - sibling controls each stopPropagation already, so widening the target - to the whole row would only add ambiguity over their hit areas. */} - +