@equos/react 3.0.2-rc.4 → 3.0.2-rc.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,12 @@
1
+ import { EquosLocale } from '../utils/copy.utils';
2
+ export declare function EquosCharacterTile({ identity, name, locale, className, startedAt, maxSeconds, recoveryTimeInSeconds, showTimeLeft, onShouldLeave, }: {
3
+ identity: string;
4
+ name: string;
5
+ locale?: EquosLocale;
6
+ className?: string;
7
+ startedAt: Date;
8
+ maxSeconds: number;
9
+ recoveryTimeInSeconds?: number;
10
+ showTimeLeft?: boolean;
11
+ onShouldLeave?: () => void | Promise<void>;
12
+ }): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,82 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.EquosCharacterTile = EquosCharacterTile;
4
+ const jsx_runtime_1 = require("react/jsx-runtime");
5
+ const components_react_1 = require("@livekit/components-react");
6
+ const cn_1 = require("../utils/cn");
7
+ const react_1 = require("react");
8
+ const livekit_client_1 = require("livekit-client");
9
+ const copy_utils_1 = require("../utils/copy.utils");
10
+ function EquosCharacterTile({ identity, name, locale = copy_utils_1.EquosLocale.EN, className, startedAt, maxSeconds, recoveryTimeInSeconds = 3, showTimeLeft = true, onShouldLeave, }) {
11
+ const waitForCharacterToJoin = 20;
12
+ const [joined, setJoined] = (0, react_1.useState)(false);
13
+ const [leftTimeout, setLeftTimeout] = (0, react_1.useState)(null);
14
+ const [remainingTime, setRemainingTime] = (0, react_1.useState)(null);
15
+ const [duration, setDuration] = (0, react_1.useState)(0);
16
+ const participants = (0, components_react_1.useParticipants)();
17
+ const trackRef = (0, react_1.useMemo)(() => {
18
+ const participant = participants.find((p) => p.identity === identity);
19
+ if (!participant || !participant.trackPublications) {
20
+ return null;
21
+ }
22
+ const publication = Array.from(participant.trackPublications.values()).find((pub) => pub.source === livekit_client_1.Track.Source.Camera);
23
+ if (!publication) {
24
+ return null;
25
+ }
26
+ return {
27
+ participant,
28
+ publication,
29
+ source: livekit_client_1.Track.Source.Camera,
30
+ };
31
+ }, [identity, participants]);
32
+ const hasTroubleJoining = (0, react_1.useMemo)(() => {
33
+ return !joined && duration > waitForCharacterToJoin - 10;
34
+ }, [joined, duration]);
35
+ const joiningCopy = (0, react_1.useMemo)(() => {
36
+ return copy_utils_1.CopyUtils.joiningCopy(locale, name);
37
+ }, [name, locale]);
38
+ const notJoiningCopy = (0, react_1.useMemo)(() => {
39
+ return copy_utils_1.CopyUtils.notJoiningCopy(locale, name);
40
+ }, [name, locale]);
41
+ const endingConversationCopy = (0, react_1.useMemo)(() => {
42
+ return copy_utils_1.CopyUtils.endingConversationCopy(locale, Math.max(waitForCharacterToJoin - duration, 0));
43
+ }, [duration, locale, waitForCharacterToJoin]);
44
+ // Detect if we should leave the conversation because the character is not joining...
45
+ (0, react_1.useEffect)(() => {
46
+ if (!onShouldLeave)
47
+ return;
48
+ if (!joined && duration > waitForCharacterToJoin) {
49
+ onShouldLeave();
50
+ }
51
+ }, [joined, duration, waitForCharacterToJoin, onShouldLeave]);
52
+ (0, react_1.useEffect)(() => {
53
+ const i = setInterval(() => {
54
+ const elapsedTime = new Date().getTime() - startedAt.getTime();
55
+ const remainingSeconds = Math.round(Math.max(0, maxSeconds * 1000 - elapsedTime) / 1000);
56
+ setRemainingTime(copy_utils_1.CopyUtils.timeLeftCopy(locale, remainingSeconds));
57
+ setDuration((duration) => duration + 1);
58
+ }, 1000);
59
+ return () => clearInterval(i);
60
+ }, [startedAt, maxSeconds]);
61
+ (0, react_1.useEffect)(() => {
62
+ if (joined) {
63
+ if (!trackRef && !leftTimeout && onShouldLeave) {
64
+ setLeftTimeout(setTimeout(() => {
65
+ onShouldLeave?.();
66
+ }, recoveryTimeInSeconds * 1000));
67
+ }
68
+ }
69
+ else if (trackRef) {
70
+ setJoined(true);
71
+ if (leftTimeout) {
72
+ clearTimeout(leftTimeout);
73
+ }
74
+ }
75
+ return () => {
76
+ if (leftTimeout) {
77
+ clearTimeout(leftTimeout);
78
+ }
79
+ };
80
+ }, [joined, trackRef]);
81
+ return ((0, jsx_runtime_1.jsxs)("div", { className: (0, cn_1.cn)('relative w-full h-full overflow-hidden bg-black', className), children: [remainingTime && showTimeLeft && ((0, jsx_runtime_1.jsx)("span", { className: "absolute right-4 top-4 z-20 text-xs text-white rounded-full bg-black/10 py-1 px-2", children: remainingTime })), !joined && !hasTroubleJoining && ((0, jsx_runtime_1.jsx)("span", { className: "absolute left-1/2 top-1/2 -translate-x-1/2 -translate-y-1/2 z-20 text-xs text-white", children: joiningCopy })), !joined && hasTroubleJoining && ((0, jsx_runtime_1.jsxs)("span", { className: "absolute left-1/2 top-1/2 -translate-x-1/2 -translate-y-1/2 z-20 flex flex-col items-center", children: [(0, jsx_runtime_1.jsx)("span", { className: "text-xs text-white", children: notJoiningCopy }), (0, jsx_runtime_1.jsx)("span", { className: "text-xs text-white", children: endingConversationCopy })] })), trackRef && (0, jsx_runtime_1.jsx)(components_react_1.VideoTrack, { trackRef: trackRef, className: "w-full h-full" })] }));
82
+ }
@@ -1,11 +1,14 @@
1
1
  import type { EquosConversationWithCharacter } from '@equos/core';
