From bce557cc2dc767628bed6aac87301a1be7c5431b Mon Sep 17 00:00:00 2001 From: rxliuli Date: Tue, 4 Nov 2025 05:03:50 +0800 Subject: init commit --- .../common/today/cards/today-ad-card-builder.js | 232 ++++++++++++++++++++ .../today/cards/today-app-event-card-builder.js | 112 ++++++++++ .../common/today/cards/today-base-card-builder.js | 244 +++++++++++++++++++++ .../today/cards/today-branded-card-builder.js | 58 +++++ .../cards/today-full-bleed-image-card-builder.js | 37 ++++ .../cards/today-in-app-purchase-card-builder.js | 62 ++++++ .../common/today/cards/today-list-card-builder.js | 71 ++++++ .../common/today/cards/today-river-card-builder.js | 62 ++++++ .../today/cards/today-short-image-card-builder.js | 42 ++++ .../today/cards/today-single-app-card-builder.js | 81 +++++++ .../common/today/cards/today-video-card-builder.js | 33 +++ 11 files changed, 1034 insertions(+) create mode 100644 node_modules/@jet-app/app-store/tmp/src/common/today/cards/today-ad-card-builder.js create mode 100644 node_modules/@jet-app/app-store/tmp/src/common/today/cards/today-app-event-card-builder.js create mode 100644 node_modules/@jet-app/app-store/tmp/src/common/today/cards/today-base-card-builder.js create mode 100644 node_modules/@jet-app/app-store/tmp/src/common/today/cards/today-branded-card-builder.js create mode 100644 node_modules/@jet-app/app-store/tmp/src/common/today/cards/today-full-bleed-image-card-builder.js create mode 100644 node_modules/@jet-app/app-store/tmp/src/common/today/cards/today-in-app-purchase-card-builder.js create mode 100644 node_modules/@jet-app/app-store/tmp/src/common/today/cards/today-list-card-builder.js create mode 100644 node_modules/@jet-app/app-store/tmp/src/common/today/cards/today-river-card-builder.js create mode 100644 node_modules/@jet-app/app-store/tmp/src/common/today/cards/today-short-image-card-builder.js create mode 100644 node_modules/@jet-app/app-store/tmp/src/common/today/cards/today-single-app-card-builder.js create mode 100644 node_modules/@jet-app/app-store/tmp/src/common/today/cards/today-video-card-builder.js (limited to 'node_modules/@jet-app/app-store/tmp/src/common/today/cards') diff --git a/node_modules/@jet-app/app-store/tmp/src/common/today/cards/today-ad-card-builder.js b/node_modules/@jet-app/app-store/tmp/src/common/today/cards/today-ad-card-builder.js new file mode 100644 index 0000000..dfe9836 --- /dev/null +++ b/node_modules/@jet-app/app-store/tmp/src/common/today/cards/today-ad-card-builder.js @@ -0,0 +1,232 @@ +import { isSome } from "@jet/environment"; +import * as validation from "@jet/environment/json/validation"; +import { MediumAdLockupWithScreenshotsBackground, CondensedAdLockupWithIconBackground, TodayCardMediaSingleLockup, TodayCardMediaMediumLockupWithScreenshots, TodayCardMediaMediumLockupWithAlignedRegion, MediumAdLockupWithAlignedRegionBackground, } from "../../../api/models"; +import { asString, isDefinedNonNull, isNull } from "../../../foundation/json-parsing/server-data"; +import { isColorEqualToColor } from "../../../foundation/util/color-util"; +import { todayAdStyle } from "../../ads/ad-common"; +import { recordLockupFromDataFailed } from "../../ads/ad-incident-recorder"; +import { iconFromData } from "../../content/content"; +import { getTemplateTypeForMediumAdFromLockupWithCustomCreative, getTemplateTypeForMediumAdFromLockupWithScreenshots, isCppDeeplinkEnabledForAdvert, performAdOverridesForCard, } from "../../lockups/ad-lockups"; +import * as lockups from "../../lockups/lockups"; +import * as metricsHelpersImpressions from "../../metrics/helpers/impressions"; +import { productVariantDataForData } from "../../product-page/product-page-variants"; +import { popTodayCardLocation, pushTodayCardLocation } from "../today-card-util"; +import { createTodayBaseCard } from "./today-base-card-builder"; +import { getSelectedCustomCreativeId } from "../../search/custom-creative"; +/** + * Create TodayCard displaying an ad fetched from Ad platforms + * + * @param objectGraph The dependency graph for the App Store + * @param adData The media api data to build the ad card from + * @param adIncidentRecorder The incident recorder for the ad, for when an issues arises + * @param cardConfig The configuration for the card + * @param context The parse context for the over all today page + * @returns The newly created TodayCard, using the full bleed image media. + */ +export function createTodayAdCard(objectGraph, adData, adIncidentRecorder, cardConfig, context) { + return validation.context("createTodayAdCard", () => { + var _a, _b, _c, _d; + if (isNull(adData)) { + return null; // No task for the position + } + const adCard = createTodayBaseCard(objectGraph, adData, cardConfig, context); + pushTodayCardLocation(objectGraph, adData, cardConfig, context, asString(adData.attributes.name)); + const metricsOptions = metricsHelpersImpressions.impressionOptions(objectGraph, adData, asString(adData.attributes.name), { + targetType: "todayCard", + pageInformation: context.pageInformation, + locationTracker: context.locationTracker, + isAdvert: true, + rowIndex: cardConfig.currentRowIndex, + displayStyle: cardConfig.metricsDisplayStyle, + }); + const productVariantData = productVariantDataForData(objectGraph, adData); + metricsOptions.productVariantData = productVariantData; + metricsOptions.adSlotOverride = context.parsedCardCount; + metricsOptions.kind = "adItem"; + const clickOptions = metricsOptions; + // Set up iAdInfo + metricsOptions.pageInformation.iAdInfo.apply(objectGraph, adData); + // Configure the action + let clientIdentifierOverride; + if (isDefinedNonNull(cardConfig)) { + clientIdentifierOverride = cardConfig.clientIdentifierOverride; + } + const customCreativeId = getSelectedCustomCreativeId(adData); + const isCustomCreative = isSome(customCreativeId); + adCard.style = "dark"; + switch (todayAdStyle(objectGraph)) { + case "singleLockup": + // Hardcode the condensed ad template type. This is not dependent on media count. + (_a = metricsOptions.pageInformation.iAdInfo) === null || _a === void 0 ? void 0 : _a.setTemplateType("APPLOCKUP"); + break; + case "mediumLockup": + if (isCustomCreative) { + (_b = metricsOptions.pageInformation.iAdInfo) === null || _b === void 0 ? void 0 : _b.setTemplateType(getTemplateTypeForMediumAdFromLockupWithCustomCreative()); + } + break; + default: + break; + } + let lockup = createAdCardLockup(objectGraph, adData, cardConfig, context); + if (isNull(lockup)) { + recordLockupFromDataFailed(objectGraph, adIncidentRecorder, adData); + popTodayCardLocation(context); + // Configure impressions + metricsHelpersImpressions.addImpressionsFieldsToTodayCard(objectGraph, adCard, metricsOptions, null, null, false, false); + return null; + } + if (objectGraph.props.enabled("advertSlotReporting")) { + (_c = lockup.searchAdOpportunity) === null || _c === void 0 ? void 0 : _c.setTemplateType("APPLOCKUP"); + } + else { + (_d = lockup.searchAd) === null || _d === void 0 ? void 0 : _d.setTemplateType("APPLOCKUP"); + } + switch (todayAdStyle(objectGraph)) { + case "singleLockup": + const condensedAdLockupWithIconBackground = new CondensedAdLockupWithIconBackground(lockup, lockup.icon); + adCard.media = new TodayCardMediaSingleLockup(condensedAdLockupWithIconBackground); + adCard.media.impressionMetrics = lockup.impressionMetrics; + break; + case "mediumLockup": + if (preprocessor.CARRY_BUILD || preprocessor.DEBUG_BUILD) { + if (isCustomCreative && objectGraph.featureFlags.isEnabled("aligned_region_artwork_2025A")) { + adCard.media = createMediumLockupWithAlignedRegion(objectGraph, lockup, adData, metricsOptions.pageInformation); + // After the media is created, we need to recreate the lockup to ensure all instrumentation + // has the updated template type, which is derived from the final set of media in + // `createMediumLockupWithAlignedRegion`. + lockup = createAdCardLockup(objectGraph, adData, cardConfig, context); + // Preserve SearchAd metadata + lockup.searchAdOpportunity = adCard.media.mediumAdLockupWithAlignedRegionBackground.lockup.searchAdOpportunity; + lockup.searchAd = adCard.media.mediumAdLockupWithAlignedRegionBackground.lockup.searchAd; + // The new lockup with the correct metrics should be set on the media. + adCard.media.mediumAdLockupWithAlignedRegionBackground.lockup = lockup; + adCard.media.impressionMetrics = lockup.impressionMetrics; + break; + } + else { + adCard.media = createMediumScreenshotsCardMedia(adCard, objectGraph, lockup, adData, cardConfig, context, metricsOptions); + } + } + else { + adCard.media = createMediumScreenshotsCardMedia(adCard, objectGraph, lockup, adData, cardConfig, context, metricsOptions); + } + break; + default: + return null; + } + popTodayCardLocation(context); + // CPP deeplinks used for ads have a requirement to not be used when targeting criteria is too narrow. + const isCppDeeplinkingEnabled = isCppDeeplinkEnabledForAdvert(adData); + // It's important the click action is created after the template type is set, to ensure it's in the metrics. + adCard.clickAction = lockups.actionFromData(objectGraph, adData, clickOptions, clientIdentifierOverride, undefined, isCppDeeplinkingEnabled); + performAdOverridesForCard(objectGraph, adData, adCard, metricsOptions); + // Configure impressions + metricsHelpersImpressions.addImpressionsFieldsToTodayCard(objectGraph, adCard, metricsOptions, null, null, false, false); + return adCard; + }); +} +function createMediumScreenshotsCardMedia(adCard, objectGraph, lockup, adData, cardConfig, context, metricsOptions) { + adCard.media = createMediumLockupWithScreenshots(objectGraph, lockup, objectGraph.bag.todayAdMediumLockupScreenshotAnimationEnabled, metricsOptions.pageInformation, adData); + // After the media is created, we need to recreate the lockup to ensure all instrumentation + // has the updated template type, which is derived from the final set of media in + // `createMediumLockupWithScreenshots`. + lockup = createAdCardLockup(objectGraph, adData, cardConfig, context); + if (isNull(lockup)) { + return null; + } + // Preserve SearchAd metadata + lockup.searchAdOpportunity = adCard.media.mediumAdLockupWithScreenshotsBackground.lockup.searchAdOpportunity; + lockup.searchAd = adCard.media.mediumAdLockupWithScreenshotsBackground.lockup.searchAd; + // The new lockup with the correct metrics should be set on the media. + adCard.media.mediumAdLockupWithScreenshotsBackground.lockup = lockup; + adCard.media.impressionMetrics = lockup.impressionMetrics; + return adCard.media; +} +function createAdCardLockup(objectGraph, data, cardConfig, context) { + const offerEnvironment = "ad"; + const offerStyle = "transparent"; + return lockups.mixedMediaAdLockupFromData(objectGraph, data, { + offerEnvironment: offerEnvironment, + offerStyle: offerStyle, + metricsOptions: { + pageInformation: context.pageInformation, + locationTracker: context.locationTracker, + isAdvert: true, + adSlotOverride: context.parsedCardCount, + disableFastImpressionsForAds: true, + }, + clientIdentifierOverride: cardConfig.clientIdentifierOverride, + crossLinkSubtitle: cardConfig.crossLinkSubtitle, + artworkUseCase: 1 /* ArtworkUseCase.LockupIconSmall */, + canDisplayArcadeOfferButton: cardConfig.canDisplayArcadeOfferButton, + }, { + allowsAutoPlay: true, + looping: true, + canPlayFullScreen: false, + playbackControls: {}, + }, null, false); +} +function createMediumLockupWithAlignedRegion(objectGraph, lockup, adData, pageInformation) { + var _a, _b, _c; + const alignedRegionArtwork = lockup.alignedRegionArtwork; + const templateString = getTemplateTypeForMediumAdFromLockupWithCustomCreative(); + (_a = pageInformation === null || pageInformation === void 0 ? void 0 : pageInformation.iAdInfo) === null || _a === void 0 ? void 0 : _a.setTemplateType(templateString); + if (objectGraph.props.enabled("advertSlotReporting")) { + (_b = lockup.searchAdOpportunity) === null || _b === void 0 ? void 0 : _b.setTemplateType(templateString); + } + else { + (_c = lockup.searchAd) === null || _c === void 0 ? void 0 : _c.setTemplateType(templateString); + } + const mediumContainer = new MediumAdLockupWithAlignedRegionBackground(lockup, alignedRegionArtwork); + return new TodayCardMediaMediumLockupWithAlignedRegion(mediumContainer); +} +/** + * Creates the media for a medium Today ad, with the appropriate media. + * Also applies information about the created media template to a provided MetricsPageInformation. + * @param objectGraph The object graph. + * @param lockup The lockup for the app. + * @param isAnimated Whether the card background should be animated. + * @param pageInformation A MetricsPageInformation to apply the created template metrics information to. + * @param adData The data for the ad. + * @returns A `TodayCardMediumLockupWithScreenshots` with the correct media to be displayed. + */ +function createMediumLockupWithScreenshots(objectGraph, lockup, isAnimated, pageInformation, adData) { + var _a, _b, _c; + // Grab the first of the platform screenshots and trailers - the ones the ad will display. + const platformScreenshots = lockup.screenshots[0]; + const templateString = getTemplateTypeForMediumAdFromLockupWithScreenshots(platformScreenshots); + (_a = pageInformation.iAdInfo) === null || _a === void 0 ? void 0 : _a.setTemplateType(templateString); + if (objectGraph.props.enabled("advertSlotReporting")) { + (_b = lockup.searchAdOpportunity) === null || _b === void 0 ? void 0 : _b.setTemplateType(templateString); + } + else { + (_c = lockup.searchAd) === null || _c === void 0 ? void 0 : _c.setTemplateType(templateString); + } + const iconData = iconFromData(objectGraph, adData, { + useCase: 0 /* ArtworkUseCase.Default */, + withJoeColorPlaceholder: true, + overrideTextColorKey: "textColor2", + }); + let backgroundColor = iconData.backgroundColor; + let secondaryTextColor = iconData.textColor; + const rgbWhite = { + type: "rgb", + red: 1, + green: 1, + blue: 1, + }; + // If `backgroundColor` is white, use `secondaryTextColor` as the "primary" color. + // Otherwise, if `secondaryTextColor` is white, remove it and use only `backgroundColor`. + // Native code has a fallback state where only `backgroundColor` is provided, so if + // either color is white, we prefer the single non-white color. + if (isColorEqualToColor(rgbWhite, backgroundColor)) { + backgroundColor = secondaryTextColor; + secondaryTextColor = undefined; + } + else if (isColorEqualToColor(rgbWhite, secondaryTextColor)) { + secondaryTextColor = undefined; + } + const mediumContainer = new MediumAdLockupWithScreenshotsBackground(lockup, [platformScreenshots], isAnimated, secondaryTextColor, backgroundColor, 8); + return new TodayCardMediaMediumLockupWithScreenshots(mediumContainer); +} +//# sourceMappingURL=today-ad-card-builder.js.map \ No newline at end of file diff --git a/node_modules/@jet-app/app-store/tmp/src/common/today/cards/today-app-event-card-builder.js b/node_modules/@jet-app/app-store/tmp/src/common/today/cards/today-app-event-card-builder.js new file mode 100644 index 0000000..c030a5a --- /dev/null +++ b/node_modules/@jet-app/app-store/tmp/src/common/today/cards/today-app-event-card-builder.js @@ -0,0 +1,112 @@ +import { isSome } from "@jet/environment"; +import * as validation from "@jet/environment/json/validation"; +import { isNothing } from "@jet/environment/types/optional"; +import { TodayCardLockupOverlay, TodayCardMediaAppEvent, } from "../../../api/models"; +import { asBooleanOrFalse } from "../../../foundation/json-parsing/server-data"; +import * as mediaAttributes from "../../../foundation/media/attributes"; +import * as mediaRelationship from "../../../foundation/media/relationships"; +import * as color from "../../../foundation/util/color-util"; +import { appEventOrPromotionStartDateFromData } from "../../app-promotions/app-event"; +import { appEventsAreEnabled } from "../../app-promotions/app-promotions-common"; +import { addNextPreferredContentRefreshDate } from "../../refresh/page-refresh-controller"; +import { todayCardArtworkDetails } from "../artwork/today-artwork-util"; +import { applyTodayCardOverridesForAcquisitionStoryIfNecessary } from "../today-card-overlay-util"; +import { cardDisplayStyleFromData, cardStyleFromJoeColorsWithoutFallback, offerEnvironmentForTodayCard, offerStyleForTodayCard, popTodayCardLocation, pushTodayCardLocation, } from "../today-card-util"; +import { createTodayBaseCard } from "./today-base-card-builder"; +/** + * Create TodayCard displaying an app event + * + * @param objectGraph The dependency graph for the App Store + * @param data The media api data to build the card from + * @param cardConfig The configuration for the card + * @param context The parse context for the over all today page + * @param augmentingData that stores some additional responses that may be used to enhance the contents of `data` + * @returns The newly created TodayCard, using a app event media. + */ +export function createTodayAppEventCard(objectGraph, data, cardConfig, context, augmentingData) { + return validation.context("createTodayAppEventCard", () => { + var _a, _b, _c, _d, _e; + if (!appEventsAreEnabled(objectGraph)) { + return null; + } + const appEventData = appEventDataFromData(objectGraph, data); + if (isNothing(appEventData)) { + return null; + } + const appEventCard = createTodayBaseCard(objectGraph, data, cardConfig, context, (clickOptions) => { + // Add app event ID to click options + clickOptions.inAppEventId = appEventData.id; + const parentAppData = mediaRelationship.relationshipData(objectGraph, appEventData, "app"); + if (isSome(parentAppData)) { + clickOptions.relatedSubjectIds = [parentAppData.id]; + } + }); + if (isSome(appEventCard.editorialDisplayOptions)) { + appEventCard.editorialDisplayOptions.useMaterialBlur = true; + } + pushTodayCardLocation(objectGraph, data, cardConfig, context); + // Artwork + const mediaDetails = todayCardArtworkDetails(objectGraph, data, cardConfig); + if (isNothing(mediaDetails)) { + popTodayCardLocation(context); + return null; + } + // Tint and styling + const tintColor = (_b = (_a = mediaDetails.joeColors) === null || _a === void 0 ? void 0 : _a.textColor4) !== null && _b !== void 0 ? _b : color.black; + const artworkBackgroundColor = (_d = (_c = mediaDetails.joeColors) === null || _c === void 0 ? void 0 : _c.bgColor) !== null && _d !== void 0 ? _d : color.black; + const blurStyle = color.isDarkColor(artworkBackgroundColor) ? "dark" : "light"; + // App event + const metricsOptions = { + pageInformation: context.pageInformation, + locationTracker: context.locationTracker, + targetType: "eventModule", + }; + // Card style + appEventCard.style = + (_e = cardStyleFromJoeColorsWithoutFallback(mediaDetails.joeColors, "textColor4")) !== null && _e !== void 0 ? _e : (color.isDarkColor(tintColor) ? "dark" : "light"); + // Offer style + const offerStyle = offerStyleForTodayCard(objectGraph, appEventCard.style); + const editorialKind = mediaAttributes.attributeAsString(data, "label"); + const appEventOrDate = appEventOrPromotionStartDateFromData(objectGraph, appEventData, null, false, false, offerEnvironmentForTodayCard(appEventCard.style), offerStyle, true, metricsOptions, true, true, editorialKind, false, asBooleanOrFalse(cardConfig.allowUnpublishedAppEventPreviews)); + // Return early if we received a Date, as this means the App Event shouldn't be shown yet. + if (isNothing(appEventOrDate) || appEventOrDate instanceof Date) { + addNextPreferredContentRefreshDate(appEventOrDate, context.refreshController); + popTodayCardLocation(context); + return null; + } + const appEvent = appEventOrDate; + // Card + appEventCard.media = new TodayCardMediaAppEvent(appEvent.formattedDates, appEvent.startDate, tintColor, mediaDetails.artworks, mediaDetails.videos, mediaDetails.artworkLayoutsWithMetrics, blurStyle); + if (isSome(appEvent.lockup)) { + appEventCard.overlay = new TodayCardLockupOverlay(appEvent.lockup); + } + // Special post-processing step for Acquisition story cards. + // This is needed to splice in data not included in initial response. + applyTodayCardOverridesForAcquisitionStoryIfNecessary(objectGraph, appEventCard, cardConfig, cardDisplayStyleFromData(data, cardConfig.coercedCollectionTodayCardDisplayStyle), data, augmentingData, context); + popTodayCardLocation(context); + return appEventCard; + }); +} +/** + * @param objectGraph The dependency graph for the App Store + * @param data The media api data to build the card from + * @returns The app event relationship data for this card + */ +function appEventDataFromData(objectGraph, data) { + let appEventData; + // Primary content + const primaryContent = mediaRelationship.relationshipCollection(data, "primary-content"); + if (primaryContent.length > 0) { + appEventData = primaryContent[0]; + } + else { + // Card contents + const cardContents = mediaRelationship.relationshipCollection(data, "card-contents"); + if (cardContents.length === 0) { + return null; + } + appEventData = cardContents[0]; + } + return appEventData; +} +//# sourceMappingURL=today-app-event-card-builder.js.map \ No newline at end of file diff --git a/node_modules/@jet-app/app-store/tmp/src/common/today/cards/today-base-card-builder.js b/node_modules/@jet-app/app-store/tmp/src/common/today/cards/today-base-card-builder.js new file mode 100644 index 0000000..77bd0de --- /dev/null +++ b/node_modules/@jet-app/app-store/tmp/src/common/today/cards/today-base-card-builder.js @@ -0,0 +1,244 @@ +import * as validation from "@jet/environment/json/validation"; +import { isNothing, isSome } from "@jet/environment/types/optional"; +import { ExternalUrlAction, TodayCard, TodayCardActionOverlay, TodayCardMediaArtwork, } from "../../../api/models"; +import { isNull } from "../../../foundation/json-parsing/server-data"; +import * as mediaAttributes from "../../../foundation/media/attributes"; +import { relationshipCollection } from "../../../foundation/media/relationships"; +import * as contentAttributes from "../../content/attributes"; +import { editorialNotesFromData, notesFromData } from "../../content/content"; +import { extractEditorialClientParams } from "../../editorial-pages/editorial-data-util"; +import { editorialItemActionFromData, subtitleFromData } from "../../lockups/lockups"; +import * as metricsHelpersImpressions from "../../metrics/helpers/impressions"; +import { addMetricsEventsToVideo } from "../../metrics/helpers/media"; +import { todayCardArtworkDetails } from "../artwork/today-artwork-util"; +import { isCardDataOnboardingCard } from "../onboarding-cards"; +import { brandedTitleArtworkForCard, cardDisplayStyleFromData, cardStyleFromJoeColors, isCardOTDIntention, relatedCardContentsContentsFromData, todayCardArtworkTitleBackingGradientForKey, todayCardEditorialDisplayOptionsFromData, todayCardMetricsOptions, } from "../today-card-util"; +import { recoMetricsFromTodayItem } from "../today-parse-util"; +import { TodayCardDisplayStyle } from "../today-types"; +/** + * If the title is not supplied for app of the day we use this + */ +const appOfTheDayFallbackTitle = "FEATURED APP"; +/** + * If the title is not supplied for game of the day we use this + */ +const gameOfTheDayFallbackTitle = "FEATURED GAME"; +/** + * Creates a TodayCard used as the base for all other TodayCards + * + * @param objectGraph The dependency graph for the App Store + * @param data The media api data to build the card from + * @param cardConfig The configuration for the card + * @param context The parse context for the over all today page + * @param clickOptionsModifier A function that can modify the click options for the card + * @returns The newly created TodayCard, which can then be modified by other TodayCard builders + */ +export function createTodayBaseCard(objectGraph, data, cardConfig, context, clickOptionsModifier) { + return validation.context("createTodayBaseCard", () => { + const baseCard = new TodayCard(); + const cardDisplayStyle = cardDisplayStyleFromData(data, cardConfig === null || cardConfig === void 0 ? void 0 : cardConfig.coercedCollectionTodayCardDisplayStyle); + // Heading + const heading = cardHeadingFromData(objectGraph, data, cardDisplayStyle, cardConfig); + baseCard.heading = heading; + // Title, title artwork + const title = cardTitleFromData(objectGraph, data, cardConfig); + baseCard.title = title; + const shortTitle = contentAttributes.contentAttributeAsString(objectGraph, data, [ + "shortEditorialNotes", + "name", + ]); + baseCard.shortTitle = shortTitle; + const cardTitleArtwork = brandedTitleArtworkForCard(objectGraph, data); + baseCard.titleArtwork = cardTitleArtwork; + // Description + const inlineDescription = cardDescriptionFromData(objectGraph, data); + baseCard.inlineDescription = inlineDescription; + const metricsOptions = todayCardMetricsOptions(objectGraph, data, cardConfig, context, title); + metricsOptions.adSlotOverride = context.parsedCardCount; + baseCard.clickAction = cardClickAction(objectGraph, data, cardDisplayStyle, cardConfig, context, metricsOptions, clickOptionsModifier); + // Configure impressions + metricsHelpersImpressions.addImpressionsFieldsToTodayCard(objectGraph, baseCard, metricsOptions, heading, cardDisplayStyle, isCardDataOnboardingCard(objectGraph, data)); + baseCard.editorialDisplayOptions = todayCardEditorialDisplayOptionsFromData(objectGraph, data, cardConfig); + return baseCard; + }); +} +/** + * @param objectGraph The dependency graph for the App Store + * @param cardDisplayStyle The display style of the card + * @param data The data to get the branded single app overlay heading from + * @param cardConfig The configuration for the card + * @returns The heading to use on the branded single app overlay + */ +export function cardHeadingFromData(objectGraph, data, cardDisplayStyle, cardConfig) { + var _a, _b; + let heading = null; + if (cardConfig === null || cardConfig === void 0 ? void 0 : cardConfig.useOTDTextStyle) { + if (cardConfig.isHorizontalShelfContext) { + // We don't support branded images or titles for a cards in a horizontal shelf + // so want to show the "APP OF THE DAY" / "GAME OF THE DAY" text as the heading instead. + heading = mediaAttributes.attributeAsString(data, "label"); + } + else { + heading = null; + } + } + else if (isCardOTDIntention(data, cardConfig)) { + heading = + (_a = mediaAttributes.attributeAsString(data, "alternateLabel")) !== null && _a !== void 0 ? _a : mediaAttributes.attributeAsString(data, "label"); + if (isNull(heading) && cardDisplayStyle === TodayCardDisplayStyle.AppOfTheDay) { + heading = appOfTheDayFallbackTitle; + } + else if (isNull(heading) && cardDisplayStyle === TodayCardDisplayStyle.GameOfTheDay) { + heading = gameOfTheDayFallbackTitle; + } + } + else { + switch (cardDisplayStyle) { + case TodayCardDisplayStyle.AppEventCard: + const fallbackCardContents = fallbackCardContentFromData(objectGraph, data); + if (isSome(fallbackCardContents)) { + heading = + (_b = editorialNotesFromData(objectGraph, data, "badge", true)) !== null && _b !== void 0 ? _b : mediaAttributes.attributeAsString(fallbackCardContents, "kind"); + } + break; + default: + heading = mediaAttributes.attributeAsString(data, "label"); + break; + } + } + return heading; +} +/** + * @param objectGraph The dependency graph for the App Store + * @param data The media api data used to determine the title of this card + * @param cardConfig The configuration for the card + * @returns The title to use for this card + */ +function cardTitleFromData(objectGraph, data, cardConfig) { + var _a; + let title = null; + if (cardConfig === null || cardConfig === void 0 ? void 0 : cardConfig.useOTDTextStyle) { + title = + (_a = mediaAttributes.attributeAsString(data, "ofTheDayLabel")) !== null && _a !== void 0 ? _a : mediaAttributes.attributeAsString(data, "label"); + // We need to replace \n characters with
tags to ensure the + // newlines in APP OF THE DAY titles are maintained. The pattern must be a RegExp since string patterns + // only replace the first occurrence. + if (isSome(title)) { + title = title.replace(/\n/g, "
"); + } + } + if (isNothing(title)) { + title = notesFromData(objectGraph, data, "name", true); + } + if (isNothing(title)) { + // Lastly fallback to the first related content title + const fallbackCardContents = fallbackCardContentFromData(objectGraph, data); + title = isSome(fallbackCardContents) ? mediaAttributes.attributeAsString(fallbackCardContents, "name") : null; + } + return title; +} +/** + * @param objectGraph The dependency graph for the App Store + * @param data The media api data used to determine the description of this card + * @returns The title to use for this card + */ +function cardDescriptionFromData(objectGraph, data) { + var _a; + const editorialClientParams = extractEditorialClientParams(objectGraph, data); + const ignoreShortNotes = mediaAttributes.attributeAsBooleanOrFalse(data, "ignoreITunesShortNotes"); + if (ignoreShortNotes || editorialClientParams.suppressNoteShort) { + return null; + } + let description = notesFromData(objectGraph, data, "short", true); + if (isNothing(description) && !editorialClientParams.suppressNoteTagline) { + // Lastly fallback to the first related content title + const fallbackCardContents = fallbackCardContentFromData(objectGraph, data); + if (isSome(fallbackCardContents)) { + description = + (_a = notesFromData(objectGraph, fallbackCardContents, "tagline")) !== null && _a !== void 0 ? _a : subtitleFromData(objectGraph, fallbackCardContents); + } + } + return description; +} +/** + * + * @param objectGraph The dependency graph for the App Store + * @param data The media api data used to build the card + * @returns + */ +function fallbackCardContentFromData(objectGraph, data) { + const primaryContent = relationshipCollection(data, "primary-content"); + if ((primaryContent === null || primaryContent === void 0 ? void 0 : primaryContent.length) === 1) { + return primaryContent[0]; + } + // Card contents + const cardContents = relatedCardContentsContentsFromData(objectGraph, data); + if (cardContents.length === 1) { + return cardContents[0]; + } + return null; +} +/** + * @param objectGraph The dependency graph for the App Store + * @param data The media api data used to build the card this action is for + * @param cardDisplayStyle The display style of the card + * @param cardConfig The configuration for the card + * @param context The parse context for the over all today page + * @param baseMetricsOptions The base metrics options for the card + * @returns The click action used for tapping on the card + */ +function cardClickAction(objectGraph, data, cardDisplayStyle, cardConfig, context, baseMetricsOptions, clickOptionsModifier) { + var _a; + const clickOptions = baseMetricsOptions; + const franchise = mediaAttributes.attributeAsString(data, "label"); + // Metrics: JS: Add franchise/label to todayCard click events + const actionDetails = { + cardType: cardDisplayStyle, + franchise: franchise, + }; + const isOnboardingCard = isCardDataOnboardingCard(objectGraph, data); + if (isOnboardingCard) { + actionDetails["isOnboardingCard"] = isOnboardingCard; + } + clickOptions["actionDetails"] = actionDetails; + if (isSome(clickOptionsModifier)) { + clickOptionsModifier(clickOptions); + } + return editorialItemActionFromData(objectGraph, data, clickOptions, (_a = cardConfig === null || cardConfig === void 0 ? void 0 : cardConfig.clientIdentifierOverride) !== null && _a !== void 0 ? _a : objectGraph.host.clientIdentifier, recoMetricsFromTodayItem(context.currentTodayItem), cardConfig); +} +/** + * @param objectGraph The dependency graph for the App Store + * @param data The media api data used to build the base card + * @param baseCard The base card to add the artwork media to + * @param cropCode The crop code to use for the artwork + * @param context The context for the page were creating the card for + * @returns Whether or not we successfully added artwork media to the base card + */ +export function addArtworkMediaToBaseCard(objectGraph, data, baseCard, cardConfig, context) { + return validation.context("addArtworkMediaToBaseCard", () => { + const ignoreEditorialArt = mediaAttributes.attributeAsBooleanOrFalse(data, "ignoreEditorialArt"); + if (ignoreEditorialArt) { + return false; + } + const mediaDetails = todayCardArtworkDetails(objectGraph, data, cardConfig); + if (isNothing(mediaDetails)) { + return false; + } + if (isSome(context)) { + addMetricsEventsToVideo(objectGraph, mediaDetails === null || mediaDetails === void 0 ? void 0 : mediaDetails.videos[0], { + pageInformation: context.pageInformation, + locationTracker: context.locationTracker, + id: data.id, + }); + } + baseCard.media = new TodayCardMediaArtwork(mediaDetails.artworks, mediaDetails.videos, mediaDetails.artworkLayoutsWithMetrics, todayCardArtworkTitleBackingGradientForKey(objectGraph, data, cardConfig)); + baseCard.style = cardStyleFromJoeColors(mediaDetails.joeColors, "bgColor"); + // External URL + if (baseCard.clickAction instanceof ExternalUrlAction && objectGraph.client.isiOS) { + baseCard.overlay = new TodayCardActionOverlay(baseCard.clickAction); + baseCard.style = "white"; + } + return true; + }); +} +//# sourceMappingURL=today-base-card-builder.js.map \ No newline at end of file diff --git a/node_modules/@jet-app/app-store/tmp/src/common/today/cards/today-branded-card-builder.js b/node_modules/@jet-app/app-store/tmp/src/common/today/cards/today-branded-card-builder.js new file mode 100644 index 0000000..9088bfa --- /dev/null +++ b/node_modules/@jet-app/app-store/tmp/src/common/today/cards/today-branded-card-builder.js @@ -0,0 +1,58 @@ +import * as validation from "@jet/environment/json/validation"; +import { isSome } from "@jet/environment/types/optional"; +import { TodayCardMediaBrandedSingleApp } from "../../../api/models"; +import { isNullOrEmpty } from "../../../foundation/json-parsing/server-data"; +import { deepLinkUrlFromData } from "../../linking/external-deep-link"; +import { todayCardArtworkDetails } from "../artwork/today-artwork-util"; +import { applyTodayCardOverridesForAcquisitionStoryIfNecessary, relatedContentOverlayFromData, } from "../today-card-overlay-util"; +import { cardDisplayStyleFromData, cardStyleFromJoeColors, lockupsForRelatedContent, offerEnvironmentForTodayCard, offerStyleForTodayCard, popTodayCardLocation, pushTodayCardLocation, relatedCardContentsContentsFromData, todayCardArtworkTitleBackingGradientForKey, } from "../today-card-util"; +import { createTodayBaseCard } from "./today-base-card-builder"; +import { createTodaySingleAppCard } from "./today-single-app-card-builder"; +/** + * Create TodayCard displaying the App of the Day and Game of the Day editorial items + * + * @param objectGraph The dependency graph for the App Store + * @param data The media api data to build the card from + * @param cardConfig The configuration for the card + * @param context The parse context for the over all today page + * @param augmentingData that stores some additional responses that may be used to enhance the contents of `data` + * @returns The newly created TodayCard, using an artwork media to display the App of the Day and Game of the Day + */ +export function createTodayBrandedCard(objectGraph, data, cardConfig, context, augmentingData) { + return validation.context("createTodayBrandedCard", () => { + const brandedCard = createTodayBaseCard(objectGraph, data, cardConfig, context); + pushTodayCardLocation(objectGraph, data, cardConfig, context); + // Configure the card style + const mediaDetails = todayCardArtworkDetails(objectGraph, data, cardConfig); + if (isSome(mediaDetails) && + isSome(mediaDetails.joeColors.bgColor) && + (mediaDetails.artworks.length > 0 || mediaDetails.videos.length > 0)) { + brandedCard.style = cardStyleFromJoeColors(mediaDetails === null || mediaDetails === void 0 ? void 0 : mediaDetails.joeColors, "bgColor"); + } + else { + // If we don't have artwork, try building a single app card instead. + popTodayCardLocation(context); + return createTodaySingleAppCard(objectGraph, data, cardConfig, context); + } + const offerStyle = offerStyleForTodayCard(objectGraph, brandedCard.style); + const relatedContent = relatedCardContentsContentsFromData(objectGraph, data); + const relatedContentLockups = lockupsForRelatedContent(objectGraph, relatedContent, cardConfig, context.pageInformation, context.locationTracker, offerEnvironmentForTodayCard(brandedCard.style), offerStyle, deepLinkUrlFromData(objectGraph, data), true); + if (isNullOrEmpty(relatedContentLockups) || relatedContentLockups.length !== 1) { + popTodayCardLocation(context); + return null; + } + if (!cardConfig.isHorizontalShelfContext) { + brandedCard.overlay = relatedContentOverlayFromData(objectGraph, brandedCard, cardConfig, data, relatedContentLockups); + } + // Configure the card media + const brandedAppLockup = relatedContentLockups[0]; + brandedCard.media = new TodayCardMediaBrandedSingleApp(brandedAppLockup.icon, mediaDetails.artworks, mediaDetails.videos, mediaDetails.artworkLayoutsWithMetrics, todayCardArtworkTitleBackingGradientForKey(objectGraph, data, cardConfig)); + brandedCard.media.impressionMetrics = brandedAppLockup.impressionMetrics; + // Special post-processing step for Acquisition story cards. + // This is needed to splice in data not included in initial response. + applyTodayCardOverridesForAcquisitionStoryIfNecessary(objectGraph, brandedCard, cardConfig, cardDisplayStyleFromData(data, cardConfig.coercedCollectionTodayCardDisplayStyle), data, augmentingData, context); + popTodayCardLocation(context); + return brandedCard; + }); +} +//# sourceMappingURL=today-branded-card-builder.js.map \ No newline at end of file diff --git a/node_modules/@jet-app/app-store/tmp/src/common/today/cards/today-full-bleed-image-card-builder.js b/node_modules/@jet-app/app-store/tmp/src/common/today/cards/today-full-bleed-image-card-builder.js new file mode 100644 index 0000000..86cacec --- /dev/null +++ b/node_modules/@jet-app/app-store/tmp/src/common/today/cards/today-full-bleed-image-card-builder.js @@ -0,0 +1,37 @@ +import * as validation from "@jet/environment/json/validation"; +import { deepLinkUrlFromData } from "../../linking/external-deep-link"; +import { applyTodayCardOverridesForAcquisitionStoryIfNecessary, relatedContentOverlayFromData, } from "../today-card-overlay-util"; +import { cardDisplayStyleFromData, lockupsForRelatedContent, offerEnvironmentForTodayCard, offerStyleForTodayCard, popTodayCardLocation, pushTodayCardLocation, relatedCardContentsContentsFromData, } from "../today-card-util"; +import { addArtworkMediaToBaseCard, createTodayBaseCard } from "./today-base-card-builder"; +/** + * Create TodayCard displaying the full bleed image + * + * @param objectGraph The dependency graph for the App Store + * @param data The media api data to build the card from + * @param cardConfig The configuration for the card + * @param context The parse context for the over all today page + * @param augmentingData that stores some additional responses that may be used to enhance the contents of `data` + * @returns The newly created TodayCard, using the full bleed image media. + */ +export function createTodayFullBleedImageCard(objectGraph, data, cardConfig, context, augmentingData) { + return validation.context("createTodayFullBleedImageCard", () => { + const fullBleedImageCard = createTodayBaseCard(objectGraph, data, cardConfig, context); + pushTodayCardLocation(objectGraph, data, cardConfig, context); + const didAddArtworkToCard = addArtworkMediaToBaseCard(objectGraph, data, fullBleedImageCard, cardConfig, context); + if (!didAddArtworkToCard) { + popTodayCardLocation(context); + return null; + } + const relatedContent = relatedCardContentsContentsFromData(objectGraph, data); + const offerStyle = offerStyleForTodayCard(objectGraph, fullBleedImageCard.style); + const relatedContentLockups = lockupsForRelatedContent(objectGraph, relatedContent, cardConfig, context.pageInformation, context.locationTracker, offerEnvironmentForTodayCard(fullBleedImageCard.style), offerStyle, deepLinkUrlFromData(objectGraph, data)); + const overlay = relatedContentOverlayFromData(objectGraph, fullBleedImageCard, cardConfig, data, relatedContentLockups); + fullBleedImageCard.overlay = overlay; + // Special post-processing step for Acquisition story cards. + // This is needed to splice in data not included in initial response. + applyTodayCardOverridesForAcquisitionStoryIfNecessary(objectGraph, fullBleedImageCard, cardConfig, cardDisplayStyleFromData(data, cardConfig.coercedCollectionTodayCardDisplayStyle), data, augmentingData, context); + popTodayCardLocation(context); + return fullBleedImageCard; + }); +} +//# sourceMappingURL=today-full-bleed-image-card-builder.js.map \ No newline at end of file diff --git a/node_modules/@jet-app/app-store/tmp/src/common/today/cards/today-in-app-purchase-card-builder.js b/node_modules/@jet-app/app-store/tmp/src/common/today/cards/today-in-app-purchase-card-builder.js new file mode 100644 index 0000000..d326c5c --- /dev/null +++ b/node_modules/@jet-app/app-store/tmp/src/common/today/cards/today-in-app-purchase-card-builder.js @@ -0,0 +1,62 @@ +import * as validation from "@jet/environment/json/validation"; +import { TodayCardInAppPurchase } from "../../../api/models"; +import { isNullOrEmpty } from "../../../foundation/json-parsing/server-data"; +import { inAppPurchaseLockupFromData } from "../../lockups/lockups"; +import { applyTodayCardOverridesForAcquisitionStoryIfNecessary } from "../today-card-overlay-util"; +import { cardDisplayStyleFromData, popTodayCardLocation, pushTodayCardLocation, relatedCardContentsContentsFromData, } from "../today-card-util"; +import { createTodayBaseCard } from "./today-base-card-builder"; +/** + * Create TodayCard displaying an in app purchase + * + * @param objectGraph The dependency graph for the App Store + * @param data The media api data to build the card from + * @param cardConfig The configuration for the card + * @param context The parse context for the over all today page + * @param augmentingData that stores some additional responses that may be used to enhance the contents of `data` + * @returns The newly created TodayCard, using the in app purchase media. + */ +export function createTodayInAppPurchaseCard(objectGraph, data, cardConfig, context, augmentingData) { + return validation.context("createTodayInAppPurchaseCard", () => { + const inAppPurchaseCard = createTodayBaseCard(objectGraph, data, cardConfig, context); + pushTodayCardLocation(objectGraph, data, cardConfig, context); + const iAPData = inAppPurchaseDataFromRelatedContent(objectGraph, relatedCardContentsContentsFromData(objectGraph, data)); + if (isNullOrEmpty(iAPData)) { + popTodayCardLocation(context); + return null; + } + const lockup = inAppPurchaseLockupFromData(objectGraph, iAPData, { + offerStyle: "colored", + metricsOptions: { + pageInformation: context.pageInformation, + locationTracker: context.locationTracker, + }, + artworkUseCase: 1 /* ArtworkUseCase.LockupIconSmall */, + }); + if (isNullOrEmpty(lockup)) { + popTodayCardLocation(context); + return null; + } + lockup.theme = "infer"; + inAppPurchaseCard.media = new TodayCardInAppPurchase(lockup); + // we need to add impressions to the media here because + // there is no overlay on an IAP inAppPurchaseCard for some reason + inAppPurchaseCard.media.impressionMetrics = lockup.impressionMetrics; + inAppPurchaseCard.media.impressionMetrics.fields["parentId"] = inAppPurchaseCard.impressionMetrics.fields["id"]; + inAppPurchaseCard.style = "white"; + // Special post-processing step for Acquisition story cards. + // This is needed to splice in data not included in initial response. + applyTodayCardOverridesForAcquisitionStoryIfNecessary(objectGraph, inAppPurchaseCard, cardConfig, cardDisplayStyleFromData(data, cardConfig.coercedCollectionTodayCardDisplayStyle), data, augmentingData, context); + popTodayCardLocation(context); + return inAppPurchaseCard; + }); +} +function inAppPurchaseDataFromRelatedContent(objectGraph, relatedContent) { + if (relatedContent.length === 1) { + const contentData = relatedContent[0]; + if (contentData.type === "in-apps") { + return contentData; + } + } + return null; +} +//# sourceMappingURL=today-in-app-purchase-card-builder.js.map \ No newline at end of file diff --git a/node_modules/@jet-app/app-store/tmp/src/common/today/cards/today-list-card-builder.js b/node_modules/@jet-app/app-store/tmp/src/common/today/cards/today-list-card-builder.js new file mode 100644 index 0000000..b803c9f --- /dev/null +++ b/node_modules/@jet-app/app-store/tmp/src/common/today/cards/today-list-card-builder.js @@ -0,0 +1,71 @@ +import * as validation from "@jet/environment/json/validation"; +import { TodayCardMediaList } from "../../../api/models"; +import * as videoDefaults from "../../constants/video-constants"; +import { todayCardArtworkDetails } from "../artwork/today-artwork-util"; +import { applyTodayCardOverridesForAcquisitionStoryIfNecessary } from "../today-card-overlay-util"; +import { applyMultiAppFallbackToCollectionCard, cardDisplayStyleFromData, cardStyleFromJoeColorsWithoutFallback, listFallbackLimit, lockupsForRelatedContent, popTodayCardLocation, pushTodayCardLocation, relatedCardContentsContentsFromData, } from "../today-card-util"; +import { TodayCardDisplayStyle, } from "../today-types"; +import { createTodayBaseCard } from "./today-base-card-builder"; +import { isEligibleForGamesApp } from "../../content/content"; +/** + * Create TodayCard displaying the list of lockups + * + * @param objectGraph The dependency graph for the App Store + * @param data The media api data to build the card from + * @param cardConfig The configuration for the card + * @param context The parse context for the over all today page + * @param augmentingData that stores some additional responses that may be used to enhance the contents of `data` + * @returns The newly created TodayCard, using a list or numbered list media. + */ +export function createTodayListCard(objectGraph, data, cardConfig, context, augmentingData) { + return validation.context("createTodayListCard", () => { + var _a, _b, _c; + const listCard = createTodayBaseCard(objectGraph, data, cardConfig, context); + pushTodayCardLocation(objectGraph, data, cardConfig, context); + cardConfig.useJoeColorIconPlaceholder = true; + let relatedContents = relatedCardContentsContentsFromData(objectGraph, data); + if (preprocessor.GAMES_TARGET) { + // Filtering out non-eligible games as they can be used as content for stories collection. + // see `createFallbackListShelf` in article.ts. + relatedContents = relatedContents.filter((item) => isEligibleForGamesApp(item)); + } + const listLockups = lockupsForRelatedContent(objectGraph, relatedContents, cardConfig, context.pageInformation, context.locationTracker, undefined, undefined, undefined); + if (listLockups.length === 0) { + popTodayCardLocation(context); + return null; + } + cardConfig.canDisplayArcadeOfferButton = false; + // We require at least `listFallbackLimit` lockups for the list card + // If this is for use on top of an article its ok to have less than `listFallbackLimit` + if (listLockups.length < listFallbackLimit(objectGraph) && cardConfig.enableListCardToMultiAppFallback) { + applyMultiAppFallbackToCollectionCard(objectGraph, data, listLockups, listCard); + } + else { + const cardDisplayStyle = cardDisplayStyleFromData(data, cardConfig.coercedCollectionTodayCardDisplayStyle); + if (cardDisplayStyle === TodayCardDisplayStyle.NumberedList) { + let index = 1; + for (const lockup of listLockups) { + lockup.ordinal = `${index}`; + index++; + } + } + const mediaDetails = todayCardArtworkDetails(objectGraph, data, cardConfig); + const cardStyle = cardStyleFromJoeColorsWithoutFallback(mediaDetails === null || mediaDetails === void 0 ? void 0 : mediaDetails.joeColors, "bgColor"); + const isModernListCard = objectGraph.host.isiOS; + // Since list videos are very wide (21:9) and ~50% masked, we prevent them from going fullscreen + mediaDetails === null || mediaDetails === void 0 ? void 0 : mediaDetails.videos.forEach((video) => { + video.canPlayFullScreen = false; + video.playbackControls = videoDefaults.noControls(objectGraph); + video.autoPlayPlaybackControls = videoDefaults.noControls(objectGraph); + }); + listCard.style = isModernListCard ? undefined : "white"; + listCard.media = new TodayCardMediaList(listLockups, (_a = mediaDetails === null || mediaDetails === void 0 ? void 0 : mediaDetails.artworks) !== null && _a !== void 0 ? _a : [], (_b = mediaDetails === null || mediaDetails === void 0 ? void 0 : mediaDetails.videos) !== null && _b !== void 0 ? _b : [], (_c = mediaDetails === null || mediaDetails === void 0 ? void 0 : mediaDetails.artworkLayoutsWithMetrics) !== null && _c !== void 0 ? _c : [], undefined, isModernListCard ? cardStyle !== "white" : cardStyle === "dark"); + } + // Special post-processing step for Acquisition story cards. + // This is needed to splice in data not included in initial response. + applyTodayCardOverridesForAcquisitionStoryIfNecessary(objectGraph, listCard, cardConfig, cardDisplayStyleFromData(data, cardConfig.coercedCollectionTodayCardDisplayStyle), data, augmentingData, context); + popTodayCardLocation(context); + return listCard; + }); +} +//# sourceMappingURL=today-list-card-builder.js.map \ No newline at end of file diff --git a/node_modules/@jet-app/app-store/tmp/src/common/today/cards/today-river-card-builder.js b/node_modules/@jet-app/app-store/tmp/src/common/today/cards/today-river-card-builder.js new file mode 100644 index 0000000..d93fa7e --- /dev/null +++ b/node_modules/@jet-app/app-store/tmp/src/common/today/cards/today-river-card-builder.js @@ -0,0 +1,62 @@ +import * as validation from "@jet/environment/json/validation"; +import { TodayCardMediaRiver } from "../../../api/models"; +import { isDarkColor, rgbWith } from "../../../foundation/util/color-util"; +import { applyTodayCardOverridesForAcquisitionStoryIfNecessary, relatedContentOverlayFromData, } from "../today-card-overlay-util"; +import { applyMultiAppFallbackToCollectionCard, cardDisplayStyleFromData, gridFallbackLimit, lockupsForCollectionCardFromData, popTodayCardLocation, pushTodayCardLocation, } from "../today-card-util"; +import { createTodayBaseCard } from "./today-base-card-builder"; +/** + * Create TodayCard displaying the river of lockups + * + * @param objectGraph The dependency graph for the App Store + * @param data The media api data to build the card from + * @param cardConfig The configuration for the card + * @param context The parse context for the over all today page + * @param augmentingData that stores some additional responses that may be used to enhance the contents of `data` + * @returns The newly created TodayCard, using a river media. + */ +export function createTodayRiverCard(objectGraph, data, cardConfig, context, augmentingData) { + return validation.context("createTodayRiverCard", () => { + const riverCard = createTodayBaseCard(objectGraph, data, cardConfig, context); + cardConfig.useJoeColorIconPlaceholder = true; + pushTodayCardLocation(objectGraph, data, cardConfig, context); + const shouldIncludeLockupClickActions = objectGraph.client.isWeb; + const riverLockups = lockupsForCollectionCardFromData(objectGraph, data, cardConfig, context, shouldIncludeLockupClickActions); + if (riverLockups.length === 0) { + popTodayCardLocation(context); + return null; + } + cardConfig.canDisplayArcadeOfferButton = false; + if (riverLockups.length < gridFallbackLimit(objectGraph)) { + // P2: Some Today cards not showing on Cinar + // less that `gridFallbackLimit` lockups gets a fallback card on Emet only + applyMultiAppFallbackToCollectionCard(objectGraph, data, riverLockups, riverCard); + } + else { + riverCard.style = "dark"; + replaceHighLuminanceIconColorsInLockups(riverLockups); + riverCard.media = new TodayCardMediaRiver(riverLockups); + } + if (objectGraph.client.isWatch) { + riverCard.overlay = relatedContentOverlayFromData(objectGraph, riverCard, cardConfig, data, riverLockups); + } + // Special post-processing step for Acquisition story cards. + // This is needed to splice in data not included in initial response. + applyTodayCardOverridesForAcquisitionStoryIfNecessary(objectGraph, riverCard, cardConfig, cardDisplayStyleFromData(data, cardConfig.coercedCollectionTodayCardDisplayStyle), data, augmentingData, context); + popTodayCardLocation(context); + return riverCard; + }); +} +/** + * Replace any icon background colors with luminance > 0.9 with grey color. + * This ensure that river background colors don't compete with the overlayed white text. + * + * @param riverLockups The river lockups. + */ +function replaceHighLuminanceIconColorsInLockups(riverLockups) { + for (const lockup of riverLockups) { + if (!isDarkColor(lockup.icon.backgroundColor, 90)) { + lockup.icon.backgroundColor = rgbWith(0.8, 0.8, 0.8); + } + } +} +//# sourceMappingURL=today-river-card-builder.js.map \ No newline at end of file diff --git a/node_modules/@jet-app/app-store/tmp/src/common/today/cards/today-short-image-card-builder.js b/node_modules/@jet-app/app-store/tmp/src/common/today/cards/today-short-image-card-builder.js new file mode 100644 index 0000000..c50836a --- /dev/null +++ b/node_modules/@jet-app/app-store/tmp/src/common/today/cards/today-short-image-card-builder.js @@ -0,0 +1,42 @@ +import * as validation from "@jet/environment/json/validation"; +import { deepLinkUrlFromData } from "../../linking/external-deep-link"; +import { applyTodayCardOverridesForAcquisitionStoryIfNecessary, relatedContentOverlayFromData, } from "../today-card-overlay-util"; +import { cardDisplayStyleFromData, lockupsForRelatedContent, offerEnvironmentForTodayCard, offerStyleForTodayCard, popTodayCardLocation, pushTodayCardLocation, relatedCardContentsContentsFromData, } from "../today-card-util"; +import { addArtworkMediaToBaseCard, createTodayBaseCard } from "./today-base-card-builder"; +import { addSingleAppFallbackToCard } from "./today-single-app-card-builder"; +/** + * Create TodayCard displaying the full bleed image + * + * @param objectGraph The dependency graph for the App Store + * @param data The media api data to build the card from + * @param cardConfig The configuration for the card + * @param context The parse context for the over all today page + * @param augmentingData that stores some additional responses that may be used to enhance the contents of `data` + * @returns The newly created TodayCard, using the full bleed image media. + */ +export function createTodayShortImageCard(objectGraph, data, cardConfig, context, augmentingData) { + return validation.context("createTodayShortImageCard", () => { + const shortImageCard = createTodayBaseCard(objectGraph, data, cardConfig, context); + pushTodayCardLocation(objectGraph, data, cardConfig, context); + const didAddArtworkToCard = addArtworkMediaToBaseCard(objectGraph, data, shortImageCard, cardConfig, context); + let didAddSingleAppFallback = false; + const relatedContent = relatedCardContentsContentsFromData(objectGraph, data); + const offerStyle = offerStyleForTodayCard(objectGraph, shortImageCard.style); + const relatedContentLockups = lockupsForRelatedContent(objectGraph, relatedContent, cardConfig, context.pageInformation, context.locationTracker, offerEnvironmentForTodayCard(shortImageCard.style), offerStyle, deepLinkUrlFromData(objectGraph, data)); + const overlay = relatedContentOverlayFromData(objectGraph, shortImageCard, cardConfig, data, relatedContentLockups); + shortImageCard.overlay = overlay; + if (!didAddArtworkToCard && relatedContent.length === 1) { + didAddSingleAppFallback = addSingleAppFallbackToCard(objectGraph, data, shortImageCard, relatedContent, cardConfig, context); + } + if (!didAddArtworkToCard && !didAddSingleAppFallback) { + popTodayCardLocation(context); + return null; + } + // Special post-processing step for Acquisition story cards. + // This is needed to splice in data not included in initial response. + applyTodayCardOverridesForAcquisitionStoryIfNecessary(objectGraph, shortImageCard, cardConfig, cardDisplayStyleFromData(data, cardConfig.coercedCollectionTodayCardDisplayStyle), data, augmentingData, context); + popTodayCardLocation(context); + return shortImageCard; + }); +} +//# sourceMappingURL=today-short-image-card-builder.js.map \ No newline at end of file diff --git a/node_modules/@jet-app/app-store/tmp/src/common/today/cards/today-single-app-card-builder.js b/node_modules/@jet-app/app-store/tmp/src/common/today/cards/today-single-app-card-builder.js new file mode 100644 index 0000000..18828c8 --- /dev/null +++ b/node_modules/@jet-app/app-store/tmp/src/common/today/cards/today-single-app-card-builder.js @@ -0,0 +1,81 @@ +import * as validation from "@jet/environment/json/validation"; +import { TodayCardMediaAppIcon, TodayCardMediaList, TodayCardParagraphOverlay } from "../../../api/models"; +import { isDefinedNonNull } from "../../../foundation/json-parsing/server-data"; +import { deepLinkUrlFromData } from "../../linking/external-deep-link"; +import { applyTodayCardOverridesForAcquisitionStoryIfNecessary, relatedContentOverlayFromData, } from "../today-card-overlay-util"; +import { cardDisplayStyleFromData, lockupsForRelatedContent, offerEnvironmentForTodayCard, offerStyleForTodayCard, popTodayCardLocation, pushTodayCardLocation, relatedCardContentsContentsFromData, } from "../today-card-util"; +import { addArtworkMediaToBaseCard, createTodayBaseCard } from "./today-base-card-builder"; +/** + * Create TodayCard displaying the SingleApp card display style + * + * @param objectGraph The dependency graph for the App Store + * @param data The media api data to build the card from + * @param cardConfig The configuration for the card + * @param context The parse context for the over all today page + * @param augmentingData that stores some additional responses that may be used to enhance the contents of `data` + * @returns The newly created TodayCard, either artwork or the single app icon. + */ +export function createTodaySingleAppCard(objectGraph, data, cardConfig, context, augmentingData) { + return validation.context("createTodaySingleAppCard", () => { + const singleAppCard = createTodayBaseCard(objectGraph, data, cardConfig, context); + pushTodayCardLocation(objectGraph, data, cardConfig, context); + // Next prefer artwork card, and then fallback to substyles + const didAddArtworkToCard = addArtworkMediaToBaseCard(objectGraph, data, singleAppCard, cardConfig, context); + const relatedContent = relatedCardContentsContentsFromData(objectGraph, data); + const relatedContentLockups = lockupsForRelatedContent(objectGraph, relatedContent, cardConfig, context.pageInformation, context.locationTracker, "todayCard", null, deepLinkUrlFromData(objectGraph, data)); + const overlay = relatedContentOverlayFromData(objectGraph, singleAppCard, cardConfig, data, relatedContentLockups); + if (isDefinedNonNull(overlay) && overlay instanceof TodayCardParagraphOverlay) { + overlay.style = "white"; + } + singleAppCard.overlay = overlay; + if (!didAddArtworkToCard && relatedContent.length === 1) { + const didAddSingleAppFallback = addSingleAppFallbackToCard(objectGraph, data, singleAppCard, relatedContent, cardConfig, context); + if (!didAddSingleAppFallback) { + popTodayCardLocation(context); + return null; + } + } + // Special post-processing step for Acquisition story cards. + // This is needed to splice in data not included in initial response. + applyTodayCardOverridesForAcquisitionStoryIfNecessary(objectGraph, singleAppCard, cardConfig, cardDisplayStyleFromData(data, cardConfig.coercedCollectionTodayCardDisplayStyle), data, augmentingData, context); + popTodayCardLocation(context); + return singleAppCard; + }); +} +/** + * Adds a single app fallback to the card. + * + * @param objectGraph - The object graph of the app store. + * @param data - The media data. + * @param card - The today card. + * @param relatedContent - The related content data. + * @param cardConfig - The configuration for the today card. + * @param context - The parse context for today card. + * @returns Returns true or false based on whether we could create a single app fallback. + */ +export function addSingleAppFallbackToCard(objectGraph, data, card, relatedContent, cardConfig, context) { + if (relatedContent.length !== 1) { + return false; + } + cardConfig.useJoeColorIconPlaceholder = true; + card.style = "dark"; + const offerStyle = offerStyleForTodayCard(objectGraph, card.style); + const relatedContentLockups = lockupsForRelatedContent(objectGraph, relatedContent, cardConfig, context.pageInformation, context.locationTracker, offerEnvironmentForTodayCard(card.style), offerStyle, deepLinkUrlFromData(objectGraph, data)); + if (relatedContentLockups.length !== 1) { + return false; + } + const lockup = relatedContentLockups[0]; + // tvOS doesn't have layout to properly render appIcon media. + // However, `media` can't be simply removed from TodayCard, as it is a required field in native code. + // This `TodayCardMediaList` works as an empty media placeholder, + // that allows to render text from TodayCard but not the image. + // From StarlightB AppIcon is disabled in native code and this check can be removed in the next major release. + if (objectGraph.client.isTV && !objectGraph.props.enabled("disableAppIconMediaTodayHeader")) { + card.media = new TodayCardMediaList([], [], [], [], undefined, undefined); + } + else { + card.media = new TodayCardMediaAppIcon(lockup.icon); + } + return true; +} +//# sourceMappingURL=today-single-app-card-builder.js.map \ No newline at end of file diff --git a/node_modules/@jet-app/app-store/tmp/src/common/today/cards/today-video-card-builder.js b/node_modules/@jet-app/app-store/tmp/src/common/today/cards/today-video-card-builder.js new file mode 100644 index 0000000..77516f6 --- /dev/null +++ b/node_modules/@jet-app/app-store/tmp/src/common/today/cards/today-video-card-builder.js @@ -0,0 +1,33 @@ +import * as validation from "@jet/environment/json/validation"; +import { deepLinkUrlFromData } from "../../linking/external-deep-link"; +import { applyTodayCardOverridesForAcquisitionStoryIfNecessary, relatedContentOverlayFromData, } from "../today-card-overlay-util"; +import { cardDisplayStyleFromData, lockupsForRelatedContent, offerStyleForTodayCard, popTodayCardLocation, pushTodayCardLocation, relatedCardContentsContentsFromData, } from "../today-card-util"; +import { addArtworkMediaToBaseCard, createTodayBaseCard } from "./today-base-card-builder"; +/** + * Create TodayCard displaying a video + * + * @param objectGraph The dependency graph for the App Store + * @param data The media api data to build the card from + * @param cardConfig The configuration for the card + * @param context The parse context for the over all today page + * @param augmentingData that stores some additional responses that may be used to enhance the contents of `data` + * @returns The newly created TodayCard, using the video media. + */ +export function createTodayVideoCard(objectGraph, data, cardConfig, context, augmentingData) { + return validation.context("createTodayVideoCard", () => { + const videoCard = createTodayBaseCard(objectGraph, data, cardConfig, context); + addArtworkMediaToBaseCard(objectGraph, data, videoCard, cardConfig, context); + pushTodayCardLocation(objectGraph, data, cardConfig, context); + const offerStyle = offerStyleForTodayCard(objectGraph, videoCard.style); + const relatedContent = relatedCardContentsContentsFromData(objectGraph, data); + const relatedContentLockups = lockupsForRelatedContent(objectGraph, relatedContent, cardConfig, context.pageInformation, context.locationTracker, "todayCard", offerStyle, deepLinkUrlFromData(objectGraph, data)); + const overlay = relatedContentOverlayFromData(objectGraph, videoCard, cardConfig, data, relatedContentLockups); + videoCard.overlay = overlay; + // Special post-processing step for Acquisition story cards. + // This is needed to splice in data not included in initial response. + applyTodayCardOverridesForAcquisitionStoryIfNecessary(objectGraph, videoCard, cardConfig, cardDisplayStyleFromData(data, cardConfig.coercedCollectionTodayCardDisplayStyle), data, augmentingData, context); + popTodayCardLocation(context); + return videoCard; + }); +} +//# sourceMappingURL=today-video-card-builder.js.map \ No newline at end of file -- cgit v1.2.3