Skip to content

Improve timeline navigation while scrubbing and scrolling#243

Merged
siddharthvaddem merged 2 commits intosiddharthvaddem:mainfrom
ryujh030820:feature/improve-timeline-navigation
Mar 21, 2026
Merged

Improve timeline navigation while scrubbing and scrolling#243
siddharthvaddem merged 2 commits intosiddharthvaddem:mainfrom
ryujh030820:feature/improve-timeline-navigation

Conversation

@ryujh030820
Copy link
Contributor

@ryujh030820 ryujh030820 commented Mar 20, 2026

Description

Improve timeline navigation in the editor by adding:

  • edge panning while dragging the playhead
  • viewport panning when scrolling over timeline rows without moving the playhead

Motivation

Editing longer recordings was awkward because the visible timeline range could not be moved naturally during common interactions. Dragging the playhead to either edge stopped at the current viewport, and row scrolling did not let users inspect nearby time ranges while keeping the playhead fixed.

Type of Change

  • New Feature
  • Bug Fix
  • Refactor / Code Cleanup
  • Documentation Update
  • Other (please specify)

Related Issue(s)

#242

Screenshots / Video

Video (if applicable):

Screen.Recording.2026-03-20.at.4.53.42.PM.mov

Testing

  1. Open the editor with a video long enough to zoom and pan.
  2. Zoom into the timeline.
  3. Drag the playhead to the left or right edge and confirm the timeline continues panning in that direction.
  4. Scroll over the timeline rows and confirm the viewport moves while the playhead time stays unchanged.
  5. Confirm panning does not move beyond the start or end of the video.

Commands used:

  npm exec tsc --noEmit
  ./node_modules/.bin/biome check src/components/video-editor/timeline/TimelineEditor.tsx

Checklist

  • I have performed a self-review of my code.
  • I have added any necessary screenshots or videos.
  • I have linked related issue(s) and updated the changelog if applicable.

Thank you for contributing!

Summary by CodeRabbit

  • New Features
    • Timeline panning via cursor drag: Dragging the playhead beyond visible bounds now pans the timeline automatically.
    • Wheel scrolling: Use scroll wheel to pan the timeline view (simplified from previous Shift + Ctrl + Scroll).
    • Improved cursor preview: Playhead position updates in real-time during dragging operations.

@coderabbitai
Copy link

coderabbitai bot commented Mar 20, 2026

📝 Walkthrough

Walkthrough

This PR enhances the timeline editor component with pan-on-wheel and pan-on-drag functionality. It adds helper functions for range clamping and wheel delta normalization, extends PlaybackCursor and Timeline with an onRangeChange callback prop, implements wheel event handling for timeline panning, and enables cursor dragging to shift the visible timeline range.

Changes

Cohort / File(s) Summary
Timeline Panning Infrastructure
src/components/video-editor/timeline/TimelineEditor.tsx
Added clampVisibleRange helper to keep visible range within video bounds and normalizeWheelDelta to convert wheel deltas to pixel-equivalent values. Both functions support range constraint logic.
PlaybackCursor Range Shifting
src/components/video-editor/timeline/TimelineEditor.tsx
Extended with optional onRangeChange callback prop and internal dragPreviewTimeMs state. During cursor drag, when pointer moves beyond timeline bounds, invokes onRangeChange to pan the visible range while maintaining span.
Timeline Wheel Panning
src/components/video-editor/timeline/TimelineEditor.tsx
Extended with optional onRangeChange callback prop and onWheel event handler. When callback is provided and Ctrl/Meta not held, wheel events pan the visible range by a time shift derived from normalized delta, with default behavior prevented.
TimelineEditor Integration & Label Updates
src/components/video-editor/timeline/TimelineEditor.tsx
Updated to pass onRangeChange={setRange} into Timeline to enable pan-on-wheel and pan-on-drag functionality. Simplified scroll label text from "Shift + Ctrl + Scroll" to "Scroll".

Sequence Diagrams

sequenceDiagram
    actor User
    participant PlaybackCursor
    participant TimelineEditor
    
    User->>PlaybackCursor: Drag cursor beyond bounds
    PlaybackCursor->>PlaybackCursor: Update dragPreviewTimeMs
    PlaybackCursor->>TimelineEditor: onRangeChange(updater)
    TimelineEditor->>TimelineEditor: setRange(clampVisibleRange(updater))
    TimelineEditor->>PlaybackCursor: Re-render with new range
    PlaybackCursor->>User: Display updated preview time
Loading
sequenceDiagram
    actor User
    participant Timeline
    participant TimelineEditor
    
    User->>Timeline: Scroll wheel (without Ctrl/Meta)
    Timeline->>Timeline: normalizeWheelDelta(wheelEvent)
    Timeline->>Timeline: Detect dominant axis
    Timeline->>Timeline: Calculate timeShift
    Timeline->>TimelineEditor: onRangeChange(updater)
    TimelineEditor->>TimelineEditor: setRange(clampVisibleRange(updater))
    TimelineEditor->>Timeline: Re-render with panned range
    Timeline->>User: Display shifted timeline
Loading

Estimated Code Review Effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly Related Issues

Poem

🐰 A cursor dances, dragging wide,
The timeline slides from side to side,
With wheel and grace, the view will pan,
No range too vast for this swift plan! ✨📹

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
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 accurately and concisely summarizes the main changes: improving timeline navigation during scrubbing (dragging playhead) and scrolling.
Description check ✅ Passed The PR description follows the required template structure with all major sections completed, including description, motivation, type of change, related issues, video demonstration, testing instructions, and checklist.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
📝 Coding Plan
  • Generate coding plan for human review comments

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

Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 203282be43

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Copy link

@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.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/components/video-editor/timeline/TimelineEditor.tsx`:
- Around line 279-314: The current pan logic only reacts to incoming mousemove
events and stops when the pointer is held at the edge; instead implement an
animation-driven pan loop: create a small edge threshold (e.g.
EDGE_THRESHOLD_PX) and store the latest pointer X (clickX / pointerX) during
pointermove/drag start, then start a requestAnimationFrame loop on drag start
that computes visibleMs, msPerPixel, overflow (using threshold) from that stored
pointer X and calls onRangeChange with a clamped shift (using clampVisibleRange)
each frame until the pointer moves back inside threshold or the visible range
hits 0/videoDurationMs; stop the RAF on drag end/cancel. Use the existing
symbols visibleMs, contentWidth, videoDurationMs, clampVisibleRange and
onRangeChange so the core shift logic remains the same but driven by RAF and the
stored pointer position.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: f8b74f8e-2bc3-4de4-b79d-c648afb219a9

📥 Commits

Reviewing files that changed from the base of the PR and between dd0b7d6 and 203282b.

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

@siddharthvaddem siddharthvaddem merged commit ece9368 into siddharthvaddem:main Mar 21, 2026
5 checks passed
@ryujh030820 ryujh030820 deleted the feature/improve-timeline-navigation branch March 22, 2026 00:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants