Spaces:
Sleeping
Sleeping
| // Configure Marked.js for Code Highlighting | |
| marked.setOptions({ | |
| highlight: function(code, lang) { | |
| const language = hljs.getLanguage(lang) ? lang : 'plaintext'; | |
| return hljs.highlight(code, { language }).value; | |
| } | |
| }); | |
| const chatBox = document.getElementById('chat-box'); | |
| const inputField = document.getElementById('user-input'); | |
| const sendBtn = document.getElementById('send-btn'); | |
| const themeToggle = document.getElementById('themeToggle'); | |
| // Theme Logic | |
| themeToggle.addEventListener('click', () => { | |
| document.body.classList.toggle('dark-mode'); | |
| }); | |
| // Auto-resize Textarea up to a max height | |
| inputField.addEventListener('input', function() { | |
| this.style.height = 'auto'; | |
| this.style.height = Math.min(this.scrollHeight, 200) + 'px'; | |
| }); | |
| // Handle Enter (Send) vs Shift+Enter (New Line) | |
| inputField.addEventListener('keydown', (e) => { | |
| if (e.key === 'Enter' && !e.shiftKey) { | |
| e.preventDefault(); | |
| sendMessage(); | |
| } | |
| }); | |
| sendBtn.addEventListener('click', sendMessage); | |
| async function sendMessage() { | |
| const text = inputField.value.trim(); | |
| if (!text) return; | |
| // Reset UI | |
| inputField.value = ''; | |
| inputField.style.height = 'auto'; | |
| appendMessage('user', text); | |
| sendBtn.disabled = true; | |
| try { | |
| const response = await fetch('/api/chat', { | |
| method: 'POST', | |
| headers: { 'Content-Type': 'application/json' }, | |
| body: JSON.stringify({ message: text }) | |
| }); | |
| const data = await response.json(); | |
| if (response.ok) { | |
| appendMessage('ai', data.reply); | |
| } else { | |
| appendMessage('ai', `**Error:** ${data.detail}`); | |
| } | |
| } catch (error) { | |
| appendMessage('ai', `**Connection Error:** Please check your network.`); | |
| } | |
| sendBtn.disabled = false; | |
| inputField.focus(); | |
| } | |
| function appendMessage(sender, text) { | |
| const msgDiv = document.createElement('div'); | |
| msgDiv.classList.add('message'); | |
| if (sender === 'ai') { | |
| msgDiv.classList.add('ai-msg'); | |
| const htmlContent = marked.parse(text); | |
| msgDiv.innerHTML = ` | |
| <div class="avatar">✦</div> | |
| <div class="content">${htmlContent}</div> | |
| `; | |
| // Add Copy Buttons to Code Blocks | |
| msgDiv.querySelectorAll('pre').forEach(pre => { | |
| const btn = document.createElement('button'); | |
| btn.className = 'copy-btn'; | |
| btn.innerText = 'Copy'; | |
| btn.onclick = () => { | |
| const codeText = pre.querySelector('code').innerText; | |
| navigator.clipboard.writeText(codeText); | |
| btn.innerText = 'Copied!'; | |
| setTimeout(() => btn.innerText = 'Copy', 2000); | |
| }; | |
| pre.appendChild(btn); | |
| }); | |
| } else { | |
| msgDiv.classList.add('user-msg'); | |
| msgDiv.innerHTML = `<div class="content">${text}</div>`; | |
| } | |
| chatBox.appendChild(msgDiv); | |
| // Smooth scroll to bottom | |
| chatBox.scrollTo({ top: chatBox.scrollHeight, behavior: 'smooth' }); | |
| } |