Skip to content

Commit

Permalink
Refactor timeSince formatting + usage
Browse files Browse the repository at this point in the history
  • Loading branch information
MattIPv4 committed Dec 1, 2023
1 parent a802994 commit 620104e
Show file tree
Hide file tree
Showing 3 changed files with 63 additions and 39 deletions.
Empty file removed src/util/check.ts
Empty file.
76 changes: 48 additions & 28 deletions src/util/format.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,39 +33,59 @@ export const plural = (number: number, singular: string, plural: string) =>
export const timeSince = (
start: Date,
end: Date,
minutes = false,
seconds = false,
{
accuracy = "hours",
floor = true,
}: {
accuracy?: "seconds" | "minutes" | "hours";
floor?: boolean;
} = {},
) => {
const diff = Math.abs(end.getTime() - start.getTime());
const secs = Math.floor(diff / 1000);
const mins = seconds
? Math.floor(diff / 1000 / 60)
: Math.round(diff / 1000 / 60);
const hours =
minutes || seconds
? Math.floor(diff / 1000 / 60 / 60)
: Math.round(diff / 1000 / 60 / 60);
const days = Math.floor(diff / 1000 / 60 / 60 / 24);
// Determine our accuracy
const minutes = accuracy === "minutes" || accuracy === "seconds";
const seconds = accuracy === "seconds";

// Get the difference in seconds
const diff = Math.abs((end.getTime() - start.getTime()) / 1000);

// Get the values for each unit
let secs = Math.round(diff);
let mins = Math[floor ? "floor" : "ceil"](secs / 60);
let hours = Math[floor ? "floor" : "ceil"](mins / 60);
const days = Math[floor ? "floor" : "ceil"](hours / 24);

// Truncate the values
secs %= 60;
mins %= 60;
hours %= 24;

// Decide which units to show
const parts = [
// Only show days if there are days
days > 0 && plural(days, "day", "days"),
// Only show hours if there are hours, seconds, or minutes
hours > 0 &&
(hours % 24 !== 0 ||
(minutes && mins % 60 !== 0) ||
(seconds && secs % 60 !== 0)) &&
plural(hours % 24, "hour", "hours"),
// Only show minutes if there are minutes or seconds
minutes &&
mins > 0 &&
(mins % 60 !== 0 || (seconds && secs % 60 !== 0)) &&
plural(mins % 60, "minute", "minutes"),
// Only show seconds if there are seconds
seconds && secs > 0 && plural(secs % 60, "second", "seconds"),
// We'll show the number of days if it's non-zero
...(days ? [plural(days, "day", "days")] : []),
// We'll show the number of hours if it's non-zero
// We'll also show the number of hours if there are days, and minutes are enabled, and they're non-zero
// We'll also show the number of hours if there are days, and seconds are enabled, and they're non-zero
...(hours || (days && minutes && mins) || (days && seconds && secs)
? [plural(hours, "hour", "hours")]
: []),
// We'll show the number of minutes if they're enabled and non-zero
// We'll also show the number of minutes if there are days or seconds, and if seconds are enabled, and they're non-zero
...((minutes && mins) || ((days || hours) && seconds && secs)
? [plural(mins, "minute", "minutes")]
: []),
// We'll also show the number of seconds if they're enabled and non-zero
...(seconds && secs ? [plural(secs, "second", "seconds")] : []),
].filter(Boolean);

// Format as a well-formed list
// If we have no parts, return less than
if (!parts.length) {
if (accuracy === "seconds") return "less than a second";
if (accuracy === "minutes") return "less than a minute";
return "less than an hour";
}

// Otherwise, return a well-formatted list
if (parts.length < 3) return parts.join(" and ");
return `${parts.slice(0, -1).join(", ")}, and ${parts.slice(-1)}`;
};
Expand Down
26 changes: 15 additions & 11 deletions src/util/messages.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,17 +9,16 @@ export const notStarted = (start: Date) => {
const now = getNow();
if (start < now) return null;

// Check if we're within the same day
const sameDay =
start.getUTCFullYear() === now.getUTCFullYear() &&
start.getUTCMonth() === now.getUTCMonth() &&
start.getUTCDate() === now.getUTCDate();
// Check if we're within the final day
const finalDay = start.getTime() - now.getTime() <= 1000 * 60 * 60 * 24;

// Get time until we start (show minutes if within the same day)
const timeRemaining = italic(timeSince(start, now, sameDay));
// Get time until we start (show minutes if within the final day)
const timeRemaining = italic(
timeSince(start, now, { accuracy: finalDay ? "minutes" : "hours" }),
);

// If we're within the same day, show the time
if (sameDay) {
if (finalDay) {
return (
`<:JingleJammy:1047503567981903894> Jingle Jam launches in ${timeRemaining}!` +
"\n:black_small_square: Get ready to raise money for some awesome causes and grab the collection when it goes live."
Expand All @@ -46,14 +45,19 @@ export const thanks = (end: Date, year: number) => {
);
}

// Get time until we end
const timeRemaining = italic(timeSince(now, end));
// Check if we're within the final hour
const finalHour = end.getTime() - now.getTime() <= 1000 * 60 * 60;

// Get time until we end (show minutes if within the final hour)
const timeRemaining = italic(
timeSince(now, end, { accuracy: finalHour ? "minutes" : "hours" }),
);

// Otherwise, show the time remaining
return (
`<:Jammy_LOVE:1047503543935967273> Thank you for supporting some wonderful causes!` +
`\n:mega: There ${
/^\D*1 /.test(timeRemaining) ? "is" : "are"
/^(\D*1|less) /.test(timeRemaining) ? "is" : "are"
} still ${timeRemaining} remaining to get involved and grab the collection at <https://jinglejam.co.uk/donate>`
);
};
Expand Down

0 comments on commit 620104e

Please sign in to comment.