Files
cozsweet-frontend-nextjs/src/hooks/use-pull-to-refresh.ts
T
admin 6e51cb7d16 Refactor: Remove original Dart references from comments across multiple files
- Updated comments in various components, schemas, and repositories to remove references to original Dart files.
- Ensured consistency in documentation while maintaining the context of the code.
2026-06-29 11:31:21 +08:00

70 lines
2.2 KiB
TypeScript

"use client";
/**
* 下拉刷新 hook(占位实现)
*
*
*
* 当前实现:最小可用版本 —— 监听顶部 overscroll 触发 onRefresh。
* 后续可替换为 react-use / react-easy-refresh。
*/
import { useEffect, useRef, useState } from "react";
export function usePullToRefresh(
onRefresh: () => Promise<void> | void,
options: { threshold?: number; disabled?: boolean } = {},
): {
isRefreshing: boolean;
pullDistance: number;
containerRef: React.RefObject<HTMLDivElement | null>;
} {
const { threshold = 80, disabled = false } = options;
const [isRefreshing, setIsRefreshing] = useState(false);
const [pullDistance, setPullDistance] = useState(0);
const startY = useRef<number | null>(null);
const containerRef = useRef<HTMLDivElement | null>(null);
useEffect(() => {
if (disabled || typeof window === "undefined") return;
const el = containerRef.current;
if (!el) return;
const onTouchStart = (e: TouchEvent) => {
if (el.scrollTop > 0) return;
startY.current = e.touches[0]?.clientY ?? null;
};
const onTouchMove = (e: TouchEvent) => {
if (startY.current == null) return;
const y = e.touches[0]?.clientY ?? startY.current;
const delta = y - startY.current;
if (delta > 0 && el.scrollTop <= 0) {
setPullDistance(Math.min(delta, threshold * 1.5));
}
};
const onTouchEnd = async () => {
if (startY.current == null) return;
if (pullDistance >= threshold && !isRefreshing) {
setIsRefreshing(true);
try {
await onRefresh();
} finally {
setIsRefreshing(false);
setPullDistance(0);
}
} else {
setPullDistance(0);
}
startY.current = null;
};
el.addEventListener("touchstart", onTouchStart, { passive: true });
el.addEventListener("touchmove", onTouchMove, { passive: true });
el.addEventListener("touchend", onTouchEnd);
return () => {
el.removeEventListener("touchstart", onTouchStart);
el.removeEventListener("touchmove", onTouchMove);
el.removeEventListener("touchend", onTouchEnd);
};
}, [threshold, disabled, isRefreshing, onRefresh, pullDistance]);
return { isRefreshing, pullDistance, containerRef };
}