mirror of
https://github.com/tooot-app/app
synced 2025-06-05 22:19:13 +02:00
Continue refine remote logic #638
This commit is contained in:
@ -1,62 +1,69 @@
|
||||
import { getAccountStorage } from '@utils/storage/actions'
|
||||
import parse from 'url-parse'
|
||||
|
||||
const getHost = (url: unknown): string | undefined | null => {
|
||||
if (typeof url !== 'string') return undefined
|
||||
|
||||
const matches = url.match(/^(?:https?:\/\/)?(?:[^@\/\n]+@)?(?:www\.)?([^:\/\n]+)/i)
|
||||
return matches?.[1]
|
||||
}
|
||||
|
||||
const matchStatus = (
|
||||
url: string
|
||||
): { id: string; style: 'default' | 'pretty'; sameInstance: boolean } | null => {
|
||||
// https://social.xmflsct.com/web/statuses/105590085754428765 <- default
|
||||
// https://social.xmflsct.com/@tooot/105590085754428765 <- pretty
|
||||
const matcherStatus = new RegExp(/(https?:\/\/)?([^\/]+)\/(web\/statuses|@.+)\/([0-9]+)/)
|
||||
|
||||
const matched = url.match(matcherStatus)
|
||||
if (matched) {
|
||||
const hostname = matched[2]
|
||||
const style = matched[3] === 'web/statuses' ? 'default' : 'pretty'
|
||||
const id = matched[4]
|
||||
|
||||
const sameInstance = hostname === getAccountStorage.string('auth.domain')
|
||||
return { id, style, sameInstance }
|
||||
}
|
||||
|
||||
return null
|
||||
}
|
||||
|
||||
const matchAccount = (
|
||||
export const urlMatcher = (
|
||||
url: string
|
||||
):
|
||||
| { id: string; style: 'default'; sameInstance: boolean }
|
||||
| { username: string; style: 'pretty'; sameInstance: boolean }
|
||||
| null => {
|
||||
// https://social.xmflsct.com/web/accounts/14195 <- default
|
||||
// https://social.xmflsct.com/web/@tooot <- pretty ! cannot be searched on the same instance
|
||||
// https://social.xmflsct.com/@tooot <- pretty
|
||||
const matcherAccount = new RegExp(
|
||||
/(https?:\/\/)?([^\/]+)(\/web\/accounts\/([0-9]+)|\/web\/(@.+)|\/(@.+))/
|
||||
)
|
||||
|
||||
const matched = url.match(matcherAccount)
|
||||
if (matched) {
|
||||
const hostname = matched[2]
|
||||
const account = matched.filter(i => i).reverse()?.[0]
|
||||
if (account) {
|
||||
const style = account.startsWith('@') ? 'pretty' : 'default'
|
||||
|
||||
const sameInstance = hostname === getAccountStorage.string('auth.domain')
|
||||
return style === 'default'
|
||||
? { id: account, style, sameInstance }
|
||||
: { username: account, style, sameInstance }
|
||||
} else {
|
||||
return null
|
||||
| {
|
||||
domain: string
|
||||
account?: Partial<Pick<Mastodon.Account, 'id' | 'acct' | '_remote'>>
|
||||
status?: Partial<Pick<Mastodon.Status, 'id' | '_remote'>>
|
||||
}
|
||||
| undefined => {
|
||||
const parsed = parse(url)
|
||||
if (!parsed.hostname.length || !parsed.pathname.length) return undefined
|
||||
|
||||
const domain = parsed.hostname
|
||||
const _remote = parsed.hostname !== getAccountStorage.string('auth.domain')
|
||||
|
||||
let statusId: string | undefined
|
||||
let accountId: string | undefined
|
||||
let accountAcct: string | undefined
|
||||
|
||||
const segments = parsed.pathname.split('/')
|
||||
const last = segments[segments.length - 1]
|
||||
const length = segments.length // there is a starting slash
|
||||
|
||||
switch (last?.startsWith('@')) {
|
||||
case true:
|
||||
if (length === 2 || (length === 3 && segments[length - 2] === 'web')) {
|
||||
// https://social.xmflsct.com/@tooot <- Mastodon v4.0 and above
|
||||
// https://social.xmflsct.com/web/@tooot <- Mastodon v3.5 and below ! cannot be searched on the same instance
|
||||
accountAcct = `${last}@${domain}`
|
||||
}
|
||||
break
|
||||
case false:
|
||||
const nextToLast = segments[length - 2]
|
||||
if (nextToLast) {
|
||||
if (nextToLast === 'statuses') {
|
||||
if (length === 4 && segments[length - 3] === 'web') {
|
||||
// https://social.xmflsct.com/web/statuses/105590085754428765 <- old
|
||||
statusId = last
|
||||
} else if (
|
||||
length === 5 &&
|
||||
segments[length - 2] === 'statuses' &&
|
||||
segments[length - 4] === 'users'
|
||||
) {
|
||||
// https://social.xmflsct.com/users/tooot/statuses/105590085754428765 <- default Mastodon
|
||||
statusId = last
|
||||
// accountAcct = `@${segments[length - 3]}@${domain}`
|
||||
}
|
||||
} else if (
|
||||
nextToLast.startsWith('@') &&
|
||||
(length === 3 || (length === 4 && segments[length - 3] === 'web'))
|
||||
) {
|
||||
// https://social.xmflsct.com/web/@tooot/105590085754428765 <- pretty Mastodon v3.5 and below
|
||||
// https://social.xmflsct.com/@tooot/105590085754428765 <- pretty Mastodon v4.0 and above
|
||||
statusId = last
|
||||
// accountAcct = `${nextToLast}@${domain}`
|
||||
}
|
||||
}
|
||||
break
|
||||
}
|
||||
|
||||
return null
|
||||
return {
|
||||
domain,
|
||||
...((accountId || accountAcct) && { account: { id: accountId, acct: accountAcct, _remote } }),
|
||||
...(statusId && { status: { id: statusId, _remote } })
|
||||
}
|
||||
}
|
||||
|
||||
export { getHost, matchStatus, matchAccount }
|
||||
|
@ -94,7 +94,7 @@ export type TabSharedStackParamList = {
|
||||
hashtag: Mastodon.Tag['name']
|
||||
}
|
||||
'Tab-Shared-History': {
|
||||
id: Mastodon.Status['id']
|
||||
status: Mastodon.Status
|
||||
detectedLanguage: string
|
||||
}
|
||||
'Tab-Shared-Report': {
|
||||
|
@ -5,7 +5,7 @@ import {
|
||||
PERMISSION_MANAGE_REPORTS,
|
||||
PERMISSION_MANAGE_USERS
|
||||
} from '@utils/helpers/permissions'
|
||||
import queryClient from '@utils/queryHooks'
|
||||
import { queryClient } from '@utils/queryHooks'
|
||||
import { QueryKeyProfile } from '@utils/queryHooks/profile'
|
||||
import { getAccountDetails, getGlobalStorage } from '@utils/storage/actions'
|
||||
import * as Notifications from 'expo-notifications'
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { displayMessage } from '@components/Message'
|
||||
import queryClient from '@utils/queryHooks'
|
||||
import { queryClient } from '@utils/queryHooks'
|
||||
import { QueryKeyTimeline } from '@utils/queryHooks/timeline'
|
||||
import { generateAccountKey, setAccount, useGlobalStorage } from '@utils/storage/actions'
|
||||
import * as Notifications from 'expo-notifications'
|
||||
|
@ -1,4 +1,4 @@
|
||||
import queryClient from '@utils/queryHooks'
|
||||
import { queryClient } from '@utils/queryHooks'
|
||||
import { QueryKeyTimeline } from '@utils/queryHooks/timeline'
|
||||
import { generateAccountKey, setAccount, useGlobalStorage } from '@utils/storage/actions'
|
||||
import * as Notifications from 'expo-notifications'
|
||||
|
@ -1,68 +1,89 @@
|
||||
import { QueryFunctionContext, useQuery, UseQueryOptions } from '@tanstack/react-query'
|
||||
import apiGeneral from '@utils/api/general'
|
||||
import apiInstance from '@utils/api/instance'
|
||||
import { urlMatcher } from '@utils/helpers/urlMatcher'
|
||||
import { AxiosError } from 'axios'
|
||||
import { SearchResult } from './search'
|
||||
import { searchLocalAccount } from './search'
|
||||
|
||||
export type QueryKeyAccount = [
|
||||
'Account',
|
||||
Pick<Mastodon.Account, 'id' | 'url' | '_remote'> | undefined
|
||||
(
|
||||
| (Partial<Pick<Mastodon.Account, 'id' | 'acct' | 'username' | '_remote'>> &
|
||||
Pick<Mastodon.Account, 'url'> & { _local?: boolean })
|
||||
| undefined
|
||||
)
|
||||
]
|
||||
|
||||
const accountQueryFunction = async ({ queryKey }: QueryFunctionContext<QueryKeyAccount>) => {
|
||||
const key = queryKey[1]
|
||||
if (!key) return Promise.reject()
|
||||
|
||||
let matchedId = key.id
|
||||
let matchedAccount: Mastodon.Account | undefined = undefined
|
||||
|
||||
if (key._remote) {
|
||||
await apiInstance<SearchResult>({
|
||||
version: 'v2',
|
||||
method: 'get',
|
||||
url: 'search',
|
||||
params: {
|
||||
q: key.url,
|
||||
type: 'accounts',
|
||||
limit: 1,
|
||||
resolve: true
|
||||
}
|
||||
})
|
||||
.then(res => {
|
||||
const account = res.body.accounts[0]
|
||||
if (account.url !== key.url) {
|
||||
return Promise.reject()
|
||||
} else {
|
||||
matchedId = account.id
|
||||
}
|
||||
})
|
||||
.catch(() => Promise.reject())
|
||||
}
|
||||
const match = urlMatcher(key.url)
|
||||
|
||||
const res = await apiInstance<Mastodon.Account>({
|
||||
method: 'get',
|
||||
url: `accounts/${matchedId}`
|
||||
})
|
||||
return res.body
|
||||
const domain = match?.domain
|
||||
const id = key.id || match?.account?.id
|
||||
const acct = key.acct || key.username || match?.account?.acct
|
||||
|
||||
if (!key._local && domain) {
|
||||
try {
|
||||
if (id) {
|
||||
matchedAccount = await apiGeneral<Mastodon.Account>({
|
||||
method: 'get',
|
||||
domain: domain,
|
||||
url: `api/v1/accounts/${id}`
|
||||
}).then(res => ({ ...res.body, _remote: true }))
|
||||
} else if (acct) {
|
||||
matchedAccount = await apiGeneral<Mastodon.Account>({
|
||||
method: 'get',
|
||||
domain: domain,
|
||||
url: 'api/v1/accounts/lookup',
|
||||
params: { acct }
|
||||
}).then(res => ({ ...res.body, _remote: true }))
|
||||
}
|
||||
} catch {}
|
||||
}
|
||||
|
||||
if (!matchedAccount) {
|
||||
matchedAccount = await searchLocalAccount(key.url)
|
||||
}
|
||||
} else {
|
||||
if (!matchedAccount) {
|
||||
matchedAccount = await apiInstance<Mastodon.Account>({
|
||||
method: 'get',
|
||||
url: `accounts/${key.id}`
|
||||
}).then(res => res.body)
|
||||
}
|
||||
}
|
||||
return matchedAccount
|
||||
}
|
||||
|
||||
const useAccountQuery = ({
|
||||
options,
|
||||
...queryKeyParams
|
||||
}: { account?: QueryKeyAccount[1] } & {
|
||||
account,
|
||||
_local,
|
||||
options
|
||||
}: {
|
||||
account?: QueryKeyAccount[1]
|
||||
_local?: boolean
|
||||
options?: UseQueryOptions<Mastodon.Account, AxiosError>
|
||||
}) => {
|
||||
const queryKey: QueryKeyAccount = [
|
||||
'Account',
|
||||
queryKeyParams.account
|
||||
account
|
||||
? {
|
||||
id: queryKeyParams.account.id,
|
||||
url: queryKeyParams.account.url,
|
||||
_remote: queryKeyParams.account._remote
|
||||
id: account.id,
|
||||
username: account.username,
|
||||
url: account.url,
|
||||
_remote: account._remote,
|
||||
...(_local && { _local })
|
||||
}
|
||||
: undefined
|
||||
]
|
||||
return useQuery(queryKey, accountQueryFunction, {
|
||||
...options,
|
||||
enabled: (queryKeyParams.account?._remote ? !!queryKeyParams.account : true) && options?.enabled
|
||||
enabled: (account?._remote ? !!account : true) && options?.enabled
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { QueryClient } from '@tanstack/react-query'
|
||||
|
||||
const queryClient = new QueryClient({
|
||||
export const queryClient = new QueryClient({
|
||||
defaultOptions: {
|
||||
queries: {
|
||||
staleTime: 1000 * 60 * 5,
|
||||
@ -15,12 +15,10 @@ const queryClient = new QueryClient({
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
logger: {
|
||||
log: log => console.log(log),
|
||||
warn: () => {},
|
||||
error: () => {}
|
||||
}
|
||||
})
|
||||
|
||||
// @ts-ignore
|
||||
import('react-query-native-devtools').then(({ addPlugin }) => {
|
||||
addPlugin({ queryClient })
|
||||
})
|
||||
|
||||
export default queryClient
|
||||
|
@ -2,7 +2,7 @@ import haptics from '@components/haptics'
|
||||
import { displayMessage } from '@components/Message'
|
||||
import { useMutation, useQuery, UseQueryOptions } from '@tanstack/react-query'
|
||||
import apiInstance from '@utils/api/instance'
|
||||
import queryClient from '@utils/queryHooks'
|
||||
import { queryClient } from '@utils/queryHooks'
|
||||
import { AxiosError } from 'axios'
|
||||
import i18next from 'i18next'
|
||||
import { RefObject } from 'react'
|
||||
|
@ -1,5 +1,6 @@
|
||||
import { QueryFunctionContext, useQuery, UseQueryOptions } from '@tanstack/react-query'
|
||||
import apiInstance from '@utils/api/instance'
|
||||
import { queryClient } from '@utils/queryHooks'
|
||||
import { AxiosError } from 'axios'
|
||||
|
||||
export type QueryKeySearch = [
|
||||
@ -43,22 +44,27 @@ const useSearchQuery = <T = SearchResult>({
|
||||
options?: UseQueryOptions<SearchResult, AxiosError, T>
|
||||
}) => {
|
||||
const queryKey: QueryKeySearch = ['Search', { ...queryKeyParams }]
|
||||
return useQuery(queryKey, queryFunction, options)
|
||||
return useQuery(queryKey, queryFunction, { ...options, staleTime: 3600, cacheTime: 3600 })
|
||||
}
|
||||
|
||||
export const searchFetchToot = (uri: Mastodon.Status['uri']): Promise<Mastodon.Status | void> =>
|
||||
apiInstance<SearchResult>({
|
||||
version: 'v2',
|
||||
method: 'get',
|
||||
url: 'search',
|
||||
params: {
|
||||
q: uri,
|
||||
type: 'statuses',
|
||||
limit: 1,
|
||||
resolve: true
|
||||
}
|
||||
})
|
||||
.then(res => res.body.statuses[0])
|
||||
.catch(err => console.warn(err))
|
||||
export const searchLocalStatus = async (uri: Mastodon.Status['uri']): Promise<Mastodon.Status> => {
|
||||
const queryKey: QueryKeySearch = ['Search', { type: 'statuses', term: uri, limit: 1 }]
|
||||
return await queryClient
|
||||
.fetchQuery(queryKey, queryFunction, { staleTime: 3600, cacheTime: 3600 })
|
||||
.then(res =>
|
||||
res.statuses[0].uri === uri || res.statuses[0].url === uri
|
||||
? res.statuses[0]
|
||||
: Promise.reject()
|
||||
)
|
||||
}
|
||||
|
||||
export const searchLocalAccount = async (
|
||||
url: Mastodon.Account['url']
|
||||
): Promise<Mastodon.Account> => {
|
||||
const queryKey: QueryKeySearch = ['Search', { type: 'accounts', term: url, limit: 1 }]
|
||||
return await queryClient
|
||||
.fetchQuery(queryKey, queryFunction, { staleTime: 3600, cacheTime: 3600 })
|
||||
.then(res => (res.accounts[0].url === url ? res.accounts[0] : Promise.reject()))
|
||||
}
|
||||
|
||||
export { useSearchQuery }
|
||||
|
@ -1,26 +1,59 @@
|
||||
import { QueryFunctionContext, useQuery, UseQueryOptions } from '@tanstack/react-query'
|
||||
import apiGeneral from '@utils/api/general'
|
||||
import apiInstance from '@utils/api/instance'
|
||||
import { urlMatcher } from '@utils/helpers/urlMatcher'
|
||||
import { AxiosError } from 'axios'
|
||||
import { searchLocalStatus } from './search'
|
||||
|
||||
export type QueryKeyStatus = ['Status', { id: Mastodon.Status['id'] }]
|
||||
export type QueryKeyStatus = [
|
||||
'Status',
|
||||
(Pick<Mastodon.Status, 'uri'> & Partial<Pick<Mastodon.Status, 'id' | '_remote'>>) | undefined
|
||||
]
|
||||
|
||||
const queryFunction = async ({ queryKey }: QueryFunctionContext<QueryKeyStatus>) => {
|
||||
const { id } = queryKey[1]
|
||||
const key = queryKey[1]
|
||||
if (!key) return Promise.reject()
|
||||
|
||||
const res = await apiInstance<Mastodon.Status>({
|
||||
method: 'get',
|
||||
url: `statuses/${id}`
|
||||
})
|
||||
return res.body
|
||||
let matchedStatus: Mastodon.Status | undefined = undefined
|
||||
|
||||
const match = urlMatcher(key.uri)
|
||||
const domain = match?.domain
|
||||
const id = key.id || match?.status?.id
|
||||
|
||||
if (key._remote && domain && id) {
|
||||
try {
|
||||
matchedStatus = await apiGeneral<Mastodon.Status>({
|
||||
method: 'get',
|
||||
domain,
|
||||
url: `api/v1/statuses/${id}`
|
||||
}).then(res => ({ ...res.body, _remote: true }))
|
||||
} catch {}
|
||||
}
|
||||
|
||||
if (!matchedStatus && !key._remote && id) {
|
||||
matchedStatus = await apiInstance<Mastodon.Status>({
|
||||
method: 'get',
|
||||
url: `statuses/${id}`
|
||||
}).then(res => res.body)
|
||||
}
|
||||
|
||||
if (!matchedStatus) {
|
||||
matchedStatus = await searchLocalStatus(key.uri)
|
||||
}
|
||||
|
||||
return matchedStatus
|
||||
}
|
||||
|
||||
const useStatusQuery = ({
|
||||
options,
|
||||
...queryKeyParams
|
||||
}: QueryKeyStatus[1] & {
|
||||
status
|
||||
}: { status?: QueryKeyStatus[1] } & {
|
||||
options?: UseQueryOptions<Mastodon.Status, AxiosError>
|
||||
}) => {
|
||||
const queryKey: QueryKeyStatus = ['Status', { ...queryKeyParams }]
|
||||
const queryKey: QueryKeyStatus = [
|
||||
'Status',
|
||||
status ? { id: status.id, uri: status.uri, _remote: status._remote } : undefined
|
||||
]
|
||||
return useQuery(queryKey, queryFunction, options)
|
||||
}
|
||||
|
||||
|
@ -1,34 +1,53 @@
|
||||
import { QueryFunctionContext, useQuery, UseQueryOptions } from '@tanstack/react-query'
|
||||
import apiGeneral from '@utils/api/general'
|
||||
import apiInstance from '@utils/api/instance'
|
||||
import { urlMatcher } from '@utils/helpers/urlMatcher'
|
||||
import { AxiosError } from 'axios'
|
||||
|
||||
export type QueryKeyStatusesHistory = [
|
||||
'StatusesHistory',
|
||||
{ id: Mastodon.Status['id'] }
|
||||
Pick<Mastodon.Status, 'id' | 'uri' | 'edited_at' | '_remote'> &
|
||||
Partial<Pick<Mastodon.Status, 'edited_at'>>
|
||||
]
|
||||
|
||||
const queryFunction = async ({
|
||||
queryKey
|
||||
}: QueryFunctionContext<QueryKeyStatusesHistory>) => {
|
||||
const { id } = queryKey[1]
|
||||
const res = await apiInstance<Mastodon.StatusHistory[]>({
|
||||
const queryFunction = async ({ queryKey }: QueryFunctionContext<QueryKeyStatusesHistory>) => {
|
||||
const { id, uri, _remote } = queryKey[1]
|
||||
|
||||
if (_remote) {
|
||||
const match = urlMatcher(uri)
|
||||
const domain = match?.domain
|
||||
if (!domain) {
|
||||
return Promise.reject('Cannot find remote domain to retrieve status histories')
|
||||
}
|
||||
return await apiGeneral<Mastodon.StatusHistory[]>({
|
||||
method: 'get',
|
||||
domain,
|
||||
url: `api/v1/statuses/${id}/history`
|
||||
}).then(res => res.body)
|
||||
}
|
||||
|
||||
return await apiInstance<Mastodon.StatusHistory[]>({
|
||||
method: 'get',
|
||||
url: `statuses/${id}/history`
|
||||
})
|
||||
return res.body
|
||||
}).then(res => res.body)
|
||||
}
|
||||
|
||||
const useStatusHistory = ({
|
||||
options,
|
||||
...queryKeyParams
|
||||
}: QueryKeyStatusesHistory[1] & {
|
||||
status
|
||||
}: { status: QueryKeyStatusesHistory[1] } & {
|
||||
options?: UseQueryOptions<Mastodon.StatusHistory[], AxiosError>
|
||||
}) => {
|
||||
const queryKey: QueryKeyStatusesHistory = [
|
||||
'StatusesHistory',
|
||||
{ ...queryKeyParams }
|
||||
{ id: status.id, uri: status.uri, edited_at: status.edited_at, _remote: status._remote }
|
||||
]
|
||||
return useQuery(queryKey, queryFunction, options)
|
||||
return useQuery(queryKey, queryFunction, {
|
||||
...options,
|
||||
enabled: !!status.edited_at,
|
||||
staleTime: 3600,
|
||||
cacheTime: 3600
|
||||
})
|
||||
}
|
||||
|
||||
export { useStatusHistory }
|
||||
|
@ -9,11 +9,11 @@ import {
|
||||
import { PagedResponse } from '@utils/api/helpers'
|
||||
import apiInstance from '@utils/api/instance'
|
||||
import { featureCheck } from '@utils/helpers/featureCheck'
|
||||
import queryClient from '@utils/queryHooks'
|
||||
import { queryClient } from '@utils/queryHooks'
|
||||
import { getAccountStorage } from '@utils/storage/actions'
|
||||
import { AxiosError } from 'axios'
|
||||
import { uniqBy } from 'lodash'
|
||||
import { searchFetchToot } from './search'
|
||||
import { searchLocalStatus } from './search'
|
||||
import deleteItem from './timeline/deleteItem'
|
||||
import editItem from './timeline/editItem'
|
||||
import updateStatusProperty from './timeline/updateStatusProperty'
|
||||
@ -342,7 +342,7 @@ const mutationFunction = async (params: MutationVarsTimeline) => {
|
||||
default:
|
||||
let tootId = params.status.id
|
||||
if (params.status._remote) {
|
||||
const fetched = await searchFetchToot(params.status.uri)
|
||||
const fetched = await searchLocalStatus(params.status.uri)
|
||||
if (fetched) {
|
||||
tootId = fetched.id
|
||||
} else {
|
||||
|
@ -1,19 +1,13 @@
|
||||
import { InfiniteData } from '@tanstack/react-query'
|
||||
import queryClient from '@utils/queryHooks'
|
||||
import { queryClient } from '@utils/queryHooks'
|
||||
import { MutationVarsTimelineDeleteItem } from '../timeline'
|
||||
|
||||
const deleteItem = ({
|
||||
queryKey,
|
||||
rootQueryKey,
|
||||
id
|
||||
}: MutationVarsTimelineDeleteItem) => {
|
||||
const deleteItem = ({ queryKey, rootQueryKey, id }: MutationVarsTimelineDeleteItem) => {
|
||||
queryKey &&
|
||||
queryClient.setQueryData<InfiniteData<any> | undefined>(queryKey, old => {
|
||||
if (old) {
|
||||
old.pages = old.pages.map(page => {
|
||||
page.body = page.body.filter(
|
||||
(item: Mastodon.Status) => item.id !== id
|
||||
)
|
||||
page.body = page.body.filter((item: Mastodon.Status) => item.id !== id)
|
||||
return page
|
||||
})
|
||||
return old
|
||||
@ -21,20 +15,15 @@ const deleteItem = ({
|
||||
})
|
||||
|
||||
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
|
||||
}
|
||||
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
|
||||
|
@ -1,12 +1,8 @@
|
||||
import { InfiniteData } from '@tanstack/react-query'
|
||||
import queryClient from '@utils/queryHooks'
|
||||
import { queryClient } from '@utils/queryHooks'
|
||||
import { MutationVarsTimelineEditItem } from '../timeline'
|
||||
|
||||
const editItem = ({
|
||||
queryKey,
|
||||
rootQueryKey,
|
||||
status
|
||||
}: MutationVarsTimelineEditItem) => {
|
||||
const editItem = ({ queryKey, rootQueryKey, status }: MutationVarsTimelineEditItem) => {
|
||||
queryKey &&
|
||||
queryClient.setQueryData<InfiniteData<any> | undefined>(queryKey, old => {
|
||||
if (old) {
|
||||
@ -24,23 +20,20 @@ const editItem = ({
|
||||
})
|
||||
|
||||
rootQueryKey &&
|
||||
queryClient.setQueryData<InfiniteData<any> | undefined>(
|
||||
rootQueryKey,
|
||||
old => {
|
||||
if (old) {
|
||||
old.pages = old.pages.map(page => {
|
||||
page.body = page.body.map((item: Mastodon.Status) => {
|
||||
if (item.id === status.id) {
|
||||
item = status
|
||||
}
|
||||
return item
|
||||
})
|
||||
return page
|
||||
queryClient.setQueryData<InfiniteData<any> | undefined>(rootQueryKey, old => {
|
||||
if (old) {
|
||||
old.pages = old.pages.map(page => {
|
||||
page.body = page.body.map((item: Mastodon.Status) => {
|
||||
if (item.id === status.id) {
|
||||
item = status
|
||||
}
|
||||
return item
|
||||
})
|
||||
return old
|
||||
}
|
||||
return page
|
||||
})
|
||||
return old
|
||||
}
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
export default editItem
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { InfiniteData } from '@tanstack/react-query'
|
||||
import queryClient from '@utils/queryHooks'
|
||||
import { queryClient } from '@utils/queryHooks'
|
||||
import { MutationVarsTimelineUpdateStatusProperty, TimelineData } from '../timeline'
|
||||
|
||||
const updateStatusProperty = ({
|
||||
@ -9,7 +9,7 @@ const updateStatusProperty = ({
|
||||
payload,
|
||||
poll
|
||||
}: MutationVarsTimelineUpdateStatusProperty & { poll?: Mastodon.Poll }) => {
|
||||
for (const key of [queryKey]) {
|
||||
for (const key of [queryKey, rootQueryKey]) {
|
||||
if (!key) continue
|
||||
|
||||
queryClient.setQueryData<InfiniteData<TimelineData> | undefined>(key, old => {
|
||||
|
@ -1,22 +1,18 @@
|
||||
import {
|
||||
QueryFunctionContext,
|
||||
useInfiniteQuery,
|
||||
UseInfiniteQueryOptions
|
||||
QueryFunctionContext,
|
||||
useInfiniteQuery,
|
||||
UseInfiniteQueryOptions
|
||||
} from '@tanstack/react-query'
|
||||
import apiGeneral from '@utils/api/general'
|
||||
import { PagedResponse } from '@utils/api/helpers'
|
||||
import apiInstance from '@utils/api/instance'
|
||||
import { getHost } from '@utils/helpers/urlMatcher'
|
||||
import { urlMatcher } from '@utils/helpers/urlMatcher'
|
||||
import { TabSharedStackParamList } from '@utils/navigation/navigators'
|
||||
import { AxiosError } from 'axios'
|
||||
|
||||
export type QueryKeyUsers = ['Users', TabSharedStackParamList['Tab-Shared-Users']]
|
||||
|
||||
const queryFunction = async ({
|
||||
queryKey,
|
||||
pageParam,
|
||||
meta
|
||||
}: QueryFunctionContext<QueryKeyUsers>) => {
|
||||
const queryFunction = async ({ queryKey, pageParam }: QueryFunctionContext<QueryKeyUsers>) => {
|
||||
const page = queryKey[1]
|
||||
let params: { [key: string]: string } = { ...pageParam }
|
||||
|
||||
@ -24,7 +20,7 @@ const queryFunction = async ({
|
||||
case 'statuses':
|
||||
return apiInstance<Mastodon.Account[]>({
|
||||
method: 'get',
|
||||
url: `${page.reference}/${page.status.id}/${page.type}`,
|
||||
url: `statuses/${page.status.id}/${page.type}`,
|
||||
params
|
||||
})
|
||||
case 'accounts':
|
||||
@ -32,14 +28,14 @@ const queryFunction = async ({
|
||||
if (localInstance) {
|
||||
return apiInstance<Mastodon.Account[]>({
|
||||
method: 'get',
|
||||
url: `${page.reference}/${page.account.id}/${page.type}`,
|
||||
url: `accounts/${page.account.id}/${page.type}`,
|
||||
params
|
||||
})
|
||||
} else {
|
||||
let res: PagedResponse<Mastodon.Account[]>
|
||||
|
||||
try {
|
||||
const domain = getHost(page.account.url)
|
||||
const domain = urlMatcher(page.account.url)?.domain
|
||||
if (!domain?.length) {
|
||||
throw new Error()
|
||||
}
|
||||
@ -54,7 +50,7 @@ const queryFunction = async ({
|
||||
res = await apiGeneral<Mastodon.Account[]>({
|
||||
method: 'get',
|
||||
domain,
|
||||
url: `api/v1/${page.reference}/${resLookup.body.id}/${page.type}`,
|
||||
url: `api/v1/accounts/${resLookup.body.id}/${page.type}`,
|
||||
params
|
||||
})
|
||||
return { ...res, remoteData: true }
|
||||
|
12
src/utils/startup/dev.ts
Normal file
12
src/utils/startup/dev.ts
Normal file
@ -0,0 +1,12 @@
|
||||
import { queryClient } from '@utils/queryHooks'
|
||||
import log from './log'
|
||||
|
||||
export const dev = () => {
|
||||
if (__DEV__) {
|
||||
log('log', 'dev', 'loading tools')
|
||||
// @ts-ignore
|
||||
import('react-query-native-devtools').then(({ addPlugin }) => {
|
||||
addPlugin({ queryClient })
|
||||
})
|
||||
}
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
import queryClient from '@utils/queryHooks'
|
||||
import { queryClient } from '@utils/queryHooks'
|
||||
import { storage } from '@utils/storage'
|
||||
import {
|
||||
MMKV,
|
||||
|
Reference in New Issue
Block a user