clipper/frontend/src/ControlBar.tsx

92 lines
2.5 KiB
TypeScript

import React from 'react';
import { PlayState } from './AppState';
import {
CloudDownloadIcon,
PauseIcon,
PlayIcon,
ZoomInIcon,
ZoomOutIcon,
} from '@heroicons/react/solid';
interface Props {
playState: PlayState;
zoomInEnabled: boolean;
zoomOutEnabled: boolean;
onTogglePlay: () => void;
onClip: () => void;
onZoomIn: () => void;
onZoomOut: () => void;
downloadClipEnabled: boolean;
}
const ControlBar: React.FC<Props> = React.memo((props: Props) => {
const buttonStyle =
'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-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';
const playPauseComponent =
props.playState == PlayState.Playing ? (
<PauseIcon className={iconStyle} />
) : (
<PlayIcon className={iconStyle} />
);
const handleClip = () => {
if (props.downloadClipEnabled) {
props.onClip();
}
};
// Detect if the space bar has been used to trigger this event, and ignore
// it if so. This conflicts with the player interface.
const filterMouseEvent = (evt: React.MouseEvent, cb: () => void) => {
if (evt.detail == 0) {
return;
}
cb();
};
return (
<>
<div className="relative grow-0 w-full py-2 space-x-2">
<button
className={buttonStyle}
onClick={(evt) => filterMouseEvent(evt, props.onTogglePlay)}
>
{playPauseComponent}
</button>
<button
className={props.zoomInEnabled ? buttonStyle : disabledButtonStyle}
onClick={(evt) => filterMouseEvent(evt, props.onZoomIn)}
>
<ZoomInIcon className={iconStyle} />
</button>
<button
className={props.zoomOutEnabled ? buttonStyle : disabledButtonStyle}
onClick={(evt) => filterMouseEvent(evt, props.onZoomOut)}
>
<ZoomOutIcon className={iconStyle} />
</button>
<button
className={downloadButtonStyle}
onClick={(evt) => filterMouseEvent(evt, handleClip)}
>
<CloudDownloadIcon className={`${iconStyle} mr-2`} />
Download clip as MP3
</button>
</div>
</>
);
});
ControlBar.displayName = 'ControlBar';
export { ControlBar };