11import { useRef , useState } from 'react' ;
22import {
33 Play , Pause , Circle , Square ,
4- Upload , Save , Film , Pencil , Scissors , ChevronDown , Trash2
4+ Upload , Save , Film , Pencil , Scissors , ChevronDown , Trash2 , Timer , Gauge
55} from 'lucide-react' ;
66import type { RecordedSession } from '../types' ;
77import { VideoTimeline } from './VideoTimeline' ;
@@ -12,6 +12,8 @@ interface RecorderControlsProps {
1212 recordingTime : number ;
1313 playbackTime : number ;
1414 session : RecordedSession | null ;
15+ segments ?: any [ ] ; // Typed as any[] to avoid import cycle for now, or use TimelineSegment
16+ updateSegment ?: ( id : string , updates : any ) => void ;
1517 playbackSpeed : number ;
1618
1719 startRecording : ( ) => void ;
@@ -29,6 +31,7 @@ interface RecorderControlsProps {
2931 deleteEventsByType : ( type : string , fromTime ?: number , toTime ?: number ) => void ;
3032 deleteEventsByTimeRange : ( fromTime : number , toTime : number ) => void ;
3133 splitSession : ( splitTime : number ) => { firstSession : any ; secondSession : any } | null ;
34+ adjustSessionSpeed : ( startTime : number , endTime : number , speedFactor : number ) => void ;
3235
3336 isLightMode : boolean ;
3437 cardBg : string ;
@@ -42,10 +45,10 @@ const formatTime = (ms: number) => {
4245} ;
4346
4447export const RecorderControls = ( {
45- isRecording, isPlaying, recordingTime, playbackTime, session, playbackSpeed,
48+ isRecording, isPlaying, recordingTime, playbackTime, session, segments , updateSegment , playbackSpeed,
4649 startRecording, stopRecording, play, pause, seek, setPlaybackSpeed,
4750 exportSession, importSession, exportVideo, updateMetadata,
48- trimSession, deleteEvent, deleteEventsByType, deleteEventsByTimeRange, splitSession,
51+ trimSession, deleteEvent, deleteEventsByType, deleteEventsByTimeRange, splitSession, adjustSessionSpeed ,
4952 isLightMode, cardBg
5053} : RecorderControlsProps ) => {
5154
@@ -57,6 +60,8 @@ export const RecorderControls = ({
5760
5861 // Visual trim mode
5962 const [ isTrimMode , setIsTrimMode ] = useState ( false ) ;
63+ const [ isSpeedMode , setIsSpeedMode ] = useState ( false ) ;
64+ const [ speedFactor , setSpeedFactor ] = useState ( 2 ) ;
6065 const [ tempTrimStart , setTempTrimStart ] = useState < number > ( 0 ) ;
6166 const [ tempTrimEnd , setTempTrimEnd ] = useState < number > ( 0 ) ;
6267
@@ -188,6 +193,8 @@ export const RecorderControls = ({
188193 < div className = "pt-2" >
189194 < VideoTimeline
190195 session = { session }
196+ segments = { segments }
197+ onSegmentUpdate = { updateSegment }
191198 playbackTime = { playbackTime }
192199 isPlaying = { isPlaying }
193200 onSeek = { seek }
@@ -361,11 +368,70 @@ export const RecorderControls = ({
361368 </ span >
362369 </ div >
363370 </ div >
371+
372+ { /* Speed Control (Feature 3) */ }
373+ < div className = "space-y-2" >
374+ < label className = { `${ styles . text } block` } > Playback Speed FX</ label >
375+ < div className = "flex gap-2 items-center flex-wrap" >
376+ < button
377+ onClick = { ( ) => {
378+ if ( isTrimMode ) setIsTrimMode ( false ) ;
379+ setIsSpeedMode ( ! isSpeedMode ) ;
380+ } }
381+ className = { `px-3 py-1.5 rounded text-xs transition-colors flex items-center gap-1 ${ isSpeedMode
382+ ? 'bg-orange-600 hover:bg-orange-700 text-white'
383+ : 'bg-orange-600/20 hover:bg-orange-600/40 border border-orange-600/30'
384+ } `}
385+ >
386+ < Gauge className = "w-3 h-3" />
387+ { isSpeedMode ? 'Select Range' : 'Adjust Speed' }
388+ </ button >
389+
390+ { isSpeedMode && (
391+ < >
392+ < div className = "flex bg-black/40 rounded p-1 gap-1" >
393+ { [ 0.5 , 1.5 , 2 , 4 ] . map ( speed => (
394+ < button
395+ key = { speed }
396+ onClick = { ( ) => setSpeedFactor ( speed ) }
397+ className = { `px-2 py-0.5 rounded text-xs transition-colors ${ speedFactor === speed
398+ ? 'bg-white/20 text-white'
399+ : 'hover:bg-white/10 text-white/50'
400+ } `}
401+ >
402+ { speed } x
403+ </ button >
404+ ) ) }
405+ </ div >
406+
407+ < button
408+ onClick = { ( ) => {
409+ adjustSessionSpeed ( tempTrimStart , tempTrimEnd , speedFactor ) ;
410+ setIsSpeedMode ( false ) ;
411+ setIsEditPanelOpen ( false ) ;
412+ } }
413+ className = "px-3 py-1.5 bg-purple-600 hover:bg-purple-700 rounded text-xs transition-colors"
414+ >
415+ Apply
416+ </ button >
417+ </ >
418+ ) }
419+ </ div >
420+ { isSpeedMode && (
421+ < div className = "text-xs opacity-60 flex gap-2 items-center" >
422+ < Timer className = "w-3 h-3" />
423+ < span >
424+ Applying { speedFactor } x speed from { formatTime ( tempTrimStart ) } to { formatTime ( tempTrimEnd ) }
425+ </ span >
426+ </ div >
427+ ) }
428+ </ div >
364429 </ div >
365430 ) }
366431 </ div >
367- ) }
368- </ div >
432+ )
433+ }
434+ </ div >
369435 ) ;
370436} ;
371437
0 commit comments