diff options
| author | syuilo <Syuilotan@yahoo.co.jp> | 2023-11-04 08:56:48 +0900 |
|---|---|---|
| committer | syuilo <Syuilotan@yahoo.co.jp> | 2023-11-04 08:56:48 +0900 |
| commit | a656447aa58440e9a41fa39e1c5d6ff3d859b64e (patch) | |
| tree | f2cd2ff1b3b2db25e9584c7078522d26b132f687 /packages/frontend/src/components/MkPullToRefresh.vue | |
| parent | Update CHANGELOG.md (diff) | |
| download | misskey-a656447aa58440e9a41fa39e1c5d6ff3d859b64e.tar.gz misskey-a656447aa58440e9a41fa39e1c5d6ff3d859b64e.tar.bz2 misskey-a656447aa58440e9a41fa39e1c5d6ff3d859b64e.zip | |
enhance(frontend): improve pull to refresh
Diffstat (limited to 'packages/frontend/src/components/MkPullToRefresh.vue')
| -rw-r--r-- | packages/frontend/src/components/MkPullToRefresh.vue | 72 |
1 files changed, 43 insertions, 29 deletions
diff --git a/packages/frontend/src/components/MkPullToRefresh.vue b/packages/frontend/src/components/MkPullToRefresh.vue index f3f5660143..64c4d6e91d 100644 --- a/packages/frontend/src/components/MkPullToRefresh.vue +++ b/packages/frontend/src/components/MkPullToRefresh.vue @@ -23,9 +23,10 @@ SPDX-License-Identifier: AGPL-3.0-only </template> <script lang="ts" setup> -import { onMounted, onUnmounted } from 'vue'; +import { onMounted, onUnmounted, watch } from 'vue'; import { deviceKind } from '@/scripts/device-kind.js'; import { i18n } from '@/i18n.js'; +import { getScrollContainer } from '@/scripts/scroll.js'; const SCROLL_STOP = 10; const MAX_PULL_DISTANCE = Infinity; @@ -57,18 +58,6 @@ const emit = defineEmits<{ (ev: 'refresh'): void; }>(); -function getScrollableParentElement(node) { - if (node == null) { - return null; - } - - if (node.scrollHeight > node.clientHeight) { - return node; - } else { - return getScrollableParentElement(node.parentNode); - } -} - function getScreenY(event) { if (supportPointerDesktop) { return event.screenY; @@ -138,12 +127,9 @@ function moveEnd() { } } -function moving(event) { +function moving(event: TouchEvent | PointerEvent) { if (!isPullStart || isRefreshing || disabled) return; - if (!scrollEl) { - scrollEl = getScrollableParentElement(rootEl); - } if ((scrollEl?.scrollTop ?? 0) > (supportPointerDesktop ? SCROLL_STOP : SCROLL_STOP + pullDistance)) { pullDistance = 0; isPullEnd = false; @@ -159,6 +145,10 @@ function moving(event) { const moveHeight = moveScreenY - startScreenY!; pullDistance = Math.min(Math.max(moveHeight, 0), MAX_PULL_DISTANCE); + if (pullDistance > 0) { + if (event.cancelable) event.preventDefault(); + } + isPullEnd = pullDistance >= FIRE_THRESHOLD; } @@ -178,24 +168,48 @@ function setDisabled(value) { disabled = value; } -onMounted(() => { - // マウス操作でpull to refreshするのは不便そう - //supportPointerDesktop = !!window.PointerEvent && deviceKind === 'desktop'; +function onScrollContainerScroll() { + const scrollPos = scrollEl!.scrollTop; - if (supportPointerDesktop) { - rootEl.addEventListener('pointerdown', moveStart); - // ポインターの場合、ポップアップ系の動作をするとdownだけ発火されてupが発火されないため - window.addEventListener('pointerup', moveEnd); - rootEl.addEventListener('pointermove', moving, { passive: true }); + // When at the top of the page, disable vertical overscroll so passive touch listeners can take over. + if (scrollPos === 0) { + scrollEl!.style.touchAction = 'pan-x pan-down pinch-zoom'; + registerEventListenersForReadyToPull(); } else { - rootEl.addEventListener('touchstart', moveStart); - rootEl.addEventListener('touchend', moveEnd); - rootEl.addEventListener('touchmove', moving, { passive: true }); + scrollEl!.style.touchAction = 'auto'; + unregisterEventListenersForReadyToPull(); } +} + +function registerEventListenersForReadyToPull() { + if (rootEl == null) return; + rootEl.addEventListener('touchstart', moveStart, { passive: true }); + rootEl.addEventListener('touchmove', moving, { passive: false }); // passive: falseにしないとpreventDefaultが使えない +} + +function unregisterEventListenersForReadyToPull() { + if (rootEl == null) return; + rootEl.removeEventListener('touchstart', moveStart); + rootEl.removeEventListener('touchmove', moving); +} + +onMounted(() => { + if (rootEl == null) return; + + scrollEl = getScrollContainer(rootEl); + if (scrollEl == null) return; + + scrollEl.addEventListener('scroll', onScrollContainerScroll, { passive: true }); + + rootEl.addEventListener('touchend', moveEnd, { passive: true }); + + registerEventListenersForReadyToPull(); }); onUnmounted(() => { - if (supportPointerDesktop) window.removeEventListener('pointerup', moveEnd); + if (scrollEl) scrollEl.removeEventListener('scroll', onScrollContainerScroll); + + unregisterEventListenersForReadyToPull(); }); defineExpose({ |