リアクションからも絵文字ミュート可能に
This commit is contained in:
parent
8dfa382869
commit
9c32a66689
|
@ -22,6 +22,7 @@ import { computed, inject, onMounted, useTemplateRef, watch } from 'vue';
|
|||
import * as Misskey from 'misskey-js';
|
||||
import { getUnicodeEmoji } from '@@/js/emojilist.js';
|
||||
import MkCustomEmojiDetailedDialog from './MkCustomEmojiDetailedDialog.vue';
|
||||
import type { MenuItem } from '@/types/menu';
|
||||
import XDetails from '@/components/MkReactionsViewer.details.vue';
|
||||
import MkReactionIcon from '@/components/MkReactionIcon.vue';
|
||||
import * as os from '@/os.js';
|
||||
|
@ -36,6 +37,7 @@ import { checkReactionPermissions } from '@/utility/check-reaction-permissions.j
|
|||
import { customEmojisMap } from '@/custom-emojis.js';
|
||||
import { prefer } from '@/preferences.js';
|
||||
import { DI } from '@/di.js';
|
||||
import { mute as muteEmoji, unmute as unmuteEmoji, checkMuted as isEmojiMuted } from '@/utility/emoji-mute.js';
|
||||
|
||||
const props = defineProps<{
|
||||
reaction: string;
|
||||
|
@ -59,6 +61,7 @@ const canToggle = computed(() => {
|
|||
return !props.reaction.match(/@\w/) && $i && emoji.value && checkReactionPermissions($i, props.note, emoji.value);
|
||||
});
|
||||
const canGetInfo = computed(() => !props.reaction.match(/@\w/) && props.reaction.includes(':'));
|
||||
const isLocalCustomEmoji = props.reaction[0] === ':' && props.reaction.includes('@.');
|
||||
|
||||
async function toggleReaction() {
|
||||
if (!canToggle.value) return;
|
||||
|
@ -118,21 +121,55 @@ async function toggleReaction() {
|
|||
}
|
||||
|
||||
async function menu(ev) {
|
||||
if (!canGetInfo.value) return;
|
||||
let menuItems: MenuItem[] = [];
|
||||
|
||||
os.popupMenu([{
|
||||
text: i18n.ts.info,
|
||||
icon: 'ti ti-info-circle',
|
||||
action: async () => {
|
||||
const { dispose } = os.popup(MkCustomEmojiDetailedDialog, {
|
||||
emoji: await misskeyApiGet('emoji', {
|
||||
name: props.reaction.replace(/:/g, '').replace(/@\./, ''),
|
||||
}),
|
||||
}, {
|
||||
closed: () => dispose(),
|
||||
});
|
||||
},
|
||||
}], ev.currentTarget ?? ev.target);
|
||||
if (canGetInfo.value) {
|
||||
menuItems.push({
|
||||
text: i18n.ts.info,
|
||||
icon: 'ti ti-info-circle',
|
||||
action: async () => {
|
||||
const { dispose } = os.popup(MkCustomEmojiDetailedDialog, {
|
||||
emoji: await misskeyApiGet('emoji', {
|
||||
name: props.reaction.replace(/:/g, '').replace(/@\./, ''),
|
||||
}),
|
||||
}, {
|
||||
closed: () => dispose(),
|
||||
});
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
if (isEmojiMuted(props.reaction).value) {
|
||||
menuItems.push({
|
||||
text: i18n.ts.unmute,
|
||||
icon: 'ti ti-mood-smile',
|
||||
action: () => {
|
||||
os.confirm({
|
||||
type: 'question',
|
||||
title: i18n.tsx.unmuteX({ x: isLocalCustomEmoji ? `:${emojiName.value}:` : props.reaction }),
|
||||
}).then(({ canceled }) => {
|
||||
if (canceled) return;
|
||||
unmuteEmoji(props.reaction);
|
||||
});
|
||||
},
|
||||
});
|
||||
} else {
|
||||
menuItems.push({
|
||||
text: i18n.ts.mute,
|
||||
icon: 'ti ti-mood-off',
|
||||
action: () => {
|
||||
os.confirm({
|
||||
type: 'question',
|
||||
title: i18n.tsx.muteX({ x: isLocalCustomEmoji ? `:${emojiName.value}:` : props.reaction }),
|
||||
}).then(({ canceled }) => {
|
||||
if (canceled) return;
|
||||
muteEmoji(props.reaction);
|
||||
});
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
os.popupMenu(menuItems, ev.currentTarget ?? ev.target);
|
||||
}
|
||||
|
||||
function anime() {
|
||||
|
|
|
@ -60,7 +60,7 @@ 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 = computed(() => checkEmojiMuted(emojiCodeToMute));
|
||||
const isMuted = checkEmojiMuted(emojiCodeToMute);
|
||||
const shouldMute = computed(() => !props.ignoreMuted && isMuted.value);
|
||||
|
||||
const rawUrl = computed(() => {
|
||||
|
@ -174,9 +174,12 @@ async function edit(name: string) {
|
|||
}
|
||||
|
||||
function mute() {
|
||||
const titleEmojiName = isLocal.value
|
||||
? `:${customEmojiName.value}:`
|
||||
: emojiCodeToMute;
|
||||
os.confirm({
|
||||
type: 'question',
|
||||
title: i18n.tsx.muteX({ x: emojiCodeToMute }),
|
||||
title: i18n.tsx.muteX({ x: titleEmojiName }),
|
||||
}).then(({ canceled }) => {
|
||||
if (canceled) {
|
||||
return;
|
||||
|
|
|
@ -34,24 +34,15 @@ import MkButton from '@/components/MkButton.vue';
|
|||
import * as os from '@/os.js';
|
||||
import { i18n } from '@/i18n.js';
|
||||
import { prefer } from '@/preferences.js';
|
||||
import { mute as muteEmoji, unmute as unmuteEmoji, checkMuted as isMuted } from '@/utility/emoji-mute.js';
|
||||
import {
|
||||
mute as muteEmoji,
|
||||
unmute as unmuteEmoji,
|
||||
extractCustomEmojiName as customEmojiName,
|
||||
extractCustomEmojiHost as customEmojiHost,
|
||||
} from '@/utility/emoji-mute.js';
|
||||
|
||||
const emojis = prefer.model('mutingEmojis');
|
||||
|
||||
function customEmojiName (name:string) {
|
||||
return (name[0] === ':' ? name.substring(1, name.length - 1) : name).replace('@.', '').split('@')[0];
|
||||
}
|
||||
|
||||
function customEmojiHost (name:string) {
|
||||
// nameは:emojiName@host:の形式
|
||||
// 取り出したい部分はhostなので、@以降を取り出す
|
||||
const index = name.indexOf('@');
|
||||
if (index === -1) {
|
||||
return null;
|
||||
}
|
||||
return name.substring(index + 1, name.length - 1);
|
||||
}
|
||||
|
||||
function getHTMLElement(ev: MouseEvent): HTMLElement {
|
||||
const target = ev.currentTarget ?? ev.target;
|
||||
return target as HTMLElement;
|
||||
|
|
|
@ -11,22 +11,50 @@ export function makeEmojiMuteKey(props: { name: string; host?: string | null })
|
|||
return props.name.startsWith(':') ? props.name : `:${props.name}${props.host ? `@${props.host}` : ''}:`;
|
||||
}
|
||||
|
||||
export function extractCustomEmojiName (name:string) {
|
||||
return (name[0] === ':' ? name.substring(1, name.length - 1) : name).replace('@.', '').split('@')[0];
|
||||
}
|
||||
|
||||
export function extractCustomEmojiHost (name:string) {
|
||||
// nameは:emojiName@host:の形式
|
||||
// 取り出したい部分はhostなので、@以降を取り出す
|
||||
const index = name.indexOf('@');
|
||||
if (index === -1) {
|
||||
return null;
|
||||
}
|
||||
const host = name.substring(index + 1, name.length - 1);
|
||||
if (host === '' || host === '.') {
|
||||
return null;
|
||||
}
|
||||
return host;
|
||||
}
|
||||
|
||||
export function mute(emoji: string) {
|
||||
const isCustomEmoji = emoji.startsWith(':') && emoji.endsWith(':');
|
||||
const emojiMuteKey = isCustomEmoji ?
|
||||
makeEmojiMuteKey({ name: extractCustomEmojiName(emoji), host: extractCustomEmojiHost(emoji) }) :
|
||||
emoji;
|
||||
const mutedEmojis = prefer.r.mutingEmojis.value;
|
||||
if (!mutedEmojis.includes(emoji)) {
|
||||
prefer.commit('mutingEmojis', [...mutedEmojis, emoji]);
|
||||
prefer.commit('mutingEmojis', [...mutedEmojis, emojiMuteKey]);
|
||||
}
|
||||
}
|
||||
|
||||
export function unmute(emoji:string) {
|
||||
const isCustomEmoji = emoji.startsWith(':') && emoji.endsWith(':');
|
||||
const emojiMuteKey = isCustomEmoji ?
|
||||
makeEmojiMuteKey({ name: extractCustomEmojiName(emoji), host: extractCustomEmojiHost(emoji) }) :
|
||||
emoji;
|
||||
const mutedEmojis = prefer.r.mutingEmojis.value;
|
||||
const index = mutedEmojis.indexOf(emoji);
|
||||
if (index !== -1) {
|
||||
mutedEmojis.splice(index, 1);
|
||||
prefer.commit('mutingEmojis', mutedEmojis);
|
||||
}
|
||||
console.log('unmute', emoji, emojiMuteKey);
|
||||
console.log('mutedEmojis', mutedEmojis);
|
||||
prefer.commit('mutingEmojis', mutedEmojis.filter((e) => e !== emojiMuteKey));
|
||||
}
|
||||
|
||||
export function checkMuted(emoji: string) {
|
||||
return computed(() => prefer.r.mutingEmojis.value.includes(emoji));
|
||||
const isCustomEmoji = emoji.startsWith(':') && emoji.endsWith(':');
|
||||
const emojiMuteKey = isCustomEmoji ?
|
||||
makeEmojiMuteKey({ name: extractCustomEmojiName(emoji), host: extractCustomEmojiHost(emoji) }) :
|
||||
emoji;
|
||||
return computed(() => prefer.r.mutingEmojis.value.includes(emojiMuteKey));
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue