fix(frontend): MkCustomEmojiでフォールバックをテキストか画像か選べるように

fix of #13487
This commit is contained in:
tamaina 2024-03-02 07:05:17 +00:00
parent b83cbc6d4d
commit 2744cbd310
9 changed files with 20 additions and 9 deletions

View File

@ -22,7 +22,7 @@ SPDX-License-Identifier: AGPL-3.0-only
</ol> </ol>
<ol v-else-if="emojis.length > 0" ref="suggests" :class="$style.list"> <ol v-else-if="emojis.length > 0" ref="suggests" :class="$style.list">
<li v-for="emoji in emojis" :key="emoji.emoji" :class="$style.item" tabindex="-1" @click="complete(type, emoji.emoji)" @keydown="onKeydown"> <li v-for="emoji in emojis" :key="emoji.emoji" :class="$style.item" tabindex="-1" @click="complete(type, emoji.emoji)" @keydown="onKeydown">
<MkCustomEmoji v-if="'isCustomEmoji' in emoji && emoji.isCustomEmoji" :name="emoji.emoji" :class="$style.emoji"/> <MkCustomEmoji v-if="'isCustomEmoji' in emoji && emoji.isCustomEmoji" :name="emoji.emoji" :class="$style.emoji" :fallbackToImage="true"/>
<MkEmoji v-else :emoji="emoji.emoji" :class="$style.emoji"/> <MkEmoji v-else :emoji="emoji.emoji" :class="$style.emoji"/>
<!-- eslint-disable-next-line vue/no-v-html --> <!-- eslint-disable-next-line vue/no-v-html -->
<span v-if="q" :class="$style.emojiName" v-html="sanitizeHtml(emoji.name.replace(q, `<b>${q}</b>`))"></span> <span v-if="q" :class="$style.emojiName" v-html="sanitizeHtml(emoji.name.replace(q, `<b>${q}</b>`))"></span>

View File

@ -20,7 +20,7 @@ SPDX-License-Identifier: AGPL-3.0-only
@pointerenter="computeButtonTitle" @pointerenter="computeButtonTitle"
@click="emit('chosen', emoji, $event)" @click="emit('chosen', emoji, $event)"
> >
<MkCustomEmoji v-if="emoji[0] === ':'" class="emoji" :name="emoji" :normal="true"/> <MkCustomEmoji v-if="emoji[0] === ':'" class="emoji" :name="emoji" :normal="true" :fallbackToImage="true"/>
<MkEmoji v-else class="emoji" :emoji="emoji" :normal="true"/> <MkEmoji v-else class="emoji" :emoji="emoji" :normal="true"/>
</button> </button>
</div> </div>

View File

@ -19,7 +19,7 @@ SPDX-License-Identifier: AGPL-3.0-only
tabindex="0" tabindex="0"
@click="chosen(emoji, $event)" @click="chosen(emoji, $event)"
> >
<MkCustomEmoji class="emoji" :name="emoji.name"/> <MkCustomEmoji class="emoji" :name="emoji.name" :fallbackToImage="true"/>
</button> </button>
</div> </div>
<div v-if="searchResultUnicode.length > 0" class="body"> <div v-if="searchResultUnicode.length > 0" class="body">

View File

@ -4,7 +4,7 @@ SPDX-License-Identifier: AGPL-3.0-only
--> -->
<template> <template>
<MkCustomEmoji v-if="reaction[0] === ':'" ref="elRef" :name="reaction" :normal="true" :noStyle="noStyle" :url="emojiUrl"/> <MkCustomEmoji v-if="reaction[0] === ':'" ref="elRef" :name="reaction" :normal="true" :noStyle="noStyle" :url="emojiUrl" :fallbackToImage="true"/>
<MkEmoji v-else ref="elRef" :emoji="reaction" :normal="true" :noStyle="noStyle"/> <MkEmoji v-else ref="elRef" :emoji="reaction" :normal="true" :noStyle="noStyle"/>
</template> </template>

View File

@ -48,10 +48,18 @@ export const Missing = {
name: Default.args.name, name: Default.args.name,
}, },
} satisfies StoryObj<typeof MkCustomEmoji>; } satisfies StoryObj<typeof MkCustomEmoji>;
export const Error = { export const ErrorToText = {
...Default, ...Default,
args: { args: {
url: 'https://example.com/404', url: 'https://example.com/404',
name: Default.args.name, name: Default.args.name,
}, },
} satisfies StoryObj<typeof MkCustomEmoji>; } satisfies StoryObj<typeof MkCustomEmoji>;
export const ErrorToImage = {
...Default,
args: {
url: 'https://example.com/404',
name: Default.args.name,
fallbackToImage: true,
},
} satisfies StoryObj<typeof MkCustomEmoji>;

