diff --git a/packages/concordia-app/package.json b/packages/concordia-app/package.json index f911dc0..aefa23f 100644 --- a/packages/concordia-app/package.json +++ b/packages/concordia-app/package.json @@ -32,6 +32,7 @@ "apexcharts": "^3.26.0", "concordia-contracts": "~0.1.0", "concordia-shared": "~0.1.0", + "crypto-js": "~4.0.0", "i18next": "^19.8.3", "i18next-browser-languagedetector": "^6.0.1", "i18next-http-backend": "^1.0.21", diff --git a/packages/concordia-app/public/locales/en/translation.json b/packages/concordia-app/public/locales/en/translation.json index f9799bd..151d1eb 100644 --- a/packages/concordia-app/public/locales/en/translation.json +++ b/packages/concordia-app/public/locales/en/translation.json @@ -22,6 +22,12 @@ "edit.information.modal.form.profile.picture.field.placeholder": "URL", "edit.information.modal.form.submit.button": "Submit", "edit.information.modal.title": "Edit profile information", + "poll.create.question.field.label": "Poll Question", + "poll.create.question.field.placeholder": "Question", + "poll.create.allow.vote.changes.field.label": "Allow vote changes", + "poll.create.option.field.label": "Option #{{id}}", + "poll.create.option.field.placeholder": "Option #{{id}}", + "poll.create.add.option.button": "Add Option", "post.create.form.send.button": "Post", "post.form.content.field.placeholder": "Message", "post.form.subject.field.placeholder": "Subject", @@ -34,6 +40,7 @@ "profile.general.tab.number.of.posts.row.title": "Number of posts:", "profile.general.tab.number.of.topics.row.title": "Number of topics created:", "profile.general.tab.posts.db.address.row.title": "PostsDB:", + "profile.general.tab.polls.db.address.row.title": "PollsDB:", "profile.general.tab.registration.date.row.title": "Member since:", "profile.general.tab.save.info.button.title": "Save information", "profile.general.tab.title": "General", @@ -73,6 +80,8 @@ "topic.create.form.post.button": "Create Topic", "topic.create.form.subject.field.label": "Topic subject", "topic.create.form.subject.field.placeholder": "Subject", + "topic.create.form.add.poll.button": "Add Poll", + "topic.create.form.remove.poll.button": "Remove Poll", "topic.list.row.topic.id": "#{{id}}", "topic.poll.tab.graph.title": "Results", "topic.poll.tab.results.votes.count": "{{totalVotes}} votes casted", diff --git a/packages/concordia-app/src/components/PollCreate/PollOption/index.jsx b/packages/concordia-app/src/components/PollCreate/PollOption/index.jsx new file mode 100644 index 0000000..c64dc0f --- /dev/null +++ b/packages/concordia-app/src/components/PollCreate/PollOption/index.jsx @@ -0,0 +1,50 @@ +import React, { memo } from 'react'; +import PropTypes from 'prop-types'; +import { + Button, Form, Icon, Input, +} from 'semantic-ui-react'; +import { useTranslation } from 'react-i18next'; +import './styles.css'; + +const PollOption = (props) => { + const { + id, removable, onChange, onRemove, + } = props; + const { t } = useTranslation(); + + return ( + + + onChange(e, id)} + /> + {removable + && ( + + )} + + ); +}; + +PollOption.propTypes = { + id: PropTypes.number.isRequired, + onChange: PropTypes.func, + onRemove: PropTypes.func, + removable: PropTypes.bool, +}; + +export default memo(PollOption); diff --git a/packages/concordia-app/src/components/PollCreate/PollOption/styles.css b/packages/concordia-app/src/components/PollCreate/PollOption/styles.css new file mode 100644 index 0000000..2516280 --- /dev/null +++ b/packages/concordia-app/src/components/PollCreate/PollOption/styles.css @@ -0,0 +1,4 @@ +.form-poll-option > .form-input{ + width: 50% !important; + margin-right: 0.25em; +} diff --git a/packages/concordia-app/src/components/PollCreate/index.jsx b/packages/concordia-app/src/components/PollCreate/index.jsx new file mode 100644 index 0000000..f631cdc --- /dev/null +++ b/packages/concordia-app/src/components/PollCreate/index.jsx @@ -0,0 +1,190 @@ +import React, { + useMemo, useState, useCallback, useEffect, forwardRef, useImperativeHandle, +} from 'react'; +import PropTypes from 'prop-types'; +import { useSelector } from 'react-redux'; +import { useTranslation } from 'react-i18next'; +import { + Button, Checkbox, Form, Icon, Input, +} from 'semantic-ui-react'; +import { VOTING_CONTRACT } from 'concordia-shared/src/constants/contracts/ContractNames'; +import { POLL_CREATED_EVENT } from 'concordia-shared/src/constants/contracts/events/VotingContractEvents'; +import { POLLS_DATABASE } from 'concordia-shared/src/constants/orbit/OrbitDatabases'; +import PollOption from './PollOption'; +import { breeze, drizzle } from '../../redux/store'; +import { TRANSACTION_ERROR, TRANSACTION_SUCCESS } from '../../constants/TransactionStatus'; +import './styles.css'; +import { POLL_OPTIONS, POLL_QUESTION } from '../../constants/orbit/PollsDatabaseKeys'; +import generateHash from '../../utils/hashUtils'; + +const { contracts: { [VOTING_CONTRACT]: { methods: { createPoll } } } } = drizzle; +const { orbit: { stores } } = breeze; + +const PollCreate = forwardRef((props, ref) => { + const { account, onChange, onCreated } = props; + const transactionStack = useSelector((state) => state.transactionStack); + const transactions = useSelector((state) => state.transactions); + const [createPollCacheSendStackId, setCreatePollCacheSendStackId] = useState(''); + const [question, setQuestion] = useState(''); + const [options, setOptions] = useState( + [{ id: 1 }, { id: 2 }], + ); + const [optionValues, setOptionValues] = useState( + ['', ''], + ); + const [optionsNextId, setOptionsNextId] = useState(3); + const [allowVoteChanges, setAllowVoteChanges] = useState(false); + const [creating, setCreating] = useState(false); + const [errored, setErrored] = useState(false); + const { t } = useTranslation(); + + const handlePollQuestionChange = useCallback((event) => { + const newQuestion = event.target.value.trim(); + if (newQuestion !== question) setQuestion(newQuestion); + }, [question]); + + const addOption = useCallback((e) => { + e.currentTarget.blur(); + const newOptions = [...options, { id: optionsNextId, removable: true }]; + const newOptionValues = [...optionValues, '']; + setOptionsNextId(optionsNextId + 1); + setOptions(newOptions); + setOptionValues(newOptionValues); + }, [optionValues, options, optionsNextId]); + + const removeOption = useCallback((e, id) => { + e.currentTarget.blur(); + const newOptions = [...options]; + newOptions.splice(id - 1, 1); + const newOptionValues = [...optionValues]; + newOptionValues.splice(id - 1, 1); + setOptions(newOptions); + setOptionValues(newOptionValues); + }, [optionValues, options]); + + const handlePollOptionChange = useCallback((event, id) => { + const newValue = event.target.value.trim(); + if (newValue !== optionValues[id - 1]) { + const newOptionValues = [...optionValues]; + newOptionValues[id - 1] = newValue; + setOptionValues(newOptionValues); + } + }, [optionValues]); + + const pollOptions = useMemo(() => options + .map((option, index) => { + const { id, removable } = option; + return ( + + ); + }), [handlePollOptionChange, options, removeOption]); + + useEffect(() => { + onChange({ question, optionValues }); + }, [onChange, optionValues, question]); + + const handleCheckboxChange = useCallback((event, data) => { + setAllowVoteChanges(data.checked); + }, []); + + useImperativeHandle(ref, () => ({ + createPoll(topicId) { + setCreating(true); + const dataHash = generateHash(JSON.stringify({ question, optionValues })); + setCreatePollCacheSendStackId(createPoll.cacheSend( + ...[topicId, options.length, dataHash, allowVoteChanges], { from: account }, + )); + }, + pollCreating() { + return creating; + }, + pollErrored() { + return errored; + }, + })); + + useEffect(() => { + if (creating && transactionStack && transactionStack[createPollCacheSendStackId] + && transactions[transactionStack[createPollCacheSendStackId]]) { + if (transactions[transactionStack[createPollCacheSendStackId]].status === TRANSACTION_ERROR) { + setErrored(true); + setCreating(false); + onCreated(false); + } else if (transactions[transactionStack[createPollCacheSendStackId]].status === TRANSACTION_SUCCESS) { + const { + receipt: { + events: { + [POLL_CREATED_EVENT]: { + returnValues: { + topicID: topicId, + }, + }, + }, + }, + } = transactions[transactionStack[createPollCacheSendStackId]]; + + const pollsDb = Object.values(stores).find((store) => store.dbname === POLLS_DATABASE); + + pollsDb + .put(topicId, { [POLL_QUESTION]: question, [POLL_OPTIONS]: optionValues }) + .then(() => { + onCreated(topicId); + }) + .catch((reason) => { + console.error(reason); + setErrored(true); + setCreating(false); + onCreated(false); + }); + } + } + }, [createPollCacheSendStackId, creating, onCreated, optionValues, question, transactionStack, transactions]); + + return useMemo(() => ( +
+ + + + + + + + {pollOptions} + +
+ ), [addOption, handleCheckboxChange, handlePollQuestionChange, pollOptions, t]); +}); + +PollCreate.propTypes = { + onChange: PropTypes.func, + onCreated: PropTypes.func, +}; + +export default PollCreate; diff --git a/packages/concordia-app/src/components/PollCreate/styles.css b/packages/concordia-app/src/components/PollCreate/styles.css new file mode 100644 index 0000000..9fc624c --- /dev/null +++ b/packages/concordia-app/src/components/PollCreate/styles.css @@ -0,0 +1,10 @@ +.poll-create { + padding-top: 1em; + padding-bottom: 1em; +} + +.poll-create .checkbox > label, label:focus, label:hover{ + color: white !important; + font-weight: 700; +} + diff --git a/packages/concordia-app/src/components/PostList/PostVoting/index.jsx b/packages/concordia-app/src/components/PostList/PostVoting/index.jsx index 52033d8..a4a780d 100644 --- a/packages/concordia-app/src/components/PostList/PostVoting/index.jsx +++ b/packages/concordia-app/src/components/PostList/PostVoting/index.jsx @@ -77,9 +77,9 @@ const PostVoting = (props) => { if (voting) return; setVoting(true); - if ((ownVote === CHOICE_DEFAULT || ownVote === CHOICE_DOWN) && choice === CHOICE_UP) setVoteCacheSendStackId(upvote.cacheSend(...[postId], { from: userAccount })); - else if ((ownVote === CHOICE_DEFAULT || ownVote === CHOICE_UP) && choice === CHOICE_DOWN) setVoteCacheSendStackId(downvote.cacheSend(...[postId], { from: userAccount })); - else if ((ownVote === CHOICE_UP && choice === CHOICE_UP) || (ownVote === CHOICE_DOWN && choice === CHOICE_DOWN)) setVoteCacheSendStackId(unvote.cacheSend(...[postId], { from: userAccount })); + if ((ownVote === CHOICE_DEFAULT || ownVote === CHOICE_DOWN) && choice === CHOICE_UP) setVoteCacheSendStackId(upvote.cacheSend(postId, { from: userAccount })); + else if ((ownVote === CHOICE_DEFAULT || ownVote === CHOICE_UP) && choice === CHOICE_DOWN) setVoteCacheSendStackId(downvote.cacheSend(postId, { from: userAccount })); + else if ((ownVote === CHOICE_UP && choice === CHOICE_UP) || (ownVote === CHOICE_DOWN && choice === CHOICE_DOWN)) setVoteCacheSendStackId(unvote.cacheSend(postId, { from: userAccount })); else setVoting(false); }, [ownVote, postId, userAccount, voting]); diff --git a/packages/concordia-app/src/constants/orbit/PollsDatabaseKeys.js b/packages/concordia-app/src/constants/orbit/PollsDatabaseKeys.js new file mode 100644 index 0000000..b1f6c72 --- /dev/null +++ b/packages/concordia-app/src/constants/orbit/PollsDatabaseKeys.js @@ -0,0 +1,9 @@ +export const POLL_QUESTION = 'question'; +export const POLL_OPTIONS = 'options'; + +const pollsDatabaseKeys = [ + POLL_QUESTION, + POLL_OPTIONS, +]; + +export default pollsDatabaseKeys; diff --git a/packages/concordia-app/src/redux/actions/contractEventActions.js b/packages/concordia-app/src/redux/actions/contractEventActions.js index b736e31..c665e8a 100644 --- a/packages/concordia-app/src/redux/actions/contractEventActions.js +++ b/packages/concordia-app/src/redux/actions/contractEventActions.js @@ -7,6 +7,10 @@ import { import { USER_VOTED_POST_EVENT, } from 'concordia-shared/src/constants/contracts/events/PostVotingContractEvents'; +import { + POLL_CREATED_EVENT, + USER_VOTED_POLL_EVENT, +} from 'concordia-shared/src/constants/contracts/events/VotingContractEvents'; export const FORUM_EVENT_USER_SIGNED_UP = 'FORUM_EVENT_USER_SIGNED_UP'; export const FORUM_EVENT_USERNAME_UPDATED = 'FORUM_EVENT_USERNAME_UPDATED'; @@ -15,12 +19,17 @@ export const FORUM_EVENT_POST_CREATED = 'FORUM_EVENT_POST_CREATED'; export const POST_VOTING_USER_VOTED_POST = 'POST_VOTING_USER_VOTED_POST'; +export const VOTING_POLL_CREATED = 'VOTING_POLL_CREATED'; +export const VOTING_USER_VOTED_POLL = 'VOTING_USER_VOTED_POLL'; + const eventActionMap = { [USER_SIGNED_UP_EVENT]: FORUM_EVENT_USER_SIGNED_UP, [USERNAME_UPDATED_EVENT]: FORUM_EVENT_USERNAME_UPDATED, [TOPIC_CREATED_EVENT]: FORUM_EVENT_TOPIC_CREATED, [POST_CREATED_EVENT]: FORUM_EVENT_POST_CREATED, [USER_VOTED_POST_EVENT]: POST_VOTING_USER_VOTED_POST, + [POLL_CREATED_EVENT]: VOTING_POLL_CREATED, + [USER_VOTED_POLL_EVENT]: VOTING_USER_VOTED_POLL, }; export default eventActionMap; diff --git a/packages/concordia-app/src/utils/hashUtils.js b/packages/concordia-app/src/utils/hashUtils.js new file mode 100644 index 0000000..3a6d269 --- /dev/null +++ b/packages/concordia-app/src/utils/hashUtils.js @@ -0,0 +1,7 @@ +import sha256 from 'crypto-js/sha256'; + +function generateHash(message) { + return sha256(message).toString().substring(0, 16); +} + +export default generateHash; diff --git a/packages/concordia-app/src/views/Profile/GeneralTab/index.jsx b/packages/concordia-app/src/views/Profile/GeneralTab/index.jsx index 0b710fa..eb956e3 100644 --- a/packages/concordia-app/src/views/Profile/GeneralTab/index.jsx +++ b/packages/concordia-app/src/views/Profile/GeneralTab/index.jsx @@ -23,6 +23,7 @@ const GeneralTab = (props) => { const [userInfoOrbitAddress, setUserInfoOrbitAddress] = useState(null); const [userTopicsOrbitAddress, setUserTopicsOrbitAddress] = useState(null); const [userPostsOrbitAddress, setUserPostsOrbitAddress] = useState(null); + const [userPollsOrbitAddress, setUserPollsOrbitAddress] = useState(null); const [profileMetadataFetched, setProfileMetadataFetched] = useState(false); const [userAvatarUrl, setUserAvatarUrl] = useState(null); const [userLocation, setUserLocation] = useState(null); @@ -41,10 +42,11 @@ const GeneralTab = (props) => { userAddress: profileAddress, }))) .then((values) => { - const [userOrbitAddress, topicsOrbitAddress, postsOrbitAddress] = values; + const [userOrbitAddress, topicsOrbitAddress, postsOrbitAddress, pollsOrbitAddress] = values; setUserInfoOrbitAddress(userOrbitAddress); setUserTopicsOrbitAddress(topicsOrbitAddress); setUserPostsOrbitAddress(postsOrbitAddress); + setUserPollsOrbitAddress(pollsOrbitAddress); const userFound = users .find((user) => user.id === userOrbitAddress); @@ -141,6 +143,12 @@ const GeneralTab = (props) => { {userPostsOrbitAddress || ()} + + {t('profile.general.tab.polls.db.address.row.title')} + + {userPollsOrbitAddress || ()} + + {t('profile.general.tab.number.of.topics.row.title')} @@ -192,7 +200,7 @@ const GeneralTab = (props) => { {isSelf && editInformationModal} - ), [editInformationModal, isSelf, numberOfPosts, numberOfTopics, profileAddress, profileMetadataFetched, t, userAvatarUrl, userInfoOrbitAddress, userLocationCell, userPostsOrbitAddress, userRegistrationTimestamp, userTopicsOrbitAddress, username]); + ), [editInformationModal, isSelf, numberOfPosts, numberOfTopics, profileAddress, profileMetadataFetched, t, userAvatarUrl, userInfoOrbitAddress, userLocationCell, userPollsOrbitAddress, userPostsOrbitAddress, userRegistrationTimestamp, userTopicsOrbitAddress, username]); }; GeneralTab.defaultProps = { diff --git a/packages/concordia-app/src/views/Topic/TopicCreate/index.jsx b/packages/concordia-app/src/views/Topic/TopicCreate/index.jsx index f9867a2..620339c 100644 --- a/packages/concordia-app/src/views/Topic/TopicCreate/index.jsx +++ b/packages/concordia-app/src/views/Topic/TopicCreate/index.jsx @@ -1,5 +1,5 @@ import React, { - useCallback, useEffect, useState, + useCallback, useEffect, useRef, useState, } from 'react'; import { Button, Container, Form, Header, Icon, Input, TextArea, @@ -15,6 +15,7 @@ import { TRANSACTION_ERROR, TRANSACTION_SUCCESS } from '../../../constants/Trans import { TOPIC_SUBJECT } from '../../../constants/orbit/TopicsDatabaseKeys'; import { POST_CONTENT } from '../../../constants/orbit/PostsDatabaseKeys'; import './styles.css'; +import PollCreate from '../../../components/PollCreate'; const { contracts: { [FORUM_CONTRACT]: { methods: { createTopic } } } } = drizzle; const { orbit: { stores } } = breeze; @@ -25,9 +26,12 @@ const TopicCreate = (props) => { const transactions = useSelector((state) => state.transactions); const [subjectInput, setSubjectInput] = useState(''); const [contentInput, setContentInput] = useState(''); + const [newTopicId, setNewTopicId] = useState(null); const [createTopicCacheSendStackId, setCreateTopicCacheSendStackId] = useState(''); const [posting, setPosting] = useState(false); - + const [pollAdded, setPollAdded] = useState(false); + const [pollFilled, setPollFilled] = useState(false); + const pollCreateRef = useRef(); const history = useHistory(); const { t } = useTranslation(); @@ -48,9 +52,18 @@ const TopicCreate = (props) => { } }, [posting]); + const goToTopic = useCallback((topicId) => { + if (topicId) history.push(`/topics/${topicId}`); + else { + console.error('Error creating poll!'); + history.push(`/topics/${newTopicId}`); + } + }, [history, newTopicId]); + useEffect(() => { if (posting && transactionStack && transactionStack[createTopicCacheSendStackId] - && transactions[transactionStack[createTopicCacheSendStackId]]) { + && transactions[transactionStack[createTopicCacheSendStackId]] + && (!pollAdded || (!pollCreateRef.current.pollCreating() && !pollCreateRef.current.pollErrored()))) { if (transactions[transactionStack[createTopicCacheSendStackId]].status === TRANSACTION_ERROR) { setPosting(false); } else if (transactions[transactionStack[createTopicCacheSendStackId]].status === TRANSACTION_SUCCESS) { @@ -67,6 +80,12 @@ const TopicCreate = (props) => { }, } = transactions[transactionStack[createTopicCacheSendStackId]]; + setNewTopicId(topicId); + + if (pollAdded) { + pollCreateRef.current.createPoll(topicId); + } + const topicsDb = Object.values(stores).find((store) => store.dbname === TOPICS_DATABASE); const postsDb = Object.values(stores).find((store) => store.dbname === POSTS_DATABASE); @@ -77,14 +96,15 @@ const TopicCreate = (props) => { [POST_CONTENT]: contentInput, })) .then(() => { - history.push(`/topics/${topicId}`); + if (!pollAdded) goToTopic(); }) .catch((reason) => { console.error(reason); }); } } - }, [createTopicCacheSendStackId, history, contentInput, posting, subjectInput, transactionStack, transactions]); + }, [createTopicCacheSendStackId, + contentInput, posting, subjectInput, transactionStack, transactions, pollAdded, goToTopic]); const validateAndPost = useCallback(() => { if (subjectInput === '' || contentInput === '') { @@ -95,8 +115,24 @@ const TopicCreate = (props) => { setCreateTopicCacheSendStackId(createTopic.cacheSend(...[], { from: account })); }, [account, contentInput, subjectInput]); + const togglePollCreate = useCallback((e) => { + e.currentTarget.blur(); + if (!pollAdded) { + setPollAdded(true); + } else { + setPollAdded(false); + } + }, [pollAdded]); + + const handlePollCreateChanges = useCallback((pollCreateState) => { + const { question, optionValues } = pollCreateState; + if (question !== '' && !optionValues.includes('')) { + setPollFilled(true); + } else setPollFilled(false); + }, []); + return ( - +
New Topic
@@ -126,13 +162,43 @@ const TopicCreate = (props) => { onChange={handleSubjectInputChange} /> + + {pollAdded && ( + + )} -
); diff --git a/packages/concordia-app/src/views/Topic/TopicCreate/styles.css b/packages/concordia-app/src/views/Topic/TopicCreate/styles.css index 2bd6916..b8cdfec 100644 --- a/packages/concordia-app/src/views/Topic/TopicCreate/styles.css +++ b/packages/concordia-app/src/views/Topic/TopicCreate/styles.css @@ -17,5 +17,5 @@ #create-topic-button { float: right; - margin: 1rem 0 4rem 0; + margin: 0 0 4rem 0; } diff --git a/packages/concordia-pinner/src/utils/orbitUtils.js b/packages/concordia-pinner/src/utils/orbitUtils.js index d1c3326..c8e4404 100644 --- a/packages/concordia-pinner/src/utils/orbitUtils.js +++ b/packages/concordia-pinner/src/utils/orbitUtils.js @@ -2,6 +2,7 @@ import OrbitDB from 'orbit-db'; import Identities from 'orbit-db-identity-provider'; import { EthereumContractIdentityProvider } from '@ezerous/eth-identity-provider'; import Web3 from 'web3'; +import { databaseNames } from 'concordia-shared/src/constants/orbit/OrbitDatabases'; import { ORBIT_DIRECTORY_DEFAULT } from '../constants'; import { logger } from './logger'; @@ -31,11 +32,7 @@ export const createOrbitInstance = async (ipfs, contractAddress) => { }; export const getPeerDatabases = async (orbit, userAddresses) => Promise.all(userAddresses - .flatMap((userAddress) => [ - determineKVAddress({ orbit, dbName: 'user', userAddress }), - determineKVAddress({ orbit, dbName: 'posts', userAddress }), - determineKVAddress({ orbit, dbName: 'topics', userAddress }), - ])); + .flatMap((userAddress) => databaseNames.map((dbName) => determineKVAddress({ orbit, dbName, userAddress })))); export const openKVDBs = async (orbit, databases) => { databases diff --git a/packages/concordia-shared/src/constants/contracts/events/VotingContractEvents.js b/packages/concordia-shared/src/constants/contracts/events/VotingContractEvents.js new file mode 100644 index 0000000..8ab8a85 --- /dev/null +++ b/packages/concordia-shared/src/constants/contracts/events/VotingContractEvents.js @@ -0,0 +1,13 @@ +const POLL_CREATED_EVENT = 'PollCreated'; +const USER_VOTED_POLL_EVENT = 'UserVotedPoll'; + +const votingContractEvents = Object.freeze([ + POLL_CREATED_EVENT, + USER_VOTED_POLL_EVENT, +]); + +module.exports = { + POLL_CREATED_EVENT, + USER_VOTED_POLL_EVENT, + votingContractEvents, +}; diff --git a/packages/concordia-shared/src/constants/contracts/events/index.js b/packages/concordia-shared/src/constants/contracts/events/index.js index ddc86bd..91b2fb4 100644 --- a/packages/concordia-shared/src/constants/contracts/events/index.js +++ b/packages/concordia-shared/src/constants/contracts/events/index.js @@ -1,10 +1,12 @@ const { forumContractEvents } = require('./ForumContractEvents'); const { postVotingContractEvents } = require('./PostVotingContractEvents'); -const { FORUM_CONTRACT, POST_VOTING_CONTRACT } = require('../ContractNames'); +const { votingContractEvents } = require('./VotingContractEvents'); +const { FORUM_CONTRACT, POST_VOTING_CONTRACT, VOTING_CONTRACT } = require('../ContractNames'); const appEvents = Object.freeze({ [FORUM_CONTRACT]: forumContractEvents, [POST_VOTING_CONTRACT]: postVotingContractEvents, + [VOTING_CONTRACT]: votingContractEvents, }); module.exports = appEvents; diff --git a/packages/concordia-shared/src/constants/orbit/OrbitDatabases.js b/packages/concordia-shared/src/constants/orbit/OrbitDatabases.js index 75048f6..085288a 100644 --- a/packages/concordia-shared/src/constants/orbit/OrbitDatabases.js +++ b/packages/concordia-shared/src/constants/orbit/OrbitDatabases.js @@ -1,6 +1,7 @@ const USER_DATABASE = 'user'; const TOPICS_DATABASE = 'topics'; const POSTS_DATABASE = 'posts'; +const POLLS_DATABASE = 'polls'; const databases = [ { @@ -15,11 +16,19 @@ const databases = [ address: POSTS_DATABASE, type: 'keyvalue', }, + { + address: POLLS_DATABASE, + type: 'keyvalue', + }, ]; +const databaseNames = [USER_DATABASE, TOPICS_DATABASE, POSTS_DATABASE, POLLS_DATABASE]; + module.exports = Object.freeze({ USER_DATABASE, TOPICS_DATABASE, POSTS_DATABASE, + POLLS_DATABASE, databases, + databaseNames, }); diff --git a/yarn.lock b/yarn.lock index 03d6ff4..61b8ce3 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5083,6 +5083,11 @@ crypto-browserify@3.12.0, crypto-browserify@^3.11.0: randombytes "^2.0.0" randomfill "^1.0.3" +crypto-js@~4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/crypto-js/-/crypto-js-4.0.0.tgz#2904ab2677a9d042856a2ea2ef80de92e4a36dcc" + integrity sha512-bzHZN8Pn+gS7DQA6n+iUmBfl0hO5DJq++QP3U6uTucDtk/0iGpXd/Gg7CGR0p8tJhofJyaKoWBuJI4eAO00BBg== + crypto-random-string@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/crypto-random-string/-/crypto-random-string-2.0.0.tgz#ef2a7a966ec11083388369baa02ebead229b30d5"