react-sounds
Version:
A library of ready-to-play sound effects for React applications.
3 lines (2 loc) • 10.8 kB
JavaScript
import{Howl as n,Howler as o}from"howler";import t,{useState as e,useRef as r,useContext as i,useCallback as c,useEffect as a,createContext as u}from"react";var s={version:"1.0.0",sounds:{"ambient/campfire":{src:"ambient/campfire.eb676cb.mp3",duration:22.047313},"ambient/heartbeat":{src:"ambient/heartbeat.3680f81.mp3",duration:22.047313},"ambient/rain":{src:"ambient/rain.96a6bc5.mp3",duration:22.047313},"ambient/water_stream":{src:"ambient/water_stream.9383548.mp3",duration:22.047313},"ambient/wind":{src:"ambient/wind.13b95c3.mp3",duration:22.047313},"arcade/coin":{src:"arcade/coin.5ec00e3.mp3",duration:.862},"arcade/coin_bling":{src:"arcade/coin_bling.e7e6644.mp3",duration:.862},"arcade/jump":{src:"arcade/jump.6baf978.mp3",duration:.862},"arcade/level_down":{src:"arcade/level_down.7f42195.mp3",duration:1.123265},"arcade/level_up":{src:"arcade/level_up.0aba301.mp3",duration:1.48898},"arcade/power_down":{src:"arcade/power_down.222ab81.mp3",duration:1.071},"arcade/power_up":{src:"arcade/power_up.bcafcc5.mp3",duration:1.071},"arcade/upgrade":{src:"arcade/upgrade.1da1db4.mp3",duration:.862},"game/coin":{src:"game/coin.21575b3.mp3",duration:.914286},"game/hit":{src:"game/hit.7f64763.mp3",duration:.313469},"game/miss":{src:"game/miss.b1d5a19.mp3",duration:.287347},"game/portal_closing":{src:"game/portal_closing.f434407.mp3",duration:2.08975},"game/portal_opening":{src:"game/portal_opening.54935de.mp3",duration:3.474286},"game/void":{src:"game/void.ab99118.mp3",duration:.862},"misc/silence":{src:"misc/silence.01e0b9b.mp3",duration:1.152},"notification/completed":{src:"notification/completed.31e527e.mp3",duration:.862},"notification/error":{src:"notification/error.b92d3c6.mp3",duration:.548563},"notification/info":{src:"notification/info.fc3baa4.mp3",duration:.862},"notification/message":{src:"notification/message.1eefe18.mp3",duration:.862},"notification/notification":{src:"notification/notification.595d086.mp3",duration:.862},"notification/popup":{src:"notification/popup.cf74b54.mp3",duration:.313469},"notification/reminder":{src:"notification/reminder.6d68587.mp3",duration:.862},"notification/success":{src:"notification/success.f38c2ed.mp3",duration:1.227755},"notification/warning":{src:"notification/warning.207aed9.mp3",duration:.862},"system/boot_down":{src:"system/boot_down.7baf040.mp3",duration:1.593469},"system/boot_up":{src:"system/boot_up.7369806.mp3",duration:3.134694},"system/device_connect":{src:"system/device_connect.e609d62.mp3",duration:.862},"system/device_disconnect":{src:"system/device_disconnect.bd814fa.mp3",duration:.862},"system/lock":{src:"system/lock.4063aab.mp3",duration:.862},"system/screenshot":{src:"system/screenshot.f3483cb.mp3",duration:.235102},"system/trash":{src:"system/trash.ed51a4e.mp3",duration:.862},"ui/blocked":{src:"ui/blocked.be40409.mp3",duration:.940408},"ui/button_hard":{src:"ui/button_hard.011f516.mp3",duration:.835918},"ui/button_hard_double":{src:"ui/button_hard_double.2c7e778.mp3",duration:.862},"ui/button_medium":{src:"ui/button_medium.f1076ea.mp3",duration:.862},"ui/button_soft":{src:"ui/button_soft.896771c.mp3",duration:.862},"ui/button_soft_double":{src:"ui/button_soft_double.ef0aec4.mp3",duration:.862},"ui/button_squishy":{src:"ui/button_squishy.69c5c9a.mp3",duration:.391837},"ui/buzz":{src:"ui/buzz.6d6857f.mp3",duration:.548563},"ui/buzz_deep":{src:"ui/buzz_deep.c1f597f.mp3",duration:.809796},"ui/buzz_long":{src:"ui/buzz_long.d506d81.mp3",duration:1.071},"ui/copy":{src:"ui/copy.4aadb27.mp3",duration:.130612},"ui/input_blur":{src:"ui/input_blur.607531b.mp3",duration:.862},"ui/input_focus":{src:"ui/input_focus.80b402e.mp3",duration:.287347},"ui/item_deselect":{src:"ui/item_deselect.9955ec7.mp3",duration:.862},"ui/item_select":{src:"ui/item_select.5d88832.mp3",duration:.862},"ui/keystroke_hard":{src:"ui/keystroke_hard.6d8eb42.mp3",duration:.548563},"ui/keystroke_medium":{src:"ui/keystroke_medium.2b4ae6c.mp3",duration:.548563},"ui/keystroke_soft":{src:"ui/keystroke_soft.fcd4503.mp3",duration:.548563},"ui/panel_collapse":{src:"ui/panel_collapse.1b8441f.mp3",duration:.862},"ui/panel_expand":{src:"ui/panel_expand.ef3ca39.mp3",duration:.862},"ui/pop_close":{src:"ui/pop_close.1f2dc35.mp3",duration:.809796},"ui/pop_open":{src:"ui/pop_open.360c640.mp3",duration:.835918},"ui/popup_close":{src:"ui/popup_close.1bd2a1b.mp3",duration:1.071},"ui/popup_open":{src:"ui/popup_open.97597a8.mp3",duration:1.071},"ui/radio_select":{src:"ui/radio_select.4fbe4e3.mp3",duration:.862},"ui/send":{src:"ui/send.396090f.mp3",duration:.182857},"ui/submit":{src:"ui/submit.1e228b1.mp3",duration:.548563},"ui/success_bling":{src:"ui/success_bling.3f44a2f.mp3",duration:.809796},"ui/success_blip":{src:"ui/success_blip.911b304.mp3",duration:.626939},"ui/success_chime":{src:"ui/success_chime.436ed4a.mp3",duration:1.619592},"ui/tab_close":{src:"ui/tab_close.3c1a646.mp3",duration:.548563},"ui/tab_open":{src:"ui/tab_open.3745bcd.mp3",duration:.548563},"ui/toggle_off":{src:"ui/toggle_off.7103845.mp3",duration:.261224},"ui/toggle_on":{src:"ui/toggle_on.2f87bf7.mp3",duration:.287347},"ui/window_close":{src:"ui/window_close.0e958da.mp3",duration:.548563},"ui/window_open":{src:"ui/window_open.7478756.mp3",duration:.548563}}};function d(n){return n in s.sounds}let p="https://reacticons.sfo3.cdn.digitaloceanspaces.com/v1",l=!0;const m=[];let f=!1;function b(n){p=n}function _(){return p}const w={},h={};function y(o){return async()=>(w[o]||(w[o]=k(o)),async function(o){if(h[o])return h[o];w[o]||(w[o]=k(o));const t=await w[o],e=URL.createObjectURL(t),r=new n({src:[e],format:["mp3"],html5:!0,onload:()=>{r._objectUrl=e}});return h[o]={instance:r,subscriptions:0},h[o]}(o))}async function g(n){const o=await y(n)();return o.subscriptions+=1,o.instance}function v(n){const o=h[n];return o&&o.subscriptions>0&&(o.subscriptions-=1),function(n){const o=h[n];if(!o||o.instance.playing()||o.subscriptions>0)return;const{instance:t}=o;t._objectUrl&&URL.revokeObjectURL(t._objectUrl);t.unload(),delete h[n]}(n),null}async function k(n){try{const o=await async function(n){var o;if(!d(n))return n;const t=`/sounds/${n}.mp3`;try{const n=new AbortController,e=setTimeout((()=>n.abort()),300),r=await fetch(t,{method:"HEAD",signal:n.signal});return clearTimeout(e),r.ok&&(null===(o=r.headers.get("content-type"))||void 0===o?void 0:o.toLowerCase().startsWith("audio"))?t:null}catch(n){}return null}(n);if(o){const n=await fetch(o);if(n.ok)return await n.blob()}}catch(o){console.warn(`Error loading local sound "${n}", falling back to CDN:`,o)}if(!d(n))throw new Error(`Failed to load custom sound "${n}"`);const o=s.sounds[n],t=`${p}/${o.src}`,e=await fetch(t);if(!e.ok)throw new Error(`Failed to fetch sound "${n}" from CDN`);return await e.blob()}function E(n){return Promise.all(n.map((async n=>{w[n]||(w[n]=k(n)),await w[n]})))}async function z(n,o){if(!L())return;const t=await g(n);let e=!1;o&&(void 0!==o.volume&&t.volume(o.volume),void 0!==o.rate&&t.rate(o.rate),void 0!==o.loop&&t.loop(o.loop)),t.on("end",(()=>{e||(null==o?void 0:o.loop)||(v(n),e=!0)})),t.play()}function L(){return"undefined"!=typeof window&&l}function x(n){l=n,"undefined"!=typeof localStorage&&localStorage.setItem("react-sounds-enabled",n?"true":"false"),m.forEach((o=>o(n)))}async function S(){if("undefined"!=typeof window&&o.ctx&&"suspended"===o.ctx.state)try{await o.ctx.resume()}catch(n){console.warn("Failed to unlock audio context:",n)}}let j;function P(n,o={}){const[t,u]=e(!1),[s,d]=e(!1),p=r(null),l=r([]);let m=L();try{const n=j?i(j):null;n&&(m=n.enabled)}catch(n){}const f=c((async()=>{if(p.current)return p.current;try{const o=await g(n);return o.on("end",(o=>{const t=l.current.findIndex((n=>n.id===o));if(t>=0){const n=l.current[t];n.resolver&&n.resolver(),n.loop||l.current.splice(t,1)}0===l.current.length&&(p.current=v(n),d(!1))})),p.current=o,u(!0),o}catch(n){throw console.error("Error loading sound:",n),n}}),[n,d]),b=c((async(n=o)=>{if(m)try{await S();const o=await f(),t=void 0!==n.loop&&n.loop;void 0!==n.volume&&o.volume(n.volume),void 0!==n.rate&&o.rate(n.rate),o.loop(t);const e=o.play();return d(!0),t?void l.current.push({id:e,loop:t}):new Promise((n=>{l.current.push({id:e,loop:t,resolver:()=>n()})}))}catch(n){throw console.error("Error playing sound:",n),n}}),[o,m,f,t]),_=c((()=>{p.current&&(l.current.forEach((n=>{n.resolver&&n.resolver()})),p.current.stop(),p.current=v(n),l.current=[],d(!1))}),[]),w=c((()=>{p.current&&(p.current.pause(),d(!1))}),[]),h=c((()=>{p.current&&m&&0!==l.current.length&&S().then((()=>{l.current.forEach((({id:n})=>{var o;return null===(o=p.current)||void 0===o?void 0:o.play(n)})),d(!0)}))}),[m]);return a((()=>{!m&&s&&w()}),[m,s,w]),a((()=>(E([n]).then((()=>u(!0))),()=>{u(!1),d(!1),l.current.forEach((n=>{n.resolver&&n.resolver()})),l.current=[],p.current&&(p.current.stop(),p.current=v(n))})),[n]),{play:b,stop:_,pause:w,resume:h,isPlaying:s,isLoaded:t}}function U(n,o,t){const{play:e}=P(n),i=r(!0);a((()=>{const n=i.current&&!1===(null==t?void 0:t.initial);i.current=!1,n||e(t).catch((n=>console.error("Failed to play sound:",n)))}),[o])}function C(){const n=i(j);if(!n)throw new Error("useSoundEnabled must be used within a SoundProvider");return[n.enabled,n.setEnabled]}function $({name:n,trigger:o="none",options:e,children:r,onLoad:i,onPlay:c,onStop:u,onError:s}){const{play:d,stop:p,isLoaded:l,isPlaying:m}=P(n,e);return a((()=>{l&&i&&i()}),[l,i]),a((()=>{m&&c&&c()}),[m,c]),a((()=>("mount"===o&&d(e).catch((n=>{s&&s(n)})),()=>{"unmount"===o&&z(n,e),p(),u&&u()})),[o,n,d,p,u,e,s]),t.createElement(t.Fragment,null,r)}function F({sound:n,soundOptions:o,children:e,onClick:r,onSoundError:i,...c}){const{play:a}=P(n,o);return t.createElement("button",{onClick:n=>{a().catch((n=>{i&&i(n)})),r&&r(n)},...c},e)}!function(){if("undefined"==typeof localStorage)return;const n=localStorage.getItem("react-sounds-enabled");null!==n&&(l="false"!==n)}(),"undefined"!=typeof window&&function(){if("undefined"==typeof window||f)return()=>{};f=!0;const n=["click","touchstart","keydown"],o=()=>{S(),n.forEach((n=>document.removeEventListener(n,o)))};n.forEach((n=>document.addEventListener(n,o)))}();const O=u(null);function R({preload:n=[],initialEnabled:o,children:r}){const[i,u]=e((()=>void 0!==o?o:L())),s=c((n=>{x(n)}),[]);return a((()=>{return n=n=>{u(n)},m.push(n),()=>{const o=m.indexOf(n);-1!==o&&m.splice(o,1)};var n}),[]),a((()=>{S()}),[]),a((()=>{if(n.length>0){E(n).catch((n=>{console.error("Error preloading sounds:",n)}))}}),[n]),t.createElement(O.Provider,{value:{enabled:i,setEnabled:s}},r)}j=O;export{$ as Sound,F as SoundButton,R as SoundProvider,k as fetchSoundBlob,_ as getCDNUrl,L as isSoundEnabled,y as makeRemoteSound,z as playSound,E as preloadSounds,b as setCDNUrl,x as setSoundEnabled,P as useSound,C as useSoundEnabled,U as useSoundOnChange};
//# sourceMappingURL=index.esm.js.map