From 3c9a41305c30901d7bf15ab804f8c564dbd1aa16 Mon Sep 17 00:00:00 2001 From: Eric Bailey Date: Fri, 4 Apr 2025 11:13:13 -0500 Subject: [PATCH] Add interests card to top of Explore --- src/screens/Search/Explore.tsx | 24 ++++ .../Search/modules/ExploreInterestsCard.tsx | 128 ++++++++++++++++++ src/state/queries/nuxs/definitions.ts | 20 ++- 3 files changed, 166 insertions(+), 6 deletions(-) create mode 100644 src/screens/Search/modules/ExploreInterestsCard.tsx diff --git a/src/screens/Search/Explore.tsx b/src/screens/Search/Explore.tsx index 00eb6c4330..088bc5724b 100644 --- a/src/screens/Search/Explore.tsx +++ b/src/screens/Search/Explore.tsx @@ -21,6 +21,7 @@ import { useFeedPreviews, } from '#/state/queries/explore-feed-previews' import {useGetPopularFeedsQuery} from '#/state/queries/feed' +import {Nux, useNux} from '#/state/queries/nuxs' import {usePreferencesQuery} from '#/state/queries/preferences' import {useSuggestedFollowsQuery} from '#/state/queries/suggested-follows' import {useGetSuggestedFeedsQuery} from '#/state/queries/trending/useGetSuggestedFeedsQuery' @@ -36,6 +37,7 @@ import { StarterPackCard, StarterPackCardSkeleton, } from '#/screens/Search/components/StarterPackCard' +import {ExploreInterestsCard} from '#/screens/Search/modules/ExploreInterestsCard' import {ExploreRecommendations} from '#/screens/Search/modules/ExploreRecommendations' import {ExploreTrendingTopics} from '#/screens/Search/modules/ExploreTrendingTopics' import {ExploreTrendingVideos} from '#/screens/Search/modules/ExploreTrendingVideos' @@ -181,6 +183,10 @@ type ExploreScreenItems = key: string } | FeedPreviewItem + | { + type: 'interests-card' + key: 'interests-card' + } export function Explore({ focusSearchInput, @@ -233,6 +239,9 @@ export function Explore({ error: feedsError, fetchNextPage: fetchNextFeedsPage, } = useGetPopularFeedsQuery({limit: 10}) + const interestsNux = useNux(Nux.ExploreInterestsCard) + const showInterestsNux = + interestsNux.status === 'ready' && !interestsNux.nux?.completed const profiles: typeof suggestedProfiles & typeof interestProfiles = !selectedInterest ? suggestedProfiles : interestProfiles @@ -558,6 +567,16 @@ export function Explore({ return i }, [feedPreviewSlices, isFetchingNextPageFeedPreviews]) + const interestsNuxModule = useMemo(() => { + if (!showInterestsNux) return [] + return [ + { + type: 'interests-card', + key: 'interests-card', + }, + ] + }, [showInterestsNux]) + const isNewUser = guide?.guide === 'follow-10' && !guide.isComplete const items = useMemo(() => { const i: ExploreScreenItems[] = [] @@ -565,6 +584,7 @@ export function Explore({ // Dynamic module ordering i.push(topBorder) + i.push(...interestsNuxModule) if (isNewUser) { i.push(...suggestedFollowsModule) i.push(...suggestedStarterPacksModule) @@ -588,6 +608,7 @@ export function Explore({ suggestedFeedsModule, trendingTopicsModule, feedPreviewsModule, + interestsNuxModule, gate, ]) @@ -854,6 +875,9 @@ export function Explore({ /> ) } + case 'interests-card': { + return + } } }, [ diff --git a/src/screens/Search/modules/ExploreInterestsCard.tsx b/src/screens/Search/modules/ExploreInterestsCard.tsx new file mode 100644 index 0000000000..7d30b02fd3 --- /dev/null +++ b/src/screens/Search/modules/ExploreInterestsCard.tsx @@ -0,0 +1,128 @@ +import {useState} from 'react' +import {View} from 'react-native' +import {msg, Trans} from '@lingui/macro' +import {useLingui} from '@lingui/react' + +import {Nux,useSaveNux} from '#/state/queries/nuxs' +import {usePreferencesQuery} from '#/state/queries/preferences' +import {useInterestsDisplayNames} from '#/screens/Onboarding/state' +import {atoms as a, useGutters,useTheme} from '#/alf' +import {Button, ButtonIcon, ButtonText} from '#/components/Button' +import {TimesLarge_Stroke2_Corner0_Rounded as X} from '#/components/icons/Times' +import {Link} from '#/components/Link' +import * as Prompt from '#/components/Prompt' +import {Text} from '#/components/Typography' + +export function ExploreInterestsCard() { + const t = useTheme() + const {_} = useLingui() + const gutters = useGutters([0, 'base']) + const {data: preferences} = usePreferencesQuery() + const interestsDisplayNames = useInterestsDisplayNames() + const {mutateAsync: saveNux} = useSaveNux() + const trendingPrompt = Prompt.usePromptControl() + const [closing, setClosing] = useState(false) + + const onClose = () => { + trendingPrompt.open() + } + const onConfirmClose = () => { + setClosing(true) + // if this fails, they can try again later + saveNux({ + id: Nux.ExploreInterestsCard, + completed: true, + data: undefined, + }).catch(() => {}) + } + + return closing ? null : ( + <> + + + + + + Your interests + + + {preferences?.interests?.tags && + preferences.interests.tags.length > 0 ? ( + + {preferences.interests.tags.map(tag => ( + + + {interestsDisplayNames[tag]} + + + ))} + + ) : null} + + + + Your selected interests help us serve you content you care about. + + + + + + Edit interests + + + + + + + + ) +} diff --git a/src/state/queries/nuxs/definitions.ts b/src/state/queries/nuxs/definitions.ts index 8166602c8a..8eb53a0a43 100644 --- a/src/state/queries/nuxs/definitions.ts +++ b/src/state/queries/nuxs/definitions.ts @@ -1,18 +1,26 @@ -import zod from 'zod' +import type zod from 'zod' -import {BaseNux} from '#/state/queries/nuxs/types' +import {type BaseNux} from '#/state/queries/nuxs/types' export enum Nux { NeueTypography = 'NeueTypography', + ExploreInterestsCard = 'ExploreInterestsCard', } export const nuxNames = new Set(Object.values(Nux)) -export type AppNux = BaseNux<{ - id: Nux.NeueTypography - data: undefined -}> +export type AppNux = BaseNux< + | { + id: Nux.NeueTypography + data: undefined + } + | { + id: Nux.ExploreInterestsCard + data: undefined + } +> export const NuxSchemas: Record | undefined> = { [Nux.NeueTypography]: undefined, + [Nux.ExploreInterestsCard]: undefined, }