Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add limitTo24Hours option to timeAgo functions #422

Merged
merged 2 commits into from
Nov 15, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 7 additions & 4 deletions web/app/helpers/time-ago.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,17 @@ import timeAgo from "hermes/utils/time-ago";
export interface TimeAgoHelperSignature {
Args: {
Positional: [time: number];
Named: {
limitTo24Hours?: boolean;
};
};
Return: string;
Return: string | null;
}

const timeAgoHelper = helper<TimeAgoHelperSignature>(
([secondsAgo]: [number]) => {
return `${timeAgo(secondsAgo)}`;
}
([time], { limitTo24Hours }) => {
return timeAgo(time, { limitTo24Hours });
},
);

export default timeAgoHelper;
Expand Down
34 changes: 28 additions & 6 deletions web/app/utils/time-ago.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,16 @@
import parseDate from "./parse-date";
/**
* A simplified "time ago" calculation, based on 28-day months.
* Intended to give a rough estimate of how long ago something happened.
* Used by the `time-ago` helper to convert numeric timestamps to strings.
*
* TODO: Replace with something more precise.
* Returns a "time ago" string from a seconds-based timestamp.
* If set, the `limitTo24Hours` option will use the short `parseDate`
* formatting. e.g., "22 Dec. 1976," for values older than a day.
* Used throughout the app to format document metadata.
*/
export default function timeAgo(timeInSeconds: number) {
export default function timeAgo(
timeInSeconds: number,
options?: {
limitTo24Hours?: boolean;
},
) {
const now = Date.now();
const before = new Date(timeInSeconds * 1000).getTime();
const elapsed = now - before;
Expand All @@ -14,53 +19,70 @@ export default function timeAgo(timeInSeconds: number) {
if (elapsedSeconds < 2) {
return "1 second ago";
}

if (elapsedSeconds < 60) {
return `${Math.floor(elapsedSeconds)} seconds ago`;
}

const elapsedMinutes = elapsedSeconds / 60;

if (elapsedMinutes < 2) {
return "1 minute ago";
}

if (elapsedMinutes < 60) {
return `${Math.floor(elapsedMinutes)} minutes ago`;
}

const elapsedHours = elapsedMinutes / 60;

if (elapsedHours < 2) {
return "1 hour ago";
}

if (elapsedHours < 24) {
return `${Math.floor(elapsedHours)} hours ago`;
}

if (options?.limitTo24Hours) {
return parseDate(timeInSeconds * 1000);
}

const elapsedDays = elapsedHours / 24;

if (elapsedDays < 2) {
return "1 day ago";
}

if (elapsedDays < 30) {
return `${Math.floor(elapsedDays)} days ago`;
}

const elapsedWeeks = elapsedDays / 7;

if (elapsedWeeks < 2) {
return "1 week ago";
}

if (elapsedWeeks < 4) {
return `${Math.floor(elapsedWeeks)} weeks ago`;
}

const elapsedMonths = elapsedWeeks / 4;

if (elapsedMonths < 2) {
return "1 month ago";
}

if (elapsedMonths < 12) {
return `${Math.floor(elapsedMonths)} months ago`;
}

const elapsedYears = elapsedMonths / 12;

if (elapsedYears < 2) {
return "1 year ago";
}

return `${Math.floor(elapsedYears)} years ago`;
}
16 changes: 12 additions & 4 deletions web/tests/integration/helpers/time-ago-test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,17 +28,25 @@ module("Integration | Helper | time-ago", function (hooks) {
<div class="one">
{{time-ago this.fiveSecondsAgo}}
</div>
<div class="two">
<div class="two-a">
{{time-ago this.twoYearsAgo}}
</div>
<div class="three">
<div class="two-b">
{{time-ago this.twoYearsAgo limitTo24Hours=true}}
</div>
<div class="three-a">
{{time-ago this.sevenMonthsAgo}}
</div>
<div class="three-b">
{{time-ago this.sevenMonthsAgo limitTo24Hours=true}}
</div>
`);

assert.dom(".one").hasText("5 seconds ago");
assert.dom(".two").hasText("2 years ago");
assert.dom(".three").hasText("7 months ago");
assert.dom(".two-a").hasText("2 years ago");
assert.dom(".two-b").hasText("1 Jan. 1998");
assert.dom(".three-a").hasText("7 months ago");
assert.dom(".three-b").hasText("5 Jun. 1999");

MockDate.reset();
});
Expand Down
12 changes: 12 additions & 0 deletions web/tests/unit/utils/time-ago-test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,21 @@ module("Unit | Utility | time-ago", function () {
assert.equal("1 minute ago", timeAgo(now - 60));
assert.equal("5 minutes ago", timeAgo(now - 300));
assert.equal("6 hours ago", timeAgo(now - 21600));

assert.equal("2 months ago", timeAgo(now - 5184000));

assert.equal(
"2 Nov. 1999",
timeAgo(now - 5184000, { limitTo24Hours: true }),
);

assert.equal("2 years ago", timeAgo(now - 63072000));

assert.equal(
"1 Jan. 1998",
timeAgo(now - 63072000, { limitTo24Hours: true }),
);

MockDate.reset();
});
});