diff options
| author | Oskar Nyberg <oskar@mullvad.net> | 2023-06-13 18:37:53 +0200 |
|---|---|---|
| committer | Oskar Nyberg <oskar@mullvad.net> | 2023-06-28 09:13:18 +0200 |
| commit | ee8c6577f91ddf60ffe944624091ceaa6a81ca34 (patch) | |
| tree | 524c2c4b1af129851d832f1c992f076e0ab1aa2d /gui/src/shared | |
| parent | 0f2e3c95e88f5eab0fe30ca842b2bc4b12a179bb (diff) | |
| download | mullvadvpn-ee8c6577f91ddf60ffe944624091ceaa6a81ca34.tar.xz mullvadvpn-ee8c6577f91ddf60ffe944624091ceaa6a81ca34.zip | |
Refactor time left calculations
Diffstat (limited to 'gui/src/shared')
| -rw-r--r-- | gui/src/shared/account-expiry.ts | 17 | ||||
| -rw-r--r-- | gui/src/shared/date-helper.ts | 86 | ||||
| -rw-r--r-- | gui/src/shared/notifications/close-to-account-expiry.ts | 10 |
3 files changed, 49 insertions, 64 deletions
diff --git a/gui/src/shared/account-expiry.ts b/gui/src/shared/account-expiry.ts index 85d0d78315..1b40848220 100644 --- a/gui/src/shared/account-expiry.ts +++ b/gui/src/shared/account-expiry.ts @@ -1,5 +1,10 @@ -import { dateByAddingComponent, DateComponent, DateType, formatTimeLeft } from './date-helper'; -import { capitalize } from './string-helpers'; +import { + dateByAddingComponent, + DateComponent, + DateType, + FormatDateOptions, + formatRelativeDate, +} from './date-helper'; export function hasExpired(expiry: DateType): boolean { return new Date(expiry).getTime() < Date.now(); @@ -18,10 +23,6 @@ export function formatDate(date: DateType, locale: string): string { ); } -export function formatRemainingTime( - expiry: DateType, - shouldCapitalizeFirstLetter?: boolean, -): string { - const remaining = formatTimeLeft(new Date(), expiry); - return shouldCapitalizeFirstLetter ? capitalize(remaining) : remaining; +export function formatRemainingTime(expiry: DateType, options?: FormatDateOptions): string { + return formatRelativeDate(new Date(), expiry, options); } diff --git a/gui/src/shared/date-helper.ts b/gui/src/shared/date-helper.ts index 017b2048f5..be83473cfa 100644 --- a/gui/src/shared/date-helper.ts +++ b/gui/src/shared/date-helper.ts @@ -1,6 +1,7 @@ import { sprintf } from 'sprintf-js'; import { messages } from './gettext'; +import { capitalize } from './string-helpers'; export type DateType = Date | string | number; @@ -72,74 +73,53 @@ export class DateDiff { } } +export interface FormatDateOptions { + suffix?: boolean; + displayMonths?: boolean; + capitalize?: boolean; +} + +// If withSuffix is true then "left" will be added at the end of the remaining time. +// If noMonths is true then the following applies: +// If a user has more than 2 years (730 days) left of time it should be displayed in whole years +// rounded down If a user has less than 2 years left (e.g. 729 days) then this should be displayed +// in days. export function formatRelativeDate( fromDate: DateType, toDate: DateType, - withSuffix = false, + options?: FormatDateOptions, ): string { const diff = new DateDiff(fromDate, toDate); const years = Math.abs(diff.years); const months = Math.abs(diff.months); const days = Math.abs(diff.days); - const hours = Math.abs(diff.hours); - const minutes = Math.abs(diff.minutes); - if (!withSuffix) { - if (years > 0) { - return sprintf(messages.ngettext('1 year', '%d years', years), years); - } else if (months >= 3) { - return sprintf(messages.ngettext('1 month', '%d months', months), months); + if (isNaN(years) || isNaN(months) || isNaN(days)) { + return ''; + } + + let result = ''; + if (!options?.suffix) { + if (options?.displayMonths ? years > 0 : days >= 730) { + result = sprintf(messages.ngettext('1 year', '%d years', years), years); + } else if (options?.displayMonths && months >= 3) { + result = sprintf(messages.ngettext('1 month', '%d months', months), months); } else if (days > 0) { - return sprintf(messages.ngettext('1 day', '%d days', days), days); + result = sprintf(messages.ngettext('1 day', '%d days', days), days); } else { - return messages.gettext('less than a day'); + result = messages.gettext('less than a day'); } } else if (diff.milliseconds > 0) { - if (years > 0) { - return sprintf(messages.ngettext('1 year left', '%d years left', years), years); - } else if (months >= 3) { - return sprintf(messages.ngettext('1 month left', '%d months left', months), months); + if (options?.displayMonths ? years > 0 : days >= 730) { + result = sprintf(messages.ngettext('1 year left', '%d years left', years), years); + } else if (options?.displayMonths && months >= 3) { + result = sprintf(messages.ngettext('1 month left', '%d months left', months), months); } else if (days > 0) { - return sprintf(messages.ngettext('1 day left', '%d days left', days), days); + result = sprintf(messages.ngettext('1 day left', '%d days left', days), days); } else { - return messages.gettext('less than a day left'); - } - } else { - if (years > 0) { - return sprintf(messages.ngettext('a year ago', '%d years ago', years), years); - } else if (months > 0) { - return sprintf(messages.ngettext('a month ago', '%d months ago', months), months); - } else if (days > 0) { - return sprintf(messages.ngettext('a day ago', '%d days ago', days), days); - } else if (hours > 0) { - return sprintf(messages.ngettext('an hour ago', '%d hours ago', hours), hours); - } else if (minutes > 0) { - return sprintf(messages.ngettext('a minute ago', '%d minutes ago', minutes), minutes); - } else { - return messages.gettext('less than a minute ago'); + result = messages.gettext('less than a day left'); } } -} -/** - * If a user has more than 2 years (730 days) left of time it should be displayed in whole years rounded down - * If a user has less than 2 years left (e.g. 729 days) then this should be displayed in days. - * - * @param fromDate - * @param toDate - */ -export const formatTimeLeft = (fromDate: DateType, toDate: DateType): string => { - const diff = new DateDiff(fromDate, toDate); - const years = Math.abs(diff.years); - const days = Math.abs(diff.days); - - if (days < 1) { - return messages.gettext('less than a day left'); - } - - if (days < 730) { - return sprintf(messages.ngettext('1 day left', '%d days left', days), days); - } - - return sprintf(messages.ngettext('1 year left', '%d years left', years), years); -}; + return options?.capitalize ? capitalize(result) : result; +} diff --git a/gui/src/shared/notifications/close-to-account-expiry.ts b/gui/src/shared/notifications/close-to-account-expiry.ts index a3f5e749ad..60feb7ec4d 100644 --- a/gui/src/shared/notifications/close-to-account-expiry.ts +++ b/gui/src/shared/notifications/close-to-account-expiry.ts @@ -3,7 +3,6 @@ import { sprintf } from 'sprintf-js'; import { links } from '../../config.json'; import { messages } from '../../shared/gettext'; import { closeToExpiry, formatRemainingTime } from '../account-expiry'; -import { formatRelativeDate } from '../date-helper'; import { InAppNotification, InAppNotificationProvider, @@ -34,7 +33,7 @@ export class CloseToAccountExpiryNotificationProvider 'Account credit expires in %(duration)s. Buy more credit.', ), { - duration: formatRelativeDate(new Date(), this.context.accountExpiry), + duration: formatRemainingTime(this.context.accountExpiry), }, ); @@ -54,7 +53,12 @@ export class CloseToAccountExpiryNotificationProvider public getInAppNotification(): InAppNotification { const subtitle = sprintf( messages.pgettext('in-app-notifications', '%(duration)s. Buy more credit.'), - { duration: formatRemainingTime(this.context.accountExpiry, true) }, + { + duration: formatRemainingTime(this.context.accountExpiry, { + capitalize: true, + suffix: true, + }), + }, ); return { |
