diff options
| author | ryu <ryumacodes@gmail.com> | 2025-08-13 14:01:07 +0500 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-08-13 14:01:07 +0500 |
| commit | 0ae09c9df5591e2d18991a9f98647826997fe740 (patch) | |
| tree | 69738461bd269ad418bc82c47e64a2670cee7f19 /apps/web/src/components/editor/timeline/timeline-track.tsx | |
| parent | e71788014d137a74f10420601451ddfbb84701bb (diff) | |
| parent | f7fddff1fc8359fc056a2a90488121980fb8ead2 (diff) | |
| download | opencut-0ae09c9df5591e2d18991a9f98647826997fe740.tar.gz | |
Merge branch 'staging' into feat/timeline-return-to-start
Diffstat (limited to 'apps/web/src/components/editor/timeline/timeline-track.tsx')
| -rw-r--r-- | apps/web/src/components/editor/timeline/timeline-track.tsx | 51 |
1 files changed, 48 insertions, 3 deletions
diff --git a/apps/web/src/components/editor/timeline/timeline-track.tsx b/apps/web/src/components/editor/timeline/timeline-track.tsx index 1982d03e..ff4797fb 100644 --- a/apps/web/src/components/editor/timeline/timeline-track.tsx +++ b/apps/web/src/components/editor/timeline/timeline-track.tsx @@ -4,11 +4,10 @@ import { useRef, useState, useEffect } from "react"; import { useTimelineStore } from "@/stores/timeline-store"; import { useMediaStore } from "@/stores/media-store"; import { toast } from "sonner"; +import { processMediaFiles } from "@/lib/media-processing"; import { TimelineElement } from "./timeline-element"; import { TimelineTrack, - sortTracksByOrder, - ensureMainTrack, getMainTrack, canElementGoOnTrack, } from "@/types/timeline"; @@ -16,6 +15,7 @@ import { usePlaybackStore } from "@/stores/playback-store"; import type { TimelineElement as TimelineElementType, DragData, + TrackType, } from "@/types/timeline"; import { snapTimeToFrame, @@ -689,8 +689,9 @@ export function TimelineTrackContent({ const hasMediaItem = e.dataTransfer.types.includes( "application/x-media-item" ); + const hasFiles = e.dataTransfer.files?.length > 0; - if (!hasTimelineElement && !hasMediaItem) return; + if (!hasTimelineElement && !hasMediaItem && !hasFiles) return; const trackContainer = e.currentTarget.querySelector( ".track-elements-container" @@ -1050,6 +1051,50 @@ export function TimelineTrackContent({ trimEnd: 0, }); } + } else if (hasFiles) { + // External file drops + const { activeProject } = useProjectStore.getState(); + const { addMediaItem } = useMediaStore.getState(); + const { addElementToTrack } = useTimelineStore.getState(); + + if (!activeProject) { + toast.error("No active project"); + return; + } + + // Process and add files to new timeline tracks at playhead position + processMediaFiles(e.dataTransfer.files) + .then(async (processedItems) => { + for (const processedItem of processedItems) { + await addMediaItem(activeProject.id, processedItem); + const currentMediaItems = useMediaStore.getState().mediaItems; + const addedItem = currentMediaItems.find( + (item) => + item.name === processedItem.name && + item.url === processedItem.url + ); + + if (addedItem) { + const trackType: TrackType = + addedItem.type === "audio" ? "audio" : "media"; + const targetTrackId = insertTrackAt(trackType, 0); + + addElementToTrack(targetTrackId, { + type: "media", + mediaId: addedItem.id, + name: addedItem.name, + duration: addedItem.duration || 5, + startTime: currentTime, + trimStart: 0, + trimEnd: 0, + }); + } + } + }) + .catch((error) => { + console.error("Error processing external files:", error); + toast.error("Failed to process dropped files"); + }); } } catch (error) { console.error("Error handling drop:", error); |
