mirror of
				https://github.com/tooot-app/app
				synced 2025-06-05 22:19:13 +02:00 
			
		
		
		
	Fixed #568
This commit is contained in:
		
							
								
								
									
										2
									
								
								src/@types/mastodon.d.ts
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								src/@types/mastodon.d.ts
									
									
									
									
										vendored
									
									
								
							| @@ -406,6 +406,8 @@ declare namespace Mastodon { | ||||
|     id: string | ||||
|     following: boolean | ||||
|     showing_reblogs: boolean | ||||
|     notifying?: boolean | ||||
|     languages?: string[] | ||||
|     followed_by: boolean | ||||
|     blocking: boolean | ||||
|     blocked_by: boolean | ||||
|   | ||||
| @@ -6,120 +6,144 @@ import { | ||||
|   useRelationshipMutation, | ||||
|   useRelationshipQuery | ||||
| } from '@utils/queryHooks/relationship' | ||||
| import { QueryKeyTimeline } from '@utils/queryHooks/timeline' | ||||
| import { useTheme } from '@utils/styles/ThemeManager' | ||||
| import React from 'react' | ||||
| import { useTranslation } from 'react-i18next' | ||||
| import { useQueryClient } from '@tanstack/react-query' | ||||
| import { useSelector } from 'react-redux' | ||||
| import { checkInstanceFeature } from '@utils/slices/instancesSlice' | ||||
| import { StyleConstants } from '@utils/styles/constants' | ||||
|  | ||||
| export interface Props { | ||||
|   id: Mastodon.Account['id'] | ||||
| } | ||||
|  | ||||
| const RelationshipOutgoing = React.memo( | ||||
|   ({ id }: Props) => { | ||||
|     const { theme } = useTheme() | ||||
|     const { t } = useTranslation('componentRelationship') | ||||
| const RelationshipOutgoing: React.FC<Props> = ({ id }: Props) => { | ||||
|   const { theme } = useTheme() | ||||
|   const { t } = useTranslation('componentRelationship') | ||||
|  | ||||
|     const query = useRelationshipQuery({ id }) | ||||
|   const canFollowNotify = useSelector(checkInstanceFeature('account_follow_notify')) | ||||
|  | ||||
|     const queryKeyRelationship: QueryKeyRelationship = ['Relationship', { id }] | ||||
|     const queryClient = useQueryClient() | ||||
|     const mutation = useRelationshipMutation({ | ||||
|       onSuccess: (res, { payload: { action } }) => { | ||||
|         haptics('Success') | ||||
|         queryClient.setQueryData<Mastodon.Relationship[]>(queryKeyRelationship, [res]) | ||||
|         if (action === 'block') { | ||||
|           const queryKey = ['Timeline', { page: 'Following' }] | ||||
|           queryClient.invalidateQueries({ queryKey, exact: false }) | ||||
|         } | ||||
|       }, | ||||
|       onError: (err: any, { payload: { action } }) => { | ||||
|         displayMessage({ | ||||
|           theme, | ||||
|           type: 'error', | ||||
|           message: t('common:message.error.message', { | ||||
|             function: t(`${action}.function`) | ||||
|           }), | ||||
|           ...(err.status && | ||||
|             typeof err.status === 'number' && | ||||
|             err.data && | ||||
|             err.data.error && | ||||
|             typeof err.data.error === 'string' && { | ||||
|               description: err.data.error | ||||
|             }) | ||||
|         }) | ||||
|   const query = useRelationshipQuery({ id }) | ||||
|  | ||||
|   const queryKeyRelationship: QueryKeyRelationship = ['Relationship', { id }] | ||||
|   const queryClient = useQueryClient() | ||||
|   const mutation = useRelationshipMutation({ | ||||
|     onSuccess: (res, { payload: { action } }) => { | ||||
|       haptics('Success') | ||||
|       queryClient.setQueryData<Mastodon.Relationship[]>(queryKeyRelationship, [res]) | ||||
|       if (action === 'block') { | ||||
|         const queryKey = ['Timeline', { page: 'Following' }] | ||||
|         queryClient.invalidateQueries({ queryKey, exact: false }) | ||||
|       } | ||||
|     }) | ||||
|     }, | ||||
|     onError: (err: any, { payload: { action } }) => { | ||||
|       displayMessage({ | ||||
|         theme, | ||||
|         type: 'error', | ||||
|         message: t('common:message.error.message', { | ||||
|           function: t(`${action}.function`) | ||||
|         }), | ||||
|         ...(err.status && | ||||
|           typeof err.status === 'number' && | ||||
|           err.data && | ||||
|           err.data.error && | ||||
|           typeof err.data.error === 'string' && { | ||||
|             description: err.data.error | ||||
|           }) | ||||
|       }) | ||||
|     } | ||||
|   }) | ||||
|  | ||||
|     let content: string | ||||
|     let onPress: () => void | ||||
|   let content: string | ||||
|   let onPress: () => void | ||||
|  | ||||
|     if (query.isError) { | ||||
|       content = t('button.error') | ||||
|   if (query.isError) { | ||||
|     content = t('button.error') | ||||
|     onPress = () => {} | ||||
|   } else { | ||||
|     if (query.data?.blocked_by) { | ||||
|       content = t('button.blocked_by') | ||||
|       onPress = () => {} | ||||
|     } else { | ||||
|       if (query.data?.blocked_by) { | ||||
|         content = t('button.blocked_by') | ||||
|         onPress = () => {} | ||||
|       if (query.data?.blocking) { | ||||
|         content = t('button.blocking') | ||||
|         onPress = () => { | ||||
|           mutation.mutate({ | ||||
|             id, | ||||
|             type: 'outgoing', | ||||
|             payload: { | ||||
|               action: 'block', | ||||
|               state: query.data?.blocking | ||||
|             } | ||||
|           }) | ||||
|         } | ||||
|       } else { | ||||
|         if (query.data?.blocking) { | ||||
|           content = t('button.blocking') | ||||
|         if (query.data?.following) { | ||||
|           content = t('button.following') | ||||
|           onPress = () => { | ||||
|             mutation.mutate({ | ||||
|               id, | ||||
|               type: 'outgoing', | ||||
|               payload: { | ||||
|                 action: 'block', | ||||
|                 state: query.data?.blocking | ||||
|                 action: 'follow', | ||||
|                 state: query.data?.following | ||||
|               } | ||||
|             }) | ||||
|           } | ||||
|         } else { | ||||
|           if (query.data?.following) { | ||||
|             content = t('button.following') | ||||
|           if (query.data?.requested) { | ||||
|             content = t('button.requested') | ||||
|             onPress = () => { | ||||
|               mutation.mutate({ | ||||
|                 id, | ||||
|                 type: 'outgoing', | ||||
|                 payload: { | ||||
|                   action: 'follow', | ||||
|                   state: query.data?.following | ||||
|                   state: query.data?.requested | ||||
|                 } | ||||
|               }) | ||||
|             } | ||||
|           } else { | ||||
|             if (query.data?.requested) { | ||||
|               content = t('button.requested') | ||||
|               onPress = () => { | ||||
|                 mutation.mutate({ | ||||
|                   id, | ||||
|                   type: 'outgoing', | ||||
|                   payload: { | ||||
|                     action: 'follow', | ||||
|                     state: query.data?.requested | ||||
|                   } | ||||
|                 }) | ||||
|               } | ||||
|             } else { | ||||
|               content = t('button.default') | ||||
|               onPress = () => { | ||||
|                 mutation.mutate({ | ||||
|                   id, | ||||
|                   type: 'outgoing', | ||||
|                   payload: { | ||||
|                     action: 'follow', | ||||
|                     state: false | ||||
|                   } | ||||
|                 }) | ||||
|               } | ||||
|             content = t('button.default') | ||||
|             onPress = () => { | ||||
|               mutation.mutate({ | ||||
|                 id, | ||||
|                 type: 'outgoing', | ||||
|                 payload: { | ||||
|                   action: 'follow', | ||||
|                   state: false | ||||
|                 } | ||||
|               }) | ||||
|             } | ||||
|           } | ||||
|         } | ||||
|       } | ||||
|     } | ||||
|   } | ||||
|  | ||||
|     return ( | ||||
|   return ( | ||||
|     <> | ||||
|       {canFollowNotify && query.data?.following ? ( | ||||
|         <Button | ||||
|           type='icon' | ||||
|           content={query.data.notifying ? 'BellOff' : 'Bell'} | ||||
|           round | ||||
|           onPress={() => | ||||
|             mutation.mutate({ | ||||
|               id, | ||||
|               type: 'outgoing', | ||||
|               payload: { | ||||
|                 action: 'follow', | ||||
|                 state: false, | ||||
|                 notify: !query.data.notifying | ||||
|               } | ||||
|             }) | ||||
|           } | ||||
|           loading={query.isLoading || mutation.isLoading} | ||||
|           style={{ marginRight: StyleConstants.Spacing.S }} | ||||
|         /> | ||||
|       ) : null} | ||||
|       <Button | ||||
|         type='text' | ||||
|         content={content} | ||||
| @@ -127,9 +151,8 @@ const RelationshipOutgoing = React.memo( | ||||
|         loading={query.isLoading || mutation.isLoading} | ||||
|         disabled={query.isError || query.data?.blocked_by} | ||||
|       /> | ||||
|     ) | ||||
|   }, | ||||
|   () => true | ||||
| ) | ||||
|     </> | ||||
|   ) | ||||
| } | ||||
|  | ||||
| export default RelationshipOutgoing | ||||
|   | ||||
| @@ -1,4 +1,8 @@ | ||||
| [ | ||||
|   { | ||||
|     "feature": "account_follow_notify", | ||||
|     "version": 3.3 | ||||
|   }, | ||||
|   { | ||||
|     "feature": "notification_type_status", | ||||
|     "version": 3.3 | ||||
|   | ||||
| @@ -8,14 +8,9 @@ import { | ||||
|   UseQueryOptions | ||||
| } from '@tanstack/react-query' | ||||
|  | ||||
| export type QueryKeyRelationship = [ | ||||
|   'Relationship', | ||||
|   { id: Mastodon.Account['id'] } | ||||
| ] | ||||
| export type QueryKeyRelationship = ['Relationship', { id: Mastodon.Account['id'] }] | ||||
|  | ||||
| const queryFunction = async ({ | ||||
|   queryKey | ||||
| }: QueryFunctionContext<QueryKeyRelationship>) => { | ||||
| const queryFunction = async ({ queryKey }: QueryFunctionContext<QueryKeyRelationship>) => { | ||||
|   const { id } = queryKey[1] | ||||
|  | ||||
|   const res = await apiInstance<Mastodon.Relationship[]>({ | ||||
| @@ -32,11 +27,7 @@ const useRelationshipQuery = ({ | ||||
|   options, | ||||
|   ...queryKeyParams | ||||
| }: QueryKeyRelationship[1] & { | ||||
|   options?: UseQueryOptions< | ||||
|     Mastodon.Relationship[], | ||||
|     AxiosError, | ||||
|     Mastodon.Relationship | ||||
|   > | ||||
|   options?: UseQueryOptions<Mastodon.Relationship[], AxiosError, Mastodon.Relationship> | ||||
| }) => { | ||||
|   const queryKey: QueryKeyRelationship = ['Relationship', { ...queryKeyParams }] | ||||
|   return useQuery(queryKey, queryFunction, { | ||||
| @@ -54,7 +45,20 @@ type MutationVarsRelationship = | ||||
|   | { | ||||
|       id: Mastodon.Account['id'] | ||||
|       type: 'outgoing' | ||||
|       payload: { action: 'follow' | 'block'; state: boolean } | ||||
|       payload: { | ||||
|         action: 'block' | ||||
|         state: boolean | ||||
|         notify?: undefined | ||||
|       } | ||||
|     } | ||||
|   | { | ||||
|       id: Mastodon.Account['id'] | ||||
|       type: 'outgoing' | ||||
|       payload: { | ||||
|         action: 'follow' | ||||
|         state: boolean | ||||
|         notify?: boolean | ||||
|       } | ||||
|     } | ||||
|  | ||||
| const mutationFunction = async (params: MutationVarsRelationship) => { | ||||
| @@ -65,21 +69,20 @@ const mutationFunction = async (params: MutationVarsRelationship) => { | ||||
|         url: `follow_requests/${params.id}/${params.payload.action}` | ||||
|       }).then(res => res.body) | ||||
|     case 'outgoing': | ||||
|       const formData = new FormData() | ||||
|       typeof params.payload.notify === 'boolean' && | ||||
|         formData.append('notify', params.payload.notify.toString()) | ||||
|  | ||||
|       return apiInstance<Mastodon.Relationship>({ | ||||
|         method: 'post', | ||||
|         url: `accounts/${params.id}/${params.payload.state ? 'un' : ''}${ | ||||
|           params.payload.action | ||||
|         }` | ||||
|         url: `accounts/${params.id}/${params.payload.state ? 'un' : ''}${params.payload.action}`, | ||||
|         body: formData | ||||
|       }).then(res => res.body) | ||||
|   } | ||||
| } | ||||
|  | ||||
| const useRelationshipMutation = ( | ||||
|   options: UseMutationOptions< | ||||
|     Mastodon.Relationship, | ||||
|     AxiosError, | ||||
|     MutationVarsRelationship | ||||
|   > | ||||
|   options: UseMutationOptions<Mastodon.Relationship, AxiosError, MutationVarsRelationship> | ||||
| ) => { | ||||
|   return useMutation(mutationFunction, options) | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user