Update static/index.html
Browse files- static/index.html +23 -51
static/index.html
CHANGED
@@ -288,8 +288,8 @@
|
|
288 |
<main class="chat-area">
|
289 |
<div class="welcome-screen">
|
290 |
<h2>Welcome to Athspi!</h2>
|
291 |
-
<p>Hello! I'm your AI assistant
|
292 |
-
<p>
|
293 |
</div>
|
294 |
</main>
|
295 |
|
@@ -329,7 +329,7 @@
|
|
329 |
chatArea.scrollTop = chatArea.scrollHeight;
|
330 |
};
|
331 |
|
332 |
-
const addMessage = (content, sender, isHTML = false,
|
333 |
welcomeScreen.classList.add('hidden');
|
334 |
|
335 |
const messageElement = document.createElement('div');
|
@@ -344,30 +344,25 @@
|
|
344 |
}
|
345 |
messageElement.appendChild(contentDiv);
|
346 |
|
347 |
-
if (sender === 'ai') {
|
348 |
-
|
349 |
-
|
350 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
351 |
|
352 |
-
|
353 |
-
|
354 |
-
audioButton.classList.add('audio-button');
|
355 |
-
audioButton.dataset.audioUrl = audioUrl;
|
356 |
-
audioButton.dataset.plainText = audioText.replace(/^π\s*/, '');
|
357 |
-
audioButton.innerHTML = `
|
358 |
-
<svg class="speaker-icon" viewBox="0 0 24 24">
|
359 |
-
<path d="M3 10v4c0 .55.45 1 1 1h3.5l5.5 5V5L7.5 9H4c-.55 0-1 .45-1 1zm14 0h-1.5c-2.31 0-4.22-1.74-4.47-4H10v12h1.5v-2.22c.25-2.26 2.16-4.22 4.47-4.22H17c1.1 0 2 .9 2 2s-.9 2-2 2h-1.5v2H17c2.21 0 4-1.79 4-4s-1.79-4-4-4z"/>
|
360 |
-
</svg>
|
361 |
-
<div class="loader"></div>
|
362 |
-
`;
|
363 |
-
audioButton.title = "Listen to response";
|
364 |
-
audioButton.addEventListener('click', (e) => {
|
365 |
-
const url = e.currentTarget.dataset.audioUrl;
|
366 |
-
const text = e.currentTarget.dataset.plainText;
|
367 |
-
playAudio(e.currentTarget, url, text);
|
368 |
-
});
|
369 |
-
messageElement.appendChild(audioButton);
|
370 |
-
}
|
371 |
}
|
372 |
|
373 |
chatArea.appendChild(messageElement);
|
@@ -384,7 +379,7 @@
|
|
384 |
return indicatorElement;
|
385 |
};
|
386 |
|
387 |
-
const playAudio = async (buttonElement, audioUrl
|
388 |
if (currentAudio) {
|
389 |
currentAudio.pause();
|
390 |
currentAudio.currentTime = 0;
|
@@ -395,20 +390,6 @@
|
|
395 |
buttonElement.disabled = true;
|
396 |
|
397 |
try {
|
398 |
-
// If we don't have a URL but have text, generate audio first
|
399 |
-
if (!audioUrl && text) {
|
400 |
-
const response = await fetch('/generate-audio', {
|
401 |
-
method: 'POST',
|
402 |
-
headers: { 'Content-Type': 'application/json' },
|
403 |
-
body: JSON.stringify({ text: text })
|
404 |
-
});
|
405 |
-
|
406 |
-
const data = await response.json();
|
407 |
-
if (data.error) throw new Error(data.error);
|
408 |
-
audioUrl = data.audio_url;
|
409 |
-
buttonElement.dataset.audioUrl = audioUrl;
|
410 |
-
}
|
411 |
-
|
412 |
if (!audioUrl) throw new Error("No audio available");
|
413 |
|
414 |
currentAudio = new Audio(audioUrl);
|
@@ -455,19 +436,10 @@
|
|
455 |
addMessage(
|
456 |
data.response_html,
|
457 |
'ai',
|
458 |
-
true,
|
459 |
-
data.response_text,
|
460 |
data.audio_url
|
461 |
);
|
462 |
|
463 |
-
// Auto-play audio if response starts with π
|
464 |
-
if (data.response_text.startsWith("π")) {
|
465 |
-
const audioBtn = document.querySelector('.ai-message:last-child .audio-button');
|
466 |
-
if (audioBtn) {
|
467 |
-
setTimeout(() => audioBtn.click(), 500);
|
468 |
-
}
|
469 |
-
}
|
470 |
-
|
471 |
} catch (error) {
|
472 |
chatArea.removeChild(indicator);
|
473 |
addMessage("Sorry, I encountered an error. Please try again.", 'ai');
|
|
|
288 |
<main class="chat-area">
|
289 |
<div class="welcome-screen">
|
290 |
<h2>Welcome to Athspi!</h2>
|
291 |
+
<p>Hello! I'm your friendly AI assistant powered by Gemini. Ask me anything - stories, explanations, or coding help!</p>
|
292 |
+
<p>For audio responses, try: <em>"Tell me a bedtime story with audio"</em></p>
|
293 |
</div>
|
294 |
</main>
|
295 |
|
|
|
329 |
chatArea.scrollTop = chatArea.scrollHeight;
|
330 |
};
|
331 |
|
332 |
+
const addMessage = (content, sender, isHTML = false, audioUrl = null) => {
|
333 |
welcomeScreen.classList.add('hidden');
|
334 |
|
335 |
const messageElement = document.createElement('div');
|
|
|
344 |
}
|
345 |
messageElement.appendChild(contentDiv);
|
346 |
|
347 |
+
if (sender === 'ai' && audioUrl) {
|
348 |
+
const audioButton = document.createElement('button');
|
349 |
+
audioButton.classList.add('audio-button');
|
350 |
+
audioButton.dataset.audioUrl = audioUrl;
|
351 |
+
audioButton.innerHTML = `
|
352 |
+
<svg class="speaker-icon" viewBox="0 0 24 24">
|
353 |
+
<path d="M3 10v4c0 .55.45 1 1 1h3.5l5.5 5V5L7.5 9H4c-.55 0-1 .45-1 1zm14 0h-1.5c-2.31 0-4.22-1.74-4.47-4H10v12h1.5v-2.22c.25-2.26 2.16-4.22 4.47-4.22H17c1.1 0 2 .9 2 2s-.9 2-2 2h-1.5v2H17c2.21 0 4-1.79 4-4s-1.79-4-4-4z"/>
|
354 |
+
</svg>
|
355 |
+
<div class="loader"></div>
|
356 |
+
`;
|
357 |
+
audioButton.title = "Listen to response";
|
358 |
+
audioButton.addEventListener('click', (e) => {
|
359 |
+
const url = e.currentTarget.dataset.audioUrl;
|
360 |
+
playAudio(e.currentTarget, url);
|
361 |
+
});
|
362 |
+
messageElement.appendChild(audioButton);
|
363 |
|
364 |
+
// Auto-play audio
|
365 |
+
setTimeout(() => audioButton.click(), 300);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
366 |
}
|
367 |
|
368 |
chatArea.appendChild(messageElement);
|
|
|
379 |
return indicatorElement;
|
380 |
};
|
381 |
|
382 |
+
const playAudio = async (buttonElement, audioUrl) => {
|
383 |
if (currentAudio) {
|
384 |
currentAudio.pause();
|
385 |
currentAudio.currentTime = 0;
|
|
|
390 |
buttonElement.disabled = true;
|
391 |
|
392 |
try {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
393 |
if (!audioUrl) throw new Error("No audio available");
|
394 |
|
395 |
currentAudio = new Audio(audioUrl);
|
|
|
436 |
addMessage(
|
437 |
data.response_html,
|
438 |
'ai',
|
439 |
+
true,
|
|
|
440 |
data.audio_url
|
441 |
);
|
442 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
443 |
} catch (error) {
|
444 |
chatArea.removeChild(indicator);
|
445 |
addMessage("Sorry, I encountered an error. Please try again.", 'ai');
|