@meshagent/meshagent-tailwind 0.39.9 → 0.40.1

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.
Files changed (111) hide show
  1. package/CHANGELOG.md +8 -0
  2. package/dist/cjs/{ChatBotView.js → chat/chat-bot-view.js} +37 -22
  3. package/dist/cjs/{chat-hooks.d.ts → chat/chat-hooks.d.ts} +5 -1
  4. package/dist/cjs/{chat-hooks.js → chat/chat-hooks.js} +12 -2
  5. package/dist/cjs/{ChatInput.js → chat/chat-input.js} +9 -9
  6. package/dist/cjs/chat/chat-thread.d.ts +12 -0
  7. package/dist/cjs/{ChatThread.js → chat/chat-thread.js} +75 -28
  8. package/dist/cjs/{ChatTypingIndicator.js → chat/chat-typing-indicator.js} +4 -4
  9. package/dist/cjs/chat/dataset-chat-thread.d.ts +13 -0
  10. package/dist/cjs/chat/dataset-chat-thread.js +1840 -0
  11. package/dist/cjs/{FileUploader.js → chat/file-uploader.js} +4 -4
  12. package/dist/cjs/{multi-thread-view.js → chat/multi-thread-view.js} +8 -3
  13. package/dist/cjs/chat/new-chat-thread.d.ts +17 -0
  14. package/dist/cjs/{Chat.js → chat/new-chat-thread.js} +43 -168
  15. package/dist/cjs/{UploadPill.js → chat/upload-pill.js} +5 -5
  16. package/dist/cjs/file-preview/file-preview.d.ts +34 -0
  17. package/dist/cjs/file-preview/file-preview.js +329 -0
  18. package/dist/cjs/forms/email-address.d.ts +10 -0
  19. package/dist/cjs/forms/email-address.js +105 -0
  20. package/dist/cjs/forms/form.d.ts +27 -0
  21. package/dist/cjs/forms/form.js +200 -0
  22. package/dist/cjs/forms/multi-select-autocomplete.d.ts +35 -0
  23. package/dist/cjs/forms/multi-select-autocomplete.js +294 -0
  24. package/dist/cjs/forms/select-users-dialog.d.ts +20 -0
  25. package/dist/cjs/forms/select-users-dialog.js +145 -0
  26. package/dist/cjs/forms/select-users.d.ts +16 -0
  27. package/dist/cjs/forms/select-users.js +117 -0
  28. package/dist/cjs/index.d.ts +19 -11
  29. package/dist/cjs/index.js +19 -11
  30. package/dist/cjs/meetings/audio-visualization.d.ts +7 -0
  31. package/dist/cjs/meetings/audio-visualization.js +74 -0
  32. package/dist/cjs/meetings/controls.d.ts +19 -0
  33. package/dist/cjs/meetings/controls.js +300 -0
  34. package/dist/cjs/meetings/meeting-scope.d.ts +83 -0
  35. package/dist/cjs/meetings/meeting-scope.js +309 -0
  36. package/dist/cjs/meetings/meetings.d.ts +5 -0
  37. package/dist/cjs/meetings/meetings.js +22 -0
  38. package/dist/cjs/meetings/participants.d.ts +13 -0
  39. package/dist/cjs/meetings/participants.js +154 -0
  40. package/dist/cjs/meetings/wake-lock.d.ts +4 -0
  41. package/dist/cjs/meetings/wake-lock.js +55 -0
  42. package/dist/esm/{ChatBotView.js → chat/chat-bot-view.js} +34 -19
  43. package/dist/esm/{chat-hooks.d.ts → chat/chat-hooks.d.ts} +5 -1
  44. package/dist/esm/{chat-hooks.js → chat/chat-hooks.js} +12 -2
  45. package/dist/esm/{ChatInput.js → chat/chat-input.js} +4 -4
  46. package/dist/esm/chat/chat-thread.d.ts +12 -0
  47. package/dist/esm/{ChatThread.js → chat/chat-thread.js} +70 -23
  48. package/dist/esm/{ChatTypingIndicator.js → chat/chat-typing-indicator.js} +1 -1
  49. package/dist/esm/chat/dataset-chat-thread.d.ts +13 -0
  50. package/dist/esm/chat/dataset-chat-thread.js +1815 -0
  51. package/dist/esm/{FileUploader.js → chat/file-uploader.js} +1 -1
  52. package/dist/esm/{multi-thread-view.js → chat/multi-thread-view.js} +8 -3
  53. package/dist/esm/chat/new-chat-thread.d.ts +17 -0
  54. package/dist/esm/{Chat.js → chat/new-chat-thread.js} +40 -165
  55. package/dist/esm/{UploadPill.js → chat/upload-pill.js} +2 -2
  56. package/dist/esm/file-preview/file-preview.d.ts +34 -0
  57. package/dist/esm/file-preview/file-preview.js +316 -0
  58. package/dist/esm/forms/email-address.d.ts +10 -0
  59. package/dist/esm/forms/email-address.js +85 -0
  60. package/dist/esm/forms/form.d.ts +27 -0
  61. package/dist/esm/forms/form.js +193 -0
  62. package/dist/esm/forms/multi-select-autocomplete.d.ts +35 -0
  63. package/dist/esm/forms/multi-select-autocomplete.js +274 -0
  64. package/dist/esm/forms/select-users-dialog.d.ts +20 -0
  65. package/dist/esm/forms/select-users-dialog.js +132 -0
  66. package/dist/esm/forms/select-users.d.ts +16 -0
  67. package/dist/esm/forms/select-users.js +97 -0
  68. package/dist/esm/index.d.ts +19 -11
  69. package/dist/esm/index.js +19 -11
  70. package/dist/esm/meetings/audio-visualization.d.ts +7 -0
  71. package/dist/esm/meetings/audio-visualization.js +54 -0
  72. package/dist/esm/meetings/controls.d.ts +19 -0
  73. package/dist/esm/meetings/controls.js +294 -0
  74. package/dist/esm/meetings/meeting-scope.d.ts +83 -0
  75. package/dist/esm/meetings/meeting-scope.js +294 -0
  76. package/dist/esm/meetings/meetings.d.ts +5 -0
  77. package/dist/esm/meetings/meetings.js +5 -0
  78. package/dist/esm/meetings/participants.d.ts +13 -0
  79. package/dist/esm/meetings/participants.js +137 -0
  80. package/dist/esm/meetings/wake-lock.d.ts +4 -0
  81. package/dist/esm/meetings/wake-lock.js +35 -0
  82. package/dist/index.css +2 -2
  83. package/package.json +7 -4
  84. package/dist/cjs/Chat.d.ts +0 -15
  85. package/dist/cjs/ChatThread.d.ts +0 -21
  86. package/dist/esm/Chat.d.ts +0 -15
  87. package/dist/esm/ChatThread.d.ts +0 -21
  88. /package/dist/cjs/{ChatBotView.d.ts → chat/chat-bot-view.d.ts} +0 -0
  89. /package/dist/cjs/{ChatInput.d.ts → chat/chat-input.d.ts} +0 -0
  90. /package/dist/cjs/{chat-message.d.ts → chat/chat-message.d.ts} +0 -0
  91. /package/dist/cjs/{chat-message.js → chat/chat-message.js} +0 -0
  92. /package/dist/cjs/{ChatTypingIndicator.d.ts → chat/chat-typing-indicator.d.ts} +0 -0
  93. /package/dist/cjs/{conversation-descriptor.d.ts → chat/conversation-descriptor.d.ts} +0 -0
  94. /package/dist/cjs/{conversation-descriptor.js → chat/conversation-descriptor.js} +0 -0
  95. /package/dist/cjs/{file-attachment.d.ts → chat/file-attachment.d.ts} +0 -0
  96. /package/dist/cjs/{file-attachment.js → chat/file-attachment.js} +0 -0
  97. /package/dist/cjs/{FileUploader.d.ts → chat/file-uploader.d.ts} +0 -0
  98. /package/dist/cjs/{multi-thread-view.d.ts → chat/multi-thread-view.d.ts} +0 -0
  99. /package/dist/cjs/{UploadPill.d.ts → chat/upload-pill.d.ts} +0 -0
  100. /package/dist/esm/{ChatBotView.d.ts → chat/chat-bot-view.d.ts} +0 -0
  101. /package/dist/esm/{ChatInput.d.ts → chat/chat-input.d.ts} +0 -0
  102. /package/dist/esm/{chat-message.d.ts → chat/chat-message.d.ts} +0 -0
  103. /package/dist/esm/{chat-message.js → chat/chat-message.js} +0 -0
  104. /package/dist/esm/{ChatTypingIndicator.d.ts → chat/chat-typing-indicator.d.ts} +0 -0
  105. /package/dist/esm/{conversation-descriptor.d.ts → chat/conversation-descriptor.d.ts} +0 -0
  106. /package/dist/esm/{conversation-descriptor.js → chat/conversation-descriptor.js} +0 -0
  107. /package/dist/esm/{file-attachment.d.ts → chat/file-attachment.d.ts} +0 -0
  108. /package/dist/esm/{file-attachment.js → chat/file-attachment.js} +0 -0
  109. /package/dist/esm/{FileUploader.d.ts → chat/file-uploader.d.ts} +0 -0
  110. /package/dist/esm/{multi-thread-view.d.ts → chat/multi-thread-view.d.ts} +0 -0
  111. /package/dist/esm/{UploadPill.d.ts → chat/upload-pill.d.ts} +0 -0
