Onboarding fixes (#3966)

* Ensure prefs are up-to-date before leaving onboarding

* Parallelize upsertProfile call

* Don't upsertProfile if no image

* Don't waterfall blob upload

* Fix useProfileUpdateMutation to parallelize uploads

* Invalidate user profile before leaving onboarding

* Ungate setting the pic
zio/stable
dan 2024-05-11 19:54:58 +01:00 committed by GitHub
parent 6f5b551bda
commit 51b4b22dec
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 60 additions and 32 deletions

View File

@ -3,13 +3,18 @@ import {View} from 'react-native'
import {TID} from '@atproto/common-web'
import {msg, Trans} from '@lingui/macro'
import {useLingui} from '@lingui/react'
import {useQueryClient} from '@tanstack/react-query'
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, useGate} from '#/lib/statsig/statsig'
import {logger} from '#/logger'
import {useOverwriteSavedFeedsMutation} from '#/state/queries/preferences'
import {
preferencesQueryKey,
useOverwriteSavedFeedsMutation,
} from '#/state/queries/preferences'
import {RQKEY as profileRQKey} from '#/state/queries/profile'
import {useAgent} from '#/state/session'
import {useOnboardingDispatch} from '#/state/shell'
import {uploadBlob} from 'lib/api'
@ -41,6 +46,7 @@ export function StepFinished() {
const onboardDispatch = useOnboardingDispatch()
const [saving, setSaving] = React.useState(false)
const {mutateAsync: overwriteSavedFeeds} = useOverwriteSavedFeedsMutation()
const queryClient = useQueryClient()
const {getAgent} = useAgent()
const gate = useGate()
@ -112,33 +118,41 @@ export function StepFinished() {
])
}
})(),
])
if (gate('reduced_onboarding_and_home_algo')) {
await getAgent().upsertProfile(async existing => {
existing = existing ?? {}
if (profileStepResults.imageUri && profileStepResults.imageMime) {
const res = await uploadBlob(
getAgent(),
profileStepResults.imageUri,
profileStepResults.imageMime,
)
if (res.data.blob) {
existing.avatar = res.data.blob
}
(async () => {
const {imageUri, imageMime} = profileStepResults
if (imageUri && imageMime) {
const blobPromise = uploadBlob(getAgent(), imageUri, imageMime)
await getAgent().upsertProfile(async existing => {
existing = existing ?? {}
const res = await blobPromise
if (res.data.blob) {
existing.avatar = res.data.blob
}
return existing
})
}
return existing
})
}
})(),
])
} catch (e: any) {
logger.info(`onboarding: bulk save failed`)
logger.error(e)
// don't alert the user, just let them into their account
}
// Try to ensure that prefs and profile are up-to-date by the time we render Home.
await Promise.all([
queryClient.invalidateQueries({
queryKey: preferencesQueryKey,
}),
queryClient.invalidateQueries({
queryKey: profileRQKey(getAgent().session?.did ?? ''),
}),
]).catch(e => {
logger.error(e)
// Keep going.
})
setSaving(false)
dispatch({type: 'finish'})
onboardDispatch({type: 'finish'})
@ -154,6 +168,7 @@ export function StepFinished() {
track,
getAgent,
gate,
queryClient,
])
React.useEffect(() => {

View File

@ -6,6 +6,7 @@ import {
AppBskyActorProfile,
AtUri,
BskyAgent,
ComAtprotoRepoUploadBlob,
} from '@atproto/api'
import {
QueryClient,
@ -124,6 +125,26 @@ export function useProfileUpdateMutation() {
newUserBanner,
checkCommitted,
}) => {
let newUserAvatarPromise:
| Promise<ComAtprotoRepoUploadBlob.Response>
| undefined
if (newUserAvatar) {
newUserAvatarPromise = uploadBlob(
getAgent(),
newUserAvatar.path,
newUserAvatar.mime,
)
}
let newUserBannerPromise:
| Promise<ComAtprotoRepoUploadBlob.Response>
| undefined
if (newUserBanner) {
newUserBannerPromise = uploadBlob(
getAgent(),
newUserBanner.path,
newUserBanner.mime,
)
}
await getAgent().upsertProfile(async existing => {
existing = existing || {}
if (typeof updates === 'function') {
@ -132,22 +153,14 @@ export function useProfileUpdateMutation() {
existing.displayName = updates.displayName
existing.description = updates.description
}
if (newUserAvatar) {
const res = await uploadBlob(
getAgent(),
newUserAvatar.path,
newUserAvatar.mime,
)
if (newUserAvatarPromise) {
const res = await newUserAvatarPromise
existing.avatar = res.data.blob
} else if (newUserAvatar === null) {
existing.avatar = undefined
}
if (newUserBanner) {
const res = await uploadBlob(
getAgent(),
newUserBanner.path,
newUserBanner.mime,
)
if (newUserBannerPromise) {
const res = await newUserBannerPromise
existing.banner = res.data.blob
} else if (newUserBanner === null) {
existing.banner = undefined