Skip to content

feat: add timeline zoom in/out controls#510

Open
ai-linor wants to merge 2 commits into
webadderallorg:mainfrom
ai-linor:feat/timeline-zoom
Open

feat: add timeline zoom in/out controls#510
ai-linor wants to merge 2 commits into
webadderallorg:mainfrom
ai-linor:feat/timeline-zoom

Conversation

@ai-linor
Copy link
Copy Markdown

@ai-linor ai-linor commented May 13, 2026

Closes #495 by adding timeline zoom in/out controls to the editor toolbar.

Summary by CodeRabbit

  • New Features
    • Added Zoom In and Zoom Out controls to the timeline toolbar for finer or broader editing views.
    • Timeline zoom preserves the current center and enforces sensible minimum/maximum limits for stable, predictable zooming.
    • Zoom controls are exposed to timeline editing tools for direct invocation (e.g., toolbar buttons and runtime handlers).

Review Change Stack

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 13, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: befc2906-25c8-4283-bcd2-9e83837d47b3

📥 Commits

Reviewing files that changed from the base of the PR and between bc3a847 and f09709d.

📒 Files selected for processing (1)
  • src/components/video-editor/timeline/TimelineEditor.tsx

📝 Walkthrough

Walkthrough

Adds timeline zoom math and helpers in the range hook, exposes zoomIn/zoomOut through the editor runtime handle, wires them into TimelineEditor, and adds toolbar zoom buttons in VideoEditor that call the runtime methods.

Changes

Timeline Zoom Controls

Layer / File(s) Summary
Timeline range hook with zoom logic
src/components/video-editor/timeline/hooks/useTimelineRange.ts
useTimelineRange adds zoomTimelineRange, zoomIn, and zoomOut, preserves center when scaling, enforces min/max span, clamps to [0, totalMs], and exposes zoom helpers alongside range, setRange, clampedRange, and handleTimelineWheel.
Imperative handle exposure
src/components/video-editor/timeline/hooks/useTimelineEditorRuntime.ts
UseTimelineEditorRuntimeParams now accepts zoomIn and zoomOut; the hook includes them in the useImperativeHandle return value and dependency array.
TimelineEditor component wiring
src/components/video-editor/timeline/TimelineEditor.tsx
TimelineEditorHandle interface adds zoomIn/zoomOut; TimelineEditor destructures zoomIn and zoomOut from useTimelineRange so the runtime/component can call them.
Timeline toolbar zoom buttons
src/components/video-editor/VideoEditor.tsx
Imports MagnifyingGlassMinus as ZoomOut and adds toolbar buttons wired to timelineRef.current?.zoomOut() and timelineRef.current?.zoomIn(), rendering icons and tooltip titles.

Sequence Diagram

sequenceDiagram
  participant VideoEditor
  participant TimelineRuntime
  participant TimelineEditor
  participant useTimelineRange
  VideoEditor->>TimelineRuntime: call timelineRef.current?.zoomIn()/zoomOut()
  TimelineRuntime->>TimelineEditor: runtime invokes zoomIn()/zoomOut()
  TimelineEditor->>useTimelineRange: zoomIn()/zoomOut() handlers
  useTimelineRange->>useTimelineRange: recompute range (scale, preserve center, clamp)
  useTimelineRange->>TimelineEditor: updated clampedRange/range
  TimelineEditor->>VideoEditor: UI reflects new timeline zoom
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Suggested labels

Checked

Poem

🐰 I nudged the timeline, hopped to the center line,
Pressed zoom in then out, kept everything aligned.
Bounds stayed tidy, frames in ordered rows,
The editor stretched and hugged the view like a rose.
A little rabbit cheer — new zoom for smoother shows. 🥕

🚥 Pre-merge checks | ✅ 2 | ❌ 3

❌ Failed checks (3 warnings)

