diff --git a/package.json b/package.json index 2b5e7e420..868b91827 100644 --- a/package.json +++ b/package.json @@ -46,7 +46,7 @@ "@subwallet/wagmi-connector": "0.2.1", "@talismn/connect-wallets": "^1.2.3", "@talismn/wagmi-connector": "^0.3.1", - "@tanstack/react-query": "^4.24.10", + "@tanstack/react-query": "4.36.1", "@types/lodash.truncate": "^4.4.7", "@types/node": "18.14.1", "@types/randomcolor": "^0.5.7", diff --git a/src/services/subsocial/datahub/posts/query.ts b/src/services/subsocial/datahub/posts/query.ts index 671834776..4e0d65f68 100644 --- a/src/services/subsocial/datahub/posts/query.ts +++ b/src/services/subsocial/datahub/posts/query.ts @@ -2,7 +2,11 @@ import { CHAT_PER_PAGE } from '@/constants/chat' import { getPostQuery } from '@/services/api/query' import { queryClient } from '@/services/provider' import { createQuery, poolQuery, QueryConfig } from '@/subsocial-query' -import { QueryClient, useInfiniteQuery } from '@tanstack/react-query' +import { + QueryClient, + useInfiniteQuery, + useQueryClient, +} from '@tanstack/react-query' import { gql } from 'graphql-request' import { commentIdsOptimisticEncoder, @@ -46,6 +50,18 @@ async function getPaginatedPostsByRootPostId({ page: number client?: QueryClient }): Promise { + const oldIds = getPaginatedPostsByPostIdFromDatahubQuery.getFirstPageData( + client, + postId + ) + const firstPageDataLength = oldIds?.length || CHAT_PER_PAGE + + // only first page that has dynamic content, where its length can increase from: + // - subscription + // - invalidation + // so the offset has to accommodate the length of the current first page + const offset = (page - 2) * CHAT_PER_PAGE + firstPageDataLength + const res = await datahubQueryRequest< GetCommentIdsInPostIdQuery, GetCommentIdsInPostIdQueryVariables @@ -57,7 +73,7 @@ async function getPaginatedPostsByRootPostId({ orderBy: 'createdAtTime', orderDirection: QueryOrder.Desc, pageSize: CHAT_PER_PAGE, - offset: (page - 1) * CHAT_PER_PAGE, + offset, }, }, }) @@ -71,22 +87,34 @@ async function getPaginatedPostsByRootPostId({ const totalData = res.findPosts.total ?? 0 const hasMore = totalData > page * CHAT_PER_PAGE + ids.length - let unincludedIds: string[] = [] - // only adding the client optimistic ids if refetching first page + const idsSet = new Set(ids) + + // only adding the client optimistic ids, and unincluded ids if refetching first page + // for fetching first page, no ids that has been fetched will be removed + // ex: first fetch: id 1-50, and after invalidation, there is new data id 0 + // the result should be id 0-50 instead of 0-49 + let unincludedOptimisticIds: string[] = [] + let unincludedFirstPageIds: string[] = [] if (page === 1) { - const oldIds = getPaginatedPostsByPostIdFromDatahubQuery.getFirstPageData( - queryClient, - postId - ) - const oldOptimisticIds = - oldIds?.filter((id) => isClientGeneratedOptimisticId(id)) || [] - unincludedIds = oldOptimisticIds.filter( - (id) => !optimisticIds.has(commentIdsOptimisticEncoder.decode(id)) - ) + if (oldIds) { + const oldOptimisticIds = [] + for (let i = 0; i < oldIds.length; i++) { + const id = oldIds[i] + if (isClientGeneratedOptimisticId(id)) { + oldOptimisticIds.push(id) + } + if (!idsSet.has(id)) { + unincludedFirstPageIds.push(id) + } + } + unincludedOptimisticIds = oldOptimisticIds.filter( + (id) => !optimisticIds.has(commentIdsOptimisticEncoder.decode(id)) + ) + } } return { - data: [...ids, ...unincludedIds], + data: [...unincludedOptimisticIds, ...ids, ...unincludedFirstPageIds], page, hasMore, totalData, @@ -145,11 +173,41 @@ export const getPaginatedPostsByPostIdFromDatahubQuery = { }) }, useInfiniteQuery: (postId: string, config?: QueryConfig) => { + const client = useQueryClient() return useInfiniteQuery({ ...config, queryKey: getQueryKey(postId), - queryFn: ({ pageParam = 1, queryKey: [_, postId] }) => - getPaginatedPostsByRootPostId({ postId, page: pageParam }), + queryFn: async ({ pageParam = 1, queryKey }) => { + const [_, postId] = queryKey + const res = await getPaginatedPostsByRootPostId({ + postId, + page: pageParam, + }) + + // hotfix because in offchain chat (/offchain/18634) its not updating cache when first invalidated from server + if (pageParam === 1) { + client.setQueryData<{ + pageParams: number[] + pages: PaginatedPostsData[] + }>(getQueryKey(postId), (oldData) => { + if ( + !oldData || + !Array.isArray(oldData.pageParams) || + !Array.isArray(oldData.pages) + ) + return oldData + const pages = [...oldData.pages] + pages.splice(0, 1, res) + return { + ...oldData, + pageParams: [...oldData.pageParams], + pages, + } + }) + } + + return res + }, getNextPageParam: (lastPage) => lastPage.hasMore ? lastPage.page + 1 : undefined, }) diff --git a/yarn.lock b/yarn.lock index 8ad9a9cfc..3dbeff747 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7685,6 +7685,11 @@ resolved "https://registry.yarnpkg.com/@tanstack/query-core/-/query-core-4.29.5.tgz#a0273e88bf2fc102c4c893dc7c034127b67fd5d9" integrity sha512-xXIiyQ/4r9KfaJ3k6kejqcaqFXXBTzN2aOJ5H1J6aTJE9hl/nbgAdfF6oiIu0CD5xowejJEJ6bBg8TO7BN4NuQ== +"@tanstack/query-core@4.36.1": + version "4.36.1" + resolved "https://registry.yarnpkg.com/@tanstack/query-core/-/query-core-4.36.1.tgz#79f8c1a539d47c83104210be2388813a7af2e524" + integrity sha512-DJSilV5+ytBP1FbFcEJovv4rnnm/CokuVvrBEtW/Va9DvuJ3HksbXUJEpI0aV1KtuL4ZoO9AVE6PyNLzF7tLeA== + "@tanstack/query-persist-client-core@4.29.5": version "4.29.5" resolved "https://registry.yarnpkg.com/@tanstack/query-persist-client-core/-/query-persist-client-core-4.29.5.tgz#88ba2e532a7651bfa0d5eb4ba116ae94859a5bb3" @@ -7706,12 +7711,12 @@ dependencies: "@tanstack/query-persist-client-core" "4.29.5" -"@tanstack/react-query@^4.24.10": - version "4.29.5" - resolved "https://registry.yarnpkg.com/@tanstack/react-query/-/react-query-4.29.5.tgz#3890741291f9f925933243d78bd74dfc59d64208" - integrity sha512-F87cibC3s3eG0Q90g2O+hqntpCrudKFnR8P24qkH9uccEhXErnJxBC/AAI4cJRV2bfMO8IeGZQYf3WyYgmSg0w== +"@tanstack/react-query@4.36.1": + version "4.36.1" + resolved "https://registry.yarnpkg.com/@tanstack/react-query/-/react-query-4.36.1.tgz#acb589fab4085060e2e78013164868c9c785e5d2" + integrity sha512-y7ySVHFyyQblPl3J3eQBWpXZkliroki3ARnBKsdJchlgt7yJLRDUcf4B8soufgiYt3pEQIkBWBx1N9/ZPIeUWw== dependencies: - "@tanstack/query-core" "4.29.5" + "@tanstack/query-core" "4.36.1" use-sync-external-store "^1.2.0" "@tanstack/react-query@^4.28.0":