ローカルのカスタム絵文字については直接オリジナルURLにリクエストするように

This commit is contained in:
syuilo 2023-01-21 20:40:09 +09:00
parent bd469420fa
commit 3e112da486
5 changed files with 21 additions and 5 deletions

View file

@ -22,7 +22,7 @@ export class EmojiEntityService {
@bindThis @bindThis
public async pack( public async pack(
src: Emoji['id'] | Emoji, src: Emoji['id'] | Emoji,
opts: { omitHost?: boolean; omitId?: boolean; } = {}, opts: { omitHost?: boolean; omitId?: boolean; withUrl?: boolean; } = {},
): Promise<Packed<'Emoji'>> { ): Promise<Packed<'Emoji'>> {
const emoji = typeof src === 'object' ? src : await this.emojisRepository.findOneByOrFail({ id: src }); const emoji = typeof src === 'object' ? src : await this.emojisRepository.findOneByOrFail({ id: src });
@ -32,13 +32,15 @@ export class EmojiEntityService {
name: emoji.name, name: emoji.name,
category: emoji.category, category: emoji.category,
host: opts.omitHost ? undefined : emoji.host, host: opts.omitHost ? undefined : emoji.host,
// ?? emoji.originalUrl してるのは後方互換性のため
url: opts.withUrl ? (emoji.publicUrl ?? emoji.originalUrl) : undefined,
}; };
} }
@bindThis @bindThis
public packMany( public packMany(
emojis: any[], emojis: any[],
opts: { omitHost?: boolean; omitId?: boolean; } = {}, opts: { omitHost?: boolean; omitId?: boolean; withUrl?: boolean; } = {},
) { ) {
return Promise.all(emojis.map(x => this.pack(x, opts))); return Promise.all(emojis.map(x => this.pack(x, opts)));
} }

View file

@ -29,5 +29,9 @@ export const packedEmojiSchema = {
optional: true, nullable: true, optional: true, nullable: true,
description: 'The local host is represented with `null`.', description: 'The local host is represented with `null`.',
}, },
url: {
type: 'string',
optional: true, nullable: false,
},
}, },
} as const; } as const;

View file

@ -83,6 +83,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> {
emojis: await this.emojiEntityService.packMany(emojis, { emojis: await this.emojiEntityService.packMany(emojis, {
omitId: true, omitId: true,
omitHost: true, omitHost: true,
withUrl: true,
}), }),
}; };
}); });

View file

@ -12,6 +12,7 @@ import { getStaticImageUrl } from '@/scripts/media-proxy';
import { char2twemojiFilePath, char2fluentEmojiFilePath } from '@/scripts/emoji-base'; import { char2twemojiFilePath, char2fluentEmojiFilePath } from '@/scripts/emoji-base';
import { defaultStore } from '@/store'; import { defaultStore } from '@/store';
import { getEmojiName } from '@/scripts/emojilist'; import { getEmojiName } from '@/scripts/emojilist';
import { customEmojis } from '@/custom-emojis';
const props = defineProps<{ const props = defineProps<{
emoji: string; emoji: string;
@ -30,6 +31,9 @@ const useOsNativeEmojis = computed(() => defaultStore.state.emojiStyle === 'nati
const url = computed(() => { const url = computed(() => {
if (char.value) { if (char.value) {
return char2path(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 { } else {
const rawUrl = props.host ? `/emoji/${customEmojiName}@${props.host}.webp` : `/emoji/${customEmojiName}.webp`; const rawUrl = props.host ? `/emoji/${customEmojiName}@${props.host}.webp` : `/emoji/${customEmojiName}.webp`;
return defaultStore.state.disableShowingAnimatedImages return defaultStore.state.disableShowingAnimatedImages
@ -38,7 +42,7 @@ const url = computed(() => {
} }
}); });
const alt = computed(() => isCustom.value ? `:${customEmojiName}:` : char.value); 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 // 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 { function computeTitle(event: PointerEvent): void {

View file

@ -2,14 +2,19 @@ import { api } from './os';
import { miLocalStorage } from './local-storage'; import { miLocalStorage } from './local-storage';
const storageCache = miLocalStorage.getItem('emojis'); 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(); fetchCustomEmojis();
export async function fetchCustomEmojis() { export async function fetchCustomEmojis() {
const now = Date.now(); const now = Date.now();
const lastFetchedAt = miLocalStorage.getItem('lastEmojisFetchedAt'); 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', {}); const res = await api('emojis', {});