// ── Session Edit Page ── let _sessionImageData = null; let _sessionPasteHandler = null; registerPage('session', { async init(params) { const sessionId = params.id; const isNew = !sessionId; let session = null; if (!isNew) { session = await apiGetSession(sessionId); if (!session) return navigateTo('dashboard'); } const titleEl = document.getElementById('sessionPageTitle'); const nameEl = document.getElementById('sessionName'); const descEl = document.getElementById('sessionDescription'); const contextEl = document.getElementById('sessionContext'); const workspaceEl = document.getElementById('sessionWorkspace'); const agentSelect = document.getElementById('agentSelect'); const imagePreview = document.getElementById('sessionImagePreview'); const imageInput = document.getElementById('sessionImageInput'); const imageBtn = document.getElementById('sessionImageBtn'); const imageClearBtn = document.getElementById('sessionImageClearBtn'); const saveBtn = document.getElementById('sessionSaveBtn'); const cancelBtn = document.getElementById('sessionCancelBtn'); const deleteBtn = document.getElementById('sessionDeleteBtn'); const commandsList = document.getElementById('customCommandsList'); const addCommandBtn = document.getElementById('addCommandBtn'); _sessionImageData = null; if (session) { titleEl.textContent = session.name || 'Unbenannt'; nameEl.value = session.name || ''; descEl.value = session.description || ''; contextEl.value = session.context || ''; workspaceEl.value = session.workspace || ''; _sessionImageData = session.image || null; deleteBtn.hidden = false; if (session.image) { imagePreview.innerHTML = ``; } // Custom Commands laden loadCommandsIntoUI(commandsList, session.customCommands); } else { titleEl.textContent = 'Neue Session'; deleteBtn.hidden = true; } // Befehl hinzufügen addCommandBtn.addEventListener('click', () => createCommandRow(commandsList)); // Telegram-Section nur für existierende Sessions if (!isNew) { initSessionTelegram(sessionId); } // Agents laden const agents = await apiGetAgents(); agentSelect.innerHTML = ''; for (const a of agents) { const opt = document.createElement('option'); opt.value = a.agentId; opt.textContent = `${a.name} (${a.model})`; agentSelect.appendChild(opt); } if (session && session.agentId) agentSelect.value = session.agentId; // Bild Upload imageBtn.addEventListener('click', () => imageInput.click()); imageInput.addEventListener('change', () => { const file = imageInput.files[0]; if (!file) return; const reader = new FileReader(); reader.onload = () => { _sessionImageData = reader.result; imagePreview.innerHTML = ``; }; reader.readAsDataURL(file); }); imageClearBtn.addEventListener('click', () => { _sessionImageData = null; imagePreview.innerHTML = '?'; imageInput.value = ''; }); // Bild Paste (Ctrl+V) document.addEventListener('paste', _sessionPasteHandler = (e) => { const items = e.clipboardData?.items; if (!items) return; for (const item of items) { if (item.type.startsWith('image/')) { e.preventDefault(); const file = item.getAsFile(); if (!file) return; const reader = new FileReader(); reader.onload = () => { _sessionImageData = reader.result; imagePreview.innerHTML = ``; }; reader.readAsDataURL(file); return; } } }); // Workspace Browse const workspaceBrowse = document.getElementById('sessionWorkspaceBrowse'); if (workspaceBrowse) { workspaceBrowse.addEventListener('click', () => { openFolderBrowser({ startPath: workspaceEl.value.trim() || '/', onSelect(path) { workspaceEl.value = path; } }); }); } // Speichern saveBtn.addEventListener('click', async () => { const commands = getCommandsFromUI(commandsList); const data = { name: nameEl.value.trim() || 'Unbenannt', description: descEl.value.trim(), image: _sessionImageData, agentId: agentSelect.value || null, context: contextEl.value || null, workspace: workspaceEl.value.trim() || null, customCommands: commands }; if (isNew) { await apiCreateSession(data); } else { await apiUpdateSession(sessionId, data); // Telegram-Config mitspeichern (falls Section sichtbar) var tgToken = document.getElementById('sessionTelegramToken'); var tgSecret = document.getElementById('sessionTelegramSecret'); if (tgToken) { try { await saveTelegramConfig(sessionId, tgToken, tgSecret); } catch(e) { showToast('Session gespeichert, aber Telegram-Fehler: ' + e.message, 'error'); return; } } } navigateTo('dashboard'); }); // Abbrechen cancelBtn.addEventListener('click', () => navigateTo('dashboard')); // Löschen deleteBtn.addEventListener('click', async () => { if (!confirm('Session wirklich löschen?')) return; await apiDeleteSession(sessionId); navigateTo('dashboard'); }); }, destroy() { if (_sessionPasteHandler) { document.removeEventListener('paste', _sessionPasteHandler); _sessionPasteHandler = null; } _sessionImageData = null; } }); function initSessionTelegram(sessionId) { var tokenInput = document.getElementById('sessionTelegramToken'); var secretInput = document.getElementById('sessionTelegramSecret'); var registerBtn = document.getElementById('sessionTelegramRegisterBtn'); var deleteBtn = document.getElementById('sessionTelegramDeleteBtn'); var statusBox = document.getElementById('sessionTelegramStatusBox'); // Vorhandene Config laden + Status abrufen apiSessionTelegramGet(sessionId).then(async function(config) { if (config.botToken) tokenInput.value = config.botToken; if (config.webhookSecret) { secretInput.value = config.webhookSecret; } else { // Secret einmalig generieren und sofort persistent speichern var newSecret = crypto.randomUUID().replace(/-/g, ''); secretInput.value = newSecret; await apiSessionTelegramSave(sessionId, config.botToken || '', newSecret); } // Status automatisch abrufen wenn Token konfiguriert ist if (config.botToken) { refreshTelegramStatus(sessionId, statusBox, registerBtn, deleteBtn); } else { showTelegramUnconfigured(statusBox, registerBtn, deleteBtn); } }).catch(function() { showTelegramUnconfigured(statusBox, registerBtn, deleteBtn); }); // Webhook registrieren registerBtn.addEventListener('click', async function() { var baseUrl = prompt('Base-URL der App:', window.location.origin); if (!baseUrl) return; registerBtn.disabled = true; registerBtn.textContent = 'Wird registriert...'; try { // Erst Token + Secret speichern (falls geändert) await saveTelegramConfig(sessionId, tokenInput, secretInput); var res = await apiSessionTelegramRegisterWebhook(sessionId, baseUrl.trim()); if (res.ok) { showToast('Webhook registriert!', 'success'); } else { showToast('Antwort: ' + JSON.stringify(res), 'error'); } } catch(e) { showToast('Fehler: ' + e.message, 'error'); } finally { registerBtn.disabled = false; registerBtn.textContent = 'Webhook registrieren'; refreshTelegramStatus(sessionId, statusBox, registerBtn, deleteBtn); } }); // Webhook entfernen deleteBtn.addEventListener('click', async function() { if (!confirm('Webhook wirklich entfernen?')) return; deleteBtn.disabled = true; deleteBtn.textContent = 'Wird entfernt...'; try { var res = await apiSessionTelegramDeleteWebhook(sessionId); if (res.ok) { showToast('Webhook entfernt', 'success'); } else { showToast('Antwort: ' + JSON.stringify(res), 'error'); } } catch(e) { showToast('Fehler: ' + e.message, 'error'); } finally { deleteBtn.disabled = false; deleteBtn.textContent = 'Webhook entfernen'; refreshTelegramStatus(sessionId, statusBox, registerBtn, deleteBtn); } }); } function showTelegramUnconfigured(statusBox, registerBtn, deleteBtn) { statusBox.innerHTML = '

