Merge pull request #2679 from bluesky-social/hailey/check-blocks-load-profile

clear cache when blocking/unblocking and whenever we get blocked, better invalidation logic for `useProfileQuery`
zio/stable
Hailey 2024-01-30 10:35:46 -08:00 committed by GitHub
commit 4058174678
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 48 additions and 13 deletions

View File

@ -28,6 +28,7 @@ import {getModerationOpts} from '#/state/queries/preferences/moderation'
import {KnownError} from '#/view/com/posts/FeedErrorMessage' import {KnownError} from '#/view/com/posts/FeedErrorMessage'
import {embedViewRecordToPostView, getEmbeddedPost} from './util' import {embedViewRecordToPostView, getEmbeddedPost} from './util'
import {useModerationOpts} from './preferences' import {useModerationOpts} from './preferences'
import {queryClient} from 'lib/react-query'
type ActorDid = string type ActorDid = string
type AuthorFilter = type AuthorFilter =
@ -444,3 +445,15 @@ function assertSomePostsPassModeration(feed: AppBskyFeedDefs.FeedViewPost[]) {
throw new Error(KnownError.FeedNSFPublic) throw new Error(KnownError.FeedNSFPublic)
} }
} }
export function resetProfilePostsQueries(did: string, timeout = 0) {
setTimeout(() => {
queryClient.resetQueries({
predicate: query =>
!!(
query.queryKey[0] === 'post-feed' &&
(query.queryKey[1] as string)?.includes(did)
),
})
}, timeout)
}

View File

@ -17,6 +17,7 @@ import {updateProfileShadow} from '../cache/profile-shadow'
import {uploadBlob} from '#/lib/api' import {uploadBlob} from '#/lib/api'
import {until} from '#/lib/async/until' import {until} from '#/lib/async/until'
import {Shadow} from '#/state/cache/types' import {Shadow} from '#/state/cache/types'
import {resetProfilePostsQueries} from '#/state/queries/post-feed'
import {useToggleMutationQueue} from '#/lib/hooks/useToggleMutationQueue' import {useToggleMutationQueue} from '#/lib/hooks/useToggleMutationQueue'
import {RQKEY as RQKEY_MY_MUTED} from './my-muted-accounts' import {RQKEY as RQKEY_MY_MUTED} from './my-muted-accounts'
import {RQKEY as RQKEY_MY_BLOCKED} from './my-blocked-accounts' import {RQKEY as RQKEY_MY_BLOCKED} from './my-blocked-accounts'
@ -26,16 +27,19 @@ import {track} from '#/lib/analytics/analytics'
export const RQKEY = (did: string) => ['profile', did] export const RQKEY = (did: string) => ['profile', did]
export const profilesQueryKey = (handles: string[]) => ['profiles', handles] export const profilesQueryKey = (handles: string[]) => ['profiles', handles]
export function useProfileQuery({did}: {did: string | undefined}) { export function useProfileQuery({
const {currentAccount} = useSession() did,
const isCurrentAccount = did === currentAccount?.did staleTime = STALE.SECONDS.FIFTEEN,
}: {
did: string | undefined
staleTime?: number
}) {
return useQuery({ return useQuery({
// WARNING // WARNING
// this staleTime is load-bearing // this staleTime is load-bearing
// if you remove it, the UI infinite-loops // if you remove it, the UI infinite-loops
// -prf // -prf
staleTime: isCurrentAccount ? STALE.SECONDS.THIRTY : STALE.MINUTES.FIVE, staleTime,
refetchOnWindowFocus: true, refetchOnWindowFocus: true,
queryKey: RQKEY(did || ''), queryKey: RQKEY(did || ''),
queryFn: async () => { queryFn: async () => {
@ -375,8 +379,9 @@ function useProfileBlockMutation() {
{subject: did, createdAt: new Date().toISOString()}, {subject: did, createdAt: new Date().toISOString()},
) )
}, },
onSuccess() { onSuccess(_, {did}) {
queryClient.invalidateQueries({queryKey: RQKEY_MY_BLOCKED()}) queryClient.invalidateQueries({queryKey: RQKEY_MY_BLOCKED()})
resetProfilePostsQueries(did, 1000)
}, },
}) })
} }
@ -394,6 +399,9 @@ function useProfileUnblockMutation() {
rkey, rkey,
}) })
}, },
onSuccess(_, {did}) {
resetProfilePostsQueries(did, 1000)
},
}) })
} }

