UNPKG

4.21 kBJavaScriptView Raw
1import React__default, { useEffect } from 'react';
2
3function _extends() {
4 _extends = Object.assign || function (target) {
5 for (var i = 1; i < arguments.length; i++) {
6 var source = arguments[i];
7
8 for (var key in source) {
9 if (Object.prototype.hasOwnProperty.call(source, key)) {
10 target[key] = source[key];
11 }
12 }
13 }
14
15 return target;
16 };
17
18 return _extends.apply(this, arguments);
19}
20
21function _objectWithoutPropertiesLoose(source, excluded) {
22 if (source == null) return {};
23 var target = {};
24 var sourceKeys = Object.keys(source);
25 var key, i;
26
27 for (i = 0; i < sourceKeys.length; i++) {
28 key = sourceKeys[i];
29 if (excluded.indexOf(key) >= 0) continue;
30 target[key] = source[key];
31 }
32
33 return target;
34}
35
36function useOnMount(callback) {
37 useEffect(callback, []);
38}
39
40function useSound(url, _ref) {
41 if (_ref === void 0) {
42 _ref = {};
43 }
44
45 var _ref2 = _ref,
46 _ref2$volume = _ref2.volume,
47 volume = _ref2$volume === void 0 ? 1 : _ref2$volume,
48 _ref2$playbackRate = _ref2.playbackRate,
49 playbackRate = _ref2$playbackRate === void 0 ? 1 : _ref2$playbackRate,
50 _ref2$soundEnabled = _ref2.soundEnabled,
51 soundEnabled = _ref2$soundEnabled === void 0 ? true : _ref2$soundEnabled,
52 _ref2$interrupt = _ref2.interrupt,
53 interrupt = _ref2$interrupt === void 0 ? false : _ref2$interrupt,
54 delegated = _objectWithoutPropertiesLoose(_ref2, ["volume", "playbackRate", "soundEnabled", "interrupt"]);
55
56 var HowlConstructor = React__default.useRef(null);
57
58 var _React$useState = React__default.useState(false),
59 isPlaying = _React$useState[0],
60 setIsPlaying = _React$useState[1];
61
62 var _React$useState2 = React__default.useState(null),
63 sound = _React$useState2[0],
64 setSound = _React$useState2[1]; // We want to lazy-load Howler, since sounds can't play on load anyway.
65
66
67 useOnMount(function () {
68 import('howler').then(function (mod) {
69 HowlConstructor.current = mod.Howl;
70 var sound = new HowlConstructor.current(_extends({
71 src: [url],
72 volume: volume
73 }, delegated));
74 setSound(sound);
75 });
76 }); // When the URL changes, we have to do a whole thing where we recreate
77 // the Howl instance. This is because Howler doesn't expose a way to
78 // tweak the sound
79
80 React__default.useEffect(function () {
81 if (HowlConstructor.current && sound) {
82 setSound(new HowlConstructor.current(_extends({
83 src: [url],
84 volume: volume
85 }, delegated)));
86 } // The linter wants to run this effect whenever ANYTHING changes,
87 // but very specifically I only want to recreate the Howl instance
88 // when the `url` changes. Other changes should have no effect.
89 // eslint-disable-next-line react-hooks/exhaustive-deps
90
91 }, [url]); // Whenever volume/playbackRate are changed, change those properties
92 // on the sound instance.
93
94 React__default.useEffect(function () {
95 if (sound) {
96 sound.volume(volume);
97 sound.rate(playbackRate);
98 } // A weird bug means that including the `sound` here can trigger an
99 // error on unmount, where the state loses track of the sprites??
100 // No idea, but anyway I don't need to re-run this if only the `sound`
101 // changes.
102 // eslint-disable-next-line react-hooks/exhaustive-deps
103
104 }, [volume, playbackRate]);
105 var play = React__default.useCallback(function (options) {
106 if (options === void 0) {
107 options = {};
108 }
109
110 if (!sound || !soundEnabled && !options.forceSoundEnabled) {
111 return;
112 }
113
114 if (interrupt) {
115 sound.stop();
116 }
117
118 if (options.playbackRate) {
119 sound.rate(options.playbackRate);
120 }
121
122 sound.play(options.id);
123 sound.once('end', function () {
124 return setIsPlaying(false);
125 });
126 setIsPlaying(true);
127 }, [sound, soundEnabled, interrupt]);
128 var stop = React__default.useCallback(function () {
129 if (!sound) {
130 return;
131 }
132
133 sound.stop();
134 setIsPlaying(false);
135 }, [sound]);
136 var returnedValue = [play, {
137 sound: sound,
138 stop: stop,
139 isPlaying: isPlaying
140 }];
141 return returnedValue;
142}
143
144export default useSound;
145//# sourceMappingURL=use-sound.esm.js.map