mirror of
https://github.com/heygen-com/hyperframes.git
synced 2026-09-11 14:50:02 +00:00
refactor(studio): split the group name button out, and unbarrel the playhead hook
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.
This commit is contained in:
@@ -12,7 +12,9 @@
|
|||||||
* dragged as well as while it is playing.
|
* dragged as well as while it is playing.
|
||||||
*/
|
*/
|
||||||
import { useEffect, useRef, useState } from "react";
|
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. */
|
/** Long enough to be much cheaper than a frame, short enough to read as motion. */
|
||||||
const THROTTLE_MS = 33;
|
const THROTTLE_MS = 33;
|
||||||
|
|||||||
@@ -41,6 +41,58 @@ interface TimelineGroupHeaderProps {
|
|||||||
* A group's own row header: caret (member disclosure) + `▤` + label + count +
|
* A group's own row header: caret (member disclosure) + `▤` + label + count +
|
||||||
* mute + solo + FX + `∿ n` (lane disclosure).
|
* 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 (
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
tabIndex={-1}
|
||||||
|
aria-label={`Open ${label} effects`}
|
||||||
|
title="Open effects"
|
||||||
|
className="flex min-w-0 flex-1 items-center gap-1.5 rounded border-0 bg-transparent p-0 text-left text-[11px] text-white hover:text-[#3CE6AC] focus-visible:outline focus-visible:outline-1 focus-visible:outline-[#3CE6AC]"
|
||||||
|
onPointerDown={(event) => event.stopPropagation()}
|
||||||
|
onClick={(event) => {
|
||||||
|
event.stopPropagation();
|
||||||
|
onOpenFxRack();
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<span aria-hidden="true" className="shrink-0 text-[12px] leading-none text-white/50">
|
||||||
|
▤
|
||||||
|
</span>
|
||||||
|
{/* Struck through, not merely dimmed — the designs are explicit that "a
|
||||||
|
muted track that only looks dim is a track someone re-mutes by
|
||||||
|
accident", and a muted GROUP silences every member at once, so it is
|
||||||
|
the most expensive one to misread. */}
|
||||||
|
<span className={`min-w-0 flex-1 truncate font-medium${hidden ? " line-through" : ""}`}>
|
||||||
|
{label}
|
||||||
|
</span>
|
||||||
|
<span
|
||||||
|
className="shrink-0 rounded-full bg-white/10 px-1 text-[9px] leading-[14px] tabular-nums text-white/55"
|
||||||
|
aria-hidden="true"
|
||||||
|
title={`${memberCount} tracks`}
|
||||||
|
>
|
||||||
|
{memberCount}
|
||||||
|
</span>
|
||||||
|
</button>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
export function TimelineGroupHeader({
|
export function TimelineGroupHeader({
|
||||||
label,
|
label,
|
||||||
memberCount,
|
memberCount,
|
||||||
@@ -95,43 +147,12 @@ export function TimelineGroupHeader({
|
|||||||
▸
|
▸
|
||||||
</span>
|
</span>
|
||||||
</button>
|
</button>
|
||||||
{/* The group's name IS the way into its rack. A group is an element
|
<GroupNameButton
|
||||||
carrying `data-fx-chain`, so selecting it is what puts the chain in
|
label={label}
|
||||||
the property panel — but nothing on this row said so, and the FX
|
memberCount={memberCount}
|
||||||
popover's footer was the only route to it. A button rather than a
|
hidden={hidden}
|
||||||
click handler on the row: it has to be reachable by keyboard, and the
|
onOpenFxRack={onOpenFxRack}
|
||||||
sibling controls each stopPropagation already, so widening the target
|
/>
|
||||||
to the whole row would only add ambiguity over their hit areas. */}
|
|
||||||
<button
|
|
||||||
type="button"
|
|
||||||
tabIndex={-1}
|
|
||||||
aria-label={`Open ${label} effects`}
|
|
||||||
title="Open effects"
|
|
||||||
className="flex min-w-0 flex-1 items-center gap-1.5 rounded border-0 bg-transparent p-0 text-left text-[11px] text-white hover:text-[#3CE6AC] focus-visible:outline focus-visible:outline-1 focus-visible:outline-[#3CE6AC]"
|
|
||||||
onPointerDown={(event) => event.stopPropagation()}
|
|
||||||
onClick={(event) => {
|
|
||||||
event.stopPropagation();
|
|
||||||
onOpenFxRack();
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<span aria-hidden="true" className="shrink-0 text-[12px] leading-none text-white/50">
|
|
||||||
▤
|
|
||||||
</span>
|
|
||||||
{/* Struck through, not merely dimmed — the designs are explicit that "a
|
|
||||||
muted track that only looks dim is a track someone re-mutes by
|
|
||||||
accident", and a muted GROUP silences every member at once, so it is
|
|
||||||
the most expensive one to misread. */}
|
|
||||||
<span className={`min-w-0 flex-1 truncate font-medium${hidden ? " line-through" : ""}`}>
|
|
||||||
{label}
|
|
||||||
</span>
|
|
||||||
<span
|
|
||||||
className="shrink-0 rounded-full bg-white/10 px-1 text-[9px] leading-[14px] tabular-nums text-white/55"
|
|
||||||
aria-hidden="true"
|
|
||||||
title={`${memberCount} tracks`}
|
|
||||||
>
|
|
||||||
{memberCount}
|
|
||||||
</span>
|
|
||||||
</button>
|
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
tabIndex={-1}
|
tabIndex={-1}
|
||||||
|
|||||||
Reference in New Issue
Block a user