Make relatives times coherent with web (#9062)
* Make relatives times coherent with web * Fix test
This commit is contained in:
parent
71cec5a3e2
commit
4f27a022c3
8 changed files with 133 additions and 177 deletions
|
|
@ -9,118 +9,157 @@ import FriendlyDate from './index';
|
|||
|
||||
describe('Friendly Date', () => {
|
||||
it('should render correctly', () => {
|
||||
jest.useFakeTimers();
|
||||
jest.setSystemTime(new Date('2020-05-15T00:00:00.000Z'));
|
||||
|
||||
const justNow = new Date();
|
||||
justNow.setSeconds(justNow.getSeconds() - 10);
|
||||
let value = justNow.getTime();
|
||||
const justNowText = renderWithIntl(
|
||||
<FriendlyDate value={justNow}/>,
|
||||
<FriendlyDate value={value}/>,
|
||||
);
|
||||
expect(justNowText.getByText('Now')).toBeTruthy();
|
||||
|
||||
const minutesAgo = new Date();
|
||||
minutesAgo.setMinutes(minutesAgo.getMinutes() - 1);
|
||||
value = minutesAgo.getTime();
|
||||
const minutesAgoText = renderWithIntl(
|
||||
<FriendlyDate value={minutesAgo}/>,
|
||||
<FriendlyDate value={value}/>,
|
||||
);
|
||||
expect(minutesAgoText.getByText('1 min ago')).toBeTruthy();
|
||||
expect(minutesAgoText.getByText('1 min. ago')).toBeTruthy();
|
||||
|
||||
const hoursAgo = new Date();
|
||||
hoursAgo.setHours(hoursAgo.getHours() - 4);
|
||||
value = hoursAgo.getTime();
|
||||
const hoursAgoText = renderWithIntl(
|
||||
<FriendlyDate value={hoursAgo}/>,
|
||||
<FriendlyDate value={value}/>,
|
||||
);
|
||||
expect(hoursAgoText.getByText('4 hours ago')).toBeTruthy();
|
||||
|
||||
const yesterday = new Date();
|
||||
yesterday.setDate(yesterday.getDate() - 1);
|
||||
value = yesterday.getTime();
|
||||
const yesterdayText = renderWithIntl(
|
||||
<FriendlyDate value={yesterday}/>,
|
||||
<FriendlyDate value={value}/>,
|
||||
);
|
||||
expect(yesterdayText.getByText('Yesterday')).toBeTruthy();
|
||||
expect(yesterdayText.getByText('yesterday')).toBeTruthy();
|
||||
|
||||
const daysAgo = new Date();
|
||||
daysAgo.setDate(daysAgo.getDate() - 10);
|
||||
value = daysAgo.getTime();
|
||||
const daysAgoText = renderWithIntl(
|
||||
<FriendlyDate value={daysAgo}/>,
|
||||
<FriendlyDate value={value}/>,
|
||||
);
|
||||
expect(daysAgoText.getByText('10 days ago')).toBeTruthy();
|
||||
|
||||
// Difference is less than 30 days
|
||||
const daysEdgeCase = new Date(2020, 3, 28);
|
||||
const daysEdgeCaseTodayDate = new Date(2020, 4, 28);
|
||||
jest.setSystemTime(daysEdgeCaseTodayDate);
|
||||
value = daysEdgeCase.getTime();
|
||||
const daysEdgeCaseText = renderWithIntl(
|
||||
<FriendlyDate
|
||||
sourceDate={daysEdgeCaseTodayDate}
|
||||
value={daysEdgeCase}
|
||||
/>,
|
||||
<FriendlyDate value={value}/>,
|
||||
);
|
||||
expect(daysEdgeCaseText.getByText('1 month ago')).toBeTruthy();
|
||||
expect(daysEdgeCaseText.getByText('last month')).toBeTruthy();
|
||||
|
||||
const daysAgoMax = new Date(2020, 4, 6);
|
||||
const daysAgoMaxTodayDate = new Date(2020, 5, 5);
|
||||
jest.setSystemTime(daysAgoMaxTodayDate);
|
||||
value = daysAgoMax.getTime();
|
||||
const daysAgoMaxText = renderWithIntl(
|
||||
<FriendlyDate
|
||||
sourceDate={daysAgoMaxTodayDate}
|
||||
value={daysAgoMax}
|
||||
/>,
|
||||
<FriendlyDate value={value}/>,
|
||||
);
|
||||
expect(daysAgoMaxText.getByText('30 days ago')).toBeTruthy();
|
||||
|
||||
const monthsAgo = new Date();
|
||||
monthsAgo.setMonth(monthsAgo.getMonth() - 2);
|
||||
value = monthsAgo.getTime();
|
||||
const monthsAgoText = renderWithIntl(
|
||||
<FriendlyDate value={monthsAgo}/>,
|
||||
<FriendlyDate value={value}/>,
|
||||
);
|
||||
expect(monthsAgoText.getByText('2 months ago')).toBeTruthy();
|
||||
|
||||
const yearsAgo = new Date();
|
||||
yearsAgo.setFullYear(yearsAgo.getFullYear() - 2);
|
||||
value = yearsAgo.getTime();
|
||||
const yearsAgoText = renderWithIntl(
|
||||
<FriendlyDate value={yearsAgo}/>,
|
||||
<FriendlyDate value={value}/>,
|
||||
);
|
||||
expect(yearsAgoText.getByText('2 years ago')).toBeTruthy();
|
||||
|
||||
jest.useRealTimers();
|
||||
});
|
||||
|
||||
it('should render correctly with times in the future', () => {
|
||||
jest.useFakeTimers();
|
||||
jest.setSystemTime(new Date('2020-05-15T00:00:00.000Z'));
|
||||
|
||||
const justNow = new Date();
|
||||
justNow.setSeconds(justNow.getSeconds() + 10);
|
||||
let value = justNow.getTime();
|
||||
const justNowText = renderWithIntl(
|
||||
<FriendlyDate value={justNow}/>,
|
||||
<FriendlyDate value={value}/>,
|
||||
);
|
||||
expect(justNowText.getByText('Now')).toBeTruthy();
|
||||
|
||||
const inMinutes = new Date();
|
||||
inMinutes.setMinutes(inMinutes.getMinutes() + 2);
|
||||
value = inMinutes.getTime();
|
||||
const inMinutesText = renderWithIntl(
|
||||
<FriendlyDate value={inMinutes}/>,
|
||||
<FriendlyDate value={value}/>,
|
||||
);
|
||||
expect(inMinutesText.getByText('in 2 mins')).toBeTruthy();
|
||||
expect(inMinutesText.getByText('in 2 min.')).toBeTruthy();
|
||||
|
||||
const inHours = new Date();
|
||||
inHours.setHours(inHours.getHours() + 2);
|
||||
value = inHours.getTime();
|
||||
const inHoursText = renderWithIntl(
|
||||
<FriendlyDate value={inHours}/>,
|
||||
<FriendlyDate value={value}/>,
|
||||
);
|
||||
expect(inHoursText.getByText('in 2 hours')).toBeTruthy();
|
||||
|
||||
const inDays = new Date();
|
||||
inDays.setDate(inDays.getDate() + 2);
|
||||
value = inDays.getTime();
|
||||
const inDaysText = renderWithIntl(
|
||||
<FriendlyDate value={inDays}/>,
|
||||
<FriendlyDate value={value}/>,
|
||||
);
|
||||
expect(inDaysText.getByText('in 2 days')).toBeTruthy();
|
||||
|
||||
const inDaysEdgeCase = new Date(2020, 5, 28);
|
||||
const inDaysEdgeCaseTodayDate = new Date(2020, 4, 28);
|
||||
jest.setSystemTime(inDaysEdgeCaseTodayDate);
|
||||
value = inDaysEdgeCase.getTime();
|
||||
const inDaysEdgeCaseText = renderWithIntl(
|
||||
<FriendlyDate value={value}/>,
|
||||
);
|
||||
expect(inDaysEdgeCaseText.getByText('next month')).toBeTruthy();
|
||||
|
||||
const inDaysMax = new Date(2020, 5, 4);
|
||||
const inDaysMaxTodayDate = new Date(2020, 4, 5);
|
||||
jest.setSystemTime(inDaysMaxTodayDate);
|
||||
value = inDaysMax.getTime();
|
||||
const inDaysMaxText = renderWithIntl(
|
||||
<FriendlyDate value={value}/>,
|
||||
);
|
||||
expect(inDaysMaxText.getByText('in 30 days')).toBeTruthy();
|
||||
|
||||
const inMonths = new Date();
|
||||
inMonths.setMonth(inMonths.getMonth() + 2);
|
||||
value = inMonths.getTime();
|
||||
const inMonthsText = renderWithIntl(
|
||||
<FriendlyDate value={inMonths}/>,
|
||||
<FriendlyDate value={value}/>,
|
||||
);
|
||||
expect(inMonthsText.getByText('in 2 months')).toBeTruthy();
|
||||
|
||||
const inYears = new Date();
|
||||
inYears.setFullYear(inYears.getFullYear() + 2);
|
||||
value = inYears.getTime();
|
||||
const inYearsText = renderWithIntl(
|
||||
<FriendlyDate value={inYears}/>,
|
||||
<FriendlyDate value={value}/>,
|
||||
);
|
||||
expect(inYearsText.getByText('in 2 years')).toBeTruthy();
|
||||
|
||||
jest.useRealTimers();
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,43 +1,49 @@
|
|||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import moment from 'moment';
|
||||
import React from 'react';
|
||||
import {type IntlShape, useIntl} from 'react-intl';
|
||||
import {type StyleProp, Text, type TextStyle} from 'react-native';
|
||||
|
||||
import {DateTime} from '@constants';
|
||||
import {isYesterday} from '@utils/datetime';
|
||||
|
||||
const {SECONDS} = DateTime;
|
||||
|
||||
type Props = {
|
||||
style?: StyleProp<TextStyle>;
|
||||
sourceDate?: number | Date;
|
||||
value: number | Date;
|
||||
value: number;
|
||||
};
|
||||
|
||||
function FriendlyDate({style, sourceDate, value}: Props) {
|
||||
function FriendlyDate({style, value}: Props) {
|
||||
const intl = useIntl();
|
||||
const formattedTime = getFriendlyDate(intl, value, sourceDate);
|
||||
const formattedTime = getFriendlyDate(intl, value);
|
||||
return (
|
||||
<Text style={style}>{formattedTime}</Text>
|
||||
);
|
||||
}
|
||||
|
||||
export function getFriendlyDate(intl: IntlShape, inputDate: number | Date, sourceDate?: number | Date): string {
|
||||
const today = sourceDate ? new Date(sourceDate) : new Date();
|
||||
const date = new Date(inputDate);
|
||||
const difference = (today.getTime() - date.getTime()) / 1000;
|
||||
if (difference < 0) {
|
||||
return getFriendlyDateAfter(intl, -difference, date, today);
|
||||
}
|
||||
function getDiff(inputDate: number, unit: moment.unitOfTime.Diff) {
|
||||
const input = new Date(inputDate);
|
||||
const today = new Date();
|
||||
|
||||
return getFriendlyDateBefore(intl, difference, date, today);
|
||||
const momentA = moment.utc(input.getTime());
|
||||
const momentB = moment.utc(today.getTime());
|
||||
|
||||
const diff = momentA.startOf(unit).diff(momentB.startOf(unit), unit);
|
||||
|
||||
return diff;
|
||||
}
|
||||
|
||||
function getFriendlyDateAfter(intl: IntlShape, difference: number, date: Date, today: Date): string {
|
||||
export function getFriendlyDate(intl: IntlShape, inputDate: number): string {
|
||||
const today = new Date();
|
||||
const date = new Date(inputDate);
|
||||
const difference = (date.getTime() - today.getTime()) / 1000;
|
||||
const absoluteDifference = Math.abs(difference);
|
||||
const sign = Math.sign(difference);
|
||||
|
||||
// Message: Now
|
||||
if (difference < SECONDS.MINUTE) {
|
||||
if (absoluteDifference < SECONDS.MINUTE) {
|
||||
return intl.formatMessage({
|
||||
id: 'friendly_date.now',
|
||||
defaultMessage: 'Now',
|
||||
|
|
@ -45,143 +51,31 @@ function getFriendlyDateAfter(intl: IntlShape, difference: number, date: Date, t
|
|||
}
|
||||
|
||||
// Message: Minutes
|
||||
if (difference < SECONDS.HOUR) {
|
||||
const minutes = Math.floor(Math.round((10 * difference) / SECONDS.MINUTE) / 10);
|
||||
return intl.formatMessage({
|
||||
id: 'friendly_date.mins',
|
||||
defaultMessage: 'in {count} {count, plural, one {min} other {mins}}',
|
||||
}, {
|
||||
count: minutes,
|
||||
});
|
||||
if (absoluteDifference < SECONDS.HOUR) {
|
||||
return intl.formatRelativeTime(getDiff(inputDate, 'minute'), 'minute', {numeric: 'auto', style: 'short'});
|
||||
}
|
||||
|
||||
// Message: Hours
|
||||
if (difference < SECONDS.DAY) {
|
||||
const hours = Math.floor(Math.round((10 * difference) / SECONDS.HOUR) / 10);
|
||||
return intl.formatMessage({
|
||||
id: 'friendly_date.hours',
|
||||
defaultMessage: 'in {count} {count, plural, one {hour} other {hours}}',
|
||||
}, {
|
||||
count: hours,
|
||||
});
|
||||
if (absoluteDifference < SECONDS.DAY) {
|
||||
return intl.formatRelativeTime(getDiff(inputDate, 'hour'), 'hour', {numeric: 'auto'});
|
||||
}
|
||||
|
||||
// Message: Days
|
||||
if (difference < SECONDS.DAYS_31) {
|
||||
if (today.getDate() + 1 === date.getDate() && today.getMonth() === date.getMonth()) {
|
||||
return intl.formatMessage({
|
||||
id: 'friendly_date.tomorrow',
|
||||
defaultMessage: 'Tomorrow',
|
||||
});
|
||||
}
|
||||
const completedAMonth = today.getMonth() !== date.getMonth() && today.getDate() <= date.getDate();
|
||||
if (absoluteDifference < SECONDS.DAYS_31) {
|
||||
const passedDate = sign === 1 ? today.getDate() <= date.getDate() : today.getDate() >= date.getDate();
|
||||
const completedAMonth = today.getMonth() !== date.getMonth() && passedDate;
|
||||
if (!completedAMonth) {
|
||||
const days = Math.floor(Math.round((10 * difference) / SECONDS.DAY) / 10) || 1;
|
||||
return intl.formatMessage({
|
||||
id: 'friendly_date.days',
|
||||
defaultMessage: 'in {count} {count, plural, one {day} other {days}}',
|
||||
}, {
|
||||
count: days,
|
||||
});
|
||||
return intl.formatRelativeTime(getDiff(inputDate, 'day'), 'day', {numeric: 'auto'});
|
||||
}
|
||||
}
|
||||
|
||||
// Message: Months
|
||||
if (difference < SECONDS.DAYS_366) {
|
||||
const months = Math.floor(Math.round((10 * difference) / SECONDS.DAYS_30) / 10) || 1;
|
||||
return intl.formatMessage({
|
||||
id: 'friendly_date.months',
|
||||
defaultMessage: 'in {count} {count, plural, one {month} other {months}}',
|
||||
}, {
|
||||
count: months,
|
||||
});
|
||||
if (absoluteDifference < SECONDS.DAYS_366) {
|
||||
return intl.formatRelativeTime(getDiff(inputDate, 'month'), 'month', {numeric: 'auto'});
|
||||
}
|
||||
|
||||
// Message: Years
|
||||
const years = Math.floor(Math.round((10 * difference) / SECONDS.DAYS_365) / 10) || 1;
|
||||
return intl.formatMessage({
|
||||
id: 'friendly_date.years',
|
||||
defaultMessage: 'in {count} {count, plural, one {year} other {years}}',
|
||||
}, {
|
||||
count: years,
|
||||
});
|
||||
}
|
||||
|
||||
function getFriendlyDateBefore(intl: IntlShape, difference: number, date: Date, today: Date): string {
|
||||
// Message: Now
|
||||
if (difference < SECONDS.MINUTE) {
|
||||
return intl.formatMessage({
|
||||
id: 'friendly_date.now',
|
||||
defaultMessage: 'Now',
|
||||
});
|
||||
}
|
||||
|
||||
// Message: Minutes Ago
|
||||
if (difference < SECONDS.HOUR) {
|
||||
const minutes = Math.floor(Math.round((10 * difference) / SECONDS.MINUTE) / 10);
|
||||
return intl.formatMessage({
|
||||
id: 'friendly_date.minsAgo',
|
||||
defaultMessage: '{count} {count, plural, one {min} other {mins}} ago',
|
||||
}, {
|
||||
count: minutes,
|
||||
});
|
||||
}
|
||||
|
||||
// Message: Hours Ago
|
||||
if (difference < SECONDS.DAY) {
|
||||
const hours = Math.floor(Math.round((10 * difference) / SECONDS.HOUR) / 10);
|
||||
return intl.formatMessage({
|
||||
id: 'friendly_date.hoursAgo',
|
||||
defaultMessage: '{count} {count, plural, one {hour} other {hours}} ago',
|
||||
}, {
|
||||
count: hours,
|
||||
});
|
||||
}
|
||||
|
||||
// Message: Days Ago
|
||||
if (difference < SECONDS.DAYS_31) {
|
||||
if (isYesterday(date)) {
|
||||
return intl.formatMessage({
|
||||
id: 'friendly_date.yesterday',
|
||||
defaultMessage: 'Yesterday',
|
||||
});
|
||||
}
|
||||
const completedAMonth = today.getMonth() !== date.getMonth() && today.getDate() >= date.getDate();
|
||||
if (!completedAMonth) {
|
||||
const days = Math.floor(Math.round((10 * difference) / SECONDS.DAY) / 10) || 1;
|
||||
return intl.formatMessage({
|
||||
id: 'friendly_date.daysAgo',
|
||||
defaultMessage: '{count} {count, plural, one {day} other {days}} ago',
|
||||
}, {
|
||||
count: days,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Message: Months Ago
|
||||
if (difference < SECONDS.DAYS_366) {
|
||||
const completedAnYear = today.getFullYear() !== date.getFullYear() &&
|
||||
today.getMonth() >= date.getMonth() &&
|
||||
today.getDate() >= date.getDate();
|
||||
if (!completedAnYear) {
|
||||
const months = Math.floor(Math.round((10 * difference) / SECONDS.DAYS_30) / 10) || 1;
|
||||
return intl.formatMessage({
|
||||
id: 'friendly_date.monthsAgo',
|
||||
defaultMessage: '{count} {count, plural, one {month} other {months}} ago',
|
||||
}, {
|
||||
count: months,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Message: Years Ago
|
||||
const years = Math.floor(Math.round((10 * difference) / SECONDS.DAYS_365) / 10) || 1;
|
||||
return intl.formatMessage({
|
||||
id: 'friendly_date.yearsAgo',
|
||||
defaultMessage: '{count} {count, plural, one {year} other {years}} ago',
|
||||
}, {
|
||||
count: years,
|
||||
});
|
||||
return intl.formatRelativeTime(getDiff(inputDate, 'year'), 'year', {numeric: 'auto'});
|
||||
}
|
||||
|
||||
export default FriendlyDate;
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@ function loadTranslation(locale?: string): {[x: string]: string} {
|
|||
require('@formatjs/intl-numberformat/locale-data/bg');
|
||||
require('@formatjs/intl-datetimeformat/locale-data/bg');
|
||||
require('@formatjs/intl-listformat/locale-data/bg');
|
||||
require('@formatjs/intl-relativetimeformat/locale-data/bg');
|
||||
|
||||
translations = require('@assets/i18n/bg.json');
|
||||
break;
|
||||
|
|
@ -32,6 +33,7 @@ function loadTranslation(locale?: string): {[x: string]: string} {
|
|||
require('@formatjs/intl-numberformat/locale-data/de');
|
||||
require('@formatjs/intl-datetimeformat/locale-data/de');
|
||||
require('@formatjs/intl-listformat/locale-data/de');
|
||||
require('@formatjs/intl-relativetimeformat/locale-data/de');
|
||||
|
||||
translations = require('@assets/i18n/de.json');
|
||||
break;
|
||||
|
|
@ -40,6 +42,7 @@ function loadTranslation(locale?: string): {[x: string]: string} {
|
|||
require('@formatjs/intl-numberformat/locale-data/en');
|
||||
require('@formatjs/intl-datetimeformat/locale-data/en');
|
||||
require('@formatjs/intl-listformat/locale-data/en');
|
||||
require('@formatjs/intl-relativetimeformat/locale-data/en');
|
||||
|
||||
translations = require('@assets/i18n/en_AU.json');
|
||||
break;
|
||||
|
|
@ -48,6 +51,7 @@ function loadTranslation(locale?: string): {[x: string]: string} {
|
|||
require('@formatjs/intl-numberformat/locale-data/es');
|
||||
require('@formatjs/intl-datetimeformat/locale-data/es');
|
||||
require('@formatjs/intl-listformat/locale-data/es');
|
||||
require('@formatjs/intl-relativetimeformat/locale-data/es');
|
||||
|
||||
translations = require('@assets/i18n/es.json');
|
||||
break;
|
||||
|
|
@ -56,6 +60,7 @@ function loadTranslation(locale?: string): {[x: string]: string} {
|
|||
require('@formatjs/intl-numberformat/locale-data/fa');
|
||||
require('@formatjs/intl-datetimeformat/locale-data/fa');
|
||||
require('@formatjs/intl-listformat/locale-data/fa');
|
||||
require('@formatjs/intl-relativetimeformat/locale-data/fa');
|
||||
|
||||
translations = require('@assets/i18n/fa.json');
|
||||
break;
|
||||
|
|
@ -64,6 +69,7 @@ function loadTranslation(locale?: string): {[x: string]: string} {
|
|||
require('@formatjs/intl-numberformat/locale-data/fr');
|
||||
require('@formatjs/intl-datetimeformat/locale-data/fr');
|
||||
require('@formatjs/intl-listformat/locale-data/fr');
|
||||
require('@formatjs/intl-relativetimeformat/locale-data/fr');
|
||||
|
||||
translations = require('@assets/i18n/fr.json');
|
||||
break;
|
||||
|
|
@ -72,6 +78,7 @@ function loadTranslation(locale?: string): {[x: string]: string} {
|
|||
require('@formatjs/intl-numberformat/locale-data/hu');
|
||||
require('@formatjs/intl-datetimeformat/locale-data/hu');
|
||||
require('@formatjs/intl-listformat/locale-data/hu');
|
||||
require('@formatjs/intl-relativetimeformat/locale-data/hu');
|
||||
|
||||
translations = require('@assets/i18n/hu.json');
|
||||
break;
|
||||
|
|
@ -80,6 +87,7 @@ function loadTranslation(locale?: string): {[x: string]: string} {
|
|||
require('@formatjs/intl-numberformat/locale-data/it');
|
||||
require('@formatjs/intl-datetimeformat/locale-data/it');
|
||||
require('@formatjs/intl-listformat/locale-data/it');
|
||||
require('@formatjs/intl-relativetimeformat/locale-data/it');
|
||||
|
||||
translations = require('@assets/i18n/it.json');
|
||||
break;
|
||||
|
|
@ -88,6 +96,7 @@ function loadTranslation(locale?: string): {[x: string]: string} {
|
|||
require('@formatjs/intl-numberformat/locale-data/ja');
|
||||
require('@formatjs/intl-datetimeformat/locale-data/ja');
|
||||
require('@formatjs/intl-listformat/locale-data/ja');
|
||||
require('@formatjs/intl-relativetimeformat/locale-data/ja');
|
||||
|
||||
translations = require('@assets/i18n/ja.json');
|
||||
break;
|
||||
|
|
@ -96,6 +105,7 @@ function loadTranslation(locale?: string): {[x: string]: string} {
|
|||
require('@formatjs/intl-numberformat/locale-data/ko');
|
||||
require('@formatjs/intl-datetimeformat/locale-data/ko');
|
||||
require('@formatjs/intl-listformat/locale-data/ko');
|
||||
require('@formatjs/intl-relativetimeformat/locale-data/ko');
|
||||
|
||||
translations = require('@assets/i18n/ko.json');
|
||||
break;
|
||||
|
|
@ -104,6 +114,7 @@ function loadTranslation(locale?: string): {[x: string]: string} {
|
|||
require('@formatjs/intl-numberformat/locale-data/nl');
|
||||
require('@formatjs/intl-datetimeformat/locale-data/nl');
|
||||
require('@formatjs/intl-listformat/locale-data/nl');
|
||||
require('@formatjs/intl-relativetimeformat/locale-data/nl');
|
||||
|
||||
translations = require('@assets/i18n/nl.json');
|
||||
break;
|
||||
|
|
@ -112,6 +123,7 @@ function loadTranslation(locale?: string): {[x: string]: string} {
|
|||
require('@formatjs/intl-numberformat/locale-data/pl');
|
||||
require('@formatjs/intl-datetimeformat/locale-data/pl');
|
||||
require('@formatjs/intl-listformat/locale-data/pl');
|
||||
require('@formatjs/intl-relativetimeformat/locale-data/pl');
|
||||
|
||||
translations = require('@assets/i18n/pl.json');
|
||||
break;
|
||||
|
|
@ -120,6 +132,7 @@ function loadTranslation(locale?: string): {[x: string]: string} {
|
|||
require('@formatjs/intl-numberformat/locale-data/pt');
|
||||
require('@formatjs/intl-datetimeformat/locale-data/pt');
|
||||
require('@formatjs/intl-listformat/locale-data/pt');
|
||||
require('@formatjs/intl-relativetimeformat/locale-data/pt');
|
||||
|
||||
translations = require('@assets/i18n/pt-BR.json');
|
||||
break;
|
||||
|
|
@ -128,6 +141,7 @@ function loadTranslation(locale?: string): {[x: string]: string} {
|
|||
require('@formatjs/intl-numberformat/locale-data/ro');
|
||||
require('@formatjs/intl-datetimeformat/locale-data/ro');
|
||||
require('@formatjs/intl-listformat/locale-data/ro');
|
||||
require('@formatjs/intl-relativetimeformat/locale-data/ro');
|
||||
|
||||
translations = require('@assets/i18n/ro.json');
|
||||
break;
|
||||
|
|
@ -136,6 +150,7 @@ function loadTranslation(locale?: string): {[x: string]: string} {
|
|||
require('@formatjs/intl-numberformat/locale-data/ru');
|
||||
require('@formatjs/intl-datetimeformat/locale-data/ru');
|
||||
require('@formatjs/intl-listformat/locale-data/ru');
|
||||
require('@formatjs/intl-relativetimeformat/locale-data/ru');
|
||||
|
||||
translations = require('@assets/i18n/ru.json');
|
||||
break;
|
||||
|
|
@ -144,6 +159,7 @@ function loadTranslation(locale?: string): {[x: string]: string} {
|
|||
require('@formatjs/intl-numberformat/locale-data/sv');
|
||||
require('@formatjs/intl-datetimeformat/locale-data/sv');
|
||||
require('@formatjs/intl-listformat/locale-data/sv');
|
||||
require('@formatjs/intl-relativetimeformat/locale-data/sv');
|
||||
|
||||
translations = require('@assets/i18n/sv.json');
|
||||
break;
|
||||
|
|
@ -152,6 +168,7 @@ function loadTranslation(locale?: string): {[x: string]: string} {
|
|||
require('@formatjs/intl-numberformat/locale-data/tr');
|
||||
require('@formatjs/intl-datetimeformat/locale-data/tr');
|
||||
require('@formatjs/intl-listformat/locale-data/tr');
|
||||
require('@formatjs/intl-relativetimeformat/locale-data/tr');
|
||||
|
||||
translations = require('@assets/i18n/tr.json');
|
||||
break;
|
||||
|
|
@ -160,6 +177,7 @@ function loadTranslation(locale?: string): {[x: string]: string} {
|
|||
require('@formatjs/intl-numberformat/locale-data/uk');
|
||||
require('@formatjs/intl-datetimeformat/locale-data/uk');
|
||||
require('@formatjs/intl-listformat/locale-data/uk');
|
||||
require('@formatjs/intl-relativetimeformat/locale-data/uk');
|
||||
|
||||
translations = require('@assets/i18n/uk.json');
|
||||
break;
|
||||
|
|
@ -168,6 +186,7 @@ function loadTranslation(locale?: string): {[x: string]: string} {
|
|||
require('@formatjs/intl-numberformat/locale-data/vi');
|
||||
require('@formatjs/intl-datetimeformat/locale-data/vi');
|
||||
require('@formatjs/intl-listformat/locale-data/vi');
|
||||
require('@formatjs/intl-relativetimeformat/locale-data/vi');
|
||||
|
||||
translations = require('@assets/i18n/vi.json');
|
||||
break;
|
||||
|
|
@ -184,6 +203,7 @@ function loadTranslation(locale?: string): {[x: string]: string} {
|
|||
require('@formatjs/intl-numberformat/locale-data/en');
|
||||
require('@formatjs/intl-datetimeformat/locale-data/en');
|
||||
require('@formatjs/intl-listformat/locale-data/en');
|
||||
require('@formatjs/intl-relativetimeformat/locale-data/en');
|
||||
|
||||
translations = en;
|
||||
break;
|
||||
|
|
@ -201,6 +221,7 @@ function loadChinesePolyfills() {
|
|||
require('@formatjs/intl-numberformat/locale-data/zh');
|
||||
require('@formatjs/intl-datetimeformat/locale-data/zh');
|
||||
require('@formatjs/intl-listformat/locale-data/zh');
|
||||
require('@formatjs/intl-relativetimeformat/locale-data/zh');
|
||||
}
|
||||
|
||||
export function getLocaleFromLanguage(lang: string) {
|
||||
|
|
|
|||
|
|
@ -239,7 +239,7 @@ describe('ChecklistItem', () => {
|
|||
const {getByTestId, rerender, queryByTestId} = renderWithIntl(<ChecklistItem {...props}/>);
|
||||
let chip = getByTestId('base-chip-component');
|
||||
expect(chip).toBeVisible();
|
||||
expect(chip.props.label).toBe('Due Tomorrow');
|
||||
expect(chip.props.label).toBe('Due tomorrow');
|
||||
expect(chip.props.type).toBe('normal');
|
||||
expect(chip.props.boldText).toBe(false);
|
||||
expect(chip.props.prefix).toBeDefined();
|
||||
|
|
@ -263,7 +263,7 @@ describe('ChecklistItem', () => {
|
|||
rerender(<ChecklistItem {...props}/>);
|
||||
chip = getByTestId('base-chip-component');
|
||||
expect(chip).toBeVisible();
|
||||
expect(chip.props.label).toBe('Due 1 year ago');
|
||||
expect(chip.props.label).toBe('Due last year');
|
||||
expect(chip.props.type).toBe('danger');
|
||||
expect(chip.props.boldText).toBe(true);
|
||||
expect(chip.props.prefix).toBeDefined();
|
||||
|
|
|
|||
|
|
@ -367,19 +367,7 @@
|
|||
"find_channels.new_channel": "New Channel",
|
||||
"find_channels.open_dm": "Open a DM",
|
||||
"find_channels.title": "Find Channels",
|
||||
"friendly_date.days": "in {count} {count, plural, one {day} other {days}}",
|
||||
"friendly_date.daysAgo": "{count} {count, plural, one {day} other {days}} ago",
|
||||
"friendly_date.hours": "in {count} {count, plural, one {hour} other {hours}}",
|
||||
"friendly_date.hoursAgo": "{count} {count, plural, one {hour} other {hours}} ago",
|
||||
"friendly_date.mins": "in {count} {count, plural, one {min} other {mins}}",
|
||||
"friendly_date.minsAgo": "{count} {count, plural, one {min} other {mins}} ago",
|
||||
"friendly_date.months": "in {count} {count, plural, one {month} other {months}}",
|
||||
"friendly_date.monthsAgo": "{count} {count, plural, one {month} other {months}} ago",
|
||||
"friendly_date.now": "Now",
|
||||
"friendly_date.tomorrow": "Tomorrow",
|
||||
"friendly_date.years": "in {count} {count, plural, one {year} other {years}}",
|
||||
"friendly_date.yearsAgo": "{count} {count, plural, one {year} other {years}} ago",
|
||||
"friendly_date.yesterday": "Yesterday",
|
||||
"gallery.copy_link.failed": "Failed to copy link to clipboard",
|
||||
"gallery.downloading": "Downloading...",
|
||||
"gallery.footer.channel_name": "Shared in {channelName}",
|
||||
|
|
|
|||
1
index.ts
1
index.ts
|
|
@ -48,6 +48,7 @@ if (global.HermesInternal) {
|
|||
require('@formatjs/intl-datetimeformat/polyfill-force');
|
||||
require('@formatjs/intl-datetimeformat/add-all-tz');
|
||||
require('@formatjs/intl-listformat/polyfill-force');
|
||||
require('@formatjs/intl-relativetimeformat/polyfill-force');
|
||||
}
|
||||
|
||||
if (Platform.OS === 'android') {
|
||||
|
|
|
|||
12
package-lock.json
generated
12
package-lock.json
generated
|
|
@ -16,6 +16,7 @@
|
|||
"@formatjs/intl-locale": "4.2.11",
|
||||
"@formatjs/intl-numberformat": "8.15.4",
|
||||
"@formatjs/intl-pluralrules": "5.4.4",
|
||||
"@formatjs/intl-relativetimeformat": "11.4.11",
|
||||
"@gorhom/bottom-sheet": "5.1.2",
|
||||
"@mattermost/calls": "github:mattermost/calls-common#ab53c24053b89e4d3d853bbe1244892899517f45",
|
||||
"@mattermost/compass-icons": "0.1.48",
|
||||
|
|
@ -4219,6 +4220,17 @@
|
|||
"tslib": "^2.8.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@formatjs/intl-relativetimeformat": {
|
||||
"version": "11.4.11",
|
||||
"resolved": "https://registry.npmjs.org/@formatjs/intl-relativetimeformat/-/intl-relativetimeformat-11.4.11.tgz",
|
||||
"integrity": "sha512-EiknGq2z8ZcIDUhf3kkizrPmHHdD0lO6B3OXG6u0o0lAvusSc9gkr33F2S/vzOHM9iTh6oHmzTl21klGsLR9LA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@formatjs/ecma402-abstract": "2.3.4",
|
||||
"@formatjs/intl-localematcher": "0.6.1",
|
||||
"tslib": "^2.8.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@gorhom/bottom-sheet": {
|
||||
"version": "5.1.2",
|
||||
"resolved": "https://registry.npmjs.org/@gorhom/bottom-sheet/-/bottom-sheet-5.1.2.tgz",
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@
|
|||
"@formatjs/intl-locale": "4.2.11",
|
||||
"@formatjs/intl-numberformat": "8.15.4",
|
||||
"@formatjs/intl-pluralrules": "5.4.4",
|
||||
"@formatjs/intl-relativetimeformat": "11.4.11",
|
||||
"@gorhom/bottom-sheet": "5.1.2",
|
||||
"@mattermost/calls": "github:mattermost/calls-common#ab53c24053b89e4d3d853bbe1244892899517f45",
|
||||
"@mattermost/compass-icons": "0.1.48",
|
||||
|
|
|
|||
Loading…
Reference in a new issue