ui: add scoreboard pjax (#545)

This commit is contained in:
panda authored and GitHub committed 2023-03-23 15:07:30 +08:00
1 parent 17cf1194de
commit 3f6f1748e6
4 files changed
+99 -84

No files matched your search

+2 -1
View File
@@ -280,7 +280,6 @@ export class ContestScoreboardHandler extends ContestDetailBaseHandler {
config.lockAt = this.tdoc.lockAt;
}
const [, rows, udict, pdict] = await contest.getScoreboard.call(this, domainId, tid, config);
this.response.template = 'contest_scoreboard.html';
// eslint-disable-next-line @typescript-eslint/naming-convention
const page_name = this.tdoc.rule === 'homework'
? 'homework_scoreboard'
@@ -288,6 +287,8 @@ export class ContestScoreboardHandler extends ContestDetailBaseHandler {
this.response.body = {
tdoc: this.tdoc, rows, udict, pdict, page_name,
};
this.response.pjax = 'partials/scoreboard.html';
this.response.template = 'contest_scoreboard.html';
}
async exportGhost(domainId: string, tid: ObjectId) {
@@ -1,5 +1,6 @@
import $ from 'jquery';
import { NamedPage } from 'vj/misc/Page';
import { pjax } from 'vj/utils';
const page = new NamedPage('contest_scoreboard', () => {
const { tdoc } = UiContext;
@@ -34,6 +35,15 @@ const page = new NamedPage('contest_scoreboard', () => {
$('.rank--unrank').closest('tr').hide();
}
});
const beginAt = new Date(UiContext.tdoc.beginAt).getTime();
const endAt = new Date(UiContext.tdoc.endAt).getTime();
function updateScoreboard() {
const now = Date.now();
if (beginAt <= now && now <= endAt) pjax.request(UiContext.scoreboardUrl || '', { push: false });
}
setInterval(updateScoreboard, 180000);
});
export default page;
@@ -3,13 +3,6 @@
{{ set(UiContext, 'tdoc', tdoc) }}
{% set type = 'homework' if tdoc.rule == 'homework' else 'contest' %}
{% macro renderRecord(cell, canView) %}
<a href="{{ url('record_detail', rid=cell.raw) if canView else '' }}"{% if cell.hover %} data-tooltip="{{ cell.hover }}"{% endif %}>
{%- set _color = utils.status.getScoreColor(cell.score|default(cell.value)) -%}
<span style="font-weight:bold;color:{{ _color }}">{{ cell.value|string|nl2br|safe }}</span>
</a>
{% endmacro %}
{% block content %}
<div class="row"><div class="medium-12 columns scoreboard--{{ tdoc.rule }}">
<div class="section visible">
@@ -35,82 +28,7 @@
</select>
</div>
</div>
{% if model.contest.isLocked(tdoc) %}
<div class="section__body no-padding">
<blockquote class="note">
{{ _('The scoreboard was frozen with {0} minutes remaining at {1} - submissions in the last {0} minutes of the contest are still shown as pending.').format((tdoc.endAt - tdoc.lockAt) / 1000 / 60, datetimeSpan(tdoc.lockAt))|safe }}
</blockquote>
</div>
{% elif model.contest.isDone(tdoc) and tdoc.lockAt and not tdoc.unlocked %}
<div class="section__body no-padding">
<blockquote class="note">
{{ _('Please wait until contest host unfreeze the scoreboard.') }}
</blockquote>
</div>
{% endif %}
<div class="section__body no-padding overflow-hidden-horizontal">
<table class="data-table">
<colgroup>
{%- for column in rows[0] -%}
<col class="col--{{ column.type }}">
{%- endfor -%}
</colgroup>
<thead>
<tr>
{%- for column in rows[0] -%}
<th class="col--{{ column.type }}">
{%- if column.type == 'problem' and column.raw -%}
<a href="{{ url('problem_detail', pid=column.raw, query={tid:tdoc.docId}) }}" data-tooltip="{{ pdict[column.raw].title }}">
{{ column.value }}<br />{{ pdict[column.raw].nAccept|default(0) }}/{{ pdict[column.raw].nSubmit|default(0) }}
</a>
{%- else -%}
{{ column.value|string|nl2br|safe }}
{%- endif -%}
</th>
{%- endfor -%}
</tr>
</thead>
<tbody>
{%- set canViewAll = handler.user.own(tdoc) or model.contest.canShowRecord.call(handler, tdoc) -%}
{%- for row in rows -%}{%- if loop.index0 > 0 -%}
<tr>
{%- for column in row -%}
<td class="col--{{ rows[0][loop.index0]['type'] }}"{% if column.style %} style="{{ column.style }}"{% endif %}>
{%- if column.type == 'rank' -%}
<span class="{{ 'rank--unrank' if column.value == '0' else 'rank--normal' }}">{{ '*' if column.value == '0' else column.value|string|nl2br|safe }}</span>
{%- elif column.type == 'user' -%}
{%- set canView = canViewAll or handler.user._id == column.raw -%}
<button class="star user--{{ column.raw }}" data-uid="{{ column.raw }}">
<span class="starred--hide"><span class="icon icon-star--outline" data-tooltip="{{ _('Star') }}"></span></span>
<span class="starred--show"><span class="icon icon-star" data-tooltip="{{ _('Unstar') }}"></span></span>
</button>
{{ user.render_inline(udict[column.raw], badge=false) }}
{%- elif column.type == 'record' and column.raw -%}
<a href="{{ url('record_detail', rid=column.raw) if canView else '' }}" data-tooltip="{{ column.hover }}">
<span style="font-weight:bold;color:{{ utils.status.getScoreColor(column.score|default(column.value)) }}">{{ column.value|string|nl2br|safe }}</span>
</a>
{%- elif column.type == 'records' -%}
{%- for record in column.raw -%}
{%- if loop.index0 -%}/{%- endif -%}
{%- if record.raw -%}
<a href="{{ url('record_detail', rid=record.raw) if canView else '' }}">
{%- set _color = utils.status.getScoreColor(record.score|default(record.value)) -%}
<span style="font-weight:bold;color:{{ _color }}">{{ record.value|string|nl2br|safe }}</span>
</a>
{%- else -%}
{{ record.value|string|nl2br|safe }}
{%- endif -%}
{%- endfor -%}
{%- else -%}
<span data-tooltip="{{ column.hover }}">{{ column.value|string|nl2br|safe }}</span>
{%- endif -%}
</td>
{%- endfor -%}
</tr>
{%- endif -%}{%- endfor -%}
</tbody>
</table>
</div>
{% include "partials/scoreboard.html" %}
</div>
</div></div>
{% endblock %}
@@ -0,0 +1,86 @@
{% import "components/user.html" as user with context %}
{% macro renderRecord(cell, canView) %}
<a href="{{ url('record_detail', rid=cell.raw) if canView else '' }}"{% if cell.hover %} data-tooltip="{{ cell.hover }}"{% endif %}>
{%- set _color = utils.status.getScoreColor(cell.score|default(cell.value)) -%}
<span style="font-weight:bold;color:{{ _color }}">{{ cell.value|string|nl2br|safe }}</span>
</a>
{% endmacro %}
<div data-fragment-id="scoreboard">
{% if model.contest.isLocked(tdoc) %}
<div class="section__body no-padding">
<blockquote class="note">
{{ _('The scoreboard was frozen with {0} minutes remaining at {1} - submissions in the last {0} minutes of the contest are still shown as pending.').format((tdoc.endAt - tdoc.lockAt) / 1000 / 60, datetimeSpan(tdoc.lockAt))|safe }}
</blockquote>
</div>
{% elif model.contest.isDone(tdoc) and tdoc.lockAt and not tdoc.unlocked %}
<div class="section__body no-padding">
<blockquote class="note">
{{ _('Please wait until contest host unfreeze the scoreboard.') }}
</blockquote>
</div>
{% endif %}
<div class="section__body no-padding overflow-hidden-horizontal">
<table class="data-table">
<colgroup>
{%- for column in rows[0] -%}
<col class="col--{{ column.type }}">
{%- endfor -%}
</colgroup>
<thead>
<tr>
{%- for column in rows[0] -%}
<th class="col--{{ column.type }}">
{%- if column.type == 'problem' and column.raw -%}
<a href="{{ url('problem_detail', pid=column.raw, query={tid:tdoc.docId}) }}" data-tooltip="{{ pdict[column.raw].title }}">
{{ column.value }}<br />{{ pdict[column.raw].nAccept|default(0) }}/{{ pdict[column.raw].nSubmit|default(0) }}
</a>
{%- else -%}
{{ column.value|string|nl2br|safe }}
{%- endif -%}
</th>
{%- endfor -%}
</tr>
</thead>
<tbody>
{%- set canViewAll = handler.user.own(tdoc) or model.contest.canShowRecord.call(handler, tdoc) -%}
{%- for row in rows -%}{%- if loop.index0 > 0 -%}
<tr>
{%- for column in row -%}
<td class="col--{{ rows[0][loop.index0]['type'] }}"{% if column.style %} style="{{ column.style }}"{% endif %}>
{%- if column.type == 'rank' -%}
<span class="{{ 'rank--unrank' if column.value == '0' else 'rank--normal' }}">{{ '*' if column.value == '0' else column.value|string|nl2br|safe }}</span>
{%- elif column.type == 'user' -%}
{%- set canView = canViewAll or handler.user._id == column.raw -%}
<button class="star user--{{ column.raw }}" data-uid="{{ column.raw }}">
<span class="starred--hide"><span class="icon icon-star--outline" data-tooltip="{{ _('Star') }}"></span></span>
<span class="starred--show"><span class="icon icon-star" data-tooltip="{{ _('Unstar') }}"></span></span>
</button>
{{ user.render_inline(udict[column.raw], badge=false) }}
{%- elif column.type == 'record' and column.raw -%}
<a href="{{ url('record_detail', rid=column.raw) if canView else '' }}" data-tooltip="{{ column.hover }}">
<span style="font-weight:bold;color:{{ utils.status.getScoreColor(column.score|default(column.value)) }}">{{ column.value|string|nl2br|safe }}</span>
</a>
{%- elif column.type == 'records' -%}
{%- for record in column.raw -%}
{%- if loop.index0 -%}/{%- endif -%}
{%- if record.raw -%}
<a href="{{ url('record_detail', rid=record.raw) if canView else '' }}">
{%- set _color = utils.status.getScoreColor(record.score|default(record.value)) -%}
<span style="font-weight:bold;color:{{ _color }}">{{ record.value|string|nl2br|safe }}</span>
</a>
{%- else -%}
{{ record.value|string|nl2br|safe }}
{%- endif -%}
{%- endfor -%}
{%- else -%}
<span data-tooltip="{{ column.hover }}">{{ column.value|string|nl2br|safe }}</span>
{%- endif -%}
</td>
{%- endfor -%}
</tr>
{%- endif -%}{%- endfor -%}
</tbody>
</table>
</div>
</div>