import { isNothing } from "@jet/environment"; 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 { createArtworkForResource } from "../../content/artwork/artwork"; import * as lockupsEditorialContext from "../../lockups/editorial-context"; import * as metricsHelpersClicks from "../../metrics/helpers/clicks"; import * as metricsHelpersImpressions from "../../metrics/helpers/impressions"; import * as metricsHelpersLocation from "../../metrics/helpers/location"; import { GroupingShelfController } from "./grouping-shelf-controller"; import * as groupingShelfControllerCommon from "./grouping-shelf-controller-common"; export class GroupingLinkShelfController extends GroupingShelfController { // region Constructors constructor() { super("GroupingLinkShelfController"); this.supportedFeaturedContentIds = new Set([ 437 /* groupingTypes.FeaturedContentID.AppStore_LinkList */, 265 /* groupingTypes.FeaturedContentID.Sundance_LinkList */, ]); } // endregion // region Shelf Creation Prerequisites /** * For a given mediaApiData extract the actual shelfContents array needed to render this shelf * * @param mediaApiData The outer shelfContents object containing the shelf contents */ initialShelfDataFromGroupingMediaApiData(objectGraph, mediaApiData) { let shelfContents = mediaRelationship.relationshipCollection(mediaApiData, "children"); if (serverData.isNullOrEmpty(shelfContents)) { shelfContents = mediaAttributes.attributeAsArrayOrEmpty(mediaApiData, "links"); } return { shelfContents: shelfContents }; } /** * For a given url that this controller handles, we should return a promise that will result in the `ShelfData` * needed to render this shelf * * @param objectGraph The App Store dependency graph * @param shelfUrl The url that this controller handled on a secondary fetch * @param parameters The extracted parameters from the shelf url */ async secondaryShelfDataForShelfUrl(objectGraph, shelfUrl, shelfToken, parameters) { return await GroupingShelfController.secondaryGroupingShelfDataForShelfUrl(objectGraph, shelfUrl, shelfToken, parameters); } /** * For a given mediaApiData create an updated shelf token that contains all the additional data for this specific shelf type * * @param objectGraph The App Store dependency graph * @param baseShelfToken The base grouping shelf token created by the grouping-controller * @param mediaApiData The outer data object containing the FC properties and data * @param groupingParseContext The parse context for the grouping page so far */ shelfTokenFromBaseTokenAndMediaApiData(objectGraph, mediaApiData, baseShelfToken, groupingParseContext) { const linkShelfToken = { ...baseShelfToken, shouldHideShelf: mediaAttributes.attributeAsBooleanOrFalse(mediaApiData, "hide"), areContentLinks: serverData.isDefinedNonNullNonEmpty(mediaRelationship.relationshipCollection(mediaApiData, "children")), }; linkShelfToken.clientIdentifierOverride = lockupsEditorialContext.clientIdentifierForEditorialContextInData(objectGraph, mediaApiData); return linkShelfToken; } // endregion // region Shelf Creation /** * * @param objectGraph The App Store dependency graph * @param shelfToken The shelf shelfToken for this current shelf creation request * @param shelfData The media api shelfContents array for this shelf * @param groupingParseContext The parse context used to generate the grouping page on the initial page load, * this will be missing when this controller renders a secondary or incomplete shelf fetch. */ _createShelf(objectGraph, shelfToken, shelfData, groupingParseContext) { if (shelfToken.shouldHideShelf) { return null; } const items = []; for (let linkIndex = 0; linkIndex < shelfData.shelfContents.length; linkIndex++) { const link = shelfData.shelfContents[linkIndex]; const metricsBase = { targetType: "link", pageInformation: shelfToken.metricsPageInformation, locationTracker: shelfToken.metricsLocationTracker, }; if (shelfToken.areContentLinks) { metricsBase.recoMetricsData = mediaDataStructure.metricsFromMediaApiObject(link); } let action = null; if (shelfToken.isSearchLandingPage) { const searchAdAction = this.trendingSearchLinkFromData(objectGraph, link, shelfToken.metricsLocationTracker); if (serverData.isNull(searchAdAction) || serverData.isNull(searchAdAction.action)) { continue; } metricsHelpersImpressions.addImpressionFields(objectGraph, searchAdAction === null || searchAdAction === void 0 ? void 0 : searchAdAction.action, { ...metricsBase, kind: "link", softwareType: serverData.asBooleanOrFalse(groupingParseContext === null || groupingParseContext === void 0 ? void 0 : groupingParseContext.isArcadePage) ? "Arcade" : null, title: searchAdAction.action.title, id: `${linkIndex}`, idType: "sequential", }); action = searchAdAction; } else { const metadata = groupingShelfControllerCommon.metadataForFCData(objectGraph, link, shelfToken, false, null, metricsBase, null); if (serverData.isNullOrEmpty(metadata) || serverData.isNullOrEmpty(metadata.action.title)) { continue; } action = metadata.action; const contentId = groupingShelfControllerCommon.contentIdFromContentItem(objectGraph, link); if (contentId) { metricsHelpersImpressions.addImpressionFields(objectGraph, action, { ...metricsBase, kind: "link", softwareType: serverData.asBooleanOrFalse(groupingParseContext === null || groupingParseContext === void 0 ? void 0 : groupingParseContext.isArcadePage) ? "Arcade" : null, title: action.title, id: contentId, }); } } if (serverData.isNullOrEmpty(action)) { continue; } items.push(action); metricsHelpersLocation.nextPosition(shelfToken.metricsLocationTracker); } if (serverData.isNullOrEmpty(items)) { return null; } const actionsShouldHaveArtwork = shelfToken.isSearchLandingPage && (objectGraph.client.isPhone || objectGraph.client.isVision) && items.length >= 6; if (actionsShouldHaveArtwork) { for (const item of items) { if (item instanceof models.SearchAdAction) { item.action.artwork = createArtworkForResource(objectGraph, "systemimage://magnifyingglass"); } } } const shelf = new models.Shelf("action"); shelf.isHorizontal = false; shelf.items = items; shelf.title = shelfToken.title; shelf.subtitle = shelfToken.subtitle; shelf.presentationHints = { isWidthConstrained: true }; shelf.url = groupingShelfControllerCommon.createShelfTokenUrlIfNecessaryForShelf(objectGraph, shelf, shelfToken); if (shelfToken.isSearchLandingPage && (objectGraph.client.isPhone || objectGraph.client.isPad)) { shelf.contentsMetadata = { type: "searchLandingTrendingSection", numberOfColumns: items.length >= 6 ? 2 : 1, }; } return shelf; } // region Helpers trendingSearchLinkFromData(objectGraph, link, locationTracker) { const term = serverData.asString(link, "label"); if (isNothing(term) || term.length === 0) { return null; } const searchAction = new models.SearchAction(term, term, null, "suggested"); metricsHelpersClicks.addEventsToSearchAction(objectGraph, searchAction, "button", locationTracker); metricsHelpersLocation.nextPosition(locationTracker); return new models.SearchAdAction(searchAction); } } //# sourceMappingURL=grouping-link-shelf-controller.js.map