document.addEventListener('DOMContentLoaded', () => { const convo = document.querySelector(".convo"); const fileUpload = document.getElementById('file-upload'); const imageUpload = document.getElementById('image-upload'); const fileBtn = document.getElementById('file-btn'); const imageBtn = document.getElementById('image-btn'); const sendButtons = document.querySelectorAll('.sendingQA'); const SummarizeInput = document.querySelector(".SummarizeInput"); const CaptionInput = document.querySelector(".CaptionInput"); let selectedFile = null; let filePreviewBubble = null; // Mode switching document.querySelectorAll('.select-options input[type="radio"]').forEach(radio => { radio.addEventListener('change', (e) => { if (e.target.checked) { const selectedValue = e.target.value; if (selectedValue === "Summarize") { SummarizeInput.classList.add("active"); SummarizeInput.classList.remove("innactive"); CaptionInput.classList.remove("active"); CaptionInput.classList.add("innactive"); } else { SummarizeInput.classList.add("innactive"); SummarizeInput.classList.remove("active"); CaptionInput.classList.remove("innactive"); CaptionInput.classList.add("active"); } } }); }); // File upload handlers fileBtn.addEventListener('click', () => fileUpload.click()); imageBtn.addEventListener('click', () => imageUpload.click()); fileUpload.addEventListener('change', (e) => { if (e.target.files.length) { selectedFile = e.target.files[0]; displayFilePreview(selectedFile); } }); imageUpload.addEventListener('change', (e) => { if (e.target.files.length) { selectedFile = e.target.files[0]; displayFilePreview(selectedFile); } }); // Drag and drop convo.addEventListener('dragover', (e) => { e.preventDefault(); convo.classList.add('drag-over'); }); convo.addEventListener('dragleave', () => { convo.classList.remove('drag-over'); }); convo.addEventListener('drop', (e) => { e.preventDefault(); convo.classList.remove('drag-over'); if (e.dataTransfer.files.length) { const file = e.dataTransfer.files[0]; const dataTransfer = new DataTransfer(); dataTransfer.items.add(file); const isSummarizeMode = document.querySelector('input[name="option"]:checked').value === 'Summarize'; if (isSummarizeMode) { fileUpload.files = dataTransfer.files; } else { imageUpload.files = dataTransfer.files; } selectedFile = file; displayFilePreview(file); } }); // Send button handlers sendButtons.forEach(button => { button.addEventListener('click', async () => { const isSummarizeMode = document.querySelector('input[name="option"]:checked').value === 'Summarize'; if (isSummarizeMode) { await handleSummarize(); } else { await handleCaption(); } }); }); function displayFilePreview(file) { if (filePreviewBubble) filePreviewBubble.remove(); filePreviewBubble = createMessageBubble( `📎 Selected ${file.type.startsWith('image/') ? 'image' : 'document'}: ${file.name}`, "You" ); } function createMessageBubble(text, sender = "You", audioSrc = null) { const bubble = document.createElement('div'); bubble.className = `bubble ${sender === "You" ? "right" : "left"}`; const label = document.createElement('div'); label.className = "label"; label.textContent = sender; const message = document.createElement('div'); message.className = "text"; if (sender === "You") { message.textContent = text; } else { message.innerHTML = typeof text === 'string' ? text : 'Processing...'; if (audioSrc) { const audioContainer = document.createElement('div'); audioContainer.style.display = 'flex'; audioContainer.style.alignItems = 'center'; audioContainer.style.gap = '10px'; audioContainer.style.marginTop = '8px'; const audio = new Audio(audioSrc); const audioIcon = document.createElement('i'); audioIcon.className = 'fa-solid fa-volume-high audio-toggle'; audioIcon.style.cursor = 'pointer'; audioIcon.addEventListener('click', () => { if (audio.paused) { audio.play(); audioIcon.classList.replace('fa-volume-xmark', 'fa-volume-high'); audioIcon.title = "Click to mute"; } else { audio.pause(); audioIcon.classList.replace('fa-volume-high', 'fa-volume-xmark'); audioIcon.title = "Click to unmute"; } }); audioContainer.appendChild(audioIcon); audioContainer.appendChild(document.createTextNode('Listen')); message.appendChild(audioContainer); } } bubble.appendChild(label); bubble.appendChild(message); convo.appendChild(bubble); convo.scrollTop = convo.scrollHeight; return bubble; } async function handleSummarize() { if (!selectedFile) { displayError('Please upload a document first'); return; } const length = document.querySelector('input[name="optionS"]:checked')?.value || "medium"; // Clear conversation and show file preview convo.innerHTML = ''; displayFileInfo(selectedFile.name, 'document'); // Show correct processing message for summarization const thinkingBubble = createMessageBubble( "Analyzing document and generating summary...
", "Aidan" ); try { const formData = new FormData(); formData.append('file', selectedFile); formData.append('length', length); const response = await fetch('/summarize/', { method: 'POST', body: formData }); if (!response.ok) { const error = await response.json(); throw new Error(error.detail || 'Summarization failed'); } const result = await response.json(); // Remove thinking message and show results thinkingBubble.remove(); displaySummaryResult( selectedFile.name, result.summary, result.audio_url || result.audioUrl, result.pdf_url || result.pdfUrl ); } catch (error) { thinkingBubble.remove(); displayError(error.message || 'Failed to summarize document'); } finally { resetFileInputs(); } } async function handleCaption() { if (!selectedFile) { alert("Please upload an image first"); return; } const thinkingBubble = createMessageBubble( "Generating caption...
", "Aidan" ); try { const formData = new FormData(); formData.append('file', selectedFile); const response = await fetch('/imagecaption/', { method: 'POST', body: formData }); if (!response.ok) { const error = await response.json(); throw new Error(error.detail || 'Captioning failed'); } const result = await response.json(); thinkingBubble.remove(); createMessageBubble( `Caption:

${result.answer || result.caption} ${result.audio ? `
` : ''}`, "Aidan", result.audio ); } catch (error) { thinkingBubble.remove(); createMessageBubble(`⚠️ Error: ${error.message}`, "Aidan"); } finally { resetFileInputs(); } } function resetFileInputs() { selectedFile = null; fileUpload.value = ''; imageUpload.value = ''; if (filePreviewBubble) { filePreviewBubble.remove(); filePreviewBubble = null; } } // Add loader CSS const style = document.createElement('style'); style.textContent = ` .loader { display: inline-block; border: 2px solid #f3f3f3; border-top: 2px solid #3b82f6; border-radius: 50%; width: 16px; height: 16px; animation: spin 1s linear infinite; } @keyframes spin { 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } } .download-link { display: inline-block; margin-top: 10px; padding: 5px 10px; background: #3b82f6; color: white; border-radius: 5px; text-decoration: none; } .download-link:hover { background: #2563eb; } .audio-toggle { cursor: pointer; transition: all 0.2s; } `; document.head.appendChild(style); });