core: contest: scoreboard-view: add advanced checker

This commit is contained in:
undefined committed 2026-07-19 19:44:23 +00:00
1 parent aba8d9c755
commit 06640c90fb
2 files changed
+24 -9

No files matched your search

+10 -6
View File
@@ -825,6 +825,7 @@ export interface ScoreboardView<T extends { [key: string]: keyof BuiltinInput |
cacheTime?: number; // in seconds
args: T;
display: (this: ContestScoreboardHandler, args: ParseArgs<T>) => Promise<void>;
checker?: (this: ContestScoreboardHandler) => boolean;
}
export class ContestScoreboardHandler extends ContestDetailBaseHandler {
@@ -884,16 +885,17 @@ class ScoreboardService extends Service {
addView<T extends { [key: string]: keyof BuiltinInput | AnyFunction | Type<any> }>(
id: string, name: string, args: T,
{ display, supportedRules, cacheTime }: {
{ display, supportedRules, cacheTime, checker }: {
display: (this: ContestScoreboardHandler, args: ParseArgs<T>) => Promise<void>;
supportedRules: string[];
cacheTime?: number;
checker?: (this: ContestScoreboardHandler) => boolean;
},
) {
if (this.views[id]) throw new Error(`View ${id} already exists`);
this.ctx.effect(() => {
this.views[id] = {
id, name, args, display, supportedRules, cacheTime,
id, name, args, display, supportedRules, cacheTime, checker,
};
return () => {
delete this.views[id];
@@ -901,9 +903,11 @@ class ScoreboardService extends Service {
});
}
getAvailableViews(rule: string) {
return Object.fromEntries(Object.values(this.views).filter((i) => i.supportedRules.includes(rule) || i.supportedRules.includes('*'))
.map((i) => [i.id, i.name]));
getAvailableViews(rule: string, handler: ContestScoreboardHandler) {
return Object.fromEntries(Object.values(this.views).filter((i) => (
(i.supportedRules.includes(rule) || i.supportedRules.includes('*'))
&& (!i.checker || i.checker.call(handler))
)).map((i) => [i.id, i.name]));
}
getView(id: string) {
@@ -963,7 +967,7 @@ export async function apply(ctx: Context) {
const page_name = tdoc.rule === 'homework'
? 'homework_scoreboard'
: 'contest_scoreboard';
const availableViews = scoreboard.getAvailableViews(tdoc.rule);
const availableViews = scoreboard.getAvailableViews(tdoc.rule, this);
this.response.body = {
tdoc: this.tdoc, tsdoc: this.tsdocAsPublic(), rows, udict, pdict, page_name, groups, availableViews,
};