From ae8f6d4be1d9574cb64c3a7c10dccb6b5063b41d Mon Sep 17 00:00:00 2001 From: Mikael Finstad Date: Tue, 5 Dec 2023 13:00:54 +0800 Subject: [PATCH] improve export confirm #1798 --- src/components/ExportConfirm.jsx | 80 +++++++++++++++++++------ src/components/ExportConfirm.module.css | 9 +-- src/components/OutSegTemplateEditor.jsx | 13 ++-- src/components/Settings.jsx | 11 +--- src/util.js | 2 +- 5 files changed, 79 insertions(+), 36 deletions(-) diff --git a/src/components/ExportConfirm.jsx b/src/components/ExportConfirm.jsx index d4948dd8..1fc77f2f 100644 --- a/src/components/ExportConfirm.jsx +++ b/src/components/ExportConfirm.jsx @@ -29,9 +29,9 @@ const boxStyle = { margin: '15px 15px 50px 15px', borderRadius: 10, padding: '10 const outDirStyle = { ...highlightedTextStyle, wordBreak: 'break-all', cursor: 'pointer' }; -const warningStyle = { color: 'var(--red11)', fontSize: '80%' }; +const warningStyle = { color: 'var(--red11)', fontSize: '80%', marginBottom: '.5em' }; -const HelpIcon = ({ onClick, style }) => ; +const HelpIcon = ({ onClick, style }) => ; const ExportConfirm = memo(({ areWeCutting, selectedSegments, segmentsToExport, willMerge, visible, onClosePress, onExportConfirm, @@ -41,7 +41,7 @@ const ExportConfirm = memo(({ }) => { const { t } = useTranslation(); - const { changeOutDir, keyframeCut, toggleKeyframeCut, preserveMovData, movFastStart, avoidNegativeTs, setAvoidNegativeTs, autoDeleteMergedSegments, exportConfirmEnabled, toggleExportConfirmEnabled, segmentsToChapters, toggleSegmentsToChapters, preserveMetadataOnMerge, togglePreserveMetadataOnMerge, enableSmartCut, setEnableSmartCut, effectiveExportMode, enableOverwriteOutput, setEnableOverwriteOutput } = useUserSettings(); + const { changeOutDir, keyframeCut, toggleKeyframeCut, preserveMovData, movFastStart, avoidNegativeTs, setAvoidNegativeTs, autoDeleteMergedSegments, exportConfirmEnabled, toggleExportConfirmEnabled, segmentsToChapters, toggleSegmentsToChapters, preserveMetadataOnMerge, togglePreserveMetadataOnMerge, enableSmartCut, setEnableSmartCut, effectiveExportMode, enableOverwriteOutput, setEnableOverwriteOutput, ffmpegExperimental, setFfmpegExperimental } = useUserSettings(); const isMov = ffmpegIsMov(outFormat); const isIpod = outFormat === 'ipod'; @@ -109,6 +109,10 @@ const ExportConfirm = memo(({ toast.fire({ icon: 'info', timer: 10000, text: `${avoidNegativeTs}: ${texts[avoidNegativeTs]}` }); }, [avoidNegativeTs]); + const onFfmpegExperimentalHelpPress = useCallback(() => { + toast.fire({ icon: 'info', timer: 10000, text: t('Enable experimental ffmpeg features flag?') }); + }, [t]); + const canEditTemplate = !willMerge || !autoDeleteMergedSegments; // https://stackoverflow.com/questions/33454533/cant-scroll-to-top-of-flex-item-that-is-overflowing-container @@ -148,10 +152,14 @@ const ExportConfirm = memo(({ - {effectiveExportMode === 'sesgments_to_chapters' && } - + {effectiveExportMode === 'sesgments_to_chapters' ? ( + + ) : ( + + )} + {t('Output container format:')} @@ -163,6 +171,7 @@ const ExportConfirm = memo(({ + Input has {{ numStreamsTotal }} tracks @@ -174,10 +183,14 @@ const ExportConfirm = memo(({ Keeping {{ numStreamsToCopy }} tracks - {areWeCuttingProblematicStreams && } - + {areWeCuttingProblematicStreams ? ( + + ) : ( + + )} + {t('Save output to path:')} @@ -226,6 +239,7 @@ const ExportConfirm = memo(({ +

