diff options
| author | Maze Winther <mazewinther@gmail.com> | 2025-07-04 01:30:24 +0200 |
|---|---|---|
| committer | Maze Winther <mazewinther@gmail.com> | 2025-07-04 01:30:24 +0200 |
| commit | 47288849319b7cec46aaf83f81845fb1ba5986d4 (patch) | |
| tree | 771c2900b6df97a3ea121e3311ca0c826165ab00 /apps/web/src/components/editor/media-panel/views | |
| parent | fb9f47117c2aad4e71828b17edc83f7cedb799e6 (diff) | |
| download | opencut-47288849319b7cec46aaf83f81845fb1ba5986d4.tar.gz | |
refactor: new reusable draggable-item component and use it
Diffstat (limited to 'apps/web/src/components/editor/media-panel/views')
| -rw-r--r-- | apps/web/src/components/editor/media-panel/views/media.tsx | 80 | ||||
| -rw-r--r-- | apps/web/src/components/editor/media-panel/views/text.tsx | 22 |
2 files changed, 44 insertions, 58 deletions
diff --git a/apps/web/src/components/editor/media-panel/views/media.tsx b/apps/web/src/components/editor/media-panel/views/media.tsx index e2c72106..50fb6fa6 100644 --- a/apps/web/src/components/editor/media-panel/views/media.tsx +++ b/apps/web/src/components/editor/media-panel/views/media.tsx @@ -7,7 +7,6 @@ import { useTimelineStore } from "@/stores/timeline-store"; import { Image, Music, Plus, Upload, Video } from "lucide-react";
import { useEffect, useRef, useState } from "react";
import { toast } from "sonner";
-import { AspectRatio } from "@/components/ui/aspect-ratio";
import { Button } from "@/components/ui/button";
import { DragOverlay } from "@/components/ui/drag-overlay";
import {
@@ -24,6 +23,7 @@ import { SelectTrigger,
SelectValue,
} from "@/components/ui/select";
+import { DraggableMediaItem } from "@/components/ui/draggable-item";
export function MediaView() {
const { mediaItems, addMediaItem, removeMediaItem } = useMediaStore();
@@ -98,19 +98,6 @@ export function MediaView() { return `${min}:${sec.toString().padStart(2, "0")}`;
};
- const startDrag = (e: React.DragEvent, item: MediaItem) => {
- // When dragging a media item, set drag data for timeline to read
- e.dataTransfer.setData(
- "application/x-media-item",
- JSON.stringify({
- id: item.id,
- type: item.type,
- name: item.name,
- })
- );
- e.dataTransfer.effectAllowed = "copy";
- };
-
const [filteredMediaItems, setFilteredMediaItems] = useState(mediaItems);
useEffect(() => {
@@ -140,7 +127,7 @@ export function MediaView() { <img
src={item.url}
alt={item.name}
- className="max-w-full max-h-full object-contain rounded"
+ className="max-w-full max-h-full object-contain"
loading="lazy"
/>
</div>
@@ -293,45 +280,30 @@ export function MediaView() { >
{/* Render each media item as a draggable button */}
{filteredMediaItems.map((item) => (
- <div key={item.id} className="relative group">
- <ContextMenu>
- <ContextMenuTrigger asChild>
- <Button
- variant="outline"
- className="flex flex-col gap-1 p-2 h-auto w-full relative border-none !bg-transparent cursor-default"
- >
- <AspectRatio
- ratio={16 / 9}
- className="bg-accent"
- draggable={true}
- onDragStart={(e: React.DragEvent) =>
- startDrag(e, item)
- }
- >
- {renderPreview(item)}
- </AspectRatio>
- <span
- className="text-[0.7rem] text-muted-foreground truncate w-full text-left"
- aria-label={item.name}
- title={item.name}
- >
- {item.name.length > 8
- ? `${item.name.slice(0, 4)}...${item.name.slice(-3)}`
- : item.name}
- </span>
- </Button>
- </ContextMenuTrigger>
- <ContextMenuContent>
- <ContextMenuItem>Export clips</ContextMenuItem>
- <ContextMenuItem
- variant="destructive"
- onClick={(e) => handleRemove(e, item.id)}
- >
- Delete
- </ContextMenuItem>
- </ContextMenuContent>
- </ContextMenu>
- </div>
+ <ContextMenu key={item.id}>
+ <ContextMenuTrigger asChild>
+ <DraggableMediaItem
+ name={item.name}
+ preview={renderPreview(item)}
+ dragData={{
+ id: item.id,
+ type: item.type,
+ name: item.name,
+ }}
+ showPlusOnDrag={false}
+ rounded={false}
+ />
+ </ContextMenuTrigger>
+ <ContextMenuContent>
+ <ContextMenuItem>Export clips</ContextMenuItem>
+ <ContextMenuItem
+ variant="destructive"
+ onClick={(e) => handleRemove(e, item.id)}
+ >
+ Delete
+ </ContextMenuItem>
+ </ContextMenuContent>
+ </ContextMenu>
))}
</div>
)}
diff --git a/apps/web/src/components/editor/media-panel/views/text.tsx b/apps/web/src/components/editor/media-panel/views/text.tsx index 9e4f6190..ab698528 100644 --- a/apps/web/src/components/editor/media-panel/views/text.tsx +++ b/apps/web/src/components/editor/media-panel/views/text.tsx @@ -1,11 +1,25 @@ -import { Card } from "@/components/ui/card";
+import { DraggableMediaItem } from "@/components/ui/draggable-item";
export function TextView() {
return (
<div className="p-4">
- <Card className="flex items-center justify-center size-24">
- <span className="text-xs select-none">Default text</span>
- </Card>
+ <DraggableMediaItem
+ name="Default text"
+ preview={
+ <div className="flex items-center justify-center w-full h-full bg-accent rounded">
+ <span className="text-xs select-none">Default text</span>
+ </div>
+ }
+ dragData={{
+ id: "default-text",
+ type: "text",
+ name: "Default text",
+ content: "Default text",
+ }}
+ aspectRatio={1}
+ className="w-24"
+ showLabel={false}
+ />
</div>
);
}
|
