|
@ -2,10 +2,11 @@ import React, { useEffect, useState } from 'react'; |
|
|
import PropTypes from 'prop-types'; |
|
|
import PropTypes from 'prop-types'; |
|
|
import { useDispatch, useSelector } from 'react-redux'; |
|
|
import { useDispatch, useSelector } from 'react-redux'; |
|
|
import { |
|
|
import { |
|
|
Container, Dimmer, Icon, Image, Placeholder, Step, |
|
|
Container, Dimmer, Divider, Header, Icon, Placeholder, Segment, |
|
|
} from 'semantic-ui-react'; |
|
|
} from 'semantic-ui-react'; |
|
|
import { Link } from 'react-router-dom'; |
|
|
import { Link } from 'react-router-dom'; |
|
|
import { useHistory } from 'react-router'; |
|
|
import { useHistory } from 'react-router'; |
|
|
|
|
|
|
|
|
import TimeAgo from 'react-timeago'; |
|
|
import TimeAgo from 'react-timeago'; |
|
|
import { breeze, drizzle } from '../../../redux/store'; |
|
|
import { breeze, drizzle } from '../../../redux/store'; |
|
|
import { FETCH_USER_DATABASE } from '../../../redux/actions/peerDbReplicationActions'; |
|
|
import { FETCH_USER_DATABASE } from '../../../redux/actions/peerDbReplicationActions'; |
|
@ -13,7 +14,6 @@ import './styles.css'; |
|
|
import PostList from '../../../components/PostList'; |
|
|
import PostList from '../../../components/PostList'; |
|
|
import { TOPICS_DATABASE, USER_DATABASE } from '../../../constants/orbit/OrbitDatabases'; |
|
|
import { TOPICS_DATABASE, USER_DATABASE } from '../../../constants/orbit/OrbitDatabases'; |
|
|
import determineKVAddress from '../../../utils/orbitUtils'; |
|
|
import determineKVAddress from '../../../utils/orbitUtils'; |
|
|
import { USER_PROFILE_PICTURE } from '../../../constants/orbit/UserDatabaseKeys'; |
|
|
|
|
|
import { TOPIC_SUBJECT } from '../../../constants/orbit/TopicsDatabaseKeys'; |
|
|
import { TOPIC_SUBJECT } from '../../../constants/orbit/TopicsDatabaseKeys'; |
|
|
import PostCreate from '../../../components/PostCreate'; |
|
|
import PostCreate from '../../../components/PostCreate'; |
|
|
import { FORUM_CONTRACT } from '../../../constants/contracts/ContractNames'; |
|
|
import { FORUM_CONTRACT } from '../../../constants/contracts/ContractNames'; |
|
@ -36,9 +36,9 @@ const TopicView = (props) => { |
|
|
const [getTopicCallHash, setGetTopicCallHash] = useState([]); |
|
|
const [getTopicCallHash, setGetTopicCallHash] = useState([]); |
|
|
const [topicAuthorAddress, setTopicAuthorAddress] = useState(initialTopicAuthorAddress || null); |
|
|
const [topicAuthorAddress, setTopicAuthorAddress] = useState(initialTopicAuthorAddress || null); |
|
|
const [topicAuthor, setTopicAuthor] = useState(initialTopicAuthor || null); |
|
|
const [topicAuthor, setTopicAuthor] = useState(initialTopicAuthor || null); |
|
|
const [topicAuthorMeta, setTopicAuthorMeta] = useState(null); |
|
|
|
|
|
const [timestamp, setTimestamp] = useState(initialTimestamp || null); |
|
|
const [timestamp, setTimestamp] = useState(initialTimestamp || null); |
|
|
const [postIds, setPostIds] = useState(initialPostIds || null); |
|
|
const [postIds, setPostIds] = useState(initialPostIds || null); |
|
|
|
|
|
const [numberOfReplies, setReplyCount] = useState(0); |
|
|
const [topicSubject, setTopicSubject] = useState(null); |
|
|
const [topicSubject, setTopicSubject] = useState(null); |
|
|
const history = useHistory(); |
|
|
const history = useHistory(); |
|
|
const dispatch = useDispatch(); |
|
|
const dispatch = useDispatch(); |
|
@ -66,7 +66,9 @@ const TopicView = (props) => { |
|
|
setTopicAuthorAddress(getTopicResults[getTopicCallHash].value[0]); |
|
|
setTopicAuthorAddress(getTopicResults[getTopicCallHash].value[0]); |
|
|
setTopicAuthor(getTopicResults[getTopicCallHash].value[1]); |
|
|
setTopicAuthor(getTopicResults[getTopicCallHash].value[1]); |
|
|
setTimestamp(getTopicResults[getTopicCallHash].value[2] * 1000); |
|
|
setTimestamp(getTopicResults[getTopicCallHash].value[2] * 1000); |
|
|
setPostIds(getTopicResults[getTopicCallHash].value[3].map((postId) => parseInt(postId, 10))); |
|
|
const postIds = getTopicResults[getTopicCallHash].value[3].map((postId) => parseInt(postId, 10)); |
|
|
|
|
|
setPostIds(postIds); |
|
|
|
|
|
setReplyCount(postIds.length - 1); |
|
|
|
|
|
|
|
|
const topicFound = topics |
|
|
const topicFound = topics |
|
|
.find((topic) => topic.id === topicId); |
|
|
.find((topic) => topic.id === topicId); |
|
@ -89,9 +91,7 @@ const TopicView = (props) => { |
|
|
const userFound = users |
|
|
const userFound = users |
|
|
.find((user) => user.id === userOrbitAddress); |
|
|
.find((user) => user.id === userOrbitAddress); |
|
|
|
|
|
|
|
|
if (userFound) { |
|
|
if (!userFound) { |
|
|
setTopicAuthorMeta(userFound); |
|
|
|
|
|
} else { |
|
|
|
|
|
dispatch({ |
|
|
dispatch({ |
|
|
type: FETCH_USER_DATABASE, |
|
|
type: FETCH_USER_DATABASE, |
|
|
orbit, |
|
|
orbit, |
|
@ -115,66 +115,43 @@ const TopicView = (props) => { |
|
|
} |
|
|
} |
|
|
}, [topicId, topics]); |
|
|
}, [topicId, topics]); |
|
|
|
|
|
|
|
|
|
|
|
const stopClickPropagation = (event) => { |
|
|
|
|
|
event.stopPropagation(); |
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
return ( |
|
|
return ( |
|
|
<Container id="topic-container" textAlign="center"> |
|
|
<Container id="topic-container" textAlign="center"> |
|
|
|
|
|
<Segment> |
|
|
<Dimmer.Dimmable |
|
|
<Dimmer.Dimmable |
|
|
blurring |
|
|
blurring |
|
|
dimmed={topicAuthorAddress === null && topicAuthor === null && timestamp === null} |
|
|
dimmed={topicAuthorAddress === null && topicAuthor === null && timestamp === null} |
|
|
> |
|
|
> |
|
|
<Step.Group fluid> |
|
|
<Header as="h2"> |
|
|
<Step key="topic-header-step-user"> |
|
|
|
|
|
<Link to={`/users/${topicAuthorAddress}`}> |
|
|
|
|
|
{topicAuthorMeta !== null && topicAuthorMeta[USER_PROFILE_PICTURE] |
|
|
|
|
|
? ( |
|
|
|
|
|
<Image |
|
|
|
|
|
avatar |
|
|
|
|
|
src={topicAuthorMeta[USER_PROFILE_PICTURE]} |
|
|
|
|
|
/> |
|
|
|
|
|
) |
|
|
|
|
|
: ( |
|
|
|
|
|
<Icon |
|
|
|
|
|
name="user circle" |
|
|
|
|
|
size="big" |
|
|
|
|
|
inverted |
|
|
|
|
|
color="black" |
|
|
|
|
|
/> |
|
|
|
|
|
)} |
|
|
|
|
|
</Link> |
|
|
|
|
|
<Step.Content> |
|
|
|
|
|
<Step.Title> |
|
|
|
|
|
<Link to={`/users/${topicAuthorAddress}`}> |
|
|
|
|
|
{topicAuthor || ( |
|
|
|
|
|
<Placeholder id="author-placeholder" inverted> |
|
|
|
|
|
<Placeholder.Line length="full" /> |
|
|
|
|
|
</Placeholder> |
|
|
|
|
|
)} |
|
|
|
|
|
</Link> |
|
|
|
|
|
</Step.Title> |
|
|
|
|
|
</Step.Content> |
|
|
|
|
|
</Step> |
|
|
|
|
|
<Step key="topic-header-step-title"> |
|
|
|
|
|
<Step.Content> |
|
|
|
|
|
<Step.Title> |
|
|
|
|
|
{topicSubject || ( |
|
|
{topicSubject || ( |
|
|
<Placeholder id="subject-placeholder"> |
|
|
<Placeholder id="subject-placeholder"> |
|
|
<Placeholder.Line length="full" /> |
|
|
<Placeholder.Line /> |
|
|
</Placeholder> |
|
|
|
|
|
)} |
|
|
|
|
|
</Step.Title> |
|
|
|
|
|
<Step.Description> |
|
|
|
|
|
{timestamp |
|
|
|
|
|
? <TimeAgo date={timestamp} /> |
|
|
|
|
|
: ( |
|
|
|
|
|
<Placeholder id="date-placeholder"> |
|
|
|
|
|
<Placeholder.Line length="full" /> |
|
|
|
|
|
</Placeholder> |
|
|
</Placeholder> |
|
|
)} |
|
|
)} |
|
|
</Step.Description> |
|
|
</Header> |
|
|
</Step.Content> |
|
|
|
|
|
</Step> |
|
|
<div id="topic-metadata"> |
|
|
</Step.Group> |
|
|
<Icon name="calendar alternate" fitted /> |
|
|
|
|
|
|
|
|
|
|
|
<TimeAgo date={timestamp} /> |
|
|
|
|
|
|
|
|
|
|
|
<Icon name="user" fitted /> |
|
|
|
|
|
|
|
|
|
|
|
<Link to={`/users/${topicAuthorAddress}`} onClick={stopClickPropagation}>{ topicAuthor }</Link> |
|
|
|
|
|
|
|
|
|
|
|
<Icon name="reply" fitted /> |
|
|
|
|
|
|
|
|
|
|
|
{ numberOfReplies } |
|
|
|
|
|
</div> |
|
|
|
|
|
<Divider /> |
|
|
</Dimmer.Dimmable> |
|
|
</Dimmer.Dimmable> |
|
|
<PostList postIds={postIds || []} loading={postIds === null} focusOnPost={focusOnPost} /> |
|
|
<PostList postIds={postIds || []} loading={postIds === null} focusOnPost={focusOnPost} /> |
|
|
|
|
|
</Segment> |
|
|
|
|
|
|
|
|
{topicSubject !== null && postIds !== null && hasSignedUp && ( |
|
|
{topicSubject !== null && postIds !== null && hasSignedUp && ( |
|
|
<PostCreate |
|
|
<PostCreate |
|
|
topicId={topicId} |
|
|
topicId={topicId} |
|
|