wip
This commit is contained in:
98
packages/frontend-embed/src/components/EmCustomEmoji.vue
Normal file
98
packages/frontend-embed/src/components/EmCustomEmoji.vue
Normal file
@@ -0,0 +1,98 @@
|
||||
<!--
|
||||
SPDX-FileCopyrightText: syuilo and misskey-project
|
||||
SPDX-License-Identifier: AGPL-3.0-only
|
||||
-->
|
||||
|
||||
<template>
|
||||
<img
|
||||
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 }]"
|
||||
:src="url"
|
||||
:alt="alt"
|
||||
:title="alt"
|
||||
decoding="async"
|
||||
@error="errored = true"
|
||||
@load="errored = false"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { computed, inject, ref } from 'vue';
|
||||
import { getProxiedImageUrl } from '@/scripts/media-proxy.js';
|
||||
import { customEmojisMap } from '@/custom-emojis.js';
|
||||
|
||||
const props = defineProps<{
|
||||
name: string;
|
||||
normal?: boolean;
|
||||
noStyle?: boolean;
|
||||
host?: string | null;
|
||||
url?: string;
|
||||
useOriginalSize?: boolean;
|
||||
menu?: boolean;
|
||||
menuReaction?: boolean;
|
||||
fallbackToImage?: boolean;
|
||||
}>();
|
||||
|
||||
const customEmojiName = computed(() => (props.name[0] === ':' ? props.name.substring(1, props.name.length - 1) : props.name).replace('@.', ''));
|
||||
const isLocal = computed(() => !props.host && (customEmojiName.value.endsWith('@.') || !customEmojiName.value.includes('@')));
|
||||
|
||||
const rawUrl = computed(() => {
|
||||
if (props.url) {
|
||||
return props.url;
|
||||
}
|
||||
if (isLocal.value) {
|
||||
return customEmojisMap.get(customEmojiName.value)?.url ?? null;
|
||||
}
|
||||
return props.host ? `/emoji/${customEmojiName.value}@${props.host}.webp` : `/emoji/${customEmojiName.value}.webp`;
|
||||
});
|
||||
|
||||
const url = computed(() => {
|
||||
if (rawUrl.value == null) return undefined;
|
||||
|
||||
const proxied =
|
||||
(rawUrl.value.startsWith('/emoji/') || (props.useOriginalSize && isLocal.value))
|
||||
? rawUrl.value
|
||||
: getProxiedImageUrl(
|
||||
rawUrl.value,
|
||||
props.useOriginalSize ? undefined : 'emoji',
|
||||
false,
|
||||
true,
|
||||
);
|
||||
return proxied;
|
||||
});
|
||||
|
||||
const alt = computed(() => `:${customEmojiName.value}:`);
|
||||
const errored = ref(url.value == null);
|
||||
</script>
|
||||
|
||||
<style lang="scss" module>
|
||||
.root {
|
||||
height: 2em;
|
||||
vertical-align: middle;
|
||||
transition: transform 0.2s ease;
|
||||
|
||||
&:hover {
|
||||
transform: scale(1.2);
|
||||
}
|
||||
}
|
||||
|
||||
.normal {
|
||||
height: 1.25em;
|
||||
vertical-align: -0.25em;
|
||||
|
||||
&:hover {
|
||||
transform: none;
|
||||
}
|
||||
}
|
||||
|
||||
.noStyle {
|
||||
height: auto !important;
|
||||
}
|
||||
</style>
|
Reference in New Issue
Block a user