import * as models from "../../api/models"; import * as serverData from "../../foundation/json-parsing/server-data"; import * as types from "../grouping/grouping-types"; import { isSome } from "@jet/environment/types/optional"; /** * Determines if placeholders are enabled for the current device * @param objectGraph Current object graph * @returns True if the current device supports placeholders */ export function placeholdersEnabled(objectGraph) { return objectGraph.client.isiOS || objectGraph.client.isVision; } /** * Whether a given shelf content type supports placeholders * @param objectGraph Current object graph * @param contentType Content type for the shelf * @returns True if the content type supports placeholders */ function contentTypeSupportsPlaceholders(objectGraph, contentType) { if (preprocessor.GAMES_TARGET) { switch (contentType) { case "smallLockup": case "mediumLockup": case "mediumImageLockup": case "largeImageLockup": case "smallStoryCard": case "mediumStoryCard": case "largeStoryCard": case "miniTodayCard": return true; default: return false; } } if (objectGraph.client.isVision) { switch (contentType) { case "smallBrick": case "brick": case "largeBrick": case "smallLockup": case "mediumLockup": case "largeLockup": case "smallVerticalLockup": case "mediumVerticalLockup": case "posterLockup": case "action": case "smallImageLockup": case "mediumImageLockup": case "largeImageLockup": case "smallStoryCard": case "mediumStoryCard": case "largeHeroBreakout": return true; default: return false; } } else { switch (contentType) { case "smallLockup": case "mediumLockup": case "largeLockup": case "brick": case "categoryBrick": case "videoCard": case "posterLockup": case "appTrailerLockup": case "screenshotsLockup": case "appPromotion": case "appEvent": case "smallStoryCard": case "tagBrick": case "miniTodayCard": return true; default: return false; } } } /** * The number of placeholders to use, if the hydration count is unknown * @param objectGraph Current object graph * @param itemCount The number of items * @param featuredContentID An optional FCID * @returns The number of placeholds to use */ function placeholderCountForItemCount(objectGraph, itemCount, featuredContentID) { if (itemCount > 0) { return itemCount; } // In some cases mediaAPI can return is a shelf with no items. This is valid for personalised shelves but not for // editorially controlled shelves and something is probably wrong with the configuration of that shelf shelf. // In that case we return 0 placeholders so the shelf doesn't get modified (and placeholders don't get inserted), staying hidden from the user if (isSome(featuredContentID) && !types.isRecommendationsShelf(featuredContentID)) { return 0; } if (objectGraph.client.isPad || objectGraph.client.isVision) { return 15; } else { return 6; } } /** * Inserts placeholder items into the given product page shelf * @param objectGraph Current object graph * @param shelf The input shelf * @param token The current shelf token * @param featuredContentId An optional FCID */ export function insertPlaceholdersIntoProductPageShelfIfRequired(objectGraph, shelf, token) { if (objectGraph.client.isiOS && objectGraph.bag.isOnDemandShelfFetchingEnabled && placeholdersEnabled(objectGraph) && isSome(shelf) && serverData.isNullOrEmpty(shelf.items) && token.isFirstRender) { token.showingPlaceholders = insertPlaceholdersIntoShelf(objectGraph, shelf, token.remainingItems.length); } } /** * Inserts placeholder items into the given shelf, if we pass some pre-flight checks * @param objectGraph Current object graph * @param shelf The input shelf * @param shelfToken The current shelf token * @param featuredContentId An optional FCID */ export function insertPlaceholdersIntoShelfIfRequired(objectGraph, shelf, shelfToken, displayLimit = undefined, featuredContentId) { if (placeholdersEnabled(objectGraph) && isSome(shelf) && isSome(shelf.url) && serverData.isNullOrEmpty(shelf.items) && shelfToken.isFirstRender) { shelfToken.showingPlaceholders = insertPlaceholdersIntoShelf(objectGraph, shelf, displayLimit !== null && displayLimit !== void 0 ? displayLimit : shelfToken.remainingItems.length, shelfToken.isSearchLandingPage, shelfToken.isArcadePage, featuredContentId); } } /** * Inserts placeholder items into the given generic page shelf * @param objectGraph Current object graph * @param shelf The input shelf * @param token The current shelf token * @param featuredContentId An optional FCID */ export function insertPlaceholdersIntoGenericPageShelf(objectGraph, shelf, token, featuredContentId) { token.showingPlaceholders = insertPlaceholdersIntoShelf(objectGraph, shelf, token.remainingItems.length, token.isSearchLandingPage, token.isArcadePage, featuredContentId); } /** * @param objectGraph The current object graph * @param shelf The shelf to insert placeholders into * @param remainaingItemCount The number of items remaining to load * @param isSearchLandingPage Whether the current page is a search landing page * @param isArcadePage Whether the current page is an arcade page * @param featuredContentId The optional FCID * @returns Whether placeholders were inserted */ function insertPlaceholdersIntoShelf(objectGraph, shelf, remainaingItemCount, isSearchLandingPage = false, isArcadePage = false, featuredContentId = null) { // Return if the shelf already has items do not insert placeholders if (serverData.isDefinedNonNullNonEmpty(shelf.items)) { return false; } // Return if not a supported placeholder type or grouping is search if (!contentTypeSupportsPlaceholders(objectGraph, shelf.contentType) || isSearchLandingPage) { return false; } const placeholderCount = placeholderCountForItemCount(objectGraph, remainaingItemCount, featuredContentId); // Generate placeholder items const placeholderItems = new Array(placeholderCount); for (let i = 0; i < placeholderCount; i += 1) { placeholderItems[i] = new models.Placeholder(); } if (serverData.isNullOrEmpty(placeholderItems)) { // If we didn't generate any items then don't modify the shelf and just return return false; } const rowsPerColumn = rowsPerColumnForShelf(objectGraph, shelf); if (isSome(rowsPerColumn)) { shelf.rowsPerColumn = rowsPerColumn; } // Swap the real content type to the placeholder type and assign the items shelf.placeholderContentType = shelf.contentType; shelf.contentType = "placeholder"; shelf.items = placeholderItems; if (serverData.isDefinedNonNullNonEmpty(isArcadePage)) { shelf.presentationHints = { ...shelf.presentationHints, isAppleArcadeContext: isArcadePage }; } // If we're showing placeholders we never want the shelf to be hidden shelf.isHidden = false; return true; } export function isPlaceholderShelf(shelf) { return shelf.contentType === "placeholder"; } /** * The preferred number of rows to use per column, for a given shelf * @param objectGraph Current object graph * @param shelf The shelf we're calculating for * @returns The number of rows to use */ function rowsPerColumnForShelf(objectGraph, shelf) { if (objectGraph.client.isVision) { switch (shelf.contentType) { case "smallLockup": return 3; case "mediumLockup": return 2; default: return 1; } } else if (isSome(shelf.rowsPerColumn)) { return shelf.rowsPerColumn; } else { switch (shelf.contentType) { case "smallLockup": return 3; case "mediumLockup": return 2; case "largeLockup": return 1; case "categoryBrick": // Do not default for Category Brick return null; default: return 1; } } } //# sourceMappingURL=placeholders.js.map