1 | "use strict";
|
2 | Object.defineProperty(exports, "__esModule", { value: true });
|
3 | var tslib_1 = require("tslib");
|
4 |
|
5 |
|
6 |
|
7 |
|
8 |
|
9 | var React = tslib_1.__importStar(require("react"));
|
10 | var ecma402_abstract_1 = require("@formatjs/ecma402-abstract");
|
11 | var useIntl_1 = tslib_1.__importDefault(require("./useIntl"));
|
12 | var MINUTE = 60;
|
13 | var HOUR = 60 * 60;
|
14 | var DAY = 60 * 60 * 24;
|
15 | function selectUnit(seconds) {
|
16 | var absValue = Math.abs(seconds);
|
17 | if (absValue < MINUTE) {
|
18 | return 'second';
|
19 | }
|
20 | if (absValue < HOUR) {
|
21 | return 'minute';
|
22 | }
|
23 | if (absValue < DAY) {
|
24 | return 'hour';
|
25 | }
|
26 | return 'day';
|
27 | }
|
28 | function getDurationInSeconds(unit) {
|
29 | switch (unit) {
|
30 | case 'second':
|
31 | return 1;
|
32 | case 'minute':
|
33 | return MINUTE;
|
34 | case 'hour':
|
35 | return HOUR;
|
36 | default:
|
37 | return DAY;
|
38 | }
|
39 | }
|
40 | function valueToSeconds(value, unit) {
|
41 | if (!value) {
|
42 | return 0;
|
43 | }
|
44 | switch (unit) {
|
45 | case 'second':
|
46 | return value;
|
47 | case 'minute':
|
48 | return value * MINUTE;
|
49 | default:
|
50 | return value * HOUR;
|
51 | }
|
52 | }
|
53 | var INCREMENTABLE_UNITS = [
|
54 | 'second',
|
55 | 'minute',
|
56 | 'hour',
|
57 | ];
|
58 | function canIncrement(unit) {
|
59 | if (unit === void 0) { unit = 'second'; }
|
60 | return INCREMENTABLE_UNITS.indexOf(unit) > -1;
|
61 | }
|
62 | var SimpleFormattedRelativeTime = function (props) {
|
63 | var _a = useIntl_1.default(), formatRelativeTime = _a.formatRelativeTime, Text = _a.textComponent;
|
64 | var children = props.children, value = props.value, unit = props.unit, otherProps = tslib_1.__rest(props, ["children", "value", "unit"]);
|
65 | var formattedRelativeTime = formatRelativeTime(value || 0, unit, otherProps);
|
66 | if (typeof children === 'function') {
|
67 | return children(formattedRelativeTime);
|
68 | }
|
69 | if (Text) {
|
70 | return React.createElement(Text, null, formattedRelativeTime);
|
71 | }
|
72 | return React.createElement(React.Fragment, null, formattedRelativeTime);
|
73 | };
|
74 | var FormattedRelativeTime = function (_a) {
|
75 | var value = _a.value, unit = _a.unit, updateIntervalInSeconds = _a.updateIntervalInSeconds, otherProps = tslib_1.__rest(_a, ["value", "unit", "updateIntervalInSeconds"]);
|
76 | ecma402_abstract_1.invariant(!updateIntervalInSeconds ||
|
77 | !!(updateIntervalInSeconds && canIncrement(unit)), 'Cannot schedule update with unit longer than hour');
|
78 | var _b = React.useState(), prevUnit = _b[0], setPrevUnit = _b[1];
|
79 | var _c = React.useState(0), prevValue = _c[0], setPrevValue = _c[1];
|
80 | var _d = React.useState(0), currentValueInSeconds = _d[0], setCurrentValueInSeconds = _d[1];
|
81 | var updateTimer;
|
82 | if (unit !== prevUnit || value !== prevValue) {
|
83 | setPrevValue(value || 0);
|
84 | setPrevUnit(unit);
|
85 | setCurrentValueInSeconds(canIncrement(unit) ? valueToSeconds(value, unit) : 0);
|
86 | }
|
87 | React.useEffect(function () {
|
88 | function clearUpdateTimer() {
|
89 | clearTimeout(updateTimer);
|
90 | }
|
91 | clearUpdateTimer();
|
92 |
|
93 | if (!updateIntervalInSeconds || !canIncrement(unit)) {
|
94 | return clearUpdateTimer;
|
95 | }
|
96 |
|
97 | var nextValueInSeconds = currentValueInSeconds - updateIntervalInSeconds;
|
98 | var nextUnit = selectUnit(nextValueInSeconds);
|
99 |
|
100 | if (nextUnit === 'day') {
|
101 | return clearUpdateTimer;
|
102 | }
|
103 | var unitDuration = getDurationInSeconds(nextUnit);
|
104 | var remainder = nextValueInSeconds % unitDuration;
|
105 | var prevInterestingValueInSeconds = nextValueInSeconds - remainder;
|
106 | var nextInterestingValueInSeconds = prevInterestingValueInSeconds >= currentValueInSeconds
|
107 | ? prevInterestingValueInSeconds - unitDuration
|
108 | : prevInterestingValueInSeconds;
|
109 | var delayInSeconds = Math.abs(nextInterestingValueInSeconds - currentValueInSeconds);
|
110 | if (currentValueInSeconds !== nextInterestingValueInSeconds) {
|
111 | updateTimer = setTimeout(function () { return setCurrentValueInSeconds(nextInterestingValueInSeconds); }, delayInSeconds * 1e3);
|
112 | }
|
113 | return clearUpdateTimer;
|
114 | }, [currentValueInSeconds, updateIntervalInSeconds, unit]);
|
115 | var currentValue = value || 0;
|
116 | var currentUnit = unit;
|
117 | if (canIncrement(unit) &&
|
118 | typeof currentValueInSeconds === 'number' &&
|
119 | updateIntervalInSeconds) {
|
120 | currentUnit = selectUnit(currentValueInSeconds);
|
121 | var unitDuration = getDurationInSeconds(currentUnit);
|
122 | currentValue = Math.round(currentValueInSeconds / unitDuration);
|
123 | }
|
124 | return (React.createElement(SimpleFormattedRelativeTime, tslib_1.__assign({ value: currentValue, unit: currentUnit }, otherProps)));
|
125 | };
|
126 | FormattedRelativeTime.displayName = 'FormattedRelativeTime';
|
127 | FormattedRelativeTime.defaultProps = {
|
128 | value: 0,
|
129 | unit: 'second',
|
130 | };
|
131 | exports.default = FormattedRelativeTime;
|