diff --git a/frontend-tools/video-js/src/VideoJS.css b/frontend-tools/video-js/src/VideoJS.css index f3723aef..03ed7117 100644 --- a/frontend-tools/video-js/src/VideoJS.css +++ b/frontend-tools/video-js/src/VideoJS.css @@ -143,9 +143,26 @@ html { background: rgba(0, 0, 0, 0.2) !important; } +/* Volume panel wrapper styling */ +.video-js .vjs-volume-wrapper { + order: 2 !important; + display: flex !important; + align-items: center !important; + justify-content: center !important; + position: relative !important; + background: rgba(0, 0, 0, 0.1) !important; + border-radius: 6px !important; + padding: 2px !important; + margin: 0 2px !important; + transition: background-color 0.3s ease !important; +} + +.video-js .vjs-volume-wrapper:hover { + background: rgba(0, 0, 0, 0.2) !important; +} + .video-js .vjs-control { height: auto !important; - } .video-js .vjs-next-video-control { order: 1 !important; @@ -190,7 +207,7 @@ html { /* YouTube-style bottom gradient overlay - covers entire video bottom when controls active */ .video-js-root-main .video-js.video-js-rounded-corners::after { - content: ''; + content: ""; position: absolute; bottom: 0; left: 0; @@ -227,7 +244,7 @@ html { /* Dark background overlay when controls are visible to improve readability on bright videos */ .video-js.vjs-user-active::before, .video-js.vjs-paused::before { - content: ''; + content: ""; position: absolute; bottom: 0; left: 0; @@ -306,7 +323,6 @@ html { } .vjs-progress-holder { background: rgba(255, 255, 255, 0.5) !important; - } .video-js .vjs-progress-control { @@ -329,7 +345,7 @@ html { .video-js .vjs-control-bar .vjs-icon-placeholder, .video-js .vjs-control-bar .vjs-button .vjs-icon-placeholder, -.video-js .vjs-control-bar [class*='vjs-icon-'] { +.video-js .vjs-control-bar [class*="vjs-icon-"] { font-size: 1.5em !important; } @@ -549,7 +565,7 @@ button.vjs-button > .vjs-icon-placeholder:before { opacity: 0 !important; display: none !important; } - + /* Ensure mute button is still visible and functional */ .video-js .vjs-volume-panel .vjs-mute-control { display: flex !important; @@ -711,7 +727,7 @@ button.vjs-button > .vjs-icon-placeholder:before { opacity: 0 !important; display: none !important; } - + /* Compact buttons for small screens */ .vjs-chapters-button button.vjs-button, .vjs-subtitles-button button.vjs-button, diff --git a/frontend-tools/video-js/src/components/video-player/VideoJSPlayer.jsx b/frontend-tools/video-js/src/components/video-player/VideoJSPlayer.jsx index dc8abe2e..4ddd78c1 100644 --- a/frontend-tools/video-js/src/components/video-player/VideoJSPlayer.jsx +++ b/frontend-tools/video-js/src/components/video-player/VideoJSPlayer.jsx @@ -2296,8 +2296,9 @@ function VideoJSPlayer({ videoId = 'default-video' }) { // BEGIN: Wrap play button in custom div container const playButtonEl = playToggle.el(); const playButtonWrapper = document.createElement('div'); - playButtonWrapper.className = 'vjs-play-wrapper vjs-menu-button vjs-menu-button-popup vjs-control vjs-button'; - + playButtonWrapper.className = + 'vjs-play-wrapper vjs-menu-button vjs-menu-button-popup vjs-control vjs-button'; + // Insert wrapper before the play button and move play button inside playButtonEl.parentNode.insertBefore(playButtonWrapper, playButtonEl); playButtonWrapper.appendChild(playButtonEl); @@ -2313,7 +2314,7 @@ function VideoJSPlayer({ videoId = 'default-video' }) { // Insert it early in control bar - right after play button for priority const playToggleIndex = controlBar.children().indexOf(playToggle); controlBar.addChild(customRemainingTime, {}, playToggleIndex + 1); - + // Store reference for cleanup customComponents.current.customRemainingTime = customRemainingTime; // END: Implement custom time display component @@ -2326,14 +2327,15 @@ function VideoJSPlayer({ videoId = 'default-video' }) { }); const playToggleIndex = controlBar.children().indexOf(playToggle); // Insert it after play button controlBar.addChild(nextVideoButton, {}, playToggleIndex + 2); // After time display - + // Wrap next video button in custom div container setTimeout(() => { const nextVideoButtonEl = nextVideoButton.el(); if (nextVideoButtonEl) { const nextVideoWrapper = document.createElement('div'); - nextVideoWrapper.className = 'vjs-next-video-wrapper vjs-menu-button vjs-menu-button-popup vjs-control vjs-button'; - + nextVideoWrapper.className = + 'vjs-next-video-wrapper vjs-menu-button vjs-menu-button-popup vjs-control vjs-button'; + // Insert wrapper before the next video button and move button inside nextVideoButtonEl.parentNode.insertBefore(nextVideoWrapper, nextVideoButtonEl); nextVideoWrapper.appendChild(nextVideoButtonEl); @@ -2342,6 +2344,24 @@ function VideoJSPlayer({ videoId = 'default-video' }) { } // END: Implement custom next video button + // BEGIN: Wrap volume panel in custom div container + setTimeout(() => { + const volumePanel = controlBar.getChild('volumePanel'); + if (volumePanel) { + const volumePanelEl = volumePanel.el(); + if (volumePanelEl) { + const volumeWrapper = document.createElement('div'); + volumeWrapper.className = + 'vjs-volume-wrapper vjs-menu-button vjs-menu-button-popup vjs-control vjs-button'; + + // Insert wrapper before the volume panel and move panel inside + volumePanelEl.parentNode.insertBefore(volumeWrapper, volumePanelEl); + volumeWrapper.appendChild(volumePanelEl); + } + } + }, 100); // Small delay to ensure volume panel is fully rendered + // END: Wrap volume panel in custom div container + // BEGIN: Implement autoplay toggle button - simplified if (!isEmbedPlayer) { try {