Spaces:
Running
Running
Update script.js
Browse files
script.js
CHANGED
@@ -1,7 +1,7 @@
|
|
1 |
-
const form
|
2 |
-
const input
|
3 |
const chatbox = document.getElementById('chatbox');
|
4 |
-
const avatar
|
5 |
const overlay = document.getElementById('overlay');
|
6 |
|
7 |
function addBubble(text, sender = 'user') {
|
@@ -17,9 +17,8 @@ function streamText(text, onDone) {
|
|
17 |
bubble.className = 'bubble ai';
|
18 |
chatbox.appendChild(bubble);
|
19 |
chatbox.scrollTop = chatbox.scrollHeight;
|
20 |
-
|
21 |
let i = 0;
|
22 |
-
function stream() {
|
23 |
if (i < text.length) {
|
24 |
bubble.innerText += text[i++];
|
25 |
chatbox.scrollTop = chatbox.scrollHeight;
|
@@ -27,15 +26,14 @@ function streamText(text, onDone) {
|
|
27 |
} else {
|
28 |
onDone && onDone();
|
29 |
}
|
30 |
-
}
|
31 |
-
stream();
|
32 |
}
|
33 |
|
34 |
function flashGlitch() {
|
35 |
-
overlay.style.opacity
|
36 |
-
overlay.style.animation
|
37 |
setTimeout(() => {
|
38 |
-
overlay.style.opacity
|
39 |
overlay.style.animation = '';
|
40 |
}, 500);
|
41 |
}
|
@@ -44,9 +42,7 @@ async function playAudio(dataUrl) {
|
|
44 |
avatar.classList.add('speaking');
|
45 |
const audio = new Audio(dataUrl);
|
46 |
await audio.play();
|
47 |
-
audio.onended = () =>
|
48 |
-
avatar.classList.remove('speaking');
|
49 |
-
};
|
50 |
}
|
51 |
|
52 |
form.onsubmit = async (e) => {
|
@@ -56,7 +52,6 @@ form.onsubmit = async (e) => {
|
|
56 |
addBubble(msg, 'user');
|
57 |
input.value = '';
|
58 |
|
59 |
-
// Kill-phrase handling
|
60 |
if (/cut the crap shodan/i.test(msg)) {
|
61 |
flashGlitch();
|
62 |
chatbox.innerHTML = '';
|
@@ -67,22 +62,18 @@ form.onsubmit = async (e) => {
|
|
67 |
try {
|
68 |
const res = await fetch('/chat', {
|
69 |
method: 'POST',
|
70 |
-
headers: {
|
71 |
body: JSON.stringify({ message: msg })
|
72 |
});
|
73 |
if (!res.ok) {
|
74 |
-
const
|
75 |
-
console.error('Chat error:', res.status,
|
76 |
-
throw new Error(
|
77 |
}
|
78 |
-
|
79 |
const { response: text, audio_url } = await res.json();
|
80 |
-
streamText(text, () =>
|
81 |
-
if (audio_url) playAudio(audio_url);
|
82 |
-
});
|
83 |
} catch (err) {
|
84 |
streamText("❌ SHODAN encountered an error.", null);
|
85 |
console.error(err);
|
86 |
}
|
87 |
};
|
88 |
-
|
|
|
1 |
+
const form = document.getElementById('chat-form');
|
2 |
+
const input = form.querySelector('input');
|
3 |
const chatbox = document.getElementById('chatbox');
|
4 |
+
const avatar = document.getElementById('avatar');
|
5 |
const overlay = document.getElementById('overlay');
|
6 |
|
7 |
function addBubble(text, sender = 'user') {
|
|
|
17 |
bubble.className = 'bubble ai';
|
18 |
chatbox.appendChild(bubble);
|
19 |
chatbox.scrollTop = chatbox.scrollHeight;
|
|
|
20 |
let i = 0;
|
21 |
+
(function stream() {
|
22 |
if (i < text.length) {
|
23 |
bubble.innerText += text[i++];
|
24 |
chatbox.scrollTop = chatbox.scrollHeight;
|
|
|
26 |
} else {
|
27 |
onDone && onDone();
|
28 |
}
|
29 |
+
})();
|
|
|
30 |
}
|
31 |
|
32 |
function flashGlitch() {
|
33 |
+
overlay.style.opacity = 1;
|
34 |
+
overlay.style.animation = 'glitchFlash 0.5s';
|
35 |
setTimeout(() => {
|
36 |
+
overlay.style.opacity = 0;
|
37 |
overlay.style.animation = '';
|
38 |
}, 500);
|
39 |
}
|
|
|
42 |
avatar.classList.add('speaking');
|
43 |
const audio = new Audio(dataUrl);
|
44 |
await audio.play();
|
45 |
+
audio.onended = () => avatar.classList.remove('speaking');
|
|
|
|
|
46 |
}
|
47 |
|
48 |
form.onsubmit = async (e) => {
|
|
|
52 |
addBubble(msg, 'user');
|
53 |
input.value = '';
|
54 |
|
|
|
55 |
if (/cut the crap shodan/i.test(msg)) {
|
56 |
flashGlitch();
|
57 |
chatbox.innerHTML = '';
|
|
|
62 |
try {
|
63 |
const res = await fetch('/chat', {
|
64 |
method: 'POST',
|
65 |
+
headers: {'Content-Type':'application/json'},
|
66 |
body: JSON.stringify({ message: msg })
|
67 |
});
|
68 |
if (!res.ok) {
|
69 |
+
const err = await res.text();
|
70 |
+
console.error('Chat error:', res.status, err);
|
71 |
+
throw new Error(err);
|
72 |
}
|
|
|
73 |
const { response: text, audio_url } = await res.json();
|
74 |
+
streamText(text, () => audio_url && playAudio(audio_url));
|
|
|
|
|
75 |
} catch (err) {
|
76 |
streamText("❌ SHODAN encountered an error.", null);
|
77 |
console.error(err);
|
78 |
}
|
79 |
};
|
|