updated distribution

This commit is contained in:
dilgenfritz 2025-11-18 06:47:29 -06:00
parent b9de382bf7
commit ec45cf69f8
7 changed files with 624 additions and 84 deletions

View File

@ -857,12 +857,38 @@
imageLibrary = [...unifiedLibrary];
console.log(`🖼️ Using unified image library: ${imageLibrary.length} images`);
} else {
// Check for popup image library data from localStorage
const popupImageLibrary = localStorage.getItem('popupImageLibrary');
if (popupImageLibrary) {
try {
let unifiedLibrary = JSON.parse(popupImageLibrary);
// Filter by selected directories if any are selected
if (currentSettings.selectedDirectories.length > 0) {
unifiedLibrary = unifiedLibrary.filter(image => {
return currentSettings.selectedDirectories.some(selectedDir => {
const imagePath = image.path || image.fullPath || '';
const normalizedImagePath = imagePath.replace(/\\/g, '/');
const normalizedSelectedDir = selectedDir.replace(/\\/g, '/');
return normalizedImagePath.startsWith(normalizedSelectedDir);
});
});
console.log(`📁 Filtered popup library to ${unifiedLibrary.length} images from selected directories`);
}
imageLibrary = [...unifiedLibrary];
console.log(`🖼️ Using popup image library: ${imageLibrary.length} images`);
} catch (error) {
console.error('Failed to parse popup image library:', error);
}
}
}
if (imageLibrary.length === 0) {
const message = currentSettings.selectedDirectories.length > 0
? '⚠️ No images found in selected directories'
: '⚠️ Image library unavailable - Electron API not accessible';
: '⚠️ Image library unavailable - Open from Quick Play to load library';
document.getElementById('imageLibraryStatus').innerHTML =
`<span style="color: #f39c12;">${message}</span>`;
return;

View File

@ -56,8 +56,18 @@
<div class="nav-right quick-play-controls">
<button id="back-to-home" class="btn btn-secondary">🏠 Home</button>
<button id="quick-play-webcam-btn" class="btn btn-info" title="Take a photo with webcam">📸 Photo</button>
<button id="force-exit" class="btn btn-danger" title="Force close application">❌ Force Exit</button>
<button id="open-hypno-gallery" class="btn btn-gallery" title="Open Hypno Gallery in separate window">
<span class="btn-icon">🎭</span>
<span class="btn-text">Gallery</span>
</button>
<button id="open-porn-cinema" class="btn btn-cinema" title="Open Porn Cinema in separate window">
<span class="btn-icon">🎬</span>
<span class="btn-text">Cinema</span>
</button>
<button id="quick-play-webcam-btn" class="btn btn-photo" title="Take a photo with webcam">
<span class="btn-icon">📸</span>
<span class="btn-text">Photo</span>
</button>
<button id="pause-game-btn" class="btn btn-secondary" style="display: none;">⏸️ Pause</button>
</div>
</div>
@ -103,34 +113,6 @@
</div>
</div>
<!-- Audio Settings -->
<div class="setting-group">
<h3>🔊 Audio Experience</h3>
<div class="audio-settings">
<div class="audio-option">
<input type="checkbox" id="enable-background-audio" checked>
<label for="enable-background-audio">
<span class="option-icon">🎵</span>
<span class="option-text">Background Music</span>
</label>
</div>
<div class="audio-option">
<input type="checkbox" id="enable-ambient-audio" checked>
<label for="enable-ambient-audio">
<span class="option-icon">🌊</span>
<span class="option-text">Ambient Sounds</span>
</label>
</div>
<div class="audio-option">
<input type="checkbox" id="enable-voice-commands">
<label for="enable-voice-commands">
<span class="option-icon">🎤</span>
<span class="option-text">Voice Commands</span>
</label>
</div>
</div>
</div>
<!-- Video Settings -->
<div class="setting-group">
<h3>🎬 Video Experience</h3>
@ -1424,24 +1406,76 @@
// Directory handle persistence functions
async function storeDirectoryHandle(directoryHandle) {
// Modern browsers with Origin Private File System API
if ('storage' in navigator && 'persist' in navigator.storage) {
try {
const opfsRoot = await navigator.storage.getDirectory();
const handleFile = await opfsRoot.getFileHandle('webcam-directory-handle', { create: true });
const writable = await handleFile.createWritable();
await writable.write(JSON.stringify({ name: directoryHandle.name }));
await writable.close();
return 'opfs-stored';
} catch (error) {
console.log('OPFS storage failed:', error);
}
// Store in IndexedDB for more reliable persistence
try {
const request = indexedDB.open('webcamStorage', 1);
request.onupgradeneeded = (event) => {
const db = event.target.result;
if (!db.objectStoreNames.contains('directoryHandles')) {
db.createObjectStore('directoryHandles', { keyPath: 'id' });
}
};
return new Promise((resolve, reject) => {
request.onsuccess = async (event) => {
try {
const db = event.target.result;
const transaction = db.transaction(['directoryHandles'], 'readwrite');
const store = transaction.objectStore('directoryHandles');
await store.put({
id: 'webcam-directory',
handle: directoryHandle,
name: directoryHandle.name,
timestamp: Date.now()
});
resolve('indexeddb-stored');
} catch (error) {
reject(error);
}
};
request.onerror = () => reject(request.error);
});
} catch (error) {
console.log('IndexedDB storage failed:', error);
}
// Fallback - just return a reference ID
return `handle-${Date.now()}`;
}
async function retrieveDirectoryHandle(handleId) {
// Retrieve from IndexedDB
try {
const request = indexedDB.open('webcamStorage', 1);
return new Promise((resolve, reject) => {
request.onsuccess = async (event) => {
try {
const db = event.target.result;
const transaction = db.transaction(['directoryHandles'], 'readonly');
const store = transaction.objectStore('directoryHandles');
const getRequest = store.get('webcam-directory');
getRequest.onsuccess = () => {
const result = getRequest.result;
if (result && result.handle) {
resolve(result.handle);
} else {
resolve(null);
}
};
getRequest.onerror = () => resolve(null);
} catch (error) {
resolve(null);
}
};
request.onerror = () => resolve(null);
});
} catch (error) {
console.log('IndexedDB retrieval failed:', error);
return null;
}
}
async function loadStoredDirectory() {
try {
// Try to load saved directory name
@ -1450,6 +1484,21 @@
quickPlaySettings.webcamOutputDirectory = savedDirectory;
document.getElementById('webcam-output-path').value = savedDirectory;
console.log('📁 Restored recording directory:', savedDirectory);
// Try to restore directory handle if available
try {
const handleId = localStorage.getItem('webcamDirectoryHandleId');
if (handleId && typeof retrieveDirectoryHandle !== 'undefined') {
const directoryHandle = await retrieveDirectoryHandle(handleId);
if (directoryHandle) {
quickPlaySettings.webcamDirectoryHandle = directoryHandle;
console.log('📁 Restored directory handle for:', savedDirectory);
}
}
} catch (handleError) {
console.log('📁 Could not restore directory handle, will use fallback download');
}
return true;
}
} catch (error) {
@ -1490,11 +1539,6 @@
}
});
// Apply audio settings
document.getElementById('enable-background-audio').checked = quickPlaySettings.enableBackgroundAudio;
document.getElementById('enable-ambient-audio').checked = quickPlaySettings.enableAmbientAudio;
document.getElementById('enable-voice-commands').checked = quickPlaySettings.enableVoiceCommands;
// Apply video settings
document.getElementById('video-mode').value = quickPlaySettings.videoMode;
document.getElementById('enable-video-sound').checked = quickPlaySettings.enableVideoSound;
@ -1524,6 +1568,10 @@
checkbox.checked = quickPlaySettings.excludeTags.includes(checkbox.value);
});
// Apply webcam recording settings
document.getElementById('enable-session-recording').checked = quickPlaySettings.enableSessionRecording;
updateWebcamOptionsVisibility();
// Show/hide video options based on mode
updateVideoOptionsVisibility();
}
@ -2323,6 +2371,182 @@
} else {
console.warn('back-to-home button not found');
}
// Hypno Gallery button
const openHypnoGalleryBtn = document.getElementById('open-hypno-gallery');
if (openHypnoGalleryBtn) {
openHypnoGalleryBtn.addEventListener('click', async (e) => {
e.preventDefault();
console.log('Opening Hypno Gallery in separate window');
try {
// Try Electron child window first (desktop app)
if (window.electronAPI && window.electronAPI.openChildWindow) {
console.log('🖥️ Using Electron child window for Hypno Gallery');
const result = await window.electronAPI.openChildWindow({
url: 'hypno-gallery.html',
windowName: 'Hypno Gallery',
width: 1200,
height: 800
});
if (result.success) {
// Add visual feedback with animation
const originalHTML = openHypnoGalleryBtn.innerHTML;
const iconSpan = '<span class="btn-icon">👁️</span>';
const textSpan = result.action === 'focused' ? '<span class="btn-text">Focused</span>' : '<span class="btn-text">Opened</span>';
openHypnoGalleryBtn.innerHTML = iconSpan + textSpan;
openHypnoGalleryBtn.disabled = true;
openHypnoGalleryBtn.classList.add('success');
// Reset button after animation
const resetTime = result.action === 'focused' ? 2000 : 3000;
setTimeout(() => {
openHypnoGalleryBtn.innerHTML = originalHTML;
openHypnoGalleryBtn.disabled = false;
openHypnoGalleryBtn.classList.remove('success');
}, resetTime);
console.log(`✅ Hypno Gallery ${result.action === 'focused' ? 'focused' : 'opened'} successfully`);
return;
}
}
// Fallback to browser popup (web version)
console.log('🌐 Falling back to browser popup for Hypno Gallery');
// Transfer media library data to localStorage for the popup window
if (window.desktopFileManager && window.desktopFileManager.unifiedImageLibrary) {
const imageLibrary = window.desktopFileManager.unifiedImageLibrary;
localStorage.setItem('popupImageLibrary', JSON.stringify(imageLibrary));
console.log(`📁 Transferred ${imageLibrary.length} images to localStorage for popup`);
}
// Open hypno-gallery.html in a new window
const galleryWindow = window.open(
'hypno-gallery.html',
'hypno-gallery',
'width=1200,height=800,scrollbars=yes,resizable=yes,menubar=no,toolbar=no,location=no,status=no'
);
if (galleryWindow) {
// Focus the new window
galleryWindow.focus();
// Add visual feedback
const originalText = openHypnoGalleryBtn.innerHTML;
openHypnoGalleryBtn.innerHTML = '✅ Gallery Opened';
openHypnoGalleryBtn.disabled = true;
// Reset button after 3 seconds
setTimeout(() => {
openHypnoGalleryBtn.innerHTML = originalText;
openHypnoGalleryBtn.disabled = false;
}, 3000);
console.log('Hypno Gallery opened successfully');
} else {
console.error('Failed to open Hypno Gallery - popup blocked?');
alert('Could not open Hypno Gallery. Please check if popups are blocked.');
}
} catch (error) {
console.error('Error opening Hypno Gallery:', error);
alert('Failed to open Hypno Gallery. Please try again.');
}
});
} else {
console.warn('open-hypno-gallery button not found');
}
// Porn Cinema button
const openPornCinemaBtn = document.getElementById('open-porn-cinema');
if (openPornCinemaBtn) {
openPornCinemaBtn.addEventListener('click', async (e) => {
e.preventDefault();
console.log('Opening Porn Cinema in separate window');
try {
// Try Electron child window first (desktop app)
if (window.electronAPI && window.electronAPI.openChildWindow) {
console.log('🖥️ Using Electron child window for Porn Cinema');
const result = await window.electronAPI.openChildWindow({
url: 'porn-cinema.html',
windowName: 'Porn Cinema',
width: 1400,
height: 900
});
if (result.success) {
// Add visual feedback with animation
const originalHTML = openPornCinemaBtn.innerHTML;
const iconSpan = '<span class="btn-icon">👁️</span>';
const textSpan = result.action === 'focused' ? '<span class="btn-text">Focused</span>' : '<span class="btn-text">Opened</span>';
openPornCinemaBtn.innerHTML = iconSpan + textSpan;
openPornCinemaBtn.disabled = true;
openPornCinemaBtn.classList.add('success');
// Reset button after animation
const resetTime = result.action === 'focused' ? 2000 : 3000;
setTimeout(() => {
openPornCinemaBtn.innerHTML = originalHTML;
openPornCinemaBtn.disabled = false;
openPornCinemaBtn.classList.remove('success');
}, resetTime);
console.log(`✅ Porn Cinema ${result.action === 'focused' ? 'focused' : 'opened'} successfully`);
return;
}
}
// Fallback to browser popup (web version)
console.log('🌐 Falling back to browser popup for Porn Cinema');
// Transfer video library data to localStorage for the popup window
if (window.desktopFileManager && typeof window.desktopFileManager.getAllVideos === 'function') {
const videoLibrary = window.desktopFileManager.getAllVideos();
localStorage.setItem('popupVideoLibrary', JSON.stringify(videoLibrary));
console.log(`🎬 Transferred ${videoLibrary.length} videos to localStorage for popup`);
}
// Open porn-cinema.html in a new window
const cinemaWindow = window.open(
'porn-cinema.html',
'porn-cinema',
'width=1400,height=900,scrollbars=yes,resizable=yes,menubar=no,toolbar=no,location=no,status=no'
);
if (cinemaWindow) {
// Focus the new window
cinemaWindow.focus();
// Add visual feedback
const originalText = openPornCinemaBtn.innerHTML;
openPornCinemaBtn.innerHTML = '✅ Cinema Opened';
openPornCinemaBtn.disabled = true;
// Reset button after 3 seconds
setTimeout(() => {
openPornCinemaBtn.innerHTML = originalText;
openPornCinemaBtn.disabled = false;
}, 3000);
console.log('Porn Cinema opened successfully');
} else {
console.error('Failed to open Porn Cinema - popup blocked?');
alert('Could not open Porn Cinema. Please check if popups are blocked.');
}
} catch (error) {
console.error('Error opening Porn Cinema:', error);
alert('Failed to open Porn Cinema. Please try again.');
}
});
} else {
console.warn('open-porn-cinema button not found');
}
const backToHomeResultsBtn = document.getElementById('back-to-home-results');
if (backToHomeResultsBtn) {
@ -2335,25 +2559,44 @@
// Force exit button
const forceExitBtn = document.getElementById('force-exit');
if (forceExitBtn) {
forceExitBtn.addEventListener('click', (e) => {
e.preventDefault();
console.log('Force exit button clicked');
if (confirm('⚠️ Force close the application? This will close the entire window.')) {
forceExit();
}
});
}
// Webcam photo button
const webcamBtn = document.getElementById('quick-play-webcam-btn');
if (webcamBtn) {
webcamBtn.addEventListener('click', (e) => {
webcamBtn.addEventListener('click', async (e) => {
e.preventDefault();
console.log('Webcam photo button clicked');
openQuickPlayWebcam();
// Add visual feedback with animation
const originalHTML = webcamBtn.innerHTML;
const iconSpan = '<span class="btn-icon">📷</span>';
const textSpan = '<span class="btn-text">Opening</span>';
webcamBtn.innerHTML = iconSpan + textSpan;
webcamBtn.disabled = true;
webcamBtn.classList.add('success');
try {
await openQuickPlayWebcam();
// Show success state briefly
webcamBtn.innerHTML = '<span class="btn-icon"></span><span class="btn-text">Opened</span>';
setTimeout(() => {
webcamBtn.innerHTML = originalHTML;
webcamBtn.disabled = false;
webcamBtn.classList.remove('success');
}, 2000);
} catch (error) {
console.error('Webcam error:', error);
webcamBtn.innerHTML = '<span class="btn-icon"></span><span class="btn-text">Error</span>';
setTimeout(() => {
webcamBtn.innerHTML = originalHTML;
webcamBtn.disabled = false;
webcamBtn.classList.remove('success');
}, 2000);
}
});
}
@ -2450,16 +2693,7 @@
});
});
// Audio checkboxes
document.getElementById('enable-background-audio').addEventListener('change', (e) => {
quickPlaySettings.enableBackgroundAudio = e.target.checked;
});
document.getElementById('enable-ambient-audio').addEventListener('change', (e) => {
quickPlaySettings.enableAmbientAudio = e.target.checked;
});
document.getElementById('enable-voice-commands').addEventListener('change', (e) => {
quickPlaySettings.enableVoiceCommands = e.target.checked;
});
// Audio controls removed
// Video settings
document.getElementById('video-mode').addEventListener('change', (e) => {
@ -2480,6 +2714,10 @@
document.getElementById('enable-session-recording').addEventListener('change', (e) => {
quickPlaySettings.enableSessionRecording = e.target.checked;
updateWebcamOptionsVisibility();
// Save settings immediately when recording preference changes
localStorage.setItem('quickPlaySettings', JSON.stringify(quickPlaySettings));
console.log('💾 Recording preference saved:', e.target.checked);
});
document.getElementById('select-webcam-directory').addEventListener('click', async () => {
try {
@ -2510,6 +2748,10 @@
document.getElementById('webcam-output-path').value = directoryPath;
console.log('📁 Webcam output directory selected and saved:', directoryPath);
// Save the complete settings to ensure directory persists
localStorage.setItem('quickPlaySettings', JSON.stringify(quickPlaySettings));
console.log('💾 Settings saved with new directory');
if (window.flashMessageManager) {
window.flashMessageManager.show(`📁 Recording directory set to: ${directoryPath}`, 'positive');
}
@ -3252,11 +3494,6 @@
// Initialize flash message system
initializeFlashMessages();
// Trigger welcome message
setTimeout(() => {
triggerEventFlashMessage('gameStart');
}, 3000); // Show after 3 seconds
// Start timer
startGameTimer(config.timeLimit);
@ -5182,6 +5419,19 @@
document.addEventListener('keydown', (e) => {
if (e.target.tagName === 'INPUT') return; // Don't interfere with input fields
// Ctrl+Shift+F to focus main window
if (e.ctrlKey && e.shiftKey && e.key === 'F') {
e.preventDefault();
if (window.electronAPI && window.electronAPI.focusMainWindow) {
window.electronAPI.focusMainWindow().then(result => {
if (result.success) {
console.log('🎯 Main window focused via keyboard shortcut');
}
});
}
return;
}
switch (e.key) {
case 'Escape':
if (isGameRunning) {
@ -10229,13 +10479,114 @@
display: none !important;
}
/* Show webcam task overlay when recording */
/* Hide webcam task overlay from preview (it will still be rendered on recording canvas) */
.webcam-viewer.recording .webcam-task-overlay {
display: block !important;
display: none !important;
}
</style>
<!-- Floating Webcam Viewer -->
/* Enhanced Gallery, Cinema, and Photo Button Styles */
.btn-gallery, .btn-cinema, .btn-photo {
position: relative;
display: inline-flex;
align-items: center;
justify-content: center;
padding: 8px 16px;
border: none;
border-radius: 8px;
font-weight: 600;
font-size: 14px;
cursor: pointer;
transition: all 0.3s ease;
text-decoration: none;
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
overflow: hidden;
}
.btn-gallery {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: white;
}
.btn-cinema {
background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%);
color: white;
}
.btn-photo {
background: linear-gradient(135deg, #2c3e50 0%, #34495e 100%);
color: white;
}
.btn-gallery:hover {
transform: translateY(-2px);
box-shadow: 0 4px 12px rgba(102, 126, 234, 0.4);
background: linear-gradient(135deg, #5a6fd8 0%, #6a4190 100%);
}
.btn-cinema:hover {
transform: translateY(-2px);
box-shadow: 0 4px 12px rgba(245, 87, 108, 0.4);
background: linear-gradient(135deg, #e081e9 0%, #e3455a 100%);
}
.btn-photo:hover {
transform: translateY(-2px);
box-shadow: 0 4px 12px rgba(52, 73, 94, 0.4);
background: linear-gradient(135deg, #1a252f 0%, #2c3e50 100%);
}
.btn-gallery:active, .btn-cinema:active, .btn-photo:active {
transform: translateY(0);
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
}
.btn-gallery:disabled, .btn-cinema:disabled, .btn-photo:disabled {
opacity: 0.6;
cursor: not-allowed;
transform: none;
}
.btn-icon {
font-size: 16px;
margin-right: 6px;
display: inline-block;
}
.btn-text {
font-size: 13px;
font-weight: 600;
letter-spacing: 0.5px;
}
/* Animation for button feedback */
.btn-gallery.success, .btn-cinema.success, .btn-photo.success {
animation: successPulse 0.6s ease-out;
}
@keyframes successPulse {
0% { transform: scale(1); }
50% { transform: scale(1.05); }
100% { transform: scale(1); }
}
/* Responsive adjustments */
@media (max-width: 768px) {
.btn-gallery, .btn-cinema, .btn-photo {
padding: 6px 12px;
font-size: 12px;
}
.btn-icon {
font-size: 14px;
margin-right: 4px;
}
.btn-text {
font-size: 11px;
}
}
</style> <!-- Floating Webcam Viewer -->
<div id="webcam-viewer" class="webcam-viewer">
<div class="recording-indicator">● REC</div>
<video id="webcam-preview" autoplay muted></video>

View File

@ -114,6 +114,116 @@ async function createWindow() {
}
}
// Register all IPC handlers before app is ready
function registerIpcHandlers() {
console.log('📝 Registering all IPC handlers...');
// Move the child window handler here for early registration
// Child window management
let childWindows = new Map();
console.log('📝 Registering open-child-window IPC handler...');
ipcMain.handle('open-child-window', async (event, options) => {
console.log('🖥️ Child window requested:', options);
try {
const { url, windowName, width = 1200, height = 800 } = options;
// Check if window already exists and focus it instead of creating a new one
if (childWindows.has(windowName)) {
const existingWindow = childWindows.get(windowName);
if (!existingWindow.isDestroyed()) {
console.log(`Focusing existing window: ${windowName}`);
existingWindow.focus();
return { success: true, windowName, action: 'focused' };
} else {
// Window was destroyed, remove from map
childWindows.delete(windowName);
}
}
// Create new child window
const childWindow = new BrowserWindow({
width,
height,
// Remove parent relationship to prevent focus issues
modal: false,
resizable: true,
minimizable: true,
maximizable: true,
webPreferences: {
nodeIntegration: false,
contextIsolation: true,
enableRemoteModule: false,
webSecurity: false,
preload: path.join(__dirname, 'preload.js'),
allowRunningInsecureContent: true,
experimentalFeatures: true
},
show: true, // Show immediately instead of waiting
title: `${windowName} - Gooner Training Academy`
});
// Load the URL - construct full path
const fullPath = path.join(__dirname, '..', '..', url);
console.log(`Loading child window file: ${fullPath}`);
try {
await childWindow.loadFile(fullPath);
console.log(`✅ Successfully loaded: ${fullPath}`);
childWindow.focus();
} catch (loadError) {
console.error(`❌ Failed to load file: ${fullPath}`, loadError);
// Try to show the window anyway with an error message
childWindow.show();
childWindow.focus();
}
// Handle window closed
childWindow.on('closed', () => {
console.log(`Child window closed: ${windowName}`);
childWindows.delete(windowName);
});
// Add error handling
childWindow.on('unresponsive', () => {
console.warn(`Child window unresponsive: ${windowName}`);
});
childWindow.webContents.on('did-fail-load', (event, errorCode, errorDescription, validatedURL) => {
console.error(`Child window failed to load: ${windowName}`, {
errorCode,
errorDescription,
validatedURL
});
});
// Store reference
childWindows.set(windowName, childWindow);
console.log(`✅ Created and showing child window: ${windowName} (${url})`);
return { success: true, windowName, action: 'created' };
} catch (error) {
console.error('Error creating child window:', error);
return { success: false, error: error.message };
}
});
}
// Add main window focus handler
ipcMain.handle('focus-main-window', async () => {
if (mainWindow && !mainWindow.isDestroyed()) {
mainWindow.show();
mainWindow.focus();
mainWindow.moveTop();
return { success: true };
}
return { success: false };
});
// Register IPC handlers
registerIpcHandlers();
app.whenReady().then(createWindow);
app.on('window-all-closed', () => {

View File

@ -31,6 +31,10 @@ contextBridge.exposeInMainWorld('electronAPI', {
// Platform info
platform: process.platform,
// Child window management
openChildWindow: (options) => ipcRenderer.invoke('open-child-window', options),
focusMainWindow: () => ipcRenderer.invoke('focus-main-window'),
// Version info
versions: {
node: process.versions.node,

View File

@ -65,7 +65,46 @@ class VideoLibrary {
async loadVideoLibrary() {
try {
// First try to get from unified video library (new system)
// First check for popup video library data (for windows opened from Quick Play)
const popupVideoLibrary = localStorage.getItem('popupVideoLibrary');
if (popupVideoLibrary) {
console.log('📁 Loading from popup video library...');
const popupVideos = JSON.parse(popupVideoLibrary);
if (popupVideos && popupVideos.length > 0) {
console.log(`📁 Loading from popup video library: ${popupVideos.length} videos`);
// Convert popup library format to VideoLibrary format
const allVideos = popupVideos.map(video => ({
name: video.name,
path: video.path,
size: video.size || 0,
duration: video.duration || 0,
thumbnail: video.thumbnail || null,
resolution: video.resolution || 'Unknown',
format: video.format || this.getFormatFromPath(video.path),
bitrate: video.bitrate || 0,
dateAdded: video.dateAdded || new Date().toISOString(),
category: video.source === 'individual' ? 'individual' : 'directory',
directory: video.directory || video.source || 'Unknown'
}));
this.videos = allVideos;
console.log(`📁 Popup video library loaded: ${this.videos.length} videos`);
if (this.videos.length === 0) {
this.displayEmptyLibrary('No videos found. Open from Quick Play to load video library!');
return;
}
// Apply filters and sort before displaying
this.applyFiltersAndSort();
this.displayLibrary();
return;
}
}
// Then try to get from unified video library (new system)
const unifiedLibrary = JSON.parse(localStorage.getItem('unifiedVideoLibrary') || '{}');
if (unifiedLibrary.allVideos && unifiedLibrary.allVideos.length > 0) {
console.log(`📁 Loading from unified video library: ${unifiedLibrary.allVideos.length} videos`);
@ -98,6 +137,8 @@ class VideoLibrary {
return;
}
// Apply filters and sort before displaying
this.applyFiltersAndSort();
this.displayLibrary();
return;
}
@ -359,7 +400,15 @@ class VideoLibrary {
}
displayLibrary() {
console.log(`📁 DisplayLibrary called - Videos: ${this.videos.length}, Filtered: ${this.filteredVideos.length}`);
if (this.filteredVideos.length === 0) {
console.log('📁 No filtered videos - applying filter to refresh');
this.applyFiltersAndSort(); // Make sure filtering is applied
}
if (this.filteredVideos.length === 0) {
console.log('📁 Still no filtered videos after applying filter');
this.displayEmptyLibrary('No videos match your search');
return;
}

View File

@ -489,7 +489,7 @@ class DesktopFileManager {
await this.updateUnifiedVideoStorage();
const totalVideos = this.allLinkedVideos.length;
this.showNotification(`🔄 Refreshed ${this.externalVideoDirectories.length} directories, found ${totalVideos} videos`, 'success');
// Removed notification to avoid startup message clutter
}
async saveLinkedDirectories() {