View File

@ -27,12 +27,12 @@ export function Component({did}: {did: string}) {
data: profile, data: profile,
error: profileError, error: profileError,
refetch: refetchProfile, refetch: refetchProfile,
isFetching: isFetchingProfile, isLoading: isLoadingProfile,
} = useProfileQuery({ } = useProfileQuery({
did: did, did: did,
}) })
if (isFetchingProfile || !moderationOpts) { if (isLoadingProfile || !moderationOpts) {
return ( return (
<CenteredView style={[pal.view, s.flex1]}> <CenteredView style={[pal.view, s.flex1]}>
<ProfileHeader <ProfileHeader

View File

@ -9,6 +9,7 @@ import {sanitizeDisplayName} from 'lib/strings/display-names'
import {sanitizeHandle} from 'lib/strings/handles' import {sanitizeHandle} from 'lib/strings/handles'
import {makeProfileLink} from 'lib/routes/links' import {makeProfileLink} from 'lib/routes/links'
import {useProfileQuery} from '#/state/queries/profile' import {useProfileQuery} from '#/state/queries/profile'
import {STALE} from '#/state/queries'
export function UserInfoText({ export function UserInfoText({
type = 'md', type = 'md',
@ -29,7 +30,10 @@ export function UserInfoText({
attr = attr || 'handle' attr = attr || 'handle'
failed = failed || 'user' failed = failed || 'user'
const {data: profile, isError} = useProfileQuery({did}) const {data: profile, isError} = useProfileQuery({
did,
staleTime: STALE.INFINITY,
})
let inner let inner
if (isError) { if (isError) {

View File

@ -21,7 +21,10 @@ import {useAnalytics} from 'lib/analytics/analytics'
import {ComposeIcon2} from 'lib/icons' import {ComposeIcon2} from 'lib/icons'
import {useSetTitle} from 'lib/hooks/useSetTitle' import {useSetTitle} from 'lib/hooks/useSetTitle'
import {combinedDisplayName} from 'lib/strings/display-names' import {combinedDisplayName} from 'lib/strings/display-names'
import {FeedDescriptor} from '#/state/queries/post-feed' import {
FeedDescriptor,
resetProfilePostsQueries,
} from '#/state/queries/post-feed'
import {useResolveDidQuery} from '#/state/queries/resolve-uri' import {useResolveDidQuery} from '#/state/queries/resolve-uri'
import {useProfileQuery} from '#/state/queries/profile' import {useProfileQuery} from '#/state/queries/profile'
import {useProfileShadow} from '#/state/cache/profile-shadow' import {useProfileShadow} from '#/state/cache/profile-shadow'
@ -55,13 +58,13 @@ export function ProfileScreen({route}: Props) {
data: resolvedDid, data: resolvedDid,
error: resolveError, error: resolveError,
refetch: refetchDid, refetch: refetchDid,
isInitialLoading: isInitialLoadingDid, isLoading: isLoadingDid,
} = useResolveDidQuery(name) } = useResolveDidQuery(name)
const { const {
data: profile, data: profile,
error: profileError, error: profileError,
refetch: refetchProfile, refetch: refetchProfile,
isInitialLoading: isInitialLoadingProfile, isLoading: isLoadingProfile,
} = useProfileQuery({ } = useProfileQuery({
did: resolvedDid, did: resolvedDid,
}) })
@ -74,7 +77,14 @@ export function ProfileScreen({route}: Props) {
} }
}, [resolveError, refetchDid, refetchProfile]) }, [resolveError, refetchDid, refetchProfile])
if (isInitialLoadingDid || isInitialLoadingProfile || !moderationOpts) { // When we open the profile, we want to reset the posts query if we are blocked.
React.useEffect(() => {
if (resolvedDid && profile?.viewer?.blockedBy) {
resetProfilePostsQueries(resolvedDid)
}
}, [profile?.viewer?.blockedBy, resolvedDid])
if (isLoadingDid || isLoadingProfile || !moderationOpts) {
return ( return (
<CenteredView> <CenteredView>
<ProfileHeader <ProfileHeader