From dced5c66c6bbe996f3e0c7b78ed1c6b52e334f53 Mon Sep 17 00:00:00 2001 From: Miroslav Pejic Date: Fri, 27 Aug 2021 20:28:46 +0200 Subject: [PATCH] [mirotalksfu] - add Room Lock/Unlock --- public/Room.html | 6 ++++ public/images/locked.png | Bin 0 -> 3290 bytes public/js/Room.js | 21 +++++++++++-- public/js/RoomClient.js | 64 ++++++++++++++++++++++++++++++++++++++- public/sounds/locked.wav | Bin 0 -> 79554 bytes src/Room.js | 12 ++++++++ src/Server.js | 28 +++++++++++++++-- 7 files changed, 126 insertions(+), 5 deletions(-) create mode 100644 public/images/locked.png create mode 100644 public/sounds/locked.wav diff --git a/public/Room.html b/public/Room.html index 3903338..12229a5 100644 --- a/public/Room.html +++ b/public/Room.html @@ -147,6 +147,12 @@ + + diff --git a/public/images/locked.png b/public/images/locked.png new file mode 100644 index 0000000000000000000000000000000000000000..42524443c87c0ca30632cc536c97f05082a4b913 GIT binary patch literal 3290 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 YFB-{kKFB4>c>n+a07*qoM6N<$f&fV%(*OVf literal 0 HcmV?d00001 diff --git a/public/js/Room.js b/public/js/Room.js index f80247b..1232650 100644 --- a/public/js/Room.js +++ b/public/js/Room.js @@ -67,6 +67,8 @@ function initClient() { setTippy('stopVideoButton', 'Stop Video', 'bottom'); setTippy('startScreenButton', 'Start Screen', 'bottom'); setTippy('stopScreenButton', 'Stop Screen', 'bottom'); + setTippy('lockRoomButton', 'Room Lock', 'bottom'); + setTippy('unlockRoomButton', 'Room Unlock', 'bottom'); setTippy('aboutButton', 'About', 'bottom'); } initEnumerateDevices(); @@ -273,7 +275,7 @@ async function shareRoom(useNavigator = false) { background: swalBackground, imageUrl: swalImageUrl, imageWidth: 300, - imageHeight: 200, + imageHeight: 150, position: 'center', title: 'Hello ' + peer_name + '', html: @@ -400,6 +402,7 @@ function roomIsReady() { if (isAudioAllowed) show(startAudioButton); if (isVideoAllowed) show(startVideoButton); show(videoMedia); + show(lockRoomButton); show(aboutButton); handleButtons(); handleSelects(); @@ -553,6 +556,12 @@ function handleButtons() { stopScreenButton.onclick = () => { rc.closeProducer(RoomClient.mediaType.screen); }; + lockRoomButton.onclick = () => { + rc.roomAction('lock'); + }; + unlockRoomButton.onclick = () => { + rc.roomAction('unlock'); + }; aboutButton.onclick = () => { showAbout(); }; @@ -667,6 +676,14 @@ function handleRoomClientEvents() { hide(stopScreenButton); show(startScreenButton); }); + rc.on(RoomClient.EVENTS.roomLock, () => { + hide(lockRoomButton); + show(unlockRoomButton); + }); + rc.on(RoomClient.EVENTS.roomUnlock, () => { + hide(unlockRoomButton); + show(lockRoomButton); + }); rc.on(RoomClient.EVENTS.exitRoom, () => { window.location.href = '/newroom'; }); @@ -715,7 +732,7 @@ function showAbout() { background: swalBackground, imageUrl: swalImageUrl, imageWidth: 300, - imageHeight: 200, + imageHeight: 150, position: 'center', html: `
diff --git a/public/js/RoomClient.js b/public/js/RoomClient.js index e114b54..d3937c6 100644 --- a/public/js/RoomClient.js +++ b/public/js/RoomClient.js @@ -11,6 +11,7 @@ const html = { const image = { poster: '../images/loader.gif', delete: '../images/delete.png', + locked: '../images/locked.png', }; const mediaType = { @@ -39,6 +40,8 @@ const _EVENTS = { pauseScreen: 'pauseScreen', resumeScreen: 'resumeScreen', stopScreen: 'stopScreen', + roomLock: 'roomLock', + roomUnlock: 'roomUnlock', }; let recordedBlobs; @@ -171,6 +174,10 @@ class RoomClient { .request('join', data) .then( async function (room) { + if (room === 'isLocked') { + this.roomIsLocked(); + return; + } this.connectedRoom = room; console.log('07 ----> Joined to room', this.connectedRoom); const data = await this.socket.request('getRouterRtpCapabilities'); @@ -359,11 +366,19 @@ class RoomClient { this.socket.on( 'message', function (data) { - console.log('message', data); + console.log('Message', data); this.showMessage(data); }.bind(this), ); + this.socket.on( + 'roomAction', + function (data) { + console.log('Room action:', data); + this.roomAction(data, false); + }.bind(this), + ); + this.socket.on( 'disconnect', function () { @@ -1365,4 +1380,51 @@ class RoomClient { this.event(_EVENTS.stopRec); this.sound('recStop'); } + + // #################################################### + // ROOM ACTION + // #################################################### + + roomAction(action, emit = true) { + if (emit) this.socket.emit('roomAction', action); + switch (action) { + case 'lock': + this.sound('locked'); + this.event(_EVENTS.roomLock); + this.userLog('info', '🔒 LOCKED the room, no one can access!', 'top-end'); + break; + case 'unlock': + this.event(_EVENTS.roomUnlock); + this.userLog('info', '🔓 UNLOCKED the room', 'top-end'); + break; + } + } + + // #################################################### + // HANDLE ROOM ACTION + // #################################################### + + roomIsLocked() { + this.sound('locked'); + this.event(_EVENTS.roomLock); + console.log('Room is Locked, try with another one'); + Swal.fire({ + allowOutsideClick: false, + background: swalBackground, + position: 'center', + imageUrl: image.locked, + title: 'Oops, Room Locked', + text: 'The room is locked, try with another one.', + showDenyButton: false, + confirmButtonText: `Ok`, + showClass: { + popup: 'animate__animated animate__fadeInDown', + }, + hideClass: { + popup: 'animate__animated animate__fadeOutUp', + }, + }).then((result) => { + if (result.isConfirmed) this.exit(); + }); + } } diff --git a/public/sounds/locked.wav b/public/sounds/locked.wav new file mode 100644 index 0000000000000000000000000000000000000000..de7439c8795092b36e9e30b0f356611c9ba4a631 GIT binary patch literal 79554 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 z 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ⅇPL+1JL3O5ely-&^qsS_ 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 G*#7`c;q)>9 literal 0 HcmV?d00001 diff --git a/src/Room.js b/src/Room.js index 52fd3f0..3b153bc 100644 --- a/src/Room.js +++ b/src/Room.js @@ -10,6 +10,7 @@ module.exports = class Room { this.worker = worker; this.router = null; this.io = io; + this._isLocked = false; this.peers = new Map(); this.createTheRouter(); } @@ -187,6 +188,17 @@ module.exports = class Room { this.peers.get(socket_id).closeProducer(producer_id); } + // #################################################### + // ROOM STATUS + // #################################################### + + isLocked() { + return this._isLocked; + } + setLocked(status) { + this._isLocked = status; + } + // #################################################### // SENDER // #################################################### diff --git a/src/Server.js b/src/Server.js index 27a21be..b5967dc 100644 --- a/src/Server.js +++ b/src/Server.js @@ -203,16 +203,36 @@ io.on('connection', (socket) => { } }); - socket.on('join', (data, cb) => { - log.debug('User joined', data); + socket.on('roomAction', (action) => { + switch (action) { + case 'lock': + roomList.get(socket.room_id).setLocked(true); + break; + case 'unlock': + roomList.get(socket.room_id).setLocked(false); + break; + } + log.debug('Room locked:', roomList.get(socket.room_id).isLocked()); + // send to all participants + roomList.get(socket.room_id).broadCast(socket.id, 'roomAction', action); + }); + socket.on('join', (data, cb) => { if (!roomList.has(socket.room_id)) { return cb({ error: 'Room does not exist', }); } + log.debug('User joined', data); roomList.get(socket.room_id).addPeer(new Peer(socket.id, data)); + + if (roomList.get(socket.room_id).isLocked()) { + log.debug('User rejected because room is locked'); + cb('isLocked'); + return; + } + cb(roomList.get(socket.room_id).toJson()); }); @@ -327,6 +347,10 @@ io.on('connection', (socket) => { log.debug('Disconnect', getPeerName()); roomList.get(socket.room_id).removePeer(socket.id); + + if (roomList.get(socket.room_id).getPeers().size === 0 && roomList.get(socket.room_id).isLocked()) { + roomList.get(socket.room_id).setLocked(false); + } }); socket.on('exitRoom', async (_, callback) => {