mirror of
https://gitcode.com/gh_mirrors/hy/Hydro.git
synced 2026-10-19 01:38:19 +08:00
core&ui: user_detail: show solutions (#414)
This commit is contained in:
1 parent
e3dd65c690
commit
6ed4d74210
8 files changed
+62
-30
No files matched your search
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "hydrooj",
|
||||
"version": "3.16.5",
|
||||
"version": "3.16.6",
|
||||
"bin": "bin/hydrooj.js",
|
||||
"main": "src/loader",
|
||||
"module": "src/loader",
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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() });
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@hydrooj/ui-default",
|
||||
"version": "4.39.15",
|
||||
"version": "4.39.16",
|
||||
"author": "undefined <i@undefined.moe>",
|
||||
"license": "AGPL-3.0",
|
||||
"main": "hydro.js",
|
||||
|
||||
@@ -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;
|
||||
@@ -0,0 +1,29 @@
|
||||
{% if psdocs %}
|
||||
<li class="section__tab-item">
|
||||
<h1 class="section__tab-title">{{ _('Recent solutions') }}</h1>
|
||||
<div class="section__tab-main">
|
||||
{% if not psdocs.length %}
|
||||
{{ nothing.render("This person is lazy and wrote any solution") }}
|
||||
{% else %}
|
||||
<div class="section__body typo no-media">
|
||||
<div class="typo section__body">
|
||||
{% set _mark = Math.ceil(psdocs.length/4) %}
|
||||
{% macro col(psdocs) %}
|
||||
<div class="medium-3 columns"><ul>
|
||||
{% for psdoc in psdocs %}
|
||||
<li><a href="{{ url('problem_solution_detail', pid=psdoc.parentId, sid=psdoc._id) }}">{{ pdict[psdoc.parentId].title|default(psdoc._id) }}</a></li>
|
||||
{% endfor %}
|
||||
</ul></div>
|
||||
{% endmacro %}
|
||||
<div class="row">
|
||||
{{ col(psdocs.slice(0, _mark)) }}
|
||||
{{ col(psdocs.slice(_mark, _mark*2)) }}
|
||||
{{ col(psdocs.slice(_mark*2, _mark*3)) }}
|
||||
{{ col(psdocs.slice(_mark*3)) }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
</li>
|
||||
{% endif %}
|
||||
@@ -125,7 +125,7 @@
|
||||
</div>
|
||||
</li>
|
||||
{% endif %}
|
||||
{% for page in findSubModule('user_detail/') %}{% include page %}{% endfor %}
|
||||
{% for page in findSubModule('partials/user_detail/') %}{% include page %}{% endfor %}
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in new issue
Block a user