89 lines
3.4 KiB
JavaScript
89 lines
3.4 KiB
JavaScript
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 = '<div class="skeleton-card"></div>'.repeat(6);
|
|
|
|
try {
|
|
// Cambiado a endpoint de libros
|
|
const response = await fetch('/api/library/manga');
|
|
const entries = await response.json();
|
|
localEntries = entries;
|
|
|
|
if (entries.length === 0) {
|
|
grid.innerHTML = '<p style="grid-column: 1/-1; text-align: center; color: var(--color-text-secondary); padding: 3rem;">No books found in your local library.</p>';
|
|
return;
|
|
}
|
|
renderLocalEntries(entries);
|
|
} catch (err) {
|
|
grid.innerHTML = '<p style="grid-column: 1/-1; text-align: center; color: var(--color-danger); padding: 3rem;">Error loading local books.</p>';
|
|
}
|
|
}
|
|
|
|
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 `
|
|
<div class="local-card" onclick="viewLocalEntry(${entry.metadata?.id || 'null'})">
|
|
<div class="card-img-wrap">
|
|
<img src="${cover}" alt="${title}" loading="lazy">
|
|
</div>
|
|
<div class="local-card-info">
|
|
<div class="local-card-title">${title}</div>
|
|
<p style="font-size: 0.85rem; color: var(--color-text-secondary); margin: 0;">
|
|
${chapters} Chapters
|
|
</p>
|
|
<div class="match-status ${entry.matched ? 'status-linked' : 'status-unlinked'}">
|
|
${entry.matched ? '● Linked' : '○ Unlinked'}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
`;
|
|
}).join('');
|
|
}
|
|
|
|
async function scanLocalLibrary() {
|
|
const btnText = document.getElementById('scan-text');
|
|
btnText.innerText = "Scanning...";
|
|
try {
|
|
// Asumiendo que el scan de libros usa este query param
|
|
const response = await fetch('/api/library/scan?mode=incremental', { method: 'POST' });
|
|
if (response.ok) {
|
|
await loadLocalEntries();
|
|
if (window.NotificationUtils) NotificationUtils.show('Library scanned!', 'success');
|
|
}
|
|
} catch (err) {
|
|
if (window.NotificationUtils) NotificationUtils.show('Scan failed', 'error');
|
|
} finally {
|
|
btnText.innerText = "Scan Library";
|
|
}
|
|
}
|
|
|
|
function viewLocalEntry(id) {
|
|
if (id) window.location.href = `/book/${id}`;
|
|
} |