feat(remote): add Fernsteuerung settings panel with token management and status display
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
d1513a58b3
commit
f13bf7f5bc
122
renderer/app.js
122
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 = `
|
||||
<div class="hoster-panel-header" data-hoster="remote">
|
||||
<span class="panel-arrow">▶</span>
|
||||
<span class="panel-title">Fernsteuerung</span>
|
||||
<span class="panel-status${remoteSettings.enabled ? ' active' : ''}" id="remoteStatusBadge">${remoteSettings.enabled ? 'Aktiv' : 'Inaktiv'}</span>
|
||||
</div>
|
||||
<div class="hoster-panel-body" data-panel="remote" style="display:none">
|
||||
<div class="settings-section-label">Server</div>
|
||||
<div class="settings-grid-mini">
|
||||
<div class="settings-row checkbox-row">
|
||||
<label>Aktiviert</label>
|
||||
<input type="checkbox" class="settings-autosave" id="remoteEnabledInput" ${remoteSettings.enabled ? 'checked' : ''}>
|
||||
</div>
|
||||
<div class="settings-row checkbox-row">
|
||||
<label>Input erlauben</label>
|
||||
<input type="checkbox" class="settings-autosave" id="remoteAllowInputInput" ${remoteSettings.allowInput !== false ? 'checked' : ''}>
|
||||
</div>
|
||||
</div>
|
||||
<div class="settings-row">
|
||||
<label>Port</label>
|
||||
<input type="number" class="hs-input settings-autosave" id="remotePortInput" value="${remoteSettings.port || 9100}" min="1024" max="65535" style="width:100px">
|
||||
</div>
|
||||
<div class="settings-row">
|
||||
<label>API-Token</label>
|
||||
<input type="text" class="key-input" id="remoteTokenInput" value="${remoteSettings.token || ''}" readonly style="flex:1">
|
||||
<button class="btn btn-xs btn-secondary" id="remoteCopyTokenBtn" title="Kopieren">Kopieren</button>
|
||||
<button class="btn btn-xs btn-secondary" id="remoteRegenerateTokenBtn" title="Neu generieren">Neu</button>
|
||||
</div>
|
||||
<div class="settings-section-label">Status</div>
|
||||
<div class="settings-row">
|
||||
<span id="remoteConnectionStatus" style="color:#94a3b8">Prüfe...</span>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
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(() => {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user