Skip to content

Commit 7589c23

Browse files
committed
fix(comment): 修复移动端评论回复功能
- 修改_replyUseName函数优先选择可见容器避免隐藏节点问题 - 添加_clearReplyUseName函数统一清理回复指示状态 - 实现cancelReply函数支持取消回复操作 - 更新reply函数增加安全的用户名转义处理 - 优化SCSS样式实现回复指示器的显示和截断效果 - 添加文档说明移动端多回复节点的处理规则
1 parent 34df956 commit 7589c23

File tree

5 files changed

+85
-9
lines changed

5 files changed

+85
-9
lines changed

AGENTS.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040

4141
## 关键链路(持续维护)
4242
- 前端全局主题变量入口:`src/main/resources/scss/_variables.scss``$theme-primary` 会影响 `module`/首页卡片/聊天室等主区背景,深色会导致整站大面积染色;顶栏建议在 `base.scss`/`mobile-base.scss``.nav` 单独设色。
43+
- 移动端文章页(`skins/mobile/article.ftl`)存在多个 `#replyUseName`(含隐藏占位 `.fn-none`);`m-article.js` 处理回复目标时需优先选中非 `.fn-none` 节点,避免“回复对象已记录但指示未显示”。
4344
- 首页右栏专栏列表(classic)需使用 `module-list long-column-module-list`(见 `skins/classic/index.ftl` 的“最新专栏/热门专栏/最近阅读”);否则会命中 `.module-list .title` 默认 `margin-left: 30px` 产生左侧空白。
4445
- 勋章管理页:`/admin/medal`
4546
- 后端:`src/main/java/org/b3log/symphony/processor/MedalProcessor.java``showAdminMedal``register`

src/main/resources/css/mobile-base.css

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/main/resources/js/m-article.js

Lines changed: 50 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -317,12 +317,14 @@ var Comment = {
317317
},
318318
})
319319

320-
$('#replyUseName').
320+
Comment._getReplyUseName().
321+
addClass('reply-use-name--active').
321322
html('<a href="javascript:void(0)" onclick="Comment._bgFade($(\'#' +
322323
id +
323324
'\'))" class="ft-a-title"><svg><use xlink:href="#edit"></use></svg> ' +
324325
Label.commonUpdateCommentPermissionLabel + '</a>').
325-
data('commentId', id)
326+
data('commentId', id).
327+
removeData('commentOriginalCommentId')
326328
},
327329
/**
328330
* 背景渐变
@@ -379,6 +381,34 @@ var Comment = {
379381
}
380382
})
381383
},
384+
/**
385+
* 获取当前可用的“回复指示”容器
386+
* 移动端模板中存在隐藏占位节点,优先选择可见容器
387+
* @returns {jQuery}
388+
*/
389+
_getReplyUseName: function () {
390+
var $replyUseName = $('#replyUseName').not('.fn-none').first()
391+
if ($replyUseName.length === 0) {
392+
$replyUseName = $('#replyUseName').first()
393+
}
394+
return $replyUseName
395+
},
396+
/**
397+
* 清理回复/编辑目标指示
398+
*/
399+
_clearReplyUseName: function () {
400+
Comment._getReplyUseName().
401+
removeClass('reply-use-name--active').
402+
html('').
403+
removeData('commentOriginalCommentId').
404+
removeData('commentId')
405+
},
406+
/**
407+
* 取消回复(恢复普通评论)
408+
*/
409+
cancelReply: function () {
410+
Comment._clearReplyUseName()
411+
},
382412
/**
383413
* 评论初始化
384414
* @returns {Boolean}
@@ -639,6 +669,7 @@ var Comment = {
639669
* @param {String} csrfToken CSRF 令牌
640670
*/
641671
add: function (id, csrfToken) {
672+
var $replyUseName = Comment._getReplyUseName()
642673

643674
var requestJSONObject = {
644675
articleId: id,
@@ -648,14 +679,14 @@ var Comment = {
648679
userCommentViewMode: Label.userCommentViewMode,
649680
}
650681

651-
if ($('#replyUseName').data('commentOriginalCommentId')) {
652-
requestJSONObject.commentOriginalCommentId = $('#replyUseName').
682+
if ($replyUseName.data('commentOriginalCommentId')) {
683+
requestJSONObject.commentOriginalCommentId = $replyUseName.
653684
data('commentOriginalCommentId')
654685
}
655686

656687
var url = Label.servePath + '/comment',
657688
type = 'POST',
658-
commentId = $('#replyUseName').data('commentId')
689+
commentId = $replyUseName.data('commentId')
659690
if (commentId) {
660691
url = Label.servePath + '/comment/' + commentId
661692
type = 'PUT'
@@ -684,7 +715,7 @@ var Comment = {
684715
Comment.editor.setValue('')
685716

686717
// clear reply comment
687-
$('#replyUseName').text('').removeData()
718+
Comment._clearReplyUseName()
688719

689720
// clear local storage
690721
if (window.localStorage) {
@@ -724,7 +755,19 @@ var Comment = {
724755
* @param {String} userName 用户名称
725756
*/
726757
reply: function (userName, id) {
727-
$('#replyUseName').data('commentOriginalCommentId', id)
758+
var safeUserName = String(userName).
759+
replace(/&/g, '&amp;').
760+
replace(/</g, '&lt;').
761+
replace(/>/g, '&gt;'),
762+
$replyUseName = Comment._getReplyUseName()
763+
764+
$replyUseName.
765+
addClass('reply-use-name--active').
766+
html('<a rel="nofollow" href="javascript:void(0)" class="ft-a-title reply-use-name__target fn-pointer" onclick="Comment.cancelReply()"><svg><use xlink:href="#reply-to"></use></svg> ' +
767+
safeUserName +
768+
'</a><span class="reply-use-name__cancel fn-pointer ft-fade" onclick="Comment.cancelReply()">×</span>').
769+
data('commentOriginalCommentId', id).
770+
removeData('commentId')
728771
Comment.editor.focus()
729772
},
730773
}

src/main/resources/js/m-article.min.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/main/resources/scss/mobile-base.scss

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1302,6 +1302,38 @@ label.cmt-anonymous {
13021302
line-height: 18px;
13031303
height: 18px;
13041304
margin: 5px 0;
1305+
overflow: hidden;
1306+
white-space: nowrap;
1307+
text-overflow: ellipsis;
1308+
1309+
&.reply-use-name--active {
1310+
visibility: visible;
1311+
}
1312+
1313+
.reply-use-name__target {
1314+
display: inline-flex;
1315+
align-items: center;
1316+
max-width: calc(100% - 26px);
1317+
overflow: hidden;
1318+
text-overflow: ellipsis;
1319+
white-space: nowrap;
1320+
1321+
svg {
1322+
margin-right: 2px;
1323+
}
1324+
}
1325+
1326+
.reply-use-name__cancel {
1327+
display: inline-flex;
1328+
align-items: center;
1329+
justify-content: center;
1330+
width: 16px;
1331+
height: 16px;
1332+
margin-left: 6px;
1333+
border-radius: 50%;
1334+
border: 1px solid #ddd;
1335+
line-height: 14px;
1336+
}
13051337
}
13061338

13071339
#articleToC {

0 commit comments

Comments
 (0)