@@ -0,0 +1,309 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+ var meeting_scope_exports = {};
20
+ __export(meeting_scope_exports, {
21
+ MeetingController: () => MeetingController,
22
+ MeetingScope: () => MeetingScope,
23
+ PendingLocalMediaState: () => PendingLocalMediaState,
24
+ firstEnabledVideoPublication: () => firstEnabledVideoPublication,
25
+ useMeetingController: () => useMeetingController
26
+ });
27
+ module.exports = __toCommonJS(meeting_scope_exports);
28
+ var import_jsx_runtime = require("react/jsx-runtime");
29
+ var import_react = require("react");
30
+ var import_livekit_client = require("livekit-client");
31
+ var import_wake_lock = require("./wake-lock");
32
+ class PendingLocalMediaState {
33
+ listeners = /* @__PURE__ */ new Set();
34
+ cameraAwaitingEnableConfirmation = false;
35
+ microphoneAwaitingEnableConfirmation = false;
36
+ _cameraPending = false;
37
+ _microphonePending = false;
38
+ _cameraUnavailable = false;
39
+ _microphoneUnavailable = false;
40
+ get cameraPending() {
41
+ return this._cameraPending;
42
+ }
43
+ get microphonePending() {
44
+ return this._microphonePending;
45
+ }
46
+ get cameraUnavailable() {
47
+ return this._cameraUnavailable;
48
+ }
49
+ get microphoneUnavailable() {
50
+ return this._microphoneUnavailable;
51
+ }
52
+ subscribe(listener) {
53
+ this.listeners.add(listener);
54
+ return () => this.listeners.delete(listener);
55
+ }
56
+ setCameraPending(value, { awaitEnableConfirmation = false } = {}) {
57
+ if (this._cameraPending === value && this.cameraAwaitingEnableConfirmation === awaitEnableConfirmation) {
58
+ return;
59
+ }
60
+ this._cameraPending = value;
61
+ this.cameraAwaitingEnableConfirmation = value && awaitEnableConfirmation;
62
+ this.notify();
63
+ }
64
+ setMicrophonePending(value, { awaitEnableConfirmation = false } = {}) {
65
+ if (this._microphonePending === value && this.microphoneAwaitingEnableConfirmation === awaitEnableConfirmation) {
66
+ return;
67
+ }
68
+ this._microphonePending = value;
69
+ this.microphoneAwaitingEnableConfirmation = value && awaitEnableConfirmation;
70
+ this.notify();
71
+ }
72
+ setCameraUnavailable(value) {
73
+ if (this._cameraUnavailable === value) {
74
+ return;
75
+ }
76
+ this._cameraUnavailable = value;
77
+ this.notify();
78
+ }
79
+ setMicrophoneUnavailable(value) {
80
+ if (this._microphoneUnavailable === value) {
81
+ return;
82
+ }
83
+ this._microphoneUnavailable = value;
84
+ this.notify();
85
+ }
86
+ setPending({
87
+ cameraPending,
88
+ microphonePending,
89
+ cameraAwaitEnableConfirmation = false,
90
+ microphoneAwaitEnableConfirmation = false
91
+ }) {
92
+ const nextCameraAwaiting = cameraPending && cameraAwaitEnableConfirmation;
93
+ const nextMicrophoneAwaiting = microphonePending && microphoneAwaitEnableConfirmation;
94
+ if (this._cameraPending === cameraPending && this._microphonePending === microphonePending && this.cameraAwaitingEnableConfirmation === nextCameraAwaiting && this.microphoneAwaitingEnableConfirmation === nextMicrophoneAwaiting) {
95
+ return;
96
+ }
97
+ this._cameraPending = cameraPending;
98
+ this._microphonePending = microphonePending;
99
+ this.cameraAwaitingEnableConfirmation = nextCameraAwaiting;
100
+ this.microphoneAwaitingEnableConfirmation = nextMicrophoneAwaiting;
101
+ this.notify();
102
+ }
103
+ syncFromLocalParticipant(participant, disconnected) {
104
+ if (disconnected) {
105
+ this.clear();
106
+ return;
107
+ }
108
+ if (this.cameraAwaitingEnableConfirmation && participant?.isCameraEnabled) {
109
+ this.setCameraPending(false);
110
+ }
111
+ if (participant?.isCameraEnabled) {
112
+ this.setCameraUnavailable(false);
113
+ }
114
+ if (this.microphoneAwaitingEnableConfirmation && participant?.isMicrophoneEnabled) {
115
+ this.setMicrophonePending(false);
116
+ }
117
+ if (participant?.isMicrophoneEnabled) {
118
+ this.setMicrophoneUnavailable(false);
119
+ }
120
+ }
121
+ clear() {
122
+ if (!this._cameraPending && !this._microphonePending && !this.cameraAwaitingEnableConfirmation && !this.microphoneAwaitingEnableConfirmation && !this._cameraUnavailable && !this._microphoneUnavailable) {
123
+ return;
124
+ }
125
+ this._cameraPending = false;
126
+ this._microphonePending = false;
127
+ this.cameraAwaitingEnableConfirmation = false;
128
+ this.microphoneAwaitingEnableConfirmation = false;
129
+ this._cameraUnavailable = false;
130
+ this._microphoneUnavailable = false;
131
+ this.notify();
132
+ }
133
+ dispose() {
134
+ this.listeners.clear();
135
+ }
136
+ notify() {
137
+ for (const listener of this.listeners) {
138
+ listener();
139
+ }
140
+ }
141
+ }
142
+ class MeetingController {
143
+ room;
144
+ livekitRoom;
145
+ pendingLocalMedia = new PendingLocalMediaState();
146
+ listeners = /* @__PURE__ */ new Set();
147
+ _config = null;
148
+ _configurationError = null;
149
+ constructor({ room, roomOptions }) {
150
+ this.room = room;
151
+ this.livekitRoom = new import_livekit_client.Room(roomOptions);
152
+ const roomEvents = [
153
+ import_livekit_client.RoomEvent.ConnectionStateChanged,
154
+ import_livekit_client.RoomEvent.Connected,
155
+ import_livekit_client.RoomEvent.Disconnected,
156
+ import_livekit_client.RoomEvent.ParticipantConnected,
157
+ import_livekit_client.RoomEvent.ParticipantDisconnected,
158
+ import_livekit_client.RoomEvent.TrackPublished,
159
+ import_livekit_client.RoomEvent.TrackSubscribed,
160
+ import_livekit_client.RoomEvent.TrackUnpublished,
161
+ import_livekit_client.RoomEvent.TrackUnsubscribed,
162
+ import_livekit_client.RoomEvent.TrackMuted,
163
+ import_livekit_client.RoomEvent.TrackUnmuted,
164
+ import_livekit_client.RoomEvent.LocalTrackPublished,
165
+ import_livekit_client.RoomEvent.LocalTrackUnpublished,
166
+ import_livekit_client.RoomEvent.ActiveSpeakersChanged,
167
+ import_livekit_client.RoomEvent.ParticipantAttributesChanged,
168
+ import_livekit_client.RoomEvent.ParticipantNameChanged,
169
+ import_livekit_client.RoomEvent.MediaDevicesChanged
170
+ ];
171
+ for (const eventName of roomEvents) {
172
+ this.livekitRoom.on(eventName, this.onRoomChanged);
173
+ }
174
+ }
175
+ get config() {
176
+ return this._config;
177
+ }
178
+ get configurationError() {
179
+ return this._configurationError;
180
+ }
181
+ get isConnected() {
182
+ return this.livekitRoom.state !== import_livekit_client.ConnectionState.Disconnected;
183
+ }
184
+ get hasParticipantsWithVideo() {
185
+ const localHasVideo = Array.from(this.livekitRoom.localParticipant.videoTrackPublications.values()).some((publication) => !publication.isMuted);
186
+ const remoteHasVideo = Array.from(this.livekitRoom.remoteParticipants.values()).some((participant) => Array.from(participant.videoTrackPublications.values()).some((publication) => !publication.isMuted));
187
+ return localHasVideo || remoteHasVideo;
188
+ }
189
+ subscribe(listener) {
190
+ this.listeners.add(listener);
191
+ return () => this.listeners.delete(listener);
192
+ }
193
+ async configure({ breakoutRoom } = {}) {
194
+ if (this.livekitRoom.state !== import_livekit_client.ConnectionState.Disconnected) {
195
+ throw new Error("You cannot reconfigure while the controller is connected");
196
+ }
197
+ this._config = null;
198
+ this._configurationError = null;
199
+ this.notify();
200
+ try {
201
+ this._config = await this.room.livekit.getConnectionInfo({ breakoutRoom });
202
+ this.notify();
203
+ } catch (error) {
204
+ this._configurationError = error;
205
+ this.notify();
206
+ throw error;
207
+ }
208
+ }
209
+ async connect(options) {
210
+ const config = this._config;
211
+ if (config == null) {
212
+ throw new Error("The controller has not been configured");
213
+ }
214
+ const cameraEnabled = options?.camera?.enabled === true;
215
+ const microphoneEnabled = options?.microphone?.enabled === true;
216
+ this.pendingLocalMedia.setCameraUnavailable(false);
217
+ this.pendingLocalMedia.setMicrophoneUnavailable(false);
218
+ this.pendingLocalMedia.setPending({
219
+ cameraPending: cameraEnabled,
220
+ microphonePending: microphoneEnabled,
221
+ cameraAwaitEnableConfirmation: cameraEnabled,
222
+ microphoneAwaitEnableConfirmation: microphoneEnabled
223
+ });
224
+ const { camera: _camera, microphone: _microphone, ...connectOptions } = options ?? {};
225
+ try {
226
+ await this.livekitRoom.connect(config.url, config.token, connectOptions);
227
+ const localParticipant = this.livekitRoom.localParticipant;
228
+ await Promise.all([
229
+ cameraEnabled ? localParticipant.setCameraEnabled(true).then(() => this.pendingLocalMedia.setCameraUnavailable(false)).catch((error) => {
230
+ this.pendingLocalMedia.setCameraPending(false);
231
+ this.pendingLocalMedia.setCameraUnavailable(true);
232
+ console.warn("unable to enable camera after connecting", error);
233
+ }) : Promise.resolve(this.pendingLocalMedia.setCameraPending(false)),
234
+ microphoneEnabled ? localParticipant.setMicrophoneEnabled(true).then(() => this.pendingLocalMedia.setMicrophoneUnavailable(false)).catch((error) => {
235
+ this.pendingLocalMedia.setMicrophonePending(false);
236
+ this.pendingLocalMedia.setMicrophoneUnavailable(true);
237
+ console.warn("unable to enable microphone after connecting", error);
238
+ }) : Promise.resolve(this.pendingLocalMedia.setMicrophonePending(false))
239
+ ]);
240
+ this.syncPendingLocalMediaState();
241
+ } catch (error) {
242
+ this.pendingLocalMedia.clear();
243
+ throw error;
244
+ }
245
+ }
246
+ async disconnect() {
247
+ this.pendingLocalMedia.clear();
248
+ await this.livekitRoom.disconnect();
249
+ }
250
+ dispose() {
251
+ this.livekitRoom.removeAllListeners();
252
+ this.pendingLocalMedia.dispose();
253
+ this.listeners.clear();
254
+ }
255
+ onRoomChanged = () => {
256
+ this.syncPendingLocalMediaState();
257
+ this.notify();
258
+ };
259
+ syncPendingLocalMediaState() {
260
+ this.pendingLocalMedia.syncFromLocalParticipant(
261
+ this.livekitRoom.localParticipant,
262
+ this.livekitRoom.state === import_livekit_client.ConnectionState.Disconnected
263
+ );
264
+ }
265
+ notify() {
266
+ for (const listener of this.listeners) {
267
+ listener();
268
+ }
269
+ }
270
+ }
271
+ const MeetingControllerContext = (0, import_react.createContext)(null);
272
+ function useMeetingController(controller) {
273
+ const contextController = (0, import_react.useContext)(MeetingControllerContext);
274
+ const resolved = controller ?? contextController;
275
+ if (resolved == null) {
276
+ throw new Error("useMeetingController must be used within MeetingScope or receive a controller");
277
+ }
278
+ (0, import_react.useSyncExternalStore)(
279
+ (listener) => resolved.subscribe(listener),
280
+ () => resolved.livekitRoom.state,
281
+ () => resolved.livekitRoom.state
282
+ );
283
+ return resolved;
284
+ }
285
+ function MeetingScope({
286
+ client,
287
+ breakoutRoom,
288
+ roomOptions,
289
+ children
290
+ }) {
291
+ const controller = (0, import_react.useMemo)(() => new MeetingController({ room: client, roomOptions }), [client, roomOptions]);
292
+ (0, import_react.useEffect)(() => {
293
+ void controller.configure({ breakoutRoom });
294
+ return () => {
295
+ if (controller.isConnected) {
296
+ void controller.disconnect().catch((error) => {
297
+ console.warn("unable to disconnect", error);
298
+ });
299
+ }
300
+ controller.dispose();
301
+ };
302
+ }, [breakoutRoom, controller]);
303
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_wake_lock.WakeLocker, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(MeetingControllerContext.Provider, { value: controller, children: typeof children === "function" ? children(controller) : children }) });
304
+ }
305
+ function firstEnabledVideoPublication(participant) {
306
+ return Array.from(participant.videoTrackPublications.values()).find(
307
+ (publication) => !publication.isMuted && publication.source === import_livekit_client.Track.Source.Camera && publication.videoTrack != null
308
+ );
309
+ }
@@ -0,0 +1,5 @@
1
+ export * from "./audio-visualization";
2
+ export * from "./controls";
3
+ export * from "./meeting-scope";
4
+ export * from "./participants";
5
+ export * from "./wake-lock";
@@ -0,0 +1,22 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __copyProps = (to, from, except, desc) => {
7
+ if (from && typeof from === "object" || typeof from === "function") {
8
+ for (let key of __getOwnPropNames(from))
9
+ if (!__hasOwnProp.call(to, key) && key !== except)
10
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
11
+ }
12
+ return to;
13
+ };
14
+ var __reExport = (target, mod, secondTarget) => (__copyProps(target, mod, "default"), secondTarget && __copyProps(secondTarget, mod, "default"));
15
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
16
+ var meetings_exports = {};
17
+ module.exports = __toCommonJS(meetings_exports);
18
+ __reExport(meetings_exports, require("./audio-visualization"), module.exports);
19
+ __reExport(meetings_exports, require("./controls"), module.exports);
20
+ __reExport(meetings_exports, require("./meeting-scope"), module.exports);
21
+ __reExport(meetings_exports, require("./participants"), module.exports);
22
+ __reExport(meetings_exports, require("./wake-lock"), module.exports);
@@ -0,0 +1,13 @@
1
+ import type { ReactElement } from "react";
2
+ import { Participant, Room } from "livekit-client";
3
+ import { MeetingController } from "./meeting-scope";
4
+ export declare function ParticipantCamerasList({ controller: providedController, spacing, className, }: {
5
+ controller?: MeetingController;
6
+ spacing?: number;
7
+ className?: string;
8
+ }): ReactElement;
9
+ export declare function ParticipantTile({ room, participant, className, }: {
10
+ room: Room;
11
+ participant: Participant;
12
+ className?: string;
13
+ }): ReactElement;
@@ -0,0 +1,154 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+ var participants_exports = {};
20
+ __export(participants_exports, {
21
+ ParticipantCamerasList: () => ParticipantCamerasList,
22
+ ParticipantTile: () => ParticipantTile
23
+ });
24
+ module.exports = __toCommonJS(participants_exports);
25
+ var import_jsx_runtime = require("react/jsx-runtime");
26
+ var import_react = require("react");
27
+ var import_livekit_client = require("livekit-client");
28
+ var import_lucide_react = require("lucide-react");
29
+ var import_utils = require("../lib/utils");
30
+ var import_audio_visualization = require("./audio-visualization");
31
+ var import_meeting_scope = require("./meeting-scope");
32
+ function useParticipantSnapshot(participant) {
33
+ (0, import_react.useSyncExternalStore)(
34
+ (listener) => {
35
+ const events = [
36
+ "trackPublished",
37
+ "trackSubscribed",
38
+ "trackUnpublished",
39
+ "trackUnsubscribed",
40
+ "trackMuted",
41
+ "trackUnmuted",
42
+ "localTrackPublished",
43
+ "localTrackUnpublished",
44
+ "participantNameChanged",
45
+ "isSpeakingChanged",
46
+ "attributesChanged"
47
+ ];
48
+ for (const eventName of events) {
49
+ participant.on(eventName, listener);
50
+ }
51
+ return () => {
52
+ for (const eventName of events) {
53
+ participant.off(eventName, listener);
54
+ }
55
+ };
56
+ },
57
+ () => `${participant.isMicrophoneEnabled}:${participant.isCameraEnabled}:${participant.name ?? ""}:${participant.isSpeaking}`,
58
+ () => ""
59
+ );
60
+ }
61
+ function useRoomSnapshot(room) {
62
+ (0, import_react.useSyncExternalStore)(
63
+ (listener) => {
64
+ const events = [
65
+ "participantConnected",
66
+ "participantDisconnected",
67
+ "trackPublished",
68
+ "trackSubscribed",
69
+ "trackUnpublished",
70
+ "trackUnsubscribed",
71
+ "trackMuted",
72
+ "trackUnmuted",
73
+ "localTrackPublished",
74
+ "localTrackUnpublished",
75
+ "activeSpeakersChanged"
76
+ ];
77
+ for (const eventName of events) {
78
+ room.on(eventName, listener);
79
+ }
80
+ return () => {
81
+ for (const eventName of events) {
82
+ room.off(eventName, listener);
83
+ }
84
+ };
85
+ },
86
+ () => `${room.remoteParticipants.size}:${room.localParticipant.sid}:${room.activeSpeakers.length}`,
87
+ () => ""
88
+ );
89
+ }
90
+ function ParticipantCamerasList({
91
+ controller: providedController,
92
+ spacing = 10,
93
+ className
94
+ }) {
95
+ const controller = (0, import_meeting_scope.useMeetingController)(providedController);
96
+ const room = controller.livekitRoom;
97
+ useRoomSnapshot(room);
98
+ const participants = [
99
+ room.localParticipant,
100
+ ...Array.from(room.remoteParticipants.values())
101
+ ];
102
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
103
+ "div",
104
+ {
105
+ className: (0, import_utils.cn)("flex h-full overflow-x-auto", className),
106
+ style: { gap: spacing },
107
+ children: participants.map((participant) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
108
+ ParticipantTile,
109
+ {
110
+ room,
111
+ participant,
112
+ className: "h-full min-h-40 min-w-64"
113
+ },
114
+ participant.sid || participant.identity
115
+ ))
116
+ }
117
+ );
118
+ }
119
+ function TrackVideo({ publication }) {
120
+ const ref = (0, import_react.useRef)(null);
121
+ const track = publication.videoTrack;
122
+ (0, import_react.useEffect)(() => {
123
+ const element = ref.current;
124
+ if (element == null || track == null) {
125
+ return void 0;
126
+ }
127
+ track.attach(element);
128
+ return () => {
129
+ track.detach(element);
130
+ };
131
+ }, [track]);
132
+ if (track == null) {
133
+ return null;
134
+ }
135
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("video", { ref, autoPlay: true, playsInline: true, muted: publication.source === import_livekit_client.Track.Source.Camera && publication.isLocal, className: "h-full w-full object-cover" });
136
+ }
137
+ function ParticipantTile({
138
+ room,
139
+ participant,
140
+ className
141
+ }) {
142
+ useParticipantSnapshot(participant);
143
+ const publication = (0, import_meeting_scope.firstEnabledVideoPublication)(participant);
144
+ const muted = !participant.isMicrophoneEnabled;
145
+ const displayName = participant.name?.trim() || participant.identity || "Participant";
146
+ const isAgent = participant.kind === import_livekit_client.ParticipantKind.AGENT;
147
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: (0, import_utils.cn)("aspect-[4/3] overflow-hidden rounded-md border bg-muted", className), children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "relative h-full w-full", children: [
148
+ publication != null ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(TrackVideo, { publication }) : isAgent ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_audio_visualization.AudioWave, { room, participant }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "flex h-full w-full items-center justify-center bg-foreground text-background", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "text-4xl font-semibold", children: displayName.slice(0, 1).toUpperCase() }) }),
149
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "absolute bottom-2 left-2 flex max-w-[calc(100%-1rem)] items-center gap-1 rounded-md border border-white/15 bg-black/60 px-3 py-2 text-xs font-medium text-white", children: [
150
+ muted ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_lucide_react.MicOff, { className: "h-4 w-4 text-red-400" }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_lucide_react.Mic, { className: "h-4 w-4" }),
151
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "truncate", children: displayName })
152
+ ] })
153
+ ] }) });
154
+ }
@@ -0,0 +1,4 @@
1
+ import type { ReactElement, ReactNode } from "react";
2
+ export declare function WakeLocker({ children }: {
3
+ children: ReactNode;
4
+ }): ReactElement;
@@ -0,0 +1,55 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+ var wake_lock_exports = {};
20
+ __export(wake_lock_exports, {
21
+ WakeLocker: () => WakeLocker
22
+ });
23
+ module.exports = __toCommonJS(wake_lock_exports);
24
+ var import_jsx_runtime = require("react/jsx-runtime");
25
+ var import_react = require("react");
26
+ let wakeLockRefCount = 0;
27
+ let wakeLockSentinel = null;
28
+ async function enableWakeLock() {
29
+ if (!("wakeLock" in navigator)) {
30
+ return;
31
+ }
32
+ wakeLockSentinel = await navigator.wakeLock.request("screen");
33
+ }
34
+ async function disableWakeLock() {
35
+ const sentinel = wakeLockSentinel;
36
+ wakeLockSentinel = null;
37
+ await sentinel?.release();
38
+ }
39
+ function WakeLocker({ children }) {
40
+ (0, import_react.useEffect)(() => {
41
+ wakeLockRefCount += 1;
42
+ if (wakeLockRefCount === 1) {
43
+ void enableWakeLock().catch(() => {
44
+ });
45
+ }
46
+ return () => {
47
+ wakeLockRefCount = Math.max(wakeLockRefCount - 1, 0);
48
+ if (wakeLockRefCount === 0) {
49
+ void disableWakeLock().catch(() => {
50
+ });
51
+ }
52
+ };
53
+ }, []);
54
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_jsx_runtime.Fragment, { children });
55
+ }
@@ -9,8 +9,9 @@ import {
9
9
  Pencil
10
10
  } from "lucide-react";
