{"version":3,"sources":["Themes/Default/Content/ts/UniversalBasket/universal-basket-timer.ts"],"names":[],"mappings":"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","file":"universal-basket-timer.js","sourcesContent":["import * as ko from \"knockout\";\r\nimport * as localisationHelper from 'localisationHelper';\r\nimport * as globalConfig from \"globalConfig\";\r\nimport * as amplify from \"amplify\";\r\nimport * as moment from \"moment\";\nimport * as $ from \"jquery\";\n\n// Helpers\r\nimport \"knockoutCustomBindings\";\n\r\n// Services\r\nimport { UniversalBasketService } from 'Content/ts/UniversalBasket/Services/universalBasketService';\r\n\r\nexport interface UniversalBasketTimerParams {\r\n Id: string,\r\n RefreshPageWhenExpiryModalDismissed: boolean,\r\n InHeader: boolean,\r\n SecondsUntilExpiry: KnockoutObservable;\r\n}\r\n\r\nexport default class UniversalBasketTimer {\r\n hasExpired: KnockoutObservable;\r\n\r\n /** Total number of seconds until basket expires. */\r\n secondsUntilExpiry: KnockoutObservable;\r\n\r\n /** Remaining time formatted for display. */\r\n formattedTimeRemaining: KnockoutObservable;\r\n\r\n /** Minutes component of time remaining (0-59). */\r\n minutesRemaining: KnockoutObservable;\r\n\r\n /** Seconds component of time remaining (0-59). */\r\n secondsRemaining: KnockoutObservable;\r\n\r\n /** Whether screen reader should announce the current time remaining (true at hard coded intervals). */\r\n screenReaderAnnounceTimeRemaining: KnockoutComputed;\r\n\r\n /** Screen reader friendly time remaining. */\r\n screenReaderFormattedTimeRemaining: KnockoutComputed;\r\n\r\n /** Populates the id attribute, used to differentiate between multiple timers on a page. */\r\n id: string;\r\n\r\n /** Whether the component is being shown in the page header. Used for styling differences. */\r\n inHeader: boolean;\r\n\r\n /** Basket expired modal */\r\n modalDismissed: KnockoutObservable;\r\n showModal: KnockoutComputed;\r\n refreshPageWhenExpiryModalDismissed: boolean;\r\n\r\n customMessages: {\r\n basketReservedText: string;\r\n basketTimerExpiredText: string;\r\n basketMinutesSecondsText: string;\r\n basketMinutesText: string;\r\n basketExpiredText: string;\r\n basketExpiredMessageText: string;\r\n }\r\n\r\n constructor(params: UniversalBasketTimerParams) {\r\n this.setupCustomMessages();\r\n\r\n if (params.SecondsUntilExpiry == null) {\r\n this.secondsUntilExpiry = ko.observable(null);\r\n\r\n /** Listen for events that should update the timer. */\r\n amplify.subscribe(globalConfig.AmplifyEvents.Names.CountBasketItems, function () {\r\n this.getBasketCountAndExpiry();\r\n }.bind(this));\r\n\r\n } else {\r\n this.secondsUntilExpiry = params.SecondsUntilExpiry;\r\n }\r\n\r\n this.formattedTimeRemaining = ko.observable(\"--:--\");\r\n this.minutesRemaining = ko.observable(0);\r\n this.secondsRemaining = ko.observable(0);\r\n this.hasExpired = ko.observable(false);\r\n this.modalDismissed = ko.observable(false);\r\n this.id = params.Id ?? \"basket-timer-\" + crypto.randomUUID();\r\n this.refreshPageWhenExpiryModalDismissed = params.RefreshPageWhenExpiryModalDismissed ?? false;\r\n this.inHeader = params.InHeader ?? false;\r\n this.setupComputeds();\r\n this.initialise();\r\n }\r\n\r\n private initialise(): void {\r\n /** If the value for the seconds remaining was not passed into the component we need to get it here. */\r\n if (this.secondsUntilExpiry() === null) {\r\n this.getBasketCountAndExpiry().finally(() => {\r\n this.initTimerUpdate();\r\n });\r\n } else {\r\n this.initTimerUpdate();\r\n }\r\n }\r\n\r\n private getBasketCountAndExpiry(): Promise {\r\n return UniversalBasketService.getBasketCountAndExpiryAsync().then((result) => {\r\n this.secondsUntilExpiry(result.SecondsUntilExpiry);\r\n });\r\n }\r\n\r\n private initTimerUpdate() {\r\n const interval = setInterval(() => {\r\n this.updateTimerText(interval);\r\n }, 1000);\r\n }\r\n\r\n private updateTimerText(interval: number): void {\r\n this.secondsUntilExpiry(this.secondsUntilExpiry() - 1);\r\n const now = moment();\r\n const basketExpiresAt = moment().add(this.secondsUntilExpiry(), 'seconds');\r\n const diff = basketExpiresAt.diff(now);\r\n\r\n if (diff <= 0) {\r\n clearInterval(interval);\r\n this.hasExpired(true);\r\n\r\n // Hack to prevent the backdrop from covering the dialog box.\r\n if (this.inHeader) {\r\n $('.modal-backdrop').appendTo('#basket-timer-modal');\r\n }\r\n\r\n } else {\r\n const diffMoment = moment.utc(diff);\r\n this.formattedTimeRemaining(diffMoment.format(\"mm:ss\"));\r\n this.minutesRemaining(diffMoment.minutes());\r\n this.secondsRemaining(diffMoment.seconds());\r\n }\r\n }\r\n\r\n private setupCustomMessages() {\r\n this.customMessages = {\r\n basketReservedText: localisationHelper.getString('BasketResources', 'BasketTimerReservedFor'),\r\n basketTimerExpiredText: localisationHelper.getString('BasketResources', 'BasketTimerExpired'),\r\n basketMinutesSecondsText: localisationHelper.getString('BasketResources', 'BasketTimerMinutesAndSeconds'),\r\n basketMinutesText: localisationHelper.getString('BasketResources', 'BasketTimerMinutes'),\r\n basketExpiredText: localisationHelper.getString('BasketResources', 'BasketExpired'),\r\n basketExpiredMessageText: localisationHelper.getString('BasketResources', 'BasketExpiredMessage'),\r\n }\r\n }\r\n\r\n private setupComputeds() {\r\n this.screenReaderAnnounceTimeRemaining = ko.pureComputed(() => {\r\n\r\n // Suppress announcements if not visible on page (for mobile vs full view).\r\n if (this.id && !$(\"#\" + this.id).is(\":visible\")) {\r\n return false;\r\n }\r\n\r\n if (this.minutesRemaining() === 0 && this.secondsRemaining() === 0) {\r\n return false;\r\n }\r\n\r\n let frequency;\r\n\r\n if (this.minutesRemaining() >= 5) {\r\n frequency = 60;\r\n } else if (this.minutesRemaining() >= 1) {\r\n frequency = 30;\r\n } else {\r\n frequency = 10;\r\n }\r\n\r\n return this.secondsRemaining() % frequency === 0 && !this.hasExpired();\r\n });\r\n\r\n this.screenReaderFormattedTimeRemaining = ko.pureComputed(() => {\r\n if (this.secondsRemaining() === 0) {\r\n return this.customMessages.basketMinutesText.replace(\"{0}\", this.minutesRemaining().toString());\r\n }\r\n return this.customMessages.basketMinutesSecondsText.replace(\"{0}\", this.minutesRemaining().toString()).replace(\"{1}\", this.secondsRemaining().toString());\r\n });\r\n\r\n this.showModal = ko.pureComputed(() => {\r\n return this.hasExpired() && !this.modalDismissed();\r\n });\r\n }\r\n \r\n private closeModal() {\r\n if (this.refreshPageWhenExpiryModalDismissed) {\r\n window.location.reload();\r\n return;\r\n }\r\n this.modalDismissed(true);\r\n amplify.publish(globalConfig.AmplifyEvents.Names.CountBasketItems);\r\n }\r\n}\r\n\r\nconst componentName = \"universal-basket-timer\";\r\nko.components.unregister(componentName);\r\nko.components.register(componentName, {\r\n viewModel: UniversalBasketTimer,\r\n template: { require: `text!/Themes/Default/Content/ts/UniversalBasket/${componentName}.html` }\r\n});\r\n"]}