summaryrefslogtreecommitdiff
path: root/node_modules/@jet-app/app-store/tmp/src/common/app-promotions/contingent-offer.js
diff options
context:
space:
mode:
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.js189
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