@ai-matrx/meet 0.7.10 → 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
  }
@@ -5049,6 +5616,14 @@ function MeetRuntime(props) {
5049
5616
  }
5050
5617
  if (chatReadFor === snapshot.meeting.id) return;
5051
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
+ });
5052
5627
  void inRoom.loadChat().catch((error) => {
5053
5628
  const normalized = error;
5054
5629
  store.patch({
@@ -6389,7 +6964,7 @@ function useGuestRecordAccess(meeting) {
6389
6964
  }
6390
6965
 
6391
6966
  // src/react/components.tsx
6392
- var import_react4 = require("react");
6967
+ var import_react5 = require("react");
6393
6968
  var import_design_system = require("@ai-matrx/design-system");
6394
6969
  var import_format3 = require("@ai-matrx/kit/format");
6395
6970
 
@@ -6456,12 +7031,19 @@ function coveredMs(intervals) {
6456
7031
  }
6457
7032
  function attendanceReport(meeting, attendees, names = {}) {
6458
7033
  const end = ms(meeting.endedAt);
7034
+ const measuredOf = /* @__PURE__ */ new Map();
6459
7035
  const perJoin = attendees.map((person) => {
6460
- const joined = ms(person.joinedAt);
6461
- const left = ms(person.leftAt);
6462
- const until = left ?? end;
6463
- const duration = joined !== null && until !== null && until >= joined ? until - joined : null;
6464
- 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 = {
6465
7047
  id: person.id,
6466
7048
  identity: person.identity,
6467
7049
  name: displayNameFor(names, person.identity, person.displayName),
@@ -6470,10 +7052,12 @@ function attendanceReport(meeting, attendees, names = {}) {
6470
7052
  joinedAt: person.joinedAt,
6471
7053
  leftAt: person.leftAt,
6472
7054
  durationMs: duration,
6473
- durationToEnd: duration !== null && left === null,
7055
+ durationToEnd: duration !== null && toEnd,
6474
7056
  admission: person.admissionState,
6475
- joins: 1
7057
+ joins: Math.max(1, person.sessions?.length ?? 0)
6476
7058
  };
7059
+ measuredOf.set(row, measured);
7060
+ return row;
6477
7061
  });
6478
7062
  const groups = /* @__PURE__ */ new Map();
6479
7063
  attendees.forEach((person, index) => {
@@ -6496,17 +7080,14 @@ function attendanceReport(meeting, attendees, names = {}) {
6496
7080
  const left = ms(row.leftAt);
6497
7081
  return left !== null && (latest === null || left > latest) ? left : latest;
6498
7082
  }, null);
6499
- const intervals = came.flatMap((row) => {
6500
- const joined = ms(row.joinedAt);
6501
- return joined !== null && row.durationMs !== null ? [[joined, joined + row.durationMs]] : [];
6502
- });
7083
+ const intervals = came.flatMap((row) => measuredOf.get(row) ?? []);
6503
7084
  return {
6504
7085
  ...first,
6505
7086
  kind,
6506
7087
  leftAt: open ? null : lastLeave === null ? null : new Date(lastLeave).toISOString(),
6507
7088
  durationMs: intervals.length === 0 ? null : coveredMs(intervals),
6508
7089
  durationToEnd: came.some((row) => row.durationToEnd),
6509
- joins: came.length === 0 ? joins.length : came.length
7090
+ joins: came.length === 0 ? joins.length : came.reduce((total, row) => total + row.joins, 0)
6510
7091
  };
6511
7092
  });
6512
7093
  const rank = KIND_RANK;
@@ -6650,8 +7231,8 @@ function transcriptDocument(bundle, format, options = {}) {
6650
7231
  if (line.identity !== last) {
6651
7232
  if (last !== null) out.push("");
6652
7233
  const who = speaker(line);
6653
- const clock = clockOfDay(line.startedAt, options);
6654
- 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})`);
6655
7236
  last = line.identity;
6656
7237
  }
6657
7238
  out.push(line.text.trim());
@@ -6832,6 +7413,9 @@ function countLabel(count2, singular, plural = `${singular}s`) {
6832
7413
  return `${count2} ${count2 === 1 ? singular : plural}`;
6833
7414
  }
6834
7415
 
7416
+ // src/react/collab.tsx
7417
+ var import_react4 = require("react");
7418
+
6835
7419
  // src/react/icons.tsx
6836
7420
  var import_jsx_runtime2 = require("react/jsx-runtime");
6837
7421
  function Icon({ children, ...props }) {
@@ -7016,99 +7600,1128 @@ function FlagIcon(props) {
7016
7600
  function PencilIcon(props) {
7017
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" }) });
7018
7602
  }
7019
-
7020
- // src/react/components.tsx
7021
- var import_jsx_runtime3 = require("react/jsx-runtime");
7022
- function InertNotice({ what }) {
7023
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "mx-meet__empty", role: "status", children: [
7024
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("p", { className: "mx-meet__empty-title", children: [
7025
- what,
7026
- " is not ready yet"
7027
- ] }),
7028
- /* @__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" })
7029
7608
  ] });
7030
7609
  }
7031
- function Avatar({
7032
- name,
7033
- url,
7034
- size = 40
7035
- }) {
7036
- const tint = (0, import_format3.avatarPaletteIndex)(name);
7037
- if (url != null && url.length > 0) {
7038
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
7039
- "img",
7040
- {
7041
- className: "mx-meet__avatar",
7042
- src: url,
7043
- alt: "",
7044
- width: size,
7045
- height: size,
7046
- style: { width: size, height: size }
7047
- }
7048
- );
7049
- }
7050
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
7051
- "span",
7052
- {
7053
- className: "mx-meet__avatar mx-meet__avatar--initials",
7054
- style: {
7055
- width: size,
7056
- height: size,
7057
- fontSize: Math.round(size * 0.38),
7058
- background: `var(--mx-meet-avatar-${tint})`
7059
- },
7060
- "aria-hidden": "true",
7061
- children: (0, import_format3.getInitials)(name)
7062
- }
7063
- );
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
+ ] });
7064
7616
  }
7065
- function ControlButton({
7066
- label,
7067
- active = false,
7068
- danger = false,
7069
- onClick,
7070
- children
7071
- }) {
7072
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
7073
- "button",
7074
- {
7075
- type: "button",
7076
- className: [
7077
- "mx-meet__control",
7078
- active ? "mx-meet__control--active" : "",
7079
- danger ? "mx-meet__control--danger" : ""
7080
- ].filter(Boolean).join(" "),
7081
- "aria-label": label,
7082
- title: label,
7083
- onClick,
7084
- children
7085
- }
7086
- );
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
+ ] });
7087
7623
  }
7088
- function RecordingIndicator() {
7089
- const { state, label } = useRecording();
7090
- if (label === null) return null;
7091
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
7092
- "span",
7093
- {
7094
- className: `mx-meet__recording mx-meet__recording--${state}`,
7095
- role: "status",
7096
- "aria-live": "polite",
7097
- children: [
7098
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(RecordIcon, { width: 10, height: 10 }),
7099
- label
7100
- ]
7101
- }
7102
- );
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
+ ] });
7103
7630
  }
7104
- function ConnectionDot({ quality }) {
7105
- if (quality === "excellent" || quality === "good" || quality === "unknown") return null;
7106
- 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 }) });
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." };
7688
+ }
7689
+ }
7690
+ };
7691
+ }
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,
8680
+ active = false,
8681
+ danger = false,
8682
+ onClick,
8683
+ children
8684
+ }) {
8685
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
8686
+ "button",
8687
+ {
8688
+ type: "button",
8689
+ className: [
8690
+ "mx-meet__control",
8691
+ active ? "mx-meet__control--active" : "",
8692
+ danger ? "mx-meet__control--danger" : ""
8693
+ ].filter(Boolean).join(" "),
8694
+ "aria-label": label,
8695
+ title: label,
8696
+ onClick,
8697
+ children
8698
+ }
8699
+ );
8700
+ }
8701
+ function RecordingIndicator() {
8702
+ const { state, label } = useRecording();
8703
+ if (label === null) return null;
8704
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
8705
+ "span",
8706
+ {
8707
+ className: `mx-meet__recording mx-meet__recording--${state}`,
8708
+ role: "status",
8709
+ "aria-live": "polite",
8710
+ children: [
8711
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(RecordIcon, { width: 10, height: 10 }),
8712
+ label
8713
+ ]
8714
+ }
8715
+ );
8716
+ }
8717
+ function ConnectionDot({ quality }) {
8718
+ if (quality === "excellent" || quality === "good" || quality === "unknown") return null;
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 }) });
7107
8720
  }
7108
8721
  function RoleBadge({ role }) {
7109
- if (role === "host") return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "mx-meet__badge", children: "Host" });
7110
- if (role === "cohost") return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "mx-meet__badge", children: "Co-host" });
7111
- 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" });
7112
8725
  return null;
7113
8726
  }
7114
8727
  function ParticipantTile({
@@ -7118,7 +8731,7 @@ function ParticipantTile({
7118
8731
  const host = useMeetHost();
7119
8732
  const snapshot = useMeetSnapshot();
7120
8733
  const queue = useHandQueue();
7121
- const [menu, setMenu] = (0, import_react4.useState)(false);
8734
+ const [menu, setMenu] = (0, import_react5.useState)(false);
7122
8735
  const videoRef = useTrack(
7123
8736
  participant.identity,
7124
8737
  participant.screenSharing ? "screen" : "camera"
@@ -7127,7 +8740,7 @@ function ParticipantTile({
7127
8740
  const pinnedHere = snapshot?.pinned === participant.identity;
7128
8741
  const spotlit = snapshot?.spotlight === participant.identity;
7129
8742
  const handPosition = participant.handRaised ? queue.findIndex((entry) => entry.identity === participant.identity) + 1 : 0;
7130
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
8743
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
7131
8744
  "div",
7132
8745
  {
7133
8746
  className: [
@@ -7137,7 +8750,7 @@ function ParticipantTile({
7137
8750
  ].filter(Boolean).join(" "),
7138
8751
  "data-identity": participant.identity,
7139
8752
  children: [
7140
- showVideo ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
8753
+ showVideo ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
7141
8754
  "video",
7142
8755
  {
7143
8756
  ref: videoRef,
@@ -7146,43 +8759,43 @@ function ParticipantTile({
7146
8759
  playsInline: true,
7147
8760
  muted: participant.isLocal
7148
8761
  }
7149
- ) : /* @__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 }) }),
7150
- participant.handRaised ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("span", { className: "mx-meet__tile-hand", title: `Hand raised \xB7 ${ordinal(handPosition)} in line`, children: [
7151
- /* @__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 }),
7152
8765
  handPosition > 0 ? handPosition : null
7153
8766
  ] }) : null,
7154
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "mx-meet__tile-bar", children: [
7155
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("span", { className: "mx-meet__tile-name", children: [
7156
- 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,
7157
8770
  participant.displayName,
7158
8771
  participant.isLocal ? " (you)" : "",
7159
- participant.isAgent ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "mx-meet__badge", children: "AI" }) : null,
7160
- /* @__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 })
7161
8774
  ] }),
7162
- !participant.micEnabled ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(MicOffIcon, { width: 14, height: 14 }) : null,
7163
- /* @__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 })
7164
8777
  ] }),
7165
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: menu ? "mx-meet__tile-actions mx-meet__tile-actions--open" : "mx-meet__tile-actions", children: [
7166
- /* @__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)(
7167
8780
  ControlButton,
7168
8781
  {
7169
8782
  label: pinnedHere ? "Unpin" : `Pin ${participant.displayName} for me`,
7170
8783
  active: pinnedHere,
7171
8784
  onClick: () => host?.engine.pin(pinnedHere ? null : participant.identity),
7172
- 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 })
7173
8786
  }
7174
8787
  ),
7175
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("span", { className: "mx-meet__anchor", children: [
7176
- /* @__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)(
7177
8790
  ControlButton,
7178
8791
  {
7179
8792
  label: `More for ${participant.displayName}`,
7180
8793
  active: menu,
7181
8794
  onClick: () => setMenu(!menu),
7182
- 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 })
7183
8796
  }
7184
8797
  ),
7185
- 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
7186
8799
  ] })
7187
8800
  ] })
7188
8801
  ]
@@ -7198,28 +8811,28 @@ function QualityBars({ quality }) {
7198
8811
  if (quality === "unknown") return null;
7199
8812
  const bars = quality === "excellent" ? 3 : quality === "good" ? 2 : quality === "poor" ? 1 : 0;
7200
8813
  const label = quality === "lost" ? "Connection lost" : quality === "poor" ? "Poor connection" : `Connection ${quality}`;
7201
- 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 }) });
7202
8815
  }
7203
8816
  function Stage({ pageSize }) {
7204
8817
  const stage = useStage(pageSize);
7205
8818
  const columns = gridColumns(stage.tiles.length);
7206
8819
  if (stage.feature === null && stage.tiles.length === 0) {
7207
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "mx-meet__stage mx-meet__stage--empty", children: [
7208
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "mx-meet__empty-title", children: "Waiting for others to join" }),
7209
- /* @__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." })
7210
8823
  ] });
7211
8824
  }
7212
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: `mx-meet__stage${stage.feature !== null ? " mx-meet__stage--speaker" : ""}`, children: [
7213
- stage.feature !== null ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(ParticipantTile, { participant: stage.feature, featured: true }) : null,
7214
- /* @__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)(
7215
8828
  "div",
7216
8829
  {
7217
8830
  className: "mx-meet__grid",
7218
8831
  style: { "--mx-meet-columns": columns },
7219
- 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))
7220
8833
  }
7221
8834
  ),
7222
- 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: [
7223
8836
  "+",
7224
8837
  stage.overflow,
7225
8838
  " more ",
@@ -7232,20 +8845,28 @@ var MEET_REACTIONS = ["\u{1F496}", "\u{1F44D}", "\u{1F389}", "\u{1F44F}", "\u{1F
7232
8845
  function ControlBar({ onLeave }) {
7233
8846
  const room = useRoom();
7234
8847
  const recording = useRecording();
7235
- const [panel, setPanel] = (0, import_react4.useState)("none");
7236
- const [chatTo, setChatTo] = (0, import_react4.useState)(null);
7237
- const [popover, setPopover] = (0, import_react4.useState)("none");
7238
- 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);
7239
8852
  const snapshot = useMeetSnapshot();
7240
8853
  const lobby = useLobby();
7241
8854
  const controls = useHostControls();
7242
8855
  const queue = useHandQueue();
7243
8856
  const micUnavailable = useLocalMedia().microphone.unavailable;
7244
8857
  const unread = useUnreadChat(panel === "chat");
8858
+ const [whiteboard, setWhiteboard] = (0, import_react5.useState)(false);
7245
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
+ });
7246
8867
  const privateChatAt = snapshot?.privateChatRequest?.at ?? null;
7247
8868
  const meetStore = useMeetHost()?.store ?? null;
7248
- (0, import_react4.useEffect)(() => {
8869
+ (0, import_react5.useEffect)(() => {
7249
8870
  const request = meetStore?.snapshot().privateChatRequest ?? null;
7250
8871
  if (request === null) return;
7251
8872
  setChatTo(request.to);
@@ -7261,11 +8882,11 @@ function ControlBar({ onLeave }) {
7261
8882
  help: () => setShortcuts(true)
7262
8883
  });
7263
8884
  const hasSpotlight = snapshot?.spotlight !== null && snapshot?.spotlight !== void 0;
7264
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_jsx_runtime3.Fragment, { children: [
7265
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(MeetingOverlays, {}),
7266
- shortcuts ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(ShortcutsSheet, { onClose: () => setShortcuts(false) }) : null,
7267
- panel === "chat" ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(ChatPanel, { onClose: () => setPanel("none"), to: chatTo, onTo: setChatTo }) : null,
7268
- 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)(
7269
8890
  PeoplePanel,
7270
8891
  {
7271
8892
  onClose: () => setPanel("none"),
@@ -7275,48 +8896,53 @@ function ControlBar({ onLeave }) {
7275
8896
  }
7276
8897
  }
7277
8898
  ) : null,
7278
- panel === "ai" ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(AiPanel, { onClose: () => setPanel("none") }) : null,
7279
- panel === "settings" ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(SettingsPanel, { onClose: () => setPanel("none") }) : null,
7280
- controls.notice !== null && panel !== "people" ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Toast, { text: controls.notice.text, failed: controls.notice.failed, onDone: controls.clearNotice }) : null,
7281
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "mx-meet__controls", children: [
7282
- /* @__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)(
7283
8909
  ControlButton,
7284
8910
  {
7285
8911
  label: micUnavailable !== null ? `Unmute \u2014 ${micUnavailable.remedy}` : room.local?.micEnabled === true ? "Mute (\u2318D)" : "Unmute (\u2318D)",
7286
8912
  active: room.local?.micEnabled === true,
7287
8913
  onClick: () => void room.toggleMicrophone(),
7288
- 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, {})
7289
8915
  }
7290
8916
  ),
7291
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
8917
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
7292
8918
  ControlButton,
7293
8919
  {
7294
8920
  label: room.local?.cameraEnabled === true ? "Stop video (\u2318E)" : "Start video (\u2318E)",
7295
8921
  active: room.local?.cameraEnabled === true,
7296
8922
  onClick: () => void room.toggleCamera(),
7297
- 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, {})
7298
8924
  }
7299
8925
  ),
7300
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
8926
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
7301
8927
  ControlButton,
7302
8928
  {
7303
8929
  label: room.local?.screenSharing === true ? "Stop sharing" : "Share screen",
7304
8930
  active: room.local?.screenSharing === true,
7305
8931
  onClick: () => void room.toggleScreenShare(),
7306
- children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(ScreenShareIcon, {})
8932
+ children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(ScreenShareIcon, {})
7307
8933
  }
7308
8934
  ),
7309
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("span", { className: "mx-meet__anchor", children: [
7310
- /* @__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)(
7311
8937
  ControlButton,
7312
8938
  {
7313
8939
  label: "Send a reaction",
7314
8940
  active: popover === "reactions",
7315
8941
  onClick: () => setPopover(popover === "reactions" ? "none" : "reactions"),
7316
- children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(SmileIcon, {})
8942
+ children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(SmileIcon, {})
7317
8943
  }
7318
8944
  ),
7319
- 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)(
7320
8946
  "button",
7321
8947
  {
7322
8948
  type: "button",
@@ -7328,46 +8954,53 @@ function ControlBar({ onLeave }) {
7328
8954
  emoji
7329
8955
  )) }) }) : null
7330
8956
  ] }),
7331
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
8957
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
7332
8958
  ControlButton,
7333
8959
  {
7334
8960
  label: room.local?.handRaised === true ? "Lower hand (\u2318\u2325H)" : "Raise hand (\u2318\u2325H)",
7335
8961
  active: room.local?.handRaised === true,
7336
8962
  onClick: () => void room.toggleHand(),
7337
- children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(HandIcon, {})
8963
+ children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(HandIcon, {})
7338
8964
  }
7339
8965
  ),
7340
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(ControlButton, { label: "Chat (\u2318\u2325C)", active: panel === "chat", onClick: () => toggle("chat"), children: [
7341
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(ChatIcon, {}),
7342
- 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
7343
8969
  ] }),
7344
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
8970
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
7345
8971
  ControlButton,
7346
8972
  {
7347
8973
  label: lobby.waiting.length > 0 ? `People \u2014 ${lobby.waiting.length} waiting` : `People \u2014 ${(snapshot?.participants ?? []).length} in the meeting`,
7348
8974
  active: panel === "people",
7349
8975
  onClick: () => toggle("people"),
7350
8976
  children: [
7351
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(PeopleIcon, {}),
7352
- 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
7353
8979
  ]
7354
8980
  }
7355
8981
  ),
7356
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(AiControl, { active: panel === "ai", onToggle: () => toggle("ai") }),
7357
- 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,
7358
- 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,
7359
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("span", { className: "mx-meet__anchor", children: [
7360
- /* @__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)(
7361
8994
  ControlButton,
7362
8995
  {
7363
8996
  label: "More options",
7364
8997
  active: popover === "more" || panel === "settings",
7365
8998
  onClick: () => setPopover(popover === "more" ? "none" : "more"),
7366
- children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(MoreIcon, {})
8999
+ children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(MoreIcon, {})
7367
9000
  }
7368
9001
  ),
7369
- 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: [
7370
- /* @__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)(
7371
9004
  MenuItem,
7372
9005
  {
7373
9006
  onSelect: () => {
@@ -7375,12 +9008,12 @@ function ControlBar({ onLeave }) {
7375
9008
  setPanel("settings");
7376
9009
  },
7377
9010
  children: [
7378
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(SettingsIcon, { width: 16, height: 16 }),
7379
- " Audio, video and effects"
9011
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(SettingsIcon, { width: 16, height: 16 }),
9012
+ " Settings"
7380
9013
  ]
7381
9014
  }
7382
9015
  ),
7383
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
9016
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
7384
9017
  MenuItem,
7385
9018
  {
7386
9019
  onSelect: () => {
@@ -7388,14 +9021,14 @@ function ControlBar({ onLeave }) {
7388
9021
  setShortcuts(true);
7389
9022
  },
7390
9023
  children: [
7391
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(KeyboardIcon, { width: 16, height: 16 }),
9024
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(KeyboardIcon, { width: 16, height: 16 }),
7392
9025
  " Keyboard shortcuts"
7393
9026
  ]
7394
9027
  }
7395
9028
  ),
7396
- controls.isHost ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_jsx_runtime3.Fragment, { children: [
7397
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "mx-meet__menu-sep", role: "separator" }),
7398
- /* @__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)(
7399
9032
  MenuItem,
7400
9033
  {
7401
9034
  onSelect: () => {
@@ -7403,12 +9036,12 @@ function ControlBar({ onLeave }) {
7403
9036
  void controls.run({ action: "mute_all" });
7404
9037
  },
7405
9038
  children: [
7406
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(MicOffIcon, { width: 16, height: 16 }),
9039
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(MicOffIcon, { width: 16, height: 16 }),
7407
9040
  " Mute everyone"
7408
9041
  ]
7409
9042
  }
7410
9043
  ),
7411
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
9044
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
7412
9045
  MenuItem,
7413
9046
  {
7414
9047
  onSelect: () => {
@@ -7416,12 +9049,12 @@ function ControlBar({ onLeave }) {
7416
9049
  void controls.run({ action: "ask_all_unmute" });
7417
9050
  },
7418
9051
  children: [
7419
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(MicIcon, { width: 16, height: 16 }),
9052
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(MicIcon, { width: 16, height: 16 }),
7420
9053
  " Ask everyone to unmute"
7421
9054
  ]
7422
9055
  }
7423
9056
  ),
7424
- queue.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
9057
+ queue.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
7425
9058
  MenuItem,
7426
9059
  {
7427
9060
  onSelect: () => {
@@ -7429,14 +9062,14 @@ function ControlBar({ onLeave }) {
7429
9062
  void controls.run({ action: "lower_all_hands" });
7430
9063
  },
7431
9064
  children: [
7432
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(HandIcon, { width: 16, height: 16 }),
9065
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(HandIcon, { width: 16, height: 16 }),
7433
9066
  " Lower all hands (",
7434
9067
  queue.length,
7435
9068
  ")"
7436
9069
  ]
7437
9070
  }
7438
9071
  ) : null,
7439
- hasSpotlight ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
9072
+ hasSpotlight ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
7440
9073
  MenuItem,
7441
9074
  {
7442
9075
  onSelect: () => {
@@ -7444,7 +9077,7 @@ function ControlBar({ onLeave }) {
7444
9077
  void controls.run({ action: "spotlight", identity: null });
7445
9078
  },
7446
9079
  children: [
7447
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(SpotlightIcon, { width: 16, height: 16 }),
9080
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(SpotlightIcon, { width: 16, height: 16 }),
7448
9081
  " Remove spotlight"
7449
9082
  ]
7450
9083
  }
@@ -7452,7 +9085,7 @@ function ControlBar({ onLeave }) {
7452
9085
  ] }) : null
7453
9086
  ] }) }) : null
7454
9087
  ] }),
7455
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
9088
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
7456
9089
  ControlButton,
7457
9090
  {
7458
9091
  label: "Leave",
@@ -7461,7 +9094,7 @@ function ControlBar({ onLeave }) {
7461
9094
  void room.leave();
7462
9095
  onLeave?.();
7463
9096
  },
7464
- children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(PhoneOffIcon, {})
9097
+ children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(PhoneOffIcon, {})
7465
9098
  }
7466
9099
  )
7467
9100
  ] })
@@ -7471,13 +9104,13 @@ function useUnreadChat(open) {
7471
9104
  const snapshot = useMeetSnapshot();
7472
9105
  const chat = snapshot?.chat ?? [];
7473
9106
  const local = snapshot?.localIdentity ?? null;
7474
- const [seen, setSeen] = (0, import_react4.useState)(0);
7475
- (0, import_react4.useEffect)(() => {
9107
+ const [seen, setSeen] = (0, import_react5.useState)(0);
9108
+ (0, import_react5.useEffect)(() => {
7476
9109
  if (open) setSeen(chat.length);
7477
9110
  }, [open, chat.length]);
7478
9111
  const loaded = snapshot?.chatLoaded === true;
7479
- const [baseline, setBaseline] = (0, import_react4.useState)(null);
7480
- (0, import_react4.useEffect)(() => {
9112
+ const [baseline, setBaseline] = (0, import_react5.useState)(null);
9113
+ (0, import_react5.useEffect)(() => {
7481
9114
  if (loaded && baseline === null) setBaseline(chat.length);
7482
9115
  }, [loaded, baseline, chat.length]);
7483
9116
  if (open) return 0;
@@ -7490,14 +9123,14 @@ function Popover({
7490
9123
  children,
7491
9124
  placement = "up"
7492
9125
  }) {
7493
- const ref = (0, import_react4.useRef)(null);
7494
- const [style, setStyle] = (0, import_react4.useState)({
9126
+ const ref = (0, import_react5.useRef)(null);
9127
+ const [style, setStyle] = (0, import_react5.useState)({
7495
9128
  position: "fixed",
7496
9129
  top: 0,
7497
9130
  left: 0,
7498
9131
  visibility: "hidden"
7499
9132
  });
7500
- (0, import_react4.useLayoutEffect)(() => {
9133
+ (0, import_react5.useLayoutEffect)(() => {
7501
9134
  const element = ref.current;
7502
9135
  const anchor = element?.parentElement ?? null;
7503
9136
  if (element === null || anchor === null) return;
@@ -7542,7 +9175,7 @@ function Popover({
7542
9175
  window.removeEventListener("scroll", place, true);
7543
9176
  };
7544
9177
  }, [placement]);
7545
- (0, import_react4.useEffect)(() => {
9178
+ (0, import_react5.useEffect)(() => {
7546
9179
  const onKey = (event) => {
7547
9180
  if (event.key === "Escape") onClose();
7548
9181
  };
@@ -7557,14 +9190,14 @@ function Popover({
7557
9190
  window.removeEventListener("pointerdown", onPointer);
7558
9191
  };
7559
9192
  }, [onClose]);
7560
- 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 });
7561
9194
  }
7562
9195
  function MenuItem({
7563
9196
  onSelect,
7564
9197
  danger = false,
7565
9198
  children
7566
9199
  }) {
7567
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
9200
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
7568
9201
  "button",
7569
9202
  {
7570
9203
  type: "button",
@@ -7576,28 +9209,28 @@ function MenuItem({
7576
9209
  );
7577
9210
  }
7578
9211
  function Toast({ text: text3, failed, onDone }) {
7579
- (0, import_react4.useEffect)(() => {
9212
+ (0, import_react5.useEffect)(() => {
7580
9213
  const timer = setTimeout(onDone, failed ? 7e3 : 4e3);
7581
9214
  return () => clearTimeout(timer);
7582
9215
  }, [text3, failed, onDone]);
7583
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: failed ? "mx-meet__toast mx-meet__toast--failed" : "mx-meet__toast", role: "status", children: [
7584
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { children: text3 }),
7585
- /* @__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 }) })
7586
9219
  ] });
7587
9220
  }
7588
9221
  function MeetingOverlays() {
7589
9222
  const reactions = useReactions();
7590
9223
  const { notice, dismiss } = useModerationNotice();
7591
9224
  const room = useRoom();
7592
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_jsx_runtime3.Fragment, { children: [
7593
- /* @__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 }),
7594
9227
  notice !== null && notice.kind !== "removed" ? (
7595
9228
  // A host's request ("the host is asking you to unmute"), not an error:
7596
9229
  // an assertive status, so it is announced at once without being filed
7597
9230
  // as a failure (design-system error-box census).
7598
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "mx-meet__notice-bar", role: "status", "aria-live": "assertive", children: [
7599
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { children: notice.text }),
7600
- 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)(
7601
9234
  "button",
7602
9235
  {
7603
9236
  type: "button",
@@ -7609,20 +9242,20 @@ function MeetingOverlays() {
7609
9242
  children: "Unmute"
7610
9243
  }
7611
9244
  ) : null,
7612
- /* @__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 }) })
7613
9246
  ] })
7614
9247
  ) : null
7615
9248
  ] });
7616
9249
  }
7617
9250
  function ShortcutsSheet({ onClose }) {
7618
- (0, import_react4.useEffect)(() => {
9251
+ (0, import_react5.useEffect)(() => {
7619
9252
  const onKey = (event) => {
7620
9253
  if (event.key === "Escape") onClose();
7621
9254
  };
7622
9255
  window.addEventListener("keydown", onKey);
7623
9256
  return () => window.removeEventListener("keydown", onKey);
7624
9257
  }, [onClose]);
7625
- 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)(
7626
9259
  "div",
7627
9260
  {
7628
9261
  className: "mx-meet__sheet",
@@ -7630,13 +9263,13 @@ function ShortcutsSheet({ onClose }) {
7630
9263
  "aria-label": "Keyboard shortcuts",
7631
9264
  onClick: (event) => event.stopPropagation(),
7632
9265
  children: [
7633
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("header", { className: "mx-meet__panel-head", children: [
7634
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("h2", { className: "mx-meet__panel-title", children: "Keyboard shortcuts" }),
7635
- /* @__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 }) })
7636
9269
  ] }),
7637
- /* @__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: [
7638
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("dt", { children: shortcut.label }),
7639
- /* @__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 }) })
7640
9273
  ] }, shortcut.id)) })
7641
9274
  ]
7642
9275
  }
@@ -7646,19 +9279,19 @@ function AiControl({ active, onToggle }) {
7646
9279
  const snapshot = useMeetSnapshot();
7647
9280
  const meeting = snapshot?.meeting ?? null;
7648
9281
  if (meeting === null || !meeting.aiEnabled) return null;
7649
- 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, {}) });
7650
9283
  }
7651
9284
  function PanelShell({
7652
9285
  title,
7653
9286
  onClose,
7654
9287
  children
7655
9288
  }) {
7656
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("aside", { className: "mx-meet__panel", "aria-label": title, children: [
7657
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("header", { className: "mx-meet__panel-head", children: [
7658
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("h2", { className: "mx-meet__panel-title", children: title }),
7659
- /* @__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 }) })
7660
9293
  ] }),
7661
- /* @__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 })
7662
9295
  ] });
7663
9296
  }
7664
9297
  function ChatPanel({
@@ -7668,17 +9301,17 @@ function ChatPanel({
7668
9301
  }) {
7669
9302
  const snapshot = useMeetSnapshot();
7670
9303
  const room = useRoom();
7671
- const [draft, setDraft] = (0, import_react4.useState)("");
7672
- const [recipient, setRecipient] = (0, import_react4.useState)(to);
7673
- 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);
7674
9307
  const messages = snapshot?.chat ?? [];
7675
9308
  const local = snapshot?.localIdentity ?? null;
7676
9309
  const people = (snapshot?.participants ?? []).filter(
7677
9310
  (participant) => !participant.isLocal && !participant.isAgent
7678
9311
  );
7679
9312
  const recipientName = recipient === null ? null : people.find((p) => p.identity === recipient)?.displayName ?? null;
7680
- (0, import_react4.useEffect)(() => setRecipient(to), [to]);
7681
- (0, import_react4.useEffect)(() => {
9313
+ (0, import_react5.useEffect)(() => setRecipient(to), [to]);
9314
+ (0, import_react5.useEffect)(() => {
7682
9315
  const list = listRef.current;
7683
9316
  if (list !== null) list.scrollTop = list.scrollHeight;
7684
9317
  }, [messages.length]);
@@ -7686,13 +9319,13 @@ function ChatPanel({
7686
9319
  setRecipient(next);
7687
9320
  onTo?.(next);
7688
9321
  };
7689
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(PanelShell, { title: "Chat", onClose, children: [
7690
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("ul", { className: "mx-meet__chat", ref: listRef, children: [
7691
- snapshot?.chatHistoryError != null ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("li", { className: "mx-meet__panel-note", children: snapshot.chatHistoryError }) : null,
7692
- 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,
7693
- 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))
7694
9327
  ] }),
7695
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
9328
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
7696
9329
  "form",
7697
9330
  {
7698
9331
  className: "mx-meet__composer mx-meet__composer--chat",
@@ -7705,7 +9338,7 @@ function ChatPanel({
7705
9338
  else void room.sendPrivateChat(recipient, text3);
7706
9339
  },
7707
9340
  children: [
7708
- people.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
9341
+ people.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
7709
9342
  "select",
7710
9343
  {
7711
9344
  className: "mx-meet__select mx-meet__select--compact",
@@ -7713,16 +9346,16 @@ function ChatPanel({
7713
9346
  value: recipient ?? "",
7714
9347
  onChange: (event) => choose(event.target.value === "" ? null : event.target.value),
7715
9348
  children: [
7716
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("option", { value: "", children: "Everyone" }),
7717
- 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: [
7718
9351
  participant.displayName,
7719
9352
  " (private)"
7720
9353
  ] }, participant.identity))
7721
9354
  ]
7722
9355
  }
7723
9356
  ) : null,
7724
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "mx-meet__composer-row", children: [
7725
- /* @__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)(
7726
9359
  "input",
7727
9360
  {
7728
9361
  className: "mx-meet__input",
@@ -7733,9 +9366,9 @@ function ChatPanel({
7733
9366
  maxLength: 4e3
7734
9367
  }
7735
9368
  ),
7736
- /* @__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" })
7737
9370
  ] }),
7738
- 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: [
7739
9372
  "Only ",
7740
9373
  recipientName,
7741
9374
  " sees this. Private messages are not saved."
@@ -7753,7 +9386,7 @@ function ChatLine({
7753
9386
  const mine = message.identity === local;
7754
9387
  const privateTo = message.to ?? null;
7755
9388
  const counterpart = privateTo === null ? null : mine ? people.find((p) => p.identity === privateTo)?.displayName ?? "them" : "you";
7756
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
9389
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
7757
9390
  "li",
7758
9391
  {
7759
9392
  className: [
@@ -7762,17 +9395,17 @@ function ChatLine({
7762
9395
  message.failed !== void 0 ? "mx-meet__chat-line--failed" : ""
7763
9396
  ].filter(Boolean).join(" "),
7764
9397
  children: [
7765
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("span", { className: "mx-meet__chat-meta", children: [
7766
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("strong", { children: mine ? "You" : message.displayName }),
7767
- 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: [
7768
9401
  "to ",
7769
9402
  counterpart,
7770
9403
  " \xB7 private"
7771
9404
  ] }) : null,
7772
- /* @__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) })
7773
9406
  ] }),
7774
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "mx-meet__chat-text", children: message.text }),
7775
- 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
7776
9409
  ]
7777
9410
  }
7778
9411
  );
@@ -7784,22 +9417,22 @@ function PeoplePanel({
7784
9417
  const snapshot = useMeetSnapshot();
7785
9418
  const controls = useHostControls();
7786
9419
  const queue = useHandQueue();
7787
- const [query, setQuery] = (0, import_react4.useState)("");
7788
- 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);
7789
9422
  const myRole = useRole();
7790
9423
  const local = snapshot?.localIdentity ?? null;
7791
9424
  const everyone = snapshot?.participants ?? [];
7792
9425
  const needle = query.trim().toLowerCase();
7793
9426
  const shown = needle.length === 0 ? everyone : everyone.filter((participant) => participant.displayName.toLowerCase().includes(needle));
7794
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(PanelShell, { title: `People (${everyone.length})`, onClose, children: [
7795
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(LobbyPanel, {}),
7796
- queue.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("section", { className: "mx-meet__section", "aria-label": "Raised hands", children: [
7797
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("header", { className: "mx-meet__section-head", children: [
7798
- /* @__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: [
7799
9432
  "Raised hands \xB7 ",
7800
9433
  queue.length
7801
9434
  ] }),
7802
- controls.isHost ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
9435
+ controls.isHost ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
7803
9436
  "button",
7804
9437
  {
7805
9438
  type: "button",
@@ -7809,13 +9442,13 @@ function PeoplePanel({
7809
9442
  }
7810
9443
  ) : null
7811
9444
  ] }),
7812
- /* @__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: [
7813
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Avatar, { name: participant.displayName, url: participant.avatarUrl, size: 28 }),
7814
- /* @__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: [
7815
9448
  participant.displayName,
7816
- 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
7817
9450
  ] }),
7818
- controls.isHost || participant.identity === local ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
9451
+ controls.isHost || participant.identity === local ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
7819
9452
  "button",
7820
9453
  {
7821
9454
  type: "button",
@@ -7826,27 +9459,27 @@ function PeoplePanel({
7826
9459
  ) : null
7827
9460
  ] }, participant.identity)) })
7828
9461
  ] }) : null,
7829
- controls.isHost && everyone.length > 1 ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "mx-meet__bulk", children: [
7830
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("button", { type: "button", className: "mx-meet__chip", onClick: () => void controls.run({ action: "mute_all" }), children: [
7831
- /* @__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 }),
7832
9465
  " Mute all"
7833
9466
  ] }),
7834
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
9467
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
7835
9468
  "button",
7836
9469
  {
7837
9470
  type: "button",
7838
9471
  className: "mx-meet__chip",
7839
9472
  onClick: () => void controls.run({ action: "ask_all_unmute" }),
7840
9473
  children: [
7841
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(MicIcon, { width: 14, height: 14 }),
9474
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(MicIcon, { width: 14, height: 14 }),
7842
9475
  " Ask all to unmute"
7843
9476
  ]
7844
9477
  }
7845
9478
  )
7846
9479
  ] }) : null,
7847
- everyone.length > 4 ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("label", { className: "mx-meet__search", children: [
7848
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(SearchIcon, { width: 16, height: 16 }),
7849
- /* @__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)(
7850
9483
  "input",
7851
9484
  {
7852
9485
  className: "mx-meet__input mx-meet__input--bare",
@@ -7857,31 +9490,31 @@ function PeoplePanel({
7857
9490
  }
7858
9491
  )
7859
9492
  ] }) : null,
7860
- 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,
7861
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("ul", { className: "mx-meet__people", children: [
7862
- shown.map((participant) => /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("li", { className: "mx-meet__person", children: [
7863
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Avatar, { name: participant.displayName, url: participant.avatarUrl, size: 32 }),
7864
- /* @__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: [
7865
9498
  participant.displayName,
7866
- participant.identity === local ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "mx-meet__you", children: " (you)" }) : null,
7867
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(RoleBadge, { role: participant.identity === local ? myRole : participant.role }),
7868
- isNoteTaker(participant) ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "mx-meet__badge", children: "Meeting assistant" }) : null,
7869
- 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
7870
9503
  ] }),
7871
- participant.handRaised ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(HandIcon, { width: 14, height: 14 }) : null,
7872
- !participant.micEnabled && !isNoteTaker(participant) ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(MicOffIcon, { width: 14, height: 14 }) : null,
7873
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(QualityBars, { quality: participant.quality }),
7874
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("span", { className: "mx-meet__anchor", children: [
7875
- /* @__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)(
7876
9509
  ControlButton,
7877
9510
  {
7878
9511
  label: `More for ${participant.displayName}`,
7879
9512
  active: menuFor === participant.identity,
7880
9513
  onClick: () => setMenuFor(menuFor === participant.identity ? null : participant.identity),
7881
- 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 })
7882
9515
  }
7883
9516
  ),
7884
- menuFor === participant.identity ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
9517
+ menuFor === participant.identity ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
7885
9518
  PersonMenu,
7886
9519
  {
7887
9520
  participant,
@@ -7892,13 +9525,13 @@ function PeoplePanel({
7892
9525
  ) : null
7893
9526
  ] })
7894
9527
  ] }, participant.identity)),
7895
- 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: [
7896
9529
  "Nobody matches \u201C",
7897
9530
  query,
7898
9531
  "\u201D."
7899
9532
  ] }) : null
7900
9533
  ] }),
7901
- 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
7902
9535
  ] });
7903
9536
  }
7904
9537
  function PersonMenu({
@@ -7910,14 +9543,14 @@ function PersonMenu({
7910
9543
  const host = useMeetHost();
7911
9544
  const snapshot = useMeetSnapshot();
7912
9545
  const controls = useHostControls();
7913
- const [mode, setMode] = (0, import_react4.useState)("menu");
7914
- const [text3, setText] = (0, import_react4.useState)("");
9546
+ const [mode, setMode] = (0, import_react5.useState)("menu");
9547
+ const [text3, setText] = (0, import_react5.useState)("");
7915
9548
  const self = participant.identity === snapshot?.localIdentity;
7916
9549
  const moderate = controls.canModerate(participant);
7917
9550
  const pinned = snapshot?.pinned === participant.identity;
7918
9551
  const spotlit = snapshot?.spotlight === participant.identity;
7919
9552
  const hasAccount = participant.userId !== null;
7920
- const [refused, setRefused] = (0, import_react4.useState)(false);
9553
+ const [refused, setRefused] = (0, import_react5.useState)(false);
7921
9554
  const act = (request) => {
7922
9555
  setRefused(false);
7923
9556
  void controls.run(request).then((result) => {
@@ -7925,10 +9558,10 @@ function PersonMenu({
7925
9558
  else setRefused(true);
7926
9559
  });
7927
9560
  };
7928
- 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;
7929
9562
  if (mode === "rename" || mode === "report") {
7930
9563
  const renaming = mode === "rename";
7931
- 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)(
7932
9565
  "form",
7933
9566
  {
7934
9567
  className: "mx-meet__menu-form",
@@ -7940,9 +9573,9 @@ function PersonMenu({
7940
9573
  );
7941
9574
  },
7942
9575
  children: [
7943
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("label", { className: "mx-meet__field", children: [
7944
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "mx-meet__field-label", children: renaming ? "Name shown in this meeting" : `What did ${participant.displayName} do?` }),
7945
- 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)(
7946
9579
  "input",
7947
9580
  {
7948
9581
  className: "mx-meet__input",
@@ -7951,7 +9584,7 @@ function PersonMenu({
7951
9584
  value: text3,
7952
9585
  onChange: (event) => setText(event.target.value)
7953
9586
  }
7954
- ) : /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
9587
+ ) : /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
7955
9588
  "textarea",
7956
9589
  {
7957
9590
  className: "mx-meet__input",
@@ -7964,9 +9597,9 @@ function PersonMenu({
7964
9597
  )
7965
9598
  ] }),
7966
9599
  refusal2,
7967
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "mx-meet__menu-actions", children: [
7968
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("button", { type: "button", className: "mx-meet__link", onClick: () => setMode("menu"), children: "Back" }),
7969
- /* @__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" })
7970
9603
  ] })
7971
9604
  ]
7972
9605
  }
@@ -7974,12 +9607,12 @@ function PersonMenu({
7974
9607
  }
7975
9608
  if (mode === "remove" || mode === "transfer") {
7976
9609
  const removing = mode === "remove";
7977
- 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: [
7978
- /* @__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.` }),
7979
9612
  refusal2,
7980
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "mx-meet__menu-actions", children: [
7981
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("button", { type: "button", className: "mx-meet__link", onClick: () => setMode("menu"), children: "Cancel" }),
7982
- /* @__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)(
7983
9616
  "button",
7984
9617
  {
7985
9618
  type: "button",
@@ -7992,8 +9625,8 @@ function PersonMenu({
7992
9625
  ] })
7993
9626
  ] }) });
7994
9627
  }
7995
- 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: [
7996
- /* @__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)(
7997
9630
  MenuItem,
7998
9631
  {
7999
9632
  onSelect: () => {
@@ -8001,13 +9634,13 @@ function PersonMenu({
8001
9634
  onClose();
8002
9635
  },
8003
9636
  children: [
8004
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(PinIcon, { width: 16, height: 16 }),
9637
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(PinIcon, { width: 16, height: 16 }),
8005
9638
  " ",
8006
9639
  pinned ? "Unpin" : "Pin for me"
8007
9640
  ]
8008
9641
  }
8009
9642
  ),
8010
- !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)(
8011
9644
  MenuItem,
8012
9645
  {
8013
9646
  onSelect: () => {
@@ -8019,42 +9652,42 @@ function PersonMenu({
8019
9652
  onClose();
8020
9653
  },
8021
9654
  children: [
8022
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(ChatIcon, { width: 16, height: 16 }),
9655
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(ChatIcon, { width: 16, height: 16 }),
8023
9656
  " Message privately"
8024
9657
  ]
8025
9658
  }
8026
9659
  ) : null,
8027
- controls.isHost ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(MenuItem, { onSelect: () => act({ action: "spotlight", identity: spotlit ? null : participant.identity }), children: [
8028
- /* @__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 }),
8029
9662
  " ",
8030
9663
  spotlit ? "Remove spotlight" : "Spotlight for everyone"
8031
9664
  ] }) : null,
8032
- moderate ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_jsx_runtime3.Fragment, { children: [
8033
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "mx-meet__menu-sep", role: "separator" }),
8034
- participant.micEnabled ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(MenuItem, { onSelect: () => act({ action: "mute", identity: participant.identity }), children: [
8035
- /* @__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 }),
8036
9669
  " Mute"
8037
- ] }) : !participant.isAgent ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(MenuItem, { onSelect: () => act({ action: "ask_unmute", identity: participant.identity }), children: [
8038
- /* @__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 }),
8039
9672
  " Ask to unmute"
8040
9673
  ] }) : null,
8041
- participant.cameraEnabled ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(MenuItem, { onSelect: () => act({ action: "stop_video", identity: participant.identity }), children: [
8042
- /* @__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 }),
8043
9676
  " Stop video"
8044
9677
  ] }) : null,
8045
- participant.screenSharing ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(MenuItem, { onSelect: () => act({ action: "stop_screen", identity: participant.identity }), children: [
8046
- /* @__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 }),
8047
9680
  " Stop screen share"
8048
9681
  ] }) : null,
8049
- participant.handRaised ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(MenuItem, { onSelect: () => act({ action: "lower_hand", identity: participant.identity }), children: [
8050
- /* @__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 }),
8051
9684
  " Lower hand"
8052
9685
  ] }) : null,
8053
- hasAccount && !participant.isAgent && participant.role !== "cohost" ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(MenuItem, { onSelect: () => act({ action: "make_cohost", identity: participant.identity }), children: [
8054
- /* @__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 }),
8055
9688
  " Make co-host"
8056
9689
  ] }) : null,
8057
- !participant.isAgent ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
9690
+ !participant.isAgent ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
8058
9691
  MenuItem,
8059
9692
  {
8060
9693
  onSelect: () => {
@@ -8062,21 +9695,21 @@ function PersonMenu({
8062
9695
  setMode("rename");
8063
9696
  },
8064
9697
  children: [
8065
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(PencilIcon, { width: 16, height: 16 }),
9698
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(PencilIcon, { width: 16, height: 16 }),
8066
9699
  " Rename"
8067
9700
  ]
8068
9701
  }
8069
9702
  ) : null
8070
9703
  ] }) : null,
8071
- controls.isOwner && participant.role === "cohost" ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(MenuItem, { onSelect: () => act({ action: "revoke_cohost", identity: participant.identity }), children: [
8072
- /* @__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 }),
8073
9706
  " Remove co-host"
8074
9707
  ] }) : null,
8075
- controls.isOwner && !self && hasAccount && !participant.isAgent ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(MenuItem, { onSelect: () => setMode("transfer"), children: [
8076
- /* @__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 }),
8077
9710
  " Make host"
8078
9711
  ] }) : null,
8079
- self ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
9712
+ self ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
8080
9713
  MenuItem,
8081
9714
  {
8082
9715
  onSelect: () => {
@@ -8084,12 +9717,12 @@ function PersonMenu({
8084
9717
  setMode("rename");
8085
9718
  },
8086
9719
  children: [
8087
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(PencilIcon, { width: 16, height: 16 }),
9720
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(PencilIcon, { width: 16, height: 16 }),
8088
9721
  " Rename yourself"
8089
9722
  ]
8090
9723
  }
8091
9724
  ) : null,
8092
- !self && !participant.isAgent ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
9725
+ !self && !participant.isAgent ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
8093
9726
  MenuItem,
8094
9727
  {
8095
9728
  onSelect: () => {
@@ -8097,21 +9730,21 @@ function PersonMenu({
8097
9730
  setMode("report");
8098
9731
  },
8099
9732
  children: [
8100
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(FlagIcon, { width: 16, height: 16 }),
9733
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(FlagIcon, { width: 16, height: 16 }),
8101
9734
  " Report"
8102
9735
  ]
8103
9736
  }
8104
9737
  ) : null,
8105
- moderate && !participant.isAgent ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(MenuItem, { danger: true, onSelect: () => setMode("remove"), children: [
8106
- /* @__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 }),
8107
9740
  " Remove from meeting"
8108
9741
  ] }) : null
8109
9742
  ] }) });
8110
9743
  }
8111
9744
  function SettingsPanel({ onClose }) {
8112
9745
  const host = useRequiredMeetHost();
8113
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(PanelShell, { title: "Audio, video and effects", onClose, children: [
8114
- /* @__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)(
8115
9748
  DeviceSettings,
8116
9749
  {
8117
9750
  onPick: (kind, deviceId2) => {
@@ -8120,7 +9753,8 @@ function SettingsPanel({ onClose }) {
8120
9753
  }
8121
9754
  }
8122
9755
  ),
8123
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(EffectsSettings, {})
9756
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(EffectsSettings, {}),
9757
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(CaptionLanguageSettings, {})
8124
9758
  ] });
8125
9759
  }
8126
9760
  function DeviceSettings({
@@ -8132,15 +9766,15 @@ function DeviceSettings({
8132
9766
  const speaker = devices?.selected.audiooutput ?? host.devices.resolve("audiooutput");
8133
9767
  const stream = useMicrophoneStream(microphone);
8134
9768
  const level = useAudioLevel(stream);
8135
- const [testing, setTesting] = (0, import_react4.useState)(false);
8136
- (0, import_react4.useEffect)(() => {
9769
+ const [testing, setTesting] = (0, import_react5.useState)(false);
9770
+ (0, import_react5.useEffect)(() => {
8137
9771
  void host.devices.refresh();
8138
9772
  }, [host]);
8139
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("section", { className: "mx-meet__section", "aria-label": "Devices", children: [
8140
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(DevicePicker, { kind: "audioinput", label: "Microphone", onPick }),
8141
- /* @__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))}%` } }) }),
8142
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(DevicePicker, { kind: "audiooutput", label: "Speaker", onPick }),
8143
- /* @__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)(
8144
9778
  "button",
8145
9779
  {
8146
9780
  type: "button",
@@ -8151,19 +9785,19 @@ function DeviceSettings({
8151
9785
  void playTestSound(speaker).finally(() => setTesting(false));
8152
9786
  },
8153
9787
  children: [
8154
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(SpeakerIcon, { width: 14, height: 14 }),
9788
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(SpeakerIcon, { width: 14, height: 14 }),
8155
9789
  " ",
8156
9790
  testing ? "Playing\u2026" : "Test speaker"
8157
9791
  ]
8158
9792
  }
8159
9793
  ),
8160
- /* @__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 })
8161
9795
  ] });
8162
9796
  }
8163
9797
  function EffectsSettings({ preview }) {
8164
9798
  const effects = useMediaEffects();
8165
- const [error, setError] = (0, import_react4.useState)(null);
8166
- const fileRef = (0, import_react4.useRef)(null);
9799
+ const [error, setError] = (0, import_react5.useState)(null);
9800
+ const fileRef = (0, import_react5.useRef)(null);
8167
9801
  const supported = effects.backgroundsSupported || preview != null || videoEffectsSupported();
8168
9802
  const apply = (next) => {
8169
9803
  setError(null);
@@ -8175,9 +9809,9 @@ function EffectsSettings({ preview }) {
8175
9809
  );
8176
9810
  }
8177
9811
  };
8178
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("section", { className: "mx-meet__section", "aria-label": "Effects", children: [
8179
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("label", { className: "mx-meet__toggle", children: [
8180
- /* @__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)(
8181
9815
  "input",
8182
9816
  {
8183
9817
  type: "checkbox",
@@ -8186,11 +9820,11 @@ function EffectsSettings({ preview }) {
8186
9820
  }
8187
9821
  ),
8188
9822
  "Noise suppression",
8189
- /* @__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." })
8190
9824
  ] }),
8191
- supported ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "mx-meet__field", children: [
8192
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "mx-meet__field-label", children: "Background" }),
8193
- /* @__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)(
8194
9828
  "button",
8195
9829
  {
8196
9830
  type: "button",
@@ -8208,7 +9842,7 @@ function EffectsSettings({ preview }) {
8208
9842
  },
8209
9843
  kind
8210
9844
  )) }),
8211
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
9845
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
8212
9846
  "input",
8213
9847
  {
8214
9848
  ref: fileRef,
@@ -8223,7 +9857,7 @@ function EffectsSettings({ preview }) {
8223
9857
  }
8224
9858
  }
8225
9859
  ),
8226
- 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
8227
9861
  ] }) : null
8228
9862
  ] });
8229
9863
  }
@@ -8282,8 +9916,8 @@ async function playTestSound(sinkId) {
8282
9916
  await context.close();
8283
9917
  }
8284
9918
  function useMicrophoneStream(deviceId2) {
8285
- const [stream, setStream] = (0, import_react4.useState)(null);
8286
- (0, import_react4.useEffect)(() => {
9919
+ const [stream, setStream] = (0, import_react5.useState)(null);
9920
+ (0, import_react5.useEffect)(() => {
8287
9921
  if (deviceId2 === "off") return void 0;
8288
9922
  let live = true;
8289
9923
  let opened = null;
@@ -8308,25 +9942,25 @@ function useMicrophoneStream(deviceId2) {
8308
9942
  function LobbyPanel() {
8309
9943
  const lobby = useLobby();
8310
9944
  if (!lobby.canAdmit || lobby.waiting.length === 0) return null;
8311
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("section", { className: "mx-meet__lobby", "aria-label": "Waiting room", children: [
8312
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("header", { className: "mx-meet__lobby-head", children: [
8313
- /* @__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` }),
8314
- /* @__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" })
8315
9949
  ] }),
8316
- /* @__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: [
8317
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Avatar, { name: entry.displayName, url: entry.avatarUrl, size: 32 }),
8318
- /* @__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: [
8319
9953
  entry.displayName,
8320
- 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
8321
9955
  ] }),
8322
- /* @__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 }) }),
8323
- /* @__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)(
8324
9958
  ControlButton,
8325
9959
  {
8326
9960
  label: `Deny ${entry.displayName}`,
8327
9961
  danger: true,
8328
9962
  onClick: () => void lobby.deny(entry),
8329
- 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 })
8330
9964
  }
8331
9965
  )
8332
9966
  ] }, entry.identity)) })
@@ -8336,21 +9970,21 @@ function NoteTakerRow() {
8336
9970
  const ai = useMeetAi();
8337
9971
  const status = ai.noteTaker;
8338
9972
  const duplicateError = status.refusal !== null && ai.error !== null && status.refusal.reason === ai.error.message && status.refusal.remedy === ai.error.remedy;
8339
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("section", { className: "mx-meet__note-taker", "aria-label": "Note-taker", children: [
8340
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("p", { className: `mx-meet__note-taker-state mx-meet__note-taker-state--${status.state}`, children: [
8341
- /* @__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" }),
8342
9976
  ai.noteTakerLabel
8343
9977
  ] }),
8344
- status.detail !== null ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "mx-meet__panel-note", children: status.detail }) : null,
8345
- 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: [
8346
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "mx-meet__refusal-reason", children: status.refusal.reason }),
8347
- 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
8348
9982
  ] }) : null,
8349
- 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: [
8350
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "mx-meet__refusal-reason", children: ai.error.message }),
8351
- /* @__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 })
8352
9986
  ] }) : null,
8353
- 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)(
8354
9988
  "button",
8355
9989
  {
8356
9990
  type: "button",
@@ -8358,7 +9992,7 @@ function NoteTakerRow() {
8358
9992
  onClick: () => void ai.stopNoteTaker(),
8359
9993
  children: "Dismiss the note-taker"
8360
9994
  }
8361
- ) : /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
9995
+ ) : /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
8362
9996
  "button",
8363
9997
  {
8364
9998
  type: "button",
@@ -8374,24 +10008,24 @@ function NoteList({
8374
10008
  notes,
8375
10009
  empty
8376
10010
  }) {
8377
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("section", { className: "mx-meet__note-group", "aria-label": title, children: [
8378
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("h3", { className: "mx-meet__note-group-title", children: title }),
8379
- 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: [
8380
10014
  note.text,
8381
- 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
8382
10016
  ] }, note.id)) })
8383
10017
  ] });
8384
10018
  }
8385
10019
  function AiPanel({ onClose }) {
8386
10020
  const ai = useMeetAi();
8387
- const [question, setQuestion] = (0, import_react4.useState)("");
8388
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(PanelShell, { title: "Meeting assistant", onClose, children: [
8389
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(NoteTakerRow, {}),
8390
- ai.summary !== null ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("section", { className: "mx-meet__note-group", "aria-label": "Summary", children: [
8391
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("h3", { className: "mx-meet__note-group-title", children: "Summary" }),
8392
- /* @__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 })
8393
10027
  ] }) : null,
8394
- 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: [
8395
10029
  "The wrap-up is written \u2014 ",
8396
10030
  ai.wrapUp.noteIds.length,
8397
10031
  " ",
@@ -8403,7 +10037,7 @@ function AiPanel({ onClose }) {
8403
10037
  ai.wrapUp.segmentCount === 1 ? "transcript line" : "transcript lines",
8404
10038
  "."
8405
10039
  ] }) : null,
8406
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
10040
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
8407
10041
  NoteList,
8408
10042
  {
8409
10043
  title: "Notes",
@@ -8411,7 +10045,7 @@ function AiPanel({ onClose }) {
8411
10045
  empty: "Notes appear here as the meeting goes on."
8412
10046
  }
8413
10047
  ),
8414
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
10048
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
8415
10049
  NoteList,
8416
10050
  {
8417
10051
  title: "Decisions",
@@ -8419,7 +10053,7 @@ function AiPanel({ onClose }) {
8419
10053
  empty: "Nothing has been decided yet."
8420
10054
  }
8421
10055
  ),
8422
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
10056
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
8423
10057
  NoteList,
8424
10058
  {
8425
10059
  title: "Action items",
@@ -8427,21 +10061,21 @@ function AiPanel({ onClose }) {
8427
10061
  empty: "No action items yet."
8428
10062
  }
8429
10063
  ),
8430
- ai.transcript.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("section", { className: "mx-meet__note-group", "aria-label": "Transcript", children: [
8431
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("h3", { className: "mx-meet__note-group-title", children: "Transcript" }),
8432
- /* @__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)(
8433
10067
  "li",
8434
10068
  {
8435
10069
  className: line.final && line.source === "record" ? "mx-meet__line" : "mx-meet__line mx-meet__line--interim",
8436
10070
  children: [
8437
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("strong", { children: line.speaker }),
8438
- /* @__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 })
8439
10073
  ]
8440
10074
  },
8441
10075
  line.id
8442
10076
  )) })
8443
10077
  ] }) : null,
8444
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
10078
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
8445
10079
  "form",
8446
10080
  {
8447
10081
  className: "mx-meet__composer",
@@ -8452,7 +10086,7 @@ function AiPanel({ onClose }) {
8452
10086
  void ai.ask(asked);
8453
10087
  },
8454
10088
  children: [
8455
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
10089
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
8456
10090
  "input",
8457
10091
  {
8458
10092
  className: "mx-meet__input",
@@ -8462,13 +10096,13 @@ function AiPanel({ onClose }) {
8462
10096
  "aria-label": "Ask about this meeting"
8463
10097
  }
8464
10098
  ),
8465
- /* @__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" })
8466
10100
  ]
8467
10101
  }
8468
10102
  ),
8469
- ai.asking && ai.phase !== null ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "mx-meet__panel-note", role: "status", children: ai.phase }) : null,
8470
- ai.answer !== null ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "mx-meet__answer", children: ai.answer }) : null,
8471
- 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: [
8472
10106
  "Answered from ",
8473
10107
  ai.coverage.segmentsUsed,
8474
10108
  " of ",
@@ -8477,48 +10111,56 @@ function AiPanel({ onClose }) {
8477
10111
  ai.coverage.truncated ? " (the oldest were left out)" : "",
8478
10112
  "."
8479
10113
  ] }) : null,
8480
- 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: [
8481
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "mx-meet__refusal-reason", children: ai.error.message }),
8482
- /* @__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 })
8483
10117
  ] }) : null
8484
10118
  ] });
8485
10119
  }
8486
10120
  function Captions({ lines = 3 }) {
8487
10121
  const ai = useMeetAi();
8488
10122
  const visible = ai.transcript.slice(-lines);
10123
+ const translation = useCaptionTranslation(visible);
8489
10124
  if (visible.length === 0) return null;
8490
- 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)(
8491
- "p",
8492
- {
8493
- className: line.final ? "mx-meet__caption" : "mx-meet__caption mx-meet__caption--interim",
8494
- children: [
8495
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("strong", { children: line.speaker }),
8496
- " ",
8497
- line.text
8498
- ]
8499
- },
8500
- line.id
8501
- )) });
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
+ ] });
8502
10144
  }
8503
10145
  function ConsentNotice() {
8504
10146
  const notice = useConsentNotice();
8505
10147
  if (notice === null) return null;
8506
- 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 });
8507
10149
  }
8508
10150
  function AttendanceNotice() {
8509
10151
  const media = useLocalMedia();
8510
10152
  const notice = listenOnlyNotice(media);
8511
10153
  if (notice === null) return null;
8512
10154
  const refused = media.microphone.unavailable;
8513
- 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: [
8514
10156
  notice,
8515
- 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 })
8516
10158
  ] });
8517
10159
  }
8518
10160
  function PreJoin(props) {
8519
10161
  const host = useMeetHost();
8520
- if (host === null) return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(InertNotice, { what: "This meeting" });
8521
- 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 });
8522
10164
  }
8523
10165
  function PreJoinBody({
8524
10166
  roomName,
@@ -8532,21 +10174,21 @@ function PreJoinBody({
8532
10174
  const recording = useRecording();
8533
10175
  const effects = useMediaEffects();
8534
10176
  const { notice } = useModerationNotice();
8535
- const [mode, setMode] = (0, import_react4.useState)("video");
8536
- const [microphone, setMicrophone] = (0, import_react4.useState)(true);
8537
- 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);
8538
10180
  const camera = devices?.selected.videoinput ?? host.devices.resolve("videoinput");
8539
10181
  const mic = devices?.selected.audioinput ?? host.devices.resolve("audioinput");
8540
10182
  const preview = useCameraPreview(mode === "video" ? camera : void 0, effects.effects);
8541
10183
  const micStream = useMicrophoneStream(microphone ? mic : "off");
8542
10184
  const level = useAudioLevel(micStream);
8543
- const [speakerTesting, setSpeakerTesting] = (0, import_react4.useState)(false);
8544
- (0, import_react4.useEffect)(() => {
10185
+ const [speakerTesting, setSpeakerTesting] = (0, import_react5.useState)(false);
10186
+ (0, import_react5.useEffect)(() => {
8545
10187
  void host.devices.refresh();
8546
10188
  }, [host]);
8547
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "mx-meet__prejoin", children: [
8548
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "mx-meet__preview", children: [
8549
- 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)(
8550
10192
  "video",
8551
10193
  {
8552
10194
  className: "mx-meet__video mx-meet__video--mirror",
@@ -8557,16 +10199,16 @@ function PreJoinBody({
8557
10199
  if (element !== null) preview.preview?.attach(element);
8558
10200
  }
8559
10201
  }
8560
- ) : /* @__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 }) }),
8561
- mode === "video" && preview.error !== null ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "mx-meet__preview-note", children: preview.error }) : null,
8562
- 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
8563
10205
  ] }),
8564
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "mx-meet__prejoin-panel", children: [
8565
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("h1", { className: "mx-meet__prejoin-title", children: "Ready to join?" }),
8566
- notice?.kind === "removed" ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "mx-meet__warning", children: notice.text }) : null,
8567
- 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: [
8568
10210
  "Your browser is hiding device names until you allow camera and microphone access.",
8569
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
10211
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
8570
10212
  "button",
8571
10213
  {
8572
10214
  type: "button",
@@ -8578,11 +10220,11 @@ function PreJoinBody({
8578
10220
  }
8579
10221
  )
8580
10222
  ] }) : null,
8581
- devices?.fallbackNotice != null ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "mx-meet__warning", children: devices.fallbackNotice }) : null,
8582
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(DevicePicker, { kind: "audioinput", label: "Microphone" }),
8583
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "mx-meet__field-row", children: [
8584
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(DevicePicker, { kind: "audiooutput", label: "Speaker" }),
8585
- /* @__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)(
8586
10228
  "button",
8587
10229
  {
8588
10230
  type: "button",
@@ -8595,19 +10237,19 @@ function PreJoinBody({
8595
10237
  );
8596
10238
  },
8597
10239
  children: [
8598
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(SpeakerIcon, { width: 14, height: 14 }),
10240
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(SpeakerIcon, { width: 14, height: 14 }),
8599
10241
  " ",
8600
10242
  speakerTesting ? "Playing\u2026" : "Test"
8601
10243
  ]
8602
10244
  }
8603
10245
  )
8604
10246
  ] }),
8605
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(DevicePicker, { kind: "videoinput", label: "Camera" }),
8606
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(EffectsSettings, { preview: preview.preview }),
8607
- recording.consentNotice !== null ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "mx-meet__consent", children: recording.consentNotice }) : null,
8608
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "mx-meet__prejoin-actions", children: [
8609
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("label", { className: "mx-meet__toggle", children: [
8610
- /* @__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)(
8611
10253
  "input",
8612
10254
  {
8613
10255
  type: "checkbox",
@@ -8617,8 +10259,8 @@ function PreJoinBody({
8617
10259
  ),
8618
10260
  "Join with video"
8619
10261
  ] }),
8620
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("label", { className: "mx-meet__toggle", children: [
8621
- /* @__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)(
8622
10264
  "input",
8623
10265
  {
8624
10266
  type: "checkbox",
@@ -8628,7 +10270,7 @@ function PreJoinBody({
8628
10270
  ),
8629
10271
  "Join with microphone"
8630
10272
  ] }),
8631
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
10273
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
8632
10274
  "button",
8633
10275
  {
8634
10276
  type: "button",
@@ -8648,20 +10290,20 @@ function PreJoinBody({
8648
10290
  }
8649
10291
  )
8650
10292
  ] }),
8651
- 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: [
8652
10294
  room.failure.message,
8653
- /* @__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 })
8654
10296
  ] }) : null
8655
10297
  ] })
8656
10298
  ] });
8657
10299
  }
8658
10300
  function useCameraPreview(deviceId2, effects) {
8659
- const [preview, setPreview] = (0, import_react4.useState)(null);
8660
- const [error, setError] = (0, import_react4.useState)(null);
8661
- const current = (0, import_react4.useRef)(null);
8662
- 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));
8663
10305
  initialEffect.current = toVideoEffect(effects);
8664
- (0, import_react4.useEffect)(() => {
10306
+ (0, import_react5.useEffect)(() => {
8665
10307
  if (deviceId2 === void 0) return void 0;
8666
10308
  let live = true;
8667
10309
  setError(null);
@@ -8705,9 +10347,9 @@ function DevicePicker({
8705
10347
  const devices = useDeviceSnapshot();
8706
10348
  const list = devices?.devices[kind] ?? [];
8707
10349
  if (list.length === 0) return null;
8708
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("label", { className: "mx-meet__field", children: [
8709
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "mx-meet__field-label", children: label }),
8710
- /* @__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)(
8711
10353
  "select",
8712
10354
  {
8713
10355
  className: "mx-meet__select",
@@ -8716,7 +10358,7 @@ function DevicePicker({
8716
10358
  if (onPick !== void 0) onPick(kind, event.target.value);
8717
10359
  else host.devices.select(kind, event.target.value);
8718
10360
  },
8719
- 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))
8720
10362
  }
8721
10363
  )
8722
10364
  ] });
@@ -8724,9 +10366,9 @@ function DevicePicker({
8724
10366
  function MeetingRoom(props) {
8725
10367
  const host = useMeetHost();
8726
10368
  if (host === null) {
8727
- 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" }) });
8728
10370
  }
8729
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(MeetingRoomBody, { ...props, host });
10371
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(MeetingRoomBody, { ...props, host });
8730
10372
  }
8731
10373
  function MeetingRoomBody({
8732
10374
  roomName,
@@ -8741,25 +10383,25 @@ function MeetingRoomBody({
8741
10383
  const isHost = useIsHost();
8742
10384
  const elapsed = useElapsed(snapshot?.meeting?.startedAt ?? null);
8743
10385
  const phase = snapshot?.phase ?? "idle";
8744
- (0, import_react4.useEffect)(() => {
10386
+ (0, import_react5.useEffect)(() => {
8745
10387
  host.meetings.watch(roomName);
8746
10388
  }, [host, roomName]);
8747
- (0, import_react4.useEffect)(() => {
10389
+ (0, import_react5.useEffect)(() => {
8748
10390
  if (given === void 0) return;
8749
10391
  if (host.store.snapshot().meeting !== null) return;
8750
10392
  host.store.patch({ meeting: given, locked: given.locked });
8751
10393
  }, [host, given]);
8752
10394
  const watchedId = meetingId ?? snapshot?.meeting?.id ?? null;
8753
- (0, import_react4.useEffect)(() => {
10395
+ (0, import_react5.useEffect)(() => {
8754
10396
  if (watchedId === null) return;
8755
10397
  host.meetings.watchMeeting(asMeetingId(watchedId));
8756
10398
  }, [host, watchedId]);
8757
10399
  const record = snapshot?.meeting ?? given ?? null;
8758
10400
  if (hasEnded(record) && phase !== "connected" && phase !== "reconnecting") {
8759
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(MeetingRecordView, { meeting: record });
10401
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(MeetingRecordView, { meeting: record });
8760
10402
  }
8761
10403
  if (phase === "idle" || phase === "failed" || phase === "left") {
8762
- 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)(
8763
10405
  PreJoin,
8764
10406
  {
8765
10407
  roomName,
@@ -8769,42 +10411,42 @@ function MeetingRoomBody({
8769
10411
  ) });
8770
10412
  }
8771
10413
  if (phase === "lobby") {
8772
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "mx-meet mx-meet--lobby", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(WaitingRoom, { roomName, host }) });
8773
- }
8774
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "mx-meet", children: [
8775
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(ConsentNotice, {}),
8776
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(AttendanceNotice, {}),
8777
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("header", { className: "mx-meet__header", children: [
8778
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("h1", { className: "mx-meet__title", children: snapshot?.meeting?.title ?? "Meeting" }),
8779
- /* @__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: [
8780
10422
  participantSummary(snapshot?.participants ?? []),
8781
10423
  elapsed > 0 ? ` \xB7 ${(0, import_format3.formatDurationMs)(elapsed)}` : ""
8782
10424
  ] }),
8783
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(RecordingIndicator, {}),
8784
- snapshot?.locked === true ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("span", { className: "mx-meet__badge", children: [
8785
- /* @__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 }),
8786
10428
  " Locked"
8787
10429
  ] }) : null,
8788
- headerControls !== void 0 && headerControls !== null ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "mx-meet__header-controls", "data-meet-header-controls": "", children: headerControls }) : null,
8789
- 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
8790
10432
  ] }),
8791
- phase === "reconnecting" ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "mx-meet__banner", role: "status", children: "Reconnecting\u2026" }) : null,
8792
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Stage, {}),
8793
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Captions, {}),
8794
- /* @__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 } : {} })
8795
10437
  ] });
8796
10438
  }
8797
10439
  function WaitingRoom({ roomName, host }) {
8798
- const knocked = (0, import_react4.useRef)(false);
8799
- (0, import_react4.useEffect)(() => {
10440
+ const knocked = (0, import_react5.useRef)(false);
10441
+ (0, import_react5.useEffect)(() => {
8800
10442
  if (knocked.current) return;
8801
10443
  knocked.current = true;
8802
10444
  host.meetings.knock(roomName);
8803
10445
  }, [host, roomName]);
8804
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "mx-meet__waiting", children: [
8805
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Avatar, { name: host.identity.displayName, url: host.identity.avatarUrl, size: 72 }),
8806
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("h1", { className: "mx-meet__prejoin-title", children: "Waiting for the host to let you in" }),
8807
- /* @__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: [
8808
10450
  "You are in the waiting room as ",
8809
10451
  host.identity.displayName,
8810
10452
  ". You will join automatically once you are admitted."
@@ -8815,10 +10457,10 @@ function HostMenu() {
8815
10457
  const host = useRequiredMeetHost();
8816
10458
  const snapshot = useMeetSnapshot();
8817
10459
  const end = useEndMeeting();
8818
- const [confirmingEnd, setConfirmingEnd] = (0, import_react4.useState)(false);
10460
+ const [confirmingEnd, setConfirmingEnd] = (0, import_react5.useState)(false);
8819
10461
  const locked = snapshot?.locked === true;
8820
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "mx-meet__host-menu", children: [
8821
- /* @__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)(
8822
10464
  "button",
8823
10465
  {
8824
10466
  type: "button",
@@ -8829,9 +10471,9 @@ function HostMenu() {
8829
10471
  children: locked ? "Unlock meeting" : "Lock meeting"
8830
10472
  }
8831
10473
  ),
8832
- end.canEnd ? confirmingEnd ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("span", { className: "mx-meet__confirm", role: "group", "aria-label": "End this meeting?", children: [
8833
- /* @__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." }),
8834
- /* @__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)(
8835
10477
  "button",
8836
10478
  {
8837
10479
  type: "button",
@@ -8843,7 +10485,7 @@ function HostMenu() {
8843
10485
  children: "End it"
8844
10486
  }
8845
10487
  ),
8846
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
10488
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
8847
10489
  "button",
8848
10490
  {
8849
10491
  type: "button",
@@ -8852,7 +10494,7 @@ function HostMenu() {
8852
10494
  children: "Keep it running"
8853
10495
  }
8854
10496
  )
8855
- ] }) : /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
10497
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
8856
10498
  "button",
8857
10499
  {
8858
10500
  type: "button",
@@ -8861,7 +10503,7 @@ function HostMenu() {
8861
10503
  children: end.ending ? "Ending\u2026" : "End meeting for everyone"
8862
10504
  }
8863
10505
  ) : null,
8864
- 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
8865
10507
  ] });
8866
10508
  }
8867
10509
  function CallButton({
@@ -8871,7 +10513,7 @@ function CallButton({
8871
10513
  }) {
8872
10514
  const calls = useCalls();
8873
10515
  if (!calls.canCall) return null;
8874
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
10516
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
8875
10517
  "button",
8876
10518
  {
8877
10519
  type: "button",
@@ -8880,55 +10522,55 @@ function CallButton({
8880
10522
  void calls.call([person.userId], mode);
8881
10523
  },
8882
10524
  "aria-label": `Call ${person.displayName}`,
8883
- 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 })
8884
10526
  }
8885
10527
  );
8886
10528
  }
8887
10529
  function IncomingCallHost() {
8888
10530
  const calls = useCalls();
8889
10531
  if (calls.incoming.length === 0) return null;
8890
- 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)) });
8891
10533
  }
8892
10534
  function IncomingCallCard({ invite }) {
8893
10535
  const calls = useCalls();
8894
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("section", { className: "mx-meet__ringing", role: "alertdialog", "aria-label": "Incoming call", children: [
8895
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Avatar, { name: invite.callerName, url: invite.callerAvatarUrl, size: 56 }),
8896
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "mx-meet__ringing-text", children: [
8897
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("strong", { children: invite.callerName }),
8898
- /* @__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" })
8899
10541
  ] }),
8900
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "mx-meet__ringing-actions", children: [
8901
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(ControlButton, { label: "Decline", danger: true, onClick: () => void calls.decline(invite), children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(PhoneOffIcon, {}) }),
8902
- 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)(
8903
10545
  ControlButton,
8904
10546
  {
8905
10547
  label: "Accept without video",
8906
10548
  onClick: () => void calls.accept({ ...invite, mode: "audio" }),
8907
- children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(CameraOffIcon, {})
10549
+ children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(CameraOffIcon, {})
8908
10550
  }
8909
10551
  ) : null,
8910
- /* @__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, {}) })
8911
10553
  ] })
8912
10554
  ] });
8913
10555
  }
8914
10556
  function ScheduleMeeting(props) {
8915
10557
  const host = useMeetHost();
8916
- if (host === null) return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(InertNotice, { what: "Scheduling a meeting" });
8917
- 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 });
8918
10560
  }
8919
10561
  function ScheduleMeetingBody({
8920
10562
  appBaseUrl,
8921
10563
  onScheduled,
8922
10564
  host
8923
10565
  }) {
8924
- const [title, setTitle] = (0, import_react4.useState)("");
8925
- const [when2, setWhen] = (0, import_react4.useState)("");
8926
- const [kind, setKind] = (0, import_react4.useState)("scheduled");
8927
- const [busy, setBusy] = (0, import_react4.useState)(false);
8928
- const [link, setLink] = (0, import_react4.useState)(null);
8929
- const [error, setError] = (0, import_react4.useState)(null);
8930
- const disabled = (0, import_react4.useMemo)(() => title.trim().length === 0 || busy, [title, busy]);
8931
- 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)(
8932
10574
  "form",
8933
10575
  {
8934
10576
  className: "mx-meet__schedule",
@@ -8953,9 +10595,9 @@ function ScheduleMeetingBody({
8953
10595
  }).finally(() => setBusy(false));
8954
10596
  },
8955
10597
  children: [
8956
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("label", { className: "mx-meet__field", children: [
8957
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "mx-meet__field-label", children: "Title" }),
8958
- /* @__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)(
8959
10601
  "input",
8960
10602
  {
8961
10603
  className: "mx-meet__input",
@@ -8965,9 +10607,9 @@ function ScheduleMeetingBody({
8965
10607
  }
8966
10608
  )
8967
10609
  ] }),
8968
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("label", { className: "mx-meet__field", children: [
8969
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "mx-meet__field-label", children: "When" }),
8970
- /* @__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)(
8971
10613
  "input",
8972
10614
  {
8973
10615
  className: "mx-meet__input",
@@ -8977,27 +10619,27 @@ function ScheduleMeetingBody({
8977
10619
  }
8978
10620
  )
8979
10621
  ] }),
8980
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("label", { className: "mx-meet__field", children: [
8981
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "mx-meet__field-label", children: "Repeats" }),
8982
- /* @__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)(
8983
10625
  "select",
8984
10626
  {
8985
10627
  className: "mx-meet__select",
8986
10628
  value: kind,
8987
10629
  onChange: (event) => setKind(event.target.value),
8988
10630
  children: [
8989
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("option", { value: "scheduled", children: "Once" }),
8990
- /* @__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" })
8991
10633
  ]
8992
10634
  }
8993
10635
  )
8994
10636
  ] }),
8995
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("button", { type: "submit", className: "mx-meet__primary", disabled, children: busy ? "Creating\u2026" : "Create meeting" }),
8996
- link !== null ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("p", { className: "mx-meet__link-out", children: [
8997
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { children: "Anyone with this link can join \u2014 no account needed." }),
8998
- /* @__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 })
8999
10641
  ] }) : null,
9000
- 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
9001
10643
  ]
9002
10644
  }
9003
10645
  );
@@ -9006,7 +10648,7 @@ function ReactionOverlay({
9006
10648
  reactions
9007
10649
  }) {
9008
10650
  if (reactions.length === 0) return null;
9009
- 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)) });
9010
10652
  }
9011
10653
  function GuestRecordAccessControl({
9012
10654
  meeting
@@ -9018,11 +10660,11 @@ function GuestRecordAccessControl({
9018
10660
  const isHost = inRoomHost || viewerId !== null && meeting.hostUserId === viewerId;
9019
10661
  if (host === null || !isHost) return null;
9020
10662
  const resolved = access.setting === "default" && access.effective !== null ? ` Right now that means: ${guestRecordAccessLabel(access.effective.level).toLowerCase()}.` : "";
9021
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("section", { className: "mx-meet__record-section", "aria-label": "What guests may read", children: [
9022
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("h2", { className: "mx-meet__record-section-title", children: "What guests may read" }),
9023
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("label", { className: "mx-meet__field", children: [
9024
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "mx-meet__field-label", children: "People who attended by link, without an account" }),
9025
- /* @__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)(
9026
10668
  "select",
9027
10669
  {
9028
10670
  className: "mx-meet__select",
@@ -9033,18 +10675,18 @@ function GuestRecordAccessControl({
9033
10675
  event.target.value
9034
10676
  );
9035
10677
  },
9036
- 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))
9037
10679
  }
9038
10680
  )
9039
10681
  ] }),
9040
- /* @__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: [
9041
10683
  guestRecordAccessExplanation(access.setting),
9042
10684
  resolved
9043
10685
  ] }),
9044
- access.saving ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "mx-meet__panel-note", role: "status", children: "Saving what guests may read\u2026" }) : null,
9045
- 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: [
9046
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "mx-meet__refusal-reason", children: access.error.message }),
9047
- /* @__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 })
9048
10690
  ] }) : null
9049
10691
  ] });
9050
10692
  }
@@ -9054,9 +10696,9 @@ function MeetingRecordView({
9054
10696
  }) {
9055
10697
  const host = useMeetHost();
9056
10698
  if (host === null) {
9057
- 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" }) });
9058
10700
  }
9059
- 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 } : {} });
9060
10702
  }
9061
10703
  function MeetingRecordBody({
9062
10704
  meeting,
@@ -9064,19 +10706,19 @@ function MeetingRecordBody({
9064
10706
  }) {
9065
10707
  const host = useRequiredMeetHost();
9066
10708
  const record = useMeetingRecord(meeting);
9067
- const [question, setQuestion] = (0, import_react4.useState)("");
9068
- 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");
9069
10711
  if (record.failure !== null) {
9070
- 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: [
9071
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "mx-meet__empty-title", children: "This meeting record could not be opened" }),
9072
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "mx-meet__empty-body", children: record.failure.message }),
9073
- /* @__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 })
9074
10716
  ] }) });
9075
10717
  }
9076
10718
  if (record.loading || record.record === null) {
9077
- 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: [
9078
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "mx-meet__empty-title", children: "Opening the meeting record\u2026" }),
9079
- /* @__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." })
9080
10722
  ] }) });
9081
10723
  }
9082
10724
  const bundle = record.record;
@@ -9095,44 +10737,44 @@ function MeetingRecordBody({
9095
10737
  );
9096
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;
9097
10739
  if (entirelyRestricted) {
9098
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "mx-meet mx-meet--record", children: [
9099
- /* @__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: [
9100
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "mx-meet__record-eyebrow", children: "Meeting record" }),
9101
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("h1", { className: "mx-meet__record-title", children: meeting.title }),
9102
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "mx-meet__record-when", children: meetingWhen(meeting) }),
9103
- 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
9104
10746
  ] }) }),
9105
- /* @__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: [
9106
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "mx-meet__record-access-title", children: "About this record" }),
9107
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "mx-meet__record-access-message", children: notice2.message }),
9108
- /* @__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 })
9109
10751
  ] }, notice2.parts.join("-"))) })
9110
10752
  ] });
9111
10753
  }
9112
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "mx-meet mx-meet--record", children: [
9113
- /* @__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: [
9114
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "mx-meet__record-eyebrow", children: "Meeting record" }),
9115
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("h1", { className: "mx-meet__record-title", children: meeting.title }),
9116
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "mx-meet__record-when", children: meetingWhen(meeting) }),
9117
- 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
9118
10760
  ] }) }),
9119
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "mx-meet__record-body", children: [
9120
- restrictionNotices.map((notice2) => /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "mx-meet__record-access", role: "status", children: [
9121
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "mx-meet__record-access-title", children: "About this record" }),
9122
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "mx-meet__record-access-message", children: notice2.message }),
9123
- /* @__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 })
9124
10766
  ] }, notice2.parts.join("-"))),
9125
10767
  attended.length === 0 ? (
9126
10768
  /* NOT SILENCE. A refused attendance read used to remove the whole
9127
10769
  section, so the reader could not tell "nobody" from "not shown". */
9128
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("section", { className: "mx-meet__record-section", "aria-label": "Who attended", children: [
9129
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("h2", { className: "mx-meet__record-section-title", children: "Who attended" }),
9130
- /* @__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.") })
9131
10773
  ] })
9132
- ) : /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("section", { className: "mx-meet__record-section", "aria-label": "Who attended", children: [
9133
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("h2", { className: "mx-meet__record-section-title", children: "Who attended" }),
9134
- /* @__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: [
9135
- /* @__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)(
9136
10778
  Avatar,
9137
10779
  {
9138
10780
  name: displayNameFor(bundle.names, person.identity, person.displayName),
@@ -9140,26 +10782,26 @@ function MeetingRecordBody({
9140
10782
  size: 28
9141
10783
  }
9142
10784
  ),
9143
- /* @__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: [
9144
10786
  displayNameFor(bundle.names, person.identity, person.displayName),
9145
- person.role === "host" ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "mx-meet__badge", children: "Host" }) : null,
9146
- person.role === "guest" ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "mx-meet__badge", children: "Guest" }) : null,
9147
- 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
9148
10790
  ] })
9149
10791
  ] }, person.id)) })
9150
10792
  ] }),
9151
- bundle.recording !== null ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("section", { className: "mx-meet__record-section mx-meet__recording-card", "aria-label": "Recording", children: [
9152
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("h2", { className: "mx-meet__record-section-title", children: "Recording" }),
9153
- fileId !== null ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_jsx_runtime3.Fragment, { children: [
9154
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(RecordingPlayer, { fileId }),
9155
- notice !== null ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "mx-meet__panel-note", children: notice }) : null
9156
- ] }) : /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "mx-meet__panel-note", children: notice ?? "This recording has no file." })
9157
- ] }) : wasRefused(bundle, "recording") ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("section", { className: "mx-meet__record-section", "aria-label": "Recording", children: [
9158
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("h2", { className: "mx-meet__record-section-title", children: "Recording" }),
9159
- /* @__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 })
9160
10802
  ] }) : null,
9161
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("nav", { className: "mx-meet__record-tabs", "aria-label": "Meeting record sections", children: [
9162
- /* @__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)(
9163
10805
  "button",
9164
10806
  {
9165
10807
  type: "button",
@@ -9169,7 +10811,7 @@ function MeetingRecordBody({
9169
10811
  children: "Summary & decisions"
9170
10812
  }
9171
10813
  ),
9172
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
10814
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
9173
10815
  "button",
9174
10816
  {
9175
10817
  type: "button",
@@ -9179,7 +10821,7 @@ function MeetingRecordBody({
9179
10821
  children: "Notes as it happened"
9180
10822
  }
9181
10823
  ),
9182
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
10824
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
9183
10825
  "button",
9184
10826
  {
9185
10827
  type: "button",
@@ -9190,15 +10832,15 @@ function MeetingRecordBody({
9190
10832
  }
9191
10833
  )
9192
10834
  ] }),
9193
- tab === "summary" ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_jsx_runtime3.Fragment, { children: [
9194
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("section", { className: "mx-meet__record-section", "aria-label": "Summary", children: [
9195
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("h2", { className: "mx-meet__record-section-title", children: "Summary" }),
9196
- 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: [
9197
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { children: wrapUp.message }),
9198
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("button", { type: "button", className: "mx-meet__link", onClick: record.reload, children: "Check again" })
9199
- ] }) : /* @__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 })
9200
10842
  ] }),
9201
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
10843
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
9202
10844
  NoteList,
9203
10845
  {
9204
10846
  title: "Decisions",
@@ -9210,7 +10852,7 @@ function MeetingRecordBody({
9210
10852
  )
9211
10853
  }
9212
10854
  ),
9213
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
10855
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
9214
10856
  NoteList,
9215
10857
  {
9216
10858
  title: "Action items",
@@ -9223,42 +10865,42 @@ function MeetingRecordBody({
9223
10865
  }
9224
10866
  )
9225
10867
  ] }) : null,
9226
- tab === "notes" ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("section", { className: "mx-meet__record-section", "aria-label": "Notes as it happened", children: [
9227
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("h2", { className: "mx-meet__record-section-title", children: "Notes as it happened" }),
9228
- 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(
9229
10871
  bundle,
9230
10872
  "notes",
9231
10873
  "No live notes are available for this meeting."
9232
- ) }) : /* @__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: [
9233
- 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: [
9234
10876
  "Window ",
9235
10877
  note.window
9236
10878
  ] }) : null,
9237
10879
  note.text
9238
10880
  ] }, note.id)) })
9239
10881
  ] }) : null,
9240
- tab === "transcript" ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("section", { className: "mx-meet__record-section", "aria-label": "Transcript", children: [
9241
- /* @__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: [
9242
10884
  "Transcript",
9243
- /* @__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` })
9244
10886
  ] }),
9245
- 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(
9246
10888
  bundle,
9247
10889
  "transcript",
9248
10890
  "No transcript is available for this meeting."
9249
- ) }) : /* @__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: [
9250
- /* @__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: [
9251
10893
  block.speaker,
9252
- /* @__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) })
9253
10895
  ] }),
9254
- 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))
9255
10897
  ] }, block.id)) })
9256
10898
  ] }) : null,
9257
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(GuestRecordAccessControl, { meeting }),
9258
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("section", { className: "mx-meet__record-section", "aria-label": "Ask about this meeting", children: [
9259
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("h2", { className: "mx-meet__record-section-title", children: "Ask about this meeting" }),
9260
- 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: [
9261
- /* @__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)(
9262
10904
  "form",
9263
10905
  {
9264
10906
  className: "mx-meet__composer",
@@ -9269,7 +10911,7 @@ function MeetingRecordBody({
9269
10911
  void record.ask(trimmed);
9270
10912
  },
9271
10913
  children: [
9272
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
10914
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
9273
10915
  "input",
9274
10916
  {
9275
10917
  className: "mx-meet__input",
@@ -9279,7 +10921,7 @@ function MeetingRecordBody({
9279
10921
  "aria-label": "Ask about this meeting"
9280
10922
  }
9281
10923
  ),
9282
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
10924
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
9283
10925
  "button",
9284
10926
  {
9285
10927
  type: "submit",
@@ -9291,8 +10933,8 @@ function MeetingRecordBody({
9291
10933
  ]
9292
10934
  }
9293
10935
  ),
9294
- record.answer !== null ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "mx-meet__answer", children: record.answer }) : null,
9295
- 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: [
9296
10938
  "Answered from ",
9297
10939
  record.coverage.segmentsUsed,
9298
10940
  " of ",
@@ -9303,9 +10945,9 @@ function MeetingRecordBody({
9303
10945
  record.coverage.truncated ? " (the oldest were left out)" : "",
9304
10946
  "."
9305
10947
  ] }) : null,
9306
- 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: [
9307
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "mx-meet__refusal-reason", children: record.askError.message }),
9308
- /* @__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 })
9309
10951
  ] }) : null
9310
10952
  ] })
9311
10953
  ] })
@@ -9316,21 +10958,21 @@ var STREAM_REFUSED = "Streaming playback did not start, so this recording was do
9316
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.";
9317
10959
  function RecordingPlayer(props) {
9318
10960
  const host = useMeetHost();
9319
- if (host === null) return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(InertNotice, { what: "This recording" });
9320
- 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 });
9321
10963
  }
9322
10964
  function RecordingPlayerBody({ fileId, host }) {
9323
- const [media, setMedia] = (0, import_react4.useState)(null);
9324
- const [loading, setLoading] = (0, import_react4.useState)(false);
9325
- const [error, setError] = (0, import_react4.useState)(null);
9326
- (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)(() => {
9327
10969
  if (media === null || media.kind !== "bytes") return void 0;
9328
10970
  const url = media.url;
9329
10971
  return () => URL.revokeObjectURL(url);
9330
10972
  }, [media]);
9331
10973
  if (media !== null) {
9332
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "mx-meet__record-section", children: [
9333
- /* @__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)(
9334
10976
  "video",
9335
10977
  {
9336
10978
  className: "mx-meet__record-player",
@@ -9372,15 +11014,15 @@ function RecordingPlayerBody({ fileId, host }) {
9372
11014
  }
9373
11015
  }
9374
11016
  ),
9375
- 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
9376
11018
  ] });
9377
11019
  }
9378
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "mx-meet__record-section", children: [
9379
- 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: [
9380
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "mx-meet__refusal-reason", children: error.message }),
9381
- /* @__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 })
9382
11024
  ] }) : null,
9383
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
11025
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
9384
11026
  "button",
9385
11027
  {
9386
11028
  type: "button",
@@ -9416,35 +11058,35 @@ function clockOf(iso) {
9416
11058
  function MeetingList({ baseUrl }) {
9417
11059
  const host = useMeetHost();
9418
11060
  const list = useMeetings();
9419
- 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" });
9420
11062
  if (list.failure !== null) {
9421
- 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: [
9422
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "mx-meet__empty-title", children: "Your meetings could not be listed" }),
9423
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "mx-meet__empty-body", children: list.failure.message }),
9424
- /* @__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 })
9425
11067
  ] });
9426
11068
  }
9427
11069
  if (list.loading) {
9428
- 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" }) });
9429
11071
  }
9430
11072
  if (list.meetings.length === 0) {
9431
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "mx-meet__empty", role: "status", children: [
9432
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "mx-meet__empty-title", children: "No meetings yet" }),
9433
- /* @__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." })
9434
11076
  ] });
9435
11077
  }
9436
11078
  const origin = baseUrl ?? (typeof window === "undefined" ? "" : window.location.origin);
9437
- 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) => {
9438
11080
  const ended = meeting.endedAt !== null;
9439
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("li", { className: "mx-meet-list__row", children: [
9440
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "mx-meet-list__main", children: [
9441
- /* @__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: [
9442
11084
  meeting.title,
9443
- 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
9444
11086
  ] }),
9445
- /* @__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) })
9446
11088
  ] }),
9447
- /* @__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" })
9448
11090
  ] }, meeting.id);
9449
11091
  }) });
9450
11092
  }