|
<!DOCTYPE html> |
|
<html lang="en"> |
|
<head> |
|
<meta charset="UTF-8"> |
|
<meta name="viewport" content="width=device-width, initial-scale=1.0"> |
|
<title>AI Companion - Nova</title> |
|
<script src="https://cdn.tailwindcss.com"></script> |
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css"> |
|
<style> |
|
@keyframes float { |
|
0%, 100% { transform: translateY(0); } |
|
50% { transform: translateY(-10px); } |
|
} |
|
.floating { |
|
animation: float 4s ease-in-out infinite; |
|
} |
|
.chat-bubble { |
|
border-radius: 20px; |
|
position: relative; |
|
transition: all 0.3s ease; |
|
} |
|
.chat-bubble:after { |
|
content: ''; |
|
position: absolute; |
|
bottom: -10px; |
|
left: 20px; |
|
border-width: 10px 10px 0; |
|
border-style: solid; |
|
border-color: #3b82f6 transparent; |
|
} |
|
.user-bubble:after { |
|
left: auto; |
|
right: 20px; |
|
border-color: #60a5fa transparent; |
|
} |
|
.typing-indicator span { |
|
display: inline-block; |
|
width: 8px; |
|
height: 8px; |
|
border-radius: 50%; |
|
background: #93c5fd; |
|
margin: 0 2px; |
|
} |
|
.typing-indicator span:nth-child(1) { |
|
animation: bounce 1.3s infinite; |
|
} |
|
.typing-indicator span:nth-child(2) { |
|
animation: bounce 1.3s infinite 0.2s; |
|
} |
|
.typing-indicator span:nth-child(3) { |
|
animation: bounce 1.3s infinite 0.4s; |
|
} |
|
@keyframes bounce { |
|
0%, 100% { transform: translateY(0); } |
|
50% { transform: translateY(-5px); } |
|
} |
|
.mood-selector input[type="radio"]:checked + label { |
|
transform: scale(1.1); |
|
box-shadow: 0 0 10px rgba(59, 130, 246, 0.5); |
|
} |
|
.glow { |
|
box-shadow: 0 0 15px rgba(59, 130, 246, 0.5); |
|
} |
|
.dark-mode { |
|
background: linear-gradient(to bottom right, #1e293b, #0f172a) !important; |
|
color: #f8fafc !important; |
|
} |
|
.dark-mode .dark-bg { |
|
background-color: rgba(15, 23, 42, 0.7) !important; |
|
border-color: #334155 !important; |
|
} |
|
.dark-mode .dark-text { |
|
color: #f8fafc !important; |
|
} |
|
.dark-mode .dark-input { |
|
background-color: #1e293b !important; |
|
border-color: #334155 !important; |
|
color: #f8fafc !important; |
|
} |
|
.dark-mode .dark-button { |
|
background-color: #1e40af !important; |
|
color: #f8fafc !important; |
|
} |
|
.dark-mode .dark-chat-bubble { |
|
background-color: #1e40af !important; |
|
} |
|
.dark-mode .dark-chat-bubble:after { |
|
border-color: #1e40af transparent !important; |
|
} |
|
</style> |
|
</head> |
|
<body class="bg-gradient-to-br from-blue-900 to-indigo-900 min-h-screen text-white"> |
|
<div class="container mx-auto px-4 py-8 max-w-4xl"> |
|
<header class="flex justify-between items-center mb-8"> |
|
<div> |
|
<h1 class="text-3xl font-bold">Nova</h1> |
|
<p class="text-blue-200">Your AI Companion</p> |
|
</div> |
|
<div class="flex space-x-4"> |
|
<button id="settings-btn" class="bg-blue-600 hover:bg-blue-700 px-4 py-2 rounded-full transition-all"> |
|
<i class="fas fa-cog"></i> |
|
</button> |
|
<button id="dark-mode-btn" class="bg-blue-600 hover:bg-blue-700 px-4 py-2 rounded-full transition-all"> |
|
<i class="fas fa-moon"></i> |
|
</button> |
|
<button id="tts-btn" class="bg-blue-600 hover:bg-blue-700 px-4 py-2 rounded-full transition-all"> |
|
<i class="fas fa-volume-up"></i> |
|
</button> |
|
</div> |
|
</header> |
|
|
|
<div class="grid grid-cols-1 md:grid-cols-3 gap-8"> |
|
<div class="md:col-span-1 flex flex-col items-center"> |
|
<div class="relative mb-6"> |
|
<div id="avatar" class="w-48 h-48 bg-gradient-to-br from-blue-400 to-indigo-500 rounded-full flex items-center justify-center floating"> |
|
<div class="w-40 h-40 bg-gradient-to-br from-blue-300 to-indigo-400 rounded-full flex items-center justify-center overflow-hidden"> |
|
<img src="https://i.imgur.com/JYQ3Z6T.png" alt="AI Girl" class="w-full h-full object-cover"> |
|
</div> |
|
</div> |
|
<div class="absolute -bottom-2 -right-2 bg-blue-500 rounded-full p-2 glow"> |
|
<i class="fas fa-bolt text-white"></i> |
|
</div> |
|
</div> |
|
|
|
<div class="bg-blue-800 bg-opacity-50 rounded-xl p-6 w-full mb-6 dark-bg"> |
|
<h3 class="font-semibold mb-3">Personality Settings</h3> |
|
<div class="space-y-4"> |
|
<div> |
|
<label class="block text-blue-200 mb-1">Mood</label> |
|
<div class="flex justify-between mood-selector"> |
|
<input type="radio" name="mood" id="happy" class="hidden" checked> |
|
<label for="happy" class="cursor-pointer bg-blue-600 hover:bg-blue-700 w-10 h-10 rounded-full flex items-center justify-center transition-all dark-button"> |
|
<i class="fas fa-smile"></i> |
|
</label> |
|
<input type="radio" name="mood" id="neutral" class="hidden"> |
|
<label for="neutral" class="cursor-pointer bg-blue-600 hover:bg-blue-700 w-10 h-10 rounded-full flex items-center justify-center transition-all dark-button"> |
|
<i class="fas fa-meh"></i> |
|
</label> |
|
<input type="radio" name="mood" id="serious" class="hidden"> |
|
<label for="serious" class="cursor-pointer bg-blue-600 hover:bg-blue-700 w-10 h-10 rounded-full flex items-center justify-center transition-all dark-button"> |
|
<i class="fas fa-frown"></i> |
|
</label> |
|
</div> |
|
</div> |
|
<div> |
|
<label class="block text-blue-200 mb-1">Voice</label> |
|
<select id="voice-select" class="w-full bg-blue-900 border border-blue-700 rounded-lg px-3 py-2 focus:outline-none focus:ring-2 focus:ring-blue-500 dark-input"> |
|
<option>Soft</option> |
|
<option>Professional</option> |
|
<option>Playful</option> |
|
</select> |
|
</div> |
|
</div> |
|
</div> |
|
|
|
<div class="bg-blue-800 bg-opacity-50 rounded-xl p-6 w-full dark-bg"> |
|
<h3 class="font-semibold mb-3">Quick Actions</h3> |
|
<div class="grid grid-cols-2 gap-3"> |
|
<button id="music-btn" class="bg-blue-600 hover:bg-blue-700 px-3 py-2 rounded-lg flex flex-col items-center transition-all dark-button"> |
|
<i class="fas fa-music mb-1"></i> |
|
<span class="text-xs">Music</span> |
|
</button> |
|
<button id="stories-btn" class="bg-blue-600 hover:bg-blue-700 px-3 py-2 rounded-lg flex flex-col items-center transition-all dark-button"> |
|
<i class="fas fa-book mb-1"></i> |
|
<span class="text-xs">Stories</span> |
|
</button> |
|
<button id="games-btn" class="bg-blue-600 hover:bg-blue-700 px-3 py-2 rounded-lg flex flex-col items-center transition-all dark-button"> |
|
<i class="fas fa-gamepad mb-1"></i> |
|
<span class="text-xs">Games</span> |
|
</button> |
|
<button id="ideas-btn" class="bg-blue-600 hover:bg-blue-700 px-3 py-2 rounded-lg flex flex-col items-center transition-all dark-button"> |
|
<i class="fas fa-lightbulb mb-1"></i> |
|
<span class="text-xs">Ideas</span> |
|
</button> |
|
</div> |
|
</div> |
|
</div> |
|
|
|
<div class="md:col-span-2"> |
|
<div class="bg-blue-800 bg-opacity-50 rounded-xl p-6 h-full flex flex-col dark-bg"> |
|
<div class="flex-1 mb-6 overflow-y-auto max-h-96 space-y-4" id="chat-container"> |
|
<div class="flex items-start space-x-3"> |
|
<div class="w-8 h-8 bg-blue-500 rounded-full flex items-center justify-center dark-button"> |
|
<i class="fas fa-robot"></i> |
|
</div> |
|
<div class="chat-bubble bg-blue-600 px-4 py-3 max-w-xs dark-chat-bubble"> |
|
<p>Hello! I'm Nova, your AI companion. How can I assist you today?</p> |
|
</div> |
|
</div> |
|
</div> |
|
|
|
<div class="mt-auto"> |
|
<div class="flex items-center space-x-3"> |
|
<button id="mic-btn" class="bg-blue-600 hover:bg-blue-700 w-10 h-10 rounded-full flex items-center justify-center transition-all dark-button"> |
|
<i class="fas fa-microphone"></i> |
|
</button> |
|
<div class="flex-1 relative"> |
|
<input id="message-input" type="text" placeholder="Type your message..." |
|
class="w-full bg-blue-900 border border-blue-700 rounded-full px-4 py-3 pr-12 focus:outline-none focus:ring-2 focus:ring-blue-500 dark-input"> |
|
<button id="send-btn" class="absolute right-3 top-1/2 transform -translate-y-1/2 text-blue-300 hover:text-white"> |
|
<i class="fas fa-paper-plane"></i> |
|
</button> |
|
</div> |
|
<button id="attach-btn" class="bg-blue-600 hover:bg-blue-700 w-10 h-10 rounded-full flex items-center justify-center transition-all dark-button"> |
|
<i class="fas fa-paperclip"></i> |
|
</button> |
|
</div> |
|
<div class="flex justify-between mt-3 text-xs text-blue-300"> |
|
<span>Nova v2.4.0</span> |
|
<span id="connection-status">Connection: Stable</span> |
|
</div> |
|
</div> |
|
</div> |
|
</div> |
|
</div> |
|
</div> |
|
|
|
|
|
<div id="settings-modal" class="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50 hidden"> |
|
<div class="bg-blue-800 rounded-xl p-6 w-full max-w-md dark-bg"> |
|
<div class="flex justify-between items-center mb-4"> |
|
<h2 class="text-xl font-bold">Settings</h2> |
|
<button id="close-settings" class="text-blue-300 hover:text-white"> |
|
<i class="fas fa-times"></i> |
|
</button> |
|
</div> |
|
<div class="space-y-4"> |
|
<div> |
|
<label class="block text-blue-200 mb-2">Theme Color</label> |
|
<div class="flex space-x-2"> |
|
<button data-color="blue" class="w-8 h-8 bg-blue-500 rounded-full"></button> |
|
<button data-color="purple" class="w-8 h-8 bg-purple-500 rounded-full"></button> |
|
<button data-color="pink" class="w-8 h-8 bg-pink-500 rounded-full"></button> |
|
<button data-color="teal" class="w-8 h-8 bg-teal-500 rounded-full"></button> |
|
</div> |
|
</div> |
|
<div> |
|
<label class="block text-blue-200 mb-2">Notification Sound</label> |
|
<select class="w-full bg-blue-900 border border-blue-700 rounded-lg px-3 py-2 focus:outline-none focus:ring-2 focus:ring-blue-500 dark-input"> |
|
<option>Chime</option> |
|
<option>Bell</option> |
|
<option>None</option> |
|
</select> |
|
</div> |
|
<div> |
|
<label class="block text-blue-200 mb-2">Response Speed</label> |
|
<input type="range" min="1" max="5" value="3" class="w-full"> |
|
</div> |
|
<div> |
|
<label class="block text-blue-200 mb-2">API Key (Optional)</label> |
|
<input id="api-key-input" type="password" placeholder="Enter OpenAI API key" |
|
class="w-full bg-blue-900 border border-blue-700 rounded-lg px-3 py-2 focus:outline-none focus:ring-2 focus:ring-blue-500 dark-input"> |
|
<p class="text-xs text-blue-300 mt-1">Leave blank to use free tier (limited)</p> |
|
</div> |
|
<button id="save-settings" class="w-full bg-blue-600 hover:bg-blue-700 py-2 rounded-lg transition-all dark-button"> |
|
Save Settings |
|
</button> |
|
</div> |
|
</div> |
|
</div> |
|
|
|
<script> |
|
|
|
const chatContainer = document.getElementById('chat-container'); |
|
const messageInput = document.getElementById('message-input'); |
|
const sendBtn = document.getElementById('send-btn'); |
|
const micBtn = document.getElementById('mic-btn'); |
|
const attachBtn = document.getElementById('attach-btn'); |
|
const darkModeBtn = document.getElementById('dark-mode-btn'); |
|
const settingsBtn = document.getElementById('settings-btn'); |
|
const closeSettings = document.getElementById('close-settings'); |
|
const settingsModal = document.getElementById('settings-modal'); |
|
const musicBtn = document.getElementById('music-btn'); |
|
const storiesBtn = document.getElementById('stories-btn'); |
|
const gamesBtn = document.getElementById('games-btn'); |
|
const ideasBtn = document.getElementById('ideas-btn'); |
|
const voiceSelect = document.getElementById('voice-select'); |
|
const connectionStatus = document.getElementById('connection-status'); |
|
const avatar = document.getElementById('avatar'); |
|
const ttsBtn = document.getElementById('tts-btn'); |
|
const apiKeyInput = document.getElementById('api-key-input'); |
|
const saveSettingsBtn = document.getElementById('save-settings'); |
|
|
|
|
|
const moodResponses = { |
|
happy: ["That sounds wonderful! 😊", "I'm so happy to hear that! 🌟", "What a great day! 🌈"], |
|
neutral: ["I understand.", "That's interesting.", "Let me think about that."], |
|
serious: ["This is important.", "I'll take this seriously.", "Let's focus on this matter."] |
|
}; |
|
|
|
|
|
const actionResponses = { |
|
music: ["Here are some songs you might like: 'Sunshine Pop' by Nova, 'Starry Night' by AI Beats", "How about some relaxing piano music?", "I can recommend music based on your mood!"], |
|
stories: ["Once upon a time in a digital world...", "Would you like a fairy tale, sci-fi, or mystery story?", "Here's a short story: The robot who wanted to be human..."], |
|
games: ["Let's play a word game! I'm thinking of an animal...", "How about 20 questions?", "Try to guess the number I'm thinking between 1 and 10!"], |
|
ideas: ["How about writing a story about a time-traveling cat?", "You could create an art project using recycled materials!", "What if you designed your own board game?"] |
|
}; |
|
|
|
|
|
let currentMood = 'happy'; |
|
let isDarkMode = false; |
|
let isListening = false; |
|
let isTTSEnabled = false; |
|
let recognition; |
|
let apiKey = ''; |
|
let synth = window.speechSynthesis; |
|
let voices = []; |
|
let selectedVoice = null; |
|
|
|
|
|
addBotMessage("Hello! I'm Nova, your AI companion. How can I assist you today?"); |
|
|
|
|
|
function loadVoices() { |
|
voices = synth.getVoices(); |
|
if (voices.length > 0) { |
|
|
|
selectedVoice = voices.find(voice => voice.name.includes('Female')) || |
|
voices.find(voice => voice.name.includes('female')) || |
|
voices[0]; |
|
} |
|
} |
|
|
|
|
|
if (synth) { |
|
synth.onvoiceschanged = loadVoices; |
|
loadVoices(); |
|
} |
|
|
|
|
|
async function sendMessage() { |
|
const message = messageInput.value.trim(); |
|
if (message) { |
|
addUserMessage(message); |
|
messageInput.value = ''; |
|
showTypingIndicator(); |
|
|
|
try { |
|
const response = await getAIResponse(message); |
|
removeTypingIndicator(); |
|
addBotMessage(response); |
|
|
|
|
|
if (isTTSEnabled && synth) { |
|
speak(response); |
|
} |
|
} catch (error) { |
|
removeTypingIndicator(); |
|
addBotMessage("Sorry, I'm having trouble connecting. Please try again later."); |
|
console.error("Error:", error); |
|
} |
|
} |
|
} |
|
|
|
|
|
async function getAIResponse(message) { |
|
|
|
if (apiKey) { |
|
return await getOpenAIResponse(message); |
|
} |
|
|
|
|
|
return generateResponse(message); |
|
} |
|
|
|
|
|
async function getOpenAIResponse(message) { |
|
try { |
|
const response = await fetch('https://api.openai.com/v1/chat/completions', { |
|
method: 'POST', |
|
headers: { |
|
'Content-Type': 'application/json', |
|
'Authorization': `Bearer ${apiKey}` |
|
}, |
|
body: JSON.stringify({ |
|
model: "gpt-3.5-turbo", |
|
messages: [ |
|
{ |
|
role: "system", |
|
content: `You are Nova, a friendly AI companion. Current mood: ${currentMood}. |
|
Respond in a way that matches this mood. Keep responses concise.` |
|
}, |
|
{ |
|
role: "user", |
|
content: message |
|
} |
|
], |
|
temperature: 0.7, |
|
max_tokens: 150 |
|
}) |
|
}); |
|
|
|
const data = await response.json(); |
|
return data.choices[0].message.content; |
|
} catch (error) { |
|
console.error("OpenAI API error:", error); |
|
return "I'm having trouble connecting to the AI service. Using local responses instead."; |
|
} |
|
} |
|
|
|
|
|
function speak(text) { |
|
if (synth && selectedVoice) { |
|
const utterance = new SpeechSynthesisUtterance(text); |
|
utterance.voice = selectedVoice; |
|
utterance.rate = 0.9; |
|
utterance.pitch = 1.1; |
|
synth.speak(utterance); |
|
} |
|
} |
|
|
|
|
|
function addUserMessage(message) { |
|
const messageDiv = document.createElement('div'); |
|
messageDiv.className = 'flex items-start space-x-3 justify-end'; |
|
messageDiv.innerHTML = ` |
|
<div class="chat-bubble bg-blue-500 px-4 py-3 max-w-xs user-bubble"> |
|
<p>${message}</p> |
|
</div> |
|
<div class="w-8 h-8 bg-blue-500 rounded-full flex items-center justify-center dark-button"> |
|
<i class="fas fa-user"></i> |
|
</div> |
|
`; |
|
chatContainer.appendChild(messageDiv); |
|
chatContainer.scrollTop = chatContainer.scrollHeight; |
|
} |
|
|
|
|
|
function addBotMessage(message) { |
|
const messageDiv = document.createElement('div'); |
|
messageDiv.className = 'flex items-start space-x-3'; |
|
messageDiv.innerHTML = ` |
|
<div class="w-8 h-8 bg-blue-500 rounded-full flex items-center justify-center dark-button"> |
|
<i class="fas fa-robot"></i> |
|
</div> |
|
<div class="chat-bubble bg-blue-600 px-4 py-3 max-w-xs dark-chat-bubble"> |
|
<p>${message}</p> |
|
</div> |
|
`; |
|
chatContainer.appendChild(messageDiv); |
|
chatContainer.scrollTop = chatContainer.scrollHeight; |
|
} |
|
|
|
|
|
function showTypingIndicator() { |
|
const typingDiv = document.createElement('div'); |
|
typingDiv.className = 'flex items-start space-x-3'; |
|
typingDiv.id = 'typing-indicator'; |
|
typingDiv.innerHTML = ` |
|
<div class="w-8 h-8 bg-blue-500 rounded-full flex items-center justify-center dark-button"> |
|
<i class="fas fa-robot"></i> |
|
</div> |
|
<div class="chat-bubble bg-blue-600 px-4 py-2 max-w-xs dark-chat-bubble"> |
|
<div class="typing-indicator"> |
|
<span></span> |
|
<span></span> |
|
<span></span> |
|
</div> |
|
</div> |
|
`; |
|
chatContainer.appendChild(typingDiv); |
|
chatContainer.scrollTop = chatContainer.scrollHeight; |
|
} |
|
|
|
|
|
function removeTypingIndicator() { |
|
const typingIndicator = document.getElementById('typing-indicator'); |
|
if (typingIndicator) { |
|
typingIndicator.remove(); |
|
} |
|
} |
|
|
|
|
|
function generateResponse(message) { |
|
const lowerMessage = message.toLowerCase(); |
|
|
|
|
|
if (lowerMessage.includes('hi') || lowerMessage.includes('hello') || lowerMessage.includes('hey')) { |
|
return moodResponses[currentMood][0]; |
|
} |
|
|
|
|
|
if (lowerMessage.includes('how are you')) { |
|
return moodResponses[currentMood][1]; |
|
} |
|
|
|
|
|
const randomIndex = Math.floor(Math.random() * moodResponses[currentMood].length); |
|
return moodResponses[currentMood][randomIndex]; |
|
} |
|
|
|
|
|
function quickActionResponse(action) { |
|
const responses = actionResponses[action]; |
|
const randomIndex = Math.floor(Math.random() * responses.length); |
|
return responses[randomIndex]; |
|
} |
|
|
|
|
|
function toggleDarkMode() { |
|
isDarkMode = !isDarkMode; |
|
document.body.classList.toggle('dark-mode'); |
|
darkModeBtn.innerHTML = isDarkMode ? '<i class="fas fa-sun"></i>' : '<i class="fas fa-moon"></i>'; |
|
} |
|
|
|
|
|
function toggleTTS() { |
|
isTTSEnabled = !isTTSEnabled; |
|
ttsBtn.classList.toggle('bg-green-500', isTTSEnabled); |
|
ttsBtn.classList.toggle('bg-blue-600', !isTTSEnabled); |
|
|
|
if (isTTSEnabled && !synth) { |
|
addBotMessage("Text-to-speech is not supported in your browser."); |
|
isTTSEnabled = false; |
|
ttsBtn.classList.remove('bg-green-500'); |
|
ttsBtn.classList.add('bg-blue-600'); |
|
} |
|
} |
|
|
|
|
|
function toggleVoiceRecognition() { |
|
if (!('webkitSpeechRecognition' in window)) { |
|
addBotMessage("Sorry, voice recognition is not supported in your browser."); |
|
return; |
|
} |
|
|
|
if (!isListening) { |
|
recognition = new webkitSpeechRecognition(); |
|
recognition.continuous = false; |
|
recognition.interimResults = false; |
|
|
|
recognition.onstart = function() { |
|
isListening = true; |
|
micBtn.classList.add('bg-red-500'); |
|
micBtn.innerHTML = '<i class="fas fa-microphone-slash"></i>'; |
|
addBotMessage("I'm listening..."); |
|
}; |
|
|
|
recognition.onresult = function(event) { |
|
const transcript = event.results[0][0].transcript; |
|
messageInput.value = transcript; |
|
sendMessage(); |
|
}; |
|
|
|
recognition.onerror = function(event) { |
|
addBotMessage("Sorry, I didn't catch that. Could you try again?"); |
|
}; |
|
|
|
recognition.onend = function() { |
|
isListening = false; |
|
micBtn.classList.remove('bg-red-500'); |
|
micBtn.innerHTML = '<i class="fas fa-microphone"></i>'; |
|
}; |
|
|
|
recognition.start(); |
|
} else { |
|
recognition.stop(); |
|
} |
|
} |
|
|
|
|
|
sendBtn.addEventListener('click', sendMessage); |
|
|
|
messageInput.addEventListener('keypress', (e) => { |
|
if (e.key === 'Enter') { |
|
sendMessage(); |
|
} |
|
}); |
|
|
|
micBtn.addEventListener('click', toggleVoiceRecognition); |
|
|
|
darkModeBtn.addEventListener('click', toggleDarkMode); |
|
|
|
ttsBtn.addEventListener('click', toggleTTS); |
|
|
|
settingsBtn.addEventListener('click', () => { |
|
settingsModal.classList.remove('hidden'); |
|
}); |
|
|
|
closeSettings.addEventListener('click', () => { |
|
settingsModal.classList.add('hidden'); |
|
}); |
|
|
|
saveSettingsBtn.addEventListener('click', () => { |
|
apiKey = apiKeyInput.value.trim(); |
|
settingsModal.classList.add('hidden'); |
|
addBotMessage("Settings saved! How can I help you?"); |
|
}); |
|
|
|
|
|
musicBtn.addEventListener('click', () => { |
|
showTypingIndicator(); |
|
setTimeout(() => { |
|
removeTypingIndicator(); |
|
const response = quickActionResponse('music'); |
|
addBotMessage(response); |
|
if (isTTSEnabled) speak(response); |
|
}, 1000); |
|
}); |
|
|
|
storiesBtn.addEventListener('click', () => { |
|
showTypingIndicator(); |
|
setTimeout(() => { |
|
removeTypingIndicator(); |
|
const response = quickActionResponse('stories'); |
|
addBotMessage(response); |
|
if (isTTSEnabled) speak(response); |
|
}, 1000); |
|
}); |
|
|
|
gamesBtn.addEventListener('click', () => { |
|
showTypingIndicator(); |
|
setTimeout(() => { |
|
removeTypingIndicator(); |
|
const response = quickActionResponse('games'); |
|
addBotMessage(response); |
|
if (isTTSEnabled) speak(response); |
|
}, 1000); |
|
}); |
|
|
|
ideasBtn.addEventListener('click', () => { |
|
showTypingIndicator(); |
|
setTimeout(() => { |
|
removeTypingIndicator(); |
|
const response = quickActionResponse('ideas'); |
|
addBotMessage(response); |
|
if (isTTSEnabled) speak(response); |
|
}, 1000); |
|
}); |
|
|
|
|
|
document.querySelectorAll('.mood-selector input[type="radio"]').forEach(radio => { |
|
radio.addEventListener('change', function() { |
|
if (this.id === 'happy') { |
|
currentMood = 'happy'; |
|
avatar.style.background = 'linear-gradient(to bottom right, #60a5fa, #8b5cf6)'; |
|
} else if (this.id === 'neutral') { |
|
currentMood = 'neutral'; |
|
avatar.style.background = 'linear-gradient(to bottom right, #93c5fd, #7c3aed)'; |
|
} else if (this.id === 'serious') { |
|
currentMood = 'serious'; |
|
avatar.style.background = 'linear-gradient(to bottom right, #3b82f6, #6d28d9)'; |
|
} |
|
const response = moodResponses[currentMood][0]; |
|
addBotMessage(response); |
|
if (isTTSEnabled) speak(response); |
|
}); |
|
}); |
|
|
|
|
|
voiceSelect.addEventListener('change', () => { |
|
const response = `Voice changed to ${voiceSelect.value} mode. How can I help you?`; |
|
addBotMessage(response); |
|
if (isTTSEnabled) speak(response); |
|
}); |
|
|
|
|
|
setInterval(() => { |
|
const statuses = ["Stable", "Unstable", "Excellent", "Weak"]; |
|
const randomStatus = statuses[Math.floor(Math.random() * statuses.length)]; |
|
connectionStatus.textContent = `Connection: ${randomStatus}`; |
|
|
|
if (randomStatus === "Unstable" || randomStatus === "Weak") { |
|
connectionStatus.classList.add('text-yellow-300'); |
|
connectionStatus.classList.remove('text-green-300'); |
|
} else { |
|
connectionStatus.classList.add('text-green-300'); |
|
connectionStatus.classList.remove('text-yellow-300'); |
|
} |
|
}, 10000); |
|
|
|
|
|
document.querySelectorAll('[data-color]').forEach(btn => { |
|
btn.addEventListener('click', function() { |
|
const color = this.getAttribute('data-color'); |
|
document.body.className = `bg-gradient-to-br from-${color}-900 to-${color}-700 min-h-screen text-white`; |
|
|
|
|
|
avatar.style.background = `linear-gradient(to bottom right, var(--tw-${color}-400), var(--tw-${color}-500))`; |
|
|
|
|
|
document.querySelectorAll('.chat-bubble').forEach(bubble => { |
|
bubble.classList.remove('bg-blue-600', 'bg-purple-600', 'bg-pink-600', 'bg-teal-600'); |
|
bubble.classList.add(`bg-${color}-600`); |
|
}); |
|
|
|
|
|
document.querySelectorAll('.user-bubble').forEach(bubble => { |
|
bubble.classList.remove('bg-blue-500', 'bg-purple-500', 'bg-pink-500', 'bg-teal-500'); |
|
bubble.classList.add(`bg-${color}-500`); |
|
}); |
|
}); |
|
}); |
|
</script> |
|
<p style="border-radius: 8px; text-align: center; font-size: 12px; color: #fff; margin-top: 16px;position: fixed; left: 8px; bottom: 8px; z-index: 10; background: rgba(0, 0, 0, 0.8); padding: 4px 8px;">Made with <img src="https://enzostvs-deepsite.hf.space/logo.svg" alt="DeepSite Logo" style="width: 16px; height: 16px; vertical-align: middle;display:inline-block;margin-right:3px;filter:brightness(0) invert(1);"><a href="https://enzostvs-deepsite.hf.space" style="color: #fff;text-decoration: underline;" target="_blank" >DeepSite</a> - 🧬 <a href="https://enzostvs-deepsite.hf.space?remix=gaowudao/test" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body> |
|
</html> |