mirror of
https://github.com/tooot-app/app
synced 2025-06-05 22:19:13 +02:00
Switch to shared hooks
This commit is contained in:
@ -14,7 +14,7 @@ const queryFunction = ({ queryKey }: { queryKey: QueryKey }) => {
|
||||
})
|
||||
}
|
||||
|
||||
const hookAccount = <TData = Mastodon.Account>({
|
||||
const useAccountQuery = <TData = Mastodon.Account>({
|
||||
options,
|
||||
...queryKeyParams
|
||||
}: QueryKey[1] & {
|
||||
@ -24,4 +24,4 @@ const hookAccount = <TData = Mastodon.Account>({
|
||||
return useQuery(queryKey, queryFunction, options)
|
||||
}
|
||||
|
||||
export default hookAccount
|
||||
export { useAccountQuery }
|
||||
|
@ -22,7 +22,7 @@ const queryFunction = async ({ queryKey }: { queryKey: QueryKey }) => {
|
||||
})
|
||||
}
|
||||
|
||||
const hookAccountCheck = <TData = Mastodon.Account>({
|
||||
const useAccountCheckQuery = <TData = Mastodon.Account>({
|
||||
options,
|
||||
...queryKeyParams
|
||||
}: QueryKey[1] & {
|
||||
@ -32,4 +32,4 @@ const hookAccountCheck = <TData = Mastodon.Account>({
|
||||
return useQuery(queryKey, queryFunction, options)
|
||||
}
|
||||
|
||||
export default hookAccountCheck
|
||||
export { useAccountCheckQuery }
|
||||
|
@ -1,10 +1,15 @@
|
||||
import client from '@api/client'
|
||||
import { AxiosError } from 'axios'
|
||||
import { useQuery, UseQueryOptions } from 'react-query'
|
||||
import {
|
||||
useMutation,
|
||||
UseMutationOptions,
|
||||
useQuery,
|
||||
UseQueryOptions
|
||||
} from 'react-query'
|
||||
|
||||
type QueryKey = ['Announcements', { showAll?: boolean }]
|
||||
type QueryKeyAnnouncement = ['Announcements', { showAll?: boolean }]
|
||||
|
||||
const queryFunction = ({ queryKey }: { queryKey: QueryKey }) => {
|
||||
const queryFunction = ({ queryKey }: { queryKey: QueryKeyAnnouncement }) => {
|
||||
const { showAll } = queryKey[1]
|
||||
|
||||
return client<Mastodon.Announcement[]>({
|
||||
@ -19,14 +24,52 @@ const queryFunction = ({ queryKey }: { queryKey: QueryKey }) => {
|
||||
})
|
||||
}
|
||||
|
||||
const hookAnnouncement = <TData = Mastodon.Announcement[]>({
|
||||
const useAnnouncementQuery = <TData = Mastodon.Announcement[]>({
|
||||
options,
|
||||
...queryKeyParams
|
||||
}: QueryKey[1] & {
|
||||
}: QueryKeyAnnouncement[1] & {
|
||||
options?: UseQueryOptions<Mastodon.Announcement[], AxiosError, TData>
|
||||
}) => {
|
||||
const queryKey: QueryKey = ['Announcements', { ...queryKeyParams }]
|
||||
const queryKey: QueryKeyAnnouncement = [
|
||||
'Announcements',
|
||||
{ ...queryKeyParams }
|
||||
]
|
||||
return useQuery(queryKey, queryFunction, options)
|
||||
}
|
||||
|
||||
export default hookAnnouncement
|
||||
type MutationVarsAnnouncement = {
|
||||
id: Mastodon.Announcement['id']
|
||||
type: 'reaction' | 'dismiss'
|
||||
name?: Mastodon.AnnouncementReaction['name']
|
||||
me?: boolean
|
||||
}
|
||||
|
||||
const mutationFunction = async ({
|
||||
id,
|
||||
type,
|
||||
name,
|
||||
me
|
||||
}: MutationVarsAnnouncement) => {
|
||||
switch (type) {
|
||||
case 'reaction':
|
||||
return client<{}>({
|
||||
method: me ? 'delete' : 'put',
|
||||
instance: 'local',
|
||||
url: `announcements/${id}/reactions/${name}`
|
||||
})
|
||||
case 'dismiss':
|
||||
return client<{}>({
|
||||
method: 'post',
|
||||
instance: 'local',
|
||||
url: `announcements/${id}/dismiss`
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
const useAnnouncementMutation = (
|
||||
options: UseMutationOptions<{}, AxiosError, MutationVarsAnnouncement>
|
||||
) => {
|
||||
return useMutation(mutationFunction, options)
|
||||
}
|
||||
|
||||
export { useAnnouncementQuery, useAnnouncementMutation }
|
||||
|
@ -21,7 +21,7 @@ const queryFunction = ({ queryKey }: { queryKey: QueryKey }) => {
|
||||
})
|
||||
}
|
||||
|
||||
const hookApps = <TData = Mastodon.Apps>({
|
||||
const useAppsQuery = <TData = Mastodon.Apps>({
|
||||
options,
|
||||
...queryKeyParams
|
||||
}: QueryKey[1] & {
|
||||
@ -31,4 +31,4 @@ const hookApps = <TData = Mastodon.Apps>({
|
||||
return useQuery(queryKey, queryFunction, options)
|
||||
}
|
||||
|
||||
export default hookApps
|
||||
export { useAppsQuery }
|
||||
|
@ -12,7 +12,7 @@ const queryFunction = () => {
|
||||
})
|
||||
}
|
||||
|
||||
const hookEmojis = <TData = Mastodon.Emoji[]>({
|
||||
const useEmojisQuery = <TData = Mastodon.Emoji[]>({
|
||||
options
|
||||
}: {
|
||||
options?: UseQueryOptions<Mastodon.Emoji[], AxiosError, TData>
|
||||
@ -21,4 +21,4 @@ const hookEmojis = <TData = Mastodon.Emoji[]>({
|
||||
return useQuery(queryKey, queryFunction, options)
|
||||
}
|
||||
|
||||
export default hookEmojis
|
||||
export { useEmojisQuery }
|
||||
|
@ -15,7 +15,7 @@ const queryFunction = ({ queryKey }: { queryKey: QueryKey }) => {
|
||||
})
|
||||
}
|
||||
|
||||
const hookInstance = <TData = Mastodon.Instance>({
|
||||
const useInstanceQuery = <TData = Mastodon.Instance>({
|
||||
options,
|
||||
...queryKeyParams
|
||||
}: QueryKey[1] & {
|
||||
@ -25,4 +25,4 @@ const hookInstance = <TData = Mastodon.Instance>({
|
||||
return useQuery(queryKey, queryFunction, options)
|
||||
}
|
||||
|
||||
export default hookInstance
|
||||
export { useInstanceQuery }
|
||||
|
@ -12,7 +12,7 @@ const queryFunction = () => {
|
||||
})
|
||||
}
|
||||
|
||||
const hookLists = <TData = Mastodon.List[]>({
|
||||
const useListsQuery = <TData = Mastodon.List[]>({
|
||||
options
|
||||
}: {
|
||||
options?: UseQueryOptions<Mastodon.List[], AxiosError, TData>
|
||||
@ -21,4 +21,4 @@ const hookLists = <TData = Mastodon.List[]>({
|
||||
return useQuery(queryKey, queryFunction, options)
|
||||
}
|
||||
|
||||
export default hookLists
|
||||
export { useListsQuery }
|
||||
|
@ -1,6 +1,11 @@
|
||||
import client from '@api/client'
|
||||
import { AxiosError } from 'axios'
|
||||
import { useQuery, UseQueryOptions } from 'react-query'
|
||||
import {
|
||||
useMutation,
|
||||
UseMutationOptions,
|
||||
useQuery,
|
||||
UseQueryOptions
|
||||
} from 'react-query'
|
||||
|
||||
export type QueryKeyRelationship = [
|
||||
'Relationship',
|
||||
@ -20,7 +25,7 @@ const queryFunction = ({ queryKey }: { queryKey: QueryKeyRelationship }) => {
|
||||
})
|
||||
}
|
||||
|
||||
const hookRelationship = ({
|
||||
const useRelationshipQuery = ({
|
||||
options,
|
||||
...queryKeyParams
|
||||
}: QueryKeyRelationship[1] & {
|
||||
@ -37,4 +42,45 @@ const hookRelationship = ({
|
||||
})
|
||||
}
|
||||
|
||||
export default hookRelationship
|
||||
type MutationVarsRelationship =
|
||||
| {
|
||||
id: Mastodon.Account['id']
|
||||
type: 'incoming'
|
||||
payload: { action: 'authorize' | 'reject' }
|
||||
}
|
||||
| {
|
||||
id: Mastodon.Account['id']
|
||||
type: 'outgoing'
|
||||
payload: { action: 'follow' | 'block'; state: boolean }
|
||||
}
|
||||
|
||||
const mutationFunction = async (params: MutationVarsRelationship) => {
|
||||
switch (params.type) {
|
||||
case 'incoming':
|
||||
return client<Mastodon.Relationship>({
|
||||
method: 'post',
|
||||
instance: 'local',
|
||||
url: `follow_requests/${params.id}/${params.payload.action}`
|
||||
})
|
||||
case 'outgoing':
|
||||
return client<Mastodon.Relationship>({
|
||||
method: 'post',
|
||||
instance: 'local',
|
||||
url: `accounts/${params.id}/${params.payload.state ? 'un' : ''}${
|
||||
params.payload.action
|
||||
}`
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
const useRelationshipMutation = (
|
||||
options: UseMutationOptions<
|
||||
Mastodon.Relationship,
|
||||
AxiosError,
|
||||
MutationVarsRelationship
|
||||
>
|
||||
) => {
|
||||
return useMutation(mutationFunction, options)
|
||||
}
|
||||
|
||||
export { useRelationshipQuery, useRelationshipMutation }
|
||||
|
@ -33,7 +33,7 @@ const queryFunction = ({
|
||||
})
|
||||
}
|
||||
|
||||
const hookRelationships = <TData = Mastodon.Account[]>({
|
||||
const useRelationshipsQuery = <TData = Mastodon.Account[]>({
|
||||
options,
|
||||
...queryKeyParams
|
||||
}: QueryKey[1] & {
|
||||
@ -43,4 +43,4 @@ const hookRelationships = <TData = Mastodon.Account[]>({
|
||||
return useInfiniteQuery(queryKey, queryFunction, options)
|
||||
}
|
||||
|
||||
export default hookRelationships
|
||||
export { useRelationshipsQuery }
|
||||
|
@ -28,7 +28,7 @@ const queryFunction = ({ queryKey }: { queryKey: QueryKey }) => {
|
||||
})
|
||||
}
|
||||
|
||||
const hookSearch = <TData = SearchResult>({
|
||||
const useSearchQuery = <TData = SearchResult>({
|
||||
options,
|
||||
...queryKeyParams
|
||||
}: QueryKey[1] & {
|
||||
@ -38,4 +38,4 @@ const hookSearch = <TData = SearchResult>({
|
||||
return useQuery(queryKey, queryFunction, options)
|
||||
}
|
||||
|
||||
export default hookSearch
|
||||
export { useSearchQuery }
|
||||
|
@ -1,7 +1,16 @@
|
||||
import client from '@api/client'
|
||||
import haptics from '@components/haptics'
|
||||
import { AxiosError } from 'axios'
|
||||
import { uniqBy } from 'lodash'
|
||||
import { useInfiniteQuery, UseInfiniteQueryOptions } from 'react-query'
|
||||
import {
|
||||
MutationOptions,
|
||||
QueryClient,
|
||||
useInfiniteQuery,
|
||||
UseInfiniteQueryOptions,
|
||||
useMutation
|
||||
} from 'react-query'
|
||||
import deleteItem from './timeline/deleteItem'
|
||||
import updateStatusProperty from './timeline/updateStatusProperty'
|
||||
|
||||
export type QueryKeyTimeline = [
|
||||
'Timeline',
|
||||
@ -14,7 +23,7 @@ export type QueryKeyTimeline = [
|
||||
}
|
||||
]
|
||||
|
||||
const queryFunction = async ({
|
||||
const queryFunction = ({
|
||||
queryKey,
|
||||
pageParam
|
||||
}: {
|
||||
@ -22,7 +31,6 @@ const queryFunction = async ({
|
||||
pageParam?: { direction: 'prev' | 'next'; id: Mastodon.Status['id'] }
|
||||
}) => {
|
||||
const { page, account, hashtag, list, toot } = queryKey[1]
|
||||
let res
|
||||
let params: { [key: string]: string } = {}
|
||||
|
||||
if (pageParam) {
|
||||
@ -46,74 +54,51 @@ const queryFunction = async ({
|
||||
|
||||
switch (page) {
|
||||
case 'Following':
|
||||
res = await client<Mastodon.Status[]>({
|
||||
return client<Mastodon.Status[]>({
|
||||
method: 'get',
|
||||
instance: 'local',
|
||||
url: 'timelines/home',
|
||||
params
|
||||
})
|
||||
return Promise.resolve({
|
||||
toots: res,
|
||||
pointer: undefined,
|
||||
pinnedLength: undefined
|
||||
})
|
||||
|
||||
case 'Local':
|
||||
params.local = 'true'
|
||||
res = await client<Mastodon.Status[]>({
|
||||
return client<Mastodon.Status[]>({
|
||||
method: 'get',
|
||||
instance: 'local',
|
||||
url: 'timelines/public',
|
||||
params
|
||||
})
|
||||
return Promise.resolve({
|
||||
toots: res,
|
||||
pointer: undefined,
|
||||
pinnedLength: undefined
|
||||
params: {
|
||||
...params,
|
||||
local: 'true'
|
||||
}
|
||||
})
|
||||
|
||||
case 'LocalPublic':
|
||||
res = await client<Mastodon.Status[]>({
|
||||
return client<Mastodon.Status[]>({
|
||||
method: 'get',
|
||||
instance: 'local',
|
||||
url: 'timelines/public',
|
||||
params
|
||||
})
|
||||
return Promise.resolve({
|
||||
toots: res,
|
||||
pointer: undefined,
|
||||
pinnedLength: undefined
|
||||
})
|
||||
|
||||
case 'RemotePublic':
|
||||
res = await client<Mastodon.Status[]>({
|
||||
return client<Mastodon.Status[]>({
|
||||
method: 'get',
|
||||
instance: 'remote',
|
||||
url: 'timelines/public',
|
||||
params
|
||||
})
|
||||
return Promise.resolve({
|
||||
toots: res,
|
||||
pointer: undefined,
|
||||
pinnedLength: undefined
|
||||
})
|
||||
|
||||
case 'Notifications':
|
||||
res = await client<Mastodon.Notification[]>({
|
||||
return client<Mastodon.Notification[]>({
|
||||
method: 'get',
|
||||
instance: 'local',
|
||||
url: 'notifications',
|
||||
params
|
||||
})
|
||||
return Promise.resolve({
|
||||
toots: res,
|
||||
pointer: undefined,
|
||||
pinnedLength: undefined
|
||||
})
|
||||
|
||||
case 'Account_Default':
|
||||
if (pageParam && pageParam.direction === 'next') {
|
||||
res = await client<Mastodon.Status[]>({
|
||||
return client<Mastodon.Status[]>({
|
||||
method: 'get',
|
||||
instance: 'local',
|
||||
url: `accounts/${account}/statuses`,
|
||||
@ -122,53 +107,41 @@ const queryFunction = async ({
|
||||
...params
|
||||
}
|
||||
})
|
||||
return Promise.resolve({
|
||||
toots: res,
|
||||
pointer: undefined,
|
||||
pinnedLength: undefined
|
||||
})
|
||||
} else {
|
||||
res = await client<Mastodon.Status[]>({
|
||||
return client<(Mastodon.Status & { isPinned: boolean })[]>({
|
||||
method: 'get',
|
||||
instance: 'local',
|
||||
url: `accounts/${account}/statuses`,
|
||||
params: {
|
||||
pinned: 'true'
|
||||
}
|
||||
})
|
||||
const pinnedLength = res.length
|
||||
let toots = res
|
||||
res = await client<Mastodon.Status[]>({
|
||||
method: 'get',
|
||||
instance: 'local',
|
||||
url: `accounts/${account}/statuses`,
|
||||
params: {
|
||||
exclude_replies: 'true'
|
||||
}
|
||||
})
|
||||
toots = uniqBy([...toots, ...res], 'id')
|
||||
return Promise.resolve({
|
||||
toots: toots,
|
||||
pointer: undefined,
|
||||
pinnedLength
|
||||
}).then(async res1 => {
|
||||
let toots = res1.map(status => {
|
||||
status.isPinned = true
|
||||
return status
|
||||
})
|
||||
const res2 = await client<Mastodon.Status[]>({
|
||||
method: 'get',
|
||||
instance: 'local',
|
||||
url: `accounts/${account}/statuses`,
|
||||
params: {
|
||||
exclude_replies: 'true'
|
||||
}
|
||||
})
|
||||
return uniqBy([...toots, ...res2], 'id')
|
||||
})
|
||||
}
|
||||
|
||||
case 'Account_All':
|
||||
res = await client<Mastodon.Status[]>({
|
||||
return client<Mastodon.Status[]>({
|
||||
method: 'get',
|
||||
instance: 'local',
|
||||
url: `accounts/${account}/statuses`,
|
||||
params
|
||||
})
|
||||
return Promise.resolve({
|
||||
toots: res,
|
||||
pointer: undefined,
|
||||
pinnedLength: undefined
|
||||
})
|
||||
|
||||
case 'Account_Media':
|
||||
res = await client<Mastodon.Status[]>({
|
||||
return client<Mastodon.Status[]>({
|
||||
method: 'get',
|
||||
instance: 'local',
|
||||
url: `accounts/${account}/statuses`,
|
||||
@ -177,100 +150,62 @@ const queryFunction = async ({
|
||||
...params
|
||||
}
|
||||
})
|
||||
return Promise.resolve({
|
||||
toots: res,
|
||||
pointer: undefined,
|
||||
pinnedLength: undefined
|
||||
})
|
||||
|
||||
case 'Hashtag':
|
||||
res = await client<Mastodon.Status[]>({
|
||||
return client<Mastodon.Status[]>({
|
||||
method: 'get',
|
||||
instance: 'local',
|
||||
url: `timelines/tag/${hashtag}`,
|
||||
params
|
||||
})
|
||||
return Promise.resolve({
|
||||
toots: res,
|
||||
pointer: undefined,
|
||||
pinnedLength: undefined
|
||||
})
|
||||
|
||||
case 'Conversations':
|
||||
res = await client<Mastodon.Conversation[]>({
|
||||
return client<Mastodon.Conversation[]>({
|
||||
method: 'get',
|
||||
instance: 'local',
|
||||
url: `conversations`,
|
||||
params
|
||||
})
|
||||
if (pageParam) {
|
||||
// Bug in pull to refresh in conversations
|
||||
res = res.filter(b => b.id !== pageParam.id)
|
||||
}
|
||||
return Promise.resolve({
|
||||
toots: res,
|
||||
pointer: undefined,
|
||||
pinnedLength: undefined
|
||||
})
|
||||
|
||||
case 'Bookmarks':
|
||||
res = await client<Mastodon.Status[]>({
|
||||
return client<Mastodon.Status[]>({
|
||||
method: 'get',
|
||||
instance: 'local',
|
||||
url: `bookmarks`,
|
||||
params
|
||||
})
|
||||
return Promise.resolve({
|
||||
toots: res,
|
||||
pointer: undefined,
|
||||
pinnedLength: undefined
|
||||
})
|
||||
|
||||
case 'Favourites':
|
||||
res = await client<Mastodon.Status[]>({
|
||||
return client<Mastodon.Status[]>({
|
||||
method: 'get',
|
||||
instance: 'local',
|
||||
url: `favourites`,
|
||||
params
|
||||
})
|
||||
return Promise.resolve({
|
||||
toots: res,
|
||||
pointer: undefined,
|
||||
pinnedLength: undefined
|
||||
})
|
||||
|
||||
case 'List':
|
||||
res = await client<Mastodon.Status[]>({
|
||||
return client<Mastodon.Status[]>({
|
||||
method: 'get',
|
||||
instance: 'local',
|
||||
url: `timelines/list/${list}`,
|
||||
params
|
||||
})
|
||||
return Promise.resolve({
|
||||
toots: res,
|
||||
pointer: undefined,
|
||||
pinnedLength: undefined
|
||||
})
|
||||
|
||||
case 'Toot':
|
||||
res = await client<Mastodon.Status>({
|
||||
return client<Mastodon.Status>({
|
||||
method: 'get',
|
||||
instance: 'local',
|
||||
url: `statuses/${toot}`
|
||||
})
|
||||
const theToot = res
|
||||
res = await client<{
|
||||
ancestors: Mastodon.Status[]
|
||||
descendants: Mastodon.Status[]
|
||||
}>({
|
||||
method: 'get',
|
||||
instance: 'local',
|
||||
url: `statuses/${toot}/context`
|
||||
})
|
||||
return Promise.resolve({
|
||||
toots: [...res.ancestors, theToot, ...res.descendants],
|
||||
pointer: res.ancestors.length,
|
||||
pinnedLength: undefined
|
||||
}).then(async res1 => {
|
||||
const res2 = await client<{
|
||||
ancestors: Mastodon.Status[]
|
||||
descendants: Mastodon.Status[]
|
||||
}>({
|
||||
method: 'get',
|
||||
instance: 'local',
|
||||
url: `statuses/${toot}/context`
|
||||
})
|
||||
return [...res2.ancestors, res1, ...res2.descendants]
|
||||
})
|
||||
default:
|
||||
return Promise.reject()
|
||||
@ -278,7 +213,8 @@ const queryFunction = async ({
|
||||
}
|
||||
|
||||
type Unpromise<T extends Promise<any>> = T extends Promise<infer U> ? U : never
|
||||
const hookTimeline = <TData = Unpromise<ReturnType<typeof queryFunction>>>({
|
||||
export type TimelineData = Unpromise<ReturnType<typeof queryFunction>>
|
||||
const useTimelineQuery = <TData = TimelineData>({
|
||||
options,
|
||||
...queryKeyParams
|
||||
}: QueryKeyTimeline[1] & {
|
||||
@ -288,4 +224,199 @@ const hookTimeline = <TData = Unpromise<ReturnType<typeof queryFunction>>>({
|
||||
return useInfiniteQuery(queryKey, queryFunction, options)
|
||||
}
|
||||
|
||||
export default hookTimeline
|
||||
// --- Separator ---
|
||||
|
||||
enum MapPropertyToUrl {
|
||||
bookmarked = 'bookmark',
|
||||
favourited = 'favourite',
|
||||
muted = 'mute',
|
||||
pinned = 'pin',
|
||||
reblogged = 'reblog'
|
||||
}
|
||||
|
||||
export type MutationVarsTimelineUpdateStatusProperty = {
|
||||
// This is status in general, including "status" inside conversation and notification
|
||||
type: 'updateStatusProperty'
|
||||
queryKey: QueryKeyTimeline
|
||||
id: Mastodon.Status['id'] | Mastodon.Poll['id']
|
||||
reblog?: boolean
|
||||
payload:
|
||||
| {
|
||||
property: 'bookmarked' | 'favourited' | 'muted' | 'pinned' | 'reblogged'
|
||||
currentValue: boolean
|
||||
}
|
||||
| {
|
||||
property: 'poll'
|
||||
id: Mastodon.Poll['id']
|
||||
type: 'vote' | 'refresh'
|
||||
options?: boolean[]
|
||||
data?: Mastodon.Poll
|
||||
}
|
||||
}
|
||||
|
||||
export type MutationVarsTimelineUpdateAccountProperty = {
|
||||
// This is status in general, including "status" inside conversation and notification
|
||||
type: 'updateAccountProperty'
|
||||
queryKey?: QueryKeyTimeline
|
||||
id: Mastodon.Account['id']
|
||||
payload: {
|
||||
property: 'mute' | 'block' | 'reports'
|
||||
}
|
||||
}
|
||||
|
||||
export type MutationVarsTimelineDeleteItem = {
|
||||
// This is for deleting status and conversation
|
||||
type: 'deleteItem'
|
||||
source: 'statuses' | 'conversations'
|
||||
queryKey: QueryKeyTimeline
|
||||
id: Mastodon.Conversation['id']
|
||||
}
|
||||
|
||||
export type MutationVarsTimelineDomainBlock = {
|
||||
// This is for deleting status and conversation
|
||||
type: 'domainBlock'
|
||||
queryKey: QueryKeyTimeline
|
||||
domain: string
|
||||
}
|
||||
|
||||
export type MutationVarsTimeline =
|
||||
| MutationVarsTimelineUpdateStatusProperty
|
||||
| MutationVarsTimelineUpdateAccountProperty
|
||||
| MutationVarsTimelineDeleteItem
|
||||
| MutationVarsTimelineDomainBlock
|
||||
|
||||
const mutationFunction = async (params: MutationVarsTimeline) => {
|
||||
switch (params.type) {
|
||||
case 'updateStatusProperty':
|
||||
switch (params.payload.property) {
|
||||
case 'poll':
|
||||
const formData = new FormData()
|
||||
params.payload.type === 'vote' &&
|
||||
params.payload.options!.forEach((option, index) => {
|
||||
if (option) {
|
||||
formData.append('choices[]', index.toString())
|
||||
}
|
||||
})
|
||||
|
||||
return client<Mastodon.Poll>({
|
||||
method: params.payload.type === 'vote' ? 'post' : 'get',
|
||||
instance: 'local',
|
||||
url:
|
||||
params.payload.type === 'vote'
|
||||
? `polls/${params.payload.id}/votes`
|
||||
: `polls/${params.payload.id}`,
|
||||
...(params.payload.type === 'vote' && { body: formData })
|
||||
})
|
||||
default:
|
||||
return client<Mastodon.Status>({
|
||||
method: 'post',
|
||||
instance: 'local',
|
||||
url: `statuses/${params.id}/${
|
||||
params.payload.currentValue ? 'un' : ''
|
||||
}${MapPropertyToUrl[params.payload.property]}`
|
||||
})
|
||||
}
|
||||
case 'updateAccountProperty':
|
||||
switch (params.payload.property) {
|
||||
case 'block':
|
||||
case 'mute':
|
||||
return client<Mastodon.Account>({
|
||||
method: 'post',
|
||||
instance: 'local',
|
||||
url: `accounts/${params.id}/${params.payload.property}`
|
||||
})
|
||||
case 'reports':
|
||||
return client<Mastodon.Account>({
|
||||
method: 'post',
|
||||
instance: 'local',
|
||||
url: `reports`,
|
||||
params: {
|
||||
account_id: params.id
|
||||
}
|
||||
})
|
||||
}
|
||||
case 'deleteItem':
|
||||
return client<Mastodon.Conversation>({
|
||||
method: 'delete',
|
||||
instance: 'local',
|
||||
url: `${params.source}/${params.id}`
|
||||
})
|
||||
case 'domainBlock':
|
||||
return client<any>({
|
||||
method: 'post',
|
||||
instance: 'local',
|
||||
url: `domain_blocks`,
|
||||
params: {
|
||||
domain: params.domain
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
type MutationOptionsTimeline = MutationOptions<
|
||||
Mastodon.Conversation | Mastodon.Notification | Mastodon.Status,
|
||||
AxiosError,
|
||||
MutationVarsTimeline
|
||||
>
|
||||
|
||||
const useTimelineMutation = ({
|
||||
queryClient,
|
||||
onError,
|
||||
onMutate,
|
||||
onSettled,
|
||||
onSuccess
|
||||
}: {
|
||||
queryClient: QueryClient
|
||||
onError?: MutationOptionsTimeline['onError']
|
||||
onMutate?: boolean
|
||||
onSettled?: MutationOptionsTimeline['onSettled']
|
||||
onSuccess?: MutationOptionsTimeline['onSuccess'] | boolean
|
||||
}) => {
|
||||
return useMutation<
|
||||
Mastodon.Conversation | Mastodon.Notification | Mastodon.Status,
|
||||
AxiosError,
|
||||
MutationVarsTimeline
|
||||
>(mutationFunction, {
|
||||
onError,
|
||||
onSettled,
|
||||
...(typeof onSuccess === 'function'
|
||||
? { onSuccess }
|
||||
: {
|
||||
onSuccess: (data, params) => {
|
||||
queryClient.cancelQueries(params.queryKey)
|
||||
|
||||
haptics('Success')
|
||||
switch (params.type) {
|
||||
case 'updateStatusProperty':
|
||||
switch (params.payload.property) {
|
||||
case 'poll':
|
||||
params.payload.data = (data as unknown) as Mastodon.Poll
|
||||
updateStatusProperty({ queryClient, ...params })
|
||||
break
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
}),
|
||||
...(onMutate && {
|
||||
onMutate: params => {
|
||||
queryClient.cancelQueries(params.queryKey)
|
||||
let oldData
|
||||
params.queryKey && (oldData = queryClient.getQueryData(params.queryKey))
|
||||
|
||||
haptics('Success')
|
||||
switch (params.type) {
|
||||
case 'updateStatusProperty':
|
||||
updateStatusProperty({ queryClient, ...params })
|
||||
break
|
||||
case 'deleteItem':
|
||||
deleteItem({ queryClient, ...params })
|
||||
break
|
||||
}
|
||||
return oldData
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
export { useTimelineQuery, useTimelineMutation }
|
||||
|
25
src/utils/queryHooks/timeline/deleteItem.ts
Normal file
25
src/utils/queryHooks/timeline/deleteItem.ts
Normal file
@ -0,0 +1,25 @@
|
||||
import { InfiniteData, QueryClient } from 'react-query'
|
||||
import { QueryKeyTimeline } from '../timeline'
|
||||
|
||||
const deleteItem = ({
|
||||
queryClient,
|
||||
queryKey,
|
||||
id
|
||||
}: {
|
||||
queryClient: QueryClient
|
||||
queryKey: QueryKeyTimeline
|
||||
id: Mastodon.Status['id']
|
||||
}) => {
|
||||
queryClient.setQueryData<InfiniteData<Mastodon.Conversation[]> | undefined>(
|
||||
queryKey,
|
||||
old => {
|
||||
if (old) {
|
||||
old.pages = old.pages.map(page => page.filter(item => item.id !== id))
|
||||
}
|
||||
|
||||
return old
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
export default deleteItem
|
27
src/utils/queryHooks/timeline/update/conversation.ts
Normal file
27
src/utils/queryHooks/timeline/update/conversation.ts
Normal file
@ -0,0 +1,27 @@
|
||||
import { MutationVarsTimelineUpdateStatusProperty } from '@utils/queryHooks/timeline'
|
||||
|
||||
const updateConversation = ({
|
||||
item,
|
||||
payload
|
||||
}: {
|
||||
item: Mastodon.Conversation
|
||||
payload: MutationVarsTimelineUpdateStatusProperty['payload']
|
||||
}) => {
|
||||
switch (payload.property) {
|
||||
case 'poll':
|
||||
if (item.last_status) {
|
||||
item.last_status[payload.property] = payload.data
|
||||
}
|
||||
return item
|
||||
default:
|
||||
if (item.last_status) {
|
||||
item.last_status[payload.property] =
|
||||
typeof payload.currentValue === 'boolean'
|
||||
? !payload.currentValue
|
||||
: true
|
||||
}
|
||||
return item
|
||||
}
|
||||
}
|
||||
|
||||
export default updateConversation
|
24
src/utils/queryHooks/timeline/update/notification.ts
Normal file
24
src/utils/queryHooks/timeline/update/notification.ts
Normal file
@ -0,0 +1,24 @@
|
||||
import { MutationVarsTimelineUpdateStatusProperty } from '@utils/queryHooks/timeline'
|
||||
|
||||
const updateNotification = ({
|
||||
item,
|
||||
payload
|
||||
}: {
|
||||
item: Mastodon.Notification
|
||||
payload: MutationVarsTimelineUpdateStatusProperty['payload']
|
||||
}) => {
|
||||
switch (payload.property) {
|
||||
case 'poll':
|
||||
return item
|
||||
default:
|
||||
if (item.status) {
|
||||
item.status[payload.property] =
|
||||
typeof payload.currentValue === 'boolean'
|
||||
? !payload.currentValue
|
||||
: true
|
||||
}
|
||||
return item
|
||||
}
|
||||
}
|
||||
|
||||
export default updateNotification
|
37
src/utils/queryHooks/timeline/update/status.ts
Normal file
37
src/utils/queryHooks/timeline/update/status.ts
Normal file
@ -0,0 +1,37 @@
|
||||
import { MutationVarsTimelineUpdateStatusProperty } from '@utils/queryHooks/timeline'
|
||||
|
||||
const updateStatus = ({
|
||||
item,
|
||||
reblog,
|
||||
payload
|
||||
}: {
|
||||
item: Mastodon.Status
|
||||
reblog?: boolean
|
||||
payload: MutationVarsTimelineUpdateStatusProperty['payload']
|
||||
}) => {
|
||||
switch (payload.property) {
|
||||
case 'poll':
|
||||
console.log(payload.data)
|
||||
if (reblog) {
|
||||
item.reblog!.poll = payload.data
|
||||
} else {
|
||||
item.poll = payload.data
|
||||
}
|
||||
break
|
||||
default:
|
||||
if (reblog) {
|
||||
item.reblog![payload.property] =
|
||||
typeof payload.currentValue === 'boolean'
|
||||
? !payload.currentValue
|
||||
: true
|
||||
} else {
|
||||
item[payload.property] =
|
||||
typeof payload.currentValue === 'boolean'
|
||||
? !payload.currentValue
|
||||
: true
|
||||
}
|
||||
return item
|
||||
}
|
||||
}
|
||||
|
||||
export default updateStatus
|
76
src/utils/queryHooks/timeline/updateStatusProperty.ts
Normal file
76
src/utils/queryHooks/timeline/updateStatusProperty.ts
Normal file
@ -0,0 +1,76 @@
|
||||
import { findIndex } from 'lodash'
|
||||
import { InfiniteData, QueryClient } from 'react-query'
|
||||
import {
|
||||
MutationVarsTimelineUpdateStatusProperty,
|
||||
TimelineData
|
||||
} from '../timeline'
|
||||
import updateConversation from './update/conversation'
|
||||
import updateNotification from './update/notification'
|
||||
import updateStatus from './update/status'
|
||||
|
||||
const updateStatusProperty = ({
|
||||
queryClient,
|
||||
queryKey,
|
||||
id,
|
||||
reblog,
|
||||
payload
|
||||
}: {
|
||||
queryClient: QueryClient
|
||||
queryKey: MutationVarsTimelineUpdateStatusProperty['queryKey']
|
||||
id: MutationVarsTimelineUpdateStatusProperty['id']
|
||||
reblog?: MutationVarsTimelineUpdateStatusProperty['reblog']
|
||||
payload: MutationVarsTimelineUpdateStatusProperty['payload']
|
||||
}) => {
|
||||
queryClient.setQueryData<InfiniteData<TimelineData> | undefined>(
|
||||
queryKey,
|
||||
old => {
|
||||
if (old) {
|
||||
let foundToot = false
|
||||
old.pages = old.pages.map(page => {
|
||||
// Skip rest of the pages if any toot is found
|
||||
if (foundToot) {
|
||||
return page
|
||||
} else {
|
||||
if (
|
||||
typeof (page as Mastodon.Conversation[])[0].unread === 'boolean'
|
||||
) {
|
||||
const items = page as Mastodon.Conversation[]
|
||||
const tootIndex = findIndex(items, ['last_status.id', id])
|
||||
if (tootIndex >= 0) {
|
||||
foundToot = true
|
||||
updateConversation({ item: items[tootIndex], payload })
|
||||
}
|
||||
return page
|
||||
} else if (
|
||||
typeof (page as Mastodon.Notification[])[0].type === 'string'
|
||||
) {
|
||||
const items = page as Mastodon.Notification[]
|
||||
const tootIndex = findIndex(items, ['status.id', id])
|
||||
if (tootIndex >= 0) {
|
||||
foundToot = true
|
||||
updateNotification({ item: items[tootIndex], payload })
|
||||
}
|
||||
} else {
|
||||
const items = page as Mastodon.Status[]
|
||||
const tootIndex = findIndex(items, [
|
||||
reblog ? 'reblog.id' : 'id',
|
||||
id
|
||||
])
|
||||
// if favouriets page and notifications page, remove the item instead
|
||||
if (tootIndex >= 0) {
|
||||
foundToot = true
|
||||
updateStatus({ item: items[tootIndex], reblog, payload })
|
||||
}
|
||||
}
|
||||
|
||||
return page
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
return old
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
export default updateStatusProperty
|
Reference in New Issue
Block a user