Compare commits

...

2 Commits

Author SHA1 Message Date
8a04d24a5b
refactor(contest): contest card
All checks were successful
continuous-integration/drone/push Build is passing
2023-02-26 18:03:00 +08:00
6d913b066a
feat(problem): display judge_type 2023-02-26 17:09:27 +08:00
9 changed files with 126 additions and 144 deletions

View File

@ -554,38 +554,7 @@ echoUOJPageHeader($tabs_info[$cur_tab]['name'] . ' - ' . UOJContest::info('name'
<hr class="d-md-none" /> <hr class="d-md-none" />
<div class="col-md-3"> <div class="col-md-3">
<div class="card card-default mb-2"> <?= UOJContest::cur()->getContestCard() ?>
<div class="card-body">
<h3 class="h4 card-title text-center">
<a class="text-decoration-none text-body" href="<?= UOJContest::cur()->getUri() ?>">
<?= UOJContest::info('name') ?>
</a>
</h3>
<div class="card-text text-center text-muted">
<?php if ($contest['cur_progress'] <= CONTEST_IN_PROGRESS) : ?>
<span id="contest-countdown"></span>
<script type="text/javascript">
$('#contest-countdown').countdown(<?= $contest['end_time']->getTimestamp() - UOJTime::$time_now->getTimestamp() ?>, function() {}, '1.75rem', false);
</script>
<?php elseif ($contest['cur_progress'] <= CONTEST_TESTING) : ?>
<?php $judge_progress = UOJContest::cur()->queryJudgeProgress() ?>
<?= $judge_progress['title'] ?> (<?= $judge_progress['rop'] ?>%)
<?php else : ?>
<?= UOJLocale::get('contests::contest ended') ?>
<?php endif ?>
</div>
</div>
<div class="list-group list-group-flush">
<li class="list-group-item d-flex justify-content-between align-items-center">
<span class="flex-shrink-0">
<?= UOJLocale::get('appraisal') ?>
</span>
<span>
<?= UOJContest::cur()->getZanBlock() ?>
</span>
</li>
</div>
</div>
<?php if (UOJContest::cur()->basicRule() === 'OI') : ?> <?php if (UOJContest::cur()->basicRule() === 'OI') : ?>
<p>此次比赛为 OI 赛制。</p> <p>此次比赛为 OI 赛制。</p>

View File

@ -112,11 +112,14 @@ if ($rest_second <= 86400) {
echo <<<EOD echo <<<EOD
<div class="text-center bot-buffer-lg"> <div class="text-center bot-buffer-lg">
<div class="text-secondary">$upcoming_contest_name 倒计时</div> <div class="text-secondary">$upcoming_contest_name 倒计时</div>
<div id="contest-countdown"></div> <div class="text-secondary" id="contest-countdown"></div>
<script type="text/javascript"> <script>
$('#contest-countdown').countdown($rest_second, function() { $('#contest-countdown').countdown($rest_second, {
if (confirm($notification)) { font_size: '30px',
window.location.href = "$upcoming_contest_href"; callback: function() {
if (confirm($notification)) {
window.location.href = "$upcoming_contest_href";
}
} }
}); });
</script> </script>

View File

@ -302,43 +302,47 @@ if (UOJContest::cur()) {
if (UOJProblem::info('type') == 'local') { if (UOJProblem::info('type') == 'local') {
$time_limit = $conf instanceof UOJProblemConf ? $conf->getVal('time_limit', 1) : null; $time_limit = $conf instanceof UOJProblemConf ? $conf->getVal('time_limit', 1) : null;
$memory_limit = $conf instanceof UOJProblemConf ? $conf->getVal('memory_limit', 256) : null; $memory_limit = $conf instanceof UOJProblemConf ? $conf->getVal('memory_limit', 256) : null;
$judge_type = $conf instanceof UOJProblemConf ? $conf->getNonTraditionalJudgeType() : null;
} else if (UOJProblem::info('type') == 'remote') { } else if (UOJProblem::info('type') == 'remote') {
$time_limit = UOJProblem::cur()->getExtraConfig('time_limit'); $time_limit = UOJProblem::cur()->getExtraConfig('time_limit');
$memory_limit = UOJProblem::cur()->getExtraConfig('memory_limit'); $memory_limit = UOJProblem::cur()->getExtraConfig('memory_limit');
$judge_type = 'remote_judge';
} }
?> ?>
<div class="text-center small"> <div class="text-center small">
<?= UOJLocale::get('problems::time limit') ?>: <?= $time_limit ? "$time_limit s" : "N/A" ?> <?= UOJLocale::get('problems::time limit') ?>: <?= $time_limit ? "$time_limit s" : "N/A" ?>
&emsp; &emsp;
<?= UOJLocale::get('problems::memory limit') ?>: <?= $memory_limit ? "$memory_limit MB" : "N/A" ?> <?= UOJLocale::get('problems::memory limit') ?>: <?= $memory_limit ? "$memory_limit MB" : "N/A" ?>
&emsp;
<?= UOJLocale::get('problems::judge type') ?>: <?= $judge_type ? (UOJLocale::get("problems::judge type $judge_type") ?: $judge_type) : "N/A" ?>
</div> </div>
<hr /> <hr />
<?php if (!UOJContest::cur()) : ?>
<?php $contest_problems = UOJProblem::cur()->findInContests(); ?>
<?php if (!empty($contest_problems)) : ?>
<div class="alert alert-light">
<h5 class="alert-heading"><?= UOJLocale::get('problems::the problem was used in the following contest') ?>:</h5>
<ul class="mb-0">
<?php usort($contest_problems, fn ($a, $b) => $a->contest->info['start_time'] < $b->contest->info['start_time']); ?>
<?php foreach ($contest_problems as $cp) : ?>
<?php if ($cp->userCanView(Auth::user())) : ?>
<li>
<?= $cp->contest->getLink(['class' => 'alert-link text-decoration-underline']) ?>
<small>(<?= $cp->contest->info['start_time_str'] ?>)</small>
</li>
<?php endif ?>
<?php endforeach ?>
</ul>
</div>
<hr />
<?php endif ?>
<?php endif ?>
<div class="tab-content"> <div class="tab-content">
<div class="tab-pane active" id="statement"> <div class="tab-pane active" id="statement">
<?php if (!UOJContest::cur()) : ?>
<?php $contest_problems = UOJProblem::cur()->findInContests(); ?>
<?php if (!empty($contest_problems)) : ?>
<div class="alert alert-light">
<h5 class="alert-heading"><?= UOJLocale::get('problems::the problem was used in the following contest') ?>:</h5>
<ul class="mb-0">
<?php usort($contest_problems, fn ($a, $b) => $a->contest->info['start_time'] < $b->contest->info['start_time']); ?>
<?php foreach ($contest_problems as $cp) : ?>
<?php if ($cp->userCanView(Auth::user())) : ?>
<li>
<?= $cp->contest->getLink(['class' => 'alert-link text-decoration-underline']) ?>
<small>(<?= $cp->contest->info['start_time_str'] ?>)</small>
</li>
<?php endif ?>
<?php endforeach ?>
</ul>
</div>
<hr />
<?php endif ?>
<?php endif ?>
<article class="mt-3 markdown-body"> <article class="mt-3 markdown-body">
<?= $problem_content['statement'] ?> <?= $problem_content['statement'] ?>
</article> </article>
@ -382,38 +386,7 @@ if (UOJContest::cur()) {
<!-- right col --> <!-- right col -->
<aside class="col-lg-3 mt-3 mt-lg-0"> <aside class="col-lg-3 mt-3 mt-lg-0">
<?php if (UOJContest::cur()) : ?> <?php if (UOJContest::cur()) : ?>
<!-- Contest card --> <?= UOJContest::cur()->getContestCard() ?>
<div class="card card-default mb-2">
<div class="card-body">
<h3 class="h4 card-title text-center">
<a class="text-decoration-none text-body" href="<?= UOJContest::cur()->getUri() ?>">
<?= UOJContest::info('name') ?>
</a>
</h3>
<div class="card-text text-center text-muted">
<?php if (UOJContest::cur()->progress() <= CONTEST_IN_PROGRESS) : ?>
<span id="contest-countdown"></span>
<?php else : ?>
<?= UOJLocale::get('contests::contest ended') ?>
<?php endif ?>
</div>
</div>
<div class="list-group list-group-flush">
<li class="list-group-item d-flex justify-content-between align-items-center">
<span class="flex-shrink-0">
<?= UOJLocale::get('appraisal') ?>
</span>
<span>
<?= UOJContest::cur()->getZanBlock() ?>
</span>
</li>
</div>
</div>
<?php if (UOJContest::cur()->progress() <= CONTEST_IN_PROGRESS) : ?>
<script>
$('#contest-countdown').countdown(<?= UOJContest::info('end_time')->getTimestamp() - UOJTime::$time_now->getTimestamp() ?>, function() {}, '1.75rem', false);
</script>
<?php endif ?>
<?php endif ?> <?php endif ?>
<!-- 题目导航卡片 --> <!-- 题目导航卡片 -->

View File

@ -258,42 +258,13 @@ if (UOJContest::cur()) {
<!-- right col --> <!-- right col -->
<aside class="col-lg-3 mt-3 mt-lg-0"> <aside class="col-lg-3 mt-3 mt-lg-0">
<?php if (UOJContest::cur()) : ?> <?php if (UOJContest::cur()) : ?>
<!-- Contest card --> <?= UOJContest::cur()->getContestCard() ?>
<div class="card card-default mb-2">
<div class="card-body">
<h3 class="h4 card-title text-center">
<?= UOJContest::cur()->getLink(['class' => 'text-body']) ?>
</h3>
<div class="card-text text-center text-muted">
<?php if (UOJContest::cur()->progress() <= CONTEST_IN_PROGRESS) : ?>
<span id="contest-countdown"></span>
<?php else : ?>
<?= UOJLocale::get('contests::contest ended') ?>
<?php endif ?>
</div>
</div>
<div class="list-group list-group-flush">
<li class="list-group-item d-flex justify-content-between align-items-center">
<span class="flex-shrink-0">
<?= UOJLocale::get('appraisal') ?>
</span>
<span>
<?= UOJContest::cur()->getZanBlock() ?>
</span>
</li>
</div>
</div>
<?php if (UOJContest::cur()->progress() <= CONTEST_IN_PROGRESS) : ?>
<script type="text/javascript">
$('#contest-countdown').countdown(<?= UOJContest::info('end_time')->getTimestamp() - UOJTime::$time_now->getTimestamp() ?>, function() {}, '1.75rem', false);
</script>
<?php endif ?>
<?php endif ?> <?php endif ?>
<div class="card card-default mb-2"> <div class="card card-default mb-2">
<ul class="nav nav-pills nav-fill flex-column" role="tablist"> <ul class="nav nav-pills nav-fill flex-column" role="tablist">
<li class="nav-item text-start"> <li class="nav-item text-start">
<a class="nav-link" role="tab" <?php if (UOJContest::cur()) : ?> href="/contest/<?= UOJContest::info('id') ?>/problem/<?= UOJProblem::info('id') ?>" <?php else : ?> href="/problem/<?= UOJProblem::info('id') ?>" <?php endif ?>> <a class="nav-link" role="tab" href="<?= UOJProblem::cur()->getUri() ?>">
<i class="bi bi-journal-text"></i> <i class="bi bi-journal-text"></i>
<?= UOJLocale::get('problems::statement') ?> <?= UOJLocale::get('problems::statement') ?>
</a> </a>

View File

@ -59,6 +59,12 @@ return [
'uploader' => 'Uploader', 'uploader' => 'Uploader',
'time limit' => 'Time limit', 'time limit' => 'Time limit',
'memory limit' => 'Memory limit', 'memory limit' => 'Memory limit',
'judge type' => 'Judge type',
'judge type traditional' => 'Traditional',
'judge type custom_judger' => 'Custom judger',
'judge type submit_answer' => 'Submit answer',
'judge type interaction' => 'Interaction',
'judge type remote_judge' => 'Remote Judge',
'attachments' => 'Attachments', 'attachments' => 'Attachments',
'test data' => 'Test data', 'test data' => 'Test data',
'attachments download' => 'Attachments download', 'attachments download' => 'Attachments download',

View File

@ -59,6 +59,12 @@ return [
'uploader' => '上传者', 'uploader' => '上传者',
'time limit' => '时间限制', 'time limit' => '时间限制',
'memory limit' => '内存限制', 'memory limit' => '内存限制',
'judge type' => '测评类型',
'judge type traditional' => '传统型',
'judge type custom_judger' => '自定义评测机',
'judge type submit_answer' => '提交答案',
'judge type interaction' => '交互型',
'judge type remote_judge' => '远端评测',
'attachments' => '附件', 'attachments' => '附件',
'test data' => '测试数据', 'test data' => '测试数据',
'attachments download' => '附件下载', 'attachments download' => '附件下载',

View File

@ -315,7 +315,7 @@ class UOJContest {
} }
public function queryJudgeProgress() { public function queryJudgeProgress() {
if ($this->basicRule() == 'OI' && $this->progress() < CONTEST_TESTING) { if (/* $this->basicRule() == 'OI' && */$this->progress() < CONTEST_TESTING) {
$rop = 0; $rop = 0;
$title = UOJLocale::get('contests::contest pending final test'); $title = UOJLocale::get('contests::contest pending final test');
$fully_judged = false; $fully_judged = false;
@ -623,4 +623,60 @@ class UOJContest {
public function getAdditionalLinks() { public function getAdditionalLinks() {
return $this->info['extra_config']['links'] ?: []; return $this->info['extra_config']['links'] ?: [];
} }
public function getContestCard($cfg = []) {
$cfg += [
'class' => 'mb-2',
];
$res = '';
$res .= <<<EOD
<div class="card mb-2">
<div class="card-body">
<h3 class="h4 card-title text-center">
<a class="text-decoration-none text-body" href="{$this->getUri()}">
{$this->info['name']}
</a>
</h3>
<div class="card-text text-center text-muted">
EOD;
if ($this->progress() <= CONTEST_IN_PROGRESS) {
$res .= HTML::tag('span', [
'class' => 'countdown fs-3',
'data-rest' => $this->info['end_time']->getTimestamp() - UOJTime::$time_now->getTimestamp(),
], ' ');
} else if ($this->progress() <= CONTEST_TESTING) {
$judge_progress = $this->queryJudgeProgress();
$res .= HTML::tag('span', [], "{$judge_progress['title']} ({$judge_progress['rop']})");
} else {
$res .= HTML::tag('span', [], UOJLocale::get('contests::contest ended'));
}
$res .= <<<EOD
</div>
</div>
<div class="list-group list-group-flush">
EOD;
$appraisal = UOJLocale::get('appraisal');
$res .= <<<EOD
<div class="list-group-item d-flex justify-content-between align-items-center">
<span class="flex-shrink-0 me-2">
{$appraisal}
</span>
<span class="text-end">
{$this->getZanBlock()}
</span>
</div>
EOD;
$res .= <<<EOD
</div>
</div>
EOD;
return $res;
}
} }

View File

@ -92,10 +92,7 @@ $parsedown = HTML::parsedown(['username_with_color' => true]);
<?php if ($rest_seconds > 86400) : ?> <?php if ($rest_seconds > 86400) : ?>
<?= UOJLocale::get('contests::will start in x days', ceil($rest_seconds / 86400)) ?> <?= UOJLocale::get('contests::will start in x days', ceil($rest_seconds / 86400)) ?>
<?php else : ?> <?php else : ?>
<div id="contest-<?= $contest->info['id'] ?>-countdown"></div> <div class="countdown" data-rest="<?= $rest_seconds ?>"></div>
<script>
$('#contest-<?= $contest->info['id'] ?>-countdown').countdown(<?= $rest_seconds ?>, function() {}, 'inherit', false);
</script>
<?php endif ?> <?php endif ?>
<?php endif ?> <?php endif ?>
</div> </div>

View File

@ -349,45 +349,46 @@ $.fn.click_zan_block = function() {
} }
// count down // count down
function getCountdownStr(t, font_size, color = true) { function getCountdownStr(t, config) {
var x = Math.floor(t); var x = Math.floor(t);
var ss = toFilledStr(x % 60, '0', 2); var ss = toFilledStr(x % 60, '0', 2);
x = Math.floor(x / 60); x = Math.floor(x / 60);
var mm = toFilledStr(x % 60, '0', 2); var mm = toFilledStr(x % 60, '0', 2);
x = Math.floor(x / 60); x = Math.floor(x / 60);
var hh = x.toString(); var hh = x.toString();
var style = '';
if (config.font_size) {
style += 'font-size: ' + config.font_size + ';';
}
var res = '<span style="font-size:' + font_size + '">'; var res = '<span style="' + style + '">';
res += '<span ' res += '<span>' + hh + '</span>';
if (color) res += ' style="color:' + getColOfScore(Math.min(t / 10800 * 100, 100)) + '" ';
res += ' >' + hh + '</span>';
res += ':'; res += ':';
res += '<span ' res += '<span>' + mm + '</span>';
if (color) res += ' style="color:' + getColOfScore(mm / 60 * 100) + '" ';
res += ' >' + mm + '</span>';
res += ':'; res += ':';
res += '<span '; res += '<span>' + ss + '</span>';
if (color) res += ' style="color:' + getColOfScore(ss / 60 * 100) + '" '; res += '</span>';
res +=' >' + ss + '</span>';
res += '</span>'
return res; return res;
} }
$.fn.countdown = function(rest, callback, font_size = '30px', color = true) { $.fn.countdown = function(rest, config = {}) {
return this.each(function() { return this.each(function() {
var start = new Date().getTime(); var start = new Date().getTime();
var cur_rest = rest != undefined ? rest : parseInt($(this).data('rest')); var cur_rest = rest != undefined ? rest : parseInt($(this).data('rest'));
config = $.merge(config, JSON.parse($(this).data('config') || '{}'));
var cur = this; var cur = this;
var countdown = function() { var countdown = function() {
var passed = Math.floor((new Date().getTime() - start) / 1000); var passed = Math.floor((new Date().getTime() - start) / 1000);
if (passed >= cur_rest) { if (passed >= cur_rest) {
$(cur).html(getCountdownStr(0, font_size, color)); $(cur).html(getCountdownStr(0, config));
if (callback != undefined) { if (config.callback != undefined) {
callback(); callback();
} }
} else { } else {
$(cur).html(getCountdownStr(cur_rest - passed, font_size, color)); $(cur).html(getCountdownStr(cur_rest - passed, config));
setTimeout(countdown, 1000); setTimeout(countdown, 500);
} }
} }
countdown(); countdown();