diff --git a/src/screens/Onboarding/StepFinished.tsx b/src/screens/Onboarding/StepFinished.tsx
index 4cc611ef..7d0bfa42 100644
--- a/src/screens/Onboarding/StepFinished.tsx
+++ b/src/screens/Onboarding/StepFinished.tsx
@@ -7,7 +7,7 @@ import {useLingui} from '@lingui/react'
import {useAnalytics} from '#/lib/analytics/analytics'
import {BSKY_APP_ACCOUNT_DID, IS_PROD_SERVICE} from '#/lib/constants'
import {DISCOVER_SAVED_FEED, TIMELINE_SAVED_FEED} from '#/lib/constants'
-import {logEvent} from '#/lib/statsig/statsig'
+import {logEvent, useGate} from '#/lib/statsig/statsig'
import {logger} from '#/logger'
import {useOverwriteSavedFeedsMutation} from '#/state/queries/preferences'
import {useAgent} from '#/state/session'
@@ -41,6 +41,7 @@ export function StepFinished() {
const [saving, setSaving] = React.useState(false)
const {mutateAsync: overwriteSavedFeeds} = useOverwriteSavedFeedsMutation()
const {getAgent} = useAgent()
+ const gate = useGate()
const finishOnboarding = React.useCallback(async () => {
setSaving(true)
@@ -67,40 +68,46 @@ export function StepFinished() {
(async () => {
await getAgent().setInterestsPref({tags: selectedInterests})
- // TODO: In the reduced onboarding, we'll want to exit early here.
+ /*
+ * In the reduced onboading experiment, we'll rely on the default
+ * feeds set in `createAgentAndCreateAccount`. No feeds will be
+ * selected in onboarding and therefore we don't need to run this
+ * code (which would overwrite the other feeds already set).
+ */
+ if (!gate('reduced_onboarding_and_home_algo')) {
+ const otherFeeds = selectedFeeds.length
+ ? selectedFeeds.map(f => ({
+ type: 'feed',
+ value: f,
+ pinned: true,
+ id: TID.nextStr(),
+ }))
+ : []
- const otherFeeds = selectedFeeds.length
- ? selectedFeeds.map(f => ({
- type: 'feed',
- value: f,
+ /*
+ * If no selected feeds and we're in prod, add the discover feed
+ * (mimics old behavior)
+ */
+ if (
+ IS_PROD_SERVICE(getAgent().service.toString()) &&
+ !otherFeeds.length
+ ) {
+ otherFeeds.push({
+ ...DISCOVER_SAVED_FEED,
pinned: true,
id: TID.nextStr(),
- }))
- : []
+ })
+ }
- /*
- * If no selected feeds and we're in prod, add the discover feed
- * (mimics old behavior)
- */
- if (
- IS_PROD_SERVICE(getAgent().service.toString()) &&
- !otherFeeds.length
- ) {
- otherFeeds.push({
- ...DISCOVER_SAVED_FEED,
- pinned: true,
- id: TID.nextStr(),
- })
+ await overwriteSavedFeeds([
+ {
+ ...TIMELINE_SAVED_FEED,
+ pinned: true,
+ id: TID.nextStr(),
+ },
+ ...otherFeeds,
+ ])
}
-
- await overwriteSavedFeeds([
- {
- ...TIMELINE_SAVED_FEED,
- pinned: true,
- id: TID.nextStr(),
- },
- ...otherFeeds,
- ])
})(),
])
} catch (e: any) {
@@ -123,6 +130,7 @@ export function StepFinished() {
overwriteSavedFeeds,
track,
getAgent,
+ gate,
])
React.useEffect(() => {
diff --git a/src/screens/Onboarding/StepProfile/index.tsx b/src/screens/Onboarding/StepProfile/index.tsx
new file mode 100644
index 00000000..8db3e776
--- /dev/null
+++ b/src/screens/Onboarding/StepProfile/index.tsx
@@ -0,0 +1,55 @@
+import React from 'react'
+import {View} from 'react-native'
+import {msg, Trans} from '@lingui/macro'
+import {useLingui} from '@lingui/react'
+
+import {
+ DescriptionText,
+ OnboardingControls,
+ TitleText,
+} from '#/screens/Onboarding/Layout'
+import {Context} from '#/screens/Onboarding/state'
+import {atoms as a} from '#/alf'
+import {Button, ButtonIcon, ButtonText} from '#/components/Button'
+import {IconCircle} from '#/components/IconCircle'
+import {ChevronRight_Stroke2_Corner0_Rounded as ChevronRight} from '#/components/icons/Chevron'
+import {StreamingLive_Stroke2_Corner0_Rounded as StreamingLive} from '#/components/icons/StreamingLive'
+
+export function StepProfile() {
+ const {_} = useLingui()
+ const {dispatch} = React.useContext(Context)
+
+ const onContinue = React.useCallback(() => {
+ dispatch({type: 'next'})
+ }, [dispatch])
+
+ return (
+
+
+
+
+ Give your profile a face
+
+
+
+ Help people know you're not a bot by uploading a picture or creating
+ an avatar.
+
+
+
+
+
+
+
+ )
+}
diff --git a/src/screens/Onboarding/index.tsx b/src/screens/Onboarding/index.tsx
index 42964910..5af7a12d 100644
--- a/src/screens/Onboarding/index.tsx
+++ b/src/screens/Onboarding/index.tsx
@@ -16,6 +16,7 @@ import {StepFinished} from '#/screens/Onboarding/StepFinished'
import {StepFollowingFeed} from '#/screens/Onboarding/StepFollowingFeed'
import {StepInterests} from '#/screens/Onboarding/StepInterests'
import {StepModeration} from '#/screens/Onboarding/StepModeration'
+import {StepProfile} from '#/screens/Onboarding/StepProfile'
import {StepSuggestedAccounts} from '#/screens/Onboarding/StepSuggestedAccounts'
import {StepTopicalFeeds} from '#/screens/Onboarding/StepTopicalFeeds'
import {Portal} from '#/components/Portal'
@@ -65,6 +66,7 @@ export function Onboarding() {
[state, dispatch, interestsDisplayNames],
)}>
+ {state.activeStep === 'profile' && }
{state.activeStep === 'interests' && }
{state.activeStep === 'suggestedAccounts' && (
diff --git a/src/screens/Onboarding/state.ts b/src/screens/Onboarding/state.ts
index d67dc88f..9452fbbc 100644
--- a/src/screens/Onboarding/state.ts
+++ b/src/screens/Onboarding/state.ts
@@ -6,6 +6,7 @@ export type OnboardingState = {
hasPrev: boolean
totalSteps: number
activeStep:
+ | 'profile'
| 'interests'
| 'suggestedAccounts'
| 'followingFeed'
@@ -28,6 +29,10 @@ export type OnboardingState = {
topicalFeedsStepResults: {
feedUris: string[]
}
+ profileStepResults: {
+ imageUri?: string
+ imageMime?: string
+ }
}
export type OnboardingAction =
@@ -57,6 +62,11 @@ export type OnboardingAction =
type: 'setTopicalFeedsStepResults'
feedUris: string[]
}
+ | {
+ type: 'setProfileStepResults'
+ imageUri: string
+ imageMime: string
+ }
export type ApiResponseMap = {
interests: string[]
@@ -91,6 +101,10 @@ export const initialState: OnboardingState = {
topicalFeedsStepResults: {
feedUris: [],
},
+ profileStepResults: {
+ imageUri: '',
+ imageMime: '',
+ },
}
export const INTEREST_TO_DISPLAY_NAME_DEFAULTS: {
@@ -240,8 +254,8 @@ export function reducer(
export const initialStateReduced: OnboardingState = {
hasPrev: false,
- totalSteps: 7,
- activeStep: 'interests',
+ totalSteps: 3,
+ activeStep: 'profile',
activeStepIndex: 1,
interestsStepResults: {
@@ -261,6 +275,10 @@ export const initialStateReduced: OnboardingState = {
topicalFeedsStepResults: {
feedUris: [],
},
+ profileStepResults: {
+ imageUri: '',
+ imageMime: '',
+ },
}
export function reducerReduced(
@@ -271,51 +289,27 @@ export function reducerReduced(
switch (a.type) {
case 'next': {
- if (s.activeStep === 'interests') {
- next.activeStep = 'suggestedAccounts'
+ if (s.activeStep === 'profile') {
+ next.activeStep = 'interests'
next.activeStepIndex = 2
- } else if (s.activeStep === 'suggestedAccounts') {
- next.activeStep = 'followingFeed'
- next.activeStepIndex = 3
- } else if (s.activeStep === 'followingFeed') {
- next.activeStep = 'algoFeeds'
- next.activeStepIndex = 4
- } else if (s.activeStep === 'algoFeeds') {
- next.activeStep = 'topicalFeeds'
- next.activeStepIndex = 5
- } else if (s.activeStep === 'topicalFeeds') {
- next.activeStep = 'moderation'
- next.activeStepIndex = 6
- } else if (s.activeStep === 'moderation') {
+ } else if (s.activeStep === 'interests') {
next.activeStep = 'finished'
- next.activeStepIndex = 7
+ next.activeStepIndex = 3
}
break
}
case 'prev': {
- if (s.activeStep === 'suggestedAccounts') {
- next.activeStep = 'interests'
+ if (s.activeStep === 'interests') {
+ next.activeStep = 'profile'
next.activeStepIndex = 1
- } else if (s.activeStep === 'followingFeed') {
- next.activeStep = 'suggestedAccounts'
- next.activeStepIndex = 2
- } else if (s.activeStep === 'algoFeeds') {
- next.activeStep = 'followingFeed'
- next.activeStepIndex = 3
- } else if (s.activeStep === 'topicalFeeds') {
- next.activeStep = 'algoFeeds'
- next.activeStepIndex = 4
- } else if (s.activeStep === 'moderation') {
- next.activeStep = 'topicalFeeds'
- next.activeStepIndex = 5
} else if (s.activeStep === 'finished') {
- next.activeStep = 'moderation'
- next.activeStepIndex = 6
+ next.activeStep = 'interests'
+ next.activeStepIndex = 2
}
break
}
case 'finish': {
- next = initialState
+ next = initialStateReduced
break
}
case 'setInterestsStepResults': {
@@ -326,22 +320,18 @@ export function reducerReduced(
break
}
case 'setSuggestedAccountsStepResults': {
- next.suggestedAccountsStepResults = {
- accountDids: next.suggestedAccountsStepResults.accountDids.concat(
- a.accountDids,
- ),
- }
break
}
case 'setAlgoFeedsStepResults': {
- next.algoFeedsStepResults = {
- feedUris: a.feedUris,
- }
break
}
case 'setTopicalFeedsStepResults': {
- next.topicalFeedsStepResults = {
- feedUris: next.topicalFeedsStepResults.feedUris.concat(a.feedUris),
+ break
+ }
+ case 'setProfileStepResults': {
+ next.profileStepResults = {
+ imageUri: a.imageUri,
+ imageMime: a.imageMime,
}
break
}
@@ -349,7 +339,7 @@ export function reducerReduced(
const state = {
...next,
- hasPrev: next.activeStep !== 'interests',
+ hasPrev: next.activeStep !== 'profile',
}
logger.debug(`onboarding`, {
@@ -362,6 +352,7 @@ export function reducerReduced(
suggestedAccountsStepResults: state.suggestedAccountsStepResults,
algoFeedsStepResults: state.algoFeedsStepResults,
topicalFeedsStepResults: state.topicalFeedsStepResults,
+ profileStepResults: state.profileStepResults,
})
if (s.activeStep !== state.activeStep) {