diff --git a/app.py b/app.py index c5ecc7d..176aeed 100644 --- a/app.py +++ b/app.py @@ -1095,6 +1095,15 @@ def r_update_check(): return jsonify(ok=True) +@app.route('/api/system/reboot', methods=['POST']) +def r_system_reboot(): + threading.Thread(target=lambda: ( + __import__('time').sleep(1), + subprocess.Popen(['reboot']) + ), daemon=True).start() + return jsonify(ok=True) + + @app.route('/api/update/install', methods=['POST']) def r_update_install(): try: @@ -1239,7 +1248,7 @@ body{background:var(--bg);color:var(--txt);font-family:-apple-system,BlinkMacSys .tog input{accent-color:var(--acc);width:16px;height:16px;cursor:pointer;flex-shrink:0} .tog span{line-height:1.35} .flash{font-size:.78rem;min-height:1rem;padding:.2rem 0} -.flash.ok{color:var(--grn)}.flash.err{color:var(--red)} +.flash.ok{color:var(--grn)}.flash.err{color:var(--red)}.flash.warn{color:#f4a332} /* ── Port Slots ── */ /* port-pair: immer echtes 1fr 1fr, unabhängig vom Explorer */ @@ -1609,6 +1618,19 @@ body{background:var(--bg);color:var(--txt);font-family:-apple-system,BlinkMacSys + +
+
+
+ System +
+
+ + + +
+
+
@@ -2063,6 +2085,41 @@ async function installUpdate() { }, 5000); } +async function checkUpdate() { + const btn = event.currentTarget; + btn.disabled = true; btn.textContent = '↻ Prüfe…'; + try { + await api('/update/check', 'POST'); + await new Promise(r => setTimeout(r, 2000)); + const u = await api('/update/status'); + const fl = $('sys-update-flash'); + if (u.available && u.latest) { + fl.className = 'flash warn'; fl.textContent = 'Update v' + u.latest + ' verfügbar – über das Badge oben installieren.'; + } else if (u.error) { + fl.className = 'flash err'; fl.textContent = 'Fehler: ' + u.error; + } else { + fl.className = 'flash ok'; fl.textContent = 'PiCopy ist aktuell.'; + } + fl.style.display = 'block'; + if (fl.className.includes('ok')) setTimeout(() => fl.style.display = 'none', 3500); + } catch(e) { + const fl = $('sys-update-flash'); + fl.className = 'flash err'; fl.textContent = 'Verbindung fehlgeschlagen.'; fl.style.display = 'block'; + } finally { + btn.disabled = false; btn.innerHTML = '🔍 Nach Update suchen'; + } +} + +async function rebootDevice() { + if (!confirm('Gerät jetzt neu starten?\n\nDas Web-Interface ist für ca. 30 Sekunden nicht erreichbar.')) return; + try { await api('/system/reboot', 'POST'); } catch(e) {} + document.body.innerHTML = '
↻ Gerät startet neu – bitte warten…
'; + setTimeout(async function waitForRestart() { + try { await fetch('/api/update/status'); location.reload(); } + catch(e) { setTimeout(waitForRestart, 2000); } + }, 10000); +} + function flash(id,cls,msg){ const el=$(id); el.className='flash '+cls; el.textContent=msg; el.style.display='block'; if(cls==='ok') setTimeout(()=>el.style.display='none',3500); diff --git a/version.txt b/version.txt index ece61c6..f9cbc01 100644 --- a/version.txt +++ b/version.txt @@ -1 +1 @@ -1.0.6 \ No newline at end of file +1.0.7 \ No newline at end of file