[Reduced Onboarding] Add new step, new state to reducer (#3931)
* Add new step, new state to reducer * Don't set default feedszio/stable
parent
08979f37e7
commit
80ce6f980e
|
@ -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,8 +68,13 @@ 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',
|
||||
|
@ -101,6 +107,7 @@ export function StepFinished() {
|
|||
},
|
||||
...otherFeeds,
|
||||
])
|
||||
}
|
||||
})(),
|
||||
])
|
||||
} catch (e: any) {
|
||||
|
@ -123,6 +130,7 @@ export function StepFinished() {
|
|||
overwriteSavedFeeds,
|
||||
track,
|
||||
getAgent,
|
||||
gate,
|
||||
])
|
||||
|
||||
React.useEffect(() => {
|
||||
|
|
|
@ -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 (
|
||||
<View style={[a.align_start]}>
|
||||
<IconCircle icon={StreamingLive} style={[a.mb_2xl]} />
|
||||
|
||||
<TitleText>
|
||||
<Trans>Give your profile a face</Trans>
|
||||
</TitleText>
|
||||
<DescriptionText>
|
||||
<Trans>
|
||||
Help people know you're not a bot by uploading a picture or creating
|
||||
an avatar.
|
||||
</Trans>
|
||||
</DescriptionText>
|
||||
|
||||
<OnboardingControls.Portal>
|
||||
<Button
|
||||
variant="gradient"
|
||||
color="gradient_sky"
|
||||
size="large"
|
||||
label={_(msg`Continue to next step`)}
|
||||
onPress={onContinue}>
|
||||
<ButtonText>
|
||||
<Trans>Continue</Trans>
|
||||
</ButtonText>
|
||||
<ButtonIcon icon={ChevronRight} position="right" />
|
||||
</Button>
|
||||
</OnboardingControls.Portal>
|
||||
</View>
|
||||
)
|
||||
}
|
|
@ -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],
|
||||
)}>
|
||||
<Layout>
|
||||
{state.activeStep === 'profile' && <StepProfile />}
|
||||
{state.activeStep === 'interests' && <StepInterests />}
|
||||
{state.activeStep === 'suggestedAccounts' && (
|
||||
<StepSuggestedAccounts />
|
||||
|
|
|
@ -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) {
|
||||
|
|
Loading…
Reference in New Issue