[D1X] Minimum interest experiment (#4653)

* Change up copy

* Add min # prompt

* Improve style

* Add gate

* Tweak padding

* Translate

* Revert string change

---------

Co-authored-by: dan <dan.abramov@gmail.com>
zio/stable
Eric Bailey 2024-07-02 14:19:03 -05:00 committed by GitHub
parent 0012c6d40f
commit 4bb4452f08
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 69 additions and 2 deletions

View File

@ -2,6 +2,7 @@ export type Gate =
// Keep this alphabetic please. // Keep this alphabetic please.
| 'debug_show_feedcontext' | 'debug_show_feedcontext'
| 'native_pwi_disabled' | 'native_pwi_disabled'
| 'onboarding_minimum_interests'
| 'request_notifications_permission_after_onboarding_v2' | 'request_notifications_permission_after_onboarding_v2'
| 'show_avi_follow_button' | 'show_avi_follow_button'
| 'show_follow_back_label_v2' | 'show_follow_back_label_v2'

View File

@ -6,8 +6,10 @@ import {useQuery} from '@tanstack/react-query'
import {useAnalytics} from '#/lib/analytics/analytics' import {useAnalytics} from '#/lib/analytics/analytics'
import {logEvent} from '#/lib/statsig/statsig' import {logEvent} from '#/lib/statsig/statsig'
import {useGate} from '#/lib/statsig/statsig'
import {capitalize} from '#/lib/strings/capitalize' import {capitalize} from '#/lib/strings/capitalize'
import {logger} from '#/logger' import {logger} from '#/logger'
import {isWeb} from '#/platform/detection'
import {useAgent} from '#/state/session' import {useAgent} from '#/state/session'
import {useOnboardingDispatch} from '#/state/shell' import {useOnboardingDispatch} from '#/state/shell'
import { import {
@ -27,16 +29,23 @@ import * as Toggle from '#/components/forms/Toggle'
import {IconCircle} from '#/components/IconCircle' import {IconCircle} from '#/components/IconCircle'
import {ArrowRotateCounterClockwise_Stroke2_Corner0_Rounded as ArrowRotateCounterClockwise} from '#/components/icons/ArrowRotateCounterClockwise' import {ArrowRotateCounterClockwise_Stroke2_Corner0_Rounded as ArrowRotateCounterClockwise} from '#/components/icons/ArrowRotateCounterClockwise'
import {ChevronRight_Stroke2_Corner0_Rounded as ChevronRight} from '#/components/icons/Chevron' import {ChevronRight_Stroke2_Corner0_Rounded as ChevronRight} from '#/components/icons/Chevron'
import {CircleInfo_Stroke2_Corner0_Rounded as CircleInfo} from '#/components/icons/CircleInfo'
import {EmojiSad_Stroke2_Corner0_Rounded as EmojiSad} from '#/components/icons/Emoji' import {EmojiSad_Stroke2_Corner0_Rounded as EmojiSad} from '#/components/icons/Emoji'
import {Hashtag_Stroke2_Corner0_Rounded as Hashtag} from '#/components/icons/Hashtag' import {Hashtag_Stroke2_Corner0_Rounded as Hashtag} from '#/components/icons/Hashtag'
import {Loader} from '#/components/Loader' import {Loader} from '#/components/Loader'
import {Text} from '#/components/Typography' import {Text} from '#/components/Typography'
const PROMPT_HEIGHT = isWeb ? 42 : 36
// matches the padding of the OnboardingControls.Portal
const PROMPT_OFFSET = isWeb ? a.pb_2xl.paddingBottom : a.pb_lg.paddingBottom
const MIN_INTERESTS = 3
export function StepInterests() { export function StepInterests() {
const {_} = useLingui() const {_} = useLingui()
const t = useTheme() const t = useTheme()
const {gtMobile} = useBreakpoints() const {gtMobile} = useBreakpoints()
const {track} = useAnalytics() const {track} = useAnalytics()
const gate = useGate()
const interestsDisplayNames = useInterestsDisplayNames() const interestsDisplayNames = useInterestsDisplayNames()
const {state, dispatch} = React.useContext(Context) const {state, dispatch} = React.useContext(Context)
@ -134,6 +143,11 @@ export function StepInterests() {
track('OnboardingV2:StepInterests:Start') track('OnboardingV2:StepInterests:Start')
}, [track]) }, [track])
const isMinimumInterestsEnabled = gate('onboarding_minimum_interests')
const meetsMinimumRequirement = isMinimumInterestsEnabled
? interests.length >= MIN_INTERESTS
: true
const title = isError ? ( const title = isError ? (
<Trans>Oh no! Something went wrong.</Trans> <Trans>Oh no! Something went wrong.</Trans>
) : ( ) : (
@ -171,8 +185,13 @@ export function StepInterests() {
<TitleText>{title}</TitleText> <TitleText>{title}</TitleText>
<DescriptionText>{description}</DescriptionText> <DescriptionText>{description}</DescriptionText>
{isMinimumInterestsEnabled && (
<DescriptionText style={[a.pt_sm]}>
<Trans>Choose 3 or more:</Trans>
</DescriptionText>
)}
<View style={[a.w_full, a.pt_2xl]}> <View style={[a.w_full, isMinimumInterestsEnabled ? a.pt_md : a.pt_2xl]}>
{isLoading ? ( {isLoading ? (
<Loader size="xl" /> <Loader size="xl" />
) : isError || !data ? ( ) : isError || !data ? (
@ -248,7 +267,7 @@ export function StepInterests() {
</View> </View>
) : ( ) : (
<Button <Button
disabled={saving || !data} disabled={saving || !data || !meetsMinimumRequirement}
variant="gradient" variant="gradient"
color="gradient_sky" color="gradient_sky"
size="large" size="large"
@ -263,6 +282,53 @@ export function StepInterests() {
/> />
</Button> </Button>
)} )}
{!meetsMinimumRequirement && (
<View
style={[
a.align_center,
a.absolute,
{
top: 0,
left: 0,
right: 0,
margin: 'auto',
transform: [
{
translateY:
-1 *
(PROMPT_OFFSET + PROMPT_HEIGHT + a.pb_lg.paddingBottom),
},
],
},
]}>
<View
style={[
a.flex_row,
a.align_center,
a.gap_sm,
a.rounded_full,
a.border,
t.atoms.bg_contrast_25,
t.atoms.border_contrast_medium,
{
height: PROMPT_HEIGHT,
...t.atoms.shadow_sm,
shadowOpacity: 0.1,
},
isWeb
? [a.py_md, a.px_lg, a.pr_xl]
: [a.py_sm, a.px_md, a.pr_lg],
]}>
<CircleInfo />
<Text>
<Trans>
Choose at least {MIN_INTERESTS - interests.length} more
</Trans>
</Text>
</View>
</View>
)}
</OnboardingControls.Portal> </OnboardingControls.Portal>
</View> </View>
) )