Skip to content

Commit

Permalink
Fix countdown localization issue (#319)
Browse files Browse the repository at this point in the history
* Draft: try with and without locale.

* Adjusting implementation and testing it.

* Updating QA snapshot.

* Handle negative values as well.

* Update build snapshot.
  • Loading branch information
RobinTail authored Oct 18, 2024
1 parent a7f8c8d commit 498c83b
Show file tree
Hide file tree
Showing 3 changed files with 62 additions and 18 deletions.
26 changes: 17 additions & 9 deletions ui/__snapshots__/qa.spec.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ var closeIconHTML = '<span class="fa fa-close fa-sm"></span>';
var closeBtnHTML = \`<button id="\${closeBtnId}" type="button" class="close">\${closeIconHTML}</button>\`;
// helpers/countdown.ts
var formatDeadline = (time) => {
var formatDeadline = (time, locales = [LOCALE, void 0]) => {
let unit = "second";
let timeLeft = (time - Date.now()) / 1e3;
if (timeLeft >= 60) {
Expand All @@ -118,14 +118,22 @@ var formatDeadline = (time) => {
unit = "hour";
}
const isLastMinute = unit === "minute" && timeLeft < 2;
const formattedTimeLeft = new Intl.NumberFormat(LOCALE, {
style: "unit",
unitDisplay: "long",
minimumFractionDigits: isLastMinute ? 1 : 0,
maximumFractionDigits: isLastMinute ? 1 : 0,
unit
}).format(Math.max(0, timeLeft));
return \`in \${formattedTimeLeft}\`;
const nonNegTimeLeft = Math.max(0, timeLeft);
for (const locale of locales) {
try {
const formattedTimeLeft = new Intl.NumberFormat(locale, {
style: "unit",
unitDisplay: "long",
minimumFractionDigits: isLastMinute ? 1 : 0,
maximumFractionDigits: isLastMinute ? 1 : 0,
unit
}).format(nonNegTimeLeft);
return \`in \${formattedTimeLeft}\`;
} catch (error) {
console.warn(\`Failed to format time using \${locale} locale\`, error);
}
}
return \`in \${nonNegTimeLeft} \${unit}\${nonNegTimeLeft === 1 ? "" : "s"}\`;
};
var getCountdownDelay = (deadline) => deadline - Date.now() > 12e4 ? 6e4 : 1e3;
var setCountdown = (selector, deadline) => {
Expand Down
25 changes: 25 additions & 0 deletions ui/helpers/countdown.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,31 @@ describe("Countdown helpers", () => {
expect(formatDeadline(Date.now() + offset * 1000)).toMatchSnapshot();
},
);

test.each([
[10000, "10 seconds"],
[60000, "1 minute"],
[-10000, "0 seconds"],
])(`should handle invalid locales %#`, (offset, label) => {
const warnSpy = vi.spyOn(console, "warn").mockImplementation(() => {});
expect(
formatDeadline(Date.now() + offset, [
"invalid_locale_id",
"another_invalid_one",
]),
).toBe(`in ${label}`);
expect(warnSpy).toHaveBeenCalledTimes(2);
expect(warnSpy.mock.calls).toEqual([
[
"Failed to format time using invalid_locale_id locale",
expect.any(Error),
],
[
"Failed to format time using another_invalid_one locale",
expect.any(Error),
],
]);
});
});

describe("getCountdownDelay() helper", () => {
Expand Down
29 changes: 20 additions & 9 deletions ui/helpers/countdown.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
export const formatDeadline = (time: number): string => {
export const formatDeadline = (
time: number,
locales = [LOCALE, undefined],
): string => {
let unit: "second" | "minute" | "hour" = "second";
let timeLeft = (time - Date.now()) / 1000;
if (timeLeft >= 60) {
Expand All @@ -10,14 +13,22 @@ export const formatDeadline = (time: number): string => {
unit = "hour";
}
const isLastMinute = unit === "minute" && timeLeft < 2;
const formattedTimeLeft = new Intl.NumberFormat(LOCALE, {
style: "unit",
unitDisplay: "long",
minimumFractionDigits: isLastMinute ? 1 : 0,
maximumFractionDigits: isLastMinute ? 1 : 0,
unit,
}).format(Math.max(0, timeLeft));
return `in ${formattedTimeLeft}`;
const nonNegTimeLeft = Math.max(0, timeLeft);
for (const locale of locales) {
try {
const formattedTimeLeft = new Intl.NumberFormat(locale, {
style: "unit",
unitDisplay: "long",
minimumFractionDigits: isLastMinute ? 1 : 0,
maximumFractionDigits: isLastMinute ? 1 : 0,
unit,
}).format(nonNegTimeLeft);
return `in ${formattedTimeLeft}`;
} catch (error) {
console.warn(`Failed to format time using ${locale} locale`, error);
}
}
return `in ${nonNegTimeLeft} ${unit}${nonNegTimeLeft === 1 ? "" : "s"}`;
};

export const getCountdownDelay = (deadline: number): number =>
Expand Down

0 comments on commit 498c83b

Please sign in to comment.