mirror of
https://github.com/heygen-com/hyperframes.git
synced 2026-09-03 23:03:09 +00:00
feat: add studio timeline editing (#390)
## Summary Add the actual Studio timeline editing layer on top of the preview/runtime foundation. This PR includes: - drag-to-move clips across time and tracks - left/right resize handles with media-aware trim persistence - edge auto-scroll and edge track creation while dragging - selector-based source patching for `data-start`, `data-duration`, `data-track-index`, `z-index`, and media trim attributes - timeline UI cleanup, theming, hover/drag states, and the `Copy Prompt` action ## Why This PR Is Separate This is the user-facing editing behavior. It depends on the preview/runtime fixes in the base PR, but it is much easier to review once that plumbing is isolated. ## Verification - `bun run --filter @hyperframes/studio test` - `bun run --filter @hyperframes/studio typecheck` - `bunx oxlint packages/studio/src/App.tsx packages/studio/src/components/nle/NLELayout.tsx packages/studio/src/player/components/EditModal.tsx packages/studio/src/player/components/Timeline.tsx packages/studio/src/player/components/TimelineClip.tsx packages/studio/src/player/components/timelineEditing.ts packages/studio/src/player/components/timelineEditing.test.ts packages/studio/src/player/components/timelineTheme.ts packages/studio/src/player/components/timelineTheme.test.ts packages/studio/src/utils/sourcePatcher.ts packages/studio/src/utils/sourcePatcher.test.ts` - `bunx oxfmt --check packages/studio/src/App.tsx packages/studio/src/components/nle/NLELayout.tsx packages/studio/src/player/components/EditModal.tsx packages/studio/src/player/components/Timeline.tsx packages/studio/src/player/components/TimelineClip.tsx packages/studio/src/player/components/timelineEditing.ts packages/studio/src/player/components/timelineEditing.test.ts packages/studio/src/player/components/timelineTheme.ts packages/studio/src/player/components/timelineTheme.test.ts packages/studio/src/utils/sourcePatcher.ts packages/studio/src/utils/sourcePatcher.test.ts` ## Browser Proof - verified timeline drag / resize / trim flows in Studio with `agent-browser` - verified preview hot-refresh behavior without iframe remount flashes ## Stack - depends on #389 - followed by `fix: smooth scrubber end seeking` [result.mp4 <span class="graphite__hidden">(uploaded via Graphite)</span> <img class="graphite__hidden" src="https://app.graphite.com/user-attachments/thumbnails/ca71c177-5042-468d-906f-b353938f40f8.mp4" />](https://app.graphite.com/user-attachments/video/ca71c177-5042-468d-906f-b353938f40f8.mp4)
This commit is contained in:
@@ -27,6 +27,15 @@ interface NLELayoutProps {
|
||||
element: TimelineElement,
|
||||
style: { clip: string; label: string },
|
||||
) => ReactNode;
|
||||
/** Persist timeline move actions back into source HTML */
|
||||
onMoveElement?: (
|
||||
element: TimelineElement,
|
||||
updates: Pick<TimelineElement, "start" | "track">,
|
||||
) => Promise<void> | void;
|
||||
onResizeElement?: (
|
||||
element: TimelineElement,
|
||||
updates: Pick<TimelineElement, "start" | "duration" | "playbackStart">,
|
||||
) => Promise<void> | void;
|
||||
/** Exposes the compIdToSrc map for parent components (e.g., useRenderClipContent) */
|
||||
onCompIdToSrcChange?: (map: Map<string, string>) => void;
|
||||
/** Whether the timeline panel is visible (default: true) */
|
||||
@@ -50,6 +59,8 @@ export const NLELayout = memo(function NLELayout({
|
||||
onIframeRef,
|
||||
onCompositionChange,
|
||||
renderClipContent,
|
||||
onMoveElement,
|
||||
onResizeElement,
|
||||
onCompIdToSrcChange,
|
||||
timelineVisible,
|
||||
onToggleTimeline,
|
||||
@@ -379,6 +390,8 @@ export const NLELayout = memo(function NLELayout({
|
||||
onSeek={seek}
|
||||
onDrillDown={handleDrillDown}
|
||||
renderClipContent={renderClipContent}
|
||||
onMoveElement={onMoveElement}
|
||||
onResizeElement={onResizeElement}
|
||||
/>
|
||||
</div>
|
||||
{timelineFooter && <div className="flex-shrink-0">{timelineFooter}</div>}
|
||||
|
||||
Reference in New Issue
Block a user