@ai-matrx/meet 0.11.36 → 0.11.38
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 +129 -87
- package/dist/core.cjs.map +1 -1
- package/dist/core.d.cts +66 -22
- package/dist/core.d.ts +66 -22
- package/dist/core.js +129 -87
- package/dist/core.js.map +1 -1
- package/dist/index.cjs +129 -87
- 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 +129 -87
- package/dist/index.js.map +1 -1
- package/dist/react.cjs +231 -107
- package/dist/react.cjs.map +1 -1
- package/dist/react.d.cts +17 -3
- package/dist/react.d.ts +17 -3
- package/dist/react.js +231 -107
- package/dist/react.js.map +1 -1
- package/dist/skins/meet.cjs +120 -20
- package/dist/skins/meet.cjs.map +1 -1
- package/dist/skins/meet.js +120 -20
- package/dist/skins/meet.js.map +1 -1
- package/dist/styles.css +7 -0
- package/package.json +5 -5
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;
|
|
@@ -663,6 +687,12 @@ var MEET_ROUTES = {
|
|
|
663
687
|
state: "/api/v1/meet/state",
|
|
664
688
|
/** S4: `withdraw` (stop waiting) or `leave` (close this tab); the pass may ride in the body. */
|
|
665
689
|
leave: "/api/v1/meet/leave",
|
|
690
|
+
/**
|
|
691
|
+
* S8: a host's browser just called an admission DOOR (`meet_admit` · `meet_deny` ·
|
|
692
|
+
* `meet_undeny` · `meet_admit_all`). Payload-free: the server republishes the room's
|
|
693
|
+
* replicated state (the People badge's waiting count) from the database truth.
|
|
694
|
+
*/
|
|
695
|
+
admissionChanged: "/api/v1/meet/admission/changed",
|
|
666
696
|
/** S4: a pass holder (guests included) saw the recording notice, for this run. */
|
|
667
697
|
consent: "/api/v1/meet/consent"
|
|
668
698
|
};
|
|
@@ -747,7 +777,8 @@ function parseRoomToken(body, roomName) {
|
|
|
747
777
|
pollSeconds: typeof payload["poll_seconds"] === "number" ? payload["poll_seconds"] : void 0,
|
|
748
778
|
breakoutRoomId: readString(payload, "breakout_room_id") ?? null,
|
|
749
779
|
observersVisibleTo: readString(payload, "observers_visible_to") === "hosts" ? "hosts" : "everyone",
|
|
750
|
-
connectionPolicy: connectionPolicyFrom(payload["connection_policy"])
|
|
780
|
+
connectionPolicy: connectionPolicyFrom(payload["connection_policy"]),
|
|
781
|
+
leavePolicy: leavePolicyFrom(payload["leave_policy"])
|
|
751
782
|
};
|
|
752
783
|
}
|
|
753
784
|
function createTokenClient(options) {
|
|
@@ -3446,6 +3477,10 @@ var EMPTY = {
|
|
|
3446
3477
|
chatHistoryError: null,
|
|
3447
3478
|
reactions: [],
|
|
3448
3479
|
spotlight: null,
|
|
3480
|
+
actingHost: null,
|
|
3481
|
+
presenter: null,
|
|
3482
|
+
waitingCount: 0,
|
|
3483
|
+
leavePolicy: DEFAULT_LEAVE_POLICY,
|
|
3449
3484
|
moderationNotice: null,
|
|
3450
3485
|
actionNotice: null,
|
|
3451
3486
|
privateChatRequest: null,
|
|
@@ -3507,8 +3542,6 @@ function createMeetStore(initial = {}) {
|
|
|
3507
3542
|
},
|
|
3508
3543
|
setParticipants(participants) {
|
|
3509
3544
|
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
3545
|
const quality = new Map(state.participants.map((p) => [p.identity, p.quality]));
|
|
3513
3546
|
commit({
|
|
3514
3547
|
...state,
|
|
@@ -3521,8 +3554,6 @@ function createMeetStore(initial = {}) {
|
|
|
3521
3554
|
// identity could reach a screen, and it is the place that asks the
|
|
3522
3555
|
// name book. `roster-names.test.ts` fails if a token ever gets past it.
|
|
3523
3556
|
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
3557
|
quality: participant.quality === "unknown" ? quality.get(participant.identity) ?? "unknown" : participant.quality
|
|
3527
3558
|
}))
|
|
3528
3559
|
});
|
|
@@ -3545,20 +3576,6 @@ function createMeetStore(initial = {}) {
|
|
|
3545
3576
|
)
|
|
3546
3577
|
});
|
|
3547
3578
|
},
|
|
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
3579
|
addChat(message) {
|
|
3563
3580
|
if (state.chat.some((existing) => existing.id === message.id)) return;
|
|
3564
3581
|
const chat = [...state.chat, message];
|
|
@@ -3707,18 +3724,6 @@ var ROOM_EVENTS = {
|
|
|
3707
3724
|
wrapUp: "matrx.meet.wrap_up",
|
|
3708
3725
|
/** The meeting ended for everyone. Payload `{ meeting_id, ended_at, trigger }`. */
|
|
3709
3726
|
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
3727
|
/**
|
|
3723
3728
|
* A chat message to everyone was SAVED (Meet wave 2). Payload
|
|
3724
3729
|
* `{ message: { id, meeting_id, sender_identity, sender_name, body, created_at } }`.
|
|
@@ -3771,8 +3776,6 @@ function applyRoomEvent(args) {
|
|
|
3771
3776
|
return applyWrapUp(store, payload, now);
|
|
3772
3777
|
case ROOM_EVENTS.ended:
|
|
3773
3778
|
return applyEnded(store, payload);
|
|
3774
|
-
case ROOM_EVENTS.recording:
|
|
3775
|
-
return applyRecording(store, payload);
|
|
3776
3779
|
case ROOM_EVENTS.chat:
|
|
3777
3780
|
return applyChat(store, payload);
|
|
3778
3781
|
case ROOM_EVENTS.moderation:
|
|
@@ -3852,9 +3855,9 @@ function applyWrapUp(store, payload, now) {
|
|
|
3852
3855
|
store.announceWrapUp(announcement);
|
|
3853
3856
|
return HANDLED;
|
|
3854
3857
|
}
|
|
3855
|
-
function
|
|
3858
|
+
function applyRecordingState(store, payload) {
|
|
3856
3859
|
const row = object(payload["recording"]);
|
|
3857
|
-
if (row === null) return ignored("
|
|
3860
|
+
if (row === null) return ignored("room state carries no recording");
|
|
3858
3861
|
const meetingId = text2(payload["meeting_id"]);
|
|
3859
3862
|
const meeting = store.snapshot().meeting;
|
|
3860
3863
|
if (meeting !== null && meetingId !== null && meetingId !== meeting.id) {
|
|
@@ -3936,19 +3939,6 @@ function applyModeration(store, payload, now) {
|
|
|
3936
3939
|
}
|
|
3937
3940
|
const kind = text2(payload["kind"]);
|
|
3938
3941
|
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
3942
|
case "role": {
|
|
3953
3943
|
const identity = text2(payload["identity"]);
|
|
3954
3944
|
const role = text2(payload["role"]);
|
|
@@ -4340,7 +4330,6 @@ function gridColumns(count2) {
|
|
|
4340
4330
|
|
|
4341
4331
|
// src/core/room-driver.ts
|
|
4342
4332
|
var DATA_TOPICS = {
|
|
4343
|
-
hand: "mx.hand",
|
|
4344
4333
|
reaction: "mx.reaction",
|
|
4345
4334
|
chat: "mx.chat"
|
|
4346
4335
|
};
|
|
@@ -4974,7 +4963,7 @@ function createMeetingSession(options) {
|
|
|
4974
4963
|
})();
|
|
4975
4964
|
return reading;
|
|
4976
4965
|
}
|
|
4977
|
-
async function postLeave(intent) {
|
|
4966
|
+
async function postLeave(intent, extra = {}) {
|
|
4978
4967
|
const meeting = requireMeeting(`meet.${intent}`);
|
|
4979
4968
|
const pass = options.resolvePass?.() ?? null;
|
|
4980
4969
|
const response = await options.api.request({
|
|
@@ -4982,7 +4971,7 @@ function createMeetingSession(options) {
|
|
|
4982
4971
|
method: "POST",
|
|
4983
4972
|
requireAuth: false,
|
|
4984
4973
|
operation: `meet.${intent}`,
|
|
4985
|
-
body: { meeting_id: meeting.id, intent },
|
|
4974
|
+
body: { meeting_id: meeting.id, intent, ...extra },
|
|
4986
4975
|
...pass !== null ? { headers: { [MEETING_PASS_HEADER]: pass } } : {}
|
|
4987
4976
|
});
|
|
4988
4977
|
if (!response.ok) {
|
|
@@ -4996,13 +4985,41 @@ function createMeetingSession(options) {
|
|
|
4996
4985
|
throw new MeetError(
|
|
4997
4986
|
"transport",
|
|
4998
4987
|
refusal2?.reason ?? `meet.${intent}: the server answered ${response.status}`,
|
|
4999
|
-
refusal2?.remedy ?? "You are still in the waiting room. Try again."
|
|
4988
|
+
refusal2?.remedy ?? (intent === "withdraw" ? "You are still in the waiting room. Try again." : "Nothing was changed. Try again.")
|
|
5000
4989
|
);
|
|
5001
4990
|
}
|
|
5002
4991
|
}
|
|
5003
4992
|
function hint() {
|
|
5004
4993
|
channel?.send(MEET_EVENTS.stateChanged, { v: null });
|
|
5005
4994
|
}
|
|
4995
|
+
async function tellServerAdmissionChanged(operation) {
|
|
4996
|
+
const meeting = store.snapshot().meeting;
|
|
4997
|
+
if (meeting === null) return;
|
|
4998
|
+
const pass = options.resolvePass?.() ?? null;
|
|
4999
|
+
try {
|
|
5000
|
+
const response = await options.api.request({
|
|
5001
|
+
path: MEET_ROUTES.admissionChanged,
|
|
5002
|
+
method: "POST",
|
|
5003
|
+
requireAuth: false,
|
|
5004
|
+
operation,
|
|
5005
|
+
body: { meeting_id: meeting.id },
|
|
5006
|
+
...pass !== null ? { headers: { [MEETING_PASS_HEADER]: pass } } : {}
|
|
5007
|
+
});
|
|
5008
|
+
if (!response.ok) {
|
|
5009
|
+
report(
|
|
5010
|
+
"warn",
|
|
5011
|
+
`${operation}: the server answered ${response.status} when told about the admission change`,
|
|
5012
|
+
"The decision was saved. The waiting count in the room may lag until the next change."
|
|
5013
|
+
);
|
|
5014
|
+
}
|
|
5015
|
+
} catch (error) {
|
|
5016
|
+
report(
|
|
5017
|
+
"warn",
|
|
5018
|
+
`${operation}: ${String(error)}`,
|
|
5019
|
+
"The decision was saved. The waiting count in the room may lag until the next change."
|
|
5020
|
+
);
|
|
5021
|
+
}
|
|
5022
|
+
}
|
|
5006
5023
|
async function refreshQueue() {
|
|
5007
5024
|
const meeting = store.snapshot().meeting;
|
|
5008
5025
|
if (meeting === null || isGuest(identity) || !isHostRole(effectiveRole(store.snapshot()))) return;
|
|
@@ -5158,6 +5175,7 @@ function createMeetingSession(options) {
|
|
|
5158
5175
|
decidedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
5159
5176
|
decidedBy: by
|
|
5160
5177
|
});
|
|
5178
|
+
await tellServerAdmissionChanged("meet.admit");
|
|
5161
5179
|
hint();
|
|
5162
5180
|
},
|
|
5163
5181
|
async undeny(entry) {
|
|
@@ -5170,6 +5188,7 @@ function createMeetingSession(options) {
|
|
|
5170
5188
|
byUserId: by
|
|
5171
5189
|
});
|
|
5172
5190
|
store.upsertLobby({ ...entry, state: decidedState(row.admissionState), decidedAt: (/* @__PURE__ */ new Date()).toISOString(), decidedBy: by });
|
|
5191
|
+
await tellServerAdmissionChanged("meet.undeny");
|
|
5173
5192
|
hint();
|
|
5174
5193
|
},
|
|
5175
5194
|
async admitAll() {
|
|
@@ -5179,6 +5198,7 @@ function createMeetingSession(options) {
|
|
|
5179
5198
|
for (const row of rows) {
|
|
5180
5199
|
store.setAdmission(row.identity, row.admissionState, by);
|
|
5181
5200
|
}
|
|
5201
|
+
await tellServerAdmissionChanged("meet.admitAll");
|
|
5182
5202
|
hint();
|
|
5183
5203
|
},
|
|
5184
5204
|
startWaiting() {
|
|
@@ -5220,6 +5240,10 @@ function createMeetingSession(options) {
|
|
|
5220
5240
|
store.dispatch({ type: "admission", admission: "withdrawn" });
|
|
5221
5241
|
hint();
|
|
5222
5242
|
},
|
|
5243
|
+
async hostLeave(intent) {
|
|
5244
|
+
if (intent === "end_for_all") await postLeave("end_for_all");
|
|
5245
|
+
else await postLeave("assign_and_leave", { assign_to: intent.assignTo });
|
|
5246
|
+
},
|
|
5223
5247
|
async askAgain() {
|
|
5224
5248
|
await options.rejoin?.();
|
|
5225
5249
|
},
|
|
@@ -6181,6 +6205,11 @@ function SCREEN_SHARE_BLOCKED_REMEDY_FOR(remedy) {
|
|
|
6181
6205
|
return /administrator|policy/i.test(remedy) ? remedy : SCREEN_SHARE_BLOCKED_REMEDY;
|
|
6182
6206
|
}
|
|
6183
6207
|
var PARTICIPANT_ROLE_ATTRIBUTE = "matrx.participant.role";
|
|
6208
|
+
var PARTICIPANT_HAND_ATTRIBUTE = "matrx.hand";
|
|
6209
|
+
function handFrom(value) {
|
|
6210
|
+
const at = value === void 0 || value.length === 0 ? Number.NaN : Number(value);
|
|
6211
|
+
return Number.isFinite(at) ? { handRaised: true, handRaisedAt: at } : { handRaised: false, handRaisedAt: null };
|
|
6212
|
+
}
|
|
6184
6213
|
var PARTICIPANT_CAN_RECORD_ATTRIBUTE = "matrx.participant.can_record";
|
|
6185
6214
|
var CONNECTION_KIND_ATTRIBUTE = "matrx.participant.connection_kind";
|
|
6186
6215
|
var PARTICIPANT_STANDING_ATTRIBUTE = "matrx.participant.standing";
|
|
@@ -6234,7 +6263,10 @@ function projectParticipant(driver, joinedAt) {
|
|
|
6234
6263
|
cameraEnabled: driver.cameraEnabled,
|
|
6235
6264
|
screenSharing: driver.screenSharing,
|
|
6236
6265
|
speaking: false,
|
|
6237
|
-
|
|
6266
|
+
// S8: a hand is the SERVER's (`hand_raised_at` on the person row, `/moderate raise_hand`),
|
|
6267
|
+
// replicated as the `matrx.hand` attribute: epoch ms of the raise, "" when down. It is
|
|
6268
|
+
// therefore delivered to late joiners and survives refresh and reconnect.
|
|
6269
|
+
...handFrom(driver.attributes[PARTICIPANT_HAND_ATTRIBUTE]),
|
|
6238
6270
|
quality: "unknown",
|
|
6239
6271
|
joinedAt
|
|
6240
6272
|
};
|
|
@@ -6364,40 +6396,38 @@ function createRoomEngine(options) {
|
|
|
6364
6396
|
},
|
|
6365
6397
|
participants(list) {
|
|
6366
6398
|
const joinedAt = new Date(now()).toISOString();
|
|
6367
|
-
const before = new Set(store.snapshot().participants.map((p) => p.identity));
|
|
6368
6399
|
projectRoster(list, joinedAt);
|
|
6369
|
-
const snapshot = store.snapshot();
|
|
6370
|
-
const newcomer = snapshot.participants.some(
|
|
6371
|
-
(participant) => !participant.isLocal && !before.has(participant.identity)
|
|
6372
|
-
);
|
|
6373
|
-
const me = snapshot.participants.find((p) => p.identity === snapshot.localIdentity);
|
|
6374
|
-
if (newcomer && before.size > 0 && me?.handRaised === true) {
|
|
6375
|
-
void publish(DATA_TOPICS.hand, { raised: true, raisedAt: me.handRaisedAt ?? now() }).catch(
|
|
6376
|
-
() => void 0
|
|
6377
|
-
);
|
|
6378
|
-
}
|
|
6379
6400
|
},
|
|
6380
6401
|
participantLeft(who, reason) {
|
|
6381
6402
|
departures.set(who, reason);
|
|
6382
6403
|
},
|
|
6383
6404
|
roomMetadata(metadata) {
|
|
6384
|
-
let
|
|
6405
|
+
let parsed = {};
|
|
6385
6406
|
if (metadata.length > 0) {
|
|
6386
6407
|
try {
|
|
6387
|
-
const
|
|
6388
|
-
if (typeof
|
|
6389
|
-
const value = parsed.spotlight;
|
|
6390
|
-
if (typeof value === "string" && value.length > 0) spotlight = asParticipantIdentity(value);
|
|
6391
|
-
}
|
|
6408
|
+
const value = JSON.parse(metadata);
|
|
6409
|
+
if (typeof value === "object" && value !== null) parsed = value;
|
|
6392
6410
|
} catch {
|
|
6393
6411
|
report(
|
|
6394
6412
|
"warn",
|
|
6395
|
-
"meet: the room's metadata is not JSON, so
|
|
6396
|
-
"Only aidream writes room metadata; check services/meet/
|
|
6413
|
+
"meet: the room's metadata is not JSON, so the room state was not read from it",
|
|
6414
|
+
"Only aidream writes room metadata; check services/meet/room_state.py."
|
|
6397
6415
|
);
|
|
6398
6416
|
}
|
|
6399
6417
|
}
|
|
6400
|
-
|
|
6418
|
+
const key = (name) => {
|
|
6419
|
+
const value = parsed[name];
|
|
6420
|
+
return typeof value === "string" && value.length > 0 ? asParticipantIdentity(personOf(value)) : null;
|
|
6421
|
+
};
|
|
6422
|
+
const waiting = typeof parsed["waiting_count"] === "number" ? parsed["waiting_count"] : 0;
|
|
6423
|
+
const before = store.snapshot();
|
|
6424
|
+
const next = { spotlight: key("spotlight"), actingHost: key("acting_host"), presenter: key("presenter"), waitingCount: waiting };
|
|
6425
|
+
if (before.spotlight !== next.spotlight || before.actingHost !== next.actingHost || before.presenter !== next.presenter || before.waitingCount !== next.waitingCount) {
|
|
6426
|
+
store.patch(next);
|
|
6427
|
+
}
|
|
6428
|
+
if (parsed["recording"] !== void 0 && parsed["recording"] !== null) {
|
|
6429
|
+
applyRecordingState(store, { meeting_id: parsed["meeting_id"], recording: parsed["recording"] });
|
|
6430
|
+
}
|
|
6401
6431
|
},
|
|
6402
6432
|
activeSpeakers(identities) {
|
|
6403
6433
|
store.setSpeaking([...new Set(identities.map((who) => personOf(who)))]);
|
|
@@ -6499,13 +6529,6 @@ function createRoomEngine(options) {
|
|
|
6499
6529
|
}
|
|
6500
6530
|
const sender = personOf(from ?? "");
|
|
6501
6531
|
switch (topic) {
|
|
6502
|
-
case DATA_TOPICS.hand:
|
|
6503
|
-
store.setHand(
|
|
6504
|
-
sender,
|
|
6505
|
-
envelope.raised === true,
|
|
6506
|
-
typeof envelope.raisedAt === "number" ? envelope.raisedAt : now()
|
|
6507
|
-
);
|
|
6508
|
-
return;
|
|
6509
6532
|
case DATA_TOPICS.reaction:
|
|
6510
6533
|
if (typeof envelope.emoji === "string") {
|
|
6511
6534
|
store.addReaction({
|
|
@@ -6604,6 +6627,7 @@ function createRoomEngine(options) {
|
|
|
6604
6627
|
current = token;
|
|
6605
6628
|
lastServerUrl = token.serverUrl;
|
|
6606
6629
|
connectionPolicy = token.connectionPolicy ?? DEFAULT_CONNECTION_POLICY;
|
|
6630
|
+
if (token.leavePolicy !== void 0) store.patch({ leavePolicy: token.leavePolicy });
|
|
6607
6631
|
store.patch({
|
|
6608
6632
|
localIdentity: token.identity,
|
|
6609
6633
|
breakoutRoomId: token.breakoutRoomId ?? null,
|
|
@@ -6970,11 +6994,6 @@ function createRoomEngine(options) {
|
|
|
6970
6994
|
dismissShareNotice() {
|
|
6971
6995
|
if (store.snapshot().share.state === "refused") store.patch({ share: NO_SHARE });
|
|
6972
6996
|
},
|
|
6973
|
-
async raiseHand(raised) {
|
|
6974
|
-
const local = store.snapshot().localIdentity;
|
|
6975
|
-
if (local !== null) store.setHand(local, raised);
|
|
6976
|
-
await publish(DATA_TOPICS.hand, { raised, raisedAt: now() });
|
|
6977
|
-
},
|
|
6978
6997
|
async react(emoji) {
|
|
6979
6998
|
const local = store.snapshot().localIdentity;
|
|
6980
6999
|
const id = `${local ?? "local"}-${now()}`;
|
|
@@ -7103,6 +7122,8 @@ var MODERATION_ACTIONS = [
|
|
|
7103
7122
|
"ask_unmute",
|
|
7104
7123
|
"ask_all_unmute",
|
|
7105
7124
|
"spotlight",
|
|
7125
|
+
"present",
|
|
7126
|
+
"raise_hand",
|
|
7106
7127
|
"lower_hand",
|
|
7107
7128
|
"lower_all_hands",
|
|
7108
7129
|
"make_cohost",
|
|
@@ -7133,7 +7154,22 @@ function createInRoomClient(options) {
|
|
|
7133
7154
|
function refusal2(response, operation, remedy) {
|
|
7134
7155
|
return refusalFromResponse(response, operation, remedy);
|
|
7135
7156
|
}
|
|
7136
|
-
|
|
7157
|
+
let toldPresenting = false;
|
|
7158
|
+
let tellChain = Promise.resolve();
|
|
7159
|
+
store.subscribe(() => {
|
|
7160
|
+
const local = store.snapshot().participants.find((p) => p.isLocal);
|
|
7161
|
+
const sharing = local?.screenSharing === true;
|
|
7162
|
+
if (sharing === toldPresenting || local === void 0) return;
|
|
7163
|
+
toldPresenting = sharing;
|
|
7164
|
+
const on = sharing;
|
|
7165
|
+
tellChain = tellChain.then(() => client.moderate({ action: "present", on })).then(
|
|
7166
|
+
() => void 0,
|
|
7167
|
+
(error) => {
|
|
7168
|
+
console.warn(`[meet] the server did not take presenter=${String(on)}: ${String(error)}`);
|
|
7169
|
+
}
|
|
7170
|
+
);
|
|
7171
|
+
});
|
|
7172
|
+
const client = {
|
|
7137
7173
|
async moderate(request) {
|
|
7138
7174
|
const operation = `meet.moderate(${request.action})`;
|
|
7139
7175
|
const hdrs = headers();
|
|
@@ -7146,7 +7182,8 @@ function createInRoomClient(options) {
|
|
|
7146
7182
|
action: request.action,
|
|
7147
7183
|
...request.identity != null ? { identity: request.identity } : {},
|
|
7148
7184
|
...request.name !== void 0 ? { name: request.name } : {},
|
|
7149
|
-
...request.reason !== void 0 ? { reason: request.reason } : {}
|
|
7185
|
+
...request.reason !== void 0 ? { reason: request.reason } : {},
|
|
7186
|
+
...request.on !== void 0 ? { on: request.on } : {}
|
|
7150
7187
|
},
|
|
7151
7188
|
...hdrs !== void 0 ? { headers: hdrs } : {}
|
|
7152
7189
|
});
|
|
@@ -7337,6 +7374,7 @@ function createInRoomClient(options) {
|
|
|
7337
7374
|
});
|
|
7338
7375
|
}
|
|
7339
7376
|
};
|
|
7377
|
+
return client;
|
|
7340
7378
|
}
|
|
7341
7379
|
|
|
7342
7380
|
// src/core/record.ts
|
|
@@ -8143,6 +8181,7 @@ export {
|
|
|
8143
8181
|
DATA_TOPICS,
|
|
8144
8182
|
DEFAULT_CONNECTION_POLICY,
|
|
8145
8183
|
DEFAULT_EFFECTS,
|
|
8184
|
+
DEFAULT_LEAVE_POLICY,
|
|
8146
8185
|
DEFAULT_PAGE_SIZE,
|
|
8147
8186
|
EMPTY_COLLAB,
|
|
8148
8187
|
END_MEETING_NOT_SERVED,
|
|
@@ -8177,6 +8216,7 @@ export {
|
|
|
8177
8216
|
NO_SHARE,
|
|
8178
8217
|
ORGANIZATION_HEADER,
|
|
8179
8218
|
PARTICIPANT_CAN_RECORD_ATTRIBUTE,
|
|
8219
|
+
PARTICIPANT_HAND_ATTRIBUTE,
|
|
8180
8220
|
PARTICIPANT_ROLE_ATTRIBUTE,
|
|
8181
8221
|
PARTICIPANT_STANDING_ATTRIBUTE,
|
|
8182
8222
|
REACTION_TTL_MS,
|
|
@@ -8289,6 +8329,8 @@ export {
|
|
|
8289
8329
|
isWaitingPhase,
|
|
8290
8330
|
learnName,
|
|
8291
8331
|
learnNames,
|
|
8332
|
+
leaveChoices,
|
|
8333
|
+
leavePolicyFrom,
|
|
8292
8334
|
listenOnlyNotice,
|
|
8293
8335
|
loadFollowUpDraft,
|
|
8294
8336
|
loadGuestMeetingRecord,
|