wavesurfer-react
Version:
react wrapper for wavesurfer.js
65 lines (62 loc) • 2.43 kB
JavaScript
import { useMemo, useRef, useState, useEffect } from 'react';
import useRegionEvent from '../hooks/useRegionEvent.js';
import useWavesurferContext from '../hooks/useWavesurferContext.js';
import { UpdatableRegionProps } from '../constants/updatableRegionProps.js';
import useRegionPluginEvent from '../hooks/useRegionPluginEvent.js';
import { isRegionsPlugin } from '../utils/isRegionsPlugin.js';
const Region = ({ onOver, onLeave, onClick, onDoubleClick, onIn, onOut, onRemove, onUpdate, onUpdateEnd, ...props })=>{
const [waveSurfer, , plugins] = useWavesurferContext();
const regPlugin = plugins.find((plugin)=>isRegionsPlugin(plugin));
const regionPlugin = useMemo(()=>regPlugin, [
plugins
]);
const isRenderedCache = useRef(false);
const [regionRef, setRegionRef] = useState(null);
useEffect(()=>{
return ()=>{
regionRef?.remove();
};
}, [
regionRef
]);
useEffect(()=>{
// If there is a regionRef, then process update on any props update
regionRef?.setOptions(UpdatableRegionProps.reduce((result, prop)=>{
if (regionRef[prop] !== props[prop]) {
return {
...result,
[prop]: props[prop]
};
}
return result;
}, {
id: props.id
}));
}, UpdatableRegionProps.map((prop)=>props[prop]));
useEffect(()=>{
if (!isRenderedCache.current && waveSurfer) {
isRenderedCache.current = true;
let region = regionPlugin?.getRegions().find((r)=>r.id === props.id);
if (!region) {
region = regionPlugin?.addRegion(props);
}
if (!region) return;
setRegionRef(region);
}
// eslint-disable-next-line
}, [
waveSurfer,
regionPlugin
]);
useRegionEvent(regionRef, "click", onClick);
useRegionEvent(regionRef, "over", onOver);
useRegionEvent(regionRef, "leave", onLeave);
useRegionEvent(regionRef, "dblclick", onDoubleClick);
useRegionPluginEvent(regionPlugin, "region-in", onIn);
useRegionPluginEvent(regionPlugin, "region-out", onOut);
useRegionEvent(regionRef, "remove", onRemove);
useRegionEvent(regionRef, "update", onUpdate);
useRegionEvent(regionRef, "update-end", onUpdateEnd);
return null;
};
export { Region, Region as default };