From bce557cc2dc767628bed6aac87301a1be7c5431b Mon Sep 17 00:00:00 2001
From: rxliuli <rxliuli@gmail.com>
Date: Tue, 4 Nov 2025 05:03:50 +0800
Subject: init commit

---
 src/components/pages/ProductPage.svelte | 77 +++++++++++++++++++++++++++++++++
 1 file changed, 77 insertions(+)
 create mode 100644 src/components/pages/ProductPage.svelte

(limited to 'src/components/pages/ProductPage.svelte')

diff --git a/src/components/pages/ProductPage.svelte b/src/components/pages/ProductPage.svelte
new file mode 100644
index 0000000..30b0ad8
--- /dev/null
+++ b/src/components/pages/ProductPage.svelte
@@ -0,0 +1,77 @@
+<script lang="ts">
+    import type { ShelfBasedProductPage } from '@jet-app/app-store/api/models';
+    import { isFlowAction } from '@jet-app/app-store/api/models';
+    import type { WebRenderablePage } from '@jet-app/app-store/api/models/web-renderable-page';
+
+    import DefaultPage, {
+        type DefaultPageRequirements,
+    } from '~/components/pages/DefaultPage.svelte';
+    import MarkerShelf from '~/components/jet/shelf/MarkerShelf.svelte';
+    import ProductPageArcadeFooter from '~/components/ProductPageArcadeFooter.svelte';
+    import { getProductPageShelvesWithExpandedMedia } from '~/utils/shelves';
+    import { setAccessibilityLayoutContext } from '~/context/accessibility-layout';
+    import { getJet } from '~/jet';
+    import { isProductPageLinkShelf } from '~/components/jet/shelf/ProductPageLinkShelf.svelte';
+    import { isEulaPageIntent } from '@jet-app/app-store/api/intents/eula-page-intent';
+    export let page: ShelfBasedProductPage & WebRenderablePage;
+
+    const jet = getJet();
+
+    $: ({ presentationOptions, webNavigation } = page);
+
+    $: shelves = getProductPageShelvesWithExpandedMedia(page);
+
+    let defaultPageRequirements: DefaultPageRequirements;
+
+    $: defaultPageRequirements = {
+        shelves,
+        presentationOptions,
+        webNavigation,
+    };
+
+    // Set up accessibility layout context for neighbor shelf detection
+    $: {
+        setAccessibilityLayoutContext({ shelves });
+
+        /**
+         * We suppport "deep linking" to the product page with the License Agreement modal open by
+         * default, based on the presence of the `lic` query parameter. No other modals support
+         * opening via deep link, which is why there isn't a more robust solution for this use case.
+         * Instead, we are just firing off the click action from the license agreement shelf.
+         */
+        if (page.canonicalURL) {
+            const canonicalUrl = new URL(page.canonicalURL);
+            const hasLic = canonicalUrl.searchParams.has('lic');
+
+            if (hasLic && shelves) {
+                const eulaItem = shelves
+                    .find(isProductPageLinkShelf)
+                    ?.items.find(
+                        ({ clickAction }) =>
+                            isFlowAction(clickAction) &&
+                            clickAction.destination &&
+                            isEulaPageIntent(clickAction.destination),
+                    );
+
+                if (eulaItem) {
+                    jet.perform(eulaItem.clickAction);
+                }
+            }
+        }
+    }
+
+    // TODO: replace with `supportsArcade` from Jet
+    // rdar://143706610 (Support `supportsArcade` attribute)
+    $: supportsArcade =
+        page.lockup.offerDisplayProperties?.offerType === 'arcadeApp';
+</script>
+
+<DefaultPage page={defaultPageRequirements}>
+    <svelte:fragment slot="marker-shelf" let:shelf>
+        <MarkerShelf {shelf} {page} />
+    </svelte:fragment>
+</DefaultPage>
+
+{#if supportsArcade}
+    <ProductPageArcadeFooter />
+{/if}
-- 
cgit v1.2.3

