@iboshkov/wavesurfer-react
Version:
react wrapper for wavesurfer.js
407 lines (394 loc) • 11 kB
JavaScript
;
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;