frontend-ota (#1)
Reviewed-on: #1
This commit was merged in pull request #1.
This commit is contained in:
@@ -1,10 +1,12 @@
|
||||
<script>
|
||||
import { getSystemInfo, reboot } from "./lib/api.js";
|
||||
import OTAUpdate from "./lib/OTAUpdate.svelte";
|
||||
|
||||
/** @type {'loading' | 'ok' | 'error' | 'rebooting'} */
|
||||
let status = $state("loading");
|
||||
let errorMsg = $state("");
|
||||
let showRebootConfirm = $state(false);
|
||||
let isRecovering = $state(false);
|
||||
|
||||
let systemInfo = $state({
|
||||
chip: "—",
|
||||
@@ -41,14 +43,17 @@
|
||||
status = "ok";
|
||||
errorMsg = "";
|
||||
} catch (e) {
|
||||
status = "error";
|
||||
errorMsg = e.message || "Connection failed";
|
||||
if (!isRecovering) {
|
||||
status = "error";
|
||||
errorMsg = e.message || "Connection failed";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async function handleReboot() {
|
||||
showRebootConfirm = false;
|
||||
status = "rebooting";
|
||||
isRecovering = true;
|
||||
try {
|
||||
await reboot();
|
||||
} catch (e) {
|
||||
@@ -56,12 +61,27 @@
|
||||
}
|
||||
}
|
||||
|
||||
// Poll every 5 seconds
|
||||
let pollInterval;
|
||||
$effect(() => {
|
||||
fetchInfo();
|
||||
pollInterval = setInterval(fetchInfo, 5000);
|
||||
return () => clearInterval(pollInterval);
|
||||
});
|
||||
|
||||
// Resilient recovery polling: Only poll when we are waiting for a reboot
|
||||
$effect(() => {
|
||||
if (isRecovering) {
|
||||
const interval = setInterval(async () => {
|
||||
try {
|
||||
const info = await getSystemInfo();
|
||||
if (info) {
|
||||
console.log("Device back online! Refreshing UI...");
|
||||
window.location.reload();
|
||||
}
|
||||
} catch (e) {
|
||||
// Still offline or rebooting, just keep waiting
|
||||
console.log("Waiting for device...");
|
||||
}
|
||||
}, 2000);
|
||||
return () => clearInterval(interval);
|
||||
}
|
||||
});
|
||||
|
||||
const infoItems = $derived([
|
||||
@@ -77,8 +97,8 @@
|
||||
<div class="w-full max-w-xl space-y-4">
|
||||
<!-- Header -->
|
||||
<div class="text-center mb-6">
|
||||
<h1 class="text-2xl font-bold text-accent">Calendink Provider</h1>
|
||||
<p class="text-text-secondary text-sm">ESP32-S3 System Dashboard</p>
|
||||
<h1 class="text-2xl font-bold text-accent">Calendink Provider 🚀</h1>
|
||||
<p class="text-text-secondary text-sm">ESP32-S3 System Dashboard v{__APP_VERSION__}</p>
|
||||
</div>
|
||||
|
||||
<!-- Status Badge -->
|
||||
@@ -146,11 +166,11 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Reboot Section -->
|
||||
<!-- Device Control Section (Reboot) -->
|
||||
<div class="bg-bg-card border border-border rounded-xl p-5">
|
||||
<div class="flex items-center justify-between">
|
||||
<div>
|
||||
<h2 class="text-sm font-semibold text-text-primary">
|
||||
<h2 class="text-sm font-semibold text-text-primary uppercase tracking-wider">
|
||||
Device Control
|
||||
</h2>
|
||||
<p class="text-xs text-text-secondary mt-1">
|
||||
@@ -170,6 +190,9 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Frontend Info & OTA Section -->
|
||||
<OTAUpdate onReboot={() => (status = "rebooting")} />
|
||||
|
||||
<!-- Reboot Confirmation Modal -->
|
||||
{#if showRebootConfirm}
|
||||
<div
|
||||
@@ -203,9 +226,5 @@
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
<!-- Footer -->
|
||||
<p class="text-center text-xs text-text-secondary/50 pt-2">
|
||||
Auto-refreshes every 5s
|
||||
</p>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
Reference in New Issue
Block a user