From 2744cbd310e7e1b7792fe455602f6e2cf376120d Mon Sep 17 00:00:00 2001
From: tamaina <tamaina@hotmail.co.jp>
Date: Sat, 2 Mar 2024 07:05:17 +0000
Subject: [PATCH] =?UTF-8?q?fix(frontend):=20MkCustomEmoji=E3=81=A7?=
 =?UTF-8?q?=E3=83=95=E3=82=A9=E3=83=BC=E3=83=AB=E3=83=90=E3=83=83=E3=82=AF?=
 =?UTF-8?q?=E3=82=92=E3=83=86=E3=82=AD=E3=82=B9=E3=83=88=E3=81=8B=E7=94=BB?=
 =?UTF-8?q?=E5=83=8F=E3=81=8B=E9=81=B8=E3=81=B9=E3=82=8B=E3=82=88=E3=81=86?=
 =?UTF-8?q?=E3=81=AB=20fix=20of=20#13487?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 packages/frontend/src/components/MkAutocomplete.vue    |  2 +-
 .../frontend/src/components/MkEmojiPicker.section.vue  |  2 +-
 packages/frontend/src/components/MkEmojiPicker.vue     |  2 +-
 packages/frontend/src/components/MkReactionIcon.vue    |  2 +-
 .../components/global/MkCustomEmoji.stories.impl.ts    | 10 +++++++++-
 .../frontend/src/components/global/MkCustomEmoji.vue   |  4 +++-
 .../src/components/global/MkMisskeyFlavoredMarkdown.ts |  1 +
 packages/frontend/src/pages/about-misskey.vue          |  2 +-
 packages/frontend/src/pages/settings/emoji-picker.vue  |  4 ++--
 9 files changed, 20 insertions(+), 9 deletions(-)

diff --git a/packages/frontend/src/components/MkAutocomplete.vue b/packages/frontend/src/components/MkAutocomplete.vue
index 2f3855266..932c4ecb2 100644
--- a/packages/frontend/src/components/MkAutocomplete.vue
+++ b/packages/frontend/src/components/MkAutocomplete.vue
@@ -22,7 +22,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 	</ol>
 	<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">
-			<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"/>
 			<!-- 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>
diff --git a/packages/frontend/src/components/MkEmojiPicker.section.vue b/packages/frontend/src/components/MkEmojiPicker.section.vue
index 012972d8e..c13164c29 100644
--- a/packages/frontend/src/components/MkEmojiPicker.section.vue
+++ b/packages/frontend/src/components/MkEmojiPicker.section.vue
@@ -20,7 +20,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 			@pointerenter="computeButtonTitle"
 			@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"/>
 		</button>
 	</div>
diff --git a/packages/frontend/src/components/MkEmojiPicker.vue b/packages/frontend/src/components/MkEmojiPicker.vue
index e30d5969d..8a6bef54d 100644
--- a/packages/frontend/src/components/MkEmojiPicker.vue
+++ b/packages/frontend/src/components/MkEmojiPicker.vue
@@ -19,7 +19,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 					tabindex="0"
 					@click="chosen(emoji, $event)"
 				>
-					<MkCustomEmoji class="emoji" :name="emoji.name"/>
+					<MkCustomEmoji class="emoji" :name="emoji.name" :fallbackToImage="true"/>
 				</button>
 			</div>
 			<div v-if="searchResultUnicode.length > 0" class="body">
diff --git a/packages/frontend/src/components/MkReactionIcon.vue b/packages/frontend/src/components/MkReactionIcon.vue
index 59ceab27d..068a2968d 100644
--- a/packages/frontend/src/components/MkReactionIcon.vue
+++ b/packages/frontend/src/components/MkReactionIcon.vue
@@ -4,7 +4,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 -->
 
 <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"/>
 </template>
 
