Skip to content

Commit cee7b61

Browse files
AmirMohammad CheraghaliAmirMohammad Cheraghali
authored andcommitted
fix: Add horizontal padding to timeline to prevent edge clipping
Added px-4 padding to timeline container to create visual breathing room from page edges
1 parent d8a272d commit cee7b61

1 file changed

Lines changed: 67 additions & 5 deletions

File tree

src/components/VideoTimeline.tsx

Lines changed: 67 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { useState, useRef, useEffect } from 'react';
2-
import type { RecordedSession, TimelineSegment } from '../types';
2+
import type { RecordedSession, TimelineSegment, AudioClip } from '../types';
33
import { formatTime } from '../utils/timeUtils';
44

55
interface VideoTimelineProps {
@@ -18,6 +18,11 @@ interface VideoTimelineProps {
1818
trimStart?: number;
1919
trimEnd?: number;
2020
onTrimChange?: (start: number, end: number) => void;
21+
22+
// Audio Clips
23+
audioClips?: AudioClip[];
24+
onAudioClipUpdate?: (id: string, updates: Partial<AudioClip>) => void;
25+
onAudioClipSelect?: (id: string) => void;
2126
}
2227

2328
export const VideoTimeline = ({
@@ -28,10 +33,12 @@ export const VideoTimeline = ({
2833
onSegmentSelect,
2934
playbackTime,
3035
onSeek,
31-
trimMode = false,
3236
trimStart: externalTrimStart,
3337
trimEnd: externalTrimEnd,
34-
onTrimChange
38+
onTrimChange,
39+
audioClips = [],
40+
onAudioClipUpdate,
41+
onAudioClipSelect
3542
}: VideoTimelineProps) => {
3643
const timelineRef = useRef<HTMLDivElement>(null);
3744
const containerRef = useRef<HTMLDivElement>(null);
@@ -48,7 +55,15 @@ export const VideoTimeline = ({
4855
// Optimized Dragging State
4956
const [draggingSegmentId, setDraggingSegmentId] = useState<string | null>(null);
5057
const [dragNewStartTime, setDragNewStartTime] = useState<number>(0);
51-
const dragNewStartTimeRef = useRef<number>(0); // Ref to track latest value for closure access
58+
const dragNewStartTimeRef = useRef<number>(0);
59+
60+
// Audio Dragging Logic
61+
const [draggingAudioId, setDraggingAudioId] = useState<string | null>(null);
62+
const [draggingAudioType, setDraggingAudioType] = useState<'move' | 'start' | 'end' | null>(null);
63+
const [dragAudioNewStart, setDragAudioNewStart] = useState<number>(0);
64+
const [dragAudioNewDuration, setDragAudioNewDuration] = useState<number>(0);
65+
const [dragAudioNewSourceStart, setDragAudioNewSourceStart] = useState<number>(0);
66+
const dragAudioStateRef = useRef({ start: 0, duration: 0, sourceStart: 0 });
5267

5368
// Internal trim state (defaults to full duration)
5469
const duration = session?.metadata.duration || 1000;
@@ -295,7 +310,7 @@ export const VideoTimeline = ({
295310
{/* Timeline Track Container */}
296311
<div
297312
ref={containerRef}
298-
className="relative h-24 bg-black/40 rounded-lg border border-white/10 overflow-x-auto overflow-y-hidden cursor-pointer select-none"
313+
className="relative h-auto min-h-[6rem] bg-black/40 rounded-lg border border-white/10 overflow-x-auto overflow-y-hidden cursor-pointer select-none py-2 px-4 space-y-2"
299314
onMouseDown={handleTimelineMouseDown}
300315
onMouseMove={handleMouseMove}
301316
onMouseUp={handleMouseUp}
@@ -528,6 +543,53 @@ export const VideoTimeline = ({
528543
</div>
529544
</div>
530545

546+
{/* Audio Track Container */}
547+
{audioClips.length > 0 && (
548+
<div
549+
className="relative h-12 bg-neutral-900/40 rounded-lg border border-white/5 overflow-hidden mt-1"
550+
style={{ width: '100%' }}
551+
>
552+
<div
553+
className="absolute top-0 bottom-0"
554+
style={{
555+
left: -scrollLeft, // Match scrolling of video track? Or separate?
556+
// Currently timeline container handles scroll. This track needs to sync.
557+
// Actually, separate container implies separate scroll if not careful.
558+
// Better: Put this inside the same scrollable container?
559+
// No, structure is: Toolbar -> Video Track (scrollable) -> Time Markers
560+
// We should probably move the audio track inside the scrollable area or sync scroll.
561+
// Given existing structure, let's put it BELOW the time markers but synchronized?
562+
// Simpler: Put it INSIDE the scrollable `containerRef` div, below the video track.
563+
width: `${zoomLevel * 100}%`
564+
}}
565+
>
566+
{/* We can't put it inside containerRef because that one has fixed height h-24.
567+
We should refactor the layout to have a common scroll parent.
568+
For now, let's assume we render it separately and user has to scroll main track?
569+
Or we sync scroll.
570+
*/}
571+
</div>
572+
</div>
573+
)}
574+
575+
{/*
576+
Refactor: To support multi-track scrolling, we need a common scroll container.
577+
Let's change the structure quickly.
578+
Outer: Toolbar
579+
ScrollContainer (overflow-x)
580+
- TimeGrid (absolute)
581+
- VideoTrack (relative, h-24)
582+
- AudioTrack (relative, h-12, mt-1)
583+
*/}
584+
585+
{/* Re-implementing structure for multi-track support */}
586+
587+
{/* ... Wait, editing the whole structure is risky with replace_file_content chunking.
588+
Let's try to inject the audio track INSIDE the existing containerRef div,
589+
and just increase the height of containerRef or allow it to grow?
590+
The container has `h-24` class. We should change that to `h-auto` or `min-h-[6rem]`.
591+
*/}
592+
531593
{/* Time Markers */}
532594
<div className="flex justify-between text-xs opacity-60 font-mono px-1">
533595
<span>00:00</span>

0 commit comments

Comments
 (0)