toggleControls() rewrite
This commit is contained in:
		@ -238,13 +238,36 @@ class Listeners {
 | 
			
		||||
            }, 0);
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        // Toggle controls visibility based on mouse movement
 | 
			
		||||
        if (this.player.config.hideControls) {
 | 
			
		||||
            // Toggle controls on mouse events and entering fullscreen
 | 
			
		||||
            utils.on(this.player.elements.container, 'mouseenter mouseleave mousemove touchstart touchend touchmove enterfullscreen exitfullscreen', event => {
 | 
			
		||||
                this.player.toggleControls(event);
 | 
			
		||||
            });
 | 
			
		||||
        }
 | 
			
		||||
        // Toggle controls on mouse events and entering fullscreen
 | 
			
		||||
        utils.on(this.player.elements.container, 'mousemove mouseleave touchstart touchmove enterfullscreen exitfullscreen', event => {
 | 
			
		||||
            const { controls } = this.player.elements;
 | 
			
		||||
 | 
			
		||||
            // Remove button states for fullscreen
 | 
			
		||||
            if (event.type === 'enterfullscreen') {
 | 
			
		||||
                controls.pressed = false;
 | 
			
		||||
                controls.hover = false;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // Show, then hide after a timeout unless another control event occurs
 | 
			
		||||
            const show = [
 | 
			
		||||
                'touchstart',
 | 
			
		||||
                'touchmove',
 | 
			
		||||
                'mousemove',
 | 
			
		||||
            ].includes(event.type);
 | 
			
		||||
 | 
			
		||||
            let delay = 0;
 | 
			
		||||
 | 
			
		||||
            if (show) {
 | 
			
		||||
                ui.toggleControls.call(this.player, true);
 | 
			
		||||
                // Use longer timeout for touch devices
 | 
			
		||||
                delay = this.player.touch ? 3000 : 2000;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // Clear timer
 | 
			
		||||
            clearTimeout(this.player.timers.controls);
 | 
			
		||||
            // Timer to prevent flicker when seeking
 | 
			
		||||
            this.player.timers.controls = setTimeout(() => ui.toggleControls.call(this.player, false), delay);
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Listen for media events
 | 
			
		||||
@ -570,26 +593,45 @@ class Listeners {
 | 
			
		||||
        // Seek tooltip
 | 
			
		||||
        on(this.player.elements.progress, 'mouseenter mouseleave mousemove', event => controls.updateSeekTooltip.call(this.player, event));
 | 
			
		||||
 | 
			
		||||
        // Toggle controls visibility based on mouse movement
 | 
			
		||||
        if (this.player.config.hideControls) {
 | 
			
		||||
            // Watch for cursor over controls so they don't hide when trying to interact
 | 
			
		||||
            on(this.player.elements.controls, 'mouseenter mouseleave', event => {
 | 
			
		||||
                this.player.elements.controls.hover = !this.player.touch && event.type === 'mouseenter';
 | 
			
		||||
            });
 | 
			
		||||
        // Update controls.hover state (used for ui.toggleControls to avoid hiding when interacting)
 | 
			
		||||
        on(this.player.elements.controls, 'mouseenter mouseleave', event => {
 | 
			
		||||
            this.player.elements.controls.hover = !this.player.touch && event.type === 'mouseenter';
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
            // Watch for cursor over controls so they don't hide when trying to interact
 | 
			
		||||
            on(this.player.elements.controls, 'mousedown mouseup touchstart touchend touchcancel', event => {
 | 
			
		||||
                this.player.elements.controls.pressed = [
 | 
			
		||||
                    'mousedown',
 | 
			
		||||
                    'touchstart',
 | 
			
		||||
                ].includes(event.type);
 | 
			
		||||
            });
 | 
			
		||||
        // Update controls.pressed state (used for ui.toggleControls to avoid hiding when interacting)
 | 
			
		||||
        on(this.player.elements.controls, 'mousedown mouseup touchstart touchend touchcancel', event => {
 | 
			
		||||
            this.player.elements.controls.pressed = [
 | 
			
		||||
                'mousedown',
 | 
			
		||||
                'touchstart',
 | 
			
		||||
            ].includes(event.type);
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
            // Focus in/out on controls
 | 
			
		||||
            on(this.player.elements.controls, 'focusin focusout', event => {
 | 
			
		||||
                this.player.toggleControls(event);
 | 
			
		||||
            });
 | 
			
		||||
        }
 | 
			
		||||
        // Focus in/out on controls
 | 
			
		||||
        on(this.player.elements.controls, 'focusin focusout', event => {
 | 
			
		||||
            const { config, elements, timers } = this.player;
 | 
			
		||||
 | 
			
		||||
            // Skip transition to prevent focus from scrolling the parent element
 | 
			
		||||
            utils.toggleClass(elements.controls, config.classNames.noTransition, event.type === 'focusin');
 | 
			
		||||
 | 
			
		||||
            // Toggle
 | 
			
		||||
            ui.toggleControls.call(this.player, event.type === 'focusin');
 | 
			
		||||
 | 
			
		||||
            // If focusin, hide again after delay
 | 
			
		||||
            if (event.type === 'focusin') {
 | 
			
		||||
                // Restore transition
 | 
			
		||||
                setTimeout(() => {
 | 
			
		||||
                    utils.toggleClass(elements.controls, config.classNames.noTransition, false);
 | 
			
		||||
                }, 0);
 | 
			
		||||
 | 
			
		||||
                // Delay a little more for keyboard users
 | 
			
		||||
                const delay = this.touch ? 3000 : 4000;
 | 
			
		||||
 | 
			
		||||
                // Clear timer
 | 
			
		||||
                clearTimeout(timers.controls);
 | 
			
		||||
                // Hide
 | 
			
		||||
                timers.controls = setTimeout(() => ui.toggleControls.call(this.player, false), delay);
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        // Mouse wheel for volume
 | 
			
		||||
        on(
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										123
									
								
								src/js/plyr.js
									
									
									
									
									
								
							
							
						
						
									
										123
									
								
								src/js/plyr.js
									
									
									
									
									
								
							@ -971,119 +971,32 @@ class Plyr {
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Toggle the player controls
 | 
			
		||||
     * @param {boolean} toggle - Whether to show the controls
 | 
			
		||||
     * @param {boolean} [toggle] - Whether to show the controls
 | 
			
		||||
     */
 | 
			
		||||
    toggleControls(toggle) {
 | 
			
		||||
        // We need controls of course...
 | 
			
		||||
        if (!utils.is.element(this.elements.controls)) {
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
        // Don't toggle if missing UI support or if it's audio
 | 
			
		||||
        if (this.supported.ui && !this.isAudio) {
 | 
			
		||||
            // Get state before change
 | 
			
		||||
            const isHidden = utils.hasClass(this.elements.container, this.config.classNames.hideControls);
 | 
			
		||||
 | 
			
		||||
        // Don't hide if no UI support or it's audio
 | 
			
		||||
        if (!this.supported.ui || this.isAudio) {
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
            // Negate the argument if not undefined since adding the class to hides the controls
 | 
			
		||||
            const force = typeof toggle === 'undefined' ? undefined : !toggle;
 | 
			
		||||
 | 
			
		||||
        let delay = 0;
 | 
			
		||||
        let show = toggle;
 | 
			
		||||
        let isEnterFullscreen = false;
 | 
			
		||||
            // Apply and get updated state
 | 
			
		||||
            const hiding = utils.toggleClass(this.elements.container, this.config.classNames.hideControls, force);
 | 
			
		||||
 | 
			
		||||
        // Get toggle state if not set
 | 
			
		||||
        if (!utils.is.boolean(toggle)) {
 | 
			
		||||
            if (utils.is.event(toggle)) {
 | 
			
		||||
                // Is the enter fullscreen event
 | 
			
		||||
                isEnterFullscreen = toggle.type === 'enterfullscreen';
 | 
			
		||||
 | 
			
		||||
                // Events that show the controls
 | 
			
		||||
                const showEvents = [
 | 
			
		||||
                    'touchstart',
 | 
			
		||||
                    'touchmove',
 | 
			
		||||
                    'mouseenter',
 | 
			
		||||
                    'mousemove',
 | 
			
		||||
                    'focusin',
 | 
			
		||||
                ];
 | 
			
		||||
 | 
			
		||||
                // Events that delay hiding
 | 
			
		||||
                const delayEvents = [
 | 
			
		||||
                    'touchmove',
 | 
			
		||||
                    'touchend',
 | 
			
		||||
                    'mousemove',
 | 
			
		||||
                ];
 | 
			
		||||
 | 
			
		||||
                // Whether to show controls
 | 
			
		||||
                show = showEvents.includes(toggle.type);
 | 
			
		||||
 | 
			
		||||
                // Delay hiding on move events
 | 
			
		||||
                if (delayEvents.includes(toggle.type)) {
 | 
			
		||||
                    delay = 2000;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                // Delay a little more for keyboard users
 | 
			
		||||
                if (!this.touch && toggle.type === 'focusin') {
 | 
			
		||||
                    delay = 3000;
 | 
			
		||||
                    utils.toggleClass(this.elements.controls, this.config.classNames.noTransition, true);
 | 
			
		||||
                }
 | 
			
		||||
            } else {
 | 
			
		||||
                show = utils.hasClass(this.elements.container, this.config.classNames.hideControls);
 | 
			
		||||
            // Close menu
 | 
			
		||||
            if (hiding && this.config.controls.includes('settings') && !utils.is.empty(this.config.settings)) {
 | 
			
		||||
                controls.toggleMenu.call(this, false);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Clear timer on every call
 | 
			
		||||
        clearTimeout(this.timers.controls);
 | 
			
		||||
 | 
			
		||||
        // If the mouse is not over the controls, set a timeout to hide them
 | 
			
		||||
        if (show || this.paused || this.loading) {
 | 
			
		||||
            // Check if controls toggled
 | 
			
		||||
            const toggled = utils.toggleClass(this.elements.container, this.config.classNames.hideControls, false);
 | 
			
		||||
 | 
			
		||||
            // Trigger event
 | 
			
		||||
            if (toggled) {
 | 
			
		||||
                utils.dispatchEvent.call(this, this.media, 'controlsshown');
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // Always show controls when paused or if touch
 | 
			
		||||
            if (this.paused || this.loading) {
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // Delay for hiding on touch
 | 
			
		||||
            if (this.touch) {
 | 
			
		||||
                delay = 3000;
 | 
			
		||||
            // Trigger event on change
 | 
			
		||||
            if (hiding !== isHidden) {
 | 
			
		||||
                const eventName = hiding ? 'controlshidden' : 'controlsshown';
 | 
			
		||||
                utils.dispatchEvent.call(this, this.media, eventName);
 | 
			
		||||
            }
 | 
			
		||||
            return !hiding;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // If toggle is false or if we're playing (regardless of toggle),
 | 
			
		||||
        // then set the timer to hide the controls
 | 
			
		||||
        if (!show || this.playing) {
 | 
			
		||||
            this.timers.controls = setTimeout(() => {
 | 
			
		||||
                // We need controls of course...
 | 
			
		||||
                if (!utils.is.element(this.elements.controls)) {
 | 
			
		||||
                    return;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                // If the mouse is over the controls (and not entering fullscreen), bail
 | 
			
		||||
                if ((this.elements.controls.pressed || this.elements.controls.hover) && !isEnterFullscreen) {
 | 
			
		||||
                    return;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                // Restore transition behaviour
 | 
			
		||||
                if (!utils.hasClass(this.elements.container, this.config.classNames.hideControls)) {
 | 
			
		||||
                    utils.toggleClass(this.elements.controls, this.config.classNames.noTransition, false);
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                // Set hideControls class
 | 
			
		||||
                const toggled = utils.toggleClass(this.elements.container, this.config.classNames.hideControls, this.config.hideControls);
 | 
			
		||||
 | 
			
		||||
                // Trigger event and close menu
 | 
			
		||||
                if (toggled) {
 | 
			
		||||
                    utils.dispatchEvent.call(this, this.media, 'controlshidden');
 | 
			
		||||
 | 
			
		||||
                    if (this.config.controls.includes('settings') && !utils.is.empty(this.config.settings)) {
 | 
			
		||||
                        controls.toggleMenu.call(this, false);
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }, delay);
 | 
			
		||||
        }
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										18
									
								
								src/js/ui.js
									
									
									
									
									
								
							
							
						
						
									
										18
									
								
								src/js/ui.js
									
									
									
									
									
								
							@ -173,7 +173,7 @@ const ui = {
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Toggle controls
 | 
			
		||||
        this.toggleControls(!this.playing);
 | 
			
		||||
        ui.toggleControls.call(this);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    // Check if media is loading
 | 
			
		||||
@ -188,14 +188,24 @@ const ui = {
 | 
			
		||||
 | 
			
		||||
        // Timer to prevent flicker when seeking
 | 
			
		||||
        this.timers.loading = setTimeout(() => {
 | 
			
		||||
            // Toggle container class hook
 | 
			
		||||
            // Update progress bar loading class state
 | 
			
		||||
            utils.toggleClass(this.elements.container, this.config.classNames.loading, this.loading);
 | 
			
		||||
 | 
			
		||||
            // Show controls if loading, hide if done
 | 
			
		||||
            this.toggleControls(this.loading);
 | 
			
		||||
            // Update controls visibility
 | 
			
		||||
            ui.toggleControls.call(this);
 | 
			
		||||
        }, this.loading ? 250 : 0);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    // Toggle controls based on state and `force` argument
 | 
			
		||||
    toggleControls(force) {
 | 
			
		||||
        const { controls } = this.elements;
 | 
			
		||||
 | 
			
		||||
        if (controls && this.config.hideControls) {
 | 
			
		||||
            // Show controls if force, loading, paused, or button interaction, otherwise hide
 | 
			
		||||
            this.toggleControls(Boolean(force || this.loading || this.paused || controls.pressed || controls.hover));
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    // Update volume UI and storage
 | 
			
		||||
    updateVolume() {
 | 
			
		||||
        if (!this.supported.ui) {
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user