fix(mobile): scope channel sections storage to relay URL - #5761
fix(mobile): scope channel sections storage to relay URL#5761crgallego wants to merge 3 commits into
Conversation
Port Desktop block#1477 to mobile so custom channel folders (sections) no longer bleed across linked workspaces/communities. Local prefs are now keyed by pubkey + normalized relay origin, with a one-time migration from the legacy account-global key onto the first active relay only. Co-authored-by: crgallego <chris.cokerconstruction@gmail.com> Signed-off-by: crgallego <chris.cokerconstruction@gmail.com>
|
Tracking issue: #5762 |
Chessing234
left a comment
There was a problem hiding this comment.
the relayUrl fallback diverges from the pattern this ports, and it interacts badly with the one-time migration.
channel_sort_provider.dart:56-59 uses activeCommunity?.relayUrl only and returns empty state when it's absent; here the else-branch falls back to relayConfig.baseUrl. activeCommunityProvider is a FutureProvider (community_provider.dart:103), so .value is null on the first build of every cold start — the first mount reads and writes under a baseUrl-derived key rather than the community one.
that's also the mount that consumes the migration: read() finds the scoped key empty, copies the legacy blob into the baseUrl-scoped key and deletes legacyChannelSectionsKey. when the future resolves and the provider rebuilds under activeCommunity.relayUrl, that key is empty and the legacy key is gone — so on any device where baseUrl doesn't normalize to exactly the community's relayUrl, the upgrade loses the sections instead of migrating them.
returning const ChannelSectionsState() while activeCommunity is null, the way channel-sort does, avoids both. the normalize helper itself is a faithful copy of normalizeChannelSortRelayUrl.
Match the channel-sort pattern this ports: when the active community has not resolved, return an empty state instead of falling back to relayConfig.baseUrl. The fallback could only ever key storage differently from the community-scoped key, and the manager consumes the one-time legacy migration in its constructor, so a divergent first read would delete the legacy blob under the wrong key. Co-authored-by: crgallego <chris.cokerconstruction@gmail.com> Signed-off-by: crgallego <chris.cokerconstruction@gmail.com>
activeCommunityProvider is a FutureProvider, so the first mount has a null community. The old baseUrl fallback would consume the one-time legacy migration under the wrong key. This test keeps nsec present while the community is still loading and asserts the blob stays put until the community relay URL is known. Co-authored-by: crgallego <chris.cokerconstruction@gmail.com> Signed-off-by: crgallego <chris.cokerconstruction@gmail.com>
|
Agreed — the Two follow-up commits are on the branch:
One extra reason the fallback was unsafe even for “the same relay”: Locally at the test commit: |
Thanks for catching this — the change is in, and it is the right change. One correction to the mechanism, though, because the PR should not carry a wrong story about why. The fallback branch was unreachable in production
The regression test in One thing you understated
And your scheme concern is stronger than you put itYou wrote "any device where baseUrl doesn't normalize to exactly the community's relayUrl." It is every invite-joined community, by construction. Communities persist NetLatent hazard rather than a live bug, and removing it is unambiguously correct — the ported pattern was right and this diverged from it for no benefit. Verified at |
Fixes #5762
Summary
Mobile custom channel folders (sections) were stored account-global (
buzz.channel-sections.v1:$pubkey), so switching linked workspaces showed empty folders from other communities (e.g. Coker Construction folders on Lit Box with no channels inside).Desktop already fixed this in #1477 by scoping local storage to pubkey + relay URL. Mobile channel-sort already uses the same pattern. This PR ports that scoping to mobile channel sections.
Changes
pubkey+encodeURIComponent(relayUrl))relayUrlinto the managerNotes
channel-sectionsblobs remain relay-local by nature of publish/fetch on the connected relay; the bug was local prefs bleeding across communities when remote was empty/absentTest plan
dart analyze lib/features/channels/channel_sections/ test/features/channels/channel_sections/— cleanflutter test test/features/channels/channel_sections/— 15/15 passed