Spaces:
Sleeping
Sleeping
| /** | |
| * ============================================ | |
| * Download Handler | |
| * - Download novels as English .txt | |
| * - Download novels as Hindi .txt (Google Translate) | |
| * - Show download info | |
| * ============================================ | |
| */ | |
| // ============================================ | |
| // Download Novel β English | |
| // ============================================ | |
| async function downloadNovel(novelId) { | |
| try { | |
| const info = await apiCall(`/api/download/${novelId}/info`); | |
| if (!info.downloadable) { | |
| showToast('No chapters to download yet!', 'warning'); | |
| return; | |
| } | |
| const confirmed = confirm( | |
| `Download "${info.title}" in ENGLISH?\n\n` + | |
| `π Chapters: ${info.chapter_count}\n` + | |
| `π Words: ${info.word_count.toLocaleString()}\n` + | |
| `π Estimated Pages: ~${info.estimated_pages}\n\n` + | |
| `Click OK to download as .txt file.` | |
| ); | |
| if (!confirmed) return; | |
| showToast(`π₯ Preparing English download...`, 'info', 3000); | |
| const link = document.createElement('a'); | |
| link.href = `${API_BASE}/api/download/${novelId}/txt`; | |
| link.download = ''; | |
| link.style.display = 'none'; | |
| document.body.appendChild(link); | |
| link.click(); | |
| document.body.removeChild(link); | |
| showToast(`β English download started for "${info.title}"!`, 'success'); | |
| } catch (error) { | |
| showToast(`Download failed: ${error.message}`, 'error'); | |
| } | |
| } | |
| // ============================================ | |
| // Download Novel β Hindi (Google Translate) | |
| // ============================================ | |
| async function downloadNovelHindi(novelId) { | |
| try { | |
| const info = await apiCall(`/api/download/${novelId}/info`); | |
| if (!info.downloadable) { | |
| showToast('No chapters to download yet!', 'warning'); | |
| return; | |
| } | |
| const confirmed = confirm( | |
| `Download "${info.title}" in HINDI?\n\n` + | |
| `π Chapters: ${info.chapter_count}\n` + | |
| `π Words: ${info.word_count.toLocaleString()}\n\n` + | |
| `β³ Note: Translation takes some time.\n` + | |
| `Zyada chapters honge toh thoda wait karo!\n\n` + | |
| `Click OK to start Hindi translation + download.` | |
| ); | |
| if (!confirmed) return; | |
| showToast(`π Hindi translation shuru ho rahi hai... Thoda wait karo!`, 'info', 10000); | |
| // Hindi download β server side translates everything | |
| const link = document.createElement('a'); | |
| link.href = `${API_BASE}/api/download/${novelId}/txt-hindi`; | |
| link.download = ''; | |
| link.style.display = 'none'; | |
| document.body.appendChild(link); | |
| link.click(); | |
| document.body.removeChild(link); | |
| showToast(`β Hindi download started for "${info.title}"!`, 'success'); | |
| } catch (error) { | |
| showToast(`Hindi download failed: ${error.message}`, 'error'); | |
| } | |
| } | |
| // ============================================ | |
| // View Chapters List | |
| // ============================================ | |
| async function viewChapters(novelId) { | |
| try { | |
| const data = await apiCall(`/api/download/${novelId}/chapters`); | |
| let html = `<h3>${escapeHtml(data.title)} - ${data.total_chapters} Chapters</h3>\n`; | |
| html += '<div style="max-height:400px;overflow-y:auto;margin-top:12px;">'; | |
| for (const ch of data.chapters) { | |
| html += `<div style="padding:8px;border-bottom:1px solid var(--border-color);font-size:0.85rem;">`; | |
| html += `<strong>Ch ${ch.number}:</strong> ${escapeHtml(ch.title)} `; | |
| html += `<span style="color:var(--text-muted);">(${ch.word_count} words)</span>`; | |
| html += `</div>`; | |
| } | |
| html += '</div>'; | |
| showModal(html); | |
| } catch (error) { | |
| showToast(`Failed to load chapters: ${error.message}`, 'error'); | |
| } | |
| } | |
| // ============================================ | |
| // Simple Modal | |
| // ============================================ | |
| function showModal(content) { | |
| const existing = document.getElementById('simpleModal'); | |
| if (existing) existing.remove(); | |
| const modal = document.createElement('div'); | |
| modal.id = 'simpleModal'; | |
| modal.style.cssText = ` | |
| position: fixed; top: 0; left: 0; right: 0; bottom: 0; | |
| background: rgba(0,0,0,0.7); z-index: 2000; | |
| display: flex; justify-content: center; align-items: center; | |
| padding: 24px; | |
| `; | |
| modal.innerHTML = ` | |
| <div style="background: var(--bg-card); border: 1px solid var(--border-color); | |
| border-radius: 12px; padding: 24px; max-width: 700px; width: 100%; | |
| max-height: 80vh; overflow-y: auto; position: relative;"> | |
| <button onclick="document.getElementById('simpleModal').remove()" | |
| style="position:absolute; top:12px; right:12px; background:none; | |
| border:none; color:var(--text-muted); font-size:1.5rem; | |
| cursor:pointer;">Γ</button> | |
| ${content} | |
| </div> | |
| `; | |
| modal.addEventListener('click', (e) => { | |
| if (e.target === modal) modal.remove(); | |
| }); | |
| document.body.appendChild(modal); | |
| } | |