-
+
+
{formatTimeAndFrames(displayTime)}{isZoomed ? ` ${displayTimePercent}` : ''}
diff --git a/src/TopMenu.jsx b/src/TopMenu.jsx
index 29fdd954..22abe0e3 100644
--- a/src/TopMenu.jsx
+++ b/src/TopMenu.jsx
@@ -1,8 +1,9 @@
import React, { memo, useCallback } from 'react';
import { IoIosSettings } from 'react-icons/io';
import { FaLock, FaUnlock } from 'react-icons/fa';
-import { IconButton, Button, CrossIcon, ListIcon, VolumeUpIcon, VolumeOffIcon } from 'evergreen-ui';
+import { IconButton, CrossIcon, ListIcon, VolumeUpIcon, VolumeOffIcon } from 'evergreen-ui';
import { useTranslation } from 'react-i18next';
+import Button from './components/Button';
import ExportModeButton from './components/ExportModeButton';
@@ -11,6 +12,9 @@ import { primaryTextColor, controlsBackground, darkModeTransition } from './colo
import useUserSettings from './hooks/useUserSettings';
+const outFmtStyle = { height: 20, maxWidth: 100 };
+const exportModeStyle = { flexGrow: 0, flexBasis: 140 };
+
const TopMenu = memo(({
filePath, fileFormat, copyAnyAudioTrack, toggleStripAudio,
renderOutFmt, numStreamsToCopy, numStreamsTotal, setStreamsSelectorShown, toggleSettings,
@@ -35,17 +39,20 @@ const TopMenu = memo(({
>
{filePath && (
<>
-
);
});
diff --git a/src/components/Button.jsx b/src/components/Button.jsx
new file mode 100644
index 00000000..65b4223d
--- /dev/null
+++ b/src/components/Button.jsx
@@ -0,0 +1,10 @@
+import React, { memo } from 'react';
+
+import styles from './Button.module.css';
+
+const Button = memo(({ type = 'button', ...props }) => (
+ // eslint-disable-next-line react/jsx-props-no-spreading, react/button-has-type
+
+));
+
+export default Button;
diff --git a/src/components/Button.module.css b/src/components/Button.module.css
new file mode 100644
index 00000000..f473ced1
--- /dev/null
+++ b/src/components/Button.module.css
@@ -0,0 +1,12 @@
+.button {
+ appearance: none;
+ font: inherit;
+ line-height: 140%;
+ font-size: .8em;
+ background-color: var(--gray3);
+ color: var(--gray12);
+ border-radius: .3em;
+ padding: 0 .5em 0 .3em;
+ outline: .05em solid var(--gray8);
+ border: .05em solid var(--gray7);
+}
diff --git a/src/hooks/useFrameCapture.js b/src/hooks/useFrameCapture.js
index 6dde5d89..01005f1e 100644
--- a/src/hooks/useFrameCapture.js
+++ b/src/hooks/useFrameCapture.js
@@ -1,5 +1,6 @@
import dataUriToBuffer from 'data-uri-to-buffer';
import pMap from 'p-map';
+import { useCallback } from 'react';
import { getSuffixedOutPath, getOutDir, transferTimestamps, getSuffixedFileName, getOutPath, escapeRegExp, fsOperationWithRetry } from '../util';
import { getNumDigits } from '../segments';
@@ -23,7 +24,7 @@ function getFrameFromVideo(video, format, quality) {
}
export default ({ formatTimecode, treatOutputFileModifiedTimeAsStart }) => {
- async function captureFramesRange({ customOutDir, filePath, fps, fromTime, toTime, estimatedMaxNumFiles, captureFormat, quality, filter, onProgress, outputTimestamps }) {
+ const captureFramesRange = useCallback(async ({ customOutDir, filePath, fps, fromTime, toTime, estimatedMaxNumFiles, captureFormat, quality, filter, onProgress, outputTimestamps }) => {
const getSuffix = (prefix) => `${prefix}.${captureFormat}`;
if (!outputTimestamps) {
@@ -67,9 +68,9 @@ export default ({ formatTimecode, treatOutputFileModifiedTimeAsStart }) => {
}, { concurrency: 1 });
return outPaths[0];
- }
+ }, [formatTimecode]);
- async function captureFrameFromFfmpeg({ customOutDir, filePath, fromTime, captureFormat, quality }) {
+ const captureFrameFromFfmpeg = useCallback(async ({ customOutDir, filePath, fromTime, captureFormat, quality }) => {
const time = formatTimecode({ seconds: fromTime, fileNameFriendly: true });
const nameSuffix = `${time}.${captureFormat}`;
const outPath = getSuffixedOutPath({ customOutDir, filePath, nameSuffix });
@@ -77,9 +78,9 @@ export default ({ formatTimecode, treatOutputFileModifiedTimeAsStart }) => {
await transferTimestamps({ inPath: filePath, outPath, cutFrom: fromTime, treatOutputFileModifiedTimeAsStart });
return outPath;
- }
+ }, [formatTimecode, treatOutputFileModifiedTimeAsStart]);
- async function captureFrameFromTag({ customOutDir, filePath, currentTime, captureFormat, video, quality }) {
+ const captureFrameFromTag = useCallback(async ({ customOutDir, filePath, currentTime, captureFormat, video, quality }) => {
const buf = getFrameFromVideo(video, captureFormat, quality);
const ext = mime.extension(buf.type);
@@ -90,7 +91,7 @@ export default ({ formatTimecode, treatOutputFileModifiedTimeAsStart }) => {
await transferTimestamps({ inPath: filePath, outPath, cutFrom: currentTime, treatOutputFileModifiedTimeAsStart });
return outPath;
- }
+ }, [formatTimecode, treatOutputFileModifiedTimeAsStart]);
return {
captureFramesRange,
diff --git a/src/hooks/useWhatChanged.js b/src/hooks/useWhatChanged.js
new file mode 100644
index 00000000..3cbd41d5
--- /dev/null
+++ b/src/hooks/useWhatChanged.js
@@ -0,0 +1,29 @@
+import React from 'react';
+
+// https://stackoverflow.com/questions/64997362/how-do-i-see-what-props-have-changed-in-react
+export default function useWhatChanged(props) {
+ // cache the last set of props
+ const prev = React.useRef(props);
+
+ React.useEffect(() => {
+ // check each prop to see if it has changed
+ const changed = Object.entries(props).reduce((a, [key, prop]) => {
+ if (prev.current[key] === prop) return a;
+ return {
+ ...a,
+ [key]: {
+ prev: prev.current[key],
+ next: prop,
+ },
+ };
+ }, {});
+
+ if (Object.keys(changed).length > 0) {
+ console.group('Props That Changed');
+ console.log(changed);
+ console.groupEnd();
+ }
+
+ prev.current = props;
+ }, [props]);
+}