@ai-matrx/meet 0.11.44 → 0.11.45

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.
@@ -115,6 +115,33 @@ var import_react10 = require("react");
115
115
  // src/react/facade.ts
116
116
  var import_react8 = require("react");
117
117
 
118
+ // src/core/phase.ts
119
+ var LIVE_PHASES = /* @__PURE__ */ new Set(["joining", "in_call"]);
120
+ var WAITING_PHASES = /* @__PURE__ */ new Set([
121
+ "waiting:host_not_started",
122
+ "waiting:knocking",
123
+ "denied",
124
+ "knock_expired"
125
+ ]);
126
+ var RETRYABLE_REFUSALS = /* @__PURE__ */ new Set([
127
+ "refused:locked",
128
+ "refused:too_early",
129
+ "refused:meeting_full",
130
+ "refused:platform_capacity"
131
+ ]);
132
+ function isLivePhase(phase) {
133
+ return LIVE_PHASES.has(phase);
134
+ }
135
+ function isWaitingPhase(phase) {
136
+ return WAITING_PHASES.has(phase);
137
+ }
138
+ function isRefusedPhase(phase) {
139
+ return phase.startsWith("refused:");
140
+ }
141
+ function reasonOf(phase) {
142
+ return isRefusedPhase(phase) ? phase.slice("refused:".length) : null;
143
+ }
144
+
118
145
  // src/core/names.ts
119
146
  var CONNECTION_SEPARATOR = "~";
120
147
  function personOf(identity) {
@@ -430,27 +457,6 @@ function isObserverRole(role) {
430
457
  return role === "viewer";
431
458
  }
432
459
 
433
- // src/core/phase.ts
434
- var LIVE_PHASES = /* @__PURE__ */ new Set(["joining", "in_call"]);
435
- var WAITING_PHASES = /* @__PURE__ */ new Set([
436
- "waiting:host_not_started",
437
- "waiting:knocking",
438
- "denied",
439
- "knock_expired"
440
- ]);
441
- function isLivePhase(phase) {
442
- return LIVE_PHASES.has(phase);
443
- }
444
- function isWaitingPhase(phase) {
445
- return WAITING_PHASES.has(phase);
446
- }
447
- function isRefusedPhase(phase) {
448
- return phase.startsWith("refused:");
449
- }
450
- function reasonOf(phase) {
451
- return isRefusedPhase(phase) ? phase.slice("refused:".length) : null;
452
- }
453
-
454
460
  // src/core/app-panel.ts
455
461
  function appPanelOf(meeting) {
456
462
  const raw = meeting?.metadata?.["app_panel"];
@@ -2095,6 +2101,10 @@ function actionsFor(host) {
2095
2101
  leave: () => engine.leave(),
2096
2102
  backToPrejoin: () => engine.backToPrejoin(),
2097
2103
  retry: () => {
2104
+ if (RETRYABLE_REFUSALS.has(store.snapshot().phase)) {
2105
+ void engine.rejoin().catch(() => void 0);
2106
+ return;
2107
+ }
2098
2108
  store.dispatch({ type: "retry", click: true });
2099
2109
  },
2100
2110
  resolved: () => {
@@ -3830,6 +3840,7 @@ function ControlBar({ onLeave }) {
3830
3840
  ]
3831
3841
  }
3832
3842
  ),
3843
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(WaitingRoomRule, {}),
3833
3844
  queue.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
3834
3845
  MenuItem,
3835
3846
  {
@@ -4049,6 +4060,58 @@ function MenuItem({
4049
4060
  }
4050
4061
  );
4051
4062
  }
4063
+ var LOBBY_BYPASS_CHOICES = [
4064
+ { value: "everyone", label: "Everyone" },
4065
+ { value: "org_and_invited", label: "Your organization and invited people" },
4066
+ { value: "org", label: "Your organization" },
4067
+ { value: "invited", label: "Invited people" },
4068
+ { value: "host_only", label: "Only hosts" }
4069
+ ];
4070
+ function WaitingRoomRule() {
4071
+ const host = useRequiredMeetHost();
4072
+ const [open, setOpen] = (0, import_react10.useState)(false);
4073
+ const [value, setValue] = (0, import_react10.useState)(null);
4074
+ const [notice, setNotice] = (0, import_react10.useState)(null);
4075
+ (0, import_react10.useEffect)(() => {
4076
+ let live = true;
4077
+ void host.meetings.meetingRule("lobby_bypass").then((rule) => {
4078
+ if (live) setValue(typeof rule === "string" ? rule : null);
4079
+ }).catch(() => void 0);
4080
+ return () => {
4081
+ live = false;
4082
+ };
4083
+ }, [host]);
4084
+ const current = LOBBY_BYPASS_CHOICES.find((choice) => choice.value === value)?.label ?? null;
4085
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
4086
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(MenuItem, { onSelect: () => setOpen(!open), children: [
4087
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(LockIcon, { width: 16, height: 16 }),
4088
+ " Who can skip the waiting room",
4089
+ current !== null ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "mx-meet__menu-value", children: current }) : null
4090
+ ] }),
4091
+ open ? /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { role: "group", "aria-label": "Who can skip the waiting room", "data-meet-rule": "lobby_bypass", children: [
4092
+ LOBBY_BYPASS_CHOICES.map((choice) => /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
4093
+ "button",
4094
+ {
4095
+ type: "button",
4096
+ role: "menuitemradio",
4097
+ "aria-checked": choice.value === value,
4098
+ className: "mx-meet__menu-item mx-meet__menu-item--sub",
4099
+ onClick: () => {
4100
+ setNotice(null);
4101
+ void host.meetings.setMeetingRule("lobby_bypass", choice.value).then(() => setValue(choice.value)).catch((error) => setNotice(error instanceof Error ? error.message : String(error)));
4102
+ },
4103
+ children: [
4104
+ choice.value === value ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(CheckIcon, { width: 14, height: 14 }) : null,
4105
+ " ",
4106
+ choice.label
4107
+ ]
4108
+ },
4109
+ choice.value
4110
+ )),
4111
+ notice !== null ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("p", { className: "mx-meet__menu-note", role: "status", children: notice }) : null
4112
+ ] }) : null
4113
+ ] });
4114
+ }
4052
4115
  function Toast({ text, failed, onDone }) {
4053
4116
  (0, import_react10.useEffect)(() => {
4054
4117
  const timer = setTimeout(onDone, failed ? 7e3 : 4e3);
@@ -5137,7 +5200,11 @@ function WaitingList({ lobby }) {
5137
5200
  /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Avatar, { name: entry.displayName, url: entry.avatarUrl, size: 32 }),
5138
5201
  /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("span", { className: "mx-meet__person-name", children: [
5139
5202
  entry.displayName,
5140
- entry.userId === null ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "mx-meet__badge", children: "Guest" }) : null
5203
+ entry.userId === null ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "mx-meet__badge", children: "Guest" }) : null,
5204
+ entry.flag === "previously_removed" ? (
5205
+ // `mod-removed-bypass`: advice for the host, never a block — Admit stays.
5206
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "mx-meet__badge mx-meet__badge--warn", "data-meet-notice": "knock-flagged", children: "Previously removed" })
5207
+ ) : null
5141
5208
  ] }),
