Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 3 additions & 10 deletions src/screens/Messages/ChatList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ import {isNative} from '#/platform/detection'
import {listenSoftReset} from '#/state/events'
import {MESSAGE_SCREEN_POLL_INTERVAL} from '#/state/messages/convo/const'
import {useMessagesEventBus} from '#/state/messages/events'
import {useLeftConvos} from '#/state/queries/messages/leave-conversation'
import {useListConvosQuery} from '#/state/queries/messages/list-conversations'
import {useSession} from '#/state/session'
import {List, type ListRef} from '#/view/com/util/List'
Expand Down Expand Up @@ -149,14 +148,11 @@ export function MessagesScreenInner({navigation, route}: Props) {
useRefreshOnFocus(refetch)
useRefreshOnFocus(refetchInbox)

const leftConvos = useLeftConvos()

const inboxAllConvos =
inboxData?.pages
.flatMap(page => page.convos)
.filter(
convo =>
!leftConvos.includes(convo.id) &&
!convo.muted &&
convo.members.every(member => member.handle !== 'missing.invalid'),
) ?? []
Expand All @@ -172,10 +168,7 @@ export function MessagesScreenInner({navigation, route}: Props) {

const conversations = useMemo(() => {
if (data?.pages) {
const conversations = data.pages
.flatMap(page => page.convos)
// filter out convos that are actively being left
.filter(convo => !leftConvos.includes(convo.id))
const flattenedConvos = data.pages.flatMap(page => page.convos)

return [
...(hasInboxConvos
Expand All @@ -187,13 +180,13 @@ export function MessagesScreenInner({navigation, route}: Props) {
},
]
: []),
...conversations.map(
...flattenedConvos.map(
convo => ({type: 'CONVERSATION', conversation: convo}) as const,
),
] satisfies ListItem[]
}
return []
}, [data, leftConvos, hasInboxConvos, inboxUnreadConvoMembers])
}, [data, hasInboxConvos, inboxUnreadConvoMembers])

