diff --git a/src/components/shared/AudioViewer/index.tsx b/src/components/shared/AudioViewer/index.tsx index 5e4cc5fd..9cffdc4f 100644 --- a/src/components/shared/AudioViewer/index.tsx +++ b/src/components/shared/AudioViewer/index.tsx @@ -16,14 +16,15 @@ import { notifyProblem } from '../../../notify'; import WaveSurfer from 'wavesurfer.js'; import RegionsPlugin from 'wavesurfer.js/dist/plugin/wavesurfer.regions.min.js'; import CursorPlugin from 'wavesurfer.js/dist/plugin/wavesurfer.cursor.min.js'; +import AutoplayIcon from '../../../icons/Autoplay'; // Maximum zoom level for waveform const MAX_ZOOM = 2500; const Container = tw.div`flex flex-col w-full h-full items-stretch justify-center`; -const Toolbar = tw.div`flex flex-row items-center justify-center p-px`; -const ToolbarButton = tw(Button)`rounded-none py-0`; +const Toolbar = tw.div`flex flex-row items-stretch justify-center border-t border-gray-300 bg-gray-100 divide-x divide-gray-300`; +const ToolbarButton = tw(Button)`rounded-none py-px`; const EmptyNote = styled.p` color: ${theme`colors.gray.500`}; @@ -145,6 +146,8 @@ interface Props { showControls?: boolean; repeat?: boolean; onChangeRepeat?: (enabled: boolean) => void; + autoplay?: boolean; + onChangeAutoplay?: (enabled: boolean) => void; onEditWindow?: (window: [number, number]) => void; onDeleteWindow?: () => void; onRegionEnter?: (windowIndex: number) => void; @@ -161,6 +164,8 @@ const AudioViewer = ({ showControls, repeat, onChangeRepeat, + autoplay = false, + onChangeAutoplay, onEditWindow, onDeleteWindow, onRegionEnter, @@ -182,6 +187,9 @@ const AudioViewer = ({ onChangeRepeat = onChangeRepeat ?? _setRepeat; const toggleRepeat = () => onChangeRepeat?.(!repeat); + const canToggleAutoplay = onChangeAutoplay !== undefined; + const toggleAutoplay = () => onChangeAutoplay?.(!autoplay); + const redrawWaveform = (height: number) => { waveform.current?.setHeight(height); }; @@ -332,7 +340,11 @@ const AudioViewer = ({ useEffect(() => { // eslint-disable-next-line @typescript-eslint/no-explicit-any (waveform.current?.backend as any).media.loop = repeat; - }, [repeat]); + if (isReady && autoplay && !waveform.current?.isPlaying()) { + switchActiveWidget(); + waveform.current?.play(); + } + }, [isReady, autoplay, repeat]); useEffect(() => { if (!waveform.current?.isReady) return; @@ -553,6 +565,22 @@ const AudioViewer = ({
+ + + + + + + - - - )} {/* eslint-disable-next-line jsx-a11y/media-has-caption */} diff --git a/src/icons/Autoplay.tsx b/src/icons/Autoplay.tsx new file mode 100644 index 00000000..8f36cf7f --- /dev/null +++ b/src/icons/Autoplay.tsx @@ -0,0 +1,8 @@ +import type { IconType } from 'react-icons'; +import { MdOutlineHdrAuto } from 'react-icons/md'; +import tw from 'twin.macro'; + +const Autoplay: IconType = tw( + MdOutlineHdrAuto +)`w-4 h-4 font-semibold inline-block align-middle stroke-current`; +export default Autoplay; diff --git a/src/lenses/AudioLens.tsx b/src/lenses/AudioLens.tsx index a2d3866d..48f98e0a 100644 --- a/src/lenses/AudioLens.tsx +++ b/src/lenses/AudioLens.tsx @@ -23,6 +23,8 @@ const AudioLens: Lens = ({ rowIndex, columns, urls, values }) => { const [repeat, setRepeat] = useSetting('repeat', false); + const [autoplay, setAutoplay] = useSetting('autoplay', false); + useEffect(() => { fetchWaveform(rowIndex, columns[audioIndex].key).then((waveform) => { setWaveform(waveform); @@ -39,6 +41,8 @@ const AudioLens: Lens = ({ rowIndex, columns, urls, values }) => { showControls={true} repeat={repeat} onChangeRepeat={setRepeat} + autoplay={autoplay} + onChangeAutoplay={setAutoplay} /> ); };