From bce557cc2dc767628bed6aac87301a1be7c5431b Mon Sep 17 00:00:00 2001 From: rxliuli Date: Tue, 4 Nov 2025 05:03:50 +0800 Subject: init commit --- .../web-navigation/flow-action-presentation.js | 79 +++++++++++ .../common/web-navigation/inject-web-navigation.js | 32 +++++ .../landing-page-links-by-platform.js | 62 +++++++++ .../platform-landing-page-intent-controllers.js | 155 +++++++++++++++++++++ .../web-navigation/platform-landing-page-utils.js | 139 ++++++++++++++++++ .../common/web-navigation/platform-selection.js | 115 +++++++++++++++ .../search-results-platform-selection.js | 28 ++++ .../src/common/web-navigation/web-navigation.js | 28 ++++ 8 files changed, 638 insertions(+) create mode 100644 node_modules/@jet-app/app-store/tmp/src/common/web-navigation/flow-action-presentation.js create mode 100644 node_modules/@jet-app/app-store/tmp/src/common/web-navigation/inject-web-navigation.js create mode 100644 node_modules/@jet-app/app-store/tmp/src/common/web-navigation/landing-page-links-by-platform.js create mode 100644 node_modules/@jet-app/app-store/tmp/src/common/web-navigation/platform-landing-page-intent-controllers.js create mode 100644 node_modules/@jet-app/app-store/tmp/src/common/web-navigation/platform-landing-page-utils.js create mode 100644 node_modules/@jet-app/app-store/tmp/src/common/web-navigation/platform-selection.js create mode 100644 node_modules/@jet-app/app-store/tmp/src/common/web-navigation/search-results-platform-selection.js create mode 100644 node_modules/@jet-app/app-store/tmp/src/common/web-navigation/web-navigation.js (limited to 'node_modules/@jet-app/app-store/tmp/src/common/web-navigation') diff --git a/node_modules/@jet-app/app-store/tmp/src/common/web-navigation/flow-action-presentation.js b/node_modules/@jet-app/app-store/tmp/src/common/web-navigation/flow-action-presentation.js new file mode 100644 index 0000000..41b5bb9 --- /dev/null +++ b/node_modules/@jet-app/app-store/tmp/src/common/web-navigation/flow-action-presentation.js @@ -0,0 +1,79 @@ +import { isSystemImage } from "../../api/models"; +import { asString } from "../../foundation/json-parsing/server-data"; +import { createArtworkForSystemImage } from "../content/artwork/artwork"; +import * as metricsHelpersClicks from "../metrics/helpers/clicks"; +import * as metricsHelpersLocation from "../metrics/helpers/location"; +/** + * Creates a {@linkcode PrepareAction} that sets the link's text and icon + */ +function createWebNavigationFlowActionConfiguration(id) { + return (objectGraph, action) => { + const tab = objectGraph.bag.tabsStandard.find((t) => t.id === id); + const imageIdentifier = asString(tab, "image-identifier"); + const artwork = isSystemImage(imageIdentifier) + ? createArtworkForSystemImage(objectGraph, imageIdentifier) + : null; + action.title = asString(tab, "title"); + action.artwork = artwork; + if (objectGraph.client.isWeb) { + metricsHelpersClicks.addClickEventToAction(objectGraph, action, { + targetType: "link", + id: id, + pageInformation: undefined, + locationTracker: metricsHelpersLocation.newLocationTracker(), + }); + } + }; +} +/** + * {@linkcode PrepareAction} that presents a link to the "Apps" landing page + */ +export const appLandingPageFlowActionPresentation = createWebNavigationFlowActionConfiguration("apps"); +/** + * {@linkcode PrepareAction} that presents a link to the "Apps & Games" landing page + */ +export const appAndGamesLandingPageFlowActionPresentation = createWebNavigationFlowActionConfiguration("apps-and-games"); +/** + * {@linkcode PrepareAction} that presents a link to the "Arcade" landing page + */ +export const arcadeLandingPageFlowActionPresentation = createWebNavigationFlowActionConfiguration("arcade"); +/** + * {@linkcode PrepareAction} that presents a link to the "Discover" landing page + */ +export const discoverLandingPageFlowActionPresentation = createWebNavigationFlowActionConfiguration("discover"); +/** + * {@linkcode PrepareAction} that presents a link to the "Games" landing page + */ +export const gamesLandingPageFlowActionPresentation = createWebNavigationFlowActionConfiguration("games"); +/** + * {@linkcode PrepareAction} that presents a link to the "Create" landing page + * + * Note: `create` refers to the specific "Create" landing page, rather than this being + * a function that creates landing page presentations + */ +export const createLandingPageFlowActionPresentation = createWebNavigationFlowActionConfiguration("create"); +/** + * {@linkcode PrepareAction} that presents a link to the "Work" landing page + */ +export const workLandingPageFlowActionPresentation = createWebNavigationFlowActionConfiguration("work"); +/** + * {@linkcode PrepareAction} that presents a link to the "Play" landing page + */ +export const playLandingPageFlowActionPresentation = createWebNavigationFlowActionConfiguration("play"); +/** + * {@linkcode PrepareAction} that presents a link to the "Develop" landing page + */ +export const developLandingPageFlowActionPresentation = createWebNavigationFlowActionConfiguration("develop"); +/** + * {@linkcode PrepareAction} that presents a link to the "Categories" landing page + */ +export const categoriesLandingPageFlowActionPresentation = createWebNavigationFlowActionConfiguration("categories"); +/** + * {@linkcode PrepareAction} that presents a link to the "Today" landing page + */ +export const todayLandingPageFlowActionPresentation = createWebNavigationFlowActionConfiguration("today"); +/** + * {@linkcode PrepareAction} that presents a link to the "Apps & Games" landing page + */ +export const searchLandingPageFlowActionPresentation = createWebNavigationFlowActionConfiguration("search"); +//# sourceMappingURL=flow-action-presentation.js.map \ No newline at end of file diff --git a/node_modules/@jet-app/app-store/tmp/src/common/web-navigation/inject-web-navigation.js b/node_modules/@jet-app/app-store/tmp/src/common/web-navigation/inject-web-navigation.js new file mode 100644 index 0000000..b882c17 --- /dev/null +++ b/node_modules/@jet-app/app-store/tmp/src/common/web-navigation/inject-web-navigation.js @@ -0,0 +1,32 @@ +import { createWebNavigation, setActivePlatform } from "./web-navigation"; +/** + * The "default" {@linkcode PreviewPlatform} that should be used for the navigation state in cases + * where an explicit value is not provided + */ +const FALLBACK_PREVIEW_PLATFORM = "iphone"; +/** + * Inject the `WebNavigation` into a page model + * + * @param objectGraph + * @param page the page to inject the navigation into + * @param platform the `PreviewPlatform` to render navigation links for + * @returns the web navigation shelf, in case further mutation is required + */ +export function injectWebNavigation(objectGraph, page, platform) { + const webNavigation = createWebNavigation(objectGraph, platform !== null && platform !== void 0 ? platform : FALLBACK_PREVIEW_PLATFORM); + if (page.title) { + webNavigation.title = page.title; + } + page.webNavigation = webNavigation; + return webNavigation; +} +/** + * Sets the `WebNavigation` contained by {@linkcode page} to reflect {@linkcode platform} + * as the active platform. Landing pages links will also be made active based on {@linkcode intent} + */ +export function updateWebNavigation(objectGraph, page, platform, intent) { + if (page.webNavigation) { + setActivePlatform(objectGraph, page.webNavigation, platform, intent); + } +} +//# sourceMappingURL=inject-web-navigation.js.map \ No newline at end of file diff --git a/node_modules/@jet-app/app-store/tmp/src/common/web-navigation/landing-page-links-by-platform.js b/node_modules/@jet-app/app-store/tmp/src/common/web-navigation/landing-page-links-by-platform.js new file mode 100644 index 0000000..02aad6c --- /dev/null +++ b/node_modules/@jet-app/app-store/tmp/src/common/web-navigation/landing-page-links-by-platform.js @@ -0,0 +1,62 @@ +import { isPreviewPlatform } from "../../api/models/preview-platform"; +import { getLocale } from "../locale"; +import { landingPageIntentsAreEquivalent, } from "./platform-landing-page-utils"; +import { iPadTodayPageController, iPadAppsController, iPadArcadeController, iPadGamesController, iPadSearchLandingController, iPhoneTodayPageController, iPhoneAppsController, iPhoneGamesController, iPhoneArcadeController, iPhoneSearchLandingController, MacDiscoverController, MacArcadeController, MacCreateController, MacWorkController, MacPlayController, MacDevelopController, MacCategoriesController, MacSearchLandingController, TVAppsController, TVArcadeController, TVDiscoverController, TVGamesController, TVSearchLandingController, VisionAppsAndGamesController, VisionArcadeController, VisionSearchLandingController, WatchDiscoverController, WatchSearchLandingController, } from "./platform-landing-page-intent-controllers"; +const ARCADE_CONTROLLERS = new Set([ + iPadArcadeController, + iPhoneArcadeController, + MacArcadeController, + TVArcadeController, + VisionArcadeController, +]); +export function createLandingPageLinks(objectGraph, platform, intent) { + if (!platform || !isPreviewPlatform(platform)) { + return []; + } + // NOTE: this map cannot be defined at the module level, for risk of creating + // a circular dependency between module-level declarations that will break the build + // tools used by the "web" client + const landingPageControllers = { + ipad: [ + iPadTodayPageController, + iPadGamesController, + iPadAppsController, + iPadArcadeController, + iPadSearchLandingController, + ], + iphone: [ + iPhoneTodayPageController, + iPhoneGamesController, + iPhoneAppsController, + iPhoneArcadeController, + iPhoneSearchLandingController, + ], + mac: [ + MacDiscoverController, + MacArcadeController, + MacCreateController, + MacWorkController, + MacPlayController, + MacDevelopController, + MacCategoriesController, + MacSearchLandingController, + ], + tv: [TVDiscoverController, TVGamesController, TVAppsController, TVArcadeController, TVSearchLandingController], + vision: [VisionAppsAndGamesController, VisionArcadeController, VisionSearchLandingController], + watch: [WatchDiscoverController, WatchSearchLandingController], + }; + const locale = getLocale(objectGraph); + const isArcadeEnabled = objectGraph.bag.isArcadeEnabled; + return landingPageControllers[platform] + .filter((landingPageController) => { + // Rejects Arcade controllers if not supported and let's all other controllers pass + const isArcadeController = ARCADE_CONTROLLERS.has(landingPageController); + return isArcadeEnabled || !isArcadeController; + }) + .map((controller) => controller.buildAction(locale, objectGraph)) + .map((action) => ({ + action, + isActive: landingPageIntentsAreEquivalent(intent, action.destination), + })); +} +//# sourceMappingURL=landing-page-links-by-platform.js.map \ No newline at end of file diff --git a/node_modules/@jet-app/app-store/tmp/src/common/web-navigation/platform-landing-page-intent-controllers.js b/node_modules/@jet-app/app-store/tmp/src/common/web-navigation/platform-landing-page-intent-controllers.js new file mode 100644 index 0000000..d19d46b --- /dev/null +++ b/node_modules/@jet-app/app-store/tmp/src/common/web-navigation/platform-landing-page-intent-controllers.js @@ -0,0 +1,155 @@ +// This module, despite exporting `IntentController` definitions, lives inside of +// `src/common` because these controllers need to be import-able by other "common" +// code in order to directly call their `buildIntent` method +// +// The "web" client expects all exports from this module to be `IntentController` instances +import { defineLandingPageController, definePlatformRootRedirectController, defineRootRedirectController, } from "./platform-landing-page-utils"; +import { makeEditorialPageIntentByName } from "../../api/intents/editorial/editorial-page-intent"; +import { makeGroupingPageIntentByName } from "../../api/intents/grouping-page-intent"; +import { makeRoutableTodayPageIntent } from "../../api/intents/routable-today-page-intent"; +import { makeArcadeGroupingPageIntent } from "../../api/intents/arcade-grouping-page-intent"; +import { appLandingPageFlowActionPresentation, appAndGamesLandingPageFlowActionPresentation, arcadeLandingPageFlowActionPresentation, discoverLandingPageFlowActionPresentation, gamesLandingPageFlowActionPresentation, createLandingPageFlowActionPresentation, workLandingPageFlowActionPresentation, playLandingPageFlowActionPresentation, todayLandingPageFlowActionPresentation, developLandingPageFlowActionPresentation, categoriesLandingPageFlowActionPresentation, searchLandingPageFlowActionPresentation, } from "./flow-action-presentation"; +import { makeSearchLandingPageIntent } from "../../api/intents/search/search-landing-page-intent"; +// Ensures that the root URL (e.g. apps.apple.com) redirects to the iPhone Today page +export const RootRedirectController = defineRootRedirectController((locale) => iPhoneTodayPageController.buildIntent(locale)); +/// MARK: Vision Pro Landing Pages +export const VisionRootRedirectController = definePlatformRootRedirectController("/vision", (locale) => VisionAppsAndGamesController.buildIntent(locale)); +export const VisionAppsAndGamesController = defineLandingPageController("/vision/apps-and-games", (locale) => makeEditorialPageIntentByName({ + ...locale, + platform: "vision", + name: "apps-and-games", +}), appAndGamesLandingPageFlowActionPresentation); +export const VisionArcadeController = defineLandingPageController("/vision/arcade", (locale) => makeEditorialPageIntentByName({ + ...locale, + platform: "vision", + name: "arcade-subscriber", +}), arcadeLandingPageFlowActionPresentation); +export const VisionSearchLandingController = defineLandingPageController("/vision/search", (locale) => makeSearchLandingPageIntent({ + ...locale, + platform: "vision", +}), searchLandingPageFlowActionPresentation); +/// MARK: Mac Landing Pages +export const MacRootRedirectController = definePlatformRootRedirectController("/mac", (locale) => MacDiscoverController.buildIntent(locale)); +export const MacDiscoverController = defineLandingPageController("/mac/discover", (locale) => makeGroupingPageIntentByName({ + ...locale, + platform: "mac", + name: "apps", +}), discoverLandingPageFlowActionPresentation); +export const MacArcadeController = defineLandingPageController("/mac/arcade", (locale) => makeArcadeGroupingPageIntent({ + ...locale, + platform: "mac", +}), arcadeLandingPageFlowActionPresentation); +export const MacCreateController = defineLandingPageController("/mac/create", (locale) => makeGroupingPageIntentByName({ + ...locale, + platform: "mac", + name: "create", +}), createLandingPageFlowActionPresentation); +export const MacWorkController = defineLandingPageController("/mac/work", (locale) => makeGroupingPageIntentByName({ + ...locale, + platform: "mac", + name: "work", +}), workLandingPageFlowActionPresentation); +export const MacPlayController = defineLandingPageController("/mac/play", (locale) => makeGroupingPageIntentByName({ + ...locale, + platform: "mac", + name: "play", +}), playLandingPageFlowActionPresentation); +export const MacDevelopController = defineLandingPageController("/mac/develop", (locale) => makeGroupingPageIntentByName({ + ...locale, + platform: "mac", + name: "develop", +}), developLandingPageFlowActionPresentation); +export const MacCategoriesController = defineLandingPageController("/mac/categories", (locale) => makeGroupingPageIntentByName({ + ...locale, + platform: "mac", + name: "categories", +}), categoriesLandingPageFlowActionPresentation); +export const MacSearchLandingController = defineLandingPageController("/mac/search", (locale) => makeSearchLandingPageIntent({ + ...locale, + platform: "mac", +}), searchLandingPageFlowActionPresentation); +/// MARK: iPhone Landing Pages +export const iPhoneRootRedirectController = definePlatformRootRedirectController("/iphone", (locale) => iPhoneTodayPageController.buildIntent(locale)); +export const iPhoneTodayPageController = defineLandingPageController("/iphone/today", (locale) => makeRoutableTodayPageIntent({ + ...locale, + platform: "iphone", +}), todayLandingPageFlowActionPresentation); +export const iPhoneAppsController = defineLandingPageController("/iphone/apps", (locale) => makeGroupingPageIntentByName({ + ...locale, + platform: "iphone", + name: "apps", +}), appLandingPageFlowActionPresentation); +export const iPhoneGamesController = defineLandingPageController("/iphone/games", (locale) => makeGroupingPageIntentByName({ + ...locale, + platform: "iphone", + name: "games", +}), gamesLandingPageFlowActionPresentation); +export const iPhoneArcadeController = defineLandingPageController("/iphone/arcade", (locale) => makeArcadeGroupingPageIntent({ + ...locale, + platform: "iphone", +}), arcadeLandingPageFlowActionPresentation); +export const iPhoneSearchLandingController = defineLandingPageController("/iphone/search", (locale) => makeSearchLandingPageIntent({ + ...locale, + platform: "iphone", +}), searchLandingPageFlowActionPresentation); +/// MARK: iPad Landing Pages +export const iPadRootRedirectController = definePlatformRootRedirectController("/ipad", (locale) => iPadTodayPageController.buildIntent(locale)); +export const iPadTodayPageController = defineLandingPageController("/ipad/today", (locale) => makeRoutableTodayPageIntent({ + ...locale, + platform: "ipad", +}), todayLandingPageFlowActionPresentation); +export const iPadGamesController = defineLandingPageController("/ipad/games", (locale) => makeGroupingPageIntentByName({ + ...locale, + platform: "ipad", + name: "games", +}), gamesLandingPageFlowActionPresentation); +export const iPadAppsController = defineLandingPageController("/ipad/apps", (locale) => makeGroupingPageIntentByName({ + ...locale, + platform: "ipad", + name: "apps", +}), appLandingPageFlowActionPresentation); +export const iPadArcadeController = defineLandingPageController("/ipad/arcade", (locale) => makeArcadeGroupingPageIntent({ + ...locale, + platform: "ipad", +}), arcadeLandingPageFlowActionPresentation); +export const iPadSearchLandingController = defineLandingPageController("/ipad/search", (locale) => makeSearchLandingPageIntent({ + ...locale, + platform: "ipad", +}), searchLandingPageFlowActionPresentation); +/// MARK: Watch Landing Pages +export const WatchRootRedirectController = definePlatformRootRedirectController("/watch", (locale) => WatchDiscoverController.buildIntent(locale)); +export const WatchDiscoverController = defineLandingPageController("/watch/apps-and-games", (locale) => makeGroupingPageIntentByName({ + ...locale, + platform: "watch", + name: "apps", +}), appAndGamesLandingPageFlowActionPresentation); +export const WatchSearchLandingController = defineLandingPageController("/watch/search", (locale) => makeSearchLandingPageIntent({ + ...locale, + platform: "watch", +}), searchLandingPageFlowActionPresentation); +/// MARK: TV Landing Pages +export const TVRootRedirectController = definePlatformRootRedirectController("/tv", (locale) => TVDiscoverController.buildIntent(locale)); +export const TVDiscoverController = defineLandingPageController("/tv/discover", (locale) => makeGroupingPageIntentByName({ + ...locale, + platform: "tv", + name: "discover", +}), discoverLandingPageFlowActionPresentation); +export const TVGamesController = defineLandingPageController("/tv/games", (locale) => makeGroupingPageIntentByName({ + ...locale, + platform: "tv", + name: "games", +}), gamesLandingPageFlowActionPresentation); +export const TVAppsController = defineLandingPageController("/tv/apps", (locale) => makeGroupingPageIntentByName({ + ...locale, + platform: "tv", + name: "apps", +}), appLandingPageFlowActionPresentation); +export const TVArcadeController = defineLandingPageController("/tv/arcade", (locale) => makeArcadeGroupingPageIntent({ + ...locale, + platform: "tv", +}), arcadeLandingPageFlowActionPresentation); +export const TVSearchLandingController = defineLandingPageController("/tv/search", (locale) => makeSearchLandingPageIntent({ + ...locale, + platform: "tv", +}), searchLandingPageFlowActionPresentation); +//# sourceMappingURL=platform-landing-page-intent-controllers.js.map \ No newline at end of file diff --git a/node_modules/@jet-app/app-store/tmp/src/common/web-navigation/platform-landing-page-utils.js b/node_modules/@jet-app/app-store/tmp/src/common/web-navigation/platform-landing-page-utils.js new file mode 100644 index 0000000..c408425 --- /dev/null +++ b/node_modules/@jet-app/app-store/tmp/src/common/web-navigation/platform-landing-page-utils.js @@ -0,0 +1,139 @@ +import { isNothing, unwrapOptional as unwrap } from "@jet/environment/types/optional"; +import { FlowAction } from "../../api/models"; +import { generateRoutes } from "../util/generate-routes"; +import { updateWebNavigation } from "./inject-web-navigation"; +/** + * Determine if the two {@linkcode LandingPageIntent} arguments are equivalent + */ +export function landingPageIntentsAreEquivalent(activeIntent, navLinkIntent) { + if (isNothing(activeIntent) || isNothing(navLinkIntent)) { + return false; + } + for (const key of ["$kind", "storefront", "language"]) { + if (activeIntent[key] !== navLinkIntent[key]) { + return false; + } + } + return true; +} +/** + * Dynamically create an {@linkcode IntentController} for a platform "landing page" + * + * A "landing page" is a vanity URL within a specific platform that loads some other + * page under-the-hood; the "canonical URL" for the "landing page" should reflect this + * vanity URL, rather than the real canonical URL for the underlying Media API entity. + * + * @param url the vanity URL for the landing page + * @param intentFactory a function that produces the underlying `Intent` for the data backing the landing page + * @param prepareAction a function that can be used to provide additional configuration of the `FlowAction` for a landing page + */ +export function defineLandingPageController(url, intentFactory, prepareAction) { + const intentKind = `LandingPage_${url.substring(1)}_Intent`; + const { routes, makeCanonicalUrl } = generateRoutes((locale) => ({ + ...locale, + $kind: intentKind, + }), url, [], { + exclusions: [ + { + query: ["term"], + }, + ], + }); + return { + $intentKind: intentKind, + routes, + async perform(landingPageIntent, objectGraph) { + var _a; + const pageIntent = intentFactory({ + storefront: landingPageIntent.storefront, + language: landingPageIntent.language, + }); + const viewModel = await objectGraph.dispatcher.dispatch(pageIntent, objectGraph); + if (viewModel) { + // Override the default canonical URL to use the vanity URL instead; this ensures + // that the navigation mechanics of the "web" client respect the vanity URL, which the + // Media API would not know about when providing it's own value for this property + // @ts-expect-error TypeScript can't know that `landingPageIntent` satisfies the requirements of + // `makeCanonicalUrl`, but this will be safe at runtime because all we actually require + // from the intent is the locale information + viewModel.canonicalURL = makeCanonicalUrl(objectGraph, landingPageIntent); + (_a = objectGraph.seo) === null || _a === void 0 ? void 0 : _a.updateCanonicalURL(viewModel, viewModel.canonicalURL); + // If the web navigation has already been injected, the active state of the "tabs" will be incorrect + // since non-"landing pages" never have display active landing page links. We need to update the + // navigation shelf, if it exists, based on the `landingPageIntent` + updateWebNavigation(objectGraph, viewModel, unwrap(pageIntent.platform), landingPageIntent); + } + return viewModel; + }, + buildIntent(locale) { + return { + ...locale, + $kind: intentKind, + }; + }, + buildAction(locale, objectGraph) { + const intent = this.buildIntent(locale); + return this.actionFor(intent, objectGraph, {}); + }, + actionFor(landingPageIntent, objectGraph) { + const action = new FlowAction("page"); + action.destination = landingPageIntent; + // @ts-expect-error TypeScript can't know that `landingPageIntent` satisfies the requirements of + // `makeCanonicalUrl`, but this will be safe at runtime because all we actually require + // from the intent is the locale information + action.pageUrl = makeCanonicalUrl(objectGraph, landingPageIntent); + prepareAction === null || prepareAction === void 0 ? void 0 : prepareAction(objectGraph, action); + return action; + }, + }; +} +/** + * Dynamically create an {@linkcode IntentController} that redirects from the platform root + * to the default landing page + * + * @param url the URL for the platform to redirect for + * @param intentFactory a function that produces the `Intent` for the `LandingPageController` that should be delegated to + */ +export function definePlatformRootRedirectController(url, intentFactory) { + const intentKind = `PlatformRootRedirect_${url.substring(1)}_Intent`; + const { routes } = generateRoutes((locale) => ({ + ...locale, + $kind: intentKind, + }), url); + return { + $intentKind: intentKind, + routes, + async perform(landingPageIntent, objectGraph) { + const pageIntent = intentFactory({ + storefront: landingPageIntent.storefront, + language: landingPageIntent.language, + }); + return await objectGraph.dispatcher.dispatch(pageIntent, objectGraph); + }, + }; +} +/** + * Dynamically create an {@linkcode IntentController} that redirects from the root + * to the default landing page + * + * @param intentFactory a function that produces the `Intent` for the `LandingPageController` that should be delegated to + */ +export function defineRootRedirectController(intentFactory) { + const intentKind = `RootRedirect_Intent`; + const { routes } = generateRoutes((locale) => ({ + ...locale, + $kind: intentKind, + }), "/"); + return { + $intentKind: intentKind, + routes, + async perform(landingPageIntent, objectGraph) { + const pageIntent = intentFactory({ + storefront: landingPageIntent.storefront, + language: landingPageIntent.language, + }); + return await objectGraph.dispatcher.dispatch(pageIntent, objectGraph); + }, + }; +} +//# sourceMappingURL=platform-landing-page-utils.js.map \ No newline at end of file diff --git a/node_modules/@jet-app/app-store/tmp/src/common/web-navigation/platform-selection.js b/node_modules/@jet-app/app-store/tmp/src/common/web-navigation/platform-selection.js new file mode 100644 index 0000000..b583859 --- /dev/null +++ b/node_modules/@jet-app/app-store/tmp/src/common/web-navigation/platform-selection.js @@ -0,0 +1,115 @@ +import { allPreviewPlatforms } from "../../api/models/preview-platform"; +import { iPadTodayPageController, WatchDiscoverController, VisionAppsAndGamesController, MacDiscoverController, iPhoneTodayPageController, TVDiscoverController, } from "./platform-landing-page-intent-controllers"; +import { unreachable } from "../../foundation/util/errors"; +import { getLocale } from "../locale"; +import { createArtworkForSystemImage } from "../content/artwork/artwork"; +import * as metricsHelpersClicks from "../metrics/helpers/clicks"; +import { newLocationTracker } from "../metrics/helpers/location"; +function makeiPhonePlatformSelector(objectGraph, isActive) { + const action = iPhoneTodayPageController.buildAction(getLocale(objectGraph), objectGraph); + action.title = objectGraph.loc.string("Web.Navigation.Platform.Phone"); + action.artwork = createArtworkForSystemImage(objectGraph, "iphone.gen2"); + return { + action, + isActive, + }; +} +function makeiPadPlatformSelector(objectGraph, isActive) { + const action = iPadTodayPageController.buildAction(getLocale(objectGraph), objectGraph); + action.title = objectGraph.loc.string("Web.Navigation.Platform.Pad"); + action.artwork = createArtworkForSystemImage(objectGraph, "ipad.gen2.landscape"); + return { + action, + isActive, + }; +} +function makeMacPlatformSelector(objectGraph, isActive) { + const action = MacDiscoverController.buildAction(getLocale(objectGraph), objectGraph); + action.title = objectGraph.loc.string("Web.Navigation.Platform.Mac"); + action.artwork = createArtworkForSystemImage(objectGraph, "macbook.gen2"); + return { + action, + isActive, + }; +} +function makeVisionPlatformSelector(objectGraph, isActive) { + const action = VisionAppsAndGamesController.buildAction(getLocale(objectGraph), objectGraph); + action.title = objectGraph.loc.string("Web.Navigation.Platform.Vision"); + action.artwork = createArtworkForSystemImage(objectGraph, "visionpro"); + return { + action, + isActive, + }; +} +function makeWatchPlatformSelector(objectGraph, isActive) { + const action = WatchDiscoverController.buildAction(getLocale(objectGraph), objectGraph); + action.title = objectGraph.loc.string("Web.Navigation.Platform.Watch"); + action.artwork = createArtworkForSystemImage(objectGraph, "applewatch"); + return { + action, + isActive, + }; +} +function makeTVPlatformSelector(objectGraph, isActive) { + const action = TVDiscoverController.buildAction(getLocale(objectGraph), objectGraph); + action.title = objectGraph.loc.string("Web.Navigation.Platform.TV"); + action.artwork = createArtworkForSystemImage(objectGraph, "tv"); + return { + action, + isActive, + }; +} +function makePlatformSelector(objectGraph, platform, activePlatform) { + let selector; + switch (platform) { + case "iphone": { + selector = makeiPhonePlatformSelector(objectGraph, activePlatform === "iphone"); + break; + } + case "ipad": { + selector = makeiPadPlatformSelector(objectGraph, activePlatform === "ipad"); + break; + } + case "mac": { + selector = makeMacPlatformSelector(objectGraph, activePlatform === "mac"); + break; + } + case "vision": { + selector = makeVisionPlatformSelector(objectGraph, activePlatform === "vision"); + break; + } + case "watch": { + selector = makeWatchPlatformSelector(objectGraph, activePlatform === "watch"); + break; + } + case "tv": { + selector = makeTVPlatformSelector(objectGraph, activePlatform === "tv"); + break; + } + default: + unreachable(platform); + } + if (objectGraph.client.isWeb) { + metricsHelpersClicks.addClickEventToAction(objectGraph, selector.action, { + id: platform, + actionType: "navigate", + locationTracker: newLocationTracker(), + pageInformation: undefined, + }, false, "link"); + } + return selector; +} +/** + * + * @param objectGraph + * @param activePlatform the active platform; navigation links to it will be presented with an "active" style + * @returns + */ +export function createPlatformSelectors(objectGraph, activePlatform) { + const isVisionSupported = objectGraph.bag.enableVisionPlatform; + return (allPreviewPlatforms + // Rejects vision if its not supported and let's all other platforms pass + .filter((platform) => isVisionSupported || platform !== "vision") + .map((platform) => makePlatformSelector(objectGraph, platform, activePlatform))); +} +//# sourceMappingURL=platform-selection.js.map \ No newline at end of file diff --git a/node_modules/@jet-app/app-store/tmp/src/common/web-navigation/search-results-platform-selection.js b/node_modules/@jet-app/app-store/tmp/src/common/web-navigation/search-results-platform-selection.js new file mode 100644 index 0000000..00993f8 --- /dev/null +++ b/node_modules/@jet-app/app-store/tmp/src/common/web-navigation/search-results-platform-selection.js @@ -0,0 +1,28 @@ +import { allPreviewPlatforms } from "../../api/models/preview-platform"; +import { makeCanonicalSearchResultsPageUrl } from "../search/search-page-url"; +function replaceDestinationIntent(objectGraph, action, intent, platform) { + const updatedIntent = { + ...intent, + platform, + }; + action.destination = updatedIntent; + action.pageUrl = makeCanonicalSearchResultsPageUrl(objectGraph, updatedIntent); +} +/** + * Replaces each of the "platform selector" actions with one that navigates to the + * {@linkcode searchResultsPageIntent} in each platform + * + * This is necessary because the existing platform selector, which normally takes + * the user to a platform landing page, instead takes the user to the search results + * page within the selected platform + */ +export function replacePlatformSelectorDestinationWithSearchResults(objectGraph, webNavigation, searchResultsPageIntent) { + const isVisionSupported = objectGraph.bag.enableVisionPlatform; + allPreviewPlatforms + // Rejects vision if its not supported and let's all other platforms pass + .filter((platform) => isVisionSupported || platform !== "vision") + .forEach((platform, index) => { + replaceDestinationIntent(objectGraph, webNavigation.platforms[index].action, searchResultsPageIntent, platform); + }); +} +//# sourceMappingURL=search-results-platform-selection.js.map \ No newline at end of file diff --git a/node_modules/@jet-app/app-store/tmp/src/common/web-navigation/web-navigation.js b/node_modules/@jet-app/app-store/tmp/src/common/web-navigation/web-navigation.js new file mode 100644 index 0000000..13b7f6d --- /dev/null +++ b/node_modules/@jet-app/app-store/tmp/src/common/web-navigation/web-navigation.js @@ -0,0 +1,28 @@ +import { createPlatformSelectors } from "./platform-selection"; +import { createLandingPageLinks } from "./landing-page-links-by-platform"; +import { makeWebSearchAction } from "../search/web-search-action"; +/** + * Create a {@linkcode WebNavigation} based on the active {@linkcode Intent} + */ +export function createWebNavigation(objectGraph, platform) { + const webNavigation = { + platforms: [], + tabs: [], + searchAction: makeWebSearchAction(objectGraph, platform), + }; + setActivePlatform(objectGraph, webNavigation, platform); + return webNavigation; +} +/** + * Updates a {@linkcode WebNavigation} to reflect: + * + * 1. the platform specified by {@linkcode platform} + * 2. the "active landing page" specified by {@linkcode intent} + */ +export function setActivePlatform(objectGraph, shelf, platform, intent) { + shelf.platforms = createPlatformSelectors(objectGraph, platform); + const searchActionDestination = shelf.searchAction.destination; + shelf.tabs = createLandingPageLinks(objectGraph, platform, intent); + searchActionDestination.platform = platform; +} +//# sourceMappingURL=web-navigation.js.map \ No newline at end of file -- cgit v1.2.3