diff options
| author | Maze Winther <mazewinther@gmail.com> | 2026-03-25 16:47:22 +0100 |
|---|---|---|
| committer | Maze Winther <mazewinther@gmail.com> | 2026-03-29 15:48:22 +0200 |
| commit | 8db3bead13441a5882d8689dfc6a9f09c82375d9 (patch) | |
| tree | e9d0cafa93904ffcbec3188c37961bcc16c6422d /apps/web/src/hooks/use-paste-media.ts | |
| parent | 39ea298a9ccba3104c549c0ca079c231981811f5 (diff) | |
| download | opencut-8db3bead13441a5882d8689dfc6a9f09c82375d9.tar.gz | |
feat: masks, properties refactor, shaders, storage migrations, and more
Diffstat (limited to 'apps/web/src/hooks/use-paste-media.ts')
| -rw-r--r-- | apps/web/src/hooks/use-paste-media.ts | 81 |
1 files changed, 48 insertions, 33 deletions
diff --git a/apps/web/src/hooks/use-paste-media.ts b/apps/web/src/hooks/use-paste-media.ts index 4533ab28..8f362a12 100644 --- a/apps/web/src/hooks/use-paste-media.ts +++ b/apps/web/src/hooks/use-paste-media.ts @@ -1,14 +1,15 @@ import { useEffect } from "react"; -import { toast } from "sonner"; import { useEditor } from "@/hooks/use-editor"; import { processMediaAssets } from "@/lib/media/processing"; +import { showMediaUploadToast } from "@/lib/media/upload-toast"; +import { invokeAction } from "@/lib/actions"; import { buildElementFromMedia } from "@/lib/timeline/element-utils"; import { AddMediaAssetCommand } from "@/lib/commands/media"; import { InsertElementCommand } from "@/lib/commands/timeline"; import { BatchCommand } from "@/lib/commands"; import { TIMELINE_CONSTANTS } from "@/constants/timeline-constants"; import { isTypableDOMElement } from "@/utils/browser"; -import type { MediaType } from "@/types/assets"; +import type { MediaType } from "@/lib/media/types"; const MEDIA_MIME_PREFIXES: MediaType[] = ["image", "video", "audio"]; @@ -40,6 +41,7 @@ export function usePasteMedia() { useEffect(() => { const handlePaste = async (event: ClipboardEvent) => { const activeElement = document.activeElement as HTMLElement; + if (activeElement && isTypableDOMElement({ element: activeElement })) { return; } @@ -47,7 +49,11 @@ export function usePasteMedia() { const files = extractMediaFilesFromClipboard({ clipboardData: event.clipboardData, }); - if (files.length === 0) return; + if (files.length === 0) { + event.preventDefault(); + invokeAction("paste-copied"); + return; + } event.preventDefault(); @@ -55,41 +61,50 @@ export function usePasteMedia() { if (!activeProject) return; try { - const processedAssets = await processMediaAssets({ files }); - const startTime = editor.playback.getCurrentTime(); + await showMediaUploadToast({ + filesCount: files.length, + promise: async () => { + const processedAssets = await processMediaAssets({ files }); + const startTime = editor.playback.getCurrentTime(); + + for (const asset of processedAssets) { + const addMediaCmd = new AddMediaAssetCommand( + activeProject.metadata.id, + asset, + ); + const assetId = addMediaCmd.getAssetId(); + const duration = + asset.duration ?? TIMELINE_CONSTANTS.DEFAULT_ELEMENT_DURATION; + const trackType = asset.type === "audio" ? "audio" : "video"; - for (const asset of processedAssets) { - const addMediaCmd = new AddMediaAssetCommand( - activeProject.metadata.id, - asset, - ); - const assetId = addMediaCmd.getAssetId(); - const duration = - asset.duration ?? TIMELINE_CONSTANTS.DEFAULT_ELEMENT_DURATION; - const trackType = asset.type === "audio" ? "audio" : "video"; + const element = buildElementFromMedia({ + mediaId: assetId, + mediaType: asset.type, + name: asset.name, + duration, + startTime, + buffer: + asset.type === "audio" + ? new AudioBuffer({ length: 1, sampleRate: 44100 }) + : undefined, + }); - const element = buildElementFromMedia({ - mediaId: assetId, - mediaType: asset.type, - name: asset.name, - duration, - startTime, - buffer: - asset.type === "audio" - ? new AudioBuffer({ length: 1, sampleRate: 44100 }) - : undefined, - }); + const insertCmd = new InsertElementCommand({ + element, + placement: { mode: "auto", trackType }, + }); + const batchCmd = new BatchCommand([addMediaCmd, insertCmd]); + editor.command.execute({ command: batchCmd }); + } - const insertCmd = new InsertElementCommand({ - element, - placement: { mode: "auto", trackType }, - }); - const batchCmd = new BatchCommand([addMediaCmd, insertCmd]); - editor.command.execute({ command: batchCmd }); - } + return { + uploadedCount: processedAssets.length, + assetNames: processedAssets.map((asset) => asset.name), + }; + }, + }); } catch (error) { console.error("Failed to paste media:", error); - toast.error("Failed to paste media"); } }; |
