refactor: improved type-safety, removal of any from all instances

This commit is contained in:
Maze Winther
2025-06-25 21:40:54 +02:00
parent 926aebe004
commit 777b0f7000
8 changed files with 43 additions and 30 deletions

View File

@ -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;

View File

@ -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 = {

View File

@ -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

View File

@ -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" />

View File

@ -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

View File

@ -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;
} }

View File

@ -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

View File

@ -0,0 +1 @@
export type BackgroundType = "blur" | "mirror" | "color";