@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.
- package/CHANGELOG.md +12 -0
- package/dist/{collab-BNJNgXFB.d.cts → collab-D1TX5uf9.d.cts} +7 -0
- package/dist/{collab-BNJNgXFB.d.ts → collab-D1TX5uf9.d.ts} +7 -0
- package/dist/{components-BDtGzHf4.d.ts → components-CNwBgmYU.d.ts} +1 -1
- package/dist/{components-BxK993iW.d.cts → components-CkyDos0f.d.cts} +1 -1
- package/dist/core.cjs +70 -10
- package/dist/core.cjs.map +1 -1
- package/dist/core.d.cts +33 -9
- package/dist/core.d.ts +33 -9
- package/dist/core.js +70 -10
- package/dist/core.js.map +1 -1
- package/dist/index.cjs +70 -10
- 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 +70 -10
- package/dist/index.js.map +1 -1
- package/dist/react.cjs +197 -30
- package/dist/react.cjs.map +1 -1
- package/dist/react.d.cts +3 -3
- package/dist/react.d.ts +3 -3
- package/dist/react.js +197 -30
- package/dist/react.js.map +1 -1
- package/dist/skins/meet.cjs +131 -28
- 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 +131 -28
- package/dist/skins/meet.js.map +1 -1
- package/dist/styles.css +16 -0
- package/package.json +5 -5
package/dist/react.cjs
CHANGED
|
@@ -358,7 +358,14 @@ function createTabClaim(platform = webTabPlatform()) {
|
|
|
358
358
|
if (message.kind === "tab-alive?" && mine !== null && message.tabId === mine && message.from !== self) {
|
|
359
359
|
platform.bus?.post({ kind: "tab-alive", tabId: mine });
|
|
360
360
|
} else if (message.kind === "who-is-in?" && current !== null && mine !== null && message.from !== self && message.room === current.room && message.person === current.person) {
|
|
361
|
-
platform.bus?.post({
|
|
361
|
+
platform.bus?.post({
|
|
362
|
+
kind: "in-room",
|
|
363
|
+
room: current.room,
|
|
364
|
+
person: current.person,
|
|
365
|
+
tabId: mine,
|
|
366
|
+
to: message.from,
|
|
367
|
+
rule: current.rule
|
|
368
|
+
});
|
|
362
369
|
}
|
|
363
370
|
}) ?? (() => {
|
|
364
371
|
});
|
|
@@ -388,28 +395,32 @@ function createTabClaim(platform = webTabPlatform()) {
|
|
|
388
395
|
return candidate;
|
|
389
396
|
}
|
|
390
397
|
const tabId = claim();
|
|
398
|
+
async function presence(room, person) {
|
|
399
|
+
const bus = platform.bus;
|
|
400
|
+
if (bus === null) return null;
|
|
401
|
+
let seen = null;
|
|
402
|
+
const stop = bus.subscribe((message) => {
|
|
403
|
+
if (message.kind === "in-room" && message.to === self && message.room === room && message.person === person) {
|
|
404
|
+
seen = { rule: seen?.rule ?? message.rule ?? null };
|
|
405
|
+
}
|
|
406
|
+
});
|
|
407
|
+
bus.post({ kind: "who-is-in?", room, person, from: self });
|
|
408
|
+
await wait(TAB_ANSWER_MS);
|
|
409
|
+
stop();
|
|
410
|
+
return seen;
|
|
411
|
+
}
|
|
391
412
|
return {
|
|
392
413
|
tabId,
|
|
393
|
-
inRoom(room, person) {
|
|
394
|
-
current = { room, person };
|
|
414
|
+
inRoom(room, person, rule) {
|
|
415
|
+
current = { room, person, rule: rule ?? null };
|
|
395
416
|
},
|
|
396
417
|
left() {
|
|
397
418
|
current = null;
|
|
398
419
|
},
|
|
399
420
|
async presentElsewhere(room, person) {
|
|
400
|
-
|
|
401
|
-
if (bus === null) return false;
|
|
402
|
-
let seen = false;
|
|
403
|
-
const stop = bus.subscribe((message) => {
|
|
404
|
-
if (message.kind === "in-room" && message.to === self && message.room === room && message.person === person) {
|
|
405
|
-
seen = true;
|
|
406
|
-
}
|
|
407
|
-
});
|
|
408
|
-
bus.post({ kind: "who-is-in?", room, person, from: self });
|
|
409
|
-
await wait(TAB_ANSWER_MS);
|
|
410
|
-
stop();
|
|
411
|
-
return seen;
|
|
421
|
+
return await presence(room, person) !== null;
|
|
412
422
|
},
|
|
423
|
+
presenceElsewhere: (room, person) => presence(room, person),
|
|
413
424
|
dispose() {
|
|
414
425
|
unsubscribe();
|
|
415
426
|
}
|
|
@@ -587,7 +598,8 @@ function createWebResumeStorage() {
|
|
|
587
598
|
}
|
|
588
599
|
};
|
|
589
600
|
}
|
|
590
|
-
var CLEARS_RESUME = (phase) => phase === "left" || phase === "removed" || phase === "superseded" || phase === "inactive" || phase === "ended" || phase === "record" || phase === "prejoin" || phase
|
|
601
|
+
var CLEARS_RESUME = (phase) => phase === "left" || phase === "removed" || phase === "superseded" || phase === "inactive" || phase === "ended" || phase === "record" || phase === "prejoin" || phase === "denied" || phase === "knock_expired" || phase.startsWith("refused:");
|
|
602
|
+
var WAITING_RESUMES = (phase) => phase.startsWith("waiting:");
|
|
591
603
|
function autoRejoinDelayMs(attempt, random = Math.random) {
|
|
592
604
|
const base = Math.min(15e3, 1e3 * 2 ** Math.max(0, attempt));
|
|
593
605
|
return Math.round(base * (0.5 + random()));
|
|
@@ -719,6 +731,10 @@ function createConnectionSupervisor(options) {
|
|
|
719
731
|
rejoinAttempts = 0;
|
|
720
732
|
stopRejoin();
|
|
721
733
|
saveMarker(true);
|
|
734
|
+
} else if (WAITING_RESUMES(phase)) {
|
|
735
|
+
stopRejoin();
|
|
736
|
+
driverRegion = null;
|
|
737
|
+
saveMarker(true);
|
|
722
738
|
} else if (phase === "disconnected") {
|
|
723
739
|
driverRegion = null;
|
|
724
740
|
saveMarker(true);
|
|
@@ -1111,10 +1127,10 @@ var MEET_ROUTES = {
|
|
|
1111
1127
|
recordingStop: "/api/v1/meet/recording/stop",
|
|
1112
1128
|
noteTakerStart: "/api/v1/meet/agent/start",
|
|
1113
1129
|
noteTakerStop: "/api/v1/meet/agent/stop",
|
|
1114
|
-
/** In-meeting Q&A. Streams NDJSON; body is `{meeting_id, question}` only. */
|
|
1115
|
-
intelligenceAsk: "/api/v1/meet/intelligence/ask",
|
|
1116
1130
|
/** Anyone in the meeting (guests with the room pass included) asks for captions for themselves. */
|
|
1117
1131
|
noteTakerCaptions: "/api/v1/meet/agent/captions",
|
|
1132
|
+
/** In-meeting Q&A. Streams NDJSON; body is `{meeting_id, question}` only. */
|
|
1133
|
+
intelligenceAsk: "/api/v1/meet/intelligence/ask",
|
|
1118
1134
|
/** A host ends the meeting for everyone. Served by MRI-A6. */
|
|
1119
1135
|
meetingEnd: "/api/v1/meet/end",
|
|
1120
1136
|
/**
|
|
@@ -1239,6 +1255,7 @@ function parseRoomToken(body, roomName) {
|
|
|
1239
1255
|
connectionIdentity: readString(payload, "connection_identity") ?? personKey,
|
|
1240
1256
|
connectionKind: readString(payload, "connection_kind") === "companion" ? "companion" : "main",
|
|
1241
1257
|
secondDeviceChoice,
|
|
1258
|
+
secondDeviceRule: readString(payload, "second_device_rule"),
|
|
1242
1259
|
displayName: readString(payload, "display_name") ?? readString(payload, "displayName") ?? identity,
|
|
1243
1260
|
expiresAt,
|
|
1244
1261
|
canPublish: readBoolean(payload, "can_publish", true),
|
|
@@ -1952,6 +1969,12 @@ var JOINABLE_FROM = /* @__PURE__ */ new Set([
|
|
|
1952
1969
|
// allows the press; the server's gate decides whether it knocks or is refused again.
|
|
1953
1970
|
"refused:lobby_rejects"
|
|
1954
1971
|
]);
|
|
1972
|
+
var RETRYABLE_REFUSALS = /* @__PURE__ */ new Set([
|
|
1973
|
+
"refused:locked",
|
|
1974
|
+
"refused:too_early",
|
|
1975
|
+
"refused:meeting_full",
|
|
1976
|
+
"refused:platform_capacity"
|
|
1977
|
+
]);
|
|
1955
1978
|
var NOT_ENDABLE = /* @__PURE__ */ new Set([
|
|
1956
1979
|
"ended",
|
|
1957
1980
|
"record",
|
|
@@ -2017,7 +2040,7 @@ function nextPhase(from, event) {
|
|
|
2017
2040
|
case "link_state":
|
|
2018
2041
|
return from === "resolving" && event.reason !== null && isJoinRefusalReason(event.reason) ? refusalPhase(event.reason) : null;
|
|
2019
2042
|
case "join":
|
|
2020
|
-
return JOINABLE_FROM.has(from) ? "joining" : null;
|
|
2043
|
+
return JOINABLE_FROM.has(from) || RETRYABLE_REFUSALS.has(from) ? "joining" : null;
|
|
2021
2044
|
case "auto_rejoin":
|
|
2022
2045
|
return from === "disconnected" ? "joining" : null;
|
|
2023
2046
|
case "resumed":
|
|
@@ -2859,6 +2882,10 @@ var RPCS = {
|
|
|
2859
2882
|
admitAll: "meet_admit_all",
|
|
2860
2883
|
setLock: "meet_set_lock",
|
|
2861
2884
|
recordConsent: "meet_record_consent",
|
|
2885
|
+
/** One meeting rule as the gate obeys it (the knob ladder, this meeting's rung included). */
|
|
2886
|
+
meetingRule: "meet_policy",
|
|
2887
|
+
/** A host sets one rule for THIS meeting (the `meet_meeting` rung); refusals come back as `{ok:false}`. */
|
|
2888
|
+
setMeetingRule: "meet_policy_set",
|
|
2862
2889
|
/*
|
|
2863
2890
|
* ── MEET WAVE 1 — management (0.8). Every write is a SECURITY DEFINER door
|
|
2864
2891
|
* authorized by the meeting's host or a real iam grant (editor to change,
|
|
@@ -2905,7 +2932,7 @@ var INVITEE_COLUMNS = "id,meeting_id,invitee_user_id,email,display_name,role,rsv
|
|
|
2905
2932
|
var RECORDING_COLUMNS = "id,meeting_id,state,started_at,ended_at,started_by,file_id,failure_reason";
|
|
2906
2933
|
var SEGMENT_COLUMNS = "id,meeting_id,identity,speaker,text,started_at,is_final,metadata";
|
|
2907
2934
|
var NOTE_COLUMNS = "id,meeting_id,text,kind,assignee_user_id,created_at,metadata";
|
|
2908
|
-
var ATTENDEE_COLUMNS = "id,meeting_id,identity,participant_user_id,display_name,avatar_url,role,admission_state,knocked_at,knock_expires_at,is_agent,joined_at,left_at,sessions:metadata->sessions";
|
|
2935
|
+
var ATTENDEE_COLUMNS = "id,meeting_id,identity,participant_user_id,display_name,avatar_url,role,admission_state,knocked_at,knock_expires_at,is_agent,joined_at,left_at,sessions:metadata->sessions,knock_flag:metadata->>knock_flag";
|
|
2909
2936
|
function projectStays(value) {
|
|
2910
2937
|
if (!Array.isArray(value)) return [];
|
|
2911
2938
|
const stays = [];
|
|
@@ -3305,6 +3332,8 @@ function createMeetRepository(options) {
|
|
|
3305
3332
|
admissionState: states.includes(admission) ? admission : "admitted",
|
|
3306
3333
|
knockedAt: text(row, "knocked_at"),
|
|
3307
3334
|
knockExpiresAt: text(row, "knock_expires_at"),
|
|
3335
|
+
// The list read selects `metadata->>knock_flag`; a Postgres Changes row carries `metadata`.
|
|
3336
|
+
knockFlag: text(row, "knock_flag") ?? (typeof row["metadata"] === "object" && row["metadata"] !== null ? text(row["metadata"], "knock_flag") : null),
|
|
3308
3337
|
isAgent: bool(row, "is_agent", false),
|
|
3309
3338
|
joinedAt: text(row, "joined_at"),
|
|
3310
3339
|
leftAt: text(row, "left_at"),
|
|
@@ -3628,6 +3657,25 @@ function createMeetRepository(options) {
|
|
|
3628
3657
|
);
|
|
3629
3658
|
return projectMeeting(row);
|
|
3630
3659
|
},
|
|
3660
|
+
async meetingRule(meetingId, key) {
|
|
3661
|
+
const response = await db.rpc(RPCS.meetingRule, { p_meeting_id: meetingId, p_key: key });
|
|
3662
|
+
if (response.error !== null) throw normalizeMeetError(response.error, "meet.meetingRule");
|
|
3663
|
+
return response.data;
|
|
3664
|
+
},
|
|
3665
|
+
async setMeetingRule(meetingId, key, value) {
|
|
3666
|
+
const response = await db.rpc(RPCS.setMeetingRule, { p_meeting_id: meetingId, p_key: key, p_value: value });
|
|
3667
|
+
if (response.error !== null) throw normalizeMeetError(response.error, "meet.setMeetingRule");
|
|
3668
|
+
const answer = response.data ?? {};
|
|
3669
|
+
if (answer["ok"] !== true) {
|
|
3670
|
+
throw new MeetError(
|
|
3671
|
+
"forbidden",
|
|
3672
|
+
typeof answer["detail"] === "string" ? answer["detail"] : "This meeting's rule was not changed.",
|
|
3673
|
+
"Only the meeting's host or a co-host sets its rules; an organization can lock a rule for everyone.",
|
|
3674
|
+
answer
|
|
3675
|
+
);
|
|
3676
|
+
}
|
|
3677
|
+
return answer["effective_value"];
|
|
3678
|
+
},
|
|
3631
3679
|
async transcript(meetingId, limit = 1e3) {
|
|
3632
3680
|
const response = await db.from(TABLES.transcripts).select(SEGMENT_COLUMNS).eq("meeting_id", meetingId).order("started_at", { ascending: true }).order("id", { ascending: true }).limit(limit);
|
|
3633
3681
|
if (response.error !== null) throw normalizeMeetError(response.error, "meet.transcript");
|
|
@@ -4522,7 +4570,8 @@ function lobbyEntryFrom(attendee, now = Date.now()) {
|
|
|
4522
4570
|
knockedAt: attendee.knockedAt ?? attendee.joinedAt ?? (/* @__PURE__ */ new Date()).toISOString(),
|
|
4523
4571
|
knockExpiresAt: attendee.knockExpiresAt ?? null,
|
|
4524
4572
|
decidedAt: null,
|
|
4525
|
-
decidedBy: null
|
|
4573
|
+
decidedBy: null,
|
|
4574
|
+
flag: attendee.knockFlag ?? null
|
|
4526
4575
|
};
|
|
4527
4576
|
}
|
|
4528
4577
|
function deniedEntryFrom(attendee) {
|
|
@@ -4694,11 +4743,15 @@ function createMeetingSession(options) {
|
|
|
4694
4743
|
}
|
|
4695
4744
|
let policyTimer = null;
|
|
4696
4745
|
let policyReading = false;
|
|
4746
|
+
let policyInFlight = null;
|
|
4697
4747
|
async function readLivePolicy() {
|
|
4698
4748
|
const meeting = store.snapshot().meeting;
|
|
4699
4749
|
const pass = options.resolvePass?.() ?? null;
|
|
4700
|
-
if (meeting === null || pass === null
|
|
4750
|
+
if (meeting === null || pass === null) return;
|
|
4751
|
+
if (policyReading) return policyInFlight ?? void 0;
|
|
4701
4752
|
policyReading = true;
|
|
4753
|
+
let done = () => void 0;
|
|
4754
|
+
policyInFlight = new Promise((resolve) => done = resolve);
|
|
4702
4755
|
try {
|
|
4703
4756
|
const response = await options.api.request({
|
|
4704
4757
|
path: `${MEET_ROUTES.state}?meeting_id=${encodeURIComponent(meeting.id)}`,
|
|
@@ -4719,6 +4772,8 @@ function createMeetingSession(options) {
|
|
|
4719
4772
|
} catch {
|
|
4720
4773
|
} finally {
|
|
4721
4774
|
policyReading = false;
|
|
4775
|
+
policyInFlight = null;
|
|
4776
|
+
done();
|
|
4722
4777
|
}
|
|
4723
4778
|
}
|
|
4724
4779
|
function syncLivePolicyTimer() {
|
|
@@ -5017,6 +5072,7 @@ function createMeetingSession(options) {
|
|
|
5017
5072
|
},
|
|
5018
5073
|
stopWaiting,
|
|
5019
5074
|
readState: readState2,
|
|
5075
|
+
readLivePolicy,
|
|
5020
5076
|
async readExit(connection, held) {
|
|
5021
5077
|
const meeting = store.snapshot().meeting;
|
|
5022
5078
|
const pass = held ?? options.resolvePass?.() ?? null;
|
|
@@ -5054,6 +5110,17 @@ function createMeetingSession(options) {
|
|
|
5054
5110
|
async askAgain() {
|
|
5055
5111
|
await options.rejoin?.();
|
|
5056
5112
|
},
|
|
5113
|
+
async meetingRule(key) {
|
|
5114
|
+
const meeting = requireMeeting("meet.meetingRule");
|
|
5115
|
+
return repository.meetingRule(meeting.id, key);
|
|
5116
|
+
},
|
|
5117
|
+
async setMeetingRule(key, value) {
|
|
5118
|
+
requireHostUser("meet.setMeetingRule");
|
|
5119
|
+
const meeting = requireMeeting("meet.setMeetingRule");
|
|
5120
|
+
const effective = await repository.setMeetingRule(meeting.id, key, value);
|
|
5121
|
+
hint();
|
|
5122
|
+
return effective;
|
|
5123
|
+
},
|
|
5057
5124
|
async setLock(locked) {
|
|
5058
5125
|
const by = requireHostUser("meet.setLock");
|
|
5059
5126
|
const meeting = requireMeeting("meet.setLock");
|
|
@@ -5831,6 +5898,7 @@ var STATES = [
|
|
|
5831
5898
|
"ended"
|
|
5832
5899
|
];
|
|
5833
5900
|
function readState(value) {
|
|
5901
|
+
if (value === "dispatching") return "joining";
|
|
5834
5902
|
return typeof value === "string" && STATES.includes(value) ? value : null;
|
|
5835
5903
|
}
|
|
5836
5904
|
function isNoteTaker(participant) {
|
|
@@ -6319,7 +6387,7 @@ function createRoomEngine(options) {
|
|
|
6319
6387
|
const { secondDevice: _answered, ...rest } = lastRequest;
|
|
6320
6388
|
lastRequest = rest;
|
|
6321
6389
|
}
|
|
6322
|
-
options.tabClaim?.inRoom(String(request.roomName), String(token.identity));
|
|
6390
|
+
options.tabClaim?.inRoom(String(request.roomName), String(token.identity), token.secondDeviceRule ?? null);
|
|
6323
6391
|
current = token;
|
|
6324
6392
|
lastServerUrl = token.serverUrl;
|
|
6325
6393
|
connectionPolicy = token.connectionPolicy ?? DEFAULT_CONNECTION_POLICY;
|
|
@@ -6631,10 +6699,12 @@ function createRoomEngine(options) {
|
|
|
6631
6699
|
if (claim === void 0 || userId === null) return false;
|
|
6632
6700
|
const before = store.snapshot();
|
|
6633
6701
|
if (before.phase !== "prejoin" || before.secondDevice !== null) return false;
|
|
6634
|
-
|
|
6702
|
+
const person = `user:${String(userId)}`;
|
|
6703
|
+
const found = claim.presenceElsewhere !== void 0 ? await claim.presenceElsewhere(String(roomName), person) : await claim.presentElsewhere(String(roomName), person) ? { rule: null } : null;
|
|
6704
|
+
if (found === null || found.rule === "allow_both") return false;
|
|
6635
6705
|
const now2 = store.snapshot();
|
|
6636
6706
|
if (now2.phase !== "prejoin" || now2.secondDevice !== null) return false;
|
|
6637
|
-
store.patch({ secondDevice: { rule: "ask_switch_or_join" } });
|
|
6707
|
+
store.patch({ secondDevice: { rule: found.rule ?? "ask_switch_or_join" } });
|
|
6638
6708
|
report("info", "meet: this browser already has you in this meeting \u2014 offering the choice before Join");
|
|
6639
6709
|
return true;
|
|
6640
6710
|
},
|
|
@@ -6890,6 +6960,7 @@ function createInRoomClient(options) {
|
|
|
6890
6960
|
action: request.action,
|
|
6891
6961
|
...request.identity != null ? { identity: request.identity } : {},
|
|
6892
6962
|
...request.name !== void 0 ? { name: request.name } : {},
|
|
6963
|
+
...request.value !== void 0 ? { value: request.value } : {},
|
|
6893
6964
|
...request.reason !== void 0 ? { reason: request.reason } : {}
|
|
6894
6965
|
},
|
|
6895
6966
|
...hdrs !== void 0 ? { headers: hdrs } : {}
|
|
@@ -9265,7 +9336,10 @@ function useEndMeeting() {
|
|
|
9265
9336
|
function useConsentNotice() {
|
|
9266
9337
|
const snapshot = useMeetSnapshot();
|
|
9267
9338
|
const agent = noteTakerParticipant(snapshot?.participants ?? []);
|
|
9268
|
-
if (agent === null)
|
|
9339
|
+
if (agent === null) {
|
|
9340
|
+
const state = noteTakerStatus({ meeting: snapshot?.meeting ?? null, participants: [] }).state;
|
|
9341
|
+
return state === "joining" ? "AI notes started. The note-taker is joining this meeting." : null;
|
|
9342
|
+
}
|
|
9269
9343
|
return `AI notes are on. ${agent.displayName} is in this meeting, transcribing what is said and writing notes everyone here can read.`;
|
|
9270
9344
|
}
|
|
9271
9345
|
function useMediaSupervisor() {
|
|
@@ -10439,6 +10513,10 @@ function actionsFor(host) {
|
|
|
10439
10513
|
leave: () => engine.leave(),
|
|
10440
10514
|
backToPrejoin: () => engine.backToPrejoin(),
|
|
10441
10515
|
retry: () => {
|
|
10516
|
+
if (RETRYABLE_REFUSALS.has(store.snapshot().phase)) {
|
|
10517
|
+
void engine.rejoin().catch(() => void 0);
|
|
10518
|
+
return;
|
|
10519
|
+
}
|
|
10442
10520
|
store.dispatch({ type: "retry", click: true });
|
|
10443
10521
|
},
|
|
10444
10522
|
resolved: () => {
|
|
@@ -12158,6 +12236,7 @@ function ControlBar({ onLeave }) {
|
|
|
12158
12236
|
]
|
|
12159
12237
|
}
|
|
12160
12238
|
),
|
|
12239
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(WaitingRoomRule, {}),
|
|
12161
12240
|
queue.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
|
|
12162
12241
|
MenuItem,
|
|
12163
12242
|
{
|
|
@@ -12377,6 +12456,58 @@ function MenuItem({
|
|
|
12377
12456
|
}
|
|
12378
12457
|
);
|
|
12379
12458
|
}
|
|
12459
|
+
var LOBBY_BYPASS_CHOICES = [
|
|
12460
|
+
{ value: "everyone", label: "Everyone" },
|
|
12461
|
+
{ value: "org_and_invited", label: "Your organization and invited people" },
|
|
12462
|
+
{ value: "org", label: "Your organization" },
|
|
12463
|
+
{ value: "invited", label: "Invited people" },
|
|
12464
|
+
{ value: "host_only", label: "Only hosts" }
|
|
12465
|
+
];
|
|
12466
|
+
function WaitingRoomRule() {
|
|
12467
|
+
const host = useRequiredMeetHost();
|
|
12468
|
+
const [open, setOpen] = (0, import_react10.useState)(false);
|
|
12469
|
+
const [value, setValue] = (0, import_react10.useState)(null);
|
|
12470
|
+
const [notice, setNotice] = (0, import_react10.useState)(null);
|
|
12471
|
+
(0, import_react10.useEffect)(() => {
|
|
12472
|
+
let live = true;
|
|
12473
|
+
void host.meetings.meetingRule("lobby_bypass").then((rule) => {
|
|
12474
|
+
if (live) setValue(typeof rule === "string" ? rule : null);
|
|
12475
|
+
}).catch(() => void 0);
|
|
12476
|
+
return () => {
|
|
12477
|
+
live = false;
|
|
12478
|
+
};
|
|
12479
|
+
}, [host]);
|
|
12480
|
+
const current = LOBBY_BYPASS_CHOICES.find((choice) => choice.value === value)?.label ?? null;
|
|
12481
|
+
return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
|
|
12482
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(MenuItem, { onSelect: () => setOpen(!open), children: [
|
|
12483
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(LockIcon, { width: 16, height: 16 }),
|
|
12484
|
+
" Who can skip the waiting room",
|
|
12485
|
+
current !== null ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "mx-meet__menu-value", children: current }) : null
|
|
12486
|
+
] }),
|
|
12487
|
+
open ? /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { role: "group", "aria-label": "Who can skip the waiting room", "data-meet-rule": "lobby_bypass", children: [
|
|
12488
|
+
LOBBY_BYPASS_CHOICES.map((choice) => /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
|
|
12489
|
+
"button",
|
|
12490
|
+
{
|
|
12491
|
+
type: "button",
|
|
12492
|
+
role: "menuitemradio",
|
|
12493
|
+
"aria-checked": choice.value === value,
|
|
12494
|
+
className: "mx-meet__menu-item mx-meet__menu-item--sub",
|
|
12495
|
+
onClick: () => {
|
|
12496
|
+
setNotice(null);
|
|
12497
|
+
void host.meetings.setMeetingRule("lobby_bypass", choice.value).then(() => setValue(choice.value)).catch((error) => setNotice(error instanceof Error ? error.message : String(error)));
|
|
12498
|
+
},
|
|
12499
|
+
children: [
|
|
12500
|
+
choice.value === value ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(CheckIcon, { width: 14, height: 14 }) : null,
|
|
12501
|
+
" ",
|
|
12502
|
+
choice.label
|
|
12503
|
+
]
|
|
12504
|
+
},
|
|
12505
|
+
choice.value
|
|
12506
|
+
)),
|
|
12507
|
+
notice !== null ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("p", { className: "mx-meet__menu-note", role: "status", children: notice }) : null
|
|
12508
|
+
] }) : null
|
|
12509
|
+
] });
|
|
12510
|
+
}
|
|
12380
12511
|
function Toast({ text: text3, failed, onDone }) {
|
|
12381
12512
|
(0, import_react10.useEffect)(() => {
|
|
12382
12513
|
const timer = setTimeout(onDone, failed ? 7e3 : 4e3);
|
|
@@ -12690,6 +12821,17 @@ function ChatPanel({
|
|
|
12690
12821
|
const snapshot = useMeetSnapshot();
|
|
12691
12822
|
const room = useRoom();
|
|
12692
12823
|
const live = useLivePolicy();
|
|
12824
|
+
const host = useMeetHost();
|
|
12825
|
+
const [rulesChecked, setRulesChecked] = (0, import_react10.useState)(false);
|
|
12826
|
+
(0, import_react10.useEffect)(() => {
|
|
12827
|
+
let alive = true;
|
|
12828
|
+
const done = () => alive && setRulesChecked(true);
|
|
12829
|
+
if (host === null) done();
|
|
12830
|
+
else void host.meetings.readLivePolicy().then(done, done);
|
|
12831
|
+
return () => {
|
|
12832
|
+
alive = false;
|
|
12833
|
+
};
|
|
12834
|
+
}, [host]);
|
|
12693
12835
|
const [draft, setDraft] = (0, import_react10.useState)("");
|
|
12694
12836
|
const [recipient, setRecipient] = (0, import_react10.useState)(to);
|
|
12695
12837
|
const listRef = (0, import_react10.useRef)(null);
|
|
@@ -12714,7 +12856,7 @@ function ChatPanel({
|
|
|
12714
12856
|
snapshot?.chatLoaded !== true && messages.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("li", { className: "mx-meet__panel-note", children: "Reading earlier messages\u2026" }) : messages.length === 0 && snapshot?.chatHistoryError == null ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("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,
|
|
12715
12857
|
messages.map((message) => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(ChatLine, { message, local, people }, message.id))
|
|
12716
12858
|
] }),
|
|
12717
|
-
!live.canChat ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("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__ */ (0, import_jsx_runtime6.jsxs)(
|
|
12859
|
+
!rulesChecked ? null : !live.canChat ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("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__ */ (0, import_jsx_runtime6.jsxs)(
|
|
12718
12860
|
"form",
|
|
12719
12861
|
{
|
|
12720
12862
|
className: "mx-meet__composer mx-meet__composer--chat",
|
|
@@ -13465,7 +13607,11 @@ function WaitingList({ lobby }) {
|
|
|
13465
13607
|
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Avatar, { name: entry.displayName, url: entry.avatarUrl, size: 32 }),
|
|
13466
13608
|
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("span", { className: "mx-meet__person-name", children: [
|
|
13467
13609
|
entry.displayName,
|
|
13468
|
-
entry.userId === null ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "mx-meet__badge", children: "Guest" }) : null
|
|
13610
|
+
entry.userId === null ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "mx-meet__badge", children: "Guest" }) : null,
|
|
13611
|
+
entry.flag === "previously_removed" ? (
|
|
13612
|
+
// `mod-removed-bypass`: advice for the host, never a block — Admit stays.
|
|
13613
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "mx-meet__badge mx-meet__badge--warn", "data-meet-notice": "knock-flagged", children: "Previously removed" })
|
|
13614
|
+
) : null
|
|
13469
13615
|
] }),
|
|
13470
13616
|
/* @__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 }) }),
|
|
13471
13617
|
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
@@ -14090,7 +14236,20 @@ function ExitScreen({ onLeave }) {
|
|
|
14090
14236
|
const { phase, reason, host, snapshot, actions, call, connection } = useMeetCore();
|
|
14091
14237
|
const [busy, setBusy] = (0, import_react10.useState)(false);
|
|
14092
14238
|
const failure = snapshot?.failure ?? null;
|
|
14093
|
-
const retryLeft = useCountdown(
|
|
14239
|
+
const retryLeft = useCountdown(
|
|
14240
|
+
phase === "refused:lobby_rejects" || phase === "refused:too_early" ? failure?.retryAt ?? null : null
|
|
14241
|
+
);
|
|
14242
|
+
const reaskedAtZero = (0, import_react10.useRef)(false);
|
|
14243
|
+
(0, import_react10.useEffect)(() => {
|
|
14244
|
+
if (phase !== "refused:too_early") {
|
|
14245
|
+
reaskedAtZero.current = false;
|
|
14246
|
+
return;
|
|
14247
|
+
}
|
|
14248
|
+
if (retryLeft === 0 && !reaskedAtZero.current) {
|
|
14249
|
+
reaskedAtZero.current = true;
|
|
14250
|
+
actions.retry();
|
|
14251
|
+
}
|
|
14252
|
+
}, [phase, retryLeft, actions]);
|
|
14094
14253
|
const rejoin = /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
14095
14254
|
import_design_system.Button,
|
|
14096
14255
|
{
|
|
@@ -14128,11 +14287,19 @@ function ExitScreen({ onLeave }) {
|
|
|
14128
14287
|
if (phase.startsWith("refused:")) {
|
|
14129
14288
|
const code = phase.slice("refused:".length);
|
|
14130
14289
|
title = REFUSED_TITLES[code] ?? "You can't join this meeting";
|
|
14131
|
-
line = code === "too_early" || code === "registration_required" || code === "cancelled" ? failure?.remedy ?? null : null;
|
|
14290
|
+
line = code === "too_early" || code === "registration_required" || code === "cancelled" || code === "wrong_account" ? failure?.remedy ?? null : null;
|
|
14291
|
+
if (code === "too_early" && retryLeft !== null && retryLeft > 0) line = `Opens in ${clockText(retryLeft)}`;
|
|
14132
14292
|
actionsNode = /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
|
|
14133
14293
|
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_design_system.Button, { type: "button", variant: "outline", onClick: actions.retry, children: "Try again" }),
|
|
14134
14294
|
home
|
|
14135
14295
|
] });
|
|
14296
|
+
if (code === "sign_in_required" || code === "wrong_account") {
|
|
14297
|
+
const back = typeof window === "undefined" ? "/" : `${window.location.pathname}${window.location.search}`;
|
|
14298
|
+
actionsNode = /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
|
|
14299
|
+
/* @__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" }) }),
|
|
14300
|
+
home
|
|
14301
|
+
] });
|
|
14302
|
+
}
|
|
14136
14303
|
if (code === "lobby_rejects") {
|
|
14137
14304
|
if (retryLeft !== null && retryLeft > 0) {
|
|
14138
14305
|
line = `You can ask again in ${clockText(retryLeft)}`;
|