summaryrefslogtreecommitdiff
path: root/node_modules/@jet-app/app-store/tmp/src/common/grouping/hero
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/grouping/hero
init commit
Diffstat (limited to 'node_modules/@jet-app/app-store/tmp/src/common/grouping/hero')
-rw-r--r--node_modules/@jet-app/app-store/tmp/src/common/grouping/hero/hero-carousel-overlay-common.js263
-rw-r--r--node_modules/@jet-app/app-store/tmp/src/common/grouping/hero/hero-common.js90
2 files changed, 353 insertions, 0 deletions
diff --git a/node_modules/@jet-app/app-store/tmp/src/common/grouping/hero/hero-carousel-overlay-common.js b/node_modules/@jet-app/app-store/tmp/src/common/grouping/hero/hero-carousel-overlay-common.js
new file mode 100644
index 0000000..183947f
--- /dev/null
+++ b/node_modules/@jet-app/app-store/tmp/src/common/grouping/hero/hero-carousel-overlay-common.js
@@ -0,0 +1,263 @@
+//
+// hero-carousel-overlay-common.ts
+// AppStoreKit
+//
+// Created by Jonathan Ellenbogen on 12/11/20.
+// 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 mediaDataStructure from "../../../foundation/media/data-structure";
+import * as mediaRelationship from "../../../foundation/media/relationships";
+import * as color from "../../../foundation/util/color-util";
+import * as breakoutsCommon from "../../arcade/breakouts-common";
+import * as contentAttributes from "../../content/attributes";
+import * as content from "../../content/content";
+import * as lockups from "../../lockups/lockups";
+import * as metricsHelpersClicks from "../../metrics/helpers/clicks";
+import * as metricsHelpersImpressions from "../../metrics/helpers/impressions";
+import * as heroCommon from "./hero-common";
+import * as lottery from "../../util/lottery";
+export function overlayFromData(objectGraph, data, requirements) {
+ const heroCarouselItemOverlay = new models.HeroCarouselItemOverlay();
+ heroCarouselItemOverlay.overlayType = overlayTypeFromData(objectGraph, data);
+ heroCarouselItemOverlay.displayOptions = {
+ horizontalPlacement: overlayPlacementFromData(objectGraph, data),
+ textAlignment: overlayTextAlignmentFromData(objectGraph, data),
+ isOverDarkContent: overlayIsOverDarkContent(objectGraph, data),
+ };
+ const primaryContent = content.primaryContentForData(objectGraph, data);
+ // If this EI can and should show the expected release date of an app, override the badge.
+ const fallbackLabel = mediaAttributes.attributeAsString(data, "label");
+ if (contentAttributes.contentAttributeAsBooleanOrFalse(objectGraph, data, "showExpectedReleaseDate")) {
+ heroCarouselItemOverlay.badgeText = objectGraph.loc.uppercased(content.dynamicPreorderDateFromData(objectGraph, primaryContent, fallbackLabel));
+ }
+ else {
+ heroCarouselItemOverlay.badgeText = fallbackLabel;
+ }
+ heroCarouselItemOverlay.titleText =
+ content.editorialNotesFromData(objectGraph, data, "name") ||
+ contentAttributes.contentAttributeAsString(objectGraph, primaryContent, "name");
+ if (heroCarouselItemOverlay.overlayType === "singleModule" ||
+ heroCarouselItemOverlay.overlayType === "collectionModule") {
+ heroCarouselItemOverlay.descriptionText = content.editorialNotesFromData(objectGraph, data, "tagline");
+ }
+ else {
+ heroCarouselItemOverlay.descriptionText =
+ content.editorialNotesFromData(objectGraph, data, "short") ||
+ contentAttributes.contentAttributeAsString(objectGraph, primaryContent, "tagline");
+ }
+ heroCarouselItemOverlay.callToActionText = mediaAttributes.attributeAsString(data, "breakoutCallToActionLabel");
+ heroCarouselItemOverlay.buttonTitle = overlayButtonTitleFromData(objectGraph, data);
+ if (heroCarouselItemOverlay.overlayType === "lockup" || heroCarouselItemOverlay.overlayType === "singleModule") {
+ heroCarouselItemOverlay.lockup = overlayLockupFromData(objectGraph, data, requirements);
+ }
+ // For hero items the design is to use editorial labels instead of "Apple Arcade" so we replace that text here
+ if ((fallbackLabel === null || fallbackLabel === void 0 ? void 0 : fallbackLabel.length) > 0 && serverData.isDefinedNonNull(heroCarouselItemOverlay.lockup)) {
+ heroCarouselItemOverlay.lockup.heading = fallbackLabel;
+ }
+ heroCarouselItemOverlay.collectionIcons = overlayCollectionIconsFromData(objectGraph, data);
+ if (serverData.isDefinedNonNullNonEmpty(heroCarouselItemOverlay.lockup)) {
+ heroCarouselItemOverlay.clickAction = heroCarouselItemOverlay.lockup.clickAction;
+ heroCarouselItemOverlay.impressionMetrics = heroCarouselItemOverlay.lockup.impressionMetrics;
+ }
+ else {
+ const heroCarouselItemOverlayMetricsOptions = {
+ targetType: "lockup",
+ pageInformation: requirements.metricsPageInformation,
+ locationTracker: requirements.metricsLocationTracker,
+ recoMetricsData: mediaDataStructure.metricsFromMediaApiObject(data),
+ };
+ const overlayMetricsTitle = heroCarouselItemTitleFromData(objectGraph, data);
+ const heroCarouselItemOverlayAction = breakoutsCommon.actionFromData(objectGraph, data);
+ heroCarouselItemOverlayAction.title = overlayMetricsTitle;
+ const heroCarouselItemOverlayClickOptions = {
+ pageInformation: requirements.metricsPageInformation,
+ locationTracker: requirements.metricsLocationTracker,
+ recoMetricsData: mediaDataStructure.metricsFromMediaApiObject(data),
+ targetType: "lockup",
+ id: data.id,
+ };
+ metricsHelpersClicks.addClickEventToAction(objectGraph, heroCarouselItemOverlayAction, heroCarouselItemOverlayClickOptions);
+ heroCarouselItemOverlay.clickAction = heroCarouselItemOverlayAction;
+ const heroCarouselItemOverlayImpressionsOptions = metricsHelpersImpressions.impressionOptions(objectGraph, data, overlayMetricsTitle, heroCarouselItemOverlayMetricsOptions);
+ metricsHelpersImpressions.addImpressionFields(objectGraph, heroCarouselItemOverlay, heroCarouselItemOverlayImpressionsOptions);
+ }
+ return heroCarouselItemOverlay;
+}
+export function overlayTypeFromData(objectGraph, data) {
+ const displayMaterial = mediaAttributes.attributeAsBooleanOrFalse(data, "displayBreakoutMaterial");
+ const editorialItemKind = mediaAttributes.attributeAsString(data, "kind");
+ const relatedCollection = mediaRelationship.relationshipCollection(data, "card-contents");
+ const tagline = content.editorialNotesFromData(objectGraph, data, "tagline");
+ const canPresentHeroModuleStyle = allowHeroModuleStylePresentation(objectGraph) && (tagline === null || tagline === void 0 ? void 0 : tagline.length) > 0;
+ let relatedApp = mediaRelationship.relationshipData(objectGraph, data, "primary-content");
+ if (serverData.isNullOrEmpty(relatedApp) && serverData.isDefinedNonNullNonEmpty(relatedCollection)) {
+ relatedApp = relatedCollection[0];
+ }
+ if (serverData.isDefinedNonNull(relatedApp) && editorialItemKind === "App") {
+ return canPresentHeroModuleStyle ? "singleModule" : "lockup";
+ }
+ else if (serverData.isDefinedNonNullNonEmpty(relatedCollection) && editorialItemKind === "Collection") {
+ return canPresentHeroModuleStyle ? "collectionModule" : "collectionLockup";
+ }
+ else if (displayMaterial) {
+ return "materialText";
+ }
+ else {
+ return objectGraph.client.isTV ? "materialText" : "text";
+ }
+}
+export function heroCarouselItemTitleFromData(objectGraph, data) {
+ const overlayType = overlayTypeFromData(objectGraph, data);
+ const primaryContent = mediaRelationship.relationshipData(objectGraph, data, "primary-content");
+ switch (overlayType) {
+ case "lockup":
+ case "singleModule":
+ return mediaAttributes.attributeAsString(primaryContent, "name");
+ case "materialText":
+ case "text":
+ case "collectionLockup":
+ case "collectionModule":
+ return (content.editorialNotesFromData(objectGraph, data, "name") ||
+ contentAttributes.contentAttributeAsString(objectGraph, primaryContent, "name"));
+ default:
+ return null;
+ }
+}
+export function overlayLockupFromData(objectGraph, data, requirements) {
+ let relatedApp = mediaRelationship.relationshipData(objectGraph, data, "primary-content");
+ const relatedCollection = mediaRelationship.relationshipCollection(data, "card-contents");
+ if (serverData.isNullOrEmpty(relatedApp) && serverData.isDefinedNonNullNonEmpty(relatedCollection)) {
+ relatedApp = relatedCollection[0];
+ }
+ if (serverData.isNullOrEmpty(relatedApp)) {
+ return null;
+ }
+ // Create the lockup
+ const lockupOptions = {
+ metricsOptions: {
+ pageInformation: requirements.metricsPageInformation,
+ locationTracker: requirements.metricsLocationTracker,
+ recoMetricsData: mediaDataStructure.metricsFromMediaApiObject(data),
+ },
+ artworkUseCase: requirements.lockupArtworkUseCase,
+ offerStyle: "transparent",
+ offerEnvironment: "dark",
+ canDisplayArcadeOfferButton: requirements.canDisplayArcadeOfferButton,
+ shouldHideArcadeHeader: objectGraph.featureFlags.isEnabled("hide_arcade_header_on_arcade_tab"),
+ isContainedInPreorderExclusiveShelf: requirements.isContainedInPreorderExclusiveShelf,
+ };
+ const lockup = lockups.lockupFromData(objectGraph, relatedApp, lockupOptions);
+ const primaryContent = content.primaryContentForData(objectGraph, data);
+ const editorialTagline = content.editorialNotesFromData(objectGraph, data, "short") ||
+ contentAttributes.contentAttributeAsString(objectGraph, primaryContent, "tagline");
+ if ((editorialTagline === null || editorialTagline === void 0 ? void 0 : editorialTagline.length) > 0) {
+ lockup.subtitle = editorialTagline;
+ }
+ return lockup;
+}
+export function overlayCollectionIconsFromData(objectGraph, data) {
+ const relatedCollection = mediaRelationship.relationshipCollection(data, "card-contents");
+ if (serverData.isNullOrEmpty(relatedCollection)) {
+ return null;
+ }
+ const icons = [];
+ for (const item of relatedCollection) {
+ const icon = content.iconFromData(objectGraph, item, {
+ useCase: 1 /* content.ArtworkUseCase.LockupIconSmall */,
+ withJoeColorPlaceholder: true,
+ });
+ if (serverData.isDefinedNonNullNonEmpty(icon)) {
+ icons.push(icon);
+ }
+ }
+ return serverData.isDefinedNonNullNonEmpty(icons) ? icons : null;
+}
+export function overlayButtonTitleFromData(objectGraph, data) {
+ if (objectGraph.client.deviceType !== "tv") {
+ return null;
+ }
+ const overlayType = overlayTypeFromData(objectGraph, data);
+ switch (overlayType) {
+ case "lockup":
+ return objectGraph.loc.string("HERO_CAROUSEL_OVERLAY_BUTTON_TITLE_GAME");
+ case "materialText":
+ case "text":
+ let buttonTitle = objectGraph.loc.string("HERO_CAROUSEL_OVERLAY_BUTTON_TITLE_VIEW");
+ if (buttonTitle === "HERO_CAROUSEL_OVERLAY_BUTTON_TITLE_VIEW") {
+ buttonTitle = objectGraph.loc.string("HERO_CAROUSEL_OVERLAY_BUTTON_TITLE_GAME");
+ }
+ return buttonTitle;
+ case "collectionLockup":
+ return objectGraph.loc.string("HERO_CAROUSEL_OVERLAY_BUTTON_TITLE_COLLECTION");
+ default:
+ return null;
+ }
+}
+export function overlayIsOverDarkContent(objectGraph, data) {
+ const heroVideoData = heroCommon.heroVideoFromData(objectGraph, data);
+ const heroArtworkData = heroCommon.heroArtworkFromData(objectGraph, data);
+ const backgroundColor = heroVideoData.backgroundColor || heroArtworkData.backgroundColor;
+ if (!backgroundColor) {
+ return true;
+ }
+ return color.isDarkColor(backgroundColor, 50);
+}
+export function overlayPlacementFromData(objectGraph, data) {
+ if (objectGraph.client.isPhone) {
+ return "center";
+ }
+ if (objectGraph.client.isTV) {
+ return "leading";
+ }
+ const heroCarouselItemPlacementString = mediaAttributes.attributeAsString(data, "breakoutTextAlignment");
+ if (!serverData.isDefinedNonNullNonEmpty(heroCarouselItemPlacementString)) {
+ return objectGraph.client.isMac ? "center" : "leading";
+ }
+ switch (heroCarouselItemPlacementString.toLowerCase()) {
+ case "left":
+ return "leading";
+ case "center":
+ return "center";
+ case "right":
+ return "trailing";
+ default:
+ return "leading";
+ }
+}
+/**
+ * The text alignment to use for a particular detail position on large breakouts
+ * @param data
+ */
+function overlayTextAlignmentFromData(objectGraph, data) {
+ const placement = overlayPlacementFromData(objectGraph, data);
+ const isTV = objectGraph.client.isTV;
+ switch (placement) {
+ case "leading":
+ return "leading";
+ case "trailing":
+ return "leading";
+ case "center":
+ if (isTV) {
+ return "leading";
+ }
+ else {
+ return objectGraph.client.isMac ? "center" : "leading";
+ }
+ default:
+ return "leading";
+ }
+}
+/**
+ * Decides whether to account for the Hero 3.0 styles.
+ *
+ * @param objectGraph The object graph.
+ */
+function allowHeroModuleStylePresentation(objectGraph) {
+ const isNotTV = !objectGraph.client.isTV;
+ const isFeatureEnabledForCurrentUser = lottery.isFeatureEnabledForCurrentUser(objectGraph, objectGraph.bag.hero3RolloutRate);
+ return isNotTV && isFeatureEnabledForCurrentUser;
+}
+//# sourceMappingURL=hero-carousel-overlay-common.js.map \ No newline at end of file
diff --git a/node_modules/@jet-app/app-store/tmp/src/common/grouping/hero/hero-common.js b/node_modules/@jet-app/app-store/tmp/src/common/grouping/hero/hero-common.js
new file mode 100644
index 0000000..4a67b72
--- /dev/null
+++ b/node_modules/@jet-app/app-store/tmp/src/common/grouping/hero/hero-common.js
@@ -0,0 +1,90 @@
+//
+// hero-carousel-overlay-common.ts
+// AppStoreKit
+//
+// Created by Jonathan Ellenbogen on 12/11/20.
+// Copyright (c) 2016 Apple Inc. All rights reserved.
+//
+import * as models from "../../../api/models";
+import * as serverData from "../../../foundation/json-parsing/server-data";
+import { artworkDictionaryFromData, videoDictionaryFromData } from "../../arcade/breakouts-common";
+import * as content from "../../content/content";
+export function heroArtworkFromData(objectGraph, data, presentedInTopShelf = false) {
+ const artworkDictionary = artworkDictionaryFromData(objectGraph, data);
+ const isPhone = objectGraph.client.isPhone;
+ const isTV = objectGraph.client.isTV;
+ let heroArtworkKey = isPhone ? "breakoutTall" : "breakoutFullScreen";
+ if (presentedInTopShelf) {
+ heroArtworkKey = "topShelf";
+ }
+ const heroArtworkData = serverData.asDictionary(artworkDictionary, heroArtworkKey);
+ let heroArtwork = null;
+ let backgroundColor = null;
+ if (serverData.isDefinedNonNullNonEmpty(heroArtworkData)) {
+ heroArtwork = content.artworkFromApiArtwork(objectGraph, heroArtworkData, {
+ withJoeColorPlaceholder: true,
+ useCase: 6 /* content.ArtworkUseCase.ArcadeLargeBreakout */,
+ });
+ if (serverData.isDefinedNonNullNonEmpty(heroArtwork)) {
+ if (isPhone) {
+ heroArtwork.crop = "oa";
+ }
+ else if (presentedInTopShelf) {
+ heroArtwork.crop = "ta";
+ }
+ else if (isTV) {
+ heroArtwork.crop = "od";
+ }
+ else {
+ heroArtwork.crop = "ob";
+ }
+ backgroundColor = heroArtwork.backgroundColor;
+ }
+ }
+ return {
+ artwork: heroArtwork,
+ artworkData: heroArtworkData,
+ backgroundColor: backgroundColor,
+ };
+}
+export function heroVideoFromData(objectGraph, data, isUpsell = false, wants9x16 = false) {
+ const videoDictionary = videoDictionaryFromData(objectGraph, data);
+ const use9x16 = objectGraph.client.isPhone || wants9x16;
+ const heroVideoKey = use9x16 ? "sizzleVideo9x16" : "sizzleVideo16x9";
+ const heroVideoFallbackKey = use9x16 ? "breakoutVideo9x16" : "breakoutVideo16x9";
+ const heroVideoData = serverData.asDictionary(videoDictionary, heroVideoKey) ||
+ serverData.asDictionary(videoDictionary, heroVideoFallbackKey);
+ let heroVideo = null;
+ let backgroundColor = null;
+ let artworkData = null;
+ if (serverData.isDefinedNonNullNonEmpty(heroVideoData)) {
+ artworkData = serverData.asDictionary(heroVideoData, "previewFrame");
+ const artwork = content.artworkFromApiArtwork(objectGraph, artworkData, {
+ withJoeColorPlaceholder: true,
+ useCase: 6 /* content.ArtworkUseCase.ArcadeLargeBreakout */,
+ });
+ if (serverData.isDefinedNonNullNonEmpty(artwork)) {
+ artwork.crop = "sr";
+ backgroundColor = artwork.backgroundColor;
+ }
+ // Get the video URL
+ const videoUrl = serverData.asString(heroVideoData, "video");
+ if (serverData.isDefinedNonNullNonEmpty(artwork) && (videoUrl === null || videoUrl === void 0 ? void 0 : videoUrl.length) > 0) {
+ heroVideo = new models.Video(videoUrl, artwork, {
+ canPlayFullScreen: false,
+ allowsAutoPlay: true,
+ looping: true,
+ playbackControls: {
+ prominentPlay: isUpsell,
+ },
+ autoPlayPlaybackControls: {},
+ });
+ }
+ }
+ return {
+ video: heroVideo,
+ artworkData: artworkData,
+ backgroundColor: backgroundColor,
+ };
+}
+//# sourceMappingURL=hero-common.js.map \ No newline at end of file