fix types

pull/2298/head
Mikael Finstad 11 months ago
parent 241210d103
commit 241210ca3b
No known key found for this signature in database
GPG Key ID: 25AB36E3E81CBC26

@ -70,8 +70,8 @@
"@vitejs/plugin-react": "^4.3.1", "@vitejs/plugin-react": "^4.3.1",
"color": "^3.1.0", "color": "^3.1.0",
"concurrently": "^6.0.0", "concurrently": "^6.0.0",
"csv-parse": "^4.15.3", "csv-parse": "^5.6.0",
"csv-stringify": "^5.6.2", "csv-stringify": "^6.5.2",
"data-uri-to-buffer": "^4.0.0", "data-uri-to-buffer": "^4.0.0",
"electron": "^33.2.1", "electron": "^33.2.1",
"electron-builder": "^24.13.3", "electron-builder": "^24.13.3",
@ -99,7 +99,6 @@
"nanoid": "^5.0.9", "nanoid": "^5.0.9",
"p-map": "^5.5.0", "p-map": "^5.5.0",
"p-retry": "^6.2.0", "p-retry": "^6.2.0",
"pify": "^5.0.0",
"pretty-bytes": "^6.0.0", "pretty-bytes": "^6.0.0",
"react": "^18.2.0", "react": "^18.2.0",
"react-dom": "^18.2.0", "react-dom": "^18.2.0",

