Precache basic profile from posts for instant future navigations (#2795)
* skeleton for caching
* modify some existing logic
* refactor uri resolution query
* add precache feed posts
* adjustments
* remove prefetch on hover (maybe revert, just example)
* fix
* change arg name to match what we want
* optional infinite stale time
* use `ProfileViewDetailed`
* Revert "remove prefetch on hover (maybe revert, just example)"
This reverts commit 08609deb0d.
* add warning comment back for stale time
* remove comment
* store profile with both the handle and did for query key
* remove extra block from revert
* clarify argument name
* remove QT cache
* structure queries the same (put `enabled` at bottom)
* use both `ProfileViewDetailed` and `ProfileView` for the query return type
* placeholder profile header
* remove logs
* remove a few other things we don't need
* add placeholder
* refactor
* refactor
* we don't need this height adjustment now
* use gray banner while loading
* set background color of image to the loading placeholder color
* reorg imports
* add border to header on loading
* Fix style
* Rm radius
* oops
* Undo edit
* Back out type changes
* Tighten some types and moderate shadow
* Move precaching fns to profile where the cache is
* Rename functions to match what they do now
* Remove anys
---------
Co-authored-by: Dan Abramov <dan.abramov@gmail.com>
This commit is contained in:
@@ -1,9 +1,9 @@
|
||||
import {QueryClient, useQuery, UseQueryResult} from '@tanstack/react-query'
|
||||
import {AtUri, AppBskyActorDefs, AppBskyFeedDefs} from '@atproto/api'
|
||||
import {useQuery, useQueryClient, UseQueryResult} from '@tanstack/react-query'
|
||||
import {AtUri, AppBskyActorDefs} from '@atproto/api'
|
||||
|
||||
import {profileBasicQueryKey as RQKEY_PROFILE_BASIC} from './profile'
|
||||
import {getAgent} from '#/state/session'
|
||||
import {STALE} from '#/state/queries'
|
||||
import {ThreadNode} from './post-thread'
|
||||
|
||||
export const RQKEY = (didOrHandle: string) => ['resolved-did', didOrHandle]
|
||||
|
||||
@@ -22,55 +22,29 @@ export function useResolveUriQuery(uri: string | undefined): UriUseQueryResult {
|
||||
}
|
||||
|
||||
export function useResolveDidQuery(didOrHandle: string | undefined) {
|
||||
const queryClient = useQueryClient()
|
||||
|
||||
return useQuery<string, Error>({
|
||||
staleTime: STALE.HOURS.ONE,
|
||||
queryKey: RQKEY(didOrHandle || ''),
|
||||
async queryFn() {
|
||||
if (!didOrHandle) {
|
||||
return ''
|
||||
}
|
||||
if (!didOrHandle.startsWith('did:')) {
|
||||
const res = await getAgent().resolveHandle({handle: didOrHandle})
|
||||
didOrHandle = res.data.did
|
||||
}
|
||||
return didOrHandle
|
||||
queryKey: RQKEY(didOrHandle ?? ''),
|
||||
queryFn: async () => {
|
||||
if (!didOrHandle) return ''
|
||||
// Just return the did if it's already one
|
||||
if (didOrHandle.startsWith('did:')) return didOrHandle
|
||||
|
||||
const res = await getAgent().resolveHandle({handle: didOrHandle})
|
||||
return res.data.did
|
||||
},
|
||||
initialData: () => {
|
||||
// Return undefined if no did or handle
|
||||
if (!didOrHandle) return
|
||||
|
||||
const profile =
|
||||
queryClient.getQueryData<AppBskyActorDefs.ProfileViewBasic>(
|
||||
RQKEY_PROFILE_BASIC(didOrHandle),
|
||||
)
|
||||
return profile?.did
|
||||
},
|
||||
enabled: !!didOrHandle,
|
||||
})
|
||||
}
|
||||
|
||||
export function precacheProfile(
|
||||
queryClient: QueryClient,
|
||||
profile:
|
||||
| AppBskyActorDefs.ProfileView
|
||||
| AppBskyActorDefs.ProfileViewBasic
|
||||
| AppBskyActorDefs.ProfileViewDetailed,
|
||||
) {
|
||||
queryClient.setQueryData(RQKEY(profile.handle), profile.did)
|
||||
}
|
||||
|
||||
export function precacheFeedPosts(
|
||||
queryClient: QueryClient,
|
||||
posts: AppBskyFeedDefs.FeedViewPost[],
|
||||
) {
|
||||
for (const post of posts) {
|
||||
precacheProfile(queryClient, post.post.author)
|
||||
}
|
||||
}
|
||||
|
||||
export function precacheThreadPosts(
|
||||
queryClient: QueryClient,
|
||||
node: ThreadNode,
|
||||
) {
|
||||
if (node.type === 'post') {
|
||||
precacheProfile(queryClient, node.post.author)
|
||||
if (node.parent) {
|
||||
precacheThreadPosts(queryClient, node.parent)
|
||||
}
|
||||
if (node.replies?.length) {
|
||||
for (const reply of node.replies) {
|
||||
precacheThreadPosts(queryClient, reply)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user