feat(评论组件): 在回复编辑器中添加用户信息输入支持

当用户首次评论或缺少昵称/邮箱时,在回复编辑器中显示用户信息输入框。修改了CWDComments、CommentList、CommentItem和ReplyEditor组件,通过currentUser和onUpdateUserInfo属性传递用户数据和更新回调,确保用户信息在回复过程中可收集和更新。
This commit is contained in:
anghunk
2026-01-23 20:02:02 +08:00
parent ee646506a9
commit 9bf0764476
4 changed files with 69 additions and 3 deletions

View File

@@ -204,6 +204,8 @@ export class CommentItem extends Component {
content: this.props.replyContent,
error: this.props.replyError,
submitting: this.props.submitting,
currentUser: this.props.currentUser,
onUpdateUserInfo: this.props.onUpdateUserInfo,
onUpdate: (content) => this.handleUpdateReplyContent(content),
onSubmit: () => this.handleSubmitReply(),
onCancel: () => this.handleCancelReply(),
@@ -229,6 +231,8 @@ export class CommentItem extends Component {
replyContent: this.props.replyContent,
replyError: this.props.replyError,
submitting: this.props.submitting,
currentUser: this.props.currentUser,
onUpdateUserInfo: this.props.onUpdateUserInfo,
adminEmail: this.props.adminEmail,
adminBadge: this.props.adminBadge,
enableCommentLike: this.props.enableCommentLike,
@@ -278,6 +282,8 @@ export class CommentItem extends Component {
content: this.props.replyContent,
error: this.props.replyError,
submitting: this.props.submitting,
currentUser: this.props.currentUser,
onUpdateUserInfo: this.props.onUpdateUserInfo,
onUpdate: (content) => this.handleUpdateReplyContent(content),
onSubmit: () => this.handleSubmitReply(),
onCancel: () => this.handleCancelReply(),
@@ -295,7 +301,8 @@ export class CommentItem extends Component {
this.replyEditor.setProps({
content: this.props.replyContent,
error: this.props.replyError,
submitting: this.props.submitting
submitting: this.props.submitting,
currentUser: this.props.currentUser
});
}
@@ -307,6 +314,7 @@ export class CommentItem extends Component {
replyContent: this.props.replyContent,
replyError: this.props.replyError,
submitting: this.props.submitting,
currentUser: this.props.currentUser,
enableCommentLike: this.props.enableCommentLike,
onLikeComment: this.props.onLikeComment
});

View File

@@ -95,6 +95,8 @@ export class CommentList extends Component {
replyContent: this.props.replyContent,
replyError: this.props.replyError,
submitting: this.props.submitting,
currentUser: this.props.currentUser,
onUpdateUserInfo: this.props.onUpdateUserInfo,
adminEmail: this.props.adminEmail,
adminBadge: this.props.adminBadge,
enableCommentLike: this.props.enableCommentLike,
@@ -159,7 +161,8 @@ export class CommentList extends Component {
// 如果只是回复状态变化,局部更新 CommentItem 而不是完全重新渲染
if (this.props.replyingTo !== prevProps.replyingTo ||
this.props.replyError !== prevProps.replyError ||
this.props.submitting !== prevProps.submitting) {
this.props.submitting !== prevProps.submitting ||
this.props.currentUser !== prevProps.currentUser) {
// 局部更新所有 CommentItem
this.commentItems.forEach((commentItem) => {
commentItem.setProps({
@@ -167,6 +170,7 @@ export class CommentList extends Component {
replyContent: this.props.replyContent,
replyError: this.props.replyError,
submitting: this.props.submitting,
currentUser: this.props.currentUser,
enableCommentLike: this.props.enableCommentLike,
onLikeComment: (commentId, isLike) => this.handleLikeComment(commentId, isLike)
});

View File

@@ -19,12 +19,18 @@ export class ReplyEditor extends Component {
*/
constructor(container, props = {}) {
super(container, props);
const { currentUser } = props;
this.state = {
content: props.content || ''
content: props.content || '',
// 如果没有昵称或邮箱,显示用户信息输入框。且一旦显示,在当前编辑器生命周期内保持显示,避免输入过程中消失
showUserInfo: !currentUser || !currentUser.name || !currentUser.email
};
}
render() {
const { currentUser } = this.props;
const { showUserInfo } = this.state;
const root = this.createElement('div', {
className: 'cwd-reply-editor',
children: [
@@ -44,6 +50,21 @@ export class ReplyEditor extends Component {
]
}),
// 用户信息输入框(当缺少信息时显示)
...(showUserInfo ? [
this.createElement('div', {
className: 'cwd-form-row',
attributes: {
style: 'margin-bottom: 12px;'
},
children: [
this.createFormField('昵称 *', 'text', 'name', currentUser?.name),
this.createFormField('邮箱 *', 'email', 'email', currentUser?.email),
this.createFormField('网址', 'url', 'url', currentUser?.url)
]
})
] : []),
// 文本框
this.createElement('textarea', {
className: 'cwd-reply-textarea',
@@ -119,6 +140,12 @@ export class ReplyEditor extends Component {
return;
}
// 如果用户信息变化,重新渲染
if (JSON.stringify(this.props.currentUser) !== JSON.stringify(prevProps?.currentUser)) {
this.render();
return;
}
// 如果有错误显示/隐藏变化,重新渲染
if (this.props.error !== prevProps?.error) {
this.render();
@@ -191,4 +218,28 @@ export class ReplyEditor extends Component {
textarea.focus();
}
}
handleUserInfoChange(field, value) {
if (this.props.onUpdateUserInfo) {
this.props.onUpdateUserInfo(field, value);
}
}
createFormField(placeholder, type, field, value) {
return this.createElement('div', {
className: 'cwd-form-field',
children: [
this.createElement('input', {
className: 'cwd-form-input',
attributes: {
type,
placeholder,
value: value || '',
disabled: this.props.submitting,
onInput: (e) => this.handleUserInfoChange(field, e.target.value)
}
})
]
});
}
}

View File

@@ -366,6 +366,8 @@ export class CWDComments {
replyContent: state.replyContent,
replyError: state.replyError,
submitting: state.submitting,
currentUser: state.form,
onUpdateUserInfo: (field, value) => this.store.updateFormField(field, value),
adminEmail: this.config.adminEmail,
adminBadge: this.config.adminBadge,
enableCommentLike: this.config.enableCommentLike !== false,
@@ -492,6 +494,7 @@ export class CWDComments {
replyContent: state.replyContent,
replyError: state.replyError,
submitting: state.submitting,
currentUser: state.form,
});
}
}