diff --git a/app/src/containers/CoreLayoutContainer.js b/app/src/containers/CoreLayoutContainer.js
index 7e61ab9..159ba92 100644
--- a/app/src/containers/CoreLayoutContainer.js
+++ b/app/src/containers/CoreLayoutContainer.js
@@ -1,6 +1,7 @@
import React, { Component } from 'react';
import NavBarContainer from './NavBarContainer';
+import RightSideBarContainer from './TransactionsMonitorContainer';
/*import TransactionsMonitorContainer from '../../containers/TransactionsMonitorContainer';*/
// Styles
@@ -33,7 +34,7 @@ class CoreLayout extends Component {
diff --git a/app/src/containers/TransactionsMonitorContainer.js b/app/src/containers/TransactionsMonitorContainer.js
new file mode 100644
index 0000000..5199902
--- /dev/null
+++ b/app/src/containers/TransactionsMonitorContainer.js
@@ -0,0 +1,113 @@
+import React, { Component } from 'react';
+import { connect } from 'react-redux';
+import { withRouter } from 'react-router-dom'
+
+import { Message } from 'semantic-ui-react';
+
+class RightSideBar extends Component {
+ constructor(props, context) {
+ super(props);
+
+ this.handleMessageClick = this.handleMessageClick.bind(this);
+ this.handleMessageDismiss = this.handleMessageDismiss.bind(this);
+
+ this.state = {
+ isTransactionMessageDismissed: []
+ }
+ }
+
+ handleMessageClick(index) {
+ let transactionHash = this.props.transactionStack[index];
+ if (this.props.transactions[transactionHash]) {
+ if (this.props.transactions[transactionHash].status === 'error') {
+ this.handleMessageDismiss(null, index);
+ } else {
+ if (this.props.transactions[transactionHash].receipt &&
+ this.props.transactions[transactionHash].receipt.events) {
+ switch (Object.keys(this.props.transactions[transactionHash].receipt.events)[0]){
+ case 'TopicCreated':
+ this.props.history.push("/topic/" +
+ this.props.transactions[transactionHash].receipt.events.TopicCreated.returnValues.topicID
+ );
+ this.handleMessageDismiss(null, index);
+ break;
+ default:
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ handleMessageDismiss(event, messageIndex) {
+ if (event !== null) {
+ event.stopPropagation();
+ }
+
+ let isTransactionMessageDismissedShallowCopy = this.state.isTransactionMessageDismissed.slice();
+ isTransactionMessageDismissedShallowCopy[messageIndex] = true;
+ this.setState({
+ isTransactionMessageDismissed: isTransactionMessageDismissedShallowCopy
+ });
+ }
+
+ render() {
+ if (this.props.transactionStack.length === 0){
+ return null;
+ }
+
+ let transactionMessages = this.props.transactionStack.map((transaction, index) => {
+ if (this.state.isTransactionMessageDismissed[index]){
+ return null;
+ }
+
+ let color = 'black';
+ let message = [];
+ message.push("New transaction has been queued and is waiting your confirmation.");
+ if (this.props.transactions[transaction]) {
+ message.push(
);
+ message.push("- transaction confirmed");
+ }
+ if (this.props.transactions[transaction] &&
+ this.props.transactions[transaction].status === 'success') {
+ /* Transaction completed successfully */
+ message.push(
);
+ message.push("- transaction mined");
+ color = 'green';
+ message.push(
);
+ message.push("- transaction completed successfully");
+ } else if (this.props.transactions[transaction] &&
+ this.props.transactions[transaction].status === "error"){
+ /* Transaction failed to complete */
+ message.push(
);
+ message.push("- transaction mined");
+ color = 'red';
+ message.push(
);
+ message.push("Transaction failed to complete!");
+ }
+
+ return (
+
{this.handleMessageClick(index)}} >
+ {this.handleMessageDismiss(e, index)}}>
+ {message}
+
+
+ );
+ });
+
+ return (transactionMessages);
+ }
+}
+
+const mapStateToProps = state => {
+ return {
+ transactions: state.transactions,
+ transactionStack: state.transactionStack
+ }
+};
+
+const RightSideBarContainer = withRouter(connect(mapStateToProps)(RightSideBar));
+
+export default RightSideBarContainer;
\ No newline at end of file
diff --git a/app/src/redux/actions/transactionsActions.js b/app/src/redux/actions/transactionsActions.js
index 35bd009..8a2e04a 100644
--- a/app/src/redux/actions/transactionsActions.js
+++ b/app/src/redux/actions/transactionsActions.js
@@ -1,5 +1,4 @@
//Action creators
-import uuid from 'uuid/v1';
export const INIT_TRANSACTION = 'INIT_TRANSACTION';
export const UPDATE_TRANSACTION = 'UPDATE_TRANSACTION';
@@ -14,7 +13,6 @@ export function updateUsername(newUsername, callback){
params: [newUsername],
event: 'UsernameUpdated'
},
- uid: uuid(),
callback: callback
};
}
@@ -29,7 +27,6 @@ export function createTopic(userInputs){
params: [],
event: 'TopicCreated'
},
- uid: uuid(),
userInputs: userInputs
};
}
@@ -44,7 +41,6 @@ export function createPost(topicID, userInputs){
params: [topicID],
event: 'PostCreated'
},
- uid: uuid(),
userInputs: userInputs
};
}
@@ -52,7 +48,6 @@ export function createPost(topicID, userInputs){
export function updateTransaction(transactionIndex, updateDescriptor){
return {
type: UPDATE_TRANSACTION,
- index: transactionIndex,
transactionUpdates: updateDescriptor
};
}
\ No newline at end of file
diff --git a/app/src/redux/reducers/transactionsReducer.js b/app/src/redux/reducers/transactionsReducer.js
deleted file mode 100644
index 5a934b2..0000000
--- a/app/src/redux/reducers/transactionsReducer.js
+++ /dev/null
@@ -1,39 +0,0 @@
-import { INIT_TRANSACTION, UPDATE_TRANSACTION } from '../actions/transactionsMonitorActions';
-
-const initialState = {
- transactions: Object.create(null)
-};
-
-const transactionsReducer = (state = initialState, action) => {
- switch (action.type) {
- case INIT_TRANSACTION:
- let transactionsShallowCopy = state.transactions.slice();
- transactionsShallowCopy.push({
- status: 'initialized',
- contract: action.transactionDescriptor.contract,
- method: action.transactionDescriptor.method,
- params: action.transactionDescriptor.params,
- event: action.transactionDescriptor.event,
- returnData: null,
- userInputs: action.userInputs
- });
- return {
- transactions: transactionsShallowCopy
- };
- case UPDATE_TRANSACTION:
- return { transactions: state.transactions.map( (transaction, index) => {
- if (index !== action.index){
- return transaction;
- }
-
- return {
- ...transaction,
- ...action.transactionUpdates
- }
- })};
- default:
- return state;
- }
-};
-
-export default transactionsReducer;
\ No newline at end of file
diff --git a/app/src/redux/sagas/transactionsSaga.js b/app/src/redux/sagas/transactionsSaga.js
index 15c494c..499b55f 100644
--- a/app/src/redux/sagas/transactionsSaga.js
+++ b/app/src/redux/sagas/transactionsSaga.js
@@ -1,36 +1,59 @@
-import {call, put, select, take, takeEvery} from 'redux-saga/effects'
-import { contract, getCurrentAccount } from './drizzleUtilsSaga';
+import {call, select, take, takeEvery} from 'redux-saga/effects'
import { drizzle } from '../../index'
let transactionsHistory = Object.create(null);
function* initTransaction(action) {
- transactionsHistory[action.uid] = action;
- transactionsHistory[action.uid].dataKey = drizzle.contracts[action.transactionDescriptor.contract]
- .methods[action.transactionDescriptor['method']]
- .cacheSend(...[action.transactionDescriptor.params]);
+ var dataKey = drizzle.contracts[action.transactionDescriptor.contract]
+ .methods[action.transactionDescriptor['method']]
+ .cacheSend(...[action.transactionDescriptor.params]);
- transactionsHistory[action.uid].state = 'initialized';
+ transactionsHistory[dataKey] = action;
}
-function* completeWithOrbitInteractions(action) {
- const orbit = yield select((state) => state.orbit);
-
- yield call(orbit.topicsDB.put, action.receipt.events['TopicCreated'].returnValues.topicID, {
- subject: 'tada'
- });
+function* handleEvent(action) {
+ switch(action.event.event) {
+ case 'TopicCreated':
+ var transactionStack = yield select((state) => state.transactionStack);
+ var dataKey = transactionStack.indexOf(action.event.transactionHash);
+ if (dataKey !== -1 &&
+ transactionsHistory[dataKey] &&
+ transactionsHistory[dataKey].state === 'initialized') {
+ //Gets orbit
+ const orbit = yield select((state) => state.orbit);
+ //And saves the topic
+ /*yield call(orbit.topicsDB.put, ...[action.event.returnValues.topicID, {
+ subject: transactionsHistory[dataKey].userInputs.topicSubject
+ }]);
+ yield call(orbit.postsDB.put, ...[action.event.returnValues.postID, {
+ subject: transactionsHistory[dataKey].userInputs.topicSubject,
+ content: transactionsHistory[dataKey].userInputs.topicMessage
+ }]);*/
+
+ transactionsHistory[dataKey].state = 'success';
+ }
+ break;
+ default:
+ //Nothing to do here
+ return;
+ }
+}
- yield call(orbit.postsDB.put, action.receipt.events['TopicCreated'].returnValues.postID, {
- subject: 'tada',
- content: 'it worked!'
- });
+function* handleError() {
+ var transactionStack = yield select((state) => state.transactionStack);
+ transactionStack.forEach((transaction, index) => {
+ if (transaction.startsWith('TEMP_')) {
+ transactionsHistory[index].state = 'error';
+ }
+ })
}
function* transactionsSaga() {
yield take("DRIZZLE_UTILS_SAGA_INITIALIZED");
yield takeEvery("INIT_TRANSACTION", initTransaction);
- yield takeEvery("TX_SUCCESSFUL", completeWithOrbitInteractions);
+ yield takeEvery("EVENT_FIRED", handleEvent);
+ yield takeEvery("TX_ERROR", handleError);
}
export default transactionsSaga;