@ai-matrx/meet 0.11.35 → 0.11.37
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/core.cjs +99 -86
- package/dist/core.cjs.map +1 -1
- package/dist/core.d.cts +73 -22
- package/dist/core.d.ts +73 -22
- package/dist/core.js +99 -86
- package/dist/core.js.map +1 -1
- package/dist/index.cjs +99 -86
- 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 +99 -86
- package/dist/index.js.map +1 -1
- package/dist/react.cjs +213 -106
- package/dist/react.cjs.map +1 -1
- package/dist/react.d.cts +20 -4
- package/dist/react.d.ts +20 -4
- package/dist/react.js +213 -106
- package/dist/react.js.map +1 -1
- package/dist/skins/meet.cjs +126 -20
- package/dist/skins/meet.cjs.map +1 -1
- package/dist/skins/meet.js +126 -20
- package/dist/skins/meet.js.map +1 -1
- package/dist/styles.css +7 -0
- package/package.json +3 -3
package/dist/core.js
CHANGED
|
@@ -556,6 +556,30 @@ function mergeGhosts(live, ghosts, at) {
|
|
|
556
556
|
return { roster: [...live, ...extra], kept };
|
|
557
557
|
}
|
|
558
558
|
|
|
559
|
+
// src/core/leave.ts
|
|
560
|
+
var DEFAULT_LEAVE_POLICY = { hostLeavePrompt: "leave_or_end", endConfirm: false };
|
|
561
|
+
var PROMPTS = ["leave_or_end", "must_assign_or_end", "leave_only"];
|
|
562
|
+
function leavePolicyFrom(raw) {
|
|
563
|
+
if (typeof raw !== "object" || raw === null) return DEFAULT_LEAVE_POLICY;
|
|
564
|
+
const value = raw;
|
|
565
|
+
const prompt = value["host_leave_prompt"];
|
|
566
|
+
const confirm = value["end_confirm"];
|
|
567
|
+
return {
|
|
568
|
+
hostLeavePrompt: PROMPTS.includes(prompt) ? prompt : DEFAULT_LEAVE_POLICY.hostLeavePrompt,
|
|
569
|
+
endConfirm: typeof confirm === "boolean" ? confirm : DEFAULT_LEAVE_POLICY.endConfirm
|
|
570
|
+
};
|
|
571
|
+
}
|
|
572
|
+
function leaveChoices(args) {
|
|
573
|
+
if (args.role !== "host") return ["leave"];
|
|
574
|
+
switch (args.policy.hostLeavePrompt) {
|
|
575
|
+
case "must_assign_or_end":
|
|
576
|
+
return args.othersPresent ? ["assign_and_leave", "end_for_all"] : ["leave", "end_for_all"];
|
|
577
|
+
case "leave_only":
|
|
578
|
+
case "leave_or_end":
|
|
579
|
+
return ["leave", "end_for_all"];
|
|
580
|
+
}
|
|
581
|
+
}
|
|
582
|
+
|
|
559
583
|
// src/core/tokens.ts
|
|
560
584
|
function createWebRoomTokenStorage(onDiagnostic) {
|
|
561
585
|
const store = globalThis.localStorage;
|
|
@@ -747,7 +771,8 @@ function parseRoomToken(body, roomName) {
|
|
|
747
771
|
pollSeconds: typeof payload["poll_seconds"] === "number" ? payload["poll_seconds"] : void 0,
|
|
748
772
|
breakoutRoomId: readString(payload, "breakout_room_id") ?? null,
|
|
749
773
|
observersVisibleTo: readString(payload, "observers_visible_to") === "hosts" ? "hosts" : "everyone",
|
|
750
|
-
connectionPolicy: connectionPolicyFrom(payload["connection_policy"])
|
|
774
|
+
connectionPolicy: connectionPolicyFrom(payload["connection_policy"]),
|
|
775
|
+
leavePolicy: leavePolicyFrom(payload["leave_policy"])
|
|
751
776
|
};
|
|
752
777
|
}
|
|
753
778
|
function createTokenClient(options) {
|
|
@@ -3446,6 +3471,10 @@ var EMPTY = {
|
|
|
3446
3471
|
chatHistoryError: null,
|
|
3447
3472
|
reactions: [],
|
|
3448
3473
|
spotlight: null,
|
|
3474
|
+
actingHost: null,
|
|
3475
|
+
presenter: null,
|
|
3476
|
+
waitingCount: 0,
|
|
3477
|
+
leavePolicy: DEFAULT_LEAVE_POLICY,
|
|
3449
3478
|
moderationNotice: null,
|
|
3450
3479
|
actionNotice: null,
|
|
3451
3480
|
privateChatRequest: null,
|
|
@@ -3507,8 +3536,6 @@ function createMeetStore(initial = {}) {
|
|
|
3507
3536
|
},
|
|
3508
3537
|
setParticipants(participants) {
|
|
3509
3538
|
const names = learnNames(state.names, participants);
|
|
3510
|
-
const hands = new Map(state.participants.map((p) => [p.identity, p.handRaised]));
|
|
3511
|
-
const handTimes = new Map(state.participants.map((p) => [p.identity, p.handRaisedAt ?? null]));
|
|
3512
3539
|
const quality = new Map(state.participants.map((p) => [p.identity, p.quality]));
|
|
3513
3540
|
commit({
|
|
3514
3541
|
...state,
|
|
@@ -3521,8 +3548,6 @@ function createMeetStore(initial = {}) {
|
|
|
3521
3548
|
// identity could reach a screen, and it is the place that asks the
|
|
3522
3549
|
// name book. `roster-names.test.ts` fails if a token ever gets past it.
|
|
3523
3550
|
displayName: displayNameFor(names, participant.identity, participant.displayName),
|
|
3524
|
-
handRaised: hands.get(participant.identity) ?? participant.handRaised,
|
|
3525
|
-
handRaisedAt: handTimes.get(participant.identity) ?? participant.handRaisedAt ?? null,
|
|
3526
3551
|
quality: participant.quality === "unknown" ? quality.get(participant.identity) ?? "unknown" : participant.quality
|
|
3527
3552
|
}))
|
|
3528
3553
|
});
|
|
@@ -3545,20 +3570,6 @@ function createMeetStore(initial = {}) {
|
|
|
3545
3570
|
)
|
|
3546
3571
|
});
|
|
3547
3572
|
},
|
|
3548
|
-
setHand(identity, raised, at) {
|
|
3549
|
-
commit({
|
|
3550
|
-
...state,
|
|
3551
|
-
participants: state.participants.map(
|
|
3552
|
-
(participant) => participant.identity === identity ? {
|
|
3553
|
-
...participant,
|
|
3554
|
-
handRaised: raised,
|
|
3555
|
-
// A hand that is ALREADY up keeps its place in the queue when
|
|
3556
|
-
// it is re-announced (to a late joiner): the first time wins.
|
|
3557
|
-
handRaisedAt: raised ? participant.handRaised && participant.handRaisedAt != null ? participant.handRaisedAt : at ?? Date.now() : null
|
|
3558
|
-
} : participant
|
|
3559
|
-
)
|
|
3560
|
-
});
|
|
3561
|
-
},
|
|
3562
3573
|
addChat(message) {
|
|
3563
3574
|
if (state.chat.some((existing) => existing.id === message.id)) return;
|
|
3564
3575
|
const chat = [...state.chat, message];
|
|
@@ -3707,18 +3718,6 @@ var ROOM_EVENTS = {
|
|
|
3707
3718
|
wrapUp: "matrx.meet.wrap_up",
|
|
3708
3719
|
/** The meeting ended for everyone. Payload `{ meeting_id, ended_at, trigger }`. */
|
|
3709
3720
|
ended: "matrx.meet.ended",
|
|
3710
|
-
/**
|
|
3711
|
-
* A `meet_recordings` row changed state. Payload
|
|
3712
|
-
* `{ meeting_id, recording: { id, state, started_by } }`.
|
|
3713
|
-
*
|
|
3714
|
-
* 🚨 THIS IS THE ONLY WAY A GUEST LEARNS A RECORDING IS RUNNING. PreJoin
|
|
3715
|
-
* promises every joiner an indicator, and `anon` holds no SELECT grant on
|
|
3716
|
-
* `meet_recordings` (MRI-A10 settled that widening it is forbidden), so
|
|
3717
|
-
* without this packet the promise was a sentence with nothing behind it: on
|
|
3718
|
-
* production 2026-09-09 the guest lane showed no indicator at all while the
|
|
3719
|
-
* host recorded (MRI-C8).
|
|
3720
|
-
*/
|
|
3721
|
-
recording: "matrx.meet.recording",
|
|
3722
3721
|
/**
|
|
3723
3722
|
* A chat message to everyone was SAVED (Meet wave 2). Payload
|
|
3724
3723
|
* `{ message: { id, meeting_id, sender_identity, sender_name, body, created_at } }`.
|
|
@@ -3771,8 +3770,6 @@ function applyRoomEvent(args) {
|
|
|
3771
3770
|
return applyWrapUp(store, payload, now);
|
|
3772
3771
|
case ROOM_EVENTS.ended:
|
|
3773
3772
|
return applyEnded(store, payload);
|
|
3774
|
-
case ROOM_EVENTS.recording:
|
|
3775
|
-
return applyRecording(store, payload);
|
|
3776
3773
|
case ROOM_EVENTS.chat:
|
|
3777
3774
|
return applyChat(store, payload);
|
|
3778
3775
|
case ROOM_EVENTS.moderation:
|
|
@@ -3852,9 +3849,9 @@ function applyWrapUp(store, payload, now) {
|
|
|
3852
3849
|
store.announceWrapUp(announcement);
|
|
3853
3850
|
return HANDLED;
|
|
3854
3851
|
}
|
|
3855
|
-
function
|
|
3852
|
+
function applyRecordingState(store, payload) {
|
|
3856
3853
|
const row = object(payload["recording"]);
|
|
3857
|
-
if (row === null) return ignored("
|
|
3854
|
+
if (row === null) return ignored("room state carries no recording");
|
|
3858
3855
|
const meetingId = text2(payload["meeting_id"]);
|
|
3859
3856
|
const meeting = store.snapshot().meeting;
|
|
3860
3857
|
if (meeting !== null && meetingId !== null && meetingId !== meeting.id) {
|
|
@@ -3936,19 +3933,6 @@ function applyModeration(store, payload, now) {
|
|
|
3936
3933
|
}
|
|
3937
3934
|
const kind = text2(payload["kind"]);
|
|
3938
3935
|
switch (kind) {
|
|
3939
|
-
case "lower-hands": {
|
|
3940
|
-
const raw = payload["identities"];
|
|
3941
|
-
const everyone = raw === "*";
|
|
3942
|
-
const named = new Set(
|
|
3943
|
-
Array.isArray(raw) ? raw.filter((value) => typeof value === "string") : []
|
|
3944
|
-
);
|
|
3945
|
-
for (const participant of snapshot.participants) {
|
|
3946
|
-
if (participant.handRaised && (everyone || named.has(participant.identity))) {
|
|
3947
|
-
store.setHand(participant.identity, false);
|
|
3948
|
-
}
|
|
3949
|
-
}
|
|
3950
|
-
return HANDLED;
|
|
3951
|
-
}
|
|
3952
3936
|
case "role": {
|
|
3953
3937
|
const identity = text2(payload["identity"]);
|
|
3954
3938
|
const role = text2(payload["role"]);
|
|
@@ -4340,7 +4324,6 @@ function gridColumns(count2) {
|
|
|
4340
4324
|
|
|
4341
4325
|
// src/core/room-driver.ts
|
|
4342
4326
|
var DATA_TOPICS = {
|
|
4343
|
-
hand: "mx.hand",
|
|
4344
4327
|
reaction: "mx.reaction",
|
|
4345
4328
|
chat: "mx.chat"
|
|
4346
4329
|
};
|
|
@@ -4482,6 +4465,7 @@ function createLiveKitDriver(handlers, options = {}) {
|
|
|
4482
4465
|
projectRoster = roster;
|
|
4483
4466
|
created.on(RoomEvent.TrackSubscribed, (track) => {
|
|
4484
4467
|
if (track.kind !== Track.Kind.Audio || typeof document === "undefined") return;
|
|
4468
|
+
if (!remoteAudioPlayback) return;
|
|
4485
4469
|
const element = track.attach();
|
|
4486
4470
|
element.setAttribute("data-mx-meet-audio", "");
|
|
4487
4471
|
audioSink().appendChild(element);
|
|
@@ -4566,6 +4550,7 @@ function createLiveKitDriver(handlers, options = {}) {
|
|
|
4566
4550
|
let sources = null;
|
|
4567
4551
|
let trackEvents = null;
|
|
4568
4552
|
let audioContainer = null;
|
|
4553
|
+
let remoteAudioPlayback = true;
|
|
4569
4554
|
function audioSink() {
|
|
4570
4555
|
if (audioContainer !== null && audioContainer.isConnected) return audioContainer;
|
|
4571
4556
|
const container = document.createElement("div");
|
|
@@ -4724,6 +4709,14 @@ function createLiveKitDriver(handlers, options = {}) {
|
|
|
4724
4709
|
throw normalizeDeviceError(error, "meet.switchDevice");
|
|
4725
4710
|
}
|
|
4726
4711
|
},
|
|
4712
|
+
setRemoteAudioPlayback(enabled) {
|
|
4713
|
+
remoteAudioPlayback = enabled;
|
|
4714
|
+
if (enabled || audioContainer === null) return;
|
|
4715
|
+
for (const element of Array.from(audioContainer.querySelectorAll("[data-mx-meet-audio]"))) {
|
|
4716
|
+
if (element instanceof HTMLMediaElement) element.srcObject = null;
|
|
4717
|
+
element.remove();
|
|
4718
|
+
}
|
|
4719
|
+
},
|
|
4727
4720
|
async startAudio() {
|
|
4728
4721
|
const target = room;
|
|
4729
4722
|
if (target === null) return;
|
|
@@ -4964,7 +4957,7 @@ function createMeetingSession(options) {
|
|
|
4964
4957
|
})();
|
|
4965
4958
|
return reading;
|
|
4966
4959
|
}
|
|
4967
|
-
async function postLeave(intent) {
|
|
4960
|
+
async function postLeave(intent, extra = {}) {
|
|
4968
4961
|
const meeting = requireMeeting(`meet.${intent}`);
|
|
4969
4962
|
const pass = options.resolvePass?.() ?? null;
|
|
4970
4963
|
const response = await options.api.request({
|
|
@@ -4972,7 +4965,7 @@ function createMeetingSession(options) {
|
|
|
4972
4965
|
method: "POST",
|
|
4973
4966
|
requireAuth: false,
|
|
4974
4967
|
operation: `meet.${intent}`,
|
|
4975
|
-
body: { meeting_id: meeting.id, intent },
|
|
4968
|
+
body: { meeting_id: meeting.id, intent, ...extra },
|
|
4976
4969
|
...pass !== null ? { headers: { [MEETING_PASS_HEADER]: pass } } : {}
|
|
4977
4970
|
});
|
|
4978
4971
|
if (!response.ok) {
|
|
@@ -4986,7 +4979,7 @@ function createMeetingSession(options) {
|
|
|
4986
4979
|
throw new MeetError(
|
|
4987
4980
|
"transport",
|
|
4988
4981
|
refusal2?.reason ?? `meet.${intent}: the server answered ${response.status}`,
|
|
4989
|
-
refusal2?.remedy ?? "You are still in the waiting room. Try again."
|
|
4982
|
+
refusal2?.remedy ?? (intent === "withdraw" ? "You are still in the waiting room. Try again." : "Nothing was changed. Try again.")
|
|
4990
4983
|
);
|
|
4991
4984
|
}
|
|
4992
4985
|
}
|
|
@@ -5210,6 +5203,10 @@ function createMeetingSession(options) {
|
|
|
5210
5203
|
store.dispatch({ type: "admission", admission: "withdrawn" });
|
|
5211
5204
|
hint();
|
|
5212
5205
|
},
|
|
5206
|
+
async hostLeave(intent) {
|
|
5207
|
+
if (intent === "end_for_all") await postLeave("end_for_all");
|
|
5208
|
+
else await postLeave("assign_and_leave", { assign_to: intent.assignTo });
|
|
5209
|
+
},
|
|
5213
5210
|
async askAgain() {
|
|
5214
5211
|
await options.rejoin?.();
|
|
5215
5212
|
},
|
|
@@ -6171,6 +6168,11 @@ function SCREEN_SHARE_BLOCKED_REMEDY_FOR(remedy) {
|
|
|
6171
6168
|
return /administrator|policy/i.test(remedy) ? remedy : SCREEN_SHARE_BLOCKED_REMEDY;
|
|
6172
6169
|
}
|
|
6173
6170
|
var PARTICIPANT_ROLE_ATTRIBUTE = "matrx.participant.role";
|
|
6171
|
+
var PARTICIPANT_HAND_ATTRIBUTE = "matrx.hand";
|
|
6172
|
+
function handFrom(value) {
|
|
6173
|
+
const at = value === void 0 || value.length === 0 ? Number.NaN : Number(value);
|
|
6174
|
+
return Number.isFinite(at) ? { handRaised: true, handRaisedAt: at } : { handRaised: false, handRaisedAt: null };
|
|
6175
|
+
}
|
|
6174
6176
|
var PARTICIPANT_CAN_RECORD_ATTRIBUTE = "matrx.participant.can_record";
|
|
6175
6177
|
var CONNECTION_KIND_ATTRIBUTE = "matrx.participant.connection_kind";
|
|
6176
6178
|
var PARTICIPANT_STANDING_ATTRIBUTE = "matrx.participant.standing";
|
|
@@ -6224,7 +6226,10 @@ function projectParticipant(driver, joinedAt) {
|
|
|
6224
6226
|
cameraEnabled: driver.cameraEnabled,
|
|
6225
6227
|
screenSharing: driver.screenSharing,
|
|
6226
6228
|
speaking: false,
|
|
6227
|
-
|
|
6229
|
+
// S8: a hand is the SERVER's (`hand_raised_at` on the person row, `/moderate raise_hand`),
|
|
6230
|
+
// replicated as the `matrx.hand` attribute: epoch ms of the raise, "" when down. It is
|
|
6231
|
+
// therefore delivered to late joiners and survives refresh and reconnect.
|
|
6232
|
+
...handFrom(driver.attributes[PARTICIPANT_HAND_ATTRIBUTE]),
|
|
6228
6233
|
quality: "unknown",
|
|
6229
6234
|
joinedAt
|
|
6230
6235
|
};
|
|
@@ -6354,40 +6359,38 @@ function createRoomEngine(options) {
|
|
|
6354
6359
|
},
|
|
6355
6360
|
participants(list) {
|
|
6356
6361
|
const joinedAt = new Date(now()).toISOString();
|
|
6357
|
-
const before = new Set(store.snapshot().participants.map((p) => p.identity));
|
|
6358
6362
|
projectRoster(list, joinedAt);
|
|
6359
|
-
const snapshot = store.snapshot();
|
|
6360
|
-
const newcomer = snapshot.participants.some(
|
|
6361
|
-
(participant) => !participant.isLocal && !before.has(participant.identity)
|
|
6362
|
-
);
|
|
6363
|
-
const me = snapshot.participants.find((p) => p.identity === snapshot.localIdentity);
|
|
6364
|
-
if (newcomer && before.size > 0 && me?.handRaised === true) {
|
|
6365
|
-
void publish(DATA_TOPICS.hand, { raised: true, raisedAt: me.handRaisedAt ?? now() }).catch(
|
|
6366
|
-
() => void 0
|
|
6367
|
-
);
|
|
6368
|
-
}
|
|
6369
6363
|
},
|
|
6370
6364
|
participantLeft(who, reason) {
|
|
6371
6365
|
departures.set(who, reason);
|
|
6372
6366
|
},
|
|
6373
6367
|
roomMetadata(metadata) {
|
|
6374
|
-
let
|
|
6368
|
+
let parsed = {};
|
|
6375
6369
|
if (metadata.length > 0) {
|
|
6376
6370
|
try {
|
|
6377
|
-
const
|
|
6378
|
-
if (typeof
|
|
6379
|
-
const value = parsed.spotlight;
|
|
6380
|
-
if (typeof value === "string" && value.length > 0) spotlight = asParticipantIdentity(value);
|
|
6381
|
-
}
|
|
6371
|
+
const value = JSON.parse(metadata);
|
|
6372
|
+
if (typeof value === "object" && value !== null) parsed = value;
|
|
6382
6373
|
} catch {
|
|
6383
6374
|
report(
|
|
6384
6375
|
"warn",
|
|
6385
|
-
"meet: the room's metadata is not JSON, so
|
|
6386
|
-
"Only aidream writes room metadata; check services/meet/
|
|
6376
|
+
"meet: the room's metadata is not JSON, so the room state was not read from it",
|
|
6377
|
+
"Only aidream writes room metadata; check services/meet/room_state.py."
|
|
6387
6378
|
);
|
|
6388
6379
|
}
|
|
6389
6380
|
}
|
|
6390
|
-
|
|
6381
|
+
const key = (name) => {
|
|
6382
|
+
const value = parsed[name];
|
|
6383
|
+
return typeof value === "string" && value.length > 0 ? asParticipantIdentity(personOf(value)) : null;
|
|
6384
|
+
};
|
|
6385
|
+
const waiting = typeof parsed["waiting_count"] === "number" ? parsed["waiting_count"] : 0;
|
|
6386
|
+
const before = store.snapshot();
|
|
6387
|
+
const next = { spotlight: key("spotlight"), actingHost: key("acting_host"), presenter: key("presenter"), waitingCount: waiting };
|
|
6388
|
+
if (before.spotlight !== next.spotlight || before.actingHost !== next.actingHost || before.presenter !== next.presenter || before.waitingCount !== next.waitingCount) {
|
|
6389
|
+
store.patch(next);
|
|
6390
|
+
}
|
|
6391
|
+
if (parsed["recording"] !== void 0 && parsed["recording"] !== null) {
|
|
6392
|
+
applyRecordingState(store, { meeting_id: parsed["meeting_id"], recording: parsed["recording"] });
|
|
6393
|
+
}
|
|
6391
6394
|
},
|
|
6392
6395
|
activeSpeakers(identities) {
|
|
6393
6396
|
store.setSpeaking([...new Set(identities.map((who) => personOf(who)))]);
|
|
@@ -6489,13 +6492,6 @@ function createRoomEngine(options) {
|
|
|
6489
6492
|
}
|
|
6490
6493
|
const sender = personOf(from ?? "");
|
|
6491
6494
|
switch (topic) {
|
|
6492
|
-
case DATA_TOPICS.hand:
|
|
6493
|
-
store.setHand(
|
|
6494
|
-
sender,
|
|
6495
|
-
envelope.raised === true,
|
|
6496
|
-
typeof envelope.raisedAt === "number" ? envelope.raisedAt : now()
|
|
6497
|
-
);
|
|
6498
|
-
return;
|
|
6499
6495
|
case DATA_TOPICS.reaction:
|
|
6500
6496
|
if (typeof envelope.emoji === "string") {
|
|
6501
6497
|
store.addReaction({
|
|
@@ -6594,6 +6590,7 @@ function createRoomEngine(options) {
|
|
|
6594
6590
|
current = token;
|
|
6595
6591
|
lastServerUrl = token.serverUrl;
|
|
6596
6592
|
connectionPolicy = token.connectionPolicy ?? DEFAULT_CONNECTION_POLICY;
|
|
6593
|
+
if (token.leavePolicy !== void 0) store.patch({ leavePolicy: token.leavePolicy });
|
|
6597
6594
|
store.patch({
|
|
6598
6595
|
localIdentity: token.identity,
|
|
6599
6596
|
breakoutRoomId: token.breakoutRoomId ?? null,
|
|
@@ -6628,6 +6625,7 @@ function createRoomEngine(options) {
|
|
|
6628
6625
|
return;
|
|
6629
6626
|
}
|
|
6630
6627
|
driver = created;
|
|
6628
|
+
if (token.connectionKind === "companion") created.setRemoteAudioPlayback?.(false);
|
|
6631
6629
|
await created.connect(token.serverUrl, token.token);
|
|
6632
6630
|
store.patch({ failure: null, connection: "stable" });
|
|
6633
6631
|
store.dispatch({ type: "connected" });
|
|
@@ -6889,6 +6887,19 @@ function createRoomEngine(options) {
|
|
|
6889
6887
|
}
|
|
6890
6888
|
},
|
|
6891
6889
|
leave: leaveRoom,
|
|
6890
|
+
async checkElsewhere(roomName) {
|
|
6891
|
+
const claim = options.tabClaim;
|
|
6892
|
+
const userId = identity.userId;
|
|
6893
|
+
if (claim === void 0 || userId === null) return false;
|
|
6894
|
+
const before = store.snapshot();
|
|
6895
|
+
if (before.phase !== "prejoin" || before.secondDevice !== null) return false;
|
|
6896
|
+
if (!await claim.presentElsewhere(String(roomName), `user:${String(userId)}`)) return false;
|
|
6897
|
+
const now2 = store.snapshot();
|
|
6898
|
+
if (now2.phase !== "prejoin" || now2.secondDevice !== null) return false;
|
|
6899
|
+
store.patch({ secondDevice: { rule: "ask_switch_or_join" } });
|
|
6900
|
+
report("info", "meet: this browser already has you in this meeting \u2014 offering the choice before Join");
|
|
6901
|
+
return true;
|
|
6902
|
+
},
|
|
6892
6903
|
backToPrejoin() {
|
|
6893
6904
|
store.dispatch({ type: "back_to_prejoin", click: true });
|
|
6894
6905
|
},
|
|
@@ -6946,11 +6957,6 @@ function createRoomEngine(options) {
|
|
|
6946
6957
|
dismissShareNotice() {
|
|
6947
6958
|
if (store.snapshot().share.state === "refused") store.patch({ share: NO_SHARE });
|
|
6948
6959
|
},
|
|
6949
|
-
async raiseHand(raised) {
|
|
6950
|
-
const local = store.snapshot().localIdentity;
|
|
6951
|
-
if (local !== null) store.setHand(local, raised);
|
|
6952
|
-
await publish(DATA_TOPICS.hand, { raised, raisedAt: now() });
|
|
6953
|
-
},
|
|
6954
6960
|
async react(emoji) {
|
|
6955
6961
|
const local = store.snapshot().localIdentity;
|
|
6956
6962
|
const id = `${local ?? "local"}-${now()}`;
|
|
@@ -7079,6 +7085,8 @@ var MODERATION_ACTIONS = [
|
|
|
7079
7085
|
"ask_unmute",
|
|
7080
7086
|
"ask_all_unmute",
|
|
7081
7087
|
"spotlight",
|
|
7088
|
+
"present",
|
|
7089
|
+
"raise_hand",
|
|
7082
7090
|
"lower_hand",
|
|
7083
7091
|
"lower_all_hands",
|
|
7084
7092
|
"make_cohost",
|
|
@@ -7122,7 +7130,8 @@ function createInRoomClient(options) {
|
|
|
7122
7130
|
action: request.action,
|
|
7123
7131
|
...request.identity != null ? { identity: request.identity } : {},
|
|
7124
7132
|
...request.name !== void 0 ? { name: request.name } : {},
|
|
7125
|
-
...request.reason !== void 0 ? { reason: request.reason } : {}
|
|
7133
|
+
...request.reason !== void 0 ? { reason: request.reason } : {},
|
|
7134
|
+
...request.on !== void 0 ? { on: request.on } : {}
|
|
7126
7135
|
},
|
|
7127
7136
|
...hdrs !== void 0 ? { headers: hdrs } : {}
|
|
7128
7137
|
});
|
|
@@ -8119,6 +8128,7 @@ export {
|
|
|
8119
8128
|
DATA_TOPICS,
|
|
8120
8129
|
DEFAULT_CONNECTION_POLICY,
|
|
8121
8130
|
DEFAULT_EFFECTS,
|
|
8131
|
+
DEFAULT_LEAVE_POLICY,
|
|
8122
8132
|
DEFAULT_PAGE_SIZE,
|
|
8123
8133
|
EMPTY_COLLAB,
|
|
8124
8134
|
END_MEETING_NOT_SERVED,
|
|
@@ -8153,6 +8163,7 @@ export {
|
|
|
8153
8163
|
NO_SHARE,
|
|
8154
8164
|
ORGANIZATION_HEADER,
|
|
8155
8165
|
PARTICIPANT_CAN_RECORD_ATTRIBUTE,
|
|
8166
|
+
PARTICIPANT_HAND_ATTRIBUTE,
|
|
8156
8167
|
PARTICIPANT_ROLE_ATTRIBUTE,
|
|
8157
8168
|
PARTICIPANT_STANDING_ATTRIBUTE,
|
|
8158
8169
|
REACTION_TTL_MS,
|
|
@@ -8265,6 +8276,8 @@ export {
|
|
|
8265
8276
|
isWaitingPhase,
|
|
8266
8277
|
learnName,
|
|
8267
8278
|
learnNames,
|
|
8279
|
+
leaveChoices,
|
|
8280
|
+
leavePolicyFrom,
|
|
8268
8281
|
listenOnlyNotice,
|
|
8269
8282
|
loadFollowUpDraft,
|
|
8270
8283
|
loadGuestMeetingRecord,
|