From 51b79e614f95d773fa06378f84c485099339d493 Mon Sep 17 00:00:00 2001 From: Sergey Krashevich Date: Sun, 1 Feb 2026 04:38:48 +0300 Subject: [PATCH] feat: enhance read-only mode with confirmation and server polling on save --- www/config.html | 34 ++++++++++++++++++++++++++++++++-- 1 file changed, 32 insertions(+), 2 deletions(-) diff --git a/www/config.html b/www/config.html index c87a6a8f..7bfa2475 100644 --- a/www/config.html +++ b/www/config.html @@ -1183,6 +1183,11 @@ let dump; const saveButton = document.getElementById('save'); + const readOnlyWarning = 'Enabling read_only: true cannot be reverted remotely. To disable it you must edit the config file on the server manually. Continue?'; + const hasReadOnlyTrue = (text) => { + if (!text) return false; + return /(^|\n)\s*read_only\s*:\s*true\s*(#.*)?$/m.test(text); + }; const applyReadOnly = () => { saveButton.disabled = true; saveButton.title = 'Read-only mode'; @@ -1202,11 +1207,36 @@ return; } - r = await fetch('api/config', {method: 'POST', body: editor.getValue()}); + const nextValue = editor.getValue(); + if (hasReadOnlyTrue(nextValue) && !hasReadOnlyTrue(dump)) { + if (!confirm(readOnlyWarning)) return; + } + + r = await fetch('api/config', {method: 'POST', body: nextValue}); if (r.ok) { alert('OK'); - dump = editor.getValue(); + dump = nextValue; await fetch('api/restart', {method: 'POST'}); + + // Poll server until it's back online before reloading + const waitForServer = async () => { + for (let i = 0; i < 20; i++) { + await new Promise(r => setTimeout(r, 500)); + try { + const response = await fetch('api/config', {cache: 'no-cache'}); + if (response.ok || response.status === 410) { + location.reload(); + return; + } + } catch (e) { + // Server still down, continue polling + } + } + // Fallback: reload after 10 seconds even if server check fails + location.reload(); + }; + waitForServer(); + } else { alert(await r.text()); }