// ========================================== // Chat Switchboard - Main Application // ========================================== function init() { console.log('🔀 Chat Switchboard initializing...'); loadSettings(); loadChats(); loadModels(); initializeEventListeners(); updateQuickModelSelector(); renderChatHistory(); console.log('✅ Chat Switchboard ready'); } function initializeEventListeners() { // Settings modal document.getElementById('settingsBtn').addEventListener('click', openSettings); document.getElementById('configureBtn').addEventListener('click', openSettings); document.getElementById('closeModalBtn').addEventListener('click', closeSettings); document.getElementById('cancelBtn').addEventListener('click', closeSettings); document.getElementById('saveBtn').addEventListener('click', handleSaveSettings); document.getElementById('fetchModelsBtn').addEventListener('click', () => fetchModels(true)); // Chat controls document.getElementById('newChatBtn').addEventListener('click', newChat); document.getElementById('sendBtn').addEventListener('click', sendMessage); document.getElementById('stopBtn').addEventListener('click', stopGeneration); document.getElementById('regenerateBtn').addEventListener('click', regenerateResponse); document.getElementById('toggleSidebarBtn').addEventListener('click', toggleSidebar); document.getElementById('quickFetchBtn').addEventListener('click', () => fetchModels(false)); // Quick model selector document.getElementById('quickModel').addEventListener('change', function() { if (this.value) { State.settings.model = this.value; saveSettings(); } }); // Export dropdown document.getElementById('exportBtn').addEventListener('click', function(e) { e.stopPropagation(); document.getElementById('exportDropdown').classList.toggle('show'); }); document.addEventListener('click', function() { document.getElementById('exportDropdown').classList.remove('show'); }); // Message input const messageInput = document.getElementById('messageInput'); messageInput.addEventListener('keydown', handleKeyDown); messageInput.addEventListener('input', function() { this.style.height = 'auto'; this.style.height = Math.min(this.scrollHeight, 200) + 'px'; }); // Settings modal model sync document.getElementById('model').addEventListener('change', function() { if (this.value) document.getElementById('modelCustom').value = ''; }); document.getElementById('modelCustom').addEventListener('input', function() { if (this.value) document.getElementById('model').value = ''; }); // Close modal on overlay click document.getElementById('settingsModal').addEventListener('click', function(e) { if (e.target === this) closeSettings(); }); // Global keyboard shortcuts document.addEventListener('keydown', function(e) { if (e.ctrlKey && e.key === ',') { e.preventDefault(); openSettings(); } if (e.ctrlKey && e.key === 'b') { e.preventDefault(); toggleSidebar(); } if (e.key === 'Escape') { if (State.isGenerating) { stopGeneration(); } else if (document.getElementById('settingsModal').classList.contains('active')) { closeSettings(); } } }); } function handleKeyDown(e) { if (e.key === 'Enter' && !e.shiftKey) { e.preventDefault(); sendMessage(); } } function handleSaveSettings() { State.settings.apiEndpoint = document.getElementById('apiEndpoint').value.trim(); State.settings.apiKey = document.getElementById('apiKey').value.trim(); const modelCustom = document.getElementById('modelCustom').value.trim(); const modelSelect = document.getElementById('model').value; State.settings.model = modelCustom || modelSelect || 'gpt-3.5-turbo'; State.settings.stream = document.getElementById('streamResponse').checked; State.settings.saveHistory = document.getElementById('saveHistory').checked; State.settings.showThinking = document.getElementById('showThinking').checked; State.settings.systemPrompt = document.getElementById('systemPrompt').value.trim(); State.settings.maxTokens = parseInt(document.getElementById('maxTokens').value) || 4096; State.settings.temperature = parseFloat(document.getElementById('temperature').value) || 0.7; State.settings.topP = parseFloat(document.getElementById('topP').value) || 1; State.settings.presencePenalty = parseFloat(document.getElementById('presencePenalty').value) || 0; saveSettings(); updateQuickModelSelector(); closeSettings(); showToast('✅ Settings saved', 'success'); } function newChat() { State.currentChatId = null; document.getElementById('chatMessages').innerHTML = `
Type a message below to begin