1
0
mirror of https://github.com/mifi/lossless-cut.git synced 2024-11-25 11:43:17 +01:00

Upgrade ESLint and add useCallback (#914)

* Improvements:

- Upgrade ESLint

* Missing useCallback.

Co-authored-by: Mikael Finstad <finstaden@gmail.com>
This commit is contained in:
Vitalii Shvetsov 2021-11-14 22:41:21 +09:00 committed by GitHub
parent 2568f5cd0f
commit 11502b84ed
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 484 additions and 297 deletions

View File

@ -207,7 +207,7 @@ const App = memo(() => {
}
}, [detectedFileFormat, outFormatLocked, setOutFormatLocked]);
function setTimelineMode(newMode) {
const setTimelineMode = useCallback((newMode) => {
if (newMode === 'waveform') {
setWaveformEnabled(v => !v);
setThumbnailsEnabled(false);
@ -215,7 +215,7 @@ const App = memo(() => {
setThumbnailsEnabled(v => !v);
setWaveformEnabled(false);
}
}
}, []);
const toggleExportConfirmEnabled = useCallback(() => setExportConfirmEnabled((v) => !v), [setExportConfirmEnabled]);
@ -239,18 +239,18 @@ const App = memo(() => {
const getCurrentTime = useCallback(() => currentTimeRef.current, []);
function setCopyStreamIdsForPath(path, cb) {
const setCopyStreamIdsForPath = useCallback((path, cb) => {
setCopyStreamIdsByFile((old) => {
const oldIds = old[path] || {};
return ({ ...old, [path]: cb(oldIds) });
});
}
}, []);
const toggleRightBar = useCallback(() => setShowRightBar(v => !v), []);
const toggleCopyStreamId = useCallback((path, index) => {
setCopyStreamIdsForPath(path, (old) => ({ ...old, [index]: !old[index] }));
}, []);
}, [setCopyStreamIdsForPath]);
const hideAllNotifications = hideNotifications === 'all';
@ -737,7 +737,7 @@ const App = memo(() => {
});
return newCopyStreamIds;
});
}, [copyAnyAudioTrack, filePath, mainStreams]);
}, [copyAnyAudioTrack, filePath, mainStreams, setCopyStreamIdsForPath]);
const removeCutSegment = useCallback((index) => {
if (cutSegments.length === 1 && cutSegments[0].start == null && cutSegments[0].end == null) return; // Initial segment
@ -1400,7 +1400,7 @@ const App = memo(() => {
resetState();
throw err;
}
}, [resetState, html5ifyAndLoad, loadEdlFile, getEdlFilePath, getEdlFilePathOld, loadCutSegments, enableAskForImportChapters, autoLoadTimecode, outFormatLocked, showPreviewFileLoadedMessage, rememberConvertToSupportedFormat, setWorking]);
}, [resetState, html5ifyAndLoad, loadEdlFile, getEdlFilePath, getEdlFilePathOld, loadCutSegments, enableAskForImportChapters, autoLoadTimecode, outFormatLocked, showPreviewFileLoadedMessage, rememberConvertToSupportedFormat, setWorking, setCopyStreamIdsForPath]);
const toggleHelp = useCallback(() => setHelpVisible(val => !val), []);
const toggleSettings = useCallback(() => setSettingsVisible(val => !val), []);
@ -1493,7 +1493,7 @@ const App = memo(() => {
// console.log('streams', streams);
setExternalStreamFiles(old => ({ ...old, [path]: { streams, formatData } }));
setCopyStreamIdsForPath(path, () => fromPairs(streams.map(({ index }) => [index, true])));
}, [externalStreamFiles]);
}, [externalStreamFiles, setCopyStreamIdsForPath]);
const userOpenSingleFile = useCallback(async ({ path: pathIn, isLlcProject }) => {
let path = pathIn;
@ -1977,7 +1977,7 @@ const App = memo(() => {
loadCutSegments, duration, checkFileOpened, loadMedia, fileFormat, reorderSegsByStartTime, closeFile, closeBatch, clearSegments, fixInvalidDuration, invertAllCutSegments,
]);
async function showAddStreamSourceDialog() {
const showAddStreamSourceDialog = useCallback(async () => {
try {
const { canceled, filePaths } = await dialog.showOpenDialog({ properties: ['openFile'] });
if (canceled || filePaths.length < 1) return;
@ -1985,7 +1985,7 @@ const App = memo(() => {
} catch (err) {
handleError(err);
}
}
}, [addStreamSourceFile]);
useEffect(() => {
async function onDrop(ev) {

View File

@ -1,4 +1,4 @@
import React, { memo } from 'react';
import React, { memo, useCallback } from 'react';
import { motion, AnimatePresence } from 'framer-motion';
import { Button, Select, CrossIcon } from 'evergreen-ui';
import i18n from 'i18next';
@ -52,39 +52,39 @@ const ExportConfirm = memo(({
const isMov = ffmpegIsMov(outFormat);
const isIpod = outFormat === 'ipod';
function onPreserveMovDataHelpPress() {
const onPreserveMovDataHelpPress = useCallback(() => {
toast.fire({ icon: 'info', timer: 10000, text: i18n.t('Preserve all MOV/MP4 metadata tags (e.g. EXIF, GPS position etc.) from source file? Note that some players have trouble playing back files where all metadata is preserved, like iTunes and other Apple software') });
}
}, []);
function onMovFastStartHelpPress() {
const onMovFastStartHelpPress = useCallback(() => {
toast.fire({ icon: 'info', timer: 10000, text: i18n.t('Enable this to allow faster playback of the resulting file. This may cause processing to take a little longer') });
}
}, []);
function onOutFmtHelpPress() {
const onOutFmtHelpPress = useCallback(() => {
toast.fire({ icon: 'info', timer: 10000, text: i18n.t('Defaults to same format as input file. You can losslessly change the file format (container) of the file with this option. Not all formats support all codecs. Matroska/MP4/MOV support the most common codecs. Sometimes it\'s even impossible to export to the same output format as input.') });
}
}, []);
function onKeyframeCutHelpPress() {
const onKeyframeCutHelpPress = useCallback(() => {
toast.fire({ icon: 'info', timer: 10000, text: i18n.t('With "keyframe cut", we will cut at the nearest keyframe before the desired start cutpoint. This is recommended for most files. With "Normal cut" you may have to manually set the cutpoint a few frames before the next keyframe to achieve a precise cut') });
}
}, []);
function onTracksHelpPress() {
const onTracksHelpPress = useCallback(() => {
toast.fire({ icon: 'info', timer: 10000, text: i18n.t('Not all formats support all track types, and LosslessCut is unable to properly cut some track types, so you may have to sacrifice some tracks by disabling them in order to get correct result.') });
}
}, []);
function onSegmentsToChaptersHelpPress() {
const onSegmentsToChaptersHelpPress = useCallback(() => {
toast.fire({ icon: 'info', timer: 10000, text: i18n.t('When merging, do you want to create chapters in the merged file, according to the cut segments? NOTE: This may dramatically increase processing time') });
}
}, []);
function onPreserveMetadataOnMergeHelpPress() {
const onPreserveMetadataOnMergeHelpPress = useCallback(() => {
toast.fire({ icon: 'info', timer: 10000, text: i18n.t('When merging, do you want to preserve metadata from your original file? NOTE: This may dramatically increase processing time') });
}
}, []);
function onOutSegTemplateHelpPress() {
const onOutSegTemplateHelpPress = useCallback(() => {
toast.fire({ icon: 'info', timer: 10000, text: i18n.t('You can customize the file name of the output segment(s) using special variables.') });
}
}, []);
function onAvoidNegativeTsHelpPress() {
const onAvoidNegativeTsHelpPress = useCallback(() => {
// https://ffmpeg.org/ffmpeg-all.html#Format-Options
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.'),
@ -93,7 +93,7 @@ const ExportConfirm = memo(({
disabled: i18n.t('Disables shifting of timestamp.'),
};
toast.fire({ icon: 'info', timer: 10000, text: `${avoidNegativeTs}: ${texts[avoidNegativeTs]}` });
}
}, [avoidNegativeTs]);
const outSegTemplateHelpIcon = <HelpIcon onClick={onOutSegTemplateHelpPress} />;

View File

@ -1,4 +1,4 @@
import React, { memo } from 'react';
import React, { memo, useCallback } from 'react';
import { Select } from 'evergreen-ui';
import { motion } from 'framer-motion';
import { FaYinYang } from 'react-icons/fa';
@ -14,14 +14,14 @@ const zoomOptions = Array(13).fill().map((unused, z) => 2 ** z);
const LeftMenu = memo(({ zoom, setZoom, invertCutSegments, setInvertCutSegments, toggleComfortZoom, simpleMode, toggleSimpleMode }) => {
const { t } = useTranslation();
function onYinYangClick() {
const onYinYangClick = useCallback(() => {
setInvertCutSegments(v => {
const newVal = !v;
if (newVal) toast.fire({ title: t('When you export, selected segments on the timeline will be REMOVED - the surrounding areas will be KEPT') });
else toast.fire({ title: t('When you export, selected segments on the timeline will be KEPT - the surrounding areas will be REMOVED.') });
return newVal;
});
}
}, [setInvertCutSegments, t]);
return (
<div className="no-user-select" style={{ padding: '.3em', display: 'flex', alignItems: 'center' }}>

View File

@ -1,4 +1,4 @@
import React, { memo, useMemo, useRef } from 'react';
import React, { memo, useMemo, useRef, useCallback } from 'react';
import prettyMs from 'pretty-ms';
import { FaSave, FaPlus, FaMinus, FaTag, FaSortNumericDown, FaAngleRight, FaCheck, FaTimes } from 'react-icons/fa';
import { AiOutlineSplitCells } from 'react-icons/ai';
@ -130,10 +130,10 @@ const SegmentList = memo(({
const sortableList = outSegments.map((seg) => ({ id: seg.segId, seg }));
function setSortableList(newList) {
const setSortableList = useCallback((newList) => {
if (isEqual(outSegments.map((s) => s.segId), newList.map((l) => l.id))) return; // No change
updateSegOrders(newList.map((list) => list.id));
}
}, [outSegments, updateSegOrders]);
let headerText = t('Segments to export:');
if (outSegments.length === 0) {

View File

@ -1,4 +1,4 @@
import React, { memo } from 'react';
import React, { memo, useCallback } from 'react';
import { FaYinYang } from 'react-icons/fa';
import { Button, Table, NumericalIcon, KeyIcon, FolderCloseIcon, DocumentIcon, TimeIcon, Checkbox, Select } from 'evergreen-ui';
import { useTranslation } from 'react-i18next';
@ -20,11 +20,11 @@ const Settings = memo(({
// eslint-disable-next-line react/jsx-props-no-spreading
const KeyCell = (props) => <Table.TextCell textProps={{ whiteSpace: 'auto' }} {...props} />;
function onLangChange(e) {
const onLangChange = useCallback((e) => {
const { value } = e.target;
const l = value !== '' ? value : undefined;
setLanguage(l);
}
}, [setLanguage]);
// https://www.electronjs.org/docs/api/locales
// See i18n.js

View File

@ -45,11 +45,11 @@ const SortableFiles = memo(({
const { t } = useTranslation();
function onSortClick() {
const onSortClick = useCallback(() => {
const newSortDesc = sortDesc == null ? false : !sortDesc;
setItems(orderBy(items, undefined, [newSortDesc ? 'desc' : 'asc']));
setSortDesc(newSortDesc);
}
}, [items, sortDesc]);
return (
<div style={{ textAlign: 'left' }}>

View File

@ -1,4 +1,4 @@
import React, { memo, useState, useMemo } from 'react';
import React, { memo, useState, useMemo, useCallback } from 'react';
import { FaCheckCircle, FaPaperclip, FaVideo, FaVideoSlash, FaFileImport, FaVolumeUp, FaVolumeMute, FaBan, FaFileExport } from 'react-icons/fa';
import { GoFileBinary } from 'react-icons/go';
@ -23,13 +23,13 @@ const TagEditor = memo(({ existingTags, customTags, onTagChange, onTagReset }) =
const [editingTagVal, setEditingTagVal] = useState();
const [newTag, setNewTag] = useState();
const mergedTags = { ...existingTags, ...customTags, ...(newTag ? { [newTag]: '' } : {}) };
const mergedTags = useMemo(() => ({ ...existingTags, ...customTags, ...(newTag ? { [newTag]: '' } : {}) }), [customTags, existingTags, newTag]);
function onResetClick() {
const onResetClick = useCallback(() => {
onTagReset(editingTag);
setEditingTag();
setNewTag();
}
}, [editingTag, onTagReset]);
function onEditClick(tag) {
if (newTag) {
@ -54,13 +54,13 @@ const TagEditor = memo(({ existingTags, customTags, onTagChange, onTagReset }) =
onEditClick();
}
async function onAddPress() {
const onAddPress = useCallback(async () => {
const tag = await askForMetadataKey();
if (!tag || Object.keys(mergedTags).includes(tag)) return;
setEditingTag(tag);
setEditingTagVal('');
setNewTag(tag);
}
}, [mergedTags]);
return (
<>
@ -103,16 +103,16 @@ const EditFileDialog = memo(({ editingFile, externalFiles, mainFileFormatData, m
const existingTags = formatData.tags || {};
const customTags = customTagsByFile[editingFile] || {};
function onTagChange(tag, value) {
const onTagChange = useCallback((tag, value) => {
setCustomTagsByFile((old) => ({ ...old, [editingFile]: { ...old[editingFile], [tag]: value } }));
}
}, [editingFile, setCustomTagsByFile]);
function onTagReset(tag) {
const onTagReset = useCallback((tag) => {
setCustomTagsByFile((old) => {
const { [tag]: deleted, ...rest } = old[editingFile] || {};
return { ...old, [editingFile]: rest };
});
}
}, [editingFile, setCustomTagsByFile]);
return <TagEditor existingTags={existingTags} customTags={customTags} onTagChange={onTagChange} onTagReset={onTagReset} />;
});
@ -132,7 +132,7 @@ const EditStreamDialog = memo(({ editingStream: { streamId: editingStreamId, pat
const { t } = useTranslation();
function onTagChange(tag, value) {
const onTagChange = useCallback((tag, value) => {
setCustomTagsByStreamId((old) => ({
...old,
[editingFile]: {
@ -143,9 +143,9 @@ const EditStreamDialog = memo(({ editingStream: { streamId: editingStreamId, pat
},
},
}));
}
}, [editingFile, editingStreamId, setCustomTagsByStreamId]);
function onTagReset(tag) {
const onTagReset = useCallback((tag) => {
setCustomTagsByStreamId((old) => {
const { [tag]: deleted, ...rest } = (old[editingFile] || {})[editingStreamId] || {};
@ -157,9 +157,9 @@ const EditStreamDialog = memo(({ editingStream: { streamId: editingStreamId, pat
},
};
});
}
}, [editingFile, editingStreamId, setCustomTagsByStreamId]);
function onCoverArtChange(e) {
const onCoverArtChange = useCallback((e) => {
const newDispositions = dispositionOptions.includes(e.target.value) ? {
[e.target.value]: 1,
} : undefined;
@ -173,7 +173,7 @@ const EditStreamDialog = memo(({ editingStream: { streamId: editingStreamId, pat
[editingStreamId]: newDispositions,
},
}));
}
}, [editingFile, editingStreamId, setDispositionByStreamId]);
if (!stream) return null;

View File

@ -52,15 +52,15 @@ const OutSegTemplateEditor = memo(({ helpIcon, outSegTemplate, setOutSegTemplate
if (validText != null) setOutSegTemplate(validText);
}, [validText, setOutSegTemplate]);
function reset() {
const reset = useCallback(() => {
setOutSegTemplate(defaultOutSegTemplate);
setText(defaultOutSegTemplate);
}
}, [setOutSegTemplate]);
function onToggleClick() {
const onToggleClick = useCallback(() => {
if (!shown) setShown(true);
else if (error == null) setShown(false);
}
}, [error, shown]);
const onTextChange = useCallback((e) => setText(e.target.value), []);

View File

@ -1,4 +1,4 @@
import React, { useState } from 'react';
import React, { useState, useCallback } from 'react';
import { Checkbox, RadioGroup, Paragraph } from 'evergreen-ui';
import Swal from 'sweetalert2';
import i18n from 'i18next';
@ -65,14 +65,14 @@ export async function askForHtml5ifySpeed({ allowedOptions, showRemember, initia
const Html = () => {
const [option, setOption] = useState(selectedOption);
const [remember, setRemember] = useState(rememberChoice);
function onOptionChange(e) {
const onOptionChange = useCallback((e) => {
selectedOption = e.target.value;
setOption(selectedOption);
}
function onRememberChange(e) {
}, []);
const onRememberChange = useCallback((e) => {
rememberChoice = e.target.checked;
setRemember(rememberChoice);
}
}, []);
return (
<div style={{ textAlign: 'left' }}>
<Paragraph>{i18n.t('These options will let you convert files to a format that is supported by the player. You can try different options and see which works with your file. Note that the conversion is for preview only. When you run an export, the output will still be lossless with full quality')}</Paragraph>

651
yarn.lock

File diff suppressed because it is too large Load Diff