diff --git a/judge/views/contests.py b/judge/views/contests.py index c46c06a..d926d37 100644 --- a/judge/views/contests.py +++ b/judge/views/contests.py @@ -643,8 +643,10 @@ def base_contest_ranking_list(contest, problems, queryset): queryset.select_related('user__user', 'rating').defer('user__about', 'user__organizations__about')] -def contest_ranking_list(contest, problems): - return base_contest_ranking_list(contest, problems, contest.users.filter(virtual__gte=0) +def contest_ranking_list(contest, problems, queryset=None): + if not queryset: + queryset = contest.users.filter(virtual=0) + return base_contest_ranking_list(contest, problems, queryset .prefetch_related('user__organizations') .extra(select={'round_score': 'round(score, 6)'}) .order_by('is_disqualified', '-round_score', 'cumtime', 'tiebreaker')) @@ -674,7 +676,15 @@ def contest_ranking_ajax(request, contest, participation=None): if not contest.can_see_full_scoreboard(request.user): raise Http404() - users, problems = get_contest_ranking_list(request, contest, participation) + queryset = contest.users.filter(virtual__gte=0) + if request.GET.get('friend') == 'true' and request.profile: + friends = list(request.profile.get_friends()) + queryset = queryset.filter(user__user__username__in=friends) + if request.GET.get('virtual') != 'true': + queryset = queryset.filter(virtual=0) + + users, problems = get_contest_ranking_list(request, contest, participation, + ranking_list=partial(contest_ranking_list, queryset=queryset)) return render(request, 'contest/ranking-table.html', { 'users': users, 'problems': problems, diff --git a/resources/loading.gif b/resources/loading.gif new file mode 100644 index 0000000..7e46f92 Binary files /dev/null and b/resources/loading.gif differ diff --git a/templates/contest/ranking-table.html b/templates/contest/ranking-table.html index 210795b..d9d674e 100644 --- a/templates/contest/ranking-table.html +++ b/templates/contest/ranking-table.html @@ -66,7 +66,7 @@ {% endblock %} {% block row_extra %} - class="{{ 'disqualified' if user.participation.is_disqualified }} {{ 'friend' if user.username in friends }} {{'highlight' if user.username == request.user.username}} {{'virtual' if user.participation.virtual}}" + class="{{ 'disqualified' if user.participation.is_disqualified }} {{'highlight' if user.username == request.user.username}}" {% endblock %} {% block before_point %} diff --git a/templates/contest/ranking.html b/templates/contest/ranking.html index 2f802c2..41d47ea 100644 --- a/templates/contest/ranking.html +++ b/templates/contest/ranking.html @@ -264,7 +264,6 @@ let problem = linkElements[linkElements.length - 2]; let score = parseFloat(scoreAndTime[0]); let time = scoreAndTime[1]; - console.log(time); if (time) { let curSubmission = { @@ -287,20 +286,17 @@ } } - let non_virtual_rank = []; - let original_rank = []; - function renew_filter() { var checkboxes = [ '#show-organizations-checkbox', '#show-fullnames-checkbox', - '#show-friends-checkbox', '#show-total-score-checkbox', - '#show-virtual-checkbox' ]; - get_all_rank(); - get_non_virtual_rank(); + var checkboxes2 = [ + '#show-friends-checkbox', + '#show-virtual-checkbox' + ] for (var i of checkboxes) { var $box = $(i); @@ -310,15 +306,30 @@ $box.prop('checked', true); } } + + var to_update = false; + for (var i of checkboxes2) { + var $box = $(i); + if ($box.is(':checked')) { + to_update = true; + } + } + if (to_update) { + update_ranking(); + } } function update_ranking() { + var friend = $('#show-friends-checkbox').is(':checked'); + var virtual = $('#show-virtual-checkbox').is(':checked'); + $('#loading-gif').show(); $.get({ - url: '/contest/{{contest.key}}/ranking/ajax', + url: `/contest/{{contest.key}}/ranking/ajax?friend=${friend}&virtual=${virtual}`, success: function(HTML) { $('#users-table').html(HTML); highlightFirstSolve(); renew_filter(); + $('#loading-gif').hide(); }, fail: function() { console.log('Fail to update ranking'); @@ -326,50 +337,6 @@ }); } - function get_all_rank() { - original_rank = []; - $('tbody tr').each(function() { - original_rank.push($(this).children('td:first').html()); - }); - } - - function get_non_virtual_rank() { - non_virtual_rank = []; - $non_virtual_rows = $('tbody tr').not('.virtual'); - $non_virtual_rows.each(function() { - non_virtual_rank.push($(this).children('td:first').html()); - }); - var res = []; - for (var i in non_virtual_rank) { - if (i > 0 && non_virtual_rank[i] === non_virtual_rank[i - 1]) { - res.push(res[res.length - 1]); - } - else { - res.push(parseInt(i) + 1); - } - } - non_virtual_rank = res; - } - - function hide_virtual() { - $('.virtual').hide(); - var $non_virtual_rows = $('tbody tr').not('.virtual'); - $non_virtual_rows.each(function(index) { - $(this).children('td:first').html(non_virtual_rank[index]); - }); - $non_virtual_rows.last().find('td').css({'border-bottom-width': - '1px', 'border-color': '#ccc'}); - } - - function show_virtual() { - $('.virtual').show(); - $('tbody tr').each(function(index) { - $(this).children('td:first').html(original_rank[index]); - }); - $('tbody tr').not('.virtual').last().find('td').css({'border-bottom-width': - '', 'border-color': ''}); - } - // window.load_dynamic_update = function (last_msg) { // return new EventReceiver( // "{{ EVENT_DAEMON_LOCATION }}", "{{ EVENT_DAEMON_POLL_LOCATION }}", @@ -415,28 +382,11 @@ {% if request.user.is_authenticated %} $('#show-friends-checkbox').click(function() { - let checked = $('#show-friends-checkbox').is(':checked'); - if (checked) { - $('tbody tr').hide(); - $('.friend').show(); - $('.friend').last().find('td').css({'border-bottom-width': - '1px', 'border-color': '#ccc'}); - } - else { - $('tr').show(); - $('.friend').last().find('td').css({'border-bottom-width': - '', 'border-color': ''}); - } + update_ranking(); }) {% endif %} $('#show-virtual-checkbox').click(function() { - let checked = $('#show-virtual-checkbox').is(':checked'); - if (checked) { - show_virtual(); - } - else { - hide_virtual(); - } + update_ranking(); }) $('#show-total-score-checkbox').click(function() { $('.problem-score-col').toggle(); @@ -448,7 +398,6 @@ $('#show-virtual-checkbox').hide(); $('#show-virtual-label').hide(); {% else %} - hide_virtual(); {% if request.in_contest %} setInterval(update_ranking, 60 * 1000); {% endif %} @@ -479,7 +428,8 @@ - + + {% include "contest/ranking-table.html" %} {% endblock %}