]>
cat aescling's git repositories - mastodon.git/blob - app/javascript/mastodon/components/relative_timestamp.js
1 import React
from 'react';
2 import { injectIntl
, defineMessages
} from 'react-intl';
3 import PropTypes
from 'prop-types';
5 const messages
= defineMessages({
6 just_now: { id: 'relative_time.just_now', defaultMessage: 'now' },
7 seconds: { id: 'relative_time.seconds', defaultMessage: '{number}s' },
8 minutes: { id: 'relative_time.minutes', defaultMessage: '{number}m' },
9 hours: { id: 'relative_time.hours', defaultMessage: '{number}h' },
10 days: { id: 'relative_time.days', defaultMessage: '{number}d' },
13 const dateFormatOptions
= {
22 const shortDateFormatOptions
= {
28 const MINUTE
= 1000 * 60;
29 const HOUR
= 1000 * 60 * 60;
30 const DAY
= 1000 * 60 * 60 * 24;
32 const MAX_DELAY
= 2147483647;
34 const selectUnits
= delta
=> {
35 const absDelta
= Math
.abs(delta
);
37 if (absDelta
< MINUTE
) {
39 } else if (absDelta
< HOUR
) {
41 } else if (absDelta
< DAY
) {
48 const getUnitDelay
= units
=> {
64 export default class RelativeTimestamp
extends React
.Component
{
67 intl: PropTypes
.object
.isRequired
,
68 timestamp: PropTypes
.string
.isRequired
,
72 now: this.props
.intl
.now(),
75 shouldComponentUpdate (nextProps
, nextState
) {
76 // As of right now the locale doesn't change without a new page load,
77 // but we might as well check in case that ever changes.
78 return this.props
.timestamp
!== nextProps
.timestamp
||
79 this.props
.intl
.locale
!== nextProps
.intl
.locale
||
80 this.state
.now
!== nextState
.now
;
83 componentWillReceiveProps (nextProps
) {
84 if (this.props
.timestamp
!== nextProps
.timestamp
) {
85 this.setState({ now: this.props
.intl
.now() });
89 componentDidMount () {
90 this._scheduleNextUpdate(this.props
, this.state
);
93 componentWillUpdate (nextProps
, nextState
) {
94 this._scheduleNextUpdate(nextProps
, nextState
);
97 componentWillUnmount () {
98 clearTimeout(this._timer
);
101 _scheduleNextUpdate (props
, state
) {
102 clearTimeout(this._timer
);
104 const { timestamp
} = props
;
105 const delta
= (new Date(timestamp
)).getTime() - state
.now
;
106 const unitDelay
= getUnitDelay(selectUnits(delta
));
107 const unitRemainder
= Math
.abs(delta
% unitDelay
);
108 const updateInterval
= 1000 * 10;
109 const delay
= delta
< 0 ? Math
.max(updateInterval
, unitDelay
- unitRemainder
) : Math
.max(updateInterval
, unitRemainder
);
111 this._timer
= setTimeout(() => {
112 this.setState({ now: this.props
.intl
.now() });
117 const { timestamp
, intl
} = this.props
;
119 const date
= new Date(timestamp
);
120 const delta
= this.state
.now
- date
.getTime();
124 if (delta
< 10 * SECOND
) {
125 relativeTime
= intl
.formatMessage(messages
.just_now
);
126 } else if (delta
< 3 * DAY
) {
127 if (delta
< MINUTE
) {
128 relativeTime
= intl
.formatMessage(messages
.seconds
, { number: Math
.floor(delta
/ SECOND
) });
129 } else if (delta
< HOUR
) {
130 relativeTime
= intl
.formatMessage(messages
.minutes
, { number: Math
.floor(delta
/ MINUTE
) });
131 } else if (delta
< DAY
) {
132 relativeTime
= intl
.formatMessage(messages
.hours
, { number: Math
.floor(delta
/ HOUR
) });
134 relativeTime
= intl
.formatMessage(messages
.days
, { number: Math
.floor(delta
/ DAY
) });
137 relativeTime
= intl
.formatDate(date
, shortDateFormatOptions
);
141 <time dateTime
={timestamp
} title
={intl
.formatDate(date
, dateFormatOptions
)}>
This page took 0.104555 seconds and 4 git commands to generate.