feat(web): add threading lines to comment replies

This commit is contained in:
CREDO23 2026-01-16 12:59:38 +02:00
parent 09317cd9f7
commit 111ecc79fd

View file

@ -45,20 +45,34 @@ export function CommentThread({
setIsReplyComposerOpen(false); setIsReplyComposerOpen(false);
}; };
const hasReplies = thread.replies.length > 0;
const showReplies = thread.replies.length === 1 || isRepliesExpanded;
return ( return (
<div className="space-y-2"> <div>
{/* Parent comment */}
<CommentItem <CommentItem
comment={parentComment} comment={parentComment}
onEdit={(id) => onEditComment(id, "")} onEdit={(id) => onEditComment(id, "")}
onDelete={onDeleteComment} onDelete={onDeleteComment}
/> />
{/* Replies and actions - using flex layout with connector */}
{(hasReplies || isReplyComposerOpen) && (
<div className="flex">
{/* Connector column - vertical line */}
<div className="flex w-7 flex-col items-center">
<div className="w-px flex-1 bg-border" />
</div>
{/* Content column */}
<div className="min-w-0 flex-1 space-y-2 pb-1">
{/* Expand/collapse for multiple replies */}
{thread.replies.length > 1 && ( {thread.replies.length > 1 && (
<div className="ml-11">
<Button <Button
variant="ghost" variant="ghost"
size="sm" size="sm"
className="h-7 px-2 text-xs text-muted-foreground hover:text-foreground" className="h-6 px-2 text-xs text-muted-foreground hover:text-foreground"
onClick={() => setIsRepliesExpanded(!isRepliesExpanded)} onClick={() => setIsRepliesExpanded(!isRepliesExpanded)}
> >
{isRepliesExpanded ? ( {isRepliesExpanded ? (
@ -68,11 +82,11 @@ export function CommentThread({
)} )}
{thread.replies.length} replies {thread.replies.length} replies
</Button> </Button>
</div>
)} )}
{thread.replies.length > 0 && (thread.replies.length === 1 || isRepliesExpanded) && ( {/* Reply items */}
<div className="ml-11 space-y-3"> {showReplies && hasReplies && (
<div className="space-y-2">
{thread.replies.map((reply) => ( {thread.replies.map((reply) => (
<CommentItem <CommentItem
key={reply.id} key={reply.id}
@ -85,7 +99,7 @@ export function CommentThread({
</div> </div>
)} )}
<div className="ml-11"> {/* Reply composer or button */}
{isReplyComposerOpen ? ( {isReplyComposerOpen ? (
<CommentComposer <CommentComposer
members={members} members={members}
@ -98,12 +112,24 @@ export function CommentThread({
autoFocus autoFocus
/> />
) : ( ) : (
<Button variant="outline" size="sm" className="h-7 px-3 text-xs" onClick={handleReply}> <Button variant="ghost" size="sm" className="h-7 px-2 text-xs" onClick={handleReply}>
<MessageSquare className="mr-1.5 size-3" /> <MessageSquare className="mr-1.5 size-3" />
Reply Reply
</Button> </Button>
)} )}
</div> </div>
</div> </div>
)}
{/* Reply button when no replies yet */}
{!hasReplies && !isReplyComposerOpen && (
<div className="ml-7 mt-1">
<Button variant="ghost" size="sm" className="h-7 px-2 text-xs" onClick={handleReply}>
<MessageSquare className="mr-1.5 size-3" />
Reply
</Button>
</div>
)}
</div>
); );
} }