diff --git a/renderer/app.js b/renderer/app.js
index b836840..53dec2b 100644
--- a/renderer/app.js
+++ b/renderer/app.js
@@ -2023,6 +2023,97 @@ function renderSettings() {
}
});
+ // --- Remote Control Panel ---
+ const remoteSettings = globalSettings.remote || {};
+ const remotePanel = document.createElement('div');
+ remotePanel.className = 'hoster-settings-panel';
+ remotePanel.innerHTML = `
+
+
+
Server
+
+
+
+
+
+
+
+
+
+
+
+
Status
+
+ Prüfe...
+
+
+ `;
+ container.appendChild(remotePanel);
+
+ // Toggle remote panel
+ remotePanel.querySelector('.hoster-panel-header').addEventListener('click', () => {
+ const body = remotePanel.querySelector('.hoster-panel-body');
+ const arrow = remotePanel.querySelector('.panel-arrow');
+ const isOpen = body.style.display !== 'none';
+ body.style.display = isOpen ? 'none' : 'block';
+ arrow.innerHTML = isOpen ? '▶' : '▼';
+ });
+
+ // Copy token
+ document.getElementById('remoteCopyTokenBtn').addEventListener('click', async () => {
+ const token = document.getElementById('remoteTokenInput').value;
+ if (token) {
+ await window.api.copyToClipboard(token);
+ document.getElementById('remoteCopyTokenBtn').textContent = 'Kopiert!';
+ setTimeout(() => { document.getElementById('remoteCopyTokenBtn').textContent = 'Kopieren'; }, 1500);
+ }
+ });
+
+ // Regenerate token
+ document.getElementById('remoteRegenerateTokenBtn').addEventListener('click', async () => {
+ const newToken = await window.api.remoteGenerateToken();
+ document.getElementById('remoteTokenInput').value = newToken;
+ scheduleSettingsSave();
+ });
+
+ // Update status
+ window.api.remoteStatus().then(status => {
+ const el = document.getElementById('remoteConnectionStatus');
+ if (!el) return;
+ if (status.running) {
+ el.textContent = `Aktiv auf Port ${status.port} — ${status.clientCount} Client(s) verbunden`;
+ el.style.color = '#10b981';
+ } else {
+ el.textContent = 'Nicht aktiv';
+ el.style.color = '#94a3b8';
+ }
+ }).catch(() => {});
+
+ // Live client count updates
+ window.api.onRemoteClientCount((count) => {
+ const el = document.getElementById('remoteConnectionStatus');
+ if (el && el.style.color === 'rgb(16, 185, 129)') {
+ window.api.remoteStatus().then(status => {
+ if (status.running) {
+ el.textContent = `Aktiv auf Port ${status.port} — ${status.clientCount} Client(s) verbunden`;
+ }
+ }).catch(() => {});
+ }
+ });
+
// --- Backup Panel ---
const backupPanel = document.createElement('div');
backupPanel.className = 'hoster-settings-panel';
@@ -2190,6 +2281,12 @@ async function saveSettings(options = {}) {
delaySec: Math.max(1, parseInt(document.getElementById('fmDelaySecInput')?.value || '3', 10) || 3),
autoStart: !!document.getElementById('fmAutoStartInput')?.checked,
hosters: Array.from(document.querySelectorAll('.fm-hoster-checkbox:checked')).map(el => el.dataset.fmHoster)
+ },
+ remote: {
+ enabled: !!document.getElementById('remoteEnabledInput')?.checked,
+ port: Math.max(1024, Math.min(65535, parseInt(document.getElementById('remotePortInput')?.value || '9100', 10) || 9100)),
+ token: (document.getElementById('remoteTokenInput')?.value || '').trim(),
+ allowInput: !!document.getElementById('remoteAllowInputInput')?.checked
}
};
@@ -2241,6 +2338,31 @@ async function saveSettings(options = {}) {
if (badge) { badge.textContent = 'Inaktiv'; badge.className = 'panel-status'; }
}
+ // Start/stop remote server based on settings
+ const remoteSettings = globalSettings.remote;
+ const remoteBadge = document.getElementById('remoteStatusBadge');
+ if (remoteSettings) {
+ try {
+ await window.api.remoteSaveSettings(remoteSettings);
+ if (remoteBadge) {
+ remoteBadge.textContent = remoteSettings.enabled ? 'Aktiv' : 'Inaktiv';
+ remoteBadge.className = `panel-status${remoteSettings.enabled ? ' active' : ''}`;
+ }
+ // Update status display
+ const status = await window.api.remoteStatus();
+ const statusEl = document.getElementById('remoteConnectionStatus');
+ if (statusEl) {
+ if (status.running) {
+ statusEl.textContent = `Aktiv auf Port ${status.port} — ${status.clientCount} Client(s) verbunden`;
+ statusEl.style.color = '#10b981';
+ } else {
+ statusEl.textContent = 'Nicht aktiv';
+ statusEl.style.color = '#94a3b8';
+ }
+ }
+ } catch {}
+ }
+
const feedback = document.getElementById('saveFeedback');
feedback.textContent = feedbackText;
setTimeout(() => {