From 121210ca841608742af9157aa40dbf8d888dce4a Mon Sep 17 00:00:00 2001 From: renato97 Date: Tue, 4 Nov 2025 05:05:10 +0000 Subject: [PATCH] Fix page detection and add floating progress popup MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ✨ 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 --- content.js | 128 +++++++++++++++++++++++++++++++++++++++++++++++++++-- popup.js | 26 ++++++++++- 2 files changed, 149 insertions(+), 5 deletions(-) diff --git a/content.js b/content.js index c9d6ac3..170ea3a 100644 --- a/content.js +++ b/content.js @@ -9,6 +9,85 @@ // Map para almacenar metadatos completos de manga por ID 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 = ` +
+

📦 Descargando Manga

+
Preparando descarga...
+
+
+
+
+
+ 0 / 0 + 0% +
+
+ `; + + 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 chrome.runtime.onMessage.addListener((request, sender, sendResponse) => { if (request.action === 'getSelectedMangas') { @@ -33,6 +112,12 @@ } else if (request.action === 'extractAllMangas') { const allMangas = extractAllMangasFromPage(); 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; }); @@ -78,31 +163,65 @@ const parser = new DOMParser(); const doc = parser.parseFromString(html, 'text/html'); - // Detectar páginas + // Detectar páginas - Múltiples patrones let actualTotalPages = 1; + console.log('🔍 Iniciando detección de páginas para:', manga.title); + const pageInfo = doc.querySelector('.gpc, .gt, #gdn + span'); + if (pageInfo) { 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) { const totalImages = parseInt(pageMatch[1]); 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`); + } } } - // Procesar todas las 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 for (let page = 1; page <= actualTotalPages; page++) { const pageUrl = page === 1 ? baseUrl : `${baseUrl}?p=${page}`; + console.log(`📄 Procesando página ${page}/${actualTotalPages}: ${pageUrl}`); + const pageResponse = await fetch(pageUrl, { 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 pageDoc = parser.parseFromString(pageHtml, 'text/html'); const links = pageDoc.querySelectorAll('a[href*="/s/"]'); + console.log(`✓ Página ${page}: Encontrados ${links.length} enlaces de imagen`); links.forEach(link => { const href = link.href; if (href && href.includes('/s/')) { @@ -118,6 +237,7 @@ } } + console.log(`✅ Total de imágenes encontradas: ${imageUrls.length}`); return imageUrls; } catch (error) { console.error('Error:', error); diff --git a/popup.js b/popup.js index 3282c40..57730a4 100644 --- a/popup.js +++ b/popup.js @@ -70,11 +70,30 @@ document.addEventListener('DOMContentLoaded', async () => { 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 { // Descargar cada manga secuencialmente for (let i = 0; i < selectedMangas.length; 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 { // Obtener URLs de imágenes @@ -98,6 +117,11 @@ document.addEventListener('DOMContentLoaded', async () => { showProgress(selectedMangas.length, selectedMangas.length, '¡Completado!'); statusElement.className = 'status success'; + // Ocultar popup flotante + chrome.tabs.sendMessage(tab.id, { + action: 'hideProgress' + }); + // Limpiar selección después de 3 segundos setTimeout(() => { chrome.tabs.sendMessage(tab.id, { action: 'clearSelection' }, async () => {