Răsfoiți Sursa

Good controls

Billy Barrow 1 lună în urmă
părinte
comite
61b5c2b039
2 a modificat fișierele cu 169 adăugiri și 20 ștergeri
  1. 165 10
      custom-controls.js
  2. 4 10
      video_player.php

+ 165 - 10
custom-controls.js

@@ -18,7 +18,9 @@ const CustomVideoControls = {
     fullscreenBtn: null,
     
     controlsTimeout: null,
+    mouseTimeout: null,
     container: null,
+    isMouseOverContainer: false,
     
     /**
      * Initialize the custom video controls
@@ -59,6 +61,12 @@ const CustomVideoControls = {
         
         // Set up mouse movement detection for auto-hiding controls
         this.setupAutoHide();
+        
+        // Set up mouse inactivity detection
+        this.setupMouseInactivityDetection();
+        
+        // Set up focus handling for top controls
+        this.setupTopControlsFocusHandling();
     },
     
     /**
@@ -78,22 +86,44 @@ const CustomVideoControls = {
      */
     setupEventListeners() {
         // Play/Pause button
-        this.playPauseBtn.addEventListener('click', () => this.togglePlayPause());
+        this.playPauseBtn.addEventListener('click', () => {
+            this.togglePlayPause();
+            this.playPauseBtn.blur();
+        });
         
         // Seek slider
-        this.seekSlider.addEventListener('input', () => this.seek());
+        this.seekSlider.addEventListener('input', () => {
+            this.seek();
+        });
+        this.seekSlider.addEventListener('change', () => {
+            this.seekSlider.blur();
+        });
         
         // Progress bar click to seek
-        this.progressBar.addEventListener('click', (e) => this.progressBarSeek(e));
+        this.progressBar.addEventListener('click', (e) => {
+            this.progressBarSeek(e);
+            e.target.blur();
+        });
         
         // Mute button
-        this.muteBtn.addEventListener('click', () => this.toggleMute());
+        this.muteBtn.addEventListener('click', () => {
+            this.toggleMute();
+            this.muteBtn.blur();
+        });
         
         // Volume slider
-        this.volumeSlider.addEventListener('input', () => this.updateVolume());
+        this.volumeSlider.addEventListener('input', () => {
+            this.updateVolume();
+        });
+        this.volumeSlider.addEventListener('change', () => {
+            this.volumeSlider.blur();
+        });
         
         // Fullscreen button
-        this.fullscreenBtn.addEventListener('click', () => this.toggleFullscreen());
+        this.fullscreenBtn.addEventListener('click', () => {
+            this.toggleFullscreen();
+            this.fullscreenBtn.blur();
+        });
         
         // Video click to toggle play/pause
         this.video.addEventListener('click', (e) => {
@@ -110,16 +140,20 @@ const CustomVideoControls = {
         this.video.addEventListener('play', () => {
             this.updatePlayPauseButton();
             this.hideControlsWithTimeout(); // Auto-hide controls when playing
+            this.hideCursorWithTimeout(); // Auto-hide cursor when playing
         });
         this.video.addEventListener('pause', () => {
             this.updatePlayPauseButton();
             this.showControls(); // Show controls when paused
+            this.showCursor(); // Show cursor when paused
+            this.resetMouseTimeout(); // Clear cursor timeout when paused
         });
         this.video.addEventListener('seeking', () => {
             this.showControls(); // Show controls when seeking
         });
         this.video.addEventListener('seeked', () => {
             this.hideControlsWithTimeout(); // Auto-hide after seeking
+            this.hideCursorWithTimeout(); // Auto-hide cursor after seeking
         });
         
         // Keyboard controls
@@ -134,9 +168,9 @@ const CustomVideoControls = {
         
         // Add mouse movement detection for the entire container
         if (this.container) {
-            this.container.addEventListener('mousemove', () => this.showControls());
-            this.container.addEventListener('mouseleave', () => this.hideControls());
-            this.container.addEventListener('mouseenter', () => this.showControls());
+            this.container.addEventListener('mousemove', () => this.handleMouseMove());
+            this.container.addEventListener('mouseleave', () => this.handleMouseLeave());
+            this.container.addEventListener('mouseenter', () => this.handleMouseEnter());
         }
         
         // Touch events for mobile support
@@ -352,9 +386,10 @@ const CustomVideoControls = {
         // Always show controls when entering/exiting fullscreen
         this.showControls();
         
-        // Auto-hide controls after a delay in fullscreen mode if video is playing
+        // Auto-hide controls and cursor after a delay in fullscreen mode if video is playing
         if (isFullscreen && !this.video.paused) {
             this.hideControlsWithTimeout();
+            this.hideCursorWithTimeout();
         }
     },
     
@@ -412,10 +447,14 @@ const CustomVideoControls = {
         if (this.topControls) {
             this.topControls.classList.add('show');
         }
+        this.showCursor();
+        
         // Only reset timeout if video is playing (to allow auto-hide when idle)
         if (!this.video.paused) {
             this.resetControlsTimeout();
             this.hideControlsWithTimeout();
+            this.resetMouseTimeout();
+            this.hideCursorWithTimeout();
         }
     },
     
@@ -428,9 +467,75 @@ const CustomVideoControls = {
             if (this.topControls) {
                 this.topControls.classList.remove('show');
             }
+            this.hideCursor();
+        }
+    },
+    
+    /**
+     * Show the cursor
+     */
+    showCursor() {
+        if (this.container) {
+            this.container.style.cursor = 'auto';
+        }
+    },
+    
+    /**
+     * Hide the cursor
+     */
+    hideCursor() {
+        if (this.container && !this.video.paused) {
+            this.container.style.cursor = 'none';
+        }
+    },
+    
+    /**
+     * Hide cursor with a timeout
+     */
+    hideCursorWithTimeout() {
+        this.resetMouseTimeout();
+        this.mouseTimeout = setTimeout(() => {
+            this.hideCursor();
+        }, 3000); // 3 seconds
+    },
+    
+    /**
+     * Reset the mouse timeout
+     */
+    resetMouseTimeout() {
+        if (this.mouseTimeout) {
+            clearTimeout(this.mouseTimeout);
+            this.mouseTimeout = null;
+        }
+    },
+    
+    /**
+     * Handle mouse movement inside the container
+     */
+    handleMouseMove() {
+        this.showControls();
+        if (!this.video.paused) {
+            this.resetMouseTimeout();
+            this.hideCursorWithTimeout();
         }
     },
     
+    /**
+     * Handle mouse entering the container
+     */
+    handleMouseEnter() {
+        this.isMouseOverContainer = true;
+        this.showControls();
+    },
+    
+    /**
+     * Handle mouse leaving the container
+     */
+    handleMouseLeave() {
+        this.isMouseOverContainer = false;
+        this.hideControls();
+    },
+    
     /**
      * Hide controls with a timeout
      */
@@ -459,6 +564,19 @@ const CustomVideoControls = {
         // so we don't need to add them again here to prevent duplicate execution
     },
     
+    /**
+     * Set up mouse inactivity detection
+     */
+    setupMouseInactivityDetection() {
+        // Initial state - show cursor
+        this.showCursor();
+        
+        // Set up initial timeout if video is playing
+        if (!this.video.paused) {
+            this.hideCursorWithTimeout();
+        }
+    },
+    
     /**
      * Handle window resize events
      */
@@ -471,9 +589,46 @@ const CustomVideoControls = {
         this.resizeTimeout = setTimeout(() => {
             if (!this.video.paused) {
                 this.hideControlsWithTimeout();
+                this.hideCursorWithTimeout();
             }
         }, 1000);
     },
+    
+    /**
+     * Set up focus handling for top controls
+     */
+    setupTopControlsFocusHandling() {
+        // Get top control buttons and select
+        const infoBtn = document.querySelector('button[onclick="showInfo()"]');
+        const shareBtn = document.querySelector('button[onclick="shareVideo()"]');
+        const downloadBtn = document.querySelector('button[onclick="downloadVideo()"]');
+        const qualitySelector = document.getElementById('quality-selector');
+        
+        // Add blur() calls to top control buttons
+        if (infoBtn) {
+            infoBtn.addEventListener('click', () => {
+                infoBtn.blur();
+            });
+        }
+        
+        if (shareBtn) {
+            shareBtn.addEventListener('click', () => {
+                shareBtn.blur();
+            });
+        }
+        
+        if (downloadBtn) {
+            downloadBtn.addEventListener('click', () => {
+                downloadBtn.blur();
+            });
+        }
+        
+        if (qualitySelector) {
+            qualitySelector.addEventListener('change', () => {
+                qualitySelector.blur();
+            });
+        }
+    },
 };
 
 // @license-end

+ 4 - 10
video_player.php

@@ -57,7 +57,8 @@ function ppvm_player($ppub, $path, $video) {
                 z-index: 2147483646; /* High z-index to stay visible in fullscreen */
             }
 
-            body:hover .additional-contols.javascript, .paused.javascript, .noscript {
+            /* Removed body:hover .additional-contols.javascript to let JavaScript handle visibility */
+            .paused.javascript, .noscript {
                 top: 0px;
                 opacity: 1;
             }
@@ -77,14 +78,7 @@ function ppvm_player($ppub, $path, $video) {
                 z-index: 2147483646 !important;
             }
             
-            /* Also ensure top controls are visible when hovering in fullscreen */
-            :fullscreen:hover .additional-contols,
-            :-webkit-full-screen:hover .additional-contols,
-            :-moz-full-screen:hover .additional-contols,
-            :-ms-fullscreen:hover .additional-contols {
-                opacity: 1 !important;
-                top: 0 !important;
-            }
+            /* Removed fullscreen hover rules to let JavaScript handle visibility */
 
             .noscript-text {
                 white-space: nowrap;
@@ -236,7 +230,7 @@ function ppvm_player($ppub, $path, $video) {
                 opacity: 1;
             }
 
-            body:hover .video-controls,
+            /* Removed body:hover .video-controls to let JavaScript handle visibility */
             .video-controls:hover,
             .video-controls:focus-within {
                 opacity: 1;