2
- export declare function EquosConversationRenderer({ conversation, accessToken, allowMic, allowCamera, allowScreenshare, allowHangUp, className, onHangUp, }: {
2
+ import { EquosLocale } from '../utils/copy.utils';
3
+ export declare function EquosConversationRenderer({ conversation, accessToken, allowMic, allowCamera, allowScreenshare, allowHangUp, className, characterVideoClassName, locale, onHangUp, }: {
3
4
  conversation?: EquosConversationWithCharacter | null;
4
5
  accessToken?: string | null;
5
6
  allowMic?: boolean;
6
7
  allowCamera?: boolean;
7
8
  allowScreenshare?: boolean;
8
9
  className?: string;
10
+ characterVideoClassName?: string;
9
11
  allowHangUp?: boolean;
12
+ locale?: EquosLocale;
10
13
  onHangUp?: () => void | Promise<void>;
11
14
  }): import("react/jsx-runtime").JSX.Element;
@@ -11,8 +11,9 @@ const equos_hangup_button_1 = require("./equos-hangup-button");
11
11
  const react_1 = require("react");
12
12
  const livekit_client_1 = require("livekit-client");
13
13
  const equos_video_tile_1 = require("./equos-video-tile");
14
- const equos_character_video_1 = require("./equos-character-video");
15
- function EquosConversationRenderer({ conversation, accessToken, allowMic = true, allowCamera = true, allowScreenshare = false, allowHangUp = true, className, onHangUp, }) {
14
+ const equos_character_tile_1 = require("./equos-character-tile");
15
+ const copy_utils_1 = require("../utils/copy.utils");
16
+ function EquosConversationRenderer({ conversation, accessToken, allowMic = true, allowCamera = true, allowScreenshare = false, allowHangUp = true, className, characterVideoClassName, locale = copy_utils_1.EquosLocale.EN, onHangUp, }) {
16
17
  const [hangingUp, setHangingUp] = (0, react_1.useState)(false);
17
18
  const [_, setMicEnabled] = (0, react_1.useState)(false);
18
19
  const [cameraEnabled, setCameraEnabled] = (0, react_1.useState)(false);
@@ -31,7 +32,7 @@ function EquosConversationRenderer({ conversation, accessToken, allowMic = true,
31
32
  const [cameraTileDragging, setCameraTileDragging] = (0, react_1.useState)(false);
32
33
  const [screenTilePos, setScreenTilePos] = (0, react_1.useState)({
33
34
  x: 8,
34
- y: 112,
35
+ y: 160,
35
36
  });
36
37
  const [screenTileDragOffset, setScreenTileDragOffset] = (0, react_1.useState)({
37
38
  x: 0,
@@ -105,8 +106,8 @@ function EquosConversationRenderer({ conversation, accessToken, allowMic = true,
105
106
  return ((0, jsx_runtime_1.jsx)("div", { ref: containerRef, onMouseMove: onMouseMove, onMouseUp: onMouseUp, onMouseLeave: onMouseUp, className: (0, cn_1.cn)('relative w-full h-full', className), children: (0, jsx_runtime_1.jsxs)(components_react_1.LiveKitRoom, { serverUrl: conversation.serverUrl, token: accessToken, audio: allowMic, video: allowCamera, screen: false, className: "w-full h-full", children: [allowCamera && cameraEnabled && ((0, jsx_runtime_1.jsx)("div", { ref: cameraTileRef, onMouseDown: onCameraTileMouseDown, className: (0, cn_1.cn)('absolute z-50 select-none', cameraTileDragging ? 'cursor-grabbing' : 'cursor-grab'), style: {
106
107
  top: cameraTilePos.y,
107
108
  left: cameraTilePos.x,
108
- }, children: (0, jsx_runtime_1.jsx)(equos_video_tile_1.EquosVideoTile, { identity: conversation.consumerIdentity, source: livekit_client_1.Track.Source.Camera }) })), allowScreenshare && screenshareEnabled && ((0, jsx_runtime_1.jsx)("div", { ref: screenTileRef, onMouseDown: onScreenTileMouseDown, className: (0, cn_1.cn)('absolute z-50 select-none', cameraTileDragging ? 'cursor-grabbing' : 'cursor-grab'), style: {
109
+ }, children: (0, jsx_runtime_1.jsx)(equos_video_tile_1.EquosVideoTile, { identity: conversation.consumerIdentity, source: livekit_client_1.Track.Source.Camera }) })), allowScreenshare && screenshareEnabled && ((0, jsx_runtime_1.jsx)("div", { ref: screenTileRef, onMouseDown: onScreenTileMouseDown, className: (0, cn_1.cn)('absolute z-50', cameraTileDragging ? 'cursor-grabbing' : 'cursor-grab'), style: {
109
110
  top: screenTilePos.y,
110
111
  left: screenTilePos.x,
111
- }, children: (0, jsx_runtime_1.jsx)(equos_video_tile_1.EquosVideoTile, { identity: conversation.consumerIdentity, source: livekit_client_1.Track.Source.ScreenShare }) })), (0, jsx_runtime_1.jsx)(equos_character_video_1.EquosCharacterVideo, { identity: conversation.character.livekitIdentity }), (0, jsx_runtime_1.jsx)(components_react_1.RoomAudioRenderer, {}), (0, jsx_runtime_1.jsxs)("div", { className: "absolute grid grid-cols-3 gap-2 max-w-full bottom-8 left-1/2 -translate-x-1/2", children: [(0, jsx_runtime_1.jsx)("div", { children: allowMic && (0, jsx_runtime_1.jsx)(equos_mic_toggle_1.EquosMicToggle, { onToggle: setMicEnabled }) }), (0, jsx_runtime_1.jsx)("div", { children: allowHangUp && ((0, jsx_runtime_1.jsx)(equos_hangup_button_1.EquosHangupButton, { onHangup: handleHangUp, loading: hangingUp })) }), (0, jsx_runtime_1.jsxs)("div", { children: [allowCamera && (0, jsx_runtime_1.jsx)(equos_camera_toggle_1.EquosCameraToggle, { onToggle: setCameraEnabled }), allowScreenshare && ((0, jsx_runtime_1.jsx)(equos_screenshare_toggle_1.EquosScreenshareToggle, { onToggle: setScreenshareEnabled }))] })] })] }) }));
112
+ }, children: (0, jsx_runtime_1.jsx)(equos_video_tile_1.EquosVideoTile, { identity: conversation.consumerIdentity, source: livekit_client_1.Track.Source.ScreenShare }) })), (0, jsx_runtime_1.jsx)(equos_character_tile_1.EquosCharacterTile, { identity: conversation.character.livekitIdentity, name: conversation.character.name, locale: locale, startedAt: conversation.startedAt, maxSeconds: conversation.maxSeconds, recoveryTimeInSeconds: 3, onShouldLeave: handleHangUp, className: characterVideoClassName }), (0, jsx_runtime_1.jsx)(components_react_1.RoomAudioRenderer, {}), (0, jsx_runtime_1.jsxs)("div", { className: "absolute grid grid-cols-3 gap-2 max-w-full bottom-8 left-1/2 -translate-x-1/2", children: [(0, jsx_runtime_1.jsx)("div", { className: "justify-self-end", children: allowMic && (0, jsx_runtime_1.jsx)(equos_mic_toggle_1.EquosMicToggle, { onToggle: setMicEnabled }) }), (0, jsx_runtime_1.jsx)("div", { children: allowHangUp && ((0, jsx_runtime_1.jsx)(equos_hangup_button_1.EquosHangupButton, { onHangup: handleHangUp, loading: hangingUp })) }), (0, jsx_runtime_1.jsxs)("div", { className: "flex items-center gap-2", children: [allowCamera && (0, jsx_runtime_1.jsx)(equos_camera_toggle_1.EquosCameraToggle, { onToggle: setCameraEnabled }), allowScreenshare && ((0, jsx_runtime_1.jsx)(equos_screenshare_toggle_1.EquosScreenshareToggle, { onToggle: setScreenshareEnabled }))] })] })] }) }));
112
113
  }
