Skip to content

fix(profile): stop the following count showing 0, or sticking there - #426

Open
dmnyc wants to merge 1 commit into
mainfrom
fix/profile-following-count-flash
Open

fix(profile): stop the following count showing 0, or sticking there#426
dmnyc wants to merge 1 commit into
mainfrom
fix/profile-following-count-flash

Conversation

@dmnyc

@dmnyc dmnyc commented Jul 28, 2026

Copy link
Copy Markdown
Collaborator

Summary

The Following count on a profile showed 0 on every visit and filled in a moment later — and sometimes stayed at 0 for good. Two separate defects produced the same symptom.

Shows 0, then fills in. ProfileViewModel.start() already reads FollowsCache to decide youFollow, but left followingCount at its 0 default until the kind-3 relay query returned. ProfileView.statRow renders that value directly, so the stat read as a fresh load of the follow list rather than a cached value updating quietly. It's now seeded from that same cache read, and loadContacts overwrites it when the relay copy lands.

Only the count is primed — deliberately not followingPubkeys. That array gates whether loadFollowingProfiles re-fetches contacts, so priming it would let the Following tab render a stale cached list and mark itself loaded without ever consulting a relay.

Sticks at 0. loadContacts races loadTargetWriteRelays inside the same task group, but builds its relay set via queryRelays(), which folds in targetWriteRelays — still empty at that point. For a profile whose kind-3 lives only on its author's own write relays, that first attempt searches the wrong servers and finds nothing. Nothing ever re-runs it: start() is one-shot behind hasStarted, and the header has no pull-to-refresh. So the count stayed at 0 for the life of the screen.

It now retries once the write relays are known. Kept concurrent rather than serialized — awaiting the kind-10002 lookup up front would delay the entire header by up to its 8s timeout, trading a wrong count for a slow screen. The retry is guarded on followingPubkeys.isEmpty, so it's a no-op whenever the first attempt succeeded.

Test plan

  • Builds clean on Simulator
  • Verified on Simulator: Following renders 1.1k at t+300ms and is unchanged at every sample through t+17s — no 0, no visible fill-in
  • Open a profile that previously stuck at 0 (kind-3 published only to the author's own write relays) and confirm the retry resolves it
  • Open the Following tab and confirm it still lists the full set — the tab must fetch from a relay, not render the seeded cache

Notes

Scope is the Following count. Followers is a remote-only count via NostrArchivesClient with an placeholder and no local cache to seed from, so it still populates on load; giving it the same treatment would need a new persistence layer rather than a one-line seed.

Two separate defects behind the same symptom.

Stale-looking load: `start()` already reads FollowsCache to decide
`youFollow`, but left `followingCount` at its 0 default until the
kind-3 relay query returned. The stat row renders that value directly,
so every profile visit showed Following as 0 and then filled it in.
Now seeded from the same cache read, with `loadContacts` overwriting it
when the relay copy lands. Only the count is primed, not
`followingPubkeys` — that array gates whether `loadFollowingProfiles`
re-fetches, so priming it would let the Following tab render a stale
list and mark itself loaded without consulting a relay.

Stuck at 0: `loadContacts` races `loadTargetWriteRelays` in the same
task group, so `queryRelays()` is built before `targetWriteRelays` is
populated. For a profile whose kind-3 lives only on its author's write
relays, that first attempt searches the wrong servers and finds
nothing — and nothing ever re-runs it, since `start()` is one-shot via
`hasStarted` and the header has no pull-to-refresh. It now retries once
the write relays are known. Kept concurrent rather than serialized:
awaiting the 10002 lookup first would delay the whole header by up to
its 8s timeout.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant