|
|
|
|
@ -66,7 +66,7 @@ function renderNoticeIcon(notice: { warning?: boolean | undefined } | undefined,
|
|
|
|
|
return notice.warning ? (
|
|
|
|
|
<FaExclamationTriangle style={{ flexShrink: '0', fontSize: '.8em', verticalAlign: 'baseline', color: warningColor, ...style }} />
|
|
|
|
|
) : (
|
|
|
|
|
<FaInfoCircle style={{ flexShrink: '0', fontSize: '.8em', verticalAlign: 'baseline', color: 'var(--blue-10)', ...style }} />
|
|
|
|
|
<FaInfoCircle style={{ flexShrink: '0', fontSize: '.8em', verticalAlign: 'baseline', color: 'var(--cyan-10)', ...style }} />
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@ -81,17 +81,39 @@ interface GenericNotice {
|
|
|
|
|
url?: string,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function renderNotice(notice: Notice | GenericNotice | undefined, { style }: { style?: CSSProperties }) {
|
|
|
|
|
if (notice == null) return null;
|
|
|
|
|
const { warning, text } = notice;
|
|
|
|
|
const url = 'url' in notice ? notice.url : undefined;
|
|
|
|
|
function Notice({ notice }: { notice: Notice | GenericNotice }) {
|
|
|
|
|
const { text, warning } = notice;
|
|
|
|
|
return (
|
|
|
|
|
<div key={typeof notice.text === 'string' ? notice.text : undefined} style={{ ...(warning ? warningStyle : infoStyle), display: 'flex', alignItems: 'center', gap: '0 .5em', ...style }}>
|
|
|
|
|
{renderNoticeIcon({ warning }, { fontSize: '1em', flexShrink: 0 })} <span style={{ fontSize: '.9em' }}>{text}</span>{url != null && <IoIosHelpCircle style={{ cursor: 'pointer', fontSize: '1.5em', flexShrink: 0, color: primaryTextColor }} title={i18n.t('Learn more')} role="button" tabIndex={0} onClick={() => shell.openExternal(url)} />}
|
|
|
|
|
<div style={{ ...(warning ? warningStyle : infoStyle), display: 'flex', alignItems: 'center', gap: '0 .5em' }}>
|
|
|
|
|
{renderNoticeIcon({ warning }, { fontSize: '1em', flexShrink: 0 })}
|
|
|
|
|
{' '}
|
|
|
|
|
<span style={{ fontSize: '.9em' }}>{text}</span>
|
|
|
|
|
</div>
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function renderNotice(notice: Notice | undefined) {
|
|
|
|
|
if (notice == null) return null;
|
|
|
|
|
const { text } = notice;
|
|
|
|
|
return (
|
|
|
|
|
<Notice notice={notice} key={typeof text === 'string' ? text : undefined} />
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function renderGenericNotice(notice: GenericNotice) {
|
|
|
|
|
const { url } = notice;
|
|
|
|
|
return (
|
|
|
|
|
<tr key={notice.text}>
|
|
|
|
|
<td colSpan={2}>
|
|
|
|
|
<Notice notice={notice} />
|
|
|
|
|
</td>
|
|
|
|
|
<td>
|
|
|
|
|
{url != null && <IoIosHelpCircle style={{ cursor: 'pointer', fontSize: '1.5em', flexShrink: 0, color: primaryTextColor }} title={i18n.t('Learn more')} role="button" tabIndex={0} onClick={() => shell.openExternal(url)} />}
|
|
|
|
|
</td>
|
|
|
|
|
</tr>
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function ExportConfirm({
|
|
|
|
|
areWeCutting,
|
|
|
|
|
segmentsToExport,
|
|
|
|
|
@ -345,12 +367,7 @@ function ExportConfirm({
|
|
|
|
|
>
|
|
|
|
|
<table className={styles['options']}>
|
|
|
|
|
<tbody>
|
|
|
|
|
<tr>
|
|
|
|
|
<td colSpan={2}>
|
|
|
|
|
{notices.generic.map((notice) => renderNotice(notice, {}))}
|
|
|
|
|
</td>
|
|
|
|
|
<td />
|
|
|
|
|
</tr>
|
|
|
|
|
{notices.generic.map((notice) => renderGenericNotice(notice))}
|
|
|
|
|
|
|
|
|
|
{segmentsOrInverse.selected.length !== segmentsOrInverse.all.length && (
|
|
|
|
|
<tr>
|
|
|
|
|
@ -364,7 +381,7 @@ function ExportConfirm({
|
|
|
|
|
<tr>
|
|
|
|
|
<td>
|
|
|
|
|
{segmentsOrInverse.selected.length > 1 ? t('Export mode for {{segments}} segments', { segments: segmentsOrInverse.selected.length }) : t('Export mode')}
|
|
|
|
|
{renderNotice(notices.specific['exportMode'], {})}
|
|
|
|
|
{renderNotice(notices.specific['exportMode'])}
|
|
|
|
|
</td>
|
|
|
|
|
<td>
|
|
|
|
|
<ExportModeButton selectedSegments={segmentsOrInverse.selected} style={{ height: '1.8em' }} />
|
|
|
|
|
@ -389,7 +406,7 @@ function ExportConfirm({
|
|
|
|
|
<tr>
|
|
|
|
|
<td>
|
|
|
|
|
<Trans>Input has {{ numStreamsTotal }} tracks</Trans>
|
|
|
|
|
{renderNotice(notices.specific['problematicStreams'], {})}
|
|
|
|
|
{renderNotice(notices.specific['problematicStreams'])}
|
|
|
|
|
</td>
|
|
|
|
|
<td>
|
|
|
|
|
<HighlightedText style={{ cursor: 'pointer' }} onClick={onShowStreamsSelectorClick}><Trans>Keeping {{ numStreamsToCopy }} tracks</Trans></HighlightedText>
|
|
|
|
|
@ -436,7 +453,7 @@ function ExportConfirm({
|
|
|
|
|
<tr>
|
|
|
|
|
<td>
|
|
|
|
|
{t('Overwrite existing files')}
|
|
|
|
|
{renderNotice(notices.specific['overwriteOutput'], {})}
|
|
|
|
|
{renderNotice(notices.specific['overwriteOutput'])}
|
|
|
|
|
</td>
|
|
|
|
|
<td>
|
|
|
|
|
<Switch checked={enableOverwriteOutput} onCheckedChange={setEnableOverwriteOutput} />
|
|
|
|
|
@ -504,7 +521,7 @@ function ExportConfirm({
|
|
|
|
|
</td>
|
|
|
|
|
<td>
|
|
|
|
|
<Switch checked={movFastStart} onCheckedChange={toggleMovFastStart} />
|
|
|
|
|
{renderNotice(notices.specific['movFastStart'], {})}
|
|
|
|
|
{renderNotice(notices.specific['movFastStart'])}
|
|
|
|
|
</td>
|
|
|
|
|
<td>
|
|
|
|
|
{renderNoticeIcon(notices.specific['movFastStart'], rightIconStyle) ?? <HelpIcon onClick={onMovFastStartHelpPress} />}
|
|
|
|
|
@ -514,7 +531,7 @@ function ExportConfirm({
|
|
|
|
|
<AnimatedTr>
|
|
|
|
|
<td>
|
|
|
|
|
{t('Preserve all MP4/MOV metadata?')}
|
|
|
|
|
{renderNotice(notices.specific['preserveMovData'], {})}
|
|
|
|
|
{renderNotice(notices.specific['preserveMovData'])}
|
|
|
|
|
</td>
|
|
|
|
|
<td>
|
|
|
|
|
<Switch checked={preserveMovData} onCheckedChange={togglePreserveMovData} />
|
|
|
|
|
@ -587,7 +604,7 @@ function ExportConfirm({
|
|
|
|
|
<AnimatedTr>
|
|
|
|
|
<td>
|
|
|
|
|
{t('Smart cut (experimental):')}
|
|
|
|
|
{renderNotice(notices.specific['smartCut'], {})}
|
|
|
|
|
{renderNotice(notices.specific['smartCut'])}
|
|
|
|
|
</td>
|
|
|
|
|
<td>
|
|
|
|
|
<Switch checked={enableSmartCut} onCheckedChange={() => setEnableSmartCut((v) => !v)} />
|
|
|
|
|
@ -601,7 +618,7 @@ function ExportConfirm({
|
|
|
|
|
<AnimatedTr>
|
|
|
|
|
<td>
|
|
|
|
|
{t('Keyframe cut mode')}
|
|
|
|
|
{renderNotice(notices.specific['cutMode'], {})}
|
|
|
|
|
{renderNotice(notices.specific['cutMode'])}
|
|
|
|
|
</td>
|
|
|
|
|
<td>
|
|
|
|
|
<Switch checked={keyframeCut} onCheckedChange={() => toggleKeyframeCut()} />
|
|
|
|
|
@ -652,7 +669,7 @@ function ExportConfirm({
|
|
|
|
|
<AnimatedTr>
|
|
|
|
|
<td>
|
|
|
|
|
"ffmpeg" <code className="highlighted">avoid_negative_ts</code>
|
|
|
|
|
{renderNotice(notices.specific['avoidNegativeTs'], {})}
|
|
|
|
|
{renderNotice(notices.specific['avoidNegativeTs'])}
|
|
|
|
|
</td>
|
|
|
|
|
<td>
|
|
|
|
|
<Select value={avoidNegativeTs} onChange={(e) => setAvoidNegativeTs(e.target.value as AvoidNegativeTs)} style={{ height: 20, marginLeft: 5 }}>
|
|
|
|
|
|