diff --git a/web/src/components/comment/comment-input.tsx b/web/src/components/comment/comment-input.tsx
index 24ba64b..894d644 100644
--- a/web/src/components/comment/comment-input.tsx
+++ b/web/src/components/comment/comment-input.tsx
@@ -49,6 +49,10 @@ export function CommentInput(
toast.error(t("content_required"));
return;
}
+ if (initContent === commentContent.trim() && initIsPrivate === isPrivate) {
+ toast.warning(t("comment_unchanged"));
+ return;
+ }
onCommentSubmitted({ commentContent, isPrivate });
setCommentContent("");
};
@@ -62,7 +66,7 @@ export function CommentInput(
-
diff --git a/web/src/components/comment/comment-item.tsx b/web/src/components/comment/comment-item.tsx
index d41d268..c94019f 100644
--- a/web/src/components/comment/comment-item.tsx
+++ b/web/src/components/comment/comment-item.tsx
@@ -21,11 +21,15 @@ export function CommentItem(
comment,
parentComment,
onCommentDelete,
+ activeInput,
+ setActiveInputId
}: {
user: User | null,
comment: Comment,
parentComment: Comment | null,
onCommentDelete: ({ commentId }: { commentId: number }) => void,
+ activeInput: { id: number; type: 'reply' | 'edit' } | null,
+ setActiveInputId: (input: { id: number; type: 'reply' | 'edit' } | null) => void,
}
) {
const t = useTranslations("Comment")
@@ -40,10 +44,8 @@ export function CommentItem(
const [isPrivate, setIsPrivate] = useState(comment.isPrivate);
const [replyCount, setReplyCount] = useState(comment.replyCount);
const [showReplies, setShowReplies] = useState(false);
- const [showReplyInput, setShowReplyInput] = useState(false);
const [replies, setReplies] = useState([]);
const [repliesLoaded, setRepliesLoaded] = useState(false);
- const [showEditInput, setShowEditInput] = useState(false);
const handleToggleLike = () => {
if (!canClickLike) {
@@ -112,7 +114,7 @@ export function CommentItem(
toast.success(t("edit_success"));
comment.content = newContent;
setIsPrivate(isPrivate);
- setShowEditInput(false);
+ setActiveInputId(null);
}).catch(error => {
toast.error(t("edit_failed") + ": " + error.message);
});
@@ -129,7 +131,7 @@ export function CommentItem(
toast.success(t("comment_success"));
reloadReplies();
setShowReplies(true);
- setShowReplyInput(false);
+ setActiveInputId(null);
setReplyCount(replyCount + 1);
}).catch(error => {
toast.error(t("comment_failed") + ": " +
@@ -181,10 +183,16 @@ export function CommentItem(
{/* 回复按钮 */}
{/* 编辑和删除按钮 仅自己的评论可见 */}
@@ -192,11 +200,18 @@ export function CommentItem(
<>
@@ -225,12 +240,12 @@ export function CommentItem(
}
{/* 这俩输入框一次只能显示一个 */}
- {showReplyInput && !showEditInput && }
- {showEditInput && !showReplyInput &&
))}
diff --git a/web/src/components/comment/index.tsx b/web/src/components/comment/index.tsx
index 982d724..a6005f0 100644
--- a/web/src/components/comment/index.tsx
+++ b/web/src/components/comment/index.tsx
@@ -33,6 +33,7 @@ export function CommentSection(
const [currentUser, setCurrentUser] = useState(null);
const [comments, setComments] = useState([]);
const [refreshCommentsKey, setRefreshCommentsKey] = useState(0);
+ const [activeInput, setActiveInput] = useState<{ id: number; type: 'reply' | 'edit' } | null>(null);
// 获取当前登录用户
useEffect(() => {
@@ -98,6 +99,8 @@ export function CommentSection(
comment={comment}
parentComment={null}
onCommentDelete={onCommentDelete}
+ activeInput={activeInput}
+ setActiveInputId={setActiveInput}
/>
))}
diff --git a/web/src/locales/zh-CN.json b/web/src/locales/zh-CN.json
index da6e3b7..b71c3c7 100644
--- a/web/src/locales/zh-CN.json
+++ b/web/src/locales/zh-CN.json
@@ -7,6 +7,7 @@
"comment": "评论",
"comment_failed": "评论失败",
"comment_success": "评论成功!",
+ "comment_unchanged": "评论内容未更改。",
"confirm_delete": "确定吗?",
"content_required": "评论内容不能为空。",
"delete": "删除",
@@ -20,8 +21,9 @@
"like_failed": "点赞失败",
"like_success": "点赞成功",
"login_required": "请先登录后再操作",
- "placeholder": "写你的评论...",
+ "placeholder": "写下你的评论...",
"private": "私密评论",
+ "private_placeholder": "悄悄地说一句...",
"reply": "回复",
"submit": "提交",
"unlike": "取消点赞",