[mirotalk] - move extra buttons

This commit is contained in:
Miroslav Pejic
2025-12-21 23:56:47 +01:00
parent 84037d802d
commit 1d883bda58
10 changed files with 226 additions and 316 deletions
+1 -1
View File
@@ -1,5 +1,5 @@
# ====================================================
# MiroTalk P2P v.1.6.95 - Environment Configuration
# MiroTalk P2P v.1.6.96 - Environment Configuration
# ====================================================
# App environment
+10 -10
View File
@@ -2,7 +2,7 @@
/**
* ==============================================
* MiroTalk P2P v.1.6.95 - Configuration File
* MiroTalk P2P v.1.6.96 - Configuration File
* ==============================================
*
* Branding and customizations require a license:
@@ -129,26 +129,26 @@ module.exports = {
*/
buttons: {
main: {
showShareQr: true,
showShareRoomBtn: true, // For guests
showHideMeBtn: true,
showFullScreenBtn: true,
showAudioBtn: true,
showVideoBtn: true,
showScreenBtn: true, // autodetected
showRecordStreamBtn: true,
showMyHandBtn: true,
showChatRoomBtn: true,
showParticipantsBtn: true,
showCaptionRoomBtn: true,
showMySettingsBtn: true,
showExtraBtn: true,
showShareQr: true,
showShareRoomBtn: true, // For guests
showHideMeBtn: true,
showRecordStreamBtn: true,
showFullScreenBtn: true,
showRoomEmojiPickerBtn: true,
showMyHandBtn: true,
showCaptionRoomBtn: true,
showWhiteboardBtn: true,
showSnapshotRoomBtn: true,
showFileShareBtn: true,
showDocumentPipBtn: true,
showMySettingsBtn: true,
showAboutBtn: true, // Please keep me always true, Thank you!
showExtraBtn: true,
},
chat: {
showTogglePinBtn: true,
+1 -1
View File
@@ -45,7 +45,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.6.95
* @version 1.6.96
*
*/
+2 -2
View File
@@ -1,12 +1,12 @@
{
"name": "mirotalk",
"version": "1.6.95",
"version": "1.6.96",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "mirotalk",
"version": "1.6.95",
"version": "1.6.96",
"license": "AGPL-3.0",
"dependencies": {
"@mattermost/client": "11.2.0",
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "mirotalk",
"version": "1.6.95",
"version": "1.6.96",
"description": "A free WebRTC browser-based video call",
"main": "server.js",
"scripts": {
+52 -77
View File
@@ -45,15 +45,6 @@
--btn-bar-bg-color: #ffffff;
--btn-bar-color: #000000;
/* left buttons bar vertical default */
--btns-top: 50%;
--btns-right: 0%;
--btns-left: 15px;
--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%;
@@ -63,15 +54,6 @@
--bottom-btns-margin-bottom: 18px;
--bottom-btns-flex-direction: row;
/* left buttons bar horizontal
--btns-top: 95%;
--btns-right: 25%;
--btns-left: 50%;
--btns-margin-left: -330px;
--btns-width: 660px;
--btns-flex-direction: row;
*/
/* dark theme */
--body-bg: radial-gradient(#393939, #000000);
--msger-bg: radial-gradient(#393939, #000000);
@@ -236,54 +218,9 @@ body {
}
/*--------------------------------------------------------------
# Left buttons
# Right extra buttons after my settings
--------------------------------------------------------------*/
#buttonsBar {
z-index: 10;
display: none;
position: fixed;
/* padding: 10px; */
top: var(--btns-top);
right: var(--btns-right);
left: var(--btns-left);
margin-left: var(--btns-margin-left);
width: var(--btns-width);
flex-direction: var(--btns-flex-direction);
justify-content: center;
grid-gap: 0.8rem;
-webkit-transform: translate(0%, -50%);
-ms-transform: translate(0%, -50%);
transform: translate(0%, -50%);
border-radius: 10px;
overflow: hidden;
}
#buttonsBar button {
padding: 5px !important;
font-size: 1.4rem;
color: var(--btn-bar-bg-color);
background: var(--btns-bg-color);
border: none !important;
border-radius: 10px;
}
#buttonsBar button:hover {
background: var(--body-bg);
transform: translateY(-3px);
}
#buttonsBar button:focus {
outline: none;
}
#toggleExtraBtn {
color: #66beff !important;
}
.fa-phone-slash,
.fa-microphone-slash,
.fa-video-slash {
@@ -324,7 +261,8 @@ body {
/* Let the dropdown menu anchor to the whole split button (not only the arrow). */
#bottomButtons #audioDropdown,
#bottomButtons #videoDropdown {
#bottomButtons #videoDropdown,
#bottomButtons #settingsExtraDropdown {
position: static;
}
@@ -401,10 +339,6 @@ body {
box-shadow: var(--box-shadow);
}
.dropdown-menu.show {
display: block;
}
#bottomButtons #audioMenu,
#bottomButtons #videoMenu {
min-width: 280px;
@@ -412,8 +346,34 @@ body {
text-align: left;
}
#bottomButtons #settingsExtraMenu {
min-width: 200px;
max-width: calc(100vw - 24px);
text-align: left;
}
/* Mobile: keep settingsExtraMenu inside viewport and scrollable */
@media (max-width: 600px) {
#bottomButtons #audioMenu,
#bottomButtons #videoMenu,
#bottomButtons #settingsExtraMenu {
min-width: unset;
max-width: 90vw;
left: 5vw !important;
right: 5vw !important;
position: fixed !important;
bottom: 70px !important;
z-index: 9999;
overflow-y: auto;
max-height: 60vh;
border-radius: 12px;
box-shadow: var(--box-shadow);
}
}
#bottomButtons #audioMenu button,
#bottomButtons #videoMenu button {
#bottomButtons #videoMenu button,
#bottomButtons #settingsExtraMenu button {
display: flex;
width: 100%;
height: 35px;
@@ -426,9 +386,19 @@ body {
transform: none !important;
}
#bottomButtons #settingsExtraMenu button i {
width: 20px;
min-width: 20px;
text-align: center;
margin-right: 10px;
font-size: 1.1em;
display: inline-block;
}
/* Quick device picker: section headers + divider (Cameras / Microphones / Speakers) */
#bottomButtons #videoMenu .device-menu-header,
#bottomButtons #audioMenu .device-menu-header {
#bottomButtons #audioMenu .device-menu-header,
#bottomButtons #settingsExtraMenu .device-menu-header {
display: flex;
align-items: center;
gap: 10px;
@@ -441,13 +411,15 @@ body {
}
#bottomButtons #videoMenu .device-menu-header i,
#bottomButtons #audioMenu .device-menu-header i {
#bottomButtons #audioMenu .device-menu-header i,
#bottomButtons #settingsExtraMenu .device-menu-header i {
width: 18px;
text-align: center;
}
#bottomButtons #videoMenu .device-menu-divider,
#bottomButtons #audioMenu .device-menu-divider {
#bottomButtons #audioMenu .device-menu-divider,
#bottomButtons #settingsExtraMenu .device-menu-divider {
height: 1px;
background: var(--btns-bg-color);
opacity: 0.6;
@@ -456,7 +428,8 @@ body {
/* Action buttons in device menu */
#bottomButtons #audioMenu .device-menu-action-btn,
#bottomButtons #videoMenu .device-menu-action-btn {
#bottomButtons #videoMenu .device-menu-action-btn,
#bottomButtons #settingsExtraMenu .device-menu-action-btn {
background: var(--body-bg);
border: 1px solid var(--border-color);
color: #fff;
@@ -466,14 +439,16 @@ body {
}
#bottomButtons #audioMenu .device-menu-action-btn:hover,
#bottomButtons #videoMenu .device-menu-action-btn:hover {
#bottomButtons #videoMenu .device-menu-action-btn:hover,
#bottomButtons #settingsExtraMenu .device-menu-action-btn:hover {
background: var(--btns-bg-color) !important;
border-color: var(--btns-color);
transform: translateY(-1px) !important;
}
#bottomButtons #audioMenu .device-menu-action-btn i,
#bottomButtons #videoMenu .device-menu-action-btn i {
#bottomButtons #videoMenu .device-menu-action-btn i,
#bottomButtons #settingsExtraMenu .device-menu-action-btn i {
width: 18px;
text-align: center;
}
@@ -2786,7 +2761,7 @@ hr {
--------------------------------------------------------------*/
.red {
color: red !important;
color: #ff4500 !important;
}
.orange {
+1 -1
View File
@@ -77,7 +77,7 @@ let brand = {
},
about: {
imageUrl: '../images/mirotalk-logo.gif',
title: 'WebRTC P2P v1.6.95',
title: 'WebRTC P2P v1.6.96',
html: `
<button
id="support-button"
+122 -136
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.6.95
* @version 1.6.96
*
*/
@@ -182,7 +182,6 @@ const initSpeakerSelect = getId('initSpeakerSelect');
const usernameEmoji = getId('usernameEmoji');
// Buttons bar
const buttonsBar = getId('buttonsBar');
const shareRoomBtn = getId('shareRoomBtn');
const recordStreamBtn = getId('recordStreamBtn');
const fullScreenBtn = getId('fullScreenBtn');
@@ -195,12 +194,10 @@ const whiteboardBtn = getId('whiteboardBtn');
const snapshotRoomBtn = getId('snapshotRoomBtn');
const fileShareBtn = getId('fileShareBtn');
const documentPiPBtn = getId('documentPiPBtn');
const mySettingsBtn = getId('mySettingsBtn');
const aboutBtn = getId('aboutBtn');
// Buttons bottom
const bottomButtons = getId('bottomButtons');
const toggleExtraBtn = getId('toggleExtraBtn');
const audioBtn = getId('audioBtn');
const videoBtn = getId('videoBtn');
const videoDropdown = getId('videoDropdown');
@@ -213,6 +210,11 @@ const swapCameraBtn = getId('swapCameraBtn');
const hideMeBtn = getId('hideMeBtn');
const screenShareBtn = getId('screenShareBtn');
const myHandBtn = getId('myHandBtn');
const mySettingsBtn = getId('mySettingsBtn');
const settingsSplit = getId('settingsSplit');
const settingsExtraDropdown = getId('settingsExtraDropdown');
const settingsExtraToggle = getId('settingsExtraToggle');
const settingsExtraMenu = getId('settingsExtraMenu');
const leaveRoomBtn = getId('leaveRoomBtn');
// Room Emoji Picker
@@ -371,8 +373,6 @@ const recordingTime = getId('recordingTime');
const lastRecordingInfo = getId('lastRecordingInfo');
const themeSelect = getId('mirotalkTheme');
const videoObjFitSelect = getId('videoObjFitSelect');
const mainButtonsBar = getQsA('#buttonsBar button');
const mainButtonsIcon = getQsA('#buttonsBar button i');
const btnsBarSelect = getId('mainButtonsBarPosition');
const pinUnpinGridDiv = getId('pinUnpinGridDiv');
const pinVideoPositionSelect = getId('pinVideoPositionSelect');
@@ -849,7 +849,7 @@ function setButtonsToolTip() {
// Whiteboard buttons
setTippy(whiteboardLockBtn, 'Toggle Lock whiteboard', 'right');
setTippy(whiteboardUnlockBtn, 'Toggle Lock whiteboard', 'right');
setTippy(whiteboardCloseBtn, 'Close', 'right');
setTippy(whiteboardCloseBtn, 'Close', 'bottom');
setTippy(wbDrawingColorEl, 'Drawing color', 'bottom');
setTippy(whiteboardGhostButton, 'Toggle transparent background', 'bottom');
setTippy(whiteboardGridBtn, 'Toggle whiteboard grid', 'bottom');
@@ -884,19 +884,6 @@ function refreshMainButtonsToolTipPlacement() {
// 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(recordStreamBtn, 'Start recording', placement);
setTippy(fullScreenBtn, 'View full screen', placement);
setTippy(captionBtn, 'Open the caption', placement);
setTippy(roomEmojiPickerBtn, 'Send reaction', placement);
setTippy(whiteboardBtn, 'Open the whiteboard', placement);
setTippy(snapshotRoomBtn, 'Snapshot screen, windows or tab', placement);
setTippy(fileShareBtn, 'Share file', placement);
setTippy(documentPiPBtn, 'Toggle Document picture in picture', placement);
setTippy(aboutBtn, 'About this project', placement);
setTippy(toggleExtraBtn, 'Toggle extra buttons', 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);
@@ -1477,16 +1464,18 @@ function handleRules(isPresenter) {
* Hide not desired buttons
*/
function handleButtonsRule() {
const showExtraBtn =
buttons.main.showExtraBtn &&
Array.from(settingsExtraMenu.children).filter((el) => el.style.display !== 'none').length > 0;
if (!showExtraBtn) {
mySettingsBtn.style.borderRadius = '10px';
}
// Main buttons
displayElements([
{ element: shareRoomBtn, display: buttons.main.showShareRoomBtn },
{ element: hideMeBtn, display: buttons.main.showHideMeBtn },
{
element: toggleExtraBtn,
display:
buttons.main.showExtraBtn &&
Array.from(buttonsBar.children).filter((el) => el.style.display !== 'none').length > 0,
},
{ element: settingsExtraDropdown, display: showExtraBtn },
{ element: audioBtn, display: buttons.main.showAudioBtn },
{ element: videoBtn, display: buttons.main.showVideoBtn },
//{ element: screenShareBtn, display: buttons.main.showScreenBtn }, // auto-detected
@@ -2282,7 +2271,7 @@ async function joinToChannel() {
peer_privacy_status: isVideoPrivacyActive,
userAgent: userAgent,
});
handleBodyOnMouseMove(); // show/hide buttonsBar, bottomButtons ...
handleBodyOnMouseMove(); // show/hide bottomButtons ...
makeRoomPopupQR();
}
@@ -3115,13 +3104,6 @@ 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%');
@@ -3132,13 +3114,6 @@ function setButtonsBarPosition(position) {
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', '-260px');
setSP('--btns-width', '520px');
setSP('--btns-flex-direction', 'row');
// bottomButtons vertically
setSP('--bottom-btns-top', '50%');
setSP('--bottom-btns-left', '15px');
@@ -5434,10 +5409,10 @@ function manageButtons() {
setMyFileShareBtn();
setDocumentPiPBtn();
setMySettingsBtn();
setMySettingsExtraBtns();
setAboutBtn();
// Buttons bottom
setToggleExtraButtons();
setAudioBtn();
setVideoBtn();
setSwapCameraBtn();
@@ -5478,39 +5453,6 @@ function setHideMeButton() {
});
}
/**
* Toggle extra buttons
*/
function setToggleExtraButtons() {
toggleExtraBtn.addEventListener('click', () => {
toggleExtraButtons();
if (!isMobileDevice) {
isToggleExtraBtnClicked = true;
setTimeout(() => {
isToggleExtraBtnClicked = false;
}, 2000);
}
});
toggleExtraBtn.addEventListener('mouseover', () => {
if (isToggleExtraBtnClicked || isMobileDevice) return;
if (buttonsBar.style.display === 'none') {
toggleExtraButtons();
}
});
}
/**
* Toggle extra buttons
*/
function toggleExtraButtons() {
const isButtonsBarHidden = buttonsBar.style.display === 'none' || buttonsBar.style.display === '';
const displayValue = isButtonsBarHidden ? 'flex' : 'none';
const cName = isButtonsBarHidden ? className.up : className.down;
elemDisplay(buttonsBar, isButtonsBarHidden, displayValue);
toggleExtraBtn.className = cName;
}
/**
* Audio mute - unmute button click event
*/
@@ -5594,11 +5536,7 @@ function setScreenShareBtn() {
*/
function setRecordStreamBtn() {
recordStreamBtn.addEventListener('click', (e) => {
if (isStreamRecording) {
stopStreamRecording();
} else {
startStreamRecording();
}
isStreamRecording ? stopStreamRecording() : startStreamRecording();
});
recImage.addEventListener('click', (e) => {
recordStreamBtn.click();
@@ -5619,11 +5557,12 @@ function setFullScreenBtn() {
if (fsSupported) {
// detect esc from full screen mode
document.addEventListener('fullscreenchange', (e) => {
const fullScreenIcon = fullScreenBtn.querySelector('i');
let fullscreenElement = document.fullscreenElement;
if (!fullscreenElement) {
fullScreenBtn.className = className.fsOff;
fullScreenIcon.className = className.fsOff;
isDocumentOnFullScreen = false;
setTippy(fullScreenBtn, 'View full screen', placement);
}
});
fullScreenBtn.addEventListener('click', (e) => {
@@ -5847,11 +5786,7 @@ function setCaptionRoomBtn() {
if (buttons.main.showCaptionRoomBtn) {
// open hide caption
captionBtn.addEventListener('click', (e) => {
if (!isCaptionBoxVisible) {
showCaptionDraggable();
} else {
hideCaptionBox();
}
!isCaptionBoxVisible ? showCaptionDraggable() : hideCaptionBox();
});
// Maximize caption
@@ -6057,12 +5992,13 @@ function setRoomEmojiButton() {
}
function toggleEmojiPicker() {
const roomEmojiPickerIcon = roomEmojiPickerBtn.querySelector('i');
if (emojiPickerContainer.style.display === 'block') {
elemDisplay(emojiPickerContainer, false);
setColor(roomEmojiPickerBtn, 'var(--btn-bar-bg-color)');
setColor(roomEmojiPickerIcon, 'var(--btn-bar-bg-color)');
} else {
emojiPickerContainer.style.display = 'block';
setColor(roomEmojiPickerBtn, 'yellow');
setColor(roomEmojiPickerIcon, 'yellow');
}
}
}
@@ -6485,7 +6421,6 @@ async function documentPictureInPictureOpen() {
function setMySettingsBtn() {
mySettingsBtn.addEventListener('click', (e) => {
if (isMobileDevice) {
elemDisplay(buttonsBar, false);
elemDisplay(bottomButtons, false);
isButtonsVisible = false;
}
@@ -6577,6 +6512,61 @@ function setMySettingsBtn() {
};
}
/**
* Settings extra buttons
*/
function setMySettingsExtraBtns() {
// Settings Split Dropdown logic (desktop hover support)
if (settingsSplit && settingsExtraDropdown && settingsExtraToggle && settingsExtraMenu) {
let showTimeout;
let hideTimeout;
function showMenu() {
clearTimeout(hideTimeout);
settingsExtraMenu.classList.remove('hidden');
settingsExtraMenu.classList.add('show');
}
function hideMenu() {
clearTimeout(showTimeout);
settingsExtraMenu.classList.remove('show');
settingsExtraMenu.classList.add('hidden');
}
// Toggle on click (arrow button)
settingsExtraToggle.addEventListener('click', function (e) {
e.stopPropagation();
!settingsExtraMenu.classList.contains('hidden') ? hideMenu() : showMenu();
});
// Desktop hover support
const supportsHover = window.matchMedia('(hover: hover) and (pointer: fine)').matches;
if (supportsHover) {
let closeTimeout;
const cancelClose = () => {
if (!closeTimeout) return;
clearTimeout(closeTimeout);
closeTimeout = null;
};
const scheduleClose = () => {
cancelClose();
closeTimeout = setTimeout(() => hideMenu(), 180);
};
settingsExtraToggle.addEventListener('mouseenter', () => {
cancelClose();
showMenu();
});
settingsExtraToggle.addEventListener('mouseleave', scheduleClose);
settingsExtraMenu.addEventListener('mouseenter', cancelClose);
settingsExtraMenu.addEventListener('mouseleave', scheduleClose);
}
// Optional: close on click outside
document.addEventListener('click', function (e) {
if (!settingsExtraToggle.contains(e.target) && !settingsExtraMenu.contains(e.target)) {
hideMenu();
}
});
}
}
/**
* About button click event
*/
@@ -6603,14 +6593,6 @@ function handleBodyOnMouseMove() {
showButtonsBarAndMenu();
});
// detect buttons bar over
buttonsBar.addEventListener('mouseover', () => {
isButtonsBarOver = true;
});
buttonsBar.addEventListener('mouseout', () => {
isButtonsBarOver = false;
});
bottomButtons.addEventListener('mouseover', () => {
isButtonsBarOver = true;
});
@@ -6766,7 +6748,6 @@ function setupMySettings() {
lsSettings.buttons_bar = btnsBarSelect.selectedIndex;
lS.setSettings(lsSettings);
setButtonsBarPosition(btnsBarSelect.value);
resizeMainButtons();
});
}
@@ -7001,7 +6982,6 @@ function loadSettingsFromLocalStorage() {
setSP('--video-object-fit', videoObjFitSelect.value);
setButtonsBarPosition(btnsBarSelect.value);
toggleVideoPin(pinVideoPositionSelect.value);
resizeMainButtons();
}
/**
@@ -7383,8 +7363,6 @@ function showButtonsBarAndMenu() {
)
return;
toggleClassElements('navbar', 'block');
//elemDisplay(buttonsBar, true, 'flex');
toggleExtraBtn.className = className.down;
elemDisplay(bottomButtons, true, 'flex');
isButtonsVisible = true;
}
@@ -7395,15 +7373,11 @@ function showButtonsBarAndMenu() {
function checkButtonsBarAndMenu() {
if (lsSettings.keep_buttons_visible) {
toggleClassElements('navbar', 'block');
toggleExtraBtn.className = className.up;
elemDisplay(buttonsBar, true, 'flex');
elemDisplay(bottomButtons, true, 'flex');
isButtonsVisible = true;
} else {
if (!isButtonsBarOver) {
toggleClassElements('navbar', 'none');
toggleExtraBtn.className = className.up;
elemDisplay(buttonsBar, false);
elemDisplay(bottomButtons, false);
isButtonsVisible = false;
}
@@ -8115,19 +8089,19 @@ async function setMyVideoStatusTrue() {
* https://developer.mozilla.org/en-US/docs/Web/API/Fullscreen_API
*/
function toggleFullScreen() {
const fullScreenIcon = fullScreenBtn.querySelector('i');
if (!document.fullscreenElement) {
document.documentElement.requestFullscreen();
fullScreenBtn.className = className.fsOn;
fullScreenIcon.className = className.fsOn;
isDocumentOnFullScreen = true;
} else {
if (document.exitFullscreen) {
document.exitFullscreen();
fullScreenBtn.className = className.fsOff;
fullScreenIcon.className = className.fsOff;
isDocumentOnFullScreen = false;
}
}
const fullScreenLabel = isDocumentOnFullScreen ? 'Exit full screen' : 'View full screen';
setTippy(fullScreenBtn, fullScreenLabel, placement);
screenReaderAccessibility.announceMessage(fullScreenLabel);
}
@@ -8652,8 +8626,8 @@ function handleMediaRecorderStart(event) {
emitPeerStatus('rec', true);
console.log('MediaRecorder started: ', event);
isStreamRecording = true;
recordStreamBtn.style.setProperty('color', '#ff4500');
setTippy(recordStreamBtn, 'Stop recording', placement);
const recordStreamIcon = recordStreamBtn.querySelector('i');
recordStreamIcon.style.setProperty('color', '#ff4500');
if (isMobileDevice) elemDisplay(swapCameraBtn, false);
recStartTs = performance.now();
playSound('recStart');
@@ -8688,9 +8662,11 @@ function handleMediaRecorderStop(event) {
});
isRecScreenStream = false;
}
recordStreamBtn.style.setProperty('color', '#ffffff');
const recordStreamIcon = recordStreamBtn.querySelector('i');
recordStreamIcon.style.setProperty('color', '#ffffff');
downloadRecordedStream();
setTippy(recordStreamBtn, 'Start recording', placement);
if (isMobileDevice) elemDisplay(swapCameraBtn, true, 'block');
playSound('recStop');
@@ -8876,7 +8852,6 @@ function showChatRoomDraggable() {
elemDisplay(msgerCP, false);
if (isMobileDevice) {
elemDisplay(buttonsBar, false);
elemDisplay(bottomButtons, false);
isButtonsVisible = false;
}
@@ -8900,20 +8875,21 @@ function showChatRoomDraggable() {
function showCaptionDraggable() {
playSound('newMessage');
if (isMobileDevice) {
elemDisplay(buttonsBar, false);
elemDisplay(bottomButtons, false);
isButtonsVisible = false;
}
//captionRightCenter();
captionCenter();
captionBtn.className = 'far fa-closed-captioning';
const captionIcon = captionBtn.querySelector('i');
captionIcon.className = 'far fa-closed-captioning';
isCaptionBoxVisible = true;
if (isDesktopDevice && canBePinned()) {
toggleCaptionPin();
}
setTippy(captionBtn, 'Close the caption', placement);
screenReaderAccessibility.announceMessage('Caption opened');
}
@@ -9262,9 +9238,11 @@ function hideCaptionBox() {
captionUnpin();
}
elemDisplay(captionDraggable, false);
captionBtn.className = className.captionOn;
const captionIcon = captionBtn.querySelector('i');
captionIcon.className = 'fas fa-closed-captioning';
isCaptionBoxVisible = false;
setTippy(captionBtn, 'Open the caption', placement);
}
/**
@@ -10451,16 +10429,17 @@ async function emitPeerStatus(element, status, extras = {}) {
* @param {boolean} isHideMeActive
*/
function handleHideMe(isHideMeActive) {
const hideMeIcon = hideMeBtn.querySelector('i');
if (isHideMeActive) {
if (isVideoPinned) myVideoPinBtn.click();
elemDisplay(myVideoWrap, false);
setColor(hideMeBtn, 'red');
hideMeBtn.className = className.hideMeOn;
setColor(hideMeIcon, 'red');
hideMeIcon.className = className.hideMeOn;
playSound('off');
} else {
elemDisplay(myVideoWrap, true, 'inline-block');
hideMeBtn.className = className.hideMeOff;
setColor(hideMeBtn, 'var(--btn-bar-bg-color)');
hideMeIcon.className = className.hideMeOff;
setColor(hideMeIcon, 'var(--btn-bar-bg-color)');
playSound('on');
}
resizeVideoMedia();
@@ -11491,9 +11470,6 @@ function toggleLockUnlockWhiteboard() {
function toggleWhiteboard() {
if (!wbIsOpen) {
playSound('newMessage');
setTippy(whiteboardBtn, 'Close the Whiteboard', placement);
} else {
setTippy(whiteboardBtn, 'Open the Whiteboard', placement);
}
whiteboard.classList.toggle('show');
@@ -13540,7 +13516,7 @@ function showAbout() {
Swal.fire({
background: swBg,
position: 'center',
title: brand.about?.title && brand.about.title.trim() !== '' ? brand.about.title : 'WebRTC P2P v1.6.95',
title: brand.about?.title && brand.about.title.trim() !== '' ? brand.about.title : 'WebRTC P2P v1.6.96',
imageUrl: brand.about?.imageUrl && brand.about.imageUrl.trim() !== '' ? brand.about.imageUrl : images.about,
customClass: { image: 'img-about' },
html: `
@@ -14139,20 +14115,30 @@ function disable(elem, disabled) {
elem.disabled = disabled;
}
/**
* Remove Border Radius
*/
function restoreSplitButtonsBorderRadius() {
// On mobile we skip dropdown behavior, but ensure split buttons still look rounded.
document.querySelectorAll('#bottomButtons .split-btn').forEach((group) => {
group.querySelectorAll('button').forEach((button) => {
// Hack: Exclude settingsExtraToggle extra buttons...
if (button.id != 'settingsExtraToggle' && button.id != 'mySettingsBtn') {
button.style.setProperty('border-radius', '10px', 'important');
}
});
const toggle = group.querySelector('.device-dropdown-toggle');
if (toggle) toggle.style.setProperty('border-left', 'none', 'important');
});
}
/**
* Setup Quick audio/video device switch dropdowns
*/
function setupQuickDeviceSwitchDropdowns() {
// For now keep this feature only for desktop devices
if (!isDesktopDevice) {
// On mobile we skip dropdown behavior, but ensure split buttons still look rounded.
document.querySelectorAll('#bottomButtons .split-btn').forEach((group) => {
group.querySelectorAll('button').forEach((button) => {
button.style.setProperty('border-radius', '10px', 'important');
});
const toggle = group.querySelector('.device-dropdown-toggle');
if (toggle) toggle.style.setProperty('border-left', 'none', 'important');
});
restoreSplitButtonsBorderRadius();
return;
}
-66
View File
@@ -145,70 +145,6 @@ function setWidth(Tiles, width, bigWidth, margin, maxHeight, isOneVideoElement)
}
}
/**
* Handle main buttons size (responsive)
*/
function resizeMainButtons() {
if (!mainButtonsBar) return;
// Devices break point
const MOBILE_BREAKPOINT = 500;
const TABLET_BREAKPOINT = 580;
const DESKTOP_BREAKPOINT = 730;
// Devices width x height
const windowWidth = window.innerWidth;
const windowHeight = window.innerHeight;
//console.log('Window size', { width: windowWidth, height: windowWidth});
// Determine whether buttons bar is vertical or horizontal
const isButtonsBarVertical = btnsBarSelect.selectedIndex === 0;
if (isButtonsBarVertical) {
// Main buttons vertical align
if (windowHeight <= MOBILE_BREAKPOINT) {
setStyles(mainButtonsBar, '0.8rem', '2px', mainButtonsIcon, '0.8rem', '25px');
} else if (windowHeight <= TABLET_BREAKPOINT) {
setStyles(mainButtonsBar, '1rem', '3px', mainButtonsIcon, '1rem', '30px');
} else if (windowHeight <= DESKTOP_BREAKPOINT) {
setStyles(mainButtonsBar, '1.2rem', '4px', mainButtonsIcon, '1rem', '35px');
} else {
// > DESKTOP_BREAKPOINT
setStyles(mainButtonsBar, '1.5rem', '4px', mainButtonsIcon, '1.2rem', '40px');
}
} else {
// Main buttons horizontal align
if (windowWidth <= MOBILE_BREAKPOINT) {
setStyles(mainButtonsBar, '0.8rem', '2px', mainButtonsIcon, '0.8rem');
} else if (windowWidth <= TABLET_BREAKPOINT) {
setStyles(mainButtonsBar, '1rem', '3px', mainButtonsIcon, '1rem');
} else if (windowWidth <= DESKTOP_BREAKPOINT) {
setStyles(mainButtonsBar, '1.2rem', '4px', mainButtonsIcon, '1rem');
} else {
// > DESKTOP_BREAKPOINT
setStyles(mainButtonsBar, '1.5rem', '4px', mainButtonsIcon, '1.2rem');
}
}
/**
* Set styles based on orientation
* @param {object} elements
* @param {string} fontSize
* @param {string} padding
* @param {object} icons
* @param {string} fontSizeIcon
* @param {string} bWidth
*/
function setStyles(elements, fontSize, padding, icons, fontSizeIcon, bWidth = null) {
if (bWidth) document.documentElement.style.setProperty('--btns-width', bWidth);
elements.forEach(function (element) {
element.style.fontSize = fontSize;
element.style.padding = padding;
});
icons.forEach(function (icon) {
icon.style.fontSize = fontSizeIcon;
});
}
}
/**
* Handle window event listener
*/
@@ -216,13 +152,11 @@ window.addEventListener(
'load',
function (event) {
resizeVideoMedia();
resizeMainButtons();
let resizeTimeout;
window.addEventListener('resize', function () {
if (resizeTimeout) cancelAnimationFrame(resizeTimeout);
resizeTimeout = requestAnimationFrame(function () {
resizeVideoMedia();
resizeMainButtons();
});
});
},
+36 -21
View File
@@ -131,27 +131,8 @@ access to use this app.
<div id="usernameEmoji" class="usernameEmoji fadein center hidden"></div>
<!-- Start buttons bar https://fontawesome.com/icons?d=gallery -->
<div id="buttonsBar" class="fadein">
<button id="shareRoomBtn" class="fas fa-share-alt"></button>
<button id="hideMeBtn" class="fas fa-user"></button>
<button id="recordStreamBtn" class="fas fa-record-vinyl"></button>
<button id="fullScreenBtn" class="fas fa-expand-alt"></button>
<button id="roomEmojiPickerBtn" class="fas fa-face-smile"></button>
<button id="captionBtn" class="fas fa-closed-captioning"></button>
<button id="whiteboardBtn" class="fas fa-chalkboard-teacher"></button>
<button id="snapshotRoomBtn" class="fas fas fa-camera-retro"></button>
<button id="fileShareBtn" class="fas fa-folder-open"></button>
<button id="documentPiPBtn" class="fas fa-images"></button>
<button id="aboutBtn" class="fas fa-question"></button>
</div>
<!-- End left buttons -->
<!-- Start bottom buttons -->
<div id="bottomButtons" class="fadein">
<button id="toggleExtraBtn" class="fas fa-chevron-down"></button>
<div id="audioSplit" class="split-btn">
<button id="audioBtn" class="fas fa-microphone"></button>
<div id="audioDropdown" class="dropdown dropup hidden">
@@ -192,7 +173,41 @@ access to use this app.
<button id="participantsBtn" class="fas fa-users">
<span id="participantsCountBadge"></span>
</button>
<button id="mySettingsBtn" class="fas fa-cogs"></button>
<div id="settingsSplit" class="split-btn">
<button id="mySettingsBtn" class="fas fa-cogs"></button>
<div id="settingsExtraDropdown" class="dropdown dropup">
<button
id="settingsExtraToggle"
class="dropdown-toggle device-dropdown-toggle"
type="button"
data-bs-toggle="dropdown"
aria-expanded="false"
aria-label="Settings menu"
>
<i class="fas fa-chevron-up"></i>
</button>
<div
id="settingsExtraMenu"
class="dropdown-menu text-start hidden"
aria-labelledby="settingsExtraToggle"
>
<!-- https://fontawesome.com/icons?d=gallery -->
<button id="shareRoomBtn"><i class="fas fa-share-alt"></i> Share Room</button>
<button id="hideMeBtn"><i class="fas fa-user"></i> Hide Me</button>
<button id="recordStreamBtn"><i class="fas fa-record-vinyl"></i> Recording</button>
<button id="fullScreenBtn"><i class="fas fa-expand-alt"></i> Full screen</button>
<button id="roomEmojiPickerBtn"><i class="fas fa-face-smile"></i> Room Emoji</button>
<button id="captionBtn"><i class="fas fa-closed-captioning"></i> Caption</button>
<button id="whiteboardBtn"><i class="fas fa-chalkboard-teacher"></i> Whiteboard</button>
<button id="snapshotRoomBtn"><i class="fas fa-camera-retro"></i> Snapshot</button>
<button id="fileShareBtn"><i class="fas fa-folder-open"></i> File Share</button>
<button id="documentPiPBtn"><i class="fas fa-images"></i> Document PiP</button>
<button id="aboutBtn"><i class="fas fa-question"></i> About</button>
</div>
</div>
</div>
<button id="leaveRoomBtn" class="fa-solid fa-phone-slash"></button>
</div>
@@ -1022,7 +1037,6 @@ access to use this app.
<section id="whiteboard" class="hidden">
<header id="whiteboardHeader" class="whiteboard-header">
<div id="whiteboardTitle" class="whiteboard-header-title">
<button id="whiteboardCloseBtn" class="fas fa-times"></button>
<button id="whiteboardLockBtn" class="fa-solid fa-lock-open"></button>
<button id="whiteboardUnlockBtn" class="fa-solid fa-lock"></button>
</div>
@@ -1079,6 +1093,7 @@ access to use this app.
<button id="whiteboardShortcutsBtn"><i class="fas fa-keyboard"></i> Shortcuts</button>
</div>
</div>
<button id="whiteboardCloseBtn" class="fas fa-times"></button>
</div>
</header>
<main>