@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/dist/react.cjs CHANGED
@@ -33,15 +33,22 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
33
33
  var react_exports = {};
34
34
  __export(react_exports, {
35
35
  ATTENDANCE_CSV_HEADER: () => ATTENDANCE_CSV_HEADER,
36
+ ActivitiesControl: () => ActivitiesControl,
37
+ ActivitiesIcon: () => ActivitiesIcon,
36
38
  AiPanel: () => AiPanel,
37
39
  AttendanceNotice: () => AttendanceNotice,
38
40
  Avatar: () => Avatar,
41
+ BreakoutBanner: () => BreakoutBanner,
42
+ BreakoutIcon: () => BreakoutIcon,
43
+ BreakoutsPanel: () => BreakoutsPanel,
39
44
  CALL_INVITE_KIND: () => CALL_INVITE_KIND,
40
45
  CALL_INVITE_VERSION: () => CALL_INVITE_VERSION,
46
+ CAPTION_LANGUAGES: () => CAPTION_LANGUAGES,
41
47
  CONSENT_NOTICE_ATTRIBUTE: () => CONSENT_NOTICE_ATTRIBUTE,
42
48
  CallButton: () => CallButton,
43
49
  CameraIcon: () => CameraIcon,
44
50
  CameraOffIcon: () => CameraOffIcon,
51
+ CaptionLanguageSettings: () => CaptionLanguageSettings,
45
52
  Captions: () => Captions,
46
53
  ChatIcon: () => ChatIcon,
47
54
  ChatPanel: () => ChatPanel,
@@ -54,6 +61,7 @@ __export(react_exports, {
54
61
  DATA_TOPICS: () => DATA_TOPICS,
55
62
  DEFAULT_EFFECTS: () => DEFAULT_EFFECTS,
56
63
  DEFAULT_PAGE_SIZE: () => DEFAULT_PAGE_SIZE,
64
+ EMPTY_COLLAB: () => EMPTY_COLLAB,
57
65
  END_MEETING_NOT_SERVED: () => END_MEETING_NOT_SERVED,
58
66
  FILE_SESSION_PATH: () => FILE_SESSION_PATH,
59
67
  FlagIcon: () => FlagIcon,
@@ -106,8 +114,12 @@ __export(react_exports, {
106
114
  PhoneIcon: () => PhoneIcon,
107
115
  PhoneOffIcon: () => PhoneOffIcon,
108
116
  PinIcon: () => PinIcon,
117
+ PollIcon: () => PollIcon,
118
+ PollsPanel: () => PollsPanel,
109
119
  PreJoin: () => PreJoin,
120
+ QaPanel: () => QaPanel,
110
121
  QualityBars: () => QualityBars,
122
+ QuestionIcon: () => QuestionIcon,
111
123
  REACTION_TTL_MS: () => REACTION_TTL_MS,
112
124
  REFUSED_ABSENCE: () => REFUSED_ABSENCE,
113
125
  ROLE_RANK: () => ROLE_RANK,
@@ -134,10 +146,13 @@ __export(react_exports, {
134
146
  TABLES: () => TABLES,
135
147
  TRANSCRIPTION_ATTRIBUTES: () => TRANSCRIPTION_ATTRIBUTES,
136
148
  TRANSCRIPTION_TOPIC: () => TRANSCRIPTION_TOPIC,
149
+ WhiteboardIcon: () => WhiteboardIcon,
150
+ WhiteboardPanel: () => WhiteboardPanel,
137
151
  WifiLowIcon: () => WifiLowIcon,
138
152
  absenceSentence: () => absenceSentence,
139
153
  activeWrapUpSummary: () => activeWrapUpSummary,
140
154
  announceMeeting: () => announceMeeting,
155
+ applyCollabPacket: () => applyCollabPacket,
141
156
  applyRoomEvent: () => applyRoomEvent,
142
157
  asCallId: () => asCallId,
143
158
  asMeetingId: () => asMeetingId,
@@ -145,10 +160,13 @@ __export(react_exports, {
145
160
  asParticipantIdentity: () => asParticipantIdentity,
146
161
  asRoomName: () => asRoomName,
147
162
  asUserId: () => asUserId,
163
+ assignedRoom: () => assignedRoom,
148
164
  attendanceCsv: () => attendanceCsv,
149
165
  attendanceReport: () => attendanceReport,
150
166
  attendanceTotals: () => attendanceTotals,
151
167
  attendeeKey: () => attendeeKey,
168
+ autoAssign: () => autoAssign,
169
+ breakoutRemainingMs: () => breakoutRemainingMs,
152
170
  callInviteAction: () => callInviteAction,
153
171
  callInviteText: () => callInviteText,
154
172
  callStateLabel: () => callStateLabel,
@@ -158,6 +176,7 @@ __export(react_exports, {
158
176
  captionSegment: () => captionSegment,
159
177
  changesPatch: () => changesPatch,
160
178
  clockPosition: () => clockPosition,
179
+ collabFromState: () => collabFromState,
161
180
  computeStage: () => computeStage,
162
181
  countLabel: () => countLabel,
163
182
  createCallCenter: () => createCallCenter,
@@ -178,6 +197,7 @@ __export(react_exports, {
178
197
  createWebDeviceStorage: () => createWebDeviceStorage,
179
198
  createWebEffectsStorage: () => createWebEffectsStorage,
180
199
  createWebRoomTokenStorage: () => createWebRoomTokenStorage,
200
+ defaultCaptionLanguage: () => defaultCaptionLanguage,
181
201
  displayNameFor: () => displayNameFor,
182
202
  fileDownloadPath: () => fileDownloadPath,
183
203
  gridColumns: () => gridColumns,
@@ -200,6 +220,7 @@ __export(react_exports, {
200
220
  listenOnlyNotice: () => listenOnlyNotice,
201
221
  loadFollowUpDraft: () => loadFollowUpDraft,
202
222
  loadGuestMeetingRecord: () => loadGuestMeetingRecord,
223
+ loadMeetingActivities: () => loadMeetingActivities,
203
224
  loadMeetingChat: () => loadMeetingChat,
204
225
  loadMeetingRecord: () => loadMeetingRecord,
205
226
  mapConnectionState: () => mapConnectionState,
@@ -254,9 +275,13 @@ __export(react_exports, {
254
275
  unavailableFrom: () => unavailableFrom,
255
276
  uniqueAttendees: () => uniqueAttendees,
256
277
  useAudioLevel: () => useAudioLevel,
278
+ useAvailableActivities: () => useAvailableActivities,
257
279
  useCalls: () => useCalls,
258
280
  useCanModerate: () => useCanModerate,
259
281
  useCanRecord: () => useCanRecord,
282
+ useCaptionTranslation: () => useCaptionTranslation,
283
+ useCollab: () => useCollab,
284
+ useCollabPanelRequest: () => useCollabPanelRequest,
260
285
  useConsentNotice: () => useConsentNotice,
261
286
  useDeviceSnapshot: () => useDeviceSnapshot,
262
287
  useElapsed: () => useElapsed,
@@ -288,6 +313,7 @@ __export(react_exports, {
288
313
  useTrack: () => useTrack,
289
314
  userTopic: () => userTopic,
290
315
  wasRefused: () => wasRefused,
316
+ withItem: () => withItem,
291
317
  wrapUpStatus: () => wrapUpStatus
292
318
  });
293
319
  module.exports = __toCommonJS(react_exports);
@@ -519,7 +545,14 @@ var MEET_ROUTES = {
519
545
  */
520
546
  moderate: "/api/v1/meet/moderate",
521
547
  /** Meet wave 2: the SAVED chat — `POST` sends to everyone, `GET ?meeting_id=` reads history. */
522
- chat: "/api/v1/meet/chat"
548
+ chat: "/api/v1/meet/chat",
549
+ /**
550
+ * Meet wave 5: polls, Q&A, the shared whiteboard and breakout rooms. `POST` acts
551
+ * (`{meeting_id, action, …}`), `GET ?meeting_id=` reads what this viewer may see.
552
+ */
553
+ collab: "/api/v1/meet/collab",
554
+ /** Meet wave 5: translate finished caption lines into this viewer's language. */
555
+ captionsTranslate: "/api/v1/meet/captions/translate"
523
556
  };
524
557
  function meetingPath(template, meetingId) {
525
558
  return template.replace("{meeting_id}", encodeURIComponent(meetingId));
@@ -578,7 +611,8 @@ function parseRoomToken(body, roomName) {
578
611
  // server that has not landed MRI-A11 — and never invents a host from
579
612
  // silence, because both fallbacks below grant nothing.
580
613
  role: readRole(payload, "role") ?? (isHost ? "host" : identity.startsWith("guest:") ? "guest" : "participant"),
581
- lobby: readBoolean(payload, "lobby", false)
614
+ lobby: readBoolean(payload, "lobby", false),
615
+ breakoutRoomId: readString(payload, "breakout_room_id") ?? null
582
616
  };
583
617
  }
584
618
  function createTokenClient(options) {
@@ -626,6 +660,7 @@ function createTokenClient(options) {
626
660
  room_name: input.roomName,
627
661
  ...input.meetingId !== void 0 ? { meeting_id: input.meetingId } : {},
628
662
  ...input.slug !== void 0 ? { slug: input.slug } : {},
663
+ ...input.breakoutRoomId != null ? { breakout_room_id: input.breakoutRoomId } : {},
629
664
  organization_id: input.identity.organizationId,
630
665
  display_name: input.identity.displayName,
631
666
  device_id: input.identity.deviceId,
@@ -689,7 +724,8 @@ function createTokenClient(options) {
689
724
  return {
690
725
  get(input) {
691
726
  const entry = cache.get(input.roomName);
692
- if (entry !== void 0) {
727
+ const sameRoom = entry !== void 0 && (entry.token.breakoutRoomId ?? null) === (input.breakoutRoomId ?? null);
728
+ if (entry !== void 0 && sameRoom) {
693
729
  if (entry.inFlight !== null) return entry.inFlight;
694
730
  if (!expired(entry)) return Promise.resolve(entry.token);
695
731
  }
@@ -735,7 +771,8 @@ function placeholder(roomName) {
735
771
  canRecord: false,
736
772
  isHost: false,
737
773
  role: "participant",
738
- lobby: false
774
+ lobby: false,
775
+ breakoutRoomId: null
739
776
  };
740
777
  }
741
778
  async function serverSentence(response) {
@@ -1793,6 +1830,339 @@ function listenOnlyNotice(media) {
1793
1830
  return isListenOnly(media) ? LISTEN_ONLY_NOTICE : null;
1794
1831
  }
1795
1832
 
1833
+ // src/core/collab.ts
1834
+ var EMPTY_COLLAB = {
1835
+ loaded: false,
1836
+ error: null,
1837
+ settings: null,
1838
+ polls: [],
1839
+ questions: [],
1840
+ strokes: [],
1841
+ breakout: null,
1842
+ broadcast: null,
1843
+ moveRequest: null,
1844
+ panelRequest: null,
1845
+ captionLanguage: null,
1846
+ captionTranslations: {},
1847
+ captionTranslationError: null
1848
+ };
1849
+ function obj(value) {
1850
+ return typeof value === "object" && value !== null && !Array.isArray(value) ? value : null;
1851
+ }
1852
+ function str(value) {
1853
+ return typeof value === "string" ? value : null;
1854
+ }
1855
+ function num(value) {
1856
+ return typeof value === "number" && Number.isFinite(value) ? value : null;
1857
+ }
1858
+ function strings(value) {
1859
+ return Array.isArray(value) ? value.filter((v) => typeof v === "string") : [];
1860
+ }
1861
+ function pollFromRow(row) {
1862
+ const id = str(row["id"]);
1863
+ if (id === null) return null;
1864
+ const options = [];
1865
+ for (const raw of Array.isArray(row["options"]) ? row["options"] : []) {
1866
+ const option = obj(raw);
1867
+ const optionId = option === null ? null : str(option["id"]);
1868
+ if (option === null || optionId === null) continue;
1869
+ const votes = num(option["votes"]);
1870
+ options.push({
1871
+ id: optionId,
1872
+ text: str(option["text"]) ?? "",
1873
+ ...votes !== null ? { votes } : {},
1874
+ ...Array.isArray(option["voters"]) ? { voters: strings(option["voters"]) } : {}
1875
+ });
1876
+ }
1877
+ const state = str(row["state"]);
1878
+ return {
1879
+ id,
1880
+ question: str(row["question"]) ?? "",
1881
+ options,
1882
+ multiple: row["multiple"] === true,
1883
+ anonymous: row["anonymous"] === true,
1884
+ state: state === "live" || state === "closed" ? state : "draft",
1885
+ resultsShared: row["results_shared"] === true,
1886
+ voterCount: num(row["voter_count"]),
1887
+ myVote: strings(row["my_vote"]),
1888
+ createdByName: str(row["created_by_name"]) ?? "",
1889
+ createdAt: str(row["created_at"])
1890
+ };
1891
+ }
1892
+ function questionFromRow(row) {
1893
+ const id = str(row["id"]);
1894
+ if (id === null) return null;
1895
+ const state = str(row["state"]);
1896
+ return {
1897
+ id,
1898
+ text: str(row["text"]) ?? "",
1899
+ askerName: str(row["asker_name"]) ?? "",
1900
+ anonymous: row["anonymous"] === true,
1901
+ state: state === "answered" || state === "dismissed" ? state : "open",
1902
+ answer: str(row["answer"]),
1903
+ answeredByName: str(row["answered_by_name"]),
1904
+ upvotes: num(row["upvotes"]) ?? 0,
1905
+ upvotedByMe: row["upvoted_by_me"] === true,
1906
+ mine: row["mine"] === true,
1907
+ createdAt: str(row["created_at"])
1908
+ };
1909
+ }
1910
+ function strokeFromRow(row) {
1911
+ const id = str(row["id"]);
1912
+ if (id === null || !Array.isArray(row["points"])) return null;
1913
+ const points = [];
1914
+ for (const raw of row["points"]) {
1915
+ if (Array.isArray(raw) && typeof raw[0] === "number" && typeof raw[1] === "number") {
1916
+ points.push([raw[0], raw[1]]);
1917
+ }
1918
+ }
1919
+ return {
1920
+ id,
1921
+ points,
1922
+ color: str(row["color"]) ?? "#111827",
1923
+ width: num(row["width"]) ?? 3,
1924
+ tool: row["tool"] === "highlighter" ? "highlighter" : "pen",
1925
+ by: str(row["by"]) ?? "",
1926
+ byName: str(row["by_name"]) ?? ""
1927
+ };
1928
+ }
1929
+ function broadcastFrom(value) {
1930
+ const row = obj(value);
1931
+ const text3 = row === null ? null : str(row["text"]);
1932
+ if (row === null || text3 === null) return null;
1933
+ return { text: text3, by: str(row["by"]) ?? "", at: str(row["at"]) ?? "" };
1934
+ }
1935
+ function planFromRow(row) {
1936
+ const id = str(row["id"]);
1937
+ if (id === null) return null;
1938
+ const rooms = [];
1939
+ for (const raw of Array.isArray(row["rooms"]) ? row["rooms"] : []) {
1940
+ const room = obj(raw);
1941
+ const roomId = room === null ? null : str(room["id"]);
1942
+ if (room === null || roomId === null) continue;
1943
+ rooms.push({ id: roomId, name: str(room["name"]) ?? roomId, identities: strings(room["identities"]) });
1944
+ }
1945
+ return {
1946
+ id,
1947
+ state: row["state"] === "open" ? "open" : "closed",
1948
+ rooms,
1949
+ allowChoose: row["allow_choose"] === true,
1950
+ minutes: num(row["minutes"]) ?? 0,
1951
+ openedAt: str(row["opened_at"]),
1952
+ endsAt: str(row["ends_at"]),
1953
+ closedAt: str(row["closed_at"]),
1954
+ broadcasts: (Array.isArray(row["broadcasts"]) ? row["broadcasts"] : []).map(broadcastFrom).filter((b) => b !== null)
1955
+ };
1956
+ }
1957
+ function settingsFromRow(row) {
1958
+ if (row === null) return null;
1959
+ return {
1960
+ pollsEnabled: row["polls_enabled"] === true,
1961
+ pollMaxOptions: num(row["poll_max_options"]) ?? 10,
1962
+ qaEnabled: row["qa_enabled"] === true,
1963
+ qaAnonymousAllowed: row["qa_anonymous_allowed"] === true,
1964
+ whiteboardEnabled: row["whiteboard_enabled"] === true,
1965
+ breakoutsEnabled: row["breakouts_enabled"] === true,
1966
+ breakoutMaxRooms: num(row["breakout_max_rooms"]) ?? 20,
1967
+ breakoutDefaultMinutes: num(row["breakout_default_minutes"]) ?? 15,
1968
+ captionTranslationEnabled: row["caption_translation_enabled"] === true,
1969
+ captionTranslationLanguage: str(row["caption_translation_language"]) ?? ""
1970
+ };
1971
+ }
1972
+ function collabFromState(body, previous) {
1973
+ const list = (key, parse) => (Array.isArray(body[key]) ? body[key] : []).map((raw) => {
1974
+ const row = obj(raw);
1975
+ return row === null ? null : parse(row);
1976
+ }).filter((item) => item !== null);
1977
+ const breakoutRow = obj(body["breakout"]);
1978
+ return {
1979
+ ...previous,
1980
+ loaded: true,
1981
+ error: null,
1982
+ settings: settingsFromRow(obj(body["settings"])),
1983
+ polls: list("polls", pollFromRow),
1984
+ questions: list("questions", questionFromRow),
1985
+ strokes: list("strokes", strokeFromRow),
1986
+ breakout: breakoutRow === null ? null : planFromRow(breakoutRow)
1987
+ };
1988
+ }
1989
+ function upsert(items, next) {
1990
+ const index = items.findIndex((item) => item.id === next.id);
1991
+ if (index === -1) return [...items, next];
1992
+ const copy = items.slice();
1993
+ copy[index] = next;
1994
+ return copy;
1995
+ }
1996
+ function withItem(collab, row, fromRoom = false) {
1997
+ const kind = str(row["kind"]);
1998
+ if (kind === "poll") {
1999
+ const poll = pollFromRow(row);
2000
+ if (poll === null) return collab;
2001
+ const known = collab.polls.find((p) => p.id === poll.id);
2002
+ const merged = fromRoom && known !== void 0 ? { ...poll, myVote: known.myVote } : poll;
2003
+ return { ...collab, polls: upsert(collab.polls, merged) };
2004
+ }
2005
+ if (kind === "question") {
2006
+ const question = questionFromRow(row);
2007
+ if (question === null) return collab;
2008
+ const known = collab.questions.find((q) => q.id === question.id);
2009
+ const merged = fromRoom && known !== void 0 ? { ...question, mine: known.mine, upvotedByMe: known.upvotedByMe } : question;
2010
+ return { ...collab, questions: upsert(collab.questions, merged) };
2011
+ }
2012
+ if (kind === "stroke") {
2013
+ const stroke = strokeFromRow(row);
2014
+ if (stroke === null) return collab;
2015
+ return { ...collab, strokes: upsert(collab.strokes, stroke) };
2016
+ }
2017
+ if (kind === "breakout") {
2018
+ const plan = planFromRow(row);
2019
+ if (plan === null) return collab;
2020
+ return { ...collab, breakout: plan };
2021
+ }
2022
+ return collab;
2023
+ }
2024
+ function without(collab, ids) {
2025
+ const gone = new Set(ids);
2026
+ return {
2027
+ ...collab,
2028
+ polls: collab.polls.filter((p) => !gone.has(p.id)),
2029
+ questions: collab.questions.filter((q) => !gone.has(q.id)),
2030
+ strokes: collab.strokes.filter((s) => !gone.has(s.id))
2031
+ };
2032
+ }
2033
+ function applyCollabPacket(collab, payload, context) {
2034
+ const item = obj(payload["item"]);
2035
+ const audience = str(payload["audience"]);
2036
+ if (item !== null) {
2037
+ const kind = str(item["kind"]);
2038
+ const hostOnlyView = kind === "poll" || kind === "question";
2039
+ if (hostOnlyView && context.isHost && audience !== "hosts") {
2040
+ return { next: null, dropped: "the room copy of an item a host receives in full" };
2041
+ }
2042
+ let next = withItem(collab, item, true);
2043
+ if (kind === "poll" && str(item["state"]) === "live") {
2044
+ const before = collab.polls.find((p) => p.id === str(item["id"]));
2045
+ if (before === void 0 || before.state !== "live") {
2046
+ next = { ...next, panelRequest: { panel: "polls", at: context.now } };
2047
+ }
2048
+ }
2049
+ if (kind === "breakout") {
2050
+ const plan = planFromRow(item);
2051
+ if (plan !== null && plan.state === "closed") {
2052
+ next = { ...next, moveRequest: { roomId: null, at: context.now } };
2053
+ }
2054
+ }
2055
+ const move = obj(payload["move"]);
2056
+ if (move !== null && str(move["identity"]) === context.localIdentity) {
2057
+ next = { ...next, moveRequest: { roomId: str(move["room_id"]), at: context.now } };
2058
+ }
2059
+ return { next };
2060
+ }
2061
+ if (Array.isArray(payload["removed"])) {
2062
+ return { next: without(collab, strings(payload["removed"])) };
2063
+ }
2064
+ if (Array.isArray(payload["hidden"])) {
2065
+ return context.isHost ? { next: null, dropped: "hosts keep dismissed questions" } : { next: without(collab, strings(payload["hidden"])) };
2066
+ }
2067
+ if (payload["cleared"] === "whiteboard") {
2068
+ return { next: { ...collab, strokes: [] } };
2069
+ }
2070
+ const broadcast = broadcastFrom(payload["broadcast"]);
2071
+ if (broadcast !== null) {
2072
+ return { next: { ...collab, broadcast } };
2073
+ }
2074
+ return { next: null, dropped: "a collab packet with nothing this version understands" };
2075
+ }
2076
+ function assignedRoom(plan, identity) {
2077
+ if (plan === null || plan.state !== "open" || identity === null) return null;
2078
+ return plan.rooms.find((room) => room.identities.includes(identity)) ?? null;
2079
+ }
2080
+ function autoAssign(identities, rooms, exclude = []) {
2081
+ const count2 = Math.max(1, Math.floor(rooms));
2082
+ const out = Array.from({ length: count2 }, () => []);
2083
+ const skip = new Set(exclude);
2084
+ let index = 0;
2085
+ for (const identity of identities) {
2086
+ if (skip.has(identity)) continue;
2087
+ out[index % count2].push(identity);
2088
+ index += 1;
2089
+ }
2090
+ return out;
2091
+ }
2092
+ function breakoutRemainingMs(plan, now) {
2093
+ if (plan === null || plan.state !== "open" || plan.endsAt === null) return null;
2094
+ const end = Date.parse(plan.endsAt);
2095
+ return Number.isNaN(end) ? null : Math.max(0, end - now);
2096
+ }
2097
+ function defaultCaptionLanguage(settings, viewerLanguage) {
2098
+ const configured = settings?.captionTranslationLanguage.trim() ?? "";
2099
+ if (configured.length > 0) return configured;
2100
+ const own = (viewerLanguage ?? "").trim();
2101
+ return own.length > 0 ? own : "en";
2102
+ }
2103
+ var CAPTION_LANGUAGES = [
2104
+ { tag: "en", name: "English" },
2105
+ { tag: "es", name: "Spanish" },
2106
+ { tag: "fr", name: "French" },
2107
+ { tag: "de", name: "German" },
2108
+ { tag: "it", name: "Italian" },
2109
+ { tag: "pt", name: "Portuguese" },
2110
+ { tag: "nl", name: "Dutch" },
2111
+ { tag: "pl", name: "Polish" },
2112
+ { tag: "ru", name: "Russian" },
2113
+ { tag: "uk", name: "Ukrainian" },
2114
+ { tag: "tr", name: "Turkish" },
2115
+ { tag: "ar", name: "Arabic" },
2116
+ { tag: "he", name: "Hebrew" },
2117
+ { tag: "fa", name: "Persian" },
2118
+ { tag: "hi", name: "Hindi" },
2119
+ { tag: "bn", name: "Bengali" },
2120
+ { tag: "zh", name: "Chinese" },
2121
+ { tag: "ja", name: "Japanese" },
2122
+ { tag: "ko", name: "Korean" },
2123
+ { tag: "vi", name: "Vietnamese" },
2124
+ { tag: "th", name: "Thai" },
2125
+ { tag: "id", name: "Indonesian" },
2126
+ { tag: "sv", name: "Swedish" }
2127
+ ];
2128
+ async function loadMeetingActivities(api, meetingId, roomToken = null) {
2129
+ let response;
2130
+ try {
2131
+ response = await api.request({
2132
+ path: `${MEET_ROUTES.collab}?meeting_id=${encodeURIComponent(meetingId)}`,
2133
+ method: "GET",
2134
+ operation: "meet.loadMeetingActivities",
2135
+ requireAuth: roomToken === null,
2136
+ ...roomToken !== null ? { headers: { [ROOM_TOKEN_HEADER]: roomToken } } : {}
2137
+ });
2138
+ } catch (error) {
2139
+ return {
2140
+ collab: null,
2141
+ refusal: {
2142
+ message: `Polls, questions and the whiteboard could not be read (${error.message}).`,
2143
+ remedy: error.remedy ?? "Reload the page."
2144
+ }
2145
+ };
2146
+ }
2147
+ if (!response.ok) {
2148
+ let body = null;
2149
+ try {
2150
+ body = await response.json();
2151
+ } catch {
2152
+ body = null;
2153
+ }
2154
+ const said = readServerRefusal(body);
2155
+ return {
2156
+ collab: null,
2157
+ refusal: {
2158
+ message: said?.reason ?? `Polls and questions could not be read (the server answered ${response.status}).`,
2159
+ remedy: said?.remedy || "Reload the page."
2160
+ }
2161
+ };
2162
+ }
2163
+ return { collab: collabFromState(await response.json(), EMPTY_COLLAB), refusal: null };
2164
+ }
2165
+
1796
2166
  // src/core/transcript.ts
1797
2167
  function normalizeSpoken(text3) {
1798
2168
  return text3.toLowerCase().replace(/[^\p{L}\p{N}]+/gu, " ").trim();
@@ -1894,7 +2264,9 @@ var EMPTY = {
1894
2264
  wrapUp: null,
1895
2265
  noteTakerRefusal: null,
1896
2266
  media: IDLE_MEDIA,
1897
- failure: null
2267
+ failure: null,
2268
+ collab: EMPTY_COLLAB,
2269
+ breakoutRoomId: null
1898
2270
  };
1899
2271
  function effectiveRole(snapshot) {
1900
2272
  const me = snapshot.participants.find(
@@ -2545,7 +2917,19 @@ var INVITEE_COLUMNS = "id,meeting_id,invitee_user_id,email,display_name,role,rsv
2545
2917
  var RECORDING_COLUMNS = "id,meeting_id,state,started_at,ended_at,started_by,file_id,failure_reason";
2546
2918
  var SEGMENT_COLUMNS = "id,meeting_id,identity,speaker,text,started_at,is_final,metadata";
2547
2919
  var NOTE_COLUMNS = "id,meeting_id,text,kind,assignee_user_id,created_at,metadata";
2548
- var ATTENDEE_COLUMNS = "id,meeting_id,identity,participant_user_id,display_name,avatar_url,role,admission_state,is_agent,joined_at,left_at";
2920
+ 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";
2921
+ function projectStays(value) {
2922
+ if (!Array.isArray(value)) return [];
2923
+ const stays = [];
2924
+ for (const item of value) {
2925
+ if (item === null || typeof item !== "object") continue;
2926
+ const joined = item["joined_at"];
2927
+ const left = item["left_at"];
2928
+ if (typeof joined !== "string" || joined.length === 0) continue;
2929
+ stays.push({ joinedAt: joined, leftAt: typeof left === "string" && left.length > 0 ? left : null });
2930
+ }
2931
+ return stays;
2932
+ }
2549
2933
  function text(row, key) {
2550
2934
  const value = row[key];
2551
2935
  return typeof value === "string" && value.length > 0 ? value : null;
@@ -2644,7 +3028,7 @@ var OCCURRENCE_STATES = ["scheduled", "moved", "cancelled"];
2644
3028
  function rsvpState(value) {
2645
3029
  return RSVP_STATES.includes(value) ? value : "needs_action";
2646
3030
  }
2647
- function num(row, key) {
3031
+ function num2(row, key) {
2648
3032
  const value = row[key];
2649
3033
  return typeof value === "number" ? value : null;
2650
3034
  }
@@ -2666,7 +3050,7 @@ function projectInvitee(row) {
2666
3050
  rsvpState: rsvpState(text(row, "rsvp_state")),
2667
3051
  respondedAt: when(row, "responded_at"),
2668
3052
  rsvpNote: text(row, "rsvp_note"),
2669
- lastSentSequence: num(row, "last_sent_sequence"),
3053
+ lastSentSequence: num2(row, "last_sent_sequence"),
2670
3054
  lastSentAt: when(row, "last_sent_at")
2671
3055
  };
2672
3056
  }
@@ -2677,10 +3061,10 @@ function projectOccurrence(row) {
2677
3061
  meetingId: asMeetingId(requireText(row, "meeting_id", operation)),
2678
3062
  originalStart: when(row, "original_start") ?? requireText(row, "original_start", operation),
2679
3063
  occurrenceStart: when(row, "occurrence_start") ?? requireText(row, "occurrence_start", operation),
2680
- durationMinutes: num(row, "duration_minutes"),
3064
+ durationMinutes: num2(row, "duration_minutes"),
2681
3065
  // An unknown state is shown as scheduled, never dropped: the row is real.
2682
3066
  state: OCCURRENCE_STATES.includes(state) ? state : "scheduled",
2683
- sequence: num(row, "sequence") ?? 0
3067
+ sequence: num2(row, "sequence") ?? 0
2684
3068
  };
2685
3069
  }
2686
3070
  function projectUpcoming(row) {
@@ -2709,9 +3093,9 @@ function projectOverride(row) {
2709
3093
  originalStart: when(row, "original_start") ?? requireText(row, "original_start", operation),
2710
3094
  state: text(row, "state") === "moved" ? "moved" : "cancelled",
2711
3095
  newStart: when(row, "new_start"),
2712
- newDurationMinutes: num(row, "new_duration_minutes"),
3096
+ newDurationMinutes: num2(row, "new_duration_minutes"),
2713
3097
  reason: text(row, "reason"),
2714
- calendarSequence: num(row, "calendar_sequence") ?? 0,
3098
+ calendarSequence: num2(row, "calendar_sequence") ?? 0,
2715
3099
  deletedAt: when(row, "deleted_at")
2716
3100
  };
2717
3101
  }
@@ -2735,7 +3119,7 @@ function projectRsvpInvitation(body) {
2735
3119
  title: text(meeting, "title") ?? "Meeting",
2736
3120
  slug: requireText(meeting, "slug", operation),
2737
3121
  scheduledFor: when(meeting, "scheduled_for"),
2738
- durationMinutes: num(meeting, "duration_minutes"),
3122
+ durationMinutes: num2(meeting, "duration_minutes"),
2739
3123
  timeZone: text(meeting, "time_zone") ?? "UTC",
2740
3124
  agenda: text(meeting, "agenda"),
2741
3125
  recurrenceRule: text(meeting, "recurrence_rule"),
@@ -2769,6 +3153,7 @@ function changesPatch(changes) {
2769
3153
  patch["scheduled_duration_minutes"] = changes.scheduledDurationMinutes;
2770
3154
  }
2771
3155
  if (changes.recurrenceRule !== void 0) patch["recurrence_rule"] = changes.recurrenceRule;
3156
+ if (changes.keepExceptions !== void 0) patch["keep_exceptions"] = changes.keepExceptions;
2772
3157
  return patch;
2773
3158
  }
2774
3159
  function createMeetRepository(options) {
@@ -2915,7 +3300,8 @@ function createMeetRepository(options) {
2915
3300
  admissionState: states.includes(admission) ? admission : "admitted",
2916
3301
  isAgent: bool(row, "is_agent", false),
2917
3302
  joinedAt: text(row, "joined_at"),
2918
- leftAt: text(row, "left_at")
3303
+ leftAt: text(row, "left_at"),
3304
+ sessions: projectStays(row["sessions"])
2919
3305
  };
2920
3306
  }
2921
3307
  function requireOrg(organizationId, operation) {
@@ -3309,8 +3695,8 @@ function projectLibraryRecording(row) {
3309
3695
  fileId: text(row, "file_id"),
3310
3696
  startedAt: text(row, "started_at"),
3311
3697
  endedAt: text(row, "ended_at"),
3312
- durationMs: num(row, "duration_ms"),
3313
- sizeBytes: num(row, "size_bytes"),
3698
+ durationMs: num2(row, "duration_ms"),
3699
+ sizeBytes: num2(row, "size_bytes"),
3314
3700
  failureReason: text(row, "failure_reason"),
3315
3701
  archivedAt: text(row, "deleted_at"),
3316
3702
  organizationId: asOrganizationId(requireText(row, "organization_id", operation))
@@ -3337,7 +3723,7 @@ function projectSearchHit(row) {
3337
3723
  speaker: text(row, "speaker"),
3338
3724
  snippet: text(row, "snippet") ?? "",
3339
3725
  at: text(row, "said_at"),
3340
- rank: num(row, "rank") ?? 0
3726
+ rank: num2(row, "rank") ?? 0
3341
3727
  };
3342
3728
  }
3343
3729
  function snippetRuns(snippet) {
@@ -3482,7 +3868,14 @@ var ROOM_EVENTS = {
3482
3868
  * person concerned; `lower-hands {identities: [...] | "*"}` · `role {identity,
3483
3869
  * role}` — to everyone.
3484
3870
  */
3485
- moderation: "matrx.meet.moderation"
3871
+ moderation: "matrx.meet.moderation",
3872
+ /**
3873
+ * A meeting ROOM ITEM changed (Meet wave 5): a poll, a Q&A question, a whiteboard
3874
+ * stroke or the breakout plan. Payload `{ meeting_id, item }` · `{ removed: [ids] }` ·
3875
+ * `{ hidden: [ids] }` · `{ cleared: "whiteboard" }` · `{ broadcast }` · `{ item, move }`.
3876
+ * A host's fuller copy of a poll or question carries `audience: "hosts"`.
3877
+ */
3878
+ collab: "matrx.meet.collab"
3486
3879
  };
3487
3880
  function isRoomEventTopic(topic) {
3488
3881
  return topic.startsWith(ROOM_EVENT_PREFIX);
@@ -3522,10 +3915,27 @@ function applyRoomEvent(args) {
3522
3915
  return applyChat(store, payload);
3523
3916
  case ROOM_EVENTS.moderation:
3524
3917
  return applyModeration(store, payload, now);
3918
+ case ROOM_EVENTS.collab:
3919
+ return applyCollab(store, payload, now);
3525
3920
  default:
3526
3921
  return ignored(`${topic} is not known to this version of @ai-matrx/meet`);
3527
3922
  }
3528
3923
  }
3924
+ function applyCollab(store, payload, now) {
3925
+ const snapshot = store.snapshot();
3926
+ const meeting = snapshot.meeting;
3927
+ if (meeting !== null && text2(payload["meeting_id"]) !== null && payload["meeting_id"] !== meeting.id) {
3928
+ return ignored("a collab event for a different meeting than this room is showing");
3929
+ }
3930
+ const result = applyCollabPacket(snapshot.collab, payload, {
3931
+ localIdentity: snapshot.localIdentity,
3932
+ isHost: ROLE_RANK[effectiveRole(snapshot)] >= ROLE_RANK.cohost,
3933
+ now: now()
3934
+ });
3935
+ if (result.next === null) return ignored(result.dropped ?? "a collab packet that changed nothing");
3936
+ store.patch({ collab: result.next });
3937
+ return HANDLED;
3938
+ }
3529
3939
  function applyNote(store, payload) {
3530
3940
  const row = object(payload["note"]);
3531
3941
  if (row === null) return ignored("a note event with no `note` row");
@@ -3847,6 +4257,7 @@ function createRoomEngine(options) {
3847
4257
  let joining = null;
3848
4258
  let lastRequest = null;
3849
4259
  let disposed = false;
4260
+ let moving = false;
3850
4261
  const confirmingEnds = /* @__PURE__ */ new WeakSet();
3851
4262
  async function leaveRoom() {
3852
4263
  const target = driver;
@@ -4076,6 +4487,7 @@ function createRoomEngine(options) {
4076
4487
  }
4077
4488
  },
4078
4489
  disconnected(reason) {
4490
+ if (moving) return;
4079
4491
  if (current !== null) {
4080
4492
  tokens.invalidate(current.roomName);
4081
4493
  current = null;
@@ -4090,11 +4502,13 @@ function createRoomEngine(options) {
4090
4502
  roomName: request.roomName,
4091
4503
  identity,
4092
4504
  ...request.meetingId !== void 0 ? { meetingId: request.meetingId } : {},
4093
- ...request.slug !== void 0 ? { slug: request.slug } : {}
4505
+ ...request.slug !== void 0 ? { slug: request.slug } : {},
4506
+ ...request.breakoutRoomId != null ? { breakoutRoomId: request.breakoutRoomId } : {}
4094
4507
  });
4095
4508
  current = token;
4096
4509
  store.patch({
4097
4510
  localIdentity: token.identity,
4511
+ breakoutRoomId: token.breakoutRoomId ?? null,
4098
4512
  grants: {
4099
4513
  role: token.role,
4100
4514
  canRecord: token.canRecord,
@@ -4213,6 +4627,56 @@ function createRoomEngine(options) {
4213
4627
  });
4214
4628
  return joining;
4215
4629
  },
4630
+ async moveToBreakout(roomId) {
4631
+ const request = lastRequest;
4632
+ if (request === null || driver === null) {
4633
+ report(
4634
+ "warn",
4635
+ "meet.moveToBreakout: this engine is not in a meeting room",
4636
+ "Join the meeting first; a breakout is a room OF a meeting."
4637
+ );
4638
+ return;
4639
+ }
4640
+ if ((store.snapshot().breakoutRoomId ?? null) === roomId) return;
4641
+ if (joining !== null) await joining.catch(() => void 0);
4642
+ const previous = driver;
4643
+ const next = {
4644
+ ...request,
4645
+ breakoutRoomId: roomId,
4646
+ // Arrive as you were: camera and microphone as they are now.
4647
+ mode: store.snapshot().media.camera.enabled ? "video" : "audio",
4648
+ microphone: store.snapshot().media.microphone.enabled
4649
+ };
4650
+ moving = true;
4651
+ try {
4652
+ driver = null;
4653
+ tokens.invalidate(request.roomName);
4654
+ current = null;
4655
+ await previous.disconnect();
4656
+ lastRequest = next;
4657
+ joining = connect(next).finally(() => {
4658
+ joining = null;
4659
+ });
4660
+ await joining;
4661
+ } catch (error) {
4662
+ const normalized = normalizeMeetError(error, "meet.moveToBreakout");
4663
+ report("warn", normalized.message, normalized.remedy);
4664
+ if (roomId !== null) {
4665
+ lastRequest = { ...next, breakoutRoomId: null };
4666
+ joining = connect(lastRequest).finally(() => {
4667
+ joining = null;
4668
+ });
4669
+ await joining.catch((again) => {
4670
+ throw fail(again, "meet.moveToBreakout");
4671
+ });
4672
+ } else {
4673
+ throw fail(error, "meet.moveToBreakout");
4674
+ }
4675
+ throw normalized;
4676
+ } finally {
4677
+ moving = false;
4678
+ }
4679
+ },
4216
4680
  leave: leaveRoom,
4217
4681
  // Turning a device on mid-meeting is the SAME operation as turning it on
4218
4682
  // during the join, so it runs the same function. A failure here used to
@@ -4482,6 +4946,109 @@ function createInRoomClient(options) {
4482
4946
  (row) => typeof row === "object" && row !== null ? chatFromRow(row) : null
4483
4947
  ).filter((message) => message !== null);
4484
4948
  store.loadChat(messages);
4949
+ },
4950
+ async loadCollab() {
4951
+ const operation = "meet.loadCollab";
4952
+ const id = meetingId(operation);
4953
+ const hdrs = headers();
4954
+ const response = await api.request({
4955
+ path: `${MEET_ROUTES.collab}?meeting_id=${encodeURIComponent(id)}`,
4956
+ method: "GET",
4957
+ operation,
4958
+ ...hdrs !== void 0 ? { headers: hdrs } : {}
4959
+ });
4960
+ if (!response.ok) {
4961
+ const error = await refusal2(
4962
+ response,
4963
+ operation,
4964
+ "Polls, questions and the whiteboard could not be read. New ones still arrive."
4965
+ );
4966
+ store.patch({ collab: { ...store.snapshot().collab, loaded: true, error: error.message } });
4967
+ throw error;
4968
+ }
4969
+ const body = await response.json();
4970
+ store.patch({ collab: collabFromState(body, store.snapshot().collab) });
4971
+ },
4972
+ async collab(request) {
4973
+ const operation = `meet.collab(${request.action})`;
4974
+ const hdrs = headers();
4975
+ const response = await api.request({
4976
+ path: MEET_ROUTES.collab,
4977
+ method: "POST",
4978
+ operation,
4979
+ body: {
4980
+ meeting_id: meetingId(operation),
4981
+ action: request.action,
4982
+ ...request.itemId !== void 0 ? { item_id: request.itemId } : {},
4983
+ ...request.question !== void 0 ? { question: request.question } : {},
4984
+ ...request.options !== void 0 ? { options: request.options } : {},
4985
+ ...request.multiple !== void 0 ? { multiple: request.multiple } : {},
4986
+ ...request.anonymous !== void 0 ? { anonymous: request.anonymous } : {},
4987
+ ...request.optionIds !== void 0 ? { option_ids: request.optionIds } : {},
4988
+ ...request.text !== void 0 ? { text: request.text } : {},
4989
+ ...request.stroke !== void 0 ? { stroke: request.stroke } : {},
4990
+ ...request.rooms !== void 0 ? { rooms: request.rooms } : {},
4991
+ ...request.allowChoose !== void 0 ? { allow_choose: request.allowChoose } : {},
4992
+ ...request.minutes !== void 0 ? { minutes: request.minutes } : {},
4993
+ ...request.identity !== void 0 ? { identity: request.identity } : {},
4994
+ ...request.roomId !== void 0 ? { room_id: request.roomId } : {}
4995
+ },
4996
+ ...hdrs !== void 0 ? { headers: hdrs } : {}
4997
+ });
4998
+ if (!response.ok) {
4999
+ throw await refusal2(response, operation, "Nothing was changed.");
5000
+ }
5001
+ const payload = await response.json();
5002
+ const removed = Array.isArray(payload["removed"]) ? payload["removed"].filter((v) => typeof v === "string") : [];
5003
+ let next = store.snapshot().collab;
5004
+ const item = payload["item"];
5005
+ if (typeof item === "object" && item !== null) next = withItem(next, item);
5006
+ if (removed.length > 0) {
5007
+ const gone = new Set(removed);
5008
+ next = {
5009
+ ...next,
5010
+ polls: next.polls.filter((p) => !gone.has(p.id)),
5011
+ questions: next.questions.filter((q) => !gone.has(q.id)),
5012
+ strokes: next.strokes.filter((st) => !gone.has(st.id))
5013
+ };
5014
+ }
5015
+ store.patch({ collab: next });
5016
+ const itemId = typeof item === "object" && item !== null && typeof item["id"] === "string" ? item["id"] : null;
5017
+ return {
5018
+ action: request.action,
5019
+ message: typeof payload["message"] === "string" ? payload["message"] : "Done.",
5020
+ removed,
5021
+ itemId
5022
+ };
5023
+ },
5024
+ async translateCaptions(language, lines) {
5025
+ if (lines.length === 0) return;
5026
+ const operation = "meet.translateCaptions";
5027
+ const hdrs = headers();
5028
+ const response = await api.request({
5029
+ path: MEET_ROUTES.captionsTranslate,
5030
+ method: "POST",
5031
+ operation,
5032
+ body: { meeting_id: meetingId(operation), target_language: language, lines },
5033
+ ...hdrs !== void 0 ? { headers: hdrs } : {}
5034
+ });
5035
+ if (!response.ok) {
5036
+ const error = await refusal2(response, operation, "Captions stay in the language they were spoken.");
5037
+ store.patch({
5038
+ collab: { ...store.snapshot().collab, captionTranslationError: error.message }
5039
+ });
5040
+ throw error;
5041
+ }
5042
+ const payload = await response.json();
5043
+ const current = store.snapshot().collab;
5044
+ if (current.captionLanguage !== language) return;
5045
+ const merged = { ...current.captionTranslations };
5046
+ for (const [id, value] of Object.entries(payload.translations ?? {})) {
5047
+ if (typeof value === "string") merged[id] = value;
5048
+ }
5049
+ store.patch({
5050
+ collab: { ...current, captionTranslations: merged, captionTranslationError: null }
5051
+ });
4485
5052
  }
4486
5053
  };
4487
5054
  }
@@ -4600,6 +5167,15 @@ function createLiveKitDriver(handlers, options = {}) {
4600
5167
  handlers.participants([local, ...remotes]);
4601
5168
  };
4602
5169
  projectRoster = roster;
5170
+ created.on(RoomEvent.TrackSubscribed, (track) => {
5171
+ if (track.kind !== Track.Kind.Audio || typeof document === "undefined") return;
5172
+ const element = track.attach();
5173
+ element.setAttribute("data-mx-meet-audio", "");
5174
+ audioSink().appendChild(element);
5175
+ }).on(RoomEvent.TrackUnsubscribed, (track) => {
5176
+ if (track.kind !== Track.Kind.Audio) return;
5177
+ for (const element of track.detach()) element.remove();
5178
+ });
4603
5179
  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) => {
4604
5180
  handlers.roomMetadata?.(metadata ?? "");
4605
5181
  }).on(RoomEvent.ActiveSpeakersChanged, (speakers) => {
@@ -4615,6 +5191,8 @@ function createLiveKitDriver(handlers, options = {}) {
4615
5191
  participant?.identity ?? null
4616
5192
  );
4617
5193
  }).on(RoomEvent.Disconnected, (reason) => {
5194
+ audioContainer?.remove();
5195
+ audioContainer = null;
4618
5196
  handlers.disconnected(reason === void 0 ? null : String(reason));
4619
5197
  });
4620
5198
  try {
@@ -4656,10 +5234,26 @@ function createLiveKitDriver(handlers, options = {}) {
4656
5234
  microphone: Track.Source.Microphone,
4657
5235
  screen: Track.Source.ScreenShare
4658
5236
  };
5237
+ trackEvents = {
5238
+ subscribed: RoomEvent.TrackSubscribed,
5239
+ localPublished: RoomEvent.LocalTrackPublished
5240
+ };
4659
5241
  room = created;
4660
5242
  return created;
4661
5243
  }
4662
5244
  let sources = null;
5245
+ let trackEvents = null;
5246
+ let audioContainer = null;
5247
+ function audioSink() {
5248
+ if (audioContainer !== null && audioContainer.isConnected) return audioContainer;
5249
+ const container = document.createElement("div");
5250
+ container.setAttribute("data-mx-meet-audio-sink", "");
5251
+ container.setAttribute("aria-hidden", "true");
5252
+ container.style.display = "none";
5253
+ document.body.appendChild(container);
5254
+ audioContainer = container;
5255
+ return container;
5256
+ }
4663
5257
  function requireRoom(operation) {
4664
5258
  if (room === null) {
4665
5259
  throw new MeetError(
@@ -4690,6 +5284,8 @@ function createLiveKitDriver(handlers, options = {}) {
4690
5284
  } catch {
4691
5285
  }
4692
5286
  projectRoster = null;
5287
+ audioContainer?.remove();
5288
+ audioContainer = null;
4693
5289
  await target.disconnect();
4694
5290
  },
4695
5291
  async setMicrophoneEnabled(enabled) {
@@ -4755,14 +5351,33 @@ function createLiveKitDriver(handlers, options = {}) {
4755
5351
  attach(identity, kind, element) {
4756
5352
  const target = requireRoom("attach");
4757
5353
  const source = sources?.[kind];
4758
- const participant = target.localParticipant.identity === identity ? target.localParticipant : target.remoteParticipants.get(identity);
4759
- if (participant === void 0 || source === void 0) return () => void 0;
4760
- const publication = participant.getTrackPublication(source);
4761
- const track = publication?.track;
4762
- if (track === void 0) return () => void 0;
4763
- track.attach(element);
5354
+ if (source === void 0) return () => void 0;
5355
+ let current = null;
5356
+ const sync = () => {
5357
+ const participant = target.localParticipant.identity === identity ? target.localParticipant : target.remoteParticipants.get(identity);
5358
+ const track = participant?.getTrackPublication(source)?.track;
5359
+ if (track === void 0 || track === current) return;
5360
+ current?.detach(element);
5361
+ track.attach(element);
5362
+ current = track;
5363
+ };
5364
+ const onTrack = (...args) => {
5365
+ const who = args[args.length - 1];
5366
+ if (who?.identity === identity) sync();
5367
+ };
5368
+ sync();
5369
+ const events = trackEvents;
5370
+ if (events !== null) {
5371
+ target.on(events.subscribed, onTrack);
5372
+ target.on(events.localPublished, onTrack);
5373
+ }
4764
5374
  return () => {
4765
- track.detach(element);
5375
+ if (events !== null) {
5376
+ target.off(events.subscribed, onTrack);
5377
+ target.off(events.localPublished, onTrack);
5378
+ }
5379
+ current?.detach(element);
5380
+ current = null;
4766
5381
  };
4767
5382
  },
4768
5383
  activeDevices() {
@@ -5001,6 +5616,14 @@ function MeetRuntime(props) {
5001
5616
  }
5002
5617
  if (chatReadFor === snapshot.meeting.id) return;
5003
5618
  chatReadFor = snapshot.meeting.id;
5619
+ void inRoom.loadCollab().catch((error) => {
5620
+ const normalized = error;
5621
+ report({
5622
+ level: "warn",
5623
+ message: normalized.message ?? "meet: polls, questions and the whiteboard could not be read",
5624
+ ...normalized.remedy !== void 0 ? { remedy: normalized.remedy } : {}
5625
+ });
5626
+ });
5004
5627
  void inRoom.loadChat().catch((error) => {
5005
5628
  const normalized = error;
5006
5629
  store.patch({
@@ -6341,7 +6964,7 @@ function useGuestRecordAccess(meeting) {
6341
6964
  }
6342
6965
 
6343
6966
  // src/react/components.tsx
6344
- var import_react4 = require("react");
6967
+ var import_react5 = require("react");
6345
6968
  var import_design_system = require("@ai-matrx/design-system");
6346
6969
  var import_format3 = require("@ai-matrx/kit/format");
6347
6970
 
@@ -6352,6 +6975,7 @@ function kindOf(person) {
6352
6975
  if (person.role === "host") return "host";
6353
6976
  if (person.role === "cohost") return "cohost";
6354
6977
  if (person.role === "guest") return person.userId !== null ? "signed-in guest" : "guest";
6978
+ if (person.userId === null) return "guest";
6355
6979
  return "member";
6356
6980
  }
6357
6981
  function ms(iso) {
@@ -6407,12 +7031,19 @@ function coveredMs(intervals) {
6407
7031
  }
6408
7032
  function attendanceReport(meeting, attendees, names = {}) {
6409
7033
  const end = ms(meeting.endedAt);
7034
+ const measuredOf = /* @__PURE__ */ new Map();
6410
7035
  const perJoin = attendees.map((person) => {
6411
- const joined = ms(person.joinedAt);
6412
- const left = ms(person.leftAt);
6413
- const until = left ?? end;
6414
- const duration = joined !== null && until !== null && until >= joined ? until - joined : null;
6415
- return {
7036
+ 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)]];
7037
+ let toEnd = false;
7038
+ const measured = [];
7039
+ for (const [joined, left] of stays) {
7040
+ const until = left ?? end;
7041
+ if (joined === null || until === null || until < joined) continue;
7042
+ if (left === null) toEnd = true;
7043
+ measured.push([joined, until]);
7044
+ }
7045
+ const duration = measured.length === 0 ? null : coveredMs(measured);
7046
+ const row = {
6416
7047
  id: person.id,
6417
7048
  identity: person.identity,
6418
7049
  name: displayNameFor(names, person.identity, person.displayName),
@@ -6421,10 +7052,12 @@ function attendanceReport(meeting, attendees, names = {}) {
6421
7052
  joinedAt: person.joinedAt,
6422
7053
  leftAt: person.leftAt,
6423
7054
  durationMs: duration,
6424
- durationToEnd: duration !== null && left === null,
7055
+ durationToEnd: duration !== null && toEnd,
6425
7056
  admission: person.admissionState,
6426
- joins: 1
7057
+ joins: Math.max(1, person.sessions?.length ?? 0)
6427
7058
  };
7059
+ measuredOf.set(row, measured);
7060
+ return row;
6428
7061
  });
6429
7062
  const groups = /* @__PURE__ */ new Map();
6430
7063
  attendees.forEach((person, index) => {
@@ -6447,17 +7080,14 @@ function attendanceReport(meeting, attendees, names = {}) {
6447
7080
  const left = ms(row.leftAt);
6448
7081
  return left !== null && (latest === null || left > latest) ? left : latest;
6449
7082
  }, null);
6450
- const intervals = came.flatMap((row) => {
6451
- const joined = ms(row.joinedAt);
6452
- return joined !== null && row.durationMs !== null ? [[joined, joined + row.durationMs]] : [];
6453
- });
7083
+ const intervals = came.flatMap((row) => measuredOf.get(row) ?? []);
6454
7084
  return {
6455
7085
  ...first,
6456
7086
  kind,
6457
7087
  leftAt: open ? null : lastLeave === null ? null : new Date(lastLeave).toISOString(),
6458
7088
  durationMs: intervals.length === 0 ? null : coveredMs(intervals),
6459
7089
  durationToEnd: came.some((row) => row.durationToEnd),
6460
- joins: came.length === 0 ? joins.length : came.length
7090
+ joins: came.length === 0 ? joins.length : came.reduce((total, row) => total + row.joins, 0)
6461
7091
  };
6462
7092
  });
6463
7093
  const rank = KIND_RANK;
@@ -6601,8 +7231,8 @@ function transcriptDocument(bundle, format, options = {}) {
6601
7231
  if (line.identity !== last) {
6602
7232
  if (last !== null) out.push("");
6603
7233
  const who = speaker(line);
6604
- const clock = clockOfDay(line.startedAt, options);
6605
- out.push(format === "md" ? `**${who}** \xB7 ${clock}` : `${who} (${clock})`);
7234
+ const clock2 = clockOfDay(line.startedAt, options);
7235
+ out.push(format === "md" ? `**${who}** \xB7 ${clock2}` : `${who} (${clock2})`);
6606
7236
  last = line.identity;
6607
7237
  }
6608
7238
  out.push(line.text.trim());
@@ -6783,6 +7413,9 @@ function countLabel(count2, singular, plural = `${singular}s`) {
6783
7413
  return `${count2} ${count2 === 1 ? singular : plural}`;
6784
7414
  }
6785
7415
 
7416
+ // src/react/collab.tsx
7417
+ var import_react4 = require("react");
7418
+
6786
7419
  // src/react/icons.tsx
6787
7420
  var import_jsx_runtime2 = require("react/jsx-runtime");
6788
7421
  function Icon({ children, ...props }) {
@@ -6967,60 +7600,1089 @@ function FlagIcon(props) {
6967
7600
  function PencilIcon(props) {
6968
7601
  return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Icon, { ...props, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "M17 3a2.85 2.83 0 1 1 4 4L7.5 20.5 2 22l1.5-5.5Z" }) });
6969
7602
  }
6970
-
6971
- // src/react/components.tsx
6972
- var import_jsx_runtime3 = require("react/jsx-runtime");
6973
- function InertNotice({ what }) {
6974
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "mx-meet__empty", role: "status", children: [
6975
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("p", { className: "mx-meet__empty-title", children: [
6976
- what,
6977
- " is not ready yet"
6978
- ] }),
6979
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("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." })
7603
+ function ActivitiesIcon(props) {
7604
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(Icon, { ...props, children: [
7605
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("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" }),
7606
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("rect", { x: "3", y: "14", width: "7", height: "7", rx: "1" }),
7607
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("circle", { cx: "17.5", cy: "17.5", r: "3.5" })
6980
7608
  ] });
6981
7609
  }
6982
- function Avatar({
6983
- name,
6984
- url,
6985
- size = 40
6986
- }) {
6987
- const tint = (0, import_format3.avatarPaletteIndex)(name);
6988
- if (url != null && url.length > 0) {
6989
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
6990
- "img",
6991
- {
6992
- className: "mx-meet__avatar",
6993
- src: url,
6994
- alt: "",
6995
- width: size,
6996
- height: size,
6997
- style: { width: size, height: size }
7610
+ function PollIcon(props) {
7611
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(Icon, { ...props, children: [
7612
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("line", { x1: "18", x2: "18", y1: "20", y2: "10" }),
7613
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("line", { x1: "12", x2: "12", y1: "20", y2: "4" }),
7614
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("line", { x1: "6", x2: "6", y1: "20", y2: "14" })
7615
+ ] });
7616
+ }
7617
+ function QuestionIcon(props) {
7618
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(Icon, { ...props, children: [
7619
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "M7.9 20A9 9 0 1 0 4 16.1L2 22Z" }),
7620
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "M9.09 9a3 3 0 0 1 5.83 1c0 2-3 3-3 3" }),
7621
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "M12 17h.01" })
7622
+ ] });
7623
+ }
7624
+ function WhiteboardIcon(props) {
7625
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(Icon, { ...props, children: [
7626
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "M2 3h20" }),
7627
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "M21 3v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V3" }),
7628
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "m7 21 5-5 5 5" })
7629
+ ] });
7630
+ }
7631
+ function BreakoutIcon(props) {
7632
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(Icon, { ...props, children: [
7633
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("rect", { width: "7", height: "18", x: "3", y: "3", rx: "1" }),
7634
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("rect", { width: "7", height: "7", x: "14", y: "3", rx: "1" }),
7635
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("rect", { width: "7", height: "7", x: "14", y: "14", rx: "1" })
7636
+ ] });
7637
+ }
7638
+ function UpvoteIcon(props) {
7639
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Icon, { ...props, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "M9 18v-6H5l7-7 7 7h-4v6H9z" }) });
7640
+ }
7641
+ function EraserIcon(props) {
7642
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(Icon, { ...props, children: [
7643
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("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" }),
7644
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "M22 21H7" }),
7645
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "m5 11 9 9" })
7646
+ ] });
7647
+ }
7648
+ function HighlighterIcon(props) {
7649
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(Icon, { ...props, children: [
7650
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "m9 11-6 6v3h9l3-3" }),
7651
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("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" })
7652
+ ] });
7653
+ }
7654
+ function UndoIcon(props) {
7655
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(Icon, { ...props, children: [
7656
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "M9 14 4 9l5-5" }),
7657
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("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" })
7658
+ ] });
7659
+ }
7660
+
7661
+ // src/react/collab.tsx
7662
+ var import_jsx_runtime3 = require("react/jsx-runtime");
7663
+ function useCollab() {
7664
+ const host = useMeetHost();
7665
+ const snapshot = useMeetSnapshot();
7666
+ const isHost = useIsHost();
7667
+ return {
7668
+ collab: snapshot?.collab ?? null,
7669
+ isHost,
7670
+ localIdentity: snapshot?.localIdentity ?? null,
7671
+ breakoutRoomId: snapshot?.breakoutRoomId ?? null,
7672
+ async act(request) {
7673
+ if (host === null) return { ok: false, message: "This meeting is not connected." };
7674
+ try {
7675
+ const result = await host.inRoom.collab(request);
7676
+ return { ok: true, message: result.message, itemId: result.itemId };
7677
+ } catch (error) {
7678
+ return { ok: false, message: error.message ?? "That did not work." };
7679
+ }
7680
+ },
7681
+ async moveTo(roomId) {
7682
+ if (host === null) return { ok: false, message: "This meeting is not connected." };
7683
+ try {
7684
+ await host.engine.moveToBreakout(roomId);
7685
+ return { ok: true, message: roomId === null ? "Back in the main room." : "Joined the breakout room." };
7686
+ } catch (error) {
7687
+ return { ok: false, message: error.message ?? "That room could not be joined." };
6998
7688
  }
6999
- );
7000
- }
7001
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
7002
- "span",
7003
- {
7004
- className: "mx-meet__avatar mx-meet__avatar--initials",
7005
- style: {
7006
- width: size,
7007
- height: size,
7008
- fontSize: Math.round(size * 0.38),
7009
- background: `var(--mx-meet-avatar-${tint})`
7010
- },
7011
- "aria-hidden": "true",
7012
- children: (0, import_format3.getInitials)(name)
7013
7689
  }
7014
- );
7690
+ };
7015
7691
  }
7016
- function ControlButton({
7017
- label,
7692
+ function useNotice() {
7693
+ const [notice, setNotice] = (0, import_react4.useState)(null);
7694
+ (0, import_react4.useEffect)(() => {
7695
+ if (notice === null) return void 0;
7696
+ const timer = setTimeout(() => setNotice(null), notice.failed ? 7e3 : 3e3);
7697
+ return () => clearTimeout(timer);
7698
+ }, [notice]);
7699
+ return [notice, (result) => setNotice({ text: result.message, failed: !result.ok })];
7700
+ }
7701
+ function Notice({ notice }) {
7702
+ if (notice === null) return null;
7703
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: notice.failed ? "mx-meet__panel-note mx-meet__collab-error" : "mx-meet__panel-note", role: "status", children: notice.text });
7704
+ }
7705
+ var ACTIVITY_LABELS = {
7706
+ polls: "Polls",
7707
+ qa: "Q&A",
7708
+ whiteboard: "Whiteboard",
7709
+ breakouts: "Breakout rooms"
7710
+ };
7711
+ function ActivityIcon({ panel }) {
7712
+ const props = { width: 16, height: 16 };
7713
+ if (panel === "polls") return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(PollIcon, { ...props });
7714
+ if (panel === "qa") return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(QuestionIcon, { ...props });
7715
+ if (panel === "whiteboard") return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(WhiteboardIcon, { ...props });
7716
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(BreakoutIcon, { ...props });
7717
+ }
7718
+ function useAvailableActivities() {
7719
+ const { collab, isHost } = useCollab();
7720
+ const settings = collab?.settings ?? null;
7721
+ if (settings === null) return [];
7722
+ const out = [];
7723
+ if (settings.whiteboardEnabled) out.push("whiteboard");
7724
+ if (settings.pollsEnabled && (isHost || (collab?.polls.length ?? 0) > 0)) out.push("polls");
7725
+ if (settings.qaEnabled) out.push("qa");
7726
+ if (settings.breakoutsEnabled && (isHost || collab?.breakout?.state === "open")) out.push("breakouts");
7727
+ return out;
7728
+ }
7729
+ function useActivityAttention() {
7730
+ const { collab, isHost } = useCollab();
7731
+ if (collab === null) return false;
7732
+ if (collab.polls.some((poll) => poll.state === "live" && poll.myVote.length === 0 && !isHost)) return true;
7733
+ if (isHost && collab.questions.some((q) => q.state === "open")) return true;
7734
+ return false;
7735
+ }
7736
+ function ActivitiesControl({
7737
+ active,
7738
+ onOpen
7739
+ }) {
7740
+ const [open, setOpen] = (0, import_react4.useState)(false);
7741
+ const available = useAvailableActivities();
7742
+ const attention = useActivityAttention();
7743
+ if (available.length === 0) return null;
7744
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("span", { className: "mx-meet__anchor", children: [
7745
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(ControlButton, { label: "Activities", active: open || active !== null, onClick: () => setOpen(!open), children: [
7746
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(ActivitiesIcon, {}),
7747
+ attention ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "mx-meet__dot", "aria-hidden": "true" }) : null
7748
+ ] }),
7749
+ open ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Popover, { label: "Activities", onClose: () => setOpen(false), children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "mx-meet__menu", role: "menu", children: available.map((panel) => /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
7750
+ MenuItem,
7751
+ {
7752
+ onSelect: () => {
7753
+ setOpen(false);
7754
+ onOpen(panel);
7755
+ },
7756
+ children: [
7757
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(ActivityIcon, { panel }),
7758
+ " ",
7759
+ ACTIVITY_LABELS[panel]
7760
+ ]
7761
+ },
7762
+ panel
7763
+ )) }) }) : null
7764
+ ] });
7765
+ }
7766
+ function PollComposer({ maxOptions, onDone }) {
7767
+ const { act } = useCollab();
7768
+ const [question, setQuestion] = (0, import_react4.useState)("");
7769
+ const [options, setOptions] = (0, import_react4.useState)(["", ""]);
7770
+ const [multiple, setMultiple] = (0, import_react4.useState)(false);
7771
+ const [anonymous, setAnonymous] = (0, import_react4.useState)(false);
7772
+ const [busy, setBusy] = (0, import_react4.useState)(false);
7773
+ const [notice, show] = useNotice();
7774
+ const filled = options.map((o) => o.trim()).filter(Boolean);
7775
+ const ready = question.trim().length > 0 && filled.length >= 2;
7776
+ const save = async (launch) => {
7777
+ setBusy(true);
7778
+ const created = await act({ action: "poll_create", question, options: filled, multiple, anonymous });
7779
+ if (!created.ok) {
7780
+ show(created);
7781
+ setBusy(false);
7782
+ return;
7783
+ }
7784
+ if (launch && created.itemId != null) {
7785
+ const launched = await act({ action: "poll_launch", itemId: created.itemId });
7786
+ if (!launched.ok) {
7787
+ show(launched);
7788
+ setBusy(false);
7789
+ return;
7790
+ }
7791
+ }
7792
+ setBusy(false);
7793
+ onDone();
7794
+ };
7795
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
7796
+ "form",
7797
+ {
7798
+ className: "mx-meet__collab-card",
7799
+ onSubmit: (event) => {
7800
+ event.preventDefault();
7801
+ if (ready) void save(true);
7802
+ },
7803
+ children: [
7804
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("label", { className: "mx-meet__field", children: [
7805
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "mx-meet__field-label", children: "Question" }),
7806
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
7807
+ "input",
7808
+ {
7809
+ className: "mx-meet__input",
7810
+ value: question,
7811
+ maxLength: 1e3,
7812
+ onChange: (event) => setQuestion(event.target.value),
7813
+ placeholder: "Ask the room something",
7814
+ autoFocus: true
7815
+ }
7816
+ )
7817
+ ] }),
7818
+ options.map((option, index) => /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "mx-meet__composer-row", children: [
7819
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
7820
+ "input",
7821
+ {
7822
+ className: "mx-meet__input",
7823
+ value: option,
7824
+ maxLength: 200,
7825
+ "aria-label": `Answer ${index + 1}`,
7826
+ placeholder: `Answer ${index + 1}`,
7827
+ onChange: (event) => setOptions(options.map((o, i) => i === index ? event.target.value : o))
7828
+ }
7829
+ ),
7830
+ options.length > 2 ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(ControlButton, { label: `Remove answer ${index + 1}`, onClick: () => setOptions(options.filter((_, i) => i !== index)), children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(CloseIcon, { width: 14, height: 14 }) }) : null
7831
+ ] }, index)),
7832
+ options.length < maxOptions ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("button", { type: "button", className: "mx-meet__link", onClick: () => setOptions([...options, ""]), children: "Add an answer" }) : null,
7833
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("label", { className: "mx-meet__toggle", children: [
7834
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("input", { type: "checkbox", checked: multiple, onChange: (event) => setMultiple(event.target.checked) }),
7835
+ "People can pick more than one"
7836
+ ] }),
7837
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("label", { className: "mx-meet__toggle", children: [
7838
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("input", { type: "checkbox", checked: anonymous, onChange: (event) => setAnonymous(event.target.checked) }),
7839
+ "Anonymous \u2014 nobody sees who picked what"
7840
+ ] }),
7841
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Notice, { notice }),
7842
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "mx-meet__collab-actions", children: [
7843
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("button", { type: "submit", className: "mx-meet__primary mx-meet__primary--small", disabled: !ready || busy, children: "Launch" }),
7844
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("button", { type: "button", className: "mx-meet__chip", disabled: !ready || busy, onClick: () => void save(false), children: "Save draft" }),
7845
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("button", { type: "button", className: "mx-meet__link", onClick: onDone, children: "Cancel" })
7846
+ ] })
7847
+ ]
7848
+ }
7849
+ );
7850
+ }
7851
+ function PollCard({ poll }) {
7852
+ const { act, isHost } = useCollab();
7853
+ const [picked, setPicked] = (0, import_react4.useState)(poll.myVote.slice());
7854
+ const [notice, show] = useNotice();
7855
+ (0, import_react4.useEffect)(() => setPicked(poll.myVote.slice()), [poll.myVote]);
7856
+ const counts = poll.options.some((o) => o.votes !== void 0);
7857
+ const total = poll.options.reduce((sum, o) => sum + (o.votes ?? 0), 0);
7858
+ const canVote = poll.state === "live";
7859
+ const voted = poll.myVote.length > 0;
7860
+ const stateWord = poll.state === "draft" ? "Draft" : poll.state === "live" ? "Open" : "Closed";
7861
+ const toggle = (id) => {
7862
+ if (!canVote) return;
7863
+ setPicked(poll.multiple ? picked.includes(id) ? picked.filter((p) => p !== id) : [...picked, id] : [id]);
7864
+ };
7865
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("article", { className: "mx-meet__collab-card", "aria-label": poll.question, children: [
7866
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("header", { className: "mx-meet__collab-head", children: [
7867
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("strong", { className: "mx-meet__collab-title", children: poll.question }),
7868
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "mx-meet__collab-state", children: stateWord })
7869
+ ] }),
7870
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("p", { className: "mx-meet__panel-note", children: [
7871
+ poll.multiple ? "Pick any." : "Pick one.",
7872
+ poll.anonymous ? " Anonymous." : "",
7873
+ counts && poll.voterCount !== null ? ` ${poll.voterCount} voted.` : "",
7874
+ isHost && poll.state !== "draft" && !poll.resultsShared ? " Results are visible only to hosts." : ""
7875
+ ] }),
7876
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("ul", { className: "mx-meet__poll-options", children: poll.options.map((option) => {
7877
+ const share = counts && total > 0 ? Math.round((option.votes ?? 0) / total * 100) : 0;
7878
+ const chosen = picked.includes(option.id);
7879
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("li", { children: [
7880
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
7881
+ "button",
7882
+ {
7883
+ type: "button",
7884
+ className: chosen ? "mx-meet__poll-option mx-meet__poll-option--chosen" : "mx-meet__poll-option",
7885
+ "aria-pressed": chosen,
7886
+ disabled: !canVote,
7887
+ onClick: () => toggle(option.id),
7888
+ children: [
7889
+ counts ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "mx-meet__poll-bar", style: { width: `${share}%` }, "aria-hidden": "true" }) : null,
7890
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "mx-meet__poll-text", children: option.text }),
7891
+ counts ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("span", { className: "mx-meet__poll-count", children: [
7892
+ option.votes ?? 0,
7893
+ " \xB7 ",
7894
+ share,
7895
+ "%"
7896
+ ] }) : null
7897
+ ]
7898
+ }
7899
+ ),
7900
+ option.voters !== void 0 && option.voters.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "mx-meet__poll-voters", children: option.voters.join(", ") }) : null
7901
+ ] }, option.id);
7902
+ }) }),
7903
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Notice, { notice }),
7904
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "mx-meet__collab-actions", children: [
7905
+ canVote ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
7906
+ "button",
7907
+ {
7908
+ type: "button",
7909
+ className: "mx-meet__primary mx-meet__primary--small",
7910
+ disabled: picked.length === 0 || voted && picked.join() === poll.myVote.join(),
7911
+ onClick: () => void act({ action: "poll_vote", itemId: poll.id, optionIds: picked }).then(show),
7912
+ children: voted ? "Change vote" : "Vote"
7913
+ }
7914
+ ) : null,
7915
+ isHost && poll.state === "draft" ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("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,
7916
+ isHost && poll.state === "live" ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("button", { type: "button", className: "mx-meet__chip", onClick: () => void act({ action: "poll_close", itemId: poll.id }).then(show), children: "End poll" }) : null,
7917
+ isHost && poll.state !== "draft" ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("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,
7918
+ isHost && poll.state === "live" ? null : isHost ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("button", { type: "button", className: "mx-meet__link", onClick: () => void act({ action: "poll_delete", itemId: poll.id }).then(show), children: "Delete" }) : null
7919
+ ] })
7920
+ ] });
7921
+ }
7922
+ function PollsPanel({ onClose }) {
7923
+ const { collab, isHost } = useCollab();
7924
+ const [composing, setComposing] = (0, import_react4.useState)(false);
7925
+ const polls = collab?.polls ?? [];
7926
+ const maxOptions = collab?.settings?.pollMaxOptions ?? 10;
7927
+ const ordered = [...polls].reverse();
7928
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(PanelShell, { title: "Polls", onClose, children: [
7929
+ collab?.error != null ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "mx-meet__panel-note mx-meet__collab-error", children: collab.error }) : null,
7930
+ isHost && !composing ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("button", { type: "button", className: "mx-meet__primary mx-meet__primary--small", onClick: () => setComposing(true), children: "New poll" }) : null,
7931
+ isHost && composing ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(PollComposer, { maxOptions, onDone: () => setComposing(false) }) : null,
7932
+ ordered.length === 0 && !composing ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "mx-meet__panel-note", children: isHost ? "No polls yet. Polls and their results are kept with the meeting." : "No polls yet." }) : null,
7933
+ ordered.map((poll) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(PollCard, { poll }, poll.id))
7934
+ ] });
7935
+ }
7936
+ function QuestionCard({ question }) {
7937
+ const { act, isHost } = useCollab();
7938
+ const [answering, setAnswering] = (0, import_react4.useState)(false);
7939
+ const [reply, setReply] = (0, import_react4.useState)("");
7940
+ const [notice, show] = useNotice();
7941
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("li", { className: `mx-meet__collab-card mx-meet__question mx-meet__question--${question.state}`, children: [
7942
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "mx-meet__question-row", children: [
7943
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
7944
+ "button",
7945
+ {
7946
+ type: "button",
7947
+ className: question.upvotedByMe ? "mx-meet__upvote mx-meet__upvote--on" : "mx-meet__upvote",
7948
+ "aria-pressed": question.upvotedByMe,
7949
+ "aria-label": question.upvotedByMe ? "Remove your upvote" : "Upvote",
7950
+ disabled: question.state === "dismissed",
7951
+ onClick: () => void act({ action: "question_upvote", itemId: question.id }).then((r) => r.ok ? void 0 : show(r)),
7952
+ children: [
7953
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(UpvoteIcon, { width: 16, height: 16 }),
7954
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { children: question.upvotes })
7955
+ ]
7956
+ }
7957
+ ),
7958
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "mx-meet__question-body", children: [
7959
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("span", { className: "mx-meet__chat-meta", children: [
7960
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("strong", { children: question.mine ? "You" : question.askerName }),
7961
+ question.mine && question.anonymous ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "mx-meet__chat-private", children: "anonymous" }) : null,
7962
+ question.state !== "open" ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "mx-meet__collab-state", children: question.state === "answered" ? "Answered" : "Dismissed" }) : null
7963
+ ] }),
7964
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "mx-meet__chat-text", children: question.text }),
7965
+ question.answer !== null ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("span", { className: "mx-meet__question-answer", children: [
7966
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("strong", { children: [
7967
+ question.answeredByName ?? "Host",
7968
+ ":"
7969
+ ] }),
7970
+ " ",
7971
+ question.answer
7972
+ ] }) : null
7973
+ ] })
7974
+ ] }),
7975
+ answering ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
7976
+ "form",
7977
+ {
7978
+ className: "mx-meet__composer-row",
7979
+ onSubmit: (event) => {
7980
+ event.preventDefault();
7981
+ void act({ action: "question_answer", itemId: question.id, text: reply }).then((r) => {
7982
+ show(r);
7983
+ if (r.ok) {
7984
+ setAnswering(false);
7985
+ setReply("");
7986
+ }
7987
+ });
7988
+ },
7989
+ children: [
7990
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
7991
+ "input",
7992
+ {
7993
+ className: "mx-meet__input",
7994
+ value: reply,
7995
+ maxLength: 2e3,
7996
+ onChange: (event) => setReply(event.target.value),
7997
+ placeholder: "Type an answer, or leave empty if you answered out loud",
7998
+ "aria-label": "Answer",
7999
+ autoFocus: true
8000
+ }
8001
+ ),
8002
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("button", { type: "submit", className: "mx-meet__send", children: "Done" })
8003
+ ]
8004
+ }
8005
+ ) : null,
8006
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Notice, { notice }),
8007
+ isHost || question.mine ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "mx-meet__collab-actions", children: [
8008
+ isHost && question.state === "open" && !answering ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("button", { type: "button", className: "mx-meet__chip", onClick: () => setAnswering(true), children: "Answer" }) : null,
8009
+ isHost && question.state === "open" ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("button", { type: "button", className: "mx-meet__chip", onClick: () => void act({ action: "question_dismiss", itemId: question.id }).then(show), children: "Dismiss" }) : null,
8010
+ isHost && question.state !== "open" ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("button", { type: "button", className: "mx-meet__chip", onClick: () => void act({ action: "question_reopen", itemId: question.id }).then(show), children: "Reopen" }) : null,
8011
+ question.mine || isHost ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("button", { type: "button", className: "mx-meet__link", onClick: () => void act({ action: "question_delete", itemId: question.id }).then(show), children: "Delete" }) : null
8012
+ ] }) : null
8013
+ ] });
8014
+ }
8015
+ function QaPanel({ onClose }) {
8016
+ const { collab, act } = useCollab();
8017
+ const [draft, setDraft] = (0, import_react4.useState)("");
8018
+ const [anonymous, setAnonymous] = (0, import_react4.useState)(false);
8019
+ const [order, setOrder] = (0, import_react4.useState)("popular");
8020
+ const [notice, show] = useNotice();
8021
+ const allowAnonymous = collab?.settings?.qaAnonymousAllowed === true;
8022
+ const questions = [...collab?.questions ?? []];
8023
+ const rank = (q) => q.state === "open" ? 0 : q.state === "answered" ? 1 : 2;
8024
+ questions.sort(
8025
+ (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 ?? "")
8026
+ );
8027
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(PanelShell, { title: "Q&A", onClose, children: [
8028
+ collab?.error != null ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "mx-meet__panel-note mx-meet__collab-error", children: collab.error }) : null,
8029
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
8030
+ "form",
8031
+ {
8032
+ className: "mx-meet__composer mx-meet__composer--chat",
8033
+ onSubmit: (event) => {
8034
+ event.preventDefault();
8035
+ const text3 = draft.trim();
8036
+ if (text3.length === 0) return;
8037
+ void act({ action: "question_ask", text: text3, anonymous: allowAnonymous && anonymous }).then((r) => {
8038
+ if (r.ok) setDraft("");
8039
+ else show(r);
8040
+ });
8041
+ },
8042
+ children: [
8043
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "mx-meet__composer-row", children: [
8044
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
8045
+ "input",
8046
+ {
8047
+ className: "mx-meet__input",
8048
+ value: draft,
8049
+ maxLength: 1e3,
8050
+ onChange: (event) => setDraft(event.target.value),
8051
+ placeholder: "Ask the host a question",
8052
+ "aria-label": "Ask the host a question"
8053
+ }
8054
+ ),
8055
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("button", { type: "submit", className: "mx-meet__send", disabled: draft.trim().length === 0, children: "Ask" })
8056
+ ] }),
8057
+ allowAnonymous ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("label", { className: "mx-meet__toggle", children: [
8058
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("input", { type: "checkbox", checked: anonymous, onChange: (event) => setAnonymous(event.target.checked) }),
8059
+ "Ask anonymously"
8060
+ ] }) : null
8061
+ ]
8062
+ }
8063
+ ),
8064
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Notice, { notice }),
8065
+ questions.length > 1 ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "mx-meet__pills", role: "group", "aria-label": "Order questions", children: ["popular", "recent"].map((value) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
8066
+ "button",
8067
+ {
8068
+ type: "button",
8069
+ className: order === value ? "mx-meet__pill mx-meet__pill--on" : "mx-meet__pill",
8070
+ "aria-pressed": order === value,
8071
+ onClick: () => setOrder(value),
8072
+ children: value === "popular" ? "Popular" : "Recent"
8073
+ },
8074
+ value
8075
+ )) }) : null,
8076
+ questions.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "mx-meet__panel-note", children: "No questions yet. Questions are kept with the meeting." }) : /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("ul", { className: "mx-meet__chat", children: questions.map((question) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(QuestionCard, { question }, question.id)) })
8077
+ ] });
8078
+ }
8079
+ var BOARD_W = 1600;
8080
+ var BOARD_H = 1e3;
8081
+ var INK = ["#111827", "#dc2626", "#2563eb", "#16a34a", "#f59e0b", "#7c3aed"];
8082
+ function strokePath(points) {
8083
+ if (points.length === 0) return "";
8084
+ const [first, ...rest] = points;
8085
+ const move = `M${(first[0] * BOARD_W).toFixed(1)} ${(first[1] * BOARD_H).toFixed(1)}`;
8086
+ if (rest.length === 0) return `${move} l0.1 0`;
8087
+ return `${move} ${rest.map(([x, y]) => `L${(x * BOARD_W).toFixed(1)} ${(y * BOARD_H).toFixed(1)}`).join(" ")}`;
8088
+ }
8089
+ function StrokeView({ stroke, onPick }) {
8090
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
8091
+ "path",
8092
+ {
8093
+ d: strokePath(stroke.points),
8094
+ fill: "none",
8095
+ stroke: stroke.color,
8096
+ strokeWidth: stroke.tool === "highlighter" ? stroke.width * 4 : stroke.width,
8097
+ strokeOpacity: stroke.tool === "highlighter" ? 0.35 : stroke.pending === true ? 0.6 : 1,
8098
+ strokeLinecap: "round",
8099
+ strokeLinejoin: "round",
8100
+ onPointerDown: onPick,
8101
+ style: onPick !== void 0 ? { cursor: "pointer" } : void 0,
8102
+ children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("title", { children: stroke.byName })
8103
+ }
8104
+ );
8105
+ }
8106
+ function WhiteboardPanel({ onClose }) {
8107
+ const { collab, act, isHost, localIdentity } = useCollab();
8108
+ const [tool, setTool] = (0, import_react4.useState)("pen");
8109
+ const [color, setColor] = (0, import_react4.useState)(INK[0]);
8110
+ const [drawing, setDrawing] = (0, import_react4.useState)(null);
8111
+ const [pending, setPending] = (0, import_react4.useState)([]);
8112
+ const [notice, show] = useNotice();
8113
+ const svgRef = (0, import_react4.useRef)(null);
8114
+ const strokes = collab?.strokes ?? [];
8115
+ const mine = strokes.filter((s) => s.by === localIdentity);
8116
+ const point = (event) => {
8117
+ const svg = svgRef.current;
8118
+ if (svg === null) return null;
8119
+ const rect = svg.getBoundingClientRect();
8120
+ const scale = Math.min(rect.width / BOARD_W, rect.height / BOARD_H);
8121
+ const offsetX = (rect.width - BOARD_W * scale) / 2;
8122
+ const offsetY = (rect.height - BOARD_H * scale) / 2;
8123
+ const x = (event.clientX - rect.left - offsetX) / (BOARD_W * scale);
8124
+ const y = (event.clientY - rect.top - offsetY) / (BOARD_H * scale);
8125
+ return [Math.min(1, Math.max(0, x)), Math.min(1, Math.max(0, y))];
8126
+ };
8127
+ const finish = () => {
8128
+ const points = drawing;
8129
+ setDrawing(null);
8130
+ if (points === null || points.length === 0 || tool === "eraser") return;
8131
+ const thinned = points.filter((p, i) => i === 0 || i === points.length - 1 || i % 2 === 0).slice(0, 2e3);
8132
+ const stroke = {
8133
+ points: thinned.map(([x, y]) => [Number(x.toFixed(4)), Number(y.toFixed(4))]),
8134
+ color,
8135
+ width: tool === "highlighter" ? 4 : 3,
8136
+ tool: tool === "highlighter" ? "highlighter" : "pen"
8137
+ };
8138
+ const localId = `pending-${Date.now()}`;
8139
+ setPending((list) => [...list, { id: localId, ...stroke, by: localIdentity ?? "", byName: "You", pending: true }]);
8140
+ void act({ action: "stroke_add", stroke }).then((result) => {
8141
+ setPending((list) => list.filter((s) => s.id !== localId));
8142
+ if (!result.ok) show(result);
8143
+ });
8144
+ };
8145
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("section", { className: "mx-meet__whiteboard", "aria-label": "Whiteboard", children: [
8146
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("header", { className: "mx-meet__whiteboard-bar", children: [
8147
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("strong", { className: "mx-meet__panel-title", children: "Whiteboard" }),
8148
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "mx-meet__pills", role: "group", "aria-label": "Tool", children: [
8149
+ ["pen", "Pen", /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(PencilIcon, { width: 16, height: 16 }, "p")],
8150
+ ["highlighter", "Highlighter", /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(HighlighterIcon, { width: 16, height: 16 }, "h")],
8151
+ ["eraser", "Eraser \u2014 click a stroke", /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(EraserIcon, { width: 16, height: 16 }, "e")]
8152
+ ].map(([value, label, icon]) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
8153
+ "button",
8154
+ {
8155
+ type: "button",
8156
+ className: tool === value ? "mx-meet__pill mx-meet__pill--on" : "mx-meet__pill",
8157
+ "aria-pressed": tool === value,
8158
+ "aria-label": label,
8159
+ title: label,
8160
+ onClick: () => setTool(value),
8161
+ children: icon
8162
+ },
8163
+ value
8164
+ )) }),
8165
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "mx-meet__swatches", role: "group", "aria-label": "Color", children: INK.map((ink) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
8166
+ "button",
8167
+ {
8168
+ type: "button",
8169
+ className: ink === color ? "mx-meet__swatch mx-meet__swatch--on" : "mx-meet__swatch",
8170
+ style: { background: ink },
8171
+ "aria-label": `Color ${ink}`,
8172
+ "aria-pressed": ink === color,
8173
+ onClick: () => {
8174
+ setColor(ink);
8175
+ if (tool === "eraser") setTool("pen");
8176
+ }
8177
+ },
8178
+ ink
8179
+ )) }),
8180
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
8181
+ ControlButton,
8182
+ {
8183
+ label: "Undo my last stroke",
8184
+ onClick: () => {
8185
+ const last = mine[mine.length - 1];
8186
+ if (last !== void 0) void act({ action: "stroke_erase", itemId: last.id }).then((r) => r.ok ? void 0 : show(r));
8187
+ },
8188
+ children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(UndoIcon, { width: 16, height: 16 })
8189
+ }
8190
+ ),
8191
+ isHost && strokes.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("button", { type: "button", className: "mx-meet__chip", onClick: () => void act({ action: "whiteboard_clear" }).then(show), children: "Clear board" }) : null,
8192
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "mx-meet__whiteboard-note", children: "Saved with the meeting" }),
8193
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(ControlButton, { label: "Close whiteboard", onClick: onClose, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(CloseIcon, { width: 16, height: 16 }) })
8194
+ ] }),
8195
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Notice, { notice }),
8196
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
8197
+ "svg",
8198
+ {
8199
+ ref: svgRef,
8200
+ className: tool === "eraser" ? "mx-meet__board mx-meet__board--erase" : "mx-meet__board",
8201
+ viewBox: `0 0 ${BOARD_W} ${BOARD_H}`,
8202
+ preserveAspectRatio: "xMidYMid meet",
8203
+ role: "img",
8204
+ "aria-label": `Shared whiteboard, ${strokes.length} strokes`,
8205
+ onPointerDown: (event) => {
8206
+ if (tool === "eraser") return;
8207
+ const p = point(event);
8208
+ if (p === null) return;
8209
+ event.target.setPointerCapture?.(event.pointerId);
8210
+ setDrawing([p]);
8211
+ },
8212
+ onPointerMove: (event) => {
8213
+ if (drawing === null) return;
8214
+ const p = point(event);
8215
+ if (p !== null) setDrawing([...drawing, p]);
8216
+ },
8217
+ onPointerUp: finish,
8218
+ onPointerCancel: finish,
8219
+ children: [
8220
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("rect", { x: 0, y: 0, width: BOARD_W, height: BOARD_H, className: "mx-meet__board-paper" }),
8221
+ strokes.map((stroke) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
8222
+ StrokeView,
8223
+ {
8224
+ stroke,
8225
+ 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
8226
+ },
8227
+ stroke.id
8228
+ )),
8229
+ pending.map((stroke) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(StrokeView, { stroke }, stroke.id)),
8230
+ drawing !== null ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
8231
+ StrokeView,
8232
+ {
8233
+ stroke: {
8234
+ id: "drawing",
8235
+ points: drawing,
8236
+ color,
8237
+ width: tool === "highlighter" ? 4 : 3,
8238
+ tool: tool === "highlighter" ? "highlighter" : "pen",
8239
+ by: "",
8240
+ byName: "You"
8241
+ }
8242
+ }
8243
+ ) : null
8244
+ ]
8245
+ }
8246
+ )
8247
+ ] });
8248
+ }
8249
+ function clock(ms2) {
8250
+ const total = Math.ceil(ms2 / 1e3);
8251
+ const minutes = Math.floor(total / 60);
8252
+ const seconds = total % 60;
8253
+ return `${minutes}:${seconds.toString().padStart(2, "0")}`;
8254
+ }
8255
+ function useNow(active) {
8256
+ const [now, setNow] = (0, import_react4.useState)(() => Date.now());
8257
+ (0, import_react4.useEffect)(() => {
8258
+ if (!active) return void 0;
8259
+ const timer = setInterval(() => setNow(Date.now()), 1e3);
8260
+ return () => clearInterval(timer);
8261
+ }, [active]);
8262
+ return now;
8263
+ }
8264
+ function BreakoutSetup() {
8265
+ const { collab, act } = useCollab();
8266
+ const snapshot = useMeetSnapshot();
8267
+ const settings = collab?.settings ?? null;
8268
+ const people = (snapshot?.participants ?? []).filter(
8269
+ (p) => !p.isAgent && p.role !== "host" && p.role !== "cohost"
8270
+ );
8271
+ const [count2, setCount] = (0, import_react4.useState)(Math.min(Math.max(2, Math.ceil(people.length / 4)), settings?.breakoutMaxRooms ?? 20));
8272
+ const [mode, setMode] = (0, import_react4.useState)("auto");
8273
+ const [minutes, setMinutes] = (0, import_react4.useState)(settings?.breakoutDefaultMinutes ?? 15);
8274
+ const [manual, setManual] = (0, import_react4.useState)({});
8275
+ const [busy, setBusy] = (0, import_react4.useState)(false);
8276
+ const [notice, show] = useNotice();
8277
+ const max = settings?.breakoutMaxRooms ?? 20;
8278
+ const rooms = Math.min(Math.max(1, count2), max);
8279
+ const assignment = mode === "auto" ? autoAssign(
8280
+ people.map((p) => p.identity),
8281
+ rooms
8282
+ ) : mode === "manual" ? Array.from(
8283
+ { length: rooms },
8284
+ (_, index) => people.filter((p) => (manual[p.identity] ?? -1) === index).map((p) => p.identity)
8285
+ ) : Array.from({ length: rooms }, () => []);
8286
+ const nameOf = (identity) => people.find((p) => p.identity === identity)?.displayName ?? identity;
8287
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "mx-meet__collab-card", children: [
8288
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("label", { className: "mx-meet__field", children: [
8289
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "mx-meet__field-label", children: "Rooms" }),
8290
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
8291
+ "input",
8292
+ {
8293
+ className: "mx-meet__input",
8294
+ type: "number",
8295
+ min: 1,
8296
+ max,
8297
+ value: count2,
8298
+ onChange: (event) => setCount(Number(event.target.value) || 1)
8299
+ }
8300
+ )
8301
+ ] }),
8302
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "mx-meet__pills", role: "group", "aria-label": "How people are placed", children: [
8303
+ ["auto", "Automatically"],
8304
+ ["manual", "Manually"],
8305
+ ["choose", "Let people choose"]
8306
+ ].map(([value, label]) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
8307
+ "button",
8308
+ {
8309
+ type: "button",
8310
+ className: mode === value ? "mx-meet__pill mx-meet__pill--on" : "mx-meet__pill",
8311
+ "aria-pressed": mode === value,
8312
+ onClick: () => setMode(value),
8313
+ children: label
8314
+ },
8315
+ value
8316
+ )) }),
8317
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("label", { className: "mx-meet__field", children: [
8318
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "mx-meet__field-label", children: "Timer (minutes, 0 for none)" }),
8319
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
8320
+ "input",
8321
+ {
8322
+ className: "mx-meet__input",
8323
+ type: "number",
8324
+ min: 0,
8325
+ max: 720,
8326
+ value: minutes,
8327
+ onChange: (event) => setMinutes(Math.max(0, Number(event.target.value) || 0))
8328
+ }
8329
+ )
8330
+ ] }),
8331
+ mode === "manual" ? people.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "mx-meet__panel-note", children: "Nobody else is in the meeting yet." }) : /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("ul", { className: "mx-meet__people", children: people.map((person) => /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("li", { className: "mx-meet__person", children: [
8332
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "mx-meet__person-name", children: person.displayName }),
8333
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
8334
+ "select",
8335
+ {
8336
+ className: "mx-meet__select mx-meet__select--compact",
8337
+ "aria-label": `Room for ${person.displayName}`,
8338
+ value: manual[person.identity] ?? -1,
8339
+ onChange: (event) => setManual({ ...manual, [person.identity]: Number(event.target.value) }),
8340
+ children: [
8341
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("option", { value: -1, children: "Main room" }),
8342
+ Array.from({ length: rooms }, (_, index) => /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("option", { value: index, children: [
8343
+ "Room ",
8344
+ index + 1
8345
+ ] }, index))
8346
+ ]
8347
+ }
8348
+ )
8349
+ ] }, person.identity)) }) : mode === "auto" ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("ul", { className: "mx-meet__breakout-rooms", children: assignment.map((members, index) => /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("li", { children: [
8350
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("strong", { children: [
8351
+ "Room ",
8352
+ index + 1
8353
+ ] }),
8354
+ " ",
8355
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "mx-meet__panel-note", children: members.length === 0 ? "empty" : members.map(nameOf).join(", ") })
8356
+ ] }, index)) }) : /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "mx-meet__panel-note", children: "Everyone picks a room from their own screen." }),
8357
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Notice, { notice }),
8358
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
8359
+ "button",
8360
+ {
8361
+ type: "button",
8362
+ className: "mx-meet__primary mx-meet__primary--small",
8363
+ disabled: busy,
8364
+ onClick: () => {
8365
+ setBusy(true);
8366
+ void act({
8367
+ action: "breakout_open",
8368
+ rooms: assignment.map((identities, index) => ({ name: `Room ${index + 1}`, identities })),
8369
+ allowChoose: mode === "choose",
8370
+ minutes
8371
+ }).then((result) => {
8372
+ setBusy(false);
8373
+ show(result);
8374
+ });
8375
+ },
8376
+ children: [
8377
+ "Open ",
8378
+ rooms,
8379
+ " room",
8380
+ rooms === 1 ? "" : "s"
8381
+ ]
8382
+ }
8383
+ )
8384
+ ] });
8385
+ }
8386
+ function BreakoutRun({ plan }) {
8387
+ const { act, moveTo, isHost, breakoutRoomId, localIdentity } = useCollab();
8388
+ const snapshot = useMeetSnapshot();
8389
+ const now = useNow(plan.endsAt !== null);
8390
+ const remaining = breakoutRemainingMs(plan, now);
8391
+ const [broadcast, setBroadcast] = (0, import_react4.useState)("");
8392
+ const [notice, show] = useNotice();
8393
+ const nameOf = (identity) => displayNameFor(snapshot?.names ?? {}, identity, snapshot?.participants.find((p) => p.identity === identity)?.displayName);
8394
+ const mine = assignedRoom(plan, localIdentity);
8395
+ const join = async (roomId) => {
8396
+ const said = await act({ action: "breakout_join", roomId });
8397
+ if (!said.ok) {
8398
+ show(said);
8399
+ return;
8400
+ }
8401
+ show(await moveTo(roomId));
8402
+ };
8403
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "mx-meet__collab-card", children: [
8404
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("p", { className: "mx-meet__panel-note", children: [
8405
+ plan.rooms.length,
8406
+ " room",
8407
+ plan.rooms.length === 1 ? "" : "s",
8408
+ " open",
8409
+ remaining !== null ? ` \xB7 ${clock(remaining)} left` : "",
8410
+ plan.allowChoose ? " \xB7 people choose their room" : ""
8411
+ ] }),
8412
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("ul", { className: "mx-meet__breakout-rooms", children: plan.rooms.map((room) => {
8413
+ const here = breakoutRoomId === room.id;
8414
+ const mayJoin = isHost || plan.allowChoose || mine?.id === room.id;
8415
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("li", { className: here ? "mx-meet__breakout-room mx-meet__breakout-room--here" : "mx-meet__breakout-room", children: [
8416
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "mx-meet__collab-head", children: [
8417
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("strong", { children: room.name }),
8418
+ here ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "mx-meet__collab-state", children: "You are here" }) : mayJoin ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("button", { type: "button", className: "mx-meet__chip", onClick: () => void join(room.id), children: "Join" }) : null
8419
+ ] }),
8420
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "mx-meet__panel-note", children: room.identities.length === 0 ? "Nobody assigned" : room.identities.map(nameOf).join(", ") }),
8421
+ isHost && room.identities.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("ul", { className: "mx-meet__people", children: room.identities.map((identity) => /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("li", { className: "mx-meet__person", children: [
8422
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "mx-meet__person-name", children: nameOf(identity) }),
8423
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
8424
+ "select",
8425
+ {
8426
+ className: "mx-meet__select mx-meet__select--compact",
8427
+ "aria-label": `Move ${nameOf(identity)}`,
8428
+ value: room.id,
8429
+ onChange: (event) => void act({
8430
+ action: "breakout_move",
8431
+ identity,
8432
+ roomId: event.target.value === "" ? null : event.target.value
8433
+ }).then(show),
8434
+ children: [
8435
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("option", { value: "", children: "Main room" }),
8436
+ plan.rooms.map((option) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("option", { value: option.id, children: option.name }, option.id))
8437
+ ]
8438
+ }
8439
+ )
8440
+ ] }, identity)) }) : null
8441
+ ] }, room.id);
8442
+ }) }),
8443
+ breakoutRoomId !== null ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("button", { type: "button", className: "mx-meet__chip", onClick: () => void join(null), children: "Return to the main room" }) : null,
8444
+ isHost ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
8445
+ "form",
8446
+ {
8447
+ className: "mx-meet__composer-row",
8448
+ onSubmit: (event) => {
8449
+ event.preventDefault();
8450
+ const text3 = broadcast.trim();
8451
+ if (text3.length === 0) return;
8452
+ void act({ action: "breakout_broadcast", text: text3 }).then((result) => {
8453
+ show(result);
8454
+ if (result.ok) setBroadcast("");
8455
+ });
8456
+ },
8457
+ children: [
8458
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
8459
+ "input",
8460
+ {
8461
+ className: "mx-meet__input",
8462
+ value: broadcast,
8463
+ maxLength: 500,
8464
+ onChange: (event) => setBroadcast(event.target.value),
8465
+ placeholder: "Message every room",
8466
+ "aria-label": "Message every room"
8467
+ }
8468
+ ),
8469
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("button", { type: "submit", className: "mx-meet__send", disabled: broadcast.trim().length === 0, children: "Send" })
8470
+ ]
8471
+ }
8472
+ ) : null,
8473
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Notice, { notice }),
8474
+ isHost ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
8475
+ "button",
8476
+ {
8477
+ type: "button",
8478
+ className: "mx-meet__primary mx-meet__primary--small",
8479
+ onClick: () => void act({ action: "breakout_close" }).then(show),
8480
+ children: "Bring everyone back"
8481
+ }
8482
+ ) : null
8483
+ ] });
8484
+ }
8485
+ function BreakoutsPanel({ onClose }) {
8486
+ const { collab, isHost } = useCollab();
8487
+ const plan = collab?.breakout?.state === "open" ? collab.breakout : null;
8488
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(PanelShell, { title: "Breakout rooms", onClose, children: [
8489
+ collab?.error != null ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "mx-meet__panel-note mx-meet__collab-error", children: collab.error }) : null,
8490
+ plan !== null ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(BreakoutRun, { plan }) : isHost ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(BreakoutSetup, {}) : /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "mx-meet__panel-note", children: "Breakout rooms are closed." })
8491
+ ] });
8492
+ }
8493
+ function BreakoutBanner() {
8494
+ const host = useMeetHost();
8495
+ const { collab, act, moveTo, localIdentity, breakoutRoomId } = useCollab();
8496
+ const plan = collab?.breakout ?? null;
8497
+ const open = plan?.state === "open" ? plan : null;
8498
+ const now = useNow(open?.endsAt != null);
8499
+ const remaining = breakoutRemainingMs(open, now);
8500
+ const assigned = assignedRoom(open, localIdentity);
8501
+ const [dismissedBroadcast, setDismissedBroadcast] = (0, import_react4.useState)(null);
8502
+ const [failure, setFailure] = (0, import_react4.useState)(null);
8503
+ const expireAsked = (0, import_react4.useRef)(null);
8504
+ const moveAt = collab?.moveRequest?.at ?? null;
8505
+ (0, import_react4.useEffect)(() => {
8506
+ const request = host?.store.snapshot().collab.moveRequest ?? null;
8507
+ if (request === null || host === null) return;
8508
+ host.store.patch({ collab: { ...host.store.snapshot().collab, moveRequest: null } });
8509
+ const here = host.store.snapshot().breakoutRoomId;
8510
+ if ((here ?? null) === request.roomId) return;
8511
+ void moveTo(request.roomId).then((result) => setFailure(result.ok ? null : result.message));
8512
+ }, [moveAt, host, moveTo]);
8513
+ (0, import_react4.useEffect)(() => {
8514
+ if (open === null || remaining === null || remaining > 0) return;
8515
+ if (expireAsked.current === open.id) return;
8516
+ expireAsked.current = open.id;
8517
+ void act({ action: "breakout_expire" });
8518
+ }, [open, remaining, act]);
8519
+ const broadcast = collab?.broadcast ?? null;
8520
+ const showBroadcast = broadcast !== null && broadcast.at !== dismissedBroadcast && open !== null;
8521
+ const room = open?.rooms.find((r) => r.id === breakoutRoomId) ?? null;
8522
+ if (open === null && failure === null) return null;
8523
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "mx-meet__breakout-banner", role: "status", children: [
8524
+ failure !== null ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "mx-meet__collab-error", children: failure }) : null,
8525
+ room !== null ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("span", { children: [
8526
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("strong", { children: room.name }),
8527
+ remaining !== null ? ` \xB7 ${clock(remaining)} left` : "",
8528
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("button", { type: "button", className: "mx-meet__chip", onClick: () => void moveTo(null), children: "Return to main room" })
8529
+ ] }) : assigned !== null ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("span", { children: [
8530
+ "You are assigned to ",
8531
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("strong", { children: assigned.name }),
8532
+ remaining !== null ? ` \xB7 ${clock(remaining)} left` : "",
8533
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
8534
+ "button",
8535
+ {
8536
+ type: "button",
8537
+ className: "mx-meet__primary mx-meet__primary--small",
8538
+ onClick: () => void act({ action: "breakout_join", roomId: assigned.id }).then(async (said) => {
8539
+ const result = said.ok ? await moveTo(assigned.id) : said;
8540
+ setFailure(result.ok ? null : result.message);
8541
+ }),
8542
+ children: "Join"
8543
+ }
8544
+ )
8545
+ ] }) : open?.allowChoose ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { children: "Breakout rooms are open \u2014 pick one under Activities." }) : null,
8546
+ showBroadcast ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("span", { className: "mx-meet__breakout-broadcast", children: [
8547
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("strong", { children: [
8548
+ broadcast.by,
8549
+ ":"
8550
+ ] }),
8551
+ " ",
8552
+ broadcast.text,
8553
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("button", { type: "button", className: "mx-meet__link", onClick: () => setDismissedBroadcast(broadcast.at), children: "Dismiss" })
8554
+ ] }) : null
8555
+ ] });
8556
+ }
8557
+ function useCaptionTranslation(lines) {
8558
+ const host = useMeetHost();
8559
+ const snapshot = useMeetSnapshot();
8560
+ const collab = snapshot?.collab ?? null;
8561
+ const language = collab?.captionLanguage ?? null;
8562
+ const asked = (0, import_react4.useRef)(/* @__PURE__ */ new Set());
8563
+ const translations = collab?.captionTranslations ?? {};
8564
+ const missing = lines.filter((line) => line.final && translations[line.id] === void 0).map(({ id, text: text3 }) => ({ id, text: text3 }));
8565
+ const key = `${language ?? ""}|${missing.map((l) => l.id).join(",")}`;
8566
+ const pending = (0, import_react4.useRef)(missing);
8567
+ pending.current = missing;
8568
+ (0, import_react4.useEffect)(() => {
8569
+ if (host === null || language === null) return;
8570
+ const batch = pending.current.filter((line) => !asked.current.has(`${language}:${line.id}`)).slice(-20);
8571
+ if (batch.length === 0) return;
8572
+ for (const line of batch) asked.current.add(`${language}:${line.id}`);
8573
+ void host.inRoom.translateCaptions(language, batch).catch(() => void 0);
8574
+ }, [host, language, key]);
8575
+ return { language, translations, error: collab?.captionTranslationError ?? null };
8576
+ }
8577
+ function CaptionLanguageSettings() {
8578
+ const host = useMeetHost();
8579
+ const snapshot = useMeetSnapshot();
8580
+ const collab = snapshot?.collab ?? null;
8581
+ const settings = collab?.settings ?? null;
8582
+ if (host === null || settings === null || !settings.captionTranslationEnabled) return null;
8583
+ const viewer = typeof navigator !== "undefined" && typeof navigator.language === "string" ? navigator.language.slice(0, 2) : null;
8584
+ const preferred = defaultCaptionLanguage(settings, viewer);
8585
+ const current = collab?.captionLanguage ?? "";
8586
+ const choices = CAPTION_LANGUAGES.some((l) => l.tag === preferred) ? CAPTION_LANGUAGES : [{ tag: preferred, name: preferred }, ...CAPTION_LANGUAGES];
8587
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("section", { className: "mx-meet__section", "aria-label": "Captions", children: [
8588
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("label", { className: "mx-meet__field", children: [
8589
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "mx-meet__field-label", children: "Translate captions to" }),
8590
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
8591
+ "select",
8592
+ {
8593
+ className: "mx-meet__select",
8594
+ value: current,
8595
+ onChange: (event) => {
8596
+ const next = event.target.value === "" ? null : event.target.value;
8597
+ host.store.patch({
8598
+ collab: {
8599
+ ...host.store.snapshot().collab,
8600
+ captionLanguage: next,
8601
+ captionTranslations: {},
8602
+ captionTranslationError: null
8603
+ }
8604
+ });
8605
+ },
8606
+ children: [
8607
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("option", { value: "", children: "Off \u2014 as spoken" }),
8608
+ current === "" ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("option", { value: preferred, children: [
8609
+ choices.find((c) => c.tag === preferred)?.name ?? preferred,
8610
+ " (yours)"
8611
+ ] }) : null,
8612
+ choices.filter((choice) => current !== "" || choice.tag !== preferred).map((choice) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("option", { value: choice.tag, children: choice.name }, choice.tag))
8613
+ ]
8614
+ }
8615
+ )
8616
+ ] }),
8617
+ collab?.captionTranslationError != null ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "mx-meet__panel-note mx-meet__collab-error", children: collab.captionTranslationError }) : null
8618
+ ] });
8619
+ }
8620
+ function useCollabPanelRequest(onRequest) {
8621
+ const host = useMeetHost();
8622
+ const at = useMeetSnapshot()?.collab.panelRequest?.at ?? null;
8623
+ const callback = (0, import_react4.useRef)(onRequest);
8624
+ callback.current = onRequest;
8625
+ (0, import_react4.useEffect)(() => {
8626
+ const request = host?.store.snapshot().collab.panelRequest ?? null;
8627
+ if (request === null || host === null) return;
8628
+ host.store.patch({ collab: { ...host.store.snapshot().collab, panelRequest: null } });
8629
+ callback.current(request.panel);
8630
+ }, [at, host]);
8631
+ }
8632
+
8633
+ // src/react/components.tsx
8634
+ var import_jsx_runtime4 = require("react/jsx-runtime");
8635
+ function InertNotice({ what }) {
8636
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "mx-meet__empty", role: "status", children: [
8637
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("p", { className: "mx-meet__empty-title", children: [
8638
+ what,
8639
+ " is not ready yet"
8640
+ ] }),
8641
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("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." })
8642
+ ] });
8643
+ }
8644
+ function Avatar({
8645
+ name,
8646
+ url,
8647
+ size = 40
8648
+ }) {
8649
+ const tint = (0, import_format3.avatarPaletteIndex)(name);
8650
+ if (url != null && url.length > 0) {
8651
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
8652
+ "img",
8653
+ {
8654
+ className: "mx-meet__avatar",
8655
+ src: url,
8656
+ alt: "",
8657
+ width: size,
8658
+ height: size,
8659
+ style: { width: size, height: size }
8660
+ }
8661
+ );
8662
+ }
8663
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
8664
+ "span",
8665
+ {
8666
+ className: "mx-meet__avatar mx-meet__avatar--initials",
8667
+ style: {
8668
+ width: size,
8669
+ height: size,
8670
+ fontSize: Math.round(size * 0.38),
8671
+ background: `var(--mx-meet-avatar-${tint})`
8672
+ },
8673
+ "aria-hidden": "true",
8674
+ children: (0, import_format3.getInitials)(name)
8675
+ }
8676
+ );
8677
+ }
8678
+ function ControlButton({
8679
+ label,
7018
8680
  active = false,
7019
8681
  danger = false,
7020
8682
  onClick,
7021
8683
  children
7022
8684
  }) {
7023
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
8685
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
7024
8686
  "button",
7025
8687
  {
7026
8688
  type: "button",
@@ -7039,14 +8701,14 @@ function ControlButton({
7039
8701
  function RecordingIndicator() {
7040
8702
  const { state, label } = useRecording();
7041
8703
  if (label === null) return null;
7042
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
8704
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
7043
8705
  "span",
7044
8706
  {
7045
8707
  className: `mx-meet__recording mx-meet__recording--${state}`,
7046
8708
  role: "status",
7047
8709
  "aria-live": "polite",
7048
8710
  children: [
7049
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(RecordIcon, { width: 10, height: 10 }),
8711
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(RecordIcon, { width: 10, height: 10 }),
7050
8712
  label
7051
8713
  ]
7052
8714
  }
@@ -7054,12 +8716,12 @@ function RecordingIndicator() {
7054
8716
  }
7055
8717
  function ConnectionDot({ quality }) {
7056
8718
  if (quality === "excellent" || quality === "good" || quality === "unknown") return null;
7057
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: `mx-meet__quality mx-meet__quality--${quality}`, title: `Connection ${quality}`, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(WifiLowIcon, { width: 14, height: 14 }) });
8719
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: `mx-meet__quality mx-meet__quality--${quality}`, title: `Connection ${quality}`, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(WifiLowIcon, { width: 14, height: 14 }) });
7058
8720
  }
7059
8721
  function RoleBadge({ role }) {
7060
- if (role === "host") return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "mx-meet__badge", children: "Host" });
7061
- if (role === "cohost") return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "mx-meet__badge", children: "Co-host" });
7062
- if (role === "guest") return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "mx-meet__badge", children: "Guest" });
8722
+ if (role === "host") return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "mx-meet__badge", children: "Host" });
8723
+ if (role === "cohost") return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "mx-meet__badge", children: "Co-host" });
8724
+ if (role === "guest") return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "mx-meet__badge", children: "Guest" });
7063
8725
  return null;
