From e5211ac91d08165ee13b3e48c01e03224a08078f Mon Sep 17 00:00:00 2001 From: Ezerous Date: Sat, 27 Feb 2021 19:26:27 +0200 Subject: [PATCH] feat: add pagination to Profile PostList --- .../src/components/PostList/index.jsx | 15 ++-- .../views/Profile/ProfilePostList/index.jsx | 89 +++++++++++++++++++ .../concordia-app/src/views/Profile/index.jsx | 14 ++- 3 files changed, 102 insertions(+), 16 deletions(-) create mode 100644 packages/concordia-app/src/views/Profile/ProfilePostList/index.jsx diff --git a/packages/concordia-app/src/components/PostList/index.jsx b/packages/concordia-app/src/components/PostList/index.jsx index 064d5a0..9b118c3 100644 --- a/packages/concordia-app/src/components/PostList/index.jsx +++ b/packages/concordia-app/src/components/PostList/index.jsx @@ -2,24 +2,24 @@ import React, { useEffect, useMemo, useState, } from 'react'; import PropTypes from 'prop-types'; -import { useSelector } from 'react-redux'; import { Dimmer, Feed, Loader, } from 'semantic-ui-react'; import { FORUM_CONTRACT } from 'concordia-shared/src/constants/contracts/ContractNames'; -import PostListRow from './PostListRow'; import { drizzle } from '../../redux/store'; +import PostListRow from './PostListRow'; +import PaginationComponent from '../PaginationComponent'; const { contracts: { [FORUM_CONTRACT]: { methods: { getPost: { cacheCall: getPostChainData } } } } } = drizzle; const PostList = (props) => { - const { postIds, loading, focusOnPost } = props; + const { + postIds, numberOfItems, onPageChange, loading, focusOnPost, + } = props; const [getPostCallHashes, setGetPostCallHashes] = useState([]); - const drizzleInitialized = useSelector((state) => state.drizzleStatus.initialized); - const drizzleInitializationFailed = useSelector((state) => state.drizzleStatus.failed); useEffect(() => { - if (drizzleInitialized && !drizzleInitializationFailed && !loading) { + if (!loading) { setGetPostCallHashes( postIds.map((postId) => ({ id: postId, @@ -27,7 +27,7 @@ const PostList = (props) => { })), ); } - }, [drizzleInitializationFailed, drizzleInitialized, loading, postIds]); + }, [loading, postIds]); const posts = useMemo(() => { if (loading) { @@ -54,6 +54,7 @@ const PostList = (props) => { {posts} + ); }; diff --git a/packages/concordia-app/src/views/Profile/ProfilePostList/index.jsx b/packages/concordia-app/src/views/Profile/ProfilePostList/index.jsx new file mode 100644 index 0000000..51dbf37 --- /dev/null +++ b/packages/concordia-app/src/views/Profile/ProfilePostList/index.jsx @@ -0,0 +1,89 @@ +import React, { + useEffect, useMemo, useState, +} from 'react'; +import { useSelector } from 'react-redux'; +import { useTranslation } from 'react-i18next'; +import { FORUM_CONTRACT } from 'concordia-shared/src/constants/contracts/ContractNames'; +import { Header } from 'semantic-ui-react'; +import { drizzle } from '../../../redux/store'; +import { ITEMS_PER_PAGE } from '../../../components/PaginationComponent'; +import PostList from '../../../components/PostList'; + +const { + contracts: { + [FORUM_CONTRACT]: { + methods: { + getUserPostCount: { cacheCall: getUserPostCountChainData }, + getUserPosts: { cacheCall: getUserPostsChainData }, + }, + }, + }, +} = drizzle; + +const ProfilePostList = (props) => { + const { username, profileAddress } = props; + const [pageNumber, setPageNumber] = useState(1); + + const [userPostCount, setUserPostCount] = useState(null); + const [postIds, setPostIds] = useState([]); + + const [getUserPostCountCallHash, setGetUserPostCountCallHash] = useState(null); + const [getUserPostsCallHash, setGetUserPostsCallHash] = useState(null); + + const getUserPostCountResult = useSelector((state) => state.contracts[FORUM_CONTRACT].getUserPostCount[getUserPostCountCallHash]); + const getUserPostsResult = useSelector((state) => state.contracts[FORUM_CONTRACT].getUserPosts[getUserPostsCallHash]); + + const { t } = useTranslation(); + + useEffect(() => { + if (getUserPostCountCallHash === null) { + setGetUserPostCountCallHash(getUserPostCountChainData(profileAddress)); + } + }, [getUserPostCountCallHash, profileAddress]); + + useEffect(() => { + if (userPostCount !== null && userPostCount !== 0) { + const startIndex = Math.max(userPostCount - ITEMS_PER_PAGE * pageNumber, 0); + const endIndex = userPostCount - ITEMS_PER_PAGE * (pageNumber - 1) - 1; + setGetUserPostsCallHash(getUserPostsChainData(profileAddress, startIndex, endIndex)); + } + }, [pageNumber, profileAddress, userPostCount]); + + useEffect(() => { + if (getUserPostCountResult) { + setUserPostCount(parseInt(getUserPostCountResult.value, 10)); + } + }, [getUserPostCountResult, userPostCount]); + + useEffect(() => { + if (getUserPostsResult) { + setPostIds(getUserPostsResult.value.slice().reverse().map(Number)); + } + }, [getUserPostsResult, userPostCount]); + + const handlePageChange = (event, data) => { + setPageNumber(data.activePage); + }; + + return useMemo(() => { + if (postIds.length && postIds.length !== 0) { + return ( + + ); + } + if (userPostCount === 0) { + return ( +
+ {t('profile.user.has.no.posts.header.message', { user: username })} +
+ ); + } + return null; + }, [t, postIds, userPostCount, username]); +}; + +export default ProfilePostList; diff --git a/packages/concordia-app/src/views/Profile/index.jsx b/packages/concordia-app/src/views/Profile/index.jsx index 65090ad..6a3165c 100644 --- a/packages/concordia-app/src/views/Profile/index.jsx +++ b/packages/concordia-app/src/views/Profile/index.jsx @@ -1,7 +1,7 @@ import React, { memo, useEffect, useMemo, useState, } from 'react'; -import { Container, Header, Tab } from 'semantic-ui-react'; +import { Container, Tab } from 'semantic-ui-react'; import { useSelector } from 'react-redux'; import { useHistory, useRouteMatch } from 'react-router'; import { useTranslation } from 'react-i18next'; @@ -9,7 +9,7 @@ import { FORUM_CONTRACT } from 'concordia-shared/src/constants/contracts/Contrac import { drizzle } from '../../redux/store'; import CustomLoadingTabPane from '../../components/CustomLoadingTabPane'; import ProfileTopicList from './ProfileTopicList'; -import PostList from '../../components/PostList'; +import ProfilePostList from './ProfilePostList'; import GeneralTab from './GeneralTab'; import { GENERAL_TAB, POSTS_TAB, TOPICS_TAB } from '../../constants/ProfileTabs'; import './styles.css'; @@ -80,13 +80,9 @@ const Profile = () => { ), [profileAddress, username]); - const postsTab = useMemo(() => (userPostIds.length > 0 - ? () - : ( -
- {t('profile.user.has.no.posts.header.message', { user: username })} -
- )), [t, userPostIds, username]); + const postsTab = useMemo(() => ( + + ), [profileAddress, username]); const panes = useMemo(() => { const generalTabPane = ({generalTab});