Portadas HD de lo seguido o leído; sección Colas con descargas, reescalado y biblioteca en tarjetas
- Portadas: se reescalan (×4/×2) solo las de mangas en historial o seguidos; caché en data/covers/. - Colas (antes Descargas): cola de descargas y de reescalado HD con progreso, tiempo restante, reintentar/detener, recortes y portadas pendientes; biblioteca descargada en tarjetas verticales. - Refresco de Colas sin parpadeo: solo se actualiza lo que cambia. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
+27
-1
@@ -175,6 +175,32 @@ export function setupUpscale({ db, MANGA_DIR, HttpError, json, readBody, MANGA_I
|
||||
}
|
||||
}
|
||||
|
||||
// Cola global (página "Colas"): por manga, en el orden en que se procesan.
|
||||
function queue() {
|
||||
const rows = db.prepare(`SELECT j.chapter_id, j.manga_id, j.status, j.error, j.created_at, c.num, c.pages, d.title
|
||||
FROM upscale_jobs j JOIN downloaded_chapters c ON c.chapter_id = j.chapter_id JOIN downloads d ON d.manga_id = j.manga_id
|
||||
ORDER BY j.created_at, j.rowid`).all()
|
||||
const groups = new Map()
|
||||
for (const r of rows) {
|
||||
let g = groups.get(r.manga_id)
|
||||
if (!g) groups.set(r.manga_id, g = { mangaId: r.manga_id, title: r.title, queued: 0, pages: 0, errors: [], next: [] })
|
||||
if (r.status === 'error') g.errors.push({ chapterId: r.chapter_id, num: r.num, error: r.error })
|
||||
else {
|
||||
g.queued++
|
||||
g.pages += r.pages || 0
|
||||
if (g.next.length < 5 && r.chapter_id !== current?.chapterId) g.next.push(r.num)
|
||||
}
|
||||
}
|
||||
const cur = current && { mangaId: current.mangaId, chapterId: current.chapterId, num: current.num, pages: current.pages, total: current.total }
|
||||
// Páginas que faltan (la del capítulo en curso cuenta solo lo que le queda).
|
||||
for (const g of groups.values()) {
|
||||
if (cur?.mangaId === g.mangaId) g.pages = Math.max(0, g.pages - (rows.find(r => r.chapter_id === cur.chapterId)?.pages || 0) + (cur.total - cur.pages))
|
||||
g.eta = Math.round(g.pages * secPerPage)
|
||||
}
|
||||
const list = [...groups.values()].sort((a, b) => (b.mangaId === cur?.mangaId) - (a.mangaId === cur?.mangaId))
|
||||
return { available: available(), current: cur, groups: list, secPerPage: Math.round(secPerPage * 10) / 10, eta: list.reduce((n, g) => n + g.eta, 0) }
|
||||
}
|
||||
|
||||
// Llamado al terminar de descargar un capítulo: si el manga está marcado como HD, encolarlo.
|
||||
function onChapterDownloaded(mangaId, chapterId) {
|
||||
if (db.prepare('SELECT hd_auto FROM downloads WHERE manga_id = ?').get(mangaId)?.hd_auto) enqueue([chapterId])
|
||||
@@ -224,5 +250,5 @@ export function setupUpscale({ db, MANGA_DIR, HttpError, json, readBody, MANGA_I
|
||||
|
||||
if (!fs.existsSync(BIN)) console.log('HD: Real-ESRGAN no instalado, reescalado desactivado')
|
||||
else if (!fs.existsSync('/dev/dri')) console.log('HD: sin /dev/dri en el contenedor, reescalado desactivado')
|
||||
return { info, hdFileOf, onChapterDownloaded, cancel, route, pump, available }
|
||||
return { info, hdFileOf, onChapterDownloaded, cancel, route, pump, available, queue }
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user