Spaces:
Sleeping
Sleeping
| // static/app.js (v2.0) | |
| document.addEventListener("DOMContentLoaded", () => { | |
| const chatLog = document.getElementById("chat-log"); | |
| const chatInput = document.getElementById("chat-input"); | |
| const sendButton = document.getElementById("send-button"); | |
| const memoriaLog = document.getElementById("memoria-log"); | |
| const connectionStatus = document.getElementById("connection-status"); | |
| let ws; | |
| const audioQueue = []; | |
| let isPlaying = false; | |
| function setConnectionStatus(status) { // status: 'connected', 'disconnected', 'connecting' | |
| const statusText = connectionStatus.querySelector('.status-text'); | |
| connectionStatus.className = status; | |
| switch (status) { | |
| case 'connected': | |
| statusText.textContent = 'Conectado'; | |
| break; | |
| case 'disconnected': | |
| statusText.textContent = 'Desconectado'; | |
| break; | |
| case 'connecting': | |
| statusText.textContent = 'Reconectando...'; | |
| break; | |
| } | |
| } | |
| function addMessageToLog(message, sender) { | |
| const messageElement = document.createElement("div"); | |
| messageElement.classList.add("chat-message", `${sender}-message`); | |
| messageElement.textContent = message; | |
| chatLog.appendChild(messageElement); | |
| chatLog.scrollTop = chatLog.scrollHeight; | |
| } | |
| function playNextAudio() { | |
| if (isPlaying || audioQueue.length === 0) return; | |
| isPlaying = true; | |
| const audioData = audioQueue.shift(); | |
| const audio = new Audio("data:audio/wav;base64," + audioData); | |
| audio.play(); | |
| audio.onended = () => { | |
| isPlaying = false; | |
| playNextAudio(); | |
| }; | |
| } | |
| function connect() { | |
| const protocol = window.location.protocol === 'https:' ? 'wss:' : 'ws:'; | |
| const host = window.location.host; | |
| ws = new WebSocket(`${protocol}//${host}/ws`); | |
| ws.onopen = () => { | |
| console.log("Conectado al Santuario Digital v2.1."); | |
| setConnectionStatus('connected'); | |
| }; | |
| ws.onmessage = (event) => { | |
| const data = JSON.parse(event.data); | |
| if (data.type === 'text') { | |
| addMessageToLog(data.content, 'samuel'); | |
| } else if (data.type === 'audio') { | |
| audioQueue.push(data.content); | |
| playNextAudio(); | |
| } else if (data.type === 'error') { | |
| addMessageToLog(`Error de Samuel: ${data.content}`, 'samuel'); | |
| } | |
| }; | |
| ws.onclose = () => { | |
| console.log("Desconectado. Intentando reconectar en 5 segundos..."); | |
| setConnectionStatus('disconnected'); | |
| setTimeout(() => { | |
| setConnectionStatus('connecting'); | |
| connect(); | |
| }, 5000); | |
| }; | |
| ws.onerror = (error) => { | |
| console.error("Error de WebSocket:", error); | |
| setConnectionStatus('disconnected'); | |
| ws.close(); | |
| }; | |
| } | |
| function sendMessage() { | |
| const message = chatInput.value.trim(); | |
| if (message && ws && ws.readyState === WebSocket.OPEN) { | |
| addMessageToLog(message, 'user'); | |
| ws.send(JSON.stringify({ type: 'chat', content: message })); | |
| chatInput.value = ''; | |
| chatInput.style.height = 'auto'; | |
| } | |
| } | |
| sendButton.addEventListener("click", sendMessage); | |
| chatInput.addEventListener("keydown", (event) => { | |
| if (event.key === "Enter" && !event.shiftKey) { | |
| event.preventDefault(); | |
| sendMessage(); | |
| } | |
| }); | |
| chatInput.addEventListener('input', () => { | |
| chatInput.style.height = 'auto'; | |
| chatInput.style.height = (chatInput.scrollHeight) + 'px'; | |
| }); | |
| window.switchView = async (view) => { | |
| document.querySelectorAll('.view').forEach(v => v.classList.remove('active')); | |
| document.querySelectorAll('.nav-item').forEach(n => n.classList.remove('active')); | |
| document.getElementById(`${view}-view`).classList.add('active'); | |
| document.querySelector(`[onclick="switchView('${view}')"]`).classList.add('active'); | |
| if (view === 'memoria') { | |
| await fetchMemories(); | |
| } | |
| }; | |
| async function fetchMemories() { | |
| try { | |
| const response = await fetch('/api/memories'); | |
| if (response.ok) { | |
| const memories = await response.json(); | |
| memoriaLog.innerHTML = ''; | |
| if (memories.length === 0) { | |
| memoriaLog.innerHTML = "<p>Aún no hay memorias. Las conversaciones profundas las crearán.</p>"; | |
| } else { | |
| memories.forEach(mem => { | |
| const entry = document.createElement('div'); | |
| entry.className = 'memory-entry'; | |
| const timestamp = new Date(mem.timestamp).toLocaleString('es-AR'); | |
| entry.innerHTML = `<p class="timestamp">${timestamp}</p><p class="content">${mem.content}</p>`; | |
| memoriaLog.appendChild(entry); | |
| }); | |
| } | |
| } else { | |
| memoriaLog.innerHTML = "<p>No se pudieron cargar las memorias.</p>"; | |
| } | |
| } catch (error) { | |
| console.error("Error al cargar memorias:", error); | |
| memoriaLog.innerHTML = "<p>Error de conexión al cargar las memorias.</p>"; | |
| } | |
| } | |
| window.logout = async () => { | |
| try { | |
| const response = await fetch('/logout', { method: 'POST' }); | |
| if(response.ok) { | |
| window.location.href = '/'; | |
| } | |
| } catch (error) { | |
| console.error("Error al cerrar sesión:", error); | |
| } | |
| }; | |
| connect(); | |
| }); | |