@ai-matrx/meet 0.11.44 → 0.11.46

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.
@@ -1,6 +1,6 @@
1
- export { A as AiPanel, a as AttendanceNotice, b as Avatar, C as Captions, c as ChatPanel, d as ConnectionDot, e as ConsentNotice, f as ControlBar, g as ControlButton, H as HostMenu, L as LobbyPanel, M as MeetSkinRoom, h as MeetingOverlays, i as MenuItem, P as PanelShell, j as ParticipantTile, k as PeoplePanel, l as PersonMenu, m as Popover, n as PreJoin, Q as QualityBars, R as ReactionOverlay, o as RecordingIndicator, S as SettingsPanel, p as ShortcutsSheet, q as Stage, T as Toast } from '../components-BxK993iW.cjs';
1
+ export { A as AiPanel, a as AttendanceNotice, b as Avatar, C as Captions, c as ChatPanel, d as ConnectionDot, e as ConsentNotice, f as ControlBar, g as ControlButton, H as HostMenu, L as LobbyPanel, M as MeetSkinRoom, h as MeetingOverlays, i as MenuItem, P as PanelShell, j as ParticipantTile, k as PeoplePanel, l as PersonMenu, m as Popover, n as PreJoin, Q as QualityBars, R as ReactionOverlay, o as RecordingIndicator, S as SettingsPanel, p as ShortcutsSheet, q as Stage, T as Toast } from '../components-CkyDos0f.cjs';
2
2
  import { ReactNode, SVGProps } from 'react';
3
- import { C as CollabPanel } from '../collab-BNJNgXFB.cjs';
3
+ import { C as CollabPanel } from '../collab-D1TX5uf9.cjs';
4
4
 
5
5
  /**
6
6
  * POLLS, Q&A, THE SHARED WHITEBOARD AND BREAKOUT ROOMS — the in-room surfaces (Meet wave 5).
@@ -1,6 +1,6 @@
1
- export { A as AiPanel, a as AttendanceNotice, b as Avatar, C as Captions, c as ChatPanel, d as ConnectionDot, e as ConsentNotice, f as ControlBar, g as ControlButton, H as HostMenu, L as LobbyPanel, M as MeetSkinRoom, h as MeetingOverlays, i as MenuItem, P as PanelShell, j as ParticipantTile, k as PeoplePanel, l as PersonMenu, m as Popover, n as PreJoin, Q as QualityBars, R as ReactionOverlay, o as RecordingIndicator, S as SettingsPanel, p as ShortcutsSheet, q as Stage, T as Toast } from '../components-BDtGzHf4.js';
1
+ export { A as AiPanel, a as AttendanceNotice, b as Avatar, C as Captions, c as ChatPanel, d as ConnectionDot, e as ConsentNotice, f as ControlBar, g as ControlButton, H as HostMenu, L as LobbyPanel, M as MeetSkinRoom, h as MeetingOverlays, i as MenuItem, P as PanelShell, j as ParticipantTile, k as PeoplePanel, l as PersonMenu, m as Popover, n as PreJoin, Q as QualityBars, R as ReactionOverlay, o as RecordingIndicator, S as SettingsPanel, p as ShortcutsSheet, q as Stage, T as Toast } from '../components-CNwBgmYU.js';
2
2
  import { ReactNode, SVGProps } from 'react';
3
- import { C as CollabPanel } from '../collab-BNJNgXFB.js';
3
+ import { C as CollabPanel } from '../collab-D1TX5uf9.js';
4
4
 
5
5
  /**
6
6
  * POLLS, Q&A, THE SHARED WHITEBOARD AND BREAKOUT ROOMS — the in-room surfaces (Meet wave 5).
@@ -7,6 +7,33 @@ import { useEffect as useEffect6, useLayoutEffect, useRef as useRef6, useState a
7
7
  // src/react/facade.ts
8
8
  import { useMemo as useMemo5 } from "react";
9
9
 
10
+ // src/core/phase.ts
11
+ var LIVE_PHASES = /* @__PURE__ */ new Set(["joining", "in_call"]);
12
+ var WAITING_PHASES = /* @__PURE__ */ new Set([
13
+ "waiting:host_not_started",
14
+ "waiting:knocking",
15
+ "denied",
16
+ "knock_expired"
17
+ ]);
18
+ var RETRYABLE_REFUSALS = /* @__PURE__ */ new Set([
19
+ "refused:locked",
20
+ "refused:too_early",
21
+ "refused:meeting_full",
22
+ "refused:platform_capacity"
23
+ ]);
24
+ function isLivePhase(phase) {
25
+ return LIVE_PHASES.has(phase);
26
+ }
27
+ function isWaitingPhase(phase) {
28
+ return WAITING_PHASES.has(phase);
29
+ }
30
+ function isRefusedPhase(phase) {
31
+ return phase.startsWith("refused:");
32
+ }
33
+ function reasonOf(phase) {
34
+ return isRefusedPhase(phase) ? phase.slice("refused:".length) : null;
35
+ }
36
+
10
37
  // src/core/names.ts