7064
8726
  }
7065
8727
  function ParticipantTile({
@@ -7069,7 +8731,7 @@ function ParticipantTile({
7069
8731
  const host = useMeetHost();
7070
8732
  const snapshot = useMeetSnapshot();
7071
8733
  const queue = useHandQueue();
7072
- const [menu, setMenu] = (0, import_react4.useState)(false);
8734
+ const [menu, setMenu] = (0, import_react5.useState)(false);
7073
8735
  const videoRef = useTrack(
7074
8736
  participant.identity,
7075
8737
  participant.screenSharing ? "screen" : "camera"
@@ -7078,7 +8740,7 @@ function ParticipantTile({
7078
8740
  const pinnedHere = snapshot?.pinned === participant.identity;
7079
8741
  const spotlit = snapshot?.spotlight === participant.identity;
7080
8742
  const handPosition = participant.handRaised ? queue.findIndex((entry) => entry.identity === participant.identity) + 1 : 0;
7081
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
8743
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
7082
8744
  "div",
7083
8745
  {
7084
8746
  className: [
@@ -7088,7 +8750,7 @@ function ParticipantTile({
7088
8750
  ].filter(Boolean).join(" "),
7089
8751
  "data-identity": participant.identity,
7090
8752
  children: [
7091
- showVideo ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
8753
+ showVideo ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
7092
8754
  "video",
7093
8755
  {
7094
8756
  ref: videoRef,
@@ -7097,43 +8759,43 @@ function ParticipantTile({
7097
8759
  playsInline: true,
7098
8760
  muted: participant.isLocal
7099
8761
  }
7100
- ) : /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "mx-meet__tile-placeholder", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Avatar, { name: participant.displayName, url: participant.avatarUrl, size: featured ? 96 : 56 }) }),
7101
- participant.handRaised ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("span", { className: "mx-meet__tile-hand", title: `Hand raised \xB7 ${ordinal(handPosition)} in line`, children: [
7102
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(HandIcon, { width: 14, height: 14 }),
8762
+ ) : /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "mx-meet__tile-placeholder", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Avatar, { name: participant.displayName, url: participant.avatarUrl, size: featured ? 96 : 56 }) }),
8763
+ participant.handRaised ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("span", { className: "mx-meet__tile-hand", title: `Hand raised \xB7 ${ordinal(handPosition)} in line`, children: [
8764
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(HandIcon, { width: 14, height: 14 }),
7103
8765
  handPosition > 0 ? handPosition : null
7104
8766
  ] }) : null,
7105
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "mx-meet__tile-bar", children: [
7106
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("span", { className: "mx-meet__tile-name", children: [
7107
- spotlit ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { title: "Spotlighted for everyone", className: "mx-meet__tile-flag", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(SpotlightIcon, { width: 12, height: 12 }) }) : null,
8767
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "mx-meet__tile-bar", children: [
8768
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("span", { className: "mx-meet__tile-name", children: [
8769
+ spotlit ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { title: "Spotlighted for everyone", className: "mx-meet__tile-flag", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(SpotlightIcon, { width: 12, height: 12 }) }) : null,
7108
8770
  participant.displayName,
7109
8771
  participant.isLocal ? " (you)" : "",
7110
- participant.isAgent ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "mx-meet__badge", children: "AI" }) : null,
7111
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(RoleBadge, { role: participant.role })
8772
+ participant.isAgent ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "mx-meet__badge", children: "AI" }) : null,
8773
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(RoleBadge, { role: participant.role })
7112
8774
  ] }),
7113
- !participant.micEnabled ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(MicOffIcon, { width: 14, height: 14 }) : null,
7114
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(QualityBars, { quality: participant.quality })
8775
+ !participant.micEnabled ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(MicOffIcon, { width: 14, height: 14 }) : null,
8776
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(QualityBars, { quality: participant.quality })
7115
8777
  ] }),
7116
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: menu ? "mx-meet__tile-actions mx-meet__tile-actions--open" : "mx-meet__tile-actions", children: [
7117
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
8778
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: menu ? "mx-meet__tile-actions mx-meet__tile-actions--open" : "mx-meet__tile-actions", children: [
8779
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
7118
8780
  ControlButton,
7119
8781
  {
7120
8782
  label: pinnedHere ? "Unpin" : `Pin ${participant.displayName} for me`,
7121
8783
  active: pinnedHere,
7122
8784
  onClick: () => host?.engine.pin(pinnedHere ? null : participant.identity),
7123
- children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(PinIcon, { width: 16, height: 16 })
8785
+ children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(PinIcon, { width: 16, height: 16 })
7124
8786
  }
7125
8787
  ),
7126
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("span", { className: "mx-meet__anchor", children: [
7127
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
8788
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("span", { className: "mx-meet__anchor", children: [
8789
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
7128
8790
  ControlButton,
7129
8791
  {
7130
8792
  label: `More for ${participant.displayName}`,
7131
8793
  active: menu,
7132
8794
  onClick: () => setMenu(!menu),
7133
- children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(MoreIcon, { width: 16, height: 16 })
8795
+ children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(MoreIcon, { width: 16, height: 16 })
7134
8796
  }
7135
8797
  ),
7136
- menu ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(PersonMenu, { participant, onClose: () => setMenu(false), placement: "down" }) : null
8798
+ menu ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(PersonMenu, { participant, onClose: () => setMenu(false), placement: "down" }) : null
7137
8799
  ] })
7138
8800
  ] })
7139
8801
  ]
@@ -7149,28 +8811,28 @@ function QualityBars({ quality }) {
7149
8811
  if (quality === "unknown") return null;
7150
8812
  const bars = quality === "excellent" ? 3 : quality === "good" ? 2 : quality === "poor" ? 1 : 0;
7151
8813
  const label = quality === "lost" ? "Connection lost" : quality === "poor" ? "Poor connection" : `Connection ${quality}`;
7152
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: `mx-meet__signal mx-meet__signal--${quality}`, title: label, "aria-label": label, role: "img", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(SignalIcon, { bars, width: 14, height: 14 }) });
8814
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: `mx-meet__signal mx-meet__signal--${quality}`, title: label, "aria-label": label, role: "img", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(SignalIcon, { bars, width: 14, height: 14 }) });
7153
8815
  }
