From 3e112da486e59d48c415a5bd3a251148ed7312b3 Mon Sep 17 00:00:00 2001 From: syuilo Date: Sat, 21 Jan 2023 20:40:09 +0900 Subject: [PATCH] =?UTF-8?q?=E3=83=AD=E3=83=BC=E3=82=AB=E3=83=AB=E3=81=AE?= =?UTF-8?q?=E3=82=AB=E3=82=B9=E3=82=BF=E3=83=A0=E7=B5=B5=E6=96=87=E5=AD=97?= =?UTF-8?q?=E3=81=AB=E3=81=A4=E3=81=84=E3=81=A6=E3=81=AF=E7=9B=B4=E6=8E=A5?= =?UTF-8?q?=E3=82=AA=E3=83=AA=E3=82=B8=E3=83=8A=E3=83=ABURL=E3=81=AB?= =?UTF-8?q?=E3=83=AA=E3=82=AF=E3=82=A8=E3=82=B9=E3=83=88=E3=81=99=E3=82=8B?= =?UTF-8?q?=E3=82=88=E3=81=86=E3=81=AB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/backend/src/core/entities/EmojiEntityService.ts | 6 ++++-- packages/backend/src/models/schema/emoji.ts | 4 ++++ packages/backend/src/server/api/endpoints/emojis.ts | 1 + packages/frontend/src/components/global/MkEmoji.vue | 6 +++++- packages/frontend/src/custom-emojis.ts | 9 +++++++-- 5 files changed, 21 insertions(+), 5 deletions(-) diff --git a/packages/backend/src/core/entities/EmojiEntityService.ts b/packages/backend/src/core/entities/EmojiEntityService.ts index 2a4e09519f..cee85a5688 100644 --- a/packages/backend/src/core/entities/EmojiEntityService.ts +++ b/packages/backend/src/core/entities/EmojiEntityService.ts @@ -22,7 +22,7 @@ export class EmojiEntityService { @bindThis public async pack( src: Emoji['id'] | Emoji, - opts: { omitHost?: boolean; omitId?: boolean; } = {}, + opts: { omitHost?: boolean; omitId?: boolean; withUrl?: boolean; } = {}, ): Promise> { const emoji = typeof src === 'object' ? src : await this.emojisRepository.findOneByOrFail({ id: src }); @@ -32,13 +32,15 @@ export class EmojiEntityService { name: emoji.name, category: emoji.category, host: opts.omitHost ? undefined : emoji.host, + // ?? emoji.originalUrl してるのは後方互換性のため + url: opts.withUrl ? (emoji.publicUrl ?? emoji.originalUrl) : undefined, }; } @bindThis public packMany( emojis: any[], - opts: { omitHost?: boolean; omitId?: boolean; } = {}, + opts: { omitHost?: boolean; omitId?: boolean; withUrl?: boolean; } = {}, ) { 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 d897a0fc05..143f25373c 100644 --- a/packages/backend/src/models/schema/emoji.ts +++ b/packages/backend/src/models/schema/emoji.ts @@ -29,5 +29,9 @@ export const packedEmojiSchema = { 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/endpoints/emojis.ts b/packages/backend/src/server/api/endpoints/emojis.ts index 97dcfde596..db1eddc80a 100644 --- a/packages/backend/src/server/api/endpoints/emojis.ts +++ b/packages/backend/src/server/api/endpoints/emojis.ts @@ -83,6 +83,7 @@ export default class extends Endpoint { emojis: await this.emojiEntityService.packMany(emojis, { omitId: true, omitHost: true, + withUrl: true, }), }; }); diff --git a/packages/frontend/src/components/global/MkEmoji.vue b/packages/frontend/src/components/global/MkEmoji.vue index b7dd0296cd..aaad81c656 100644 --- a/packages/frontend/src/components/global/MkEmoji.vue +++ b/packages/frontend/src/components/global/MkEmoji.vue @@ -12,6 +12,7 @@ import { getStaticImageUrl } from '@/scripts/media-proxy'; import { char2twemojiFilePath, char2fluentEmojiFilePath } from '@/scripts/emoji-base'; import { defaultStore } from '@/store'; import { getEmojiName } from '@/scripts/emojilist'; +import { customEmojis } from '@/custom-emojis'; const props = defineProps<{ emoji: string; @@ -30,6 +31,9 @@ const useOsNativeEmojis = computed(() => defaultStore.state.emojiStyle === 'nati const url = computed(() => { if (char.value) { return char2path(char.value); + } else if (props.host == null) { + const found = customEmojis.find(x => x.name === customEmojiName); + return found ? found.url : null; } else { const rawUrl = props.host ? `/emoji/${customEmojiName}@${props.host}.webp` : `/emoji/${customEmojiName}.webp`; return defaultStore.state.disableShowingAnimatedImages @@ -38,7 +42,7 @@ const url = computed(() => { } }); const alt = computed(() => isCustom.value ? `:${customEmojiName}:` : char.value); -let errored = $ref(false); +let errored = $ref(isCustom.value && url.value == null); // Searching from an array with 2000 items for every emoji felt like too energy-consuming, so I decided to do it lazily on pointerenter function computeTitle(event: PointerEvent): void { diff --git a/packages/frontend/src/custom-emojis.ts b/packages/frontend/src/custom-emojis.ts index 19469999b6..637ee9c06e 100644 --- a/packages/frontend/src/custom-emojis.ts +++ b/packages/frontend/src/custom-emojis.ts @@ -2,14 +2,19 @@ import { api } from './os'; import { miLocalStorage } from './local-storage'; const storageCache = miLocalStorage.getItem('emojis'); -export let customEmojis = storageCache ? JSON.parse(storageCache) : []; +export let customEmojis: { + name: string; + aliases: string[]; + category: string; + url: string; +}[] = storageCache ? JSON.parse(storageCache) : []; fetchCustomEmojis(); export async function fetchCustomEmojis() { const now = Date.now(); const lastFetchedAt = miLocalStorage.getItem('lastEmojisFetchedAt'); - if (lastFetchedAt && (now - parseInt(lastFetchedAt)) < 1000 * 60 * 60) return; + if (lastFetchedAt && (now - parseInt(lastFetchedAt)) < 1000 * 60 * 60 * 24) return; const res = await api('emojis', {});