ProductPage.svelte
1 <script lang="ts"> 2 import type { ShelfBasedProductPage } from '@jet-app/app-store/api/models'; 3 import { isFlowAction } from '@jet-app/app-store/api/models'; 4 import type { WebRenderablePage } from '@jet-app/app-store/api/models/web-renderable-page'; 5 6 import DefaultPage, { 7 type DefaultPageRequirements, 8 } from '~/components/pages/DefaultPage.svelte'; 9 import MarkerShelf from '~/components/jet/shelf/MarkerShelf.svelte'; 10 import ProductPageArcadeFooter from '~/components/ProductPageArcadeFooter.svelte'; 11 import { getProductPageShelvesWithExpandedMedia } from '~/utils/shelves'; 12 import { setAccessibilityLayoutContext } from '~/context/accessibility-layout'; 13 import { getJet } from '~/jet'; 14 import { isProductPageLinkShelf } from '~/components/jet/shelf/ProductPageLinkShelf.svelte'; 15 import { isEulaPageIntent } from '@jet-app/app-store/api/intents/eula-page-intent'; 16 export let page: ShelfBasedProductPage & WebRenderablePage; 17 18 const jet = getJet(); 19 20 $: ({ presentationOptions, webNavigation } = page); 21 22 $: shelves = getProductPageShelvesWithExpandedMedia(page); 23 24 let defaultPageRequirements: DefaultPageRequirements; 25 26 $: defaultPageRequirements = { 27 shelves, 28 presentationOptions, 29 webNavigation, 30 }; 31 32 // Set up accessibility layout context for neighbor shelf detection 33 $: { 34 setAccessibilityLayoutContext({ shelves }); 35 36 /** 37 * We suppport "deep linking" to the product page with the License Agreement modal open by 38 * default, based on the presence of the `lic` query parameter. No other modals support 39 * opening via deep link, which is why there isn't a more robust solution for this use case. 40 * Instead, we are just firing off the click action from the license agreement shelf. 41 */ 42 if (page.canonicalURL) { 43 const canonicalUrl = new URL(page.canonicalURL); 44 const hasLic = canonicalUrl.searchParams.has('lic'); 45 46 if (hasLic && shelves) { 47 const eulaItem = shelves 48 .find(isProductPageLinkShelf) 49 ?.items.find( 50 ({ clickAction }) => 51 isFlowAction(clickAction) && 52 clickAction.destination && 53 isEulaPageIntent(clickAction.destination), 54 ); 55 56 if (eulaItem) { 57 jet.perform(eulaItem.clickAction); 58 } 59 } 60 } 61 } 62 63 // TODO: replace with `supportsArcade` from Jet 64 // rdar://143706610 (Support `supportsArcade` attribute) 65 $: supportsArcade = 66 page.lockup.offerDisplayProperties?.offerType === 'arcadeApp'; 67 </script> 68 69 <DefaultPage page={defaultPageRequirements}> 70 <svelte:fragment slot="marker-shelf" let:shelf> 71 <MarkerShelf {shelf} {page} /> 72 </svelte:fragment> 73 </DefaultPage> 74 75 {#if supportsArcade} 76 <ProductPageArcadeFooter /> 77 {/if}