fix(ui): wrong relative time being rendered (#9098)

* fix(ui): wrong relative time being rendered

* unit tests added for timeUtils

* remove tailwind classes
This commit is contained in:
Chirag Madlani 2022-12-01 17:41:16 +05:30 committed by GitHub
parent 7d2eab332d
commit 173a88be7c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 58 additions and 135 deletions

View File

@ -37,6 +37,7 @@ import {
threadFilterList,
} from './ActivityFeedList.util';
import FeedListBody from './FeedListBody';
import FeedListSeparator from './FeedListSeparator';
const ActivityFeedList: FC<ActivityFeedListProp> = ({
className,
@ -251,6 +252,10 @@ const ActivityFeedList: FC<ActivityFeedListProp> = ({
{relativeDays.map((d, i) => {
return (
<div data-testid={`feed${i}`} key={i}>
<FeedListSeparator
className="relative m-y-xs"
relativeDay={d}
/>
<FeedListBody
deletePostHandler={deletePostHandler}
isEntityFeed={isEntityFeed}

View File

@ -0,0 +1,38 @@
/*
* Copyright 2021 Collate
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { getRelativeDateByTimeStamp } from './TimeUtils';
describe('TimeUtils tests', () => {
it("getRelativeDateByTimeStamp should return Today for currentDay's date", () => {
expect(getRelativeDateByTimeStamp(Date.now())).toBe('Today');
});
it("getRelativeDateByTimeStamp should return Yesterday for yesterday's date", () => {
expect(
getRelativeDateByTimeStamp(
new Date('2020/01/01').valueOf(),
new Date('2020/01/02').valueOf()
)
).toBe('Yesterday');
});
it('getRelativeDateByTimeStamp should return Last month for past months date', () => {
expect(
getRelativeDateByTimeStamp(
new Date('2020/01/01').valueOf(),
new Date('2020/02/01').valueOf()
)
).toBe('Last month');
});
});

View File

@ -11,147 +11,27 @@
* limitations under the License.
*/
import { isNil, toInteger, toNumber } from 'lodash';
import { capitalize, isNil, toInteger, toNumber } from 'lodash';
import { DateTime, Duration } from 'luxon';
const msPerSecond = 1000;
const msPerMinute = 60 * msPerSecond;
const msPerHour = msPerMinute * 60;
const msPerDay = msPerHour * 24;
const msPerMonth = msPerDay * 30;
const msPerYear = msPerDay * 365;
const formattingObj = {
sameDay: "'Today'",
lastDay: "'Yesterday'",
lastWeek: "DDD 'at' hh:mm a",
sameElse: "DDD 'at' hh:mm a",
};
const activityFeedTimeFormat = {
sameDay: "'Today at' hh:mm a",
lastDay: "'Yesterday at' hh:mm a",
lastWeek: "'Last' EEEE 'at' hh:mm a",
sameElse: "DDD 'at' hh:mm a",
};
/**
* If the difference between the two dates is less than -1, return 'lastWeek'. If the difference is
* less than 0, return 'lastDay'. If the difference is less than 1, return 'sameDay'. Otherwise, return
* 'sameElse'.
* @param {DateTime} myDateTime - The date you want to format.
* @param {DateTime} now - The current date and time.
* @returns A string
*/
const getCalendarFormat = (myDateTime: DateTime, now: DateTime): string => {
const diff = myDateTime.diff(now.startOf('day'), 'days').as('days');
if (diff < -7) return 'sameElse';
else if (diff < 0) return 'lastWeek';
else if (diff < 1) return 'lastDay';
return 'sameDay';
};
export const getRelativeTimeDifference = (
current: number,
previous: number
): string => {
const elapsed = current - previous;
if (elapsed <= msPerSecond) {
return 'now';
} else if (elapsed < msPerMinute / 5) {
return 'a few seconds ago';
} else if (elapsed < msPerMinute) {
const relativeTime = Math.round(elapsed / msPerSecond);
return `${relativeTime} second${relativeTime > 1 ? 's' : ''} ago`;
} else if (elapsed < msPerHour) {
const relativeTime = Math.round(elapsed / msPerMinute);
return `${relativeTime} minute${relativeTime > 1 ? 's' : ''} ago`;
} else if (elapsed < msPerDay) {
const relativeTime = Math.round(elapsed / msPerHour);
return `${relativeTime} hour${relativeTime > 1 ? 's' : ''} ago`;
} else if (elapsed < msPerMonth) {
const relativeTime = Math.round(elapsed / msPerDay);
return `${relativeTime} day${relativeTime > 1 ? 's' : ''} ago`;
} else if (elapsed < msPerYear) {
const relativeTime = Math.round(elapsed / msPerMonth);
return `${relativeTime} month${relativeTime > 1 ? 's' : ''} ago`;
} else {
const relativeTime = Math.round(elapsed / msPerYear);
return `${relativeTime} year${relativeTime > 1 ? 's' : ''} ago`;
}
};
export const getRelativeDayDifference = (
current: number,
previous: number
): string => {
const elapsed = current - previous;
if (elapsed < msPerDay / 6) {
return 'in last few hours';
} else if (elapsed < msPerDay) {
return 'today';
} else if (elapsed < msPerMonth) {
const relativeTime = Math.round(elapsed / msPerDay);
return `in last ${relativeTime} day${relativeTime > 1 ? 's' : ''}`;
} else if (elapsed < msPerYear) {
const relativeTime = Math.round(elapsed / msPerMonth);
return `${relativeTime} month${relativeTime > 1 ? 's' : ''} ago`;
} else {
const relativeTime = Math.round(elapsed / msPerYear);
return `${relativeTime} year${relativeTime > 1 ? 's' : ''} ago`;
}
};
export const getRelativeTime = (timestamp: number): string => {
return getRelativeTimeDifference(Date.now(), timestamp);
};
const getFormattedDateTime = (
dt1: DateTime,
dt2: DateTime,
formattingRulesObj: Record<string, string>
) => {
const format = getCalendarFormat(dt1, dt2) || 'sameElse';
return dt1.toFormat(formattingRulesObj[format]);
};
export const getRelativeDay = (timestamp: number): string => {
return getRelativeDayDifference(Date.now(), timestamp);
};
export const getRelativeDateByTimeStamp = (timeStamp: number): string => {
return getFormattedDateTime(
DateTime.fromMillis(timeStamp),
DateTime.now(),
formattingObj
);
};
export const getTimeByTimeStamp = (timeStamp: number): string =>
DateTime.fromMillis(timeStamp).toFormat('hh:mm a');
export const getDayTimeByTimeStamp = (timeStamp: number): string => {
return getFormattedDateTime(
DateTime.fromMillis(timeStamp),
DateTime.now(),
activityFeedTimeFormat
export const getRelativeDateByTimeStamp = (
timeStamp: number,
baseTimeStamp?: number
): string => {
return capitalize(
DateTime.fromMillis(timeStamp).toRelativeCalendar({
base: baseTimeStamp ? DateTime.fromMillis(baseTimeStamp) : DateTime.now(),
}) || ''
);
};
export const getDayTimeByTimeStamp = (timeStamp: number): string => {
return DateTime.fromMillis(timeStamp).toRelative() || '';
};
export const getUTCDateTime = (dateTime: string) => {
const dateObject = new Date(dateTime);
@ -197,8 +77,8 @@ export const getDateByTimeStamp = (
* It takes a timestamp and returns a relative date time string
* @param {number} timestamp - number - The timestamp to convert to a relative date time.
*/
export const getRelativeDateTimeByTimeStamp = (timestamp: number) =>
DateTime.fromMillis(timestamp as number).toRelative();
export const getRelativeDateTimeByTimeStamp = (timestamp: number): string =>
DateTime.fromMillis(timestamp as number).toRelative() || '';
export const getLocaleDateFromTimeStamp = (timeStamp: number): string => {
return DateTime.fromMillis(timeStamp).toISO({ includeOffset: false });