Skip to content

Commit

Permalink
Reimplement time rendering logic and add stories
Browse files Browse the repository at this point in the history
  • Loading branch information
ghengeveld committed Dec 12, 2024
1 parent d5bdc51 commit 6c9d375
Show file tree
Hide file tree
Showing 2 changed files with 73 additions and 27 deletions.
50 changes: 50 additions & 0 deletions code/addons/test/src/components/RelativeTime.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import type { Meta, StoryObj } from '@storybook/react';

import { RelativeTime } from './RelativeTime';

const meta = {
component: RelativeTime,
args: {
testCount: 42,
},
} satisfies Meta<typeof RelativeTime>;

export default meta;

type Story = StoryObj<typeof meta>;

export const JustNow: Story = {
args: {
timestamp: new Date(),
},
};

export const SecondsAgo: Story = {
args: {
timestamp: new Date(Date.now() - 1000 * 15),
},
};

export const MinutesAgo: Story = {
args: {
timestamp: new Date(Date.now() - 1000 * 60 * 2),
},
};

export const HoursAgo: Story = {
args: {
timestamp: new Date(Date.now() - 1000 * 60 * 60 * 3),
},
};

export const Yesterday: Story = {
args: {
timestamp: new Date(Date.now() - 1000 * 60 * 60 * 24),
},
};

export const DaysAgo: Story = {
args: {
timestamp: new Date(Date.now() - 1000 * 60 * 60 * 24 * 3),
},
};
50 changes: 23 additions & 27 deletions code/addons/test/src/components/RelativeTime.tsx
Original file line number Diff line number Diff line change
@@ -1,38 +1,34 @@
import { useEffect, useState } from 'react';
import { useCallback, useEffect, useState } from 'react';

export function getRelativeTimeString(date: Date): string {
const delta = Math.round((date.getTime() - Date.now()) / 1000);
const cutoffs = [60, 3600, 86400, 86400 * 7, 86400 * 30, 86400 * 365, Infinity];
const units: Intl.RelativeTimeFormatUnit[] = [
'second',
'minute',
'hour',
'day',
'week',
'month',
'year',
];

const unitIndex = cutoffs.findIndex((cutoff) => cutoff > Math.abs(delta));
const divisor = unitIndex ? cutoffs[unitIndex - 1] : 1;
const rtf = new Intl.RelativeTimeFormat('en', { numeric: 'auto' });
return rtf.format(Math.floor(delta / divisor), units[unitIndex]);
const delta = Math.round((Date.now() - date.getTime()) / 1000);
if (delta < 60) {
return 'just now';
}
if (delta < 60 * 60) {
const minutes = Math.floor(delta / 60);
return minutes === 1 ? 'a minute ago' : `${minutes} minutes ago`;
}
if (delta < 60 * 60 * 24) {
const hours = Math.floor(delta / 60 / 60);
return hours === 1 ? 'an hour ago' : `${hours} hours ago`;
}
const days = Math.floor(delta / 60 / 60 / 24);
return days === 1 ? 'yesterday' : `${days} days ago`;
}

export const RelativeTime = ({ timestamp, testCount }: { timestamp: Date; testCount: number }) => {
const [relativeTimeString, setRelativeTimeString] = useState(null);
const updateRelativeTimeString = useCallback(
() => timestamp && setRelativeTimeString(getRelativeTimeString(timestamp)),
[timestamp]
);

useEffect(() => {
if (timestamp) {
setRelativeTimeString(getRelativeTimeString(timestamp).replace(/^now$/, 'just now'));

const interval = setInterval(() => {
setRelativeTimeString(getRelativeTimeString(timestamp).replace(/^now$/, 'just now'));
}, 10000);

return () => clearInterval(interval);
}
}, [timestamp]);
updateRelativeTimeString();
const interval = setInterval(updateRelativeTimeString, 10000);
return () => clearInterval(interval);
}, [updateRelativeTimeString]);

return (
relativeTimeString &&
Expand Down

0 comments on commit 6c9d375

Please sign in to comment.