Skip to content

Commit

Permalink
Fix Relative Time expressions
Browse files Browse the repository at this point in the history
  • Loading branch information
willemarcel committed Jan 6, 2021
1 parent 7ae5c70 commit 01e14d4
Show file tree
Hide file tree
Showing 8 changed files with 222 additions and 11 deletions.
1 change: 0 additions & 1 deletion frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
"@formatjs/intl-locale": "^2.4.13",
"@formatjs/intl-pluralrules": "^4.0.3",
"@formatjs/intl-relativetimeformat": "^8.0.3",
"@formatjs/intl-utils": "^3.8.4",
"@formatjs/macro": "^0.2.8",
"@hotosm/id": "^2.19.5",
"@hotosm/iso-countries-languages": "^1.0.2",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { useSelector } from 'react-redux';
import { Link, useLocation, navigate } from '@reach/router';
import ReactPlaceholder from 'react-placeholder';
import 'react-placeholder/lib/reactPlaceholder.css';
import { selectUnit } from '@formatjs/intl-utils';
import { selectUnit } from '../../utils/selectUnit';
import { FormattedRelativeTime, FormattedMessage } from 'react-intl';

import messages from './messages';
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/components/user/content.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import React from 'react';
import { useSelector } from 'react-redux';
import { Link } from '@reach/router';
import { FormattedMessage, FormattedNumber, FormattedRelativeTime } from 'react-intl';
import { selectUnit } from '@formatjs/intl-utils';
import { selectUnit } from '../../utils/selectUnit';
import { useCopyClipboard } from '@lokibai/react-use-copy-clipboard';
import ReactPlaceholder from 'react-placeholder';
import { OSM_SERVER_URL } from '../../config';
Expand Down
3 changes: 2 additions & 1 deletion frontend/src/utils/formattedRelativeTime.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import React from 'react';
import { selectUnit } from '@formatjs/intl-utils';
import { FormattedRelativeTime } from 'react-intl';

import { selectUnit } from './selectUnit';

