From d7672cf81be72e386ec5b671e1378430f1934267 Mon Sep 17 00:00:00 2001 From: Tuan-Dung Bui Date: Tue, 11 Apr 2023 23:55:11 +0700 Subject: [PATCH] change comment style --- dmoj/urls.py | 3 + judge/comments.py | 18 ++-- judge/models/comment.py | 1 + judge/views/comment.py | 74 +++++++++++++++- resources/comments.scss | 12 +++ templates/actionbar/list.html | 4 +- templates/comments/content-list.html | 121 +++++++++++++++++++++++++++ templates/comments/list.html | 114 +------------------------ templates/comments/media-js.html | 49 +++++++++++ 9 files changed, 272 insertions(+), 124 deletions(-) create mode 100644 templates/comments/content-list.html diff --git a/dmoj/urls.py b/dmoj/urls.py index 4900d7c..913e63f 100644 --- a/dmoj/urls.py +++ b/dmoj/urls.py @@ -1,5 +1,6 @@ import chat_box.views as chat +from django.urls import include, path from django.conf import settings from django.conf.urls import include, url from django.contrib import admin @@ -468,6 +469,8 @@ urlpatterns = [ url(r"^comments/upvote/$", comment.upvote_comment, name="comment_upvote"), url(r"^comments/downvote/$", comment.downvote_comment, name="comment_downvote"), url(r"^comments/hide/$", comment.comment_hide, name="comment_hide"), + url(r"^comments/reply/$", comment.get_reply, name="comment_reply"), + url(r"^comments/showmore/$", comment.get_showmore, name="comment_show_more"), url( r"^comments/(?P\d+)/", include( diff --git a/judge/comments.py b/judge/comments.py index d99f11e..f13a560 100644 --- a/judge/comments.py +++ b/judge/comments.py @@ -162,14 +162,14 @@ class CommentedDetailView(TemplateResponseMixin, SingleObjectMixin, View): def get_context_data(self, **kwargs): context = super(CommentedDetailView, self).get_context_data(**kwargs) queryset = self.object.comments + context["replies"] = len(queryset.filter(parent=None)) + queryset = ( + queryset.filter(parent=None)[:10].select_related("author__user") + .defer("author__about") + .annotate(revisions=Count("versions")).annotate(count_replies=Count("replies")) + ) context["has_comments"] = queryset.exists() context["comment_lock"] = self.is_comment_locked() - queryset = ( - queryset.select_related("author__user") - .defer("author__about") - .annotate(revisions=Count("versions")) - ) - if self.request.user.is_authenticated: profile = self.request.profile queryset = queryset.annotate( @@ -184,6 +184,10 @@ class CommentedDetailView(TemplateResponseMixin, SingleObjectMixin, View): ).exists() ) context["comment_list"] = queryset - context["comment_count"] = len(queryset) + # context["comment_count"] = len(queryset) context["vote_hide_threshold"] = settings.DMOJ_COMMENT_VOTE_HIDE_THRESHOLD + context["comment_root_id"] = 0 + context["offset"] = 10 + context["limit"] = 10 + return context diff --git a/judge/models/comment.py b/judge/models/comment.py index fc9af4c..a9cdd15 100644 --- a/judge/models/comment.py +++ b/judge/models/comment.py @@ -56,6 +56,7 @@ class Comment(MPTTModel): related_name="replies", on_delete=CASCADE, ) + versions = VersionRelation() class Meta: diff --git a/judge/views/comment.py b/judge/views/comment.py index 962d9f1..ec30647 100644 --- a/judge/views/comment.py +++ b/judge/views/comment.py @@ -1,8 +1,13 @@ +from django.conf import settings + from django.contrib.auth.decorators import login_required from django.contrib.auth.mixins import LoginRequiredMixin, PermissionRequiredMixin +from django.contrib.auth.context_processors import PermWrapper from django.core.exceptions import PermissionDenied from django.db import IntegrityError, transaction -from django.db.models import F +from django.db.models import Q, F, Count, FilteredRelation +from django.db.models.functions import Coalesce +from django.db.models.expressions import F, Value from django.forms.models import ModelForm from django.http import ( Http404, @@ -15,11 +20,12 @@ from django.utils.translation import gettext as _ from django.views.decorators.http import require_POST from django.views.generic import DetailView, UpdateView from django.urls import reverse_lazy +from django.template import loader from reversion import revisions from reversion.models import Version from judge.dblock import LockModel -from judge.models import Comment, CommentVote, Notification +from judge.models import Comment, CommentVote, Notification, BlogPost from judge.utils.views import TitleMixin from judge.widgets import MathJaxPagedownWidget, HeavyPreviewPageDownWidget from judge.comments import add_mention_notifications, del_mention_notifications @@ -34,6 +40,11 @@ __all__ = [ @login_required + +# def get_more_reply(request, id): +# queryset = Comment.get_pk(id) + + def vote_comment(request, delta): if abs(delta) != 1: return HttpResponseBadRequest( @@ -97,10 +108,67 @@ def vote_comment(request, delta): def upvote_comment(request): return vote_comment(request, 1) - def downvote_comment(request): return vote_comment(request, -1) +def get_comment(request, limit=10): + try: + comment_id = int(request.GET["id"]) + page_id = int(request.GET["page"]) + except ValueError: + return HttpResponseBadRequest() + else: + if comment_id and not Comment.objects.filter(id=comment_id).exists(): + raise Http404() + if not BlogPost.objects.filter(id=page_id).exists(): + raise Http404() + offset = 0 + if "offset" in request.GET: + offset = int(request.GET["offset"]) + comment_root_id = 0 + if (comment_id): + comment_obj = Comment.objects.get(pk=comment_id) + comment_root_id = comment_obj.id + else: + comment_obj = None + page_obj = BlogPost.objects.get(pk=page_id) + queryset = page_obj.comments + replies = len(queryset.filter(parent=comment_obj)) + queryset = ( + queryset.filter(parent=comment_obj)[offset:offset+limit].select_related("author__user") + .defer("author__about") + .annotate(revisions=Count("versions")).annotate(count_replies=Count("replies")) + ) + if request.user.is_authenticated: + profile = request.profile + queryset = queryset.annotate( + my_vote=FilteredRelation( + "votes", condition=Q(votes__voter_id=profile.id) + ), + ).annotate(vote_score=Coalesce(F("my_vote__score"), Value(0))) + + comment_html = loader.render_to_string( + "comments/content-list.html", + { + "request": request, + "comment_root_id": comment_root_id, + "comment_list": queryset, + "vote_hide_threshold" : settings.DMOJ_COMMENT_VOTE_HIDE_THRESHOLD, + "perms": PermWrapper(request.user), + "object": page_obj, + "offset": offset + min(len(queryset), limit), + "replies": replies, + "limit": limit + } + ) + + return HttpResponse(comment_html) + +def get_showmore(request): + return get_comment(request) + +def get_reply(request): + return get_comment(request) class CommentMixin(object): model = Comment diff --git a/resources/comments.scss b/resources/comments.scss index 54118e7..efede6a 100644 --- a/resources/comments.scss +++ b/resources/comments.scss @@ -121,6 +121,18 @@ a { margin: -50px 23px 10px -40px; padding-top: 50px; } + + .show_more_reply { + font-weight: bold; + display: block; + margin: 16px 40px; + } + + .show_more_comment { + font-weight: bold; + display: block; + margin: 0 -40px; + } } .no-comments-message { diff --git a/templates/actionbar/list.html b/templates/actionbar/list.html index 0bad8e1..0defe94 100644 --- a/templates/actionbar/list.html +++ b/templates/actionbar/list.html @@ -27,9 +27,9 @@ {{_("Comment")}} - {% if comment_count %} + {% if replies %} - ({{comment_count}}) + ({{replies}}) {% endif %} diff --git a/templates/comments/content-list.html b/templates/comments/content-list.html new file mode 100644 index 0000000..04507b0 --- /dev/null +++ b/templates/comments/content-list.html @@ -0,0 +1,121 @@ +{% set logged_in = request.user.is_authenticated %} +{% set profile = request.profile if logged_in else None %} +{% for node in mptt_tree(comment_list) recursive %} +
  • +
    +
    +
    + {% if logged_in %} + + {% else %} + + {% endif %} +
    +
    {{ node.score }}
    + {% if logged_in %} + + {% else %} + + {% endif %} +
    + {% with author=node.author, user=node.author.user %} + + + + {% endwith %} +
    +
    +
    + {{ link_user(node.author) }}  + {{ relative_time(node.time, abs=_('commented on {time}'), rel=_('commented {time}')) }} + + + {% if node.revisions > 1 %} + + + + {% if node.revisions > 2 %} + {% trans edits=node.revisions - 1 %}edit {{ edits }}{% endtrans %} + {% else %} + {{ _('edited') }} + {% endif %} + + + + {% else %} + + {% endif %} + + + + {% if logged_in and not comment_lock %} + {% set can_edit = node.author.id == profile.id and not profile.mute %} + {% if can_edit %} + + + + {% else %} + + + + {% endif %} + {% if perms.judge.change_comment %} + {% if can_edit %} + + {% else %} + + {% endif %} + + + {% endif %} + {% endif %} + +
    +
    + + {% if node.score <= vote_hide_threshold %}
    +

    + {% trans id=node.id %}This comment is hidden due to too much negative feedback. Click here to view it.{% endtrans %} +

    +
    + {% endif %} +
    +
    +
    + + + {% if node.revisions == 1 %} + {% set real_replies = node.count_replies - node.revisions + 1 %} + {% else %} + {% set real_replies = node.count_replies - node.revisions + 2 %} + {% endif %} + + {% if real_replies > 1 %} + {{ real_replies }} {{ _(' Replies ') }} + {% elif real_replies %} + {{ real_replies }} {{ _(' Reply ') }} + {% endif %} +
  • + + +{% endfor %} + +{% if replies - offset > 0 %} + {{ replies - offset }} Replies More +{% endif %} \ No newline at end of file diff --git a/templates/comments/list.html b/templates/comments/list.html index 44c2515..d561210 100644 --- a/templates/comments/list.html +++ b/templates/comments/list.html @@ -37,118 +37,8 @@ {% endif %} {% if has_comments %} -