⚠️ Kein Bot-Token konfiguriert. Speichere zuerst die Session mit einem Token.

'; statusBox.hidden = false; registerBtn.hidden = true; deleteBtn.hidden = true; } async function refreshTelegramStatus(sessionId, statusBox, registerBtn, deleteBtn) { statusBox.hidden = true; try { var info = await apiSessionTelegramWebhookInfo(sessionId); var result = info.result || {}; var url = result.url || ''; var pending = result.pending_update_count || 0; var lastError = result.last_error_message; var active = !!url; var html = ''; if (active) { html += '

✅ Webhook aktiv

'; html += '

URL: ' + escapeHtml(url) + '

'; html += '

Ausstehend: ' + pending + '

'; if (lastError) html += '

Letzter Fehler: ' + escapeHtml(lastError) + '

'; } else { html += '

⚠️ Webhook nicht registriert

'; } statusBox.innerHTML = html; statusBox.hidden = false; // Buttons ein/ausblenden je nach Status registerBtn.hidden = active; deleteBtn.hidden = !active; } catch(e) { statusBox.innerHTML = '

Status konnte nicht abgerufen werden: ' + escapeHtml(e.message) + '

'; statusBox.hidden = false; registerBtn.hidden = false; deleteBtn.hidden = true; } } async function saveTelegramConfig(sessionId, tokenInput, secretInput) { var token = tokenInput.value.trim(); var secret = secretInput.value.trim(); await apiSessionTelegramSave(sessionId, token, secret); } function escapeHtml(str) { return String(str) .replace(/&/g, '&') .replace(//g, '>') .replace(/"/g, '"'); }