📜
settings_copy.js
Back
📝 Javascript ⚡ Executable Ctrl+S: Save • Ctrl+R: Run • Ctrl+F: Find
// settings.js - Settings Management (function() { console.log("[settings] Loading Settings interface..."); // --- Model Configuration --- const MODEL_CONFIG = { 'grok-code-fast-1': { provider: 'xai', name: 'Grok Code Fast 1', icon: '🤖', color: '#8b5cf6' }, 'deepseek-chat': { provider: 'deepseek', name: 'DeepSeek Chat', icon: '🧠', color: '#3b82f6' }, 'deepseek-reasoner': { provider: 'deepseek', name: 'DeepSeek Reasoner', icon: '🧠', color: '#3b82f6' }, 'gpt-4o': { provider: 'openai', name: 'GPT-4o', icon: '🌟', color: '#10b981' }, 'gpt-4o-mini': { provider: 'openai', name: 'GPT-4o Mini', icon: '🌟', color: '#10b981' }, 'grok-3': { provider: 'xai', name: 'Grok 3', icon: '🤖', color: '#8b5cf6' } }; const API_ENDPOINT = 'api.php'; // Load settings from localStorage let settings = { defaultModel: localStorage.getItem('settings_defaultModel') || 'grok-code-fast-1', maxTokens: parseInt(localStorage.getItem('settings_maxTokens')) || 2000, temperature: parseFloat(localStorage.getItem('settings_temperature')) || 0.7, chatPrompt: localStorage.getItem('settings_chatPrompt') || 'You are a helpful AI assistant for web development.', snippetsPrompt: localStorage.getItem('settings_snippetsPrompt') || 'You are an expert at writing small, focused code snippets. Provide concise, working code examples.', fullCodePrompt: localStorage.getItem('settings_fullCodePrompt') || 'You are an expert full-stack developer. Provide complete, production-ready code solutions.', responseMode: localStorage.getItem('settings_responseMode') || 'normal', currentMode: localStorage.getItem('settings_currentMode') || 'chat' }; // Save settings to localStorage function saveSettings() { localStorage.setItem('settings_defaultModel', settings.defaultModel); localStorage.setItem('settings_maxTokens', settings.maxTokens); localStorage.setItem('settings_temperature', settings.temperature); localStorage.setItem('settings_chatPrompt', settings.chatPrompt); localStorage.setItem('settings_snippetsPrompt', settings.snippetsPrompt); localStorage.setItem('settings_fullCodePrompt', settings.fullCodePrompt); localStorage.setItem('settings_responseMode', settings.responseMode); localStorage.setItem('settings_currentMode', settings.currentMode); console.log('[settings] Settings saved:', settings); // Dispatch event so other modules can react window.dispatchEvent(new CustomEvent('settingsUpdated', { detail: settings })); } // --- Settings Slide Configuration --- const settingsSlide = { title: 'Settings', html: ` <div style="height: 100%; overflow-y: auto; padding: 20px; background: #0a0a0a;"> <h2 style="color: #fff; font-size: 24px; margin-bottom: 24px; font-weight: 700;">⚙️ Settings</h2> <!-- AI Configuration Section --> <div style="background: #1a1a1a; border: 2px solid #2a2a2a; border-radius: 8px; padding: 20px; margin-bottom: 20px;"> <h3 style="color: #fff; font-size: 18px; margin-bottom: 16px; font-weight: 600;">🤖 AI Configuration</h3> <div style="margin-bottom: 20px;"> <label style="display: block; color: #888; font-size: 13px; font-weight: 600; margin-bottom: 8px;">Default AI Model:</label> <select id="settingsDefaultModel" style="width: 100%; padding: 10px 12px; background: #2a2a2a; border: 1px solid #3a3a3a; border-radius: 4px; color: #e0e0e0; font-size: 14px; font-family: monospace; cursor: pointer; outline: none;"> <option value="grok-code-fast-1">🤖 Grok Code Fast 1</option> <option value="deepseek-chat">🧠 DeepSeek Chat</option> <option value="deepseek-reasoner">🧠 DeepSeek Reasoner</option> <option value="gpt-4o">🌟 GPT-4o</option> <option value="gpt-4o-mini">🌟 GPT-4o Mini</option> <option value="grok-3">🤖 Grok 3</option> </select> </div> <div style="margin-bottom: 20px;"> <label style="display: block; color: #888; font-size: 13px; font-weight: 600; margin-bottom: 8px;">Max Tokens: <span id="maxTokensValue" style="color: #16a34a;">2000</span></label> <input type="range" id="settingsMaxTokens" min="500" max="8000" step="100" value="2000" style="width: 100%; cursor: pointer;" /> <div style="display: flex; justify-content: space-between; color: #666; font-size: 11px; margin-top: 4px;"> <span>500</span> <span>8000</span> </div> </div> <div style="margin-bottom: 20px;"> <label style="display: block; color: #888; font-size: 13px; font-weight: 600; margin-bottom: 8px;">Temperature: <span id="temperatureValue" style="color: #16a34a;">0.7</span></label> <input type="range" id="settingsTemperature" min="0" max="2" step="0.1" value="0.7" style="width: 100%; cursor: pointer;" /> <div style="display: flex; justify-content: space-between; color: #666; font-size: 11px; margin-top: 4px;"> <span>0.0 (Focused)</span> <span>2.0 (Creative)</span> </div> </div> <button id="saveSettingsBtn" style="width: 100%; padding: 12px; background: #16a34a; border: 1px solid #15803d; border-radius: 4px; color: #fff; font-size: 14px; font-weight: 600; cursor: pointer; transition: all 0.2s;">💾 Save Settings</button> </div> <!-- System Prompts Section --> <div style="background: #1a1a1a; border: 2px solid #2a2a2a; border-radius: 8px; padding: 20px; margin-bottom: 20px;"> <h3 style="color: #fff; font-size: 18px; margin-bottom: 16px; font-weight: 600;">📝 System Prompts & Mode</h3> <div style="margin-bottom: 20px;"> <label style="display: block; color: #888; font-size: 13px; font-weight: 600; margin-bottom: 8px;">🎨 Active Mode:</label> <select id="settingsCurrentMode" style="width: 100%; padding: 10px 12px; background: #2a2a2a; border: 1px solid #3a3a3a; border-radius: 4px; color: #e0e0e0; font-size: 14px; font-family: monospace; cursor: pointer; outline: none;"> <option value="chat">💬 Chat Mode</option> <option value="snippets">✂️ Snippets Mode</option> <option value="fullcode">🔧 Full Code Mode</option> </select> <div style="margin-top: 8px; padding: 8px 12px; background: rgba(139, 92, 246, 0.1); border: 1px solid #8b5cf6; border-radius: 4px; color: #c4b5fd; font-size: 11px; line-height: 1.4;"> This determines which system prompt is used for your conversations. </div> </div> <div style="margin-bottom: 20px;"> <label style="display: block; color: #888; font-size: 13px; font-weight: 600; margin-bottom: 8px;">💬 Chat Mode Prompt:</label> <textarea id="settingsChatPrompt" placeholder="System prompt for general chat..." style="width: 100%; min-height: 80px; padding: 10px 12px; background: #2a2a2a; border: 1px solid #3a3a3a; border-radius: 4px; color: #e0e0e0; font-size: 13px; font-family: 'Segoe UI', sans-serif; resize: vertical; outline: none;"></textarea> </div> <div style="margin-bottom: 20px;"> <label style="display: block; color: #888; font-size: 13px; font-weight: 600; margin-bottom: 8px;">✂️ Snippets Mode Prompt:</label> <textarea id="settingsSnippetsPrompt" placeholder="System prompt for code snippets..." style="width: 100%; min-height: 80px; padding: 10px 12px; background: #2a2a2a; border: 1px solid #3a3a3a; border-radius: 4px; color: #e0e0e0; font-size: 13px; font-family: 'Segoe UI', sans-serif; resize: vertical; outline: none;"></textarea> </div> <div style="margin-bottom: 20px;"> <label style="display: block; color: #888; font-size: 13px; font-weight: 600; margin-bottom: 8px;">🔧 Full Code Mode Prompt:</label> <textarea id="settingsFullCodePrompt" placeholder="System prompt for full code solutions..." style="width: 100%; min-height: 80px; padding: 10px 12px; background: #2a2a2a; border: 1px solid #3a3a3a; border-radius: 4px; color: #e0e0e0; font-size: 13px; font-family: 'Segoe UI', sans-serif; resize: vertical; outline: none;"></textarea> </div> <div style="margin-bottom: 0;"> <label style="display: block; color: #888; font-size: 13px; font-weight: 600; margin-bottom: 8px;">📤 Response Mode:</label> <select id="settingsResponseMode" style="width: 100%; padding: 10px 12px; background: #2a2a2a; border: 1px solid #3a3a3a; border-radius: 4px; color: #e0e0e0; font-size: 14px; font-family: monospace; cursor: pointer; outline: none;"> <option value="normal">📋 Normal (Formatted response)</option> <option value="raw">🔤 Raw (Plain text only)</option> </select> <div style="margin-top: 8px; padding: 8px 12px; background: rgba(59, 130, 246, 0.1); border: 1px solid #3b82f6; border-radius: 4px; color: #93c5fd; font-size: 11px; line-height: 1.4;"> <strong>Normal:</strong> AI provides explanations with code.<br> <strong>Raw:</strong> AI returns only code without commentary. </div> </div> </div> <!-- Model Information --> <div style="background: #1a1a1a; border: 2px solid #2a2a2a; border-radius: 8px; padding: 20px;"> <h3 style="color: #fff; font-size: 18px; margin-bottom: 16px; font-weight: 600;">📊 Model Information</h3> <div id="modelInfoContainer" style="font-size: 13px; line-height: 1.6;"></div> </div> </div> `, onRender(el) { console.log('[settings] Rendering settings interface'); const defaultModelSelect = el.querySelector('#settingsDefaultModel'); const maxTokensSlider = el.querySelector('#settingsMaxTokens'); const maxTokensValue = el.querySelector('#maxTokensValue'); const temperatureSlider = el.querySelector('#settingsTemperature'); const temperatureValue = el.querySelector('#temperatureValue'); const chatPrompt = el.querySelector('#settingsChatPrompt'); const snippetsPrompt = el.querySelector('#settingsSnippetsPrompt'); const fullCodePrompt = el.querySelector('#settingsFullCodePrompt'); const responseMode = el.querySelector('#settingsResponseMode'); const currentMode = el.querySelector('#settingsCurrentMode'); const saveBtn = el.querySelector('#saveSettingsBtn'); const modelInfoContainer = el.querySelector('#modelInfoContainer'); // Load current settings defaultModelSelect.value = settings.defaultModel; maxTokensSlider.value = settings.maxTokens; maxTokensValue.textContent = settings.maxTokens; temperatureSlider.value = settings.temperature; temperatureValue.textContent = settings.temperature.toFixed(1); chatPrompt.value = settings.chatPrompt; snippetsPrompt.value = settings.snippetsPrompt; fullCodePrompt.value = settings.fullCodePrompt; responseMode.value = settings.responseMode; currentMode.value = settings.currentMode; // Update max tokens display maxTokensSlider.addEventListener('input', () => { maxTokensValue.textContent = maxTokensSlider.value; }); // Update temperature display temperatureSlider.addEventListener('input', () => { temperatureValue.textContent = parseFloat(temperatureSlider.value).toFixed(1); }); // Display model info function updateModelInfo() { const modelKey = defaultModelSelect.value; const model = MODEL_CONFIG[modelKey]; if (model) { const r = parseInt(model.color.slice(1,3), 16); const g = parseInt(model.color.slice(3,5), 16); const b = parseInt(model.color.slice(5,7), 16); modelInfoContainer.innerHTML = ` <div style="padding: 12px; background: rgba(${r}, ${g}, ${b}, 0.1); border: 1px solid ${model.color}; border-radius: 6px; margin-bottom: 12px;"> <div style="font-size: 16px; margin-bottom: 8px;">${model.icon} <strong style="color: #fff;">${model.name}</strong></div> <div style="color: #888;">Provider: <span style="color: #e0e0e0; font-family: monospace;">${model.provider}</span></div> </div> <div style="color: #666; font-size: 12px; line-height: 1.6;"> <p style="margin-bottom: 8px;"><strong style="color: #888;">Max Tokens:</strong> Controls the maximum length of the response.</p> <p style="margin-bottom: 8px;"><strong style="color: #888;">Temperature:</strong> Controls creativity (0 = focused, 2 = creative).</p> </div> `; } } defaultModelSelect.addEventListener('change', updateModelInfo); updateModelInfo(); // Save settings saveBtn.addEventListener('click', () => { settings.defaultModel = defaultModelSelect.value; settings.maxTokens = parseInt(maxTokensSlider.value); settings.temperature = parseFloat(temperatureSlider.value); settings.chatPrompt = chatPrompt.value.trim(); settings.snippetsPrompt = snippetsPrompt.value.trim(); settings.fullCodePrompt = fullCodePrompt.value.trim(); settings.responseMode = responseMode.value; settings.currentMode = currentMode.value; saveSettings(); // Visual feedback saveBtn.textContent = '✅ Saved!'; saveBtn.style.background = '#15803d'; setTimeout(() => { saveBtn.textContent = '💾 Save Settings'; saveBtn.style.background = '#16a34a'; }, 1500); }); // Button hover effect saveBtn.addEventListener('mouseenter', () => { if (saveBtn.textContent === '💾 Save Settings') { saveBtn.style.background = '#15803d'; } }); saveBtn.addEventListener('mouseleave', () => { if (saveBtn.textContent === '💾 Save Settings') { saveBtn.style.background = '#16a34a'; } }); } }; // --- Expose Settings API --- window.Settings = { open: () => { if (window.AppOverlay) { window.AppOverlay.open([settingsSlide]); } else { console.error('[settings] AppOverlay not available'); } }, slide: settingsSlide, get: () => ({ ...settings }), getModelConfig: (modelKey) => MODEL_CONFIG[modelKey], getAllModels: () => MODEL_CONFIG, getApiEndpoint: () => API_ENDPOINT }; // --- Register as AppItems component --- /* if (window.AppItems) { window.AppItems.push({ title: 'Settings', html: settingsSlide.html, onRender: settingsSlide.onRender }); console.log('[settings] Registered as AppItems component'); }*/ console.log('[settings] Settings interface loaded with settings:', settings); })();