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 { Button, Divider, Empty, Flex, Pagination, Skeleton, Space, Switch, Typography } from "antd";
|
||||||
import type { IEventInfo } from "../types";
|
import type { IEventInfo } from "../types";
|
||||||
import { useCallback, useMemo, useState } from "react";
|
import { useCallback, useEffect, useMemo, useState } from "react";
|
||||||
import { EventCard } from "./EventCard";
|
import { EventCard } from "./EventCard";
|
||||||
import { useRequest } from "ahooks";
|
import { useRequest } from "ahooks";
|
||||||
import { CalendarOutlined } from "@ant-design/icons";
|
import { CalendarOutlined } from "@ant-design/icons";
|
||||||
import { STORE_PAGE_LIST_KEY } from "../utils/constants";
|
import { STORE_PAGE_LIST_KEY } from "../utils/constants";
|
||||||
import { useRunOnce } from "../hooks/useRunOnce";
|
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
clubId: string;
|
clubId: string;
|
||||||
@ -58,8 +57,13 @@ export const ClubEvenList = (props: Props) => {
|
|||||||
setShowFinishedEvents(prePage !== 1 || isAllFinishedOrAllNotFinished);
|
setShowFinishedEvents(prePage !== 1 || isAllFinishedOrAllNotFinished);
|
||||||
setPaginationControlVisible(prePage === 1 ? !isAllFinishedOrAllNotFinished : false);
|
setPaginationControlVisible(prePage === 1 ? !isAllFinishedOrAllNotFinished : false);
|
||||||
}
|
}
|
||||||
}, [props]);
|
}, [props.clubId]);
|
||||||
useRunOnce(onPageInit);
|
useEffect(() => {
|
||||||
|
const id = setTimeout(() => {
|
||||||
|
onPageInit();
|
||||||
|
}, 300);
|
||||||
|
return () => clearTimeout(id);
|
||||||
|
}, [onPageInit]);
|
||||||
const handleAddToCalendar = useCallback(() => {
|
const handleAddToCalendar = useCallback(() => {
|
||||||
const url = `${window.location.origin}/api/club/${props.clubId}/calendar.ics`;
|
const url = `${window.location.origin}/api/club/${props.clubId}/calendar.ics`;
|
||||||
const uri = url.replace(/^http(s)?/, 'webcal');
|
const uri = url.replace(/^http(s)?/, 'webcal');
|
||||||
|
|||||||
@ -6,7 +6,7 @@ import timezone from 'dayjs/plugin/timezone';
|
|||||||
import { EyeOutlined } from "@ant-design/icons";
|
import { EyeOutlined } from "@ant-design/icons";
|
||||||
import { useCallback, useEffect, useMemo, useState } from "react";
|
import { useCallback, useEffect, useMemo, useState } from "react";
|
||||||
import { useNavigate } from "react-router";
|
import { useNavigate } from "react-router";
|
||||||
import { useRunOnce } from "../hooks/useRunOnce";
|
import type { TimerType } from "antd/lib/statistic/Timer";
|
||||||
|
|
||||||
dayjs.extend(utc);
|
dayjs.extend(utc);
|
||||||
dayjs.extend(timezone);
|
dayjs.extend(timezone);
|
||||||
@ -23,24 +23,47 @@ export function EventCard(props: EventCardProps) {
|
|||||||
navigate(`/event/${e.matchId}`);
|
navigate(`/event/${e.matchId}`);
|
||||||
}, [e]);
|
}, [e]);
|
||||||
const [messageFormat, setMessageFormat] = useState('');
|
const [messageFormat, setMessageFormat] = useState('');
|
||||||
const getMessageFormat = useCallback(() => {
|
const getStatisticProps = useCallback((): {
|
||||||
|
format: string;
|
||||||
|
type: TimerType;
|
||||||
|
} => {
|
||||||
if (e.isFinished) {
|
if (e.isFinished) {
|
||||||
if (dayjs().diff(day, 'days') < 1) return `已结束`;
|
if (dayjs().diff(day, 'days') < 1) return {
|
||||||
return `已结束 DD 天`;
|
type: 'countdown',
|
||||||
|
format: `已结束`,
|
||||||
|
};
|
||||||
|
return {
|
||||||
|
type: 'countup',
|
||||||
|
format: `已结束 DD 天`,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
if (e.isProcessing) {
|
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]);
|
}, [e, day]);
|
||||||
|
const [statisticType, setStatisticType] = useState<TimerType>('countdown');
|
||||||
const updateMessageFormat = useCallback(() => {
|
const updateMessageFormat = useCallback(() => {
|
||||||
const format = getMessageFormat();
|
const statistic = getStatisticProps();
|
||||||
setMessageFormat(format);
|
setMessageFormat(statistic.format);
|
||||||
console.debug('format: %s', format);
|
setStatisticType(statistic.type);
|
||||||
}, [getMessageFormat])
|
console.debug('format: %s', day.format(statistic.format), statistic);
|
||||||
useRunOnce(updateMessageFormat);
|
}, [getStatisticProps])
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const timeout = day.toDate().getTime() - Date.now();
|
const timeout = day.toDate().getTime() - Date.now();
|
||||||
|
updateMessageFormat();
|
||||||
const id = setTimeout(() => {
|
const id = setTimeout(() => {
|
||||||
updateMessageFormat();
|
updateMessageFormat();
|
||||||
}, timeout);
|
}, timeout);
|
||||||
@ -63,7 +86,7 @@ export function EventCard(props: EventCardProps) {
|
|||||||
>
|
>
|
||||||
<Typography.Text type={e.isFinished ? 'secondary' : 'success'}>{e.title}</Typography.Text>
|
<Typography.Text type={e.isFinished ? 'secondary' : 'success'}>{e.title}</Typography.Text>
|
||||||
<Statistic.Timer
|
<Statistic.Timer
|
||||||
type={e.isProcessing ? 'countup' : 'countdown'}
|
type={statisticType}
|
||||||
value={day.toDate().getTime()}
|
value={day.toDate().getTime()}
|
||||||
format={messageFormat}
|
format={messageFormat}
|
||||||
styles={{ content: e.isFinished ? { color: 'gray' } : {} }}
|
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