Browse Source

Add contract and orbit interactions on posting

develop
Apostolos Fanakis 4 years ago
parent
commit
f5fc3ffdf7
  1. 67
      packages/concordia-app/src/components/PostCreate/index.jsx
  2. 9
      packages/concordia-app/src/components/PostList/PostListRow/index.jsx
  3. 3
      packages/concordia-app/src/components/PostList/index.jsx
  4. 3
      packages/concordia-app/src/views/Topic/TopicView/index.jsx

67
packages/concordia-app/src/components/PostCreate/index.jsx

@ -8,19 +8,29 @@ import PropTypes from 'prop-types';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
import { useDispatch, useSelector } from 'react-redux'; import { useDispatch, useSelector } from 'react-redux';
import determineKVAddress from '../../utils/orbitUtils'; import determineKVAddress from '../../utils/orbitUtils';
import { USER_DATABASE } from '../../constants/OrbitDatabases'; import { POSTS_DATABASE, USER_DATABASE } from '../../constants/OrbitDatabases';
import { FETCH_USER_DATABASE } from '../../redux/actions/peerDbReplicationActions'; import { FETCH_USER_DATABASE } from '../../redux/actions/peerDbReplicationActions';
import { USER_PROFILE_PICTURE } from '../../constants/UserDatabaseKeys'; import { USER_PROFILE_PICTURE } from '../../constants/UserDatabaseKeys';
import { breeze } from '../../redux/store'; import { breeze, drizzle } from '../../redux/store';
import './styles.css'; import './styles.css';
import { TRANSACTION_ERROR, TRANSACTION_SUCCESS } from '../../constants/TransactionStatus';
import { POST_CONTENT, POST_SUBJECT } from '../../constants/PostsDatabaseKeys';
const { contracts: { Forum: { methods: { createPost } } } } = drizzle;
const { orbit } = breeze; const { orbit } = breeze;
const PostCreate = (props) => { const PostCreate = (props) => {
const { id: postId, initialPostSubject } = props; const {
topicId, postIndexInTopic, initialPostSubject, account,
} = props;
const transactionStack = useSelector((state) => state.transactionStack);
const transactions = useSelector((state) => state.transactions);
const [postSubject, setPostSubject] = useState(initialPostSubject); const [postSubject, setPostSubject] = useState(initialPostSubject);
const [postContent, setPostContent] = useState(''); const [postContent, setPostContent] = useState('');
const [userProfilePictureUrl, setUserProfilePictureUrl] = useState(); const [userProfilePictureUrl, setUserProfilePictureUrl] = useState();
const [postSubjectInputEmptySubmit, setPostSubjectInputEmptySubmit] = useState(false);
const [postContentInputEmptySubmit, setPostContentInputEmptySubmit] = useState(false);
const [createPostCacheSendStackId, setCreatePostCacheSendStackId] = useState('');
const [posting, setPosting] = useState(false); const [posting, setPosting] = useState(false);
const userAddress = useSelector((state) => state.user.address); const userAddress = useSelector((state) => state.user.address);
const users = useSelector((state) => state.orbitData.users); const users = useSelector((state) => state.orbitData.users);
@ -68,13 +78,49 @@ const PostCreate = (props) => {
} }
}, [posting]); }, [posting]);
useEffect(() => {
if (posting && transactionStack && transactionStack[createPostCacheSendStackId]
&& transactions[transactionStack[createPostCacheSendStackId]]) {
if (transactions[transactionStack[createPostCacheSendStackId]].status === TRANSACTION_ERROR) {
setPosting(false);
} else if (transactions[transactionStack[createPostCacheSendStackId]].status === TRANSACTION_SUCCESS) {
const {
receipt: { events: { PostCreated: { returnValues: { postID: contractPostId } } } },
} = transactions[transactionStack[createPostCacheSendStackId]];
const { stores } = orbit;
const postsDb = Object.values(stores).find((store) => store.dbname === POSTS_DATABASE);
postsDb
.put(contractPostId, {
[POST_SUBJECT]: postSubject,
[POST_CONTENT]: postContent,
}, { pin: true })
.then(() => {
setPostSubject(initialPostSubject);
setPostContent('');
})
.catch((reason) => {
console.log(reason);
});
}
}
}, [createPostCacheSendStackId, postContent, postSubject, posting, transactionStack, transactions]);
const savePost = useCallback(() => { const savePost = useCallback(() => {
if (postSubject === '' || postContent === '') { if (postSubject === '') {
setPostSubjectInputEmptySubmit(true);
return;
}
if (postContent === '') {
setPostContentInputEmptySubmit(true);
return; return;
} }
setPosting(true); setPosting(true);
}, [postContent, postSubject]); setCreatePostCacheSendStackId(createPost.cacheSend(...[topicId], { from: account }));
}, [account, postContent, postSubject, topicId]);
return ( return (
<Feed> <Feed>
@ -104,11 +150,12 @@ const PostCreate = (props) => {
name="postSubject" name="postSubject"
className="subject-input" className="subject-input"
size="mini" size="mini"
error={postSubjectInputEmptySubmit}
value={postSubject} value={postSubject}
onChange={handleInputChange} onChange={handleInputChange}
/> />
<span className="post-summary-meta-index"> <span className="post-summary-meta-index">
{t('post.list.row.post.id', { id: postId })} {t('post.list.row.post.id', { id: postIndexInTopic })}
</span> </span>
</div> </div>
</Feed.Summary> </Feed.Summary>
@ -120,6 +167,7 @@ const PostCreate = (props) => {
className="content-input" className="content-input"
size="mini" size="mini"
rows={4} rows={4}
error={postContentInputEmptySubmit}
value={postContent} value={postContent}
onChange={handleInputChange} onChange={handleInputChange}
/> />
@ -132,8 +180,8 @@ const PostCreate = (props) => {
animated animated
type="button" type="button"
color="green" color="green"
disabled={posting} disabled={posting || postSubject === '' || postContent === ''}
onClick={savePost || postSubject === '' || postContent === ''} onClick={savePost}
> >
<Button.Content visible> <Button.Content visible>
{t('post.create.form.send.button')} {t('post.create.form.send.button')}
@ -151,7 +199,8 @@ const PostCreate = (props) => {
}; };
PostCreate.propTypes = { PostCreate.propTypes = {
id: PropTypes.number.isRequired, topicId: PropTypes.number.isRequired,
postIndexInTopic: PropTypes.number.isRequired,
initialPostSubject: PropTypes.string.isRequired, initialPostSubject: PropTypes.string.isRequired,
}; };

9
packages/concordia-app/src/components/PostList/PostListRow/index.jsx

@ -20,7 +20,9 @@ import { POST_CONTENT, POST_SUBJECT } from '../../../constants/PostsDatabaseKeys
const { orbit } = breeze; const { orbit } = breeze;
const PostListRow = (props) => { const PostListRow = (props) => {
const { id: postId, postCallHash, loading } = props; const {
id: postId, postIndexInTopic, postCallHash, loading,
} = props;
const getPostResults = useSelector((state) => state.contracts.Forum.getPost); const getPostResults = useSelector((state) => state.contracts.Forum.getPost);
const [postAuthorAddress, setPostAuthorAddress] = useState(null); const [postAuthorAddress, setPostAuthorAddress] = useState(null);
const [postAuthor, setPostAuthor] = useState(null); const [postAuthor, setPostAuthor] = useState(null);
@ -114,7 +116,7 @@ const PostListRow = (props) => {
? postSubject ? postSubject
: <Placeholder><Placeholder.Line length="very long" /></Placeholder>} : <Placeholder><Placeholder.Line length="very long" /></Placeholder>}
<span className="post-summary-meta-index"> <span className="post-summary-meta-index">
{t('post.list.row.post.id', { id: postId })} {t('post.list.row.post.id', { id: postIndexInTopic })}
</span> </span>
</div> </div>
{postAuthor !== null && timeAgo !== null {postAuthor !== null && timeAgo !== null
@ -133,7 +135,7 @@ const PostListRow = (props) => {
</Feed.Extra> </Feed.Extra>
</Feed.Content> </Feed.Content>
</Dimmer.Dimmable> </Dimmer.Dimmable>
), [loading, postAuthor, postAuthorMeta, postId, postContent, postSubject, t, timeAgo]); ), [loading, postAuthor, postAuthorMeta, postContent, postIndexInTopic, postSubject, t, timeAgo]);
}; };
PostListRow.defaultProps = { PostListRow.defaultProps = {
@ -142,6 +144,7 @@ PostListRow.defaultProps = {
PostListRow.propTypes = { PostListRow.propTypes = {
id: PropTypes.number.isRequired, id: PropTypes.number.isRequired,
postIndexInTopic: PropTypes.number.isRequired,
postCallHash: PropTypes.string, postCallHash: PropTypes.string,
loading: PropTypes.bool, loading: PropTypes.bool,
}; };

3
packages/concordia-app/src/components/PostList/index.jsx

@ -40,12 +40,13 @@ const PostList = (props) => {
return null; return null;
} }
return postIds return postIds
.map((postId) => { .map((postId, index) => {
const postHash = getPostCallHashes.find((getPostCallHash) => getPostCallHash.id === postId); const postHash = getPostCallHashes.find((getPostCallHash) => getPostCallHash.id === postId);
return ( return (
<PostListRow <PostListRow
id={postId} id={postId}
postIndexInTopic={index + 1}
key={postId} key={postId}
postCallHash={postHash && postHash.hash} postCallHash={postHash && postHash.hash}
loading={postHash === undefined} loading={postHash === undefined}

3
packages/concordia-app/src/views/Topic/TopicView/index.jsx

@ -164,7 +164,8 @@ const TopicView = (props) => {
<PostList postIds={postIds || []} loading={postIds === null} /> <PostList postIds={postIds || []} loading={postIds === null} />
{topicSubject !== null && postIds !== null && ( {topicSubject !== null && postIds !== null && (
<PostCreate <PostCreate
id={postIds.length} topicId={topicId}
postIndexInTopic={postIds.length + 1}
initialPostSubject={topicSubject} initialPostSubject={topicSubject}
/> />
)} )}

Loading…
Cancel
Save