mirror of
https://github.com/renbaoshuo/S2OJ.git
synced 2024-11-25 03:08:42 +00:00
feat(blog): markdown comment support
All checks were successful
continuous-integration/drone/push Build is passing
All checks were successful
continuous-integration/drone/push Build is passing
This commit is contained in:
parent
4582a6b947
commit
c98a893fb6
@ -9,20 +9,46 @@ UOJBlog::cur()->belongsToUserBlog() || UOJResponse::page404();
|
||||
UOJBlog::cur()->userCanView(Auth::user()) || UOJResponse::page403();
|
||||
|
||||
$blog = UOJBlog::info();
|
||||
$purifier = HTML::purifier();
|
||||
$parsedown = HTML::parsedown([
|
||||
'username_with_color' => true,
|
||||
]);
|
||||
|
||||
function getCommentContentToDisplay($comment) {
|
||||
if (!$comment['is_hidden']) {
|
||||
return $comment['content'];
|
||||
} else if (UOJUserBlog::userHasManagePermission(Auth::user())) {
|
||||
return '<span class="text-muted mb-3">【' . HTML::escape($comment['reason_to_hide']) . '】</span>' . $comment['content'];
|
||||
} else {
|
||||
return '<span class="text-muted">【' . HTML::escape($comment['reason_to_hide']) . '】</span>';
|
||||
global $purifier, $parsedown;
|
||||
|
||||
$rendered = $purifier->purify($parsedown->text($comment['content']));
|
||||
|
||||
if ($comment['is_hidden']) {
|
||||
$esc_hide_reason = $comment['reason_to_hide'];
|
||||
$res = <<<EOD
|
||||
<div class="alert alert-warning d-flex align-items-center my-0" role="alert">
|
||||
<div class="flex-shrink-0 me-3">
|
||||
<i class="fs-4 bi bi-exclamation-triangle-fill"></i>
|
||||
</div>
|
||||
<div>
|
||||
<div class="fw-bold mb-2">该评论被隐藏</div>
|
||||
<div class="small">{$esc_hide_reason}</div>
|
||||
</div>
|
||||
</div>
|
||||
EOD;
|
||||
|
||||
if (UOJUserBlog::userHasManagePermission(Auth::user())) {
|
||||
$res .= <<<EOD
|
||||
<div class="mt-2">{$rendered}</div>
|
||||
EOD;
|
||||
}
|
||||
|
||||
return $res;
|
||||
}
|
||||
|
||||
return $rendered;
|
||||
}
|
||||
|
||||
$comment_form = new UOJForm('comment');
|
||||
$comment_form->addTextArea('comment', [
|
||||
'label' => '内容',
|
||||
'help' => '评论支持 Markdown 语法。可以用 <code>@mike</code> 来提到 <code>mike</code> 这个用户,<code>mike</code> 会被高亮显示。如果你真的想打 <code>@</code> 这个字符,请用 <code>@@</code>。',
|
||||
'validator_php' => function ($comment) {
|
||||
if (!Auth::check()) {
|
||||
return '请先登录';
|
||||
@ -257,22 +283,24 @@ $comments_pag = new Paginator([
|
||||
$asrc = HTML::avatar_addr($poster, 80);
|
||||
|
||||
$replies = DB::selectAll([
|
||||
"select id, poster, content, post_time, is_hidden, reason_to_hide from blogs_comments",
|
||||
"select id, poster, content, post_time, is_hidden, reason_to_hide, zan from blogs_comments",
|
||||
"where", ["reply_id" => $comment['id']],
|
||||
"order by id"
|
||||
]);
|
||||
foreach ($replies as $idx => $reply) {
|
||||
$reply_user = UOJUser::query($reply['poster']);
|
||||
$replies[$idx]['poster_avatar'] = HTML::avatar_addr($reply_user, 80);
|
||||
$replies[$idx]['poster_realname'] = $reply_user['realname'];
|
||||
$replies[$idx]['poster_username_color'] = UOJUser::getUserColor($reply_user);
|
||||
$replies[$idx]['content'] = getCommentContentToDisplay($reply);
|
||||
$replies[$idx]['click_zan_block'] = ClickZans::getBlock('BC', $reply['id'], $reply['zan']);
|
||||
}
|
||||
$replies_json = json_encode($replies);
|
||||
?>
|
||||
<div id="comment-<?= $comment['id'] ?>" class="list-group-item">
|
||||
<div class="d-flex">
|
||||
<div class="mr-3 flex-shrink-0">
|
||||
<a href="<?= HTML::url('/user/' . $poster['username']) ?>" class="d-none d-sm-block text-decoration-none">
|
||||
<div class="d-none d-sm-block mr-3 flex-shrink-0">
|
||||
<a href="<?= HTML::url('/user/' . $poster['username']) ?>">
|
||||
<img class="rounded uoj-user-avatar" src="<?= $asrc ?>" alt="Avatar of <?= $poster['username'] ?>" width="64" height="64" />
|
||||
</a>
|
||||
</div>
|
||||
@ -285,7 +313,7 @@ $comments_pag = new Paginator([
|
||||
<?= ClickZans::getBlock('BC', $comment['id'], $comment['zan']) ?>
|
||||
</div>
|
||||
</div>
|
||||
<div class="comment-content my-2" id="comment-content-<?= $comment['id'] ?>"><?= getCommentContentToDisplay($comment) ?></div>
|
||||
<div class="comment-content markdown-body my-2" id="comment-content-<?= $comment['id'] ?>"><?= getCommentContentToDisplay($comment) ?></div>
|
||||
<ul class="list-inline mb-0 text-end">
|
||||
<li class="list-inline-item small text-muted">
|
||||
<?= $comment['post_time'] ?>
|
||||
@ -304,11 +332,11 @@ $comments_pag = new Paginator([
|
||||
</li>
|
||||
</ul>
|
||||
<?php if ($replies) : ?>
|
||||
<div id="replies-<?= $comment['id'] ?>" class="rounded bg-secondary bg-opacity-10 border"></div>
|
||||
<div id="replies-<?= $comment['id'] ?>" class="rounded bg-secondary-subtle mt-2 border"></div>
|
||||
<script>
|
||||
showCommentReplies('<?= $comment['id'] ?>', <?= $replies_json ?>);
|
||||
</script>
|
||||
<?php endif ?>
|
||||
<script type="text/javascript">
|
||||
showCommentReplies('<?= $comment['id'] ?>', <?= $replies_json ?>);
|
||||
</script>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -318,7 +346,6 @@ $comments_pag = new Paginator([
|
||||
<?= $comments_pag->pagination() ?>
|
||||
|
||||
<h3 class="mt-4">发表评论</h3>
|
||||
<p>可以用 @mike 来提到 mike 这个用户,mike 会被高亮显示。如果你真的想打“@”这个字符,请用“@@”。</p>
|
||||
<?php $comment_form->printHTML() ?>
|
||||
|
||||
<div id="div-form-reply" style="display:none">
|
||||
|
@ -62,7 +62,7 @@ class UOJMarkdown extends ParsedownMath {
|
||||
$mentioned_user = UOJUser::query($matches[1]);
|
||||
|
||||
if ($mentioned_user) {
|
||||
$color = '#0d6efd';
|
||||
$color = 'blue';
|
||||
|
||||
if ($this->options['username_with_color']) {
|
||||
$color = UOJUser::getUserColor($mentioned_user);
|
||||
@ -74,7 +74,7 @@ class UOJMarkdown extends ParsedownMath {
|
||||
'name' => 'span',
|
||||
'text' => '@' . $mentioned_user['username'],
|
||||
'attributes' => [
|
||||
'class' => 'uoj-username',
|
||||
'class' => "uoj-username uoj-username-{$color}",
|
||||
'data-realname' => UOJUser::getRealname($mentioned_user),
|
||||
'data-color' => $color,
|
||||
],
|
||||
|
@ -395,9 +395,6 @@ form.form-horizontal {
|
||||
/* Comments */
|
||||
|
||||
.comment-content {
|
||||
white-space: pre-wrap;
|
||||
word-break: break-all;
|
||||
|
||||
min-height: 50px;
|
||||
}
|
||||
|
||||
|
@ -176,6 +176,10 @@ $.fn.uoj_honor = function() {
|
||||
});
|
||||
}
|
||||
|
||||
function getClickZanBlock(type, id, cnt, val) {
|
||||
return '<div class="uoj-click-zan-block" data-id="' + id + '" data-type="' + type + '" data-val="' + val + '" data-cnt="' + cnt + '"></div>';
|
||||
}
|
||||
|
||||
function showErrorHelp(name, err) {
|
||||
if (err) {
|
||||
$('#div-' + name).addClass('has-validation has-error');
|
||||
@ -291,6 +295,11 @@ $.fn.click_zan_block = function() {
|
||||
var type = $(this).data('type');
|
||||
var val = parseInt($(this).data('val'));
|
||||
var cnt = parseInt($(this).data('cnt'));
|
||||
var rendered = $(this).attr('data-click-zan-rendered');
|
||||
|
||||
if (rendered == 'true') {
|
||||
return;
|
||||
}
|
||||
if (isNaN(cnt)) {
|
||||
return;
|
||||
}
|
||||
@ -332,6 +341,7 @@ $.fn.click_zan_block = function() {
|
||||
if (cnt < 0) display_cnt = '-?';
|
||||
|
||||
$(this)
|
||||
.attr('data-click-zan-rendered', 'true')
|
||||
.append(up_node)
|
||||
.append(down_node)
|
||||
.append($('<span class="uoj-click-zan-cnt" title="' + cnt + '">[<strong>' + display_cnt + '</strong>]</span>'));
|
||||
@ -1707,25 +1717,41 @@ function showCommentReplies(id, replies) {
|
||||
function(reply) {
|
||||
return $('<tr id="' + 'comment-' + reply.id + '" />').append(
|
||||
$('<td />').append(
|
||||
$('<div class="comment-content">' + getUserLink(reply.poster, reply.poster_realname, reply.poster_username_color) + ':' + reply.content + '</div>')
|
||||
).append(
|
||||
$('<ul class="text-end mb-0 list-inline" />').append(
|
||||
'<li class="list-inline-item small text-muted">' + reply.post_time + '</li>'
|
||||
$('<div class="d-flex" />').append(
|
||||
$('<div class="d-none d-sm-block mr-3 flex-shrink-0" />').append(
|
||||
$('<a />').append(
|
||||
$('<img class="rounded uoj-user-avatar" width="64" height="64" />').attr('src', reply.poster_avatar)
|
||||
).attr('href', uojHome + '/user/' + reply.poster)
|
||||
)
|
||||
).append(
|
||||
user_can_hide_comment
|
||||
? $('<li class="list-inline-item" />').append(
|
||||
$('<a href="#" class="text-warning-emphasis text-decoration-none p-0" />').data('comment-id', reply.id).text('隐藏').click(function(event) {
|
||||
event.preventDefault();
|
||||
toggleModalHideComment(reply.id, reply.content);
|
||||
})
|
||||
$('<div id="comment-body-' + reply.id + '" class="flex-grow-1 ms-3" />').append(
|
||||
$('<div class="row justify-content-between flex-wrap g-0" />').append(
|
||||
$('<div class="col-auto" />').append(getUserLink(reply.poster, reply.poster_realname, reply.poster_username_color))
|
||||
).append(
|
||||
$('<div class="col-auto" />').append(reply.click_zan_block)
|
||||
)
|
||||
).append(
|
||||
$('<div class="comment-content markdown-body my-2" />').attr('id', 'comment-content-' + reply.id).html(reply.content)
|
||||
).append(
|
||||
$('<ul class="text-end mb-0 list-inline" />').append(
|
||||
'<li class="list-inline-item small text-muted">' + reply.post_time + '</li>'
|
||||
).append(
|
||||
user_can_hide_comment
|
||||
? $('<li class="list-inline-item" />').append(
|
||||
$('<a href="#" class="text-warning-emphasis text-decoration-none p-0" />').data('comment-id', reply.id).text('隐藏').click(function(event) {
|
||||
event.preventDefault();
|
||||
toggleModalHideComment(reply.id, reply.content);
|
||||
})
|
||||
)
|
||||
: ''
|
||||
).append(
|
||||
$('<li class="list-inline-item" />').append(
|
||||
$('<a href="#">回复</a>').click(function (e) {
|
||||
e.preventDefault();
|
||||
toggleFormReply(reply.id, '回复 @' + reply.poster + ':');
|
||||
})
|
||||
)
|
||||
)
|
||||
: ''
|
||||
).append(
|
||||
$('<li class="list-inline-item" />').append(
|
||||
$('<a href="#">回复</a>').click(function (e) {
|
||||
e.preventDefault();
|
||||
toggleFormReply(reply.id, '回复 @' + reply.poster + ':');
|
||||
})
|
||||
)
|
||||
)
|
||||
)
|
||||
|
Loading…
Reference in New Issue
Block a user