diff --git a/packages/frontend/src/components/MkEmojiPicker.vue b/packages/frontend/src/components/MkEmojiPicker.vue index 0d3d222f0c..7eeff8d2a4 100644 --- a/packages/frontend/src/components/MkEmojiPicker.vue +++ b/packages/frontend/src/components/MkEmojiPicker.vue @@ -49,7 +49,7 @@ SPDX-License-Identifier: AGPL-3.0-only @pointerenter="computeButtonTitle" @click="chosen(emoji, $event)" > - + @@ -67,7 +67,7 @@ SPDX-License-Identifier: AGPL-3.0-only @pointerenter="computeButtonTitle" @click="chosen(emoji, $event)" > - + @@ -108,7 +108,6 @@ import * as Misskey from 'misskey-js'; import XSection from '@/components/MkEmojiPicker.section.vue'; import { emojilist, - unicodeEmojisMap, emojiCharByCategory, UnicodeEmojiDef, unicodeEmojiCategories as categories, @@ -357,8 +356,8 @@ watch(q, () => { searchResultUnicode.value = Array.from(searchUnicode()); }); -function canReact(emoji: Misskey.entities.EmojiSimple | UnicodeEmojiDef): boolean { - return !props.targetNote || checkReactionPermissions($i!, props.targetNote, emoji); +function canReact(emoji: string | UnicodeEmojiDef | Misskey.entities.EmojiSimple): boolean { + return !props.targetNote || typeof emoji === 'string' || Object.hasOwn(emoji, 'char') || checkReactionPermissions($i!, props.targetNote, emoji); } function filterCategory(emoji: Misskey.entities.EmojiSimple, category: string): boolean { @@ -378,15 +377,21 @@ function reset() { q.value = ''; } -function getKey(emoji: string | Misskey.entities.EmojiSimple | UnicodeEmojiDef): string { - return typeof emoji === 'string' ? emoji : 'char' in emoji ? emoji.char : `:${emoji.name}:`; +function getKey(emoji: string | UnicodeEmojiDef | Misskey.entities.EmojiSimple): string { + if (typeof emoji === 'string') { + return emoji; + } else if (Object.hasOwn(emoji, 'char')) { + return (emoji as UnicodeEmojiDef).char; + } else { + return `:${emoji.name}:`; + } } function getDef(emoji: string) { if (emoji.includes(':')) { return customEmojisMap.get(emoji.replace(/:/g, '')) ?? null; } else { - return unicodeEmojisMap.get(emoji) ?? null; + return emoji; } } diff --git a/packages/frontend/src/components/MkReactionsViewer.reaction.vue b/packages/frontend/src/components/MkReactionsViewer.reaction.vue index bccee5109d..c33e50b2ce 100644 --- a/packages/frontend/src/components/MkReactionsViewer.reaction.vue +++ b/packages/frontend/src/components/MkReactionsViewer.reaction.vue @@ -34,7 +34,6 @@ import { i18n } from '@/i18n.js'; import * as sound from '@/scripts/sound.js'; import { checkReactionPermissions } from '@/scripts/check-reaction-permissions.js'; import { customEmojisMap } from '@/custom-emojis.js'; -import { unicodeEmojisMap } from '@/scripts/emojilist.js'; const props = defineProps<{ reaction: string; @@ -45,19 +44,24 @@ const props = defineProps<{ const mock = inject('mock', false); -const emit = defineEmits<{ - (ev: 'reactionToggled', emoji: string, newCount: number): void; -}>(); +const emit = defineEmits< + (ev: 'reactionToggled', emoji: string, newCount: number) => void +>(); const buttonEl = shallowRef(); +const remoteReactionRegExp = /@\w/; +const isCustomEmoji = computed(() => props.reaction.includes(':')); const emojiName = computed(() => props.reaction.replace(/:/g, '').replace(/@\./, '')); -const emoji = computed(() => customEmojisMap.get(emojiName.value) ?? unicodeEmojisMap.get(props.reaction)); +const emoji = computed(() => isCustomEmoji.value ? customEmojisMap.get(emojiName.value) : null); const canToggle = computed(() => { - return !props.reaction.match(/@\w/) && $i && emoji.value && checkReactionPermissions($i, props.note, emoji.value); + return !RegExp(remoteReactionRegExp).exec(props.reaction) && $i && ( + !isCustomEmoji.value + || (emoji.value && checkReactionPermissions($i, props.note, emoji.value)) + ); }); -const canGetInfo = computed(() => !props.reaction.match(/@\w/) && props.reaction.includes(':')); +const canGetInfo = computed(() => !RegExp(remoteReactionRegExp).exec(props.reaction) && props.reaction.includes(':')); async function toggleReaction() { if (!canToggle.value) return; diff --git a/packages/frontend/src/scripts/check-reaction-permissions.ts b/packages/frontend/src/scripts/check-reaction-permissions.ts index 293a97dbaa..530d4f8153 100644 --- a/packages/frontend/src/scripts/check-reaction-permissions.ts +++ b/packages/frontend/src/scripts/check-reaction-permissions.ts @@ -1,10 +1,6 @@ import * as Misskey from 'misskey-js'; -import { UnicodeEmojiDef } from './emojilist.js'; -export function checkReactionPermissions(me: Misskey.entities.MeDetailed, note: Misskey.entities.Note, emoji: Misskey.entities.EmojiSimple | UnicodeEmojiDef): boolean { - if ('char' in emoji) return true; // UnicodeEmojiDefなら常にリアクション可能 - - emoji = emoji as Misskey.entities.EmojiSimple; +export function checkReactionPermissions(me: Misskey.entities.MeDetailed, note: Misskey.entities.Note, emoji: Misskey.entities.EmojiSimple): boolean { const roleIdsThatCanBeUsedThisEmojiAsReaction = emoji.roleIdsThatCanBeUsedThisEmojiAsReaction ?? []; const roleIdsThatCanNotBeUsedThisEmojiAsReaction = emoji.roleIdsThatCanNotBeUsedThisEmojiAsReaction ?? []; diff --git a/packages/frontend/src/scripts/emojilist.ts b/packages/frontend/src/scripts/emojilist.ts index 4ec3a6455b..8ecdab96ea 100644 --- a/packages/frontend/src/scripts/emojilist.ts +++ b/packages/frontend/src/scripts/emojilist.ts @@ -20,10 +20,6 @@ export const emojilist: UnicodeEmojiDef[] = _emojilist.map(x => ({ category: unicodeEmojiCategories[x[2]], })); -export const unicodeEmojisMap = new Map( - emojilist.map(x => [x.char, x]) -); - const _indexByChar = new Map(); const _charGroupByCategory = new Map(); for (let i = 0; i < emojilist.length; i++) {