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 (
+
+
+
+
+ You're ready to go!
+
+
+ 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
}