@convai/web-sdk 1.8.0-beta.7 → 1.8.0
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/README.md +44 -194
- package/dist/core/ConvaiClient.d.ts +1 -190
- package/dist/core/ConvaiClient.d.ts.map +1 -1
- package/dist/core/ConvaiClient.js +286 -1306
- package/dist/core/ConvaiClient.js.map +1 -1
- package/dist/core/MessageHandler.d.ts +1 -19
- package/dist/core/MessageHandler.d.ts.map +1 -1
- package/dist/core/MessageHandler.js +27 -378
- package/dist/core/MessageHandler.js.map +1 -1
- package/dist/core/connectRequest.d.ts +4 -17
- package/dist/core/connectRequest.d.ts.map +1 -1
- package/dist/core/connectRequest.js +17 -28
- package/dist/core/connectRequest.js.map +1 -1
- package/dist/core/index.d.ts +1 -6
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/index.js +1 -7
- package/dist/core/index.js.map +1 -1
- package/dist/core/logicalTurn.d.ts +6 -4
- package/dist/core/logicalTurn.d.ts.map +1 -1
- package/dist/core/logicalTurn.js +4 -29
- package/dist/core/logicalTurn.js.map +1 -1
- package/dist/core/modelOutput.d.ts.map +1 -1
- package/dist/core/modelOutput.js +2 -2
- package/dist/core/modelOutput.js.map +1 -1
- package/dist/core/types.d.ts +22 -860
- package/dist/core/types.d.ts.map +1 -1
- package/dist/core/types.js.map +1 -1
- package/dist/embed/chat-embed-v1.js +9 -10
- package/dist/embed/chat-embed-v1.js.map +4 -4
- package/dist/react/components/ConvaiWidget.d.ts.map +1 -1
- package/dist/react/components/ConvaiWidget.js +1 -6
- package/dist/react/components/ConvaiWidget.js.map +1 -1
- package/dist/react/components/rtc-widget/components/AudioVisualizer.d.ts.map +1 -1
- package/dist/react/components/rtc-widget/components/AudioVisualizer.js +1 -28
- package/dist/react/components/rtc-widget/components/AudioVisualizer.js.map +1 -1
- package/dist/react/components/rtc-widget/components/MarkdownRenderer.d.ts.map +1 -1
- package/dist/react/components/rtc-widget/components/MarkdownRenderer.js +44 -39
- package/dist/react/components/rtc-widget/components/MarkdownRenderer.js.map +1 -1
- package/dist/react/components/rtc-widget/components/conviComponents/VoiceModeOverlay.d.ts.map +1 -1
- package/dist/react/components/rtc-widget/components/conviComponents/VoiceModeOverlay.js +49 -93
- package/dist/react/components/rtc-widget/components/conviComponents/VoiceModeOverlay.js.map +1 -1
- package/dist/react/hooks/useConvaiClient.d.ts.map +1 -1
- package/dist/react/hooks/useConvaiClient.js +2 -17
- package/dist/react/hooks/useConvaiClient.js.map +1 -1
- package/dist/react/index.d.ts +1 -1
- package/dist/react/index.d.ts.map +1 -1
- package/dist/react/index.js +1 -1
- package/dist/react/index.js.map +1 -1
- package/dist/vanilla/AudioRenderer.d.ts +1 -3
- package/dist/vanilla/AudioRenderer.d.ts.map +1 -1
- package/dist/vanilla/AudioRenderer.js +2 -8
- package/dist/vanilla/AudioRenderer.js.map +1 -1
- package/dist/vanilla/ConvaiWidget.d.ts.map +1 -1
- package/dist/vanilla/ConvaiWidget.js +300 -994
- package/dist/vanilla/ConvaiWidget.js.map +1 -1
- package/dist/vanilla/WidgetEventSubscriptions.d.ts +1 -1
- package/dist/vanilla/WidgetEventSubscriptions.d.ts.map +1 -1
- package/dist/vanilla/WidgetEventSubscriptions.js +0 -5
- package/dist/vanilla/WidgetEventSubscriptions.js.map +1 -1
- package/dist/vanilla/icons.d.ts.map +1 -1
- package/dist/vanilla/icons.js +15 -62
- package/dist/vanilla/icons.js.map +1 -1
- package/dist/vanilla/index.d.ts +2 -4
- package/dist/vanilla/index.d.ts.map +1 -1
- package/dist/vanilla/index.js +1 -3
- package/dist/vanilla/index.js.map +1 -1
- package/dist/vanilla/styles.d.ts +1 -18
- package/dist/vanilla/styles.d.ts.map +1 -1
- package/dist/vanilla/styles.js +29 -129
- package/dist/vanilla/styles.js.map +1 -1
- package/dist/vanilla/types.d.ts +0 -74
- package/dist/vanilla/types.d.ts.map +1 -1
- package/dist/vanilla/types.js.map +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.d.ts.map +1 -1
- package/dist/version.js +1 -1
- package/dist/version.js.map +1 -1
- package/package.json +8 -13
- package/dist/core/CharacterRoster.d.ts +0 -84
- package/dist/core/CharacterRoster.d.ts.map +0 -1
- package/dist/core/CharacterRoster.js +0 -348
- package/dist/core/CharacterRoster.js.map +0 -1
- package/dist/core/CharacterVersionManager.d.ts +0 -100
- package/dist/core/CharacterVersionManager.d.ts.map +0 -1
- package/dist/core/CharacterVersionManager.js +0 -227
- package/dist/core/CharacterVersionManager.js.map +0 -1
- package/dist/core/ConvaiRoomError.d.ts +0 -48
- package/dist/core/ConvaiRoomError.d.ts.map +0 -1
- package/dist/core/ConvaiRoomError.js +0 -111
- package/dist/core/ConvaiRoomError.js.map +0 -1
- package/dist/core/SSESession.d.ts +0 -59
- package/dist/core/SSESession.d.ts.map +0 -1
- package/dist/core/SSESession.js +0 -289
- package/dist/core/SSESession.js.map +0 -1
- package/dist/core/characterReference.d.ts +0 -40
- package/dist/core/characterReference.d.ts.map +0 -1
- package/dist/core/characterReference.js +0 -72
- package/dist/core/characterReference.js.map +0 -1
- package/dist/core/rosterRequest.d.ts +0 -57
- package/dist/core/rosterRequest.d.ts.map +0 -1
- package/dist/core/rosterRequest.js +0 -210
- package/dist/core/rosterRequest.js.map +0 -1
- package/dist/utils/inlineMarkdown.d.ts +0 -38
- package/dist/utils/inlineMarkdown.d.ts.map +0 -1
- package/dist/utils/inlineMarkdown.js +0 -106
- package/dist/utils/inlineMarkdown.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MarkdownRenderer.js","sourceRoot":"","sources":["../../../../../src/react/components/rtc-widget/components/MarkdownRenderer.tsx"],"names":[],"mappings":";AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"MarkdownRenderer.js","sourceRoot":"","sources":["../../../../../src/react/components/rtc-widget/components/MarkdownRenderer.tsx"],"names":[],"mappings":"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","sourcesContent":["import React from \"react\";\n\ninterface MarkdownRendererProps {\n text: string;\n}\n\nexport const MarkdownRenderer: React.FC<MarkdownRendererProps> = ({ text }) => {\n // Convert markdown to JSX elements\n const renderMarkdown = (input: string): React.ReactNode => {\n if (!input) return null;\n\n // Handle both actual newlines and \\n escape sequences\n // Replace literal \\n strings with actual newlines\n const normalizedText = input.replace(/\\\\n/g, '\\n');\n \n // Split by actual newlines\n const lines = normalizedText.split('\\n');\n \n return lines.map((line, lineIndex) => {\n // Process markdown within each line\n const processLine = (text: string): React.ReactNode[] => {\n const parts: React.ReactNode[] = [];\n let remaining = text;\n let keyCounter = 0;\n\n // Process bold and italic markdown\n // Bold: **text** or __text__\n // Italic: *text* or _text_\n const markdownRegex = /(\\*\\*|__)(.*?)\\1|\\*([^*]+)\\*|_([^_]+)_/g;\n let lastIndex = 0;\n let match;\n\n while ((match = markdownRegex.exec(remaining)) !== null) {\n // Add text before the match\n if (match.index > lastIndex) {\n const textBefore = remaining.substring(lastIndex, match.index);\n if (textBefore) {\n parts.push(\n <React.Fragment key={`text-${lineIndex}-${keyCounter++}`}>\n {textBefore}\n </React.Fragment>\n );\n }\n }\n\n // Determine if it's bold or italic\n if (match[1] && match[2]) {\n // Bold text (** or __)\n parts.push(\n <strong key={`bold-${lineIndex}-${keyCounter++}`}>\n {match[2]}\n </strong>\n );\n } else if (match[3]) {\n // Italic text (*)\n parts.push(\n <em key={`italic-${lineIndex}-${keyCounter++}`}>\n {match[3]}\n </em>\n );\n } else if (match[4]) {\n // Italic text (_)\n parts.push(\n <em key={`italic-${lineIndex}-${keyCounter++}`}>\n {match[4]}\n </em>\n );\n }\n\n lastIndex = match.index + match[0].length;\n }\n\n // Add remaining text\n if (lastIndex < remaining.length) {\n const textAfter = remaining.substring(lastIndex);\n if (textAfter) {\n parts.push(\n <React.Fragment key={`text-${lineIndex}-${keyCounter++}`}>\n {textAfter}\n </React.Fragment>\n );\n }\n }\n\n return parts;\n };\n\n const processedLine = processLine(line);\n\n // Handle empty lines (creates paragraph spacing)\n if (line.trim() === \"\" && lineIndex > 0) {\n return <br key={`br-${lineIndex}`} />;\n }\n\n // Return the line with line break\n return (\n <React.Fragment key={`line-${lineIndex}`}>\n {processedLine.length > 0 ? processedLine : line}\n {lineIndex < lines.length - 1 && <br />}\n </React.Fragment>\n );\n });\n };\n\n return <div style={{ whiteSpace: 'pre-wrap', wordWrap: 'break-word' }}>{renderMarkdown(text)}</div>;\n};\n\n"]}
|
package/dist/react/components/rtc-widget/components/conviComponents/VoiceModeOverlay.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"VoiceModeOverlay.d.ts","sourceRoot":"","sources":["../../../../../../src/react/components/rtc-widget/components/conviComponents/VoiceModeOverlay.tsx"],"names":[],"mappings":"AAKA,OAAO,EAAE,IAAI,EAAE,MAAM,gBAAgB,CAAC;AAEtC,UAAU,qBAAqB;IAC7B,QAAQ,EAAE,OAAO,CAAC;IAClB,SAAS,EAAE,OAAO,CAAC;IACnB,2EAA2E;IAC3E,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,YAAY,CAAC,EAAE,GAAG,CAAC;IACnB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,IAAI,CAAC,EAAE,IAAI,GAAG,IAAI,CAAC;CACpB;AAED,eAAO,MAAM,gBAAgB,GAAI,0FAQ9B,qBAAqB,
|
|
1
|
+
{"version":3,"file":"VoiceModeOverlay.d.ts","sourceRoot":"","sources":["../../../../../../src/react/components/rtc-widget/components/conviComponents/VoiceModeOverlay.tsx"],"names":[],"mappings":"AAKA,OAAO,EAAE,IAAI,EAAE,MAAM,gBAAgB,CAAC;AAEtC,UAAU,qBAAqB;IAC7B,QAAQ,EAAE,OAAO,CAAC;IAClB,SAAS,EAAE,OAAO,CAAC;IACnB,2EAA2E;IAC3E,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,YAAY,CAAC,EAAE,GAAG,CAAC;IACnB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,IAAI,CAAC,EAAE,IAAI,GAAG,IAAI,CAAC;CACpB;AAED,eAAO,MAAM,gBAAgB,GAAI,0FAQ9B,qBAAqB,4CA8YvB,CAAC"}
|
|
@@ -6,91 +6,10 @@ import { iosTransitions } from "../../styles/framerConfig.js";
|
|
|
6
6
|
import { AudioVisualizer } from "../AudioVisualizer.js";
|
|
7
7
|
export const VoiceModeOverlay = ({ isActive, isTalking, isListening = false, convaiClient, characterImage, characterName = "Character", room, }) => {
|
|
8
8
|
const barsCount = 40; // Number of bars for user microphone waveform
|
|
9
|
-
|
|
10
|
-
// frame re-rendered the whole overlay (reconcile + style recalc +
|
|
11
|
-
// framer-motion filter retarget) ~60x/s — ~30ms main-thread tasks that
|
|
12
|
-
// visibly juddered the host page's 3D scene whenever voice mode was
|
|
13
|
-
// open. Levels live in a ref and the SVG paths are updated directly.
|
|
14
|
-
const audioLevelsRef = useRef(Array(barsCount).fill(0));
|
|
15
|
-
const waveCanvasRef = useRef(null);
|
|
9
|
+
const [audioLevels, setAudioLevels] = useState(Array(barsCount).fill(0));
|
|
16
10
|
const analyzerRef = useRef(null);
|
|
17
11
|
const animationFrameRef = useRef(undefined);
|
|
18
12
|
const audioContextRef = useRef(null);
|
|
19
|
-
// Paint the three waves onto a small canvas — no React, no SVG filters.
|
|
20
|
-
// (The previous SVG version re-rasterized a 35px drop-shadow blur every
|
|
21
|
-
// frame; that GPU paint alone pushed the host page to ~30fps.) Glow is
|
|
22
|
-
// approximated with a wide low-alpha understroke, which is ~free.
|
|
23
|
-
// Painting is THROTTLED to 30fps and skipped entirely while silent:
|
|
24
|
-
// every canvas update forces the compositor to re-blend the whole
|
|
25
|
-
// panel stack over the host WebGL canvas, so idle repaints are pure
|
|
26
|
-
// waste that judders the 3D scene.
|
|
27
|
-
const waveFrameParityRef = useRef(0);
|
|
28
|
-
const waveWasSilentRef = useRef(false);
|
|
29
|
-
const drawWaves = () => {
|
|
30
|
-
waveFrameParityRef.current ^= 1;
|
|
31
|
-
if (waveFrameParityRef.current)
|
|
32
|
-
return; // 30fps is plenty for a waveform
|
|
33
|
-
const canvas = waveCanvasRef.current;
|
|
34
|
-
if (!canvas)
|
|
35
|
-
return;
|
|
36
|
-
{
|
|
37
|
-
const lv = audioLevelsRef.current;
|
|
38
|
-
let sum = 0;
|
|
39
|
-
for (let i = 0; i < lv.length; i++)
|
|
40
|
-
sum += lv[i];
|
|
41
|
-
const silent = sum / lv.length < 0.012;
|
|
42
|
-
if (silent && waveWasSilentRef.current)
|
|
43
|
-
return; // static line already drawn
|
|
44
|
-
waveWasSilentRef.current = silent;
|
|
45
|
-
}
|
|
46
|
-
const dpr = Math.min(window.devicePixelRatio || 1, 2);
|
|
47
|
-
if (canvas.width !== 250 * dpr) {
|
|
48
|
-
canvas.width = 250 * dpr;
|
|
49
|
-
canvas.height = 80 * dpr;
|
|
50
|
-
}
|
|
51
|
-
const ctx = canvas.getContext("2d");
|
|
52
|
-
if (!ctx)
|
|
53
|
-
return;
|
|
54
|
-
ctx.setTransform(dpr, 0, 0, dpr, 0, 0);
|
|
55
|
-
ctx.clearRect(0, 0, 250, 80);
|
|
56
|
-
const audioLevels = audioLevelsRef.current;
|
|
57
|
-
const centerY = 40;
|
|
58
|
-
const waveWidth = 250;
|
|
59
|
-
const segments = barsCount;
|
|
60
|
-
const avgLevel = audioLevels.reduce((sum, level) => sum + level, 0) / audioLevels.length;
|
|
61
|
-
const waveColors = [
|
|
62
|
-
aeroTheme.colors.convai.light,
|
|
63
|
-
aeroTheme.colors.convai.light,
|
|
64
|
-
"#34d399",
|
|
65
|
-
];
|
|
66
|
-
ctx.lineCap = "round";
|
|
67
|
-
ctx.lineJoin = "round";
|
|
68
|
-
for (let waveIndex = 2; waveIndex >= 0; waveIndex--) {
|
|
69
|
-
ctx.beginPath();
|
|
70
|
-
for (let i = 0; i <= segments; i++) {
|
|
71
|
-
const x = (i / segments) * waveWidth;
|
|
72
|
-
const levelIndex = Math.floor((i / segments) * (audioLevels.length - 1));
|
|
73
|
-
const level = audioLevels[levelIndex] || 0;
|
|
74
|
-
const phase = (Date.now() / 500 + i * 0.2 + waveIndex * 1.5) % (Math.PI * 2);
|
|
75
|
-
const baseAmplitude = avgLevel > 0.05 ? 2 + waveIndex * 1.5 : 0;
|
|
76
|
-
const amplitude = baseAmplitude + level * (25 - baseAmplitude);
|
|
77
|
-
const y = centerY + Math.sin(phase) * amplitude;
|
|
78
|
-
if (i === 0)
|
|
79
|
-
ctx.moveTo(x, y);
|
|
80
|
-
else
|
|
81
|
-
ctx.lineTo(x, y);
|
|
82
|
-
}
|
|
83
|
-
// glow understroke scaled by level, then the crisp line on top
|
|
84
|
-
ctx.strokeStyle = waveColors[waveIndex];
|
|
85
|
-
ctx.globalAlpha = 0.18 * (0.3 + avgLevel);
|
|
86
|
-
ctx.lineWidth = (2.5 - waveIndex * 0.4) + 8 * avgLevel + 3;
|
|
87
|
-
ctx.stroke();
|
|
88
|
-
ctx.globalAlpha = 0.95 - waveIndex * 0.15;
|
|
89
|
-
ctx.lineWidth = 2.5 - waveIndex * 0.4;
|
|
90
|
-
ctx.stroke();
|
|
91
|
-
}
|
|
92
|
-
ctx.globalAlpha = 1;
|
|
93
|
-
};
|
|
94
13
|
// Setup audio analysis for USER microphone input ONLY
|
|
95
14
|
useEffect(() => {
|
|
96
15
|
if (!isActive) {
|
|
@@ -98,8 +17,7 @@ export const VoiceModeOverlay = ({ isActive, isTalking, isListening = false, con
|
|
|
98
17
|
if (animationFrameRef.current) {
|
|
99
18
|
cancelAnimationFrame(animationFrameRef.current);
|
|
100
19
|
}
|
|
101
|
-
|
|
102
|
-
drawWaves();
|
|
20
|
+
setAudioLevels(Array(barsCount).fill(0));
|
|
103
21
|
return;
|
|
104
22
|
}
|
|
105
23
|
let stream = null;
|
|
@@ -132,17 +50,17 @@ export const VoiceModeOverlay = ({ isActive, isTalking, isListening = false, con
|
|
|
132
50
|
const rms = Math.sqrt(sum / dataArray.length);
|
|
133
51
|
// Apply some scaling and clamping
|
|
134
52
|
const volume = Math.min(1, rms * 3); // Boost sensitivity
|
|
135
|
-
// Create left-to-right wave effect
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
53
|
+
// Create left-to-right wave effect
|
|
54
|
+
const levels = Array(barsCount)
|
|
55
|
+
.fill(0)
|
|
56
|
+
.map((_, i) => {
|
|
57
|
+
// Progressive wave from left to right
|
|
140
58
|
const position = i / barsCount; // 0 to 1 from left to right
|
|
141
59
|
const wavePhase = Date.now() / 300 + position * Math.PI * 2;
|
|
142
60
|
const waveVariation = Math.sin(wavePhase) * 0.15 + 0.85; // 0.7 to 1.0
|
|
143
|
-
|
|
144
|
-
}
|
|
145
|
-
|
|
61
|
+
return volume * waveVariation;
|
|
62
|
+
});
|
|
63
|
+
setAudioLevels(levels);
|
|
146
64
|
animationFrameRef.current = requestAnimationFrame(updateLevels);
|
|
147
65
|
};
|
|
148
66
|
updateLevels();
|
|
@@ -282,7 +200,45 @@ export const VoiceModeOverlay = ({ isActive, isTalking, isListening = false, con
|
|
|
282
200
|
width: "250px",
|
|
283
201
|
height: "80px",
|
|
284
202
|
position: "relative",
|
|
285
|
-
}, children: _jsx("
|
|
203
|
+
}, children: _jsx("svg", { width: "250", height: "80", style: {
|
|
204
|
+
overflow: "visible",
|
|
205
|
+
}, children: [0, 1, 2].map((waveIndex) => {
|
|
206
|
+
// Calculate wave path based on audio levels
|
|
207
|
+
const points = [];
|
|
208
|
+
const centerY = 40;
|
|
209
|
+
const waveWidth = 250;
|
|
210
|
+
const segments = barsCount;
|
|
211
|
+
// Calculate average audio level for glow intensity
|
|
212
|
+
const avgLevel = audioLevels.reduce((sum, level) => sum + level, 0) / audioLevels.length;
|
|
213
|
+
const glowIntensity = avgLevel * 35; // 0-35px glow (increased from 20)
|
|
214
|
+
// Green color variants for each wave
|
|
215
|
+
const waveColors = [
|
|
216
|
+
aeroTheme.colors.convai.light, // Bright green - front wave
|
|
217
|
+
aeroTheme.colors.convai.light, // Medium green - mid wave
|
|
218
|
+
"#34d399", // Medium-light green - back wave (lighter than dark)
|
|
219
|
+
];
|
|
220
|
+
for (let i = 0; i <= segments; i++) {
|
|
221
|
+
const x = (i / segments) * waveWidth;
|
|
222
|
+
const levelIndex = Math.floor((i / segments) * (audioLevels.length - 1));
|
|
223
|
+
const level = audioLevels[levelIndex] || 0;
|
|
224
|
+
// When idle (low audio), show straight line
|
|
225
|
+
// When active, create waves with increased amplitude
|
|
226
|
+
const phase = (Date.now() / 500 + i * 0.2 + waveIndex * 1.5) % (Math.PI * 2);
|
|
227
|
+
// Only add wave motion when there's audio
|
|
228
|
+
// Idle: amplitude ~0 (straight line)
|
|
229
|
+
// Active: amplitude up to 25px (increased from 15)
|
|
230
|
+
const baseAmplitude = avgLevel > 0.05 ? (2 + waveIndex * 1.5) : 0;
|
|
231
|
+
const amplitude = baseAmplitude + level * (25 - baseAmplitude);
|
|
232
|
+
const y = centerY + Math.sin(phase) * amplitude;
|
|
233
|
+
points.push(`${x},${y}`);
|
|
234
|
+
}
|
|
235
|
+
return (_jsx(motion.path, { d: `M ${points.join(" L ")}`, fill: "none", stroke: waveColors[waveIndex], strokeWidth: 2.5 - waveIndex * 0.4, strokeLinecap: "round", strokeLinejoin: "round", opacity: 0.95 - waveIndex * 0.15, animate: {
|
|
236
|
+
filter: `drop-shadow(0 0 ${glowIntensity}px ${waveColors[waveIndex]}) blur(${waveIndex * 0.3}px)`,
|
|
237
|
+
}, transition: {
|
|
238
|
+
duration: 0.1,
|
|
239
|
+
ease: "easeOut",
|
|
240
|
+
} }, waveIndex));
|
|
241
|
+
}) }) })) }), _jsxs(motion.div, { initial: { opacity: 0, y: 10 }, animate: { opacity: 1, y: 0 }, transition: { delay: 0.2, ...iosTransitions.fadePop }, children: [_jsx("div", { style: {
|
|
286
242
|
fontSize: "16px",
|
|
287
243
|
fontWeight: 600,
|
|
288
244
|
color: aeroTheme.colors.text.primary,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"VoiceModeOverlay.js","sourceRoot":"","sources":["../../../../../../src/react/components/rtc-widget/components/conviComponents/VoiceModeOverlay.tsx"],"names":[],"mappings":"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","sourcesContent":["import React, { useEffect, useRef, useState } from \"react\";\nimport { motion, AnimatePresence } from \"framer-motion\";\nimport { aeroTheme } from \"../../styles/theme\";\nimport { iosTransitions } from \"../../styles/framerConfig\";\nimport { AudioVisualizer } from \"../AudioVisualizer\";\nimport { Room } from \"livekit-client\";\n\ninterface VoiceModeOverlayProps {\n isActive: boolean;\n isTalking: boolean;\n /** When true (user is speaking, from server), show \"Listening...\" label */\n isListening?: boolean;\n convaiClient?: any; // Reference to convai client for audio analysis\n characterImage?: string;\n characterName?: string;\n room?: Room | null;\n}\n\nexport const VoiceModeOverlay = ({\n isActive,\n isTalking,\n isListening = false,\n convaiClient,\n characterImage,\n characterName = \"Character\",\n room,\n}: VoiceModeOverlayProps) => {\n const barsCount = 40; // Number of bars for user microphone waveform\n // PERF: the waveform is driven OUTSIDE React. A setState per animation\n // frame re-rendered the whole overlay (reconcile + style recalc +\n // framer-motion filter retarget) ~60x/s — ~30ms main-thread tasks that\n // visibly juddered the host page's 3D scene whenever voice mode was\n // open. Levels live in a ref and the SVG paths are updated directly.\n const audioLevelsRef = useRef<number[]>(Array(barsCount).fill(0));\n const waveCanvasRef = useRef<HTMLCanvasElement | null>(null);\n const analyzerRef = useRef<AnalyserNode | null>(null);\n const animationFrameRef = useRef<number | undefined>(undefined);\n const audioContextRef = useRef<AudioContext | null>(null);\n\n // Paint the three waves onto a small canvas — no React, no SVG filters.\n // (The previous SVG version re-rasterized a 35px drop-shadow blur every\n // frame; that GPU paint alone pushed the host page to ~30fps.) Glow is\n // approximated with a wide low-alpha understroke, which is ~free.\n // Painting is THROTTLED to 30fps and skipped entirely while silent:\n // every canvas update forces the compositor to re-blend the whole\n // panel stack over the host WebGL canvas, so idle repaints are pure\n // waste that judders the 3D scene.\n const waveFrameParityRef = useRef(0);\n const waveWasSilentRef = useRef(false);\n const drawWaves = () => {\n waveFrameParityRef.current ^= 1;\n if (waveFrameParityRef.current) return; // 30fps is plenty for a waveform\n const canvas = waveCanvasRef.current;\n if (!canvas) return;\n {\n const lv = audioLevelsRef.current;\n let sum = 0;\n for (let i = 0; i < lv.length; i++) sum += lv[i];\n const silent = sum / lv.length < 0.012;\n if (silent && waveWasSilentRef.current) return; // static line already drawn\n waveWasSilentRef.current = silent;\n }\n const dpr = Math.min(window.devicePixelRatio || 1, 2);\n if (canvas.width !== 250 * dpr) {\n canvas.width = 250 * dpr;\n canvas.height = 80 * dpr;\n }\n const ctx = canvas.getContext(\"2d\");\n if (!ctx) return;\n ctx.setTransform(dpr, 0, 0, dpr, 0, 0);\n ctx.clearRect(0, 0, 250, 80);\n const audioLevels = audioLevelsRef.current;\n const centerY = 40;\n const waveWidth = 250;\n const segments = barsCount;\n const avgLevel =\n audioLevels.reduce((sum, level) => sum + level, 0) / audioLevels.length;\n const waveColors = [\n aeroTheme.colors.convai.light,\n aeroTheme.colors.convai.light,\n \"#34d399\",\n ];\n ctx.lineCap = \"round\";\n ctx.lineJoin = \"round\";\n for (let waveIndex = 2; waveIndex >= 0; waveIndex--) {\n ctx.beginPath();\n for (let i = 0; i <= segments; i++) {\n const x = (i / segments) * waveWidth;\n const levelIndex = Math.floor((i / segments) * (audioLevels.length - 1));\n const level = audioLevels[levelIndex] || 0;\n const phase = (Date.now() / 500 + i * 0.2 + waveIndex * 1.5) % (Math.PI * 2);\n const baseAmplitude = avgLevel > 0.05 ? 2 + waveIndex * 1.5 : 0;\n const amplitude = baseAmplitude + level * (25 - baseAmplitude);\n const y = centerY + Math.sin(phase) * amplitude;\n if (i === 0) ctx.moveTo(x, y);\n else ctx.lineTo(x, y);\n }\n // glow understroke scaled by level, then the crisp line on top\n ctx.strokeStyle = waveColors[waveIndex];\n ctx.globalAlpha = 0.18 * (0.3 + avgLevel);\n ctx.lineWidth = (2.5 - waveIndex * 0.4) + 8 * avgLevel + 3;\n ctx.stroke();\n ctx.globalAlpha = 0.95 - waveIndex * 0.15;\n ctx.lineWidth = 2.5 - waveIndex * 0.4;\n ctx.stroke();\n }\n ctx.globalAlpha = 1;\n };\n\n // Setup audio analysis for USER microphone input ONLY\n useEffect(() => {\n if (!isActive) {\n // Clean up when user is not speaking\n if (animationFrameRef.current) {\n cancelAnimationFrame(animationFrameRef.current);\n }\n audioLevelsRef.current = Array(barsCount).fill(0);\n drawWaves();\n return;\n }\n\n let stream: MediaStream | null = null;\n\n const setupAudioAnalysis = async () => {\n try {\n // Get microphone stream\n stream = await navigator.mediaDevices.getUserMedia({ audio: true });\n\n // Create audio context and analyzer\n const audioContext = new (window.AudioContext ||\n (window as any).webkitAudioContext)();\n audioContextRef.current = audioContext;\n\n const analyzer = audioContext.createAnalyser();\n analyzer.fftSize = 256; // Better resolution for time domain\n analyzer.smoothingTimeConstant = 0.7;\n analyzerRef.current = analyzer;\n\n const source = audioContext.createMediaStreamSource(stream);\n source.connect(analyzer);\n\n const dataArray = new Uint8Array(analyzer.fftSize);\n\n const updateLevels = () => {\n if (!analyzerRef.current) return;\n\n // Use time domain data (waveform) instead of frequency\n analyzer.getByteTimeDomainData(dataArray);\n\n // Calculate RMS (Root Mean Square) for volume\n let sum = 0;\n for (let i = 0; i < dataArray.length; i++) {\n const normalized = (dataArray[i] - 128) / 128; // Center around 0\n sum += normalized * normalized;\n }\n const rms = Math.sqrt(sum / dataArray.length);\n\n // Apply some scaling and clamping\n const volume = Math.min(1, rms * 3); // Boost sensitivity\n\n // Create left-to-right wave effect — write into the ref and paint\n // the SVG directly (no setState: a per-frame React render here\n // visibly juddered the host page).\n const levels = audioLevelsRef.current;\n for (let i = 0; i < barsCount; i++) {\n const position = i / barsCount; // 0 to 1 from left to right\n const wavePhase = Date.now() / 300 + position * Math.PI * 2;\n const waveVariation = Math.sin(wavePhase) * 0.15 + 0.85; // 0.7 to 1.0\n levels[i] = volume * waveVariation;\n }\n drawWaves();\n animationFrameRef.current = requestAnimationFrame(updateLevels);\n };\n\n updateLevels();\n } catch (error) {\n console.error(\"Error setting up audio analysis:\", error);\n }\n };\n\n setupAudioAnalysis();\n\n return () => {\n if (animationFrameRef.current) {\n cancelAnimationFrame(animationFrameRef.current);\n }\n if (stream) {\n stream.getTracks().forEach((track) => track.stop());\n }\n if (audioContextRef.current) {\n audioContextRef.current.close();\n }\n };\n }, [isActive, barsCount]);\n\n const [isBotSpeaking, setIsBotSpeaking] = useState(false);\n\n return (\n <div\n style={{\n position: \"absolute\",\n top: \"50%\",\n left: \"50%\",\n transform: \"translate(-50%, -50%)\",\n textAlign: \"center\",\n padding: \"1rem\",\n zIndex: 10,\n pointerEvents: \"none\",\n display: \"flex\",\n flexDirection: \"column\",\n alignItems: \"center\",\n gap: \"2rem\",\n }}\n >\n {/* Character Avatar with Audio Visualizer */}\n <div\n style={{\n position: \"relative\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n isolation: \"isolate\", // Create stacking context\n }}\n >\n {/* Audio Visualizer - positioned absolutely behind the character */}\n {room && (\n <motion.div\n initial={{ opacity: 0, scale: 0.8 }}\n animate={{\n opacity: isBotSpeaking ? 1 : 0,\n scale: isBotSpeaking ? 1 : 0.8,\n }}\n transition={iosTransitions.fadePop}\n style={{\n position: \"absolute\",\n width: \"220px\",\n height: \"220px\",\n zIndex: -1, // Negative z-index to ensure it's behind\n pointerEvents: \"none\",\n }}\n >\n <AudioVisualizer\n room={room}\n size={220}\n color={aeroTheme.colors.convai.light}\n opacity={0.6}\n avatarRadius={110}\n barCount={48}\n onSpeakingChange={setIsBotSpeaking}\n />\n </motion.div>\n )}\n\n {/* Character Image - pops from header to center */}\n <motion.div\n key=\"center-avatar\" // Use key instead of layoutId for independent animation\n initial={{ scale: 0.8, opacity: 0 }}\n animate={{ scale: 1, opacity: 1 }}\n exit={{ scale: 0.8, opacity: 0 }}\n transition={iosTransitions.fadePop}\n style={{\n position: \"relative\",\n zIndex: 10, // Higher z-index to be clearly on top\n borderRadius: \"50%\",\n overflow: \"visible\", // Changed to visible to show glow\n boxShadow: \"0 8px 32px rgba(0, 0, 0, 0.3)\",\n background: \"white\",\n }}\n >\n {/* Animated liquid gradient - Layer 1 */}\n <motion.div\n animate={{\n rotate: [0, 360],\n scale: isBotSpeaking ? [1, 1.05, 1.02, 1.05, 1] : 1,\n }}\n transition={{\n rotate: { duration: 20, repeat: Infinity, ease: \"linear\" },\n scale: { duration: 3, repeat: Infinity, ease: \"easeInOut\" },\n }}\n style={{\n position: \"absolute\",\n width: \"126px\",\n height: \"126px\",\n borderRadius: \"50%\",\n background: `\n conic-gradient(\n from 0deg,\n ${aeroTheme.colors.convai.light}00 0%,\n ${aeroTheme.colors.convai.light}40 25%,\n ${aeroTheme.colors.convai.dark}60 50%,\n ${aeroTheme.colors.convai.light}40 75%,\n ${aeroTheme.colors.convai.light}00 100%\n )\n `,\n opacity: 0.8,\n filter: \"blur(8px)\",\n zIndex: -2,\n }}\n />\n\n {/* Animated liquid gradient - Layer 2 (counter-rotating) */}\n <motion.div\n animate={{\n rotate: [360, 0],\n scale: isBotSpeaking ? [1, 1.03, 1.06, 1.03, 1] : 1,\n }}\n transition={{\n rotate: { duration: 15, repeat: Infinity, ease: \"linear\" },\n scale: { duration: 2.5, repeat: Infinity, ease: \"easeInOut\" },\n }}\n style={{\n position: \"absolute\",\n width: \"126px\",\n height: \"126px\",\n borderRadius: \"50%\",\n background: `\n radial-gradient(\n ellipse 80% 100% at 30% 40%,\n ${aeroTheme.colors.convai.light}50,\n ${aeroTheme.colors.convai.light}30 40%,\n transparent 70%\n ),\n radial-gradient(\n ellipse 80% 100% at 70% 60%,\n ${aeroTheme.colors.convai.dark}50,\n ${aeroTheme.colors.convai.dark}30 40%,\n transparent 70%\n )\n `,\n opacity: 0.9,\n filter: \"blur(6px)\",\n zIndex: -1,\n }}\n />\n\n {/* Character container with border */}\n <div\n style={{\n position: \"relative\",\n borderRadius: \"50%\",\n overflow: \"hidden\",\n border: `3px solid rgba(255, 255, 255, 0.2)`,\n }}\n >\n {characterImage ? (\n <motion.img\n src={characterImage}\n alt={characterName}\n animate={{\n scale: isBotSpeaking ? 1.05 : 1,\n }}\n transition={{\n duration: 0.3,\n ease: \"easeInOut\",\n }}\n style={{\n width: \"120px\",\n height: \"120px\",\n objectFit: \"cover\",\n display: \"block\",\n }}\n />\n ) : (\n <div\n style={{\n width: \"120px\",\n height: \"120px\",\n backgroundColor: aeroTheme.colors.convai.light + \"20\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n fontSize: \"48px\",\n color: aeroTheme.colors.convai.light,\n fontWeight: 600,\n }}\n >\n {characterName[0]?.toUpperCase() || \"C\"}\n </div>\n )}\n </div>\n </motion.div>\n </div>\n\n {/* Sound Wave Lines - USER microphone ONLY */}\n <AnimatePresence>\n {isActive && (\n <motion.div\n initial={{ opacity: 0, y: 20 }}\n animate={{ opacity: 1, y: 0 }}\n exit={{ opacity: 0, y: -20 }}\n transition={iosTransitions.fadePop}\n style={{\n width: \"250px\",\n height: \"80px\",\n position: \"relative\",\n }}\n >\n {/* Wave lines painted by drawWaves() (rAF-driven canvas) — the\n previous SVG + animated drop-shadow filter re-rasterized a\n blurred layer every frame and juddered the host page. */}\n <canvas\n ref={waveCanvasRef}\n style={{ width: \"250px\", height: \"80px\" }}\n />\n </motion.div>\n )}\n </AnimatePresence>\n\n {/* Status Text */}\n <motion.div\n initial={{ opacity: 0, y: 10 }}\n animate={{ opacity: 1, y: 0 }}\n transition={{ delay: 0.2, ...iosTransitions.fadePop }}\n >\n <div\n style={{\n fontSize: \"16px\",\n fontWeight: 600,\n color: aeroTheme.colors.text.primary,\n marginBottom: \"0.5rem\",\n }}\n >\n {isTalking\n ? `${characterName} Speaking...`\n : isListening || isActive\n ? \"Listening...\"\n : \"Voice Mode\"}\n </div>\n <div\n style={{\n fontSize: \"13px\",\n color: aeroTheme.colors.text.secondary,\n }}\n >\n {isListening || isActive || isTalking ? \"Audio active\" : \"Tap microphone to talk\"}\n </div>\n </motion.div>\n </div>\n );\n};\n"]}
|
|
1
|
+
{"version":3,"file":"VoiceModeOverlay.js","sourceRoot":"","sources":["../../../../../../src/react/components/rtc-widget/components/conviComponents/VoiceModeOverlay.tsx"],"names":[],"mappings":"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","sourcesContent":["import React, { useEffect, useRef, useState } from \"react\";\nimport { motion, AnimatePresence } from \"framer-motion\";\nimport { aeroTheme } from \"../../styles/theme\";\nimport { iosTransitions } from \"../../styles/framerConfig\";\nimport { AudioVisualizer } from \"../AudioVisualizer\";\nimport { Room } from \"livekit-client\";\n\ninterface VoiceModeOverlayProps {\n isActive: boolean;\n isTalking: boolean;\n /** When true (user is speaking, from server), show \"Listening...\" label */\n isListening?: boolean;\n convaiClient?: any; // Reference to convai client for audio analysis\n characterImage?: string;\n characterName?: string;\n room?: Room | null;\n}\n\nexport const VoiceModeOverlay = ({\n isActive,\n isTalking,\n isListening = false,\n convaiClient,\n characterImage,\n characterName = \"Character\",\n room,\n}: VoiceModeOverlayProps) => {\n const barsCount = 40; // Number of bars for user microphone waveform\n const [audioLevels, setAudioLevels] = useState<number[]>(\n Array(barsCount).fill(0) as number[],\n );\n const analyzerRef = useRef<AnalyserNode | null>(null);\n const animationFrameRef = useRef<number | undefined>(undefined);\n const audioContextRef = useRef<AudioContext | null>(null);\n\n // Setup audio analysis for USER microphone input ONLY\n useEffect(() => {\n if (!isActive) {\n // Clean up when user is not speaking\n if (animationFrameRef.current) {\n cancelAnimationFrame(animationFrameRef.current);\n }\n setAudioLevels(Array(barsCount).fill(0));\n return;\n }\n\n let stream: MediaStream | null = null;\n\n const setupAudioAnalysis = async () => {\n try {\n // Get microphone stream\n stream = await navigator.mediaDevices.getUserMedia({ audio: true });\n\n // Create audio context and analyzer\n const audioContext = new (window.AudioContext ||\n (window as any).webkitAudioContext)();\n audioContextRef.current = audioContext;\n\n const analyzer = audioContext.createAnalyser();\n analyzer.fftSize = 256; // Better resolution for time domain\n analyzer.smoothingTimeConstant = 0.7;\n analyzerRef.current = analyzer;\n\n const source = audioContext.createMediaStreamSource(stream);\n source.connect(analyzer);\n\n const dataArray = new Uint8Array(analyzer.fftSize);\n\n const updateLevels = () => {\n if (!analyzerRef.current) return;\n\n // Use time domain data (waveform) instead of frequency\n analyzer.getByteTimeDomainData(dataArray);\n\n // Calculate RMS (Root Mean Square) for volume\n let sum = 0;\n for (let i = 0; i < dataArray.length; i++) {\n const normalized = (dataArray[i] - 128) / 128; // Center around 0\n sum += normalized * normalized;\n }\n const rms = Math.sqrt(sum / dataArray.length);\n\n // Apply some scaling and clamping\n const volume = Math.min(1, rms * 3); // Boost sensitivity\n\n // Create left-to-right wave effect\n const levels = Array(barsCount)\n .fill(0)\n .map((_, i) => {\n // Progressive wave from left to right\n const position = i / barsCount; // 0 to 1 from left to right\n const wavePhase = Date.now() / 300 + position * Math.PI * 2;\n const waveVariation = Math.sin(wavePhase) * 0.15 + 0.85; // 0.7 to 1.0\n return volume * waveVariation;\n });\n\n setAudioLevels(levels);\n animationFrameRef.current = requestAnimationFrame(updateLevels);\n };\n\n updateLevels();\n } catch (error) {\n console.error(\"Error setting up audio analysis:\", error);\n }\n };\n\n setupAudioAnalysis();\n\n return () => {\n if (animationFrameRef.current) {\n cancelAnimationFrame(animationFrameRef.current);\n }\n if (stream) {\n stream.getTracks().forEach((track) => track.stop());\n }\n if (audioContextRef.current) {\n audioContextRef.current.close();\n }\n };\n }, [isActive, barsCount]);\n\n const [isBotSpeaking, setIsBotSpeaking] = useState(false);\n\n return (\n <div\n style={{\n position: \"absolute\",\n top: \"50%\",\n left: \"50%\",\n transform: \"translate(-50%, -50%)\",\n textAlign: \"center\",\n padding: \"1rem\",\n zIndex: 10,\n pointerEvents: \"none\",\n display: \"flex\",\n flexDirection: \"column\",\n alignItems: \"center\",\n gap: \"2rem\",\n }}\n >\n {/* Character Avatar with Audio Visualizer */}\n <div\n style={{\n position: \"relative\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n isolation: \"isolate\", // Create stacking context\n }}\n >\n {/* Audio Visualizer - positioned absolutely behind the character */}\n {room && (\n <motion.div\n initial={{ opacity: 0, scale: 0.8 }}\n animate={{\n opacity: isBotSpeaking ? 1 : 0,\n scale: isBotSpeaking ? 1 : 0.8,\n }}\n transition={iosTransitions.fadePop}\n style={{\n position: \"absolute\",\n width: \"220px\",\n height: \"220px\",\n zIndex: -1, // Negative z-index to ensure it's behind\n pointerEvents: \"none\",\n }}\n >\n <AudioVisualizer\n room={room}\n size={220}\n color={aeroTheme.colors.convai.light}\n opacity={0.6}\n avatarRadius={110}\n barCount={48}\n onSpeakingChange={setIsBotSpeaking}\n />\n </motion.div>\n )}\n\n {/* Character Image - pops from header to center */}\n <motion.div\n key=\"center-avatar\" // Use key instead of layoutId for independent animation\n initial={{ scale: 0.8, opacity: 0 }}\n animate={{ scale: 1, opacity: 1 }}\n exit={{ scale: 0.8, opacity: 0 }}\n transition={iosTransitions.fadePop}\n style={{\n position: \"relative\",\n zIndex: 10, // Higher z-index to be clearly on top\n borderRadius: \"50%\",\n overflow: \"visible\", // Changed to visible to show glow\n boxShadow: \"0 8px 32px rgba(0, 0, 0, 0.3)\",\n background: \"white\",\n }}\n >\n {/* Animated liquid gradient - Layer 1 */}\n <motion.div\n animate={{\n rotate: [0, 360],\n scale: isBotSpeaking ? [1, 1.05, 1.02, 1.05, 1] : 1,\n }}\n transition={{\n rotate: { duration: 20, repeat: Infinity, ease: \"linear\" },\n scale: { duration: 3, repeat: Infinity, ease: \"easeInOut\" },\n }}\n style={{\n position: \"absolute\",\n width: \"126px\",\n height: \"126px\",\n borderRadius: \"50%\",\n background: `\n conic-gradient(\n from 0deg,\n ${aeroTheme.colors.convai.light}00 0%,\n ${aeroTheme.colors.convai.light}40 25%,\n ${aeroTheme.colors.convai.dark}60 50%,\n ${aeroTheme.colors.convai.light}40 75%,\n ${aeroTheme.colors.convai.light}00 100%\n )\n `,\n opacity: 0.8,\n filter: \"blur(8px)\",\n zIndex: -2,\n }}\n />\n\n {/* Animated liquid gradient - Layer 2 (counter-rotating) */}\n <motion.div\n animate={{\n rotate: [360, 0],\n scale: isBotSpeaking ? [1, 1.03, 1.06, 1.03, 1] : 1,\n }}\n transition={{\n rotate: { duration: 15, repeat: Infinity, ease: \"linear\" },\n scale: { duration: 2.5, repeat: Infinity, ease: \"easeInOut\" },\n }}\n style={{\n position: \"absolute\",\n width: \"126px\",\n height: \"126px\",\n borderRadius: \"50%\",\n background: `\n radial-gradient(\n ellipse 80% 100% at 30% 40%,\n ${aeroTheme.colors.convai.light}50,\n ${aeroTheme.colors.convai.light}30 40%,\n transparent 70%\n ),\n radial-gradient(\n ellipse 80% 100% at 70% 60%,\n ${aeroTheme.colors.convai.dark}50,\n ${aeroTheme.colors.convai.dark}30 40%,\n transparent 70%\n )\n `,\n opacity: 0.9,\n filter: \"blur(6px)\",\n zIndex: -1,\n }}\n />\n\n {/* Character container with border */}\n <div\n style={{\n position: \"relative\",\n borderRadius: \"50%\",\n overflow: \"hidden\",\n border: `3px solid rgba(255, 255, 255, 0.2)`,\n }}\n >\n {characterImage ? (\n <motion.img\n src={characterImage}\n alt={characterName}\n animate={{\n scale: isBotSpeaking ? 1.05 : 1,\n }}\n transition={{\n duration: 0.3,\n ease: \"easeInOut\",\n }}\n style={{\n width: \"120px\",\n height: \"120px\",\n objectFit: \"cover\",\n display: \"block\",\n }}\n />\n ) : (\n <div\n style={{\n width: \"120px\",\n height: \"120px\",\n backgroundColor: aeroTheme.colors.convai.light + \"20\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n fontSize: \"48px\",\n color: aeroTheme.colors.convai.light,\n fontWeight: 600,\n }}\n >\n {characterName[0]?.toUpperCase() || \"C\"}\n </div>\n )}\n </div>\n </motion.div>\n </div>\n\n {/* Sound Wave Lines - USER microphone ONLY */}\n <AnimatePresence>\n {isActive && (\n <motion.div\n initial={{ opacity: 0, y: 20 }}\n animate={{ opacity: 1, y: 0 }}\n exit={{ opacity: 0, y: -20 }}\n transition={iosTransitions.fadePop}\n style={{\n width: \"250px\",\n height: \"80px\",\n position: \"relative\",\n }}\n >\n <svg\n width=\"250\"\n height=\"80\"\n style={{\n overflow: \"visible\",\n }}\n >\n {/* Generate 3 wave lines with green shades */}\n {[0, 1, 2].map((waveIndex) => {\n // Calculate wave path based on audio levels\n const points: string[] = [];\n const centerY = 40;\n const waveWidth = 250;\n const segments = barsCount;\n \n // Calculate average audio level for glow intensity\n const avgLevel = audioLevels.reduce((sum, level) => sum + level, 0) / audioLevels.length;\n const glowIntensity = avgLevel * 35; // 0-35px glow (increased from 20)\n \n // Green color variants for each wave\n const waveColors = [\n aeroTheme.colors.convai.light, // Bright green - front wave\n aeroTheme.colors.convai.light, // Medium green - mid wave\n \"#34d399\", // Medium-light green - back wave (lighter than dark)\n ];\n \n for (let i = 0; i <= segments; i++) {\n const x = (i / segments) * waveWidth;\n const levelIndex = Math.floor((i / segments) * (audioLevels.length - 1));\n const level = audioLevels[levelIndex] || 0;\n \n // When idle (low audio), show straight line\n // When active, create waves with increased amplitude\n const phase = (Date.now() / 500 + i * 0.2 + waveIndex * 1.5) % (Math.PI * 2);\n \n // Only add wave motion when there's audio\n // Idle: amplitude ~0 (straight line)\n // Active: amplitude up to 25px (increased from 15)\n const baseAmplitude = avgLevel > 0.05 ? (2 + waveIndex * 1.5) : 0;\n const amplitude = baseAmplitude + level * (25 - baseAmplitude);\n const y = centerY + Math.sin(phase) * amplitude;\n \n points.push(`${x},${y}`);\n }\n \n return (\n <motion.path\n key={waveIndex}\n d={`M ${points.join(\" L \")}`}\n fill=\"none\"\n stroke={waveColors[waveIndex]}\n strokeWidth={2.5 - waveIndex * 0.4}\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n opacity={0.95 - waveIndex * 0.15}\n animate={{\n filter: `drop-shadow(0 0 ${glowIntensity}px ${waveColors[waveIndex]}) blur(${waveIndex * 0.3}px)`,\n }}\n transition={{\n duration: 0.1,\n ease: \"easeOut\",\n }}\n />\n );\n })}\n </svg>\n </motion.div>\n )}\n </AnimatePresence>\n\n {/* Status Text */}\n <motion.div\n initial={{ opacity: 0, y: 10 }}\n animate={{ opacity: 1, y: 0 }}\n transition={{ delay: 0.2, ...iosTransitions.fadePop }}\n >\n <div\n style={{\n fontSize: \"16px\",\n fontWeight: 600,\n color: aeroTheme.colors.text.primary,\n marginBottom: \"0.5rem\",\n }}\n >\n {isTalking\n ? `${characterName} Speaking...`\n : isListening || isActive\n ? \"Listening...\"\n : \"Voice Mode\"}\n </div>\n <div\n style={{\n fontSize: \"13px\",\n color: aeroTheme.colors.text.secondary,\n }}\n >\n {isListening || isActive || isTalking ? \"Audio active\" : \"Tap microphone to talk\"}\n </div>\n </motion.div>\n </div>\n );\n};\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useConvaiClient.d.ts","sourceRoot":"","sources":["../../../src/react/hooks/useConvaiClient.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,YAAY,EACZ,aAAa,EACb,WAAW,EAEZ,MAAM,kBAAkB,CAAC;AAE1B;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,eAAO,MAAM,eAAe,GAC1B,SAAS,YAAY,KACpB,aAAa,GAAG;IACjB,oFAAoF;IACpF,2BAA2B,EAAE,WAAW,CACtC,aAAa,CAAC,6BAA6B,CAAC,CAC7C,CAAC;IACF,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,WAAW,EAAE,CAAC;IAC5B,YAAY,EAAE,OAAO,CAAC;IACtB,cAAc,EAAE,OAAO,CAAC;IACxB,mBAAmB,EAAE,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"useConvaiClient.d.ts","sourceRoot":"","sources":["../../../src/react/hooks/useConvaiClient.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,YAAY,EACZ,aAAa,EACb,WAAW,EAEZ,MAAM,kBAAkB,CAAC;AAE1B;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,eAAO,MAAM,eAAe,GAC1B,SAAS,YAAY,KACpB,aAAa,GAAG;IACjB,oFAAoF;IACpF,2BAA2B,EAAE,WAAW,CACtC,aAAa,CAAC,6BAA6B,CAAC,CAC7C,CAAC;IACF,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,WAAW,EAAE,CAAC;IAC5B,YAAY,EAAE,OAAO,CAAC;IACtB,cAAc,EAAE,OAAO,CAAC;IACxB,mBAAmB,EAAE,OAAO,CAAC;CAwO9B,CAAC"}
|
|
@@ -27,10 +27,8 @@ import { ConvaiClient as CoreConvaiClient } from "../../core/index.js";
|
|
|
27
27
|
* ```
|
|
28
28
|
*/
|
|
29
29
|
export const useConvaiClient = (config) => {
|
|
30
|
-
// Create client instance once
|
|
31
|
-
|
|
32
|
-
// `characterVersions` are usable before the first connect().
|
|
33
|
-
const [client] = useState(() => new CoreConvaiClient(config));
|
|
30
|
+
// Create client instance once
|
|
31
|
+
const [client] = useState(() => new CoreConvaiClient());
|
|
34
32
|
// React state for UI updates
|
|
35
33
|
const [state, setState] = useState(client.state);
|
|
36
34
|
const [activity, setActivity] = useState("Idle");
|
|
@@ -172,19 +170,8 @@ export const useConvaiClient = (config) => {
|
|
|
172
170
|
...(client.apiKey && { apiKey: client.apiKey }),
|
|
173
171
|
...(client.authToken && { authToken: client.authToken }),
|
|
174
172
|
characterId: client.characterId,
|
|
175
|
-
characterVersion: client.characterVersion,
|
|
176
|
-
characterReference: client.characterReference,
|
|
177
173
|
requestTraceId: client.requestTraceId,
|
|
178
174
|
connect,
|
|
179
|
-
connectWithConnectionData: client.connectWithConnectionData.bind(client),
|
|
180
|
-
joinRoom: client.joinRoom.bind(client),
|
|
181
|
-
appendMessage: client.appendMessage.bind(client),
|
|
182
|
-
toggleUsageUpdates: client.toggleUsageUpdates.bind(client),
|
|
183
|
-
setInteractionTarget: client.setInteractionTarget.bind(client),
|
|
184
|
-
updateCharacterRoster: client.updateCharacterRoster.bind(client),
|
|
185
|
-
roomSession: client.roomSession,
|
|
186
|
-
characters: client.characters,
|
|
187
|
-
activeMembershipId: client.activeMembershipId,
|
|
188
175
|
connectWithPublicationGrant,
|
|
189
176
|
disconnect: client.disconnect.bind(client),
|
|
190
177
|
reconnect,
|
|
@@ -192,7 +179,6 @@ export const useConvaiClient = (config) => {
|
|
|
192
179
|
room: client.room,
|
|
193
180
|
sendUserTextMessage: client.sendUserTextMessage.bind(client),
|
|
194
181
|
sendActionResult: client.sendActionResult.bind(client),
|
|
195
|
-
sendActionResultAndWait: client.sendActionResultAndWait.bind(client),
|
|
196
182
|
sendTriggerMessage: client.sendTriggerMessage.bind(client),
|
|
197
183
|
sendInterruptMessage: client.sendInterruptMessage.bind(client),
|
|
198
184
|
resetIdleTimer: client.resetIdleTimer.bind(client),
|
|
@@ -215,7 +201,6 @@ export const useConvaiClient = (config) => {
|
|
|
215
201
|
blendshapeQueue: client.blendshapeQueue,
|
|
216
202
|
conversationSessionId: client.conversationSessionId,
|
|
217
203
|
memoryManager: client.memoryManager,
|
|
218
|
-
characterVersions: client.characterVersions,
|
|
219
204
|
toggleTts: client.toggleTts.bind(client),
|
|
220
205
|
toggleStt: client.toggleStt.bind(client),
|
|
221
206
|
uploadFile: client.uploadFile.bind(client),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useConvaiClient.js","sourceRoot":"","sources":["../../../src/react/hooks/useConvaiClient.ts"],"names":[],"mappings":"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","sourcesContent":["import { useState, useEffect, useCallback } from \"react\";\nimport { ConvaiClient as CoreConvaiClient } from \"../../core\";\nimport type {\n ConvaiConfig,\n IConvaiClient,\n ChatMessage,\n PublishedChatConnectOptions,\n} from \"../../core/types\";\n\n/**\n * React hook wrapper for ConvaiClient\n * Main hook for managing Convai client connection and functionality.\n *\n * Provides a complete interface for connecting to Convai's AI-powered voice assistants,\n * managing real-time audio/video conversations, and handling various message types.\n *\n * @param config - Optional configuration to store for later connection\n * @returns {ConvaiClient & { activity: string; chatMessages: ChatMessage[] }} Complete client interface with connection state, methods, and message history\n *\n * @example\n * ```tsx\n * function App() {\n * const convaiClient = useConvaiClient({\n * apiKey: 'your-api-key',\n * characterId: 'your-character-id',\n * endUserId: 'user-uuid', // Optional: enables memory & analytics\n * enableVideo: true,\n * });\n *\n * return (\n * <ConvaiWidget convaiClient={convaiClient} />\n * );\n * }\n * ```\n */\nexport const useConvaiClient = (\n config?: ConvaiConfig,\n): IConvaiClient & {\n /** This hook always supplies the publication connector, unlike generic adapters. */\n connectWithPublicationGrant: NonNullable<\n IConvaiClient[\"connectWithPublicationGrant\"]\n >;\n activity: string;\n chatMessages: ChatMessage[];\n isAudioMuted: boolean;\n isVideoEnabled: boolean;\n isScreenShareActive: boolean;\n} => {\n // Create client instance once. The config is handed to the client as well\n // as kept in the hook, so config-derived surfaces such as\n // `characterVersions` are usable before the first connect().\n const [client] = useState(() => new CoreConvaiClient(config));\n\n // React state for UI updates\n const [state, setState] = useState(client.state);\n const [activity, setActivity] = useState<string>(\"Idle\");\n const [chatMessages, setChatMessages] = useState<ChatMessage[]>(\n client.chatMessages,\n );\n const [userTranscription, setUserTranscription] = useState<string>(\n client.userTranscription,\n );\n const [isSpeaking, setIsSpeaking] = useState<boolean>(false);\n const [isBotReady, setIsBotReady] = useState<boolean>(client.isBotReady);\n \n // Reactive states for control managers\n const [isAudioMuted, setIsAudioMuted] = useState<boolean>(\n client.audioControls.isAudioMuted\n );\n const [isVideoEnabled, setIsVideoEnabled] = useState<boolean>(\n client.videoControls.isVideoEnabled\n );\n const [isScreenShareActive, setIsScreenShareActive] = useState<boolean>(\n client.screenShareControls.isScreenShareActive\n );\n\n // Store config if provided\n const [storedConfig] = useState<ConvaiConfig | undefined>(config);\n\n // Setup event listeners\n useEffect(() => {\n // State change listener\n const unsubStateChange = client.on(\"stateChange\", (newState) => {\n setState(newState);\n\n // Update activity based on state (priority: speaking > listening > thinking > connected)\n if (!newState.isConnected) {\n setActivity(\"Disconnected\");\n } else if (newState.isConnecting) {\n setActivity(\"Connecting...\");\n } else if (newState.isSpeaking) {\n setActivity(\"Speaking\");\n } else if (newState.isListening) {\n setActivity(\"Listening\");\n } else if (newState.isThinking) {\n setActivity(\"Thinking\");\n } else {\n setActivity(\"Connected\");\n }\n });\n\n // Messages change listener\n const unsubMessagesChange = client.on(\"messagesChange\", (messages) => {\n setChatMessages([...messages]);\n });\n\n // User transcription change listener\n const unsubUserTranscription = client.on(\n \"userTranscriptionChange\",\n (transcription) => {\n setUserTranscription(transcription);\n },\n );\n\n // Speaking change listener\n const unsubSpeaking = client.on(\"speakingChange\", (speaking) => {\n setIsSpeaking(speaking);\n });\n\n // Bot ready listener\n const unsubBotReady = client.on(\"botReady\", () => {\n setIsBotReady(true);\n setActivity(\"Connected\");\n });\n\n // Connect listener\n const unsubConnect = client.on(\"connect\", () => {\n setState(client.state);\n });\n\n // Disconnect listener\n const unsubDisconnect = client.on(\"disconnect\", () => {\n setIsBotReady(false);\n setState(client.state);\n setActivity(\"Disconnected\");\n setChatMessages([]);\n // Reset control states on disconnect\n setIsAudioMuted(true);\n setIsVideoEnabled(false);\n setIsScreenShareActive(false);\n });\n\n // WebSocket transport: play bot audio track via a hidden <audio> element\n const wsAudioEl = document.createElement(\"audio\");\n wsAudioEl.autoplay = true;\n wsAudioEl.dataset.convaiWs = \"true\";\n document.body.appendChild(wsAudioEl);\n\n const unsubBotAudioTrack = client.on(\n \"botAudioTrack\",\n (track: MediaStreamTrack) => {\n wsAudioEl.srcObject = new MediaStream([track]);\n },\n );\n\n // Disconnect listener also clears WS audio\n const unsubDisconnectWsAudio = client.on(\"disconnect\", () => {\n wsAudioEl.srcObject = null;\n });\n\n // Audio controls state change listener\n const unsubAudioState = client.audioControls.on(\"audioStateChange\", (audioState: any) => {\n if (audioState.isAudioMuted !== undefined) {\n setIsAudioMuted(audioState.isAudioMuted);\n }\n });\n\n // Video controls state change listener\n const unsubVideoState = client.videoControls.on(\"videoStateChange\", (videoState: any) => {\n if (videoState.isVideoEnabled !== undefined) {\n setIsVideoEnabled(videoState.isVideoEnabled);\n }\n });\n\n // Screen share controls state change listener\n const unsubScreenShareState = client.screenShareControls.on(\"screenShareStateChange\", (screenShareState: any) => {\n if (screenShareState.isScreenShareActive !== undefined) {\n setIsScreenShareActive(screenShareState.isScreenShareActive);\n }\n });\n\n // Cleanup listeners on unmount\n return () => {\n unsubStateChange();\n unsubMessagesChange();\n unsubUserTranscription();\n unsubSpeaking();\n unsubBotReady();\n unsubConnect();\n unsubDisconnect();\n unsubBotAudioTrack();\n unsubDisconnectWsAudio();\n unsubAudioState();\n unsubVideoState();\n unsubScreenShareState();\n wsAudioEl.srcObject = null;\n wsAudioEl.remove();\n };\n }, [client]);\n\n // Create enhanced connect function that can use stored config\n const connect = useCallback(\n async (configOverride?: ConvaiConfig) => {\n const finalConfig = configOverride || storedConfig;\n\n if (!finalConfig) {\n throw new Error(\n \"No configuration provided. Pass config to useConvaiClient() or to connect()\",\n );\n }\n\n await client.connect(finalConfig);\n },\n [client, storedConfig],\n );\n\n // Create reconnect function wrapper\n const reconnect = useCallback(async () => {\n await client.reconnect();\n }, [client]);\n\n const connectWithPublicationGrant = useCallback(\n async (\n launchToken: string,\n options?: PublishedChatConnectOptions,\n ) => {\n await client.connectWithPublicationGrant(launchToken, options);\n },\n [client],\n );\n\n // Return client interface with React-friendly additions\n return {\n state,\n connectionType: client.connectionType,\n isPublishedChatSession: client.isPublishedChatSession,\n ...(client.apiKey && { apiKey: client.apiKey }),\n ...(client.authToken && { authToken: client.authToken }),\n characterId: client.characterId,\n characterVersion: client.characterVersion,\n characterReference: client.characterReference,\n requestTraceId: client.requestTraceId,\n connect,\n connectWithConnectionData: client.connectWithConnectionData.bind(client),\n joinRoom: client.joinRoom.bind(client),\n appendMessage: client.appendMessage.bind(client),\n toggleUsageUpdates: client.toggleUsageUpdates.bind(client),\n setInteractionTarget: client.setInteractionTarget.bind(client),\n updateCharacterRoster: client.updateCharacterRoster.bind(client),\n roomSession: client.roomSession,\n characters: client.characters,\n activeMembershipId: client.activeMembershipId,\n connectWithPublicationGrant,\n disconnect: client.disconnect.bind(client),\n reconnect,\n resetSession: client.resetSession.bind(client),\n room: client.room,\n sendUserTextMessage: client.sendUserTextMessage.bind(client),\n sendActionResult: client.sendActionResult.bind(client),\n sendActionResultAndWait: client.sendActionResultAndWait.bind(client),\n sendTriggerMessage: client.sendTriggerMessage.bind(client),\n sendInterruptMessage: client.sendInterruptMessage.bind(client),\n resetIdleTimer: client.resetIdleTimer.bind(client),\n updateTemplateKeys: client.updateTemplateKeys.bind(client),\n updateDynamicInfo: client.updateDynamicInfo.bind(client),\n updateContext: client.updateContext.bind(client),\n updateEmotion: client.updateEmotion.bind(client),\n visionStatus: client.visionStatus.bind(client),\n visionTrigger: client.visionTrigger.bind(client),\n respondModeUpdate: client.respondModeUpdate.bind(client),\n updateSceneMetadata: client.updateSceneMetadata.bind(client),\n activity,\n chatMessages,\n userTranscription,\n characterSessionId: client.characterSessionId,\n isBotReady,\n audioControls: client.audioControls,\n videoControls: client.videoControls,\n screenShareControls: client.screenShareControls,\n blendshapeQueue: client.blendshapeQueue,\n conversationSessionId: client.conversationSessionId,\n memoryManager: client.memoryManager,\n characterVersions: client.characterVersions,\n toggleTts: client.toggleTts.bind(client),\n toggleStt: client.toggleStt.bind(client),\n uploadFile: client.uploadFile.bind(client),\n on: client.on.bind(client),\n off: client.off.bind(client),\n // Reactive control states\n isAudioMuted,\n isVideoEnabled,\n isScreenShareActive,\n };\n};\n"]}
|
|
1
|
+
{"version":3,"file":"useConvaiClient.js","sourceRoot":"","sources":["../../../src/react/hooks/useConvaiClient.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,OAAO,CAAC;AACzD,OAAO,EAAE,YAAY,IAAI,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAQ9D;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG,CAC7B,MAAqB,EAWrB,EAAE;IACF,8BAA8B;IAC9B,MAAM,CAAC,MAAM,CAAC,GAAG,QAAQ,CAAC,GAAG,EAAE,CAAC,IAAI,gBAAgB,EAAE,CAAC,CAAC;IAExD,6BAA6B;IAC7B,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,QAAQ,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IACjD,MAAM,CAAC,QAAQ,EAAE,WAAW,CAAC,GAAG,QAAQ,CAAS,MAAM,CAAC,CAAC;IACzD,MAAM,CAAC,YAAY,EAAE,eAAe,CAAC,GAAG,QAAQ,CAC9C,MAAM,CAAC,YAAY,CACpB,CAAC;IACF,MAAM,CAAC,iBAAiB,EAAE,oBAAoB,CAAC,GAAG,QAAQ,CACxD,MAAM,CAAC,iBAAiB,CACzB,CAAC;IACF,MAAM,CAAC,UAAU,EAAE,aAAa,CAAC,GAAG,QAAQ,CAAU,KAAK,CAAC,CAAC;IAC7D,MAAM,CAAC,UAAU,EAAE,aAAa,CAAC,GAAG,QAAQ,CAAU,MAAM,CAAC,UAAU,CAAC,CAAC;IAEzE,uCAAuC;IACvC,MAAM,CAAC,YAAY,EAAE,eAAe,CAAC,GAAG,QAAQ,CAC9C,MAAM,CAAC,aAAa,CAAC,YAAY,CAClC,CAAC;IACF,MAAM,CAAC,cAAc,EAAE,iBAAiB,CAAC,GAAG,QAAQ,CAClD,MAAM,CAAC,aAAa,CAAC,cAAc,CACpC,CAAC;IACF,MAAM,CAAC,mBAAmB,EAAE,sBAAsB,CAAC,GAAG,QAAQ,CAC5D,MAAM,CAAC,mBAAmB,CAAC,mBAAmB,CAC/C,CAAC;IAEF,2BAA2B;IAC3B,MAAM,CAAC,YAAY,CAAC,GAAG,QAAQ,CAA2B,MAAM,CAAC,CAAC;IAElE,wBAAwB;IACxB,SAAS,CAAC,GAAG,EAAE;QACb,wBAAwB;QACxB,MAAM,gBAAgB,GAAG,MAAM,CAAC,EAAE,CAAC,aAAa,EAAE,CAAC,QAAQ,EAAE,EAAE;YAC7D,QAAQ,CAAC,QAAQ,CAAC,CAAC;YAEnB,yFAAyF;YACzF,IAAI,CAAC,QAAQ,CAAC,WAAW,EAAE,CAAC;gBAC1B,WAAW,CAAC,cAAc,CAAC,CAAC;YAC9B,CAAC;iBAAM,IAAI,QAAQ,CAAC,YAAY,EAAE,CAAC;gBACjC,WAAW,CAAC,eAAe,CAAC,CAAC;YAC/B,CAAC;iBAAM,IAAI,QAAQ,CAAC,UAAU,EAAE,CAAC;gBAC/B,WAAW,CAAC,UAAU,CAAC,CAAC;YAC1B,CAAC;iBAAM,IAAI,QAAQ,CAAC,WAAW,EAAE,CAAC;gBAChC,WAAW,CAAC,WAAW,CAAC,CAAC;YAC3B,CAAC;iBAAM,IAAI,QAAQ,CAAC,UAAU,EAAE,CAAC;gBAC/B,WAAW,CAAC,UAAU,CAAC,CAAC;YAC1B,CAAC;iBAAM,CAAC;gBACN,WAAW,CAAC,WAAW,CAAC,CAAC;YAC3B,CAAC;QACH,CAAC,CAAC,CAAC;QAEH,2BAA2B;QAC3B,MAAM,mBAAmB,GAAG,MAAM,CAAC,EAAE,CAAC,gBAAgB,EAAE,CAAC,QAAQ,EAAE,EAAE;YACnE,eAAe,CAAC,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC;QACjC,CAAC,CAAC,CAAC;QAEH,qCAAqC;QACrC,MAAM,sBAAsB,GAAG,MAAM,CAAC,EAAE,CACtC,yBAAyB,EACzB,CAAC,aAAa,EAAE,EAAE;YAChB,oBAAoB,CAAC,aAAa,CAAC,CAAC;QACtC,CAAC,CACF,CAAC;QAEF,2BAA2B;QAC3B,MAAM,aAAa,GAAG,MAAM,CAAC,EAAE,CAAC,gBAAgB,EAAE,CAAC,QAAQ,EAAE,EAAE;YAC7D,aAAa,CAAC,QAAQ,CAAC,CAAC;QAC1B,CAAC,CAAC,CAAC;QAEH,qBAAqB;QACrB,MAAM,aAAa,GAAG,MAAM,CAAC,EAAE,CAAC,UAAU,EAAE,GAAG,EAAE;YAC/C,aAAa,CAAC,IAAI,CAAC,CAAC;YACpB,WAAW,CAAC,WAAW,CAAC,CAAC;QAC3B,CAAC,CAAC,CAAC;QAEH,mBAAmB;QACnB,MAAM,YAAY,GAAG,MAAM,CAAC,EAAE,CAAC,SAAS,EAAE,GAAG,EAAE;YAC7C,QAAQ,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QACzB,CAAC,CAAC,CAAC;QAEH,sBAAsB;QACtB,MAAM,eAAe,GAAG,MAAM,CAAC,EAAE,CAAC,YAAY,EAAE,GAAG,EAAE;YACnD,aAAa,CAAC,KAAK,CAAC,CAAC;YACrB,QAAQ,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;YACvB,WAAW,CAAC,cAAc,CAAC,CAAC;YAC5B,eAAe,CAAC,EAAE,CAAC,CAAC;YACpB,qCAAqC;YACrC,eAAe,CAAC,IAAI,CAAC,CAAC;YACtB,iBAAiB,CAAC,KAAK,CAAC,CAAC;YACzB,sBAAsB,CAAC,KAAK,CAAC,CAAC;QAChC,CAAC,CAAC,CAAC;QAEH,yEAAyE;QACzE,MAAM,SAAS,GAAG,QAAQ,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC;QAClD,SAAS,CAAC,QAAQ,GAAG,IAAI,CAAC;QAC1B,SAAS,CAAC,OAAO,CAAC,QAAQ,GAAG,MAAM,CAAC;QACpC,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,SAAS,CAAC,CAAC;QAErC,MAAM,kBAAkB,GAAG,MAAM,CAAC,EAAE,CAClC,eAAe,EACf,CAAC,KAAuB,EAAE,EAAE;YAC1B,SAAS,CAAC,SAAS,GAAG,IAAI,WAAW,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC;QACjD,CAAC,CACF,CAAC;QAEF,2CAA2C;QAC3C,MAAM,sBAAsB,GAAG,MAAM,CAAC,EAAE,CAAC,YAAY,EAAE,GAAG,EAAE;YAC1D,SAAS,CAAC,SAAS,GAAG,IAAI,CAAC;QAC7B,CAAC,CAAC,CAAC;QAEH,uCAAuC;QACvC,MAAM,eAAe,GAAG,MAAM,CAAC,aAAa,CAAC,EAAE,CAAC,kBAAkB,EAAE,CAAC,UAAe,EAAE,EAAE;YACtF,IAAI,UAAU,CAAC,YAAY,KAAK,SAAS,EAAE,CAAC;gBAC1C,eAAe,CAAC,UAAU,CAAC,YAAY,CAAC,CAAC;YAC3C,CAAC;QACH,CAAC,CAAC,CAAC;QAEH,uCAAuC;QACvC,MAAM,eAAe,GAAG,MAAM,CAAC,aAAa,CAAC,EAAE,CAAC,kBAAkB,EAAE,CAAC,UAAe,EAAE,EAAE;YACtF,IAAI,UAAU,CAAC,cAAc,KAAK,SAAS,EAAE,CAAC;gBAC5C,iBAAiB,CAAC,UAAU,CAAC,cAAc,CAAC,CAAC;YAC/C,CAAC;QACH,CAAC,CAAC,CAAC;QAEH,8CAA8C;QAC9C,MAAM,qBAAqB,GAAG,MAAM,CAAC,mBAAmB,CAAC,EAAE,CAAC,wBAAwB,EAAE,CAAC,gBAAqB,EAAE,EAAE;YAC9G,IAAI,gBAAgB,CAAC,mBAAmB,KAAK,SAAS,EAAE,CAAC;gBACvD,sBAAsB,CAAC,gBAAgB,CAAC,mBAAmB,CAAC,CAAC;YAC/D,CAAC;QACH,CAAC,CAAC,CAAC;QAEH,+BAA+B;QAC/B,OAAO,GAAG,EAAE;YACV,gBAAgB,EAAE,CAAC;YACnB,mBAAmB,EAAE,CAAC;YACtB,sBAAsB,EAAE,CAAC;YACzB,aAAa,EAAE,CAAC;YAChB,aAAa,EAAE,CAAC;YAChB,YAAY,EAAE,CAAC;YACf,eAAe,EAAE,CAAC;YAClB,kBAAkB,EAAE,CAAC;YACrB,sBAAsB,EAAE,CAAC;YACzB,eAAe,EAAE,CAAC;YAClB,eAAe,EAAE,CAAC;YAClB,qBAAqB,EAAE,CAAC;YACxB,SAAS,CAAC,SAAS,GAAG,IAAI,CAAC;YAC3B,SAAS,CAAC,MAAM,EAAE,CAAC;QACrB,CAAC,CAAC;IACJ,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC;IAEb,8DAA8D;IAC9D,MAAM,OAAO,GAAG,WAAW,CACzB,KAAK,EAAE,cAA6B,EAAE,EAAE;QACtC,MAAM,WAAW,GAAG,cAAc,IAAI,YAAY,CAAC;QAEnD,IAAI,CAAC,WAAW,EAAE,CAAC;YACjB,MAAM,IAAI,KAAK,CACb,6EAA6E,CAC9E,CAAC;QACJ,CAAC;QAED,MAAM,MAAM,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC;IACpC,CAAC,EACD,CAAC,MAAM,EAAE,YAAY,CAAC,CACvB,CAAC;IAEF,oCAAoC;IACpC,MAAM,SAAS,GAAG,WAAW,CAAC,KAAK,IAAI,EAAE;QACvC,MAAM,MAAM,CAAC,SAAS,EAAE,CAAC;IAC3B,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC;IAEb,MAAM,2BAA2B,GAAG,WAAW,CAC7C,KAAK,EACH,WAAmB,EACnB,OAAqC,EACrC,EAAE;QACF,MAAM,MAAM,CAAC,2BAA2B,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;IACjE,CAAC,EACD,CAAC,MAAM,CAAC,CACT,CAAC;IAEF,wDAAwD;IACxD,OAAO;QACL,KAAK;QACL,cAAc,EAAE,MAAM,CAAC,cAAc;QACrC,sBAAsB,EAAE,MAAM,CAAC,sBAAsB;QACrD,GAAG,CAAC,MAAM,CAAC,MAAM,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC;QAC/C,GAAG,CAAC,MAAM,CAAC,SAAS,IAAI,EAAE,SAAS,EAAE,MAAM,CAAC,SAAS,EAAE,CAAC;QACxD,WAAW,EAAE,MAAM,CAAC,WAAW;QAC/B,cAAc,EAAE,MAAM,CAAC,cAAc;QACrC,OAAO;QACP,2BAA2B;QAC3B,UAAU,EAAE,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC,MAAM,CAAC;QAC1C,SAAS;QACT,YAAY,EAAE,MAAM,CAAC,YAAY,CAAC,IAAI,CAAC,MAAM,CAAC;QAC9C,IAAI,EAAE,MAAM,CAAC,IAAI;QACjB,mBAAmB,EAAE,MAAM,CAAC,mBAAmB,CAAC,IAAI,CAAC,MAAM,CAAC;QAC5D,gBAAgB,EAAE,MAAM,CAAC,gBAAgB,CAAC,IAAI,CAAC,MAAM,CAAC;QACtD,kBAAkB,EAAE,MAAM,CAAC,kBAAkB,CAAC,IAAI,CAAC,MAAM,CAAC;QAC1D,oBAAoB,EAAE,MAAM,CAAC,oBAAoB,CAAC,IAAI,CAAC,MAAM,CAAC;QAC9D,cAAc,EAAE,MAAM,CAAC,cAAc,CAAC,IAAI,CAAC,MAAM,CAAC;QAClD,kBAAkB,EAAE,MAAM,CAAC,kBAAkB,CAAC,IAAI,CAAC,MAAM,CAAC;QAC1D,iBAAiB,EAAE,MAAM,CAAC,iBAAiB,CAAC,IAAI,CAAC,MAAM,CAAC;QACxD,aAAa,EAAE,MAAM,CAAC,aAAa,CAAC,IAAI,CAAC,MAAM,CAAC;QAChD,aAAa,EAAE,MAAM,CAAC,aAAa,CAAC,IAAI,CAAC,MAAM,CAAC;QAChD,YAAY,EAAE,MAAM,CAAC,YAAY,CAAC,IAAI,CAAC,MAAM,CAAC;QAC9C,aAAa,EAAE,MAAM,CAAC,aAAa,CAAC,IAAI,CAAC,MAAM,CAAC;QAChD,iBAAiB,EAAE,MAAM,CAAC,iBAAiB,CAAC,IAAI,CAAC,MAAM,CAAC;QACxD,mBAAmB,EAAE,MAAM,CAAC,mBAAmB,CAAC,IAAI,CAAC,MAAM,CAAC;QAC5D,QAAQ;QACR,YAAY;QACZ,iBAAiB;QACjB,kBAAkB,EAAE,MAAM,CAAC,kBAAkB;QAC7C,UAAU;QACV,aAAa,EAAE,MAAM,CAAC,aAAa;QACnC,aAAa,EAAE,MAAM,CAAC,aAAa;QACnC,mBAAmB,EAAE,MAAM,CAAC,mBAAmB;QAC/C,eAAe,EAAE,MAAM,CAAC,eAAe;QACvC,qBAAqB,EAAE,MAAM,CAAC,qBAAqB;QACnD,aAAa,EAAE,MAAM,CAAC,aAAa;QACnC,SAAS,EAAE,MAAM,CAAC,SAAS,CAAC,IAAI,CAAC,MAAM,CAAC;QACxC,SAAS,EAAE,MAAM,CAAC,SAAS,CAAC,IAAI,CAAC,MAAM,CAAC;QACxC,UAAU,EAAE,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC,MAAM,CAAC;QAC1C,EAAE,EAAE,MAAM,CAAC,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC;QAC1B,GAAG,EAAE,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC;QAC5B,0BAA0B;QAC1B,YAAY;QACZ,cAAc;QACd,mBAAmB;KACpB,CAAC;AACJ,CAAC,CAAC","sourcesContent":["import { useState, useEffect, useCallback } from \"react\";\nimport { ConvaiClient as CoreConvaiClient } from \"../../core\";\nimport type {\n ConvaiConfig,\n IConvaiClient,\n ChatMessage,\n PublishedChatConnectOptions,\n} from \"../../core/types\";\n\n/**\n * React hook wrapper for ConvaiClient\n * Main hook for managing Convai client connection and functionality.\n *\n * Provides a complete interface for connecting to Convai's AI-powered voice assistants,\n * managing real-time audio/video conversations, and handling various message types.\n *\n * @param config - Optional configuration to store for later connection\n * @returns {ConvaiClient & { activity: string; chatMessages: ChatMessage[] }} Complete client interface with connection state, methods, and message history\n *\n * @example\n * ```tsx\n * function App() {\n * const convaiClient = useConvaiClient({\n * apiKey: 'your-api-key',\n * characterId: 'your-character-id',\n * endUserId: 'user-uuid', // Optional: enables memory & analytics\n * enableVideo: true,\n * });\n *\n * return (\n * <ConvaiWidget convaiClient={convaiClient} />\n * );\n * }\n * ```\n */\nexport const useConvaiClient = (\n config?: ConvaiConfig,\n): IConvaiClient & {\n /** This hook always supplies the publication connector, unlike generic adapters. */\n connectWithPublicationGrant: NonNullable<\n IConvaiClient[\"connectWithPublicationGrant\"]\n >;\n activity: string;\n chatMessages: ChatMessage[];\n isAudioMuted: boolean;\n isVideoEnabled: boolean;\n isScreenShareActive: boolean;\n} => {\n // Create client instance once\n const [client] = useState(() => new CoreConvaiClient());\n\n // React state for UI updates\n const [state, setState] = useState(client.state);\n const [activity, setActivity] = useState<string>(\"Idle\");\n const [chatMessages, setChatMessages] = useState<ChatMessage[]>(\n client.chatMessages,\n );\n const [userTranscription, setUserTranscription] = useState<string>(\n client.userTranscription,\n );\n const [isSpeaking, setIsSpeaking] = useState<boolean>(false);\n const [isBotReady, setIsBotReady] = useState<boolean>(client.isBotReady);\n \n // Reactive states for control managers\n const [isAudioMuted, setIsAudioMuted] = useState<boolean>(\n client.audioControls.isAudioMuted\n );\n const [isVideoEnabled, setIsVideoEnabled] = useState<boolean>(\n client.videoControls.isVideoEnabled\n );\n const [isScreenShareActive, setIsScreenShareActive] = useState<boolean>(\n client.screenShareControls.isScreenShareActive\n );\n\n // Store config if provided\n const [storedConfig] = useState<ConvaiConfig | undefined>(config);\n\n // Setup event listeners\n useEffect(() => {\n // State change listener\n const unsubStateChange = client.on(\"stateChange\", (newState) => {\n setState(newState);\n\n // Update activity based on state (priority: speaking > listening > thinking > connected)\n if (!newState.isConnected) {\n setActivity(\"Disconnected\");\n } else if (newState.isConnecting) {\n setActivity(\"Connecting...\");\n } else if (newState.isSpeaking) {\n setActivity(\"Speaking\");\n } else if (newState.isListening) {\n setActivity(\"Listening\");\n } else if (newState.isThinking) {\n setActivity(\"Thinking\");\n } else {\n setActivity(\"Connected\");\n }\n });\n\n // Messages change listener\n const unsubMessagesChange = client.on(\"messagesChange\", (messages) => {\n setChatMessages([...messages]);\n });\n\n // User transcription change listener\n const unsubUserTranscription = client.on(\n \"userTranscriptionChange\",\n (transcription) => {\n setUserTranscription(transcription);\n },\n );\n\n // Speaking change listener\n const unsubSpeaking = client.on(\"speakingChange\", (speaking) => {\n setIsSpeaking(speaking);\n });\n\n // Bot ready listener\n const unsubBotReady = client.on(\"botReady\", () => {\n setIsBotReady(true);\n setActivity(\"Connected\");\n });\n\n // Connect listener\n const unsubConnect = client.on(\"connect\", () => {\n setState(client.state);\n });\n\n // Disconnect listener\n const unsubDisconnect = client.on(\"disconnect\", () => {\n setIsBotReady(false);\n setState(client.state);\n setActivity(\"Disconnected\");\n setChatMessages([]);\n // Reset control states on disconnect\n setIsAudioMuted(true);\n setIsVideoEnabled(false);\n setIsScreenShareActive(false);\n });\n\n // WebSocket transport: play bot audio track via a hidden <audio> element\n const wsAudioEl = document.createElement(\"audio\");\n wsAudioEl.autoplay = true;\n wsAudioEl.dataset.convaiWs = \"true\";\n document.body.appendChild(wsAudioEl);\n\n const unsubBotAudioTrack = client.on(\n \"botAudioTrack\",\n (track: MediaStreamTrack) => {\n wsAudioEl.srcObject = new MediaStream([track]);\n },\n );\n\n // Disconnect listener also clears WS audio\n const unsubDisconnectWsAudio = client.on(\"disconnect\", () => {\n wsAudioEl.srcObject = null;\n });\n\n // Audio controls state change listener\n const unsubAudioState = client.audioControls.on(\"audioStateChange\", (audioState: any) => {\n if (audioState.isAudioMuted !== undefined) {\n setIsAudioMuted(audioState.isAudioMuted);\n }\n });\n\n // Video controls state change listener\n const unsubVideoState = client.videoControls.on(\"videoStateChange\", (videoState: any) => {\n if (videoState.isVideoEnabled !== undefined) {\n setIsVideoEnabled(videoState.isVideoEnabled);\n }\n });\n\n // Screen share controls state change listener\n const unsubScreenShareState = client.screenShareControls.on(\"screenShareStateChange\", (screenShareState: any) => {\n if (screenShareState.isScreenShareActive !== undefined) {\n setIsScreenShareActive(screenShareState.isScreenShareActive);\n }\n });\n\n // Cleanup listeners on unmount\n return () => {\n unsubStateChange();\n unsubMessagesChange();\n unsubUserTranscription();\n unsubSpeaking();\n unsubBotReady();\n unsubConnect();\n unsubDisconnect();\n unsubBotAudioTrack();\n unsubDisconnectWsAudio();\n unsubAudioState();\n unsubVideoState();\n unsubScreenShareState();\n wsAudioEl.srcObject = null;\n wsAudioEl.remove();\n };\n }, [client]);\n\n // Create enhanced connect function that can use stored config\n const connect = useCallback(\n async (configOverride?: ConvaiConfig) => {\n const finalConfig = configOverride || storedConfig;\n\n if (!finalConfig) {\n throw new Error(\n \"No configuration provided. Pass config to useConvaiClient() or to connect()\",\n );\n }\n\n await client.connect(finalConfig);\n },\n [client, storedConfig],\n );\n\n // Create reconnect function wrapper\n const reconnect = useCallback(async () => {\n await client.reconnect();\n }, [client]);\n\n const connectWithPublicationGrant = useCallback(\n async (\n launchToken: string,\n options?: PublishedChatConnectOptions,\n ) => {\n await client.connectWithPublicationGrant(launchToken, options);\n },\n [client],\n );\n\n // Return client interface with React-friendly additions\n return {\n state,\n connectionType: client.connectionType,\n isPublishedChatSession: client.isPublishedChatSession,\n ...(client.apiKey && { apiKey: client.apiKey }),\n ...(client.authToken && { authToken: client.authToken }),\n characterId: client.characterId,\n requestTraceId: client.requestTraceId,\n connect,\n connectWithPublicationGrant,\n disconnect: client.disconnect.bind(client),\n reconnect,\n resetSession: client.resetSession.bind(client),\n room: client.room,\n sendUserTextMessage: client.sendUserTextMessage.bind(client),\n sendActionResult: client.sendActionResult.bind(client),\n sendTriggerMessage: client.sendTriggerMessage.bind(client),\n sendInterruptMessage: client.sendInterruptMessage.bind(client),\n resetIdleTimer: client.resetIdleTimer.bind(client),\n updateTemplateKeys: client.updateTemplateKeys.bind(client),\n updateDynamicInfo: client.updateDynamicInfo.bind(client),\n updateContext: client.updateContext.bind(client),\n updateEmotion: client.updateEmotion.bind(client),\n visionStatus: client.visionStatus.bind(client),\n visionTrigger: client.visionTrigger.bind(client),\n respondModeUpdate: client.respondModeUpdate.bind(client),\n updateSceneMetadata: client.updateSceneMetadata.bind(client),\n activity,\n chatMessages,\n userTranscription,\n characterSessionId: client.characterSessionId,\n isBotReady,\n audioControls: client.audioControls,\n videoControls: client.videoControls,\n screenShareControls: client.screenShareControls,\n blendshapeQueue: client.blendshapeQueue,\n conversationSessionId: client.conversationSessionId,\n memoryManager: client.memoryManager,\n toggleTts: client.toggleTts.bind(client),\n toggleStt: client.toggleStt.bind(client),\n uploadFile: client.uploadFile.bind(client),\n on: client.on.bind(client),\n off: client.off.bind(client),\n // Reactive control states\n isAudioMuted,\n isVideoEnabled,\n isScreenShareActive,\n };\n};\n"]}
|
package/dist/react/index.d.ts
CHANGED
|
@@ -3,6 +3,6 @@ export { ConvaiWidget } from './components/ConvaiWidget.js';
|
|
|
3
3
|
export * from './hooks/index.js';
|
|
4
4
|
export * from '../core/types.js';
|
|
5
5
|
export { getDisconnectReasonMessage } from '../core/types.js';
|
|
6
|
-
export {
|
|
6
|
+
export { ConvaiClient } from '../core/index.js';
|
|
7
7
|
export { RoomAudioRenderer as AudioRenderer, RoomContext as AudioContext } from '@livekit/components-react';
|
|
8
8
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/react/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAG1D,OAAO,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AAGzD,cAAc,SAAS,CAAC;AAGxB,cAAc,eAAe,CAAC;AAG9B,OAAO,EAAE,0BAA0B,EAAE,MAAM,eAAe,CAAC;AAG3D,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/react/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAG1D,OAAO,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AAGzD,cAAc,SAAS,CAAC;AAGxB,cAAc,eAAe,CAAC;AAG9B,OAAO,EAAE,0BAA0B,EAAE,MAAM,eAAe,CAAC;AAG3D,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAGvC,OAAO,EAAE,iBAAiB,IAAI,aAAa,EAAE,WAAW,IAAI,YAAY,EAAE,MAAM,2BAA2B,CAAC"}
|
package/dist/react/index.js
CHANGED
|
@@ -9,7 +9,7 @@ export * from '../core/types.js';
|
|
|
9
9
|
// Re-export helper functions explicitly
|
|
10
10
|
export { getDisconnectReasonMessage } from '../core/types.js';
|
|
11
11
|
// Re-export core client for advanced usage
|
|
12
|
-
export {
|
|
12
|
+
export { ConvaiClient } from '../core/index.js';
|
|
13
13
|
// Re-export LiveKit components for convenience (backward compatible)
|
|
14
14
|
export { RoomAudioRenderer as AudioRenderer, RoomContext as AudioContext } from '@livekit/components-react';
|
|
15
15
|
//# sourceMappingURL=index.js.map
|
package/dist/react/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/react/index.ts"],"names":[],"mappings":"AAAA,kCAAkC;AAClC,OAAO,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAE1D,aAAa;AACb,OAAO,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AAEzD,wCAAwC;AACxC,cAAc,SAAS,CAAC;AAExB,uCAAuC;AACvC,cAAc,eAAe,CAAC;AAE9B,wCAAwC;AACxC,OAAO,EAAE,0BAA0B,EAAE,MAAM,eAAe,CAAC;AAE3D,2CAA2C;AAC3C,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/react/index.ts"],"names":[],"mappings":"AAAA,kCAAkC;AAClC,OAAO,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAE1D,aAAa;AACb,OAAO,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AAEzD,wCAAwC;AACxC,cAAc,SAAS,CAAC;AAExB,uCAAuC;AACvC,cAAc,eAAe,CAAC;AAE9B,wCAAwC;AACxC,OAAO,EAAE,0BAA0B,EAAE,MAAM,eAAe,CAAC;AAE3D,2CAA2C;AAC3C,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAEvC,qEAAqE;AACrE,OAAO,EAAE,iBAAiB,IAAI,aAAa,EAAE,WAAW,IAAI,YAAY,EAAE,MAAM,2BAA2B,CAAC","sourcesContent":["// Main hook (backward compatible)\nexport { useConvaiClient } from './hooks/useConvaiClient';\n\n// Components\nexport { ConvaiWidget } from './components/ConvaiWidget';\n\n// Additional hooks (for advanced usage)\nexport * from './hooks';\n\n// Re-export core types for convenience\nexport * from '../core/types';\n\n// Re-export helper functions explicitly\nexport { getDisconnectReasonMessage } from '../core/types';\n\n// Re-export core client for advanced usage\nexport { ConvaiClient } from '../core';\n\n// Re-export LiveKit components for convenience (backward compatible)\nexport { RoomAudioRenderer as AudioRenderer, RoomContext as AudioContext } from '@livekit/components-react';\n\n"]}
|
|
@@ -13,9 +13,7 @@ export declare class AudioRenderer {
|
|
|
13
13
|
private boundHandleTrackSubscribed;
|
|
14
14
|
private boundHandleTrackUnsubscribed;
|
|
15
15
|
private boundHandleParticipantDisconnected;
|
|
16
|
-
constructor(room: Room
|
|
17
|
-
container?: HTMLElement;
|
|
18
|
-
});
|
|
16
|
+
constructor(room: Room);
|
|
19
17
|
/**
|
|
20
18
|
* Setup event listeners for room events
|
|
21
19
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AudioRenderer.d.ts","sourceRoot":"","sources":["../../src/vanilla/AudioRenderer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAwD,MAAM,gBAAgB,CAAC;AAG5F;;;;GAIG;AACH,qBAAa,aAAa;IACxB,OAAO,CAAC,IAAI,CAAO;IACnB,OAAO,CAAC,aAAa,CAA4C;IACjE,OAAO,CAAC,SAAS,CAAc;IAC/B,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,aAAa,CAA+B;IAGpD,OAAO,CAAC,0BAA0B,CAAM;IACxC,OAAO,CAAC,4BAA4B,CAAM;IAC1C,OAAO,CAAC,kCAAkC,CAAM;gBAEpC,IAAI,EAAE,IAAI
|
|
1
|
+
{"version":3,"file":"AudioRenderer.d.ts","sourceRoot":"","sources":["../../src/vanilla/AudioRenderer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAwD,MAAM,gBAAgB,CAAC;AAG5F;;;;GAIG;AACH,qBAAa,aAAa;IACxB,OAAO,CAAC,IAAI,CAAO;IACnB,OAAO,CAAC,aAAa,CAA4C;IACjE,OAAO,CAAC,SAAS,CAAc;IAC/B,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,aAAa,CAA+B;IAGpD,OAAO,CAAC,0BAA0B,CAAM;IACxC,OAAO,CAAC,4BAA4B,CAAM;IAC1C,OAAO,CAAC,kCAAkC,CAAM;gBAEpC,IAAI,EAAE,IAAI;IAmBtB;;OAEG;IACH,OAAO,CAAC,mBAAmB;IAM3B;;OAEG;IACH,OAAO,CAAC,oBAAoB;IAU5B;;OAEG;IACH,OAAO,CAAC,qBAAqB;IAU7B;;OAEG;IACH,OAAO,CAAC,uBAAuB;IAU/B;;OAEG;IACH,OAAO,CAAC,6BAA6B;IAMrC;;OAEG;IACH,OAAO,CAAC,gBAAgB;IA+BxB;;OAEG;IACH,OAAO,CAAC,gBAAgB;IAmBxB,OAAO,CAAC,eAAe,CAAiC;IAExD;;OAEG;IACH,oBAAoB,CAAC,KAAK,EAAE,gBAAgB,GAAG,IAAI;IASnD,oBAAoB,IAAI,IAAI;IAS5B;;OAEG;IACH,OAAO,IAAI,IAAI;CAmBhB"}
|
|
@@ -6,7 +6,7 @@ import { logger } from '../utils/logger.js';
|
|
|
6
6
|
* This replaces React's RoomAudioRenderer for vanilla implementations
|
|
7
7
|
*/
|
|
8
8
|
export class AudioRenderer {
|
|
9
|
-
constructor(room
|
|
9
|
+
constructor(room) {
|
|
10
10
|
this.audioElements = new Map();
|
|
11
11
|
this.livekitTracks = new Map(); // Store track references
|
|
12
12
|
this._wsAudioElement = null;
|
|
@@ -20,7 +20,7 @@ export class AudioRenderer {
|
|
|
20
20
|
this.container = document.createElement('div');
|
|
21
21
|
this.container.id = `convai-audio-renderer-${this.rendererId}`;
|
|
22
22
|
this.container.style.display = 'none';
|
|
23
|
-
|
|
23
|
+
document.body.appendChild(this.container);
|
|
24
24
|
this.setupEventListeners();
|
|
25
25
|
this.attachExistingTracks();
|
|
26
26
|
}
|
|
@@ -84,12 +84,6 @@ export class AudioRenderer {
|
|
|
84
84
|
// Create audio element
|
|
85
85
|
const audioElement = document.createElement('audio');
|
|
86
86
|
audioElement.id = `audio-${trackSid}`;
|
|
87
|
-
// Expose who owns this element, so a host page can find a member's
|
|
88
|
-
// audio by identity (`character:{membershipId}` in a roster room).
|
|
89
|
-
audioElement.dataset.participantIdentity = participant.identity;
|
|
90
|
-
if (participant.identity.startsWith('character:')) {
|
|
91
|
-
audioElement.dataset.membershipId = participant.identity.slice('character:'.length);
|
|
92
|
-
}
|
|
93
87
|
audioElement.autoplay = true;
|
|
94
88
|
// Direct track attachment - play audio immediately
|
|
95
89
|
track.attach(audioElement);
|