From 0f0006b5bdb3533a3dc4317be6677ff74cfb8ee1 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 7 Sep 2026 15:25:16 +0000 Subject: [PATCH] Render orphaned reply sub-trees and open the composer for orphaned notes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A reply whose parent was never fetched is promoted out of the thread, but its own children resolved against it fine — keep them nested beneath it instead of dropping them, and mount the inline composer when an orphaned note is the reply target so the Reply button never claims a composer that isn't there (aria-expanded/aria-controls now always point at a real node). Co-authored-by: mroxso <24775431+mroxso@users.noreply.github.com> --- src/apps/notes/index.tsx | 67 ++++++++++++++++++++++++++++++++++++---- 1 file changed, 61 insertions(+), 6 deletions(-) diff --git a/src/apps/notes/index.tsx b/src/apps/notes/index.tsx index fe1ddd8..444dedb 100644 --- a/src/apps/notes/index.tsx +++ b/src/apps/notes/index.tsx @@ -218,12 +218,29 @@ export default function NotesApp({ params, setTitle, setParams }: AppProps) { conflict.

{orphaned.map((node) => ( - +
+ + {node.event.id === replyTarget?.id && composer} + {node.children.length > 0 && ( + // The orphan's own replies resolved against it fine, so they + // stay nested beneath it even though it sits apart. +
+ {node.children.map((child) => ( + + ))} +
+ )} +
))} )} @@ -259,6 +276,44 @@ function AuthorName({ pubkey }: { pubkey: string }) { return {displayName(pubkey, author.data?.metadata)}; } +/** A well-placed sub-branch beneath an orphaned note (no tree roles — the orphan sits outside the tree). */ +function OrphanBranch({ + node, + onReply, + composer, + replyTargetId, +}: { + node: ReplyNode; + onReply?: (event: NostrEvent) => void; + composer?: React.ReactNode; + replyTargetId?: string; +}) { + return ( +
+ {node.parentPubkey && ( +

+ Replying to +

+ )} + + {node.event.id === replyTargetId && composer} + {node.children.length > 0 && ( +
+ {node.children.map((child) => ( + + ))} +
+ )} +
+ ); +} + /** One reply and its children, nested with a thread line. */ function ThreadNode({ node,