Skip to content

Conversation

@ameer2468
Copy link
Collaborator

@ameer2468 ameer2468 commented Oct 31, 2025

This PR: previously if you trim the first clip or segment, it would go under the next one. This PR prevents that.

Screen.Recording.2025-10-31.at.16.43.11.mov

Summary by CodeRabbit

  • Bug Fixes

    • Improved timeline dragging to prevent segment overlap and ensure coordinated dragging across segments.
    • Prevented proposing zoom segments when there isn’t enough space for the minimum duration.
    • Removed stray debug console output from timeline editing.
  • UI

    • Adjusted visual stacking during drags and zoom previews for clearer layering and focus.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Oct 31, 2025

Walkthrough

Introduces a shared drag-tracking state to coordinate dragging across timeline segments, clamps start/end to avoid overlaps, adjusts z-index during active drags, and tightens zoom-segment proposal guards to only return proposals when minimum duration and next-segment bounds permit.

Changes

Cohort / File(s) Change Summary
Drag state coordination
apps/desktop/src/routes/editor/Timeline/ClipTrack.tsx
Adds shared activeDragState for cross-segment dragging; computes relative segment positions using current and previous segment offsets and clamps to avoid overlap; sets/clears shared state on drag start/cleanup; adds conditional z-50 elevation when dragging; removes stray console log and some inline prev-segment comparison logic.
Zoom segment validation & layering
apps/desktop/src/routes/editor/Timeline/ZoomTrack.tsx
Replaces fallback segment construction with guards that return undefined when space < minDuration; computes max bound from next segment start or total duration and ensures max - previewTime >= minDuration; uses computed max for proposals; adjusts UI stacking classes (z-10 for main container, z-0 for placeholder).

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant ClipTrack as ClipTrack Component
    participant ActiveState as activeDragState (shared)
    participant PrevSegment as Previous Segment
    participant Renderer

    Note over User,ClipTrack: Start dragging a segment handle
    User ->> ClipTrack: pointerdown(start handle)
    ClipTrack ->> ClipTrack: compute local offset, set startHandleDrag
    ClipTrack ->> ActiveState: setActiveDragState({ index, offset })
    ActiveState -->> ClipTrack: shared state stored

    Note over ClipTrack,PrevSegment: During drag updates
    User ->> ClipTrack: pointermove(delta)
    ClipTrack ->> ClipTrack: compute proposedStart = base + localOffset + prevOffset
    ClipTrack ->> ClipTrack: clampedStart = clamp(proposedStart, min, prevEnd)
    ClipTrack ->> Renderer: render segment with clampedStart (z-50 if active)

    Note over ClipTrack,ActiveState: On drag end/cleanup
    User ->> ClipTrack: pointerup
    ClipTrack ->> ClipTrack: clear startHandleDrag
    ClipTrack ->> ActiveState: setActiveDragState(null)
    ClipTrack ->> Renderer: render final state
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20–25 minutes

  • Review focus:
    • apps/desktop/src/routes/editor/Timeline/ClipTrack.tsx — correctness of offset accumulation, clamping logic, and shared state lifecycle (race conditions on async set).
    • apps/desktop/src/routes/editor/Timeline/ZoomTrack.tsx — correctness of new guards (edge cases when next segment is adjacent) and the computed max boundary.
    • UI z-index adjustments for unintended stacking regressions in overlapping UI states.

Possibly related PRs

Suggested labels

Desktop

Suggested reviewers

  • Brendonovich

Poem

🐰
I nudged the clips so timelines glide,
Offsets synced, no overlaps to hide.
Zooms now check the space before they play,
Layers stack tidy — hop, hooray! 🥕

Pre-merge checks and finishing touches

❌ 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%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed The title "desktop app: improve trimming behaviour" directly aligns with the PR's stated objective and the changes made in both affected files. The PR explicitly addresses a bug where trimming the first clip or segment causes it to overlap with the following segment, and the changes implement this fix through enhanced overlap prevention logic (clamping in ClipTrack and boundary checks in ZoomTrack) and improved z-index handling. The title is clear, concise, and appropriately describes the main intent without being vague or misleading.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch improve-trimming-behaviour

📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 7f86cfd and fc60532.

📒 Files selected for processing (1)
  • apps/desktop/src/routes/editor/Timeline/ClipTrack.tsx (5 hunks)
🧰 Additional context used
📓 Path-based instructions (2)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{ts,tsx}: Use a 2-space indent for TypeScript code.
Use Biome for formatting and linting TypeScript/JavaScript files by running pnpm format.

Files:

  • apps/desktop/src/routes/editor/Timeline/ClipTrack.tsx
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{ts,tsx,js,jsx}: Use kebab-case for filenames for TypeScript/JavaScript modules (e.g., user-menu.tsx).
Use PascalCase for React/Solid components.

Files:

  • apps/desktop/src/routes/editor/Timeline/ClipTrack.tsx
🧬 Code graph analysis (1)
apps/desktop/src/routes/editor/Timeline/ClipTrack.tsx (1)
packages/database/auth/auth-options.ts (1)
  • maxDuration (20-20)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: Build Desktop (x86_64-pc-windows-msvc, windows-latest)
  • GitHub Check: Build Desktop (aarch64-apple-darwin, macos-latest)
  • GitHub Check: Analyze (rust)
🔇 Additional comments (4)
apps/desktop/src/routes/editor/Timeline/ClipTrack.tsx (4)

200-204: Excellent approach to coordinate drag state across segments.

The shared activeDragState signal effectively enables subsequent segments to adjust their visual position when a previous segment is being trimmed, preventing the overlap issue described in the PR.


