Update poll remaining time just like with status timestamps (#10466)

remotes/1727458204337373841/tmp_refs/heads/signup-info-prompt
ThibG 2019-04-03 18:16:55 +02:00 committed by Eugen Rochko
parent d07b0c038f
commit daab45d4ae
2 changed files with 30 additions and 33 deletions

View File

@ -9,41 +9,12 @@ import Motion from 'mastodon/features/ui/util/optional_motion';
import spring from 'react-motion/lib/spring'; import spring from 'react-motion/lib/spring';
import escapeTextContentForBrowser from 'escape-html'; import escapeTextContentForBrowser from 'escape-html';
import emojify from 'mastodon/features/emoji/emoji'; import emojify from 'mastodon/features/emoji/emoji';
import RelativeTimestamp from './relative_timestamp';
const messages = defineMessages({ const messages = defineMessages({
moments: { id: 'time_remaining.moments', defaultMessage: 'Moments remaining' },
seconds: { id: 'time_remaining.seconds', defaultMessage: '{number, plural, one {# second} other {# seconds}} left' },
minutes: { id: 'time_remaining.minutes', defaultMessage: '{number, plural, one {# minute} other {# minutes}} left' },
hours: { id: 'time_remaining.hours', defaultMessage: '{number, plural, one {# hour} other {# hours}} left' },
days: { id: 'time_remaining.days', defaultMessage: '{number, plural, one {# day} other {# days}} left' },
closed: { id: 'poll.closed', defaultMessage: 'Closed' }, closed: { id: 'poll.closed', defaultMessage: 'Closed' },
}); });
const SECOND = 1000;
const MINUTE = 1000 * 60;
const HOUR = 1000 * 60 * 60;
const DAY = 1000 * 60 * 60 * 24;
const timeRemainingString = (intl, date, now) => {
const delta = date.getTime() - now;
let relativeTime;
if (delta < 10 * SECOND) {
relativeTime = intl.formatMessage(messages.moments);
} else if (delta < MINUTE) {
relativeTime = intl.formatMessage(messages.seconds, { number: Math.floor(delta / SECOND) });
} else if (delta < HOUR) {
relativeTime = intl.formatMessage(messages.minutes, { number: Math.floor(delta / MINUTE) });
} else if (delta < DAY) {
relativeTime = intl.formatMessage(messages.hours, { number: Math.floor(delta / HOUR) });
} else {
relativeTime = intl.formatMessage(messages.days, { number: Math.floor(delta / DAY) });
}
return relativeTime;
};
const makeEmojiMap = record => record.get('emojis').reduce((obj, emoji) => { const makeEmojiMap = record => record.get('emojis').reduce((obj, emoji) => {
obj[`:${emoji.get('shortcode')}:`] = emoji.toJS(); obj[`:${emoji.get('shortcode')}:`] = emoji.toJS();
return obj; return obj;
@ -146,7 +117,7 @@ class Poll extends ImmutablePureComponent {
return null; return null;
} }
const timeRemaining = poll.get('expired') ? intl.formatMessage(messages.closed) : timeRemainingString(intl, new Date(poll.get('expires_at')), intl.now()); const timeRemaining = poll.get('expired') ? intl.formatMessage(messages.closed) : <RelativeTimestamp timestamp={poll.get('expires_at')} futureDate />;
const showResults = poll.get('voted') || poll.get('expired'); const showResults = poll.get('voted') || poll.get('expired');
const disabled = this.props.disabled || Object.entries(this.state.selected).every(item => !item); const disabled = this.props.disabled || Object.entries(this.state.selected).every(item => !item);

View File

@ -8,6 +8,11 @@ const messages = defineMessages({
minutes: { id: 'relative_time.minutes', defaultMessage: '{number}m' }, minutes: { id: 'relative_time.minutes', defaultMessage: '{number}m' },
hours: { id: 'relative_time.hours', defaultMessage: '{number}h' }, hours: { id: 'relative_time.hours', defaultMessage: '{number}h' },
days: { id: 'relative_time.days', defaultMessage: '{number}d' }, days: { id: 'relative_time.days', defaultMessage: '{number}d' },
moments_remaining: { id: 'time_remaining.moments', defaultMessage: 'Moments remaining' },
seconds_remaining: { id: 'time_remaining.seconds', defaultMessage: '{number, plural, one {# second} other {# seconds}} left' },
minutes_remaining: { id: 'time_remaining.minutes', defaultMessage: '{number, plural, one {# minute} other {# minutes}} left' },
hours_remaining: { id: 'time_remaining.hours', defaultMessage: '{number, plural, one {# hour} other {# hours}} left' },
days_remaining: { id: 'time_remaining.days', defaultMessage: '{number, plural, one {# day} other {# days}} left' },
}); });
const dateFormatOptions = { const dateFormatOptions = {
@ -86,6 +91,26 @@ export const timeAgoString = (intl, date, now, year) => {
return relativeTime; return relativeTime;
}; };
const timeRemainingString = (intl, date, now) => {
const delta = date.getTime() - now;
let relativeTime;
if (delta < 10 * SECOND) {
relativeTime = intl.formatMessage(messages.moments_remaining);
} else if (delta < MINUTE) {
relativeTime = intl.formatMessage(messages.seconds_remaining, { number: Math.floor(delta / SECOND) });
} else if (delta < HOUR) {
relativeTime = intl.formatMessage(messages.minutes_remaining, { number: Math.floor(delta / MINUTE) });
} else if (delta < DAY) {
relativeTime = intl.formatMessage(messages.hours_remaining, { number: Math.floor(delta / HOUR) });
} else {
relativeTime = intl.formatMessage(messages.days_remaining, { number: Math.floor(delta / DAY) });
}
return relativeTime;
};
export default @injectIntl export default @injectIntl
class RelativeTimestamp extends React.Component { class RelativeTimestamp extends React.Component {
@ -93,6 +118,7 @@ class RelativeTimestamp extends React.Component {
intl: PropTypes.object.isRequired, intl: PropTypes.object.isRequired,
timestamp: PropTypes.string.isRequired, timestamp: PropTypes.string.isRequired,
year: PropTypes.number.isRequired, year: PropTypes.number.isRequired,
futureDate: PropTypes.bool,
}; };
state = { state = {
@ -145,10 +171,10 @@ class RelativeTimestamp extends React.Component {
} }
render () { render () {
const { timestamp, intl, year } = this.props; const { timestamp, intl, year, futureDate } = this.props;
const date = new Date(timestamp); const date = new Date(timestamp);
const relativeTime = timeAgoString(intl, date, this.state.now, year); const relativeTime = futureDate ? timeRemainingString(intl, date, this.state.now) : timeAgoString(intl, date, this.state.now, year);
return ( return (
<time dateTime={timestamp} title={intl.formatDate(date, dateFormatOptions)}> <time dateTime={timestamp} title={intl.formatDate(date, dateFormatOptions)}>