import { isSome } from "@jet/environment"; import { isNothing } from "@jet/environment/types/optional"; import { marketingItemContextFromString, TodayCardArcadeLockupOverlay, TodayCardLockupListOverlay, TodayCardLockupOverlay, TodayCardThreeLineOverlay, } from "../../api/models"; import * as mediaAttributes from "../../foundation/media/attributes"; import { upsellFromContentsOfUpsellResponse, upsellFromRelationshipOf, } from "../arcade/arcade-common"; import { extractEditorialClientParams } from "../editorial-pages/editorial-data-util"; import { arcadeLockupFromData } from "../lockups/lockups"; import { todayCardArtworkDetails } from "./artwork/today-artwork-util"; import { cardStyleFromJoeColors, offerStyleForTodayCard } from "./today-card-util"; // MARK: - Paragraph / Related Content Overlays /** * @param objectGraph The dependency graph for the App Store * @param card The card being built that we'd like to add the overlay to * @param cardConfig The configuration used to create the card * @param data The media api data to build the card from * @param relatedContentLockups The lockups created from the related content * @returns A TodayCardLockupOverlay, TodayCardLockupListOverlay, TodayCardThreeLineOverlay, depending on whether * the card should ignore the short notes, has a deep link, or has related content lockups. */ export function relatedContentOverlayFromData(objectGraph, card, cardConfig, data, relatedContentLockups) { const editorialClientParams = extractEditorialClientParams(objectGraph, data); if (isSome(editorialClientParams.suppressLockup) && editorialClientParams.suppressLockup) { return null; } let overlay = null; const hasSingleLockup = isSome(relatedContentLockups) && relatedContentLockups.length === 1; const hasMultipleLockups = isSome(relatedContentLockups) && relatedContentLockups.length > 1; const hasThreeLineCards = objectGraph.client.isMac || objectGraph.client.isWatch; if (hasThreeLineCards) { overlay = new TodayCardThreeLineOverlay(card.heading, card.title, card.inlineDescription); } else if (hasSingleLockup) { overlay = new TodayCardLockupOverlay(relatedContentLockups[0]); } else if (hasMultipleLockups) { overlay = new TodayCardLockupListOverlay(relatedContentLockups); } return overlay; } // MARK: - Arcade Acquisitions /** * Applies a set of overrides to an existing `card` built by the standard pipelie using the contents of augmenting data fetched externally. * This function provides support for parsing editorial-items fetched for: * - Today * - Articles (with data augmentation) * - Groupings (with data augmentation) * * @param card Card to override behavior of. * @param data Original data `card` was created with * @param augmentingData Data used to augment `card`. * @param metricsContext Metrics context to use for overrides. * @returns Overridden Card, or `null` if overrides failed. Note that `card` is modified *IN PLACE*. */ export function applyTodayCardOverridesForAcquisitionStoryIfNecessary(objectGraph, card, cardConfig, cardDisplayStyle, data, augmentingData, context) { const isAcquisitionStory = mediaAttributes.attributeAsBooleanOrFalse(data, "isAcquisition"); if (!isAcquisitionStory) { return; } // Try to build upsell data from upsell relationship, if that exists. let upsellData = upsellFromRelationshipOf(objectGraph, data); if (isNothing(upsellData) && isSome(augmentingData)) { // Fallback: Try to build off upsell data off `augmentingData`. This relies on the caller being proactive about fetching upsell separately for endpoints that don't return upsell relationship. upsellData = upsellFromContentsOfUpsellResponse(objectGraph, augmentingData.arcadeUpsellEditorialResponse); } // Override: Arcade Overlay const arcadeLockupOverlay = arcadeOverlayFromData(objectGraph, data, card, cardConfig, cardDisplayStyle, upsellData, context); if (arcadeLockupOverlay) { card.overlay = arcadeLockupOverlay; card.impressionMetrics.fields["displaysArcadeUpsell"] = true; // If we're overriding the card style used with the overlay we should also update the style for the card itself. const style = cardStyleForArcadeOverlay(objectGraph, data, card, cardConfig); if (card.style !== style) { card.style = style; } } } /** * Whether or not current platform supports arcade overlay. */ function currentPlatformSupportsArcadeOverlay(objectGraph) { // Check if on platform that will actually display data. const platform = objectGraph.host.platform; const platformSupportsArcadeLockupOverlay = platform === "iOS" || platform === "macOS"; return platformSupportsArcadeLockupOverlay; } /** * Creates an instance of `TodayCardArcadeLockupOverlay` to use for Acquisition Editorial Items. * @param upsellData Upsell data containing editorial and iAP data. * @param metricsContext Metrics context to use for generated lockup. */ function arcadeOverlayFromData(objectGraph, data, card, cardConfig, cardDisplayStyle, upsellData, context) { if (!currentPlatformSupportsArcadeOverlay(objectGraph)) { return null; } const style = cardStyleForArcadeOverlay(objectGraph, data, card, cardConfig); const offerStyle = offerStyleForTodayCard(objectGraph, style); const lockup = arcadeLockupFromData(objectGraph, upsellData, context, marketingItemContextFromString("editorialItem"), offerStyle, "todayCard"); return new TodayCardArcadeLockupOverlay(lockup); } /** * Returns the `TodayCardStyle` that should be used for the arcade overlay. * Some cards use different styles when fetched as part of an article vs. today feed. Using the media artwork to determine the * cardStyle in these cases avoids issues with today cards changing styles when transitionin from to today feed to articles. */ function cardStyleForArcadeOverlay(objectGraph, data, card, cardConfig) { const useCardStyle = !cardConfig.enableListCardToMultiAppFallback; const mediaDetails = todayCardArtworkDetails(objectGraph, data, cardConfig); const styleFromMedia = cardStyleFromJoeColors(mediaDetails === null || mediaDetails === void 0 ? void 0 : mediaDetails.joeColors); return useCardStyle ? card.style : styleFromMedia; } //# sourceMappingURL=today-card-overlay-util.js.map