/* Cosmic Chatbot - Scripts JavaScript */ // Attendre que le DOM soit complètement chargé document.addEventListener('DOMContentLoaded', function() { // Éléments DOM const messagesDiv = document.getElementById('messages'); const chatInput = document.getElementById('chatInput'); const sendButton = document.getElementById('sendButton'); const fileInput = document.getElementById('fileInput'); const filePreviewArea = document.getElementById('filePreviewArea'); const themeToggle = document.getElementById('themeToggle'); const featureToggle = document.getElementById('featureToggle'); const featureShowcase = document.getElementById('featureShowcase'); const starsContainer = document.getElementById('starsContainer'); const particlesContainer = document.getElementById('particlesContainer'); // Variables globales let currentTheme = 'dark'; let selectedFile = null; // Initialisation initializeStars(); initializeParticles(); initializeEventListeners(); // Fonctions d'initialisation function initializeStars() { // Créer des étoiles avec des positions et tailles aléatoires for (let i = 0; i < 100; i++) { const star = document.createElement('div'); star.className = 'star'; // Position aléatoire const x = Math.random() * 100; const y = Math.random() * 100; // Taille aléatoire const size = Math.random() * 2 + 1; // Délai d'animation aléatoire const delay = Math.random() * 3; // Appliquer les styles star.style.left = `${x}%`; star.style.top = `${y}%`; star.style.width = `${size}px`; star.style.height = `${size}px`; star.style.animationDelay = `${delay}s`; starsContainer.appendChild(star); } } function initializeParticles() { // Créer des particules flottantes for (let i = 0; i < 15; i++) { const particle = document.createElement('div'); particle.className = 'particle'; // Position aléatoire const x = Math.random() * 100; const y = Math.random() * 100; // Taille aléatoire const size = Math.random() * 50 + 20; // Délai d'animation aléatoire const delay = Math.random() * 5; // Appliquer les styles particle.style.left = `${x}%`; particle.style.top = `${y}%`; particle.style.width = `${size}px`; particle.style.height = `${size}px`; particle.style.animationDelay = `${delay}s`; particlesContainer.appendChild(particle); } } function initializeEventListeners() { // Événement d'envoi de message sendButton.addEventListener('click', processInput); chatInput.addEventListener('keydown', (e) => { if (e.key === 'Enter' && !e.shiftKey) { e.preventDefault(); processInput(); } }); // Événement de changement de thème themeToggle.addEventListener('click', toggleTheme); // Événement d'affichage des fonctionnalités featureToggle.addEventListener('click', toggleFeatureShowcase); // Événement de sélection de fichier fileInput.addEventListener('change', handleFileSelection); // Événement de clic sur une carte de fonctionnalité document.querySelectorAll('.feature-card').forEach(card => { card.addEventListener('click', () => { const feature = card.getAttribute('data-feature'); suggestFeaturePrompt(feature); }); }); } // Fonctions de gestion des événements function toggleTheme() { const body = document.body; const icon = themeToggle.querySelector('i'); if (currentTheme === 'dark') { // Passer au thème clair body.classList.add('light-theme'); icon.className = 'bx bx-sun'; currentTheme = 'light'; } else { // Passer au thème sombre body.classList.remove('light-theme'); icon.className = 'bx bx-moon'; currentTheme = 'dark'; } // Ajouter une classe pour la transition body.classList.add('theme-transition'); // Supprimer la classe après la transition setTimeout(() => { body.classList.remove('theme-transition'); }, 500); } function toggleFeatureShowcase() { featureShowcase.classList.toggle('active'); // Changer l'icône et le texte du bouton if (featureShowcase.classList.contains('active')) { featureToggle.innerHTML = ' Fermer'; } else { featureToggle.innerHTML = ' Fonctionnalités'; } } function handleFileSelection(e) { const file = e.target.files[0]; if (!file) return; selectedFile = file; // Afficher l'aperçu du fichier filePreviewArea.innerHTML = ''; const preview = document.createElement('div'); preview.className = 'file-preview'; // Déterminer l'icône en fonction du type de fichier let iconClass = 'bx-file'; if (file.type.startsWith('image/')) { iconClass = 'bx-image'; } else if (file.name.endsWith('.pdf')) { iconClass = 'bx-file-pdf'; } else if (file.name.endsWith('.xlsx') || file.name.endsWith('.xls')) { iconClass = 'bx-spreadsheet'; } else if (file.name.endsWith('.docx') || file.name.endsWith('.doc')) { iconClass = 'bx-file-doc'; } preview.innerHTML = `
${responseText}
`, false, true); }; reader.readAsDataURL(file); return; } addMessage(responseText); } catch (error) { document.getElementById('typingIndicator')?.remove(); addMessage(`Erreur: ${error.message}`); } } function addMessage(content, isUser = false, isHTML = false) { const msgDiv = document.createElement('div'); msgDiv.className = `message ${isUser ? 'user-message' : 'bot-message'}`; // Ajouter l'avatar const avatar = document.createElement('div'); avatar.className = 'message-avatar'; avatar.innerHTML = isUser ? '' : ''; msgDiv.appendChild(avatar); // Ajouter l'heure const time = document.createElement('div'); time.className = 'message-time'; time.textContent = formatTime(new Date()); // Formater le contenu if (isHTML) { // Si le contenu est du HTML (pour les images) msgDiv.innerHTML += content; } else if (content.includes('```')) { // Formater les blocs de code const contentDiv = document.createElement('div'); contentDiv.className = 'markdown-content'; const parts = content.split(/```([\s\S]*?)```/); parts.forEach((part, i) => { if (i % 2 === 1) { // Bloc de code const pre = document.createElement('div'); pre.className = 'code-block'; pre.textContent = part.trim(); // Bouton de copie const copyBtn = document.createElement('button'); copyBtn.className = 'copy-code'; copyBtn.textContent = 'Copier'; copyBtn.addEventListener('click', () => { navigator.clipboard.writeText(part.trim()); copyBtn.textContent = 'Copié !'; setTimeout(() => { copyBtn.textContent = 'Copier'; }, 2000); }); pre.appendChild(copyBtn); contentDiv.appendChild(pre); } else if (part.trim()) { // Texte normal const p = document.createElement('p'); p.textContent = part.trim(); contentDiv.appendChild(p); } }); msgDiv.appendChild(contentDiv); } else { // Texte normal avec formatage Markdown basique const contentDiv = document.createElement('div'); contentDiv.className = 'markdown-content'; // Convertir les listes let formattedContent = content; if (content.includes('\n- ')) { const listItems = content.split('\n- '); formattedContent = listItems[0]; if (listItems.length > 1) { const ul = document.createElement('ul'); for (let i = 1; i < listItems.length; i++) { const li = document.createElement('li'); li.textContent = listItems[i].trim(); ul.appendChild(li); } contentDiv.innerHTML = `${formattedContent}
`; contentDiv.appendChild(ul); msgDiv.appendChild(contentDiv); } else { contentDiv.textContent = formattedContent; msgDiv.appendChild(contentDiv); } } else { contentDiv.textContent = formattedContent; msgDiv.appendChild(contentDiv); } } msgDiv.appendChild(time); messagesDiv.appendChild(msgDiv); messagesDiv.scrollTop = messagesDiv.scrollHeight; return msgDiv; } function showTyping() { const typingDiv = document.createElement('div'); typingDiv.className = 'typing'; typingDiv.id = 'typingIndicator'; for (let i = 0; i < 3; i++) { const dot = document.createElement('div'); dot.className = 'typing-dot'; typingDiv.appendChild(dot); } messagesDiv.appendChild(typingDiv); messagesDiv.scrollTop = messagesDiv.scrollHeight; } // Fonctions utilitaires function formatTime(date) { const hours = date.getHours().toString().padStart(2, '0'); const minutes = date.getMinutes().toString().padStart(2, '0'); return `${hours}:${minutes}`; } });