From 09f4885f8975c935861ddef01f4cdb83c4a185d9 Mon Sep 17 00:00:00 2001 From: syuilo Date: Sun, 24 Oct 2021 21:02:50 +0900 Subject: [PATCH] =?UTF-8?q?feat(client):=20=E3=83=A1=E3=83=B3=E3=82=B7?= =?UTF-8?q?=E3=83=A7=E3=83=B3=E3=81=AB=E3=83=A6=E3=83=BC=E3=82=B6=E3=83=BC?= =?UTF-8?q?=E3=81=AE=E3=82=A2=E3=83=90=E3=82=BF=E3=83=BC=E3=82=92=E8=A1=A8?= =?UTF-8?q?=E7=A4=BA=E3=81=99=E3=82=8B=E3=82=88=E3=81=86=E3=81=AB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Resolve #350 --- CHANGELOG.md | 7 +++++++ assets/user-unknown.png | Bin 0 -> 3518 bytes src/client/components/mention.vue | 8 ++++++++ src/models/repositories/user.ts | 10 +++++++++- src/server/index.ts | 18 +++++++++++++++++- 5 files changed, 41 insertions(+), 2 deletions(-) create mode 100644 assets/user-unknown.png diff --git a/CHANGELOG.md b/CHANGELOG.md index 7d2b3f7159..e07a35f221 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,13 @@ --> +## 12.x.x (unreleased) + +### Improvements +- クライアント: メンションにユーザーのアバターを表示するように + +### Bugfixes + ## 12.93.2 (2021/10/23) ### Bugfixes diff --git a/assets/user-unknown.png b/assets/user-unknown.png new file mode 100644 index 0000000000000000000000000000000000000000..ab29bef2b17ba5aaca78d8f809a010bc29970225 GIT binary patch literal 3518 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 fB~=PWz4VW%LrP-)!S_Y4LESD-S3j3^P6 {{ $ts.you }} + @{{ username }} @{{ toUnicode(host) }} @@ -76,6 +77,13 @@ export default defineComponent({ vertical-align: top; } + > .icon { + width: 1.5em; + margin: 0 0.2em; + vertical-align: bottom; + border-radius: 100%; + } + > .main { > .host { opacity: 0.5; diff --git a/src/models/repositories/user.ts b/src/models/repositories/user.ts index 2b77b613a8..72cefbaac5 100644 --- a/src/models/repositories/user.ts +++ b/src/models/repositories/user.ts @@ -155,6 +155,14 @@ export class UserRepository extends Repository { ); } + public getAvatarUrl(user: User): string { + if (user.avatarUrl) { + return user.avatarUrl; + } else { + return `${config.url}/random-avatar/${user.id}`; + } + } + public async pack( src: User['id'] | User, me?: { id: User['id'] } | null | undefined, @@ -186,7 +194,7 @@ export class UserRepository extends Repository { name: user.name, username: user.username, host: user.host, - avatarUrl: user.avatarUrl ? user.avatarUrl : config.url + '/avatar/' + user.id, + avatarUrl: this.getAvatarUrl(user), avatarBlurhash: user.avatarBlurhash, avatarColor: null, // 後方互換性のため isAdmin: user.isAdmin || falsy, diff --git a/src/server/index.ts b/src/server/index.ts index c891596140..5e1a12e4d3 100644 --- a/src/server/index.ts +++ b/src/server/index.ts @@ -26,6 +26,7 @@ import { networkChart } from '@/services/chart/index'; import { genAvatar } from '@/misc/gen-avatar'; import { createTemp } from '@/misc/create-temp'; import { publishMainStream } from '@/services/stream'; +import { parseAcct } from '@/misc/acct'; export const serverLogger = new Logger('server', 'gray', false); @@ -68,7 +69,22 @@ router.use(activityPub.routes()); router.use(nodeinfo.routes()); router.use(wellKnown.routes()); -router.get('/avatar/:x', async ctx => { +router.get('/avatar/@:acct', async ctx => { + const { username, host } = parseAcct(ctx.params.acct); + const user = await Users.findOne({ + usernameLower: username.toLowerCase(), + host: host === config.host ? null : host, + isSuspended: false + }); + + if (user) { + ctx.redirect(Users.getAvatarUrl(user)); + } else { + ctx.redirect('/static-assets/user-unknown.png'); + } +}); + +router.get('/random-avatar/:x', async ctx => { const [temp] = await createTemp(); await genAvatar(ctx.params.x, fs.createWriteStream(temp)); ctx.set('Content-Type', 'image/png');