ui: media: support contest

pull/162/head
undefined 3 years ago
parent 675e28abc5
commit 70abfd2595

@ -8,7 +8,7 @@ export default new AutoloadPage('media', async () => {
const users = $dom.find('div[data-user]'); const users = $dom.find('div[data-user]');
const resolve = (ele, item) => { const resolve = (ele, item) => {
items.push(item); items.push(item);
resolvers.push((html) => $(ele).replaceWith($(html))); resolvers.push((html) => html && $(ele).replaceWith($(html)));
}; };
users.get().forEach((ele) => resolve(ele, { type: 'user', id: +$(ele).text() })); users.get().forEach((ele) => resolve(ele, { type: 'user', id: +$(ele).text() }));
$dom.find('.typo').get().forEach((el) => { $dom.find('.typo').get().forEach((el) => {
@ -30,6 +30,7 @@ export default new AutoloadPage('media', async () => {
if (!data) return; if (!data) return;
if (category === 'user' && Number.isInteger(+data) && !extra) resolve(ele, { type: 'user', id: +data }); if (category === 'user' && Number.isInteger(+data) && !extra) resolve(ele, { type: 'user', id: +data });
if (category === 'p' && !extra) resolve(ele, { type: 'problem', id: data, domainId }); if (category === 'p' && !extra) resolve(ele, { type: 'problem', id: data, domainId });
if (category === 'contest' && !extra) resolve(ele, { type: 'contest', id: data, domainId });
}); });
}); });
if (!items.length) return; if (!items.length) return;

@ -4,12 +4,13 @@ const { readdirSync, readFileSync } = require('fs');
const { join } = require('path'); const { join } = require('path');
const crypto = require('crypto'); const crypto = require('crypto');
const { tmpdir } = require('os'); const { tmpdir } = require('os');
const { ObjectID } = require('mongodb');
const bus = require('hydrooj/dist/service/bus'); const bus = require('hydrooj/dist/service/bus');
const { PERM } = require('hydrooj/dist/model/builtin'); const { PERM } = require('hydrooj/dist/model/builtin');
const markdown = require('./backendlib/markdown'); const markdown = require('./backendlib/markdown');
const { const {
system, domain, user, setting, problem, system, domain, user, setting, problem, contest,
} = global.Hydro.model; } = global.Hydro.model;
const { Route, Handler, UiContextBase } = global.Hydro.service.server; const { Route, Handler, UiContextBase } = global.Hydro.service.server;
@ -132,18 +133,28 @@ class RichMediaHandler extends Handler {
async renderProblem(domainId, payload) { async renderProblem(domainId, payload) {
const cur = payload.domainId ? await user.getById(payload.domainId, this.user._id) : this.user; const cur = payload.domainId ? await user.getById(payload.domainId, this.user._id) : this.user;
let pdoc = cur.hasPerm(PERM.PERM_VIEW | PERM.PERM_VIEW_PROBLEM) let pdoc = cur.hasPerm(PERM.PERM_VIEW | PERM.PERM_VIEW_PROBLEM)
? await problem.get(domainId, payload.id) || problem.default ? await problem.get(payload.domainId || domainId, payload.id) || problem.default
: problem.default; : problem.default;
if (pdoc.hidden && !cur.own(pdoc) && !cur.hasPerm(PERM.PERM_VIEW_PROBLEM_HIDDEN)) pdoc = problem.default; if (pdoc.hidden && !cur.own(pdoc) && !cur.hasPerm(PERM.PERM_VIEW_PROBLEM_HIDDEN)) pdoc = problem.default;
return await this.renderHTML('partials/problem.html', { pdoc }); return await this.renderHTML('partials/problem.html', { pdoc });
} }
async renderContest(domainId, payload) {
const cur = payload.domainId ? await user.getById(payload.domainId, this.user._id) : this.user;
const tdoc = cur.hasPerm(PERM.PERM_VIEW | PERM.PERM_VIEW_CONTEST)
? await contest.get(payload.domainId || domainId, new ObjectID(payload.id))
: null;
if (tdoc) return await this.renderHTML('partials/contest.html', { tdoc });
return '';
}
async post({ domainId, items }) { async post({ domainId, items }) {
const res = []; const res = [];
for (const item of items) { for (const item of items) {
if (item.domainId && item.domainId === domainId) delete item.domainId; if (item.domainId && item.domainId === domainId) delete item.domainId;
if (item.type === 'user') res.push(this.renderUser(domainId, item)); if (item.type === 'user') res.push(this.renderUser(domainId, item).catch(() => ''));
else if (item.type === 'problem') res.push(this.renderProblem(domainId, item)); else if (item.type === 'problem') res.push(this.renderProblem(domainId, item).catch(() => ''));
else if (item.type === 'contest') res.push(this.renderContest(domainId, item).catch(() => ''));
else res.push(''); else res.push('');
} }
this.response.body = await Promise.all(res); this.response.body = await Promise.all(res);

@ -252,7 +252,8 @@ small, figcaption
.typo a, .typo .link, .typo-a .typo a, .typo .link, .typo-a
&, &:visited, &:active, &:hover &, &:visited, &:active, &:hover
&:not(.user-profile-name) &:not(.user-profile-name)
color: $primary-color &:not(.media-link)
color: $primary-color
.typo dl, .typo form, .typo hr, .typo table .typo dl, .typo form, .typo hr, .typo table
padding-top: 0.3em padding-top: 0.3em

@ -1,6 +1,6 @@
{ {
"name": "@hydrooj/ui-default", "name": "@hydrooj/ui-default",
"version": "4.12.11", "version": "4.12.12",
"author": "undefined <i@undefined.moe>", "author": "undefined <i@undefined.moe>",
"license": "AGPL-3.0", "license": "AGPL-3.0",
"main": "hydro.js", "main": "hydro.js",
@ -121,6 +121,7 @@
"markdown-it-mark": "^3.0.1", "markdown-it-mark": "^3.0.1",
"markdown-it-merge-cells": "^1.0.1", "markdown-it-merge-cells": "^1.0.1",
"markdown-it-table-of-contents": "^0.5.2", "markdown-it-table-of-contents": "^0.5.2",
"mongodb": "^3.6.9",
"nunjucks": "^3.2.3", "nunjucks": "^3.2.3",
"streamsaver": "^2.0.5", "streamsaver": "^2.0.5",
"xss": "^1.0.9" "xss": "^1.0.9"

@ -0,0 +1,3 @@
<a class="discussion-node-tag media-link" href="{{ url('contest_detail', domainId=tdoc.domainId, tid=tdoc.docId) }}">
<span class="v-center icon icon-award"></span>{{ tdoc.title }}
</a>

@ -1,2 +1,2 @@
{% import "components/user.html" as user with context %} {% import "components/user.html" as user with context %}
{{ user.render_inline(udoc) }} {{ user.render_inline(udoc, badge=false) }}
Loading…
Cancel
Save