summaryrefslogtreecommitdiff
path: root/node_modules/@jet-app/app-store/tmp/src/common/arcade/arcade-upsell.js
diff options
context:
space:
mode:
authorrxliuli <rxliuli@gmail.com>2025-11-04 05:03:50 +0800
committerrxliuli <rxliuli@gmail.com>2025-11-04 05:03:50 +0800
commitbce557cc2dc767628bed6aac87301a1be7c5431b (patch)
treeb51a051228d01fe3306cd7626d4a96768aadb944 /node_modules/@jet-app/app-store/tmp/src/common/arcade/arcade-upsell.js
init commit
Diffstat (limited to 'node_modules/@jet-app/app-store/tmp/src/common/arcade/arcade-upsell.js')
-rw-r--r--node_modules/@jet-app/app-store/tmp/src/common/arcade/arcade-upsell.js257
1 files changed, 257 insertions, 0 deletions
diff --git a/node_modules/@jet-app/app-store/tmp/src/common/arcade/arcade-upsell.js b/node_modules/@jet-app/app-store/tmp/src/common/arcade/arcade-upsell.js
new file mode 100644
index 0000000..5c5d30e
--- /dev/null
+++ b/node_modules/@jet-app/app-store/tmp/src/common/arcade/arcade-upsell.js
@@ -0,0 +1,257 @@
+//
+// arcade-upsell.ts
+// AppStoreKit
+//
+// Created by Jonathan Ellenbogen on 11/19/19.
+// Copyright (c) 2016 Apple Inc. All rights reserved.
+//
+import * as models from "../../api/models";
+import * as serverData from "../../foundation/json-parsing/server-data";
+import * as mediaAttributes from "../../foundation/media/attributes";
+import * as color from "../../foundation/util/color-util";
+import * as heroCommon from "../grouping/hero/hero-common";
+import * as metricsHelpersClicks from "../metrics/helpers/clicks";
+import * as metricsHelpersImpressions from "../metrics/helpers/impressions";
+import * as metricsHelpersLocation from "../metrics/helpers/location";
+import * as metricsHelpersUtil from "../metrics/helpers/util";
+import * as offers from "../offers/offers";
+import * as breakoutsCommon from "./breakouts-common";
+import { ArcadeSubscriptionStateAction } from "../../api/models";
+import { isFeatureEnabledForCurrentUser } from "../util/lottery";
+export function createUpsellBreakout(objectGraph, upsellData, metricsOptions, style = "white") {
+ if (serverData.isNullOrEmpty(upsellData) ||
+ (serverData.isNullOrEmpty(upsellData.attributes) && !objectGraph.client.isVision)) {
+ return null;
+ }
+ const heroVideoData = heroCommon.heroVideoFromData(objectGraph, upsellData, true);
+ const heroArtworkData = heroCommon.heroArtworkFromData(objectGraph, upsellData);
+ const backgroundColor = heroVideoData.backgroundColor || heroArtworkData.backgroundColor;
+ const detailPosition = breakoutsCommon.detailPositionFromData(objectGraph, upsellData, true, true);
+ const supportsMaterial = objectGraph.client.isTV;
+ const wantsBlur = breakoutsCommon.wantsBlur(objectGraph, breakoutsCommon.detailBackgroundStyleFromData(objectGraph, upsellData, supportsMaterial, true, true), true);
+ const details = createBreakoutDetailsFromData(objectGraph, upsellData, null, supportsMaterial, wantsBlur, "wordmark");
+ let buttonCallToAction = null;
+ if (objectGraph.client.deviceType !== "tv") {
+ buttonCallToAction = details.description;
+ details.description = null;
+ }
+ const offerTint = offerTintFromMarketingItem(objectGraph, upsellData);
+ const offerDisplayProperties = new models.OfferDisplayProperties("arcade", objectGraph.bag.arcadeAppAdamId, null, style, null, "arcade", offerTint, null, null, null, null, null, null, null, null, null, null, null, objectGraph.bag.arcadeProductFamilyId);
+ const displayProperties = {
+ backgroundColor: backgroundColor,
+ wantsMaterialDetailBackground: false,
+ wantsBlur: wantsBlur,
+ badgeColor: null,
+ titleColor: null,
+ descriptionColor: null,
+ callToActionColor: null,
+ textAlignment: null,
+ detailsPosition: detailPosition,
+ };
+ const upsellBreakout = new models.UpsellBreakout(details, offerDisplayProperties, displayProperties, null, buttonCallToAction, heroArtworkData.artwork, heroVideoData.video);
+ const impressionOptions = metricsHelpersImpressions.impressionOptions(objectGraph, upsellData, upsellBreakout.details.title, {
+ ...metricsOptions,
+ targetType: "upsellBreakout",
+ });
+ impressionOptions.displaysArcadeUpsell = true;
+ metricsHelpersImpressions.addImpressionFields(objectGraph, upsellBreakout, impressionOptions);
+ // Push the breakout here so that the click action has the breakout in its location
+ // but we do not want to add it to the overall location tracker, so pop it right after adding it to the button
+ // action
+ // <rdar://problem/60883269> Metrics: Arcade: Container values requested in Location field
+ metricsHelpersLocation.pushContentLocation(objectGraph, impressionOptions, upsellBreakout.details.title);
+ upsellBreakout.offerButtonAction = arcadeOfferButtonActionFromData(objectGraph, upsellData, models.marketingItemContextFromString("arcadeTabHeader"), metricsOptions);
+ metricsHelpersLocation.popLocation(metricsOptions.locationTracker);
+ return upsellBreakout;
+}
+export function pageTitleEffectFromData(objectGraph, upsellData) {
+ const heroVideoData = heroCommon.heroVideoFromData(objectGraph, upsellData, true);
+ const heroArtworkData = heroCommon.heroArtworkFromData(objectGraph, upsellData);
+ const titleEffectArtwork = heroVideoData.artworkData || heroArtworkData.artworkData;
+ return breakoutsCommon.titleEffectFromArtwork(objectGraph, titleEffectArtwork, true);
+}
+export function callToActionLabelFromData(objectGraph, data) {
+ return breakoutsCommon.callToActionLabelFromData(objectGraph, data);
+}
+export function artworkDictionaryFromData(objectGraph, data) {
+ return breakoutsCommon.artworkDictionaryFromData(objectGraph, data);
+}
+export function artworkDataFromData(objectGraph, data, attributePath) {
+ const dictionary = artworkDictionaryFromData(objectGraph, data);
+ return serverData.asDictionary(dictionary, attributePath);
+}
+export function titleFromData(objectGraph, data) {
+ return mediaAttributes.attributeAsString(data, "title");
+}
+export function descriptionFromData(objectGraph, data) {
+ return mediaAttributes.attributeAsString(data, "subtitle");
+}
+export function createBreakoutDetailsFromData(objectGraph, data, contextualAppDataOrNull, supportsMaterial, wantsBlur, badgeType) {
+ let badge = null;
+ switch (badgeType) {
+ case "wordmark":
+ badge = {
+ type: "wordmark",
+ };
+ break;
+ case "text":
+ const badgeTitle = mediaAttributes.attributeAsString(data, "badge");
+ if ((badgeTitle === null || badgeTitle === void 0 ? void 0 : badgeTitle.length) > 0) {
+ badge = {
+ type: "text",
+ title: badgeTitle,
+ };
+ }
+ else {
+ badge = {
+ type: "none",
+ };
+ }
+ break;
+ default:
+ badge = {
+ type: "none",
+ };
+ break;
+ }
+ let backgroundStyle = breakoutsCommon.detailBackgroundStyleFromData(objectGraph, data, supportsMaterial, true, true);
+ const detailPosition = breakoutsCommon.detailPositionFromData(objectGraph, data, true, true);
+ if (wantsBlur) {
+ backgroundStyle = "dark";
+ }
+ const details = new models.BreakoutDetails(titleFromData(objectGraph, data), descriptionFromData(objectGraph, data), badge, null, backgroundStyle, breakoutsCommon.detailTextAlignmentForDetailPosition(objectGraph, detailPosition, data, true));
+ return details;
+}
+// region Offer Action
+export function arcadeOfferButtonActionFromData(objectGraph, upsellData, context, metricsOptions) {
+ const arcadeUpsellData = {
+ marketingItemData: upsellData,
+ };
+ // "arcadeTabHeader" context covers both hero and navbar button on the Arcade page
+ const showStarterPackOnboarding = context === models.marketingItemContextFromString("arcadeTabHeader") &&
+ objectGraph.bag.arcadeDownloadPackPostSubscribeTrigger &&
+ isFeatureEnabledForCurrentUser(objectGraph, objectGraph.bag.arcadeDownloadPackRolloutRate);
+ return arcadeActionFromUpsellData(objectGraph, arcadeUpsellData, callToActionLabelFromData(objectGraph, upsellData), metricsOptions, showStarterPackOnboarding);
+}
+export function arcadeActionFromUpsellData(objectGraph, data, title, baseMetricsOptions, showStarterPackOnboarding) {
+ const marketingItemData = data.marketingItemData;
+ if (!serverData.isDefinedNonNull(marketingItemData)) {
+ return null;
+ }
+ const offerData = offers.offerDataFromMarketingItem(objectGraph, marketingItemData);
+ const isLinkAction = serverData.asString(offerData, "kind") === "link";
+ const linkUrlString = serverData.asString(offerData, "url");
+ if (isLinkAction && linkUrlString) {
+ const linkAction = arcadeLinkActionFromMarketingItemLinkUrl(objectGraph, linkUrlString);
+ const linkClickOptions = {
+ id: objectGraph.bag.arcadeAppAdamId,
+ actionType: "buy",
+ actionContext: "Arcade",
+ contextualAdamId: objectGraph.bag.arcadeAppAdamId,
+ offerType: "subscribe",
+ targetType: "button",
+ mercuryMetricsData: metricsHelpersUtil.marketingItemTopLevelBaseFieldsFromData(objectGraph, marketingItemData),
+ ...baseMetricsOptions,
+ };
+ linkAction.title = title;
+ metricsHelpersClicks.addClickEventToAction(objectGraph, linkAction, linkClickOptions);
+ return linkAction;
+ }
+ else {
+ const arcadeAction = arcadeBuyActionFromMarketingItemData(objectGraph, marketingItemData, title, baseMetricsOptions);
+ if (showStarterPackOnboarding) {
+ const downloadPackOnboarding = new models.FlowAction("arcadeDownloadPackCategories");
+ const subscriptionStatus = "new";
+ downloadPackOnboarding.pageData = subscriptionStatus;
+ downloadPackOnboarding.presentationContext = "presentModalFormSheet";
+ // Passing `undefined` for other than subscribed actions instead of `BlankAction` to record an error.
+ const subscriptionCheckAction = new ArcadeSubscriptionStateAction(undefined, undefined, downloadPackOnboarding, undefined);
+ const action = new models.CompoundAction([arcadeAction, subscriptionCheckAction]);
+ action.title = title;
+ return action;
+ }
+ else {
+ return arcadeAction;
+ }
+ }
+}
+function arcadeLinkActionFromMarketingItemLinkUrl(objectGraph, urlString) {
+ /**
+ * Check against the bag routing regex and dispatch one of the AMS actions.
+ */
+ // Dynamic UI
+ const dynamicUIRegexPatterns = objectGraph.bag.dynamicUIRegexStrings;
+ for (const pattern of dynamicUIRegexPatterns) {
+ const dynamicUIPattern = new RegExp(pattern);
+ if (dynamicUIPattern.test(urlString)) {
+ const action = new models.FlowAction("dynamicUI", urlString);
+ action.pageData = new models.DynamicUIRequestInfo(objectGraph.bag.metricsTopic);
+ return action;
+ }
+ }
+ // Finance UI regex check
+ const financeUIRegexPatterns = objectGraph.bag.financeUIRegexStrings;
+ for (const pattern of financeUIRegexPatterns) {
+ const financeUIPattern = new RegExp(pattern);
+ if (financeUIPattern.test(urlString)) {
+ return new models.FlowAction("finance", urlString);
+ }
+ }
+ // Web UI regex check
+ const webViewRegexPatterns = objectGraph.bag.webViewRegexStrings;
+ for (const pattern of webViewRegexPatterns) {
+ const webViewPattern = new RegExp(pattern);
+ if (webViewPattern.test(urlString)) {
+ return new models.FlowAction("webView", urlString);
+ }
+ }
+ return new models.ExternalUrlAction(urlString, false);
+}
+function arcadeBuyActionFromMarketingItemData(objectGraph, data, title, baseMetricsOptions) {
+ const offerData = offers.offerDataFromMarketingItem(objectGraph, data);
+ const offerName = serverData.asString(offerData, "offerName");
+ const buyParams = serverData.asString(offerData, "buyParams");
+ if (!serverData.isDefinedNonNull(offerName) || !serverData.isDefinedNonNull(buyParams)) {
+ return null;
+ }
+ const offerServiceTypes = serverData.asArrayOrEmpty(offerData, "serviceTypes");
+ const isAristotleOffer = offerServiceTypes.length > 1 && objectGraph.bag.aristotleParentAppAdamId;
+ const parentAdamId = isAristotleOffer ? objectGraph.bag.aristotleParentAppAdamId : objectGraph.bag.arcadeAppAdamId;
+ const arcadeAction = new models.ArcadeAction(offerName, parentAdamId, {
+ buyParams: buyParams,
+ productIdentifier: offerName,
+ pageInformation: baseMetricsOptions.pageInformation,
+ });
+ const metricsClickOptions = {
+ id: parentAdamId,
+ actionType: "buy",
+ targetType: "button",
+ subscriptionSKU: offerName,
+ actionContext: "Arcade",
+ contextualAdamId: parentAdamId,
+ actionDetails: { buyParams: buyParams },
+ offerType: "subscribe",
+ mercuryMetricsData: metricsHelpersUtil.marketingItemTopLevelBaseFieldsFromData(objectGraph, data),
+ ...baseMetricsOptions,
+ };
+ arcadeAction.title = title;
+ metricsHelpersClicks.addClickEventToAction(objectGraph, arcadeAction, metricsClickOptions);
+ return arcadeAction;
+}
+// endregion
+// region Helpers
+function offerTintFromMarketingItem(objectGraph, data) {
+ const templateParameters = breakoutsCommon.templateParametersFromData(objectGraph, data);
+ const fillColor = serverData.asString(templateParameters, "ctaButtonBackgroundColor");
+ const textColor = serverData.asString(templateParameters, "ctaButtonTextColor");
+ if (!serverData.isDefinedNonNull(fillColor) || !serverData.isDefinedNonNull(textColor)) {
+ return { type: "blue", fillColor: null, textColor: null };
+ }
+ return {
+ type: "custom",
+ fillColor: color.fromHex(fillColor),
+ textColor: color.fromHex(textColor),
+ };
+}
+// endregion
+//# sourceMappingURL=arcade-upsell.js.map \ No newline at end of file