about summary refs log tree commit diff
path: root/src/screens/Onboarding
diff options
context:
space:
mode:
Diffstat (limited to 'src/screens/Onboarding')
-rw-r--r--src/screens/Onboarding/StepFinished.tsx68
-rw-r--r--src/screens/Onboarding/StepProfile/index.tsx55
-rw-r--r--src/screens/Onboarding/index.tsx2
-rw-r--r--src/screens/Onboarding/state.ts83
4 files changed, 132 insertions, 76 deletions
diff --git a/src/screens/Onboarding/StepFinished.tsx b/src/screens/Onboarding/StepFinished.tsx
index 4cc611ef4..7d0bfa422 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 000000000..8db3e7761
--- /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 (
+    <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>
+  )
+}
diff --git a/src/screens/Onboarding/index.tsx b/src/screens/Onboarding/index.tsx
index 429649106..5af7a12dc 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],
           )}>
           <Layout>
+            {state.activeStep === 'profile' && <StepProfile />}
             {state.activeStep === 'interests' && <StepInterests />}
             {state.activeStep === 'suggestedAccounts' && (
               <StepSuggestedAccounts />
diff --git a/src/screens/Onboarding/state.ts b/src/screens/Onboarding/state.ts
index d67dc88f3..9452fbbc7 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) {