11
38
  var CONNECTION_SEPARATOR = "~";
12
39
  function personOf(identity) {
@@ -158,10 +185,10 @@ var MEET_ROUTES = {
158
185
  recordingStop: "/api/v1/meet/recording/stop",
159
186
  noteTakerStart: "/api/v1/meet/agent/start",
160
187
  noteTakerStop: "/api/v1/meet/agent/stop",
161
- /** In-meeting Q&A. Streams NDJSON; body is `{meeting_id, question}` only. */
162
- intelligenceAsk: "/api/v1/meet/intelligence/ask",
163
188
  /** Anyone in the meeting (guests with the room pass included) asks for captions for themselves. */
164
189
  noteTakerCaptions: "/api/v1/meet/agent/captions",
190
+ /** In-meeting Q&A. Streams NDJSON; body is `{meeting_id, question}` only. */
191
+ intelligenceAsk: "/api/v1/meet/intelligence/ask",
165
192
  /** A host ends the meeting for everyone. Served by MRI-A6. */
166
193
  meetingEnd: "/api/v1/meet/end",
167
194
  /**
@@ -322,27 +349,6 @@ function isObserverRole(role) {
322
349
  return role === "viewer";
323
350
  }
324
351
 
325
- // src/core/phase.ts
326
- var LIVE_PHASES = /* @__PURE__ */ new Set(["joining", "in_call"]);
327
- var WAITING_PHASES = /* @__PURE__ */ new Set([
328
- "waiting:host_not_started",
329
- "waiting:knocking",
330
- "denied",
331
- "knock_expired"
332
- ]);
333
- function isLivePhase(phase) {
334
- return LIVE_PHASES.has(phase);
335
- }
336
- function isWaitingPhase(phase) {
337
- return WAITING_PHASES.has(phase);
338
- }
339
- function isRefusedPhase(phase) {
340
- return phase.startsWith("refused:");
341
- }
342
- function reasonOf(phase) {
343
- return isRefusedPhase(phase) ? phase.slice("refused:".length) : null;
344
- }
345
-
346
352
  // src/core/app-panel.ts
347
353
  function appPanelOf(meeting) {
348
354
  const raw = meeting?.metadata?.["app_panel"];
@@ -757,6 +763,7 @@ var STATES = [
757
763
  "ended"
758
764
  ];
759
765
  function readState(value) {
766
+ if (value === "dispatching") return "joining";
760
767
  return typeof value === "string" && STATES.includes(value) ? value : null;
761
768
  }
762
769
  function isNoteTaker(participant) {
@@ -1601,7 +1608,10 @@ function useEndMeeting() {
1601
1608
  function useConsentNotice() {
1602
1609
  const snapshot = useMeetSnapshot();
1603
1610
  const agent = noteTakerParticipant(snapshot?.participants ?? []);
1604
- if (agent === null) return null;
1611
+ if (agent === null) {
1612
+ const state = noteTakerStatus({ meeting: snapshot?.meeting ?? null, participants: [] }).state;
1613
+ return state === "joining" ? "AI notes started. The note-taker is joining this meeting." : null;
1614
+ }
1605
1615
  return `AI notes are on. ${agent.displayName} is in this meeting, transcribing what is said and writing notes everyone here can read.`;
1606
1616
  }
1607
1617
  function useMediaSupervisor() {
@@ -2000,6 +2010,10 @@ function actionsFor(host) {
2000
2010
  leave: () => engine.leave(),
2001
2011
  backToPrejoin: () => engine.backToPrejoin(),
2002
2012
  retry: () => {
2013
+ if (RETRYABLE_REFUSALS.has(store.snapshot().phase)) {
2014
+ void engine.rejoin().catch(() => void 0);
2015
+ return;
2016
+ }
2003
2017
  store.dispatch({ type: "retry", click: true });
2004
2018
  },
2005
2019
  resolved: () => {
@@ -3735,6 +3749,7 @@ function ControlBar({ onLeave }) {
3735
3749
  ]
3736
3750
  }
3737
3751
  ),
3752
+ /* @__PURE__ */ jsx6(WaitingRoomRule, {}),
3738
3753
  queue.length > 0 ? /* @__PURE__ */ jsxs4(
3739
3754
  MenuItem,
3740
3755
  {
@@ -3954,6 +3969,58 @@ function MenuItem({
3954
3969
  }
3955
3970
  );
3956
3971
  }
3972
+ var LOBBY_BYPASS_CHOICES = [
3973
+ { value: "everyone", label: "Everyone" },
3974
+ { value: "org_and_invited", label: "Your organization and invited people" },
3975
+ { value: "org", label: "Your organization" },
3976
+ { value: "invited", label: "Invited people" },
3977
+ { value: "host_only", label: "Only hosts" }
3978
+ ];
3979
+ function WaitingRoomRule() {
3980
+ const host = useRequiredMeetHost();
3981
+ const [open, setOpen] = useState5(false);
3982
+ const [value, setValue] = useState5(null);
3983
+ const [notice, setNotice] = useState5(null);
3984
+ useEffect6(() => {
3985
+ let live = true;
3986
+ void host.meetings.meetingRule("lobby_bypass").then((rule) => {
3987
+ if (live) setValue(typeof rule === "string" ? rule : null);
3988
+ }).catch(() => void 0);
3989
+ return () => {
3990
+ live = false;
3991
+ };
3992
+ }, [host]);
3993
+ const current = LOBBY_BYPASS_CHOICES.find((choice) => choice.value === value)?.label ?? null;
3994
+ return /* @__PURE__ */ jsxs4(Fragment, { children: [
3995
+ /* @__PURE__ */ jsxs4(MenuItem, { onSelect: () => setOpen(!open), children: [
3996
+ /* @__PURE__ */ jsx6(LockIcon, { width: 16, height: 16 }),
3997
+ " Who can skip the waiting room",
3998
+ current !== null ? /* @__PURE__ */ jsx6("span", { className: "mx-meet__menu-value", children: current }) : null
3999
+ ] }),
4000
+ open ? /* @__PURE__ */ jsxs4("div", { role: "group", "aria-label": "Who can skip the waiting room", "data-meet-rule": "lobby_bypass", children: [
4001
+ LOBBY_BYPASS_CHOICES.map((choice) => /* @__PURE__ */ jsxs4(
4002
+ "button",
4003
+ {
4004
+ type: "button",
4005
+ role: "menuitemradio",
4006
+ "aria-checked": choice.value === value,
4007
+ className: "mx-meet__menu-item mx-meet__menu-item--sub",
4008
+ onClick: () => {
4009
+ setNotice(null);
4010
+ void host.meetings.setMeetingRule("lobby_bypass", choice.value).then(() => setValue(choice.value)).catch((error) => setNotice(error instanceof Error ? error.message : String(error)));
4011
+ },
4012
+ children: [
4013
+ choice.value === value ? /* @__PURE__ */ jsx6(CheckIcon, { width: 14, height: 14 }) : null,
4014
+ " ",
4015
+ choice.label
4016
+ ]
4017
+ },
4018
+ choice.value
4019
+ )),
4020
+ notice !== null ? /* @__PURE__ */ jsx6("p", { className: "mx-meet__menu-note", role: "status", children: notice }) : null
4021
+ ] }) : null
4022
+ ] });
4023
+ }
3957
4024
  function Toast({ text, failed, onDone }) {
3958
4025
  useEffect6(() => {
3959
4026
  const timer = setTimeout(onDone, failed ? 7e3 : 4e3);
@@ -4267,6 +4334,17 @@ function ChatPanel({
4267
4334
  const snapshot = useMeetSnapshot();
4268
4335
  const room = useRoom();
4269
4336
  const live = useLivePolicy();
4337
+ const host = useMeetHost();
4338
+ const [rulesChecked, setRulesChecked] = useState5(false);
4339
+ useEffect6(() => {
4340
+ let alive = true;
4341
+ const done = () => alive && setRulesChecked(true);
4342
+ if (host === null) done();
4343
+ else void host.meetings.readLivePolicy().then(done, done);
4344
+ return () => {
4345
+ alive = false;
4346
+ };
4347
+ }, [host]);
4270
4348
  const [draft, setDraft] = useState5("");
4271
4349
  const [recipient, setRecipient] = useState5(to);
4272
4350
  const listRef = useRef6(null);
@@ -4291,7 +4369,7 @@ function ChatPanel({
4291
4369
  snapshot?.chatLoaded !== true && messages.length === 0 ? /* @__PURE__ */ jsx6("li", { className: "mx-meet__panel-note", children: "Reading earlier messages\u2026" }) : messages.length === 0 && snapshot?.chatHistoryError == null ? /* @__PURE__ */ jsx6("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,
4292
4370
  messages.map((message) => /* @__PURE__ */ jsx6(ChatLine, { message, local, people }, message.id))
4293
4371
  ] }),
4294
- !live.canChat ? /* @__PURE__ */ jsx6("p", { className: "mx-meet__panel-note", role: "status", "data-meet-notice": "chat-restricted", children: live.chatMode === "off" ? "Chat is turned off for this meeting." : "Chat is limited to the host and co-hosts in this meeting." }) : /* @__PURE__ */ jsxs4(
4372
+ !rulesChecked ? null : !live.canChat ? /* @__PURE__ */ jsx6("p", { className: "mx-meet__panel-note", role: "status", "data-meet-notice": "chat-restricted", children: live.chatMode === "off" ? "Chat is turned off for this meeting." : "Chat is limited to the host and co-hosts in this meeting." }) : /* @__PURE__ */ jsxs4(
4295
4373
  "form",
4296
4374
  {
4297
4375
  className: "mx-meet__composer mx-meet__composer--chat",
@@ -5042,7 +5120,11 @@ function WaitingList({ lobby }) {
5042
5120
  /* @__PURE__ */ jsx6(Avatar, { name: entry.displayName, url: entry.avatarUrl, size: 32 }),
5043
5121
  /* @__PURE__ */ jsxs4("span", { className: "mx-meet__person-name", children: [
5044
5122
  entry.displayName,
5045
- entry.userId === null ? /* @__PURE__ */ jsx6("span", { className: "mx-meet__badge", children: "Guest" }) : null
5123
+ entry.userId === null ? /* @__PURE__ */ jsx6("span", { className: "mx-meet__badge", children: "Guest" }) : null,
5124
+ entry.flag === "previously_removed" ? (
5125
+ // `mod-removed-bypass`: advice for the host, never a block — Admit stays.
5126
+ /* @__PURE__ */ jsx6("span", { className: "mx-meet__badge mx-meet__badge--warn", "data-meet-notice": "knock-flagged", children: "Previously removed" })
5127
+ ) : null
5046
5128
  ] }),
5047
5129
  /* @__PURE__ */ jsx6(ControlButton, { label: `Admit ${entry.displayName}`, onClick: () => void lobby.admit(entry), children: /* @__PURE__ */ jsx6(CheckIcon, { width: 16, height: 16 }) }),
5048
5130
  /* @__PURE__ */ jsx6(
@@ -5667,7 +5749,20 @@ function ExitScreen({ onLeave }) {
5667
5749
  const { phase, reason, host, snapshot, actions, call, connection } = useMeetCore();
5668
5750
  const [busy, setBusy] = useState5(false);
5669
5751
  const failure = snapshot?.failure ?? null;
5670
- const retryLeft = useCountdown(phase === "refused:lobby_rejects" ? failure?.retryAt ?? null : null);
5752
+ const retryLeft = useCountdown(
5753
+ phase === "refused:lobby_rejects" || phase === "refused:too_early" ? failure?.retryAt ?? null : null
5754
+ );
5755
+ const reaskedAtZero = useRef6(false);
5756
+ useEffect6(() => {
5757
+ if (phase !== "refused:too_early") {
5758
+ reaskedAtZero.current = false;
5759
+ return;
5760
+ }
5761
+ if (retryLeft === 0 && !reaskedAtZero.current) {
5762
+ reaskedAtZero.current = true;
5763
+ actions.retry();
5764
+ }
5765
+ }, [phase, retryLeft, actions]);
5671
5766
  const rejoin = /* @__PURE__ */ jsx6(
5672
5767
  Button,
5673
5768
  {
@@ -5705,11 +5800,19 @@ function ExitScreen({ onLeave }) {
5705
5800
  if (phase.startsWith("refused:")) {
5706
5801
  const code = phase.slice("refused:".length);
5707
5802
  title = REFUSED_TITLES[code] ?? "You can't join this meeting";
5708
- line = code === "too_early" || code === "registration_required" || code === "cancelled" ? failure?.remedy ?? null : null;
5803
+ line = code === "too_early" || code === "registration_required" || code === "cancelled" || code === "wrong_account" ? failure?.remedy ?? null : null;
5804
+ if (code === "too_early" && retryLeft !== null && retryLeft > 0) line = `Opens in ${clockText(retryLeft)}`;
5709
5805
  actionsNode = /* @__PURE__ */ jsxs4(Fragment, { children: [
5710
5806
  /* @__PURE__ */ jsx6(Button, { type: "button", variant: "outline", onClick: actions.retry, children: "Try again" }),
5711
5807
  home
5712
5808
  ] });
5809
+ if (code === "sign_in_required" || code === "wrong_account") {
5810
+ const back = typeof window === "undefined" ? "/" : `${window.location.pathname}${window.location.search}`;
5811
+ actionsNode = /* @__PURE__ */ jsxs4(Fragment, { children: [
5812
+ /* @__PURE__ */ jsx6(Button, { asChild: true, children: /* @__PURE__ */ jsx6("a", { href: `/login?redirectTo=${encodeURIComponent(back)}`, children: code === "sign_in_required" ? "Sign in" : "Switch account" }) }),
5813
+ home
5814
+ ] });
5815
+ }
5713
5816
  if (code === "lobby_rejects") {
5714
5817
  if (retryLeft !== null && retryLeft > 0) {
5715
5818
  line = `You can ask again in ${clockText(retryLeft)}`;