View File

@ -5,11 +5,12 @@ SPDX-License-Identifier: AGPL-3.0-only
<template> <template>
<img <img
v-if="errored" v-if="errored && fallbackToImage"
:class="[$style.root, { [$style.normal]: normal, [$style.noStyle]: noStyle }]" :class="[$style.root, { [$style.normal]: normal, [$style.noStyle]: noStyle }]"
src="/client-assets/dummy.png" src="/client-assets/dummy.png"
:title="alt" :title="alt"
/> />
<span v-else-if="errored">:{{ customEmojiName }}:</span>
<img <img
v-else v-else
:class="[$style.root, { [$style.normal]: normal, [$style.noStyle]: noStyle }]" :class="[$style.root, { [$style.normal]: normal, [$style.noStyle]: noStyle }]"
@ -44,6 +45,7 @@ const props = defineProps<{
useOriginalSize?: boolean; useOriginalSize?: boolean;
menu?: boolean; menu?: boolean;
menuReaction?: boolean; menuReaction?: boolean;
fallbackToImage?: boolean;
}>(); }>();
const react = inject<((name: string) => void) | null>('react', null); const react = inject<((name: string) => void) | null>('react', null);

View File

@ -407,6 +407,7 @@ export default function (props: MfmProps, { emit }: { emit: SetupContext<MfmEven
useOriginalSize: scale >= 2.5, useOriginalSize: scale >= 2.5,
menu: props.enableEmojiMenu, menu: props.enableEmojiMenu,
menuReaction: props.enableEmojiMenuReaction, menuReaction: props.enableEmojiMenuReaction,
fallbackToImage: false,
})]; })];
} else { } else {
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition

View File

@ -15,7 +15,7 @@ SPDX-License-Identifier: AGPL-3.0-only
<div class="misskey">Misskey</div> <div class="misskey">Misskey</div>
<div class="version">v{{ version }}</div> <div class="version">v{{ version }}</div>
<span v-for="emoji in easterEggEmojis" :key="emoji.id" class="emoji" :data-physics-x="emoji.left" :data-physics-y="emoji.top" :class="{ _physics_circle_: !emoji.emoji.startsWith(':') }"> <span v-for="emoji in easterEggEmojis" :key="emoji.id" class="emoji" :data-physics-x="emoji.left" :data-physics-y="emoji.top" :class="{ _physics_circle_: !emoji.emoji.startsWith(':') }">
<MkCustomEmoji v-if="emoji.emoji[0] === ':'" class="emoji" :name="emoji.emoji" :normal="true" :noStyle="true"/> <MkCustomEmoji v-if="emoji.emoji[0] === ':'" class="emoji" :name="emoji.emoji" :normal="true" :noStyle="true" :fallbackToImage="true"/>
<MkEmoji v-else class="emoji" :emoji="emoji.emoji" :normal="true" :noStyle="true"/> <MkEmoji v-else class="emoji" :emoji="emoji.emoji" :normal="true" :noStyle="true"/>
</span> </span>
</div> </div>

View File

@ -23,7 +23,7 @@ SPDX-License-Identifier: AGPL-3.0-only
> >
<template #item="{element}"> <template #item="{element}">
<button class="_button" :class="$style.emojisItem" @click="removeReaction(element, $event)"> <button class="_button" :class="$style.emojisItem" @click="removeReaction(element, $event)">
<MkCustomEmoji v-if="element[0] === ':'" :name="element" :normal="true"/> <MkCustomEmoji v-if="element[0] === ':'" :name="element" :normal="true" :fallbackToImage="true"/>
<MkEmoji v-else :emoji="element" :normal="true"/> <MkEmoji v-else :emoji="element" :normal="true"/>
</button> </button>
</template> </template>
@ -63,7 +63,7 @@ SPDX-License-Identifier: AGPL-3.0-only
> >
<template #item="{element}"> <template #item="{element}">
<button class="_button" :class="$style.emojisItem" @click="removeEmoji(element, $event)"> <button class="_button" :class="$style.emojisItem" @click="removeEmoji(element, $event)">
<MkCustomEmoji v-if="element[0] === ':'" :name="element" :normal="true"/> <MkCustomEmoji v-if="element[0] === ':'" :name="element" :normal="true" :fallbackToImage="true"/>
<MkEmoji v-else :emoji="element" :normal="true"/> <MkEmoji v-else :emoji="element" :normal="true"/>
</button> </button>
</template> </template>