const downloadsMap = new Map(); // downloadId -> { tabId, filename } chrome.runtime.onMessage.addListener((msg, sender, sendResponse) => { if (!msg || !msg.action) { sendResponse({ status: "unknown" }); return; } if (msg.action === "videoProgressCompleted") { console.log('Video completed:', msg.videoId, 'name:', msg.name); sendResponse({ status: "success" }); return; } if (msg.action === "startBackgroundDownload") { const url = msg.url; let filename = msg.filename || ('download_' + Date.now()); if (!url) { sendResponse({ status: "error", message: "No URL provided" }); return; } try { chrome.downloads.download( { url: url, filename: filename, conflictAction: "uniquify", saveAs: false }, downloadId => { if (chrome.runtime.lastError) { console.error('chrome.downloads.download error:', chrome.runtime.lastError.message); sendResponse({ status: "error", message: chrome.runtime.lastError.message }); } else { const tabId = (sender && sender.tab && sender.tab.id) ? sender.tab.id : null; downloadsMap.set(downloadId, { tabId, filename }); sendResponse({ status: "started", downloadId }); } } ); return true; } catch (e) { console.error('Exception starting download', e); sendResponse({ status: "error", message: String(e) }); return; } } sendResponse({ status: "ok" }); }); // Listen for download changes and forward progress/state to the tab chrome.downloads.onChanged.addListener(delta => { const info = downloadsMap.get(delta.id); if (!info || !info.tabId) return; if (delta.bytesReceived) { chrome.downloads.search({ id: delta.id }, items => { const item = items && items[0]; if (!item) return; const received = item.bytesReceived || 0; const total = item.totalBytes || 0; const percent = total > 0 ? Math.round(100 * received / total) : null; chrome.tabs.sendMessage(info.tabId, { action: 'downloadProgress', downloadId: delta.id, bytesReceived: received, totalBytes: total, percent }, () => { /* ignore response */ }); }); } if (delta.state && delta.state.current === 'complete') { chrome.tabs.sendMessage(info.tabId, { action: 'downloadComplete', downloadId: delta.id, filename: info.filename }, () => { /* ignore response */ }); downloadsMap.delete(delta.id); } if (delta.state && delta.state.current === 'interrupted') { chrome.tabs.sendMessage(info.tabId, { action: 'downloadFailed', downloadId: delta.id, filename: info.filename, reason: delta.state && delta.state.current }, () => { /* ignore response */ }); downloadsMap.delete(delta.id); } });