Skip to content

fix(desktop): refresh channel state after unarchive#923

Merged
wesbillman merged 1 commit into
mainfrom
brain/unarchive-refresh
Jun 9, 2026
Merged

fix(desktop): refresh channel state after unarchive#923
wesbillman merged 1 commit into
mainfrom
brain/unarchive-refresh

Conversation

@wesbillman

Copy link
Copy Markdown
Collaborator

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 read archived_at fresh from the DB.

Root cause

In desktop/src/features/channels/hooks.ts there's an asymmetry between the archive and unarchive mutations:

  • useArchiveChannelMutation patches the cache optimistically (onSuccess) and invalidates/refetches via onSettled → invalidateChannelState.
  • useUnarchiveChannelMutation only did the optimistic patch — no onSettled.

The optimistic patch updates channelsQueryKey and 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; with useChannelsQuery on a 60s staleTime/refetchInterval, the stale archived state sticks until an unrelated refetch fires.

Fix

Give the unarchive mutation the same onSettled: invalidateChannelState the 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 — clean
  • biome lint (changed file) — clean
  • pnpm test — 585/585 pass
  • pre-push hook suite (rust-tests, clippy, desktop/mobile/tauri tests) — all green

Note on tests

No regression test added. The desktop suite runs node's built-in test runner over *.test.mjs for 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.

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>
@wesbillman wesbillman requested a review from a team as a code owner June 9, 2026 16:36
@wesbillman wesbillman merged commit 56230c1 into main Jun 9, 2026
14 checks passed
@wesbillman wesbillman deleted the brain/unarchive-refresh branch June 9, 2026 16:49
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
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