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 piczio/stable
parent
6f5b551bda
commit
51b4b22dec
|
@ -3,13 +3,18 @@ import {View} from 'react-native'
|
||||||
import {TID} from '@atproto/common-web'
|
import {TID} from '@atproto/common-web'
|
||||||
import {msg, Trans} from '@lingui/macro'
|
import {msg, Trans} from '@lingui/macro'
|
||||||
import {useLingui} from '@lingui/react'
|
import {useLingui} from '@lingui/react'
|
||||||
|
import {useQueryClient} from '@tanstack/react-query'
|
||||||
|
|
||||||
import {useAnalytics} from '#/lib/analytics/analytics'
|
import {useAnalytics} from '#/lib/analytics/analytics'
|
||||||
import {BSKY_APP_ACCOUNT_DID, IS_PROD_SERVICE} from '#/lib/constants'
|
import {BSKY_APP_ACCOUNT_DID, IS_PROD_SERVICE} from '#/lib/constants'
|
||||||
import {DISCOVER_SAVED_FEED, TIMELINE_SAVED_FEED} from '#/lib/constants'
|
import {DISCOVER_SAVED_FEED, TIMELINE_SAVED_FEED} from '#/lib/constants'
|
||||||
import {logEvent, useGate} from '#/lib/statsig/statsig'
|
import {logEvent, useGate} from '#/lib/statsig/statsig'
|
||||||
import {logger} from '#/logger'
|
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 {useAgent} from '#/state/session'
|
||||||
import {useOnboardingDispatch} from '#/state/shell'
|
import {useOnboardingDispatch} from '#/state/shell'
|
||||||
import {uploadBlob} from 'lib/api'
|
import {uploadBlob} from 'lib/api'
|
||||||
|
@ -41,6 +46,7 @@ export function StepFinished() {
|
||||||
const onboardDispatch = useOnboardingDispatch()
|
const onboardDispatch = useOnboardingDispatch()
|
||||||
const [saving, setSaving] = React.useState(false)
|
const [saving, setSaving] = React.useState(false)
|
||||||
const {mutateAsync: overwriteSavedFeeds} = useOverwriteSavedFeedsMutation()
|
const {mutateAsync: overwriteSavedFeeds} = useOverwriteSavedFeedsMutation()
|
||||||
|
const queryClient = useQueryClient()
|
||||||
const {getAgent} = useAgent()
|
const {getAgent} = useAgent()
|
||||||
const gate = useGate()
|
const gate = useGate()
|
||||||
|
|
||||||
|
@ -112,33 +118,41 @@ export function StepFinished() {
|
||||||
])
|
])
|
||||||
}
|
}
|
||||||
})(),
|
})(),
|
||||||
])
|
|
||||||
|
|
||||||
if (gate('reduced_onboarding_and_home_algo')) {
|
(async () => {
|
||||||
await getAgent().upsertProfile(async existing => {
|
const {imageUri, imageMime} = profileStepResults
|
||||||
existing = existing ?? {}
|
if (imageUri && imageMime) {
|
||||||
|
const blobPromise = uploadBlob(getAgent(), imageUri, imageMime)
|
||||||
if (profileStepResults.imageUri && profileStepResults.imageMime) {
|
await getAgent().upsertProfile(async existing => {
|
||||||
const res = await uploadBlob(
|
existing = existing ?? {}
|
||||||
getAgent(),
|
const res = await blobPromise
|
||||||
profileStepResults.imageUri,
|
if (res.data.blob) {
|
||||||
profileStepResults.imageMime,
|
existing.avatar = res.data.blob
|
||||||
)
|
}
|
||||||
|
return existing
|
||||||
if (res.data.blob) {
|
})
|
||||||
existing.avatar = res.data.blob
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
})(),
|
||||||
return existing
|
])
|
||||||
})
|
|
||||||
}
|
|
||||||
} catch (e: any) {
|
} catch (e: any) {
|
||||||
logger.info(`onboarding: bulk save failed`)
|
logger.info(`onboarding: bulk save failed`)
|
||||||
logger.error(e)
|
logger.error(e)
|
||||||
// don't alert the user, just let them into their account
|
// 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)
|
setSaving(false)
|
||||||
dispatch({type: 'finish'})
|
dispatch({type: 'finish'})
|
||||||
onboardDispatch({type: 'finish'})
|
onboardDispatch({type: 'finish'})
|
||||||
|
@ -154,6 +168,7 @@ export function StepFinished() {
|
||||||
track,
|
track,
|
||||||
getAgent,
|
getAgent,
|
||||||
gate,
|
gate,
|
||||||
|
queryClient,
|
||||||
])
|
])
|
||||||
|
|
||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
|
|
|
@ -6,6 +6,7 @@ import {
|
||||||
AppBskyActorProfile,
|
AppBskyActorProfile,
|
||||||
AtUri,
|
AtUri,
|
||||||
BskyAgent,
|
BskyAgent,
|
||||||
|
ComAtprotoRepoUploadBlob,
|
||||||
} from '@atproto/api'
|
} from '@atproto/api'
|
||||||
import {
|
import {
|
||||||
QueryClient,
|
QueryClient,
|
||||||
|
@ -124,6 +125,26 @@ export function useProfileUpdateMutation() {
|
||||||
newUserBanner,
|
newUserBanner,
|
||||||
checkCommitted,
|
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 => {
|
await getAgent().upsertProfile(async existing => {
|
||||||
existing = existing || {}
|
existing = existing || {}
|
||||||
if (typeof updates === 'function') {
|
if (typeof updates === 'function') {
|
||||||
|
@ -132,22 +153,14 @@ export function useProfileUpdateMutation() {
|
||||||
existing.displayName = updates.displayName
|
existing.displayName = updates.displayName
|
||||||
existing.description = updates.description
|
existing.description = updates.description
|
||||||
}
|
}
|
||||||
if (newUserAvatar) {
|
if (newUserAvatarPromise) {
|
||||||
const res = await uploadBlob(
|
const res = await newUserAvatarPromise
|
||||||
getAgent(),
|
|
||||||
newUserAvatar.path,
|
|
||||||
newUserAvatar.mime,
|
|
||||||
)
|
|
||||||
existing.avatar = res.data.blob
|
existing.avatar = res.data.blob
|
||||||
} else if (newUserAvatar === null) {
|
} else if (newUserAvatar === null) {
|
||||||
existing.avatar = undefined
|
existing.avatar = undefined
|
||||||
}
|
}
|
||||||
if (newUserBanner) {
|
if (newUserBannerPromise) {
|
||||||
const res = await uploadBlob(
|
const res = await newUserBannerPromise
|
||||||
getAgent(),
|
|
||||||
newUserBanner.path,
|
|
||||||
newUserBanner.mime,
|
|
||||||
)
|
|
||||||
existing.banner = res.data.blob
|
existing.banner = res.data.blob
|
||||||
} else if (newUserBanner === null) {
|
} else if (newUserBanner === null) {
|
||||||
existing.banner = undefined
|
existing.banner = undefined
|
||||||
|
|
Loading…
Reference in New Issue