From 4b7b51d5ccdcdad5134edc0232c98e9e8ce2caf5 Mon Sep 17 00:00:00 2001 From: syuilo Date: Fri, 12 Nov 2021 23:53:10 +0900 Subject: [PATCH] refactor(client): use composition api for tooltip logic --- .../client/src/components/note-detailed.vue | 26 ++-- packages/client/src/components/note.vue | 26 ++-- .../client/src/components/notification.vue | 38 +---- .../components/reactions-viewer.reaction.vue | 146 ++++++++---------- .../client/src/components/renote-button.vue | 126 ++++++--------- packages/client/src/scripts/use-tooltip.ts | 44 ++++++ 6 files changed, 187 insertions(+), 219 deletions(-) create mode 100644 packages/client/src/scripts/use-tooltip.ts diff --git a/packages/client/src/components/note-detailed.vue b/packages/client/src/components/note-detailed.vue index 09c05d776..3b5b12a60 100644 --- a/packages/client/src/components/note-detailed.vue +++ b/packages/client/src/components/note-detailed.vue @@ -94,7 +94,7 @@

{{ appearNote.repliesCount }}

- + @@ -132,16 +132,16 @@ import XMediaList from './media-list.vue'; import XCwButton from './cw-button.vue'; import XPoll from './poll.vue'; import XRenoteButton from './renote-button.vue'; -import { pleaseLogin } from '@client/scripts/please-login'; -import { focusPrev, focusNext } from '@client/scripts/focus'; -import { url } from '@client/config'; -import copyToClipboard from '@client/scripts/copy-to-clipboard'; -import { checkWordMute } from '@client/scripts/check-word-mute'; -import { userPage } from '@client/filters/user'; -import * as os from '@client/os'; -import { noteActions, noteViewInterruptors } from '@client/store'; -import { reactionPicker } from '@client/scripts/reaction-picker'; -import { extractUrlFromMfm } from '@/misc/extract-url-from-mfm'; +import { pleaseLogin } from '@/scripts/please-login'; +import { focusPrev, focusNext } from '@/scripts/focus'; +import { url } from '@/config'; +import copyToClipboard from '@/scripts/copy-to-clipboard'; +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'; +import { extractUrlFromMfm } from '@/scripts/extract-url-from-mfm'; // TODO: note.vueとほぼ同じなので共通化したい export default defineComponent({ @@ -154,8 +154,8 @@ export default defineComponent({ XCwButton, XPoll, XRenoteButton, - MkUrlPreview: defineAsyncComponent(() => import('@client/components/url-preview.vue')), - MkInstanceTicker: defineAsyncComponent(() => import('@client/components/instance-ticker.vue')), + MkUrlPreview: defineAsyncComponent(() => import('@/components/url-preview.vue')), + MkInstanceTicker: defineAsyncComponent(() => import('@/components/instance-ticker.vue')), }, inject: { diff --git a/packages/client/src/components/note.vue b/packages/client/src/components/note.vue index 19486c4df..2ab769db4 100644 --- a/packages/client/src/components/note.vue +++ b/packages/client/src/components/note.vue @@ -78,7 +78,7 @@

{{ appearNote.repliesCount }}

- + @@ -115,16 +115,16 @@ import XMediaList from './media-list.vue'; import XCwButton from './cw-button.vue'; import XPoll from './poll.vue'; import XRenoteButton from './renote-button.vue'; -import { pleaseLogin } from '@client/scripts/please-login'; -import { focusPrev, focusNext } from '@client/scripts/focus'; -import { url } from '@client/config'; -import copyToClipboard from '@client/scripts/copy-to-clipboard'; -import { checkWordMute } from '@client/scripts/check-word-mute'; -import { userPage } from '@client/filters/user'; -import * as os from '@client/os'; -import { noteActions, noteViewInterruptors } from '@client/store'; -import { reactionPicker } from '@client/scripts/reaction-picker'; -import { extractUrlFromMfm } from '@/misc/extract-url-from-mfm'; +import { pleaseLogin } from '@/scripts/please-login'; +import { focusPrev, focusNext } from '@/scripts/focus'; +import { url } from '@/config'; +import copyToClipboard from '@/scripts/copy-to-clipboard'; +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'; +import { extractUrlFromMfm } from '@/scripts/extract-url-from-mfm'; export default defineComponent({ components: { @@ -136,8 +136,8 @@ export default defineComponent({ XCwButton, XPoll, XRenoteButton, - MkUrlPreview: defineAsyncComponent(() => import('@client/components/url-preview.vue')), - MkInstanceTicker: defineAsyncComponent(() => import('@client/components/instance-ticker.vue')), + MkUrlPreview: defineAsyncComponent(() => import('@/components/url-preview.vue')), + MkInstanceTicker: defineAsyncComponent(() => import('@/components/instance-ticker.vue')), }, inject: { diff --git a/packages/client/src/components/notification.vue b/packages/client/src/components/notification.vue index 1f61bee6f..40670daa9 100644 --- a/packages/client/src/components/notification.vue +++ b/packages/client/src/components/notification.vue @@ -78,6 +78,7 @@ import notePage from '@/filters/note'; import { userPage } from '@/filters/user'; import { i18n } from '@/i18n'; import * as os from '@/os'; +import { useTooltip } from '@/scripts/use-tooltip'; export default defineComponent({ components: { @@ -153,47 +154,14 @@ export default defineComponent({ os.api('users/groups/invitations/reject', { invitationId: props.notification.invitation.id }); }; - let isReactionHovering = false; - let reactionTooltipTimeoutId; - - const onReactionMouseover = () => { - if (isReactionHovering) return; - isReactionHovering = true; - reactionTooltipTimeoutId = setTimeout(openReactionTooltip, 300); - }; - - const onReactionMouseleave = () => { - if (!isReactionHovering) return; - isReactionHovering = false; - clearTimeout(reactionTooltipTimeoutId); - closeReactionTooltip(); - }; - - let changeReactionTooltipShowingState: (() => void) | null; - - const openReactionTooltip = () => { - closeReactionTooltip(); - if (!isReactionHovering) return; - - const showing = ref(true); + const { onMouseover: onReactionMouseover, onMouseleave: onReactionMouseleave } = useTooltip((showing) => { os.popup(XReactionTooltip, { showing, reaction: props.notification.reaction ? props.notification.reaction.replace(/^:(\w+):$/, ':$1@.:') : props.notification.reaction, emojis: props.notification.note.emojis, source: reactionRef.value.$el, }, {}, 'closed'); - - changeReactionTooltipShowingState = () => { - showing.value = false; - }; - }; - - const closeReactionTooltip = () => { - if (changeReactionTooltipShowingState != null) { - changeReactionTooltipShowingState(); - changeReactionTooltipShowingState = null; - } - }; + }); return { getNoteSummary: (note: misskey.entities.Note) => getNoteSummary(note), diff --git a/packages/client/src/components/reactions-viewer.reaction.vue b/packages/client/src/components/reactions-viewer.reaction.vue index 47a3bb972..a7769868b 100644 --- a/packages/client/src/components/reactions-viewer.reaction.vue +++ b/packages/client/src/components/reactions-viewer.reaction.vue @@ -2,13 +2,13 @@