Don't refresh on network change (#1144)

* Configure sagas and components to react to network switch.

* tscheck

* Update tests with new behavior.

* tscheck

* Log out of wallet on network change.

* Fix up test.
This commit is contained in:
William O'Beirne 2018-02-24 20:32:34 -05:00 committed by Daniel Ternyak
parent 33f5ede22a
commit 1b6143e457
9 changed files with 46 additions and 36 deletions

View File

@ -81,11 +81,12 @@ class EquivalentValues extends React.Component<Props, State> {
}
public componentWillReceiveProps(nextProps: Props) {
const { balance, tokenBalances, isOffline } = this.props;
const { balance, tokenBalances, isOffline, network } = this.props;
if (
nextProps.balance !== balance ||
nextProps.tokenBalances !== tokenBalances ||
nextProps.isOffline !== isOffline
nextProps.isOffline !== isOffline ||
nextProps.network.unit !== network.unit
) {
const defaultOption = this.defaultOption(
nextProps.balance,
@ -288,7 +289,8 @@ class EquivalentValues extends React.Component<Props, State> {
const currencies = tokenBalances
.filter(tk => !tk.balance.isZero())
.map(tk => tk.symbol)
.sort();
.sort()
.concat([props.network.unit]);
// If it's the same currencies as we have, skip it
if (this.requestedCurrencies && currencies.join() === this.requestedCurrencies.join()) {

View File

@ -76,7 +76,10 @@ class TXMetaDataPanel extends React.Component<Props, State> {
}
public componentWillReceiveProps(nextProps: Props) {
if (this.props.offline && !nextProps.offline) {
if (
(this.props.offline && !nextProps.offline) ||
this.props.network.unit !== nextProps.network.unit
) {
this.props.fetchCCRates([this.props.network.unit]);
}
if (this.props.gasPrice !== nextProps.gasPrice) {

View File

@ -46,6 +46,12 @@ class LedgerNanoSDecryptClass extends PureComponent<Props, State> {
});
};
public componentWillReceiveProps(nextProps: Props) {
if (this.props.dPath !== nextProps.dPath) {
this.setState({ dPath: nextProps.dPath.value });
}
}
public render() {
const { dPath, publicKey, chainCode, error, isLoading, showTip } = this.state;
const showErr = error ? 'is-showing' : '';

View File

@ -9,7 +9,7 @@ import { connect } from 'react-redux';
import { getSingleDPath, getPaths } from 'selectors/config/wallet';
import { TogglablePassword } from 'components';
interface Props {
interface OwnProps {
onUnlock(param: any): void;
}
@ -18,6 +18,8 @@ interface StateProps {
dPaths: DPath[];
}
type Props = OwnProps & StateProps;
interface State {
phrase: string;
formattedPhrase: string;
@ -26,7 +28,7 @@ interface State {
dPath: string;
}
class MnemonicDecryptClass extends PureComponent<Props & StateProps, State> {
class MnemonicDecryptClass extends PureComponent<Props, State> {
public state: State = {
phrase: '',
formattedPhrase: '',
@ -35,6 +37,12 @@ class MnemonicDecryptClass extends PureComponent<Props & StateProps, State> {
dPath: this.props.dPath.value
};
public componentWillReceiveProps(nextProps: Props) {
if (this.props.dPath !== nextProps.dPath) {
this.setState({ dPath: nextProps.dPath.value });
}
}
public render() {
const { phrase, formattedPhrase, seed, dPath, pass } = this.state;
const isValidMnemonic = validateMnemonic(formattedPhrase);

View File

@ -40,6 +40,12 @@ class TrezorDecryptClass extends PureComponent<Props, State> {
isLoading: false
};
public componentWillReceiveProps(nextProps: Props) {
if (this.props.dPath !== nextProps.dPath) {
this.setState({ dPath: nextProps.dPath.value });
}
}
public render() {
const { dPath, publicKey, chainCode, error, isLoading } = this.state;
const showErr = error ? 'is-showing' : '';

View File

@ -30,10 +30,10 @@ import {
ChangeNodeIntentAction
} from 'actions/config';
import { showNotification } from 'actions/notifications';
import { resetWallet } from 'actions/wallet';
import { translateRaw } from 'translations';
import { StaticNodeConfig, CustomNodeConfig, NodeConfig } from 'types/node';
import { CustomNetworkConfig, StaticNetworkConfig } from 'types/network';
import { Web3Service } from 'libs/nodes/web3';
let hasCheckedOnline = false;
export function* pollOfflineStatus(): SagaIterator {
@ -168,18 +168,8 @@ export function* handleNodeChangeIntent({
yield put(setLatestBlock(currentBlock));
yield put(changeNode({ networkId: nextNodeConfig.network, nodeId: nodeIdToSwitchTo }));
// TODO - re-enable once DeterministicWallet state is fixed to flush properly.
// DeterministicWallet keeps path related state we need to flush before we can stop reloading
// const currentWallet: IWallet | null = yield select(getWalletInst);
// if there's no wallet, do not reload as there's no component state to resync
// if (currentWallet && currentConfig.network !== actionConfig.network) {
const isNewNetwork = currentConfig.network !== nextNodeConfig.network;
const newIsWeb3 = nextNodeConfig.service === Web3Service;
// don't reload when web3 is selected; node will automatically re-set and state is not an issue here
if (isNewNetwork && !newIsWeb3) {
yield call(reload);
if (currentConfig.network !== nextNodeConfig.network) {
yield fork(handleNewNetwork);
}
}
@ -187,6 +177,10 @@ export function* switchToNewNode(action: AddCustomNodeAction): SagaIterator {
yield put(changeNodeIntent(action.payload.id));
}
export function* handleNewNetwork() {
yield put(resetWallet());
}
export const node = [
takeEvery(TypeKeys.CONFIG_NODE_CHANGE_INTENT, handleNodeChangeIntent),
takeLatest(TypeKeys.CONFIG_POLL_OFFLINE_STATUS, handlePollOfflineStatus),

View File

@ -14,13 +14,10 @@ export function* handleNonceRequest(): SagaIterator {
const walletInst: AppState['wallet']['inst'] = yield select(getWalletInst);
const isOffline: boolean = yield select(getOffline);
try {
if (isOffline) {
if (isOffline || !walletInst) {
return;
}
if (!walletInst) {
throw Error();
}
const fromAddress: string = yield apply(walletInst, walletInst.getAddressString);
const retrievedNonce: string = yield apply(nodeLib, nodeLib.getTransactionCount, [fromAddress]);

View File

@ -7,7 +7,7 @@ import {
handleNodeChangeIntent,
handlePollOfflineStatus,
pollOfflineStatus,
reload
handleNewNetwork
} from 'sagas/config/node';
import {
getNodeId,
@ -213,9 +213,8 @@ describe('handleNodeChangeIntent*', () => {
);
});
it('should call reload if network is new', () => {
expect(data.gen.next().value).toEqual(call(reload));
expect(data.gen.next().done).toEqual(true);
it('should fork handleNewNetwork', () => {
expect(data.gen.next().value).toEqual(fork(handleNewNetwork));
});
it('should be done', () => {

View File

@ -1,8 +1,7 @@
import { getNonceSucceeded, getNonceFailed, inputNonce } from 'actions/transaction';
import { getNonceSucceeded, inputNonce } from 'actions/transaction';
import { apply, put, select, fork, take, cancel } from 'redux-saga/effects';
import { getNodeLib, getOffline } from 'selectors/config';
import { getWalletInst } from 'selectors/wallet';
import { showNotification } from 'actions/notifications';
import { handleNonceRequest, handleNonceRequestWrapper } from 'sagas/transaction/network/nonce';
import { cloneableGenerator, createMockTask } from 'redux-saga/utils';
import { TypeKeys as WalletTK } from 'actions/wallet';
@ -41,14 +40,10 @@ describe('handleNonceRequest*', () => {
expect(gens.gen.next(nodeLib).value).toEqual(select(getWalletInst));
});
it('should handle being called without wallet inst correctly', () => {
it('should exit if being called without a wallet inst', () => {
gens.noWallet = gens.gen.clone();
gens.noWallet.next();
expect(gens.noWallet.next(offline).value).toEqual(
put(showNotification('warning', 'Your addresses nonce could not be fetched'))
);
expect(gens.noWallet.next().value).toEqual(put(getNonceFailed()));
expect(gens.noWallet.next().done).toEqual(true);
gens.noWallet.next(null); // No wallet inst
expect(gens.noWallet.next(offline).done).toEqual(true);
});
it('should select getOffline', () => {