Skip to content

feat(backup): offer Mutable follow recovery when no backup exists - #641

Open
dmnyc wants to merge 5 commits into
zapcooking:mainfrom
dmnyc:feat/settings-follow-recovery
Open

feat(backup): offer Mutable follow recovery when no backup exists#641
dmnyc wants to merge 5 commits into
zapcooking:mainfrom
dmnyc:feat/settings-follow-recovery

Conversation

@dmnyc

@dmnyc dmnyc commented Aug 20, 2026

Copy link
Copy Markdown
Collaborator

The gap

In Settings → Nostr Backup, "Restore" is gated on a backup existing:

disabled={!status.exists || !canEncrypt || restoring[type]}

So the case where someone most needs help — follows wiped, no zap.cooking backup — is exactly the case where Settings offers nothing. The card just says "No backup found" and stops.

Meanwhile the app already has the answer: Mutable's follow-list recovery (FollowListRecoveryModal + $lib/followRecovery) scans relay history for earlier kind:3 events and needs no backup at all. It was only reachable from a profile page, which isn't where anyone looks after losing their follows.

The change

The Follows card gains a third action, "Recover from relays", alongside Backup Now / Restore.

It is deliberately not gated on status.exists — it works from relay history, so it's available precisely when Restore isn't. The only guard is being signed in.

When no follows backup exists, the card also explains the option rather than dead-ending:

No backup here yet — but your follow list may still be recoverable from relay history. Try Recover from relays.

Both the button and the hint are scoped to type === 'follows'; the Mute List and Profile cards are unchanged, since Mutable's recovery is follow-list specific.

The modal is mounted from this component behind an {#if $userPublickey} guard, and is the same component the profile page uses — no duplicated recovery logic.

Verification

  • pnpm check — 1 error / 152 warnings, identical to main (pre-existing delete-operator error)
  • pnpm test — 1267 passed
  • Checked in a browser: on the Follows card the hint and the third button render as intended, and the Mute List / Profile cards below still show only Backup Now / Restore

Not verified

The recovery flow itself (scan → pick a candidate → restore) runs behind auth, so I could only confirm the entry point renders and is correctly ungated. The modal and followRecovery logic are unchanged — this PR only adds a second way in — but a signed-in pass through the scan is worth doing.

@dmnyc

dmnyc commented Aug 20, 2026

Copy link
Copy Markdown
Collaborator Author

Pushed a round of layout/copy refinements from review feedback:

  • Moved relay recovery out of the backup action row. That row was wrapping with four buttons, and grouping recovery with Backup/Restore implied it was the same kind of operation — it isn't. The action row is about zap.cooking's own encrypted backups; recovery reads other people's relays for an older kind:3. It's now its own bordered strip below the actions, and the separate hint paragraph is gone (it was saying the same thing twice).
  • Titled it "Follow List Recovery" rather than asking "Lost your follows?", so it reads as a named feature alongside the backup rows.
  • Added Mutable attribution — same /mutable_logo.svg treatment used in FollowListRecoveryModal and MuteListEditor.
  • Fixed the baseline on that row. Title (12px) and attribution (11px) were under items-center, so neither sat on a shared baseline; switched to items-baseline, sized the logo to the 12px line so it stops stretching the line box, and added leading-none to the small spans.

pnpm check at baseline, 1267 tests.

Not visually verified — the browser tooling in my environment kept attaching to unrelated tabs, so the last few rounds are markup-level only. Worth a glance before merge at: the strip on a narrow viewport (button wraps below the text), and whether the 12px logo still reads clearly. If it looks weak, w-3.5 with self-center on the img keeps the baseline fix and the larger mark.

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