Skip to content

Commit 792267b

Browse files
committed
core&ui: add keep scoreboard hidden option
1 parent 6e17062 commit 792267b

8 files changed

Lines changed: 30 additions & 26 deletions

File tree

package.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -47,16 +47,16 @@
4747
"eslint-import-resolver-typescript": "^4.4.4",
4848
"eslint-import-resolver-webpack": "^0.13.11",
4949
"fs-extra": "^11.3.4",
50-
"globals": "^17.4.0",
50+
"globals": "^17.5.0",
5151
"globby": "~14.0.2",
5252
"inspectpack": "^4.7.1",
5353
"mongodb-memory-server": "11.0.1",
5454
"nyc": "^18.0.0",
5555
"ora": "^9.3.0",
56-
"oxlint": "^1.58.0",
56+
"oxlint": "^1.60.0",
5757
"package-json": "^10.0.1",
5858
"semver": "^7.7.4",
59-
"simple-git": "^3.33.0",
59+
"simple-git": "^3.36.0",
6060
"supertest": "^7.2.2",
6161
"supports-hyperlinks": "^4.4.0",
6262
"typescript": "5.8.3",

packages/hydrooj/src/handler/contest.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -403,12 +403,14 @@ export class ContestEditHandler extends Handler {
403403
@param('maintainer', Types.NumericArray, true)
404404
@param('allowViewCode', Types.Boolean)
405405
@param('allowPrint', Types.Boolean)
406+
@param('keepScoreboardHidden', Types.Boolean)
406407
@param('langs', Types.CommaSeperatedArray, true)
407408
async postUpdate(
408409
domainId: string, tid: ObjectId, beginAtDate: string, beginAtTime: string, duration: number,
409410
title: string, content: string, rule: string, _pids: string, rated = false,
410411
_code = '', autoHide = false, assign: string[] = [], lock: number = null,
411-
contestDuration: number = null, maintainer: number[] = [], allowViewCode = false, allowPrint = false, langs: string[] = [],
412+
contestDuration: number = null, maintainer: number[] = [], allowViewCode = false, allowPrint = false,
413+
keepScoreboardHidden = false, langs: string[] = [],
412414
) {
413415
if (!Object.keys(contest.RULES).includes(rule) || contest.RULES[rule].hidden) throw new ValidationError('rule');
414416
if (autoHide) this.checkPerm(PERM.PERM_EDIT_PROBLEM);
@@ -450,7 +452,7 @@ export class ContestEditHandler extends Handler {
450452
});
451453
}
452454
await contest.edit(domainId, tid, {
453-
assign, _code, autoHide, lockAt, maintainer, allowViewCode, allowPrint, langs,
455+
assign, _code, autoHide, lockAt, maintainer, allowViewCode, allowPrint, keepScoreboardHidden, langs,
454456
});
455457
this.response.body = { tid };
456458
this.response.redirect = this.url('contest_detail', { tid });

