Files
HooHacks-12/Backend/index.html
2025-03-30 10:53:51 -04:00

268 lines
8.6 KiB
HTML

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>AI Voice Chat</title>
<style>
body {
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
margin: 0;
padding: 0;
background-color: #f5f5f5;
color: #333;
}
.container {
max-width: 800px;
margin: 0 auto;
padding: 20px;
}
header {
text-align: center;
margin-bottom: 30px;
}
h1 {
color: #2c3e50;
}
.status-bar {
background-color: #2c3e50;
color: white;
padding: 10px;
border-radius: 5px;
margin-bottom: 20px;
display: flex;
justify-content: space-between;
align-items: center;
}
.status-indicator {
display: flex;
align-items: center;
}
.status-dot {
height: 10px;
width: 10px;
border-radius: 50%;
margin-right: 8px;
}
.status-dot.connected { background-color: #2ecc71; }
.status-dot.connecting { background-color: #f39c12; }
.status-dot.disconnected { background-color: #e74c3c; }
.conversation {
background-color: white;
border-radius: 10px;
box-shadow: 0 2px 10px rgba(0,0,0,0.1);
height: 400px;
padding: 20px;
overflow-y: auto;
margin-bottom: 20px;
}
.message {
margin-bottom: 15px;
padding: 10px 15px;
border-radius: 18px;
max-width: 80%;
word-wrap: break-word;
}
.user-message {
background-color: #e3f2fd;
margin-left: auto;
border-bottom-right-radius: 5px;
}
.ai-message {
background-color: #f0f0f0;
margin-right: auto;
border-bottom-left-radius: 5px;
}
.controls {
display: flex;
justify-content: center;
gap: 15px;
margin-bottom: 20px;
}
button {
background-color: #2c3e50;
color: white;
border: none;
padding: 12px 24px;
border-radius: 25px;
cursor: pointer;
font-size: 16px;
transition: all 0.2s;
display: flex;
align-items: center;
justify-content: center;
gap: 8px;
}
button:hover {
background-color: #1a252f;
}
button:disabled {
background-color: #95a5a6;
cursor: not-allowed;
}
.button-icon {
width: 20px;
height: 20px;
}
.mic-animation {
width: 60px;
height: 60px;
border-radius: 50%;
background-color: rgba(231, 76, 60, 0.2);
display: flex;
align-items: center;
justify-content: center;
animation: pulse 1.5s infinite;
margin: 0 auto 15px;
}
@keyframes pulse {
0% {
transform: scale(0.95);
box-shadow: 0 0 0 0 rgba(231, 76, 60, 0.5);
}
70% {
transform: scale(1);
box-shadow: 0 0 0 15px rgba(231, 76, 60, 0);
}
100% {
transform: scale(0.95);
box-shadow: 0 0 0 0 rgba(231, 76, 60, 0);
}
}
.settings {
margin-top: 20px;
padding: 15px;
background-color: white;
border-radius: 10px;
box-shadow: 0 2px 10px rgba(0,0,0,0.1);
}
.settings h3 {
margin-top: 0;
color: #2c3e50;
border-bottom: 1px solid #eee;
padding-bottom: 10px;
}
.settings-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
gap: 15px;
}
.setting-item {
padding: 10px;
background-color: #f9f9f9;
border-radius: 5px;
}
.audio-visualizer {
height: 50px;
width: 100%;
background-color: #f0f0f0;
margin-top: 10px;
border-radius: 5px;
overflow: hidden;
}
.info-message {
text-align: center;
color: #7f8c8d;
margin: 10px 0;
font-style: italic;
}
.loading {
text-align: center;
margin: 20px 0;
}
.spinner {
border: 4px solid rgba(0, 0, 0, 0.1);
border-radius: 50%;
border-top: 4px solid #2c3e50;
width: 30px;
height: 30px;
animation: spin 1s linear infinite;
margin: 0 auto 10px;
}
@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
footer {
text-align: center;
margin-top: 30px;
padding: 20px;
color: #7f8c8d;
font-size: 14px;
}
</style>
</head>
<body>
<div class="container">
<header>
<h1>AI Voice Assistant</h1>
</header>
<div class="status-bar">
<div class="status-indicator">
<div class="status-dot disconnected" id="connection-dot"></div>
<span id="connection-status">Disconnected</span>
</div>
<div id="runtime-info">
<span id="models-status"></span>
</div>
</div>
<div class="conversation" id="conversation">
<div class="info-message">Your conversation will appear here.</div>
</div>
<div id="mic-animation" class="mic-animation" style="display: none;">
<svg width="24" height="24" viewBox="0 0 24 24" fill="white">
<path d="M12 14c1.66 0 3-1.34 3-3V5c0-1.66-1.34-3-3-3S9 3.34 9 5v6c0 1.66 1.34 3 3 3zm5.91-3c-.49 0-.9.36-.98.85C16.52 14.2 14.47 16 12 16s-4.52-1.8-4.93-4.15c-.08-.49-.49-.85-.98-.85-.61 0-1.09.54-1 1.14.49 3 2.89 5.35 5.91 5.78V20c0 .55.45 1 1 1s1-.45 1-1v-2.08c3.02-.43 5.42-2.78 5.91-5.78.1-.6-.39-1.14-1-1.14z"></path>
</svg>
</div>
<div class="controls">
<button id="start-button" disabled>
<svg class="button-icon" viewBox="0 0 24 24" fill="white">
<path d="M12 14c1.66 0 3-1.34 3-3V5c0-1.66-1.34-3-3-3S9 3.34 9 5v6c0 1.66 1.34 3 3 3zm5.91-3c-.49 0-.9.36-.98.85C16.52 14.2 14.47 16 12 16s-4.52-1.8-4.93-4.15c-.08-.49-.49-.85-.98-.85-.61 0-1.09.54-1 1.14.49 3 2.89 5.35 5.91 5.78V20c0 .55.45 1 1 1s1-.45 1-1v-2.08c3.02-.43 5.42-2.78 5.91-5.78.1-.6-.39-1.14-1-1.14z"></path>
</svg>
Start Listening
</button>
<button id="interrupt-button" disabled>
<svg class="button-icon" viewBox="0 0 24 24" fill="white">
<path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm1 15h-2v-2h2v2zm0-4h-2V7h2v6z"></path>
</svg>
Interrupt
</button>
</div>
<div id="loading" class="loading" style="display: none;">
<div class="spinner"></div>
<p id="loading-text">Processing your speech...</p>
</div>
<div class="settings">
<h3>Status</h3>
<div class="settings-grid">
<div class="setting-item">
<div><strong>Whisper Model:</strong> <span id="whisper-status">Loading...</span></div>
</div>
<div class="setting-item">
<div><strong>CSM Audio Model:</strong> <span id="csm-status">Loading...</span></div>
</div>
<div class="setting-item">
<div><strong>LLM Model:</strong> <span id="llm-status">Loading...</span></div>
</div>
<div class="setting-item">
<div><strong>WebRTC:</strong> <span id="webrtc-status">Not Connected</span></div>
</div>
</div>
</div>
</div>
<footer>
<p>AI Voice Assistant | Using Fast Whisper, Llama 3.2, and CSM Audio Models</p>
</footer>
<script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/4.6.1/socket.io.min.js"></script>
<script src="/voice-chat.js"></script>
</body>
</html>