@@ -8,7 +8,7 @@ const lucide_react_1 = require("lucide-react");
8
8
  const components_react_1 = require("@livekit/components-react");
9
9
  const livekit_client_1 = require("livekit-client");
10
10
  function EquosVideoTile({ identity, defaultToLocal = true, className, source = livekit_client_1.Track.Source.Camera, }) {
11
- const [expanded, setExpanded] = (0, react_1.useState)(true);
11
+ const [expanded, setExpanded] = (0, react_1.useState)(false);
12
12
  const participants = (0, components_react_1.useParticipants)();
13
13
  const trackRef = (0, react_1.useMemo)(() => {
14
14
  const participant = participants.find((p) => p.identity === identity || (defaultToLocal && p.isLocal));
@@ -25,5 +25,8 @@ function EquosVideoTile({ identity, defaultToLocal = true, className, source = l
25
25
  source,
26
26
  };
27
27
  }, [identity, source, participants]);
28
- return ((0, jsx_runtime_1.jsxs)("div", { className: (0, cn_1.cn)('relative border border-white/60 shadow-xl rounded-2xl bg-black aspect-video transition-all max-w-full overflow-hidden', expanded ? 'w-96' : 'w-64', className), children: [(0, jsx_runtime_1.jsx)("button", { className: "absolute top-4 right-4 text-white cursor-pointer", onClick: () => setExpanded(!expanded), children: expanded ? (0, jsx_runtime_1.jsx)(lucide_react_1.Minimize2, { size: 12 }) : (0, jsx_runtime_1.jsx)(lucide_react_1.Maximize2, { size: 12 }) }), trackRef && (0, jsx_runtime_1.jsx)(components_react_1.VideoTrack, { trackRef: trackRef, className: "w-full h-full" })] }));
28
+ return ((0, jsx_runtime_1.jsxs)("div", { className: (0, cn_1.cn)('relative border border-white/60 shadow-xl rounded-2xl bg-black aspect-video transition-all max-w-full overflow-hidden', expanded ? 'w-96' : 'w-64', className), children: [(0, jsx_runtime_1.jsx)("button", { className: "absolute top-2 right-2 text-white cursor-pointer p-2 z-10 hover:bg-black/10 rounded-full transition-colors", onClick: (e) => {
29
+ e.stopPropagation();
30
+ setExpanded(!expanded);
31
+ }, children: expanded ? (0, jsx_runtime_1.jsx)(lucide_react_1.Minimize2, { size: 12 }) : (0, jsx_runtime_1.jsx)(lucide_react_1.Maximize2, { size: 12 }) }), trackRef && (0, jsx_runtime_1.jsx)(components_react_1.VideoTrack, { trackRef: trackRef, className: "w-full h-full" })] }));
29
32
  }
@@ -4,5 +4,5 @@ export * from './equos-camera-toggle';
4
4
  export * from './equos-screenshare-toggle';
5
5
  export * from './equos-hangup-button';
6
6
  export * from './equos-video-tile';
7
- export * from './equos-character-video';
7
+ export * from './equos-character-tile';
8
8
  export * from './equos-conversation-renderer';
@@ -20,5 +20,5 @@ __exportStar(require("./equos-camera-toggle"), exports);
20
20
  __exportStar(require("./equos-screenshare-toggle"), exports);
21
21
  __exportStar(require("./equos-hangup-button"), exports);
22
22
  __exportStar(require("./equos-video-tile"), exports);
23
- __exportStar(require("./equos-character-video"), exports);
23
+ __exportStar(require("./equos-character-tile"), exports);
24
24
  __exportStar(require("./equos-conversation-renderer"), exports);
package/dist/styles.css CHANGED
@@ -25,6 +25,7 @@
25
25
  --radius-3xl: 1.5rem;
26
26
  --animate-spin: spin 1s linear infinite;
27
27
  --blur-sm: 8px;
28
+ --blur-2xl: 40px;
28
29
  --aspect-video: 16 / 9;
29
30
  --default-transition-duration: 150ms;
30
31
  --default-transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
@@ -181,27 +182,63 @@
181
182
  }
