fix(desktop): flatten private/DM timelines without stripping reply tags#2593
fix(desktop): flatten private/DM timelines without stripping reply tags#2593StephGlansberg wants to merge 6 commits into
Conversation
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>
90b56cf to
ae835ca
Compare
Signed-off-by: StephGlansberg <StephGlansberg@users.noreply.github.com> Co-authored-by: Cursor <cursoragent@cursor.com>
There was a problem hiding this comment.
💡 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".
Signed-off-by: StephGlansberg <StephGlansberg@users.noreply.github.com>
…rivate-timelines Signed-off-by: StephGlansberg <StephGlansberg@users.noreply.github.com>
5d804a4 to
e091836
Compare
|
@codex review |
There was a problem hiding this comment.
💡 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".
Signed-off-by: StephGlansberg <StephGlansberg@users.noreply.github.com>
|
@codex review |
There was a problem hiding this comment.
💡 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".
Signed-off-by: StephGlansberg <StephGlansberg@users.noreply.github.com>
|
@codex review |
There was a problem hiding this comment.
💡 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); |
There was a problem hiding this comment.
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 👍 / 👎.
| .filter( | ||
| (message) => | ||
| message.parentId == null || isBroadcastReply(message.tags ?? []), | ||
| flattenReplies || | ||
| message.parentId == null || | ||
| isBroadcastReply(message.tags ?? []), |
There was a problem hiding this comment.
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 👍 / 👎.
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
flattenChannelTimeline+threadPanelflatten cases (27 passing in prior verification).Made with Cursor