diff --git a/packages/hydrooj/package.json b/packages/hydrooj/package.json index 42f03e5a9..aa70a8aa8 100644 --- a/packages/hydrooj/package.json +++ b/packages/hydrooj/package.json @@ -1,6 +1,6 @@ { "name": "hydrooj", - "version": "2.36.12", + "version": "2.36.13", "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 9cf7ad17c..607285324 100644 --- a/packages/hydrooj/src/handler/user.ts +++ b/packages/hydrooj/src/handler/user.ts @@ -2,18 +2,15 @@ import moment from 'moment-timezone'; import { BlacklistedError, InvalidTokenError, LoginError, SystemError, UserAlreadyExistError, UserFacingError, - UserNotFoundError, VerifyPasswordError, + UserNotFoundError, ValidationError, VerifyPasswordError, } from '../error'; import { User } from '../interface'; import avatar from '../lib/avatar'; import { sendMail } from '../lib/mail'; -import paginate from '../lib/paginate'; import { isEmail, isPassword, isUname } from '../lib/validator'; import BlackListModel from '../model/blacklist'; import { PERM, PRIV } from '../model/builtin'; import oauth from '../model/oauth'; -import problem, { ProblemDoc } from '../model/problem'; -import record from '../model/record'; import * as system from '../model/system'; import task from '../model/task'; import token from '../model/token'; @@ -136,6 +133,7 @@ export class UserRegisterHandler extends Handler { }); await sendMail(mail, 'Sign Up', 'user_register_mail', m); this.response.template = 'user_register_mail_sent.html'; + this.response.body = { mail }; } else this.response.redirect = this.url('user_register_with_code', { code: t[0] }); } else if (phoneNumber) { if (!global.Hydro.lib.sendSms) throw new SystemError('Cannot send sms'); @@ -148,7 +146,7 @@ export class UserRegisterHandler extends Handler { ); await global.Hydro.lib.sendSms(phoneNumber, 'register', t[0]); this.response.template = 'user_register_sms.html'; - } + } else throw new ValidationError('mail'); } } @@ -237,41 +235,19 @@ class UserDetailHandler extends Handler { async get(domainId: string, uid: number) { if (uid === 0) throw new UserNotFoundError(0); const isSelfProfile = this.user._id === uid; - const udoc = await user.getById(domainId, uid); - if (!udoc) throw new UserNotFoundError(uid); - const [sdoc, rdocs, [pdocs, pcount]] = await Promise.all([ + const [udoc, sdoc] = await Promise.all([ + user.getById(domainId, uid), token.getMostRecentSessionByUid(uid), - record.getByUid(domainId, uid, 30), - this.user.hasPerm(PERM.PERM_VIEW_PROBLEM) - ? paginate( - problem.getMulti(domainId, { owner: uid }), - 1, - 100, - ) - : [[], 0, 0] as [ProblemDoc[], number, number], ]); - const pdict = this.user.hasPerm(PERM.PERM_VIEW_PROBLEM) - ? await problem.getList( - domainId, rdocs.map((rdoc) => rdoc.pid), - this.user.hasPerm(PERM.PERM_VIEW_PROBLEM_HIDDEN) || this.user._id, false, - ) - : Object.fromEntries(rdocs.map( - (rdoc) => [rdoc.pid, { ...problem.default, pid: rdoc.pid }], - )); + if (!udoc) throw new UserNotFoundError(uid); // Remove sensitive data if (!isSelfProfile && sdoc) { sdoc.createIp = ''; sdoc.updateIp = ''; sdoc._id = ''; } - const path = [ - ['Hydro', 'homepage'], - ['user_detail', 'user_detail', { uid }], - ]; this.response.template = 'user_detail.html'; - this.response.body = { - isSelfProfile, udoc, sdoc, rdocs, pdocs, pcount, pdict, path, - }; + this.response.body = { isSelfProfile, udoc, sdoc }; this.extraTitleContent = udoc.uname; } } @@ -343,7 +319,6 @@ export async function apply() { Route('user_oauth', '/oauth/:type', OauthHandler); Route('user_oauth_callback', '/oauth/:type/callback', OauthCallbackHandler); Route('user_register', '/register', UserRegisterHandler, PRIV.PRIV_REGISTER_USER); - Route('user_register_without_code', '/register/code', UserRegisterWithCodeHandler, PRIV.PRIV_REGISTER_USER); Route('user_register_with_code', '/register/:code', UserRegisterWithCodeHandler, PRIV.PRIV_REGISTER_USER); Route('user_logout', '/logout', UserLogoutHandler, PRIV.PRIV_USER_PROFILE); Route('user_lostpass', '/lostpass', UserLostPassHandler); diff --git a/packages/hydrooj/src/model/record.ts b/packages/hydrooj/src/model/record.ts index 60c56404b..8973cc3a5 100644 --- a/packages/hydrooj/src/model/record.ts +++ b/packages/hydrooj/src/model/record.ts @@ -219,13 +219,6 @@ class RecordModel { } return r; } - - @ArgMethod - static getByUid(domainId: string, uid: number, limit: number): Promise { - return RecordModel.coll.find({ - domainId, 'contest.tid': null, hidden: false, uid, - }).sort({ _id: -1 }).limit(limit).toArray(); - } } // Mark problem as deleted diff --git a/packages/ui-default/components/message/index.page.js b/packages/ui-default/components/message/index.page.js index ecb878da7..f1e36c807 100644 --- a/packages/ui-default/components/message/index.page.js +++ b/packages/ui-default/components/message/index.page.js @@ -5,7 +5,8 @@ import { FLAG_ALERT } from 'vj/constant/message'; import i18n from 'vj/utils/i18n'; import tpl from 'vj/utils/tpl'; -const messagePage = new AutoloadPage('messagePage', () => { +const messagePage = new AutoloadPage('messagePage', (pagename) => { + if (pagename === 'home_messages') return; let visible = true; document.addEventListener('visibilitychange', () => { const state = document.visibilityState; diff --git a/packages/ui-default/package.json b/packages/ui-default/package.json index a34da3a64..3be8ee378 100644 --- a/packages/ui-default/package.json +++ b/packages/ui-default/package.json @@ -1,6 +1,6 @@ { "name": "@hydrooj/ui-default", - "version": "4.21.9", + "version": "4.21.10", "author": "undefined ", "license": "AGPL-3.0", "main": "hydro.js", diff --git a/packages/ui-default/pages/home_messages.page.jsx b/packages/ui-default/pages/home_messages.page.jsx index 30f0b7979..ec43ef749 100644 --- a/packages/ui-default/pages/home_messages.page.jsx +++ b/packages/ui-default/pages/home_messages.page.jsx @@ -2,7 +2,7 @@ import { NamedPage } from 'vj/misc/Page'; import api, { gql } from 'vj/utils/api'; import loadReactRedux from 'vj/utils/loadReactRedux'; import parseQueryString from 'vj/utils/parseQueryString'; - +import VjNotification from 'vj/components/notification'; import { ActionDialog } from 'vj/components/dialog'; import UserSelectAutoComplete from 'vj/components/autocomplete/UserSelectAutoComplete'; @@ -39,6 +39,13 @@ const page = new NamedPage('home_messages', () => { type: 'DIALOGUES_MESSAGE_PUSH', payload: msg, }); + new VjNotification({ + title: msg.udoc.uname, + avatar: msg.udoc.avatarUrl, + message: msg.mdoc.content, + duration: 15000, + action: () => createDialog(msg.udoc), + }).show(); }; const userSelector = UserSelectAutoComplete.getOrConstruct($('.dialog__body--user-select [name="user"]')); diff --git a/packages/ui-default/templates/user_detail.html b/packages/ui-default/templates/user_detail.html index 9c115158b..74aa2a513 100644 --- a/packages/ui-default/templates/user_detail.html +++ b/packages/ui-default/templates/user_detail.html @@ -46,12 +46,12 @@ {% endif %} {% if udoc['qq'] %} - + {% endif %} {% if udoc['wechat'] %} - + {% endif %} @@ -98,65 +98,6 @@ {% endif %} -
  • -

    {{ _('Contributions') }} ({{ pcount }})

    -
    - {% if not pdocs %} - {{ nothing.render("Oh, the user doesn't have any contributions!") }} - {% else %} -
    -

    {{ _('Contributed Problems') }}

    -
    -
    - {%- for pdoc in pdocs -%} -

    {{ pdoc['title'] }}

    - {%- endfor -%} -
    - {% endif %} -
    -
  • -
  • -

    {{ _('Submissions') }} ({{ udoc['nSubmit']|default(0) }})

    -
    - {% if not rdocs %} - {{ nothing.render("Oh, the user hasn't submitted yet!") }} - {% else %} -
    -

    {{ _('Recent Submissions') }}

    -
    -
    - - - - - - - - - - - - - - - - - - - - - - - {%- for rdoc in rdocs -%} - {% set pdoc = pdict[rdoc.pid] %} - {% include 'record_main_tr.html' %} - {%- endfor -%} - -
    {{ _('Status') }}{{ _('Problem') }}{{ _('Submit By') }}{{ _('Time') }}{{ _('Memory') }}{{ _('Language') }}{{ _('Submit At') }}
    -
    - {% endif %} -
    -
  • @@ -174,6 +115,12 @@