Improve reaction picker performance

This commit is contained in:
syuilo 2021-03-05 13:49:46 +09:00
parent a4ddd18f12
commit f871cf1053
6 changed files with 49 additions and 35 deletions

View file

@ -140,6 +140,7 @@ import { checkWordMute } from '@/scripts/check-word-mute';
import { userPage } from '@/filters/user'; import { userPage } from '@/filters/user';
import * as os from '@/os'; import * as os from '@/os';
import { noteActions, noteViewInterruptors } from '@/store'; import { noteActions, noteViewInterruptors } from '@/store';
import { reactionPicker } from '@/scripts/reaction-picker';
function markRawAll(...xs) { function markRawAll(...xs) {
for (const x of xs) { for (const x of xs) {
@ -523,7 +524,7 @@ export default defineComponent({
react(viaKeyboard = false) { react(viaKeyboard = false) {
pleaseLogin(); pleaseLogin();
this.blur(); this.blur();
os.pickReaction(this.$refs.reactButton, reaction => { reactionPicker.show(this.$refs.reactButton, reaction => {
os.api('notes/reactions/create', { os.api('notes/reactions/create', {
noteId: this.appearNote.id, noteId: this.appearNote.id,
reaction: reaction reaction: reaction

View file

@ -122,6 +122,7 @@ import { checkWordMute } from '@/scripts/check-word-mute';
import { userPage } from '@/filters/user'; import { userPage } from '@/filters/user';
import * as os from '@/os'; import * as os from '@/os';
import { noteActions, noteViewInterruptors } from '@/store'; import { noteActions, noteViewInterruptors } from '@/store';
import { reactionPicker } from '@/scripts/reaction-picker';
function markRawAll(...xs) { function markRawAll(...xs) {
for (const x of xs) { for (const x of xs) {
@ -498,7 +499,7 @@ export default defineComponent({
react(viaKeyboard = false) { react(viaKeyboard = false) {
pleaseLogin(); pleaseLogin();
this.blur(); this.blur();
os.pickReaction(this.$refs.reactButton, reaction => { reactionPicker.show(this.$refs.reactButton, reaction => {
os.api('notes/reactions/create', { os.api('notes/reactions/create', {
noteId: this.appearNote.id, noteId: this.appearNote.id,
reaction: reaction reaction: reaction

View file

@ -62,6 +62,7 @@ import { isMobile } from '@/scripts/is-mobile';
import { getThemes } from '@/theme-store'; import { getThemes } from '@/theme-store';
import { initializeSw } from '@/scripts/initialize-sw'; import { initializeSw } from '@/scripts/initialize-sw';
import { reloadChannel } from '@/scripts/unison-reload'; import { reloadChannel } from '@/scripts/unison-reload';
import { reactionPicker } from '@/scripts/reaction-picker';
console.info(`Misskey v${version}`); console.info(`Misskey v${version}`);
@ -222,6 +223,7 @@ await router.isReady();
//document.body.innerHTML = '<div id="app"></div>'; //document.body.innerHTML = '<div id="app"></div>';
app.mount('body'); app.mount('body');
reactionPicker.init();
watch(defaultStore.reactiveState.darkMode, (darkMode) => { watch(defaultStore.reactiveState.darkMode, (darkMode) => {
import('@/scripts/theme').then(({ builtinThemes }) => { import('@/scripts/theme').then(({ builtinThemes }) => {

View file

@ -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 }) { export function modalMenu(items: any[], src?: HTMLElement, options?: { align?: string; viaKeyboard?: boolean }) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
let dispose; let dispose;

View file

@ -0,0 +1,41 @@
import { Ref, ref } from 'vue';
import { popup } from '@/os';
class ReactionPicker {
private src: Ref<HTMLElement | null> = 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();

View file

@ -121,6 +121,7 @@ import { checkWordMute } from '@/scripts/check-word-mute';
import { userPage } from '@/filters/user'; import { userPage } from '@/filters/user';
import * as os from '@/os'; import * as os from '@/os';
import { noteActions, noteViewInterruptors } from '@/store'; import { noteActions, noteViewInterruptors } from '@/store';
import { reactionPicker } from '@/scripts/reaction-picker';
function markRawAll(...xs) { function markRawAll(...xs) {
for (const x of xs) { for (const x of xs) {
@ -504,7 +505,7 @@ export default defineComponent({
pleaseLogin(); pleaseLogin();
this.operating = true; this.operating = true;
this.blur(); this.blur();
os.pickReaction(this.$refs.reactButton, reaction => { reactionPicker.show(this.$refs.reactButton, reaction => {
os.api('notes/reactions/create', { os.api('notes/reactions/create', {
noteId: this.appearNote.id, noteId: this.appearNote.id,
reaction: reaction reaction: reaction