fix(desktop): refresh channel state after unarchive#923
Merged
Conversation
useUnarchiveChannelMutation only patched the cache optimistically, while useArchiveChannelMutation also invalidates+refetches via onSettled. Without that, the channel browser (reads the list query) and the composer gate (reads the detail query) kept showing stale archived state after a successful server-side unarchive — until an unrelated refetch happened up to 60s later. Mirror the archive mutation: add onSettled -> invalidateChannelState so all gated surfaces reconcile against the relay. Co-authored-by: Brain <21994759fc7a6fa6b965551d35cfd7897d262f2495467f2d78694ddcfa6a5c7e@sprout-oss.stage.blox.sqprod.co> Signed-off-by: Wes <wesbillman@users.noreply.github.com>
tlongwell-block
pushed a commit
that referenced
this pull request
Jun 10, 2026
* origin/main: Fix post-compact handoff context for OpenAI providers (#931) chore(release): release version 0.3.15 (#936) fix: persona is source of truth at spawn + thread-depth conventions (#930) fix: skip avatar reconciliation for legacy agent records (#933) feat(desktop): add nest commit identity guidance with human sign-off (#929) feat: provider/model selection for personas and runtime-aware env injection (#794) fix: reconcile agent profile on startup when relay publish was missed (#921) Revamp first-run onboarding (#924) Update setup loading screen (#926) fix(dm): keep hidden DMs hidden across refetch via relay-signed visibility snapshot (NIP-DV) (#857) Maximize desktop window on launch (#925) feat: preview features (experiments settings UI) (#888) fix(updater): send no-cache header on update check to avoid stale manifest (#922) fix(desktop): refresh channel state after unarchive (#923) Add channel visibility & ephemeral TTL controls to manage sidebar (#911) ci(release): add Intel macOS (x86_64) DMG as a release target (#748) Signed-off-by: npub1mprnacetjua2xx3p5eddmhxyk6wv929ymm5py8kd2xfxurxahspqqlgyta <d8473ee32b973aa31a21a65adddcc4b69cc2a8a4dee8121ecd51926e0cddbc02@sprout-oss.stage.blox.sqprod.co> # Conflicts: # desktop/src/features/sidebar/ui/AppSidebar.tsx
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
Unarchiving a channel succeeds on the relay, but the desktop UI keeps showing the channel as archived in the channel browser/search and leaves the message composer disabled. Verified the relay side is correct: the unarchived channel reports
archived_at: null, and both the send-gate and channel-list/search readarchived_atfresh from the DB.Root cause
In
desktop/src/features/channels/hooks.tsthere's an asymmetry between the archive and unarchive mutations:useArchiveChannelMutationpatches the cache optimistically (onSuccess) and invalidates/refetches viaonSettled → invalidateChannelState.useUnarchiveChannelMutationonly did the optimistic patch — noonSettled.The optimistic patch updates
channelsQueryKeyand the detail query in place, but doesn't reconcile against the relay. The channel browser reads the list query and the composer gate reads the detail query; withuseChannelsQueryon a 60sstaleTime/refetchInterval, the stale archived state sticks until an unrelated refetch fires.Fix
Give the unarchive mutation the same
onSettled: invalidateChannelStatethe archive mutation already has, so the channel list, detail, and members queries refetch from the relay after a successful unarchive.setChannelArchivedState(queryClient, channelId, null); }, + onSettled: async () => { + await invalidateChannelState(queryClient, channelId); + }, }); }Verification
tsc --noEmit— cleanbiome lint(changed file) — cleanpnpm test— 585/585 passNote on tests
No regression test added. The desktop suite runs node's built-in test runner over
*.test.mjsfor pure-logic modules — there's no React/renderHook/QueryClient harness, so testing this React Query lifecycle wiring would require standing up a new harness, disproportionate to a one-line symmetry fix. Happy to add the harness + a mutation-lifecycle test as a follow-up if desired.