document.addEventListener('DOMContentLoaded', () => { // Starry Background Animation const stars = document.createElement('canvas'); stars.className = 'stars'; document.body.appendChild(stars); const ctx = stars.getContext('2d'); stars.width = window.innerWidth; stars.height = window.innerHeight; const starArray = []; for (let i = 0; i < 100; i++) { starArray.push({ x: Math.random() * stars.width, y: Math.random() * stars.height, radius: Math.random() * 2, opacity: Math.random() }); } function animateStars() { ctx.clearRect(0, 0, stars.width, stars.height); starArray.forEach(star => { ctx.beginPath(); ctx.arc(star.x, star.y, star.radius, 0, Math.PI * 2); ctx.fillStyle = `rgba(255, 255, 255, ${star.opacity})`; ctx.fill(); star.opacity += (Math.random() - 0.5) * 0.05; if (star.opacity > 1) star.opacity = 1; if (star.opacity < 0) star.opacity = 0; }); requestAnimationFrame(animateStars); } animateStars(); // Card Hover Effects const cards = document.querySelectorAll(".card"); cards.forEach(card => { card.addEventListener("mouseenter", () => { if (!card.classList.contains('shadowed')) { card.style.transition = "transform 0.4s ease-in-out"; card.style.transform = "scale(1.05) rotate(0.5deg)"; } }); card.addEventListener("mouseleave", () => { if (!card.classList.contains('shadowed')) { card.style.transform = "scale(1) rotate(0deg)"; } }); }); // Window Resize Handler for Canvas window.addEventListener('resize', () => { stars.width = window.innerWidth; stars.height = window.innerHeight; starArray.length = 0; for (let i = 0; i < 100; i++) { starArray.push({ x: Math.random() * stars.width, y: Math.random() * stars.height, radius: Math.random() * 2, opacity: Math.random() }); } }); // Box Click to Open Modal document.querySelectorAll('.function-box').forEach(box => { box.addEventListener('click', () => { const modalId = box.dataset.modal; const modal = document.getElementById(modalId); if (modal) { modal.classList.remove('hidden'); document.querySelectorAll('.function-box').forEach(otherBox => { if (otherBox !== box) { otherBox.classList.add('shadowed'); } }); } }); }); // Chatbot Icon Click const chatbotIcon = document.querySelector('.chatbot-icon'); if (chatbotIcon) { chatbotIcon.addEventListener('click', () => { const chatbotModal = document.getElementById('chatbot-modal'); if (chatbotModal) { chatbotModal.classList.remove('hidden'); } }); } // Close Modal document.querySelectorAll('.close-modal').forEach(closeBtn => { closeBtn.addEventListener('click', () => { const modal = closeBtn.closest('.modal'); modal.classList.add('hidden'); const forms = modal.querySelectorAll('form'); forms.forEach(form => form.reset()); const responseCards = modal.querySelectorAll('.response-card'); responseCards.forEach(card => { card.classList.add('hidden'); card.innerHTML = ''; }); const spinners = modal.querySelectorAll('.loading-spinner'); spinners.forEach(spinner => spinner.classList.add('hidden')); const dropAreas = modal.querySelectorAll('.drop-area p'); dropAreas.forEach(p => p.textContent = 'Drop File Here or Click to Choose'); if (modal.id === 'chatbot-modal') { const conversation = document.getElementById('chatbot-conversation'); if (conversation) { conversation.innerHTML = ''; } } document.querySelectorAll('.function-box').forEach(box => { box.classList.remove('shadowed'); }); }); }); // Tab Switching for Summarize and Translate document.querySelectorAll('.tab-btn').forEach(btn => { btn.addEventListener('click', () => { const tab = btn.dataset.tab; const modal = btn.closest('.modal'); modal.querySelectorAll('.tab-btn').forEach(b => b.classList.remove('active')); btn.classList.add('active'); modal.querySelectorAll('.tab-content').forEach(content => { content.classList.add('hidden'); if (content.dataset.tab === tab) content.classList.remove('hidden'); }); }); }); // File Drop Handler window.handleDrop = function(event, dropArea) { event.preventDefault(); const fileInput = dropArea.querySelector('input[type="file"]'); const files = event.dataTransfer.files; if (files.length > 0) { fileInput.files = files; dropArea.querySelector('p').textContent = `Selected: ${files[0].name}`; } }; // File Input Click Handler document.querySelectorAll('.drop-area').forEach(dropArea => { const fileInput = dropArea.querySelector('input[type="file"]'); dropArea.addEventListener('click', () => { fileInput.click(); }); fileInput.addEventListener('change', () => { if (fileInput.files.length > 0) { dropArea.querySelector('p').textContent = `Selected: ${fileInput.files[0].name}`; } }); }); // Chatbot Form Submission const chatbotForm = document.getElementById('chatbot-form'); if (chatbotForm) { chatbotForm.addEventListener('submit', async (e) => { e.preventDefault(); const input = e.target.querySelector('input'); const message = input.value.trim(); const spinner = e.target.querySelector('.loading-spinner') || document.createElement('div'); if (!spinner.classList.contains('loading-spinner')) { spinner.className = 'loading-spinner'; spinner.innerHTML = 'Processing...'; e.target.appendChild(spinner); } if (!message) return; spinner.classList.remove('hidden'); const conversation = document.getElementById('chatbot-conversation'); conversation.innerHTML += `

You: ${message}

`; conversation.scrollTop = conversation.scrollHeight; input.value = ''; try { const response = await fetch('/chat', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ message }) }); const data = await response.json(); spinner.classList.add('hidden'); if (response.ok) { conversation.innerHTML += `

Gemini: ${data.response}

`; } else { conversation.innerHTML += `

Error: ${data.detail || 'Unknown error'}

`; } conversation.scrollTop = conversation.scrollHeight; } catch (error) { spinner.classList.add('hidden'); conversation.innerHTML += `

Error: ${error.message}

`; conversation.scrollTop = conversation.scrollHeight; } }); } // Form Submissions for Other Functionalities const forms = { 'summarize-form': { endpoint: '/process', intent: 'summarize' }, 'summarize-file-form': { endpoint: '/process', intent: 'summarize' }, 'translate-text-form': { endpoint: '/process', intent: 'translate' }, 'translate-file-form': { endpoint: '/process', intent: 'file-translate' }, 'file-qa-form': { endpoint: '/process', intent: 'file-qa' }, 'image-caption-form': { endpoint: '/process', intent: 'image-to-text' }, 'visual-qa-form': { endpoint: '/process', intent: 'visual-qa' }, 'visualize-form': { endpoint: '/process', intent: 'visualize' } }; Object.keys(forms).forEach(formId => { const form = document.getElementById(formId); if (!form) return; form.addEventListener('submit', async (e) => { e.preventDefault(); const formData = new FormData(); const responseCard = form.nextElementSibling; let spinner = form.querySelector('.loading-spinner'); if (!spinner) { spinner = document.createElement('div'); spinner.className = 'loading-spinner hidden'; spinner.innerHTML = 'Processing...'; form.appendChild(spinner); } // Collect form data const textInput = form.querySelector('textarea, input[type="text"]'); const fileInput = form.querySelector('input[type="file"]'); const languageSelect = form.querySelector('select[name="language"]'); const visualizationSelect = form.querySelector('select[name="visualization-type"]'); let textValue = textInput && textInput.value.trim() ? textInput.value.trim() : ''; if (languageSelect && textValue && (formId === 'translate-text-form' || formId === 'translate-file-form')) { textValue = `Translate to ${languageSelect.value}: ${textValue}`; } if (textValue) { formData.append('text', textValue); } if (fileInput && fileInput.files.length > 0) { formData.append('file', fileInput.files[0]); } if (visualizationSelect) { formData.append('text', visualizationSelect.value); } // Validate input if (!textValue && (!fileInput || fileInput.files.length === 0)) { responseCard.classList.remove('hidden'); responseCard.innerHTML = '

Please provide text or a file.

'; return; } spinner.classList.remove('hidden'); responseCard.classList.add('hidden'); responseCard.innerHTML = ''; // Display uploaded image locally for caption and visual QA let localImageUrl = ''; if (fileInput && fileInput.files.length > 0 && (formId === 'image-caption-form' || formId === 'visual-qa-form')) { const file = fileInput.files[0]; localImageUrl = await new Promise(resolve => { const reader = new FileReader(); reader.onload = () => resolve(reader.result); reader.readAsDataURL(file); }); } try { const response = await fetch(forms[formId].endpoint, { method: 'POST', body: formData }); const data = await response.json(); spinner.classList.add('hidden'); responseCard.classList.remove('hidden'); if (response.ok) { let responseText = data.response; if (data.type === 'visualization_code') { responseText = `
${responseText}
`; } else if (data.type === 'caption' || data.type === 'visual_qa') { responseText = `${responseText}
Uploaded Image`; } else if (data.type === 'file_qa' || data.type === 'file_translation') { responseText = `${responseText}
File: ${data.additional_data.file_name}`; } responseCard.innerHTML = `

${responseText}

`; if (data.message) { responseCard.innerHTML += `

${data.message}

`; } } else { responseCard.innerHTML = `

Error: ${data.detail || 'Unknown error'}

`; } } catch (error) { spinner.classList.add('hidden'); responseCard.classList.remove('hidden'); responseCard.innerHTML = `

Error: ${error.message}

`; } }); }); });