409-409: Visual elevation during drag works perfectly.

The conditional z-50 class ensures the segment being trimmed always renders above adjacent segments, directly addressing the overlap issue shown in the PR demo.


555-580: Improved overlap prevention logic.

The removal of the prevSegmentIsSameClip check correctly ensures no overlap occurs regardless of clip boundaries, which aligns with the PR objective.

One observation: the activeDragState update (lines 575-580) happens asynchronously via requestAnimationFrame, while the project update (lines 582-588) is synchronous. This batching improves performance but could theoretically cause a one-frame delay before subsequent segments adjust their position.

Please verify during manual testing that rapid dragging doesn't produce noticeable visual lag or "jumping" of subsequent segments.


596-596: Proper cleanup of shared drag state.

Resetting activeDragState to null on cleanup correctly prevents stale offset values from affecting subsequent segments after the drag operation completes.


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

Actionable comments posted: 0

🧹 Nitpick comments (1)
apps/desktop/src/routes/editor/Timeline/ZoomTrack.tsx (1)

119-133: Redundant space check when next segment exists.

When nextSegment exists (lines 111-125), the code checks spaceToNext < minDuration at line 121 and then again checks max - previewTime < minDuration at line 133 (where max === nextSegment.start). These are identical checks. The guard at line 133 is only necessary when there's no next segment.

Consider restructuring to avoid the duplicate check:

 	if (Option.isSome(nextSegment)) {
 		if (Option.isSome(prevSegment)) {
 			const availableTime =
 				nextSegment.value[0].start - prevSegment.value[0].end;
 
 			if (availableTime < minDuration) return;
 		}
 
-		// Check if there's space between preview time and next segment
-		const spaceToNext = nextSegment.value[0].start - previewTime;
-		if (spaceToNext < minDuration) {
-			// If there's not enough space for minimum duration, don't show proposed zoom
-			return;
-		}
 	}
 
 	const max = nextSegment.pipe(
 		Option.map(([s]) => s.start),
 		Option.getOrElse(() => totalDuration()),
 	);
 
 	// Check if there's enough space before returning
 	if (max - previewTime < minDuration) return;
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between b4aceaf and 7f86cfd.

📒 Files selected for processing (2)
  • apps/desktop/src/routes/editor/Timeline/ClipTrack.tsx (5 hunks)
  • apps/desktop/src/routes/editor/Timeline/ZoomTrack.tsx (3 hunks)
🧰 Additional context used
📓 Path-based instructions (2)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{ts,tsx}: Use a 2-space indent for TypeScript code.
Use Biome for formatting and linting TypeScript/JavaScript files by running pnpm format.

Files:

  • apps/desktop/src/routes/editor/Timeline/ClipTrack.tsx
  • apps/desktop/src/routes/editor/Timeline/ZoomTrack.tsx
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{ts,tsx,js,jsx}: Use kebab-case for filenames for TypeScript/JavaScript modules (e.g., user-menu.tsx).
Use PascalCase for React/Solid components.

Files:

  • apps/desktop/src/routes/editor/Timeline/ClipTrack.tsx
  • apps/desktop/src/routes/editor/Timeline/ZoomTrack.tsx
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: Build Desktop (aarch64-apple-darwin, macos-latest)
  • GitHub Check: Build Desktop (x86_64-pc-windows-msvc, windows-latest)
  • GitHub Check: Analyze (rust)
🔇 Additional comments (9)
apps/desktop/src/routes/editor/Timeline/ClipTrack.tsx (5)

200-204: LGTM! Good use of shared state for drag coordination.

The activeDragState signal appropriately coordinates dragging across multiple timeline segments, enabling the behavior described in the PR objectives where trimming the first clip no longer causes it to go underneath the following clip.


231-256: LGTM! Offset propagation logic correctly implements the improved trimming behavior.

The calculation properly propagates drag offsets from previous segments to following segments, preventing clips from going underneath each other during trimming operations. The use of Math.max ensures the start position remains non-negative.


406-406: LGTM! Appropriate z-index stacking during drag.

The conditional z-50 class ensures the segment being dragged appears on top of other segments, providing clear visual feedback during the interaction.


566-577: LGTM! Correct offset calculation and state synchronization.

The offset is properly computed as the difference between the clamped start position and the initial start position. Both local and shared drag states are updated consistently, enabling coordinated behavior across segments.


590-595: LGTM! Proper cleanup of drag state.

The cleanup correctly resets both local (startHandleDrag) and shared (activeDragState) drag states, preventing stale state from affecting subsequent drag operations.

apps/desktop/src/routes/editor/Timeline/ZoomTrack.tsx (4)

119-124: LGTM! Appropriate guard against insufficient space.

This guard correctly prevents proposing a new zoom segment when there isn't enough space between the preview time and the next segment, improving the boundary handling as described in the PR objectives.


127-130: LGTM! Good refactor to compute max boundary once.

Computing the max value once and reusing it improves clarity and eliminates duplicate logic. The fallback to totalDuration() when there's no next segment is correct.


139-139: LGTM! Consistent use of computed max boundary.

Using the pre-computed max value ensures consistency with the boundary checks above and improves code clarity.


425-425: LGTM! Proper z-index stacking for visual clarity.

The z-index adjustments ensure actual zoom segments (z-10) appear above the placeholder segment (z-0), providing clear visual feedback during timeline interactions. This coordinates with the z-50 applied in ClipTrack.tsx for dragged segments.

Also applies to: 616-616

@ameer2468 ameer2468 marked this pull request as draft November 3, 2025 11:35
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