document.addEventListener('DOMContentLoaded', () => { const chatWindow = document.getElementById('chat-window'); const chatInput = document.getElementById('chat-input'); const sendBtn = document.getElementById('send-btn'); const modeItems = document.querySelectorAll('.mode-item'); const currentModeBadge = document.getElementById('current-mode-badge'); const newChatBtn = document.getElementById('new-chat-btn'); // Settings elements const creativityRange = document.getElementById('creativity-range'); const creativityVal = document.getElementById('creativity-val'); const limitsToggle = document.getElementById('limits-toggle'); const themeSwatches = document.querySelectorAll('.theme-swatch'); const saveSettingsBtn = document.getElementById('save-settings-btn'); let currentMode = 'regular'; let currentChatId = null; // --- Sidebar & Mode Switching --- modeItems.forEach(item => { item.addEventListener('click', () => { modeItems.forEach(i => i.classList.remove('active')); item.classList.add('active'); currentMode = item.dataset.mode; currentModeBadge.textContent = item.querySelector('span').textContent; // If switching modes, start a new chat for that mode startNewChat(); }); }); function startNewChat() { currentChatId = null; chatWindow.innerHTML = `

New ${currentMode} Chat

How can I help you in this mode?

`; } newChatBtn.addEventListener('click', startNewChat); // --- Chat Logic --- async function sendMessage() { const message = chatInput.value.trim(); if (!message) return; // Clear input and disable chatInput.value = ''; chatInput.style.height = 'auto'; toggleLoading(true); // Append User Message appendMessage('user', message); try { const response = await fetch('api/chat.php', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ message: message, mode: currentMode, chat_id: currentChatId, creativity: creativityRange.value, limits_off: limitsToggle.checked ? 1 : 0 }) }); const data = await response.json(); if (data.success) { currentChatId = data.chat_id; appendMessage('assistant', data.message); // Special handling for game/app mode if (currentMode === 'game' || currentMode === 'app') { addLaunchButton(data.message); } } else { appendMessage('assistant', 'Error: ' + (data.error || 'Unknown error')); } } catch (error) { appendMessage('assistant', 'Error: ' + error.message); } finally { toggleLoading(false); } } function appendMessage(role, text) { // Remove empty state if present const emptyState = chatWindow.querySelector('.my-auto'); if (emptyState) emptyState.remove(); const msgDiv = document.createElement('div'); msgDiv.className = `message message-${role}`; // Handle code blocks if any if (text.includes('```')) { msgDiv.innerHTML = formatCodeBlocks(text); } else { msgDiv.textContent = text; } chatWindow.appendChild(msgDiv); chatWindow.scrollTop = chatWindow.scrollHeight; } function formatCodeBlocks(text) { return text.replace(/```(\w+)?\n([\s\S]*?)```/g, (match, lang, code) => { return `
${escapeHtml(code.trim())}
`; }); } function escapeHtml(text) { const div = document.createElement('div'); div.textContent = text; return div.innerHTML; } function addLaunchButton(content) { // Try to find code block content if wrapped in backticks let codeToLaunch = content; const match = content.match(/```(?:html|xml)?\n([\s\S]*?)```/i); if (match) { codeToLaunch = match[1]; } // Check if it looks like HTML if (codeToLaunch.toLowerCase().includes(' { const blob = new Blob([codeToLaunch], { type: 'text/html' }); const url = URL.createObjectURL(blob); window.open(url, '_blank'); }; chatWindow.lastElementChild.appendChild(btn); } } function toggleLoading(isLoading) { sendBtn.disabled = isLoading; if (isLoading) { sendBtn.innerHTML = ''; } else { sendBtn.innerHTML = ''; } } sendBtn.addEventListener('click', sendMessage); chatInput.addEventListener('keydown', (e) => { if (e.key === 'Enter' && !e.shiftKey) { e.preventDefault(); sendMessage(); } }); // Auto-resize textarea chatInput.addEventListener('input', () => { chatInput.style.height = 'auto'; chatInput.style.height = (chatInput.scrollHeight) + 'px'; }); // --- Settings & Themes --- creativityRange.addEventListener('input', () => { creativityVal.textContent = creativityRange.value; }); themeSwatches.forEach(swatch => { swatch.addEventListener('click', () => { const theme = swatch.dataset.theme; document.documentElement.setAttribute('data-theme', theme); themeSwatches.forEach(s => s.classList.remove('active')); swatch.classList.add('active'); }); }); saveSettingsBtn.addEventListener('click', async () => { const theme = document.documentElement.getAttribute('data-theme'); const settings = { theme: theme, creativity: creativityRange.value, limits_off: limitsToggle.checked ? '1' : '0' }; try { const resp = await fetch('api/settings.php', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(settings) }); const data = await resp.json(); if (data.success) { bootstrap.Modal.getInstance(document.getElementById('settingsModal')).hide(); // Minimal toast notification const toast = document.createElement('div'); toast.className = 'position-fixed bottom-0 start-50 translate-middle-x mb-3 bg-success text-white px-3 py-2 rounded shadow-lg'; toast.style.zIndex = '2000'; toast.textContent = 'Settings saved!'; document.body.appendChild(toast); setTimeout(() => toast.remove(), 2000); } } catch (e) { console.error(e); } }); // Set active theme swatch on load const currentTheme = document.documentElement.getAttribute('data-theme'); const activeSwatch = document.querySelector(`.theme-swatch[data-theme="${currentTheme}"]`); if (activeSwatch) activeSwatch.classList.add('active'); });