MM-18466 Change recent date separators to yesterday/today (#3245)

* MM-18466 Change recent date separators to yesterday/today

* Add i18n strings
This commit is contained in:
Harrison Healey 2019-09-14 06:02:51 -04:00 committed by Elias Nahum
parent ed29e2fbee
commit 6fc8569266
5 changed files with 198 additions and 8 deletions

View file

@ -31,8 +31,7 @@ exports[`DateHeader component should match snapshot when timezone is set 1`] = `
}
}
>
<FormattedDate
format="ddd, MMM DD, YYYY"
<RecentDate
style={
Object {
"color": "#3d3c40",
@ -88,8 +87,7 @@ exports[`DateHeader component should match snapshot with suffix 1`] = `
}
}
>
<FormattedDate
format="ddd, MMM DD, YYYY"
<RecentDate
style={
Object {
"color": "#3d3c40",
@ -145,8 +143,7 @@ exports[`DateHeader component should match snapshot without suffix 1`] = `
}
}
>
<FormattedDate
format="ddd, MMM DD, YYYY"
<RecentDate
style={
Object {
"color": "#3d3c40",

View file

@ -8,7 +8,7 @@ import {
ViewPropTypes,
} from 'react-native';
import FormattedDate from 'app/components/formatted_date';
import RecentDate from 'app/components/recent_date';
import {makeStyleSheetFromTheme} from 'app/utils/theme';
// DateHeader accepts as a timestamp for rendering as part of a post list.
@ -28,7 +28,7 @@ export default class DateHeader extends PureComponent {
<View style={[style.container, this.props.style]}>
<View style={style.line}/>
<View style={style.dateContainer}>
<FormattedDate
<RecentDate
style={style.date}
timeZone={timeZone}
value={date}

View file

@ -0,0 +1,68 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
import PropTypes from 'prop-types';
import React from 'react';
import FormattedText from 'app/components/formatted_text';
import FormattedDate from 'app/components/formatted_date';
export default class RecentDate extends React.PureComponent {
static propTypes = {
value: PropTypes.oneOfType([
PropTypes.number,
PropTypes.instanceOf(Date),
]).isRequired,
}
render() {
const {value, ...otherProps} = this.props;
const date = new Date(value);
if (isToday(date)) {
return (
<FormattedText
{...otherProps}
id='date_separator.today'
defaultMessage='Today'
/>
);
} else if (isYesterday(date)) {
return (
<FormattedText
{...otherProps}
id='date_separator.yesterday'
defaultMessage='Yesterday'
/>
);
}
return (
<FormattedDate
{...otherProps}
value={value}
weekday='short'
month='short'
day='2-digit'
year='numeric'
/>
);
}
}
export function isSameDay(a, b) {
return a.getDate() === b.getDate() && a.getMonth() === b.getMonth() && a.getFullYear() === b.getFullYear();
}
export function isToday(date) {
const now = new Date();
return isSameDay(date, now);
}
export function isYesterday(date) {
const yesterday = new Date();
yesterday.setDate(yesterday.getDate() - 1);
return isSameDay(date, yesterday);
}

View file

@ -0,0 +1,123 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
import React from 'react';
import FormattedDate from 'app/components/formatted_date';
import FormattedText from 'app/components/formatted_text';
import {shallowWithIntl} from 'test/intl-test-helper.js';
import RecentDate, {
isToday,
isYesterday,
} from './recent_date';
describe('RecentDate', () => {
test('should render "Today" today', () => {
const today = new Date();
const props = {
value: today,
};
const wrapper = shallowWithIntl(<RecentDate {...props}/>);
expect(wrapper.find(FormattedText).exists()).toBe(true);
expect(wrapper.find(FormattedText).prop('id')).toBe('date_separator.today');
});
test('should render "Yesterday" yesterday', () => {
const yesterday = new Date();
yesterday.setDate(yesterday.getDate() - 1);
const props = {
value: yesterday,
};
const wrapper = shallowWithIntl(<RecentDate {...props}/>);
expect(wrapper.find(FormattedText).exists()).toBe(true);
expect(wrapper.find(FormattedText).prop('id')).toBe('date_separator.yesterday');
});
test('should render date two days ago', () => {
const twoDaysAgo = new Date();
twoDaysAgo.setDate(twoDaysAgo.getDate() - 2);
const props = {
value: twoDaysAgo,
};
const wrapper = shallowWithIntl(<RecentDate {...props}/>);
expect(wrapper.find(FormattedDate).exists()).toBe(true);
});
});
describe('isToday and isYesterday', () => {
test('tomorrow at 12am', () => {
const date = new Date();
date.setDate(date.getDate() + 1);
date.setHours(0);
date.setMinutes(0);
expect(isToday(date)).toBe(false);
expect(isYesterday(date)).toBe(false);
});
test('now', () => {
const date = new Date();
expect(isToday(date)).toBe(true);
expect(isYesterday(date)).toBe(false);
});
test('today at 12am', () => {
const date = new Date();
date.setHours(0);
date.setMinutes(0);
expect(isToday(date)).toBe(true);
expect(isYesterday(date)).toBe(false);
});
test('today at 11:59pm', () => {
const date = new Date();
date.setHours(23);
date.setMinutes(59);
expect(isToday(date)).toBe(true);
expect(isYesterday(date)).toBe(false);
});
test('yesterday at 11:59pm', () => {
const date = new Date();
date.setDate(date.getDate() - 1);
date.setHours(23);
date.setMinutes(59);
expect(isToday(date)).toBe(false);
expect(isYesterday(date)).toBe(true);
});
test('yesterday at 12am', () => {
const date = new Date();
date.setDate(date.getDate() - 1);
date.setHours(0);
date.setMinutes(0);
expect(isToday(date)).toBe(false);
expect(isYesterday(date)).toBe(true);
});
test('two days ago at 11:59pm', () => {
const date = new Date();
date.setDate(date.getDate() - 2);
date.setHours(23);
date.setMinutes(59);
expect(isToday(date)).toBe(false);
expect(isYesterday(date)).toBe(false);
});
});

View file

@ -74,6 +74,8 @@
"create_comment.addComment": "Add a comment...",
"create_post.deactivated": "You are viewing an archived channel with a deactivated user.",
"create_post.write": "Write to {channelDisplayName}",
"date_separator.today": "Today",
"date_separator.yesterday": "Yesterday",
"edit_post.editPost": "Edit the post...",
"edit_post.save": "Save",
"file_attachment.download": "Download",