mirror of
https://github.com/mifi/lossless-cut.git
synced 2024-11-22 02:12:30 +01:00
upgrade lint and support esm
fix lint too
This commit is contained in:
parent
2a373042f8
commit
23cbd73e93
@ -22,6 +22,11 @@
|
|||||||
"arrow-parens": 0,
|
"arrow-parens": 0,
|
||||||
"jsx-a11y/control-has-associated-label": 0,
|
"jsx-a11y/control-has-associated-label": 0,
|
||||||
"react/prop-types": 0,
|
"react/prop-types": 0,
|
||||||
"no-multiple-empty-lines": ["error", { "max": 2, "maxBOF": 0, "maxEOF": 0 }]
|
"no-multiple-empty-lines": ["error", { "max": 2, "maxBOF": 0, "maxEOF": 0 }],
|
||||||
|
"no-promise-executor-return": 0,
|
||||||
|
"react/function-component-definition": 0
|
||||||
|
},
|
||||||
|
"parserOptions": {
|
||||||
|
"ecmaVersion": 2022
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
24
icon-gen.js
24
icon-gen.js
@ -1,24 +0,0 @@
|
|||||||
const sharp = require('sharp');
|
|
||||||
const icongen = require('icon-gen');
|
|
||||||
|
|
||||||
const svg2png = (from, to, width, height) => sharp(from)
|
|
||||||
.png()
|
|
||||||
.resize(width, height, {
|
|
||||||
fit: sharp.fit.contain,
|
|
||||||
background: { r: 0, g: 0, b: 0, alpha: 0 },
|
|
||||||
})
|
|
||||||
.toFile(to);
|
|
||||||
|
|
||||||
(async () => {
|
|
||||||
await svg2png('src/icon.svg', './icon-build/app-512.png', 512, 512);
|
|
||||||
await svg2png('src/icon.svg', './build-resources/appx/StoreLogo.png', 50, 50);
|
|
||||||
await svg2png('src/icon.svg', './build-resources/appx/Square150x150Logo.png', 300, 300);
|
|
||||||
await svg2png('src/icon.svg', './build-resources/appx/Square44x44Logo.png', 44, 44);
|
|
||||||
await svg2png('src/icon.svg', './build-resources/appx/Wide310x150Logo.png', 620, 300);
|
|
||||||
|
|
||||||
await icongen('./src/icon.svg', './icon-build', { icns: { sizes: [512, 1024] } });
|
|
||||||
|
|
||||||
// https://github.com/mifi/lossless-cut/issues/778
|
|
||||||
// https://stackoverflow.com/questions/3236115/which-icon-sizes-should-my-windows-applications-icon-include
|
|
||||||
await icongen('./src/icon.svg', './icon-build', { ico: { sizes: [16, 24, 32, 40, 48, 64, 96, 128, 256, 512] } });
|
|
||||||
})();
|
|
12
package.json
12
package.json
@ -10,14 +10,14 @@
|
|||||||
"start": "concurrently -k \"npm run start:frontend\" \"npm run start:electron\"",
|
"start": "concurrently -k \"npm run start:frontend\" \"npm run start:electron\"",
|
||||||
"start:frontend": "cross-env BROWSER=none PORT=3001 DISABLE_ESLINT_PLUGIN=true react-scripts start",
|
"start:frontend": "cross-env BROWSER=none PORT=3001 DISABLE_ESLINT_PLUGIN=true react-scripts start",
|
||||||
"start:electron": "wait-on http://localhost:3001 && electron .",
|
"start:electron": "wait-on http://localhost:3001 && electron .",
|
||||||
"icon-gen": "mkdirp icon-build build-resources/appx && node icon-gen.js",
|
"icon-gen": "mkdirp icon-build build-resources/appx && node script/icon-gen.mjs",
|
||||||
"download-ffmpeg-mac": "mkdir -p ffmpeg/darwin && cd ffmpeg/darwin && wget https://github.com/mifi/ffmpeg-build-script/releases/download/n4.4.1/ffmpeg -O ffmpeg && wget https://github.com/mifi/ffmpeg-build-script/releases/download/n4.4.1/ffprobe -O ffprobe && chmod +x ffmpeg && chmod +x ffprobe",
|
"download-ffmpeg-mac": "mkdirp ffmpeg/darwin && cd ffmpeg/darwin && wget https://github.com/mifi/ffmpeg-build-script/releases/download/n4.4.1/ffmpeg -O ffmpeg && wget https://github.com/mifi/ffmpeg-build-script/releases/download/n4.4.1/ffprobe -O ffprobe && chmod +x ffmpeg && chmod +x ffprobe",
|
||||||
"download-ffmpeg-linux": "mkdir -p ffmpeg/linux && cd ffmpeg/linux && wget https://github.com/mifi/ffmpeg-builds/releases/download/4.4.1/ffmpeg-release-amd64-static.tar.xz -O ffmpeg.xz && tar xvf ffmpeg.xz ffmpeg-4.4.1-amd64-static/ffmpeg ffmpeg-4.4.1-amd64-static/ffprobe --strip-components=1",
|
"download-ffmpeg-linux": "mkdirp ffmpeg/linux && cd ffmpeg/linux && wget https://github.com/mifi/ffmpeg-builds/releases/download/4.4.1/ffmpeg-release-amd64-static.tar.xz -O ffmpeg.xz && tar xvf ffmpeg.xz ffmpeg-4.4.1-amd64-static/ffmpeg ffmpeg-4.4.1-amd64-static/ffprobe --strip-components=1",
|
||||||
"download-ffmpeg-windows": "npx shx mkdir -p ffmpeg/win32 && cd ffmpeg/win32 && npx download-cli https://github.com/mifi/ffmpeg-builds/releases/download/4.4.1/ffmpeg-n4.4.1-2-gcc33e73618-win64-gpl-4.4.zip --out . --filename ffmpeg.zip && 7z x ffmpeg.zip && npx shx mv ffmpeg-n4.4.1-2-gcc33e73618-win64-gpl-4.4/bin/ffmpeg.exe ./ && npx shx mv ffmpeg-n4.4.1-2-gcc33e73618-win64-gpl-4.4/bin/ffprobe.exe ./",
|
"download-ffmpeg-windows": "mkdirp ffmpeg/win32 && cd ffmpeg/win32 && npx download-cli https://github.com/mifi/ffmpeg-builds/releases/download/4.4.1/ffmpeg-n4.4.1-2-gcc33e73618-win64-gpl-4.4.zip --out . --filename ffmpeg.zip && 7z x ffmpeg.zip && npx shx mv ffmpeg-n4.4.1-2-gcc33e73618-win64-gpl-4.4/bin/ffmpeg.exe ./ && npx shx mv ffmpeg-n4.4.1-2-gcc33e73618-win64-gpl-4.4/bin/ffprobe.exe ./",
|
||||||
"build": "yarn icon-gen && react-scripts build",
|
"build": "yarn icon-gen && react-scripts build",
|
||||||
"test": "react-scripts test",
|
"test": "react-scripts test",
|
||||||
"eject": "react-scripts eject",
|
"eject": "react-scripts eject",
|
||||||
"lint": "eslint --ext .jsx --ext .js .",
|
"lint": "eslint --ext .jsx --ext .js . --ext .mjs",
|
||||||
"pack-mac": "electron-builder --mac -m dmg",
|
"pack-mac": "electron-builder --mac -m dmg",
|
||||||
"prepack-mac": "yarn build",
|
"prepack-mac": "yarn build",
|
||||||
"pack-mas-dev": "electron-builder --mac -m mas-dev -c.mas.provisioningProfile=LosslessCut_Dev.provisionprofile -c.mas.identity='Apple Development: Mikael Finstad (JH4PH8B3C8)'",
|
"pack-mas-dev": "electron-builder --mac -m mas-dev -c.mas.provisioningProfile=LosslessCut_Dev.provisionprofile -c.mas.identity='Apple Development: Mikael Finstad (JH4PH8B3C8)'",
|
||||||
@ -54,7 +54,7 @@
|
|||||||
"electron-builder-notarize": "1.1.2",
|
"electron-builder-notarize": "1.1.2",
|
||||||
"electron-devtools-installer": "^3.1.1",
|
"electron-devtools-installer": "^3.1.1",
|
||||||
"eslint": "^7.32.0 || ^8.2.0",
|
"eslint": "^7.32.0 || ^8.2.0",
|
||||||
"eslint-config-airbnb": "^18.2.1",
|
"eslint-config-airbnb": "^19.0.4",
|
||||||
"eslint-plugin-import": "^2.25.3",
|
"eslint-plugin-import": "^2.25.3",
|
||||||
"eslint-plugin-jsx-a11y": "^6.5.1",
|
"eslint-plugin-jsx-a11y": "^6.5.1",
|
||||||
"eslint-plugin-react": "^7.28.0",
|
"eslint-plugin-react": "^7.28.0",
|
||||||
|
22
script/icon-gen.mjs
Normal file
22
script/icon-gen.mjs
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
import sharp from 'sharp';
|
||||||
|
import icongen from 'icon-gen';
|
||||||
|
|
||||||
|
const svg2png = (from, to, width, height) => sharp(from)
|
||||||
|
.png()
|
||||||
|
.resize(width, height, {
|
||||||
|
fit: sharp.fit.contain,
|
||||||
|
background: { r: 0, g: 0, b: 0, alpha: 0 },
|
||||||
|
})
|
||||||
|
.toFile(to);
|
||||||
|
|
||||||
|
await svg2png('src/icon.svg', './icon-build/app-512.png', 512, 512);
|
||||||
|
await svg2png('src/icon.svg', './build-resources/appx/StoreLogo.png', 50, 50);
|
||||||
|
await svg2png('src/icon.svg', './build-resources/appx/Square150x150Logo.png', 300, 300);
|
||||||
|
await svg2png('src/icon.svg', './build-resources/appx/Square44x44Logo.png', 44, 44);
|
||||||
|
await svg2png('src/icon.svg', './build-resources/appx/Wide310x150Logo.png', 620, 300);
|
||||||
|
|
||||||
|
await icongen('./src/icon.svg', './icon-build', { icns: { sizes: [512, 1024] } });
|
||||||
|
|
||||||
|
// https://github.com/mifi/lossless-cut/issues/778
|
||||||
|
// https://stackoverflow.com/questions/3236115/which-icon-sizes-should-my-windows-applications-icon-include
|
||||||
|
await icongen('./src/icon.svg', './icon-build', { ico: { sizes: [16, 24, 32, 40, 48, 64, 96, 128, 256, 512] } });
|
@ -1092,8 +1092,9 @@ const App = memo(() => {
|
|||||||
}
|
}
|
||||||
}, [previewFilePath, filePath, edlFilePath, cleanupChoices, isFileOpened, resetState, batchRemoveFile, setWorking]);
|
}, [previewFilePath, filePath, edlFilePath, cleanupChoices, isFileOpened, resetState, batchRemoveFile, setWorking]);
|
||||||
|
|
||||||
const inverseOrNormalSegments = useMemo(() => (invertCutSegments ? inverseCutSegments : apparentCutSegments),
|
const inverseOrNormalSegments = useMemo(() => (
|
||||||
[invertCutSegments, inverseCutSegments, apparentCutSegments]);
|
invertCutSegments ? inverseCutSegments : apparentCutSegments
|
||||||
|
), [invertCutSegments, inverseCutSegments, apparentCutSegments]);
|
||||||
|
|
||||||
const enabledSegmentsRaw = useMemo(() => {
|
const enabledSegmentsRaw = useMemo(() => {
|
||||||
// For invertCutSegments we do not support filtering
|
// For invertCutSegments we do not support filtering
|
||||||
|
@ -6,8 +6,7 @@ import CanvasPlayer from './CanvasPlayer';
|
|||||||
const Canvas = memo(({ rotate, filePath, width, height, playerTime, streamIndex, commandedTime, playing }) => {
|
const Canvas = memo(({ rotate, filePath, width, height, playerTime, streamIndex, commandedTime, playing }) => {
|
||||||
const canvasRef = useRef();
|
const canvasRef = useRef();
|
||||||
|
|
||||||
const canvasPlayer = useMemo(() => CanvasPlayer({ path: filePath, width, height, streamIndex }),
|
const canvasPlayer = useMemo(() => CanvasPlayer({ path: filePath, width, height, streamIndex }), [filePath, width, height, streamIndex]);
|
||||||
[filePath, width, height, streamIndex]);
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
canvasPlayer.setCanvas(canvasRef.current);
|
canvasPlayer.setCanvas(canvasRef.current);
|
||||||
|
@ -34,7 +34,7 @@ const HelpSheet = memo(({ visible, onTogglePress, ffmpegCommandLog, onKeyboardSh
|
|||||||
<span style={{ color: primaryTextColor, cursor: 'pointer' }} role="button" onClick={() => electron.shell.openExternal(githubLink)}>{githubLink}</span>
|
<span style={{ color: primaryTextColor, cursor: 'pointer' }} role="button" onClick={() => electron.shell.openExternal(githubLink)}>{githubLink}</span>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<Button iconBefore={() => <FaKeyboard />} onClick={onKeyboardShortcutsDialogRequested}>{t('Keyboard & mouse shortcuts')}</Button>
|
<Button iconBefore={<FaKeyboard />} onClick={onKeyboardShortcutsDialogRequested}>{t('Keyboard & mouse shortcuts')}</Button>
|
||||||
|
|
||||||
<p style={{ fontWeight: 'bold' }}>{t('Hover mouse over buttons in the main interface to see which function they have')}</p>
|
<p style={{ fontWeight: 'bold' }}>{t('Hover mouse over buttons in the main interface to see which function they have')}</p>
|
||||||
|
|
||||||
|
@ -30,6 +30,10 @@ const langNames = {
|
|||||||
ko: '한국어',
|
ko: '한국어',
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// eslint-disable-next-line react/jsx-props-no-spreading
|
||||||
|
const Row = (props) => <Table.Row height="auto" paddingY={12} {...props} />;
|
||||||
|
// eslint-disable-next-line react/jsx-props-no-spreading
|
||||||
|
const KeyCell = (props) => <Table.TextCell textProps={{ whiteSpace: 'auto' }} {...props} />;
|
||||||
|
|
||||||
const Settings = memo(({
|
const Settings = memo(({
|
||||||
changeOutDir, customOutDir, keyframeCut, setKeyframeCut, invertCutSegments, setInvertCutSegments,
|
changeOutDir, customOutDir, keyframeCut, setKeyframeCut, invertCutSegments, setInvertCutSegments,
|
||||||
@ -43,11 +47,6 @@ const Settings = memo(({
|
|||||||
}) => {
|
}) => {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
|
||||||
// eslint-disable-next-line react/jsx-props-no-spreading
|
|
||||||
const Row = (props) => <Table.Row height="auto" paddingY={12} {...props} />;
|
|
||||||
// eslint-disable-next-line react/jsx-props-no-spreading
|
|
||||||
const KeyCell = (props) => <Table.TextCell textProps={{ whiteSpace: 'auto' }} {...props} />;
|
|
||||||
|
|
||||||
const onLangChange = useCallback((e) => {
|
const onLangChange = useCallback((e) => {
|
||||||
const { value } = e.target;
|
const { value } = e.target;
|
||||||
const l = value !== '' ? value : undefined;
|
const l = value !== '' ? value : undefined;
|
||||||
@ -83,7 +82,7 @@ const Settings = memo(({
|
|||||||
<Row>
|
<Row>
|
||||||
<KeyCell>{t('Keyboard & mouse shortcuts')}</KeyCell>
|
<KeyCell>{t('Keyboard & mouse shortcuts')}</KeyCell>
|
||||||
<Table.TextCell>
|
<Table.TextCell>
|
||||||
<Button iconBefore={() => <FaKeyboard />} onClick={onKeyboardShortcutsDialogRequested}>{t('Keyboard & mouse shortcuts')}</Button>
|
<Button iconBefore={<FaKeyboard />} onClick={onKeyboardShortcutsDialogRequested}>{t('Keyboard & mouse shortcuts')}</Button>
|
||||||
</Table.TextCell>
|
</Table.TextCell>
|
||||||
</Row>
|
</Row>
|
||||||
|
|
||||||
|
@ -235,7 +235,7 @@ const Stream = memo(({ filePath, stream, onToggle, batchSetCopyStreamIds, copySt
|
|||||||
return (
|
return (
|
||||||
<tr style={{ opacity: copyStream ? undefined : 0.4 }}>
|
<tr style={{ opacity: copyStream ? undefined : 0.4 }}>
|
||||||
<td style={{ whiteSpace: 'nowrap', display: 'flex', alignItems: 'center' }}>
|
<td style={{ whiteSpace: 'nowrap', display: 'flex', alignItems: 'center' }}>
|
||||||
<IconButton title={t('Click to toggle track inclusion when exporting')} appearance="minimal" icon={() => <Icon color={copyStream ? '#52BD95' : '#D14343'} size={20} />} onClick={onClick} />
|
<IconButton title={t('Click to toggle track inclusion when exporting')} appearance="minimal" icon={<Icon color={copyStream ? '#52BD95' : '#D14343'} size={20} />} onClick={onClick} />
|
||||||
<div style={{ width: 20, textAlign: 'center' }}>{stream.index}</div>
|
<div style={{ width: 20, textAlign: 'center' }}>{stream.index}</div>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
@ -250,7 +250,7 @@ const Stream = memo(({ filePath, stream, onToggle, batchSetCopyStreamIds, copySt
|
|||||||
<td>{stream.width && stream.height && `${stream.width}x${stream.height}`} {stream.channels && `${stream.channels}c`} {stream.channel_layout} {streamFps && `${streamFps.toFixed(2)}fps`}</td>
|
<td>{stream.width && stream.height && `${stream.width}x${stream.height}`} {stream.channels && `${stream.channels}c`} {stream.channel_layout} {streamFps && `${streamFps.toFixed(2)}fps`}</td>
|
||||||
<td style={{ display: 'flex' }}>
|
<td style={{ display: 'flex' }}>
|
||||||
<IconButton icon={InfoSignIcon} onClick={() => onInfoClick(stream, t('Track info'))} appearance="minimal" iconSize={18} />
|
<IconButton icon={InfoSignIcon} onClick={() => onInfoClick(stream, t('Track info'))} appearance="minimal" iconSize={18} />
|
||||||
<IconButton title={t('Extract this track as file')} icon={() => <FaFileExport size={18} />} onClick={onExtractStreamPress} appearance="minimal" iconSize={18} />
|
<IconButton title={t('Extract this track as file')} icon={<FaFileExport size={18} />} onClick={onExtractStreamPress} appearance="minimal" iconSize={18} />
|
||||||
|
|
||||||
<Popover
|
<Popover
|
||||||
position={Position.BOTTOM_LEFT}
|
position={Position.BOTTOM_LEFT}
|
||||||
@ -263,10 +263,10 @@ const Stream = memo(({ filePath, stream, onToggle, batchSetCopyStreamIds, copySt
|
|||||||
</Menu.Group>
|
</Menu.Group>
|
||||||
<Menu.Divider />
|
<Menu.Divider />
|
||||||
<Menu.Group>
|
<Menu.Group>
|
||||||
<Menu.Item icon={() => <Icon color="black" />} intent="success" onClick={() => batchSetCopyStreamIds((s) => s.codec_type === stream.codec_type, true)}>
|
<Menu.Item icon={<Icon color="black" />} intent="success" onClick={() => batchSetCopyStreamIds((s) => s.codec_type === stream.codec_type, true)}>
|
||||||
{t('Keep all {{type}} tracks', { type: stream.codec_type })}
|
{t('Keep all {{type}} tracks', { type: stream.codec_type })}
|
||||||
</Menu.Item>
|
</Menu.Item>
|
||||||
<Menu.Item icon={() => <FaBan color="black" />} intent="danger" onClick={() => batchSetCopyStreamIds((s) => s.codec_type === stream.codec_type, false)}>
|
<Menu.Item icon={<FaBan color="black" />} intent="danger" onClick={() => batchSetCopyStreamIds((s) => s.codec_type === stream.codec_type, false)}>
|
||||||
{t('Discard all {{type}} tracks', { type: stream.codec_type })}
|
{t('Discard all {{type}} tracks', { type: stream.codec_type })}
|
||||||
</Menu.Item>
|
</Menu.Item>
|
||||||
</Menu.Group>
|
</Menu.Group>
|
||||||
@ -293,9 +293,9 @@ const FileHeading = ({ path, formatData, chapters, onTrashClick, onEditClick, se
|
|||||||
{chapters && chapters.length > 0 && <IconButton icon={BookIcon} onClick={() => onInfoClick(chapters, t('Chapters'))} appearance="minimal" iconSize={18} />}
|
{chapters && chapters.length > 0 && <IconButton icon={BookIcon} onClick={() => onInfoClick(chapters, t('Chapters'))} appearance="minimal" iconSize={18} />}
|
||||||
{onEditClick && <IconButton icon={EditIcon} onClick={onEditClick} appearance="minimal" iconSize={18} />}
|
{onEditClick && <IconButton icon={EditIcon} onClick={onEditClick} appearance="minimal" iconSize={18} />}
|
||||||
{onTrashClick && <IconButton icon={TrashIcon} onClick={onTrashClick} appearance="minimal" iconSize={18} />}
|
{onTrashClick && <IconButton icon={TrashIcon} onClick={onTrashClick} appearance="minimal" iconSize={18} />}
|
||||||
<IconButton icon={() => <FaCheckCircle color="#52BD95" size={18} />} onClick={() => setCopyAllStreams(true)} appearance="minimal" />
|
<IconButton icon={<FaCheckCircle color="#52BD95" size={18} />} onClick={() => setCopyAllStreams(true)} appearance="minimal" />
|
||||||
<IconButton icon={() => <FaBan color="#D14343" size={18} />} onClick={() => setCopyAllStreams(false)} appearance="minimal" />
|
<IconButton icon={<FaBan color="#D14343" size={18} />} onClick={() => setCopyAllStreams(false)} appearance="minimal" />
|
||||||
{onExtractAllStreamsPress && <IconButton title={t('Export each track as individual files')} icon={() => <ForkIcon size={16} />} onClick={onExtractAllStreamsPress} appearance="minimal" />}
|
{onExtractAllStreamsPress && <IconButton title={t('Export each track as individual files')} icon={<ForkIcon size={16} />} onClick={onExtractAllStreamsPress} appearance="minimal" />}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
@ -424,7 +424,7 @@ const StreamsSelector = memo(({
|
|||||||
<Alert intent="warning" appearance="card" marginBottom={5}>{t('Note: Cutting and including external tracks at the same time does not yet work. If you want to do both, it must be done as separate operations. See github issue #896.')}</Alert>
|
<Alert intent="warning" appearance="card" marginBottom={5}>{t('Note: Cutting and including external tracks at the same time does not yet work. If you want to do both, it must be done as separate operations. See github issue #896.')}</Alert>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
<Button iconBefore={() => <FaFileImport size={16} />} onClick={showAddStreamSourceDialog}>
|
<Button iconBefore={<FaFileImport size={16} />} onClick={showAddStreamSourceDialog}>
|
||||||
{t('Include more tracks from other file')}
|
{t('Include more tracks from other file')}
|
||||||
</Button>
|
</Button>
|
||||||
|
|
||||||
|
@ -66,7 +66,7 @@ const MergeExportButton = memo(({ autoMerge, enabledSegments, setAutoMerge, auto
|
|||||||
style={{ minWidth: 120, textAlign: 'center', opacity: enabledSegments && enabledSegments.length < 2 ? 0.4 : undefined }}
|
style={{ minWidth: 120, textAlign: 'center', opacity: enabledSegments && enabledSegments.length < 2 ? 0.4 : undefined }}
|
||||||
title={description}
|
title={description}
|
||||||
onClick={withBlur(onClick)}
|
onClick={withBlur(onClick)}
|
||||||
iconBefore={AutoMergeIcon && (() => <AutoMergeIcon />)}
|
iconBefore={AutoMergeIcon && <AutoMergeIcon />}
|
||||||
>
|
>
|
||||||
{title}
|
{title}
|
||||||
</Button>
|
</Button>
|
||||||
|
@ -123,12 +123,11 @@ function useFfmpegOperations({ filePath, enableTransferTimestamps }) {
|
|||||||
return streamCount + copiedStreamIndex;
|
return streamCount + copiedStreamIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
const lessDeepMap = (root, fn) => flatMapDeep(
|
const lessDeepMap = (root, fn) => flatMapDeep((
|
||||||
Object.entries(root), ([path, streamsMap]) => (
|
Object.entries(root), ([path, streamsMap]) => (
|
||||||
Object.entries(streamsMap || {}).map(([streamId, value]) => (
|
Object.entries(streamsMap || {}).map(([streamId, value]) => (
|
||||||
fn(path, streamId, value)
|
fn(path, streamId, value)
|
||||||
))),
|
)))));
|
||||||
);
|
|
||||||
|
|
||||||
// The structure is deep! file -> stream -> key -> value Example: { 'file.mp4': { 0: { key: 'value' } } }
|
// The structure is deep! file -> stream -> key -> value Example: { 'file.mp4': { 0: { key: 'value' } } }
|
||||||
const deepMap = (root, fn) => lessDeepMap(root, (path, streamId, tagsMap) => (
|
const deepMap = (root, fn) => lessDeepMap(root, (path, streamId, tagsMap) => (
|
||||||
|
@ -14,10 +14,12 @@ const electron = window.require('electron');
|
|||||||
console.log('Version', electron.remote.app.getVersion());
|
console.log('Version', electron.remote.app.getVersion());
|
||||||
|
|
||||||
|
|
||||||
ReactDOM.render((
|
ReactDOM.render(
|
||||||
<ErrorBoundary>
|
(
|
||||||
<Suspense fallback={<div />}>
|
<ErrorBoundary>
|
||||||
<App />
|
<Suspense fallback={<div />}>
|
||||||
</Suspense>
|
<App />
|
||||||
</ErrorBoundary>
|
</Suspense>
|
||||||
), document.getElementById('root'));
|
</ErrorBoundary>
|
||||||
|
), document.getElementById('root'),
|
||||||
|
);
|
||||||
|
25
yarn.lock
25
yarn.lock
@ -4744,23 +4744,24 @@ escodegen@^2.0.0:
|
|||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
source-map "~0.6.1"
|
source-map "~0.6.1"
|
||||||
|
|
||||||
eslint-config-airbnb-base@^14.2.1:
|
eslint-config-airbnb-base@^15.0.0:
|
||||||
version "14.2.1"
|
version "15.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/eslint-config-airbnb-base/-/eslint-config-airbnb-base-14.2.1.tgz#8a2eb38455dc5a312550193b319cdaeef042cd1e"
|
resolved "https://registry.yarnpkg.com/eslint-config-airbnb-base/-/eslint-config-airbnb-base-15.0.0.tgz#6b09add90ac79c2f8d723a2580e07f3925afd236"
|
||||||
integrity sha512-GOrQyDtVEc1Xy20U7vsB2yAoB4nBlfH5HZJeatRXHleO+OS5Ot+MWij4Dpltw4/DyIkqUfqz1epfhVR5XWWQPA==
|
integrity sha512-xaX3z4ZZIcFLvh2oUNvcX5oEofXda7giYmuplVxoOg5A7EXJMrUyqRgR+mhDhPK8LZ4PttFOBvCYDbX3sUoUig==
|
||||||
dependencies:
|
dependencies:
|
||||||
confusing-browser-globals "^1.0.10"
|
confusing-browser-globals "^1.0.10"
|
||||||
object.assign "^4.1.2"
|
object.assign "^4.1.2"
|
||||||
object.entries "^1.1.2"
|
object.entries "^1.1.5"
|
||||||
|
semver "^6.3.0"
|
||||||
|
|
||||||
eslint-config-airbnb@^18.2.1:
|
eslint-config-airbnb@^19.0.4:
|
||||||
version "18.2.1"
|
version "19.0.4"
|
||||||
resolved "https://registry.yarnpkg.com/eslint-config-airbnb/-/eslint-config-airbnb-18.2.1.tgz#b7fe2b42f9f8173e825b73c8014b592e449c98d9"
|
resolved "https://registry.yarnpkg.com/eslint-config-airbnb/-/eslint-config-airbnb-19.0.4.tgz#84d4c3490ad70a0ffa571138ebcdea6ab085fdc3"
|
||||||
integrity sha512-glZNDEZ36VdlZWoxn/bUR1r/sdFKPd1mHPbqUtkctgNG4yT2DLLtJ3D+yCV+jzZCc2V1nBVkmdknOJBZ5Hc0fg==
|
integrity sha512-T75QYQVQX57jiNgpF9r1KegMICE94VYwoFQyMGhrvc+lB8YF2E/M/PYDaQe1AJcWaEgqLE+ErXV1Og/+6Vyzew==
|
||||||
dependencies:
|
dependencies:
|
||||||
eslint-config-airbnb-base "^14.2.1"
|
eslint-config-airbnb-base "^15.0.0"
|
||||||
object.assign "^4.1.2"
|
object.assign "^4.1.2"
|
||||||
object.entries "^1.1.2"
|
object.entries "^1.1.5"
|
||||||
|
|
||||||
eslint-config-react-app@^7.0.0:
|
eslint-config-react-app@^7.0.0:
|
||||||
version "7.0.0"
|
version "7.0.0"
|
||||||
@ -8146,7 +8147,7 @@ object.assign@^4.0.4, object.assign@^4.1.0, object.assign@^4.1.2:
|
|||||||
has-symbols "^1.0.1"
|
has-symbols "^1.0.1"
|
||||||
object-keys "^1.1.1"
|
object-keys "^1.1.1"
|
||||||
|
|
||||||
object.entries@^1.1.2, object.entries@^1.1.5:
|
object.entries@^1.1.5:
|
||||||
version "1.1.5"
|
version "1.1.5"
|
||||||
resolved "https://registry.yarnpkg.com/object.entries/-/object.entries-1.1.5.tgz#e1acdd17c4de2cd96d5a08487cfb9db84d881861"
|
resolved "https://registry.yarnpkg.com/object.entries/-/object.entries-1.1.5.tgz#e1acdd17c4de2cd96d5a08487cfb9db84d881861"
|
||||||
integrity sha512-TyxmjUoZggd4OrrU1W66FMDG6CuqJxsFvymeyXI51+vQLN67zYfZseptRge703kKQdo4uccgAKebXFcRCzk4+g==
|
integrity sha512-TyxmjUoZggd4OrrU1W66FMDG6CuqJxsFvymeyXI51+vQLN67zYfZseptRge703kKQdo4uccgAKebXFcRCzk4+g==
|
||||||
|
Loading…
Reference in New Issue
Block a user