web-ai / static /scripts.js
Hadiil's picture
Update static/scripts.js
5a6b8cd verified
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;
document.getElementById(modalId).classList.remove('hidden');
// Dim other function-box elements
document.querySelectorAll('.function-box').forEach(otherBox => {
if (otherBox !== box) {
otherBox.classList.add('shadowed');
}
});
});
});
// Chatbot Icon Click
document.querySelector('.chatbot-icon').addEventListener('click', () => {
document.getElementById('chatbot-modal').classList.remove('hidden');
});
// Close Modal
document.querySelectorAll('.close-modal').forEach(closeBtn => {
closeBtn.addEventListener('click', () => {
closeBtn.closest('.modal').classList.add('hidden');
// Reset forms and responses
const forms = closeBtn.closest('.modal').querySelectorAll('form');
forms.forEach(form => form.reset());
const responseCards = closeBtn.closest('.modal').querySelectorAll('.response-card');
responseCards.forEach(card => {
card.classList.add('hidden');
card.innerHTML = '';
});
const spinners = closeBtn.closest('.modal').querySelectorAll('.loading-spinner');
spinners.forEach(spinner => spinner.classList.add('hidden'));
const dropAreas = closeBtn.closest('.modal').querySelectorAll('.drop-area p');
dropAreas.forEach(p => p.textContent = 'Drop File Here or Click to Choose');
// Clear chatbot conversation
if (closeBtn.closest('.modal').id === 'chatbot-modal') {
document.getElementById('chatbot-conversation').innerHTML = '';
}
// Remove dimming from all function-box elements
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;
btn.closest('.modal').querySelectorAll('.tab-btn').forEach(b => b.classList.remove('active'));
btn.classList.add('active');
btn.closest('.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}`;
}
};
// Chatbot Form Submission
document.getElementById('chatbot-form').addEventListener('submit', async (e) => {
e.preventDefault();
const input = e.target.querySelector('input');
const message = input.value.trim();
const spinner = e.target.querySelector('.loading-spinner');
if (!message) return;
spinner.classList.remove('hidden');
const conversation = document.getElementById('chatbot-conversation');
conversation.innerHTML += `<p class="user-message">You: ${message}</p>`;
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 += `<p class="bot-message">Gemini: ${data.response}</p>`;
} else {
conversation.innerHTML += `<p class="bot-message">Error: ${data.detail}</p>`;
}
conversation.scrollTop = conversation.scrollHeight;
} catch (error) {
spinner.classList.add('hidden');
conversation.innerHTML += `<p class="bot-message">Error: ${error.message}</p>`;
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);
form.addEventListener('submit', async (e) => {
e.preventDefault();
const formData = new FormData();
const responseCard = form.nextElementSibling;
const spinner = form.querySelector('.loading-spinner');
responseCard.classList.add('hidden');
responseCard.innerHTML = '';
spinner.classList.remove('hidden');
// Append intent to FormData
formData.append('intent', forms[formId].intent);
if (formId === 'summarize-form') {
formData.append('text', form.querySelector('input[type="text"]').value);
} else if (formId === 'summarize-file-form') {
const file = form.querySelector('input[type="file"]').files[0];
if (!file) {
responseCard.innerHTML = `<p class="text-red-500">Please select a file.</p>`;
responseCard.classList.remove('hidden');
spinner.classList.add('hidden');
return;
}
formData.append('file', file);
} else if (formId === 'translate-text-form') {
const text = form.querySelector('input[type="text"]').value;
const lang = form.querySelector('select[name="language"]').value;
formData.append('text', `Translate to ${lang}: ${text}`);
} else if (formId === 'translate-file-form') {
const file = form.querySelector('input[type="file"]').files[0];
const lang = form.querySelector('select[name="language"]').value;
if (!file) {
responseCard.innerHTML = `<p class="text-red-500">Please select a file.</p>`;
responseCard.classList.remove('hidden');
spinner.classList.add('hidden');
return;
}
formData.append('file', file);
formData.append('text', `Translate to ${lang}`);
} else if (formId === 'file-qa-form') {
const file = form.querySelector('input[type="file"]').files[0];
const text = form.querySelector('input[type="text"]').value;
if (!file) {
responseCard.innerHTML = `<p class="text-red-500">Please select a file.</p>`;
responseCard.classList.remove('hidden');
spinner.classList.add('hidden');
return;
}
formData.append('file', file);
formData.append('text', text);
} else if (formId === 'image-caption-form') {
const file = form.querySelector('input[type="file"]').files[0];
if (!file) {
responseCard.innerHTML = `<p class="text-red-500">Please select an image.</p>`;
responseCard.classList.remove('hidden');
spinner.classList.add('hidden');
return;
}
formData.append('file', file);
} else if (formId === 'visual-qa-form') {
const file = form.querySelector('input[type="file"]').files[0];
const text = form.querySelector('input[type="text"]').value;
if (!file) {
responseCard.innerHTML = `<p class="text-red-500">Please select an image.</p>`;
responseCard.classList.remove('hidden');
spinner.classList.add('hidden');
return;
}
formData.append('file', file);
formData.append('text', text);
} else if (formId === 'visualize-form') {
const file = form.querySelector('input[type="file"]').files[0];
const visualizationType = form.querySelector('select[name="visualization-type"]').value;
if (!file) {
responseCard.innerHTML = `<p class="text-red-500">Please select a file.</p>`;
responseCard.classList.remove('hidden');
spinner.classList.add('hidden');
return;
}
formData.append('file', file);
formData.append('text', visualizationType);
}
try {
const response = await fetch(forms[formId].endpoint, {
method: 'POST',
body: formData
});
const data = await response.json();
spinner.classList.add('hidden');
if (response.ok) {
responseCard.innerHTML = `<p>${data.response}</p>`;
if (data.additional_data) {
Object.entries(data.additional_data).forEach(([key, value]) => {
responseCard.innerHTML += `<p><strong>${key.replace('_', ' ').replace(/\b\w/g, char => char.toUpperCase())}:</strong> ${value}</p>`;
});
}
responseCard.classList.remove('hidden');
} else {
responseCard.innerHTML = `<p class="text-red-500">Error: ${data.detail}</p>`;
responseCard.classList.remove('hidden');
}
} catch (error) {
spinner.classList.add('hidden');
responseCard.innerHTML = `<p class="text-red-500">Error: ${error.message}</p>`;
responseCard.classList.remove('hidden');
}
});
});
});