export function usePullToRefresh(onRefresh: () => Promise | void) { const isPulling = ref(false) const pullDistance = ref(0) const isRefreshing = ref(false) const threshold = 80 let startY = 0 let currentY = 0 const onTouchStart = (e: TouchEvent) => { if (window.scrollY === 0) { startY = e.touches[0].clientY isPulling.value = true } } const onTouchMove = (e: TouchEvent) => { if (!isPulling.value || isRefreshing.value) return currentY = e.touches[0].clientY const diff = currentY - startY if (diff > 0 && window.scrollY === 0) { pullDistance.value = Math.min(diff * 0.5, threshold * 1.5) if (diff > 10) { e.preventDefault() } } } const onTouchEnd = async () => { if (!isPulling.value) return if (pullDistance.value >= threshold && !isRefreshing.value) { isRefreshing.value = true await onRefresh() isRefreshing.value = false } isPulling.value = false pullDistance.value = 0 startY = 0 } onMounted(() => { document.addEventListener('touchstart', onTouchStart, { passive: true }) document.addEventListener('touchmove', onTouchMove, { passive: false }) document.addEventListener('touchend', onTouchEnd) }) onUnmounted(() => { document.removeEventListener('touchstart', onTouchStart) document.removeEventListener('touchmove', onTouchMove) document.removeEventListener('touchend', onTouchEnd) }) return { isPulling, pullDistance, isRefreshing, threshold } }