diff --git a/packages/frontend/src/components/MkUserPopup.vue b/packages/frontend/src/components/MkUserPopup.vue index d2fca76495..cb959f8347 100644 --- a/packages/frontend/src/components/MkUserPopup.vue +++ b/packages/frontend/src/components/MkUserPopup.vue @@ -11,7 +11,7 @@ SPDX-License-Identifier: AGPL-3.0-only :leaveToClass="prefer.s.animation ? $style.transition_popup_leaveTo : ''" appear @afterLeave="emit('closed')" > -
+
@@ -92,7 +92,7 @@ const props = defineProps<{ const emit = defineEmits<{ (ev: 'closed'): void; - (ev: 'mouseover'): void; + (ev: 'pointerover', event: PointerEvent): void; (ev: 'mouseleave'): void; }>(); diff --git a/packages/frontend/src/directives/user-preview.ts b/packages/frontend/src/directives/user-preview.ts index 94deea82c7..96f58fb68c 100644 --- a/packages/frontend/src/directives/user-preview.ts +++ b/packages/frontend/src/directives/user-preview.ts @@ -21,7 +21,7 @@ export class UserPreview { this.show = this.show.bind(this); this.close = this.close.bind(this); - this.onMouseover = this.onMouseover.bind(this); + this.onPointerover = this.onPointerover.bind(this); this.onMouseleave = this.onMouseleave.bind(this); this.onClick = this.onClick.bind(this); this.attach = this.attach.bind(this); @@ -41,7 +41,8 @@ export class UserPreview { q: this.user, source: this.el, }, { - mouseover: () => { + pointerover: (event: PointerEvent) => { + if (event.pointerType === 'touch') return; window.clearTimeout(this.hideTimer); }, mouseleave: () => { @@ -74,7 +75,8 @@ export class UserPreview { } } - private onMouseover() { + private onPointerover(event: PointerEvent) { + if (event.pointerType === 'touch') return; window.clearTimeout(this.showTimer); window.clearTimeout(this.hideTimer); this.showTimer = window.setTimeout(this.show, 500); @@ -92,13 +94,13 @@ export class UserPreview { } public attach() { - this.el.addEventListener('mouseover', this.onMouseover); + this.el.addEventListener('pointerover', this.onPointerover); this.el.addEventListener('mouseleave', this.onMouseleave); this.el.addEventListener('click', this.onClick); } public detach() { - this.el.removeEventListener('mouseover', this.onMouseover); + this.el.removeEventListener('pointerover', this.onPointerover); this.el.removeEventListener('mouseleave', this.onMouseleave); this.el.removeEventListener('click', this.onClick); } diff --git a/packages/frontend/src/use/use-tooltip.ts b/packages/frontend/src/use/use-tooltip.ts index af76a3a1e8..5cf94d0005 100644 --- a/packages/frontend/src/use/use-tooltip.ts +++ b/packages/frontend/src/use/use-tooltip.ts @@ -13,11 +13,6 @@ export function useTooltip( ): void { let isHovering = false; - // iOS(Androidも?)では、要素をタップした直後に(おせっかいで)mouseoverイベントを発火させたりするため、それを無視するためのフラグ - // 無視しないと、画面に触れてないのにツールチップが出たりし、ユーザビリティが損なわれる - // TODO: 一度でもタップすると二度とマウスでツールチップ出せなくなるのをどうにかする 定期的にfalseに戻すとか...? - let shouldIgnoreMouseover = false; - let timeoutId: number; let changeShowingState: (() => void) | null; @@ -55,9 +50,9 @@ export function useTooltip( } }; - const onMouseover = () => { + const onPointerover = (event: PointerEvent) => { + if (event.pointerType === 'touch') return; if (isHovering) return; - if (shouldIgnoreMouseover) return; isHovering = true; timeoutId = window.setTimeout(open, delay); }; @@ -71,7 +66,6 @@ export function useTooltip( }; const onTouchstart = () => { - shouldIgnoreMouseover = true; if (isHovering) return; isHovering = true; timeoutId = window.setTimeout(open, delay); @@ -89,7 +83,7 @@ export function useTooltip( if (elRef.value) { stop(); const el = elRef.value instanceof Element ? elRef.value : elRef.value.$el; - el.addEventListener('mouseover', onMouseover, { passive: true }); + el.addEventListener('pointerover', onPointerover, { passive: true }); el.addEventListener('mouseleave', onMouseleave, { passive: true }); el.addEventListener('touchstart', onTouchstart, { passive: true }); el.addEventListener('touchend', onTouchend, { passive: true });