Skip to content
This repository has been archived by the owner on Nov 6, 2020. It is now read-only.

Don't pop-up notifications after network switch #4076

Merged
merged 24 commits into from
Jan 12, 2017
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 17 additions & 3 deletions js/src/api/transport/http/http.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,19 +46,33 @@ export default class Http extends JsonRpcBase {
};
}

_setConnected () {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think these should have been in the JsonRpc base - so both implementations are consistent with the flags they set and the events they emit (at least the base flags, not the internal extensions).

if (!this._connected) {
this._connected = true;
this.emit('open');
}
}

_setDisconnected () {
if (this._connected) {
this._connected = false;
this.emit('close');
}
}

execute (method, ...params) {
const request = this._encodeOptions(method, params);

return fetch(this._url, request)
.catch((error) => {
this._connected = false;
this._setDisconnected();
throw error;
})
.then((response) => {
this._connected = true;
this._setConnected();

if (response.status !== 200) {
this._connected = false;
this._setDisconnected();
this.error(JSON.stringify({ status: response.status, statusText: response.statusText }));
console.error(`${method}(${JSON.stringify(params)}): ${response.status}: ${response.statusText}`);

Expand Down
20 changes: 20 additions & 0 deletions js/src/api/transport/http/http.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,26 @@ describe('api/transport/Http', () => {
});
});

describe('transport emitter', () => {
it('emits close event', (done) => {
transport.once('close', () => {
done();
});

transport.execute('eth_call');
});

it('emits open event', (done) => {
mockHttp([{ method: 'eth_call', reply: { result: '' } }]);

transport.once('open', () => {
done();
});

transport.execute('eth_call');
});
});

describe('transport', () => {
const RESULT = ['this is some result'];

Expand Down
6 changes: 5 additions & 1 deletion js/src/api/transport/jsonRpcBase.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,12 @@
// You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>.

export default class JsonRpcBase {
import EventEmitter from 'eventemitter3';

export default class JsonRpcBase extends EventEmitter {
constructor () {
super();

this._id = 1;
this._debug = false;
this._connected = false;
Expand Down
6 changes: 4 additions & 2 deletions js/src/api/transport/ws/ws.js
Original file line number Diff line number Diff line change
Expand Up @@ -124,13 +124,13 @@ export default class Ws extends JsonRpcBase {
}

_onOpen = (event) => {
console.log('ws:onOpen');

this._connected = true;
this._connecting = false;
this._autoConnect = true;
this._retries = 0;

this.emit('open');
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Only ws? We have 2 transports, needs to be in-sync.

Additionally, since it is done on the API layer, we need to have tests that prove that is does what it is supposed to for all the transports.

Copy link
Contributor Author

@ngotchac ngotchac Jan 10, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well the HTTP layer will never close nor open right (or at each request)?

Copy link
Contributor

@jacogr jacogr Jan 10, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It still has the isConnected & connected property. Basically when connected is set to true it should emit open, when set to false (errors), it should be emit false.

(Since we actually have the polling to say connected/not-connected the emitter will actually add value)


Object.keys(this._messages)
.filter((id) => this._messages[id].queued)
.forEach(this._send);
Expand All @@ -148,6 +148,8 @@ export default class Ws extends JsonRpcBase {
event.timestamp = Date.now();
this._lastError = event;

this.emit('close');

if (this._autoConnect) {
const timeout = this.retryTimeout;

Expand Down
31 changes: 31 additions & 0 deletions js/src/api/transport/ws/ws.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,37 @@ describe('api/transport/Ws', () => {
let transport;
let scope;

describe('transport emitter', () => {
const connect = () => {
const scope = mockWs();
const transport = new Ws(TEST_WS_URL);

return { transport, scope };
};

it('emits open event', (done) => {
const { transport, scope } = connect();

transport.once('open', () => {
done();
});

scope.stop();
});

it('emits close event', (done) => {
const { transport, scope } = connect();

transport.once('open', () => {
scope.server.close();
});

transport.once('close', () => {
done();
});
});
});

describe('transport', () => {
let result;

Expand Down
14 changes: 7 additions & 7 deletions js/src/redux/providers/balancesActions.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ const ETH = {
image: imagesEthereum
};

function setBalances (_balances) {
function setBalances (_balances, skipNotifications = false) {
return (dispatch, getState) => {
const state = getState();

Expand Down Expand Up @@ -65,12 +65,12 @@ function setBalances (_balances) {
const oldValue = nextTokens[tokenIndex].value;

// If received a token/eth (old value < new value), notify
if (oldValue.lt(value) && accounts[address]) {
if (oldValue.lt(value) && accounts[address] && !skipNotifications) {
const account = accounts[address];
const txValue = value.minus(oldValue);

const redirectToAccount = () => {
const route = `/account/${account.address}`;
const route = `/accounts/${account.address}`;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Picked this up last night as well. I guess we actually need to externalise the route definitions somehow so we don't miss these again in the future.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Might be worth it yes. Note that this route is still working

dispatch(push(route));
};

Expand Down Expand Up @@ -170,7 +170,7 @@ export function fetchTokens (_tokenIds) {
};
}

export function fetchBalances (_addresses) {
export function fetchBalances (_addresses, skipNotifications = false) {
return (dispatch, getState) => {
const { api, personal } = getState();
const { visibleAccounts, accounts } = personal;
Expand All @@ -192,7 +192,7 @@ export function fetchBalances (_addresses) {
balances[addr] = accountsBalances[idx];
});

dispatch(setBalances(balances));
dispatch(setBalances(balances, skipNotifications));
updateTokensFilter(addresses)(dispatch, getState);
})
.catch((error) => {
Expand Down Expand Up @@ -326,7 +326,7 @@ export function queryTokensFilter (tokensFilter) {
};
}

export function fetchTokensBalances (_addresses = null, _tokens = null) {
export function fetchTokensBalances (_addresses = null, _tokens = null, skipNotifications = false) {
return (dispatch, getState) => {
const { api, personal, balances } = getState();
const { visibleAccounts, accounts } = personal;
Expand All @@ -348,7 +348,7 @@ export function fetchTokensBalances (_addresses = null, _tokens = null) {
balances[addr] = tokensBalances[idx];
});

dispatch(setBalances(balances));
dispatch(setBalances(balances, skipNotifications));
})
.catch((error) => {
console.warn('balances::fetchTokensBalances', error);
Expand Down
5 changes: 5 additions & 0 deletions js/src/redux/providers/chainMiddleware.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
// You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>.

import { fetchBalances, fetchTokensBalances } from './balancesActions';
import { showSnackbar } from './snackbarActions';
import { DEFAULT_NETCHAIN } from './statusReducer';

Expand All @@ -29,6 +30,10 @@ export default class ChainMiddleware {

if (newChain !== nodeStatus.netChain && nodeStatus.netChain !== DEFAULT_NETCHAIN) {
store.dispatch(showSnackbar(`Switched to ${newChain}. Please reload the page.`, 60000));

// Fetch the new balances without notifying the user of any change
store.dispatch(fetchBalances(null, true));
store.dispatch(fetchTokensBalances(null, null, true));
}
}
}
Expand Down
Loading