summaryrefslogtreecommitdiff
path: root/apps/web/src/components/editor/timeline/timeline-content-click.tsx
diff options
context:
space:
mode:
authorSimon Orzel <simonorzel@gmail.com>2025-07-17 01:59:39 +0200
committerSimon Orzel <simonorzel@gmail.com>2025-07-17 01:59:39 +0200
commit9fa9f406fe2722cec1e0d65d9b3868acd1e99f87 (patch)
tree8d6eebabf99941c970a36dc271da9e9d63128f42 /apps/web/src/components/editor/timeline/timeline-content-click.tsx
parent0d2894feda369d518f650ac2c832edb0bb8b9254 (diff)
downloadopencut-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.tsx126
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 };
+}