summaryrefslogtreecommitdiff
path: root/src/components/navigation/navigation-items.ts
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 /src/components/navigation/navigation-items.ts
init commit
Diffstat (limited to 'src/components/navigation/navigation-items.ts')
-rw-r--r--src/components/navigation/navigation-items.ts79
1 files changed, 79 insertions, 0 deletions
diff --git a/src/components/navigation/navigation-items.ts b/src/components/navigation/navigation-items.ts
new file mode 100644
index 0000000..8692765
--- /dev/null
+++ b/src/components/navigation/navigation-items.ts
@@ -0,0 +1,79 @@
+import {
+ isSome,
+ unwrapOptional as unwrap,
+} from '@jet/environment/types/optional';
+
+import type { NavigationItem } from '@amp/web-app-components/src/components/Navigation/types';
+import type { NavigationId } from '@amp/web-app-components/src/types';
+import type {
+ WebNavigation,
+ WebNavigationLink,
+} from '@jet-app/app-store/api/models/web-navigation';
+
+import {
+ isSystemImageArtwork,
+ getIconNameFromTemplate,
+} from '~/components/SystemImage.svelte';
+import { getIconComponentByName } from '../SFSymbol.svelte';
+import type { Artwork } from '@jet-app/app-store/api/models';
+import CategoryTabItem from '~/components/jet/web-navigation/CategoryTabItem.svelte';
+
+/**
+ * A {@linkcode NavigationItem} that includes the original {@linkcode WebNavigationLink}
+ * it was defined from, which is needed for the
+ */
+export interface NavigationItemWithTab extends NavigationItem {
+ tab: WebNavigationLink;
+ artwork?: Artwork;
+ isActive?: boolean;
+}
+
+export function navigationIdFromLink(link: WebNavigationLink): NavigationId {
+ const intent = unwrap(link.action.destination);
+
+ return {
+ type: intent.$kind,
+ // `intent.$kind` will be unique for each `Intent` used here as they are
+ // each a different `LandingPageIntent`
+ resourceId: link.action.pageUrl ?? intent.$kind,
+ };
+}
+
+/**
+ * Transform the "tabs" in the `WebNavigation` into a shape that works with our
+ * shared navigation side-bar components.
+ */
+export function makeNavLinks(
+ tabs: WebNavigationLink[],
+ { shouldShowSearchTab = false },
+): NavigationItemWithTab[] {
+ return tabs
+ .filter((tab) => {
+ const isSearchTab =
+ tab.action?.destination?.['$kind'].includes('search_Intent');
+
+ // Allows for filtering our the search tab, which we use when the sidebar is visible,
+ // since there is a search input in the sidebar
+ return isSearchTab ? shouldShowSearchTab : true;
+ })
+ .map((tab) => {
+ const { action, artwork: tabArtwork } = tab;
+ const { artwork } = action || {};
+ const hasSystemImageArtwork =
+ isSome(artwork) && isSystemImageArtwork(artwork);
+
+ return {
+ id: navigationIdFromLink(tab),
+ label: unwrap(tab.action.title),
+ url: action.pageUrl ?? undefined,
+ icon: hasSystemImageArtwork
+ ? getIconComponentByName(
+ getIconNameFromTemplate(artwork.template),
+ )
+ : undefined,
+ artwork: tabArtwork,
+ component: !hasSystemImageArtwork ? CategoryTabItem : undefined,
+ tab,
+ };
+ });
+}