7154
8816
  function Stage({ pageSize }) {
7155
8817
  const stage = useStage(pageSize);
7156
8818
  const columns = gridColumns(stage.tiles.length);
7157
8819
  if (stage.feature === null && stage.tiles.length === 0) {
7158
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "mx-meet__stage mx-meet__stage--empty", children: [
7159
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "mx-meet__empty-title", children: "Waiting for others to join" }),
7160
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "mx-meet__empty-body", children: "Share the meeting link and people can join from anywhere \u2014 no account needed." })
8820
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "mx-meet__stage mx-meet__stage--empty", children: [
8821
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { className: "mx-meet__empty-title", children: "Waiting for others to join" }),
8822
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { className: "mx-meet__empty-body", children: "Share the meeting link and people can join from anywhere \u2014 no account needed." })
7161
8823
  ] });
7162
8824
  }
7163
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: `mx-meet__stage${stage.feature !== null ? " mx-meet__stage--speaker" : ""}`, children: [
7164
- stage.feature !== null ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(ParticipantTile, { participant: stage.feature, featured: true }) : null,
7165
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
8825
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: `mx-meet__stage${stage.feature !== null ? " mx-meet__stage--speaker" : ""}`, children: [
8826
+ stage.feature !== null ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(ParticipantTile, { participant: stage.feature, featured: true }) : null,
8827
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
7166
8828
  "div",
7167
8829
  {
7168
8830
  className: "mx-meet__grid",
7169
8831
  style: { "--mx-meet-columns": columns },
7170
- children: stage.tiles.map((participant) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(ParticipantTile, { participant }, participant.identity))
8832
+ children: stage.tiles.map((participant) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(ParticipantTile, { participant }, participant.identity))
7171
8833
  }
7172
8834
  ),
7173
- stage.overflow > 0 ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("p", { className: "mx-meet__overflow", children: [
8835
+ stage.overflow > 0 ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("p", { className: "mx-meet__overflow", children: [
7174
8836
  "+",
7175
8837
  stage.overflow,
7176
8838
  " more ",
@@ -7183,20 +8845,28 @@ var MEET_REACTIONS = ["\u{1F496}", "\u{1F44D}", "\u{1F389}", "\u{1F44F}", "\u{1F
7183
8845
  function ControlBar({ onLeave }) {
7184
8846
  const room = useRoom();
7185
8847
  const recording = useRecording();
7186
- const [panel, setPanel] = (0, import_react4.useState)("none");
7187
- const [chatTo, setChatTo] = (0, import_react4.useState)(null);
7188
- const [popover, setPopover] = (0, import_react4.useState)("none");
7189
- const [shortcuts, setShortcuts] = (0, import_react4.useState)(false);
8848
+ const [panel, setPanel] = (0, import_react5.useState)("none");
8849
+ const [chatTo, setChatTo] = (0, import_react5.useState)(null);
8850
+ const [popover, setPopover] = (0, import_react5.useState)("none");
8851
+ const [shortcuts, setShortcuts] = (0, import_react5.useState)(false);
7190
8852
  const snapshot = useMeetSnapshot();
7191
8853
  const lobby = useLobby();
7192
8854
  const controls = useHostControls();
7193
8855
  const queue = useHandQueue();
7194
8856
  const micUnavailable = useLocalMedia().microphone.unavailable;
7195
8857
  const unread = useUnreadChat(panel === "chat");
8858
+ const [whiteboard, setWhiteboard] = (0, import_react5.useState)(false);
7196
8859
  const toggle = (next) => setPanel(panel === next ? "none" : next);
8860
+ const openActivity = (activity) => {
8861
+ if (activity === "whiteboard") setWhiteboard(true);
8862
+ else setPanel(activity);
8863
+ };
8864
+ useCollabPanelRequest((activity) => {
8865
+ if (!controls.isHost) openActivity(activity);
8866
+ });
7197
8867
  const privateChatAt = snapshot?.privateChatRequest?.at ?? null;
7198
8868
  const meetStore = useMeetHost()?.store ?? null;
7199
- (0, import_react4.useEffect)(() => {
8869
+ (0, import_react5.useEffect)(() => {
7200
8870
  const request = meetStore?.snapshot().privateChatRequest ?? null;
7201
8871
  if (request === null) return;
7202
8872
  setChatTo(request.to);
@@ -7212,11 +8882,11 @@ function ControlBar({ onLeave }) {
7212
8882
  help: () => setShortcuts(true)
7213
8883
  });
7214
8884
  const hasSpotlight = snapshot?.spotlight !== null && snapshot?.spotlight !== void 0;
7215
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_jsx_runtime3.Fragment, { children: [
7216
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(MeetingOverlays, {}),
7217
- shortcuts ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(ShortcutsSheet, { onClose: () => setShortcuts(false) }) : null,
7218
- panel === "chat" ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(ChatPanel, { onClose: () => setPanel("none"), to: chatTo, onTo: setChatTo }) : null,
7219
- panel === "people" ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
8885
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_jsx_runtime4.Fragment, { children: [
8886
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(MeetingOverlays, {}),
8887
+ shortcuts ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(ShortcutsSheet, { onClose: () => setShortcuts(false) }) : null,
8888
+ panel === "chat" ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(ChatPanel, { onClose: () => setPanel("none"), to: chatTo, onTo: setChatTo }) : null,
8889
+ panel === "people" ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
7220
8890
  PeoplePanel,
7221
8891
  {
7222
8892
  onClose: () => setPanel("none"),
@@ -7226,48 +8896,53 @@ function ControlBar({ onLeave }) {
7226
8896
  }
7227
8897
  }
7228
8898
  ) : null,
7229
- panel === "ai" ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(AiPanel, { onClose: () => setPanel("none") }) : null,
7230
- panel === "settings" ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(SettingsPanel, { onClose: () => setPanel("none") }) : null,
7231
- controls.notice !== null && panel !== "people" ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Toast, { text: controls.notice.text, failed: controls.notice.failed, onDone: controls.clearNotice }) : null,
7232
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "mx-meet__controls", children: [
7233
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
8899
+ panel === "ai" ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(AiPanel, { onClose: () => setPanel("none") }) : null,
8900
+ panel === "settings" ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(SettingsPanel, { onClose: () => setPanel("none") }) : null,
8901
+ panel === "polls" ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(PollsPanel, { onClose: () => setPanel("none") }) : null,
8902
+ panel === "qa" ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(QaPanel, { onClose: () => setPanel("none") }) : null,
8903
+ panel === "breakouts" ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(BreakoutsPanel, { onClose: () => setPanel("none") }) : null,
8904
+ whiteboard ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(WhiteboardPanel, { onClose: () => setWhiteboard(false) }) : null,
8905
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(BreakoutBanner, {}),
8906
+ controls.notice !== null && panel !== "people" ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Toast, { text: controls.notice.text, failed: controls.notice.failed, onDone: controls.clearNotice }) : null,
8907
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "mx-meet__controls", children: [
8908
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
7234
8909
  ControlButton,
7235
8910
  {
7236
8911
  label: micUnavailable !== null ? `Unmute \u2014 ${micUnavailable.remedy}` : room.local?.micEnabled === true ? "Mute (\u2318D)" : "Unmute (\u2318D)",
7237
8912
  active: room.local?.micEnabled === true,
7238
8913
  onClick: () => void room.toggleMicrophone(),
7239
- children: room.local?.micEnabled === true ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(MicIcon, {}) : /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(MicOffIcon, {})
8914
+ children: room.local?.micEnabled === true ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(MicIcon, {}) : /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(MicOffIcon, {})
7240
8915
  }
7241
8916
  ),
7242
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
8917
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
7243
8918
  ControlButton,
7244
8919
  {
7245
8920
  label: room.local?.cameraEnabled === true ? "Stop video (\u2318E)" : "Start video (\u2318E)",
7246
8921
  active: room.local?.cameraEnabled === true,
7247
8922
  onClick: () => void room.toggleCamera(),
7248
- children: room.local?.cameraEnabled === true ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(CameraIcon, {}) : /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(CameraOffIcon, {})
8923
+ children: room.local?.cameraEnabled === true ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(CameraIcon, {}) : /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(CameraOffIcon, {})
7249
8924
  }
7250
8925
  ),
7251
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
8926
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
7252
8927
  ControlButton,
7253
8928
  {
7254
8929
  label: room.local?.screenSharing === true ? "Stop sharing" : "Share screen",
7255
8930
  active: room.local?.screenSharing === true,
7256
8931
  onClick: () => void room.toggleScreenShare(),
7257
- children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(ScreenShareIcon, {})
8932
+ children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(ScreenShareIcon, {})
7258
8933
  }
7259
8934
  ),
7260
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("span", { className: "mx-meet__anchor", children: [
7261
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
8935
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("span", { className: "mx-meet__anchor", children: [
8936
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
7262
8937
  ControlButton,
7263
8938
  {
7264
8939
  label: "Send a reaction",
7265
8940
  active: popover === "reactions",
7266
8941
  onClick: () => setPopover(popover === "reactions" ? "none" : "reactions"),
7267
- children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(SmileIcon, {})
8942
+ children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(SmileIcon, {})
7268
8943
  }
7269
8944
  ),
7270
- popover === "reactions" ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Popover, { label: "Reactions", onClose: () => setPopover("none"), children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "mx-meet__emoji-bar", children: MEET_REACTIONS.map((emoji) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
8945
+ popover === "reactions" ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Popover, { label: "Reactions", onClose: () => setPopover("none"), children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "mx-meet__emoji-bar", children: MEET_REACTIONS.map((emoji) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
7271
8946
  "button",
7272
8947
  {
7273
8948
  type: "button",
@@ -7279,46 +8954,53 @@ function ControlBar({ onLeave }) {
7279
8954
  emoji
7280
8955
  )) }) }) : null
7281
8956
  ] }),
7282
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
8957
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
7283
8958
  ControlButton,
7284
8959
  {
7285
8960
  label: room.local?.handRaised === true ? "Lower hand (\u2318\u2325H)" : "Raise hand (\u2318\u2325H)",
7286
8961
  active: room.local?.handRaised === true,
7287
8962
  onClick: () => void room.toggleHand(),
7288
- children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(HandIcon, {})
8963
+ children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(HandIcon, {})
7289
8964
  }
7290
8965
  ),
7291
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(ControlButton, { label: "Chat (\u2318\u2325C)", active: panel === "chat", onClick: () => toggle("chat"), children: [
7292
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(ChatIcon, {}),
7293
- unread > 0 ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "mx-meet__dot", "aria-hidden": "true" }) : null
8966
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(ControlButton, { label: "Chat (\u2318\u2325C)", active: panel === "chat", onClick: () => toggle("chat"), children: [
8967
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(ChatIcon, {}),
8968
+ unread > 0 ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "mx-meet__dot", "aria-hidden": "true" }) : null
7294
8969
  ] }),
7295
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
8970
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
7296
8971
  ControlButton,
7297
8972
  {
7298
8973
  label: lobby.waiting.length > 0 ? `People \u2014 ${lobby.waiting.length} waiting` : `People \u2014 ${(snapshot?.participants ?? []).length} in the meeting`,
7299
8974
  active: panel === "people",
7300
8975
  onClick: () => toggle("people"),
7301
8976
  children: [
7302
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(PeopleIcon, {}),
7303
- lobby.waiting.length > 0 || controls.isHost && queue.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "mx-meet__dot", "aria-hidden": "true" }) : null
8977
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(PeopleIcon, {}),
8978
+ lobby.waiting.length > 0 || controls.isHost && queue.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "mx-meet__dot", "aria-hidden": "true" }) : null
7304
8979
  ]
7305
8980
  }
7306
8981
  ),
7307
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(AiControl, { active: panel === "ai", onToggle: () => toggle("ai") }),
7308
- recording.canStart ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(ControlButton, { label: "Start recording", onClick: () => void recording.start(), children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(RecordIcon, {}) }) : null,
7309
- recording.canStop ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(ControlButton, { label: "Stop recording", active: true, onClick: () => void recording.stop(), children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(RecordIcon, {}) }) : null,
7310
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("span", { className: "mx-meet__anchor", children: [
7311
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
8982
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
8983
+ ActivitiesControl,
8984
+ {
8985
+ active: whiteboard ? "whiteboard" : panel === "polls" || panel === "qa" || panel === "breakouts" ? panel : null,
8986
+ onOpen: openActivity
8987
+ }
8988
+ ),
8989
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(AiControl, { active: panel === "ai", onToggle: () => toggle("ai") }),
8990
+ recording.canStart ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(ControlButton, { label: "Start recording", onClick: () => void recording.start(), children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(RecordIcon, {}) }) : null,
8991
+ recording.canStop ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(ControlButton, { label: "Stop recording", active: true, onClick: () => void recording.stop(), children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(RecordIcon, {}) }) : null,
8992
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("span", { className: "mx-meet__anchor", children: [
8993
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
7312
8994
  ControlButton,
7313
8995
  {
7314
8996
  label: "More options",
7315
8997
  active: popover === "more" || panel === "settings",
7316
8998
  onClick: () => setPopover(popover === "more" ? "none" : "more"),
7317
- children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(MoreIcon, {})
8999
+ children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(MoreIcon, {})
7318
9000
  }
7319
9001
  ),
7320
- popover === "more" ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Popover, { label: "More options", onClose: () => setPopover("none"), children: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "mx-meet__menu", role: "menu", children: [
7321
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
9002
+ popover === "more" ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Popover, { label: "More options", onClose: () => setPopover("none"), children: /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "mx-meet__menu", role: "menu", children: [
9003
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
7322
9004
  MenuItem,
7323
9005
  {
7324
9006
  onSelect: () => {
@@ -7326,12 +9008,12 @@ function ControlBar({ onLeave }) {
7326
9008
  setPanel("settings");
7327
9009
  },
7328
9010
  children: [
7329
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(SettingsIcon, { width: 16, height: 16 }),
7330
- " Audio, video and effects"
9011
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(SettingsIcon, { width: 16, height: 16 }),
9012
+ " Settings"
7331
9013
  ]
7332
9014
  }
7333
9015
  ),
7334
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
9016
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
7335
9017
  MenuItem,
7336
9018
  {
7337
9019
  onSelect: () => {
@@ -7339,14 +9021,14 @@ function ControlBar({ onLeave }) {
7339
9021
  setShortcuts(true);
7340
9022
  },
7341
9023
  children: [
7342
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(KeyboardIcon, { width: 16, height: 16 }),
9024
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(KeyboardIcon, { width: 16, height: 16 }),
7343
9025
  " Keyboard shortcuts"
7344
9026
  ]
7345
9027
  }
7346
9028
  ),
7347
- controls.isHost ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_jsx_runtime3.Fragment, { children: [
7348
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "mx-meet__menu-sep", role: "separator" }),
7349
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
9029
+ controls.isHost ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_jsx_runtime4.Fragment, { children: [
9030
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "mx-meet__menu-sep", role: "separator" }),
9031
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
7350
9032
  MenuItem,
7351
9033
  {
7352
9034
  onSelect: () => {
@@ -7354,12 +9036,12 @@ function ControlBar({ onLeave }) {
7354
9036
  void controls.run({ action: "mute_all" });
7355
9037
  },
7356
9038
  children: [
7357
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(MicOffIcon, { width: 16, height: 16 }),
9039
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(MicOffIcon, { width: 16, height: 16 }),
7358
9040
  " Mute everyone"
7359
9041
  ]
7360
9042
  }
7361
9043
  ),
7362
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
9044
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
7363
9045
  MenuItem,
7364
9046
  {
7365
9047
  onSelect: () => {
@@ -7367,12 +9049,12 @@ function ControlBar({ onLeave }) {
7367
9049
  void controls.run({ action: "ask_all_unmute" });
7368
9050
  },
7369
9051
  children: [
7370
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(MicIcon, { width: 16, height: 16 }),
9052
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(MicIcon, { width: 16, height: 16 }),
7371
9053
  " Ask everyone to unmute"
7372
9054
  ]
7373
9055
  }
7374
9056
  ),
7375
- queue.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
9057
+ queue.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
7376
9058
  MenuItem,
7377
9059
  {
7378
9060
  onSelect: () => {
@@ -7380,14 +9062,14 @@ function ControlBar({ onLeave }) {
7380
9062
  void controls.run({ action: "lower_all_hands" });
7381
9063
  },
7382
9064
  children: [
7383
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(HandIcon, { width: 16, height: 16 }),
9065
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(HandIcon, { width: 16, height: 16 }),
7384
9066
  " Lower all hands (",
7385
9067
  queue.length,
7386
9068
  ")"
7387
9069
  ]
7388
9070
  }
7389
9071
  ) : null,
7390
- hasSpotlight ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
9072
+ hasSpotlight ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
7391
9073
  MenuItem,
7392
9074
  {
7393
9075
  onSelect: () => {
@@ -7395,7 +9077,7 @@ function ControlBar({ onLeave }) {
7395
9077
  void controls.run({ action: "spotlight", identity: null });
7396
9078
  },
7397
9079
  children: [
7398
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(SpotlightIcon, { width: 16, height: 16 }),
9080
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(SpotlightIcon, { width: 16, height: 16 }),
7399
9081
  " Remove spotlight"
7400
9082
  ]
7401
9083
  }
@@ -7403,7 +9085,7 @@ function ControlBar({ onLeave }) {
7403
9085
  ] }) : null
7404
9086
  ] }) }) : null
7405
9087
  ] }),
7406
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
9088
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
7407
9089
  ControlButton,
7408
9090
  {
7409
9091
  label: "Leave",
@@ -7412,7 +9094,7 @@ function ControlBar({ onLeave }) {
7412
9094
  void room.leave();
7413
9095
  onLeave?.();
7414
9096
  },
7415
- children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(PhoneOffIcon, {})
9097
+ children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(PhoneOffIcon, {})
7416
9098
  }
7417
9099
  )
7418
9100
  ] })
@@ -7422,13 +9104,13 @@ function useUnreadChat(open) {
7422
9104
  const snapshot = useMeetSnapshot();
7423
9105
  const chat = snapshot?.chat ?? [];
7424
9106
  const local = snapshot?.localIdentity ?? null;
7425
- const [seen, setSeen] = (0, import_react4.useState)(0);
7426
- (0, import_react4.useEffect)(() => {
9107
+ const [seen, setSeen] = (0, import_react5.useState)(0);
9108
+ (0, import_react5.useEffect)(() => {
7427
9109
  if (open) setSeen(chat.length);
7428
9110
  }, [open, chat.length]);
7429
9111
  const loaded = snapshot?.chatLoaded === true;
7430
- const [baseline, setBaseline] = (0, import_react4.useState)(null);
7431
- (0, import_react4.useEffect)(() => {
9112
+ const [baseline, setBaseline] = (0, import_react5.useState)(null);
9113
+ (0, import_react5.useEffect)(() => {
7432
9114
  if (loaded && baseline === null) setBaseline(chat.length);
7433
9115
  }, [loaded, baseline, chat.length]);
7434
9116
  if (open) return 0;
@@ -7441,14 +9123,14 @@ function Popover({
7441
9123
  children,
7442
9124
  placement = "up"
7443
9125
  }) {
7444
- const ref = (0, import_react4.useRef)(null);
7445
- const [style, setStyle] = (0, import_react4.useState)({
9126
+ const ref = (0, import_react5.useRef)(null);
9127
+ const [style, setStyle] = (0, import_react5.useState)({
7446
9128
  position: "fixed",
7447
9129
  top: 0,
7448
9130
  left: 0,
7449
9131
  visibility: "hidden"
7450
9132
  });
7451
- (0, import_react4.useLayoutEffect)(() => {
9133
+ (0, import_react5.useLayoutEffect)(() => {
7452
9134
  const element = ref.current;
7453
9135
  const anchor = element?.parentElement ?? null;
7454
9136
  if (element === null || anchor === null) return;
@@ -7493,7 +9175,7 @@ function Popover({
7493
9175
  window.removeEventListener("scroll", place, true);
7494
9176
  };
7495
9177
  }, [placement]);
7496
- (0, import_react4.useEffect)(() => {
9178
+ (0, import_react5.useEffect)(() => {
7497
9179
  const onKey = (event) => {
7498
9180
  if (event.key === "Escape") onClose();
7499
9181
  };
@@ -7508,14 +9190,14 @@ function Popover({
7508
9190
  window.removeEventListener("pointerdown", onPointer);
7509
9191
  };
7510
9192
  }, [onClose]);
7511
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { ref, className: "mx-meet__popover", style, role: "dialog", "aria-label": label, children });
9193
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { ref, className: "mx-meet__popover", style, role: "dialog", "aria-label": label, children });
7512
9194
  }
7513
9195
  function MenuItem({
7514
9196
  onSelect,
7515
9197
  danger = false,
7516
9198
  children
7517
9199
  }) {
7518
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
9200
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
7519
9201
  "button",
7520
9202
  {
7521
9203
  type: "button",
@@ -7527,28 +9209,28 @@ function MenuItem({
7527
9209
  );
7528
9210
  }
7529
9211
  function Toast({ text: text3, failed, onDone }) {
7530
- (0, import_react4.useEffect)(() => {
9212
+ (0, import_react5.useEffect)(() => {
7531
9213
  const timer = setTimeout(onDone, failed ? 7e3 : 4e3);
7532
9214
  return () => clearTimeout(timer);
7533
9215
  }, [text3, failed, onDone]);
7534
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: failed ? "mx-meet__toast mx-meet__toast--failed" : "mx-meet__toast", role: "status", children: [
7535
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { children: text3 }),
7536
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("button", { type: "button", className: "mx-meet__toast-close", "aria-label": "Dismiss", onClick: onDone, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(CloseIcon, { width: 14, height: 14 }) })
9216
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: failed ? "mx-meet__toast mx-meet__toast--failed" : "mx-meet__toast", role: "status", children: [
9217
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { children: text3 }),
9218
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("button", { type: "button", className: "mx-meet__toast-close", "aria-label": "Dismiss", onClick: onDone, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(CloseIcon, { width: 14, height: 14 }) })
7537
9219
  ] });
7538
9220
  }
7539
9221
  function MeetingOverlays() {
7540
9222
  const reactions = useReactions();
7541
9223
  const { notice, dismiss } = useModerationNotice();
7542
9224
  const room = useRoom();
7543
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_jsx_runtime3.Fragment, { children: [
7544
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(ReactionOverlay, { reactions }),
9225
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_jsx_runtime4.Fragment, { children: [
9226
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(ReactionOverlay, { reactions }),
7545
9227
  notice !== null && notice.kind !== "removed" ? (
7546
9228
  // A host's request ("the host is asking you to unmute"), not an error:
7547
9229
  // an assertive status, so it is announced at once without being filed
7548
9230
  // as a failure (design-system error-box census).
7549
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "mx-meet__notice-bar", role: "status", "aria-live": "assertive", children: [
7550
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { children: notice.text }),
7551
- notice.kind === "ask-unmute" && room.local?.micEnabled !== true ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
9231
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "mx-meet__notice-bar", role: "status", "aria-live": "assertive", children: [
9232
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { children: notice.text }),
9233
+ notice.kind === "ask-unmute" && room.local?.micEnabled !== true ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
7552
9234
  "button",
7553
9235
  {
7554
9236
  type: "button",
@@ -7560,20 +9242,20 @@ function MeetingOverlays() {
7560
9242
  children: "Unmute"
7561
9243
  }
7562
9244
  ) : null,
7563
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("button", { type: "button", className: "mx-meet__toast-close", "aria-label": "Dismiss", onClick: dismiss, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(CloseIcon, { width: 14, height: 14 }) })
9245
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("button", { type: "button", className: "mx-meet__toast-close", "aria-label": "Dismiss", onClick: dismiss, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(CloseIcon, { width: 14, height: 14 }) })
7564
9246
  ] })
7565
9247
  ) : null
7566
9248
  ] });
7567
9249
  }
7568
9250
  function ShortcutsSheet({ onClose }) {
7569
- (0, import_react4.useEffect)(() => {
9251
+ (0, import_react5.useEffect)(() => {
7570
9252
  const onKey = (event) => {
7571
9253
  if (event.key === "Escape") onClose();
7572
9254
  };
7573
9255
  window.addEventListener("keydown", onKey);
7574
9256
  return () => window.removeEventListener("keydown", onKey);
7575
9257
  }, [onClose]);
7576
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "mx-meet__sheet-backdrop", onClick: onClose, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
9258
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "mx-meet__sheet-backdrop", onClick: onClose, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
7577
9259
  "div",
7578
9260
  {
7579
9261
  className: "mx-meet__sheet",
@@ -7581,13 +9263,13 @@ function ShortcutsSheet({ onClose }) {
7581
9263
  "aria-label": "Keyboard shortcuts",
7582
9264
  onClick: (event) => event.stopPropagation(),
7583
9265
  children: [
7584
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("header", { className: "mx-meet__panel-head", children: [
7585
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("h2", { className: "mx-meet__panel-title", children: "Keyboard shortcuts" }),
7586
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(ControlButton, { label: "Close", onClick: onClose, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(CloseIcon, { width: 16, height: 16 }) })
9266
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("header", { className: "mx-meet__panel-head", children: [
9267
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("h2", { className: "mx-meet__panel-title", children: "Keyboard shortcuts" }),
9268
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(ControlButton, { label: "Close", onClick: onClose, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(CloseIcon, { width: 16, height: 16 }) })
7587
9269
  ] }),
7588
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("dl", { className: "mx-meet__shortcuts", children: MEET_SHORTCUTS.map((shortcut) => /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "mx-meet__shortcut", children: [
7589
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("dt", { children: shortcut.label }),
7590
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("dd", { children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("kbd", { className: "mx-meet__kbd", children: shortcut.keys }) })
9270
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("dl", { className: "mx-meet__shortcuts", children: MEET_SHORTCUTS.map((shortcut) => /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "mx-meet__shortcut", children: [
9271
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("dt", { children: shortcut.label }),
9272
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("dd", { children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("kbd", { className: "mx-meet__kbd", children: shortcut.keys }) })
7591
9273
  ] }, shortcut.id)) })
7592
9274
  ]
7593
9275
  }
@@ -7597,19 +9279,19 @@ function AiControl({ active, onToggle }) {
7597
9279
  const snapshot = useMeetSnapshot();
7598
9280
  const meeting = snapshot?.meeting ?? null;
7599
9281
  if (meeting === null || !meeting.aiEnabled) return null;
7600
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(ControlButton, { label: "Meeting assistant", active, onClick: onToggle, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(SparklesIcon, {}) });
9282
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(ControlButton, { label: "Meeting assistant", active, onClick: onToggle, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(SparklesIcon, {}) });
7601
9283
  }
7602
9284
  function PanelShell({
7603
9285
  title,
7604
9286
  onClose,
7605
9287
  children
7606
9288
  }) {
7607
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("aside", { className: "mx-meet__panel", "aria-label": title, children: [
7608
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("header", { className: "mx-meet__panel-head", children: [
7609
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("h2", { className: "mx-meet__panel-title", children: title }),
7610
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(ControlButton, { label: "Close panel", onClick: onClose, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(CloseIcon, { width: 16, height: 16 }) })
9289
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("aside", { className: "mx-meet__panel", "aria-label": title, children: [
9290
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("header", { className: "mx-meet__panel-head", children: [
9291
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("h2", { className: "mx-meet__panel-title", children: title }),
9292
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(ControlButton, { label: "Close panel", onClick: onClose, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(CloseIcon, { width: 16, height: 16 }) })
7611
9293
  ] }),
7612
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "mx-meet__panel-body", children })
9294
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "mx-meet__panel-body", children })
7613
9295
  ] });
7614
9296
  }
7615
9297
  function ChatPanel({
@@ -7619,17 +9301,17 @@ function ChatPanel({
7619
9301
  }) {
7620
9302
  const snapshot = useMeetSnapshot();
7621
9303
  const room = useRoom();
7622
- const [draft, setDraft] = (0, import_react4.useState)("");
7623
- const [recipient, setRecipient] = (0, import_react4.useState)(to);
7624
- const listRef = (0, import_react4.useRef)(null);
9304
+ const [draft, setDraft] = (0, import_react5.useState)("");
9305
+ const [recipient, setRecipient] = (0, import_react5.useState)(to);
9306
+ const listRef = (0, import_react5.useRef)(null);
7625
9307
  const messages = snapshot?.chat ?? [];
7626
9308
  const local = snapshot?.localIdentity ?? null;
7627
9309
  const people = (snapshot?.participants ?? []).filter(
7628
9310
  (participant) => !participant.isLocal && !participant.isAgent
7629
9311
  );
7630
9312
  const recipientName = recipient === null ? null : people.find((p) => p.identity === recipient)?.displayName ?? null;
7631
- (0, import_react4.useEffect)(() => setRecipient(to), [to]);
7632
- (0, import_react4.useEffect)(() => {
9313
+ (0, import_react5.useEffect)(() => setRecipient(to), [to]);
9314
+ (0, import_react5.useEffect)(() => {
7633
9315
  const list = listRef.current;
7634
9316
  if (list !== null) list.scrollTop = list.scrollHeight;
7635
9317
  }, [messages.length]);
@@ -7637,13 +9319,13 @@ function ChatPanel({
7637
9319
  setRecipient(next);
7638
9320
  onTo?.(next);
7639
9321
  };
7640
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(PanelShell, { title: "Chat", onClose, children: [
7641
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("ul", { className: "mx-meet__chat", ref: listRef, children: [
7642
- snapshot?.chatHistoryError != null ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("li", { className: "mx-meet__panel-note", children: snapshot.chatHistoryError }) : null,
7643
- snapshot?.chatLoaded !== true && messages.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("li", { className: "mx-meet__panel-note", children: "Reading earlier messages\u2026" }) : messages.length === 0 && snapshot?.chatHistoryError == null ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("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,
7644
- messages.map((message) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(ChatLine, { message, local, people }, message.id))
9322
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(PanelShell, { title: "Chat", onClose, children: [
9323
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("ul", { className: "mx-meet__chat", ref: listRef, children: [
9324
+ snapshot?.chatHistoryError != null ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("li", { className: "mx-meet__panel-note", children: snapshot.chatHistoryError }) : null,
9325
+ snapshot?.chatLoaded !== true && messages.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("li", { className: "mx-meet__panel-note", children: "Reading earlier messages\u2026" }) : messages.length === 0 && snapshot?.chatHistoryError == null ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("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,
9326
+ messages.map((message) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(ChatLine, { message, local, people }, message.id))
7645
9327
  ] }),
7646
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
9328
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
7647
9329
  "form",
7648
9330
  {
7649
9331
  className: "mx-meet__composer mx-meet__composer--chat",
@@ -7656,7 +9338,7 @@ function ChatPanel({
7656
9338
  else void room.sendPrivateChat(recipient, text3);
7657
9339
  },
7658
9340
  children: [
7659
- people.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
9341
+ people.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
7660
9342
  "select",
7661
9343
  {
7662
9344
  className: "mx-meet__select mx-meet__select--compact",
@@ -7664,16 +9346,16 @@ function ChatPanel({
7664
9346
  value: recipient ?? "",
7665
9347
  onChange: (event) => choose(event.target.value === "" ? null : event.target.value),
7666
9348
  children: [
7667
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("option", { value: "", children: "Everyone" }),
7668
- people.map((participant) => /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("option", { value: participant.identity, children: [
9349
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("option", { value: "", children: "Everyone" }),
9350
+ people.map((participant) => /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("option", { value: participant.identity, children: [
7669
9351
  participant.displayName,
7670
9352
  " (private)"
7671
9353
  ] }, participant.identity))
7672
9354
  ]
7673
9355
  }
7674
9356
  ) : null,
7675
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "mx-meet__composer-row", children: [
7676
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
9357
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "mx-meet__composer-row", children: [
9358
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
7677
9359
  "input",
7678
9360
  {
7679
9361
  className: "mx-meet__input",
@@ -7684,9 +9366,9 @@ function ChatPanel({
7684
9366
  maxLength: 4e3
7685
9367
  }
7686
9368
  ),
7687
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("button", { type: "submit", className: "mx-meet__send", disabled: draft.trim().length === 0, children: "Send" })
9369
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("button", { type: "submit", className: "mx-meet__send", disabled: draft.trim().length === 0, children: "Send" })
7688
9370
  ] }),
7689
- recipientName !== null ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("p", { className: "mx-meet__panel-note", children: [
9371
+ recipientName !== null ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("p", { className: "mx-meet__panel-note", children: [
7690
9372
  "Only ",
7691
9373
  recipientName,
7692
9374
  " sees this. Private messages are not saved."
@@ -7704,7 +9386,7 @@ function ChatLine({
7704
9386
  const mine = message.identity === local;
7705
9387
  const privateTo = message.to ?? null;
7706
9388
  const counterpart = privateTo === null ? null : mine ? people.find((p) => p.identity === privateTo)?.displayName ?? "them" : "you";
7707
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
9389
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
7708
9390
  "li",
7709
9391
  {
7710
9392
  className: [
@@ -7713,17 +9395,17 @@ function ChatLine({
7713
9395
  message.failed !== void 0 ? "mx-meet__chat-line--failed" : ""
7714
9396
  ].filter(Boolean).join(" "),
7715
9397
  children: [
7716
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("span", { className: "mx-meet__chat-meta", children: [
7717
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("strong", { children: mine ? "You" : message.displayName }),
7718
- counterpart !== null ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("span", { className: "mx-meet__chat-private", children: [
9398
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("span", { className: "mx-meet__chat-meta", children: [
9399
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("strong", { children: mine ? "You" : message.displayName }),
9400
+ counterpart !== null ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("span", { className: "mx-meet__chat-private", children: [
7719
9401
  "to ",
7720
9402
  counterpart,
7721
9403
  " \xB7 private"
7722
9404
  ] }) : null,
7723
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("time", { dateTime: message.at, children: clockOf(message.at) })
9405
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("time", { dateTime: message.at, children: clockOf(message.at) })
7724
9406
  ] }),
7725
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "mx-meet__chat-text", children: message.text }),
7726
- message.failed !== void 0 ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "mx-meet__chat-failed", children: message.failed }) : privateTo === null && message.saved === false ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("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
9407
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "mx-meet__chat-text", children: message.text }),
9408
+ message.failed !== void 0 ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "mx-meet__chat-failed", children: message.failed }) : privateTo === null && message.saved === false ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("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
7727
9409
  ]
7728
9410
  }
7729
9411
  );
@@ -7735,22 +9417,22 @@ function PeoplePanel({
7735
9417
  const snapshot = useMeetSnapshot();
7736
9418
  const controls = useHostControls();
7737
9419
  const queue = useHandQueue();
7738
- const [query, setQuery] = (0, import_react4.useState)("");
7739
- const [menuFor, setMenuFor] = (0, import_react4.useState)(null);
9420
+ const [query, setQuery] = (0, import_react5.useState)("");
9421
+ const [menuFor, setMenuFor] = (0, import_react5.useState)(null);
7740
9422
  const myRole = useRole();
7741
9423
  const local = snapshot?.localIdentity ?? null;
7742
9424
  const everyone = snapshot?.participants ?? [];
7743
9425
  const needle = query.trim().toLowerCase();
7744
9426
  const shown = needle.length === 0 ? everyone : everyone.filter((participant) => participant.displayName.toLowerCase().includes(needle));
7745
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(PanelShell, { title: `People (${everyone.length})`, onClose, children: [
7746
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(LobbyPanel, {}),
7747
- queue.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("section", { className: "mx-meet__section", "aria-label": "Raised hands", children: [
7748
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("header", { className: "mx-meet__section-head", children: [
7749
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("h3", { className: "mx-meet__section-title", children: [
9427
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(PanelShell, { title: `People (${everyone.length})`, onClose, children: [
9428
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(LobbyPanel, {}),
9429
+ queue.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("section", { className: "mx-meet__section", "aria-label": "Raised hands", children: [
9430
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("header", { className: "mx-meet__section-head", children: [
9431
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("h3", { className: "mx-meet__section-title", children: [
7750
9432
  "Raised hands \xB7 ",
7751
9433
  queue.length
7752
9434
  ] }),
7753
- controls.isHost ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
9435
+ controls.isHost ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
7754
9436
  "button",
7755
9437
  {
7756
9438
  type: "button",
@@ -7760,13 +9442,13 @@ function PeoplePanel({
7760
9442
  }
7761
9443
  ) : null
7762
9444
  ] }),
7763
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("ol", { className: "mx-meet__queue", children: queue.map((participant) => /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("li", { className: "mx-meet__person", children: [
7764
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Avatar, { name: participant.displayName, url: participant.avatarUrl, size: 28 }),
7765
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("span", { className: "mx-meet__person-name", children: [
9445
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("ol", { className: "mx-meet__queue", children: queue.map((participant) => /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("li", { className: "mx-meet__person", children: [
9446
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Avatar, { name: participant.displayName, url: participant.avatarUrl, size: 28 }),
9447
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("span", { className: "mx-meet__person-name", children: [
7766
9448
  participant.displayName,
7767
- participant.identity === local ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "mx-meet__you", children: " (you)" }) : null
9449
+ participant.identity === local ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "mx-meet__you", children: " (you)" }) : null
7768
9450
  ] }),
7769
- controls.isHost || participant.identity === local ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
9451
+ controls.isHost || participant.identity === local ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
7770
9452
  "button",
7771
9453
  {
7772
9454
  type: "button",
@@ -7777,27 +9459,27 @@ function PeoplePanel({
7777
9459
  ) : null
7778
9460
  ] }, participant.identity)) })
7779
9461
  ] }) : null,
7780
- controls.isHost && everyone.length > 1 ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "mx-meet__bulk", children: [
7781
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("button", { type: "button", className: "mx-meet__chip", onClick: () => void controls.run({ action: "mute_all" }), children: [
7782
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(MicOffIcon, { width: 14, height: 14 }),
9462
+ controls.isHost && everyone.length > 1 ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "mx-meet__bulk", children: [
9463
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("button", { type: "button", className: "mx-meet__chip", onClick: () => void controls.run({ action: "mute_all" }), children: [
9464
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(MicOffIcon, { width: 14, height: 14 }),
7783
9465
  " Mute all"
7784
9466
  ] }),
7785
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
9467
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
7786
9468
  "button",
7787
9469
  {
7788
9470
  type: "button",
7789
9471
  className: "mx-meet__chip",
7790
9472
  onClick: () => void controls.run({ action: "ask_all_unmute" }),
7791
9473
  children: [
7792
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(MicIcon, { width: 14, height: 14 }),
9474
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(MicIcon, { width: 14, height: 14 }),
7793
9475
  " Ask all to unmute"
7794
9476
  ]
7795
9477
  }
7796
9478
  )
7797
9479
  ] }) : null,
7798
- everyone.length > 4 ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("label", { className: "mx-meet__search", children: [
7799
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(SearchIcon, { width: 16, height: 16 }),
7800
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
9480
+ everyone.length > 4 ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("label", { className: "mx-meet__search", children: [
9481
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(SearchIcon, { width: 16, height: 16 }),
9482
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
7801
9483
  "input",
7802
9484
  {
7803
9485
  className: "mx-meet__input mx-meet__input--bare",
@@ -7808,31 +9490,31 @@ function PeoplePanel({
7808
9490
  }
7809
9491
  )
7810
9492
  ] }) : null,
7811
- controls.notice !== null ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: controls.notice.failed ? "mx-meet__error" : "mx-meet__notice", role: "status", children: controls.notice.text }) : null,
7812
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("ul", { className: "mx-meet__people", children: [
7813
- shown.map((participant) => /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("li", { className: "mx-meet__person", children: [
7814
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Avatar, { name: participant.displayName, url: participant.avatarUrl, size: 32 }),
7815
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("span", { className: "mx-meet__person-name", children: [
9493
+ controls.notice !== null ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { className: controls.notice.failed ? "mx-meet__error" : "mx-meet__notice", role: "status", children: controls.notice.text }) : null,
9494
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("ul", { className: "mx-meet__people", children: [
9495
+ shown.map((participant) => /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("li", { className: "mx-meet__person", children: [
9496
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Avatar, { name: participant.displayName, url: participant.avatarUrl, size: 32 }),
9497
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("span", { className: "mx-meet__person-name", children: [
7816
9498
  participant.displayName,
7817
- participant.identity === local ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "mx-meet__you", children: " (you)" }) : null,
7818
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(RoleBadge, { role: participant.identity === local ? myRole : participant.role }),
7819
- isNoteTaker(participant) ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "mx-meet__badge", children: "Meeting assistant" }) : null,
7820
- snapshot?.spotlight === participant.identity ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "mx-meet__badge", children: "Spotlight" }) : null
9499
+ participant.identity === local ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "mx-meet__you", children: " (you)" }) : null,
9500
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(RoleBadge, { role: participant.identity === local ? myRole : participant.role }),
9501
+ isNoteTaker(participant) ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "mx-meet__badge", children: "Meeting assistant" }) : null,
9502
+ snapshot?.spotlight === participant.identity ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "mx-meet__badge", children: "Spotlight" }) : null
7821
9503
  ] }),
7822
- participant.handRaised ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(HandIcon, { width: 14, height: 14 }) : null,
7823
- !participant.micEnabled && !isNoteTaker(participant) ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(MicOffIcon, { width: 14, height: 14 }) : null,
7824
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(QualityBars, { quality: participant.quality }),
7825
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("span", { className: "mx-meet__anchor", children: [
7826
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
9504
+ participant.handRaised ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(HandIcon, { width: 14, height: 14 }) : null,
9505
+ !participant.micEnabled && !isNoteTaker(participant) ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(MicOffIcon, { width: 14, height: 14 }) : null,
9506
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(QualityBars, { quality: participant.quality }),
9507
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("span", { className: "mx-meet__anchor", children: [
9508
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
7827
9509
  ControlButton,
7828
9510
  {
7829
9511
  label: `More for ${participant.displayName}`,
7830
9512
  active: menuFor === participant.identity,
7831
9513
  onClick: () => setMenuFor(menuFor === participant.identity ? null : participant.identity),
7832
- children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(MoreIcon, { width: 16, height: 16 })
9514
+ children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(MoreIcon, { width: 16, height: 16 })
7833
9515
  }
7834
9516
  ),
7835
- menuFor === participant.identity ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
9517
+ menuFor === participant.identity ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
7836
9518
  PersonMenu,
7837
9519
  {
7838
9520
  participant,
@@ -7843,13 +9525,13 @@ function PeoplePanel({
7843
9525
  ) : null
7844
9526
  ] })
7845
9527
  ] }, participant.identity)),
7846
- shown.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("li", { className: "mx-meet__panel-note", children: [
9528
+ shown.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("li", { className: "mx-meet__panel-note", children: [
7847
9529
  "Nobody matches \u201C",
7848
9530
  query,
7849
9531
  "\u201D."
7850
9532
  ] }) : null
7851
9533
  ] }),
7852
- snapshot?.meeting !== null && snapshot?.meeting !== void 0 ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(GuestRecordAccessControl, { meeting: snapshot.meeting }) : null
9534
+ snapshot?.meeting !== null && snapshot?.meeting !== void 0 ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(GuestRecordAccessControl, { meeting: snapshot.meeting }) : null
7853
9535
  ] });
7854
9536
  }
7855
9537
  function PersonMenu({
@@ -7861,14 +9543,14 @@ function PersonMenu({
7861
9543
  const host = useMeetHost();
7862
9544
  const snapshot = useMeetSnapshot();
7863
9545
  const controls = useHostControls();
7864
- const [mode, setMode] = (0, import_react4.useState)("menu");
7865
- const [text3, setText] = (0, import_react4.useState)("");
9546
+ const [mode, setMode] = (0, import_react5.useState)("menu");
9547
+ const [text3, setText] = (0, import_react5.useState)("");
7866
9548
  const self = participant.identity === snapshot?.localIdentity;
7867
9549
  const moderate = controls.canModerate(participant);
7868
9550
  const pinned = snapshot?.pinned === participant.identity;
7869
9551
  const spotlit = snapshot?.spotlight === participant.identity;
7870
9552
  const hasAccount = participant.userId !== null;
7871
- const [refused, setRefused] = (0, import_react4.useState)(false);
9553
+ const [refused, setRefused] = (0, import_react5.useState)(false);
7872
9554
  const act = (request) => {
7873
9555
  setRefused(false);
7874
9556
  void controls.run(request).then((result) => {
@@ -7876,10 +9558,10 @@ function PersonMenu({
7876
9558
  else setRefused(true);
7877
9559
  });
7878
9560
  };
7879
- const refusal2 = refused && controls.notice?.failed === true ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_design_system.ErrorBox, { as: "p", className: "mx-meet__error", message: controls.notice.text, operation: "Change this participant", origin: "meet/components", children: controls.notice.text }) : null;
9561
+ const refusal2 = refused && controls.notice?.failed === true ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_design_system.ErrorBox, { as: "p", className: "mx-meet__error", message: controls.notice.text, operation: "Change this participant", origin: "meet/components", children: controls.notice.text }) : null;
7880
9562
  if (mode === "rename" || mode === "report") {
7881
9563
  const renaming = mode === "rename";
7882
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Popover, { label: renaming ? "Rename" : "Report", onClose, placement, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
9564
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Popover, { label: renaming ? "Rename" : "Report", onClose, placement, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
7883
9565
  "form",
7884
9566
  {
7885
9567
  className: "mx-meet__menu-form",
@@ -7891,9 +9573,9 @@ function PersonMenu({
7891
9573
  );
7892
9574
  },
7893
9575
  children: [
7894
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("label", { className: "mx-meet__field", children: [
7895
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "mx-meet__field-label", children: renaming ? "Name shown in this meeting" : `What did ${participant.displayName} do?` }),
7896
- renaming ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
9576
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("label", { className: "mx-meet__field", children: [
9577
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "mx-meet__field-label", children: renaming ? "Name shown in this meeting" : `What did ${participant.displayName} do?` }),
9578
+ renaming ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
7897
9579
  "input",
7898
9580
  {
7899
9581
  className: "mx-meet__input",
@@ -7902,7 +9584,7 @@ function PersonMenu({
7902
9584
  value: text3,
7903
9585
  onChange: (event) => setText(event.target.value)
7904
9586
  }
7905
- ) : /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
9587
+ ) : /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
7906
9588
  "textarea",
7907
9589
  {
7908
9590
  className: "mx-meet__input",
@@ -7915,9 +9597,9 @@ function PersonMenu({
7915
9597
  )
7916
9598
  ] }),
7917
9599
  refusal2,
7918
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "mx-meet__menu-actions", children: [
7919
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("button", { type: "button", className: "mx-meet__link", onClick: () => setMode("menu"), children: "Back" }),
7920
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("button", { type: "submit", className: "mx-meet__send", disabled: text3.trim().length === 0 || controls.busy, children: renaming ? "Rename" : "Report" })
9600
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "mx-meet__menu-actions", children: [
9601
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("button", { type: "button", className: "mx-meet__link", onClick: () => setMode("menu"), children: "Back" }),
9602
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("button", { type: "submit", className: "mx-meet__send", disabled: text3.trim().length === 0 || controls.busy, children: renaming ? "Rename" : "Report" })
7921
9603
  ] })
7922
9604
  ]
7923
9605
  }
@@ -7925,12 +9607,12 @@ function PersonMenu({
7925
9607
  }
7926
9608
  if (mode === "remove" || mode === "transfer") {
7927
9609
  const removing = mode === "remove";
7928
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Popover, { label: removing ? "Remove" : "Make host", onClose, placement, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "mx-meet__menu-form", children: [
7929
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("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.` }),
9610
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Popover, { label: removing ? "Remove" : "Make host", onClose, placement, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "mx-meet__menu-form", children: [
9611
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("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.` }),
7930
9612
  refusal2,
7931
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "mx-meet__menu-actions", children: [
7932
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("button", { type: "button", className: "mx-meet__link", onClick: () => setMode("menu"), children: "Cancel" }),
7933
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
9613
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "mx-meet__menu-actions", children: [
9614
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("button", { type: "button", className: "mx-meet__link", onClick: () => setMode("menu"), children: "Cancel" }),
9615
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
7934
9616
  "button",
7935
9617
  {
7936
9618
  type: "button",
@@ -7943,8 +9625,8 @@ function PersonMenu({
7943
9625
  ] })
7944
9626
  ] }) });
7945
9627
  }
7946
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Popover, { label: `Options for ${participant.displayName}`, onClose, placement, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "mx-meet__menu", role: "menu", children: [
7947
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
9628
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Popover, { label: `Options for ${participant.displayName}`, onClose, placement, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "mx-meet__menu", role: "menu", children: [
9629
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
7948
9630
  MenuItem,
7949
9631
  {
7950
9632
  onSelect: () => {
@@ -7952,13 +9634,13 @@ function PersonMenu({
7952
9634
  onClose();
7953
9635
  },
7954
9636
  children: [
7955
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(PinIcon, { width: 16, height: 16 }),
9637
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(PinIcon, { width: 16, height: 16 }),
7956
9638
  " ",
7957
9639
  pinned ? "Unpin" : "Pin for me"
7958
9640
  ]
7959
9641
  }
7960
9642
  ),
7961
- !self && !participant.isAgent && (onMessage !== void 0 || host !== null) ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
9643
+ !self && !participant.isAgent && (onMessage !== void 0 || host !== null) ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
7962
9644
  MenuItem,
7963
9645
  {
7964
9646
  onSelect: () => {
@@ -7970,42 +9652,42 @@ function PersonMenu({
7970
9652
  onClose();
7971
9653
  },
7972
9654
  children: [
7973
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(ChatIcon, { width: 16, height: 16 }),
9655
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(ChatIcon, { width: 16, height: 16 }),
7974
9656
  " Message privately"
7975
9657
  ]
7976
9658
  }
7977
9659
  ) : null,
7978
- controls.isHost ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(MenuItem, { onSelect: () => act({ action: "spotlight", identity: spotlit ? null : participant.identity }), children: [
7979
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(SpotlightIcon, { width: 16, height: 16 }),
9660
+ controls.isHost ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(MenuItem, { onSelect: () => act({ action: "spotlight", identity: spotlit ? null : participant.identity }), children: [
9661
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(SpotlightIcon, { width: 16, height: 16 }),
7980
9662
  " ",
7981
9663
  spotlit ? "Remove spotlight" : "Spotlight for everyone"
7982
9664
  ] }) : null,
7983
- moderate ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_jsx_runtime3.Fragment, { children: [
7984
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "mx-meet__menu-sep", role: "separator" }),
7985
- participant.micEnabled ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(MenuItem, { onSelect: () => act({ action: "mute", identity: participant.identity }), children: [
7986
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(MicOffIcon, { width: 16, height: 16 }),
9665
+ moderate ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_jsx_runtime4.Fragment, { children: [
9666
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "mx-meet__menu-sep", role: "separator" }),
9667
+ participant.micEnabled ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(MenuItem, { onSelect: () => act({ action: "mute", identity: participant.identity }), children: [
9668
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(MicOffIcon, { width: 16, height: 16 }),
7987
9669
  " Mute"
7988
- ] }) : !participant.isAgent ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(MenuItem, { onSelect: () => act({ action: "ask_unmute", identity: participant.identity }), children: [
7989
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(MicIcon, { width: 16, height: 16 }),
9670
+ ] }) : !participant.isAgent ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(MenuItem, { onSelect: () => act({ action: "ask_unmute", identity: participant.identity }), children: [
9671
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(MicIcon, { width: 16, height: 16 }),
7990
9672
  " Ask to unmute"
7991
9673
  ] }) : null,
7992
- participant.cameraEnabled ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(MenuItem, { onSelect: () => act({ action: "stop_video", identity: participant.identity }), children: [
7993
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(CameraOffIcon, { width: 16, height: 16 }),
9674
+ participant.cameraEnabled ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(MenuItem, { onSelect: () => act({ action: "stop_video", identity: participant.identity }), children: [
9675
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(CameraOffIcon, { width: 16, height: 16 }),
7994
9676
  " Stop video"
7995
9677
  ] }) : null,
7996
- participant.screenSharing ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(MenuItem, { onSelect: () => act({ action: "stop_screen", identity: participant.identity }), children: [
7997
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(ScreenShareIcon, { width: 16, height: 16 }),
9678
+ participant.screenSharing ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(MenuItem, { onSelect: () => act({ action: "stop_screen", identity: participant.identity }), children: [
9679
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(ScreenShareIcon, { width: 16, height: 16 }),
7998
9680
  " Stop screen share"
7999
9681
  ] }) : null,
8000
- participant.handRaised ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(MenuItem, { onSelect: () => act({ action: "lower_hand", identity: participant.identity }), children: [
8001
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(HandIcon, { width: 16, height: 16 }),
9682
+ participant.handRaised ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(MenuItem, { onSelect: () => act({ action: "lower_hand", identity: participant.identity }), children: [
9683
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(HandIcon, { width: 16, height: 16 }),
8002
9684
  " Lower hand"
8003
9685
  ] }) : null,
8004
- hasAccount && !participant.isAgent && participant.role !== "cohost" ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(MenuItem, { onSelect: () => act({ action: "make_cohost", identity: participant.identity }), children: [
8005
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(PeopleIcon, { width: 16, height: 16 }),
9686
+ hasAccount && !participant.isAgent && participant.role !== "cohost" ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(MenuItem, { onSelect: () => act({ action: "make_cohost", identity: participant.identity }), children: [
9687
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(PeopleIcon, { width: 16, height: 16 }),
8006
9688
  " Make co-host"
8007
9689
  ] }) : null,
8008
- !participant.isAgent ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
9690
+ !participant.isAgent ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
8009
9691
  MenuItem,
8010
9692
  {
8011
9693
  onSelect: () => {
@@ -8013,21 +9695,21 @@ function PersonMenu({
8013
9695
  setMode("rename");
8014
9696
  },
8015
9697
  children: [
8016
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(PencilIcon, { width: 16, height: 16 }),
9698
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(PencilIcon, { width: 16, height: 16 }),
8017
9699
  " Rename"
8018
9700
  ]
8019
9701
  }
8020
9702
  ) : null
8021
9703
  ] }) : null,
8022
- controls.isOwner && participant.role === "cohost" ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(MenuItem, { onSelect: () => act({ action: "revoke_cohost", identity: participant.identity }), children: [
8023
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(PeopleIcon, { width: 16, height: 16 }),
9704
+ controls.isOwner && participant.role === "cohost" ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(MenuItem, { onSelect: () => act({ action: "revoke_cohost", identity: participant.identity }), children: [
9705
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(PeopleIcon, { width: 16, height: 16 }),
8024
9706
  " Remove co-host"
8025
9707
  ] }) : null,
8026
- controls.isOwner && !self && hasAccount && !participant.isAgent ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(MenuItem, { onSelect: () => setMode("transfer"), children: [
8027
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(SpotlightIcon, { width: 16, height: 16 }),
9708
+ controls.isOwner && !self && hasAccount && !participant.isAgent ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(MenuItem, { onSelect: () => setMode("transfer"), children: [
9709
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(SpotlightIcon, { width: 16, height: 16 }),
8028
9710
  " Make host"
8029
9711
  ] }) : null,
8030
- self ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
9712
+ self ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
8031
9713
  MenuItem,
8032
9714
  {
8033
9715
  onSelect: () => {
@@ -8035,12 +9717,12 @@ function PersonMenu({
8035
9717
  setMode("rename");
8036
9718
  },
8037
9719
  children: [
8038
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(PencilIcon, { width: 16, height: 16 }),
9720
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(PencilIcon, { width: 16, height: 16 }),
8039
9721
  " Rename yourself"
8040
9722
  ]
8041
9723
  }
8042
9724
  ) : null,
8043
- !self && !participant.isAgent ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
9725
+ !self && !participant.isAgent ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
8044
9726
  MenuItem,
8045
9727
  {
8046
9728
  onSelect: () => {
@@ -8048,21 +9730,21 @@ function PersonMenu({
8048
9730
  setMode("report");
8049
9731
  },
8050
9732
  children: [
8051
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(FlagIcon, { width: 16, height: 16 }),
9733
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(FlagIcon, { width: 16, height: 16 }),
8052
9734
  " Report"
8053
9735
  ]
8054
9736
  }
8055
9737
  ) : null,
8056
- moderate && !participant.isAgent ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(MenuItem, { danger: true, onSelect: () => setMode("remove"), children: [
8057
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(CloseIcon, { width: 16, height: 16 }),
9738
+ moderate && !participant.isAgent ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(MenuItem, { danger: true, onSelect: () => setMode("remove"), children: [
9739
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(CloseIcon, { width: 16, height: 16 }),
8058
9740
  " Remove from meeting"
8059
9741
  ] }) : null
8060
9742
  ] }) });
8061
9743
  }
8062
9744
  function SettingsPanel({ onClose }) {
8063
9745
  const host = useRequiredMeetHost();
8064
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(PanelShell, { title: "Audio, video and effects", onClose, children: [
8065
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
9746
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(PanelShell, { title: "Settings", onClose, children: [
9747
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
8066
9748
  DeviceSettings,
8067
9749
  {
8068
9750
  onPick: (kind, deviceId2) => {
@@ -8071,7 +9753,8 @@ function SettingsPanel({ onClose }) {
8071
9753
  }
8072
9754
  }
8073
9755
  ),
8074
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(EffectsSettings, {})
9756
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(EffectsSettings, {}),
9757
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(CaptionLanguageSettings, {})
8075
9758
  ] });
8076
9759
  }
8077
9760
  function DeviceSettings({
@@ -8083,15 +9766,15 @@ function DeviceSettings({
8083
9766
  const speaker = devices?.selected.audiooutput ?? host.devices.resolve("audiooutput");
8084
9767
  const stream = useMicrophoneStream(microphone);
8085
9768
  const level = useAudioLevel(stream);
8086
- const [testing, setTesting] = (0, import_react4.useState)(false);
8087
- (0, import_react4.useEffect)(() => {
9769
+ const [testing, setTesting] = (0, import_react5.useState)(false);
9770
+ (0, import_react5.useEffect)(() => {
8088
9771
  void host.devices.refresh();
8089
9772
  }, [host]);
8090
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("section", { className: "mx-meet__section", "aria-label": "Devices", children: [
8091
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(DevicePicker, { kind: "audioinput", label: "Microphone", onPick }),
8092
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("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__ */ (0, import_jsx_runtime3.jsx)("span", { style: { width: `${Math.min(100, Math.round(level * 160))}%` } }) }),
8093
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(DevicePicker, { kind: "audiooutput", label: "Speaker", onPick }),
8094
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
9773
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("section", { className: "mx-meet__section", "aria-label": "Devices", children: [
9774
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(DevicePicker, { kind: "audioinput", label: "Microphone", onPick }),
9775
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("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__ */ (0, import_jsx_runtime4.jsx)("span", { style: { width: `${Math.min(100, Math.round(level * 160))}%` } }) }),
9776
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(DevicePicker, { kind: "audiooutput", label: "Speaker", onPick }),
9777
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
8095
9778
  "button",
8096
9779
  {
8097
9780
  type: "button",
@@ -8102,19 +9785,19 @@ function DeviceSettings({
8102
9785
  void playTestSound(speaker).finally(() => setTesting(false));
8103
9786
  },
8104
9787
  children: [
8105
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(SpeakerIcon, { width: 14, height: 14 }),
9788
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(SpeakerIcon, { width: 14, height: 14 }),
8106
9789
  " ",
8107
9790
  testing ? "Playing\u2026" : "Test speaker"
8108
9791
  ]
8109
9792
  }
8110
9793
  ),
8111
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(DevicePicker, { kind: "videoinput", label: "Camera", onPick })
9794
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(DevicePicker, { kind: "videoinput", label: "Camera", onPick })
8112
9795
  ] });
8113
9796
  }
8114
9797
  function EffectsSettings({ preview }) {
8115
9798
  const effects = useMediaEffects();
8116
- const [error, setError] = (0, import_react4.useState)(null);
8117
- const fileRef = (0, import_react4.useRef)(null);
9799
+ const [error, setError] = (0, import_react5.useState)(null);
9800
+ const fileRef = (0, import_react5.useRef)(null);
8118
9801
  const supported = effects.backgroundsSupported || preview != null || videoEffectsSupported();
8119
9802
  const apply = (next) => {
8120
9803
  setError(null);
@@ -8126,9 +9809,9 @@ function EffectsSettings({ preview }) {
8126
9809
  );
8127
9810
  }
8128
9811
  };
8129
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("section", { className: "mx-meet__section", "aria-label": "Effects", children: [
8130
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("label", { className: "mx-meet__toggle", children: [
8131
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
9812
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("section", { className: "mx-meet__section", "aria-label": "Effects", children: [
9813
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("label", { className: "mx-meet__toggle", children: [
9814
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
8132
9815
  "input",
8133
9816
  {
8134
9817
  type: "checkbox",
@@ -8137,11 +9820,11 @@ function EffectsSettings({ preview }) {
8137
9820
  }
8138
9821
  ),
8139
9822
  "Noise suppression",
8140
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "mx-meet__hint", children: "Filters keyboards, fans and background chatter." })
9823
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "mx-meet__hint", children: "Filters keyboards, fans and background chatter." })
8141
9824
  ] }),
8142
- supported ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "mx-meet__field", children: [
8143
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "mx-meet__field-label", children: "Background" }),
8144
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "mx-meet__pills", role: "radiogroup", "aria-label": "Background", children: ["none", "blur", "image"].map((kind) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
9825
+ supported ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "mx-meet__field", children: [
9826
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "mx-meet__field-label", children: "Background" }),
9827
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "mx-meet__pills", role: "radiogroup", "aria-label": "Background", children: ["none", "blur", "image"].map((kind) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
8145
9828
  "button",
8146
9829
  {
8147
9830
  type: "button",
@@ -8159,7 +9842,7 @@ function EffectsSettings({ preview }) {
8159
9842
  },
8160
9843
  kind
8161
9844
  )) }),
8162
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
9845
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
8163
9846
  "input",
8164
9847
  {
8165
9848
  ref: fileRef,
@@ -8174,7 +9857,7 @@ function EffectsSettings({ preview }) {
8174
9857
  }
8175
9858
  }
8176
9859
  ),
8177
- error !== null ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "mx-meet__error", children: error }) : null
9860
+ error !== null ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { className: "mx-meet__error", children: error }) : null
8178
9861
  ] }) : null
8179
9862
  ] });
8180
9863
  }
@@ -8233,8 +9916,8 @@ async function playTestSound(sinkId) {
8233
9916
  await context.close();
8234
9917
  }
8235
9918
  function useMicrophoneStream(deviceId2) {
8236
- const [stream, setStream] = (0, import_react4.useState)(null);
8237
- (0, import_react4.useEffect)(() => {
9919
+ const [stream, setStream] = (0, import_react5.useState)(null);
9920
+ (0, import_react5.useEffect)(() => {
8238
9921
  if (deviceId2 === "off") return void 0;
8239
9922
  let live = true;
8240
9923
  let opened = null;
@@ -8259,25 +9942,25 @@ function useMicrophoneStream(deviceId2) {
8259
9942
  function LobbyPanel() {
8260
9943
  const lobby = useLobby();
8261
9944
  if (!lobby.canAdmit || lobby.waiting.length === 0) return null;
8262
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("section", { className: "mx-meet__lobby", "aria-label": "Waiting room", children: [
8263
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("header", { className: "mx-meet__lobby-head", children: [
8264
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("h3", { className: "mx-meet__lobby-title", children: lobby.waiting.length === 1 ? "1 person is waiting" : `${lobby.waiting.length} people are waiting` }),
8265
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("button", { type: "button", className: "mx-meet__link", onClick: () => void lobby.admitAll(), children: "Admit all" })
9945
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("section", { className: "mx-meet__lobby", "aria-label": "Waiting room", children: [
9946
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("header", { className: "mx-meet__lobby-head", children: [
9947
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("h3", { className: "mx-meet__lobby-title", children: lobby.waiting.length === 1 ? "1 person is waiting" : `${lobby.waiting.length} people are waiting` }),
9948
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("button", { type: "button", className: "mx-meet__link", onClick: () => void lobby.admitAll(), children: "Admit all" })
8266
9949
  ] }),
8267
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("ul", { className: "mx-meet__lobby-list", children: lobby.waiting.map((entry) => /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("li", { className: "mx-meet__lobby-row", children: [
8268
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Avatar, { name: entry.displayName, url: entry.avatarUrl, size: 32 }),
8269
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("span", { className: "mx-meet__person-name", children: [
9950
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("ul", { className: "mx-meet__lobby-list", children: lobby.waiting.map((entry) => /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("li", { className: "mx-meet__lobby-row", children: [
9951
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Avatar, { name: entry.displayName, url: entry.avatarUrl, size: 32 }),
9952
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("span", { className: "mx-meet__person-name", children: [
8270
9953
  entry.displayName,
8271
- entry.userId === null ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "mx-meet__badge", children: "Guest" }) : null
9954
+ entry.userId === null ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "mx-meet__badge", children: "Guest" }) : null
8272
9955
  ] }),
8273
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(ControlButton, { label: `Admit ${entry.displayName}`, onClick: () => void lobby.admit(entry), children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(CheckIcon, { width: 16, height: 16 }) }),
8274
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
9956
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(ControlButton, { label: `Admit ${entry.displayName}`, onClick: () => void lobby.admit(entry), children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(CheckIcon, { width: 16, height: 16 }) }),
9957
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
8275
9958
  ControlButton,
8276
9959
  {
8277
9960
  label: `Deny ${entry.displayName}`,
8278
9961
  danger: true,
8279
9962
  onClick: () => void lobby.deny(entry),
8280
- children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(CloseIcon, { width: 16, height: 16 })
9963
+ children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(CloseIcon, { width: 16, height: 16 })
8281
9964
  }
8282
9965
  )
8283
9966
  ] }, entry.identity)) })
@@ -8287,21 +9970,21 @@ function NoteTakerRow() {
8287
9970
  const ai = useMeetAi();
8288
9971
  const status = ai.noteTaker;
8289
9972
  const duplicateError = status.refusal !== null && ai.error !== null && status.refusal.reason === ai.error.message && status.refusal.remedy === ai.error.remedy;
8290
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("section", { className: "mx-meet__note-taker", "aria-label": "Note-taker", children: [
8291
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("p", { className: `mx-meet__note-taker-state mx-meet__note-taker-state--${status.state}`, children: [
8292
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "mx-meet__note-taker-dot", "aria-hidden": "true" }),
9973
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("section", { className: "mx-meet__note-taker", "aria-label": "Note-taker", children: [
9974
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("p", { className: `mx-meet__note-taker-state mx-meet__note-taker-state--${status.state}`, children: [
9975
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "mx-meet__note-taker-dot", "aria-hidden": "true" }),
8293
9976
  ai.noteTakerLabel
8294
9977
  ] }),
8295
- status.detail !== null ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "mx-meet__panel-note", children: status.detail }) : null,
8296
- status.refusal !== null ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_design_system.ErrorBox, { as: "div", className: "mx-meet__refusal", error: status.refusal, operation: "Join this meeting", origin: "meet/components", children: [
8297
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "mx-meet__refusal-reason", children: status.refusal.reason }),
8298
- status.refusal.remedy.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "mx-meet__refusal-remedy", children: status.refusal.remedy }) : null
9978
+ status.detail !== null ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { className: "mx-meet__panel-note", children: status.detail }) : null,
9979
+ status.refusal !== null ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_design_system.ErrorBox, { as: "div", className: "mx-meet__refusal", error: status.refusal, operation: "Join this meeting", origin: "meet/components", children: [
9980
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { className: "mx-meet__refusal-reason", children: status.refusal.reason }),
9981
+ status.refusal.remedy.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { className: "mx-meet__refusal-remedy", children: status.refusal.remedy }) : null
8299
9982
  ] }) : null,
8300
- ai.error !== null && !duplicateError ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_design_system.ErrorBox, { as: "div", className: "mx-meet__refusal", error: ai.error, operation: "Run the meeting assistant", origin: "meet/components", children: [
8301
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "mx-meet__refusal-reason", children: ai.error.message }),
8302
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "mx-meet__refusal-remedy", children: ai.error.remedy })
9983
+ ai.error !== null && !duplicateError ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_design_system.ErrorBox, { as: "div", className: "mx-meet__refusal", error: ai.error, operation: "Run the meeting assistant", origin: "meet/components", children: [
9984
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { className: "mx-meet__refusal-reason", children: ai.error.message }),
9985
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { className: "mx-meet__refusal-remedy", children: ai.error.remedy })
8303
9986
  ] }) : null,
8304
- ai.canControlNoteTaker ? status.state === "transcribing" || status.state === "joining" || status.state === "handoff_pending" ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
9987
+ ai.canControlNoteTaker ? status.state === "transcribing" || status.state === "joining" || status.state === "handoff_pending" ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
8305
9988
  "button",
8306
9989
  {
8307
9990
  type: "button",
@@ -8309,7 +9992,7 @@ function NoteTakerRow() {
8309
9992
  onClick: () => void ai.stopNoteTaker(),
8310
9993
  children: "Dismiss the note-taker"
8311
9994
  }
8312
- ) : /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
9995
+ ) : /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
8313
9996
  "button",
8314
9997
  {
8315
9998
  type: "button",
@@ -8325,24 +10008,24 @@ function NoteList({
8325
10008
  notes,
8326
10009
  empty
8327
10010
  }) {
8328
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("section", { className: "mx-meet__note-group", "aria-label": title, children: [
8329
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("h3", { className: "mx-meet__note-group-title", children: title }),
8330
- notes.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "mx-meet__panel-note", children: empty }) : /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("ul", { className: "mx-meet__notes", children: notes.map((note) => /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("li", { className: "mx-meet__note", children: [
10011
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("section", { className: "mx-meet__note-group", "aria-label": title, children: [
10012
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("h3", { className: "mx-meet__note-group-title", children: title }),
10013
+ notes.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { className: "mx-meet__panel-note", children: empty }) : /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("ul", { className: "mx-meet__notes", children: notes.map((note) => /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("li", { className: "mx-meet__note", children: [
8331
10014
  note.text,
8332
- note.assigneeDisplayName !== void 0 && note.assigneeDisplayName !== null ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "mx-meet__assignee", children: note.assigneeDisplayName }) : null
10015
+ note.assigneeDisplayName !== void 0 && note.assigneeDisplayName !== null ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "mx-meet__assignee", children: note.assigneeDisplayName }) : null
8333
10016
  ] }, note.id)) })
8334
10017
  ] });
8335
10018
  }
8336
10019
  function AiPanel({ onClose }) {
8337
10020
  const ai = useMeetAi();
8338
- const [question, setQuestion] = (0, import_react4.useState)("");
8339
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(PanelShell, { title: "Meeting assistant", onClose, children: [
8340
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(NoteTakerRow, {}),
8341
- ai.summary !== null ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("section", { className: "mx-meet__note-group", "aria-label": "Summary", children: [
8342
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("h3", { className: "mx-meet__note-group-title", children: "Summary" }),
8343
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "mx-meet__summary", children: ai.summary.text })
10021
+ const [question, setQuestion] = (0, import_react5.useState)("");
10022
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(PanelShell, { title: "Meeting assistant", onClose, children: [
10023
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(NoteTakerRow, {}),
10024
+ ai.summary !== null ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("section", { className: "mx-meet__note-group", "aria-label": "Summary", children: [
10025
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("h3", { className: "mx-meet__note-group-title", children: "Summary" }),
10026
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { className: "mx-meet__summary", children: ai.summary.text })
8344
10027
  ] }) : null,
8345
- ai.wrapUp !== null ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("p", { className: "mx-meet__wrap-up-notice", role: "status", children: [
10028
+ ai.wrapUp !== null ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("p", { className: "mx-meet__wrap-up-notice", role: "status", children: [
8346
10029
  "The wrap-up is written \u2014 ",
8347
10030
  ai.wrapUp.noteIds.length,
8348
10031
  " ",
@@ -8354,7 +10037,7 @@ function AiPanel({ onClose }) {
8354
10037
  ai.wrapUp.segmentCount === 1 ? "transcript line" : "transcript lines",
8355
10038
  "."
8356
10039
  ] }) : null,
8357
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
10040
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
8358
10041
  NoteList,
8359
10042
  {
8360
10043
  title: "Notes",
@@ -8362,7 +10045,7 @@ function AiPanel({ onClose }) {
8362
10045
  empty: "Notes appear here as the meeting goes on."
8363
10046
  }
8364
10047
  ),
8365
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
10048
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
8366
10049
  NoteList,
8367
10050
  {
8368
10051
  title: "Decisions",
@@ -8370,7 +10053,7 @@ function AiPanel({ onClose }) {
8370
10053
  empty: "Nothing has been decided yet."
8371
10054
  }
8372
10055
  ),
8373
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
10056
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
8374
10057
  NoteList,
8375
10058
  {
8376
10059
  title: "Action items",
@@ -8378,21 +10061,21 @@ function AiPanel({ onClose }) {
8378
10061
  empty: "No action items yet."
8379
10062
  }
8380
10063
  ),
8381
- ai.transcript.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("section", { className: "mx-meet__note-group", "aria-label": "Transcript", children: [
8382
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("h3", { className: "mx-meet__note-group-title", children: "Transcript" }),
8383
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("ul", { className: "mx-meet__transcript", children: ai.transcript.map((line) => /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
10064
+ ai.transcript.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("section", { className: "mx-meet__note-group", "aria-label": "Transcript", children: [
10065
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("h3", { className: "mx-meet__note-group-title", children: "Transcript" }),
10066
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("ul", { className: "mx-meet__transcript", children: ai.transcript.map((line) => /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
8384
10067
  "li",
8385
10068
  {
8386
10069
  className: line.final && line.source === "record" ? "mx-meet__line" : "mx-meet__line mx-meet__line--interim",
8387
10070
  children: [
8388
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("strong", { children: line.speaker }),
8389
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { children: line.text })
10071
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("strong", { children: line.speaker }),
10072
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { children: line.text })
8390
10073
  ]
8391
10074
  },
8392
10075
  line.id
8393
10076
  )) })
8394
10077
  ] }) : null,
8395
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
10078
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
8396
10079
  "form",
8397
10080
  {
8398
10081
  className: "mx-meet__composer",
@@ -8403,7 +10086,7 @@ function AiPanel({ onClose }) {
8403
10086
  void ai.ask(asked);
8404
10087
  },
8405
10088
  children: [
8406
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
10089
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
8407
10090
  "input",
8408
10091
  {
8409
10092
  className: "mx-meet__input",
@@ -8413,13 +10096,13 @@ function AiPanel({ onClose }) {
8413
10096
  "aria-label": "Ask about this meeting"
8414
10097
  }
8415
10098
  ),
8416
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("button", { type: "submit", className: "mx-meet__send", disabled: ai.asking, children: ai.asking ? "Asking\u2026" : "Ask" })
10099
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("button", { type: "submit", className: "mx-meet__send", disabled: ai.asking, children: ai.asking ? "Asking\u2026" : "Ask" })
8417
10100
  ]
8418
10101
  }
8419
10102
  ),
8420
- ai.asking && ai.phase !== null ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "mx-meet__panel-note", role: "status", children: ai.phase }) : null,
8421
- ai.answer !== null ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "mx-meet__answer", children: ai.answer }) : null,
8422
- ai.answer !== null && ai.coverage !== null ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("p", { className: "mx-meet__coverage", children: [
10103
+ ai.asking && ai.phase !== null ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { className: "mx-meet__panel-note", role: "status", children: ai.phase }) : null,
10104
+ ai.answer !== null ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { className: "mx-meet__answer", children: ai.answer }) : null,
10105
+ ai.answer !== null && ai.coverage !== null ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("p", { className: "mx-meet__coverage", children: [
8423
10106
  "Answered from ",
8424
10107
  ai.coverage.segmentsUsed,
8425
10108
  " of ",
@@ -8428,48 +10111,56 @@ function AiPanel({ onClose }) {
8428
10111
  ai.coverage.truncated ? " (the oldest were left out)" : "",
8429
10112
  "."
8430
10113
  ] }) : null,
8431
- ai.error !== null ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_design_system.ErrorBox, { as: "div", className: "mx-meet__refusal", error: ai.error, operation: "Run the meeting assistant", origin: "meet/components", children: [
8432
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "mx-meet__refusal-reason", children: ai.error.message }),
8433
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "mx-meet__refusal-remedy", children: ai.error.remedy })
10114
+ ai.error !== null ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_design_system.ErrorBox, { as: "div", className: "mx-meet__refusal", error: ai.error, operation: "Run the meeting assistant", origin: "meet/components", children: [
10115
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { className: "mx-meet__refusal-reason", children: ai.error.message }),
10116
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { className: "mx-meet__refusal-remedy", children: ai.error.remedy })
8434
10117
  ] }) : null
8435
10118
  ] });
8436
10119
  }
8437
10120
  function Captions({ lines = 3 }) {
8438
10121
  const ai = useMeetAi();
8439
10122
  const visible = ai.transcript.slice(-lines);
10123
+ const translation = useCaptionTranslation(visible);
8440
10124
  if (visible.length === 0) return null;
8441
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "mx-meet__captions", "aria-live": "polite", "aria-label": "Live captions", children: visible.map((line) => /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
8442
- "p",
8443
- {
8444
- className: line.final ? "mx-meet__caption" : "mx-meet__caption mx-meet__caption--interim",
8445
- children: [
8446
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("strong", { children: line.speaker }),
8447
- " ",
8448
- line.text
8449
- ]
8450
- },
8451
- line.id
8452
- )) });
10125
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "mx-meet__captions", "aria-live": "polite", "aria-label": "Live captions", children: [
10126
+ visible.map((line) => {
10127
+ const translated = translation.language === null ? void 0 : translation.translations[line.id];
10128
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
10129
+ "p",
10130
+ {
10131
+ className: line.final ? "mx-meet__caption" : "mx-meet__caption mx-meet__caption--interim",
10132
+ children: [
10133
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("strong", { children: line.speaker }),
10134
+ " ",
10135
+ translated ?? line.text,
10136
+ translated !== void 0 ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "mx-meet__caption-original", children: line.text }) : null
10137
+ ]
10138
+ },
10139
+ line.id
10140
+ );
10141
+ }),
10142
+ translation.language !== null && translation.error !== null ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { className: "mx-meet__caption mx-meet__caption--interim", children: translation.error }) : null
10143
+ ] });
8453
10144
  }
8454
10145
  function ConsentNotice() {
8455
10146
  const notice = useConsentNotice();
8456
10147
  if (notice === null) return null;
8457
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "mx-meet__consent", role: "status", children: notice });
10148
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { className: "mx-meet__consent", role: "status", children: notice });
8458
10149
  }
8459
10150
  function AttendanceNotice() {
8460
10151
  const media = useLocalMedia();
8461
10152
  const notice = listenOnlyNotice(media);
8462
10153
  if (notice === null) return null;
8463
10154
  const refused = media.microphone.unavailable;
8464
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("p", { className: "mx-meet__banner mx-meet__banner--attendance", role: "status", children: [
10155
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("p", { className: "mx-meet__banner mx-meet__banner--attendance", role: "status", children: [
8465
10156
  notice,
8466
- refused === null ? null : /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "mx-meet__remedy", children: refused.remedy })
10157
+ refused === null ? null : /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "mx-meet__remedy", children: refused.remedy })
8467
10158
  ] });
8468
10159
  }
8469
10160
  function PreJoin(props) {
8470
10161
  const host = useMeetHost();
8471
- if (host === null) return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(InertNotice, { what: "This meeting" });
8472
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(PreJoinBody, { ...props, host });
10162
+ if (host === null) return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(InertNotice, { what: "This meeting" });
10163
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(PreJoinBody, { ...props, host });
8473
10164
  }
8474
10165
  function PreJoinBody({
8475
10166
  roomName,
@@ -8483,21 +10174,21 @@ function PreJoinBody({
8483
10174
  const recording = useRecording();
8484
10175
  const effects = useMediaEffects();
8485
10176
  const { notice } = useModerationNotice();
8486
- const [mode, setMode] = (0, import_react4.useState)("video");
8487
- const [microphone, setMicrophone] = (0, import_react4.useState)(true);
8488
- const [joining, setJoining] = (0, import_react4.useState)(false);
10177
+ const [mode, setMode] = (0, import_react5.useState)("video");
10178
+ const [microphone, setMicrophone] = (0, import_react5.useState)(true);
10179
+ const [joining, setJoining] = (0, import_react5.useState)(false);
8489
10180
  const camera = devices?.selected.videoinput ?? host.devices.resolve("videoinput");
8490
10181
  const mic = devices?.selected.audioinput ?? host.devices.resolve("audioinput");
8491
10182
  const preview = useCameraPreview(mode === "video" ? camera : void 0, effects.effects);
8492
10183
  const micStream = useMicrophoneStream(microphone ? mic : "off");
8493
10184
  const level = useAudioLevel(micStream);
8494
- const [speakerTesting, setSpeakerTesting] = (0, import_react4.useState)(false);
8495
- (0, import_react4.useEffect)(() => {
10185
+ const [speakerTesting, setSpeakerTesting] = (0, import_react5.useState)(false);
10186
+ (0, import_react5.useEffect)(() => {
8496
10187
  void host.devices.refresh();
8497
10188
  }, [host]);
8498
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "mx-meet__prejoin", children: [
8499
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "mx-meet__preview", children: [
8500
- mode === "video" && preview.preview !== null ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
10189
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "mx-meet__prejoin", children: [
10190
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "mx-meet__preview", children: [
10191
+ mode === "video" && preview.preview !== null ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
8501
10192
  "video",
8502
10193
  {
8503
10194
  className: "mx-meet__video mx-meet__video--mirror",
@@ -8508,16 +10199,16 @@ function PreJoinBody({
8508
10199
  if (element !== null) preview.preview?.attach(element);
8509
10200
  }
8510
10201
  }
8511
- ) : /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "mx-meet__tile-placeholder", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Avatar, { name: host.identity.displayName, url: host.identity.avatarUrl, size: 96 }) }),
8512
- mode === "video" && preview.error !== null ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "mx-meet__preview-note", children: preview.error }) : null,
8513
- microphone && micStream !== null ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("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__ */ (0, import_jsx_runtime3.jsx)("span", { style: { width: `${Math.min(100, Math.round(level * 160))}%` } }) }) : null
10202
+ ) : /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "mx-meet__tile-placeholder", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Avatar, { name: host.identity.displayName, url: host.identity.avatarUrl, size: 96 }) }),
10203
+ mode === "video" && preview.error !== null ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { className: "mx-meet__preview-note", children: preview.error }) : null,
10204
+ microphone && micStream !== null ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("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__ */ (0, import_jsx_runtime4.jsx)("span", { style: { width: `${Math.min(100, Math.round(level * 160))}%` } }) }) : null
8514
10205
  ] }),
8515
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "mx-meet__prejoin-panel", children: [
8516
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("h1", { className: "mx-meet__prejoin-title", children: "Ready to join?" }),
8517
- notice?.kind === "removed" ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "mx-meet__warning", children: notice.text }) : null,
8518
- devices?.labelsHidden === true ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("p", { className: "mx-meet__panel-note", children: [
10206
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "mx-meet__prejoin-panel", children: [
10207
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("h1", { className: "mx-meet__prejoin-title", children: "Ready to join?" }),
10208
+ notice?.kind === "removed" ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { className: "mx-meet__warning", children: notice.text }) : null,
10209
+ devices?.labelsHidden === true ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("p", { className: "mx-meet__panel-note", children: [
8519
10210
  "Your browser is hiding device names until you allow camera and microphone access.",
8520
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
10211
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
8521
10212
  "button",
8522
10213
  {
8523
10214
  type: "button",
@@ -8529,11 +10220,11 @@ function PreJoinBody({
8529
10220
  }
8530
10221
  )
8531
10222
  ] }) : null,
8532
- devices?.fallbackNotice != null ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "mx-meet__warning", children: devices.fallbackNotice }) : null,
8533
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(DevicePicker, { kind: "audioinput", label: "Microphone" }),
8534
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "mx-meet__field-row", children: [
8535
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(DevicePicker, { kind: "audiooutput", label: "Speaker" }),
8536
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
10223
+ devices?.fallbackNotice != null ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { className: "mx-meet__warning", children: devices.fallbackNotice }) : null,
10224
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(DevicePicker, { kind: "audioinput", label: "Microphone" }),
10225
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "mx-meet__field-row", children: [
10226
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(DevicePicker, { kind: "audiooutput", label: "Speaker" }),
10227
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
8537
10228
  "button",
8538
10229
  {
8539
10230
  type: "button",
@@ -8546,19 +10237,19 @@ function PreJoinBody({
8546
10237
  );
8547
10238
  },
8548
10239
  children: [
8549
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(SpeakerIcon, { width: 14, height: 14 }),
10240
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(SpeakerIcon, { width: 14, height: 14 }),
8550
10241
  " ",
8551
10242
  speakerTesting ? "Playing\u2026" : "Test"
8552
10243
  ]
8553
10244
  }
8554
10245
  )
8555
10246
  ] }),
8556
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(DevicePicker, { kind: "videoinput", label: "Camera" }),
8557
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(EffectsSettings, { preview: preview.preview }),
8558
- recording.consentNotice !== null ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "mx-meet__consent", children: recording.consentNotice }) : null,
8559
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "mx-meet__prejoin-actions", children: [
8560
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("label", { className: "mx-meet__toggle", children: [
8561
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
10247
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(DevicePicker, { kind: "videoinput", label: "Camera" }),
10248
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(EffectsSettings, { preview: preview.preview }),
10249
+ recording.consentNotice !== null ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { className: "mx-meet__consent", children: recording.consentNotice }) : null,
10250
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "mx-meet__prejoin-actions", children: [
10251
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("label", { className: "mx-meet__toggle", children: [
10252
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
8562
10253
  "input",
8563
10254
  {
8564
10255
  type: "checkbox",
@@ -8568,8 +10259,8 @@ function PreJoinBody({
8568
10259
  ),
8569
10260
  "Join with video"
8570
10261
  ] }),
8571
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("label", { className: "mx-meet__toggle", children: [
8572
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
10262
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("label", { className: "mx-meet__toggle", children: [
10263
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
8573
10264
  "input",
8574
10265
  {
8575
10266
  type: "checkbox",
@@ -8579,7 +10270,7 @@ function PreJoinBody({
8579
10270
  ),
8580
10271
  "Join with microphone"
8581
10272
  ] }),
8582
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
10273
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
8583
10274
  "button",
8584
10275
  {
8585
10276
  type: "button",
@@ -8599,20 +10290,20 @@ function PreJoinBody({
8599
10290
  }
8600
10291
  )
8601
10292
  ] }),
8602
- room.failure !== null ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("p", { className: "mx-meet__error", children: [
10293
+ room.failure !== null ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("p", { className: "mx-meet__error", children: [
8603
10294
  room.failure.message,
8604
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "mx-meet__remedy", children: room.failure.remedy })
10295
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "mx-meet__remedy", children: room.failure.remedy })
8605
10296
  ] }) : null
8606
10297
  ] })
8607
10298
  ] });
8608
10299
  }
8609
10300
  function useCameraPreview(deviceId2, effects) {
8610
- const [preview, setPreview] = (0, import_react4.useState)(null);
8611
- const [error, setError] = (0, import_react4.useState)(null);
8612
- const current = (0, import_react4.useRef)(null);
8613
- const initialEffect = (0, import_react4.useRef)(toVideoEffect(effects));
10301
+ const [preview, setPreview] = (0, import_react5.useState)(null);
10302
+ const [error, setError] = (0, import_react5.useState)(null);
10303
+ const current = (0, import_react5.useRef)(null);
10304
+ const initialEffect = (0, import_react5.useRef)(toVideoEffect(effects));
8614
10305
  initialEffect.current = toVideoEffect(effects);
8615
- (0, import_react4.useEffect)(() => {
10306
+ (0, import_react5.useEffect)(() => {
8616
10307
  if (deviceId2 === void 0) return void 0;
8617
10308
  let live = true;
8618
10309
  setError(null);
@@ -8656,9 +10347,9 @@ function DevicePicker({
8656
10347
  const devices = useDeviceSnapshot();
8657
10348
  const list = devices?.devices[kind] ?? [];
8658
10349
  if (list.length === 0) return null;
8659
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("label", { className: "mx-meet__field", children: [
8660
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "mx-meet__field-label", children: label }),
8661
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
10350
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("label", { className: "mx-meet__field", children: [
10351
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "mx-meet__field-label", children: label }),
10352
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
8662
10353
  "select",
8663
10354
  {
8664
10355
  className: "mx-meet__select",
@@ -8667,7 +10358,7 @@ function DevicePicker({
8667
10358
  if (onPick !== void 0) onPick(kind, event.target.value);
8668
10359
  else host.devices.select(kind, event.target.value);
8669
10360
  },
8670
- children: list.map((device) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("option", { value: device.deviceId, children: device.label.length > 0 ? device.label : `${label} (name hidden)` }, device.deviceId))
10361
+ children: list.map((device) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("option", { value: device.deviceId, children: device.label.length > 0 ? device.label : `${label} (name hidden)` }, device.deviceId))
8671
10362
  }
8672
10363
  )
8673
10364
  ] });
@@ -8675,9 +10366,9 @@ function DevicePicker({
8675
10366
  function MeetingRoom(props) {
8676
10367
  const host = useMeetHost();
8677
10368
  if (host === null) {
8678
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "mx-meet", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(InertNotice, { what: "This meeting" }) });
10369
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "mx-meet", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(InertNotice, { what: "This meeting" }) });
8679
10370
  }
8680
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(MeetingRoomBody, { ...props, host });
10371
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(MeetingRoomBody, { ...props, host });
8681
10372
  }
8682
10373
  function MeetingRoomBody({
8683
10374
  roomName,
@@ -8692,25 +10383,25 @@ function MeetingRoomBody({
8692
10383
  const isHost = useIsHost();
8693
10384
  const elapsed = useElapsed(snapshot?.meeting?.startedAt ?? null);
8694
10385
  const phase = snapshot?.phase ?? "idle";
8695
- (0, import_react4.useEffect)(() => {
10386
+ (0, import_react5.useEffect)(() => {
8696
10387
  host.meetings.watch(roomName);
8697
10388
  }, [host, roomName]);
8698
- (0, import_react4.useEffect)(() => {
10389
+ (0, import_react5.useEffect)(() => {
8699
10390
  if (given === void 0) return;
8700
10391
  if (host.store.snapshot().meeting !== null) return;
8701
10392
  host.store.patch({ meeting: given, locked: given.locked });
8702
10393
  }, [host, given]);
8703
10394
  const watchedId = meetingId ?? snapshot?.meeting?.id ?? null;
8704
- (0, import_react4.useEffect)(() => {
10395
+ (0, import_react5.useEffect)(() => {
8705
10396
  if (watchedId === null) return;
8706
10397
  host.meetings.watchMeeting(asMeetingId(watchedId));
8707
10398
  }, [host, watchedId]);
8708
10399
  const record = snapshot?.meeting ?? given ?? null;
8709
10400
  if (hasEnded(record) && phase !== "connected" && phase !== "reconnecting") {
8710
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(MeetingRecordView, { meeting: record });
10401
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(MeetingRecordView, { meeting: record });
8711
10402
  }
8712
10403
  if (phase === "idle" || phase === "failed" || phase === "left") {
8713
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "mx-meet", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
10404
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "mx-meet", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
8714
10405
  PreJoin,
8715
10406
  {
8716
10407
  roomName,
@@ -8720,42 +10411,42 @@ function MeetingRoomBody({
8720
10411
  ) });
8721
10412
  }
8722
10413
  if (phase === "lobby") {
8723
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "mx-meet mx-meet--lobby", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(WaitingRoom, { roomName, host }) });
8724
- }
8725
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "mx-meet", children: [
8726
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(ConsentNotice, {}),
8727
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(AttendanceNotice, {}),
8728
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("header", { className: "mx-meet__header", children: [
8729
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("h1", { className: "mx-meet__title", children: snapshot?.meeting?.title ?? "Meeting" }),
8730
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("span", { className: "mx-meet__meta", children: [
10414
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "mx-meet mx-meet--lobby", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(WaitingRoom, { roomName, host }) });
10415
+ }
10416
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "mx-meet", children: [
10417
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(ConsentNotice, {}),
10418
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(AttendanceNotice, {}),
10419
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("header", { className: "mx-meet__header", children: [
10420
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("h1", { className: "mx-meet__title", children: snapshot?.meeting?.title ?? "Meeting" }),
10421
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("span", { className: "mx-meet__meta", children: [
8731
10422
  participantSummary(snapshot?.participants ?? []),
8732
10423
  elapsed > 0 ? ` \xB7 ${(0, import_format3.formatDurationMs)(elapsed)}` : ""
8733
10424
  ] }),
8734
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(RecordingIndicator, {}),
8735
- snapshot?.locked === true ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("span", { className: "mx-meet__badge", children: [
8736
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(LockIcon, { width: 12, height: 12 }),
10425
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(RecordingIndicator, {}),
10426
+ snapshot?.locked === true ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("span", { className: "mx-meet__badge", children: [
10427
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(LockIcon, { width: 12, height: 12 }),
8737
10428
  " Locked"
8738
10429
  ] }) : null,
8739
- headerControls !== void 0 && headerControls !== null ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "mx-meet__header-controls", "data-meet-header-controls": "", children: headerControls }) : null,
8740
- isHost ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(HostMenu, {}) : null
10430
+ headerControls !== void 0 && headerControls !== null ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "mx-meet__header-controls", "data-meet-header-controls": "", children: headerControls }) : null,
10431
+ isHost ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(HostMenu, {}) : null
8741
10432
  ] }),
8742
- phase === "reconnecting" ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "mx-meet__banner", role: "status", children: "Reconnecting\u2026" }) : null,
8743
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Stage, {}),
8744
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Captions, {}),
8745
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(ControlBar, { ...onLeave !== void 0 ? { onLeave } : {} })
10433
+ phase === "reconnecting" ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { className: "mx-meet__banner", role: "status", children: "Reconnecting\u2026" }) : null,
10434
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Stage, {}),
10435
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Captions, {}),
10436
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(ControlBar, { ...onLeave !== void 0 ? { onLeave } : {} })
8746
10437
  ] });
8747
10438
  }
8748
10439
  function WaitingRoom({ roomName, host }) {
8749
- const knocked = (0, import_react4.useRef)(false);
8750
- (0, import_react4.useEffect)(() => {
10440
+ const knocked = (0, import_react5.useRef)(false);
10441
+ (0, import_react5.useEffect)(() => {
8751
10442
  if (knocked.current) return;
8752
10443
  knocked.current = true;
8753
10444
  host.meetings.knock(roomName);
8754
10445
  }, [host, roomName]);
8755
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "mx-meet__waiting", children: [
8756
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Avatar, { name: host.identity.displayName, url: host.identity.avatarUrl, size: 72 }),
8757
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("h1", { className: "mx-meet__prejoin-title", children: "Waiting for the host to let you in" }),
8758
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("p", { className: "mx-meet__empty-body", children: [
10446
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "mx-meet__waiting", children: [
10447
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Avatar, { name: host.identity.displayName, url: host.identity.avatarUrl, size: 72 }),
10448
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("h1", { className: "mx-meet__prejoin-title", children: "Waiting for the host to let you in" }),
10449
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("p", { className: "mx-meet__empty-body", children: [
8759
10450
  "You are in the waiting room as ",
8760
10451
  host.identity.displayName,
8761
10452
  ". You will join automatically once you are admitted."
@@ -8766,10 +10457,10 @@ function HostMenu() {
8766
10457
  const host = useRequiredMeetHost();
8767
10458
  const snapshot = useMeetSnapshot();
8768
10459
  const end = useEndMeeting();
8769
- const [confirmingEnd, setConfirmingEnd] = (0, import_react4.useState)(false);
10460
+ const [confirmingEnd, setConfirmingEnd] = (0, import_react5.useState)(false);
8770
10461
  const locked = snapshot?.locked === true;
8771
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "mx-meet__host-menu", children: [
8772
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
10462
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "mx-meet__host-menu", children: [
10463
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
8773
10464
  "button",
8774
10465
  {
8775
10466
  type: "button",
@@ -8780,9 +10471,9 @@ function HostMenu() {
8780
10471
  children: locked ? "Unlock meeting" : "Lock meeting"
8781
10472
  }
8782
10473
  ),
8783
- end.canEnd ? confirmingEnd ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("span", { className: "mx-meet__confirm", role: "group", "aria-label": "End this meeting?", children: [
8784
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("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." }),
8785
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
10474
+ end.canEnd ? confirmingEnd ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("span", { className: "mx-meet__confirm", role: "group", "aria-label": "End this meeting?", children: [
10475
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("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." }),
10476
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
8786
10477
  "button",
8787
10478
  {
8788
10479
  type: "button",
@@ -8794,7 +10485,7 @@ function HostMenu() {
8794
10485
  children: "End it"
8795
10486
  }
8796
10487
  ),
8797
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
10488
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
8798
10489
  "button",
8799
10490
  {
8800
10491
  type: "button",
@@ -8803,7 +10494,7 @@ function HostMenu() {
8803
10494
  children: "Keep it running"
8804
10495
  }
8805
10496
  )
8806
- ] }) : /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
10497
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
8807
10498
  "button",
8808
10499
  {
8809
10500
  type: "button",
@@ -8812,7 +10503,7 @@ function HostMenu() {
8812
10503
  children: end.ending ? "Ending\u2026" : "End meeting for everyone"
8813
10504
  }
8814
10505
  ) : null,
8815
- end.notice !== null ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "mx-meet__notice", role: "status", children: end.notice }) : null
10506
+ end.notice !== null ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "mx-meet__notice", role: "status", children: end.notice }) : null
8816
10507
  ] });
8817
10508
  }
8818
10509
  function CallButton({
@@ -8822,7 +10513,7 @@ function CallButton({
8822
10513
  }) {
8823
10514
  const calls = useCalls();
8824
10515
  if (!calls.canCall) return null;
8825
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
10516
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
8826
10517
  "button",
8827
10518
  {
8828
10519
  type: "button",
@@ -8831,55 +10522,55 @@ function CallButton({
8831
10522
  void calls.call([person.userId], mode);
8832
10523
  },
8833
10524
  "aria-label": `Call ${person.displayName}`,
8834
- children: children ?? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(PhoneIcon, { width: 18, height: 18 })
10525
+ children: children ?? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(PhoneIcon, { width: 18, height: 18 })
8835
10526
  }
8836
10527
  );
8837
10528
  }
8838
10529
  function IncomingCallHost() {
8839
10530
  const calls = useCalls();
8840
10531
  if (calls.incoming.length === 0) return null;
8841
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "mx-meet__ringing-stack", children: calls.incoming.map((invite) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(IncomingCallCard, { invite }, invite.id)) });
10532
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "mx-meet__ringing-stack", children: calls.incoming.map((invite) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(IncomingCallCard, { invite }, invite.id)) });
8842
10533
  }
8843
10534
  function IncomingCallCard({ invite }) {
8844
10535
  const calls = useCalls();
8845
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("section", { className: "mx-meet__ringing", role: "alertdialog", "aria-label": "Incoming call", children: [
8846
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Avatar, { name: invite.callerName, url: invite.callerAvatarUrl, size: 56 }),
8847
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "mx-meet__ringing-text", children: [
8848
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("strong", { children: invite.callerName }),
8849
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { children: invite.mode === "video" ? "Incoming video call" : "Incoming call" })
10536
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("section", { className: "mx-meet__ringing", role: "alertdialog", "aria-label": "Incoming call", children: [
10537
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Avatar, { name: invite.callerName, url: invite.callerAvatarUrl, size: 56 }),
10538
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "mx-meet__ringing-text", children: [
10539
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("strong", { children: invite.callerName }),
10540
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { children: invite.mode === "video" ? "Incoming video call" : "Incoming call" })
8850
10541
  ] }),
8851
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "mx-meet__ringing-actions", children: [
8852
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(ControlButton, { label: "Decline", danger: true, onClick: () => void calls.decline(invite), children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(PhoneOffIcon, {}) }),
8853
- invite.mode === "video" ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
10542
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "mx-meet__ringing-actions", children: [
10543
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(ControlButton, { label: "Decline", danger: true, onClick: () => void calls.decline(invite), children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(PhoneOffIcon, {}) }),
10544
+ invite.mode === "video" ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
8854
10545
  ControlButton,
8855
10546
  {
8856
10547
  label: "Accept without video",
8857
10548
  onClick: () => void calls.accept({ ...invite, mode: "audio" }),
8858
- children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(CameraOffIcon, {})
10549
+ children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(CameraOffIcon, {})
8859
10550
  }
8860
10551
  ) : null,
8861
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(ControlButton, { label: "Accept", onClick: () => void calls.accept(invite), children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(PhoneIcon, {}) })
10552
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(ControlButton, { label: "Accept", onClick: () => void calls.accept(invite), children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(PhoneIcon, {}) })
8862
10553
  ] })
8863
10554
  ] });
8864
10555
  }
8865
10556
  function ScheduleMeeting(props) {
8866
10557
  const host = useMeetHost();
8867
- if (host === null) return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(InertNotice, { what: "Scheduling a meeting" });
8868
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(ScheduleMeetingBody, { ...props, host });
10558
+ if (host === null) return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(InertNotice, { what: "Scheduling a meeting" });
10559
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(ScheduleMeetingBody, { ...props, host });
8869
10560
  }
8870
10561
  function ScheduleMeetingBody({
8871
10562
  appBaseUrl,
8872
10563
  onScheduled,
8873
10564
  host
8874
10565
  }) {
8875
- const [title, setTitle] = (0, import_react4.useState)("");
8876
- const [when2, setWhen] = (0, import_react4.useState)("");
8877
- const [kind, setKind] = (0, import_react4.useState)("scheduled");
8878
- const [busy, setBusy] = (0, import_react4.useState)(false);
8879
- const [link, setLink] = (0, import_react4.useState)(null);
8880
- const [error, setError] = (0, import_react4.useState)(null);
8881
- const disabled = (0, import_react4.useMemo)(() => title.trim().length === 0 || busy, [title, busy]);
8882
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
10566
+ const [title, setTitle] = (0, import_react5.useState)("");
10567
+ const [when2, setWhen] = (0, import_react5.useState)("");
10568
+ const [kind, setKind] = (0, import_react5.useState)("scheduled");
10569
+ const [busy, setBusy] = (0, import_react5.useState)(false);
10570
+ const [link, setLink] = (0, import_react5.useState)(null);
10571
+ const [error, setError] = (0, import_react5.useState)(null);
10572
+ const disabled = (0, import_react5.useMemo)(() => title.trim().length === 0 || busy, [title, busy]);
10573
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
8883
10574
  "form",
8884
10575
  {
8885
10576
  className: "mx-meet__schedule",
@@ -8904,9 +10595,9 @@ function ScheduleMeetingBody({
8904
10595
  }).finally(() => setBusy(false));
8905
10596
  },
8906
10597
  children: [
8907
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("label", { className: "mx-meet__field", children: [
8908
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "mx-meet__field-label", children: "Title" }),
8909
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
10598
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("label", { className: "mx-meet__field", children: [
10599
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "mx-meet__field-label", children: "Title" }),
10600
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
8910
10601
  "input",
8911
10602
  {
8912
10603
  className: "mx-meet__input",
@@ -8916,9 +10607,9 @@ function ScheduleMeetingBody({
8916
10607
  }
8917
10608
  )
8918
10609
  ] }),
8919
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("label", { className: "mx-meet__field", children: [
8920
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "mx-meet__field-label", children: "When" }),
8921
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
10610
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("label", { className: "mx-meet__field", children: [
10611
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "mx-meet__field-label", children: "When" }),
10612
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
8922
10613
  "input",
8923
10614
  {
8924
10615
  className: "mx-meet__input",
@@ -8928,27 +10619,27 @@ function ScheduleMeetingBody({
8928
10619
  }
8929
10620
  )
8930
10621
  ] }),
8931
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("label", { className: "mx-meet__field", children: [
8932
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "mx-meet__field-label", children: "Repeats" }),
8933
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
10622
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("label", { className: "mx-meet__field", children: [
10623
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "mx-meet__field-label", children: "Repeats" }),
10624
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
8934
10625
  "select",
8935
10626
  {
8936
10627
  className: "mx-meet__select",
8937
10628
  value: kind,
8938
10629
  onChange: (event) => setKind(event.target.value),
8939
10630
  children: [
8940
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("option", { value: "scheduled", children: "Once" }),
8941
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("option", { value: "recurring", children: "Recurring \u2014 one link, every time" })
10631
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("option", { value: "scheduled", children: "Once" }),
10632
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("option", { value: "recurring", children: "Recurring \u2014 one link, every time" })
8942
10633
  ]
8943
10634
  }
8944
10635
  )
8945
10636
  ] }),
8946
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("button", { type: "submit", className: "mx-meet__primary", disabled, children: busy ? "Creating\u2026" : "Create meeting" }),
8947
- link !== null ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("p", { className: "mx-meet__link-out", children: [
8948
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { children: "Anyone with this link can join \u2014 no account needed." }),
8949
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("code", { children: link })
10637
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("button", { type: "submit", className: "mx-meet__primary", disabled, children: busy ? "Creating\u2026" : "Create meeting" }),
10638
+ link !== null ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("p", { className: "mx-meet__link-out", children: [
10639
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { children: "Anyone with this link can join \u2014 no account needed." }),
10640
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("code", { children: link })
8950
10641
  ] }) : null,
8951
- error !== null ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "mx-meet__error", children: error }) : null
10642
+ error !== null ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { className: "mx-meet__error", children: error }) : null
8952
10643
  ]
8953
10644
  }
8954
10645
  );
@@ -8957,7 +10648,7 @@ function ReactionOverlay({
8957
10648
  reactions
8958
10649
  }) {
8959
10650
  if (reactions.length === 0) return null;
8960
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "mx-meet__reactions", "aria-hidden": "true", children: reactions.map((reaction) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "mx-meet__reaction", children: reaction.emoji }, reaction.id)) });
10651
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "mx-meet__reactions", "aria-hidden": "true", children: reactions.map((reaction) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "mx-meet__reaction", children: reaction.emoji }, reaction.id)) });
8961
10652
  }
8962
10653
  function GuestRecordAccessControl({
8963
10654
  meeting
@@ -8969,11 +10660,11 @@ function GuestRecordAccessControl({
8969
10660
  const isHost = inRoomHost || viewerId !== null && meeting.hostUserId === viewerId;
8970
10661
  if (host === null || !isHost) return null;
8971
10662
  const resolved = access.setting === "default" && access.effective !== null ? ` Right now that means: ${guestRecordAccessLabel(access.effective.level).toLowerCase()}.` : "";
8972
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("section", { className: "mx-meet__record-section", "aria-label": "What guests may read", children: [
8973
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("h2", { className: "mx-meet__record-section-title", children: "What guests may read" }),
8974
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("label", { className: "mx-meet__field", children: [
8975
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "mx-meet__field-label", children: "People who attended by link, without an account" }),
8976
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
10663
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("section", { className: "mx-meet__record-section", "aria-label": "What guests may read", children: [
10664
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("h2", { className: "mx-meet__record-section-title", children: "What guests may read" }),
10665
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("label", { className: "mx-meet__field", children: [
10666
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "mx-meet__field-label", children: "People who attended by link, without an account" }),
10667
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
8977
10668
  "select",
8978
10669
  {
8979
10670
  className: "mx-meet__select",
@@ -8984,18 +10675,18 @@ function GuestRecordAccessControl({
8984
10675
  event.target.value
8985
10676
  );
8986
10677
  },
8987
- children: GUEST_RECORD_ACCESS_CHOICES.map((choice) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("option", { value: choice, children: guestRecordAccessLabel(choice) }, choice))
10678
+ children: GUEST_RECORD_ACCESS_CHOICES.map((choice) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("option", { value: choice, children: guestRecordAccessLabel(choice) }, choice))
8988
10679
  }
8989
10680
  )
8990
10681
  ] }),
8991
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("p", { className: "mx-meet__panel-note", children: [
10682
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("p", { className: "mx-meet__panel-note", children: [
8992
10683
  guestRecordAccessExplanation(access.setting),
8993
10684
  resolved
8994
10685
  ] }),
8995
- access.saving ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "mx-meet__panel-note", role: "status", children: "Saving what guests may read\u2026" }) : null,
8996
- access.error !== null ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_design_system.ErrorBox, { as: "div", className: "mx-meet__refusal", error: access.error, operation: "Change who can join", origin: "meet/components", children: [
8997
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "mx-meet__refusal-reason", children: access.error.message }),
8998
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "mx-meet__refusal-remedy", children: access.error.remedy })
10686
+ access.saving ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { className: "mx-meet__panel-note", role: "status", children: "Saving what guests may read\u2026" }) : null,
10687
+ access.error !== null ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_design_system.ErrorBox, { as: "div", className: "mx-meet__refusal", error: access.error, operation: "Change who can join", origin: "meet/components", children: [
10688
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { className: "mx-meet__refusal-reason", children: access.error.message }),
10689
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { className: "mx-meet__refusal-remedy", children: access.error.remedy })
8999
10690
  ] }) : null
9000
10691
  ] });
9001
10692
  }
@@ -9005,9 +10696,9 @@ function MeetingRecordView({
9005
10696
  }) {
9006
10697
  const host = useMeetHost();
9007
10698
  if (host === null) {
9008
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "mx-meet mx-meet--record", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(InertNotice, { what: "This meeting record" }) });
10699
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "mx-meet mx-meet--record", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(InertNotice, { what: "This meeting record" }) });
9009
10700
  }
9010
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(MeetingRecordBody, { meeting, ...onRejoin !== void 0 ? { onRejoin } : {} });
10701
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(MeetingRecordBody, { meeting, ...onRejoin !== void 0 ? { onRejoin } : {} });
9011
10702
  }
9012
10703
  function MeetingRecordBody({
9013
10704
  meeting,
@@ -9015,19 +10706,19 @@ function MeetingRecordBody({
9015
10706
  }) {
9016
10707
  const host = useRequiredMeetHost();
9017
10708
  const record = useMeetingRecord(meeting);
9018
- const [question, setQuestion] = (0, import_react4.useState)("");
9019
- const [tab, setTab] = (0, import_react4.useState)("summary");
10709
+ const [question, setQuestion] = (0, import_react5.useState)("");
10710
+ const [tab, setTab] = (0, import_react5.useState)("summary");
9020
10711
  if (record.failure !== null) {
9021
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "mx-meet mx-meet--record", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_design_system.ErrorBox, { as: "div", className: "mx-meet__empty", error: record.failure, operation: "Open this meeting record", origin: "meet/components", children: [
9022
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "mx-meet__empty-title", children: "This meeting record could not be opened" }),
9023
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "mx-meet__empty-body", children: record.failure.message }),
9024
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "mx-meet__empty-body", children: record.failure.remedy })
10712
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "mx-meet mx-meet--record", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_design_system.ErrorBox, { as: "div", className: "mx-meet__empty", error: record.failure, operation: "Open this meeting record", origin: "meet/components", children: [
10713
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { className: "mx-meet__empty-title", children: "This meeting record could not be opened" }),
10714
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { className: "mx-meet__empty-body", children: record.failure.message }),
10715
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { className: "mx-meet__empty-body", children: record.failure.remedy })
9025
10716
  ] }) });
9026
10717
  }
9027
10718
  if (record.loading || record.record === null) {
9028
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "mx-meet mx-meet--record", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "mx-meet__empty", role: "status", children: [
9029
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "mx-meet__empty-title", children: "Opening the meeting record\u2026" }),
9030
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "mx-meet__empty-body", children: "Reading the summary, the notes and the transcript this meeting left behind." })
10719
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "mx-meet mx-meet--record", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "mx-meet__empty", role: "status", children: [
10720
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { className: "mx-meet__empty-title", children: "Opening the meeting record\u2026" }),
10721
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { className: "mx-meet__empty-body", children: "Reading the summary, the notes and the transcript this meeting left behind." })
9031
10722
  ] }) });
9032
10723
  }
9033
10724
  const bundle = record.record;
@@ -9046,44 +10737,44 @@ function MeetingRecordBody({
9046
10737
  );
9047
10738
  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;
9048
10739
  if (entirelyRestricted) {
9049
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "mx-meet mx-meet--record", children: [
9050
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("header", { className: "mx-meet__record-head", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "mx-meet__record-head-inner", children: [
9051
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "mx-meet__record-eyebrow", children: "Meeting record" }),
9052
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("h1", { className: "mx-meet__record-title", children: meeting.title }),
9053
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "mx-meet__record-when", children: meetingWhen(meeting) }),
9054
- onRejoin !== void 0 ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("button", { type: "button", className: "mx-meet__link", onClick: onRejoin, children: "Open this link again" }) : null
10740
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "mx-meet mx-meet--record", children: [
10741
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("header", { className: "mx-meet__record-head", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "mx-meet__record-head-inner", children: [
10742
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { className: "mx-meet__record-eyebrow", children: "Meeting record" }),
10743
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("h1", { className: "mx-meet__record-title", children: meeting.title }),
10744
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { className: "mx-meet__record-when", children: meetingWhen(meeting) }),
10745
+ onRejoin !== void 0 ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("button", { type: "button", className: "mx-meet__link", onClick: onRejoin, children: "Open this link again" }) : null
9055
10746
  ] }) }),
9056
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "mx-meet__record-body", children: restrictionNotices.map((notice2) => /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "mx-meet__record-access", role: "status", children: [
9057
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "mx-meet__record-access-title", children: "About this record" }),
9058
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "mx-meet__record-access-message", children: notice2.message }),
9059
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "mx-meet__record-access-remedy", children: notice2.remedy })
10747
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "mx-meet__record-body", children: restrictionNotices.map((notice2) => /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "mx-meet__record-access", role: "status", children: [
10748
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { className: "mx-meet__record-access-title", children: "About this record" }),
10749
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { className: "mx-meet__record-access-message", children: notice2.message }),
10750
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { className: "mx-meet__record-access-remedy", children: notice2.remedy })
9060
10751
  ] }, notice2.parts.join("-"))) })
9061
10752
  ] });
9062
10753
  }
9063
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "mx-meet mx-meet--record", children: [
9064
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("header", { className: "mx-meet__record-head", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "mx-meet__record-head-inner", children: [
9065
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "mx-meet__record-eyebrow", children: "Meeting record" }),
9066
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("h1", { className: "mx-meet__record-title", children: meeting.title }),
9067
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "mx-meet__record-when", children: meetingWhen(meeting) }),
9068
- onRejoin !== void 0 ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("button", { type: "button", className: "mx-meet__link", onClick: onRejoin, children: "Open this link again" }) : null
10754
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "mx-meet mx-meet--record", children: [
10755
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("header", { className: "mx-meet__record-head", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "mx-meet__record-head-inner", children: [
10756
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { className: "mx-meet__record-eyebrow", children: "Meeting record" }),
10757
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("h1", { className: "mx-meet__record-title", children: meeting.title }),
10758
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { className: "mx-meet__record-when", children: meetingWhen(meeting) }),
10759
+ onRejoin !== void 0 ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("button", { type: "button", className: "mx-meet__link", onClick: onRejoin, children: "Open this link again" }) : null
9069
10760
  ] }) }),
9070
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "mx-meet__record-body", children: [
9071
- restrictionNotices.map((notice2) => /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "mx-meet__record-access", role: "status", children: [
9072
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "mx-meet__record-access-title", children: "About this record" }),
9073
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "mx-meet__record-access-message", children: notice2.message }),
9074
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "mx-meet__record-access-remedy", children: notice2.remedy })
10761
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "mx-meet__record-body", children: [
10762
+ restrictionNotices.map((notice2) => /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "mx-meet__record-access", role: "status", children: [
10763
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { className: "mx-meet__record-access-title", children: "About this record" }),
10764
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { className: "mx-meet__record-access-message", children: notice2.message }),
10765
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { className: "mx-meet__record-access-remedy", children: notice2.remedy })
9075
10766
  ] }, notice2.parts.join("-"))),
9076
10767
  attended.length === 0 ? (
9077
10768
  /* NOT SILENCE. A refused attendance read used to remove the whole
9078
10769
  section, so the reader could not tell "nobody" from "not shown". */
9079
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("section", { className: "mx-meet__record-section", "aria-label": "Who attended", children: [
9080
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("h2", { className: "mx-meet__record-section-title", children: "Who attended" }),
9081
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "mx-meet__panel-note", children: absenceSentence(bundle, "attendance", "Nobody is recorded as having attended.") })
10770
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("section", { className: "mx-meet__record-section", "aria-label": "Who attended", children: [
10771
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("h2", { className: "mx-meet__record-section-title", children: "Who attended" }),
10772
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { className: "mx-meet__panel-note", children: absenceSentence(bundle, "attendance", "Nobody is recorded as having attended.") })
9082
10773
  ] })
9083
- ) : /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("section", { className: "mx-meet__record-section", "aria-label": "Who attended", children: [
9084
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("h2", { className: "mx-meet__record-section-title", children: "Who attended" }),
9085
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("ul", { className: "mx-meet__record-attendees", children: attended.map((person) => /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("li", { className: "mx-meet__record-attendee", children: [
9086
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
10774
+ ) : /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("section", { className: "mx-meet__record-section", "aria-label": "Who attended", children: [
10775
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("h2", { className: "mx-meet__record-section-title", children: "Who attended" }),
10776
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("ul", { className: "mx-meet__record-attendees", children: attended.map((person) => /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("li", { className: "mx-meet__record-attendee", children: [
10777
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
9087
10778
  Avatar,
9088
10779
  {
9089
10780
  name: displayNameFor(bundle.names, person.identity, person.displayName),
@@ -9091,26 +10782,26 @@ function MeetingRecordBody({
9091
10782
  size: 28
9092
10783
  }
9093
10784
  ),
9094
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("span", { className: "mx-meet__person-name", children: [
10785
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("span", { className: "mx-meet__person-name", children: [
9095
10786
  displayNameFor(bundle.names, person.identity, person.displayName),
9096
- person.role === "host" ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "mx-meet__badge", children: "Host" }) : null,
9097
- person.role === "guest" ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "mx-meet__badge", children: "Guest" }) : null,
9098
- person.isAgent ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "mx-meet__badge", children: "Meeting assistant" }) : null
10787
+ person.role === "host" ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "mx-meet__badge", children: "Host" }) : null,
10788
+ person.role === "guest" ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "mx-meet__badge", children: "Guest" }) : null,
10789
+ person.isAgent ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "mx-meet__badge", children: "Meeting assistant" }) : null
9099
10790
  ] })
9100
10791
  ] }, person.id)) })
9101
10792
  ] }),
9102
- bundle.recording !== null ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("section", { className: "mx-meet__record-section mx-meet__recording-card", "aria-label": "Recording", children: [
9103
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("h2", { className: "mx-meet__record-section-title", children: "Recording" }),
9104
- fileId !== null ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_jsx_runtime3.Fragment, { children: [
9105
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(RecordingPlayer, { fileId }),
9106
- notice !== null ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "mx-meet__panel-note", children: notice }) : null
9107
- ] }) : /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "mx-meet__panel-note", children: notice ?? "This recording has no file." })
9108
- ] }) : wasRefused(bundle, "recording") ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("section", { className: "mx-meet__record-section", "aria-label": "Recording", children: [
9109
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("h2", { className: "mx-meet__record-section-title", children: "Recording" }),
9110
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "mx-meet__panel-note", children: REFUSED_ABSENCE })
10793
+ bundle.recording !== null ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("section", { className: "mx-meet__record-section mx-meet__recording-card", "aria-label": "Recording", children: [
10794
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("h2", { className: "mx-meet__record-section-title", children: "Recording" }),
10795
+ fileId !== null ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_jsx_runtime4.Fragment, { children: [
10796
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(RecordingPlayer, { fileId }),
10797
+ notice !== null ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { className: "mx-meet__panel-note", children: notice }) : null
10798
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { className: "mx-meet__panel-note", children: notice ?? "This recording has no file." })
10799
+ ] }) : wasRefused(bundle, "recording") ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("section", { className: "mx-meet__record-section", "aria-label": "Recording", children: [
10800
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("h2", { className: "mx-meet__record-section-title", children: "Recording" }),
10801
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { className: "mx-meet__panel-note", children: REFUSED_ABSENCE })
9111
10802
  ] }) : null,
9112
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("nav", { className: "mx-meet__record-tabs", "aria-label": "Meeting record sections", children: [
9113
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
10803
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("nav", { className: "mx-meet__record-tabs", "aria-label": "Meeting record sections", children: [
10804
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
9114
10805
  "button",
9115
10806
  {
9116
10807
  type: "button",
@@ -9120,7 +10811,7 @@ function MeetingRecordBody({
9120
10811
  children: "Summary & decisions"
9121
10812
  }
9122
10813
  ),
9123
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
10814
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
9124
10815
  "button",
9125
10816
  {
9126
10817
  type: "button",
@@ -9130,7 +10821,7 @@ function MeetingRecordBody({
9130
10821
  children: "Notes as it happened"
9131
10822
  }
9132
10823
  ),
9133
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
10824
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
9134
10825
  "button",
9135
10826
  {
9136
10827
  type: "button",
@@ -9141,15 +10832,15 @@ function MeetingRecordBody({
9141
10832
  }
9142
10833
  )
9143
10834
  ] }),
9144
- tab === "summary" ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_jsx_runtime3.Fragment, { children: [
9145
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("section", { className: "mx-meet__record-section", "aria-label": "Summary", children: [
9146
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("h2", { className: "mx-meet__record-section-title", children: "Summary" }),
9147
- wrapUp.state === "written" ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "mx-meet__record-summary", children: bundle.summary?.text }) : wrapUp.state === "in-progress" ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "mx-meet__panel-note", role: "status", children: [
9148
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { children: wrapUp.message }),
9149
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("button", { type: "button", className: "mx-meet__link", onClick: record.reload, children: "Check again" })
9150
- ] }) : /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "mx-meet__panel-note", role: wrapUp.state === "failed" ? "alert" : void 0, children: wrapUp.message })
10835
+ tab === "summary" ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_jsx_runtime4.Fragment, { children: [
10836
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("section", { className: "mx-meet__record-section", "aria-label": "Summary", children: [
10837
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("h2", { className: "mx-meet__record-section-title", children: "Summary" }),
10838
+ wrapUp.state === "written" ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { className: "mx-meet__record-summary", children: bundle.summary?.text }) : wrapUp.state === "in-progress" ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "mx-meet__panel-note", role: "status", children: [
10839
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { children: wrapUp.message }),
10840
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("button", { type: "button", className: "mx-meet__link", onClick: record.reload, children: "Check again" })
10841
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { className: "mx-meet__panel-note", role: wrapUp.state === "failed" ? "alert" : void 0, children: wrapUp.message })
9151
10842
  ] }),
9152
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
10843
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
9153
10844
  NoteList,
9154
10845
  {
9155
10846
  title: "Decisions",
@@ -9161,7 +10852,7 @@ function MeetingRecordBody({
9161
10852
  )
9162
10853
  }
9163
10854
  ),
9164
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
10855
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
9165
10856
  NoteList,
9166
10857
  {
9167
10858
  title: "Action items",
@@ -9174,42 +10865,42 @@ function MeetingRecordBody({
9174
10865
  }
9175
10866
  )
9176
10867
  ] }) : null,
9177
- tab === "notes" ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("section", { className: "mx-meet__record-section", "aria-label": "Notes as it happened", children: [
9178
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("h2", { className: "mx-meet__record-section-title", children: "Notes as it happened" }),
9179
- bundle.liveNotes.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "mx-meet__panel-note", children: absenceSentence(
10868
+ tab === "notes" ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("section", { className: "mx-meet__record-section", "aria-label": "Notes as it happened", children: [
10869
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("h2", { className: "mx-meet__record-section-title", children: "Notes as it happened" }),
10870
+ bundle.liveNotes.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { className: "mx-meet__panel-note", children: absenceSentence(
9180
10871
  bundle,
9181
10872
  "notes",
9182
10873
  "No live notes are available for this meeting."
9183
- ) }) : /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("ul", { className: "mx-meet__notes", children: bundle.liveNotes.map((note) => /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("li", { className: "mx-meet__note", children: [
9184
- note.window !== null ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("span", { className: "mx-meet__badge", children: [
10874
+ ) }) : /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("ul", { className: "mx-meet__notes", children: bundle.liveNotes.map((note) => /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("li", { className: "mx-meet__note", children: [
10875
+ note.window !== null ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("span", { className: "mx-meet__badge", children: [
9185
10876
  "Window ",
9186
10877
  note.window
9187
10878
  ] }) : null,
9188
10879
  note.text
9189
10880
  ] }, note.id)) })
9190
10881
  ] }) : null,
9191
- tab === "transcript" ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("section", { className: "mx-meet__record-section", "aria-label": "Transcript", children: [
9192
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("h2", { className: "mx-meet__record-section-title", children: [
10882
+ tab === "transcript" ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("section", { className: "mx-meet__record-section", "aria-label": "Transcript", children: [
10883
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("h2", { className: "mx-meet__record-section-title", children: [
9193
10884
  "Transcript",
9194
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "mx-meet__record-count", children: bundle.transcript.length === 1 ? "1 line" : `${bundle.transcript.length} lines` })
10885
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "mx-meet__record-count", children: bundle.transcript.length === 1 ? "1 line" : `${bundle.transcript.length} lines` })
9195
10886
  ] }),
9196
- blocks.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "mx-meet__panel-note", children: absenceSentence(
10887
+ blocks.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { className: "mx-meet__panel-note", children: absenceSentence(
9197
10888
  bundle,
9198
10889
  "transcript",
9199
10890
  "No transcript is available for this meeting."
9200
- ) }) : /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("ol", { className: "mx-meet__record-transcript", children: blocks.map((block) => /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("li", { className: "mx-meet__record-block", children: [
9201
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("p", { className: "mx-meet__record-speaker", children: [
10891
+ ) }) : /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("ol", { className: "mx-meet__record-transcript", children: blocks.map((block) => /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("li", { className: "mx-meet__record-block", children: [
10892
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("p", { className: "mx-meet__record-speaker", children: [
9202
10893
  block.speaker,
9203
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("time", { className: "mx-meet__record-time", dateTime: block.startedAt, children: clockOf(block.startedAt) })
10894
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("time", { className: "mx-meet__record-time", dateTime: block.startedAt, children: clockOf(block.startedAt) })
9204
10895
  ] }),
9205
- block.lines.map((line) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "mx-meet__record-line", children: line.text }, line.id))
10896
+ block.lines.map((line) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { className: "mx-meet__record-line", children: line.text }, line.id))
9206
10897
  ] }, block.id)) })
9207
10898
  ] }) : null,
9208
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(GuestRecordAccessControl, { meeting }),
9209
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("section", { className: "mx-meet__record-section", "aria-label": "Ask about this meeting", children: [
9210
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("h2", { className: "mx-meet__record-section-title", children: "Ask about this meeting" }),
9211
- guestFinishedMeeting ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "mx-meet__panel-note", children: "Sign in to ask the assistant about a meeting after it ends." }) : /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_jsx_runtime3.Fragment, { children: [
9212
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
10899
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(GuestRecordAccessControl, { meeting }),
10900
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("section", { className: "mx-meet__record-section", "aria-label": "Ask about this meeting", children: [
10901
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("h2", { className: "mx-meet__record-section-title", children: "Ask about this meeting" }),
10902
+ guestFinishedMeeting ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { className: "mx-meet__panel-note", children: "Sign in to ask the assistant about a meeting after it ends." }) : /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_jsx_runtime4.Fragment, { children: [
10903
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
9213
10904
  "form",
9214
10905
  {
9215
10906
  className: "mx-meet__composer",
@@ -9220,7 +10911,7 @@ function MeetingRecordBody({
9220
10911
  void record.ask(trimmed);
9221
10912
  },
9222
10913
  children: [
9223
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
10914
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
9224
10915
  "input",
9225
10916
  {
9226
10917
  className: "mx-meet__input",
@@ -9230,7 +10921,7 @@ function MeetingRecordBody({
9230
10921
  "aria-label": "Ask about this meeting"
9231
10922
  }
9232
10923
  ),
9233
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
10924
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
9234
10925
  "button",
9235
10926
  {
9236
10927
  type: "submit",
@@ -9242,8 +10933,8 @@ function MeetingRecordBody({
9242
10933
  ]
9243
10934
  }
9244
10935
  ),
9245
- record.answer !== null ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "mx-meet__answer", children: record.answer }) : null,
9246
- record.coverage !== null ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("p", { className: "mx-meet__coverage", children: [
10936
+ record.answer !== null ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { className: "mx-meet__answer", children: record.answer }) : null,
10937
+ record.coverage !== null ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("p", { className: "mx-meet__coverage", children: [
9247
10938
  "Answered from ",
9248
10939
  record.coverage.segmentsUsed,
9249
10940
  " of ",
@@ -9254,9 +10945,9 @@ function MeetingRecordBody({
9254
10945
  record.coverage.truncated ? " (the oldest were left out)" : "",
9255
10946
  "."
9256
10947
  ] }) : null,
9257
- record.askError !== null ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_design_system.ErrorBox, { as: "div", className: "mx-meet__refusal", error: record.askError, operation: "Ask about this meeting", origin: "meet/components", children: [
9258
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "mx-meet__refusal-reason", children: record.askError.message }),
9259
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "mx-meet__refusal-remedy", children: record.askError.remedy })
10948
+ record.askError !== null ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_design_system.ErrorBox, { as: "div", className: "mx-meet__refusal", error: record.askError, operation: "Ask about this meeting", origin: "meet/components", children: [
10949
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { className: "mx-meet__refusal-reason", children: record.askError.message }),
10950
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { className: "mx-meet__refusal-remedy", children: record.askError.remedy })
9260
10951
  ] }) : null
9261
10952
  ] })
9262
10953
  ] })
@@ -9267,21 +10958,21 @@ var STREAM_REFUSED = "Streaming playback did not start, so this recording was do
9267
10958
  var PLAYBACK_RETRY_REMEDY = "Reload the page and try again. If it still will not play, ask a meeting host to check the recording.";
9268
10959
  function RecordingPlayer(props) {
9269
10960
  const host = useMeetHost();
9270
- if (host === null) return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(InertNotice, { what: "This recording" });
9271
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(RecordingPlayerBody, { ...props, host });
10961
+ if (host === null) return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(InertNotice, { what: "This recording" });
10962
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(RecordingPlayerBody, { ...props, host });
9272
10963
  }
9273
10964
  function RecordingPlayerBody({ fileId, host }) {
9274
- const [media, setMedia] = (0, import_react4.useState)(null);
9275
- const [loading, setLoading] = (0, import_react4.useState)(false);
9276
- const [error, setError] = (0, import_react4.useState)(null);
9277
- (0, import_react4.useEffect)(() => {
10965
+ const [media, setMedia] = (0, import_react5.useState)(null);
10966
+ const [loading, setLoading] = (0, import_react5.useState)(false);
10967
+ const [error, setError] = (0, import_react5.useState)(null);
10968
+ (0, import_react5.useEffect)(() => {
9278
10969
  if (media === null || media.kind !== "bytes") return void 0;
9279
10970
  const url = media.url;
9280
10971
  return () => URL.revokeObjectURL(url);
9281
10972
  }, [media]);
9282
10973
  if (media !== null) {
9283
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "mx-meet__record-section", children: [
9284
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
10974
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "mx-meet__record-section", children: [
10975
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
9285
10976
  "video",
9286
10977
  {
9287
10978
  className: "mx-meet__record-player",
@@ -9323,15 +11014,15 @@ function RecordingPlayerBody({ fileId, host }) {
9323
11014
  }
9324
11015
  }
9325
11016
  ),
9326
- media.fallbackReason !== null ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "mx-meet__panel-note", children: media.fallbackReason }) : null
11017
+ media.fallbackReason !== null ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { className: "mx-meet__panel-note", children: media.fallbackReason }) : null
9327
11018
  ] });
9328
11019
  }
9329
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "mx-meet__record-section", children: [
9330
- error !== null ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_design_system.ErrorBox, { as: "div", className: "mx-meet__refusal", error, operation: "Complete this meeting action", origin: "meet/components", children: [
9331
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "mx-meet__refusal-reason", children: error.message }),
9332
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "mx-meet__refusal-remedy", children: error.remedy })
11020
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "mx-meet__record-section", children: [
11021
+ error !== null ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_design_system.ErrorBox, { as: "div", className: "mx-meet__refusal", error, operation: "Complete this meeting action", origin: "meet/components", children: [
11022
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { className: "mx-meet__refusal-reason", children: error.message }),
11023
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { className: "mx-meet__refusal-remedy", children: error.remedy })
9333
11024
  ] }) : null,
9334
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
11025
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
9335
11026
  "button",
9336
11027
  {
9337
11028
  type: "button",
@@ -9367,35 +11058,35 @@ function clockOf(iso) {
9367
11058
  function MeetingList({ baseUrl }) {
9368
11059
  const host = useMeetHost();
9369
11060
  const list = useMeetings();
9370
- if (host === null) return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(InertNotice, { what: "Your meetings" });
11061
+ if (host === null) return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(InertNotice, { what: "Your meetings" });
9371
11062
  if (list.failure !== null) {
9372
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_design_system.ErrorBox, { as: "div", className: "mx-meet__empty", error: list.failure, operation: "List your meetings", origin: "meet/components", children: [
9373
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "mx-meet__empty-title", children: "Your meetings could not be listed" }),
9374
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "mx-meet__empty-body", children: list.failure.message }),
9375
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "mx-meet__empty-body", children: list.failure.remedy })
11063
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_design_system.ErrorBox, { as: "div", className: "mx-meet__empty", error: list.failure, operation: "List your meetings", origin: "meet/components", children: [
11064
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { className: "mx-meet__empty-title", children: "Your meetings could not be listed" }),
11065
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { className: "mx-meet__empty-body", children: list.failure.message }),
11066
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { className: "mx-meet__empty-body", children: list.failure.remedy })
9376
11067
  ] });
9377
11068
  }
9378
11069
  if (list.loading) {
9379
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "mx-meet__empty", role: "status", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "mx-meet__empty-title", children: "Loading your meetings\u2026" }) });
11070
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "mx-meet__empty", role: "status", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { className: "mx-meet__empty-title", children: "Loading your meetings\u2026" }) });
9380
11071
  }
9381
11072
  if (list.meetings.length === 0) {
9382
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "mx-meet__empty", role: "status", children: [
9383
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "mx-meet__empty-title", children: "No meetings yet" }),
9384
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("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." })
11073
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "mx-meet__empty", role: "status", children: [
11074
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { className: "mx-meet__empty-title", children: "No meetings yet" }),
11075
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("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." })
9385
11076
  ] });
9386
11077
  }
9387
11078
  const origin = baseUrl ?? (typeof window === "undefined" ? "" : window.location.origin);
9388
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("ul", { className: "mx-meet-list", children: list.meetings.map((meeting) => {
11079
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("ul", { className: "mx-meet-list", children: list.meetings.map((meeting) => {
9389
11080
  const ended = meeting.endedAt !== null;
9390
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("li", { className: "mx-meet-list__row", children: [
9391
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "mx-meet-list__main", children: [
9392
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("span", { className: "mx-meet-list__title", children: [
11081
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("li", { className: "mx-meet-list__row", children: [
11082
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "mx-meet-list__main", children: [
11083
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("span", { className: "mx-meet-list__title", children: [
9393
11084
  meeting.title,
9394
- ended ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "mx-meet__badge", children: "Ended" }) : null
11085
+ ended ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "mx-meet__badge", children: "Ended" }) : null
9395
11086
  ] }),
9396
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "mx-meet-list__when", children: meetingWhen(meeting) })
11087
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "mx-meet-list__when", children: meetingWhen(meeting) })
9397
11088
  ] }),
9398
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("a", { className: "mx-meet-list__action", href: meetingLink(origin, meeting.slug), children: ended ? "Open the record" : "Join" })
11089
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("a", { className: "mx-meet-list__action", href: meetingLink(origin, meeting.slug), children: ended ? "Open the record" : "Join" })
9399
11090
  ] }, meeting.id);
9400
11091
  }) });
9401
11092
  }