diff options
Diffstat (limited to 'node_modules/@jet-app/app-store/tmp/src/common/app-promotions/contingent-offer.js')
| -rw-r--r-- | node_modules/@jet-app/app-store/tmp/src/common/app-promotions/contingent-offer.js | 189 |
1 files changed, 189 insertions, 0 deletions
diff --git a/node_modules/@jet-app/app-store/tmp/src/common/app-promotions/contingent-offer.js b/node_modules/@jet-app/app-store/tmp/src/common/app-promotions/contingent-offer.js new file mode 100644 index 0000000..8cc3cd7 --- /dev/null +++ b/node_modules/@jet-app/app-store/tmp/src/common/app-promotions/contingent-offer.js @@ -0,0 +1,189 @@ +import * as models from "../../api/models"; +import * as serverData from "../../foundation/json-parsing/server-data"; +import * as mediaAttributes from "../../foundation/media/attributes"; +import * as mediaRelationship from "../../foundation/media/relationships"; +import * as appPromotionCommon from "./app-promotions-common"; +import * as offerFormatting from "../offers/offer-formatting"; +import * as offers from "../offers/offers"; +import * as color from "../../foundation/util/color-util"; +import { isNothing, isSome } from "@jet/environment/types/optional"; +import { contentAttributeAsDictionary } from "../content/attributes"; +import * as content from "../content/content"; +/** + * Creates a contingent offer object. + * @param data The data blob + * @param parentAppData The related parent app of this app event. If not provided will be derived from `data`. + * @param offerEnvironment The preferred environment for the offer + * @param offerStyle The preferred style of the offer + * @param baseMetricsOptions The base metrics options + * @param allowEndedEvents Whether events in the past are allowed + * @param includeLockupClickAction Whether to include the click action for the lockup + * @param isArcadePage Whether or not this is presented on the Arcade page + * @returns an ContingentOffer or null + */ +export function contingentOfferFromData(objectGraph, data, parentAppData, offerEnvironment, offerStyle, baseMetricsOptions, includeLockupClickAction, isArcadePage) { + var _a, _b, _c; + if (data.type !== "contingent-items") { + return null; + } + // Artwork + const moduleArtwork = appPromotionCommon.artworkFromPlatformData(objectGraph, data, "lockupArtwork"); + if (serverData.isNull(moduleArtwork)) { + return null; + } + const isArtworkDark = color.isDarkColor(moduleArtwork.backgroundColor); + const mediaOverlayStyle = isArtworkDark ? "dark" : "light"; + // Labels + const badge = mediaAttributes.attributeAsString(data, "badge"); + const subtitle = mediaAttributes.attributeAsString(data, "subtitle"); + const label = mediaAttributes.attributeAsString(data, "label"); + const additionalInfoLabel = objectGraph.loc.string("ContingentOffer.AdditionalInfoButton.Title"); + if (isNothing(badge) || isNothing(label)) { + return null; + } + // The discounted offer + const branch = mediaRelationship.relationshipData(objectGraph, data, "branch"); + if (isNothing(branch) || serverData.isNullOrEmpty(serverData.asDictionary(branch, "meta.contingentItemOffer"))) { + return null; + } + const formattedText = formattedTextFromData(objectGraph, data); + if (isNothing(formattedText) || isNothing(formattedText === null || formattedText === void 0 ? void 0 : formattedText.title)) { + return null; + } + // The Apps + const resolvedBranchAppData = mediaRelationship.relationshipData(objectGraph, data, "branch-app"); + const supportsStreamlinedBuy = mediaAttributes.attributeAsBooleanOrFalse(resolvedBranchAppData, "supportsStreamlinedBuy"); + const offerLockup = appPromotionCommon.lockupFromData(objectGraph, data, resolvedBranchAppData, "", offerEnvironment, offerStyle, false, baseMetricsOptions, includeLockupClickAction, null, isArcadePage, true); + if (isNothing(offerLockup)) { + return null; + } + // Trunk Lockup. The app you need to be subscribed to in order to get the discounted offer + const resolvedTrunkAppData = mediaRelationship.relationshipData(objectGraph, data, "trunk-app"); + let trunkAppIcon; + if (isSome(resolvedTrunkAppData) && isSome(subtitle) && (subtitle === null || subtitle === void 0 ? void 0 : subtitle.length) > 0) { + trunkAppIcon = + (_a = appPromotionCommon.artworkFromPlatformData(objectGraph, resolvedTrunkAppData, "artwork")) !== null && _a !== void 0 ? _a : appPromotionCommon.artworkFromData(objectGraph, resolvedTrunkAppData, "artwork"); + } + // When displaying a first party offer the trunk artwork is in a different location + if (isSome(subtitle) && (subtitle === null || subtitle === void 0 ? void 0 : subtitle.length) > 0) { + trunkAppIcon = (_b = firstPartyTrunkLockupFromData(objectGraph, data)) !== null && _b !== void 0 ? _b : trunkAppIcon; + } + // Offer Strings + const additionalInfo = formattedAdditionalInfoFromData(objectGraph, data, branch); + const contingentOffer = new models.ContingentOffer(moduleArtwork, mediaOverlayStyle, supportsStreamlinedBuy, additionalInfoLabel, formattedText.title, subtitle !== null && subtitle !== void 0 ? subtitle : undefined, (_c = formattedText.description) !== null && _c !== void 0 ? _c : undefined, label, badge, additionalInfo, trunkAppIcon !== null && trunkAppIcon !== void 0 ? trunkAppIcon : undefined, offerLockup); + /// The raw title is used for metrics purposes + contingentOffer.title = formattedText.rawTitle; + // Detail page click action + if (serverData.isDefinedNonNull(resolvedBranchAppData)) { + contingentOffer.clickAction = appPromotionCommon.detailPageClickActionFromData(objectGraph, data, resolvedBranchAppData, contingentOffer, baseMetricsOptions, includeLockupClickAction); + } + return contingentOffer; +} +/** + * Creates the Title and description of the contingent offer out of a templated string + * @param data A data blob for the contingent-item + * @returns Creates a formatted string of the tile including the subscription price and period + */ +export function formattedTextFromData(objectGraph, data) { + var _a, _b, _c; + const branch = mediaRelationship.relationshipData(objectGraph, data, "branch"); + if (isNothing(branch)) { + return undefined; + } + const regularOffer = offers.offerDataFromData(objectGraph, branch); + const discountedOffer = serverData.asDictionary(branch, "meta.contingentItemOffer"); + if (serverData.isNullOrEmpty(regularOffer) || serverData.isNullOrEmpty(discountedOffer)) { + return undefined; + } + // Price Strings + // Adding \u{2060} (Word Joiner) prevents the string from breaking on the slash character + const regularPrice = (_a = formattedPrice(objectGraph, serverData.asString(regularOffer, "recurringSubscriptionPeriod"), serverData.asNumber(regularOffer, "numOfPeriods"), serverData.asString(regularOffer, "priceFormatted"))) === null || _a === void 0 ? void 0 : _a.replace("/", "/\u{2060}"); + const discountedPrice = (_b = formattedPrice(objectGraph, serverData.asString(discountedOffer, "recurringSubscriptionPeriod"), serverData.asNumber(discountedOffer, "numOfPeriods"), serverData.asString(discountedOffer, "priceFormatted"))) === null || _b === void 0 ? void 0 : _b.replace("/", "/\u{2060}"); + if (serverData.isNullOrEmpty(regularPrice) || serverData.isNullOrEmpty(discountedPrice)) { + return null; + } + const title = mediaAttributes.attributeAsString(data, "name"); + const titleKeys = { + "@@discountedPrice@@/@@recurringSubscriptionPeriod@@": discountedPrice, + "@@regularPrice@@/@@recurringSubscriptionPeriod@@": regularPrice, + "@@discountedPricePerRecurringSubscriptionPeriod@@": discountedPrice, + "@@regularPricePerRecurringSubscriptionPeriod@@": regularPrice, + }; + let titleTemplate = title !== null && title !== void 0 ? title : ""; + Object.keys(titleKeys).forEach((element) => { + titleTemplate = titleTemplate.replace(element, titleKeys[element]); + }); + const htmlRegex = /<(?:"[^"]*"['"]*|'[^']*'['"]*|[^'">])+>/g; + const rawTitle = titleTemplate.replace(htmlRegex, ""); + const formattedTitle = new models.Paragraph(titleTemplate, "text/x-apple-as3-nqml", "appPromotionTitle"); + const developerDetailText = (_c = mediaAttributes.attributeAsString(data, "description.standard")) !== null && _c !== void 0 ? _c : ""; + const detailTemplate = objectGraph.loc.string("ContingentOffer.Description.Format"); + const descriptionKeys = { + "@@BranchName@@": mediaAttributes.attributeAsString(branch, "name"), + "@@RegularPrice@@": regularPrice, + "@@DiscountedPrice@@": discountedPrice, + }; + let description = detailTemplate; + Object.keys(descriptionKeys).forEach((element) => { + description = description.replace(element, descriptionKeys[element]); + }); + const formattedDescription = [description, developerDetailText].join(" "); + return { + title: formattedTitle, + rawTitle, + description: formattedDescription, + }; +} +/** + * Creates a readable subscription price + * @param recurringSubscriptionPeriod The subscription recurrence in the server format. (eg P1M) + * @param price A price string in a readable format like $3.99. + * @returns A formatted string eg $3.99/month + */ +function formattedPrice(objectGraph, recurringSubscriptionPeriod, numberOfPeriods, price) { + const subscriptionRecurrence = offerFormatting.subscriptionRecurrenceForServerRecurrence(objectGraph, recurringSubscriptionPeriod, numberOfPeriods); + if (isNothing(subscriptionRecurrence) || isNothing(price)) { + return undefined; + } + return offerFormatting.priceDurationString(objectGraph, subscriptionRecurrence.type, subscriptionRecurrence.periodDuration, price); +} +/** + * Creates the additional info text of the contingent offer out of a templated string + * @param data A data blob + * @param branch A data blob containing the offer also known as the branch + * @param trunk A data blob containing the required subscription app also known as the trunk + * @returns Creates a formatted paragraph containing the contents of the additional info page. + */ +function formattedAdditionalInfoFromData(objectGraph, data, branch) { + const skuNameTitle = "<b>" + mediaAttributes.attributeAsString(branch, "name") + "</b>"; + const skuDescription = mediaAttributes.attributeAsString(branch, "description.standard") + "<br>"; + const termsTitle = "<b>" + objectGraph.loc.string("ContingentOffer.Terms.Title") + "</b>"; + const terms = mediaAttributes.attributeAsString(data, "additionalTerms"); + return new models.Paragraph([skuNameTitle, skuDescription, termsTitle, terms].join("<br>"), "text/x-apple-as3-nqml"); +} +/** + * If the contingent offer has a an associated trunk use that instead of the trunk-app + * @param data The data blob + * @returns Creates a lockup to use as the TrunkLockup + */ +function firstPartyTrunkLockupFromData(objectGraph, data) { + var _a, _b; + const firstPartyTrunkData = serverData.asInterface(data, "meta.associations.trunks"); + if (isNothing(firstPartyTrunkData)) { + return null; + } + const firstPartyApp = firstPartyTrunkData.data[0]; + const shouldUseTrunkArtwork = (_b = (_a = firstPartyApp === null || firstPartyApp === void 0 ? void 0 : firstPartyApp.meta) === null || _a === void 0 ? void 0 : _a["useTrunkArtwork"]) !== null && _b !== void 0 ? _b : false; + if (shouldUseTrunkArtwork) { + const editorialArtwork = contentAttributeAsDictionary(objectGraph, firstPartyApp, "editorialArtwork.brandLogo"); + if (isNothing(editorialArtwork)) { + return null; + } + return content.artworkFromApiArtwork(objectGraph, editorialArtwork, { + useCase: 1 /* content.ArtworkUseCase.LockupIconSmall */, + style: "roundedRect", + }); + } + return null; +} +//# sourceMappingURL=contingent-offer.js.map
\ No newline at end of file |
