@runwayml/avatars-react 0.4.0 → 0.6.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/dist/index.cjs +240 -96
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +7 -1
- package/dist/index.d.ts +7 -1
- package/dist/index.js +243 -99
- package/dist/index.js.map +1 -1
- package/dist/styles.css +67 -47
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { LiveKitRoom, RoomAudioRenderer, useRoomContext, useConnectionState, useRemoteParticipants, useTracks, isTrackReference, VideoTrack, useLocalParticipant, useMediaDevices, TrackToggle } from '@livekit/components-react';
|
|
1
|
+
import { LiveKitRoom, RoomAudioRenderer, useRoomContext, useConnectionState, useMaybeRoomContext, useRemoteParticipants, useTracks, isTrackReference, VideoTrack, useLocalParticipant, useMediaDevices, TrackToggle } from '@livekit/components-react';
|
|
2
2
|
export { RoomAudioRenderer as AudioRenderer, VideoTrack } from '@livekit/components-react';
|
|
3
|
-
import { createContext, useRef, useCallback,
|
|
3
|
+
import { createContext, useRef, useCallback, useState, useEffect, useContext } from 'react';
|
|
4
4
|
import { Track, ConnectionState } from 'livekit-client';
|
|
5
|
-
import {
|
|
5
|
+
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
6
6
|
|
|
7
7
|
// src/api/config.ts
|
|
8
8
|
var DEFAULT_BASE_URL = "https://api.dev.runwayml.com";
|
|
@@ -26,44 +26,15 @@ async function consumeSession(options) {
|
|
|
26
26
|
}
|
|
27
27
|
return response.json();
|
|
28
28
|
}
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
const suspender = promise.then(
|
|
36
|
-
(value) => {
|
|
37
|
-
status = "fulfilled";
|
|
38
|
-
result = value;
|
|
39
|
-
},
|
|
40
|
-
(err) => {
|
|
41
|
-
status = "rejected";
|
|
42
|
-
error = err;
|
|
43
|
-
}
|
|
44
|
-
);
|
|
45
|
-
return {
|
|
46
|
-
read() {
|
|
47
|
-
switch (status) {
|
|
48
|
-
case "pending":
|
|
49
|
-
throw suspender;
|
|
50
|
-
case "rejected":
|
|
51
|
-
throw error;
|
|
52
|
-
case "fulfilled":
|
|
53
|
-
return result;
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
};
|
|
29
|
+
function useLatest(value) {
|
|
30
|
+
const ref = useRef(value);
|
|
31
|
+
useEffect(() => {
|
|
32
|
+
ref.current = value;
|
|
33
|
+
}, [value]);
|
|
34
|
+
return ref;
|
|
57
35
|
}
|
|
58
36
|
|
|
59
37
|
// src/hooks/useCredentials.ts
|
|
60
|
-
var resourceCache = /* @__PURE__ */ new Map();
|
|
61
|
-
function computeKey(options) {
|
|
62
|
-
if (options.credentials) return `direct:${options.credentials.sessionId}`;
|
|
63
|
-
if (options.sessionId && options.sessionKey)
|
|
64
|
-
return `session:${options.sessionId}`;
|
|
65
|
-
return `connect:${options.avatarId}:${options.connectUrl ?? "custom"}`;
|
|
66
|
-
}
|
|
67
38
|
async function fetchCredentials(options) {
|
|
68
39
|
const { avatarId, sessionId, sessionKey, connectUrl, connect, baseUrl } = options;
|
|
69
40
|
if (sessionId && sessionKey) {
|
|
@@ -94,28 +65,106 @@ async function fetchCredentials(options) {
|
|
|
94
65
|
);
|
|
95
66
|
}
|
|
96
67
|
function useCredentials(options) {
|
|
97
|
-
const
|
|
68
|
+
const {
|
|
69
|
+
credentials: directCredentials,
|
|
70
|
+
avatarId,
|
|
71
|
+
sessionId,
|
|
72
|
+
sessionKey,
|
|
73
|
+
connectUrl,
|
|
74
|
+
connect,
|
|
75
|
+
baseUrl,
|
|
76
|
+
onError
|
|
77
|
+
} = options;
|
|
78
|
+
const onErrorRef = useLatest(onError);
|
|
79
|
+
const [state, setState] = useState(() => {
|
|
80
|
+
if (directCredentials) {
|
|
81
|
+
return { status: "ready", credentials: directCredentials, error: null };
|
|
82
|
+
}
|
|
83
|
+
return { status: "loading", credentials: null, error: null };
|
|
84
|
+
});
|
|
98
85
|
useEffect(() => {
|
|
86
|
+
if (directCredentials) {
|
|
87
|
+
setState({
|
|
88
|
+
status: "ready",
|
|
89
|
+
credentials: directCredentials,
|
|
90
|
+
error: null
|
|
91
|
+
});
|
|
92
|
+
return;
|
|
93
|
+
}
|
|
94
|
+
let cancelled = false;
|
|
95
|
+
setState({ status: "loading", credentials: null, error: null });
|
|
96
|
+
async function load() {
|
|
97
|
+
try {
|
|
98
|
+
const fetchOptions = {
|
|
99
|
+
avatarId,
|
|
100
|
+
sessionId,
|
|
101
|
+
sessionKey,
|
|
102
|
+
connectUrl,
|
|
103
|
+
connect,
|
|
104
|
+
baseUrl
|
|
105
|
+
};
|
|
106
|
+
const credentials = await fetchCredentials(fetchOptions);
|
|
107
|
+
if (!cancelled) {
|
|
108
|
+
setState({ status: "ready", credentials, error: null });
|
|
109
|
+
}
|
|
110
|
+
} catch (err) {
|
|
111
|
+
if (!cancelled) {
|
|
112
|
+
const error = err instanceof Error ? err : new Error(String(err));
|
|
113
|
+
setState({ status: "error", credentials: null, error });
|
|
114
|
+
onErrorRef.current?.(error);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
load();
|
|
99
119
|
return () => {
|
|
100
|
-
|
|
120
|
+
cancelled = true;
|
|
101
121
|
};
|
|
102
|
-
}, [
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
122
|
+
}, [
|
|
123
|
+
directCredentials,
|
|
124
|
+
avatarId,
|
|
125
|
+
sessionId,
|
|
126
|
+
sessionKey,
|
|
127
|
+
connectUrl,
|
|
128
|
+
connect,
|
|
129
|
+
baseUrl
|
|
130
|
+
]);
|
|
131
|
+
return state;
|
|
132
|
+
}
|
|
133
|
+
async function hasMediaDevice(kind) {
|
|
134
|
+
try {
|
|
135
|
+
const devices = await navigator.mediaDevices.enumerateDevices();
|
|
136
|
+
return devices.some((device) => device.kind === kind);
|
|
137
|
+
} catch {
|
|
138
|
+
return false;
|
|
110
139
|
}
|
|
111
|
-
return resource.read();
|
|
112
140
|
}
|
|
113
|
-
function
|
|
114
|
-
const
|
|
141
|
+
function useDeviceAvailability(requestAudio, requestVideo) {
|
|
142
|
+
const [state, setState] = useState({
|
|
143
|
+
audio: false,
|
|
144
|
+
video: false,
|
|
145
|
+
isChecking: true
|
|
146
|
+
});
|
|
115
147
|
useEffect(() => {
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
148
|
+
let cancelled = false;
|
|
149
|
+
async function checkDevices() {
|
|
150
|
+
const [hasAudio, hasVideo] = await Promise.all([
|
|
151
|
+
requestAudio ? hasMediaDevice("audioinput") : Promise.resolve(false),
|
|
152
|
+
requestVideo ? hasMediaDevice("videoinput") : Promise.resolve(false)
|
|
153
|
+
]);
|
|
154
|
+
if (!cancelled) {
|
|
155
|
+
setState({
|
|
156
|
+
audio: requestAudio && hasAudio,
|
|
157
|
+
video: requestVideo && hasVideo,
|
|
158
|
+
isChecking: false
|
|
159
|
+
});
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
checkDevices();
|
|
163
|
+
return () => {
|
|
164
|
+
cancelled = true;
|
|
165
|
+
};
|
|
166
|
+
}, [requestAudio, requestVideo]);
|
|
167
|
+
return state;
|
|
119
168
|
}
|
|
120
169
|
var DEFAULT_ROOM_OPTIONS = {
|
|
121
170
|
adaptiveStream: false,
|
|
@@ -141,13 +190,14 @@ var AvatarSessionContext = createContext(
|
|
|
141
190
|
function AvatarSession({
|
|
142
191
|
credentials,
|
|
143
192
|
children,
|
|
144
|
-
audio = true,
|
|
145
|
-
video = true,
|
|
193
|
+
audio: requestAudio = true,
|
|
194
|
+
video: requestVideo = true,
|
|
146
195
|
onEnd,
|
|
147
196
|
onError,
|
|
148
197
|
__unstable_roomOptions
|
|
149
198
|
}) {
|
|
150
199
|
const errorRef = useRef(null);
|
|
200
|
+
const deviceAvailability = useDeviceAvailability(requestAudio, requestVideo);
|
|
151
201
|
const handleError = (error) => {
|
|
152
202
|
errorRef.current = error;
|
|
153
203
|
onError?.(error);
|
|
@@ -156,14 +206,29 @@ function AvatarSession({
|
|
|
156
206
|
...DEFAULT_ROOM_OPTIONS,
|
|
157
207
|
...__unstable_roomOptions
|
|
158
208
|
};
|
|
209
|
+
if (deviceAvailability.isChecking) {
|
|
210
|
+
return /* @__PURE__ */ jsx(
|
|
211
|
+
AvatarSessionContext.Provider,
|
|
212
|
+
{
|
|
213
|
+
value: {
|
|
214
|
+
state: "connecting",
|
|
215
|
+
sessionId: credentials.sessionId,
|
|
216
|
+
error: null,
|
|
217
|
+
end: async () => {
|
|
218
|
+
}
|
|
219
|
+
},
|
|
220
|
+
children
|
|
221
|
+
}
|
|
222
|
+
);
|
|
223
|
+
}
|
|
159
224
|
return /* @__PURE__ */ jsxs(
|
|
160
225
|
LiveKitRoom,
|
|
161
226
|
{
|
|
162
227
|
serverUrl: credentials.serverUrl,
|
|
163
228
|
token: credentials.token,
|
|
164
229
|
connect: true,
|
|
165
|
-
audio,
|
|
166
|
-
video,
|
|
230
|
+
audio: deviceAvailability.audio,
|
|
231
|
+
video: deviceAvailability.video,
|
|
167
232
|
onDisconnected: () => onEnd?.(),
|
|
168
233
|
onError: handleError,
|
|
169
234
|
options: roomOptions,
|
|
@@ -222,14 +287,34 @@ function useAvatarSessionContext() {
|
|
|
222
287
|
}
|
|
223
288
|
return context;
|
|
224
289
|
}
|
|
290
|
+
function LoadingSessionProvider({
|
|
291
|
+
state,
|
|
292
|
+
error,
|
|
293
|
+
children
|
|
294
|
+
}) {
|
|
295
|
+
const contextValue = {
|
|
296
|
+
state,
|
|
297
|
+
sessionId: "",
|
|
298
|
+
error,
|
|
299
|
+
end: async () => {
|
|
300
|
+
}
|
|
301
|
+
};
|
|
302
|
+
return /* @__PURE__ */ jsx(AvatarSessionContext.Provider, { value: contextValue, children });
|
|
303
|
+
}
|
|
225
304
|
function useAvatar() {
|
|
226
|
-
const
|
|
305
|
+
const room = useMaybeRoomContext();
|
|
306
|
+
const hasRoomContext = room !== void 0;
|
|
307
|
+
const remoteParticipants = useRemoteParticipants({ room });
|
|
227
308
|
const avatarParticipant = remoteParticipants[0] ?? null;
|
|
228
309
|
const videoTracks = useTracks(
|
|
229
310
|
[{ source: Track.Source.Camera, withPlaceholder: true }],
|
|
230
|
-
{
|
|
311
|
+
{
|
|
312
|
+
onlySubscribed: true,
|
|
313
|
+
updateOnlyOn: [],
|
|
314
|
+
room: hasRoomContext ? room : void 0
|
|
315
|
+
}
|
|
231
316
|
).filter((ref) => !ref.participant.isLocal);
|
|
232
|
-
const videoTrackRef = videoTracks[0] ?? null;
|
|
317
|
+
const videoTrackRef = hasRoomContext ? videoTracks[0] ?? null : null;
|
|
233
318
|
const hasVideo = videoTrackRef !== null && isTrackReference(videoTrackRef);
|
|
234
319
|
return {
|
|
235
320
|
participant: avatarParticipant,
|
|
@@ -271,40 +356,57 @@ function AvatarVideo({ children, ...props }) {
|
|
|
271
356
|
if (children) {
|
|
272
357
|
return /* @__PURE__ */ jsx(Fragment, { children: children(videoStatus) });
|
|
273
358
|
}
|
|
274
|
-
return /* @__PURE__ */ jsx(
|
|
359
|
+
return /* @__PURE__ */ jsx(
|
|
360
|
+
"div",
|
|
361
|
+
{
|
|
362
|
+
...props,
|
|
363
|
+
"data-avatar-video": "",
|
|
364
|
+
"data-avatar-status": videoStatus.status,
|
|
365
|
+
children: videoStatus.status === "ready" && isTrackReference(videoStatus.videoTrackRef) && /* @__PURE__ */ jsx(VideoTrack, { trackRef: videoStatus.videoTrackRef })
|
|
366
|
+
}
|
|
367
|
+
);
|
|
275
368
|
}
|
|
276
369
|
function useLocalMedia() {
|
|
277
|
-
const
|
|
370
|
+
const room = useMaybeRoomContext();
|
|
371
|
+
const hasRoomContext = room !== void 0;
|
|
372
|
+
const { localParticipant } = useLocalParticipant({ room });
|
|
278
373
|
const audioDevices = useMediaDevices({ kind: "audioinput" });
|
|
279
374
|
const videoDevices = useMediaDevices({ kind: "videoinput" });
|
|
280
|
-
const hasMic = audioDevices
|
|
281
|
-
const hasCamera = videoDevices
|
|
375
|
+
const hasMic = audioDevices?.length > 0;
|
|
376
|
+
const hasCamera = videoDevices?.length > 0;
|
|
282
377
|
const isMicEnabled = localParticipant?.isMicrophoneEnabled ?? false;
|
|
283
378
|
const isCameraEnabled = localParticipant?.isCameraEnabled ?? false;
|
|
284
379
|
const isScreenShareEnabled = localParticipant?.isScreenShareEnabled ?? false;
|
|
285
380
|
const isMicEnabledRef = useLatest(isMicEnabled);
|
|
286
381
|
const isCameraEnabledRef = useLatest(isCameraEnabled);
|
|
287
382
|
const isScreenShareEnabledRef = useLatest(isScreenShareEnabled);
|
|
383
|
+
const hasMicRef = useLatest(hasMic);
|
|
384
|
+
const hasCameraRef = useLatest(hasCamera);
|
|
288
385
|
const toggleMic = useCallback(() => {
|
|
289
|
-
|
|
290
|
-
|
|
386
|
+
if (hasMicRef.current || isMicEnabledRef.current) {
|
|
387
|
+
localParticipant?.setMicrophoneEnabled(!isMicEnabledRef.current);
|
|
388
|
+
}
|
|
389
|
+
}, [localParticipant]);
|
|
291
390
|
const toggleCamera = useCallback(() => {
|
|
292
|
-
|
|
293
|
-
|
|
391
|
+
if (hasCameraRef.current || isCameraEnabledRef.current) {
|
|
392
|
+
localParticipant?.setCameraEnabled(!isCameraEnabledRef.current);
|
|
393
|
+
}
|
|
394
|
+
}, [localParticipant]);
|
|
294
395
|
const toggleScreenShare = useCallback(() => {
|
|
295
396
|
localParticipant?.setScreenShareEnabled(!isScreenShareEnabledRef.current);
|
|
296
|
-
}, [localParticipant
|
|
397
|
+
}, [localParticipant]);
|
|
297
398
|
const tracks = useTracks(
|
|
298
399
|
[{ source: Track.Source.Camera, withPlaceholder: true }],
|
|
299
400
|
{
|
|
300
401
|
onlySubscribed: false,
|
|
301
|
-
updateOnlyOn: []
|
|
402
|
+
updateOnlyOn: [],
|
|
403
|
+
room: hasRoomContext ? room : void 0
|
|
302
404
|
}
|
|
303
405
|
);
|
|
304
406
|
const localIdentity = localParticipant?.identity;
|
|
305
|
-
const localVideoTrackRef = tracks.find(
|
|
407
|
+
const localVideoTrackRef = hasRoomContext ? tracks.find(
|
|
306
408
|
(trackRef) => trackRef.participant.identity === localIdentity && trackRef.source === Track.Source.Camera
|
|
307
|
-
) ?? null;
|
|
409
|
+
) ?? null : null;
|
|
308
410
|
return {
|
|
309
411
|
hasMic,
|
|
310
412
|
hasCamera,
|
|
@@ -326,13 +428,22 @@ function ControlBar({
|
|
|
326
428
|
...props
|
|
327
429
|
}) {
|
|
328
430
|
const session = useAvatarSession();
|
|
329
|
-
const {
|
|
431
|
+
const {
|
|
432
|
+
isMicEnabled,
|
|
433
|
+
isCameraEnabled,
|
|
434
|
+
isScreenShareEnabled,
|
|
435
|
+
toggleMic,
|
|
436
|
+
toggleCamera,
|
|
437
|
+
toggleScreenShare
|
|
438
|
+
} = useLocalMedia();
|
|
330
439
|
const isActive = session.state === "active";
|
|
331
440
|
const state = {
|
|
332
441
|
isMicEnabled,
|
|
333
442
|
isCameraEnabled,
|
|
443
|
+
isScreenShareEnabled,
|
|
334
444
|
toggleMic,
|
|
335
445
|
toggleCamera,
|
|
446
|
+
toggleScreenShare,
|
|
336
447
|
endCall: session.end,
|
|
337
448
|
isActive
|
|
338
449
|
};
|
|
@@ -342,14 +453,14 @@ function ControlBar({
|
|
|
342
453
|
if (!isActive) {
|
|
343
454
|
return null;
|
|
344
455
|
}
|
|
345
|
-
return /* @__PURE__ */ jsxs("div", { ...props, "data-active": isActive, children: [
|
|
456
|
+
return /* @__PURE__ */ jsxs("div", { ...props, "data-avatar-control-bar": "", "data-avatar-active": isActive, children: [
|
|
346
457
|
showMicrophone && /* @__PURE__ */ jsx(
|
|
347
458
|
"button",
|
|
348
459
|
{
|
|
349
460
|
type: "button",
|
|
350
461
|
onClick: toggleMic,
|
|
351
|
-
"data-control": "microphone",
|
|
352
|
-
"data-enabled": isMicEnabled,
|
|
462
|
+
"data-avatar-control": "microphone",
|
|
463
|
+
"data-avatar-enabled": isMicEnabled,
|
|
353
464
|
"aria-label": isMicEnabled ? "Mute microphone" : "Unmute microphone",
|
|
354
465
|
children: microphoneIcon
|
|
355
466
|
}
|
|
@@ -359,8 +470,8 @@ function ControlBar({
|
|
|
359
470
|
{
|
|
360
471
|
type: "button",
|
|
361
472
|
onClick: toggleCamera,
|
|
362
|
-
"data-control": "camera",
|
|
363
|
-
"data-enabled": isCameraEnabled,
|
|
473
|
+
"data-avatar-control": "camera",
|
|
474
|
+
"data-avatar-enabled": isCameraEnabled,
|
|
364
475
|
"aria-label": isCameraEnabled ? "Turn off camera" : "Turn on camera",
|
|
365
476
|
children: cameraIcon
|
|
366
477
|
}
|
|
@@ -370,7 +481,8 @@ function ControlBar({
|
|
|
370
481
|
{
|
|
371
482
|
source: Track.Source.ScreenShare,
|
|
372
483
|
showIcon: false,
|
|
373
|
-
"data-control": "screen-share",
|
|
484
|
+
"data-avatar-control": "screen-share",
|
|
485
|
+
"data-avatar-enabled": isScreenShareEnabled,
|
|
374
486
|
"aria-label": "Toggle screen share",
|
|
375
487
|
children: screenShareIcon
|
|
376
488
|
}
|
|
@@ -380,7 +492,8 @@ function ControlBar({
|
|
|
380
492
|
{
|
|
381
493
|
type: "button",
|
|
382
494
|
onClick: session.end,
|
|
383
|
-
"data-control": "end-call",
|
|
495
|
+
"data-avatar-control": "end-call",
|
|
496
|
+
"data-avatar-enabled": true,
|
|
384
497
|
"aria-label": "End call",
|
|
385
498
|
children: phoneIcon
|
|
386
499
|
}
|
|
@@ -454,7 +567,11 @@ var phoneIcon = /* @__PURE__ */ jsx(
|
|
|
454
567
|
children: /* @__PURE__ */ jsx("path", { d: "M12.8429 22.5693L11.4018 21.0986C11.2675 20.9626 11.1625 20.7995 11.0935 20.6197C11.0245 20.4399 10.9931 20.2474 11.0013 20.0545C11.0094 19.8616 11.0569 19.6726 11.1408 19.4995C11.2247 19.3265 11.343 19.1732 11.4883 19.0495C13.127 17.7049 15.0519 16.7714 17.1083 16.3239C19.0064 15.892 20.9744 15.892 22.8725 16.3239C24.9374 16.7743 26.8693 17.7147 28.5117 19.0691C28.6565 19.1924 28.7746 19.3451 28.8585 19.5176C28.9423 19.69 28.99 19.8784 28.9986 20.0707C29.0072 20.263 28.9764 20.455 28.9083 20.6345C28.8402 20.814 28.7362 20.9771 28.603 21.1133L27.1619 22.584C26.9311 22.8242 26.6226 22.9706 26.2938 22.9959C25.9651 23.0211 25.6385 22.9235 25.3751 22.7212C24.8531 22.3127 24.2875 21.9657 23.689 21.6869C23.4525 21.5774 23.2517 21.4009 23.1103 21.1785C22.969 20.9561 22.8931 20.697 22.8917 20.4319V19.1867C21.0053 18.6573 19.0139 18.6573 17.1275 19.1867V20.4319C17.1261 20.697 17.0502 20.9561 16.9089 21.1785C16.7676 21.4009 16.5667 21.5774 16.3302 21.6869C15.7317 21.9657 15.1661 22.3127 14.6442 22.7212C14.3779 22.9258 14.0473 23.0233 13.7152 22.9953C13.383 22.9673 13.0726 22.8156 12.8429 22.5693Z" })
|
|
455
568
|
}
|
|
456
569
|
);
|
|
457
|
-
function UserVideo({
|
|
570
|
+
function UserVideo({
|
|
571
|
+
children,
|
|
572
|
+
mirror = true,
|
|
573
|
+
...props
|
|
574
|
+
}) {
|
|
458
575
|
const { localVideoTrackRef, isCameraEnabled } = useLocalMedia();
|
|
459
576
|
const hasVideo = localVideoTrackRef !== null && isTrackReference(localVideoTrackRef);
|
|
460
577
|
const state = {
|
|
@@ -469,9 +586,10 @@ function UserVideo({ children, mirror = true, ...props }) {
|
|
|
469
586
|
"div",
|
|
470
587
|
{
|
|
471
588
|
...props,
|
|
472
|
-
"data-
|
|
473
|
-
"data-
|
|
474
|
-
"data-
|
|
589
|
+
"data-avatar-user-video": "",
|
|
590
|
+
"data-avatar-has-video": hasVideo,
|
|
591
|
+
"data-avatar-camera-enabled": isCameraEnabled,
|
|
592
|
+
"data-avatar-mirror": mirror,
|
|
475
593
|
children: hasVideo && localVideoTrackRef && isTrackReference(localVideoTrackRef) && /* @__PURE__ */ jsx(VideoTrack, { trackRef: localVideoTrackRef })
|
|
476
594
|
}
|
|
477
595
|
);
|
|
@@ -492,19 +610,44 @@ function AvatarCall({
|
|
|
492
610
|
...props
|
|
493
611
|
}) {
|
|
494
612
|
const onErrorRef = useLatest(onError);
|
|
495
|
-
const
|
|
613
|
+
const credentialsState = useCredentials({
|
|
496
614
|
avatarId,
|
|
497
615
|
sessionId,
|
|
498
616
|
sessionKey,
|
|
499
617
|
credentials: directCredentials,
|
|
500
618
|
connectUrl,
|
|
501
619
|
connect,
|
|
502
|
-
baseUrl
|
|
620
|
+
baseUrl,
|
|
621
|
+
onError: (err) => onErrorRef.current?.(err)
|
|
503
622
|
});
|
|
504
623
|
const handleSessionError = (err) => {
|
|
505
624
|
onErrorRef.current?.(err);
|
|
506
625
|
};
|
|
507
626
|
const backgroundStyle = avatarImageUrl ? { "--avatar-image": `url(${avatarImageUrl})` } : void 0;
|
|
627
|
+
const defaultChildren = /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
628
|
+
/* @__PURE__ */ jsx(AvatarVideo, {}),
|
|
629
|
+
/* @__PURE__ */ jsx(UserVideo, {}),
|
|
630
|
+
/* @__PURE__ */ jsx(ControlBar, {})
|
|
631
|
+
] });
|
|
632
|
+
if (credentialsState.status !== "ready") {
|
|
633
|
+
return /* @__PURE__ */ jsx(
|
|
634
|
+
"div",
|
|
635
|
+
{
|
|
636
|
+
...props,
|
|
637
|
+
"data-avatar-call": "",
|
|
638
|
+
"data-avatar-id": avatarId,
|
|
639
|
+
style: { ...props.style, ...backgroundStyle },
|
|
640
|
+
children: /* @__PURE__ */ jsx(
|
|
641
|
+
LoadingSessionProvider,
|
|
642
|
+
{
|
|
643
|
+
state: credentialsState.status === "error" ? "error" : "connecting",
|
|
644
|
+
error: credentialsState.error,
|
|
645
|
+
children: children ?? defaultChildren
|
|
646
|
+
}
|
|
647
|
+
)
|
|
648
|
+
}
|
|
649
|
+
);
|
|
650
|
+
}
|
|
508
651
|
return /* @__PURE__ */ jsx(
|
|
509
652
|
"div",
|
|
510
653
|
{
|
|
@@ -515,30 +658,31 @@ function AvatarCall({
|
|
|
515
658
|
children: /* @__PURE__ */ jsx(
|
|
516
659
|
AvatarSession,
|
|
517
660
|
{
|
|
518
|
-
credentials,
|
|
661
|
+
credentials: credentialsState.credentials,
|
|
519
662
|
onEnd,
|
|
520
663
|
onError: handleSessionError,
|
|
521
664
|
__unstable_roomOptions,
|
|
522
|
-
children: children ??
|
|
523
|
-
/* @__PURE__ */ jsx(AvatarVideo, {}),
|
|
524
|
-
/* @__PURE__ */ jsx(UserVideo, {}),
|
|
525
|
-
/* @__PURE__ */ jsx(ControlBar, {})
|
|
526
|
-
] })
|
|
665
|
+
children: children ?? defaultChildren
|
|
527
666
|
}
|
|
528
667
|
)
|
|
529
668
|
}
|
|
530
669
|
);
|
|
531
670
|
}
|
|
532
|
-
function ScreenShareVideo({
|
|
533
|
-
|
|
671
|
+
function ScreenShareVideo({
|
|
672
|
+
children,
|
|
673
|
+
...props
|
|
674
|
+
}) {
|
|
675
|
+
const room = useMaybeRoomContext();
|
|
676
|
+
const hasRoomContext = room !== void 0;
|
|
677
|
+
const { localParticipant } = useLocalParticipant({ room });
|
|
534
678
|
const tracks = useTracks(
|
|
535
679
|
[{ source: Track.Source.ScreenShare, withPlaceholder: false }],
|
|
536
|
-
{ onlySubscribed: false }
|
|
680
|
+
{ onlySubscribed: false, room: hasRoomContext ? room : void 0 }
|
|
537
681
|
);
|
|
538
682
|
const localIdentity = localParticipant?.identity;
|
|
539
|
-
const screenShareTrackRef = tracks.find(
|
|
683
|
+
const screenShareTrackRef = hasRoomContext ? tracks.find(
|
|
540
684
|
(trackRef) => trackRef.participant.identity === localIdentity && trackRef.source === Track.Source.ScreenShare
|
|
541
|
-
) ?? null;
|
|
685
|
+
) ?? null : null;
|
|
542
686
|
const isSharing = screenShareTrackRef !== null && isTrackReference(screenShareTrackRef);
|
|
543
687
|
const state = {
|
|
544
688
|
isSharing,
|
|
@@ -550,7 +694,7 @@ function ScreenShareVideo({ children, ...props }) {
|
|
|
550
694
|
if (!isSharing) {
|
|
551
695
|
return null;
|
|
552
696
|
}
|
|
553
|
-
return /* @__PURE__ */ jsx("div", { ...props, "data-sharing": isSharing, children: screenShareTrackRef && isTrackReference(screenShareTrackRef) && /* @__PURE__ */ jsx(VideoTrack, { trackRef: screenShareTrackRef }) });
|
|
697
|
+
return /* @__PURE__ */ jsx("div", { ...props, "data-avatar-screen-share": "", "data-avatar-sharing": isSharing, children: screenShareTrackRef && isTrackReference(screenShareTrackRef) && /* @__PURE__ */ jsx(VideoTrack, { trackRef: screenShareTrackRef }) });
|
|
554
698
|
}
|
|
555
699
|
|
|
556
700
|
export { AvatarCall, AvatarSession, AvatarVideo, ControlBar, ScreenShareVideo, UserVideo, useAvatar, useAvatarSession, useAvatarStatus, useLocalMedia };
|