fix(mobile): protect unpublished channel-section edits and sync channel sort#2829
Open
tellaho wants to merge 1 commit into
Open
fix(mobile): protect unpublished channel-section edits and sync channel sort#2829tellaho wants to merge 1 commit into
tellaho wants to merge 1 commit into
Conversation
…el sort
Mobile channel-section edits were silently lost: sections publish on a 5s
debounce, but the provider tears the sync manager down on every relay-session
status flip without flushing. The rebuilt manager then fetched the stale
remote blob and unconditionally adopted it over newer local state, erasing
the just-made edit ("groups do not persist").
Fix, mirroring the read-state manager pattern:
- Persisted dirty flag (dirty-since) in ChannelSectionsStorage so
unpublished edits survive manager teardown and app restarts.
- Dirty-state protection in _mergeEvent: a remote blob never overwrites
unpublished local edits; the pending publish reconciles the relay.
- Publish-on-reconnect: initialize() re-schedules a publish when the dirty
flag is set, and seed-publishes local state when the relay confirms it has
no blob (never on a failed fetch).
- Edit-generation guard so a publish only clears the dirty flag when no new
edit landed while it was in flight.
Also adds mobile channel-sort sync parity (desktop-only until now):
- New channel_sort feature (storage/manager/provider) using the same
encrypted NIP-78 blob desktop publishes (kind 30078, d-tag channel-sort,
NIP-44 to self, whole-blob LWW) including the dirty-flag protection above.
- Per-group Sort: Recent / A-Z controls on Starred, custom sections,
Channels, and DMs, matching desktop group keys (starred/channels/dms,
section:<id>) and sort semantics; orphaned section:<id> keys are pruned
on write.
Co-authored-by: npub1223z34hd7vtwc6qj4s7flsxkj644nlre2nthu7lrrmkumhu3xddsrx9r6w <52a228d6edf316ec6812ac3c9fc0d696ab59fc7954d77e7be31eedcddf91335b@buzz.block.builderlab.xyz>
Signed-off-by: npub1223z34hd7vtwc6qj4s7flsxkj644nlre2nthu7lrrmkumhu3xddsrx9r6w <52a228d6edf316ec6812ac3c9fc0d696ab59fc7954d77e7be31eedcddf91335b@buzz.block.builderlab.xyz>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
Mobile channel-section edits were silently lost ("groups don't persist"). Investigation on
main(ab3af8287) showed:channel-sectionsblob is on the relay and mobile decrypts/fetches/renders it correctly — the blank-sidebar screenshot was a stale build, not a read-path bug.ChannelSectionsNotifier.build()tears the manager down on every relay-session status flip without flushing (dispose(flushPending: false)). The rebuilt manager fetches the stale remote blob and unconditionally adopts it over newer local state — the just-made edit vanishes.channel-sortd-tag) — desktop-only since sync channel sort preferences across clients #1556.Fix
Sections — dirty-state protection (mirrors the read-state manager pattern):
dirty-sinceflag inChannelSectionsStorageso unpublished edits survive manager teardown and app restarts._mergeEventnever lets a remote blob overwrite unpublished local edits; the pending publish reconciles the relay (LWW timestamps still advance so our event sorts after the remote one).initialize()re-schedules a publish when the dirty flag is set, and seed-publishes local state when the relay confirms it has no blob (never on a failed fetch).Channel-sort parity (new mobile feature):
channel_sort/storage/manager/provider using the exact wire format desktop publishes: kind 30078, d-tagchannel-sort, NIP-44 encrypted-to-self, whole-blob LWW, same group keys (starred/channels/dms/section:<id>,alpha/recent). Includes the same dirty-flag protection.sortChannelsForSidebar(recent = newest first, message-less channels sink alphabetically). Orphanedsection:<id>keys pruned on write.Verification
flutter analyzeclean,dart formatclean.