5142
5209
  /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(ControlButton, { label: `Admit ${entry.displayName}`, onClick: () => void lobby.admit(entry), children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(CheckIcon, { width: 16, height: 16 }) }),
5143
5210
  /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
@@ -5762,7 +5829,20 @@ function ExitScreen({ onLeave }) {
5762
5829
  const { phase, reason, host, snapshot, actions, call, connection } = useMeetCore();
5763
5830
  const [busy, setBusy] = (0, import_react10.useState)(false);
5764
5831
  const failure = snapshot?.failure ?? null;
5765
- const retryLeft = useCountdown(phase === "refused:lobby_rejects" ? failure?.retryAt ?? null : null);
5832
+ const retryLeft = useCountdown(
5833
+ phase === "refused:lobby_rejects" || phase === "refused:too_early" ? failure?.retryAt ?? null : null
5834
+ );
5835
+ const reaskedAtZero = (0, import_react10.useRef)(false);
5836
+ (0, import_react10.useEffect)(() => {
5837
+ if (phase !== "refused:too_early") {
5838
+ reaskedAtZero.current = false;
5839
+ return;
5840
+ }
5841
+ if (retryLeft === 0 && !reaskedAtZero.current) {
5842
+ reaskedAtZero.current = true;
5843
+ actions.retry();
5844
+ }
5845
+ }, [phase, retryLeft, actions]);
5766
5846
  const rejoin = /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
5767
5847
  import_design_system.Button,
5768
5848
  {
@@ -5800,11 +5880,19 @@ function ExitScreen({ onLeave }) {
5800
5880
  if (phase.startsWith("refused:")) {
5801
5881
  const code = phase.slice("refused:".length);
5802
5882
  title = REFUSED_TITLES[code] ?? "You can't join this meeting";
5803
- line = code === "too_early" || code === "registration_required" || code === "cancelled" ? failure?.remedy ?? null : null;
5883
+ line = code === "too_early" || code === "registration_required" || code === "cancelled" || code === "wrong_account" ? failure?.remedy ?? null : null;
5884
+ if (code === "too_early" && retryLeft !== null && retryLeft > 0) line = `Opens in ${clockText(retryLeft)}`;
5804
5885
  actionsNode = /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
5805
5886
  /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_design_system.Button, { type: "button", variant: "outline", onClick: actions.retry, children: "Try again" }),
5806
5887
  home
5807
5888
  ] });
5889
+ if (code === "sign_in_required" || code === "wrong_account") {
5890
+ const back = typeof window === "undefined" ? "/" : `${window.location.pathname}${window.location.search}`;
5891
+ actionsNode = /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
5892
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_design_system.Button, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("a", { href: `/login?redirectTo=${encodeURIComponent(back)}`, children: code === "sign_in_required" ? "Sign in" : "Switch account" }) }),
5893
+ home
5894
+ ] });
5895
+ }
5808
5896
  if (code === "lobby_rejects") {
5809
5897
  if (retryLeft !== null && retryLeft > 0) {
5810
5898
  line = `You can ask again in ${clockText(retryLeft)}`;