fix(home): bitcoin sync tile no longer vanishes on a transient poll (B16)

The Home > System bitcoin tile is gated on bitcoinAvailable===true, so any
transient bitcoin.getinfo failure (RPC busy during heavy IBD, route-change
scan) could blank it even though the node is fine. Add a bitcoinStale flag:
- getinfo fails while the container is Running, or package data is momentarily
  absent → retain the last-known value and mark it stale (tile stays, shows
  "Updating…" instead of a frozen figure presented as live).
- container authoritatively Stopped/Exited → flip to not-available as before
  (no stale-as-live).
- first-ever poll times out but container Running → show the tile as updating
  rather than staying hidden on a syncing node.

Harness: src/stores/__tests__/homeStatus.test.ts (6 cases) — red before, green
after. type-check clean.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
archipelago
2026-06-16 02:57:35 -04:00
co-authored by Claude Opus 4.8
parent 386d4bfc3f
commit 83dbd25c50
4 changed files with 113 additions and 3 deletions
+1
View File
@@ -506,6 +506,7 @@ const systemStatsLoaded = computed(() => homeStatus.systemStatsLoaded)
const systemStats = computed(() => ({
...homeStatus.stats,
bitcoinAvailable: homeStatus.stats.bitcoinAvailable === true,
bitcoinStale: homeStatus.bitcoinStale,
}))
const systemUptimeDisplay = computed(() => { if (homeStatus.stats.uptimeSecs === 0) return t('home.systemMonitoring'); const days = Math.floor(homeStatus.stats.uptimeSecs / 86400); const hours = Math.floor((homeStatus.stats.uptimeSecs % 86400) / 3600); if (days > 0) return `Uptime: ${days}d ${hours}h`; const mins = Math.floor((homeStatus.stats.uptimeSecs % 3600) / 60); return `Uptime: ${hours}h ${mins}m` })
+3 -2
View File
@@ -60,8 +60,8 @@
<div v-if="stats.bitcoinAvailable" class="p-4 bg-white/5 rounded-lg">
<div class="flex items-center justify-between mb-2">
<p class="text-xs text-orange-400/80">Bitcoin</p>
<p class="text-sm font-medium" :class="stats.bitcoinSyncPercent >= 99.9 ? 'text-green-400' : 'text-orange-400'">
{{ stats.bitcoinSyncPercent >= 99.9 ? 'Synced' : stats.bitcoinSyncPercent.toFixed(1) + '%' }}
<p class="text-sm font-medium" :class="stats.bitcoinStale ? 'text-white/50' : (stats.bitcoinSyncPercent >= 99.9 ? 'text-green-400' : 'text-orange-400')">
{{ stats.bitcoinStale ? 'Updating…' : (stats.bitcoinSyncPercent >= 99.9 ? 'Synced' : stats.bitcoinSyncPercent.toFixed(1) + '%') }}
</p>
</div>
<div class="w-full h-2 bg-white/10 rounded-full overflow-hidden">
@@ -96,6 +96,7 @@ defineProps<{
bitcoinSyncPercent: number
bitcoinBlockHeight: number
bitcoinAvailable: boolean
bitcoinStale?: boolean
}
uptimeDisplay: string
}>()