@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.
- package/CHANGELOG.md +8 -0
- package/dist/cjs/{ChatBotView.js → chat/chat-bot-view.js} +37 -22
- package/dist/cjs/{chat-hooks.d.ts → chat/chat-hooks.d.ts} +5 -1
- package/dist/cjs/{chat-hooks.js → chat/chat-hooks.js} +12 -2
- package/dist/cjs/{ChatInput.js → chat/chat-input.js} +9 -9
- package/dist/cjs/chat/chat-thread.d.ts +12 -0
- package/dist/cjs/{ChatThread.js → chat/chat-thread.js} +75 -28
- package/dist/cjs/{ChatTypingIndicator.js → chat/chat-typing-indicator.js} +4 -4
- package/dist/cjs/chat/dataset-chat-thread.d.ts +13 -0
- package/dist/cjs/chat/dataset-chat-thread.js +1840 -0
- package/dist/cjs/{FileUploader.js → chat/file-uploader.js} +4 -4
- package/dist/cjs/{multi-thread-view.js → chat/multi-thread-view.js} +8 -3
- package/dist/cjs/chat/new-chat-thread.d.ts +17 -0
- package/dist/cjs/{Chat.js → chat/new-chat-thread.js} +43 -168
- package/dist/cjs/{UploadPill.js → chat/upload-pill.js} +5 -5
- package/dist/cjs/file-preview/file-preview.d.ts +34 -0
- package/dist/cjs/file-preview/file-preview.js +329 -0
- package/dist/cjs/forms/email-address.d.ts +10 -0
- package/dist/cjs/forms/email-address.js +105 -0
- package/dist/cjs/forms/form.d.ts +27 -0
- package/dist/cjs/forms/form.js +200 -0
- package/dist/cjs/forms/multi-select-autocomplete.d.ts +35 -0
- package/dist/cjs/forms/multi-select-autocomplete.js +294 -0
- package/dist/cjs/forms/select-users-dialog.d.ts +20 -0
- package/dist/cjs/forms/select-users-dialog.js +145 -0
- package/dist/cjs/forms/select-users.d.ts +16 -0
- package/dist/cjs/forms/select-users.js +117 -0
- package/dist/cjs/index.d.ts +19 -11
- package/dist/cjs/index.js +19 -11
- package/dist/cjs/meetings/audio-visualization.d.ts +7 -0
- package/dist/cjs/meetings/audio-visualization.js +74 -0
- package/dist/cjs/meetings/controls.d.ts +19 -0
- package/dist/cjs/meetings/controls.js +300 -0
- package/dist/cjs/meetings/meeting-scope.d.ts +83 -0
- package/dist/cjs/meetings/meeting-scope.js +309 -0
- package/dist/cjs/meetings/meetings.d.ts +5 -0
- package/dist/cjs/meetings/meetings.js +22 -0
- package/dist/cjs/meetings/participants.d.ts +13 -0
- package/dist/cjs/meetings/participants.js +154 -0
- package/dist/cjs/meetings/wake-lock.d.ts +4 -0
- package/dist/cjs/meetings/wake-lock.js +55 -0
- package/dist/esm/{ChatBotView.js → chat/chat-bot-view.js} +34 -19
- package/dist/esm/{chat-hooks.d.ts → chat/chat-hooks.d.ts} +5 -1
- package/dist/esm/{chat-hooks.js → chat/chat-hooks.js} +12 -2
- package/dist/esm/{ChatInput.js → chat/chat-input.js} +4 -4
- package/dist/esm/chat/chat-thread.d.ts +12 -0
- package/dist/esm/{ChatThread.js → chat/chat-thread.js} +70 -23
- package/dist/esm/{ChatTypingIndicator.js → chat/chat-typing-indicator.js} +1 -1
- package/dist/esm/chat/dataset-chat-thread.d.ts +13 -0
- package/dist/esm/chat/dataset-chat-thread.js +1815 -0
- package/dist/esm/{FileUploader.js → chat/file-uploader.js} +1 -1
- package/dist/esm/{multi-thread-view.js → chat/multi-thread-view.js} +8 -3
- package/dist/esm/chat/new-chat-thread.d.ts +17 -0
- package/dist/esm/{Chat.js → chat/new-chat-thread.js} +40 -165
- package/dist/esm/{UploadPill.js → chat/upload-pill.js} +2 -2
- package/dist/esm/file-preview/file-preview.d.ts +34 -0
- package/dist/esm/file-preview/file-preview.js +316 -0
- package/dist/esm/forms/email-address.d.ts +10 -0
- package/dist/esm/forms/email-address.js +85 -0
- package/dist/esm/forms/form.d.ts +27 -0
- package/dist/esm/forms/form.js +193 -0
- package/dist/esm/forms/multi-select-autocomplete.d.ts +35 -0
- package/dist/esm/forms/multi-select-autocomplete.js +274 -0
- package/dist/esm/forms/select-users-dialog.d.ts +20 -0
- package/dist/esm/forms/select-users-dialog.js +132 -0
- package/dist/esm/forms/select-users.d.ts +16 -0
- package/dist/esm/forms/select-users.js +97 -0
- package/dist/esm/index.d.ts +19 -11
- package/dist/esm/index.js +19 -11
- package/dist/esm/meetings/audio-visualization.d.ts +7 -0
- package/dist/esm/meetings/audio-visualization.js +54 -0
- package/dist/esm/meetings/controls.d.ts +19 -0
- package/dist/esm/meetings/controls.js +294 -0
- package/dist/esm/meetings/meeting-scope.d.ts +83 -0
- package/dist/esm/meetings/meeting-scope.js +294 -0
- package/dist/esm/meetings/meetings.d.ts +5 -0
- package/dist/esm/meetings/meetings.js +5 -0
- package/dist/esm/meetings/participants.d.ts +13 -0
- package/dist/esm/meetings/participants.js +137 -0
- package/dist/esm/meetings/wake-lock.d.ts +4 -0
- package/dist/esm/meetings/wake-lock.js +35 -0
- package/dist/index.css +2 -2
- package/package.json +7 -4
- package/dist/cjs/Chat.d.ts +0 -15
- package/dist/cjs/ChatThread.d.ts +0 -21
- package/dist/esm/Chat.d.ts +0 -15
- package/dist/esm/ChatThread.d.ts +0 -21
- /package/dist/cjs/{ChatBotView.d.ts → chat/chat-bot-view.d.ts} +0 -0
- /package/dist/cjs/{ChatInput.d.ts → chat/chat-input.d.ts} +0 -0
- /package/dist/cjs/{chat-message.d.ts → chat/chat-message.d.ts} +0 -0
- /package/dist/cjs/{chat-message.js → chat/chat-message.js} +0 -0
- /package/dist/cjs/{ChatTypingIndicator.d.ts → chat/chat-typing-indicator.d.ts} +0 -0
- /package/dist/cjs/{conversation-descriptor.d.ts → chat/conversation-descriptor.d.ts} +0 -0
- /package/dist/cjs/{conversation-descriptor.js → chat/conversation-descriptor.js} +0 -0
- /package/dist/cjs/{file-attachment.d.ts → chat/file-attachment.d.ts} +0 -0
- /package/dist/cjs/{file-attachment.js → chat/file-attachment.js} +0 -0
- /package/dist/cjs/{FileUploader.d.ts → chat/file-uploader.d.ts} +0 -0
- /package/dist/cjs/{multi-thread-view.d.ts → chat/multi-thread-view.d.ts} +0 -0
- /package/dist/cjs/{UploadPill.d.ts → chat/upload-pill.d.ts} +0 -0
- /package/dist/esm/{ChatBotView.d.ts → chat/chat-bot-view.d.ts} +0 -0
- /package/dist/esm/{ChatInput.d.ts → chat/chat-input.d.ts} +0 -0
- /package/dist/esm/{chat-message.d.ts → chat/chat-message.d.ts} +0 -0
- /package/dist/esm/{chat-message.js → chat/chat-message.js} +0 -0
- /package/dist/esm/{ChatTypingIndicator.d.ts → chat/chat-typing-indicator.d.ts} +0 -0
- /package/dist/esm/{conversation-descriptor.d.ts → chat/conversation-descriptor.d.ts} +0 -0
- /package/dist/esm/{conversation-descriptor.js → chat/conversation-descriptor.js} +0 -0
- /package/dist/esm/{file-attachment.d.ts → chat/file-attachment.d.ts} +0 -0
- /package/dist/esm/{file-attachment.js → chat/file-attachment.js} +0 -0
- /package/dist/esm/{FileUploader.d.ts → chat/file-uploader.d.ts} +0 -0
- /package/dist/esm/{multi-thread-view.d.ts → chat/multi-thread-view.d.ts} +0 -0
- /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,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,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 {
|
|
13
|
-
import {
|
|
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 "
|
|
23
|
-
import { Input } from "
|
|
24
|
-
import { Label } from "
|
|
25
|
-
import { Spinner } from "
|
|
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 "
|
|
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
|
-
|
|
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
|
-
|
|
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
|
}
|