Remove leave-convo suppression, use real optimistic update (#10834)
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -1,18 +1,18 @@
|
||||
import {useMemo} from 'react'
|
||||
import {
|
||||
type ChatBskyConvoLeaveConvo,
|
||||
type ChatBskyConvoListConvos,
|
||||
} from '@atproto/api'
|
||||
import {
|
||||
useMutation,
|
||||
useMutationState,
|
||||
useQueryClient,
|
||||
} from '@tanstack/react-query'
|
||||
import {useMutation, useQueryClient} from '@tanstack/react-query'
|
||||
|
||||
import {DM_SERVICE_HEADERS} from '#/lib/constants'
|
||||
import {logger} from '#/logger'
|
||||
import {invalidateJoinLinkPreviewsForConvo} from '#/state/queries/join-links'
|
||||
import {useAgent} from '#/state/session'
|
||||
import {
|
||||
type ConvoRequestListQueryData,
|
||||
optimisticDelete as optimisticDeleteRequest,
|
||||
RQKEY_ROOT as REQUESTS_RQKEY_ROOT,
|
||||
} from './list-conversation-requests'
|
||||
import {RQKEY_ROOT as CONVO_LIST_KEY} from './list-conversations'
|
||||
|
||||
const RQKEY_ROOT = 'leave-convo'
|
||||
@@ -20,6 +20,11 @@ export function RQKEY(convoId: string | undefined) {
|
||||
return [RQKEY_ROOT, convoId]
|
||||
}
|
||||
|
||||
type ConvoListQueryData = {
|
||||
pageParams: Array<string | undefined>
|
||||
pages: Array<ChatBskyConvoListConvos.OutputSchema>
|
||||
}
|
||||
|
||||
export function useLeaveConvo(
|
||||
convoId: string | undefined,
|
||||
{
|
||||
@@ -48,31 +53,37 @@ export function useLeaveConvo(
|
||||
return data
|
||||
},
|
||||
onMutate: () => {
|
||||
let prevPages: ChatBskyConvoListConvos.OutputSchema[] = []
|
||||
queryClient.setQueryData(
|
||||
[CONVO_LIST_KEY],
|
||||
(old?: {
|
||||
pageParams: Array<string | undefined>
|
||||
pages: Array<ChatBskyConvoListConvos.OutputSchema>
|
||||
}) => {
|
||||
const prevConvoListQueries =
|
||||
queryClient.getQueriesData<ConvoListQueryData>({
|
||||
queryKey: [CONVO_LIST_KEY],
|
||||
})
|
||||
queryClient.setQueriesData<ConvoListQueryData>(
|
||||
{queryKey: [CONVO_LIST_KEY]},
|
||||
old => {
|
||||
if (!old) return old
|
||||
prevPages = old.pages
|
||||
return {
|
||||
...old,
|
||||
pages: old.pages.map(page => {
|
||||
return {
|
||||
...page,
|
||||
convos: page.convos.filter(convo => convo.id !== convoId),
|
||||
}
|
||||
}),
|
||||
pages: old.pages.map(page => ({
|
||||
...page,
|
||||
convos: page.convos.filter(convo => convo.id !== convoId),
|
||||
})),
|
||||
}
|
||||
},
|
||||
)
|
||||
const prevRequestsQueries =
|
||||
queryClient.getQueriesData<ConvoRequestListQueryData>({
|
||||
queryKey: [REQUESTS_RQKEY_ROOT],
|
||||
})
|
||||
queryClient.setQueriesData<ConvoRequestListQueryData>(
|
||||
{queryKey: [REQUESTS_RQKEY_ROOT]},
|
||||
old => (convoId ? optimisticDeleteRequest(convoId, old) : old),
|
||||
)
|
||||
onMutate?.()
|
||||
return {prevPages}
|
||||
return {prevConvoListQueries, prevRequestsQueries}
|
||||
},
|
||||
onSuccess: data => {
|
||||
void queryClient.invalidateQueries({queryKey: [CONVO_LIST_KEY]})
|
||||
void queryClient.invalidateQueries({queryKey: [REQUESTS_RQKEY_ROOT]})
|
||||
if (convoId) {
|
||||
void invalidateJoinLinkPreviewsForConvo(queryClient, convoId)
|
||||
}
|
||||
@@ -80,41 +91,19 @@ export function useLeaveConvo(
|
||||
},
|
||||
onError: (error, _, context) => {
|
||||
logger.error(error)
|
||||
queryClient.setQueryData(
|
||||
[CONVO_LIST_KEY],
|
||||
(old?: {
|
||||
pageParams: Array<string | undefined>
|
||||
pages: Array<ChatBskyConvoListConvos.OutputSchema>
|
||||
}) => {
|
||||
if (!old) return old
|
||||
return {
|
||||
...old,
|
||||
pages: context?.prevPages || old.pages,
|
||||
}
|
||||
},
|
||||
)
|
||||
if (context?.prevConvoListQueries) {
|
||||
for (const [queryKey, prevData] of context.prevConvoListQueries) {
|
||||
queryClient.setQueryData(queryKey, prevData)
|
||||
}
|
||||
}
|
||||
if (context?.prevRequestsQueries) {
|
||||
for (const [queryKey, prevData] of context.prevRequestsQueries) {
|
||||
queryClient.setQueryData(queryKey, prevData)
|
||||
}
|
||||
}
|
||||
void queryClient.invalidateQueries({queryKey: [CONVO_LIST_KEY]})
|
||||
void queryClient.invalidateQueries({queryKey: [REQUESTS_RQKEY_ROOT]})
|
||||
onError?.(error)
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets currently pending and successful leave convo mutations
|
||||
*
|
||||
* @returns Array of `convoId`
|
||||
*/
|
||||
export function useLeftConvos() {
|
||||
const pending = useMutationState({
|
||||
filters: {mutationKey: [RQKEY_ROOT], status: 'pending'},
|
||||
select: mutation => mutation.options.mutationKey?.[1] as string | undefined,
|
||||
})
|
||||
const success = useMutationState({
|
||||
filters: {mutationKey: [RQKEY_ROOT], status: 'success'},
|
||||
select: mutation => mutation.options.mutationKey?.[1] as string | undefined,
|
||||
})
|
||||
return useMemo(
|
||||
() => [...pending, ...success].filter(id => id !== undefined),
|
||||
[pending, success],
|
||||
)
|
||||
}
|
||||
|
||||
@@ -25,7 +25,6 @@ import {useAgeAssurance} from '#/ageAssurance'
|
||||
import {type AgeAssuranceFlags} from '#/ageAssurance/types'
|
||||
import * as bsky from '#/types/bsky'
|
||||
import {RQKEY as CONVO_KEY} from './conversation'
|
||||
import {useLeftConvos} from './leave-conversation'
|
||||
import {
|
||||
type ConvoRequestListQueryData,
|
||||
optimisticDelete as optimisticDeleteRequest,
|
||||
@@ -136,7 +135,6 @@ export function ListConvosProviderInner({
|
||||
const queryClient = useQueryClient()
|
||||
const {currentConvoId} = useCurrentConvoId()
|
||||
const {currentAccount} = useSession()
|
||||
const leftConvos = useLeftConvos()
|
||||
|
||||
const debouncedRefetch = useMemo(() => {
|
||||
const refetchAndInvalidate = () => {
|
||||
@@ -664,15 +662,12 @@ export function ListConvosProviderInner({
|
||||
])
|
||||
|
||||
const ctx = useMemo(() => {
|
||||
const convos =
|
||||
data?.pages
|
||||
.flatMap(page => page.convos)
|
||||
.filter(convo => !leftConvos.includes(convo.id)) ?? []
|
||||
const convos = data?.pages.flatMap(page => page.convos) ?? []
|
||||
return {
|
||||
accepted: convos.filter(conv => conv.status === 'accepted'),
|
||||
request: convos.filter(conv => conv.status === 'request'),
|
||||
}
|
||||
}, [data, leftConvos])
|
||||
}, [data])
|
||||
|
||||
return (
|
||||
<ListConvosContext.Provider value={ctx}>
|
||||
|
||||
Reference in New Issue
Block a user