From db5cf919dc01a90e7ef0aa1d83c853d8fdf13c02 Mon Sep 17 00:00:00 2001 From: Paul Frazee Date: Tue, 2 Jul 2024 22:33:19 -0700 Subject: [PATCH] Add progress guide interstitial, put behind gate --- src/components/FeedInterstitials.tsx | 24 ++++++++++++ src/components/ProgressGuide/List.tsx | 4 +- src/components/ProgressGuide/Task.tsx | 37 +++++++++--------- src/lib/statsig/gates.ts | 1 + src/state/shell/progress-guide.tsx | 14 +++---- src/view/com/posts/Feed.tsx | 54 ++++++++++++++++++++++----- 6 files changed, 96 insertions(+), 38 deletions(-) diff --git a/src/components/FeedInterstitials.tsx b/src/components/FeedInterstitials.tsx index 00342b39f2..2f4ae52bff 100644 --- a/src/components/FeedInterstitials.tsx +++ b/src/components/FeedInterstitials.tsx @@ -6,6 +6,7 @@ import {msg, Trans} from '@lingui/macro' import {useLingui} from '@lingui/react' import {useNavigation} from '@react-navigation/native' +import {useWebMediaQueries} from '#/lib/hooks/useWebMediaQueries' import {NavigationProp} from '#/lib/routes/types' import {logEvent} from '#/lib/statsig/statsig' import {useModerationOpts} from '#/state/preferences/moderation-opts' @@ -20,6 +21,7 @@ import {PersonPlus_Stroke2_Corner0_Rounded as Person} from '#/components/icons/P import {InlineLinkText} from '#/components/Link' import * as ProfileCard from '#/components/ProfileCard' import {Text} from '#/components/Typography' +import {ProgressGuideList} from './ProgressGuide/List' function CardOuter({ children, @@ -352,3 +354,25 @@ export function SuggestedFeeds() { ) } + +export function ProgressGuide() { + const t = useTheme() + const {isDesktop} = useWebMediaQueries() + + if (isDesktop) { + return null + } + + return ( + + + + ) +} diff --git a/src/components/ProgressGuide/List.tsx b/src/components/ProgressGuide/List.tsx index ad6b14e691..dd5258dc83 100644 --- a/src/components/ProgressGuide/List.tsx +++ b/src/components/ProgressGuide/List.tsx @@ -13,7 +13,7 @@ import {TimesLarge_Stroke2_Corner0_Rounded as Times} from '#/components/icons/Ti import {Text} from '#/components/Typography' import {ProgressGuideTask} from './Task' -export function ProgressGuideList({style}: {style: StyleProp}) { +export function ProgressGuideList({style}: {style?: StyleProp}) { const t = useTheme() const {_} = useLingui() const guide = useProgressGuide('like-10-and-follow-7') @@ -27,7 +27,7 @@ export function ProgressGuideList({style}: {style: StyleProp}) { style={[ t.atoms.text_contrast_medium, a.font_semibold, - a.text_xs, + a.text_sm, {textTransform: 'uppercase'}, ]}> Get started diff --git a/src/components/ProgressGuide/Task.tsx b/src/components/ProgressGuide/Task.tsx index 591eef905b..69d7bc9274 100644 --- a/src/components/ProgressGuide/Task.tsx +++ b/src/components/ProgressGuide/Task.tsx @@ -6,44 +6,41 @@ import {atoms as a, useTheme} from '#/alf' import {AnimatedCheck} from '../anim/AnimatedCheck' import {Text} from '../Typography' -export interface ProgressGuideTaskProps { - current: number - total: number - title: string - subtitle?: string -} - export function ProgressGuideTask({ current, total, title, subtitle, -}: ProgressGuideTaskProps) { +}: { + current: number + total: number + title: string + subtitle?: string +}) { const t = useTheme() return ( - + {current === total ? ( - + ) : ( )} - - - {title} - {subtitle && ( - - {subtitle} - - )} - + + + {title} + {subtitle && ( + + {subtitle} + + )} ) diff --git a/src/lib/statsig/gates.ts b/src/lib/statsig/gates.ts index e4991ad384..c8a55b9288 100644 --- a/src/lib/statsig/gates.ts +++ b/src/lib/statsig/gates.ts @@ -7,5 +7,6 @@ export type Gate = | 'show_avi_follow_button' | 'show_follow_back_label_v2' | 'new_user_guided_tour' + | 'new_user_progress_guide' | 'suggested_feeds_interstitial' | 'suggested_follows_interstitial' diff --git a/src/state/shell/progress-guide.tsx b/src/state/shell/progress-guide.tsx index d58fa8691f..3aa84bebfb 100644 --- a/src/state/shell/progress-guide.tsx +++ b/src/state/shell/progress-guide.tsx @@ -2,6 +2,7 @@ import React from 'react' import {msg} from '@lingui/macro' import {useLingui} from '@lingui/react' +import {useGate} from '#/lib/statsig/statsig' import { ProgressGuideToast, ProgressGuideToastRef, @@ -55,14 +56,10 @@ export function useProgressGuideControls() { export function Provider({children}: React.PropsWithChildren<{}>) { const {_} = useLingui() const {mutate} = useSetActiveProgressGuideMutation() + const gate = useGate() const [activeProgressGuide, setActiveProgressGuide] = - React.useState({ - guide: 'like-10-and-follow-7', - numLikes: 0, - numFollows: 0, - isComplete: false, - }) + React.useState(undefined) const firstLikeToastRef = React.useRef(null) const fifthLikeToastRef = React.useRef(null) @@ -71,6 +68,9 @@ export function Provider({children}: React.PropsWithChildren<{}>) { const controls = React.useMemo(() => { return { startProgressGuide(guide: ProgressGuideName) { + if (!gate('new_user_progress_guide')) { + return + } if (guide === 'like-10-and-follow-7') { const guideObj = { guide: 'like-10-and-follow-7', @@ -127,7 +127,7 @@ export function Provider({children}: React.PropsWithChildren<{}>) { setActiveProgressGuide(guide) }, } - }, [activeProgressGuide, setActiveProgressGuide, mutate]) + }, [activeProgressGuide, setActiveProgressGuide, mutate, gate]) return ( diff --git a/src/view/com/posts/Feed.tsx b/src/view/com/posts/Feed.tsx index 3d90b8897d..96c3781899 100644 --- a/src/view/com/posts/Feed.tsx +++ b/src/view/com/posts/Feed.tsx @@ -34,7 +34,11 @@ import {useSession} from '#/state/session' import {useAnalytics} from 'lib/analytics/analytics' import {useInitialNumToRender} from 'lib/hooks/useInitialNumToRender' import {useTheme} from 'lib/ThemeContext' -import {SuggestedFeeds, SuggestedFollows} from '#/components/FeedInterstitials' +import { + ProgressGuide, + SuggestedFeeds, + SuggestedFollows, +} from '#/components/FeedInterstitials' import {List, ListRef} from '../util/List' import {PostFeedLoadingPlaceholder} from '../util/LoadingPlaceholder' import {LoadMoreRetryBtn} from '../util/LoadMoreRetryBtn' @@ -85,14 +89,36 @@ type FeedItem = } slot: number } + | { + type: 'interstitialProgressGuide' + key: string + params: { + variant: 'default' | string + } + slot: number + } const feedInterstitialType = 'interstitialFeeds' const followInterstitialType = 'interstitialFollows' +const progressGuideInterstitialType = 'interstitialProgressGuide' const interstials: Record< 'following' | 'discover', - (FeedItem & {type: 'interstitialFeeds' | 'interstitialFollows'})[] + (FeedItem & { + type: + | 'interstitialFeeds' + | 'interstitialFollows' + | 'interstitialProgressGuide' + })[] > = { following: [ + { + type: progressGuideInterstitialType, + params: { + variant: 'default', + }, + key: progressGuideInterstitialType, + slot: 0, + }, { type: followInterstitialType, params: { @@ -111,6 +137,14 @@ const interstials: Record< }, ], discover: [ + { + type: progressGuideInterstitialType, + params: { + variant: 'default', + }, + key: progressGuideInterstitialType, + slot: 0, + }, { type: feedInterstitialType, params: { @@ -336,14 +370,14 @@ let Feed = ({ if (feedType) { for (const interstitial of interstials[feedType]) { - const feedInterstitialEnabled = - interstitial.type === feedInterstitialType && - gate('suggested_feeds_interstitial') - const followInterstitialEnabled = - interstitial.type === followInterstitialType && - gate('suggested_follows_interstitial') + const shouldShow = + (interstitial.type === feedInterstitialType && + gate('suggested_feeds_interstitial')) || + (interstitial.type === followInterstitialType && + gate('suggested_follows_interstitial')) || + interstitial.type === progressGuideInterstitialType - if (feedInterstitialEnabled || followInterstitialEnabled) { + if (shouldShow) { const variant = 'default' // replace with experiment variant const int = { ...interstitial, @@ -460,6 +494,8 @@ let Feed = ({ return } else if (item.type === followInterstitialType) { return + } else if (item.type === progressGuideInterstitialType) { + return } else if (item.type === 'slice') { if (item.slice.rootUri === FALLBACK_MARKER_POST.post.uri) { // HACK