Check name Status Explanation Resolution
Description check ⚠️ Warning The description is minimal but mentions closing issue #495. However, it lacks required template sections like Motivation, Type of Change, Testing Guide, and Screenshots/Video. Expand description to follow the template: add Motivation, check Type of Change, include Testing Guide, and add screenshots or video demonstrating the zoom controls functionality.
Linked Issues check ⚠️ Warning The PR wires zoom controls into the toolbar and runtime but does not address the core issue: zoom not affecting clips/audio clips or resolving the scrollbar inconsistency mentioned in #495. Verify that the zoom changes affect all timeline elements (clips, audio clips, cursors) uniformly and that the custom scrollbar behavior is implemented, not just add UI controls.
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely describes the main feature addition: zoom in/out controls for the timeline, which is the primary focus of this changeset.
Out of Scope Changes check ✅ Passed All changes are scoped to adding zoom controls: UI button imports, toolbar button additions, and runtime wiring. No unrelated modifications were introduced.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Tip

💬 Introducing Slack Agent: The best way for teams to turn conversations into code.

Slack Agent is built on CodeRabbit's deep understanding of your code, so your team can collaborate across the entire SDLC without losing context.

  • Generate code and open pull requests
  • Plan features and break down work
  • Investigate incidents and troubleshoot customer tickets together
  • Automate recurring tasks and respond to alerts with triggers
  • Summarize progress and report instantly

Built for teams:

  • Shared memory across your entire org—no repeating context
  • Per-thread sandboxes to safely plan and execute work
  • Governance built-in—scoped access, auditability, and budget controls

One agent for your entire SDLC. Right inside Slack.

👉 Get started


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/components/video-editor/timeline/TimelineEditor.tsx (1)

193-376: ⚠️ Potential issue | 🔴 Critical | ⚡ Quick win

Pass zoomIn and zoomOut into useTimelineEditorRuntime.

zoomIn and zoomOut are created via useTimelineRange on line 193 but not forwarded to the useTimelineEditorRuntime call. The hook interface requires both callbacks; they cannot be omitted without breaking the ref contract for timeline zoom controls.

Suggested fix
 		} = useTimelineEditorRuntime({
 			ref,
 			videoDuration,
 			totalMs,
@@
 			keyShortcuts,
 			isTimelineFocusedRef,
+			zoomIn,
+			zoomOut,
 		});
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/components/video-editor/timeline/TimelineEditor.tsx` around lines 193 -
376, The hook outputs zoomIn and zoomOut from useTimelineRange but they are not
passed into useTimelineEditorRuntime; update the call to
useTimelineEditorRuntime to include zoomIn and zoomOut in its argument object
(alongside existing props like ref, videoDuration, totalMs, etc.) so the runtime
hook receives the callbacks (ensure the property names match the hook's expected
params and types).
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@src/components/video-editor/timeline/TimelineEditor.tsx`:
- Around line 193-376: The hook outputs zoomIn and zoomOut from useTimelineRange
but they are not passed into useTimelineEditorRuntime; update the call to
useTimelineEditorRuntime to include zoomIn and zoomOut in its argument object
(alongside existing props like ref, videoDuration, totalMs, etc.) so the runtime
hook receives the callbacks (ensure the property names match the hook's expected
params and types).

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 1bc08b4f-b086-47c5-9f40-629db2d761cd

📥 Commits

Reviewing files that changed from the base of the PR and between 7bc06c9 and b79d6dd.

📒 Files selected for processing (4)
  • src/components/video-editor/VideoEditor.tsx
  • src/components/video-editor/timeline/TimelineEditor.tsx
  • src/components/video-editor/timeline/hooks/useTimelineEditorRuntime.ts
  • src/components/video-editor/timeline/hooks/useTimelineRange.ts

@ai-linor ai-linor force-pushed the feat/timeline-zoom branch from b79d6dd to bc3a847 Compare May 13, 2026 09:32
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/components/video-editor/timeline/TimelineEditor.tsx (1)

334-376: ⚠️ Potential issue | 🔴 Critical | ⚡ Quick win

Pass zoomIn and zoomOut to useTimelineEditorRuntime — imperative handle methods are undefined.

