diff --git a/public/js/LocalStorage.js b/public/js/LocalStorage.js index 638f16cd..ee9dea7f 100644 --- a/public/js/LocalStorage.js +++ b/public/js/LocalStorage.js @@ -18,6 +18,7 @@ class LocalStorage { this.SFU_SETTINGS = { share_on_join: true, // popup message on join show_chat_on_msg: true, // show chat on new message + speech_in_msg: false, // speech incoming message video_fps: 0, // default 1280x768 30fps screen_fps: 0, // max 30fps lobby: false, // default false diff --git a/public/js/Room.js b/public/js/Room.js index 42615039..b44c7e3c 100644 --- a/public/js/Room.js +++ b/public/js/Room.js @@ -103,6 +103,7 @@ let isVideoControlsOn = false; let isChatPasteTxt = false; let isChatMarkdownOn = false; let isChatGPTOn = false; +let isSpeechSynthesisSupported = 'speechSynthesis' in window; let joinRoomWithoutAudioVideo = true; let joinRoomWithScreen = false; let initAudioButton = null; @@ -208,6 +209,7 @@ function initClient() { setTippy('chatPasteButton', 'Paste', 'top'); setTippy('chatSendButton', 'Send', 'top'); setTippy('showChatOnMsg', 'Show chat on new message comes', 'top'); + setTippy('speechIncomingMsg', 'speech the incoming messages', 'top'); setTippy('chatSpeechStartButton', 'Start speech recognition', 'top'); setTippy('chatSpeechStopButton', 'Stop speech recognition', 'top'); setTippy('chatEmojiButton', 'Emoji', 'top'); @@ -895,6 +897,7 @@ function joinRoom(peer_name, room_id) { isVideoAllowed, isScreenAllowed, joinRoomWithScreen, + isSpeechSynthesisSupported, roomIsReady, ); handleRoomClientEvents(); @@ -966,6 +969,7 @@ function roomIsReady() { BUTTONS.settings.host_only_recording && show(roomRecording); BUTTONS.main.aboutButton && show(aboutButton); if (!DetectRTC.isMobileDevice) show(pinUnpinGridDiv); + if (!isSpeechSynthesisSupported) hide(speechIncomingMsg); handleButtons(); handleSelects(); handleInputs(); @@ -1613,17 +1617,19 @@ function handleSelects() { }; // chat showChatOnMsg.onchange = (e) => { - sound('switch'); rc.showChatOnMessage = e.currentTarget.checked; - if (rc.showChatOnMessage) { - userLog('info', 'Chat will be shown, when you receive a message', 'top-end'); - } else { - userLog('info', 'Chat not will be shown, when you receive a message', 'top-end'); - } + rc.roomMessage('showChat', rc.showChatOnMessage); lsSettings.show_chat_on_msg = rc.showChatOnMessage; lS.setSettings(lsSettings); e.target.blur(); }; + speechIncomingMsg.onchange = (e) => { + rc.speechInMessages = e.currentTarget.checked; + rc.roomMessage('speechMessages', rc.speechInMessages); + lsSettings.speech_in_msg = rc.speechInMessages; + lS.setSettings(lsSettings); + e.target.blur(); + }; // whiteboard options wbDrawingColorEl.onchange = () => { wbCanvas.freeDrawingBrush.color = wbDrawingColorEl.value; @@ -1693,9 +1699,11 @@ function handleInputs() { function loadSettingsFromLocalStorage() { rc.showChatOnMessage = lsSettings.show_chat_on_msg; + rc.speechInMessages = lsSettings.speech_in_msg; isPitchBarEnabled = lsSettings.pitch_bar; isSoundEnabled = lsSettings.sounds; showChatOnMsg.checked = rc.showChatOnMessage; + speechIncomingMsg.checked = rc.speechInMessages; switchPitchBar.checked = isPitchBarEnabled; switchSounds.checked = isSoundEnabled; switchShare.checked = notify; diff --git a/public/js/RoomClient.js b/public/js/RoomClient.js index 3e5db1c6..af81b96d 100644 --- a/public/js/RoomClient.js +++ b/public/js/RoomClient.js @@ -42,6 +42,8 @@ const html = { }; const icons = { + chat: '', + speech: '', share: '', ptt: '', lobby: '', @@ -131,6 +133,7 @@ class RoomClient { isVideoAllowed, isScreenAllowed, joinRoomWithScreen, + isSpeechSynthesisSupported, successCallback, ) { this.localAudioEl = localAudioEl; @@ -166,6 +169,8 @@ class RoomClient { this.isVideoPictureInPictureSupported = !DetectRTC.isMobileDevice && document.pictureInPictureEnabled; this.isChatOpen = false; this.isChatEmojiOpen = false; + this.isSpeechSynthesisSupported = isSpeechSynthesisSupported; + this.speechInMessages = false; this.showChatOnMessage = true; this.isChatBgTransparent = false; this.isVideoPinned = false; @@ -2968,6 +2973,9 @@ class RoomClient { if (!this.showChatOnMessage) { this.userLog('info', `💬 New message from: ${data.peer_name}`, 'top-end'); } + if (this.speechInMessages) { + this.speechMessage(true, data.peer_name, data.peer_msg); + } this.sound('message'); } @@ -3020,7 +3028,17 @@ class RoomClient { id="msg-copy-${chatMessagesId}" class="fas fa-copy" onclick="rc.copyToClipboard('${chatMessagesId}')" + >`; + if (this.isSpeechSynthesisSupported) { + msgHTML += ` + + `; + } + msgHTML += ` @@ -3030,6 +3048,7 @@ class RoomClient { chatMsger.scrollTop += 500; this.setTippy('msg-delete-' + chatMessagesId, 'Delete', 'top'); this.setTippy('msg-copy-' + chatMessagesId, 'Copy', 'top'); + this.setTippy('msg-speech-' + chatMessagesId, 'Speech', 'top'); this.setTippy('msg-private-reply-' + chatMessagesId, 'Reply', 'top'); chatMessagesId++; } @@ -3196,6 +3215,13 @@ class RoomClient { }); } + speechMessage(newMsg = true, from, msg) { + const speech = new SpeechSynthesisUtterance(); + speech.text = (newMsg ? 'New' : '') + ' message from:' + from + '. The message is:' + msg; + speech.rate = 0.9; + window.speechSynthesis.speak(speech); + } + chatToggleBg() { this.isChatBgTransparent = !this.isChatBgTransparent; this.isChatBgTransparent @@ -4067,27 +4093,31 @@ class RoomClient { roomMessage(action, active = false) { const status = active ? 'ON' : 'OFF'; + this.sound('switch'); switch (action) { case 'pitchBar': - this.sound('switch'); this.userLog('info', `${icons.pitchBar} Audio pitch bar ${status}`, 'top-end'); break; case 'sounds': - this.sound('switch'); this.userLog('info', `${icons.sounds} Sounds notification ${status}`, 'top-end'); break; case 'ptt': - this.sound('switch'); this.userLog('info', `${icons.ptt} Push to talk ${status}`, 'top-end'); break; case 'notify': - this.sound('switch'); this.userLog('info', `${icons.share} Share room on join ${status}`, 'top-end'); break; case 'hostOnlyRecording': - this.sound('switch'); this.userLog('info', `${icons.recording} Only host recording ${status}`, 'top-end'); break; + case 'showChat': + active + ? userLog('info', `${icons.chat} Chat will be shown, when you receive a message`, 'top-end') + : userLog('info', `${icons.chat} Chat not will be shown, when you receive a message`, 'top-end'); + break; + case 'speechMessages': + this.userLog('info', `${icons.speech} Speech incoming messages ${status}`, 'top-end'); + break; default: break; } diff --git a/public/views/Room.html b/public/views/Room.html index 615ea417..ad9035e7 100644 --- a/public/views/Room.html +++ b/public/views/Room.html @@ -679,6 +679,16 @@ access to use this app. +
+ +
+ +
+ +
+ +
+
@@ -723,9 +733,6 @@ access to use this app. -
- -