mirror of https://github.com/mifi/lossless-cut
Implement merge function
Also upgrade to react 16, sweetalert2 8 and refactor a bitpull/111/head
parent
8817c2c80b
commit
cfaa11028e
@ -0,0 +1,36 @@
|
||||
const React = require('react');
|
||||
const PropTypes = require('prop-types');
|
||||
|
||||
/* eslint-disable react/jsx-one-expression-per-line */
|
||||
const HelpSheet = ({ visible }) => {
|
||||
if (visible) {
|
||||
return (
|
||||
<div className="help-sheet">
|
||||
<h1>Keyboard shortcuts</h1>
|
||||
<ul>
|
||||
<li><kbd>H</kbd> Show/hide help</li>
|
||||
<li><kbd>SPACE</kbd>, <kbd>k</kbd> Play/pause</li>
|
||||
<li><kbd>J</kbd> Slow down video</li>
|
||||
<li><kbd>L</kbd> Speed up video</li>
|
||||
<li><kbd>←</kbd> Seek backward 1 sec</li>
|
||||
<li><kbd>→</kbd> Seek forward 1 sec</li>
|
||||
<li><kbd>.</kbd> (period) Tiny seek forward (1/60 sec)</li>
|
||||
<li><kbd>,</kbd> (comma) Tiny seek backward (1/60 sec)</li>
|
||||
<li><kbd>I</kbd> Mark in / cut start point</li>
|
||||
<li><kbd>O</kbd> Mark out / cut end point</li>
|
||||
<li><kbd>E</kbd> Cut (export selection in the same directory)</li>
|
||||
<li><kbd>C</kbd> Capture snapshot (in the same directory)</li>
|
||||
</ul>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
return null;
|
||||
};
|
||||
/* eslint-enable react/jsx-one-expression-per-line */
|
||||
|
||||
HelpSheet.propTypes = {
|
||||
visible: PropTypes.bool.isRequired,
|
||||
};
|
||||
|
||||
module.exports = HelpSheet;
|
||||
@ -0,0 +1,71 @@
|
||||
import React, { PureComponent } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import {
|
||||
sortableContainer,
|
||||
sortableElement,
|
||||
arrayMove,
|
||||
} from 'react-sortable-hoc';
|
||||
import { basename } from 'path';
|
||||
|
||||
const rowStyle = {
|
||||
padding: 5, fontSize: 14, margin: '7px 0', boxShadow: '0 0 5px 0px rgba(0,0,0,0.3)', overflowY: 'auto', whiteSpace: 'nowrap',
|
||||
};
|
||||
|
||||
const SortableItem = sortableElement(({ value, sortIndex }) => (
|
||||
<div style={rowStyle} title={value}>
|
||||
{sortIndex + 1}
|
||||
{'. '}
|
||||
{basename(value)}
|
||||
</div>));
|
||||
|
||||
const SortableContainer = sortableContainer(({ items }) => (
|
||||
<div>
|
||||
{items.map((value, index) => (
|
||||
<SortableItem key={value} index={index} sortIndex={index} value={value} />
|
||||
))}
|
||||
</div>
|
||||
));
|
||||
|
||||
class SortableFiles extends PureComponent {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
this.state = {
|
||||
items: props.items,
|
||||
};
|
||||
}
|
||||
|
||||
onSortEnd = ({ oldIndex, newIndex }) => {
|
||||
const { items } = this.state;
|
||||
const { onChange } = this.props;
|
||||
const newItems = arrayMove(items, oldIndex, newIndex);
|
||||
this.setState({ items: newItems });
|
||||
onChange(newItems);
|
||||
};
|
||||
|
||||
render() {
|
||||
const { helperContainer } = this.props;
|
||||
const { items } = this.state;
|
||||
|
||||
return (
|
||||
<div>
|
||||
<div><b>Sort your files for merge</b></div>
|
||||
<SortableContainer
|
||||
items={items}
|
||||
onSortEnd={this.onSortEnd}
|
||||
helperContainer={helperContainer}
|
||||
getContainer={() => helperContainer().parentNode}
|
||||
helperClass="dragging-helper-class"
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
SortableFiles.propTypes = {
|
||||
onChange: PropTypes.func.isRequired,
|
||||
helperContainer: PropTypes.func.isRequired,
|
||||
items: PropTypes.array.isRequired,
|
||||
};
|
||||
|
||||
export default SortableFiles;
|
||||
@ -0,0 +1,49 @@
|
||||
const React = require('react');
|
||||
const swal = require('sweetalert2');
|
||||
const withReactContent = require('sweetalert2-react-content');
|
||||
|
||||
const SortableFiles = require('./SortableFiles').default;
|
||||
|
||||
const { errorToast } = require('../util');
|
||||
|
||||
const MySwal = withReactContent(swal);
|
||||
|
||||
|
||||
function showMergeDialog({ dialog, defaultPath, onMergeClick }) {
|
||||
const title = 'Please select files to be merged';
|
||||
const message = 'Please select files to be merged. The files need to be of the exact same format and codecs';
|
||||
dialog.showOpenDialog({
|
||||
title,
|
||||
defaultPath,
|
||||
properties: ['openFile', 'multiSelections'],
|
||||
message,
|
||||
}, async (paths) => {
|
||||
if (!paths) return;
|
||||
if (paths.length < 2) {
|
||||
errorToast('More than one file must be selected');
|
||||
return;
|
||||
}
|
||||
|
||||
{
|
||||
let swalElem;
|
||||
let outPaths = paths;
|
||||
const { dismiss } = await MySwal.fire({
|
||||
width: '90%',
|
||||
showCancelButton: true,
|
||||
confirmButtonText: 'Merge!',
|
||||
onBeforeOpen: (el) => { swalElem = el; },
|
||||
html: (<SortableFiles
|
||||
items={outPaths}
|
||||
onChange={(val) => { outPaths = val; }}
|
||||
helperContainer={() => swalElem}
|
||||
/>),
|
||||
});
|
||||
|
||||
if (!dismiss) {
|
||||
onMergeClick(outPaths);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
module.exports = { showMergeDialog };
|
||||
Loading…
Reference in New Issue