Conversation
added 6 commits
September 29, 2026 21:29
Replace Archive with Unarchive for direct owners and admins, reuse the confirmed lifecycle command and retain the open conversation. Keep joined archived channels reachable through name search without adding them to recent activity. Cover restore authority, host isolation, readback uncertainty and the full archive-to-restore browser journey. Signed-off-by: Carl <acda9e433d19dcd0e6b6840f7f4b98f3a56f1fab98049d444c087019e6d36560@buzz.block.builderlab.xyz>
Signed-off-by: Carl <acda9e433d19dcd0e6b6840f7f4b98f3a56f1fab98049d444c087019e6d36560@buzz.block.builderlab.xyz>
Signed-off-by: Carl <acda9e433d19dcd0e6b6840f7f4b98f3a56f1fab98049d444c087019e6d36560@buzz.block.builderlab.xyz>
Keep the selected conversation and Settings through archive and restore, preserve focus when actions remount, and block new messages while archived without discarding drafts. Use standard button spinners and accessible status for lifecycle confirmations and Edit details permission checks. Cover the retained destination, recovery, and held-read presentation in component and browser tests. Signed-off-by: Carl <acda9e433d19dcd0e6b6840f7f4b98f3a56f1fab98049d444c087019e6d36560@buzz.block.builderlab.xyz>
Exercise a nonempty draft in the existing built-app lifecycle journey, including reload and the search return path. Assert archived send lockout and restored editing without adding browser cases. Signed-off-by: Carl <acda9e433d19dcd0e6b6840f7f4b98f3a56f1fab98049d444c087019e6d36560@buzz.block.builderlab.xyz>
Align the sorting integration journey with the accepted archive contract: retain the selected URL and disabled composer, including after reload. Preserve Recent ordering, DM visibility and publication assertions. Signed-off-by: Carl <acda9e433d19dcd0e6b6840f7f4b98f3a56f1fab98049d444c087019e6d36560@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.
Overview
Category: improvement
User Impact: Channel administrators can archive and restore a channel without losing their place or draft, with consistent loading feedback while actions are pending.
Problem: Archiving currently removes the open conversation and Settings, leaving no in-app restoration path. Lifecycle and permission checks also use inconsistent loading feedback.
Solution: Keep the selected conversation and Settings open, replace Archive with Unarchive, and preserve the draft while sending is disabled. Reuse the existing lifecycle, navigation, and loading-button owners so removal actions retain their current behavior and recovery.
Follow-up to #385; only the five unmerged follow-up commits are included. No new relay-server work, permission expansion, or general archived-channel browser.
Changes
File changes
dev/relay-broker-api.test.mjs
Exercise the narrow Unarchive command at the development-broker boundary.
docs/channels.md
Document restoration, search reachability, retained context, loading feedback, and the full broker-process restart requirement. Native-support wording still needs reconciliation as noted above.
src/app/shell/SearchResults.tsx
Offer eligible joined archived channels in explicit search, with an archive label, without adding them to Recent activity.
src/app/shell/SearchResults.test.tsx
Cover archived search eligibility and exclusion from recent destinations.
src/bundled/channels/ChannelDetailsEditor.tsx
Use the shared loading button for permission checks and retain screen-reader status and visible recovery.
src/bundled/channels/ChannelDetailsEditor.test.tsx
Verify pending permission feedback remains accessible and non-actionable.
src/bundled/channels/ChannelLifecycleActions.tsx
Swap Archive/Unarchive according to current authority and preserve pending/error presentation.
src/bundled/channels/ChannelLifecycleActions.test.tsx
Cover restoration eligibility and action/status recovery.
src/bundled/channels/ChannelLifecycleDialog.tsx
Add Unarchive confirmation and use shared loading feedback without weakening pending lockout.
src/bundled/channels/ChannelLifecycleMenu.tsx
Reuse the lifecycle action model for Archive/Unarchive labels and selection.
src/bundled/channels/ChannelLifecycleMenu.test.tsx
Verify restoration actions and loading/recovery presentation.
src/bundled/channels/ChannelsPage.tsx
Separate joined-channel access from sidebar visibility so an archived destination remains selected; refresh Settings actions when archive state changes.
src/features/channel-navigation/ChannelNavigationState.tsx
Retain a persistent Settings focus fallback when lifecycle action buttons remount.
src/features/channel-navigation/ChannelSidebar.tsx
Keep the destination for Archive/Unarchive while preserving removal navigation for Delete/Leave/Hide.
src/features/messages/MessageComposer.tsx
Disable archived-channel sending without discarding the existing draft.
src/features/messages/MessageComposer.test.tsx
Cover draft retention and restored editing across archive-state changes.
src/features/relay/channel-lifecycle-protocol.ts
Add the narrow Unarchive template and direct owner/admin eligibility using the existing lifecycle command.
src/features/relay/channel-lifecycle.ts
Authorize restoration and require confirming metadata before updating shared discovery.
src/features/relay/channel-lifecycle.test.ts
Cover restore authority, command shape, host isolation, readback, and uncertain outcomes.
tests/browser/channel-archive-delete-pane.spec.mjs
Extend the existing real-app journey through Archive, reload, navigation away, search, Unarchive, and another reload with a nonempty draft; assert spinner geometry, lockout, and focus recovery.
tests/browser/channel-lifecycle.spec.mjs
Assert retained archive destinations while keeping Delete/Leave/Hide removal behavior, including reload with no visible rows.
tests/browser/fixture.mjs
Model restore publications in the isolated upstream fixture by removing the archive flag.
Validation
Checked head:
083b43669c33f53e699d2a43a93b7d7352048d44, based on main329fe2a1de0ad7f9aa8eebbc02e1a957bcafa25d. All five patches replayed unchanged; working tree clean.git diff --check origin/main...HEADpassed; remote branch matches the checked head.Reproduction Steps
Screenshots / Demos
Real built browser app at the checked head, in dark theme with a color accent, using isolated synthetic fixture identities and neutral content. Crops exclude unrelated workspace context. These are active → archived → restored states of this build, not native captures or before/after revisions.
Active — draft and Settings open
Archived — same draft, disabled sending, Unarchive available
Restored — same draft, sending enabled again
Loading states
Confirmation pending: shared button spinner; cancellation and repeat submission are locked.
Edit details permission lookup: shared loading button rather than a visible checking paragraph; accessible status remains.
Prepared with Carl (AI agent) assistance.