From 87df1c5e5f556ce4274fe914bdb64756c0c4839e Mon Sep 17 00:00:00 2001 From: Mikael Finstad Date: Fri, 14 Jan 2022 22:54:33 +0700 Subject: [PATCH] implement go to timecode #625 inputted value `g` key or right click timeline context menu --- src/App.jsx | 24 ++++++++++++++++++++---- src/HelpSheet.jsx | 1 + src/Timeline.jsx | 11 ++++++++--- src/dialogs.jsx | 10 +++++----- 4 files changed, 34 insertions(+), 12 deletions(-) diff --git a/src/App.jsx b/src/App.jsx index 96143b5b..bdbce9b3 100644 --- a/src/App.jsx +++ b/src/App.jsx @@ -1648,6 +1648,18 @@ const App = memo(() => { } }, [customOutDir, filePath, html5ifyAndLoad, hasVideo, hasAudio, rememberConvertToSupportedFormat, setWorking]); + const goToTimecode = useCallback(async () => { + if (!filePath) return; + const timeCode = await promptTimeOffset({ + initialValue: formatDuration({ seconds: commandedTimeRef.current }), + title: i18n.t('Seek to timecode'), + }); + + if (timeCode === undefined) return; + + seekAbs(timeCode); + }, [filePath, seekAbs]); + // TODO split up? useEffect(() => { @@ -1704,6 +1716,7 @@ const App = memo(() => { mousetrap.bind('d', () => cleanupFiles()); mousetrap.bind('b', () => splitCurrentSegment()); mousetrap.bind('r', () => increaseRotation()); + mousetrap.bind('g', () => goToTimecode()); mousetrap.bind('left', () => seekBackwards()); mousetrap.bind('left', () => seekReset(), 'keyup'); @@ -1746,7 +1759,7 @@ const App = memo(() => { setCutEnd, setCutStart, seekRel, seekRelPercent, shortStep, cleanupFiles, jumpSeg, seekClosestKeyframe, zoomRel, toggleComfortZoom, splitCurrentSegment, exportConfirmVisible, increaseRotation, jumpCutStart, jumpCutEnd, cutSegmentsHistory, keyboardSeekAccFactor, - keyboardNormalSeekSpeed, onLabelSegmentPress, currentSegIndexSafe, batchFileJump, + keyboardNormalSeekSpeed, onLabelSegmentPress, currentSegIndexSafe, batchFileJump, goToTimecode, ]); const onVideoError = useCallback(async () => { @@ -1797,9 +1810,11 @@ const App = memo(() => { } async function setStartOffset() { - const newStartTimeOffset = await promptTimeOffset( - startTimeOffset !== undefined ? formatDuration({ seconds: startTimeOffset }) : undefined, - ); + const newStartTimeOffset = await promptTimeOffset({ + initialValue: startTimeOffset !== undefined ? formatDuration({ seconds: startTimeOffset }) : undefined, + title: i18n.t('Set custom start time offset'), + text: i18n.t('Instead of video apparently starting at 0, you can offset by a specified value. This only applies to the preview inside LosslessCut and does not modify the file in any way. (Useful for viewing/cutting videos according to timecodes)'), + }); if (newStartTimeOffset === undefined) return; @@ -2415,6 +2430,7 @@ const App = memo(() => { playing={playing} isFileOpened={isFileOpened} onWheel={onTimelineWheel} + goToTimecode={goToTimecode} /> CTRL / CMD + {t('Seek forward 1% of timeline at current zoom')}
, SHIFT + {t('Jump to cut start')}
, SHIFT + {t('Jump to cut end')}
+
G {t('Seek to timecode')}

{t('Segments and cut points')}

diff --git a/src/Timeline.jsx b/src/Timeline.jsx index 79ed56ec..e984fd0f 100644 --- a/src/Timeline.jsx +++ b/src/Timeline.jsx @@ -7,6 +7,7 @@ import { FaCaretDown, FaCaretUp } from 'react-icons/fa'; import TimelineSeg from './TimelineSeg'; import BetweenSegments from './BetweenSegments'; +import useContextMenu from './hooks/useContextMenu'; import { timelineBackground } from './colors'; @@ -41,14 +42,14 @@ const Waveform = memo(({ calculateTimelinePercent, durationSafe, waveform, zoom, const CommandedTime = memo(({ commandedTimePercent }) => { const color = 'white'; - const commonStyle = { left: commandedTimePercent, position: 'absolute', zIndex: 4, pointerEvents: 'none' } + const commonStyle = { left: commandedTimePercent, position: 'absolute', zIndex: 4, pointerEvents: 'none' }; return ( <>
- ) + ); }); const Timeline = memo(({ @@ -57,7 +58,7 @@ const Timeline = memo(({ setCurrentSegIndex, currentSegIndexSafe, invertCutSegments, inverseCutSegments, formatTimecode, waveform, shouldShowWaveform, shouldShowKeyframes, timelineHeight, thumbnails, onZoomWindowStartTimeChange, waveformEnabled, thumbnailsEnabled, - playing, isFileOpened, onWheel, commandedTimeRef, + playing, isFileOpened, onWheel, commandedTimeRef, goToTimecode, }) => { const { t } = useTranslation(); @@ -191,6 +192,10 @@ const Timeline = memo(({ const onMouseMove = useCallback((e) => setHoveringTime(getMouseTimelinePos(e.nativeEvent)), [getMouseTimelinePos]); const onMouseOut = useCallback(() => setHoveringTime(), []); + useContextMenu(timelineScrollerRef, [ + { label: t('Seek to timecode'), click: goToTimecode }, + ]); + return ( // eslint-disable-next-line jsx-a11y/mouse-events-have-key-events