@ai-matrx/meet 0.11.47 → 0.11.48
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/CHANGELOG.md +6 -0
- package/dist/{collab-D1TX5uf9.d.cts → collab-Dk3r37MW.d.cts} +5 -0
- package/dist/{collab-D1TX5uf9.d.ts → collab-Dk3r37MW.d.ts} +5 -0
- package/dist/{components-CNwBgmYU.d.ts → components-BWqIoc_V.d.ts} +1 -1
- package/dist/{components-CkyDos0f.d.cts → components-fpQrqtcs.d.cts} +1 -1
- package/dist/core.cjs +367 -11
- package/dist/core.cjs.map +1 -1
- package/dist/core.d.cts +79 -5
- package/dist/core.d.ts +79 -5
- package/dist/core.js +367 -11
- package/dist/core.js.map +1 -1
- package/dist/index.cjs +367 -11
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +367 -11
- package/dist/index.js.map +1 -1
- package/dist/react.cjs +481 -25
- package/dist/react.cjs.map +1 -1
- package/dist/react.d.cts +11 -4
- package/dist/react.d.ts +11 -4
- package/dist/react.js +481 -25
- package/dist/react.js.map +1 -1
- package/dist/skins/meet.cjs +125 -16
- package/dist/skins/meet.cjs.map +1 -1
- package/dist/skins/meet.d.cts +2 -2
- package/dist/skins/meet.d.ts +2 -2
- package/dist/skins/meet.js +125 -16
- package/dist/skins/meet.js.map +1 -1
- package/package.json +2 -2
package/dist/skins/meet.cjs
CHANGED
|
@@ -394,17 +394,34 @@ function recordingLabel(state) {
|
|
|
394
394
|
|
|
395
395
|
// src/core/live-policy.ts
|
|
396
396
|
var DEFAULT_LIVE_POLICY = {
|
|
397
|
+
headlessPowers: "members_admit",
|
|
397
398
|
chatMode: "everyone",
|
|
398
399
|
avLock: "off",
|
|
399
400
|
timeLimitMinutes: 0,
|
|
400
401
|
timeLimitWarningMinutes: 5,
|
|
401
|
-
recordingConsent: "notice"
|
|
402
|
+
recordingConsent: "notice",
|
|
403
|
+
shareWhoCan: "everyone",
|
|
404
|
+
shareConcurrency: "one_takeover"
|
|
402
405
|
};
|
|
403
406
|
var MODERATORS = /* @__PURE__ */ new Set(["host", "cohost"]);
|
|
404
407
|
function isLockedFor(policy, role, kind) {
|
|
405
408
|
if (MODERATORS.has(role)) return false;
|
|
406
409
|
return policy.avLock === "both" || (kind === "microphone" ? policy.avLock === "mic" : policy.avLock === "camera");
|
|
407
410
|
}
|
|
411
|
+
function canShareUnder(policy, role, standing) {
|
|
412
|
+
if (role === "viewer") return false;
|
|
413
|
+
if (MODERATORS.has(role)) return true;
|
|
414
|
+
switch (policy.shareWhoCan) {
|
|
415
|
+
case "host_only":
|
|
416
|
+
return false;
|
|
417
|
+
case "presenters":
|
|
418
|
+
return role === "presenter";
|
|
419
|
+
case "org":
|
|
420
|
+
return role === "presenter" || standing === "member";
|
|
421
|
+
default:
|
|
422
|
+
return true;
|
|
423
|
+
}
|
|
424
|
+
}
|
|
408
425
|
function consentPending(policy, role, recordingOn, given) {
|
|
409
426
|
return recordingOn && !given && policy.recordingConsent !== "notice" && !MODERATORS.has(role);
|
|
410
427
|
}
|
|
@@ -416,6 +433,12 @@ function minutesLeft(policy, startedAtMs, nowMs) {
|
|
|
416
433
|
if (policy.timeLimitMinutes <= 0 || startedAtMs === null) return null;
|
|
417
434
|
return Math.ceil((startedAtMs + policy.timeLimitMinutes * 6e4 - nowMs) / 6e4);
|
|
418
435
|
}
|
|
436
|
+
function mayAdmitNow(role, participants, policy) {
|
|
437
|
+
if (role === "none") return false;
|
|
438
|
+
if (role === "host" || role === "cohost") return true;
|
|
439
|
+
const hostIn = participants.some((p) => p.role === "host" || p.role === "cohost");
|
|
440
|
+
return !hostIn && policy.headlessPowers === "members_admit";
|
|
441
|
+
}
|
|
419
442
|
|
|
420
443
|
// src/core/attendance.ts
|
|
421
444
|
var IDLE_PREVIEW = { state: "idle", unavailable: null };
|
|
@@ -753,7 +776,7 @@ function observe(input) {
|
|
|
753
776
|
const phase = observedPhase(input);
|
|
754
777
|
const inCall = phase === "in_call";
|
|
755
778
|
const actual = inCall && snapshot !== null ? effectiveRole(snapshot) : "none";
|
|
756
|
-
const canAdmit =
|
|
779
|
+
const canAdmit = snapshot !== null && mayAdmitNow(actual, snapshot.participants, snapshot.livePolicy);
|
|
757
780
|
const role = actual === "none" || snapshot === null ? "none" : observedRole(actual, effectiveStanding(snapshot));
|
|
758
781
|
const deviceInPlay = phase === "joining" || inCall;
|
|
759
782
|
const region = snapshot?.mediaRegion;
|
|
@@ -1284,6 +1307,13 @@ function requireSession(session, action) {
|
|
|
1284
1307
|
if (session === null) throw noRuntime(action);
|
|
1285
1308
|
return session;
|
|
1286
1309
|
}
|
|
1310
|
+
function otherPresenterOf(snapshot) {
|
|
1311
|
+
if (snapshot === null || snapshot.presenter === null || snapshot.presenter === snapshot.localIdentity) return null;
|
|
1312
|
+
const rule = snapshot.livePolicy.shareConcurrency;
|
|
1313
|
+
if (rule === "multiple") return null;
|
|
1314
|
+
const who = snapshot.participants.find((p) => p.identity === snapshot.presenter);
|
|
1315
|
+
return who === void 0 ? null : { name: who.displayName, rule };
|
|
1316
|
+
}
|
|
1287
1317
|
function useRoom() {
|
|
1288
1318
|
const host = useMeetHost();
|
|
1289
1319
|
const snapshot = useMeetSnapshot();
|
|
@@ -1298,7 +1328,9 @@ function useRoom() {
|
|
|
1298
1328
|
secondDevice: snapshot?.secondDevice ?? null,
|
|
1299
1329
|
local,
|
|
1300
1330
|
// An observer (role `viewer`) publishes nothing: no Share screen to press and be refused (MD-16).
|
|
1301
|
-
|
|
1331
|
+
sharingAllowed: snapshot === null || canShareUnder(snapshot.livePolicy, effectiveRole(snapshot), effectiveStanding(snapshot)),
|
|
1332
|
+
canShareScreen: (engine?.supportsScreenShare() ?? true) && !isObserverRole(snapshot?.grants.role ?? null) && (snapshot === null || canShareUnder(snapshot.livePolicy, effectiveRole(snapshot), effectiveStanding(snapshot))),
|
|
1333
|
+
otherPresenter: otherPresenterOf(snapshot),
|
|
1302
1334
|
join: (0, import_react5.useCallback)(
|
|
1303
1335
|
async (request) => requireEngine(engine, "join").join(request),
|
|
1304
1336
|
[engine]
|
|
@@ -1396,7 +1428,7 @@ function useLobby() {
|
|
|
1396
1428
|
declined: (snapshot?.lobby ?? []).filter((entry) => entry.state === "denied"),
|
|
1397
1429
|
// No runtime means no host powers — `<LobbyPanel>` renders nothing rather
|
|
1398
1430
|
// than an admit button that would throw.
|
|
1399
|
-
canAdmit: session !== null && isHost,
|
|
1431
|
+
canAdmit: session !== null && (isHost || snapshot !== null && snapshot.phase === "in_call" && mayAdmitNow(snapshot.participants.find((p) => p.identity === snapshot.localIdentity)?.role ?? "none", snapshot.participants, snapshot.livePolicy)),
|
|
1400
1432
|
admit: (0, import_react5.useCallback)(
|
|
1401
1433
|
async (entry) => requireSession(session, "admit").admit(entry, true),
|
|
1402
1434
|
[session]
|
|
@@ -3510,7 +3542,8 @@ function ParticipantTile({
|
|
|
3510
3542
|
participant.isLocal ? " (you)" : "",
|
|
3511
3543
|
participant.isAgent ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "mx-meet__badge", children: "AI" }) : null,
|
|
3512
3544
|
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(RoleBadge, { role: participant.role, standing: participant.standing }),
|
|
3513
|
-
participant.reconnecting === true ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "mx-meet__badge", children: "Reconnecting\u2026" }) : null
|
|
3545
|
+
participant.reconnecting === true ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "mx-meet__badge", children: "Reconnecting\u2026" }) : null,
|
|
3546
|
+
participant.reconnecting !== true && participant.videoPaused === true && !participant.isLocal ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "mx-meet__badge", "data-meet-video-paused": "", children: "Video paused to save audio" }) : null
|
|
3514
3547
|
] }),
|
|
3515
3548
|
!participant.micEnabled ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(MicOffIcon, { width: 14, height: 14 }) : null,
|
|
3516
3549
|
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(QualityBars, { quality: participant.quality })
|
|
@@ -3600,6 +3633,8 @@ function ControlBar({ onLeave }) {
|
|
|
3600
3633
|
const queue = useHandQueue();
|
|
3601
3634
|
const micUnavailable = useLocalMedia().microphone.unavailable;
|
|
3602
3635
|
const live = useLivePolicy();
|
|
3636
|
+
const core = useMeetCore();
|
|
3637
|
+
const [askPresentInstead, setAskPresentInstead] = (0, import_react10.useState)(false);
|
|
3603
3638
|
const unread = useUnreadChat(panel === "chat");
|
|
3604
3639
|
const [whiteboard, setWhiteboard] = (0, import_react10.useState)(false);
|
|
3605
3640
|
const app = useMeetAppPanel();
|
|
@@ -3688,15 +3723,39 @@ function ControlBar({ onLeave }) {
|
|
|
3688
3723
|
}
|
|
3689
3724
|
),
|
|
3690
3725
|
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(CaptionsControl, {}),
|
|
3691
|
-
room.canShareScreen || room.local?.screenSharing === true ? /* @__PURE__ */ (0, import_jsx_runtime6.
|
|
3692
|
-
|
|
3693
|
-
|
|
3694
|
-
|
|
3695
|
-
|
|
3696
|
-
|
|
3697
|
-
|
|
3698
|
-
|
|
3699
|
-
|
|
3726
|
+
room.canShareScreen || room.local?.screenSharing === true && core.share.state !== "ended" ? /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("span", { className: "mx-meet__anchor", children: [
|
|
3727
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
3728
|
+
ControlButton,
|
|
3729
|
+
{
|
|
3730
|
+
label: room.local?.screenSharing === true ? "Stop sharing" : "Share screen",
|
|
3731
|
+
active: room.local?.screenSharing === true,
|
|
3732
|
+
onClick: () => {
|
|
3733
|
+
if (room.local?.screenSharing !== true && room.otherPresenter !== null) setAskPresentInstead(true);
|
|
3734
|
+
else void room.toggleScreenShare();
|
|
3735
|
+
},
|
|
3736
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(ScreenShareIcon, {})
|
|
3737
|
+
}
|
|
3738
|
+
),
|
|
3739
|
+
askPresentInstead && room.otherPresenter !== null ? /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "mx-meet__confirm", role: "group", "aria-label": "Someone else is presenting", "data-meet-notice": "share-takeover", children: [
|
|
3740
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("span", { className: "mx-meet__confirm-text", children: [
|
|
3741
|
+
room.otherPresenter.name,
|
|
3742
|
+
" is presenting"
|
|
3743
|
+
] }),
|
|
3744
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
3745
|
+
"button",
|
|
3746
|
+
{
|
|
3747
|
+
type: "button",
|
|
3748
|
+
className: "mx-meet__primary mx-meet__primary--small",
|
|
3749
|
+
onClick: () => {
|
|
3750
|
+
setAskPresentInstead(false);
|
|
3751
|
+
void room.toggleScreenShare();
|
|
3752
|
+
},
|
|
3753
|
+
children: room.otherPresenter.rule === "one_takeover" ? "Present instead" : "Share anyway"
|
|
3754
|
+
}
|
|
3755
|
+
),
|
|
3756
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("button", { type: "button", className: "mx-meet__link", onClick: () => setAskPresentInstead(false), children: "Cancel" })
|
|
3757
|
+
] }) : null
|
|
3758
|
+
] }) : null,
|
|
3700
3759
|
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("span", { className: "mx-meet__anchor", children: [
|
|
3701
3760
|
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
3702
3761
|
ControlButton,
|
|
@@ -3793,7 +3852,7 @@ function ControlBar({ onLeave }) {
|
|
|
3793
3852
|
]
|
|
3794
3853
|
}
|
|
3795
3854
|
),
|
|
3796
|
-
!room.canShareScreen && room.local?.screenSharing !== true ? (
|
|
3855
|
+
!room.canShareScreen && room.sharingAllowed && room.local?.screenSharing !== true ? (
|
|
3797
3856
|
// `share-unsupported-mobile`: the control is absent; the menu says where it lives.
|
|
3798
3857
|
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("p", { className: "mx-meet__menu-note", role: "note", "data-meet-notice": "share-unsupported", children: [
|
|
3799
3858
|
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(ScreenShareIcon, { width: 16, height: 16 }),
|
|
@@ -5798,13 +5857,53 @@ function MeetSkinRoom({
|
|
|
5798
5857
|
] }),
|
|
5799
5858
|
core.connectionBanner && core.connection !== "stable" ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("p", { className: "mx-meet__banner", role: "status", "data-meet-notice": `connection-${core.connection}`, children: CONNECTION_BANNER[core.connection] }) : null,
|
|
5800
5859
|
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(ShareNotice, {}),
|
|
5860
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(NetworkNotice, {}),
|
|
5801
5861
|
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Stage, {}),
|
|
5802
5862
|
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Captions, {}),
|
|
5803
5863
|
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(ControlBar, { ...onLeave !== void 0 ? { onLeave } : {} })
|
|
5804
5864
|
] });
|
|
5805
5865
|
}
|
|
5866
|
+
var RESTRICTED_NOTICE_MS = 3e4;
|
|
5867
|
+
function NetworkNotice() {
|
|
5868
|
+
const { snapshot, connectionBanner } = useMeetCore();
|
|
5869
|
+
const room = useRoom();
|
|
5870
|
+
const network = snapshot?.localNetwork;
|
|
5871
|
+
const [closed, setClosed] = (0, import_react10.useState)(() => /* @__PURE__ */ new Set());
|
|
5872
|
+
const [restrictedSince, setRestrictedSince] = (0, import_react10.useState)(null);
|
|
5873
|
+
const [, setTick] = (0, import_react10.useState)(0);
|
|
5874
|
+
const restricted = network?.path === "restricted";
|
|
5875
|
+
(0, import_react10.useEffect)(() => {
|
|
5876
|
+
if (!restricted || restrictedSince !== null) return;
|
|
5877
|
+
setRestrictedSince(Date.now());
|
|
5878
|
+
const timer = setTimeout(() => setTick((n) => n + 1), RESTRICTED_NOTICE_MS + 50);
|
|
5879
|
+
return () => clearTimeout(timer);
|
|
5880
|
+
}, [restricted, restrictedSince]);
|
|
5881
|
+
if (network === void 0 || snapshot?.phase !== "in_call" || connectionBanner) return null;
|
|
5882
|
+
const close = (code) => () => setClosed((prev) => /* @__PURE__ */ new Set([...prev, code]));
|
|
5883
|
+
const cameraOn = room.local?.cameraEnabled === true;
|
|
5884
|
+
if (network.videoPaused && !cameraOn) {
|
|
5885
|
+
return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("p", { className: "mx-meet__banner", role: "status", "data-meet-notice": "video-paused", children: [
|
|
5886
|
+
"Your video is paused to save your audio",
|
|
5887
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("button", { type: "button", className: "mx-meet__link", onClick: () => void room.toggleCamera(), children: "Try video again" })
|
|
5888
|
+
] });
|
|
5889
|
+
}
|
|
5890
|
+
if (network.quality === "poor" && !closed.has("connection-poor")) {
|
|
5891
|
+
return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("p", { className: "mx-meet__banner", role: "status", "data-meet-notice": "connection-poor", children: [
|
|
5892
|
+
"Your connection is unstable",
|
|
5893
|
+
cameraOn ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("button", { type: "button", className: "mx-meet__link", onClick: () => void room.toggleCamera(), children: "Turn off camera" }) : null,
|
|
5894
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("button", { type: "button", className: "mx-meet__link", onClick: close("connection-poor"), children: "Dismiss" })
|
|
5895
|
+
] });
|
|
5896
|
+
}
|
|
5897
|
+
if (restricted && !closed.has("restricted-network") && restrictedSince !== null && Date.now() - restrictedSince < RESTRICTED_NOTICE_MS) {
|
|
5898
|
+
return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("p", { className: "mx-meet__banner", role: "status", "data-meet-notice": "restricted-network", children: [
|
|
5899
|
+
"Restricted network \xB7 quality may be reduced",
|
|
5900
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("button", { type: "button", className: "mx-meet__link", onClick: close("restricted-network"), children: "Dismiss" })
|
|
5901
|
+
] });
|
|
5902
|
+
}
|
|
5903
|
+
return null;
|
|
5904
|
+
}
|
|
5806
5905
|
function ShareNotice() {
|
|
5807
|
-
const { share, actions } = useMeetCore();
|
|
5906
|
+
const { share, actions, snapshot } = useMeetCore();
|
|
5808
5907
|
const [soundHintClosed, setSoundHintClosed] = (0, import_react10.useState)(null);
|
|
5809
5908
|
if (share.state === "presenting" && share.audio === false && soundHintClosed !== share.at) {
|
|
5810
5909
|
return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("p", { className: "mx-meet__banner", role: "status", "data-meet-notice": "share-audio-missing", children: [
|
|
@@ -5813,6 +5912,16 @@ function ShareNotice() {
|
|
|
5813
5912
|
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("button", { type: "button", className: "mx-meet__link", onClick: () => setSoundHintClosed(share.at), children: "Dismiss" })
|
|
5814
5913
|
] });
|
|
5815
5914
|
}
|
|
5915
|
+
if (share.state === "ended") {
|
|
5916
|
+
const replaced = share.reason === "replaced";
|
|
5917
|
+
const rule = snapshot?.livePolicy.shareWhoCan ?? "host_only";
|
|
5918
|
+
const why = replaced ? `${share.by ?? "Someone"} is now presenting` : rule === "presenters" ? "Sharing is turned off. Only presenters can share their screen" : rule === "org" ? "Sharing is turned off. Only people in the organization can share their screen" : "Sharing is turned off. Only the host can share their screen";
|
|
5919
|
+
return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("p", { className: "mx-meet__banner", role: "status", "data-meet-notice": replaced ? "share-ended" : "share-unavailable", children: [
|
|
5920
|
+
replaced ? "Your presentation ended" : "Your presentation was stopped",
|
|
5921
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "mx-meet__remedy", children: why }),
|
|
5922
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("button", { type: "button", className: "mx-meet__link", onClick: () => actions.dismissShareNotice(), children: "Dismiss" })
|
|
5923
|
+
] });
|
|
5924
|
+
}
|
|
5816
5925
|
if (share.state !== "refused") return null;
|
|
5817
5926
|
const text = share.reason === "unsupported" ? "You can't share your screen from this browser" : share.reason === "blocked" ? "Screen sharing is blocked" : "Couldn't start sharing your screen";
|
|
5818
5927
|
return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("p", { className: "mx-meet__banner", role: "status", "data-meet-notice": "share-unavailable", children: [
|