11
11
  import { useThreadStatus } from "./chat-hooks";
12
- import { Chat } from "./Chat";
13
- import { Button } from "./components/ui/button";
12
+ import { ChatThread } from "./chat-thread";
13
+ import { DatasetChatThread } from "./dataset-chat-thread";
14
+ import { Button } from "../components/ui/button";
14
15
  import {
15
16
  Dialog,
16
17
  DialogClose,
@@ -19,17 +20,17 @@ import {
19
20
  DialogFooter,
20
21
  DialogHeader,
21
22
  DialogTitle
22
- } from "./components/ui/dialog";
23
- import { Input } from "./components/ui/input";
24
- import { Label } from "./components/ui/label";
25
- import { Spinner } from "./components/ui/spinner";
23
+ } from "../components/ui/dialog";
24
+ import { Input } from "../components/ui/input";
25
+ import { Label } from "../components/ui/label";
26
+ import { Spinner } from "../components/ui/spinner";
26
27
  import {
27
28
  ChatThreadDisplayMode,
28
29
  chatDocumentPath,
29
30
  defaultThreadDisplayNameFromPath,
30
31
  resolvedThreadListPath
31
32
  } from "./conversation-descriptor";
32
- import { cn } from "./lib/utils";
33
+ import { cn } from "../lib/utils";
33
34
  import { MultiThreadView } from "./multi-thread-view";
