let activeFilter = 'all'; let activeSort = 'az'; let isLocalMode = false; let localEntries = []; function toggleLibraryMode() { isLocalMode = !isLocalMode; const btn = document.getElementById('library-mode-btn'); const onlineContent = document.getElementById('online-content'); const localContent = document.getElementById('local-content'); const svg = btn.querySelector('svg'); const label = btn.querySelector('span'); if (isLocalMode) { // LOCAL MODE btn.classList.add('active'); onlineContent.classList.add('hidden'); localContent.classList.remove('hidden'); loadLocalEntries(); svg.innerHTML = ` `; } else { // ONLINE MODE btn.classList.remove('active'); onlineContent.classList.remove('hidden'); localContent.classList.add('hidden'); svg.innerHTML = ` `; } } async function loadLocalEntries() { const grid = document.getElementById('local-entries-grid'); grid.innerHTML = '
'.repeat(8); try { const response = await fetch('/api/library/anime'); const entries = await response.json(); localEntries = entries; if (entries.length === 0) { grid.innerHTML = '

No anime found in your local library. Click "Scan Library" to scan your folders.

'; return; } // Renderizar grid grid.innerHTML = entries.map(entry => { const title = entry.metadata?.title?.romaji || entry.metadata?.title?.english || entry.id; const cover = entry.metadata?.coverImage?.extraLarge || entry.metadata?.coverImage?.large || '/public/assets/placeholder.jpg'; const score = entry.metadata?.averageScore || '--'; const episodes = entry.metadata?.episodes || '??'; return `
${title}
${title}

${score}% • ${episodes} Eps

${entry.matched ? '● Linked' : '○ Unlinked'}
`; }).join(''); } catch (err) { console.error('Error loading local entries:', err); grid.innerHTML = '

Error loading local library. Make sure the backend is running.

'; } } async function scanLocalLibrary() { const btnText = document.getElementById('scan-text'); const originalText = btnText.innerText; btnText.innerText = "Scanning..."; try { const response = await fetch('/api/library/scan?mode=incremental', { method: 'POST' }); if (response.ok) { await loadLocalEntries(); // Mostrar notificación de éxito si tienes sistema de notificaciones if (window.NotificationUtils) { NotificationUtils.show('Library scanned successfully!', 'success'); } } else { throw new Error('Scan failed'); } } catch (err) { console.error("Scan failed", err); alert("Failed to scan library. Check console for details."); // Mostrar notificación de error si tienes sistema de notificaciones if (window.NotificationUtils) { NotificationUtils.show('Failed to scan library', 'error'); } } finally { btnText.innerText = originalText; } } function viewLocalEntry(anilistId) { if (!anilistId) { console.warn('Anime not linked'); return; } window.location.href = `/anime/${anilistId}`; } function renderLocalEntries(entries) { const grid = document.getElementById('local-entries-grid'); grid.innerHTML = entries.map(entry => { const title = entry.metadata?.title?.romaji || entry.metadata?.title?.english || entry.id; const cover = entry.metadata?.coverImage?.extraLarge || entry.metadata?.coverImage?.large || '/public/assets/placeholder.jpg'; const score = entry.metadata?.averageScore || '--'; const episodes = entry.metadata?.episodes || '??'; return `
${title}
${title}

${score}% • ${episodes} Eps

${entry.matched ? '● Linked' : '○ Unlinked'}
`; }).join(''); } function applyLocalFilters() { let filtered = [...localEntries]; if (activeFilter === 'linked') { filtered = filtered.filter(e => e.matched); } if (activeFilter === 'unlinked') { filtered = filtered.filter(e => !e.matched); } if (activeSort === 'az') { filtered.sort((a, b) => (a.metadata?.title?.romaji || a.id) .localeCompare(b.metadata?.title?.romaji || b.id) ); } if (activeSort === 'za') { filtered.sort((a, b) => (b.metadata?.title?.romaji || b.id) .localeCompare(a.metadata?.title?.romaji || a.id) ); } renderLocalEntries(filtered); } document.addEventListener('click', e => { const btn = e.target.closest('.filter-btn'); if (!btn) return; if (btn.dataset.filter) { activeFilter = btn.dataset.filter; } if (btn.dataset.sort) { activeSort = btn.dataset.sort; } btn .closest('.local-filters') .querySelectorAll('.filter-btn') .forEach(b => b.classList.remove('active')); btn.classList.add('active'); applyLocalFilters(); });