From a2a8bf42af58e2901245eb481e8f21ab13437add Mon Sep 17 00:00:00 2001 From: ukimsanov Date: Sat, 11 Jul 2026 13:55:25 -0700 Subject: [PATCH] feat(studio): assets/blocks panel behaviors + preview helpers What: blocks tab install flow, right-panel and global drag-overlay polish, music beat analysis and clip-content rendering hooks, and the preview-helper utilities backing asset preview. Why: completes the studio NLE stack on top of the visual refresh. How: modified files only (kept as one PR: splitting further would produce sub-150-LOC fragments of interdependent panel glue). Test plan: bunx vitest run studioPreviewHelpers/studioUrlState suites; tsc --noEmit; fallow audit clean. --- .../components/StudioGlobalDragOverlay.tsx | 4 +- .../src/components/StudioRightPanel.tsx | 11 +- .../src/components/sidebar/BlocksTab.tsx | 9 +- packages/studio/src/hooks/useBlockHandlers.ts | 82 ++++++++----- .../studio/src/hooks/useMusicBeatAnalysis.ts | 108 ++++++++++++------ .../studio/src/hooks/useRenderClipContent.ts | 30 ++++- .../src/utils/studioPreviewHelpers.test.ts | 73 ++++++++++-- .../studio/src/utils/studioPreviewHelpers.ts | 10 ++ .../studio/src/utils/studioUrlState.test.ts | 1 - 9 files changed, 243 insertions(+), 85 deletions(-) diff --git a/packages/studio/src/components/StudioGlobalDragOverlay.tsx b/packages/studio/src/components/StudioGlobalDragOverlay.tsx index ecd65cb614..00e562af33 100644 --- a/packages/studio/src/components/StudioGlobalDragOverlay.tsx +++ b/packages/studio/src/components/StudioGlobalDragOverlay.tsx @@ -17,9 +17,7 @@ export function StudioGlobalDragOverlay() { - - Drop files to import into project - + Drop to add at the playhead ); diff --git a/packages/studio/src/components/StudioRightPanel.tsx b/packages/studio/src/components/StudioRightPanel.tsx index c65fd3d0c4..652876c2bb 100644 --- a/packages/studio/src/components/StudioRightPanel.tsx +++ b/packages/studio/src/components/StudioRightPanel.tsx @@ -446,12 +446,14 @@ export function StudioRightPanel({ return ( <> + {/* Vertical resize divider: 3px visible seam, 8px pointer-capture zone via + the absolutely-positioned inner hit area. */}
handlePanelResizeStart("right", e)} onPointerMove={handlePanelResizeMove} @@ -465,10 +467,13 @@ export function StudioRightPanel({ setRightWidth(Math.max(160, Math.min(600, rightWidth + delta))); }} > -
+ {/* Expanded hit zone: 8px wide, centered on the 3px seam */} +
+ {/* Visible hairline */} +
{captionEditMode ? ( diff --git a/packages/studio/src/components/sidebar/BlocksTab.tsx b/packages/studio/src/components/sidebar/BlocksTab.tsx index c94807f1a6..6b4c27eec8 100644 --- a/packages/studio/src/components/sidebar/BlocksTab.tsx +++ b/packages/studio/src/components/sidebar/BlocksTab.tsx @@ -10,6 +10,7 @@ import { import { usePlayerStore } from "../../player"; import { formatTime } from "../../player/lib/time"; import { useStudioShellContext } from "../../contexts/StudioContext"; +import { TIMELINE_BLOCK_MIME } from "../../utils/timelineAssetDrop"; export interface BlockPreviewInfo { videoUrl?: string; posterUrl?: string; @@ -383,10 +384,16 @@ function BlockCard({ return (
{ + e.dataTransfer.effectAllowed = "copy"; + e.dataTransfer.setData(TIMELINE_BLOCK_MIME, JSON.stringify({ name })); + e.dataTransfer.setData("text/plain", name); + handleLeave(); // cancel the hover-preview timer so it doesn't fire mid-drag + }} onPointerEnter={handleEnter} onPointerLeave={handleLeave} > - {/* Thumbnail */}
{hovered && videoUrl ? (