File size: 3,105 Bytes
4d9101c
e4a5846
 
 
 
 
 
 
 
 
 
 
 
4d9101c
e4a5846
07d40a4
e4a5846
07d40a4
4d9101c
e4a5846
 
4d9101c
e4a5846
 
4d9101c
e4a5846
 
 
 
07d40a4
 
 
e4a5846
07d40a4
e4a5846
 
 
07d40a4
4d9101c
e4a5846
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4d9101c
e4a5846
 
 
4d9101c
e4a5846
07d40a4
e4a5846
 
 
 
 
 
 
 
 
 
 
 
4d9101c
e4a5846
 
 
 
 
 
 
 
 
 
 
 
 
 
4d9101c
 
e4a5846
 
 
4d9101c
 
e4a5846
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
// 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' });
}