@ai-matrx/meet 0.7.9 → 0.7.11
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 +51 -0
- package/dist/index.cjs +1917 -1311
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +292 -1
- package/dist/index.d.ts +292 -1
- package/dist/index.js +1917 -1311
- package/dist/index.js.map +1 -1
- package/dist/react.cjs +2360 -669
- package/dist/react.cjs.map +1 -1
- package/dist/react.d.cts +94 -3
- package/dist/react.d.ts +94 -3
- package/dist/react.js +2361 -670
- package/dist/react.js.map +1 -1
- package/dist/styles.css +293 -0
- package/dist/tokens.css +2 -0
- package/package.json +1 -1
package/dist/react.js
CHANGED
|
@@ -241,7 +241,14 @@ var MEET_ROUTES = {
|
|
|
241
241
|
*/
|
|
242
242
|
moderate: "/api/v1/meet/moderate",
|
|
243
243
|
/** Meet wave 2: the SAVED chat — `POST` sends to everyone, `GET ?meeting_id=` reads history. */
|
|
244
|
-
chat: "/api/v1/meet/chat"
|
|
244
|
+
chat: "/api/v1/meet/chat",
|
|
245
|
+
/**
|
|
246
|
+
* Meet wave 5: polls, Q&A, the shared whiteboard and breakout rooms. `POST` acts
|
|
247
|
+
* (`{meeting_id, action, …}`), `GET ?meeting_id=` reads what this viewer may see.
|
|
248
|
+
*/
|
|
249
|
+
collab: "/api/v1/meet/collab",
|
|
250
|
+
/** Meet wave 5: translate finished caption lines into this viewer's language. */
|
|
251
|
+
captionsTranslate: "/api/v1/meet/captions/translate"
|
|
245
252
|
};
|
|
246
253
|
function meetingPath(template, meetingId) {
|
|
247
254
|
return template.replace("{meeting_id}", encodeURIComponent(meetingId));
|
|
@@ -300,7 +307,8 @@ function parseRoomToken(body, roomName) {
|
|
|
300
307
|
// server that has not landed MRI-A11 — and never invents a host from
|
|
301
308
|
// silence, because both fallbacks below grant nothing.
|
|
302
309
|
role: readRole(payload, "role") ?? (isHost ? "host" : identity.startsWith("guest:") ? "guest" : "participant"),
|
|
303
|
-
lobby: readBoolean(payload, "lobby", false)
|
|
310
|
+
lobby: readBoolean(payload, "lobby", false),
|
|
311
|
+
breakoutRoomId: readString(payload, "breakout_room_id") ?? null
|
|
304
312
|
};
|
|
305
313
|
}
|
|
306
314
|
function createTokenClient(options) {
|
|
@@ -348,6 +356,7 @@ function createTokenClient(options) {
|
|
|
348
356
|
room_name: input.roomName,
|
|
349
357
|
...input.meetingId !== void 0 ? { meeting_id: input.meetingId } : {},
|
|
350
358
|
...input.slug !== void 0 ? { slug: input.slug } : {},
|
|
359
|
+
...input.breakoutRoomId != null ? { breakout_room_id: input.breakoutRoomId } : {},
|
|
351
360
|
organization_id: input.identity.organizationId,
|
|
352
361
|
display_name: input.identity.displayName,
|
|
353
362
|
device_id: input.identity.deviceId,
|
|
@@ -411,7 +420,8 @@ function createTokenClient(options) {
|
|
|
411
420
|
return {
|
|
412
421
|
get(input) {
|
|
413
422
|
const entry = cache.get(input.roomName);
|
|
414
|
-
|
|
423
|
+
const sameRoom = entry !== void 0 && (entry.token.breakoutRoomId ?? null) === (input.breakoutRoomId ?? null);
|
|
424
|
+
if (entry !== void 0 && sameRoom) {
|
|
415
425
|
if (entry.inFlight !== null) return entry.inFlight;
|
|
416
426
|
if (!expired(entry)) return Promise.resolve(entry.token);
|
|
417
427
|
}
|
|
@@ -457,7 +467,8 @@ function placeholder(roomName) {
|
|
|
457
467
|
canRecord: false,
|
|
458
468
|
isHost: false,
|
|
459
469
|
role: "participant",
|
|
460
|
-
lobby: false
|
|
470
|
+
lobby: false,
|
|
471
|
+
breakoutRoomId: null
|
|
461
472
|
};
|
|
462
473
|
}
|
|
463
474
|
async function serverSentence(response) {
|
|
@@ -1515,6 +1526,339 @@ function listenOnlyNotice(media) {
|
|
|
1515
1526
|
return isListenOnly(media) ? LISTEN_ONLY_NOTICE : null;
|
|
1516
1527
|
}
|
|
1517
1528
|
|
|
1529
|
+
// src/core/collab.ts
|
|
1530
|
+
var EMPTY_COLLAB = {
|
|
1531
|
+
loaded: false,
|
|
1532
|
+
error: null,
|
|
1533
|
+
settings: null,
|
|
1534
|
+
polls: [],
|
|
1535
|
+
questions: [],
|
|
1536
|
+
strokes: [],
|
|
1537
|
+
breakout: null,
|
|
1538
|
+
broadcast: null,
|
|
1539
|
+
moveRequest: null,
|
|
1540
|
+
panelRequest: null,
|
|
1541
|
+
captionLanguage: null,
|
|
1542
|
+
captionTranslations: {},
|
|
1543
|
+
captionTranslationError: null
|
|
1544
|
+
};
|
|
1545
|
+
function obj(value) {
|
|
1546
|
+
return typeof value === "object" && value !== null && !Array.isArray(value) ? value : null;
|
|
1547
|
+
}
|
|
1548
|
+
function str(value) {
|
|
1549
|
+
return typeof value === "string" ? value : null;
|
|
1550
|
+
}
|
|
1551
|
+
function num(value) {
|
|
1552
|
+
return typeof value === "number" && Number.isFinite(value) ? value : null;
|
|
1553
|
+
}
|
|
1554
|
+
function strings(value) {
|
|
1555
|
+
return Array.isArray(value) ? value.filter((v) => typeof v === "string") : [];
|
|
1556
|
+
}
|
|
1557
|
+
function pollFromRow(row) {
|
|
1558
|
+
const id = str(row["id"]);
|
|
1559
|
+
if (id === null) return null;
|
|
1560
|
+
const options = [];
|
|
1561
|
+
for (const raw of Array.isArray(row["options"]) ? row["options"] : []) {
|
|
1562
|
+
const option = obj(raw);
|
|
1563
|
+
const optionId = option === null ? null : str(option["id"]);
|
|
1564
|
+
if (option === null || optionId === null) continue;
|
|
1565
|
+
const votes = num(option["votes"]);
|
|
1566
|
+
options.push({
|
|
1567
|
+
id: optionId,
|
|
1568
|
+
text: str(option["text"]) ?? "",
|
|
1569
|
+
...votes !== null ? { votes } : {},
|
|
1570
|
+
...Array.isArray(option["voters"]) ? { voters: strings(option["voters"]) } : {}
|
|
1571
|
+
});
|
|
1572
|
+
}
|
|
1573
|
+
const state = str(row["state"]);
|
|
1574
|
+
return {
|
|
1575
|
+
id,
|
|
1576
|
+
question: str(row["question"]) ?? "",
|
|
1577
|
+
options,
|
|
1578
|
+
multiple: row["multiple"] === true,
|
|
1579
|
+
anonymous: row["anonymous"] === true,
|
|
1580
|
+
state: state === "live" || state === "closed" ? state : "draft",
|
|
1581
|
+
resultsShared: row["results_shared"] === true,
|
|
1582
|
+
voterCount: num(row["voter_count"]),
|
|
1583
|
+
myVote: strings(row["my_vote"]),
|
|
1584
|
+
createdByName: str(row["created_by_name"]) ?? "",
|
|
1585
|
+
createdAt: str(row["created_at"])
|
|
1586
|
+
};
|
|
1587
|
+
}
|
|
1588
|
+
function questionFromRow(row) {
|
|
1589
|
+
const id = str(row["id"]);
|
|
1590
|
+
if (id === null) return null;
|
|
1591
|
+
const state = str(row["state"]);
|
|
1592
|
+
return {
|
|
1593
|
+
id,
|
|
1594
|
+
text: str(row["text"]) ?? "",
|
|
1595
|
+
askerName: str(row["asker_name"]) ?? "",
|
|
1596
|
+
anonymous: row["anonymous"] === true,
|
|
1597
|
+
state: state === "answered" || state === "dismissed" ? state : "open",
|
|
1598
|
+
answer: str(row["answer"]),
|
|
1599
|
+
answeredByName: str(row["answered_by_name"]),
|
|
1600
|
+
upvotes: num(row["upvotes"]) ?? 0,
|
|
1601
|
+
upvotedByMe: row["upvoted_by_me"] === true,
|
|
1602
|
+
mine: row["mine"] === true,
|
|
1603
|
+
createdAt: str(row["created_at"])
|
|
1604
|
+
};
|
|
1605
|
+
}
|
|
1606
|
+
function strokeFromRow(row) {
|
|
1607
|
+
const id = str(row["id"]);
|
|
1608
|
+
if (id === null || !Array.isArray(row["points"])) return null;
|
|
1609
|
+
const points = [];
|
|
1610
|
+
for (const raw of row["points"]) {
|
|
1611
|
+
if (Array.isArray(raw) && typeof raw[0] === "number" && typeof raw[1] === "number") {
|
|
1612
|
+
points.push([raw[0], raw[1]]);
|
|
1613
|
+
}
|
|
1614
|
+
}
|
|
1615
|
+
return {
|
|
1616
|
+
id,
|
|
1617
|
+
points,
|
|
1618
|
+
color: str(row["color"]) ?? "#111827",
|
|
1619
|
+
width: num(row["width"]) ?? 3,
|
|
1620
|
+
tool: row["tool"] === "highlighter" ? "highlighter" : "pen",
|
|
1621
|
+
by: str(row["by"]) ?? "",
|
|
1622
|
+
byName: str(row["by_name"]) ?? ""
|
|
1623
|
+
};
|
|
1624
|
+
}
|
|
1625
|
+
function broadcastFrom(value) {
|
|
1626
|
+
const row = obj(value);
|
|
1627
|
+
const text3 = row === null ? null : str(row["text"]);
|
|
1628
|
+
if (row === null || text3 === null) return null;
|
|
1629
|
+
return { text: text3, by: str(row["by"]) ?? "", at: str(row["at"]) ?? "" };
|
|
1630
|
+
}
|
|
1631
|
+
function planFromRow(row) {
|
|
1632
|
+
const id = str(row["id"]);
|
|
1633
|
+
if (id === null) return null;
|
|
1634
|
+
const rooms = [];
|
|
1635
|
+
for (const raw of Array.isArray(row["rooms"]) ? row["rooms"] : []) {
|
|
1636
|
+
const room = obj(raw);
|
|
1637
|
+
const roomId = room === null ? null : str(room["id"]);
|
|
1638
|
+
if (room === null || roomId === null) continue;
|
|
1639
|
+
rooms.push({ id: roomId, name: str(room["name"]) ?? roomId, identities: strings(room["identities"]) });
|
|
1640
|
+
}
|
|
1641
|
+
return {
|
|
1642
|
+
id,
|
|
1643
|
+
state: row["state"] === "open" ? "open" : "closed",
|
|
1644
|
+
rooms,
|
|
1645
|
+
allowChoose: row["allow_choose"] === true,
|
|
1646
|
+
minutes: num(row["minutes"]) ?? 0,
|
|
1647
|
+
openedAt: str(row["opened_at"]),
|
|
1648
|
+
endsAt: str(row["ends_at"]),
|
|
1649
|
+
closedAt: str(row["closed_at"]),
|
|
1650
|
+
broadcasts: (Array.isArray(row["broadcasts"]) ? row["broadcasts"] : []).map(broadcastFrom).filter((b) => b !== null)
|
|
1651
|
+
};
|
|
1652
|
+
}
|
|
1653
|
+
function settingsFromRow(row) {
|
|
1654
|
+
if (row === null) return null;
|
|
1655
|
+
return {
|
|
1656
|
+
pollsEnabled: row["polls_enabled"] === true,
|
|
1657
|
+
pollMaxOptions: num(row["poll_max_options"]) ?? 10,
|
|
1658
|
+
qaEnabled: row["qa_enabled"] === true,
|
|
1659
|
+
qaAnonymousAllowed: row["qa_anonymous_allowed"] === true,
|
|
1660
|
+
whiteboardEnabled: row["whiteboard_enabled"] === true,
|
|
1661
|
+
breakoutsEnabled: row["breakouts_enabled"] === true,
|
|
1662
|
+
breakoutMaxRooms: num(row["breakout_max_rooms"]) ?? 20,
|
|
1663
|
+
breakoutDefaultMinutes: num(row["breakout_default_minutes"]) ?? 15,
|
|
1664
|
+
captionTranslationEnabled: row["caption_translation_enabled"] === true,
|
|
1665
|
+
captionTranslationLanguage: str(row["caption_translation_language"]) ?? ""
|
|
1666
|
+
};
|
|
1667
|
+
}
|
|
1668
|
+
function collabFromState(body, previous) {
|
|
1669
|
+
const list = (key, parse) => (Array.isArray(body[key]) ? body[key] : []).map((raw) => {
|
|
1670
|
+
const row = obj(raw);
|
|
1671
|
+
return row === null ? null : parse(row);
|
|
1672
|
+
}).filter((item) => item !== null);
|
|
1673
|
+
const breakoutRow = obj(body["breakout"]);
|
|
1674
|
+
return {
|
|
1675
|
+
...previous,
|
|
1676
|
+
loaded: true,
|
|
1677
|
+
error: null,
|
|
1678
|
+
settings: settingsFromRow(obj(body["settings"])),
|
|
1679
|
+
polls: list("polls", pollFromRow),
|
|
1680
|
+
questions: list("questions", questionFromRow),
|
|
1681
|
+
strokes: list("strokes", strokeFromRow),
|
|
1682
|
+
breakout: breakoutRow === null ? null : planFromRow(breakoutRow)
|
|
1683
|
+
};
|
|
1684
|
+
}
|
|
1685
|
+
function upsert(items, next) {
|
|
1686
|
+
const index = items.findIndex((item) => item.id === next.id);
|
|
1687
|
+
if (index === -1) return [...items, next];
|
|
1688
|
+
const copy = items.slice();
|
|
1689
|
+
copy[index] = next;
|
|
1690
|
+
return copy;
|
|
1691
|
+
}
|
|
1692
|
+
function withItem(collab, row, fromRoom = false) {
|
|
1693
|
+
const kind = str(row["kind"]);
|
|
1694
|
+
if (kind === "poll") {
|
|
1695
|
+
const poll = pollFromRow(row);
|
|
1696
|
+
if (poll === null) return collab;
|
|
1697
|
+
const known = collab.polls.find((p) => p.id === poll.id);
|
|
1698
|
+
const merged = fromRoom && known !== void 0 ? { ...poll, myVote: known.myVote } : poll;
|
|
1699
|
+
return { ...collab, polls: upsert(collab.polls, merged) };
|
|
1700
|
+
}
|
|
1701
|
+
if (kind === "question") {
|
|
1702
|
+
const question = questionFromRow(row);
|
|
1703
|
+
if (question === null) return collab;
|
|
1704
|
+
const known = collab.questions.find((q) => q.id === question.id);
|
|
1705
|
+
const merged = fromRoom && known !== void 0 ? { ...question, mine: known.mine, upvotedByMe: known.upvotedByMe } : question;
|
|
1706
|
+
return { ...collab, questions: upsert(collab.questions, merged) };
|
|
1707
|
+
}
|
|
1708
|
+
if (kind === "stroke") {
|
|
1709
|
+
const stroke = strokeFromRow(row);
|
|
1710
|
+
if (stroke === null) return collab;
|
|
1711
|
+
return { ...collab, strokes: upsert(collab.strokes, stroke) };
|
|
1712
|
+
}
|
|
1713
|
+
if (kind === "breakout") {
|
|
1714
|
+
const plan = planFromRow(row);
|
|
1715
|
+
if (plan === null) return collab;
|
|
1716
|
+
return { ...collab, breakout: plan };
|
|
1717
|
+
}
|
|
1718
|
+
return collab;
|
|
1719
|
+
}
|
|
1720
|
+
function without(collab, ids) {
|
|
1721
|
+
const gone = new Set(ids);
|
|
1722
|
+
return {
|
|
1723
|
+
...collab,
|
|
1724
|
+
polls: collab.polls.filter((p) => !gone.has(p.id)),
|
|
1725
|
+
questions: collab.questions.filter((q) => !gone.has(q.id)),
|
|
1726
|
+
strokes: collab.strokes.filter((s) => !gone.has(s.id))
|
|
1727
|
+
};
|
|
1728
|
+
}
|
|
1729
|
+
function applyCollabPacket(collab, payload, context) {
|
|
1730
|
+
const item = obj(payload["item"]);
|
|
1731
|
+
const audience = str(payload["audience"]);
|
|
1732
|
+
if (item !== null) {
|
|
1733
|
+
const kind = str(item["kind"]);
|
|
1734
|
+
const hostOnlyView = kind === "poll" || kind === "question";
|
|
1735
|
+
if (hostOnlyView && context.isHost && audience !== "hosts") {
|
|
1736
|
+
return { next: null, dropped: "the room copy of an item a host receives in full" };
|
|
1737
|
+
}
|
|
1738
|
+
let next = withItem(collab, item, true);
|
|
1739
|
+
if (kind === "poll" && str(item["state"]) === "live") {
|
|
1740
|
+
const before = collab.polls.find((p) => p.id === str(item["id"]));
|
|
1741
|
+
if (before === void 0 || before.state !== "live") {
|
|
1742
|
+
next = { ...next, panelRequest: { panel: "polls", at: context.now } };
|
|
1743
|
+
}
|
|
1744
|
+
}
|
|
1745
|
+
if (kind === "breakout") {
|
|
1746
|
+
const plan = planFromRow(item);
|
|
1747
|
+
if (plan !== null && plan.state === "closed") {
|
|
1748
|
+
next = { ...next, moveRequest: { roomId: null, at: context.now } };
|
|
1749
|
+
}
|
|
1750
|
+
}
|
|
1751
|
+
const move = obj(payload["move"]);
|
|
1752
|
+
if (move !== null && str(move["identity"]) === context.localIdentity) {
|
|
1753
|
+
next = { ...next, moveRequest: { roomId: str(move["room_id"]), at: context.now } };
|
|
1754
|
+
}
|
|
1755
|
+
return { next };
|
|
1756
|
+
}
|
|
1757
|
+
if (Array.isArray(payload["removed"])) {
|
|
1758
|
+
return { next: without(collab, strings(payload["removed"])) };
|
|
1759
|
+
}
|
|
1760
|
+
if (Array.isArray(payload["hidden"])) {
|
|
1761
|
+
return context.isHost ? { next: null, dropped: "hosts keep dismissed questions" } : { next: without(collab, strings(payload["hidden"])) };
|
|
1762
|
+
}
|
|
1763
|
+
if (payload["cleared"] === "whiteboard") {
|
|
1764
|
+
return { next: { ...collab, strokes: [] } };
|
|
1765
|
+
}
|
|
1766
|
+
const broadcast = broadcastFrom(payload["broadcast"]);
|
|
1767
|
+
if (broadcast !== null) {
|
|
1768
|
+
return { next: { ...collab, broadcast } };
|
|
1769
|
+
}
|
|
1770
|
+
return { next: null, dropped: "a collab packet with nothing this version understands" };
|
|
1771
|
+
}
|
|
1772
|
+
function assignedRoom(plan, identity) {
|
|
1773
|
+
if (plan === null || plan.state !== "open" || identity === null) return null;
|
|
1774
|
+
return plan.rooms.find((room) => room.identities.includes(identity)) ?? null;
|
|
1775
|
+
}
|
|
1776
|
+
function autoAssign(identities, rooms, exclude = []) {
|
|
1777
|
+
const count2 = Math.max(1, Math.floor(rooms));
|
|
1778
|
+
const out = Array.from({ length: count2 }, () => []);
|
|
1779
|
+
const skip = new Set(exclude);
|
|
1780
|
+
let index = 0;
|
|
1781
|
+
for (const identity of identities) {
|
|
1782
|
+
if (skip.has(identity)) continue;
|
|
1783
|
+
out[index % count2].push(identity);
|
|
1784
|
+
index += 1;
|
|
1785
|
+
}
|
|
1786
|
+
return out;
|
|
1787
|
+
}
|
|
1788
|
+
function breakoutRemainingMs(plan, now) {
|
|
1789
|
+
if (plan === null || plan.state !== "open" || plan.endsAt === null) return null;
|
|
1790
|
+
const end = Date.parse(plan.endsAt);
|
|
1791
|
+
return Number.isNaN(end) ? null : Math.max(0, end - now);
|
|
1792
|
+
}
|
|
1793
|
+
function defaultCaptionLanguage(settings, viewerLanguage) {
|
|
1794
|
+
const configured = settings?.captionTranslationLanguage.trim() ?? "";
|
|
1795
|
+
if (configured.length > 0) return configured;
|
|
1796
|
+
const own = (viewerLanguage ?? "").trim();
|
|
1797
|
+
return own.length > 0 ? own : "en";
|
|
1798
|
+
}
|
|
1799
|
+
var CAPTION_LANGUAGES = [
|
|
1800
|
+
{ tag: "en", name: "English" },
|
|
1801
|
+
{ tag: "es", name: "Spanish" },
|
|
1802
|
+
{ tag: "fr", name: "French" },
|
|
1803
|
+
{ tag: "de", name: "German" },
|
|
1804
|
+
{ tag: "it", name: "Italian" },
|
|
1805
|
+
{ tag: "pt", name: "Portuguese" },
|
|
1806
|
+
{ tag: "nl", name: "Dutch" },
|
|
1807
|
+
{ tag: "pl", name: "Polish" },
|
|
1808
|
+
{ tag: "ru", name: "Russian" },
|
|
1809
|
+
{ tag: "uk", name: "Ukrainian" },
|
|
1810
|
+
{ tag: "tr", name: "Turkish" },
|
|
1811
|
+
{ tag: "ar", name: "Arabic" },
|
|
1812
|
+
{ tag: "he", name: "Hebrew" },
|
|
1813
|
+
{ tag: "fa", name: "Persian" },
|
|
1814
|
+
{ tag: "hi", name: "Hindi" },
|
|
1815
|
+
{ tag: "bn", name: "Bengali" },
|
|
1816
|
+
{ tag: "zh", name: "Chinese" },
|
|
1817
|
+
{ tag: "ja", name: "Japanese" },
|
|
1818
|
+
{ tag: "ko", name: "Korean" },
|
|
1819
|
+
{ tag: "vi", name: "Vietnamese" },
|
|
1820
|
+
{ tag: "th", name: "Thai" },
|
|
1821
|
+
{ tag: "id", name: "Indonesian" },
|
|
1822
|
+
{ tag: "sv", name: "Swedish" }
|
|
1823
|
+
];
|
|
1824
|
+
async function loadMeetingActivities(api, meetingId, roomToken = null) {
|
|
1825
|
+
let response;
|
|
1826
|
+
try {
|
|
1827
|
+
response = await api.request({
|
|
1828
|
+
path: `${MEET_ROUTES.collab}?meeting_id=${encodeURIComponent(meetingId)}`,
|
|
1829
|
+
method: "GET",
|
|
1830
|
+
operation: "meet.loadMeetingActivities",
|
|
1831
|
+
requireAuth: roomToken === null,
|
|
1832
|
+
...roomToken !== null ? { headers: { [ROOM_TOKEN_HEADER]: roomToken } } : {}
|
|
1833
|
+
});
|
|
1834
|
+
} catch (error) {
|
|
1835
|
+
return {
|
|
1836
|
+
collab: null,
|
|
1837
|
+
refusal: {
|
|
1838
|
+
message: `Polls, questions and the whiteboard could not be read (${error.message}).`,
|
|
1839
|
+
remedy: error.remedy ?? "Reload the page."
|
|
1840
|
+
}
|
|
1841
|
+
};
|
|
1842
|
+
}
|
|
1843
|
+
if (!response.ok) {
|
|
1844
|
+
let body = null;
|
|
1845
|
+
try {
|
|
1846
|
+
body = await response.json();
|
|
1847
|
+
} catch {
|
|
1848
|
+
body = null;
|
|
1849
|
+
}
|
|
1850
|
+
const said = readServerRefusal(body);
|
|
1851
|
+
return {
|
|
1852
|
+
collab: null,
|
|
1853
|
+
refusal: {
|
|
1854
|
+
message: said?.reason ?? `Polls and questions could not be read (the server answered ${response.status}).`,
|
|
1855
|
+
remedy: said?.remedy || "Reload the page."
|
|
1856
|
+
}
|
|
1857
|
+
};
|
|
1858
|
+
}
|
|
1859
|
+
return { collab: collabFromState(await response.json(), EMPTY_COLLAB), refusal: null };
|
|
1860
|
+
}
|
|
1861
|
+
|
|
1518
1862
|
// src/core/transcript.ts
|
|
1519
1863
|
function normalizeSpoken(text3) {
|
|
1520
1864
|
return text3.toLowerCase().replace(/[^\p{L}\p{N}]+/gu, " ").trim();
|
|
@@ -1616,7 +1960,9 @@ var EMPTY = {
|
|
|
1616
1960
|
wrapUp: null,
|
|
1617
1961
|
noteTakerRefusal: null,
|
|
1618
1962
|
media: IDLE_MEDIA,
|
|
1619
|
-
failure: null
|
|
1963
|
+
failure: null,
|
|
1964
|
+
collab: EMPTY_COLLAB,
|
|
1965
|
+
breakoutRoomId: null
|
|
1620
1966
|
};
|
|
1621
1967
|
function effectiveRole(snapshot) {
|
|
1622
1968
|
const me = snapshot.participants.find(
|
|
@@ -2267,7 +2613,19 @@ var INVITEE_COLUMNS = "id,meeting_id,invitee_user_id,email,display_name,role,rsv
|
|
|
2267
2613
|
var RECORDING_COLUMNS = "id,meeting_id,state,started_at,ended_at,started_by,file_id,failure_reason";
|
|
2268
2614
|
var SEGMENT_COLUMNS = "id,meeting_id,identity,speaker,text,started_at,is_final,metadata";
|
|
2269
2615
|
var NOTE_COLUMNS = "id,meeting_id,text,kind,assignee_user_id,created_at,metadata";
|
|
2270
|
-
var ATTENDEE_COLUMNS = "id,meeting_id,identity,participant_user_id,display_name,avatar_url,role,admission_state,is_agent,joined_at,left_at";
|
|
2616
|
+
var ATTENDEE_COLUMNS = "id,meeting_id,identity,participant_user_id,display_name,avatar_url,role,admission_state,is_agent,joined_at,left_at,sessions:metadata->sessions";
|
|
2617
|
+
function projectStays(value) {
|
|
2618
|
+
if (!Array.isArray(value)) return [];
|
|
2619
|
+
const stays = [];
|
|
2620
|
+
for (const item of value) {
|
|
2621
|
+
if (item === null || typeof item !== "object") continue;
|
|
2622
|
+
const joined = item["joined_at"];
|
|
2623
|
+
const left = item["left_at"];
|
|
2624
|
+
if (typeof joined !== "string" || joined.length === 0) continue;
|
|
2625
|
+
stays.push({ joinedAt: joined, leftAt: typeof left === "string" && left.length > 0 ? left : null });
|
|
2626
|
+
}
|
|
2627
|
+
return stays;
|
|
2628
|
+
}
|
|
2271
2629
|
function text(row, key) {
|
|
2272
2630
|
const value = row[key];
|
|
2273
2631
|
return typeof value === "string" && value.length > 0 ? value : null;
|
|
@@ -2366,7 +2724,7 @@ var OCCURRENCE_STATES = ["scheduled", "moved", "cancelled"];
|
|
|
2366
2724
|
function rsvpState(value) {
|
|
2367
2725
|
return RSVP_STATES.includes(value) ? value : "needs_action";
|
|
2368
2726
|
}
|
|
2369
|
-
function
|
|
2727
|
+
function num2(row, key) {
|
|
2370
2728
|
const value = row[key];
|
|
2371
2729
|
return typeof value === "number" ? value : null;
|
|
2372
2730
|
}
|
|
@@ -2388,7 +2746,7 @@ function projectInvitee(row) {
|
|
|
2388
2746
|
rsvpState: rsvpState(text(row, "rsvp_state")),
|
|
2389
2747
|
respondedAt: when(row, "responded_at"),
|
|
2390
2748
|
rsvpNote: text(row, "rsvp_note"),
|
|
2391
|
-
lastSentSequence:
|
|
2749
|
+
lastSentSequence: num2(row, "last_sent_sequence"),
|
|
2392
2750
|
lastSentAt: when(row, "last_sent_at")
|
|
2393
2751
|
};
|
|
2394
2752
|
}
|
|
@@ -2399,10 +2757,10 @@ function projectOccurrence(row) {
|
|
|
2399
2757
|
meetingId: asMeetingId(requireText(row, "meeting_id", operation)),
|
|
2400
2758
|
originalStart: when(row, "original_start") ?? requireText(row, "original_start", operation),
|
|
2401
2759
|
occurrenceStart: when(row, "occurrence_start") ?? requireText(row, "occurrence_start", operation),
|
|
2402
|
-
durationMinutes:
|
|
2760
|
+
durationMinutes: num2(row, "duration_minutes"),
|
|
2403
2761
|
// An unknown state is shown as scheduled, never dropped: the row is real.
|
|
2404
2762
|
state: OCCURRENCE_STATES.includes(state) ? state : "scheduled",
|
|
2405
|
-
sequence:
|
|
2763
|
+
sequence: num2(row, "sequence") ?? 0
|
|
2406
2764
|
};
|
|
2407
2765
|
}
|
|
2408
2766
|
function projectUpcoming(row) {
|
|
@@ -2431,9 +2789,9 @@ function projectOverride(row) {
|
|
|
2431
2789
|
originalStart: when(row, "original_start") ?? requireText(row, "original_start", operation),
|
|
2432
2790
|
state: text(row, "state") === "moved" ? "moved" : "cancelled",
|
|
2433
2791
|
newStart: when(row, "new_start"),
|
|
2434
|
-
newDurationMinutes:
|
|
2792
|
+
newDurationMinutes: num2(row, "new_duration_minutes"),
|
|
2435
2793
|
reason: text(row, "reason"),
|
|
2436
|
-
calendarSequence:
|
|
2794
|
+
calendarSequence: num2(row, "calendar_sequence") ?? 0,
|
|
2437
2795
|
deletedAt: when(row, "deleted_at")
|
|
2438
2796
|
};
|
|
2439
2797
|
}
|
|
@@ -2457,7 +2815,7 @@ function projectRsvpInvitation(body) {
|
|
|
2457
2815
|
title: text(meeting, "title") ?? "Meeting",
|
|
2458
2816
|
slug: requireText(meeting, "slug", operation),
|
|
2459
2817
|
scheduledFor: when(meeting, "scheduled_for"),
|
|
2460
|
-
durationMinutes:
|
|
2818
|
+
durationMinutes: num2(meeting, "duration_minutes"),
|
|
2461
2819
|
timeZone: text(meeting, "time_zone") ?? "UTC",
|
|
2462
2820
|
agenda: text(meeting, "agenda"),
|
|
2463
2821
|
recurrenceRule: text(meeting, "recurrence_rule"),
|
|
@@ -2491,6 +2849,7 @@ function changesPatch(changes) {
|
|
|
2491
2849
|
patch["scheduled_duration_minutes"] = changes.scheduledDurationMinutes;
|
|
2492
2850
|
}
|
|
2493
2851
|
if (changes.recurrenceRule !== void 0) patch["recurrence_rule"] = changes.recurrenceRule;
|
|
2852
|
+
if (changes.keepExceptions !== void 0) patch["keep_exceptions"] = changes.keepExceptions;
|
|
2494
2853
|
return patch;
|
|
2495
2854
|
}
|
|
2496
2855
|
function createMeetRepository(options) {
|
|
@@ -2637,7 +2996,8 @@ function createMeetRepository(options) {
|
|
|
2637
2996
|
admissionState: states.includes(admission) ? admission : "admitted",
|
|
2638
2997
|
isAgent: bool(row, "is_agent", false),
|
|
2639
2998
|
joinedAt: text(row, "joined_at"),
|
|
2640
|
-
leftAt: text(row, "left_at")
|
|
2999
|
+
leftAt: text(row, "left_at"),
|
|
3000
|
+
sessions: projectStays(row["sessions"])
|
|
2641
3001
|
};
|
|
2642
3002
|
}
|
|
2643
3003
|
function requireOrg(organizationId, operation) {
|
|
@@ -3031,8 +3391,8 @@ function projectLibraryRecording(row) {
|
|
|
3031
3391
|
fileId: text(row, "file_id"),
|
|
3032
3392
|
startedAt: text(row, "started_at"),
|
|
3033
3393
|
endedAt: text(row, "ended_at"),
|
|
3034
|
-
durationMs:
|
|
3035
|
-
sizeBytes:
|
|
3394
|
+
durationMs: num2(row, "duration_ms"),
|
|
3395
|
+
sizeBytes: num2(row, "size_bytes"),
|
|
3036
3396
|
failureReason: text(row, "failure_reason"),
|
|
3037
3397
|
archivedAt: text(row, "deleted_at"),
|
|
3038
3398
|
organizationId: asOrganizationId(requireText(row, "organization_id", operation))
|
|
@@ -3059,7 +3419,7 @@ function projectSearchHit(row) {
|
|
|
3059
3419
|
speaker: text(row, "speaker"),
|
|
3060
3420
|
snippet: text(row, "snippet") ?? "",
|
|
3061
3421
|
at: text(row, "said_at"),
|
|
3062
|
-
rank:
|
|
3422
|
+
rank: num2(row, "rank") ?? 0
|
|
3063
3423
|
};
|
|
3064
3424
|
}
|
|
3065
3425
|
function snippetRuns(snippet) {
|
|
@@ -3204,7 +3564,14 @@ var ROOM_EVENTS = {
|
|
|
3204
3564
|
* person concerned; `lower-hands {identities: [...] | "*"}` · `role {identity,
|
|
3205
3565
|
* role}` — to everyone.
|
|
3206
3566
|
*/
|
|
3207
|
-
moderation: "matrx.meet.moderation"
|
|
3567
|
+
moderation: "matrx.meet.moderation",
|
|
3568
|
+
/**
|
|
3569
|
+
* A meeting ROOM ITEM changed (Meet wave 5): a poll, a Q&A question, a whiteboard
|
|
3570
|
+
* stroke or the breakout plan. Payload `{ meeting_id, item }` · `{ removed: [ids] }` ·
|
|
3571
|
+
* `{ hidden: [ids] }` · `{ cleared: "whiteboard" }` · `{ broadcast }` · `{ item, move }`.
|
|
3572
|
+
* A host's fuller copy of a poll or question carries `audience: "hosts"`.
|
|
3573
|
+
*/
|
|
3574
|
+
collab: "matrx.meet.collab"
|
|
3208
3575
|
};
|
|
3209
3576
|
function isRoomEventTopic(topic) {
|
|
3210
3577
|
return topic.startsWith(ROOM_EVENT_PREFIX);
|
|
@@ -3244,10 +3611,27 @@ function applyRoomEvent(args) {
|
|
|
3244
3611
|
return applyChat(store, payload);
|
|
3245
3612
|
case ROOM_EVENTS.moderation:
|
|
3246
3613
|
return applyModeration(store, payload, now);
|
|
3614
|
+
case ROOM_EVENTS.collab:
|
|
3615
|
+
return applyCollab(store, payload, now);
|
|
3247
3616
|
default:
|
|
3248
3617
|
return ignored(`${topic} is not known to this version of @ai-matrx/meet`);
|
|
3249
3618
|
}
|
|
3250
3619
|
}
|
|
3620
|
+
function applyCollab(store, payload, now) {
|
|
3621
|
+
const snapshot = store.snapshot();
|
|
3622
|
+
const meeting = snapshot.meeting;
|
|
3623
|
+
if (meeting !== null && text2(payload["meeting_id"]) !== null && payload["meeting_id"] !== meeting.id) {
|
|
3624
|
+
return ignored("a collab event for a different meeting than this room is showing");
|
|
3625
|
+
}
|
|
3626
|
+
const result = applyCollabPacket(snapshot.collab, payload, {
|
|
3627
|
+
localIdentity: snapshot.localIdentity,
|
|
3628
|
+
isHost: ROLE_RANK[effectiveRole(snapshot)] >= ROLE_RANK.cohost,
|
|
3629
|
+
now: now()
|
|
3630
|
+
});
|
|
3631
|
+
if (result.next === null) return ignored(result.dropped ?? "a collab packet that changed nothing");
|
|
3632
|
+
store.patch({ collab: result.next });
|
|
3633
|
+
return HANDLED;
|
|
3634
|
+
}
|
|
3251
3635
|
function applyNote(store, payload) {
|
|
3252
3636
|
const row = object(payload["note"]);
|
|
3253
3637
|
if (row === null) return ignored("a note event with no `note` row");
|
|
@@ -3569,6 +3953,7 @@ function createRoomEngine(options) {
|
|
|
3569
3953
|
let joining = null;
|
|
3570
3954
|
let lastRequest = null;
|
|
3571
3955
|
let disposed = false;
|
|
3956
|
+
let moving = false;
|
|
3572
3957
|
const confirmingEnds = /* @__PURE__ */ new WeakSet();
|
|
3573
3958
|
async function leaveRoom() {
|
|
3574
3959
|
const target = driver;
|
|
@@ -3798,6 +4183,7 @@ function createRoomEngine(options) {
|
|
|
3798
4183
|
}
|
|
3799
4184
|
},
|
|
3800
4185
|
disconnected(reason) {
|
|
4186
|
+
if (moving) return;
|
|
3801
4187
|
if (current !== null) {
|
|
3802
4188
|
tokens.invalidate(current.roomName);
|
|
3803
4189
|
current = null;
|
|
@@ -3812,11 +4198,13 @@ function createRoomEngine(options) {
|
|
|
3812
4198
|
roomName: request.roomName,
|
|
3813
4199
|
identity,
|
|
3814
4200
|
...request.meetingId !== void 0 ? { meetingId: request.meetingId } : {},
|
|
3815
|
-
...request.slug !== void 0 ? { slug: request.slug } : {}
|
|
4201
|
+
...request.slug !== void 0 ? { slug: request.slug } : {},
|
|
4202
|
+
...request.breakoutRoomId != null ? { breakoutRoomId: request.breakoutRoomId } : {}
|
|
3816
4203
|
});
|
|
3817
4204
|
current = token;
|
|
3818
4205
|
store.patch({
|
|
3819
4206
|
localIdentity: token.identity,
|
|
4207
|
+
breakoutRoomId: token.breakoutRoomId ?? null,
|
|
3820
4208
|
grants: {
|
|
3821
4209
|
role: token.role,
|
|
3822
4210
|
canRecord: token.canRecord,
|
|
@@ -3935,6 +4323,56 @@ function createRoomEngine(options) {
|
|
|
3935
4323
|
});
|
|
3936
4324
|
return joining;
|
|
3937
4325
|
},
|
|
4326
|
+
async moveToBreakout(roomId) {
|
|
4327
|
+
const request = lastRequest;
|
|
4328
|
+
if (request === null || driver === null) {
|
|
4329
|
+
report(
|
|
4330
|
+
"warn",
|
|
4331
|
+
"meet.moveToBreakout: this engine is not in a meeting room",
|
|
4332
|
+
"Join the meeting first; a breakout is a room OF a meeting."
|
|
4333
|
+
);
|
|
4334
|
+
return;
|
|
4335
|
+
}
|
|
4336
|
+
if ((store.snapshot().breakoutRoomId ?? null) === roomId) return;
|
|
4337
|
+
if (joining !== null) await joining.catch(() => void 0);
|
|
4338
|
+
const previous = driver;
|
|
4339
|
+
const next = {
|
|
4340
|
+
...request,
|
|
4341
|
+
breakoutRoomId: roomId,
|
|
4342
|
+
// Arrive as you were: camera and microphone as they are now.
|
|
4343
|
+
mode: store.snapshot().media.camera.enabled ? "video" : "audio",
|
|
4344
|
+
microphone: store.snapshot().media.microphone.enabled
|
|
4345
|
+
};
|
|
4346
|
+
moving = true;
|
|
4347
|
+
try {
|
|
4348
|
+
driver = null;
|
|
4349
|
+
tokens.invalidate(request.roomName);
|
|
4350
|
+
current = null;
|
|
4351
|
+
await previous.disconnect();
|
|
4352
|
+
lastRequest = next;
|
|
4353
|
+
joining = connect(next).finally(() => {
|
|
4354
|
+
joining = null;
|
|
4355
|
+
});
|
|
4356
|
+
await joining;
|
|
4357
|
+
} catch (error) {
|
|
4358
|
+
const normalized = normalizeMeetError(error, "meet.moveToBreakout");
|
|
4359
|
+
report("warn", normalized.message, normalized.remedy);
|
|
4360
|
+
if (roomId !== null) {
|
|
4361
|
+
lastRequest = { ...next, breakoutRoomId: null };
|
|
4362
|
+
joining = connect(lastRequest).finally(() => {
|
|
4363
|
+
joining = null;
|
|
4364
|
+
});
|
|
4365
|
+
await joining.catch((again) => {
|
|
4366
|
+
throw fail(again, "meet.moveToBreakout");
|
|
4367
|
+
});
|
|
4368
|
+
} else {
|
|
4369
|
+
throw fail(error, "meet.moveToBreakout");
|
|
4370
|
+
}
|
|
4371
|
+
throw normalized;
|
|
4372
|
+
} finally {
|
|
4373
|
+
moving = false;
|
|
4374
|
+
}
|
|
4375
|
+
},
|
|
3938
4376
|
leave: leaveRoom,
|
|
3939
4377
|
// Turning a device on mid-meeting is the SAME operation as turning it on
|
|
3940
4378
|
// during the join, so it runs the same function. A failure here used to
|
|
@@ -4204,6 +4642,109 @@ function createInRoomClient(options) {
|
|
|
4204
4642
|
(row) => typeof row === "object" && row !== null ? chatFromRow(row) : null
|
|
4205
4643
|
).filter((message) => message !== null);
|
|
4206
4644
|
store.loadChat(messages);
|
|
4645
|
+
},
|
|
4646
|
+
async loadCollab() {
|
|
4647
|
+
const operation = "meet.loadCollab";
|
|
4648
|
+
const id = meetingId(operation);
|
|
4649
|
+
const hdrs = headers();
|
|
4650
|
+
const response = await api.request({
|
|
4651
|
+
path: `${MEET_ROUTES.collab}?meeting_id=${encodeURIComponent(id)}`,
|
|
4652
|
+
method: "GET",
|
|
4653
|
+
operation,
|
|
4654
|
+
...hdrs !== void 0 ? { headers: hdrs } : {}
|
|
4655
|
+
});
|
|
4656
|
+
if (!response.ok) {
|
|
4657
|
+
const error = await refusal2(
|
|
4658
|
+
response,
|
|
4659
|
+
operation,
|
|
4660
|
+
"Polls, questions and the whiteboard could not be read. New ones still arrive."
|
|
4661
|
+
);
|
|
4662
|
+
store.patch({ collab: { ...store.snapshot().collab, loaded: true, error: error.message } });
|
|
4663
|
+
throw error;
|
|
4664
|
+
}
|
|
4665
|
+
const body = await response.json();
|
|
4666
|
+
store.patch({ collab: collabFromState(body, store.snapshot().collab) });
|
|
4667
|
+
},
|
|
4668
|
+
async collab(request) {
|
|
4669
|
+
const operation = `meet.collab(${request.action})`;
|
|
4670
|
+
const hdrs = headers();
|
|
4671
|
+
const response = await api.request({
|
|
4672
|
+
path: MEET_ROUTES.collab,
|
|
4673
|
+
method: "POST",
|
|
4674
|
+
operation,
|
|
4675
|
+
body: {
|
|
4676
|
+
meeting_id: meetingId(operation),
|
|
4677
|
+
action: request.action,
|
|
4678
|
+
...request.itemId !== void 0 ? { item_id: request.itemId } : {},
|
|
4679
|
+
...request.question !== void 0 ? { question: request.question } : {},
|
|
4680
|
+
...request.options !== void 0 ? { options: request.options } : {},
|
|
4681
|
+
...request.multiple !== void 0 ? { multiple: request.multiple } : {},
|
|
4682
|
+
...request.anonymous !== void 0 ? { anonymous: request.anonymous } : {},
|
|
4683
|
+
...request.optionIds !== void 0 ? { option_ids: request.optionIds } : {},
|
|
4684
|
+
...request.text !== void 0 ? { text: request.text } : {},
|
|
4685
|
+
...request.stroke !== void 0 ? { stroke: request.stroke } : {},
|
|
4686
|
+
...request.rooms !== void 0 ? { rooms: request.rooms } : {},
|
|
4687
|
+
...request.allowChoose !== void 0 ? { allow_choose: request.allowChoose } : {},
|
|
4688
|
+
...request.minutes !== void 0 ? { minutes: request.minutes } : {},
|
|
4689
|
+
...request.identity !== void 0 ? { identity: request.identity } : {},
|
|
4690
|
+
...request.roomId !== void 0 ? { room_id: request.roomId } : {}
|
|
4691
|
+
},
|
|
4692
|
+
...hdrs !== void 0 ? { headers: hdrs } : {}
|
|
4693
|
+
});
|
|
4694
|
+
if (!response.ok) {
|
|
4695
|
+
throw await refusal2(response, operation, "Nothing was changed.");
|
|
4696
|
+
}
|
|
4697
|
+
const payload = await response.json();
|
|
4698
|
+
const removed = Array.isArray(payload["removed"]) ? payload["removed"].filter((v) => typeof v === "string") : [];
|
|
4699
|
+
let next = store.snapshot().collab;
|
|
4700
|
+
const item = payload["item"];
|
|
4701
|
+
if (typeof item === "object" && item !== null) next = withItem(next, item);
|
|
4702
|
+
if (removed.length > 0) {
|
|
4703
|
+
const gone = new Set(removed);
|
|
4704
|
+
next = {
|
|
4705
|
+
...next,
|
|
4706
|
+
polls: next.polls.filter((p) => !gone.has(p.id)),
|
|
4707
|
+
questions: next.questions.filter((q) => !gone.has(q.id)),
|
|
4708
|
+
strokes: next.strokes.filter((st) => !gone.has(st.id))
|
|
4709
|
+
};
|
|
4710
|
+
}
|
|
4711
|
+
store.patch({ collab: next });
|
|
4712
|
+
const itemId = typeof item === "object" && item !== null && typeof item["id"] === "string" ? item["id"] : null;
|
|
4713
|
+
return {
|
|
4714
|
+
action: request.action,
|
|
4715
|
+
message: typeof payload["message"] === "string" ? payload["message"] : "Done.",
|
|
4716
|
+
removed,
|
|
4717
|
+
itemId
|
|
4718
|
+
};
|
|
4719
|
+
},
|
|
4720
|
+
async translateCaptions(language, lines) {
|
|
4721
|
+
if (lines.length === 0) return;
|
|
4722
|
+
const operation = "meet.translateCaptions";
|
|
4723
|
+
const hdrs = headers();
|
|
4724
|
+
const response = await api.request({
|
|
4725
|
+
path: MEET_ROUTES.captionsTranslate,
|
|
4726
|
+
method: "POST",
|
|
4727
|
+
operation,
|
|
4728
|
+
body: { meeting_id: meetingId(operation), target_language: language, lines },
|
|
4729
|
+
...hdrs !== void 0 ? { headers: hdrs } : {}
|
|
4730
|
+
});
|
|
4731
|
+
if (!response.ok) {
|
|
4732
|
+
const error = await refusal2(response, operation, "Captions stay in the language they were spoken.");
|
|
4733
|
+
store.patch({
|
|
4734
|
+
collab: { ...store.snapshot().collab, captionTranslationError: error.message }
|
|
4735
|
+
});
|
|
4736
|
+
throw error;
|
|
4737
|
+
}
|
|
4738
|
+
const payload = await response.json();
|
|
4739
|
+
const current = store.snapshot().collab;
|
|
4740
|
+
if (current.captionLanguage !== language) return;
|
|
4741
|
+
const merged = { ...current.captionTranslations };
|
|
4742
|
+
for (const [id, value] of Object.entries(payload.translations ?? {})) {
|
|
4743
|
+
if (typeof value === "string") merged[id] = value;
|
|
4744
|
+
}
|
|
4745
|
+
store.patch({
|
|
4746
|
+
collab: { ...current, captionTranslations: merged, captionTranslationError: null }
|
|
4747
|
+
});
|
|
4207
4748
|
}
|
|
4208
4749
|
};
|
|
4209
4750
|
}
|
|
@@ -4322,6 +4863,15 @@ function createLiveKitDriver(handlers, options = {}) {
|
|
|
4322
4863
|
handlers.participants([local, ...remotes]);
|
|
4323
4864
|
};
|
|
4324
4865
|
projectRoster = roster;
|
|
4866
|
+
created.on(RoomEvent.TrackSubscribed, (track) => {
|
|
4867
|
+
if (track.kind !== Track.Kind.Audio || typeof document === "undefined") return;
|
|
4868
|
+
const element = track.attach();
|
|
4869
|
+
element.setAttribute("data-mx-meet-audio", "");
|
|
4870
|
+
audioSink().appendChild(element);
|
|
4871
|
+
}).on(RoomEvent.TrackUnsubscribed, (track) => {
|
|
4872
|
+
if (track.kind !== Track.Kind.Audio) return;
|
|
4873
|
+
for (const element of track.detach()) element.remove();
|
|
4874
|
+
});
|
|
4325
4875
|
created.on(RoomEvent.ParticipantConnected, roster).on(RoomEvent.ParticipantDisconnected, roster).on(RoomEvent.TrackSubscribed, roster).on(RoomEvent.TrackUnsubscribed, roster).on(RoomEvent.TrackMuted, roster).on(RoomEvent.TrackUnmuted, roster).on(RoomEvent.LocalTrackPublished, roster).on(RoomEvent.LocalTrackUnpublished, roster).on(RoomEvent.ParticipantNameChanged, roster).on(RoomEvent.ParticipantAttributesChanged, roster).on(RoomEvent.ParticipantMetadataChanged, roster).on(RoomEvent.RoomMetadataChanged, (metadata) => {
|
|
4326
4876
|
handlers.roomMetadata?.(metadata ?? "");
|
|
4327
4877
|
}).on(RoomEvent.ActiveSpeakersChanged, (speakers) => {
|
|
@@ -4337,6 +4887,8 @@ function createLiveKitDriver(handlers, options = {}) {
|
|
|
4337
4887
|
participant?.identity ?? null
|
|
4338
4888
|
);
|
|
4339
4889
|
}).on(RoomEvent.Disconnected, (reason) => {
|
|
4890
|
+
audioContainer?.remove();
|
|
4891
|
+
audioContainer = null;
|
|
4340
4892
|
handlers.disconnected(reason === void 0 ? null : String(reason));
|
|
4341
4893
|
});
|
|
4342
4894
|
try {
|
|
@@ -4378,10 +4930,26 @@ function createLiveKitDriver(handlers, options = {}) {
|
|
|
4378
4930
|
microphone: Track.Source.Microphone,
|
|
4379
4931
|
screen: Track.Source.ScreenShare
|
|
4380
4932
|
};
|
|
4933
|
+
trackEvents = {
|
|
4934
|
+
subscribed: RoomEvent.TrackSubscribed,
|
|
4935
|
+
localPublished: RoomEvent.LocalTrackPublished
|
|
4936
|
+
};
|
|
4381
4937
|
room = created;
|
|
4382
4938
|
return created;
|
|
4383
4939
|
}
|
|
4384
4940
|
let sources = null;
|
|
4941
|
+
let trackEvents = null;
|
|
4942
|
+
let audioContainer = null;
|
|
4943
|
+
function audioSink() {
|
|
4944
|
+
if (audioContainer !== null && audioContainer.isConnected) return audioContainer;
|
|
4945
|
+
const container = document.createElement("div");
|
|
4946
|
+
container.setAttribute("data-mx-meet-audio-sink", "");
|
|
4947
|
+
container.setAttribute("aria-hidden", "true");
|
|
4948
|
+
container.style.display = "none";
|
|
4949
|
+
document.body.appendChild(container);
|
|
4950
|
+
audioContainer = container;
|
|
4951
|
+
return container;
|
|
4952
|
+
}
|
|
4385
4953
|
function requireRoom(operation) {
|
|
4386
4954
|
if (room === null) {
|
|
4387
4955
|
throw new MeetError(
|
|
@@ -4412,6 +4980,8 @@ function createLiveKitDriver(handlers, options = {}) {
|
|
|
4412
4980
|
} catch {
|
|
4413
4981
|
}
|
|
4414
4982
|
projectRoster = null;
|
|
4983
|
+
audioContainer?.remove();
|
|
4984
|
+
audioContainer = null;
|
|
4415
4985
|
await target.disconnect();
|
|
4416
4986
|
},
|
|
4417
4987
|
async setMicrophoneEnabled(enabled) {
|
|
@@ -4477,14 +5047,33 @@ function createLiveKitDriver(handlers, options = {}) {
|
|
|
4477
5047
|
attach(identity, kind, element) {
|
|
4478
5048
|
const target = requireRoom("attach");
|
|
4479
5049
|
const source = sources?.[kind];
|
|
4480
|
-
|
|
4481
|
-
|
|
4482
|
-
const
|
|
4483
|
-
|
|
4484
|
-
|
|
4485
|
-
|
|
5050
|
+
if (source === void 0) return () => void 0;
|
|
5051
|
+
let current = null;
|
|
5052
|
+
const sync = () => {
|
|
5053
|
+
const participant = target.localParticipant.identity === identity ? target.localParticipant : target.remoteParticipants.get(identity);
|
|
5054
|
+
const track = participant?.getTrackPublication(source)?.track;
|
|
5055
|
+
if (track === void 0 || track === current) return;
|
|
5056
|
+
current?.detach(element);
|
|
5057
|
+
track.attach(element);
|
|
5058
|
+
current = track;
|
|
5059
|
+
};
|
|
5060
|
+
const onTrack = (...args) => {
|
|
5061
|
+
const who = args[args.length - 1];
|
|
5062
|
+
if (who?.identity === identity) sync();
|
|
5063
|
+
};
|
|
5064
|
+
sync();
|
|
5065
|
+
const events = trackEvents;
|
|
5066
|
+
if (events !== null) {
|
|
5067
|
+
target.on(events.subscribed, onTrack);
|
|
5068
|
+
target.on(events.localPublished, onTrack);
|
|
5069
|
+
}
|
|
4486
5070
|
return () => {
|
|
4487
|
-
|
|
5071
|
+
if (events !== null) {
|
|
5072
|
+
target.off(events.subscribed, onTrack);
|
|
5073
|
+
target.off(events.localPublished, onTrack);
|
|
5074
|
+
}
|
|
5075
|
+
current?.detach(element);
|
|
5076
|
+
current = null;
|
|
4488
5077
|
};
|
|
4489
5078
|
},
|
|
4490
5079
|
activeDevices() {
|
|
@@ -4723,6 +5312,14 @@ function MeetRuntime(props) {
|
|
|
4723
5312
|
}
|
|
4724
5313
|
if (chatReadFor === snapshot.meeting.id) return;
|
|
4725
5314
|
chatReadFor = snapshot.meeting.id;
|
|
5315
|
+
void inRoom.loadCollab().catch((error) => {
|
|
5316
|
+
const normalized = error;
|
|
5317
|
+
report({
|
|
5318
|
+
level: "warn",
|
|
5319
|
+
message: normalized.message ?? "meet: polls, questions and the whiteboard could not be read",
|
|
5320
|
+
...normalized.remedy !== void 0 ? { remedy: normalized.remedy } : {}
|
|
5321
|
+
});
|
|
5322
|
+
});
|
|
4726
5323
|
void inRoom.loadChat().catch((error) => {
|
|
4727
5324
|
const normalized = error;
|
|
4728
5325
|
store.patch({
|
|
@@ -6063,7 +6660,7 @@ function useGuestRecordAccess(meeting) {
|
|
|
6063
6660
|
}
|
|
6064
6661
|
|
|
6065
6662
|
// src/react/components.tsx
|
|
6066
|
-
import { useEffect as
|
|
6663
|
+
import { useEffect as useEffect4, useLayoutEffect, useMemo as useMemo3, useRef as useRef4, useState as useState4 } from "react";
|
|
6067
6664
|
import { ErrorBox } from "@ai-matrx/design-system";
|
|
6068
6665
|
import { avatarPaletteIndex, formatDurationMs as formatDurationMs3, getInitials } from "@ai-matrx/kit/format";
|
|
6069
6666
|
|
|
@@ -6074,6 +6671,7 @@ function kindOf(person) {
|
|
|
6074
6671
|
if (person.role === "host") return "host";
|
|
6075
6672
|
if (person.role === "cohost") return "cohost";
|
|
6076
6673
|
if (person.role === "guest") return person.userId !== null ? "signed-in guest" : "guest";
|
|
6674
|
+
if (person.userId === null) return "guest";
|
|
6077
6675
|
return "member";
|
|
6078
6676
|
}
|
|
6079
6677
|
function ms(iso) {
|
|
@@ -6129,12 +6727,19 @@ function coveredMs(intervals) {
|
|
|
6129
6727
|
}
|
|
6130
6728
|
function attendanceReport(meeting, attendees, names = {}) {
|
|
6131
6729
|
const end = ms(meeting.endedAt);
|
|
6730
|
+
const measuredOf = /* @__PURE__ */ new Map();
|
|
6132
6731
|
const perJoin = attendees.map((person) => {
|
|
6133
|
-
const
|
|
6134
|
-
|
|
6135
|
-
const
|
|
6136
|
-
const
|
|
6137
|
-
|
|
6732
|
+
const stays = person.sessions !== void 0 && person.sessions.length > 0 ? person.sessions.map((stay) => [ms(stay.joinedAt), ms(stay.leftAt)]) : [[ms(person.joinedAt), ms(person.leftAt)]];
|
|
6733
|
+
let toEnd = false;
|
|
6734
|
+
const measured = [];
|
|
6735
|
+
for (const [joined, left] of stays) {
|
|
6736
|
+
const until = left ?? end;
|
|
6737
|
+
if (joined === null || until === null || until < joined) continue;
|
|
6738
|
+
if (left === null) toEnd = true;
|
|
6739
|
+
measured.push([joined, until]);
|
|
6740
|
+
}
|
|
6741
|
+
const duration = measured.length === 0 ? null : coveredMs(measured);
|
|
6742
|
+
const row = {
|
|
6138
6743
|
id: person.id,
|
|
6139
6744
|
identity: person.identity,
|
|
6140
6745
|
name: displayNameFor(names, person.identity, person.displayName),
|
|
@@ -6143,10 +6748,12 @@ function attendanceReport(meeting, attendees, names = {}) {
|
|
|
6143
6748
|
joinedAt: person.joinedAt,
|
|
6144
6749
|
leftAt: person.leftAt,
|
|
6145
6750
|
durationMs: duration,
|
|
6146
|
-
durationToEnd: duration !== null &&
|
|
6751
|
+
durationToEnd: duration !== null && toEnd,
|
|
6147
6752
|
admission: person.admissionState,
|
|
6148
|
-
joins: 1
|
|
6753
|
+
joins: Math.max(1, person.sessions?.length ?? 0)
|
|
6149
6754
|
};
|
|
6755
|
+
measuredOf.set(row, measured);
|
|
6756
|
+
return row;
|
|
6150
6757
|
});
|
|
6151
6758
|
const groups = /* @__PURE__ */ new Map();
|
|
6152
6759
|
attendees.forEach((person, index) => {
|
|
@@ -6169,17 +6776,14 @@ function attendanceReport(meeting, attendees, names = {}) {
|
|
|
6169
6776
|
const left = ms(row.leftAt);
|
|
6170
6777
|
return left !== null && (latest === null || left > latest) ? left : latest;
|
|
6171
6778
|
}, null);
|
|
6172
|
-
const intervals = came.flatMap((row) =>
|
|
6173
|
-
const joined = ms(row.joinedAt);
|
|
6174
|
-
return joined !== null && row.durationMs !== null ? [[joined, joined + row.durationMs]] : [];
|
|
6175
|
-
});
|
|
6779
|
+
const intervals = came.flatMap((row) => measuredOf.get(row) ?? []);
|
|
6176
6780
|
return {
|
|
6177
6781
|
...first,
|
|
6178
6782
|
kind,
|
|
6179
6783
|
leftAt: open ? null : lastLeave === null ? null : new Date(lastLeave).toISOString(),
|
|
6180
6784
|
durationMs: intervals.length === 0 ? null : coveredMs(intervals),
|
|
6181
6785
|
durationToEnd: came.some((row) => row.durationToEnd),
|
|
6182
|
-
joins: came.length === 0 ? joins.length : came.
|
|
6786
|
+
joins: came.length === 0 ? joins.length : came.reduce((total, row) => total + row.joins, 0)
|
|
6183
6787
|
};
|
|
6184
6788
|
});
|
|
6185
6789
|
const rank = KIND_RANK;
|
|
@@ -6323,8 +6927,8 @@ function transcriptDocument(bundle, format, options = {}) {
|
|
|
6323
6927
|
if (line.identity !== last) {
|
|
6324
6928
|
if (last !== null) out.push("");
|
|
6325
6929
|
const who = speaker(line);
|
|
6326
|
-
const
|
|
6327
|
-
out.push(format === "md" ? `**${who}** \xB7 ${
|
|
6930
|
+
const clock2 = clockOfDay(line.startedAt, options);
|
|
6931
|
+
out.push(format === "md" ? `**${who}** \xB7 ${clock2}` : `${who} (${clock2})`);
|
|
6328
6932
|
last = line.identity;
|
|
6329
6933
|
}
|
|
6330
6934
|
out.push(line.text.trim());
|
|
@@ -6505,6 +7109,9 @@ function countLabel(count2, singular, plural = `${singular}s`) {
|
|
|
6505
7109
|
return `${count2} ${count2 === 1 ? singular : plural}`;
|
|
6506
7110
|
}
|
|
6507
7111
|
|
|
7112
|
+
// src/react/collab.tsx
|
|
7113
|
+
import { useEffect as useEffect3, useRef as useRef3, useState as useState3 } from "react";
|
|
7114
|
+
|
|
6508
7115
|
// src/react/icons.tsx
|
|
6509
7116
|
import { jsx as jsx2, jsxs } from "react/jsx-runtime";
|
|
6510
7117
|
function Icon({ children, ...props }) {
|
|
@@ -6689,60 +7296,1089 @@ function FlagIcon(props) {
|
|
|
6689
7296
|
function PencilIcon(props) {
|
|
6690
7297
|
return /* @__PURE__ */ jsx2(Icon, { ...props, children: /* @__PURE__ */ jsx2("path", { d: "M17 3a2.85 2.83 0 1 1 4 4L7.5 20.5 2 22l1.5-5.5Z" }) });
|
|
6691
7298
|
}
|
|
6692
|
-
|
|
6693
|
-
|
|
6694
|
-
|
|
6695
|
-
|
|
6696
|
-
|
|
6697
|
-
/* @__PURE__ */ jsxs2("p", { className: "mx-meet__empty-title", children: [
|
|
6698
|
-
what,
|
|
6699
|
-
" is not ready yet"
|
|
6700
|
-
] }),
|
|
6701
|
-
/* @__PURE__ */ jsx3("p", { className: "mx-meet__empty-body", children: "Calls and meetings need a signed-in identity and an active organization. This will appear as soon as they resolve." })
|
|
7299
|
+
function ActivitiesIcon(props) {
|
|
7300
|
+
return /* @__PURE__ */ jsxs(Icon, { ...props, children: [
|
|
7301
|
+
/* @__PURE__ */ jsx2("path", { d: "M8.3 10a.7.7 0 0 1-.626-1.079L11.4 3a.7.7 0 0 1 1.198-.043L16.3 8.9a.7.7 0 0 1-.572 1.1Z" }),
|
|
7302
|
+
/* @__PURE__ */ jsx2("rect", { x: "3", y: "14", width: "7", height: "7", rx: "1" }),
|
|
7303
|
+
/* @__PURE__ */ jsx2("circle", { cx: "17.5", cy: "17.5", r: "3.5" })
|
|
6702
7304
|
] });
|
|
6703
7305
|
}
|
|
6704
|
-
function
|
|
6705
|
-
|
|
6706
|
-
|
|
6707
|
-
|
|
6708
|
-
})
|
|
6709
|
-
|
|
6710
|
-
|
|
6711
|
-
|
|
6712
|
-
|
|
6713
|
-
|
|
6714
|
-
|
|
6715
|
-
|
|
6716
|
-
|
|
6717
|
-
|
|
6718
|
-
|
|
6719
|
-
|
|
7306
|
+
function PollIcon(props) {
|
|
7307
|
+
return /* @__PURE__ */ jsxs(Icon, { ...props, children: [
|
|
7308
|
+
/* @__PURE__ */ jsx2("line", { x1: "18", x2: "18", y1: "20", y2: "10" }),
|
|
7309
|
+
/* @__PURE__ */ jsx2("line", { x1: "12", x2: "12", y1: "20", y2: "4" }),
|
|
7310
|
+
/* @__PURE__ */ jsx2("line", { x1: "6", x2: "6", y1: "20", y2: "14" })
|
|
7311
|
+
] });
|
|
7312
|
+
}
|
|
7313
|
+
function QuestionIcon(props) {
|
|
7314
|
+
return /* @__PURE__ */ jsxs(Icon, { ...props, children: [
|
|
7315
|
+
/* @__PURE__ */ jsx2("path", { d: "M7.9 20A9 9 0 1 0 4 16.1L2 22Z" }),
|
|
7316
|
+
/* @__PURE__ */ jsx2("path", { d: "M9.09 9a3 3 0 0 1 5.83 1c0 2-3 3-3 3" }),
|
|
7317
|
+
/* @__PURE__ */ jsx2("path", { d: "M12 17h.01" })
|
|
7318
|
+
] });
|
|
7319
|
+
}
|
|
7320
|
+
function WhiteboardIcon(props) {
|
|
7321
|
+
return /* @__PURE__ */ jsxs(Icon, { ...props, children: [
|
|
7322
|
+
/* @__PURE__ */ jsx2("path", { d: "M2 3h20" }),
|
|
7323
|
+
/* @__PURE__ */ jsx2("path", { d: "M21 3v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V3" }),
|
|
7324
|
+
/* @__PURE__ */ jsx2("path", { d: "m7 21 5-5 5 5" })
|
|
7325
|
+
] });
|
|
7326
|
+
}
|
|
7327
|
+
function BreakoutIcon(props) {
|
|
7328
|
+
return /* @__PURE__ */ jsxs(Icon, { ...props, children: [
|
|
7329
|
+
/* @__PURE__ */ jsx2("rect", { width: "7", height: "18", x: "3", y: "3", rx: "1" }),
|
|
7330
|
+
/* @__PURE__ */ jsx2("rect", { width: "7", height: "7", x: "14", y: "3", rx: "1" }),
|
|
7331
|
+
/* @__PURE__ */ jsx2("rect", { width: "7", height: "7", x: "14", y: "14", rx: "1" })
|
|
7332
|
+
] });
|
|
7333
|
+
}
|
|
7334
|
+
function UpvoteIcon(props) {
|
|
7335
|
+
return /* @__PURE__ */ jsx2(Icon, { ...props, children: /* @__PURE__ */ jsx2("path", { d: "M9 18v-6H5l7-7 7 7h-4v6H9z" }) });
|
|
7336
|
+
}
|
|
7337
|
+
function EraserIcon(props) {
|
|
7338
|
+
return /* @__PURE__ */ jsxs(Icon, { ...props, children: [
|
|
7339
|
+
/* @__PURE__ */ jsx2("path", { d: "m7 21-4.3-4.3c-1-1-1-2.5 0-3.4l9.6-9.6c1-1 2.5-1 3.4 0l5.6 5.6c1 1 1 2.5 0 3.4L13 21" }),
|
|
7340
|
+
/* @__PURE__ */ jsx2("path", { d: "M22 21H7" }),
|
|
7341
|
+
/* @__PURE__ */ jsx2("path", { d: "m5 11 9 9" })
|
|
7342
|
+
] });
|
|
7343
|
+
}
|
|
7344
|
+
function HighlighterIcon(props) {
|
|
7345
|
+
return /* @__PURE__ */ jsxs(Icon, { ...props, children: [
|
|
7346
|
+
/* @__PURE__ */ jsx2("path", { d: "m9 11-6 6v3h9l3-3" }),
|
|
7347
|
+
/* @__PURE__ */ jsx2("path", { d: "m22 12-4.6 4.6a2 2 0 0 1-2.8 0l-5.2-5.2a2 2 0 0 1 0-2.8L14 4" })
|
|
7348
|
+
] });
|
|
7349
|
+
}
|
|
7350
|
+
function UndoIcon(props) {
|
|
7351
|
+
return /* @__PURE__ */ jsxs(Icon, { ...props, children: [
|
|
7352
|
+
/* @__PURE__ */ jsx2("path", { d: "M9 14 4 9l5-5" }),
|
|
7353
|
+
/* @__PURE__ */ jsx2("path", { d: "M4 9h10.5a5.5 5.5 0 0 1 5.5 5.5a5.5 5.5 0 0 1-5.5 5.5H11" })
|
|
7354
|
+
] });
|
|
7355
|
+
}
|
|
7356
|
+
|
|
7357
|
+
// src/react/collab.tsx
|
|
7358
|
+
import { jsx as jsx3, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
7359
|
+
function useCollab() {
|
|
7360
|
+
const host = useMeetHost();
|
|
7361
|
+
const snapshot = useMeetSnapshot();
|
|
7362
|
+
const isHost = useIsHost();
|
|
7363
|
+
return {
|
|
7364
|
+
collab: snapshot?.collab ?? null,
|
|
7365
|
+
isHost,
|
|
7366
|
+
localIdentity: snapshot?.localIdentity ?? null,
|
|
7367
|
+
breakoutRoomId: snapshot?.breakoutRoomId ?? null,
|
|
7368
|
+
async act(request) {
|
|
7369
|
+
if (host === null) return { ok: false, message: "This meeting is not connected." };
|
|
7370
|
+
try {
|
|
7371
|
+
const result = await host.inRoom.collab(request);
|
|
7372
|
+
return { ok: true, message: result.message, itemId: result.itemId };
|
|
7373
|
+
} catch (error) {
|
|
7374
|
+
return { ok: false, message: error.message ?? "That did not work." };
|
|
7375
|
+
}
|
|
7376
|
+
},
|
|
7377
|
+
async moveTo(roomId) {
|
|
7378
|
+
if (host === null) return { ok: false, message: "This meeting is not connected." };
|
|
7379
|
+
try {
|
|
7380
|
+
await host.engine.moveToBreakout(roomId);
|
|
7381
|
+
return { ok: true, message: roomId === null ? "Back in the main room." : "Joined the breakout room." };
|
|
7382
|
+
} catch (error) {
|
|
7383
|
+
return { ok: false, message: error.message ?? "That room could not be joined." };
|
|
6720
7384
|
}
|
|
6721
|
-
);
|
|
6722
|
-
}
|
|
6723
|
-
return /* @__PURE__ */ jsx3(
|
|
6724
|
-
"span",
|
|
6725
|
-
{
|
|
6726
|
-
className: "mx-meet__avatar mx-meet__avatar--initials",
|
|
6727
|
-
style: {
|
|
6728
|
-
width: size,
|
|
6729
|
-
height: size,
|
|
6730
|
-
fontSize: Math.round(size * 0.38),
|
|
6731
|
-
background: `var(--mx-meet-avatar-${tint})`
|
|
6732
|
-
},
|
|
6733
|
-
"aria-hidden": "true",
|
|
6734
|
-
children: getInitials(name)
|
|
6735
7385
|
}
|
|
6736
|
-
|
|
7386
|
+
};
|
|
6737
7387
|
}
|
|
6738
|
-
function
|
|
6739
|
-
|
|
6740
|
-
|
|
6741
|
-
|
|
6742
|
-
|
|
6743
|
-
|
|
7388
|
+
function useNotice() {
|
|
7389
|
+
const [notice, setNotice] = useState3(null);
|
|
7390
|
+
useEffect3(() => {
|
|
7391
|
+
if (notice === null) return void 0;
|
|
7392
|
+
const timer = setTimeout(() => setNotice(null), notice.failed ? 7e3 : 3e3);
|
|
7393
|
+
return () => clearTimeout(timer);
|
|
7394
|
+
}, [notice]);
|
|
7395
|
+
return [notice, (result) => setNotice({ text: result.message, failed: !result.ok })];
|
|
7396
|
+
}
|
|
7397
|
+
function Notice({ notice }) {
|
|
7398
|
+
if (notice === null) return null;
|
|
7399
|
+
return /* @__PURE__ */ jsx3("p", { className: notice.failed ? "mx-meet__panel-note mx-meet__collab-error" : "mx-meet__panel-note", role: "status", children: notice.text });
|
|
7400
|
+
}
|
|
7401
|
+
var ACTIVITY_LABELS = {
|
|
7402
|
+
polls: "Polls",
|
|
7403
|
+
qa: "Q&A",
|
|
7404
|
+
whiteboard: "Whiteboard",
|
|
7405
|
+
breakouts: "Breakout rooms"
|
|
7406
|
+
};
|
|
7407
|
+
function ActivityIcon({ panel }) {
|
|
7408
|
+
const props = { width: 16, height: 16 };
|
|
7409
|
+
if (panel === "polls") return /* @__PURE__ */ jsx3(PollIcon, { ...props });
|
|
7410
|
+
if (panel === "qa") return /* @__PURE__ */ jsx3(QuestionIcon, { ...props });
|
|
7411
|
+
if (panel === "whiteboard") return /* @__PURE__ */ jsx3(WhiteboardIcon, { ...props });
|
|
7412
|
+
return /* @__PURE__ */ jsx3(BreakoutIcon, { ...props });
|
|
7413
|
+
}
|
|
7414
|
+
function useAvailableActivities() {
|
|
7415
|
+
const { collab, isHost } = useCollab();
|
|
7416
|
+
const settings = collab?.settings ?? null;
|
|
7417
|
+
if (settings === null) return [];
|
|
7418
|
+
const out = [];
|
|
7419
|
+
if (settings.whiteboardEnabled) out.push("whiteboard");
|
|
7420
|
+
if (settings.pollsEnabled && (isHost || (collab?.polls.length ?? 0) > 0)) out.push("polls");
|
|
7421
|
+
if (settings.qaEnabled) out.push("qa");
|
|
7422
|
+
if (settings.breakoutsEnabled && (isHost || collab?.breakout?.state === "open")) out.push("breakouts");
|
|
7423
|
+
return out;
|
|
7424
|
+
}
|
|
7425
|
+
function useActivityAttention() {
|
|
7426
|
+
const { collab, isHost } = useCollab();
|
|
7427
|
+
if (collab === null) return false;
|
|
7428
|
+
if (collab.polls.some((poll) => poll.state === "live" && poll.myVote.length === 0 && !isHost)) return true;
|
|
7429
|
+
if (isHost && collab.questions.some((q) => q.state === "open")) return true;
|
|
7430
|
+
return false;
|
|
7431
|
+
}
|
|
7432
|
+
function ActivitiesControl({
|
|
7433
|
+
active,
|
|
7434
|
+
onOpen
|
|
6744
7435
|
}) {
|
|
7436
|
+
const [open, setOpen] = useState3(false);
|
|
7437
|
+
const available = useAvailableActivities();
|
|
7438
|
+
const attention = useActivityAttention();
|
|
7439
|
+
if (available.length === 0) return null;
|
|
7440
|
+
return /* @__PURE__ */ jsxs2("span", { className: "mx-meet__anchor", children: [
|
|
7441
|
+
/* @__PURE__ */ jsxs2(ControlButton, { label: "Activities", active: open || active !== null, onClick: () => setOpen(!open), children: [
|
|
7442
|
+
/* @__PURE__ */ jsx3(ActivitiesIcon, {}),
|
|
7443
|
+
attention ? /* @__PURE__ */ jsx3("span", { className: "mx-meet__dot", "aria-hidden": "true" }) : null
|
|
7444
|
+
] }),
|
|
7445
|
+
open ? /* @__PURE__ */ jsx3(Popover, { label: "Activities", onClose: () => setOpen(false), children: /* @__PURE__ */ jsx3("div", { className: "mx-meet__menu", role: "menu", children: available.map((panel) => /* @__PURE__ */ jsxs2(
|
|
7446
|
+
MenuItem,
|
|
7447
|
+
{
|
|
7448
|
+
onSelect: () => {
|
|
7449
|
+
setOpen(false);
|
|
7450
|
+
onOpen(panel);
|
|
7451
|
+
},
|
|
7452
|
+
children: [
|
|
7453
|
+
/* @__PURE__ */ jsx3(ActivityIcon, { panel }),
|
|
7454
|
+
" ",
|
|
7455
|
+
ACTIVITY_LABELS[panel]
|
|
7456
|
+
]
|
|
7457
|
+
},
|
|
7458
|
+
panel
|
|
7459
|
+
)) }) }) : null
|
|
7460
|
+
] });
|
|
7461
|
+
}
|
|
7462
|
+
function PollComposer({ maxOptions, onDone }) {
|
|
7463
|
+
const { act } = useCollab();
|
|
7464
|
+
const [question, setQuestion] = useState3("");
|
|
7465
|
+
const [options, setOptions] = useState3(["", ""]);
|
|
7466
|
+
const [multiple, setMultiple] = useState3(false);
|
|
7467
|
+
const [anonymous, setAnonymous] = useState3(false);
|
|
7468
|
+
const [busy, setBusy] = useState3(false);
|
|
7469
|
+
const [notice, show] = useNotice();
|
|
7470
|
+
const filled = options.map((o) => o.trim()).filter(Boolean);
|
|
7471
|
+
const ready = question.trim().length > 0 && filled.length >= 2;
|
|
7472
|
+
const save = async (launch) => {
|
|
7473
|
+
setBusy(true);
|
|
7474
|
+
const created = await act({ action: "poll_create", question, options: filled, multiple, anonymous });
|
|
7475
|
+
if (!created.ok) {
|
|
7476
|
+
show(created);
|
|
7477
|
+
setBusy(false);
|
|
7478
|
+
return;
|
|
7479
|
+
}
|
|
7480
|
+
if (launch && created.itemId != null) {
|
|
7481
|
+
const launched = await act({ action: "poll_launch", itemId: created.itemId });
|
|
7482
|
+
if (!launched.ok) {
|
|
7483
|
+
show(launched);
|
|
7484
|
+
setBusy(false);
|
|
7485
|
+
return;
|
|
7486
|
+
}
|
|
7487
|
+
}
|
|
7488
|
+
setBusy(false);
|
|
7489
|
+
onDone();
|
|
7490
|
+
};
|
|
7491
|
+
return /* @__PURE__ */ jsxs2(
|
|
7492
|
+
"form",
|
|
7493
|
+
{
|
|
7494
|
+
className: "mx-meet__collab-card",
|
|
7495
|
+
onSubmit: (event) => {
|
|
7496
|
+
event.preventDefault();
|
|
7497
|
+
if (ready) void save(true);
|
|
7498
|
+
},
|
|
7499
|
+
children: [
|
|
7500
|
+
/* @__PURE__ */ jsxs2("label", { className: "mx-meet__field", children: [
|
|
7501
|
+
/* @__PURE__ */ jsx3("span", { className: "mx-meet__field-label", children: "Question" }),
|
|
7502
|
+
/* @__PURE__ */ jsx3(
|
|
7503
|
+
"input",
|
|
7504
|
+
{
|
|
7505
|
+
className: "mx-meet__input",
|
|
7506
|
+
value: question,
|
|
7507
|
+
maxLength: 1e3,
|
|
7508
|
+
onChange: (event) => setQuestion(event.target.value),
|
|
7509
|
+
placeholder: "Ask the room something",
|
|
7510
|
+
autoFocus: true
|
|
7511
|
+
}
|
|
7512
|
+
)
|
|
7513
|
+
] }),
|
|
7514
|
+
options.map((option, index) => /* @__PURE__ */ jsxs2("div", { className: "mx-meet__composer-row", children: [
|
|
7515
|
+
/* @__PURE__ */ jsx3(
|
|
7516
|
+
"input",
|
|
7517
|
+
{
|
|
7518
|
+
className: "mx-meet__input",
|
|
7519
|
+
value: option,
|
|
7520
|
+
maxLength: 200,
|
|
7521
|
+
"aria-label": `Answer ${index + 1}`,
|
|
7522
|
+
placeholder: `Answer ${index + 1}`,
|
|
7523
|
+
onChange: (event) => setOptions(options.map((o, i) => i === index ? event.target.value : o))
|
|
7524
|
+
}
|
|
7525
|
+
),
|
|
7526
|
+
options.length > 2 ? /* @__PURE__ */ jsx3(ControlButton, { label: `Remove answer ${index + 1}`, onClick: () => setOptions(options.filter((_, i) => i !== index)), children: /* @__PURE__ */ jsx3(CloseIcon, { width: 14, height: 14 }) }) : null
|
|
7527
|
+
] }, index)),
|
|
7528
|
+
options.length < maxOptions ? /* @__PURE__ */ jsx3("button", { type: "button", className: "mx-meet__link", onClick: () => setOptions([...options, ""]), children: "Add an answer" }) : null,
|
|
7529
|
+
/* @__PURE__ */ jsxs2("label", { className: "mx-meet__toggle", children: [
|
|
7530
|
+
/* @__PURE__ */ jsx3("input", { type: "checkbox", checked: multiple, onChange: (event) => setMultiple(event.target.checked) }),
|
|
7531
|
+
"People can pick more than one"
|
|
7532
|
+
] }),
|
|
7533
|
+
/* @__PURE__ */ jsxs2("label", { className: "mx-meet__toggle", children: [
|
|
7534
|
+
/* @__PURE__ */ jsx3("input", { type: "checkbox", checked: anonymous, onChange: (event) => setAnonymous(event.target.checked) }),
|
|
7535
|
+
"Anonymous \u2014 nobody sees who picked what"
|
|
7536
|
+
] }),
|
|
7537
|
+
/* @__PURE__ */ jsx3(Notice, { notice }),
|
|
7538
|
+
/* @__PURE__ */ jsxs2("div", { className: "mx-meet__collab-actions", children: [
|
|
7539
|
+
/* @__PURE__ */ jsx3("button", { type: "submit", className: "mx-meet__primary mx-meet__primary--small", disabled: !ready || busy, children: "Launch" }),
|
|
7540
|
+
/* @__PURE__ */ jsx3("button", { type: "button", className: "mx-meet__chip", disabled: !ready || busy, onClick: () => void save(false), children: "Save draft" }),
|
|
7541
|
+
/* @__PURE__ */ jsx3("button", { type: "button", className: "mx-meet__link", onClick: onDone, children: "Cancel" })
|
|
7542
|
+
] })
|
|
7543
|
+
]
|
|
7544
|
+
}
|
|
7545
|
+
);
|
|
7546
|
+
}
|
|
7547
|
+
function PollCard({ poll }) {
|
|
7548
|
+
const { act, isHost } = useCollab();
|
|
7549
|
+
const [picked, setPicked] = useState3(poll.myVote.slice());
|
|
7550
|
+
const [notice, show] = useNotice();
|
|
7551
|
+
useEffect3(() => setPicked(poll.myVote.slice()), [poll.myVote]);
|
|
7552
|
+
const counts = poll.options.some((o) => o.votes !== void 0);
|
|
7553
|
+
const total = poll.options.reduce((sum, o) => sum + (o.votes ?? 0), 0);
|
|
7554
|
+
const canVote = poll.state === "live";
|
|
7555
|
+
const voted = poll.myVote.length > 0;
|
|
7556
|
+
const stateWord = poll.state === "draft" ? "Draft" : poll.state === "live" ? "Open" : "Closed";
|
|
7557
|
+
const toggle = (id) => {
|
|
7558
|
+
if (!canVote) return;
|
|
7559
|
+
setPicked(poll.multiple ? picked.includes(id) ? picked.filter((p) => p !== id) : [...picked, id] : [id]);
|
|
7560
|
+
};
|
|
7561
|
+
return /* @__PURE__ */ jsxs2("article", { className: "mx-meet__collab-card", "aria-label": poll.question, children: [
|
|
7562
|
+
/* @__PURE__ */ jsxs2("header", { className: "mx-meet__collab-head", children: [
|
|
7563
|
+
/* @__PURE__ */ jsx3("strong", { className: "mx-meet__collab-title", children: poll.question }),
|
|
7564
|
+
/* @__PURE__ */ jsx3("span", { className: "mx-meet__collab-state", children: stateWord })
|
|
7565
|
+
] }),
|
|
7566
|
+
/* @__PURE__ */ jsxs2("p", { className: "mx-meet__panel-note", children: [
|
|
7567
|
+
poll.multiple ? "Pick any." : "Pick one.",
|
|
7568
|
+
poll.anonymous ? " Anonymous." : "",
|
|
7569
|
+
counts && poll.voterCount !== null ? ` ${poll.voterCount} voted.` : "",
|
|
7570
|
+
isHost && poll.state !== "draft" && !poll.resultsShared ? " Results are visible only to hosts." : ""
|
|
7571
|
+
] }),
|
|
7572
|
+
/* @__PURE__ */ jsx3("ul", { className: "mx-meet__poll-options", children: poll.options.map((option) => {
|
|
7573
|
+
const share = counts && total > 0 ? Math.round((option.votes ?? 0) / total * 100) : 0;
|
|
7574
|
+
const chosen = picked.includes(option.id);
|
|
7575
|
+
return /* @__PURE__ */ jsxs2("li", { children: [
|
|
7576
|
+
/* @__PURE__ */ jsxs2(
|
|
7577
|
+
"button",
|
|
7578
|
+
{
|
|
7579
|
+
type: "button",
|
|
7580
|
+
className: chosen ? "mx-meet__poll-option mx-meet__poll-option--chosen" : "mx-meet__poll-option",
|
|
7581
|
+
"aria-pressed": chosen,
|
|
7582
|
+
disabled: !canVote,
|
|
7583
|
+
onClick: () => toggle(option.id),
|
|
7584
|
+
children: [
|
|
7585
|
+
counts ? /* @__PURE__ */ jsx3("span", { className: "mx-meet__poll-bar", style: { width: `${share}%` }, "aria-hidden": "true" }) : null,
|
|
7586
|
+
/* @__PURE__ */ jsx3("span", { className: "mx-meet__poll-text", children: option.text }),
|
|
7587
|
+
counts ? /* @__PURE__ */ jsxs2("span", { className: "mx-meet__poll-count", children: [
|
|
7588
|
+
option.votes ?? 0,
|
|
7589
|
+
" \xB7 ",
|
|
7590
|
+
share,
|
|
7591
|
+
"%"
|
|
7592
|
+
] }) : null
|
|
7593
|
+
]
|
|
7594
|
+
}
|
|
7595
|
+
),
|
|
7596
|
+
option.voters !== void 0 && option.voters.length > 0 ? /* @__PURE__ */ jsx3("span", { className: "mx-meet__poll-voters", children: option.voters.join(", ") }) : null
|
|
7597
|
+
] }, option.id);
|
|
7598
|
+
}) }),
|
|
7599
|
+
/* @__PURE__ */ jsx3(Notice, { notice }),
|
|
7600
|
+
/* @__PURE__ */ jsxs2("div", { className: "mx-meet__collab-actions", children: [
|
|
7601
|
+
canVote ? /* @__PURE__ */ jsx3(
|
|
7602
|
+
"button",
|
|
7603
|
+
{
|
|
7604
|
+
type: "button",
|
|
7605
|
+
className: "mx-meet__primary mx-meet__primary--small",
|
|
7606
|
+
disabled: picked.length === 0 || voted && picked.join() === poll.myVote.join(),
|
|
7607
|
+
onClick: () => void act({ action: "poll_vote", itemId: poll.id, optionIds: picked }).then(show),
|
|
7608
|
+
children: voted ? "Change vote" : "Vote"
|
|
7609
|
+
}
|
|
7610
|
+
) : null,
|
|
7611
|
+
isHost && poll.state === "draft" ? /* @__PURE__ */ jsx3("button", { type: "button", className: "mx-meet__primary mx-meet__primary--small", onClick: () => void act({ action: "poll_launch", itemId: poll.id }).then(show), children: "Launch" }) : null,
|
|
7612
|
+
isHost && poll.state === "live" ? /* @__PURE__ */ jsx3("button", { type: "button", className: "mx-meet__chip", onClick: () => void act({ action: "poll_close", itemId: poll.id }).then(show), children: "End poll" }) : null,
|
|
7613
|
+
isHost && poll.state !== "draft" ? /* @__PURE__ */ jsx3("button", { type: "button", className: "mx-meet__chip", onClick: () => void act({ action: "poll_share", itemId: poll.id }).then(show), children: poll.resultsShared ? "Hide results" : "Share results" }) : null,
|
|
7614
|
+
isHost && poll.state === "live" ? null : isHost ? /* @__PURE__ */ jsx3("button", { type: "button", className: "mx-meet__link", onClick: () => void act({ action: "poll_delete", itemId: poll.id }).then(show), children: "Delete" }) : null
|
|
7615
|
+
] })
|
|
7616
|
+
] });
|
|
7617
|
+
}
|
|
7618
|
+
function PollsPanel({ onClose }) {
|
|
7619
|
+
const { collab, isHost } = useCollab();
|
|
7620
|
+
const [composing, setComposing] = useState3(false);
|
|
7621
|
+
const polls = collab?.polls ?? [];
|
|
7622
|
+
const maxOptions = collab?.settings?.pollMaxOptions ?? 10;
|
|
7623
|
+
const ordered = [...polls].reverse();
|
|
7624
|
+
return /* @__PURE__ */ jsxs2(PanelShell, { title: "Polls", onClose, children: [
|
|
7625
|
+
collab?.error != null ? /* @__PURE__ */ jsx3("p", { className: "mx-meet__panel-note mx-meet__collab-error", children: collab.error }) : null,
|
|
7626
|
+
isHost && !composing ? /* @__PURE__ */ jsx3("button", { type: "button", className: "mx-meet__primary mx-meet__primary--small", onClick: () => setComposing(true), children: "New poll" }) : null,
|
|
7627
|
+
isHost && composing ? /* @__PURE__ */ jsx3(PollComposer, { maxOptions, onDone: () => setComposing(false) }) : null,
|
|
7628
|
+
ordered.length === 0 && !composing ? /* @__PURE__ */ jsx3("p", { className: "mx-meet__panel-note", children: isHost ? "No polls yet. Polls and their results are kept with the meeting." : "No polls yet." }) : null,
|
|
7629
|
+
ordered.map((poll) => /* @__PURE__ */ jsx3(PollCard, { poll }, poll.id))
|
|
7630
|
+
] });
|
|
7631
|
+
}
|
|
7632
|
+
function QuestionCard({ question }) {
|
|
7633
|
+
const { act, isHost } = useCollab();
|
|
7634
|
+
const [answering, setAnswering] = useState3(false);
|
|
7635
|
+
const [reply, setReply] = useState3("");
|
|
7636
|
+
const [notice, show] = useNotice();
|
|
7637
|
+
return /* @__PURE__ */ jsxs2("li", { className: `mx-meet__collab-card mx-meet__question mx-meet__question--${question.state}`, children: [
|
|
7638
|
+
/* @__PURE__ */ jsxs2("div", { className: "mx-meet__question-row", children: [
|
|
7639
|
+
/* @__PURE__ */ jsxs2(
|
|
7640
|
+
"button",
|
|
7641
|
+
{
|
|
7642
|
+
type: "button",
|
|
7643
|
+
className: question.upvotedByMe ? "mx-meet__upvote mx-meet__upvote--on" : "mx-meet__upvote",
|
|
7644
|
+
"aria-pressed": question.upvotedByMe,
|
|
7645
|
+
"aria-label": question.upvotedByMe ? "Remove your upvote" : "Upvote",
|
|
7646
|
+
disabled: question.state === "dismissed",
|
|
7647
|
+
onClick: () => void act({ action: "question_upvote", itemId: question.id }).then((r) => r.ok ? void 0 : show(r)),
|
|
7648
|
+
children: [
|
|
7649
|
+
/* @__PURE__ */ jsx3(UpvoteIcon, { width: 16, height: 16 }),
|
|
7650
|
+
/* @__PURE__ */ jsx3("span", { children: question.upvotes })
|
|
7651
|
+
]
|
|
7652
|
+
}
|
|
7653
|
+
),
|
|
7654
|
+
/* @__PURE__ */ jsxs2("div", { className: "mx-meet__question-body", children: [
|
|
7655
|
+
/* @__PURE__ */ jsxs2("span", { className: "mx-meet__chat-meta", children: [
|
|
7656
|
+
/* @__PURE__ */ jsx3("strong", { children: question.mine ? "You" : question.askerName }),
|
|
7657
|
+
question.mine && question.anonymous ? /* @__PURE__ */ jsx3("span", { className: "mx-meet__chat-private", children: "anonymous" }) : null,
|
|
7658
|
+
question.state !== "open" ? /* @__PURE__ */ jsx3("span", { className: "mx-meet__collab-state", children: question.state === "answered" ? "Answered" : "Dismissed" }) : null
|
|
7659
|
+
] }),
|
|
7660
|
+
/* @__PURE__ */ jsx3("span", { className: "mx-meet__chat-text", children: question.text }),
|
|
7661
|
+
question.answer !== null ? /* @__PURE__ */ jsxs2("span", { className: "mx-meet__question-answer", children: [
|
|
7662
|
+
/* @__PURE__ */ jsxs2("strong", { children: [
|
|
7663
|
+
question.answeredByName ?? "Host",
|
|
7664
|
+
":"
|
|
7665
|
+
] }),
|
|
7666
|
+
" ",
|
|
7667
|
+
question.answer
|
|
7668
|
+
] }) : null
|
|
7669
|
+
] })
|
|
7670
|
+
] }),
|
|
7671
|
+
answering ? /* @__PURE__ */ jsxs2(
|
|
7672
|
+
"form",
|
|
7673
|
+
{
|
|
7674
|
+
className: "mx-meet__composer-row",
|
|
7675
|
+
onSubmit: (event) => {
|
|
7676
|
+
event.preventDefault();
|
|
7677
|
+
void act({ action: "question_answer", itemId: question.id, text: reply }).then((r) => {
|
|
7678
|
+
show(r);
|
|
7679
|
+
if (r.ok) {
|
|
7680
|
+
setAnswering(false);
|
|
7681
|
+
setReply("");
|
|
7682
|
+
}
|
|
7683
|
+
});
|
|
7684
|
+
},
|
|
7685
|
+
children: [
|
|
7686
|
+
/* @__PURE__ */ jsx3(
|
|
7687
|
+
"input",
|
|
7688
|
+
{
|
|
7689
|
+
className: "mx-meet__input",
|
|
7690
|
+
value: reply,
|
|
7691
|
+
maxLength: 2e3,
|
|
7692
|
+
onChange: (event) => setReply(event.target.value),
|
|
7693
|
+
placeholder: "Type an answer, or leave empty if you answered out loud",
|
|
7694
|
+
"aria-label": "Answer",
|
|
7695
|
+
autoFocus: true
|
|
7696
|
+
}
|
|
7697
|
+
),
|
|
7698
|
+
/* @__PURE__ */ jsx3("button", { type: "submit", className: "mx-meet__send", children: "Done" })
|
|
7699
|
+
]
|
|
7700
|
+
}
|
|
7701
|
+
) : null,
|
|
7702
|
+
/* @__PURE__ */ jsx3(Notice, { notice }),
|
|
7703
|
+
isHost || question.mine ? /* @__PURE__ */ jsxs2("div", { className: "mx-meet__collab-actions", children: [
|
|
7704
|
+
isHost && question.state === "open" && !answering ? /* @__PURE__ */ jsx3("button", { type: "button", className: "mx-meet__chip", onClick: () => setAnswering(true), children: "Answer" }) : null,
|
|
7705
|
+
isHost && question.state === "open" ? /* @__PURE__ */ jsx3("button", { type: "button", className: "mx-meet__chip", onClick: () => void act({ action: "question_dismiss", itemId: question.id }).then(show), children: "Dismiss" }) : null,
|
|
7706
|
+
isHost && question.state !== "open" ? /* @__PURE__ */ jsx3("button", { type: "button", className: "mx-meet__chip", onClick: () => void act({ action: "question_reopen", itemId: question.id }).then(show), children: "Reopen" }) : null,
|
|
7707
|
+
question.mine || isHost ? /* @__PURE__ */ jsx3("button", { type: "button", className: "mx-meet__link", onClick: () => void act({ action: "question_delete", itemId: question.id }).then(show), children: "Delete" }) : null
|
|
7708
|
+
] }) : null
|
|
7709
|
+
] });
|
|
7710
|
+
}
|
|
7711
|
+
function QaPanel({ onClose }) {
|
|
7712
|
+
const { collab, act } = useCollab();
|
|
7713
|
+
const [draft, setDraft] = useState3("");
|
|
7714
|
+
const [anonymous, setAnonymous] = useState3(false);
|
|
7715
|
+
const [order, setOrder] = useState3("popular");
|
|
7716
|
+
const [notice, show] = useNotice();
|
|
7717
|
+
const allowAnonymous = collab?.settings?.qaAnonymousAllowed === true;
|
|
7718
|
+
const questions = [...collab?.questions ?? []];
|
|
7719
|
+
const rank = (q) => q.state === "open" ? 0 : q.state === "answered" ? 1 : 2;
|
|
7720
|
+
questions.sort(
|
|
7721
|
+
(a, b) => rank(a) !== rank(b) ? rank(a) - rank(b) : order === "popular" ? b.upvotes - a.upvotes || (b.createdAt ?? "").localeCompare(a.createdAt ?? "") : (b.createdAt ?? "").localeCompare(a.createdAt ?? "")
|
|
7722
|
+
);
|
|
7723
|
+
return /* @__PURE__ */ jsxs2(PanelShell, { title: "Q&A", onClose, children: [
|
|
7724
|
+
collab?.error != null ? /* @__PURE__ */ jsx3("p", { className: "mx-meet__panel-note mx-meet__collab-error", children: collab.error }) : null,
|
|
7725
|
+
/* @__PURE__ */ jsxs2(
|
|
7726
|
+
"form",
|
|
7727
|
+
{
|
|
7728
|
+
className: "mx-meet__composer mx-meet__composer--chat",
|
|
7729
|
+
onSubmit: (event) => {
|
|
7730
|
+
event.preventDefault();
|
|
7731
|
+
const text3 = draft.trim();
|
|
7732
|
+
if (text3.length === 0) return;
|
|
7733
|
+
void act({ action: "question_ask", text: text3, anonymous: allowAnonymous && anonymous }).then((r) => {
|
|
7734
|
+
if (r.ok) setDraft("");
|
|
7735
|
+
else show(r);
|
|
7736
|
+
});
|
|
7737
|
+
},
|
|
7738
|
+
children: [
|
|
7739
|
+
/* @__PURE__ */ jsxs2("div", { className: "mx-meet__composer-row", children: [
|
|
7740
|
+
/* @__PURE__ */ jsx3(
|
|
7741
|
+
"input",
|
|
7742
|
+
{
|
|
7743
|
+
className: "mx-meet__input",
|
|
7744
|
+
value: draft,
|
|
7745
|
+
maxLength: 1e3,
|
|
7746
|
+
onChange: (event) => setDraft(event.target.value),
|
|
7747
|
+
placeholder: "Ask the host a question",
|
|
7748
|
+
"aria-label": "Ask the host a question"
|
|
7749
|
+
}
|
|
7750
|
+
),
|
|
7751
|
+
/* @__PURE__ */ jsx3("button", { type: "submit", className: "mx-meet__send", disabled: draft.trim().length === 0, children: "Ask" })
|
|
7752
|
+
] }),
|
|
7753
|
+
allowAnonymous ? /* @__PURE__ */ jsxs2("label", { className: "mx-meet__toggle", children: [
|
|
7754
|
+
/* @__PURE__ */ jsx3("input", { type: "checkbox", checked: anonymous, onChange: (event) => setAnonymous(event.target.checked) }),
|
|
7755
|
+
"Ask anonymously"
|
|
7756
|
+
] }) : null
|
|
7757
|
+
]
|
|
7758
|
+
}
|
|
7759
|
+
),
|
|
7760
|
+
/* @__PURE__ */ jsx3(Notice, { notice }),
|
|
7761
|
+
questions.length > 1 ? /* @__PURE__ */ jsx3("div", { className: "mx-meet__pills", role: "group", "aria-label": "Order questions", children: ["popular", "recent"].map((value) => /* @__PURE__ */ jsx3(
|
|
7762
|
+
"button",
|
|
7763
|
+
{
|
|
7764
|
+
type: "button",
|
|
7765
|
+
className: order === value ? "mx-meet__pill mx-meet__pill--on" : "mx-meet__pill",
|
|
7766
|
+
"aria-pressed": order === value,
|
|
7767
|
+
onClick: () => setOrder(value),
|
|
7768
|
+
children: value === "popular" ? "Popular" : "Recent"
|
|
7769
|
+
},
|
|
7770
|
+
value
|
|
7771
|
+
)) }) : null,
|
|
7772
|
+
questions.length === 0 ? /* @__PURE__ */ jsx3("p", { className: "mx-meet__panel-note", children: "No questions yet. Questions are kept with the meeting." }) : /* @__PURE__ */ jsx3("ul", { className: "mx-meet__chat", children: questions.map((question) => /* @__PURE__ */ jsx3(QuestionCard, { question }, question.id)) })
|
|
7773
|
+
] });
|
|
7774
|
+
}
|
|
7775
|
+
var BOARD_W = 1600;
|
|
7776
|
+
var BOARD_H = 1e3;
|
|
7777
|
+
var INK = ["#111827", "#dc2626", "#2563eb", "#16a34a", "#f59e0b", "#7c3aed"];
|
|
7778
|
+
function strokePath(points) {
|
|
7779
|
+
if (points.length === 0) return "";
|
|
7780
|
+
const [first, ...rest] = points;
|
|
7781
|
+
const move = `M${(first[0] * BOARD_W).toFixed(1)} ${(first[1] * BOARD_H).toFixed(1)}`;
|
|
7782
|
+
if (rest.length === 0) return `${move} l0.1 0`;
|
|
7783
|
+
return `${move} ${rest.map(([x, y]) => `L${(x * BOARD_W).toFixed(1)} ${(y * BOARD_H).toFixed(1)}`).join(" ")}`;
|
|
7784
|
+
}
|
|
7785
|
+
function StrokeView({ stroke, onPick }) {
|
|
6745
7786
|
return /* @__PURE__ */ jsx3(
|
|
7787
|
+
"path",
|
|
7788
|
+
{
|
|
7789
|
+
d: strokePath(stroke.points),
|
|
7790
|
+
fill: "none",
|
|
7791
|
+
stroke: stroke.color,
|
|
7792
|
+
strokeWidth: stroke.tool === "highlighter" ? stroke.width * 4 : stroke.width,
|
|
7793
|
+
strokeOpacity: stroke.tool === "highlighter" ? 0.35 : stroke.pending === true ? 0.6 : 1,
|
|
7794
|
+
strokeLinecap: "round",
|
|
7795
|
+
strokeLinejoin: "round",
|
|
7796
|
+
onPointerDown: onPick,
|
|
7797
|
+
style: onPick !== void 0 ? { cursor: "pointer" } : void 0,
|
|
7798
|
+
children: /* @__PURE__ */ jsx3("title", { children: stroke.byName })
|
|
7799
|
+
}
|
|
7800
|
+
);
|
|
7801
|
+
}
|
|
7802
|
+
function WhiteboardPanel({ onClose }) {
|
|
7803
|
+
const { collab, act, isHost, localIdentity } = useCollab();
|
|
7804
|
+
const [tool, setTool] = useState3("pen");
|
|
7805
|
+
const [color, setColor] = useState3(INK[0]);
|
|
7806
|
+
const [drawing, setDrawing] = useState3(null);
|
|
7807
|
+
const [pending, setPending] = useState3([]);
|
|
7808
|
+
const [notice, show] = useNotice();
|
|
7809
|
+
const svgRef = useRef3(null);
|
|
7810
|
+
const strokes = collab?.strokes ?? [];
|
|
7811
|
+
const mine = strokes.filter((s) => s.by === localIdentity);
|
|
7812
|
+
const point = (event) => {
|
|
7813
|
+
const svg = svgRef.current;
|
|
7814
|
+
if (svg === null) return null;
|
|
7815
|
+
const rect = svg.getBoundingClientRect();
|
|
7816
|
+
const scale = Math.min(rect.width / BOARD_W, rect.height / BOARD_H);
|
|
7817
|
+
const offsetX = (rect.width - BOARD_W * scale) / 2;
|
|
7818
|
+
const offsetY = (rect.height - BOARD_H * scale) / 2;
|
|
7819
|
+
const x = (event.clientX - rect.left - offsetX) / (BOARD_W * scale);
|
|
7820
|
+
const y = (event.clientY - rect.top - offsetY) / (BOARD_H * scale);
|
|
7821
|
+
return [Math.min(1, Math.max(0, x)), Math.min(1, Math.max(0, y))];
|
|
7822
|
+
};
|
|
7823
|
+
const finish = () => {
|
|
7824
|
+
const points = drawing;
|
|
7825
|
+
setDrawing(null);
|
|
7826
|
+
if (points === null || points.length === 0 || tool === "eraser") return;
|
|
7827
|
+
const thinned = points.filter((p, i) => i === 0 || i === points.length - 1 || i % 2 === 0).slice(0, 2e3);
|
|
7828
|
+
const stroke = {
|
|
7829
|
+
points: thinned.map(([x, y]) => [Number(x.toFixed(4)), Number(y.toFixed(4))]),
|
|
7830
|
+
color,
|
|
7831
|
+
width: tool === "highlighter" ? 4 : 3,
|
|
7832
|
+
tool: tool === "highlighter" ? "highlighter" : "pen"
|
|
7833
|
+
};
|
|
7834
|
+
const localId = `pending-${Date.now()}`;
|
|
7835
|
+
setPending((list) => [...list, { id: localId, ...stroke, by: localIdentity ?? "", byName: "You", pending: true }]);
|
|
7836
|
+
void act({ action: "stroke_add", stroke }).then((result) => {
|
|
7837
|
+
setPending((list) => list.filter((s) => s.id !== localId));
|
|
7838
|
+
if (!result.ok) show(result);
|
|
7839
|
+
});
|
|
7840
|
+
};
|
|
7841
|
+
return /* @__PURE__ */ jsxs2("section", { className: "mx-meet__whiteboard", "aria-label": "Whiteboard", children: [
|
|
7842
|
+
/* @__PURE__ */ jsxs2("header", { className: "mx-meet__whiteboard-bar", children: [
|
|
7843
|
+
/* @__PURE__ */ jsx3("strong", { className: "mx-meet__panel-title", children: "Whiteboard" }),
|
|
7844
|
+
/* @__PURE__ */ jsx3("div", { className: "mx-meet__pills", role: "group", "aria-label": "Tool", children: [
|
|
7845
|
+
["pen", "Pen", /* @__PURE__ */ jsx3(PencilIcon, { width: 16, height: 16 }, "p")],
|
|
7846
|
+
["highlighter", "Highlighter", /* @__PURE__ */ jsx3(HighlighterIcon, { width: 16, height: 16 }, "h")],
|
|
7847
|
+
["eraser", "Eraser \u2014 click a stroke", /* @__PURE__ */ jsx3(EraserIcon, { width: 16, height: 16 }, "e")]
|
|
7848
|
+
].map(([value, label, icon]) => /* @__PURE__ */ jsx3(
|
|
7849
|
+
"button",
|
|
7850
|
+
{
|
|
7851
|
+
type: "button",
|
|
7852
|
+
className: tool === value ? "mx-meet__pill mx-meet__pill--on" : "mx-meet__pill",
|
|
7853
|
+
"aria-pressed": tool === value,
|
|
7854
|
+
"aria-label": label,
|
|
7855
|
+
title: label,
|
|
7856
|
+
onClick: () => setTool(value),
|
|
7857
|
+
children: icon
|
|
7858
|
+
},
|
|
7859
|
+
value
|
|
7860
|
+
)) }),
|
|
7861
|
+
/* @__PURE__ */ jsx3("div", { className: "mx-meet__swatches", role: "group", "aria-label": "Color", children: INK.map((ink) => /* @__PURE__ */ jsx3(
|
|
7862
|
+
"button",
|
|
7863
|
+
{
|
|
7864
|
+
type: "button",
|
|
7865
|
+
className: ink === color ? "mx-meet__swatch mx-meet__swatch--on" : "mx-meet__swatch",
|
|
7866
|
+
style: { background: ink },
|
|
7867
|
+
"aria-label": `Color ${ink}`,
|
|
7868
|
+
"aria-pressed": ink === color,
|
|
7869
|
+
onClick: () => {
|
|
7870
|
+
setColor(ink);
|
|
7871
|
+
if (tool === "eraser") setTool("pen");
|
|
7872
|
+
}
|
|
7873
|
+
},
|
|
7874
|
+
ink
|
|
7875
|
+
)) }),
|
|
7876
|
+
/* @__PURE__ */ jsx3(
|
|
7877
|
+
ControlButton,
|
|
7878
|
+
{
|
|
7879
|
+
label: "Undo my last stroke",
|
|
7880
|
+
onClick: () => {
|
|
7881
|
+
const last = mine[mine.length - 1];
|
|
7882
|
+
if (last !== void 0) void act({ action: "stroke_erase", itemId: last.id }).then((r) => r.ok ? void 0 : show(r));
|
|
7883
|
+
},
|
|
7884
|
+
children: /* @__PURE__ */ jsx3(UndoIcon, { width: 16, height: 16 })
|
|
7885
|
+
}
|
|
7886
|
+
),
|
|
7887
|
+
isHost && strokes.length > 0 ? /* @__PURE__ */ jsx3("button", { type: "button", className: "mx-meet__chip", onClick: () => void act({ action: "whiteboard_clear" }).then(show), children: "Clear board" }) : null,
|
|
7888
|
+
/* @__PURE__ */ jsx3("span", { className: "mx-meet__whiteboard-note", children: "Saved with the meeting" }),
|
|
7889
|
+
/* @__PURE__ */ jsx3(ControlButton, { label: "Close whiteboard", onClick: onClose, children: /* @__PURE__ */ jsx3(CloseIcon, { width: 16, height: 16 }) })
|
|
7890
|
+
] }),
|
|
7891
|
+
/* @__PURE__ */ jsx3(Notice, { notice }),
|
|
7892
|
+
/* @__PURE__ */ jsxs2(
|
|
7893
|
+
"svg",
|
|
7894
|
+
{
|
|
7895
|
+
ref: svgRef,
|
|
7896
|
+
className: tool === "eraser" ? "mx-meet__board mx-meet__board--erase" : "mx-meet__board",
|
|
7897
|
+
viewBox: `0 0 ${BOARD_W} ${BOARD_H}`,
|
|
7898
|
+
preserveAspectRatio: "xMidYMid meet",
|
|
7899
|
+
role: "img",
|
|
7900
|
+
"aria-label": `Shared whiteboard, ${strokes.length} strokes`,
|
|
7901
|
+
onPointerDown: (event) => {
|
|
7902
|
+
if (tool === "eraser") return;
|
|
7903
|
+
const p = point(event);
|
|
7904
|
+
if (p === null) return;
|
|
7905
|
+
event.target.setPointerCapture?.(event.pointerId);
|
|
7906
|
+
setDrawing([p]);
|
|
7907
|
+
},
|
|
7908
|
+
onPointerMove: (event) => {
|
|
7909
|
+
if (drawing === null) return;
|
|
7910
|
+
const p = point(event);
|
|
7911
|
+
if (p !== null) setDrawing([...drawing, p]);
|
|
7912
|
+
},
|
|
7913
|
+
onPointerUp: finish,
|
|
7914
|
+
onPointerCancel: finish,
|
|
7915
|
+
children: [
|
|
7916
|
+
/* @__PURE__ */ jsx3("rect", { x: 0, y: 0, width: BOARD_W, height: BOARD_H, className: "mx-meet__board-paper" }),
|
|
7917
|
+
strokes.map((stroke) => /* @__PURE__ */ jsx3(
|
|
7918
|
+
StrokeView,
|
|
7919
|
+
{
|
|
7920
|
+
stroke,
|
|
7921
|
+
onPick: tool === "eraser" && (isHost || stroke.by === localIdentity) ? () => void act({ action: "stroke_erase", itemId: stroke.id }).then((r) => r.ok ? void 0 : show(r)) : void 0
|
|
7922
|
+
},
|
|
7923
|
+
stroke.id
|
|
7924
|
+
)),
|
|
7925
|
+
pending.map((stroke) => /* @__PURE__ */ jsx3(StrokeView, { stroke }, stroke.id)),
|
|
7926
|
+
drawing !== null ? /* @__PURE__ */ jsx3(
|
|
7927
|
+
StrokeView,
|
|
7928
|
+
{
|
|
7929
|
+
stroke: {
|
|
7930
|
+
id: "drawing",
|
|
7931
|
+
points: drawing,
|
|
7932
|
+
color,
|
|
7933
|
+
width: tool === "highlighter" ? 4 : 3,
|
|
7934
|
+
tool: tool === "highlighter" ? "highlighter" : "pen",
|
|
7935
|
+
by: "",
|
|
7936
|
+
byName: "You"
|
|
7937
|
+
}
|
|
7938
|
+
}
|
|
7939
|
+
) : null
|
|
7940
|
+
]
|
|
7941
|
+
}
|
|
7942
|
+
)
|
|
7943
|
+
] });
|
|
7944
|
+
}
|
|
7945
|
+
function clock(ms2) {
|
|
7946
|
+
const total = Math.ceil(ms2 / 1e3);
|
|
7947
|
+
const minutes = Math.floor(total / 60);
|
|
7948
|
+
const seconds = total % 60;
|
|
7949
|
+
return `${minutes}:${seconds.toString().padStart(2, "0")}`;
|
|
7950
|
+
}
|
|
7951
|
+
function useNow(active) {
|
|
7952
|
+
const [now, setNow] = useState3(() => Date.now());
|
|
7953
|
+
useEffect3(() => {
|
|
7954
|
+
if (!active) return void 0;
|
|
7955
|
+
const timer = setInterval(() => setNow(Date.now()), 1e3);
|
|
7956
|
+
return () => clearInterval(timer);
|
|
7957
|
+
}, [active]);
|
|
7958
|
+
return now;
|
|
7959
|
+
}
|
|
7960
|
+
function BreakoutSetup() {
|
|
7961
|
+
const { collab, act } = useCollab();
|
|
7962
|
+
const snapshot = useMeetSnapshot();
|
|
7963
|
+
const settings = collab?.settings ?? null;
|
|
7964
|
+
const people = (snapshot?.participants ?? []).filter(
|
|
7965
|
+
(p) => !p.isAgent && p.role !== "host" && p.role !== "cohost"
|
|
7966
|
+
);
|
|
7967
|
+
const [count2, setCount] = useState3(Math.min(Math.max(2, Math.ceil(people.length / 4)), settings?.breakoutMaxRooms ?? 20));
|
|
7968
|
+
const [mode, setMode] = useState3("auto");
|
|
7969
|
+
const [minutes, setMinutes] = useState3(settings?.breakoutDefaultMinutes ?? 15);
|
|
7970
|
+
const [manual, setManual] = useState3({});
|
|
7971
|
+
const [busy, setBusy] = useState3(false);
|
|
7972
|
+
const [notice, show] = useNotice();
|
|
7973
|
+
const max = settings?.breakoutMaxRooms ?? 20;
|
|
7974
|
+
const rooms = Math.min(Math.max(1, count2), max);
|
|
7975
|
+
const assignment = mode === "auto" ? autoAssign(
|
|
7976
|
+
people.map((p) => p.identity),
|
|
7977
|
+
rooms
|
|
7978
|
+
) : mode === "manual" ? Array.from(
|
|
7979
|
+
{ length: rooms },
|
|
7980
|
+
(_, index) => people.filter((p) => (manual[p.identity] ?? -1) === index).map((p) => p.identity)
|
|
7981
|
+
) : Array.from({ length: rooms }, () => []);
|
|
7982
|
+
const nameOf = (identity) => people.find((p) => p.identity === identity)?.displayName ?? identity;
|
|
7983
|
+
return /* @__PURE__ */ jsxs2("div", { className: "mx-meet__collab-card", children: [
|
|
7984
|
+
/* @__PURE__ */ jsxs2("label", { className: "mx-meet__field", children: [
|
|
7985
|
+
/* @__PURE__ */ jsx3("span", { className: "mx-meet__field-label", children: "Rooms" }),
|
|
7986
|
+
/* @__PURE__ */ jsx3(
|
|
7987
|
+
"input",
|
|
7988
|
+
{
|
|
7989
|
+
className: "mx-meet__input",
|
|
7990
|
+
type: "number",
|
|
7991
|
+
min: 1,
|
|
7992
|
+
max,
|
|
7993
|
+
value: count2,
|
|
7994
|
+
onChange: (event) => setCount(Number(event.target.value) || 1)
|
|
7995
|
+
}
|
|
7996
|
+
)
|
|
7997
|
+
] }),
|
|
7998
|
+
/* @__PURE__ */ jsx3("div", { className: "mx-meet__pills", role: "group", "aria-label": "How people are placed", children: [
|
|
7999
|
+
["auto", "Automatically"],
|
|
8000
|
+
["manual", "Manually"],
|
|
8001
|
+
["choose", "Let people choose"]
|
|
8002
|
+
].map(([value, label]) => /* @__PURE__ */ jsx3(
|
|
8003
|
+
"button",
|
|
8004
|
+
{
|
|
8005
|
+
type: "button",
|
|
8006
|
+
className: mode === value ? "mx-meet__pill mx-meet__pill--on" : "mx-meet__pill",
|
|
8007
|
+
"aria-pressed": mode === value,
|
|
8008
|
+
onClick: () => setMode(value),
|
|
8009
|
+
children: label
|
|
8010
|
+
},
|
|
8011
|
+
value
|
|
8012
|
+
)) }),
|
|
8013
|
+
/* @__PURE__ */ jsxs2("label", { className: "mx-meet__field", children: [
|
|
8014
|
+
/* @__PURE__ */ jsx3("span", { className: "mx-meet__field-label", children: "Timer (minutes, 0 for none)" }),
|
|
8015
|
+
/* @__PURE__ */ jsx3(
|
|
8016
|
+
"input",
|
|
8017
|
+
{
|
|
8018
|
+
className: "mx-meet__input",
|
|
8019
|
+
type: "number",
|
|
8020
|
+
min: 0,
|
|
8021
|
+
max: 720,
|
|
8022
|
+
value: minutes,
|
|
8023
|
+
onChange: (event) => setMinutes(Math.max(0, Number(event.target.value) || 0))
|
|
8024
|
+
}
|
|
8025
|
+
)
|
|
8026
|
+
] }),
|
|
8027
|
+
mode === "manual" ? people.length === 0 ? /* @__PURE__ */ jsx3("p", { className: "mx-meet__panel-note", children: "Nobody else is in the meeting yet." }) : /* @__PURE__ */ jsx3("ul", { className: "mx-meet__people", children: people.map((person) => /* @__PURE__ */ jsxs2("li", { className: "mx-meet__person", children: [
|
|
8028
|
+
/* @__PURE__ */ jsx3("span", { className: "mx-meet__person-name", children: person.displayName }),
|
|
8029
|
+
/* @__PURE__ */ jsxs2(
|
|
8030
|
+
"select",
|
|
8031
|
+
{
|
|
8032
|
+
className: "mx-meet__select mx-meet__select--compact",
|
|
8033
|
+
"aria-label": `Room for ${person.displayName}`,
|
|
8034
|
+
value: manual[person.identity] ?? -1,
|
|
8035
|
+
onChange: (event) => setManual({ ...manual, [person.identity]: Number(event.target.value) }),
|
|
8036
|
+
children: [
|
|
8037
|
+
/* @__PURE__ */ jsx3("option", { value: -1, children: "Main room" }),
|
|
8038
|
+
Array.from({ length: rooms }, (_, index) => /* @__PURE__ */ jsxs2("option", { value: index, children: [
|
|
8039
|
+
"Room ",
|
|
8040
|
+
index + 1
|
|
8041
|
+
] }, index))
|
|
8042
|
+
]
|
|
8043
|
+
}
|
|
8044
|
+
)
|
|
8045
|
+
] }, person.identity)) }) : mode === "auto" ? /* @__PURE__ */ jsx3("ul", { className: "mx-meet__breakout-rooms", children: assignment.map((members, index) => /* @__PURE__ */ jsxs2("li", { children: [
|
|
8046
|
+
/* @__PURE__ */ jsxs2("strong", { children: [
|
|
8047
|
+
"Room ",
|
|
8048
|
+
index + 1
|
|
8049
|
+
] }),
|
|
8050
|
+
" ",
|
|
8051
|
+
/* @__PURE__ */ jsx3("span", { className: "mx-meet__panel-note", children: members.length === 0 ? "empty" : members.map(nameOf).join(", ") })
|
|
8052
|
+
] }, index)) }) : /* @__PURE__ */ jsx3("p", { className: "mx-meet__panel-note", children: "Everyone picks a room from their own screen." }),
|
|
8053
|
+
/* @__PURE__ */ jsx3(Notice, { notice }),
|
|
8054
|
+
/* @__PURE__ */ jsxs2(
|
|
8055
|
+
"button",
|
|
8056
|
+
{
|
|
8057
|
+
type: "button",
|
|
8058
|
+
className: "mx-meet__primary mx-meet__primary--small",
|
|
8059
|
+
disabled: busy,
|
|
8060
|
+
onClick: () => {
|
|
8061
|
+
setBusy(true);
|
|
8062
|
+
void act({
|
|
8063
|
+
action: "breakout_open",
|
|
8064
|
+
rooms: assignment.map((identities, index) => ({ name: `Room ${index + 1}`, identities })),
|
|
8065
|
+
allowChoose: mode === "choose",
|
|
8066
|
+
minutes
|
|
8067
|
+
}).then((result) => {
|
|
8068
|
+
setBusy(false);
|
|
8069
|
+
show(result);
|
|
8070
|
+
});
|
|
8071
|
+
},
|
|
8072
|
+
children: [
|
|
8073
|
+
"Open ",
|
|
8074
|
+
rooms,
|
|
8075
|
+
" room",
|
|
8076
|
+
rooms === 1 ? "" : "s"
|
|
8077
|
+
]
|
|
8078
|
+
}
|
|
8079
|
+
)
|
|
8080
|
+
] });
|
|
8081
|
+
}
|
|
8082
|
+
function BreakoutRun({ plan }) {
|
|
8083
|
+
const { act, moveTo, isHost, breakoutRoomId, localIdentity } = useCollab();
|
|
8084
|
+
const snapshot = useMeetSnapshot();
|
|
8085
|
+
const now = useNow(plan.endsAt !== null);
|
|
8086
|
+
const remaining = breakoutRemainingMs(plan, now);
|
|
8087
|
+
const [broadcast, setBroadcast] = useState3("");
|
|
8088
|
+
const [notice, show] = useNotice();
|
|
8089
|
+
const nameOf = (identity) => displayNameFor(snapshot?.names ?? {}, identity, snapshot?.participants.find((p) => p.identity === identity)?.displayName);
|
|
8090
|
+
const mine = assignedRoom(plan, localIdentity);
|
|
8091
|
+
const join = async (roomId) => {
|
|
8092
|
+
const said = await act({ action: "breakout_join", roomId });
|
|
8093
|
+
if (!said.ok) {
|
|
8094
|
+
show(said);
|
|
8095
|
+
return;
|
|
8096
|
+
}
|
|
8097
|
+
show(await moveTo(roomId));
|
|
8098
|
+
};
|
|
8099
|
+
return /* @__PURE__ */ jsxs2("div", { className: "mx-meet__collab-card", children: [
|
|
8100
|
+
/* @__PURE__ */ jsxs2("p", { className: "mx-meet__panel-note", children: [
|
|
8101
|
+
plan.rooms.length,
|
|
8102
|
+
" room",
|
|
8103
|
+
plan.rooms.length === 1 ? "" : "s",
|
|
8104
|
+
" open",
|
|
8105
|
+
remaining !== null ? ` \xB7 ${clock(remaining)} left` : "",
|
|
8106
|
+
plan.allowChoose ? " \xB7 people choose their room" : ""
|
|
8107
|
+
] }),
|
|
8108
|
+
/* @__PURE__ */ jsx3("ul", { className: "mx-meet__breakout-rooms", children: plan.rooms.map((room) => {
|
|
8109
|
+
const here = breakoutRoomId === room.id;
|
|
8110
|
+
const mayJoin = isHost || plan.allowChoose || mine?.id === room.id;
|
|
8111
|
+
return /* @__PURE__ */ jsxs2("li", { className: here ? "mx-meet__breakout-room mx-meet__breakout-room--here" : "mx-meet__breakout-room", children: [
|
|
8112
|
+
/* @__PURE__ */ jsxs2("div", { className: "mx-meet__collab-head", children: [
|
|
8113
|
+
/* @__PURE__ */ jsx3("strong", { children: room.name }),
|
|
8114
|
+
here ? /* @__PURE__ */ jsx3("span", { className: "mx-meet__collab-state", children: "You are here" }) : mayJoin ? /* @__PURE__ */ jsx3("button", { type: "button", className: "mx-meet__chip", onClick: () => void join(room.id), children: "Join" }) : null
|
|
8115
|
+
] }),
|
|
8116
|
+
/* @__PURE__ */ jsx3("span", { className: "mx-meet__panel-note", children: room.identities.length === 0 ? "Nobody assigned" : room.identities.map(nameOf).join(", ") }),
|
|
8117
|
+
isHost && room.identities.length > 0 ? /* @__PURE__ */ jsx3("ul", { className: "mx-meet__people", children: room.identities.map((identity) => /* @__PURE__ */ jsxs2("li", { className: "mx-meet__person", children: [
|
|
8118
|
+
/* @__PURE__ */ jsx3("span", { className: "mx-meet__person-name", children: nameOf(identity) }),
|
|
8119
|
+
/* @__PURE__ */ jsxs2(
|
|
8120
|
+
"select",
|
|
8121
|
+
{
|
|
8122
|
+
className: "mx-meet__select mx-meet__select--compact",
|
|
8123
|
+
"aria-label": `Move ${nameOf(identity)}`,
|
|
8124
|
+
value: room.id,
|
|
8125
|
+
onChange: (event) => void act({
|
|
8126
|
+
action: "breakout_move",
|
|
8127
|
+
identity,
|
|
8128
|
+
roomId: event.target.value === "" ? null : event.target.value
|
|
8129
|
+
}).then(show),
|
|
8130
|
+
children: [
|
|
8131
|
+
/* @__PURE__ */ jsx3("option", { value: "", children: "Main room" }),
|
|
8132
|
+
plan.rooms.map((option) => /* @__PURE__ */ jsx3("option", { value: option.id, children: option.name }, option.id))
|
|
8133
|
+
]
|
|
8134
|
+
}
|
|
8135
|
+
)
|
|
8136
|
+
] }, identity)) }) : null
|
|
8137
|
+
] }, room.id);
|
|
8138
|
+
}) }),
|
|
8139
|
+
breakoutRoomId !== null ? /* @__PURE__ */ jsx3("button", { type: "button", className: "mx-meet__chip", onClick: () => void join(null), children: "Return to the main room" }) : null,
|
|
8140
|
+
isHost ? /* @__PURE__ */ jsxs2(
|
|
8141
|
+
"form",
|
|
8142
|
+
{
|
|
8143
|
+
className: "mx-meet__composer-row",
|
|
8144
|
+
onSubmit: (event) => {
|
|
8145
|
+
event.preventDefault();
|
|
8146
|
+
const text3 = broadcast.trim();
|
|
8147
|
+
if (text3.length === 0) return;
|
|
8148
|
+
void act({ action: "breakout_broadcast", text: text3 }).then((result) => {
|
|
8149
|
+
show(result);
|
|
8150
|
+
if (result.ok) setBroadcast("");
|
|
8151
|
+
});
|
|
8152
|
+
},
|
|
8153
|
+
children: [
|
|
8154
|
+
/* @__PURE__ */ jsx3(
|
|
8155
|
+
"input",
|
|
8156
|
+
{
|
|
8157
|
+
className: "mx-meet__input",
|
|
8158
|
+
value: broadcast,
|
|
8159
|
+
maxLength: 500,
|
|
8160
|
+
onChange: (event) => setBroadcast(event.target.value),
|
|
8161
|
+
placeholder: "Message every room",
|
|
8162
|
+
"aria-label": "Message every room"
|
|
8163
|
+
}
|
|
8164
|
+
),
|
|
8165
|
+
/* @__PURE__ */ jsx3("button", { type: "submit", className: "mx-meet__send", disabled: broadcast.trim().length === 0, children: "Send" })
|
|
8166
|
+
]
|
|
8167
|
+
}
|
|
8168
|
+
) : null,
|
|
8169
|
+
/* @__PURE__ */ jsx3(Notice, { notice }),
|
|
8170
|
+
isHost ? /* @__PURE__ */ jsx3(
|
|
8171
|
+
"button",
|
|
8172
|
+
{
|
|
8173
|
+
type: "button",
|
|
8174
|
+
className: "mx-meet__primary mx-meet__primary--small",
|
|
8175
|
+
onClick: () => void act({ action: "breakout_close" }).then(show),
|
|
8176
|
+
children: "Bring everyone back"
|
|
8177
|
+
}
|
|
8178
|
+
) : null
|
|
8179
|
+
] });
|
|
8180
|
+
}
|
|
8181
|
+
function BreakoutsPanel({ onClose }) {
|
|
8182
|
+
const { collab, isHost } = useCollab();
|
|
8183
|
+
const plan = collab?.breakout?.state === "open" ? collab.breakout : null;
|
|
8184
|
+
return /* @__PURE__ */ jsxs2(PanelShell, { title: "Breakout rooms", onClose, children: [
|
|
8185
|
+
collab?.error != null ? /* @__PURE__ */ jsx3("p", { className: "mx-meet__panel-note mx-meet__collab-error", children: collab.error }) : null,
|
|
8186
|
+
plan !== null ? /* @__PURE__ */ jsx3(BreakoutRun, { plan }) : isHost ? /* @__PURE__ */ jsx3(BreakoutSetup, {}) : /* @__PURE__ */ jsx3("p", { className: "mx-meet__panel-note", children: "Breakout rooms are closed." })
|
|
8187
|
+
] });
|
|
8188
|
+
}
|
|
8189
|
+
function BreakoutBanner() {
|
|
8190
|
+
const host = useMeetHost();
|
|
8191
|
+
const { collab, act, moveTo, localIdentity, breakoutRoomId } = useCollab();
|
|
8192
|
+
const plan = collab?.breakout ?? null;
|
|
8193
|
+
const open = plan?.state === "open" ? plan : null;
|
|
8194
|
+
const now = useNow(open?.endsAt != null);
|
|
8195
|
+
const remaining = breakoutRemainingMs(open, now);
|
|
8196
|
+
const assigned = assignedRoom(open, localIdentity);
|
|
8197
|
+
const [dismissedBroadcast, setDismissedBroadcast] = useState3(null);
|
|
8198
|
+
const [failure, setFailure] = useState3(null);
|
|
8199
|
+
const expireAsked = useRef3(null);
|
|
8200
|
+
const moveAt = collab?.moveRequest?.at ?? null;
|
|
8201
|
+
useEffect3(() => {
|
|
8202
|
+
const request = host?.store.snapshot().collab.moveRequest ?? null;
|
|
8203
|
+
if (request === null || host === null) return;
|
|
8204
|
+
host.store.patch({ collab: { ...host.store.snapshot().collab, moveRequest: null } });
|
|
8205
|
+
const here = host.store.snapshot().breakoutRoomId;
|
|
8206
|
+
if ((here ?? null) === request.roomId) return;
|
|
8207
|
+
void moveTo(request.roomId).then((result) => setFailure(result.ok ? null : result.message));
|
|
8208
|
+
}, [moveAt, host, moveTo]);
|
|
8209
|
+
useEffect3(() => {
|
|
8210
|
+
if (open === null || remaining === null || remaining > 0) return;
|
|
8211
|
+
if (expireAsked.current === open.id) return;
|
|
8212
|
+
expireAsked.current = open.id;
|
|
8213
|
+
void act({ action: "breakout_expire" });
|
|
8214
|
+
}, [open, remaining, act]);
|
|
8215
|
+
const broadcast = collab?.broadcast ?? null;
|
|
8216
|
+
const showBroadcast = broadcast !== null && broadcast.at !== dismissedBroadcast && open !== null;
|
|
8217
|
+
const room = open?.rooms.find((r) => r.id === breakoutRoomId) ?? null;
|
|
8218
|
+
if (open === null && failure === null) return null;
|
|
8219
|
+
return /* @__PURE__ */ jsxs2("div", { className: "mx-meet__breakout-banner", role: "status", children: [
|
|
8220
|
+
failure !== null ? /* @__PURE__ */ jsx3("span", { className: "mx-meet__collab-error", children: failure }) : null,
|
|
8221
|
+
room !== null ? /* @__PURE__ */ jsxs2("span", { children: [
|
|
8222
|
+
/* @__PURE__ */ jsx3("strong", { children: room.name }),
|
|
8223
|
+
remaining !== null ? ` \xB7 ${clock(remaining)} left` : "",
|
|
8224
|
+
/* @__PURE__ */ jsx3("button", { type: "button", className: "mx-meet__chip", onClick: () => void moveTo(null), children: "Return to main room" })
|
|
8225
|
+
] }) : assigned !== null ? /* @__PURE__ */ jsxs2("span", { children: [
|
|
8226
|
+
"You are assigned to ",
|
|
8227
|
+
/* @__PURE__ */ jsx3("strong", { children: assigned.name }),
|
|
8228
|
+
remaining !== null ? ` \xB7 ${clock(remaining)} left` : "",
|
|
8229
|
+
/* @__PURE__ */ jsx3(
|
|
8230
|
+
"button",
|
|
8231
|
+
{
|
|
8232
|
+
type: "button",
|
|
8233
|
+
className: "mx-meet__primary mx-meet__primary--small",
|
|
8234
|
+
onClick: () => void act({ action: "breakout_join", roomId: assigned.id }).then(async (said) => {
|
|
8235
|
+
const result = said.ok ? await moveTo(assigned.id) : said;
|
|
8236
|
+
setFailure(result.ok ? null : result.message);
|
|
8237
|
+
}),
|
|
8238
|
+
children: "Join"
|
|
8239
|
+
}
|
|
8240
|
+
)
|
|
8241
|
+
] }) : open?.allowChoose ? /* @__PURE__ */ jsx3("span", { children: "Breakout rooms are open \u2014 pick one under Activities." }) : null,
|
|
8242
|
+
showBroadcast ? /* @__PURE__ */ jsxs2("span", { className: "mx-meet__breakout-broadcast", children: [
|
|
8243
|
+
/* @__PURE__ */ jsxs2("strong", { children: [
|
|
8244
|
+
broadcast.by,
|
|
8245
|
+
":"
|
|
8246
|
+
] }),
|
|
8247
|
+
" ",
|
|
8248
|
+
broadcast.text,
|
|
8249
|
+
/* @__PURE__ */ jsx3("button", { type: "button", className: "mx-meet__link", onClick: () => setDismissedBroadcast(broadcast.at), children: "Dismiss" })
|
|
8250
|
+
] }) : null
|
|
8251
|
+
] });
|
|
8252
|
+
}
|
|
8253
|
+
function useCaptionTranslation(lines) {
|
|
8254
|
+
const host = useMeetHost();
|
|
8255
|
+
const snapshot = useMeetSnapshot();
|
|
8256
|
+
const collab = snapshot?.collab ?? null;
|
|
8257
|
+
const language = collab?.captionLanguage ?? null;
|
|
8258
|
+
const asked = useRef3(/* @__PURE__ */ new Set());
|
|
8259
|
+
const translations = collab?.captionTranslations ?? {};
|
|
8260
|
+
const missing = lines.filter((line) => line.final && translations[line.id] === void 0).map(({ id, text: text3 }) => ({ id, text: text3 }));
|
|
8261
|
+
const key = `${language ?? ""}|${missing.map((l) => l.id).join(",")}`;
|
|
8262
|
+
const pending = useRef3(missing);
|
|
8263
|
+
pending.current = missing;
|
|
8264
|
+
useEffect3(() => {
|
|
8265
|
+
if (host === null || language === null) return;
|
|
8266
|
+
const batch = pending.current.filter((line) => !asked.current.has(`${language}:${line.id}`)).slice(-20);
|
|
8267
|
+
if (batch.length === 0) return;
|
|
8268
|
+
for (const line of batch) asked.current.add(`${language}:${line.id}`);
|
|
8269
|
+
void host.inRoom.translateCaptions(language, batch).catch(() => void 0);
|
|
8270
|
+
}, [host, language, key]);
|
|
8271
|
+
return { language, translations, error: collab?.captionTranslationError ?? null };
|
|
8272
|
+
}
|
|
8273
|
+
function CaptionLanguageSettings() {
|
|
8274
|
+
const host = useMeetHost();
|
|
8275
|
+
const snapshot = useMeetSnapshot();
|
|
8276
|
+
const collab = snapshot?.collab ?? null;
|
|
8277
|
+
const settings = collab?.settings ?? null;
|
|
8278
|
+
if (host === null || settings === null || !settings.captionTranslationEnabled) return null;
|
|
8279
|
+
const viewer = typeof navigator !== "undefined" && typeof navigator.language === "string" ? navigator.language.slice(0, 2) : null;
|
|
8280
|
+
const preferred = defaultCaptionLanguage(settings, viewer);
|
|
8281
|
+
const current = collab?.captionLanguage ?? "";
|
|
8282
|
+
const choices = CAPTION_LANGUAGES.some((l) => l.tag === preferred) ? CAPTION_LANGUAGES : [{ tag: preferred, name: preferred }, ...CAPTION_LANGUAGES];
|
|
8283
|
+
return /* @__PURE__ */ jsxs2("section", { className: "mx-meet__section", "aria-label": "Captions", children: [
|
|
8284
|
+
/* @__PURE__ */ jsxs2("label", { className: "mx-meet__field", children: [
|
|
8285
|
+
/* @__PURE__ */ jsx3("span", { className: "mx-meet__field-label", children: "Translate captions to" }),
|
|
8286
|
+
/* @__PURE__ */ jsxs2(
|
|
8287
|
+
"select",
|
|
8288
|
+
{
|
|
8289
|
+
className: "mx-meet__select",
|
|
8290
|
+
value: current,
|
|
8291
|
+
onChange: (event) => {
|
|
8292
|
+
const next = event.target.value === "" ? null : event.target.value;
|
|
8293
|
+
host.store.patch({
|
|
8294
|
+
collab: {
|
|
8295
|
+
...host.store.snapshot().collab,
|
|
8296
|
+
captionLanguage: next,
|
|
8297
|
+
captionTranslations: {},
|
|
8298
|
+
captionTranslationError: null
|
|
8299
|
+
}
|
|
8300
|
+
});
|
|
8301
|
+
},
|
|
8302
|
+
children: [
|
|
8303
|
+
/* @__PURE__ */ jsx3("option", { value: "", children: "Off \u2014 as spoken" }),
|
|
8304
|
+
current === "" ? /* @__PURE__ */ jsxs2("option", { value: preferred, children: [
|
|
8305
|
+
choices.find((c) => c.tag === preferred)?.name ?? preferred,
|
|
8306
|
+
" (yours)"
|
|
8307
|
+
] }) : null,
|
|
8308
|
+
choices.filter((choice) => current !== "" || choice.tag !== preferred).map((choice) => /* @__PURE__ */ jsx3("option", { value: choice.tag, children: choice.name }, choice.tag))
|
|
8309
|
+
]
|
|
8310
|
+
}
|
|
8311
|
+
)
|
|
8312
|
+
] }),
|
|
8313
|
+
collab?.captionTranslationError != null ? /* @__PURE__ */ jsx3("p", { className: "mx-meet__panel-note mx-meet__collab-error", children: collab.captionTranslationError }) : null
|
|
8314
|
+
] });
|
|
8315
|
+
}
|
|
8316
|
+
function useCollabPanelRequest(onRequest) {
|
|
8317
|
+
const host = useMeetHost();
|
|
8318
|
+
const at = useMeetSnapshot()?.collab.panelRequest?.at ?? null;
|
|
8319
|
+
const callback = useRef3(onRequest);
|
|
8320
|
+
callback.current = onRequest;
|
|
8321
|
+
useEffect3(() => {
|
|
8322
|
+
const request = host?.store.snapshot().collab.panelRequest ?? null;
|
|
8323
|
+
if (request === null || host === null) return;
|
|
8324
|
+
host.store.patch({ collab: { ...host.store.snapshot().collab, panelRequest: null } });
|
|
8325
|
+
callback.current(request.panel);
|
|
8326
|
+
}, [at, host]);
|
|
8327
|
+
}
|
|
8328
|
+
|
|
8329
|
+
// src/react/components.tsx
|
|
8330
|
+
import { Fragment, jsx as jsx4, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
8331
|
+
function InertNotice({ what }) {
|
|
8332
|
+
return /* @__PURE__ */ jsxs3("div", { className: "mx-meet__empty", role: "status", children: [
|
|
8333
|
+
/* @__PURE__ */ jsxs3("p", { className: "mx-meet__empty-title", children: [
|
|
8334
|
+
what,
|
|
8335
|
+
" is not ready yet"
|
|
8336
|
+
] }),
|
|
8337
|
+
/* @__PURE__ */ jsx4("p", { className: "mx-meet__empty-body", children: "Calls and meetings need a signed-in identity and an active organization. This will appear as soon as they resolve." })
|
|
8338
|
+
] });
|
|
8339
|
+
}
|
|
8340
|
+
function Avatar({
|
|
8341
|
+
name,
|
|
8342
|
+
url,
|
|
8343
|
+
size = 40
|
|
8344
|
+
}) {
|
|
8345
|
+
const tint = avatarPaletteIndex(name);
|
|
8346
|
+
if (url != null && url.length > 0) {
|
|
8347
|
+
return /* @__PURE__ */ jsx4(
|
|
8348
|
+
"img",
|
|
8349
|
+
{
|
|
8350
|
+
className: "mx-meet__avatar",
|
|
8351
|
+
src: url,
|
|
8352
|
+
alt: "",
|
|
8353
|
+
width: size,
|
|
8354
|
+
height: size,
|
|
8355
|
+
style: { width: size, height: size }
|
|
8356
|
+
}
|
|
8357
|
+
);
|
|
8358
|
+
}
|
|
8359
|
+
return /* @__PURE__ */ jsx4(
|
|
8360
|
+
"span",
|
|
8361
|
+
{
|
|
8362
|
+
className: "mx-meet__avatar mx-meet__avatar--initials",
|
|
8363
|
+
style: {
|
|
8364
|
+
width: size,
|
|
8365
|
+
height: size,
|
|
8366
|
+
fontSize: Math.round(size * 0.38),
|
|
8367
|
+
background: `var(--mx-meet-avatar-${tint})`
|
|
8368
|
+
},
|
|
8369
|
+
"aria-hidden": "true",
|
|
8370
|
+
children: getInitials(name)
|
|
8371
|
+
}
|
|
8372
|
+
);
|
|
8373
|
+
}
|
|
8374
|
+
function ControlButton({
|
|
8375
|
+
label,
|
|
8376
|
+
active = false,
|
|
8377
|
+
danger = false,
|
|
8378
|
+
onClick,
|
|
8379
|
+
children
|
|
8380
|
+
}) {
|
|
8381
|
+
return /* @__PURE__ */ jsx4(
|
|
6746
8382
|
"button",
|
|
6747
8383
|
{
|
|
6748
8384
|
type: "button",
|
|
@@ -6761,14 +8397,14 @@ function ControlButton({
|
|
|
6761
8397
|
function RecordingIndicator() {
|
|
6762
8398
|
const { state, label } = useRecording();
|
|
6763
8399
|
if (label === null) return null;
|
|
6764
|
-
return /* @__PURE__ */
|
|
8400
|
+
return /* @__PURE__ */ jsxs3(
|
|
6765
8401
|
"span",
|
|
6766
8402
|
{
|
|
6767
8403
|
className: `mx-meet__recording mx-meet__recording--${state}`,
|
|
6768
8404
|
role: "status",
|
|
6769
8405
|
"aria-live": "polite",
|
|
6770
8406
|
children: [
|
|
6771
|
-
/* @__PURE__ */
|
|
8407
|
+
/* @__PURE__ */ jsx4(RecordIcon, { width: 10, height: 10 }),
|
|
6772
8408
|
label
|
|
6773
8409
|
]
|
|
6774
8410
|
}
|
|
@@ -6776,12 +8412,12 @@ function RecordingIndicator() {
|
|
|
6776
8412
|
}
|
|
6777
8413
|
function ConnectionDot({ quality }) {
|
|
6778
8414
|
if (quality === "excellent" || quality === "good" || quality === "unknown") return null;
|
|
6779
|
-
return /* @__PURE__ */
|
|
8415
|
+
return /* @__PURE__ */ jsx4("span", { className: `mx-meet__quality mx-meet__quality--${quality}`, title: `Connection ${quality}`, children: /* @__PURE__ */ jsx4(WifiLowIcon, { width: 14, height: 14 }) });
|
|
6780
8416
|
}
|
|
6781
8417
|
function RoleBadge({ role }) {
|
|
6782
|
-
if (role === "host") return /* @__PURE__ */
|
|
6783
|
-
if (role === "cohost") return /* @__PURE__ */
|
|
6784
|
-
if (role === "guest") return /* @__PURE__ */
|
|
8418
|
+
if (role === "host") return /* @__PURE__ */ jsx4("span", { className: "mx-meet__badge", children: "Host" });
|
|
8419
|
+
if (role === "cohost") return /* @__PURE__ */ jsx4("span", { className: "mx-meet__badge", children: "Co-host" });
|
|
8420
|
+
if (role === "guest") return /* @__PURE__ */ jsx4("span", { className: "mx-meet__badge", children: "Guest" });
|
|
6785
8421
|
return null;
|
|
6786
8422
|
}
|
|
6787
8423
|
function ParticipantTile({
|
|
@@ -6791,7 +8427,7 @@ function ParticipantTile({
|
|
|
6791
8427
|
const host = useMeetHost();
|
|
6792
8428
|
const snapshot = useMeetSnapshot();
|
|
6793
8429
|
const queue = useHandQueue();
|
|
6794
|
-
const [menu, setMenu] =
|
|
8430
|
+
const [menu, setMenu] = useState4(false);
|
|
6795
8431
|
const videoRef = useTrack(
|
|
6796
8432
|
participant.identity,
|
|
6797
8433
|
participant.screenSharing ? "screen" : "camera"
|
|
@@ -6800,7 +8436,7 @@ function ParticipantTile({
|
|
|
6800
8436
|
const pinnedHere = snapshot?.pinned === participant.identity;
|
|
6801
8437
|
const spotlit = snapshot?.spotlight === participant.identity;
|
|
6802
8438
|
const handPosition = participant.handRaised ? queue.findIndex((entry) => entry.identity === participant.identity) + 1 : 0;
|
|
6803
|
-
return /* @__PURE__ */
|
|
8439
|
+
return /* @__PURE__ */ jsxs3(
|
|
6804
8440
|
"div",
|
|
6805
8441
|
{
|
|
6806
8442
|
className: [
|
|
@@ -6810,7 +8446,7 @@ function ParticipantTile({
|
|
|
6810
8446
|
].filter(Boolean).join(" "),
|
|
6811
8447
|
"data-identity": participant.identity,
|
|
6812
8448
|
children: [
|
|
6813
|
-
showVideo ? /* @__PURE__ */
|
|
8449
|
+
showVideo ? /* @__PURE__ */ jsx4(
|
|
6814
8450
|
"video",
|
|
6815
8451
|
{
|
|
6816
8452
|
ref: videoRef,
|
|
@@ -6819,43 +8455,43 @@ function ParticipantTile({
|
|
|
6819
8455
|
playsInline: true,
|
|
6820
8456
|
muted: participant.isLocal
|
|
6821
8457
|
}
|
|
6822
|
-
) : /* @__PURE__ */
|
|
6823
|
-
participant.handRaised ? /* @__PURE__ */
|
|
6824
|
-
/* @__PURE__ */
|
|
8458
|
+
) : /* @__PURE__ */ jsx4("div", { className: "mx-meet__tile-placeholder", children: /* @__PURE__ */ jsx4(Avatar, { name: participant.displayName, url: participant.avatarUrl, size: featured ? 96 : 56 }) }),
|
|
8459
|
+
participant.handRaised ? /* @__PURE__ */ jsxs3("span", { className: "mx-meet__tile-hand", title: `Hand raised \xB7 ${ordinal(handPosition)} in line`, children: [
|
|
8460
|
+
/* @__PURE__ */ jsx4(HandIcon, { width: 14, height: 14 }),
|
|
6825
8461
|
handPosition > 0 ? handPosition : null
|
|
6826
8462
|
] }) : null,
|
|
6827
|
-
/* @__PURE__ */
|
|
6828
|
-
/* @__PURE__ */
|
|
6829
|
-
spotlit ? /* @__PURE__ */
|
|
8463
|
+
/* @__PURE__ */ jsxs3("div", { className: "mx-meet__tile-bar", children: [
|
|
8464
|
+
/* @__PURE__ */ jsxs3("span", { className: "mx-meet__tile-name", children: [
|
|
8465
|
+
spotlit ? /* @__PURE__ */ jsx4("span", { title: "Spotlighted for everyone", className: "mx-meet__tile-flag", children: /* @__PURE__ */ jsx4(SpotlightIcon, { width: 12, height: 12 }) }) : null,
|
|
6830
8466
|
participant.displayName,
|
|
6831
8467
|
participant.isLocal ? " (you)" : "",
|
|
6832
|
-
participant.isAgent ? /* @__PURE__ */
|
|
6833
|
-
/* @__PURE__ */
|
|
8468
|
+
participant.isAgent ? /* @__PURE__ */ jsx4("span", { className: "mx-meet__badge", children: "AI" }) : null,
|
|
8469
|
+
/* @__PURE__ */ jsx4(RoleBadge, { role: participant.role })
|
|
6834
8470
|
] }),
|
|
6835
|
-
!participant.micEnabled ? /* @__PURE__ */
|
|
6836
|
-
/* @__PURE__ */
|
|
8471
|
+
!participant.micEnabled ? /* @__PURE__ */ jsx4(MicOffIcon, { width: 14, height: 14 }) : null,
|
|
8472
|
+
/* @__PURE__ */ jsx4(QualityBars, { quality: participant.quality })
|
|
6837
8473
|
] }),
|
|
6838
|
-
/* @__PURE__ */
|
|
6839
|
-
/* @__PURE__ */
|
|
8474
|
+
/* @__PURE__ */ jsxs3("div", { className: menu ? "mx-meet__tile-actions mx-meet__tile-actions--open" : "mx-meet__tile-actions", children: [
|
|
8475
|
+
/* @__PURE__ */ jsx4(
|
|
6840
8476
|
ControlButton,
|
|
6841
8477
|
{
|
|
6842
8478
|
label: pinnedHere ? "Unpin" : `Pin ${participant.displayName} for me`,
|
|
6843
8479
|
active: pinnedHere,
|
|
6844
8480
|
onClick: () => host?.engine.pin(pinnedHere ? null : participant.identity),
|
|
6845
|
-
children: /* @__PURE__ */
|
|
8481
|
+
children: /* @__PURE__ */ jsx4(PinIcon, { width: 16, height: 16 })
|
|
6846
8482
|
}
|
|
6847
8483
|
),
|
|
6848
|
-
/* @__PURE__ */
|
|
6849
|
-
/* @__PURE__ */
|
|
8484
|
+
/* @__PURE__ */ jsxs3("span", { className: "mx-meet__anchor", children: [
|
|
8485
|
+
/* @__PURE__ */ jsx4(
|
|
6850
8486
|
ControlButton,
|
|
6851
8487
|
{
|
|
6852
8488
|
label: `More for ${participant.displayName}`,
|
|
6853
8489
|
active: menu,
|
|
6854
8490
|
onClick: () => setMenu(!menu),
|
|
6855
|
-
children: /* @__PURE__ */
|
|
8491
|
+
children: /* @__PURE__ */ jsx4(MoreIcon, { width: 16, height: 16 })
|
|
6856
8492
|
}
|
|
6857
8493
|
),
|
|
6858
|
-
menu ? /* @__PURE__ */
|
|
8494
|
+
menu ? /* @__PURE__ */ jsx4(PersonMenu, { participant, onClose: () => setMenu(false), placement: "down" }) : null
|
|
6859
8495
|
] })
|
|
6860
8496
|
] })
|
|
6861
8497
|
]
|
|
@@ -6871,28 +8507,28 @@ function QualityBars({ quality }) {
|
|
|
6871
8507
|
if (quality === "unknown") return null;
|
|
6872
8508
|
const bars = quality === "excellent" ? 3 : quality === "good" ? 2 : quality === "poor" ? 1 : 0;
|
|
6873
8509
|
const label = quality === "lost" ? "Connection lost" : quality === "poor" ? "Poor connection" : `Connection ${quality}`;
|
|
6874
|
-
return /* @__PURE__ */
|
|
8510
|
+
return /* @__PURE__ */ jsx4("span", { className: `mx-meet__signal mx-meet__signal--${quality}`, title: label, "aria-label": label, role: "img", children: /* @__PURE__ */ jsx4(SignalIcon, { bars, width: 14, height: 14 }) });
|
|
6875
8511
|
}
|
|
6876
8512
|
function Stage({ pageSize }) {
|
|
6877
8513
|
const stage = useStage(pageSize);
|
|
6878
8514
|
const columns = gridColumns(stage.tiles.length);
|
|
6879
8515
|
if (stage.feature === null && stage.tiles.length === 0) {
|
|
6880
|
-
return /* @__PURE__ */
|
|
6881
|
-
/* @__PURE__ */
|
|
6882
|
-
/* @__PURE__ */
|
|
8516
|
+
return /* @__PURE__ */ jsxs3("div", { className: "mx-meet__stage mx-meet__stage--empty", children: [
|
|
8517
|
+
/* @__PURE__ */ jsx4("p", { className: "mx-meet__empty-title", children: "Waiting for others to join" }),
|
|
8518
|
+
/* @__PURE__ */ jsx4("p", { className: "mx-meet__empty-body", children: "Share the meeting link and people can join from anywhere \u2014 no account needed." })
|
|
6883
8519
|
] });
|
|
6884
8520
|
}
|
|
6885
|
-
return /* @__PURE__ */
|
|
6886
|
-
stage.feature !== null ? /* @__PURE__ */
|
|
6887
|
-
/* @__PURE__ */
|
|
8521
|
+
return /* @__PURE__ */ jsxs3("div", { className: `mx-meet__stage${stage.feature !== null ? " mx-meet__stage--speaker" : ""}`, children: [
|
|
8522
|
+
stage.feature !== null ? /* @__PURE__ */ jsx4(ParticipantTile, { participant: stage.feature, featured: true }) : null,
|
|
8523
|
+
/* @__PURE__ */ jsx4(
|
|
6888
8524
|
"div",
|
|
6889
8525
|
{
|
|
6890
8526
|
className: "mx-meet__grid",
|
|
6891
8527
|
style: { "--mx-meet-columns": columns },
|
|
6892
|
-
children: stage.tiles.map((participant) => /* @__PURE__ */
|
|
8528
|
+
children: stage.tiles.map((participant) => /* @__PURE__ */ jsx4(ParticipantTile, { participant }, participant.identity))
|
|
6893
8529
|
}
|
|
6894
8530
|
),
|
|
6895
|
-
stage.overflow > 0 ? /* @__PURE__ */
|
|
8531
|
+
stage.overflow > 0 ? /* @__PURE__ */ jsxs3("p", { className: "mx-meet__overflow", children: [
|
|
6896
8532
|
"+",
|
|
6897
8533
|
stage.overflow,
|
|
6898
8534
|
" more ",
|
|
@@ -6905,20 +8541,28 @@ var MEET_REACTIONS = ["\u{1F496}", "\u{1F44D}", "\u{1F389}", "\u{1F44F}", "\u{1F
|
|
|
6905
8541
|
function ControlBar({ onLeave }) {
|
|
6906
8542
|
const room = useRoom();
|
|
6907
8543
|
const recording = useRecording();
|
|
6908
|
-
const [panel, setPanel] =
|
|
6909
|
-
const [chatTo, setChatTo] =
|
|
6910
|
-
const [popover, setPopover] =
|
|
6911
|
-
const [shortcuts, setShortcuts] =
|
|
8544
|
+
const [panel, setPanel] = useState4("none");
|
|
8545
|
+
const [chatTo, setChatTo] = useState4(null);
|
|
8546
|
+
const [popover, setPopover] = useState4("none");
|
|
8547
|
+
const [shortcuts, setShortcuts] = useState4(false);
|
|
6912
8548
|
const snapshot = useMeetSnapshot();
|
|
6913
8549
|
const lobby = useLobby();
|
|
6914
8550
|
const controls = useHostControls();
|
|
6915
8551
|
const queue = useHandQueue();
|
|
6916
8552
|
const micUnavailable = useLocalMedia().microphone.unavailable;
|
|
6917
8553
|
const unread = useUnreadChat(panel === "chat");
|
|
8554
|
+
const [whiteboard, setWhiteboard] = useState4(false);
|
|
6918
8555
|
const toggle = (next) => setPanel(panel === next ? "none" : next);
|
|
8556
|
+
const openActivity = (activity) => {
|
|
8557
|
+
if (activity === "whiteboard") setWhiteboard(true);
|
|
8558
|
+
else setPanel(activity);
|
|
8559
|
+
};
|
|
8560
|
+
useCollabPanelRequest((activity) => {
|
|
8561
|
+
if (!controls.isHost) openActivity(activity);
|
|
8562
|
+
});
|
|
6919
8563
|
const privateChatAt = snapshot?.privateChatRequest?.at ?? null;
|
|
6920
8564
|
const meetStore = useMeetHost()?.store ?? null;
|
|
6921
|
-
|
|
8565
|
+
useEffect4(() => {
|
|
6922
8566
|
const request = meetStore?.snapshot().privateChatRequest ?? null;
|
|
6923
8567
|
if (request === null) return;
|
|
6924
8568
|
setChatTo(request.to);
|
|
@@ -6934,11 +8578,11 @@ function ControlBar({ onLeave }) {
|
|
|
6934
8578
|
help: () => setShortcuts(true)
|
|
6935
8579
|
});
|
|
6936
8580
|
const hasSpotlight = snapshot?.spotlight !== null && snapshot?.spotlight !== void 0;
|
|
6937
|
-
return /* @__PURE__ */
|
|
6938
|
-
/* @__PURE__ */
|
|
6939
|
-
shortcuts ? /* @__PURE__ */
|
|
6940
|
-
panel === "chat" ? /* @__PURE__ */
|
|
6941
|
-
panel === "people" ? /* @__PURE__ */
|
|
8581
|
+
return /* @__PURE__ */ jsxs3(Fragment, { children: [
|
|
8582
|
+
/* @__PURE__ */ jsx4(MeetingOverlays, {}),
|
|
8583
|
+
shortcuts ? /* @__PURE__ */ jsx4(ShortcutsSheet, { onClose: () => setShortcuts(false) }) : null,
|
|
8584
|
+
panel === "chat" ? /* @__PURE__ */ jsx4(ChatPanel, { onClose: () => setPanel("none"), to: chatTo, onTo: setChatTo }) : null,
|
|
8585
|
+
panel === "people" ? /* @__PURE__ */ jsx4(
|
|
6942
8586
|
PeoplePanel,
|
|
6943
8587
|
{
|
|
6944
8588
|
onClose: () => setPanel("none"),
|
|
@@ -6948,48 +8592,53 @@ function ControlBar({ onLeave }) {
|
|
|
6948
8592
|
}
|
|
6949
8593
|
}
|
|
6950
8594
|
) : null,
|
|
6951
|
-
panel === "ai" ? /* @__PURE__ */
|
|
6952
|
-
panel === "settings" ? /* @__PURE__ */
|
|
6953
|
-
|
|
6954
|
-
/* @__PURE__ */
|
|
6955
|
-
|
|
8595
|
+
panel === "ai" ? /* @__PURE__ */ jsx4(AiPanel, { onClose: () => setPanel("none") }) : null,
|
|
8596
|
+
panel === "settings" ? /* @__PURE__ */ jsx4(SettingsPanel, { onClose: () => setPanel("none") }) : null,
|
|
8597
|
+
panel === "polls" ? /* @__PURE__ */ jsx4(PollsPanel, { onClose: () => setPanel("none") }) : null,
|
|
8598
|
+
panel === "qa" ? /* @__PURE__ */ jsx4(QaPanel, { onClose: () => setPanel("none") }) : null,
|
|
8599
|
+
panel === "breakouts" ? /* @__PURE__ */ jsx4(BreakoutsPanel, { onClose: () => setPanel("none") }) : null,
|
|
8600
|
+
whiteboard ? /* @__PURE__ */ jsx4(WhiteboardPanel, { onClose: () => setWhiteboard(false) }) : null,
|
|
8601
|
+
/* @__PURE__ */ jsx4(BreakoutBanner, {}),
|
|
8602
|
+
controls.notice !== null && panel !== "people" ? /* @__PURE__ */ jsx4(Toast, { text: controls.notice.text, failed: controls.notice.failed, onDone: controls.clearNotice }) : null,
|
|
8603
|
+
/* @__PURE__ */ jsxs3("div", { className: "mx-meet__controls", children: [
|
|
8604
|
+
/* @__PURE__ */ jsx4(
|
|
6956
8605
|
ControlButton,
|
|
6957
8606
|
{
|
|
6958
8607
|
label: micUnavailable !== null ? `Unmute \u2014 ${micUnavailable.remedy}` : room.local?.micEnabled === true ? "Mute (\u2318D)" : "Unmute (\u2318D)",
|
|
6959
8608
|
active: room.local?.micEnabled === true,
|
|
6960
8609
|
onClick: () => void room.toggleMicrophone(),
|
|
6961
|
-
children: room.local?.micEnabled === true ? /* @__PURE__ */
|
|
8610
|
+
children: room.local?.micEnabled === true ? /* @__PURE__ */ jsx4(MicIcon, {}) : /* @__PURE__ */ jsx4(MicOffIcon, {})
|
|
6962
8611
|
}
|
|
6963
8612
|
),
|
|
6964
|
-
/* @__PURE__ */
|
|
8613
|
+
/* @__PURE__ */ jsx4(
|
|
6965
8614
|
ControlButton,
|
|
6966
8615
|
{
|
|
6967
8616
|
label: room.local?.cameraEnabled === true ? "Stop video (\u2318E)" : "Start video (\u2318E)",
|
|
6968
8617
|
active: room.local?.cameraEnabled === true,
|
|
6969
8618
|
onClick: () => void room.toggleCamera(),
|
|
6970
|
-
children: room.local?.cameraEnabled === true ? /* @__PURE__ */
|
|
8619
|
+
children: room.local?.cameraEnabled === true ? /* @__PURE__ */ jsx4(CameraIcon, {}) : /* @__PURE__ */ jsx4(CameraOffIcon, {})
|
|
6971
8620
|
}
|
|
6972
8621
|
),
|
|
6973
|
-
/* @__PURE__ */
|
|
8622
|
+
/* @__PURE__ */ jsx4(
|
|
6974
8623
|
ControlButton,
|
|
6975
8624
|
{
|
|
6976
8625
|
label: room.local?.screenSharing === true ? "Stop sharing" : "Share screen",
|
|
6977
8626
|
active: room.local?.screenSharing === true,
|
|
6978
8627
|
onClick: () => void room.toggleScreenShare(),
|
|
6979
|
-
children: /* @__PURE__ */
|
|
8628
|
+
children: /* @__PURE__ */ jsx4(ScreenShareIcon, {})
|
|
6980
8629
|
}
|
|
6981
8630
|
),
|
|
6982
|
-
/* @__PURE__ */
|
|
6983
|
-
/* @__PURE__ */
|
|
8631
|
+
/* @__PURE__ */ jsxs3("span", { className: "mx-meet__anchor", children: [
|
|
8632
|
+
/* @__PURE__ */ jsx4(
|
|
6984
8633
|
ControlButton,
|
|
6985
8634
|
{
|
|
6986
8635
|
label: "Send a reaction",
|
|
6987
8636
|
active: popover === "reactions",
|
|
6988
8637
|
onClick: () => setPopover(popover === "reactions" ? "none" : "reactions"),
|
|
6989
|
-
children: /* @__PURE__ */
|
|
8638
|
+
children: /* @__PURE__ */ jsx4(SmileIcon, {})
|
|
6990
8639
|
}
|
|
6991
8640
|
),
|
|
6992
|
-
popover === "reactions" ? /* @__PURE__ */
|
|
8641
|
+
popover === "reactions" ? /* @__PURE__ */ jsx4(Popover, { label: "Reactions", onClose: () => setPopover("none"), children: /* @__PURE__ */ jsx4("div", { className: "mx-meet__emoji-bar", children: MEET_REACTIONS.map((emoji) => /* @__PURE__ */ jsx4(
|
|
6993
8642
|
"button",
|
|
6994
8643
|
{
|
|
6995
8644
|
type: "button",
|
|
@@ -7001,46 +8650,53 @@ function ControlBar({ onLeave }) {
|
|
|
7001
8650
|
emoji
|
|
7002
8651
|
)) }) }) : null
|
|
7003
8652
|
] }),
|
|
7004
|
-
/* @__PURE__ */
|
|
8653
|
+
/* @__PURE__ */ jsx4(
|
|
7005
8654
|
ControlButton,
|
|
7006
8655
|
{
|
|
7007
8656
|
label: room.local?.handRaised === true ? "Lower hand (\u2318\u2325H)" : "Raise hand (\u2318\u2325H)",
|
|
7008
8657
|
active: room.local?.handRaised === true,
|
|
7009
8658
|
onClick: () => void room.toggleHand(),
|
|
7010
|
-
children: /* @__PURE__ */
|
|
8659
|
+
children: /* @__PURE__ */ jsx4(HandIcon, {})
|
|
7011
8660
|
}
|
|
7012
8661
|
),
|
|
7013
|
-
/* @__PURE__ */
|
|
7014
|
-
/* @__PURE__ */
|
|
7015
|
-
unread > 0 ? /* @__PURE__ */
|
|
8662
|
+
/* @__PURE__ */ jsxs3(ControlButton, { label: "Chat (\u2318\u2325C)", active: panel === "chat", onClick: () => toggle("chat"), children: [
|
|
8663
|
+
/* @__PURE__ */ jsx4(ChatIcon, {}),
|
|
8664
|
+
unread > 0 ? /* @__PURE__ */ jsx4("span", { className: "mx-meet__dot", "aria-hidden": "true" }) : null
|
|
7016
8665
|
] }),
|
|
7017
|
-
/* @__PURE__ */
|
|
8666
|
+
/* @__PURE__ */ jsxs3(
|
|
7018
8667
|
ControlButton,
|
|
7019
8668
|
{
|
|
7020
8669
|
label: lobby.waiting.length > 0 ? `People \u2014 ${lobby.waiting.length} waiting` : `People \u2014 ${(snapshot?.participants ?? []).length} in the meeting`,
|
|
7021
8670
|
active: panel === "people",
|
|
7022
8671
|
onClick: () => toggle("people"),
|
|
7023
8672
|
children: [
|
|
7024
|
-
/* @__PURE__ */
|
|
7025
|
-
lobby.waiting.length > 0 || controls.isHost && queue.length > 0 ? /* @__PURE__ */
|
|
8673
|
+
/* @__PURE__ */ jsx4(PeopleIcon, {}),
|
|
8674
|
+
lobby.waiting.length > 0 || controls.isHost && queue.length > 0 ? /* @__PURE__ */ jsx4("span", { className: "mx-meet__dot", "aria-hidden": "true" }) : null
|
|
7026
8675
|
]
|
|
7027
8676
|
}
|
|
7028
8677
|
),
|
|
7029
|
-
/* @__PURE__ */
|
|
7030
|
-
|
|
7031
|
-
|
|
7032
|
-
|
|
7033
|
-
|
|
8678
|
+
/* @__PURE__ */ jsx4(
|
|
8679
|
+
ActivitiesControl,
|
|
8680
|
+
{
|
|
8681
|
+
active: whiteboard ? "whiteboard" : panel === "polls" || panel === "qa" || panel === "breakouts" ? panel : null,
|
|
8682
|
+
onOpen: openActivity
|
|
8683
|
+
}
|
|
8684
|
+
),
|
|
8685
|
+
/* @__PURE__ */ jsx4(AiControl, { active: panel === "ai", onToggle: () => toggle("ai") }),
|
|
8686
|
+
recording.canStart ? /* @__PURE__ */ jsx4(ControlButton, { label: "Start recording", onClick: () => void recording.start(), children: /* @__PURE__ */ jsx4(RecordIcon, {}) }) : null,
|
|
8687
|
+
recording.canStop ? /* @__PURE__ */ jsx4(ControlButton, { label: "Stop recording", active: true, onClick: () => void recording.stop(), children: /* @__PURE__ */ jsx4(RecordIcon, {}) }) : null,
|
|
8688
|
+
/* @__PURE__ */ jsxs3("span", { className: "mx-meet__anchor", children: [
|
|
8689
|
+
/* @__PURE__ */ jsx4(
|
|
7034
8690
|
ControlButton,
|
|
7035
8691
|
{
|
|
7036
8692
|
label: "More options",
|
|
7037
8693
|
active: popover === "more" || panel === "settings",
|
|
7038
8694
|
onClick: () => setPopover(popover === "more" ? "none" : "more"),
|
|
7039
|
-
children: /* @__PURE__ */
|
|
8695
|
+
children: /* @__PURE__ */ jsx4(MoreIcon, {})
|
|
7040
8696
|
}
|
|
7041
8697
|
),
|
|
7042
|
-
popover === "more" ? /* @__PURE__ */
|
|
7043
|
-
/* @__PURE__ */
|
|
8698
|
+
popover === "more" ? /* @__PURE__ */ jsx4(Popover, { label: "More options", onClose: () => setPopover("none"), children: /* @__PURE__ */ jsxs3("div", { className: "mx-meet__menu", role: "menu", children: [
|
|
8699
|
+
/* @__PURE__ */ jsxs3(
|
|
7044
8700
|
MenuItem,
|
|
7045
8701
|
{
|
|
7046
8702
|
onSelect: () => {
|
|
@@ -7048,12 +8704,12 @@ function ControlBar({ onLeave }) {
|
|
|
7048
8704
|
setPanel("settings");
|
|
7049
8705
|
},
|
|
7050
8706
|
children: [
|
|
7051
|
-
/* @__PURE__ */
|
|
7052
|
-
"
|
|
8707
|
+
/* @__PURE__ */ jsx4(SettingsIcon, { width: 16, height: 16 }),
|
|
8708
|
+
" Settings"
|
|
7053
8709
|
]
|
|
7054
8710
|
}
|
|
7055
8711
|
),
|
|
7056
|
-
/* @__PURE__ */
|
|
8712
|
+
/* @__PURE__ */ jsxs3(
|
|
7057
8713
|
MenuItem,
|
|
7058
8714
|
{
|
|
7059
8715
|
onSelect: () => {
|
|
@@ -7061,14 +8717,14 @@ function ControlBar({ onLeave }) {
|
|
|
7061
8717
|
setShortcuts(true);
|
|
7062
8718
|
},
|
|
7063
8719
|
children: [
|
|
7064
|
-
/* @__PURE__ */
|
|
8720
|
+
/* @__PURE__ */ jsx4(KeyboardIcon, { width: 16, height: 16 }),
|
|
7065
8721
|
" Keyboard shortcuts"
|
|
7066
8722
|
]
|
|
7067
8723
|
}
|
|
7068
8724
|
),
|
|
7069
|
-
controls.isHost ? /* @__PURE__ */
|
|
7070
|
-
/* @__PURE__ */
|
|
7071
|
-
/* @__PURE__ */
|
|
8725
|
+
controls.isHost ? /* @__PURE__ */ jsxs3(Fragment, { children: [
|
|
8726
|
+
/* @__PURE__ */ jsx4("div", { className: "mx-meet__menu-sep", role: "separator" }),
|
|
8727
|
+
/* @__PURE__ */ jsxs3(
|
|
7072
8728
|
MenuItem,
|
|
7073
8729
|
{
|
|
7074
8730
|
onSelect: () => {
|
|
@@ -7076,12 +8732,12 @@ function ControlBar({ onLeave }) {
|
|
|
7076
8732
|
void controls.run({ action: "mute_all" });
|
|
7077
8733
|
},
|
|
7078
8734
|
children: [
|
|
7079
|
-
/* @__PURE__ */
|
|
8735
|
+
/* @__PURE__ */ jsx4(MicOffIcon, { width: 16, height: 16 }),
|
|
7080
8736
|
" Mute everyone"
|
|
7081
8737
|
]
|
|
7082
8738
|
}
|
|
7083
8739
|
),
|
|
7084
|
-
/* @__PURE__ */
|
|
8740
|
+
/* @__PURE__ */ jsxs3(
|
|
7085
8741
|
MenuItem,
|
|
7086
8742
|
{
|
|
7087
8743
|
onSelect: () => {
|
|
@@ -7089,12 +8745,12 @@ function ControlBar({ onLeave }) {
|
|
|
7089
8745
|
void controls.run({ action: "ask_all_unmute" });
|
|
7090
8746
|
},
|
|
7091
8747
|
children: [
|
|
7092
|
-
/* @__PURE__ */
|
|
8748
|
+
/* @__PURE__ */ jsx4(MicIcon, { width: 16, height: 16 }),
|
|
7093
8749
|
" Ask everyone to unmute"
|
|
7094
8750
|
]
|
|
7095
8751
|
}
|
|
7096
8752
|
),
|
|
7097
|
-
queue.length > 0 ? /* @__PURE__ */
|
|
8753
|
+
queue.length > 0 ? /* @__PURE__ */ jsxs3(
|
|
7098
8754
|
MenuItem,
|
|
7099
8755
|
{
|
|
7100
8756
|
onSelect: () => {
|
|
@@ -7102,14 +8758,14 @@ function ControlBar({ onLeave }) {
|
|
|
7102
8758
|
void controls.run({ action: "lower_all_hands" });
|
|
7103
8759
|
},
|
|
7104
8760
|
children: [
|
|
7105
|
-
/* @__PURE__ */
|
|
8761
|
+
/* @__PURE__ */ jsx4(HandIcon, { width: 16, height: 16 }),
|
|
7106
8762
|
" Lower all hands (",
|
|
7107
8763
|
queue.length,
|
|
7108
8764
|
")"
|
|
7109
8765
|
]
|
|
7110
8766
|
}
|
|
7111
8767
|
) : null,
|
|
7112
|
-
hasSpotlight ? /* @__PURE__ */
|
|
8768
|
+
hasSpotlight ? /* @__PURE__ */ jsxs3(
|
|
7113
8769
|
MenuItem,
|
|
7114
8770
|
{
|
|
7115
8771
|
onSelect: () => {
|
|
@@ -7117,7 +8773,7 @@ function ControlBar({ onLeave }) {
|
|
|
7117
8773
|
void controls.run({ action: "spotlight", identity: null });
|
|
7118
8774
|
},
|
|
7119
8775
|
children: [
|
|
7120
|
-
/* @__PURE__ */
|
|
8776
|
+
/* @__PURE__ */ jsx4(SpotlightIcon, { width: 16, height: 16 }),
|
|
7121
8777
|
" Remove spotlight"
|
|
7122
8778
|
]
|
|
7123
8779
|
}
|
|
@@ -7125,7 +8781,7 @@ function ControlBar({ onLeave }) {
|
|
|
7125
8781
|
] }) : null
|
|
7126
8782
|
] }) }) : null
|
|
7127
8783
|
] }),
|
|
7128
|
-
/* @__PURE__ */
|
|
8784
|
+
/* @__PURE__ */ jsx4(
|
|
7129
8785
|
ControlButton,
|
|
7130
8786
|
{
|
|
7131
8787
|
label: "Leave",
|
|
@@ -7134,7 +8790,7 @@ function ControlBar({ onLeave }) {
|
|
|
7134
8790
|
void room.leave();
|
|
7135
8791
|
onLeave?.();
|
|
7136
8792
|
},
|
|
7137
|
-
children: /* @__PURE__ */
|
|
8793
|
+
children: /* @__PURE__ */ jsx4(PhoneOffIcon, {})
|
|
7138
8794
|
}
|
|
7139
8795
|
)
|
|
7140
8796
|
] })
|
|
@@ -7144,13 +8800,13 @@ function useUnreadChat(open) {
|
|
|
7144
8800
|
const snapshot = useMeetSnapshot();
|
|
7145
8801
|
const chat = snapshot?.chat ?? [];
|
|
7146
8802
|
const local = snapshot?.localIdentity ?? null;
|
|
7147
|
-
const [seen, setSeen] =
|
|
7148
|
-
|
|
8803
|
+
const [seen, setSeen] = useState4(0);
|
|
8804
|
+
useEffect4(() => {
|
|
7149
8805
|
if (open) setSeen(chat.length);
|
|
7150
8806
|
}, [open, chat.length]);
|
|
7151
8807
|
const loaded = snapshot?.chatLoaded === true;
|
|
7152
|
-
const [baseline, setBaseline] =
|
|
7153
|
-
|
|
8808
|
+
const [baseline, setBaseline] = useState4(null);
|
|
8809
|
+
useEffect4(() => {
|
|
7154
8810
|
if (loaded && baseline === null) setBaseline(chat.length);
|
|
7155
8811
|
}, [loaded, baseline, chat.length]);
|
|
7156
8812
|
if (open) return 0;
|
|
@@ -7163,8 +8819,8 @@ function Popover({
|
|
|
7163
8819
|
children,
|
|
7164
8820
|
placement = "up"
|
|
7165
8821
|
}) {
|
|
7166
|
-
const ref =
|
|
7167
|
-
const [style, setStyle] =
|
|
8822
|
+
const ref = useRef4(null);
|
|
8823
|
+
const [style, setStyle] = useState4({
|
|
7168
8824
|
position: "fixed",
|
|
7169
8825
|
top: 0,
|
|
7170
8826
|
left: 0,
|
|
@@ -7215,7 +8871,7 @@ function Popover({
|
|
|
7215
8871
|
window.removeEventListener("scroll", place, true);
|
|
7216
8872
|
};
|
|
7217
8873
|
}, [placement]);
|
|
7218
|
-
|
|
8874
|
+
useEffect4(() => {
|
|
7219
8875
|
const onKey = (event) => {
|
|
7220
8876
|
if (event.key === "Escape") onClose();
|
|
7221
8877
|
};
|
|
@@ -7230,14 +8886,14 @@ function Popover({
|
|
|
7230
8886
|
window.removeEventListener("pointerdown", onPointer);
|
|
7231
8887
|
};
|
|
7232
8888
|
}, [onClose]);
|
|
7233
|
-
return /* @__PURE__ */
|
|
8889
|
+
return /* @__PURE__ */ jsx4("div", { ref, className: "mx-meet__popover", style, role: "dialog", "aria-label": label, children });
|
|
7234
8890
|
}
|
|
7235
8891
|
function MenuItem({
|
|
7236
8892
|
onSelect,
|
|
7237
8893
|
danger = false,
|
|
7238
8894
|
children
|
|
7239
8895
|
}) {
|
|
7240
|
-
return /* @__PURE__ */
|
|
8896
|
+
return /* @__PURE__ */ jsx4(
|
|
7241
8897
|
"button",
|
|
7242
8898
|
{
|
|
7243
8899
|
type: "button",
|
|
@@ -7249,28 +8905,28 @@ function MenuItem({
|
|
|
7249
8905
|
);
|
|
7250
8906
|
}
|
|
7251
8907
|
function Toast({ text: text3, failed, onDone }) {
|
|
7252
|
-
|
|
8908
|
+
useEffect4(() => {
|
|
7253
8909
|
const timer = setTimeout(onDone, failed ? 7e3 : 4e3);
|
|
7254
8910
|
return () => clearTimeout(timer);
|
|
7255
8911
|
}, [text3, failed, onDone]);
|
|
7256
|
-
return /* @__PURE__ */
|
|
7257
|
-
/* @__PURE__ */
|
|
7258
|
-
/* @__PURE__ */
|
|
8912
|
+
return /* @__PURE__ */ jsxs3("div", { className: failed ? "mx-meet__toast mx-meet__toast--failed" : "mx-meet__toast", role: "status", children: [
|
|
8913
|
+
/* @__PURE__ */ jsx4("span", { children: text3 }),
|
|
8914
|
+
/* @__PURE__ */ jsx4("button", { type: "button", className: "mx-meet__toast-close", "aria-label": "Dismiss", onClick: onDone, children: /* @__PURE__ */ jsx4(CloseIcon, { width: 14, height: 14 }) })
|
|
7259
8915
|
] });
|
|
7260
8916
|
}
|
|
7261
8917
|
function MeetingOverlays() {
|
|
7262
8918
|
const reactions = useReactions();
|
|
7263
8919
|
const { notice, dismiss } = useModerationNotice();
|
|
7264
8920
|
const room = useRoom();
|
|
7265
|
-
return /* @__PURE__ */
|
|
7266
|
-
/* @__PURE__ */
|
|
8921
|
+
return /* @__PURE__ */ jsxs3(Fragment, { children: [
|
|
8922
|
+
/* @__PURE__ */ jsx4(ReactionOverlay, { reactions }),
|
|
7267
8923
|
notice !== null && notice.kind !== "removed" ? (
|
|
7268
8924
|
// A host's request ("the host is asking you to unmute"), not an error:
|
|
7269
8925
|
// an assertive status, so it is announced at once without being filed
|
|
7270
8926
|
// as a failure (design-system error-box census).
|
|
7271
|
-
/* @__PURE__ */
|
|
7272
|
-
/* @__PURE__ */
|
|
7273
|
-
notice.kind === "ask-unmute" && room.local?.micEnabled !== true ? /* @__PURE__ */
|
|
8927
|
+
/* @__PURE__ */ jsxs3("div", { className: "mx-meet__notice-bar", role: "status", "aria-live": "assertive", children: [
|
|
8928
|
+
/* @__PURE__ */ jsx4("span", { children: notice.text }),
|
|
8929
|
+
notice.kind === "ask-unmute" && room.local?.micEnabled !== true ? /* @__PURE__ */ jsx4(
|
|
7274
8930
|
"button",
|
|
7275
8931
|
{
|
|
7276
8932
|
type: "button",
|
|
@@ -7282,20 +8938,20 @@ function MeetingOverlays() {
|
|
|
7282
8938
|
children: "Unmute"
|
|
7283
8939
|
}
|
|
7284
8940
|
) : null,
|
|
7285
|
-
/* @__PURE__ */
|
|
8941
|
+
/* @__PURE__ */ jsx4("button", { type: "button", className: "mx-meet__toast-close", "aria-label": "Dismiss", onClick: dismiss, children: /* @__PURE__ */ jsx4(CloseIcon, { width: 14, height: 14 }) })
|
|
7286
8942
|
] })
|
|
7287
8943
|
) : null
|
|
7288
8944
|
] });
|
|
7289
8945
|
}
|
|
7290
8946
|
function ShortcutsSheet({ onClose }) {
|
|
7291
|
-
|
|
8947
|
+
useEffect4(() => {
|
|
7292
8948
|
const onKey = (event) => {
|
|
7293
8949
|
if (event.key === "Escape") onClose();
|
|
7294
8950
|
};
|
|
7295
8951
|
window.addEventListener("keydown", onKey);
|
|
7296
8952
|
return () => window.removeEventListener("keydown", onKey);
|
|
7297
8953
|
}, [onClose]);
|
|
7298
|
-
return /* @__PURE__ */
|
|
8954
|
+
return /* @__PURE__ */ jsx4("div", { className: "mx-meet__sheet-backdrop", onClick: onClose, children: /* @__PURE__ */ jsxs3(
|
|
7299
8955
|
"div",
|
|
7300
8956
|
{
|
|
7301
8957
|
className: "mx-meet__sheet",
|
|
@@ -7303,13 +8959,13 @@ function ShortcutsSheet({ onClose }) {
|
|
|
7303
8959
|
"aria-label": "Keyboard shortcuts",
|
|
7304
8960
|
onClick: (event) => event.stopPropagation(),
|
|
7305
8961
|
children: [
|
|
7306
|
-
/* @__PURE__ */
|
|
7307
|
-
/* @__PURE__ */
|
|
7308
|
-
/* @__PURE__ */
|
|
8962
|
+
/* @__PURE__ */ jsxs3("header", { className: "mx-meet__panel-head", children: [
|
|
8963
|
+
/* @__PURE__ */ jsx4("h2", { className: "mx-meet__panel-title", children: "Keyboard shortcuts" }),
|
|
8964
|
+
/* @__PURE__ */ jsx4(ControlButton, { label: "Close", onClick: onClose, children: /* @__PURE__ */ jsx4(CloseIcon, { width: 16, height: 16 }) })
|
|
7309
8965
|
] }),
|
|
7310
|
-
/* @__PURE__ */
|
|
7311
|
-
/* @__PURE__ */
|
|
7312
|
-
/* @__PURE__ */
|
|
8966
|
+
/* @__PURE__ */ jsx4("dl", { className: "mx-meet__shortcuts", children: MEET_SHORTCUTS.map((shortcut) => /* @__PURE__ */ jsxs3("div", { className: "mx-meet__shortcut", children: [
|
|
8967
|
+
/* @__PURE__ */ jsx4("dt", { children: shortcut.label }),
|
|
8968
|
+
/* @__PURE__ */ jsx4("dd", { children: /* @__PURE__ */ jsx4("kbd", { className: "mx-meet__kbd", children: shortcut.keys }) })
|
|
7313
8969
|
] }, shortcut.id)) })
|
|
7314
8970
|
]
|
|
7315
8971
|
}
|
|
@@ -7319,19 +8975,19 @@ function AiControl({ active, onToggle }) {
|
|
|
7319
8975
|
const snapshot = useMeetSnapshot();
|
|
7320
8976
|
const meeting = snapshot?.meeting ?? null;
|
|
7321
8977
|
if (meeting === null || !meeting.aiEnabled) return null;
|
|
7322
|
-
return /* @__PURE__ */
|
|
8978
|
+
return /* @__PURE__ */ jsx4(ControlButton, { label: "Meeting assistant", active, onClick: onToggle, children: /* @__PURE__ */ jsx4(SparklesIcon, {}) });
|
|
7323
8979
|
}
|
|
7324
8980
|
function PanelShell({
|
|
7325
8981
|
title,
|
|
7326
8982
|
onClose,
|
|
7327
8983
|
children
|
|
7328
8984
|
}) {
|
|
7329
|
-
return /* @__PURE__ */
|
|
7330
|
-
/* @__PURE__ */
|
|
7331
|
-
/* @__PURE__ */
|
|
7332
|
-
/* @__PURE__ */
|
|
8985
|
+
return /* @__PURE__ */ jsxs3("aside", { className: "mx-meet__panel", "aria-label": title, children: [
|
|
8986
|
+
/* @__PURE__ */ jsxs3("header", { className: "mx-meet__panel-head", children: [
|
|
8987
|
+
/* @__PURE__ */ jsx4("h2", { className: "mx-meet__panel-title", children: title }),
|
|
8988
|
+
/* @__PURE__ */ jsx4(ControlButton, { label: "Close panel", onClick: onClose, children: /* @__PURE__ */ jsx4(CloseIcon, { width: 16, height: 16 }) })
|
|
7333
8989
|
] }),
|
|
7334
|
-
/* @__PURE__ */
|
|
8990
|
+
/* @__PURE__ */ jsx4("div", { className: "mx-meet__panel-body", children })
|
|
7335
8991
|
] });
|
|
7336
8992
|
}
|
|
7337
8993
|
function ChatPanel({
|
|
@@ -7341,17 +8997,17 @@ function ChatPanel({
|
|
|
7341
8997
|
}) {
|
|
7342
8998
|
const snapshot = useMeetSnapshot();
|
|
7343
8999
|
const room = useRoom();
|
|
7344
|
-
const [draft, setDraft] =
|
|
7345
|
-
const [recipient, setRecipient] =
|
|
7346
|
-
const listRef =
|
|
9000
|
+
const [draft, setDraft] = useState4("");
|
|
9001
|
+
const [recipient, setRecipient] = useState4(to);
|
|
9002
|
+
const listRef = useRef4(null);
|
|
7347
9003
|
const messages = snapshot?.chat ?? [];
|
|
7348
9004
|
const local = snapshot?.localIdentity ?? null;
|
|
7349
9005
|
const people = (snapshot?.participants ?? []).filter(
|
|
7350
9006
|
(participant) => !participant.isLocal && !participant.isAgent
|
|
7351
9007
|
);
|
|
7352
9008
|
const recipientName = recipient === null ? null : people.find((p) => p.identity === recipient)?.displayName ?? null;
|
|
7353
|
-
|
|
7354
|
-
|
|
9009
|
+
useEffect4(() => setRecipient(to), [to]);
|
|
9010
|
+
useEffect4(() => {
|
|
7355
9011
|
const list = listRef.current;
|
|
7356
9012
|
if (list !== null) list.scrollTop = list.scrollHeight;
|
|
7357
9013
|
}, [messages.length]);
|
|
@@ -7359,13 +9015,13 @@ function ChatPanel({
|
|
|
7359
9015
|
setRecipient(next);
|
|
7360
9016
|
onTo?.(next);
|
|
7361
9017
|
};
|
|
7362
|
-
return /* @__PURE__ */
|
|
7363
|
-
/* @__PURE__ */
|
|
7364
|
-
snapshot?.chatHistoryError != null ? /* @__PURE__ */
|
|
7365
|
-
snapshot?.chatLoaded !== true && messages.length === 0 ? /* @__PURE__ */
|
|
7366
|
-
messages.map((message) => /* @__PURE__ */
|
|
9018
|
+
return /* @__PURE__ */ jsxs3(PanelShell, { title: "Chat", onClose, children: [
|
|
9019
|
+
/* @__PURE__ */ jsxs3("ul", { className: "mx-meet__chat", ref: listRef, children: [
|
|
9020
|
+
snapshot?.chatHistoryError != null ? /* @__PURE__ */ jsx4("li", { className: "mx-meet__panel-note", children: snapshot.chatHistoryError }) : null,
|
|
9021
|
+
snapshot?.chatLoaded !== true && messages.length === 0 ? /* @__PURE__ */ jsx4("li", { className: "mx-meet__panel-note", children: "Reading earlier messages\u2026" }) : messages.length === 0 && snapshot?.chatHistoryError == null ? /* @__PURE__ */ jsx4("li", { className: "mx-meet__panel-note", children: "No messages yet. Messages to everyone stay with the meeting, so people who join later see them." }) : null,
|
|
9022
|
+
messages.map((message) => /* @__PURE__ */ jsx4(ChatLine, { message, local, people }, message.id))
|
|
7367
9023
|
] }),
|
|
7368
|
-
/* @__PURE__ */
|
|
9024
|
+
/* @__PURE__ */ jsxs3(
|
|
7369
9025
|
"form",
|
|
7370
9026
|
{
|
|
7371
9027
|
className: "mx-meet__composer mx-meet__composer--chat",
|
|
@@ -7378,7 +9034,7 @@ function ChatPanel({
|
|
|
7378
9034
|
else void room.sendPrivateChat(recipient, text3);
|
|
7379
9035
|
},
|
|
7380
9036
|
children: [
|
|
7381
|
-
people.length > 0 ? /* @__PURE__ */
|
|
9037
|
+
people.length > 0 ? /* @__PURE__ */ jsxs3(
|
|
7382
9038
|
"select",
|
|
7383
9039
|
{
|
|
7384
9040
|
className: "mx-meet__select mx-meet__select--compact",
|
|
@@ -7386,16 +9042,16 @@ function ChatPanel({
|
|
|
7386
9042
|
value: recipient ?? "",
|
|
7387
9043
|
onChange: (event) => choose(event.target.value === "" ? null : event.target.value),
|
|
7388
9044
|
children: [
|
|
7389
|
-
/* @__PURE__ */
|
|
7390
|
-
people.map((participant) => /* @__PURE__ */
|
|
9045
|
+
/* @__PURE__ */ jsx4("option", { value: "", children: "Everyone" }),
|
|
9046
|
+
people.map((participant) => /* @__PURE__ */ jsxs3("option", { value: participant.identity, children: [
|
|
7391
9047
|
participant.displayName,
|
|
7392
9048
|
" (private)"
|
|
7393
9049
|
] }, participant.identity))
|
|
7394
9050
|
]
|
|
7395
9051
|
}
|
|
7396
9052
|
) : null,
|
|
7397
|
-
/* @__PURE__ */
|
|
7398
|
-
/* @__PURE__ */
|
|
9053
|
+
/* @__PURE__ */ jsxs3("div", { className: "mx-meet__composer-row", children: [
|
|
9054
|
+
/* @__PURE__ */ jsx4(
|
|
7399
9055
|
"input",
|
|
7400
9056
|
{
|
|
7401
9057
|
className: "mx-meet__input",
|
|
@@ -7406,9 +9062,9 @@ function ChatPanel({
|
|
|
7406
9062
|
maxLength: 4e3
|
|
7407
9063
|
}
|
|
7408
9064
|
),
|
|
7409
|
-
/* @__PURE__ */
|
|
9065
|
+
/* @__PURE__ */ jsx4("button", { type: "submit", className: "mx-meet__send", disabled: draft.trim().length === 0, children: "Send" })
|
|
7410
9066
|
] }),
|
|
7411
|
-
recipientName !== null ? /* @__PURE__ */
|
|
9067
|
+
recipientName !== null ? /* @__PURE__ */ jsxs3("p", { className: "mx-meet__panel-note", children: [
|
|
7412
9068
|
"Only ",
|
|
7413
9069
|
recipientName,
|
|
7414
9070
|
" sees this. Private messages are not saved."
|
|
@@ -7426,7 +9082,7 @@ function ChatLine({
|
|
|
7426
9082
|
const mine = message.identity === local;
|
|
7427
9083
|
const privateTo = message.to ?? null;
|
|
7428
9084
|
const counterpart = privateTo === null ? null : mine ? people.find((p) => p.identity === privateTo)?.displayName ?? "them" : "you";
|
|
7429
|
-
return /* @__PURE__ */
|
|
9085
|
+
return /* @__PURE__ */ jsxs3(
|
|
7430
9086
|
"li",
|
|
7431
9087
|
{
|
|
7432
9088
|
className: [
|
|
@@ -7435,17 +9091,17 @@ function ChatLine({
|
|
|
7435
9091
|
message.failed !== void 0 ? "mx-meet__chat-line--failed" : ""
|
|
7436
9092
|
].filter(Boolean).join(" "),
|
|
7437
9093
|
children: [
|
|
7438
|
-
/* @__PURE__ */
|
|
7439
|
-
/* @__PURE__ */
|
|
7440
|
-
counterpart !== null ? /* @__PURE__ */
|
|
9094
|
+
/* @__PURE__ */ jsxs3("span", { className: "mx-meet__chat-meta", children: [
|
|
9095
|
+
/* @__PURE__ */ jsx4("strong", { children: mine ? "You" : message.displayName }),
|
|
9096
|
+
counterpart !== null ? /* @__PURE__ */ jsxs3("span", { className: "mx-meet__chat-private", children: [
|
|
7441
9097
|
"to ",
|
|
7442
9098
|
counterpart,
|
|
7443
9099
|
" \xB7 private"
|
|
7444
9100
|
] }) : null,
|
|
7445
|
-
/* @__PURE__ */
|
|
9101
|
+
/* @__PURE__ */ jsx4("time", { dateTime: message.at, children: clockOf(message.at) })
|
|
7446
9102
|
] }),
|
|
7447
|
-
/* @__PURE__ */
|
|
7448
|
-
message.failed !== void 0 ? /* @__PURE__ */
|
|
9103
|
+
/* @__PURE__ */ jsx4("span", { className: "mx-meet__chat-text", children: message.text }),
|
|
9104
|
+
message.failed !== void 0 ? /* @__PURE__ */ jsx4("span", { className: "mx-meet__chat-failed", children: message.failed }) : privateTo === null && message.saved === false ? /* @__PURE__ */ jsx4("span", { className: "mx-meet__chat-pending", children: message.id.startsWith("pending-") ? "Sending\u2026" : "Not saved \u2014 people who join later will not see this" }) : null
|
|
7449
9105
|
]
|
|
7450
9106
|
}
|
|
7451
9107
|
);
|
|
@@ -7457,22 +9113,22 @@ function PeoplePanel({
|
|
|
7457
9113
|
const snapshot = useMeetSnapshot();
|
|
7458
9114
|
const controls = useHostControls();
|
|
7459
9115
|
const queue = useHandQueue();
|
|
7460
|
-
const [query, setQuery] =
|
|
7461
|
-
const [menuFor, setMenuFor] =
|
|
9116
|
+
const [query, setQuery] = useState4("");
|
|
9117
|
+
const [menuFor, setMenuFor] = useState4(null);
|
|
7462
9118
|
const myRole = useRole();
|
|
7463
9119
|
const local = snapshot?.localIdentity ?? null;
|
|
7464
9120
|
const everyone = snapshot?.participants ?? [];
|
|
7465
9121
|
const needle = query.trim().toLowerCase();
|
|
7466
9122
|
const shown = needle.length === 0 ? everyone : everyone.filter((participant) => participant.displayName.toLowerCase().includes(needle));
|
|
7467
|
-
return /* @__PURE__ */
|
|
7468
|
-
/* @__PURE__ */
|
|
7469
|
-
queue.length > 0 ? /* @__PURE__ */
|
|
7470
|
-
/* @__PURE__ */
|
|
7471
|
-
/* @__PURE__ */
|
|
9123
|
+
return /* @__PURE__ */ jsxs3(PanelShell, { title: `People (${everyone.length})`, onClose, children: [
|
|
9124
|
+
/* @__PURE__ */ jsx4(LobbyPanel, {}),
|
|
9125
|
+
queue.length > 0 ? /* @__PURE__ */ jsxs3("section", { className: "mx-meet__section", "aria-label": "Raised hands", children: [
|
|
9126
|
+
/* @__PURE__ */ jsxs3("header", { className: "mx-meet__section-head", children: [
|
|
9127
|
+
/* @__PURE__ */ jsxs3("h3", { className: "mx-meet__section-title", children: [
|
|
7472
9128
|
"Raised hands \xB7 ",
|
|
7473
9129
|
queue.length
|
|
7474
9130
|
] }),
|
|
7475
|
-
controls.isHost ? /* @__PURE__ */
|
|
9131
|
+
controls.isHost ? /* @__PURE__ */ jsx4(
|
|
7476
9132
|
"button",
|
|
7477
9133
|
{
|
|
7478
9134
|
type: "button",
|
|
@@ -7482,13 +9138,13 @@ function PeoplePanel({
|
|
|
7482
9138
|
}
|
|
7483
9139
|
) : null
|
|
7484
9140
|
] }),
|
|
7485
|
-
/* @__PURE__ */
|
|
7486
|
-
/* @__PURE__ */
|
|
7487
|
-
/* @__PURE__ */
|
|
9141
|
+
/* @__PURE__ */ jsx4("ol", { className: "mx-meet__queue", children: queue.map((participant) => /* @__PURE__ */ jsxs3("li", { className: "mx-meet__person", children: [
|
|
9142
|
+
/* @__PURE__ */ jsx4(Avatar, { name: participant.displayName, url: participant.avatarUrl, size: 28 }),
|
|
9143
|
+
/* @__PURE__ */ jsxs3("span", { className: "mx-meet__person-name", children: [
|
|
7488
9144
|
participant.displayName,
|
|
7489
|
-
participant.identity === local ? /* @__PURE__ */
|
|
9145
|
+
participant.identity === local ? /* @__PURE__ */ jsx4("span", { className: "mx-meet__you", children: " (you)" }) : null
|
|
7490
9146
|
] }),
|
|
7491
|
-
controls.isHost || participant.identity === local ? /* @__PURE__ */
|
|
9147
|
+
controls.isHost || participant.identity === local ? /* @__PURE__ */ jsx4(
|
|
7492
9148
|
"button",
|
|
7493
9149
|
{
|
|
7494
9150
|
type: "button",
|
|
@@ -7499,27 +9155,27 @@ function PeoplePanel({
|
|
|
7499
9155
|
) : null
|
|
7500
9156
|
] }, participant.identity)) })
|
|
7501
9157
|
] }) : null,
|
|
7502
|
-
controls.isHost && everyone.length > 1 ? /* @__PURE__ */
|
|
7503
|
-
/* @__PURE__ */
|
|
7504
|
-
/* @__PURE__ */
|
|
9158
|
+
controls.isHost && everyone.length > 1 ? /* @__PURE__ */ jsxs3("div", { className: "mx-meet__bulk", children: [
|
|
9159
|
+
/* @__PURE__ */ jsxs3("button", { type: "button", className: "mx-meet__chip", onClick: () => void controls.run({ action: "mute_all" }), children: [
|
|
9160
|
+
/* @__PURE__ */ jsx4(MicOffIcon, { width: 14, height: 14 }),
|
|
7505
9161
|
" Mute all"
|
|
7506
9162
|
] }),
|
|
7507
|
-
/* @__PURE__ */
|
|
9163
|
+
/* @__PURE__ */ jsxs3(
|
|
7508
9164
|
"button",
|
|
7509
9165
|
{
|
|
7510
9166
|
type: "button",
|
|
7511
9167
|
className: "mx-meet__chip",
|
|
7512
9168
|
onClick: () => void controls.run({ action: "ask_all_unmute" }),
|
|
7513
9169
|
children: [
|
|
7514
|
-
/* @__PURE__ */
|
|
9170
|
+
/* @__PURE__ */ jsx4(MicIcon, { width: 14, height: 14 }),
|
|
7515
9171
|
" Ask all to unmute"
|
|
7516
9172
|
]
|
|
7517
9173
|
}
|
|
7518
9174
|
)
|
|
7519
9175
|
] }) : null,
|
|
7520
|
-
everyone.length > 4 ? /* @__PURE__ */
|
|
7521
|
-
/* @__PURE__ */
|
|
7522
|
-
/* @__PURE__ */
|
|
9176
|
+
everyone.length > 4 ? /* @__PURE__ */ jsxs3("label", { className: "mx-meet__search", children: [
|
|
9177
|
+
/* @__PURE__ */ jsx4(SearchIcon, { width: 16, height: 16 }),
|
|
9178
|
+
/* @__PURE__ */ jsx4(
|
|
7523
9179
|
"input",
|
|
7524
9180
|
{
|
|
7525
9181
|
className: "mx-meet__input mx-meet__input--bare",
|
|
@@ -7530,31 +9186,31 @@ function PeoplePanel({
|
|
|
7530
9186
|
}
|
|
7531
9187
|
)
|
|
7532
9188
|
] }) : null,
|
|
7533
|
-
controls.notice !== null ? /* @__PURE__ */
|
|
7534
|
-
/* @__PURE__ */
|
|
7535
|
-
shown.map((participant) => /* @__PURE__ */
|
|
7536
|
-
/* @__PURE__ */
|
|
7537
|
-
/* @__PURE__ */
|
|
9189
|
+
controls.notice !== null ? /* @__PURE__ */ jsx4("p", { className: controls.notice.failed ? "mx-meet__error" : "mx-meet__notice", role: "status", children: controls.notice.text }) : null,
|
|
9190
|
+
/* @__PURE__ */ jsxs3("ul", { className: "mx-meet__people", children: [
|
|
9191
|
+
shown.map((participant) => /* @__PURE__ */ jsxs3("li", { className: "mx-meet__person", children: [
|
|
9192
|
+
/* @__PURE__ */ jsx4(Avatar, { name: participant.displayName, url: participant.avatarUrl, size: 32 }),
|
|
9193
|
+
/* @__PURE__ */ jsxs3("span", { className: "mx-meet__person-name", children: [
|
|
7538
9194
|
participant.displayName,
|
|
7539
|
-
participant.identity === local ? /* @__PURE__ */
|
|
7540
|
-
/* @__PURE__ */
|
|
7541
|
-
isNoteTaker(participant) ? /* @__PURE__ */
|
|
7542
|
-
snapshot?.spotlight === participant.identity ? /* @__PURE__ */
|
|
9195
|
+
participant.identity === local ? /* @__PURE__ */ jsx4("span", { className: "mx-meet__you", children: " (you)" }) : null,
|
|
9196
|
+
/* @__PURE__ */ jsx4(RoleBadge, { role: participant.identity === local ? myRole : participant.role }),
|
|
9197
|
+
isNoteTaker(participant) ? /* @__PURE__ */ jsx4("span", { className: "mx-meet__badge", children: "Meeting assistant" }) : null,
|
|
9198
|
+
snapshot?.spotlight === participant.identity ? /* @__PURE__ */ jsx4("span", { className: "mx-meet__badge", children: "Spotlight" }) : null
|
|
7543
9199
|
] }),
|
|
7544
|
-
participant.handRaised ? /* @__PURE__ */
|
|
7545
|
-
!participant.micEnabled && !isNoteTaker(participant) ? /* @__PURE__ */
|
|
7546
|
-
/* @__PURE__ */
|
|
7547
|
-
/* @__PURE__ */
|
|
7548
|
-
/* @__PURE__ */
|
|
9200
|
+
participant.handRaised ? /* @__PURE__ */ jsx4(HandIcon, { width: 14, height: 14 }) : null,
|
|
9201
|
+
!participant.micEnabled && !isNoteTaker(participant) ? /* @__PURE__ */ jsx4(MicOffIcon, { width: 14, height: 14 }) : null,
|
|
9202
|
+
/* @__PURE__ */ jsx4(QualityBars, { quality: participant.quality }),
|
|
9203
|
+
/* @__PURE__ */ jsxs3("span", { className: "mx-meet__anchor", children: [
|
|
9204
|
+
/* @__PURE__ */ jsx4(
|
|
7549
9205
|
ControlButton,
|
|
7550
9206
|
{
|
|
7551
9207
|
label: `More for ${participant.displayName}`,
|
|
7552
9208
|
active: menuFor === participant.identity,
|
|
7553
9209
|
onClick: () => setMenuFor(menuFor === participant.identity ? null : participant.identity),
|
|
7554
|
-
children: /* @__PURE__ */
|
|
9210
|
+
children: /* @__PURE__ */ jsx4(MoreIcon, { width: 16, height: 16 })
|
|
7555
9211
|
}
|
|
7556
9212
|
),
|
|
7557
|
-
menuFor === participant.identity ? /* @__PURE__ */
|
|
9213
|
+
menuFor === participant.identity ? /* @__PURE__ */ jsx4(
|
|
7558
9214
|
PersonMenu,
|
|
7559
9215
|
{
|
|
7560
9216
|
participant,
|
|
@@ -7565,13 +9221,13 @@ function PeoplePanel({
|
|
|
7565
9221
|
) : null
|
|
7566
9222
|
] })
|
|
7567
9223
|
] }, participant.identity)),
|
|
7568
|
-
shown.length === 0 ? /* @__PURE__ */
|
|
9224
|
+
shown.length === 0 ? /* @__PURE__ */ jsxs3("li", { className: "mx-meet__panel-note", children: [
|
|
7569
9225
|
"Nobody matches \u201C",
|
|
7570
9226
|
query,
|
|
7571
9227
|
"\u201D."
|
|
7572
9228
|
] }) : null
|
|
7573
9229
|
] }),
|
|
7574
|
-
snapshot?.meeting !== null && snapshot?.meeting !== void 0 ? /* @__PURE__ */
|
|
9230
|
+
snapshot?.meeting !== null && snapshot?.meeting !== void 0 ? /* @__PURE__ */ jsx4(GuestRecordAccessControl, { meeting: snapshot.meeting }) : null
|
|
7575
9231
|
] });
|
|
7576
9232
|
}
|
|
7577
9233
|
function PersonMenu({
|
|
@@ -7583,14 +9239,14 @@ function PersonMenu({
|
|
|
7583
9239
|
const host = useMeetHost();
|
|
7584
9240
|
const snapshot = useMeetSnapshot();
|
|
7585
9241
|
const controls = useHostControls();
|
|
7586
|
-
const [mode, setMode] =
|
|
7587
|
-
const [text3, setText] =
|
|
9242
|
+
const [mode, setMode] = useState4("menu");
|
|
9243
|
+
const [text3, setText] = useState4("");
|
|
7588
9244
|
const self = participant.identity === snapshot?.localIdentity;
|
|
7589
9245
|
const moderate = controls.canModerate(participant);
|
|
7590
9246
|
const pinned = snapshot?.pinned === participant.identity;
|
|
7591
9247
|
const spotlit = snapshot?.spotlight === participant.identity;
|
|
7592
9248
|
const hasAccount = participant.userId !== null;
|
|
7593
|
-
const [refused, setRefused] =
|
|
9249
|
+
const [refused, setRefused] = useState4(false);
|
|
7594
9250
|
const act = (request) => {
|
|
7595
9251
|
setRefused(false);
|
|
7596
9252
|
void controls.run(request).then((result) => {
|
|
@@ -7598,10 +9254,10 @@ function PersonMenu({
|
|
|
7598
9254
|
else setRefused(true);
|
|
7599
9255
|
});
|
|
7600
9256
|
};
|
|
7601
|
-
const refusal2 = refused && controls.notice?.failed === true ? /* @__PURE__ */
|
|
9257
|
+
const refusal2 = refused && controls.notice?.failed === true ? /* @__PURE__ */ jsx4(ErrorBox, { as: "p", className: "mx-meet__error", message: controls.notice.text, operation: "Change this participant", origin: "meet/components", children: controls.notice.text }) : null;
|
|
7602
9258
|
if (mode === "rename" || mode === "report") {
|
|
7603
9259
|
const renaming = mode === "rename";
|
|
7604
|
-
return /* @__PURE__ */
|
|
9260
|
+
return /* @__PURE__ */ jsx4(Popover, { label: renaming ? "Rename" : "Report", onClose, placement, children: /* @__PURE__ */ jsxs3(
|
|
7605
9261
|
"form",
|
|
7606
9262
|
{
|
|
7607
9263
|
className: "mx-meet__menu-form",
|
|
@@ -7613,9 +9269,9 @@ function PersonMenu({
|
|
|
7613
9269
|
);
|
|
7614
9270
|
},
|
|
7615
9271
|
children: [
|
|
7616
|
-
/* @__PURE__ */
|
|
7617
|
-
/* @__PURE__ */
|
|
7618
|
-
renaming ? /* @__PURE__ */
|
|
9272
|
+
/* @__PURE__ */ jsxs3("label", { className: "mx-meet__field", children: [
|
|
9273
|
+
/* @__PURE__ */ jsx4("span", { className: "mx-meet__field-label", children: renaming ? "Name shown in this meeting" : `What did ${participant.displayName} do?` }),
|
|
9274
|
+
renaming ? /* @__PURE__ */ jsx4(
|
|
7619
9275
|
"input",
|
|
7620
9276
|
{
|
|
7621
9277
|
className: "mx-meet__input",
|
|
@@ -7624,7 +9280,7 @@ function PersonMenu({
|
|
|
7624
9280
|
value: text3,
|
|
7625
9281
|
onChange: (event) => setText(event.target.value)
|
|
7626
9282
|
}
|
|
7627
|
-
) : /* @__PURE__ */
|
|
9283
|
+
) : /* @__PURE__ */ jsx4(
|
|
7628
9284
|
"textarea",
|
|
7629
9285
|
{
|
|
7630
9286
|
className: "mx-meet__input",
|
|
@@ -7637,9 +9293,9 @@ function PersonMenu({
|
|
|
7637
9293
|
)
|
|
7638
9294
|
] }),
|
|
7639
9295
|
refusal2,
|
|
7640
|
-
/* @__PURE__ */
|
|
7641
|
-
/* @__PURE__ */
|
|
7642
|
-
/* @__PURE__ */
|
|
9296
|
+
/* @__PURE__ */ jsxs3("div", { className: "mx-meet__menu-actions", children: [
|
|
9297
|
+
/* @__PURE__ */ jsx4("button", { type: "button", className: "mx-meet__link", onClick: () => setMode("menu"), children: "Back" }),
|
|
9298
|
+
/* @__PURE__ */ jsx4("button", { type: "submit", className: "mx-meet__send", disabled: text3.trim().length === 0 || controls.busy, children: renaming ? "Rename" : "Report" })
|
|
7643
9299
|
] })
|
|
7644
9300
|
]
|
|
7645
9301
|
}
|
|
@@ -7647,12 +9303,12 @@ function PersonMenu({
|
|
|
7647
9303
|
}
|
|
7648
9304
|
if (mode === "remove" || mode === "transfer") {
|
|
7649
9305
|
const removing = mode === "remove";
|
|
7650
|
-
return /* @__PURE__ */
|
|
7651
|
-
/* @__PURE__ */
|
|
9306
|
+
return /* @__PURE__ */ jsx4(Popover, { label: removing ? "Remove" : "Make host", onClose, placement, children: /* @__PURE__ */ jsxs3("div", { className: "mx-meet__menu-form", children: [
|
|
9307
|
+
/* @__PURE__ */ jsx4("p", { className: "mx-meet__confirm-text", children: removing ? `Remove ${participant.displayName}? They leave immediately and cannot rejoin this meeting.` : `Make ${participant.displayName} the host? They get every host control and own this meeting. You stay on as a co-host.` }),
|
|
7652
9308
|
refusal2,
|
|
7653
|
-
/* @__PURE__ */
|
|
7654
|
-
/* @__PURE__ */
|
|
7655
|
-
/* @__PURE__ */
|
|
9309
|
+
/* @__PURE__ */ jsxs3("div", { className: "mx-meet__menu-actions", children: [
|
|
9310
|
+
/* @__PURE__ */ jsx4("button", { type: "button", className: "mx-meet__link", onClick: () => setMode("menu"), children: "Cancel" }),
|
|
9311
|
+
/* @__PURE__ */ jsx4(
|
|
7656
9312
|
"button",
|
|
7657
9313
|
{
|
|
7658
9314
|
type: "button",
|
|
@@ -7665,8 +9321,8 @@ function PersonMenu({
|
|
|
7665
9321
|
] })
|
|
7666
9322
|
] }) });
|
|
7667
9323
|
}
|
|
7668
|
-
return /* @__PURE__ */
|
|
7669
|
-
/* @__PURE__ */
|
|
9324
|
+
return /* @__PURE__ */ jsx4(Popover, { label: `Options for ${participant.displayName}`, onClose, placement, children: /* @__PURE__ */ jsxs3("div", { className: "mx-meet__menu", role: "menu", children: [
|
|
9325
|
+
/* @__PURE__ */ jsxs3(
|
|
7670
9326
|
MenuItem,
|
|
7671
9327
|
{
|
|
7672
9328
|
onSelect: () => {
|
|
@@ -7674,13 +9330,13 @@ function PersonMenu({
|
|
|
7674
9330
|
onClose();
|
|
7675
9331
|
},
|
|
7676
9332
|
children: [
|
|
7677
|
-
/* @__PURE__ */
|
|
9333
|
+
/* @__PURE__ */ jsx4(PinIcon, { width: 16, height: 16 }),
|
|
7678
9334
|
" ",
|
|
7679
9335
|
pinned ? "Unpin" : "Pin for me"
|
|
7680
9336
|
]
|
|
7681
9337
|
}
|
|
7682
9338
|
),
|
|
7683
|
-
!self && !participant.isAgent && (onMessage !== void 0 || host !== null) ? /* @__PURE__ */
|
|
9339
|
+
!self && !participant.isAgent && (onMessage !== void 0 || host !== null) ? /* @__PURE__ */ jsxs3(
|
|
7684
9340
|
MenuItem,
|
|
7685
9341
|
{
|
|
7686
9342
|
onSelect: () => {
|
|
@@ -7692,42 +9348,42 @@ function PersonMenu({
|
|
|
7692
9348
|
onClose();
|
|
7693
9349
|
},
|
|
7694
9350
|
children: [
|
|
7695
|
-
/* @__PURE__ */
|
|
9351
|
+
/* @__PURE__ */ jsx4(ChatIcon, { width: 16, height: 16 }),
|
|
7696
9352
|
" Message privately"
|
|
7697
9353
|
]
|
|
7698
9354
|
}
|
|
7699
9355
|
) : null,
|
|
7700
|
-
controls.isHost ? /* @__PURE__ */
|
|
7701
|
-
/* @__PURE__ */
|
|
9356
|
+
controls.isHost ? /* @__PURE__ */ jsxs3(MenuItem, { onSelect: () => act({ action: "spotlight", identity: spotlit ? null : participant.identity }), children: [
|
|
9357
|
+
/* @__PURE__ */ jsx4(SpotlightIcon, { width: 16, height: 16 }),
|
|
7702
9358
|
" ",
|
|
7703
9359
|
spotlit ? "Remove spotlight" : "Spotlight for everyone"
|
|
7704
9360
|
] }) : null,
|
|
7705
|
-
moderate ? /* @__PURE__ */
|
|
7706
|
-
/* @__PURE__ */
|
|
7707
|
-
participant.micEnabled ? /* @__PURE__ */
|
|
7708
|
-
/* @__PURE__ */
|
|
9361
|
+
moderate ? /* @__PURE__ */ jsxs3(Fragment, { children: [
|
|
9362
|
+
/* @__PURE__ */ jsx4("div", { className: "mx-meet__menu-sep", role: "separator" }),
|
|
9363
|
+
participant.micEnabled ? /* @__PURE__ */ jsxs3(MenuItem, { onSelect: () => act({ action: "mute", identity: participant.identity }), children: [
|
|
9364
|
+
/* @__PURE__ */ jsx4(MicOffIcon, { width: 16, height: 16 }),
|
|
7709
9365
|
" Mute"
|
|
7710
|
-
] }) : !participant.isAgent ? /* @__PURE__ */
|
|
7711
|
-
/* @__PURE__ */
|
|
9366
|
+
] }) : !participant.isAgent ? /* @__PURE__ */ jsxs3(MenuItem, { onSelect: () => act({ action: "ask_unmute", identity: participant.identity }), children: [
|
|
9367
|
+
/* @__PURE__ */ jsx4(MicIcon, { width: 16, height: 16 }),
|
|
7712
9368
|
" Ask to unmute"
|
|
7713
9369
|
] }) : null,
|
|
7714
|
-
participant.cameraEnabled ? /* @__PURE__ */
|
|
7715
|
-
/* @__PURE__ */
|
|
9370
|
+
participant.cameraEnabled ? /* @__PURE__ */ jsxs3(MenuItem, { onSelect: () => act({ action: "stop_video", identity: participant.identity }), children: [
|
|
9371
|
+
/* @__PURE__ */ jsx4(CameraOffIcon, { width: 16, height: 16 }),
|
|
7716
9372
|
" Stop video"
|
|
7717
9373
|
] }) : null,
|
|
7718
|
-
participant.screenSharing ? /* @__PURE__ */
|
|
7719
|
-
/* @__PURE__ */
|
|
9374
|
+
participant.screenSharing ? /* @__PURE__ */ jsxs3(MenuItem, { onSelect: () => act({ action: "stop_screen", identity: participant.identity }), children: [
|
|
9375
|
+
/* @__PURE__ */ jsx4(ScreenShareIcon, { width: 16, height: 16 }),
|
|
7720
9376
|
" Stop screen share"
|
|
7721
9377
|
] }) : null,
|
|
7722
|
-
participant.handRaised ? /* @__PURE__ */
|
|
7723
|
-
/* @__PURE__ */
|
|
9378
|
+
participant.handRaised ? /* @__PURE__ */ jsxs3(MenuItem, { onSelect: () => act({ action: "lower_hand", identity: participant.identity }), children: [
|
|
9379
|
+
/* @__PURE__ */ jsx4(HandIcon, { width: 16, height: 16 }),
|
|
7724
9380
|
" Lower hand"
|
|
7725
9381
|
] }) : null,
|
|
7726
|
-
hasAccount && !participant.isAgent && participant.role !== "cohost" ? /* @__PURE__ */
|
|
7727
|
-
/* @__PURE__ */
|
|
9382
|
+
hasAccount && !participant.isAgent && participant.role !== "cohost" ? /* @__PURE__ */ jsxs3(MenuItem, { onSelect: () => act({ action: "make_cohost", identity: participant.identity }), children: [
|
|
9383
|
+
/* @__PURE__ */ jsx4(PeopleIcon, { width: 16, height: 16 }),
|
|
7728
9384
|
" Make co-host"
|
|
7729
9385
|
] }) : null,
|
|
7730
|
-
!participant.isAgent ? /* @__PURE__ */
|
|
9386
|
+
!participant.isAgent ? /* @__PURE__ */ jsxs3(
|
|
7731
9387
|
MenuItem,
|
|
7732
9388
|
{
|
|
7733
9389
|
onSelect: () => {
|
|
@@ -7735,21 +9391,21 @@ function PersonMenu({
|
|
|
7735
9391
|
setMode("rename");
|
|
7736
9392
|
},
|
|
7737
9393
|
children: [
|
|
7738
|
-
/* @__PURE__ */
|
|
9394
|
+
/* @__PURE__ */ jsx4(PencilIcon, { width: 16, height: 16 }),
|
|
7739
9395
|
" Rename"
|
|
7740
9396
|
]
|
|
7741
9397
|
}
|
|
7742
9398
|
) : null
|
|
7743
9399
|
] }) : null,
|
|
7744
|
-
controls.isOwner && participant.role === "cohost" ? /* @__PURE__ */
|
|
7745
|
-
/* @__PURE__ */
|
|
9400
|
+
controls.isOwner && participant.role === "cohost" ? /* @__PURE__ */ jsxs3(MenuItem, { onSelect: () => act({ action: "revoke_cohost", identity: participant.identity }), children: [
|
|
9401
|
+
/* @__PURE__ */ jsx4(PeopleIcon, { width: 16, height: 16 }),
|
|
7746
9402
|
" Remove co-host"
|
|
7747
9403
|
] }) : null,
|
|
7748
|
-
controls.isOwner && !self && hasAccount && !participant.isAgent ? /* @__PURE__ */
|
|
7749
|
-
/* @__PURE__ */
|
|
9404
|
+
controls.isOwner && !self && hasAccount && !participant.isAgent ? /* @__PURE__ */ jsxs3(MenuItem, { onSelect: () => setMode("transfer"), children: [
|
|
9405
|
+
/* @__PURE__ */ jsx4(SpotlightIcon, { width: 16, height: 16 }),
|
|
7750
9406
|
" Make host"
|
|
7751
9407
|
] }) : null,
|
|
7752
|
-
self ? /* @__PURE__ */
|
|
9408
|
+
self ? /* @__PURE__ */ jsxs3(
|
|
7753
9409
|
MenuItem,
|
|
7754
9410
|
{
|
|
7755
9411
|
onSelect: () => {
|
|
@@ -7757,12 +9413,12 @@ function PersonMenu({
|
|
|
7757
9413
|
setMode("rename");
|
|
7758
9414
|
},
|
|
7759
9415
|
children: [
|
|
7760
|
-
/* @__PURE__ */
|
|
9416
|
+
/* @__PURE__ */ jsx4(PencilIcon, { width: 16, height: 16 }),
|
|
7761
9417
|
" Rename yourself"
|
|
7762
9418
|
]
|
|
7763
9419
|
}
|
|
7764
9420
|
) : null,
|
|
7765
|
-
!self && !participant.isAgent ? /* @__PURE__ */
|
|
9421
|
+
!self && !participant.isAgent ? /* @__PURE__ */ jsxs3(
|
|
7766
9422
|
MenuItem,
|
|
7767
9423
|
{
|
|
7768
9424
|
onSelect: () => {
|
|
@@ -7770,21 +9426,21 @@ function PersonMenu({
|
|
|
7770
9426
|
setMode("report");
|
|
7771
9427
|
},
|
|
7772
9428
|
children: [
|
|
7773
|
-
/* @__PURE__ */
|
|
9429
|
+
/* @__PURE__ */ jsx4(FlagIcon, { width: 16, height: 16 }),
|
|
7774
9430
|
" Report"
|
|
7775
9431
|
]
|
|
7776
9432
|
}
|
|
7777
9433
|
) : null,
|
|
7778
|
-
moderate && !participant.isAgent ? /* @__PURE__ */
|
|
7779
|
-
/* @__PURE__ */
|
|
9434
|
+
moderate && !participant.isAgent ? /* @__PURE__ */ jsxs3(MenuItem, { danger: true, onSelect: () => setMode("remove"), children: [
|
|
9435
|
+
/* @__PURE__ */ jsx4(CloseIcon, { width: 16, height: 16 }),
|
|
7780
9436
|
" Remove from meeting"
|
|
7781
9437
|
] }) : null
|
|
7782
9438
|
] }) });
|
|
7783
9439
|
}
|
|
7784
9440
|
function SettingsPanel({ onClose }) {
|
|
7785
9441
|
const host = useRequiredMeetHost();
|
|
7786
|
-
return /* @__PURE__ */
|
|
7787
|
-
/* @__PURE__ */
|
|
9442
|
+
return /* @__PURE__ */ jsxs3(PanelShell, { title: "Settings", onClose, children: [
|
|
9443
|
+
/* @__PURE__ */ jsx4(
|
|
7788
9444
|
DeviceSettings,
|
|
7789
9445
|
{
|
|
7790
9446
|
onPick: (kind, deviceId2) => {
|
|
@@ -7793,7 +9449,8 @@ function SettingsPanel({ onClose }) {
|
|
|
7793
9449
|
}
|
|
7794
9450
|
}
|
|
7795
9451
|
),
|
|
7796
|
-
/* @__PURE__ */
|
|
9452
|
+
/* @__PURE__ */ jsx4(EffectsSettings, {}),
|
|
9453
|
+
/* @__PURE__ */ jsx4(CaptionLanguageSettings, {})
|
|
7797
9454
|
] });
|
|
7798
9455
|
}
|
|
7799
9456
|
function DeviceSettings({
|
|
@@ -7805,15 +9462,15 @@ function DeviceSettings({
|
|
|
7805
9462
|
const speaker = devices?.selected.audiooutput ?? host.devices.resolve("audiooutput");
|
|
7806
9463
|
const stream = useMicrophoneStream(microphone);
|
|
7807
9464
|
const level = useAudioLevel(stream);
|
|
7808
|
-
const [testing, setTesting] =
|
|
7809
|
-
|
|
9465
|
+
const [testing, setTesting] = useState4(false);
|
|
9466
|
+
useEffect4(() => {
|
|
7810
9467
|
void host.devices.refresh();
|
|
7811
9468
|
}, [host]);
|
|
7812
|
-
return /* @__PURE__ */
|
|
7813
|
-
/* @__PURE__ */
|
|
7814
|
-
/* @__PURE__ */
|
|
7815
|
-
/* @__PURE__ */
|
|
7816
|
-
/* @__PURE__ */
|
|
9469
|
+
return /* @__PURE__ */ jsxs3("section", { className: "mx-meet__section", "aria-label": "Devices", children: [
|
|
9470
|
+
/* @__PURE__ */ jsx4(DevicePicker, { kind: "audioinput", label: "Microphone", onPick }),
|
|
9471
|
+
/* @__PURE__ */ jsx4("div", { className: "mx-meet__meter", role: "meter", "aria-label": "Microphone level", "aria-valuemin": 0, "aria-valuemax": 100, "aria-valuenow": Math.round(level * 100), children: /* @__PURE__ */ jsx4("span", { style: { width: `${Math.min(100, Math.round(level * 160))}%` } }) }),
|
|
9472
|
+
/* @__PURE__ */ jsx4(DevicePicker, { kind: "audiooutput", label: "Speaker", onPick }),
|
|
9473
|
+
/* @__PURE__ */ jsxs3(
|
|
7817
9474
|
"button",
|
|
7818
9475
|
{
|
|
7819
9476
|
type: "button",
|
|
@@ -7824,19 +9481,19 @@ function DeviceSettings({
|
|
|
7824
9481
|
void playTestSound(speaker).finally(() => setTesting(false));
|
|
7825
9482
|
},
|
|
7826
9483
|
children: [
|
|
7827
|
-
/* @__PURE__ */
|
|
9484
|
+
/* @__PURE__ */ jsx4(SpeakerIcon, { width: 14, height: 14 }),
|
|
7828
9485
|
" ",
|
|
7829
9486
|
testing ? "Playing\u2026" : "Test speaker"
|
|
7830
9487
|
]
|
|
7831
9488
|
}
|
|
7832
9489
|
),
|
|
7833
|
-
/* @__PURE__ */
|
|
9490
|
+
/* @__PURE__ */ jsx4(DevicePicker, { kind: "videoinput", label: "Camera", onPick })
|
|
7834
9491
|
] });
|
|
7835
9492
|
}
|
|
7836
9493
|
function EffectsSettings({ preview }) {
|
|
7837
9494
|
const effects = useMediaEffects();
|
|
7838
|
-
const [error, setError] =
|
|
7839
|
-
const fileRef =
|
|
9495
|
+
const [error, setError] = useState4(null);
|
|
9496
|
+
const fileRef = useRef4(null);
|
|
7840
9497
|
const supported = effects.backgroundsSupported || preview != null || videoEffectsSupported();
|
|
7841
9498
|
const apply = (next) => {
|
|
7842
9499
|
setError(null);
|
|
@@ -7848,9 +9505,9 @@ function EffectsSettings({ preview }) {
|
|
|
7848
9505
|
);
|
|
7849
9506
|
}
|
|
7850
9507
|
};
|
|
7851
|
-
return /* @__PURE__ */
|
|
7852
|
-
/* @__PURE__ */
|
|
7853
|
-
/* @__PURE__ */
|
|
9508
|
+
return /* @__PURE__ */ jsxs3("section", { className: "mx-meet__section", "aria-label": "Effects", children: [
|
|
9509
|
+
/* @__PURE__ */ jsxs3("label", { className: "mx-meet__toggle", children: [
|
|
9510
|
+
/* @__PURE__ */ jsx4(
|
|
7854
9511
|
"input",
|
|
7855
9512
|
{
|
|
7856
9513
|
type: "checkbox",
|
|
@@ -7859,11 +9516,11 @@ function EffectsSettings({ preview }) {
|
|
|
7859
9516
|
}
|
|
7860
9517
|
),
|
|
7861
9518
|
"Noise suppression",
|
|
7862
|
-
/* @__PURE__ */
|
|
9519
|
+
/* @__PURE__ */ jsx4("span", { className: "mx-meet__hint", children: "Filters keyboards, fans and background chatter." })
|
|
7863
9520
|
] }),
|
|
7864
|
-
supported ? /* @__PURE__ */
|
|
7865
|
-
/* @__PURE__ */
|
|
7866
|
-
/* @__PURE__ */
|
|
9521
|
+
supported ? /* @__PURE__ */ jsxs3("div", { className: "mx-meet__field", children: [
|
|
9522
|
+
/* @__PURE__ */ jsx4("span", { className: "mx-meet__field-label", children: "Background" }),
|
|
9523
|
+
/* @__PURE__ */ jsx4("div", { className: "mx-meet__pills", role: "radiogroup", "aria-label": "Background", children: ["none", "blur", "image"].map((kind) => /* @__PURE__ */ jsx4(
|
|
7867
9524
|
"button",
|
|
7868
9525
|
{
|
|
7869
9526
|
type: "button",
|
|
@@ -7881,7 +9538,7 @@ function EffectsSettings({ preview }) {
|
|
|
7881
9538
|
},
|
|
7882
9539
|
kind
|
|
7883
9540
|
)) }),
|
|
7884
|
-
/* @__PURE__ */
|
|
9541
|
+
/* @__PURE__ */ jsx4(
|
|
7885
9542
|
"input",
|
|
7886
9543
|
{
|
|
7887
9544
|
ref: fileRef,
|
|
@@ -7896,7 +9553,7 @@ function EffectsSettings({ preview }) {
|
|
|
7896
9553
|
}
|
|
7897
9554
|
}
|
|
7898
9555
|
),
|
|
7899
|
-
error !== null ? /* @__PURE__ */
|
|
9556
|
+
error !== null ? /* @__PURE__ */ jsx4("p", { className: "mx-meet__error", children: error }) : null
|
|
7900
9557
|
] }) : null
|
|
7901
9558
|
] });
|
|
7902
9559
|
}
|
|
@@ -7955,8 +9612,8 @@ async function playTestSound(sinkId) {
|
|
|
7955
9612
|
await context.close();
|
|
7956
9613
|
}
|
|
7957
9614
|
function useMicrophoneStream(deviceId2) {
|
|
7958
|
-
const [stream, setStream] =
|
|
7959
|
-
|
|
9615
|
+
const [stream, setStream] = useState4(null);
|
|
9616
|
+
useEffect4(() => {
|
|
7960
9617
|
if (deviceId2 === "off") return void 0;
|
|
7961
9618
|
let live = true;
|
|
7962
9619
|
let opened = null;
|
|
@@ -7981,25 +9638,25 @@ function useMicrophoneStream(deviceId2) {
|
|
|
7981
9638
|
function LobbyPanel() {
|
|
7982
9639
|
const lobby = useLobby();
|
|
7983
9640
|
if (!lobby.canAdmit || lobby.waiting.length === 0) return null;
|
|
7984
|
-
return /* @__PURE__ */
|
|
7985
|
-
/* @__PURE__ */
|
|
7986
|
-
/* @__PURE__ */
|
|
7987
|
-
/* @__PURE__ */
|
|
9641
|
+
return /* @__PURE__ */ jsxs3("section", { className: "mx-meet__lobby", "aria-label": "Waiting room", children: [
|
|
9642
|
+
/* @__PURE__ */ jsxs3("header", { className: "mx-meet__lobby-head", children: [
|
|
9643
|
+
/* @__PURE__ */ jsx4("h3", { className: "mx-meet__lobby-title", children: lobby.waiting.length === 1 ? "1 person is waiting" : `${lobby.waiting.length} people are waiting` }),
|
|
9644
|
+
/* @__PURE__ */ jsx4("button", { type: "button", className: "mx-meet__link", onClick: () => void lobby.admitAll(), children: "Admit all" })
|
|
7988
9645
|
] }),
|
|
7989
|
-
/* @__PURE__ */
|
|
7990
|
-
/* @__PURE__ */
|
|
7991
|
-
/* @__PURE__ */
|
|
9646
|
+
/* @__PURE__ */ jsx4("ul", { className: "mx-meet__lobby-list", children: lobby.waiting.map((entry) => /* @__PURE__ */ jsxs3("li", { className: "mx-meet__lobby-row", children: [
|
|
9647
|
+
/* @__PURE__ */ jsx4(Avatar, { name: entry.displayName, url: entry.avatarUrl, size: 32 }),
|
|
9648
|
+
/* @__PURE__ */ jsxs3("span", { className: "mx-meet__person-name", children: [
|
|
7992
9649
|
entry.displayName,
|
|
7993
|
-
entry.userId === null ? /* @__PURE__ */
|
|
9650
|
+
entry.userId === null ? /* @__PURE__ */ jsx4("span", { className: "mx-meet__badge", children: "Guest" }) : null
|
|
7994
9651
|
] }),
|
|
7995
|
-
/* @__PURE__ */
|
|
7996
|
-
/* @__PURE__ */
|
|
9652
|
+
/* @__PURE__ */ jsx4(ControlButton, { label: `Admit ${entry.displayName}`, onClick: () => void lobby.admit(entry), children: /* @__PURE__ */ jsx4(CheckIcon, { width: 16, height: 16 }) }),
|
|
9653
|
+
/* @__PURE__ */ jsx4(
|
|
7997
9654
|
ControlButton,
|
|
7998
9655
|
{
|
|
7999
9656
|
label: `Deny ${entry.displayName}`,
|
|
8000
9657
|
danger: true,
|
|
8001
9658
|
onClick: () => void lobby.deny(entry),
|
|
8002
|
-
children: /* @__PURE__ */
|
|
9659
|
+
children: /* @__PURE__ */ jsx4(CloseIcon, { width: 16, height: 16 })
|
|
8003
9660
|
}
|
|
8004
9661
|
)
|
|
8005
9662
|
] }, entry.identity)) })
|
|
@@ -8009,21 +9666,21 @@ function NoteTakerRow() {
|
|
|
8009
9666
|
const ai = useMeetAi();
|
|
8010
9667
|
const status = ai.noteTaker;
|
|
8011
9668
|
const duplicateError = status.refusal !== null && ai.error !== null && status.refusal.reason === ai.error.message && status.refusal.remedy === ai.error.remedy;
|
|
8012
|
-
return /* @__PURE__ */
|
|
8013
|
-
/* @__PURE__ */
|
|
8014
|
-
/* @__PURE__ */
|
|
9669
|
+
return /* @__PURE__ */ jsxs3("section", { className: "mx-meet__note-taker", "aria-label": "Note-taker", children: [
|
|
9670
|
+
/* @__PURE__ */ jsxs3("p", { className: `mx-meet__note-taker-state mx-meet__note-taker-state--${status.state}`, children: [
|
|
9671
|
+
/* @__PURE__ */ jsx4("span", { className: "mx-meet__note-taker-dot", "aria-hidden": "true" }),
|
|
8015
9672
|
ai.noteTakerLabel
|
|
8016
9673
|
] }),
|
|
8017
|
-
status.detail !== null ? /* @__PURE__ */
|
|
8018
|
-
status.refusal !== null ? /* @__PURE__ */
|
|
8019
|
-
/* @__PURE__ */
|
|
8020
|
-
status.refusal.remedy.length > 0 ? /* @__PURE__ */
|
|
9674
|
+
status.detail !== null ? /* @__PURE__ */ jsx4("p", { className: "mx-meet__panel-note", children: status.detail }) : null,
|
|
9675
|
+
status.refusal !== null ? /* @__PURE__ */ jsxs3(ErrorBox, { as: "div", className: "mx-meet__refusal", error: status.refusal, operation: "Join this meeting", origin: "meet/components", children: [
|
|
9676
|
+
/* @__PURE__ */ jsx4("p", { className: "mx-meet__refusal-reason", children: status.refusal.reason }),
|
|
9677
|
+
status.refusal.remedy.length > 0 ? /* @__PURE__ */ jsx4("p", { className: "mx-meet__refusal-remedy", children: status.refusal.remedy }) : null
|
|
8021
9678
|
] }) : null,
|
|
8022
|
-
ai.error !== null && !duplicateError ? /* @__PURE__ */
|
|
8023
|
-
/* @__PURE__ */
|
|
8024
|
-
/* @__PURE__ */
|
|
9679
|
+
ai.error !== null && !duplicateError ? /* @__PURE__ */ jsxs3(ErrorBox, { as: "div", className: "mx-meet__refusal", error: ai.error, operation: "Run the meeting assistant", origin: "meet/components", children: [
|
|
9680
|
+
/* @__PURE__ */ jsx4("p", { className: "mx-meet__refusal-reason", children: ai.error.message }),
|
|
9681
|
+
/* @__PURE__ */ jsx4("p", { className: "mx-meet__refusal-remedy", children: ai.error.remedy })
|
|
8025
9682
|
] }) : null,
|
|
8026
|
-
ai.canControlNoteTaker ? status.state === "transcribing" || status.state === "joining" || status.state === "handoff_pending" ? /* @__PURE__ */
|
|
9683
|
+
ai.canControlNoteTaker ? status.state === "transcribing" || status.state === "joining" || status.state === "handoff_pending" ? /* @__PURE__ */ jsx4(
|
|
8027
9684
|
"button",
|
|
8028
9685
|
{
|
|
8029
9686
|
type: "button",
|
|
@@ -8031,7 +9688,7 @@ function NoteTakerRow() {
|
|
|
8031
9688
|
onClick: () => void ai.stopNoteTaker(),
|
|
8032
9689
|
children: "Dismiss the note-taker"
|
|
8033
9690
|
}
|
|
8034
|
-
) : /* @__PURE__ */
|
|
9691
|
+
) : /* @__PURE__ */ jsx4(
|
|
8035
9692
|
"button",
|
|
8036
9693
|
{
|
|
8037
9694
|
type: "button",
|
|
@@ -8047,24 +9704,24 @@ function NoteList({
|
|
|
8047
9704
|
notes,
|
|
8048
9705
|
empty
|
|
8049
9706
|
}) {
|
|
8050
|
-
return /* @__PURE__ */
|
|
8051
|
-
/* @__PURE__ */
|
|
8052
|
-
notes.length === 0 ? /* @__PURE__ */
|
|
9707
|
+
return /* @__PURE__ */ jsxs3("section", { className: "mx-meet__note-group", "aria-label": title, children: [
|
|
9708
|
+
/* @__PURE__ */ jsx4("h3", { className: "mx-meet__note-group-title", children: title }),
|
|
9709
|
+
notes.length === 0 ? /* @__PURE__ */ jsx4("p", { className: "mx-meet__panel-note", children: empty }) : /* @__PURE__ */ jsx4("ul", { className: "mx-meet__notes", children: notes.map((note) => /* @__PURE__ */ jsxs3("li", { className: "mx-meet__note", children: [
|
|
8053
9710
|
note.text,
|
|
8054
|
-
note.assigneeDisplayName !== void 0 && note.assigneeDisplayName !== null ? /* @__PURE__ */
|
|
9711
|
+
note.assigneeDisplayName !== void 0 && note.assigneeDisplayName !== null ? /* @__PURE__ */ jsx4("span", { className: "mx-meet__assignee", children: note.assigneeDisplayName }) : null
|
|
8055
9712
|
] }, note.id)) })
|
|
8056
9713
|
] });
|
|
8057
9714
|
}
|
|
8058
9715
|
function AiPanel({ onClose }) {
|
|
8059
9716
|
const ai = useMeetAi();
|
|
8060
|
-
const [question, setQuestion] =
|
|
8061
|
-
return /* @__PURE__ */
|
|
8062
|
-
/* @__PURE__ */
|
|
8063
|
-
ai.summary !== null ? /* @__PURE__ */
|
|
8064
|
-
/* @__PURE__ */
|
|
8065
|
-
/* @__PURE__ */
|
|
9717
|
+
const [question, setQuestion] = useState4("");
|
|
9718
|
+
return /* @__PURE__ */ jsxs3(PanelShell, { title: "Meeting assistant", onClose, children: [
|
|
9719
|
+
/* @__PURE__ */ jsx4(NoteTakerRow, {}),
|
|
9720
|
+
ai.summary !== null ? /* @__PURE__ */ jsxs3("section", { className: "mx-meet__note-group", "aria-label": "Summary", children: [
|
|
9721
|
+
/* @__PURE__ */ jsx4("h3", { className: "mx-meet__note-group-title", children: "Summary" }),
|
|
9722
|
+
/* @__PURE__ */ jsx4("p", { className: "mx-meet__summary", children: ai.summary.text })
|
|
8066
9723
|
] }) : null,
|
|
8067
|
-
ai.wrapUp !== null ? /* @__PURE__ */
|
|
9724
|
+
ai.wrapUp !== null ? /* @__PURE__ */ jsxs3("p", { className: "mx-meet__wrap-up-notice", role: "status", children: [
|
|
8068
9725
|
"The wrap-up is written \u2014 ",
|
|
8069
9726
|
ai.wrapUp.noteIds.length,
|
|
8070
9727
|
" ",
|
|
@@ -8076,7 +9733,7 @@ function AiPanel({ onClose }) {
|
|
|
8076
9733
|
ai.wrapUp.segmentCount === 1 ? "transcript line" : "transcript lines",
|
|
8077
9734
|
"."
|
|
8078
9735
|
] }) : null,
|
|
8079
|
-
/* @__PURE__ */
|
|
9736
|
+
/* @__PURE__ */ jsx4(
|
|
8080
9737
|
NoteList,
|
|
8081
9738
|
{
|
|
8082
9739
|
title: "Notes",
|
|
@@ -8084,7 +9741,7 @@ function AiPanel({ onClose }) {
|
|
|
8084
9741
|
empty: "Notes appear here as the meeting goes on."
|
|
8085
9742
|
}
|
|
8086
9743
|
),
|
|
8087
|
-
/* @__PURE__ */
|
|
9744
|
+
/* @__PURE__ */ jsx4(
|
|
8088
9745
|
NoteList,
|
|
8089
9746
|
{
|
|
8090
9747
|
title: "Decisions",
|
|
@@ -8092,7 +9749,7 @@ function AiPanel({ onClose }) {
|
|
|
8092
9749
|
empty: "Nothing has been decided yet."
|
|
8093
9750
|
}
|
|
8094
9751
|
),
|
|
8095
|
-
/* @__PURE__ */
|
|
9752
|
+
/* @__PURE__ */ jsx4(
|
|
8096
9753
|
NoteList,
|
|
8097
9754
|
{
|
|
8098
9755
|
title: "Action items",
|
|
@@ -8100,21 +9757,21 @@ function AiPanel({ onClose }) {
|
|
|
8100
9757
|
empty: "No action items yet."
|
|
8101
9758
|
}
|
|
8102
9759
|
),
|
|
8103
|
-
ai.transcript.length > 0 ? /* @__PURE__ */
|
|
8104
|
-
/* @__PURE__ */
|
|
8105
|
-
/* @__PURE__ */
|
|
9760
|
+
ai.transcript.length > 0 ? /* @__PURE__ */ jsxs3("section", { className: "mx-meet__note-group", "aria-label": "Transcript", children: [
|
|
9761
|
+
/* @__PURE__ */ jsx4("h3", { className: "mx-meet__note-group-title", children: "Transcript" }),
|
|
9762
|
+
/* @__PURE__ */ jsx4("ul", { className: "mx-meet__transcript", children: ai.transcript.map((line) => /* @__PURE__ */ jsxs3(
|
|
8106
9763
|
"li",
|
|
8107
9764
|
{
|
|
8108
9765
|
className: line.final && line.source === "record" ? "mx-meet__line" : "mx-meet__line mx-meet__line--interim",
|
|
8109
9766
|
children: [
|
|
8110
|
-
/* @__PURE__ */
|
|
8111
|
-
/* @__PURE__ */
|
|
9767
|
+
/* @__PURE__ */ jsx4("strong", { children: line.speaker }),
|
|
9768
|
+
/* @__PURE__ */ jsx4("span", { children: line.text })
|
|
8112
9769
|
]
|
|
8113
9770
|
},
|
|
8114
9771
|
line.id
|
|
8115
9772
|
)) })
|
|
8116
9773
|
] }) : null,
|
|
8117
|
-
/* @__PURE__ */
|
|
9774
|
+
/* @__PURE__ */ jsxs3(
|
|
8118
9775
|
"form",
|
|
8119
9776
|
{
|
|
8120
9777
|
className: "mx-meet__composer",
|
|
@@ -8125,7 +9782,7 @@ function AiPanel({ onClose }) {
|
|
|
8125
9782
|
void ai.ask(asked);
|
|
8126
9783
|
},
|
|
8127
9784
|
children: [
|
|
8128
|
-
/* @__PURE__ */
|
|
9785
|
+
/* @__PURE__ */ jsx4(
|
|
8129
9786
|
"input",
|
|
8130
9787
|
{
|
|
8131
9788
|
className: "mx-meet__input",
|
|
@@ -8135,13 +9792,13 @@ function AiPanel({ onClose }) {
|
|
|
8135
9792
|
"aria-label": "Ask about this meeting"
|
|
8136
9793
|
}
|
|
8137
9794
|
),
|
|
8138
|
-
/* @__PURE__ */
|
|
9795
|
+
/* @__PURE__ */ jsx4("button", { type: "submit", className: "mx-meet__send", disabled: ai.asking, children: ai.asking ? "Asking\u2026" : "Ask" })
|
|
8139
9796
|
]
|
|
8140
9797
|
}
|
|
8141
9798
|
),
|
|
8142
|
-
ai.asking && ai.phase !== null ? /* @__PURE__ */
|
|
8143
|
-
ai.answer !== null ? /* @__PURE__ */
|
|
8144
|
-
ai.answer !== null && ai.coverage !== null ? /* @__PURE__ */
|
|
9799
|
+
ai.asking && ai.phase !== null ? /* @__PURE__ */ jsx4("p", { className: "mx-meet__panel-note", role: "status", children: ai.phase }) : null,
|
|
9800
|
+
ai.answer !== null ? /* @__PURE__ */ jsx4("p", { className: "mx-meet__answer", children: ai.answer }) : null,
|
|
9801
|
+
ai.answer !== null && ai.coverage !== null ? /* @__PURE__ */ jsxs3("p", { className: "mx-meet__coverage", children: [
|
|
8145
9802
|
"Answered from ",
|
|
8146
9803
|
ai.coverage.segmentsUsed,
|
|
8147
9804
|
" of ",
|
|
@@ -8150,48 +9807,56 @@ function AiPanel({ onClose }) {
|
|
|
8150
9807
|
ai.coverage.truncated ? " (the oldest were left out)" : "",
|
|
8151
9808
|
"."
|
|
8152
9809
|
] }) : null,
|
|
8153
|
-
ai.error !== null ? /* @__PURE__ */
|
|
8154
|
-
/* @__PURE__ */
|
|
8155
|
-
/* @__PURE__ */
|
|
9810
|
+
ai.error !== null ? /* @__PURE__ */ jsxs3(ErrorBox, { as: "div", className: "mx-meet__refusal", error: ai.error, operation: "Run the meeting assistant", origin: "meet/components", children: [
|
|
9811
|
+
/* @__PURE__ */ jsx4("p", { className: "mx-meet__refusal-reason", children: ai.error.message }),
|
|
9812
|
+
/* @__PURE__ */ jsx4("p", { className: "mx-meet__refusal-remedy", children: ai.error.remedy })
|
|
8156
9813
|
] }) : null
|
|
8157
9814
|
] });
|
|
8158
9815
|
}
|
|
8159
9816
|
function Captions({ lines = 3 }) {
|
|
8160
9817
|
const ai = useMeetAi();
|
|
8161
9818
|
const visible = ai.transcript.slice(-lines);
|
|
9819
|
+
const translation = useCaptionTranslation(visible);
|
|
8162
9820
|
if (visible.length === 0) return null;
|
|
8163
|
-
return /* @__PURE__ */
|
|
8164
|
-
|
|
8165
|
-
|
|
8166
|
-
|
|
8167
|
-
|
|
8168
|
-
|
|
8169
|
-
|
|
8170
|
-
|
|
8171
|
-
|
|
8172
|
-
|
|
8173
|
-
|
|
8174
|
-
|
|
9821
|
+
return /* @__PURE__ */ jsxs3("div", { className: "mx-meet__captions", "aria-live": "polite", "aria-label": "Live captions", children: [
|
|
9822
|
+
visible.map((line) => {
|
|
9823
|
+
const translated = translation.language === null ? void 0 : translation.translations[line.id];
|
|
9824
|
+
return /* @__PURE__ */ jsxs3(
|
|
9825
|
+
"p",
|
|
9826
|
+
{
|
|
9827
|
+
className: line.final ? "mx-meet__caption" : "mx-meet__caption mx-meet__caption--interim",
|
|
9828
|
+
children: [
|
|
9829
|
+
/* @__PURE__ */ jsx4("strong", { children: line.speaker }),
|
|
9830
|
+
" ",
|
|
9831
|
+
translated ?? line.text,
|
|
9832
|
+
translated !== void 0 ? /* @__PURE__ */ jsx4("span", { className: "mx-meet__caption-original", children: line.text }) : null
|
|
9833
|
+
]
|
|
9834
|
+
},
|
|
9835
|
+
line.id
|
|
9836
|
+
);
|
|
9837
|
+
}),
|
|
9838
|
+
translation.language !== null && translation.error !== null ? /* @__PURE__ */ jsx4("p", { className: "mx-meet__caption mx-meet__caption--interim", children: translation.error }) : null
|
|
9839
|
+
] });
|
|
8175
9840
|
}
|
|
8176
9841
|
function ConsentNotice() {
|
|
8177
9842
|
const notice = useConsentNotice();
|
|
8178
9843
|
if (notice === null) return null;
|
|
8179
|
-
return /* @__PURE__ */
|
|
9844
|
+
return /* @__PURE__ */ jsx4("p", { className: "mx-meet__consent", role: "status", children: notice });
|
|
8180
9845
|
}
|
|
8181
9846
|
function AttendanceNotice() {
|
|
8182
9847
|
const media = useLocalMedia();
|
|
8183
9848
|
const notice = listenOnlyNotice(media);
|
|
8184
9849
|
if (notice === null) return null;
|
|
8185
9850
|
const refused = media.microphone.unavailable;
|
|
8186
|
-
return /* @__PURE__ */
|
|
9851
|
+
return /* @__PURE__ */ jsxs3("p", { className: "mx-meet__banner mx-meet__banner--attendance", role: "status", children: [
|
|
8187
9852
|
notice,
|
|
8188
|
-
refused === null ? null : /* @__PURE__ */
|
|
9853
|
+
refused === null ? null : /* @__PURE__ */ jsx4("span", { className: "mx-meet__remedy", children: refused.remedy })
|
|
8189
9854
|
] });
|
|
8190
9855
|
}
|
|
8191
9856
|
function PreJoin(props) {
|
|
8192
9857
|
const host = useMeetHost();
|
|
8193
|
-
if (host === null) return /* @__PURE__ */
|
|
8194
|
-
return /* @__PURE__ */
|
|
9858
|
+
if (host === null) return /* @__PURE__ */ jsx4(InertNotice, { what: "This meeting" });
|
|
9859
|
+
return /* @__PURE__ */ jsx4(PreJoinBody, { ...props, host });
|
|
8195
9860
|
}
|
|
8196
9861
|
function PreJoinBody({
|
|
8197
9862
|
roomName,
|
|
@@ -8205,21 +9870,21 @@ function PreJoinBody({
|
|
|
8205
9870
|
const recording = useRecording();
|
|
8206
9871
|
const effects = useMediaEffects();
|
|
8207
9872
|
const { notice } = useModerationNotice();
|
|
8208
|
-
const [mode, setMode] =
|
|
8209
|
-
const [microphone, setMicrophone] =
|
|
8210
|
-
const [joining, setJoining] =
|
|
9873
|
+
const [mode, setMode] = useState4("video");
|
|
9874
|
+
const [microphone, setMicrophone] = useState4(true);
|
|
9875
|
+
const [joining, setJoining] = useState4(false);
|
|
8211
9876
|
const camera = devices?.selected.videoinput ?? host.devices.resolve("videoinput");
|
|
8212
9877
|
const mic = devices?.selected.audioinput ?? host.devices.resolve("audioinput");
|
|
8213
9878
|
const preview = useCameraPreview(mode === "video" ? camera : void 0, effects.effects);
|
|
8214
9879
|
const micStream = useMicrophoneStream(microphone ? mic : "off");
|
|
8215
9880
|
const level = useAudioLevel(micStream);
|
|
8216
|
-
const [speakerTesting, setSpeakerTesting] =
|
|
8217
|
-
|
|
9881
|
+
const [speakerTesting, setSpeakerTesting] = useState4(false);
|
|
9882
|
+
useEffect4(() => {
|
|
8218
9883
|
void host.devices.refresh();
|
|
8219
9884
|
}, [host]);
|
|
8220
|
-
return /* @__PURE__ */
|
|
8221
|
-
/* @__PURE__ */
|
|
8222
|
-
mode === "video" && preview.preview !== null ? /* @__PURE__ */
|
|
9885
|
+
return /* @__PURE__ */ jsxs3("div", { className: "mx-meet__prejoin", children: [
|
|
9886
|
+
/* @__PURE__ */ jsxs3("div", { className: "mx-meet__preview", children: [
|
|
9887
|
+
mode === "video" && preview.preview !== null ? /* @__PURE__ */ jsx4(
|
|
8223
9888
|
"video",
|
|
8224
9889
|
{
|
|
8225
9890
|
className: "mx-meet__video mx-meet__video--mirror",
|
|
@@ -8230,16 +9895,16 @@ function PreJoinBody({
|
|
|
8230
9895
|
if (element !== null) preview.preview?.attach(element);
|
|
8231
9896
|
}
|
|
8232
9897
|
}
|
|
8233
|
-
) : /* @__PURE__ */
|
|
8234
|
-
mode === "video" && preview.error !== null ? /* @__PURE__ */
|
|
8235
|
-
microphone && micStream !== null ? /* @__PURE__ */
|
|
9898
|
+
) : /* @__PURE__ */ jsx4("div", { className: "mx-meet__tile-placeholder", children: /* @__PURE__ */ jsx4(Avatar, { name: host.identity.displayName, url: host.identity.avatarUrl, size: 96 }) }),
|
|
9899
|
+
mode === "video" && preview.error !== null ? /* @__PURE__ */ jsx4("p", { className: "mx-meet__preview-note", children: preview.error }) : null,
|
|
9900
|
+
microphone && micStream !== null ? /* @__PURE__ */ jsx4("div", { className: "mx-meet__meter mx-meet__meter--preview", role: "meter", "aria-label": "Microphone level", "aria-valuemin": 0, "aria-valuemax": 100, "aria-valuenow": Math.round(level * 100), children: /* @__PURE__ */ jsx4("span", { style: { width: `${Math.min(100, Math.round(level * 160))}%` } }) }) : null
|
|
8236
9901
|
] }),
|
|
8237
|
-
/* @__PURE__ */
|
|
8238
|
-
/* @__PURE__ */
|
|
8239
|
-
notice?.kind === "removed" ? /* @__PURE__ */
|
|
8240
|
-
devices?.labelsHidden === true ? /* @__PURE__ */
|
|
9902
|
+
/* @__PURE__ */ jsxs3("div", { className: "mx-meet__prejoin-panel", children: [
|
|
9903
|
+
/* @__PURE__ */ jsx4("h1", { className: "mx-meet__prejoin-title", children: "Ready to join?" }),
|
|
9904
|
+
notice?.kind === "removed" ? /* @__PURE__ */ jsx4("p", { className: "mx-meet__warning", children: notice.text }) : null,
|
|
9905
|
+
devices?.labelsHidden === true ? /* @__PURE__ */ jsxs3("p", { className: "mx-meet__panel-note", children: [
|
|
8241
9906
|
"Your browser is hiding device names until you allow camera and microphone access.",
|
|
8242
|
-
/* @__PURE__ */
|
|
9907
|
+
/* @__PURE__ */ jsx4(
|
|
8243
9908
|
"button",
|
|
8244
9909
|
{
|
|
8245
9910
|
type: "button",
|
|
@@ -8251,11 +9916,11 @@ function PreJoinBody({
|
|
|
8251
9916
|
}
|
|
8252
9917
|
)
|
|
8253
9918
|
] }) : null,
|
|
8254
|
-
devices?.fallbackNotice != null ? /* @__PURE__ */
|
|
8255
|
-
/* @__PURE__ */
|
|
8256
|
-
/* @__PURE__ */
|
|
8257
|
-
/* @__PURE__ */
|
|
8258
|
-
/* @__PURE__ */
|
|
9919
|
+
devices?.fallbackNotice != null ? /* @__PURE__ */ jsx4("p", { className: "mx-meet__warning", children: devices.fallbackNotice }) : null,
|
|
9920
|
+
/* @__PURE__ */ jsx4(DevicePicker, { kind: "audioinput", label: "Microphone" }),
|
|
9921
|
+
/* @__PURE__ */ jsxs3("div", { className: "mx-meet__field-row", children: [
|
|
9922
|
+
/* @__PURE__ */ jsx4(DevicePicker, { kind: "audiooutput", label: "Speaker" }),
|
|
9923
|
+
/* @__PURE__ */ jsxs3(
|
|
8259
9924
|
"button",
|
|
8260
9925
|
{
|
|
8261
9926
|
type: "button",
|
|
@@ -8268,19 +9933,19 @@ function PreJoinBody({
|
|
|
8268
9933
|
);
|
|
8269
9934
|
},
|
|
8270
9935
|
children: [
|
|
8271
|
-
/* @__PURE__ */
|
|
9936
|
+
/* @__PURE__ */ jsx4(SpeakerIcon, { width: 14, height: 14 }),
|
|
8272
9937
|
" ",
|
|
8273
9938
|
speakerTesting ? "Playing\u2026" : "Test"
|
|
8274
9939
|
]
|
|
8275
9940
|
}
|
|
8276
9941
|
)
|
|
8277
9942
|
] }),
|
|
8278
|
-
/* @__PURE__ */
|
|
8279
|
-
/* @__PURE__ */
|
|
8280
|
-
recording.consentNotice !== null ? /* @__PURE__ */
|
|
8281
|
-
/* @__PURE__ */
|
|
8282
|
-
/* @__PURE__ */
|
|
8283
|
-
/* @__PURE__ */
|
|
9943
|
+
/* @__PURE__ */ jsx4(DevicePicker, { kind: "videoinput", label: "Camera" }),
|
|
9944
|
+
/* @__PURE__ */ jsx4(EffectsSettings, { preview: preview.preview }),
|
|
9945
|
+
recording.consentNotice !== null ? /* @__PURE__ */ jsx4("p", { className: "mx-meet__consent", children: recording.consentNotice }) : null,
|
|
9946
|
+
/* @__PURE__ */ jsxs3("div", { className: "mx-meet__prejoin-actions", children: [
|
|
9947
|
+
/* @__PURE__ */ jsxs3("label", { className: "mx-meet__toggle", children: [
|
|
9948
|
+
/* @__PURE__ */ jsx4(
|
|
8284
9949
|
"input",
|
|
8285
9950
|
{
|
|
8286
9951
|
type: "checkbox",
|
|
@@ -8290,8 +9955,8 @@ function PreJoinBody({
|
|
|
8290
9955
|
),
|
|
8291
9956
|
"Join with video"
|
|
8292
9957
|
] }),
|
|
8293
|
-
/* @__PURE__ */
|
|
8294
|
-
/* @__PURE__ */
|
|
9958
|
+
/* @__PURE__ */ jsxs3("label", { className: "mx-meet__toggle", children: [
|
|
9959
|
+
/* @__PURE__ */ jsx4(
|
|
8295
9960
|
"input",
|
|
8296
9961
|
{
|
|
8297
9962
|
type: "checkbox",
|
|
@@ -8301,7 +9966,7 @@ function PreJoinBody({
|
|
|
8301
9966
|
),
|
|
8302
9967
|
"Join with microphone"
|
|
8303
9968
|
] }),
|
|
8304
|
-
/* @__PURE__ */
|
|
9969
|
+
/* @__PURE__ */ jsx4(
|
|
8305
9970
|
"button",
|
|
8306
9971
|
{
|
|
8307
9972
|
type: "button",
|
|
@@ -8321,20 +9986,20 @@ function PreJoinBody({
|
|
|
8321
9986
|
}
|
|
8322
9987
|
)
|
|
8323
9988
|
] }),
|
|
8324
|
-
room.failure !== null ? /* @__PURE__ */
|
|
9989
|
+
room.failure !== null ? /* @__PURE__ */ jsxs3("p", { className: "mx-meet__error", children: [
|
|
8325
9990
|
room.failure.message,
|
|
8326
|
-
/* @__PURE__ */
|
|
9991
|
+
/* @__PURE__ */ jsx4("span", { className: "mx-meet__remedy", children: room.failure.remedy })
|
|
8327
9992
|
] }) : null
|
|
8328
9993
|
] })
|
|
8329
9994
|
] });
|
|
8330
9995
|
}
|
|
8331
9996
|
function useCameraPreview(deviceId2, effects) {
|
|
8332
|
-
const [preview, setPreview] =
|
|
8333
|
-
const [error, setError] =
|
|
8334
|
-
const current =
|
|
8335
|
-
const initialEffect =
|
|
9997
|
+
const [preview, setPreview] = useState4(null);
|
|
9998
|
+
const [error, setError] = useState4(null);
|
|
9999
|
+
const current = useRef4(null);
|
|
10000
|
+
const initialEffect = useRef4(toVideoEffect(effects));
|
|
8336
10001
|
initialEffect.current = toVideoEffect(effects);
|
|
8337
|
-
|
|
10002
|
+
useEffect4(() => {
|
|
8338
10003
|
if (deviceId2 === void 0) return void 0;
|
|
8339
10004
|
let live = true;
|
|
8340
10005
|
setError(null);
|
|
@@ -8378,9 +10043,9 @@ function DevicePicker({
|
|
|
8378
10043
|
const devices = useDeviceSnapshot();
|
|
8379
10044
|
const list = devices?.devices[kind] ?? [];
|
|
8380
10045
|
if (list.length === 0) return null;
|
|
8381
|
-
return /* @__PURE__ */
|
|
8382
|
-
/* @__PURE__ */
|
|
8383
|
-
/* @__PURE__ */
|
|
10046
|
+
return /* @__PURE__ */ jsxs3("label", { className: "mx-meet__field", children: [
|
|
10047
|
+
/* @__PURE__ */ jsx4("span", { className: "mx-meet__field-label", children: label }),
|
|
10048
|
+
/* @__PURE__ */ jsx4(
|
|
8384
10049
|
"select",
|
|
8385
10050
|
{
|
|
8386
10051
|
className: "mx-meet__select",
|
|
@@ -8389,7 +10054,7 @@ function DevicePicker({
|
|
|
8389
10054
|
if (onPick !== void 0) onPick(kind, event.target.value);
|
|
8390
10055
|
else host.devices.select(kind, event.target.value);
|
|
8391
10056
|
},
|
|
8392
|
-
children: list.map((device) => /* @__PURE__ */
|
|
10057
|
+
children: list.map((device) => /* @__PURE__ */ jsx4("option", { value: device.deviceId, children: device.label.length > 0 ? device.label : `${label} (name hidden)` }, device.deviceId))
|
|
8393
10058
|
}
|
|
8394
10059
|
)
|
|
8395
10060
|
] });
|
|
@@ -8397,9 +10062,9 @@ function DevicePicker({
|
|
|
8397
10062
|
function MeetingRoom(props) {
|
|
8398
10063
|
const host = useMeetHost();
|
|
8399
10064
|
if (host === null) {
|
|
8400
|
-
return /* @__PURE__ */
|
|
10065
|
+
return /* @__PURE__ */ jsx4("div", { className: "mx-meet", children: /* @__PURE__ */ jsx4(InertNotice, { what: "This meeting" }) });
|
|
8401
10066
|
}
|
|
8402
|
-
return /* @__PURE__ */
|
|
10067
|
+
return /* @__PURE__ */ jsx4(MeetingRoomBody, { ...props, host });
|
|
8403
10068
|
}
|
|
8404
10069
|
function MeetingRoomBody({
|
|
8405
10070
|
roomName,
|
|
@@ -8414,25 +10079,25 @@ function MeetingRoomBody({
|
|
|
8414
10079
|
const isHost = useIsHost();
|
|
8415
10080
|
const elapsed = useElapsed(snapshot?.meeting?.startedAt ?? null);
|
|
8416
10081
|
const phase = snapshot?.phase ?? "idle";
|
|
8417
|
-
|
|
10082
|
+
useEffect4(() => {
|
|
8418
10083
|
host.meetings.watch(roomName);
|
|
8419
10084
|
}, [host, roomName]);
|
|
8420
|
-
|
|
10085
|
+
useEffect4(() => {
|
|
8421
10086
|
if (given === void 0) return;
|
|
8422
10087
|
if (host.store.snapshot().meeting !== null) return;
|
|
8423
10088
|
host.store.patch({ meeting: given, locked: given.locked });
|
|
8424
10089
|
}, [host, given]);
|
|
8425
10090
|
const watchedId = meetingId ?? snapshot?.meeting?.id ?? null;
|
|
8426
|
-
|
|
10091
|
+
useEffect4(() => {
|
|
8427
10092
|
if (watchedId === null) return;
|
|
8428
10093
|
host.meetings.watchMeeting(asMeetingId(watchedId));
|
|
8429
10094
|
}, [host, watchedId]);
|
|
8430
10095
|
const record = snapshot?.meeting ?? given ?? null;
|
|
8431
10096
|
if (hasEnded(record) && phase !== "connected" && phase !== "reconnecting") {
|
|
8432
|
-
return /* @__PURE__ */
|
|
10097
|
+
return /* @__PURE__ */ jsx4(MeetingRecordView, { meeting: record });
|
|
8433
10098
|
}
|
|
8434
10099
|
if (phase === "idle" || phase === "failed" || phase === "left") {
|
|
8435
|
-
return /* @__PURE__ */
|
|
10100
|
+
return /* @__PURE__ */ jsx4("div", { className: "mx-meet", children: /* @__PURE__ */ jsx4(
|
|
8436
10101
|
PreJoin,
|
|
8437
10102
|
{
|
|
8438
10103
|
roomName,
|
|
@@ -8442,42 +10107,42 @@ function MeetingRoomBody({
|
|
|
8442
10107
|
) });
|
|
8443
10108
|
}
|
|
8444
10109
|
if (phase === "lobby") {
|
|
8445
|
-
return /* @__PURE__ */
|
|
8446
|
-
}
|
|
8447
|
-
return /* @__PURE__ */
|
|
8448
|
-
/* @__PURE__ */
|
|
8449
|
-
/* @__PURE__ */
|
|
8450
|
-
/* @__PURE__ */
|
|
8451
|
-
/* @__PURE__ */
|
|
8452
|
-
/* @__PURE__ */
|
|
10110
|
+
return /* @__PURE__ */ jsx4("div", { className: "mx-meet mx-meet--lobby", children: /* @__PURE__ */ jsx4(WaitingRoom, { roomName, host }) });
|
|
10111
|
+
}
|
|
10112
|
+
return /* @__PURE__ */ jsxs3("div", { className: "mx-meet", children: [
|
|
10113
|
+
/* @__PURE__ */ jsx4(ConsentNotice, {}),
|
|
10114
|
+
/* @__PURE__ */ jsx4(AttendanceNotice, {}),
|
|
10115
|
+
/* @__PURE__ */ jsxs3("header", { className: "mx-meet__header", children: [
|
|
10116
|
+
/* @__PURE__ */ jsx4("h1", { className: "mx-meet__title", children: snapshot?.meeting?.title ?? "Meeting" }),
|
|
10117
|
+
/* @__PURE__ */ jsxs3("span", { className: "mx-meet__meta", children: [
|
|
8453
10118
|
participantSummary(snapshot?.participants ?? []),
|
|
8454
10119
|
elapsed > 0 ? ` \xB7 ${formatDurationMs3(elapsed)}` : ""
|
|
8455
10120
|
] }),
|
|
8456
|
-
/* @__PURE__ */
|
|
8457
|
-
snapshot?.locked === true ? /* @__PURE__ */
|
|
8458
|
-
/* @__PURE__ */
|
|
10121
|
+
/* @__PURE__ */ jsx4(RecordingIndicator, {}),
|
|
10122
|
+
snapshot?.locked === true ? /* @__PURE__ */ jsxs3("span", { className: "mx-meet__badge", children: [
|
|
10123
|
+
/* @__PURE__ */ jsx4(LockIcon, { width: 12, height: 12 }),
|
|
8459
10124
|
" Locked"
|
|
8460
10125
|
] }) : null,
|
|
8461
|
-
headerControls !== void 0 && headerControls !== null ? /* @__PURE__ */
|
|
8462
|
-
isHost ? /* @__PURE__ */
|
|
10126
|
+
headerControls !== void 0 && headerControls !== null ? /* @__PURE__ */ jsx4("span", { className: "mx-meet__header-controls", "data-meet-header-controls": "", children: headerControls }) : null,
|
|
10127
|
+
isHost ? /* @__PURE__ */ jsx4(HostMenu, {}) : null
|
|
8463
10128
|
] }),
|
|
8464
|
-
phase === "reconnecting" ? /* @__PURE__ */
|
|
8465
|
-
/* @__PURE__ */
|
|
8466
|
-
/* @__PURE__ */
|
|
8467
|
-
/* @__PURE__ */
|
|
10129
|
+
phase === "reconnecting" ? /* @__PURE__ */ jsx4("p", { className: "mx-meet__banner", role: "status", children: "Reconnecting\u2026" }) : null,
|
|
10130
|
+
/* @__PURE__ */ jsx4(Stage, {}),
|
|
10131
|
+
/* @__PURE__ */ jsx4(Captions, {}),
|
|
10132
|
+
/* @__PURE__ */ jsx4(ControlBar, { ...onLeave !== void 0 ? { onLeave } : {} })
|
|
8468
10133
|
] });
|
|
8469
10134
|
}
|
|
8470
10135
|
function WaitingRoom({ roomName, host }) {
|
|
8471
|
-
const knocked =
|
|
8472
|
-
|
|
10136
|
+
const knocked = useRef4(false);
|
|
10137
|
+
useEffect4(() => {
|
|
8473
10138
|
if (knocked.current) return;
|
|
8474
10139
|
knocked.current = true;
|
|
8475
10140
|
host.meetings.knock(roomName);
|
|
8476
10141
|
}, [host, roomName]);
|
|
8477
|
-
return /* @__PURE__ */
|
|
8478
|
-
/* @__PURE__ */
|
|
8479
|
-
/* @__PURE__ */
|
|
8480
|
-
/* @__PURE__ */
|
|
10142
|
+
return /* @__PURE__ */ jsxs3("div", { className: "mx-meet__waiting", children: [
|
|
10143
|
+
/* @__PURE__ */ jsx4(Avatar, { name: host.identity.displayName, url: host.identity.avatarUrl, size: 72 }),
|
|
10144
|
+
/* @__PURE__ */ jsx4("h1", { className: "mx-meet__prejoin-title", children: "Waiting for the host to let you in" }),
|
|
10145
|
+
/* @__PURE__ */ jsxs3("p", { className: "mx-meet__empty-body", children: [
|
|
8481
10146
|
"You are in the waiting room as ",
|
|
8482
10147
|
host.identity.displayName,
|
|
8483
10148
|
". You will join automatically once you are admitted."
|
|
@@ -8488,10 +10153,10 @@ function HostMenu() {
|
|
|
8488
10153
|
const host = useRequiredMeetHost();
|
|
8489
10154
|
const snapshot = useMeetSnapshot();
|
|
8490
10155
|
const end = useEndMeeting();
|
|
8491
|
-
const [confirmingEnd, setConfirmingEnd] =
|
|
10156
|
+
const [confirmingEnd, setConfirmingEnd] = useState4(false);
|
|
8492
10157
|
const locked = snapshot?.locked === true;
|
|
8493
|
-
return /* @__PURE__ */
|
|
8494
|
-
/* @__PURE__ */
|
|
10158
|
+
return /* @__PURE__ */ jsxs3("div", { className: "mx-meet__host-menu", children: [
|
|
10159
|
+
/* @__PURE__ */ jsx4(
|
|
8495
10160
|
"button",
|
|
8496
10161
|
{
|
|
8497
10162
|
type: "button",
|
|
@@ -8502,9 +10167,9 @@ function HostMenu() {
|
|
|
8502
10167
|
children: locked ? "Unlock meeting" : "Lock meeting"
|
|
8503
10168
|
}
|
|
8504
10169
|
),
|
|
8505
|
-
end.canEnd ? confirmingEnd ? /* @__PURE__ */
|
|
8506
|
-
/* @__PURE__ */
|
|
8507
|
-
/* @__PURE__ */
|
|
10170
|
+
end.canEnd ? confirmingEnd ? /* @__PURE__ */ jsxs3("span", { className: "mx-meet__confirm", role: "group", "aria-label": "End this meeting?", children: [
|
|
10171
|
+
/* @__PURE__ */ jsx4("span", { className: "mx-meet__confirm-text", children: "End it for everyone? Every participant is disconnected, the note-taker stops, and the wrap-up is written. Nobody can rejoin this meeting afterwards." }),
|
|
10172
|
+
/* @__PURE__ */ jsx4(
|
|
8508
10173
|
"button",
|
|
8509
10174
|
{
|
|
8510
10175
|
type: "button",
|
|
@@ -8516,7 +10181,7 @@ function HostMenu() {
|
|
|
8516
10181
|
children: "End it"
|
|
8517
10182
|
}
|
|
8518
10183
|
),
|
|
8519
|
-
/* @__PURE__ */
|
|
10184
|
+
/* @__PURE__ */ jsx4(
|
|
8520
10185
|
"button",
|
|
8521
10186
|
{
|
|
8522
10187
|
type: "button",
|
|
@@ -8525,7 +10190,7 @@ function HostMenu() {
|
|
|
8525
10190
|
children: "Keep it running"
|
|
8526
10191
|
}
|
|
8527
10192
|
)
|
|
8528
|
-
] }) : /* @__PURE__ */
|
|
10193
|
+
] }) : /* @__PURE__ */ jsx4(
|
|
8529
10194
|
"button",
|
|
8530
10195
|
{
|
|
8531
10196
|
type: "button",
|
|
@@ -8534,7 +10199,7 @@ function HostMenu() {
|
|
|
8534
10199
|
children: end.ending ? "Ending\u2026" : "End meeting for everyone"
|
|
8535
10200
|
}
|
|
8536
10201
|
) : null,
|
|
8537
|
-
end.notice !== null ? /* @__PURE__ */
|
|
10202
|
+
end.notice !== null ? /* @__PURE__ */ jsx4("span", { className: "mx-meet__notice", role: "status", children: end.notice }) : null
|
|
8538
10203
|
] });
|
|
8539
10204
|
}
|
|
8540
10205
|
function CallButton({
|
|
@@ -8544,7 +10209,7 @@ function CallButton({
|
|
|
8544
10209
|
}) {
|
|
8545
10210
|
const calls = useCalls();
|
|
8546
10211
|
if (!calls.canCall) return null;
|
|
8547
|
-
return /* @__PURE__ */
|
|
10212
|
+
return /* @__PURE__ */ jsx4(
|
|
8548
10213
|
"button",
|
|
8549
10214
|
{
|
|
8550
10215
|
type: "button",
|
|
@@ -8553,55 +10218,55 @@ function CallButton({
|
|
|
8553
10218
|
void calls.call([person.userId], mode);
|
|
8554
10219
|
},
|
|
8555
10220
|
"aria-label": `Call ${person.displayName}`,
|
|
8556
|
-
children: children ?? /* @__PURE__ */
|
|
10221
|
+
children: children ?? /* @__PURE__ */ jsx4(PhoneIcon, { width: 18, height: 18 })
|
|
8557
10222
|
}
|
|
8558
10223
|
);
|
|
8559
10224
|
}
|
|
8560
10225
|
function IncomingCallHost() {
|
|
8561
10226
|
const calls = useCalls();
|
|
8562
10227
|
if (calls.incoming.length === 0) return null;
|
|
8563
|
-
return /* @__PURE__ */
|
|
10228
|
+
return /* @__PURE__ */ jsx4("div", { className: "mx-meet__ringing-stack", children: calls.incoming.map((invite) => /* @__PURE__ */ jsx4(IncomingCallCard, { invite }, invite.id)) });
|
|
8564
10229
|
}
|
|
8565
10230
|
function IncomingCallCard({ invite }) {
|
|
8566
10231
|
const calls = useCalls();
|
|
8567
|
-
return /* @__PURE__ */
|
|
8568
|
-
/* @__PURE__ */
|
|
8569
|
-
/* @__PURE__ */
|
|
8570
|
-
/* @__PURE__ */
|
|
8571
|
-
/* @__PURE__ */
|
|
10232
|
+
return /* @__PURE__ */ jsxs3("section", { className: "mx-meet__ringing", role: "alertdialog", "aria-label": "Incoming call", children: [
|
|
10233
|
+
/* @__PURE__ */ jsx4(Avatar, { name: invite.callerName, url: invite.callerAvatarUrl, size: 56 }),
|
|
10234
|
+
/* @__PURE__ */ jsxs3("div", { className: "mx-meet__ringing-text", children: [
|
|
10235
|
+
/* @__PURE__ */ jsx4("strong", { children: invite.callerName }),
|
|
10236
|
+
/* @__PURE__ */ jsx4("span", { children: invite.mode === "video" ? "Incoming video call" : "Incoming call" })
|
|
8572
10237
|
] }),
|
|
8573
|
-
/* @__PURE__ */
|
|
8574
|
-
/* @__PURE__ */
|
|
8575
|
-
invite.mode === "video" ? /* @__PURE__ */
|
|
10238
|
+
/* @__PURE__ */ jsxs3("div", { className: "mx-meet__ringing-actions", children: [
|
|
10239
|
+
/* @__PURE__ */ jsx4(ControlButton, { label: "Decline", danger: true, onClick: () => void calls.decline(invite), children: /* @__PURE__ */ jsx4(PhoneOffIcon, {}) }),
|
|
10240
|
+
invite.mode === "video" ? /* @__PURE__ */ jsx4(
|
|
8576
10241
|
ControlButton,
|
|
8577
10242
|
{
|
|
8578
10243
|
label: "Accept without video",
|
|
8579
10244
|
onClick: () => void calls.accept({ ...invite, mode: "audio" }),
|
|
8580
|
-
children: /* @__PURE__ */
|
|
10245
|
+
children: /* @__PURE__ */ jsx4(CameraOffIcon, {})
|
|
8581
10246
|
}
|
|
8582
10247
|
) : null,
|
|
8583
|
-
/* @__PURE__ */
|
|
10248
|
+
/* @__PURE__ */ jsx4(ControlButton, { label: "Accept", onClick: () => void calls.accept(invite), children: /* @__PURE__ */ jsx4(PhoneIcon, {}) })
|
|
8584
10249
|
] })
|
|
8585
10250
|
] });
|
|
8586
10251
|
}
|
|
8587
10252
|
function ScheduleMeeting(props) {
|
|
8588
10253
|
const host = useMeetHost();
|
|
8589
|
-
if (host === null) return /* @__PURE__ */
|
|
8590
|
-
return /* @__PURE__ */
|
|
10254
|
+
if (host === null) return /* @__PURE__ */ jsx4(InertNotice, { what: "Scheduling a meeting" });
|
|
10255
|
+
return /* @__PURE__ */ jsx4(ScheduleMeetingBody, { ...props, host });
|
|
8591
10256
|
}
|
|
8592
10257
|
function ScheduleMeetingBody({
|
|
8593
10258
|
appBaseUrl,
|
|
8594
10259
|
onScheduled,
|
|
8595
10260
|
host
|
|
8596
10261
|
}) {
|
|
8597
|
-
const [title, setTitle] =
|
|
8598
|
-
const [when2, setWhen] =
|
|
8599
|
-
const [kind, setKind] =
|
|
8600
|
-
const [busy, setBusy] =
|
|
8601
|
-
const [link, setLink] =
|
|
8602
|
-
const [error, setError] =
|
|
10262
|
+
const [title, setTitle] = useState4("");
|
|
10263
|
+
const [when2, setWhen] = useState4("");
|
|
10264
|
+
const [kind, setKind] = useState4("scheduled");
|
|
10265
|
+
const [busy, setBusy] = useState4(false);
|
|
10266
|
+
const [link, setLink] = useState4(null);
|
|
10267
|
+
const [error, setError] = useState4(null);
|
|
8603
10268
|
const disabled = useMemo3(() => title.trim().length === 0 || busy, [title, busy]);
|
|
8604
|
-
return /* @__PURE__ */
|
|
10269
|
+
return /* @__PURE__ */ jsxs3(
|
|
8605
10270
|
"form",
|
|
8606
10271
|
{
|
|
8607
10272
|
className: "mx-meet__schedule",
|
|
@@ -8626,9 +10291,9 @@ function ScheduleMeetingBody({
|
|
|
8626
10291
|
}).finally(() => setBusy(false));
|
|
8627
10292
|
},
|
|
8628
10293
|
children: [
|
|
8629
|
-
/* @__PURE__ */
|
|
8630
|
-
/* @__PURE__ */
|
|
8631
|
-
/* @__PURE__ */
|
|
10294
|
+
/* @__PURE__ */ jsxs3("label", { className: "mx-meet__field", children: [
|
|
10295
|
+
/* @__PURE__ */ jsx4("span", { className: "mx-meet__field-label", children: "Title" }),
|
|
10296
|
+
/* @__PURE__ */ jsx4(
|
|
8632
10297
|
"input",
|
|
8633
10298
|
{
|
|
8634
10299
|
className: "mx-meet__input",
|
|
@@ -8638,9 +10303,9 @@ function ScheduleMeetingBody({
|
|
|
8638
10303
|
}
|
|
8639
10304
|
)
|
|
8640
10305
|
] }),
|
|
8641
|
-
/* @__PURE__ */
|
|
8642
|
-
/* @__PURE__ */
|
|
8643
|
-
/* @__PURE__ */
|
|
10306
|
+
/* @__PURE__ */ jsxs3("label", { className: "mx-meet__field", children: [
|
|
10307
|
+
/* @__PURE__ */ jsx4("span", { className: "mx-meet__field-label", children: "When" }),
|
|
10308
|
+
/* @__PURE__ */ jsx4(
|
|
8644
10309
|
"input",
|
|
8645
10310
|
{
|
|
8646
10311
|
className: "mx-meet__input",
|
|
@@ -8650,27 +10315,27 @@ function ScheduleMeetingBody({
|
|
|
8650
10315
|
}
|
|
8651
10316
|
)
|
|
8652
10317
|
] }),
|
|
8653
|
-
/* @__PURE__ */
|
|
8654
|
-
/* @__PURE__ */
|
|
8655
|
-
/* @__PURE__ */
|
|
10318
|
+
/* @__PURE__ */ jsxs3("label", { className: "mx-meet__field", children: [
|
|
10319
|
+
/* @__PURE__ */ jsx4("span", { className: "mx-meet__field-label", children: "Repeats" }),
|
|
10320
|
+
/* @__PURE__ */ jsxs3(
|
|
8656
10321
|
"select",
|
|
8657
10322
|
{
|
|
8658
10323
|
className: "mx-meet__select",
|
|
8659
10324
|
value: kind,
|
|
8660
10325
|
onChange: (event) => setKind(event.target.value),
|
|
8661
10326
|
children: [
|
|
8662
|
-
/* @__PURE__ */
|
|
8663
|
-
/* @__PURE__ */
|
|
10327
|
+
/* @__PURE__ */ jsx4("option", { value: "scheduled", children: "Once" }),
|
|
10328
|
+
/* @__PURE__ */ jsx4("option", { value: "recurring", children: "Recurring \u2014 one link, every time" })
|
|
8664
10329
|
]
|
|
8665
10330
|
}
|
|
8666
10331
|
)
|
|
8667
10332
|
] }),
|
|
8668
|
-
/* @__PURE__ */
|
|
8669
|
-
link !== null ? /* @__PURE__ */
|
|
8670
|
-
/* @__PURE__ */
|
|
8671
|
-
/* @__PURE__ */
|
|
10333
|
+
/* @__PURE__ */ jsx4("button", { type: "submit", className: "mx-meet__primary", disabled, children: busy ? "Creating\u2026" : "Create meeting" }),
|
|
10334
|
+
link !== null ? /* @__PURE__ */ jsxs3("p", { className: "mx-meet__link-out", children: [
|
|
10335
|
+
/* @__PURE__ */ jsx4("span", { children: "Anyone with this link can join \u2014 no account needed." }),
|
|
10336
|
+
/* @__PURE__ */ jsx4("code", { children: link })
|
|
8672
10337
|
] }) : null,
|
|
8673
|
-
error !== null ? /* @__PURE__ */
|
|
10338
|
+
error !== null ? /* @__PURE__ */ jsx4("p", { className: "mx-meet__error", children: error }) : null
|
|
8674
10339
|
]
|
|
8675
10340
|
}
|
|
8676
10341
|
);
|
|
@@ -8679,7 +10344,7 @@ function ReactionOverlay({
|
|
|
8679
10344
|
reactions
|
|
8680
10345
|
}) {
|
|
8681
10346
|
if (reactions.length === 0) return null;
|
|
8682
|
-
return /* @__PURE__ */
|
|
10347
|
+
return /* @__PURE__ */ jsx4("div", { className: "mx-meet__reactions", "aria-hidden": "true", children: reactions.map((reaction) => /* @__PURE__ */ jsx4("span", { className: "mx-meet__reaction", children: reaction.emoji }, reaction.id)) });
|
|
8683
10348
|
}
|
|
8684
10349
|
function GuestRecordAccessControl({
|
|
8685
10350
|
meeting
|
|
@@ -8691,11 +10356,11 @@ function GuestRecordAccessControl({
|
|
|
8691
10356
|
const isHost = inRoomHost || viewerId !== null && meeting.hostUserId === viewerId;
|
|
8692
10357
|
if (host === null || !isHost) return null;
|
|
8693
10358
|
const resolved = access.setting === "default" && access.effective !== null ? ` Right now that means: ${guestRecordAccessLabel(access.effective.level).toLowerCase()}.` : "";
|
|
8694
|
-
return /* @__PURE__ */
|
|
8695
|
-
/* @__PURE__ */
|
|
8696
|
-
/* @__PURE__ */
|
|
8697
|
-
/* @__PURE__ */
|
|
8698
|
-
/* @__PURE__ */
|
|
10359
|
+
return /* @__PURE__ */ jsxs3("section", { className: "mx-meet__record-section", "aria-label": "What guests may read", children: [
|
|
10360
|
+
/* @__PURE__ */ jsx4("h2", { className: "mx-meet__record-section-title", children: "What guests may read" }),
|
|
10361
|
+
/* @__PURE__ */ jsxs3("label", { className: "mx-meet__field", children: [
|
|
10362
|
+
/* @__PURE__ */ jsx4("span", { className: "mx-meet__field-label", children: "People who attended by link, without an account" }),
|
|
10363
|
+
/* @__PURE__ */ jsx4(
|
|
8699
10364
|
"select",
|
|
8700
10365
|
{
|
|
8701
10366
|
className: "mx-meet__select",
|
|
@@ -8706,18 +10371,18 @@ function GuestRecordAccessControl({
|
|
|
8706
10371
|
event.target.value
|
|
8707
10372
|
);
|
|
8708
10373
|
},
|
|
8709
|
-
children: GUEST_RECORD_ACCESS_CHOICES.map((choice) => /* @__PURE__ */
|
|
10374
|
+
children: GUEST_RECORD_ACCESS_CHOICES.map((choice) => /* @__PURE__ */ jsx4("option", { value: choice, children: guestRecordAccessLabel(choice) }, choice))
|
|
8710
10375
|
}
|
|
8711
10376
|
)
|
|
8712
10377
|
] }),
|
|
8713
|
-
/* @__PURE__ */
|
|
10378
|
+
/* @__PURE__ */ jsxs3("p", { className: "mx-meet__panel-note", children: [
|
|
8714
10379
|
guestRecordAccessExplanation(access.setting),
|
|
8715
10380
|
resolved
|
|
8716
10381
|
] }),
|
|
8717
|
-
access.saving ? /* @__PURE__ */
|
|
8718
|
-
access.error !== null ? /* @__PURE__ */
|
|
8719
|
-
/* @__PURE__ */
|
|
8720
|
-
/* @__PURE__ */
|
|
10382
|
+
access.saving ? /* @__PURE__ */ jsx4("p", { className: "mx-meet__panel-note", role: "status", children: "Saving what guests may read\u2026" }) : null,
|
|
10383
|
+
access.error !== null ? /* @__PURE__ */ jsxs3(ErrorBox, { as: "div", className: "mx-meet__refusal", error: access.error, operation: "Change who can join", origin: "meet/components", children: [
|
|
10384
|
+
/* @__PURE__ */ jsx4("p", { className: "mx-meet__refusal-reason", children: access.error.message }),
|
|
10385
|
+
/* @__PURE__ */ jsx4("p", { className: "mx-meet__refusal-remedy", children: access.error.remedy })
|
|
8721
10386
|
] }) : null
|
|
8722
10387
|
] });
|
|
8723
10388
|
}
|
|
@@ -8727,9 +10392,9 @@ function MeetingRecordView({
|
|
|
8727
10392
|
}) {
|
|
8728
10393
|
const host = useMeetHost();
|
|
8729
10394
|
if (host === null) {
|
|
8730
|
-
return /* @__PURE__ */
|
|
10395
|
+
return /* @__PURE__ */ jsx4("div", { className: "mx-meet mx-meet--record", children: /* @__PURE__ */ jsx4(InertNotice, { what: "This meeting record" }) });
|
|
8731
10396
|
}
|
|
8732
|
-
return /* @__PURE__ */
|
|
10397
|
+
return /* @__PURE__ */ jsx4(MeetingRecordBody, { meeting, ...onRejoin !== void 0 ? { onRejoin } : {} });
|
|
8733
10398
|
}
|
|
8734
10399
|
function MeetingRecordBody({
|
|
8735
10400
|
meeting,
|
|
@@ -8737,19 +10402,19 @@ function MeetingRecordBody({
|
|
|
8737
10402
|
}) {
|
|
8738
10403
|
const host = useRequiredMeetHost();
|
|
8739
10404
|
const record = useMeetingRecord(meeting);
|
|
8740
|
-
const [question, setQuestion] =
|
|
8741
|
-
const [tab, setTab] =
|
|
10405
|
+
const [question, setQuestion] = useState4("");
|
|
10406
|
+
const [tab, setTab] = useState4("summary");
|
|
8742
10407
|
if (record.failure !== null) {
|
|
8743
|
-
return /* @__PURE__ */
|
|
8744
|
-
/* @__PURE__ */
|
|
8745
|
-
/* @__PURE__ */
|
|
8746
|
-
/* @__PURE__ */
|
|
10408
|
+
return /* @__PURE__ */ jsx4("div", { className: "mx-meet mx-meet--record", children: /* @__PURE__ */ jsxs3(ErrorBox, { as: "div", className: "mx-meet__empty", error: record.failure, operation: "Open this meeting record", origin: "meet/components", children: [
|
|
10409
|
+
/* @__PURE__ */ jsx4("p", { className: "mx-meet__empty-title", children: "This meeting record could not be opened" }),
|
|
10410
|
+
/* @__PURE__ */ jsx4("p", { className: "mx-meet__empty-body", children: record.failure.message }),
|
|
10411
|
+
/* @__PURE__ */ jsx4("p", { className: "mx-meet__empty-body", children: record.failure.remedy })
|
|
8747
10412
|
] }) });
|
|
8748
10413
|
}
|
|
8749
10414
|
if (record.loading || record.record === null) {
|
|
8750
|
-
return /* @__PURE__ */
|
|
8751
|
-
/* @__PURE__ */
|
|
8752
|
-
/* @__PURE__ */
|
|
10415
|
+
return /* @__PURE__ */ jsx4("div", { className: "mx-meet mx-meet--record", children: /* @__PURE__ */ jsxs3("div", { className: "mx-meet__empty", role: "status", children: [
|
|
10416
|
+
/* @__PURE__ */ jsx4("p", { className: "mx-meet__empty-title", children: "Opening the meeting record\u2026" }),
|
|
10417
|
+
/* @__PURE__ */ jsx4("p", { className: "mx-meet__empty-body", children: "Reading the summary, the notes and the transcript this meeting left behind." })
|
|
8753
10418
|
] }) });
|
|
8754
10419
|
}
|
|
8755
10420
|
const bundle = record.record;
|
|
@@ -8768,44 +10433,44 @@ function MeetingRecordBody({
|
|
|
8768
10433
|
);
|
|
8769
10434
|
const entirelyRestricted = everyRecordPartRefused && bundle.attendees.length === 0 && bundle.liveNotes.length === 0 && bundle.transcript.length === 0 && bundle.recording === null && bundle.summary === null && bundle.decisions.length === 0 && bundle.actionItems.length === 0;
|
|
8770
10435
|
if (entirelyRestricted) {
|
|
8771
|
-
return /* @__PURE__ */
|
|
8772
|
-
/* @__PURE__ */
|
|
8773
|
-
/* @__PURE__ */
|
|
8774
|
-
/* @__PURE__ */
|
|
8775
|
-
/* @__PURE__ */
|
|
8776
|
-
onRejoin !== void 0 ? /* @__PURE__ */
|
|
10436
|
+
return /* @__PURE__ */ jsxs3("div", { className: "mx-meet mx-meet--record", children: [
|
|
10437
|
+
/* @__PURE__ */ jsx4("header", { className: "mx-meet__record-head", children: /* @__PURE__ */ jsxs3("div", { className: "mx-meet__record-head-inner", children: [
|
|
10438
|
+
/* @__PURE__ */ jsx4("p", { className: "mx-meet__record-eyebrow", children: "Meeting record" }),
|
|
10439
|
+
/* @__PURE__ */ jsx4("h1", { className: "mx-meet__record-title", children: meeting.title }),
|
|
10440
|
+
/* @__PURE__ */ jsx4("p", { className: "mx-meet__record-when", children: meetingWhen(meeting) }),
|
|
10441
|
+
onRejoin !== void 0 ? /* @__PURE__ */ jsx4("button", { type: "button", className: "mx-meet__link", onClick: onRejoin, children: "Open this link again" }) : null
|
|
8777
10442
|
] }) }),
|
|
8778
|
-
/* @__PURE__ */
|
|
8779
|
-
/* @__PURE__ */
|
|
8780
|
-
/* @__PURE__ */
|
|
8781
|
-
/* @__PURE__ */
|
|
10443
|
+
/* @__PURE__ */ jsx4("div", { className: "mx-meet__record-body", children: restrictionNotices.map((notice2) => /* @__PURE__ */ jsxs3("div", { className: "mx-meet__record-access", role: "status", children: [
|
|
10444
|
+
/* @__PURE__ */ jsx4("p", { className: "mx-meet__record-access-title", children: "About this record" }),
|
|
10445
|
+
/* @__PURE__ */ jsx4("p", { className: "mx-meet__record-access-message", children: notice2.message }),
|
|
10446
|
+
/* @__PURE__ */ jsx4("p", { className: "mx-meet__record-access-remedy", children: notice2.remedy })
|
|
8782
10447
|
] }, notice2.parts.join("-"))) })
|
|
8783
10448
|
] });
|
|
8784
10449
|
}
|
|
8785
|
-
return /* @__PURE__ */
|
|
8786
|
-
/* @__PURE__ */
|
|
8787
|
-
/* @__PURE__ */
|
|
8788
|
-
/* @__PURE__ */
|
|
8789
|
-
/* @__PURE__ */
|
|
8790
|
-
onRejoin !== void 0 ? /* @__PURE__ */
|
|
10450
|
+
return /* @__PURE__ */ jsxs3("div", { className: "mx-meet mx-meet--record", children: [
|
|
10451
|
+
/* @__PURE__ */ jsx4("header", { className: "mx-meet__record-head", children: /* @__PURE__ */ jsxs3("div", { className: "mx-meet__record-head-inner", children: [
|
|
10452
|
+
/* @__PURE__ */ jsx4("p", { className: "mx-meet__record-eyebrow", children: "Meeting record" }),
|
|
10453
|
+
/* @__PURE__ */ jsx4("h1", { className: "mx-meet__record-title", children: meeting.title }),
|
|
10454
|
+
/* @__PURE__ */ jsx4("p", { className: "mx-meet__record-when", children: meetingWhen(meeting) }),
|
|
10455
|
+
onRejoin !== void 0 ? /* @__PURE__ */ jsx4("button", { type: "button", className: "mx-meet__link", onClick: onRejoin, children: "Open this link again" }) : null
|
|
8791
10456
|
] }) }),
|
|
8792
|
-
/* @__PURE__ */
|
|
8793
|
-
restrictionNotices.map((notice2) => /* @__PURE__ */
|
|
8794
|
-
/* @__PURE__ */
|
|
8795
|
-
/* @__PURE__ */
|
|
8796
|
-
/* @__PURE__ */
|
|
10457
|
+
/* @__PURE__ */ jsxs3("div", { className: "mx-meet__record-body", children: [
|
|
10458
|
+
restrictionNotices.map((notice2) => /* @__PURE__ */ jsxs3("div", { className: "mx-meet__record-access", role: "status", children: [
|
|
10459
|
+
/* @__PURE__ */ jsx4("p", { className: "mx-meet__record-access-title", children: "About this record" }),
|
|
10460
|
+
/* @__PURE__ */ jsx4("p", { className: "mx-meet__record-access-message", children: notice2.message }),
|
|
10461
|
+
/* @__PURE__ */ jsx4("p", { className: "mx-meet__record-access-remedy", children: notice2.remedy })
|
|
8797
10462
|
] }, notice2.parts.join("-"))),
|
|
8798
10463
|
attended.length === 0 ? (
|
|
8799
10464
|
/* NOT SILENCE. A refused attendance read used to remove the whole
|
|
8800
10465
|
section, so the reader could not tell "nobody" from "not shown". */
|
|
8801
|
-
/* @__PURE__ */
|
|
8802
|
-
/* @__PURE__ */
|
|
8803
|
-
/* @__PURE__ */
|
|
10466
|
+
/* @__PURE__ */ jsxs3("section", { className: "mx-meet__record-section", "aria-label": "Who attended", children: [
|
|
10467
|
+
/* @__PURE__ */ jsx4("h2", { className: "mx-meet__record-section-title", children: "Who attended" }),
|
|
10468
|
+
/* @__PURE__ */ jsx4("p", { className: "mx-meet__panel-note", children: absenceSentence(bundle, "attendance", "Nobody is recorded as having attended.") })
|
|
8804
10469
|
] })
|
|
8805
|
-
) : /* @__PURE__ */
|
|
8806
|
-
/* @__PURE__ */
|
|
8807
|
-
/* @__PURE__ */
|
|
8808
|
-
/* @__PURE__ */
|
|
10470
|
+
) : /* @__PURE__ */ jsxs3("section", { className: "mx-meet__record-section", "aria-label": "Who attended", children: [
|
|
10471
|
+
/* @__PURE__ */ jsx4("h2", { className: "mx-meet__record-section-title", children: "Who attended" }),
|
|
10472
|
+
/* @__PURE__ */ jsx4("ul", { className: "mx-meet__record-attendees", children: attended.map((person) => /* @__PURE__ */ jsxs3("li", { className: "mx-meet__record-attendee", children: [
|
|
10473
|
+
/* @__PURE__ */ jsx4(
|
|
8809
10474
|
Avatar,
|
|
8810
10475
|
{
|
|
8811
10476
|
name: displayNameFor(bundle.names, person.identity, person.displayName),
|
|
@@ -8813,26 +10478,26 @@ function MeetingRecordBody({
|
|
|
8813
10478
|
size: 28
|
|
8814
10479
|
}
|
|
8815
10480
|
),
|
|
8816
|
-
/* @__PURE__ */
|
|
10481
|
+
/* @__PURE__ */ jsxs3("span", { className: "mx-meet__person-name", children: [
|
|
8817
10482
|
displayNameFor(bundle.names, person.identity, person.displayName),
|
|
8818
|
-
person.role === "host" ? /* @__PURE__ */
|
|
8819
|
-
person.role === "guest" ? /* @__PURE__ */
|
|
8820
|
-
person.isAgent ? /* @__PURE__ */
|
|
10483
|
+
person.role === "host" ? /* @__PURE__ */ jsx4("span", { className: "mx-meet__badge", children: "Host" }) : null,
|
|
10484
|
+
person.role === "guest" ? /* @__PURE__ */ jsx4("span", { className: "mx-meet__badge", children: "Guest" }) : null,
|
|
10485
|
+
person.isAgent ? /* @__PURE__ */ jsx4("span", { className: "mx-meet__badge", children: "Meeting assistant" }) : null
|
|
8821
10486
|
] })
|
|
8822
10487
|
] }, person.id)) })
|
|
8823
10488
|
] }),
|
|
8824
|
-
bundle.recording !== null ? /* @__PURE__ */
|
|
8825
|
-
/* @__PURE__ */
|
|
8826
|
-
fileId !== null ? /* @__PURE__ */
|
|
8827
|
-
/* @__PURE__ */
|
|
8828
|
-
notice !== null ? /* @__PURE__ */
|
|
8829
|
-
] }) : /* @__PURE__ */
|
|
8830
|
-
] }) : wasRefused(bundle, "recording") ? /* @__PURE__ */
|
|
8831
|
-
/* @__PURE__ */
|
|
8832
|
-
/* @__PURE__ */
|
|
10489
|
+
bundle.recording !== null ? /* @__PURE__ */ jsxs3("section", { className: "mx-meet__record-section mx-meet__recording-card", "aria-label": "Recording", children: [
|
|
10490
|
+
/* @__PURE__ */ jsx4("h2", { className: "mx-meet__record-section-title", children: "Recording" }),
|
|
10491
|
+
fileId !== null ? /* @__PURE__ */ jsxs3(Fragment, { children: [
|
|
10492
|
+
/* @__PURE__ */ jsx4(RecordingPlayer, { fileId }),
|
|
10493
|
+
notice !== null ? /* @__PURE__ */ jsx4("p", { className: "mx-meet__panel-note", children: notice }) : null
|
|
10494
|
+
] }) : /* @__PURE__ */ jsx4("p", { className: "mx-meet__panel-note", children: notice ?? "This recording has no file." })
|
|
10495
|
+
] }) : wasRefused(bundle, "recording") ? /* @__PURE__ */ jsxs3("section", { className: "mx-meet__record-section", "aria-label": "Recording", children: [
|
|
10496
|
+
/* @__PURE__ */ jsx4("h2", { className: "mx-meet__record-section-title", children: "Recording" }),
|
|
10497
|
+
/* @__PURE__ */ jsx4("p", { className: "mx-meet__panel-note", children: REFUSED_ABSENCE })
|
|
8833
10498
|
] }) : null,
|
|
8834
|
-
/* @__PURE__ */
|
|
8835
|
-
/* @__PURE__ */
|
|
10499
|
+
/* @__PURE__ */ jsxs3("nav", { className: "mx-meet__record-tabs", "aria-label": "Meeting record sections", children: [
|
|
10500
|
+
/* @__PURE__ */ jsx4(
|
|
8836
10501
|
"button",
|
|
8837
10502
|
{
|
|
8838
10503
|
type: "button",
|
|
@@ -8842,7 +10507,7 @@ function MeetingRecordBody({
|
|
|
8842
10507
|
children: "Summary & decisions"
|
|
8843
10508
|
}
|
|
8844
10509
|
),
|
|
8845
|
-
/* @__PURE__ */
|
|
10510
|
+
/* @__PURE__ */ jsx4(
|
|
8846
10511
|
"button",
|
|
8847
10512
|
{
|
|
8848
10513
|
type: "button",
|
|
@@ -8852,7 +10517,7 @@ function MeetingRecordBody({
|
|
|
8852
10517
|
children: "Notes as it happened"
|
|
8853
10518
|
}
|
|
8854
10519
|
),
|
|
8855
|
-
/* @__PURE__ */
|
|
10520
|
+
/* @__PURE__ */ jsx4(
|
|
8856
10521
|
"button",
|
|
8857
10522
|
{
|
|
8858
10523
|
type: "button",
|
|
@@ -8863,15 +10528,15 @@ function MeetingRecordBody({
|
|
|
8863
10528
|
}
|
|
8864
10529
|
)
|
|
8865
10530
|
] }),
|
|
8866
|
-
tab === "summary" ? /* @__PURE__ */
|
|
8867
|
-
/* @__PURE__ */
|
|
8868
|
-
/* @__PURE__ */
|
|
8869
|
-
wrapUp.state === "written" ? /* @__PURE__ */
|
|
8870
|
-
/* @__PURE__ */
|
|
8871
|
-
/* @__PURE__ */
|
|
8872
|
-
] }) : /* @__PURE__ */
|
|
10531
|
+
tab === "summary" ? /* @__PURE__ */ jsxs3(Fragment, { children: [
|
|
10532
|
+
/* @__PURE__ */ jsxs3("section", { className: "mx-meet__record-section", "aria-label": "Summary", children: [
|
|
10533
|
+
/* @__PURE__ */ jsx4("h2", { className: "mx-meet__record-section-title", children: "Summary" }),
|
|
10534
|
+
wrapUp.state === "written" ? /* @__PURE__ */ jsx4("p", { className: "mx-meet__record-summary", children: bundle.summary?.text }) : wrapUp.state === "in-progress" ? /* @__PURE__ */ jsxs3("div", { className: "mx-meet__panel-note", role: "status", children: [
|
|
10535
|
+
/* @__PURE__ */ jsx4("p", { children: wrapUp.message }),
|
|
10536
|
+
/* @__PURE__ */ jsx4("button", { type: "button", className: "mx-meet__link", onClick: record.reload, children: "Check again" })
|
|
10537
|
+
] }) : /* @__PURE__ */ jsx4("p", { className: "mx-meet__panel-note", role: wrapUp.state === "failed" ? "alert" : void 0, children: wrapUp.message })
|
|
8873
10538
|
] }),
|
|
8874
|
-
/* @__PURE__ */
|
|
10539
|
+
/* @__PURE__ */ jsx4(
|
|
8875
10540
|
NoteList,
|
|
8876
10541
|
{
|
|
8877
10542
|
title: "Decisions",
|
|
@@ -8883,7 +10548,7 @@ function MeetingRecordBody({
|
|
|
8883
10548
|
)
|
|
8884
10549
|
}
|
|
8885
10550
|
),
|
|
8886
|
-
/* @__PURE__ */
|
|
10551
|
+
/* @__PURE__ */ jsx4(
|
|
8887
10552
|
NoteList,
|
|
8888
10553
|
{
|
|
8889
10554
|
title: "Action items",
|
|
@@ -8896,42 +10561,42 @@ function MeetingRecordBody({
|
|
|
8896
10561
|
}
|
|
8897
10562
|
)
|
|
8898
10563
|
] }) : null,
|
|
8899
|
-
tab === "notes" ? /* @__PURE__ */
|
|
8900
|
-
/* @__PURE__ */
|
|
8901
|
-
bundle.liveNotes.length === 0 ? /* @__PURE__ */
|
|
10564
|
+
tab === "notes" ? /* @__PURE__ */ jsxs3("section", { className: "mx-meet__record-section", "aria-label": "Notes as it happened", children: [
|
|
10565
|
+
/* @__PURE__ */ jsx4("h2", { className: "mx-meet__record-section-title", children: "Notes as it happened" }),
|
|
10566
|
+
bundle.liveNotes.length === 0 ? /* @__PURE__ */ jsx4("p", { className: "mx-meet__panel-note", children: absenceSentence(
|
|
8902
10567
|
bundle,
|
|
8903
10568
|
"notes",
|
|
8904
10569
|
"No live notes are available for this meeting."
|
|
8905
|
-
) }) : /* @__PURE__ */
|
|
8906
|
-
note.window !== null ? /* @__PURE__ */
|
|
10570
|
+
) }) : /* @__PURE__ */ jsx4("ul", { className: "mx-meet__notes", children: bundle.liveNotes.map((note) => /* @__PURE__ */ jsxs3("li", { className: "mx-meet__note", children: [
|
|
10571
|
+
note.window !== null ? /* @__PURE__ */ jsxs3("span", { className: "mx-meet__badge", children: [
|
|
8907
10572
|
"Window ",
|
|
8908
10573
|
note.window
|
|
8909
10574
|
] }) : null,
|
|
8910
10575
|
note.text
|
|
8911
10576
|
] }, note.id)) })
|
|
8912
10577
|
] }) : null,
|
|
8913
|
-
tab === "transcript" ? /* @__PURE__ */
|
|
8914
|
-
/* @__PURE__ */
|
|
10578
|
+
tab === "transcript" ? /* @__PURE__ */ jsxs3("section", { className: "mx-meet__record-section", "aria-label": "Transcript", children: [
|
|
10579
|
+
/* @__PURE__ */ jsxs3("h2", { className: "mx-meet__record-section-title", children: [
|
|
8915
10580
|
"Transcript",
|
|
8916
|
-
/* @__PURE__ */
|
|
10581
|
+
/* @__PURE__ */ jsx4("span", { className: "mx-meet__record-count", children: bundle.transcript.length === 1 ? "1 line" : `${bundle.transcript.length} lines` })
|
|
8917
10582
|
] }),
|
|
8918
|
-
blocks.length === 0 ? /* @__PURE__ */
|
|
10583
|
+
blocks.length === 0 ? /* @__PURE__ */ jsx4("p", { className: "mx-meet__panel-note", children: absenceSentence(
|
|
8919
10584
|
bundle,
|
|
8920
10585
|
"transcript",
|
|
8921
10586
|
"No transcript is available for this meeting."
|
|
8922
|
-
) }) : /* @__PURE__ */
|
|
8923
|
-
/* @__PURE__ */
|
|
10587
|
+
) }) : /* @__PURE__ */ jsx4("ol", { className: "mx-meet__record-transcript", children: blocks.map((block) => /* @__PURE__ */ jsxs3("li", { className: "mx-meet__record-block", children: [
|
|
10588
|
+
/* @__PURE__ */ jsxs3("p", { className: "mx-meet__record-speaker", children: [
|
|
8924
10589
|
block.speaker,
|
|
8925
|
-
/* @__PURE__ */
|
|
10590
|
+
/* @__PURE__ */ jsx4("time", { className: "mx-meet__record-time", dateTime: block.startedAt, children: clockOf(block.startedAt) })
|
|
8926
10591
|
] }),
|
|
8927
|
-
block.lines.map((line) => /* @__PURE__ */
|
|
10592
|
+
block.lines.map((line) => /* @__PURE__ */ jsx4("p", { className: "mx-meet__record-line", children: line.text }, line.id))
|
|
8928
10593
|
] }, block.id)) })
|
|
8929
10594
|
] }) : null,
|
|
8930
|
-
/* @__PURE__ */
|
|
8931
|
-
/* @__PURE__ */
|
|
8932
|
-
/* @__PURE__ */
|
|
8933
|
-
guestFinishedMeeting ? /* @__PURE__ */
|
|
8934
|
-
/* @__PURE__ */
|
|
10595
|
+
/* @__PURE__ */ jsx4(GuestRecordAccessControl, { meeting }),
|
|
10596
|
+
/* @__PURE__ */ jsxs3("section", { className: "mx-meet__record-section", "aria-label": "Ask about this meeting", children: [
|
|
10597
|
+
/* @__PURE__ */ jsx4("h2", { className: "mx-meet__record-section-title", children: "Ask about this meeting" }),
|
|
10598
|
+
guestFinishedMeeting ? /* @__PURE__ */ jsx4("p", { className: "mx-meet__panel-note", children: "Sign in to ask the assistant about a meeting after it ends." }) : /* @__PURE__ */ jsxs3(Fragment, { children: [
|
|
10599
|
+
/* @__PURE__ */ jsxs3(
|
|
8935
10600
|
"form",
|
|
8936
10601
|
{
|
|
8937
10602
|
className: "mx-meet__composer",
|
|
@@ -8942,7 +10607,7 @@ function MeetingRecordBody({
|
|
|
8942
10607
|
void record.ask(trimmed);
|
|
8943
10608
|
},
|
|
8944
10609
|
children: [
|
|
8945
|
-
/* @__PURE__ */
|
|
10610
|
+
/* @__PURE__ */ jsx4(
|
|
8946
10611
|
"input",
|
|
8947
10612
|
{
|
|
8948
10613
|
className: "mx-meet__input",
|
|
@@ -8952,7 +10617,7 @@ function MeetingRecordBody({
|
|
|
8952
10617
|
"aria-label": "Ask about this meeting"
|
|
8953
10618
|
}
|
|
8954
10619
|
),
|
|
8955
|
-
/* @__PURE__ */
|
|
10620
|
+
/* @__PURE__ */ jsx4(
|
|
8956
10621
|
"button",
|
|
8957
10622
|
{
|
|
8958
10623
|
type: "submit",
|
|
@@ -8964,8 +10629,8 @@ function MeetingRecordBody({
|
|
|
8964
10629
|
]
|
|
8965
10630
|
}
|
|
8966
10631
|
),
|
|
8967
|
-
record.answer !== null ? /* @__PURE__ */
|
|
8968
|
-
record.coverage !== null ? /* @__PURE__ */
|
|
10632
|
+
record.answer !== null ? /* @__PURE__ */ jsx4("p", { className: "mx-meet__answer", children: record.answer }) : null,
|
|
10633
|
+
record.coverage !== null ? /* @__PURE__ */ jsxs3("p", { className: "mx-meet__coverage", children: [
|
|
8969
10634
|
"Answered from ",
|
|
8970
10635
|
record.coverage.segmentsUsed,
|
|
8971
10636
|
" of ",
|
|
@@ -8976,9 +10641,9 @@ function MeetingRecordBody({
|
|
|
8976
10641
|
record.coverage.truncated ? " (the oldest were left out)" : "",
|
|
8977
10642
|
"."
|
|
8978
10643
|
] }) : null,
|
|
8979
|
-
record.askError !== null ? /* @__PURE__ */
|
|
8980
|
-
/* @__PURE__ */
|
|
8981
|
-
/* @__PURE__ */
|
|
10644
|
+
record.askError !== null ? /* @__PURE__ */ jsxs3(ErrorBox, { as: "div", className: "mx-meet__refusal", error: record.askError, operation: "Ask about this meeting", origin: "meet/components", children: [
|
|
10645
|
+
/* @__PURE__ */ jsx4("p", { className: "mx-meet__refusal-reason", children: record.askError.message }),
|
|
10646
|
+
/* @__PURE__ */ jsx4("p", { className: "mx-meet__refusal-remedy", children: record.askError.remedy })
|
|
8982
10647
|
] }) : null
|
|
8983
10648
|
] })
|
|
8984
10649
|
] })
|
|
@@ -8989,21 +10654,21 @@ var STREAM_REFUSED = "Streaming playback did not start, so this recording was do
|
|
|
8989
10654
|
var PLAYBACK_RETRY_REMEDY = "Reload the page and try again. If it still will not play, ask a meeting host to check the recording.";
|
|
8990
10655
|
function RecordingPlayer(props) {
|
|
8991
10656
|
const host = useMeetHost();
|
|
8992
|
-
if (host === null) return /* @__PURE__ */
|
|
8993
|
-
return /* @__PURE__ */
|
|
10657
|
+
if (host === null) return /* @__PURE__ */ jsx4(InertNotice, { what: "This recording" });
|
|
10658
|
+
return /* @__PURE__ */ jsx4(RecordingPlayerBody, { ...props, host });
|
|
8994
10659
|
}
|
|
8995
10660
|
function RecordingPlayerBody({ fileId, host }) {
|
|
8996
|
-
const [media, setMedia] =
|
|
8997
|
-
const [loading, setLoading] =
|
|
8998
|
-
const [error, setError] =
|
|
8999
|
-
|
|
10661
|
+
const [media, setMedia] = useState4(null);
|
|
10662
|
+
const [loading, setLoading] = useState4(false);
|
|
10663
|
+
const [error, setError] = useState4(null);
|
|
10664
|
+
useEffect4(() => {
|
|
9000
10665
|
if (media === null || media.kind !== "bytes") return void 0;
|
|
9001
10666
|
const url = media.url;
|
|
9002
10667
|
return () => URL.revokeObjectURL(url);
|
|
9003
10668
|
}, [media]);
|
|
9004
10669
|
if (media !== null) {
|
|
9005
|
-
return /* @__PURE__ */
|
|
9006
|
-
/* @__PURE__ */
|
|
10670
|
+
return /* @__PURE__ */ jsxs3("div", { className: "mx-meet__record-section", children: [
|
|
10671
|
+
/* @__PURE__ */ jsx4(
|
|
9007
10672
|
"video",
|
|
9008
10673
|
{
|
|
9009
10674
|
className: "mx-meet__record-player",
|
|
@@ -9045,15 +10710,15 @@ function RecordingPlayerBody({ fileId, host }) {
|
|
|
9045
10710
|
}
|
|
9046
10711
|
}
|
|
9047
10712
|
),
|
|
9048
|
-
media.fallbackReason !== null ? /* @__PURE__ */
|
|
10713
|
+
media.fallbackReason !== null ? /* @__PURE__ */ jsx4("p", { className: "mx-meet__panel-note", children: media.fallbackReason }) : null
|
|
9049
10714
|
] });
|
|
9050
10715
|
}
|
|
9051
|
-
return /* @__PURE__ */
|
|
9052
|
-
error !== null ? /* @__PURE__ */
|
|
9053
|
-
/* @__PURE__ */
|
|
9054
|
-
/* @__PURE__ */
|
|
10716
|
+
return /* @__PURE__ */ jsxs3("div", { className: "mx-meet__record-section", children: [
|
|
10717
|
+
error !== null ? /* @__PURE__ */ jsxs3(ErrorBox, { as: "div", className: "mx-meet__refusal", error, operation: "Complete this meeting action", origin: "meet/components", children: [
|
|
10718
|
+
/* @__PURE__ */ jsx4("p", { className: "mx-meet__refusal-reason", children: error.message }),
|
|
10719
|
+
/* @__PURE__ */ jsx4("p", { className: "mx-meet__refusal-remedy", children: error.remedy })
|
|
9055
10720
|
] }) : null,
|
|
9056
|
-
/* @__PURE__ */
|
|
10721
|
+
/* @__PURE__ */ jsx4(
|
|
9057
10722
|
"button",
|
|
9058
10723
|
{
|
|
9059
10724
|
type: "button",
|
|
@@ -9089,35 +10754,35 @@ function clockOf(iso) {
|
|
|
9089
10754
|
function MeetingList({ baseUrl }) {
|
|
9090
10755
|
const host = useMeetHost();
|
|
9091
10756
|
const list = useMeetings();
|
|
9092
|
-
if (host === null) return /* @__PURE__ */
|
|
10757
|
+
if (host === null) return /* @__PURE__ */ jsx4(InertNotice, { what: "Your meetings" });
|
|
9093
10758
|
if (list.failure !== null) {
|
|
9094
|
-
return /* @__PURE__ */
|
|
9095
|
-
/* @__PURE__ */
|
|
9096
|
-
/* @__PURE__ */
|
|
9097
|
-
/* @__PURE__ */
|
|
10759
|
+
return /* @__PURE__ */ jsxs3(ErrorBox, { as: "div", className: "mx-meet__empty", error: list.failure, operation: "List your meetings", origin: "meet/components", children: [
|
|
10760
|
+
/* @__PURE__ */ jsx4("p", { className: "mx-meet__empty-title", children: "Your meetings could not be listed" }),
|
|
10761
|
+
/* @__PURE__ */ jsx4("p", { className: "mx-meet__empty-body", children: list.failure.message }),
|
|
10762
|
+
/* @__PURE__ */ jsx4("p", { className: "mx-meet__empty-body", children: list.failure.remedy })
|
|
9098
10763
|
] });
|
|
9099
10764
|
}
|
|
9100
10765
|
if (list.loading) {
|
|
9101
|
-
return /* @__PURE__ */
|
|
10766
|
+
return /* @__PURE__ */ jsx4("div", { className: "mx-meet__empty", role: "status", children: /* @__PURE__ */ jsx4("p", { className: "mx-meet__empty-title", children: "Loading your meetings\u2026" }) });
|
|
9102
10767
|
}
|
|
9103
10768
|
if (list.meetings.length === 0) {
|
|
9104
|
-
return /* @__PURE__ */
|
|
9105
|
-
/* @__PURE__ */
|
|
9106
|
-
/* @__PURE__ */
|
|
10769
|
+
return /* @__PURE__ */ jsxs3("div", { className: "mx-meet__empty", role: "status", children: [
|
|
10770
|
+
/* @__PURE__ */ jsx4("p", { className: "mx-meet__empty-title", children: "No meetings yet" }),
|
|
10771
|
+
/* @__PURE__ */ jsx4("p", { className: "mx-meet__empty-body", children: "Create one above. Its link works before, during and after the meeting \u2014 afterwards it opens the record." })
|
|
9107
10772
|
] });
|
|
9108
10773
|
}
|
|
9109
10774
|
const origin = baseUrl ?? (typeof window === "undefined" ? "" : window.location.origin);
|
|
9110
|
-
return /* @__PURE__ */
|
|
10775
|
+
return /* @__PURE__ */ jsx4("ul", { className: "mx-meet-list", children: list.meetings.map((meeting) => {
|
|
9111
10776
|
const ended = meeting.endedAt !== null;
|
|
9112
|
-
return /* @__PURE__ */
|
|
9113
|
-
/* @__PURE__ */
|
|
9114
|
-
/* @__PURE__ */
|
|
10777
|
+
return /* @__PURE__ */ jsxs3("li", { className: "mx-meet-list__row", children: [
|
|
10778
|
+
/* @__PURE__ */ jsxs3("div", { className: "mx-meet-list__main", children: [
|
|
10779
|
+
/* @__PURE__ */ jsxs3("span", { className: "mx-meet-list__title", children: [
|
|
9115
10780
|
meeting.title,
|
|
9116
|
-
ended ? /* @__PURE__ */
|
|
10781
|
+
ended ? /* @__PURE__ */ jsx4("span", { className: "mx-meet__badge", children: "Ended" }) : null
|
|
9117
10782
|
] }),
|
|
9118
|
-
/* @__PURE__ */
|
|
10783
|
+
/* @__PURE__ */ jsx4("span", { className: "mx-meet-list__when", children: meetingWhen(meeting) })
|
|
9119
10784
|
] }),
|
|
9120
|
-
/* @__PURE__ */
|
|
10785
|
+
/* @__PURE__ */ jsx4("a", { className: "mx-meet-list__action", href: meetingLink(origin, meeting.slug), children: ended ? "Open the record" : "Join" })
|
|
9121
10786
|
] }, meeting.id);
|
|
9122
10787
|
}) });
|
|
9123
10788
|
}
|
|
@@ -9274,15 +10939,22 @@ async function pushMeetingToGoogleCalendar(api, meetingId, target) {
|
|
|
9274
10939
|
}
|
|
9275
10940
|
export {
|
|
9276
10941
|
ATTENDANCE_CSV_HEADER,
|
|
10942
|
+
ActivitiesControl,
|
|
10943
|
+
ActivitiesIcon,
|
|
9277
10944
|
AiPanel,
|
|
9278
10945
|
AttendanceNotice,
|
|
9279
10946
|
Avatar,
|
|
10947
|
+
BreakoutBanner,
|
|
10948
|
+
BreakoutIcon,
|
|
10949
|
+
BreakoutsPanel,
|
|
9280
10950
|
CALL_INVITE_KIND,
|
|
9281
10951
|
CALL_INVITE_VERSION,
|
|
10952
|
+
CAPTION_LANGUAGES,
|
|
9282
10953
|
CONSENT_NOTICE_ATTRIBUTE,
|
|
9283
10954
|
CallButton,
|
|
9284
10955
|
CameraIcon,
|
|
9285
10956
|
CameraOffIcon,
|
|
10957
|
+
CaptionLanguageSettings,
|
|
9286
10958
|
Captions,
|
|
9287
10959
|
ChatIcon,
|
|
9288
10960
|
ChatPanel,
|
|
@@ -9295,6 +10967,7 @@ export {
|
|
|
9295
10967
|
DATA_TOPICS,
|
|
9296
10968
|
DEFAULT_EFFECTS,
|
|
9297
10969
|
DEFAULT_PAGE_SIZE,
|
|
10970
|
+
EMPTY_COLLAB,
|
|
9298
10971
|
END_MEETING_NOT_SERVED,
|
|
9299
10972
|
FILE_SESSION_PATH,
|
|
9300
10973
|
FlagIcon,
|
|
@@ -9347,8 +11020,12 @@ export {
|
|
|
9347
11020
|
PhoneIcon,
|
|
9348
11021
|
PhoneOffIcon,
|
|
9349
11022
|
PinIcon,
|
|
11023
|
+
PollIcon,
|
|
11024
|
+
PollsPanel,
|
|
9350
11025
|
PreJoin,
|
|
11026
|
+
QaPanel,
|
|
9351
11027
|
QualityBars,
|
|
11028
|
+
QuestionIcon,
|
|
9352
11029
|
REACTION_TTL_MS,
|
|
9353
11030
|
REFUSED_ABSENCE,
|
|
9354
11031
|
ROLE_RANK,
|
|
@@ -9375,10 +11052,13 @@ export {
|
|
|
9375
11052
|
TABLES,
|
|
9376
11053
|
TRANSCRIPTION_ATTRIBUTES,
|
|
9377
11054
|
TRANSCRIPTION_TOPIC,
|
|
11055
|
+
WhiteboardIcon,
|
|
11056
|
+
WhiteboardPanel,
|
|
9378
11057
|
WifiLowIcon,
|
|
9379
11058
|
absenceSentence,
|
|
9380
11059
|
activeWrapUpSummary,
|
|
9381
11060
|
announceMeeting,
|
|
11061
|
+
applyCollabPacket,
|
|
9382
11062
|
applyRoomEvent,
|
|
9383
11063
|
asCallId,
|
|
9384
11064
|
asMeetingId,
|
|
@@ -9386,10 +11066,13 @@ export {
|
|
|
9386
11066
|
asParticipantIdentity,
|
|
9387
11067
|
asRoomName,
|
|
9388
11068
|
asUserId,
|
|
11069
|
+
assignedRoom,
|
|
9389
11070
|
attendanceCsv,
|
|
9390
11071
|
attendanceReport,
|
|
9391
11072
|
attendanceTotals,
|
|
9392
11073
|
attendeeKey,
|
|
11074
|
+
autoAssign,
|
|
11075
|
+
breakoutRemainingMs,
|
|
9393
11076
|
callInviteAction,
|
|
9394
11077
|
callInviteText,
|
|
9395
11078
|
callStateLabel,
|
|
@@ -9399,6 +11082,7 @@ export {
|
|
|
9399
11082
|
captionSegment,
|
|
9400
11083
|
changesPatch,
|
|
9401
11084
|
clockPosition,
|
|
11085
|
+
collabFromState,
|
|
9402
11086
|
computeStage,
|
|
9403
11087
|
countLabel,
|
|
9404
11088
|
createCallCenter,
|
|
@@ -9419,6 +11103,7 @@ export {
|
|
|
9419
11103
|
createWebDeviceStorage,
|
|
9420
11104
|
createWebEffectsStorage,
|
|
9421
11105
|
createWebRoomTokenStorage,
|
|
11106
|
+
defaultCaptionLanguage,
|
|
9422
11107
|
displayNameFor,
|
|
9423
11108
|
fileDownloadPath,
|
|
9424
11109
|
gridColumns,
|
|
@@ -9441,6 +11126,7 @@ export {
|
|
|
9441
11126
|
listenOnlyNotice,
|
|
9442
11127
|
loadFollowUpDraft,
|
|
9443
11128
|
loadGuestMeetingRecord,
|
|
11129
|
+
loadMeetingActivities,
|
|
9444
11130
|
loadMeetingChat,
|
|
9445
11131
|
loadMeetingRecord,
|
|
9446
11132
|
mapConnectionState,
|
|
@@ -9495,9 +11181,13 @@ export {
|
|
|
9495
11181
|
unavailableFrom,
|
|
9496
11182
|
uniqueAttendees,
|
|
9497
11183
|
useAudioLevel,
|
|
11184
|
+
useAvailableActivities,
|
|
9498
11185
|
useCalls,
|
|
9499
11186
|
useCanModerate,
|
|
9500
11187
|
useCanRecord,
|
|
11188
|
+
useCaptionTranslation,
|
|
11189
|
+
useCollab,
|
|
11190
|
+
useCollabPanelRequest,
|
|
9501
11191
|
useConsentNotice,
|
|
9502
11192
|
useDeviceSnapshot,
|
|
9503
11193
|
useElapsed,
|
|
@@ -9529,6 +11219,7 @@ export {
|
|
|
9529
11219
|
useTrack,
|
|
9530
11220
|
userTopic,
|
|
9531
11221
|
wasRefused,
|
|
11222
|
+
withItem,
|
|
9532
11223
|
wrapUpStatus
|
|
9533
11224
|
};
|
|
9534
11225
|
//# sourceMappingURL=react.js.map
|