added local manga, todo: novels

This commit is contained in:
2025-12-27 21:59:03 +01:00
parent 295cab93f3
commit d49f739565
16 changed files with 759 additions and 53 deletions

View File

@@ -0,0 +1,89 @@
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}`;
}