@equos/react 3.0.2-rc.5 → 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", { 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
+ }, 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,9 +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 p-2", onClick: (e) => {
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
29
  e.stopPropagation();
30
- console.log('toggle', !expanded);
31
30
  setExpanded(!expanded);
32
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" })] }));
33
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
  }
@@ -362,6 +413,12 @@
362
413
  .bg-black {
363
414
  background-color: var(--color-black);
364
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
+ }
365
422
  .bg-white\/20 {
366
423
  background-color: color-mix(in srgb, #fff 20%, transparent);
367
424
  @supports (color: color-mix(in lab, red, red)) {
@@ -383,6 +440,12 @@
383
440
  .p-4 {
384
441
  padding: calc(var(--spacing) * 4);
385
442
  }
443
+ .px-2 {
444
+ padding-inline: calc(var(--spacing) * 2);
445
+ }
446
+ .py-1 {
447
+ padding-block: calc(var(--spacing) * 1);
448
+ }
386
449
  .text-2xl {
387
450
  font-size: var(--text-2xl);
388
451
  line-height: var(--tw-leading, var(--text-2xl--line-height));
@@ -408,10 +471,23 @@
408
471
  .text-white {
409
472
  color: var(--color-white);
410
473
  }
474
+ .opacity-0 {
475
+ opacity: 0%;
476
+ }
411
477
  .shadow-xl {
412
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));
413
479
  box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);
414
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
+ }
415
491
  .backdrop-blur-sm {
416
492
  --tw-backdrop-blur: blur(var(--blur-sm));
417
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,);
@@ -427,6 +503,10 @@
427
503
  transition-timing-function: var(--tw-ease, var(--default-transition-timing-function));
428
504
  transition-duration: var(--tw-duration, var(--default-transition-duration));
429
505
  }
506
+ .duration-300 {
507
+ --tw-duration: 300ms;
508
+ transition-duration: 300ms;
509
+ }
430
510
  .select-none {
431
511
  -webkit-user-select: none;
432
512
  user-select: none;
@@ -438,6 +518,16 @@
438
518
  }
439
519
  }
440
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
+ }
441
531
  .hover\:bg-white\/40 {
442
532
  &:hover {
443
533
  @media (hover: hover) {
@@ -618,6 +708,10 @@
618
708
  syntax: "*";
619
709
  inherits: false;
620
710
  }
711
+ @property --tw-duration {
712
+ syntax: "*";
713
+ inherits: false;
714
+ }
621
715
  @keyframes spin {
622
716
  to {
623
717
  transform: rotate(360deg);
@@ -654,6 +748,7 @@
654
748
  --tw-backdrop-opacity: initial;
655
749
  --tw-backdrop-saturate: initial;
656
750
  --tw-backdrop-sepia: initial;
751
+ --tw-duration: initial;
657
752
  }
658
753
  }
659
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.5",
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
- }