diff --git a/chat_box/utils.py b/chat_box/utils.py index ad93ad4..e25e861 100644 --- a/chat_box/utils.py +++ b/chat_box/utils.py @@ -1,6 +1,10 @@ from cryptography.fernet import Fernet from django.conf import settings +from django.db.models import OuterRef, Count, Subquery, IntegerField +from django.db.models.functions import Coalesce + +from chat_box.models import Ignore, Message, UserRoom secret_key = settings.CHAT_SECRET_KEY fernet = Fernet(secret_key) @@ -18,3 +22,28 @@ def decrypt_url(message_encrypted): return int(creator_id), int(other_id) except Exception as e: return None, None + + +def get_unread_boxes(profile): + ignored_users = Ignore.get_ignored_users(profile) + + mess = ( + Message.objects.filter(room=OuterRef("room"), time__gte=OuterRef("last_seen")) + .exclude(author=profile) + .exclude(author__in=ignored_users) + .order_by() + .values("room") + .annotate(unread_count=Count("pk")) + .values("unread_count") + ) + + unread_boxes = ( + UserRoom.objects.filter(user=profile, room__isnull=False) + .annotate( + unread_count=Coalesce(Subquery(mess, output_field=IntegerField()), 0), + ) + .filter(unread_count__gte=1) + .count() + ) + + return unread_boxes diff --git a/chat_box/views.py b/chat_box/views.py index 1d303ef..95a6819 100644 --- a/chat_box/views.py +++ b/chat_box/views.py @@ -502,32 +502,3 @@ def toggle_ignore(request, **kwargs): Ignore.toggle_ignore(request.profile, other_user) next_url = request.GET.get("next", "/") return HttpResponseRedirect(next_url) - - -@login_required -def get_unread_boxes(request): - if request.method != "GET": - return HttpResponseBadRequest() - - ignored_users = Ignore.get_ignored_users(request.profile) - - mess = ( - Message.objects.filter(room=OuterRef("room"), time__gte=OuterRef("last_seen")) - .exclude(author=request.profile) - .exclude(author__in=ignored_users) - .order_by() - .values("room") - .annotate(unread_count=Count("pk")) - .values("unread_count") - ) - - unread_boxes = ( - UserRoom.objects.filter(user=request.profile, room__isnull=False) - .annotate( - unread_count=Coalesce(Subquery(mess, output_field=IntegerField()), 0), - ) - .filter(unread_count__gte=1) - .count() - ) - - return JsonResponse({"unread_boxes": unread_boxes}) diff --git a/dmoj/urls.py b/dmoj/urls.py index e657af1..282b146 100644 --- a/dmoj/urls.py +++ b/dmoj/urls.py @@ -1036,11 +1036,6 @@ urlpatterns = [ chat.toggle_ignore, name="toggle_ignore", ), - url( - r"^get_unread_boxes$", - chat.get_unread_boxes, - name="get_unread_boxes", - ), ] ), ), diff --git a/judge/models/profile.py b/judge/models/profile.py index 2a0a80f..d9c6691 100644 --- a/judge/models/profile.py +++ b/judge/models/profile.py @@ -16,6 +16,7 @@ from judge.models.choices import ACE_THEMES, MATH_ENGINES_CHOICES, TIMEZONE from judge.models.runtime import Language from judge.ratings import rating_class + __all__ = ["Organization", "Profile", "OrganizationRequest", "Friend"] @@ -242,6 +243,12 @@ class Profile(models.Model): } return self.notifications.filter(**query).count() + @cached_property + def count_unread_chat_boxes(self): + from chat_box.utils import get_unread_boxes + + return get_unread_boxes(self) + _pp_table = [pow(settings.DMOJ_PP_STEP, i) for i in range(settings.DMOJ_PP_ENTRIES)] def calculate_points(self, table=_pp_table): diff --git a/templates/base.html b/templates/base.html index 5e6dc54..03e7c5e 100644 --- a/templates/base.html +++ b/templates/base.html @@ -158,20 +158,6 @@ id: '{{ request.user.id|escapejs }}', name: '{{ request.user.username|escapejs }}' }; - $(function() { - if ($('#chat-icon').length) { - $.get("{{url('get_unread_boxes')}}") - .done(function(data) { - if (data.unread_boxes) { - var html = `${data.unread_boxes}`; - $('#chat-icon').append(html); - } - }) - .fail(function(data) { - console.log('Fail to get unread boxes'); - }); - } - }); {% else %} @@ -230,6 +216,10 @@