From 2a1ac8fcf7075a4a25523c7601e98013313658c5 Mon Sep 17 00:00:00 2001 From: Andrew Kordampalos Date: Mon, 23 Jun 2025 22:17:36 +0300 Subject: [PATCH 1/3] Implement click-to-seek functionality in timeline --- .gitignore | 3 +++ apps/web/src/app/editor/editor.css | 4 ++++ apps/web/src/app/editor/page.tsx | 1 + apps/web/src/components/editor/timeline.tsx | 19 +++++++++++++++++-- 4 files changed, 25 insertions(+), 2 deletions(-) create mode 100644 apps/web/src/app/editor/editor.css diff --git a/.gitignore b/.gitignore index 24d66f8..3deed24 100644 --- a/.gitignore +++ b/.gitignore @@ -19,3 +19,6 @@ # typescript /apps/web/next-env.d.ts /apps/web/yarn.lock + +# asdf version management +.tool-versions diff --git a/apps/web/src/app/editor/editor.css b/apps/web/src/app/editor/editor.css new file mode 100644 index 0000000..f482c6d --- /dev/null +++ b/apps/web/src/app/editor/editor.css @@ -0,0 +1,4 @@ +/* Prevent scroll jumping on Mac devices when using the editor */ +body { + overflow: hidden; +} \ No newline at end of file diff --git a/apps/web/src/app/editor/page.tsx b/apps/web/src/app/editor/page.tsx index 64186a3..2efb59c 100644 --- a/apps/web/src/app/editor/page.tsx +++ b/apps/web/src/app/editor/page.tsx @@ -1,6 +1,7 @@ "use client"; import { useEffect } from "react"; +import "./editor.css"; import { ResizablePanelGroup, ResizablePanel, diff --git a/apps/web/src/components/editor/timeline.tsx b/apps/web/src/components/editor/timeline.tsx index 675b398..24169b6 100644 --- a/apps/web/src/components/editor/timeline.tsx +++ b/apps/web/src/components/editor/timeline.tsx @@ -290,11 +290,18 @@ export function Timeline() { } }; - // Deselect all clips when clicking empty timeline area + // Deselect all clips when clicking empty timeline area and seek to clicked position const handleTimelineAreaClick = (e: React.MouseEvent) => { // Only clear selection if the click target is the timeline background (not a child/clip) if (e.target === e.currentTarget) { clearSelectedClips(); + + // Calculate the clicked time position and seek to it + const rect = e.currentTarget.getBoundingClientRect(); + const clickX = e.clientX - rect.left; + const clickedTime = clickX / (50 * zoomLevel); + const clampedTime = Math.max(0, Math.min(duration, clickedTime)); + seek(clampedTime); } }; @@ -487,10 +494,18 @@ export function Timeline() {
{ + // Calculate the clicked time position and seek to it + const rect = e.currentTarget.getBoundingClientRect(); + const clickX = e.clientX - rect.left; + const clickedTime = clickX / (50 * zoomLevel); + const clampedTime = Math.max(0, Math.min(duration, clickedTime)); + seek(clampedTime); + }} > {/* Time markers */} {(() => { From 267a590d04c89ad0a74b682d8b575197e1a742fc Mon Sep 17 00:00:00 2001 From: Andrew Kordampalos Date: Mon, 23 Jun 2025 22:32:17 +0300 Subject: [PATCH 2/3] De-duplicate code --- apps/web/src/components/editor/timeline.tsx | 22 ++++++++++----------- 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/apps/web/src/components/editor/timeline.tsx b/apps/web/src/components/editor/timeline.tsx index 24169b6..e2c212d 100644 --- a/apps/web/src/components/editor/timeline.tsx +++ b/apps/web/src/components/editor/timeline.tsx @@ -290,18 +290,20 @@ export function Timeline() { } }; - // Deselect all clips when clicking empty timeline area and seek to clicked position + const handleSeekToPosition = (e: React.MouseEvent) => { + const rect = e.currentTarget.getBoundingClientRect(); + const clickX = e.clientX - rect.left; + const clickedTime = clickX / (50 * zoomLevel); + const clampedTime = Math.max(0, Math.min(duration, clickedTime)); + seek(clampedTime); + }; + const handleTimelineAreaClick = (e: React.MouseEvent) => { - // Only clear selection if the click target is the timeline background (not a child/clip) if (e.target === e.currentTarget) { clearSelectedClips(); // Calculate the clicked time position and seek to it - const rect = e.currentTarget.getBoundingClientRect(); - const clickX = e.clientX - rect.left; - const clickedTime = clickX / (50 * zoomLevel); - const clampedTime = Math.max(0, Math.min(duration, clickedTime)); - seek(clampedTime); + handleSeekToPosition(e); } }; @@ -500,11 +502,7 @@ export function Timeline() { }} onClick={(e) => { // Calculate the clicked time position and seek to it - const rect = e.currentTarget.getBoundingClientRect(); - const clickX = e.clientX - rect.left; - const clickedTime = clickX / (50 * zoomLevel); - const clampedTime = Math.max(0, Math.min(duration, clickedTime)); - seek(clampedTime); + handleSeekToPosition(e); }} > {/* Time markers */} From c7f56d61d776f87607fc02e9f71bb4b8e1a49d98 Mon Sep 17 00:00:00 2001 From: Andrew Kordampalos Date: Mon, 23 Jun 2025 22:41:38 +0300 Subject: [PATCH 3/3] Format --- apps/web/src/components/editor/timeline.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/apps/web/src/components/editor/timeline.tsx b/apps/web/src/components/editor/timeline.tsx index e2c212d..cf6b57e 100644 --- a/apps/web/src/components/editor/timeline.tsx +++ b/apps/web/src/components/editor/timeline.tsx @@ -295,6 +295,7 @@ export function Timeline() { const clickX = e.clientX - rect.left; const clickedTime = clickX / (50 * zoomLevel); const clampedTime = Math.max(0, Math.min(duration, clickedTime)); + seek(clampedTime); };