@ai-matrx/meet 0.7.80 → 0.7.82

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/react.cjs CHANGED
@@ -468,6 +468,55 @@ function normalizeDeviceError(error, operation) {
468
468
  );
469
469
  }
470
470
  }
471
+ var SYSTEM_BLOCK = /by system|permissions?[- ]policy|display-capture|disallowed|not allowed by the system/i;
472
+ function classifyScreenShareError(error) {
473
+ const read = (value, key) => {
474
+ const v = value?.[key];
475
+ return typeof v === "string" ? v : "";
476
+ };
477
+ const cause = error instanceof MeetError ? error.cause : void 0;
478
+ const denied = [error, cause].some((value) => {
479
+ const name = read(value, "name");
480
+ return name === "NotAllowedError" || name === "AbortError" || name === "SecurityError";
481
+ });
482
+ if (denied) {
483
+ const text3 = [read(error, "message"), read(cause, "message")].join(" ");
484
+ return SYSTEM_BLOCK.test(text3) || [error, cause].some((v) => read(v, "name") === "SecurityError") ? "blocked" : "ambiguous";
485
+ }
486
+ if (error instanceof MeetError && error.code === "permission-denied" && cause === void 0) {
487
+ return "ambiguous";
488
+ }
489
+ return "other";
490
+ }
491
+ var SCREEN_SHARE_BLOCKED_REMEDY = "Your browser or computer is blocking screen sharing. On a Mac, open System Settings > Privacy & Security > Screen Recording, turn it on for your browser, then restart the browser. On a work computer, ask your administrator. You are still in the call.";
492
+ function normalizeScreenShareError(error, operation) {
493
+ if (error instanceof MeetError) return error;
494
+ const raw = error ?? {};
495
+ const message = typeof raw.message === "string" ? raw.message : String(error);
496
+ const kind = classifyScreenShareError(error);
497
+ if (kind === "blocked") {
498
+ return new MeetError(
499
+ "permission-denied",
500
+ `${operation}: screen sharing is blocked (${message})`,
501
+ SCREEN_SHARE_BLOCKED_REMEDY,
502
+ error
503
+ );
504
+ }
505
+ if (kind === "ambiguous") {
506
+ return new MeetError(
507
+ "permission-denied",
508
+ `${operation}: screen sharing was cancelled or refused`,
509
+ "Choose a screen, window or tab in the picker to share it. If no picker appeared, " + SCREEN_SHARE_BLOCKED_REMEDY,
510
+ error
511
+ );
512
+ }
513
+ return new MeetError(
514
+ "media-unsupported",
515
+ `${operation}: screen sharing is not available (${message})`,
516
+ "This browser or device could not share a screen. You are still in the call; try a desktop browser to present.",
517
+ error
518
+ );
519
+ }
471
520
  function invalidResponse(operation, detail) {
472
521
  return new MeetError(
473
522
  "invalid-response",
@@ -1835,7 +1884,7 @@ function unavailableFrom(error) {
1835
1884
  }
1836
1885
  var LISTEN_ONLY_NOTICE = "You're attending without a microphone \u2014 others can't hear you";
1837
1886
  function isListenOnly(media) {
1838
- return !media.microphone.enabled;
1887
+ return !media.microphone.enabled && media.microphone.unavailable !== null;
1839
1888
  }
1840
1889
  function listenOnlyNotice(media) {
1841
1890
  return isListenOnly(media) ? LISTEN_ONLY_NOTICE : null;
@@ -4321,6 +4370,7 @@ function createRoomEngine(options) {
4321
4370
  function report(level, message, remedy) {
4322
4371
  options.onDiagnostic?.(remedy === void 0 ? { level, message } : { level, message, remedy });
4323
4372
  }
4373
+ let ambiguousShareDenials = 0;
4324
4374
  function fail(error, operation) {
4325
4375
  const normalized = normalizeMeetError(error, operation);
4326
4376
  store.patch({
@@ -4711,8 +4761,17 @@ function createRoomEngine(options) {
4711
4761
  if (driver === null) return;
4712
4762
  try {
4713
4763
  await driver.setScreenShareEnabled(enabled);
4764
+ ambiguousShareDenials = 0;
4714
4765
  } catch (error) {
4715
- throw fail(error, "meet.setScreenShareEnabled");
4766
+ const kind = classifyScreenShareError(error);
4767
+ if (kind === "ambiguous") {
4768
+ ambiguousShareDenials += 1;
4769
+ if (ambiguousShareDenials < 2) return;
4770
+ }
4771
+ const normalized = normalizeScreenShareError(error, "meet.setScreenShareEnabled");
4772
+ report("warn", normalized.message, normalized.remedy);
4773
+ const text3 = kind === "other" ? `Screen sharing is not available. ${normalized.remedy}` : `Screen sharing did not start. ${SCREEN_SHARE_BLOCKED_REMEDY}`;
4774
+ store.patch({ actionNotice: { text: text3, failed: true, at: now() } });
4716
4775
  }
4717
4776
  },
4718
4777
  async raiseHand(raised) {
@@ -4760,6 +4819,9 @@ function createRoomEngine(options) {
4760
4819
  supportsVideoEffects() {
4761
4820
  return driver?.supportsVideoEffects?.() ?? false;
4762
4821
  },
4822
+ supportsScreenShare() {
4823
+ return driver?.supportsScreenShare?.() ?? true;
4824
+ },
4763
4825
  async switchDevice(kind, deviceId2) {
4764
4826
  if (driver === null) return;
4765
4827
  await driver.switchDevice(kind, deviceId2);
@@ -5329,7 +5391,7 @@ function createLiveKitDriver(handlers, options = {}) {
5329
5391
  try {
5330
5392
  await requireRoom("setScreenShareEnabled").localParticipant.setScreenShareEnabled(enabled);
5331
5393
  } catch (error) {
5332
- throw normalizeDeviceError(error, "meet.setScreenShareEnabled");
5394
+ throw normalizeScreenShareError(error, "meet.setScreenShareEnabled");
5333
5395
  }
5334
5396
  },
5335
5397
  async publishData(topic, payload, to) {
@@ -5366,6 +5428,9 @@ function createLiveKitDriver(handlers, options = {}) {
5366
5428
  supportsVideoEffects() {
5367
5429
  return videoEffectsSupported();
5368
5430
  },
5431
+ supportsScreenShare() {
5432
+ return typeof navigator !== "undefined" && typeof navigator.mediaDevices?.getDisplayMedia === "function";
5433
+ },
5369
5434
  attach(identity, kind, element) {
5370
5435
  const target = requireRoom("attach");
5371
5436
  const source = sources?.[kind];
@@ -6475,6 +6540,7 @@ function useRoom() {
6475
6540
  participants: snapshot?.participants ?? [],
6476
6541
  failure: snapshot?.failure ?? null,
6477
6542
  local,
6543
+ canShareScreen: engine?.supportsScreenShare() ?? true,
6478
6544
  join: (0, import_react3.useCallback)(
6479
6545
  async (request) => requireEngine(engine, "join").join(request),
6480
6546
  [engine]
@@ -7774,11 +7840,7 @@ function PhoneIcon(props) {
7774
7840
  return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Icon, { ...props, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "M22 16.92v3a2 2 0 0 1-2.18 2 19.79 19.79 0 0 1-8.63-3.07 19.5 19.5 0 0 1-6-6A19.79 19.79 0 0 1 2.12 4.18 2 2 0 0 1 4.11 2h3a2 2 0 0 1 2 1.72c.13.96.36 1.9.7 2.81a2 2 0 0 1-.45 2.11L8.09 9.91a16 16 0 0 0 6 6l1.27-1.27a2 2 0 0 1 2.11-.45c.9.34 1.85.57 2.81.7A2 2 0 0 1 22 16.92Z" }) });
7775
7841
  }
7776
7842
  function PhoneOffIcon(props) {
7777
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(Icon, { ...props, children: [
7778
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "M2 2l20 20" }),
7779
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "M10.68 13.31a16 16 0 0 0 3.41 2.6l1.27-1.27a2 2 0 0 1 2.11-.45c.9.34 1.85.57 2.81.7A2 2 0 0 1 22 16.92v3a2 2 0 0 1-2.18 2 19.79 19.79 0 0 1-8.63-3.07 19.42 19.42 0 0 1-3.33-2.67" }),
7780
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "M5.53 5.53A19.79 19.79 0 0 1 2.12 4.18 2 2 0 0 1 4.11 2h3a2 2 0 0 1 2 1.72c.13.96.36 1.9.7 2.81a2 2 0 0 1-.45 2.11L8.09 9.91" })
7781
- ] });
7843
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Icon, { fill: "currentColor", stroke: "none", ...props, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "M12 9c-1.6 0-3.15.25-4.6.72v3.1c0 .39-.23.74-.56.9-.98.49-1.87 1.12-2.66 1.85-.18.18-.43.28-.7.28-.28 0-.53-.11-.71-.29L.29 13.08a.99.99 0 0 1-.29-.7c0-.28.11-.53.29-.71C3.34 8.78 7.46 7 12 7s8.66 1.78 11.71 4.67c.18.18.29.43.29.71 0 .28-.11.53-.29.71l-2.48 2.48c-.18.18-.43.29-.71.29-.27 0-.52-.11-.7-.28a11.27 11.27 0 0 0-2.67-1.85.996.996 0 0 1-.56-.9v-3.1C15.15 9.25 13.6 9 12 9Z" }) });
7782
7844
  }
7783
7845
  function HandIcon(props) {
7784
7846
  return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(Icon, { ...props, children: [
@@ -9219,7 +9281,7 @@ function ControlBar({ onLeave }) {
9219
9281
  children: room.local?.cameraEnabled === true ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(CameraIcon, {}) : /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(CameraOffIcon, {})
9220
9282
  }
9221
9283
  ),
9222
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
9284
+ room.canShareScreen || room.local?.screenSharing === true ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
9223
9285
  ControlButton,
9224
9286
  {
9225
9287
  label: room.local?.screenSharing === true ? "Stop sharing" : "Share screen",
@@ -9227,7 +9289,7 @@ function ControlBar({ onLeave }) {
9227
9289
  onClick: () => void room.toggleScreenShare(),
9228
9290
  children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(ScreenShareIcon, {})
9229
9291
  }
9230
- ),
9292
+ ) : null,
9231
9293
  /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("span", { className: "mx-meet__anchor", children: [
9232
9294
  /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
9233
9295
  ControlButton,