Spaces:
Sleeping
Sleeping
| 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"); | |
| const gotItButton = document.querySelector('.explainChoix button'); | |
| const explainChoixDiv = document.querySelector('.explainChoix'); | |
| let selectedFile = null; | |
| // β Default mode: Summarize selected | |
| const summarizeRadio = document.getElementById('summarize-radio'); | |
| if (summarizeRadio) summarizeRadio.checked = true; | |
| // Mode switching | |
| document.querySelectorAll('.select-options input[name="mode"]').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); | |
| } | |
| }); | |
| // "Got it" button to hide explanation div | |
| gotItButton.addEventListener('click', () => { | |
| explainChoixDiv.style.display = "none"; | |
| }); | |
| // Send button handlers | |
| sendButtons.forEach(button => { | |
| button.addEventListener('click', handleSubmit); | |
| }); | |
| function displayFilePreview(file) { | |
| // β DO NOT remove old previews anymore | |
| const previewBubble = document.createElement("div"); | |
| previewBubble.className = "file-preview-bubble bubble right"; | |
| previewBubble.style.display = "flex"; | |
| previewBubble.style.flexDirection = "column"; | |
| previewBubble.style.maxWidth = "50%"; | |
| if (file.type.startsWith('image/')) { | |
| const reader = new FileReader(); | |
| reader.onload = (e) => { | |
| const img = document.createElement("img"); | |
| img.src = e.target.result; | |
| img.style.width = "100%"; | |
| img.style.height = "200px"; | |
| img.style.objectFit = "cover"; | |
| img.style.borderRadius = "10px"; | |
| img.style.marginBottom = "8px"; | |
| const text = document.createElement("span"); | |
| text.textContent = `π Selected image: ${file.name}`; | |
| text.style.fontSize = "13px"; | |
| previewBubble.appendChild(img); | |
| previewBubble.appendChild(text); | |
| convo.appendChild(previewBubble); | |
| convo.scrollTop = convo.scrollHeight; | |
| }; | |
| reader.readAsDataURL(file); | |
| } else { | |
| const text = document.createElement("span"); | |
| text.textContent = `π Selected document: ${file.name}`; | |
| text.style.fontSize = "13px"; | |
| previewBubble.appendChild(text); | |
| convo.appendChild(previewBubble); | |
| convo.scrollTop = convo.scrollHeight; | |
| } | |
| } | |
| function createMessageBubble(text, sender = "You", audioSrc = null, fileName = null) { | |
| const bubble = document.createElement('div'); | |
| bubble.className = `bubble ${sender === "You" ? "right" : "left"}`; | |
| bubble.style.maxWidth = "50%"; | |
| bubble.style.wordWrap = "break-word"; | |
| const label = document.createElement('div'); | |
| label.className = "label"; | |
| label.textContent = sender; | |
| const message = document.createElement('div'); | |
| message.className = "text"; | |
| message.style.whiteSpace = "pre-wrap"; | |
| message.style.display = "flex"; | |
| message.style.flexDirection = "column"; | |
| const textSpan = document.createElement("span"); | |
| textSpan.innerHTML = text; | |
| message.appendChild(textSpan); | |
| if (sender !== "You" && (audioSrc || fileName)) { | |
| const iconContainer = document.createElement('div'); | |
| iconContainer.style.marginTop = "10px"; | |
| iconContainer.style.display = "flex"; | |
| iconContainer.style.justifyContent = "flex-end"; | |
| iconContainer.style.gap = "15px"; | |
| if (audioSrc) { | |
| const audio = new Audio(audioSrc); | |
| const audioIcon = document.createElement("i"); | |
| audioIcon.className = "fa-solid fa-volume-high audio-toggle"; | |
| audioIcon.title = "Play Audio"; | |
| audioIcon.style.cursor = "pointer"; | |
| audioIcon.style.fontSize = "18px"; | |
| audioIcon.addEventListener("click", () => { | |
| if (audio.paused) { | |
| audio.play(); | |
| audioIcon.classList.remove("fa-volume-xmark"); | |
| audioIcon.classList.add("fa-volume-high"); | |
| audioIcon.title = "Mute Audio"; | |
| } else { | |
| audio.pause(); | |
| audioIcon.classList.remove("fa-volume-high"); | |
| audioIcon.classList.add("fa-volume-xmark"); | |
| audioIcon.title = "Unmute Audio"; | |
| } | |
| }); | |
| iconContainer.appendChild(audioIcon); | |
| } | |
| if (fileName) { | |
| const downloadLink = document.createElement('a'); | |
| downloadLink.href = fileName; | |
| downloadLink.target = "_blank"; | |
| downloadLink.download = "summary.pdf"; // β Suggest filename | |
| const downloadIcon = document.createElement("i"); | |
| downloadIcon.className = "fa-solid fa-file-arrow-down"; | |
| downloadIcon.style.fontSize = "18px"; | |
| downloadIcon.style.cursor = "pointer"; | |
| downloadLink.appendChild(downloadIcon); | |
| iconContainer.appendChild(downloadLink); | |
| } | |
| message.appendChild(iconContainer); | |
| } | |
| bubble.appendChild(label); | |
| bubble.appendChild(message); | |
| convo.appendChild(bubble); | |
| convo.scrollTop = convo.scrollHeight; | |
| return bubble; | |
| } | |
| async function handleSubmit() { | |
| if (!selectedFile) { | |
| alert("Please upload a file first"); | |
| return; | |
| } | |
| const isSummarizeMode = document.querySelector('input[name="mode"]:checked').value === 'Summarize'; | |
| const endpoint = isSummarizeMode ? '/summarize/' : '/imagecaption/'; | |
| const thinkingText = isSummarizeMode ? 'Processing document π... <div class="loader"></div>' : "Generating caption πΌοΈ ... <div class='loader'></div>"; | |
| const senderName = "Aidan"; | |
| const thinkingBubble = createMessageBubble(thinkingText, senderName); | |
| const formData = new FormData(); | |
| formData.append('file', selectedFile); | |
| if (isSummarizeMode) formData.append('length', 'medium'); | |
| try { | |
| const response = await fetch(endpoint, { | |
| method: 'POST', | |
| body: formData | |
| }); | |
| if (!response.ok) { | |
| let errorMessage = 'Request failed'; | |
| try { | |
| const error = await response.json(); | |
| errorMessage = error.detail || error.error || errorMessage; | |
| } catch (e) {} | |
| throw new Error(errorMessage); | |
| } | |
| const result = await response.json(); | |
| thinkingBubble.remove(); | |
| if (isSummarizeMode) { | |
| createMessageBubble( | |
| result.summary || "No summary generated.", | |
| "Aidan", | |
| result.audioUrl, | |
| result.pdfUrl | |
| ); | |
| } else { | |
| createMessageBubble( | |
| result.caption || result.answer || "No caption generated.", | |
| "Aidan", | |
| result.audio, | |
| null | |
| ); | |
| } | |
| } catch (error) { | |
| thinkingBubble.remove(); | |
| createMessageBubble(`β οΈ Error: ${error.message}`, "Aidan"); | |
| } finally { | |
| selectedFile = null; // β Reset selected file AFTER send | |
| } | |
| } | |
| // 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); } | |
| } | |
| .audio-toggle { | |
| cursor: pointer; | |
| transition: all 0.2s; | |
| } | |
| `; | |
| document.head.appendChild(style); | |
| }); | |