import { html, css, LitElement } from '../../assets/lit-core-2.7.4.min.js'; import { resizeLayout } from '../../utils/windowResize.js'; export class CustomizeView extends LitElement { static styles = css` * { font-family: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif; cursor: default; user-select: none; } :host { display: block; height: 100%; } .settings-layout { display: flex; height: 100%; } /* Sidebar */ .settings-sidebar { width: 160px; min-width: 160px; border-right: 1px solid var(--border-color); padding: 8px 0; display: flex; flex-direction: column; gap: 2px; } .sidebar-item { display: flex; align-items: center; gap: 10px; padding: 8px 12px; margin: 0 8px; border-radius: 3px; font-size: 12px; color: var(--text-secondary); cursor: pointer; transition: all 0.1s ease; border: none; background: transparent; text-align: left; width: calc(100% - 16px); } .sidebar-item:hover { background: var(--hover-background); color: var(--text-color); } .sidebar-item.active { background: var(--bg-tertiary); color: var(--text-color); } .sidebar-item svg { width: 16px; height: 16px; flex-shrink: 0; } .sidebar-item.danger { color: var(--error-color); } .sidebar-item.danger:hover, .sidebar-item.danger.active { color: var(--error-color); } /* Main content */ .settings-content { flex: 1; padding: 16px 0; overflow-y: auto; display: flex; flex-direction: column; } .settings-content > * { flex-shrink: 0; } .settings-content > .profile-section { flex: 1; min-height: 0; } .settings-content::-webkit-scrollbar { width: 8px; } .settings-content::-webkit-scrollbar-track { background: transparent; } .settings-content::-webkit-scrollbar-thumb { background: var(--scrollbar-thumb); border-radius: 4px; } .settings-content::-webkit-scrollbar-thumb:hover { background: var(--scrollbar-thumb-hover); } .content-header { font-size: 16px; font-weight: 600; color: var(--text-color); margin-bottom: 16px; padding: 0 16px 12px 16px; border-bottom: 1px solid var(--border-color); } .settings-section { padding: 12px 16px; } .section-title { font-size: 11px; font-weight: 600; color: var(--text-muted); text-transform: uppercase; letter-spacing: 0.5px; margin-bottom: 12px; } .form-grid { display: grid; gap: 12px; padding: 0 16px; } .form-row { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; align-items: start; } @media (max-width: 600px) { .form-row { grid-template-columns: 1fr; } } .form-group { display: flex; flex-direction: column; gap: 6px; } .form-group.full-width { grid-column: 1 / -1; } .form-label { font-weight: 500; font-size: 12px; color: var(--text-color); display: flex; align-items: center; gap: 6px; } .form-description { font-size: 11px; color: var(--text-muted); line-height: 1.4; margin-top: 2px; } .form-control { background: var(--input-background); color: var(--text-color); border: 1px solid var(--border-color); padding: 8px 10px; border-radius: 3px; font-size: 12px; transition: border-color 0.1s ease; } .form-control:focus { outline: none; border-color: var(--border-default); } .form-control:hover:not(:focus) { border-color: var(--border-default); } select.form-control { cursor: pointer; appearance: none; background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 20 20'%3e%3cpath stroke='%236b6b6b' stroke-linecap='round' stroke-linejoin='round' stroke-width='1.5' d='M6 8l4 4 4-4'/%3e%3c/svg%3e"); background-position: right 8px center; background-repeat: no-repeat; background-size: 12px; padding-right: 28px; } textarea.form-control { resize: vertical; min-height: 60px; line-height: 1.4; font-family: inherit; } /* Profile section with expanding textarea */ .profile-section { display: flex; flex-direction: column; height: 100%; } .profile-section .form-grid { flex: 1; display: flex; flex-direction: column; } .profile-section .form-group.expand { flex: 1; display: flex; flex-direction: column; } .profile-section .form-group.expand textarea { flex: 1; resize: none; } textarea.form-control::placeholder { color: var(--placeholder-color); } .current-selection { display: inline-flex; align-items: center; font-size: 10px; color: var(--text-secondary); background: var(--bg-tertiary); padding: 2px 6px; border-radius: 3px; font-weight: 500; } .keybind-input { cursor: pointer; font-family: 'SF Mono', Monaco, monospace; text-align: center; letter-spacing: 0.5px; font-weight: 500; } .keybind-input:focus { cursor: text; } .keybind-input::placeholder { color: var(--placeholder-color); font-style: italic; } .reset-keybinds-button { background: transparent; color: var(--text-color); border: 1px solid var(--border-color); padding: 6px 10px; border-radius: 3px; font-size: 11px; font-weight: 500; cursor: pointer; transition: background 0.1s ease; } .reset-keybinds-button:hover { background: var(--hover-background); } .keybinds-table { width: 100%; border-collapse: collapse; margin-top: 8px; } .keybinds-table th, .keybinds-table td { padding: 8px 0; text-align: left; border-bottom: 1px solid var(--border-color); } .keybinds-table th { font-weight: 600; font-size: 11px; color: var(--text-muted); text-transform: uppercase; letter-spacing: 0.5px; } .keybinds-table td { vertical-align: middle; } .keybinds-table .action-name { font-weight: 500; color: var(--text-color); font-size: 12px; } .keybinds-table .action-description { font-size: 10px; color: var(--text-muted); margin-top: 1px; } .keybinds-table .keybind-input { min-width: 100px; padding: 4px 8px; margin: 0; font-size: 11px; } .keybinds-table tr:hover { background: var(--hover-background); } .keybinds-table tr:last-child td { border-bottom: none; } .table-reset-row { border-top: 1px solid var(--border-color); } .table-reset-row td { padding-top: 10px; padding-bottom: 8px; border-bottom: none; } .table-reset-row:hover { background: transparent; } .settings-note { font-size: 11px; color: var(--text-muted); text-align: center; margin-top: 16px; padding: 12px; border-top: 1px solid var(--border-color); } .checkbox-group { display: flex; align-items: center; gap: 8px; padding: 8px 0; } .checkbox-input { width: 14px; height: 14px; accent-color: var(--text-color); cursor: pointer; } .checkbox-label { font-weight: 500; font-size: 12px; color: var(--text-color); cursor: pointer; user-select: none; } /* Slider styles */ .slider-container { display: flex; flex-direction: column; gap: 8px; } .slider-header { display: flex; justify-content: space-between; align-items: center; } .slider-value { font-size: 11px; color: var(--text-secondary); background: var(--bg-tertiary); padding: 2px 6px; border-radius: 3px; font-weight: 500; font-family: 'SF Mono', Monaco, monospace; } .slider-input { -webkit-appearance: none; appearance: none; width: 100%; height: 4px; border-radius: 2px; background: var(--border-color); outline: none; cursor: pointer; } .slider-input::-webkit-slider-thumb { -webkit-appearance: none; appearance: none; width: 14px; height: 14px; border-radius: 50%; background: var(--text-color); cursor: pointer; border: none; } .slider-input::-moz-range-thumb { width: 14px; height: 14px; border-radius: 50%; background: var(--text-color); cursor: pointer; border: none; } .slider-labels { display: flex; justify-content: space-between; margin-top: 4px; font-size: 10px; color: var(--text-muted); } /* Color picker styles */ .color-picker-container { display: flex; align-items: center; gap: 10px; } .color-picker-input { -webkit-appearance: none; appearance: none; width: 40px; height: 32px; border: 1px solid var(--border-color); border-radius: 3px; cursor: pointer; padding: 2px; background: var(--input-background); } .color-picker-input::-webkit-color-swatch-wrapper { padding: 0; } .color-picker-input::-webkit-color-swatch { border: none; border-radius: 2px; } .color-hex-input { width: 80px; font-family: 'SF Mono', Monaco, monospace; text-transform: uppercase; } .reset-color-button { background: transparent; color: var(--text-secondary); border: 1px solid var(--border-color); padding: 6px 10px; border-radius: 3px; font-size: 11px; font-weight: 500; cursor: pointer; transition: all 0.1s ease; } .reset-color-button:hover { background: var(--hover-background); color: var(--text-color); } /* Danger button and status */ .danger-button { background: transparent; color: var(--error-color); border: 1px solid var(--error-color); padding: 8px 14px; border-radius: 3px; font-size: 11px; font-weight: 500; cursor: pointer; transition: background 0.1s ease; } .danger-button:hover { background: rgba(241, 76, 76, 0.1); } .danger-button:disabled { opacity: 0.5; cursor: not-allowed; } .status-message { margin-top: 12px; padding: 8px 12px; border-radius: 3px; font-size: 11px; font-weight: 500; } .status-success { background: var(--bg-secondary); color: var(--success-color); border-left: 2px solid var(--success-color); } .status-error { background: var(--bg-secondary); color: var(--error-color); border-left: 2px solid var(--error-color); } `; static properties = { selectedProfile: { type: String }, selectedLanguage: { type: String }, selectedImageQuality: { type: String }, layoutMode: { type: String }, keybinds: { type: Object }, googleSearchEnabled: { type: Boolean }, backgroundTransparency: { type: Number }, fontSize: { type: Number }, theme: { type: String }, onProfileChange: { type: Function }, onLanguageChange: { type: Function }, onImageQualityChange: { type: Function }, onLayoutModeChange: { type: Function }, activeSection: { type: String }, isClearing: { type: Boolean }, clearStatusMessage: { type: String }, clearStatusType: { type: String }, }; constructor() { super(); this.selectedProfile = 'interview'; this.selectedLanguage = 'en-US'; this.selectedImageQuality = 'medium'; this.layoutMode = 'normal'; this.keybinds = this.getDefaultKeybinds(); this.onProfileChange = () => {}; this.onLanguageChange = () => {}; this.onImageQualityChange = () => {}; this.onLayoutModeChange = () => {}; // Google Search default this.googleSearchEnabled = true; // Clear data state this.isClearing = false; this.clearStatusMessage = ''; this.clearStatusType = ''; // Background transparency default this.backgroundTransparency = 0.8; // Font size default (in pixels) this.fontSize = 20; // Audio mode default this.audioMode = 'speaker_only'; // Custom prompt this.customPrompt = ''; // Active section for sidebar navigation this.activeSection = 'profile'; // Theme default this.theme = 'dark'; // AI Provider settings this.aiProvider = 'gemini'; this.geminiApiKey = ''; this.openaiApiKey = ''; this.openaiBaseUrl = ''; this.openaiModel = 'gpt-4o-realtime-preview-2024-12-17'; // OpenAI SDK settings this.openaiSdkApiKey = ''; this.openaiSdkBaseUrl = ''; this.openaiSdkModel = 'gpt-4o'; this.openaiSdkVisionModel = 'gpt-4o'; this.openaiSdkWhisperModel = 'whisper-1'; this._loadFromStorage(); } getThemes() { return cheatingDaddy.theme.getAll(); } setActiveSection(section) { this.activeSection = section; this.requestUpdate(); } getSidebarSections() { return [ { id: 'profile', name: 'Profile', icon: 'user' }, { id: 'ai-provider', name: 'AI Provider', icon: 'cpu' }, { id: 'appearance', name: 'Appearance', icon: 'display' }, { id: 'audio', name: 'Audio', icon: 'mic' }, { id: 'language', name: 'Language', icon: 'globe' }, { id: 'capture', name: 'Capture', icon: 'camera' }, { id: 'keyboard', name: 'Keyboard', icon: 'keyboard' }, { id: 'search', name: 'Search', icon: 'search' }, { id: 'advanced', name: 'Advanced', icon: 'warning', danger: true }, ]; } renderSidebarIcon(icon) { const icons = { user: html``, mic: html``, globe: html``, display: html``, camera: html``, keyboard: html``, search: html``, cpu: html``, warning: html``, }; return icons[icon] || ''; } async _loadFromStorage() { try { const [prefs, keybinds, credentials, openaiCreds, openaiSdkCreds] = await Promise.all([ cheatingDaddy.storage.getPreferences(), cheatingDaddy.storage.getKeybinds(), cheatingDaddy.storage.getCredentials(), cheatingDaddy.storage.getOpenAICredentials(), cheatingDaddy.storage.getOpenAISDKCredentials() ]); this.googleSearchEnabled = prefs.googleSearchEnabled ?? true; this.backgroundTransparency = prefs.backgroundTransparency ?? 0.8; this.fontSize = prefs.fontSize ?? 20; this.audioMode = prefs.audioMode ?? 'speaker_only'; this.customPrompt = prefs.customPrompt ?? ''; this.theme = prefs.theme ?? 'dark'; this.aiProvider = prefs.aiProvider ?? 'gemini'; // Load Gemini API key this.geminiApiKey = credentials.apiKey ?? ''; // Load OpenAI Realtime credentials this.openaiApiKey = openaiCreds.apiKey ?? ''; this.openaiBaseUrl = openaiCreds.baseUrl ?? ''; this.openaiModel = openaiCreds.model ?? 'gpt-4o-realtime-preview-2024-12-17'; // Load OpenAI SDK credentials this.openaiSdkApiKey = openaiSdkCreds.apiKey ?? ''; this.openaiSdkBaseUrl = openaiSdkCreds.baseUrl ?? ''; this.openaiSdkModel = openaiSdkCreds.model ?? 'gpt-4o'; this.openaiSdkVisionModel = openaiSdkCreds.visionModel ?? 'gpt-4o'; this.openaiSdkWhisperModel = openaiSdkCreds.whisperModel ?? 'whisper-1'; if (keybinds) { this.keybinds = { ...this.getDefaultKeybinds(), ...keybinds }; } this.updateBackgroundTransparency(); this.updateFontSize(); this.requestUpdate(); } catch (error) { console.error('Error loading settings:', error); } } connectedCallback() { super.connectedCallback(); // Resize window for this view resizeLayout(); } getProfiles() { return [ { value: 'interview', name: 'Job Interview', description: 'Get help with answering interview questions', }, { value: 'sales', name: 'Sales Call', description: 'Assist with sales conversations and objection handling', }, { value: 'meeting', name: 'Business Meeting', description: 'Support for professional meetings and discussions', }, { value: 'presentation', name: 'Presentation', description: 'Help with presentations and public speaking', }, { value: 'negotiation', name: 'Negotiation', description: 'Guidance for business negotiations and deals', }, { value: 'exam', name: 'Exam Assistant', description: 'Academic assistance for test-taking and exam questions', }, ]; } getLanguages() { return [ { value: 'en-US', name: 'English (US)' }, { value: 'en-GB', name: 'English (UK)' }, { value: 'en-AU', name: 'English (Australia)' }, { value: 'en-IN', name: 'English (India)' }, { value: 'de-DE', name: 'German (Germany)' }, { value: 'es-US', name: 'Spanish (United States)' }, { value: 'es-ES', name: 'Spanish (Spain)' }, { value: 'fr-FR', name: 'French (France)' }, { value: 'fr-CA', name: 'French (Canada)' }, { value: 'hi-IN', name: 'Hindi (India)' }, { value: 'pt-BR', name: 'Portuguese (Brazil)' }, { value: 'ar-XA', name: 'Arabic (Generic)' }, { value: 'id-ID', name: 'Indonesian (Indonesia)' }, { value: 'it-IT', name: 'Italian (Italy)' }, { value: 'ja-JP', name: 'Japanese (Japan)' }, { value: 'tr-TR', name: 'Turkish (Turkey)' }, { value: 'vi-VN', name: 'Vietnamese (Vietnam)' }, { value: 'bn-IN', name: 'Bengali (India)' }, { value: 'gu-IN', name: 'Gujarati (India)' }, { value: 'kn-IN', name: 'Kannada (India)' }, { value: 'ml-IN', name: 'Malayalam (India)' }, { value: 'mr-IN', name: 'Marathi (India)' }, { value: 'ta-IN', name: 'Tamil (India)' }, { value: 'te-IN', name: 'Telugu (India)' }, { value: 'nl-NL', name: 'Dutch (Netherlands)' }, { value: 'ko-KR', name: 'Korean (South Korea)' }, { value: 'cmn-CN', name: 'Mandarin Chinese (China)' }, { value: 'pl-PL', name: 'Polish (Poland)' }, { value: 'ru-RU', name: 'Russian (Russia)' }, { value: 'th-TH', name: 'Thai (Thailand)' }, ]; } getProfileNames() { return { interview: 'Job Interview', sales: 'Sales Call', meeting: 'Business Meeting', presentation: 'Presentation', negotiation: 'Negotiation', exam: 'Exam Assistant', }; } handleProfileSelect(e) { this.selectedProfile = e.target.value; this.onProfileChange(this.selectedProfile); } handleLanguageSelect(e) { this.selectedLanguage = e.target.value; this.onLanguageChange(this.selectedLanguage); } handleImageQualitySelect(e) { this.selectedImageQuality = e.target.value; this.onImageQualityChange(e.target.value); } handleLayoutModeSelect(e) { this.layoutMode = e.target.value; this.onLayoutModeChange(e.target.value); } async handleCustomPromptInput(e) { this.customPrompt = e.target.value; await cheatingDaddy.storage.updatePreference('customPrompt', e.target.value); } async handleAudioModeSelect(e) { this.audioMode = e.target.value; await cheatingDaddy.storage.updatePreference('audioMode', e.target.value); this.requestUpdate(); } async handleThemeChange(e) { this.theme = e.target.value; await cheatingDaddy.theme.save(this.theme); this.updateBackgroundAppearance(); this.requestUpdate(); } getDefaultKeybinds() { const isMac = cheatingDaddy.isMacOS || navigator.platform.includes('Mac'); return { moveUp: isMac ? 'Alt+Up' : 'Ctrl+Up', moveDown: isMac ? 'Alt+Down' : 'Ctrl+Down', moveLeft: isMac ? 'Alt+Left' : 'Ctrl+Left', moveRight: isMac ? 'Alt+Right' : 'Ctrl+Right', toggleVisibility: isMac ? 'Cmd+\\' : 'Ctrl+\\', toggleClickThrough: isMac ? 'Cmd+M' : 'Ctrl+M', nextStep: isMac ? 'Cmd+Enter' : 'Ctrl+Enter', previousResponse: isMac ? 'Cmd+[' : 'Ctrl+[', nextResponse: isMac ? 'Cmd+]' : 'Ctrl+]', scrollUp: isMac ? 'Cmd+Shift+Up' : 'Ctrl+Shift+Up', scrollDown: isMac ? 'Cmd+Shift+Down' : 'Ctrl+Shift+Down', }; } async saveKeybinds() { await cheatingDaddy.storage.setKeybinds(this.keybinds); // Send to main process to update global shortcuts if (window.require) { const { ipcRenderer } = window.require('electron'); ipcRenderer.send('update-keybinds', this.keybinds); } } handleKeybindChange(action, value) { this.keybinds = { ...this.keybinds, [action]: value }; this.saveKeybinds(); this.requestUpdate(); } async resetKeybinds() { this.keybinds = this.getDefaultKeybinds(); await cheatingDaddy.storage.setKeybinds(null); this.requestUpdate(); if (window.require) { const { ipcRenderer } = window.require('electron'); ipcRenderer.send('update-keybinds', this.keybinds); } } getKeybindActions() { return [ { key: 'moveUp', name: 'Move Window Up', description: 'Move the application window up', }, { key: 'moveDown', name: 'Move Window Down', description: 'Move the application window down', }, { key: 'moveLeft', name: 'Move Window Left', description: 'Move the application window left', }, { key: 'moveRight', name: 'Move Window Right', description: 'Move the application window right', }, { key: 'toggleVisibility', name: 'Toggle Window Visibility', description: 'Show/hide the application window', }, { key: 'toggleClickThrough', name: 'Toggle Click-through Mode', description: 'Enable/disable click-through functionality', }, { key: 'nextStep', name: 'Ask Next Step', description: 'Take screenshot and ask AI for the next step suggestion', }, { key: 'previousResponse', name: 'Previous Response', description: 'Navigate to the previous AI response', }, { key: 'nextResponse', name: 'Next Response', description: 'Navigate to the next AI response', }, { key: 'scrollUp', name: 'Scroll Response Up', description: 'Scroll the AI response content up', }, { key: 'scrollDown', name: 'Scroll Response Down', description: 'Scroll the AI response content down', }, ]; } handleKeybindFocus(e) { e.target.placeholder = 'Press key combination...'; e.target.select(); } handleKeybindInput(e) { e.preventDefault(); const modifiers = []; const keys = []; // Check modifiers if (e.ctrlKey) modifiers.push('Ctrl'); if (e.metaKey) modifiers.push('Cmd'); if (e.altKey) modifiers.push('Alt'); if (e.shiftKey) modifiers.push('Shift'); // Get the main key let mainKey = e.key; // Handle special keys switch (e.code) { case 'ArrowUp': mainKey = 'Up'; break; case 'ArrowDown': mainKey = 'Down'; break; case 'ArrowLeft': mainKey = 'Left'; break; case 'ArrowRight': mainKey = 'Right'; break; case 'Enter': mainKey = 'Enter'; break; case 'Space': mainKey = 'Space'; break; case 'Backslash': mainKey = '\\'; break; case 'KeyS': if (e.shiftKey) mainKey = 'S'; break; case 'KeyM': mainKey = 'M'; break; default: if (e.key.length === 1) { mainKey = e.key.toUpperCase(); } break; } // Skip if only modifier keys are pressed if (['Control', 'Meta', 'Alt', 'Shift'].includes(e.key)) { return; } // Construct keybind string const keybind = [...modifiers, mainKey].join('+'); // Get the action from the input's data attribute const action = e.target.dataset.action; // Update the keybind this.handleKeybindChange(action, keybind); // Update the input value e.target.value = keybind; e.target.blur(); } async handleGoogleSearchChange(e) { this.googleSearchEnabled = e.target.checked; await cheatingDaddy.storage.updatePreference('googleSearchEnabled', this.googleSearchEnabled); // Notify main process if available if (window.require) { try { const { ipcRenderer } = window.require('electron'); await ipcRenderer.invoke('update-google-search-setting', this.googleSearchEnabled); } catch (error) { console.error('Failed to notify main process:', error); } } this.requestUpdate(); } async handleAIProviderChange(e) { this.aiProvider = e.target.value; await cheatingDaddy.storage.updatePreference('aiProvider', e.target.value); this.requestUpdate(); } async handleGeminiApiKeyInput(e) { this.geminiApiKey = e.target.value; await cheatingDaddy.storage.setApiKey(e.target.value); } async handleOpenAIApiKeyInput(e) { this.openaiApiKey = e.target.value; await cheatingDaddy.storage.setOpenAICredentials({ apiKey: e.target.value }); } async handleOpenAIBaseUrlInput(e) { this.openaiBaseUrl = e.target.value; await cheatingDaddy.storage.setOpenAICredentials({ baseUrl: e.target.value }); } async handleOpenAIModelInput(e) { this.openaiModel = e.target.value; await cheatingDaddy.storage.setOpenAICredentials({ model: e.target.value }); } // OpenAI SDK handlers async handleOpenAISdkApiKeyInput(e) { this.openaiSdkApiKey = e.target.value; await cheatingDaddy.storage.setOpenAISDKCredentials({ apiKey: e.target.value }); } async handleOpenAISdkBaseUrlInput(e) { this.openaiSdkBaseUrl = e.target.value; await cheatingDaddy.storage.setOpenAISDKCredentials({ baseUrl: e.target.value }); } async handleOpenAISdkModelInput(e) { this.openaiSdkModel = e.target.value; await cheatingDaddy.storage.setOpenAISDKCredentials({ model: e.target.value }); } async handleOpenAISdkVisionModelInput(e) { this.openaiSdkVisionModel = e.target.value; await cheatingDaddy.storage.setOpenAISDKCredentials({ visionModel: e.target.value }); } async handleOpenAISdkWhisperModelInput(e) { this.openaiSdkWhisperModel = e.target.value; await cheatingDaddy.storage.setOpenAISDKCredentials({ whisperModel: e.target.value }); } async clearLocalData() { if (this.isClearing) return; this.isClearing = true; this.clearStatusMessage = ''; this.clearStatusType = ''; this.requestUpdate(); try { await cheatingDaddy.storage.clearAll(); this.clearStatusMessage = 'Successfully cleared all local data'; this.clearStatusType = 'success'; this.requestUpdate(); // Close the application after a short delay setTimeout(() => { this.clearStatusMessage = 'Closing application...'; this.requestUpdate(); setTimeout(async () => { if (window.require) { const { ipcRenderer } = window.require('electron'); await ipcRenderer.invoke('quit-application'); } }, 1000); }, 2000); } catch (error) { console.error('Error clearing data:', error); this.clearStatusMessage = `Error clearing data: ${error.message}`; this.clearStatusType = 'error'; } finally { this.isClearing = false; this.requestUpdate(); } } async handleBackgroundTransparencyChange(e) { this.backgroundTransparency = parseFloat(e.target.value); await cheatingDaddy.storage.updatePreference('backgroundTransparency', this.backgroundTransparency); this.updateBackgroundAppearance(); this.requestUpdate(); } updateBackgroundAppearance() { // Use theme's background color const colors = cheatingDaddy.theme.get(this.theme); cheatingDaddy.theme.applyBackgrounds(colors.background, this.backgroundTransparency); } // Keep old function name for backwards compatibility updateBackgroundTransparency() { this.updateBackgroundAppearance(); } async handleFontSizeChange(e) { this.fontSize = parseInt(e.target.value, 10); await cheatingDaddy.storage.updatePreference('fontSize', this.fontSize); this.updateFontSize(); this.requestUpdate(); } updateFontSize() { const root = document.documentElement; root.style.setProperty('--response-font-size', `${this.fontSize}px`); } renderProfileSection() { const profiles = this.getProfiles(); const profileNames = this.getProfileNames(); const currentProfile = profiles.find(p => p.value === this.selectedProfile); return html`
| Action | Shortcut |
|---|---|
|
${action.name}
${action.description}
|
|