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'); if (isLocalMode) { btn.classList.add('active'); onlineContent.classList.add('hidden'); localContent.classList.remove('hidden'); loadLocalEntries(); } else { btn.classList.remove('active'); onlineContent.classList.remove('hidden'); localContent.classList.add('hidden'); } } async function loadLocalEntries() { const grid = document.getElementById('local-entries-grid'); grid.innerHTML = '
'.repeat(6); try { const [mangaRes, novelRes] = await Promise.all([ fetch('/api/library/manga'), fetch('/api/library/novels') ]); const [manga, novel] = await Promise.all([ mangaRes.json(), novelRes.json() ]); localEntries = [ ...manga.map(e => ({ ...e, type: 'manga' })), ...novel.map(e => ({ ...e, type: 'novel' })) ]; if (localEntries.length === 0) { grid.innerHTML = 'No books found.
'; return; } renderLocalEntries(localEntries); } catch { grid.innerHTML = 'Error loading library.
'; } } function filterLocal(type) { if (type === 'all') renderLocalEntries(localEntries); else renderLocalEntries(localEntries.filter(e => e.type === type)); } 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 || '/public/assets/placeholder.jpg'; const chapters = entry.metadata?.chapters || '??'; return `${chapters} Chapters