From f871cf10538cc35d67114d780ec13afa4d30903c Mon Sep 17 00:00:00 2001 From: syuilo Date: Fri, 5 Mar 2021 13:49:46 +0900 Subject: [PATCH] Improve reaction picker performance --- src/client/components/note-detailed.vue | 3 +- src/client/components/note.vue | 3 +- src/client/init.ts | 2 ++ src/client/os.ts | 32 ------------------- src/client/scripts/reaction-picker.ts | 41 +++++++++++++++++++++++++ src/client/ui/chat/note.vue | 3 +- 6 files changed, 49 insertions(+), 35 deletions(-) create mode 100644 src/client/scripts/reaction-picker.ts diff --git a/src/client/components/note-detailed.vue b/src/client/components/note-detailed.vue index b5bc054e5e..1ef3f43389 100644 --- a/src/client/components/note-detailed.vue +++ b/src/client/components/note-detailed.vue @@ -140,6 +140,7 @@ import { checkWordMute } from '@/scripts/check-word-mute'; import { userPage } from '@/filters/user'; import * as os from '@/os'; import { noteActions, noteViewInterruptors } from '@/store'; +import { reactionPicker } from '@/scripts/reaction-picker'; function markRawAll(...xs) { for (const x of xs) { @@ -523,7 +524,7 @@ export default defineComponent({ react(viaKeyboard = false) { pleaseLogin(); this.blur(); - os.pickReaction(this.$refs.reactButton, reaction => { + reactionPicker.show(this.$refs.reactButton, reaction => { os.api('notes/reactions/create', { noteId: this.appearNote.id, reaction: reaction diff --git a/src/client/components/note.vue b/src/client/components/note.vue index bc2f87fe85..65e09b7802 100644 --- a/src/client/components/note.vue +++ b/src/client/components/note.vue @@ -122,6 +122,7 @@ import { checkWordMute } from '@/scripts/check-word-mute'; import { userPage } from '@/filters/user'; import * as os from '@/os'; import { noteActions, noteViewInterruptors } from '@/store'; +import { reactionPicker } from '@/scripts/reaction-picker'; function markRawAll(...xs) { for (const x of xs) { @@ -498,7 +499,7 @@ export default defineComponent({ react(viaKeyboard = false) { pleaseLogin(); this.blur(); - os.pickReaction(this.$refs.reactButton, reaction => { + reactionPicker.show(this.$refs.reactButton, reaction => { os.api('notes/reactions/create', { noteId: this.appearNote.id, reaction: reaction diff --git a/src/client/init.ts b/src/client/init.ts index b3c53db7bb..596312ff71 100644 --- a/src/client/init.ts +++ b/src/client/init.ts @@ -62,6 +62,7 @@ import { isMobile } from '@/scripts/is-mobile'; import { getThemes } from '@/theme-store'; import { initializeSw } from '@/scripts/initialize-sw'; import { reloadChannel } from '@/scripts/unison-reload'; +import { reactionPicker } from '@/scripts/reaction-picker'; console.info(`Misskey v${version}`); @@ -222,6 +223,7 @@ await router.isReady(); //document.body.innerHTML = '
'; app.mount('body'); +reactionPicker.init(); watch(defaultStore.reactiveState.darkMode, (darkMode) => { import('@/scripts/theme').then(({ builtinThemes }) => { diff --git a/src/client/os.ts b/src/client/os.ts index 2b72391bf5..9be45e6c6d 100644 --- a/src/client/os.ts +++ b/src/client/os.ts @@ -357,38 +357,6 @@ export async function openEmojiPicker(src?: HTMLElement, opts, initialTextarea: }); } -let reactionPicker = null; -export async function pickReaction(src: HTMLElement, chosen, closed) { - if (reactionPicker) { - reactionPicker.src.value = src; - reactionPicker.manualShowing.value = true; - reactionPicker.chosen = chosen; - reactionPicker.closed = closed; - } else { - reactionPicker = { - src: ref(src), - manualShowing: ref(true), - chosen, closed - }; - popup(import('@/components/emoji-picker-dialog.vue'), { - src: reactionPicker.src, - asReactionPicker: true, - manualShowing: reactionPicker.manualShowing - }, { - done: reaction => { - reactionPicker.chosen(reaction); - }, - close: () => { - reactionPicker.manualShowing.value = false; - }, - closed: () => { - reactionPicker.src.value = null; - reactionPicker.closed(); - } - }); - } -} - export function modalMenu(items: any[], src?: HTMLElement, options?: { align?: string; viaKeyboard?: boolean }) { return new Promise((resolve, reject) => { let dispose; diff --git a/src/client/scripts/reaction-picker.ts b/src/client/scripts/reaction-picker.ts new file mode 100644 index 0000000000..e923326ece --- /dev/null +++ b/src/client/scripts/reaction-picker.ts @@ -0,0 +1,41 @@ +import { Ref, ref } from 'vue'; +import { popup } from '@/os'; + +class ReactionPicker { + private src: Ref = ref(null); + private manualShowing = ref(false); + private onChosen?: Function; + private onClosed?: Function; + + constructor() { + // nop + } + + public async init() { + await popup(import('@/components/emoji-picker-dialog.vue'), { + src: this.src, + asReactionPicker: true, + manualShowing: this.manualShowing + }, { + done: reaction => { + this.onChosen!(reaction); + }, + close: () => { + this.manualShowing.value = false; + }, + closed: () => { + this.src.value = null; + this.onClosed!(); + } + }); + } + + public show(src: HTMLElement, onChosen: Function, onClosed: Function) { + this.src.value = src; + this.manualShowing.value = true; + this.onChosen = onChosen; + this.onClosed = onClosed; + } +} + +export const reactionPicker = new ReactionPicker(); diff --git a/src/client/ui/chat/note.vue b/src/client/ui/chat/note.vue index bd7bbc5a4f..5a4a13d889 100644 --- a/src/client/ui/chat/note.vue +++ b/src/client/ui/chat/note.vue @@ -121,6 +121,7 @@ import { checkWordMute } from '@/scripts/check-word-mute'; import { userPage } from '@/filters/user'; import * as os from '@/os'; import { noteActions, noteViewInterruptors } from '@/store'; +import { reactionPicker } from '@/scripts/reaction-picker'; function markRawAll(...xs) { for (const x of xs) { @@ -504,7 +505,7 @@ export default defineComponent({ pleaseLogin(); this.operating = true; this.blur(); - os.pickReaction(this.$refs.reactButton, reaction => { + reactionPicker.show(this.$refs.reactButton, reaction => { os.api('notes/reactions/create', { noteId: this.appearNote.id, reaction: reaction