{t('Advanced options')}

@@ -243,6 +257,7 @@ const ExportConfirm = memo(({ + + {!needSmartCut && ( )} @@ -304,11 +326,17 @@ const ExportConfirm = memo(({ + @@ -340,11 +371,26 @@ const ExportConfirm = memo(({ )} + + + + + +
{t('Preserve original metadata when merging? (slow)')} @@ -274,10 +289,14 @@ const ExportConfirm = memo(({ setEnableSmartCut((v) => !v)} /> - {needSmartCut && } - + {needSmartCut ? ( + + ) : ( + + )}
@@ -288,8 +307,11 @@ const ExportConfirm = memo(({ toggleKeyframeCut()} /> - {!keyframeCut && } - + {!keyframeCut ? ( + + ) : ( + + )}
+ {isIpod && !movFastStart &&
{t('For the ipod format, it is recommended to activate this option')}
}
- {isIpod && !movFastStart && {t('For the ipod format, it is recommended to activate this option')}} + {isIpod && !movFastStart ? ( + + ) : ( + + )}
{t('Preserve all MP4/MOV metadata?')} @@ -318,8 +346,11 @@ const ExportConfirm = memo(({ - {isIpod && preserveMovData && } - + {isIpod && preserveMovData ? ( + + ) : ( + + )}
- {!['make_zero', 'auto'].includes(avoidNegativeTs) && } - + {!['make_zero', 'auto'].includes(avoidNegativeTs) ? ( + + ) : ( + + )}
+ {t('"ffmpeg" experimental flag')} + + + + +
@@ -357,7 +403,7 @@ const ExportConfirm = memo(({ animate={{ opacity: 1, translateX: 0 }} exit={{ opacity: 0, translateX: 50 }} transition={{ duration: 0.4, easings: ['easeOut'] }} - style={{ display: 'flex', alignItems: 'flex-end' }} + style={{ display: 'flex', alignItems: 'flex-end', background: 'rgba(0,0,0,0.5)' }} >
{t('Show this page before exporting?')}
diff --git a/src/components/ExportConfirm.module.css b/src/components/ExportConfirm.module.css index b068fb4f..cd446175 100644 --- a/src/components/ExportConfirm.module.css +++ b/src/components/ExportConfirm.module.css @@ -28,14 +28,15 @@ table.options { width: 100%; } -table.options td:last-child { - text-align: right; - width: 3em; -} table.options td:nth-child(2) { text-align: right; } +table.options td:last-child { + text-align: center; + width: 1.7em; +} + table.options td { vertical-align: top; } \ No newline at end of file diff --git a/src/components/OutSegTemplateEditor.jsx b/src/components/OutSegTemplateEditor.jsx index 43c9ccfa..9521a3c1 100644 --- a/src/components/OutSegTemplateEditor.jsx +++ b/src/components/OutSegTemplateEditor.jsx @@ -120,7 +120,7 @@ const OutSegTemplateEditor = memo(({ outSegTemplate, setOutSegTemplate, generate {outSegFileNames != null && } - +
@@ -134,11 +134,16 @@ const OutSegTemplateEditor = memo(({ outSegTemplate, setOutSegTemplate, generate {error != null &&
{i18n.t('There is an error in the file name template:')} {error}
} - {isMissingExtension &&
{i18n.t('The file name template is missing {{ext}} and will result in a file without the suggested extension. This may result in an unplayable output file.', { ext: extVar })}
} + {isMissingExtension && ( +
+ {' '} + {i18n.t('The file name template is missing {{ext}} and will result in a file without the suggested extension. This may result in an unplayable output file.', { ext: extVar })} +
+ )} {hasTextNumericPaddedValue && (
- setOutputFileNameMinZeroPadding(parseInt(e.target.value, 10))} style={{ marginRight: '1em', fontSize: '1em' }}> {Array.from({ length: 10 }).map((v, i) => i + 1).map((v) => )} Minimum numeric padded length @@ -149,7 +154,7 @@ const OutSegTemplateEditor = memo(({ outSegTemplate, setOutSegTemplate, generate {t('Sanitize file names')} - {!safeOutputFileName && } + {!safeOutputFileName && }
)} diff --git a/src/components/Settings.jsx b/src/components/Settings.jsx index a02b9a05..336ae72a 100644 --- a/src/components/Settings.jsx +++ b/src/components/Settings.jsx @@ -49,7 +49,7 @@ const Settings = memo(({ const { t } = useTranslation(); const [showAdvanced, setShowAdvanced] = useState(!simpleMode); - const { customOutDir, changeOutDir, keyframeCut, toggleKeyframeCut, timecodeFormat, setTimecodeFormat, invertCutSegments, setInvertCutSegments, askBeforeClose, setAskBeforeClose, enableAskForImportChapters, setEnableAskForImportChapters, enableAskForFileOpenAction, setEnableAskForFileOpenAction, autoSaveProjectFile, setAutoSaveProjectFile, invertTimelineScroll, setInvertTimelineScroll, language, setLanguage, ffmpegExperimental, setFfmpegExperimental, hideNotifications, setHideNotifications, autoLoadTimecode, setAutoLoadTimecode, enableAutoHtml5ify, setEnableAutoHtml5ify, customFfPath, setCustomFfPath, storeProjectInWorkingDir, mouseWheelZoomModifierKey, setMouseWheelZoomModifierKey, captureFrameMethod, setCaptureFrameMethod, captureFrameQuality, setCaptureFrameQuality, captureFrameFileNameFormat, setCaptureFrameFileNameFormat, enableNativeHevc, setEnableNativeHevc, enableUpdateCheck, setEnableUpdateCheck, allowMultipleInstances, setAllowMultipleInstances, preferStrongColors, setPreferStrongColors, treatInputFileModifiedTimeAsStart, setTreatInputFileModifiedTimeAsStart, treatOutputFileModifiedTimeAsStart, setTreatOutputFileModifiedTimeAsStart, exportConfirmEnabled, toggleExportConfirmEnabled } = useUserSettings(); + const { customOutDir, changeOutDir, keyframeCut, toggleKeyframeCut, timecodeFormat, setTimecodeFormat, invertCutSegments, setInvertCutSegments, askBeforeClose, setAskBeforeClose, enableAskForImportChapters, setEnableAskForImportChapters, enableAskForFileOpenAction, setEnableAskForFileOpenAction, autoSaveProjectFile, setAutoSaveProjectFile, invertTimelineScroll, setInvertTimelineScroll, language, setLanguage, hideNotifications, setHideNotifications, autoLoadTimecode, setAutoLoadTimecode, enableAutoHtml5ify, setEnableAutoHtml5ify, customFfPath, setCustomFfPath, storeProjectInWorkingDir, mouseWheelZoomModifierKey, setMouseWheelZoomModifierKey, captureFrameMethod, setCaptureFrameMethod, captureFrameQuality, setCaptureFrameQuality, captureFrameFileNameFormat, setCaptureFrameFileNameFormat, enableNativeHevc, setEnableNativeHevc, enableUpdateCheck, setEnableUpdateCheck, allowMultipleInstances, setAllowMultipleInstances, preferStrongColors, setPreferStrongColors, treatInputFileModifiedTimeAsStart, setTreatInputFileModifiedTimeAsStart, treatOutputFileModifiedTimeAsStart, setTreatOutputFileModifiedTimeAsStart, exportConfirmEnabled, toggleExportConfirmEnabled } = useUserSettings(); const onLangChange = useCallback((e) => { const { value } = e.target; @@ -252,15 +252,6 @@ const Settings = memo(({ - {showAdvanced && ( - - {t('Enable experimental ffmpeg features flag?')} - - - - - )} - {showAdvanced && ( diff --git a/src/util.js b/src/util.js index a07f5ad0..24be5d2f 100644 --- a/src/util.js +++ b/src/util.js @@ -144,7 +144,7 @@ export function filenamify(name) { export function withBlur(cb) { return (e) => { cb(e); - e.target.blur(); + e.target?.blur(); }; }