fix: hide reply button and menu for NIP-10 root message

In NIP-10 thread chats, the root message now cannot be replied to
directly, as all messages in the thread are implicitly replies to
the root.

Changes:
- Added isRootMessage prop to MessageItem component
- Hide reply button when message is the root message
- Remove reply option from context menu for root message
- Root message check: protocol === "nip-10" && message ID matches rootEventId
This commit is contained in:
Claude
2026-01-19 20:31:39 +00:00
parent a6e0a9c1a3
commit 0d55331303

View File

@@ -262,6 +262,7 @@ const MessageItem = memo(function MessageItem({
onReply,
canReply,
onScrollToMessage,
isRootMessage,
}: {
message: Message;
adapter: ChatProtocolAdapter;
@@ -269,6 +270,7 @@ const MessageItem = memo(function MessageItem({
onReply?: (messageId: string) => void;
canReply: boolean;
onScrollToMessage?: (messageId: string) => void;
isRootMessage?: boolean;
}) {
// Get relays for this conversation (memoized to prevent unnecessary re-subscriptions)
const relays = useMemo(
@@ -377,7 +379,7 @@ const MessageItem = memo(function MessageItem({
</span>
{/* Reactions display - inline after timestamp */}
<MessageReactions messageId={message.id} relays={relays} />
{canReply && onReply && (
{canReply && onReply && !isRootMessage && (
<button
onClick={() => onReply(message.id)}
className="opacity-0 group-hover:opacity-100 transition-opacity text-muted-foreground hover:text-foreground ml-auto"
@@ -414,7 +416,11 @@ const MessageItem = memo(function MessageItem({
return (
<ChatMessageContextMenu
event={message.event}
onReply={canReply && onReply ? () => onReply(message.id) : undefined}
onReply={
canReply && onReply && !isRootMessage
? () => onReply(message.id)
: undefined
}
conversation={conversation}
adapter={adapter}
message={message}
@@ -1027,6 +1033,11 @@ export function ChatViewer({
</div>
);
}
// For NIP-10 threads, check if this is the root message
const isRootMessage =
protocol === "nip-10" &&
conversation.metadata?.rootEventId === item.data.id;
return (
<MessageItem
key={item.data.id}
@@ -1036,6 +1047,7 @@ export function ChatViewer({
onReply={handleReply}
canReply={canSign}
onScrollToMessage={handleScrollToMessage}
isRootMessage={isRootMessage}
/>
);
}}