@ai-matrx/meet 0.7.84 → 0.8.0

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.js CHANGED
@@ -2,6 +2,7 @@
2
2
  "use client";
3
3
 
4
4
  // src/react/provider.tsx
5
+ import { globalSlot as globalSlot2 } from "@ai-matrx/kit/global-slot";
5
6
  import {
6
7
  createContext,
7
8
  useCallback,
@@ -901,22 +902,9 @@ function fileDownloadPath(fileId) {
901
902
 
902
903
  // src/core/channels.ts
903
904
  import { defineChannelNamespace } from "@ai-matrx/realtime";
904
-
905
- // src/core/slot.ts
906
- var NAMESPACE = "ai-matrx.meet";
907
- function globalSlot(name, create) {
908
- const key = /* @__PURE__ */ Symbol.for(`${NAMESPACE}.${name}`);
909
- const host = globalThis;
910
- const existing = host[key];
911
- if (existing !== void 0) return existing;
912
- const created = create();
913
- host[key] = created;
914
- return created;
915
- }
916
-
917
- // src/core/channels.ts
905
+ import { globalSlot } from "@ai-matrx/kit/global-slot";
918
906
  function namespaces() {
919
- return globalSlot("channel-namespaces", () => ({
907
+ return globalSlot("ai-matrx.meet.channel-namespaces", () => ({
920
908
  user: defineChannelNamespace({
921
909
  namespace: "meet-user",
922
910
  parts: ["userId"],
@@ -3499,87 +3487,22 @@ function snippetRuns(snippet) {
3499
3487
  }
3500
3488
 
3501
3489
  // src/core/session-identity.ts
3502
- var RESOLVING = Object.freeze({
3503
- state: "resolving",
3504
- userId: null
3505
- });
3506
- var SERVER_SESSION_IDENTITY = RESOLVING;
3507
- function authOf(client) {
3508
- const candidate = client.auth;
3509
- if (candidate === null || typeof candidate !== "object") return null;
3510
- const auth = candidate;
3511
- if (typeof auth.getSession !== "function") return null;
3512
- if (typeof auth.onAuthStateChange !== "function") return null;
3513
- return auth;
3514
- }
3515
- function userIdOf(session) {
3516
- const id = session?.user?.id;
3517
- return typeof id === "string" && id.length > 0 ? asUserId(id) : null;
3518
- }
3519
- function createSessionIdentity(options) {
3520
- const { client, onDiagnostic } = options;
3521
- const listeners = /* @__PURE__ */ new Set();
3522
- let current = RESOLVING;
3523
- let disposed = false;
3524
- const publish = (state, userId) => {
3525
- if (disposed) return;
3526
- if (current.state === state && current.userId === userId) return;
3527
- current = Object.freeze({ state, userId });
3528
- for (const listener of [...listeners]) listener();
3529
- };
3530
- const auth = authOf(client);
3531
- if (auth === null) {
3532
- onDiagnostic?.({
3533
- level: "error",
3534
- message: "Meet cannot tell who is signed in: the Supabase client it was given has no auth session source.",
3535
- remedy: "Pass your app's browser Supabase client to <MeetProvider client={...}> \u2014 the same client it signs in with. Meet reads the acting user from that client's session; there is no prop for a user id, on purpose."
3536
- });
3537
- current = Object.freeze({ state: "resolved", userId: null });
3538
- return {
3539
- snapshot: () => current,
3540
- subscribe: (listener) => {
3541
- listeners.add(listener);
3542
- return () => listeners.delete(listener);
3543
- },
3544
- dispose: () => {
3545
- disposed = true;
3546
- listeners.clear();
3547
- }
3548
- };
3549
- }
3550
- void (async () => {
3551
- try {
3552
- const result = await auth.getSession();
3553
- publish("resolved", userIdOf(result?.data?.session));
3554
- } catch (error) {
3555
- onDiagnostic?.({
3556
- level: "warn",
3557
- message: `Meet could not read the signed-in session: ${String(
3558
- error?.message ?? error
3559
- )}`,
3560
- remedy: "Calls and meetings stay unavailable on this device until the session can be read. Reload the page; if it persists, sign in again."
3561
- });
3562
- publish("resolved", null);
3563
- }
3564
- })();
3565
- const subscription = auth.onAuthStateChange((_event, session) => {
3566
- publish("resolved", userIdOf(session));
3490
+ import {
3491
+ createSessionIdentity as createDataSessionIdentity
3492
+ } from "@ai-matrx/data/session-identity";
3493
+ import { authOf, SERVER_SESSION_IDENTITY } from "@ai-matrx/data/session-identity";
3494
+ var MEET_SESSION_WORDS = {
3495
+ product: "Meet",
3496
+ noAuthSourceRemedy: "Pass your app's browser Supabase client to <MeetProvider client={...}> \u2014 the same client it signs in with. Meet reads the acting user from that client's session; there is no prop for a user id, on purpose.",
3497
+ unreadableRemedy: "Calls and meetings stay unavailable on this device until the session can be read. Reload the page; if it persists, sign in again."
3498
+ };
3499
+ function createMeetSessionIdentity(options) {
3500
+ return createDataSessionIdentity({
3501
+ client: options.client,
3502
+ words: MEET_SESSION_WORDS,
3503
+ toUserId: asUserId,
3504
+ onDiagnostic: options.onDiagnostic
3567
3505
  });
3568
- return {
3569
- snapshot: () => current,
3570
- subscribe: (listener) => {
3571
- listeners.add(listener);
3572
- return () => listeners.delete(listener);
3573
- },
3574
- dispose: () => {
3575
- disposed = true;
3576
- listeners.clear();
3577
- try {
3578
- subscription.data.subscription.unsubscribe();
3579
- } catch {
3580
- }
3581
- }
3582
- };
3583
3506
  }
3584
3507
 
3585
3508
  // src/core/room-events.ts
@@ -5223,7 +5146,7 @@ async function createCameraPreview(deviceId2, effect) {
5223
5146
 
5224
5147
  // src/react/provider.tsx
5225
5148
  import { jsx } from "react/jsx-runtime";
5226
- var MeetContext = createContext(null);
5149
+ var MeetContext = globalSlot2("ai-matrx.meet.react.context", () => createContext(null));
5227
5150
  function defaultDiagnostics(event) {
5228
5151
  const line = `[@ai-matrx/meet] ${event.message}${event.remedy !== void 0 ? `
5229
5152
  \u2192 ${event.remedy}` : ""}`;
@@ -5251,7 +5174,7 @@ function useSessionIdentity(client, report) {
5251
5174
  setSnapshot(SERVER_SESSION_IDENTITY);
5252
5175
  return void 0;
5253
5176
  }
5254
- const identity = createSessionIdentity({ client, onDiagnostic: report });
5177
+ const identity = createMeetSessionIdentity({ client, onDiagnostic: report });
5255
5178
  setSnapshot(identity.snapshot());
5256
5179
  const unsubscribe = identity.subscribe(() => setSnapshot(identity.snapshot()));
5257
5180
  return () => {
@@ -7201,23 +7124,15 @@ function useGuestRecordAccess(meeting) {
7201
7124
  };
7202
7125
  }
7203
7126
 
7204
- // src/react/components.tsx
7205
- import { useEffect as useEffect5, useLayoutEffect, useMemo as useMemo4, useRef as useRef5, useState as useState4 } from "react";
7206
- import {
7207
- Alert,
7208
- AlertDescription,
7209
- Button,
7210
- Checkbox,
7211
- ErrorBox,
7212
- Label,
7213
- SegmentedControl,
7214
- Select,
7215
- SelectContent,
7216
- SelectItem,
7217
- SelectTrigger,
7218
- SelectValue
7219
- } from "@ai-matrx/design-system";
7220
- import { avatarPaletteIndex, formatDurationMs as formatDurationMs4, getInitials } from "@ai-matrx/kit/format";
7127
+ // src/react/skin-root.tsx
7128
+ import { useEffect as useEffect8 } from "react";
7129
+
7130
+ // src/skins/meet/components.tsx
7131
+ import { useEffect as useEffect6, useLayoutEffect, useRef as useRef6, useState as useState4 } from "react";
7132
+
7133
+ // src/react/facade.ts
7134
+ import { useMemo as useMemo4 } from "react";
7135
+ import { avatarPaletteIndex, formatDurationMs as formatDurationMs3, getInitials } from "@ai-matrx/kit/format";
7221
7136
 
7222
7137
  // src/core/after.ts
7223
7138
  import { toDelimited } from "@ai-matrx/kit/delimited";
@@ -7654,11 +7569,151 @@ function countLabel(count2, singular, plural = `${singular}s`) {
7654
7569
  return `${count2} ${count2 === 1 ? singular : plural}`;
7655
7570
  }
7656
7571
 
7657
- // src/react/collab.tsx
7658
- import { useEffect as useEffect4, useRef as useRef4, useState as useState3 } from "react";
7659
- import { formatDurationMs as formatDurationMs3 } from "@ai-matrx/kit/format";
7572
+ // src/core/collab-state.ts
7573
+ function availableActivities(collab, isHost) {
7574
+ const settings = collab?.settings ?? null;
7575
+ if (settings === null) return [];
7576
+ const out = [];
7577
+ if (settings.whiteboardEnabled) out.push("whiteboard");
7578
+ if (settings.pollsEnabled && (isHost || (collab?.polls.length ?? 0) > 0)) out.push("polls");
7579
+ if (settings.qaEnabled) out.push("qa");
7580
+ if (settings.breakoutsEnabled && (isHost || collab?.breakout?.state === "open")) out.push("breakouts");
7581
+ return out;
7582
+ }
7583
+ function activityAttention(collab, isHost) {
7584
+ if (collab === null) return false;
7585
+ if (collab.polls.some((poll) => poll.state === "live" && poll.myVote.length === 0 && !isHost)) return true;
7586
+ if (isHost && collab.questions.some((q) => q.state === "open")) return true;
7587
+ return false;
7588
+ }
7589
+ async function performCollab(runtime, request) {
7590
+ if (runtime === null) return { ok: false, message: "This meeting is not connected." };
7591
+ try {
7592
+ const result = await runtime.inRoom.collab(request);
7593
+ return { ok: true, message: result.message, itemId: result.itemId };
7594
+ } catch (error) {
7595
+ return { ok: false, message: error.message ?? "That did not work." };
7596
+ }
7597
+ }
7598
+ async function moveToRoom(runtime, roomId) {
7599
+ if (runtime === null) return { ok: false, message: "This meeting is not connected." };
7600
+ try {
7601
+ await runtime.engine.moveToBreakout(roomId);
7602
+ return { ok: true, message: roomId === null ? "Back in the main room." : "Joined the breakout room." };
7603
+ } catch (error) {
7604
+ return { ok: false, message: error.message ?? "That room could not be joined." };
7605
+ }
7606
+ }
7607
+ function untranslatedLines(lines, translations) {
7608
+ return lines.filter((line) => line.final && translations[line.id] === void 0).map(({ id, text: text3 }) => ({ id, text: text3 }));
7609
+ }
7610
+ function nextTranslationBatch(pending, language, asked) {
7611
+ const batch = pending.filter((line) => !asked.has(`${language}:${line.id}`)).slice(-20);
7612
+ for (const line of batch) asked.add(`${language}:${line.id}`);
7613
+ return batch;
7614
+ }
7615
+ function setCaptionLanguage(store, next) {
7616
+ store.patch({
7617
+ collab: {
7618
+ ...store.snapshot().collab,
7619
+ captionLanguage: next,
7620
+ captionTranslations: {},
7621
+ captionTranslationError: null
7622
+ }
7623
+ });
7624
+ }
7625
+ function takePanelRequest(store) {
7626
+ const request = store.snapshot().collab.panelRequest;
7627
+ if (request === null) return null;
7628
+ store.patch({ collab: { ...store.snapshot().collab, panelRequest: null } });
7629
+ return request.panel;
7630
+ }
7631
+ function takeMoveRequest(store) {
7632
+ const request = store.snapshot().collab.moveRequest;
7633
+ if (request === null) return null;
7634
+ store.patch({ collab: { ...store.snapshot().collab, moveRequest: null } });
7635
+ return { roomId: request.roomId };
7636
+ }
7660
7637
 
7661
- // src/react/icons.tsx
7638
+ // src/react/collab-hooks.ts
7639
+ import { useEffect as useEffect4, useRef as useRef4 } from "react";
7640
+ function useCollab() {
7641
+ const host = useMeetHost();
7642
+ const snapshot = useMeetSnapshot();
7643
+ const isHost = useIsHost();
7644
+ return {
7645
+ collab: snapshot?.collab ?? null,
7646
+ isHost,
7647
+ localIdentity: snapshot?.localIdentity ?? null,
7648
+ breakoutRoomId: snapshot?.breakoutRoomId ?? null,
7649
+ act: (request) => performCollab(host, request),
7650
+ moveTo: (roomId) => moveToRoom(host, roomId)
7651
+ };
7652
+ }
7653
+ function useAvailableActivities() {
7654
+ const { collab, isHost } = useCollab();
7655
+ return availableActivities(collab, isHost);
7656
+ }
7657
+ function useActivityAttention() {
7658
+ const { collab, isHost } = useCollab();
7659
+ return activityAttention(collab, isHost);
7660
+ }
7661
+ function useCaptionTranslation(lines) {
7662
+ const host = useMeetHost();
7663
+ const snapshot = useMeetSnapshot();
7664
+ const collab = snapshot?.collab ?? null;
7665
+ const language = collab?.captionLanguage ?? null;
7666
+ const asked = useRef4(/* @__PURE__ */ new Set());
7667
+ const translations = collab?.captionTranslations ?? {};
7668
+ const missing = untranslatedLines(lines, translations);
7669
+ const key = `${language ?? ""}|${missing.map((l) => l.id).join(",")}`;
7670
+ const pending = useRef4(missing);
7671
+ pending.current = missing;
7672
+ useEffect4(() => {
7673
+ if (host === null || language === null) return;
7674
+ const batch = nextTranslationBatch(pending.current, language, asked.current);
7675
+ if (batch.length === 0) return;
7676
+ void host.inRoom.translateCaptions(language, batch).catch(() => void 0);
7677
+ }, [host, language, key]);
7678
+ return { language, translations, error: collab?.captionTranslationError ?? null };
7679
+ }
7680
+ function useCollabPanelRequest(onRequest) {
7681
+ const host = useMeetHost();
7682
+ const at = useMeetSnapshot()?.collab.panelRequest?.at ?? null;
7683
+ const callback = useRef4(onRequest);
7684
+ callback.current = onRequest;
7685
+ useEffect4(() => {
7686
+ if (host === null) return;
7687
+ const panel = takePanelRequest(host.store);
7688
+ if (panel === null) return;
7689
+ callback.current(panel);
7690
+ }, [at, host]);
7691
+ }
7692
+
7693
+ // src/core/reactions.ts
7694
+ var MEET_REACTIONS = ["\u{1F496}", "\u{1F44D}", "\u{1F389}", "\u{1F44F}", "\u{1F602}", "\u{1F62E}", "\u{1F622}", "\u{1F914}", "\u{1F44E}"];
7695
+
7696
+ // src/react/facade.ts
7697
+ function useMeetCore() {
7698
+ const host = useMeetHost();
7699
+ const snapshot = useMeetSnapshot();
7700
+ const devices = useDeviceSnapshot();
7701
+ const role = useRole();
7702
+ const isHost = useIsHost();
7703
+ const observation = useCoreObservation();
7704
+ return useMemo4(
7705
+ () => ({ host, snapshot, devices, role, isHost, observation }),
7706
+ [host, snapshot, devices, role, isHost, observation]
7707
+ );
7708
+ }
7709
+
7710
+ // src/skins/meet/components.tsx
7711
+ import { Alert, AlertDescription, Button, Checkbox, ErrorBox, Label, SegmentedControl, Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@ai-matrx/design-system";
7712
+
7713
+ // src/skins/meet/collab.tsx
7714
+ import { useEffect as useEffect5, useRef as useRef5, useState as useState3 } from "react";
7715
+
7716
+ // src/skins/meet/icons.tsx
7662
7717
  import { jsx as jsx3, jsxs } from "react/jsx-runtime";
7663
7718
  function Icon({ children, ...props }) {
7664
7719
  return /* @__PURE__ */ jsx3(
@@ -7754,12 +7809,6 @@ function LockIcon(props) {
7754
7809
  /* @__PURE__ */ jsx3("path", { d: "M8 10V7a4 4 0 0 1 8 0v3" })
7755
7810
  ] });
7756
7811
  }
7757
- function LayoutIcon(props) {
7758
- return /* @__PURE__ */ jsxs(Icon, { ...props, children: [
7759
- /* @__PURE__ */ jsx3("rect", { x: "3", y: "3", width: "18", height: "18", rx: "2" }),
7760
- /* @__PURE__ */ jsx3("path", { d: "M3 9h18M9 21V9" })
7761
- ] });
7762
- }
7763
7812
  function SettingsIcon(props) {
7764
7813
  return /* @__PURE__ */ jsxs(Icon, { ...props, children: [
7765
7814
  /* @__PURE__ */ jsx3("circle", { cx: "12", cy: "12", r: "3" }),
@@ -7778,12 +7827,6 @@ function PinIcon(props) {
7778
7827
  /* @__PURE__ */ jsx3("path", { d: "M9 2h6l-1 6 3.5 3.5V14H6.5v-2.5L10 8 9 2Z" })
7779
7828
  ] });
7780
7829
  }
7781
- function WifiLowIcon(props) {
7782
- return /* @__PURE__ */ jsxs(Icon, { ...props, children: [
7783
- /* @__PURE__ */ jsx3("path", { d: "M12 20h.01" }),
7784
- /* @__PURE__ */ jsx3("path", { d: "M8.5 16.5a5 5 0 0 1 7 0" })
7785
- ] });
7786
- }
7787
7830
  function SmileIcon(props) {
7788
7831
  return /* @__PURE__ */ jsxs(Icon, { ...props, children: [
7789
7832
  /* @__PURE__ */ jsx3("circle", { cx: "12", cy: "12", r: "10" }),
@@ -7896,40 +7939,11 @@ function UndoIcon(props) {
7896
7939
  ] });
7897
7940
  }
7898
7941
 
7899
- // src/react/collab.tsx
7942
+ // src/skins/meet/collab.tsx
7900
7943
  import { jsx as jsx4, jsxs as jsxs2 } from "react/jsx-runtime";
7901
- function useCollab() {
7902
- const host = useMeetHost();
7903
- const snapshot = useMeetSnapshot();
7904
- const isHost = useIsHost();
7905
- return {
7906
- collab: snapshot?.collab ?? null,
7907
- isHost,
7908
- localIdentity: snapshot?.localIdentity ?? null,
7909
- breakoutRoomId: snapshot?.breakoutRoomId ?? null,
7910
- async act(request) {
7911
- if (host === null) return { ok: false, message: "This meeting is not connected." };
7912
- try {
7913
- const result = await host.inRoom.collab(request);
7914
- return { ok: true, message: result.message, itemId: result.itemId };
7915
- } catch (error) {
7916
- return { ok: false, message: error.message ?? "That did not work." };
7917
- }
7918
- },
7919
- async moveTo(roomId) {
7920
- if (host === null) return { ok: false, message: "This meeting is not connected." };
7921
- try {
7922
- await host.engine.moveToBreakout(roomId);
7923
- return { ok: true, message: roomId === null ? "Back in the main room." : "Joined the breakout room." };
7924
- } catch (error) {
7925
- return { ok: false, message: error.message ?? "That room could not be joined." };
7926
- }
7927
- }
7928
- };
7929
- }
7930
7944
  function useNotice() {
7931
7945
  const [notice, setNotice] = useState3(null);
7932
- useEffect4(() => {
7946
+ useEffect5(() => {
7933
7947
  if (notice === null) return void 0;
7934
7948
  const timer = setTimeout(() => setNotice(null), notice.failed ? 7e3 : 3e3);
7935
7949
  return () => clearTimeout(timer);
@@ -7953,24 +7967,6 @@ function ActivityIcon({ panel }) {
7953
7967
  if (panel === "whiteboard") return /* @__PURE__ */ jsx4(WhiteboardIcon, { ...props });
7954
7968
  return /* @__PURE__ */ jsx4(BreakoutIcon, { ...props });
7955
7969
  }
7956
- function useAvailableActivities() {
7957
- const { collab, isHost } = useCollab();
7958
- const settings = collab?.settings ?? null;
7959
- if (settings === null) return [];
7960
- const out = [];
7961
- if (settings.whiteboardEnabled) out.push("whiteboard");
7962
- if (settings.pollsEnabled && (isHost || (collab?.polls.length ?? 0) > 0)) out.push("polls");
7963
- if (settings.qaEnabled) out.push("qa");
7964
- if (settings.breakoutsEnabled && (isHost || collab?.breakout?.state === "open")) out.push("breakouts");
7965
- return out;
7966
- }
7967
- function useActivityAttention() {
7968
- const { collab, isHost } = useCollab();
7969
- if (collab === null) return false;
7970
- if (collab.polls.some((poll) => poll.state === "live" && poll.myVote.length === 0 && !isHost)) return true;
7971
- if (isHost && collab.questions.some((q) => q.state === "open")) return true;
7972
- return false;
7973
- }
7974
7970
  function ActivitiesControl({
7975
7971
  active,
7976
7972
  onOpen
@@ -8090,7 +8086,7 @@ function PollCard({ poll }) {
8090
8086
  const { act, isHost } = useCollab();
8091
8087
  const [picked, setPicked] = useState3(poll.myVote.slice());
8092
8088
  const [notice, show] = useNotice();
8093
- useEffect4(() => setPicked(poll.myVote.slice()), [poll.myVote]);
8089
+ useEffect5(() => setPicked(poll.myVote.slice()), [poll.myVote]);
8094
8090
  const counts = poll.options.some((o) => o.votes !== void 0);
8095
8091
  const total = poll.options.reduce((sum, o) => sum + (o.votes ?? 0), 0);
8096
8092
  const canVote = poll.state === "live";
@@ -8348,7 +8344,7 @@ function WhiteboardPanel({ onClose }) {
8348
8344
  const [drawing, setDrawing] = useState3(null);
8349
8345
  const [pending, setPending] = useState3([]);
8350
8346
  const [notice, show] = useNotice();
8351
- const svgRef = useRef4(null);
8347
+ const svgRef = useRef5(null);
8352
8348
  const strokes = collab?.strokes ?? [];
8353
8349
  const mine = strokes.filter((s) => s.by === localIdentity);
8354
8350
  const point = (event) => {
@@ -8490,7 +8486,7 @@ function clock(ms2) {
8490
8486
  var BREAKOUT_EXPIRE_RETRY_MS = 5e3;
8491
8487
  function useNow(active) {
8492
8488
  const [now, setNow] = useState3(() => Date.now());
8493
- useEffect4(() => {
8489
+ useEffect5(() => {
8494
8490
  if (!active) return void 0;
8495
8491
  const timer = setInterval(() => setNow(Date.now()), 1e3);
8496
8492
  return () => clearInterval(timer);
@@ -8736,17 +8732,17 @@ function BreakoutBanner() {
8736
8732
  const assigned = assignedRoom(open, localIdentity);
8737
8733
  const [dismissedBroadcast, setDismissedBroadcast] = useState3(null);
8738
8734
  const [failure, setFailure] = useState3(null);
8739
- const expireAsked = useRef4(null);
8735
+ const expireAsked = useRef5(null);
8740
8736
  const moveAt = collab?.moveRequest?.at ?? null;
8741
- useEffect4(() => {
8742
- const request = host?.store.snapshot().collab.moveRequest ?? null;
8743
- if (request === null || host === null) return;
8744
- host.store.patch({ collab: { ...host.store.snapshot().collab, moveRequest: null } });
8737
+ useEffect5(() => {
8738
+ if (host === null) return;
8739
+ const request = takeMoveRequest(host.store);
8740
+ if (request === null) return;
8745
8741
  const here = host.store.snapshot().breakoutRoomId;
8746
8742
  if ((here ?? null) === request.roomId) return;
8747
8743
  void moveTo(request.roomId).then((result) => setFailure(result.ok ? null : result.message));
8748
8744
  }, [moveAt, host, moveTo]);
8749
- useEffect4(() => {
8745
+ useEffect5(() => {
8750
8746
  if (open === null || remaining === null || remaining > 0) return;
8751
8747
  const asked = expireAsked.current;
8752
8748
  if (asked !== null && asked.id === open.id && now - asked.at < BREAKOUT_EXPIRE_RETRY_MS) return;
@@ -8791,26 +8787,6 @@ function BreakoutBanner() {
8791
8787
  ] }) : null
8792
8788
  ] });
8793
8789
  }
8794
- function useCaptionTranslation(lines) {
8795
- const host = useMeetHost();
8796
- const snapshot = useMeetSnapshot();
8797
- const collab = snapshot?.collab ?? null;
8798
- const language = collab?.captionLanguage ?? null;
8799
- const asked = useRef4(/* @__PURE__ */ new Set());
8800
- const translations = collab?.captionTranslations ?? {};
8801
- const missing = lines.filter((line) => line.final && translations[line.id] === void 0).map(({ id, text: text3 }) => ({ id, text: text3 }));
8802
- const key = `${language ?? ""}|${missing.map((l) => l.id).join(",")}`;
8803
- const pending = useRef4(missing);
8804
- pending.current = missing;
8805
- useEffect4(() => {
8806
- if (host === null || language === null) return;
8807
- const batch = pending.current.filter((line) => !asked.current.has(`${language}:${line.id}`)).slice(-20);
8808
- if (batch.length === 0) return;
8809
- for (const line of batch) asked.current.add(`${language}:${line.id}`);
8810
- void host.inRoom.translateCaptions(language, batch).catch(() => void 0);
8811
- }, [host, language, key]);
8812
- return { language, translations, error: collab?.captionTranslationError ?? null };
8813
- }
8814
8790
  function CaptionLanguageSettings() {
8815
8791
  const host = useMeetHost();
8816
8792
  const snapshot = useMeetSnapshot();
@@ -8831,14 +8807,7 @@ function CaptionLanguageSettings() {
8831
8807
  value: current,
8832
8808
  onChange: (event) => {
8833
8809
  const next = event.target.value === "" ? null : event.target.value;
8834
- host.store.patch({
8835
- collab: {
8836
- ...host.store.snapshot().collab,
8837
- captionLanguage: next,
8838
- captionTranslations: {},
8839
- captionTranslationError: null
8840
- }
8841
- });
8810
+ setCaptionLanguage(host.store, next);
8842
8811
  },
8843
8812
  children: [
8844
8813
  /* @__PURE__ */ jsx4("option", { value: "", children: "Off \u2014 as spoken" }),
@@ -8854,20 +8823,8 @@ function CaptionLanguageSettings() {
8854
8823
  collab?.captionTranslationError != null ? /* @__PURE__ */ jsx4("p", { className: "mx-meet__panel-note mx-meet__collab-error", children: collab.captionTranslationError }) : null
8855
8824
  ] });
8856
8825
  }
8857
- function useCollabPanelRequest(onRequest) {
8858
- const host = useMeetHost();
8859
- const at = useMeetSnapshot()?.collab.panelRequest?.at ?? null;
8860
- const callback = useRef4(onRequest);
8861
- callback.current = onRequest;
8862
- useEffect4(() => {
8863
- const request = host?.store.snapshot().collab.panelRequest ?? null;
8864
- if (request === null || host === null) return;
8865
- host.store.patch({ collab: { ...host.store.snapshot().collab, panelRequest: null } });
8866
- callback.current(request.panel);
8867
- }, [at, host]);
8868
- }
8869
8826
 
8870
- // src/react/components.tsx
8827
+ // src/skins/meet/components.tsx
8871
8828
  import { Fragment, jsx as jsx5, jsxs as jsxs3 } from "react/jsx-runtime";
8872
8829
  function InertNotice({ what }) {
8873
8830
  return /* @__PURE__ */ jsxs3("div", { className: "mx-meet__empty", role: "status", children: [
@@ -8951,10 +8908,6 @@ function RecordingIndicator() {
8951
8908
  }
8952
8909
  );
8953
8910
  }
8954
- function ConnectionDot({ quality }) {
8955
- if (quality === "excellent" || quality === "good" || quality === "unknown") return null;
8956
- return /* @__PURE__ */ jsx5("span", { className: `mx-meet__quality mx-meet__quality--${quality}`, title: `Connection ${quality}`, children: /* @__PURE__ */ jsx5(WifiLowIcon, { width: 14, height: 14 }) });
8957
- }
8958
8911
  function RoleBadge({ role }) {
8959
8912
  if (role === "host") return /* @__PURE__ */ jsx5("span", { className: "mx-meet__badge", children: "Host" });
8960
8913
  if (role === "cohost") return /* @__PURE__ */ jsx5("span", { className: "mx-meet__badge", children: "Co-host" });
@@ -9079,7 +9032,6 @@ function Stage({ pageSize }) {
9079
9032
  ] }) : null
9080
9033
  ] });
9081
9034
  }
9082
- var MEET_REACTIONS = ["\u{1F496}", "\u{1F44D}", "\u{1F389}", "\u{1F44F}", "\u{1F602}", "\u{1F62E}", "\u{1F622}", "\u{1F914}", "\u{1F44E}"];
9083
9035
  function ControlBar({ onLeave }) {
9084
9036
  const room = useRoom();
9085
9037
  const recording = useRecording();
@@ -9104,7 +9056,7 @@ function ControlBar({ onLeave }) {
9104
9056
  });
9105
9057
  const privateChatAt = snapshot?.privateChatRequest?.at ?? null;
9106
9058
  const meetStore = useMeetHost()?.store ?? null;
9107
- useEffect5(() => {
9059
+ useEffect6(() => {
9108
9060
  const request = meetStore?.snapshot().privateChatRequest ?? null;
9109
9061
  if (request === null) return;
9110
9062
  setChatTo(request.to);
@@ -9343,12 +9295,12 @@ function useUnreadChat(open) {
9343
9295
  const chat = snapshot?.chat ?? [];
9344
9296
  const local = snapshot?.localIdentity ?? null;
9345
9297
  const [seen, setSeen] = useState4(0);
9346
- useEffect5(() => {
9298
+ useEffect6(() => {
9347
9299
  if (open) setSeen(chat.length);
9348
9300
  }, [open, chat.length]);
9349
9301
  const loaded = snapshot?.chatLoaded === true;
9350
9302
  const [baseline, setBaseline] = useState4(null);
9351
- useEffect5(() => {
9303
+ useEffect6(() => {
9352
9304
  if (loaded && baseline === null) setBaseline(chat.length);
9353
9305
  }, [loaded, baseline, chat.length]);
9354
9306
  if (open) return 0;
@@ -9361,7 +9313,7 @@ function Popover({
9361
9313
  children,
9362
9314
  placement = "up"
9363
9315
  }) {
9364
- const ref = useRef5(null);
9316
+ const ref = useRef6(null);
9365
9317
  const [style, setStyle] = useState4({
9366
9318
  position: "fixed",
9367
9319
  top: 0,
@@ -9413,7 +9365,7 @@ function Popover({
9413
9365
  window.removeEventListener("scroll", place, true);
9414
9366
  };
9415
9367
  }, [placement]);
9416
- useEffect5(() => {
9368
+ useEffect6(() => {
9417
9369
  const onKey = (event) => {
9418
9370
  if (event.key === "Escape") onClose();
9419
9371
  };
@@ -9447,7 +9399,7 @@ function MenuItem({
9447
9399
  );
9448
9400
  }
9449
9401
  function Toast({ text: text3, failed, onDone }) {
9450
- useEffect5(() => {
9402
+ useEffect6(() => {
9451
9403
  const timer = setTimeout(onDone, failed ? 7e3 : 4e3);
9452
9404
  return () => clearTimeout(timer);
9453
9405
  }, [text3, failed, onDone]);
@@ -9486,7 +9438,7 @@ function MeetingOverlays() {
9486
9438
  ] });
9487
9439
  }
9488
9440
  function ShortcutsSheet({ onClose }) {
9489
- useEffect5(() => {
9441
+ useEffect6(() => {
9490
9442
  const onKey = (event) => {
9491
9443
  if (event.key === "Escape") onClose();
9492
9444
  };
@@ -9524,7 +9476,7 @@ function PanelShell({
9524
9476
  onClose,
9525
9477
  children
9526
9478
  }) {
9527
- const ref = useRef5(null);
9479
+ const ref = useRef6(null);
9528
9480
  useLayoutEffect(() => {
9529
9481
  const panel = ref.current;
9530
9482
  const root = panel?.closest(".mx-meet");
@@ -9554,15 +9506,15 @@ function ChatPanel({
9554
9506
  const room = useRoom();
9555
9507
  const [draft, setDraft] = useState4("");
9556
9508
  const [recipient, setRecipient] = useState4(to);
9557
- const listRef = useRef5(null);
9509
+ const listRef = useRef6(null);
9558
9510
  const messages = snapshot?.chat ?? [];
9559
9511
  const local = snapshot?.localIdentity ?? null;
9560
9512
  const people = (snapshot?.participants ?? []).filter(
9561
9513
  (participant) => !participant.isLocal && !participant.isAgent
9562
9514
  );
9563
9515
  const recipientName = recipient === null ? null : people.find((p) => p.identity === recipient)?.displayName ?? null;
9564
- useEffect5(() => setRecipient(to), [to]);
9565
- useEffect5(() => {
9516
+ useEffect6(() => setRecipient(to), [to]);
9517
+ useEffect6(() => {
9566
9518
  const list = listRef.current;
9567
9519
  if (list !== null) list.scrollTop = list.scrollHeight;
9568
9520
  }, [messages.length]);
@@ -10018,7 +9970,7 @@ function DeviceSettings({
10018
9970
  const stream = useMicrophoneStream(microphone);
10019
9971
  const level = useAudioLevel(stream);
10020
9972
  const [testing, setTesting] = useState4(false);
10021
- useEffect5(() => {
9973
+ useEffect6(() => {
10022
9974
  void host.devices.refresh();
10023
9975
  }, [host]);
10024
9976
  return /* @__PURE__ */ jsxs3("section", { className: "mx-meet__section", "aria-label": "Devices", children: [
@@ -10048,7 +10000,7 @@ function DeviceSettings({
10048
10000
  function EffectsSettings({ preview }) {
10049
10001
  const effects = useMediaEffects();
10050
10002
  const [error, setError] = useState4(null);
10051
- const fileRef = useRef5(null);
10003
+ const fileRef = useRef6(null);
10052
10004
  const supported = effects.backgroundsSupported || preview != null || videoEffectsSupported();
10053
10005
  const apply = (next) => {
10054
10006
  setError(null);
@@ -10171,7 +10123,7 @@ async function playTestSound(sinkId) {
10171
10123
  }
10172
10124
  function useMicrophoneStream(deviceId2) {
10173
10125
  const [stream, setStream] = useState4(null);
10174
- useEffect5(() => {
10126
+ useEffect6(() => {
10175
10127
  if (deviceId2 === "off") return void 0;
10176
10128
  let live = true;
10177
10129
  let opened = null;
@@ -10455,7 +10407,7 @@ function PreJoinBody({
10455
10407
  const micStream = useMicrophoneStream(microphone ? mic : "off");
10456
10408
  const level = useAudioLevel(micStream);
10457
10409
  const [speakerTesting, setSpeakerTesting] = useState4(false);
10458
- useEffect5(() => {
10410
+ useEffect6(() => {
10459
10411
  void host.devices.refresh();
10460
10412
  }, [host]);
10461
10413
  return /* @__PURE__ */ jsxs3("div", { className: "mx-meet__prejoin", children: [
@@ -10573,10 +10525,10 @@ function PreJoinBody({
10573
10525
  function useCameraPreview(deviceId2, effects) {
10574
10526
  const [preview, setPreview] = useState4(null);
10575
10527
  const [error, setError] = useState4(null);
10576
- const current = useRef5(null);
10577
- const initialEffect = useRef5(toVideoEffect(effects));
10528
+ const current = useRef6(null);
10529
+ const initialEffect = useRef6(toVideoEffect(effects));
10578
10530
  initialEffect.current = toVideoEffect(effects);
10579
- useEffect5(() => {
10531
+ useEffect6(() => {
10580
10532
  if (deviceId2 === void 0) return void 0;
10581
10533
  let live = true;
10582
10534
  setError(null);
@@ -10642,43 +10594,17 @@ function DevicePicker({
10642
10594
  )
10643
10595
  ] });
10644
10596
  }
10645
- function MeetingRoom(props) {
10646
- const host = useMeetHost();
10647
- if (host === null) {
10648
- return /* @__PURE__ */ jsx5(MeetRoot, { meeting: props.meeting, children: /* @__PURE__ */ jsx5("div", { className: "mx-meet", children: /* @__PURE__ */ jsx5(InertNotice, { what: "This meeting" }) }) });
10649
- }
10650
- return /* @__PURE__ */ jsx5(MeetRoot, { meeting: props.meeting, children: /* @__PURE__ */ jsx5(MeetingRoomBody, { ...props, host }) });
10651
- }
10652
- function MeetingRoomBody({
10597
+ function MeetSkinRoom({
10653
10598
  roomName,
10654
10599
  meetingId,
10655
10600
  slug,
10656
- meeting: given,
10657
10601
  onLeave,
10658
- headerControls,
10659
- host
10602
+ headerControls
10660
10603
  }) {
10661
- const snapshot = useMeetSnapshot();
10662
- const isHost = useIsHost();
10604
+ const { host, snapshot, isHost } = useMeetCore();
10663
10605
  const elapsed = useElapsed(snapshot?.meeting?.startedAt ?? null);
10664
10606
  const phase = snapshot?.phase ?? "idle";
10665
- useEffect5(() => {
10666
- host.meetings.watch(roomName);
10667
- }, [host, roomName]);
10668
- useEffect5(() => {
10669
- if (given === void 0) return;
10670
- if (host.store.snapshot().meeting !== null) return;
10671
- host.store.patch({ meeting: given, locked: given.locked });
10672
- }, [host, given]);
10673
- const watchedId = meetingId ?? snapshot?.meeting?.id ?? null;
10674
- useEffect5(() => {
10675
- if (watchedId === null) return;
10676
- host.meetings.watchMeeting(asMeetingId(watchedId));
10677
- }, [host, watchedId]);
10678
- const record = snapshot?.meeting ?? given ?? null;
10679
- if (hasEnded(record) && phase !== "connected" && phase !== "reconnecting") {
10680
- return /* @__PURE__ */ jsx5(MeetingRecordView, { meeting: record });
10681
- }
10607
+ if (host === null) return null;
10682
10608
  if (phase === "idle" || phase === "failed" || phase === "left") {
10683
10609
  return /* @__PURE__ */ jsx5("div", { className: "mx-meet", children: /* @__PURE__ */ jsx5(
10684
10610
  PreJoin,
@@ -10699,7 +10625,7 @@ function MeetingRoomBody({
10699
10625
  /* @__PURE__ */ jsx5("h1", { className: "mx-meet__title", children: snapshot?.meeting?.title ?? "Meeting" }),
10700
10626
  /* @__PURE__ */ jsxs3("span", { className: "mx-meet__meta", children: [
10701
10627
  participantSummary(snapshot?.participants ?? []),
10702
- elapsed > 0 ? ` \xB7 ${formatDurationMs4(elapsed)}` : ""
10628
+ elapsed > 0 ? ` \xB7 ${formatDurationMs3(elapsed)}` : ""
10703
10629
  ] }),
10704
10630
  /* @__PURE__ */ jsx5(RecordingIndicator, {}),
10705
10631
  snapshot?.locked === true ? /* @__PURE__ */ jsxs3("span", { className: "mx-meet__badge", children: [
@@ -10716,8 +10642,8 @@ function MeetingRoomBody({
10716
10642
  ] });
10717
10643
  }
10718
10644
  function WaitingRoom({ roomName, host }) {
10719
- const knocked = useRef5(false);
10720
- useEffect5(() => {
10645
+ const knocked = useRef6(false);
10646
+ useEffect6(() => {
10721
10647
  if (knocked.current) return;
10722
10648
  knocked.current = true;
10723
10649
  host.meetings.knock(roomName);
@@ -10785,150 +10711,17 @@ function HostMenu() {
10785
10711
  end.notice !== null ? /* @__PURE__ */ jsx5("span", { className: "mx-meet__notice", role: "status", children: end.notice }) : null
10786
10712
  ] });
10787
10713
  }
10788
- function CallButton({
10789
- person,
10790
- mode = "video",
10791
- children
10792
- }) {
10793
- const calls = useCalls();
10794
- if (!calls.canCall) return null;
10795
- return /* @__PURE__ */ jsx5(
10796
- "button",
10797
- {
10798
- type: "button",
10799
- className: "mx-meet__call-button",
10800
- onClick: () => {
10801
- void calls.call([person.userId], mode);
10802
- },
10803
- "aria-label": `Call ${person.displayName}`,
10804
- children: children ?? /* @__PURE__ */ jsx5(PhoneIcon, { width: 18, height: 18 })
10805
- }
10806
- );
10807
- }
10808
- function IncomingCallHost() {
10809
- const calls = useCalls();
10810
- if (calls.incoming.length === 0) return null;
10811
- return /* @__PURE__ */ jsx5("div", { className: "mx-meet__ringing-stack", children: calls.incoming.map((invite) => /* @__PURE__ */ jsx5(IncomingCallCard, { invite }, invite.id)) });
10812
- }
10813
- function IncomingCallCard({ invite }) {
10814
- const calls = useCalls();
10815
- return /* @__PURE__ */ jsxs3("section", { className: "mx-meet__ringing", role: "alertdialog", "aria-label": "Incoming call", children: [
10816
- /* @__PURE__ */ jsx5(Avatar, { name: invite.callerName, url: invite.callerAvatarUrl, size: 56 }),
10817
- /* @__PURE__ */ jsxs3("div", { className: "mx-meet__ringing-text", children: [
10818
- /* @__PURE__ */ jsx5("strong", { children: invite.callerName }),
10819
- /* @__PURE__ */ jsx5("span", { children: invite.mode === "video" ? "Incoming video call" : "Incoming call" })
10820
- ] }),
10821
- /* @__PURE__ */ jsxs3("div", { className: "mx-meet__ringing-actions", children: [
10822
- /* @__PURE__ */ jsx5(ControlButton, { label: "Decline", danger: true, onClick: () => void calls.decline(invite), children: /* @__PURE__ */ jsx5(PhoneOffIcon, {}) }),
10823
- invite.mode === "video" ? /* @__PURE__ */ jsx5(
10824
- ControlButton,
10825
- {
10826
- label: "Accept without video",
10827
- onClick: () => void calls.accept({ ...invite, mode: "audio" }),
10828
- children: /* @__PURE__ */ jsx5(CameraOffIcon, {})
10829
- }
10830
- ) : null,
10831
- /* @__PURE__ */ jsx5(ControlButton, { label: "Accept", onClick: () => void calls.accept(invite), children: /* @__PURE__ */ jsx5(PhoneIcon, {}) })
10832
- ] })
10833
- ] });
10834
- }
10835
- function ScheduleMeeting(props) {
10836
- const host = useMeetHost();
10837
- if (host === null) return /* @__PURE__ */ jsx5(InertNotice, { what: "Scheduling a meeting" });
10838
- return /* @__PURE__ */ jsx5(ScheduleMeetingBody, { ...props, host });
10839
- }
10840
- function ScheduleMeetingBody({
10841
- appBaseUrl,
10842
- onScheduled,
10843
- host
10844
- }) {
10845
- const [title, setTitle] = useState4("");
10846
- const [when2, setWhen] = useState4("");
10847
- const [kind, setKind] = useState4("scheduled");
10848
- const [busy, setBusy] = useState4(false);
10849
- const [link, setLink] = useState4(null);
10850
- const [error, setError] = useState4(null);
10851
- const disabled = useMemo4(() => title.trim().length === 0 || busy, [title, busy]);
10852
- return /* @__PURE__ */ jsxs3(
10853
- "form",
10854
- {
10855
- className: "mx-meet__schedule",
10856
- onSubmit: (event) => {
10857
- event.preventDefault();
10858
- if (host.identity.userId === null) return;
10859
- setBusy(true);
10860
- setError(null);
10861
- void host.repository.getOrCreateMeeting({
10862
- organizationId: host.identity.organizationId,
10863
- hostUserId: host.identity.userId,
10864
- title: title.trim(),
10865
- kind,
10866
- scheduledFor: when2.length > 0 ? new Date(when2).toISOString() : null
10867
- }).then((meeting) => {
10868
- setLink(meetingLink(appBaseUrl, meeting.slug));
10869
- onScheduled?.(meeting.slug);
10870
- }).catch((thrown) => {
10871
- setError(
10872
- thrown.remedy ?? thrown.message ?? "The meeting could not be created."
10873
- );
10874
- }).finally(() => setBusy(false));
10875
- },
10876
- children: [
10877
- /* @__PURE__ */ jsxs3("label", { className: "mx-meet__field", children: [
10878
- /* @__PURE__ */ jsx5("span", { className: "mx-meet__field-label", children: "Title" }),
10879
- /* @__PURE__ */ jsx5(
10880
- "input",
10881
- {
10882
- className: "mx-meet__input",
10883
- value: title,
10884
- onChange: (event) => setTitle(event.target.value),
10885
- placeholder: "Weekly sync"
10886
- }
10887
- )
10888
- ] }),
10889
- /* @__PURE__ */ jsxs3("label", { className: "mx-meet__field", children: [
10890
- /* @__PURE__ */ jsx5("span", { className: "mx-meet__field-label", children: "When" }),
10891
- /* @__PURE__ */ jsx5(
10892
- "input",
10893
- {
10894
- className: "mx-meet__input",
10895
- type: "datetime-local",
10896
- value: when2,
10897
- onChange: (event) => setWhen(event.target.value)
10898
- }
10899
- )
10900
- ] }),
10901
- /* @__PURE__ */ jsxs3("label", { className: "mx-meet__field", children: [
10902
- /* @__PURE__ */ jsx5("span", { className: "mx-meet__field-label", children: "Repeats" }),
10903
- /* @__PURE__ */ jsxs3(
10904
- "select",
10905
- {
10906
- className: "mx-meet__select",
10907
- value: kind,
10908
- onChange: (event) => setKind(event.target.value),
10909
- children: [
10910
- /* @__PURE__ */ jsx5("option", { value: "scheduled", children: "Once" }),
10911
- /* @__PURE__ */ jsx5("option", { value: "recurring", children: "Recurring \u2014 one link, every time" })
10912
- ]
10913
- }
10914
- )
10915
- ] }),
10916
- /* @__PURE__ */ jsx5("button", { type: "submit", className: "mx-meet__primary", disabled, children: busy ? "Creating\u2026" : "Create meeting" }),
10917
- link !== null ? /* @__PURE__ */ jsxs3("p", { className: "mx-meet__link-out", children: [
10918
- /* @__PURE__ */ jsx5("span", { children: "Anyone with this link can join \u2014 no account needed." }),
10919
- /* @__PURE__ */ jsx5("code", { children: link })
10920
- ] }) : null,
10921
- error !== null ? /* @__PURE__ */ jsx5("p", { className: "mx-meet__error", children: error }) : null
10922
- ]
10923
- }
10924
- );
10925
- }
10926
10714
  function ReactionOverlay({
10927
10715
  reactions
10928
10716
  }) {
10929
10717
  if (reactions.length === 0) return null;
10930
10718
  return /* @__PURE__ */ jsx5("div", { className: "mx-meet__reactions", "aria-hidden": "true", children: reactions.map((reaction) => /* @__PURE__ */ jsx5("span", { className: "mx-meet__reaction", children: reaction.emoji }, reaction.id)) });
10931
10719
  }
10720
+ function clockOf(iso) {
10721
+ const at = new Date(iso);
10722
+ if (Number.isNaN(at.getTime())) return "";
10723
+ return at.toLocaleTimeString(void 0, { hour: "numeric", minute: "2-digit" });
10724
+ }
10932
10725
  function GuestRecordAccessControl({
10933
10726
  meeting
10934
10727
  }) {
@@ -10969,15 +10762,20 @@ function GuestRecordAccessControl({
10969
10762
  ] }) : null
10970
10763
  ] });
10971
10764
  }
10765
+
10766
+ // src/react/record.tsx
10767
+ import { useEffect as useEffect7, useState as useState5 } from "react";
10768
+ import { ErrorBox as ErrorBox2 } from "@ai-matrx/design-system";
10769
+ import { Fragment as Fragment2, jsx as jsx6, jsxs as jsxs4 } from "react/jsx-runtime";
10972
10770
  function MeetingRecordView({
10973
10771
  meeting,
10974
10772
  onRejoin
10975
10773
  }) {
10976
10774
  const host = useMeetHost();
10977
10775
  if (host === null) {
10978
- return /* @__PURE__ */ jsx5("div", { className: "mx-meet mx-meet--record", children: /* @__PURE__ */ jsx5(InertNotice, { what: "This meeting record" }) });
10776
+ return /* @__PURE__ */ jsx6("div", { className: "mx-meet mx-meet--record", children: /* @__PURE__ */ jsx6(InertNotice, { what: "This meeting record" }) });
10979
10777
  }
10980
- return /* @__PURE__ */ jsx5(MeetingRecordBody, { meeting, ...onRejoin !== void 0 ? { onRejoin } : {} });
10778
+ return /* @__PURE__ */ jsx6(MeetingRecordBody, { meeting, ...onRejoin !== void 0 ? { onRejoin } : {} });
10981
10779
  }
10982
10780
  function MeetingRecordBody({
10983
10781
  meeting,
@@ -10985,19 +10783,19 @@ function MeetingRecordBody({
10985
10783
  }) {
10986
10784
  const host = useRequiredMeetHost();
10987
10785
  const record = useMeetingRecord(meeting);
10988
- const [question, setQuestion] = useState4("");
10989
- const [tab, setTab] = useState4("summary");
10786
+ const [question, setQuestion] = useState5("");
10787
+ const [tab, setTab] = useState5("summary");
10990
10788
  if (record.failure !== null) {
10991
- return /* @__PURE__ */ jsx5("div", { className: "mx-meet mx-meet--record", children: /* @__PURE__ */ jsxs3(ErrorBox, { as: "div", className: "mx-meet__empty", error: record.failure, operation: "Open this meeting record", origin: "meet/components", children: [
10992
- /* @__PURE__ */ jsx5("p", { className: "mx-meet__empty-title", children: "This meeting record could not be opened" }),
10993
- /* @__PURE__ */ jsx5("p", { className: "mx-meet__empty-body", children: record.failure.message }),
10994
- /* @__PURE__ */ jsx5("p", { className: "mx-meet__empty-body", children: record.failure.remedy })
10789
+ return /* @__PURE__ */ jsx6("div", { className: "mx-meet mx-meet--record", children: /* @__PURE__ */ jsxs4(ErrorBox2, { as: "div", className: "mx-meet__empty", error: record.failure, operation: "Open this meeting record", origin: "meet/components", children: [
10790
+ /* @__PURE__ */ jsx6("p", { className: "mx-meet__empty-title", children: "This meeting record could not be opened" }),
10791
+ /* @__PURE__ */ jsx6("p", { className: "mx-meet__empty-body", children: record.failure.message }),
10792
+ /* @__PURE__ */ jsx6("p", { className: "mx-meet__empty-body", children: record.failure.remedy })
10995
10793
  ] }) });
10996
10794
  }
10997
10795
  if (record.loading || record.record === null) {
10998
- return /* @__PURE__ */ jsx5("div", { className: "mx-meet mx-meet--record", children: /* @__PURE__ */ jsxs3("div", { className: "mx-meet__empty", role: "status", children: [
10999
- /* @__PURE__ */ jsx5("p", { className: "mx-meet__empty-title", children: "Opening the meeting record\u2026" }),
11000
- /* @__PURE__ */ jsx5("p", { className: "mx-meet__empty-body", children: "Reading the summary, the notes and the transcript this meeting left behind." })
10796
+ return /* @__PURE__ */ jsx6("div", { className: "mx-meet mx-meet--record", children: /* @__PURE__ */ jsxs4("div", { className: "mx-meet__empty", role: "status", children: [
10797
+ /* @__PURE__ */ jsx6("p", { className: "mx-meet__empty-title", children: "Opening the meeting record\u2026" }),
10798
+ /* @__PURE__ */ jsx6("p", { className: "mx-meet__empty-body", children: "Reading the summary, the notes and the transcript this meeting left behind." })
11001
10799
  ] }) });
11002
10800
  }
11003
10801
  const bundle = record.record;
@@ -11016,44 +10814,44 @@ function MeetingRecordBody({
11016
10814
  );
11017
10815
  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;
11018
10816
  if (entirelyRestricted) {
11019
- return /* @__PURE__ */ jsxs3("div", { className: "mx-meet mx-meet--record", children: [
11020
- /* @__PURE__ */ jsx5("header", { className: "mx-meet__record-head", children: /* @__PURE__ */ jsxs3("div", { className: "mx-meet__record-head-inner", children: [
11021
- /* @__PURE__ */ jsx5("p", { className: "mx-meet__record-eyebrow", children: "Meeting record" }),
11022
- /* @__PURE__ */ jsx5("h1", { className: "mx-meet__record-title", children: meeting.title }),
11023
- /* @__PURE__ */ jsx5("p", { className: "mx-meet__record-when", children: meetingWhen(meeting) }),
11024
- onRejoin !== void 0 ? /* @__PURE__ */ jsx5("button", { type: "button", className: "mx-meet__link", onClick: onRejoin, children: "Open this link again" }) : null
10817
+ return /* @__PURE__ */ jsxs4("div", { className: "mx-meet mx-meet--record", children: [
10818
+ /* @__PURE__ */ jsx6("header", { className: "mx-meet__record-head", children: /* @__PURE__ */ jsxs4("div", { className: "mx-meet__record-head-inner", children: [
10819
+ /* @__PURE__ */ jsx6("p", { className: "mx-meet__record-eyebrow", children: "Meeting record" }),
10820
+ /* @__PURE__ */ jsx6("h1", { className: "mx-meet__record-title", children: meeting.title }),
10821
+ /* @__PURE__ */ jsx6("p", { className: "mx-meet__record-when", children: meetingWhen(meeting) }),
10822
+ onRejoin !== void 0 ? /* @__PURE__ */ jsx6("button", { type: "button", className: "mx-meet__link", onClick: onRejoin, children: "Open this link again" }) : null
11025
10823
  ] }) }),
11026
- /* @__PURE__ */ jsx5("div", { className: "mx-meet__record-body", children: restrictionNotices.map((notice2) => /* @__PURE__ */ jsxs3("div", { className: "mx-meet__record-access", role: "status", children: [
11027
- /* @__PURE__ */ jsx5("p", { className: "mx-meet__record-access-title", children: "About this record" }),
11028
- /* @__PURE__ */ jsx5("p", { className: "mx-meet__record-access-message", children: notice2.message }),
11029
- /* @__PURE__ */ jsx5("p", { className: "mx-meet__record-access-remedy", children: notice2.remedy })
10824
+ /* @__PURE__ */ jsx6("div", { className: "mx-meet__record-body", children: restrictionNotices.map((notice2) => /* @__PURE__ */ jsxs4("div", { className: "mx-meet__record-access", role: "status", children: [
10825
+ /* @__PURE__ */ jsx6("p", { className: "mx-meet__record-access-title", children: "About this record" }),
10826
+ /* @__PURE__ */ jsx6("p", { className: "mx-meet__record-access-message", children: notice2.message }),
10827
+ /* @__PURE__ */ jsx6("p", { className: "mx-meet__record-access-remedy", children: notice2.remedy })
11030
10828
  ] }, notice2.parts.join("-"))) })
11031
10829
  ] });
11032
10830
  }
11033
- return /* @__PURE__ */ jsxs3("div", { className: "mx-meet mx-meet--record", children: [
11034
- /* @__PURE__ */ jsx5("header", { className: "mx-meet__record-head", children: /* @__PURE__ */ jsxs3("div", { className: "mx-meet__record-head-inner", children: [
11035
- /* @__PURE__ */ jsx5("p", { className: "mx-meet__record-eyebrow", children: "Meeting record" }),
11036
- /* @__PURE__ */ jsx5("h1", { className: "mx-meet__record-title", children: meeting.title }),
11037
- /* @__PURE__ */ jsx5("p", { className: "mx-meet__record-when", children: meetingWhen(meeting) }),
11038
- onRejoin !== void 0 ? /* @__PURE__ */ jsx5("button", { type: "button", className: "mx-meet__link", onClick: onRejoin, children: "Open this link again" }) : null
10831
+ return /* @__PURE__ */ jsxs4("div", { className: "mx-meet mx-meet--record", children: [
10832
+ /* @__PURE__ */ jsx6("header", { className: "mx-meet__record-head", children: /* @__PURE__ */ jsxs4("div", { className: "mx-meet__record-head-inner", children: [
10833
+ /* @__PURE__ */ jsx6("p", { className: "mx-meet__record-eyebrow", children: "Meeting record" }),
10834
+ /* @__PURE__ */ jsx6("h1", { className: "mx-meet__record-title", children: meeting.title }),
10835
+ /* @__PURE__ */ jsx6("p", { className: "mx-meet__record-when", children: meetingWhen(meeting) }),
10836
+ onRejoin !== void 0 ? /* @__PURE__ */ jsx6("button", { type: "button", className: "mx-meet__link", onClick: onRejoin, children: "Open this link again" }) : null
11039
10837
  ] }) }),
11040
- /* @__PURE__ */ jsxs3("div", { className: "mx-meet__record-body", children: [
11041
- restrictionNotices.map((notice2) => /* @__PURE__ */ jsxs3("div", { className: "mx-meet__record-access", role: "status", children: [
11042
- /* @__PURE__ */ jsx5("p", { className: "mx-meet__record-access-title", children: "About this record" }),
11043
- /* @__PURE__ */ jsx5("p", { className: "mx-meet__record-access-message", children: notice2.message }),
11044
- /* @__PURE__ */ jsx5("p", { className: "mx-meet__record-access-remedy", children: notice2.remedy })
10838
+ /* @__PURE__ */ jsxs4("div", { className: "mx-meet__record-body", children: [
10839
+ restrictionNotices.map((notice2) => /* @__PURE__ */ jsxs4("div", { className: "mx-meet__record-access", role: "status", children: [
10840
+ /* @__PURE__ */ jsx6("p", { className: "mx-meet__record-access-title", children: "About this record" }),
10841
+ /* @__PURE__ */ jsx6("p", { className: "mx-meet__record-access-message", children: notice2.message }),
10842
+ /* @__PURE__ */ jsx6("p", { className: "mx-meet__record-access-remedy", children: notice2.remedy })
11045
10843
  ] }, notice2.parts.join("-"))),
11046
10844
  attended.length === 0 ? (
11047
10845
  /* NOT SILENCE. A refused attendance read used to remove the whole
11048
10846
  section, so the reader could not tell "nobody" from "not shown". */
11049
- /* @__PURE__ */ jsxs3("section", { className: "mx-meet__record-section", "aria-label": "Who attended", children: [
11050
- /* @__PURE__ */ jsx5("h2", { className: "mx-meet__record-section-title", children: "Who attended" }),
11051
- /* @__PURE__ */ jsx5("p", { className: "mx-meet__panel-note", children: absenceSentence(bundle, "attendance", "Nobody is recorded as having attended.") })
10847
+ /* @__PURE__ */ jsxs4("section", { className: "mx-meet__record-section", "aria-label": "Who attended", children: [
10848
+ /* @__PURE__ */ jsx6("h2", { className: "mx-meet__record-section-title", children: "Who attended" }),
10849
+ /* @__PURE__ */ jsx6("p", { className: "mx-meet__panel-note", children: absenceSentence(bundle, "attendance", "Nobody is recorded as having attended.") })
11052
10850
  ] })
11053
- ) : /* @__PURE__ */ jsxs3("section", { className: "mx-meet__record-section", "aria-label": "Who attended", children: [
11054
- /* @__PURE__ */ jsx5("h2", { className: "mx-meet__record-section-title", children: "Who attended" }),
11055
- /* @__PURE__ */ jsx5("ul", { className: "mx-meet__record-attendees", children: attended.map((person) => /* @__PURE__ */ jsxs3("li", { className: "mx-meet__record-attendee", children: [
11056
- /* @__PURE__ */ jsx5(
10851
+ ) : /* @__PURE__ */ jsxs4("section", { className: "mx-meet__record-section", "aria-label": "Who attended", children: [
10852
+ /* @__PURE__ */ jsx6("h2", { className: "mx-meet__record-section-title", children: "Who attended" }),
10853
+ /* @__PURE__ */ jsx6("ul", { className: "mx-meet__record-attendees", children: attended.map((person) => /* @__PURE__ */ jsxs4("li", { className: "mx-meet__record-attendee", children: [
10854
+ /* @__PURE__ */ jsx6(
11057
10855
  Avatar,
11058
10856
  {
11059
10857
  name: displayNameFor(bundle.names, person.identity, person.displayName),
@@ -11061,26 +10859,26 @@ function MeetingRecordBody({
11061
10859
  size: 28
11062
10860
  }
11063
10861
  ),
11064
- /* @__PURE__ */ jsxs3("span", { className: "mx-meet__person-name", children: [
10862
+ /* @__PURE__ */ jsxs4("span", { className: "mx-meet__person-name", children: [
11065
10863
  displayNameFor(bundle.names, person.identity, person.displayName),
11066
- person.role === "host" ? /* @__PURE__ */ jsx5("span", { className: "mx-meet__badge", children: "Host" }) : null,
11067
- person.role === "guest" ? /* @__PURE__ */ jsx5("span", { className: "mx-meet__badge", children: "Guest" }) : null,
11068
- person.isAgent ? /* @__PURE__ */ jsx5("span", { className: "mx-meet__badge", children: "Meeting assistant" }) : null
10864
+ person.role === "host" ? /* @__PURE__ */ jsx6("span", { className: "mx-meet__badge", children: "Host" }) : null,
10865
+ person.role === "guest" ? /* @__PURE__ */ jsx6("span", { className: "mx-meet__badge", children: "Guest" }) : null,
10866
+ person.isAgent ? /* @__PURE__ */ jsx6("span", { className: "mx-meet__badge", children: "Meeting assistant" }) : null
11069
10867
  ] })
11070
10868
  ] }, person.id)) })
11071
10869
  ] }),
11072
- bundle.recording !== null ? /* @__PURE__ */ jsxs3("section", { className: "mx-meet__record-section mx-meet__recording-card", "aria-label": "Recording", children: [
11073
- /* @__PURE__ */ jsx5("h2", { className: "mx-meet__record-section-title", children: "Recording" }),
11074
- fileId !== null ? /* @__PURE__ */ jsxs3(Fragment, { children: [
11075
- /* @__PURE__ */ jsx5(RecordingPlayer, { fileId }),
11076
- notice !== null ? /* @__PURE__ */ jsx5("p", { className: "mx-meet__panel-note", children: notice }) : null
11077
- ] }) : /* @__PURE__ */ jsx5("p", { className: "mx-meet__panel-note", children: notice ?? "This recording has no file." })
11078
- ] }) : wasRefused(bundle, "recording") ? /* @__PURE__ */ jsxs3("section", { className: "mx-meet__record-section", "aria-label": "Recording", children: [
11079
- /* @__PURE__ */ jsx5("h2", { className: "mx-meet__record-section-title", children: "Recording" }),
11080
- /* @__PURE__ */ jsx5("p", { className: "mx-meet__panel-note", children: REFUSED_ABSENCE })
10870
+ bundle.recording !== null ? /* @__PURE__ */ jsxs4("section", { className: "mx-meet__record-section mx-meet__recording-card", "aria-label": "Recording", children: [
10871
+ /* @__PURE__ */ jsx6("h2", { className: "mx-meet__record-section-title", children: "Recording" }),
10872
+ fileId !== null ? /* @__PURE__ */ jsxs4(Fragment2, { children: [
10873
+ /* @__PURE__ */ jsx6(RecordingPlayer, { fileId }),
10874
+ notice !== null ? /* @__PURE__ */ jsx6("p", { className: "mx-meet__panel-note", children: notice }) : null
10875
+ ] }) : /* @__PURE__ */ jsx6("p", { className: "mx-meet__panel-note", children: notice ?? "This recording has no file." })
10876
+ ] }) : wasRefused(bundle, "recording") ? /* @__PURE__ */ jsxs4("section", { className: "mx-meet__record-section", "aria-label": "Recording", children: [
10877
+ /* @__PURE__ */ jsx6("h2", { className: "mx-meet__record-section-title", children: "Recording" }),
10878
+ /* @__PURE__ */ jsx6("p", { className: "mx-meet__panel-note", children: REFUSED_ABSENCE })
11081
10879
  ] }) : null,
11082
- /* @__PURE__ */ jsxs3("nav", { className: "mx-meet__record-tabs", "aria-label": "Meeting record sections", children: [
11083
- /* @__PURE__ */ jsx5(
10880
+ /* @__PURE__ */ jsxs4("nav", { className: "mx-meet__record-tabs", "aria-label": "Meeting record sections", children: [
10881
+ /* @__PURE__ */ jsx6(
11084
10882
  "button",
11085
10883
  {
11086
10884
  type: "button",
@@ -11090,7 +10888,7 @@ function MeetingRecordBody({
11090
10888
  children: "Summary & decisions"
11091
10889
  }
11092
10890
  ),
11093
- /* @__PURE__ */ jsx5(
10891
+ /* @__PURE__ */ jsx6(
11094
10892
  "button",
11095
10893
  {
11096
10894
  type: "button",
@@ -11100,7 +10898,7 @@ function MeetingRecordBody({
11100
10898
  children: "Notes as it happened"
11101
10899
  }
11102
10900
  ),
11103
- /* @__PURE__ */ jsx5(
10901
+ /* @__PURE__ */ jsx6(
11104
10902
  "button",
11105
10903
  {
11106
10904
  type: "button",
@@ -11111,15 +10909,15 @@ function MeetingRecordBody({
11111
10909
  }
11112
10910
  )
11113
10911
  ] }),
11114
- tab === "summary" ? /* @__PURE__ */ jsxs3(Fragment, { children: [
11115
- /* @__PURE__ */ jsxs3("section", { className: "mx-meet__record-section", "aria-label": "Summary", children: [
11116
- /* @__PURE__ */ jsx5("h2", { className: "mx-meet__record-section-title", children: "Summary" }),
11117
- wrapUp.state === "written" ? /* @__PURE__ */ jsx5("p", { className: "mx-meet__record-summary", children: bundle.summary?.text }) : wrapUp.state === "in-progress" ? /* @__PURE__ */ jsxs3("div", { className: "mx-meet__panel-note", role: "status", children: [
11118
- /* @__PURE__ */ jsx5("p", { children: wrapUp.message }),
11119
- /* @__PURE__ */ jsx5("button", { type: "button", className: "mx-meet__link", onClick: record.reload, children: "Check again" })
11120
- ] }) : /* @__PURE__ */ jsx5("p", { className: "mx-meet__panel-note", role: wrapUp.state === "failed" ? "alert" : void 0, children: wrapUp.message })
10912
+ tab === "summary" ? /* @__PURE__ */ jsxs4(Fragment2, { children: [
10913
+ /* @__PURE__ */ jsxs4("section", { className: "mx-meet__record-section", "aria-label": "Summary", children: [
10914
+ /* @__PURE__ */ jsx6("h2", { className: "mx-meet__record-section-title", children: "Summary" }),
10915
+ wrapUp.state === "written" ? /* @__PURE__ */ jsx6("p", { className: "mx-meet__record-summary", children: bundle.summary?.text }) : wrapUp.state === "in-progress" ? /* @__PURE__ */ jsxs4("div", { className: "mx-meet__panel-note", role: "status", children: [
10916
+ /* @__PURE__ */ jsx6("p", { children: wrapUp.message }),
10917
+ /* @__PURE__ */ jsx6("button", { type: "button", className: "mx-meet__link", onClick: record.reload, children: "Check again" })
10918
+ ] }) : /* @__PURE__ */ jsx6("p", { className: "mx-meet__panel-note", role: wrapUp.state === "failed" ? "alert" : void 0, children: wrapUp.message })
11121
10919
  ] }),
11122
- /* @__PURE__ */ jsx5(
10920
+ /* @__PURE__ */ jsx6(
11123
10921
  NoteList,
11124
10922
  {
11125
10923
  title: "Decisions",
@@ -11131,7 +10929,7 @@ function MeetingRecordBody({
11131
10929
  )
11132
10930
  }
11133
10931
  ),
11134
- /* @__PURE__ */ jsx5(
10932
+ /* @__PURE__ */ jsx6(
11135
10933
  NoteList,
11136
10934
  {
11137
10935
  title: "Action items",
@@ -11144,42 +10942,42 @@ function MeetingRecordBody({
11144
10942
  }
11145
10943
  )
11146
10944
  ] }) : null,
11147
- tab === "notes" ? /* @__PURE__ */ jsxs3("section", { className: "mx-meet__record-section", "aria-label": "Notes as it happened", children: [
11148
- /* @__PURE__ */ jsx5("h2", { className: "mx-meet__record-section-title", children: "Notes as it happened" }),
11149
- bundle.liveNotes.length === 0 ? /* @__PURE__ */ jsx5("p", { className: "mx-meet__panel-note", children: absenceSentence(
10945
+ tab === "notes" ? /* @__PURE__ */ jsxs4("section", { className: "mx-meet__record-section", "aria-label": "Notes as it happened", children: [
10946
+ /* @__PURE__ */ jsx6("h2", { className: "mx-meet__record-section-title", children: "Notes as it happened" }),
10947
+ bundle.liveNotes.length === 0 ? /* @__PURE__ */ jsx6("p", { className: "mx-meet__panel-note", children: absenceSentence(
11150
10948
  bundle,
11151
10949
  "notes",
11152
10950
  "No live notes are available for this meeting."
11153
- ) }) : /* @__PURE__ */ jsx5("ul", { className: "mx-meet__notes", children: bundle.liveNotes.map((note) => /* @__PURE__ */ jsxs3("li", { className: "mx-meet__note", children: [
11154
- note.window !== null ? /* @__PURE__ */ jsxs3("span", { className: "mx-meet__badge", children: [
10951
+ ) }) : /* @__PURE__ */ jsx6("ul", { className: "mx-meet__notes", children: bundle.liveNotes.map((note) => /* @__PURE__ */ jsxs4("li", { className: "mx-meet__note", children: [
10952
+ note.window !== null ? /* @__PURE__ */ jsxs4("span", { className: "mx-meet__badge", children: [
11155
10953
  "Window ",
11156
10954
  note.window
11157
10955
  ] }) : null,
11158
10956
  note.text
11159
10957
  ] }, note.id)) })
11160
10958
  ] }) : null,
11161
- tab === "transcript" ? /* @__PURE__ */ jsxs3("section", { className: "mx-meet__record-section", "aria-label": "Transcript", children: [
11162
- /* @__PURE__ */ jsxs3("h2", { className: "mx-meet__record-section-title", children: [
10959
+ tab === "transcript" ? /* @__PURE__ */ jsxs4("section", { className: "mx-meet__record-section", "aria-label": "Transcript", children: [
10960
+ /* @__PURE__ */ jsxs4("h2", { className: "mx-meet__record-section-title", children: [
11163
10961
  "Transcript",
11164
- /* @__PURE__ */ jsx5("span", { className: "mx-meet__record-count", children: bundle.transcript.length === 1 ? "1 line" : `${bundle.transcript.length} lines` })
10962
+ /* @__PURE__ */ jsx6("span", { className: "mx-meet__record-count", children: bundle.transcript.length === 1 ? "1 line" : `${bundle.transcript.length} lines` })
11165
10963
  ] }),
11166
- blocks.length === 0 ? /* @__PURE__ */ jsx5("p", { className: "mx-meet__panel-note", children: absenceSentence(
10964
+ blocks.length === 0 ? /* @__PURE__ */ jsx6("p", { className: "mx-meet__panel-note", children: absenceSentence(
11167
10965
  bundle,
11168
10966
  "transcript",
11169
10967
  "No transcript is available for this meeting."
11170
- ) }) : /* @__PURE__ */ jsx5("ol", { className: "mx-meet__record-transcript", children: blocks.map((block) => /* @__PURE__ */ jsxs3("li", { className: "mx-meet__record-block", children: [
11171
- /* @__PURE__ */ jsxs3("p", { className: "mx-meet__record-speaker", children: [
10968
+ ) }) : /* @__PURE__ */ jsx6("ol", { className: "mx-meet__record-transcript", children: blocks.map((block) => /* @__PURE__ */ jsxs4("li", { className: "mx-meet__record-block", children: [
10969
+ /* @__PURE__ */ jsxs4("p", { className: "mx-meet__record-speaker", children: [
11172
10970
  block.speaker,
11173
- /* @__PURE__ */ jsx5("time", { className: "mx-meet__record-time", dateTime: block.startedAt, children: clockOf(block.startedAt) })
10971
+ /* @__PURE__ */ jsx6("time", { className: "mx-meet__record-time", dateTime: block.startedAt, children: clockOf(block.startedAt) })
11174
10972
  ] }),
11175
- block.lines.map((line) => /* @__PURE__ */ jsx5("p", { className: "mx-meet__record-line", children: line.text }, line.id))
10973
+ block.lines.map((line) => /* @__PURE__ */ jsx6("p", { className: "mx-meet__record-line", children: line.text }, line.id))
11176
10974
  ] }, block.id)) })
11177
10975
  ] }) : null,
11178
- /* @__PURE__ */ jsx5(GuestRecordAccessControl, { meeting }),
11179
- /* @__PURE__ */ jsxs3("section", { className: "mx-meet__record-section", "aria-label": "Ask about this meeting", children: [
11180
- /* @__PURE__ */ jsx5("h2", { className: "mx-meet__record-section-title", children: "Ask about this meeting" }),
11181
- guestFinishedMeeting ? /* @__PURE__ */ jsx5("p", { className: "mx-meet__panel-note", children: "Sign in to ask the assistant about a meeting after it ends." }) : /* @__PURE__ */ jsxs3(Fragment, { children: [
11182
- /* @__PURE__ */ jsxs3(
10976
+ /* @__PURE__ */ jsx6(GuestRecordAccessControl, { meeting }),
10977
+ /* @__PURE__ */ jsxs4("section", { className: "mx-meet__record-section", "aria-label": "Ask about this meeting", children: [
10978
+ /* @__PURE__ */ jsx6("h2", { className: "mx-meet__record-section-title", children: "Ask about this meeting" }),
10979
+ guestFinishedMeeting ? /* @__PURE__ */ jsx6("p", { className: "mx-meet__panel-note", children: "Sign in to ask the assistant about a meeting after it ends." }) : /* @__PURE__ */ jsxs4(Fragment2, { children: [
10980
+ /* @__PURE__ */ jsxs4(
11183
10981
  "form",
11184
10982
  {
11185
10983
  className: "mx-meet__composer",
@@ -11190,7 +10988,7 @@ function MeetingRecordBody({
11190
10988
  void record.ask(trimmed);
11191
10989
  },
11192
10990
  children: [
11193
- /* @__PURE__ */ jsx5(
10991
+ /* @__PURE__ */ jsx6(
11194
10992
  "input",
11195
10993
  {
11196
10994
  className: "mx-meet__input",
@@ -11200,7 +10998,7 @@ function MeetingRecordBody({
11200
10998
  "aria-label": "Ask about this meeting"
11201
10999
  }
11202
11000
  ),
11203
- /* @__PURE__ */ jsx5(
11001
+ /* @__PURE__ */ jsx6(
11204
11002
  "button",
11205
11003
  {
11206
11004
  type: "submit",
@@ -11212,8 +11010,8 @@ function MeetingRecordBody({
11212
11010
  ]
11213
11011
  }
11214
11012
  ),
11215
- record.answer !== null ? /* @__PURE__ */ jsx5("p", { className: "mx-meet__answer", children: record.answer }) : null,
11216
- record.coverage !== null ? /* @__PURE__ */ jsxs3("p", { className: "mx-meet__coverage", children: [
11013
+ record.answer !== null ? /* @__PURE__ */ jsx6("p", { className: "mx-meet__answer", children: record.answer }) : null,
11014
+ record.coverage !== null ? /* @__PURE__ */ jsxs4("p", { className: "mx-meet__coverage", children: [
11217
11015
  "Answered from ",
11218
11016
  record.coverage.segmentsUsed,
11219
11017
  " of ",
@@ -11224,9 +11022,9 @@ function MeetingRecordBody({
11224
11022
  record.coverage.truncated ? " (the oldest were left out)" : "",
11225
11023
  "."
11226
11024
  ] }) : null,
11227
- record.askError !== null ? /* @__PURE__ */ jsxs3(ErrorBox, { as: "div", className: "mx-meet__refusal", error: record.askError, operation: "Ask about this meeting", origin: "meet/components", children: [
11228
- /* @__PURE__ */ jsx5("p", { className: "mx-meet__refusal-reason", children: record.askError.message }),
11229
- /* @__PURE__ */ jsx5("p", { className: "mx-meet__refusal-remedy", children: record.askError.remedy })
11025
+ record.askError !== null ? /* @__PURE__ */ jsxs4(ErrorBox2, { as: "div", className: "mx-meet__refusal", error: record.askError, operation: "Ask about this meeting", origin: "meet/components", children: [
11026
+ /* @__PURE__ */ jsx6("p", { className: "mx-meet__refusal-reason", children: record.askError.message }),
11027
+ /* @__PURE__ */ jsx6("p", { className: "mx-meet__refusal-remedy", children: record.askError.remedy })
11230
11028
  ] }) : null
11231
11029
  ] })
11232
11030
  ] })
@@ -11237,21 +11035,21 @@ var STREAM_REFUSED = "Streaming playback did not start, so this recording was do
11237
11035
  var PLAYBACK_RETRY_REMEDY = "Reload the page and try again. If it still will not play, ask a meeting host to check the recording.";
11238
11036
  function RecordingPlayer(props) {
11239
11037
  const host = useMeetHost();
11240
- if (host === null) return /* @__PURE__ */ jsx5(InertNotice, { what: "This recording" });
11241
- return /* @__PURE__ */ jsx5(RecordingPlayerBody, { ...props, host });
11038
+ if (host === null) return /* @__PURE__ */ jsx6(InertNotice, { what: "This recording" });
11039
+ return /* @__PURE__ */ jsx6(RecordingPlayerBody, { ...props, host });
11242
11040
  }
11243
11041
  function RecordingPlayerBody({ fileId, host }) {
11244
- const [media, setMedia] = useState4(null);
11245
- const [loading, setLoading] = useState4(false);
11246
- const [error, setError] = useState4(null);
11247
- useEffect5(() => {
11042
+ const [media, setMedia] = useState5(null);
11043
+ const [loading, setLoading] = useState5(false);
11044
+ const [error, setError] = useState5(null);
11045
+ useEffect7(() => {
11248
11046
  if (media === null || media.kind !== "bytes") return void 0;
11249
11047
  const url = media.url;
11250
11048
  return () => URL.revokeObjectURL(url);
11251
11049
  }, [media]);
11252
11050
  if (media !== null) {
11253
- return /* @__PURE__ */ jsxs3("div", { className: "mx-meet__record-section", children: [
11254
- /* @__PURE__ */ jsx5(
11051
+ return /* @__PURE__ */ jsxs4("div", { className: "mx-meet__record-section", children: [
11052
+ /* @__PURE__ */ jsx6(
11255
11053
  "video",
11256
11054
  {
11257
11055
  className: "mx-meet__record-player",
@@ -11293,15 +11091,15 @@ function RecordingPlayerBody({ fileId, host }) {
11293
11091
  }
11294
11092
  }
11295
11093
  ),
11296
- media.fallbackReason !== null ? /* @__PURE__ */ jsx5("p", { className: "mx-meet__panel-note", children: media.fallbackReason }) : null
11094
+ media.fallbackReason !== null ? /* @__PURE__ */ jsx6("p", { className: "mx-meet__panel-note", children: media.fallbackReason }) : null
11297
11095
  ] });
11298
11096
  }
11299
- return /* @__PURE__ */ jsxs3("div", { className: "mx-meet__record-section", children: [
11300
- error !== null ? /* @__PURE__ */ jsxs3(ErrorBox, { as: "div", className: "mx-meet__refusal", error, operation: "Complete this meeting action", origin: "meet/components", children: [
11301
- /* @__PURE__ */ jsx5("p", { className: "mx-meet__refusal-reason", children: error.message }),
11302
- /* @__PURE__ */ jsx5("p", { className: "mx-meet__refusal-remedy", children: error.remedy })
11097
+ return /* @__PURE__ */ jsxs4("div", { className: "mx-meet__record-section", children: [
11098
+ error !== null ? /* @__PURE__ */ jsxs4(ErrorBox2, { as: "div", className: "mx-meet__refusal", error, operation: "Complete this meeting action", origin: "meet/components", children: [
11099
+ /* @__PURE__ */ jsx6("p", { className: "mx-meet__refusal-reason", children: error.message }),
11100
+ /* @__PURE__ */ jsx6("p", { className: "mx-meet__refusal-remedy", children: error.remedy })
11303
11101
  ] }) : null,
11304
- /* @__PURE__ */ jsx5(
11102
+ /* @__PURE__ */ jsx6(
11305
11103
  "button",
11306
11104
  {
11307
11105
  type: "button",
@@ -11329,45 +11127,84 @@ function RecordingPlayerBody({ fileId, host }) {
11329
11127
  )
11330
11128
  ] });
11331
11129
  }
11332
- function clockOf(iso) {
11333
- const at = new Date(iso);
11334
- if (Number.isNaN(at.getTime())) return "";
11335
- return at.toLocaleTimeString(void 0, { hour: "numeric", minute: "2-digit" });
11336
- }
11337
- function MeetingList({ baseUrl }) {
11130
+
11131
+ // src/react/skin-root.tsx
11132
+ import { jsx as jsx7 } from "react/jsx-runtime";
11133
+ function MeetingSkinRoot(props) {
11338
11134
  const host = useMeetHost();
11339
- const list = useMeetings();
11340
- if (host === null) return /* @__PURE__ */ jsx5(InertNotice, { what: "Your meetings" });
11341
- if (list.failure !== null) {
11342
- return /* @__PURE__ */ jsxs3(ErrorBox, { as: "div", className: "mx-meet__empty", error: list.failure, operation: "List your meetings", origin: "meet/components", children: [
11343
- /* @__PURE__ */ jsx5("p", { className: "mx-meet__empty-title", children: "Your meetings could not be listed" }),
11344
- /* @__PURE__ */ jsx5("p", { className: "mx-meet__empty-body", children: list.failure.message }),
11345
- /* @__PURE__ */ jsx5("p", { className: "mx-meet__empty-body", children: list.failure.remedy })
11346
- ] });
11347
- }
11348
- if (list.loading) {
11349
- return /* @__PURE__ */ jsx5("div", { className: "mx-meet__empty", role: "status", children: /* @__PURE__ */ jsx5("p", { className: "mx-meet__empty-title", children: "Loading your meetings\u2026" }) });
11135
+ if (host === null) {
11136
+ return /* @__PURE__ */ jsx7(MeetRoot, { meeting: props.meeting, children: /* @__PURE__ */ jsx7("div", { className: "mx-meet", children: /* @__PURE__ */ jsx7(InertNotice, { what: "This meeting" }) }) });
11350
11137
  }
11351
- if (list.meetings.length === 0) {
11352
- return /* @__PURE__ */ jsxs3("div", { className: "mx-meet__empty", role: "status", children: [
11353
- /* @__PURE__ */ jsx5("p", { className: "mx-meet__empty-title", children: "No meetings yet" }),
11354
- /* @__PURE__ */ jsx5("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." })
11355
- ] });
11138
+ return /* @__PURE__ */ jsx7(MeetRoot, { meeting: props.meeting, children: /* @__PURE__ */ jsx7(MeetingSkinRootBody, { ...props, host }) });
11139
+ }
11140
+ function MeetingSkinRootBody({
11141
+ roomName,
11142
+ meetingId,
11143
+ slug,
11144
+ meeting: given,
11145
+ onLeave,
11146
+ headerControls,
11147
+ host
11148
+ }) {
11149
+ const snapshot = useMeetSnapshot();
11150
+ const phase = snapshot?.phase ?? "idle";
11151
+ useEffect8(() => {
11152
+ host.meetings.watch(roomName);
11153
+ }, [host, roomName]);
11154
+ useEffect8(() => {
11155
+ if (given === void 0) return;
11156
+ if (host.store.snapshot().meeting !== null) return;
11157
+ host.store.patch({ meeting: given, locked: given.locked });
11158
+ }, [host, given]);
11159
+ const watchedId = meetingId ?? snapshot?.meeting?.id ?? null;
11160
+ useEffect8(() => {
11161
+ if (watchedId === null) return;
11162
+ host.meetings.watchMeeting(asMeetingId(watchedId));
11163
+ }, [host, watchedId]);
11164
+ const record = snapshot?.meeting ?? given ?? null;
11165
+ if (hasEnded(record) && phase !== "connected" && phase !== "reconnecting") {
11166
+ return /* @__PURE__ */ jsx7(MeetingRecordView, { meeting: record });
11356
11167
  }
11357
- const origin = baseUrl ?? (typeof window === "undefined" ? "" : window.location.origin);
11358
- return /* @__PURE__ */ jsx5("ul", { className: "mx-meet-list", children: list.meetings.map((meeting) => {
11359
- const ended = meeting.endedAt !== null;
11360
- return /* @__PURE__ */ jsxs3("li", { className: "mx-meet-list__row", children: [
11361
- /* @__PURE__ */ jsxs3("div", { className: "mx-meet-list__main", children: [
11362
- /* @__PURE__ */ jsxs3("span", { className: "mx-meet-list__title", children: [
11363
- meeting.title,
11364
- ended ? /* @__PURE__ */ jsx5("span", { className: "mx-meet__badge", children: "Ended" }) : null
11365
- ] }),
11366
- /* @__PURE__ */ jsx5("span", { className: "mx-meet-list__when", children: meetingWhen(meeting) })
11367
- ] }),
11368
- /* @__PURE__ */ jsx5("a", { className: "mx-meet-list__action", href: meetingLink(origin, meeting.slug), children: ended ? "Open the record" : "Join" })
11369
- ] }, meeting.id);
11370
- }) });
11168
+ return /* @__PURE__ */ jsx7(
11169
+ MeetSkinRoom,
11170
+ {
11171
+ roomName,
11172
+ ...meetingId !== void 0 ? { meetingId } : {},
11173
+ ...slug !== void 0 ? { slug } : {},
11174
+ ...onLeave !== void 0 ? { onLeave } : {},
11175
+ ...headerControls !== void 0 ? { headerControls } : {}
11176
+ }
11177
+ );
11178
+ }
11179
+
11180
+ // src/react/calls-ui.tsx
11181
+ import { jsx as jsx8, jsxs as jsxs5 } from "react/jsx-runtime";
11182
+ function IncomingCallHost() {
11183
+ const calls = useCalls();
11184
+ if (calls.incoming.length === 0) return null;
11185
+ return /* @__PURE__ */ jsx8("div", { className: "mx-meet__ringing-stack", children: calls.incoming.map((invite) => /* @__PURE__ */ jsx8(IncomingCallCard, { invite }, invite.id)) });
11186
+ }
11187
+ function IncomingCallCard({ invite }) {
11188
+ const calls = useCalls();
11189
+ return /* @__PURE__ */ jsxs5("section", { className: "mx-meet__ringing", role: "alertdialog", "aria-label": "Incoming call", children: [
11190
+ /* @__PURE__ */ jsx8(Avatar, { name: invite.callerName, url: invite.callerAvatarUrl, size: 56 }),
11191
+ /* @__PURE__ */ jsxs5("div", { className: "mx-meet__ringing-text", children: [
11192
+ /* @__PURE__ */ jsx8("strong", { children: invite.callerName }),
11193
+ /* @__PURE__ */ jsx8("span", { children: invite.mode === "video" ? "Incoming video call" : "Incoming call" })
11194
+ ] }),
11195
+ /* @__PURE__ */ jsxs5("div", { className: "mx-meet__ringing-actions", children: [
11196
+ /* @__PURE__ */ jsx8(ControlButton, { label: "Decline", danger: true, onClick: () => void calls.decline(invite), children: /* @__PURE__ */ jsx8(PhoneOffIcon, {}) }),
11197
+ invite.mode === "video" ? /* @__PURE__ */ jsx8(
11198
+ ControlButton,
11199
+ {
11200
+ label: "Accept without video",
11201
+ onClick: () => void calls.accept({ ...invite, mode: "audio" }),
11202
+ children: /* @__PURE__ */ jsx8(CameraOffIcon, {})
11203
+ }
11204
+ ) : null,
11205
+ /* @__PURE__ */ jsx8(ControlButton, { label: "Accept", onClick: () => void calls.accept(invite), children: /* @__PURE__ */ jsx8(PhoneIcon, {}) })
11206
+ ] })
11207
+ ] });
11371
11208
  }
11372
11209
 
11373
11210
  // src/core/invitations.ts
@@ -11522,54 +11359,26 @@ async function pushMeetingToGoogleCalendar(api, meetingId, target) {
11522
11359
  }
11523
11360
  export {
11524
11361
  ATTENDANCE_CSV_HEADER,
11525
- ActivitiesControl,
11526
- ActivitiesIcon,
11527
- AiPanel,
11528
- AttendanceNotice,
11529
- Avatar,
11530
- BreakoutBanner,
11531
- BreakoutIcon,
11532
- BreakoutsPanel,
11533
11362
  CALL_INVITE_KIND,
11534
11363
  CALL_INVITE_VERSION,
11535
11364
  CAPTION_LANGUAGES,
11536
11365
  CONSENT_NOTICE_ATTRIBUTE,
11537
- CallButton,
11538
- CameraIcon,
11539
- CameraOffIcon,
11540
- CaptionLanguageSettings,
11541
- Captions,
11542
- ChatIcon,
11543
- ChatPanel,
11544
- CheckIcon,
11545
- CloseIcon,
11546
- ConnectionDot,
11547
- ConsentNotice,
11548
- ControlBar,
11549
- ControlButton,
11550
11366
  DATA_TOPICS,
11551
11367
  DEFAULT_EFFECTS,
11552
11368
  DEFAULT_PAGE_SIZE,
11553
11369
  EMPTY_COLLAB,
11554
11370
  END_MEETING_NOT_SERVED,
11555
11371
  FILE_SESSION_PATH,
11556
- FlagIcon,
11557
11372
  GUEST_RECORD_ACCESS_CHOICES,
11558
11373
  GUEST_RECORD_ACCESS_LEVELS,
11559
11374
  GUEST_RECORD_ACCESS_METADATA_KEY,
11560
11375
  GUEST_RECORD_NOT_SHARED,
11561
11376
  GuestRecordAccessControl,
11562
- HandIcon,
11563
- HostMenu,
11564
11377
  IDLE_MEDIA,
11565
11378
  IDLE_TRACK,
11566
11379
  IncomingCallCard,
11567
11380
  IncomingCallHost,
11568
- KeyboardIcon,
11569
11381
  LISTEN_ONLY_NOTICE,
11570
- LayoutIcon,
11571
- LobbyPanel,
11572
- LockIcon,
11573
11382
  MEETING_INVITE_KIND,
11574
11383
  MEETING_INVITE_VERSION,
11575
11384
  MEETING_RECORD_GRACE_MS,
@@ -11584,33 +11393,14 @@ export {
11584
11393
  MeetError,
11585
11394
  MeetProvider,
11586
11395
  MeetRoot,
11587
- MeetingList,
11588
- MeetingOverlays,
11589
11396
  MeetingRecordView,
11590
- MeetingRoom,
11591
- MicIcon,
11592
- MicOffIcon,
11593
- MoreIcon,
11397
+ MeetingSkinRoot,
11594
11398
  NOTE_TAKER_IDENTITY_PREFIX,
11595
11399
  NOTE_TAKER_METADATA_KEY,
11596
11400
  NO_GRANTS,
11597
11401
  ORGANIZATION_HEADER,
11598
11402
  PARTICIPANT_CAN_RECORD_ATTRIBUTE,
11599
11403
  PARTICIPANT_ROLE_ATTRIBUTE,
11600
- ParticipantTile,
11601
- PencilIcon,
11602
- PeopleIcon,
11603
- PeoplePanel,
11604
- PersonMenu,
11605
- PhoneIcon,
11606
- PhoneOffIcon,
11607
- PinIcon,
11608
- PollIcon,
11609
- PollsPanel,
11610
- PreJoin,
11611
- QaPanel,
11612
- QualityBars,
11613
- QuestionIcon,
11614
11404
  REACTION_TTL_MS,
11615
11405
  REFUSED_ABSENCE,
11616
11406
  ROLE_RANK,
@@ -11618,30 +11408,13 @@ export {
11618
11408
  ROOM_EVENT_PREFIX,
11619
11409
  ROOM_TOKEN_HEADER,
11620
11410
  RPCS,
11621
- ReactionOverlay,
11622
- RecordIcon,
11623
- RecordingIndicator,
11624
11411
  RecordingPlayer,
11625
- ScheduleMeeting,
11626
- ScreenShareIcon,
11627
- SearchIcon,
11628
- SettingsIcon,
11629
- SettingsPanel,
11630
- ShortcutsSheet,
11631
- SignalIcon,
11632
- SmileIcon,
11633
- SparklesIcon,
11634
- SpeakerIcon,
11635
- SpotlightIcon,
11636
- Stage,
11637
11412
  TABLES,
11638
11413
  TRANSCRIPTION_ATTRIBUTES,
11639
11414
  TRANSCRIPTION_TOPIC,
11640
- WhiteboardIcon,
11641
- WhiteboardPanel,
11642
- WifiLowIcon,
11643
11415
  absenceSentence,
11644
11416
  activeWrapUpSummary,
11417
+ activityAttention,
11645
11418
  announceMeeting,
11646
11419
  applyCollabPacket,
11647
11420
  applyRoomEvent,
@@ -11658,6 +11431,7 @@ export {
11658
11431
  attendanceTotals,
11659
11432
  attendeeKey,
11660
11433
  autoAssign,
11434
+ availableActivities,
11661
11435
  breakoutRemainingMs,
11662
11436
  callInviteAction,
11663
11437
  callInviteText,
@@ -11730,6 +11504,8 @@ export {
11730
11504
  mergeCaption,
11731
11505
  mergeRecord,
11732
11506
  microphoneNoticeCode,
11507
+ moveToRoom,
11508
+ nextTranslationBatch,
11733
11509
  normalizeDeviceError,
11734
11510
  normalizeMeetError,
11735
11511
  normalizeSpoken,
@@ -11746,6 +11522,7 @@ export {
11746
11522
  parseRoomToken,
11747
11523
  participantAttributes,
11748
11524
  participantSummary,
11525
+ performCollab,
11749
11526
  playableRecordingFileId,
11750
11527
  projectInvitee,
11751
11528
  projectLibraryRecording,
@@ -11768,15 +11545,20 @@ export {
11768
11545
  rootAttributes,
11769
11546
  searchTranscript,
11770
11547
  sendFollowUp,
11548
+ setCaptionLanguage,
11771
11549
  setGuestRecordAccess,
11772
11550
  settingsPatch,
11773
11551
  snapshotParticipant,
11774
11552
  snippetRuns,
11775
11553
  staticObservation,
11776
11554
  summarizeMeetingRecordRestrictions,
11555
+ takeMoveRequest,
11556
+ takePanelRequest,
11777
11557
  transcriptDocument,
11778
11558
  unavailableFrom,
11779
11559
  uniqueAttendees,
11560
+ untranslatedLines,
11561
+ useActivityAttention,
11780
11562
  useAudioLevel,
11781
11563
  useAvailableActivities,
11782
11564
  useCalls,
@@ -11801,6 +11583,7 @@ export {
11801
11583
  useLocalUserId,
11802
11584
  useMediaEffects,
11803
11585
  useMeetAi,
11586
+ useMeetCore,
11804
11587
  useMeetHost,
11805
11588
  useMeetShortcuts,
11806
11589
  useMeetSnapshot,