- Neue Spalte 'settings' in users-Tabelle (Migration via TryAddColumn) - SettingsEndpoint: GET/PUT /api/settings - DatabaseService: GetUserSettings() + UpdateUserSettings() - Frontend: currentSettings als globaler State in app.js - settings-page.js: localStorage komplett entfernt, nutzt API - Settings werden beim App-Start aus DB geladen und angewendet
173 lines
6.8 KiB
JavaScript
173 lines
6.8 KiB
JavaScript
// ── Settings Page ──
|
|
|
|
registerPage('settings', {
|
|
init() {
|
|
const slider = document.getElementById('settingPageWidth');
|
|
const display = document.getElementById('settingPageWidthValue');
|
|
const toolCallSelect = document.getElementById('settingToolCallDisplay');
|
|
const chainMetaSelect = document.getElementById('settingChainMetaDisplay');
|
|
const showDeletedToggle = document.getElementById('settingShowDeletedMessages');
|
|
const resetBtn = document.getElementById('settingsResetBtn');
|
|
const backupSection = document.getElementById('settingsBackupSection');
|
|
const telegramSection = document.getElementById('settingsTelegramSection');
|
|
|
|
// Backup + Telegram nur für Admins
|
|
if (currentUser && currentUser.isAdmin) {
|
|
backupSection.style.display = '';
|
|
initTelegramSection();
|
|
}
|
|
|
|
const s = loadSettings();
|
|
slider.value = s.pageWidth;
|
|
display.textContent = s.pageWidth + 'px';
|
|
toolCallSelect.value = s.toolCallDisplay;
|
|
chainMetaSelect.value = s.chainMetaDisplay;
|
|
showDeletedToggle.checked = s.showDeletedMessages;
|
|
|
|
slider.addEventListener('input', () => {
|
|
display.textContent = slider.value + 'px';
|
|
});
|
|
|
|
slider.addEventListener('change', () => {
|
|
var s = loadSettings();
|
|
s.pageWidth = parseInt(slider.value, 10);
|
|
saveSettings(s);
|
|
});
|
|
|
|
toolCallSelect.addEventListener('change', () => {
|
|
var s = loadSettings();
|
|
s.toolCallDisplay = toolCallSelect.value;
|
|
saveSettings(s);
|
|
});
|
|
|
|
chainMetaSelect.addEventListener('change', () => {
|
|
var s = loadSettings();
|
|
s.chainMetaDisplay = chainMetaSelect.value;
|
|
saveSettings(s);
|
|
});
|
|
|
|
showDeletedToggle.addEventListener('change', () => {
|
|
var s = loadSettings();
|
|
s.showDeletedMessages = showDeletedToggle.checked;
|
|
saveSettings(s);
|
|
});
|
|
|
|
const backupBtn = document.getElementById('settingsBackupBtn');
|
|
if (backupBtn) backupBtn.addEventListener('click', async () => {
|
|
backupBtn.disabled = true;
|
|
backupBtn.textContent = 'Wird erstellt...';
|
|
try {
|
|
await apiBackupDb();
|
|
} catch (e) {
|
|
console.error('Backup fehlgeschlagen:', e);
|
|
} finally {
|
|
backupBtn.textContent = 'Jetzt sichern';
|
|
backupBtn.disabled = false;
|
|
}
|
|
});
|
|
|
|
resetBtn.addEventListener('click', async () => {
|
|
if (!confirm('Alle Einstellungen auf Standard zurücksetzen?')) return;
|
|
await saveSettings(Object.assign({}, SETTINGS_DEFAULTS));
|
|
// Update UI
|
|
slider.value = SETTINGS_DEFAULTS.pageWidth;
|
|
display.textContent = SETTINGS_DEFAULTS.pageWidth + 'px';
|
|
toolCallSelect.value = SETTINGS_DEFAULTS.toolCallDisplay;
|
|
chainMetaSelect.value = SETTINGS_DEFAULTS.chainMetaDisplay;
|
|
showDeletedToggle.checked = SETTINGS_DEFAULTS.showDeletedMessages;
|
|
});
|
|
|
|
function initTelegramSection() {
|
|
// Erst prüfen ob Telegram überhaupt konfiguriert ist
|
|
apiTelegramStatus().then(s => {
|
|
if (!s.configured) return; // Bot-Token nicht gesetzt → Section versteckt lassen
|
|
telegramSection.style.display = '';
|
|
|
|
const statusBtn = document.getElementById('settingsTelegramStatusBtn');
|
|
const statusBox = document.getElementById('settingsTelegramStatusBox');
|
|
const registerBtn = document.getElementById('settingsTelegramRegisterBtn');
|
|
const deleteBtn = document.getElementById('settingsTelegramDeleteBtn');
|
|
|
|
// Status abrufen
|
|
statusBtn.addEventListener('click', async () => {
|
|
statusBtn.disabled = true;
|
|
statusBtn.textContent = 'Wird abgerufen...';
|
|
statusBox.style.display = 'none';
|
|
try {
|
|
const info = await apiTelegramWebhookInfo();
|
|
const result = info.result || {};
|
|
const url = result.url || '(kein Webhook registriert)';
|
|
const pending = result.pending_update_count ?? 0;
|
|
const lastError = result.last_error_message;
|
|
let html = `<div class="tg-status-row"><span class="tg-label">Webhook-URL</span><span class="tg-value">${escapeHtml(url)}</span></div>`;
|
|
html += `<div class="tg-status-row"><span class="tg-label">Ausstehende Updates</span><span class="tg-value">${pending}</span></div>`;
|
|
if (lastError) {
|
|
html += `<div class="tg-status-row tg-error"><span class="tg-label">Letzter Fehler</span><span class="tg-value">${escapeHtml(lastError)}</span></div>`;
|
|
}
|
|
const active = !!result.url;
|
|
html += `<div class="tg-status-row"><span class="tg-label">Status</span><span class="tg-value tg-badge ${active ? 'tg-badge-ok' : 'tg-badge-off'}">${active ? '✅ Aktiv' : '⚠️ Nicht registriert'}</span></div>`;
|
|
statusBox.innerHTML = html;
|
|
statusBox.style.display = '';
|
|
} catch (e) {
|
|
statusBox.innerHTML = `<div class="tg-status-row tg-error"><span class="tg-value">Fehler: ${escapeHtml(e.message)}</span></div>`;
|
|
statusBox.style.display = '';
|
|
} finally {
|
|
statusBtn.disabled = false;
|
|
statusBtn.textContent = 'Status abrufen';
|
|
}
|
|
});
|
|
|
|
// Webhook registrieren
|
|
registerBtn.addEventListener('click', async () => {
|
|
const baseUrl = prompt('Base-URL der App (z.B. ' + window.location.origin + '):', window.location.origin);
|
|
if (!baseUrl) return;
|
|
registerBtn.disabled = true;
|
|
registerBtn.textContent = 'Wird registriert...';
|
|
try {
|
|
const res = await apiTelegramRegisterWebhook(baseUrl.trim());
|
|
if (res.result && res.result.ok) {
|
|
alert('✅ Webhook erfolgreich registriert!');
|
|
} else {
|
|
alert('Antwort: ' + JSON.stringify(res.result));
|
|
}
|
|
} catch (e) {
|
|
alert('Fehler: ' + e.message);
|
|
} finally {
|
|
registerBtn.disabled = false;
|
|
registerBtn.textContent = 'Registrieren';
|
|
}
|
|
});
|
|
|
|
// Webhook löschen
|
|
deleteBtn.addEventListener('click', async () => {
|
|
if (!confirm('Webhook wirklich entfernen? Der Bot empfängt dann keine Nachrichten mehr.')) return;
|
|
deleteBtn.disabled = true;
|
|
deleteBtn.textContent = 'Wird entfernt...';
|
|
try {
|
|
const res = await apiTelegramDeleteWebhook();
|
|
if (res.ok) {
|
|
alert('✅ Webhook erfolgreich entfernt.');
|
|
} else {
|
|
alert('Antwort: ' + JSON.stringify(res));
|
|
}
|
|
} catch (e) {
|
|
alert('Fehler: ' + e.message);
|
|
} finally {
|
|
deleteBtn.disabled = false;
|
|
deleteBtn.textContent = 'Webhook entfernen';
|
|
}
|
|
});
|
|
});
|
|
}
|
|
},
|
|
destroy() {}
|
|
});
|
|
|
|
function escapeHtml(str) {
|
|
return String(str)
|
|
.replace(/&/g, '&')
|
|
.replace(/</g, '<')
|
|
.replace(/>/g, '>')
|
|
.replace(/"/g, '"');
|
|
}
|