Files
digiserver-v2/app/templates/players/player_fullscreen.html
2025-11-20 20:46:09 +02:00

236 lines
7.7 KiB
HTML

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{{ player.name }} - Live Preview</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
background: #000;
overflow: hidden;
font-family: Arial, sans-serif;
}
#player-container {
width: 100vw;
height: 100vh;
display: flex;
align-items: center;
justify-content: center;
position: relative;
}
#media-display {
max-width: 100%;
max-height: 100%;
width: 100%;
height: 100%;
object-fit: contain;
display: none;
}
#media-display.active {
display: block;
}
.loading {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
color: white;
font-size: 24px;
text-align: center;
}
.info-overlay {
position: fixed;
bottom: 20px;
left: 20px;
background: rgba(0, 0, 0, 0.7);
color: white;
padding: 10px 20px;
border-radius: 8px;
font-size: 14px;
z-index: 1000;
}
.controls {
position: fixed;
top: 20px;
right: 20px;
display: flex;
gap: 10px;
z-index: 1000;
transition: opacity 0.3s ease;
}
.controls button {
background: rgba(255, 255, 255, 0.2);
border: 1px solid rgba(255, 255, 255, 0.3);
color: white;
padding: 10px 15px;
border-radius: 6px;
cursor: pointer;
font-size: 14px;
}
.controls button:hover {
background: rgba(255, 255, 255, 0.3);
}
.no-content {
color: white;
text-align: center;
font-size: 24px;
}
</style>
</head>
<body>
<div id="player-container">
<div class="loading" id="loading">Loading playlist...</div>
<img id="media-display" alt="Content">
<video id="video-display" muted autoplay playsinline style="display: none; max-width: 100%; max-height: 100%; width: 100%; height: 100%; object-fit: contain;"></video>
<div class="no-content" id="no-content" style="display: none;">
<p>💭 No content in playlist</p>
<p style="font-size: 16px; margin-top: 10px; opacity: 0.7;">Add content to the playlist to preview</p>
</div>
</div>
<div class="info-overlay" id="info-overlay" style="display: none;">
<div id="current-item">Item: -</div>
<div id="playlist-info">Playlist: {{ playlist|length }} items</div>
</div>
<div class="controls">
<button onclick="toggleFullscreen()">🔳 Fullscreen</button>
<button onclick="restartPlaylist()">🔄 Restart</button>
<button onclick="window.close()">✖️ Close</button>
</div>
<script>
const playlist = {{ playlist|tojson }};
let currentIndex = 0;
let timer = null;
let inactivityTimer = null;
const imgDisplay = document.getElementById('media-display');
const videoDisplay = document.getElementById('video-display');
const loading = document.getElementById('loading');
const noContent = document.getElementById('no-content');
const infoOverlay = document.getElementById('info-overlay');
const currentItemDiv = document.getElementById('current-item');
const controls = document.querySelector('.controls');
function playNext() {
if (!playlist || playlist.length === 0) {
loading.style.display = 'none';
noContent.style.display = 'block';
return;
}
const item = playlist[currentIndex];
loading.style.display = 'none';
infoOverlay.style.display = 'block';
// Update info
currentItemDiv.textContent = `Item ${currentIndex + 1}/${playlist.length}: ${item.filename}`;
// Hide both displays
imgDisplay.style.display = 'none';
videoDisplay.style.display = 'none';
videoDisplay.pause();
if (item.type === 'video') {
videoDisplay.src = item.url;
videoDisplay.muted = item.muted !== false; // Muted unless explicitly set to false
videoDisplay.style.display = 'block';
videoDisplay.play();
// When video ends, move to next
videoDisplay.onended = () => {
currentIndex = (currentIndex + 1) % playlist.length;
playNext();
};
} else {
// Image or PDF
imgDisplay.src = item.url;
imgDisplay.style.display = 'block';
imgDisplay.classList.add('active');
// Clear any existing timer
if (timer) clearTimeout(timer);
// Show for specified duration
timer = setTimeout(() => {
currentIndex = (currentIndex + 1) % playlist.length;
playNext();
}, (item.duration || 10) * 1000);
}
}
function toggleFullscreen() {
if (!document.fullscreenElement) {
document.documentElement.requestFullscreen();
} else {
document.exitFullscreen();
}
}
function restartPlaylist() {
currentIndex = 0;
if (timer) clearTimeout(timer);
videoDisplay.pause();
playNext();
}
// Auto-hide controls after 5 seconds of inactivity
function resetInactivityTimer() {
// Show controls
controls.style.opacity = '1';
controls.style.pointerEvents = 'auto';
// Clear existing timer
if (inactivityTimer) {
clearTimeout(inactivityTimer);
}
// Set new timer to hide controls after 5 seconds
inactivityTimer = setTimeout(() => {
controls.style.opacity = '0';
controls.style.pointerEvents = 'none';
}, 5000);
}
// Track user activity to show/hide controls
document.addEventListener('mousemove', resetInactivityTimer);
document.addEventListener('mousedown', resetInactivityTimer);
document.addEventListener('keydown', resetInactivityTimer);
document.addEventListener('touchstart', resetInactivityTimer);
// Start playing when page loads
window.addEventListener('load', () => {
playNext();
resetInactivityTimer(); // Start inactivity timer
});
// Handle keyboard shortcuts
document.addEventListener('keydown', (e) => {
if (e.key === 'f' || e.key === 'F') {
toggleFullscreen();
} else if (e.key === 'r' || e.key === 'R') {
restartPlaylist();
} else if (e.key === 'Escape' && document.fullscreenElement) {
document.exitFullscreen();
}
});
</script>
</body>
</html>