UNPKG

@iboshkov/wavesurfer-react

Version:
407 lines (394 loc) 11 kB
'use strict'; Object.defineProperty(exports, '__esModule', { value: true }); var React2 = require('react'); var WaveSurfer = require('wavesurfer.js'); function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; } var React2__default = /*#__PURE__*/_interopDefaultLegacy(React2); var WaveSurfer__default = /*#__PURE__*/_interopDefaultLegacy(WaveSurfer); // react-shim.js var useRegionEvent = (ref, eventName, callback) => { const callbackRef = React2.useRef(null); React2.useEffect(() => { if (!ref) { return; } if (callback) { callbackRef.current = (...args) => callback(ref, ...args); ref.on(eventName, callbackRef.current); } return () => { callbackRef.current && ref.un(eventName, callbackRef.current); callbackRef.current = null; }; }, [ref, eventName, callback]); }; var useRegionEvent_default = useRegionEvent; var WaveSurferContext = React2.createContext(null); var WaveSurferContext_default = WaveSurferContext; function useWavesurferContext() { return React2.useContext(WaveSurferContext_default); } // src/components/Region.tsx var Region = ({ onOver, onLeave, onClick, onDoubleClick, onIn, onOut, onRemove, onUpdate, onUpdateEnd, ...props }) => { const waveSurfer = useWavesurferContext(); const isRenderedCache = React2.useRef(false); const [regionRef, setRegionRef] = React2.useState(null); React2.useEffect(() => { return () => { if (regionRef) { regionRef.remove(); } }; }, [regionRef]); React2.useEffect( () => { if (regionRef) { const update = UpdatableRegionProps.reduce( (result, prop) => { if (regionRef[prop] !== props[prop]) { return { ...result, [prop]: props[prop] }; } return result; }, { id: props.id } ); regionRef.update(update); } }, UpdatableRegionProps.map((prop) => props[prop]) ); React2.useEffect(() => { if (!isRenderedCache.current && waveSurfer) { isRenderedCache.current = true; let region; region = waveSurfer.regions.list[props.id]; if (!region) { region = waveSurfer.addRegion(props); } setRegionRef(region); } }, [waveSurfer]); useRegionEvent_default(regionRef, "click", onClick); useRegionEvent_default(regionRef, "mouseenter", onOver); useRegionEvent_default(regionRef, "mouseleave", onLeave); useRegionEvent_default(regionRef, "dblclick", onDoubleClick); useRegionEvent_default(regionRef, "in", onIn); useRegionEvent_default(regionRef, "out", onOut); useRegionEvent_default(regionRef, "remove", onRemove); useRegionEvent_default(regionRef, "update", onUpdate); useRegionEvent_default(regionRef, "update-end", onUpdateEnd); return null; }; var Region_default = Region; var UpdatableRegionProps = [ "start", "end", "loop", "color", "handleStyle", "resize", "drag", "drag", "end", "handleStyle", "id", "loop", "preventContextMenu", "resize", "start" ]; function Marker({ onClick, onDrop, onDrag, ...data }) { const ws = useWavesurferContext(); const ws$ = React2.useRef(ws); React2.useEffect(() => { ws$.current = ws; }, [ws]); const isRendered = React2.useRef(false); const markerEl = React2.useRef(null); React2.useEffect(() => { if (!ws) return; if (!onClick) return; function handler(marker, event) { if (!markerEl.current) return; if (marker.el !== markerEl.current.el) return; onClick == null ? void 0 : onClick(marker, event); } ws.on("marker-click", handler); return () => { ws.un("marker-click", handler); }; }, [ws, onClick]); React2.useEffect(() => { if (!ws) return; if (!onDrag) return; function handler(marker, event) { if (!markerEl.current) return; if (marker.el !== markerEl.current.el) return; onDrag == null ? void 0 : onDrag(marker, event); } ws.on("marker-drag", handler); return () => { ws.un("marker-drag", handler); }; }, [ws, onDrag]); React2.useEffect(() => { if (!ws) return; if (!onDrop) return; function handler(marker, event) { if (!markerEl.current) return; if (marker.el !== markerEl.current.el) return; onDrop == null ? void 0 : onDrop(marker, event); } ws.on("marker-drop", handler); return () => { ws.un("marker-drop", handler); }; }, [ws, onDrop]); React2.useEffect(() => { if (!ws) return; if (isRendered.current) return; isRendered.current = true; markerEl.current = ws.addMarker(data); }, [ws]); React2.useEffect(() => { var _a; if (!ws || !markerEl.current || !isRendered.current) return; if (data.time === ((_a = markerEl.current) == null ? void 0 : _a.time)) return; const marker = ws.markers.markers.find((mark) => { var _a2; return mark.el === ((_a2 = markerEl.current) == null ? void 0 : _a2.el); }); if (!marker) return; marker.time = data.time; ws.markers._updateMarkerPosition({ ...markerEl.current, time: data.time }); }, [data == null ? void 0 : data.time]); React2.useEffect(() => () => { if (!ws$.current || !markerEl.current) return; const index = ws$.current.markers.markers.findIndex((marker) => { var _a; return marker.el === ((_a = markerEl.current) == null ? void 0 : _a.el); }); ws$.current.markers.remove(index); }, []); return null; } var WaveForm = ({ id = "waveform", children }) => { return /* @__PURE__ */ React2__default["default"].createElement("div", { id }, children); }; var WaveForm_default = WaveForm; // src/utils/getWaveFormOptionsFromProps.ts var waveFormPropsList = [ "audioRate", "audioContext", "audioScriptProcessor", "autoCenter", "backend", "backgroundColor", "barGap", "barHeight", "barMinHeight", "barRadius", "barWidth", "closeAudioContext", "cursorColor", "cursorWidth", "fillParent", "forceDecode", "height", "hideScrollbar", "interact", "loopSelection", "maxCanvasWidth", "mediaControls", "mediaType", "minPxPerSec", "normalize", "partialRender", "pixelRatio", "progressColor", "removeMediaElementOnDestroy", "renderer", "responsive", "scrollParent", "skipLength", "splitChannels", "waveColor", "autoCenterRate", "autoCenterImmediately", "drawingContextAttributes", "duration", "ignoreSilenceMode", "rtl", "splitChannelsOptions", "vertical", "xhr" ]; var getWaveFormOptionsFromProps = (props) => { if (!props) return {}; return waveFormPropsList.reduce((waveFormOptions, optionName) => { if (!Object.prototype.hasOwnProperty.call(props, optionName)) { return waveFormOptions; } return { ...waveFormOptions, [optionName]: props[optionName] }; }, {}); }; var getWaveFormOptionsFromProps_default = getWaveFormOptionsFromProps; function createWavesurfer(options) { return WaveSurfer__default["default"].create(options); } // src/utils/createPlugin.ts function createPlugin(pluginObj) { const { plugin, options, creator = "create" } = pluginObj; const createMethod = plugin[creator]; if (!plugin) throw new Error(`Please pass a valid plugin in plugin list`); if (!creator) throw new Error(`Please pass the creator function name in 'creator' property.`); if (createMethod instanceof Function === false) { throw new Error(`"${creator}" is not callable on given plugin. Please pass a valid 'creator' in plugins list.`); } return createMethod(options); } // src/utils/getDifference.ts var getDifference = (arr1, arr2) => { let nextArr1 = [...arr1]; let nextArr2 = [...arr2]; const disabled = nextArr1.filter((item) => { return nextArr2.findIndex((nextItem) => nextItem.name === item.name) === -1; }); const enabled = nextArr2.filter((item) => { return nextArr1.findIndex((nextItem) => nextItem.name === item.name) === -1; }); return { disabled, enabled }; }; var getDifference_default = getDifference; // src/hooks/useWavesurfer.ts function useWavesurfer({ container, plugins = [], onMount, ...props }) { const usedPluginsListCache = React2.useRef([]); const [wavesurfer, setWavesurfer] = React2.useState(null); React2.useEffect(() => { if (!container) return; let _plugins = []; if (plugins) { _plugins = plugins.map(createPlugin); } usedPluginsListCache.current = _plugins; const ws = createWavesurfer({ container, ...props, plugins: _plugins }); onMount == null ? void 0 : onMount(ws); setWavesurfer(ws); return () => { ws.destroy(); }; }, [container]); React2.useEffect(() => { if (wavesurfer) { const nextPluginsMap = plugins.map(createPlugin); const { disabled, enabled } = getDifference_default( usedPluginsListCache.current, nextPluginsMap ); usedPluginsListCache.current = nextPluginsMap; disabled.forEach((plugin) => { if (!plugin.name) return; wavesurfer == null ? void 0 : wavesurfer.destroyPlugin(plugin.name); }); enabled.forEach((plugin) => { if (!plugin.name) return; wavesurfer == null ? void 0 : wavesurfer.addPlugin(plugin).initPlugin(plugin.name); }); } }, [plugins]); return wavesurfer; } // src/containers/WaveSurfer.tsx var WaveSurfer3 = ({ children, plugins = [], onMount, ...props }) => { const UNSTABLE_waveFormProps = React2.useMemo(() => { let waveformProps = {}; React2.Children.forEach(children, (element) => { if (typeof element !== "object" || element === null || ["string", "number"].includes(typeof element)) { return; } if (!("props" in element || "type" in element)) return; const props2 = element.props; const elType = element.type; if (elType === WaveForm_default) { const { id, ...rest } = props2; waveformProps = getWaveFormOptionsFromProps_default(rest); waveformProps = { ...waveformProps, container: "#" + id }; } }); return waveformProps; }, [children]); const wavesurfer = useWavesurfer({ plugins, onMount, ...props, ...UNSTABLE_waveFormProps }); return /* @__PURE__ */ React2__default["default"].createElement(WaveSurferContext_default.Provider, { value: wavesurfer }, children); }; WaveSurfer3.defaultProps = { children: null, plugins: [] }; var WaveSurfer_default = WaveSurfer3; exports.Marker = Marker; exports.Region = Region_default; exports.WaveForm = WaveForm_default; exports.WaveSurfer = WaveSurfer_default; exports.useWavesurfer = useWavesurfer; exports.useWavesurferContext = useWavesurferContext;