diff options
Diffstat (limited to 'node_modules/@jet-app/app-store/tmp/src/common/top-charts-common.js')
| -rw-r--r-- | node_modules/@jet-app/app-store/tmp/src/common/top-charts-common.js | 212 |
1 files changed, 212 insertions, 0 deletions
diff --git a/node_modules/@jet-app/app-store/tmp/src/common/top-charts-common.js b/node_modules/@jet-app/app-store/tmp/src/common/top-charts-common.js new file mode 100644 index 0000000..c93843b --- /dev/null +++ b/node_modules/@jet-app/app-store/tmp/src/common/top-charts-common.js @@ -0,0 +1,212 @@ +/** + * Common for top-charts. + * Incrementally migrate `top-charts-controller` builder logic here. + */ +import { isSome, isNothing } from "@jet/environment/types/optional"; +import * as categories from "../common/categories"; +import { isDefinedNonNullNonEmpty } from "../foundation/json-parsing/server-data"; +import { attributeAsString } from "../foundation/media/attributes"; +import { fetchData } from "../foundation/media/network"; +import { Parameters } from "../foundation/network/url-constants"; +import { URL } from "../foundation/network/urls"; +import * as client from "../foundation/wrappers/client"; +import { mediaApiChartRequestForGenre } from "./builders/url-mapping"; +// region API - URLs +/** + * Given a chart type, lookup the most appropriate chart to show next to it using + * fallback mapping logic, e.g. `top-paid` for `top-free` and visa versa. + * + * MAINTAINERS NOTE: This is typically driven by Editorial's programming but this can be used as a fallback. + * + * @param objectGraph The App Store object graph. + * @param chartType The type of chart to lookup a sibling for, e.g. `top-free`. + * @returns The sibling of the provided chart type, e.g. `top-paid`. + */ +export function lookupFallbackSiblingChart(objectGraph, chartType) { + // Vision currently doesn't support sibling charts - don't attempt to find one. + if (isNothing(chartType) || objectGraph.client.isVision) { + return undefined; + } + switch (chartType) { + case "top-free" /* TopChartType.TopFree */: + return "top-paid" /* TopChartType.TopPaid */; + case "top-paid" /* TopChartType.TopPaid */: + return "top-free" /* TopChartType.TopFree */; + /* + ** MAINTAINERS NOTE ** + We don't want to show "Top Apps" / "Paid Apps" for extensions, trending, or emerging, + so don't map these together until we can confirm the desired UX we want for this. + + case TopChartType.TopFreeSafariExtensions: + return TopChartType.TopPaidSafariExtensions; + case TopChartType.TopPaidSafariExtensions: + return TopChartType.TopFreeSafariExtensions; + case TopChartType.TopFreeTrending: + return TopChartType.TopPaidTrending; + case TopChartType.TopPaidTrending: + return TopChartType.TopFreeTrending; + case TopChartType.TopFreeEmerging: + return TopChartType.TopPaidEmerging; + case TopChartType.TopPaidEmerging: + return TopChartType.TopFreeEmerging; + */ + default: + return undefined; + } +} +/** + * Creates a charts parameter value for an invidual chart shelf's see all flow action URL, which may show multiple charts. + * + * ** MAINTAINERS NOTE ** + * This function guarantees the selected chart is always included in charts. + * This helps make the user experience more resilient to either unexpected editorial programming or client JS programmer error. + * For example, if provided chart set is missing the selected chart or is missing any siblings, we lookup hardcoded fallback + * mappings, e.g. `top-paid` for `top-free`. + * + * @param objectGraph The App Store object graph. + * @param selectedChartType The selected chart, e.g. `top-free`. + * @param chartSet The collection fo charts to be shown as sibligs, e.g. `top-free` and `top-paid` in a segmented control + * @returns Value for charts URL query paramater. + */ +function makeChartsParameterValue(objectGraph, selectedChartType, chartSet) { + var _a; + const hasMultipleCharts = (_a = (chartSet === null || chartSet === void 0 ? void 0 : chartSet.editorialCharts.length) > 1) !== null && _a !== void 0 ? _a : false; + const charts = chartSet === null || chartSet === void 0 ? void 0 : chartSet.editorialCharts.map((chart) => chart.type.toString()).join(","); + // use editorially programmed chart set if defined with multiple charts, including the selection. + if (isSome(charts) && charts.includes(selectedChartType) && hasMultipleCharts) { + return charts; + } + // otherwise, lookup hardcoded fallback sibling if available, e.g. `top-paid` for `top-free`. + const siblingChartType = lookupFallbackSiblingChart(objectGraph, selectedChartType); + if (siblingChartType === undefined) { + return selectedChartType; // no sibling found, show just the single selected chart + } + return [selectedChartType, siblingChartType].join(","); // show harcoded pair of charts +} +/** + * Construct the URL for a single chart shelf "See All", that might be part of an editorial chart set. + * @param objectGraph The App Store object graph. + * @param chartData The media API data for the chart shelf, e.g. `top-paid`. + * @param chartSet The set of charts shown when tapping "See All", e.g. `top-free` and `top-paid`. + */ +export function makeSeeAllUrlFromMediaApiData(objectGraph, chartData, chartSet) { + const baseUrl = attributeAsString(chartData, "chartHref"); + const chartSeeAllUrl = new URL(baseUrl); + /** + * The selected chart to show, e.g. `top-free`. + */ + const selectedChart = attributeAsString(chartData, "chart"); + if (isDefinedNonNullNonEmpty(selectedChart)) { + chartSeeAllUrl.param(Parameters.chart, selectedChart); + } + /** + * The collection of charts to show, e.g. `top-free` and `top-paid`. + * This is needed since a chart sets are vended down as a single fcKind item with children that is divided into multiple shelves. + * Tapping "See All" on a chart shelf, should show a top charts page with all `charts` provided and `chart` selected. + */ + const charts = makeChartsParameterValue(objectGraph, selectedChart, chartSet); + if (isDefinedNonNullNonEmpty(charts)) { + chartSeeAllUrl.param(Parameters.charts, charts); + } + return chartSeeAllUrl.toString(); +} +/** + * Returns whether or not given chart page URL charts parameter is for safari extensions. + * Charts for safari extensions must be handled as a special case since they don't have an associated specific genre. + * + * @param url The URL to check if it is Safari Extension charts. + */ +function isSafariExtensionCharts(charts) { + return (isDefinedNonNullNonEmpty(charts) && + (charts.indexOf("top-free-safari-extensions" /* TopChartType.TopFreeSafariExtensions */) !== -1 || + charts.indexOf("top-paid-safari-extensions" /* TopChartType.TopPaidSafariExtensions */) !== -1)); +} +// endregion API +// region MAPI Requests +/** + * Fetch the top-level structural data for top charts. + * + * @param objectGraph The App Store object graph. + * @param genreId The genre to fetch charts for, e.g. Apps or Games. + * @param charts The specific charts in this genre. + */ +export async function fetchTopChartsData(objectGraph, genreId, charts, ages = null) { + // Request + const topChartsRequest = mediaApiChartRequestForGenre(objectGraph, genreId, charts, ages); + // Pagination + Sparse limits + topChartsRequest.withLimit(200); + if (objectGraph.client.isMac || objectGraph.client.isWeb) { + topChartsRequest.withSparseLimit(25); + } + topChartsRequest.enablingFeature("newChartsElements"); + return await fetchData(objectGraph, topChartsRequest); +} +/** + * Fetch the categories data promise accompanying given `chartUrl`. + * + * @param objectGraph Object graph + * @param charts The charts to fetch categories data for, e.g. `top-free,top-paid` + * @param genreId The genre for chart to fetch categories data for, e.g. Apps or Games + */ +export async function fetchCategoriesDataForPlatform(objectGraph, charts, genreId) { + let categoriesRequestPromise; + /** + * No categories filter on: + * - All tvOS charts + * - All Messages AppStore charts + * - Safari Extension Charts (Genre-less Genre) + */ + if (objectGraph.client.isTV || + objectGraph.host.clientIdentifier === client.messagesIdentifier || + isSafariExtensionCharts(charts)) { + categoriesRequestPromise = Promise.resolve({}); + } + else { + const categoriesRequest = categories.createRequest(objectGraph, genreId); + categoriesRequestPromise = fetchData(objectGraph, categoriesRequest).catch(() => undefined); + } + return await categoriesRequestPromise; +} +// endregion +// region Page Title +/** + * Return the top charts page title to use for a collection of top chart segments. + * + * @param objectGraph Object graph + * @param segments The segments to derive page title for + */ +export function topChartsPageTitleForSegments(objectGraph, segments) { + const everySegmentIsTrending = segments.every((seg) => isTrendingChartType(seg.chart)); + if (everySegmentIsTrending) { + return objectGraph.loc.string("PAGE_TITLE_TRENDING_CHARTS"); + } + const everySegmentIsEmerging = segments.every((seg) => isEmergingChartType(seg.chart)); + if (everySegmentIsEmerging) { + return objectGraph.loc.string("PAGE_TITLE_EMERGING_CHARTS"); + } + return objectGraph.loc.string("PAGE_TITLE_TOP_CHARTS"); +} +// endregion +// region Top Charts Type +/// Whether or not given chart type is trending chart type +function isTrendingChartType(chart) { + switch (chart) { + case "top-trending-free" /* TopChartType.TopFreeTrending */: + case "top-trending-paid" /* TopChartType.TopPaidTrending */: + return true; + default: + return false; + } +} +/// Whether or not given chart type is emerging chart type +function isEmergingChartType(chart) { + switch (chart) { + case "top-emerging-free" /* TopChartType.TopFreeEmerging */: + case "top-emerging-paid" /* TopChartType.TopPaidEmerging */: + return true; + default: + return false; + } +} +// endregion +//# sourceMappingURL=top-charts-common.js.map
\ No newline at end of file |
