@meshagent/meshagent-tailwind 0.41.4 → 0.41.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.
- package/CHANGELOG.md +10 -0
- package/README.md +33 -0
- package/dist/cjs/chat/chat-thread.js +15 -10
- package/dist/cjs/chat/dataset-chat-thread.d.ts +4 -1
- package/dist/cjs/chat/dataset-chat-thread.js +130 -157
- package/dist/cjs/chat/multi-thread-view.d.ts +4 -1
- package/dist/cjs/chat/multi-thread-view.js +4 -0
- package/dist/cjs/chat/new-chat-thread.d.ts +4 -1
- package/dist/cjs/chat/new-chat-thread.js +43 -87
- package/dist/cjs/file-preview/file-preview.d.ts +6 -0
- package/dist/cjs/file-preview/file-preview.js +220 -0
- package/dist/cjs/meetings/camera-grid.d.ts +46 -0
- package/dist/cjs/meetings/camera-grid.js +435 -0
- package/dist/cjs/meetings/controls.d.ts +4 -2
- package/dist/cjs/meetings/controls.js +9 -3
- package/dist/cjs/meetings/lobby.d.ts +17 -0
- package/dist/cjs/meetings/lobby.js +595 -0
- package/dist/cjs/meetings/meeting-scope.d.ts +7 -6
- package/dist/cjs/meetings/meeting-scope.js +64 -15
- package/dist/cjs/meetings/meeting-view.d.ts +6 -0
- package/dist/cjs/meetings/meeting-view.js +635 -0
- package/dist/cjs/meetings/meetings.d.ts +3 -0
- package/dist/cjs/meetings/meetings.js +3 -0
- package/dist/cjs/meetings/wake-lock.js +2 -2
- package/dist/esm/chat/chat-thread.js +15 -10
- package/dist/esm/chat/dataset-chat-thread.d.ts +4 -1
- package/dist/esm/chat/dataset-chat-thread.js +129 -133
- package/dist/esm/chat/multi-thread-view.d.ts +4 -1
- package/dist/esm/chat/multi-thread-view.js +4 -0
- package/dist/esm/chat/new-chat-thread.d.ts +4 -1
- package/dist/esm/chat/new-chat-thread.js +43 -87
- package/dist/esm/file-preview/file-preview.d.ts +6 -0
- package/dist/esm/file-preview/file-preview.js +220 -0
- package/dist/esm/meetings/camera-grid.d.ts +46 -0
- package/dist/esm/meetings/camera-grid.js +405 -0
- package/dist/esm/meetings/controls.d.ts +4 -2
- package/dist/esm/meetings/controls.js +9 -3
- package/dist/esm/meetings/lobby.d.ts +17 -0
- package/dist/esm/meetings/lobby.js +595 -0
- package/dist/esm/meetings/meeting-scope.d.ts +7 -6
- package/dist/esm/meetings/meeting-scope.js +71 -16
- package/dist/esm/meetings/meeting-view.d.ts +6 -0
- package/dist/esm/meetings/meeting-view.js +630 -0
- package/dist/esm/meetings/meetings.d.ts +3 -0
- package/dist/esm/meetings/meetings.js +3 -0
- package/dist/esm/meetings/wake-lock.js +2 -2
- package/dist/index.css +1 -1
- package/package.json +9 -5
|
@@ -0,0 +1,435 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __export = (target, all) => {
|
|
9
|
+
for (var name in all)
|
|
10
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
11
|
+
};
|
|
12
|
+
var __copyProps = (to, from, except, desc) => {
|
|
13
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
14
|
+
for (let key of __getOwnPropNames(from))
|
|
15
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
16
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
17
|
+
}
|
|
18
|
+
return to;
|
|
19
|
+
};
|
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
+
mod
|
|
27
|
+
));
|
|
28
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
|
+
var camera_grid_exports = {};
|
|
30
|
+
__export(camera_grid_exports, {
|
|
31
|
+
CameraGrid: () => CameraGrid,
|
|
32
|
+
TrackSource: () => TrackSource
|
|
33
|
+
});
|
|
34
|
+
module.exports = __toCommonJS(camera_grid_exports);
|
|
35
|
+
var import_jsx_runtime = require("react/jsx-runtime");
|
|
36
|
+
var import_react = __toESM(require("react"));
|
|
37
|
+
var import_livekit_client = require("livekit-client");
|
|
38
|
+
const TrackSource = {
|
|
39
|
+
Camera: import_livekit_client.Track.Source.Camera,
|
|
40
|
+
ScreenShareVideo: import_livekit_client.Track.Source.ScreenShare
|
|
41
|
+
};
|
|
42
|
+
function useParticipantsSnapshot(participants) {
|
|
43
|
+
(0, import_react.useSyncExternalStore)(
|
|
44
|
+
(listener) => {
|
|
45
|
+
const events = [
|
|
46
|
+
"trackPublished",
|
|
47
|
+
"trackSubscribed",
|
|
48
|
+
"trackUnpublished",
|
|
49
|
+
"trackUnsubscribed",
|
|
50
|
+
"trackMuted",
|
|
51
|
+
"trackUnmuted",
|
|
52
|
+
"localTrackPublished",
|
|
53
|
+
"localTrackUnpublished",
|
|
54
|
+
"participantNameChanged",
|
|
55
|
+
"isSpeakingChanged",
|
|
56
|
+
"attributesChanged"
|
|
57
|
+
];
|
|
58
|
+
for (const participant of participants) {
|
|
59
|
+
for (const eventName of events) {
|
|
60
|
+
participant.on(eventName, listener);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
return () => {
|
|
64
|
+
for (const participant of participants) {
|
|
65
|
+
for (const eventName of events) {
|
|
66
|
+
participant.off(eventName, listener);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
};
|
|
70
|
+
},
|
|
71
|
+
() => participants.map(
|
|
72
|
+
(participant) => [
|
|
73
|
+
participant.sid,
|
|
74
|
+
participant.identity,
|
|
75
|
+
participant.isCameraEnabled,
|
|
76
|
+
participant.isScreenShareEnabled,
|
|
77
|
+
participant.isMicrophoneEnabled,
|
|
78
|
+
participant.isSpeaking,
|
|
79
|
+
participant.trackPublications.size,
|
|
80
|
+
participant.name ?? ""
|
|
81
|
+
].join(":")
|
|
82
|
+
).join("|"),
|
|
83
|
+
() => ""
|
|
84
|
+
);
|
|
85
|
+
}
|
|
86
|
+
function publicationAspectRatio(publication) {
|
|
87
|
+
const dimensions = publication?.dimensions ?? { width: 640, height: 480 };
|
|
88
|
+
return dimensions.height > 0 ? dimensions.width / dimensions.height : 4 / 3;
|
|
89
|
+
}
|
|
90
|
+
function layoutCameras(publications, width, height) {
|
|
91
|
+
const slots = Math.max(publications.length, 1);
|
|
92
|
+
let bestRows = 1;
|
|
93
|
+
let bestCols = slots;
|
|
94
|
+
let minWaste = Number.POSITIVE_INFINITY;
|
|
95
|
+
for (let rows = 1; rows <= slots; rows += 1) {
|
|
96
|
+
const cols = Math.ceil(slots / rows);
|
|
97
|
+
const gridAspectRatio = width / cols / (height / rows);
|
|
98
|
+
let aspectRatioWaste = 0;
|
|
99
|
+
for (const publication of publications) {
|
|
100
|
+
aspectRatioWaste += Math.abs(
|
|
101
|
+
publicationAspectRatio(publication) - gridAspectRatio
|
|
102
|
+
);
|
|
103
|
+
}
|
|
104
|
+
if (aspectRatioWaste < minWaste) {
|
|
105
|
+
minWaste = aspectRatioWaste;
|
|
106
|
+
bestRows = rows;
|
|
107
|
+
bestCols = cols;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
return [bestRows, bestCols];
|
|
111
|
+
}
|
|
112
|
+
function CameraGrid({
|
|
113
|
+
participants,
|
|
114
|
+
room,
|
|
115
|
+
spacing = 0,
|
|
116
|
+
showNames = true,
|
|
117
|
+
showAllVideos = false,
|
|
118
|
+
preferredSource,
|
|
119
|
+
rowsDesired = 0,
|
|
120
|
+
columnsDesired = 0,
|
|
121
|
+
tryFill = true,
|
|
122
|
+
activeVideoPublicationForSource,
|
|
123
|
+
activeVideoPublications,
|
|
124
|
+
renderVideoTrack,
|
|
125
|
+
renderAudioStats,
|
|
126
|
+
frameBuilder
|
|
127
|
+
}) {
|
|
128
|
+
useParticipantsSnapshot(participants);
|
|
129
|
+
const items = (0, import_react.useMemo)(() => {
|
|
130
|
+
if (!room) return [];
|
|
131
|
+
const hasShare = participants.some(
|
|
132
|
+
(participant) => activeVideoPublicationForSource(
|
|
133
|
+
participant,
|
|
134
|
+
TrackSource.ScreenShareVideo
|
|
135
|
+
) != null
|
|
136
|
+
);
|
|
137
|
+
const videoSource = preferredSource ?? (hasShare ? TrackSource.ScreenShareVideo : TrackSource.Camera);
|
|
138
|
+
const shouldShowCameraPlaceholder = videoSource === TrackSource.Camera;
|
|
139
|
+
const nextItems = [];
|
|
140
|
+
for (const participant of participants) {
|
|
141
|
+
let added = false;
|
|
142
|
+
const publications = showAllVideos ? activeVideoPublications(participant) : activeVideoPublications(participant, { source: videoSource });
|
|
143
|
+
for (const publication of publications) {
|
|
144
|
+
const track = publication.videoTrack;
|
|
145
|
+
if (track == null) continue;
|
|
146
|
+
added = true;
|
|
147
|
+
nextItems.push({
|
|
148
|
+
participant,
|
|
149
|
+
publication,
|
|
150
|
+
trackNode: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: { pointerEvents: "none", width: "100%", height: "100%" }, children: renderVideoTrack({
|
|
151
|
+
track,
|
|
152
|
+
fit: publication.source === TrackSource.ScreenShareVideo ? "contain" : "cover",
|
|
153
|
+
publication,
|
|
154
|
+
participant
|
|
155
|
+
}) })
|
|
156
|
+
});
|
|
157
|
+
}
|
|
158
|
+
if (shouldShowCameraPlaceholder && !added) {
|
|
159
|
+
nextItems.push({
|
|
160
|
+
participant,
|
|
161
|
+
publication: null,
|
|
162
|
+
trackNode: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
163
|
+
"div",
|
|
164
|
+
{
|
|
165
|
+
style: {
|
|
166
|
+
width: "100%",
|
|
167
|
+
height: "100%",
|
|
168
|
+
background: "#222222",
|
|
169
|
+
display: "flex",
|
|
170
|
+
alignItems: "center",
|
|
171
|
+
justifyContent: "center"
|
|
172
|
+
},
|
|
173
|
+
children: participant.identity.includes(".agent") && renderAudioStats ? renderAudioStats({ room, participant }) : null
|
|
174
|
+
}
|
|
175
|
+
)
|
|
176
|
+
});
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
return nextItems;
|
|
180
|
+
}, [
|
|
181
|
+
activeVideoPublicationForSource,
|
|
182
|
+
activeVideoPublications,
|
|
183
|
+
participants,
|
|
184
|
+
preferredSource,
|
|
185
|
+
renderAudioStats,
|
|
186
|
+
renderVideoTrack,
|
|
187
|
+
room,
|
|
188
|
+
showAllVideos
|
|
189
|
+
]);
|
|
190
|
+
if (!room || items.length === 0) return null;
|
|
191
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: { width: "100%", height: "100%", position: "relative" }, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
192
|
+
CameraGridLayout,
|
|
193
|
+
{
|
|
194
|
+
items,
|
|
195
|
+
spacing,
|
|
196
|
+
showNames,
|
|
197
|
+
rowsDesired,
|
|
198
|
+
columnsDesired,
|
|
199
|
+
tryFill,
|
|
200
|
+
frameBuilder
|
|
201
|
+
}
|
|
202
|
+
) });
|
|
203
|
+
}
|
|
204
|
+
function CameraGridLayout({
|
|
205
|
+
items,
|
|
206
|
+
spacing,
|
|
207
|
+
showNames,
|
|
208
|
+
rowsDesired,
|
|
209
|
+
columnsDesired,
|
|
210
|
+
tryFill,
|
|
211
|
+
frameBuilder
|
|
212
|
+
}) {
|
|
213
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: { position: "absolute", inset: 0 }, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
214
|
+
ResponsiveAbsoluteLayout,
|
|
215
|
+
{
|
|
216
|
+
items,
|
|
217
|
+
spacing,
|
|
218
|
+
showNames,
|
|
219
|
+
rowsDesired,
|
|
220
|
+
columnsDesired,
|
|
221
|
+
tryFill,
|
|
222
|
+
frameBuilder
|
|
223
|
+
}
|
|
224
|
+
) });
|
|
225
|
+
}
|
|
226
|
+
function ResponsiveAbsoluteLayout(props) {
|
|
227
|
+
const { items } = props;
|
|
228
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(SizeObserver, { children: ({ width, height }) => {
|
|
229
|
+
if (width <= 0 || height <= 0) return null;
|
|
230
|
+
return renderAbsoluteItems({ ...props, width, height, slots: items.length });
|
|
231
|
+
} });
|
|
232
|
+
}
|
|
233
|
+
function renderAbsoluteItems({
|
|
234
|
+
items,
|
|
235
|
+
spacing,
|
|
236
|
+
showNames,
|
|
237
|
+
rowsDesired,
|
|
238
|
+
columnsDesired,
|
|
239
|
+
tryFill,
|
|
240
|
+
frameBuilder,
|
|
241
|
+
width,
|
|
242
|
+
height,
|
|
243
|
+
slots
|
|
244
|
+
}) {
|
|
245
|
+
const positioned = [];
|
|
246
|
+
if (rowsDesired === 0 && columnsDesired === 0) {
|
|
247
|
+
const [rows, cols] = layoutCameras(
|
|
248
|
+
items.map((item) => item.publication),
|
|
249
|
+
width,
|
|
250
|
+
height
|
|
251
|
+
);
|
|
252
|
+
const availableWidth = Math.max(width - spacing * (cols - 1), 0);
|
|
253
|
+
const availableHeight = Math.max(height - spacing * (rows - 1), 0);
|
|
254
|
+
const cellWidth = availableWidth / cols;
|
|
255
|
+
const cellHeight = availableHeight / rows;
|
|
256
|
+
for (let row = 0; row < rows; row += 1) {
|
|
257
|
+
for (let col = 0; col < cols; col += 1) {
|
|
258
|
+
const index = row * cols + col;
|
|
259
|
+
const item = items[index];
|
|
260
|
+
if (!item) break;
|
|
261
|
+
positioned.push(
|
|
262
|
+
absoluteCell({
|
|
263
|
+
key: index,
|
|
264
|
+
left: col * (cellWidth + spacing),
|
|
265
|
+
top: row * (cellHeight + spacing),
|
|
266
|
+
width: cellWidth,
|
|
267
|
+
height: cellHeight,
|
|
268
|
+
item,
|
|
269
|
+
showNames,
|
|
270
|
+
frameBuilder
|
|
271
|
+
})
|
|
272
|
+
);
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_jsx_runtime.Fragment, { children: positioned });
|
|
276
|
+
}
|
|
277
|
+
let x = 0;
|
|
278
|
+
let y = 0;
|
|
279
|
+
if (rowsDesired > 0 || columnsDesired > 0 || Math.min(width / height, height / width) > 0.5 || slots < 4 && tryFill) {
|
|
280
|
+
let rows;
|
|
281
|
+
let cols;
|
|
282
|
+
if (width < height) {
|
|
283
|
+
rows = Math.trunc(
|
|
284
|
+
rowsDesired > 0 ? rowsDesired : columnsDesired > 0 ? slots / columnsDesired : Math.ceil(Math.sqrt(slots))
|
|
285
|
+
);
|
|
286
|
+
cols = columnsDesired > 0 ? columnsDesired : Math.ceil(slots / rows);
|
|
287
|
+
} else {
|
|
288
|
+
cols = Math.trunc(
|
|
289
|
+
columnsDesired > 0 ? columnsDesired : rowsDesired > 0 ? slots / rowsDesired : Math.ceil(Math.sqrt(slots))
|
|
290
|
+
);
|
|
291
|
+
rows = rowsDesired > 0 ? rowsDesired : Math.ceil(slots / cols);
|
|
292
|
+
}
|
|
293
|
+
const cellWidth = width / cols + 1 - spacing * (cols - 1) / cols;
|
|
294
|
+
const cellHeight = height / rows - spacing * (rows - 1) / rows;
|
|
295
|
+
for (let row = 0; row < rows; row += 1) {
|
|
296
|
+
for (let col = 0; col < cols; col += 1) {
|
|
297
|
+
const index = col + row * cols;
|
|
298
|
+
const item = items[index];
|
|
299
|
+
if (!item) continue;
|
|
300
|
+
positioned.push(
|
|
301
|
+
absoluteCell({
|
|
302
|
+
key: index,
|
|
303
|
+
left: col * cellWidth + spacing * col,
|
|
304
|
+
top: row * cellHeight + spacing * row,
|
|
305
|
+
width: cellWidth,
|
|
306
|
+
height: cellHeight,
|
|
307
|
+
item,
|
|
308
|
+
showNames,
|
|
309
|
+
frameBuilder
|
|
310
|
+
})
|
|
311
|
+
);
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
} else {
|
|
315
|
+
const totalSpace = width * height;
|
|
316
|
+
let rowUsedSpace = totalSpace;
|
|
317
|
+
let rows = 1;
|
|
318
|
+
let vertRows = false;
|
|
319
|
+
for (let i = 1; i < 10; i += 0.1) {
|
|
320
|
+
const floored = Math.floor(i);
|
|
321
|
+
const itemSize = height / i;
|
|
322
|
+
const usedSpace = itemSize * itemSize * Math.max(slots, 1);
|
|
323
|
+
if (itemSize * Math.ceil(slots / floored) <= width && itemSize * floored <= height && usedSpace <= totalSpace && totalSpace - usedSpace < rowUsedSpace) {
|
|
324
|
+
rows = i;
|
|
325
|
+
rowUsedSpace = totalSpace - usedSpace;
|
|
326
|
+
vertRows = true;
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
for (let i = 1; i < 10; i += 0.1) {
|
|
330
|
+
const floored = Math.floor(i);
|
|
331
|
+
const itemSize = width / i;
|
|
332
|
+
const usedSpace = itemSize * itemSize * Math.max(slots, 1);
|
|
333
|
+
if (itemSize * Math.ceil(slots / floored) <= height && itemSize * floored <= width && usedSpace <= totalSpace && totalSpace - usedSpace < rowUsedSpace) {
|
|
334
|
+
rows = i;
|
|
335
|
+
rowUsedSpace = totalSpace - usedSpace;
|
|
336
|
+
vertRows = false;
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
if (vertRows) {
|
|
340
|
+
const itemSize = (height - spacing * rows) / rows;
|
|
341
|
+
for (let index = 0; index < items.length; index += 1) {
|
|
342
|
+
const item = items[index];
|
|
343
|
+
positioned.push(
|
|
344
|
+
absoluteCell({
|
|
345
|
+
key: index,
|
|
346
|
+
left: x,
|
|
347
|
+
top: y,
|
|
348
|
+
width: itemSize,
|
|
349
|
+
height: itemSize,
|
|
350
|
+
item,
|
|
351
|
+
showNames,
|
|
352
|
+
frameBuilder
|
|
353
|
+
})
|
|
354
|
+
);
|
|
355
|
+
x += itemSize + spacing;
|
|
356
|
+
if (x + itemSize > width) {
|
|
357
|
+
x = spacing;
|
|
358
|
+
y += itemSize + spacing;
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
} else {
|
|
362
|
+
const itemSize = (width - spacing * rows) / rows;
|
|
363
|
+
for (let index = 0; index < items.length; index += 1) {
|
|
364
|
+
const item = items[index];
|
|
365
|
+
positioned.push(
|
|
366
|
+
absoluteCell({
|
|
367
|
+
key: index,
|
|
368
|
+
left: x,
|
|
369
|
+
top: y,
|
|
370
|
+
width: itemSize,
|
|
371
|
+
height: itemSize,
|
|
372
|
+
item,
|
|
373
|
+
showNames,
|
|
374
|
+
frameBuilder
|
|
375
|
+
})
|
|
376
|
+
);
|
|
377
|
+
y += itemSize + spacing;
|
|
378
|
+
if (y + itemSize > height) {
|
|
379
|
+
y = spacing;
|
|
380
|
+
x += itemSize + spacing;
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
}
|
|
384
|
+
}
|
|
385
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_jsx_runtime.Fragment, { children: positioned });
|
|
386
|
+
}
|
|
387
|
+
function absoluteCell({
|
|
388
|
+
key,
|
|
389
|
+
left,
|
|
390
|
+
top,
|
|
391
|
+
width,
|
|
392
|
+
height,
|
|
393
|
+
item,
|
|
394
|
+
showNames,
|
|
395
|
+
frameBuilder
|
|
396
|
+
}) {
|
|
397
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
398
|
+
"div",
|
|
399
|
+
{
|
|
400
|
+
style: {
|
|
401
|
+
position: "absolute",
|
|
402
|
+
left,
|
|
403
|
+
top,
|
|
404
|
+
width,
|
|
405
|
+
height,
|
|
406
|
+
overflow: "hidden"
|
|
407
|
+
},
|
|
408
|
+
children: frameBuilder({
|
|
409
|
+
participant: item.participant,
|
|
410
|
+
publication: item.publication,
|
|
411
|
+
trackNode: item.trackNode,
|
|
412
|
+
showName: showNames
|
|
413
|
+
})
|
|
414
|
+
},
|
|
415
|
+
key
|
|
416
|
+
);
|
|
417
|
+
}
|
|
418
|
+
function SizeObserver({ children }) {
|
|
419
|
+
const ref = import_react.default.useRef(null);
|
|
420
|
+
const [size, setSize] = import_react.default.useState({
|
|
421
|
+
width: 0,
|
|
422
|
+
height: 0
|
|
423
|
+
});
|
|
424
|
+
import_react.default.useLayoutEffect(() => {
|
|
425
|
+
const element = ref.current;
|
|
426
|
+
if (!element) return;
|
|
427
|
+
const observer = new ResizeObserver(([entry]) => {
|
|
428
|
+
const rect = entry.contentRect;
|
|
429
|
+
setSize({ width: rect.width, height: rect.height });
|
|
430
|
+
});
|
|
431
|
+
observer.observe(element);
|
|
432
|
+
return () => observer.disconnect();
|
|
433
|
+
}, []);
|
|
434
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { ref, className: "absolute inset-0", children: children(size) });
|
|
435
|
+
}
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import type { ReactElement } from "react";
|
|
2
2
|
import { Room } from "livekit-client";
|
|
3
3
|
import { MeetingController } from "./meeting-scope";
|
|
4
|
-
export declare function MeetingControls({ controller: providedController, spacing, }: {
|
|
4
|
+
export declare function MeetingControls({ controller: providedController, onDisconnect, spacing, }: {
|
|
5
5
|
controller?: MeetingController;
|
|
6
|
+
onDisconnect?: () => void;
|
|
6
7
|
spacing?: number;
|
|
7
8
|
}): ReactElement;
|
|
8
9
|
export declare function CameraToggle({ controller }: {
|
|
@@ -11,8 +12,9 @@ export declare function CameraToggle({ controller }: {
|
|
|
11
12
|
export declare function MicToggle({ controller }: {
|
|
12
13
|
controller?: MeetingController;
|
|
13
14
|
}): ReactElement | null;
|
|
14
|
-
export declare function ConnectionButton({ controller }: {
|
|
15
|
+
export declare function ConnectionButton({ controller, onDisconnect, }: {
|
|
15
16
|
controller?: MeetingController;
|
|
17
|
+
onDisconnect?: () => void;
|
|
16
18
|
}): ReactElement;
|
|
17
19
|
export declare function ChangeSettings({ room }: {
|
|
18
20
|
room: Room;
|
|
@@ -49,6 +49,7 @@ function useControllerVersion(controller) {
|
|
|
49
49
|
}
|
|
50
50
|
function MeetingControls({
|
|
51
51
|
controller: providedController,
|
|
52
|
+
onDisconnect,
|
|
52
53
|
spacing = 5
|
|
53
54
|
}) {
|
|
54
55
|
const controller = (0, import_meeting_scope.useMeetingController)(providedController);
|
|
@@ -60,7 +61,7 @@ function MeetingControls({
|
|
|
60
61
|
className: "flex flex-wrap items-center justify-center",
|
|
61
62
|
style: { gap: spacing },
|
|
62
63
|
children: [
|
|
63
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(ConnectionButton, { controller }),
|
|
64
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(ConnectionButton, { controller, onDisconnect }),
|
|
64
65
|
hasLocalParticipant ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
|
|
65
66
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(MicToggle, { controller }),
|
|
66
67
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(CameraToggle, { controller }),
|
|
@@ -179,7 +180,10 @@ function MicToggle({ controller }) {
|
|
|
179
180
|
}
|
|
180
181
|
);
|
|
181
182
|
}
|
|
182
|
-
function ConnectionButton({
|
|
183
|
+
function ConnectionButton({
|
|
184
|
+
controller,
|
|
185
|
+
onDisconnect
|
|
186
|
+
}) {
|
|
183
187
|
const resolvedController = (0, import_meeting_scope.useMeetingController)(controller);
|
|
184
188
|
useControllerVersion(resolvedController);
|
|
185
189
|
const state = resolvedController.livekitRoom.state;
|
|
@@ -191,7 +195,9 @@ function ConnectionButton({ controller }) {
|
|
|
191
195
|
destructive: true,
|
|
192
196
|
icon: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_lucide_react.Phone, {}),
|
|
193
197
|
onClick: () => {
|
|
194
|
-
void resolvedController.disconnect()
|
|
198
|
+
void resolvedController.disconnect().catch((error) => {
|
|
199
|
+
console.warn("unable to disconnect meeting", error);
|
|
200
|
+
}).finally(() => onDisconnect?.());
|
|
195
201
|
}
|
|
196
202
|
}
|
|
197
203
|
);
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { ReactElement } from "react";
|
|
2
|
+
import { type MeetingController, type MeetingFastConnectOptions } from "./meeting-scope";
|
|
3
|
+
export interface MeetingLobbyJoinOptions {
|
|
4
|
+
enableVideo: boolean;
|
|
5
|
+
enableAudio: boolean;
|
|
6
|
+
videoUnavailable: boolean;
|
|
7
|
+
audioUnavailable: boolean;
|
|
8
|
+
videoDeviceId?: string;
|
|
9
|
+
audioDeviceId?: string;
|
|
10
|
+
audioOutputDeviceId?: string;
|
|
11
|
+
}
|
|
12
|
+
export declare function meetingFastConnectOptions(options: MeetingLobbyJoinOptions): MeetingFastConnectOptions;
|
|
13
|
+
export declare function MeetingLobby({ controller: providedController, onCancel, onJoin, }: {
|
|
14
|
+
controller?: MeetingController;
|
|
15
|
+
onCancel?: () => void;
|
|
16
|
+
onJoin?: (options: MeetingLobbyJoinOptions) => void | Promise<void>;
|
|
17
|
+
}): ReactElement;
|