diff --git a/chatv2.js b/chatv2.js index 2a48ca4..896b937 100644 --- a/chatv2.js +++ b/chatv2.js @@ -89,7 +89,10 @@ function updateBackendModelDisplay() { const displayText = IS_PRODUCTION ? `${backend.prod} - ${backend.name}` : backend.dev; - document.getElementById('backendDisplay').textContent = `${displayText} - Model: ${model || 'None'}`; + const displayElement = document.getElementById('backendDisplay'); + if (displayElement) { + displayElement.textContent = `${displayText} - Model: ${model || 'None'}`; + } } async function fetchBackendModels() { @@ -103,6 +106,7 @@ async function fetchBackendModels() { console.log(`Fetching models from: ${apiUrl}`); const response = await fetch(`${apiUrl}/models`); + const selector = document.getElementById('backendModelSelector'); if (response.ok) { const data = await response.json(); @@ -119,24 +123,31 @@ async function fetchBackendModels() { // ✅ FIX: Only auto-select if no model is set const hasModel = currentBackendModel && currentBackendModel.includes(':') && currentBackendModel.split(':')[1]; - if (!hasModel && availableBackendModels.length > 0) { + if (!hasModel && availableBackendModels.length > 0 && selector) { currentBackendModel = `${availableBackendModels[0].backend}:${availableBackendModels[0].model}`; - document.getElementById('backendModelSelector').value = currentBackendModel; + selector.value = currentBackendModel; } updateBackendModelDisplay(); } else { console.error('Failed to fetch models:', response.statusText); - document.getElementById('backendModelSelector').innerHTML = ''; + if (selector) { + selector.innerHTML = ''; + } } } catch (error) { console.error('Error fetching models:', error); - document.getElementById('backendModelSelector').innerHTML = ''; + const selector = document.getElementById('backendModelSelector'); + if (selector) { + selector.innerHTML = ''; + } } } function populateBackendModelSelector() { const selector = document.getElementById('backendModelSelector'); + if (!selector) return; + if (availableBackendModels.length === 0) { selector.innerHTML = ''; return; @@ -168,13 +179,13 @@ function trimChatHistory() { document.addEventListener('DOMContentLoaded', () => { const backendModelSelector = document.getElementById('backendModelSelector'); - backendModelSelector.addEventListener('change', (e) => { - currentBackendModel = e.target.value; - updateBackendModelDisplay(); - fetchBackendModels(); - }); - - fetchBackendModels(); + if (backendModelSelector) { + backendModelSelector.addEventListener('change', (e) => { + currentBackendModel = e.target.value; + updateBackendModelDisplay(); + fetchBackendModels(); + }); + } }); const chatLog = document.getElementById('chatLog'); @@ -201,7 +212,7 @@ function autoResize(textarea) { textarea.style.height = Math.min(textarea.scrollHeight, 300) + 'px'; } -function addMessage(role, content, markdown = false, messageId = null) { +function addMessage(role, content, markdown = false, messageId = null, saveToHistory = true) { const messageDiv = document.createElement('div'); messageDiv.className = `message message-${role}`; if (messageId) { @@ -213,7 +224,7 @@ function addMessage(role, content, markdown = false, messageId = null) { const avatar = document.createElement('div'); avatar.className = `avatar ${role}-avatar`; - avatar.textContent = role === 'user' ? '?' : '?'; + avatar.textContent = role === 'user' ? '👤' : '🤖'; const name = document.createElement('span'); name.textContent = role === 'user' ? 'You' : 'Assistant'; @@ -239,17 +250,21 @@ function addMessage(role, content, markdown = false, messageId = null) { contentDiv.innerHTML = processedContent; contentDiv.style.whiteSpace = 'pre-wrap'; contentDiv.style.padding = '8px 0'; - contentDiv.style.color = '#2d3339'; + contentDiv.style.color = '#e0e0e0'; } messageDiv.appendChild(headerDiv); messageDiv.appendChild(contentDiv); - chatLog.appendChild(messageDiv); - chatLog.scrollTop = chatLog.scrollHeight; + if (chatLog) { + chatLog.appendChild(messageDiv); + chatLog.scrollTop = chatLog.scrollHeight; + } - chatHistory.push({ role, content, markdown, messageId }); - trimChatHistory(); - localStorage.setItem('chatHistory', JSON.stringify(chatHistory)); + if (saveToHistory) { + chatHistory.push({ role, content, markdown, messageId }); + trimChatHistory(); + localStorage.setItem('chatHistory', JSON.stringify(chatHistory)); + } return contentDiv; } @@ -300,7 +315,7 @@ window.toggleThinking = function(id) { function updateMessageContent(contentDiv, newContent, markdown = false, role) { const processedContent = parseThinkingTags(newContent); - if (markdown && role === 'assistant' && markdownToggle.checked) { + if (markdown && role === 'assistant' && markdownToggle && markdownToggle.checked) { contentDiv.innerHTML = marked.parse(processedContent); if (window.hljs) { setTimeout(() => { @@ -311,6 +326,12 @@ function updateMessageContent(contentDiv, newContent, markdown = false, role) { } } else { contentDiv.innerHTML = processedContent; + contentDiv.style.whiteSpace = 'pre-wrap'; + contentDiv.style.padding = '8px 0'; + contentDiv.style.color = '#e0e0e0'; + } + if (chatLog) { + chatLog.scrollTop = chatLog.scrollHeight; } } @@ -324,12 +345,12 @@ function showTypingIndicator() { const avatar = document.createElement('div'); avatar.className = 'avatar assistant-avatar'; - avatar.textContent = '?'; + avatar.textContent = '🤖'; const name = document.createElement('span'); name.textContent = 'Assistant'; - headerDiv.appendChild(avatar); // ✅ FIX: Typo "abatar" + headerDiv.appendChild(avatar); headerDiv.appendChild(name); const dotsDiv = document.createElement('div'); @@ -343,8 +364,10 @@ function showTypingIndicator() { typingDiv.appendChild(headerDiv); typingDiv.appendChild(dotsDiv); - chatLog.appendChild(typingDiv); - chatLog.scrollTop = chatLog.scrollHeight; + if (chatLog) { + chatLog.appendChild(typingDiv); + chatLog.scrollTop = chatLog.scrollHeight; + } return typingDiv; } @@ -369,7 +392,7 @@ async function handleStreamingResponse(userMessage) { const avatar = document.createElement('div'); avatar.className = 'avatar assistant-avatar'; - avatar.textContent = '?'; + avatar.textContent = '🤖'; const name = document.createElement('span'); name.textContent = 'Assistant'; @@ -382,7 +405,9 @@ async function handleStreamingResponse(userMessage) { messageDiv.appendChild(headerDiv); messageDiv.appendChild(contentDiv); - chatLog.appendChild(messageDiv); + if (chatLog) { + chatLog.appendChild(messageDiv); + } const cursorSpan = document.createElement('span'); cursorSpan.className = 'streaming-cursor'; @@ -433,24 +458,28 @@ async function handleStreamingResponse(userMessage) { if (timeSinceLastUpdate >= MIN_UPDATE_INTERVAL) { updateScheduled = true; - requestAnimationFrame(() => { - updateMessageContent(contentDiv, accumulatedContent, markdownToggle.checked, 'assistant'); - if (cursorSpan.parentNode) { - contentDiv.appendChild(cursorSpan); - } - chatLog.scrollTop = chatLog.scrollHeight; - lastUpdate = Date.now(); - updateScheduled = false; - }); + requestAnimationFrame(() => { + updateMessageContent(contentDiv, accumulatedContent, markdownToggle && markdownToggle.checked, 'assistant'); + if (cursorSpan.parentNode) { + contentDiv.appendChild(cursorSpan); + } + if (chatLog) { + chatLog.scrollTop = chatLog.scrollHeight; + } + lastUpdate = Date.now(); + updateScheduled = false; + }); } else { updateScheduled = true; setTimeout(() => { requestAnimationFrame(() => { - updateMessageContent(contentDiv, accumulatedContent, markdownToggle.checked, 'assistant'); + updateMessageContent(contentDiv, accumulatedContent, markdownToggle && markdownToggle.checked, 'assistant'); if (cursorSpan.parentNode) { contentDiv.appendChild(cursorSpan); } - chatLog.scrollTop = chatLog.scrollHeight; + if (chatLog) { + chatLog.scrollTop = chatLog.scrollHeight; + } lastUpdate = Date.now(); updateScheduled = false; }); @@ -618,7 +647,7 @@ userInput.addEventListener('keydown', (e) => { // ✅ Updated window.onload with better initialization window.onload = () => { - userInput.focus(); + if (userInput) userInput.focus(); // Set default backend BEFORE fetching if (!currentBackendModel) { @@ -629,11 +658,11 @@ window.onload = () => { // Load chat history after models are fetched if (chatLog) { if (chatHistory.length === 0) { - //addMessage('assistant', welcomeMessage, true); + //addMessage('assistant', welcomeMessage, true, null, false); } else { chatHistory.forEach(msg => { if (typeof msg.content === 'string' && msg.content.trim()) { - addMessage(msg.role, msg.content, msg.markdown, msg.messageId); + addMessage(msg.role, msg.content, msg.markdown, msg.messageId, false); } }); } @@ -649,6 +678,6 @@ function resetChat() { if (chatLog) { chatLog.innerHTML = ''; - addMessage('assistant', welcomeMessage, true); + addMessage('assistant', welcomeMessage, true, null, false); } } \ No newline at end of file