[mirotalksfu] - fix whiteboard & add lock functionality

هذا الالتزام موجود في:
Miroslav Pejic
2023-08-08 11:02:04 +02:00
الأصل 037db75928
التزام a1cb5234cf
6 ملفات معدلة مع 72 إضافات و9 حذوفات

عرض الملف

@@ -159,9 +159,8 @@ $ PORT=3011 npm start
![docker](public/images/docker.png) ![docker](public/images/docker.png)
- Install docker engine: https://docs.docker.com/engine/install/ - Install [docker engine](https://docs.docker.com/engine/install/)
- Install docker compose: https://docs.docker.com/compose/install/ - Install [docker compose](https://docs.docker.com/compose/install/)
- Repository docker hub: https://hub.docker.com/r/mirotalk/sfu
```bash ```bash
# Copy app/src/config.template.js in app/src/config.js IMPORTANT (edit it according to your needs) # Copy app/src/config.template.js in app/src/config.js IMPORTANT (edit it according to your needs)
@@ -177,6 +176,7 @@ $ docker-compose down
``` ```
- Open in browser https://localhost:3010 - Open in browser https://localhost:3010
- Repository [docker hub](https://hub.docker.com/r/mirotalk/sfu)
</details> </details>

عرض الملف

@@ -987,6 +987,11 @@ progress {
cursor: move; cursor: move;
} }
.whiteboard-header-title {
display: flex;
align-items: center;
}
.whiteboard-header button { .whiteboard-header button {
padding: 10px; padding: 10px;
margin: 2px; margin: 2px;

عرض الملف

@@ -107,6 +107,7 @@ let recTimer = null;
let recElapsedTime = null; let recElapsedTime = null;
let wbCanvas = null; let wbCanvas = null;
let wbIsLock = false;
let wbIsDrawing = false; let wbIsDrawing = false;
let wbIsOpen = false; let wbIsOpen = false;
let wbIsRedoing = false; let wbIsRedoing = false;
@@ -178,6 +179,7 @@ function initClient() {
setTippy('whiteboardSaveBtn', 'Save', 'bottom'); setTippy('whiteboardSaveBtn', 'Save', 'bottom');
setTippy('whiteboardEraserBtn', 'Eraser', 'bottom'); setTippy('whiteboardEraserBtn', 'Eraser', 'bottom');
setTippy('whiteboardCleanBtn', 'Clean', 'bottom'); setTippy('whiteboardCleanBtn', 'Clean', 'bottom');
setTippy('whiteboardLockButton', 'If enabled, participants cannot interact', 'right');
setTippy('whiteboardCloseBtn', 'Close', 'right'); setTippy('whiteboardCloseBtn', 'Close', 'right');
setTippy('chatCleanTextButton', 'Clean', 'top'); setTippy('chatCleanTextButton', 'Clean', 'top');
setTippy('chatPasteButton', 'Paste', 'top'); setTippy('chatPasteButton', 'Paste', 'top');
@@ -851,6 +853,10 @@ function roomIsReady() {
} }
} }
function elemDisplay(element, display, mode = 'block') {
element.style.display = display ? mode : 'none';
}
function hide(elem) { function hide(elem) {
elem.className = 'hidden'; elem.className = 'hidden';
} }
@@ -1137,6 +1143,10 @@ function handleButtons() {
whiteboardCleanBtn.onclick = () => { whiteboardCleanBtn.onclick = () => {
confirmClearBoard(); confirmClearBoard();
}; };
whiteboardLockButton.onchange = () => {
wbIsLock = !wbIsLock;
whiteboardAction(getWhiteboardAction(wbIsLock ? 'lock' : 'unlock'));
};
whiteboardCloseBtn.onclick = () => { whiteboardCloseBtn.onclick = () => {
whiteboardAction(getWhiteboardAction('close')); whiteboardAction(getWhiteboardAction('close'));
}; };
@@ -2097,7 +2107,16 @@ function wbCanvasSaveImg() {
saveDataToFile(dataURL, fileName); saveDataToFile(dataURL, fileName);
} }
function wbUpdate() {
if (wbIsOpen && (!isRulesActive || isPresenter)) {
console.log('IsPresenter: update whiteboard canvas to the participants in the room');
wbCanvasToJson();
whiteboardAction(getWhiteboardAction(wbIsLock ? 'lock' : 'unlock'));
}
}
function wbCanvasToJson() { function wbCanvasToJson() {
if (!isPresenter && wbIsLock) return;
if (rc.thereIsParticipants()) { if (rc.thereIsParticipants()) {
let wbCanvasJson = JSON.stringify(wbCanvas.toJSON()); let wbCanvasJson = JSON.stringify(wbCanvas.toJSON());
rc.socket.emit('wbCanvasToJson', wbCanvasJson); rc.socket.emit('wbCanvasToJson', wbCanvasJson);
@@ -2106,9 +2125,11 @@ function wbCanvasToJson() {
function JsonToWbCanvas(json) { function JsonToWbCanvas(json) {
if (!wbIsOpen) toggleWhiteboard(); if (!wbIsOpen) toggleWhiteboard();
wbCanvas.loadFromJSON(json); wbCanvas.loadFromJSON(json);
wbCanvas.renderAll(); wbCanvas.renderAll();
if (!isPresenter && !wbCanvas.isDrawingMode && wbIsLock) {
wbDrawing(false);
}
} }
function getWhiteboardAction(action) { function getWhiteboardAction(action) {
@@ -2164,6 +2185,24 @@ function whiteboardAction(data, emit = true) {
case 'clear': case 'clear':
wbCanvas.clear(); wbCanvas.clear();
break; break;
case 'lock':
if (!isPresenter) {
elemDisplay(whiteboardTitle, false);
elemDisplay(whiteboardOptions, false);
elemDisplay(whiteboardButton, false);
wbDrawing(false);
wbIsLock = true;
}
break;
case 'unlock':
if (!isPresenter) {
elemDisplay(whiteboardTitle, true, 'flex');
elemDisplay(whiteboardOptions, true, 'inline');
elemDisplay(whiteboardButton, true);
wbDrawing(true);
wbIsLock = false;
}
break;
case 'close': case 'close':
if (wbIsOpen) toggleWhiteboard(); if (wbIsOpen) toggleWhiteboard();
break; break;
@@ -2171,6 +2210,14 @@ function whiteboardAction(data, emit = true) {
} }
} }
function wbDrawing(status) {
wbCanvas.isDrawingMode = status; // Disable free drawing
wbCanvas.selection = status; // Disable object selection
wbCanvas.forEachObject(function (obj) {
obj.selectable = status; // Make all objects unselectable
});
}
// #################################################### // ####################################################
// HANDLE PARTICIPANTS // HANDLE PARTICIPANTS
// #################################################### // ####################################################

عرض الملف

@@ -1624,10 +1624,8 @@ class RoomClient {
async consume(producer_id, peer_name, peer_info, type) { async consume(producer_id, peer_name, peer_info, type) {
// //
if (wbIsOpen && (!isRulesActive || isPresenter)) { wbUpdate();
console.log('Update whiteboard canvas to the participants in the room');
wbCanvasToJson();
}
this.getConsumeStream(producer_id, peer_info.peer_id, type).then( this.getConsumeStream(producer_id, peer_info.peer_id, type).then(
function ({ consumer, stream, kind }) { function ({ consumer, stream, kind }) {
console.log('CONSUMER MEDIA TYPE ----> ' + type); console.log('CONSUMER MEDIA TYPE ----> ' + type);
@@ -1983,6 +1981,8 @@ class RoomClient {
this.setTippy(ko.id, 'Eject', 'top-end'); this.setTippy(ko.id, 'Eject', 'top-end');
} }
console.log('[setVideoOff] Video-element-count', this.videoMediaContainer.childElementCount); console.log('[setVideoOff] Video-element-count', this.videoMediaContainer.childElementCount);
//
wbUpdate();
} }
removeVideoOff(peer_id) { removeVideoOff(peer_id) {

عرض الملف

@@ -68,6 +68,9 @@ const BUTTONS = {
participantsList: { participantsList: {
saveInfoButton: true, saveInfoButton: true,
}, },
whiteboard: {
whiteboardLockButton: false,
},
//... //...
}; };
@@ -84,6 +87,7 @@ function handleRules(isPresenter) {
BUTTONS.consumerVideo.ejectButton = false; BUTTONS.consumerVideo.ejectButton = false;
BUTTONS.consumerVideo.muteAudioButton = false; BUTTONS.consumerVideo.muteAudioButton = false;
BUTTONS.consumerVideo.muteVideoButton = false; BUTTONS.consumerVideo.muteVideoButton = false;
BUTTONS.whiteboard.whiteboardLockButton = false;
//... //...
} else { } else {
BUTTONS.participantsList.saveInfoButton = true; BUTTONS.participantsList.saveInfoButton = true;
@@ -95,6 +99,7 @@ function handleRules(isPresenter) {
BUTTONS.consumerVideo.ejectButton = true; BUTTONS.consumerVideo.ejectButton = true;
BUTTONS.consumerVideo.muteAudioButton = true; BUTTONS.consumerVideo.muteAudioButton = true;
BUTTONS.consumerVideo.muteVideoButton = true; BUTTONS.consumerVideo.muteVideoButton = true;
BUTTONS.whiteboard.whiteboardLockButton = true;
//... //...
} }
// main. settings... // main. settings...
@@ -102,5 +107,8 @@ function handleRules(isPresenter) {
BUTTONS.settings.unlockRoomButton ? show(unlockRoomButton) : hide(unlockRoomButton); BUTTONS.settings.unlockRoomButton ? show(unlockRoomButton) : hide(unlockRoomButton);
BUTTONS.settings.lobbyButton ? show(lobbyButton) : hide(lobbyButton); BUTTONS.settings.lobbyButton ? show(lobbyButton) : hide(lobbyButton);
BUTTONS.participantsList.saveInfoButton ? show(participantsSaveBtn) : hide(participantsSaveBtn); BUTTONS.participantsList.saveInfoButton ? show(participantsSaveBtn) : hide(participantsSaveBtn);
BUTTONS.whiteboard.whiteboardLockButton
? elemDisplay(whiteboardLockButton, true)
: elemDisplay(whiteboardLockButton, false, 'flex');
//... //...
} }

عرض الملف

@@ -412,8 +412,11 @@ access to use this app.
<header id="whiteboardHeader" class="whiteboard-header"> <header id="whiteboardHeader" class="whiteboard-header">
<div id="whiteboardTitle" class="whiteboard-header-title"> <div id="whiteboardTitle" class="whiteboard-header-title">
<button id="whiteboardCloseBtn" class="fas fa-times"></button> <button id="whiteboardCloseBtn" class="fas fa-times"></button>
<div class="form-check form-switch form-switch-md" style="margin-left: 10px">
<input id="whiteboardLockButton" class="form-check-input" type="checkbox" />
</div>
</div> </div>
<div class="whiteboard-header-options"> <div id="whiteboardOptions" class="whiteboard-header-options">
<button id="whiteboardGhostButton" class="fas fa-circle-half-stroke"></button> <button id="whiteboardGhostButton" class="fas fa-circle-half-stroke"></button>
<input id="wbBackgroundColorEl" class="whiteboardColorPicker" type="color" value="#000000" /> <input id="wbBackgroundColorEl" class="whiteboardColorPicker" type="color" value="#000000" />
<input id="wbDrawingColorEl" class="whiteboardColorPicker" type="color" value="#FFFFFF" /> <input id="wbDrawingColorEl" class="whiteboardColorPicker" type="color" value="#FFFFFF" />