@ai-matrx/meet 0.10.6 → 0.11.0
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-ytIzjceh.d.cts → collab-CIyXdQ5l.d.cts} +1 -2
- package/dist/{collab-ytIzjceh.d.ts → collab-CIyXdQ5l.d.ts} +1 -2
- package/dist/{components-CnnefQn-.d.cts → components-DUvy3BQf.d.cts} +1 -1
- package/dist/{components-DjzH3u_c.d.ts → components-DiGxfKXI.d.ts} +1 -1
- package/dist/core.cjs +403 -98
- package/dist/core.cjs.map +1 -1
- package/dist/core.d.cts +254 -24
- package/dist/core.d.ts +254 -24
- package/dist/core.js +403 -98
- package/dist/core.js.map +1 -1
- package/dist/index.cjs +403 -98
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +403 -98
- package/dist/index.js.map +1 -1
- package/dist/react.cjs +696 -116
- package/dist/react.cjs.map +1 -1
- package/dist/react.d.cts +68 -7
- package/dist/react.d.ts +68 -7
- package/dist/react.js +697 -117
- package/dist/react.js.map +1 -1
- package/dist/skins/meet.cjs +265 -50
- 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 +265 -50
- package/dist/skins/meet.js.map +1 -1
- package/dist/styles.css +20 -0
- package/package.json +2 -2
package/dist/index.cjs
CHANGED
|
@@ -46,9 +46,11 @@ __export(src_exports, {
|
|
|
46
46
|
GUEST_RECORD_ACCESS_METADATA_KEY: () => GUEST_RECORD_ACCESS_METADATA_KEY,
|
|
47
47
|
GUEST_RECORD_NOT_SHARED: () => GUEST_RECORD_NOT_SHARED,
|
|
48
48
|
IDLE_MEDIA: () => IDLE_MEDIA,
|
|
49
|
+
IDLE_PHASES: () => IDLE_PHASES,
|
|
49
50
|
IDLE_TRACK: () => IDLE_TRACK,
|
|
50
51
|
JOIN_REFUSAL_REASONS: () => JOIN_REFUSAL_REASONS,
|
|
51
52
|
LISTEN_ONLY_NOTICE: () => LISTEN_ONLY_NOTICE,
|
|
53
|
+
LIVE_PHASES: () => LIVE_PHASES,
|
|
52
54
|
MEETING_INVITE_KIND: () => MEETING_INVITE_KIND,
|
|
53
55
|
MEETING_INVITE_VERSION: () => MEETING_INVITE_VERSION,
|
|
54
56
|
MEETING_PASS_HEADER: () => MEETING_PASS_HEADER,
|
|
@@ -64,6 +66,7 @@ __export(src_exports, {
|
|
|
64
66
|
NOTE_TAKER_IDENTITY_PREFIX: () => NOTE_TAKER_IDENTITY_PREFIX,
|
|
65
67
|
NOTE_TAKER_METADATA_KEY: () => NOTE_TAKER_METADATA_KEY,
|
|
66
68
|
NO_GRANTS: () => NO_GRANTS,
|
|
69
|
+
NO_SHARE: () => NO_SHARE,
|
|
67
70
|
ORGANIZATION_HEADER: () => ORGANIZATION_HEADER,
|
|
68
71
|
PARTICIPANT_CAN_RECORD_ATTRIBUTE: () => PARTICIPANT_CAN_RECORD_ATTRIBUTE,
|
|
69
72
|
PARTICIPANT_ROLE_ATTRIBUTE: () => PARTICIPANT_ROLE_ATTRIBUTE,
|
|
@@ -77,9 +80,11 @@ __export(src_exports, {
|
|
|
77
80
|
TABLES: () => TABLES,
|
|
78
81
|
TRANSCRIPTION_ATTRIBUTES: () => TRANSCRIPTION_ATTRIBUTES,
|
|
79
82
|
TRANSCRIPTION_TOPIC: () => TRANSCRIPTION_TOPIC,
|
|
83
|
+
WAITING_PHASES: () => WAITING_PHASES,
|
|
80
84
|
absenceSentence: () => absenceSentence,
|
|
81
85
|
activeWrapUpSummary: () => activeWrapUpSummary,
|
|
82
86
|
activityAttention: () => activityAttention,
|
|
87
|
+
admissionPhase: () => admissionPhase,
|
|
83
88
|
announceMeeting: () => announceMeeting,
|
|
84
89
|
appPanelOf: () => appPanelOf,
|
|
85
90
|
applyCollabPacket: () => applyCollabPacket,
|
|
@@ -149,10 +154,13 @@ __export(src_exports, {
|
|
|
149
154
|
isJoinRefusalReason: () => isJoinRefusalReason,
|
|
150
155
|
isLinkFollower: () => isLinkFollower,
|
|
151
156
|
isListenOnly: () => isListenOnly,
|
|
157
|
+
isLivePhase: () => isLivePhase,
|
|
152
158
|
isNoteTaker: () => isNoteTaker,
|
|
153
159
|
isObserverRole: () => isObserverRole,
|
|
154
160
|
isRealName: () => isRealName,
|
|
161
|
+
isRefusedPhase: () => isRefusedPhase,
|
|
155
162
|
isRoomEventTopic: () => isRoomEventTopic,
|
|
163
|
+
isWaitingPhase: () => isWaitingPhase,
|
|
156
164
|
learnName: () => learnName,
|
|
157
165
|
learnNames: () => learnNames,
|
|
158
166
|
listenOnlyNotice: () => listenOnlyNotice,
|
|
@@ -176,6 +184,7 @@ __export(src_exports, {
|
|
|
176
184
|
mergeRecord: () => mergeRecord,
|
|
177
185
|
microphoneNoticeCode: () => microphoneNoticeCode,
|
|
178
186
|
moveToRoom: () => moveToRoom,
|
|
187
|
+
nextPhase: () => nextPhase,
|
|
179
188
|
nextTranslationBatch: () => nextTranslationBatch,
|
|
180
189
|
normalizeDeviceError: () => normalizeDeviceError,
|
|
181
190
|
normalizeMeetError: () => normalizeMeetError,
|
|
@@ -208,10 +217,13 @@ __export(src_exports, {
|
|
|
208
217
|
pushMeetingToGoogleCalendar: () => pushMeetingToGoogleCalendar,
|
|
209
218
|
readServerRefusal: () => readServerRefusal,
|
|
210
219
|
readableTranscript: () => readableTranscript,
|
|
220
|
+
reasonOf: () => reasonOf,
|
|
211
221
|
recordingLabel: () => recordingLabel,
|
|
212
222
|
recordingNotice: () => recordingNotice,
|
|
213
223
|
recordingOffsetMs: () => recordingOffsetMs,
|
|
224
|
+
refusalPhase: () => refusalPhase,
|
|
214
225
|
rememberedMeetingPass: () => rememberedMeetingPass,
|
|
226
|
+
resolveExit: () => resolveExit,
|
|
215
227
|
roleOf: () => roleOf,
|
|
216
228
|
roomTopic: () => roomTopic,
|
|
217
229
|
rootAttributes: () => rootAttributes,
|
|
@@ -1254,6 +1266,166 @@ var MEET_EVENTS = {
|
|
|
1254
1266
|
stateChanged: "mx.state.changed"
|
|
1255
1267
|
};
|
|
1256
1268
|
|
|
1269
|
+
// src/core/reasons.ts
|
|
1270
|
+
var JOIN_REFUSAL_REASONS = [
|
|
1271
|
+
"not_found",
|
|
1272
|
+
"cancelled",
|
|
1273
|
+
"ended",
|
|
1274
|
+
"expired",
|
|
1275
|
+
"too_early",
|
|
1276
|
+
"sign_in_required",
|
|
1277
|
+
"wrong_account",
|
|
1278
|
+
"not_invited",
|
|
1279
|
+
"locked",
|
|
1280
|
+
"removed",
|
|
1281
|
+
"lobby_rejects",
|
|
1282
|
+
"meeting_full",
|
|
1283
|
+
"platform_capacity",
|
|
1284
|
+
"verification_required",
|
|
1285
|
+
"registration_required"
|
|
1286
|
+
];
|
|
1287
|
+
function isJoinRefusalReason(value) {
|
|
1288
|
+
return typeof value === "string" && JOIN_REFUSAL_REASONS.includes(value);
|
|
1289
|
+
}
|
|
1290
|
+
|
|
1291
|
+
// src/core/phase.ts
|
|
1292
|
+
var LIVE_PHASES = /* @__PURE__ */ new Set(["joining", "in_call"]);
|
|
1293
|
+
var WAITING_PHASES = /* @__PURE__ */ new Set([
|
|
1294
|
+
"waiting:host_not_started",
|
|
1295
|
+
"waiting:knocking",
|
|
1296
|
+
"denied",
|
|
1297
|
+
"knock_expired"
|
|
1298
|
+
]);
|
|
1299
|
+
var JOINABLE_FROM = /* @__PURE__ */ new Set([
|
|
1300
|
+
"prejoin",
|
|
1301
|
+
"left",
|
|
1302
|
+
"disconnected",
|
|
1303
|
+
"superseded",
|
|
1304
|
+
"inactive",
|
|
1305
|
+
"denied",
|
|
1306
|
+
"knock_expired"
|
|
1307
|
+
]);
|
|
1308
|
+
var NOT_ENDABLE = /* @__PURE__ */ new Set([
|
|
1309
|
+
"ended",
|
|
1310
|
+
"record",
|
|
1311
|
+
"unsupported",
|
|
1312
|
+
"ringing_out",
|
|
1313
|
+
"ringing_in",
|
|
1314
|
+
"call_declined",
|
|
1315
|
+
"call_missed",
|
|
1316
|
+
"call_busy",
|
|
1317
|
+
"answered_elsewhere"
|
|
1318
|
+
]);
|
|
1319
|
+
var RINGING = /* @__PURE__ */ new Set(["ringing_out", "ringing_in"]);
|
|
1320
|
+
var IDLE_PHASES = /* @__PURE__ */ new Set([
|
|
1321
|
+
"resolving",
|
|
1322
|
+
"left",
|
|
1323
|
+
"call_declined",
|
|
1324
|
+
"call_missed",
|
|
1325
|
+
"call_busy",
|
|
1326
|
+
"answered_elsewhere"
|
|
1327
|
+
]);
|
|
1328
|
+
function isLivePhase(phase) {
|
|
1329
|
+
return LIVE_PHASES.has(phase);
|
|
1330
|
+
}
|
|
1331
|
+
function isWaitingPhase(phase) {
|
|
1332
|
+
return WAITING_PHASES.has(phase);
|
|
1333
|
+
}
|
|
1334
|
+
function isRefusedPhase(phase) {
|
|
1335
|
+
return phase.startsWith("refused:");
|
|
1336
|
+
}
|
|
1337
|
+
function reasonOf(phase) {
|
|
1338
|
+
return isRefusedPhase(phase) ? phase.slice("refused:".length) : null;
|
|
1339
|
+
}
|
|
1340
|
+
function refusalPhase(reason) {
|
|
1341
|
+
if (reason === null || !isJoinRefusalReason(reason)) return "disconnected";
|
|
1342
|
+
return reason === "ended" ? "ended" : `refused:${reason}`;
|
|
1343
|
+
}
|
|
1344
|
+
function admissionPhase(admission) {
|
|
1345
|
+
switch (admission) {
|
|
1346
|
+
case "waiting_host":
|
|
1347
|
+
return "waiting:host_not_started";
|
|
1348
|
+
case "knocking":
|
|
1349
|
+
return "waiting:knocking";
|
|
1350
|
+
case "denied":
|
|
1351
|
+
return "denied";
|
|
1352
|
+
case "expired":
|
|
1353
|
+
return "knock_expired";
|
|
1354
|
+
case "withdrawn":
|
|
1355
|
+
return "left";
|
|
1356
|
+
case "ended":
|
|
1357
|
+
return "ended";
|
|
1358
|
+
case "removed":
|
|
1359
|
+
return "refused:removed";
|
|
1360
|
+
default:
|
|
1361
|
+
return null;
|
|
1362
|
+
}
|
|
1363
|
+
}
|
|
1364
|
+
function nextPhase(from, event) {
|
|
1365
|
+
switch (event.type) {
|
|
1366
|
+
case "resolved":
|
|
1367
|
+
return from === "resolving" ? "prejoin" : null;
|
|
1368
|
+
case "unsupported":
|
|
1369
|
+
return from === "resolving" ? "unsupported" : null;
|
|
1370
|
+
case "join":
|
|
1371
|
+
return JOINABLE_FROM.has(from) ? "joining" : null;
|
|
1372
|
+
case "back_to_prejoin":
|
|
1373
|
+
return from === "left" || from === "disconnected" ? "prejoin" : null;
|
|
1374
|
+
case "retry":
|
|
1375
|
+
return isRefusedPhase(from) || from === "unsupported" ? "resolving" : null;
|
|
1376
|
+
case "admission": {
|
|
1377
|
+
if (from !== "joining" && !WAITING_PHASES.has(from)) return null;
|
|
1378
|
+
return admissionPhase(event.admission);
|
|
1379
|
+
}
|
|
1380
|
+
case "admitted":
|
|
1381
|
+
return WAITING_PHASES.has(from) ? "joining" : null;
|
|
1382
|
+
case "connected":
|
|
1383
|
+
return from === "joining" ? "in_call" : null;
|
|
1384
|
+
case "join_failed":
|
|
1385
|
+
return from === "joining" ? refusalPhase(event.reason) : null;
|
|
1386
|
+
case "exit":
|
|
1387
|
+
return from === "in_call" || from === "joining" ? event.to : null;
|
|
1388
|
+
case "leave":
|
|
1389
|
+
return from === "in_call" || from === "joining" || WAITING_PHASES.has(from) ? "left" : null;
|
|
1390
|
+
case "ended":
|
|
1391
|
+
return NOT_ENDABLE.has(from) ? null : "ended";
|
|
1392
|
+
case "ring_out":
|
|
1393
|
+
return IDLE_PHASES.has(from) || from === "prejoin" ? "ringing_out" : null;
|
|
1394
|
+
case "ring_in":
|
|
1395
|
+
return IDLE_PHASES.has(from) ? "ringing_in" : null;
|
|
1396
|
+
case "call_answered":
|
|
1397
|
+
return RINGING.has(from) ? "joining" : null;
|
|
1398
|
+
case "call_outcome":
|
|
1399
|
+
return RINGING.has(from) ? event.outcome : null;
|
|
1400
|
+
case "reset":
|
|
1401
|
+
return LIVE_PHASES.has(from) ? null : "resolving";
|
|
1402
|
+
}
|
|
1403
|
+
}
|
|
1404
|
+
function resolveExit(input) {
|
|
1405
|
+
const { server, hint } = input;
|
|
1406
|
+
if (server === null) {
|
|
1407
|
+
return { to: "disconnected", reason: null, connection: "server_unreachable", notice: null };
|
|
1408
|
+
}
|
|
1409
|
+
const word = server?.exitReason ?? null;
|
|
1410
|
+
if (server !== void 0 && (server.sessionPhase === "ended" || server.meetingPhase === "ended" || word === "ended" || word === "time_limit")) {
|
|
1411
|
+
return { to: "ended", reason: word === "time_limit" ? "time_limit" : "ended", connection: "stable", notice: null };
|
|
1412
|
+
}
|
|
1413
|
+
if (word === "removed") return { to: "removed", reason: "removed", connection: "stable", notice: null };
|
|
1414
|
+
if (word === "displaced") return { to: "superseded", reason: "displaced", connection: "stable", notice: null };
|
|
1415
|
+
if (word === "sent_to_waiting") {
|
|
1416
|
+
return { to: "waiting:knocking", reason: "sent_to_waiting", connection: "stable", notice: "sent-to-waiting" };
|
|
1417
|
+
}
|
|
1418
|
+
if (hint === "DUPLICATE_IDENTITY") return { to: "superseded", reason: "displaced", connection: "stable", notice: null };
|
|
1419
|
+
if (hint === "PARTICIPANT_REMOVED" && word === null && server === void 0) {
|
|
1420
|
+
return { to: "removed", reason: "removed", connection: "stable", notice: null };
|
|
1421
|
+
}
|
|
1422
|
+
if (hint === "ROOM_DELETED" && server === void 0) {
|
|
1423
|
+
return { to: "ended", reason: "ended", connection: "stable", notice: null };
|
|
1424
|
+
}
|
|
1425
|
+
if (input.frozen === true) return { to: "inactive", reason: "inactive", connection: "stable", notice: null };
|
|
1426
|
+
return { to: "disconnected", reason: null, connection: "stable", notice: null };
|
|
1427
|
+
}
|
|
1428
|
+
|
|
1257
1429
|
// src/core/types.ts
|
|
1258
1430
|
var asMeetingId = (value) => value;
|
|
1259
1431
|
var asCallId = (value) => value;
|
|
@@ -1345,6 +1517,39 @@ function createCallCenter(options) {
|
|
|
1345
1517
|
clearRing(invite.id);
|
|
1346
1518
|
incoming.delete(invite.id);
|
|
1347
1519
|
if (outgoing !== null && outgoing.id === invite.id) outgoing = invite;
|
|
1520
|
+
const held = options.store.snapshot().call;
|
|
1521
|
+
if (held !== null && held.invite.id === invite.id && held.direction === "incoming") {
|
|
1522
|
+
const outcome = invite.state === "connecting" || invite.state === "active" ? "answered_elsewhere" : invite.state === "declined" ? "reset" : "call_missed";
|
|
1523
|
+
const moved = outcome === "reset" ? options.store.dispatch({ type: "reset" }) : options.store.dispatch({ type: "call_outcome", outcome });
|
|
1524
|
+
if (moved) options.store.patch({ call: outcome === "reset" ? null : { ...held, invite } });
|
|
1525
|
+
}
|
|
1526
|
+
options.onSettled?.(invite);
|
|
1527
|
+
}
|
|
1528
|
+
function settleOutgoing(invite) {
|
|
1529
|
+
if (outgoing === null || outgoing.id !== invite.id) return;
|
|
1530
|
+
clearRing(invite.id);
|
|
1531
|
+
outgoing = invite;
|
|
1532
|
+
const store = options.store;
|
|
1533
|
+
const held = store.snapshot().call;
|
|
1534
|
+
if (held !== null && held.invite.id === invite.id) store.patch({ call: { ...held, invite } });
|
|
1535
|
+
switch (invite.state) {
|
|
1536
|
+
case "connecting":
|
|
1537
|
+
case "active":
|
|
1538
|
+
if (store.dispatch({ type: "call_answered" })) options.onAnswered?.(invite);
|
|
1539
|
+
break;
|
|
1540
|
+
case "declined":
|
|
1541
|
+
store.dispatch({ type: "call_outcome", outcome: "call_declined" });
|
|
1542
|
+
break;
|
|
1543
|
+
case "busy":
|
|
1544
|
+
store.dispatch({ type: "call_outcome", outcome: "call_busy" });
|
|
1545
|
+
break;
|
|
1546
|
+
case "missed":
|
|
1547
|
+
case "failed":
|
|
1548
|
+
store.dispatch({ type: "call_outcome", outcome: "call_missed" });
|
|
1549
|
+
break;
|
|
1550
|
+
default:
|
|
1551
|
+
break;
|
|
1552
|
+
}
|
|
1348
1553
|
options.onSettled?.(invite);
|
|
1349
1554
|
}
|
|
1350
1555
|
function ingest(invite) {
|
|
@@ -1353,7 +1558,7 @@ function createCallCenter(options) {
|
|
|
1353
1558
|
if (identity.userId === null) return;
|
|
1354
1559
|
if (invite.callerUserId === identity.userId) return;
|
|
1355
1560
|
const phase = options.store.snapshot().phase;
|
|
1356
|
-
if (phase
|
|
1561
|
+
if (isLivePhase(phase) || phase === "ringing_out") {
|
|
1357
1562
|
void repository.settleCallInvite(invite.id, "busy", null).then((settled) => {
|
|
1358
1563
|
to(settled.callerUserId).send(MEET_EVENTS.settled, settled);
|
|
1359
1564
|
}).catch((error) => {
|
|
@@ -1366,6 +1571,9 @@ function createCallCenter(options) {
|
|
|
1366
1571
|
return;
|
|
1367
1572
|
}
|
|
1368
1573
|
incoming.set(invite.id, { ...invite, state: "ringing" });
|
|
1574
|
+
if (options.store.snapshot().call === null && options.store.dispatch({ type: "ring_in" })) {
|
|
1575
|
+
options.store.patch({ call: { invite: { ...invite, state: "ringing" }, direction: "incoming" } });
|
|
1576
|
+
}
|
|
1369
1577
|
options.onIncoming?.(invite);
|
|
1370
1578
|
timeouts.set(
|
|
1371
1579
|
invite.id,
|
|
@@ -1403,6 +1611,7 @@ function createCallCenter(options) {
|
|
|
1403
1611
|
const invite = message.data;
|
|
1404
1612
|
const held = incoming.get(invite.id);
|
|
1405
1613
|
if (held !== void 0) settleLocal(invite);
|
|
1614
|
+
else if (outgoing?.id === invite.id) settleOutgoing(invite);
|
|
1406
1615
|
}
|
|
1407
1616
|
}
|
|
1408
1617
|
],
|
|
@@ -1469,6 +1678,9 @@ function createCallCenter(options) {
|
|
|
1469
1678
|
expiresAt: new Date(timers.now() + ringTimeoutMs).toISOString()
|
|
1470
1679
|
});
|
|
1471
1680
|
outgoing = invite;
|
|
1681
|
+
if (options.store.dispatch({ type: "ring_out" })) {
|
|
1682
|
+
options.store.patch({ call: { invite, direction: "outgoing" } });
|
|
1683
|
+
}
|
|
1472
1684
|
for (const callee of people) {
|
|
1473
1685
|
to(callee).send(MEET_EVENTS.ring, invite);
|
|
1474
1686
|
}
|
|
@@ -1477,8 +1689,7 @@ function createCallCenter(options) {
|
|
|
1477
1689
|
timers.setTimeout(() => {
|
|
1478
1690
|
if (outgoing?.id !== invite.id) return;
|
|
1479
1691
|
void repository.settleCallInvite(invite.id, "missed", null).then((settled) => {
|
|
1480
|
-
|
|
1481
|
-
options.onSettled?.(settled);
|
|
1692
|
+
settleOutgoing(settled);
|
|
1482
1693
|
}).catch(() => void 0);
|
|
1483
1694
|
}, ringTimeoutMs)
|
|
1484
1695
|
);
|
|
@@ -1493,7 +1704,9 @@ function createCallCenter(options) {
|
|
|
1493
1704
|
"A late accept must not resurrect a settled call. Close the ringing UI; the caller has already moved on."
|
|
1494
1705
|
);
|
|
1495
1706
|
}
|
|
1707
|
+
if (options.store.snapshot().phase === "ringing_in") options.store.dispatch({ type: "call_answered" });
|
|
1496
1708
|
const settled = await repository.settleCallInvite(id, "connecting", null);
|
|
1709
|
+
options.store.patch({ call: { invite: settled, direction: "incoming" } });
|
|
1497
1710
|
settleLocal(settled);
|
|
1498
1711
|
channel?.send(MEET_EVENTS.settled, settled);
|
|
1499
1712
|
to(settled.callerUserId).send(MEET_EVENTS.settled, { ...settled, mode });
|
|
@@ -1501,6 +1714,9 @@ function createCallCenter(options) {
|
|
|
1501
1714
|
},
|
|
1502
1715
|
async decline(id, message) {
|
|
1503
1716
|
const settled = await repository.settleCallInvite(id, "declined", message ?? null);
|
|
1717
|
+
if (options.store.snapshot().call?.invite.id === id && options.store.dispatch({ type: "reset" })) {
|
|
1718
|
+
options.store.patch({ call: null });
|
|
1719
|
+
}
|
|
1504
1720
|
settleLocal(settled);
|
|
1505
1721
|
channel?.send(MEET_EVENTS.settled, settled);
|
|
1506
1722
|
to(settled.callerUserId).send(MEET_EVENTS.settled, settled);
|
|
@@ -1510,6 +1726,9 @@ function createCallCenter(options) {
|
|
|
1510
1726
|
const settled = await repository.settleCallInvite(id, "cancelled", null);
|
|
1511
1727
|
clearRing(id);
|
|
1512
1728
|
if (outgoing?.id === id) outgoing = settled;
|
|
1729
|
+
if (options.store.snapshot().call?.invite.id === id && options.store.dispatch({ type: "reset" })) {
|
|
1730
|
+
options.store.patch({ call: null });
|
|
1731
|
+
}
|
|
1513
1732
|
for (const callee of settled.calleeUserIds) {
|
|
1514
1733
|
to(callee).send(MEET_EVENTS.cancel, settled);
|
|
1515
1734
|
}
|
|
@@ -1541,7 +1760,9 @@ var TABLES = {
|
|
|
1541
1760
|
/** Wave 1 (0.8): who a meeting was sent to, and what they answered. */
|
|
1542
1761
|
invitees: "meet_invitees",
|
|
1543
1762
|
/** Wave 1 (0.8): one occurrence of a series cancelled or moved. */
|
|
1544
|
-
occurrenceOverrides: "meet_occurrence_overrides"
|
|
1763
|
+
occurrenceOverrides: "meet_occurrence_overrides",
|
|
1764
|
+
/** S5: one row per RUN of a meeting; carries that run's note-taker state. */
|
|
1765
|
+
sessions: "meet_sessions"
|
|
1545
1766
|
};
|
|
1546
1767
|
var RPCS = {
|
|
1547
1768
|
/** Atomic: create the invite row and stamp its expiry in one statement. */
|
|
@@ -3022,8 +3243,15 @@ var NO_GRANTS = {
|
|
|
3022
3243
|
canPublish: false,
|
|
3023
3244
|
canSubscribe: false
|
|
3024
3245
|
};
|
|
3246
|
+
var NO_SHARE = { state: "none", reason: null, remedy: null, at: 0 };
|
|
3025
3247
|
var EMPTY = {
|
|
3026
|
-
phase: "
|
|
3248
|
+
phase: "resolving",
|
|
3249
|
+
reason: null,
|
|
3250
|
+
phaseNotice: null,
|
|
3251
|
+
roomName: null,
|
|
3252
|
+
connection: "stable",
|
|
3253
|
+
share: NO_SHARE,
|
|
3254
|
+
call: null,
|
|
3027
3255
|
waiting: null,
|
|
3028
3256
|
meeting: null,
|
|
3029
3257
|
localIdentity: null,
|
|
@@ -3087,8 +3315,20 @@ function createMeetStore(initial = {}) {
|
|
|
3087
3315
|
return () => listeners.delete(listener);
|
|
3088
3316
|
},
|
|
3089
3317
|
patch(next) {
|
|
3318
|
+
if ("phase" in next || "reason" in next || "phaseNotice" in next) {
|
|
3319
|
+
throw new TypeError("meet store: the phase moves only through store.dispatch(event)");
|
|
3320
|
+
}
|
|
3090
3321
|
commit({ ...state, ...next });
|
|
3091
3322
|
},
|
|
3323
|
+
dispatch(event, detail) {
|
|
3324
|
+
const to = nextPhase(state.phase, event);
|
|
3325
|
+
if (to === null) return false;
|
|
3326
|
+
const reason = detail?.reason !== void 0 ? detail.reason : reasonOf(to);
|
|
3327
|
+
const phaseNotice = detail?.notice ?? null;
|
|
3328
|
+
if (to === state.phase && reason === state.reason && phaseNotice === state.phaseNotice) return true;
|
|
3329
|
+
commit({ ...state, phase: to, reason, phaseNotice });
|
|
3330
|
+
return true;
|
|
3331
|
+
},
|
|
3092
3332
|
setParticipants(participants) {
|
|
3093
3333
|
const names = learnNames(state.names, participants);
|
|
3094
3334
|
const hands = new Map(state.participants.map((p) => [p.identity, p.handRaised]));
|
|
@@ -4082,7 +4322,8 @@ function createLiveKitDriver(handlers, options = {}) {
|
|
|
4082
4322
|
}).on(RoomEvent.Disconnected, (reason) => {
|
|
4083
4323
|
audioContainer?.remove();
|
|
4084
4324
|
audioContainer = null;
|
|
4085
|
-
|
|
4325
|
+
const named = reason === void 0 ? null : module2?.DisconnectReason?.[reason] ?? String(reason);
|
|
4326
|
+
handlers.disconnected(named);
|
|
4086
4327
|
});
|
|
4087
4328
|
try {
|
|
4088
4329
|
created.registerTextStreamHandler(TRANSCRIPTION_TOPIC, (reader, participantInfo) => {
|
|
@@ -4430,7 +4671,7 @@ function createMeetingSession(options) {
|
|
|
4430
4671
|
}
|
|
4431
4672
|
function apply(read) {
|
|
4432
4673
|
const snapshot = store.snapshot();
|
|
4433
|
-
if (snapshot.phase
|
|
4674
|
+
if (!isWaitingPhase(snapshot.phase)) return;
|
|
4434
4675
|
const admission = read.admission_state ?? null;
|
|
4435
4676
|
const ended = admission === "ended" || read.session_phase === "ended" || read.meeting_phase === "ended";
|
|
4436
4677
|
if (admission === "admitted" && !ended) {
|
|
@@ -4447,6 +4688,7 @@ function createMeetingSession(options) {
|
|
|
4447
4688
|
if (read.meeting_phase === "ended" && meeting !== null && meeting.endedAt === null) {
|
|
4448
4689
|
store.patch({ meeting: { ...meeting, endedAt: (/* @__PURE__ */ new Date()).toISOString() } });
|
|
4449
4690
|
}
|
|
4691
|
+
store.dispatch({ type: "admission", admission: "ended" }, { reason: "ended" });
|
|
4450
4692
|
return;
|
|
4451
4693
|
}
|
|
4452
4694
|
if (admission === null) return;
|
|
@@ -4458,6 +4700,7 @@ function createMeetingSession(options) {
|
|
|
4458
4700
|
pollSeconds: read.poll_seconds ?? snapshot.waiting?.pollSeconds ?? 3,
|
|
4459
4701
|
liveVersion: read.live_version ?? 0
|
|
4460
4702
|
});
|
|
4703
|
+
store.dispatch({ type: "admission", admission });
|
|
4461
4704
|
if (admission === "denied" || admission === "expired" || admission === "withdrawn" || admission === "removed") {
|
|
4462
4705
|
stopWaiting();
|
|
4463
4706
|
}
|
|
@@ -4553,7 +4796,7 @@ function createMeetingSession(options) {
|
|
|
4553
4796
|
// 🚨 PAYLOAD-FREE. Every receiver reads again; a spoofed hint only causes a read.
|
|
4554
4797
|
event: MEET_EVENTS.stateChanged,
|
|
4555
4798
|
onMessage: () => {
|
|
4556
|
-
if (store.snapshot().phase
|
|
4799
|
+
if (isWaitingPhase(store.snapshot().phase)) void readState2();
|
|
4557
4800
|
void refreshQueue();
|
|
4558
4801
|
}
|
|
4559
4802
|
}
|
|
@@ -4565,7 +4808,7 @@ function createMeetingSession(options) {
|
|
|
4565
4808
|
if (meeting === null) return;
|
|
4566
4809
|
const fresh = isGuest(identity) ? await repository.meetingBySlug(meeting.slug) : await readMeeting(meeting.id);
|
|
4567
4810
|
store.patch({ meeting: fresh, locked: fresh.locked });
|
|
4568
|
-
if (store.snapshot().phase
|
|
4811
|
+
if (isWaitingPhase(store.snapshot().phase)) void readState2();
|
|
4569
4812
|
}
|
|
4570
4813
|
});
|
|
4571
4814
|
},
|
|
@@ -4732,10 +4975,34 @@ function createMeetingSession(options) {
|
|
|
4732
4975
|
},
|
|
4733
4976
|
stopWaiting,
|
|
4734
4977
|
readState: readState2,
|
|
4978
|
+
async readExit(connection) {
|
|
4979
|
+
const meeting = store.snapshot().meeting;
|
|
4980
|
+
const pass = options.resolvePass?.() ?? null;
|
|
4981
|
+
if (meeting === null || pass === null) return void 0;
|
|
4982
|
+
try {
|
|
4983
|
+
const response = await options.api.request({
|
|
4984
|
+
path: `${MEET_ROUTES.state}?meeting_id=${encodeURIComponent(meeting.id)}&connection=${encodeURIComponent(connection)}`,
|
|
4985
|
+
method: "GET",
|
|
4986
|
+
requireAuth: false,
|
|
4987
|
+
operation: "meet.state(exit)",
|
|
4988
|
+
headers: { [MEETING_PASS_HEADER]: pass }
|
|
4989
|
+
});
|
|
4990
|
+
if (!response.ok) return null;
|
|
4991
|
+
const read = await response.json();
|
|
4992
|
+
return {
|
|
4993
|
+
exitReason: read.exit_reason ?? null,
|
|
4994
|
+
sessionPhase: read.session_phase ?? null,
|
|
4995
|
+
meetingPhase: read.meeting_phase ?? null
|
|
4996
|
+
};
|
|
4997
|
+
} catch {
|
|
4998
|
+
return null;
|
|
4999
|
+
}
|
|
5000
|
+
},
|
|
4735
5001
|
async withdraw() {
|
|
4736
5002
|
stopWaiting();
|
|
4737
5003
|
await postLeave("withdraw");
|
|
4738
5004
|
patchWaiting({ admission: "withdrawn" });
|
|
5005
|
+
store.dispatch({ type: "admission", admission: "withdrawn" });
|
|
4739
5006
|
hint();
|
|
4740
5007
|
},
|
|
4741
5008
|
async askAgain() {
|
|
@@ -5359,6 +5626,9 @@ async function pushMeetingToGoogleCalendar(api, meetingId, target) {
|
|
|
5359
5626
|
}
|
|
5360
5627
|
|
|
5361
5628
|
// src/core/room.ts
|
|
5629
|
+
function SCREEN_SHARE_BLOCKED_REMEDY_FOR(remedy) {
|
|
5630
|
+
return /administrator|policy/i.test(remedy) ? remedy : SCREEN_SHARE_BLOCKED_REMEDY;
|
|
5631
|
+
}
|
|
5362
5632
|
var PARTICIPANT_ROLE_ATTRIBUTE = "matrx.participant.role";
|
|
5363
5633
|
var PARTICIPANT_CAN_RECORD_ATTRIBUTE = "matrx.participant.can_record";
|
|
5364
5634
|
var PARTICIPANT_STANDING_ATTRIBUTE = "matrx.participant.standing";
|
|
@@ -5426,7 +5696,7 @@ function createRoomEngine(options) {
|
|
|
5426
5696
|
let disposed = false;
|
|
5427
5697
|
let moving = false;
|
|
5428
5698
|
const confirmingEnds = /* @__PURE__ */ new WeakSet();
|
|
5429
|
-
async function
|
|
5699
|
+
async function dropRoom() {
|
|
5430
5700
|
const target = driver;
|
|
5431
5701
|
driver = null;
|
|
5432
5702
|
if (current !== null) {
|
|
@@ -5435,9 +5705,14 @@ function createRoomEngine(options) {
|
|
|
5435
5705
|
}
|
|
5436
5706
|
store.setLocalTrack("microphone", IDLE_TRACK);
|
|
5437
5707
|
store.setLocalTrack("camera", IDLE_TRACK);
|
|
5438
|
-
store.patch({
|
|
5708
|
+
store.patch({ share: NO_SHARE, connection: "stable" });
|
|
5439
5709
|
await target?.disconnect();
|
|
5440
5710
|
}
|
|
5711
|
+
async function leaveRoom() {
|
|
5712
|
+
store.dispatch({ type: "leave" });
|
|
5713
|
+
await dropRoom();
|
|
5714
|
+
options.onLeft?.(null);
|
|
5715
|
+
}
|
|
5441
5716
|
async function confirmMeetingEnd() {
|
|
5442
5717
|
const meeting = store.snapshot().meeting;
|
|
5443
5718
|
const target = driver;
|
|
@@ -5459,7 +5734,9 @@ function createRoomEngine(options) {
|
|
|
5459
5734
|
const latest = store.snapshot().meeting;
|
|
5460
5735
|
if (latest === null) return;
|
|
5461
5736
|
store.patch({ meeting: { ...latest, endedAt: verified.endedAt } });
|
|
5462
|
-
|
|
5737
|
+
store.dispatch({ type: "ended" }, { reason: "ended" });
|
|
5738
|
+
await dropRoom();
|
|
5739
|
+
options.onLeft?.("ended");
|
|
5463
5740
|
} catch (error) {
|
|
5464
5741
|
report("error", `Meet could not confirm or finish meeting teardown: ${String(error)}`, "Check the meeting link again; if media remains active, close this meeting tab.");
|
|
5465
5742
|
} finally {
|
|
@@ -5471,12 +5748,12 @@ function createRoomEngine(options) {
|
|
|
5471
5748
|
options.onDiagnostic?.(remedy === void 0 ? { level, message } : { level, message, remedy });
|
|
5472
5749
|
}
|
|
5473
5750
|
let ambiguousShareDenials = 0;
|
|
5474
|
-
function
|
|
5751
|
+
function failJoin(error, operation) {
|
|
5475
5752
|
const normalized = normalizeMeetError(error, operation);
|
|
5476
5753
|
store.patch({
|
|
5477
|
-
phase: "failed",
|
|
5478
5754
|
failure: { message: normalized.message, remedy: normalized.remedy, reason: normalized.reason }
|
|
5479
5755
|
});
|
|
5756
|
+
store.dispatch({ type: "join_failed", reason: normalized.reason ?? null });
|
|
5480
5757
|
report(
|
|
5481
5758
|
normalized.code === "session-unavailable" ? "warn" : "error",
|
|
5482
5759
|
normalized.message,
|
|
@@ -5484,6 +5761,14 @@ function createRoomEngine(options) {
|
|
|
5484
5761
|
);
|
|
5485
5762
|
return normalized;
|
|
5486
5763
|
}
|
|
5764
|
+
async function lostRoom(error, operation) {
|
|
5765
|
+
const normalized = normalizeMeetError(error, operation);
|
|
5766
|
+
store.patch({ failure: { message: normalized.message, remedy: normalized.remedy, reason: normalized.reason } });
|
|
5767
|
+
await dropRoom();
|
|
5768
|
+
store.dispatch({ type: "exit", to: "disconnected" });
|
|
5769
|
+
report("error", normalized.message, normalized.remedy);
|
|
5770
|
+
return normalized;
|
|
5771
|
+
}
|
|
5487
5772
|
const handlers = {
|
|
5488
5773
|
participants(list) {
|
|
5489
5774
|
const joinedAt = new Date(now()).toISOString();
|
|
@@ -5526,9 +5811,12 @@ function createRoomEngine(options) {
|
|
|
5526
5811
|
store.setQuality(asParticipantIdentity(who), value);
|
|
5527
5812
|
},
|
|
5528
5813
|
connectionState(state) {
|
|
5529
|
-
if (state === "connected")
|
|
5530
|
-
|
|
5531
|
-
|
|
5814
|
+
if (state === "connected") {
|
|
5815
|
+
if (store.snapshot().connection !== "stable") store.patch({ connection: "stable" });
|
|
5816
|
+
store.dispatch({ type: "connected" });
|
|
5817
|
+
} else if (state === "reconnecting") {
|
|
5818
|
+
store.patch({ connection: "reconnecting" });
|
|
5819
|
+
}
|
|
5532
5820
|
},
|
|
5533
5821
|
transcription(event) {
|
|
5534
5822
|
const snapshot = store.snapshot();
|
|
@@ -5655,17 +5943,48 @@ function createRoomEngine(options) {
|
|
|
5655
5943
|
}
|
|
5656
5944
|
},
|
|
5657
5945
|
disconnected(reason) {
|
|
5658
|
-
if (moving) return;
|
|
5659
|
-
|
|
5660
|
-
tokens.invalidate(current.roomName);
|
|
5661
|
-
current = null;
|
|
5662
|
-
}
|
|
5663
|
-
store.patch({ phase: "left" });
|
|
5664
|
-
options.onLeft?.(reason);
|
|
5946
|
+
if (moving || driver === null) return;
|
|
5947
|
+
void resolveExitAndApply(reason);
|
|
5665
5948
|
}
|
|
5666
5949
|
};
|
|
5950
|
+
async function resolveExitAndApply(hint) {
|
|
5951
|
+
const connection = current?.identity ?? store.snapshot().localIdentity ?? null;
|
|
5952
|
+
await dropRoom();
|
|
5953
|
+
let server;
|
|
5954
|
+
if (options.readExit === void 0 || connection === null || store.snapshot().meeting === null) {
|
|
5955
|
+
server = void 0;
|
|
5956
|
+
} else {
|
|
5957
|
+
try {
|
|
5958
|
+
server = await options.readExit(connection);
|
|
5959
|
+
} catch {
|
|
5960
|
+
server = null;
|
|
5961
|
+
}
|
|
5962
|
+
}
|
|
5963
|
+
if (disposed) return;
|
|
5964
|
+
const resolved = resolveExit({ server, hint, frozen: options.wasFrozen?.() ?? false });
|
|
5965
|
+
store.patch({ connection: resolved.connection });
|
|
5966
|
+
if (resolved.to === "waiting:knocking") {
|
|
5967
|
+
store.patch({
|
|
5968
|
+
waiting: {
|
|
5969
|
+
admission: "knocking",
|
|
5970
|
+
admittersPresent: null,
|
|
5971
|
+
reknockAllowed: true,
|
|
5972
|
+
knockExpiresAt: null,
|
|
5973
|
+
pollSeconds: store.snapshot().waiting?.pollSeconds ?? 3,
|
|
5974
|
+
liveVersion: 0
|
|
5975
|
+
}
|
|
5976
|
+
});
|
|
5977
|
+
}
|
|
5978
|
+
store.dispatch({ type: "exit", to: resolved.to }, { reason: resolved.reason, notice: resolved.notice });
|
|
5979
|
+
report(
|
|
5980
|
+
resolved.to === "disconnected" ? "warn" : "info",
|
|
5981
|
+
`meet: the room connection ended (${hint ?? "no LiveKit reason"}) \u2192 ${resolved.to}`,
|
|
5982
|
+
resolved.to === "disconnected" ? "Press Rejoin; the meeting is still going." : "The screen says what happened."
|
|
5983
|
+
);
|
|
5984
|
+
options.onLeft?.(hint);
|
|
5985
|
+
}
|
|
5667
5986
|
async function connect(request) {
|
|
5668
|
-
store.patch({
|
|
5987
|
+
store.patch({ failure: null, waiting: null, roomName: request.roomName, share: NO_SHARE, connection: "stable" });
|
|
5669
5988
|
const token = await tokens.get({
|
|
5670
5989
|
roomName: request.roomName,
|
|
5671
5990
|
identity,
|
|
@@ -5688,10 +6007,10 @@ function createRoomEngine(options) {
|
|
|
5688
6007
|
}
|
|
5689
6008
|
});
|
|
5690
6009
|
if (token.lobby || !token.canSubscribe) {
|
|
6010
|
+
const admission = token.admissionState !== void 0 && token.admissionState !== "admitted" ? token.admissionState : "knocking";
|
|
5691
6011
|
store.patch({
|
|
5692
|
-
phase: "lobby",
|
|
5693
6012
|
waiting: {
|
|
5694
|
-
admission
|
|
6013
|
+
admission,
|
|
5695
6014
|
admittersPresent: null,
|
|
5696
6015
|
reknockAllowed: true,
|
|
5697
6016
|
knockExpiresAt: null,
|
|
@@ -5699,9 +6018,10 @@ function createRoomEngine(options) {
|
|
|
5699
6018
|
liveVersion: 0
|
|
5700
6019
|
}
|
|
5701
6020
|
});
|
|
6021
|
+
store.dispatch({ type: "admission", admission });
|
|
5702
6022
|
return;
|
|
5703
6023
|
}
|
|
5704
|
-
store.patch({
|
|
6024
|
+
store.patch({ waiting: null });
|
|
5705
6025
|
const created = await options.driverFactory(handlers);
|
|
5706
6026
|
if (disposed) {
|
|
5707
6027
|
await created.disconnect();
|
|
@@ -5709,7 +6029,8 @@ function createRoomEngine(options) {
|
|
|
5709
6029
|
}
|
|
5710
6030
|
driver = created;
|
|
5711
6031
|
await created.connect(token.serverUrl, token.token);
|
|
5712
|
-
store.patch({
|
|
6032
|
+
store.patch({ failure: null, connection: "stable" });
|
|
6033
|
+
store.dispatch({ type: "connected" });
|
|
5713
6034
|
store.setLocalTrack("microphone", IDLE_TRACK);
|
|
5714
6035
|
store.setLocalTrack("camera", IDLE_TRACK);
|
|
5715
6036
|
const effects = options.effectsStorage?.load() ?? store.snapshot().effects;
|
|
@@ -5780,9 +6101,17 @@ function createRoomEngine(options) {
|
|
|
5780
6101
|
return {
|
|
5781
6102
|
join(request) {
|
|
5782
6103
|
if (joining !== null) return joining;
|
|
6104
|
+
if (store.snapshot().phase !== "joining" && !store.dispatch({ type: "join", click: true })) {
|
|
6105
|
+
report(
|
|
6106
|
+
"warn",
|
|
6107
|
+
`meet.join: cannot join from "${store.snapshot().phase}"`,
|
|
6108
|
+
"Join is offered from the pre-join, left, disconnected and replaced screens only."
|
|
6109
|
+
);
|
|
6110
|
+
return Promise.resolve();
|
|
6111
|
+
}
|
|
5783
6112
|
lastRequest = request;
|
|
5784
6113
|
joining = connect(request).catch((error) => {
|
|
5785
|
-
throw
|
|
6114
|
+
throw failJoin(error, "meet.join");
|
|
5786
6115
|
}).finally(() => {
|
|
5787
6116
|
joining = null;
|
|
5788
6117
|
});
|
|
@@ -5799,10 +6128,16 @@ function createRoomEngine(options) {
|
|
|
5799
6128
|
return;
|
|
5800
6129
|
}
|
|
5801
6130
|
if (joining !== null) return joining;
|
|
6131
|
+
const phase = store.snapshot().phase;
|
|
6132
|
+
const moved = phase === "joining" || store.dispatch({ type: "join", click: true }) || store.dispatch({ type: "admitted" });
|
|
6133
|
+
if (!moved) {
|
|
6134
|
+
report("warn", `meet.rejoin: cannot rejoin from "${phase}"`, "Rejoin is offered after leaving, a lost connection, or admission.");
|
|
6135
|
+
return;
|
|
6136
|
+
}
|
|
5802
6137
|
tokens.invalidate(request.roomName);
|
|
5803
6138
|
current = null;
|
|
5804
6139
|
joining = connect(request).catch((error) => {
|
|
5805
|
-
throw
|
|
6140
|
+
throw failJoin(error, "meet.rejoin");
|
|
5806
6141
|
}).finally(() => {
|
|
5807
6142
|
joining = null;
|
|
5808
6143
|
});
|
|
@@ -5847,11 +6182,11 @@ function createRoomEngine(options) {
|
|
|
5847
6182
|
joining = connect(lastRequest).finally(() => {
|
|
5848
6183
|
joining = null;
|
|
5849
6184
|
});
|
|
5850
|
-
await joining.catch((again) => {
|
|
5851
|
-
throw
|
|
6185
|
+
await joining.catch(async (again) => {
|
|
6186
|
+
throw await lostRoom(again, "meet.moveToBreakout");
|
|
5852
6187
|
});
|
|
5853
6188
|
} else {
|
|
5854
|
-
throw
|
|
6189
|
+
throw await lostRoom(error, "meet.moveToBreakout");
|
|
5855
6190
|
}
|
|
5856
6191
|
throw normalized;
|
|
5857
6192
|
} finally {
|
|
@@ -5859,6 +6194,9 @@ function createRoomEngine(options) {
|
|
|
5859
6194
|
}
|
|
5860
6195
|
},
|
|
5861
6196
|
leave: leaveRoom,
|
|
6197
|
+
backToPrejoin() {
|
|
6198
|
+
store.dispatch({ type: "back_to_prejoin", click: true });
|
|
6199
|
+
},
|
|
5862
6200
|
// Turning a device on mid-meeting is the SAME operation as turning it on
|
|
5863
6201
|
// during the join, so it runs the same function. A failure here used to
|
|
5864
6202
|
// stamp the room `failed` — a busy microphone would blank a live meeting.
|
|
@@ -5872,21 +6210,41 @@ function createRoomEngine(options) {
|
|
|
5872
6210
|
},
|
|
5873
6211
|
async setScreenShareEnabled(enabled) {
|
|
5874
6212
|
if (driver === null) return;
|
|
6213
|
+
if (enabled && driver.supportsScreenShare?.() === false) {
|
|
6214
|
+
store.patch({ share: { state: "refused", reason: "unsupported", remedy: null, at: now() } });
|
|
6215
|
+
report("warn", "meet: this browser cannot share a screen", "Share from a desktop browser (Chrome, Edge, Firefox or Safari).");
|
|
6216
|
+
return;
|
|
6217
|
+
}
|
|
6218
|
+
if (enabled) store.patch({ share: { state: "picking", reason: null, remedy: null, at: now() } });
|
|
5875
6219
|
try {
|
|
5876
6220
|
await driver.setScreenShareEnabled(enabled);
|
|
5877
6221
|
ambiguousShareDenials = 0;
|
|
6222
|
+
store.patch({ share: { state: enabled ? "presenting" : "none", reason: null, remedy: null, at: now() } });
|
|
5878
6223
|
} catch (error) {
|
|
5879
6224
|
const kind = classifyScreenShareError(error);
|
|
5880
6225
|
if (kind === "ambiguous") {
|
|
5881
6226
|
ambiguousShareDenials += 1;
|
|
5882
|
-
if (ambiguousShareDenials < 2)
|
|
6227
|
+
if (ambiguousShareDenials < 2) {
|
|
6228
|
+
store.patch({ share: NO_SHARE });
|
|
6229
|
+
return;
|
|
6230
|
+
}
|
|
5883
6231
|
}
|
|
6232
|
+
ambiguousShareDenials = 0;
|
|
5884
6233
|
const normalized = normalizeScreenShareError(error, "meet.setScreenShareEnabled");
|
|
5885
6234
|
report("warn", normalized.message, normalized.remedy);
|
|
5886
|
-
|
|
5887
|
-
|
|
6235
|
+
store.patch({
|
|
6236
|
+
share: {
|
|
6237
|
+
state: "refused",
|
|
6238
|
+
reason: kind === "other" ? "failed" : "blocked",
|
|
6239
|
+
remedy: kind === "other" ? normalized.remedy : SCREEN_SHARE_BLOCKED_REMEDY_FOR(normalized.remedy),
|
|
6240
|
+
at: now()
|
|
6241
|
+
}
|
|
6242
|
+
});
|
|
5888
6243
|
}
|
|
5889
6244
|
},
|
|
6245
|
+
dismissShareNotice() {
|
|
6246
|
+
if (store.snapshot().share.state === "refused") store.patch({ share: NO_SHARE });
|
|
6247
|
+
},
|
|
5890
6248
|
async raiseHand(raised) {
|
|
5891
6249
|
const local = store.snapshot().localIdentity;
|
|
5892
6250
|
if (local !== null) store.setHand(local, raised);
|
|
@@ -6853,28 +7211,6 @@ function createMeetingRecordCache(options = {}) {
|
|
|
6853
7211
|
};
|
|
6854
7212
|
}
|
|
6855
7213
|
|
|
6856
|
-
// src/core/reasons.ts
|
|
6857
|
-
var JOIN_REFUSAL_REASONS = [
|
|
6858
|
-
"not_found",
|
|
6859
|
-
"cancelled",
|
|
6860
|
-
"ended",
|
|
6861
|
-
"expired",
|
|
6862
|
-
"too_early",
|
|
6863
|
-
"sign_in_required",
|
|
6864
|
-
"wrong_account",
|
|
6865
|
-
"not_invited",
|
|
6866
|
-
"locked",
|
|
6867
|
-
"removed",
|
|
6868
|
-
"lobby_rejects",
|
|
6869
|
-
"meeting_full",
|
|
6870
|
-
"platform_capacity",
|
|
6871
|
-
"verification_required",
|
|
6872
|
-
"registration_required"
|
|
6873
|
-
];
|
|
6874
|
-
function isJoinRefusalReason(value) {
|
|
6875
|
-
return typeof value === "string" && JOIN_REFUSAL_REASONS.includes(value);
|
|
6876
|
-
}
|
|
6877
|
-
|
|
6878
7214
|
// src/core/reactions.ts
|
|
6879
7215
|
var MEET_REACTIONS = ["\u{1F496}", "\u{1F44D}", "\u{1F389}", "\u{1F44F}", "\u{1F602}", "\u{1F62E}", "\u{1F622}", "\u{1F914}", "\u{1F44E}"];
|
|
6880
7216
|
|
|
@@ -6973,43 +7309,12 @@ function endedRecord(snapshot, given) {
|
|
|
6973
7309
|
function observedPhase(input) {
|
|
6974
7310
|
const { snapshot } = input;
|
|
6975
7311
|
if (snapshot === null) return "resolving";
|
|
6976
|
-
const
|
|
6977
|
-
|
|
6978
|
-
|
|
6979
|
-
const reason = raw === "failed" ? snapshot.failure?.reason ?? null : null;
|
|
6980
|
-
if (reason !== null) return reason === "ended" ? "ended" : `refused:${reason}`;
|
|
6981
|
-
switch (raw) {
|
|
6982
|
-
case "idle":
|
|
6983
|
-
case "failed":
|
|
6984
|
-
case "left":
|
|
6985
|
-
return "prejoin";
|
|
6986
|
-
case "lobby":
|
|
6987
|
-
return waitingPhase(snapshot);
|
|
6988
|
-
case "requesting-token":
|
|
6989
|
-
case "connecting":
|
|
6990
|
-
return "joining";
|
|
6991
|
-
case "connected":
|
|
6992
|
-
case "reconnecting":
|
|
6993
|
-
return "in_call";
|
|
6994
|
-
}
|
|
7312
|
+
const phase = snapshot.phase;
|
|
7313
|
+
if (endedRecord(snapshot, input.meeting ?? null) && !isLivePhase(phase) && !isCallPhase(phase)) return "ended";
|
|
7314
|
+
return phase;
|
|
6995
7315
|
}
|
|
6996
|
-
function
|
|
6997
|
-
|
|
6998
|
-
case "waiting_host":
|
|
6999
|
-
return "waiting:host_not_started";
|
|
7000
|
-
case "denied":
|
|
7001
|
-
return "denied";
|
|
7002
|
-
case "expired":
|
|
7003
|
-
return "knock_expired";
|
|
7004
|
-
case "withdrawn":
|
|
7005
|
-
return "left";
|
|
7006
|
-
case "ended":
|
|
7007
|
-
return "ended";
|
|
7008
|
-
case "removed":
|
|
7009
|
-
return "refused:removed";
|
|
7010
|
-
default:
|
|
7011
|
-
return "waiting:knocking";
|
|
7012
|
-
}
|
|
7316
|
+
function isCallPhase(phase) {
|
|
7317
|
+
return phase.startsWith("ringing_") || phase.startsWith("call_") || phase === "answered_elsewhere";
|
|
7013
7318
|
}
|
|
7014
7319
|
var ADMITTER_ROLES = /* @__PURE__ */ new Set(["host", "cohost"]);
|
|
7015
7320
|
function observe(input) {
|
|
@@ -7022,10 +7327,10 @@ function observe(input) {
|
|
|
7022
7327
|
const deviceInPlay = phase === "joining" || inCall;
|
|
7023
7328
|
return {
|
|
7024
7329
|
phase,
|
|
7025
|
-
reason: phase
|
|
7330
|
+
reason: phase === "ended" ? snapshot?.reason ?? null : snapshot?.reason ?? reasonOf(phase),
|
|
7026
7331
|
role,
|
|
7027
|
-
connection: snapshot?.
|
|
7028
|
-
hostPresent: inCall && snapshot !== null ? snapshot.participants.some((p) => ADMITTER_ROLES.has(p.role)) : snapshot
|
|
7332
|
+
connection: snapshot?.connection ?? "stable",
|
|
7333
|
+
hostPresent: inCall && snapshot !== null ? snapshot.participants.some((p) => ADMITTER_ROLES.has(p.role)) : snapshot !== null && isWaitingPhase(snapshot.phase) ? snapshot.waiting?.admittersPresent ?? null : null,
|
|
7029
7334
|
lobbyCount: canAdmit && snapshot !== null ? snapshot.lobby.filter((entry) => entry.state === "knocking").length : 0,
|
|
7030
7335
|
recording: snapshot?.recording === "recording" || snapshot?.recording === "stopping",
|
|
7031
7336
|
audioBlocked: null,
|