feat(fasting): 新增轻断食功能模块
新增完整的轻断食功能,包括: - 断食计划列表和详情页面,支持12-12、14-10、16-8、18-6四种计划 - 断食状态实时追踪和倒计时显示 - 自定义开始时间选择器 - 断食通知提醒功能 - Redux状态管理和数据持久化 - 新增tab导航入口和路由配置
This commit is contained in:
54
hooks/useCountdown.ts
Normal file
54
hooks/useCountdown.ts
Normal file
@@ -0,0 +1,54 @@
|
||||
import { useEffect, useMemo, useRef, useState } from 'react';
|
||||
import { formatCountdown } from '@/utils/fasting';
|
||||
|
||||
interface CountdownOptions {
|
||||
target: Date | null | undefined;
|
||||
intervalMs?: number;
|
||||
autoStart?: boolean;
|
||||
}
|
||||
|
||||
export const useCountdown = ({ target, intervalMs = 1000, autoStart = true }: CountdownOptions) => {
|
||||
const [now, setNow] = useState(() => new Date());
|
||||
const timerRef = useRef<ReturnType<typeof setInterval> | null>(null);
|
||||
const targetTimestamp = target instanceof Date ? target.getTime() : null;
|
||||
|
||||
useEffect(() => {
|
||||
if (!autoStart) return undefined;
|
||||
if (targetTimestamp == null) return undefined;
|
||||
|
||||
timerRef.current && clearInterval(timerRef.current);
|
||||
timerRef.current = setInterval(() => {
|
||||
setNow(new Date());
|
||||
}, intervalMs);
|
||||
|
||||
return () => {
|
||||
if (timerRef.current) {
|
||||
clearInterval(timerRef.current);
|
||||
timerRef.current = null;
|
||||
}
|
||||
};
|
||||
}, [targetTimestamp, intervalMs, autoStart]);
|
||||
|
||||
useEffect(() => {
|
||||
if (targetTimestamp == null) return;
|
||||
setNow(new Date());
|
||||
}, [targetTimestamp]);
|
||||
|
||||
const diffMs = useMemo(() => {
|
||||
if (targetTimestamp == null) return 0;
|
||||
return targetTimestamp - now.getTime();
|
||||
}, [targetTimestamp, now]);
|
||||
|
||||
const formatted = useMemo(() => {
|
||||
if (targetTimestamp == null) return '--:--:--';
|
||||
return formatCountdown(new Date(targetTimestamp), now);
|
||||
}, [targetTimestamp, now]);
|
||||
|
||||
return {
|
||||
now,
|
||||
diffMs,
|
||||
formatted,
|
||||
isExpired: diffMs <= 0,
|
||||
hasTarget: targetTimestamp != null,
|
||||
};
|
||||
};
|
||||
Reference in New Issue
Block a user