diff --git a/packages/frontend/src/components/global/MkCustomEmoji.stories.impl.ts b/packages/frontend/src/components/global/MkCustomEmoji.stories.impl.ts
index 2e791e991..9e6177045 100644
--- a/packages/frontend/src/components/global/MkCustomEmoji.stories.impl.ts
+++ b/packages/frontend/src/components/global/MkCustomEmoji.stories.impl.ts
@@ -48,10 +48,18 @@ export const Missing = {
 		name: Default.args.name,
 	},
 } satisfies StoryObj<typeof MkCustomEmoji>;
-export const Error = {
+export const ErrorToText = {
 	...Default,
 	args: {
 		url: 'https://example.com/404',
 		name: Default.args.name,
 	},
 } satisfies StoryObj<typeof MkCustomEmoji>;
+export const ErrorToImage = {
+	...Default,
+	args: {
+		url: 'https://example.com/404',
+		name: Default.args.name,
+		fallbackToImage: true,
+	},
+} satisfies StoryObj<typeof MkCustomEmoji>;
diff --git a/packages/frontend/src/components/global/MkCustomEmoji.vue b/packages/frontend/src/components/global/MkCustomEmoji.vue
index 67927ddd2..612383534 100644
--- a/packages/frontend/src/components/global/MkCustomEmoji.vue
+++ b/packages/frontend/src/components/global/MkCustomEmoji.vue
@@ -5,11 +5,12 @@ SPDX-License-Identifier: AGPL-3.0-only
 
 <template>
 <img
-	v-if="errored"
+	v-if="errored && fallbackToImage"
 	:class="[$style.root, { [$style.normal]: normal, [$style.noStyle]: noStyle }]"
 	src="/client-assets/dummy.png"
 	:title="alt"
 />
+<span v-else-if="errored">:{{ customEmojiName }}:</span>
 <img
 	v-else
 	:class="[$style.root, { [$style.normal]: normal, [$style.noStyle]: noStyle }]"
@@ -44,6 +45,7 @@ const props = defineProps<{
 	useOriginalSize?: boolean;
 	menu?: boolean;
 	menuReaction?: boolean;
+	fallbackToImage?: boolean;
 }>();
 
 const react = inject<((name: string) => void) | null>('react', null);
diff --git a/packages/frontend/src/components/global/MkMisskeyFlavoredMarkdown.ts b/packages/frontend/src/components/global/MkMisskeyFlavoredMarkdown.ts
index 6ce3b6752..4ed76f6bc 100644
--- a/packages/frontend/src/components/global/MkMisskeyFlavoredMarkdown.ts
+++ b/packages/frontend/src/components/global/MkMisskeyFlavoredMarkdown.ts
@@ -407,6 +407,7 @@ export default function (props: MfmProps, { emit }: { emit: SetupContext<MfmEven
 						useOriginalSize: scale >= 2.5,
 						menu: props.enableEmojiMenu,
 						menuReaction: props.enableEmojiMenuReaction,
+						fallbackToImage: false,
 					})];
 				} else {
 					// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
diff --git a/packages/frontend/src/pages/about-misskey.vue b/packages/frontend/src/pages/about-misskey.vue
index fd97ab97b..1a49dbf1d 100644
--- a/packages/frontend/src/pages/about-misskey.vue
+++ b/packages/frontend/src/pages/about-misskey.vue
@@ -15,7 +15,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 						<div class="misskey">Misskey</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(':') }">
-							<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"/>
 						</span>
 					</div>
diff --git a/packages/frontend/src/pages/settings/emoji-picker.vue b/packages/frontend/src/pages/settings/emoji-picker.vue
index ce296ec18..dc3e3ee50 100644
--- a/packages/frontend/src/pages/settings/emoji-picker.vue
+++ b/packages/frontend/src/pages/settings/emoji-picker.vue
@@ -23,7 +23,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 					>
 						<template #item="{element}">
 							<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"/>
 							</button>
 						</template>
@@ -63,7 +63,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 					>
 						<template #item="{element}">
 							<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"/>
 							</button>
 						</template>