267 lines
14 KiB
Twig
267 lines
14 KiB
Twig
{% macro comments_input(category, user, perms, reply_to) %}
|
|
{% set reply_mode = reply_to is not null %}
|
|
|
|
{% from '_layout/input.twig' import input_hidden, input_csrf, input_checkbox %}
|
|
|
|
<form class="comment comment--input{% if reply_mode %} comment--reply{% endif %}"
|
|
method="post" action="/comments.php?m=create"
|
|
id="comment-{{ reply_mode ? 'reply-' ~ reply_to.comment_id : 'create-' ~ category.category_id }}">
|
|
{{ input_hidden('comment[category]', category.category_id) }}
|
|
{{ input_csrf('comments') }}
|
|
|
|
{% if reply_mode %}
|
|
{{ input_hidden('comment[reply]', reply_to.comment_id) }}
|
|
{% endif %}
|
|
|
|
<div class="comment__container">
|
|
<div class="avatar comment__avatar"
|
|
style="background-image:url('/profile.php?m=avatar&u={{ user.user_id }}')">
|
|
</div>
|
|
<div class="comment__content">
|
|
<div class="comment__info">
|
|
<div class="comment__user"
|
|
style="{{ user.user_colour|html_colour }}">{{ user.username }}</div>
|
|
</div>
|
|
<textarea
|
|
class="comment__text input__textarea comment__text--input"
|
|
name="comment[text]" placeholder="Share your extensive insights..."></textarea>
|
|
<div class="comment__actions">
|
|
{% if not reply_mode %}
|
|
{% if perms.can_pin %}
|
|
{{ input_checkbox('comment[pin]', 'Pin this comment', false, 'comment__action') }}
|
|
{% endif %}
|
|
{% if perms.can_lock %}
|
|
{{ input_checkbox('comment[lock]', 'Toggle locked status', false, 'comment__action') }}
|
|
{% endif %}
|
|
{% endif %}
|
|
<button class="input__button comment__action comment__action--button comment__action--post">
|
|
{{ reply_mode ? 'Reply' : 'Post' }}
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</form>
|
|
{% endmacro %}
|
|
|
|
{% macro comments_entry(comment, indent, category, user, perms) %}
|
|
{% from '_layout/input.twig' import input_checkbox_raw %}
|
|
|
|
{% if comment.comment_deleted is null or comment.comment_replies|length > 0 %}
|
|
<div class="comment" id="comment-{{ comment.comment_id }}">
|
|
<div class="comment__container">
|
|
<a class="avatar comment__avatar"
|
|
href="/profile.php?u={{ comment.user_id }}"
|
|
style="background-image:url('/profile.php?m=avatar&u={{ comment.user_id }}')">
|
|
</a>
|
|
<div class="comment__content">
|
|
<div class="comment__info">
|
|
<a class="comment__user comment__user--link"
|
|
href="/profile.php?u={{ comment.user_id }}"
|
|
style="{{ comment.user_colour|html_colour }}">{{ comment.username }}</a>
|
|
<a class="comment__link" href="#comment-{{ comment.comment_id }}">
|
|
<time class="comment__date"
|
|
title="{{ comment.comment_created|date('r') }}"
|
|
datetime="{{ comment.comment_created|date('c') }}">
|
|
{{ comment.comment_created|time_diff }}
|
|
</time>
|
|
</a>
|
|
{% if comment.comment_pinned is not null %}
|
|
<span class="comment__pin">{% spaceless %}
|
|
Pinned
|
|
{% if comment.comment_pinned != comment.comment_created %}
|
|
<time title="{{ comment.comment_pinned|date('r') }}"
|
|
datetime="{{ comment.comment_pinned|date('c') }}">
|
|
{{ comment.comment_pinned|time_diff }}
|
|
</time>
|
|
{% endif %}
|
|
{% endspaceless %}</span>
|
|
{% endif %}
|
|
</div>
|
|
<div class="comment__text{{ comment.comment_deleted is null ? '' : ' comment__text--deleted' }}">
|
|
{{ comment.comment_deleted is null ? (comment.comment_html is defined ? comment.comment_html|raw : comment.comment_text|nl2br) : 'deleted' }}
|
|
</div>
|
|
{% if comment.comment_deleted is null and user is not null %}
|
|
<div class="comment__actions">
|
|
{% if perms.can_vote %}
|
|
<a class="comment__action comment__action--link comment__action--like{% if comment.comment_user_vote == 'Like' %} comment__action--voted{% endif %}"
|
|
href="/comments.php?m=vote&c={{ comment.comment_id }}&v={{ comment.comment_user_vote == 'Like' ? '0' : '1' }}&csrf={{ csrf_token('comments') }}">
|
|
Like
|
|
{% if comment.comment_likes > 0 %}
|
|
({{ comment.comment_likes|number_format }})
|
|
{% endif %}
|
|
</a>
|
|
<a class="comment__action comment__action--link comment__action--dislike{% if comment.comment_user_vote == 'Dislike' %} comment__action--voted{% endif %}"
|
|
href="/comments.php?m=vote&c={{ comment.comment_id }}&v={{ comment.comment_user_vote == 'Dislike' ? '0' : '-1' }}&csrf={{ csrf_token('comments') }}">
|
|
Dislike
|
|
{% if comment.comment_dislikes > 0 %}
|
|
({{ comment.comment_dislikes|number_format }})
|
|
{% endif %}
|
|
</a>
|
|
{% endif %}
|
|
{% if perms.can_comment %}
|
|
<label class="comment__action comment__action--link" for="comment-reply-toggle-{{ comment.comment_id }}">Reply</label>
|
|
{% endif %}
|
|
{% if perms.can_delete_any or (comment.user_id == user.user_id and perms.can_delete) %}
|
|
<a class="comment__action comment__action--link comment__action--hide comment__action--delete"
|
|
href="/comments.php?m=delete&c={{ comment.comment_id }}&csrf={{ csrf_token('comments') }}">Delete</a>
|
|
{% endif %}
|
|
{# if user is not null %}
|
|
<a class="comment__action comment__action--link comment__action--hide" href="#">Report</a>
|
|
{% endif #}
|
|
</div>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
|
|
<div class="comment__replies comment__replies--indent-{{ indent }}" id="comment-{{ comment.comment_id }}-replies">
|
|
{% from _self import comments_entry, comments_input %}
|
|
{% if user|default(null) is not null and category|default(null) is not null and perms|default(null) is not null and perms.can_comment %}
|
|
{{ input_checkbox_raw('', false, 'comment__reply-toggle', '', false, {'id':'comment-reply-toggle-' ~ comment.comment_id}) }}
|
|
{{ comments_input(category, user, perms, comment) }}
|
|
{% endif %}
|
|
{% if comment.comment_replies is defined and comment.comment_replies|length > 0 %}
|
|
{% for reply in comment.comment_replies %}
|
|
{{ comments_entry(reply, indent + 1, category, user, perms) }}
|
|
{% endfor %}
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
{% endif %}
|
|
{% endmacro %}
|
|
|
|
{% macro comments_section(comments, category, user, perms) %}
|
|
<div class="comments">
|
|
<div class="comments__input">
|
|
{% if user|default(null) is null %}
|
|
<div class="comments__notice">
|
|
Please <a href="/auth.php?m=login" class="comments__notice__link">login</a> to comment.
|
|
</div>
|
|
{% elseif category|default(null) is null or perms|default(null) is null %}
|
|
<div class="comments__notice">
|
|
Posting new comments here is disabled.
|
|
</div>
|
|
{% elseif not perms.can_lock and category.category_locked is not null %}
|
|
<div class="comments__notice">
|
|
This comment section was locked, <time datetime="{{ category.category_locked|date('c') }}" title="{{ category.category_locked|date('r') }}">{{ category.category_locked|time_diff }}</time>.
|
|
</div>
|
|
{% elseif not perms.can_comment %}
|
|
<div class="comments__notice">
|
|
You are not allowed to post comments.
|
|
</div>
|
|
{% else %}
|
|
{% from _self import comments_input %}
|
|
{{ comments_input(category, user, perms) }}
|
|
{% endif %}
|
|
</div>
|
|
|
|
{% if perms.can_lock and category.category_locked is not null %}
|
|
<div class="comments__notice comments__notice--staff">
|
|
This comment section was locked, <time datetime="{{ category.category_locked|date('c') }}" title="{{ category.category_locked|date('r') }}">{{ category.category_locked|time_diff }}</time>.
|
|
</div>
|
|
{% endif %}
|
|
|
|
<noscript>
|
|
<div class="comments__javascript">
|
|
While the comments work fine without Javascript, it is recommended you enable it as it has a lower bandwidth overhead.
|
|
</div>
|
|
</noscript>
|
|
|
|
<div class="comments__listing">
|
|
{% if comments|length > 0 %}
|
|
{% from _self import comments_entry %}
|
|
{% for comment in comments %}
|
|
{{ comments_entry(comment, 1, category, user, perms) }}
|
|
{% endfor %}
|
|
{% else %}
|
|
<div class="comments__none" id="_no_comments_notice_{{ category.category_id }}">
|
|
There are no comments yet.
|
|
</div>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
|
|
<script>
|
|
window.addEventListener('load', function () {
|
|
var likeButtons = document.getElementsByClassName('comment__action--like'),
|
|
dislikeButtons = document.getElementsByClassName('comment__action--dislike');
|
|
|
|
for (var i = 0; i < likeButtons.length; i++) // there's gonna be an equal amount of like and dislike buttons
|
|
{
|
|
likeButtons[i].href = 'javascript:void(0);';
|
|
likeButtons[i].onclick = commentVote;
|
|
dislikeButtons[i].href = 'javascript:void(0);';
|
|
dislikeButtons[i].onclick = commentVote;
|
|
}
|
|
});
|
|
|
|
var commentVoteLock = false,
|
|
commentLikeClass = 'comment__action--like',
|
|
commentDislikeClass = 'comment__action--dislike',
|
|
commentVotedClass = 'comment__action--voted',
|
|
commentLikeText = 'Like',
|
|
commentDislikeText = 'Dislike',
|
|
commentVoteCountSuffix = ' ({0})';
|
|
|
|
// DEBUG THIS IF YOU MAKE MAJOR DOM CHANGES TO COMMENTS
|
|
function commentVote(ev)
|
|
{
|
|
var elem = ev.target,
|
|
id = elem.parentNode.parentNode.parentNode.parentNode.id.substr(8); // STACK UP
|
|
|
|
// the moment we find the id we engage vote lock
|
|
if (id < 1 || commentVoteLock)
|
|
return;
|
|
commentVoteLock = true;
|
|
elem.textContent = '.';
|
|
|
|
var isLike = elem.classList.contains(commentLikeClass),
|
|
isDislike = elem.classList.contains(commentDislikeClass),
|
|
isIndifferent = elem.classList.contains(commentVotedClass),
|
|
vote = isIndifferent ? 0 : (isLike ? 1 : -1);
|
|
|
|
elem.textContent += '.';
|
|
|
|
// find friendo (the other vote button), this'll fuck up if the parent element is fucked with
|
|
for (var i = 0; i < elem.parentNode.childNodes.length; i++) {
|
|
var current = elem.parentNode.childNodes[i];
|
|
if (current.nodeName.toLowerCase() === 'a' && current !== elem) {
|
|
var friend = current;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (typeof friend !== 'object') {
|
|
console.error('something happened');
|
|
return;
|
|
}
|
|
|
|
friend.classList.remove(commentVotedClass);
|
|
|
|
friend.textContent = '';
|
|
|
|
elem.textContent += '.';
|
|
|
|
commentVoteV2(
|
|
id, vote,
|
|
(vInfo, uVote) => {
|
|
if (vote)
|
|
elem.classList.add(commentVotedClass);
|
|
else
|
|
elem.classList.remove(commentVotedClass);
|
|
|
|
var likes = vInfo.likes || 0,
|
|
dislikes = vInfo.dislikes || 0;
|
|
|
|
if (isLike) { // somewhat implicitly defined, like will always come before dislike
|
|
elem.textContent = commentLikeText + (likes > 0 ? commentVoteCountSuffix.replace('{0}', likes.toLocaleString()) : '');
|
|
friend.textContent = commentDislikeText + (dislikes > 0 ? commentVoteCountSuffix.replace('{0}', dislikes.toLocaleString()) : '');
|
|
} else {
|
|
elem.textContent = commentDislikeText + (dislikes > 0 ? commentVoteCountSuffix.replace('{0}', dislikes.toLocaleString()) : '');
|
|
friend.textContent = commentLikeText + (likes > 0 ? commentVoteCountSuffix.replace('{0}', likes.toLocaleString()) : '');
|
|
}
|
|
},
|
|
alert
|
|
);
|
|
}
|
|
</script>
|
|
{% endmacro %}
|