1
0
mirror of https://github.com/tooot-app/app synced 2025-06-05 22:19:13 +02:00

Try to fix #16

This commit is contained in:
Zhiyuan Zheng
2021-02-13 01:26:02 +01:00
parent d2aec8d590
commit 4c8003b533
16 changed files with 195 additions and 51 deletions

View File

@ -5,6 +5,7 @@ declare namespace Nav {
| { | {
type: 'status' type: 'status'
queryKey: QueryKeyTimeline queryKey: QueryKeyTimeline
rootQueryKey?: QueryKeyTimeline
status: Mastodon.Status status: Mastodon.Status
} }
| { | {
@ -86,6 +87,7 @@ declare namespace Nav {
'Tab-Shared-Search': undefined 'Tab-Shared-Search': undefined
'Tab-Shared-Toot': { 'Tab-Shared-Toot': {
toot: Mastodon.Status toot: Mastodon.Status
rootQueryKey: any
} }
} }

View File

@ -1,5 +1,5 @@
import ComponentSeparator from '@components/Separator' import ComponentSeparator from '@components/Separator'
import { useScrollToTop } from '@react-navigation/native' import { useNavigation, useScrollToTop } from '@react-navigation/native'
import { QueryKeyTimeline, useTimelineQuery } from '@utils/queryHooks/timeline' import { QueryKeyTimeline, useTimelineQuery } from '@utils/queryHooks/timeline'
import { getLocalActiveIndex } from '@utils/slices/instancesSlice' import { getLocalActiveIndex } from '@utils/slices/instancesSlice'
import { StyleConstants } from '@utils/styles/constants' import { StyleConstants } from '@utils/styles/constants'
@ -27,6 +27,7 @@ export interface Props {
hashtag?: Mastodon.Tag['name'] hashtag?: Mastodon.Tag['name']
list?: Mastodon.List['id'] list?: Mastodon.List['id']
toot?: Mastodon.Status['id'] toot?: Mastodon.Status['id']
rootQueryKey?: QueryKeyTimeline
account?: Mastodon.Account['id'] account?: Mastodon.Account['id']
disableRefresh?: boolean disableRefresh?: boolean
disableInfinity?: boolean disableInfinity?: boolean
@ -38,6 +39,7 @@ const Timeline: React.FC<Props> = ({
hashtag, hashtag,
list, list,
toot, toot,
rootQueryKey,
account, account,
disableRefresh = false, disableRefresh = false,
disableInfinity = false, disableInfinity = false,
@ -108,6 +110,13 @@ const Timeline: React.FC<Props> = ({
350 350
) )
}, []) }, [])
// Auto go back when toot page is empty
const navigation = useNavigation()
useEffect(() => {
if (toot && isSuccess && flattenData.length === 0) {
navigation.goBack()
}
}, [isSuccess, flattenData.length])
const keyExtractor = useCallback(({ id }) => id, []) const keyExtractor = useCallback(({ id }) => id, [])
const renderItem = useCallback( const renderItem = useCallback(
@ -127,6 +136,7 @@ const Timeline: React.FC<Props> = ({
item={item} item={item}
queryKey={queryKey} queryKey={queryKey}
{...(toot === item.id && { highlighted: true })} {...(toot === item.id && { highlighted: true })}
{...(toot && { rootQueryKey })}
// @ts-ignore // @ts-ignore
{...(data?.pages[0].pinned && { pinned: data?.pages[0].pinned })} {...(data?.pages[0].pinned && { pinned: data?.pages[0].pinned })}
/> />

View File

@ -86,7 +86,8 @@ const TimelineConversation: React.FC<Props> = ({
if (conversation.last_status) { if (conversation.last_status) {
conversation.unread && mutate() conversation.unread && mutate()
navigation.push('Tab-Shared-Toot', { navigation.push('Tab-Shared-Toot', {
toot: conversation.last_status toot: conversation.last_status,
rootQueryKey: queryKey
}) })
} }
}, []) }, [])

View File

@ -20,17 +20,19 @@ import { useSelector } from 'react-redux'
export interface Props { export interface Props {
item: Mastodon.Status & { isPinned?: boolean } item: Mastodon.Status & { isPinned?: boolean }
queryKey?: QueryKeyTimeline queryKey?: QueryKeyTimeline
rootQueryKey?: QueryKeyTimeline
origin?: string origin?: string
highlighted?: boolean highlighted?: boolean
disableDetails?: boolean disableDetails?: boolean
disableOnPress?: boolean disableOnPress?: boolean
pinned: Mastodon.Status['id'][] pinned?: Mastodon.Status['id'][]
} }
// When the poll is long // When the poll is long
const TimelineDefault: React.FC<Props> = ({ const TimelineDefault: React.FC<Props> = ({
item, item,
queryKey, queryKey,
rootQueryKey,
origin, origin,
highlighted = false, highlighted = false,
disableDetails = false, disableDetails = false,
@ -55,7 +57,8 @@ const TimelineDefault: React.FC<Props> = ({
!disableOnPress && !disableOnPress &&
!highlighted && !highlighted &&
navigation.push('Tab-Shared-Toot', { navigation.push('Tab-Shared-Toot', {
toot: actualStatus toot: actualStatus,
rootQueryKey: queryKey
}) })
}, []) }, [])
@ -72,6 +75,7 @@ const TimelineDefault: React.FC<Props> = ({
} }
]} ]}
onPress={onPress} onPress={onPress}
disabled={queryKey && queryKey[1].toot !== undefined}
> >
{item.reblog ? ( {item.reblog ? (
<TimelineActioned action='reblog' account={item.account} /> <TimelineActioned action='reblog' account={item.account} />
@ -86,6 +90,7 @@ const TimelineDefault: React.FC<Props> = ({
/> />
<TimelineHeaderDefault <TimelineHeaderDefault
queryKey={disableOnPress ? undefined : queryKey} queryKey={disableOnPress ? undefined : queryKey}
rootQueryKey={disableOnPress ? undefined : rootQueryKey}
status={actualStatus} status={actualStatus}
/> />
</View> </View>
@ -109,6 +114,7 @@ const TimelineDefault: React.FC<Props> = ({
{queryKey && actualStatus.poll ? ( {queryKey && actualStatus.poll ? (
<TimelinePoll <TimelinePoll
queryKey={queryKey} queryKey={queryKey}
rootQueryKey={rootQueryKey}
statusId={actualStatus.id} statusId={actualStatus.id}
poll={actualStatus.poll} poll={actualStatus.poll}
reblog={item.reblog ? true : false} reblog={item.reblog ? true : false}
@ -135,6 +141,7 @@ const TimelineDefault: React.FC<Props> = ({
> >
<TimelineActions <TimelineActions
queryKey={queryKey} queryKey={queryKey}
rootQueryKey={rootQueryKey}
status={actualStatus} status={actualStatus}
accts={([actualStatus.account] as Mastodon.Account[] & accts={([actualStatus.account] as Mastodon.Account[] &
Mastodon.Mention[]) Mastodon.Mention[])

View File

@ -44,7 +44,8 @@ const TimelineNotifications: React.FC<Props> = ({
analytics('timeline_notification_press') analytics('timeline_notification_press')
notification.status && notification.status &&
navigation.push('Tab-Shared-Toot', { navigation.push('Tab-Shared-Toot', {
toot: notification.status toot: notification.status,
rootQueryKey: queryKey
}) })
}, []) }, [])

View File

@ -17,6 +17,7 @@ import { useQueryClient } from 'react-query'
export interface Props { export interface Props {
queryKey: QueryKeyTimeline queryKey: QueryKeyTimeline
rootQueryKey?: QueryKeyTimeline
status: Mastodon.Status status: Mastodon.Status
accts: Mastodon.Account['acct'][] // When replying to conversations accts: Mastodon.Account['acct'][] // When replying to conversations
reblog: boolean reblog: boolean
@ -24,6 +25,7 @@ export interface Props {
const TimelineActions: React.FC<Props> = ({ const TimelineActions: React.FC<Props> = ({
queryKey, queryKey,
rootQueryKey,
status, status,
accts, accts,
reblog reblog
@ -120,6 +122,7 @@ const TimelineActions: React.FC<Props> = ({
mutation.mutate({ mutation.mutate({
type: 'updateStatusProperty', type: 'updateStatusProperty',
queryKey, queryKey,
rootQueryKey,
id: status.id, id: status.id,
reblog, reblog,
payload: { payload: {
@ -139,6 +142,7 @@ const TimelineActions: React.FC<Props> = ({
mutation.mutate({ mutation.mutate({
type: 'updateStatusProperty', type: 'updateStatusProperty',
queryKey, queryKey,
rootQueryKey,
id: status.id, id: status.id,
reblog, reblog,
payload: { payload: {
@ -157,6 +161,7 @@ const TimelineActions: React.FC<Props> = ({
mutation.mutate({ mutation.mutate({
type: 'updateStatusProperty', type: 'updateStatusProperty',
queryKey, queryKey,
rootQueryKey,
id: status.id, id: status.id,
reblog, reblog,
payload: { payload: {

View File

@ -1,22 +1,27 @@
import Icon from '@components/Icon'
import { useNavigation } from '@react-navigation/native'
import { QueryKeyTimeline } from '@utils/queryHooks/timeline'
import { StyleConstants } from '@utils/styles/constants' import { StyleConstants } from '@utils/styles/constants'
import { useTheme } from '@utils/styles/ThemeManager'
import React from 'react' import React from 'react'
import { Pressable, StyleSheet, View } from 'react-native' import { Pressable, StyleSheet, View } from 'react-native'
import HeaderSharedAccount from './HeaderShared/Account' import HeaderSharedAccount from './HeaderShared/Account'
import HeaderSharedApplication from './HeaderShared/Application' import HeaderSharedApplication from './HeaderShared/Application'
import HeaderSharedCreated from './HeaderShared/Created' import HeaderSharedCreated from './HeaderShared/Created'
import HeaderSharedVisibility from './HeaderShared/Visibility'
import { QueryKeyTimeline } from '@utils/queryHooks/timeline'
import HeaderSharedMuted from './HeaderShared/Muted' import HeaderSharedMuted from './HeaderShared/Muted'
import { useNavigation } from '@react-navigation/native' import HeaderSharedVisibility from './HeaderShared/Visibility'
import Icon from '@components/Icon'
import { useTheme } from '@utils/styles/ThemeManager'
export interface Props { export interface Props {
queryKey?: QueryKeyTimeline queryKey?: QueryKeyTimeline
rootQueryKey?: QueryKeyTimeline
status: Mastodon.Status status: Mastodon.Status
} }
const TimelineHeaderDefault: React.FC<Props> = ({ queryKey, status }) => { const TimelineHeaderDefault: React.FC<Props> = ({
queryKey,
rootQueryKey,
status
}) => {
const navigation = useNavigation() const navigation = useNavigation()
const { theme } = useTheme() const { theme } = useTheme()
@ -38,6 +43,7 @@ const TimelineHeaderDefault: React.FC<Props> = ({ queryKey, status }) => {
onPress={() => onPress={() =>
navigation.navigate('Screen-Actions', { navigation.navigate('Screen-Actions', {
queryKey, queryKey,
rootQueryKey,
status, status,
url: status.url || status.uri, url: status.url || status.uri,
type: 'status' type: 'status'

View File

@ -10,6 +10,7 @@ import {
QueryKeyTimeline, QueryKeyTimeline,
useTimelineMutation useTimelineMutation
} from '@utils/queryHooks/timeline' } from '@utils/queryHooks/timeline'
import updateStatusProperty from '@utils/queryHooks/timeline/updateStatusProperty'
import { StyleConstants } from '@utils/styles/constants' import { StyleConstants } from '@utils/styles/constants'
import { useTheme } from '@utils/styles/ThemeManager' import { useTheme } from '@utils/styles/ThemeManager'
import { maxBy } from 'lodash' import { maxBy } from 'lodash'
@ -20,6 +21,7 @@ import { useQueryClient } from 'react-query'
export interface Props { export interface Props {
queryKey: QueryKeyTimeline queryKey: QueryKeyTimeline
rootQueryKey?: QueryKeyTimeline
statusId: Mastodon.Status['id'] statusId: Mastodon.Status['id']
poll: NonNullable<Mastodon.Status['poll']> poll: NonNullable<Mastodon.Status['poll']>
reblog: boolean reblog: boolean
@ -28,6 +30,7 @@ export interface Props {
const TimelinePoll: React.FC<Props> = ({ const TimelinePoll: React.FC<Props> = ({
queryKey, queryKey,
rootQueryKey,
statusId, statusId,
poll, poll,
reblog, reblog,
@ -43,7 +46,19 @@ const TimelinePoll: React.FC<Props> = ({
const queryClient = useQueryClient() const queryClient = useQueryClient()
const mutation = useTimelineMutation({ const mutation = useTimelineMutation({
queryClient, queryClient,
onSuccess: true, onSuccess: ({ body }, params) => {
const theParams = params as MutationVarsTimelineUpdateStatusProperty
queryClient.cancelQueries(queryKey)
rootQueryKey && queryClient.cancelQueries(rootQueryKey)
haptics('Success')
switch (theParams.payload.property) {
case 'poll':
theParams.payload.data = (body as unknown) as Mastodon.Poll
updateStatusProperty({ queryClient, ...theParams })
break
}
},
onError: (err: any, params) => { onError: (err: any, params) => {
const theParams = params as MutationVarsTimelineUpdateStatusProperty const theParams = params as MutationVarsTimelineUpdateStatusProperty
haptics('Error') haptics('Error')
@ -76,6 +91,7 @@ const TimelinePoll: React.FC<Props> = ({
mutation.mutate({ mutation.mutate({
type: 'updateStatusProperty', type: 'updateStatusProperty',
queryKey, queryKey,
rootQueryKey,
id: statusId, id: statusId,
reblog, reblog,
payload: { payload: {
@ -102,6 +118,7 @@ const TimelinePoll: React.FC<Props> = ({
mutation.mutate({ mutation.mutate({
type: 'updateStatusProperty', type: 'updateStatusProperty',
queryKey, queryKey,
rootQueryKey,
id: statusId, id: statusId,
reblog, reblog,
payload: { payload: {

View File

@ -13,11 +13,17 @@ import { useQueryClient } from 'react-query'
export interface Props { export interface Props {
queryKey?: QueryKeyTimeline queryKey?: QueryKeyTimeline
rootQueryKey?: QueryKeyTimeline
account: Mastodon.Account account: Mastodon.Account
dismiss: () => void dismiss: () => void
} }
const ActionsAccount: React.FC<Props> = ({ queryKey, account, dismiss }) => { const ActionsAccount: React.FC<Props> = ({
queryKey,
rootQueryKey,
account,
dismiss
}) => {
const { t } = useTranslation('componentTimeline') const { t } = useTranslation('componentTimeline')
const queryClient = useQueryClient() const queryClient = useQueryClient()
@ -59,6 +65,7 @@ const ActionsAccount: React.FC<Props> = ({ queryKey, account, dismiss }) => {
}, },
onSettled: () => { onSettled: () => {
queryKey && queryClient.invalidateQueries(queryKey) queryKey && queryClient.invalidateQueries(queryKey)
rootQueryKey && queryClient.invalidateQueries(rootQueryKey)
} }
}) })

View File

@ -14,11 +14,17 @@ import { useQueryClient } from 'react-query'
export interface Props { export interface Props {
queryKey: QueryKeyTimeline queryKey: QueryKeyTimeline
rootQueryKey?: QueryKeyTimeline
domain: string domain: string
dismiss: () => void dismiss: () => void
} }
const ActionsDomain: React.FC<Props> = ({ queryKey, domain, dismiss }) => { const ActionsDomain: React.FC<Props> = ({
queryKey,
rootQueryKey,
domain,
dismiss
}) => {
const { t } = useTranslation('componentTimeline') const { t } = useTranslation('componentTimeline')
const queryClient = useQueryClient() const queryClient = useQueryClient()
const mutation = useTimelineMutation({ const mutation = useTimelineMutation({
@ -31,6 +37,7 @@ const ActionsDomain: React.FC<Props> = ({ queryKey, domain, dismiss }) => {
}) })
}) })
queryClient.invalidateQueries(queryKey) queryClient.invalidateQueries(queryKey)
rootQueryKey && queryClient.invalidateQueries(rootQueryKey)
} }
}) })

View File

@ -107,6 +107,7 @@ const ScreenActionsRoot = React.memo(
{!sameAccount && ( {!sameAccount && (
<ActionsAccount <ActionsAccount
queryKey={params.queryKey} queryKey={params.queryKey}
rootQueryKey={params.rootQueryKey}
account={params.status.account} account={params.status.account}
dismiss={dismiss} dismiss={dismiss}
/> />
@ -115,6 +116,7 @@ const ScreenActionsRoot = React.memo(
<ActionsStatus <ActionsStatus
navigation={navigation} navigation={navigation}
queryKey={params.queryKey} queryKey={params.queryKey}
rootQueryKey={params.rootQueryKey}
status={params.status} status={params.status}
dismiss={dismiss} dismiss={dismiss}
/> />
@ -122,6 +124,7 @@ const ScreenActionsRoot = React.memo(
{!sameDomain && statusDomain && ( {!sameDomain && statusDomain && (
<ActionsDomain <ActionsDomain
queryKey={params.queryKey} queryKey={params.queryKey}
rootQueryKey={params.rootQueryKey}
domain={statusDomain} domain={statusDomain}
dismiss={dismiss} dismiss={dismiss}
/> />

View File

@ -11,10 +11,12 @@ import {
} from '@utils/queryHooks/timeline' } from '@utils/queryHooks/timeline'
import analytics from '@components/analytics' import analytics from '@components/analytics'
import { StackNavigationProp } from '@react-navigation/stack' import { StackNavigationProp } from '@react-navigation/stack'
import deleteItem from '@utils/queryHooks/timeline/deleteItem'
export interface Props { export interface Props {
navigation: StackNavigationProp<Nav.RootStackParamList, 'Screen-Actions'> navigation: StackNavigationProp<Nav.RootStackParamList, 'Screen-Actions'>
queryKey: QueryKeyTimeline queryKey: QueryKeyTimeline
rootQueryKey?: QueryKeyTimeline
status: Mastodon.Status status: Mastodon.Status
dismiss: () => void dismiss: () => void
} }
@ -22,6 +24,7 @@ export interface Props {
const ActionsStatus: React.FC<Props> = ({ const ActionsStatus: React.FC<Props> = ({
navigation, navigation,
queryKey, queryKey,
rootQueryKey,
status, status,
dismiss dismiss
}) => { }) => {
@ -66,6 +69,7 @@ const ActionsStatus: React.FC<Props> = ({
type: 'deleteItem', type: 'deleteItem',
source: 'statuses', source: 'statuses',
queryKey, queryKey,
rootQueryKey,
id: status.id id: status.id
}) })
}} }}
@ -106,6 +110,11 @@ const ActionsStatus: React.FC<Props> = ({
queryKey, queryKey,
id: status.id id: status.id
}) })
deleteItem({
queryClient,
rootQueryKey,
id: status.id
})
if (res.body.id) { if (res.body.id) {
// @ts-ignore // @ts-ignore
navigation.navigate('Screen-Compose', { navigation.navigate('Screen-Compose', {
@ -131,6 +140,7 @@ const ActionsStatus: React.FC<Props> = ({
mutation.mutate({ mutation.mutate({
type: 'updateStatusProperty', type: 'updateStatusProperty',
queryKey, queryKey,
rootQueryKey,
id: status.id, id: status.id,
payload: { payload: {
property: 'muted', property: 'muted',
@ -158,6 +168,7 @@ const ActionsStatus: React.FC<Props> = ({
mutation.mutate({ mutation.mutate({
type: 'updateStatusProperty', type: 'updateStatusProperty',
queryKey, queryKey,
rootQueryKey,
id: status.id, id: status.id,
payload: { payload: {
property: 'pinned', property: 'pinned',

View File

@ -4,10 +4,18 @@ import { SharedTootProp } from './sharedScreens'
const TabSharedToot: React.FC<SharedTootProp> = ({ const TabSharedToot: React.FC<SharedTootProp> = ({
route: { route: {
params: { toot } params: { toot, rootQueryKey }
} }
}) => { }) => {
return <Timeline page='Toot' toot={toot.id} disableRefresh disableInfinity /> return (
<Timeline
page='Toot'
toot={toot.id}
rootQueryKey={rootQueryKey}
disableRefresh
disableInfinity
/>
)
} }
export default TabSharedToot export default TabSharedToot

View File

@ -226,6 +226,7 @@ export type MutationVarsTimelineUpdateStatusProperty = {
// This is status in general, including "status" inside conversation and notification // This is status in general, including "status" inside conversation and notification
type: 'updateStatusProperty' type: 'updateStatusProperty'
queryKey: QueryKeyTimeline queryKey: QueryKeyTimeline
rootQueryKey?: QueryKeyTimeline
id: Mastodon.Status['id'] | Mastodon.Poll['id'] id: Mastodon.Status['id'] | Mastodon.Poll['id']
reblog?: boolean reblog?: boolean
payload: payload:
@ -264,7 +265,8 @@ export type MutationVarsTimelineDeleteItem = {
// This is for deleting status and conversation // This is for deleting status and conversation
type: 'deleteItem' type: 'deleteItem'
source: 'statuses' | 'conversations' source: 'statuses' | 'conversations'
queryKey: QueryKeyTimeline queryKey?: QueryKeyTimeline
rootQueryKey?: QueryKeyTimeline
id: Mastodon.Conversation['id'] id: Mastodon.Conversation['id']
} }
@ -366,7 +368,7 @@ const useTimelineMutation = ({
onError?: MutationOptionsTimeline['onError'] onError?: MutationOptionsTimeline['onError']
onMutate?: boolean onMutate?: boolean
onSettled?: MutationOptionsTimeline['onSettled'] onSettled?: MutationOptionsTimeline['onSettled']
onSuccess?: MutationOptionsTimeline['onSuccess'] | boolean onSuccess?: MutationOptionsTimeline['onSuccess']
}) => { }) => {
return useMutation< return useMutation<
{ body: Mastodon.Conversation | Mastodon.Notification | Mastodon.Status }, { body: Mastodon.Conversation | Mastodon.Notification | Mastodon.Status },
@ -375,27 +377,7 @@ const useTimelineMutation = ({
>(mutationFunction, { >(mutationFunction, {
onError, onError,
onSettled, onSettled,
...(typeof onSuccess === 'function' onSuccess,
? { onSuccess }
: onSuccess
? {
onSuccess: ({ body }, params) => {
queryClient.cancelQueries(params.queryKey)
haptics('Success')
switch (params.type) {
case 'updateStatusProperty':
switch (params.payload.property) {
case 'poll':
params.payload.data = (body as unknown) as Mastodon.Poll
updateStatusProperty({ queryClient, ...params })
break
}
break
}
}
}
: undefined),
...(onMutate && { ...(onMutate && {
onMutate: params => { onMutate: params => {
queryClient.cancelQueries(params.queryKey) queryClient.cancelQueries(params.queryKey)

View File

@ -1,24 +1,45 @@
import { InfiniteData, QueryClient } from 'react-query' import { InfiniteData, QueryClient } from 'react-query'
import { QueryKeyTimeline, TimelineData } from '../timeline' import { MutationVarsTimelineDeleteItem } from '../timeline'
const deleteItem = ({ const deleteItem = ({
queryClient, queryClient,
queryKey, queryKey,
rootQueryKey,
id id
}: { }: {
queryClient: QueryClient queryClient: QueryClient
queryKey: QueryKeyTimeline queryKey?: MutationVarsTimelineDeleteItem['queryKey']
id: Mastodon.Status['id'] rootQueryKey?: MutationVarsTimelineDeleteItem['rootQueryKey']
id: MutationVarsTimelineDeleteItem['id']
}) => { }) => {
queryClient.setQueryData<InfiniteData<any> | undefined>(queryKey, old => { queryKey &&
if (old) { queryClient.setQueryData<InfiniteData<any> | undefined>(queryKey, old => {
old.pages = old.pages.map(page => { if (old) {
page.body = page.body.filter((item: Mastodon.Status) => item.id !== id) old.pages = old.pages.map(page => {
return page page.body = page.body.filter(
}) (item: Mastodon.Status) => item.id !== id
return old )
} return page
}) })
return old
}
})
rootQueryKey &&
queryClient.setQueryData<InfiniteData<any> | undefined>(
rootQueryKey,
old => {
if (old) {
old.pages = old.pages.map(page => {
page.body = page.body.filter(
(item: Mastodon.Status) => item.id !== id
)
return page
})
return old
}
}
)
} }
export default deleteItem export default deleteItem

View File

@ -11,12 +11,14 @@ import updateStatus from './update/status'
const updateStatusProperty = ({ const updateStatusProperty = ({
queryClient, queryClient,
queryKey, queryKey,
rootQueryKey,
id, id,
reblog, reblog,
payload payload
}: { }: {
queryClient: QueryClient queryClient: QueryClient
queryKey: MutationVarsTimelineUpdateStatusProperty['queryKey'] queryKey: MutationVarsTimelineUpdateStatusProperty['queryKey']
rootQueryKey?: MutationVarsTimelineUpdateStatusProperty['rootQueryKey']
id: MutationVarsTimelineUpdateStatusProperty['id'] id: MutationVarsTimelineUpdateStatusProperty['id']
reblog?: MutationVarsTimelineUpdateStatusProperty['reblog'] reblog?: MutationVarsTimelineUpdateStatusProperty['reblog']
payload: MutationVarsTimelineUpdateStatusProperty['payload'] payload: MutationVarsTimelineUpdateStatusProperty['payload']
@ -72,6 +74,60 @@ const updateStatusProperty = ({
return old return old
} }
) )
rootQueryKey &&
queryClient.setQueryData<InfiniteData<TimelineData> | undefined>(
rootQueryKey,
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 = findIndex(items, ['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 = findIndex(items, ['status.id', id])
if (tootIndex >= 0) {
foundToot = true
updateNotification({ item: items[tootIndex], payload })
}
} else {
const items = page.body 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 export default updateStatusProperty