@ai-matrx/meet 0.7.79 → 0.7.81

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,32 @@ function normalizeDeviceError(error, operation) {
468
468
  );
469
469
  }
470
470
  }
471
+ function isScreenShareCancel(error) {
472
+ const named = (value) => typeof value?.name === "string" ? value.name : "";
473
+ const cause = error instanceof MeetError ? error.cause : void 0;
474
+ const names = [named(error), named(cause)];
475
+ if (names.some((name) => name === "NotAllowedError" || name === "AbortError")) return true;
476
+ return error instanceof MeetError && error.code === "permission-denied";
477
+ }
478
+ function normalizeScreenShareError(error, operation) {
479
+ if (error instanceof MeetError) return error;
480
+ const raw = error ?? {};
481
+ const message = typeof raw.message === "string" ? raw.message : String(error);
482
+ if (isScreenShareCancel(error)) {
483
+ return new MeetError(
484
+ "permission-denied",
485
+ `${operation}: screen sharing was cancelled`,
486
+ "Choose a screen, window or tab in the picker to share it.",
487
+ error
488
+ );
489
+ }
490
+ return new MeetError(
491
+ "media-unsupported",
492
+ `${operation}: screen sharing is not available (${message})`,
493
+ "This browser or device could not share a screen. You are still in the call; try a desktop browser to present.",
494
+ error
495
+ );
496
+ }
471
497
  function invalidResponse(operation, detail) {
472
498
  return new MeetError(
473
499
  "invalid-response",
@@ -1835,7 +1861,7 @@ function unavailableFrom(error) {
1835
1861
  }
1836
1862
  var LISTEN_ONLY_NOTICE = "You're attending without a microphone \u2014 others can't hear you";
1837
1863
  function isListenOnly(media) {
1838
- return !media.microphone.enabled;
1864
+ return !media.microphone.enabled && media.microphone.unavailable !== null;
1839
1865
  }
1840
1866
  function listenOnlyNotice(media) {
1841
1867
  return isListenOnly(media) ? LISTEN_ONLY_NOTICE : null;
@@ -4712,7 +4738,16 @@ function createRoomEngine(options) {
4712
4738
  try {
4713
4739
  await driver.setScreenShareEnabled(enabled);
4714
4740
  } catch (error) {
4715
- throw fail(error, "meet.setScreenShareEnabled");
4741
+ if (isScreenShareCancel(error)) return;
4742
+ const normalized = normalizeScreenShareError(error, "meet.setScreenShareEnabled");
4743
+ report("warn", normalized.message, normalized.remedy);
4744
+ store.patch({
4745
+ actionNotice: {
4746
+ text: `Screen sharing is not available. ${normalized.remedy}`,
4747
+ failed: true,
4748
+ at: now()
4749
+ }
4750
+ });
4716
4751
  }
4717
4752
  },
4718
4753
  async raiseHand(raised) {
@@ -4760,6 +4795,9 @@ function createRoomEngine(options) {
4760
4795
  supportsVideoEffects() {
4761
4796
  return driver?.supportsVideoEffects?.() ?? false;
4762
4797
  },
4798
+ supportsScreenShare() {
4799
+ return driver?.supportsScreenShare?.() ?? true;
4800
+ },
4763
4801
  async switchDevice(kind, deviceId2) {
4764
4802
  if (driver === null) return;
4765
4803
  await driver.switchDevice(kind, deviceId2);
@@ -5329,7 +5367,7 @@ function createLiveKitDriver(handlers, options = {}) {
5329
5367
  try {
5330
5368
  await requireRoom("setScreenShareEnabled").localParticipant.setScreenShareEnabled(enabled);
5331
5369
  } catch (error) {
5332
- throw normalizeDeviceError(error, "meet.setScreenShareEnabled");
5370
+ throw normalizeScreenShareError(error, "meet.setScreenShareEnabled");
5333
5371
  }
5334
5372
  },
5335
5373
  async publishData(topic, payload, to) {
@@ -5366,6 +5404,9 @@ function createLiveKitDriver(handlers, options = {}) {
5366
5404
  supportsVideoEffects() {
5367
5405
  return videoEffectsSupported();
5368
5406
  },
5407
+ supportsScreenShare() {
5408
+ return typeof navigator !== "undefined" && typeof navigator.mediaDevices?.getDisplayMedia === "function";
5409
+ },
5369
5410
  attach(identity, kind, element) {
5370
5411
  const target = requireRoom("attach");
5371
5412
  const source = sources?.[kind];
@@ -6475,6 +6516,7 @@ function useRoom() {
6475
6516
  participants: snapshot?.participants ?? [],
6476
6517
  failure: snapshot?.failure ?? null,
6477
6518
  local,
6519
+ canShareScreen: engine?.supportsScreenShare() ?? true,
6478
6520
  join: (0, import_react3.useCallback)(
6479
6521
  async (request) => requireEngine(engine, "join").join(request),
6480
6522
  [engine]
@@ -7275,6 +7317,7 @@ var import_design_system = require("@ai-matrx/design-system");
7275
7317
  var import_format4 = require("@ai-matrx/kit/format");
7276
7318
 
7277
7319
  // src/core/after.ts
7320
+ var import_delimited = require("@ai-matrx/kit/delimited");
7278
7321
  var import_format2 = require("@ai-matrx/kit/format");
7279
7322
  function kindOf(person) {
7280
7323
  if (person.isAgent) return "assistant";
@@ -7413,11 +7456,6 @@ function attendanceTotals(rows) {
7413
7456
  averageMs: timed.length === 0 ? null : Math.round(timed.reduce((sum, row) => sum + (row.durationMs ?? 0), 0) / timed.length)
7414
7457
  };
7415
7458
  }
7416
- function csvCell(value) {
7417
- if (value === null) return "";
7418
- const text3 = String(value);
7419
- return /[",\n\r]/.test(text3) ? `"${text3.replace(/"/g, '""')}"` : text3;
7420
- }
7421
7459
  var ATTENDANCE_CSV_HEADER = [
7422
7460
  "Meeting",
7423
7461
  "Meeting started",
@@ -7429,11 +7467,11 @@ var ATTENDANCE_CSV_HEADER = [
7429
7467
  "Admission"
7430
7468
  ];
7431
7469
  function attendanceCsv(reports) {
7432
- const lines = [ATTENDANCE_CSV_HEADER.join(",")];
7433
- for (const { meeting, rows } of reports) {
7434
- for (const row of rows) {
7435
- lines.push(
7436
- [
7470
+ return (0, import_delimited.toDelimited)(
7471
+ [
7472
+ ATTENDANCE_CSV_HEADER,
7473
+ ...reports.flatMap(
7474
+ ({ meeting, rows }) => rows.map((row) => [
7437
7475
  meeting.title,
7438
7476
  meeting.startedAt ?? meeting.scheduledFor,
7439
7477
  row.name,
@@ -7442,12 +7480,11 @@ function attendanceCsv(reports) {
7442
7480
  row.leftAt,
7443
7481
  row.durationMs === null ? null : Math.round(row.durationMs / 6e3) / 10,
7444
7482
  row.admission
7445
- ].map(csvCell).join(",")
7446
- );
7447
- }
7448
- }
7449
- return `${lines.join("\r\n")}\r
7450
- `;
7483
+ ])
7484
+ )
7485
+ ],
7486
+ { lineEnding: "\r\n", trailingNewline: true }
7487
+ );
7451
7488
  }
7452
7489
  function recordingOffsetMs(at, recording) {
7453
7490
  if (recording === null || recording.state !== "available") return null;
@@ -7779,11 +7816,7 @@ function PhoneIcon(props) {
7779
7816
  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" }) });
7780
7817
  }
7781
7818
  function PhoneOffIcon(props) {
7782
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(Icon, { ...props, children: [
7783
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "M2 2l20 20" }),
7784
- /* @__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" }),
7785
- /* @__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" })
7786
- ] });
7819
+ 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" }) });
7787
7820
  }
7788
7821
  function HandIcon(props) {
7789
7822
  return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(Icon, { ...props, children: [
@@ -9224,7 +9257,7 @@ function ControlBar({ onLeave }) {
9224
9257
  children: room.local?.cameraEnabled === true ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(CameraIcon, {}) : /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(CameraOffIcon, {})
9225
9258
  }
9226
9259
  ),
9227
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
9260
+ room.canShareScreen || room.local?.screenSharing === true ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
9228
9261
  ControlButton,
9229
9262
  {
9230
9263
  label: room.local?.screenSharing === true ? "Stop sharing" : "Share screen",
@@ -9232,7 +9265,7 @@ function ControlBar({ onLeave }) {
9232
9265
  onClick: () => void room.toggleScreenShare(),
9233
9266
  children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(ScreenShareIcon, {})
9234
9267
  }
9235
- ),
9268
+ ) : null,
9236
9269
  /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("span", { className: "mx-meet__anchor", children: [
9237
9270
  /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
9238
9271
  ControlButton,