// CONFIGURATION PROFESSIONNELLE const LaBaleineIA = { token: "hf_votre_token_gratuit", // À configurer sur HuggingFace endpoints: { image: "https://api-inference.huggingface.co/models/stabilityai/stable-diffusion-xl-base-1.0", video: "https://api-inference.huggingface.co/models/cerspense/zeroscope_v2_576w" }, // Initialisation init: function() { console.log("🐋 La Baleine IA initialisĂ©e"); this.setupEventListeners(); }, // Configuration des Ă©vĂ©nements setupEventListeners: function() { // RĂ©cupĂšre la zone de saisie existante const inputField = document.querySelector('input[placeholder*="Écrivez votre message"], input[placeholder*="Ă©crire"]'); if (inputField) { inputField.addEventListener('keypress', (e) => { if (e.key === 'Enter' && e.target.value.trim()) { this.processerDemande(e.target.value); e.target.value = ''; } }); } // Bouton d'envoi (si existant) const sendButton = document.querySelector('button:contains("Envoyer"), button:contains("Send")'); if (sendButton) { sendButton.addEventListener('click', () => { const input = document.querySelector('input[placeholder*="Écrivez votre message"], input[placeholder*="Ă©crire"]'); if (input && input.value.trim()) { this.processerDemande(input.value); input.value = ''; } }); } }, // Traiter la demande utilisateur processerDemande: async function(demande) { // 1. Afficher le message utilisateur this.afficherMessage('utilisateur', demande); // 2. RĂ©ponse initiale de La Baleine this.afficherMessage('ia', `J'ai bien reçu : "${demande}". Je commence la gĂ©nĂ©ration...`); // 3. Analyser la demande pour le type const type = this.analyserTypeDemande(demande); // 4. Expliquer les Ă©tapes this.afficherExplication(`Étape 1/3 : Analyse de votre demande...`); await this.delay(800); this.afficherExplication(`Étape 2/3 : PrĂ©paration de la gĂ©nĂ©ration ${type === 'image' ? 'd\'image' : 'de vidĂ©o'}...`); await this.delay(800); // 5. GĂ©nĂ©ration try { this.afficherExplication(`Étape 3/3 : GĂ©nĂ©ration en cours avec les modĂšles IA...`); if (type === 'image') { await this.genererImage(demande); } else { await this.genererVideo(demande); } this.afficherMessage('ia', `✅ GĂ©nĂ©ration terminĂ©e ! Consultez la colonne de droite pour voir le rĂ©sultat.`); this.afficherExplication(`Processus complet terminĂ© avec succĂšs.`); } catch (error) { this.afficherMessage('ia', `❌ DĂ©solĂ©e, une erreur est survenue : ${error.message}`); } }, // GĂ©nĂ©rer une image genererImage: async function(prompt) { const response = await fetch(this.endpoints.image, { method: 'POST', headers: { 'Authorization': `Bearer ${this.token}`, 'Content-Type': 'application/json' }, body: JSON.stringify({ inputs: prompt, parameters: { num_inference_steps: 30, guidance_scale: 7.5 } }) }); if (!response.ok) throw new Error(`Erreur API: ${response.status}`); const blob = await response.blob(); const urlImage = URL.createObjectURL(blob); // Afficher dans la colonne droite this.afficherResultatVisuel('image', urlImage, prompt); // Sauvegarder pour tĂ©lĂ©chargement this.mediaCourant = { type: 'image', url: urlImage, nom: `baleine_${Date.now()}.png` }; }, // Afficher le rĂ©sultat visuel afficherResultatVisuel: function(type, url, prompt) { const section = document.getElementById('apercu-section'); const statut = document.getElementById('statut-generation'); const resultat = document.getElementById('resultat-visuel'); const controles = document.getElementById('controles-generation'); if (statut) statut.textContent = `✅ ${type === 'image' ? 'Image gĂ©nĂ©rĂ©e' : 'VidĂ©o gĂ©nĂ©rĂ©e'}`; if (resultat) { if (type === 'image') { resultat.innerHTML = `
"${prompt}"
Généré par La Baleine `; } else { resultat.innerHTML = `
"${prompt}"
`; } } if (controles) controles.style.display = 'block'; // Scroll automatique section.scrollTop = section.scrollHeight; }, // Afficher un message dans le chat afficherMessage: function(auteur, contenu) { const chat = document.getElementById('assistant-ia'); if (!chat) return; const messageDiv = document.createElement('div'); messageDiv.className = `message-${auteur}`; messageDiv.style.cssText = ` padding: 12px; border-radius: 12px; margin-bottom: 15px; max-width: 80%; ${auteur === 'utilisateur' ? 'background: #007bff; color: white; margin-left: auto;' : 'background: #e3f2fd; color: #333;'} `; messageDiv.innerHTML = `${auteur === 'utilisateur' ? 'đŸ‘€ Vous' : '🐋 La Baleine'}: ${contenu}`; chat.appendChild(messageDiv); chat.scrollTop = chat.scrollHeight; }, // Afficher une explication technique afficherExplication: function(texte) { const chat = document.getElementById('assistant-ia'); if (!chat) return; const explicationDiv = document.createElement('div'); explicationDiv.style.cssText = ` padding: 10px; border-radius: 8px; margin: 5px 0; background: #f5f5f5; border-left: 4px solid #4fc3f7; font-size: 14px; color: #555; `; explicationDiv.innerHTML = `⚙ ${texte}`; chat.appendChild(explicationDiv); chat.scrollTop = chat.scrollHeight; }, // Analyser le type de demande analyserTypeDemande: function(demande) { const motsVideo = ['vidĂ©o', 'film', 'animation', 'mouvement', 'cinĂ©ma']; const contientVideo = motsVideo.some(mot => demande.toLowerCase().includes(mot)); return contientVideo ? 'video' : 'image'; }, // Fonction d'attente delay: function(ms) { return new Promise(resolve => setTimeout(resolve, ms)); } }; // Fonctions de contrĂŽle function telechargerMedia() { if (LaBaleineIA.mediaCourant) { const a = document.createElement('a'); a.href = LaBaleineIA.mediaCourant.url; a.download = LaBaleineIA.mediaCourant.nom; document.body.appendChild(a); a.click(); document.body.removeChild(a); } } function genererNouvelleVersion() { const dernierMessage = document.querySelector('.message-utilisateur:last-child'); if (dernierMessage) { const texte = dernierMessage.textContent.replace('đŸ‘€ Vous:', '').trim(); if (texte) LaBaleineIA.processerDemande(texte); } } document.addEventListener('DOMContentLoaded', () => { LaBaleineIA.init(); // Initialize tooltips for icons const initTooltips = () => { const buttons = document.querySelectorAll('button'); buttons.forEach(button => { const icon = button.querySelector('[data-feather]'); if (icon) { const iconName = icon.getAttribute('data-feather'); button.setAttribute('title', iconName.charAt(0).toUpperCase() + iconName.slice(1)); } }); }; // Handle message sending and AI responses const setupMessageInput = () => { const input = document.querySelector('main input'); const sendBtn = document.querySelector('main button:disabled'); const micBtn = document.querySelector('main button[data-feather="mic"]'); const plusBtn = document.querySelector('main button[data-feather="plus"]'); const paperclipBtn = document.querySelector('main button[data-feather="paperclip"]'); const messageContainer = document.querySelector('.flex-1.flex.items-center.justify-center'); // AI response logic const getAIResponse = (message) => { const lowerMsg = message.toLowerCase(); if (lowerMsg.includes('image') || lowerMsg.includes('photo') || lowerMsg.includes('picture')) { return `Je peux gĂ©nĂ©rer des images pour toi. Voici un exemple : Ouvrir le gĂ©nĂ©rateur d'images La Baleine IA`; } else if (lowerMsg.includes('vidĂ©o') || lowerMsg.includes('video')) { return "Pour les vidĂ©os, je peux te conseiller sur le format, la durĂ©e et le style. Quel type de vidĂ©o veux-tu crĂ©er ?"; } else if (lowerMsg.includes('thĂšme') || lowerMsg.includes('theme')) { return "Je peux t'aider Ă  concevoir un thĂšme. Dis-moi pour quelle plateforme (Shopify, WordPress, etc.) et quel style tu recherches."; } else if (lowerMsg.includes('plugin')) { return "Les plugins peuvent Ă©tendre les fonctionnalitĂ©s. Quel type de plugin veux-tu dĂ©velopper ? (pour WordPress, Shopify, etc.)"; } else { return "Je peux t'aider avec des images, vidĂ©os, thĂšmes et plugins. Dis-moi plus prĂ©cisĂ©ment ce que tu veux crĂ©er !"; } }; // Display message in chat const displayMessage = (text, isUser = false) => { if (!messageContainer) return; const messageDiv = document.createElement('div'); messageDiv.className = `p-4 mb-2 rounded-lg max-w-[80%] ${isUser ? 'ml-auto bg-blue-900/30 text-blue-100' : 'bg-gray-700/50 text-gray-100'}`; messageDiv.innerHTML = text; if (isUser) { messageContainer.insertBefore(messageDiv, messageContainer.firstChild); } else { messageContainer.appendChild(messageDiv); } }; // Handle send message const handleSend = () => { const message = input.value.trim(); if (!message) return; displayMessage(message, true); input.value = ''; sendBtn.disabled = true; // Simulate AI thinking setTimeout(() => { const response = getAIResponse(message); displayMessage(response); }, 1000); }; // Event listeners input.addEventListener('keydown', (e) => { if (e.key === 'Enter') handleSend(); }); sendBtn.addEventListener('click', handleSend); // Microphone functionality using Web Speech API if (micBtn) { micBtn.addEventListener('click', async () => { try { const SpeechRecognition = window.SpeechRecognition || window.webkitSpeechRecognition; if (!SpeechRecognition) { statusEl.textContent = "Micro: non supportĂ©"; return; } const recognition = new SpeechRecognition(); recognition.lang = 'fr-FR'; recognition.interimResults = false; recognition.onresult = (event) => { let transcript = ''; for (let i = event.resultIndex; i < event.results.length; i++) { transcript += event.results[i][0].transcript; } inp.value = transcript; // Only send if the result is final if (event.results[0].isFinal) { handleSend(); } }; recognition.onerror = (event) => { console.error('Erreur de reconnaissance vocale:', event.error); statusEl.textContent = "Micro: erreur - " + event.error; }; statusEl.textContent = "Micro: Ă©coute..."; await navigator.mediaDevices.getUserMedia({ audio: true }); recognition.start(); micBtn.innerHTML = ''; feather.replace(); recognition.onend = () => { micBtn.innerHTML = ''; feather.replace(); statusEl.textContent = "Micro: prĂȘt"; }; } catch (err) { console.error('Erreur microphone:', err); statusEl.textContent = "Micro: permission refusĂ©e"; } }); } // File attachment functionality if (paperclipBtn) { // Create hidden file input const fileInput = document.createElement('input'); fileInput.type = 'file'; fileInput.style.display = 'none'; document.body.appendChild(fileInput); paperclipBtn.addEventListener('click', () => { fileInput.click(); }); fileInput.addEventListener('change', (e) => { const file = e.target.files[0]; if (!file) return; // Handle different file types if (file.type.startsWith('image/')) { const reader = new FileReader(); reader.onload = (event) => { const img = document.createElement('img'); img.src = event.target.result; img.classList.add('max-w-xs', 'max-h-40', 'rounded-lg', 'mt-2'); const message = `Fichier image: ${file.name}`; displayMessage(`${message}
`); messageContainer.appendChild(img); }; reader.readAsDataURL(file); } else { displayMessage(`Fichier joint: ${file.name} (${(file.size / 1024).toFixed(1)} KB)`); } }); } }; // Initialize all functionality const init = () => { initTooltips(); setupMessageInput(); }; init(); });