Browse Source

feat: add pagination to Profile PostList

develop
Ezerous 4 years ago
parent
commit
e5211ac91d
  1. 15
      packages/concordia-app/src/components/PostList/index.jsx
  2. 89
      packages/concordia-app/src/views/Profile/ProfilePostList/index.jsx
  3. 14
      packages/concordia-app/src/views/Profile/index.jsx

15
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) => {
<Dimmer.Dimmable as={Feed} blurring dimmed={loading} id="post-list" size="large">
<Loader active={loading} />
{posts}
<PaginationComponent onPageChange={onPageChange} numberOfItems={numberOfItems} />
</Dimmer.Dimmable>
);
};

89
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 (
<PostList
postIds={postIds}
numberOfItems={userPostCount}
onPageChange={handlePageChange}
/>
);
}
if (userPostCount === 0) {
return (
<Header textAlign="center" as="h2">
{t('profile.user.has.no.posts.header.message', { user: username })}
</Header>
);
}
return null;
}, [t, postIds, userPostCount, username]);
};
export default ProfilePostList;

14
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 = () => {
<ProfileTopicList username={username} profileAddress={profileAddress} />
), [profileAddress, username]);
const postsTab = useMemo(() => (userPostIds.length > 0
? (<PostList postIds={userPostIds} />)
: (
<Header textAlign="center" as="h2">
{t('profile.user.has.no.posts.header.message', { user: username })}
</Header>
)), [t, userPostIds, username]);
const postsTab = useMemo(() => (
<ProfilePostList username={username} profileAddress={profileAddress} />
), [profileAddress, username]);
const panes = useMemo(() => {
const generalTabPane = (<CustomLoadingTabPane loading={loading}>{generalTab}</CustomLoadingTabPane>);

Loading…
Cancel
Save