From 3c76a3f241c8d0d00f9aa635bb14728e61296c58 Mon Sep 17 00:00:00 2001 From: leimingsheng Date: Mon, 21 Jul 2025 19:51:11 +0800 Subject: [PATCH] feat: fix some error --- .../src/components/editor/timeline-fixed.tsx | 21 ++++++++++++------- .../src/hooks/use-timeline-zoom-actions.ts | 5 +++-- apps/web/src/hooks/use-timeline-zoom.ts | 2 +- apps/web/src/stores/timeline-store.ts | 7 ++++--- 4 files changed, 22 insertions(+), 13 deletions(-) diff --git a/apps/web/src/components/editor/timeline-fixed.tsx b/apps/web/src/components/editor/timeline-fixed.tsx index 12b7012c..52103bda 100644 --- a/apps/web/src/components/editor/timeline-fixed.tsx +++ b/apps/web/src/components/editor/timeline-fixed.tsx @@ -198,12 +198,11 @@ export function Timeline() { !target.closest("[data-track-labels]"); if (isTimelineBackground) { - const now = Date.now(); mouseTrackingRef.current = { isMouseDown: true, downX: e.clientX, downY: e.clientY, - downTime: now, + downTime: e.timeStamp, }; } }, []); @@ -250,7 +249,8 @@ export function Timeline() { clickX / (TIMELINE_CONSTANTS.PIXELS_PER_SECOND * zoomLevel); // Snap to frame boundary for accurate seeking - const snappedTime = snapTimeToFrame(timeFromClick); + const projectFps = activeProject?.fps || 30; + const snappedTime = snapTimeToFrame(timeFromClick, projectFps); // Seek to the clicked time seek(Math.max(0, snappedTime)); @@ -382,7 +382,11 @@ export function Timeline() { }); for (const media of processedMedia) { - addMediaItem(media); + if (!activeProject) { + toast.error("No active project"); + return; + } + await addMediaItem(activeProject.id, media); // Add to timeline automatically const trackId = crypto.randomUUID(); @@ -517,9 +521,12 @@ export function Timeline() { // --- Scroll synchronization effect --- useEffect(() => { const rulerViewport = rulerScrollRef.current; - const tracksViewport = tracksScrollRef.current?.parentElement; // The container with overflow-auto - const trackLabelsViewport = trackLabelsScrollRef.current?.parentElement; // The container with overflow-y-auto - + const tracksViewport = tracksScrollRef.current?.querySelector( + "[data-radix-scroll-area-viewport]" + ) as HTMLElement; + const trackLabelsViewport = trackLabelsScrollRef.current?.querySelector( + "[data-radix-scroll-area-viewport]" + ) as HTMLElement; if (!rulerViewport || !tracksViewport) return; // Horizontal scroll synchronization between ruler and tracks diff --git a/apps/web/src/hooks/use-timeline-zoom-actions.ts b/apps/web/src/hooks/use-timeline-zoom-actions.ts index 85003684..c6f9c50c 100644 --- a/apps/web/src/hooks/use-timeline-zoom-actions.ts +++ b/apps/web/src/hooks/use-timeline-zoom-actions.ts @@ -1,6 +1,7 @@ "use client"; import { useActionHandler } from "@/constants/actions"; +import { MIN_ZOOM, MAX_ZOOM /*, ZOOM_STEP */ } from "../constants/timeline-constants"; interface UseTimelineZoomActionsProps { zoomLevel: number; @@ -15,12 +16,12 @@ export function useTimelineZoomActions({ }: UseTimelineZoomActionsProps) { // Zoom in action useActionHandler("zoom-in", () => { - setZoomLevel((prev) => Math.min(5, prev + 0.2)); + setZoomLevel((prev) => Math.min(MAX_ZOOM, prev + /*ZOOM_STEP*/ 0.2)); }); // Zoom out action useActionHandler("zoom-out", () => { - setZoomLevel((prev) => Math.max(0.1, prev - 0.2)); + setZoomLevel((prev) => Math.max(MIN_ZOOM, prev - /*ZOOM_STEP*/ 0.2)); }); // Reset zoom action diff --git a/apps/web/src/hooks/use-timeline-zoom.ts b/apps/web/src/hooks/use-timeline-zoom.ts index eca9d44d..1031e4a0 100644 --- a/apps/web/src/hooks/use-timeline-zoom.ts +++ b/apps/web/src/hooks/use-timeline-zoom.ts @@ -87,7 +87,7 @@ export function useTimelineZoom({ document.addEventListener('keydown', handleKeyDown); return () => document.removeEventListener('keydown', handleKeyDown); } - }, [isInTimeline, setZoomLevel]); + }, [isInTimeline, setZoomLevel, onFitToWindow]); // Prevent browser zooming in/out when in timeline useEffect(() => { diff --git a/apps/web/src/stores/timeline-store.ts b/apps/web/src/stores/timeline-store.ts index 89a81942..f21a4d57 100644 --- a/apps/web/src/stores/timeline-store.ts +++ b/apps/web/src/stores/timeline-store.ts @@ -1169,12 +1169,13 @@ export const useTimelineStore = create((set, get) => { if (totalDuration === 0) return 1; // Leave some padding (10% on each side) - const availableWidth = containerWidth * 0.8; + const CONTAINER_PADDING_FACTOR = 0.8; + const availableWidth = containerWidth * CONTAINER_PADDING_FACTOR; const requiredWidth = totalDuration * TIMELINE_CONSTANTS.PIXELS_PER_SECOND; const calculatedZoom = availableWidth / requiredWidth; - // Clamp between min and max zoom levels (0.3 to 5) - return Math.max(0.5, Math.min(5, calculatedZoom)); + // Clamp between min and max zoom levels + return Math.max(TIMELINE_CONSTANTS.MIN_ZOOM, Math.min(TIMELINE_CONSTANTS.MAX_ZOOM, calculatedZoom)); }, redo: () => {