summaryrefslogtreecommitdiff
path: root/node_modules/@jet-app/app-store/tmp/src/common/grouping/render-grouping-page.js
diff options
context:
space:
mode:
authorrxliuli <rxliuli@gmail.com>2025-11-04 05:03:50 +0800
committerrxliuli <rxliuli@gmail.com>2025-11-04 05:03:50 +0800
commitbce557cc2dc767628bed6aac87301a1be7c5431b (patch)
treeb51a051228d01fe3306cd7626d4a96768aadb944 /node_modules/@jet-app/app-store/tmp/src/common/grouping/render-grouping-page.js
init commit
Diffstat (limited to 'node_modules/@jet-app/app-store/tmp/src/common/grouping/render-grouping-page.js')
-rw-r--r--node_modules/@jet-app/app-store/tmp/src/common/grouping/render-grouping-page.js246
1 files changed, 246 insertions, 0 deletions
diff --git a/node_modules/@jet-app/app-store/tmp/src/common/grouping/render-grouping-page.js b/node_modules/@jet-app/app-store/tmp/src/common/grouping/render-grouping-page.js
new file mode 100644
index 0000000..8640079
--- /dev/null
+++ b/node_modules/@jet-app/app-store/tmp/src/common/grouping/render-grouping-page.js
@@ -0,0 +1,246 @@
+import { isSome, isNothing } from "@jet/environment/types/optional";
+import { FlowAction, GenericPage, Shelf } from "../../api/models";
+import { attributeAsNumber, attributeAsString } from "../../foundation/media/attributes";
+import { dataFromDataContainer } from "../../foundation/media/data-structure";
+import { asNumber, isDefinedNonNull, isDefinedNonNullNonEmpty, isNull, } from "../../foundation/json-parsing/server-data";
+import { hasRelationship, relationship } from "../../foundation/media/relationships";
+import { URL } from "../../foundation/network/urls";
+import { appStoreIdentifier } from "../../foundation/wrappers/client";
+import { createArtworkForResource } from "../content/artwork/artwork";
+import { addMetricsEventsToPageWithInformation, metricsPageInformationFromMediaApiResponse, } from "../metrics/helpers/page";
+import { newPageRefreshControllerFromResponse, pageRefreshPolicyForController, } from "../refresh/page-refresh-controller";
+import { metricsData } from "../personalization/on-device-personalization";
+import { impressionEventsFromData } from "../personalization/on-device-impression-demotion";
+import { combinedRecoMetricsDataFromMetricsData } from "../metrics/helpers/util";
+import { newLocationTracker } from "../metrics/helpers/location";
+import { flattenMediaApiGroupingData, insertInitialShelvesIntoGroupingParseContext, shelfForFooterButtons, shelfForTermsAndConditions, shelfForUnifiedMessage, } from "./grouping-common";
+import { addBatchGroupsToPage } from "./shelf-batching";
+import { nameFromGroupingData } from "../lockups/lockups";
+// The key that contains the impression data for the grouping page fetched as an additional request.
+export const GroupingImpressionAdditionalDataKey = "amdImpressionData";
+export function groupingParseContextFromDataContainer(objectGraph, data, additionalPageRequirements) {
+ const mediaApiGroupingData = dataFromDataContainer(objectGraph, data);
+ if (isNothing(mediaApiGroupingData)) {
+ return null;
+ }
+ const metricsPageInformation = metricsPageInformationFromMediaApiResponse(objectGraph, "Genre", mediaApiGroupingData.id, data);
+ const onDevicePersonalizationMetricsData = metricsData(objectGraph);
+ metricsPageInformation.recoMetricsData = combinedRecoMetricsDataFromMetricsData(metricsPageInformation.recoMetricsData, null, onDevicePersonalizationMetricsData);
+ return {
+ shelves: [],
+ metricsPageInformation: metricsPageInformation,
+ metricsLocationTracker: newLocationTracker(),
+ pageGenreAdamId: attributeAsString(mediaApiGroupingData, "id"),
+ pageGenreId: null,
+ hasAuthenticatedUser: isDefinedNonNull(objectGraph.user.dsid),
+ refreshController: newPageRefreshControllerFromResponse(data),
+ recoImpressionData: impressionEventsFromData(objectGraph, additionalPageRequirements === null || additionalPageRequirements === void 0 ? void 0 : additionalPageRequirements[GroupingImpressionAdditionalDataKey]),
+ };
+}
+export function flattenedGroupingFromDataContainer(objectGraph, data) {
+ const mediaApiGroupingData = dataFromDataContainer(objectGraph, data);
+ if (!mediaApiGroupingData) {
+ return null;
+ }
+ if (!hasRelationship(mediaApiGroupingData, "tabs")) {
+ return null;
+ }
+ return flattenMediaApiGroupingData(objectGraph, mediaApiGroupingData);
+}
+// TODO: Once 18E is in we need to get the genreId from the chart URL
+export function genreIdFromChartURL(chartURLString) {
+ if (isNull(chartURLString)) {
+ return null;
+ }
+ const chartURL = URL.from(chartURLString);
+ return asNumber(chartURL.query, "genre");
+}
+function groupingPageTitleForData(objectGraph, groupingData, genreId) {
+ var _a;
+ let pageTitle = null;
+ switch (genreId) {
+ case 36 /* GenreIds.Apps */:
+ if (objectGraph.host.clientIdentifier === appStoreIdentifier && !objectGraph.client.isWatch) {
+ if (objectGraph.client.isMac) {
+ pageTitle = macDiscoverPageTitleForData(objectGraph, groupingData);
+ }
+ else {
+ pageTitle = objectGraph.loc.string("GROUPING_APPS");
+ }
+ }
+ else {
+ if (objectGraph.client.isTV) {
+ pageTitle = objectGraph.loc.string("GROUPING_APPS");
+ }
+ else if (objectGraph.client.isWeb) {
+ pageTitle =
+ ((_a = objectGraph.activeIntent) === null || _a === void 0 ? void 0 : _a.previewPlatform) === "mac"
+ ? macDiscoverPageTitleForData(objectGraph, groupingData)
+ : objectGraph.loc.string("GROUPING_APPS");
+ }
+ else {
+ pageTitle = objectGraph.loc.string("GROUPING_APP_STORE", "App Store");
+ }
+ }
+ break;
+ case 39 /* GenreIds.Discover */:
+ pageTitle = objectGraph.loc.string("GROUPING_DISCOVER");
+ break;
+ default:
+ pageTitle = nameFromGroupingData(objectGraph, groupingData);
+ break;
+ }
+ return pageTitle;
+}
+/**
+ * Create a shelf for header buttons, e.g. "Search".
+ *
+ * @return Shelf configured to display header buttons.
+ */
+function shelfForHeaderButtons(objectGraph) {
+ const shelf = new Shelf("action");
+ const items = [];
+ const searchFlowAction = new FlowAction("search");
+ searchFlowAction.title = objectGraph.loc.string("SEARCH", "Search");
+ searchFlowAction.artwork = createArtworkForResource(objectGraph, "systemimage://magnifyingglass");
+ items.push(searchFlowAction);
+ shelf.items = items;
+ return shelf;
+}
+/**
+ * Returns the page title for the Discover tab on macOS
+ *
+ * @param objectGraph
+ * @param {Data} groupingData MAPI data blob describing the grouping
+ * @return Page title string
+ */
+function macDiscoverPageTitleForData(objectGraph, groupingData) {
+ const tabs = relationship(groupingData, "tabs");
+ if (isDefinedNonNull(tabs) && isDefinedNonNull(tabs.data)) {
+ for (const tabData of tabs.data) {
+ const tabName = attributeAsString(tabData, "name");
+ const featuredContentId = attributeAsNumber(tabData, "editorialElementKind");
+ const token = attributeAsString(tabData, "token");
+ if (isSome(tabName) &&
+ tabName.length > 0 &&
+ isDefinedNonNull(featuredContentId) &&
+ isDefinedNonNullNonEmpty(token) &&
+ token === "macOS" &&
+ featuredContentId === 414 /* FeaturedContentID.AppStore_TabRoot */) {
+ return tabName;
+ }
+ }
+ }
+ return objectGraph.loc.string("GROUPING_DISCOVER");
+}
+/**
+ * Insert the unified message shelves into the arcade page
+ *
+ * @param objectGraph The App Store dependency graph
+ * @param page The generic page to insert shelves into
+ * @param genreId The genre Id of the generic page, e.g. Apps or Games
+ */
+function insertUnifiedMessageShelves(objectGraph, page, genreId) {
+ if (page.shelves.length <= 0) {
+ return;
+ }
+ // Insert Unified message shelves. These are hidden by default and act as 'placeholder' locations
+ // for the marketing teams to target with inline banners or bubble tip messages
+ switch (genreId) {
+ case 36 /* GenreIds.Apps */:
+ page.shelves.splice(0, 0, shelfForUnifiedMessage(objectGraph, "appsPageHeader"));
+ page.shelves.splice(6, 0, shelfForUnifiedMessage(objectGraph, "appsPageMid"));
+ page.shelves.push(shelfForUnifiedMessage(objectGraph, "appsPageFooter"));
+ break;
+ case 6014 /* GenreIds.Games */:
+ page.shelves.splice(0, 0, shelfForUnifiedMessage(objectGraph, "gamesPageHeader"));
+ page.shelves.splice(6, 0, shelfForUnifiedMessage(objectGraph, "gamesPageMid"));
+ page.shelves.push(shelfForUnifiedMessage(objectGraph, "gamesPageFooter"));
+ break;
+ default:
+ break;
+ }
+}
+export function groupingPageFromFlattenedGrouping(objectGraph, flattenedGrouping, groupingParseContext) {
+ groupingParseContext.pageGenreId =
+ attributeAsNumber(flattenedGrouping.originalGroupingData, "genre") ||
+ genreIdFromChartURL(attributeAsString(flattenedGrouping.originalGroupingData, "chartUrl"));
+ // Construct the shelves
+ insertInitialShelvesIntoGroupingParseContext(objectGraph, flattenedGrouping, groupingParseContext);
+ if (objectGraph.client.isWatch) {
+ // Remove title of first shelf with cards if needed.
+ if (groupingParseContext.shelves.length > 0 && groupingParseContext.shelves[0].contentType === "todayCard") {
+ groupingParseContext.shelves[0].title = undefined;
+ }
+ // Prepend Header Buttons
+ if (objectGraph.client.deviceType !== "watch") {
+ const headerButtonShelf = shelfForHeaderButtons(objectGraph);
+ groupingParseContext.shelves.unshift(headerButtonShelf);
+ }
+ }
+ // TODO: Add for ATV
+ // Append Footer Buttons
+ if (objectGraph.client.deviceType !== "tv" && objectGraph.client.deviceType !== "web") {
+ const footerButtonShelf = shelfForFooterButtons(objectGraph, groupingParseContext.metricsPageInformation, groupingParseContext.metricsLocationTracker);
+ if (footerButtonShelf) {
+ groupingParseContext.shelves.push(footerButtonShelf);
+ }
+ }
+ // TODO: Add for ATV
+ // Append T&C
+ if (objectGraph.client.deviceType !== "watch" && objectGraph.client.deviceType !== "tv") {
+ const url = objectGraph.bag.termsAndConditionsURL;
+ if (!isNull(url)) {
+ const termsAndConditionsShelf = shelfForTermsAndConditions(objectGraph, url);
+ groupingParseContext.shelves.push(termsAndConditionsShelf);
+ }
+ }
+ // Determine the title
+ const pageTitle = groupingPageTitleForData(objectGraph, flattenedGrouping.originalGroupingData, groupingParseContext.pageGenreId);
+ // Build the page
+ const page = new GenericPage(groupingParseContext.shelves);
+ switch (objectGraph.client.deviceType) {
+ case "tv":
+ page.title = pageTitle;
+ break;
+ case "watch":
+ page.title = pageTitle;
+ page.presentationOptions = ["prefersLargeTitleWhenRoot"];
+ break;
+ case "web":
+ page.title = pageTitle;
+ page.presentationOptions = ["prefersLargeTitleWhenRoot"];
+ const firstShelfType = page.shelves[0].contentType;
+ if (["heroCarousel", "editorialCard", "largeStoryCard"].includes(firstShelfType)) {
+ page.presentationOptions.push("prefersOverlayedPageHeader");
+ }
+ break;
+ default:
+ page.title = pageTitle;
+ if ((groupingParseContext.pageGenreId === 39 /* GenreIds.Discover */ ||
+ (groupingParseContext.pageGenreId === 36 /* GenreIds.Apps */ && objectGraph.client.isMac)) &&
+ !objectGraph.client.isIconArtworkCapable) {
+ page.presentationOptions = ["prefersRevealNavigationBarOnMouseOver"];
+ }
+ else {
+ page.presentationOptions = ["prefersLargeTitleWhenRoot"];
+ }
+ break;
+ }
+ if (objectGraph.client.isiOS) {
+ if (groupingParseContext.shelves[0].contentType === "mediaPageHeader") {
+ page.presentationOptions.push("prefersNonStandardBackButton");
+ page.presentationOptions.push("prefersHiddenPageTitle");
+ page.presentationOptions.push("prefersOverlayedPageHeader");
+ }
+ }
+ page.pageRefreshPolicy = pageRefreshPolicyForController(objectGraph, groupingParseContext === null || groupingParseContext === void 0 ? void 0 : groupingParseContext.refreshController);
+ addMetricsEventsToPageWithInformation(objectGraph, page, groupingParseContext.metricsPageInformation);
+ // Add unified message shelves
+ if (objectGraph.client.isiOS) {
+ insertUnifiedMessageShelves(objectGraph, page, groupingParseContext.pageGenreId);
+ }
+ addBatchGroupsToPage(page);
+ return page;
+}
+//# sourceMappingURL=render-grouping-page.js.map \ No newline at end of file