@spaced-out/ui-design-system 0.6.2 → 0.6.6
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/CHANGELOG.md +28 -0
- package/lib/components/Icon/Icon.module.css +4 -0
- package/lib/components/Link/Link.js +2 -4
- package/lib/components/VoiceOrb/Microphone/Microphone.d.ts.map +1 -1
- package/lib/components/VoiceOrb/Microphone/Microphone.js +21 -18
- package/lib/components/VoiceOrb/VoiceOrb/VoiceOrb.d.ts +2 -2
- package/lib/components/VoiceOrb/VoiceOrb/VoiceOrb.d.ts.map +1 -1
- package/lib/components/VoiceOrb/VoiceOrb/VoiceOrb.js +19 -4
- package/lib/components/VoiceOrb/constants.d.ts +1 -1
- package/lib/components/VoiceOrb/constants.d.ts.map +1 -1
- package/lib/components/VoiceOrb/constants.js +3 -3
- package/lib/hooks/useAudioAnalyzer/useAudioAnalyzer.d.ts +2 -2
- package/lib/hooks/useAudioAnalyzer/useAudioAnalyzer.d.ts.map +1 -1
- package/lib/hooks/useAudioAnalyzer/useAudioAnalyzer.js +6 -5
- package/mcp/package.json +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,34 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
|
|
4
4
|
|
|
5
|
+
### [0.6.6](https://github.com/spaced-out/ui-design-system/compare/v0.6.6-beta.2...v0.6.6) (2026-03-24)
|
|
6
|
+
|
|
7
|
+
### [0.6.6-beta.2](https://github.com/spaced-out/ui-design-system/compare/v0.6.6-beta.1...v0.6.6-beta.2) (2026-03-23)
|
|
8
|
+
|
|
9
|
+
### [0.6.6-beta.1](https://github.com/spaced-out/ui-design-system/compare/v0.6.6-beta.0...v0.6.6-beta.1) (2026-03-23)
|
|
10
|
+
|
|
11
|
+
### [0.6.6-beta.0](https://github.com/spaced-out/ui-design-system/compare/v0.6.4...v0.6.6-beta.0) (2026-03-23)
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
### Bug Fixes
|
|
15
|
+
|
|
16
|
+
* add ref for microphone animations ([#470](https://github.com/spaced-out/ui-design-system/issues/470)) ([6aedae2](https://github.com/spaced-out/ui-design-system/commit/6aedae264108a9344ca8d5669a832d80f80a783e))
|
|
17
|
+
|
|
18
|
+
### [0.6.5](https://github.com/spaced-out/ui-design-system/compare/v0.6.4...v0.6.5) (2026-03-23)
|
|
19
|
+
|
|
20
|
+
### Performance
|
|
21
|
+
|
|
22
|
+
* Optimize Voice-Orb and Microphone animations by skipping react lifecycle and updating DOM directly (https://github.com/Spaced-Out/ui-design-system/pull/469)
|
|
23
|
+
|
|
24
|
+
### [0.6.4](https://github.com/spaced-out/ui-design-system/compare/v0.6.3...v0.6.4) (2026-03-18)
|
|
25
|
+
|
|
26
|
+
### [0.6.3](https://github.com/spaced-out/ui-design-system/compare/v0.6.2...v0.6.3) (2026-03-18)
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
### Bug Fixes
|
|
30
|
+
|
|
31
|
+
* disable state link icon color issue ([#467](https://github.com/spaced-out/ui-design-system/issues/467)) ([43cc16f](https://github.com/spaced-out/ui-design-system/commit/43cc16f958f99a3c653e36bfd896b23903da3d9d))
|
|
32
|
+
|
|
5
33
|
### [0.6.2](https://github.com/spaced-out/ui-design-system/compare/v0.6.2-beta.0...v0.6.2) (2026-03-10)
|
|
6
34
|
|
|
7
35
|
|
|
@@ -118,9 +118,7 @@ const Link = exports.Link = /*#__PURE__*/React.forwardRef((_ref, ref) => {
|
|
|
118
118
|
name: iconLeftName,
|
|
119
119
|
size: iconLeftSize,
|
|
120
120
|
type: iconLeftType,
|
|
121
|
-
className:
|
|
122
|
-
[_typographyModule.default.disabled]: disabled
|
|
123
|
-
}),
|
|
121
|
+
className: _IconModule.default.inherit,
|
|
124
122
|
testId: (0, _qa.generateTestId)({
|
|
125
123
|
base: testId,
|
|
126
124
|
slot: 'icon-left'
|
|
@@ -142,7 +140,7 @@ const Link = exports.Link = /*#__PURE__*/React.forwardRef((_ref, ref) => {
|
|
|
142
140
|
name: iconRightName,
|
|
143
141
|
size: iconRightSize,
|
|
144
142
|
type: iconRightType,
|
|
145
|
-
className: _IconModule.default
|
|
143
|
+
className: _IconModule.default.inherit,
|
|
146
144
|
testId: (0, _qa.generateTestId)({
|
|
147
145
|
base: testId,
|
|
148
146
|
slot: 'icon-right'
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Microphone.d.ts","sourceRoot":"","sources":["../../../../src/components/VoiceOrb/Microphone/Microphone.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAiB/B,KAAK,UAAU,GAAG,QAAQ,CAAC;IAAC,aAAa,CAAC,EAAE,MAAM,CAAC;IAAC,GAAG,CAAC,EAAE,MAAM,CAAA;CAAC,CAAC,CAAC;AAEnE,MAAM,WAAW,eAAe;IAC9B,UAAU,CAAC,EAAE,UAAU,CAAC;IACxB,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,QAAA,MAAM,UAAU,EAAE,KAAK,CAAC,EAAE,CAAC,eAAe,
|
|
1
|
+
{"version":3,"file":"Microphone.d.ts","sourceRoot":"","sources":["../../../../src/components/VoiceOrb/Microphone/Microphone.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAiB/B,KAAK,UAAU,GAAG,QAAQ,CAAC;IAAC,aAAa,CAAC,EAAE,MAAM,CAAC;IAAC,GAAG,CAAC,EAAE,MAAM,CAAA;CAAC,CAAC,CAAC;AAEnE,MAAM,WAAW,eAAe;IAC9B,UAAU,CAAC,EAAE,UAAU,CAAC;IACxB,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,QAAA,MAAM,UAAU,EAAE,KAAK,CAAC,EAAE,CAAC,eAAe,CAyDzC,CAAC;AAEF,OAAO,EAAC,UAAU,EAAC,CAAC"}
|
|
@@ -20,40 +20,43 @@ const Microphone = _ref => {
|
|
|
20
20
|
classNames,
|
|
21
21
|
testId
|
|
22
22
|
} = _ref;
|
|
23
|
-
const
|
|
24
|
-
|
|
25
|
-
|
|
23
|
+
const barsRef = React.useRef(null);
|
|
24
|
+
const onAnalyze = React.useCallback(intensities => {
|
|
25
|
+
const container = barsRef.current;
|
|
26
|
+
if (!container || container.children.length !== _constants.BAR_COUNT) {
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
const bars = container.children;
|
|
30
|
+
for (let i = 0; i < intensities.length; i++) {
|
|
31
|
+
const multiplier = 1 + intensities[i] * (_constants.MAX_MULTIPLIERS[i] - 1);
|
|
32
|
+
const height = _constants.BASE_HEIGHT * multiplier;
|
|
33
|
+
bars[i].style.height = `${height}px`;
|
|
34
|
+
}
|
|
35
|
+
}, []);
|
|
36
|
+
(0, _useAudioAnalyzer.useAudioAnalyzer)({
|
|
26
37
|
isListening: enableMicrophone,
|
|
27
38
|
audioStream: null,
|
|
28
|
-
barCount: _constants.BAR_COUNT
|
|
39
|
+
barCount: _constants.BAR_COUNT,
|
|
40
|
+
onAnalyze
|
|
29
41
|
});
|
|
30
42
|
const barKeys = React.useMemo(() => Array.from({
|
|
31
43
|
length: _constants.BAR_COUNT
|
|
32
44
|
}, () => (0, _constants.uuid)()), [_constants.BAR_COUNT]);
|
|
33
|
-
// Calculate dynamic styles for each bar based on audio intensity
|
|
34
|
-
const barStyles = barIntensities.map((intensity, index) => {
|
|
35
|
-
// Height from BASE_HEIGHT (no audio) to BASE_HEIGHT * MAX_MULTIPLIERS[index] (max audio)
|
|
36
|
-
const multiplier = 1 + intensity * (_constants.MAX_MULTIPLIERS[index] - 1);
|
|
37
|
-
const height = _constants.BASE_HEIGHT * multiplier;
|
|
38
|
-
return {
|
|
39
|
-
height: `${height}px`
|
|
40
|
-
};
|
|
41
|
-
});
|
|
42
45
|
return /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
|
|
43
46
|
"data-testid": (0, _qa.generateTestId)({
|
|
44
47
|
base: testId,
|
|
45
48
|
slot: 'container'
|
|
46
49
|
}),
|
|
47
50
|
className: (0, _classify.default)(_MicrophoneModule.default.barsContainer, classNames?.barsContainer),
|
|
48
|
-
|
|
51
|
+
ref: barsRef,
|
|
52
|
+
children: enableMicrophone ? barKeys.map(barKey => /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
|
|
49
53
|
"data-testid": (0, _qa.generateTestId)({
|
|
50
54
|
base: testId,
|
|
51
55
|
slot: 'bar',
|
|
52
|
-
index
|
|
56
|
+
index: barKey
|
|
53
57
|
}),
|
|
54
|
-
className: (0, _classify.default)(_MicrophoneModule.default.bar, classNames?.bar)
|
|
55
|
-
|
|
56
|
-
}, barKeys[index])) : /*#__PURE__*/(0, _jsxRuntime.jsx)(_jsxRuntime.Fragment, {
|
|
58
|
+
className: (0, _classify.default)(_MicrophoneModule.default.bar, classNames?.bar)
|
|
59
|
+
}, barKey)) : /*#__PURE__*/(0, _jsxRuntime.jsx)(_jsxRuntime.Fragment, {
|
|
57
60
|
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_MicIcon.MicIcon, {})
|
|
58
61
|
})
|
|
59
62
|
});
|
|
@@ -8,8 +8,8 @@ export interface VoiceOrbProps {
|
|
|
8
8
|
classNames?: ClassNames;
|
|
9
9
|
/** Enable listening to microphone audio input for bar animation */
|
|
10
10
|
enableMicrophone?: boolean;
|
|
11
|
-
/**
|
|
12
|
-
|
|
11
|
+
/** Custom event name to listen for agent volume updates. Default `'agent_volume_update'`. */
|
|
12
|
+
volumeTickEvent?: string;
|
|
13
13
|
testId?: string;
|
|
14
14
|
}
|
|
15
15
|
export declare const VoiceOrb: React.ForwardRefExoticComponent<VoiceOrbProps & React.RefAttributes<HTMLDivElement>>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"VoiceOrb.d.ts","sourceRoot":"","sources":["../../../../src/components/VoiceOrb/VoiceOrb/VoiceOrb.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAW/B,KAAK,UAAU,GAAG,QAAQ,CAAC;IACzB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,GAAG,CAAC,EAAE,MAAM,CAAC;CACd,CAAC,CAAC;AAEH,MAAM,WAAW,aAAa;IAC5B,UAAU,CAAC,EAAE,UAAU,CAAC;IACxB,mEAAmE;IACnE,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B
|
|
1
|
+
{"version":3,"file":"VoiceOrb.d.ts","sourceRoot":"","sources":["../../../../src/components/VoiceOrb/VoiceOrb/VoiceOrb.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAW/B,KAAK,UAAU,GAAG,QAAQ,CAAC;IACzB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,GAAG,CAAC,EAAE,MAAM,CAAC;CACd,CAAC,CAAC;AAEH,MAAM,WAAW,aAAa;IAC5B,UAAU,CAAC,EAAE,UAAU,CAAC;IACxB,mEAAmE;IACnE,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,6FAA6F;IAC7F,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,eAAO,MAAM,QAAQ,sFAmDpB,CAAC"}
|
|
@@ -16,12 +16,27 @@ function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r
|
|
|
16
16
|
const VoiceOrb = exports.VoiceOrb = /*#__PURE__*/React.forwardRef((_ref, ref) => {
|
|
17
17
|
let {
|
|
18
18
|
classNames,
|
|
19
|
-
volume = 0,
|
|
20
19
|
enableMicrophone = false,
|
|
20
|
+
volumeTickEvent = 'agent_volume_update',
|
|
21
21
|
testId
|
|
22
22
|
} = _ref;
|
|
23
|
-
|
|
24
|
-
|
|
23
|
+
const orbRef = React.useRef(null);
|
|
24
|
+
React.useEffect(() => {
|
|
25
|
+
const handleAgentVolumeUpdate = event => {
|
|
26
|
+
const el = orbRef.current;
|
|
27
|
+
if (!el) {
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
const vars = (0, _constants.calculateOrbShadowVars)(event.detail.volume);
|
|
31
|
+
for (const [key, value] of Object.entries(vars)) {
|
|
32
|
+
el.style.setProperty(key, value);
|
|
33
|
+
}
|
|
34
|
+
};
|
|
35
|
+
window.addEventListener(volumeTickEvent, handleAgentVolumeUpdate);
|
|
36
|
+
return () => {
|
|
37
|
+
window.removeEventListener(volumeTickEvent, handleAgentVolumeUpdate);
|
|
38
|
+
};
|
|
39
|
+
}, [volumeTickEvent]);
|
|
25
40
|
return /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
|
|
26
41
|
ref: ref,
|
|
27
42
|
"data-testid": (0, _qa.generateTestId)({
|
|
@@ -32,8 +47,8 @@ const VoiceOrb = exports.VoiceOrb = /*#__PURE__*/React.forwardRef((_ref, ref) =>
|
|
|
32
47
|
children: /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
|
|
33
48
|
className: (0, _classify.default)(_VoiceOrbModule.default.orbContainer, classNames?.orbContainer),
|
|
34
49
|
children: /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
|
|
50
|
+
ref: orbRef,
|
|
35
51
|
className: (0, _classify.default)(_VoiceOrbModule.default.orb, classNames?.orb),
|
|
36
|
-
style: orbShadowVars,
|
|
37
52
|
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_Microphone.Microphone, {
|
|
38
53
|
enableMicrophone: enableMicrophone
|
|
39
54
|
})
|
|
@@ -13,6 +13,6 @@ export declare const MIN_OPACITY_2 = 0.2;
|
|
|
13
13
|
export declare const MAX_OPACITY_2 = 0.6;
|
|
14
14
|
export declare const MIN_OPACITY_3 = 0.15;
|
|
15
15
|
export declare const MAX_OPACITY_3 = 0.4;
|
|
16
|
-
export declare function calculateOrbShadowVars(volume: number):
|
|
16
|
+
export declare function calculateOrbShadowVars(volume: number): Record<string, string>;
|
|
17
17
|
export declare function uuid(): string;
|
|
18
18
|
//# sourceMappingURL=constants.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../../src/components/VoiceOrb/constants.ts"],"names":[],"mappings":"AACA,eAAO,MAAM,SAAS,IAAI,CAAC;AAG3B,eAAO,MAAM,WAAW,IAAI,CAAC;AAG7B,eAAO,MAAM,eAAe,2BAA4B,CAAC;AAKzD,eAAO,MAAM,eAAe,IAAI,CAAC;AACjC,eAAO,MAAM,eAAe,KAAK,CAAC;AAClC,eAAO,MAAM,iBAAiB,IAAI,CAAC;AACnC,eAAO,MAAM,iBAAiB,KAAK,CAAC;AACpC,eAAO,MAAM,iBAAiB,IAAI,CAAC;AACnC,eAAO,MAAM,iBAAiB,KAAK,CAAC;AACpC,eAAO,MAAM,aAAa,MAAM,CAAC;AACjC,eAAO,MAAM,aAAa,MAAM,CAAC;AACjC,eAAO,MAAM,aAAa,MAAM,CAAC;AACjC,eAAO,MAAM,aAAa,MAAM,CAAC;AACjC,eAAO,MAAM,aAAa,OAAO,CAAC;AAClC,eAAO,MAAM,aAAa,MAAM,CAAC;AAEjC,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../../src/components/VoiceOrb/constants.ts"],"names":[],"mappings":"AACA,eAAO,MAAM,SAAS,IAAI,CAAC;AAG3B,eAAO,MAAM,WAAW,IAAI,CAAC;AAG7B,eAAO,MAAM,eAAe,2BAA4B,CAAC;AAKzD,eAAO,MAAM,eAAe,IAAI,CAAC;AACjC,eAAO,MAAM,eAAe,KAAK,CAAC;AAClC,eAAO,MAAM,iBAAiB,IAAI,CAAC;AACnC,eAAO,MAAM,iBAAiB,KAAK,CAAC;AACpC,eAAO,MAAM,iBAAiB,IAAI,CAAC;AACnC,eAAO,MAAM,iBAAiB,KAAK,CAAC;AACpC,eAAO,MAAM,aAAa,MAAM,CAAC;AACjC,eAAO,MAAM,aAAa,MAAM,CAAC;AACjC,eAAO,MAAM,aAAa,MAAM,CAAC;AACjC,eAAO,MAAM,aAAa,MAAM,CAAC;AACjC,eAAO,MAAM,aAAa,OAAO,CAAC;AAClC,eAAO,MAAM,aAAa,MAAM,CAAC;AAEjC,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CA4B7E;AAGD,wBAAgB,IAAI,WAQnB"}
|
|
@@ -47,9 +47,9 @@ function calculateOrbShadowVars(volume) {
|
|
|
47
47
|
'--shadow-blur-1': `${blur1}px`,
|
|
48
48
|
'--shadow-blur-2': `${blur2}px`,
|
|
49
49
|
'--shadow-blur-3': `${blur3}px`,
|
|
50
|
-
'--shadow-opacity-1': opacity1,
|
|
51
|
-
'--shadow-opacity-2': opacity2,
|
|
52
|
-
'--shadow-opacity-3': opacity3
|
|
50
|
+
'--shadow-opacity-1': String(opacity1),
|
|
51
|
+
'--shadow-opacity-2': String(opacity2),
|
|
52
|
+
'--shadow-opacity-3': String(opacity3)
|
|
53
53
|
};
|
|
54
54
|
}
|
|
55
55
|
|
|
@@ -9,12 +9,12 @@ export interface AudioAnalyzerOptions {
|
|
|
9
9
|
smoothingTimeConstant?: number;
|
|
10
10
|
/** FFT size for frequency analysis */
|
|
11
11
|
fftSize?: number;
|
|
12
|
+
/** Called on every rAF tick with computed intensities -- can use for imperative DOM updates */
|
|
13
|
+
onAnalyze?: (intensities: number[]) => void;
|
|
12
14
|
/** Minimum ms between state updates (throttle). Default 50 (~20fps). */
|
|
13
15
|
updateIntervalMs?: number;
|
|
14
16
|
}
|
|
15
17
|
export interface AudioAnalyzerResult {
|
|
16
|
-
/** Array of intensity values (0-1) for each bar */
|
|
17
|
-
barIntensities: number[];
|
|
18
18
|
/** Whether the audio stream is active */
|
|
19
19
|
isActive: boolean;
|
|
20
20
|
/** Any error that occurred */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useAudioAnalyzer.d.ts","sourceRoot":"","sources":["../../../src/hooks/useAudioAnalyzer/useAudioAnalyzer.tsx"],"names":[],"mappings":"AAGA,MAAM,WAAW,oBAAoB;IACnC,oCAAoC;IACpC,WAAW,EAAE,OAAO,CAAC;IACrB,2CAA2C;IAC3C,WAAW,CAAC,EAAE,WAAW,GAAG,IAAI,CAAC;IACjC,sDAAsD;IACtD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,8CAA8C;IAC9C,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B,sCAAsC;IACtC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,wEAAwE;IACxE,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED,MAAM,WAAW,mBAAmB;IAClC,
|
|
1
|
+
{"version":3,"file":"useAudioAnalyzer.d.ts","sourceRoot":"","sources":["../../../src/hooks/useAudioAnalyzer/useAudioAnalyzer.tsx"],"names":[],"mappings":"AAGA,MAAM,WAAW,oBAAoB;IACnC,oCAAoC;IACpC,WAAW,EAAE,OAAO,CAAC;IACrB,2CAA2C;IAC3C,WAAW,CAAC,EAAE,WAAW,GAAG,IAAI,CAAC;IACjC,sDAAsD;IACtD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,8CAA8C;IAC9C,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B,sCAAsC;IACtC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,+FAA+F;IAC/F,SAAS,CAAC,EAAE,CAAC,WAAW,EAAE,MAAM,EAAE,KAAK,IAAI,CAAC;IAC5C,wEAAwE;IACxE,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED,MAAM,WAAW,mBAAmB;IAClC,yCAAyC;IACzC,QAAQ,EAAE,OAAO,CAAC;IAClB,8BAA8B;IAC9B,KAAK,EAAE,KAAK,GAAG,IAAI,CAAC;CACrB;AAcD,eAAO,MAAM,gBAAgB;cAClB,oBAAoB,GAC5B,mBAAmB;;CAsLrB,CAAC"}
|
|
@@ -23,11 +23,13 @@ const useAudioAnalyzer = options => {
|
|
|
23
23
|
barCount = DEFAULT_BAR_COUNT,
|
|
24
24
|
smoothingTimeConstant = DEFAULT_SMOOTHING,
|
|
25
25
|
fftSize = DEFAULT_FFT_SIZE,
|
|
26
|
-
updateIntervalMs = DEFAULT_UPDATE_INTERVAL_MS
|
|
26
|
+
updateIntervalMs = DEFAULT_UPDATE_INTERVAL_MS,
|
|
27
|
+
onAnalyze
|
|
27
28
|
} = options;
|
|
28
|
-
const [barIntensities, setBarIntensities] = (0, _react.useState)(() => Array(barCount).fill(0));
|
|
29
29
|
const [isActive, setIsActive] = (0, _react.useState)(false);
|
|
30
30
|
const [error, setError] = (0, _react.useState)(null);
|
|
31
|
+
const onAnalyzeRef = (0, _react.useRef)(onAnalyze);
|
|
32
|
+
onAnalyzeRef.current = onAnalyze;
|
|
31
33
|
const audioContextRef = (0, _react.useRef)(null);
|
|
32
34
|
const analyzerRef = (0, _react.useRef)(null);
|
|
33
35
|
const sourceRef = (0, _react.useRef)(null);
|
|
@@ -84,7 +86,7 @@ const useAudioAnalyzer = options => {
|
|
|
84
86
|
const now = Date.now();
|
|
85
87
|
if (now - lastUpdateTimeRef.current >= updateIntervalMs) {
|
|
86
88
|
lastUpdateTimeRef.current = now;
|
|
87
|
-
|
|
89
|
+
onAnalyzeRef.current?.(intensities);
|
|
88
90
|
}
|
|
89
91
|
animationFrameRef.current = requestAnimationFrame(analyze);
|
|
90
92
|
};
|
|
@@ -115,7 +117,7 @@ const useAudioAnalyzer = options => {
|
|
|
115
117
|
audioContextRef.current = null;
|
|
116
118
|
}
|
|
117
119
|
setIsActive(false);
|
|
118
|
-
|
|
120
|
+
onAnalyzeRef.current?.(Array(barCount).fill(0));
|
|
119
121
|
}, [barCount]);
|
|
120
122
|
(0, _react.useEffect)(() => {
|
|
121
123
|
if (!isListening) {
|
|
@@ -162,7 +164,6 @@ const useAudioAnalyzer = options => {
|
|
|
162
164
|
return cleanup;
|
|
163
165
|
}, [isListening, externalStream, fftSize, smoothingTimeConstant, analyzeAudio, cleanup]);
|
|
164
166
|
return {
|
|
165
|
-
barIntensities,
|
|
166
167
|
isActive,
|
|
167
168
|
error
|
|
168
169
|
};
|
package/mcp/package.json
CHANGED