import { db } from '../../db/database.js'; import { Clipboard } from '@capacitor/clipboard'; import { authService } from '../../services/auth-service.js'; import { AuthView } from '../auth/auth-view.js'; import { promptQuickSettingsTile } from '../../services/quick-settings-service.js'; export class SettingsView { constructor(containerId) { this.container = document.getElementById(containerId); } init() { this.render(); this.attachEvents(); } render() { const currentModel = db.getSetting('model') || 'gemini-3.5-flash'; const currentApiKey = db.getSetting('gemini_api_key') || ''; const groqApiKey = db.getSetting('groq_api_key') || ''; const openrouterApiKey = db.getSetting('openrouter_api_key') || ''; const deepseekApiKey = db.getSetting('deepseek_api_key') || ''; const huggingfaceApiKey = db.getSetting('huggingface_api_key') || ''; const ollamaUrl = db.getSetting('ollama_url') || 'http://localhost:11434'; const startBehavior = db.getSetting('start_behavior') || 'new'; const bgStyle = db.getSetting('background_style') || 'standard'; this.container.innerHTML = `

Einstellungen

Passe die SchoolMind KI an deine Bedürfnisse an.

☁️ Cloud Account

Sichere deine Chats und API Keys mit End-zu-End Verschlüsselung und synchronisiere sie zwischen Geräten.

🧠 KI-Modell

🔑 API-Schlüssel & Verbindungen

🚀 Startverhalten

🎨 Hintergrund-Stil

✍️ Schreibstil-Profil

Dein persönlicher Stil (Note 2, 12. Klasse) ist aktiv und steuert jede Antwort der KI.

⚙️ System-Integration

Füge Schnelleingabe zu deinen Android Quick Settings hinzu (Android 13+).

`; } attachEvents() { const saveBtn = document.getElementById('save-settings-btn'); // Attach paste button listeners document.querySelectorAll('.paste-key-btn').forEach(btn => { btn.addEventListener('click', async (e) => { e.preventDefault(); const targetId = btn.getAttribute('data-target'); const input = document.getElementById(targetId); if (!input) return; // Force focus into the input field so the OS knows we are in typing mode input.focus(); try { // 1. Try native Capacitor clipboard (works reliably if inside Android/iOS App wrapper) let text = ''; try { const result = await Clipboard.read(); text = result.value; } catch(err) { // 2. Fallback to Web API (works in secure contexts) if (navigator.clipboard && navigator.clipboard.readText) { text = await navigator.clipboard.readText(); } } if (text) { input.value = text.trim(); const originalHTML = btn.innerHTML; btn.innerHTML = ``; setTimeout(() => { btn.innerHTML = originalHTML; }, 2000); } else { // 3. Fallback: just trigger native paste event document.execCommand('paste'); } } catch (error) { console.warn('Konnte nicht einfügen', error); document.execCommand('paste'); } }); }); if (!saveBtn) return; saveBtn.addEventListener('click', () => { const model = document.getElementById('model-select').value; const apiKey = document.getElementById('api-key-input').value.trim(); const tavilyKey = document.getElementById('tavily-key-input').value.trim(); const groqKey = document.getElementById('groq-key-input').value.trim(); const orKey = document.getElementById('openrouter-key-input').value.trim(); const dsKey = document.getElementById('deepseek-key-input').value.trim(); const hfKey = document.getElementById('huggingface-key-input').value.trim(); const serpApiKey = document.getElementById('serpapi-key-input').value.trim(); const deeplKey = document.getElementById('deepl-key-input').value.trim(); const ollamaUrl = document.getElementById('ollama-url-input').value.trim(); const startBehavior = document.getElementById('start-behavior-select').value; const bgStyle = document.getElementById('background-style-select').value; const styleProfile = document.getElementById('style-profile-input').value.trim(); db.setSetting('model', model); db.setSetting('style_profile', styleProfile); db.setSetting('start_behavior', startBehavior); db.setSetting('background_style', bgStyle); document.body.dataset.bgStyle = bgStyle; if (apiKey) db.setSetting('gemini_api_key', apiKey); if (tavilyKey !== undefined) db.setSetting('tavily_api_key', tavilyKey); if (groqKey) db.setSetting('groq_api_key', groqKey); if (orKey) db.setSetting('openrouter_api_key', orKey); if (dsKey) db.setSetting('deepseek_api_key', dsKey); if (hfKey) db.setSetting('huggingface_api_key', hfKey); if (serpApiKey) db.setSetting('serpapi_key', serpApiKey); if (deeplKey) db.setSetting('deepl_api_key', deeplKey); if (ollamaUrl) db.setSetting('ollama_url', ollamaUrl); // Visual feedback const originalText = saveBtn.innerText; saveBtn.innerText = 'Gespeichert! ✓'; saveBtn.style.color = 'var(--success)'; saveBtn.style.borderColor = 'rgba(48, 209, 88, 0.3)'; setTimeout(() => { saveBtn.innerText = originalText; saveBtn.style.color = 'var(--primary-accent)'; saveBtn.style.borderColor = 'rgba(0, 122, 255, 0.3)'; }, 2000); }); this.updateAccountStatus(); authService.onAuthStateChange(() => { this.updateAccountStatus(); }); const addTileBtn = document.getElementById('add-quick-tile-btn'); if (addTileBtn) { addTileBtn.addEventListener('click', async () => { const originalText = addTileBtn.innerText; addTileBtn.innerText = 'Wird angefragt...'; const success = await promptQuickSettingsTile(); if (success) { addTileBtn.innerText = 'Hinzugefügt ✓'; addTileBtn.style.color = 'var(--success)'; } else { addTileBtn.innerText = 'Nicht unterstützt oder Fehler'; addTileBtn.style.color = '#ff3b30'; } setTimeout(() => { addTileBtn.innerText = originalText; addTileBtn.style.color = 'white'; }, 3000); }); } } updateAccountStatus() { const container = this.container.querySelector('#account-status-container'); if (!container) return; if (authService.user) { const email = authService.user.email; const isUnlocked = authService.isCryptoUnlocked(); container.innerHTML = `
Eingeloggt als
${email}
${isUnlocked ? '🔒 E2E Verschlüsselung aktiv' : '🔓 Keys gesperrt (Passwort benötigt)'}
`; container.querySelector('#auth-action-btn').addEventListener('click', () => { if (isUnlocked) { authService.signOut(); } else { const authView = new AuthView(); authView.show(); } }); } else { container.innerHTML = ` `; container.querySelector('#auth-action-btn').addEventListener('click', () => { const authView = new AuthView(); authView.show(); }); } } }