diff --git a/packages/concordia-app/package.json b/packages/concordia-app/package.json
index afb2d22..cdb1b9c 100644
--- a/packages/concordia-app/package.json
+++ b/packages/concordia-app/package.json
@@ -34,6 +34,7 @@
"i18next-http-backend": "^1.0.21",
"level": "~6.0.1",
"lodash": "^4.17.20",
+ "moment": "^2.29.1",
"orbit-db-identity-provider": "~0.3.1",
"prop-types": "~15.7.2",
"react": "~16.13.1",
diff --git a/packages/concordia-app/public/locales/en/translation.json b/packages/concordia-app/public/locales/en/translation.json
index c55754f..107d60d 100644
--- a/packages/concordia-app/public/locales/en/translation.json
+++ b/packages/concordia-app/public/locales/en/translation.json
@@ -19,5 +19,8 @@
"topic.create.form.subject.field.placeholder": "Subject",
"topic.create.form.message.field.label": "First post message",
"topic.create.form.message.field.placeholder": "Message",
- "topic.create.form.post.button": "Post"
+ "topic.create.form.post.button": "Post",
+ "topic.list.row.author.date": "Posted by {{author}}, {{timeAgo}}",
+ "topic.list.row.number.of.replies": "{{numberOfReplies}} replies",
+ "topic.list.row.topic.id": "#{{id}}"
}
\ No newline at end of file
diff --git a/packages/concordia-app/src/components/TopicList/TopicListRow/index.jsx b/packages/concordia-app/src/components/TopicList/TopicListRow/index.jsx
index fec1ce1..7f83bc3 100644
--- a/packages/concordia-app/src/components/TopicList/TopicListRow/index.jsx
+++ b/packages/concordia-app/src/components/TopicList/TopicListRow/index.jsx
@@ -1,34 +1,42 @@
import React, {
memo, useEffect, useMemo, useState,
} from 'react';
-import { List } from 'semantic-ui-react';
+import {
+ Dimmer, Grid, List, Loader, Placeholder,
+} from 'semantic-ui-react';
import PropTypes from 'prop-types';
+import { useTranslation } from 'react-i18next';
+import moment from 'moment';
+import { useHistory } from 'react-router';
import { useDispatch, useSelector } from 'react-redux';
import { FETCH_USER_DATABASE } from '../../../redux/actions/peerDbReplicationActions';
import { breeze } from '../../../redux/store';
+import './styles.css';
const { orbit } = breeze;
const TopicListRow = (props) => {
- const { id: topicId, topicCallHash } = props;
+ const { id: topicId, topicCallHash, loading } = props;
const getTopicResults = useSelector((state) => state.contracts.Forum.getTopic);
const [numberOfReplies, setNumberOfReplies] = useState(null);
const [username, setUsername] = useState(null);
const [topicAuthor, setTopicAuthor] = useState(null);
- const [timestamp, setTimestamp] = useState(null);
+ const [timeAgo, setTimeAgo] = useState(null);
const [topicSubject, setTopicSubject] = useState(null);
const userAddress = useSelector((state) => state.user.address);
const topics = useSelector((state) => state.orbitData.topics);
const dispatch = useDispatch();
+ const history = useHistory();
+ const { t } = useTranslation();
useEffect(() => {
- if (topicCallHash && getTopicResults[topicCallHash] !== undefined) {
+ if (!loading && topicCallHash && getTopicResults[topicCallHash] !== undefined) {
setTopicAuthor(getTopicResults[topicCallHash].value[0]);
setUsername(getTopicResults[topicCallHash].value[1]);
- setTimestamp(getTopicResults[topicCallHash].value[2] * 1000);
+ setTimeAgo(moment(getTopicResults[topicCallHash].value[2] * 1000).fromNow());
setNumberOfReplies(getTopicResults[topicCallHash].value[3].length);
}
- }, [getTopicResults, topicCallHash]);
+ }, [getTopicResults, loading, topicCallHash]);
useEffect(() => {
if (topicAuthor && userAddress !== topicAuthor) {
@@ -45,30 +53,68 @@ const TopicListRow = (props) => {
.find((topic) => topic.id === topicId);
if (topicFound) {
- setTopicSubject(topicFound);
+ setTopicSubject(topicFound.subject);
}
}, [topicId, topics]);
- return useMemo(() => (
- <>
-
-
- {topicSubject && topicSubject.subject}
-
-
- {username}
- {numberOfReplies}
- {' '}
- replies
- {timestamp}
-
- >
- ), [topicSubject, username, numberOfReplies, timestamp]);
+ return useMemo(() => {
+ const handleTopicClick = () => {
+ history.push(`/topics/${topicId}`);
+ };
+
+ return (
+
+
+
+
+
+
+
+
+
+ {topicSubject !== null
+ ? topicSubject
+ : }
+
+
+
+ {t('topic.list.row.topic.id', { id: topicId })}
+
+
+
+
+
+
+
+ {username !== null && timeAgo !== null
+ ? t('topic.list.row.author.date', { author: username, timeAgo })
+ : }
+
+
+ {numberOfReplies !== null
+ ? (
+
+ {t('topic.list.row.number.of.replies', { numberOfReplies })}
+
+ )
+ : }
+
+
+
+
+
+ );
+ }, [history, loading, numberOfReplies, t, timeAgo, topicId, topicSubject, username]);
+};
+
+TopicListRow.defaultProps = {
+ loading: false,
};
TopicListRow.propTypes = {
id: PropTypes.number.isRequired,
- topicCallHash: PropTypes.string.isRequired,
+ topicCallHash: PropTypes.string,
+ loading: PropTypes.bool,
};
TopicListRow.whyDidYouRender = true;
diff --git a/packages/concordia-app/src/components/TopicList/TopicListRow/styles.css b/packages/concordia-app/src/components/TopicList/TopicListRow/styles.css
new file mode 100644
index 0000000..8e808b6
--- /dev/null
+++ b/packages/concordia-app/src/components/TopicList/TopicListRow/styles.css
@@ -0,0 +1,8 @@
+.topic-metadata {
+ font-size: 12px !important;
+ font-weight: initial;
+}
+
+.list-item {
+ text-align: start;
+}
diff --git a/packages/concordia-app/src/components/TopicList/index.jsx b/packages/concordia-app/src/components/TopicList/index.jsx
index b7ac6c5..89786df 100644
--- a/packages/concordia-app/src/components/TopicList/index.jsx
+++ b/packages/concordia-app/src/components/TopicList/index.jsx
@@ -4,11 +4,7 @@ import React, {
import PropTypes from 'prop-types';
import { useSelector } from 'react-redux';
import { List } from 'semantic-ui-react';
-import { useHistory } from 'react-router';
import TopicListRow from './TopicListRow';
-import { PLACEHOLDER_TYPE_TOPIC } from '../../constants/PlaceholderTypes';
-import Placeholder from '../Placeholder';
-import './styles.css';
import { drizzle } from '../../redux/store';
const { contracts: { Forum: { methods: { getTopic: { cacheCall: getTopicChainData } } } } } = drizzle;
@@ -18,7 +14,6 @@ const TopicList = (props) => {
const [getTopicCallHashes, setGetTopicCallHashes] = useState([]);
const drizzleInitialized = useSelector((state) => state.drizzleStatus.initialized);
const drizzleInitializationFailed = useSelector((state) => state.drizzleStatus.failed);
- const history = useHistory();
useEffect(() => {
if (drizzleInitialized && !drizzleInitializationFailed) {
@@ -44,27 +39,15 @@ const TopicList = (props) => {
.map((topicId) => {
const topicHash = getTopicCallHashes.find((getTopicCallHash) => getTopicCallHash.id === topicId);
- const handleTopicClick = () => {
- history.push(`/topics/${topicId}`);
- };
-
- if (topicHash) {
- return (
-
-
-
- );
- }
-
return (
- handleTopicClick(topicId)}>
-
-
+
);
- }), [getTopicCallHashes, history, topicIds]);
+ }), [getTopicCallHashes, topicIds]);
return (
diff --git a/packages/concordia-app/src/components/TopicList/styles.css b/packages/concordia-app/src/components/TopicList/styles.css
index 5e461d1..ac3c53c 100644
--- a/packages/concordia-app/src/components/TopicList/styles.css
+++ b/packages/concordia-app/src/components/TopicList/styles.css
@@ -1,7 +1,3 @@
#topic-list{
height: 100%;
}
-
-.list-item {
- text-align: start;
-}
\ No newline at end of file
diff --git a/yarn.lock b/yarn.lock
index 1a2a1ea..31f30d9 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -11942,6 +11942,11 @@ mock-fs@^4.1.0:
resolved "https://registry.yarnpkg.com/mock-fs/-/mock-fs-4.13.0.tgz#31c02263673ec3789f90eb7b6963676aa407a598"
integrity sha512-DD0vOdofJdoaRNtnWcrXe6RQbpHkPPmtqGq14uRX0F8ZKJ5nv89CVTYl/BZdppDxBDaV0hl75htg3abpEWlPZA==
+moment@^2.29.1:
+ version "2.29.1"
+ resolved "https://registry.yarnpkg.com/moment/-/moment-2.29.1.tgz#b2be769fa31940be9eeea6469c075e35006fa3d3"
+ integrity sha512-kHmoybcPV8Sqy59DwNDY3Jefr64lK/by/da0ViFcuA4DH0vQg5Q6Ze5VimxkfQNSC+Mls/Kx53s7TjP1RhFEDQ==
+
mortice@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/mortice/-/mortice-2.0.0.tgz#7be171409c2115561ba3fc035e4527f9082eefde"