Browse Source

Merge branch 'add-event-saga-fix-user-state' into 'implement-ui'

Add event saga fix user state

See merge request ecentrics/apella!2
develop
Apostolos Fanakis 4 years ago
parent
commit
784b032c09
  1. 5
      packages/concordia-app/src/components/LoadingContainer.jsx
  2. 6
      packages/concordia-app/src/components/PostCreate/index.jsx
  3. 3
      packages/concordia-app/src/components/PostList/PostListRow/index.jsx
  4. 3
      packages/concordia-app/src/components/PostList/index.jsx
  5. 3
      packages/concordia-app/src/components/TopicList/TopicListRow/index.jsx
  6. 3
      packages/concordia-app/src/components/TopicList/index.jsx
  7. 2
      packages/concordia-app/src/constants/ContractNames.js
  8. 13
      packages/concordia-app/src/constants/ForumContractEvents.js
  9. 4
      packages/concordia-app/src/options/drizzleOptions.js
  10. 20
      packages/concordia-app/src/redux/actions/contractEventActions.js
  11. 13
      packages/concordia-app/src/redux/sagas/eventSaga.js
  12. 2
      packages/concordia-app/src/redux/sagas/rootSaga.js
  13. 18
      packages/concordia-app/src/redux/sagas/userSaga.js
  14. 5
      packages/concordia-app/src/views/Home/index.jsx
  15. 5
      packages/concordia-app/src/views/Register/SignUpStep/index.jsx
  16. 3
      packages/concordia-app/src/views/Register/index.jsx
  17. 6
      packages/concordia-app/src/views/Topic/TopicCreate/index.jsx
  18. 5
      packages/concordia-app/src/views/Topic/TopicView/index.jsx

5
packages/concordia-app/src/components/LoadingContainer.jsx