182
183
  }
183
184
  @layer utilities {
185
+ .pointer-events-none {
186
+ pointer-events: none;
187
+ }
184
188
  .absolute {
185
189
  position: absolute;
186
190
  }
191
+ .fixed {
192
+ position: fixed;
193
+ }
187
194
  .relative {
188
195
  position: relative;
189
196
  }
190
197
  .static {
191
198
  position: static;
192
199
  }
200
+ .top-0 {
201
+ top: calc(var(--spacing) * 0);
202
+ }
203
+ .top-1\/2 {
204
+ top: calc(1/2 * 100%);
205
+ }
206
+ .top-2 {
207
+ top: calc(var(--spacing) * 2);
208
+ }
193
209
  .top-4 {
194
210
  top: calc(var(--spacing) * 4);
195
211
  }
212
+ .right-0 {
213
+ right: calc(var(--spacing) * 0);
214
+ }
215
+ .right-2 {
216
+ right: calc(var(--spacing) * 2);
217
+ }
196
218
  .right-4 {
197
219
  right: calc(var(--spacing) * 4);
198
220
  }
221
+ .bottom-0 {
222
+ bottom: calc(var(--spacing) * 0);
223
+ }
199
224
  .bottom-8 {
200
225
  bottom: calc(var(--spacing) * 8);
201
226
  }
227
+ .left-0 {
228
+ left: calc(var(--spacing) * 0);
229
+ }
202
230
  .left-1\/2 {
203
231
  left: calc(1/2 * 100%);
204
232
  }
233
+ .-z-10 {
234
+ z-index: calc(10 * -1);
235
+ }
236
+ .z-10 {
237
+ z-index: 10;
238
+ }
239
+ .z-20 {
240
+ z-index: 20;
241
+ }
205
242
  .z-50 {
206
243
  z-index: 50;
207
244
  }
@@ -255,9 +292,16 @@
255
292
  width: calc(var(--spacing) * 32);
256
293
  height: calc(var(--spacing) * 32);
257
294
  }
