mirror of
https://github.com/mifi/lossless-cut.git
synced 2024-11-25 03:33:14 +01:00
parent
b855e9e7d1
commit
cc202b4845
@ -2281,11 +2281,21 @@ function App() {
|
|||||||
|
|
||||||
focusWindow();
|
focusWindow();
|
||||||
|
|
||||||
await userOpenFiles(filePaths);
|
userOpenFiles(filePaths);
|
||||||
|
}
|
||||||
|
const element = videoContainerRef.current;
|
||||||
|
element?.addEventListener('drop', onDrop);
|
||||||
|
return () => element?.removeEventListener('drop', onDrop);
|
||||||
|
}, [userOpenFiles, videoContainerRef]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
function onDrop(ev: DragEvent) {
|
||||||
|
// default drop handler to prevent new electron window from popping up https://github.com/electron/electron/issues/39839
|
||||||
|
ev.preventDefault();
|
||||||
}
|
}
|
||||||
document.body.addEventListener('drop', onDrop);
|
document.body.addEventListener('drop', onDrop);
|
||||||
return () => document.body.removeEventListener('drop', onDrop);
|
return () => document.body.removeEventListener('drop', onDrop);
|
||||||
}, [userOpenFiles]);
|
}, []);
|
||||||
|
|
||||||
const renderOutFmt = useCallback((style: CSSProperties) => (
|
const renderOutFmt = useCallback((style: CSSProperties) => (
|
||||||
<OutputFormatSelect style={style} detectedFileFormat={detectedFileFormat} fileFormat={fileFormat} onOutputFormatUserChange={onOutputFormatUserChange} />
|
<OutputFormatSelect style={style} detectedFileFormat={detectedFileFormat} fileFormat={fileFormat} onOutputFormatUserChange={onOutputFormatUserChange} />
|
||||||
|
@ -5,11 +5,15 @@ import { useTranslation, Trans } from 'react-i18next';
|
|||||||
import SetCutpointButton from './components/SetCutpointButton';
|
import SetCutpointButton from './components/SetCutpointButton';
|
||||||
import SimpleModeButton from './components/SimpleModeButton';
|
import SimpleModeButton from './components/SimpleModeButton';
|
||||||
import useUserSettings from './hooks/useUserSettings';
|
import useUserSettings from './hooks/useUserSettings';
|
||||||
|
import { StateSegment } from './types';
|
||||||
|
|
||||||
const electron = window.require('electron');
|
const electron = window.require('electron');
|
||||||
|
|
||||||
function NoFileLoaded({ mifiLink, currentCutSeg, onClick, darkMode }: {
|
function NoFileLoaded({ mifiLink, currentCutSeg, onClick, darkMode }: {
|
||||||
mifiLink: unknown, currentCutSeg, onClick: () => void, darkMode?: boolean,
|
mifiLink: unknown,
|
||||||
|
currentCutSeg: StateSegment,
|
||||||
|
onClick: () => void,
|
||||||
|
darkMode?: boolean,
|
||||||
}) {
|
}) {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const { simpleMode } = useUserSettings();
|
const { simpleMode } = useUserSettings();
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { CSSProperties, ReactNode, memo, useCallback } from 'react';
|
import { CSSProperties, ReactNode, memo, useCallback, useEffect, useRef } from 'react';
|
||||||
import { IoIosSettings } from 'react-icons/io';
|
import { IoIosSettings } from 'react-icons/io';
|
||||||
import { FaLock, FaUnlock } from 'react-icons/fa';
|
import { FaLock, FaUnlock } from 'react-icons/fa';
|
||||||
import { CrossIcon, ListIcon, VolumeUpIcon, VolumeOffIcon } from 'evergreen-ui';
|
import { CrossIcon, ListIcon, VolumeUpIcon, VolumeOffIcon } from 'evergreen-ui';
|
||||||
@ -13,6 +13,8 @@ import useUserSettings from './hooks/useUserSettings';
|
|||||||
import { InverseCutSegment } from './types';
|
import { InverseCutSegment } from './types';
|
||||||
|
|
||||||
|
|
||||||
|
const { stat } = window.require('fs/promises');
|
||||||
|
|
||||||
const outFmtStyle = { height: 20, maxWidth: 100 };
|
const outFmtStyle = { height: 20, maxWidth: 100 };
|
||||||
const exportModeStyle = { flexGrow: 0, flexBasis: 140 };
|
const exportModeStyle = { flexGrow: 0, flexBasis: 140 };
|
||||||
|
|
||||||
@ -44,7 +46,8 @@ function TopMenu({
|
|||||||
clearOutDir: () => void,
|
clearOutDir: () => void,
|
||||||
}) {
|
}) {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const { customOutDir, changeOutDir, simpleMode, outFormatLocked, setOutFormatLocked } = useUserSettings();
|
const { customOutDir, changeOutDir, setCustomOutDir, simpleMode, outFormatLocked, setOutFormatLocked } = useUserSettings();
|
||||||
|
const workingDirButtonRef = useRef<HTMLButtonElement>(null);
|
||||||
|
|
||||||
const onOutFormatLockedClick = useCallback(() => setOutFormatLocked((v) => (v ? undefined : fileFormat)), [fileFormat, setOutFormatLocked]);
|
const onOutFormatLockedClick = useCallback(() => setOutFormatLocked((v) => (v ? undefined : fileFormat)), [fileFormat, setOutFormatLocked]);
|
||||||
|
|
||||||
@ -55,6 +58,22 @@ function TopMenu({
|
|||||||
return <Icon onClick={onOutFormatLockedClick} title={t('Lock/unlock output format')} size={14} style={{ marginRight: 7, marginLeft: 2, color: outFormatLocked ? primaryTextColor : undefined }} />;
|
return <Icon onClick={onOutFormatLockedClick} title={t('Lock/unlock output format')} size={14} style={{ marginRight: 7, marginLeft: 2, color: outFormatLocked ? primaryTextColor : undefined }} />;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Convenience for drag and drop: https://github.com/mifi/lossless-cut/issues/2147
|
||||||
|
useEffect(() => {
|
||||||
|
async function onDrop(ev: DragEvent) {
|
||||||
|
ev.preventDefault();
|
||||||
|
if (!ev.dataTransfer) return;
|
||||||
|
const paths = [...ev.dataTransfer.files].map((f) => f.path);
|
||||||
|
const [firstPath] = paths;
|
||||||
|
if (paths.length === 1 && firstPath && (await stat(firstPath)).isDirectory()) {
|
||||||
|
setCustomOutDir(firstPath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const element = workingDirButtonRef.current;
|
||||||
|
element?.addEventListener('drop', onDrop);
|
||||||
|
return () => element?.removeEventListener('drop', onDrop);
|
||||||
|
}, [setCustomOutDir]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className="no-user-select"
|
className="no-user-select"
|
||||||
@ -93,6 +112,7 @@ function TopMenu({
|
|||||||
)}
|
)}
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
|
ref={workingDirButtonRef}
|
||||||
onClick={withBlur(changeOutDir)}
|
onClick={withBlur(changeOutDir)}
|
||||||
title={customOutDir}
|
title={customOutDir}
|
||||||
style={{ paddingLeft: showClearWorkingDirButton ? 4 : undefined }}
|
style={{ paddingLeft: showClearWorkingDirButton ? 4 : undefined }}
|
||||||
|
@ -1,12 +1,11 @@
|
|||||||
import { ButtonHTMLAttributes, memo } from 'react';
|
import { ButtonHTMLAttributes, DetailedHTMLProps, forwardRef } from 'react';
|
||||||
|
|
||||||
import styles from './Button.module.css';
|
import styles from './Button.module.css';
|
||||||
|
|
||||||
function Button({ type = 'button', ...props }: ButtonHTMLAttributes<HTMLButtonElement>) {
|
// eslint-disable-next-line react/display-name
|
||||||
return (
|
const Button = forwardRef<HTMLButtonElement, DetailedHTMLProps<ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>>(({ type = 'button', ...props }, ref) => (
|
||||||
// eslint-disable-next-line react/jsx-props-no-spreading, react/button-has-type
|
// eslint-disable-next-line react/jsx-props-no-spreading, react/button-has-type
|
||||||
<button className={styles['button']} type={type} {...props} />
|
<button ref={ref} className={styles['button']} type={type} {...props} />
|
||||||
);
|
));
|
||||||
}
|
|
||||||
|
|
||||||
export default memo(Button);
|
export default Button;
|
||||||
|
Loading…
Reference in New Issue
Block a user