@cuemath/leap 3.5.29-mb → 3.5.29-mb-2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,131 +1,127 @@
1
- import { useRef as O, useCallback as d, useEffect as v } from "react";
2
- import { useAutoPlayPermission as U } from "../../../hooks/use-auto-play-permission/use-auto-play-permission.js";
3
- import { SWIPE_SOUND_ORDER as w, CircleSoundKeyMapper as y } from "./constants.js";
4
- import { CircleSoundKey as e } from "./use-circle-sounds-enums.js";
1
+ import { useRef as v, useCallback as c, useEffect as L } from "react";
2
+ import { useAutoPlayPermission as P } from "../../../hooks/use-auto-play-permission/use-auto-play-permission.js";
3
+ import { SWIPE_SOUND_ORDER as I, CircleSoundKeyMapper as y } from "./constants.js";
4
+ import { CircleSoundKey as n } from "./use-circle-sounds-enums.js";
5
5
  let C = 0;
6
- const u = new (window.AudioContext || window.webkitAudioContext)(), _ = {
7
- [e.BACKGROUND]: null,
8
- [e.BACKGROUND_RUSHHOUR]: null,
9
- [e.TUTORIAL]: null,
10
- [e.SWIPE_01]: null,
11
- [e.SWIPE_02]: null,
12
- [e.SWIPE_03]: null,
13
- [e.SWIPE_04]: null,
14
- [e.SWIPE_DOWN]: null,
15
- [e.TOGGLE]: null,
16
- [e.POINTS_AWARDED]: null,
17
- [e.POINTS_ADDED]: null,
18
- [e.GAME_CARD_CLICK]: null,
19
- [e.CLOCK_IN]: null,
20
- [e.CLOCK_OUT]: null,
21
- [e.ACCURACY_IN]: null,
22
- [e.ACCURACY_OUT]: null,
23
- [e.STREAK_IN]: null,
24
- [e.STREAK_OUT]: null,
25
- [e.ACCURACY_INTRO]: null,
26
- [e.ACCURACY_TARGET]: null,
27
- [e.TIME_INTRO]: null,
28
- [e.TIME_TARGET]: null,
29
- [e.METER_FILL]: null,
30
- [e.YOUR_SCORE]: null,
31
- [e.HIGH_SCORE]: null,
32
- [e.KEEP_IT_UP]: null,
33
- [e.DOING_GREAT]: null,
34
- [e.ALL_DONE]: null,
35
- [e.ACTIVITY_COMPLETE]: null,
36
- [e.ALL_ACTIVITIES_COMPLETE]: null
37
- }, l = {};
38
- let R = !1;
39
- const S = async () => {
40
- if (u.state === "suspended" && !R) {
41
- R = !0;
6
+ const t = new (window.AudioContext || window.webkitAudioContext)(), m = {
7
+ [n.BACKGROUND]: null,
8
+ [n.BACKGROUND_RUSHHOUR]: null,
9
+ [n.TUTORIAL]: null,
10
+ [n.SWIPE_01]: null,
11
+ [n.SWIPE_02]: null,
12
+ [n.SWIPE_03]: null,
13
+ [n.SWIPE_04]: null,
14
+ [n.SWIPE_DOWN]: null,
15
+ [n.TOGGLE]: null,
16
+ [n.POINTS_AWARDED]: null,
17
+ [n.POINTS_ADDED]: null,
18
+ [n.GAME_CARD_CLICK]: null,
19
+ [n.CLOCK_IN]: null,
20
+ [n.CLOCK_OUT]: null,
21
+ [n.ACCURACY_IN]: null,
22
+ [n.ACCURACY_OUT]: null,
23
+ [n.STREAK_IN]: null,
24
+ [n.STREAK_OUT]: null,
25
+ [n.ACCURACY_INTRO]: null,
26
+ [n.ACCURACY_TARGET]: null,
27
+ [n.TIME_INTRO]: null,
28
+ [n.TIME_TARGET]: null,
29
+ [n.METER_FILL]: null,
30
+ [n.YOUR_SCORE]: null,
31
+ [n.HIGH_SCORE]: null,
32
+ [n.KEEP_IT_UP]: null,
33
+ [n.DOING_GREAT]: null,
34
+ [n.ALL_DONE]: null,
35
+ [n.ACTIVITY_COMPLETE]: null,
36
+ [n.ALL_ACTIVITIES_COMPLETE]: null
37
+ }, r = {};
38
+ let _ = !1;
39
+ const O = async () => {
40
+ if (t.state === "suspended" && !_) {
41
+ _ = !0;
42
42
  try {
43
- await u.resume();
43
+ await t.resume();
44
44
  } catch (a) {
45
45
  console.warn("Failed to resume AudioContext:", a);
46
46
  } finally {
47
- R = !1;
47
+ _ = !1;
48
48
  }
49
49
  }
50
50
  }, K = () => {
51
- const { canAutoPlayAudio: a } = U(), s = O(/* @__PURE__ */ new Set()), f = O({}), T = d(async (n) => {
52
- if (!_[n]) {
53
- const t = await D(y[n]);
54
- t && (_[n] = t);
51
+ const { canAutoPlayAudio: a } = P(), i = v({}), f = c(async (e) => {
52
+ if (!m[e]) {
53
+ const u = await U(y[e]);
54
+ u && (m[e] = u);
55
55
  }
56
- }, []), p = (n) => {
57
- n.gain.setValueAtTime(0, u.currentTime), n.gain.linearRampToValueAtTime(1, u.currentTime + 0.5);
58
- }, L = (n, t) => {
59
- n.gain.setValueAtTime(n.gain.value, u.currentTime), n.gain.linearRampToValueAtTime(0, u.currentTime + 0.5);
60
- const o = setTimeout(() => {
61
- var r;
62
- (r = l[t]) == null || r.source.stop(), delete l[t];
63
- }, 500);
64
- f.current[t] = o;
65
- }, i = d(
66
- async (n, t = !0, o = !1) => {
67
- await S(), await T(n);
68
- const r = _[n];
69
- if (!r || !a) {
70
- console.warn("Cannot play sound", n, { buffer: r, canPlayAudio: a });
56
+ }, []), T = (e) => {
57
+ e.gain.cancelScheduledValues(t.currentTime), e.gain.setValueAtTime(e.gain.value, t.currentTime), e.gain.linearRampToValueAtTime(1, t.currentTime + 0.5);
58
+ }, R = (e) => {
59
+ e.gain.cancelScheduledValues(t.currentTime), e.gain.setValueAtTime(e.gain.value, t.currentTime), e.gain.linearRampToValueAtTime(0, t.currentTime + 0.5);
60
+ }, d = c(
61
+ async (e, u = !0, o = !1) => {
62
+ await O(), await f(e);
63
+ const l = m[e];
64
+ if (!l || !a) {
65
+ console.warn("Cannot play sound", e, { buffer: l, canPlayAudio: a });
71
66
  return;
72
67
  }
73
- if (l[n] && o)
68
+ if (r[e] && o) {
69
+ T(r[e].gainNode);
74
70
  return;
75
- const c = u.createBufferSource(), E = u.createGain();
76
- c.buffer = r, c.loop = o, c.connect(E).connect(u.destination), t ? E.gain.setValueAtTime(1, u.currentTime) : p(E), c.start(), l[n] = { source: c, gainNode: E, loop: o }, o || (c.onended = () => {
77
- var I;
78
- ((I = l[n]) == null ? void 0 : I.source) === c && delete l[n];
71
+ }
72
+ const s = t.createBufferSource(), E = t.createGain();
73
+ s.buffer = l, s.loop = o, s.connect(E).connect(t.destination), u ? E.gain.setValueAtTime(1, t.currentTime) : T(E), s.start(), r[e] = { source: s, gainNode: E, loop: o }, o || (s.onended = () => {
74
+ var S;
75
+ ((S = r[e]) == null ? void 0 : S.source) === s && delete r[e];
79
76
  });
80
77
  },
81
- [a, T]
82
- ), A = d(async (n, t = !0) => {
83
- const o = l[n];
84
- o && (t ? (o.source.stop(), delete l[n]) : L(o.gainNode, n));
85
- }, []), P = d(() => {
86
- const n = w[C] || e.SWIPE_01;
87
- C = (C + 1) % w.length, i(n);
88
- }, [i]), h = d(() => {
89
- i(e.TOGGLE);
90
- }, [i]), m = d(async () => {
91
- document.visibilityState === "visible" ? (await S(), Array.from(s.current).forEach((t) => {
92
- var o;
93
- i(t, !1, ((o = l[t]) == null ? void 0 : o.loop) ?? !1);
94
- }), s.current.clear()) : Object.keys(l).forEach((n) => {
95
- A(n, !0), s.current.add(n);
78
+ [a, f]
79
+ ), w = c(async (e, u = !0) => {
80
+ const o = r[e];
81
+ o && (u ? (o.source.stop(), delete r[e]) : R(o.gainNode));
82
+ }, []), p = c(() => {
83
+ const e = I[C] || n.SWIPE_01;
84
+ C = (C + 1) % I.length, d(e);
85
+ }, [d]), h = c(() => {
86
+ d(n.TOGGLE);
87
+ }, [d]), A = c(async () => {
88
+ document.visibilityState === "visible" ? (await O(), Object.values(r).forEach(({ gainNode: e }) => {
89
+ T(e);
90
+ })) : Object.values(r).forEach(({ gainNode: e }) => {
91
+ R(e);
96
92
  });
97
- }, [i, A]);
98
- return v(() => {
99
- const n = ["pointerdown", "touchstart"], t = () => {
100
- S();
93
+ }, []);
94
+ return L(() => {
95
+ const e = ["pointerdown", "touchstart"], u = () => {
96
+ O();
101
97
  };
102
- document.addEventListener("visibilitychange", m), n.forEach((r) => {
103
- window.addEventListener(r, t, { once: !0 });
98
+ document.addEventListener("visibilitychange", A), e.forEach((l) => {
99
+ window.addEventListener(l, u, { once: !0 });
104
100
  });
105
- const o = f.current;
101
+ const o = i.current;
106
102
  return () => {
107
- document.removeEventListener("visibilitychange", m), n.forEach((r) => {
108
- window.removeEventListener(r, t);
109
- }), Object.values(o).forEach((r) => clearTimeout(r));
103
+ document.removeEventListener("visibilitychange", A), e.forEach((l) => {
104
+ window.removeEventListener(l, u);
105
+ }), Object.values(o).forEach((l) => clearTimeout(l));
110
106
  };
111
- }, [m]), {
112
- playSwipeSound: P,
113
- play: i,
114
- stop: A,
107
+ }, [A]), {
108
+ playSwipeSound: p,
109
+ play: d,
110
+ stop: w,
115
111
  playButtonSound: h
116
112
  };
117
- }, D = async (a) => {
113
+ }, U = async (a) => {
118
114
  try {
119
- const s = await fetch(a, {
115
+ const i = await fetch(a, {
120
116
  mode: "cors",
121
117
  credentials: "omit"
122
118
  });
123
- if (!s.ok)
124
- throw new Error(`HTTP error! status: ${s.status}`);
125
- const f = await s.arrayBuffer();
126
- return await u.decodeAudioData(f);
127
- } catch (s) {
128
- console.error("CORS error loading audio:", s);
119
+ if (!i.ok)
120
+ throw new Error(`HTTP error! status: ${i.status}`);
121
+ const f = await i.arrayBuffer();
122
+ return await t.decodeAudioData(f);
123
+ } catch (i) {
124
+ console.error("CORS error loading audio:", i);
129
125
  return;
130
126
  }
131
127
  };
@@ -1 +1 @@
1
- {"version":3,"file":"use-circle-sounds.js","sources":["../../../../../src/features/circle-games/hooks/use-circle-sounds/use-circle-sounds.ts"],"sourcesContent":["/* eslint-disable no-console */\nimport { useCallback, useEffect, useRef } from 'react';\n\nimport { useAutoPlayPermission } from '../../../hooks/use-auto-play-permission/use-auto-play-permission';\nimport { CircleSoundKeyMapper, SWIPE_SOUND_ORDER } from './constants';\nimport type { TimeoutMap } from './use-circle-sound-types';\nimport { CircleSoundKey } from './use-circle-sounds-enums';\n\nlet swipeSoundIndex = 0;\nconst audioContext = new (window.AudioContext || window.webkitAudioContext)();\n\nconst bufferMapper: Record<CircleSoundKey, AudioBuffer | null> = {\n [CircleSoundKey.BACKGROUND]: null,\n [CircleSoundKey.BACKGROUND_RUSHHOUR]: null,\n [CircleSoundKey.TUTORIAL]: null,\n [CircleSoundKey.SWIPE_01]: null,\n [CircleSoundKey.SWIPE_02]: null,\n [CircleSoundKey.SWIPE_03]: null,\n [CircleSoundKey.SWIPE_04]: null,\n [CircleSoundKey.SWIPE_DOWN]: null,\n [CircleSoundKey.TOGGLE]: null,\n [CircleSoundKey.POINTS_AWARDED]: null,\n [CircleSoundKey.POINTS_ADDED]: null,\n [CircleSoundKey.GAME_CARD_CLICK]: null,\n [CircleSoundKey.CLOCK_IN]: null,\n [CircleSoundKey.CLOCK_OUT]: null,\n [CircleSoundKey.ACCURACY_IN]: null,\n [CircleSoundKey.ACCURACY_OUT]: null,\n [CircleSoundKey.STREAK_IN]: null,\n [CircleSoundKey.STREAK_OUT]: null,\n [CircleSoundKey.ACCURACY_INTRO]: null,\n [CircleSoundKey.ACCURACY_TARGET]: null,\n [CircleSoundKey.TIME_INTRO]: null,\n [CircleSoundKey.TIME_TARGET]: null,\n [CircleSoundKey.METER_FILL]: null,\n [CircleSoundKey.YOUR_SCORE]: null,\n [CircleSoundKey.HIGH_SCORE]: null,\n [CircleSoundKey.KEEP_IT_UP]: null,\n [CircleSoundKey.DOING_GREAT]: null,\n [CircleSoundKey.ALL_DONE]: null,\n [CircleSoundKey.ACTIVITY_COMPLETE]: null,\n [CircleSoundKey.ALL_ACTIVITIES_COMPLETE]: null,\n};\n\ntype ActiveSound = {\n source: AudioBufferSourceNode;\n gainNode: GainNode;\n loop: boolean;\n};\n\nconst activeSounds: Partial<Record<CircleSoundKey, ActiveSound>> = {};\n\nlet resuming = false;\nconst resumeAudioContext = async () => {\n if (audioContext.state === 'suspended' && !resuming) {\n resuming = true;\n try {\n await audioContext.resume();\n } catch (err) {\n console.warn('Failed to resume AudioContext:', err);\n } finally {\n resuming = false;\n }\n }\n};\n\nexport const useCircleSounds = () => {\n const { canAutoPlayAudio: canPlayAudio } = useAutoPlayPermission();\n\n const pausedSoundsRef = useRef<Set<CircleSoundKey>>(new Set());\n const timeoutRefs = useRef<TimeoutMap>({});\n\n const loadSound = useCallback(async (key: CircleSoundKey) => {\n if (!bufferMapper[key]) {\n const audioBuffer = await fetchAudio(CircleSoundKeyMapper[key]);\n\n if (audioBuffer) {\n bufferMapper[key] = audioBuffer;\n }\n }\n }, []);\n\n const fadeIn = (gainNode: GainNode) => {\n gainNode.gain.setValueAtTime(0, audioContext.currentTime);\n gainNode.gain.linearRampToValueAtTime(1, audioContext.currentTime + 0.5);\n };\n\n const fadeOut = (gainNode: GainNode, key: CircleSoundKey) => {\n gainNode.gain.setValueAtTime(gainNode.gain.value, audioContext.currentTime);\n gainNode.gain.linearRampToValueAtTime(0, audioContext.currentTime + 0.5);\n const timeout = setTimeout(() => {\n activeSounds[key]?.source.stop();\n delete activeSounds[key];\n }, 500);\n\n timeoutRefs.current[key] = timeout as unknown as number;\n };\n\n const play = useCallback(\n async (key: CircleSoundKey, immediately = true, loop = false) => {\n await resumeAudioContext();\n await loadSound(key);\n const buffer = bufferMapper[key];\n\n if (!buffer || !canPlayAudio) {\n console.warn('Cannot play sound', key, { buffer, canPlayAudio });\n\n return;\n }\n\n // prevent duplicate loop sounds\n if (activeSounds[key] && loop) {\n return;\n }\n\n const source = audioContext.createBufferSource();\n const gainNode = audioContext.createGain();\n\n source.buffer = buffer;\n source.loop = loop;\n source.connect(gainNode).connect(audioContext.destination);\n\n if (immediately) {\n gainNode.gain.setValueAtTime(1, audioContext.currentTime);\n } else {\n fadeIn(gainNode);\n }\n\n source.start();\n activeSounds[key] = { source, gainNode, loop };\n\n if (!loop) {\n source.onended = () => {\n if (activeSounds[key]?.source === source) {\n delete activeSounds[key];\n }\n };\n }\n },\n [canPlayAudio, loadSound],\n );\n\n const stop = useCallback(async (key: CircleSoundKey, immediately = true) => {\n const sound = activeSounds[key];\n\n if (!sound) return;\n\n if (immediately) {\n sound.source.stop();\n delete activeSounds[key];\n } else {\n fadeOut(sound.gainNode, key);\n }\n }, []);\n\n const playSwipeSound = useCallback(() => {\n const key = SWIPE_SOUND_ORDER[swipeSoundIndex] || CircleSoundKey.SWIPE_01;\n\n swipeSoundIndex = (swipeSoundIndex + 1) % SWIPE_SOUND_ORDER.length;\n play(key);\n }, [play]);\n\n const playButtonSound = useCallback(() => {\n play(CircleSoundKey.TOGGLE);\n }, [play]);\n\n const handleVisibilityChange = useCallback(async () => {\n if (document.visibilityState === 'visible') {\n await resumeAudioContext();\n // replay paused sounds with fresh source nodes\n const paused = Array.from(pausedSoundsRef.current);\n\n paused.forEach(key => {\n play(key, false, activeSounds[key]?.loop ?? false);\n });\n pausedSoundsRef.current.clear();\n } else {\n Object.keys(activeSounds).forEach(key => {\n stop(key as CircleSoundKey, true);\n pausedSoundsRef.current.add(key as CircleSoundKey);\n });\n }\n }, [play, stop]);\n\n useEffect(() => {\n const interactionEvents = ['pointerdown', 'touchstart'];\n const tryResume = () => {\n resumeAudioContext();\n };\n\n document.addEventListener('visibilitychange', handleVisibilityChange);\n interactionEvents.forEach(event => {\n window.addEventListener(event, tryResume, { once: true });\n });\n\n const timeouts = timeoutRefs.current;\n\n return () => {\n document.removeEventListener('visibilitychange', handleVisibilityChange);\n interactionEvents.forEach(event => {\n window.removeEventListener(event, tryResume);\n });\n Object.values(timeouts).forEach(id => clearTimeout(id));\n };\n }, [handleVisibilityChange]);\n\n return {\n playSwipeSound,\n play,\n stop,\n playButtonSound,\n };\n};\n\nconst fetchAudio = async (url: string): Promise<AudioBuffer | undefined> => {\n try {\n const response: Response = await fetch(url, {\n mode: 'cors',\n credentials: 'omit',\n });\n\n if (!response.ok) {\n throw new Error(`HTTP error! status: ${response.status}`);\n }\n\n const arrayBuffer: ArrayBuffer = await response.arrayBuffer();\n const decoded: AudioBuffer = await audioContext.decodeAudioData(arrayBuffer);\n\n return decoded;\n } catch (error) {\n console.error('CORS error loading audio:', error);\n\n return undefined;\n }\n};\n"],"names":["swipeSoundIndex","audioContext","bufferMapper","CircleSoundKey","activeSounds","resuming","resumeAudioContext","err","useCircleSounds","canPlayAudio","useAutoPlayPermission","pausedSoundsRef","useRef","timeoutRefs","loadSound","useCallback","key","audioBuffer","fetchAudio","CircleSoundKeyMapper","fadeIn","gainNode","fadeOut","timeout","_a","play","immediately","loop","buffer","source","stop","sound","playSwipeSound","SWIPE_SOUND_ORDER","playButtonSound","handleVisibilityChange","useEffect","interactionEvents","tryResume","event","timeouts","id","url","response","arrayBuffer","error"],"mappings":"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"}
1
+ {"version":3,"file":"use-circle-sounds.js","sources":["../../../../../src/features/circle-games/hooks/use-circle-sounds/use-circle-sounds.ts"],"sourcesContent":["import { useCallback, useEffect, useRef } from 'react';\n\nimport { useAutoPlayPermission } from '../../../hooks/use-auto-play-permission/use-auto-play-permission';\nimport { CircleSoundKeyMapper, SWIPE_SOUND_ORDER } from './constants';\nimport type { TimeoutMap } from './use-circle-sound-types';\nimport { CircleSoundKey } from './use-circle-sounds-enums';\n\nlet swipeSoundIndex = 0;\nconst audioContext = new (window.AudioContext || window.webkitAudioContext)();\n\nconst bufferMapper: Record<CircleSoundKey, AudioBuffer | null> = {\n [CircleSoundKey.BACKGROUND]: null,\n [CircleSoundKey.BACKGROUND_RUSHHOUR]: null,\n [CircleSoundKey.TUTORIAL]: null,\n [CircleSoundKey.SWIPE_01]: null,\n [CircleSoundKey.SWIPE_02]: null,\n [CircleSoundKey.SWIPE_03]: null,\n [CircleSoundKey.SWIPE_04]: null,\n [CircleSoundKey.SWIPE_DOWN]: null,\n [CircleSoundKey.TOGGLE]: null,\n [CircleSoundKey.POINTS_AWARDED]: null,\n [CircleSoundKey.POINTS_ADDED]: null,\n [CircleSoundKey.GAME_CARD_CLICK]: null,\n [CircleSoundKey.CLOCK_IN]: null,\n [CircleSoundKey.CLOCK_OUT]: null,\n [CircleSoundKey.ACCURACY_IN]: null,\n [CircleSoundKey.ACCURACY_OUT]: null,\n [CircleSoundKey.STREAK_IN]: null,\n [CircleSoundKey.STREAK_OUT]: null,\n [CircleSoundKey.ACCURACY_INTRO]: null,\n [CircleSoundKey.ACCURACY_TARGET]: null,\n [CircleSoundKey.TIME_INTRO]: null,\n [CircleSoundKey.TIME_TARGET]: null,\n [CircleSoundKey.METER_FILL]: null,\n [CircleSoundKey.YOUR_SCORE]: null,\n [CircleSoundKey.HIGH_SCORE]: null,\n [CircleSoundKey.KEEP_IT_UP]: null,\n [CircleSoundKey.DOING_GREAT]: null,\n [CircleSoundKey.ALL_DONE]: null,\n [CircleSoundKey.ACTIVITY_COMPLETE]: null,\n [CircleSoundKey.ALL_ACTIVITIES_COMPLETE]: null,\n};\n\ntype ActiveSound = {\n source: AudioBufferSourceNode;\n gainNode: GainNode;\n loop: boolean;\n};\n\nconst activeSounds: Partial<Record<CircleSoundKey, ActiveSound>> = {};\n\nlet resuming = false;\nconst resumeAudioContext = async () => {\n if (audioContext.state === 'suspended' && !resuming) {\n resuming = true;\n try {\n await audioContext.resume();\n } catch (err) {\n // eslint-disable-next-line no-console\n console.warn('Failed to resume AudioContext:', err);\n } finally {\n resuming = false;\n }\n }\n};\n\nexport const useCircleSounds = () => {\n const { canAutoPlayAudio: canPlayAudio } = useAutoPlayPermission();\n\n const timeoutRefs = useRef<TimeoutMap>({});\n\n const loadSound = useCallback(async (key: CircleSoundKey) => {\n if (!bufferMapper[key]) {\n const audioBuffer = await fetchAudio(CircleSoundKeyMapper[key]);\n\n if (audioBuffer) {\n bufferMapper[key] = audioBuffer;\n }\n }\n }, []);\n\n const fadeIn = (gainNode: GainNode) => {\n gainNode.gain.cancelScheduledValues(audioContext.currentTime);\n gainNode.gain.setValueAtTime(gainNode.gain.value, audioContext.currentTime);\n gainNode.gain.linearRampToValueAtTime(1, audioContext.currentTime + 0.5);\n };\n\n const fadeOut = (gainNode: GainNode) => {\n gainNode.gain.cancelScheduledValues(audioContext.currentTime);\n gainNode.gain.setValueAtTime(gainNode.gain.value, audioContext.currentTime);\n gainNode.gain.linearRampToValueAtTime(0, audioContext.currentTime + 0.5);\n };\n\n const play = useCallback(\n async (key: CircleSoundKey, immediately = true, loop = false) => {\n await resumeAudioContext();\n await loadSound(key);\n const buffer = bufferMapper[key];\n\n if (!buffer || !canPlayAudio) {\n // eslint-disable-next-line no-console\n console.warn('Cannot play sound', key, { buffer, canPlayAudio });\n\n return;\n }\n\n // prevent duplicate loop sounds\n if (activeSounds[key] && loop) {\n // if it's just faded out, fade it back in\n fadeIn(activeSounds[key]!.gainNode);\n\n return;\n }\n\n const source = audioContext.createBufferSource();\n const gainNode = audioContext.createGain();\n\n source.buffer = buffer;\n source.loop = loop;\n source.connect(gainNode).connect(audioContext.destination);\n\n if (immediately) {\n gainNode.gain.setValueAtTime(1, audioContext.currentTime);\n } else {\n fadeIn(gainNode);\n }\n\n source.start();\n activeSounds[key] = { source, gainNode, loop };\n\n if (!loop) {\n source.onended = () => {\n if (activeSounds[key]?.source === source) {\n delete activeSounds[key];\n }\n };\n }\n },\n [canPlayAudio, loadSound],\n );\n\n const stop = useCallback(async (key: CircleSoundKey, immediately = true) => {\n const sound = activeSounds[key];\n\n if (!sound) return;\n\n if (immediately) {\n sound.source.stop();\n delete activeSounds[key];\n } else {\n fadeOut(sound.gainNode);\n }\n }, []);\n\n const playSwipeSound = useCallback(() => {\n const key = SWIPE_SOUND_ORDER[swipeSoundIndex] || CircleSoundKey.SWIPE_01;\n\n swipeSoundIndex = (swipeSoundIndex + 1) % SWIPE_SOUND_ORDER.length;\n play(key);\n }, [play]);\n\n const playButtonSound = useCallback(() => {\n play(CircleSoundKey.TOGGLE);\n }, [play]);\n\n const handleVisibilityChange = useCallback(async () => {\n if (document.visibilityState === 'visible') {\n await resumeAudioContext();\n // fade back in active loop sounds\n Object.values(activeSounds).forEach(({ gainNode }) => {\n fadeIn(gainNode);\n });\n } else {\n // fade out but don’t stop\n Object.values(activeSounds).forEach(({ gainNode }) => {\n fadeOut(gainNode);\n });\n }\n }, []);\n\n useEffect(() => {\n const interactionEvents = ['pointerdown', 'touchstart'];\n const tryResume = () => {\n resumeAudioContext();\n };\n\n document.addEventListener('visibilitychange', handleVisibilityChange);\n interactionEvents.forEach(event => {\n window.addEventListener(event, tryResume, { once: true });\n });\n\n const timeouts = timeoutRefs.current;\n\n return () => {\n document.removeEventListener('visibilitychange', handleVisibilityChange);\n interactionEvents.forEach(event => {\n window.removeEventListener(event, tryResume);\n });\n Object.values(timeouts).forEach(id => clearTimeout(id));\n };\n }, [handleVisibilityChange]);\n\n return {\n playSwipeSound,\n play,\n stop,\n playButtonSound,\n };\n};\n\nconst fetchAudio = async (url: string): Promise<AudioBuffer | undefined> => {\n try {\n const response: Response = await fetch(url, {\n mode: 'cors',\n credentials: 'omit',\n });\n\n if (!response.ok) {\n throw new Error(`HTTP error! status: ${response.status}`);\n }\n\n const arrayBuffer: ArrayBuffer = await response.arrayBuffer();\n const decoded: AudioBuffer = await audioContext.decodeAudioData(arrayBuffer);\n\n return decoded;\n } catch (error) {\n // eslint-disable-next-line no-console\n console.error('CORS error loading audio:', error);\n\n return undefined;\n }\n};\n"],"names":["swipeSoundIndex","audioContext","bufferMapper","CircleSoundKey","activeSounds","resuming","resumeAudioContext","err","useCircleSounds","canPlayAudio","useAutoPlayPermission","timeoutRefs","useRef","loadSound","useCallback","key","audioBuffer","fetchAudio","CircleSoundKeyMapper","fadeIn","gainNode","fadeOut","play","immediately","loop","buffer","source","_a","stop","sound","playSwipeSound","SWIPE_SOUND_ORDER","playButtonSound","handleVisibilityChange","useEffect","interactionEvents","tryResume","event","timeouts","id","url","response","arrayBuffer","error"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cuemath/leap",
3
- "version": "3.5.29-mb",
3
+ "version": "3.5.29-mb-2",
4
4
  "type": "module",
5
5
  "files": [
6
6
  "dist"