zoomIn and zoomOut are destructured from useTimelineRange at line 193 and declared in the TimelineEditorHandle interface, but they're not passed into the useTimelineEditorRuntime({...}) call. Since the runtime hook includes these methods in its useImperativeHandle return value, omitting them here means timelineRef.current.zoomIn and timelineRef.current.zoomOut will be undefined. The toolbar buttons calling these methods will silently no-op, and the Biome noUnusedVariables errors at line 193 confirm the leak.

Proposed fix
 		} = useTimelineEditorRuntime({
 			ref,
 			videoDuration,
 			totalMs,
 			currentTimeMs,
 			safeMinDurationMs,
 			cursorTelemetry,
 			autoSuggestZoomsTrigger,
 			onAutoSuggestZoomsConsumed,
 			disableSuggestedZooms,
 			zoomRegions,
 			onZoomAdded,
 			onZoomSuggested,
 			onZoomSpanChange,
 			onZoomDelete,
 			selectedZoomId,
 			onSelectZoom,
 			trimRegions,
 			onTrimSpanChange,
 			clipRegions,
 			onClipSplit,
 			onClipSpanChange,
 			onClipDelete,
 			selectedClipId,
 			onSelectClip,
 			annotationRegions,
 			onAnnotationAdded,
 			onAnnotationSpanChange,
 			onAnnotationDelete,
 			selectedAnnotationId,
 			onSelectAnnotation,
 			speedRegions,
 			onSpeedSpanChange,
 			audioRegions,
 			onAudioAdded,
 			onAudioSpanChange,
 			onAudioDelete,
 			selectedAudioId,
 			onSelectAudio,
 			isMac,
 			keyShortcuts,
 			isTimelineFocusedRef,
+			zoomIn,
+			zoomOut,
 		});
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/components/video-editor/timeline/TimelineEditor.tsx` around lines 334 -
376, The runtime hook call to useTimelineEditorRuntime is missing the zoomIn and
zoomOut functions (which are destructured from useTimelineRange and expected by
the TimelineEditorHandle), so timelineRef.current.zoomIn/zoomOut end up
undefined; fix this by including zoomIn and zoomOut in the object passed into
useTimelineEditorRuntime so the hook can wire them into its useImperativeHandle
return (ensure the properties are named zoomIn and zoomOut to match the
TimelineEditorHandle and toolbar callers).
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@src/components/video-editor/timeline/TimelineEditor.tsx`:
- Around line 334-376: The runtime hook call to useTimelineEditorRuntime is
missing the zoomIn and zoomOut functions (which are destructured from
useTimelineRange and expected by the TimelineEditorHandle), so
timelineRef.current.zoomIn/zoomOut end up undefined; fix this by including
zoomIn and zoomOut in the object passed into useTimelineEditorRuntime so the
hook can wire them into its useImperativeHandle return (ensure the properties
are named zoomIn and zoomOut to match the TimelineEditorHandle and toolbar
callers).

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 1b385556-ed23-4962-a8b3-f95ae52691d7

📥 Commits

Reviewing files that changed from the base of the PR and between b79d6dd and bc3a847.

📒 Files selected for processing (4)
  • src/components/video-editor/VideoEditor.tsx
  • src/components/video-editor/timeline/TimelineEditor.tsx
  • src/components/video-editor/timeline/hooks/useTimelineEditorRuntime.ts
  • src/components/video-editor/timeline/hooks/useTimelineRange.ts
🚧 Files skipped from review as they are similar to previous changes (3)
  • src/components/video-editor/timeline/hooks/useTimelineRange.ts
  • src/components/video-editor/VideoEditor.tsx
  • src/components/video-editor/timeline/hooks/useTimelineEditorRuntime.ts

@ExtraBinoss
Copy link
Copy Markdown
Collaborator

Hello, thanks for taking care of that feature !

Can you please link a video (edit your PR) so that we can see it in action ? please !
Looks good otherwise!

@ai-linor
Copy link
Copy Markdown
Author

Hello, thanks for taking care of that feature !

Can you please link a video (edit your PR) so that we can see it in action ? please ! Looks good otherwise!

Yeah I'll see.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Timeline zoom don't affect clip or audio clips.

2 participants