Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fetch post and space data from squid with blockchain fallback #413

Merged
merged 4 commits into from
Apr 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/components/posts/editor/ModalEditor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,7 @@ export const PostEditorModalBody = ({

const url = postUrl({ id: spaceId! }, postData)
router
.push('/[spaceId]/[slug]', url + '?source=chain')
.push('/[spaceId]/[slug]', url)
.catch(err => log.error(`Failed to redirect to a post page. ${err}`))
}

Expand Down
2 changes: 1 addition & 1 deletion src/components/posts/editor/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ function EditPostForm(props: PostFormProps) {

const url = postUrl({ id: spaceForPost! }, postData)
router
.push('/[spaceId]/[slug]', url + '?source=chain')
.push('/[spaceId]/[slug]', url)
.catch(err => log.error(`Failed to redirect to a post page. ${err}`))
}

Expand Down
25 changes: 18 additions & 7 deletions src/components/posts/view-post/PostPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,11 @@ import { useIsPostBlocked } from 'src/rtk/features/moderation/hooks'
import { fetchPost, fetchPosts, selectPost } from 'src/rtk/features/posts/postsSlice'
import { fetchPostsViewCount } from 'src/rtk/features/posts/postsViewCountSlice'
import { useFetchMyReactionsByPostId } from 'src/rtk/features/reactions/myPostReactionsHooks'
import { fetchPostReplyIds, selectReplyIds } from 'src/rtk/features/replies/repliesSlice'
import {
asCommentStruct,
DataSourceTypes,
HasStatusCode,
idToBn,
PostData,
PostWithSomeDetails,
} from 'src/types'
Expand Down Expand Up @@ -283,30 +283,41 @@ export async function loadPostOnNextReq({
reduxStore,
}: NextContextWithRedux): Promise<PostWithSomeDetails & HasStatusCode> {
const {
query: { slug, source },
query: { slug },
res,
asPath,
} = context

const { blockchain } = subsocial

const slugStr = slug as string
const postId = getPostIdFromSlug(slugStr)

if (!postId) return return404(context)

async function getPost() {
const replyIds = await blockchain.getReplyIdsByPostId(idToBn(postId!))
const ids = replyIds.concat(postId!)
await dispatch(fetchPostReplyIds({ id: postId!, api: subsocial }))
const replyIds = selectReplyIds(reduxStore.getState(), postId!)
const ids = [postId!, ...(replyIds?.replyIds ?? [])]
await dispatch(
fetchPosts({
api: subsocial,
ids,
reload: true,
eagerLoadHandles: true,
dataSource: source === 'chain' ? DataSourceTypes.CHAIN : DataSourceTypes.SQUID,
dataSource: DataSourceTypes.SQUID,
}),
)
const postData = selectPost(reduxStore.getState(), { id: postId! })
if (!postData) {
await dispatch(
fetchPosts({
api: subsocial,
ids: [postId!],
reload: true,
eagerLoadHandles: true,
dataSource: DataSourceTypes.CHAIN,
}),
)
}
}
await Promise.all([getPost(), dispatch(fetchBlockedResources({ appId }))])
const postData = selectPost(reduxStore.getState(), { id: postId })
Expand Down
18 changes: 14 additions & 4 deletions src/components/spaces/helpers/loadSpaceOnNextReq.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ export async function loadSpaceOnNextReq(
): Promise<SpaceWithSomeDetails & HasStatusCode> {
const { context, subsocial, dispatch, reduxStore } = props
const { query, res } = context
const { spaceId, source } = query
const { spaceId } = query
const idOrHandle = spaceId as string

try {
Expand All @@ -29,13 +29,23 @@ export async function loadSpaceOnNextReq(
id: idStr,
reload: true,
eagerLoadHandles: true,
dataSource: source === 'chain' ? DataSourceTypes.CHAIN : DataSourceTypes.SQUID,
dataSource: DataSourceTypes.SQUID,
}),
)
const spaceData = selectSpace(reduxStore.getState(), { id: idStr })
let spaceData = selectSpace(reduxStore.getState(), { id: idStr })

if (!spaceData) {
return return404(context)
await dispatch(
fetchSpace({
api: subsocial,
id: idStr,
reload: true,
eagerLoadHandles: true,
dataSource: DataSourceTypes.CHAIN,
}),
)
spaceData = selectSpace(reduxStore.getState(), { id: idStr })
if (!spaceData) return return404(context)
}

const maybeHandle = idStr !== idOrHandle ? idOrHandle : undefined
Expand Down
20 changes: 18 additions & 2 deletions src/components/spaces/withLoadSpaceFromUrl.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@ import { isFunction } from '@polkadot/util'
import { newLogger } from '@subsocial/utils'
import { useRouter } from 'next/router'
import React, { useState } from 'react'
import { useDispatch, useStore } from 'react-redux'
import { useFetchMyPermissionsBySpaceId } from 'src/rtk/features/permissions/mySpacePermissionsHooks'
import { SpaceData } from 'src/types'
import { fetchSpace, selectSpace } from 'src/rtk/features/spaces/spacesSlice'
import { DataSourceTypes, SpaceData } from 'src/types'
import useSubsocialEffect from '../api/useSubsocialEffect'
import { getSpaceId } from '../substrate'
import { Loading } from '../utils'
Expand Down Expand Up @@ -35,6 +37,8 @@ export function withLoadSpaceFromUrl<Props extends CanHaveSpaceProps>(
const [isLoaded, setIsLoaded] = useState(!idOrHandle)
const [loadedData, setLoadedData] = useState<CanHaveSpaceProps>({})
useFetchMyPermissionsBySpaceId(loadedData.space?.id)
const dispatch = useDispatch()
const store = useStore()

useSubsocialEffect(
({ subsocial }) => {
Expand All @@ -45,7 +49,19 @@ export function withLoadSpaceFromUrl<Props extends CanHaveSpaceProps>(

if (isMounted && id) {
setIsLoaded(false)
const space = await subsocial.findSpace({ id })
await dispatch(fetchSpace({ api: subsocial, id: id.toString() }))
let space = selectSpace(store.getState(), { id: id.toString() })

if (!space) {
await dispatch(
fetchSpace({
api: subsocial,
id: id.toString(),
dataSource: DataSourceTypes.CHAIN,
}),
)
space = selectSpace(store.getState(), { id: id.toString() })
}

setLoadedData({ space })
}
Expand Down
2 changes: 1 addition & 1 deletion src/components/urls/goToPage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { createNewPostLinkProps } from '../spaces/helpers'
const log = newLogger('Go to page')

export function goToSpacePage(spaceId: AnyId, isFirstSpace?: boolean) {
const params = `?source=chain${isFirstSpace ? '&isFirst' : ''}`
const params = `?${isFirstSpace ? 'isFirst' : ''}`

Router.push('/[spaceId]', `/${spaceId.toString()}${params}`).catch(err =>
log.error('Failed to redirect to "View Space" page:', err),
Expand Down
8 changes: 8 additions & 0 deletions src/graphql/apis/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -417,3 +417,11 @@ export async function getLastestPostIdsInSpace(
const posts = res.data.posts ?? []
return posts.map(post => post.id)
}

export async function getReplyIdsByParentId(client: GqlClient, variables: { parentId: string }) {
const posts = await client.query<{ posts: { id: string }[] }, { parentId: string }>({
query: q.GET_REPLY_IDS_BY_PARENT_ID,
variables,
})
return posts.data.posts.map(post => post.id)
}
16 changes: 16 additions & 0 deletions src/graphql/queries.ts
Original file line number Diff line number Diff line change
Expand Up @@ -835,3 +835,19 @@ export const GET_LASTEST_POST_IDS_IN_SPACE = gql`
}
}
`

// Replies

export const GET_REPLY_IDS_BY_PARENT_ID = gql`
query GetReplyIdsByParentId($parentId: String!) {
posts(
orderBy: createdAtTime_ASC
where: {
parentPost: { id_eq: $parentId }
OR: { rootPost: { id_eq: $parentId }, parentPost: { id_isNull: true } }
}
) {
id
}
}
`
25 changes: 23 additions & 2 deletions src/rtk/features/replies/repliesSlice.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,17 @@
import { createAsyncThunk, createEntityAdapter, createSlice } from '@reduxjs/toolkit'
import { SubsocialApi } from '@subsocial/api'
import { idToBn, isEmptyArray } from '@subsocial/utils'
import { getReplyIdsByParentId } from 'src/graphql/apis'
import {
CommonFetchProps,
createSelectUnknownIds,
SelectManyArgs,
SelectOneArgs,
ThunkApiConfig,
validateDataSource,
} from 'src/rtk/app/helpers'
import { RootState } from 'src/rtk/app/rootReducer'
import { createFetchDataFn } from 'src/rtk/app/wrappers'
import { AccountId, DataSourceTypes, PostId, PostWithSomeDetails } from 'src/types'
import { fetchPosts } from '../posts/postsSlice'

Expand Down Expand Up @@ -72,12 +76,26 @@ export function selectManyReplyIds(
// return selectManyPostReplies(state, { ids: [ parentId ]})[parentId] || []
// }

const getReplyIds = createFetchDataFn<string[]>([])({
chain: async ({ api, parentId }: { api: SubsocialApi; parentId: string }) => {
return api.blockchain.getReplyIdsByPostId(idToBn(parentId))
},
squid: async ({ parentId }: { parentId: string }, client) => {
if (!parentId) return []
const ids = await getReplyIdsByParentId(client, {
parentId,
})
return ids
},
})

export const fetchPostReplyIds = createAsyncThunk<
ReplyIdsByPostId[],
FetchManyPostRepliesArgs,
ThunkApiConfig
>('replyIds/fetchMany', async (args, { getState, dispatch }) => {
const { id: parentId, myAddress, api, reload } = args
const { id: parentId, myAddress, api, reload, dataSource: _dataSource } = args
const dataSource = validateDataSource(_dataSource)

if (!reload) {
const parentIds = selectUnknownParentIds(getState(), [parentId])
Expand All @@ -87,7 +105,10 @@ export const fetchPostReplyIds = createAsyncThunk<
}
}

const replyIds = await api.blockchain.getReplyIdsByPostId(idToBn(parentId))
const replyIds = await getReplyIds(dataSource, {
chain: { api, parentId },
squid: { parentId },
})

await Promise.allSettled([
dispatch(
Expand Down
Loading