diff --git a/packages/concordia-app/src/components/PostCreate/index.jsx b/packages/concordia-app/src/components/PostCreate/index.jsx index be2ba0b..aadf71d 100644 --- a/packages/concordia-app/src/components/PostCreate/index.jsx +++ b/packages/concordia-app/src/components/PostCreate/index.jsx @@ -8,19 +8,29 @@ import PropTypes from 'prop-types'; import { useTranslation } from 'react-i18next'; import { useDispatch, useSelector } from 'react-redux'; 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 { USER_PROFILE_PICTURE } from '../../constants/UserDatabaseKeys'; -import { breeze } from '../../redux/store'; +import { breeze, drizzle } from '../../redux/store'; 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 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 [postContent, setPostContent] = 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 userAddress = useSelector((state) => state.user.address); const users = useSelector((state) => state.orbitData.users); @@ -68,13 +78,49 @@ const PostCreate = (props) => { } }, [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(() => { - if (postSubject === '' || postContent === '') { + if (postSubject === '') { + setPostSubjectInputEmptySubmit(true); + return; + } + + if (postContent === '') { + setPostContentInputEmptySubmit(true); return; } setPosting(true); - }, [postContent, postSubject]); + setCreatePostCacheSendStackId(createPost.cacheSend(...[topicId], { from: account })); + }, [account, postContent, postSubject, topicId]); return ( @@ -104,11 +150,12 @@ const PostCreate = (props) => { name="postSubject" className="subject-input" size="mini" + error={postSubjectInputEmptySubmit} value={postSubject} onChange={handleInputChange} /> - {t('post.list.row.post.id', { id: postId })} + {t('post.list.row.post.id', { id: postIndexInTopic })} @@ -120,6 +167,7 @@ const PostCreate = (props) => { className="content-input" size="mini" rows={4} + error={postContentInputEmptySubmit} value={postContent} onChange={handleInputChange} /> @@ -132,8 +180,8 @@ const PostCreate = (props) => { animated type="button" color="green" - disabled={posting} - onClick={savePost || postSubject === '' || postContent === ''} + disabled={posting || postSubject === '' || postContent === ''} + onClick={savePost} > {t('post.create.form.send.button')} @@ -151,7 +199,8 @@ const PostCreate = (props) => { }; PostCreate.propTypes = { - id: PropTypes.number.isRequired, + topicId: PropTypes.number.isRequired, + postIndexInTopic: PropTypes.number.isRequired, initialPostSubject: PropTypes.string.isRequired, }; diff --git a/packages/concordia-app/src/components/PostList/PostListRow/index.jsx b/packages/concordia-app/src/components/PostList/PostListRow/index.jsx index 06fe0a0..1b7e666 100644 --- a/packages/concordia-app/src/components/PostList/PostListRow/index.jsx +++ b/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 PostListRow = (props) => { - const { id: postId, postCallHash, loading } = props; + const { + id: postId, postIndexInTopic, postCallHash, loading, + } = props; const getPostResults = useSelector((state) => state.contracts.Forum.getPost); const [postAuthorAddress, setPostAuthorAddress] = useState(null); const [postAuthor, setPostAuthor] = useState(null); @@ -114,7 +116,7 @@ const PostListRow = (props) => { ? postSubject : } - {t('post.list.row.post.id', { id: postId })} + {t('post.list.row.post.id', { id: postIndexInTopic })} {postAuthor !== null && timeAgo !== null @@ -133,7 +135,7 @@ const PostListRow = (props) => { - ), [loading, postAuthor, postAuthorMeta, postId, postContent, postSubject, t, timeAgo]); + ), [loading, postAuthor, postAuthorMeta, postContent, postIndexInTopic, postSubject, t, timeAgo]); }; PostListRow.defaultProps = { @@ -142,6 +144,7 @@ PostListRow.defaultProps = { PostListRow.propTypes = { id: PropTypes.number.isRequired, + postIndexInTopic: PropTypes.number.isRequired, postCallHash: PropTypes.string, loading: PropTypes.bool, }; diff --git a/packages/concordia-app/src/components/PostList/index.jsx b/packages/concordia-app/src/components/PostList/index.jsx index 2c93daf..c4fe149 100644 --- a/packages/concordia-app/src/components/PostList/index.jsx +++ b/packages/concordia-app/src/components/PostList/index.jsx @@ -40,12 +40,13 @@ const PostList = (props) => { return null; } return postIds - .map((postId) => { + .map((postId, index) => { const postHash = getPostCallHashes.find((getPostCallHash) => getPostCallHash.id === postId); return ( { {topicSubject !== null && postIds !== null && ( )}