diff --git a/packages/concordia-app/src/components/PostList/index.jsx b/packages/concordia-app/src/components/PostList/index.jsx
index 9b118c3..c42a8c6 100644
--- a/packages/concordia-app/src/components/PostList/index.jsx
+++ b/packages/concordia-app/src/components/PostList/index.jsx
@@ -51,11 +51,13 @@ const PostList = (props) => {
}, [focusOnPost, getPostCallHashes, loading, postIds]);
return (
-
-
- {posts}
+ <>
+
+
+ {posts}
+
-
+ >
);
};
diff --git a/packages/concordia-app/src/views/Topic/TopicView/TopicPostList/index.jsx b/packages/concordia-app/src/views/Topic/TopicView/TopicPostList/index.jsx
new file mode 100644
index 0000000..1b5a771
--- /dev/null
+++ b/packages/concordia-app/src/views/Topic/TopicView/TopicPostList/index.jsx
@@ -0,0 +1,82 @@
+import React, {
+ useEffect, useMemo, useState,
+} from 'react';
+import { useSelector } from 'react-redux';
+import { FORUM_CONTRACT } from 'concordia-shared/src/constants/contracts/ContractNames';
+import PostList from '../../../../components/PostList';
+import { ITEMS_PER_PAGE } from '../../../../components/PaginationComponent';
+import { drizzle } from '../../../../redux/store';
+
+const {
+ contracts: {
+ [FORUM_CONTRACT]: {
+ methods: {
+ getTopicPostCount: { cacheCall: getTopicPostCountChainData },
+ getTopicPosts: { cacheCall: getTopicPostsChainData },
+ },
+ },
+ },
+} = drizzle;
+
+const TopicPostList = (props) => {
+ const {
+ topicId, loading, focusOnPost,
+ } = props;
+ const [pageNumber, setPageNumber] = useState(1);
+
+ const [topicPostCount, setTopicPostCount] = useState(null);
+ const [postIds, setPostIds] = useState([]);
+
+ const [getTopicPostCountCallHash, setGetTopicPostCountCallHash] = useState(null);
+ const [getTopicPostsCallHash, setGetTopicPostsCallHash] = useState(null);
+
+ const getTopicPostCountResult = useSelector((state) => state.contracts[FORUM_CONTRACT].getTopicPostCount[getTopicPostCountCallHash]);
+ const getTopicPostsResult = useSelector((state) => state.contracts[FORUM_CONTRACT].getTopicPosts[getTopicPostsCallHash]);
+
+ useEffect(() => {
+ if (getTopicPostCountCallHash === null) {
+ setGetTopicPostCountCallHash(getTopicPostCountChainData(topicId));
+ }
+ }, [getTopicPostCountCallHash, topicId]);
+
+ useEffect(() => {
+ if (topicPostCount !== null && topicPostCount !== 0) {
+ const startIndex = Math.max(topicPostCount - ITEMS_PER_PAGE * pageNumber, 0);
+ const endIndex = topicPostCount - ITEMS_PER_PAGE * (pageNumber - 1) - 1;
+ setGetTopicPostsCallHash(getTopicPostsChainData(topicId, startIndex, endIndex));
+ }
+ }, [pageNumber, topicId, topicPostCount]);
+
+ useEffect(() => {
+ if (getTopicPostCountResult) {
+ setTopicPostCount(parseInt(getTopicPostCountResult.value, 10));
+ }
+ }, [getTopicPostCountResult, topicPostCount]);
+
+ useEffect(() => {
+ if (getTopicPostsResult) {
+ setPostIds(getTopicPostsResult.value.slice().reverse().map(Number));
+ }
+ }, [getTopicPostsResult, topicPostCount]);
+
+ const handlePageChange = (event, data) => {
+ setPageNumber(data.activePage);
+ };
+
+ return useMemo(() => {
+ if (postIds.length && postIds.length !== 0) {
+ return (
+
+ );
+ }
+ return null;
+ }, [postIds, topicPostCount, loading, focusOnPost]);
+};
+
+export default TopicPostList;
diff --git a/packages/concordia-app/src/views/Topic/TopicView/index.jsx b/packages/concordia-app/src/views/Topic/TopicView/index.jsx
index f77715a..a602db3 100644
--- a/packages/concordia-app/src/views/Topic/TopicView/index.jsx
+++ b/packages/concordia-app/src/views/Topic/TopicView/index.jsx
@@ -11,7 +11,7 @@ import { TOPICS_DATABASE, USER_DATABASE } from 'concordia-shared/src/constants/o
import { breeze, drizzle } from '../../../redux/store';
import { FETCH_USER_DATABASE } from '../../../redux/actions/peerDbReplicationActions';
import './styles.css';
-import PostList from '../../../components/PostList';
+import TopicPostList from './TopicPostList';
import determineKVAddress from '../../../utils/orbitUtils';
import { TOPIC_SUBJECT } from '../../../constants/orbit/TopicsDatabaseKeys';
import PostCreate from '../../../components/PostCreate';
@@ -24,8 +24,6 @@ const TopicView = (props) => {
topicId, topicAuthorAddress: initialTopicAuthorAddress, topicAuthor: initialTopicAuthor,
timestamp: initialTimestamp, postIds: initialPostIds, focusOnPost,
} = props;
- const drizzleInitialized = useSelector((state) => state.drizzleStatus.initialized);
- const drizzleInitializationFailed = useSelector((state) => state.drizzleStatus.failed);
const userAddress = useSelector((state) => state.user.address);
const hasSignedUp = useSelector((state) => state.user.hasSignedUp);
const getTopicResults = useSelector((state) => state.contracts[FORUM_CONTRACT].getTopic);
@@ -47,12 +45,10 @@ const TopicView = (props) => {
|| timestamp === null
|| postIds === null;
- if (drizzleInitialized && !drizzleInitializationFailed && shouldGetTopicDataFromChain) {
+ if (shouldGetTopicDataFromChain) {
setGetTopicCallHash(getTopicChainData(topicId));
}
- }, [
- drizzleInitializationFailed, drizzleInitialized, postIds, timestamp, topicAuthor, topicAuthorAddress, topicId,
- ]);
+ }, [postIds, timestamp, topicAuthor, topicAuthorAddress, topicId]);
useEffect(() => {
if (getTopicCallHash && getTopicResults && getTopicResults[getTopicCallHash]) {
@@ -149,7 +145,7 @@ const TopicView = (props) => {
-
+
{topicSubject !== null && postIds !== null && hasSignedUp && (
diff --git a/packages/concordia-app/src/views/Topic/TopicView/styles.css b/packages/concordia-app/src/views/Topic/TopicView/styles.css
index bea6ab3..2b3a8d0 100644
--- a/packages/concordia-app/src/views/Topic/TopicView/styles.css
+++ b/packages/concordia-app/src/views/Topic/TopicView/styles.css
@@ -1,5 +1,6 @@
#topic-container {
height: auto !important;
+ text-align: center;
}
#topic-header {
diff --git a/packages/concordia-contracts/contracts/Forum.sol b/packages/concordia-contracts/contracts/Forum.sol
index 12ab81a..7f04d33 100644
--- a/packages/concordia-contracts/contracts/Forum.sol
+++ b/packages/concordia-contracts/contracts/Forum.sol
@@ -188,9 +188,22 @@ contract Forum {
);
}
- function getTopicPosts(uint topicID) public view returns (uint[] memory) {
+ function getTopicPostCount(uint topicID) public view returns (uint) {
require(topicExists(topicID), TOPIC_DOES_NOT_EXIST);
- return topics[topicID].postIDs;
+ return topics[topicID].postIDs.length;
+ }
+
+ function getTopicPosts(uint topicID, uint startIndex, uint endIndex) public view returns (uint[] memory) {
+ require(topicExists(topicID), TOPIC_DOES_NOT_EXIST);
+ require(startIndex <= endIndex && topics[topicID].postIDs.length > endIndex, INVALID_RANGE);
+ uint length = endIndex - startIndex + 1;
+ uint[] memory topicPosts = new uint[](length);
+ uint counter = 0;
+ for (uint i = startIndex; i <= endIndex; i++) {
+ topicPosts[counter] = topics[topicID].postIDs[i];
+ counter++;
+ }
+ return topicPosts;
}
function getTopicAuthor(uint topicID) public view returns (address) {