Skip to content

Commit

Permalink
Add limitTo24Hours option to timeAgo functions (#422)
Browse files Browse the repository at this point in the history
* Edit "time-ago" function

* Make limiting optional
  • Loading branch information
jeffdaley committed Nov 15, 2023
1 parent 21f177d commit 392c456
Show file tree
Hide file tree
Showing 4 changed files with 59 additions and 14 deletions.
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();
});
});

0 comments on commit 392c456

Please sign in to comment.