Download mindfull_client.html from IamSamkk/mindfull: direct link, hf CLI and curl.
- Browser
- Download file 17 kB
-
https://huggingface.co/spaces/IamSamkk/mindfull/resolve/main/mindfull_client.html
- Command line
-
hf download hf://spaces/IamSamkk/mindfull/mindfull_client.html
-
curl -L -o mindfull_client.html https://huggingface.co/spaces/IamSamkk/mindfull/resolve/main/mindfull_client.html
17 kB
| <html lang="en"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| <title>Mindfull AI Avatar Chatbot</title> | |
| <style> | |
| * { | |
| margin: 0; | |
| padding: 0; | |
| box-sizing: border-box; | |
| } | |
| body { | |
| font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; | |
| background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); | |
| min-height: 100vh; | |
| display: flex; | |
| justify-content: center; | |
| align-items: center; | |
| } | |
| .chat-container { | |
| background: white; | |
| border-radius: 20px; | |
| box-shadow: 0 20px 40px rgba(0, 0, 0, 0.1); | |
| width: 100%; | |
| max-width: 800px; | |
| height: 90vh; | |
| display: flex; | |
| flex-direction: column; | |
| overflow: hidden; | |
| } | |
| .chat-header { | |
| background: #4a5568; | |
| color: white; | |
| padding: 20px; | |
| text-align: center; | |
| } | |
| .chat-header h1 { | |
| margin-bottom: 5px; | |
| } | |
| .chat-header p { | |
| opacity: 0.8; | |
| font-size: 14px; | |
| } | |
| .status-bar { | |
| background: #f7fafc; | |
| padding: 10px 20px; | |
| border-bottom: 1px solid #e2e8f0; | |
| font-size: 12px; | |
| color: #4a5568; | |
| } | |
| .status-indicator { | |
| display: inline-block; | |
| width: 8px; | |
| height: 8px; | |
| border-radius: 50%; | |
| margin-right: 5px; | |
| } | |
| .status-connected { | |
| background: #48bb78; | |
| } | |
| .status-disconnected { | |
| background: #f56565; | |
| } | |
| .chat-messages { | |
| flex: 1; | |
| padding: 20px; | |
| overflow-y: auto; | |
| background: #f8f9fa; | |
| } | |
| .message { | |
| margin-bottom: 20px; | |
| display: flex; | |
| align-items: flex-start; | |
| } | |
| .message.user { | |
| justify-content: flex-end; | |
| } | |
| .message-content { | |
| max-width: 70%; | |
| padding: 15px; | |
| border-radius: 15px; | |
| position: relative; | |
| } | |
| .message.user .message-content { | |
| background: #4299e1; | |
| color: white; | |
| border-bottom-right-radius: 5px; | |
| } | |
| .message.bot .message-content { | |
| background: white; | |
| border: 1px solid #e2e8f0; | |
| border-bottom-left-radius: 5px; | |
| } | |
| .message-meta { | |
| font-size: 11px; | |
| opacity: 0.7; | |
| margin-top: 5px; | |
| } | |
| .emotion-tag { | |
| display: inline-block; | |
| background: #edf2f7; | |
| color: #4a5568; | |
| padding: 2px 8px; | |
| border-radius: 10px; | |
| font-size: 10px; | |
| margin-left: 5px; | |
| } | |
| .media-content { | |
| margin-top: 10px; | |
| } | |
| .audio-player { | |
| width: 100%; | |
| margin-top: 10px; | |
| } | |
| .video-player { | |
| width: 100%; | |
| max-width: 300px; | |
| border-radius: 10px; | |
| margin-top: 10px; | |
| } | |
| .chat-input { | |
| padding: 20px; | |
| background: white; | |
| border-top: 1px solid #e2e8f0; | |
| } | |
| .input-container { | |
| display: flex; | |
| gap: 10px; | |
| align-items: flex-end; | |
| } | |
| .message-input { | |
| flex: 1; | |
| border: 2px solid #e2e8f0; | |
| border-radius: 25px; | |
| padding: 15px 20px; | |
| font-size: 14px; | |
| resize: none; | |
| max-height: 100px; | |
| min-height: 50px; | |
| outline: none; | |
| transition: border-color 0.3s; | |
| } | |
| .message-input:focus { | |
| border-color: #4299e1; | |
| } | |
| .send-button { | |
| background: #4299e1; | |
| color: white; | |
| border: none; | |
| border-radius: 50%; | |
| width: 50px; | |
| height: 50px; | |
| cursor: pointer; | |
| display: flex; | |
| align-items: center; | |
| justify-content: center; | |
| transition: background 0.3s; | |
| } | |
| .send-button:hover:not(:disabled) { | |
| background: #3182ce; | |
| } | |
| .send-button:disabled { | |
| background: #a0aec0; | |
| cursor: not-allowed; | |
| } | |
| .loading { | |
| display: none; | |
| text-align: center; | |
| padding: 20px; | |
| color: #4a5568; | |
| } | |
| .loading.show { | |
| display: block; | |
| } | |
| .spinner { | |
| display: inline-block; | |
| width: 20px; | |
| height: 20px; | |
| border: 3px solid #e2e8f0; | |
| border-radius: 50%; | |
| border-top-color: #4299e1; | |
| animation: spin 1s ease-in-out infinite; | |
| } | |
| @keyframes spin { | |
| to { transform: rotate(360deg); } | |
| } | |
| .controls { | |
| display: flex; | |
| gap: 10px; | |
| margin-top: 10px; | |
| flex-wrap: wrap; | |
| } | |
| .control-checkbox { | |
| display: flex; | |
| align-items: center; | |
| gap: 5px; | |
| font-size: 12px; | |
| color: #4a5568; | |
| } | |
| .error-message { | |
| background: #fed7d7; | |
| color: #c53030; | |
| padding: 10px; | |
| border-radius: 5px; | |
| margin-bottom: 10px; | |
| font-size: 12px; | |
| } | |
| @media (max-width: 768px) { | |
| .chat-container { | |
| height: 100vh; | |
| border-radius: 0; | |
| } | |
| .message-content { | |
| max-width: 90%; | |
| } | |
| } | |
| </style> | |
| </head> | |
| <body> | |
| <div class="chat-container"> | |
| <div class="chat-header"> | |
| <h1>🛡️ Mindfull</h1> | |
| <p>AI Mental Wellness Assistant for Police Officers</p> | |
| </div> | |
| <div class="status-bar"> | |
| <span class="status-indicator status-disconnected" id="statusIndicator"></span> | |
| <span id="statusText">Connecting...</span> | |
| </div> | |
| <div class="chat-messages" id="chatMessages"> | |
| <div class="message bot"> | |
| <div class="message-content"> | |
| <div>🙏 Namaskara! I'm Mindfull, your AI wellness assistant. I'm here to support you with any mental health concerns or stress you might be experiencing. How are you feeling today?</div> | |
| <div class="message-meta">System message</div> | |
| </div> | |
| </div> | |
| </div> | |
| <div class="loading" id="loadingIndicator"> | |
| <div class="spinner"></div> | |
| <span>Processing your message...</span> | |
| </div> | |
| <div class="chat-input"> | |
| <div class="error-message" id="errorMessage" style="display: none;"></div> | |
| <div class="input-container"> | |
| <textarea | |
| id="messageInput" | |
| class="message-input" | |
| placeholder="Share how you're feeling today..." | |
| rows="1" | |
| ></textarea> | |
| <button id="sendButton" class="send-button"> | |
| <svg width="20" height="20" viewBox="0 0 24 24" fill="currentColor"> | |
| <path d="M2.01 21L23 12 2.01 3 2 10l15 2-15 2z"/> | |
| </svg> | |
| </button> | |
| </div> | |
| <div class="controls"> | |
| <label class="control-checkbox"> | |
| <input type="checkbox" id="enableVideo" checked> | |
| Generate Avatar Video | |
| </label> | |
| <label class="control-checkbox"> | |
| <input type="checkbox" id="autoPlay" checked> | |
| Auto-play Audio | |
| </label> | |
| </div> | |
| </div> | |
| </div> | |
| <script> | |
| class MindfullChat { | |
| constructor() { | |
| this.apiUrl = 'http://localhost:5000'; | |
| this.sessionId = null; | |
| this.isConnected = false; | |
| this.initializeElements(); | |
| this.setupEventListeners(); | |
| this.checkConnection(); | |
| this.createSession(); | |
| } | |
| initializeElements() { | |
| this.messagesContainer = document.getElementById('chatMessages'); | |
| this.messageInput = document.getElementById('messageInput'); | |
| this.sendButton = document.getElementById('sendButton'); | |
| this.loadingIndicator = document.getElementById('loadingIndicator'); | |
| this.statusIndicator = document.getElementById('statusIndicator'); | |
| this.statusText = document.getElementById('statusText'); | |
| this.errorMessage = document.getElementById('errorMessage'); | |
| this.enableVideo = document.getElementById('enableVideo'); | |
| this.autoPlay = document.getElementById('autoPlay'); | |
| } | |
| setupEventListeners() { | |
| this.sendButton.addEventListener('click', () => this.sendMessage()); | |
| this.messageInput.addEventListener('keypress', (e) => { | |
| if (e.key === 'Enter' && !e.shiftKey) { | |
| e.preventDefault(); | |
| this.sendMessage(); | |
| } | |
| }); | |
| // Auto-resize textarea | |
| this.messageInput.addEventListener('input', () => { | |
| this.messageInput.style.height = 'auto'; | |
| this.messageInput.style.height = this.messageInput.scrollHeight + 'px'; | |
| }); | |
| } | |
| async checkConnection() { | |
| try { | |
| const response = await fetch(`${this.apiUrl}/health`); | |
| if (response.ok) { | |
| this.setConnectionStatus(true, 'Connected'); | |
| } else { | |
| this.setConnectionStatus(false, 'API Error'); | |
| } | |
| } catch (error) { | |
| this.setConnectionStatus(false, 'Disconnected'); | |
| this.showError('Unable to connect to Mindfull API. Please ensure the server is running.'); | |
| } | |
| } | |
| async createSession() { | |
| try { | |
| const response = await fetch(`${this.apiUrl}/session`, { | |
| method: 'POST', | |
| headers: { | |
| 'Content-Type': 'application/json', | |
| } | |
| }); | |
| if (response.ok) { | |
| const data = await response.json(); | |
| this.sessionId = data.session_id; | |
| console.log('Session created:', this.sessionId); | |
| } | |
| } catch (error) { | |
| console.error('Failed to create session:', error); | |
| } | |
| } | |
| setConnectionStatus(connected, text) { | |
| this.isConnected = connected; | |
| this.statusIndicator.className = `status-indicator ${connected ? 'status-connected' : 'status-disconnected'}`; | |
| this.statusText.textContent = text; | |
| } | |
| showError(message) { | |
| this.errorMessage.textContent = message; | |
| this.errorMessage.style.display = 'block'; | |
| setTimeout(() => { | |
| this.errorMessage.style.display = 'none'; | |
| }, 5000); | |
| } | |
| addMessage(content, isUser = false, metadata = {}) { | |
| const messageDiv = document.createElement('div'); | |
| messageDiv.className = `message ${isUser ? 'user' : 'bot'}`; | |
| let metaInfo = ''; | |
| if (!isUser) { | |
| const emotion = metadata.emotion ? `<span class="emotion-tag">${metadata.emotion}</span>` : ''; | |
| const processingTime = metadata.processingTime ? ` • ${metadata.processingTime}s` : ''; | |
| metaInfo = `<div class="message-meta">${new Date().toLocaleTimeString()}${emotion}${processingTime}</div>`; | |
| } | |
| let mediaContent = ''; | |
| if (metadata.audioUrl) { | |
| mediaContent += ` | |
| <div class="media-content"> | |
| <audio controls class="audio-player" ${this.autoPlay.checked ? 'autoplay' : ''}> | |
| <source src="${this.apiUrl}${metadata.audioUrl}" type="audio/wav"> | |
| Your browser does not support the audio element. | |
| </audio> | |
| </div> | |
| `; | |
| } | |
| if (metadata.videoUrl) { | |
| mediaContent += ` | |
| <div class="media-content"> | |
| <video controls class="video-player" ${this.autoPlay.checked ? 'autoplay' : ''}> | |
| <source src="${this.apiUrl}${metadata.videoUrl}" type="video/mp4"> | |
| Your browser does not support the video element. | |
| </video> | |
| </div> | |
| `; | |
| } | |
| messageDiv.innerHTML = ` | |
| <div class="message-content"> | |
| <div>${content}</div> | |
| ${metaInfo} | |
| ${mediaContent} | |
| </div> | |
| `; | |
| this.messagesContainer.appendChild(messageDiv); | |
| this.messagesContainer.scrollTop = this.messagesContainer.scrollHeight; | |
| } | |
| setLoading(loading) { | |
| this.loadingIndicator.classList.toggle('show', loading); | |
| this.sendButton.disabled = loading; | |
| if (loading) { | |
| this.messagesContainer.scrollTop = this.messagesContainer.scrollHeight; | |
| } | |
| } | |
| async sendMessage() { | |
| const message = this.messageInput.value.trim(); | |
| if (!message || !this.isConnected) return; | |
| // Add user message | |
| this.addMessage(message, true); | |
| // Clear input | |
| this.messageInput.value = ''; | |
| this.messageInput.style.height = 'auto'; | |
| // Show loading | |
| this.setLoading(true); | |
| try { | |
| const response = await fetch(`${this.apiUrl}/chat`, { | |
| method: 'POST', | |
| headers: { | |
| 'Content-Type': 'application/json', | |
| }, | |
| body: JSON.stringify({ | |
| message: message, | |
| session_id: this.sessionId, | |
| include_video: this.enableVideo.checked | |
| }) | |
| }); | |
| if (response.ok) { | |
| const data = await response.json(); | |
| // Add bot response | |
| this.addMessage(data.response_text, false, { | |
| emotion: data.emotion_detected, | |
| processingTime: data.processing_time?.toFixed(2), | |
| audioUrl: data.audio_url, | |
| videoUrl: data.video_url | |
| }); | |
| if (data.warnings && data.warnings.length > 0) { | |
| console.warn('Warnings:', data.warnings); | |
| } | |
| } else { | |
| const errorData = await response.json(); | |
| this.showError(errorData.message || 'Failed to send message'); | |
| } | |
| } catch (error) { | |
| console.error('Send message error:', error); | |
| this.showError('Network error. Please try again.'); | |
| } finally { | |
| this.setLoading(false); | |
| } | |
| } | |
| } | |
| // Initialize chat when page loads | |
| document.addEventListener('DOMContentLoaded', () => { | |
| new MindfullChat(); | |
| }); | |
| </script> | |
| </body> | |
| </html> | |