Skip to content

feat(desktop): show thread replies inline - #7036

Draft
asymetryk wants to merge 6 commits into
block:mainfrom
asymetryk:feature/inline-thread-replies
Draft

feat(desktop): show thread replies inline#7036
asymetryk wants to merge 6 commits into
block:mainfrom
asymetryk:feature/inline-thread-replies

Conversation

@asymetryk

Copy link
Copy Markdown

What

  • add a separate per-thread Show in channel / Hide replies control without changing the existing thread-panel action
  • fetch expanded reply subtrees on demand and render direct plus nested replies in the main channel or DM timeline
  • keep loading and failure state scoped to the owning expanded thread, with an inline retry action

Validation

  • CHECK_FILE_SIZES_BASE=upstream/main just ci
  • focused thread contracts: 31 passed
  • Playwright smoke: channel and DM inline expansion, nested replies, keyboard activation, panel independence — 2 passed
  • visually reviewed channel and DM screenshots

Signed-off-by: Howard Shaw <asymetryk@outlook.com>
@github-actions

github-actions Bot commented Aug 29, 2026

Copy link
Copy Markdown

🔐 Codex Security Review

Status: review required for the current range.

The current range is 00e61eafa917d296104006576b7a2ddbfd58bb5a...c75ca0decc311b8271c3410d27cd97bc2464fd01.
A new review must complete for this exact range. When manual authorization
is required, a Block organization member must comment exactly
@buzz-security-review c75ca0decc311b8271c3410d27cd97bc2464fd01 to authorize a new review.
Any previous review applies only to its recorded range.

@asymetryk

Copy link
Copy Markdown
Author

Screenshots

pr-7036--channel

pr-7036--dm

@asymetryk

Copy link
Copy Markdown
Author

@codex review

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Aug 29, 2026

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review Completed 2026-08-29T17:59:30.569729Z c75ca0d Manual request
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@asymetryk

Copy link
Copy Markdown
Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 4a5d8b89dd

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread desktop/src/features/messages/useThreadReplies.ts
Comment thread desktop/src/features/messages/ui/TimelineMessageRow.tsx Outdated

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 4a5d8b89dd

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread desktop/src/features/channels/ui/ChannelScreen.tsx
Comment thread desktop/src/features/messages/useThreadReplies.ts Outdated
Signed-off-by: Howard Shaw <asymetryk@outlook.com>
@asymetryk

Copy link
Copy Markdown
Author

Screenshots

pr-7036--channel

pr-7036--dm

asymetryk added a commit to asymetryk/buzz that referenced this pull request Aug 29, 2026
@asymetryk

Copy link
Copy Markdown
Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 5d09a9ba13

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread desktop/src/features/messages/ui/TimelineMessageRow.tsx
Comment thread desktop/src/features/messages/ui/TimelineMessageRow.tsx
Signed-off-by: Howard Shaw <asymetryk@outlook.com>
@asymetryk

Copy link
Copy Markdown
Author

Screenshots

pr-7036--channel

pr-7036--dm

asymetryk added a commit to asymetryk/buzz that referenced this pull request Aug 29, 2026
@asymetryk

Copy link
Copy Markdown
Author

@codex review

1 similar comment
@asymetryk

Copy link
Copy Markdown
Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: e73064c7b3

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread desktop/src/features/messages/useThreadReplies.ts Outdated
Signed-off-by: Howard Shaw <asymetryk@outlook.com>
@asymetryk

Copy link
Copy Markdown
Author

@codex review

@asymetryk

Copy link
Copy Markdown
Author

Screenshots

pr-7036--channel

pr-7036--dm

asymetryk added a commit to asymetryk/buzz that referenced this pull request Aug 29, 2026

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 5115275982

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread desktop/src/features/messages/useThreadReplies.ts
Signed-off-by: Howard Shaw <asymetryk@outlook.com>
@asymetryk

Copy link
Copy Markdown
Author

@codex review

asymetryk added a commit to asymetryk/buzz that referenced this pull request Aug 29, 2026
@asymetryk

Copy link
Copy Markdown
Author

Screenshots

pr-7036--channel

pr-7036--dm

@asymetryk

Copy link
Copy Markdown
Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 782384f031

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread desktop/src/features/messages/useThreadReplies.ts Outdated
Signed-off-by: Howard Shaw <asymetryk@outlook.com>
@asymetryk

Copy link
Copy Markdown
Author

@codex review

@asymetryk

Copy link
Copy Markdown
Author

Screenshots

pr-7036--channel

pr-7036--dm

asymetryk added a commit to asymetryk/buzz that referenced this pull request Aug 29, 2026
@asymetryk

Copy link
Copy Markdown
Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: c75ca0decc

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

const handleEdit = React.useCallback(
(message: { id: string }) => {
(message: { id: string; rootId?: string | null }) => {
const threadHeadId = message.rootId ?? null;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Keep broadcast edits in the main composer

When the user edits a broadcast reply, isThreadReply deliberately classifies it as a top-level message, but it still carries a rootId; treating every such message as a thread child opens the containing thread before setting the non-thread edit target. In a single-panel or focus-drawer layout, that panel covers the main composer while the thread composer receives no edit target, leaving no visible editor. Only route genuine non-broadcast thread replies through this panel-opening path.

Useful? React with 👍 / 👎.

Comment on lines +254 to +255
messageIds.push(rootId, ...(replyIdsByRoot.get(rootId) ?? []));
if (!errorRootIds.has(rootId)) activeRevealedRootIds.add(rootId);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Freeze failed-refresh snapshots before live updates

When an expanded thread's refresh fails with cached rows, this deliberately leaves the root out of activeRevealedRootIds; if a reply then arrives through the live subscription while the root is offscreen, the cache update reruns this helper and the new reply is included in messageIds, so it is marked read without being seen. Fresh evidence after the prior fix is the new error branch here: it repeatedly processes the entire cache until a retry succeeds, recreating the future-reply unread regression specifically after refresh failures. Track the already-rendered error snapshot separately so later live additions stay unread while preserving retry eligibility.

Useful? React with 👍 / 👎.

Comment on lines +298 to +300
inlineRepliesPending={inlineThreadController?.pendingRootIds.has(
item.entry.message.id,
)}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Show loading during stale empty-cache refreshes

When this thread query has a cached empty array, expanding it starts a stale background refresh with isPending === false and isFetching === true; because the row only receives pendingRootIds, it displays “No replies available” while replies are actively loading, even though the summary says the thread has replies. Use the already-collected fetchingRootIds state when the rendered row list is empty so this refresh path shows the loading status instead of a false empty result.

Useful? React with 👍 / 👎.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: c75ca0decc

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +172 to +173
const rootIds =
state.channelId === activeChannelId ? state.rootIds : EMPTY_THREAD_ROOT_IDS;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Clear inline expansions when leaving the channel

When a root is expanded in channel A, navigating to channel B substitutes the empty set but preserves A's state, so returning to A silently restores the expansion. Meanwhile, useMarkInlineRepliesRead has filtered its revealed-root snapshot to empty while B was active; after A's stale-cache refresh completes, every reply that arrived while the user was away is treated as newly revealed and marked read even if the restored root is offscreen. Fresh evidence after the earlier future-reply fix is this channel-mismatch branch retaining A's Set rather than resetting it; clear expansions on channel change or retain read snapshots per channel.

Useful? React with 👍 / 👎.

Comment on lines +183 to +186
if (nextRootIds.has(message.id)) {
nextRootIds.delete(message.id);
} else {
nextRootIds.add(message.id);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Fetch broadcast descendants from their actual thread root

When a broadcast reply has descendants, it can receive a thread summary as a top-level timeline row, but toggling it stores message.id as the query root. Broadcast replies still carry their containing root in message.rootId, and the relay's subtree query matches thread_metadata.root_event_id, so descendants rooted at the original message are not returned for the broadcast ID; after the containing root's cached data is removed, this expansion incorrectly shows “No replies available.” Track the display subtree separately while fetching through the containing root.

Useful? React with 👍 / 👎.

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