feat: add notification boxes on new created escrows

This commit is contained in:
Jonathan Rainville 2019-05-31 10:24:24 -04:00
parent 24ea6e95a9
commit c350973da6
No known key found for this signature in database
GPG Key ID: 5F4630B759727D9C
10 changed files with 80 additions and 16 deletions

View File

@ -74,6 +74,7 @@
"react-dom": "^16.8.2",
"react-google-maps": "^9.4.5",
"react-i18next": "^9.0.2",
"react-notifications": "^1.4.3",
"react-redux": "^6.0.0",
"react-router-dom": "^4.3.1",
"react-scripts": "2.1.5",

View File

@ -1,6 +1,8 @@
import React, {Component} from 'react';
import EscrowNotifications from './notifications/EscrowNotifications';
import 'react-notifications/lib/notifications.css';
class NotificationManager extends Component {
render() {
return (

View File

@ -3,28 +3,34 @@ import {withRouter} from "react-router-dom";
import PropTypes from 'prop-types';
import {connect} from "react-redux";
import escrow from '../../../features/escrow';
import {NotificationContainer, NotificationManager} from 'react-notifications';
const DELAY = 5000;
class EscrowNotifications extends Component {
componentDidUpdate(prevProps) {
if (!prevProps.newEscrow && this.props.newEscrow) {
NotificationManager.info(`For Offer ${this.props.newEscrow.offerId}: ${this.props.newEscrow.token.symbol}${this.props.newEscrow.offer.currency}`,
'New trade created', DELAY, () => {
clearTimeout(this.escrowNotifTimeout);
this.props.clearNewEscrow();
this.props.history.push(`/escrow/${this.props.newEscrow.escrowId}`);
});
this.escrowNotifTimeout = setTimeout(() => {
console.log('Remove this');
this.props.clearNewEscrow();
}, DELAY);
}
}
render() {
if (this.props.newEscrow) {
console.log('NEW ESCrow', this.props.newEscrow);
}
return null;
return <NotificationContainer/>;
}
}
EscrowNotifications.propTypes = {
newEscrow: PropTypes.object
newEscrow: PropTypes.object,
history: PropTypes.object,
clearNewEscrow: PropTypes.func
};
@ -38,5 +44,6 @@ const mapStateToProps = (state) => {
export default connect(
mapStateToProps,
{
clearNewEscrow: escrow.actions.clearNewEscrow
}
)(withRouter(EscrowNotifications));

View File

@ -3,7 +3,7 @@ import {
CREATE_ESCROW, LOAD_ESCROWS, RELEASE_ESCROW, CANCEL_ESCROW,
RATE_TRANSACTION, PAY_ESCROW, OPEN_CASE, OPEN_CASE_SIGNATURE, PAY_ESCROW_SIGNATURE, CLOSE_DIALOG,
ADD_USER_RATING, USER_RATING, GET_ESCROW, GET_FEE, FUND_ESCROW, RESET_STATUS,
WATCH_ESCROW, WATCH_ESCROW_CREATIONS
WATCH_ESCROW, WATCH_ESCROW_CREATIONS, CLEAR_NEW_ESCROW
} from './constants';
import Escrow from '../../../embarkArtifacts/contracts/Escrow';
@ -84,6 +84,8 @@ export const resetStatus = () => ({type: RESET_STATUS});
export const watchEscrow = (escrowId) => ({type: WATCH_ESCROW, escrowId});
export const watchEscrowCreations = (offers) => ({type: WATCH_ESCROW_CREATIONS, offers});
export const clearNewEscrow = () => ({type: CLEAR_NEW_ESCROW});
// TODO: Update with new UI
export const payEscrowSignature = (escrowId) => ({ type: PAY_ESCROW_SIGNATURE, escrowId });

View File

@ -11,6 +11,8 @@ export const ESCROW_EVENT_RECEIVED = 'ESCROW_EVENT_RECEIVED';
export const WATCH_ESCROW_CREATIONS = 'WATCH_ESCROW_CREATIONS';
export const ESCROW_CREATED_EVENT_RECEIVED = 'ESCROW_CREATED_EVENT_RECEIVED';
export const CLEAR_NEW_ESCROW = 'CLEAR_NEW_ESCROW';
export const GET_ESCROW = 'GET_ESCROW';
export const GET_ESCROW_SUCCEEDED = 'GET_ESCROW_SUCCEEDED';
export const GET_ESCROW_FAILED = 'GET_ESCROW_FAILED';

View File

@ -9,7 +9,7 @@ import {
PAY_ESCROW, PAY_ESCROW_SUCCEEDED, PAY_ESCROW_FAILED, PAY_ESCROW_PRE_SUCCESS,
CANCEL_ESCROW, CANCEL_ESCROW_SUCCEEDED, CANCEL_ESCROW_FAILED, CANCEL_ESCROW_PRE_SUCCESS,
RATE_TRANSACTION, RATE_TRANSACTION_FAILED, RATE_TRANSACTION_SUCCEEDED, RATE_TRANSACTION_PRE_SUCCESS,
ESCROW_EVENT_RECEIVED, ESCROW_CREATED_EVENT_RECEIVED
ESCROW_EVENT_RECEIVED, ESCROW_CREATED_EVENT_RECEIVED, CLEAR_NEW_ESCROW
} from './constants';
import { States } from '../../utils/transaction';
import { escrowStatus, eventTypes } from './helpers';
@ -235,6 +235,11 @@ function reducer(state = DEFAULT_STATE, action) {
...state,
newEscrow: action.result.returnValues.escrowId
};
case CLEAR_NEW_ESCROW:
return {
...state,
newEscrow: null
};
case RESET_STATUS:
return {
...state,

View File

@ -277,7 +277,7 @@ export function *onWatchEscrow() {
export function *watchEscrowCreations({offers}) {
try {
yield all(offers.map(offer => contractEvent(Escrow, eventTypes.created, {offerId: offer.offerId}, ESCROW_CREATED_EVENT_RECEIVED)));
yield all(offers.map(offer => contractEvent(Escrow, eventTypes.created, {offerId: offer.id}, ESCROW_CREATED_EVENT_RECEIVED)));
} catch (error) {
console.error(error);
}

View File

@ -109,9 +109,9 @@ class App extends Component {
return (
<Fragment>
<NotificationManager/>
<HashRouter>
<Container className="p-0">
<NotificationManager/>
<Header profile={this.props.profile}/>
<div className="body-content">
<BackButton/>

View File

@ -48,7 +48,7 @@ export function *doTransaction(preSuccess, success, failed, {value = 0, toSend})
}
}
export function contractEventChannel(contract, event, filter, emitter) {
export function contractOnceEventChannel(contract, event, filter, emitter) {
contract.once(event, {filter}, (err, result) => {
if (err) {
emitter({err});
@ -60,8 +60,28 @@ export function contractEventChannel(contract, event, filter, emitter) {
return () => {};
}
export function *contractEvent(contract, event, filter, successType) {
const channel = eventChannel(contractEventChannel.bind(null, contract, event, filter));
export function contractEventChannel(contract, event, filter, emitter) {
const sub = contract.events[event]({
filter
}, (err, result) => {
if (err) {
emitter({err});
return emitter(END);
}
emitter({result});
});
return () => {
sub.unsubscribe();
};
}
export function *contractEvent(contract, event, filter, successType, perpetualEvent) {
let channel;
if (perpetualEvent) {
channel = eventChannel(contractEventChannel.bind(null, contract, event, filter));
} else {
channel = eventChannel(contractOnceEventChannel.bind(null, contract, event, filter));
}
while (true) {
const {result, error} = yield take(channel);
if (result) {

View File

@ -4392,6 +4392,11 @@ ccount@^1.0.3:
resolved "https://registry.yarnpkg.com/ccount/-/ccount-1.0.3.tgz#f1cec43f332e2ea5a569fd46f9f5bde4e6102aff"
integrity sha512-Jt9tIBkRc9POUof7QA/VwWd+58fKkEEfI+/t1/eOlxKM7ZhrczNzMFefge7Ai+39y1pR/pP6cI19guHy3FSLmw==
chain-function@^1.0.0:
version "1.0.1"
resolved "https://registry.yarnpkg.com/chain-function/-/chain-function-1.0.1.tgz#c63045e5b4b663fb86f1c6e186adaf1de402a1cc"
integrity sha512-SxltgMwL9uCko5/ZCLiyG2B7R9fY4pDZUw7hJ4MhirdjBLosoDqkWABi3XMucddHdLiFJMb7PD2MZifZriuMTg==
chalk@2.4.1:
version "2.4.1"
resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.1.tgz#18c49ab16a037b6eb0152cc83e3471338215b66e"
@ -4603,7 +4608,7 @@ class-utils@^0.3.5:
isobject "^3.0.0"
static-extend "^0.1.1"
classnames@^2.2.0, classnames@^2.2.3, classnames@^2.2.5, classnames@^2.2.6:
classnames@^2.1.1, classnames@^2.2.0, classnames@^2.2.3, classnames@^2.2.5, classnames@^2.2.6:
version "2.2.6"
resolved "https://registry.yarnpkg.com/classnames/-/classnames-2.2.6.tgz#43935bffdd291f326dad0a205309b38d00f650ce"
integrity sha512-JR/iSQOSt+LQIWwrwEzJ9uk0xfN3mTVYMwt1Ir5mUcSN6pU+V4zQFFaJsclJbPuAUQH+yfWef6tm7l1quW3C8Q==
@ -6022,7 +6027,7 @@ dom-converter@^0.2:
dependencies:
utila "~0.4"
dom-helpers@^3.2.1, dom-helpers@^3.4.0:
dom-helpers@^3.2.0, dom-helpers@^3.2.1, dom-helpers@^3.4.0:
version "3.4.0"
resolved "https://registry.yarnpkg.com/dom-helpers/-/dom-helpers-3.4.0.tgz#e9b369700f959f62ecde5a6babde4bccd9169af8"
integrity sha512-LnuPJ+dwqKDIyotW1VzmOZ5TONUN7CwkCR5hrgawTUbkBGYdeoNLZo6nNfGkCrjtE1nXXaj7iMMpDa8/d9WoIA==
@ -14104,7 +14109,7 @@ prop-types-extra@^1.0.1:
react-is "^16.3.2"
warning "^3.0.0"
prop-types@15.x, prop-types@^15.5.10, prop-types@^15.5.4, prop-types@^15.5.7, prop-types@^15.5.8, prop-types@^15.5.9, prop-types@^15.6.0, prop-types@^15.6.1, prop-types@^15.6.2, prop-types@^15.7.2:
prop-types@15.x, prop-types@^15.5.10, prop-types@^15.5.4, prop-types@^15.5.6, prop-types@^15.5.7, prop-types@^15.5.8, prop-types@^15.5.9, prop-types@^15.6.0, prop-types@^15.6.1, prop-types@^15.6.2, prop-types@^15.7.2:
version "15.7.2"
resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.7.2.tgz#52c41e75b8c87e72b9d9360e0206b99dcbffa6c5"
integrity sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ==
@ -14729,6 +14734,15 @@ react-modal@^3.6.1:
react-lifecycles-compat "^3.0.0"
warning "^3.0.0"
react-notifications@^1.4.3:
version "1.4.3"
resolved "https://registry.yarnpkg.com/react-notifications/-/react-notifications-1.4.3.tgz#7060d339896f125a5b183ebcd04526980a433222"
integrity sha1-cGDTOYlvElpbGD680EUmmApDMiI=
dependencies:
classnames "^2.1.1"
prop-types "^15.5.10"
react-transition-group "^1.2.0"
react-onclickoutside@^6.5.0:
version "6.8.0"
resolved "https://registry.yarnpkg.com/react-onclickoutside/-/react-onclickoutside-6.8.0.tgz#9f91b5b3ed59f4d9e43fd71620dc200773a4d569"
@ -14892,6 +14906,17 @@ react-textarea-autosize@^7.0.4:
"@babel/runtime" "^7.1.2"
prop-types "^15.6.0"
react-transition-group@^1.2.0:
version "1.2.1"
resolved "https://registry.yarnpkg.com/react-transition-group/-/react-transition-group-1.2.1.tgz#e11f72b257f921b213229a774df46612346c7ca6"
integrity sha512-CWaL3laCmgAFdxdKbhhps+c0HRGF4c+hdM4H23+FI1QBNUyx/AMeIJGWorehPNSaKnQNOAxL7PQmqMu78CDj3Q==
dependencies:
chain-function "^1.0.0"
dom-helpers "^3.2.0"
loose-envify "^1.3.1"
prop-types "^15.5.6"
warning "^3.0.0"
react-transition-group@^2.0.0, react-transition-group@^2.2.0, react-transition-group@^2.3.1:
version "2.9.0"
resolved "https://registry.yarnpkg.com/react-transition-group/-/react-transition-group-2.9.0.tgz#df9cdb025796211151a436c69a8f3b97b5b07c8d"