refactor(components): migrate to Ant Design Statistic.Timer and remove useRunOnce
- Deleted the custom `useRunOnce` hook as its functionality is no longer needed. - Refactored `EventCard` to determine `type` (countup/countdown) dynamically based on the event state and current time. - Updated `EventCard` to pass `type` and `format` separately to the `Statistic.Timer` component, removing the need for string formatting logic inside the component. - Modified `ClubEventList` to add a 300ms delay on page initialization, ensuring the component is fully mounted before triggering the initial fetch logic.
This commit is contained in:
parent
0f9e80856b
commit
7103c5f7e3
@ -1,11 +1,10 @@
|
||||
import { Button, Divider, Empty, Flex, Pagination, Skeleton, Space, Switch, Typography } from "antd";
|
||||
import type { IEventInfo } from "../types";
|
||||
import { useCallback, useMemo, useState } from "react";
|
||||
import { useCallback, useEffect, useMemo, useState } from "react";
|
||||
import { EventCard } from "./EventCard";
|
||||
import { useRequest } from "ahooks";
|
||||
import { CalendarOutlined } from "@ant-design/icons";
|
||||
import { STORE_PAGE_LIST_KEY } from "../utils/constants";
|
||||
import { useRunOnce } from "../hooks/useRunOnce";
|
||||
|
||||
interface Props {
|
||||
clubId: string;
|
||||
@ -58,8 +57,13 @@ export const ClubEvenList = (props: Props) => {
|
||||
setShowFinishedEvents(prePage !== 1 || isAllFinishedOrAllNotFinished);
|
||||
setPaginationControlVisible(prePage === 1 ? !isAllFinishedOrAllNotFinished : false);
|
||||
}
|
||||
}, [props]);
|
||||
useRunOnce(onPageInit);
|
||||
}, [props.clubId]);
|
||||
useEffect(() => {
|
||||
const id = setTimeout(() => {
|
||||
onPageInit();
|
||||
}, 300);
|
||||
return () => clearTimeout(id);
|
||||
}, [onPageInit]);
|
||||
const handleAddToCalendar = useCallback(() => {
|
||||
const url = `${window.location.origin}/api/club/${props.clubId}/calendar.ics`;
|
||||
const uri = url.replace(/^http(s)?/, 'webcal');
|
||||
|
||||
@ -6,7 +6,7 @@ import timezone from 'dayjs/plugin/timezone';
|
||||
import { EyeOutlined } from "@ant-design/icons";
|
||||
import { useCallback, useEffect, useMemo, useState } from "react";
|
||||
import { useNavigate } from "react-router";
|
||||
import { useRunOnce } from "../hooks/useRunOnce";
|
||||
import type { TimerType } from "antd/lib/statistic/Timer";
|
||||
|
||||
dayjs.extend(utc);
|
||||
dayjs.extend(timezone);
|
||||
@ -23,24 +23,47 @@ export function EventCard(props: EventCardProps) {
|
||||
navigate(`/event/${e.matchId}`);
|
||||
}, [e]);
|
||||
const [messageFormat, setMessageFormat] = useState('');
|
||||
const getMessageFormat = useCallback(() => {
|
||||
const getStatisticProps = useCallback((): {
|
||||
format: string;
|
||||
type: TimerType;
|
||||
} => {
|
||||
if (e.isFinished) {
|
||||
if (dayjs().diff(day, 'days') < 1) return `已结束`;
|
||||
return `已结束 DD 天`;
|
||||
if (dayjs().diff(day, 'days') < 1) return {
|
||||
type: 'countdown',
|
||||
format: `已结束`,
|
||||
};
|
||||
return {
|
||||
type: 'countup',
|
||||
format: `已结束 DD 天`,
|
||||
};
|
||||
}
|
||||
if (e.isProcessing) {
|
||||
return '比赛进行中 HH:mm:ss';
|
||||
return {
|
||||
type: 'countup',
|
||||
format: '比赛进行中 HH:mm:ss',
|
||||
}
|
||||
return `距离比赛开始还有 DD 天 HH:mm:ss`;
|
||||
}
|
||||
if (dayjs().diff(day, 'days') === 0) {
|
||||
return {
|
||||
type: 'countdown',
|
||||
format: `距离比赛开始还有 HH:mm:ss`,
|
||||
};
|
||||
}
|
||||
return {
|
||||
type: 'countdown',
|
||||
format: `距离比赛开始还有 DD 天 HH:mm:ss`,
|
||||
};
|
||||
}, [e, day]);
|
||||
const [statisticType, setStatisticType] = useState<TimerType>('countdown');
|
||||
const updateMessageFormat = useCallback(() => {
|
||||
const format = getMessageFormat();
|
||||
setMessageFormat(format);
|
||||
console.debug('format: %s', format);
|
||||
}, [getMessageFormat])
|
||||
useRunOnce(updateMessageFormat);
|
||||
const statistic = getStatisticProps();
|
||||
setMessageFormat(statistic.format);
|
||||
setStatisticType(statistic.type);
|
||||
console.debug('format: %s', day.format(statistic.format), statistic);
|
||||
}, [getStatisticProps])
|
||||
useEffect(() => {
|
||||
const timeout = day.toDate().getTime() - Date.now();
|
||||
updateMessageFormat();
|
||||
const id = setTimeout(() => {
|
||||
updateMessageFormat();
|
||||
}, timeout);
|
||||
@ -63,7 +86,7 @@ export function EventCard(props: EventCardProps) {
|
||||
>
|
||||
<Typography.Text type={e.isFinished ? 'secondary' : 'success'}>{e.title}</Typography.Text>
|
||||
<Statistic.Timer
|
||||
type={e.isProcessing ? 'countup' : 'countdown'}
|
||||
type={statisticType}
|
||||
value={day.toDate().getTime()}
|
||||
format={messageFormat}
|
||||
styles={{ content: e.isFinished ? { color: 'gray' } : {} }}
|
||||
|
||||
@ -1,13 +0,0 @@
|
||||
import { useEffect, useRef } from "react"
|
||||
|
||||
export const useRunOnce = (callback: () => void) => {
|
||||
const done = useRef(false);
|
||||
useEffect(() => {
|
||||
const id = setTimeout(() => {
|
||||
if (done.current) return;
|
||||
done.current = true;
|
||||
callback();
|
||||
}, 0);
|
||||
return () => clearTimeout(id);
|
||||
}, [callback]);
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user