Disable buttons when zooming is not possible
This commit is contained in:
parent
a4e9ebca3b
commit
9ae4335b19
|
@ -16,7 +16,12 @@ import { SeekBar } from './SeekBar';
|
|||
import { firstValueFrom, from, Observable } from 'rxjs';
|
||||
import { first, map } from 'rxjs/operators';
|
||||
import millisFromDuration from './helpers/millisFromDuration';
|
||||
import { zoomViewportIn, zoomViewportOut } from './helpers/zoom';
|
||||
import {
|
||||
canZoomViewportIn,
|
||||
canZoomViewportOut,
|
||||
zoomViewportIn,
|
||||
zoomViewportOut,
|
||||
} from './helpers/zoom';
|
||||
import toHHMMSS from './helpers/toHHMMSS';
|
||||
import framesToDuration from './helpers/framesToDuration';
|
||||
import { ClockIcon, ExternalLinkIcon } from '@heroicons/react/solid';
|
||||
|
@ -448,6 +453,8 @@ function App(): JSX.Element {
|
|||
</div>
|
||||
<ControlBar
|
||||
playState={playState}
|
||||
zoomInEnabled={canZoomViewportIn(viewport, selection, zoomFactor)}
|
||||
zoomOutEnabled={canZoomViewportOut(viewport, mediaSet.audioFrames)}
|
||||
onTogglePlay={togglePlay}
|
||||
onClip={handleClip}
|
||||
onZoomIn={handleZoomIn}
|
||||
|
|
|
@ -12,6 +12,8 @@ import {
|
|||
|
||||
interface Props {
|
||||
playState: PlayState;
|
||||
zoomInEnabled: boolean;
|
||||
zoomOutEnabled: boolean;
|
||||
onTogglePlay: () => void;
|
||||
onClip: () => void;
|
||||
onZoomIn: () => void;
|
||||
|
@ -21,11 +23,14 @@ interface Props {
|
|||
|
||||
const ControlBar: React.FC<Props> = React.memo((props: Props) => {
|
||||
const buttonStyle =
|
||||
'bg-gray-700 hover:bg-gray-600 text-white font-bold py-2 px-4 rounded';
|
||||
'bg-gray-600 hover:bg-gray-500 text-white font-bold py-2 px-4 rounded';
|
||||
|
||||
const disabledButtonStyle =
|
||||
'bg-gray-700 text-white font-bold py-2 px-4 rounded cursor-auto';
|
||||
|
||||
const downloadButtonStyle = props.downloadClipEnabled
|
||||
? 'bg-green-700 hover:bg-green-600 text-white font-bold py-2 px-4 rounded absolute right-0'
|
||||
: 'bg-gray-700 hover:cursor-not-allowed text-gray-500 font-bold py-2 px-4 rounded absolute right-0';
|
||||
? 'bg-green-600 hover:bg-green-600 text-white font-bold py-2 px-4 rounded absolute right-0'
|
||||
: 'bg-gray-600 hover:cursor-not-allowed text-gray-500 font-bold py-2 px-4 rounded absolute right-0';
|
||||
|
||||
const iconStyle = 'inline h-7 w-7 text-white-500';
|
||||
|
||||
|
@ -67,13 +72,13 @@ const ControlBar: React.FC<Props> = React.memo((props: Props) => {
|
|||
<FastForwardIcon className={iconStyle} />
|
||||
</button>
|
||||
<button
|
||||
className={buttonStyle}
|
||||
className={props.zoomInEnabled ? buttonStyle : disabledButtonStyle}
|
||||
onClick={(evt) => filterMouseEvent(evt, props.onZoomIn)}
|
||||
>
|
||||
<ZoomInIcon className={iconStyle} />
|
||||
</button>
|
||||
<button
|
||||
className={buttonStyle}
|
||||
className={props.zoomOutEnabled ? buttonStyle : disabledButtonStyle}
|
||||
onClick={(evt) => filterMouseEvent(evt, props.onZoomOut)}
|
||||
>
|
||||
<ZoomOutIcon className={iconStyle} />
|
||||
|
|
|
@ -1,4 +1,9 @@
|
|||
import { zoomViewportIn, zoomViewportOut } from './zoom';
|
||||
import {
|
||||
zoomViewportIn,
|
||||
zoomViewportOut,
|
||||
canZoomViewportIn,
|
||||
canZoomViewportOut,
|
||||
} from './zoom';
|
||||
|
||||
// zf is the zoom factor.
|
||||
const zf = 2;
|
||||
|
@ -220,3 +225,49 @@ describe('zoomViewportOut', () => {
|
|||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('canZoomViewportIn', () => {
|
||||
it('does now allow zooming when the viewport is inactive', () => {
|
||||
const result = canZoomViewportIn(
|
||||
{ start: 0, end: 0 },
|
||||
{ start: 0, end: 0 },
|
||||
zf
|
||||
);
|
||||
expect(result).toBeFalsy();
|
||||
});
|
||||
|
||||
it('does not allow zooming past the selection', () => {
|
||||
const result = canZoomViewportIn(
|
||||
{ start: 1000, end: 2000 },
|
||||
{ start: 1100, end: 1900 },
|
||||
zf
|
||||
);
|
||||
expect(result).toBeFalsy();
|
||||
});
|
||||
|
||||
it('allows zooming', () => {
|
||||
const result = canZoomViewportIn(
|
||||
{ start: 1000, end: 2000 },
|
||||
{ start: 0, end: 100 },
|
||||
zf
|
||||
);
|
||||
expect(result).toBeTruthy();
|
||||
});
|
||||
});
|
||||
|
||||
describe('canZoomViewportOut', () => {
|
||||
it('does now allow zooming when the viewport is inactive', () => {
|
||||
const result = canZoomViewportOut({ start: 0, end: 0 }, 1000);
|
||||
expect(result).toBeFalsy();
|
||||
});
|
||||
|
||||
it('does now allow zooming when already at maximum zoom', () => {
|
||||
const result = canZoomViewportOut({ start: 0, end: 1000 }, 1000);
|
||||
expect(result).toBeFalsy();
|
||||
});
|
||||
|
||||
it('allows zooming', () => {
|
||||
const result = canZoomViewportOut({ start: 1000, end: 2000 }, 5000);
|
||||
expect(result).toBeTruthy();
|
||||
});
|
||||
});
|
||||
|
|
|
@ -7,7 +7,7 @@ export function zoomViewportIn(
|
|||
position: number,
|
||||
factor: number
|
||||
): Frames {
|
||||
if (viewport.start == viewport.end) {
|
||||
if (!canZoomViewportIn(viewport, selection, factor)) {
|
||||
return viewport;
|
||||
}
|
||||
|
||||
|
@ -27,7 +27,7 @@ export function zoomViewportOut(
|
|||
position: number,
|
||||
factor: number
|
||||
): Frames {
|
||||
if (viewport.start == viewport.end) {
|
||||
if (!canZoomViewportOut(viewport, numFrames)) {
|
||||
return viewport;
|
||||
}
|
||||
|
||||
|
@ -74,3 +74,31 @@ function zoom(
|
|||
|
||||
return { start: newStart, end: newEnd };
|
||||
}
|
||||
|
||||
export function canZoomViewportIn(
|
||||
viewport: Frames,
|
||||
selection: Frames,
|
||||
factor: number
|
||||
): boolean {
|
||||
if (viewport.start == viewport.end) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (selection.start != selection.end) {
|
||||
const newWidth = Math.round((viewport.end - viewport.start) / factor);
|
||||
return newWidth > selection.end - selection.start;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
export function canZoomViewportOut(
|
||||
viewport: Frames,
|
||||
numFrames: number
|
||||
): boolean {
|
||||
if (viewport.start == viewport.end) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return viewport.start > 0 || viewport.end < numFrames;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue