Skip to content

fix(desktop): flatten private/DM timelines without stripping reply tags#2593

Open
StephGlansberg wants to merge 6 commits into
block:mainfrom
StephGlansberg:fix/desktop-flatten-private-timelines
Open

fix(desktop): flatten private/DM timelines without stripping reply tags#2593
StephGlansberg wants to merge 6 commits into
block:mainfrom
StephGlansberg:fix/desktop-flatten-private-timelines

Conversation

@StephGlansberg

Copy link
Copy Markdown

What Problem This Solves

Private rooms and DMs (including AEON Aspect offices like #aspect-nexus) show reply-tagged messages as “1 reply” thread summaries instead of a normal flat chat feed, even when those replies are the primary conversation.

Why This Change Was Made

Presentation-only flatten for visibility === "private" and DM channels: include reply-tagged events on the main timeline with no summary badge, while keeping NIP-10 reply tags on the wire so ACP turn receipts still correlate.

User Impact

Private/DM timelines read as ordinary chat. Public/broadcast channels are unchanged. Receipt/ACP behavior is unchanged.

Evidence

  • Unit tests: flattenChannelTimeline + threadPanel flatten cases (27 passing in prior verification).
  • Pre-push hooks green on this branch (desktop-check/test, rust-tests, mobile-test, desktop-tauri-test).

Made with Cursor

@StephGlansberg
StephGlansberg requested a review from a team as a code owner July 23, 2026 19:25
Show reply-tagged events inline in private rooms and DMs so Nexus chat
reads as a normal feed, while keeping NIP-10 anchors for ACP receipts.

Co-authored-by: Cursor <cursoragent@cursor.com>
Signed-off-by: StephGlansberg <StephGlansberg@users.noreply.github.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
@StephGlansberg
StephGlansberg force-pushed the fix/desktop-flatten-private-timelines branch from 90b56cf to ae835ca Compare July 23, 2026 19:25
Signed-off-by: StephGlansberg <StephGlansberg@users.noreply.github.com>
Co-authored-by: Cursor <cursoragent@cursor.com>

@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: 90b56cf835

ℹ️ 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/lib/flattenChannelTimeline.ts
Comment thread desktop/src/features/messages/lib/flattenChannelTimeline.ts Outdated
Signed-off-by: StephGlansberg <StephGlansberg@users.noreply.github.com>
…rivate-timelines

Signed-off-by: StephGlansberg <StephGlansberg@users.noreply.github.com>
@StephGlansberg
StephGlansberg force-pushed the fix/desktop-flatten-private-timelines branch from 5d804a4 to e091836 Compare July 24, 2026 20:00
@StephGlansberg

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: e091836187

ℹ️ 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/lib/threadPanel.ts
Comment thread desktop/scripts/check-file-sizes.mjs Outdated
Signed-off-by: StephGlansberg <StephGlansberg@users.noreply.github.com>
@StephGlansberg

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: 63b13f6bc1

ℹ️ 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/lib/threadPanel.ts Outdated
Signed-off-by: StephGlansberg <StephGlansberg@users.noreply.github.com>
@StephGlansberg

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: 4bb50159cb

ℹ️ 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".

if (!shouldFlattenChannelTimeline(channel)) {
return messages;
}
const rootIds = flattenTimelineRootIds(window);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Include recent replies whose roots are off-window

In a private/DM channel where a new reply lands on an older thread root that is not in the newest top-level window, this only hydrates replies for roots that already have a 39005 summary in the loaded window. I checked the relay window path: top_level rows exclude non-broadcast replies and only include depth-null/depth-0/broadcast rows, so the recent reply itself is absent; after a cold load or reconnect replaceNewestChannelWindow also clears the live overlay and this code never fetches that root. The visible flattened timeline can therefore drop the newest DM/private messages until the user pages far enough back to load the old root.

Useful? React with 👍 / 👎.

Comment on lines 454 to +458
.filter(
(message) =>
message.parentId == null || isBroadcastReply(message.tags ?? []),
flattenReplies ||
message.parentId == null ||
isBroadcastReply(message.tags ?? []),

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 Advance read state over flattened private replies

When flattenReplies admits reply-tagged events as ordinary private/DM timeline rows, the passive read marker still uses ChannelScreen's newest parentId === null message and calls markChannelRead(..., { topLevelOnly: true }). For a DM/private room whose latest visible rows are flattened replies, opening and reading the channel leaves the read marker at the older root, so the channel becomes unread again as soon as it is no longer active. The read-at computation needs to treat flattened replies as visible channel rows too.

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