import videojs from 'video.js';
import './AutoplayToggleButton.css';
const Button = videojs.getComponent('Button');
// Custom Autoplay Toggle Button Component using modern Video.js API
class AutoplayToggleButton extends Button {
constructor(player, options) {
super(player, options);
// Check if this is a touch device - don't create button on touch devices
const isTouchDevice =
options.isTouchDevice ||
'ontouchstart' in window ||
navigator.maxTouchPoints > 0 ||
navigator.msMaxTouchPoints > 0;
if (isTouchDevice) {
// Hide the button on touch devices
this.hide();
return;
}
this.userPreferences = options.userPreferences;
// Get autoplay preference from localStorage, default to false if not set
if (this.userPreferences) {
const savedAutoplay = this.userPreferences.getPreference('autoplay');
this.isAutoplayEnabled = savedAutoplay === true; // Explicit boolean check
} else {
this.isAutoplayEnabled = false;
}
// Bind methods
this.updateIcon = this.updateIcon.bind(this);
this.handleClick = this.handleClick.bind(this);
}
createEl() {
const button = super.createEl('button', {
className: 'vjs-autoplay-toggle vjs-control vjs-button',
type: 'button',
title: this.isAutoplayEnabled ? 'Autoplay is on' : 'Autoplay is off',
'aria-label': this.isAutoplayEnabled ? 'Autoplay is on' : 'Autoplay is off',
});
// Create icon placeholder using VideoJS icon system
this.iconSpan = videojs.dom.createEl('span', {
'aria-hidden': 'true',
className: 'vjs-icon-placeholder vjs-autoplay-icon',
});
// Set initial icon state using font icons
this.updateIconClass();
// Create control text span
const controlTextSpan = videojs.dom.createEl('span', {
className: 'vjs-control-text',
});
controlTextSpan.textContent = this.isAutoplayEnabled ? 'Autoplay is on' : 'Autoplay is off';
// Append both spans to button
button.appendChild(this.iconSpan);
button.appendChild(controlTextSpan);
// Add touch support for mobile tooltips
this.addTouchSupport(button);
return button;
}
updateIconClass() {
// Remove existing icon classes
this.iconSpan.className = 'vjs-icon-placeholder vjs-svg-icon vjs-autoplay-icon__OFFF';
this.iconSpan.style.position = 'relative';
this.iconSpan.style.top = '2px';
// Add appropriate icon class based on state
// Add appropriate icon class based on state
if (this.isAutoplayEnabled) {
// this.iconSpan.classList.add('vjs-icon-spinner');
this.iconSpan.innerHTML = `
`;
} else {
// this.iconSpan.classList.add('vjs-icon-play-circle');
this.iconSpan.innerHTML = `
`;
}
}
updateIcon() {
// Add transition and start fade-out
this.iconSpan.style.transition = 'opacity 0.1s ease';
this.iconSpan.style.opacity = '0';
// After fade-out complete, update icon class and fade back in
setTimeout(() => {
this.updateIconClass();
if (this.el()) {
this.el().title = this.isAutoplayEnabled ? 'Autoplay is on' : 'Autoplay is off';
this.el().setAttribute('aria-label', this.isAutoplayEnabled ? 'Autoplay is on' : 'Autoplay is off');
const controlText = this.el().querySelector('.vjs-control-text');
if (controlText)
controlText.textContent = this.isAutoplayEnabled ? 'Autoplay is on' : 'Autoplay is off';
}
// Fade back in
this.iconSpan.style.opacity = '1';
}, 100);
}
handleClick() {
// Toggle autoplay state
this.isAutoplayEnabled = !this.isAutoplayEnabled;
// Save preference if userPreferences is available
if (this.userPreferences) {
this.userPreferences.setAutoplayPreference(this.isAutoplayEnabled);
}
// Update icon and accessibility attributes
this.updateIcon();
// Trigger custom event for other components to listen to
this.player().trigger('autoplayToggle', { autoplay: this.isAutoplayEnabled });
}
// Method to update button state from external sources
setAutoplayState(enabled) {
this.isAutoplayEnabled = enabled;
this.updateIcon();
}
// Add touch support for mobile tooltips
addTouchSupport(button) {
// Check if device is touch-enabled
const isTouchDevice =
this.options_.isTouchDevice ||
'ontouchstart' in window ||
navigator.maxTouchPoints > 0 ||
navigator.msMaxTouchPoints > 0;
// Only add touch tooltip support on actual touch devices
if (!isTouchDevice) {
return;
}
let touchStartTime = 0;
// Touch start
button.addEventListener(
'touchstart',
() => {
touchStartTime = Date.now();
},
{ passive: true }
);
// Touch end
button.addEventListener(
'touchend',
(e) => {
const touchDuration = Date.now() - touchStartTime;
// Only show tooltip for quick taps (not swipes) and only on mobile screens
const isMobileScreen = window.innerWidth <= 767;
if (touchDuration < 500 && isMobileScreen) {
e.preventDefault();
e.stopPropagation();
// Show tooltip briefly
button.classList.add('touch-active');
// Hide tooltip after shorter delay on mobile
setTimeout(() => {
button.classList.remove('touch-active');
}, 1500);
}
},
{ passive: false }
);
}
}
// Register the component
videojs.registerComponent('AutoplayToggleButton', AutoplayToggleButton);
export default AutoplayToggleButton;