Files
camera-gallery/src/js/options.js
2025-10-23 00:54:43 +01:00

184 lines
6.0 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
document.addEventListener('page-loaded', e => {
if (e.detail.page !== 'options') return;
// ---- STATUS WIDGET ----
const wifi = document.getElementById('statusWifi');
const uptime = document.getElementById('statusUptime');
const load = document.getElementById('statusLoad');
const mem = document.getElementById('statusMem');
const services = document.getElementById('statusServices');
const btnRefresh = document.getElementById('btnRefreshStatus');
async function updateStatus() {
try {
const res = await fetch('includes/api/system.php', {
method: 'POST',
body: new URLSearchParams({ action: 'system-info' })
});
const j = await res.json();
if (j.error) throw new Error(j.error);
wifi.textContent = j.wifi || '';
uptime.textContent = j.uptime || '';
load.textContent = j.load || '';
mem.textContent = j.memory || '';
const svcList = CONFIG.options_status_services;
const results = [];
for (const svc of svcList) {
const r = await fetch('includes/api/system.php', {
method: 'POST',
body: new URLSearchParams({ action: 'service-status', service: svc })
});
const text = await r.text();
results.push(`${svc}: ${text.includes('running') ? '🟢' : '🔴'}`);
}
services.textContent = results.join(' ');
} catch (err) {
wifi.textContent = uptime.textContent = load.textContent = mem.textContent = 'Error';
services.textContent = err.message;
}
}
btnRefresh?.addEventListener('click', updateStatus);
updateStatus();
setInterval(updateStatus, CONFIG.options_status_interval);
// ---- CONFIG EDITOR ----
const editor = document.getElementById('configEditor');
const msg = document.getElementById('configMessage');
const btnLoadConfig = document.getElementById('btnLoadConfig');
const btnSaveConfig = document.getElementById('btnSaveConfig');
if (!btnSaveConfig.dataset.bound) {
btnSaveConfig.dataset.bound = 'true';
btnLoadConfig?.addEventListener('click', async () => {
msg.textContent = 'Loading...';
try {
const res = await fetch('includes/api/config.php', {
method: 'POST',
body: new URLSearchParams({ action: 'load' })
});
const j = await res.json();
if (j.error) msg.textContent = j.error;
else {
editor.value = j.content || '';
msg.textContent = 'Config loaded.';
}
} catch (err) {
msg.textContent = 'Error loading config: ' + err.message;
}
});
btnSaveConfig?.addEventListener('click', async () => {
msg.textContent = 'Checking changes...';
try {
const data = editor.value;
// Preview changes & syntax check
const previewRes = await fetch('includes/api/config.php', {
method: 'POST',
body: new URLSearchParams({ action: 'preview-save', data })
});
const preview = await previewRes.json();
if (preview.error) {
msg.textContent = preview.error;
return;
}
if (preview.message) {
msg.textContent = preview.message;
return;
}
const confirmMsg = `⚙️ Changes detected (${preview.diff.split('\n\n').length} lines):\n\n` +
preview.diff.slice(0, 1000) +
(preview.diff.length > 1000 ? '\n\n...preview truncated...' : '') +
`\n\nSave these changes?`;
if (!confirm(confirmMsg)) {
msg.textContent = 'Save canceled.';
return;
}
msg.textContent = 'Saving...';
const resSave = await fetch('includes/api/config.php', {
method: 'POST',
body: new URLSearchParams({ action: 'save', data })
});
const jSave = await resSave.json();
msg.textContent = jSave.message || jSave.error || 'Saved successfully.';
if (jSave.message && jSave.message.includes('successfully')) {
editor.value = '';
msg.textContent = '';
}
} catch (err) {
msg.textContent = 'Error: ' + err.message;
}
});
}
// ---- CACHE ----
const cacheBtn = document.getElementById('btnClearCache');
cacheBtn?.addEventListener('click', async () => {
if (!confirm('Clear cache folder?')) return;
const res = await fetch('includes/api/cache.php', { method: 'POST' });
const j = await res.json();
alert(j.message || j.error);
});
// ---- LOGS ----
const logsBtn = document.getElementById('btnViewLogs');
const logsBox = document.getElementById('logsBox');
logsBtn?.addEventListener('click', async () => {
const res = await fetch('includes/api/logs.php');
const j = await res.json();
logsBox.textContent = j.content || j.error;
});
// ---- WIFI / LAN ----
const wifiBtn = document.getElementById('btnWifiToggle');
const lanBtn = document.getElementById('btnLanRestart');
wifiBtn?.addEventListener('click', async () => {
await fetch('includes/api/system.php', {
method: 'POST',
body: new URLSearchParams({ action: 'wifi-toggle' })
});
updateStatus();
});
lanBtn?.addEventListener('click', async () => {
await fetch('includes/api/system.php', {
method: 'POST',
body: new URLSearchParams({ action: 'service-restart', service: 'network' })
});
updateStatus();
});
// ---- PASSWORD CHANGE ----
const oldPass = document.getElementById('oldPass');
const newPass = document.getElementById('newPass');
const confirmPass = document.getElementById('confirmPass');
const passBtn = document.getElementById('btnChangePass');
passBtn?.addEventListener('click', async () => {
if (newPass.value !== confirmPass.value) {
alert('New passwords do not match');
return;
}
const res = await fetch('includes/api/admin.php', {
method: 'POST',
body: new URLSearchParams({
action: 'change_pass',
oldPass: oldPass.value,
newPass: newPass.value
})
});
const j = await res.json();
alert(j.message || j.error);
});
});