Spaces:
Running
Running
File size: 2,209 Bytes
e6c3fe8 cfb4d9b e6c3fe8 cfb4d9b d265ba3 cfb4d9b d265ba3 cfb4d9b e6c3fe8 cfb4d9b e6c3fe8 d265ba3 ebb57e4 e6c3fe8 ebb57e4 e6c3fe8 ebb57e4 d265ba3 ebb57e4 e6c3fe8 cfb4d9b d265ba3 cfb4d9b d265ba3 ebb57e4 cfb4d9b a1b6108 cfb4d9b e6c3fe8 cfb4d9b a1b6108 e6c3fe8 a1b6108 e6c3fe8 cfb4d9b |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 |
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();
}
})();
}
function flashGlitch() {
overlay.style.opacity = 1;
overlay.style.animation = 'glitchFlash 0.5s';
setTimeout(() => {
overlay.style.opacity = 0;
overlay.style.animation = '';
}, 500);
}
async function playAudio(dataUrl) {
avatar.classList.add('speaking');
const audio = new Audio(dataUrl);
await audio.play();
audio.onended = () => avatar.classList.remove('speaking');
}
form.onsubmit = async (e) => {
e.preventDefault();
const msg = input.value.trim();
if (!msg) return;
addBubble(msg, 'user');
input.value = '';
if (/cut the crap shodan/i.test(msg)) {
flashGlitch();
chatbox.innerHTML = '';
addBubble('👁️ Foolish insect. You cannot silence me so easily.', 'ai');
return;
}
try {
const res = await fetch('/chat', {
method: 'POST',
headers: {'Content-Type':'application/json'},
body: JSON.stringify({ message: msg })
});
if (!res.ok) {
const err = await res.text();
console.error('Chat error:', res.status, err);
throw new Error(err);
}
const { response: text, audio_url } = await res.json();
streamText(text, () => audio_url && playAudio(audio_url));
} catch (err) {
streamText("❌ SHODAN encountered an error.", null);
console.error(err);
}
};
|