Fix page detection and add floating progress popup

 Improvements:
- Enhanced page detection to support 'X pages' pattern
- Added comprehensive logging for debugging
- Implemented floating progress popup on page
- Added show/hide progress message handlers
- Better error handling and logging for image extraction
- Fixed popup to display real-time progress

🐛 Fixed:
- Page detection now works for both 'Showing X of Y images' and 'X pages' patterns
- Downloads should now work correctly with proper page iteration
- Added visible feedback via floating popup

🔍 Debugging:
- Added console logs for page detection
- Logs show total pages found and images extracted
- Each page is logged during processing
This commit is contained in:
renato97
2025-11-04 05:05:10 +00:00
parent 8e1631b340
commit 121210ca84
2 changed files with 149 additions and 5 deletions

View File

@@ -9,6 +9,85 @@
// Map para almacenar metadatos completos de manga por ID // Map para almacenar metadatos completos de manga por ID
let mangaMetadata = new Map(); let mangaMetadata = new Map();
// Crear popup flotante de progreso
function createFloatingProgressPopup() {
// Remover popup anterior si existe
const existingPopup = document.getElementById('mass-downloader-progress-popup');
if (existingPopup) {
existingPopup.remove();
}
const popup = document.createElement('div');
popup.id = 'mass-downloader-progress-popup';
popup.style.cssText = `
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 400px;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: white;
padding: 25px;
border-radius: 12px;
box-shadow: 0 10px 40px rgba(0,0,0,0.5);
z-index: 10001;
font-family: Arial, sans-serif;
display: none;
`;
popup.innerHTML = `
<div style="text-align: center; margin-bottom: 15px;">
<h3 style="margin: 0 0 10px 0; font-size: 18px;">📦 Descargando Manga</h3>
<div id="progress-title" style="font-size: 14px; opacity: 0.9; max-height: 40px; overflow: hidden;">Preparando descarga...</div>
</div>
<div style="background: rgba(255,255,255,0.3); height: 12px; border-radius: 6px; overflow: hidden;">
<div id="progress-bar-fill" style="height: 100%; width: 0%; background: white; transition: width 0.3s ease;"></div>
</div>
<div style="display: flex; justify-content: space-between; margin-top: 8px; font-size: 13px;">
<span id="progress-count">0 / 0</span>
<span id="progress-percent">0%</span>
</div>
<div id="progress-status" style="margin-top: 10px; font-size: 12px; opacity: 0.8; text-align: center;"></div>
`;
document.body.appendChild(popup);
return popup;
}
// Actualizar progreso
function updateProgress(current, total, title, status) {
const popup = document.getElementById('mass-downloader-progress-popup') || createFloatingProgressPopup();
const percent = total > 0 ? Math.round((current / total) * 100) : 0;
const titleEl = document.getElementById('progress-title');
const countEl = document.getElementById('progress-count');
const percentEl = document.getElementById('progress-percent');
const statusEl = document.getElementById('progress-status');
const barEl = document.getElementById('progress-bar-fill');
if (titleEl) titleEl.textContent = title || 'Descargando...';
if (countEl) countEl.textContent = `${current} / ${total}`;
if (percentEl) percentEl.textContent = `${percent}%`;
if (statusEl) statusEl.textContent = status || '';
if (barEl) barEl.style.width = `${percent}%`;
popup.style.display = 'block';
}
// Ocultar progreso
function hideProgress() {
const popup = document.getElementById('mass-downloader-progress-popup');
if (popup) {
setTimeout(() => {
popup.style.opacity = '0';
popup.style.transition = 'opacity 0.5s ease';
setTimeout(() => {
popup.remove();
}, 500);
}, 1000);
}
}
// Escuchar mensajes del popup // Escuchar mensajes del popup
chrome.runtime.onMessage.addListener((request, sender, sendResponse) => { chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
if (request.action === 'getSelectedMangas') { if (request.action === 'getSelectedMangas') {
@@ -33,6 +112,12 @@
} else if (request.action === 'extractAllMangas') { } else if (request.action === 'extractAllMangas') {
const allMangas = extractAllMangasFromPage(); const allMangas = extractAllMangasFromPage();
sendResponse({ mangas: allMangas }); sendResponse({ mangas: allMangas });
} else if (request.action === 'showProgress') {
updateProgress(request.current, request.total, request.title, request.status);
sendResponse({ success: true });
} else if (request.action === 'hideProgress') {
hideProgress();
sendResponse({ success: true });
} }
return true; return true;
}); });
@@ -78,31 +163,65 @@
const parser = new DOMParser(); const parser = new DOMParser();
const doc = parser.parseFromString(html, 'text/html'); const doc = parser.parseFromString(html, 'text/html');
// Detectar páginas // Detectar páginas - Múltiples patrones
let actualTotalPages = 1; let actualTotalPages = 1;
console.log('🔍 Iniciando detección de páginas para:', manga.title);
const pageInfo = doc.querySelector('.gpc, .gt, #gdn + span'); const pageInfo = doc.querySelector('.gpc, .gt, #gdn + span');
if (pageInfo) { if (pageInfo) {
const pageText = pageInfo.textContent.trim(); const pageText = pageInfo.textContent.trim();
const pageMatch = pageText.match(/Showing\s+1\s*-\s*\d+\s+of\s+(\d+)\s+images/i); console.log('🔍 Page info encontrado:', pageText);
// Patrón 1: "Showing 1 - 20 of 220 images"
let pageMatch = pageText.match(/Showing\s+1\s*-\s*\d+\s+of\s+(\d+)\s+images/i);
if (pageMatch) { if (pageMatch) {
const totalImages = parseInt(pageMatch[1]); const totalImages = parseInt(pageMatch[1]);
actualTotalPages = Math.ceil(totalImages / 20); actualTotalPages = Math.ceil(totalImages / 20);
console.log(`✓ Patrón "Showing": ${totalImages} imágenes = ${actualTotalPages} páginas`);
} else {
// Patrón 2: "5 pages" o "X pages"
pageMatch = pageText.match(/(\d+)\s+pages?/i);
if (pageMatch) {
actualTotalPages = parseInt(pageMatch[1]);
console.log(`✓ Patrón "pages": ${actualTotalPages} páginas`);
} }
} }
}
// Fallback: Buscar en todo el documento
if (actualTotalPages === 1) {
const allText = doc.body.textContent;
const pageMatch = allText.match(/(\d+)\s+pages?/i);
if (pageMatch) {
actualTotalPages = parseInt(pageMatch[1]);
console.log(`✓ Fallback: Encontradas ${actualTotalPages} páginas en el documento`);
} else {
console.log('⚠️ No se detectaron múltiples páginas, asumiendo 1 página');
}
}
console.log(`📄 Total páginas a procesar: ${actualTotalPages}`);
// Procesar todas las páginas // Procesar todas las páginas
for (let page = 1; page <= actualTotalPages; page++) { for (let page = 1; page <= actualTotalPages; page++) {
const pageUrl = page === 1 ? baseUrl : `${baseUrl}?p=${page}`; const pageUrl = page === 1 ? baseUrl : `${baseUrl}?p=${page}`;
console.log(`📄 Procesando página ${page}/${actualTotalPages}: ${pageUrl}`);
const pageResponse = await fetch(pageUrl, { const pageResponse = await fetch(pageUrl, {
credentials: 'include' credentials: 'include'
}); });
if (!pageResponse.ok) continue; if (!pageResponse.ok) {
console.error(`❌ Error ${pageResponse.status} en página ${page}`);
continue;
}
const pageHtml = await pageResponse.text(); const pageHtml = await pageResponse.text();
const pageDoc = parser.parseFromString(pageHtml, 'text/html'); const pageDoc = parser.parseFromString(pageHtml, 'text/html');
const links = pageDoc.querySelectorAll('a[href*="/s/"]'); const links = pageDoc.querySelectorAll('a[href*="/s/"]');
console.log(`✓ Página ${page}: Encontrados ${links.length} enlaces de imagen`);
links.forEach(link => { links.forEach(link => {
const href = link.href; const href = link.href;
if (href && href.includes('/s/')) { if (href && href.includes('/s/')) {
@@ -118,6 +237,7 @@
} }
} }
console.log(`✅ Total de imágenes encontradas: ${imageUrls.length}`);
return imageUrls; return imageUrls;
} catch (error) { } catch (error) {
console.error('Error:', error); console.error('Error:', error);

View File

@@ -70,11 +70,30 @@ document.addEventListener('DOMContentLoaded', async () => {
showProgress(0, selectedMangas.length, 'Iniciando descargas...'); showProgress(0, selectedMangas.length, 'Iniciando descargas...');
// Mostrar popup flotante en la página
chrome.tabs.sendMessage(tab.id, {
action: 'showProgress',
current: 0,
total: selectedMangas.length,
title: 'Preparando...',
status: 'Iniciando descargas...'
});
try { try {
// Descargar cada manga secuencialmente // Descargar cada manga secuencialmente
for (let i = 0; i < selectedMangas.length; i++) { for (let i = 0; i < selectedMangas.length; i++) {
const manga = selectedMangas[i]; const manga = selectedMangas[i];
showProgress(i + 1, selectedMangas.length, `Descargando: ${manga.title.substring(0, 30)}...`); const title = manga.title ? manga.title.substring(0, 50) : 'Manga sin título';
showProgress(i + 1, selectedMangas.length, `Descargando: ${title}...`);
// Actualizar popup flotante
chrome.tabs.sendMessage(tab.id, {
action: 'showProgress',
current: i,
total: selectedMangas.length,
title: title,
status: `Descargando manga ${i + 1} de ${selectedMangas.length}...`
});
try { try {
// Obtener URLs de imágenes // Obtener URLs de imágenes
@@ -98,6 +117,11 @@ document.addEventListener('DOMContentLoaded', async () => {
showProgress(selectedMangas.length, selectedMangas.length, '¡Completado!'); showProgress(selectedMangas.length, selectedMangas.length, '¡Completado!');
statusElement.className = 'status success'; statusElement.className = 'status success';
// Ocultar popup flotante
chrome.tabs.sendMessage(tab.id, {
action: 'hideProgress'
});
// Limpiar selección después de 3 segundos // Limpiar selección después de 3 segundos
setTimeout(() => { setTimeout(() => {
chrome.tabs.sendMessage(tab.id, { action: 'clearSelection' }, async () => { chrome.tabs.sendMessage(tab.id, { action: 'clearSelection' }, async () => {