@@ -259,6 +259,14 @@ export function VideoTrackView({
259259 const bounds = calculateBounds ( ) ;
260260 const startX = e . clientX ;
261261 const startLeft = trackElement . offsetLeft ;
262+ const duplicateMode = e . ctrlKey || e . metaKey ;
263+ const originalTimestamp = frame . timestamp ;
264+ const originalLeftStyle = trackElement . style . left ;
265+ let duplicateTimestamp = frame . timestamp ;
266+
267+ const applyLeftStyle = ( timestamp : number ) => {
268+ trackElement . style . left = `${ ( ( timestamp / 30 ) * 100 ) / 1000 } %` ;
269+ } ;
262270
263271 const handleMouseMove = ( moveEvent : MouseEvent ) => {
264272 const deltaX = moveEvent . clientX - startX ;
@@ -274,16 +282,40 @@ export function VideoTrackView({
274282 const parentWidth = timelineElement
275283 ? ( timelineElement as HTMLElement ) . offsetWidth
276284 : 1 ;
277- const newTimestamp = ( newLeft / parentWidth ) * 30 ;
278- frame . timestamp = ( newTimestamp < 0 ? 0 : newTimestamp ) * 1000 ;
285+ const calculatedTimestamp = ( newLeft / parentWidth ) * 30 ;
286+ const sanitizedTimestamp =
287+ ( calculatedTimestamp < 0 ? 0 : calculatedTimestamp ) * 1000 ;
288+
289+ if ( duplicateMode ) {
290+ duplicateTimestamp = sanitizedTimestamp ;
291+ applyLeftStyle ( sanitizedTimestamp ) ;
292+ return ;
293+ }
279294
280- trackElement . style . left = `${ ( ( frame . timestamp / 30 ) * 100 ) / 1000 } %` ;
295+ frame . timestamp = sanitizedTimestamp ;
296+ applyLeftStyle ( frame . timestamp ) ;
281297 db . keyFrames . update ( frame . id , { timestamp : frame . timestamp } ) ;
282298 } ;
283299
284- const handleMouseUp = ( ) => {
300+ const handleMouseUp = async ( ) => {
285301 document . removeEventListener ( "mousemove" , handleMouseMove ) ;
286302 document . removeEventListener ( "mouseup" , handleMouseUp ) ;
303+
304+ if ( duplicateMode ) {
305+ if ( originalLeftStyle ) {
306+ trackElement . style . left = originalLeftStyle ;
307+ } else {
308+ applyLeftStyle ( originalTimestamp ) ;
309+ }
310+
311+ await db . keyFrames . create ( {
312+ trackId : frame . trackId ,
313+ data : { ...frame . data } ,
314+ timestamp : duplicateTimestamp ,
315+ duration : frame . duration ,
316+ } ) ;
317+ }
318+
287319 queryClient . invalidateQueries ( {
288320 queryKey : queryKeys . projectPreview ( projectId ) ,
289321 } ) ;
0 commit comments