0cbb03cd14
* new follow-10 progress guide * find follows dialog * wip tabs * flatlist version with search * hardcode out jake gold * lazy load followup suggestions * Update src/components/ProgressGuide/FollowDialog.tsx Co-authored-by: surfdude29 <149612116+surfdude29@users.noreply.github.com> * comment out replacing, enable paging * rm autofocus * find shadow profiles in paginated search * clear search when press tabs * better tab a11y * fix label * adjust scroll indicator insets * do the same scroll indicator adjustment for searchable people list * hardcode jake to just be 'tech' * Retain state on close/reopen * only change follow btn color when not followed * add guide to inside dialog * fix task alignment * Enable contextual suggestions * WIP: show multiple suggestions * Rework so it animates well * Show more items * remove card style * move tabs to own component * split out header top * scroll active tab into view * rm log * Improve perf a bit * boost popular interests over alphabetical ones * scroll active tab into view * revert back to round buttons * Fix overrenders of the tab bar items * Fix unintended animation * Scroll initial into view if needed * Unlift state, the dialog thing breaks lifting * Persist simply * Fix empty state * Fix incorrect gate exposure * Fix another bad useGate * Nit --------- Co-authored-by: surfdude29 <149612116+surfdude29@users.noreply.github.com> Co-authored-by: Dan Abramov <dan.abramov@gmail.com>
222 lines
4.8 KiB
TypeScript
222 lines
4.8 KiB
TypeScript
import React from 'react'
|
|
import {msg} from '@lingui/macro'
|
|
import {useLingui} from '@lingui/react'
|
|
|
|
import {logger} from '#/logger'
|
|
import {AvatarColor, Emoji} from '#/screens/Onboarding/StepProfile/types'
|
|
|
|
export type OnboardingState = {
|
|
hasPrev: boolean
|
|
totalSteps: number
|
|
activeStep: 'profile' | 'interests' | 'finished'
|
|
activeStepIndex: number
|
|
|
|
interestsStepResults: {
|
|
selectedInterests: string[]
|
|
apiResponse: ApiResponseMap
|
|
}
|
|
profileStepResults: {
|
|
isCreatedAvatar: boolean
|
|
image?: {
|
|
path: string
|
|
mime: string
|
|
size: number
|
|
width: number
|
|
height: number
|
|
}
|
|
imageUri?: string
|
|
imageMime?: string
|
|
creatorState?: {
|
|
emoji: Emoji
|
|
backgroundColor: AvatarColor
|
|
}
|
|
}
|
|
}
|
|
|
|
export type OnboardingAction =
|
|
| {
|
|
type: 'next'
|
|
}
|
|
| {
|
|
type: 'prev'
|
|
}
|
|
| {
|
|
type: 'finish'
|
|
}
|
|
| {
|
|
type: 'setInterestsStepResults'
|
|
selectedInterests: string[]
|
|
apiResponse: ApiResponseMap
|
|
}
|
|
| {
|
|
type: 'setProfileStepResults'
|
|
isCreatedAvatar: boolean
|
|
image: OnboardingState['profileStepResults']['image'] | undefined
|
|
imageUri: string | undefined
|
|
imageMime: string
|
|
creatorState:
|
|
| {
|
|
emoji: Emoji
|
|
backgroundColor: AvatarColor
|
|
}
|
|
| undefined
|
|
}
|
|
|
|
export type ApiResponseMap = {
|
|
interests: string[]
|
|
suggestedAccountDids: {
|
|
[key: string]: string[]
|
|
}
|
|
suggestedFeedUris: {
|
|
[key: string]: string[]
|
|
}
|
|
}
|
|
|
|
// most popular selected interests
|
|
export const popularInterests = [
|
|
'art',
|
|
'gaming',
|
|
'sports',
|
|
'comics',
|
|
'music',
|
|
'politics',
|
|
'photography',
|
|
'science',
|
|
'news',
|
|
]
|
|
|
|
export function useInterestsDisplayNames() {
|
|
const {_} = useLingui()
|
|
|
|
return React.useMemo<Record<string, string>>(() => {
|
|
return {
|
|
// Keep this alphabetized
|
|
animals: _(msg`Animals`),
|
|
art: _(msg`Art`),
|
|
books: _(msg`Books`),
|
|
comedy: _(msg`Comedy`),
|
|
comics: _(msg`Comics`),
|
|
culture: _(msg`Culture`),
|
|
dev: _(msg`Software Dev`),
|
|
education: _(msg`Education`),
|
|
food: _(msg`Food`),
|
|
gaming: _(msg`Video Games`),
|
|
journalism: _(msg`Journalism`),
|
|
movies: _(msg`Movies`),
|
|
music: _(msg`Music`),
|
|
nature: _(msg`Nature`),
|
|
news: _(msg`News`),
|
|
pets: _(msg`Pets`),
|
|
photography: _(msg`Photography`),
|
|
politics: _(msg`Politics`),
|
|
science: _(msg`Science`),
|
|
sports: _(msg`Sports`),
|
|
tech: _(msg`Tech`),
|
|
tv: _(msg`TV`),
|
|
writers: _(msg`Writers`),
|
|
}
|
|
}, [_])
|
|
}
|
|
|
|
export const initialState: OnboardingState = {
|
|
hasPrev: false,
|
|
totalSteps: 3,
|
|
activeStep: 'profile',
|
|
activeStepIndex: 1,
|
|
|
|
interestsStepResults: {
|
|
selectedInterests: [],
|
|
apiResponse: {
|
|
interests: [],
|
|
suggestedAccountDids: {},
|
|
suggestedFeedUris: {},
|
|
},
|
|
},
|
|
profileStepResults: {
|
|
isCreatedAvatar: false,
|
|
image: undefined,
|
|
imageUri: '',
|
|
imageMime: '',
|
|
},
|
|
}
|
|
|
|
export const Context = React.createContext<{
|
|
state: OnboardingState
|
|
dispatch: React.Dispatch<OnboardingAction>
|
|
}>({
|
|
state: {...initialState},
|
|
dispatch: () => {},
|
|
})
|
|
|
|
export function reducer(
|
|
s: OnboardingState,
|
|
a: OnboardingAction,
|
|
): OnboardingState {
|
|
let next = {...s}
|
|
|
|
switch (a.type) {
|
|
case 'next': {
|
|
if (s.activeStep === 'profile') {
|
|
next.activeStep = 'interests'
|
|
next.activeStepIndex = 2
|
|
} else if (s.activeStep === 'interests') {
|
|
next.activeStep = 'finished'
|
|
next.activeStepIndex = 3
|
|
}
|
|
break
|
|
}
|
|
case 'prev': {
|
|
if (s.activeStep === 'interests') {
|
|
next.activeStep = 'profile'
|
|
next.activeStepIndex = 1
|
|
} else if (s.activeStep === 'finished') {
|
|
next.activeStep = 'interests'
|
|
next.activeStepIndex = 2
|
|
}
|
|
break
|
|
}
|
|
case 'finish': {
|
|
next = initialState
|
|
break
|
|
}
|
|
case 'setInterestsStepResults': {
|
|
next.interestsStepResults = {
|
|
selectedInterests: a.selectedInterests,
|
|
apiResponse: a.apiResponse,
|
|
}
|
|
break
|
|
}
|
|
case 'setProfileStepResults': {
|
|
next.profileStepResults = {
|
|
isCreatedAvatar: a.isCreatedAvatar,
|
|
image: a.image,
|
|
imageUri: a.imageUri,
|
|
imageMime: a.imageMime,
|
|
creatorState: a.creatorState,
|
|
}
|
|
break
|
|
}
|
|
}
|
|
|
|
const state = {
|
|
...next,
|
|
hasPrev: next.activeStep !== 'profile',
|
|
}
|
|
|
|
logger.debug(`onboarding`, {
|
|
hasPrev: state.hasPrev,
|
|
activeStep: state.activeStep,
|
|
activeStepIndex: state.activeStepIndex,
|
|
interestsStepResults: {
|
|
selectedInterests: state.interestsStepResults.selectedInterests,
|
|
},
|
|
profileStepResults: state.profileStepResults,
|
|
})
|
|
|
|
if (s.activeStep !== state.activeStep) {
|
|
logger.debug(`onboarding: step changed`, {activeStep: state.activeStep})
|
|
}
|
|
|
|
return state
|
|
}
|