import React, { Component } from 'react'; import PropTypes from 'prop-types'; import { bindActionCreators } from 'redux'; import { push } from 'connected-react-router'; import { Link, withRouter } from 'react-router-dom'; import { connect } from 'react-redux'; import ContentLoader from 'react-content-loader'; import { Button, Divider, Grid, Icon, Label, Transition } from 'semantic-ui-react'; import TimeAgo from 'react-timeago'; import UserAvatar from 'react-user-avatar'; import ReactMarkdown from 'react-markdown'; import epochTimeConverter from '../helpers/EpochTimeConverter'; class Post extends Component { constructor(props) { super(props); const { getFocus } = props; this.getBlockchainData = this.getBlockchainData.bind(this); this.fetchPost = this.fetchPost.bind(this); if (getFocus) { this.postRef = React.createRef(); } this.state = { fetchPostDataStatus: 'pending', postContent: '', postSubject: '', readyForAnimation: false, animateOnToggle: true }; } componentDidMount() { this.getBlockchainData(); } componentDidUpdate() { this.getBlockchainData(); const { readyForAnimation } = this.state; if (readyForAnimation) { if (this.postRef) { setTimeout(() => { this.postRef.current.scrollIntoView( { block: 'start', behavior: 'smooth' }, ); setTimeout(() => { this.setState({ animateOnToggle: false }); }, 300); }, 100); this.setState({ readyForAnimation: false }); } } } getBlockchainData() { const { fetchPostDataStatus } = this.state; const { postData, orbitDB, postID } = this.props; if (postData && orbitDB.orbitdb && fetchPostDataStatus === 'pending') { this.setState({ fetchPostDataStatus: 'fetching' }); this.fetchPost(postID); } } async fetchPost(postID) { const { user, postData, orbitDB } = this.props; let orbitPostData; if (postData.value[1] === user.address) { orbitPostData = orbitDB.postsDB.get(postID); } else { const fullAddress = `/orbitdb/${postData.value[0]}/posts`; const store = await orbitDB.orbitdb.keyvalue(fullAddress); await store.load(); const localOrbitData = store.get(postID); if (localOrbitData) { orbitPostData = localOrbitData; } else { // Wait until we have received something from the network store.events.on('replicated', () => { orbitPostData = store.get(postID); }); } } this.setState({ postContent: orbitPostData.content, postSubject: orbitPostData.subject, fetchPostDataStatus: 'fetched', readyForAnimation: true }); } render() { const { animateOnToggle, postSubject, postContent } = this.state; const { avatarUrl, postIndex, navigateTo, postData, postID } = this.props; const avatarView = (postData ? ( ) : (
) ); return (
# {postIndex} {postData !== null ? ( { event.stopPropagation(); }} > {avatarView} ) : avatarView }
{postData !== null ? postData.value[2] : 'Username' } {postData !== null && ( ) }
{postSubject === '' ? ( ) : `Subject: ${ postSubject}` }
{postContent !== '' ? : ( ) }
); } } Post.propTypes = { getFocus: PropTypes.bool.isRequired, user: PropTypes.object.isRequired, orbitDB: PropTypes.object.isRequired, avatarUrl: PropTypes.string, postIndex: PropTypes.number.isRequired, navigateTo: PropTypes.func.isRequired, postData: PropTypes.object, postID: PropTypes.string.isRequired }; const mapDispatchToProps = dispatch => bindActionCreators({ navigateTo: location => push(location) }, dispatch); const mapStateToProps = state => ({ user: state.user, orbitDB: state.orbit }); export default withRouter(connect(mapStateToProps, mapDispatchToProps)(Post));