import * as models from "../../../api/models"; import * as serverData from "../../../foundation/json-parsing/server-data"; import * as mediaDataStructure from "../../../foundation/media/data-structure"; import * as mediaNetwork from "../../../foundation/media/network"; import { ResponseMetadata } from "../../../foundation/network/network"; import * as color from "../../../foundation/util/color-util"; import * as arcadeCommon from "../../arcade/arcade-common"; import * as content from "../../content/content"; 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 GroupingArcadeFooterShelfController extends GroupingShelfController { // region Constructors constructor() { super("GroupingArcadeFooterShelfController"); this.supportedFeaturedContentIds = new Set([-1 /* groupingTypes.FeaturedContentID.Native_GroupingShelf */]); this.supportedNativeGroupingShelfIds = new Set([1 /* groupingTypes.NativeGroupingShelfID.Arcade_SeeAllGamesFooter */]); } // endregion // region Metrics shouldImpressShelf() { return false; } // 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) { return { shelfContents: mediaDataStructure.dataCollectionFromResultsListContainer(mediaApiData), responseTimingValues: null, }; } /** * 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) { const footerRequest = arcadeCommon.arcadeAppsRequestForIcons(objectGraph, this.numberOfIconsForArcadeAppGrid(objectGraph.client.deviceType)); return await mediaNetwork .fetchData(objectGraph, footerRequest) .then((mediaApiData) => { const shelfData = this.initialShelfDataFromGroupingMediaApiData(objectGraph, mediaApiData); shelfData.responseTimingValues = mediaApiData[ResponseMetadata.timingValues]; return shelfData; }); } /** * 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 footerShelfToken = { ...baseShelfToken, shouldIncludeShelfUrl: baseShelfToken.isFirstRender, }; footerShelfToken.showingPlaceholders = baseShelfToken.isFirstRender; return footerShelfToken; } // 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) { const footer = new models.ArcadeFooter(); const shelf = new models.Shelf("arcadeFooter"); shelf.items = [footer]; const impressionOptions = { targetType: "arcadeSeeAllGamesFooter", pageInformation: shelfToken.metricsPageInformation, locationTracker: shelfToken.metricsLocationTracker, title: objectGraph.loc.string("Arcade.SeeAllGames.Button.Title"), id: shelfToken.id, kind: "footer", softwareType: "Arcade", }; metricsHelpersImpressions.addImpressionFields(objectGraph, footer, impressionOptions); metricsHelpersLocation.pushContentLocation(objectGraph, impressionOptions, impressionOptions.title); footer.buttonAction = arcadeCommon.seeAllArcadeGamesPageFlowAction(objectGraph, "releaseDate", shelfToken.metricsPageInformation, shelfToken.metricsLocationTracker); const buttonImpressionOptions = { targetType: "button", pageInformation: shelfToken.metricsPageInformation, locationTracker: shelfToken.metricsLocationTracker, title: footer.buttonAction.title, id: "arcade-see-all-games-button", kind: "button", softwareType: "Arcade", }; metricsHelpersImpressions.addImpressionFields(objectGraph, footer.buttonAction, buttonImpressionOptions); metricsHelpersLocation.popLocation(impressionOptions.locationTracker); const termsAndConditionsUrl = objectGraph.bag.termsAndConditionsURL; const shouldAddTermsAndConditions = !serverData.isNull(termsAndConditionsUrl) && objectGraph.client.deviceType !== "tv"; if (objectGraph.client.isiOS) { if (shouldAddTermsAndConditions) { const termsAndConditionTitle = objectGraph.loc.string("TermsAndConditions.Title"); const urlAction = new models.ExternalUrlAction(termsAndConditionsUrl); const footnote = new models.Footnote(termsAndConditionTitle); footnote.clickAction = urlAction; footnote.presentationStyle = ["hasChevron", "textLightensOnHighlight", "hasSeparator"]; footer.footnote = footnote; } shelf.background = { type: "color", color: color.named("placeholderBackground"), }; } if (serverData.isDefinedNonNullNonEmpty(shelfData.shelfContents)) { const metricsOptions = { pageInformation: shelfToken.metricsPageInformation, locationTracker: shelfToken.metricsLocationTracker, }; footer.icons = content.impressionableAppIconsFromDataCollection(objectGraph, shelfData.shelfContents, metricsOptions, { useCase: 2 /* content.ArtworkUseCase.LockupIconMedium */, }); } else { footer.icons = []; } if (shelfToken.shouldIncludeShelfUrl) { shelf.url = groupingShelfControllerCommon.groupingShelfUrl(shelfToken); } return shelf; } // region Helpers /** * The maximum number of icons that can be displayed in a device's icon grid, i.e. Arcade Grid Footer. * This is used to limit the number of icon data to fetch to what we'll actually use. * Note that views are expected to handle situations where we have less than the max number of icons. * * @param deviceType The device type that arcade icon grid is being displayed in. * @returns The maximum number of icons to fetch. */ numberOfIconsForArcadeAppGrid(deviceType) { switch (deviceType) { case "phone": return 9; default: // iPad, provided `footerShowsIconsForPlatform == true`. return 20; } } } //# sourceMappingURL=grouping-arcade-footer-shelf-controller.js.map