From 579a07db9eedc3e887aa5aa8908840690e48d7c1 Mon Sep 17 00:00:00 2001 From: Hailey Date: Tue, 13 Feb 2024 09:31:26 -0800 Subject: [PATCH] add screen to onboarding flow --- src/screens/Onboarding/StepProfile/index.tsx | 158 +++++++++++++++++++ src/screens/Onboarding/index.tsx | 2 + src/screens/Onboarding/state.ts | 11 +- 3 files changed, 169 insertions(+), 2 deletions(-) create mode 100644 src/screens/Onboarding/StepProfile/index.tsx diff --git a/src/screens/Onboarding/StepProfile/index.tsx b/src/screens/Onboarding/StepProfile/index.tsx new file mode 100644 index 0000000000..b1c610fbcb --- /dev/null +++ b/src/screens/Onboarding/StepProfile/index.tsx @@ -0,0 +1,158 @@ +import React from 'react' +import {View} from 'react-native' +import {useLingui} from '@lingui/react' +import {msg, Trans} from '@lingui/macro' + +import {logger} from '#/logger' +import {atoms as a, useTheme} from '#/alf' +import {Button, ButtonText, ButtonIcon} from '#/components/Button' +import {News2_Stroke2_Corner0_Rounded as News} from '#/components/icons/News2' +import {Check_Stroke2_Corner0_Rounded as Check} from '#/components/icons/Check' +import {Growth_Stroke2_Corner0_Rounded as Growth} from '#/components/icons/Growth' +import {Trending2_Stroke2_Corner2_Rounded as Trending} from '#/components/icons/Trending2' +import {Text} from '#/components/Typography' +import {useOnboardingDispatch} from '#/state/shell' +import {Loader} from '#/components/Loader' +import {useSetSaveFeedsMutation} from '#/state/queries/preferences' +import {getAgent} from '#/state/session' +import {useAnalytics} from '#/lib/analytics/analytics' + +import {Context} from '#/screens/Onboarding/state' +import { + Title, + Description, + OnboardingControls, +} from '#/screens/Onboarding/Layout' +import {IconCircle} from '#/screens/Onboarding/IconCircle' +import { + bulkWriteFollows, + sortPrimaryAlgorithmFeeds, +} from '#/screens/Onboarding/util' + +export function StepProfile() { + const {_} = useLingui() + const t = useTheme() + const {track} = useAnalytics() + const {state, dispatch} = React.useContext(Context) + const onboardDispatch = useOnboardingDispatch() + const [saving, setSaving] = React.useState(false) + const {mutateAsync: saveFeeds} = useSetSaveFeedsMutation() + + const finishOnboarding = React.useCallback(async () => { + setSaving(true) + + const { + interestsStepResults, + suggestedAccountsStepResults, + algoFeedsStepResults, + topicalFeedsStepResults, + } = state + const {selectedInterests} = interestsStepResults + const selectedFeeds = [ + ...sortPrimaryAlgorithmFeeds(algoFeedsStepResults.feedUris), + ...topicalFeedsStepResults.feedUris, + ] + + try { + await Promise.all([ + bulkWriteFollows(suggestedAccountsStepResults.accountDids), + // these must be serial + (async () => { + await getAgent().setInterestsPref({tags: selectedInterests}) + await saveFeeds({ + saved: selectedFeeds, + pinned: selectedFeeds, + }) + })(), + ]) + } catch (e: any) { + logger.info(`onboarding: bulk save failed`) + logger.error(e) + // don't alert the user, just let them into their account + } + + setSaving(false) + dispatch({type: 'finish'}) + onboardDispatch({type: 'finish'}) + track('OnboardingV2:StepFinished:End') + track('OnboardingV2:Complete') + }, [state, dispatch, onboardDispatch, setSaving, saveFeeds, track]) + + React.useEffect(() => { + track('OnboardingV2:StepFinished:Start') + }, [track]) + + return ( + + + + + <Trans>You're ready to go!</Trans> + + + We hope you have a wonderful time. Remember, Bluesky is: + + + + + + + + Public + + + + Your posts, likes, and blocks are public. Mutes are private. + + + + + + + + + Open + + + Never lose access to your followers or data. + + + + + + + + Flexible + + + Choose the algorithms that power your custom feeds. + + + + + + + + + + ) +} diff --git a/src/screens/Onboarding/index.tsx b/src/screens/Onboarding/index.tsx index 9e5029e87a..32ad53497c 100644 --- a/src/screens/Onboarding/index.tsx +++ b/src/screens/Onboarding/index.tsx @@ -13,6 +13,7 @@ import {StepAlgoFeeds} from '#/screens/Onboarding/StepAlgoFeeds' import {StepTopicalFeeds} from '#/screens/Onboarding/StepTopicalFeeds' import {StepFinished} from '#/screens/Onboarding/StepFinished' import {StepModeration} from '#/screens/Onboarding/StepModeration' +import {StepProfile} from '#/screens/Onboarding/StepProfile' export function Onboarding() { const {_} = useLingui() @@ -62,6 +63,7 @@ export function Onboarding() { {state.activeStep === 'algoFeeds' && } {state.activeStep === 'topicalFeeds' && } {state.activeStep === 'moderation' && } + {state.activeStep === 'profile' && } {state.activeStep === 'finished' && } diff --git a/src/screens/Onboarding/state.ts b/src/screens/Onboarding/state.ts index bd8205ca2d..817c65a08c 100644 --- a/src/screens/Onboarding/state.ts +++ b/src/screens/Onboarding/state.ts @@ -12,6 +12,7 @@ export type OnboardingState = { | 'algoFeeds' | 'topicalFeeds' | 'moderation' + | 'profile' | 'finished' activeStepIndex: number @@ -154,8 +155,11 @@ export function reducer( next.activeStep = 'moderation' next.activeStepIndex = 6 } else if (s.activeStep === 'moderation') { - next.activeStep = 'finished' + next.activeStep = 'profile' next.activeStepIndex = 7 + } else if (s.activeStep === 'profile') { + next.activeStep = 'finished' + next.activeStepIndex = 8 } break } @@ -175,9 +179,12 @@ export function reducer( } else if (s.activeStep === 'moderation') { next.activeStep = 'topicalFeeds' next.activeStepIndex = 5 - } else if (s.activeStep === 'finished') { + } else if (s.activeStep === 'profile') { next.activeStep = 'moderation' next.activeStepIndex = 6 + } else if (s.activeStep === 'finished') { + next.activeStep = 'profile' + next.activeStepIndex = 7 } break }