Merge pull request #242 from h4ni0/reorginizing-control-buttons

[mirotalk] - redesigned the control buttons & made the most important buttons easier to reach
This commit is contained in:
Miroslav Pejic
2024-07-21 10:34:06 +02:00
committed by GitHub
5 changed files with 168 additions and 45 deletions
+1 -1
View File
@@ -40,7 +40,7 @@ dependencies: {
* @license For commercial use or closed source, contact us at license.mirotalk@gmail.com or purchase directly from CodeCanyon
* @license CodeCanyon: https://codecanyon.net/item/mirotalk-p2p-webrtc-realtime-video-conferences/38376661
* @author Miroslav Pejic - miroslav.pejic.85@gmail.com
* @version 1.3.46
* @version 1.3.47
*
*/
+2 -2
View File
@@ -1,6 +1,6 @@
{
"name": "mirotalk",
"version": "1.3.46",
"version": "1.3.47",
"description": "A free WebRTC browser-based video call",
"main": "server.js",
"scripts": {
@@ -42,7 +42,7 @@
"homepage": "https://github.com/miroslavpejic85/mirotalk",
"dependencies": {
"@sentry/integrations": "^7.114.0",
"@sentry/node": "^8.18.0",
"@sentry/node": "^8.19.0",
"axios": "^1.7.2",
"body-parser": "^1.20.2",
"colors": "^1.4.0",
+76 -12
View File
@@ -39,8 +39,8 @@
--tab-btn-active: rgb(30 29 29);
--btn-bar-bg-color: #fff;
--btn-bar-color: #000;
--btn-bar-bg-color: #ffffff;
--btn-bar-color: #000000;
/* left buttons bar vertical default */
--btns-top: 50%;
@@ -49,6 +49,16 @@
--btns-margin-left: 0px;
--btns-width: 40px;
--btns-flex-direction: column;
--btns-bg-color: rgba(0, 0, 0, 0.7);
/* bottom buttons bar horizontal default */
--bottom-btns-top: auto;
--bottom-btns-left: 50%;
--bottom-btns-bottom: 0;
--bottom-btns-translate-X: -50%;
--bottom-btns-translate-Y: 0%;
--bottom-btns-margin-bottom: 18px;
--bottom-btns-flex-direction: row;
/* left buttons bar horizontal
--btns-top: 95%;
@@ -225,7 +235,6 @@ body {
display: none;
position: fixed;
padding: 10px;
top: var(--btns-top);
right: var(--btns-right);
left: var(--btns-left);
@@ -234,31 +243,40 @@ body {
flex-direction: var(--btns-flex-direction);
justify-content: center;
grid-gap: 0.4rem;
grid-gap: 0.5rem;
-webkit-transform: translate(0%, -50%);
-ms-transform: translate(0%, -50%);
transform: translate(0%, -50%);
/* background: var(--body-bg); */
box-shadow: 0px 8px 16px 0px rgb(33 33 33);
border: var(--border);
/* box-shadow: 0px 8px 16px 0px rgb(33 33 33);*/
border-radius: 10px;
border: var(--border) !important;
box-shadow: var(--box-shadow);
overflow: hidden;
}
#buttonsBar button {
padding: 4px;
border: none;
background: var(--btn-bar-bg-color);
padding: 5px !important;
border: none !important;
/*
Use this to maintain the theme colors of buttons while making them less visible during video playback.
color: var(--btn-bar-bg-color);
background: var(--btns-bg-color);
*/
color: var(--btn-bar-color);
background: var(--btn-bar-bg-color);
font-size: 1.5rem;
border-radius: 5px;
transition: all 0.3s ease-in-out;
}
#buttonsBar button:hover {
color: var(--hover-color);
transform: var(--btns-hover-scale);
}
@@ -267,7 +285,7 @@ body {
}
#buttonsBar #leaveRoomBtn {
color: #ff2d00;
color: #e74c3c;
}
.fa-microphone-slash,
@@ -275,6 +293,52 @@ body {
color: #e74c3c !important;
}
/*--------------------------------------------------------------
# Bottom buttons
--------------------------------------------------------------*/
#bottomButtons {
z-index: 10;
display: none;
position: fixed;
padding: 10px;
top: var(--bottom-btns-top);
left: var(--bottom-btns-left);
bottom: var(--bottom-btns-bottom);
transform: translate(var(--bottom-btns-translate-X), var(--bottom-btns-translate-Y));
flex-direction: var(--bottom-btns-flex-direction);
align-items: center;
justify-content: center;
gap: 0.5rem;
margin-bottom: var(--bottom-btns-margin-bottom);
border-radius: 10px;
border: none !important;
box-shadow: var(--box-shadow);
}
#bottomButtons button {
width: 48px;
padding: 10px;
font-size: 1.5rem;
/*
Use this to maintain the theme colors of buttons while making them less visible during video playback.
color: var(--btn-bar-bg-color);
background: var(--btns-bg-color);
*/
color: var(--btn-bar-color);
background: var(--btn-bar-bg-color);
border: none !important;
border-radius: 5px;
transition: all 0.3s ease-in-out;
}
#bottomButtons button:hover {
transform: var(--btns-hover-scale);
}
/*--------------------------------------------------------------
# Caption
--------------------------------------------------------------*/
@@ -1069,7 +1133,7 @@ button:hover {
#muteEveryoneBtn:hover,
#hideEveryoneBtn:hover,
#ejectEveryoneBtn:hover {
color: #ff2d00;
color: #e74c3c;
transform: scale(0.95);
transition: all 0.3s ease-in-out;
}
+77 -24
View File
@@ -15,7 +15,7 @@
* @license For commercial use or closed source, contact us at license.mirotalk@gmail.com or purchase directly from CodeCanyon
* @license CodeCanyon: https://codecanyon.net/item/mirotalk-p2p-webrtc-realtime-video-conferences/38376661
* @author Miroslav Pejic - miroslav.pejic.85@gmail.com
* @version 1.3.46
* @version 1.3.47
*
*/
@@ -26,6 +26,10 @@
// Signaling server URL
const signalingServer = getSignalingServer();
// Get the computed styles of the root element
const root = document.documentElement;
const computedStyles = getComputedStyle(root);
// This room
const myRoomId = getId('myRoomId');
const roomId = getRoomId();
@@ -232,6 +236,7 @@ const initSpeakerSelect = getId('initSpeakerSelect');
// Buttons bar
const buttonsBar = getId('buttonsBar');
const bottomButtons = getId('bottomButtons');
const shareRoomBtn = getId('shareRoomBtn');
const hideMeBtn = getId('hideMeBtn');
const videoBtn = getId('videoBtn');
@@ -610,9 +615,10 @@ let localAudioMediaStream; // my microphone
let peerVideoMediaElements = {}; // keep track of our peer <video> tags, indexed by peer_id_video
let peerAudioMediaElements = {}; // keep track of our peer <audio> tags, indexed by peer_id_audio
// main buttons
// main and bottom buttons
let mainButtonsBarPosition = 'vertical'; // vertical - horizontal
let placement = 'right'; // https://atomiks.github.io/tippyjs/#placements
let bottomButtonsPlacement = 'right';
let isButtonsVisible = false;
let isButtonsBarOver = false;
@@ -851,25 +857,31 @@ function setButtonsToolTip() {
function refreshMainButtonsToolTipPlacement() {
// not need for mobile
if (isMobileDevice) return;
// main buttons
// ButtonsBar
placement = btnsBarSelect.options[btnsBarSelect.selectedIndex].value == 'vertical' ? 'right' : 'top';
// BottomButtons
bottomButtonsPlacement = btnsBarSelect.options[btnsBarSelect.selectedIndex].value == 'vertical' ? 'top' : 'right';
setTippy(shareRoomBtn, 'Share the Room', placement);
setTippy(hideMeBtn, 'Toggle hide myself from the room view', placement);
setTippy(audioBtn, useAudio ? 'Stop the audio' : 'My audio is disabled', placement);
setTippy(videoBtn, useVideo ? 'Stop the video' : 'My video is disabled', placement);
setTippy(screenShareBtn, 'Start screen sharing', placement);
setTippy(recordStreamBtn, 'Start recording', placement);
setTippy(fullScreenBtn, 'View full screen', placement);
setTippy(chatRoomBtn, 'Open the chat', placement);
setTippy(captionBtn, 'Open the caption', placement);
setTippy(roomEmojiPickerBtn, 'Send reaction', placement);
setTippy(myHandBtn, 'Raise your hand', placement);
setTippy(whiteboardBtn, 'Open the whiteboard', placement);
setTippy(fileShareBtn, 'Share file', placement);
setTippy(documentPiPBtn, 'Toggle picture in picture', placement);
setTippy(mySettingsBtn, 'Open the settings', placement);
setTippy(aboutBtn, 'About this project', placement);
setTippy(leaveRoomBtn, 'Leave this room', placement);
setTippy(hideMeBtn, 'Toggle hide myself from the room view', bottomButtonsPlacement);
setTippy(audioBtn, useAudio ? 'Stop the audio' : 'My audio is disabled', bottomButtonsPlacement);
setTippy(videoBtn, useVideo ? 'Stop the video' : 'My video is disabled', bottomButtonsPlacement);
setTippy(screenShareBtn, 'Start screen sharing', bottomButtonsPlacement);
setTippy(myHandBtn, 'Raise your hand', bottomButtonsPlacement);
}
/**
@@ -1937,7 +1949,7 @@ async function joinToChannel() {
peer_privacy_status: isVideoPrivacyActive,
userAgent: userAgent,
});
handleBodyOnMouseMove(); // show/hide buttonsBar...
handleBodyOnMouseMove(); // show/hide buttonsBar, bottomButtons ...
}
/**
@@ -2441,6 +2453,7 @@ function setCustomTheme() {
setSP('--private-msg-bg', '#6b1226');
setSP('--btn-bar-bg-color', '#FFFFFF');
setSP('--btn-bar-color', '#000000');
setSP('--btns-bg-color', `${color}`);
document.body.style.background = `radial-gradient(${color}, ${color})`;
}
@@ -2470,6 +2483,7 @@ function setTheme() {
setSP('--private-msg-bg', '#2a2a2a');
setSP('--btn-bar-bg-color', '#FFFFFF');
setSP('--btn-bar-color', '#000000');
setSP('--btns-bg-color', 'rgba(0, 0, 0, 0.7)');
document.body.style.background = 'radial-gradient(#393939, #000000)';
mirotalkTheme.selectedIndex = 0;
break;
@@ -2490,6 +2504,7 @@ function setTheme() {
setSP('--private-msg-bg', '#616161');
setSP('--btn-bar-bg-color', '#FFFFFF');
setSP('--btn-bar-color', '#000000');
setSP('--btns-bg-color', 'rgba(0, 0, 0, 0.7)');
document.body.style.background = 'radial-gradient(#4f4f4f, #1c1c1c)';
mirotalkTheme.selectedIndex = 1;
break;
@@ -2510,6 +2525,7 @@ function setTheme() {
setSP('--private-msg-bg', '#004a47');
setSP('--btn-bar-bg-color', '#FFFFFF');
setSP('--btn-bar-color', '#000000');
setSP('--btns-bg-color', 'rgba(0, 42, 34, 0.7)');
document.body.style.background = 'radial-gradient(#004d40, #001f1c)';
mirotalkTheme.selectedIndex = 2;
break;
@@ -2530,6 +2546,7 @@ function setTheme() {
setSP('--private-msg-bg', '#1a237e');
setSP('--btn-bar-bg-color', '#FFFFFF');
setSP('--btn-bar-color', '#000000');
setSP('--btns-bg-color', 'rgba(0, 39, 77, 0.7)');
document.body.style.background = 'radial-gradient(#1a237e, #0d1b34)';
mirotalkTheme.selectedIndex = 3;
break;
@@ -2549,6 +2566,7 @@ function setTheme() {
setSP('--private-msg-bg', '#8B0000');
setSP('--btn-bar-bg-color', '#FFFFFF');
setSP('--btn-bar-color', '#000000');
setSP('--btns-bg-color', 'rgba(42, 13, 13, 0.7)');
document.body.style.background = 'radial-gradient(#8B0000, #320000)';
mirotalkTheme.selectedIndex = 4;
break;
@@ -2569,6 +2587,7 @@ function setTheme() {
setSP('--private-msg-bg', '#4B0082');
setSP('--btn-bar-bg-color', '#FFFFFF');
setSP('--btn-bar-color', '#000000');
setSP('--btns-bg-color', 'rgba(42, 0, 29, 0.7)');
document.body.style.background = 'radial-gradient(#4B0082, #2C003E)';
mirotalkTheme.selectedIndex = 5;
break;
@@ -2589,6 +2608,7 @@ function setTheme() {
setSP('--private-msg-bg', '#FF8C00');
setSP('--btn-bar-bg-color', '#FFFFFF');
setSP('--btn-bar-color', '#000000');
setSP('--btns-bg-color', 'rgba(61, 26, 0, 0.7)');
document.body.style.background = 'radial-gradient(#FF8C00, #4B1C00)';
mirotalkTheme.selectedIndex = 6;
break;
@@ -2609,6 +2629,7 @@ function setTheme() {
setSP('--private-msg-bg', '#FFD700');
setSP('--btn-bar-bg-color', '#FFFFFF');
setSP('--btn-bar-color', '#000000');
setSP('--btns-bg-color', 'rgba(77, 59, 0, 0.7)');
document.body.style.background = 'radial-gradient(#FFD700, #3B3B00)';
mirotalkTheme.selectedIndex = 7;
break;
@@ -2630,20 +2651,38 @@ function setButtonsBarPosition(position) {
mainButtonsBarPosition = position;
switch (mainButtonsBarPosition) {
case 'vertical':
// buttonsBar
setSP('--btns-top', '50%');
setSP('--btns-right', '0px');
setSP('--btns-left', '15px');
setSP('--btns-margin-left', '0px');
setSP('--btns-width', '40px');
setSP('--btns-flex-direction', 'column');
// bottomButtons horizontally
setSP('--bottom-btns-top', 'auto');
setSP('--bottom-btns-left', '50%');
setSP('--bottom-btns-bottom', '0');
setSP('--bottom-btns-translate-X', '-50%');
setSP('--bottom-btns-translate-Y', '0%');
setSP('--bottom-btns-margin-bottom', '16px');
setSP('--bottom-btns-flex-direction', 'row');
break;
case 'horizontal':
// buttonsBar
setSP('--btns-top', '95%');
setSP('--btns-right', '25%');
setSP('--btns-left', '50%');
setSP('--btns-margin-left', '-330px');
setSP('--btns-width', '660px');
setSP('--btns-margin-left', '-260px');
setSP('--btns-width', '520px');
setSP('--btns-flex-direction', 'row');
// bottomButtons vertically
setSP('--bottom-btns-top', '50%');
setSP('--bottom-btns-left', '15px');
setSP('--bottom-btns-bottom', 'auto');
setSP('--bottom-btns-translate-X', '0%');
setSP('--bottom-btns-translate-Y', '-50%');
setSP('--bottom-btns-margin-bottom', '0');
setSP('--bottom-btns-flex-direction', 'column');
break;
default:
console.log('No position found');
@@ -4704,10 +4743,10 @@ function setRoomEmojiButton() {
function toggleEmojiPicker() {
if (emojiPickerContainer.style.display === 'block') {
elemDisplay(emojiPickerContainer, false);
setColor(roomEmojiPickerBtn, 'black');
setColor(roomEmojiPickerBtn, computedStyles.getPropertyValue('--btn-bar-color').trim());
} else {
emojiPickerContainer.style.display = 'block';
setColor(roomEmojiPickerBtn, 'yellow');
setColor(roomEmojiPickerBtn, 'green');
}
}
}
@@ -5003,6 +5042,7 @@ function setMySettingsBtn() {
mySettingsBtn.addEventListener('click', (e) => {
if (isMobileDevice) {
elemDisplay(buttonsBar, false);
elemDisplay(bottomButtons, false);
isButtonsVisible = false;
}
hideShowMySettings();
@@ -5108,6 +5148,7 @@ function handleBodyOnMouseMove() {
document.body.addEventListener('mousemove', (e) => {
showButtonsBarAndMenu();
});
// detect buttons bar over
buttonsBar.addEventListener('mouseover', () => {
isButtonsBarOver = true;
@@ -5115,6 +5156,14 @@ function handleBodyOnMouseMove() {
buttonsBar.addEventListener('mouseout', () => {
isButtonsBarOver = false;
});
bottomButtons.addEventListener('mouseover', () => {
isButtonsBarOver = true;
});
bottomButtons.addEventListener('mouseout', () => {
isButtonsBarOver = false;
});
checkButtonsBarAndMenu();
}
@@ -5684,6 +5733,7 @@ function showButtonsBarAndMenu() {
return;
toggleClassElements('navbar', 'block');
elemDisplay(buttonsBar, true, 'flex');
elemDisplay(bottomButtons, true, 'flex');
isButtonsVisible = true;
}
@@ -5694,6 +5744,7 @@ function checkButtonsBarAndMenu() {
if (!isButtonsBarOver) {
toggleClassElements('navbar', 'none');
elemDisplay(buttonsBar, false);
elemDisplay(bottomButtons, false);
isButtonsVisible = false;
}
setTimeout(() => {
@@ -5749,7 +5800,7 @@ function shareRoomMeetingURL(checkScreen = false) {
<p style="color:rgb(8, 189, 89);">${roomURL}</p>`,
showDenyButton: true,
showCancelButton: true,
cancelButtonColor: 'red',
cancelButtonColor: '#e74c3c',
denyButtonColor: 'green',
confirmButtonText: `Copy URL`,
denyButtonText: `Email invite`,
@@ -5812,7 +5863,7 @@ function shareRoomByEmail() {
html: '<input type="text" id="datetimePicker" class="flatpickr" />',
showCancelButton: true,
confirmButtonText: 'OK',
cancelButtonColor: 'red',
cancelButtonColor: '#e74c3c',
showClass: { popup: 'animate__animated animate__fadeInDown' },
hideClass: { popup: 'animate__animated animate__fadeOutUp' },
preConfirm: () => {
@@ -5867,7 +5918,7 @@ function handleAudio(e, init, force = null) {
if (init) {
initAudioBtn.className = audioClassName;
setTippy(initAudioBtn, audioStatus ? 'Stop the audio' : 'Start the audio', 'top');
setTippy(initAudioBtn, audioStatus ? 'Stop the audio' : 'Start the audio', 'right');
initMicrophoneSelect.disabled = !audioStatus;
initSpeakerSelect.disabled = !audioStatus;
lS.setInitConfig(lS.MEDIA_TYPE.audio, audioStatus);
@@ -6510,7 +6561,7 @@ function recordingOptions(options, audioMixerTracks) {
title: 'Recording options',
showDenyButton: true,
showCancelButton: true,
cancelButtonColor: 'red',
cancelButtonColor: '#e74c3c',
denyButtonColor: 'green',
confirmButtonText: `Camera`,
denyButtonText: `Screen/Window`,
@@ -6864,6 +6915,7 @@ function showChatRoomDraggable() {
playSound('newMessage');
if (isMobileDevice) {
elemDisplay(buttonsBar, false);
elemDisplay(bottomButtons, false);
isButtonsVisible = false;
}
chatRoomBtn.className = className.chatOff;
@@ -6881,6 +6933,7 @@ function showCaptionDraggable() {
playSound('newMessage');
if (isMobileDevice) {
elemDisplay(buttonsBar, false);
elemDisplay(bottomButtons, false);
isButtonsVisible = false;
}
captionBtn.className = 'far fa-closed-captioning';
@@ -7886,13 +7939,13 @@ function handleHideMe(isHideMeActive) {
if (isHideMeActive) {
if (isVideoPinned) myVideoPinBtn.click();
elemDisplay(myVideoWrap, false);
setColor(hideMeBtn, 'red');
setColor(hideMeBtn, '#e74c3c');
hideMeBtn.className = className.hideMeOn;
playSound('off');
} else {
elemDisplay(myVideoWrap, true, 'inline-block');
hideMeBtn.className = className.hideMeOff;
setColor(hideMeBtn, 'black');
setColor(hideMeBtn, computedStyles.getPropertyValue('--btn-bar-color').trim());
playSound('on');
}
resizeVideoMedia();
@@ -7907,13 +7960,13 @@ function setMyHandStatus() {
// Raise hand
setColor(myHandBtn, 'green');
elemDisplay(myHandStatusIcon, true);
setTippy(myHandBtn, 'Raise your hand', placement);
setTippy(myHandBtn, 'Raise your hand', bottomButtonsPlacement);
playSound('raiseHand');
} else {
// Lower hand
setColor(myHandBtn, 'black');
setColor(myHandBtn, computedStyles.getPropertyValue('--btn-bar-color').trim());
elemDisplay(myHandStatusIcon, false);
setTippy(myHandBtn, 'Lower your hand', placement);
setTippy(myHandBtn, 'Lower your hand', bottomButtonsPlacement);
}
emitPeerStatus('hand', myHandStatus);
}
@@ -7930,7 +7983,7 @@ function setMyAudioStatus(status) {
// send my audio status to all peers in the room
emitPeerStatus('audio', status);
setTippy(myAudioStatusIcon, status ? 'My audio is on' : 'My audio is off', 'bottom');
setTippy(audioBtn, status ? 'Stop the audio' : 'Start the audio', placement);
setTippy(audioBtn, status ? 'Stop the audio' : 'Start the audio', bottomButtonsPlacement);
status ? playSound('on') : playSound('off');
}
@@ -7954,7 +8007,7 @@ function setMyVideoStatus(status) {
if (!isMobileDevice) {
if (myVideoStatusIcon) setTippy(myVideoStatusIcon, status ? 'My video is on' : 'My video is off', 'bottom');
setTippy(videoBtn, status ? 'Stop the video' : 'Start the video', placement);
setTippy(videoBtn, status ? 'Stop the video' : 'Start the video', bottomButtonsPlacement);
}
if (status) {
+12 -6
View File
@@ -114,17 +114,11 @@ access to use this app.
<div id="buttonsBar" class="fadein">
<button id="shareRoomBtn" class="fas fa-share-alt"></button>
<button id="hideMeBtn" class="fas fa-user"></button>
<button id="swapCameraBtn" class="fas fa-camera-rotate"></button>
<button id="videoBtn" class="fas fa-video"></button>
<button id="audioBtn" class="fas fa-microphone"></button>
<button id="screenShareBtn" class="fas fa-desktop"></button>
<button id="recordStreamBtn" class="fas fa-record-vinyl"></button>
<button id="fullScreenBtn" class="fas fa-expand-alt"></button>
<button id="chatRoomBtn" class="fas fa-comment"></button>
<button id="captionBtn" class="fas fa-closed-captioning"></button>
<button id="roomEmojiPickerBtn" class="fas fa-face-smile"></button>
<button id="myHandBtn" class="fas fa-hand-paper"></button>
<button id="whiteboardBtn" class="fas fa-chalkboard-teacher"></button>
<button id="fileShareBtn" class="fas fa-folder-open"></button>
<button id="documentPiPBtn" class="fas fa-images"></button>
@@ -134,6 +128,18 @@ access to use this app.
</div>
<!-- End left buttons -->
<!-- Start bottom buttons -->
<div id="bottomButtons" class="fadein">
<button id="audioBtn" class="fas fa-microphone"></button>
<button id="videoBtn" class="fas fa-video"></button>
<button id="swapCameraBtn" class="fas fa-camera-rotate"></button>
<button id="hideMeBtn" class="fas fa-user"></button>
<button id="screenShareBtn" class="fas fa-desktop"></button>
<button id="myHandBtn" class="fas fa-hand-paper"></button>
</div>
<!-- End bottom buttons -->
<!-- Start room emoji picker -->
<div id="emojiPickerContainer" class="roomEmoji fadein">