packages/hydrooj/src/interface.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -268,6 +268,7 @@ export interface Tdoc extends Document {
268268
privateFiles?: FileInfo[];
269269
allowViewCode?: boolean;
270270
allowPrint?: boolean;
271+
keepScoreboardHidden?: boolean;
271272

272273
// For contest
273274
lockAt?: Date;

packages/hydrooj/src/model/contest.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -312,9 +312,9 @@ const oi = buildContestRule({
312312
}
313313
return { score, detail, display };
314314
},
315-
showScoreboard: (tdoc, now) => now > tdoc.endAt,
316-
showSelfRecord: (tdoc, now) => now > tdoc.endAt,
317-
showRecord: (tdoc, now) => now > tdoc.endAt,
315+
showScoreboard: (tdoc, now) => now > tdoc.endAt && !tdoc.keepScoreboardHidden,
316+
showSelfRecord: (tdoc, now) => now > tdoc.endAt && !tdoc.keepScoreboardHidden,
317+
showRecord: (tdoc, now) => now > tdoc.endAt && !tdoc.keepScoreboardHidden,
318318
async scoreboardHeader(config, _, tdoc, pdict) {
319319
const columns: ScoreboardNode[] = [
320320
{ type: 'rank', value: '#' },
@@ -477,9 +477,9 @@ const ioi = buildContestRule({
477477
const strictioi = buildContestRule({
478478
TEXT: 'IOI(Strict)',
479479
submitAfterAccept: false,
480-
showRecord: (tdoc, now) => now > tdoc.endAt,
481-
showSelfRecord: () => true,
482-
showScoreboard: (tdoc, now) => now > tdoc.endAt,
480+
showRecord: (tdoc, now) => now > tdoc.endAt && !tdoc.keepScoreboardHidden,
481+
showSelfRecord: (tdoc) => !tdoc.keepScoreboardHidden || !isDone(tdoc),
482+
showScoreboard: (tdoc, now) => now > tdoc.endAt && !tdoc.keepScoreboardHidden,
483483
stat(tdoc, journal) {
484484
const detail = {};
485485
let score = 0;

packages/onsite-toolkit/index.ts

Lines changed: 3 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
import { LRUCache } from 'lru-cache';
33
import moment from 'moment';
44
import {
5-
_, avatar, BadRequestError, ContestModel, ContestNotEndedError, Context, db, findFileSync,
5+
_, avatar, ContestModel, ContestNotEndedError, Context, db, findFileSync,
66
ForbiddenError, fs, Handler, InvalidTokenError, ObjectId, param, parseTimeMS, PERM, ProblemConfig, ProblemModel,
77
randomstring, Schema, SettingModel, STATUS, STATUS_SHORT_TEXTS, STATUS_TEXTS,
88
SystemModel, TokenModel, Types, UserModel, Zip,
@@ -89,12 +89,6 @@ export function apply(ctx: Context, config: ReturnType<typeof Config>) {
8989
});
9090

9191
async function generateCdpZip(tdoc) {
92-
const serverUrl = SystemModel.get('server.url');
93-
try {
94-
new URL(serverUrl);
95-
} catch (e) {
96-
throw new BadRequestError('Server URL not set');
97-
}
9892
let token = 0;
9993
const getFeed = (type: string, data: any) => ({
10094
type, id: data.id, data, token: `t${token++}`,
@@ -168,7 +162,7 @@ export function apply(ctx: Context, config: ReturnType<typeof Config>) {
168162
group_ids: i.group.map((j) => groupId[j]),
169163
organization_id: orgId[i.organization],
170164
photo: [{ href: `contest/${tdoc._id}/teams/${i.team_id}/photo`, filename: 'photo.png', mime: 'image/png', width: 1920, height: 1080 }],
171-
logo: [{ href: new URL(i.avatar, serverUrl).toString(), filename: 'logo.webp', mime: 'image/webp', width: 128, height: 128 }],
165+
logo: [{ href: new URL(i.avatar, SystemModel.get('server.url')).toString(), filename: 'logo.webp', mime: 'image/webp', width: 128, height: 128 }],
172166
})),
173167
...tdoc.pids.map((i, idx) => getFeed('problems', {
174168
id: `${i}`, label: String.fromCharCode(65 + idx), name: pdict[i].title, ordinal: idx,
@@ -268,17 +262,11 @@ export function apply(ctx: Context, config: ReturnType<typeof Config>) {
268262
async display({ tdoc }) {
269263
if (!this.user.own(tdoc)) this.checkPerm(PERM.PERM_EDIT_CONTEST);
270264
if (!ContestModel.isDone(tdoc)) throw new ContestNotEndedError();
271-
const serverUrl = SystemModel.get('server.url');
272-
try {
273-
new URL(serverUrl);
274-
} catch (e) {
275-
throw new BadRequestError('Server URL not set');
276-
}
277265
const [tokenId] = await TokenModel.add(
278266
TokenModel.TYPE_EXPORT, 600,
279267
{ domainId: tdoc.domainId, contestId: tdoc._id },
280268
);
281-
const source = new URL(`/d/${tdoc.domainId}/contest/${tdoc._id}/resolver-cdp/${tokenId}`, serverUrl).toString();
269+
const source = new URL(`/d/${tdoc.domainId}/contest/${tdoc._id}/resolver-cdp/${tokenId}`, SystemModel.get('server.url')).toString();
282270
const target = new URL('https://resolver.hydrooj.com');
283271
target.searchParams.set('source', source);
284272
target.searchParams.set('mode', tdoc.rule === 'oi' ? 'oi' : 'acm');

packages/ui-default/locales/zh.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -419,6 +419,7 @@ Forgot Password and/or Username: 忘记密码和/或用户名
419419
Forgot password or username?: 忘记密码或者用户名?
420420
Formula blocks: 公式区块
421421
Freeze scoreboard with N minutes remaining: 在赛事剩余N分钟时封榜
422+
Keep scoreboard hidden even after contest ends: 即使比赛结束后也保持成绩表隐藏
422423
fs_upload: 上传文件
423424
Gender Visibility: 性别可见性
424425
Gender: 性别

packages/ui-default/locales/zh_TW.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -418,6 +418,7 @@ Forgot Password and/or Username: 忘記密碼和/或使用者名稱
418418
Forgot password or username?: 忘記密碼或者使用者名?
419419
Formula blocks: 公式區塊
420420
Freeze scoreboard with N minutes remaining: 在賽事剩餘N分鐘時封榜
421+
Keep scoreboard hidden even after contest ends: 即使比賽結束後也保持成績表隱藏
421422
fs_upload: 上傳檔案
422423
Gender Visibility: 性別可見性
423424
Gender: 性別

packages/ui-default/templates/contest_edit.html

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,17 @@ <h2 class="section__title">{{ _('Contest Settings') }}</h2>
174174
value:tdoc.allowPrint|default(false),
175175
row:false
176176
}) }}
177+
<div style="display: none" class="contest-rule-settings contest-rule--oi contest-rule--strictioi">
178+
{{ form.form_checkbox({
179+
columns:4,
180+
label:'Keep Scoreboard Hidden',
181+
name:'keepScoreboardHidden',
182+
placeholder:_('Keep scoreboard hidden even after contest ends'),
183+
value:tdoc.keepScoreboardHidden|default(false),
184+
disabled:true,
185+
row:false
186+
}) }}
187+
</div>
177188
<div style="display: none" class="contest-rule-settings contest-rule--acm contest-rule--ioi">
178189
{{ form.form_text({
179190
columns:4,

0 commit comments

Comments
 (0)