@zeroweight/react 0.2.30 → 0.2.32
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -1,29 +1,29 @@
|
|
|
1
|
-
import { useMemo as be, useRef as
|
|
1
|
+
import { useMemo as be, useRef as k, useState as x, useCallback as S, useEffect as h } from "react";
|
|
2
2
|
import { ZeroWeightRenderer as Se, ActionQueue as xe, VoiceActivityDetector as ke } from "@zeroweight/renderer";
|
|
3
|
-
import { jsxs as
|
|
4
|
-
import { useVoiceAssistant as we, useLocalParticipant as Ae, useIsSpeaking as Te, useDataChannel as Ie, RoomAudioRenderer as
|
|
3
|
+
import { jsxs as w, jsx as r, Fragment as j } from "react/jsx-runtime";
|
|
4
|
+
import { useVoiceAssistant as we, useLocalParticipant as Ae, useIsSpeaking as Te, useDataChannel as Ie, RoomAudioRenderer as Ce, LiveKitRoom as Re } from "@livekit/components-react";
|
|
5
5
|
import "@livekit/components-styles";
|
|
6
|
-
import { Loader2 as
|
|
6
|
+
import { Loader2 as J, MicOff as Me, Mic as Ee, Power as Le, Activity as De } from "lucide-react";
|
|
7
7
|
const ze = 3e4, Pe = 120, Fe = "wss://prod-project-pazuyq69.livekit.cloud", ne = "https://api.zeroweight.ai";
|
|
8
8
|
function Ue(v) {
|
|
9
9
|
const {
|
|
10
10
|
avatarId: a,
|
|
11
|
-
apiKey:
|
|
11
|
+
apiKey: e = null,
|
|
12
12
|
api: u,
|
|
13
13
|
turnOffMicWhenAISpeaking: d = !0,
|
|
14
|
-
livekitUrl:
|
|
14
|
+
livekitUrl: A = Fe,
|
|
15
15
|
sessionDuration: p = Pe,
|
|
16
|
-
inactivityTimeout:
|
|
17
|
-
} = v,
|
|
16
|
+
inactivityTimeout: C = ze
|
|
17
|
+
} = v, D = A, y = be(() => {
|
|
18
18
|
if (u) return u;
|
|
19
|
-
const
|
|
19
|
+
const t = e ? { "X-ZW-Api-Key": e } : void 0;
|
|
20
20
|
return {
|
|
21
|
-
getBundle: async (
|
|
21
|
+
getBundle: async (g) => {
|
|
22
22
|
const T = await fetch(
|
|
23
23
|
`${ne}/avatars/bundle/${encodeURIComponent(
|
|
24
|
-
|
|
24
|
+
g
|
|
25
25
|
)}`,
|
|
26
|
-
{ headers:
|
|
26
|
+
{ headers: t }
|
|
27
27
|
);
|
|
28
28
|
if (!T.ok)
|
|
29
29
|
throw new Error(
|
|
@@ -31,13 +31,13 @@ function Ue(v) {
|
|
|
31
31
|
);
|
|
32
32
|
return T.json();
|
|
33
33
|
},
|
|
34
|
-
getLiveKitToken: async (
|
|
34
|
+
getLiveKitToken: async (g) => {
|
|
35
35
|
const T = new URLSearchParams({
|
|
36
|
-
avatar_id:
|
|
36
|
+
avatar_id: g,
|
|
37
37
|
name: "anonymuous"
|
|
38
38
|
}), c = await fetch(
|
|
39
39
|
`${ne}/livekit/token?${T.toString()}`,
|
|
40
|
-
{ headers:
|
|
40
|
+
{ headers: t }
|
|
41
41
|
);
|
|
42
42
|
if (!c.ok)
|
|
43
43
|
throw new Error(
|
|
@@ -46,133 +46,133 @@ function Ue(v) {
|
|
|
46
46
|
return c.json();
|
|
47
47
|
}
|
|
48
48
|
};
|
|
49
|
-
}, [u,
|
|
49
|
+
}, [u, e]), m = k(null), E = k(null), i = k(null), l = k(null), [b, R] = x("idle"), [f, P] = x(null), [s, U] = x(
|
|
50
50
|
/* @__PURE__ */ new Set(["listening"])
|
|
51
|
-
), [
|
|
51
|
+
), [n, o] = x({
|
|
52
52
|
listening: { kind: "looped" },
|
|
53
53
|
speaking: { kind: "looped" }
|
|
54
|
-
}), [
|
|
55
|
-
}), [oe, X] = x(!1), [se, Y] = x(0.8),
|
|
56
|
-
const
|
|
57
|
-
if (!
|
|
58
|
-
let
|
|
59
|
-
return
|
|
54
|
+
}), [O, z] = x(!1), [F, $] = x(null), [W, K] = x(!1), [N, Z] = x(!1), [ae, V] = x(p), M = k(null), B = k(() => {
|
|
55
|
+
}), [oe, X] = x(!1), [se, Y] = x(0.8), L = k(null), H = b === "ready", G = S(() => {
|
|
56
|
+
const t = m.current;
|
|
57
|
+
if (!t) return null;
|
|
58
|
+
let g = t.querySelector("canvas");
|
|
59
|
+
return g || (g = document.createElement("canvas"), g.style.width = "100%", g.style.height = "100%", g.style.display = "block", t.appendChild(g)), E.current = g, g;
|
|
60
60
|
}, []);
|
|
61
61
|
h(() => {
|
|
62
|
-
let
|
|
62
|
+
let t = !1;
|
|
63
63
|
return (async () => {
|
|
64
64
|
const T = G();
|
|
65
65
|
if (!T) return;
|
|
66
66
|
const c = new Se();
|
|
67
67
|
i.current = c;
|
|
68
|
-
const
|
|
68
|
+
const q = new xe((I, _) => {
|
|
69
69
|
c.play(I, _);
|
|
70
70
|
});
|
|
71
|
-
|
|
72
|
-
|
|
71
|
+
l.current = q, c.on("stateChanged", (I) => {
|
|
72
|
+
t || R(I);
|
|
73
73
|
}), c.on("dimensions", (I, _) => {
|
|
74
|
-
|
|
74
|
+
t || P({ width: I, height: _ });
|
|
75
75
|
}), c.on("actionLoaded", (I) => {
|
|
76
|
-
|
|
76
|
+
t || U((_) => {
|
|
77
77
|
const te = new Set(_);
|
|
78
78
|
return te.add(I), te;
|
|
79
79
|
});
|
|
80
80
|
}), c.on("allActionsLoaded", () => {
|
|
81
|
-
|
|
81
|
+
t || z(!1);
|
|
82
82
|
}), c.on("ready", () => {
|
|
83
|
-
|
|
83
|
+
t || (o(c.getActionMetadata()), q.setActionMetadata(c.getActionMetadata()));
|
|
84
84
|
});
|
|
85
85
|
try {
|
|
86
|
-
|
|
87
|
-
const I = await
|
|
88
|
-
if (
|
|
89
|
-
|
|
86
|
+
z(!0);
|
|
87
|
+
const I = await y.getBundle(a);
|
|
88
|
+
if (t || (await c.init(T, { payload: I.payload }), t)) return;
|
|
89
|
+
o(c.getActionMetadata()), q.setActionMetadata(c.getActionMetadata());
|
|
90
90
|
} catch (I) {
|
|
91
91
|
console.error("[useAvatarSession] Init failed:", I);
|
|
92
92
|
}
|
|
93
93
|
})(), () => {
|
|
94
|
-
|
|
94
|
+
t = !0, i.current?.destroy(), i.current = null, l.current = null;
|
|
95
95
|
};
|
|
96
|
-
}, [a, G,
|
|
97
|
-
const ee =
|
|
96
|
+
}, [a, G, y]);
|
|
97
|
+
const ee = k(!1);
|
|
98
98
|
h(() => {
|
|
99
|
-
|
|
100
|
-
}, [
|
|
99
|
+
H && i.current && s.has("wave_hand") && !ee.current && (i.current.play("wave_hand", "listening"), ee.current = !0);
|
|
100
|
+
}, [H, s]);
|
|
101
101
|
const ce = S(async () => {
|
|
102
|
-
if (!(
|
|
103
|
-
|
|
102
|
+
if (!(W || N)) {
|
|
103
|
+
K(!0);
|
|
104
104
|
try {
|
|
105
105
|
await navigator.mediaDevices.getUserMedia({ audio: !0 });
|
|
106
|
-
const
|
|
107
|
-
|
|
108
|
-
} catch (
|
|
109
|
-
console.error("[useAvatarSession] Failed to connect:",
|
|
106
|
+
const t = await y.getLiveKitToken(a);
|
|
107
|
+
$(t.token);
|
|
108
|
+
} catch (t) {
|
|
109
|
+
console.error("[useAvatarSession] Failed to connect:", t), K(!1);
|
|
110
110
|
}
|
|
111
111
|
}
|
|
112
|
-
}, [
|
|
113
|
-
|
|
112
|
+
}, [W, N, a, y]), Q = S(() => {
|
|
113
|
+
M.current && (clearInterval(M.current), M.current = null), V(p), L.current && (clearTimeout(L.current), L.current = null), $(null), Z(!1), K(!1), l.current?.forceListening();
|
|
114
114
|
}, [p]);
|
|
115
115
|
h(() => {
|
|
116
|
-
|
|
117
|
-
}, [
|
|
116
|
+
B.current = Q;
|
|
117
|
+
}, [Q]);
|
|
118
118
|
const le = S(() => {
|
|
119
|
-
Z(!0),
|
|
119
|
+
Z(!0), K(!1);
|
|
120
120
|
}, []), ue = S(() => {
|
|
121
|
-
|
|
122
|
-
|
|
121
|
+
M.current && clearInterval(M.current), V(p), M.current = setInterval(() => {
|
|
122
|
+
V((t) => t <= 1 ? (clearInterval(M.current), M.current = null, setTimeout(() => B.current(), 0), 0) : t - 1);
|
|
123
123
|
}, 1e3);
|
|
124
|
-
}, [p]), de = S((
|
|
125
|
-
const
|
|
126
|
-
return `${
|
|
124
|
+
}, [p]), de = S((t) => {
|
|
125
|
+
const g = Math.floor(t / 60).toString().padStart(2, "0"), T = (t % 60).toString().padStart(2, "0");
|
|
126
|
+
return `${g}:${T}`;
|
|
127
127
|
}, []);
|
|
128
128
|
h(() => () => {
|
|
129
|
-
|
|
129
|
+
M.current && clearInterval(M.current);
|
|
130
130
|
}, []);
|
|
131
131
|
const pe = S(
|
|
132
|
-
(
|
|
133
|
-
if (!
|
|
134
|
-
|
|
132
|
+
(t) => {
|
|
133
|
+
if (!t) {
|
|
134
|
+
L.current && (clearTimeout(L.current), L.current = null);
|
|
135
135
|
return;
|
|
136
136
|
}
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
},
|
|
137
|
+
L.current || (L.current = setTimeout(() => {
|
|
138
|
+
L.current = null, B.current();
|
|
139
|
+
}, C));
|
|
140
140
|
},
|
|
141
|
-
[
|
|
141
|
+
[C]
|
|
142
142
|
), fe = S(() => {
|
|
143
|
-
X((
|
|
144
|
-
}, []), ge = S((
|
|
145
|
-
X(
|
|
146
|
-
}, []), he = S((
|
|
147
|
-
Y(
|
|
143
|
+
X((t) => !t);
|
|
144
|
+
}, []), ge = S((t) => {
|
|
145
|
+
X(t);
|
|
146
|
+
}, []), he = S((t) => {
|
|
147
|
+
Y(t);
|
|
148
148
|
}, []), me = S(() => {
|
|
149
|
-
Y((
|
|
149
|
+
Y((t) => t > 0 ? 0 : 1);
|
|
150
150
|
}, []), ve = S(() => {
|
|
151
151
|
i.current?.interrupt();
|
|
152
|
-
}, []), ye = S((
|
|
153
|
-
i.current?.play(
|
|
152
|
+
}, []), ye = S((t) => {
|
|
153
|
+
i.current?.play(t, "listening");
|
|
154
154
|
}, []);
|
|
155
155
|
return {
|
|
156
|
-
containerRef:
|
|
156
|
+
containerRef: m,
|
|
157
157
|
renderer: i.current,
|
|
158
|
-
actionQueue:
|
|
159
|
-
rendererState:
|
|
160
|
-
avatarDimensions:
|
|
161
|
-
loadedActions:
|
|
162
|
-
actionMetadata:
|
|
163
|
-
isLoadingActions:
|
|
164
|
-
isEngineReady:
|
|
165
|
-
token:
|
|
166
|
-
isConnecting:
|
|
167
|
-
isConnected:
|
|
168
|
-
livekitUrl:
|
|
158
|
+
actionQueue: l.current,
|
|
159
|
+
rendererState: b,
|
|
160
|
+
avatarDimensions: f,
|
|
161
|
+
loadedActions: s,
|
|
162
|
+
actionMetadata: n,
|
|
163
|
+
isLoadingActions: O,
|
|
164
|
+
isEngineReady: H,
|
|
165
|
+
token: F,
|
|
166
|
+
isConnecting: W,
|
|
167
|
+
isConnected: N,
|
|
168
|
+
livekitUrl: D,
|
|
169
169
|
timeRemaining: ae,
|
|
170
170
|
formatTime: de,
|
|
171
171
|
micMuted: oe,
|
|
172
172
|
volume: se,
|
|
173
173
|
turnOffMicWhenAISpeaking: d,
|
|
174
174
|
connect: ce,
|
|
175
|
-
disconnect:
|
|
175
|
+
disconnect: Q,
|
|
176
176
|
toggleMic: fe,
|
|
177
177
|
setMicMuted: ge,
|
|
178
178
|
setVolume: he,
|
|
@@ -187,8 +187,8 @@ function Ue(v) {
|
|
|
187
187
|
const _e = ({
|
|
188
188
|
session: v,
|
|
189
189
|
style: a,
|
|
190
|
-
loadingContent:
|
|
191
|
-
}) => /* @__PURE__ */
|
|
190
|
+
loadingContent: e
|
|
191
|
+
}) => /* @__PURE__ */ w(
|
|
192
192
|
"div",
|
|
193
193
|
{
|
|
194
194
|
style: {
|
|
@@ -238,7 +238,7 @@ const _e = ({
|
|
|
238
238
|
backdropFilter: "blur(4px)",
|
|
239
239
|
zIndex: 10
|
|
240
240
|
},
|
|
241
|
-
children:
|
|
241
|
+
children: e || /* @__PURE__ */ w(
|
|
242
242
|
"div",
|
|
243
243
|
{
|
|
244
244
|
style: {
|
|
@@ -249,7 +249,7 @@ const _e = ({
|
|
|
249
249
|
},
|
|
250
250
|
children: [
|
|
251
251
|
/* @__PURE__ */ r(
|
|
252
|
-
|
|
252
|
+
J,
|
|
253
253
|
{
|
|
254
254
|
style: {
|
|
255
255
|
width: 40,
|
|
@@ -312,26 +312,26 @@ const _e = ({
|
|
|
312
312
|
style: a
|
|
313
313
|
}) => {
|
|
314
314
|
const {
|
|
315
|
-
micMuted:
|
|
315
|
+
micMuted: e,
|
|
316
316
|
toggleMic: u,
|
|
317
317
|
isConnected: d,
|
|
318
|
-
isConnecting:
|
|
318
|
+
isConnecting: A,
|
|
319
319
|
isEngineReady: p,
|
|
320
|
-
loadedActions:
|
|
321
|
-
connect:
|
|
322
|
-
disconnect:
|
|
323
|
-
} = v, [
|
|
320
|
+
loadedActions: C,
|
|
321
|
+
connect: D,
|
|
322
|
+
disconnect: y
|
|
323
|
+
} = v, [m, E] = x(!1), [i, l] = x(!1), b = p && C.has("listening") && C.has("speaking"), R = e ? {
|
|
324
324
|
...re,
|
|
325
325
|
background: "rgba(239,68,68,0.1)",
|
|
326
326
|
color: "#f87171",
|
|
327
327
|
boxShadow: "inset 0 0 0 1px rgba(239,68,68,0.3)",
|
|
328
|
-
...
|
|
328
|
+
...m ? { background: "rgba(239,68,68,0.2)" } : {}
|
|
329
329
|
} : {
|
|
330
330
|
...re,
|
|
331
|
-
background:
|
|
331
|
+
background: m ? "rgba(255,255,255,0.1)" : "rgba(0,0,0,0.4)",
|
|
332
332
|
color: "#fff",
|
|
333
333
|
boxShadow: "inset 0 0 0 1px rgba(255,255,255,0.1)"
|
|
334
|
-
},
|
|
334
|
+
}, f = d ? {
|
|
335
335
|
...ie,
|
|
336
336
|
background: i ? "rgba(239,68,68,0.22)" : "rgba(239,68,68,0.14)",
|
|
337
337
|
boxShadow: "inset 0 0 0 1px rgba(239,68,68,0.5), 0 0 20px rgba(239,68,68,0.2)"
|
|
@@ -341,7 +341,7 @@ const _e = ({
|
|
|
341
341
|
boxShadow: "0 0 30px rgba(236,72,153,0.3)",
|
|
342
342
|
opacity: i ? 0.9 : 1
|
|
343
343
|
};
|
|
344
|
-
return (
|
|
344
|
+
return (A || !b) && (f.opacity = 0.5, f.cursor = "not-allowed"), /* @__PURE__ */ w(
|
|
345
345
|
"div",
|
|
346
346
|
{
|
|
347
347
|
style: {
|
|
@@ -361,7 +361,7 @@ const _e = ({
|
|
|
361
361
|
to { transform: rotate(360deg); }
|
|
362
362
|
}
|
|
363
363
|
` }),
|
|
364
|
-
/* @__PURE__ */
|
|
364
|
+
/* @__PURE__ */ w(
|
|
365
365
|
"div",
|
|
366
366
|
{
|
|
367
367
|
style: {
|
|
@@ -379,32 +379,32 @@ const _e = ({
|
|
|
379
379
|
{
|
|
380
380
|
type: "button",
|
|
381
381
|
onClick: u,
|
|
382
|
-
onMouseEnter: () =>
|
|
383
|
-
onMouseLeave: () =>
|
|
384
|
-
style:
|
|
385
|
-
title:
|
|
386
|
-
children:
|
|
382
|
+
onMouseEnter: () => E(!0),
|
|
383
|
+
onMouseLeave: () => E(!1),
|
|
384
|
+
style: R,
|
|
385
|
+
title: e ? "Unmute mic" : "Mute mic",
|
|
386
|
+
children: e ? /* @__PURE__ */ r(Me, { size: 24 }) : /* @__PURE__ */ r(Ee, { size: 24 })
|
|
387
387
|
}
|
|
388
388
|
),
|
|
389
389
|
/* @__PURE__ */ r(
|
|
390
390
|
"button",
|
|
391
391
|
{
|
|
392
392
|
type: "button",
|
|
393
|
-
onClick: d ?
|
|
394
|
-
onMouseEnter: () =>
|
|
395
|
-
onMouseLeave: () =>
|
|
396
|
-
disabled: !d && (
|
|
397
|
-
style:
|
|
398
|
-
children:
|
|
399
|
-
/* @__PURE__ */ r(
|
|
393
|
+
onClick: d ? y : D,
|
|
394
|
+
onMouseEnter: () => l(!0),
|
|
395
|
+
onMouseLeave: () => l(!1),
|
|
396
|
+
disabled: !d && (A || !b),
|
|
397
|
+
style: f,
|
|
398
|
+
children: A ? /* @__PURE__ */ w(j, { children: [
|
|
399
|
+
/* @__PURE__ */ r(J, { size: 20, style: { animation: "zwr-spin 1s linear infinite" } }),
|
|
400
400
|
/* @__PURE__ */ r("span", { children: "Connecting..." })
|
|
401
|
-
] }) : !d && !
|
|
402
|
-
/* @__PURE__ */ r(
|
|
401
|
+
] }) : !d && !b ? /* @__PURE__ */ w(j, { children: [
|
|
402
|
+
/* @__PURE__ */ r(J, { size: 20, style: { animation: "zwr-spin 1s linear infinite" } }),
|
|
403
403
|
/* @__PURE__ */ r("span", { children: "Loading Avatar..." })
|
|
404
|
-
] }) : d ? /* @__PURE__ */
|
|
404
|
+
] }) : d ? /* @__PURE__ */ w(j, { children: [
|
|
405
405
|
/* @__PURE__ */ r(Le, { size: 20 }),
|
|
406
406
|
/* @__PURE__ */ r("span", { children: "End Session" })
|
|
407
|
-
] }) : /* @__PURE__ */
|
|
407
|
+
] }) : /* @__PURE__ */ w(j, { children: [
|
|
408
408
|
/* @__PURE__ */ r(De, { size: 20 }),
|
|
409
409
|
/* @__PURE__ */ r("span", { children: "Start Session" })
|
|
410
410
|
] })
|
|
@@ -419,7 +419,7 @@ const _e = ({
|
|
|
419
419
|
}, Oe = ({
|
|
420
420
|
session: v
|
|
421
421
|
}) => {
|
|
422
|
-
const { isConnected: a, timeRemaining:
|
|
422
|
+
const { isConnected: a, timeRemaining: e, formatTime: u } = v, d = a && e <= 30, A = a && e > 30 && e <= 60, p = {
|
|
423
423
|
display: "flex",
|
|
424
424
|
alignItems: "center",
|
|
425
425
|
gap: 8,
|
|
@@ -434,7 +434,7 @@ const _e = ({
|
|
|
434
434
|
borderColor: "rgba(239,68,68,0.4)",
|
|
435
435
|
boxShadow: "0 0 15px rgba(239,68,68,0.3)",
|
|
436
436
|
animation: "zwr-pulse 2s ease-in-out infinite"
|
|
437
|
-
} :
|
|
437
|
+
} : A ? {
|
|
438
438
|
background: "rgba(249,115,22,0.2)",
|
|
439
439
|
borderColor: "rgba(249,115,22,0.3)",
|
|
440
440
|
boxShadow: "0 4px 12px rgba(0,0,0,0.3)"
|
|
@@ -444,14 +444,14 @@ const _e = ({
|
|
|
444
444
|
boxShadow: "0 4px 12px rgba(0,0,0,0.3)"
|
|
445
445
|
}
|
|
446
446
|
};
|
|
447
|
-
return /* @__PURE__ */
|
|
447
|
+
return /* @__PURE__ */ w(j, { children: [
|
|
448
448
|
/* @__PURE__ */ r("style", { children: `
|
|
449
449
|
@keyframes zwr-pulse {
|
|
450
450
|
0%, 100% { opacity: 1; }
|
|
451
451
|
50% { opacity: 0.5; }
|
|
452
452
|
}
|
|
453
453
|
` }),
|
|
454
|
-
/* @__PURE__ */
|
|
454
|
+
/* @__PURE__ */ w("div", { style: p, children: [
|
|
455
455
|
/* @__PURE__ */ r(
|
|
456
456
|
"div",
|
|
457
457
|
{
|
|
@@ -478,7 +478,7 @@ const _e = ({
|
|
|
478
478
|
color: "rgba(255,255,255,0.7)",
|
|
479
479
|
textTransform: "uppercase"
|
|
480
480
|
},
|
|
481
|
-
children: a ? `Online ${u(
|
|
481
|
+
children: a ? `Online ${u(e)}` : "Offline"
|
|
482
482
|
}
|
|
483
483
|
)
|
|
484
484
|
] })
|
|
@@ -486,125 +486,146 @@ const _e = ({
|
|
|
486
486
|
}, $e = ({
|
|
487
487
|
session: v
|
|
488
488
|
}) => {
|
|
489
|
-
const {
|
|
489
|
+
const {
|
|
490
|
+
renderer: a,
|
|
491
|
+
actionQueue: e,
|
|
492
|
+
micMuted: u,
|
|
493
|
+
volume: d,
|
|
494
|
+
setInactivityActive: A,
|
|
495
|
+
loadedActions: p,
|
|
496
|
+
token: C,
|
|
497
|
+
isConnected: D
|
|
498
|
+
} = v, { turnOffMicWhenAISpeaking: y, setMicMuted: m } = v, E = k(!1), { state: i, audioTrack: l } = we(), b = Ae(), R = Te(b.localParticipant), f = k(null), P = k(p);
|
|
490
499
|
h(() => {
|
|
491
|
-
|
|
500
|
+
P.current = p;
|
|
492
501
|
}, [p]), h(() => {
|
|
493
|
-
const
|
|
494
|
-
if (!a || !
|
|
495
|
-
const
|
|
496
|
-
return a.onOneshotComplete((
|
|
497
|
-
const
|
|
502
|
+
const n = b.localParticipant;
|
|
503
|
+
if (!a || !n) return;
|
|
504
|
+
const o = new TextEncoder();
|
|
505
|
+
return a.onOneshotComplete((z) => {
|
|
506
|
+
const F = o.encode(
|
|
498
507
|
JSON.stringify({
|
|
499
508
|
type: "ACTION_FINISHED",
|
|
500
|
-
action:
|
|
509
|
+
action: z
|
|
501
510
|
})
|
|
502
511
|
);
|
|
503
|
-
|
|
512
|
+
n.publishData(F, {
|
|
504
513
|
reliable: !0
|
|
505
514
|
}).catch(($) => {
|
|
506
515
|
console.error("[LiveKitAvatarProvider] Failed to publish action completion:", $);
|
|
507
516
|
});
|
|
508
517
|
});
|
|
509
|
-
}, [a,
|
|
510
|
-
if (!
|
|
511
|
-
const
|
|
518
|
+
}, [a, b.localParticipant]), h(() => {
|
|
519
|
+
if (!e) return;
|
|
520
|
+
const n = new ke({
|
|
512
521
|
threshold: 8e-3,
|
|
513
522
|
analyseIntervalMs: 30,
|
|
514
523
|
speechStartFrames: 1,
|
|
515
524
|
speechPauseFrames: 30,
|
|
516
525
|
turnEndFrames: 50
|
|
517
526
|
});
|
|
518
|
-
return
|
|
519
|
-
|
|
520
|
-
}),
|
|
521
|
-
|
|
527
|
+
return f.current = n, n.on("speechStart", () => {
|
|
528
|
+
e.setTurnActive(!0), e.setSpeechState("speaking");
|
|
529
|
+
}), n.on("turnEnd", () => {
|
|
530
|
+
e.setTurnActive(!1);
|
|
522
531
|
}), () => {
|
|
523
|
-
|
|
532
|
+
n.stop(), f.current = null;
|
|
524
533
|
};
|
|
525
|
-
}, [
|
|
526
|
-
const
|
|
527
|
-
if (
|
|
528
|
-
if (
|
|
529
|
-
const
|
|
530
|
-
|
|
534
|
+
}, [e]), h(() => {
|
|
535
|
+
const n = f.current;
|
|
536
|
+
if (n)
|
|
537
|
+
if (l?.publication?.track) {
|
|
538
|
+
const o = l.publication.track.mediaStreamTrack;
|
|
539
|
+
o && n.start(o);
|
|
531
540
|
} else
|
|
532
|
-
|
|
533
|
-
}, [
|
|
534
|
-
const
|
|
541
|
+
n.stop();
|
|
542
|
+
}, [l?.publication?.track]);
|
|
543
|
+
const s = k(null), U = k(!1);
|
|
535
544
|
return h(() => {
|
|
536
|
-
if (!
|
|
537
|
-
const
|
|
538
|
-
|
|
539
|
-
|
|
545
|
+
if (!e) return;
|
|
546
|
+
const n = i;
|
|
547
|
+
if (!C || !D || n === "disconnected") {
|
|
548
|
+
s.current && (clearTimeout(s.current), s.current = null), f.current?.endTurn(), e.forceListening();
|
|
549
|
+
return;
|
|
550
|
+
}
|
|
551
|
+
n === "speaking" ? (s.current && (clearTimeout(s.current), s.current = null), e.setTurnActive(!0), e.setSpeechState("speaking")) : n === "listening" || n === "idle" ? (s.current && (clearTimeout(s.current), s.current = null), f.current?.endTurn(), e.setTurnActive(!1)) : n === "thinking" && (s.current || (s.current = setTimeout(() => {
|
|
552
|
+
s.current = null, f.current?.endTurn(), e.setTurnActive(!1);
|
|
540
553
|
}, 500)));
|
|
541
|
-
}, [
|
|
542
|
-
const
|
|
543
|
-
if (!
|
|
544
|
-
|
|
554
|
+
}, [e, D, i, C]), h(() => {
|
|
555
|
+
const n = i === "speaking";
|
|
556
|
+
if (!y) {
|
|
557
|
+
U.current = n;
|
|
545
558
|
return;
|
|
546
559
|
}
|
|
547
|
-
const
|
|
548
|
-
!
|
|
549
|
-
}, [u,
|
|
550
|
-
|
|
551
|
-
|
|
560
|
+
const o = U.current;
|
|
561
|
+
!o && n ? u || m(!0) : o && !n && u && m(!1), U.current = n;
|
|
562
|
+
}, [u, m, i, y]), h(() => {
|
|
563
|
+
if (!y || !e) return;
|
|
564
|
+
const n = (o) => {
|
|
565
|
+
o || m(!1);
|
|
566
|
+
};
|
|
567
|
+
return e.on("turnChanged", n), () => {
|
|
568
|
+
e.off("turnChanged", n);
|
|
569
|
+
};
|
|
570
|
+
}, [e, m, y]), h(() => () => {
|
|
571
|
+
s.current && clearTimeout(s.current);
|
|
572
|
+
}, []), Ie((n) => {
|
|
552
573
|
try {
|
|
553
|
-
const
|
|
554
|
-
if (
|
|
555
|
-
const
|
|
556
|
-
if (!
|
|
574
|
+
const O = new TextDecoder().decode(n.payload), z = JSON.parse(O);
|
|
575
|
+
if (z.type === "AVATAR_UPDATE") {
|
|
576
|
+
const F = z.action;
|
|
577
|
+
if (!P.current.has(F))
|
|
557
578
|
return;
|
|
558
|
-
|
|
579
|
+
e?.dispatch(F);
|
|
559
580
|
}
|
|
560
|
-
} catch (
|
|
561
|
-
console.error("[LiveKitAvatarProvider] Failed to parse data message:",
|
|
581
|
+
} catch (o) {
|
|
582
|
+
console.error("[LiveKitAvatarProvider] Failed to parse data message:", o);
|
|
562
583
|
}
|
|
563
584
|
}), h(() => {
|
|
564
|
-
|
|
565
|
-
}, [
|
|
566
|
-
if (!
|
|
567
|
-
const
|
|
568
|
-
(!
|
|
569
|
-
}, [
|
|
570
|
-
const
|
|
571
|
-
|
|
572
|
-
console.error("[LiveKitAvatarProvider] Failed to set mic state:",
|
|
585
|
+
A(!(i === "speaking") && !R);
|
|
586
|
+
}, [R, A, i]), h(() => {
|
|
587
|
+
if (!e) return;
|
|
588
|
+
const n = !!l;
|
|
589
|
+
(!n || i === "disconnected") && (f.current?.endTurn(), e.forceListening()), E.current = n;
|
|
590
|
+
}, [l, i, e]), h(() => {
|
|
591
|
+
const n = b.localParticipant;
|
|
592
|
+
n && n.setMicrophoneEnabled(!u).catch((o) => {
|
|
593
|
+
console.error("[LiveKitAvatarProvider] Failed to set mic state:", o);
|
|
573
594
|
});
|
|
574
|
-
}, [u,
|
|
595
|
+
}, [u, b.localParticipant]), /* @__PURE__ */ r("div", { style: { position: "absolute", bottom: 80, left: 8, right: 8, display: "flex", flexDirection: "column", gap: 8 }, children: /* @__PURE__ */ r(Ce, { volume: d }) });
|
|
575
596
|
}, Qe = ({
|
|
576
597
|
avatarId: v,
|
|
577
598
|
apiKey: a,
|
|
578
|
-
api:
|
|
599
|
+
api: e,
|
|
579
600
|
turnOffMicWhenAISpeaking: u,
|
|
580
601
|
livekitUrl: d,
|
|
581
|
-
sessionDuration:
|
|
602
|
+
sessionDuration: A,
|
|
582
603
|
inactivityTimeout: p,
|
|
583
|
-
style:
|
|
584
|
-
className:
|
|
585
|
-
loadingContent:
|
|
586
|
-
customControls:
|
|
587
|
-
customStatusBadge:
|
|
604
|
+
style: C,
|
|
605
|
+
className: D,
|
|
606
|
+
loadingContent: y,
|
|
607
|
+
customControls: m,
|
|
608
|
+
customStatusBadge: E
|
|
588
609
|
}) => {
|
|
589
610
|
const i = Ue({
|
|
590
611
|
avatarId: v,
|
|
591
612
|
apiKey: a,
|
|
592
|
-
api:
|
|
613
|
+
api: e,
|
|
593
614
|
turnOffMicWhenAISpeaking: u,
|
|
594
615
|
livekitUrl: d,
|
|
595
|
-
sessionDuration:
|
|
616
|
+
sessionDuration: A,
|
|
596
617
|
inactivityTimeout: p
|
|
597
618
|
}), {
|
|
598
|
-
token:
|
|
599
|
-
isConnected:
|
|
600
|
-
avatarDimensions:
|
|
601
|
-
disconnect:
|
|
602
|
-
startSessionTimer:
|
|
619
|
+
token: l,
|
|
620
|
+
isConnected: b,
|
|
621
|
+
avatarDimensions: R,
|
|
622
|
+
disconnect: f,
|
|
623
|
+
startSessionTimer: P
|
|
603
624
|
} = i;
|
|
604
|
-
return /* @__PURE__ */
|
|
625
|
+
return /* @__PURE__ */ w(
|
|
605
626
|
"section",
|
|
606
627
|
{
|
|
607
|
-
className:
|
|
628
|
+
className: D,
|
|
608
629
|
style: {
|
|
609
630
|
position: "relative",
|
|
610
631
|
display: "flex",
|
|
@@ -618,12 +639,12 @@ const _e = ({
|
|
|
618
639
|
height: "80vh",
|
|
619
640
|
width: "auto",
|
|
620
641
|
maxWidth: "100%",
|
|
621
|
-
aspectRatio:
|
|
622
|
-
...
|
|
642
|
+
aspectRatio: R ? `${R.width} / ${R.height}` : "3 / 4",
|
|
643
|
+
...C
|
|
623
644
|
},
|
|
624
645
|
children: [
|
|
625
|
-
/* @__PURE__ */ r(_e, { session: i, loadingContent:
|
|
626
|
-
/* @__PURE__ */
|
|
646
|
+
/* @__PURE__ */ r(_e, { session: i, loadingContent: y }),
|
|
647
|
+
/* @__PURE__ */ w(
|
|
627
648
|
"div",
|
|
628
649
|
{
|
|
629
650
|
style: {
|
|
@@ -637,7 +658,7 @@ const _e = ({
|
|
|
637
658
|
padding: 16
|
|
638
659
|
},
|
|
639
660
|
children: [
|
|
640
|
-
/* @__PURE__ */
|
|
661
|
+
/* @__PURE__ */ w(
|
|
641
662
|
"div",
|
|
642
663
|
{
|
|
643
664
|
style: {
|
|
@@ -647,27 +668,27 @@ const _e = ({
|
|
|
647
668
|
justifyContent: "space-between"
|
|
648
669
|
},
|
|
649
670
|
children: [
|
|
650
|
-
|
|
671
|
+
E ? E(i) : /* @__PURE__ */ r(Oe, { session: i }),
|
|
651
672
|
/* @__PURE__ */ r("div", {})
|
|
652
673
|
]
|
|
653
674
|
}
|
|
654
675
|
),
|
|
655
|
-
|
|
676
|
+
m ? m(i) : /* @__PURE__ */ r(je, { session: i })
|
|
656
677
|
]
|
|
657
678
|
}
|
|
658
679
|
),
|
|
659
|
-
/* @__PURE__ */ r("div", { style: { display: "none" }, children:
|
|
660
|
-
|
|
680
|
+
/* @__PURE__ */ r("div", { style: { display: "none" }, children: l && d && /* @__PURE__ */ r(
|
|
681
|
+
Re,
|
|
661
682
|
{
|
|
662
683
|
serverUrl: d,
|
|
663
|
-
token:
|
|
684
|
+
token: l,
|
|
664
685
|
connect: !0,
|
|
665
686
|
video: !1,
|
|
666
687
|
audio: !0,
|
|
667
688
|
onConnected: () => {
|
|
668
|
-
i.markConnected(),
|
|
689
|
+
i.markConnected(), P();
|
|
669
690
|
},
|
|
670
|
-
onDisconnected:
|
|
691
|
+
onDisconnected: f,
|
|
671
692
|
children: /* @__PURE__ */ r($e, { session: i })
|
|
672
693
|
}
|
|
673
694
|
) })
|