From 6ed4d74210c1b4411d99070bfe2579dccd28acc3 Mon Sep 17 00:00:00 2001 From: undefined Date: Mon, 29 Aug 2022 15:41:50 +0800 Subject: [PATCH] core&ui: user_detail: show solutions (#414) --- packages/hydrooj/package.json | 2 +- packages/hydrooj/src/handler/user.ts | 11 +++++++ packages/hydrooj/src/model/solution.ts | 7 +++++ .../ui-default/components/clipboard.page.ts | 16 +++++++--- packages/ui-default/package.json | 2 +- packages/ui-default/pages/user_detail.page.js | 23 --------------- .../partials/user_detail/solution.html | 29 +++++++++++++++++++ .../ui-default/templates/user_detail.html | 2 +- 8 files changed, 62 insertions(+), 30 deletions(-) delete mode 100644 packages/ui-default/pages/user_detail.page.js create mode 100644 packages/ui-default/templates/partials/user_detail/solution.html diff --git a/packages/hydrooj/package.json b/packages/hydrooj/package.json index 96be28033..522aad93a 100644 --- a/packages/hydrooj/package.json +++ b/packages/hydrooj/package.json @@ -1,6 +1,6 @@ { "name": "hydrooj", - "version": "3.16.5", + "version": "3.16.6", "bin": "bin/hydrooj.js", "main": "src/loader", "module": "src/loader", diff --git a/packages/hydrooj/src/handler/user.ts b/packages/hydrooj/src/handler/user.ts index bb0d7a2c0..abf7c38ea 100644 --- a/packages/hydrooj/src/handler/user.ts +++ b/packages/hydrooj/src/handler/user.ts @@ -16,6 +16,7 @@ import domain from '../model/domain'; import oauth from '../model/oauth'; import * as oplog from '../model/oplog'; import problem, { ProblemDoc } from '../model/problem'; +import SolutionModel from '../model/solution'; import * as system from '../model/system'; import task from '../model/task'; import token from '../model/token'; @@ -323,6 +324,16 @@ class UserDetailHandler extends Handler { this.response.body = { isSelfProfile, udoc, sdoc, pdocs, tags, }; + if (this.user.hasPerm(PERM.PERM_VIEW_PROBLEM_SOLUTION)) { + const psdocs = await SolutionModel.getByUser(domainId, uid).limit(10).toArray(); + this.response.body.psdocs = psdocs; + if (this.user.hasPerm(PERM.PERM_VIEW_PROBLEM)) { + this.response.body.pdict = await problem.getList( + domainId, psdocs.map((i) => i.parentId), canViewHidden, + this.user.group, false, problem.PROJECTION_LIST, + ); + } + } this.UiContext.extraTitleContent = udoc.uname; } } diff --git a/packages/hydrooj/src/model/solution.ts b/packages/hydrooj/src/model/solution.ts index 4de9555fa..81902f19f 100644 --- a/packages/hydrooj/src/model/solution.ts +++ b/packages/hydrooj/src/model/solution.ts @@ -46,6 +46,13 @@ class SolutionModel { ).sort({ vote: -1 }); } + static getByUser(domainId: string, uid: number) { + return document.getMulti( + domainId, document.TYPE_PROBLEM_SOLUTION, + { parentType: document.TYPE_PROBLEM, owner: uid }, + ).sort({ _id: -1 }); + } + static reply(domainId: string, psid: ObjectID, owner: number, content: string) { return document.push(domainId, document.TYPE_PROBLEM_SOLUTION, psid, 'reply', content, owner); } diff --git a/packages/ui-default/components/clipboard.page.ts b/packages/ui-default/components/clipboard.page.ts index a4f0fbfe4..9d19d5c72 100644 --- a/packages/ui-default/components/clipboard.page.ts +++ b/packages/ui-default/components/clipboard.page.ts @@ -1,13 +1,21 @@ import Clipboard from 'clipboard'; import Notification from 'vj/components/notification'; import { AutoloadPage } from 'vj/misc/Page'; +import base64 from 'vj/utils/base64'; import i18n from 'vj/utils/i18n'; +import substitute from 'vj/utils/substitute'; export default new AutoloadPage('clipboard', () => { - $('[data-copy]').each(function () { - const clip = new Clipboard(this, { text: () => this.dataset.copy }); - clip.on('success', () => Notification.success(i18n('Copied to clipboard!'))); - clip.on('error', () => Notification.error(i18n('Copy failed :('))); + $('[data-copy]').get().forEach((el) => { + const data = $(el).attr('data-copy'); + const decoded = base64.decode(data); + const clip = new Clipboard(el, { text: () => decoded }); + clip.on('success', () => { + Notification.success(substitute(i18n('"{data}" copied to clipboard!'), { data: decoded }), 2000); + }); + clip.on('error', () => { + Notification.error(substitute(i18n('Copy "{data}" failed :('), { data: decoded })); + }); }); $('[data-copylink]').each(function () { const clip = new Clipboard(this, { text: () => new URL(this.dataset.copylink, document.location.href).toString() }); diff --git a/packages/ui-default/package.json b/packages/ui-default/package.json index a7933e0d4..21cbc1436 100644 --- a/packages/ui-default/package.json +++ b/packages/ui-default/package.json @@ -1,6 +1,6 @@ { "name": "@hydrooj/ui-default", - "version": "4.39.15", + "version": "4.39.16", "author": "undefined ", "license": "AGPL-3.0", "main": "hydro.js", diff --git a/packages/ui-default/pages/user_detail.page.js b/packages/ui-default/pages/user_detail.page.js deleted file mode 100644 index 27c57effd..000000000 --- a/packages/ui-default/pages/user_detail.page.js +++ /dev/null @@ -1,23 +0,0 @@ -import Clipboard from 'clipboard'; -import $ from 'jquery'; -import Notification from 'vj/components/notification'; -import { NamedPage } from 'vj/misc/Page'; -import base64 from 'vj/utils/base64'; -import i18n from 'vj/utils/i18n'; -import substitute from 'vj/utils/substitute'; - -const page = new NamedPage('user_detail', () => { - $('[data-copy]').get().forEach((el) => { - const data = $(el).attr('data-copy'); - const decoded = base64.decode(data); - const clip = new Clipboard(el, { text: () => decoded }); - clip.on('success', () => { - Notification.success(substitute(i18n('"{data}" copied to clipboard!'), { data: decoded }), 2000); - }); - clip.on('error', () => { - Notification.error(substitute(i18n('Copy "{data}" failed :('), { data: decoded })); - }); - }); -}); - -export default page; diff --git a/packages/ui-default/templates/partials/user_detail/solution.html b/packages/ui-default/templates/partials/user_detail/solution.html new file mode 100644 index 000000000..327369ef3 --- /dev/null +++ b/packages/ui-default/templates/partials/user_detail/solution.html @@ -0,0 +1,29 @@ +{% if psdocs %} +
  • +

    {{ _('Recent solutions') }}

    +
    + {% if not psdocs.length %} + {{ nothing.render("This person is lazy and wrote any solution") }} + {% else %} +
    +
    + {% set _mark = Math.ceil(psdocs.length/4) %} + {% macro col(psdocs) %} +
    + {% endmacro %} +
    + {{ col(psdocs.slice(0, _mark)) }} + {{ col(psdocs.slice(_mark, _mark*2)) }} + {{ col(psdocs.slice(_mark*2, _mark*3)) }} + {{ col(psdocs.slice(_mark*3)) }} +
    +
    +
    + {% endif %} +
    +
  • +{% endif %} \ No newline at end of file diff --git a/packages/ui-default/templates/user_detail.html b/packages/ui-default/templates/user_detail.html index 8c0b1556b..437ad4143 100644 --- a/packages/ui-default/templates/user_detail.html +++ b/packages/ui-default/templates/user_detail.html @@ -125,7 +125,7 @@ {% endif %} - {% for page in findSubModule('user_detail/') %}{% include page %}{% endfor %} + {% for page in findSubModule('partials/user_detail/') %}{% include page %}{% endfor %}