diff options
| author | Simon Orzel <simonorzel@gmail.com> | 2025-07-17 01:59:39 +0200 |
|---|---|---|
| committer | Simon Orzel <simonorzel@gmail.com> | 2025-07-17 01:59:39 +0200 |
| commit | 9fa9f406fe2722cec1e0d65d9b3868acd1e99f87 (patch) | |
| tree | 8d6eebabf99941c970a36dc271da9e9d63128f42 /apps/web/src/components/editor/timeline/timeline-content-click.tsx | |
| parent | 0d2894feda369d518f650ac2c832edb0bb8b9254 (diff) | |
| download | opencut-9fa9f406fe2722cec1e0d65d9b3868acd1e99f87.tar.gz | |
feat: splits working code
Diffstat (limited to 'apps/web/src/components/editor/timeline/timeline-content-click.tsx')
| -rw-r--r-- | apps/web/src/components/editor/timeline/timeline-content-click.tsx | 126 |
1 files changed, 126 insertions, 0 deletions
diff --git a/apps/web/src/components/editor/timeline/timeline-content-click.tsx b/apps/web/src/components/editor/timeline/timeline-content-click.tsx new file mode 100644 index 00000000..9b86effc --- /dev/null +++ b/apps/web/src/components/editor/timeline/timeline-content-click.tsx @@ -0,0 +1,126 @@ +import { useCallback } from "react"; +import { useProjectStore } from "@/stores/project-store"; +import { TIMELINE_CONSTANTS, snapTimeToFrame } from "@/constants/timeline-constants"; + +export interface TimelineContentClickProps { + duration: number; + zoomLevel: number; + seek: (time: number) => void; + rulerScrollRef: React.RefObject<HTMLDivElement>; + tracksScrollRef: React.RefObject<HTMLDivElement>; + clearSelectedElements: () => void; + isSelecting: boolean; + justFinishedSelecting: boolean; + playheadRef: React.RefObject<HTMLDivElement>; +} + +export function useTimelineContentClick({ + duration, + zoomLevel, + seek, + rulerScrollRef, + tracksScrollRef, + clearSelectedElements, + isSelecting, + justFinishedSelecting, + playheadRef, +}: TimelineContentClickProps) { + const { activeProject } = useProjectStore(); + + // Timeline content click to seek handler + const handleTimelineContentClick = useCallback( + (e: React.MouseEvent) => { + console.log( + JSON.stringify({ + timelineClick: { + isSelecting, + justFinishedSelecting, + willReturn: isSelecting || justFinishedSelecting, + }, + }) + ); + + // Don't seek if this was a selection box operation + if (isSelecting || justFinishedSelecting) { + return; + } + + // Don't seek if clicking on timeline elements, but still deselect + if ((e.target as HTMLElement).closest(".timeline-element")) { + return; + } + + // Don't seek if clicking on playhead + if (playheadRef.current?.contains(e.target as Node)) { + return; + } + + // Don't seek if clicking on track labels + if ((e.target as HTMLElement).closest("[data-track-labels]")) { + clearSelectedElements(); + return; + } + + // Clear selected elements when clicking empty timeline area + console.log(JSON.stringify({ clearingSelectedElements: true })); + clearSelectedElements(); + + // Determine if we're clicking in ruler or tracks area + const isRulerClick = (e.target as HTMLElement).closest( + "[data-ruler-area]" + ); + + let mouseX: number; + let scrollLeft = 0; + + if (isRulerClick) { + // Calculate based on ruler position + const rulerContent = rulerScrollRef.current?.querySelector( + "[data-radix-scroll-area-viewport]" + ) as HTMLElement; + if (!rulerContent) return; + const rect = rulerContent.getBoundingClientRect(); + mouseX = e.clientX - rect.left; + scrollLeft = rulerContent.scrollLeft; + } else { + // Calculate based on tracks content position + const tracksContent = tracksScrollRef.current?.querySelector( + "[data-radix-scroll-area-viewport]" + ) as HTMLElement; + if (!tracksContent) return; + const rect = tracksContent.getBoundingClientRect(); + mouseX = e.clientX - rect.left; + scrollLeft = tracksContent.scrollLeft; + } + + const rawTime = Math.max( + 0, + Math.min( + duration, + (mouseX + scrollLeft) / + (TIMELINE_CONSTANTS.PIXELS_PER_SECOND * zoomLevel) + ) + ); + + // Use frame snapping for timeline clicking + const projectFps = activeProject?.fps || 30; + const time = snapTimeToFrame(rawTime, projectFps); + + seek(time); + }, + [ + duration, + zoomLevel, + seek, + rulerScrollRef, + tracksScrollRef, + clearSelectedElements, + isSelecting, + justFinishedSelecting, + playheadRef, + activeProject?.fps, + ] + ); + + return { handleTimelineContentClick }; +} |
