training-academy/porn-cinema.html

925 lines
44 KiB
HTML
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="Content-Security-Policy" content="default-src 'self' 'unsafe-inline' 'unsafe-eval' data: file: blob: http://localhost:* https:; connect-src 'self' http://localhost:* https: ws://localhost:*; img-src 'self' data: file: blob:; media-src 'self' data: file: blob:; script-src 'self' 'unsafe-inline' 'unsafe-eval' https:;">
<title>Porn Cinema - Gooner Training Academy</title>
<link rel="stylesheet" href="src/styles/color-variables.css">
<link rel="stylesheet" href="src/styles/styles.css">
<link rel="stylesheet" href="src/styles/base-video-player.css">
<link rel="stylesheet" href="src/styles/porn-cinema.css">
<link href="https://fonts.googleapis.com/css2?family=Audiowide&display=swap" rel="stylesheet">
<script src="src/utils/themeManager.js"></script>
</head>
<body class="cinema-mode">
<!-- Cinema Header -->
<header class="cinema-header">
<div class="cinema-nav">
<h1>🎬 Porn Cinema</h1>
<div class="cinema-controls">
<!-- Theme Switcher -->
<div id="theme-switcher-container"></div>
<button id="back-to-home" class="btn btn-secondary">🏠 Home</button>
<button id="settings-btn" class="btn btn-secondary">⚙️ Settings</button>
<button id="theater-mode" class="btn btn-secondary">🎭 Theater</button>
<button id="fullscreen-toggle" class="btn btn-secondary">⛶ Fullscreen</button>
</div>
</div>
</header>
<!-- Keyboard Shortcuts Help -->
<div class="shortcuts-help" id="shortcuts-help">
<div class="shortcuts-content">
<h3>🎹 One-Handed Controls</h3>
<div class="shortcuts-grid">
<div class="shortcut-item"><kbd>Space</kbd> Play/Pause</div>
<div class="shortcut-item"><kbd></kbd><kbd></kbd> Seek ±10s</div>
<div class="shortcut-item"><kbd></kbd><kbd></kbd> Volume ±10%</div>
<div class="shortcut-item"><kbd>F</kbd> Fullscreen</div>
<div class="shortcut-item"><kbd>T</kbd> Theater Mode</div>
<div class="shortcut-item"><kbd>M</kbd> Mute/Unmute</div>
<div class="shortcut-item"><kbd>1-4</kbd> Quality</div>
<div class="shortcut-item"><kbd>Enter</kbd> Add to Playlist</div>
<div class="shortcut-item"><kbd>N</kbd> Next Video</div>
<div class="shortcut-item"><kbd>P</kbd> Previous Video</div>
<div class="shortcut-item"><kbd>S</kbd> Shuffle Playlist</div>
<div class="shortcut-item"><kbd>Escape</kbd> Exit Theater/Fullscreen</div>
<div class="shortcut-item"><kbd>?</kbd> Toggle This Help</div>
</div>
</div>
</div>
<!-- Loading Overlay -->
<div id="cinema-loading" class="cinema-loading">
<div class="loading-content">
<div class="loading-spinner"></div>
<h2>Loading Cinema...</h2>
<p>Preparing your video library...</p>
</div>
</div>
<!-- Main Cinema Content -->
<main class="cinema-main">
<!-- Main Content Area -->
<div class="main-content-area">
<!-- Video Player Section -->
<section class="video-player-section">
<div class="video-container" id="video-container">
<video id="main-video-player" class="main-video" preload="metadata">
<source id="video-source" src="" type="video/mp4">
Your browser does not support the video tag.
</video>
<!-- Video Overlay Controls -->
<div class="video-overlay" id="video-overlay">
<div class="video-title" id="video-title">Select a video to begin</div>
<div class="video-info" id="video-info"></div>
<!-- Play Button Overlay -->
<div class="play-overlay" id="play-overlay">
<button class="play-button-large" id="play-button-large"></button>
</div>
<!-- Loading Spinner -->
<div class="video-loading" id="video-loading" style="display: none;">
<div class="loading-spinner"></div>
<p>Loading video...</p>
</div>
</div>
<!-- Custom Video Controls -->
<div class="video-controls" id="video-controls">
<div class="progress-container">
<div class="progress-bar" id="progress-bar">
<div class="progress-filled" id="progress-filled"></div>
<div class="progress-thumb" id="progress-thumb"></div>
</div>
<div class="time-display">
<span id="current-time">0:00</span>
<span class="time-separator">/</span>
<span id="total-time">0:00</span>
</div>
</div>
<div class="controls-row">
<div class="controls-left">
<button id="play-pause-btn" class="control-btn"></button>
<button id="prev-video-btn" class="control-btn" title="Previous Video (P)"></button>
<button id="next-video-btn" class="control-btn" title="Next Video (N)"></button>
<div class="volume-control">
<button id="mute-btn" class="control-btn" title="Mute (M)">🔊</button>
<input type="range" id="volume-slider" class="volume-slider" min="0" max="100" value="70">
<span id="volume-percentage">70%</span>
</div>
</div>
<div class="controls-center">
<div class="quality-selector">
<select id="quality-select" class="quality-dropdown">
<option value="auto">Auto Quality</option>
<option value="1080p">1080p (1)</option>
<option value="720p">720p (2)</option>
<option value="480p">480p (3)</option>
<option value="360p">360p (4)</option>
</select>
</div>
<div class="speed-control">
<select id="speed-select" class="speed-dropdown">
<option value="0.5">0.5x</option>
<option value="0.75">0.75x</option>
<option value="1" selected>1x</option>
<option value="1.25">1.25x</option>
<option value="1.5">1.5x</option>
<option value="2">2x</option>
</select>
</div>
</div>
<div class="controls-right">
<button id="add-to-playlist-btn" class="control-btn" title="Add to Playlist (Enter)"></button>
<button id="theater-mode-btn" class="control-btn" title="Theater Mode">🎭</button>
<button id="fullscreen-btn" class="control-btn" title="Fullscreen (F)"></button>
</div>
</div>
</div>
</div>
</section>
<!-- Video Library Section -->
<section class="video-library-section">
<div class="library-header">
<h3><EFBFBD> Video Library</h3>
<div class="library-controls">
<div class="view-toggle">
<button id="grid-view-btn" class="view-btn active" title="Grid View"></button>
<button id="list-view-btn" class="view-btn" title="List View"></button>
</div>
<div class="playlist-management">
<button id="create-playlist-btn" class="btn btn-mini" title="Create New Playlist">📝 New Playlist</button>
<button id="select-mode-btn" class="btn btn-mini" title="Select Multiple Videos">☑️ Select</button>
</div>
<div class="sort-controls">
<select id="sort-select" class="sort-dropdown">
<option value="name">Sort by Name</option>
<option value="date">Sort by Date</option>
<option value="duration">Sort by Duration</option>
<option value="size">Sort by Size</option>
</select>
<button id="sort-direction" class="btn btn-mini" title="Sort Direction">↕️</button>
</div>
<div class="search-controls">
<input type="text" id="library-search" class="search-input" placeholder="Search videos...">
<button id="refresh-library" class="btn btn-mini" title="Refresh Library">🔄</button>
</div>
</div>
</div>
<div class="library-content" id="library-content">
<div class="library-loading">
<div class="loading-spinner"></div>
<p>Loading video library...</p>
</div>
</div>
</section>
</div>
<!-- Right Sidebar -->
<aside class="cinema-sidebar">
<!-- Sidebar Tabs -->
<div class="sidebar-tabs">
<button class="sidebar-tab active" id="playlist-tab">🎵 Playlist</button>
<button class="sidebar-tab" id="search-tab">🔍 Search</button>
</div>
<!-- Playlist Panel -->
<div class="sidebar-panel active" id="playlist-panel">
<div class="panel-header">
<h3>Current Playlist</h3>
<div class="playlist-controls">
<button id="repeat-mode-btn" class="btn btn-mini" title="Repeat: Off">🔁</button>
<button id="shuffle-playlist" class="btn btn-mini" title="Shuffle (S)">🔀</button>
<button id="clear-playlist" class="btn btn-mini btn-danger">🗑️</button>
<button id="save-playlist" class="btn btn-mini">💾</button>
<button id="load-playlist" class="btn btn-mini">📁</button>
</div>
</div>
<div class="playlist-content" id="playlist-content">
<div class="playlist-empty">
<p>Playlist is empty. Add videos by clicking or pressing Enter while a video is selected.</p>
</div>
</div>
</div>
<!-- Search Panel -->
<div class="sidebar-panel" id="search-panel">
<div class="panel-header">
<h3>Search Videos</h3>
</div>
<div class="search-content">
<input type="text" class="search-input-sidebar" placeholder="Search your library...">
<div class="search-results" id="search-results">
<p>Enter search terms to find videos...</p>
</div>
</div>
</div>
</aside>
</main>
<!-- Scripts -->
<script src="src/data/gameDataManager.js"></script>
<script src="src/utils/desktop-file-manager.js"></script>
<script src="src/features/stats/playerStats.js"></script>
<script src="src/features/media/baseVideoPlayer.js"></script>
<script src="src/features/media/videoLibrary.js"></script>
<script src="src/features/media/pornCinema.js"></script>
<script>
// Initialize cinema when page loads
document.addEventListener('DOMContentLoaded', async function() {
try {
console.log('🎬 Initializing Porn Cinema...');
// Initialize theme switcher UI
if (window.themeManager) {
const themeSwitcher = window.themeManager.createThemeToggle();
const container = document.getElementById('theme-switcher-container');
if (container) {
container.appendChild(themeSwitcher);
console.log('✅ Theme switcher initialized');
}
}
// Initialize desktop file manager if in Electron environment
if (window.electronAPI) {
// Try to reuse existing desktop file manager from parent window first
if (window.opener && window.opener.game && window.opener.game.fileManager) {
console.log('🔗 Reusing desktop file manager from main window');
window.desktopFileManager = window.opener.game.fileManager;
} else {
console.log('🆕 Creating new desktop file manager instance');
// Create a data manager wrapper that matches the real DataManager behavior
// This ensures linked directories are stored in the same place across all pages
const minimalDataManager = {
data: null,
storageKey: 'webGame-data',
loadData() {
try {
const stored = localStorage.getItem(this.storageKey);
if (stored) {
this.data = JSON.parse(stored);
} else {
this.data = {};
}
} catch (e) {
console.error('Error loading data:', e);
this.data = {};
}
},
saveData() {
try {
if (!this.data) this.data = {};
this.data.timestamp = Date.now();
localStorage.setItem(this.storageKey, JSON.stringify(this.data));
} catch (e) {
console.error('Error saving data:', e);
}
},
get(key) {
if (!this.data) this.loadData();
return this.data[key];
},
set(key, value) {
if (!this.data) this.loadData();
this.data[key] = value;
this.saveData();
}
};
// Load data initially
minimalDataManager.loadData();
window.desktopFileManager = new DesktopFileManager(minimalDataManager);
await window.desktopFileManager.init();
}
console.log('🖥️ Desktop File Manager initialized for porn cinema');
// Wait for the desktop file manager to fully initialize
// This includes loading linked directories and video files
let retries = 0;
const maxRetries = 50; // Wait up to 5 seconds
while (retries < maxRetries) {
// Check if initialization is complete by verifying video directories are set up
if (window.desktopFileManager.videoDirectories &&
window.desktopFileManager.videoDirectories.background) {
console.log('✅ Desktop file manager video directories are ready');
break;
}
// Waiting for desktop file manager to initialize...
await new Promise(resolve => setTimeout(resolve, 100));
retries++;
}
if (retries >= maxRetries) {
console.warn('⚠️ Desktop file manager took too long to initialize');
}
// Force refresh of linked directories to ensure we have the latest video data
try {
// If we're reusing the main window's file manager, don't reload/refresh
if (window.opener && window.opener.game && window.opener.game.fileManager) {
console.log('📁 Using directories from main window file manager');
} else {
// Only reload and refresh if we created a new instance
await window.desktopFileManager.loadLinkedDirectories();
}
} catch (error) {
console.warn('⚠️ Error refreshing directories:', error);
}
} else if (!window.electronAPI) {
console.warn('⚠️ Running in browser mode - video management limited');
}
// Initialize the cinema after desktop file manager is ready
window.pornCinema = new PornCinema();
await window.pornCinema.initialize();
// Hide loading overlay
setTimeout(() => {
const loadingOverlay = document.getElementById('cinema-loading');
if (loadingOverlay) {
loadingOverlay.style.display = 'none';
}
}, 1000);
} catch (error) {
console.error('❌ Critical error initializing Porn Cinema:', error);
// Show error to user
const loadingOverlay = document.getElementById('cinema-loading');
if (loadingOverlay) {
loadingOverlay.innerHTML = `
<div class="loading-content">
<h2 style="color: #ff4444;">⚠️ Error Loading Cinema</h2>
<p>${error.message || 'Unknown error occurred'}</p>
<p style="font-size: 0.9em; opacity: 0.7;">Check console for details</p>
<button onclick="location.reload()" class="btn btn-primary" style="margin-top: 20px;">
🔄 Retry
</button>
<button onclick="location.href='index.html'" class="btn btn-secondary" style="margin-top: 10px;">
🏠 Return Home
</button>
</div>
`;
}
}
});
// Back to home functionality
document.getElementById('back-to-home').addEventListener('click', () => {
showExitConfirmationDialog();
});
// Cleanup on window close to prevent memory leaks
window.addEventListener('beforeunload', () => {
if (window.pornCinema && typeof window.pornCinema.destroy === 'function') {
window.pornCinema.destroy();
}
});
// Cleanup when navigating away
window.addEventListener('pagehide', () => {
if (window.pornCinema && typeof window.pornCinema.destroy === 'function') {
window.pornCinema.destroy();
}
});
function getSassyTheaterAttendantDialog() {
// Array of sassy theater attendant responses
const sassyResponses = [
{
avatar: '🎭',
title: 'Leaving Already?',
message: 'Oh honey, the show was just getting good! Are you sure you want to walk out now?',
snarkIcon: '🍿',
snark: 'I mean, I guess not everyone has the stamina for a full feature presentation...',
exitIcon: '🚶‍♀️',
exitText: 'Leave Theater',
stayIcon: '🎬',
stayText: 'Keep Watching'
},
{
avatar: '💅',
title: 'Really? Right Now?',
message: 'Sweetie, you\'re about to miss the best part! The climax is coming up...',
snarkIcon: '🎪',
snark: 'But sure, go ahead and leave during the most exciting scene. Your loss!',
exitIcon: '🚶‍♀️',
exitText: 'Leave Theater',
stayIcon: '🎬',
stayText: 'Keep Watching'
},
{
avatar: '😏',
title: 'Intermission Over?',
message: 'Darling, this isn\'t a bathroom break - you\'re actually leaving? How disappointing...',
snarkIcon: '🎭',
snark: 'I thought you had better taste in entertainment. Guess I was wrong.',
exitIcon: '🚶‍♀️',
exitText: 'Leave Theater',
stayIcon: '🎬',
stayText: 'Keep Watching'
},
{
avatar: '🎪',
title: 'Show\'s Not Over!',
message: 'Excuse me? The feature presentation is still running! You can\'t just leave mid-scene!',
snarkIcon: '🎬',
snark: 'This is like walking out of the theater during the finale. Absolutely scandalous!',
exitIcon: '🚶‍♀️',
exitText: 'Leave Theater',
stayIcon: '🎬',
stayText: 'Keep Watching'
},
{
avatar: '💄',
title: 'Attention Deficit?',
message: 'Oh sweetie, can\'t focus for more than five minutes? The good stuff requires patience...',
snarkIcon: '⏰',
snark: 'Real connoisseurs know that the best performances build up slowly to an explosive finish.',
exitIcon: '🚶‍♀️',
exitText: 'Leave Theater',
stayIcon: '🎬',
stayText: 'Keep Watching'
},
{
avatar: '🎬',
title: 'Intermission Confusion?',
message: 'Hun, this isn\'t the lobby! You\'re in the middle of premium content here!',
snarkIcon: '🍾',
snark: 'Some people pay extra for this level of entertainment, and you\'re just... walking away?',
exitIcon: '🚶‍♀️',
exitText: 'Leave Theater',
stayIcon: '🎬',
stayText: 'Keep Watching'
}
];
// Return a random sassy response
return sassyResponses[Math.floor(Math.random() * sassyResponses.length)];
}
function showExitConfirmationDialog() {
// Get sassy theater attendant content
const attendantDialog = getSassyTheaterAttendantDialog();
// Create modal dialog
const modal = document.createElement('div');
modal.className = 'confirmation-modal cinema-attendant-modal';
modal.innerHTML = `
<div class="confirmation-modal-content">
<div class="confirmation-modal-header cinema-attendant-header">
<div class="attendant-avatar">${attendantDialog.avatar}</div>
<h3>${attendantDialog.title}</h3>
</div>
<div class="confirmation-modal-body cinema-attendant-body">
<p class="attendant-main-message">${attendantDialog.message}</p>
<div class="attendant-snark">
<span class="snark-icon">${attendantDialog.snarkIcon}</span>
<span class="snark-text">${attendantDialog.snark}</span>
</div>
</div>
<div class="confirmation-modal-actions">
<button class="btn-confirm-exit cinema-exit-btn">
<span class="btn-icon">${attendantDialog.exitIcon}</span>
<span>${attendantDialog.exitText}</span>
</button>
<button class="btn-cancel-exit cinema-stay-btn">
<span class="btn-icon">${attendantDialog.stayIcon}</span>
<span>${attendantDialog.stayText}</span>
</button>
</div>
</div>
`;
// Add enhanced modal styles for theater attendant
modal.innerHTML += `
<style>
.cinema-attendant-modal {
position: fixed;
top: 0;
left: 0;
width: 100vw;
height: 100vh;
background: rgba(0, 0, 0, 0.85);
display: flex;
align-items: center;
justify-content: center;
z-index: 10003;
backdrop-filter: blur(8px);
animation: fadeIn 0.4s ease-out;
}
.cinema-attendant-modal .confirmation-modal-content {
background: linear-gradient(145deg, #1a0d2e, #2d1b3d);
border: 3px solid #ff6b35;
border-radius: 20px;
padding: 2.5rem;
max-width: 500px;
width: 90%;
box-shadow: 0 25px 50px rgba(255, 107, 53, 0.3), 0 0 30px rgba(255, 107, 53, 0.2);
animation: modalBounceIn 0.5s ease-out;
text-align: center;
position: relative;
overflow: hidden;
}
.cinema-attendant-modal .confirmation-modal-content::before {
content: '';
position: absolute;
top: 0;
left: -100%;
width: 100%;
height: 100%;
background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.1), transparent);
animation: shimmer 3s infinite;
}
.cinema-attendant-header {
margin-bottom: 2rem;
position: relative;
z-index: 1;
}
.attendant-avatar {
font-size: 4rem;
margin-bottom: 0.5rem;
filter: drop-shadow(0 0 15px rgba(255, 107, 53, 0.6));
animation: pulse 2s infinite;
}
.cinema-attendant-header h3 {
color: #ff6b35;
font-size: 1.8rem;
font-weight: 700;
margin: 0;
text-shadow: 0 0 15px rgba(255, 107, 53, 0.4);
font-family: 'Audiowide', cursive;
}
.cinema-attendant-body {
margin-bottom: 2.5rem;
position: relative;
z-index: 1;
}
.attendant-main-message {
color: #f0f0f0;
font-size: 1.2rem;
margin-bottom: 1.5rem;
line-height: 1.6;
font-style: italic;
}
.attendant-snark {
background: linear-gradient(135deg, rgba(255, 107, 53, 0.15), rgba(255, 193, 7, 0.1));
border: 1px solid rgba(255, 107, 53, 0.4);
border-radius: 15px;
padding: 1rem;
display: flex;
align-items: center;
gap: 0.75rem;
font-size: 1rem;
color: #ffab91;
}
.snark-icon {
font-size: 1.3rem;
filter: drop-shadow(0 0 8px rgba(255, 107, 53, 0.5));
}
.snark-text {
flex: 1;
font-style: italic;
}
.cinema-attendant-modal .confirmation-modal-actions {
display: flex;
gap: 1.5rem;
justify-content: center;
position: relative;
z-index: 1;
}
.cinema-attendant-modal .confirmation-modal-actions button {
background: linear-gradient(135deg, #2d1b3d, #1a0d2e);
border: 2px solid;
border-radius: 15px;
padding: 1rem 1.5rem;
color: white;
font-size: 1.1rem;
font-weight: 600;
cursor: pointer;
display: flex;
align-items: center;
gap: 0.5rem;
transition: all 0.3s ease;
min-width: 160px;
justify-content: center;
font-family: 'Audiowide', cursive;
}
.cinema-exit-btn {
border-color: #ff6b35 !important;
box-shadow: 0 0 20px rgba(255, 107, 53, 0.3);
}
.cinema-exit-btn:hover {
background: linear-gradient(135deg, #ff6b35, #ff5722) !important;
transform: translateY(-3px);
box-shadow: 0 8px 25px rgba(255, 107, 53, 0.5);
}
.cinema-stay-btn {
border-color: #4caf50 !important;
box-shadow: 0 0 20px rgba(76, 175, 80, 0.3);
}
.cinema-stay-btn:hover {
background: linear-gradient(135deg, #4caf50, #388e3c) !important;
transform: translateY(-3px);
box-shadow: 0 8px 25px rgba(76, 175, 80, 0.5);
}
.btn-icon {
font-size: 1.2rem;
filter: drop-shadow(0 0 8px currentColor);
}
@keyframes modalBounceIn {
0% {
transform: scale(0.3) translateY(-100px);
opacity: 0;
}
50% {
transform: scale(1.1) translateY(0);
}
100% {
transform: scale(1) translateY(0);
opacity: 1;
}
}
@keyframes pulse {
0%, 100% { transform: scale(1); }
50% { transform: scale(1.1); }
}
@keyframes shimmer {
0% { left: -100%; }
100% { left: 100%; }
}
@keyframes fadeIn {
from { opacity: 0; }
to { opacity: 1; }
}
@keyframes fadeOut {
from { opacity: 1; }
to { opacity: 0; }
}
</style>
`;
modal.style.cssText = ``;
document.body.appendChild(modal);
// Setup event handlers
const confirmBtn = modal.querySelector('.btn-confirm-exit');
const cancelBtn = modal.querySelector('.btn-cancel-exit');
const closeModal = () => {
modal.style.animation = 'fadeOut 0.3s ease-in';
setTimeout(() => {
if (modal.parentNode) {
document.body.removeChild(modal);
}
}, 300);
};
confirmBtn.addEventListener('click', () => {
window.location.href = 'index.html';
});
cancelBtn.addEventListener('click', closeModal);
// Close on escape key
const escapeHandler = (e) => {
if (e.key === 'Escape') {
closeModal();
document.removeEventListener('keydown', escapeHandler);
}
};
document.addEventListener('keydown', escapeHandler);
// Click outside to close
modal.addEventListener('click', (e) => {
if (e.target === modal) {
closeModal();
}
});
// Focus on cancel button by default
setTimeout(() => {
cancelBtn.focus();
}, 100);
}
// Theater mode functionality
let theaterModeActive = false;
let headerHideTimeout = null;
let escapeHintTimeout = null;
function createTheaterModeElements() {
// Create header hover zone for theater mode
const hoverZone = document.createElement('div');
hoverZone.className = 'header-hover-zone';
hoverZone.id = 'header-hover-zone';
document.body.appendChild(hoverZone);
// Create escape hint
const escapeHint = document.createElement('div');
escapeHint.className = 'theater-escape-hint';
escapeHint.id = 'theater-escape-hint';
escapeHint.innerHTML = 'Press <kbd>T</kbd> or <kbd>Esc</kbd> to exit theater mode';
document.body.appendChild(escapeHint);
}
function setupTheaterMouseTracking() {
const header = document.querySelector('.cinema-header');
const hoverZone = document.getElementById('header-hover-zone');
const escapeHint = document.getElementById('theater-escape-hint');
if (!hoverZone || !header) return;
// Show header when mouse enters hover zone
hoverZone.addEventListener('mouseenter', () => {
if (theaterModeActive) {
header.classList.remove('auto-hide');
header.classList.add('show-on-hover');
clearTimeout(headerHideTimeout);
}
});
// Hide header when mouse leaves hover zone
hoverZone.addEventListener('mouseleave', () => {
if (theaterModeActive) {
headerHideTimeout = setTimeout(() => {
header.classList.remove('show-on-hover');
header.classList.add('auto-hide');
}, 2000);
}
});
// Auto-hide escape hint after 5 seconds
if (escapeHint) {
escapeHintTimeout = setTimeout(() => {
escapeHint.classList.add('fade-out');
}, 5000);
}
}
function toggleTheaterMode() {
theaterModeActive = !theaterModeActive;
const body = document.body;
const sidebar = document.querySelector('.cinema-sidebar');
const librarySection = document.querySelector('.video-library-section');
const mainContentArea = document.querySelector('.main-content-area');
const cinemaMain = document.querySelector('.cinema-main');
const theaterBtn = document.getElementById('theater-mode');
const theaterBtnControl = document.getElementById('theater-mode-btn');
const header = document.querySelector('.cinema-header');
const escapeHint = document.getElementById('theater-escape-hint');
if (theaterModeActive) {
// Enter theater mode
body.classList.add('theater-mode-active');
sidebar.style.display = 'none';
librarySection.style.display = 'none';
cinemaMain.style.gridTemplateColumns = '1fr';
mainContentArea.style.padding = '0';
// Create theater mode elements if they don't exist
if (!document.getElementById('header-hover-zone')) {
createTheaterModeElements();
}
// Setup mouse tracking for header auto-hide
setupTheaterMouseTracking();
// Initially hide header after 3 seconds
headerHideTimeout = setTimeout(() => {
if (header) {
header.classList.add('auto-hide');
}
}, 3000);
// Update button text
if (theaterBtn) theaterBtn.innerHTML = '🎭 Exit Theater';
if (theaterBtnControl) theaterBtnControl.innerHTML = '🎭';
console.log('🎭 Theater mode activated - Video player fills entire window');
} else {
// Exit theater mode
body.classList.remove('theater-mode-active');
sidebar.style.display = 'flex';
librarySection.style.display = 'block';
cinemaMain.style.gridTemplateColumns = '1fr 320px';
mainContentArea.style.padding = '20px';
// Clean up theater mode elements
clearTimeout(headerHideTimeout);
clearTimeout(escapeHintTimeout);
if (header) {
header.classList.remove('auto-hide', 'show-on-hover');
}
if (escapeHint) {
escapeHint.classList.remove('fade-out');
}
// Update button text
if (theaterBtn) theaterBtn.innerHTML = '🎭 Theater';
if (theaterBtnControl) theaterBtnControl.innerHTML = '🎭';
console.log('🎭 Theater mode deactivated - Normal layout restored');
}
}
// Theater mode button event listeners
const theaterModeBtn = document.getElementById('theater-mode');
const theaterModeBtnControl = document.getElementById('theater-mode-btn');
if (theaterModeBtn) {
theaterModeBtn.addEventListener('click', toggleTheaterMode);
}
if (theaterModeBtnControl) {
theaterModeBtnControl.addEventListener('click', toggleTheaterMode);
}
// Keyboard shortcut to toggle help
document.addEventListener('keydown', (e) => {
if (e.key === '?' || (e.shiftKey && e.key === '/')) {
const help = document.getElementById('shortcuts-help');
help.style.display = help.style.display === 'none' ? 'block' : 'none';
}
// Theater mode keyboard shortcuts
if (e.key.toLowerCase() === 't' && !e.ctrlKey && !e.altKey && !e.shiftKey) {
// Only toggle if not typing in an input field
if (!['INPUT', 'TEXTAREA'].includes(e.target.tagName)) {
toggleTheaterMode();
e.preventDefault();
}
}
// Escape key to exit theater mode
if (e.key === 'Escape' && theaterModeActive) {
toggleTheaterMode();
e.preventDefault();
}
});
// Sidebar tab functionality
document.getElementById('playlist-tab').addEventListener('click', () => {
// Remove active from all tabs and panels
document.querySelectorAll('.sidebar-tab').forEach(tab => tab.classList.remove('active'));
document.querySelectorAll('.sidebar-panel').forEach(panel => panel.classList.remove('active'));
// Activate playlist tab and panel
document.getElementById('playlist-tab').classList.add('active');
document.getElementById('playlist-panel').classList.add('active');
});
document.getElementById('search-tab').addEventListener('click', () => {
// Remove active from all tabs and panels
document.querySelectorAll('.sidebar-tab').forEach(tab => tab.classList.remove('active'));
document.querySelectorAll('.sidebar-panel').forEach(panel => panel.classList.remove('active'));
// Activate search tab and panel
document.getElementById('search-tab').classList.add('active');
document.getElementById('search-panel').classList.add('active');
});
</script>
</body>
</html>