295
+ .size-full {
296
+ width: 100%;
297
+ height: 100%;
298
+ }
258
299
  .h-full {
259
300
  height: 100%;
260
301
  }
302
+ .max-h-\[512px\] {
303
+ max-height: 512px;
304
+ }
261
305
  .w-32 {
262
306
  width: calc(var(--spacing) * 32);
263
307
  }
@@ -270,6 +314,9 @@
270
314
  .w-full {
271
315
  width: 100%;
272
316
  }
317
+ .max-w-\[512px\] {
318
+ max-width: 512px;
319
+ }
273
320
  .max-w-full {
274
321
  max-width: 100%;
275
322
  }
@@ -277,6 +324,10 @@
277
324
  --tw-translate-x: calc(calc(1/2 * 100%) * -1);
278
325
  translate: var(--tw-translate-x) var(--tw-translate-y);
279
326
  }
327
+ .-translate-y-1\/2 {
328
+ --tw-translate-y: calc(calc(1/2 * 100%) * -1);
329
+ translate: var(--tw-translate-x) var(--tw-translate-y);
330
+ }
280
331
  .animate-spin {
281
332
  animation: var(--animate-spin);
282
333
  }
@@ -313,6 +364,9 @@
313
364
  .gap-4 {
314
365
  gap: calc(var(--spacing) * 4);
315
366
  }
367
+ .justify-self-end {
368
+ justify-self: flex-end;
369
+ }
316
370
  .overflow-hidden {
317
371
  overflow: hidden;
318
372
  }
@@ -359,6 +413,12 @@
359
413
  .bg-black {
360
414
  background-color: var(--color-black);
361
415
  }
416
+ .bg-black\/10 {
417
+ background-color: color-mix(in srgb, #000 10%, transparent);
418
+ @supports (color: color-mix(in lab, red, red)) {
419
+ background-color: color-mix(in oklab, var(--color-black) 10%, transparent);
420
+ }
421
+ }
362
422
  .bg-white\/20 {
363
423
  background-color: color-mix(in srgb, #fff 20%, transparent);
364
424
  @supports (color: color-mix(in lab, red, red)) {
@@ -371,12 +431,21 @@
371
431
  background-color: color-mix(in oklab, var(--color-white) 60%, transparent);
372
432
  }
373
433
  }
434
+ .p-2 {
435
+ padding: calc(var(--spacing) * 2);
436
+ }
374
437
  .p-3 {
375
438
  padding: calc(var(--spacing) * 3);
376
439
  }
377
440
  .p-4 {
378
441
  padding: calc(var(--spacing) * 4);
379
442
  }
443
+ .px-2 {
444
+ padding-inline: calc(var(--spacing) * 2);
445
+ }
446
+ .py-1 {
447
+ padding-block: calc(var(--spacing) * 1);
448
+ }
380
449
  .text-2xl {
381
450
  font-size: var(--text-2xl);
382
451
  line-height: var(--tw-leading, var(--text-2xl--line-height));
@@ -402,10 +471,23 @@
402
471
  .text-white {
403
472
  color: var(--color-white);
404
473
  }
474
+ .opacity-0 {
475
+ opacity: 0%;
476
+ }
405
477
  .shadow-xl {
406
478
  --tw-shadow: 0 20px 25px -5px var(--tw-shadow-color, rgb(0 0 0 / 0.1)), 0 8px 10px -6px var(--tw-shadow-color, rgb(0 0 0 / 0.1));
407
479
  box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);
408
480
  }
481
+ .backdrop-blur-2xl {
482
+ --tw-backdrop-blur: blur(var(--blur-2xl));
483
+ -webkit-backdrop-filter: var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,);
484
+ backdrop-filter: var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,);
485
+ }
486
+ .backdrop-blur-none {
487
+ --tw-backdrop-blur: ;
488
+ -webkit-backdrop-filter: var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,);
489
+ backdrop-filter: var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,);
490
+ }
409
491
  .backdrop-blur-sm {
410
492
  --tw-backdrop-blur: blur(var(--blur-sm));
411
493
  -webkit-backdrop-filter: var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,);
@@ -421,6 +503,10 @@
421
503
  transition-timing-function: var(--tw-ease, var(--default-transition-timing-function));
422
504
  transition-duration: var(--tw-duration, var(--default-transition-duration));
423
505
  }
506
+ .duration-300 {
507
+ --tw-duration: 300ms;
508
+ transition-duration: 300ms;
509
+ }
424
510
  .select-none {
425
511
  -webkit-user-select: none;
426
512
  user-select: none;
@@ -432,6 +518,16 @@
432
518
  }
433
519
  }
434
520
  }
