New user progress guides (#4716)

* Add the animated checkmark svg

* Add progress guide list and task components

* Add ProgressGuide Toast component

* Implement progress-guide controller

* Add 7 follows to the progress guide

* Wire up action captures

* Wire up progress-guide persistence

* Trigger progress guide on account creation

* Clear the progress guide from storage on complete

* Add progress guide interstitial, put behind gate

* Fix: read progress guide state from prefs

* Some defensive type checks

* Create separate toast for completion

* List tweaks

* Only show on Discover

* Spacing and progress tweaks

* Completely hide when complete

* Capture the progress guide in local state, and only render toasts while guide is active

* Fix: ensure persisted hydrates into local state

* Gate

---------

Co-authored-by: Eric Bailey <git@esb.lol>
Co-authored-by: Dan Abramov <dan.abramov@gmail.com>
This commit is contained in:
Paul Frazee 2024-07-03 19:05:19 -07:00 committed by GitHub
parent aa7117edb6
commit 0ed99b840d
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
19 changed files with 721 additions and 22 deletions

View file

@ -34,4 +34,8 @@ export const DEFAULT_LOGGED_OUT_PREFERENCES: UsePreferencesQueryResponse = {
userAge: 13, // TODO(pwi)
interests: {tags: []},
savedFeeds: [],
bskyAppState: {
queuedNudges: [],
activeProgressGuide: undefined,
},
}

View file

@ -342,3 +342,50 @@ export function useRemoveMutedWordMutation() {
},
})
}
export function useQueueNudgesMutation() {
const queryClient = useQueryClient()
const agent = useAgent()
return useMutation({
mutationFn: async (nudges: string | string[]) => {
await agent.bskyAppQueueNudges(nudges)
// triggers a refetch
await queryClient.invalidateQueries({
queryKey: preferencesQueryKey,
})
},
})
}
export function useDismissNudgesMutation() {
const queryClient = useQueryClient()
const agent = useAgent()
return useMutation({
mutationFn: async (nudges: string | string[]) => {
await agent.bskyAppDismissNudges(nudges)
// triggers a refetch
await queryClient.invalidateQueries({
queryKey: preferencesQueryKey,
})
},
})
}
export function useSetActiveProgressGuideMutation() {
const queryClient = useQueryClient()
const agent = useAgent()
return useMutation({
mutationFn: async (
guide: AppBskyActorDefs.BskyAppProgressGuide | undefined,
) => {
await agent.bskyAppSetActiveProgressGuide(guide)
// triggers a refetch
await queryClient.invalidateQueries({
queryKey: preferencesQueryKey,
})
},
})
}

View file

@ -25,6 +25,10 @@ import {STALE} from '#/state/queries'
import {resetProfilePostsQueries} from '#/state/queries/post-feed'
import {updateProfileShadow} from '../cache/profile-shadow'
import {useAgent, useSession} from '../session'
import {
ProgressGuideAction,
useProgressGuideControls,
} from '../shell/progress-guide'
import {RQKEY as RQKEY_LIST_CONVOS} from './messages/list-converations'
import {RQKEY as RQKEY_MY_BLOCKED} from './my-blocked-accounts'
import {RQKEY as RQKEY_MY_MUTED} from './my-muted-accounts'
@ -274,12 +278,15 @@ function useProfileFollowMutation(
const {currentAccount} = useSession()
const agent = useAgent()
const queryClient = useQueryClient()
const {captureAction} = useProgressGuideControls()
return useMutation<{uri: string; cid: string}, Error, {did: string}>({
mutationFn: async ({did}) => {
let ownProfile: AppBskyActorDefs.ProfileViewDetailed | undefined
if (currentAccount) {
ownProfile = findProfileQueryData(queryClient, currentAccount.did)
}
captureAction(ProgressGuideAction.Follow)
logEvent('profile:follow', {
logContext,
didBecomeMutual: profile.viewer