From 6e5b6a3bdb32a47dda2ae3cb3ae9995fad12d66b Mon Sep 17 00:00:00 2001 From: syuilo <4439005+syuilo@users.noreply.github.com> Date: Fri, 2 May 2025 13:02:16 +0900 Subject: [PATCH] Revert "test" This reverts commit 3375619396c54dcda5e564eb1da444c2391208c9. --- .../src/components/MkPullToRefresh.vue | 112 +++++++++++------- 1 file changed, 69 insertions(+), 43 deletions(-) diff --git a/packages/frontend/src/components/MkPullToRefresh.vue b/packages/frontend/src/components/MkPullToRefresh.vue index 1836515b83..22ae563d13 100644 --- a/packages/frontend/src/components/MkPullToRefresh.vue +++ b/packages/frontend/src/components/MkPullToRefresh.vue @@ -39,11 +39,14 @@ const isPullEnd = ref(false); const isRefreshing = ref(false); const pullDistance = ref(0); +let supportPointerDesktop = false; let startScreenY: number | null = null; const rootEl = useTemplateRef('rootEl'); let scrollEl: HTMLElement | null = null; +let disabled = false; + const props = withDefaults(defineProps<{ refresher: () => Promise; }>(), { @@ -54,17 +57,17 @@ const emit = defineEmits<{ (ev: 'refresh'): void; }>(); -function moveStart(event: PointerEvent) { - if (scrollEl!.scrollTop !== 0) return; +function getScreenY(event) { + if (supportPointerDesktop) { + return event.screenY; + } + return event.touches[0].screenY; +} - window.addEventListener('pointermove', moving, { passive: false }); // passive: falseにしないとpreventDefaultが使えない - // setPointerCaptureするとクリックが効かなくなる - //rootEl.value.setPointerCapture(event.pointerId); - window.addEventListener('pointerup', moveEnd, { passive: true, once: true }); - - if (!isPullStart.value && !isRefreshing.value) { +function moveStart(event) { + if (!isPullStart.value && !isRefreshing.value && !disabled) { isPullStart.value = true; - startScreenY = event.screenY; + startScreenY = getScreenY(event); pullDistance.value = 0; } } @@ -105,39 +108,7 @@ async function closeContent() { } } -function moving(event: PointerEvent) { - if (!isPullStart.value || isRefreshing.value) return; - - if ((scrollEl?.scrollTop ?? 0) > SCROLL_STOP + pullDistance.value || isHorizontalSwipeSwiping.value) { - pullDistance.value = 0; - isPullEnd.value = false; - moveEnd(event); - return; - } - - if (startScreenY === null) { - startScreenY = event.screenY; - } - const moveScreenY = event.screenY; - - const moveHeight = moveScreenY - startScreenY!; - pullDistance.value = Math.min(Math.max(moveHeight, 0), MAX_PULL_DISTANCE); - - if (pullDistance.value > 0) { - if (event.cancelable) event.preventDefault(); - } - - if (pullDistance.value > SCROLL_STOP) { - event.stopPropagation(); - } - - isPullEnd.value = pullDistance.value >= FIRE_THRESHOLD; -} - -function moveEnd(event: PointerEvent) { - window.removeEventListener('pointermove', moving); - //rootEl.value.releasePointerCapture(event.pointerId); - +function moveEnd() { if (isPullStart.value && !isRefreshing.value) { startScreenY = null; if (isPullEnd.value) { @@ -155,6 +126,35 @@ function moveEnd(event: PointerEvent) { } } +function moving(event: TouchEvent | PointerEvent) { + if (!isPullStart.value || isRefreshing.value || disabled) return; + + if ((scrollEl?.scrollTop ?? 0) > (supportPointerDesktop ? SCROLL_STOP : SCROLL_STOP + pullDistance.value) || isHorizontalSwipeSwiping.value) { + pullDistance.value = 0; + isPullEnd.value = false; + moveEnd(); + return; + } + + if (startScreenY === null) { + startScreenY = getScreenY(event); + } + const moveScreenY = getScreenY(event); + + const moveHeight = moveScreenY - startScreenY!; + pullDistance.value = Math.min(Math.max(moveHeight, 0), MAX_PULL_DISTANCE); + + if (pullDistance.value > 0) { + if (event.cancelable) event.preventDefault(); + } + + if (pullDistance.value > SCROLL_STOP) { + event.stopPropagation(); + } + + isPullEnd.value = pullDistance.value >= FIRE_THRESHOLD; +} + /** * emit(refresh)が完了したことを知らせる関数 * @@ -167,17 +167,35 @@ function refreshFinished() { }); } +function setDisabled(value) { + disabled = value; +} + function onScrollContainerScroll() { const scrollPos = scrollEl!.scrollTop; // 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 { scrollEl!.style.touchAction = 'auto'; + unregisterEventListenersForReadyToPull(); } } +function registerEventListenersForReadyToPull() { + if (rootEl.value == null) return; + rootEl.value.addEventListener('touchstart', moveStart, { passive: true }); + rootEl.value.addEventListener('touchmove', moving, { passive: false }); // passive: falseにしないとpreventDefaultが使えない +} + +function unregisterEventListenersForReadyToPull() { + if (rootEl.value == null) return; + rootEl.value.removeEventListener('touchstart', moveStart); + rootEl.value.removeEventListener('touchmove', moving); +} + onMounted(() => { if (rootEl.value == null) return; @@ -186,11 +204,19 @@ onMounted(() => { scrollEl.addEventListener('scroll', onScrollContainerScroll, { passive: true }); - rootEl.value.addEventListener('pointerdown', moveStart, { passive: true }); + rootEl.value.addEventListener('touchend', moveEnd, { passive: true }); + + registerEventListenersForReadyToPull(); }); onUnmounted(() => { if (scrollEl) scrollEl.removeEventListener('scroll', onScrollContainerScroll); + + unregisterEventListenersForReadyToPull(); +}); + +defineExpose({ + setDisabled, });