Improve mobile player controls and remove fullscreen button

Mobile improvements:
- Controls auto-hide after 3 seconds on page load
- Tap player to show/hide controls (instant hide or show with 3s auto-hide)
- Tapping outside controls grid hides them immediately
- Mobile autoplay fix: start muted, unmute after 100ms

Button changes:
- Remove fullscreen button (not needed for pop-out windows)
- Page button now always opens in new tab (simplified logic)
- Remove F key shortcut for fullscreen

Desktop behavior unchanged (hover to show controls).

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
russell@unturf.com 2026-01-21 12:40:42 -05:00
parent c6ea5f7f4b
commit 741004b2d2
2 changed files with 86 additions and 23 deletions

View file

@ -19,7 +19,6 @@
// Get media element
const media = document.getElementById('media');
const alwaysOnTopBtn = document.getElementById('alwaysOnTopBtn');
const fullscreenBtn = document.getElementById('fullscreenBtn');
const autoResizeBtn = document.getElementById('autoResizeBtn');
const playPauseBtn = document.getElementById('playPauseBtn');
@ -365,11 +364,6 @@
navigate(window.playerData.nextProductId);
}
break;
case 'f':
case 'F':
e.preventDefault();
toggleFullscreen();
break;
case 't':
case 'T':
e.preventDefault();
@ -442,9 +436,6 @@
stopAutoAdvance();
});
// Set up fullscreen change listener
document.addEventListener('fullscreenchange', updateFullscreenButton);
// Set up expiration warning
setupExpirationWarning();

View file

@ -74,7 +74,8 @@
/* Hide desktop-only buttons on mobile */
#pipBtn,
#autoResizeBtn,
#alwaysOnTopBtn {
#alwaysOnTopBtn,
#fullscreenBtn {
display: none;
}
@ -96,7 +97,22 @@
transition: opacity 0.3s;
}
.player-container:hover .player-controls {
/* Show controls on hover for desktop */
@media (min-width: 601px) {
.player-container:hover .player-controls {
opacity: 1;
}
.player-container:hover .product-title {
opacity: 1;
}
}
/* Mobile: controls shown via tap (controlled by JS) */
.player-controls.visible {
opacity: 1;
}
.product-title.visible {
opacity: 1;
}
@ -164,9 +180,6 @@
transition: opacity 0.3s;
}
.player-container:hover .product-title {
opacity: 1;
}
/* For images, add some styling to make navigation visible */
img#media {
@ -218,8 +231,8 @@
<!-- Row 2: Features -->
<button id="alwaysOnTopBtn" onclick="toggleAlwaysOnTop()" title="Always on Top (T)">📌 On Top</button>
<button id="fullscreenBtn" onclick="toggleFullscreen()" title="Fullscreen (F)">⛶ Full</button>
<button onclick="goToProductPage()" title="Go to Product Page (G)">🔗 Page</button>
<span></span><!-- Empty cell for grid alignment -->
<!-- Row 3: More options -->
<button id="autoResizeBtn" onclick="toggleAutoResize()" title="Auto-Resize Window (R)">↔ Resize</button>
@ -242,15 +255,74 @@
nextProductUrl: {{ ('"%s"' % next_product_url) if next_product_url else 'null' }}
};
// Go to the product page
// Go to the product page (always opens in new tab)
function goToProductPage() {
if (window.opener && !window.opener.closed) {
// If opened from another window, navigate that window
window.opener.location.href = window.playerData.productUrl;
window.opener.focus();
} else {
// Otherwise open in new tab
window.open(window.playerData.productUrl, '_blank');
window.open(window.playerData.productUrl, '_blank');
}
// Mobile: tap to show/hide controls
let hideTimeout;
const isMobile = window.innerWidth <= 600;
if (isMobile) {
const playerContainer = document.getElementById('playerContainer');
const playerControls = document.querySelector('.player-controls');
const controlsGrid = document.querySelector('.controls-grid');
const productTitle = document.querySelector('.product-title');
// Show controls initially for 3 seconds
playerControls.classList.add('visible');
productTitle.classList.add('visible');
hideTimeout = setTimeout(() => {
playerControls.classList.remove('visible');
productTitle.classList.remove('visible');
}, 3000);
// Tap on player container to toggle controls
playerContainer.addEventListener('click', (e) => {
// Don't toggle if clicking on a control button
if (controlsGrid.contains(e.target)) {
return;
}
// Clear existing timeout
if (hideTimeout) {
clearTimeout(hideTimeout);
}
// Toggle controls visibility
const isVisible = playerControls.classList.contains('visible');
if (isVisible) {
// Hide immediately
playerControls.classList.remove('visible');
productTitle.classList.remove('visible');
} else {
// Show and auto-hide after 3 seconds
playerControls.classList.add('visible');
productTitle.classList.add('visible');
hideTimeout = setTimeout(() => {
playerControls.classList.remove('visible');
productTitle.classList.remove('visible');
}, 3000);
}
});
}
// Mobile autoplay fix: unmute after user interaction
if (isMobile) {
const media = document.getElementById('media');
if (media && (media.tagName === 'VIDEO' || media.tagName === 'AUDIO')) {
// Try to play muted first (allowed by most browsers)
media.muted = true;
media.play().then(() => {
// Once playing, unmute after a short delay
setTimeout(() => {
media.muted = false;
}, 100);
}).catch(err => {
console.log('Autoplay failed:', err);
// User will need to tap play button
});
}
}
</script>