mirror of
https://github.com/mifi/lossless-cut.git
synced 2024-11-21 18:02:35 +01:00
improve settings
This commit is contained in:
parent
52f615421f
commit
7463049ee5
@ -2847,7 +2847,7 @@ function App() {
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<ExportConfirm areWeCutting={areWeCutting} nonFilteredSegmentsOrInverse={nonFilteredSegmentsOrInverse} selectedSegments={selectedSegmentsOrInverse} segmentsToExport={segmentsToExport} willMerge={willMerge} visible={exportConfirmVisible} onClosePress={closeExportConfirm} onExportConfirm={onExportConfirm} renderOutFmt={renderOutFmt} outputDir={outputDir} numStreamsTotal={numStreamsTotal} numStreamsToCopy={numStreamsToCopy} onShowStreamsSelectorClick={handleShowStreamsSelectorClick} outFormat={fileFormat} setOutSegTemplate={setOutSegTemplate} outSegTemplate={outSegTemplateOrDefault} generateOutSegFileNames={generateOutSegFileNames} currentSegIndexSafe={currentSegIndexSafe} mainCopiedThumbnailStreams={mainCopiedThumbnailStreams} needSmartCut={needSmartCut} mergedOutFileName={mergedOutFileName} setMergedOutFileName={setMergedOutFileName} smartCutBitrate={smartCutBitrate} setSmartCutBitrate={setSmartCutBitrate} />
|
<ExportConfirm areWeCutting={areWeCutting} nonFilteredSegmentsOrInverse={nonFilteredSegmentsOrInverse} selectedSegments={selectedSegmentsOrInverse} segmentsToExport={segmentsToExport} willMerge={willMerge} visible={exportConfirmVisible} onClosePress={closeExportConfirm} onExportConfirm={onExportConfirm} renderOutFmt={renderOutFmt} outputDir={outputDir} numStreamsTotal={numStreamsTotal} numStreamsToCopy={numStreamsToCopy} onShowStreamsSelectorClick={handleShowStreamsSelectorClick} outFormat={fileFormat} setOutSegTemplate={setOutSegTemplate} outSegTemplate={outSegTemplateOrDefault} generateOutSegFileNames={generateOutSegFileNames} currentSegIndexSafe={currentSegIndexSafe} mainCopiedThumbnailStreams={mainCopiedThumbnailStreams} needSmartCut={needSmartCut} mergedOutFileName={mergedOutFileName} setMergedOutFileName={setMergedOutFileName} smartCutBitrate={smartCutBitrate} setSmartCutBitrate={setSmartCutBitrate} toggleSettings={toggleSettings} />
|
||||||
|
|
||||||
<Sheet visible={streamsSelectorShown} onClosePress={() => setStreamsSelectorShown(false)} maxWidth={1000}>
|
<Sheet visible={streamsSelectorShown} onClosePress={() => setStreamsSelectorShown(false)} maxWidth={1000}>
|
||||||
{mainStreams && filePath != null && (
|
{mainStreams && filePath != null && (
|
||||||
|
@ -4,7 +4,7 @@ import { WarningSignIcon, CrossIcon } from 'evergreen-ui';
|
|||||||
import { FaRegCheckCircle } from 'react-icons/fa';
|
import { FaRegCheckCircle } from 'react-icons/fa';
|
||||||
import i18n from 'i18next';
|
import i18n from 'i18next';
|
||||||
import { useTranslation, Trans } from 'react-i18next';
|
import { useTranslation, Trans } from 'react-i18next';
|
||||||
import { IoIosHelpCircle } from 'react-icons/io';
|
import { IoIosHelpCircle, IoIosSettings } from 'react-icons/io';
|
||||||
import type { SweetAlertIcon } from 'sweetalert2';
|
import type { SweetAlertIcon } from 'sweetalert2';
|
||||||
|
|
||||||
import ExportButton from './ExportButton';
|
import ExportButton from './ExportButton';
|
||||||
@ -64,6 +64,7 @@ function ExportConfirm({
|
|||||||
setMergedOutFileName,
|
setMergedOutFileName,
|
||||||
smartCutBitrate,
|
smartCutBitrate,
|
||||||
setSmartCutBitrate,
|
setSmartCutBitrate,
|
||||||
|
toggleSettings,
|
||||||
} : {
|
} : {
|
||||||
areWeCutting: boolean,
|
areWeCutting: boolean,
|
||||||
selectedSegments: InverseCutSegment[],
|
selectedSegments: InverseCutSegment[],
|
||||||
@ -89,6 +90,7 @@ function ExportConfirm({
|
|||||||
setMergedOutFileName: (a: string) => void,
|
setMergedOutFileName: (a: string) => void,
|
||||||
smartCutBitrate: number | undefined,
|
smartCutBitrate: number | undefined,
|
||||||
setSmartCutBitrate: Dispatch<SetStateAction<number | undefined>>,
|
setSmartCutBitrate: Dispatch<SetStateAction<number | undefined>>,
|
||||||
|
toggleSettings: () => void,
|
||||||
}) {
|
}) {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
|
||||||
@ -151,6 +153,7 @@ function ExportConfirm({
|
|||||||
|
|
||||||
const onAvoidNegativeTsHelpPress = useCallback(() => {
|
const onAvoidNegativeTsHelpPress = useCallback(() => {
|
||||||
// https://ffmpeg.org/ffmpeg-all.html#Format-Options
|
// https://ffmpeg.org/ffmpeg-all.html#Format-Options
|
||||||
|
// https://github.com/mifi/lossless-cut/issues/1206
|
||||||
const texts = {
|
const texts = {
|
||||||
make_non_negative: i18n.t('Shift timestamps to make them non-negative. Also note that this affects only leading negative timestamps, and not non-monotonic negative timestamps.'),
|
make_non_negative: i18n.t('Shift timestamps to make them non-negative. Also note that this affects only leading negative timestamps, and not non-monotonic negative timestamps.'),
|
||||||
make_zero: i18n.t('Shift timestamps so that the first timestamp is 0. (LosslessCut default)'),
|
make_zero: i18n.t('Shift timestamps so that the first timestamp is 0. (LosslessCut default)'),
|
||||||
@ -309,6 +312,61 @@ function ExportConfirm({
|
|||||||
|
|
||||||
<table className={styles['options']}>
|
<table className={styles['options']}>
|
||||||
<tbody>
|
<tbody>
|
||||||
|
|
||||||
|
{areWeCutting && (
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
{t('Shift all start times')}
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<Select value={cutFromAdjustmentFrames} onChange={(e) => setCutFromAdjustmentFrames(Number(e.target.value))} style={{ height: 20, marginLeft: 5 }}>
|
||||||
|
{[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10].map((v) => <option key={v} value={v}>{t('+{{numFrames}} frames', { numFrames: v, count: v })}</option>)}
|
||||||
|
</Select>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<HelpIcon onClick={onCutFromAdjustmentFramesHelpPress} />
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{isMov && (
|
||||||
|
<>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
{t('Enable MOV Faststart?')}
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<MovFastStartButton />
|
||||||
|
{isIpod && !movFastStart && <div style={warningStyle}>{t('For the ipod format, it is recommended to activate this option')}</div>}
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
{isIpod && !movFastStart ? (
|
||||||
|
<WarningSignIcon verticalAlign="middle" color="warning" />
|
||||||
|
) : (
|
||||||
|
<HelpIcon onClick={onMovFastStartHelpPress} />
|
||||||
|
)}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
{t('Preserve all MP4/MOV metadata?')}
|
||||||
|
{isIpod && preserveMovData && <div style={warningStyle}>{t('For the ipod format, it is recommended to deactivate this option')}</div>}
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<PreserveMovDataButton />
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
{isIpod && preserveMovData ? (
|
||||||
|
<WarningSignIcon verticalAlign="middle" color="warning" />
|
||||||
|
) : (
|
||||||
|
<HelpIcon onClick={onPreserveMovDataHelpPress} />
|
||||||
|
)}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
|
||||||
{willMerge && (
|
{willMerge && (
|
||||||
<>
|
<>
|
||||||
<tr>
|
<tr>
|
||||||
@ -403,60 +461,6 @@ function ExportConfirm({
|
|||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{areWeCutting && (
|
|
||||||
<tr>
|
|
||||||
<td>
|
|
||||||
{t('Shift all start times')}
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<Select value={cutFromAdjustmentFrames} onChange={(e) => setCutFromAdjustmentFrames(Number(e.target.value))} style={{ height: 20, marginLeft: 5 }}>
|
|
||||||
{[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10].map((v) => <option key={v} value={v}>{t('+{{numFrames}} frames', { numFrames: v, count: v })}</option>)}
|
|
||||||
</Select>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<HelpIcon onClick={onCutFromAdjustmentFramesHelpPress} />
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
)}
|
|
||||||
|
|
||||||
{isMov && (
|
|
||||||
<>
|
|
||||||
<tr>
|
|
||||||
<td>
|
|
||||||
{t('Enable MOV Faststart?')}
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<MovFastStartButton />
|
|
||||||
{isIpod && !movFastStart && <div style={warningStyle}>{t('For the ipod format, it is recommended to activate this option')}</div>}
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
{isIpod && !movFastStart ? (
|
|
||||||
<WarningSignIcon verticalAlign="middle" color="warning" />
|
|
||||||
) : (
|
|
||||||
<HelpIcon onClick={onMovFastStartHelpPress} />
|
|
||||||
)}
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
|
|
||||||
<tr>
|
|
||||||
<td>
|
|
||||||
{t('Preserve all MP4/MOV metadata?')}
|
|
||||||
{isIpod && preserveMovData && <div style={warningStyle}>{t('For the ipod format, it is recommended to deactivate this option')}</div>}
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<PreserveMovDataButton />
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
{isIpod && preserveMovData ? (
|
|
||||||
<WarningSignIcon verticalAlign="middle" color="warning" />
|
|
||||||
) : (
|
|
||||||
<HelpIcon onClick={onPreserveMovDataHelpPress} />
|
|
||||||
)}
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</>
|
|
||||||
)}
|
|
||||||
|
|
||||||
{!needSmartCut && (() => {
|
{!needSmartCut && (() => {
|
||||||
const avoidNegativeTsWarn = (() => {
|
const avoidNegativeTsWarn = (() => {
|
||||||
if (willMerge) {
|
if (willMerge) {
|
||||||
@ -474,7 +478,7 @@ function ExportConfirm({
|
|||||||
return (
|
return (
|
||||||
<tr>
|
<tr>
|
||||||
<td>
|
<td>
|
||||||
{`"${'avoid_negative_ts'}"`}
|
"ffmpeg" <code className="highlighted">avoid_negative_ts</code>
|
||||||
{avoidNegativeTsWarn != null && <div style={warningStyle}>{avoidNegativeTsWarn}</div>}
|
{avoidNegativeTsWarn != null && <div style={warningStyle}>{avoidNegativeTsWarn}</div>}
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
@ -507,6 +511,16 @@ function ExportConfirm({
|
|||||||
<HelpIcon onClick={onFfmpegExperimentalHelpPress} />
|
<HelpIcon onClick={onFfmpegExperimentalHelpPress} />
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
{t('More settings')}
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<IoIosSettings size={24} role="button" onClick={toggleSettings} style={{ marginLeft: 5 }} />
|
||||||
|
</td>
|
||||||
|
<td />
|
||||||
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
|
@ -103,13 +103,6 @@ function Settings({
|
|||||||
</thead>
|
</thead>
|
||||||
|
|
||||||
<tbody>
|
<tbody>
|
||||||
<Row>
|
|
||||||
<KeyCell>{t('Show advanced settings')}</KeyCell>
|
|
||||||
<td>
|
|
||||||
<Switch checked={showAdvanced} onCheckedChange={setShowAdvanced} />
|
|
||||||
</td>
|
|
||||||
</Row>
|
|
||||||
|
|
||||||
<Row>
|
<Row>
|
||||||
<KeyCell><GlobeIcon style={{ verticalAlign: 'middle', marginRight: '.5em' }} /> App language</KeyCell>
|
<KeyCell><GlobeIcon style={{ verticalAlign: 'middle', marginRight: '.5em' }} /> App language</KeyCell>
|
||||||
<td>
|
<td>
|
||||||
@ -120,6 +113,30 @@ function Settings({
|
|||||||
</td>
|
</td>
|
||||||
</Row>
|
</Row>
|
||||||
|
|
||||||
|
<Row>
|
||||||
|
<KeyCell>
|
||||||
|
{t('Show advanced settings')}
|
||||||
|
<div style={detailsStyle}>
|
||||||
|
{!showAdvanced && t('Advanced settings are currently not visible.')}
|
||||||
|
</div>
|
||||||
|
</KeyCell>
|
||||||
|
<td>
|
||||||
|
<Switch checked={showAdvanced} onCheckedChange={setShowAdvanced} />
|
||||||
|
</td>
|
||||||
|
</Row>
|
||||||
|
|
||||||
|
<Row>
|
||||||
|
<KeyCell>
|
||||||
|
{t('Show export options screen before exporting?')}
|
||||||
|
<div style={detailsStyle}>
|
||||||
|
{t('This gives you an overview of the export and allows you to customise more parameters before exporting.')}
|
||||||
|
</div>
|
||||||
|
</KeyCell>
|
||||||
|
<td>
|
||||||
|
<Switch checked={exportConfirmEnabled} onCheckedChange={toggleExportConfirmEnabled} />
|
||||||
|
</td>
|
||||||
|
</Row>
|
||||||
|
|
||||||
{showAdvanced && (
|
{showAdvanced && (
|
||||||
<Row>
|
<Row>
|
||||||
<KeyCell>
|
<KeyCell>
|
||||||
@ -184,12 +201,15 @@ function Settings({
|
|||||||
<KeyCell>
|
<KeyCell>
|
||||||
{t('Choose cutting mode: Remove or keep selected segments from video when exporting?')}<br />
|
{t('Choose cutting mode: Remove or keep selected segments from video when exporting?')}<br />
|
||||||
<div style={detailsStyle}>
|
<div style={detailsStyle}>
|
||||||
<b>{t('Keep')}</b>: {t('The video inside segments will be kept, while the video outside will be discarded.')}<br />
|
{invertCutSegments ? (
|
||||||
<b>{t('Remove')}</b>: {t('The video inside segments will be discarded, while the video surrounding them will be kept.')}
|
<><b>{t('Remove')}</b>: {t('The video inside segments will be discarded, while the video surrounding them will be kept.')}</>
|
||||||
|
) : (
|
||||||
|
<><b>{t('Keep')}</b>: {t('The video inside segments will be kept, while the video outside will be discarded.')}</>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
</KeyCell>
|
</KeyCell>
|
||||||
<td>
|
<td>
|
||||||
<Button iconBefore={FaYinYang} appearance={invertCutSegments ? 'default' : 'primary'} intent="success" onClick={() => setInvertCutSegments((v) => !v)}>
|
<Button iconBefore={FaYinYang} appearance="primary" intent={invertCutSegments ? 'danger' : 'success'} onClick={() => setInvertCutSegments((v) => !v)}>
|
||||||
{invertCutSegments ? t('Remove') : t('Keep')}
|
{invertCutSegments ? t('Remove') : t('Keep')}
|
||||||
</Button>
|
</Button>
|
||||||
</td>
|
</td>
|
||||||
@ -203,10 +223,10 @@ function Settings({
|
|||||||
</div>
|
</div>
|
||||||
</KeyCell>
|
</KeyCell>
|
||||||
<td>
|
<td>
|
||||||
|
<div>{customOutDir}</div>
|
||||||
<Button iconBefore={customOutDir ? FolderCloseIcon : DocumentIcon} onClick={changeOutDir}>
|
<Button iconBefore={customOutDir ? FolderCloseIcon : DocumentIcon} onClick={changeOutDir}>
|
||||||
{customOutDir ? t('Custom working directory') : t('Same directory as input file')}...
|
{customOutDir ? t('Custom working directory') : t('Same directory as input file')}...
|
||||||
</Button>
|
</Button>
|
||||||
<div>{customOutDir}</div>
|
|
||||||
{customOutDir && (
|
{customOutDir && (
|
||||||
<Button
|
<Button
|
||||||
height={20}
|
height={20}
|
||||||
@ -250,13 +270,13 @@ function Settings({
|
|||||||
<div style={detailsStyle}>
|
<div style={detailsStyle}>
|
||||||
{keyframeCut ? (
|
{keyframeCut ? (
|
||||||
<>
|
<>
|
||||||
{t('Cut at the nearest keyframe (not accurate time.) Equiv to')}:<br />
|
<b>{t('Keyframe cut')}</b>: {t('Cut at the nearest keyframe (not accurate time.) Equiv to')}:<br />
|
||||||
<code className="highlighted">ffmpeg -ss -i ...</code>
|
<code className="highlighted">ffmpeg -ss -i input.mp4</code>
|
||||||
</>
|
</>
|
||||||
) : (
|
) : (
|
||||||
<>
|
<>
|
||||||
{t('Accurate time but could leave an empty portion at the beginning of the video. Equiv to')}:<br />
|
<b>{t('Normal cut')}</b>: {t('Accurate time but could leave an empty portion at the beginning of the video. Equiv to')}:<br />
|
||||||
<code className="highlighted">ffmpeg -i -ss ...</code>
|
<code className="highlighted">ffmpeg -i -ss input.mp4</code>
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
@ -299,17 +319,19 @@ function Settings({
|
|||||||
</td>
|
</td>
|
||||||
</Row>
|
</Row>
|
||||||
|
|
||||||
<Row>
|
{showAdvanced && (
|
||||||
<KeyCell>
|
<Row>
|
||||||
{t('Snapshot capture method')}
|
<KeyCell>
|
||||||
<div style={detailsStyle}>{t('FFmpeg capture method might sometimes capture more correct colors, but the captured snapshot might be off by one or more frames, relative to the preview.')}</div>
|
{t('Snapshot capture method')}
|
||||||
</KeyCell>
|
<div style={detailsStyle}>{t('FFmpeg capture method might sometimes capture more correct colors, but the captured snapshot might be off by one or more frames, relative to the preview.')}</div>
|
||||||
<td>
|
</KeyCell>
|
||||||
<Button onClick={() => setCaptureFrameMethod((existing) => (existing === 'ffmpeg' ? 'videotag' : 'ffmpeg'))}>
|
<td>
|
||||||
{captureFrameMethod === 'ffmpeg' ? t('FFmpeg') : t('HTML video tag')}
|
<Button onClick={() => setCaptureFrameMethod((existing) => (existing === 'ffmpeg' ? 'videotag' : 'ffmpeg'))}>
|
||||||
</Button>
|
{captureFrameMethod === 'ffmpeg' ? t('FFmpeg') : t('HTML video tag')}
|
||||||
</td>
|
</Button>
|
||||||
</Row>
|
</td>
|
||||||
|
</Row>
|
||||||
|
)}
|
||||||
|
|
||||||
<Row>
|
<Row>
|
||||||
<KeyCell>{t('Snapshot capture quality')}</KeyCell>
|
<KeyCell>{t('Snapshot capture quality')}</KeyCell>
|
||||||
@ -319,14 +341,16 @@ function Settings({
|
|||||||
</td>
|
</td>
|
||||||
</Row>
|
</Row>
|
||||||
|
|
||||||
<Row>
|
{showAdvanced && (
|
||||||
<KeyCell>{t('File names of extracted video frames')}</KeyCell>
|
<Row>
|
||||||
<td>
|
<KeyCell>{t('File names of extracted video frames')}</KeyCell>
|
||||||
<Button iconBefore={captureFrameFileNameFormat === 'timestamp' ? TimeIcon : NumericalIcon} onClick={() => setCaptureFrameFileNameFormat((existing) => (existing === 'timestamp' ? 'index' : 'timestamp'))}>
|
<td>
|
||||||
{captureFrameFileNameFormat === 'timestamp' ? t('Frame timestamp') : t('Frame number')}
|
<Button iconBefore={captureFrameFileNameFormat === 'timestamp' ? TimeIcon : NumericalIcon} onClick={() => setCaptureFrameFileNameFormat((existing) => (existing === 'timestamp' ? 'index' : 'timestamp'))}>
|
||||||
</Button>
|
{captureFrameFileNameFormat === 'timestamp' ? t('Frame timestamp') : t('Frame number')}
|
||||||
</td>
|
</Button>
|
||||||
</Row>
|
</td>
|
||||||
|
</Row>
|
||||||
|
)}
|
||||||
|
|
||||||
|
|
||||||
<Header title={t('Keyboard, mouse and input')} />
|
<Header title={t('Keyboard, mouse and input')} />
|
||||||
@ -391,6 +415,7 @@ function Settings({
|
|||||||
</td>
|
</td>
|
||||||
</Row>
|
</Row>
|
||||||
|
|
||||||
|
|
||||||
<Header title={t('User interface')} />
|
<Header title={t('User interface')} />
|
||||||
|
|
||||||
{showAdvanced && (
|
{showAdvanced && (
|
||||||
@ -421,6 +446,13 @@ function Settings({
|
|||||||
</Row>
|
</Row>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
<Row>
|
||||||
|
<KeyCell>{t('Prefer strong colors')}</KeyCell>
|
||||||
|
<td>
|
||||||
|
<Switch checked={preferStrongColors} onCheckedChange={setPreferStrongColors} />
|
||||||
|
</td>
|
||||||
|
</Row>
|
||||||
|
|
||||||
<Row>
|
<Row>
|
||||||
<KeyCell>{t('In timecode show')}</KeyCell>
|
<KeyCell>{t('In timecode show')}</KeyCell>
|
||||||
<td>
|
<td>
|
||||||
@ -430,22 +462,9 @@ function Settings({
|
|||||||
</td>
|
</td>
|
||||||
</Row>
|
</Row>
|
||||||
|
|
||||||
<Row>
|
|
||||||
<KeyCell>{t('Prefer strong colors')}</KeyCell>
|
|
||||||
<td>
|
|
||||||
<Switch checked={preferStrongColors} onCheckedChange={setPreferStrongColors} />
|
|
||||||
</td>
|
|
||||||
</Row>
|
|
||||||
|
|
||||||
<Header title={t('Prompts and dialogs')} />
|
<Header title={t('Prompts and dialogs')} />
|
||||||
|
|
||||||
<Row>
|
|
||||||
<KeyCell>{t('Show export options screen before exporting?')}</KeyCell>
|
|
||||||
<td>
|
|
||||||
<Switch checked={exportConfirmEnabled} onCheckedChange={toggleExportConfirmEnabled} />
|
|
||||||
</td>
|
|
||||||
</Row>
|
|
||||||
|
|
||||||
<Row>
|
<Row>
|
||||||
<KeyCell>{t('Show notifications')}</KeyCell>
|
<KeyCell>{t('Show notifications')}</KeyCell>
|
||||||
<td>
|
<td>
|
||||||
|
Loading…
Reference in New Issue
Block a user