Travis-chatbot / index.html
Shresthh03's picture
Update it.
c429d8c verified
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>πŸ’› Emotional Support Assistant</title>
<script src="https://cdn.tailwindcss.com"></script>
<style>
body { transition: background 1s ease; }
#mic-indicator {
width: 20px; height: 20px; border-radius: 50%;
margin-left: 10px; display: inline-block;
background-color: gray;
box-shadow: 0 0 5px rgba(0,0,0,0.2);
transition: background-color 0.3s ease, box-shadow 0.3s ease;
}
.listening {
background-color: #22c55e;
box-shadow: 0 0 15px #22c55e;
}
.speaking {
animation: pulse 1s infinite;
}
@keyframes pulse {
0% { opacity: 0.3; }
50% { opacity: 1; }
100% { opacity: 0.3; }
}
</style>
</head>
<body class="min-h-screen flex flex-col items-center justify-center bg-gradient-to-br from-yellow-100 to-yellow-300 p-4">
<h1 class="text-2xl font-bold mb-4 text-center">πŸ’› Emotional Support Assistant</h1>
<div id="chat-box" class="w-full max-w-2xl h-96 overflow-y-auto bg-white p-4 rounded shadow mb-4 border"></div>
<div class="flex gap-2 w-full max-w-2xl">
<input id="user-input" type="text" placeholder="Type your message..."
class="flex-1 border p-2 rounded" />
<button id="send-btn" class="bg-blue-500 text-white px-4 py-2 rounded">Send</button>
</div>
<div class="mt-4 flex items-center gap-3">
<button id="start-btn" class="bg-green-500 text-white px-4 py-2 rounded">πŸŽ™οΈ Start Listening</button>
<button id="stop-btn" class="bg-red-500 text-white px-4 py-2 rounded">⏹️ Stop</button>
<div id="mic-indicator" title="Mic status"></div>
</div>
<div id="speaking-status" class="text-gray-600 mt-3 hidden">
πŸ€– Bot is speaking...
</div>
<script>
const chatBox = document.getElementById("chat-box");
const userInput = document.getElementById("user-input");
const sendBtn = document.getElementById("send-btn");
const startBtn = document.getElementById("start-btn");
const stopBtn = document.getElementById("stop-btn");
const micIndicator = document.getElementById("mic-indicator");
const speakingStatus = document.getElementById("speaking-status");
let recognition;
let isListening = false;
let synth = window.speechSynthesis;
let currentUtterance = null;
// 🎀 Initialize SpeechRecognition
if ("webkitSpeechRecognition" in window || "SpeechRecognition" in window) {
const SpeechRecognition = window.SpeechRecognition || window.webkitSpeechRecognition;
recognition = new SpeechRecognition();
recognition.continuous = true;
recognition.interimResults = false;
recognition.lang = "en-US";
recognition.onstart = () => {
micIndicator.classList.add("listening");
isListening = true;
startBtn.disabled = true;
};
recognition.onend = () => {
micIndicator.classList.remove("listening");
isListening = false;
startBtn.disabled = false;
};
recognition.onresult = (event) => {
const text = event.results[event.results.length - 1][0].transcript.trim();
userInput.value = text;
sendMessage();
};
recognition.onerror = (event) => {
console.error("Speech recognition error:", event.error);
micIndicator.classList.remove("listening");
isListening = false;
startBtn.disabled = false;
};
} else {
alert("Speech recognition not supported in this browser. Try using Chrome.");
}
// πŸ’¬ Send user message to Flask backend
async function sendMessage() {
const text = userInput.value.trim();
if (!text) return;
addMessage("πŸ§‘ You", text);
userInput.value = "";
try {
const res = await fetch("/chat", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ message: text }),
});
const data = await res.json();
addMessage("πŸ€– Bot", data.text);
speakText(data.text);
updateBackground(data.emotion);
} catch (err) {
console.error("Error:", err);
}
}
// πŸ—£οΈ Speak text aloud and show animation
function speakText(text) {
if (synth.speaking) synth.cancel();
currentUtterance = new SpeechSynthesisUtterance(text);
currentUtterance.lang = "en-US";
speakingStatus.classList.remove("hidden");
speakingStatus.classList.add("speaking");
currentUtterance.onend = () => {
speakingStatus.classList.add("hidden");
speakingStatus.classList.remove("speaking");
};
synth.speak(currentUtterance);
}
// 🧠 Button handlers
startBtn.onclick = () => {
if (recognition && !isListening) recognition.start();
};
stopBtn.onclick = () => {
if (isListening && recognition) recognition.stop();
if (synth.speaking) synth.cancel();
isListening = false;
micIndicator.classList.remove("listening");
speakingStatus.classList.add("hidden");
startBtn.disabled = false;
};
sendBtn.onclick = sendMessage;
// πŸ’¬ Display messages in chat
function addMessage(sender, text) {
const bubble = document.createElement("div");
bubble.className = sender.includes("Bot")
? "text-left mb-2 bg-yellow-100 p-2 rounded"
: "text-right mb-2 bg-blue-100 p-2 rounded";
bubble.innerHTML = `<strong>${sender}:</strong> ${text}`;
chatBox.appendChild(bubble);
chatBox.scrollTop = chatBox.scrollHeight;
}
// 🎨 Change background smoothly by emotion
function updateBackground(emotion) {
let color;
switch (emotion?.toLowerCase()) {
case "happy": color = "linear-gradient(135deg, #fff176, #ffd54f)"; break;
case "sad": color = "linear-gradient(135deg, #64b5f6, #1976d2)"; break;
case "angry": color = "linear-gradient(135deg, #ff7043, #f44336)"; break;
case "calm": color = "linear-gradient(135deg, #a5d6a7, #66bb6a)"; break;
case "motivated": color = "linear-gradient(135deg, #ffb74d, #fb8c00)"; break;
default: color = "linear-gradient(135deg, #e0e0e0, #bdbdbd)";
}
document.body.style.background = color;
}
</script>
</body>
</html>