summaryrefslogtreecommitdiff
path: root/apps/web/src/types
diff options
context:
space:
mode:
authorMaze Winther <mazewinther@gmail.com>2025-07-06 20:45:29 +0200
committerMaze Winther <mazewinther@gmail.com>2025-07-06 20:45:29 +0200
commit40c7fbb4f86130c83fbd9029e83c5e7550e3219d (patch)
tree054d918d282358c084f4fc08462913833de644a5 /apps/web/src/types
parent0e32c732ddc335d35e6a7f8547f4af68bfd9c369 (diff)
downloadopencut-40c7fbb4f86130c83fbd9029e83c5e7550e3219d.tar.gz
refactor: move to a typed-tracks system and add support for text
Diffstat (limited to 'apps/web/src/types')
-rw-r--r--apps/web/src/types/timeline.ts73
1 files changed, 66 insertions, 7 deletions
diff --git a/apps/web/src/types/timeline.ts b/apps/web/src/types/timeline.ts
index 54a433a7..daada718 100644
--- a/apps/web/src/types/timeline.ts
+++ b/apps/web/src/types/timeline.ts
@@ -1,20 +1,79 @@
-import { TimelineTrack, TimelineClip } from "@/stores/timeline-store";
+import { MediaType } from "@/stores/media-store";
+import { TimelineTrack } from "@/stores/timeline-store";
-export type TrackType = "video" | "audio" | "effects";
+export type TrackType = "media" | "text" | "audio";
-export interface TimelineClipProps {
- clip: TimelineClip;
+// Base element properties
+interface BaseTimelineElement {
+ id: string;
+ name: string;
+ duration: number;
+ startTime: number;
+ trimStart: number;
+ trimEnd: number;
+}
+
+// Media element that references MediaStore
+export interface MediaElement extends BaseTimelineElement {
+ type: "media";
+ mediaId: string;
+}
+
+// Text element with embedded text data
+export interface TextElement extends BaseTimelineElement {
+ type: "text";
+ content: string;
+ fontSize: number;
+ fontFamily: string;
+ color: string;
+ backgroundColor: string;
+ textAlign: "left" | "center" | "right";
+ fontWeight: "normal" | "bold";
+ fontStyle: "normal" | "italic";
+ textDecoration: "none" | "underline" | "line-through";
+ x: number; // Position relative to canvas center
+ y: number; // Position relative to canvas center
+ rotation: number; // in degrees
+ opacity: number; // 0-1
+}
+
+// Typed timeline elements
+export type TimelineElement = MediaElement | TextElement;
+
+// Creation types (without id, for addElementToTrack)
+export type CreateMediaElement = Omit<MediaElement, "id">;
+export type CreateTextElement = Omit<TextElement, "id">;
+export type CreateTimelineElement = CreateMediaElement | CreateTextElement;
+
+export interface TimelineElementProps {
+ element: TimelineElement;
track: TimelineTrack;
zoomLevel: number;
isSelected: boolean;
- onClipMouseDown: (e: React.MouseEvent, clip: TimelineClip) => void;
- onClipClick: (e: React.MouseEvent, clip: TimelineClip) => void;
+ onElementMouseDown: (e: React.MouseEvent, element: TimelineElement) => void;
+ onElementClick: (e: React.MouseEvent, element: TimelineElement) => void;
}
export interface ResizeState {
- clipId: string;
+ elementId: string;
side: "left" | "right";
startX: number;
initialTrimStart: number;
initialTrimEnd: number;
}
+
+// Drag data types for type-safe drag and drop
+export interface MediaItemDragData {
+ id: string;
+ type: MediaType;
+ name: string;
+}
+
+export interface TextItemDragData {
+ id: string;
+ type: "text";
+ name: string;
+ content: string;
+}
+
+export type DragData = MediaItemDragData | TextItemDragData;