@cuemath/leap 3.5.41-m-1 → 3.5.41
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.
- package/dist/features/circle-games/hooks/use-circle-sounds/constants.js +4 -7
- package/dist/features/circle-games/hooks/use-circle-sounds/constants.js.map +1 -1
- package/dist/features/circle-games/hooks/use-circle-sounds/helper.js +19 -0
- package/dist/features/circle-games/hooks/use-circle-sounds/helper.js.map +1 -0
- package/dist/features/circle-games/hooks/use-circle-sounds/use-circle-sounds.js +110 -51
- package/dist/features/circle-games/hooks/use-circle-sounds/use-circle-sounds.js.map +1 -1
- package/dist/features/hooks/use-audio-player.js +54 -0
- package/dist/features/hooks/use-audio-player.js.map +1 -0
- package/dist/features/worksheet/worksheet/hooks/use-create-imperative-handle.js +57 -61
- package/dist/features/worksheet/worksheet/hooks/use-create-imperative-handle.js.map +1 -1
- package/dist/features/worksheet/worksheet/worksheet-questions-controller/use-handler-callbacks.js +82 -86
- package/dist/features/worksheet/worksheet/worksheet-questions-controller/use-handler-callbacks.js.map +1 -1
- package/dist/index.d.ts +3 -12
- package/package.json +1 -1
- package/dist/features/hooks/use-audio-player/use-audio-player.js +0 -164
- package/dist/features/hooks/use-audio-player/use-audio-player.js.map +0 -1
|
@@ -35,14 +35,11 @@ const e = "https://cuemath-circle.s3.ap-southeast-1.amazonaws.com/assets/sounds/
|
|
|
35
35
|
c.SWIPE_02,
|
|
36
36
|
c.SWIPE_03,
|
|
37
37
|
c.SWIPE_01
|
|
38
|
-
], _ =
|
|
39
|
-
c.BACKGROUND,
|
|
40
|
-
c.BACKGROUND_RUSHHOUR,
|
|
41
|
-
c.TUTORIAL
|
|
42
|
-
]);
|
|
38
|
+
], _ = 100, E = 0.1;
|
|
43
39
|
export {
|
|
44
|
-
_ as BACKGROUND_SOUNDS,
|
|
45
40
|
t as CircleSoundKeyMapper,
|
|
46
|
-
i as SWIPE_SOUND_ORDER
|
|
41
|
+
i as SWIPE_SOUND_ORDER,
|
|
42
|
+
_ as VOLUME_FADE_DURATION,
|
|
43
|
+
E as VOLUME_TO_CHANGE
|
|
47
44
|
};
|
|
48
45
|
//# sourceMappingURL=constants.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"constants.js","sources":["../../../../../src/features/circle-games/hooks/use-circle-sounds/constants.ts"],"sourcesContent":["import { CircleSoundKey } from './use-circle-sounds-enums';\n\nconst BASE_URL = 'https://cuemath-circle.s3.ap-southeast-1.amazonaws.com/assets/sounds/production';\n\nconst STATIC_BASE_URL = 'https://static.cuemath.com/static/sounds';\n\nexport const CircleSoundKeyMapper = {\n [CircleSoundKey.BACKGROUND]: `${BASE_URL}/bg-sound.mp3`,\n [CircleSoundKey.BACKGROUND_RUSHHOUR]: `${BASE_URL}/circle-background-rushhour.mp3`,\n [CircleSoundKey.TUTORIAL]: `${BASE_URL}/bg-sound-tutorials.mp3`,\n [CircleSoundKey.SWIPE_01]: `${BASE_URL}/circle-swipe-1.wav`,\n [CircleSoundKey.SWIPE_02]: `${BASE_URL}/circle-swipe-2.wav`,\n [CircleSoundKey.SWIPE_03]: `${BASE_URL}/circle-swipe-3.wav`,\n [CircleSoundKey.SWIPE_04]: `${BASE_URL}/circle-swipe-4.wav`,\n [CircleSoundKey.SWIPE_DOWN]: `${BASE_URL}/circle-swipe-down-1.wav`,\n [CircleSoundKey.TOGGLE]: `${BASE_URL}/circle-button-v3.wav`,\n [CircleSoundKey.POINTS_AWARDED]: `${BASE_URL}/circle-points-v2.wav`,\n [CircleSoundKey.ACTIVITY_COMPLETE]: `${BASE_URL}/circle-activity-complete.wav`,\n [CircleSoundKey.POINTS_ADDED]: `${BASE_URL}/circle-points-add-v1.wav`,\n [CircleSoundKey.GAME_CARD_CLICK]: `${BASE_URL}/circle-gamecard-button-v1.wav`,\n [CircleSoundKey.CLOCK_IN]: `${BASE_URL}/circle-meter-v1.wav`,\n [CircleSoundKey.CLOCK_OUT]: `${BASE_URL}/circle-disappear-v1.wav`,\n [CircleSoundKey.ACCURACY_IN]: `${BASE_URL}/circle-meter-v1.wav`,\n [CircleSoundKey.ACCURACY_OUT]: `${BASE_URL}/circle-disappear-v1.wav`,\n [CircleSoundKey.STREAK_IN]: `${BASE_URL}/circle-streak-v1.wav`,\n [CircleSoundKey.STREAK_OUT]: `${BASE_URL}/circle-disappear-v1.wav`,\n [CircleSoundKey.ACCURACY_INTRO]: `${STATIC_BASE_URL}/accuracy-intro.mp3`,\n [CircleSoundKey.ACCURACY_TARGET]: `${STATIC_BASE_URL}/accuracy-target.mp3`,\n [CircleSoundKey.TIME_INTRO]: `${STATIC_BASE_URL}/timer-intro.mp3`,\n [CircleSoundKey.TIME_TARGET]: `${STATIC_BASE_URL}/timer-target.mp3`,\n [CircleSoundKey.METER_FILL]: `${STATIC_BASE_URL}/meter-fill.mp3`,\n [CircleSoundKey.YOUR_SCORE]: `${BASE_URL}/your-score.mp3`,\n [CircleSoundKey.HIGH_SCORE]: `${BASE_URL}/high-score.mp3`,\n [CircleSoundKey.ALL_ACTIVITIES_COMPLETE]: `${BASE_URL}/circle-all-activities-complete.mp3`,\n [CircleSoundKey.ALL_DONE]: `${BASE_URL}/all-done.mp3`,\n [CircleSoundKey.DOING_GREAT]: `${BASE_URL}/doing-great.mp3`,\n [CircleSoundKey.KEEP_IT_UP]: `${BASE_URL}/keep-it-up.mp3`,\n};\n\nexport const SWIPE_SOUND_ORDER = [\n CircleSoundKey.SWIPE_04,\n CircleSoundKey.SWIPE_02,\n CircleSoundKey.SWIPE_03,\n CircleSoundKey.SWIPE_01,\n];\n\nexport const
|
|
1
|
+
{"version":3,"file":"constants.js","sources":["../../../../../src/features/circle-games/hooks/use-circle-sounds/constants.ts"],"sourcesContent":["import { CircleSoundKey } from './use-circle-sounds-enums';\n\nconst BASE_URL = 'https://cuemath-circle.s3.ap-southeast-1.amazonaws.com/assets/sounds/production';\n\nconst STATIC_BASE_URL = 'https://static.cuemath.com/static/sounds';\n\nexport const CircleSoundKeyMapper = {\n [CircleSoundKey.BACKGROUND]: `${BASE_URL}/bg-sound.mp3`,\n [CircleSoundKey.BACKGROUND_RUSHHOUR]: `${BASE_URL}/circle-background-rushhour.mp3`,\n [CircleSoundKey.TUTORIAL]: `${BASE_URL}/bg-sound-tutorials.mp3`,\n [CircleSoundKey.SWIPE_01]: `${BASE_URL}/circle-swipe-1.wav`,\n [CircleSoundKey.SWIPE_02]: `${BASE_URL}/circle-swipe-2.wav`,\n [CircleSoundKey.SWIPE_03]: `${BASE_URL}/circle-swipe-3.wav`,\n [CircleSoundKey.SWIPE_04]: `${BASE_URL}/circle-swipe-4.wav`,\n [CircleSoundKey.SWIPE_DOWN]: `${BASE_URL}/circle-swipe-down-1.wav`,\n [CircleSoundKey.TOGGLE]: `${BASE_URL}/circle-button-v3.wav`,\n [CircleSoundKey.POINTS_AWARDED]: `${BASE_URL}/circle-points-v2.wav`,\n [CircleSoundKey.ACTIVITY_COMPLETE]: `${BASE_URL}/circle-activity-complete.wav`,\n [CircleSoundKey.POINTS_ADDED]: `${BASE_URL}/circle-points-add-v1.wav`,\n [CircleSoundKey.GAME_CARD_CLICK]: `${BASE_URL}/circle-gamecard-button-v1.wav`,\n [CircleSoundKey.CLOCK_IN]: `${BASE_URL}/circle-meter-v1.wav`,\n [CircleSoundKey.CLOCK_OUT]: `${BASE_URL}/circle-disappear-v1.wav`,\n [CircleSoundKey.ACCURACY_IN]: `${BASE_URL}/circle-meter-v1.wav`,\n [CircleSoundKey.ACCURACY_OUT]: `${BASE_URL}/circle-disappear-v1.wav`,\n [CircleSoundKey.STREAK_IN]: `${BASE_URL}/circle-streak-v1.wav`,\n [CircleSoundKey.STREAK_OUT]: `${BASE_URL}/circle-disappear-v1.wav`,\n [CircleSoundKey.ACCURACY_INTRO]: `${STATIC_BASE_URL}/accuracy-intro.mp3`,\n [CircleSoundKey.ACCURACY_TARGET]: `${STATIC_BASE_URL}/accuracy-target.mp3`,\n [CircleSoundKey.TIME_INTRO]: `${STATIC_BASE_URL}/timer-intro.mp3`,\n [CircleSoundKey.TIME_TARGET]: `${STATIC_BASE_URL}/timer-target.mp3`,\n [CircleSoundKey.METER_FILL]: `${STATIC_BASE_URL}/meter-fill.mp3`,\n [CircleSoundKey.YOUR_SCORE]: `${BASE_URL}/your-score.mp3`,\n [CircleSoundKey.HIGH_SCORE]: `${BASE_URL}/high-score.mp3`,\n [CircleSoundKey.ALL_ACTIVITIES_COMPLETE]: `${BASE_URL}/circle-all-activities-complete.mp3`,\n [CircleSoundKey.ALL_DONE]: `${BASE_URL}/all-done.mp3`,\n [CircleSoundKey.DOING_GREAT]: `${BASE_URL}/doing-great.mp3`,\n [CircleSoundKey.KEEP_IT_UP]: `${BASE_URL}/keep-it-up.mp3`,\n};\n\nexport const SWIPE_SOUND_ORDER = [\n CircleSoundKey.SWIPE_04,\n CircleSoundKey.SWIPE_02,\n CircleSoundKey.SWIPE_03,\n CircleSoundKey.SWIPE_01,\n];\n\nexport const VOLUME_FADE_DURATION = 100; // in milliseconds\nexport const VOLUME_TO_CHANGE = 0.1; // volume change per fade step\n"],"names":["BASE_URL","STATIC_BASE_URL","CircleSoundKeyMapper","CircleSoundKey","SWIPE_SOUND_ORDER","VOLUME_FADE_DURATION","VOLUME_TO_CHANGE"],"mappings":";AAEA,MAAMA,IAAW,mFAEXC,IAAkB,4CAEXC,IAAuB;AAAA,EAClC,CAACC,EAAe,UAAU,GAAG,GAAGH,CAAQ;AAAA,EACxC,CAACG,EAAe,mBAAmB,GAAG,GAAGH,CAAQ;AAAA,EACjD,CAACG,EAAe,QAAQ,GAAG,GAAGH,CAAQ;AAAA,EACtC,CAACG,EAAe,QAAQ,GAAG,GAAGH,CAAQ;AAAA,EACtC,CAACG,EAAe,QAAQ,GAAG,GAAGH,CAAQ;AAAA,EACtC,CAACG,EAAe,QAAQ,GAAG,GAAGH,CAAQ;AAAA,EACtC,CAACG,EAAe,QAAQ,GAAG,GAAGH,CAAQ;AAAA,EACtC,CAACG,EAAe,UAAU,GAAG,GAAGH,CAAQ;AAAA,EACxC,CAACG,EAAe,MAAM,GAAG,GAAGH,CAAQ;AAAA,EACpC,CAACG,EAAe,cAAc,GAAG,GAAGH,CAAQ;AAAA,EAC5C,CAACG,EAAe,iBAAiB,GAAG,GAAGH,CAAQ;AAAA,EAC/C,CAACG,EAAe,YAAY,GAAG,GAAGH,CAAQ;AAAA,EAC1C,CAACG,EAAe,eAAe,GAAG,GAAGH,CAAQ;AAAA,EAC7C,CAACG,EAAe,QAAQ,GAAG,GAAGH,CAAQ;AAAA,EACtC,CAACG,EAAe,SAAS,GAAG,GAAGH,CAAQ;AAAA,EACvC,CAACG,EAAe,WAAW,GAAG,GAAGH,CAAQ;AAAA,EACzC,CAACG,EAAe,YAAY,GAAG,GAAGH,CAAQ;AAAA,EAC1C,CAACG,EAAe,SAAS,GAAG,GAAGH,CAAQ;AAAA,EACvC,CAACG,EAAe,UAAU,GAAG,GAAGH,CAAQ;AAAA,EACxC,CAACG,EAAe,cAAc,GAAG,GAAGF,CAAe;AAAA,EACnD,CAACE,EAAe,eAAe,GAAG,GAAGF,CAAe;AAAA,EACpD,CAACE,EAAe,UAAU,GAAG,GAAGF,CAAe;AAAA,EAC/C,CAACE,EAAe,WAAW,GAAG,GAAGF,CAAe;AAAA,EAChD,CAACE,EAAe,UAAU,GAAG,GAAGF,CAAe;AAAA,EAC/C,CAACE,EAAe,UAAU,GAAG,GAAGH,CAAQ;AAAA,EACxC,CAACG,EAAe,UAAU,GAAG,GAAGH,CAAQ;AAAA,EACxC,CAACG,EAAe,uBAAuB,GAAG,GAAGH,CAAQ;AAAA,EACrD,CAACG,EAAe,QAAQ,GAAG,GAAGH,CAAQ;AAAA,EACtC,CAACG,EAAe,WAAW,GAAG,GAAGH,CAAQ;AAAA,EACzC,CAACG,EAAe,UAAU,GAAG,GAAGH,CAAQ;AAC1C,GAEaI,IAAoB;AAAA,EAC/BD,EAAe;AAAA,EACfA,EAAe;AAAA,EACfA,EAAe;AAAA,EACfA,EAAe;AACjB,GAEaE,IAAuB,KACvBC,IAAmB;"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { VOLUME_TO_CHANGE as r, VOLUME_FADE_DURATION as o } from "./constants.js";
|
|
2
|
+
const a = (e) => {
|
|
3
|
+
const l = setInterval(() => {
|
|
4
|
+
const t = e.volume || 0;
|
|
5
|
+
t < 1 ? e.volume = Math.min(t + r, 1) : clearInterval(l);
|
|
6
|
+
}, o);
|
|
7
|
+
return l;
|
|
8
|
+
}, m = (e) => {
|
|
9
|
+
let l = e.volume || 0;
|
|
10
|
+
const t = setInterval(() => {
|
|
11
|
+
l - r <= 0 ? (e.volume = 0, e.pause(), clearInterval(t)) : (l = l - r, e.volume = l);
|
|
12
|
+
}, o);
|
|
13
|
+
return t;
|
|
14
|
+
};
|
|
15
|
+
export {
|
|
16
|
+
a as fadeInSound,
|
|
17
|
+
m as fadeOutSound
|
|
18
|
+
};
|
|
19
|
+
//# sourceMappingURL=helper.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"helper.js","sources":["../../../../../src/features/circle-games/hooks/use-circle-sounds/helper.ts"],"sourcesContent":["import { VOLUME_FADE_DURATION, VOLUME_TO_CHANGE } from './constants';\n\nexport const fadeInSound = (soundInstance: HTMLAudioElement) => {\n const intervalId = setInterval(() => {\n const vol = soundInstance.volume || 0;\n\n if (vol < 1) {\n soundInstance.volume = Math.min(vol + VOLUME_TO_CHANGE, 1);\n } else {\n clearInterval(intervalId);\n }\n }, VOLUME_FADE_DURATION);\n\n return intervalId;\n};\n\nexport const fadeOutSound = (soundInstance: HTMLAudioElement) => {\n let vol = soundInstance.volume || 0;\n const intervalId = setInterval(() => {\n if (vol - VOLUME_TO_CHANGE <= 0) {\n soundInstance.volume = 0;\n soundInstance.pause();\n clearInterval(intervalId);\n } else {\n vol = vol - VOLUME_TO_CHANGE;\n soundInstance.volume = vol;\n }\n }, VOLUME_FADE_DURATION);\n\n return intervalId;\n};\n"],"names":["fadeInSound","soundInstance","intervalId","vol","VOLUME_TO_CHANGE","VOLUME_FADE_DURATION","fadeOutSound"],"mappings":";AAEa,MAAAA,IAAc,CAACC,MAAoC;AACxD,QAAAC,IAAa,YAAY,MAAM;AAC7B,UAAAC,IAAMF,EAAc,UAAU;AAEpC,IAAIE,IAAM,IACRF,EAAc,SAAS,KAAK,IAAIE,IAAMC,GAAkB,CAAC,IAEzD,cAAcF,CAAU;AAAA,KAEzBG,CAAoB;AAEhB,SAAAH;AACT,GAEaI,IAAe,CAACL,MAAoC;AAC3D,MAAAE,IAAMF,EAAc,UAAU;AAC5B,QAAAC,IAAa,YAAY,MAAM;AAC/B,IAAAC,IAAMC,KAAoB,KAC5BH,EAAc,SAAS,GACvBA,EAAc,MAAM,GACpB,cAAcC,CAAU,MAExBC,IAAMA,IAAMC,GACZH,EAAc,SAASE;AAAA,KAExBE,CAAoB;AAEhB,SAAAH;AACT;"}
|
|
@@ -1,56 +1,115 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { useAutoPlayPermission as
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
play: o,
|
|
44
|
-
stop: l,
|
|
45
|
-
audioManager: {
|
|
46
|
-
stopAll: e.stopAll,
|
|
47
|
-
isPlaying: e.isPlaying,
|
|
48
|
-
setVolume: e.setVolume,
|
|
49
|
-
loadSound: e.loadSound
|
|
1
|
+
import { useCallback as s, useRef as T, useEffect as P } from "react";
|
|
2
|
+
import { useAutoPlayPermission as m } from "../../../hooks/use-auto-play-permission/use-auto-play-permission.js";
|
|
3
|
+
import { CircleSoundKeyMapper as L, SWIPE_SOUND_ORDER as O } from "./constants.js";
|
|
4
|
+
import { fadeInSound as R, fadeOutSound as U } from "./helper.js";
|
|
5
|
+
import { CircleSoundKey as n } from "./use-circle-sounds-enums.js";
|
|
6
|
+
let S = 0;
|
|
7
|
+
const c = {
|
|
8
|
+
[n.BACKGROUND]: null,
|
|
9
|
+
[n.BACKGROUND_RUSHHOUR]: null,
|
|
10
|
+
[n.TUTORIAL]: null,
|
|
11
|
+
[n.SWIPE_01]: null,
|
|
12
|
+
[n.SWIPE_02]: null,
|
|
13
|
+
[n.SWIPE_03]: null,
|
|
14
|
+
[n.SWIPE_04]: null,
|
|
15
|
+
[n.SWIPE_DOWN]: null,
|
|
16
|
+
[n.TOGGLE]: null,
|
|
17
|
+
[n.POINTS_AWARDED]: null,
|
|
18
|
+
[n.POINTS_ADDED]: null,
|
|
19
|
+
[n.GAME_CARD_CLICK]: null,
|
|
20
|
+
[n.CLOCK_IN]: null,
|
|
21
|
+
[n.CLOCK_OUT]: null,
|
|
22
|
+
[n.ACCURACY_IN]: null,
|
|
23
|
+
[n.ACCURACY_OUT]: null,
|
|
24
|
+
[n.STREAK_IN]: null,
|
|
25
|
+
[n.STREAK_OUT]: null,
|
|
26
|
+
[n.ACCURACY_INTRO]: null,
|
|
27
|
+
[n.ACCURACY_TARGET]: null,
|
|
28
|
+
[n.TIME_INTRO]: null,
|
|
29
|
+
[n.TIME_TARGET]: null,
|
|
30
|
+
[n.METER_FILL]: null,
|
|
31
|
+
[n.YOUR_SCORE]: null,
|
|
32
|
+
[n.HIGH_SCORE]: null,
|
|
33
|
+
[n.KEEP_IT_UP]: null,
|
|
34
|
+
[n.DOING_GREAT]: null,
|
|
35
|
+
[n.ALL_DONE]: null,
|
|
36
|
+
[n.ACTIVITY_COMPLETE]: null,
|
|
37
|
+
[n.ALL_ACTIVITIES_COMPLETE]: null
|
|
38
|
+
}, _ = {}, b = () => {
|
|
39
|
+
const { canAutoPlayAudio: f } = m(), C = s((l) => {
|
|
40
|
+
if (!c[l]) {
|
|
41
|
+
const t = new Audio(L[l]);
|
|
42
|
+
c[l] = t;
|
|
50
43
|
}
|
|
51
|
-
}
|
|
44
|
+
}, []), i = T(/* @__PURE__ */ new Set()), o = T({}), r = s(
|
|
45
|
+
(l, t = !0, e = !1) => {
|
|
46
|
+
C(l);
|
|
47
|
+
const u = c[l];
|
|
48
|
+
if (!u || !f) return;
|
|
49
|
+
if (e && (u.loop = e), o.current[l] && clearInterval(o.current[l]), !u.paused && u.currentTime > 0 && !u.ended) {
|
|
50
|
+
if (t)
|
|
51
|
+
u.volume = 1;
|
|
52
|
+
else {
|
|
53
|
+
const I = R(u);
|
|
54
|
+
o.current[l] = I;
|
|
55
|
+
}
|
|
56
|
+
return u;
|
|
57
|
+
}
|
|
58
|
+
u.volume = t ? 1 : 0;
|
|
59
|
+
const A = u.play();
|
|
60
|
+
if (A && (_[l] = A), !t) {
|
|
61
|
+
const I = R(u);
|
|
62
|
+
o.current[l] = I;
|
|
63
|
+
}
|
|
64
|
+
return u;
|
|
65
|
+
},
|
|
66
|
+
[C, f]
|
|
67
|
+
), a = s((l, t) => {
|
|
68
|
+
const e = c[l];
|
|
69
|
+
if (!e) return;
|
|
70
|
+
if (o.current[l] && clearInterval(o.current[l]), t) {
|
|
71
|
+
e.pause();
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
const u = U(e);
|
|
75
|
+
o.current[l] = u;
|
|
76
|
+
}, []), d = s(
|
|
77
|
+
(l, t = !0) => {
|
|
78
|
+
var e;
|
|
79
|
+
if (_[l] !== void 0) {
|
|
80
|
+
(e = _[l]) == null || e.then(() => {
|
|
81
|
+
a(l, t);
|
|
82
|
+
}).catch((u) => {
|
|
83
|
+
console.log("sound not playing", u);
|
|
84
|
+
});
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
a(l, t);
|
|
88
|
+
},
|
|
89
|
+
[a]
|
|
90
|
+
), p = s(() => {
|
|
91
|
+
const l = O[S] || n.SWIPE_01;
|
|
92
|
+
S = (S + 1) % O.length, r(l);
|
|
93
|
+
}, [r]), v = s(() => r(n.TOGGLE), [r]), E = s(() => {
|
|
94
|
+
const l = document.visibilityState;
|
|
95
|
+
l === "hidden" && Object.entries(c).forEach(([t, e]) => {
|
|
96
|
+
e && !e.paused && (d(t, !0), i.current.add(t));
|
|
97
|
+
}), l === "visible" && (i.current.forEach((t) => {
|
|
98
|
+
r(t);
|
|
99
|
+
}), i.current.clear());
|
|
100
|
+
}, [r, d]);
|
|
101
|
+
return P(() => {
|
|
102
|
+
document.addEventListener("visibilitychange", E);
|
|
103
|
+
const l = o.current;
|
|
104
|
+
return () => {
|
|
105
|
+
document.removeEventListener("visibilitychange", E), Object.values(l).forEach((t) => {
|
|
106
|
+
t && clearInterval(t);
|
|
107
|
+
});
|
|
108
|
+
};
|
|
109
|
+
}, [E]), { playSwipeSound: p, play: r, stop: d, playButtonSound: v };
|
|
52
110
|
};
|
|
53
111
|
export {
|
|
54
|
-
|
|
112
|
+
c as soundMapper,
|
|
113
|
+
b as useCircleSounds
|
|
55
114
|
};
|
|
56
115
|
//# sourceMappingURL=use-circle-sounds.js.map
|
|
@@ -1 +1 @@
|
|
|
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 { useAudioPlayer } from '../../../hooks/use-audio-player/use-audio-player';\nimport { CircleSoundKey } from './use-circle-sounds-enums';\nimport { BACKGROUND_SOUNDS, CircleSoundKeyMapper, SWIPE_SOUND_ORDER } from './constants';\n\nexport const useCircleSounds = () => {\n const { canAutoPlayAudio } = useAutoPlayPermission();\n const swipeIndexRef = useRef(0);\n\n const audioManager = useAudioPlayer(CircleSoundKeyMapper, canAutoPlayAudio);\n\n const play = useCallback(\n async (key: CircleSoundKey, immediately = true, loop = false) => {\n return audioManager.play(key, {\n loop,\n fadeIn: !immediately,\n fadeDuration: 0.5,\n });\n },\n [audioManager],\n );\n\n const stop = useCallback(\n async (key: CircleSoundKey, immediately = true) => {\n return audioManager.stop(key, {\n immediately,\n fadeOut: !immediately,\n fadeDuration: 0.5,\n });\n },\n [audioManager],\n );\n\n const playSwipeSound = useCallback(() => {\n const key = SWIPE_SOUND_ORDER[swipeIndexRef.current] || CircleSoundKey.SWIPE_01;\n\n swipeIndexRef.current = (swipeIndexRef.current + 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(() => {\n audioManager.handleVisibilityChange(BACKGROUND_SOUNDS, true);\n }, [audioManager]);\n\n useEffect(() => {\n const interactionEvents = ['pointerdown', 'touchstart'];\n\n const tryResume = () => {\n audioManager.resumeAudioContext();\n };\n\n interactionEvents.forEach(event => {\n window.addEventListener(event, tryResume, { once: true });\n });\n\n document.addEventListener('visibilitychange', handleVisibilityChange);\n\n return () => {\n interactionEvents.forEach(event => {\n window.removeEventListener(event, tryResume);\n });\n document.removeEventListener('visibilitychange', handleVisibilityChange);\n };\n }, [audioManager, handleVisibilityChange]);\n\n return {\n playSwipeSound,\n playButtonSound,\n play,\n stop,\n\n audioManager: {\n stopAll: audioManager.stopAll,\n isPlaying: audioManager.isPlaying,\n setVolume: audioManager.setVolume,\n loadSound: audioManager.loadSound,\n },\n };\n};\n"],"names":["useCircleSounds","canAutoPlayAudio","useAutoPlayPermission","swipeIndexRef","useRef","audioManager","useAudioPlayer","CircleSoundKeyMapper","play","useCallback","key","immediately","loop","stop","playSwipeSound","SWIPE_SOUND_ORDER","CircleSoundKey","playButtonSound","handleVisibilityChange","BACKGROUND_SOUNDS","useEffect","interactionEvents","tryResume","event"],"mappings":";;;;;AAOO,MAAMA,IAAkB,MAAM;AAC7B,QAAA,EAAE,kBAAAC,MAAqBC,KACvBC,IAAgBC,EAAO,CAAC,GAExBC,IAAeC,EAAeC,GAAsBN,CAAgB,GAEpEO,IAAOC;AAAA,IACX,OAAOC,GAAqBC,IAAc,IAAMC,IAAO,OAC9CP,EAAa,KAAKK,GAAK;AAAA,MAC5B,MAAAE;AAAA,MACA,QAAQ,CAACD;AAAA,MACT,cAAc;AAAA,IAAA,CACf;AAAA,IAEH,CAACN,CAAY;AAAA,EAAA,GAGTQ,IAAOJ;AAAA,IACX,OAAOC,GAAqBC,IAAc,OACjCN,EAAa,KAAKK,GAAK;AAAA,MAC5B,aAAAC;AAAA,MACA,SAAS,CAACA;AAAA,MACV,cAAc;AAAA,IAAA,CACf;AAAA,IAEH,CAACN,CAAY;AAAA,EAAA,GAGTS,IAAiBL,EAAY,MAAM;AACvC,UAAMC,IAAMK,EAAkBZ,EAAc,OAAO,KAAKa,EAAe;AAEvE,IAAAb,EAAc,WAAWA,EAAc,UAAU,KAAKY,EAAkB,QACxEP,EAAKE,CAAG;AAAA,EAAA,GACP,CAACF,CAAI,CAAC,GAEHS,IAAkBR,EAAY,MAAM;AACxC,IAAAD,EAAKQ,EAAe,MAAM;AAAA,EAAA,GACzB,CAACR,CAAI,CAAC,GAEHU,IAAyBT,EAAY,MAAM;AAClC,IAAAJ,EAAA,uBAAuBc,GAAmB,EAAI;AAAA,EAAA,GAC1D,CAACd,CAAY,CAAC;AAEjB,SAAAe,EAAU,MAAM;AACR,UAAAC,IAAoB,CAAC,eAAe,YAAY,GAEhDC,IAAY,MAAM;AACtB,MAAAjB,EAAa,mBAAmB;AAAA,IAAA;AAGlC,WAAAgB,EAAkB,QAAQ,CAASE,MAAA;AACjC,aAAO,iBAAiBA,GAAOD,GAAW,EAAE,MAAM,IAAM;AAAA,IAAA,CACzD,GAEQ,SAAA,iBAAiB,oBAAoBJ,CAAsB,GAE7D,MAAM;AACX,MAAAG,EAAkB,QAAQ,CAASE,MAAA;AAC1B,eAAA,oBAAoBA,GAAOD,CAAS;AAAA,MAAA,CAC5C,GACQ,SAAA,oBAAoB,oBAAoBJ,CAAsB;AAAA,IAAA;AAAA,EACzE,GACC,CAACb,GAAca,CAAsB,CAAC,GAElC;AAAA,IACL,gBAAAJ;AAAA,IACA,iBAAAG;AAAA,IACA,MAAAT;AAAA,IACA,MAAAK;AAAA,IAEA,cAAc;AAAA,MACZ,SAASR,EAAa;AAAA,MACtB,WAAWA,EAAa;AAAA,MACxB,WAAWA,EAAa;AAAA,MACxB,WAAWA,EAAa;AAAA,IAC1B;AAAA,EAAA;AAEJ;"}
|
|
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 { fadeInSound, fadeOutSound } from './helper';\nimport type { TimeoutMap } from './use-circle-sound-types';\nimport { CircleSoundKey } from './use-circle-sounds-enums';\n\nlet swipeSoundIndex = 0;\n\nexport const soundMapper: Record<keyof typeof CircleSoundKeyMapper, null | HTMLAudioElement> = {\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\nconst soundInstancePromise: Partial<Record<keyof typeof CircleSoundKeyMapper, Promise<void>>> = {};\n\nexport const useCircleSounds = () => {\n const { canAutoPlayAudio: canPlayAudio } = useAutoPlayPermission();\n\n const loadSound = useCallback((key: CircleSoundKey) => {\n if (!soundMapper[key]) {\n const loadedSound = new Audio(CircleSoundKeyMapper[key]);\n\n soundMapper[key] = loadedSound;\n }\n }, []);\n\n const pausedSoundsRef = useRef<Set<CircleSoundKey>>(new Set());\n const timeoutRefs = useRef<TimeoutMap>({});\n\n const play = useCallback(\n (key: CircleSoundKey, immediately: boolean = true, loop = false) => {\n loadSound(key);\n const soundInstance = soundMapper[key];\n\n if (!soundInstance || !canPlayAudio) return;\n\n // this makes sure that it keeps the default loop value at the time it was requested to be loaded\n // helps in visibility change where we only want to resume\n if (loop) {\n soundInstance.loop = loop;\n }\n\n if (timeoutRefs.current[key]) {\n clearInterval(timeoutRefs.current[key]);\n }\n\n // resume sound\n if (!soundInstance.paused && soundInstance.currentTime > 0 && !soundInstance.ended) {\n if (!immediately) {\n const intervalId = fadeInSound(soundInstance);\n\n timeoutRefs.current[key] = intervalId;\n } else {\n soundInstance.volume = 1;\n }\n\n return soundInstance;\n }\n\n // play sound\n soundInstance.volume = immediately ? 1 : 0;\n const promise = soundInstance.play();\n\n if (promise) {\n soundInstancePromise[key] = promise;\n }\n\n if (!immediately) {\n const intervalId = fadeInSound(soundInstance);\n\n timeoutRefs.current[key] = intervalId;\n }\n\n return soundInstance;\n },\n [loadSound, canPlayAudio],\n );\n\n const handleSoundStop = useCallback((key: CircleSoundKey, immediately: boolean) => {\n const soundInstance = soundMapper[key];\n\n if (!soundInstance) return;\n\n if (timeoutRefs.current[key]) {\n clearInterval(timeoutRefs.current[key]);\n }\n\n if (immediately) {\n soundInstance.pause();\n\n return;\n }\n\n const intervalId = fadeOutSound(soundInstance);\n\n timeoutRefs.current[key] = intervalId;\n }, []);\n\n const stop = useCallback(\n (key: CircleSoundKey, immediately: boolean = true) => {\n // if play returned a promise\n if (soundInstancePromise[key] !== undefined) {\n soundInstancePromise[key]\n ?.then(() => {\n handleSoundStop(key, immediately);\n })\n .catch(err => {\n // eslint-disable-next-line no-console\n console.log('sound not playing', err);\n });\n\n return;\n }\n\n handleSoundStop(key, immediately);\n },\n [handleSoundStop],\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\n play(key);\n }, [play]);\n\n const playButtonSound = useCallback(() => {\n const sound = play(CircleSoundKey.TOGGLE);\n\n return sound;\n }, [play]);\n\n const handleVisibilityChange = useCallback(() => {\n const visibilityState = document.visibilityState;\n\n if (visibilityState === 'hidden') {\n Object.entries(soundMapper).forEach(([key, sound]) => {\n if (sound && !sound.paused) {\n stop(key as CircleSoundKey, true);\n pausedSoundsRef.current.add(key as CircleSoundKey);\n }\n });\n }\n\n if (visibilityState === 'visible') {\n pausedSoundsRef.current.forEach(key => {\n play(key);\n });\n pausedSoundsRef.current.clear();\n }\n }, [play, stop]);\n\n useEffect(() => {\n document.addEventListener('visibilitychange', handleVisibilityChange);\n const timeouts = timeoutRefs.current;\n\n return () => {\n document.removeEventListener('visibilitychange', handleVisibilityChange);\n Object.values(timeouts).forEach(id => {\n if (id) {\n clearInterval(id);\n }\n });\n };\n }, [handleVisibilityChange]);\n\n return { playSwipeSound, play, stop, playButtonSound };\n};\n"],"names":["swipeSoundIndex","soundMapper","CircleSoundKey","soundInstancePromise","useCircleSounds","canPlayAudio","useAutoPlayPermission","loadSound","useCallback","key","loadedSound","CircleSoundKeyMapper","pausedSoundsRef","useRef","timeoutRefs","play","immediately","loop","soundInstance","intervalId","fadeInSound","promise","handleSoundStop","fadeOutSound","stop","_a","err","playSwipeSound","SWIPE_SOUND_ORDER","playButtonSound","handleVisibilityChange","visibilityState","sound","useEffect","timeouts","id"],"mappings":"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"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { useState as _, useMemo as y, useCallback as f, useEffect as w } from "react";
|
|
2
|
+
import { useUIContext as x } from "../ui/context/context.js";
|
|
3
|
+
const A = (u) => {
|
|
4
|
+
const [c, s] = _({}), { onEvent: o } = x(), t = y(() => {
|
|
5
|
+
const e = window.AudioContext || window.webkitAudioContext;
|
|
6
|
+
try {
|
|
7
|
+
if (e)
|
|
8
|
+
return new e();
|
|
9
|
+
} catch (r) {
|
|
10
|
+
o("audio_context_detection_failed", { error: r, isContextPresent: !!e });
|
|
11
|
+
}
|
|
12
|
+
return null;
|
|
13
|
+
}, [o]), a = f(
|
|
14
|
+
async (e, r) => {
|
|
15
|
+
if (t)
|
|
16
|
+
try {
|
|
17
|
+
const i = await (await fetch(e)).arrayBuffer(), d = await t.decodeAudioData(i);
|
|
18
|
+
s((l) => ({ ...l, [r]: d }));
|
|
19
|
+
} catch (n) {
|
|
20
|
+
o("audio_fetch_failed", { error: n });
|
|
21
|
+
}
|
|
22
|
+
},
|
|
23
|
+
[t, o]
|
|
24
|
+
);
|
|
25
|
+
return w(() => (u.forEach(({ url: e, name: r }) => {
|
|
26
|
+
a(e, r);
|
|
27
|
+
}), () => {
|
|
28
|
+
try {
|
|
29
|
+
t && t.state !== "closed" && t.close();
|
|
30
|
+
} catch (e) {
|
|
31
|
+
o("audio_context_closing_failed", { error: e });
|
|
32
|
+
}
|
|
33
|
+
}), [u, t, a, o]), f(
|
|
34
|
+
(e) => {
|
|
35
|
+
if (!t) return;
|
|
36
|
+
const r = c[e];
|
|
37
|
+
if (!r) {
|
|
38
|
+
o("audio_buffer_not_found", { name: e });
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
try {
|
|
42
|
+
const n = t.createBufferSource();
|
|
43
|
+
n.buffer = r, n.connect(t.destination), n.start();
|
|
44
|
+
} catch (n) {
|
|
45
|
+
o("audio_source_creation_failed", { name: e, sourceError: n });
|
|
46
|
+
}
|
|
47
|
+
},
|
|
48
|
+
[c, t, o]
|
|
49
|
+
);
|
|
50
|
+
};
|
|
51
|
+
export {
|
|
52
|
+
A as default
|
|
53
|
+
};
|
|
54
|
+
//# sourceMappingURL=use-audio-player.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"use-audio-player.js","sources":["../../../src/features/hooks/use-audio-player.ts"],"sourcesContent":["import { useCallback, useEffect, useMemo, useState } from 'react';\n\nimport { useUIContext } from '../ui/context/context';\n\ndeclare global {\n interface Window {\n webkitAudioContext?: AudioContext;\n }\n}\n\nconst useAudioPlayer = (audioUrls: { url: string; name: string }[]) => {\n const [audioBuffers, setAudioBuffers] = useState<Record<string, AudioBuffer | null>>({});\n const { onEvent: trackEvent } = useUIContext();\n\n const context = useMemo(() => {\n const Ctx = window.AudioContext || window.webkitAudioContext;\n\n try {\n if (Ctx) {\n return new Ctx();\n }\n } catch (e) {\n trackEvent('audio_context_detection_failed', { error: e, isContextPresent: !!Ctx });\n }\n\n return null;\n }, [trackEvent]);\n\n const getAudioBuffer = useCallback(\n async (url: string, name: string) => {\n if (!context) return;\n\n try {\n const response = await fetch(url);\n const arrayBuffer = await response.arrayBuffer();\n const audioBuffer = await context.decodeAudioData(arrayBuffer);\n\n setAudioBuffers(prev => ({ ...prev, [name]: audioBuffer }));\n } catch (e) {\n trackEvent('audio_fetch_failed', { error: e });\n }\n },\n [context, trackEvent],\n );\n\n useEffect(() => {\n audioUrls.forEach(({ url, name }) => {\n getAudioBuffer(url, name);\n });\n\n return () => {\n try {\n if (context && context.state !== 'closed') context.close();\n } catch (e) {\n trackEvent('audio_context_closing_failed', { error: e });\n }\n };\n }, [audioUrls, context, getAudioBuffer, trackEvent]);\n const playSound = useCallback(\n (name: string) => {\n if (!context) return;\n\n const buffer = audioBuffers[name];\n\n if (!buffer) {\n trackEvent('audio_buffer_not_found', { name });\n\n return;\n }\n\n try {\n const source = context.createBufferSource();\n\n source.buffer = buffer;\n source.connect(context.destination);\n source.start();\n } catch (sourceError) {\n trackEvent('audio_source_creation_failed', { name, sourceError });\n }\n },\n [audioBuffers, context, trackEvent],\n );\n\n return playSound;\n};\n\nexport default useAudioPlayer;\n"],"names":["useAudioPlayer","audioUrls","audioBuffers","setAudioBuffers","useState","trackEvent","useUIContext","context","useMemo","Ctx","e","getAudioBuffer","useCallback","url","name","arrayBuffer","audioBuffer","prev","useEffect","buffer","source","sourceError"],"mappings":";;AAUM,MAAAA,IAAiB,CAACC,MAA+C;AACrE,QAAM,CAACC,GAAcC,CAAe,IAAIC,EAA6C,CAAE,CAAA,GACjF,EAAE,SAASC,EAAW,IAAIC,EAAa,GAEvCC,IAAUC,EAAQ,MAAM;AACtB,UAAAC,IAAM,OAAO,gBAAgB,OAAO;AAEtC,QAAA;AACF,UAAIA;AACF,eAAO,IAAIA,EAAI;AAAA,aAEVC,GAAG;AACC,MAAAL,EAAA,kCAAkC,EAAE,OAAOK,GAAG,kBAAkB,CAAC,CAACD,GAAK;AAAA,IACpF;AAEO,WAAA;AAAA,EAAA,GACN,CAACJ,CAAU,CAAC,GAETM,IAAiBC;AAAA,IACrB,OAAOC,GAAaC,MAAiB;AACnC,UAAKP;AAED,YAAA;AAEI,gBAAAQ,IAAc,OADH,MAAM,MAAMF,CAAG,GACG,eAC7BG,IAAc,MAAMT,EAAQ,gBAAgBQ,CAAW;AAE7C,UAAAZ,EAAA,CAAAc,OAAS,EAAE,GAAGA,GAAM,CAACH,CAAI,GAAGE,EAAc,EAAA;AAAA,iBACnDN,GAAG;AACV,UAAAL,EAAW,sBAAsB,EAAE,OAAOK,EAAG,CAAA;AAAA,QAC/C;AAAA,IACF;AAAA,IACA,CAACH,GAASF,CAAU;AAAA,EAAA;AAGtB,SAAAa,EAAU,OACRjB,EAAU,QAAQ,CAAC,EAAE,KAAAY,GAAK,MAAAC,QAAW;AACnC,IAAAH,EAAeE,GAAKC,CAAI;AAAA,EAAA,CACzB,GAEM,MAAM;AACP,QAAA;AACF,MAAIP,KAAWA,EAAQ,UAAU,cAAkB;aAC5C,GAAG;AACV,MAAAF,EAAW,gCAAgC,EAAE,OAAO,EAAG,CAAA;AAAA,IACzD;AAAA,EAAA,IAED,CAACJ,GAAWM,GAASI,GAAgBN,CAAU,CAAC,GACjCO;AAAA,IAChB,CAACE,MAAiB;AAChB,UAAI,CAACP,EAAS;AAER,YAAAY,IAASjB,EAAaY,CAAI;AAEhC,UAAI,CAACK,GAAQ;AACA,QAAAd,EAAA,0BAA0B,EAAE,MAAAS,EAAA,CAAM;AAE7C;AAAA,MACF;AAEI,UAAA;AACI,cAAAM,IAASb,EAAQ;AAEvB,QAAAa,EAAO,SAASD,GACTC,EAAA,QAAQb,EAAQ,WAAW,GAClCa,EAAO,MAAM;AAAA,eACNC,GAAa;AACpB,QAAAhB,EAAW,gCAAgC,EAAE,MAAAS,GAAM,aAAAO,EAAa,CAAA;AAAA,MAClE;AAAA,IACF;AAAA,IACA,CAACnB,GAAcK,GAASF,CAAU;AAAA,EAAA;AAItC;"}
|
|
@@ -1,70 +1,66 @@
|
|
|
1
|
-
import { useCallback as O, useImperativeHandle as
|
|
2
|
-
import
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
|
|
8
|
-
const
|
|
9
|
-
const { onResponseChange: Q, onBulkResponsesChange: n, behavior: w, questions: s, setResponses: m } = z((t) => ({
|
|
1
|
+
import { useCallback as O, useImperativeHandle as C } from "react";
|
|
2
|
+
import M from "../../../hooks/use-audio-player.js";
|
|
3
|
+
import { TEACHER_VALIDATION_AUDIO_LIST as k } from "../constants.js";
|
|
4
|
+
import { getQuestionMetadata as u, isConceptIntroWidget as H } from "../worksheet-helpers.js";
|
|
5
|
+
import { QUESTIONS_RATING as V, QUESTION_TAGS as A } from "../worksheet-types.js";
|
|
6
|
+
import { useWorksheetStore as G } from "./use-worksheet-store.js";
|
|
7
|
+
const X = (b, { getTimeSpentOnQuestion: N }) => {
|
|
8
|
+
const { onResponseChange: Q, onBulkResponsesChange: n, behavior: w, questions: s, setResponses: m } = G((t) => ({
|
|
10
9
|
onResponseChange: t.onResponseChange,
|
|
11
10
|
onBulkResponsesChange: t.onBulkResponsesChange,
|
|
12
11
|
behavior: t.behavior,
|
|
13
12
|
questions: t.questions,
|
|
14
13
|
setResponses: t.setResponses
|
|
15
|
-
})), { navigationMode:
|
|
16
|
-
(t,
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
(t, r, d) => {
|
|
20
|
-
h.play("VALIDATE");
|
|
21
|
-
const a = y(t);
|
|
14
|
+
})), { navigationMode: h } = w, g = M(k), y = O(
|
|
15
|
+
(t, r, c) => {
|
|
16
|
+
g("VALIDATE");
|
|
17
|
+
const a = N(t);
|
|
22
18
|
m((e) => {
|
|
23
|
-
var
|
|
24
|
-
const
|
|
19
|
+
var P, D;
|
|
20
|
+
const d = s.findIndex((p) => p.response_id === t), i = s[d], o = {
|
|
25
21
|
...u(s, t),
|
|
26
22
|
...e[t],
|
|
27
23
|
validatedByTeacher: !0,
|
|
28
|
-
rating: r ?
|
|
24
|
+
rating: r ? V[r] : void 0,
|
|
29
25
|
timeSpent: a
|
|
30
26
|
};
|
|
31
|
-
if (
|
|
32
|
-
if ((
|
|
27
|
+
if (h === "ADAPTIVE") {
|
|
28
|
+
if ((P = e[t]) != null && P.validatedByTeacher)
|
|
33
29
|
return e;
|
|
34
|
-
const p = i.item_tags_map[
|
|
30
|
+
const p = i.item_tags_map[A.TRIAL_TOPIC], I = i.item_tags_map[A.QUESTION_CODE], T = I && I.length < 3 ? `${I}${r}` : "Q", _ = s.findIndex((f, l) => l <= d ? !1 : T !== "Q" ? f.item_tags_map[A.TRIAL_TOPIC] === p && f.item_tags_map[A.QUESTION_CODE] === T : f.item_tags_map[A.TRIAL_TOPIC] !== p), S = {
|
|
35
31
|
[t]: o,
|
|
36
32
|
...s.reduce(
|
|
37
|
-
(f,
|
|
38
|
-
...u(s,
|
|
39
|
-
...e[
|
|
33
|
+
(f, l, W) => (W <= d || _ > -1 && W >= _ || (f[l.response_id] = {
|
|
34
|
+
...u(s, l.response_id),
|
|
35
|
+
...e[l.response_id],
|
|
40
36
|
assignStatus: "skipped"
|
|
41
37
|
}), f),
|
|
42
38
|
{}
|
|
43
39
|
)
|
|
44
|
-
}, E = (D = s[
|
|
40
|
+
}, E = (D = s[_]) == null ? void 0 : D.response_id;
|
|
45
41
|
return E ? n == null || n({
|
|
46
|
-
...
|
|
42
|
+
...S,
|
|
47
43
|
[E]: {
|
|
48
44
|
...e[E],
|
|
49
45
|
...u(s, E),
|
|
50
46
|
assignStatus: void 0
|
|
51
47
|
}
|
|
52
|
-
}) : n == null || n(
|
|
48
|
+
}) : n == null || n(S), {
|
|
53
49
|
...e,
|
|
54
|
-
...
|
|
50
|
+
...S
|
|
55
51
|
};
|
|
56
52
|
}
|
|
57
|
-
if (
|
|
53
|
+
if (c) {
|
|
58
54
|
const { item_reference: p } = i, I = {
|
|
59
55
|
[t]: o,
|
|
60
56
|
...s.reduce(
|
|
61
|
-
(
|
|
62
|
-
var
|
|
63
|
-
return
|
|
64
|
-
...u(s,
|
|
65
|
-
...e[
|
|
57
|
+
(T, _) => {
|
|
58
|
+
var S;
|
|
59
|
+
return _.response_id !== i.response_id && _.item_reference === p && !((S = e[_.response_id]) != null && S.validatedByTeacher) && (T[_.response_id] = {
|
|
60
|
+
...u(s, _.response_id),
|
|
61
|
+
...e[_.response_id],
|
|
66
62
|
assignStatus: "skipped"
|
|
67
|
-
}),
|
|
63
|
+
}), T;
|
|
68
64
|
},
|
|
69
65
|
{}
|
|
70
66
|
)
|
|
@@ -77,7 +73,7 @@ const B = (b, { getTimeSpentOnQuestion: y }) => {
|
|
|
77
73
|
...I
|
|
78
74
|
};
|
|
79
75
|
}
|
|
80
|
-
return
|
|
76
|
+
return h === "CURRENT" && i.item_number === 0 ? n == null || n({
|
|
81
77
|
...e,
|
|
82
78
|
[t]: o
|
|
83
79
|
}) : Q == null || Q({
|
|
@@ -92,24 +88,24 @@ const B = (b, { getTimeSpentOnQuestion: y }) => {
|
|
|
92
88
|
});
|
|
93
89
|
},
|
|
94
90
|
[
|
|
95
|
-
|
|
96
|
-
|
|
91
|
+
N,
|
|
92
|
+
h,
|
|
97
93
|
n,
|
|
98
94
|
Q,
|
|
99
|
-
|
|
95
|
+
g,
|
|
100
96
|
s,
|
|
101
97
|
m
|
|
102
98
|
]
|
|
103
|
-
),
|
|
99
|
+
), U = O(
|
|
104
100
|
(t) => {
|
|
105
101
|
m((r) => {
|
|
106
|
-
const
|
|
102
|
+
const c = s.filter(
|
|
107
103
|
(e) => {
|
|
108
|
-
var
|
|
109
|
-
return t.startsWith("advanced-") ? (
|
|
104
|
+
var d;
|
|
105
|
+
return t.startsWith("advanced-") ? (d = e.item_type) == null ? void 0 : d.startsWith("advanced-") : e.item_type === t;
|
|
110
106
|
}
|
|
111
107
|
), a = {};
|
|
112
|
-
return
|
|
108
|
+
return c.length > 0 ? (c.forEach((e) => {
|
|
113
109
|
a[e.response_id] = {
|
|
114
110
|
...u(s, e.response_id),
|
|
115
111
|
...r[e.response_id],
|
|
@@ -122,16 +118,16 @@ const B = (b, { getTimeSpentOnQuestion: y }) => {
|
|
|
122
118
|
});
|
|
123
119
|
},
|
|
124
120
|
[n, s, m]
|
|
125
|
-
),
|
|
121
|
+
), x = O(
|
|
126
122
|
(t) => {
|
|
127
123
|
m((r) => {
|
|
128
|
-
const
|
|
129
|
-
(
|
|
124
|
+
const c = s.filter(
|
|
125
|
+
(d) => {
|
|
130
126
|
var i;
|
|
131
|
-
return t.startsWith("advanced-") ? (i =
|
|
127
|
+
return t.startsWith("advanced-") ? (i = d.item_type) == null ? void 0 : i.startsWith("advanced-") : d.item_type === t;
|
|
132
128
|
}
|
|
133
129
|
), a = {}, e = [];
|
|
134
|
-
return
|
|
130
|
+
return c.length > 0 ? (c.forEach((i) => {
|
|
135
131
|
const o = r[i.response_id];
|
|
136
132
|
o != null && o.validatedByTeacher ? e.push(i) : a[i.response_id] = {
|
|
137
133
|
...u(s, i.response_id),
|
|
@@ -139,7 +135,7 @@ const B = (b, { getTimeSpentOnQuestion: y }) => {
|
|
|
139
135
|
assignStatus: "skipped"
|
|
140
136
|
};
|
|
141
137
|
}), e.some(
|
|
142
|
-
({ instructor_stimulus: i }) => !(i === "SystemIntro" ||
|
|
138
|
+
({ instructor_stimulus: i }) => !(i === "SystemIntro" || H(i))
|
|
143
139
|
) || e.forEach((i) => {
|
|
144
140
|
a[i.response_id] = {
|
|
145
141
|
...u(s, i.response_id),
|
|
@@ -153,15 +149,15 @@ const B = (b, { getTimeSpentOnQuestion: y }) => {
|
|
|
153
149
|
});
|
|
154
150
|
},
|
|
155
151
|
[n, s, m]
|
|
156
|
-
),
|
|
157
|
-
(t, r,
|
|
152
|
+
), L = O(
|
|
153
|
+
(t, r, c) => {
|
|
158
154
|
const a = r === "SIMULATION" ? "simState" : void 0;
|
|
159
155
|
a && m((e) => {
|
|
160
156
|
if (!s.find((o) => o.response_id === t)) return e;
|
|
161
157
|
const i = {
|
|
162
158
|
...u(s, t),
|
|
163
159
|
...e[t],
|
|
164
|
-
[a]:
|
|
160
|
+
[a]: c
|
|
165
161
|
};
|
|
166
162
|
return {
|
|
167
163
|
...e,
|
|
@@ -171,18 +167,18 @@ const B = (b, { getTimeSpentOnQuestion: y }) => {
|
|
|
171
167
|
},
|
|
172
168
|
[s, m]
|
|
173
169
|
);
|
|
174
|
-
|
|
170
|
+
C(
|
|
175
171
|
b,
|
|
176
172
|
() => ({
|
|
177
|
-
validateQuestion:
|
|
178
|
-
assignOptionalItems:
|
|
179
|
-
skipOptionalItems:
|
|
180
|
-
updateMediaState:
|
|
173
|
+
validateQuestion: y,
|
|
174
|
+
assignOptionalItems: U,
|
|
175
|
+
skipOptionalItems: x,
|
|
176
|
+
updateMediaState: L
|
|
181
177
|
}),
|
|
182
|
-
[
|
|
178
|
+
[U, x, L, y]
|
|
183
179
|
);
|
|
184
180
|
};
|
|
185
181
|
export {
|
|
186
|
-
|
|
182
|
+
X as default
|
|
187
183
|
};
|
|
188
184
|
//# sourceMappingURL=use-create-imperative-handle.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-create-imperative-handle.js","sources":["../../../../../src/features/worksheet/worksheet/hooks/use-create-imperative-handle.ts"],"sourcesContent":["import { useCallback, useImperativeHandle, type ForwardedRef } from 'react';\n\nimport { useAudioPlayer } from '../../../hooks/use-audio-player/use-audio-player';\nimport { useAutoPlayPermission } from '../../../hooks/use-auto-play-permission/use-auto-play-permission';\nimport { TEACHER_VALIDATION_AUDIO_LIST } from '../constants';\nimport { getQuestionMetadata, isConceptIntroWidget } from '../worksheet-helpers';\nimport {\n QUESTION_TAGS,\n QUESTIONS_RATING,\n type IWorksheetQuestion,\n type IWorksheetRef,\n type IWorksheetResponse,\n} from '../worksheet-types';\nimport { useWorksheetStore } from './use-worksheet-store';\n\ninterface IUseCreateImperativeHandle {\n (\n ref: ForwardedRef<IWorksheetRef>,\n options: {\n getTimeSpentOnQuestion: (questionId: string) => number;\n },\n ): void;\n}\n\nconst useCreateImperativeHandle: IUseCreateImperativeHandle = (ref, { getTimeSpentOnQuestion }) => {\n const { onResponseChange, onBulkResponsesChange, behavior, questions, setResponses } =\n useWorksheetStore(store => ({\n onResponseChange: store.onResponseChange,\n onBulkResponsesChange: store.onBulkResponsesChange,\n behavior: store.behavior,\n questions: store.questions,\n setResponses: store.setResponses,\n }));\n const { navigationMode } = behavior;\n const { canAutoPlayAudio } = useAutoPlayPermission();\n\n // Convert array to object config for new useAudioPlayer\n const audioConfig = TEACHER_VALIDATION_AUDIO_LIST.reduce(\n (acc, { name, url }) => {\n acc[name] = url;\n\n return acc;\n },\n {} as Record<string, string>,\n );\n\n const audioManager = useAudioPlayer(audioConfig, canAutoPlayAudio);\n const validateQuestion = useCallback<IWorksheetRef['validateQuestion']>(\n (questionId, rating, skipRemainingQuestions) => {\n audioManager.play('VALIDATE');\n const timeSpentOnQuestion = getTimeSpentOnQuestion(questionId);\n\n setResponses(prevResponses => {\n const questionIndex = questions.findIndex(q => q.response_id === questionId);\n const question = questions[questionIndex]!;\n\n const newResponse = {\n ...getQuestionMetadata(questions, questionId),\n ...prevResponses[questionId],\n validatedByTeacher: true,\n rating: rating ? QUESTIONS_RATING[rating] : undefined,\n timeSpent: timeSpentOnQuestion,\n };\n\n if (navigationMode === 'ADAPTIVE') {\n if (prevResponses[questionId]?.validatedByTeacher) {\n return prevResponses;\n }\n\n const topicName = question.item_tags_map[QUESTION_TAGS.TRIAL_TOPIC];\n const questionCode = question.item_tags_map[QUESTION_TAGS.QUESTION_CODE];\n const nextQuestionCode =\n questionCode && questionCode.length < 3 ? `${questionCode}${rating}` : 'Q';\n const nextQuestionIndex = questions.findIndex((q, qIndex) => {\n if (qIndex <= questionIndex) return false;\n\n if (nextQuestionCode !== 'Q') {\n return (\n q.item_tags_map[QUESTION_TAGS.TRIAL_TOPIC] === topicName &&\n q.item_tags_map[QUESTION_TAGS.QUESTION_CODE] === nextQuestionCode\n );\n }\n\n return q.item_tags_map[QUESTION_TAGS.TRIAL_TOPIC] !== topicName;\n });\n\n const newResponses = {\n [questionId]: newResponse,\n ...questions.reduce(\n (acc, q, qIndex) => {\n if (qIndex <= questionIndex) return acc;\n\n if (nextQuestionIndex > -1 && qIndex >= nextQuestionIndex) return acc;\n\n acc[q.response_id] = {\n ...getQuestionMetadata(questions, q.response_id),\n ...prevResponses[q.response_id],\n assignStatus: 'skipped',\n };\n\n return acc;\n },\n {} as Record<string, IWorksheetResponse>,\n ),\n };\n const nextQuestionResponseId = questions[nextQuestionIndex]?.response_id;\n\n if (nextQuestionResponseId) {\n onBulkResponsesChange?.({\n ...newResponses,\n [nextQuestionResponseId]: {\n ...prevResponses[nextQuestionResponseId],\n ...getQuestionMetadata(questions, nextQuestionResponseId),\n assignStatus: undefined,\n },\n });\n } else {\n onBulkResponsesChange?.(newResponses);\n }\n\n return {\n ...prevResponses,\n ...newResponses,\n };\n }\n\n if (skipRemainingQuestions) {\n const { item_reference } = question;\n const newResponses = {\n [questionId]: newResponse,\n ...questions.reduce(\n (acc, q) => {\n if (\n q.response_id !== question.response_id &&\n q.item_reference === item_reference &&\n !prevResponses[q.response_id]?.validatedByTeacher\n ) {\n acc[q.response_id] = {\n ...getQuestionMetadata(questions, q.response_id),\n ...prevResponses[q.response_id],\n assignStatus: 'skipped',\n };\n }\n\n return acc;\n },\n {} as Record<string, IWorksheetResponse>,\n ),\n };\n\n onBulkResponsesChange?.({\n ...prevResponses,\n ...newResponses,\n });\n\n return {\n ...prevResponses,\n ...newResponses,\n };\n }\n\n if (navigationMode === 'CURRENT' && question.item_number === 0) {\n onBulkResponsesChange?.({\n ...prevResponses,\n [questionId]: newResponse,\n });\n } else {\n onResponseChange?.({\n responseId: questionId,\n response: newResponse,\n question,\n isNewAttempt: false,\n });\n }\n\n return {\n ...prevResponses,\n [questionId]: newResponse,\n };\n });\n },\n [\n getTimeSpentOnQuestion,\n navigationMode,\n onBulkResponsesChange,\n onResponseChange,\n audioManager,\n questions,\n setResponses,\n ],\n );\n\n const assignOptionalItems = useCallback<IWorksheetRef['assignOptionalItems']>(\n itemType => {\n setResponses(prevResponses => {\n const optionalQuestions = questions.filter(q =>\n itemType.startsWith('advanced-')\n ? q.item_type?.startsWith('advanced-')\n : q.item_type === itemType,\n );\n const assignedResponses: Record<string, IWorksheetResponse> = {};\n\n if (optionalQuestions.length > 0) {\n optionalQuestions.forEach(question => {\n assignedResponses[question.response_id] = {\n ...getQuestionMetadata(questions, question.response_id),\n ...prevResponses[question.response_id],\n assignStatus: 'assigned',\n };\n });\n\n onBulkResponsesChange?.(assignedResponses);\n\n return {\n ...prevResponses,\n ...assignedResponses,\n };\n }\n\n return prevResponses;\n });\n },\n [onBulkResponsesChange, questions, setResponses],\n );\n\n const skipOptionalItems = useCallback<IWorksheetRef['skipOptionalItems']>(\n itemType => {\n setResponses(prevResponses => {\n const optionalQuestions = questions.filter(q =>\n itemType.startsWith('advanced-')\n ? q.item_type?.startsWith('advanced-')\n : q.item_type === itemType,\n );\n const skippedResponses: Record<string, IWorksheetResponse> = {};\n const unskippedQuestions: IWorksheetQuestion[] = [];\n\n if (optionalQuestions.length > 0) {\n optionalQuestions.forEach(question => {\n const prevResponse = prevResponses[question.response_id];\n\n if (!prevResponse?.validatedByTeacher) {\n skippedResponses[question.response_id] = {\n ...getQuestionMetadata(questions, question.response_id),\n ...prevResponse,\n assignStatus: 'skipped',\n };\n } else {\n unskippedQuestions.push(question);\n }\n });\n\n const nonIntroUnskippedQuestionsPresent = unskippedQuestions.some(\n ({ instructor_stimulus }) =>\n !(instructor_stimulus === 'SystemIntro' || isConceptIntroWidget(instructor_stimulus)),\n );\n\n if (!nonIntroUnskippedQuestionsPresent) {\n unskippedQuestions.forEach(question => {\n skippedResponses[question.response_id] = {\n ...getQuestionMetadata(questions, question.response_id),\n ...prevResponses[question.response_id],\n assignStatus: 'skipped',\n };\n });\n }\n\n onBulkResponsesChange?.(skippedResponses);\n\n return {\n ...prevResponses,\n ...skippedResponses,\n };\n }\n\n return prevResponses;\n });\n },\n [onBulkResponsesChange, questions, setResponses],\n );\n\n const updateMediaState = useCallback<IWorksheetRef['updateMediaState']>(\n (responseId, mediaType, mediaState) => {\n const key = mediaType === 'SIMULATION' ? 'simState' : undefined;\n\n if (!key) return;\n\n setResponses(prevResponses => {\n const question = questions.find(q => q.response_id === responseId);\n\n if (!question) return prevResponses;\n\n const newResponse = {\n ...getQuestionMetadata(questions, responseId),\n ...prevResponses[responseId],\n [key]: mediaState,\n };\n\n return {\n ...prevResponses,\n [responseId]: newResponse,\n };\n });\n },\n [questions, setResponses],\n );\n\n useImperativeHandle(\n ref,\n () => ({\n validateQuestion,\n assignOptionalItems,\n skipOptionalItems,\n updateMediaState,\n }),\n [assignOptionalItems, skipOptionalItems, updateMediaState, validateQuestion],\n );\n};\n\nexport default useCreateImperativeHandle;\n"],"names":["useCreateImperativeHandle","ref","getTimeSpentOnQuestion","onResponseChange","onBulkResponsesChange","behavior","questions","setResponses","useWorksheetStore","store","navigationMode","canAutoPlayAudio","useAutoPlayPermission","audioConfig","TEACHER_VALIDATION_AUDIO_LIST","acc","name","url","audioManager","useAudioPlayer","validateQuestion","useCallback","questionId","rating","skipRemainingQuestions","timeSpentOnQuestion","prevResponses","questionIndex","q","question","newResponse","getQuestionMetadata","QUESTIONS_RATING","_a","topicName","QUESTION_TAGS","questionCode","nextQuestionCode","nextQuestionIndex","qIndex","newResponses","nextQuestionResponseId","_b","item_reference","assignOptionalItems","itemType","optionalQuestions","assignedResponses","skipOptionalItems","skippedResponses","unskippedQuestions","prevResponse","instructor_stimulus","isConceptIntroWidget","updateMediaState","responseId","mediaType","mediaState","key","useImperativeHandle"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"use-create-imperative-handle.js","sources":["../../../../../src/features/worksheet/worksheet/hooks/use-create-imperative-handle.ts"],"sourcesContent":["import { useCallback, useImperativeHandle, type ForwardedRef } from 'react';\n\nimport useAudioPlayer from '../../../hooks/use-audio-player';\nimport { TEACHER_VALIDATION_AUDIO_LIST } from '../constants';\nimport { getQuestionMetadata, isConceptIntroWidget } from '../worksheet-helpers';\nimport {\n QUESTION_TAGS,\n QUESTIONS_RATING,\n type IWorksheetQuestion,\n type IWorksheetRef,\n type IWorksheetResponse,\n} from '../worksheet-types';\nimport { useWorksheetStore } from './use-worksheet-store';\n\ninterface IUseCreateImperativeHandle {\n (\n ref: ForwardedRef<IWorksheetRef>,\n options: {\n getTimeSpentOnQuestion: (questionId: string) => number;\n },\n ): void;\n}\n\nconst useCreateImperativeHandle: IUseCreateImperativeHandle = (ref, { getTimeSpentOnQuestion }) => {\n const { onResponseChange, onBulkResponsesChange, behavior, questions, setResponses } =\n useWorksheetStore(store => ({\n onResponseChange: store.onResponseChange,\n onBulkResponsesChange: store.onBulkResponsesChange,\n behavior: store.behavior,\n questions: store.questions,\n setResponses: store.setResponses,\n }));\n const { navigationMode } = behavior;\n const playNotifSound = useAudioPlayer(TEACHER_VALIDATION_AUDIO_LIST);\n const validateQuestion = useCallback<IWorksheetRef['validateQuestion']>(\n (questionId, rating, skipRemainingQuestions) => {\n playNotifSound('VALIDATE');\n const timeSpentOnQuestion = getTimeSpentOnQuestion(questionId);\n\n setResponses(prevResponses => {\n const questionIndex = questions.findIndex(q => q.response_id === questionId);\n const question = questions[questionIndex]!;\n\n const newResponse = {\n ...getQuestionMetadata(questions, questionId),\n ...prevResponses[questionId],\n validatedByTeacher: true,\n rating: rating ? QUESTIONS_RATING[rating] : undefined,\n timeSpent: timeSpentOnQuestion,\n };\n\n if (navigationMode === 'ADAPTIVE') {\n if (prevResponses[questionId]?.validatedByTeacher) {\n return prevResponses;\n }\n\n const topicName = question.item_tags_map[QUESTION_TAGS.TRIAL_TOPIC];\n const questionCode = question.item_tags_map[QUESTION_TAGS.QUESTION_CODE];\n const nextQuestionCode =\n questionCode && questionCode.length < 3 ? `${questionCode}${rating}` : 'Q';\n const nextQuestionIndex = questions.findIndex((q, qIndex) => {\n if (qIndex <= questionIndex) return false;\n\n if (nextQuestionCode !== 'Q') {\n return (\n q.item_tags_map[QUESTION_TAGS.TRIAL_TOPIC] === topicName &&\n q.item_tags_map[QUESTION_TAGS.QUESTION_CODE] === nextQuestionCode\n );\n }\n\n return q.item_tags_map[QUESTION_TAGS.TRIAL_TOPIC] !== topicName;\n });\n\n const newResponses = {\n [questionId]: newResponse,\n ...questions.reduce(\n (acc, q, qIndex) => {\n if (qIndex <= questionIndex) return acc;\n\n if (nextQuestionIndex > -1 && qIndex >= nextQuestionIndex) return acc;\n\n acc[q.response_id] = {\n ...getQuestionMetadata(questions, q.response_id),\n ...prevResponses[q.response_id],\n assignStatus: 'skipped',\n };\n\n return acc;\n },\n {} as Record<string, IWorksheetResponse>,\n ),\n };\n const nextQuestionResponseId = questions[nextQuestionIndex]?.response_id;\n\n if (nextQuestionResponseId) {\n onBulkResponsesChange?.({\n ...newResponses,\n [nextQuestionResponseId]: {\n ...prevResponses[nextQuestionResponseId],\n ...getQuestionMetadata(questions, nextQuestionResponseId),\n assignStatus: undefined,\n },\n });\n } else {\n onBulkResponsesChange?.(newResponses);\n }\n\n return {\n ...prevResponses,\n ...newResponses,\n };\n }\n\n if (skipRemainingQuestions) {\n const { item_reference } = question;\n const newResponses = {\n [questionId]: newResponse,\n ...questions.reduce(\n (acc, q) => {\n if (\n q.response_id !== question.response_id &&\n q.item_reference === item_reference &&\n !prevResponses[q.response_id]?.validatedByTeacher\n ) {\n acc[q.response_id] = {\n ...getQuestionMetadata(questions, q.response_id),\n ...prevResponses[q.response_id],\n assignStatus: 'skipped',\n };\n }\n\n return acc;\n },\n {} as Record<string, IWorksheetResponse>,\n ),\n };\n\n onBulkResponsesChange?.({\n ...prevResponses,\n ...newResponses,\n });\n\n return {\n ...prevResponses,\n ...newResponses,\n };\n }\n\n if (navigationMode === 'CURRENT' && question.item_number === 0) {\n onBulkResponsesChange?.({\n ...prevResponses,\n [questionId]: newResponse,\n });\n } else {\n onResponseChange?.({\n responseId: questionId,\n response: newResponse,\n question,\n isNewAttempt: false,\n });\n }\n\n return {\n ...prevResponses,\n [questionId]: newResponse,\n };\n });\n },\n [\n getTimeSpentOnQuestion,\n navigationMode,\n onBulkResponsesChange,\n onResponseChange,\n playNotifSound,\n questions,\n setResponses,\n ],\n );\n\n const assignOptionalItems = useCallback<IWorksheetRef['assignOptionalItems']>(\n itemType => {\n setResponses(prevResponses => {\n const optionalQuestions = questions.filter(q =>\n itemType.startsWith('advanced-')\n ? q.item_type?.startsWith('advanced-')\n : q.item_type === itemType,\n );\n const assignedResponses: Record<string, IWorksheetResponse> = {};\n\n if (optionalQuestions.length > 0) {\n optionalQuestions.forEach(question => {\n assignedResponses[question.response_id] = {\n ...getQuestionMetadata(questions, question.response_id),\n ...prevResponses[question.response_id],\n assignStatus: 'assigned',\n };\n });\n\n onBulkResponsesChange?.(assignedResponses);\n\n return {\n ...prevResponses,\n ...assignedResponses,\n };\n }\n\n return prevResponses;\n });\n },\n [onBulkResponsesChange, questions, setResponses],\n );\n\n const skipOptionalItems = useCallback<IWorksheetRef['skipOptionalItems']>(\n itemType => {\n setResponses(prevResponses => {\n const optionalQuestions = questions.filter(q =>\n itemType.startsWith('advanced-')\n ? q.item_type?.startsWith('advanced-')\n : q.item_type === itemType,\n );\n const skippedResponses: Record<string, IWorksheetResponse> = {};\n const unskippedQuestions: IWorksheetQuestion[] = [];\n\n if (optionalQuestions.length > 0) {\n optionalQuestions.forEach(question => {\n const prevResponse = prevResponses[question.response_id];\n\n if (!prevResponse?.validatedByTeacher) {\n skippedResponses[question.response_id] = {\n ...getQuestionMetadata(questions, question.response_id),\n ...prevResponse,\n assignStatus: 'skipped',\n };\n } else {\n unskippedQuestions.push(question);\n }\n });\n\n const nonIntroUnskippedQuestionsPresent = unskippedQuestions.some(\n ({ instructor_stimulus }) =>\n !(instructor_stimulus === 'SystemIntro' || isConceptIntroWidget(instructor_stimulus)),\n );\n\n if (!nonIntroUnskippedQuestionsPresent) {\n unskippedQuestions.forEach(question => {\n skippedResponses[question.response_id] = {\n ...getQuestionMetadata(questions, question.response_id),\n ...prevResponses[question.response_id],\n assignStatus: 'skipped',\n };\n });\n }\n\n onBulkResponsesChange?.(skippedResponses);\n\n return {\n ...prevResponses,\n ...skippedResponses,\n };\n }\n\n return prevResponses;\n });\n },\n [onBulkResponsesChange, questions, setResponses],\n );\n\n const updateMediaState = useCallback<IWorksheetRef['updateMediaState']>(\n (responseId, mediaType, mediaState) => {\n const key = mediaType === 'SIMULATION' ? 'simState' : undefined;\n\n if (!key) return;\n\n setResponses(prevResponses => {\n const question = questions.find(q => q.response_id === responseId);\n\n if (!question) return prevResponses;\n\n const newResponse = {\n ...getQuestionMetadata(questions, responseId),\n ...prevResponses[responseId],\n [key]: mediaState,\n };\n\n return {\n ...prevResponses,\n [responseId]: newResponse,\n };\n });\n },\n [questions, setResponses],\n );\n\n useImperativeHandle(\n ref,\n () => ({\n validateQuestion,\n assignOptionalItems,\n skipOptionalItems,\n updateMediaState,\n }),\n [assignOptionalItems, skipOptionalItems, updateMediaState, validateQuestion],\n );\n};\n\nexport default useCreateImperativeHandle;\n"],"names":["useCreateImperativeHandle","ref","getTimeSpentOnQuestion","onResponseChange","onBulkResponsesChange","behavior","questions","setResponses","useWorksheetStore","store","navigationMode","playNotifSound","useAudioPlayer","TEACHER_VALIDATION_AUDIO_LIST","validateQuestion","useCallback","questionId","rating","skipRemainingQuestions","timeSpentOnQuestion","prevResponses","questionIndex","q","question","newResponse","getQuestionMetadata","QUESTIONS_RATING","_a","topicName","QUESTION_TAGS","questionCode","nextQuestionCode","nextQuestionIndex","qIndex","newResponses","acc","nextQuestionResponseId","_b","item_reference","assignOptionalItems","itemType","optionalQuestions","assignedResponses","skipOptionalItems","skippedResponses","unskippedQuestions","prevResponse","instructor_stimulus","isConceptIntroWidget","updateMediaState","responseId","mediaType","mediaState","key","useImperativeHandle"],"mappings":"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"}
|
package/dist/features/worksheet/worksheet/worksheet-questions-controller/use-handler-callbacks.js
CHANGED
|
@@ -1,28 +1,27 @@
|
|
|
1
1
|
import { useCallback as a } from "react";
|
|
2
|
-
import { useErrorBoundary as
|
|
3
|
-
import
|
|
4
|
-
import
|
|
5
|
-
import
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
|
|
9
|
-
const Se = (v) => {
|
|
2
|
+
import { useErrorBoundary as J } from "react-error-boundary";
|
|
3
|
+
import ee from "../../../hooks/use-audio-player.js";
|
|
4
|
+
import te from "../../constants/events.js";
|
|
5
|
+
import { SYSTEM_VALIDATION_AUDIO_LIST as ne } from "../constants.js";
|
|
6
|
+
import { useWorksheetStore as se } from "../hooks/use-worksheet-store.js";
|
|
7
|
+
import { isOkayTypeQuestion as Q, getQuestionMetadata as S, checkIsClozeFormulaResponseInvalid as oe } from "../worksheet-helpers.js";
|
|
8
|
+
const me = (v) => {
|
|
10
9
|
const {
|
|
11
10
|
behavior: V,
|
|
12
11
|
layout: L,
|
|
13
12
|
questions: s,
|
|
14
|
-
setResponses:
|
|
13
|
+
setResponses: u,
|
|
15
14
|
questionIndex: p,
|
|
16
|
-
updateResponse:
|
|
17
|
-
onResponseChange:
|
|
15
|
+
updateResponse: y,
|
|
16
|
+
onResponseChange: o,
|
|
18
17
|
showSummary: B,
|
|
19
18
|
changeQuestion: m,
|
|
20
|
-
setBlocker:
|
|
19
|
+
setBlocker: r,
|
|
21
20
|
onTeacherValidation: h,
|
|
22
|
-
learnosity:
|
|
21
|
+
learnosity: l,
|
|
23
22
|
loggerRef: E,
|
|
24
|
-
onHelp:
|
|
25
|
-
} =
|
|
23
|
+
onHelp: k
|
|
24
|
+
} = se((e) => ({
|
|
26
25
|
behavior: e.behavior,
|
|
27
26
|
layout: e.layout,
|
|
28
27
|
questions: e.questions,
|
|
@@ -37,159 +36,156 @@ const Se = (v) => {
|
|
|
37
36
|
learnosity: e.learnosity,
|
|
38
37
|
loggerRef: e.loggerRef,
|
|
39
38
|
onHelp: e.onHelp
|
|
40
|
-
})), { question:
|
|
41
|
-
|
|
42
|
-
{}
|
|
43
|
-
), C = ne(z, D), { showBoundary: R } = te(), T = a(() => {
|
|
44
|
-
const e = r.question(t);
|
|
39
|
+
})), { question: C, getTimeSpentOnQuestion: I, setSkipped: q } = v, { questionsScrollable: M } = L, { response_id: t, item_type: U, question_number: b, item_number: g, total_questions: x } = C, A = U === "exit-ticket", { validation: w, teacherValidationEnabled: D } = V, _ = ee(ne), { showBoundary: N } = J(), R = a(() => {
|
|
40
|
+
const e = l.question(t);
|
|
45
41
|
e && w && !Q(e.getQuestion()) && e.getScore((n) => {
|
|
46
|
-
const { max_score:
|
|
47
|
-
|
|
42
|
+
const { max_score: i, score: c } = n || {};
|
|
43
|
+
i && _(i === c ? "CORRECT" : "INCORRECT");
|
|
48
44
|
});
|
|
49
|
-
}, [
|
|
45
|
+
}, [l, _, t, w]), T = a(
|
|
50
46
|
(e, n) => {
|
|
51
|
-
|
|
52
|
-
const
|
|
47
|
+
u((i) => {
|
|
48
|
+
const c = {
|
|
53
49
|
...S(s, e),
|
|
54
|
-
...
|
|
50
|
+
...i[e],
|
|
55
51
|
validatedByTeacher: !0,
|
|
56
52
|
rating: n
|
|
57
53
|
};
|
|
58
|
-
return
|
|
54
|
+
return o == null || o({
|
|
59
55
|
responseId: e,
|
|
60
|
-
response:
|
|
56
|
+
response: c,
|
|
61
57
|
question: s.find((O) => O.response_id === e),
|
|
62
58
|
isNewAttempt: !1
|
|
63
59
|
}), {
|
|
64
|
-
...
|
|
65
|
-
[e]:
|
|
60
|
+
...i,
|
|
61
|
+
[e]: c
|
|
66
62
|
};
|
|
67
63
|
});
|
|
68
64
|
},
|
|
69
|
-
[
|
|
70
|
-
),
|
|
71
|
-
|
|
65
|
+
[o, s, u]
|
|
66
|
+
), z = a(() => {
|
|
67
|
+
k && C && k({
|
|
72
68
|
questionId: t,
|
|
73
|
-
questionNumber: `${
|
|
69
|
+
questionNumber: `${g + 1}${x > 1 ? String.fromCharCode(97 + b) : ""}`
|
|
74
70
|
});
|
|
75
|
-
}, [
|
|
76
|
-
E.current(
|
|
77
|
-
var
|
|
71
|
+
}, [g, k, C, b, t, x]), F = a(() => {
|
|
72
|
+
E.current(te.WORKSHEET_V3_HINT_SEEN), u((e) => {
|
|
73
|
+
var i;
|
|
78
74
|
const n = {
|
|
79
75
|
...S(s, t),
|
|
80
76
|
...e[t],
|
|
81
|
-
hintsUsed: (((
|
|
77
|
+
hintsUsed: (((i = e[t]) == null ? void 0 : i.hintsUsed) ?? 0) + 1
|
|
82
78
|
};
|
|
83
|
-
return
|
|
79
|
+
return o == null || o({
|
|
84
80
|
responseId: t,
|
|
85
81
|
response: n,
|
|
86
|
-
question: s.find((
|
|
82
|
+
question: s.find((c) => c.response_id === t),
|
|
87
83
|
isNewAttempt: !1
|
|
88
84
|
}), {
|
|
89
85
|
...e,
|
|
90
86
|
[t]: n
|
|
91
87
|
};
|
|
92
88
|
});
|
|
93
|
-
}, [E,
|
|
89
|
+
}, [E, o, s, t, u]), P = a(() => {
|
|
94
90
|
var n;
|
|
95
91
|
const e = (n = s[p - 1]) == null ? void 0 : n.response_id;
|
|
96
92
|
e && m(e);
|
|
97
|
-
}, [m, p, s]),
|
|
93
|
+
}, [m, p, s]), W = a(() => {
|
|
98
94
|
var n;
|
|
99
95
|
const e = (n = s[p + 1]) == null ? void 0 : n.response_id;
|
|
100
96
|
e ? m(e) : B();
|
|
101
|
-
}, [m, p, s, B]),
|
|
102
|
-
|
|
97
|
+
}, [m, p, s, B]), X = a(() => {
|
|
98
|
+
u((e) => {
|
|
103
99
|
const n = {
|
|
104
100
|
...S(s, t),
|
|
105
101
|
...e[t],
|
|
106
102
|
skipped: !0
|
|
107
103
|
};
|
|
108
|
-
return
|
|
104
|
+
return o == null || o({
|
|
109
105
|
responseId: t,
|
|
110
106
|
response: n,
|
|
111
|
-
question: s.find((
|
|
107
|
+
question: s.find((i) => i.response_id === t),
|
|
112
108
|
isNewAttempt: !1
|
|
113
109
|
}), {
|
|
114
110
|
...e,
|
|
115
111
|
[t]: n
|
|
116
112
|
};
|
|
117
113
|
}), q(!0);
|
|
118
|
-
}, [
|
|
114
|
+
}, [o, s, t, u, q]), d = a(
|
|
119
115
|
(e) => {
|
|
120
|
-
const n =
|
|
116
|
+
const n = l.question(t);
|
|
121
117
|
if (n) {
|
|
122
|
-
const
|
|
123
|
-
(
|
|
124
|
-
|
|
118
|
+
const i = n.getQuestion(), c = n.getResponse();
|
|
119
|
+
(i.type === "clozeformula" && c && (c == null ? void 0 : c.value) ? oe(c) : !1) && N(new Error("CLOZE_FORMULA_RESPONSE_EXCEEDS_MAX_LENGTH")), n.getScore((f) => {
|
|
120
|
+
y({
|
|
125
121
|
responseId: t,
|
|
126
|
-
response:
|
|
127
|
-
score: Q(
|
|
122
|
+
response: c,
|
|
123
|
+
score: Q(i) || !f ? {
|
|
128
124
|
max_score: 0,
|
|
129
125
|
score: 0,
|
|
130
|
-
unscored: !
|
|
126
|
+
unscored: !f
|
|
131
127
|
// score will be null for unscored questions
|
|
132
|
-
} : { ...
|
|
128
|
+
} : { ...f, score: f.score ?? 0 },
|
|
133
129
|
answerChecked: e,
|
|
134
130
|
timeSpent: I(t)
|
|
135
131
|
});
|
|
136
132
|
});
|
|
137
133
|
}
|
|
138
134
|
},
|
|
139
|
-
[I,
|
|
140
|
-
),
|
|
141
|
-
const e =
|
|
135
|
+
[I, l, t, N, y]
|
|
136
|
+
), $ = a(() => {
|
|
137
|
+
const e = l.question(t);
|
|
142
138
|
e && (e.enable(), e.resetValidationUI(), d());
|
|
143
|
-
}, [d,
|
|
144
|
-
|
|
145
|
-
}, [d,
|
|
146
|
-
const e =
|
|
139
|
+
}, [d, l, t]), H = a(() => {
|
|
140
|
+
R(), d(!0);
|
|
141
|
+
}, [d, R]), G = a(() => {
|
|
142
|
+
const e = l.question(t);
|
|
147
143
|
e && (e.disable(), e.validate(
|
|
148
144
|
{
|
|
149
145
|
feedbackAttempts: !0
|
|
150
146
|
},
|
|
151
147
|
H
|
|
152
148
|
));
|
|
153
|
-
}, [H,
|
|
154
|
-
|
|
155
|
-
}, [
|
|
156
|
-
|
|
157
|
-
}, [t,
|
|
158
|
-
|
|
149
|
+
}, [H, l, t]), K = a(() => {
|
|
150
|
+
A ? r("exit-ticket-review") : h == null || h(t);
|
|
151
|
+
}, [A, h, t, r]), Y = a(() => {
|
|
152
|
+
T(t);
|
|
153
|
+
}, [t, T]), Z = a(() => {
|
|
154
|
+
u((e) => {
|
|
159
155
|
const n = {
|
|
160
156
|
...S(s, t),
|
|
161
157
|
...e[t],
|
|
162
158
|
submittedByStudent: !0
|
|
163
159
|
};
|
|
164
|
-
return
|
|
160
|
+
return o == null || o({
|
|
165
161
|
responseId: t,
|
|
166
162
|
response: n,
|
|
167
|
-
question: s.find((
|
|
163
|
+
question: s.find((i) => i.response_id === t),
|
|
168
164
|
isNewAttempt: !1
|
|
169
165
|
}), {
|
|
170
166
|
...e,
|
|
171
167
|
[t]: n
|
|
172
168
|
};
|
|
173
|
-
}),
|
|
174
|
-
}, [
|
|
175
|
-
|
|
176
|
-
}, [
|
|
169
|
+
}), r("exit-ticket-student-submission");
|
|
170
|
+
}, [o, s, t, r, u]), j = a(() => {
|
|
171
|
+
r("optional-items-skip");
|
|
172
|
+
}, [r]);
|
|
177
173
|
return {
|
|
178
174
|
handleResponseChange: d,
|
|
179
|
-
handleHelpButtonClick:
|
|
180
|
-
handleHintButtonClick:
|
|
181
|
-
handleBackButtonClick: !M && !
|
|
182
|
-
handleNextButtonClick:
|
|
183
|
-
handleRetryButtonClick:
|
|
184
|
-
handleCheckButtonClick:
|
|
185
|
-
handleValidateButtonClick:
|
|
186
|
-
handleStartButtonClick:
|
|
187
|
-
handleReadyButtonClick:
|
|
188
|
-
handleSkipSectionButtonClick:
|
|
189
|
-
handleSkipButtonClick:
|
|
175
|
+
handleHelpButtonClick: k ? z : void 0,
|
|
176
|
+
handleHintButtonClick: F,
|
|
177
|
+
handleBackButtonClick: !M && !D ? P : void 0,
|
|
178
|
+
handleNextButtonClick: W,
|
|
179
|
+
handleRetryButtonClick: $,
|
|
180
|
+
handleCheckButtonClick: G,
|
|
181
|
+
handleValidateButtonClick: K,
|
|
182
|
+
handleStartButtonClick: Y,
|
|
183
|
+
handleReadyButtonClick: Z,
|
|
184
|
+
handleSkipSectionButtonClick: j,
|
|
185
|
+
handleSkipButtonClick: X
|
|
190
186
|
};
|
|
191
187
|
};
|
|
192
188
|
export {
|
|
193
|
-
|
|
189
|
+
me as default
|
|
194
190
|
};
|
|
195
191
|
//# sourceMappingURL=use-handler-callbacks.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-handler-callbacks.js","sources":["../../../../../src/features/worksheet/worksheet/worksheet-questions-controller/use-handler-callbacks.ts"],"sourcesContent":["import { useCallback, type Dispatch, type SetStateAction } from 'react';\nimport { useErrorBoundary } from 'react-error-boundary';\n\nimport { useAudioPlayer } from '../../../hooks/use-audio-player/use-audio-player';\nimport { useAutoPlayPermission } from '../../../hooks/use-auto-play-permission/use-auto-play-permission';\nimport EVENTS from '../../constants/events';\nimport { SYSTEM_VALIDATION_AUDIO_LIST } from '../constants';\nimport { useWorksheetStore } from '../hooks/use-worksheet-store';\nimport {\n checkIsClozeFormulaResponseInvalid,\n getQuestionMetadata,\n isOkayTypeQuestion,\n} from '../worksheet-helpers';\nimport type { IWorksheetResponse } from '../worksheet-types';\nimport type { IWorksheetQuestionsControllerProps } from './worksheet-questions-controller-types';\n\ninterface IUseHandlerCallbacks {\n (\n options: Pick<IWorksheetQuestionsControllerProps, 'question' | 'getTimeSpentOnQuestion'> & {\n setSkipped: Dispatch<SetStateAction<boolean>>;\n },\n ): {\n handleResponseChange: () => void;\n handleHelpButtonClick?: () => void;\n handleHintButtonClick: () => void;\n handleBackButtonClick?: () => void;\n handleNextButtonClick: () => void;\n handleRetryButtonClick: () => void;\n handleCheckButtonClick: () => void;\n handleValidateButtonClick: () => void;\n handleStartButtonClick: () => void;\n handleReadyButtonClick: () => void;\n handleSkipSectionButtonClick: () => void;\n handleSkipButtonClick: () => void;\n };\n}\n\nconst useHandlerCallbacks: IUseHandlerCallbacks = options => {\n const {\n behavior,\n layout,\n questions,\n setResponses,\n questionIndex,\n updateResponse,\n onResponseChange,\n showSummary,\n changeQuestion,\n setBlocker,\n onTeacherValidation,\n learnosity,\n loggerRef,\n onHelp,\n } = useWorksheetStore(store => ({\n behavior: store.behavior,\n layout: store.layout,\n questions: store.questions,\n questionIndex: store.activeQuestionIndex,\n setResponses: store.setResponses,\n updateResponse: store.updateResponse,\n onResponseChange: store.onResponseChange,\n showSummary: store.showSummary,\n changeQuestion: store.changeQuestion,\n setBlocker: store.setBlocker,\n onTeacherValidation: store.onTeacherValidation,\n learnosity: store.learnosity,\n loggerRef: store.loggerRef,\n onHelp: store.onHelp,\n }));\n const { question, getTimeSpentOnQuestion, setSkipped } = options;\n const { questionsScrollable } = layout;\n const { response_id, item_type, question_number, item_number, total_questions } = question;\n const isExitTicket = item_type === 'exit-ticket';\n const { validation, teacherValidationEnabled } = behavior;\n const { canAutoPlayAudio } = useAutoPlayPermission();\n\n // Convert array to object config for new useAudioPlayer\n const audioConfig = SYSTEM_VALIDATION_AUDIO_LIST.reduce(\n (acc, { name, url }) => {\n acc[name] = url;\n\n return acc;\n },\n {} as Record<string, string>,\n );\n\n const audioManager = useAudioPlayer(audioConfig, canAutoPlayAudio);\n const { showBoundary } = useErrorBoundary();\n\n const playAudio = useCallback(() => {\n const questionInstance = learnosity.question(response_id);\n\n if (questionInstance && validation && !isOkayTypeQuestion(questionInstance.getQuestion())) {\n questionInstance.getScore(sc => {\n const { max_score: maxScore, score: currentScore } = sc || {};\n\n if (maxScore) {\n if (maxScore === currentScore) {\n audioManager.play('CORRECT');\n } else {\n audioManager.play('INCORRECT');\n }\n }\n });\n }\n }, [learnosity, audioManager, response_id, validation]);\n\n const validateQuestion = useCallback(\n (questionId: string, rating?: number) => {\n setResponses(prevResponses => {\n const newResponse = {\n ...getQuestionMetadata(questions, questionId),\n ...prevResponses[questionId],\n validatedByTeacher: true,\n rating,\n };\n\n onResponseChange?.({\n responseId: questionId,\n response: newResponse,\n question: questions.find(q => q.response_id === questionId)!,\n isNewAttempt: false,\n });\n\n return {\n ...prevResponses,\n [questionId]: newResponse,\n };\n });\n },\n [onResponseChange, questions, setResponses],\n );\n\n const handleHelpButtonClick = useCallback(() => {\n if (onHelp && question) {\n onHelp({\n questionId: response_id,\n questionNumber: `${item_number + 1}${\n total_questions > 1 ? String.fromCharCode('a'.charCodeAt(0) + question_number) : ''\n }`,\n });\n }\n }, [item_number, onHelp, question, question_number, response_id, total_questions]);\n\n const handleHintButtonClick = useCallback(() => {\n loggerRef.current(EVENTS.WORKSHEET_V3_HINT_SEEN);\n setResponses(prevResponses => {\n const newResponse = {\n ...getQuestionMetadata(questions, response_id),\n ...prevResponses[response_id],\n hintsUsed: (prevResponses[response_id]?.hintsUsed ?? 0) + 1,\n };\n\n onResponseChange?.({\n responseId: response_id,\n response: newResponse,\n question: questions.find(q => q.response_id === response_id)!,\n isNewAttempt: false,\n });\n\n return {\n ...prevResponses,\n [response_id]: newResponse,\n };\n });\n }, [loggerRef, onResponseChange, questions, response_id, setResponses]);\n\n const handleBackButtonClick = useCallback(() => {\n const questionId = questions[questionIndex - 1]?.response_id;\n\n if (questionId) {\n changeQuestion(questionId);\n }\n }, [changeQuestion, questionIndex, questions]);\n\n const handleNextButtonClick = useCallback(() => {\n const questionId = questions[questionIndex + 1]?.response_id;\n\n if (questionId) {\n changeQuestion(questionId);\n } else {\n showSummary();\n }\n }, [changeQuestion, questionIndex, questions, showSummary]);\n\n const handleSkipButtonClick = useCallback(() => {\n setResponses(prevResponses => {\n const newResponse = {\n ...getQuestionMetadata(questions, response_id),\n ...prevResponses[response_id],\n skipped: true,\n };\n\n onResponseChange?.({\n responseId: response_id,\n response: newResponse,\n question: questions.find(q => q.response_id === response_id)!,\n isNewAttempt: false,\n });\n\n return {\n ...prevResponses,\n [response_id]: newResponse,\n };\n });\n setSkipped(true);\n }, [onResponseChange, questions, response_id, setResponses, setSkipped]);\n\n const handleResponseChange = useCallback(\n (answerChecked?: boolean) => {\n const questionInstance = learnosity.question(response_id);\n\n if (questionInstance) {\n const lquestion = questionInstance.getQuestion();\n const questionResponse = questionInstance.getResponse();\n const shouldCheckAbuse =\n lquestion.type === 'clozeformula' && questionResponse && questionResponse?.value;\n const isInputExceedingMaxLength = shouldCheckAbuse\n ? checkIsClozeFormulaResponseInvalid(questionResponse)\n : false;\n\n if (isInputExceedingMaxLength) {\n showBoundary(new Error('CLOZE_FORMULA_RESPONSE_EXCEEDS_MAX_LENGTH'));\n }\n\n questionInstance.getScore(score => {\n updateResponse({\n responseId: response_id,\n response: questionResponse,\n score:\n isOkayTypeQuestion(lquestion) || !score\n ? {\n max_score: 0,\n score: 0,\n unscored: !score, // score will be null for unscored questions\n }\n : { ...score, score: score.score ?? 0 },\n answerChecked,\n timeSpent: getTimeSpentOnQuestion(response_id),\n });\n });\n }\n },\n [getTimeSpentOnQuestion, learnosity, response_id, showBoundary, updateResponse],\n );\n\n const handleRetryButtonClick = useCallback(() => {\n const questionInstance = learnosity.question(response_id);\n\n if (questionInstance) {\n questionInstance.enable();\n questionInstance.resetValidationUI();\n handleResponseChange();\n }\n }, [handleResponseChange, learnosity, response_id]);\n\n const handleValidate = useCallback(() => {\n playAudio();\n handleResponseChange(true);\n }, [handleResponseChange, playAudio]);\n\n const handleCheckButtonClick = useCallback(() => {\n const questionInstance = learnosity.question(response_id);\n\n if (questionInstance) {\n questionInstance.disable();\n questionInstance.validate(\n {\n feedbackAttempts: true,\n },\n handleValidate,\n );\n }\n }, [handleValidate, learnosity, response_id]);\n\n const handleValidateButtonClick = useCallback(() => {\n if (isExitTicket) {\n setBlocker('exit-ticket-review');\n } else {\n onTeacherValidation?.(response_id);\n }\n }, [isExitTicket, onTeacherValidation, response_id, setBlocker]);\n\n const handleStartButtonClick = useCallback(() => {\n validateQuestion(response_id);\n }, [response_id, validateQuestion]);\n\n const handleReadyButtonClick = useCallback(() => {\n setResponses(prevResponses => {\n const newResponse: IWorksheetResponse = {\n ...getQuestionMetadata(questions, response_id),\n ...prevResponses[response_id],\n submittedByStudent: true,\n };\n\n onResponseChange?.({\n responseId: response_id,\n response: newResponse,\n question: questions.find(q => q.response_id === response_id)!,\n isNewAttempt: false,\n });\n\n return {\n ...prevResponses,\n [response_id]: newResponse,\n };\n });\n setBlocker('exit-ticket-student-submission');\n }, [onResponseChange, questions, response_id, setBlocker, setResponses]);\n\n const handleSkipSectionButtonClick = useCallback(() => {\n setBlocker('optional-items-skip');\n }, [setBlocker]);\n\n return {\n handleResponseChange,\n handleHelpButtonClick: onHelp ? handleHelpButtonClick : undefined,\n handleHintButtonClick,\n handleBackButtonClick:\n !questionsScrollable && !teacherValidationEnabled ? handleBackButtonClick : undefined,\n handleNextButtonClick,\n handleRetryButtonClick,\n handleCheckButtonClick,\n handleValidateButtonClick,\n handleStartButtonClick,\n handleReadyButtonClick,\n handleSkipSectionButtonClick,\n handleSkipButtonClick,\n };\n};\n\nexport default useHandlerCallbacks;\n"],"names":["useHandlerCallbacks","options","behavior","layout","questions","setResponses","questionIndex","updateResponse","onResponseChange","showSummary","changeQuestion","setBlocker","onTeacherValidation","learnosity","loggerRef","onHelp","useWorksheetStore","store","question","getTimeSpentOnQuestion","setSkipped","questionsScrollable","response_id","item_type","question_number","item_number","total_questions","isExitTicket","validation","teacherValidationEnabled","canAutoPlayAudio","useAutoPlayPermission","audioConfig","SYSTEM_VALIDATION_AUDIO_LIST","acc","name","url","audioManager","useAudioPlayer","showBoundary","useErrorBoundary","playAudio","useCallback","questionInstance","isOkayTypeQuestion","sc","maxScore","currentScore","validateQuestion","questionId","rating","prevResponses","newResponse","getQuestionMetadata","q","handleHelpButtonClick","handleHintButtonClick","EVENTS","_a","handleBackButtonClick","handleNextButtonClick","handleSkipButtonClick","handleResponseChange","answerChecked","lquestion","questionResponse","checkIsClozeFormulaResponseInvalid","score","handleRetryButtonClick","handleValidate","handleCheckButtonClick","handleValidateButtonClick","handleStartButtonClick","handleReadyButtonClick","handleSkipSectionButtonClick"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"use-handler-callbacks.js","sources":["../../../../../src/features/worksheet/worksheet/worksheet-questions-controller/use-handler-callbacks.ts"],"sourcesContent":["import { useCallback, type Dispatch, type SetStateAction } from 'react';\nimport { useErrorBoundary } from 'react-error-boundary';\n\nimport useAudioPlayer from '../../../hooks/use-audio-player';\nimport EVENTS from '../../constants/events';\nimport { SYSTEM_VALIDATION_AUDIO_LIST } from '../constants';\nimport { useWorksheetStore } from '../hooks/use-worksheet-store';\nimport {\n checkIsClozeFormulaResponseInvalid,\n getQuestionMetadata,\n isOkayTypeQuestion,\n} from '../worksheet-helpers';\nimport type { IWorksheetResponse } from '../worksheet-types';\nimport type { IWorksheetQuestionsControllerProps } from './worksheet-questions-controller-types';\n\ninterface IUseHandlerCallbacks {\n (\n options: Pick<IWorksheetQuestionsControllerProps, 'question' | 'getTimeSpentOnQuestion'> & {\n setSkipped: Dispatch<SetStateAction<boolean>>;\n },\n ): {\n handleResponseChange: () => void;\n handleHelpButtonClick?: () => void;\n handleHintButtonClick: () => void;\n handleBackButtonClick?: () => void;\n handleNextButtonClick: () => void;\n handleRetryButtonClick: () => void;\n handleCheckButtonClick: () => void;\n handleValidateButtonClick: () => void;\n handleStartButtonClick: () => void;\n handleReadyButtonClick: () => void;\n handleSkipSectionButtonClick: () => void;\n handleSkipButtonClick: () => void;\n };\n}\n\nconst useHandlerCallbacks: IUseHandlerCallbacks = options => {\n const {\n behavior,\n layout,\n questions,\n setResponses,\n questionIndex,\n updateResponse,\n onResponseChange,\n showSummary,\n changeQuestion,\n setBlocker,\n onTeacherValidation,\n learnosity,\n loggerRef,\n onHelp,\n } = useWorksheetStore(store => ({\n behavior: store.behavior,\n layout: store.layout,\n questions: store.questions,\n questionIndex: store.activeQuestionIndex,\n setResponses: store.setResponses,\n updateResponse: store.updateResponse,\n onResponseChange: store.onResponseChange,\n showSummary: store.showSummary,\n changeQuestion: store.changeQuestion,\n setBlocker: store.setBlocker,\n onTeacherValidation: store.onTeacherValidation,\n learnosity: store.learnosity,\n loggerRef: store.loggerRef,\n onHelp: store.onHelp,\n }));\n const { question, getTimeSpentOnQuestion, setSkipped } = options;\n const { questionsScrollable } = layout;\n const { response_id, item_type, question_number, item_number, total_questions } = question;\n const isExitTicket = item_type === 'exit-ticket';\n const { validation, teacherValidationEnabled } = behavior;\n const playNotifSound = useAudioPlayer(SYSTEM_VALIDATION_AUDIO_LIST);\n const { showBoundary } = useErrorBoundary();\n\n const playAudio = useCallback(() => {\n const questionInstance = learnosity.question(response_id);\n\n if (questionInstance && validation && !isOkayTypeQuestion(questionInstance.getQuestion())) {\n questionInstance.getScore(sc => {\n const { max_score: maxScore, score: currentScore } = sc || {};\n\n if (maxScore) {\n if (maxScore === currentScore) {\n playNotifSound('CORRECT');\n } else {\n playNotifSound('INCORRECT');\n }\n }\n });\n }\n }, [learnosity, playNotifSound, response_id, validation]);\n\n const validateQuestion = useCallback(\n (questionId: string, rating?: number) => {\n setResponses(prevResponses => {\n const newResponse = {\n ...getQuestionMetadata(questions, questionId),\n ...prevResponses[questionId],\n validatedByTeacher: true,\n rating,\n };\n\n onResponseChange?.({\n responseId: questionId,\n response: newResponse,\n question: questions.find(q => q.response_id === questionId)!,\n isNewAttempt: false,\n });\n\n return {\n ...prevResponses,\n [questionId]: newResponse,\n };\n });\n },\n [onResponseChange, questions, setResponses],\n );\n\n const handleHelpButtonClick = useCallback(() => {\n if (onHelp && question) {\n onHelp({\n questionId: response_id,\n questionNumber: `${item_number + 1}${\n total_questions > 1 ? String.fromCharCode('a'.charCodeAt(0) + question_number) : ''\n }`,\n });\n }\n }, [item_number, onHelp, question, question_number, response_id, total_questions]);\n\n const handleHintButtonClick = useCallback(() => {\n loggerRef.current(EVENTS.WORKSHEET_V3_HINT_SEEN);\n setResponses(prevResponses => {\n const newResponse = {\n ...getQuestionMetadata(questions, response_id),\n ...prevResponses[response_id],\n hintsUsed: (prevResponses[response_id]?.hintsUsed ?? 0) + 1,\n };\n\n onResponseChange?.({\n responseId: response_id,\n response: newResponse,\n question: questions.find(q => q.response_id === response_id)!,\n isNewAttempt: false,\n });\n\n return {\n ...prevResponses,\n [response_id]: newResponse,\n };\n });\n }, [loggerRef, onResponseChange, questions, response_id, setResponses]);\n\n const handleBackButtonClick = useCallback(() => {\n const questionId = questions[questionIndex - 1]?.response_id;\n\n if (questionId) {\n changeQuestion(questionId);\n }\n }, [changeQuestion, questionIndex, questions]);\n\n const handleNextButtonClick = useCallback(() => {\n const questionId = questions[questionIndex + 1]?.response_id;\n\n if (questionId) {\n changeQuestion(questionId);\n } else {\n showSummary();\n }\n }, [changeQuestion, questionIndex, questions, showSummary]);\n\n const handleSkipButtonClick = useCallback(() => {\n setResponses(prevResponses => {\n const newResponse = {\n ...getQuestionMetadata(questions, response_id),\n ...prevResponses[response_id],\n skipped: true,\n };\n\n onResponseChange?.({\n responseId: response_id,\n response: newResponse,\n question: questions.find(q => q.response_id === response_id)!,\n isNewAttempt: false,\n });\n\n return {\n ...prevResponses,\n [response_id]: newResponse,\n };\n });\n setSkipped(true);\n }, [onResponseChange, questions, response_id, setResponses, setSkipped]);\n\n const handleResponseChange = useCallback(\n (answerChecked?: boolean) => {\n const questionInstance = learnosity.question(response_id);\n\n if (questionInstance) {\n const lquestion = questionInstance.getQuestion();\n const questionResponse = questionInstance.getResponse();\n const shouldCheckAbuse =\n lquestion.type === 'clozeformula' && questionResponse && questionResponse?.value;\n const isInputExceedingMaxLength = shouldCheckAbuse\n ? checkIsClozeFormulaResponseInvalid(questionResponse)\n : false;\n\n if (isInputExceedingMaxLength) {\n showBoundary(new Error('CLOZE_FORMULA_RESPONSE_EXCEEDS_MAX_LENGTH'));\n }\n\n questionInstance.getScore(score => {\n updateResponse({\n responseId: response_id,\n response: questionResponse,\n score:\n isOkayTypeQuestion(lquestion) || !score\n ? {\n max_score: 0,\n score: 0,\n unscored: !score, // score will be null for unscored questions\n }\n : { ...score, score: score.score ?? 0 },\n answerChecked,\n timeSpent: getTimeSpentOnQuestion(response_id),\n });\n });\n }\n },\n [getTimeSpentOnQuestion, learnosity, response_id, showBoundary, updateResponse],\n );\n\n const handleRetryButtonClick = useCallback(() => {\n const questionInstance = learnosity.question(response_id);\n\n if (questionInstance) {\n questionInstance.enable();\n questionInstance.resetValidationUI();\n handleResponseChange();\n }\n }, [handleResponseChange, learnosity, response_id]);\n\n const handleValidate = useCallback(() => {\n playAudio();\n handleResponseChange(true);\n }, [handleResponseChange, playAudio]);\n\n const handleCheckButtonClick = useCallback(() => {\n const questionInstance = learnosity.question(response_id);\n\n if (questionInstance) {\n questionInstance.disable();\n questionInstance.validate(\n {\n feedbackAttempts: true,\n },\n handleValidate,\n );\n }\n }, [handleValidate, learnosity, response_id]);\n\n const handleValidateButtonClick = useCallback(() => {\n if (isExitTicket) {\n setBlocker('exit-ticket-review');\n } else {\n onTeacherValidation?.(response_id);\n }\n }, [isExitTicket, onTeacherValidation, response_id, setBlocker]);\n\n const handleStartButtonClick = useCallback(() => {\n validateQuestion(response_id);\n }, [response_id, validateQuestion]);\n\n const handleReadyButtonClick = useCallback(() => {\n setResponses(prevResponses => {\n const newResponse: IWorksheetResponse = {\n ...getQuestionMetadata(questions, response_id),\n ...prevResponses[response_id],\n submittedByStudent: true,\n };\n\n onResponseChange?.({\n responseId: response_id,\n response: newResponse,\n question: questions.find(q => q.response_id === response_id)!,\n isNewAttempt: false,\n });\n\n return {\n ...prevResponses,\n [response_id]: newResponse,\n };\n });\n setBlocker('exit-ticket-student-submission');\n }, [onResponseChange, questions, response_id, setBlocker, setResponses]);\n\n const handleSkipSectionButtonClick = useCallback(() => {\n setBlocker('optional-items-skip');\n }, [setBlocker]);\n\n return {\n handleResponseChange,\n handleHelpButtonClick: onHelp ? handleHelpButtonClick : undefined,\n handleHintButtonClick,\n handleBackButtonClick:\n !questionsScrollable && !teacherValidationEnabled ? handleBackButtonClick : undefined,\n handleNextButtonClick,\n handleRetryButtonClick,\n handleCheckButtonClick,\n handleValidateButtonClick,\n handleStartButtonClick,\n handleReadyButtonClick,\n handleSkipSectionButtonClick,\n handleSkipButtonClick,\n };\n};\n\nexport default useHandlerCallbacks;\n"],"names":["useHandlerCallbacks","options","behavior","layout","questions","setResponses","questionIndex","updateResponse","onResponseChange","showSummary","changeQuestion","setBlocker","onTeacherValidation","learnosity","loggerRef","onHelp","useWorksheetStore","store","question","getTimeSpentOnQuestion","setSkipped","questionsScrollable","response_id","item_type","question_number","item_number","total_questions","isExitTicket","validation","teacherValidationEnabled","playNotifSound","useAudioPlayer","SYSTEM_VALIDATION_AUDIO_LIST","showBoundary","useErrorBoundary","playAudio","useCallback","questionInstance","isOkayTypeQuestion","sc","maxScore","currentScore","validateQuestion","questionId","rating","prevResponses","newResponse","getQuestionMetadata","q","handleHelpButtonClick","handleHintButtonClick","EVENTS","_a","handleBackButtonClick","handleNextButtonClick","handleSkipButtonClick","handleResponseChange","answerChecked","lquestion","questionResponse","checkIsClozeFormulaResponseInvalid","score","handleRetryButtonClick","handleValidate","handleCheckButtonClick","handleValidateButtonClick","handleStartButtonClick","handleReadyButtonClick","handleSkipSectionButtonClick"],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -7285,18 +7285,9 @@ export declare const useChapterPageJourney: () => {
|
|
|
7285
7285
|
|
|
7286
7286
|
export declare const useCircleSounds: () => {
|
|
7287
7287
|
playSwipeSound: () => void;
|
|
7288
|
-
|
|
7289
|
-
|
|
7290
|
-
|
|
7291
|
-
audioManager: {
|
|
7292
|
-
stopAll: (options?: {
|
|
7293
|
-
immediately?: boolean;
|
|
7294
|
-
fadeOut?: boolean;
|
|
7295
|
-
}) => void;
|
|
7296
|
-
isPlaying: (key: string) => boolean;
|
|
7297
|
-
setVolume: (key: string, volume: number, duration?: number) => void;
|
|
7298
|
-
loadSound: (key: string) => Promise<void>;
|
|
7299
|
-
};
|
|
7288
|
+
play: (key: CircleSoundKey, immediately?: boolean, loop?: boolean) => HTMLAudioElement | undefined;
|
|
7289
|
+
stop: (key: CircleSoundKey, immediately?: boolean) => void;
|
|
7290
|
+
playButtonSound: () => HTMLAudioElement | undefined;
|
|
7300
7291
|
};
|
|
7301
7292
|
|
|
7302
7293
|
export declare const useClassTimeAlerts: ({ alertLevel, classStartedOn, classDuration, onUpdateClassTimeAlertConfig, }: IUseClassTimeAlerts) => {
|
package/package.json
CHANGED
|
@@ -1,164 +0,0 @@
|
|
|
1
|
-
import { useRef as h, useEffect as x, useCallback as i } from "react";
|
|
2
|
-
const R = (V, p = !0) => {
|
|
3
|
-
const n = h(null), T = h({}), c = h({}), a = h({});
|
|
4
|
-
x(() => {
|
|
5
|
-
try {
|
|
6
|
-
const e = window.AudioContext || window.webkitAudioContext;
|
|
7
|
-
n.current = new e();
|
|
8
|
-
} catch (e) {
|
|
9
|
-
console.warn("Failed to create AudioContext:", e);
|
|
10
|
-
}
|
|
11
|
-
return () => {
|
|
12
|
-
n.current && n.current.state !== "closed" && n.current.close();
|
|
13
|
-
};
|
|
14
|
-
}, []);
|
|
15
|
-
const m = i(async () => {
|
|
16
|
-
var e;
|
|
17
|
-
if (((e = n.current) == null ? void 0 : e.state) === "suspended")
|
|
18
|
-
try {
|
|
19
|
-
await n.current.resume();
|
|
20
|
-
} catch (t) {
|
|
21
|
-
console.warn("Failed to resume AudioContext:", t);
|
|
22
|
-
}
|
|
23
|
-
}, []), A = i(
|
|
24
|
-
async (e) => {
|
|
25
|
-
if (!(!n.current || T.current[e]))
|
|
26
|
-
try {
|
|
27
|
-
const t = V[e];
|
|
28
|
-
if (!t) throw new Error(`No URL found for sound key: ${e}`);
|
|
29
|
-
const r = await fetch(t, {
|
|
30
|
-
mode: "cors",
|
|
31
|
-
credentials: "omit"
|
|
32
|
-
});
|
|
33
|
-
if (!r.ok)
|
|
34
|
-
throw new Error(`HTTP error! status: ${r.status}`);
|
|
35
|
-
const o = await r.arrayBuffer(), u = await n.current.decodeAudioData(o);
|
|
36
|
-
T.current[e] = u;
|
|
37
|
-
} catch (t) {
|
|
38
|
-
console.error(`Failed to load sound "${e}":`, t), T.current[e] = null;
|
|
39
|
-
}
|
|
40
|
-
},
|
|
41
|
-
[V]
|
|
42
|
-
), g = i((e, t = 0.5) => {
|
|
43
|
-
if (!n.current) return;
|
|
44
|
-
const r = n.current.currentTime;
|
|
45
|
-
e.gain.cancelScheduledValues(r), e.gain.setValueAtTime(e.gain.value, r), e.gain.linearRampToValueAtTime(1, r + t);
|
|
46
|
-
}, []), w = i(
|
|
47
|
-
(e, t, r = 0.5, o = !0) => {
|
|
48
|
-
if (!n.current) return;
|
|
49
|
-
a.current[e] && (clearTimeout(a.current[e]), delete a.current[e]);
|
|
50
|
-
const u = n.current.currentTime;
|
|
51
|
-
t.gainNode.gain.cancelScheduledValues(u), t.gainNode.gain.setValueAtTime(t.gainNode.gain.value, u), t.gainNode.gain.linearRampToValueAtTime(0, u + r), o && (a.current[e] = window.setTimeout(() => {
|
|
52
|
-
var l;
|
|
53
|
-
try {
|
|
54
|
-
t.source.stop();
|
|
55
|
-
} catch (f) {
|
|
56
|
-
console.warn("Error stopping sound:", f);
|
|
57
|
-
}
|
|
58
|
-
((l = c.current[e]) == null ? void 0 : l.source) === t.source && delete c.current[e], delete a.current[e];
|
|
59
|
-
}, r * 1e3));
|
|
60
|
-
},
|
|
61
|
-
[]
|
|
62
|
-
), N = i(
|
|
63
|
-
async (e, t = {}) => {
|
|
64
|
-
const {
|
|
65
|
-
loop: r = !1,
|
|
66
|
-
volume: o = 1,
|
|
67
|
-
fadeIn: u = !1,
|
|
68
|
-
fadeDuration: l = 0.5
|
|
69
|
-
} = t;
|
|
70
|
-
if (!n.current || !p) {
|
|
71
|
-
console.warn("Cannot play sound:", {
|
|
72
|
-
key: e,
|
|
73
|
-
hasContext: !!n.current,
|
|
74
|
-
canPlayAudio: p
|
|
75
|
-
});
|
|
76
|
-
return;
|
|
77
|
-
}
|
|
78
|
-
await m(), await A(e);
|
|
79
|
-
const f = T.current[e];
|
|
80
|
-
if (!f) {
|
|
81
|
-
console.warn(`No buffer available for sound: ${e}`);
|
|
82
|
-
return;
|
|
83
|
-
}
|
|
84
|
-
if (c.current[e] && r) {
|
|
85
|
-
a.current[e] && (clearTimeout(a.current[e]), delete a.current[e]), g(c.current[e].gainNode, l);
|
|
86
|
-
return;
|
|
87
|
-
}
|
|
88
|
-
if (c.current[e]) {
|
|
89
|
-
const s = c.current[e];
|
|
90
|
-
try {
|
|
91
|
-
s.source.stop();
|
|
92
|
-
} catch (d) {
|
|
93
|
-
console.warn("Error stopping existing sound:", d);
|
|
94
|
-
}
|
|
95
|
-
delete c.current[e];
|
|
96
|
-
}
|
|
97
|
-
try {
|
|
98
|
-
const s = n.current.createBufferSource(), d = n.current.createGain();
|
|
99
|
-
s.buffer = f, s.loop = r, s.connect(d).connect(n.current.destination), u ? (d.gain.setValueAtTime(0, n.current.currentTime), g(d, l)) : d.gain.setValueAtTime(o, n.current.currentTime), s.start(), c.current[e] = { source: s, gainNode: d, loop: r }, r || (s.onended = () => {
|
|
100
|
-
var C;
|
|
101
|
-
((C = c.current[e]) == null ? void 0 : C.source) === s && delete c.current[e];
|
|
102
|
-
});
|
|
103
|
-
} catch (s) {
|
|
104
|
-
console.error(`Failed to play sound "${e}":`, s);
|
|
105
|
-
}
|
|
106
|
-
},
|
|
107
|
-
[p, m, A, g]
|
|
108
|
-
), b = i(
|
|
109
|
-
async (e, t = {}) => {
|
|
110
|
-
const { immediately: r = !0, fadeOut: o = !1, fadeDuration: u = 0.5 } = t, l = c.current[e];
|
|
111
|
-
if (l)
|
|
112
|
-
if (r && !o) {
|
|
113
|
-
try {
|
|
114
|
-
l.source.stop();
|
|
115
|
-
} catch (f) {
|
|
116
|
-
console.warn("Error stopping sound:", f);
|
|
117
|
-
}
|
|
118
|
-
delete c.current[e], a.current[e] && (clearTimeout(a.current[e]), delete a.current[e]);
|
|
119
|
-
} else
|
|
120
|
-
w(e, l, u);
|
|
121
|
-
},
|
|
122
|
-
[w]
|
|
123
|
-
), E = i(
|
|
124
|
-
(e = {}) => {
|
|
125
|
-
Object.keys(c.current).forEach((r) => b(r, e));
|
|
126
|
-
},
|
|
127
|
-
[b]
|
|
128
|
-
), v = i((e) => !!c.current[e], []), S = i((e, t, r = 0) => {
|
|
129
|
-
const o = c.current[e];
|
|
130
|
-
if (!o || !n.current) return;
|
|
131
|
-
const u = n.current.currentTime;
|
|
132
|
-
r > 0 ? (o.gainNode.gain.cancelScheduledValues(u), o.gainNode.gain.setValueAtTime(o.gainNode.gain.value, u), o.gainNode.gain.linearRampToValueAtTime(t, u + r)) : o.gainNode.gain.setValueAtTime(t, u);
|
|
133
|
-
}, []), O = i(
|
|
134
|
-
(e = /* @__PURE__ */ new Set(), t = !0) => {
|
|
135
|
-
t && (document.visibilityState === "visible" ? (m(), Object.values(c.current).forEach((r) => {
|
|
136
|
-
r && g(r.gainNode);
|
|
137
|
-
})) : Object.entries(c.current).forEach(([r, o]) => {
|
|
138
|
-
o && (e.has(r) ? w(r, o, 0.5, !1) : w(r, o));
|
|
139
|
-
}));
|
|
140
|
-
},
|
|
141
|
-
[m, g, w]
|
|
142
|
-
);
|
|
143
|
-
return x(() => {
|
|
144
|
-
const e = a.current;
|
|
145
|
-
return () => {
|
|
146
|
-
Object.values(e).forEach((t) => {
|
|
147
|
-
t && clearTimeout(t);
|
|
148
|
-
});
|
|
149
|
-
};
|
|
150
|
-
}, []), {
|
|
151
|
-
play: N,
|
|
152
|
-
stop: b,
|
|
153
|
-
stopAll: E,
|
|
154
|
-
isPlaying: v,
|
|
155
|
-
setVolume: S,
|
|
156
|
-
handleVisibilityChange: O,
|
|
157
|
-
loadSound: A,
|
|
158
|
-
resumeAudioContext: m
|
|
159
|
-
};
|
|
160
|
-
};
|
|
161
|
-
export {
|
|
162
|
-
R as useAudioPlayer
|
|
163
|
-
};
|
|
164
|
-
//# sourceMappingURL=use-audio-player.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"use-audio-player.js","sources":["../../../../src/features/hooks/use-audio-player/use-audio-player.ts"],"sourcesContent":["import { useCallback, useEffect, useRef } from 'react';\n\nimport { type IActiveSound, type IAudioConfig, type IAudioOptions } from './use-audio-player-types';\n\ndeclare global {\n interface Window {\n webkitAudioContext?: typeof AudioContext;\n }\n}\n\nexport const useAudioPlayer = (audioConfig: IAudioConfig, canPlayAudio: boolean = true) => {\n const audioContext = useRef<AudioContext | null>(null);\n const bufferCache = useRef<Record<string, AudioBuffer | null>>({});\n const activeSounds = useRef<Partial<Record<string, IActiveSound>>>({});\n const fadeTimeouts = useRef<Partial<Record<string, number>>>({});\n\n useEffect(() => {\n try {\n const AudioContextClass = window.AudioContext || window.webkitAudioContext;\n\n audioContext.current = new AudioContextClass();\n } catch (error) {\n // eslint-disable-next-line no-console\n console.warn('Failed to create AudioContext:', error);\n }\n\n return () => {\n if (audioContext.current && audioContext.current.state !== 'closed') {\n audioContext.current.close();\n }\n };\n }, []);\n\n const resumeAudioContext = useCallback(async () => {\n if (audioContext.current?.state === 'suspended') {\n try {\n await audioContext.current.resume();\n } catch (error) {\n // eslint-disable-next-line no-console\n console.warn('Failed to resume AudioContext:', error);\n }\n }\n }, []);\n\n const loadSound = useCallback(\n async (key: string): Promise<void> => {\n if (!audioContext.current || bufferCache.current[key]) return;\n\n try {\n const url = audioConfig[key];\n\n if (!url) throw new Error(`No URL found for sound key: ${key}`);\n\n const 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 = await response.arrayBuffer();\n const audioBuffer = await audioContext.current.decodeAudioData(arrayBuffer);\n\n bufferCache.current[key] = audioBuffer;\n } catch (error) {\n // eslint-disable-next-line no-console\n console.error(`Failed to load sound \"${key}\":`, error);\n bufferCache.current[key] = null;\n }\n },\n [audioConfig],\n );\n\n const fadeIn = useCallback((gainNode: GainNode, duration: number = 0.5) => {\n if (!audioContext.current) return;\n\n const now = audioContext.current.currentTime;\n\n gainNode.gain.cancelScheduledValues(now);\n gainNode.gain.setValueAtTime(gainNode.gain.value, now);\n gainNode.gain.linearRampToValueAtTime(1, now + duration);\n }, []);\n\n const fadeOut = useCallback(\n (key: string, sound: IActiveSound, duration: number = 0.5, shouldStop: boolean = true) => {\n if (!audioContext.current) return;\n\n if (fadeTimeouts.current[key]) {\n clearTimeout(fadeTimeouts.current[key]);\n delete fadeTimeouts.current[key];\n }\n\n const now = audioContext.current.currentTime;\n\n sound.gainNode.gain.cancelScheduledValues(now);\n sound.gainNode.gain.setValueAtTime(sound.gainNode.gain.value, now);\n sound.gainNode.gain.linearRampToValueAtTime(0, now + duration);\n\n if (shouldStop) {\n fadeTimeouts.current[key] = window.setTimeout(() => {\n try {\n sound.source.stop();\n } catch (error) {\n // eslint-disable-next-line no-console\n console.warn('Error stopping sound:', error);\n }\n\n if (activeSounds.current[key]?.source === sound.source) {\n delete activeSounds.current[key];\n }\n delete fadeTimeouts.current[key];\n }, duration * 1000);\n }\n },\n [],\n );\n\n const play = useCallback(\n async (key: string, options: IAudioOptions = {}): Promise<void> => {\n const {\n loop = false,\n volume = 1,\n fadeIn: shouldFadeIn = false,\n fadeDuration = 0.5,\n } = options;\n\n if (!audioContext.current || !canPlayAudio) {\n // eslint-disable-next-line no-console\n console.warn('Cannot play sound:', {\n key,\n hasContext: !!audioContext.current,\n canPlayAudio,\n });\n\n return;\n }\n\n await resumeAudioContext();\n await loadSound(key);\n\n const buffer = bufferCache.current[key];\n\n if (!buffer) {\n // eslint-disable-next-line no-console\n console.warn(`No buffer available for sound: ${key}`);\n\n return;\n }\n\n if (activeSounds.current[key] && loop) {\n if (fadeTimeouts.current[key]) {\n clearTimeout(fadeTimeouts.current[key]);\n delete fadeTimeouts.current[key];\n }\n fadeIn(activeSounds.current[key]!.gainNode, fadeDuration);\n\n return;\n }\n\n if (activeSounds.current[key]) {\n const existingSound = activeSounds.current[key];\n\n try {\n existingSound!.source.stop();\n } catch (error) {\n // eslint-disable-next-line no-console\n console.warn('Error stopping existing sound:', error);\n }\n delete activeSounds.current[key];\n }\n\n try {\n const source = audioContext.current.createBufferSource();\n const gainNode = audioContext.current.createGain();\n\n source.buffer = buffer;\n source.loop = loop;\n source.connect(gainNode).connect(audioContext.current.destination);\n\n if (shouldFadeIn) {\n gainNode.gain.setValueAtTime(0, audioContext.current.currentTime);\n fadeIn(gainNode, fadeDuration);\n } else {\n gainNode.gain.setValueAtTime(volume, audioContext.current.currentTime);\n }\n\n source.start();\n activeSounds.current[key] = { source, gainNode, loop };\n\n if (!loop) {\n source.onended = () => {\n if (activeSounds.current[key]?.source === source) {\n delete activeSounds.current[key];\n }\n };\n }\n } catch (error) {\n // eslint-disable-next-line no-console\n console.error(`Failed to play sound \"${key}\":`, error);\n }\n },\n [canPlayAudio, resumeAudioContext, loadSound, fadeIn],\n );\n\n const stop = useCallback(\n async (\n key: string,\n options: { immediately?: boolean; fadeOut?: boolean; fadeDuration?: number } = {},\n ): Promise<void> => {\n const { immediately = true, fadeOut: shouldFadeOut = false, fadeDuration = 0.5 } = options;\n\n const sound = activeSounds.current[key];\n\n if (!sound) return;\n\n if (immediately && !shouldFadeOut) {\n try {\n sound.source.stop();\n } catch (error) {\n // eslint-disable-next-line no-console\n console.warn('Error stopping sound:', error);\n }\n\n delete activeSounds.current[key];\n if (fadeTimeouts.current[key]) {\n clearTimeout(fadeTimeouts.current[key]);\n delete fadeTimeouts.current[key];\n }\n } else {\n fadeOut(key, sound, fadeDuration);\n }\n },\n [fadeOut],\n );\n\n const stopAll = useCallback(\n (options: { immediately?: boolean; fadeOut?: boolean } = {}) => {\n const soundKeys = Object.keys(activeSounds.current);\n\n soundKeys.forEach(key => stop(key, options));\n },\n [stop],\n );\n\n const isPlaying = useCallback((key: string): boolean => {\n return !!activeSounds.current[key];\n }, []);\n\n const setVolume = useCallback((key: string, volume: number, duration: number = 0) => {\n const sound = activeSounds.current[key];\n\n if (!sound || !audioContext.current) return;\n\n const now = audioContext.current.currentTime;\n\n if (duration > 0) {\n sound.gainNode.gain.cancelScheduledValues(now);\n sound.gainNode.gain.setValueAtTime(sound.gainNode.gain.value, now);\n sound.gainNode.gain.linearRampToValueAtTime(volume, now + duration);\n } else {\n sound.gainNode.gain.setValueAtTime(volume, now);\n }\n }, []);\n\n const handleVisibilityChange = useCallback(\n (backgroundSounds: Set<string> = new Set(), fadeOnHide: boolean = true) => {\n if (!fadeOnHide) return;\n\n if (document.visibilityState === 'visible') {\n resumeAudioContext();\n Object.values(activeSounds.current).forEach(sound => {\n if (sound) {\n fadeIn(sound.gainNode);\n }\n });\n } else {\n Object.entries(activeSounds.current).forEach(([key, sound]) => {\n if (sound) {\n if (backgroundSounds.has(key)) {\n fadeOut(key, sound, 0.5, false);\n } else {\n fadeOut(key, sound);\n }\n }\n });\n }\n },\n [resumeAudioContext, fadeIn, fadeOut],\n );\n\n useEffect(() => {\n const timeouts = fadeTimeouts.current;\n\n return () => {\n Object.values(timeouts).forEach(id => {\n if (id) clearTimeout(id);\n });\n };\n }, []);\n\n return {\n play,\n stop,\n stopAll,\n isPlaying,\n setVolume,\n handleVisibilityChange,\n loadSound,\n resumeAudioContext,\n };\n};\n"],"names":["useAudioPlayer","audioConfig","canPlayAudio","audioContext","useRef","bufferCache","activeSounds","fadeTimeouts","useEffect","AudioContextClass","error","resumeAudioContext","useCallback","_a","loadSound","key","url","response","arrayBuffer","audioBuffer","fadeIn","gainNode","duration","now","fadeOut","sound","shouldStop","play","options","loop","volume","shouldFadeIn","fadeDuration","buffer","existingSound","source","stop","immediately","shouldFadeOut","stopAll","isPlaying","setVolume","handleVisibilityChange","backgroundSounds","fadeOnHide","timeouts","id"],"mappings":"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"}
|