const onRefresh = useCallback(async () => {
setIsPTRing(true)
Expand Down
11 changes: 2 additions & 9 deletions src/screens/Messages/Inbox.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ import {logger} from '#/logger'
import {isNative} from '#/platform/detection'
import {MESSAGE_SCREEN_POLL_INTERVAL} from '#/state/messages/convo/const'
import {useMessagesEventBus} from '#/state/messages/events'
import {useLeftConvos} from '#/state/queries/messages/leave-conversation'
import {useListConvosQuery} from '#/state/queries/messages/list-conversations'
import {useUpdateAllRead} from '#/state/queries/messages/update-all-read'
import {FAB} from '#/view/com/util/fab/FAB'
Expand Down Expand Up @@ -66,19 +65,13 @@ export function MessagesInboxScreenInner({}: Props) {
const listConvosQuery = useListConvosQuery({status: 'request'})
const {data} = listConvosQuery

const leftConvos = useLeftConvos()

const conversations = useMemo(() => {
if (data?.pages) {
const convos = data.pages
.flatMap(page => page.convos)
// filter out convos that are actively being left
.filter(convo => !leftConvos.includes(convo.id))

const convos = data.pages.flatMap(page => page.convos)
return convos
}
return []
}, [data, leftConvos])
}, [data])

const hasUnreadConvos = useMemo(() => {
return conversations.some(
Expand Down
56 changes: 14 additions & 42 deletions src/state/queries/messages/leave-conversation.ts
Original file line number Diff line number Diff line change
@@ -1,33 +1,24 @@
import {useMemo} from 'react'
import {
type ChatBskyConvoLeaveConvo,
type ChatBskyConvoListConvos,
} from '@atproto/api'
import {
useMutation,
useMutationState,
useQueryClient,
} from '@tanstack/react-query'
import {type ChatBskyConvoListConvos} from '@atproto/api'
import {useMutation, useQueryClient} from '@tanstack/react-query'

import {DM_SERVICE_HEADERS} from '#/lib/constants'
import {logger} from '#/logger'
import {useAgent} from '#/state/session'
import {RQKEY_ROOT as CONVO_LIST_KEY} from './list-conversations'

const RQKEY_ROOT = 'leave-convo'
export function RQKEY(convoId: string | undefined) {
return [RQKEY_ROOT, convoId]
export const RQKEY_ROOT = 'leave-convo'

export function RQKEY(convoId: string) {
return [RQKEY_ROOT, convoId] as const
}

export function useLeaveConvo(
convoId: string | undefined,
convoId: string,
{
onSuccess,
onMutate,
onError,
}: {
onMutate?: () => void
onSuccess?: (data: ChatBskyConvoLeaveConvo.OutputSchema) => void
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Didn't see this option being used at all. Easy enough to add back in if you need it.

onError?: (error: Error) => void
},
) {
Expand All @@ -46,7 +37,8 @@ export function useLeaveConvo(

return data
},
onMutate: () => {
onMutate: async () => {
await queryClient.cancelQueries({queryKey: [CONVO_LIST_KEY]})
let prevPages: ChatBskyConvoListConvos.OutputSchema[] = []
queryClient.setQueryData(
[CONVO_LIST_KEY],
Expand All @@ -70,10 +62,6 @@ export function useLeaveConvo(
onMutate?.()
return {prevPages}
},
onSuccess: data => {
queryClient.invalidateQueries({queryKey: [CONVO_LIST_KEY]})
onSuccess?.(data)
},
onError: (error, _, context) => {
logger.error(error)
queryClient.setQueryData(
Expand All @@ -89,28 +77,12 @@ export function useLeaveConvo(
}
},
)
queryClient.invalidateQueries({queryKey: [CONVO_LIST_KEY]})
onError?.(error)
},
onSettled: () => {
if (queryClient.isMutating({mutationKey: RQKEY(convoId)}) === 1) {
queryClient.invalidateQueries({queryKey: [CONVO_LIST_KEY]})
}
},
})
}

/**
* 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],
)
}
22 changes: 14 additions & 8 deletions src/state/queries/messages/list-conversations.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {
type InfiniteData,
type QueryClient,
useInfiniteQuery,
useMutationState,
useQueryClient,
} from '@tanstack/react-query'
import throttle from 'lodash.throttle'
Expand All @@ -17,8 +18,8 @@ import {DM_SERVICE_HEADERS} from '#/lib/constants'
import {useCurrentConvoId} from '#/state/messages/current-convo-id'
import {useMessagesEventBus} from '#/state/messages/events'
import {useModerationOpts} from '#/state/preferences/moderation-opts'
import {RQKEY_ROOT as LEAVE_CONVO_RQKEY_ROOT} from '#/state/queries/messages/leave-conversation'
import {useAgent, useSession} from '#/state/session'
import {useLeftConvos} from './leave-conversation'

export const RQKEY_ROOT = 'convo-list'
export const RQKEY = (
Expand All @@ -38,8 +39,17 @@ export function useListConvosQuery({
} = {}) {
const agent = useAgent()

const leaveConvoMutationStates = useMutationState({
filters: {
mutationKey: [LEAVE_CONVO_RQKEY_ROOT],
status: 'pending',
},
})

return useInfiniteQuery({
enabled,
// Stop refetching if leaving conversation is pending, we
// do not want to override the optimistic update.
enabled: enabled && leaveConvoMutationStates.length === 0,
queryKey: RQKEY(status ?? 'all', readState),
queryFn: async ({pageParam}) => {
const {data} = await agent.chat.bsky.convo.listConvos(
Expand Down Expand Up @@ -97,7 +107,6 @@ export function ListConvosProviderInner({
const queryClient = useQueryClient()
const {currentConvoId} = useCurrentConvoId()
const {currentAccount} = useSession()
const leftConvos = useLeftConvos()

const debouncedRefetch = useMemo(() => {
const refetchAndInvalidate = () => {
Expand Down Expand Up @@ -376,15 +385,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}>
Expand Down
Loading