Recortes de paneles desde el lector, reescalados aparte, con galería y acceso directo a la página

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-31 15:38:12 -06:00
co-authored by Claude Opus 5.5
parent d48378aa49
commit 5d82a5e020
8 changed files with 466 additions and 12 deletions
+4 -1
View File
@@ -8,6 +8,7 @@ import { DatabaseSync } from 'node:sqlite'
import { writeCbz, readCbzIndex, sendCbzEntry, imageType } from './cbz.js'
import { setupFeatures } from './features.js'
import { setupUpscale } from './upscale.js'
import { setupClips } from './clips.js'
const PORT = Number(process.env.PORT || 3352)
const DATA_DIR = process.env.DATA_DIR || '/app/data'
@@ -732,6 +733,7 @@ async function route(req, res) {
const user = requireUser(req)
if ((await features.route(p, method, q, req, res, user)) !== false) return
if ((await upscale.route(p, method, req, res)) !== false) return
if (p.startsWith('/api/clips') && (await clips.route(p, method, q, req, res, user)) !== false) return
if (p === '/api/settings' && method === 'POST') {
const body = await readBody(req)
@@ -783,7 +785,7 @@ async function route(req, res) {
const reads = db.prepare('SELECT chapter_id, page, total_pages FROM chapter_reads WHERE user_id = ? AND manga_id = ?').all(user.id, m[1])
const progress = db.prepare('SELECT * FROM progress WHERE user_id = ? AND manga_id = ?').get(user.id, m[1]) ?? null
const chapterLangs = chapters.length || manga.source === 'lc' || offline ? [] : await getChapterLangs(m[1]).catch(() => [])
return json(res, 200, { manga, chapters, lang, reads, progress, chapterLangs, offline, downloaded, download: downloadInfo(m[1], true), upscale: upscale.info(m[1]), ...features.mangaExtras(user.id, manga) })
return json(res, 200, { manga, chapters, lang, reads, progress, chapterLangs, offline, downloaded, download: downloadInfo(m[1], true), upscale: upscale.info(m[1]), clips: clips.count(user.id, m[1]), ...features.mangaExtras(user.id, manga) })
}
if ((m = /^\/api\/chapter\/([^/]+)$/.exec(p)) && CHAPTER_ID.test(m[1]) && method === 'GET') {
const hdAvailable = !!upscale.hdFileOf(m[1])
@@ -881,6 +883,7 @@ async function route(req, res) {
const features = setupFeatures({ db, fetchMangaFull, enqueueDownload, downloadInfo, HttpError, json, readBody, MANGA_ID })
const upscale = setupUpscale({ db, MANGA_DIR, HttpError, json, readBody, MANGA_ID })
const clips = setupClips({ db, DATA_DIR, HttpError, json, readBody, MANGA_ID, CHAPTER_ID, upscale })
// Migración: portadas guardadas antes de firmar las URLs del proxy.
for (const row of db.prepare("SELECT user_id, manga_id, cover FROM progress WHERE cover LIKE '/api/img?u=%' AND cover NOT LIKE '%&s=%'").all()) {