diff options
Diffstat (limited to 'packages/frontend/src/components/global/MkCustomEmoji.vue')
| -rw-r--r-- | packages/frontend/src/components/global/MkCustomEmoji.vue | 112 |
1 files changed, 91 insertions, 21 deletions
diff --git a/packages/frontend/src/components/global/MkCustomEmoji.vue b/packages/frontend/src/components/global/MkCustomEmoji.vue index dda45ceaa2..ed114d8d31 100644 --- a/packages/frontend/src/components/global/MkCustomEmoji.vue +++ b/packages/frontend/src/components/global/MkCustomEmoji.vue @@ -5,7 +5,16 @@ SPDX-License-Identifier: AGPL-3.0-only <template> <img - v-if="errored && fallbackToImage" + v-if="shouldMute" + :class="[$style.root, { [$style.normal]: normal, [$style.noStyle]: noStyle }]" + src="/client-assets/unknown.png" + :title="alt" + draggable="false" + style="-webkit-user-drag: none;" + @click="onClick" +/> +<img + v-else-if="errored && fallbackToImage" :class="[$style.root, { [$style.normal]: normal, [$style.noStyle]: noStyle }]" src="/client-assets/dummy.png" :title="alt" @@ -40,6 +49,7 @@ import MkCustomEmojiDetailedDialog from '@/components/MkCustomEmojiDetailedDialo import { $i } from '@/i.js'; import { prefer } from '@/preferences.js'; import { DI } from '@/di.js'; +import { makeEmojiMuteKey, mute as muteEmoji, unmute as unmuteEmoji, checkMuted as checkEmojiMuted } from '@/utility/emoji-mute'; const props = defineProps<{ name: string; @@ -51,12 +61,16 @@ const props = defineProps<{ menu?: boolean; menuReaction?: boolean; fallbackToImage?: boolean; + ignoreMuted?: boolean; }>(); const react = inject(DI.mfmEmojiReactCallback); 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 emojiCodeToMute = makeEmojiMuteKey(props); +const isMuted = checkEmojiMuted(emojiCodeToMute); +const shouldMute = computed(() => !props.ignoreMuted && isMuted.value); const rawUrl = computed(() => { if (props.url) { @@ -95,14 +109,18 @@ function onClick(ev: MouseEvent) { menuItems.push({ type: 'label', text: `:${props.name}:`, - }, { - text: i18n.ts.copy, - icon: 'ti ti-copy', - action: () => { - copyToClipboard(`:${props.name}:`); - }, }); + if (isLocal.value) { + menuItems.push({ + text: i18n.ts.copy, + icon: 'ti ti-copy', + action: () => { + copyToClipboard(`:${props.name}:`); + }, + }); + } + if (props.menuReaction && react) { menuItems.push({ text: i18n.ts.doReaction, @@ -113,21 +131,43 @@ function onClick(ev: MouseEvent) { }); } - menuItems.push({ - text: i18n.ts.info, - icon: 'ti ti-info-circle', - action: async () => { - const { dispose } = os.popup(MkCustomEmojiDetailedDialog, { - emoji: await misskeyApiGet('emoji', { - name: customEmojiName.value, - }), - }, { - closed: () => dispose(), - }); - }, - }); + if (isLocal.value) { + menuItems.push({ + type: 'divider', + }, { + text: i18n.ts.info, + icon: 'ti ti-info-circle', + action: async () => { + const { dispose } = os.popup(MkCustomEmojiDetailedDialog, { + emoji: await misskeyApiGet('emoji', { + name: customEmojiName.value, + }), + }, { + closed: () => dispose(), + }); + }, + }); + } - if ($i?.isModerator ?? $i?.isAdmin) { + if (isMuted.value) { + menuItems.push({ + text: i18n.ts.emojiUnmute, + icon: 'ti ti-mood-smile', + action: async () => { + await unmute(); + }, + }); + } else { + menuItems.push({ + text: i18n.ts.emojiMute, + icon: 'ti ti-mood-off', + action: async () => { + await mute(); + }, + }); + } + + if (($i?.isModerator ?? $i?.isAdmin) && isLocal.value) { menuItems.push({ text: i18n.ts.edit, icon: 'ti ti-pencil', @@ -152,6 +192,36 @@ async function edit(name: string) { }); } +function mute() { + const titleEmojiName = isLocal.value + ? `:${customEmojiName.value}:` + : emojiCodeToMute; + os.confirm({ + type: 'question', + title: i18n.tsx.muteX({ x: titleEmojiName }), + }).then(({ canceled }) => { + if (canceled) { + return; + } + muteEmoji(emojiCodeToMute); + }); +} + +function unmute() { + const titleEmojiName = isLocal.value + ? `:${customEmojiName.value}:` + : emojiCodeToMute; + os.confirm({ + type: 'question', + title: i18n.tsx.unmuteX({ x: titleEmojiName }), + }).then(({ canceled }) => { + if (canceled) { + return; + } + unmuteEmoji(emojiCodeToMute); + }); +} + </script> <style lang="scss" module> |