refactor(submissions): new design
All checks were successful
continuous-integration/drone/push Build is passing

This commit is contained in:
Baoshuo Ren 2023-02-18 09:19:21 +08:00
parent 2baeac115e
commit ec8f271713
Signed by: baoshuo
GPG Key ID: 00CB9680AB29F51A
5 changed files with 161 additions and 17 deletions

View File

@ -136,7 +136,13 @@ function handleUpload($zip_file_name, $content, $tot_size) {
} }
} }
UOJSubmission::onUpload($zip_file_name, $content, $tot_size, $is_participating); $id = UOJSubmission::onUpload($zip_file_name, $content, $tot_size, $is_participating);
if ($is_participating) {
// redirect by UOJForm
} else {
redirectTo("/submission/$id");
}
} }
function handleCustomTestUpload($zip_file_name, $content, $tot_size) { function handleCustomTestUpload($zip_file_name, $content, $tot_size) {
UOJCustomTestSubmission::onUpload($zip_file_name, $content, $tot_size); UOJCustomTestSubmission::onUpload($zip_file_name, $content, $tot_size);

View File

@ -3,7 +3,9 @@ requirePHPLib('judger');
Auth::check() || redirectToLogin(); Auth::check() || redirectToLogin();
$conds = []; $conds = [
UOJSubmission::sqlForUserCanView(Auth::user()),
];
$config = [ $config = [
'time_format' => 'friendly', 'time_format' => 'friendly',
'time_font_size' => 'normal', 'time_font_size' => 'normal',
@ -44,6 +46,83 @@ if ($q_lang != null) {
if (!$conds) { if (!$conds) {
$conds = '1'; $conds = '1';
} }
function echoSubmissionItem($info) {
$submission = new UOJSubmission($info);
$submission->setProblem();
$submitter = UOJUser::query($submission->info['submitter']);
$cfg = [
'show_actual_score' => $submission->viewerCanSeeScore(Auth::user()),
'unknown_char' => '?',
'result_badge' => true,
];
echo '<div class="list-group-item">';
echo '<div class="row gy-2 align-items-center">';
echo '<div class="col-lg-3 col-sm-8 d-flex gap-2">';
echo '<div class="d-flex align-items-center">';
echo HTML::tag('a', [
'href' => HTML::url('/user/' . $submitter['username']),
'class' => 'd-inline-block me-2',
], HTML::empty_tag('img', [
'src' => HTML::avatar_addr($submitter, 64),
'class' => 'uoj-user-avatar rounded',
'style' => 'width: 2.5rem; height: 2.5rem;',
]));
echo '</div>';
echo '<div class="d-flex flex-column gap-1">';
echo '<div>', UOJUser::getLink($submitter), '</div>';
echo '<div class="small text-muted">', '<i class="bi bi-clock"></i> ', UOJTime::userFriendlyFormat($submission->info['submit_time']), '</div>';
echo '</div>';
echo '</div>';
echo '<div class="col-lg-2 col-sm-4">';
echo '<div>', $submission->echoStatusBarTD('result', $cfg), '</div>';
echo '</div>';
echo '<div class="col-lg-4 col-sm-12 text-truncate">';
echo $submission->problem->getLink();
echo '</div>';
$lang = UOJLang::getLanguageDisplayName($submission->info['language']);
echo '<div class="col-lg-3 small text-muted">';
echo '<span class="d-inline-block">', '<i class="bi bi-hourglass-split"></i> ', $submission->echoStatusBarTD('used_time', $cfg), '</span>', ' / ';
echo '<span class="d-inline-block">', '<i class="bi bi-memory"></i> ', $submission->echoStatusBarTD('used_memory', $cfg), '</span>', ' / ';
echo '<span class="d-inline-block">', '<i class="bi bi-file-code"></i> ', $submission->echoStatusBarTD('tot_size', $cfg), '</span>';
if ($lang != '/') {
echo ' / <span class="d-inline-block">', $lang, '</span> ';
}
echo '</div>';
echo '</div>';
echo '</div>';
}
$pag = new Paginator([
'page_len' => 10,
'table_name' => 'submissions',
'col_names' => [
'id',
'problem_id',
'contest_id',
'submitter',
'used_time',
'used_memory',
'tot_size',
'language',
'submit_time',
'status_details',
'status',
'result_error',
'score',
'hide_score_to_others',
'hidden_score',
],
'cond' => $conds,
'tail' => 'order by id desc',
]);
?> ?>
<?php echoUOJPageHeader(UOJLocale::get('submissions')) ?> <?php echoUOJPageHeader(UOJLocale::get('submissions')) ?>
@ -55,13 +134,13 @@ if (!$conds) {
<form id="form-search" class="row gy-2 gx-3 align-items-end mb-3" target="_self" method="GET"> <form id="form-search" class="row gy-2 gx-3 align-items-end mb-3" target="_self" method="GET">
<div id="form-group-problem_id" class="col-auto"> <div id="form-group-problem_id" class="col-auto">
<label for="input-problem_id" class="form-label"> <label for="input-problem_id" class="form-label">
<?= UOJLocale::get('problems::problem id') ?>: <?= UOJLocale::get('problems::problem id') ?>
</label> </label>
<input type="text" class="form-control form-control-sm" name="problem_id" id="input-problem_id" value="<?= $q_problem_id ?>" style="width:4em" /> <input type="text" class="form-control form-control-sm" name="problem_id" id="input-problem_id" value="<?= $q_problem_id ?>" style="width:4em" />
</div> </div>
<div id="form-group-submitter" class="col-auto"> <div id="form-group-submitter" class="col-auto">
<label for="input-submitter" class="form-label"> <label for="input-submitter" class="form-label">
<?= UOJLocale::get('username') ?>: <?= UOJLocale::get('username') ?>
</label> </label>
<div class="input-group input-group-sm"> <div class="input-group input-group-sm">
<input type="text" class="form-control form-control-sm" name="submitter" id="input-submitter" value="<?= $q_submitter ?>" maxlength="20" style="width:10em" /> <input type="text" class="form-control form-control-sm" name="submitter" id="input-submitter" value="<?= $q_submitter ?>" maxlength="20" style="width:10em" />
@ -81,7 +160,7 @@ if (!$conds) {
</div> </div>
<div id="form-group-score" class="col-auto"> <div id="form-group-score" class="col-auto">
<label for="input-min_score" class="form-label"> <label for="input-min_score" class="form-label">
<?= UOJLocale::get('score range') ?>: <?= UOJLocale::get('score range') ?>
</label> </label>
<div class="input-group input-group-sm"> <div class="input-group input-group-sm">
<input type="text" class="form-control" name="min_score" id="input-min_score" value="<?= $q_min_score ?>" maxlength="15" style="width:4em" placeholder="0" /> <input type="text" class="form-control" name="min_score" id="input-min_score" value="<?= $q_min_score ?>" maxlength="15" style="width:4em" placeholder="0" />
@ -91,7 +170,7 @@ if (!$conds) {
</div> </div>
<div id="form-group-language" class="col-auto"> <div id="form-group-language" class="col-auto">
<label for="input-language" class="form-label"> <label for="input-language" class="form-label">
<?= UOJLocale::get('problems::language') ?>: <?= UOJLocale::get('problems::language') ?>
</label> </label>
<select class="form-select form-select-sm" id="input-language" name="language"> <select class="form-select form-select-sm" id="input-language" name="language">
<option value="">All</option> <option value="">All</option>
@ -101,11 +180,29 @@ if (!$conds) {
</select> </select>
</div> </div>
<div class="col-auto"> <div class="col-auto">
<button type="submit" id="submit-search" class="btn btn-secondary btn-sm ml-2"><?= UOJLocale::get('search') ?></button> <button type="submit" id="submit-search" class="btn btn-secondary btn-sm ml-2">
<?= UOJLocale::get('search') ?>
</button>
</div> </div>
</form> </form>
</div> </div>
<?php echoSubmissionsList($conds, 'order by id desc', $config, Auth::user()) ?> <div class="card mb-3">
<div class="list-group list-group-flush">
<?php if ($pag->isEmpty()) : ?>
<div class="list-group-item text-center">
<?= UOJLocale::get('none') ?>
</div>
<?php endif ?>
<?php foreach ($pag->get() as $idx => $row) : ?>
<?php echoSubmissionItem($row) ?>
<?php endforeach ?>
</div>
</div>
<div class="">
<?= $pag->pagination() ?>
</div>
<?php echoUOJPageFooter() ?> <?php echoUOJPageFooter() ?>

View File

@ -188,7 +188,7 @@ class Paginator {
} }
$html = ''; $html = '';
$html .= '<ul class="pagination my-0 justify-content-center">'; $html .= '<ul class="pagination my-0 justify-content-center flex-wrap">';
if ($prev_page !== false) { if ($prev_page !== false) {
$html .= '<li class="page-item"><a class="page-link" href="' . $this->getPageUri(1) . '""><i class="bi bi-chevron-double-left"></i></a></li>'; $html .= '<li class="page-item"><a class="page-link" href="' . $this->getPageUri(1) . '""><i class="bi bi-chevron-double-left"></i></a></li>';
$html .= '<li class="page-item"><a class="page-link" href="' . $this->getPageUri($prev_page) . '"><i class="bi bi-chevron-left"></i></a></li>'; $html .= '<li class="page-item"><a class="page-link" href="' . $this->getPageUri($prev_page) . '"><i class="bi bi-chevron-left"></i></a></li>';

View File

@ -144,6 +144,13 @@ class UOJSubmission {
if ($ret === false) { if ($ret === false) {
unlink(UOJContext::storagePath() . $zip_file_name); unlink(UOJContext::storagePath() . $zip_file_name);
UOJLog::error('submission failed.'); UOJLog::error('submission failed.');
UOJResponse::page500('submission failed.');
return false;
} else {
$id = DB::insert_id();
return $id;
} }
} }
@ -476,6 +483,10 @@ class UOJSubmission {
} }
public function echoStatusBarTD($name, array $cfg) { public function echoStatusBarTD($name, array $cfg) {
$cfg += [
'result_badge' => false,
];
switch ($name) { switch ($name) {
case 'result': case 'result':
if (empty($cfg['no_link'])) { if (empty($cfg['no_link'])) {
@ -497,13 +508,34 @@ class UOJSubmission {
} else { } else {
$actual_score = $this->getActualScore(); $actual_score = $this->getActualScore();
if ($actual_score === null) { if ($actual_score === null) {
echo $tag_st, ' class="small text-decoration-none">', $this->info['result_error'], $tag_ed; if ($cfg['result_badge']) {
echo $tag_st, ' class="fs-5"><span class="badge text-white bg-warning">', $this->info['result_error'], '</span>', $tag_ed;
} else {
echo $tag_st, ' class="small text-decoration-none">', $this->info['result_error'], $tag_ed;
}
} else { } else {
echo $tag_st, ' class="uoj-score text-decoration-none">', $actual_score, $tag_ed; echo $tag_st, ' class="vstack gap-1 d-inline-flex">';
if ($cfg['result_badge']) {
echo '<span class="fs-5">';
if ($actual_score == 100) {
// rgb(0, 204, 0)
echo '<span class="badge text-white bg-success">', 'Accepted', '</span>';
} else {
// rgb(204, 0, 0)
echo '<span class="badge text-white bg-danger">', 'Unaccepted', '</span>';
}
echo '</span>';
}
echo '<span class="uoj-score">', $actual_score, '</span>';
echo $tag_ed;
} }
} }
} else { } else {
echo $tag_st, '" class="small text-decoration-none">', $this->publicStatus(), $tag_ed; if ($cfg['result_badge']) {
echo $tag_st, ' class="fs-5"><span class="badge text-bg-primary">', $this->publicStatus(), '</span>', $tag_ed;
} else {
echo $tag_st, ' class="small text-decoration-none">', $this->publicStatus(), $tag_ed;
}
} }
break; break;
case 'language': case 'language':

View File

@ -255,6 +255,7 @@ trait UOJSubmissionLikeTrait {
$cfg += [ $cfg += [
'time_format' => 'normal', 'time_format' => 'normal',
'time_font_size' => 'small', 'time_font_size' => 'small',
'unknown_char' => '/',
]; ];
switch ($name) { switch ($name) {
@ -275,23 +276,31 @@ trait UOJSubmissionLikeTrait {
break; break;
case 'used_time': case 'used_time':
if ($cfg['show_actual_score']) { if ($cfg['show_actual_score']) {
echo $this->info['used_time'] . ' ms'; if ($this->info['used_time'] < 1000) {
echo $this->info['used_time'] . ' ms';
} else {
echo sprintf("%.2f", $this->info['used_time'] / 1000) . ' s';
}
} else { } else {
echo '/'; echo $cfg['unknown_char'];
} }
break; break;
case 'used_memory': case 'used_memory':
if ($cfg['show_actual_score']) { if ($cfg['show_actual_score']) {
echo $this->info['used_memory'] . ' KB'; if ($this->info['used_memory'] < 1024) {
echo $this->info['used_memory'] . ' KB';
} else {
echo sprintf("%.2f", $this->info['used_memory'] / 1024) . ' MB';
}
} else { } else {
echo '/'; echo $cfg['unknown_char'];
} }
break; break;
case 'tot_size': case 'tot_size':
if ($this->info['tot_size'] < 1024) { if ($this->info['tot_size'] < 1024) {
echo $this->info['tot_size'] . ' B'; echo $this->info['tot_size'] . ' B';
} else { } else {
echo sprintf("%.1f", $this->info['tot_size'] / 1024) . ' KB'; echo sprintf("%.2f", $this->info['tot_size'] / 1024) . ' KB';
} }
break; break;
case 'submit_time': case 'submit_time':