From 462acc9eee3f89a926fd4b46ffed0b066519759b Mon Sep 17 00:00:00 2001 From: syuilo Date: Mon, 9 Jan 2023 15:50:25 +0900 Subject: [PATCH] =?UTF-8?q?=E3=82=AB=E3=82=B9=E3=82=BF=E3=83=A0=E7=B5=B5?= =?UTF-8?q?=E6=96=87=E5=AD=97=E4=B8=80=E8=A6=A7=E6=83=85=E5=A0=B1=E3=82=92?= =?UTF-8?q?meta=E3=81=8B=E3=82=89=E5=88=86=E9=9B=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CHANGELOG.md | 2 + .../src/core/entities/EmojiEntityService.ts | 8 +- packages/backend/src/models/schema/emoji.ts | 8 +- .../backend/src/server/api/EndpointsModule.ts | 4 + packages/backend/src/server/api/endpoints.ts | 2 + .../src/server/api/endpoints/emojis.ts | 91 +++++++++++++++++++ .../backend/src/server/api/endpoints/meta.ts | 57 ------------ .../src/components/MkAutocomplete.vue | 5 +- .../frontend/src/components/MkEmojiPicker.vue | 9 +- packages/frontend/src/custom-emojis.ts | 48 ++++++++++ packages/frontend/src/instance.ts | 24 +---- packages/frontend/src/local-storage.ts | 2 + packages/frontend/src/pages/about.emojis.vue | 87 +++++++----------- .../src/pages/admin/emoji-edit-dialog.vue | 4 +- .../src/pages/admin/overview.stats.vue | 5 +- .../frontend/src/pages/mfm-cheat-sheet.vue | 5 +- .../frontend/src/pages/settings/index.vue | 2 + 17 files changed, 212 insertions(+), 151 deletions(-) create mode 100644 packages/backend/src/server/api/endpoints/emojis.ts create mode 100644 packages/frontend/src/custom-emojis.ts diff --git a/CHANGELOG.md b/CHANGELOG.md index 269f8b100..43cf0ef6e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -40,6 +40,8 @@ You should also include the user name that made the change. - Firefox109以下はサポートされなくなりました #### For app developers +- API: metaのレスポンスに`emojis`プロパティが含まれなくなりました + - カスタム絵文字一覧情報を取得するには、`emojis`エンドポイントにリクエストします - API: カスタム絵文字エンティティに`url`プロパティが含まれなくなりました - 絵文字画像を表示するには、`/emoji/.webp`にリクエストすると画像が返ります。 - e.g. `https://p1.a9z.dev/emoji/misskey.webp` diff --git a/packages/backend/src/core/entities/EmojiEntityService.ts b/packages/backend/src/core/entities/EmojiEntityService.ts index 8a2dc70ed..2a4e09519 100644 --- a/packages/backend/src/core/entities/EmojiEntityService.ts +++ b/packages/backend/src/core/entities/EmojiEntityService.ts @@ -22,23 +22,25 @@ export class EmojiEntityService { @bindThis public async pack( src: Emoji['id'] | Emoji, + opts: { omitHost?: boolean; omitId?: boolean; } = {}, ): Promise> { const emoji = typeof src === 'object' ? src : await this.emojisRepository.findOneByOrFail({ id: src }); return { - id: emoji.id, + id: opts.omitId ? undefined : emoji.id, aliases: emoji.aliases, name: emoji.name, category: emoji.category, - host: emoji.host, + host: opts.omitHost ? undefined : emoji.host, }; } @bindThis public packMany( emojis: any[], + opts: { omitHost?: boolean; omitId?: boolean; } = {}, ) { - return Promise.all(emojis.map(x => this.pack(x))); + return Promise.all(emojis.map(x => this.pack(x, opts))); } } diff --git a/packages/backend/src/models/schema/emoji.ts b/packages/backend/src/models/schema/emoji.ts index 9a52609b6..d897a0fc0 100644 --- a/packages/backend/src/models/schema/emoji.ts +++ b/packages/backend/src/models/schema/emoji.ts @@ -3,7 +3,7 @@ export const packedEmojiSchema = { properties: { id: { type: 'string', - optional: false, nullable: false, + optional: true, nullable: false, format: 'id', example: 'xxxxxxxxxx', }, @@ -26,12 +26,8 @@ export const packedEmojiSchema = { }, host: { type: 'string', - optional: false, nullable: true, + optional: true, nullable: true, description: 'The local host is represented with `null`.', }, - url: { - type: 'string', - optional: true, nullable: false, - }, }, } as const; diff --git a/packages/backend/src/server/api/EndpointsModule.ts b/packages/backend/src/server/api/EndpointsModule.ts index 60beca4f4..ab9349966 100644 --- a/packages/backend/src/server/api/EndpointsModule.ts +++ b/packages/backend/src/server/api/EndpointsModule.ts @@ -220,6 +220,7 @@ import * as ep___messaging_messages_create from './endpoints/messaging/messages/ import * as ep___messaging_messages_delete from './endpoints/messaging/messages/delete.js'; import * as ep___messaging_messages_read from './endpoints/messaging/messages/read.js'; import * as ep___meta from './endpoints/meta.js'; +import * as ep___emojis from './endpoints/emojis.js'; import * as ep___miauth_genToken from './endpoints/miauth/gen-token.js'; import * as ep___mute_create from './endpoints/mute/create.js'; import * as ep___mute_delete from './endpoints/mute/delete.js'; @@ -550,6 +551,7 @@ const $messaging_messages_create: Provider = { provide: 'ep:messaging/messages/c const $messaging_messages_delete: Provider = { provide: 'ep:messaging/messages/delete', useClass: ep___messaging_messages_delete.default }; const $messaging_messages_read: Provider = { provide: 'ep:messaging/messages/read', useClass: ep___messaging_messages_read.default }; const $meta: Provider = { provide: 'ep:meta', useClass: ep___meta.default }; +const $emojis: Provider = { provide: 'ep:emojis', useClass: ep___emojis.default }; const $miauth_genToken: Provider = { provide: 'ep:miauth/gen-token', useClass: ep___miauth_genToken.default }; const $mute_create: Provider = { provide: 'ep:mute/create', useClass: ep___mute_create.default }; const $mute_delete: Provider = { provide: 'ep:mute/delete', useClass: ep___mute_delete.default }; @@ -884,6 +886,7 @@ const $retention: Provider = { provide: 'ep:retention', useClass: ep___retention $messaging_messages_delete, $messaging_messages_read, $meta, + $emojis, $miauth_genToken, $mute_create, $mute_delete, @@ -1212,6 +1215,7 @@ const $retention: Provider = { provide: 'ep:retention', useClass: ep___retention $messaging_messages_delete, $messaging_messages_read, $meta, + $emojis, $miauth_genToken, $mute_create, $mute_delete, diff --git a/packages/backend/src/server/api/endpoints.ts b/packages/backend/src/server/api/endpoints.ts index d4f8be5b8..f9749ad66 100644 --- a/packages/backend/src/server/api/endpoints.ts +++ b/packages/backend/src/server/api/endpoints.ts @@ -219,6 +219,7 @@ import * as ep___messaging_messages_create from './endpoints/messaging/messages/ import * as ep___messaging_messages_delete from './endpoints/messaging/messages/delete.js'; import * as ep___messaging_messages_read from './endpoints/messaging/messages/read.js'; import * as ep___meta from './endpoints/meta.js'; +import * as ep___emojis from './endpoints/emojis.js'; import * as ep___miauth_genToken from './endpoints/miauth/gen-token.js'; import * as ep___mute_create from './endpoints/mute/create.js'; import * as ep___mute_delete from './endpoints/mute/delete.js'; @@ -547,6 +548,7 @@ const eps = [ ['messaging/messages/delete', ep___messaging_messages_delete], ['messaging/messages/read', ep___messaging_messages_read], ['meta', ep___meta], + ['emojis', ep___emojis], ['miauth/gen-token', ep___miauth_genToken], ['mute/create', ep___mute_create], ['mute/delete', ep___mute_delete], diff --git a/packages/backend/src/server/api/endpoints/emojis.ts b/packages/backend/src/server/api/endpoints/emojis.ts new file mode 100644 index 000000000..0a1626822 --- /dev/null +++ b/packages/backend/src/server/api/endpoints/emojis.ts @@ -0,0 +1,91 @@ +import { IsNull, MoreThan } from 'typeorm'; +import { Inject, Injectable } from '@nestjs/common'; +import type { EmojisRepository } from '@/models/index.js'; +import { Endpoint } from '@/server/api/endpoint-base.js'; +import { EmojiEntityService } from '@/core/entities/EmojiEntityService.js'; +import type { Config } from '@/config.js'; +import { DI } from '@/di-symbols.js'; + +export const meta = { + tags: ['meta'], + + requireCredential: false, + + res: { + type: 'object', + optional: false, nullable: false, + properties: { + emojis: { + type: 'array', + optional: false, nullable: false, + items: { + type: 'object', + optional: false, nullable: false, + properties: { + id: { + type: 'string', + optional: false, nullable: false, + format: 'id', + }, + aliases: { + type: 'array', + optional: false, nullable: false, + items: { + type: 'string', + optional: false, nullable: false, + }, + }, + category: { + type: 'string', + optional: false, nullable: true, + }, + }, + }, + }, + }, + }, +} as const; + +export const paramDef = { + type: 'object', + properties: { + }, + required: [], +} as const; + +// eslint-disable-next-line import/no-default-export +@Injectable() +export default class extends Endpoint { + constructor( + @Inject(DI.config) + private config: Config, + + @Inject(DI.emojisRepository) + private emojisRepository: EmojisRepository, + + private emojiEntityService: EmojiEntityService, + ) { + super(meta, paramDef, async (ps, me) => { + const emojis = await this.emojisRepository.find({ + where: { + host: IsNull(), + }, + order: { + category: 'ASC', + name: 'ASC', + }, + cache: { + id: 'meta_emojis', + milliseconds: 3600000, // 1 hour + }, + }); + + return { + emojis: await this.emojiEntityService.packMany(emojis, { + omitId: true, + omitHost: true, + }), + }; + }); + } +} diff --git a/packages/backend/src/server/api/endpoints/meta.ts b/packages/backend/src/server/api/endpoints/meta.ts index 05da01197..c44d63d64 100644 --- a/packages/backend/src/server/api/endpoints/meta.ts +++ b/packages/backend/src/server/api/endpoints/meta.ts @@ -4,7 +4,6 @@ import type { AdsRepository, EmojisRepository, UsersRepository } from '@/models/ import { MAX_NOTE_TEXT_LENGTH, DB_MAX_NOTE_TEXT_LENGTH } from '@/const.js'; import { Endpoint } from '@/server/api/endpoint-base.js'; import { UserEntityService } from '@/core/entities/UserEntityService.js'; -import { EmojiEntityService } from '@/core/entities/EmojiEntityService.js'; import { MetaService } from '@/core/MetaService.js'; import type { Config } from '@/config.js'; import { DI } from '@/di-symbols.js'; @@ -152,43 +151,6 @@ export const meta = { type: 'number', optional: false, nullable: false, }, - emojis: { - type: 'array', - optional: false, nullable: false, - items: { - type: 'object', - optional: false, nullable: false, - properties: { - id: { - type: 'string', - optional: false, nullable: false, - format: 'id', - }, - aliases: { - type: 'array', - optional: false, nullable: false, - items: { - type: 'string', - optional: false, nullable: false, - }, - }, - category: { - type: 'string', - optional: false, nullable: true, - }, - host: { - type: 'string', - optional: false, nullable: true, - description: 'The local host is represented with `null`.', - }, - url: { - type: 'string', - optional: false, nullable: false, - format: 'url', - }, - }, - }, - }, ads: { type: 'array', optional: false, nullable: false, @@ -326,30 +288,12 @@ export default class extends Endpoint { @Inject(DI.adsRepository) private adsRepository: AdsRepository, - @Inject(DI.emojisRepository) - private emojisRepository: EmojisRepository, - private userEntityService: UserEntityService, - private emojiEntityService: EmojiEntityService, private metaService: MetaService, ) { super(meta, paramDef, async (ps, me) => { const instance = await this.metaService.fetch(true); - const emojis = await this.emojisRepository.find({ - where: { - host: IsNull(), - }, - order: { - category: 'ASC', - name: 'ASC', - }, - cache: { - id: 'meta_emojis', - milliseconds: 3600000, // 1 hour - }, - }); - const ads = await this.adsRepository.find({ where: { expiresAt: MoreThan(new Date()), @@ -390,7 +334,6 @@ export default class extends Endpoint { backgroundImageUrl: instance.backgroundImageUrl, logoImageUrl: instance.logoImageUrl, maxNoteTextLength: MAX_NOTE_TEXT_LENGTH, // 後方互換性のため - emojis: await this.emojiEntityService.packMany(emojis), defaultLightTheme: instance.defaultLightTheme, defaultDarkTheme: instance.defaultDarkTheme, ads: ads.map(ad => ({ diff --git a/packages/frontend/src/components/MkAutocomplete.vue b/packages/frontend/src/components/MkAutocomplete.vue index 8ed60bc5d..0d0c5edba 100644 --- a/packages/frontend/src/components/MkAutocomplete.vue +++ b/packages/frontend/src/components/MkAutocomplete.vue @@ -47,6 +47,9 @@ import { emojilist } from '@/scripts/emojilist'; import { instance } from '@/instance'; import { i18n } from '@/i18n'; import { miLocalStorage } from '@/local-storage'; +import { getCustomEmojis } from '@/custom-emojis'; + +const customEmojis = await getCustomEmojis(); type EmojiDef = { emoji: string; @@ -86,7 +89,6 @@ for (const x of lib) { emjdb.sort((a, b) => a.name.length - b.name.length); //#region Construct Emoji DB -const customEmojis = instance.emojis; const emojiDefinitions: EmojiDef[] = []; for (const x of customEmojis) { @@ -117,7 +119,6 @@ export default { emojiDb, emojiDefinitions, emojilist, - customEmojis, }; diff --git a/packages/frontend/src/components/MkEmojiPicker.vue b/packages/frontend/src/components/MkEmojiPicker.vue index f3b3ac0b5..8df01f6c2 100644 --- a/packages/frontend/src/components/MkEmojiPicker.vue +++ b/packages/frontend/src/components/MkEmojiPicker.vue @@ -6,7 +6,7 @@
@@ -28,8 +28,8 @@ -