UNPKG

5.17 kBJavaScriptView Raw
1"use strict";
2Object.defineProperty(exports, "__esModule", { value: true });
3var tslib_1 = require("tslib");
4/*
5 * Copyright 2015, Yahoo Inc.
6 * Copyrights licensed under the New BSD License.
7 * See the accompanying LICENSE file for terms.
8 */
9var React = tslib_1.__importStar(require("react"));
10var ecma402_abstract_1 = require("@formatjs/ecma402-abstract");
11var useIntl_1 = tslib_1.__importDefault(require("./useIntl"));
12var MINUTE = 60;
13var HOUR = 60 * 60;
14var DAY = 60 * 60 * 24;
15function 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}
28function 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}
40function 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}
53var INCREMENTABLE_UNITS = [
54 'second',
55 'minute',
56 'hour',
57];
58function canIncrement(unit) {
59 if (unit === void 0) { unit = 'second'; }
60 return INCREMENTABLE_UNITS.indexOf(unit) > -1;
61}
62var 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};
74var 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 // If there's no interval and we cannot increment this unit, do nothing
93 if (!updateIntervalInSeconds || !canIncrement(unit)) {
94 return clearUpdateTimer;
95 }
96 // Figure out the next interesting time
97 var nextValueInSeconds = currentValueInSeconds - updateIntervalInSeconds;
98 var nextUnit = selectUnit(nextValueInSeconds);
99 // We've reached the max auto incrementable unit, don't schedule another update
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};
126FormattedRelativeTime.displayName = 'FormattedRelativeTime';
127FormattedRelativeTime.defaultProps = {
128 value: 0,
129 unit: 'second',
130};
131exports.default = FormattedRelativeTime;