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:
128
content.js
128
content.js
@@ -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`);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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++) {
|
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);
|
||||||
|
|||||||
26
popup.js
26
popup.js
@@ -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 () => {
|
||||||
|
|||||||
Reference in New Issue
Block a user