add shortcut shift+j for toggling keyboard shortcut dialog #654

also allow resetting key config #726
pull/982/head
Mikael Finstad 2022-02-20 20:12:58 +08:00
rodzic 1a59be3e75
commit c2cb1f5501
Nie znaleziono w bazie danych klucza dla tego podpisu
ID klucza GPG: 25AB36E3E81CBC26
4 zmienionych plików z 41 dodań i 7 usunięć

Wyświetl plik

@ -62,6 +62,7 @@ const defaultKeyBindings = [
{ keys: 'e', action: 'export' },
{ keys: 'h', action: 'toggleHelp' },
{ keys: 'shift+/', action: 'toggleKeyboardShortcuts' },
{ keys: 'escape', action: 'closeActiveScreen' },
];

Wyświetl plik

@ -197,7 +197,7 @@ const App = memo(() => {
const isCustomFormatSelected = fileFormat !== detectedFileFormat;
const {
captureFormat, setCaptureFormat, customOutDir, setCustomOutDir, keyframeCut, setKeyframeCut, preserveMovData, setPreserveMovData, movFastStart, setMovFastStart, avoidNegativeTs, setAvoidNegativeTs, autoMerge, setAutoMerge, timecodeFormat, setTimecodeFormat, invertCutSegments, setInvertCutSegments, autoExportExtraStreams, setAutoExportExtraStreams, askBeforeClose, setAskBeforeClose, enableAskForImportChapters, setEnableAskForImportChapters, enableAskForFileOpenAction, setEnableAskForFileOpenAction, playbackVolume, setPlaybackVolume, autoSaveProjectFile, setAutoSaveProjectFile, wheelSensitivity, setWheelSensitivity, invertTimelineScroll, setInvertTimelineScroll, language, setLanguage, ffmpegExperimental, setFfmpegExperimental, hideNotifications, setHideNotifications, autoLoadTimecode, setAutoLoadTimecode, autoDeleteMergedSegments, setAutoDeleteMergedSegments, exportConfirmEnabled, setExportConfirmEnabled, segmentsToChapters, setSegmentsToChapters, preserveMetadataOnMerge, setPreserveMetadataOnMerge, simpleMode, setSimpleMode, outSegTemplate, setOutSegTemplate, keyboardSeekAccFactor, setKeyboardSeekAccFactor, keyboardNormalSeekSpeed, setKeyboardNormalSeekSpeed, enableTransferTimestamps, setEnableTransferTimestamps, outFormatLocked, setOutFormatLocked, safeOutputFileName, setSafeOutputFileName, enableAutoHtml5ify, setEnableAutoHtml5ify, segmentsToChaptersOnly, setSegmentsToChaptersOnly, keyBindings, setKeyBindings,
captureFormat, setCaptureFormat, customOutDir, setCustomOutDir, keyframeCut, setKeyframeCut, preserveMovData, setPreserveMovData, movFastStart, setMovFastStart, avoidNegativeTs, setAvoidNegativeTs, autoMerge, setAutoMerge, timecodeFormat, setTimecodeFormat, invertCutSegments, setInvertCutSegments, autoExportExtraStreams, setAutoExportExtraStreams, askBeforeClose, setAskBeforeClose, enableAskForImportChapters, setEnableAskForImportChapters, enableAskForFileOpenAction, setEnableAskForFileOpenAction, playbackVolume, setPlaybackVolume, autoSaveProjectFile, setAutoSaveProjectFile, wheelSensitivity, setWheelSensitivity, invertTimelineScroll, setInvertTimelineScroll, language, setLanguage, ffmpegExperimental, setFfmpegExperimental, hideNotifications, setHideNotifications, autoLoadTimecode, setAutoLoadTimecode, autoDeleteMergedSegments, setAutoDeleteMergedSegments, exportConfirmEnabled, setExportConfirmEnabled, segmentsToChapters, setSegmentsToChapters, preserveMetadataOnMerge, setPreserveMetadataOnMerge, simpleMode, setSimpleMode, outSegTemplate, setOutSegTemplate, keyboardSeekAccFactor, setKeyboardSeekAccFactor, keyboardNormalSeekSpeed, setKeyboardNormalSeekSpeed, enableTransferTimestamps, setEnableTransferTimestamps, outFormatLocked, setOutFormatLocked, safeOutputFileName, setSafeOutputFileName, enableAutoHtml5ify, setEnableAutoHtml5ify, segmentsToChaptersOnly, setSegmentsToChaptersOnly, keyBindings, setKeyBindings, resetKeyBindings,
} = useUserPreferences();
const {
@ -1626,6 +1626,8 @@ const App = memo(() => {
setStartTimeOffset(newStartTimeOffset);
}, [startTimeOffset]);
const toggleKeyboardShortcuts = useCallback(() => setKeyboardShortcutsVisible((v) => !v), []);
const onKeyPress = useCallback(({ action, keyup }) => {
function seekReset() {
seekAccelerationRef.current = 1;
@ -1723,6 +1725,11 @@ const App = memo(() => {
return false;
}
if (action === 'toggleKeyboardShortcuts') {
toggleKeyboardShortcuts();
return false;
}
if (concatDialogVisible || keyboardShortcutsVisible) {
return true; // don't allow any further hotkeys
}
@ -1740,7 +1747,7 @@ const App = memo(() => {
if (match) return bubble;
return true; // bubble the event
}, [addCutSegment, askSetStartTimeOffset, batchFileJump, captureSnapshot, changePlaybackRate, cleanupFilesDialog, clearSegments, closeBatch, closeExportConfirm, concatCurrentBatch, concatDialogVisible, convertFormatBatch, createFixedDurationSegments, createNumSegments, currentSegIndexSafe, cutSegmentsHistory, exportConfirmVisible, extractAllStreams, goToTimecode, increaseRotation, invertAllCutSegments, jumpCutEnd, jumpCutStart, jumpSeg, jumpTimelineEnd, jumpTimelineStart, keyboardNormalSeekSpeed, keyboardSeekAccFactor, keyboardShortcutsVisible, onExportConfirm, onExportPress, onLabelSegmentPress, removeCutSegment, reorderSegsByStartTime, seekClosestKeyframe, seekRel, seekRelPercent, setCutEnd, setCutStart, shortStep, shuffleSegments, splitCurrentSegment, timelineToggleComfortZoom, toggleCaptureFormat, toggleHelp, toggleKeyframeCut, togglePlay, toggleSegmentsList, toggleStreamsSelector, toggleStripAudio, userHtml5ifyCurrentFile, zoomRel]);
}, [addCutSegment, askSetStartTimeOffset, batchFileJump, captureSnapshot, changePlaybackRate, cleanupFilesDialog, clearSegments, closeBatch, closeExportConfirm, concatCurrentBatch, concatDialogVisible, convertFormatBatch, createFixedDurationSegments, createNumSegments, currentSegIndexSafe, cutSegmentsHistory, exportConfirmVisible, extractAllStreams, goToTimecode, increaseRotation, invertAllCutSegments, jumpCutEnd, jumpCutStart, jumpSeg, jumpTimelineEnd, jumpTimelineStart, keyboardNormalSeekSpeed, keyboardSeekAccFactor, keyboardShortcutsVisible, onExportConfirm, onExportPress, onLabelSegmentPress, removeCutSegment, reorderSegsByStartTime, seekClosestKeyframe, seekRel, seekRelPercent, setCutEnd, setCutStart, shortStep, shuffleSegments, splitCurrentSegment, timelineToggleComfortZoom, toggleCaptureFormat, toggleHelp, toggleKeyboardShortcuts, toggleKeyframeCut, togglePlay, toggleSegmentsList, toggleStreamsSelector, toggleStripAudio, userHtml5ifyCurrentFile, zoomRel]);
useKeyboard({ keyBindings, onKeyPress });
@ -2481,7 +2488,7 @@ const App = memo(() => {
<ConcatDialog isShown={batchFiles.length > 0 && concatDialogVisible} onHide={() => setConcatDialogVisible(false)} initialPaths={batchFilePaths} onConcat={mergeFiles} segmentsToChapters={segmentsToChapters} setSegmentsToChapters={setSegmentsToChapters} setAlwaysConcatMultipleFiles={setAlwaysConcatMultipleFiles} alwaysConcatMultipleFiles={alwaysConcatMultipleFiles} preserveMetadataOnMerge={preserveMetadataOnMerge} setPreserveMetadataOnMerge={setPreserveMetadataOnMerge} preserveMovData={preserveMovData} setPreserveMovData={setPreserveMovData} />
<KeyboardShortcuts isShown={keyboardShortcutsVisible} onHide={() => setKeyboardShortcutsVisible(false)} keyBindings={keyBindings} setKeyBindings={setKeyBindings} currentCutSeg={currentCutSeg} />
<KeyboardShortcuts isShown={keyboardShortcutsVisible} onHide={() => setKeyboardShortcutsVisible(false)} keyBindings={keyBindings} setKeyBindings={setKeyBindings} currentCutSeg={currentCutSeg} resetKeyBindings={resetKeyBindings} />
</div>
</ThemeProvider>
);

Wyświetl plik

@ -100,7 +100,7 @@ const CreateBinding = memo(({
const rowStyle = { display: 'flex', alignItems: 'center', margin: '6px 0' };
const KeyboardShortcuts = memo(({
keyBindings, setKeyBindings, currentCutSeg,
keyBindings, setKeyBindings, resetKeyBindings, currentCutSeg,
}) => {
const { t } = useTranslation();
@ -136,7 +136,11 @@ const KeyboardShortcuts = memo(({
toggleHelp: {
name: t('Show/hide help screen'),
},
toggleKeyboardShortcuts: {
name: t('Keyboard & mouse shortcuts'),
},
// playbackCategory
togglePlayResetSpeed: {
name: t('Play/pause'),
category: playbackCategory,
@ -162,6 +166,7 @@ const KeyboardShortcuts = memo(({
category: playbackCategory,
},
// seekingCategory
seekPreviousFrame: {
name: t('Step backward 1 frame'),
category: seekingCategory,
@ -209,6 +214,7 @@ const KeyboardShortcuts = memo(({
category: seekingCategory,
},
// segmentsAndCutpointsCategory
addSegment: {
name: t('Add cut segment'),
category: segmentsAndCutpointsCategory,
@ -272,6 +278,7 @@ const KeyboardShortcuts = memo(({
category: segmentsAndCutpointsCategory,
},
// streamsCategory
toggleStreamsSelector: {
name: t('Edit tracks / metadata tags'),
category: streamsCategory,
@ -281,6 +288,7 @@ const KeyboardShortcuts = memo(({
category: streamsCategory,
},
// zoomOperationsCategory
timelineZoomIn: {
name: t('Zoom in timeline'),
category: zoomOperationsCategory,
@ -294,6 +302,7 @@ const KeyboardShortcuts = memo(({
category: zoomOperationsCategory,
},
// outputCategory
export: {
name: t('Export segment(s)'),
category: outputCategory,
@ -315,6 +324,7 @@ const KeyboardShortcuts = memo(({
category: outputCategory,
},
// batchFilesCategory
batchPreviousFile: {
name: t('Previous file'),
category: batchFilesCategory,
@ -332,6 +342,7 @@ const KeyboardShortcuts = memo(({
category: batchFilesCategory,
},
// otherCategory
toggleKeyframeCutMode: {
name: t('Cut mode'),
category: otherCategory,
@ -380,6 +391,14 @@ const KeyboardShortcuts = memo(({
setKeyBindings((existingBindings) => existingBindings.filter((existingBinding) => !(existingBinding.keys === keys && existingBinding.action === action)));
}, [setKeyBindings, t]);
const onResetClick = useCallback(() => {
// eslint-disable-next-line no-alert
if (!window.confirm(t('Are you sure?'))) return;
resetKeyBindings();
}, [resetKeyBindings, t]);
const onAddBindingClick = useCallback((action) => {
setCreatingBinding(action);
}, []);
@ -448,13 +467,15 @@ const KeyboardShortcuts = memo(({
))}
</div>
<Button intent="danger" onClick={onResetClick}>{t('Reset')}</Button>
<CreateBinding actionsMap={actionsMap} action={creatingBinding} setCreatingBinding={setCreatingBinding} onNewKeyBindingConfirmed={onNewKeyBindingConfirmed} />
</>
);
});
const KeyboardShortcutsDialog = memo(({
isShown, onHide, keyBindings, setKeyBindings, currentCutSeg,
isShown, onHide, keyBindings, setKeyBindings, resetKeyBindings, currentCutSeg,
}) => {
const { t } = useTranslation();
@ -468,7 +489,7 @@ const KeyboardShortcutsDialog = memo(({
onConfirm={onHide}
topOffset="3vh"
>
{isShown ? <KeyboardShortcuts keyBindings={keyBindings} setKeyBindings={setKeyBindings} currentCutSeg={currentCutSeg} /> : <div />}
{isShown ? <KeyboardShortcuts keyBindings={keyBindings} setKeyBindings={setKeyBindings} currentCutSeg={currentCutSeg} resetKeyBindings={resetKeyBindings} /> : <div />}
</Dialog>
);
});

Wyświetl plik

@ -1,4 +1,4 @@
import { useEffect, useState, useRef } from 'react';
import { useEffect, useState, useRef, useCallback } from 'react';
import i18n from 'i18next';
import { errorToast } from '../util';
@ -102,6 +102,10 @@ export default () => {
useEffect(() => safeSetConfig('segmentsToChaptersOnly', segmentsToChaptersOnly), [segmentsToChaptersOnly]);
const [keyBindings, setKeyBindings] = useState(safeGetConfig('keyBindings'));
useEffect(() => safeSetConfig('keyBindings', keyBindings), [keyBindings]);
const resetKeyBindings = useCallback(() => {
configStore.reset('keyBindings');
setKeyBindings(safeGetConfig('keyBindings'));
}, []);
// NOTE! This useEffect must be placed after all usages of firstUpdateRef.current (safeSetConfig)
useEffect(() => {
@ -182,5 +186,6 @@ export default () => {
setSegmentsToChaptersOnly,
keyBindings,
setKeyBindings,
resetKeyBindings,
};
};