1
0
Fork 0
mirror of https://github.com/paricafe/misskey.git synced 2025-04-01 09:09:29 -05:00

enhance(frontend): refactor and improve ux

This commit is contained in:
syuilo 2025-03-25 18:30:28 +09:00
parent de76a66c03
commit 22f99b42f6
6 changed files with 38 additions and 11 deletions

View file

@ -379,7 +379,8 @@ const keymap = {
},
} as const satisfies Keymap;
provide('react', (reaction: string) => {
provide(DI.mfmEmojiReactCallback, (reaction) => {
sound.playMisskeySfx('reaction');
misskeyApi('notes/reactions/create', {
noteId: appearNote.value.id,
reaction: reaction,

View file

@ -256,6 +256,7 @@ import { isEnabledUrlPreview } from '@/instance.js';
import { getAppearNote } from '@/utility/get-appear-note.js';
import { prefer } from '@/preferences.js';
import { getPluginHandlers } from '@/plugin.js';
import { DI } from '@/di.js';
const props = withDefaults(defineProps<{
note: Misskey.entities.Note;
@ -337,7 +338,8 @@ const keymap = {
},
} as const satisfies Keymap;
provide('react', (reaction: string) => {
provide(DI.mfmEmojiReactCallback, (reaction) => {
sound.playMisskeySfx('reaction');
misskeyApi('notes/reactions/create', {
noteId: appearNote.value.id,
reaction: reaction,

View file

@ -35,11 +35,11 @@ import { customEmojisMap } from '@/custom-emojis.js';
import * as os from '@/os.js';
import { misskeyApi, misskeyApiGet } from '@/utility/misskey-api.js';
import { copyToClipboard } from '@/utility/copy-to-clipboard.js';
import * as sound from '@/utility/sound.js';
import { i18n } from '@/i18n.js';
import MkCustomEmojiDetailedDialog from '@/components/MkCustomEmojiDetailedDialog.vue';
import { $i } from '@/i.js';
import { prefer } from '@/preferences.js';
import { DI } from '@/di.js';
const props = defineProps<{
name: string;
@ -53,7 +53,7 @@ const props = defineProps<{
fallbackToImage?: boolean;
}>();
const react = inject<((name: string) => void) | null>('react', null);
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('@')));
@ -109,7 +109,6 @@ function onClick(ev: MouseEvent) {
icon: 'ti ti-plus',
action: () => {
react(`:${props.name}:`);
sound.playMisskeySfx('reaction');
},
});
}

View file

@ -15,9 +15,9 @@ import { char2fluentEmojiFilePath, char2twemojiFilePath } from '@@/js/emoji-base
import type { MenuItem } from '@/types/menu.js';
import * as os from '@/os.js';
import { copyToClipboard } from '@/utility/copy-to-clipboard.js';
import * as sound from '@/utility/sound.js';
import { i18n } from '@/i18n.js';
import { prefer } from '@/preferences.js';
import { DI } from '@/di.js';
const props = defineProps<{
emoji: string;
@ -25,7 +25,7 @@ const props = defineProps<{
menuReaction?: boolean;
}>();
const react = inject<((name: string) => void) | null>('react', null);
const react = inject(DI.mfmEmojiReactCallback);
const char2path = prefer.s.emojiStyle === 'twemoji' ? char2twemojiFilePath : char2fluentEmojiFilePath;
@ -59,7 +59,6 @@ function onClick(ev: MouseEvent) {
icon: 'ti ti-plus',
action: () => {
react(props.emoji);
sound.playMisskeySfx('reaction');
},
});
}

View file

@ -14,4 +14,5 @@ export const DI = {
viewId: Symbol() as InjectionKey<string>,
currentStickyTop: Symbol() as InjectionKey<Ref<number>>,
currentStickyBottom: Symbol() as InjectionKey<Ref<number>>,
mfmEmojiReactCallback: Symbol() as InjectionKey<(emoji: string) => void>,
};

View file

@ -10,7 +10,16 @@ SPDX-License-Identifier: AGPL-3.0-only
<div v-if="!isMe && prefer.s['chat.showSenderName']" :class="$style.header"><MkUserName :user="message.fromUser"/></div>
<MkFukidashi :class="$style.fukidashi" :tail="isMe ? 'right' : 'left'" :accented="isMe">
<div v-if="!message.isDeleted" :class="$style.content">
<Mfm v-if="message.text" ref="text" class="_selectable" :text="message.text" :i="$i"/>
<Mfm
v-if="message.text"
ref="text"
class="_selectable"
:text="message.text"
:i="$i"
:nyaize="'respect'"
:enableEmojiMenu="true"
:enableEmojiMenuReaction="true"
/>
<MkMediaList v-if="message.file" :mediaList="[message.file]" :class="$style.file"/>
</div>
<div v-else :class="$style.content">
@ -47,7 +56,7 @@ SPDX-License-Identifier: AGPL-3.0-only
</template>
<script lang="ts" setup>
import { computed, defineAsyncComponent } from 'vue';
import { computed, defineAsyncComponent, provide } from 'vue';
import * as mfm from 'mfm-js';
import * as Misskey from 'misskey-js';
import { url } from '@@/js/config.js';
@ -65,6 +74,7 @@ import { reactionPicker } from '@/utility/reaction-picker.js';
import * as sound from '@/utility/sound.js';
import MkReactionIcon from '@/components/MkReactionIcon.vue';
import { prefer } from '@/preferences.js';
import { DI } from '@/di.js';
const $i = ensureSignin();
@ -76,10 +86,17 @@ const props = defineProps<{
const isMe = computed(() => props.message.fromUserId === $i.id);
const urls = computed(() => props.message.text ? extractUrlFromMfm(mfm.parse(props.message.text)) : []);
provide(DI.mfmEmojiReactCallback, (reaction) => {
sound.playMisskeySfx('reaction');
misskeyApi('chat/messages/react', {
messageId: props.message.id,
reaction: reaction,
});
});
function react(ev: MouseEvent) {
reactionPicker.show(ev.currentTarget ?? ev.target, null, async (reaction) => {
sound.playMisskeySfx('reaction');
misskeyApi('chat/messages/react', {
messageId: props.message.id,
reaction: reaction,
@ -93,6 +110,14 @@ function onReactionClick(record: Misskey.entities.ChatMessage['reactions'][0]) {
messageId: props.message.id,
reaction: record.reaction,
});
} else {
if (!props.message.reactions.some(r => r.user.id === $i.id && r.reaction === record.reaction)) {
sound.playMisskeySfx('reaction');
misskeyApi('chat/messages/react', {
messageId: props.message.id,
reaction: record.reaction,
});
}
}
}