34
35
  const multiThreadLayoutBreakpointPx = 920;
35
36
  import {
@@ -41,6 +42,9 @@ function normalizePath(path) {
41
42
  const normalized = path?.trim();
42
43
  return normalized ? normalized : null;
43
44
  }
45
+ function isDatasetBackedThreadPath(path) {
46
+ return path.startsWith("dataset://") || path.startsWith("tmp://");
47
+ }
44
48
  function parseDate(value) {
45
49
  const parsed = new Date(value);
46
50
  return Number.isNaN(parsed.getTime()) ? /* @__PURE__ */ new Date(0) : parsed;
@@ -479,19 +483,24 @@ function ChatBotView({
479
483
  closeRenameThreadDialog();
480
484
  }, [activeSelectedThreadPath, closeRenameThreadDialog, emitResolvedThread, renameThreadDialog]);
481
485
  if (threadDisplayMode !== ChatThreadDisplayMode.MultiThreadComposer) {
482
- return /* @__PURE__ */ jsx(
483
- Chat,
486
+ return isDatasetBackedThreadPath(resolvedSingleThreadPath) ? /* @__PURE__ */ jsx(
487
+ DatasetChatThread,
488
+ {
489
+ room,
490
+ path: resolvedSingleThreadPath,
491
+ agentName,
492
+ emptyStateTitle,
493
+ emptyStateDescription
494
+ }
495
+ ) : /* @__PURE__ */ jsx(
496
+ ChatThread,
484
497
  {
485
498
  room,
486
499
  path: resolvedSingleThreadPath,
487
500
  participants,
488
501
  agentName,
489
- toolkit,
490
- tool,
491
- centerComposer,
492
502
  emptyStateTitle,
493
- emptyStateDescription,
494
- onThreadResolved
503
+ emptyStateDescription
495
504
  }
496
505
  );
497
506
  }
@@ -510,16 +519,22 @@ function ChatBotView({
510
519
  onSelectedThreadResolved: emitResolvedThread,
511
520
  newThreadResetVersion,
512
521
  centerComposer,
513
- builder: (threadPath) => /* @__PURE__ */ jsx(
514
- Chat,
522
+ builder: (threadPath) => isDatasetBackedThreadPath(threadPath) ? /* @__PURE__ */ jsx(
523
+ DatasetChatThread,
524
+ {
525
+ room,
526
+ path: threadPath,
527
+ agentName,
528
+ emptyStateTitle: startNewThreadTitle,
529
+ emptyStateDescription: startNewThreadDescription
530
+ }
531
+ ) : /* @__PURE__ */ jsx(
532
+ ChatThread,
515
533
  {
516
534
  room,
517
535
  path: threadPath,
518
536
  participants,
519
537
  agentName,
520
- toolkit,
521
- tool,
522
- centerComposer,
523
538
  emptyStateTitle: startNewThreadTitle,
524
539
  emptyStateDescription: startNewThreadDescription
525
540
  }