Bluesky app fork with some witchin' additions 💫
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

[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>

authored by

Eric Bailey
dan
and committed by
GitHub
4bb4452f 0012c6d4

+69 -2
+1
src/lib/statsig/gates.ts
··· 2 2 // Keep this alphabetic please. 3 3 | 'debug_show_feedcontext' 4 4 | 'native_pwi_disabled' 5 + | 'onboarding_minimum_interests' 5 6 | 'request_notifications_permission_after_onboarding_v2' 6 7 | 'show_avi_follow_button' 7 8 | 'show_follow_back_label_v2'
+68 -2
src/screens/Onboarding/StepInterests/index.tsx
··· 6 6 7 7 import {useAnalytics} from '#/lib/analytics/analytics' 8 8 import {logEvent} from '#/lib/statsig/statsig' 9 + import {useGate} from '#/lib/statsig/statsig' 9 10 import {capitalize} from '#/lib/strings/capitalize' 10 11 import {logger} from '#/logger' 12 + import {isWeb} from '#/platform/detection' 11 13 import {useAgent} from '#/state/session' 12 14 import {useOnboardingDispatch} from '#/state/shell' 13 15 import { ··· 27 29 import {IconCircle} from '#/components/IconCircle' 28 30 import {ArrowRotateCounterClockwise_Stroke2_Corner0_Rounded as ArrowRotateCounterClockwise} from '#/components/icons/ArrowRotateCounterClockwise' 29 31 import {ChevronRight_Stroke2_Corner0_Rounded as ChevronRight} from '#/components/icons/Chevron' 32 + import {CircleInfo_Stroke2_Corner0_Rounded as CircleInfo} from '#/components/icons/CircleInfo' 30 33 import {EmojiSad_Stroke2_Corner0_Rounded as EmojiSad} from '#/components/icons/Emoji' 31 34 import {Hashtag_Stroke2_Corner0_Rounded as Hashtag} from '#/components/icons/Hashtag' 32 35 import {Loader} from '#/components/Loader' 33 36 import {Text} from '#/components/Typography' 34 37 38 + const PROMPT_HEIGHT = isWeb ? 42 : 36 39 + // matches the padding of the OnboardingControls.Portal 40 + const PROMPT_OFFSET = isWeb ? a.pb_2xl.paddingBottom : a.pb_lg.paddingBottom 41 + const MIN_INTERESTS = 3 42 + 35 43 export function StepInterests() { 36 44 const {_} = useLingui() 37 45 const t = useTheme() 38 46 const {gtMobile} = useBreakpoints() 39 47 const {track} = useAnalytics() 48 + const gate = useGate() 40 49 const interestsDisplayNames = useInterestsDisplayNames() 41 50 42 51 const {state, dispatch} = React.useContext(Context) ··· 134 143 track('OnboardingV2:StepInterests:Start') 135 144 }, [track]) 136 145 146 + const isMinimumInterestsEnabled = gate('onboarding_minimum_interests') 147 + const meetsMinimumRequirement = isMinimumInterestsEnabled 148 + ? interests.length >= MIN_INTERESTS 149 + : true 150 + 137 151 const title = isError ? ( 138 152 <Trans>Oh no! Something went wrong.</Trans> 139 153 ) : ( ··· 171 185 172 186 <TitleText>{title}</TitleText> 173 187 <DescriptionText>{description}</DescriptionText> 188 + {isMinimumInterestsEnabled && ( 189 + <DescriptionText style={[a.pt_sm]}> 190 + <Trans>Choose 3 or more:</Trans> 191 + </DescriptionText> 192 + )} 174 193 175 - <View style={[a.w_full, a.pt_2xl]}> 194 + <View style={[a.w_full, isMinimumInterestsEnabled ? a.pt_md : a.pt_2xl]}> 176 195 {isLoading ? ( 177 196 <Loader size="xl" /> 178 197 ) : isError || !data ? ( ··· 248 267 </View> 249 268 ) : ( 250 269 <Button 251 - disabled={saving || !data} 270 + disabled={saving || !data || !meetsMinimumRequirement} 252 271 variant="gradient" 253 272 color="gradient_sky" 254 273 size="large" ··· 262 281 position="right" 263 282 /> 264 283 </Button> 284 + )} 285 + 286 + {!meetsMinimumRequirement && ( 287 + <View 288 + style={[ 289 + a.align_center, 290 + a.absolute, 291 + { 292 + top: 0, 293 + left: 0, 294 + right: 0, 295 + margin: 'auto', 296 + transform: [ 297 + { 298 + translateY: 299 + -1 * 300 + (PROMPT_OFFSET + PROMPT_HEIGHT + a.pb_lg.paddingBottom), 301 + }, 302 + ], 303 + }, 304 + ]}> 305 + <View 306 + style={[ 307 + a.flex_row, 308 + a.align_center, 309 + a.gap_sm, 310 + a.rounded_full, 311 + a.border, 312 + t.atoms.bg_contrast_25, 313 + t.atoms.border_contrast_medium, 314 + { 315 + height: PROMPT_HEIGHT, 316 + ...t.atoms.shadow_sm, 317 + shadowOpacity: 0.1, 318 + }, 319 + isWeb 320 + ? [a.py_md, a.px_lg, a.pr_xl] 321 + : [a.py_sm, a.px_md, a.pr_lg], 322 + ]}> 323 + <CircleInfo /> 324 + <Text> 325 + <Trans> 326 + Choose at least {MIN_INTERESTS - interests.length} more 327 + </Trans> 328 + </Text> 329 + </View> 330 + </View> 265 331 )} 266 332 </OnboardingControls.Portal> 267 333 </View>