diff --git a/src/components/dms/ConvoMenu.tsx b/src/components/dms/ConvoMenu.tsx
index cac4eb4d9d..8c8e7ed486 100644
--- a/src/components/dms/ConvoMenu.tsx
+++ b/src/components/dms/ConvoMenu.tsx
@@ -2,17 +2,18 @@ import React, {useCallback} from 'react'
import {Keyboard, Pressable, View} from 'react-native'
import {AppBskyActorDefs} from '@atproto/api'
import {ChatBskyConvoDefs} from '@atproto-labs/api'
+import {ConvoView} from '@atproto-labs/api/dist/client/types/chat/bsky/convo/defs'
import {msg, Trans} from '@lingui/macro'
import {useLingui} from '@lingui/react'
import {useNavigation} from '@react-navigation/native'
import {NavigationProp} from '#/lib/routes/types'
-import {useMarkAsReadMutation} from '#/state/queries/messages/conversation'
-import {useLeaveConvo} from '#/state/queries/messages/leave-conversation'
import {
- useMuteConvo,
- useUnmuteConvo,
-} from '#/state/queries/messages/mute-conversation'
+ useConvoQuery,
+ useMarkAsReadMutation,
+} from '#/state/queries/messages/conversation'
+import {useLeaveConvo} from '#/state/queries/messages/leave-conversation'
+import {useMuteConvo} from '#/state/queries/messages/mute-conversation'
import * as Toast from '#/view/com/util/Toast'
import {atoms as a, useTheme} from '#/alf'
import {ArrowBoxLeft_Stroke2_Corner0_Rounded as ArrowBoxLeft} from '#/components/icons/ArrowBoxLeft'
@@ -28,16 +29,15 @@ import * as Prompt from '#/components/Prompt'
import {Bubble_Stroke2_Corner2_Rounded as Bubble} from '../icons/Bubble'
let ConvoMenu = ({
- convo,
+ convo: initialConvo,
profile,
- onUpdateConvo,
control,
currentScreen,
showMarkAsRead,
hideTrigger,
triggerOpacity,
}: {
- convo: ChatBskyConvoDefs.ConvoView
+ convo: ConvoView
profile: AppBskyActorDefs.ProfileViewBasic
onUpdateConvo?: (convo: ChatBskyConvoDefs.ConvoView) => void
control?: Menu.MenuControlProps
@@ -52,31 +52,26 @@ let ConvoMenu = ({
const leaveConvoControl = Prompt.usePromptControl()
const {mutate: markAsRead} = useMarkAsReadMutation()
+ const {data: convo} = useConvoQuery(initialConvo)
+
const onNavigateToProfile = useCallback(() => {
navigation.navigate('Profile', {name: profile.did})
}, [navigation, profile.did])
- const {mutate: muteConvo} = useMuteConvo(convo.id, {
+ const {mutate: muteConvo} = useMuteConvo(convo?.id, {
onSuccess: data => {
- onUpdateConvo?.(data.convo)
- Toast.show(_(msg`Chat muted`))
+ if (data.convo.muted) {
+ Toast.show(_(msg`Chat muted`))
+ } else {
+ Toast.show(_(msg`Chat unmuted`))
+ }
},
onError: () => {
Toast.show(_(msg`Could not mute chat`))
},
})
- const {mutate: unmuteConvo} = useUnmuteConvo(convo.id, {
- onSuccess: data => {
- onUpdateConvo?.(data.convo)
- Toast.show(_(msg`Chat unmuted`))
- },
- onError: () => {
- Toast.show(_(msg`Could not unmute chat`))
- },
- })
-
- const {mutate: leaveConvo} = useLeaveConvo(convo.id, {
+ const {mutate: leaveConvo} = useLeaveConvo(convo?.id, {
onSuccess: () => {
if (currentScreen === 'conversation') {
navigation.replace('Messages')
@@ -121,7 +116,7 @@ let ConvoMenu = ({
label={_(msg`Mark as read`)}
onPress={() =>
markAsRead({
- convoId: convo.id,
+ convoId: convo?.id,
})
}>
@@ -140,7 +135,7 @@ let ConvoMenu = ({
(convo?.muted ? unmuteConvo() : muteConvo())}>
+ onPress={() => muteConvo({mute: !convo?.muted})}>
{convo?.muted ? (
Unmute notifications
diff --git a/src/screens/Messages/Conversation/index.tsx b/src/screens/Messages/Conversation/index.tsx
index fc4df0a24b..a783a0bd6d 100644
--- a/src/screens/Messages/Conversation/index.tsx
+++ b/src/screens/Messages/Conversation/index.tsx
@@ -56,7 +56,7 @@ export function MessagesConversationScreen({route}: Props) {
function Inner() {
const t = useTheme()
- const convo = useConvo()
+ const convoState = useConvo()
const {_} = useLingui()
const [hasInitiallyRendered, setHasInitiallyRendered] = React.useState(false)
@@ -72,23 +72,23 @@ function Inner() {
React.useEffect(() => {
if (
!hasInitiallyRendered &&
- convo.status === ConvoStatus.Ready &&
- !convo.isFetchingHistory
+ convoState.status === ConvoStatus.Ready &&
+ !convoState.isFetchingHistory
) {
setTimeout(() => {
setHasInitiallyRendered(true)
}, 15)
}
- }, [convo.isFetchingHistory, convo.items, convo.status, hasInitiallyRendered])
+ }, [convoState.isFetchingHistory, convoState.status, hasInitiallyRendered])
- if (convo.status === ConvoStatus.Error) {
+ if (convoState.status === ConvoStatus.Error) {
return (
convo.error.retry()}
+ onRetry={() => convoState.error.retry()}
/>
)
@@ -106,9 +106,9 @@ function Inner() {
behavior="padding"
contentContainerStyle={a.flex_1}>
-
+
- {convo.status !== ConvoStatus.Ready ? (
+ {convoState.status !== ConvoStatus.Ready ? (
) : (
@@ -145,7 +145,7 @@ let Header = ({
const {_} = useLingui()
const {gtTablet} = useBreakpoints()
const navigation = useNavigation()
- const convo = useConvo()
+ const convoState = useConvo()
const onPressBack = useCallback(() => {
if (isWeb) {
@@ -155,10 +155,6 @@ let Header = ({
}
}, [navigation])
- const onUpdateConvo = useCallback(() => {
- // TODO eric update muted state
- }, [])
-
return (
)}
- {convo.status === ConvoStatus.Ready && profile ? (
+ {convoState.status === ConvoStatus.Ready && profile ? (
) : (
diff --git a/src/state/queries/messages/conversation.ts b/src/state/queries/messages/conversation.ts
index b4861b5721..e420ba7363 100644
--- a/src/state/queries/messages/conversation.ts
+++ b/src/state/queries/messages/conversation.ts
@@ -1,4 +1,5 @@
import {BskyAgent} from '@atproto-labs/api'
+import {ConvoView} from '@atproto-labs/api/dist/client/types/chat/bsky/convo/defs'
import {useMutation, useQuery, useQueryClient} from '@tanstack/react-query'
import {useOnMarkAsRead} from '#/state/queries/messages/list-converations'
@@ -9,20 +10,21 @@ import {useHeaders} from './temp-headers'
const RQKEY_ROOT = 'convo'
export const RQKEY = (convoId: string) => [RQKEY_ROOT, convoId]
-export function useConvoQuery(convoId: string) {
+export function useConvoQuery(convo: ConvoView) {
const headers = useHeaders()
const {serviceUrl} = useDmServiceUrlStorage()
return useQuery({
- queryKey: RQKEY(convoId),
+ queryKey: RQKEY(convo.id),
queryFn: async () => {
const agent = new BskyAgent({service: serviceUrl})
const {data} = await agent.api.chat.bsky.convo.getConvo(
- {convoId},
+ {convoId: convo.id},
{headers},
)
return data.convo
},
+ initialData: convo,
})
}
@@ -37,9 +39,11 @@ export function useMarkAsReadMutation() {
convoId,
messageId,
}: {
- convoId: string
+ convoId?: string
messageId?: string
}) => {
+ if (!convoId) throw new Error('No convoId provided')
+
const agent = new BskyAgent({service: serviceUrl})
await agent.api.chat.bsky.convo.updateRead(
{
@@ -53,6 +57,7 @@ export function useMarkAsReadMutation() {
)
},
onMutate({convoId}) {
+ if (!convoId) throw new Error('No convoId provided')
optimisticUpdate(convoId)
},
onSettled() {
diff --git a/src/state/queries/messages/leave-conversation.ts b/src/state/queries/messages/leave-conversation.ts
index 0dd67fa0b1..5d5c64c5b9 100644
--- a/src/state/queries/messages/leave-conversation.ts
+++ b/src/state/queries/messages/leave-conversation.ts
@@ -11,7 +11,7 @@ import {RQKEY as CONVO_LIST_KEY} from './list-converations'
import {useHeaders} from './temp-headers'
export function useLeaveConvo(
- convoId: string,
+ convoId: string | undefined,
{
onSuccess,
onError,
@@ -26,6 +26,8 @@ export function useLeaveConvo(
return useMutation({
mutationFn: async () => {
+ if (!convoId) throw new Error('No convoId provided')
+
const agent = new BskyAgent({service: serviceUrl})
const {data} = await agent.api.chat.bsky.convo.leaveConvo(
{convoId},
@@ -41,7 +43,6 @@ export function useLeaveConvo(
pageParams: Array
pages: Array
}) => {
- console.log('old', old)
if (!old) return old
return {
...old,
diff --git a/src/state/queries/messages/mute-conversation.ts b/src/state/queries/messages/mute-conversation.ts
index 4840c65ade..f30612c73e 100644
--- a/src/state/queries/messages/mute-conversation.ts
+++ b/src/state/queries/messages/mute-conversation.ts
@@ -1,18 +1,18 @@
import {
BskyAgent,
+ ChatBskyConvoDefs,
+ ChatBskyConvoListConvos,
ChatBskyConvoMuteConvo,
- ChatBskyConvoUnmuteConvo,
} from '@atproto-labs/api'
-import {useMutation, useQueryClient} from '@tanstack/react-query'
+import {InfiniteData, useMutation, useQueryClient} from '@tanstack/react-query'
-import {logger} from '#/logger'
import {useDmServiceUrlStorage} from '#/screens/Messages/Temp/useDmServiceUrlStorage'
import {RQKEY as CONVO_KEY} from './conversation'
import {RQKEY as CONVO_LIST_KEY} from './list-converations'
import {useHeaders} from './temp-headers'
export function useMuteConvo(
- convoId: string,
+ convoId: string | undefined,
{
onSuccess,
onError,
@@ -26,59 +26,58 @@ export function useMuteConvo(
const {serviceUrl} = useDmServiceUrlStorage()
return useMutation({
- mutationFn: async () => {
- const agent = new BskyAgent({service: serviceUrl})
- const {data} = await agent.api.chat.bsky.convo.muteConvo(
- {convoId},
- {headers, encoding: 'application/json'},
- )
+ mutationFn: async ({mute}: {mute: boolean}) => {
+ if (!convoId) throw new Error('No convoId provided')
- return data
+ const agent = new BskyAgent({service: serviceUrl})
+ if (mute) {
+ const {data} = await agent.api.chat.bsky.convo.muteConvo(
+ {convoId},
+ {headers, encoding: 'application/json'},
+ )
+ return data
+ } else {
+ const {data} = await agent.api.chat.bsky.convo.unmuteConvo(
+ {convoId},
+ {headers, encoding: 'application/json'},
+ )
+ return data
+ }
},
- onSuccess: data => {
- queryClient.invalidateQueries({queryKey: CONVO_LIST_KEY})
- queryClient.invalidateQueries({queryKey: CONVO_KEY(convoId)})
+ onSuccess: (data, params) => {
+ queryClient.setQueryData(
+ CONVO_KEY(data.convo.id),
+ prev => {
+ if (!prev) return
+ return {
+ ...prev,
+ muted: params.mute,
+ }
+ },
+ )
+ queryClient.setQueryData<
+ InfiniteData
+ >(CONVO_LIST_KEY, prev => {
+ if (!prev?.pages) return
+ return {
+ ...prev,
+ pages: prev.pages.map(page => ({
+ ...page,
+ convos: page.convos.map(convo => {
+ if (convo.id !== data.convo.id) return convo
+ return {
+ ...convo,
+ muted: params.mute,
+ }
+ }),
+ })),
+ }
+ })
+
onSuccess?.(data)
},
- onError: error => {
- logger.error(error)
- onError?.(error)
- },
- })
-}
-
-export function useUnmuteConvo(
- convoId: string,
- {
- onSuccess,
- onError,
- }: {
- onSuccess?: (data: ChatBskyConvoUnmuteConvo.OutputSchema) => void
- onError?: (error: Error) => void
- },
-) {
- const queryClient = useQueryClient()
- const headers = useHeaders()
- const {serviceUrl} = useDmServiceUrlStorage()
-
- return useMutation({
- mutationFn: async () => {
- const agent = new BskyAgent({service: serviceUrl})
- const {data} = await agent.api.chat.bsky.convo.unmuteConvo(
- {convoId},
- {headers, encoding: 'application/json'},
- )
-
- return data
- },
- onSuccess: data => {
- queryClient.invalidateQueries({queryKey: CONVO_LIST_KEY})
- queryClient.invalidateQueries({queryKey: CONVO_KEY(convoId)})
- onSuccess?.(data)
- },
- onError: error => {
- logger.error(error)
- onError?.(error)
+ onError: e => {
+ onError?.(e)
},
})
}