auto detect now works properly on reader

This commit is contained in:
2026-01-01 13:58:48 +01:00
parent a02db95501
commit 7fdd67316d
2 changed files with 126 additions and 72 deletions

View File

@@ -211,7 +211,7 @@ async function loadChapter() {
updateSettingsVisibility(); updateSettingsVisibility();
applyStyles(); applyStyles();
currentPages = manifest.pages; currentPages = manifest.pages;
loadManga(currentPages); await loadManga(currentPages);
return; return;
} }
if (manifest.type === 'ln') { if (manifest.type === 'ln') {
@@ -267,7 +267,7 @@ async function loadChapter() {
if (data.type === 'manga') { if (data.type === 'manga') {
currentPages = data.pages || []; currentPages = data.pages || [];
loadManga(currentPages); await loadManga(currentPages);
} else if (data.type === 'ln') { } else if (data.type === 'ln') {
loadLN(data.content); loadLN(data.content);
} }
@@ -343,7 +343,6 @@ function setupLocalNavigation(currentIndex, totalUnits) {
} }
} }
// === CAMBIO: Función helper para cambiar de capítulo ===
function changeChapter(newId) { function changeChapter(newId) {
currentChapterId = newId; currentChapterId = newId;
updateURL(newId); updateURL(newId);
@@ -351,16 +350,22 @@ function changeChapter(newId) {
loadChapter(); 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) { 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); window.history.pushState({}, '', newUrl);
} }
// --- Resto de funciones UI (Manga/LN loading) sin cambios lógicos mayores --- async function loadManga(pages) {
function loadManga(pages) {
if (!pages || pages.length === 0) { if (!pages || pages.length === 0) {
reader.innerHTML = '<div class="loading-container"><span>No pages found</span></div>'; reader.innerHTML = '<div class="loading-container"><span>No pages found</span></div>';
return; return;
@@ -369,17 +374,22 @@ function loadManga(pages) {
const container = document.createElement('div'); const container = document.createElement('div');
container.className = 'manga-container'; container.className = 'manga-container';
let isLongStrip = false; const analysis = await analyzePages(pages);
if (config.manga.mode === 'longstrip') {
isLongStrip = true;
} else if (config.manga.mode === 'auto' && detectLongStrip(pages)) {
isLongStrip = true;
}
const useDouble = config.manga.mode === 'double' || const isLongStrip =
(config.manga.mode === 'auto' && !isLongStrip && shouldUseDoublePage(pages)); 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); loadDoublePage(container, pages);
} else { } else {
loadSinglePage(container, pages); loadSinglePage(container, pages);
@@ -390,17 +400,6 @@ function loadManga(pages) {
enableMangaPageNavigation(); 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) { function loadSinglePage(container, pages) {
pages.forEach((page, index) => { pages.forEach((page, index) => {
const img = createImageElement(page, index); const img = createImageElement(page, index);
@@ -513,11 +512,41 @@ function buildProxyUrl(url, headers = {}) {
return `/api/proxy?${params.toString()}`; return `/api/proxy?${params.toString()}`;
} }
function detectLongStrip(pages) { function analyzePages(pages, sample = 6) {
if (!pages || pages.length === 0) return false; return new Promise(resolve => {
const relevant = pages.slice(1); let tall = 0;
const tall = relevant.filter(p => p.height && p.width && (p.height / p.width) > 2); let wide = 0;
return tall.length >= 2 || (tall.length / relevant.length) > 0.3; 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() { function setupLazyLoading() {
@@ -741,7 +770,6 @@ function setupProgressTracking(data, source) {
if (percent >= 0.8 && !progressSaved) { if (percent >= 0.8 && !progressSaved) {
progressSaved = true; progressSaved = true;
// Usamos el número real del capítulo, no el ID
const chapterNumber = (typeof data.number !== 'undefined' && data.number !== null) const chapterNumber = (typeof data.number !== 'undefined' && data.number !== null)
? data.number ? data.number
: 0; // Fallback si no hay numero : 0; // Fallback si no hay numero
@@ -754,7 +782,6 @@ function setupProgressTracking(data, source) {
window.addEventListener('scroll', checkProgress); window.addEventListener('scroll', checkProgress);
} }
// Inicialización
if (!bookId || !currentChapterId || !provider) { if (!bookId || !currentChapterId || !provider) {
reader.innerHTML = ` reader.innerHTML = `
<div class="loading-container"> <div class="loading-container">

View File

@@ -211,7 +211,7 @@ async function loadChapter() {
updateSettingsVisibility(); updateSettingsVisibility();
applyStyles(); applyStyles();
currentPages = manifest.pages; currentPages = manifest.pages;
loadManga(currentPages); await loadManga(currentPages);
return; return;
} }
if (manifest.type === 'ln') { if (manifest.type === 'ln') {
@@ -267,7 +267,7 @@ async function loadChapter() {
if (data.type === 'manga') { if (data.type === 'manga') {
currentPages = data.pages || []; currentPages = data.pages || [];
loadManga(currentPages); await loadManga(currentPages);
} else if (data.type === 'ln') { } else if (data.type === 'ln') {
loadLN(data.content); loadLN(data.content);
} }
@@ -343,7 +343,6 @@ function setupLocalNavigation(currentIndex, totalUnits) {
} }
} }
// === CAMBIO: Función helper para cambiar de capítulo ===
function changeChapter(newId) { function changeChapter(newId) {
currentChapterId = newId; currentChapterId = newId;
updateURL(newId); updateURL(newId);
@@ -351,16 +350,22 @@ function changeChapter(newId) {
loadChapter(); 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) { 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); window.history.pushState({}, '', newUrl);
} }
// --- Resto de funciones UI (Manga/LN loading) sin cambios lógicos mayores --- async function loadManga(pages) {
function loadManga(pages) {
if (!pages || pages.length === 0) { if (!pages || pages.length === 0) {
reader.innerHTML = '<div class="loading-container"><span>No pages found</span></div>'; reader.innerHTML = '<div class="loading-container"><span>No pages found</span></div>';
return; return;
@@ -369,17 +374,22 @@ function loadManga(pages) {
const container = document.createElement('div'); const container = document.createElement('div');
container.className = 'manga-container'; container.className = 'manga-container';
let isLongStrip = false; const analysis = await analyzePages(pages);
if (config.manga.mode === 'longstrip') {
isLongStrip = true;
} else if (config.manga.mode === 'auto' && detectLongStrip(pages)) {
isLongStrip = true;
}
const useDouble = config.manga.mode === 'double' || const isLongStrip =
(config.manga.mode === 'auto' && !isLongStrip && shouldUseDoublePage(pages)); 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); loadDoublePage(container, pages);
} else { } else {
loadSinglePage(container, pages); loadSinglePage(container, pages);
@@ -390,17 +400,6 @@ function loadManga(pages) {
enableMangaPageNavigation(); 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) { function loadSinglePage(container, pages) {
pages.forEach((page, index) => { pages.forEach((page, index) => {
const img = createImageElement(page, index); const img = createImageElement(page, index);
@@ -513,11 +512,41 @@ function buildProxyUrl(url, headers = {}) {
return `/api/proxy?${params.toString()}`; return `/api/proxy?${params.toString()}`;
} }
function detectLongStrip(pages) { function analyzePages(pages, sample = 6) {
if (!pages || pages.length === 0) return false; return new Promise(resolve => {
const relevant = pages.slice(1); let tall = 0;
const tall = relevant.filter(p => p.height && p.width && (p.height / p.width) > 2); let wide = 0;
return tall.length >= 2 || (tall.length / relevant.length) > 0.3; 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() { function setupLazyLoading() {
@@ -741,7 +770,6 @@ function setupProgressTracking(data, source) {
if (percent >= 0.8 && !progressSaved) { if (percent >= 0.8 && !progressSaved) {
progressSaved = true; progressSaved = true;
// Usamos el número real del capítulo, no el ID
const chapterNumber = (typeof data.number !== 'undefined' && data.number !== null) const chapterNumber = (typeof data.number !== 'undefined' && data.number !== null)
? data.number ? data.number
: 0; // Fallback si no hay numero : 0; // Fallback si no hay numero
@@ -754,7 +782,6 @@ function setupProgressTracking(data, source) {
window.addEventListener('scroll', checkProgress); window.addEventListener('scroll', checkProgress);
} }
// Inicialización
if (!bookId || !currentChapterId || !provider) { if (!bookId || !currentChapterId || !provider) {
reader.innerHTML = ` reader.innerHTML = `
<div class="loading-container"> <div class="loading-container">