diff --git a/.fallowrc.jsonc b/.fallowrc.jsonc index ccb30a1f32..ba82d3950b 100644 --- a/.fallowrc.jsonc +++ b/.fallowrc.jsonc @@ -55,6 +55,16 @@ "packages/studio/src/hooks/gsapRuntimePreview.ts", // TEMP(studio-dnd): shipped unwired ahead of the NLE integration; // the app-shell swap PR (studio-dnd/pr22) wires the consumers and removes this block. + "packages/studio/src/components/nle/NLEContext.tsx", + "packages/studio/src/components/nle/PreviewPane.tsx", + "packages/studio/src/components/nle/AssetPreviewOverlay.tsx", + "packages/studio/src/player/components/TimelineOverlays.tsx", + "packages/studio/src/player/components/timelineClipChildren.tsx", + "packages/studio/src/player/components/timelineClipDragTypes.ts", + "packages/studio/src/player/hooks/useTimelinePlayerLoop.ts", + "packages/studio/src/utils/assetPreviewStore.ts", + // TEMP(studio-dnd): shipped unwired ahead of the NLE integration; + // the app-shell swap PR (studio-dnd/pr22) wires the consumers and removes this block. "packages/studio/src/components/editor/CanvasContextMenu.tsx", ], "ignorePatterns": [ @@ -446,6 +456,9 @@ // complexity pre-dates the computed-timeline work. Exempted at file level // rather than refactored as scope creep. "ignore": [ + // TEMP(studio-dnd): coexistence-window complexity flare (inherited/CRAP-no-coverage); + // removed by studio-dnd/pr22 when the final config lands. + "packages/studio/src/player/components/TimelineOverlays.tsx", // TEMP(studio-dnd): coexistence-window complexity flare (inherited/CRAP-no-coverage); // removed by studio-dnd/pr22 when the final config lands. "packages/studio/src/player/hooks/useTimelineSyncCallbacks.ts", diff --git a/packages/studio/src/components/nle/AssetPreviewOverlay.tsx b/packages/studio/src/components/nle/AssetPreviewOverlay.tsx new file mode 100644 index 0000000000..5364289f15 --- /dev/null +++ b/packages/studio/src/components/nle/AssetPreviewOverlay.tsx @@ -0,0 +1,147 @@ +/** + * CapCut-style asset preview overlay rendered inside PreviewPane. + * + * Shown when the user clicks an asset card that has NOT yet been added to the + * timeline. Displays the media (image / video / audio) without modifying the + * composition — no undo entry, no file mutation. + * + * Dismiss: X button, Escape key, or click on the scrim. + * Switching to another not-added asset replaces the current preview. + */ +import { useEffect, useCallback } from "react"; +import { VIDEO_EXT, IMAGE_EXT } from "../../utils/mediaTypes"; +import { useAssetPreviewStore } from "../../utils/assetPreviewStore"; + +function basename(path: string): string { + return path.split("/").pop() ?? path; +} + +type AssetKind = "image" | "video" | "audio"; + +function resolveAssetKind(path: string): AssetKind { + if (VIDEO_EXT.test(path)) return "video"; + if (IMAGE_EXT.test(path)) return "image"; + return "audio"; +} + +/** The media element for a previewed asset, chosen by kind. */ +function AssetPreviewMedia({ + kind, + serveUrl, + name, +}: { + kind: AssetKind; + serveUrl: string; + name: string; +}) { + if (kind === "image") { + return ( + {name} + ); + } + if (kind === "video") { + return ( +