Spaces:
Running
Running
const form = document.getElementById('chat-form'); | |
const input = form.querySelector('input'); | |
const chatbox = document.getElementById('chatbox'); | |
const avatar = document.getElementById('avatar'); | |
const overlay = document.getElementById('overlay'); | |
function addBubble(text, sender = 'user') { | |
const bubble = document.createElement('div'); | |
bubble.className = 'bubble ' + sender; | |
bubble.innerText = text; | |
chatbox.appendChild(bubble); | |
chatbox.scrollTop = chatbox.scrollHeight; | |
} | |
function streamText(text, onDone) { | |
const bubble = document.createElement('div'); | |
bubble.className = 'bubble ai'; | |
chatbox.appendChild(bubble); | |
chatbox.scrollTop = chatbox.scrollHeight; | |
let i = 0; | |
function stream() { | |
if (i < text.length) { | |
bubble.innerText += text[i++]; | |
chatbox.scrollTop = chatbox.scrollHeight; | |
setTimeout(stream, 20); | |
} else { | |
onDone && onDone(); | |
} | |
} | |
stream(); | |
} | |
function playAudio(url) { | |
avatar.classList.add('speaking'); | |
const audio = new Audio(url); | |
audio.play(); | |
audio.onended = () => { | |
avatar.classList.remove('speaking'); | |
fetch(`/delete_audio?path=${encodeURIComponent(url)}`); | |
}; | |
} | |
form.onsubmit = async (e) => { | |
e.preventDefault(); | |
const msg = input.value.trim(); | |
if (!msg) return; | |
addBubble(msg, 'user'); | |
input.value = ''; | |
try { | |
const res = await fetch('/chat', { | |
method: 'POST', | |
headers: { 'Content-Type': 'application/json' }, | |
body: JSON.stringify({ message: msg }) | |
}); | |
if (!res.ok) { | |
// log the actual payload for debugging: | |
const text = await res.text(); | |
console.error('Chat error:', res.status, text); | |
throw new Error(`Status ${res.status}`); | |
} | |
const { response: text, audio_url } = await res.json(); | |
streamText(text, () => { | |
if (audio_url) playAudio(audio_url); | |
}); | |
} catch (err) { | |
streamText("❌ SHODAN encountered an error.", null); | |
console.error(err); | |
} | |
}; | |