diff --git a/desktop/src/scripts/books/reader.js b/desktop/src/scripts/books/reader.js index fb636eb..3ba5707 100644 --- a/desktop/src/scripts/books/reader.js +++ b/desktop/src/scripts/books/reader.js @@ -211,7 +211,7 @@ async function loadChapter() { updateSettingsVisibility(); applyStyles(); currentPages = manifest.pages; - loadManga(currentPages); + await loadManga(currentPages); return; } if (manifest.type === 'ln') { @@ -267,7 +267,7 @@ async function loadChapter() { if (data.type === 'manga') { currentPages = data.pages || []; - loadManga(currentPages); + await loadManga(currentPages); } else if (data.type === 'ln') { loadLN(data.content); } @@ -343,7 +343,6 @@ function setupLocalNavigation(currentIndex, totalUnits) { } } -// === CAMBIO: Función helper para cambiar de capítulo === function changeChapter(newId) { currentChapterId = newId; updateURL(newId); @@ -351,16 +350,22 @@ function changeChapter(newId) { loadChapter(); } +function loadLongStrip(container, pages) { + pages.forEach((page, index) => { + const img = createImageElement(page, index); + img.classList.remove('fit-width', 'fit-height', 'fit-screen'); + + img.classList.add('longstrip-fit'); + container.appendChild(img); + }); +} + function updateURL(newId) { - // La URL ahora contiene el ID en lugar del número/índice - const newUrl = - `/read/${provider}/${newId}/${bookId}?source=${source}&lang=${lang}`; + const newUrl = `/read/${provider}/${newId}/${bookId}?source=${source}&lang=${lang}`; window.history.pushState({}, '', newUrl); } -// --- Resto de funciones UI (Manga/LN loading) sin cambios lógicos mayores --- - -function loadManga(pages) { +async function loadManga(pages) { if (!pages || pages.length === 0) { reader.innerHTML = '
No pages found
'; return; @@ -369,17 +374,22 @@ function loadManga(pages) { const container = document.createElement('div'); container.className = 'manga-container'; - let isLongStrip = false; - if (config.manga.mode === 'longstrip') { - isLongStrip = true; - } else if (config.manga.mode === 'auto' && detectLongStrip(pages)) { - isLongStrip = true; - } + const analysis = await analyzePages(pages); - const useDouble = config.manga.mode === 'double' || - (config.manga.mode === 'auto' && !isLongStrip && shouldUseDoublePage(pages)); + const isLongStrip = + config.manga.mode === 'longstrip' || + (config.manga.mode === 'auto' && analysis.tallRatio > 0.3); - if (useDouble) { + const useDouble = + !isLongStrip && + ( + config.manga.mode === 'double' || + (config.manga.mode === 'auto' && analysis.wideRatio < 0.3) + ); + + if (isLongStrip) { + loadLongStrip(container, pages); + } else if (useDouble) { loadDoublePage(container, pages); } else { loadSinglePage(container, pages); @@ -390,17 +400,6 @@ function loadManga(pages) { enableMangaPageNavigation(); } -function shouldUseDoublePage(pages) { - if (pages.length <= 5) return false; - const widePages = pages.filter(p => { - if (!p.height || !p.width) return false; - const ratio = p.width / p.height; - return ratio > 1.3; - }); - if (widePages.length > pages.length * 0.3) return false; - return true; -} - function loadSinglePage(container, pages) { pages.forEach((page, index) => { const img = createImageElement(page, index); @@ -513,11 +512,41 @@ function buildProxyUrl(url, headers = {}) { return `/api/proxy?${params.toString()}`; } -function detectLongStrip(pages) { - if (!pages || pages.length === 0) return false; - const relevant = pages.slice(1); - const tall = relevant.filter(p => p.height && p.width && (p.height / p.width) > 2); - return tall.length >= 2 || (tall.length / relevant.length) > 0.3; +function analyzePages(pages, sample = 6) { + return new Promise(resolve => { + let tall = 0; + let wide = 0; + let loaded = 0; + + const count = Math.min(sample, pages.length); + + for (let i = 0; i < count; i++) { + const img = new Image(); + img.src = provider === 'local' + ? pages[i].url + : buildProxyUrl(pages[i].url, pages[i].headers); + + img.onload = () => { + const ratio = img.naturalWidth / img.naturalHeight; + if (ratio < 0.6) tall++; + else if (ratio > 1.3) wide++; + loaded++; + if (loaded === count) finish(); + }; + + img.onerror = () => { + loaded++; + if (loaded === count) finish(); + }; + } + + function finish() { + resolve({ + tallRatio: tall / count, + wideRatio: wide / count + }); + } + }); } function setupLazyLoading() { @@ -741,7 +770,6 @@ function setupProgressTracking(data, source) { if (percent >= 0.8 && !progressSaved) { progressSaved = true; - // Usamos el número real del capítulo, no el ID const chapterNumber = (typeof data.number !== 'undefined' && data.number !== null) ? data.number : 0; // Fallback si no hay numero @@ -754,7 +782,6 @@ function setupProgressTracking(data, source) { window.addEventListener('scroll', checkProgress); } -// Inicialización if (!bookId || !currentChapterId || !provider) { reader.innerHTML = `
diff --git a/docker/src/scripts/books/reader.js b/docker/src/scripts/books/reader.js index fb636eb..3ba5707 100644 --- a/docker/src/scripts/books/reader.js +++ b/docker/src/scripts/books/reader.js @@ -211,7 +211,7 @@ async function loadChapter() { updateSettingsVisibility(); applyStyles(); currentPages = manifest.pages; - loadManga(currentPages); + await loadManga(currentPages); return; } if (manifest.type === 'ln') { @@ -267,7 +267,7 @@ async function loadChapter() { if (data.type === 'manga') { currentPages = data.pages || []; - loadManga(currentPages); + await loadManga(currentPages); } else if (data.type === 'ln') { loadLN(data.content); } @@ -343,7 +343,6 @@ function setupLocalNavigation(currentIndex, totalUnits) { } } -// === CAMBIO: Función helper para cambiar de capítulo === function changeChapter(newId) { currentChapterId = newId; updateURL(newId); @@ -351,16 +350,22 @@ function changeChapter(newId) { loadChapter(); } +function loadLongStrip(container, pages) { + pages.forEach((page, index) => { + const img = createImageElement(page, index); + img.classList.remove('fit-width', 'fit-height', 'fit-screen'); + + img.classList.add('longstrip-fit'); + container.appendChild(img); + }); +} + function updateURL(newId) { - // La URL ahora contiene el ID en lugar del número/índice - const newUrl = - `/read/${provider}/${newId}/${bookId}?source=${source}&lang=${lang}`; + const newUrl = `/read/${provider}/${newId}/${bookId}?source=${source}&lang=${lang}`; window.history.pushState({}, '', newUrl); } -// --- Resto de funciones UI (Manga/LN loading) sin cambios lógicos mayores --- - -function loadManga(pages) { +async function loadManga(pages) { if (!pages || pages.length === 0) { reader.innerHTML = '
No pages found
'; return; @@ -369,17 +374,22 @@ function loadManga(pages) { const container = document.createElement('div'); container.className = 'manga-container'; - let isLongStrip = false; - if (config.manga.mode === 'longstrip') { - isLongStrip = true; - } else if (config.manga.mode === 'auto' && detectLongStrip(pages)) { - isLongStrip = true; - } + const analysis = await analyzePages(pages); - const useDouble = config.manga.mode === 'double' || - (config.manga.mode === 'auto' && !isLongStrip && shouldUseDoublePage(pages)); + const isLongStrip = + config.manga.mode === 'longstrip' || + (config.manga.mode === 'auto' && analysis.tallRatio > 0.3); - if (useDouble) { + const useDouble = + !isLongStrip && + ( + config.manga.mode === 'double' || + (config.manga.mode === 'auto' && analysis.wideRatio < 0.3) + ); + + if (isLongStrip) { + loadLongStrip(container, pages); + } else if (useDouble) { loadDoublePage(container, pages); } else { loadSinglePage(container, pages); @@ -390,17 +400,6 @@ function loadManga(pages) { enableMangaPageNavigation(); } -function shouldUseDoublePage(pages) { - if (pages.length <= 5) return false; - const widePages = pages.filter(p => { - if (!p.height || !p.width) return false; - const ratio = p.width / p.height; - return ratio > 1.3; - }); - if (widePages.length > pages.length * 0.3) return false; - return true; -} - function loadSinglePage(container, pages) { pages.forEach((page, index) => { const img = createImageElement(page, index); @@ -513,11 +512,41 @@ function buildProxyUrl(url, headers = {}) { return `/api/proxy?${params.toString()}`; } -function detectLongStrip(pages) { - if (!pages || pages.length === 0) return false; - const relevant = pages.slice(1); - const tall = relevant.filter(p => p.height && p.width && (p.height / p.width) > 2); - return tall.length >= 2 || (tall.length / relevant.length) > 0.3; +function analyzePages(pages, sample = 6) { + return new Promise(resolve => { + let tall = 0; + let wide = 0; + let loaded = 0; + + const count = Math.min(sample, pages.length); + + for (let i = 0; i < count; i++) { + const img = new Image(); + img.src = provider === 'local' + ? pages[i].url + : buildProxyUrl(pages[i].url, pages[i].headers); + + img.onload = () => { + const ratio = img.naturalWidth / img.naturalHeight; + if (ratio < 0.6) tall++; + else if (ratio > 1.3) wide++; + loaded++; + if (loaded === count) finish(); + }; + + img.onerror = () => { + loaded++; + if (loaded === count) finish(); + }; + } + + function finish() { + resolve({ + tallRatio: tall / count, + wideRatio: wide / count + }); + } + }); } function setupLazyLoading() { @@ -741,7 +770,6 @@ function setupProgressTracking(data, source) { if (percent >= 0.8 && !progressSaved) { progressSaved = true; - // Usamos el número real del capítulo, no el ID const chapterNumber = (typeof data.number !== 'undefined' && data.number !== null) ? data.number : 0; // Fallback si no hay numero @@ -754,7 +782,6 @@ function setupProgressTracking(data, source) { window.addEventListener('scroll', checkProgress); } -// Inicialización if (!bookId || !currentChapterId || !provider) { reader.innerHTML = `