Allow screen share takeover

This commit is contained in:
codex
2026-06-12 21:54:02 +02:00
parent d391e0fb3b
commit 71cdd06ef5
3 changed files with 45 additions and 5 deletions
+15 -1
View File
@@ -500,7 +500,21 @@ When KEEP-OPEN is nil, close PROCESS after writing."
(sharing . ,(if (alist-get 'sharing payload) t :false))
(updatedAt . ,(floor (* 1000 (float-time)))))))
(if (alist-get 'sharing payload)
(puthash safe-room-id event kkkmeet-server--presentation-states)
(let ((previous (gethash safe-room-id kkkmeet-server--presentation-states)))
(when (and previous
(alist-get 'peerId previous)
(not (equal (alist-get 'peerId previous) from)))
(kkkmeet-server--broadcast
safe-room-id from `((type . "presentation-state")
(from . ,(alist-get 'peerId previous))
(peerId . ,(alist-get 'peerId previous))
(name . ,(alist-get 'name previous))
(sharing . :false)
(reason . "takeover")
(replacedBy . ,from)
(replacedByName . ,(alist-get 'name event))
(updatedAt . ,(floor (* 1000 (float-time)))))))
(puthash safe-room-id event kkkmeet-server--presentation-states))
(when (equal (alist-get 'peerId (gethash safe-room-id kkkmeet-server--presentation-states))
from)
(remhash safe-room-id kkkmeet-server--presentation-states)))
+16 -4
View File
@@ -1337,10 +1337,20 @@ async function handleSignal(message) {
}
if (message.type === "presentation-state") {
if (
message.reason === "takeover" &&
message.from === peerId &&
!message.sharing &&
screenStream
) {
await stopScreenShare({ announce: false });
}
setRemotePresentation(message.from, message.sharing, message.name);
setActivity(
message.name,
message.sharing ? "started sharing their screen." : "stopped sharing their screen."
message.reason === "takeover"
? `was replaced by ${participantDisplayName(message.replacedByName)} as presenter.`
: message.sharing ? "started sharing their screen." : "stopped sharing their screen."
);
return;
}
@@ -1576,7 +1586,7 @@ async function startScreenShare() {
}
}
async function stopScreenShare() {
async function stopScreenShare({ announce = true } = {}) {
if (!screenStream || stoppingScreenShare) return;
stoppingScreenShare = true;
@@ -1590,8 +1600,10 @@ async function stopScreenShare() {
await replaceOutboundVideoTrack(cameraTrack);
}
shareButton.textContent = "Share Screen";
await sendRoomEvent({ type: "presentation-state", sharing: false });
setActivity(displayName, "stopped sharing their screen.");
if (announce) {
await sendRoomEvent({ type: "presentation-state", sharing: false });
setActivity(displayName, "stopped sharing their screen.");
}
} finally {
streamToStop.getTracks().forEach((track) => {
track.onended = null;
+14
View File
@@ -327,6 +327,20 @@ const server = http.createServer(async (req, res) => {
};
if (event.sharing) {
const previous = presentationStates.get(roomId);
if (previous?.peerId && previous.peerId !== payload.from) {
broadcast(roomId, payload.from, {
type: "presentation-state",
from: previous.peerId,
peerId: previous.peerId,
name: previous.name,
sharing: false,
reason: "takeover",
replacedBy: payload.from,
replacedByName: event.name,
updatedAt: Date.now()
});
}
presentationStates.set(roomId, { ...event, peerId: payload.from });
} else if (presentationStates.get(roomId)?.peerId === payload.from) {
presentationStates.delete(roomId);