diff --git a/app/components/formatted_date.js b/app/components/formatted_date.js
index 370e51222..8641688b1 100644
--- a/app/components/formatted_date.js
+++ b/app/components/formatted_date.js
@@ -3,35 +3,33 @@
import React from 'react';
import PropTypes from 'prop-types';
-import {injectIntl, intlShape} from 'react-intl';
+import moment from 'moment-timezone';
import {Text} from 'react-native';
-class FormattedDate extends React.PureComponent {
+export default class FormattedDate extends React.PureComponent {
static propTypes = {
- intl: intlShape.isRequired,
- value: PropTypes.any.isRequired,
format: PropTypes.string,
- children: PropTypes.func,
+ timeZone: PropTypes.string,
+ value: PropTypes.any.isRequired,
+ };
+
+ static defaultProps = {
+ format: 'ddd, MMM DD, YYYY',
};
render() {
const {
- intl,
+ format,
+ timeZone,
value,
- children,
...props
} = this.props;
- Reflect.deleteProperty(props, 'format');
-
- const formattedDate = intl.formatDate(value, this.props);
-
- if (typeof children === 'function') {
- return children(formattedDate);
+ let formattedDate = moment(value).format(format);
+ if (timeZone) {
+ formattedDate = moment.tz(value, timeZone).format(format);
}
return {formattedDate};
}
}
-
-export default injectIntl(FormattedDate);
diff --git a/app/components/formatted_time.js b/app/components/formatted_time.js
index 9f9ea57dd..64cc06569 100644
--- a/app/components/formatted_time.js
+++ b/app/components/formatted_time.js
@@ -3,7 +3,6 @@
import React from 'react';
import PropTypes from 'prop-types';
-import {intlShape} from 'react-intl';
import {Text} from 'react-native';
import moment from 'moment-timezone';
@@ -15,30 +14,19 @@ export default class FormattedTime extends React.PureComponent {
hour12: PropTypes.bool,
};
- static contextTypes = {
- intl: intlShape.isRequired,
- };
-
getFormattedTime = () => {
- const {intl} = this.context;
-
const {
value,
timeZone,
hour12,
} = this.props;
+ const format = hour12 ? 'hh:mm A' : 'HH:mm';
if (timeZone) {
- const format = hour12 ? 'hh:mm A' : 'HH:mm';
return moment.tz(value, timeZone).format(format);
}
- // If no timezone is defined fallback to the previous implementation
- return intl.formatDate(new Date(value), {
- hour: 'numeric',
- minute: 'numeric',
- hour12,
- });
+ return moment(value).format(format);
};
render() {
diff --git a/app/components/post_header/post_header.js b/app/components/post_header/post_header.js
index f9a62f9a9..fee5d3406 100644
--- a/app/components/post_header/post_header.js
+++ b/app/components/post_header/post_header.js
@@ -218,7 +218,10 @@ export default class PostHeader extends PureComponent {
dateComponent = (
-
+
-
-
-
diff --git a/app/i18n/index.js b/app/i18n/index.js
index 7cc58dd93..5271638ed 100644
--- a/app/i18n/index.js
+++ b/app/i18n/index.js
@@ -4,6 +4,7 @@
import 'intl';
import {addLocaleData} from 'react-intl';
import enLocaleData from 'react-intl/locale-data/en';
+import moment from 'moment';
import en from 'assets/i18n/en.json';
@@ -16,72 +17,92 @@ addLocaleData(enLocaleData);
function loadTranslation(locale) {
try {
let localeData;
+ let momentData;
switch (locale) {
case 'de':
TRANSLATIONS.de = require('assets/i18n/de.json');
localeData = require('react-intl/locale-data/de');
+ momentData = require('moment/locale/de');
break;
case 'es':
TRANSLATIONS.es = require('assets/i18n/es.json');
localeData = require('react-intl/locale-data/es');
+ momentData = require('moment/locale/es');
break;
case 'fr':
TRANSLATIONS.fr = require('assets/i18n/fr.json');
localeData = require('react-intl/locale-data/fr');
+ momentData = require('moment/locale/fr');
break;
case 'it':
TRANSLATIONS.it = require('assets/i18n/it.json');
localeData = require('react-intl/locale-data/it');
+ momentData = require('moment/locale/it');
break;
case 'ja':
TRANSLATIONS.ja = require('assets/i18n/ja.json');
localeData = require('react-intl/locale-data/ja');
+ momentData = require('moment/locale/ja');
break;
case 'ko':
TRANSLATIONS.ko = require('assets/i18n/ko.json');
localeData = require('react-intl/locale-data/ko');
+ momentData = require('moment/locale/ko');
break;
case 'nl':
TRANSLATIONS.nl = require('assets/i18n/nl.json');
localeData = require('react-intl/locale-data/nl');
+ momentData = require('moment/locale/nl');
break;
case 'pl':
TRANSLATIONS.pl = require('assets/i18n/pl.json');
localeData = require('react-intl/locale-data/pl');
+ momentData = require('moment/locale/pl');
break;
case 'pt-BR':
TRANSLATIONS[locale] = require('assets/i18n/pt-BR.json');
localeData = require('react-intl/locale-data/pt');
+ momentData = require('moment/locale/pt-br');
break;
case 'ro':
TRANSLATIONS.ro = require('assets/i18n/ro.json');
localeData = require('react-intl/locale-data/ro');
+ momentData = require('moment/locale/ro');
break;
case 'ru':
TRANSLATIONS.ru = require('assets/i18n/ru.json');
localeData = require('react-intl/locale-data/ru');
+ momentData = require('moment/locale/ru');
break;
case 'tr':
TRANSLATIONS.tr = require('assets/i18n/tr.json');
localeData = require('react-intl/locale-data/tr');
+ momentData = require('moment/locale/tr');
break;
case 'uk':
TRANSLATIONS.tr = require('assets/i18n/uk.json');
localeData = require('react-intl/locale-data/uk');
+ momentData = require('moment/locale/uk');
break;
case 'zh-CN':
TRANSLATIONS[locale] = require('assets/i18n/zh-CN.json');
localeData = require('react-intl/locale-data/zh');
+ momentData = require('moment/locale/zh-cn');
break;
case 'zh-TW':
TRANSLATIONS[locale] = require('assets/i18n/zh-TW.json');
localeData = require('react-intl/locale-data/zh');
+ momentData = require('moment/locale/zh-tw');
break;
}
if (localeData) {
addLocaleData(localeData);
}
+
+ if (momentData) {
+ moment.updateLocale(locale, momentData);
+ }
} catch (e) {
console.error('NO Translation found', e); //eslint-disable-line no-console
}
diff --git a/app/screens/channel_info/__snapshots__/channel_info_header.test.js.snap b/app/screens/channel_info/__snapshots__/channel_info_header.test.js.snap
index cb023a6ae..3bb6582f1 100644
--- a/app/screens/channel_info/__snapshots__/channel_info_header.test.js.snap
+++ b/app/screens/channel_info/__snapshots__/channel_info_header.test.js.snap
@@ -1,13 +1,7 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`channel_info_header should match snapshot 1`] = `
-
+
-
@@ -416,13 +408,7 @@ exports[`channel_info_header should match snapshot 1`] = `
`;
exports[`channel_info_header should match snapshot when DM and hasGuests 1`] = `
-
+
-
@@ -859,13 +843,7 @@ exports[`channel_info_header should match snapshot when DM and hasGuests 1`] = `
`;
exports[`channel_info_header should match snapshot when GM and hasGuests 1`] = `
-
+
-
@@ -1302,13 +1278,7 @@ exports[`channel_info_header should match snapshot when GM and hasGuests 1`] = `
`;
exports[`channel_info_header should match snapshot when is group constrained 1`] = `
-
+
-
@@ -1738,13 +1706,7 @@ exports[`channel_info_header should match snapshot when is group constrained 1`]
`;
exports[`channel_info_header should match snapshot when public channel and hasGuests 1`] = `
-
+
-
diff --git a/app/screens/channel_info/channel_info_header.js b/app/screens/channel_info/channel_info_header.js
index 7a52023c5..053495368 100644
--- a/app/screens/channel_info/channel_info_header.js
+++ b/app/screens/channel_info/channel_info_header.js
@@ -41,6 +41,7 @@ export default class ChannelInfoHeader extends React.PureComponent {
isBot: PropTypes.bool.isRequired,
hasGuests: PropTypes.bool.isRequired,
isGroupConstrained: PropTypes.bool,
+ timeZone: PropTypes.string,
};
static contextTypes = {
@@ -135,6 +136,7 @@ export default class ChannelInfoHeader extends React.PureComponent {
isArchived,
isBot,
isGroupConstrained,
+ timeZone,
} = this.props;
const style = getStyleSheet(theme);
@@ -145,7 +147,7 @@ export default class ChannelInfoHeader extends React.PureComponent {
style.detail;
return (
-
+
}
@@ -287,8 +288,5 @@ const getStyleSheet = makeStyleSheetFromTheme((theme) => {
row: {
paddingHorizontal: 15,
},
- safeAreaView: {
- backgroundColor: 'white',
- },
};
});
diff --git a/app/screens/channel_info/index.js b/app/screens/channel_info/index.js
index f849083b6..81be9d9d9 100644
--- a/app/screens/channel_info/index.js
+++ b/app/screens/channel_info/index.js
@@ -29,7 +29,8 @@ import {getCurrentUserId, getUser, getStatusForUserId, getCurrentUserRoles} from
import {areChannelMentionsIgnored, getUserIdFromChannelName, isChannelMuted, showDeleteOption, showManagementOptions} from 'mattermost-redux/utils/channel_utils';
import {isAdmin as checkIsAdmin, isChannelAdmin as checkIsChannelAdmin, isSystemAdmin as checkIsSystemAdmin} from 'mattermost-redux/utils/user_utils';
import {getConfig, getLicense} from 'mattermost-redux/selectors/entities/general';
-import {isGuest} from 'app/utils/users';
+import {isTimezoneEnabled} from 'mattermost-redux/selectors/entities/timezone';
+import {getUserCurrentTimezone} from 'mattermost-redux/utils/timezone_utils';
import {
popTopScreen,
@@ -47,6 +48,8 @@ import {
setChannelDisplayName,
} from 'app/actions/views/channel';
import {isLandscape} from 'app/selectors/device';
+import {isGuest} from 'app/utils/users';
+
import ChannelInfo from './channel_info';
function mapStateToProps(state) {
@@ -93,6 +96,12 @@ function mapStateToProps(state) {
const canEditChannel = !channelIsReadOnly && showManagementOptions(state, config, license, currentChannel, isAdmin, isSystemAdmin, isChannelAdmin);
const viewArchivedChannels = config.ExperimentalViewArchivedChannels === 'true';
+ const enableTimezone = isTimezoneEnabled(state);
+ let timeZone = null;
+ if (enableTimezone) {
+ timeZone = getUserCurrentTimezone(currentUser.timezone);
+ }
+
return {
canDeleteChannel: showDeleteOption(state, config, license, currentChannel, isAdmin, isSystemAdmin, isChannelAdmin),
viewArchivedChannels,
@@ -112,6 +121,7 @@ function mapStateToProps(state) {
canManageUsers,
isBot,
isLandscape: isLandscape(state),
+ timeZone,
};
}