docs: record uniform-strict offline semantics for DVM liveness

This commit is contained in:
Believethehype
2026-09-10 12:52:23 +02:00
parent ad1d4ccf8b
commit e9ae377e1b
2 changed files with 9 additions and 5 deletions
@@ -943,7 +943,7 @@ RefresheableBox(onRefresh = onRefresh) {
}
```
Notes: `heartbeatFresh?.value == false` deliberately shows the banner only when a note object exists and is stale — an unresolved heartbeat note (surfaces that never subscribed) shows nothing rather than a false "offline". `AppDefinitionEvent` is already imported in this file; add `androidx.compose.foundation.layout.Box`, `androidx.compose.foundation.layout.fillMaxSize`, `androidx.compose.ui.Alignment`, `com.vitorpamplona.amethyst.ui.screen.loggedIn.dvms.DvmOfflineBanner` (same package — no import needed) and `rememberDvmHeartbeatFresh` (same package — no import needed).
Notes: `heartbeatFresh?.value == false` exists only because `appDef` itself may be null. Per human ruling (uniform-strict), unresolved heartbeat beats count as offline on every surface — chips, home banners, and the detail screen all show the offline indicator once the beat is unresolved/stale, rather than showing nothing. `AppDefinitionEvent` is already imported in this file; add `androidx.compose.foundation.layout.Box`, `androidx.compose.foundation.layout.fillMaxSize`, `androidx.compose.ui.Alignment`, `com.vitorpamplona.amethyst.ui.screen.loggedIn.dvms.DvmOfflineBanner` (same package — no import needed) and `rememberDvmHeartbeatFresh` (same package — no import needed).
- [ ] **Step 5: Manage screen rows**
@@ -73,9 +73,13 @@ Small helper file in `amethyst/.../dvms/`:
- `LocalCache.dvmHeartbeatOf(appDef: AppDefinitionEvent): DvmHeartbeatEvent?` — address
lookup `Address(DvmHeartbeatEvent.KIND, appDef.pubKey, appDef.dTag())`
- `DvmHeartbeatEvent.isFreshAt(now: Long): Boolean` — `createdAt >= now - 420`
- `@Composable fun rememberDvmHeartbeat(address: Address): State<DvmHeartbeatEvent?>` —
composable-scoped subscription (§5) + staleness re-check tick (§6), shared by every
surface that renders liveness.
- `@Composable fun rememberDvmHeartbeatFresh(address: Address, accountViewModel: AccountViewModel): State<Boolean>` —
as built (uniform-strict ruling): returns true while the DVM has a heartbeat at most 420s
old; an unresolved/absent beat counts as offline (`false`) on every surface. The returned
`State` identity is stable for the lifetime of the call site (one unconditional
`rememberUpdatedState`), so callers may capture it across recompositions. Composable-scoped
subscription (§5) + staleness re-check tick (§6), shared by every surface that renders
liveness.
## 5. Subscriptions
@@ -107,7 +111,7 @@ the session-scoped watcher for pinned DVMs. Traffic is negligible (a few pinned
(alongside the existing `scope.launch { flows.collect { … } }` observers) calls
`discoverDVMs.invalidateData()` every minute. The rebuild is a cheap scan (≤ a few
hundred 31990s) and `refreshSuspended()` no-ops when the list is unchanged. Composables
using `rememberDvmHeartbeat` tick on a 30s cadence internally.
using `rememberDvmHeartbeatFresh` tick on a 30s cadence internally.
## 7. UI surfaces