refactor: improved type-safety, removal of any from all instances
This commit is contained in:
@ -49,7 +49,7 @@ async function getContributors(): Promise<Contributor[]> {
|
|||||||
const contributors = await response.json();
|
const contributors = await response.json();
|
||||||
|
|
||||||
const filteredContributors = contributors.filter(
|
const filteredContributors = contributors.filter(
|
||||||
(contributor: any) => contributor.type === "User"
|
(contributor: Contributor) => contributor.type === "User"
|
||||||
);
|
);
|
||||||
|
|
||||||
return filteredContributors;
|
return filteredContributors;
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
import { Button } from "../ui/button";
|
import { Button } from "../ui/button";
|
||||||
import { AspectRatio } from "../ui/aspect-ratio";
|
import { AspectRatio } from "../ui/aspect-ratio";
|
||||||
import { DragOverlay } from "../ui/drag-overlay";
|
import { DragOverlay } from "../ui/drag-overlay";
|
||||||
import { useMediaStore } from "@/stores/media-store";
|
import { useMediaStore, type MediaItem } from "@/stores/media-store";
|
||||||
import { processMediaFiles } from "@/lib/media-processing";
|
import { processMediaFiles } from "@/lib/media-processing";
|
||||||
import { Plus, Image, Video, Music, Trash2, Upload } from "lucide-react";
|
import { Plus, Image, Video, Music, Trash2, Upload } from "lucide-react";
|
||||||
import { useDragDrop } from "@/hooks/use-drag-drop";
|
import { useDragDrop } from "@/hooks/use-drag-drop";
|
||||||
@ -68,7 +68,7 @@ export function MediaPanel() {
|
|||||||
return `${min}:${sec.toString().padStart(2, "0")}`;
|
return `${min}:${sec.toString().padStart(2, "0")}`;
|
||||||
};
|
};
|
||||||
|
|
||||||
const startDrag = (e: React.DragEvent, item: any) => {
|
const startDrag = (e: React.DragEvent, item: MediaItem) => {
|
||||||
// When dragging a media item, set drag data for timeline to read
|
// When dragging a media item, set drag data for timeline to read
|
||||||
e.dataTransfer.setData(
|
e.dataTransfer.setData(
|
||||||
"application/x-media-item",
|
"application/x-media-item",
|
||||||
@ -102,7 +102,7 @@ export function MediaPanel() {
|
|||||||
setFilteredMediaItems(filtered);
|
setFilteredMediaItems(filtered);
|
||||||
}, [mediaItems, mediaFilter, searchQuery]);
|
}, [mediaItems, mediaFilter, searchQuery]);
|
||||||
|
|
||||||
const renderPreview = (item: any) => {
|
const renderPreview = (item: MediaItem) => {
|
||||||
// Render a preview for each media type (image, video, audio, unknown)
|
// Render a preview for each media type (image, video, audio, unknown)
|
||||||
// Each preview is draggable to the timeline
|
// Each preview is draggable to the timeline
|
||||||
const baseDragProps = {
|
const baseDragProps = {
|
||||||
|
@ -1,7 +1,11 @@
|
|||||||
"use client";
|
"use client";
|
||||||
|
|
||||||
import { useTimelineStore } from "@/stores/timeline-store";
|
import {
|
||||||
import { useMediaStore } from "@/stores/media-store";
|
useTimelineStore,
|
||||||
|
type TimelineClip,
|
||||||
|
type TimelineTrack,
|
||||||
|
} from "@/stores/timeline-store";
|
||||||
|
import { useMediaStore, type MediaItem } from "@/stores/media-store";
|
||||||
import { usePlaybackStore } from "@/stores/playback-store";
|
import { usePlaybackStore } from "@/stores/playback-store";
|
||||||
import { VideoPlayer } from "@/components/ui/video-player";
|
import { VideoPlayer } from "@/components/ui/video-player";
|
||||||
import { Button } from "@/components/ui/button";
|
import { Button } from "@/components/ui/button";
|
||||||
@ -11,6 +15,12 @@ import { useState, useRef } from "react";
|
|||||||
// Debug flag - set to false to hide active clips info
|
// Debug flag - set to false to hide active clips info
|
||||||
const SHOW_DEBUG_INFO = process.env.NODE_ENV === "development";
|
const SHOW_DEBUG_INFO = process.env.NODE_ENV === "development";
|
||||||
|
|
||||||
|
interface ActiveClip {
|
||||||
|
clip: TimelineClip;
|
||||||
|
track: TimelineTrack;
|
||||||
|
mediaItem: MediaItem | null;
|
||||||
|
}
|
||||||
|
|
||||||
export function PreviewPanel() {
|
export function PreviewPanel() {
|
||||||
const { tracks } = useTimelineStore();
|
const { tracks } = useTimelineStore();
|
||||||
const { mediaItems } = useMediaStore();
|
const { mediaItems } = useMediaStore();
|
||||||
@ -21,12 +31,8 @@ export function PreviewPanel() {
|
|||||||
const previewRef = useRef<HTMLDivElement>(null);
|
const previewRef = useRef<HTMLDivElement>(null);
|
||||||
|
|
||||||
// Get active clips at current time
|
// Get active clips at current time
|
||||||
const getActiveClips = () => {
|
const getActiveClips = (): ActiveClip[] => {
|
||||||
const activeClips: Array<{
|
const activeClips: ActiveClip[] = [];
|
||||||
clip: any;
|
|
||||||
track: any;
|
|
||||||
mediaItem: any;
|
|
||||||
}> = [];
|
|
||||||
|
|
||||||
tracks.forEach((track) => {
|
tracks.forEach((track) => {
|
||||||
track.clips.forEach((clip) => {
|
track.clips.forEach((clip) => {
|
||||||
@ -37,12 +43,10 @@ export function PreviewPanel() {
|
|||||||
if (currentTime >= clipStart && currentTime < clipEnd) {
|
if (currentTime >= clipStart && currentTime < clipEnd) {
|
||||||
const mediaItem =
|
const mediaItem =
|
||||||
clip.mediaId === "test"
|
clip.mediaId === "test"
|
||||||
? { type: "test", name: clip.name, url: "", thumbnailUrl: "" }
|
? null // Test clips don't have a real media item
|
||||||
: mediaItems.find((item) => item.id === clip.mediaId);
|
: mediaItems.find((item) => item.id === clip.mediaId) || null;
|
||||||
|
|
||||||
if (mediaItem || clip.mediaId === "test") {
|
activeClips.push({ clip, track, mediaItem });
|
||||||
activeClips.push({ clip, track, mediaItem });
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@ -54,7 +58,7 @@ export function PreviewPanel() {
|
|||||||
const aspectRatio = canvasSize.width / canvasSize.height;
|
const aspectRatio = canvasSize.width / canvasSize.height;
|
||||||
|
|
||||||
// Render a clip
|
// Render a clip
|
||||||
const renderClip = (clipData: any, index: number) => {
|
const renderClip = (clipData: ActiveClip, index: number) => {
|
||||||
const { clip, mediaItem } = clipData;
|
const { clip, mediaItem } = clipData;
|
||||||
|
|
||||||
// Test clips
|
// Test clips
|
||||||
|
@ -17,13 +17,12 @@ import { useMediaStore } from "@/stores/media-store";
|
|||||||
import { ImageTimelineTreatment } from "@/components/ui/image-timeline-treatment";
|
import { ImageTimelineTreatment } from "@/components/ui/image-timeline-treatment";
|
||||||
import { useState } from "react";
|
import { useState } from "react";
|
||||||
import { SpeedControl } from "./speed-control";
|
import { SpeedControl } from "./speed-control";
|
||||||
|
import type { BackgroundType } from "@/types/editor";
|
||||||
|
|
||||||
export function PropertiesPanel() {
|
export function PropertiesPanel() {
|
||||||
const { tracks } = useTimelineStore();
|
const { tracks } = useTimelineStore();
|
||||||
const { mediaItems } = useMediaStore();
|
const { mediaItems } = useMediaStore();
|
||||||
const [backgroundType, setBackgroundType] = useState<
|
const [backgroundType, setBackgroundType] = useState<BackgroundType>("blur");
|
||||||
"blur" | "mirror" | "color"
|
|
||||||
>("blur");
|
|
||||||
const [backgroundColor, setBackgroundColor] = useState("#000000");
|
const [backgroundColor, setBackgroundColor] = useState("#000000");
|
||||||
|
|
||||||
// Get the first video clip for preview (simplified)
|
// Get the first video clip for preview (simplified)
|
||||||
@ -78,7 +77,9 @@ export function PropertiesPanel() {
|
|||||||
<Label htmlFor="bg-type">Background Type</Label>
|
<Label htmlFor="bg-type">Background Type</Label>
|
||||||
<Select
|
<Select
|
||||||
value={backgroundType}
|
value={backgroundType}
|
||||||
onValueChange={(value: any) => setBackgroundType(value)}
|
onValueChange={(value: BackgroundType) =>
|
||||||
|
setBackgroundType(value)
|
||||||
|
}
|
||||||
>
|
>
|
||||||
<SelectTrigger>
|
<SelectTrigger>
|
||||||
<SelectValue placeholder="Select background type" />
|
<SelectValue placeholder="Select background type" />
|
||||||
|
@ -22,7 +22,11 @@ import {
|
|||||||
TooltipTrigger,
|
TooltipTrigger,
|
||||||
TooltipProvider,
|
TooltipProvider,
|
||||||
} from "../ui/tooltip";
|
} from "../ui/tooltip";
|
||||||
import { useTimelineStore, type TimelineTrack } from "@/stores/timeline-store";
|
import {
|
||||||
|
useTimelineStore,
|
||||||
|
type TimelineTrack,
|
||||||
|
type TimelineClip,
|
||||||
|
} from "@/stores/timeline-store";
|
||||||
import { useMediaStore } from "@/stores/media-store";
|
import { useMediaStore } from "@/stores/media-store";
|
||||||
import { usePlaybackStore } from "@/stores/playback-store";
|
import { usePlaybackStore } from "@/stores/playback-store";
|
||||||
import { useDragClip } from "@/hooks/use-drag-clip";
|
import { useDragClip } from "@/hooks/use-drag-clip";
|
||||||
@ -1253,7 +1257,7 @@ function TimelineTrackContent({
|
|||||||
|
|
||||||
const [justFinishedDrag, setJustFinishedDrag] = useState(false);
|
const [justFinishedDrag, setJustFinishedDrag] = useState(false);
|
||||||
|
|
||||||
const handleClipMouseDown = (e: React.MouseEvent, clip: any) => {
|
const handleClipMouseDown = (e: React.MouseEvent, clip: TimelineClip) => {
|
||||||
// Handle selection first
|
// Handle selection first
|
||||||
if (!justFinishedDrag) {
|
if (!justFinishedDrag) {
|
||||||
const isSelected = selectedClips.some(
|
const isSelected = selectedClips.some(
|
||||||
@ -1374,7 +1378,7 @@ function TimelineTrackContent({
|
|||||||
(t: TimelineTrack) => t.id === fromTrackId
|
(t: TimelineTrack) => t.id === fromTrackId
|
||||||
);
|
);
|
||||||
const movingClip = sourceTrack?.clips.find(
|
const movingClip = sourceTrack?.clips.find(
|
||||||
(c: any) => c.id === clipId
|
(c: TimelineClip) => c.id === clipId
|
||||||
);
|
);
|
||||||
|
|
||||||
if (movingClip) {
|
if (movingClip) {
|
||||||
@ -1499,7 +1503,9 @@ function TimelineTrackContent({
|
|||||||
const sourceTrack = tracks.find(
|
const sourceTrack = tracks.find(
|
||||||
(t: TimelineTrack) => t.id === fromTrackId
|
(t: TimelineTrack) => t.id === fromTrackId
|
||||||
);
|
);
|
||||||
const movingClip = sourceTrack?.clips.find((c: any) => c.id === clipId);
|
const movingClip = sourceTrack?.clips.find(
|
||||||
|
(c: TimelineClip) => c.id === clipId
|
||||||
|
);
|
||||||
|
|
||||||
if (!movingClip) {
|
if (!movingClip) {
|
||||||
toast.error("Clip not found");
|
toast.error("Clip not found");
|
||||||
@ -1629,7 +1635,7 @@ function TimelineTrackContent({
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const renderClipContent = (clip: any) => {
|
const renderClipContent = (clip: TimelineClip) => {
|
||||||
const mediaItem = mediaItems.find((item) => item.id === clip.mediaId);
|
const mediaItem = mediaItems.find((item) => item.id === clip.mediaId);
|
||||||
|
|
||||||
if (!mediaItem) {
|
if (!mediaItem) {
|
||||||
@ -1689,7 +1695,7 @@ function TimelineTrackContent({
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleSplitClip = (clip: any) => {
|
const handleSplitClip = (clip: TimelineClip) => {
|
||||||
// Use current playback time as split point
|
// Use current playback time as split point
|
||||||
const splitTime = currentTime;
|
const splitTime = currentTime;
|
||||||
// Only split if splitTime is within the clip's effective range
|
// Only split if splitTime is within the clip's effective range
|
||||||
|
@ -2,13 +2,14 @@
|
|||||||
|
|
||||||
import { useState } from "react";
|
import { useState } from "react";
|
||||||
import { cn } from "@/lib/utils";
|
import { cn } from "@/lib/utils";
|
||||||
|
import type { BackgroundType } from "@/types/editor";
|
||||||
|
|
||||||
interface ImageTimelineTreatmentProps {
|
interface ImageTimelineTreatmentProps {
|
||||||
src: string;
|
src: string;
|
||||||
alt: string;
|
alt: string;
|
||||||
targetAspectRatio?: number; // Default to 16:9 for video
|
targetAspectRatio?: number; // Default to 16:9 for video
|
||||||
className?: string;
|
className?: string;
|
||||||
backgroundType?: "blur" | "mirror" | "color";
|
backgroundType?: BackgroundType;
|
||||||
backgroundColor?: string;
|
backgroundColor?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8,7 +8,7 @@ interface PlaybackStore extends PlaybackState, PlaybackControls {
|
|||||||
|
|
||||||
let playbackTimer: number | null = null;
|
let playbackTimer: number | null = null;
|
||||||
|
|
||||||
const startTimer = (store: any) => {
|
const startTimer = (store: () => PlaybackStore) => {
|
||||||
if (playbackTimer) cancelAnimationFrame(playbackTimer);
|
if (playbackTimer) cancelAnimationFrame(playbackTimer);
|
||||||
|
|
||||||
// Use requestAnimationFrame for smoother updates
|
// Use requestAnimationFrame for smoother updates
|
||||||
|
1
apps/web/src/types/editor.ts
Normal file
1
apps/web/src/types/editor.ts
Normal file
@ -0,0 +1 @@
|
|||||||
|
export type BackgroundType = "blur" | "mirror" | "color";
|
Reference in New Issue
Block a user