export const RelativeTimeWithUnit = ({ date }: Object) => {
const { value, unit } = selectUnit(new Date(date));

Expand Down
85 changes: 85 additions & 0 deletions frontend/src/utils/selectUnit.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
// this code is an adaptation of https://www.npmjs.com/package/@formatjs/intl-utils

var __assign =
(this && this.__assign) ||
function () {
__assign =
Object.assign ||
function (t) {
for (var s, i = 1, n = arguments.length; i < n; i++) {
s = arguments[i];
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
}
return t;
};
return __assign.apply(this, arguments);
};

const MS_PER_SECOND = 1e3;
const SECS_PER_MIN = 60;
const SECS_PER_HOUR = SECS_PER_MIN * 60;
const SECS_PER_DAY = SECS_PER_HOUR * 24;
const SECS_PER_WEEK = SECS_PER_DAY * 7;
const DEFAULT_THRESHOLDS = {
second: 45,
minute: 45,
hour: 23,
day: 7,
};

export function selectUnit(from, to, thresholds) {
if (to === void 0) {
to = Date.now();
}
if (thresholds === void 0) {
thresholds = {};
}
const resolvedThresholds = __assign(__assign({}, DEFAULT_THRESHOLDS), thresholds || {});
const secs = (+from - +to) / MS_PER_SECOND;
if (Math.abs(secs) < resolvedThresholds.second) {
return {
value: Math.round(secs),
unit: 'second',
};
}
const mins = secs / SECS_PER_MIN;
if (Math.abs(mins) < resolvedThresholds.minute) {
return {
value: Math.round(mins),
unit: 'minute',
};
}
const hours = secs / SECS_PER_HOUR;
if (Math.abs(hours) < resolvedThresholds.hour) {
return {
value: Math.round(hours),
unit: 'hour',
};
}
const days = secs / SECS_PER_DAY;
if (Math.abs(days) < resolvedThresholds.day) {
return {
value: Math.round(days),
unit: 'day',
};
}
const weeks = secs / SECS_PER_WEEK;
const years = weeks / 52;
if (Math.abs(years) >= 1) {
return {
value: Math.round(years),
unit: 'year',
};
}
const months = days / 30;
if (Math.round(Math.abs(weeks)) > 4) {
return {
value: Math.round(months),
unit: 'month',
};
}
return {
value: Math.round(weeks),
unit: 'week',
};
}
41 changes: 41 additions & 0 deletions frontend/src/utils/tests/formattedRelativeTime.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import React from 'react';
import { render, screen } from '@testing-library/react';
import '@testing-library/jest-dom';

import { RelativeTimeWithUnit } from '../formattedRelativeTime';
import { ReduxIntlProviders } from '../testWithIntl';

describe('RelativeTimeWithUnit renders', () => {
it('1 hour ago', () => {
render(
<ReduxIntlProviders>
<RelativeTimeWithUnit date={Date.now() - 1e3 * 60 * 60} />
</ReduxIntlProviders>,
);
expect(screen.getByText('1 hour ago')).toBeInTheDocument();
});
it('in 1 hour', () => {
render(
<ReduxIntlProviders>
<RelativeTimeWithUnit date={Date.now() + 1e3 * 60 * 60} />
</ReduxIntlProviders>,
);
expect(screen.getByText('in 1 hour')).toBeInTheDocument();
});
it('1 day ago', () => {
render(
<ReduxIntlProviders>
<RelativeTimeWithUnit date={Date.now() - 1e3 * 60 * 60 * 24} />
</ReduxIntlProviders>,
);
expect(screen.getByText('1 day ago')).toBeInTheDocument();
});
it('1 week ago', () => {
render(
<ReduxIntlProviders>
<RelativeTimeWithUnit date={Date.now() - 1e3 * 60 * 60 * 24 * 7} />
</ReduxIntlProviders>,
);
expect(screen.getByText('1 week ago')).toBeInTheDocument();
});
});
92 changes: 92 additions & 0 deletions frontend/src/utils/tests/selectUnit.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
import { selectUnit } from '../selectUnit';

describe('selectUnit returns', () => {
it('1 week interval', () => {
expect(selectUnit(new Date(2020, 12, 25), new Date(2021, 1, 1))).toEqual({
value: -1,
unit: 'week',
});
expect(selectUnit(new Date(2021, 1, 1), new Date(2021, 1, 8))).toEqual({
value: -1,
unit: 'week',
});
expect(selectUnit(new Date(2020, 12, 1), new Date(2020, 12, 10))).toEqual({
value: -1,
unit: 'week',
});
});
it('12 month interval', () => {
expect(selectUnit(new Date(2021, 12, 25), new Date(2022, 12, 23))).toEqual({
value: -12,
unit: 'month',
});
expect(selectUnit(new Date(2021, 12, 25), new Date(2022, 12, 12))).toEqual({
value: -12,
unit: 'month',
});
});
it('1 year interval', () => {
expect(selectUnit(new Date(2021, 12, 25), new Date(2022, 12, 26))).toEqual({
value: -1,
unit: 'year',
});
expect(selectUnit(new Date(2021, 1, 25), new Date(2022, 12, 26))).toEqual({
value: -2,
unit: 'year',
});
});
it('some months interval', () => {
expect(selectUnit(new Date(2020, 12, 25), new Date(2021, 1, 26))).toEqual({
value: -1,
unit: 'month',
});
expect(selectUnit(new Date(2020, 12, 25), new Date(2021, 2, 22))).toEqual({
value: -2,
unit: 'month',
});
});
it('some weeks interval', () => {
expect(selectUnit(new Date(2020, 12, 1), new Date(2020, 12, 29))).toEqual({
value: -4,
unit: 'week',
});
expect(selectUnit(new Date(2020, 2, 23), new Date(2020, 1, 25))).toEqual({
value: 4,
unit: 'week',
});
});
it('some days interval', () => {
expect(selectUnit(new Date(2020, 12, 1), new Date(2020, 12, 6))).toEqual({
value: -5,
unit: 'day',
});
expect(selectUnit(new Date(2021, 1, 1), new Date(2021, 1, 7))).toEqual({
value: -6,
unit: 'day',
});
});
it('some hours interval', () => {
expect(selectUnit(new Date(2020, 12, 1, 13, 47), new Date(2020, 12, 1, 14, 47))).toEqual({
value: -1,
unit: 'hour',
});
expect(selectUnit(new Date(2020, 12, 1, 1, 47), new Date(2020, 12, 1, 23, 47))).toEqual({
value: -22,
unit: 'hour',
});
expect(selectUnit(new Date(2020, 12, 1, 0, 48), new Date(2020, 12, 1, 23, 47))).toEqual({
value: -23,
unit: 'hour',
});
});
it('1 day interval', () => {
expect(selectUnit(new Date(2020, 12, 1, 0, 47), new Date(2020, 12, 1, 23, 47))).toEqual({
value: -1,
unit: 'day',
});
expect(selectUnit(new Date(2020, 12, 1, 0, 1), new Date(2020, 12, 1, 23, 59))).toEqual({
value: -1,
unit: 'day',
});
});
});
7 changes: 0 additions & 7 deletions frontend/yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1212,13 +1212,6 @@
resolved "https://registry.yarnpkg.com/@formatjs/intl-utils/-/intl-utils-2.2.1.tgz#0eeefe92d317acfcd179c14826e719b3b130d82a"
integrity sha512-WF3oU6l2WqJjN4OWvnjF9AHyQjHpjcfpyuckM7euFeX6ZGRPpPj+ZCqzf41g81MSksf9aZI4fFCZXWTBusgcWA==

"@formatjs/intl-utils@^3.8.4":
version "3.8.4"
resolved "https://registry.yarnpkg.com/@formatjs/intl-utils/-/intl-utils-3.8.4.tgz#291baac91001db428fc3275c515a3e40fbe95945"
integrity sha512-j5C6NyfKevIxsfLK8KwO1C0vvP7k1+h4A9cFpc+cr6mEwCc1sPkr17dzh0Ke6k9U5pQccAQoXdcNBl3IYa4+ZQ==
dependencies:
emojis-list "^3.0.0"

"@formatjs/[email protected]":
version "1.4.16"
resolved "https://registry.yarnpkg.com/@formatjs/intl/-/intl-1.4.16.tgz#07b98e021f7c589102f06a39fdd9ee3a26a38dca"
Expand Down

0 comments on commit 01e14d4

Please sign in to comment.