521
+ .hover\:bg-black\/10 {
522
+ &:hover {
523
+ @media (hover: hover) {
524
+ background-color: color-mix(in srgb, #000 10%, transparent);
525
+ @supports (color: color-mix(in lab, red, red)) {
526
+ background-color: color-mix(in oklab, var(--color-black) 10%, transparent);
527
+ }
528
+ }
529
+ }
530
+ }
435
531
  .hover\:bg-white\/40 {
436
532
  &:hover {
437
533
  @media (hover: hover) {
@@ -612,6 +708,10 @@
612
708
  syntax: "*";
613
709
  inherits: false;
614
710
  }
711
+ @property --tw-duration {
712
+ syntax: "*";
713
+ inherits: false;
714
+ }
615
715
  @keyframes spin {
616
716
  to {
617
717
  transform: rotate(360deg);
@@ -648,6 +748,7 @@
648
748
  --tw-backdrop-opacity: initial;
649
749
  --tw-backdrop-saturate: initial;
650
750
  --tw-backdrop-sepia: initial;
751
+ --tw-duration: initial;
651
752
  }
652
753
  }
653
754
  }
@@ -0,0 +1,24 @@
1
+ export declare enum EquosLocale {
2
+ EN = "en",
3
+ FR = "fr",
4
+ ES = "es",
5
+ DE = "de",
6
+ IT = "it",
7
+ PT = "pt",
8
+ NL = "nl",
9
+ RU = "ru",
10
+ ZH = "zh",
11
+ JA = "ja",
12
+ KO = "ko",
13
+ AR = "ar",
14
+ HI = "hi"
15
+ }
16
+ export declare class CopyUtils {
17
+ static talkToCopy(locale: EquosLocale, name?: string): string;
18
+ static availableNowCopy(locale: string): string;
19
+ static timeLeftCopy(locale: string, remaining: number): string;
20
+ static failedToHangupCopy(locale: string): string;
21
+ static notJoiningCopy(locale: string, name: string): string;
22
+ static joiningCopy(locale: string, name: string): string;
23
+ static endingConversationCopy(locale: string, countdown: number): string;
24
+ }
@@ -0,0 +1,273 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.CopyUtils = exports.EquosLocale = void 0;
4
+ var EquosLocale;
5
+ (function (EquosLocale) {
6
+ EquosLocale["EN"] = "en";
7
+ EquosLocale["FR"] = "fr";
8
+ EquosLocale["ES"] = "es";
9
+ EquosLocale["DE"] = "de";
10
+ EquosLocale["IT"] = "it";
11
+ EquosLocale["PT"] = "pt";
12
+ EquosLocale["NL"] = "nl";
13
+ EquosLocale["RU"] = "ru";
14
+ EquosLocale["ZH"] = "zh";
15
+ EquosLocale["JA"] = "ja";
16
+ EquosLocale["KO"] = "ko";
17
+ EquosLocale["AR"] = "ar";
18
+ EquosLocale["HI"] = "hi";
19
+ })(EquosLocale || (exports.EquosLocale = EquosLocale = {}));
20
+ class CopyUtils {
21
+ static talkToCopy(locale, name) {
22
+ const assistant = name ||
23
+ {
24
+ [EquosLocale.FR]: 'votre assistant',
25
+ [EquosLocale.ES]: 'tu asistente',
26
+ [EquosLocale.DE]: 'Ihrem Assistenten',
27
+ [EquosLocale.IT]: 'il tuo assistente',
28
+ [EquosLocale.PT]: 'seu assistente',
29
+ [EquosLocale.NL]: 'je assistent',
30
+ [EquosLocale.RU]: 'вашим помощником',
31
+ [EquosLocale.ZH]: '您的助手',
32
+ [EquosLocale.JA]: 'あなたのアシスタント',
33
+ [EquosLocale.KO]: '귀하의 어시스턴트',
34
+ [EquosLocale.EN]: 'your assistant',
35
+ [EquosLocale.AR]: 'مساعدك',
36
+ [EquosLocale.HI]: 'आपका सहायक',
37
+ }[locale] ||
38
+ 'your assistant';
39
+ switch (locale) {
40
+ case EquosLocale.FR:
41
+ return `Parler à ${assistant}`;
42
+ case EquosLocale.ES:
43
+ return `Habla con ${assistant}`;
44
+ case EquosLocale.DE:
45
+ return `Chatten mit ${assistant}`;
46
+ case EquosLocale.IT:
47
+ return `Parla con ${assistant}`;
48
+ case EquosLocale.PT:
49
+ return `Fale com ${assistant}`;
50
+ case EquosLocale.NL:
51
+ return `Chat met ${assistant}`;
52
+ case EquosLocale.RU:
53
+ return `Пообщайтесь с ${assistant}`;
54
+ case EquosLocale.ZH:
55
+ return `与${assistant}聊天`;
56
+ case EquosLocale.JA:
57
+ return `${assistant}と話す`;
58
+ case EquosLocale.KO:
59
+ return `${assistant}와 대화`;
60
+ case EquosLocale.AR:
61
+ return `تكلم مع ${assistant}`;
62
+ case EquosLocale.HI:
63
+ return `${assistant} से बात करें`;
64
+ case EquosLocale.EN:
65
+ default:
66
+ return `Chat with ${assistant}`;
67
+ }
68
+ }
69
+ static availableNowCopy(locale) {
70
+ switch (locale) {
71
+ case EquosLocale.FR:
72
+ return `Disponible`;
73
+ case EquosLocale.ES:
74
+ return `Disponible`;
75
+ case EquosLocale.DE:
76
+ return `Verfügbar`;
77
+ case EquosLocale.IT:
78
+ return `Disponibile`;
79
+ case EquosLocale.PT:
80
+ return `Disponível`;
81
+ case EquosLocale.NL:
82
+ return `Beschikbaar`;
83
+ case EquosLocale.RU:
84
+ return `Доступно`;
85
+ case EquosLocale.ZH:
86
+ return `可用`;
87
+ case EquosLocale.JA:
88
+ return `利用可能`;
89
+ case EquosLocale.KO:
90
+ return `사용 가능`;
91
+ case EquosLocale.AR:
92
+ return `متاح`;
93
+ case EquosLocale.HI:
94
+ return `ऑनलाइन है`;
95
+ case EquosLocale.EN:
96
+ default:
97
+ return `Available`;
98
+ }
99
+ }
100
+ static timeLeftCopy(locale, remaining) {
101
+ const hours = Math.floor(remaining / 3600)
102
+ .toString()
103
+ .padStart(2, '0');
104
+ const minutes = Math.floor((remaining % 3600) / 60)
105
+ .toString()
106
+ .padStart(2, '0');
107
+ const seconds = (remaining % 60).toString().padStart(2, '0');
108
+ const parts = [];
109
+ let timeString = '';
110
+ if (remaining > 3600) {
111
+ parts.push(`${hours}h`);
112
+ }
113
+ parts.push(`${minutes}m`);
114
+ if (parts.length < 2) {
115
+ parts.push(`${seconds}s`);
116
+ }
117
+ timeString = parts.join('');
118
+ switch (locale) {
119
+ case EquosLocale.FR:
120
+ return `${timeString} restantes`;
121
+ case EquosLocale.ES:
122
+ return `${timeString} restantes`;
123
+ case EquosLocale.DE:
124
+ return `${timeString} verbleibend`;
125
+ case EquosLocale.IT:
126
+ return `${timeString} rimanenti`;
127
+ case EquosLocale.PT:
128
+ return `${timeString} restantes`;
129
+ case EquosLocale.NL:
130
+ return `${timeString} resterend`;
131
+ case EquosLocale.RU:
132
+ return `Осталось ${timeString}`;
133
+ case EquosLocale.ZH:
134
+ return `剩余 ${timeString}`;
135
+ case EquosLocale.JA:
136
+ return `残り ${timeString}`;
137
+ case EquosLocale.KO:
138
+ return `남은 시간 ${timeString}`;
139
+ case EquosLocale.AR:
140
+ return `متبقي ${timeString}`;
141
+ case EquosLocale.HI:
142
+ return `${timeString} बाकी`;
143
+ case EquosLocale.EN:
144
+ default:
145
+ return `${timeString} left`;
146
+ }
147
+ }
148
+ static failedToHangupCopy(locale) {
149
+ switch (locale) {
150
+ case EquosLocale.FR:
151
+ return `Nous n'avons pas réussi à raccrocher.`;
152
+ case EquosLocale.ES:
153
+ return `No pudimos colgar.`;
154
+ case EquosLocale.DE:
155
+ return `Auflegen fehlgeschlagen.`;
156
+ case EquosLocale.IT:
157
+ return `Non siamo riusciti a riagganciare.`;
158
+ case EquosLocale.PT:
159
+ return `Não conseguimos desligar.`;
160
+ case EquosLocale.NL:
161
+ return `We konden niet ophangen.`;
162
+ case EquosLocale.RU:
163
+ return `Не удалось завершить звонок.`;
164
+ case EquosLocale.ZH:
165
+ return `我们无法挂断。`;
166
+ case EquosLocale.JA:
167
+ return `通話を終了できませんでした。`;
168
+ case EquosLocale.KO:
169
+ return `전화를 끊지 못했습니다.`;
170
+ case EquosLocale.AR:
171
+ return `لم نتمكن من إنهاء المكالمة.`;
172
+ case EquosLocale.HI:
173
+ return `हम कॉल समाप्त नहीं कर सके।`;
174
+ case EquosLocale.EN:
175
+ default:
176
+ return `We failed to hang up.`;
177
+ }
178
+ }
179
+ static notJoiningCopy(locale, name) {
180
+ switch (locale) {
181
+ case EquosLocale.FR:
182
+ return `${name} à du mal à se connecter.`;
183
+ case EquosLocale.ES:
184
+ return `${name} tiene problemas para unirse.`;
185
+ case EquosLocale.DE:
186
+ return `${name} Probleme beim Beitreten hat.`;
187
+ case EquosLocale.IT:
188
+ return `${name} abbia difficoltà a connettersi.`;
189
+ case EquosLocale.PT:
190
+ return `${name} está com dificuldades para entrar.`;
191
+ case EquosLocale.NL:
192
+ return `${name} moeite heeft om deel te nemen.`;
193
+ case EquosLocale.RU:
194
+ return `${name} испытывает трудности с подключением.`;
195
+ case EquosLocale.ZH:
196
+ return `${name}加入时遇到困难。`;
197
+ case EquosLocale.JA:
198
+ return `${name}が参加できないようです。`;
199
+ case EquosLocale.KO:
200
+ return `${name}(이)가 참여하는 데 어려움을 겪고 있습니다.`;
201
+ case EquosLocale.AR:
202
+ return `${name} يواجه صعوبة في الانضمام.`;
203
+ case EquosLocale.HI:
204
+ return `${name} जुड़ने में परेशानी हो रही है।`;
205
+ case EquosLocale.EN:
206
+ default:
207
+ return `${name} is having trouble joining.`;
208
+ }
209
+ }
210
+ static joiningCopy(locale, name) {
211
+ switch (locale) {
212
+ case EquosLocale.FR:
213
+ return `${name} se connecte...`;
214
+ case EquosLocale.ES:
215
+ return `${name} se está uniendo...`;
216
+ case EquosLocale.DE:
217
+ return `${name} tritt bei...`;
218
+ case EquosLocale.IT:
219
+ return `${name} si sta connettendo...`;
220
+ case EquosLocale.PT:
221
+ return `${name} está entrando...`;
222
+ case EquosLocale.NL:
223
+ return `${name} doet mee...`;
224
+ case EquosLocale.RU:
225
+ return `${name} присоединяется...`;
226
+ case EquosLocale.ZH:
227
+ return `${name}正在加入...`;
228
+ case EquosLocale.JA:
229
+ return `${name}が参加しています...`;
230
+ case EquosLocale.KO:
231
+ return `${name}(이)가 참여 중입니다...`;
232
+ case EquosLocale.AR:
233
+ return `${name} ينضم...`;
234
+ case EquosLocale.HI:
235
+ return `${name} जुड़ रहा है...`;
236
+ case EquosLocale.EN:
237
+ default:
238
+ return `${name} is joining...`;
239
+ }
240
+ }
241
+ static endingConversationCopy(locale, countdown) {
242
+ switch (locale) {
243
+ case EquosLocale.FR:
244
+ return `Fin automatique dans ${countdown}s...`;
245
+ case EquosLocale.ES:
246
+ return `Finalización automática en ${countdown}s...`;
247
+ case EquosLocale.DE:
248
+ return `Automatisches Beenden in ${countdown}s...`;
249
+ case EquosLocale.IT:
250
+ return `Chiusura automatica tra ${countdown}s...`;
251
+ case EquosLocale.PT:
252
+ return `Encerramento automático em ${countdown}s...`;
253
+ case EquosLocale.NL:
254
+ return `Automatisch afsluiten over ${countdown}s...`;
255
+ case EquosLocale.RU:
256
+ return `Автоматическое завершение через ${countdown}с...`;
257
+ case EquosLocale.ZH:
258
+ return `${countdown}秒后自动结束...`;
259
+ case EquosLocale.JA:
260
+ return `${countdown}秒で自動終了します...`;
261
+ case EquosLocale.KO:
262
+ return `${countdown}초 후 자동 종료...`;
263
+ case EquosLocale.AR:
264
+ return `إنهاء تلقائي في ${countdown} ثوان...`;
265
+ case EquosLocale.HI:
266
+ return `${countdown} सेकंड में स्वचालित समाप्ति...`;
267
+ case EquosLocale.EN:
268
+ default:
269
+ return `Auto ending in ${countdown}s...`;
270
+ }
271
+ }
272
+ }
273
+ exports.CopyUtils = CopyUtils;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@equos/react",
3
- "version": "3.0.2-rc.4",
3
+ "version": "3.0.2-rc.6",
4
4
  "description": "",
5
5
  "license": "ISC",
6
6
  "author": "",
@@ -1,4 +0,0 @@
1
- export declare function EquosCharacterVideo({ identity, className, }: {
2
- identity: string;
3
- className?: string;
4
- }): import("react/jsx-runtime").JSX.Element;
@@ -1,27 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.EquosCharacterVideo = EquosCharacterVideo;
4
- const jsx_runtime_1 = require("react/jsx-runtime");
5
- const components_react_1 = require("@livekit/components-react");
6
- const cn_1 = require("../utils/cn");
7
- const react_1 = require("react");
8
- const livekit_client_1 = require("livekit-client");
9
- function EquosCharacterVideo({ identity, className, }) {
10
- const participants = (0, components_react_1.useParticipants)();
11
- const trackRef = (0, react_1.useMemo)(() => {
12
- const participant = participants.find((p) => p.identity === identity);
13
- if (!participant || !participant.trackPublications) {
14
- return null;
15
- }
16
- const publication = Array.from(participant.trackPublications.values()).find((pub) => pub.source === livekit_client_1.Track.Source.Camera);
17
- if (!publication) {
18
- return null;
19
- }
20
- return {
21
- participant,
22
- publication,
23
- source: livekit_client_1.Track.Source.Camera,
24
- };
25
- }, [identity, participants]);
26
- return ((0, jsx_runtime_1.jsx)("div", { className: (0, cn_1.cn)('relative w-full h-full', className), children: trackRef && (0, jsx_runtime_1.jsx)(components_react_1.VideoTrack, { trackRef: trackRef, className: "w-full h-full" }) }));
27
- }