refactor sheets

pull/471/head
Mikael Finstad 5 years ago
parent 85d88cf944
commit 806e270da6

@ -1,113 +1,101 @@
import React, { memo } from 'react'; import React, { memo } from 'react';
import { IoIosCloseCircleOutline } from 'react-icons/io';
import { FaClipboard, FaHandPointRight, FaHandPointLeft, FaStepBackward, FaStepForward } from 'react-icons/fa'; import { FaClipboard, FaHandPointRight, FaHandPointLeft, FaStepBackward, FaStepForward } from 'react-icons/fa';
import { motion, AnimatePresence } from 'framer-motion';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
import SetCutpointButton from './SetCutpointButton'; import SetCutpointButton from './SetCutpointButton';
import { toast } from './util'; import { toast } from './util';
import { primaryTextColor } from './colors'; import { primaryTextColor } from './colors';
import Sheet from './Sheet';
const electron = window.require('electron'); const electron = window.require('electron');
const { clipboard } = electron; const { clipboard } = electron;
const { githubLink } = electron.remote.require('./constants'); const { githubLink } = electron.remote.require('./constants');
const HelpSheet = memo(({ const HelpSheet = memo(({ visible, onTogglePress, ffmpegCommandLog, currentCutSeg }) => {
visible, onTogglePress, ffmpegCommandLog, currentCutSeg,
}) => {
const { t } = useTranslation(); const { t } = useTranslation();
return ( return (
<AnimatePresence> <Sheet visible={visible} onClosePress={onTogglePress} style={{ background: '#6b6b6b', color: 'white' }}>
{visible && ( <div className="help-sheet">
<motion.div <h1>{t('Common problems')}</h1>
initial={{ scale: 0, opacity: 0.5 }} <p>
animate={{ scale: 1, opacity: 1 }} {t('Lossless cutting is not an exact science. For some codecs and files it just works. For others you may need to trial and error depending on the codec, keyframes etc to get the best cut.')}
exit={{ scale: 0, opacity: 0 }} </p>
className="help-sheet" <ol>
> <li>Try both <b>Keyframe cut</b> and <b>Normal cut</b> modes</li>
<IoIosCloseCircleOutline role="button" onClick={onTogglePress} size={30} style={{ position: 'fixed', right: 0, top: 0, padding: 20 }} /> <li>Try to set the <b>start-</b>cutpoint a <b>few frames before or after</b> the nearest keyframe (may also solve audio sync issues)</li>
<li>Try to disable some <b>Tracks</b></li>
<h1>{t('Common problems')}</h1> <li>Try a different <b>Output format</b></li>
<p> <li>Try to enable the <b>Experimental Flag</b> in Settings</li>
{t('Lossless cutting is not an exact science. For some codecs and files it just works. For others you may need to trial and error depending on the codec, keyframes etc to get the best cut.')} </ol>
</p>
<ol> <p style={{ fontWeight: 'bold' }}>
<li>Try both <b>Keyframe cut</b> and <b>Normal cut</b> modes</li> {t('For more help and issues, please go to:')}<br />
<li>Try to set the <b>start-</b>cutpoint a <b>few frames before or after</b> the nearest keyframe (may also solve audio sync issues)</li> <span style={{ color: primaryTextColor, cursor: 'pointer' }} role="button" onClick={() => electron.shell.openExternal(githubLink)}>{githubLink}</span>
<li>Try to disable some <b>Tracks</b></li> </p>
<li>Try a different <b>Output format</b></li>
<li>Try to enable the <b>Experimental Flag</b> in Settings</li> <h1>{t('Keyboard & mouse shortcuts')}</h1>
</ol>
<div><kbd>H</kbd> {t('Show/hide help screen')}</div>
<p style={{ fontWeight: 'bold' }}>
{t('For more help and issues, please go to:')}<br /> <h2>{t('Playback')}</h2>
<span style={{ color: primaryTextColor, cursor: 'pointer' }} role="button" onClick={() => electron.shell.openExternal(githubLink)}>{githubLink}</span>
</p> <div><kbd>SPACE</kbd>, <kbd>k</kbd> {t('Play/pause')}</div>
<div><kbd>J</kbd> {t('Slow down playback')}</div>
<h1>{t('Keyboard & mouse shortcuts')}</h1> <div><kbd>L</kbd> {t('Speed up playback')}</div>
<div><kbd>H</kbd> {t('Show/hide help screen')}</div> <h2>{t('Seeking')}</h2>
<h2>{t('Playback')}</h2> <div><kbd>,</kbd> {t('Step backward 1 frame')}</div>
<div><kbd>.</kbd> {t('Step forward 1 frame')}</div>
<div><kbd>SPACE</kbd>, <kbd>k</kbd> {t('Play/pause')}</div> <div><kbd>ALT</kbd> / <kbd>OPT</kbd> + <kbd></kbd> {t('Seek to previous keyframe')}</div>
<div><kbd>J</kbd> {t('Slow down playback')}</div> <div><kbd>ALT</kbd> / <kbd>OPT</kbd> + <kbd></kbd> {t('Seek to next keyframe')}</div>
<div><kbd>L</kbd> {t('Speed up playback')}</div> <div><kbd></kbd> {t('Seek backward 1 sec')}</div>
<div><kbd></kbd> {t('Seek forward 1 sec')}</div>
<h2>{t('Seeking')}</h2> <div><kbd>CTRL</kbd> / <kbd>CMD</kbd> + <kbd></kbd> {t('Seek backward 1% of timeline at current zoom')}</div>
<div><kbd>CTRL</kbd> / <kbd>CMD</kbd> + <kbd></kbd> {t('Seek forward 1% of timeline at current zoom')}</div>
<div><kbd>,</kbd> {t('Step backward 1 frame')}</div> <div style={{ lineHeight: 1.7 }}><SetCutpointButton currentCutSeg={currentCutSeg} side="start" Icon={FaStepBackward} style={{ verticalAlign: 'middle' }} /> {t('Jump to cut end')}</div>
<div><kbd>.</kbd> {t('Step forward 1 frame')}</div> <div style={{ lineHeight: 1.7 }}><SetCutpointButton currentCutSeg={currentCutSeg} side="end" Icon={FaStepForward} style={{ verticalAlign: 'middle' }} /> {t('Jump to cut end')}</div>
<div><kbd>ALT</kbd> / <kbd>OPT</kbd> + <kbd></kbd> {t('Seek to previous keyframe')}</div>
<div><kbd>ALT</kbd> / <kbd>OPT</kbd> + <kbd></kbd> {t('Seek to next keyframe')}</div> <h2>{t('Segments and cut points')}</h2>
<div><kbd></kbd> {t('Seek backward 1 sec')}</div>
<div><kbd></kbd> {t('Seek forward 1 sec')}</div> <div style={{ lineHeight: 1.7 }}><SetCutpointButton currentCutSeg={currentCutSeg} side="start" Icon={FaHandPointLeft} style={{ verticalAlign: 'middle' }} />, <kbd>I</kbd> {t('Mark in / cut start point for current segment')}</div>
<div><kbd>CTRL</kbd> / <kbd>CMD</kbd> + <kbd></kbd> {t('Seek backward 1% of timeline at current zoom')}</div> <div style={{ lineHeight: 1.7 }}><SetCutpointButton currentCutSeg={currentCutSeg} side="end" Icon={FaHandPointRight} style={{ verticalAlign: 'middle' }} />, <kbd>O</kbd> {t('Mark out / cut end point for current segment')}</div>
<div><kbd>CTRL</kbd> / <kbd>CMD</kbd> + <kbd></kbd> {t('Seek forward 1% of timeline at current zoom')}</div> <div><kbd>+</kbd> {t('Add cut segment')}</div>
<div style={{ lineHeight: 1.7 }}><SetCutpointButton currentCutSeg={currentCutSeg} side="start" Icon={FaStepBackward} style={{ verticalAlign: 'middle' }} /> {t('Jump to cut end')}</div> <div><kbd>BACKSPACE</kbd> {t('Remove current segment')}</div>
<div style={{ lineHeight: 1.7 }}><SetCutpointButton currentCutSeg={currentCutSeg} side="end" Icon={FaStepForward} style={{ verticalAlign: 'middle' }} /> {t('Jump to cut end')}</div> <div><kbd></kbd> {t('Select previous segment')}</div>
<div><kbd></kbd> {t('Select next segment')}</div>
<h2>{t('Segments and cut points')}</h2>
<h2>{t('Timeline/zoom operations')}</h2>
<div style={{ lineHeight: 1.7 }}><SetCutpointButton currentCutSeg={currentCutSeg} side="start" Icon={FaHandPointLeft} style={{ verticalAlign: 'middle' }} />, <kbd>I</kbd> {t('Mark in / cut start point for current segment')}</div> <div><kbd>Z</kbd> {t('Toggle zoom between 1x and a calculated comfortable zoom level')}</div>
<div style={{ lineHeight: 1.7 }}><SetCutpointButton currentCutSeg={currentCutSeg} side="end" Icon={FaHandPointRight} style={{ verticalAlign: 'middle' }} />, <kbd>O</kbd> {t('Mark out / cut end point for current segment')}</div> <div><kbd>CTRL</kbd> / <kbd>CMD</kbd> + <kbd></kbd> {t('Zoom in timeline')}</div>
<div><kbd>+</kbd> {t('Add cut segment')}</div> <div><kbd>CTRL</kbd> / <kbd>CMD</kbd> + <kbd></kbd> {t('Zoom out timeline')}</div>
<div><kbd>BACKSPACE</kbd> {t('Remove current segment')}</div> <div><kbd>CTRL</kbd> <i>+ {t('Mouse scroll/wheel up/down')}</i> - {t('Zoom in/out timeline')}</div>
<div><kbd></kbd> {t('Select previous segment')}</div> <div><i>{t('Mouse scroll/wheel left/right')}</i> - {t('Pan timeline')}</div>
<div><kbd></kbd> {t('Select next segment')}</div>
<h2>{t('Output actions')}</h2>
<h2>{t('Timeline/zoom operations')}</h2> <div><kbd>E</kbd> {t('Export segment(s)')}</div>
<div><kbd>Z</kbd> {t('Toggle zoom between 1x and a calculated comfortable zoom level')}</div> <div><kbd>C</kbd> {t('Capture snapshot')}</div>
<div><kbd>CTRL</kbd> / <kbd>CMD</kbd> + <kbd></kbd> {t('Zoom in timeline')}</div> <div><kbd>D</kbd> {t('Delete source file')}</div>
<div><kbd>CTRL</kbd> / <kbd>CMD</kbd> + <kbd></kbd> {t('Zoom out timeline')}</div>
<div><kbd>CTRL</kbd> <i>+ {t('Mouse scroll/wheel up/down')}</i> - {t('Zoom in/out timeline')}</div> <p style={{ fontWeight: 'bold' }}>{t('Hover mouse over buttons in the main interface to see which function they have')}</p>
<div><i>{t('Mouse scroll/wheel left/right')}</i> - {t('Pan timeline')}</div>
<h1 style={{ marginTop: 40 }}>{t('Last ffmpeg commands')}</h1>
<h2>{t('Output actions')}</h2> {ffmpegCommandLog.length > 0 ? (
<div><kbd>E</kbd> {t('Export segment(s)')}</div> <div style={{ overflowY: 'scroll', height: 200 }}>
<div><kbd>C</kbd> {t('Capture snapshot')}</div> {ffmpegCommandLog.reverse().map(({ command }, i) => (
<div><kbd>D</kbd> {t('Delete source file')}</div> // eslint-disable-next-line react/no-array-index-key
<div key={i} style={{ whiteSpace: 'pre', margin: '5px 0' }}>
<p style={{ fontWeight: 'bold' }}>{t('Hover mouse over buttons in the main interface to see which function they have')}</p> <FaClipboard style={{ cursor: 'pointer' }} title={t('Copy to clipboard')} onClick={() => { clipboard.writeText(command); toast.fire({ timer: 2000, icon: 'success', title: t('Copied to clipboard') }); }} /> {command}
</div>
<h1 style={{ marginTop: 40 }}>{t('Last ffmpeg commands')}</h1> ))}
{ffmpegCommandLog.length > 0 ? ( </div>
<div style={{ overflowY: 'scroll', height: 200 }}> ) : (
{ffmpegCommandLog.reverse().map(({ command }, i) => ( <p>{t('The last executed ffmpeg commands will show up here after you run operations. You can copy them to clipboard and modify them to your needs before running on your command line.')}</p>
// eslint-disable-next-line react/no-array-index-key )}
<div key={i} style={{ whiteSpace: 'pre', margin: '5px 0' }}> </div>
<FaClipboard style={{ cursor: 'pointer' }} title={t('Copy to clipboard')} onClick={() => { clipboard.writeText(command); toast.fire({ timer: 2000, icon: 'success', title: t('Copied to clipboard') }); }} /> {command} </Sheet>
</div>
))}
</div>
) : (
<p>{t('The last executed ffmpeg commands will show up here after you run operations. You can copy them to clipboard and modify them to your needs before running on your command line.')}</p>
)}
</motion.div>
)}
</AnimatePresence>
); );
}); });

@ -1,41 +1,28 @@
import React, { memo } from 'react'; import React, { memo } from 'react';
import { IoIosCloseCircleOutline } from 'react-icons/io';
import { motion, AnimatePresence } from 'framer-motion';
import { Table } from 'evergreen-ui'; import { Table } from 'evergreen-ui';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
const SettingsSheet = memo(({ import Sheet from './Sheet';
visible, onTogglePress, renderSettings,
}) => { const SettingsSheet = memo(({ visible, onTogglePress, renderSettings }) => {
const { t } = useTranslation(); const { t } = useTranslation();
return ( return (
<AnimatePresence> <Sheet visible={visible} onClosePress={onTogglePress} style={{ background: 'white', color: 'black' }}>
{visible && ( <Table style={{ marginTop: 40 }}>
<motion.div <Table.Head>
initial={{ scale: 0, opacity: 0 }} <Table.TextHeaderCell>
animate={{ scale: 1, opacity: 1 }} {t('Settings')}
exit={{ scale: 0, opacity: 0 }} </Table.TextHeaderCell>
className="settings-sheet" <Table.TextHeaderCell>
> {t('Current setting')}
<IoIosCloseCircleOutline role="button" onClick={onTogglePress} size={30} style={{ position: 'fixed', right: 0, top: 0, padding: 20 }} /> </Table.TextHeaderCell>
</Table.Head>
<Table style={{ marginTop: 40 }}> <Table.Body>
<Table.Head> {renderSettings()}
<Table.TextHeaderCell> </Table.Body>
{t('Settings')} </Table>
</Table.TextHeaderCell> </Sheet>
<Table.TextHeaderCell>
{t('Current setting')}
</Table.TextHeaderCell>
</Table.Head>
<Table.Body>
{renderSettings()}
</Table.Body>
</Table>
</motion.div>
)}
</AnimatePresence>
); );
}); });

@ -0,0 +1,33 @@
import React, { memo } from 'react';
import { IoIosCloseCircleOutline } from 'react-icons/io';
import { motion, AnimatePresence } from 'framer-motion';
const sheetStyle = {
padding: '1em 2em',
position: 'fixed',
left: 0,
right: 0,
top: 0,
bottom: 0,
zIndex: 10,
overflowY: 'scroll',
};
const Sheet = memo(({ visible, onClosePress, style, children }) => (
<AnimatePresence>
{visible && (
<motion.div
initial={{ scale: 0, opacity: 0.5 }}
animate={{ scale: 1, opacity: 1 }}
exit={{ scale: 0, opacity: 0 }}
style={{ ...sheetStyle, ...style }}
>
<IoIosCloseCircleOutline role="button" onClick={onClosePress} size={30} style={{ position: 'fixed', right: 0, top: 0, padding: 20 }} />
{children}
</motion.div>
)}
</AnimatePresence>
));
export default Sheet;

@ -19,35 +19,14 @@ body {
cursor: default; cursor: default;
} }
.help-sheet, .settings-sheet { .help-sheet h1 {
padding: 1em 2em;
position: fixed;
left: 0;
right: 0;
top: 0;
bottom: 0;
z-index: 10;
overflow-y: scroll;
}
.help-sheet {
background: #6b6b6b;
color: white;
}
.settings-sheet {
background: white;
color: black;
}
.help-sheet h1, .settings-sheet h1 {
font-size: 1.2em; font-size: 1.2em;
margin-bottom: .5em; margin-bottom: .5em;
margin-top: 1.3em; margin-top: 1.3em;
text-transform: uppercase; text-transform: uppercase;
} }
.help-sheet h2, .settings-sheet h2 { .help-sheet h2 {
font-size: 1em; font-size: 1em;
margin-bottom: .5em; margin-bottom: .5em;
text-transform: uppercase; text-transform: uppercase;

Loading…
Cancel
Save