mirror of
https://github.com/misskey-dev/misskey.git
synced 2026-05-21 20:25:36 +02:00
feat(frontend): 絵文字をミュート可能にする機能 (#15966)
* wip ( 絵文字ミュートの基礎実装, PoC )
* refactor: 絵文字のmute/unmute処理の共通化
* SPDX
* リアクションからも絵文字ミュート可能に
* emojiMute/emojiUnmute
* replace resource of emojiMute
* add vitest preferstate for mutedEmojis
* add vitest to preferReactive
* 混入削除
* Fix typo (mutedEmojis -> mutingEmojis)
* reactiveやめる
* add時の判定ミスを修正
* Add CHANGELOG
* Revert "reactiveやめる"
This reverts commit 442742c371.
* Update Changelog
This commit is contained in:
105
packages/frontend/src/pages/settings/mute-block.emoji-mute.vue
Normal file
105
packages/frontend/src/pages/settings/mute-block.emoji-mute.vue
Normal file
@@ -0,0 +1,105 @@
|
||||
<!--
|
||||
SPDX-FileCopyrightText: syuilo and misskey-project
|
||||
SPDX-License-Identifier: AGPL-3.0-only
|
||||
-->
|
||||
|
||||
<template>
|
||||
<div :class="$style.emojis">
|
||||
<div v-for="emoji in emojis" :key="`emojiMute-${emoji}`" :class="$style.emoji" @click="onEmojiClick($event, emoji)">
|
||||
<MkCustomEmoji
|
||||
v-if="emoji.startsWith(':')"
|
||||
:name="customEmojiName(emoji)"
|
||||
:host="customEmojiHost(emoji)"
|
||||
:normal="true"
|
||||
:menu="false"
|
||||
:menuReaction="false"
|
||||
:ignoreMuted="true"
|
||||
/>
|
||||
<MkEmoji
|
||||
v-else
|
||||
:emoji="emoji"
|
||||
:menu="false"
|
||||
:menuReaction="false"
|
||||
:ignoreMuted="true"
|
||||
></MkEmoji>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<MkButton primary inline @click="add"><i class="ti ti-plus"></i> {{ i18n.ts.add }}</MkButton>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import type { MenuItem } from '@/types/menu';
|
||||
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,
|
||||
extractCustomEmojiName as customEmojiName,
|
||||
extractCustomEmojiHost as customEmojiHost,
|
||||
} from '@/utility/emoji-mute.js';
|
||||
|
||||
const emojis = prefer.model('mutingEmojis');
|
||||
|
||||
function getHTMLElement(ev: MouseEvent): HTMLElement {
|
||||
const target = ev.currentTarget ?? ev.target;
|
||||
return target as HTMLElement;
|
||||
}
|
||||
|
||||
function add(ev: MouseEvent) {
|
||||
os.pickEmoji(getHTMLElement(ev), { showPinned: false }).then((emoji) => {
|
||||
if (emoji) {
|
||||
muteEmoji(emoji);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function onEmojiClick(ev: MouseEvent, emoji: string) {
|
||||
const menuItems : MenuItem[] = [{
|
||||
type: 'label',
|
||||
text: emoji,
|
||||
}, {
|
||||
text: i18n.ts.emojiUnmute,
|
||||
icon: 'ti ti-mood-off',
|
||||
action: () => unmute(emoji),
|
||||
}];
|
||||
os.popupMenu(menuItems, ev.currentTarget ?? ev.target);
|
||||
}
|
||||
|
||||
function unmute(emoji: string) {
|
||||
os.confirm({
|
||||
type: 'question',
|
||||
title: i18n.tsx.unmuteX({ x: emoji }),
|
||||
}).then(({ canceled }) => {
|
||||
if (canceled) {
|
||||
return;
|
||||
}
|
||||
unmuteEmoji(emoji);
|
||||
});
|
||||
}
|
||||
</script>
|
||||
<style module>
|
||||
.emojis {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
align-items: center;
|
||||
gap: 4px;
|
||||
|
||||
&:empty {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
.emoji {
|
||||
display: inline-flex;
|
||||
height: 42px;
|
||||
padding: 0 6px;
|
||||
font-size: 1.5em;
|
||||
border-radius: 6px;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background: var(--MI_THEME-buttonBg);
|
||||
}
|
||||
</style>
|
||||
@@ -49,6 +49,20 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||
</MkFolder>
|
||||
</SearchMarker>
|
||||
|
||||
<SearchMarker
|
||||
:label="i18n.ts.emojiMute"
|
||||
:keywords="['emoji', 'mute', 'hide']"
|
||||
>
|
||||
<MkFolder>
|
||||
<template #icon><i class="ti ti-mood-off"></i></template>
|
||||
<template #label>{{ i18n.ts.emojiMute }}</template>
|
||||
|
||||
<div class="_gaps_m">
|
||||
<XEmojiMute/>
|
||||
</div>
|
||||
</mkfolder>
|
||||
</SearchMarker>
|
||||
|
||||
<SearchMarker
|
||||
:label="i18n.ts.instanceMute"
|
||||
:keywords="['note', 'server', 'instance', 'host', 'federation', 'mute', 'hide']"
|
||||
@@ -163,6 +177,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref, computed, watch } from 'vue';
|
||||
import XEmojiMute from './mute-block.emoji-mute.vue';
|
||||
import XInstanceMute from './mute-block.instance-mute.vue';
|
||||
import XWordMute from './mute-block.word-mute.vue';
|
||||
import MkPagination from '@/components/MkPagination.vue';
|
||||
|
||||
Reference in New Issue
Block a user