Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Countdown support onFinish #14791

Merged
merged 4 commits into from
Feb 12, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 17 additions & 4 deletions components/statistic/Countdown.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,11 @@ const REFRESH_INTERVAL = 1000 / 30;
interface CountdownProps extends StatisticProps {
value?: countdownValueType;
format?: string;
onFinish?: () => void;
}

function getTime(value?: countdownValueType) {
return interopDefault(moment)(value).valueOf();
}

class Countdown extends React.Component<CountdownProps, {}> {
Expand All @@ -34,7 +39,7 @@ class Countdown extends React.Component<CountdownProps, {}> {
syncTimer = () => {
const { value } = this.props;

const timestamp = interopDefault(moment)(value).valueOf();
const timestamp = getTime(value);
if (timestamp >= Date.now()) {
this.startTimer();
} else {
Expand All @@ -43,16 +48,24 @@ class Countdown extends React.Component<CountdownProps, {}> {
};

startTimer = () => {
if (this.countdownId !== undefined) return;
if (this.countdownId) return;

this.countdownId = window.setInterval(() => {
this.forceUpdate();
}, REFRESH_INTERVAL);
};

stopTimer = () => {
clearInterval(this.countdownId);
this.countdownId = undefined;
const { onFinish, value } = this.props;
if (this.countdownId) {
clearInterval(this.countdownId);
this.countdownId = undefined;

const timestamp = getTime(value);
if (onFinish && timestamp < Date.now()) {
onFinish();
}
}
};

formatCountdown = (value: countdownValueType, config: FormatConfig) => {
Expand Down
34 changes: 32 additions & 2 deletions components/statistic/__tests__/index.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -61,17 +61,47 @@ describe('Statistic', () => {

it('time going', async () => {
const now = Date.now() + 1000;
const wrapper = mount(<Statistic.Countdown value={now} />);
const onFinish = jest.fn();
const wrapper = mount(<Statistic.Countdown value={now} onFinish={onFinish} />);
wrapper.update();

// setInterval should work
const instance = wrapper.instance();
expect(instance.countdownId).not.toBe(undefined);

await delay(50);
await delay(10);

wrapper.unmount();
expect(instance.countdownId).toBe(undefined);
expect(onFinish).not.toBeCalled();
});

describe('time finished', () => {
it('not call if time already passed', () => {
const now = Date.now() - 1000;

const onFinish = jest.fn();
const wrapper = mount(<Statistic.Countdown value={now} onFinish={onFinish} />);
wrapper.update();

const instance = wrapper.instance();
expect(instance.countdownId).toBe(undefined);
expect(onFinish).not.toBeCalled();
});

it('called if finished', async () => {
jest.useFakeTimers();
const now = Date.now() + 10;
const onFinish = jest.fn();
const wrapper = mount(<Statistic.Countdown value={now} onFinish={onFinish} />);
wrapper.update();

MockDate.set(moment('2019-11-28 00:00:00'));
jest.runAllTimers();

expect(onFinish).toBeCalled();
jest.useFakeTimers();
});
});
});
});
6 changes: 5 additions & 1 deletion components/statistic/demo/countdown.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,14 @@ import { Statistic, Row, Col } from 'antd';
const Countdown = Statistic.Countdown;
const deadline = Date.now() + 1000 * 60 * 60 * 24 * 2 + 1000 * 30; // Moment is also OK

function onFinish() {
console.log('finished!');
}

ReactDOM.render(
<Row gutter={16}>
<Col span={12}>
<Countdown title="Countdown" value={deadline} />
<Countdown title="Countdown" value={deadline} onFinish={onFinish} />
</Col>
<Col span={12}>
<Countdown title="Million Seconds" value={deadline} format="HH:mm:ss:SSS" />
Expand Down
1 change: 1 addition & 0 deletions components/statistic/index.en-US.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ Display statistic number.
| Property | Description | Type | Default |
| -------- | ----------- | ---- | ------- |
| format | Format as [moment](http://momentjs.com/) | string | 'HH:mm:ss' |
| onFinish | Trigger when time's up | () => void | - |
| prefix | prefix node of value | string \| ReactNode | - |
| suffix | suffix node of value | string \| ReactNode | - |
| title | Display title | string \| ReactNode | - |
Expand Down
1 change: 1 addition & 0 deletions components/statistic/index.zh-CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ title: Statistic
| 参数 | 说明 | 类型 | 默认值 |
| -------- | ----------- | ---- | ------- |
| format | 格式化倒计时展示,参考 [moment](http://momentjs.com/) | string | 'HH:mm:ss' |
| onFinish | 倒计时完成时触发 | () => void | - |
| prefix | 设置数值的前缀 | string \| ReactNode | - |
| suffix | 设置数值的后缀 | string \| ReactNode | - |
| title | 数值的标题 | string \| ReactNode | - |
Expand Down