fix(client): タッチ機能付きディスプレイを使っていてマウス操作をしている場合に一部機能が動作しない問題を修正

This commit is contained in:
syuilo 2021-12-05 13:10:19 +09:00
parent b1bd7307bb
commit fbe4869d1e
9 changed files with 40 additions and 26 deletions

View file

@ -7,6 +7,13 @@
--> -->
## 12.x.x (unreleased)
### Improvements
### Bugfixes
- クライアント: タッチ機能付きディスプレイを使っていてマウス操作をしている場合に一部機能が動作しない問題を修正
## 12.98.0 (2021/12/03) ## 12.98.0 (2021/12/03)
### Improvements ### Improvements

View file

@ -79,7 +79,7 @@ import { emojilist } from '@/scripts/emojilist';
import { getStaticImageUrl } from '@/scripts/get-static-image-url'; import { getStaticImageUrl } from '@/scripts/get-static-image-url';
import Particle from '@/components/particle.vue'; import Particle from '@/components/particle.vue';
import * as os from '@/os'; import * as os from '@/os';
import { isDeviceTouch } from '@/scripts/is-device-touch'; import { isTouchUsing } from '@/scripts/touch';
import { isMobile } from '@/scripts/is-mobile'; import { isMobile } from '@/scripts/is-mobile';
import { emojiCategories } from '@/instance'; import { emojiCategories } from '@/instance';
import XSection from './emoji-picker.section.vue'; import XSection from './emoji-picker.section.vue';
@ -108,7 +108,7 @@ export default defineComponent({
pinned: this.$store.reactiveState.reactions, pinned: this.$store.reactiveState.reactions,
width: this.asReactionPicker ? this.$store.state.reactionPickerWidth : 3, width: this.asReactionPicker ? this.$store.state.reactionPickerWidth : 3,
height: this.asReactionPicker ? this.$store.state.reactionPickerHeight : 2, height: this.asReactionPicker ? this.$store.state.reactionPickerHeight : 2,
big: this.asReactionPicker ? isDeviceTouch : false, big: this.asReactionPicker ? isTouchUsing : false,
customEmojiCategories: emojiCategories, customEmojiCategories: emojiCategories,
customEmojis: this.$instance.emojis, customEmojis: this.$instance.emojis,
q: null, q: null,
@ -268,7 +268,7 @@ export default defineComponent({
methods: { methods: {
focus() { focus() {
if (!isMobile && !isDeviceTouch) { if (!isMobile && !isTouchUsing) {
this.$refs.search.focus({ this.$refs.search.focus({
preventScroll: true preventScroll: true
}); });

View file

@ -23,7 +23,7 @@
import { defineComponent } from 'vue'; import { defineComponent } from 'vue';
import { toUnicode as decodePunycode } from 'punycode/'; import { toUnicode as decodePunycode } from 'punycode/';
import { url as local } from '@/config'; import { url as local } from '@/config';
import { isDeviceTouch } from '@/scripts/is-device-touch'; import { isTouchUsing } from '@/scripts/touch';
import * as os from '@/os'; import * as os from '@/os';
export default defineComponent({ export default defineComponent({
@ -91,13 +91,13 @@ export default defineComponent({
} }
}, },
onMouseover() { onMouseover() {
if (isDeviceTouch) return; if (isTouchUsing) return;
clearTimeout(this.showTimer); clearTimeout(this.showTimer);
clearTimeout(this.hideTimer); clearTimeout(this.hideTimer);
this.showTimer = setTimeout(this.showPreview, 500); this.showTimer = setTimeout(this.showPreview, 500);
}, },
onMouseleave() { onMouseleave() {
if (isDeviceTouch) return; if (isTouchUsing) return;
clearTimeout(this.showTimer); clearTimeout(this.showTimer);
clearTimeout(this.hideTimer); clearTimeout(this.hideTimer);
this.hideTimer = setTimeout(this.closePreview, 500); this.hideTimer = setTimeout(this.closePreview, 500);

View file

@ -12,7 +12,7 @@
<script lang="ts"> <script lang="ts">
import { defineComponent } from 'vue'; import { defineComponent } from 'vue';
import { url as local } from '@/config'; import { url as local } from '@/config';
import { isDeviceTouch } from '@/scripts/is-device-touch'; import { isTouchUsing } from '@/scripts/touch';
import * as os from '@/os'; import * as os from '@/os';
export default defineComponent({ export default defineComponent({
@ -65,13 +65,13 @@ export default defineComponent({
} }
}, },
onMouseover() { onMouseover() {
if (isDeviceTouch) return; if (isTouchUsing) return;
clearTimeout(this.showTimer); clearTimeout(this.showTimer);
clearTimeout(this.hideTimer); clearTimeout(this.hideTimer);
this.showTimer = setTimeout(this.showPreview, 500); this.showTimer = setTimeout(this.showPreview, 500);
}, },
onMouseleave() { onMouseleave() {
if (isDeviceTouch) return; if (isTouchUsing) return;
clearTimeout(this.showTimer); clearTimeout(this.showTimer);
clearTimeout(this.hideTimer); clearTimeout(this.hideTimer);
this.hideTimer = setTimeout(this.closePreview, 500); this.hideTimer = setTimeout(this.closePreview, 500);

View file

@ -2,11 +2,11 @@
// ただディレクティブ内でonUnmountedなどのcomposition api使えるのか不明 // ただディレクティブ内でonUnmountedなどのcomposition api使えるのか不明
import { Directive, ref } from 'vue'; import { Directive, ref } from 'vue';
import { isDeviceTouch } from '@/scripts/is-device-touch'; import { isTouchUsing } from '@/scripts/touch';
import { popup, alert } from '@/os'; import { popup, alert } from '@/os';
const start = isDeviceTouch ? 'touchstart' : 'mouseover'; const start = isTouchUsing ? 'touchstart' : 'mouseover';
const end = isDeviceTouch ? 'touchend' : 'mouseleave'; const end = isTouchUsing ? 'touchend' : 'mouseleave';
const delay = 100; const delay = 100;
export default { export default {

View file

@ -12,16 +12,6 @@ import { resolve } from '@/router';
import { $i } from '@/account'; import { $i } from '@/account';
import { defaultStore } from '@/store'; import { defaultStore } from '@/store';
export let isScreenTouching = false;
window.addEventListener('touchstart', () => {
isScreenTouching = true;
}, { passive: true });
window.addEventListener('touchend', () => {
isScreenTouching = false;
}, { passive: true });
export const stream = markRaw(new Misskey.Stream(url, $i)); export const stream = markRaw(new Misskey.Stream(url, $i));
export const pendingApiRequestsCount = ref(0); export const pendingApiRequestsCount = ref(0);

View file

@ -1 +0,0 @@
export const isDeviceTouch = 'maxTouchPoints' in navigator && navigator.maxTouchPoints > 0;

View file

@ -0,0 +1,19 @@
const isTouchSupported = 'maxTouchPoints' in navigator && navigator.maxTouchPoints > 0;
export let isTouchUsing = false;
export let isScreenTouching = false;
if (isTouchSupported) {
window.addEventListener('touchstart', () => {
// maxTouchPointsなどでの判定だけだと、「タッチ機能付きディスプレイを使っているがマウスでしか操作しない」場合にも
// タッチで使っていると判定されてしまうため、実際に一度でもタッチされたらtrueにする
isTouchUsing = true;
isScreenTouching = true;
}, { passive: true });
window.addEventListener('touchend', () => {
isScreenTouching = false;
}, { passive: true });
}

View file

@ -1,6 +1,5 @@
import { isScreenTouching } from '@/os';
import { Ref, ref } from 'vue'; import { Ref, ref } from 'vue';
import { isDeviceTouch } from './is-device-touch'; import { isScreenTouching, isTouchUsing } from './touch';
export function useTooltip(onShow: (showing: Ref<boolean>) => void) { export function useTooltip(onShow: (showing: Ref<boolean>) => void) {
let isHovering = false; let isHovering = false;
@ -14,7 +13,7 @@ export function useTooltip(onShow: (showing: Ref<boolean>) => void) {
// iOS(Androidも)では、要素をタップした直後に(おせっかいで)mouseoverイベントを発火させたりするため、その対策 // iOS(Androidも)では、要素をタップした直後に(おせっかいで)mouseoverイベントを発火させたりするため、その対策
// これが無いと、画面に触れてないのにツールチップが出たりしてしまう // これが無いと、画面に触れてないのにツールチップが出たりしてしまう
if (isDeviceTouch && !isScreenTouching) return; if (isTouchUsing && !isScreenTouching) return;
const showing = ref(true); const showing = ref(true);
onShow(showing); onShow(showing);