mirror of
https://github.com/snowykami/neo-blog.git
synced 2025-09-26 19:16:24 +00:00
✨ feat: 优化评论项组件的布局和交互,增强用户体验
This commit is contained in:
@ -149,106 +149,108 @@ export function CommentItem(
|
|||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="flex">
|
<div>
|
||||||
<div className="fade-in">
|
<div className="flex">
|
||||||
{getGravatarByUser(comment.user)}
|
<div onClick={() => clickToUserProfile(comment.user.username)} className="cursor-pointer fade-in">
|
||||||
</div>
|
{getGravatarByUser(comment.user)}
|
||||||
<div className="flex-1 pl-2 fade-in-up">
|
</div>
|
||||||
<div className="font-bold text-base text-slate-800 dark:text-slate-100 fade-in-up">{comment.user.nickname}</div>
|
<div className="flex-1 pl-2 fade-in-up">
|
||||||
<p className="text-lg text-slate-600 dark:text-slate-400 fade-in">
|
<div onClick={() => clickToUserProfile(comment.user.username)} className="font-bold text-base text-slate-800 dark:text-slate-100 cursor-pointer fade-in-up">{comment.user.nickname}</div>
|
||||||
{
|
<p className="text-lg text-slate-600 dark:text-slate-400 fade-in">
|
||||||
isPrivate && <Lock className="inline w-4 h-4 mr-1 mb-1 text-slate-500 dark:text-slate-400" />
|
{
|
||||||
}
|
isPrivate && <Lock className="inline w-4 h-4 mr-1 mb-1 text-slate-500 dark:text-slate-400" />
|
||||||
{
|
}
|
||||||
parentComment &&
|
{
|
||||||
<>{t("reply")} <button onClick={() => clickToUserProfile(parentComment.user.nickname)} className="text-primary">{parentComment?.user.nickname}</button>: </>
|
parentComment &&
|
||||||
}
|
<>{t("reply")} <button onClick={() => clickToUserProfile(parentComment.user.nickname)} className="text-primary">{parentComment?.user.nickname}</button>: </>
|
||||||
{comment.content}
|
}
|
||||||
</p>
|
{comment.content}
|
||||||
<div className="mt-1 text-xs text-slate-500 dark:text-slate-400 flex items-center gap-4 fade-in">
|
</p>
|
||||||
<span>{new Date(comment.updatedAt).toLocaleString()}</span>
|
<div className="mt-1 text-xs text-slate-500 dark:text-slate-400 flex items-center gap-4 fade-in">
|
||||||
{/* 点赞按钮 */}
|
<span>{new Date(comment.updatedAt).toLocaleString()}</span>
|
||||||
<button
|
{/* 点赞按钮 */}
|
||||||
title={t(liked ? "unlike" : "like")}
|
<button
|
||||||
onClick={handleToggleLike}
|
title={t(liked ? "unlike" : "like")}
|
||||||
className={`flex items-center justify-center px-2 py-1 h-5 gap-1 text-xs rounded
|
onClick={handleToggleLike}
|
||||||
|
className={`flex items-center justify-center px-2 py-1 h-5 gap-1 text-xs rounded
|
||||||
${liked ? 'bg-primary ' : 'bg-slate-400 hover:bg-slate-600'}
|
${liked ? 'bg-primary ' : 'bg-slate-400 hover:bg-slate-600'}
|
||||||
text-primary-foreground dark:text-white dark:hover:bg-slate-500 fade-in`}
|
text-primary-foreground dark:text-white dark:hover:bg-slate-500 fade-in`}
|
||||||
>
|
>
|
||||||
<Heart className="w-3 h-3" /> <div>{likeCount}</div>
|
<Heart className="w-3 h-3" /> <div>{likeCount}</div>
|
||||||
</button>
|
</button>
|
||||||
{/* 回复按钮 */}
|
{/* 回复按钮 */}
|
||||||
<button
|
<button
|
||||||
title={t("reply")}
|
title={t("reply")}
|
||||||
onClick={() => { setShowReplyInput(!showReplyInput); setShowEditInput(false); }}
|
onClick={() => { setShowReplyInput(!showReplyInput); setShowEditInput(false); }}
|
||||||
className={`flex items-center justify-center px-2 py-1 h-5
|
className={`flex items-center justify-center px-2 py-1 h-5
|
||||||
text-primary-foreground dark:text-white text-xs
|
text-primary-foreground dark:text-white text-xs
|
||||||
rounded ${showReplyInput ? "bg-slate-600" : "bg-slate-400"} hover:bg-slate-600 dark:hover:bg-slate-500 fade-in-up`}>
|
rounded ${showReplyInput ? "bg-slate-600" : "bg-slate-400"} hover:bg-slate-600 dark:hover:bg-slate-500 fade-in-up`}>
|
||||||
<Reply className="w-3 h-3" />
|
<Reply className="w-3 h-3" />
|
||||||
</button>
|
</button>
|
||||||
{/* 编辑和删除按钮 仅自己的评论可见 */}
|
{/* 编辑和删除按钮 仅自己的评论可见 */}
|
||||||
{user?.id === comment.user.id && (
|
{user?.id === comment.user.id && (
|
||||||
<>
|
<>
|
||||||
<button
|
<button
|
||||||
title={t("edit")}
|
title={t("edit")}
|
||||||
className={`
|
className={`
|
||||||
flex items-center justify-center px-2 py-1 h-5
|
flex items-center justify-center px-2 py-1 h-5
|
||||||
text-primary-foreground dark:text-white text-xs
|
text-primary-foreground dark:text-white text-xs
|
||||||
rounded ${showEditInput ? "bg-slate-600" : "bg-slate-400"} hover:bg-slate-600 dark:hover:bg-slate-500 fade-in-up`}
|
rounded ${showEditInput ? "bg-slate-600" : "bg-slate-400"} hover:bg-slate-600 dark:hover:bg-slate-500 fade-in-up`}
|
||||||
onClick={() => { setShowEditInput(!showEditInput); setShowReplyInput(false); }}
|
onClick={() => { setShowEditInput(!showEditInput); setShowReplyInput(false); }}
|
||||||
>
|
>
|
||||||
<Pencil className="w-3 h-3" />
|
<Pencil className="w-3 h-3" />
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<button
|
<button
|
||||||
title={t("delete")}
|
title={t("delete")}
|
||||||
className={`flex items-center justify-center px-2 py-1 h-5 rounded
|
className={`flex items-center justify-center px-2 py-1 h-5 rounded
|
||||||
text-primary-foreground dark:text-white text-xs
|
text-primary-foreground dark:text-white text-xs
|
||||||
${confirming ? 'bg-red-600 hover:bg-red-700 dark:bg-red-500 dark:hover:bg-red-600' : 'bg-slate-400 hover:bg-slate-600 dark:hover:bg-slate-500'} fade-in`}
|
${confirming ? 'bg-red-600 hover:bg-red-700 dark:bg-red-500 dark:hover:bg-red-600' : 'bg-slate-400 hover:bg-slate-600 dark:hover:bg-slate-500'} fade-in`}
|
||||||
onClick={() => onClick(() => { onCommentDelete({ commentId: comment.id }); })}
|
onClick={() => onClick(() => { onCommentDelete({ commentId: comment.id }); })}
|
||||||
onBlur={onBlur}
|
onBlur={onBlur}
|
||||||
>
|
>
|
||||||
|
|
||||||
<Trash className="w-3 h-3" />
|
<Trash className="w-3 h-3" />
|
||||||
{confirming && (
|
{confirming && (
|
||||||
<span className="ml-1 confirm-delete-anim">{t("confirm_delete")}</span>
|
<span className="ml-1 confirm-delete-anim">{t("confirm_delete")}</span>
|
||||||
)}
|
)}
|
||||||
|
</button>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{replyCount > 0 &&
|
||||||
|
<button onClick={toggleReplies} className="fade-in-up">
|
||||||
|
{!showReplies ? t("expand_replies", { count: replyCount }) : t("collapse_replies")}
|
||||||
</button>
|
</button>
|
||||||
</>
|
}
|
||||||
)}
|
|
||||||
|
|
||||||
{replyCount > 0 &&
|
|
||||||
<button onClick={toggleReplies} className="fade-in-up">
|
|
||||||
{!showReplies ? t("expand_replies", { count: replyCount }) : t("collapse_replies")}
|
|
||||||
</button>
|
|
||||||
}
|
|
||||||
</div>
|
|
||||||
{/* 这俩输入框一次只能显示一个 */}
|
|
||||||
{showReplyInput && !showEditInput && <CommentInput
|
|
||||||
user={user}
|
|
||||||
onCommentSubmitted={onReply}
|
|
||||||
/>}
|
|
||||||
{showEditInput && !showReplyInput && <CommentInput
|
|
||||||
user={user}
|
|
||||||
initContent={comment.content}
|
|
||||||
initIsPrivate={isPrivate}
|
|
||||||
onCommentSubmitted={onCommentEdit}
|
|
||||||
isUpdate={true}
|
|
||||||
/>}
|
|
||||||
{showReplies && replies.length > 0 && (
|
|
||||||
<div className="mt-4 pl-4 border-l border-slate-300 dark:border-slate-600 space-y-4">
|
|
||||||
{replies.map((reply) => (
|
|
||||||
<CommentItem
|
|
||||||
key={reply.id}
|
|
||||||
user={reply.user}
|
|
||||||
comment={reply}
|
|
||||||
parentComment={comment}
|
|
||||||
onCommentDelete={onReplyDelete}
|
|
||||||
/>
|
|
||||||
))}
|
|
||||||
</div>
|
</div>
|
||||||
)}
|
{/* 这俩输入框一次只能显示一个 */}
|
||||||
</div>
|
{showReplyInput && !showEditInput && <CommentInput
|
||||||
</div >
|
user={user}
|
||||||
|
onCommentSubmitted={onReply}
|
||||||
|
/>}
|
||||||
|
{showEditInput && !showReplyInput && <CommentInput
|
||||||
|
user={user}
|
||||||
|
initContent={comment.content}
|
||||||
|
initIsPrivate={isPrivate}
|
||||||
|
onCommentSubmitted={onCommentEdit}
|
||||||
|
isUpdate={true}
|
||||||
|
/>}
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div >
|
||||||
|
{showReplies && replies.length > 0 && (
|
||||||
|
<div className="mt-4 pl-4 md:pl-8 border-l border-slate-300 dark:border-slate-600 space-y-4">
|
||||||
|
{replies.map((reply) => (
|
||||||
|
<CommentItem
|
||||||
|
key={reply.id}
|
||||||
|
user={reply.user}
|
||||||
|
comment={reply}
|
||||||
|
parentComment={comment}
|
||||||
|
onCommentDelete={onReplyDelete}
|
||||||
|
/>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
)}</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user