@ -5,6 +5,7 @@ import LoadingComponent from './LoadingComponent';
// CSS // CSS
import '../assets/css/loading-component.css'; import '../assets/css/loading-component.css';
import { FORUM_CONTRACT } from '../constants/ContractNames';
const LoadingContainer = ({ children }) => { const LoadingContainer = ({ children }) => {
const initializing = useSelector((state) => state.drizzleStatus.initializing); const initializing = useSelector((state) => state.drizzleStatus.initializing);
@ -15,8 +16,8 @@ const LoadingContainer = ({ children }) => {
const web3NetworkId = useSelector((state) => state.web3.networkId); const web3NetworkId = useSelector((state) => state.web3.networkId);
const web3NetworkFailed = useSelector((state) => state.web3.networkFailed); const web3NetworkFailed = useSelector((state) => state.web3.networkFailed);
const web3AccountsFailed = useSelector((state) => state.web3.accountsFailed); const web3AccountsFailed = useSelector((state) => state.web3.accountsFailed);
const contractInitialized = useSelector((state) => state.contracts.Forum.initialized); const contractInitialized = useSelector((state) => state.contracts[FORUM_CONTRACT].initialized);
const contractDeployed = useSelector((state) => state.contracts.Forum.deployed); const contractDeployed = useSelector((state) => state.contracts[FORUM_CONTRACT].deployed);
const userFetched = useSelector((state) => state.user.address); const userFetched = useSelector((state) => state.user.address);
if (!window.ethereum) { if (!window.ethereum) {

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

@ -15,8 +15,10 @@ import { breeze, drizzle } from '../../redux/store';
import './styles.css'; import './styles.css';
import { TRANSACTION_ERROR, TRANSACTION_SUCCESS } from '../../constants/TransactionStatus'; import { TRANSACTION_ERROR, TRANSACTION_SUCCESS } from '../../constants/TransactionStatus';
import { POST_CONTENT, POST_SUBJECT } from '../../constants/PostsDatabaseKeys'; import { POST_CONTENT, POST_SUBJECT } from '../../constants/PostsDatabaseKeys';
import { FORUM_CONTRACT } from '../../constants/ContractNames';
import { POST_CREATED_EVENT } from '../../constants/ForumContractEvents';
const { contracts: { Forum: { methods: { createPost } } } } = drizzle; const { contracts: { [FORUM_CONTRACT]: { methods: { createPost } } } } = drizzle;
const { orbit } = breeze; const { orbit } = breeze;
const PostCreate = (props) => { const PostCreate = (props) => {
@ -84,7 +86,7 @@ const PostCreate = (props) => {
setPosting(false); setPosting(false);
} else if (transactions[transactionStack[createPostCacheSendStackId]].status === TRANSACTION_SUCCESS) { } else if (transactions[transactionStack[createPostCacheSendStackId]].status === TRANSACTION_SUCCESS) {
const { const {
receipt: { events: { PostCreated: { returnValues: { postID: contractPostId } } } }, receipt: { events: { [POST_CREATED_EVENT]: { returnValues: { postID: contractPostId } } } },
} = transactions[transactionStack[createPostCacheSendStackId]]; } = transactions[transactionStack[createPostCacheSendStackId]];
const { stores } = orbit; const { stores } = orbit;

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

@ -16,6 +16,7 @@ import { POSTS_DATABASE, USER_DATABASE } from '../../../constants/OrbitDatabases
import determineKVAddress from '../../../utils/orbitUtils'; import determineKVAddress from '../../../utils/orbitUtils';
import { USER_PROFILE_PICTURE } from '../../../constants/UserDatabaseKeys'; import { USER_PROFILE_PICTURE } from '../../../constants/UserDatabaseKeys';
import { POST_CONTENT, POST_SUBJECT } from '../../../constants/PostsDatabaseKeys'; import { POST_CONTENT, POST_SUBJECT } from '../../../constants/PostsDatabaseKeys';
import { FORUM_CONTRACT } from '../../../constants/ContractNames';
const { orbit } = breeze; const { orbit } = breeze;
@ -23,7 +24,7 @@ const PostListRow = (props) => {
const { const {
id: postId, postIndexInTopic, postCallHash, loading, id: postId, postIndexInTopic, postCallHash, loading,
} = props; } = props;
const getPostResults = useSelector((state) => state.contracts.Forum.getPost); const getPostResults = useSelector((state) => state.contracts[FORUM_CONTRACT].getPost);
const [postAuthorAddress, setPostAuthorAddress] = useState(null); const [postAuthorAddress, setPostAuthorAddress] = useState(null);
const [postAuthor, setPostAuthor] = useState(null); const [postAuthor, setPostAuthor] = useState(null);
const [timeAgo, setTimeAgo] = useState(null); const [timeAgo, setTimeAgo] = useState(null);

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

@ -6,8 +6,9 @@ import { useSelector } from 'react-redux';
import { Dimmer, Feed, Loader } from 'semantic-ui-react'; import { Dimmer, Feed, Loader } from 'semantic-ui-react';
import PostListRow from './PostListRow'; import PostListRow from './PostListRow';
import { drizzle } from '../../redux/store'; import { drizzle } from '../../redux/store';
import { FORUM_CONTRACT } from '../../constants/ContractNames';
const { contracts: { Forum: { methods: { getPost: { cacheCall: getPostChainData } } } } } = drizzle; const { contracts: { [FORUM_CONTRACT]: { methods: { getPost: { cacheCall: getPostChainData } } } } } = drizzle;
const PostList = (props) => { const PostList = (props) => {
const { postIds, loading } = props; const { postIds, loading } = props;

3
packages/concordia-app/src/components/TopicList/TopicListRow/index.jsx

@ -17,12 +17,13 @@ import { TOPICS_DATABASE, USER_DATABASE } from '../../../constants/OrbitDatabase
import determineKVAddress from '../../../utils/orbitUtils'; import determineKVAddress from '../../../utils/orbitUtils';
import { USER_PROFILE_PICTURE } from '../../../constants/UserDatabaseKeys'; import { USER_PROFILE_PICTURE } from '../../../constants/UserDatabaseKeys';
import { TOPIC_SUBJECT } from '../../../constants/TopicsDatabaseKeys'; import { TOPIC_SUBJECT } from '../../../constants/TopicsDatabaseKeys';
import { FORUM_CONTRACT } from '../../../constants/ContractNames';
const { orbit } = breeze; const { orbit } = breeze;
const TopicListRow = (props) => { const TopicListRow = (props) => {
const { id: topicId, topicCallHash, loading } = props; const { id: topicId, topicCallHash, loading } = props;
const getTopicResults = useSelector((state) => state.contracts.Forum.getTopic); const getTopicResults = useSelector((state) => state.contracts[FORUM_CONTRACT].getTopic);
const [numberOfReplies, setNumberOfReplies] = useState(null); const [numberOfReplies, setNumberOfReplies] = useState(null);
const [topicAuthorAddress, setTopicAuthorAddress] = useState(null); const [topicAuthorAddress, setTopicAuthorAddress] = useState(null);
const [topicAuthor, setTopicAuthor] = useState(null); const [topicAuthor, setTopicAuthor] = useState(null);

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

@ -6,8 +6,9 @@ import { useSelector } from 'react-redux';
import { List } from 'semantic-ui-react'; import { List } from 'semantic-ui-react';
import TopicListRow from './TopicListRow'; import TopicListRow from './TopicListRow';
import { drizzle } from '../../redux/store'; import { drizzle } from '../../redux/store';
import { FORUM_CONTRACT } from '../../constants/ContractNames';
const { contracts: { Forum: { methods: { getTopic: { cacheCall: getTopicChainData } } } } } = drizzle; const { contracts: { [FORUM_CONTRACT]: { methods: { getTopic: { cacheCall: getTopicChainData } } } } } = drizzle;
const TopicList = (props) => { const TopicList = (props) => {
const { topicIds } = props; const { topicIds } = props;

2
packages/concordia-app/src/constants/ContractNames.js

@ -1 +1 @@
export const FORUM = 'Forum'; export const FORUM_CONTRACT = 'Forum';

13
packages/concordia-app/src/constants/ForumContractEvents.js

@ -0,0 +1,13 @@
export const USER_SIGNED_UP_EVENT = 'UserSignedUp';
export const USERNAME_UPDATED_EVENT = 'UsernameUpdated';
export const TOPIC_CREATED_EVENT = 'TopicCreated';
export const POST_CREATED_EVENT = 'PostCreated';
const forumContractEvents = [
USER_SIGNED_UP_EVENT,
USERNAME_UPDATED_EVENT,
TOPIC_CREATED_EVENT,
POST_CREATED_EVENT,
];
export default forumContractEvents;

4
packages/concordia-app/src/options/drizzleOptions.js

@ -1,6 +1,8 @@
// See also: https://truffleframework.com/docs/drizzle/reference/drizzle-options // See also: https://truffleframework.com/docs/drizzle/reference/drizzle-options
import { contracts } from 'concordia-contracts'; import { contracts } from 'concordia-contracts';
import web3Options from './web3Options'; import web3Options from './web3Options';
import forumContractEvents from '../constants/ForumContractEvents';
import { FORUM_CONTRACT } from '../constants/ContractNames';
const drizzleOptions = { const drizzleOptions = {
web3: { web3: {
@ -8,7 +10,7 @@ const drizzleOptions = {
}, },
contracts, contracts,
events: { events: {
Forum: ['UserSignedUp', 'UsernameUpdated', 'TopicCreated', 'PostCreated'], [FORUM_CONTRACT]: forumContractEvents,
}, },
reloadWindowOnNetworkChange: true, reloadWindowOnNetworkChange: true,
reloadWindowOnAccountChange: true, // We need it to reinitialize breeze and create new Orbit databases reloadWindowOnAccountChange: true, // We need it to reinitialize breeze and create new Orbit databases

20
packages/concordia-app/src/redux/actions/contractEventActions.js

@ -0,0 +1,20 @@
import {
POST_CREATED_EVENT,
TOPIC_CREATED_EVENT,
USER_SIGNED_UP_EVENT,
USERNAME_UPDATED_EVENT,
} from '../../constants/ForumContractEvents';
export const FORUM_EVENT_USER_SIGNED_UP = 'FORUM_EVENT_USER_SIGNED_UP';
export const FORUM_EVENT_USERNAME_UPDATED = 'FORUM_EVENT_USERNAME_UPDATED';
export const FORUM_EVENT_TOPIC_CREATED = 'FORUM_EVENT_TOPIC_CREATED';
export const FORUM_EVENT_POST_CREATED = 'FORUM_EVENT_POST_CREATED';
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,
};
export default eventActionMap;

13
packages/concordia-app/src/redux/sagas/eventSaga.js

@ -0,0 +1,13 @@
import { put, takeEvery } from 'redux-saga/effects';
import { CONTRACT_EVENT_FIRED } from '@ezerous/drizzle/src/contracts/constants';
import eventActionMap from '../actions/contractEventActions';
function* eventBreakDown({ event }) {
yield put({ type: eventActionMap[event.event], event: { ...event } });
}
function* eventSaga() {
yield takeEvery(CONTRACT_EVENT_FIRED, eventBreakDown);
}
export default eventSaga;

2
packages/concordia-app/src/redux/sagas/rootSaga.js

@ -4,11 +4,13 @@ import { breezeSagas } from '@ezerous/breeze';
import orbitSaga from './orbitSaga'; import orbitSaga from './orbitSaga';
import userSaga from './userSaga'; import userSaga from './userSaga';
import peerDbReplicationSaga from './peerDbReplicationSaga'; import peerDbReplicationSaga from './peerDbReplicationSaga';
import eventSaga from './eventSaga';
export default function* root() { export default function* root() {
const sagas = [ const sagas = [
...drizzleSagas, ...drizzleSagas,
...breezeSagas, ...breezeSagas,
eventSaga,
orbitSaga, orbitSaga,
userSaga, userSaga,
peerDbReplicationSaga, peerDbReplicationSaga,

18
packages/concordia-app/src/redux/sagas/userSaga.js

@ -1,13 +1,14 @@
/* eslint-disable no-console */ /* eslint-disable no-console */
import { import {
all, call, put, take, all, call, put, take, takeLatest,
} from 'redux-saga/effects'; } from 'redux-saga/effects';
import { drizzleActions } from '@ezerous/drizzle'; import { drizzleActions } from '@ezerous/drizzle';
import { USER_DATA_UPDATED, USER_DATA_ERROR } from '../actions/userActions'; import { USER_DATA_UPDATED, USER_DATA_ERROR } from '../actions/userActions';
import { FORUM_EVENT_USER_SIGNED_UP } from '../actions/contractEventActions';
import { FORUM_CONTRACT } from '../../constants/ContractNames';
function* fetchUserData({ drizzle, account }) { function* fetchUserData({ drizzle, account }) {
const contract = drizzle.contracts.Forum; const contract = drizzle.contracts[FORUM_CONTRACT];
const transaction = yield call(contract.methods.hasUserSignedUp, account); const transaction = yield call(contract.methods.hasUserSignedUp, account);
try { try {
@ -31,6 +32,15 @@ function* fetchUserData({ drizzle, account }) {
} }
} }
function* userHasSignedUp({ event }) {
yield put({
type: USER_DATA_UPDATED,
...{
address: event.returnValues.userAddress, username: event.returnValues.username,
},
});
}
function* userSaga() { function* userSaga() {
const res = yield all([ const res = yield all([
take(drizzleActions.drizzle.DRIZZLE_INITIALIZED), take(drizzleActions.drizzle.DRIZZLE_INITIALIZED),
@ -38,6 +48,8 @@ function* userSaga() {
]); ]);
yield fetchUserData({ drizzle: res[0].drizzle, account: res[1].accounts[0] }); yield fetchUserData({ drizzle: res[0].drizzle, account: res[1].accounts[0] });
yield takeLatest(FORUM_EVENT_USER_SIGNED_UP, userHasSignedUp);
} }
export default userSaga; export default userSaga;

5
packages/concordia-app/src/views/Home/index.jsx

@ -6,12 +6,13 @@ import { useSelector } from 'react-redux';
import Board from './Board'; import Board from './Board';
import './styles.css'; import './styles.css';
import { drizzle } from '../../redux/store'; import { drizzle } from '../../redux/store';
import { FORUM_CONTRACT } from '../../constants/ContractNames';
const { contracts: { Forum: { methods: { getNumberOfTopics } } } } = drizzle; const { contracts: { [FORUM_CONTRACT]: { methods: { getNumberOfTopics } } } } = drizzle;
const Home = () => { const Home = () => {
const [numberOfTopicsCallHash, setNumberOfTopicsCallHash] = useState(''); const [numberOfTopicsCallHash, setNumberOfTopicsCallHash] = useState('');
const getNumberOfTopicsResults = useSelector((state) => state.contracts.Forum.getNumberOfTopics); const getNumberOfTopicsResults = useSelector((state) => state.contracts[FORUM_CONTRACT].getNumberOfTopics);
useEffect(() => { useEffect(() => {
setNumberOfTopicsCallHash(getNumberOfTopics.cacheCall()); setNumberOfTopicsCallHash(getNumberOfTopics.cacheCall());

5
packages/concordia-app/src/views/Register/SignUpStep/index.jsx

@ -11,13 +11,14 @@ import { useHistory } from 'react-router';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { drizzle } from '../../../redux/store'; import { drizzle } from '../../../redux/store';
import { TRANSACTION_ERROR, TRANSACTION_SUCCESS } from '../../../constants/TransactionStatus'; import { TRANSACTION_ERROR, TRANSACTION_SUCCESS } from '../../../constants/TransactionStatus';
import { FORUM_CONTRACT } from '../../../constants/ContractNames';
const { contracts: { Forum: { methods: { isUserNameTaken, signUp } } } } = drizzle; const { contracts: { [FORUM_CONTRACT]: { methods: { isUserNameTaken, signUp } } } } = drizzle;
const SignUpStep = (props) => { const SignUpStep = (props) => {
const { pushNextStep, account } = props; const { pushNextStep, account } = props;
const user = useSelector((state) => state.user); const user = useSelector((state) => state.user);
const isUserNameTakenResults = useSelector((state) => state.contracts.Forum.isUserNameTaken); const isUserNameTakenResults = useSelector((state) => state.contracts[FORUM_CONTRACT].isUserNameTaken);
const transactionStack = useSelector((state) => state.transactionStack); const transactionStack = useSelector((state) => state.transactionStack);
const transactions = useSelector((state) => state.transactions); const transactions = useSelector((state) => state.transactions);
const [usernameInput, setUsernameInput] = useState(''); const [usernameInput, setUsernameInput] = useState('');

3
packages/concordia-app/src/views/Register/index.jsx

@ -13,6 +13,7 @@ import { REGISTER_STEP_PROFILE_INFORMATION, REGISTER_STEP_SIGNUP } from '../../c
const Register = () => { const Register = () => {
const [currentStep, setCurrentStep] = useState('signup'); const [currentStep, setCurrentStep] = useState('signup');
const user = useSelector((state) => state.user); const user = useSelector((state) => state.user);
const [signingUp] = useState(!user.hasSignedUp);
const history = useHistory(); const history = useHistory();
const { t } = useTranslation(); const { t } = useTranslation();
@ -92,7 +93,7 @@ const Register = () => {
</p> </p>
</Card.Description> </Card.Description>
</Card.Content> </Card.Content>
{user.hasSignedUp {user.hasSignedUp && !signingUp
? ( ? (
<> <>
<Card.Content> <Card.Content>

6
packages/concordia-app/src/views/Topic/TopicCreate/index.jsx

@ -13,8 +13,10 @@ import { TRANSACTION_ERROR, TRANSACTION_SUCCESS } from '../../../constants/Trans
import { POSTS_DATABASE, TOPICS_DATABASE } from '../../../constants/OrbitDatabases'; import { POSTS_DATABASE, TOPICS_DATABASE } from '../../../constants/OrbitDatabases';
import { TOPIC_SUBJECT } from '../../../constants/TopicsDatabaseKeys'; import { TOPIC_SUBJECT } from '../../../constants/TopicsDatabaseKeys';
import { POST_CONTENT, POST_SUBJECT } from '../../../constants/PostsDatabaseKeys'; import { POST_CONTENT, POST_SUBJECT } from '../../../constants/PostsDatabaseKeys';
import { FORUM_CONTRACT } from '../../../constants/ContractNames';
import { TOPIC_CREATED_EVENT } from '../../../constants/ForumContractEvents';
const { contracts: { Forum: { methods: { createTopic } } } } = drizzle; const { contracts: { [FORUM_CONTRACT]: { methods: { createTopic } } } } = drizzle;
const { orbit: { stores } } = breeze; const { orbit: { stores } } = breeze;
const TopicCreate = (props) => { const TopicCreate = (props) => {
@ -55,7 +57,7 @@ const TopicCreate = (props) => {
const { const {
receipt: { receipt: {
events: { events: {
TopicCreated: { [TOPIC_CREATED_EVENT]: {
returnValues: { returnValues: {
topicID: topicId, topicID: topicId,
postID: postId, postID: postId,

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

@ -16,8 +16,9 @@ import determineKVAddress from '../../../utils/orbitUtils';
import { USER_PROFILE_PICTURE } from '../../../constants/UserDatabaseKeys'; import { USER_PROFILE_PICTURE } from '../../../constants/UserDatabaseKeys';
import { TOPIC_SUBJECT } from '../../../constants/TopicsDatabaseKeys'; import { TOPIC_SUBJECT } from '../../../constants/TopicsDatabaseKeys';
import PostCreate from '../../../components/PostCreate'; import PostCreate from '../../../components/PostCreate';
import { FORUM_CONTRACT } from '../../../constants/ContractNames';
const { contracts: { Forum: { methods: { getTopic: { cacheCall: getTopicChainData } } } } } = drizzle; const { contracts: { [FORUM_CONTRACT]: { methods: { getTopic: { cacheCall: getTopicChainData } } } } } = drizzle;
const { orbit } = breeze; const { orbit } = breeze;
const TopicView = (props) => { const TopicView = (props) => {
@ -28,7 +29,7 @@ const TopicView = (props) => {
const drizzleInitialized = useSelector((state) => state.drizzleStatus.initialized); const drizzleInitialized = useSelector((state) => state.drizzleStatus.initialized);
const drizzleInitializationFailed = useSelector((state) => state.drizzleStatus.failed); const drizzleInitializationFailed = useSelector((state) => state.drizzleStatus.failed);
const userAddress = useSelector((state) => state.user.address); const userAddress = useSelector((state) => state.user.address);
const getTopicResults = useSelector((state) => state.contracts.Forum.getTopic); const getTopicResults = useSelector((state) => state.contracts[FORUM_CONTRACT].getTopic);
const topics = useSelector((state) => state.orbitData.topics); const topics = useSelector((state) => state.orbitData.topics);
const users = useSelector((state) => state.orbitData.users); const users = useSelector((state) => state.orbitData.users);
const [getTopicCallHash, setGetTopicCallHash] = useState([]); const [getTopicCallHash, setGetTopicCallHash] = useState([]);

Loading…
Cancel
Save