[mirotalksfu] - add ban button, update dep

هذا الالتزام موجود في:
Miroslav Pejic
2024-01-31 12:53:36 +01:00
الأصل a4f9748cac
التزام 70c3542fdf
6 ملفات معدلة مع 117 إضافات و17 حذوفات

عرض الملف

@@ -40,7 +40,7 @@ dependencies: {
* @license For commercial or closed source, contact us at license.mirotalk@gmail.com or purchase directly via CodeCanyon * @license For commercial or closed source, contact us at license.mirotalk@gmail.com or purchase directly via CodeCanyon
* @license CodeCanyon: https://codecanyon.net/item/mirotalk-sfu-webrtc-realtime-video-conferences/40769970 * @license CodeCanyon: https://codecanyon.net/item/mirotalk-sfu-webrtc-realtime-video-conferences/40769970
* @author Miroslav Pejic - miroslav.pejic.85@gmail.com * @author Miroslav Pejic - miroslav.pejic.85@gmail.com
* @version 1.3.59 * @version 1.3.60
* *
*/ */
@@ -773,7 +773,18 @@ function startServer() {
log.debug('Peer action', data); log.debug('Peer action', data);
const presenterActions = ['mute', 'unmute', 'hide', 'unhide', 'stop', 'start', 'eject', 'geoLocation']; const presenterActions = [
'mute',
'unmute',
'hide',
'unhide',
'stop',
'start',
'eject',
'ban',
'geoLocation',
];
if (presenterActions.some((v) => data.action === v)) { if (presenterActions.some((v) => data.action === v)) {
const isPresenter = await isPeerPresenter( const isPresenter = await isPeerPresenter(
socket.room_id, socket.room_id,
@@ -786,7 +797,7 @@ function startServer() {
const room = roomList.get(socket.room_id); const room = roomList.get(socket.room_id);
if (data.action === 'eject') room.addBannedPeer(data.to_peer_uuid); if (data.action === 'ban') room.addBannedPeer(data.to_peer_uuid);
data.broadcast data.broadcast
? room.broadCast(data.peer_id, 'peerAction', data) ? room.broadCast(data.peer_id, 'peerAction', data)

عرض الملف

@@ -1,6 +1,6 @@
{ {
"name": "mirotalksfu", "name": "mirotalksfu",
"version": "1.3.59", "version": "1.3.60",
"description": "WebRTC SFU browser-based video calls", "description": "WebRTC SFU browser-based video calls",
"main": "Server.js", "main": "Server.js",
"scripts": { "scripts": {
@@ -38,8 +38,8 @@
"author": "Miroslav Pejic", "author": "Miroslav Pejic",
"license": "AGPL-3.0", "license": "AGPL-3.0",
"dependencies": { "dependencies": {
"@sentry/integrations": "7.98.0", "@sentry/integrations": "7.99.0",
"@sentry/node": "7.98.0", "@sentry/node": "7.99.0",
"axios": "^1.6.7", "axios": "^1.6.7",
"body-parser": "1.20.2", "body-parser": "1.20.2",
"colors": "1.4.0", "colors": "1.4.0",

عرض الملف

@@ -11,7 +11,7 @@ if (location.href.substr(0, 5) !== 'https') location.href = 'https' + location.h
* @license For commercial or closed source, contact us at license.mirotalk@gmail.com or purchase directly via CodeCanyon * @license For commercial or closed source, contact us at license.mirotalk@gmail.com or purchase directly via CodeCanyon
* @license CodeCanyon: https://codecanyon.net/item/mirotalk-sfu-webrtc-realtime-video-conferences/40769970 * @license CodeCanyon: https://codecanyon.net/item/mirotalk-sfu-webrtc-realtime-video-conferences/40769970
* @author Miroslav Pejic - miroslav.pejic.85@gmail.com * @author Miroslav Pejic - miroslav.pejic.85@gmail.com
* @version 1.3.59 * @version 1.3.60
* *
*/ */
@@ -48,6 +48,7 @@ const _PEER = {
raiseHand: '<i style="color: rgb(0, 255, 71);" class="fas fa-hand-paper pulsate"></i>', raiseHand: '<i style="color: rgb(0, 255, 71);" class="fas fa-hand-paper pulsate"></i>',
lowerHand: '', lowerHand: '',
acceptPeer: '<i class="fas fa-check"></i>', acceptPeer: '<i class="fas fa-check"></i>',
banPeer: '<i class="fas fa-ban"></i>',
ejectPeer: '<i class="fas fa-times"></i>', ejectPeer: '<i class="fas fa-times"></i>',
geoLocation: '<i class="fas fa-location-dot"></i>', geoLocation: '<i class="fas fa-location-dot"></i>',
sendFile: '<i class="fas fa-upload"></i>', sendFile: '<i class="fas fa-upload"></i>',
@@ -3206,6 +3207,7 @@ function getParticipantsList(peers) {
const peer_video = peer_info.peer_video ? _PEER.videoOn : _PEER.videoOff; const peer_video = peer_info.peer_video ? _PEER.videoOn : _PEER.videoOff;
const peer_screen = peer_info.peer_screen ? _PEER.screenOn : _PEER.screenOff; const peer_screen = peer_info.peer_screen ? _PEER.screenOn : _PEER.screenOff;
const peer_hand = peer_info.peer_hand ? _PEER.raiseHand : _PEER.lowerHand; const peer_hand = peer_info.peer_hand ? _PEER.raiseHand : _PEER.lowerHand;
const peer_ban = _PEER.banPeer;
const peer_eject = _PEER.ejectPeer; const peer_eject = _PEER.ejectPeer;
const peer_geoLocation = _PEER.geoLocation; const peer_geoLocation = _PEER.geoLocation;
const peer_sendFile = _PEER.sendFile; const peer_sendFile = _PEER.sendFile;
@@ -3247,6 +3249,7 @@ function getParticipantsList(peers) {
<li><button class="btn-sm ml5" id='${peer_id}___shareFile' onclick="rc.selectFileToShare('${peer_id}', false)">${peer_sendFile} Share file</button></li> <li><button class="btn-sm ml5" id='${peer_id}___shareFile' onclick="rc.selectFileToShare('${peer_id}', false)">${peer_sendFile} Share file</button></li>
<li><button class="btn-sm ml5" id="${peer_id}___sendVideoTo" onclick="rc.shareVideo('${peer_id}');">${_PEER.sendVideo} Share audio/video</button></li> <li><button class="btn-sm ml5" id="${peer_id}___sendVideoTo" onclick="rc.shareVideo('${peer_id}');">${_PEER.sendVideo} Share audio/video</button></li>
<li><button class="btn-sm ml5" id='${peer_id}___geoLocation' onclick="rc.askPeerGeoLocation(this.id)">${peer_geoLocation} Get geolocation</button></li> <li><button class="btn-sm ml5" id='${peer_id}___geoLocation' onclick="rc.askPeerGeoLocation(this.id)">${peer_geoLocation} Get geolocation</button></li>
<li><button class="btn-sm ml5" id='${peer_id}___pBan' onclick="rc.peerAction('me',this.id,'ban')">${peer_ban} Ban participant</button></li>
<li><button class="btn-sm ml5" id='${peer_id}___pEject' onclick="rc.peerAction('me',this.id,'eject')">${peer_eject} Eject participant</button></li> <li><button class="btn-sm ml5" id='${peer_id}___pEject' onclick="rc.peerAction('me',this.id,'eject')">${peer_eject} Eject participant</button></li>
</ul> </ul>
</div> </div>

عرض الملف

@@ -9,7 +9,7 @@
* @license For commercial or closed source, contact us at license.mirotalk@gmail.com or purchase directly via CodeCanyon * @license For commercial or closed source, contact us at license.mirotalk@gmail.com or purchase directly via CodeCanyon
* @license CodeCanyon: https://codecanyon.net/item/mirotalk-sfu-webrtc-realtime-video-conferences/40769970 * @license CodeCanyon: https://codecanyon.net/item/mirotalk-sfu-webrtc-realtime-video-conferences/40769970
* @author Miroslav Pejic - miroslav.pejic.85@gmail.com * @author Miroslav Pejic - miroslav.pejic.85@gmail.com
* @version 1.3.59 * @version 1.3.60
* *
*/ */
@@ -33,6 +33,8 @@ const html = {
sendFile: 'fas fa-upload', sendFile: 'fas fa-upload',
sendMsg: 'fas fa-paper-plane', sendMsg: 'fas fa-paper-plane',
sendVideo: 'fab fa-youtube', sendVideo: 'fab fa-youtube',
geolocation: 'fas fa-location-dot',
ban: 'fas fa-ban',
kickOut: 'fas fa-times', kickOut: 'fas fa-times',
ghost: 'fas fa-ghost', ghost: 'fas fa-ghost',
undo: 'fas fa-undo', undo: 'fas fa-undo',
@@ -1943,7 +1945,7 @@ class RoomClient {
} }
handleConsumer(id, type, stream, peer_name, peer_info) { handleConsumer(id, type, stream, peer_name, peer_info) {
let elem, vb, d, p, i, cm, au, pip, fs, ts, sf, sm, sv, ko, pb, pm, pv, pn; let elem, vb, d, p, i, cm, au, pip, fs, ts, sf, sm, sv, ban, ko, pb, pm, pv, pn;
console.log('PEER-INFO', peer_info); console.log('PEER-INFO', peer_info);
@@ -2004,6 +2006,9 @@ class RoomClient {
au = document.createElement('button'); au = document.createElement('button');
au.id = remotePeerId + '__audio'; au.id = remotePeerId + '__audio';
au.className = remotePeerAudio ? html.audioOn : html.audioOff; au.className = remotePeerAudio ? html.audioOn : html.audioOff;
ban = document.createElement('button');
ban.id = id + '___' + remotePeerId + '___ban';
ban.className = html.ban;
ko = document.createElement('button'); ko = document.createElement('button');
ko.id = id + '___' + remotePeerId + '___kickOut'; ko.id = id + '___' + remotePeerId + '___kickOut';
ko.className = html.kickOut; ko.className = html.kickOut;
@@ -2023,6 +2028,7 @@ class RoomClient {
pb.style.height = '1%'; pb.style.height = '1%';
pm.appendChild(pb); pm.appendChild(pb);
BUTTONS.consumerVideo.ejectButton && vb.appendChild(ko); BUTTONS.consumerVideo.ejectButton && vb.appendChild(ko);
BUTTONS.consumerVideo.banButton && vb.appendChild(ban);
BUTTONS.consumerVideo.audioVolumeInput && !this.isMobileDevice && vb.appendChild(pv); BUTTONS.consumerVideo.audioVolumeInput && !this.isMobileDevice && vb.appendChild(pv);
vb.appendChild(au); vb.appendChild(au);
vb.appendChild(cm); vb.appendChild(cm);
@@ -2052,6 +2058,7 @@ class RoomClient {
BUTTONS.consumerVideo.muteVideoButton && this.handleCM(cm.id); BUTTONS.consumerVideo.muteVideoButton && this.handleCM(cm.id);
BUTTONS.consumerVideo.muteAudioButton && this.handleAU(au.id); BUTTONS.consumerVideo.muteAudioButton && this.handleAU(au.id);
this.handlePV(id + '___' + pv.id); this.handlePV(id + '___' + pv.id);
this.handleBAN(ban.id);
this.handleKO(ko.id); this.handleKO(ko.id);
this.handlePN(elem.id, pn.id, d.id, remoteIsScreen); this.handlePN(elem.id, pn.id, d.id, remoteIsScreen);
this.handleZV(elem.id, d.id, remotePeerId); this.handleZV(elem.id, d.id, remotePeerId);
@@ -2072,6 +2079,7 @@ class RoomClient {
this.setTippy(cm.id, 'Hide', 'bottom'); this.setTippy(cm.id, 'Hide', 'bottom');
this.setTippy(au.id, 'Mute', 'bottom'); this.setTippy(au.id, 'Mute', 'bottom');
this.setTippy(pv.id, '🔊 Volume', 'bottom'); this.setTippy(pv.id, '🔊 Volume', 'bottom');
this.setTippy(ban.id, 'Ban', 'bottom');
this.setTippy(ko.id, 'Eject', 'bottom'); this.setTippy(ko.id, 'Eject', 'bottom');
} }
this.setPeerAudio(remotePeerId, remotePeerAudio); this.setPeerAudio(remotePeerId, remotePeerAudio);
@@ -2154,7 +2162,7 @@ class RoomClient {
setVideoOff(peer_info, remotePeer = false) { setVideoOff(peer_info, remotePeer = false) {
//console.log('setVideoOff', peer_info); //console.log('setVideoOff', peer_info);
let d, vb, i, h, au, sf, sm, sv, ko, p, pm, pb, pv; let d, vb, i, h, au, sf, sm, sv, ban, ko, p, pm, pb, pv;
let peer_id = peer_info.peer_id; let peer_id = peer_info.peer_id;
let peer_name = peer_info.peer_name; let peer_name = peer_info.peer_name;
let peer_audio = peer_info.peer_audio; let peer_audio = peer_info.peer_audio;
@@ -2184,6 +2192,9 @@ class RoomClient {
sv = document.createElement('button'); sv = document.createElement('button');
sv.id = 'remotePeer___' + peer_id + '___sendVideo'; sv.id = 'remotePeer___' + peer_id + '___sendVideo';
sv.className = html.sendVideo; sv.className = html.sendVideo;
ban = document.createElement('button');
ban.id = 'remotePeer___' + peer_id + '___ban';
ban.className = html.ban;
ko = document.createElement('button'); ko = document.createElement('button');
ko.id = 'remotePeer___' + peer_id + '___kickOut'; ko.id = 'remotePeer___' + peer_id + '___kickOut';
ko.className = html.kickOut; ko.className = html.kickOut;
@@ -2208,6 +2219,7 @@ class RoomClient {
pm.appendChild(pb); pm.appendChild(pb);
if (remotePeer) { if (remotePeer) {
BUTTONS.videoOff.ejectButton && vb.appendChild(ko); BUTTONS.videoOff.ejectButton && vb.appendChild(ko);
BUTTONS.videoOff.banButton && vb.appendChild(ban);
BUTTONS.videoOff.sendVideoButton && vb.appendChild(sv); BUTTONS.videoOff.sendVideoButton && vb.appendChild(sv);
BUTTONS.videoOff.sendFileButton && vb.appendChild(sf); BUTTONS.videoOff.sendFileButton && vb.appendChild(sf);
BUTTONS.videoOff.sendMessageButton && vb.appendChild(sm); BUTTONS.videoOff.sendMessageButton && vb.appendChild(sm);
@@ -2226,6 +2238,7 @@ class RoomClient {
this.handleSM(sm.id); this.handleSM(sm.id);
this.handleSF(sf.id); this.handleSF(sf.id);
this.handleSV(sv.id); this.handleSV(sv.id);
this.handleBAN(ban.id);
this.handleKO(ko.id); this.handleKO(ko.id);
} }
this.handleDD(d.id, peer_id, !remotePeer); this.handleDD(d.id, peer_id, !remotePeer);
@@ -2240,6 +2253,7 @@ class RoomClient {
this.setTippy(sv.id, 'Send video', 'bottom'); this.setTippy(sv.id, 'Send video', 'bottom');
this.setTippy(au.id, 'Mute', 'bottom'); this.setTippy(au.id, 'Mute', 'bottom');
this.setTippy(pv.id, '🔊 Volume', 'bottom'); this.setTippy(pv.id, '🔊 Volume', 'bottom');
this.setTippy(ban.id, 'Ban', 'bottom');
this.setTippy(ko.id, 'Eject', 'bottom'); this.setTippy(ko.id, 'Eject', 'bottom');
} }
remotePeer ? this.setPeerAudio(peer_id, peer_audio) : this.setIsAudio(peer_id, peer_audio); remotePeer ? this.setPeerAudio(peer_id, peer_audio) : this.setIsAudio(peer_id, peer_audio);
@@ -5357,6 +5371,23 @@ class RoomClient {
} }
} }
// ####################################################
// HANDLE BAN
// ###################################################
handleBAN(uid) {
const words = uid.split('___');
let peer_id = words[1] + '___pBan';
let btnBan = this.getId(uid);
if (btnBan) {
btnBan.addEventListener('click', () => {
isPresenter
? this.peerAction('me', peer_id, 'ban')
: this.userLog('warning', 'Only the presenter can ban the participants', 'top-end');
});
}
}
// #################################################### // ####################################################
// HANDLE KICK-OUT // HANDLE KICK-OUT
// ################################################### // ###################################################
@@ -5566,11 +5597,14 @@ class RoomClient {
} }
} }
break; break;
case 'eject': case 'ban':
if (!isRulesActive || isPresenter) { if (!isRulesActive || isPresenter) {
const peer_info = await getRemotePeerInfo(peer_id); const peer_info = await getRemotePeerInfo(peer_id);
console.log('EJECT PEER', peer_info); console.log('BAN PEER', peer_info);
if (peer_info) data.to_peer_uuid = peer_info.peer_uuid; if (peer_info) {
data.to_peer_uuid = peer_info.peer_uuid;
return this.confirmPeerAction(data.action, data);
}
} }
break; break;
default: default:
@@ -5582,6 +5616,16 @@ class RoomClient {
// receive... // receive...
const peerActionAllowed = peer_id === this.peer_id || broadcast; const peerActionAllowed = peer_id === this.peer_id || broadcast;
switch (action) { switch (action) {
case 'ban':
if (peerActionAllowed) {
const message = `Will ban you from the room${
msg ? `<br><br><span class="red">Reason: ${msg}</span>` : ''
}`;
this.exit(true);
this.sound(action);
this.peerActionProgress(from_peer_name, message, 5000, action);
}
break;
case 'eject': case 'eject':
if (peerActionAllowed) { if (peerActionAllowed) {
const message = `Will eject you from the room${ const message = `Will eject you from the room${
@@ -5715,6 +5759,7 @@ class RoomClient {
case 'refresh': case 'refresh':
getRoomParticipants(); getRoomParticipants();
break; break;
case 'ban':
case 'eject': case 'eject':
this.exit(); this.exit();
break; break;
@@ -5727,6 +5772,39 @@ class RoomClient {
confirmPeerAction(action, data) { confirmPeerAction(action, data) {
console.log('Confirm peer action', action); console.log('Confirm peer action', action);
switch (action) { switch (action) {
case 'ban':
let banConfirmed = false;
Swal.fire({
background: swalBackground,
position: 'center',
imageUrl: image.forbidden,
title: 'Ban current participant',
input: 'text',
inputPlaceholder: 'Ban reason',
showDenyButton: true,
confirmButtonText: `Yes`,
denyButtonText: `No`,
showClass: { popup: 'animate__animated animate__fadeInDown' },
hideClass: { popup: 'animate__animated animate__fadeOutUp' },
})
.then((result) => {
if (result.isConfirmed) {
banConfirmed = true;
const message = result.value;
if (message) data.message = message;
this.socket.emit('peerAction', data);
let peer = this.getId(data.peer_id);
if (peer) {
peer.parentNode.removeChild(peer);
participantsCount--;
refreshParticipantsCount(participantsCount);
}
}
})
.then(() => {
if (banConfirmed) this.peerActionProgress(action, 'In progress, wait...', 6000, 'refresh');
});
break;
case 'eject': case 'eject':
let ejectConfirmed = false; let ejectConfirmed = false;
let whoEject = data.broadcast ? 'All participants except yourself?' : 'current participant?'; let whoEject = data.broadcast ? 'All participants except yourself?' : 'current participant?';

عرض الملف

@@ -53,7 +53,8 @@ const BUTTONS = {
muteVideoButton: true, muteVideoButton: true,
muteAudioButton: true, muteAudioButton: true,
audioVolumeInput: true, // Disabled for mobile audioVolumeInput: true, // Disabled for mobile
ejectButton: true, banButton: true, // presenter
ejectButton: true, // presenter
}, },
videoOff: { videoOff: {
sendMessageButton: true, sendMessageButton: true,
@@ -61,7 +62,8 @@ const BUTTONS = {
sendVideoButton: true, sendVideoButton: true,
muteAudioButton: true, muteAudioButton: true,
audioVolumeInput: true, // Disabled for mobile audioVolumeInput: true, // Disabled for mobile
ejectButton: true, banButton: true, // presenter
ejectButton: true, // presenter
}, },
chat: { chat: {
chatPinButton: true, chatPinButton: true,
@@ -72,10 +74,10 @@ const BUTTONS = {
chatSpeechStartButton: true, chatSpeechStartButton: true,
}, },
participantsList: { participantsList: {
saveInfoButton: true, saveInfoButton: true, // presenter
}, },
whiteboard: { whiteboard: {
whiteboardLockButton: false, whiteboardLockButton: false, // presenter
}, },
//... //...
}; };
@@ -95,7 +97,9 @@ function handleRules(isPresenter) {
BUTTONS.settings.micOptionsButton = false; BUTTONS.settings.micOptionsButton = false;
BUTTONS.settings.tabModerator = false; BUTTONS.settings.tabModerator = false;
BUTTONS.videoOff.muteAudioButton = false; BUTTONS.videoOff.muteAudioButton = false;
BUTTONS.videoOff.banButton = false;
BUTTONS.videoOff.ejectButton = false; BUTTONS.videoOff.ejectButton = false;
BUTTONS.consumerVideo.banButton = false;
BUTTONS.consumerVideo.ejectButton = false; BUTTONS.consumerVideo.ejectButton = false;
//BUTTONS.consumerVideo.muteAudioButton = false; //BUTTONS.consumerVideo.muteAudioButton = false;
//BUTTONS.consumerVideo.muteVideoButton = false; //BUTTONS.consumerVideo.muteVideoButton = false;
@@ -113,7 +117,9 @@ function handleRules(isPresenter) {
BUTTONS.settings.micOptionsButton = true; BUTTONS.settings.micOptionsButton = true;
BUTTONS.settings.tabModerator = true; BUTTONS.settings.tabModerator = true;
BUTTONS.videoOff.muteAudioButton = true; BUTTONS.videoOff.muteAudioButton = true;
BUTTONS.videoOff.banButton = true;
BUTTONS.videoOff.ejectButton = true; BUTTONS.videoOff.ejectButton = true;
BUTTONS.consumerVideo.banButton = true;
BUTTONS.consumerVideo.ejectButton = true; BUTTONS.consumerVideo.ejectButton = true;
BUTTONS.consumerVideo.muteAudioButton = true; BUTTONS.consumerVideo.muteAudioButton = true;
BUTTONS.consumerVideo.muteVideoButton = true; BUTTONS.consumerVideo.muteVideoButton = true;
@@ -190,10 +196,12 @@ function handleRulesBroadcasting() {
BUTTONS.settings.unlockRoomButton = false; BUTTONS.settings.unlockRoomButton = false;
BUTTONS.settings.lobbyButton = false; BUTTONS.settings.lobbyButton = false;
BUTTONS.videoOff.muteAudioButton = false; BUTTONS.videoOff.muteAudioButton = false;
BUTTONS.videoOff.banButton = false;
BUTTONS.videoOff.ejectButton = false; BUTTONS.videoOff.ejectButton = false;
BUTTONS.consumerVideo.sendMessageButton = false; BUTTONS.consumerVideo.sendMessageButton = false;
BUTTONS.consumerVideo.sendFileButton = false; BUTTONS.consumerVideo.sendFileButton = false;
BUTTONS.consumerVideo.sendVideoButton = false; BUTTONS.consumerVideo.sendVideoButton = false;
BUTTONS.consumerVideo.banButton = false;
BUTTONS.consumerVideo.ejectButton = false; BUTTONS.consumerVideo.ejectButton = false;
BUTTONS.consumerVideo.muteAudioButton = false; BUTTONS.consumerVideo.muteAudioButton = false;
BUTTONS.consumerVideo.muteVideoButton = false; BUTTONS.consumerVideo.muteVideoButton = false;

ثنائية
public/sounds/ban.wav Normal file

ملف ثنائي غير معروض.