mirror of
https://github.com/tooot-app/app
synced 2025-06-05 22:19:13 +02:00
Simplify update toot logic
This commit is contained in:
@ -248,35 +248,23 @@ export type MutationVarsTimelineUpdateStatusProperty = {
|
||||
type: 'updateStatusProperty'
|
||||
queryKey: QueryKeyTimeline
|
||||
rootQueryKey?: QueryKeyTimeline
|
||||
id: Mastodon.Status['id'] | Mastodon.Poll['id']
|
||||
isReblog?: boolean
|
||||
fetchRemoteURI?: Mastodon.Status['uri']
|
||||
status: Mastodon.Status
|
||||
payload:
|
||||
| {
|
||||
property: 'bookmarked' | 'muted' | 'pinned'
|
||||
currentValue: boolean
|
||||
propertyCount?: undefined
|
||||
countValue?: undefined
|
||||
type: 'bookmarked' | 'muted' | 'pinned' | 'favourited'
|
||||
}
|
||||
| {
|
||||
property: 'favourited'
|
||||
currentValue: boolean
|
||||
propertyCount: 'favourites_count' | 'reblogs_count'
|
||||
countValue: number
|
||||
}
|
||||
| {
|
||||
property: 'reblogged'
|
||||
currentValue: boolean
|
||||
propertyCount: 'favourites_count' | 'reblogs_count'
|
||||
countValue: number
|
||||
type: 'reblogged'
|
||||
visibility: 'public' | 'unlisted'
|
||||
}
|
||||
| {
|
||||
property: 'poll'
|
||||
id: Mastodon.Poll['id']
|
||||
type: 'vote' | 'refresh'
|
||||
options?: boolean[]
|
||||
data?: Mastodon.Poll
|
||||
type: 'poll'
|
||||
action: 'vote'
|
||||
options: boolean[]
|
||||
}
|
||||
| {
|
||||
type: 'poll'
|
||||
action: 'refresh'
|
||||
}
|
||||
}
|
||||
|
||||
@ -325,10 +313,10 @@ export type MutationVarsTimeline =
|
||||
const mutationFunction = async (params: MutationVarsTimeline) => {
|
||||
switch (params.type) {
|
||||
case 'updateStatusProperty':
|
||||
switch (params.payload.property) {
|
||||
switch (params.payload.type) {
|
||||
case 'poll':
|
||||
const formData = new FormData()
|
||||
params.payload.type === 'vote' &&
|
||||
params.payload.action === 'vote' &&
|
||||
params.payload.options?.forEach((option, index) => {
|
||||
if (option) {
|
||||
formData.append('choices[]', index.toString())
|
||||
@ -336,17 +324,17 @@ const mutationFunction = async (params: MutationVarsTimeline) => {
|
||||
})
|
||||
|
||||
return apiInstance<Mastodon.Poll>({
|
||||
method: params.payload.type === 'vote' ? 'post' : 'get',
|
||||
method: params.payload.action === 'vote' ? 'post' : 'get',
|
||||
url:
|
||||
params.payload.type === 'vote'
|
||||
? `polls/${params.payload.id}/votes`
|
||||
: `polls/${params.payload.id}`,
|
||||
...(params.payload.type === 'vote' && { body: formData })
|
||||
params.payload.action === 'vote'
|
||||
? `polls/${params.status.poll?.id}/votes`
|
||||
: `polls/${params.status.poll?.id}`,
|
||||
...(params.payload.action === 'vote' && { body: formData })
|
||||
})
|
||||
default:
|
||||
let tootId = params.id
|
||||
if (params.fetchRemoteURI) {
|
||||
const fetched = await searchFetchToot(params.fetchRemoteURI)
|
||||
let tootId = params.status.id
|
||||
if (params.status._remote) {
|
||||
const fetched = await searchFetchToot(params.status.uri)
|
||||
if (fetched) {
|
||||
tootId = fetched.id
|
||||
} else {
|
||||
@ -354,15 +342,15 @@ const mutationFunction = async (params: MutationVarsTimeline) => {
|
||||
}
|
||||
}
|
||||
const body = new FormData()
|
||||
if (params.payload.property === 'reblogged') {
|
||||
if (params.payload.type === 'reblogged') {
|
||||
body.append('visibility', params.payload.visibility)
|
||||
}
|
||||
return apiInstance<Mastodon.Status>({
|
||||
method: 'post',
|
||||
url: `statuses/${tootId}/${params.payload.currentValue ? 'un' : ''}${
|
||||
MapPropertyToUrl[params.payload.property]
|
||||
url: `statuses/${tootId}/${params.status[params.payload.type] ? '' : 'un'}${
|
||||
MapPropertyToUrl[params.payload.type]
|
||||
}`,
|
||||
...(params.payload.property === 'reblogged' && { body })
|
||||
...(params.payload.type === 'reblogged' && { body })
|
||||
})
|
||||
}
|
||||
case 'updateAccountProperty':
|
||||
|
@ -1,34 +0,0 @@
|
||||
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
|
||||
if (payload.propertyCount) {
|
||||
if (typeof payload.currentValue === 'boolean' && payload.currentValue) {
|
||||
item.last_status[payload.propertyCount] = payload.countValue - 1
|
||||
} else {
|
||||
item.last_status[payload.propertyCount] = payload.countValue + 1
|
||||
}
|
||||
}
|
||||
}
|
||||
return item
|
||||
}
|
||||
}
|
||||
|
||||
export default updateConversation
|
@ -1,31 +0,0 @@
|
||||
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
|
||||
if (payload.propertyCount) {
|
||||
if (typeof payload.currentValue === 'boolean' && payload.currentValue) {
|
||||
item.status[payload.propertyCount] = payload.countValue - 1
|
||||
} else {
|
||||
item.status[payload.propertyCount] = payload.countValue + 1
|
||||
}
|
||||
}
|
||||
}
|
||||
return item
|
||||
}
|
||||
}
|
||||
|
||||
export default updateNotification
|
@ -1,46 +0,0 @@
|
||||
import { MutationVarsTimelineUpdateStatusProperty } from '@utils/queryHooks/timeline'
|
||||
|
||||
const updateStatus = ({
|
||||
item,
|
||||
isReblog,
|
||||
payload
|
||||
}: {
|
||||
item: Mastodon.Status
|
||||
isReblog?: boolean
|
||||
payload: MutationVarsTimelineUpdateStatusProperty['payload']
|
||||
}) => {
|
||||
switch (payload.property) {
|
||||
case 'poll':
|
||||
if (isReblog) {
|
||||
item.reblog!.poll = payload.data
|
||||
} else {
|
||||
item.poll = payload.data
|
||||
}
|
||||
break
|
||||
default:
|
||||
if (isReblog) {
|
||||
item.reblog![payload.property] =
|
||||
typeof payload.currentValue === 'boolean' ? !payload.currentValue : true
|
||||
if (payload.propertyCount) {
|
||||
if (typeof payload.currentValue === 'boolean' && payload.currentValue) {
|
||||
item.reblog![payload.propertyCount] = payload.countValue - 1
|
||||
} else {
|
||||
item.reblog![payload.propertyCount] = payload.countValue + 1
|
||||
}
|
||||
}
|
||||
} else {
|
||||
item[payload.property] =
|
||||
typeof payload.currentValue === 'boolean' ? !payload.currentValue : true
|
||||
if (payload.propertyCount) {
|
||||
if (typeof payload.currentValue === 'boolean' && payload.currentValue) {
|
||||
item[payload.propertyCount] = payload.countValue - 1
|
||||
} else {
|
||||
item[payload.propertyCount] = payload.countValue + 1
|
||||
}
|
||||
}
|
||||
}
|
||||
return item
|
||||
}
|
||||
}
|
||||
|
||||
export default updateStatus
|
@ -1,103 +1,72 @@
|
||||
import { InfiniteData } from '@tanstack/react-query'
|
||||
import queryClient from '@utils/queryHooks'
|
||||
import { MutationVarsTimelineUpdateStatusProperty, TimelineData } from '../timeline'
|
||||
import updateConversation from './update/conversation'
|
||||
import updateNotification from './update/notification'
|
||||
import updateStatus from './update/status'
|
||||
|
||||
const updateStatusProperty = ({
|
||||
queryKey,
|
||||
rootQueryKey,
|
||||
id,
|
||||
isReblog,
|
||||
payload
|
||||
}: MutationVarsTimelineUpdateStatusProperty) => {
|
||||
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.body as Mastodon.Conversation[])[0].unread === 'boolean') {
|
||||
const items = page.body as Mastodon.Conversation[]
|
||||
const tootIndex = items.findIndex(({ last_status }) => last_status?.id === id)
|
||||
if (tootIndex >= 0) {
|
||||
foundToot = true
|
||||
updateConversation({ item: items[tootIndex], payload })
|
||||
}
|
||||
return page
|
||||
} else if (typeof (page.body as Mastodon.Notification[])[0].type === 'string') {
|
||||
const items = page.body as Mastodon.Notification[]
|
||||
const tootIndex = items.findIndex(({ status }) => status?.id === id)
|
||||
if (tootIndex >= 0) {
|
||||
foundToot = true
|
||||
updateNotification({ item: items[tootIndex], payload })
|
||||
}
|
||||
} else {
|
||||
const items = page.body as Mastodon.Status[]
|
||||
const tootIndex = isReblog
|
||||
? items.findIndex(({ reblog }) => reblog?.id === id)
|
||||
: items.findIndex(toot => toot.id === id)
|
||||
// if favourites page and notifications page, remove the item instead
|
||||
if (tootIndex >= 0) {
|
||||
foundToot = true
|
||||
updateStatus({ item: items[tootIndex], isReblog, payload })
|
||||
}
|
||||
}
|
||||
status,
|
||||
payload,
|
||||
poll
|
||||
}: MutationVarsTimelineUpdateStatusProperty & { poll?: Mastodon.Poll }) => {
|
||||
for (const key of [queryKey, rootQueryKey]) {
|
||||
if (!key) continue
|
||||
|
||||
return page
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
return old
|
||||
})
|
||||
|
||||
rootQueryKey &&
|
||||
queryClient.setQueryData<InfiniteData<TimelineData> | undefined>(rootQueryKey, old => {
|
||||
queryClient.setQueryData<InfiniteData<TimelineData> | undefined>(key, old => {
|
||||
if (old) {
|
||||
let foundToot = false
|
||||
let foundToot: Mastodon.Status | undefined = undefined
|
||||
old.pages = old.pages.map(page => {
|
||||
// Skip rest of the pages if any toot is found
|
||||
if (foundToot) {
|
||||
return page
|
||||
} else {
|
||||
if (typeof (page.body as Mastodon.Conversation[])[0].unread === 'boolean') {
|
||||
const items = page.body as Mastodon.Conversation[]
|
||||
const tootIndex = items.findIndex(({ last_status }) => last_status?.id === id)
|
||||
if (tootIndex >= 0) {
|
||||
foundToot = true
|
||||
updateConversation({ item: items[tootIndex], payload })
|
||||
}
|
||||
foundToot = (page.body as Mastodon.Conversation[]).find(
|
||||
({ last_status }) => last_status?.id === status.id
|
||||
)?.last_status
|
||||
return page
|
||||
} else if (typeof (page.body as Mastodon.Notification[])[0].type === 'string') {
|
||||
const items = page.body as Mastodon.Notification[]
|
||||
const tootIndex = items.findIndex(({ status }) => status?.id === id)
|
||||
if (tootIndex >= 0) {
|
||||
foundToot = true
|
||||
updateNotification({ item: items[tootIndex], payload })
|
||||
}
|
||||
foundToot = (page.body as Mastodon.Notification[]).find(
|
||||
no => no.status?.id === status.id
|
||||
)?.status
|
||||
} else {
|
||||
const items = page.body as Mastodon.Status[]
|
||||
const tootIndex = isReblog
|
||||
? items.findIndex(({ reblog }) => reblog?.id === id)
|
||||
: items.findIndex(toot => toot.id === id)
|
||||
// if favourites page and notifications page, remove the item instead
|
||||
if (tootIndex >= 0) {
|
||||
foundToot = true
|
||||
updateStatus({ item: items[tootIndex], isReblog, payload })
|
||||
}
|
||||
foundToot = (page.body as Mastodon.Status[]).find(toot => toot.id === status.id)
|
||||
}
|
||||
|
||||
return page
|
||||
}
|
||||
})
|
||||
|
||||
if (foundToot) {
|
||||
enum MapPropertyToCount {
|
||||
favourited = 'favourites_count',
|
||||
reblogged = 'reblogs_count'
|
||||
}
|
||||
|
||||
switch (payload.type) {
|
||||
case 'poll':
|
||||
status.poll = poll
|
||||
break
|
||||
default:
|
||||
status[payload.type] =
|
||||
typeof status[payload.type] === 'boolean' ? !status[payload.type] : true
|
||||
switch (payload.type) {
|
||||
case 'favourited':
|
||||
case 'reblogged':
|
||||
if (typeof status[payload.type] === 'boolean' && status[payload.type]) {
|
||||
status[MapPropertyToCount[payload.type]]--
|
||||
} else {
|
||||
status[MapPropertyToCount[payload.type]]++
|
||||
}
|
||||
break
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return old
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
export default updateStatusProperty
|
||||
|
Reference in New Issue
Block a user