@ -759,7 +759,7 @@ function App() {
setSelectedBatchFiles([]); setSelectedBatchFiles([]);
}, [askBeforeClose]); }, [askBeforeClose]);
const batchListRemoveFile = useCallback((path) => { const batchListRemoveFile = useCallback((path: string | undefined) => {
setBatchFiles((existingBatch) => { setBatchFiles((existingBatch) => {
const index = existingBatch.findIndex((existingFile) => existingFile.path === path); const index = existingBatch.findIndex((existingFile) => existingFile.path === path);
if (index < 0) return existingBatch; if (index < 0) return existingBatch;
@ -1246,7 +1246,7 @@ function App() {
const storeProjectInSourceDir = !storeProjectInWorkingDir; const storeProjectInSourceDir = !storeProjectInWorkingDir;
async function tryFindAndLoadProjectFile({ chapters, cod }: { chapters, cod: string | undefined }) { async function tryFindAndLoadProjectFile({ chapters, cod }: { chapters: FFprobeChapter[], cod: string | undefined }) {
try { try {
// First try to open from from working dir // First try to open from from working dir
if (await tryOpenProjectPath(getEdlFilePath(fp, cod), 'llc')) return; if (await tryOpenProjectPath(getEdlFilePath(fp, cod), 'llc')) return;
@ -1658,7 +1658,7 @@ function App() {
const batchLoadPaths = useCallback((newPaths: string[], append?: boolean) => { const batchLoadPaths = useCallback((newPaths: string[], append?: boolean) => {
setBatchFiles((existingFiles) => { setBatchFiles((existingFiles) => {
const mapPathsToFiles = (paths) => paths.map((path) => ({ path, name: basename(path) })); const mapPathsToFiles = (paths: string[]) => paths.map((path) => ({ path, name: basename(path) }));
if (append) { if (append) {
const newUniquePaths = newPaths.filter((newPath) => !existingFiles.some(({ path: existingPath }) => newPath === existingPath)); const newUniquePaths = newPaths.filter((newPath) => !existingFiles.some(({ path: existingPath }) => newPath === existingPath));
const [firstNewUniquePath] = newUniquePaths; const [firstNewUniquePath] = newUniquePaths;

@ -1,4 +1,4 @@
import { CSSProperties, Dispatch, SetStateAction, memo, useCallback, useEffect, useMemo, useState } from 'react'; import { CSSProperties, ClipboardEvent, Dispatch, FormEvent, SetStateAction, memo, useCallback, useEffect, useMemo, useState } from 'react';
import { motion } from 'framer-motion'; import { motion } from 'framer-motion';
import { MdRotate90DegreesCcw } from 'react-icons/md'; import { MdRotate90DegreesCcw } from 'react-icons/md';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
@ -100,7 +100,7 @@ const CutTimeInput = memo(({ darkMode, cutTime, setCutTime, startTimeOffset, see
border, borderRadius: 5, backgroundColor: 'var(--gray5)', transition: darkModeTransition, fontSize: 13, textAlign: 'center', padding: '1px 5px', marginTop: 0, marginBottom: 0, marginLeft: isStart ? 0 : 5, marginRight: isStart ? 5 : 0, boxSizing: 'border-box', fontFamily: 'inherit', width: 90, outline: 'none', border, borderRadius: 5, backgroundColor: 'var(--gray5)', transition: darkModeTransition, fontSize: 13, textAlign: 'center', padding: '1px 5px', marginTop: 0, marginBottom: 0, marginLeft: isStart ? 0 : 5, marginRight: isStart ? 5 : 0, boxSizing: 'border-box', fontFamily: 'inherit', width: 90, outline: 'none',
}; };
const trySetTime = useCallback((timeWithOffset) => { const trySetTime = useCallback((timeWithOffset: number) => {
const timeWithoutOffset = Math.max(timeWithOffset - startTimeOffset, 0); const timeWithoutOffset = Math.max(timeWithOffset - startTimeOffset, 0);
try { try {
setCutTime(isStart ? 'start' : 'end', timeWithoutOffset); setCutTime(isStart ? 'start' : 'end', timeWithoutOffset);
@ -113,7 +113,7 @@ const CutTimeInput = memo(({ darkMode, cutTime, setCutTime, startTimeOffset, see
} }
}, [isStart, seekAbs, setCutTime, startTimeOffset]); }, [isStart, seekAbs, setCutTime, startTimeOffset]);
const handleSubmit = useCallback((e) => { const handleSubmit = useCallback((e: FormEvent<HTMLFormElement>) => {
e.preventDefault(); e.preventDefault();
// Don't proceed if not a valid time value // Don't proceed if not a valid time value
@ -123,7 +123,7 @@ const CutTimeInput = memo(({ darkMode, cutTime, setCutTime, startTimeOffset, see
trySetTime(timeWithOffset); trySetTime(timeWithOffset);
}, [cutTimeManual, parseTimecode, trySetTime]); }, [cutTimeManual, parseTimecode, trySetTime]);
const parseAndSetCutTime = useCallback((text) => { const parseAndSetCutTime = useCallback((text: string) => {
// Don't proceed if not a valid time value // Don't proceed if not a valid time value
const timeWithOffset = parseTimecode(text); const timeWithOffset = parseTimecode(text);
if (timeWithOffset === undefined) return; if (timeWithOffset === undefined) return;
@ -131,13 +131,13 @@ const CutTimeInput = memo(({ darkMode, cutTime, setCutTime, startTimeOffset, see
trySetTime(timeWithOffset); trySetTime(timeWithOffset);
}, [parseTimecode, trySetTime]); }, [parseTimecode, trySetTime]);
function handleCutTimeInput(text) { function handleCutTimeInput(text: string) {
setCutTimeManual(text); setCutTimeManual(text);
if (isExactDurationMatch(text)) parseAndSetCutTime(text); if (isExactDurationMatch(text)) parseAndSetCutTime(text);
} }
const tryPaste = useCallback((clipboardText) => { const tryPaste = useCallback((clipboardText: string) => {
try { try {
setCutTimeManual(clipboardText); setCutTimeManual(clipboardText);
parseAndSetCutTime(clipboardText); parseAndSetCutTime(clipboardText);
@ -146,7 +146,7 @@ const CutTimeInput = memo(({ darkMode, cutTime, setCutTime, startTimeOffset, see
} }
}, [parseAndSetCutTime]); }, [parseAndSetCutTime]);
const handleCutTimePaste = useCallback((e) => { const handleCutTimePaste = useCallback((e: ClipboardEvent<HTMLInputElement>) => {
e.preventDefault(); e.preventDefault();
try { try {

@ -1,18 +1,15 @@
import { XMLParser } from 'fast-xml-parser'; import { XMLParser } from 'fast-xml-parser';
import i18n from 'i18next'; import i18n from 'i18next';
import csvParse from 'csv-parse/lib/browser'; import { parse as csvParse } from 'csv-parse/browser/esm/sync';
import csvStringify from 'csv-stringify/lib/browser'; import { stringify as csvStringify } from 'csv-stringify/browser/esm/sync';
import pify from 'pify';
import sortBy from 'lodash/sortBy'; import sortBy from 'lodash/sortBy';
import type { ICueSheet, ITrack } from 'cue-parser/lib/types'; import type { ICueSheet, ITrack } from 'cue-parser/lib/types';
import { formatDuration } from './util/duration'; import { formatDuration } from './util/duration';
import { invertSegments, sortSegments } from './segments'; import { invertSegments, sortSegments } from './segments';
import { Segment, SegmentBase } from './types'; import { GetFrameCount, Segment, SegmentBase } from './types';
import invariant from 'tiny-invariant';
const csvParseAsync = pify(csvParse);
const csvStringifyAsync = pify(csvStringify);
export const getTimeFromFrameNum = (detectedFps: number, frameNum: number) => frameNum / detectedFps; export const getTimeFromFrameNum = (detectedFps: number, frameNum: number) => frameNum / detectedFps;
@ -48,7 +45,7 @@ export const getFrameValParser = (fps: number) => (str: string) => {
}; };
export async function parseCsv(csvStr: string, parseTimeFn: (a: string) => number | undefined) { export async function parseCsv(csvStr: string, parseTimeFn: (a: string) => number | undefined) {
const rows = await csvParseAsync(csvStr, {}) as [string, string, string][]; const rows = csvParse(csvStr, {}) as [string, string, string][];
if (rows.length === 0) throw new Error(i18n.t('No rows found')); if (rows.length === 0) throw new Error(i18n.t('No rows found'));
if (!rows.every((row) => row.length === 3)) throw new Error(i18n.t('One or more rows does not have 3 columns')); if (!rows.every((row) => row.length === 3)) throw new Error(i18n.t('One or more rows does not have 3 columns'));
@ -77,61 +74,56 @@ export async function parseCutlist(clStr: string) {
param: /^\s*([^=]+?)\s*=\s*(.*?)\s*$/, param: /^\s*([^=]+?)\s*=\s*(.*?)\s*$/,
comment: /^\s*;.*$/, comment: /^\s*;.*$/,
}; };
const iniValue = {}; const iniValue: Record<string, string | undefined | Record<string, string | undefined>> = {};
const lines = clStr.split(/[\n\r]+/); const lines = clStr.split(/[\n\r]+/);
let section: string | null | undefined = null; let section: string | undefined;
lines.forEach((line) => { lines.forEach((line) => {
if (regex.comment.test(line)) { if (regex.comment.test(line)) {
return; return;
} if (regex.param.test(line)) { }
if (regex.param.test(line)) {
const match = line.match(regex.param) || []; const match = line.match(regex.param) || [];
const [, m1, m2] = match; const [, key, value] = match;
if (m1) { if (key) {
if (section) { if (section) {
iniValue[section][m1] = m2; const sectionObj = iniValue[section];
invariant(sectionObj != null && typeof sectionObj !== 'string');
sectionObj[key] = value;
} else { } else {
iniValue[m1] = m2; iniValue[key] = value;
} }
} }
} else if (regex.section.test(line)) { } else if (regex.section.test(line)) {
const match = line.match(regex.section) || []; const match = line.match(regex.section) || [];
const [, m1] = match; const [, sectionMatch] = match;
if (m1) { if (sectionMatch) {
iniValue[m1] = {}; iniValue[sectionMatch] = {};
section = m1; section = sectionMatch;
} }
} else if (line.length === 0 && section) { } else if (line.length === 0 && section) {
section = null; section = undefined;
} }
}); });
// end INI-File parse // end INI-File parse
let found = true;
let i = 0;
const cutArr: { start: number, end: number, name: string }[] = []; const cutArr: { start: number, end: number, name: string }[] = [];
while (found) { for (let i = 0; ; i += 1) {
const cutEntry = iniValue[`Cut${i}`]; const cutEntry = iniValue[`Cut${i}`];
if (cutEntry) { if (cutEntry && typeof cutEntry !== 'string') {
const start = parseFloat(cutEntry.Start); const start = parseFloat(cutEntry['Start']!);
const end = Math.round((start + parseFloat(cutEntry.Duration) + Number.EPSILON) * 100) / 100; const end = Math.round((start + parseFloat(cutEntry['Duration']!) + Number.EPSILON) * 100) / 100;
invariant(!Number.isNaN(start), 'Invalid Start');
invariant(!Number.isNaN(end), 'Invalid End');
cutArr.push({ cutArr.push({
start, start,
end, end,
name: `Cut ${i}`, name: `Cut ${i}`,
}); });
} else { } else {
found = false; break;
} }
i += 1;
}
if (!cutArr.every(({ start, end }) => (
(start === undefined || !Number.isNaN(start))
&& (end === undefined || !Number.isNaN(end))
))) {
console.log(cutArr);
throw new Error(i18n.t('Invalid start or end value. Must contain a number of seconds'));
} }
return cutArr; return cutArr;
@ -295,7 +287,7 @@ export function parseYouTube(str: string) {
return edl.filter((ed) => ed.start !== ed.end); return edl.filter((ed) => ed.start !== ed.end);
} }
export function formatYouTube(segments) { export function formatYouTube(segments: Segment[]) {
return segments.map((segment) => { return segments.map((segment) => {
const timeStr = formatDuration({ seconds: segment.start, showFraction: false, shorten: true }); const timeStr = formatDuration({ seconds: segment.start, showFraction: false, shorten: true });
const namePart = segment.name ? ` ${segment.name}` : ''; const namePart = segment.name ? ` ${segment.name}` : '';
@ -304,16 +296,16 @@ export function formatYouTube(segments) {
} }
// because null/undefined is also valid values (start/end of timeline) // because null/undefined is also valid values (start/end of timeline)
const safeFormatDuration = (duration) => (duration != null ? formatDuration({ seconds: duration }) : ''); const safeFormatDuration = (duration: number | undefined) => (duration != null ? formatDuration({ seconds: duration }) : '');
export const formatSegmentsTimes = (cutSegments) => cutSegments.map(({ start, end, name }) => [ export const formatSegmentsTimes = (cutSegments: Segment[]) => cutSegments.map(({ start, end, name }) => [
safeFormatDuration(start), safeFormatDuration(start),
safeFormatDuration(end), safeFormatDuration(end),
name, name,
]); ]);
export async function formatCsvFrames({ cutSegments, getFrameCount }) { export async function formatCsvFrames({ cutSegments, getFrameCount }: { cutSegments: Segment[], getFrameCount: GetFrameCount }) {
const safeFormatFrameCount = (seconds) => (seconds != null ? getFrameCount(seconds) : ''); const safeFormatFrameCount = (seconds: number | undefined) => (seconds != null ? getFrameCount(seconds) : '');
const formatted = cutSegments.map(({ start, end, name }) => [ const formatted = cutSegments.map(({ start, end, name }) => [
safeFormatFrameCount(start), safeFormatFrameCount(start),
@ -321,20 +313,20 @@ export async function formatCsvFrames({ cutSegments, getFrameCount }) {
name, name,
]); ]);
return csvStringifyAsync(formatted); return csvStringify(formatted);
} }
export async function formatCsvSeconds(cutSegments) { export async function formatCsvSeconds(cutSegments: Segment[]) {
const rows = cutSegments.map(({ start, end, name }) => [start, end, name]); const rows = cutSegments.map(({ start, end, name }) => [start, end, name]);
return csvStringifyAsync(rows); return csvStringify(rows);
} }
export async function formatCsvHuman(cutSegments) { export async function formatCsvHuman(cutSegments: Segment[]) {
return csvStringifyAsync(formatSegmentsTimes(cutSegments)); return csvStringify(formatSegmentsTimes(cutSegments));
} }
export async function formatTsv(cutSegments) { export async function formatTsv(cutSegments: Segment[]) {
return csvStringifyAsync(formatSegmentsTimes(cutSegments), { delimiter: '\t' }); return csvStringify(formatSegmentsTimes(cutSegments), { delimiter: '\t' });
} }
export function parseDvAnalyzerSummaryTxt(txt: string) { export function parseDvAnalyzerSummaryTxt(txt: string) {
@ -424,7 +416,7 @@ export function parseSrtToSegments(text: string) {
})); }));
} }
export function formatSrt(segments) { export function formatSrt(segments: Segment[]) {
return segments.reduce((acc, segment, index) => `${acc}${index > 0 ? '\r\n' : ''}${index + 1}\r\n${formatDuration({ seconds: segment.start }).replaceAll('.', ',')} --> ${formatDuration({ seconds: segment.end }).replaceAll('.', ',')}\r\n${segment.name || '-'}\r\n`, ''); return segments.reduce((acc, segment, index) => `${acc}${index > 0 ? '\r\n' : ''}${index + 1}\r\n${formatDuration({ seconds: segment.start }).replaceAll('.', ',')} --> ${formatDuration({ seconds: segment.end }).replaceAll('.', ',')}\r\n${segment.name || '-'}\r\n`, '');
} }

@ -4005,17 +4005,17 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"csv-parse@npm:^4.15.3": "csv-parse@npm:^5.6.0":
version: 4.16.3 version: 5.6.0
resolution: "csv-parse@npm:4.16.3" resolution: "csv-parse@npm:5.6.0"
checksum: 10/b873dd2d312ac0329200f13788176bae3073862241483b0339a4777c9eddcebd9f2f48f13d02dc0baf4bc02e957f886ea03a9cb22160d70836b0017432f8fa41 checksum: 10/4c82e11f50ae0ccbac2aed716ef2502d0468bf96552083561db789fc0258ee4bb0a30106fcfb2684f153cb4042f0413e0eac3645d5466874803b7ccdeba67ac8
languageName: node languageName: node
linkType: hard linkType: hard
"csv-stringify@npm:^5.6.2": "csv-stringify@npm:^6.5.2":
version: 5.6.5 version: 6.5.2
resolution: "csv-stringify@npm:5.6.5" resolution: "csv-stringify@npm:6.5.2"
checksum: 10/efed94869b8426e6a983f2237bd74eff15953e2e27affee9c1324f66a67dabe948573c4c21a8661a79aa20b58efbcafcf11c34e80bdd532a43f35e9cde5985b9 checksum: 10/7715664020d291ccece25a32ecca617cea8d7e320af0c4e58cabbfb52d914832c3ea63c77c9796ca032ce6b47b899c879140c55bfd380105c42038ec305607a3
languageName: node languageName: node
linkType: hard linkType: hard
@ -7604,8 +7604,8 @@ __metadata:
"@vitejs/plugin-react": "npm:^4.3.1" "@vitejs/plugin-react": "npm:^4.3.1"
color: "npm:^3.1.0" color: "npm:^3.1.0"
concurrently: "npm:^6.0.0" concurrently: "npm:^6.0.0"
csv-parse: "npm:^4.15.3" csv-parse: "npm:^5.6.0"
csv-stringify: "npm:^5.6.2" csv-stringify: "npm:^6.5.2"
cue-parser: "npm:^0.3.0" cue-parser: "npm:^0.3.0"
data-uri-to-buffer: "npm:^4.0.0" data-uri-to-buffer: "npm:^4.0.0"
electron: "npm:^33.2.1" electron: "npm:^33.2.1"
@ -7647,7 +7647,6 @@ __metadata:
nanoid: "npm:^5.0.9" nanoid: "npm:^5.0.9"
p-map: "npm:^5.5.0" p-map: "npm:^5.5.0"
p-retry: "npm:^6.2.0" p-retry: "npm:^6.2.0"
pify: "npm:^5.0.0"
pretty-bytes: "npm:^6.0.0" pretty-bytes: "npm:^6.0.0"
react: "npm:^18.2.0" react: "npm:^18.2.0"
react-dom: "npm:^18.2.0" react-dom: "npm:^18.2.0"
@ -8780,13 +8779,6 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"pify@npm:^5.0.0":
version: 5.0.0
resolution: "pify@npm:5.0.0"
checksum: 10/443e3e198ad6bfa8c0c533764cf75c9d5bc976387a163792fb553ffe6ce923887cf14eebf5aea9b7caa8eab930da8c33612990ae85bd8c2bc18bedb9eae94ecb
languageName: node
linkType: hard
"pkg-up@npm:^3.0.1": "pkg-up@npm:^3.0.1":
version: 3.1.0 version: 3.1.0
resolution: "pkg-up@npm:3.1.0" resolution: "pkg-up@npm:3.1.0"

Loading…
Cancel
Save