From be1ae20d9089e81cb84a8294be76fe680a24b60f Mon Sep 17 00:00:00 2001 From: Hyteq Date: Sun, 20 Jul 2025 11:00:22 +0300 Subject: format --- apps/web/src/types/editor.ts | 24 ++--- apps/web/src/types/keybinding.ts | 74 ++++++++++++--- apps/web/src/types/playback.ts | 32 +++---- apps/web/src/types/project.ts | 20 ++--- apps/web/src/types/timeline.ts | 188 +++++++++++++++++++-------------------- 5 files changed, 192 insertions(+), 146 deletions(-) (limited to 'apps/web/src/types') diff --git a/apps/web/src/types/editor.ts b/apps/web/src/types/editor.ts index dce7ac50..d09e1912 100644 --- a/apps/web/src/types/editor.ts +++ b/apps/web/src/types/editor.ts @@ -1,12 +1,12 @@ -export type BackgroundType = "blur" | "mirror" | "color"; - -export interface CanvasSize { - width: number; - height: number; -} - -export interface CanvasPreset { - name: string; - width: number; - height: number; -} +export type BackgroundType = "blur" | "mirror" | "color"; + +export interface CanvasSize { + width: number; + height: number; +} + +export interface CanvasPreset { + name: string; + width: number; + height: number; +} diff --git a/apps/web/src/types/keybinding.ts b/apps/web/src/types/keybinding.ts index d97c88da..c66a04dd 100644 --- a/apps/web/src/types/keybinding.ts +++ b/apps/web/src/types/keybinding.ts @@ -5,23 +5,69 @@ import { ActionWithOptionalArgs } from "@/constants/actions"; * Ctrl is also regarded as macOS COMMAND (⌘) key (NOTE: this differs from HTML Keyboard spec where COMMAND is Meta key!) */ export type ModifierKeys = - | "ctrl" - | "alt" - | "shift" - | "ctrl+shift" - | "alt+shift" - | "ctrl+alt" - | "ctrl+alt+shift"; + | "ctrl" + | "alt" + | "shift" + | "ctrl+shift" + | "alt+shift" + | "ctrl+alt" + | "ctrl+alt+shift"; /* eslint-disable prettier/prettier */ // prettier-ignore export type Key = - | "a" | "b" | "c" | "d" | "e" | "f" | "g" | "h" | "i" | "j" - | "k" | "l" | "m" | "n" | "o" | "p" | "q" | "r" | "s" | "t" - | "u" | "v" | "w" | "x" | "y" | "z" | "0" | "1" | "2" | "3" - | "4" | "5" | "6" | "7" | "8" | "9" | "up" | "down" | "left" - | "right" | "/" | "?" | "." | "enter" | "tab" | "space" - | "escape" | "esc" | "backspace" | "delete" | "home" | "end" + | "a" + | "b" + | "c" + | "d" + | "e" + | "f" + | "g" + | "h" + | "i" + | "j" + | "k" + | "l" + | "m" + | "n" + | "o" + | "p" + | "q" + | "r" + | "s" + | "t" + | "u" + | "v" + | "w" + | "x" + | "y" + | "z" + | "0" + | "1" + | "2" + | "3" + | "4" + | "5" + | "6" + | "7" + | "8" + | "9" + | "up" + | "down" + | "left" + | "right" + | "/" + | "?" + | "." + | "enter" + | "tab" + | "space" + | "escape" + | "esc" + | "backspace" + | "delete" + | "home" + | "end"; /* eslint-enable */ export type ModifierBasedShortcutKey = `${ModifierKeys}+${Key}`; @@ -31,5 +77,5 @@ export type SingleCharacterShortcutKey = `${Key}`; export type ShortcutKey = ModifierBasedShortcutKey | SingleCharacterShortcutKey; export type KeybindingConfig = { - [key in ShortcutKey]?: ActionWithOptionalArgs; + [key in ShortcutKey]?: ActionWithOptionalArgs; }; diff --git a/apps/web/src/types/playback.ts b/apps/web/src/types/playback.ts index 8758ea03..18c1e099 100644 --- a/apps/web/src/types/playback.ts +++ b/apps/web/src/types/playback.ts @@ -1,21 +1,21 @@ export interface PlaybackState { - isPlaying: boolean; - currentTime: number; - duration: number; - volume: number; - speed: number; - muted: boolean; - previousVolume?: number; + isPlaying: boolean; + currentTime: number; + duration: number; + volume: number; + speed: number; + muted: boolean; + previousVolume?: number; } export interface PlaybackControls { - play: () => void; - pause: () => void; - seek: (time: number) => void; - setVolume: (volume: number) => void; - setSpeed: (speed: number) => void; - toggle: () => void; - mute: () => void; - unmute: () => void; - toggleMute: () => void; + play: () => void; + pause: () => void; + seek: (time: number) => void; + setVolume: (volume: number) => void; + setSpeed: (speed: number) => void; + toggle: () => void; + mute: () => void; + unmute: () => void; + toggleMute: () => void; } diff --git a/apps/web/src/types/project.ts b/apps/web/src/types/project.ts index 58d37b03..b3ab1332 100644 --- a/apps/web/src/types/project.ts +++ b/apps/web/src/types/project.ts @@ -1,12 +1,12 @@ export interface TProject { - id: string; - name: string; - thumbnail: string; - createdAt: Date; - updatedAt: Date; - mediaItems?: string[]; - backgroundColor?: string; - backgroundType?: "color" | "blur"; - blurIntensity?: number; // in pixels (4, 8, 18) - fps?: number; + id: string; + name: string; + thumbnail: string; + createdAt: Date; + updatedAt: Date; + mediaItems?: string[]; + backgroundColor?: string; + backgroundType?: "color" | "blur"; + blurIntensity?: number; // in pixels (4, 8, 18) + fps?: number; } diff --git a/apps/web/src/types/timeline.ts b/apps/web/src/types/timeline.ts index 17dbb5d1..e45908d6 100644 --- a/apps/web/src/types/timeline.ts +++ b/apps/web/src/types/timeline.ts @@ -5,36 +5,36 @@ export type TrackType = "media" | "text" | "audio"; // Base element properties interface BaseTimelineElement { - id: string; - name: string; - duration: number; - startTime: number; - trimStart: number; - trimEnd: number; + 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; + 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 + 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 @@ -46,112 +46,112 @@ export type CreateTextElement = Omit; export type CreateTimelineElement = CreateMediaElement | CreateTextElement; export interface TimelineElementProps { - element: TimelineElement; - track: TimelineTrack; - zoomLevel: number; - isSelected: boolean; - onElementMouseDown: (e: React.MouseEvent, element: TimelineElement) => void; - onElementClick: (e: React.MouseEvent, element: TimelineElement) => void; + element: TimelineElement; + track: TimelineTrack; + zoomLevel: number; + isSelected: boolean; + onElementMouseDown: (e: React.MouseEvent, element: TimelineElement) => void; + onElementClick: (e: React.MouseEvent, element: TimelineElement) => void; } export interface ResizeState { - elementId: string; - side: "left" | "right"; - startX: number; - initialTrimStart: number; - initialTrimEnd: number; + 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; + id: string; + type: MediaType; + name: string; } export interface TextItemDragData { - id: string; - type: "text"; - name: string; - content: string; + id: string; + type: "text"; + name: string; + content: string; } export type DragData = MediaItemDragData | TextItemDragData; export interface TimelineTrack { - id: string; - name: string; - type: TrackType; - elements: TimelineElement[]; - muted?: boolean; - isMain?: boolean; + id: string; + name: string; + type: TrackType; + elements: TimelineElement[]; + muted?: boolean; + isMain?: boolean; } export function sortTracksByOrder(tracks: TimelineTrack[]): TimelineTrack[] { - return [...tracks].sort((a, b) => { - // Audio tracks always go to bottom - if (a.type === "audio" && b.type !== "audio") return 1; - if (b.type === "audio" && a.type !== "audio") return -1; - - // Main track goes above audio but below other tracks - if (a.isMain && !b.isMain && b.type !== "audio") return 1; - if (b.isMain && !a.isMain && a.type !== "audio") return -1; - - // Within same category, maintain creation order - return 0; - }); + return [...tracks].sort((a, b) => { + // Audio tracks always go to bottom + if (a.type === "audio" && b.type !== "audio") return 1; + if (b.type === "audio" && a.type !== "audio") return -1; + + // Main track goes above audio but below other tracks + if (a.isMain && !b.isMain && b.type !== "audio") return 1; + if (b.isMain && !a.isMain && a.type !== "audio") return -1; + + // Within same category, maintain creation order + return 0; + }); } export function getMainTrack(tracks: TimelineTrack[]): TimelineTrack | null { - return tracks.find((track) => track.isMain) || null; + return tracks.find((track) => track.isMain) || null; } export function ensureMainTrack(tracks: TimelineTrack[]): TimelineTrack[] { - const hasMainTrack = tracks.some((track) => track.isMain); - - if (!hasMainTrack) { - // Create main track if it doesn't exist - const mainTrack: TimelineTrack = { - id: generateUUID(), - name: "Main Track", - type: "media", - elements: [], - muted: false, - isMain: true, - }; - return [mainTrack, ...tracks]; - } - - return tracks; + const hasMainTrack = tracks.some((track) => track.isMain); + + if (!hasMainTrack) { + // Create main track if it doesn't exist + const mainTrack: TimelineTrack = { + id: generateUUID(), + name: "Main Track", + type: "media", + elements: [], + muted: false, + isMain: true, + }; + return [mainTrack, ...tracks]; + } + + return tracks; } // Timeline validation utilities export function canElementGoOnTrack( - elementType: "text" | "media", - trackType: TrackType + elementType: "text" | "media", + trackType: TrackType, ): boolean { - if (elementType === "text") { - return trackType === "text"; - } else if (elementType === "media") { - return trackType === "media" || trackType === "audio"; - } - return false; + if (elementType === "text") { + return trackType === "text"; + } else if (elementType === "media") { + return trackType === "media" || trackType === "audio"; + } + return false; } export function validateElementTrackCompatibility( - element: { type: "text" | "media" }, - track: { type: TrackType } + element: { type: "text" | "media" }, + track: { type: TrackType }, ): { isValid: boolean; errorMessage?: string } { - const isValid = canElementGoOnTrack(element.type, track.type); + const isValid = canElementGoOnTrack(element.type, track.type); - if (!isValid) { - const errorMessage = - element.type === "text" - ? "Text elements can only be placed on text tracks" - : "Media elements can only be placed on media or audio tracks"; + if (!isValid) { + const errorMessage = + element.type === "text" + ? "Text elements can only be placed on text tracks" + : "Media elements can only be placed on media or audio tracks"; - return { isValid: false, errorMessage }; - } + return { isValid: false, errorMessage }; + } - return { isValid: true }; + return { isValid: true }; } -- cgit v1.3.1