dora-ui
Version:
A React.js Mobile UI Library
203 lines (173 loc) • 6.25 kB
JavaScript
import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray";
import _classCallCheck from "@babel/runtime/helpers/esm/classCallCheck";
import _createClass from "@babel/runtime/helpers/esm/createClass";
import _possibleConstructorReturn from "@babel/runtime/helpers/esm/possibleConstructorReturn";
import _getPrototypeOf from "@babel/runtime/helpers/esm/getPrototypeOf";
import _assertThisInitialized from "@babel/runtime/helpers/esm/assertThisInitialized";
import _inherits from "@babel/runtime/helpers/esm/inherits";
import _defineProperty from "@babel/runtime/helpers/esm/defineProperty";
import React, { Component } from 'react';
import cx from 'classnames';
import PropTypes from 'prop-types';
var Countdown =
/*#__PURE__*/
function (_Component) {
_inherits(Countdown, _Component);
/** 计时器句柄 */
/** 计数器用于校正定时器偏差 */
function Countdown(props) {
var _this;
_classCallCheck(this, Countdown);
_this = _possibleConstructorReturn(this, _getPrototypeOf(Countdown).call(this, props));
_defineProperty(_assertThisInitialized(_this), "beginTime", new Date().getTime());
_defineProperty(_assertThisInitialized(_this), "interval", 1000);
_defineProperty(_assertThisInitialized(_this), "timeCounter", null);
_defineProperty(_assertThisInitialized(_this), "count", 0);
_defineProperty(_assertThisInitialized(_this), "initCounter", function () {
if (_this.timeCounter) clearTimeout(_this.timeCounter);
var endTime = _this.props.endTime;
var ms = endTime - _this.beginTime;
if (ms < 0) return;
_this.setState({
ms: ms
}, function () {
_this.timeCounter = setTimeout(_this.startCountDown, _this.interval);
});
});
_defineProperty(_assertThisInitialized(_this), "startCountDown", function () {
var ms = _this.state.ms;
var onEnd = _this.props.onEnd;
_this.count += 1;
var offset = new Date().getTime() - (_this.beginTime + _this.count * _this.interval); // 误差校正
var nextTime = _this.interval - offset;
if (nextTime < 0) {
nextTime = 0;
}
_this.setState({
ms: Math.max(ms - _this.interval, 0)
}); // console.log(
// `误差:${offset} ms,下一次执行:${nextTime} ms 后,离活动开始还有:${this.state.ms} ms`
// );
if (_this.state.ms <= 0) {
clearTimeout(_this.timeCounter);
typeof onEnd === 'function' && onEnd();
} else {
_this.timeCounter = setTimeout(_this.startCountDown, nextTime);
}
});
_defineProperty(_assertThisInitialized(_this), "padNumber", function (mark, num) {
var _this$props = _this.props,
padding = _this$props.padding,
daysPadding = _this$props.daysPadding;
if (mark === 'dd' && !daysPadding) return num;
if (padding) return num.toString().padStart(2, '0');
return num;
});
_this.state = {
ms: 1
};
return _this;
}
_createClass(Countdown, [{
key: "componentDidMount",
value: function componentDidMount() {
this.initCounter();
}
}, {
key: "componentDidUpdate",
value: function componentDidUpdate(prevProps) {
var endTime = this.props.endTime;
if (endTime !== prevProps.endTime) {
this.initCounter();
}
}
}, {
key: "componentWillUnmount",
value: function componentWillUnmount() {
clearTimeout(this.timeCounter);
}
}, {
key: "render",
value: function render() {
var _this$props2 = this.props,
prefixCls = _this$props2.prefixCls,
wrapClassName = _this$props2.wrapClassName;
var rootCls = cx(prefixCls, wrapClassName);
return React.createElement("div", {
className: rootCls
}, this.formatTime);
}
}, {
key: "parseTime",
// 毫秒 => 天 时 分 秒
get: function get() {
var ms = this.state.ms;
return {
days: Math.floor(ms / (1000 * 60 * 60 * 24)),
hours: Math.floor(ms / (1000 * 60 * 60) % 24),
minutes: Math.floor(ms / (1000 * 60) % 60),
seconds: Math.floor(ms / 1000 % 60)
};
} // 天 时 分 秒 => 展示字符串
}, {
key: "formatTime",
get: function get() {
var _this2 = this;
var _this$props3 = this.props,
format = _this$props3.format,
prefixCls = _this$props3.prefixCls;
var _this$parseTime = this.parseTime,
days = _this$parseTime.days,
hours = _this$parseTime.hours,
minutes = _this$parseTime.minutes,
seconds = _this$parseTime.seconds;
var timeMap = {
dd: days,
hh: hours,
mm: minutes,
ss: seconds
};
return format.split(' ').map(function (item) {
var _item$split = item.split('-'),
_item$split2 = _slicedToArray(_item$split, 2),
mark = _item$split2[0],
_item$split2$ = _item$split2[1],
unit = _item$split2$ === void 0 ? '' : _item$split2$;
return React.createElement("span", {
className: "".concat(prefixCls, "-time-block"),
key: mark + unit
}, React.createElement("span", {
className: "".concat(prefixCls, "-time")
}, String(_this2.padNumber(mark, timeMap[mark])).split('').map(function (s, i) {
return (
/* eslint-disable-next-line react/no-array-index-key */
React.createElement("span", {
key: i,
className: "".concat(prefixCls, "-num")
}, s)
);
})), React.createElement("span", {
className: "".concat(prefixCls, "-unit")
}, unit));
});
}
}]);
return Countdown;
}(Component);
_defineProperty(Countdown, "propTypes", {
endTime: PropTypes.number.isRequired,
onEnd: PropTypes.func,
prefixCls: PropTypes.string,
wrapClassName: PropTypes.string,
format: PropTypes.string,
padding: PropTypes.bool,
daysPadding: PropTypes.bool
});
_defineProperty(Countdown, "defaultProps", {
prefixCls: 'dora-countdown',
wrapClassName: '',
format: 'dd-天 hh-时 mm-分 ss-秒',
padding: true,
daysPadding: false
});
export default Countdown;