diff --git a/package.json b/package.json index 234210f1c..45f2131a9 100644 --- a/package.json +++ b/package.json @@ -7,7 +7,7 @@ "main": "package.json", "scripts": { "build": "node build/prepare.js && tsc -b", - "build:watch": "node build/build.js && tsc -b --watch", + "build:watch": "node build/prepare.js && tsc -b --watch", "build:ui": "node packages/ui-default/build", "build:ui:dev": "node packages/ui-default/build --dev", "build:ui:production": "node packages/ui-default/build --production", diff --git a/packages/hydrooj/locales/ko.yaml b/packages/hydrooj/locales/ko.yaml index ce9c1da7c..d5bd55a77 100644 --- a/packages/hydrooj/locales/ko.yaml +++ b/packages/hydrooj/locales/ko.yaml @@ -35,7 +35,6 @@ __langname: 한국어 'Role {1} already exists in domain {0}.': '역할 {1}이(가) 이미 {0}에 존재합니다.' 'Solved {0} problems, RP: {1} (No. {2})': '총 {0} 문제 해결.RP: {1} (No. {2})' 'The value `{1}` of {0} already exists.': '{0} 의 값 `{1}` 이 이미 존재합니다.' -'We use Gravatar to present your avatar icon.': 'Gravatar를 만들어 보세요.' 'Yes': 예 "Effects only when Difficulty is not 'Use algorithm calculated'.": 난이도가 알고리즘에 의해 정해지지 않은 경우에만 적용됩니다. "Split by ', '.": “, ”“,”으로 구분 @@ -312,7 +311,6 @@ Formula blocks: 공식 블록 fs_upload: 업로드 Gender Visibility: 성별 공개 Gender: 성 -Gravatar Email: Gravatar 이메일 Hard Deadline: 마감일 Hash: 해시 Have ALL PERMISSIONS in this domain: 이 그룹에 대한 모든 권한 diff --git a/packages/hydrooj/locales/zh.yaml b/packages/hydrooj/locales/zh.yaml index 45b8a0f63..ef2b0d355 100644 --- a/packages/hydrooj/locales/zh.yaml +++ b/packages/hydrooj/locales/zh.yaml @@ -35,7 +35,6 @@ __langname: 简体中文 'Role {1} already exists in domain {0}.': '域 {0} 中已存在角色 {1}。' 'Solved {0} problems, RP: {1} (No. {2})': '解决了 {0} 道题目,RP: {1} (No. {2})' 'The value `{1}` of {0} already exists.': '{0} 的值 `{1}` 已经存在。' -'We use Gravatar to present your avatar icon.': '我们使用 Gravatar 服务来呈现您的头像。' 'Yes': 是 "Effects only when Difficulty is not 'Use algorithm calculated'.": 仅当难度不为“使用算法计算”时才起效。 "Split by ',' '.'": 由“, ”或“,”分隔。 @@ -81,6 +80,7 @@ Attend Contest: 参加比赛 Attend contests: 参加比赛 Attended: 已参加 author: 作者 +Avatar: 头像 Be Copied: 被复制 Begin at: 开始于 Begin Date: 开始日期 @@ -326,7 +326,6 @@ Formula blocks: 公式区块 fs_upload: 上传文件 Gender Visibility: 性别可见性 Gender: 性别 -Gravatar Email: Gravatar Email 地址 Hard Deadline: 最终截止时间 Hash: 散列 Have ALL PERMISSIONS in this domain: 在此域中拥有全部权限 diff --git a/packages/hydrooj/locales/zh_TW.yaml b/packages/hydrooj/locales/zh_TW.yaml index 2392851c0..f1616a512 100644 --- a/packages/hydrooj/locales/zh_TW.yaml +++ b/packages/hydrooj/locales/zh_TW.yaml @@ -195,7 +195,6 @@ Forgot password or username?: 忘記密碼或者使用者名? Formula blocks: 公式區塊 Gender Visibility: 性別可見性 Gender: 性別 -Gravatar Email: Gravatar Email 地址 Hard Deadline: 最終截止時間 Have ALL PERMISSIONS in this domain: 在此域中擁有全部許可權 Help: 幫助 @@ -539,7 +538,6 @@ Visible to registered users: 對註冊使用者可見 Visit: 檢視 Vote problem solutions: 為題解投票 Vote: 投票 -We use Gravatar to present your avatar icon.: 我們使用 Gravatar 服務來呈現您的頭像。 We will check code similarity after this contest.: 我們會在賽後檢查程式碼相似度。 WeChat Visibility: 微信可見性 WeChat: 微信 diff --git a/packages/hydrooj/package.json b/packages/hydrooj/package.json index 75099f9d0..d61e920e4 100644 --- a/packages/hydrooj/package.json +++ b/packages/hydrooj/package.json @@ -1,6 +1,6 @@ { "name": "hydrooj", - "version": "2.23.6", + "version": "2.23.7", "bin": "bin/hydrooj.js", "main": "dist/loader.js", "typings": "dist/loader.d.ts", diff --git a/packages/hydrooj/src/entry/common.ts b/packages/hydrooj/src/entry/common.ts index b0389da5c..8f0663ce8 100644 --- a/packages/hydrooj/src/entry/common.ts +++ b/packages/hydrooj/src/entry/common.ts @@ -13,6 +13,7 @@ export const builtinLib = [ 'jwt', 'download', 'i18n', 'mail', 'useragent', 'crypto', 'misc', 'paginate', 'hash.hydro', 'rank', 'validator', 'ui', 'testdataConfig', 'difficulty', 'content', + 'avatar', ]; export const builtinModel = [ diff --git a/packages/hydrooj/src/handler/domain.ts b/packages/hydrooj/src/handler/domain.ts index a2eec10b9..ee65f4e8d 100644 --- a/packages/hydrooj/src/handler/domain.ts +++ b/packages/hydrooj/src/handler/domain.ts @@ -14,7 +14,7 @@ import { DOMAIN_SETTINGS, DOMAIN_SETTINGS_BY_KEY } from '../model/setting'; import { DEFAULT_NODES, PERM, PERMS_BY_FAMILY, PRIV, } from '../model/builtin'; -import { gravatar } from '../lib/misc'; +import avatar from '../lib/avatar'; import paginate from '../lib/paginate'; import { Route, Handler, Types, param, query, post, @@ -297,7 +297,7 @@ class DomainSearchHandler extends Handler { async get(domainId: string, q: string) { const ddocs = await domain.getPrefixSearch(q, 20); for (let i = 0; i < ddocs.length; i++) { - ddocs[i].gravatar = ddocs[i].gravatar ? gravatar(ddocs[i].gravatar) : '/img/team_avatar.png'; + ddocs[i].avatarUrl = ddocs[i].avatar ? avatar(ddocs[i].avatar, 64) : '/img/team_avatar.png'; } this.response.body = ddocs; } diff --git a/packages/hydrooj/src/handler/home.ts b/packages/hydrooj/src/handler/home.ts index 78fb16a56..35ec353a0 100644 --- a/packages/hydrooj/src/handler/home.ts +++ b/packages/hydrooj/src/handler/home.ts @@ -10,8 +10,9 @@ import * as bus from '../service/bus'; import { Route, Connection, Handler, ConnectionHandler, param, Types, } from '../service/server'; -import * as misc from '../lib/misc'; import { md5 } from '../lib/crypto'; +import { isPassword, isEmail } from '../lib/validator'; +import avatar from '../lib/avatar'; import * as mail from '../lib/mail'; import * as contest from '../model/contest'; import message from '../model/message'; @@ -24,7 +25,6 @@ import * as discussion from '../model/discussion'; import token from '../model/token'; import * as training from '../model/training'; import { PERM, PRIV } from '../model/builtin'; -import { isPassword, isEmail } from '../lib/validator'; const { geoip, useragent } = global.Hydro.lib; @@ -309,13 +309,13 @@ class HomeDomainCreateHandler extends Handler { @param('id', Types.Name) @param('name', Types.Title) @param('bulletin', Types.Content) - @param('gravatar', Types.Content, true, isEmail) - async post(_: string, id: string, name: string, bulletin: string, gravatar: string) { + @param('avatar', Types.Content, true, isEmail) + async post(_: string, id: string, name: string, bulletin: string, avatar: string) { const doc = await domain.get(id); if (doc) throw new DomainAlreadyExistsError(id); - gravatar = gravatar || this.user.gravatar || this.user.mail || 'guest@hydro.local'; + avatar = avatar || this.user.avatar || `gravatar:${this.user.mail}` || 'gravatar:guest@hydro.local'; const domainId = await domain.add(id, this.user._id, name, bulletin); - await domain.edit(domainId, { gravatar }); + await domain.edit(domainId, { avatar }); await domain.setUserRole(domainId, this.user._id, 'root'); this.response.redirect = this.url('domain_dashboard', { domainId }); this.response.body = { domainId }; @@ -338,7 +338,7 @@ class HomeMessagesHandler extends Handler { if (!parsed[target]) { parsed[target] = { _id: target, - udoc: { ...udict[target], gravatar: misc.gravatar(udict[target].gravatar) }, + udoc: { ...udict[target], avatarUrl: avatar(udict[target].avatar) }, messages: [], }; } @@ -358,7 +358,7 @@ class HomeMessagesHandler extends Handler { async postSend(domainId: string, uid: number, content: string) { const udoc = await user.getById('system', uid); if (!udoc) throw new UserNotFoundError(uid); - if (udoc.gravatar) udoc.gravatar = misc.gravatar(udoc.gravatar); + if (udoc.avatar) udoc.avatarUrl = avatar(udoc.avatar); const mdoc = await message.send(this.user._id, uid, content, message.FLAG_UNREAD); this.back({ mdoc, udoc }); } @@ -391,7 +391,7 @@ class HomeMessagesConnectionHandler extends ConnectionHandler { async onMessageReceived(uid: number, mdoc: Mdoc) { if (uid !== this.user._id) return; const udoc = await user.getById(this.domainId, mdoc.from); - udoc.gravatar_url = misc.gravatar(udoc.gravatar, 64); + udoc.avatarUrl = avatar(udoc.avatar, 64); this.send({ udoc, mdoc }); } diff --git a/packages/hydrooj/src/handler/user.ts b/packages/hydrooj/src/handler/user.ts index cc7606e35..5fa1f5d9a 100644 --- a/packages/hydrooj/src/handler/user.ts +++ b/packages/hydrooj/src/handler/user.ts @@ -4,6 +4,7 @@ import { UserNotFoundError, SystemError, BlacklistedError, UserFacingError, LoginError, } from '../error'; +import { User } from '../interface'; import { Route, Handler, Types, param, post, } from '../service/server'; @@ -17,9 +18,8 @@ import * as system from '../model/system'; import { PERM, PRIV } from '../model/builtin'; import { isEmail, isPassword, isUname } from '../lib/validator'; import { sendMail } from '../lib/mail'; -import * as misc from '../lib/misc'; import paginate from '../lib/paginate'; -import { User } from '../interface'; +import avatar from '../lib/avatar'; class UserLoginHandler extends Handler { async get() { @@ -241,7 +241,7 @@ class UserSearchHandler extends Handler { if (udoc) udocs.push(udoc); if (!exactMatch) udocs.push(...await user.getPrefixList(domainId, q, 20)); for (const i in udocs) { - udocs[i].gravatar = misc.gravatar(udocs[i].gravatar || ''); + udocs[i].avatarUrl = avatar(udocs[i].avatar); } this.response.body = udocs; } diff --git a/packages/hydrooj/src/interface.ts b/packages/hydrooj/src/interface.ts index 59d19ed95..53cf702fc 100644 --- a/packages/hydrooj/src/interface.ts +++ b/packages/hydrooj/src/interface.ts @@ -301,7 +301,7 @@ export interface DomainDoc extends Record { _id: string, owner: number, roles: Dictionary, - gravatar: string, + avatar: string, bulletin: string, _join?: any, host?: string, diff --git a/packages/hydrooj/src/lib/avatar.ts b/packages/hydrooj/src/lib/avatar.ts new file mode 100644 index 000000000..d2bc6c528 --- /dev/null +++ b/packages/hydrooj/src/lib/avatar.ts @@ -0,0 +1,20 @@ +import { md5 } from './crypto'; + +type AvatarProvider = (src: string, size: number) => string; + +export const providers: Record = { + gravatar: (email, size) => `//gravatar.loli.net/avatar/${md5((email || '').toString().trim().toLowerCase())}?d=mm&s=${size || 32}`, + qq: (id) => `//q1.qlogo.cn/g?b=qq&nk=${/(\d+)/g.exec(id)[1]}&s=640`, + github: (id, size) => `//github.com/${id}.png?size=${Math.min(size, 460)}`, +}; + +function avatar(src: string, size = 64) { + const index = src.indexOf(':'); + if (index === -1) return providers.gravatar('', size); + const [provider, str] = [src.substr(0, index), src.substr(index + 1, src.length)]; + if (!providers[provider] || !str) return providers.gravatar('', size); + return providers[provider](str, size); +} + +export default avatar; +global.Hydro.lib.avatar = avatar; diff --git a/packages/hydrooj/src/lib/misc.ts b/packages/hydrooj/src/lib/misc.ts index 7ebb51964..75659ddf9 100644 --- a/packages/hydrooj/src/lib/misc.ts +++ b/packages/hydrooj/src/lib/misc.ts @@ -1,7 +1,6 @@ import AnsiUp from 'ansi_up'; import { ObjectID } from 'mongodb'; import { size, formatSeconds } from '@hydrooj/utils/lib/utils'; -import { md5 } from './crypto'; export { size, formatSeconds } from '@hydrooj/utils/lib/utils'; @@ -11,10 +10,6 @@ export function ansiToHtml(str: string) { return AU.ansi_to_html(str); } -export function gravatar(email: string, s = 32) { - return `//gravatar.loli.net/avatar/${md5((email || '').toString().trim().toLowerCase())}?d=mm&s=${s}`; -} - export function datetimeSpan(dt: Date | ObjectID, relative = true, format = '%Y-%m-%d %H:%M:%S') { if (!dt) return 'DATETIME_SPAN_ERROR'; if (dt instanceof ObjectID) dt = new Date(dt.generationTime * 1000); @@ -53,5 +48,5 @@ export function* paginate(page: number, numPages: number) { } global.Hydro.lib.misc = { - gravatar, datetimeSpan, paginate, size, formatSeconds, ansiToHtml, + datetimeSpan, paginate, size, formatSeconds, ansiToHtml, }; diff --git a/packages/hydrooj/src/model/domain.ts b/packages/hydrooj/src/model/domain.ts index 7cb3b071f..98ed5ffbf 100644 --- a/packages/hydrooj/src/model/domain.ts +++ b/packages/hydrooj/src/model/domain.ts @@ -47,7 +47,7 @@ class DomainModel { name, bulletin, roles: {}, - gravatar: '', + avatar: '', }; await bus.serial('domain/create', ddoc); await coll.insertOne(ddoc); diff --git a/packages/hydrooj/src/model/setting.ts b/packages/hydrooj/src/model/setting.ts index 4abdac444..9c959f1f8 100644 --- a/packages/hydrooj/src/model/setting.ts +++ b/packages/hydrooj/src/model/setting.ts @@ -107,8 +107,8 @@ PreferenceSetting( ); AccountSetting( - Setting('setting_info', 'gravatar', null, 'text', 'Gravatar Email', - 'We use Gravatar to present your avatar icon.'), + Setting('setting_info', 'avatar', '', 'text', 'Avatar', + 'Allow using gravatar:email qq:id github:name format.'), Setting('setting_info', 'qq', null, 'text', 'QQ'), Setting('setting_info', 'gender', builtin.USER_GENDER_OTHER, builtin.USER_GENDER_RANGE, 'Gender'), Setting('setting_info', 'bio', null, 'markdown', 'Bio'), @@ -122,7 +122,7 @@ AccountSetting( DomainSetting( Setting('setting_domain', 'name', 'New domain', 'text', 'name'), - Setting('setting_domain', 'gravatar', '', 'text', 'gravatar', 'Will be used as the domain icon.'), + Setting('setting_domain', 'avatar', '', 'text', 'avatar', 'Will be used as the domain icon.'), Setting('setting_domain', 'bulletin', '', 'markdown', 'Bulletin'), Setting('setting_storage', 'host', '', 'text', 'Custom host', null, FLAG_HIDDEN | FLAG_DISABLED), ); diff --git a/packages/hydrooj/src/model/user.ts b/packages/hydrooj/src/model/user.ts index 102b38754..bae4895a1 100644 --- a/packages/hydrooj/src/model/user.ts +++ b/packages/hydrooj/src/model/user.ts @@ -101,7 +101,7 @@ class UserModel { _id: 0, uname: 'Unknown User', unameLower: 'unknown user', - gravatar: 'unknown@hydro.local', + avatar: 'gravatar:unknown@hydro.local', mail: 'unknown@hydro.local', mailLower: 'unknown@hydro.local', salt: '', @@ -213,7 +213,7 @@ class UserModel { loginat: new Date(), loginip: regip, priv, - gravatar: mail, + avatar: `gravatar:${mail}`, }); } catch (e) { logger.warn('%o', e); diff --git a/packages/hydrooj/src/pipelineUtils.ts b/packages/hydrooj/src/pipelineUtils.ts index d868cdb99..989eb0574 100644 --- a/packages/hydrooj/src/pipelineUtils.ts +++ b/packages/hydrooj/src/pipelineUtils.ts @@ -1,6 +1,7 @@ /* eslint-disable no-await-in-loop */ -import { DomainDoc } from './loader'; +import type { DomainDoc, Udoc } from './interface'; import domain from './model/domain'; +import user from './model/user'; import problem, { Field, Pdoc } from './model/problem'; export async function iterateAllDomain(cb: (ddoc: DomainDoc, current?: number, total?: number) => Promise) { @@ -8,6 +9,11 @@ export async function iterateAllDomain(cb: (ddoc: DomainDoc, current?: number, t for (const i in ddocs) await cb(ddocs[i], +i, ddocs.length); } +export async function iterateAllUser(cb: (udoc: Udoc, current?: number, total?: number) => Promise) { + const udocs = await user.getMulti().toArray(); + for (const i in udocs) await cb(udocs[i], +i, udocs.length); +} + interface PartialPdoc extends Pdoc { [key: string]: any, } diff --git a/packages/hydrooj/src/service/server.ts b/packages/hydrooj/src/service/server.ts index 4d6e63b66..950dbc13a 100644 --- a/packages/hydrooj/src/service/server.ts +++ b/packages/hydrooj/src/service/server.ts @@ -28,8 +28,8 @@ import { CsrfTokenError, InvalidOperationError, MethodNotAllowedError, NotFoundError, HydroError, SystemError, } from '../error'; -import * as misc from '../lib/misc'; import { isContent, isName, isTitle } from '../lib/validator'; +import avatar from '../lib/avatar'; import user from '../model/user'; import domain from '../model/domain'; import * as system from '../model/system'; @@ -322,7 +322,7 @@ export class HandlerCommon { async renderHTML(name: string, context: any): Promise { const UserContext: any = { ...this.user, - gravatar: misc.gravatar(this.user.gravatar || '', 128), + avatar: avatar(this.user.avatar || '', 128), perm: this.user.perm.toString(), viewLang: this.translate('__id'), }; @@ -508,6 +508,7 @@ export class Handler extends HandlerCommon { this.user = await user.getById(domainId, this.session.uid, this.session.scope); } if (this.user._id === 0 && this.session.viewLang) this.user.viewLang = this.session.viewLang; + this.user.avatarUrl = avatar(this.user.avatar, 128); this.csrfToken = this.getCsrfToken(this.session._id || String.random(32)); this.UiContext.csrfToken = this.csrfToken; this.loginMethods = filter(Object.keys(global.Hydro.lib), (str) => str.startsWith('oauth_')) diff --git a/packages/hydrooj/src/upgrade.ts b/packages/hydrooj/src/upgrade.ts index 916739841..179c953e2 100644 --- a/packages/hydrooj/src/upgrade.ts +++ b/packages/hydrooj/src/upgrade.ts @@ -10,12 +10,13 @@ import { Progress } from './ui'; import { Rdoc } from './interface'; import { Logger } from './logger'; import { streamToBuffer } from './utils'; -import { iterateAllDomain, iterateAllProblem } from './pipelineUtils'; +import { iterateAllDomain, iterateAllProblem, iterateAllUser } from './pipelineUtils'; import gridfs from './service/gridfs'; import storage from './service/storage'; import db from './service/db'; import difficultyAlgorithm from './lib/difficulty'; import problem from './model/problem'; +import user from './model/user'; import domain from './model/domain'; import * as document from './model/document'; import * as system from './model/system'; @@ -299,6 +300,13 @@ const scripts: UpgradeScript[] = [ }); return true; }, + async function _22_23() { + await iterateAllUser(async (udoc) => { + if (!udoc.gravatar) return; + await user.setById(udoc._id, { avatar: `gravatar:${udoc.gravatar}` }, { gravatar: '' }); + }); + return true; + }, ]; export default scripts; diff --git a/packages/migrate-vijos/package.json b/packages/migrate-vijos/package.json index 5db7ddb9b..e1089ff7b 100644 --- a/packages/migrate-vijos/package.json +++ b/packages/migrate-vijos/package.json @@ -1,6 +1,6 @@ { "name": "@hydrooj/migrate-vijos", - "version": "1.4.1", + "version": "1.4.2", "main": "package.json", "repository": "git@github.com:hydro-dev/Hydro.git", "author": "undefined ", diff --git a/packages/migrate-vijos/script.ts b/packages/migrate-vijos/script.ts index d4adfff00..9c8a67143 100644 --- a/packages/migrate-vijos/script.ts +++ b/packages/migrate-vijos/script.ts @@ -23,7 +23,7 @@ const tasks = { hash: doc.hash.split('|')[1], hashType: doc.hash.split('|')[0] === 'vj4' ? 'hydro' : doc.hash.split('|')[0], priv: doc.priv, - gravatar: doc.gravatar, + avatar: `gravatar:${doc.gravatar}`, mail: doc.mail, mailLower: doc.mail_lower, regat: doc.regat, @@ -256,7 +256,10 @@ const tasks = { return res; }, }, - gravatar: 'gravatar', + gravatar: { + field: 'avatar', + processer: (gravatar) => `gavatar:${gravatar}`, + }, bulletin: 'bulletin', }, 'fs.files': async (doc) => doc, diff --git a/packages/syzoj-ng-api/handlers/problem.ts b/packages/syzoj-ng-api/handlers/problem.ts index df20ed381..515d71384 100644 --- a/packages/syzoj-ng-api/handlers/problem.ts +++ b/packages/syzoj-ng-api/handlers/problem.ts @@ -104,8 +104,8 @@ export class QueryProblemSetAPIHandler extends Handler { nickname: udoc.displayName || udoc.uname, bio: udoc.bio, avatar: { - type: 'gravatar', - key: udoc.gravatar, + type: udoc.avatar.split(':')[0], + key: udoc.avatar.split(':')[1], }, isAdmin: udoc.hasPriv(PRIV.PRIV_MANAGE_ALL_DOMAIN) || udoc.hasPerm(PERM.PERM_ADMIN), acceptedProblemCount: udoc.nAccept, diff --git a/packages/ui-default/backendlib/template.js b/packages/ui-default/backendlib/template.js index 4b5e3157f..120863f85 100644 --- a/packages/ui-default/backendlib/template.js +++ b/packages/ui-default/backendlib/template.js @@ -9,7 +9,7 @@ const Xss = require('xss'); const { findFileSync } = require('@hydrooj/utils/lib/utils'); const markdown = require('./markdown'); -const { misc, buildContent } = global.Hydro.lib; +const { misc, buildContent, avatar } = global.Hydro.lib; const xss = new Xss.FilterXSS({ whiteList: { @@ -187,7 +187,7 @@ env.addGlobal('typeof', (o) => typeof o); env.addGlobal('datetimeSpan', misc.datetimeSpan); env.addGlobal('paginate', misc.paginate); env.addGlobal('size', misc.size); -env.addGlobal('gravatar', misc.gravatar); +env.addGlobal('avatarUrl', avatar); env.addGlobal('formatSeconds', misc.formatSeconds); env.addGlobal('model', global.Hydro.model); env.addGlobal('ui', global.Hydro.ui); diff --git a/packages/ui-default/components/autocomplete/DomainSelectAutoComplete.js b/packages/ui-default/components/autocomplete/DomainSelectAutoComplete.js index a26e3bd09..a09a9520b 100644 --- a/packages/ui-default/components/autocomplete/DomainSelectAutoComplete.js +++ b/packages/ui-default/components/autocomplete/DomainSelectAutoComplete.js @@ -16,7 +16,7 @@ function renderItem(domain) { return tpl`
- +
${domain.name}
diff --git a/packages/ui-default/components/autocomplete/UserSelectAutoComplete.js b/packages/ui-default/components/autocomplete/UserSelectAutoComplete.js index a0897f33e..33d6f0fd6 100644 --- a/packages/ui-default/components/autocomplete/UserSelectAutoComplete.js +++ b/packages/ui-default/components/autocomplete/UserSelectAutoComplete.js @@ -16,7 +16,7 @@ function renderItem(user) { return tpl`
- +
${user.uname}
diff --git a/packages/ui-default/components/message/index.page.js b/packages/ui-default/components/message/index.page.js index e06ec5425..4248d31ad 100644 --- a/packages/ui-default/components/message/index.page.js +++ b/packages/ui-default/components/message/index.page.js @@ -23,7 +23,7 @@ const messagePage = new AutoloadPage('messagePage', () => { console.log('Received message', msg); if (msg.mdoc.flag & FLAG_ALERT) { // Is alert - new InfoDialog({ + new InfoDialog({ $body: tpl`

${i18n('Message from {0}:', msg.mdoc.from)}

@@ -34,7 +34,7 @@ const messagePage = new AutoloadPage('messagePage', () => { // Is message new Notification({ title: msg.udoc.uname, - avatar: msg.udoc.gravatar_url, + avatar: msg.udoc.avatarUrl, message: msg.mdoc.content, duration: 15000, action: () => window.open(`/home/messages?uid=${msg.udoc._id}`, '_blank'), diff --git a/packages/ui-default/components/messagepad/MessagePadDialogueContentContainer.jsx b/packages/ui-default/components/messagepad/MessagePadDialogueContentContainer.jsx index 52ba452c1..35eda40f5 100644 --- a/packages/ui-default/components/messagepad/MessagePadDialogueContentContainer.jsx +++ b/packages/ui-default/components/messagepad/MessagePadDialogueContentContainer.jsx @@ -52,8 +52,8 @@ export default connect(mapStateToProps, null)(class MessagePadDialogueContentCon isSelf={reply.from === UserContext._id} faceUrl={ reply.from === UserContext._id - ? UserContext.gravatar - : this.props.item.udoc.gravatar + ? UserContext.avatarUrl + : this.props.item.udoc.avatarUrl } >
{reply.content}
diff --git a/packages/ui-default/components/messagepad/MessagePadDialogueListContainer.jsx b/packages/ui-default/components/messagepad/MessagePadDialogueListContainer.jsx index 8bd203b3c..b0db10b67 100644 --- a/packages/ui-default/components/messagepad/MessagePadDialogueListContainer.jsx +++ b/packages/ui-default/components/messagepad/MessagePadDialogueListContainer.jsx @@ -39,7 +39,7 @@ export default connect(mapStateToProps, mapDispatchToProps)(class MessagePadDial key={dialogue._id} userName={dialogue.udoc.uname} summary={(_.last(dialogue.messages)?.content) || ''} - faceUrl={dialogue.udoc.gravatar} + faceUrl={dialogue.udoc.avatarUrl} active={dialogue._id === this.props.activeId} onClick={() => this.props.handleClick(dialogue._id)} /> diff --git a/packages/ui-default/jsconfig.json b/packages/ui-default/jsconfig.json index f72edc0c6..991b251e2 100644 --- a/packages/ui-default/jsconfig.json +++ b/packages/ui-default/jsconfig.json @@ -1,4 +1,7 @@ { + "exclude": [ + "node_modules" + ], "compilerOptions": { "experimentalDecorators": true, "allowSyntheticDefaultImports": true, diff --git a/packages/ui-default/locales/zh.yaml b/packages/ui-default/locales/zh.yaml index e239e3fec..32cfeee63 100644 --- a/packages/ui-default/locales/zh.yaml +++ b/packages/ui-default/locales/zh.yaml @@ -34,7 +34,6 @@ __langname: 简体中文 'Role {1} already exists in domain {0}.': '域 {0} 中已存在角色 {1}。' 'Solved {0} problems, RP: {1} (No. {2})': '解决了 {0} 道题目,RP: {1} (No. {2})' 'The value `{1}` of {0} already exists.': '{0} 的值 `{1}` 已经存在。' -'We use Gravatar to present your avatar icon.': '我们使用 Gravatar 服务来呈现您的头像。' 'Yes': 是 "Effects only when Difficulty is not 'Use algorithm calculated'.": 仅当难度不为“使用算法计算”时才起效。 "Split by ', '.": 由“, ”或“,”分隔。 @@ -317,7 +316,6 @@ Formula blocks: 公式区块 fs_upload: 上传文件 Gender Visibility: 性别可见性 Gender: 性别 -Gravatar Email: Gravatar Email 地址 Hard Deadline: 最终截止时间 Hash: 散列 Have ALL PERMISSIONS in this domain: 在此域中拥有全部权限 diff --git a/packages/ui-default/locales/zh_TW.yaml b/packages/ui-default/locales/zh_TW.yaml index 3bb864b57..1d67084d3 100644 --- a/packages/ui-default/locales/zh_TW.yaml +++ b/packages/ui-default/locales/zh_TW.yaml @@ -194,7 +194,6 @@ Forgot password or username?: 忘記密碼或者使用者名? Formula blocks: 公式區塊 Gender Visibility: 性別可見性 Gender: 性別 -Gravatar Email: Gravatar Email 地址 Hard Deadline: 最終截止時間 Have ALL PERMISSIONS in this domain: 在此域中擁有全部許可權 Help: 幫助 @@ -538,7 +537,6 @@ Visible to registered users: 對註冊使用者可見 Visit: 檢視 Vote problem solutions: 為題解投票 Vote: 投票 -We use Gravatar to present your avatar icon.: 我們使用 Gravatar 服務來呈現您的頭像。 We will check code similarity after this contest.: 我們會在賽後檢查程式碼相似度。 WeChat Visibility: 微信可見性 WeChat: 微信 diff --git a/packages/ui-default/package.json b/packages/ui-default/package.json index 6686193ce..da5169d7b 100644 --- a/packages/ui-default/package.json +++ b/packages/ui-default/package.json @@ -1,6 +1,6 @@ { "name": "@hydrooj/ui-default", - "version": "4.6.6", + "version": "4.6.7", "author": "undefined ", "license": "AGPL-3.0", "main": "hydro.js", diff --git a/packages/ui-default/templates/components/comments_discussion.html b/packages/ui-default/templates/components/comments_discussion.html index 245b7e8ef..5cdf85dd9 100644 --- a/packages/ui-default/templates/components/comments_discussion.html +++ b/packages/ui-default/templates/components/comments_discussion.html @@ -31,7 +31,7 @@
  • - +
    @@ -55,7 +55,7 @@
  • - +
    @@ -72,7 +72,7 @@
  • - +
    @@ -108,7 +108,7 @@
  • - +
    diff --git a/packages/ui-default/templates/components/user.html b/packages/ui-default/templates/components/user.html index 7c4b676a6..547a9862f 100644 --- a/packages/ui-default/templates/components/user.html +++ b/packages/ui-default/templates/components/user.html @@ -2,7 +2,7 @@ {% if udoc %}