import React, { Fragment, memo } from 'react'; import { FaHandPointLeft, FaHandPointRight, FaStepBackward, FaStepForward, FaCaretLeft, FaCaretRight, FaPause, FaPlay, FaImages, FaKey } from 'react-icons/fa'; import { GiSoundWaves } from 'react-icons/gi'; import { IoMdKey } from 'react-icons/io'; import { useTranslation } from 'react-i18next'; // import useTraceUpdate from 'use-trace-update'; import { getSegColors } from './util/colors'; import { formatDuration, parseDuration } from './util/duration'; import { primaryTextColor } from './colors'; import SetCutpointButton from './components/SetCutpointButton'; const TimelineControls = memo(({ seekAbs, currentSegIndexSafe, cutSegments, currentCutSeg, setCutStart, setCutEnd, setCurrentSegIndex, cutStartTimeManual, setCutStartTimeManual, cutEndTimeManual, setCutEndTimeManual, duration, jumpCutEnd, jumpCutStart, startTimeOffset, setCutTime, currentApparentCutSeg, playing, shortStep, togglePlay, setTimelineMode, hasAudio, hasVideo, timelineMode, keyframesEnabled, toggleKeyframesEnabled, seekClosestKeyframe, simpleMode, }) => { const { t } = useTranslation(); function renderJumpCutpointButton(direction) { const newIndex = currentSegIndexSafe + direction; const seg = cutSegments[newIndex]; const getSegButtonStyle = ({ segActiveBgColor, segBorderColor }) => ({ background: segActiveBgColor, border: `2px solid ${segBorderColor}`, borderRadius: 6, color: 'white', fontSize: 14, textAlign: 'center', lineHeight: '11px', fontWeight: 'bold' }); let segButtonStyle; if (seg) { const { segActiveBgColor, segBorderColor } = getSegColors(seg); segButtonStyle = getSegButtonStyle({ segActiveBgColor, segBorderColor }); } else { segButtonStyle = getSegButtonStyle({ segActiveBgColor: 'rgba(255,255,255,0.3)', segBorderColor: 'rgba(255,255,255,0.5)' }); } return (
0 ? t('Select next segment') : t('Select previous segment')} (${newIndex + 1})`} onClick={() => seg && setCurrentSegIndex(newIndex)} > {newIndex + 1}
); } function renderCutTimeInput(type) { const isStart = type === 'start'; const cutTimeManual = isStart ? cutStartTimeManual : cutEndTimeManual; const cutTime = isStart ? currentApparentCutSeg.start : currentApparentCutSeg.end; const setCutTimeManual = isStart ? setCutStartTimeManual : setCutEndTimeManual; const isCutTimeManualSet = () => cutTimeManual !== undefined; const cutTimeInputStyle = { background: 'white', borderRadius: 5, color: 'rgba(0, 0, 0, 0.7)', fontSize: 13, textAlign: 'center', padding: '1px 5px', marginTop: 0, marginBottom: 0, marginLeft: isStart ? 0 : 5, marginRight: isStart ? 5 : 0, border: 'none', boxSizing: 'border-box', fontFamily: 'inherit', width: 90, outline: 'none', }; function parseAndSetCutTime(text) { // Not a valid duration? Only set manual const timeWithOffset = parseDuration(text); if (timeWithOffset === undefined) { setCutTimeManual(text); return; } setCutTimeManual(); const timeWithoutOffset = Math.max(timeWithOffset - startTimeOffset, 0); try { setCutTime(type, timeWithoutOffset); seekAbs(timeWithoutOffset); } catch (err) { console.error('Cannot set cut time', err); } } function handleCutTimeInput(text) { // Allow the user to erase to reset if (text.length === 0) { setCutTimeManual(); return; } parseAndSetCutTime(text); } async function handleCutTimePaste(e) { e.preventDefault(); try { const clipboardData = e.clipboardData.getData('Text'); parseAndSetCutTime(clipboardData); } catch (err) { console.error(err); } } return ( handleCutTimeInput(e.target.value)} onPaste={handleCutTimePaste} value={isCutTimeManualSet() ? cutTimeManual : formatDuration({ seconds: cutTime + startTimeOffset })} /> ); } const PlayPause = playing ? FaPause : FaPlay; const leftRightWidth = 100; const toolbarHeight = 24; return (
{hasAudio && !simpleMode && ( setTimelineMode('waveform')} /> )} {hasVideo && !simpleMode && ( <> setTimelineMode('thumbnails')} /> )}
{!simpleMode && ( seekAbs(0)} /> )} {!simpleMode && renderJumpCutpointButton(-1)} {!simpleMode && } {!simpleMode && renderCutTimeInput('start')} seekClosestKeyframe(-1)} /> {!simpleMode && ( shortStep(-1)} /> )} {!simpleMode && ( shortStep(1)} /> )} seekClosestKeyframe(1)} /> {!simpleMode && renderCutTimeInput('end')} {!simpleMode && } {!simpleMode && renderJumpCutpointButton(1)} {!simpleMode && ( seekAbs(duration)} /> )}
); }); export default TimelineControls;