Daniel Ternyak b493a0c968 Offline Send (#276)
* offline-send mvp

* cleanup unneeded imports

* - create pollOfflineStatus action, action creator, interface

* expand UnlockHeader when collapse-button is clicked, instead of div

* kick-off pollOfflineStatus upon SendTransaction mount.

* Create sagas for polling offline status

* remove comment

* - create CONFIG_FORCE_OFFLINE action, action creator, interface

* Adjust OfflineToggle terms to "Force Online/Offline", and understand when forced offline and when really offline.

* - Assume offline in SendTransaction when either offline or forcedOffline

* - handle forceOffline action in reducer
- adjust state type / provide default state for forceOffline in config reducer

* adjust test to pass with different key name

* fix incorrect import

* - allow size to be specified in offline toggle

* - Decode and display nonce in confirmation modal

* - set default nonces when forced offline and have online connectivity based on transaction count
- pass nonce to generateCompleteTransaction
- refactor componentDidUpdate

* Allow optional nonce to be passed to generateCompleteTransaction

* - create stripHexPrefix function

* - cleanup sagas

* move getParam into helper util

* update address on component update

* - show spinner while transaction is being signed
- reset state when wallet instance changes (new wallet instantiated via UnlockHeader)

* center-align offline message

* Adjust force offline/online button text

* - validate nonces when offline
- only estimate gas when online
- don't show send tx button when offline

* - break generateCompleteTransactionFromRawTransaction into multiple functions.
- support offline generation in generateCompleteTransaction (and generateCompleteTransactionFromRawTransaction). Balance checking is now only done when not offline to support offline generation.

* Create Help component (to be used as a tooltip)

* Disable hardware wallets when offline.

* Hide Send Entire Balance when balance is falsy

* Show help icon in nonce field.

* - show helper instructions on how to broadcast when user is offline after generating a tx
- hardcoded gas limits when offline
- refactors

* create isPositiveInteger helper function

* fix nonce validation

* really fix nonce validation (specifically the input highlighting)

* remove stray // @flow's

* remove offline tab nav

* remove unused action arg

* address PR comments
2017-10-10 22:04:49 -07:00

137 lines
3.2 KiB
TypeScript

import {
addCustomToken,
removeCustomToken,
TAddCustomToken,
TRemoveCustomToken
} from 'actions/customTokens';
import { showNotification, TShowNotification } from 'actions/notifications';
import { fetchCCRates as dFetchCCRates, TFetchCCRates } from 'actions/rates';
import { NetworkConfig } from 'config/data';
import { Ether } from 'libs/units';
import { IWallet } from 'libs/wallet/IWallet';
import React from 'react';
import { connect } from 'react-redux';
import { AppState } from 'reducers';
import { getNetworkConfig } from 'selectors/config';
import {
getTokenBalances,
getWalletInst,
TokenBalance
} from 'selectors/wallet';
import AccountInfo from './AccountInfo';
import EquivalentValues from './EquivalentValues';
import Promos from './Promos';
import TokenBalances from './TokenBalances';
import { State } from 'reducers/rates';
import OfflineToggle from './OfflineToggle';
interface Props {
wallet: IWallet;
balance: Ether;
network: NetworkConfig;
tokenBalances: TokenBalance[];
rates: State['rates'];
ratesError: State['ratesError'];
showNotification: TShowNotification;
addCustomToken: TAddCustomToken;
removeCustomToken: TRemoveCustomToken;
fetchCCRates: TFetchCCRates;
}
interface Block {
name: string;
content: React.ReactElement<any>;
isFullWidth?: boolean;
}
export class BalanceSidebar extends React.Component<Props, {}> {
public render() {
const {
wallet,
balance,
network,
tokenBalances,
rates,
ratesError,
fetchCCRates
} = this.props;
if (!wallet) {
return null;
}
const blocks: Block[] = [
{
name: 'Go Offline',
content: <OfflineToggle />
},
{
name: 'Account Info',
content: (
<AccountInfo
wallet={wallet}
balance={balance}
network={network}
fetchCCRates={fetchCCRates}
/>
)
},
{
name: 'Promos',
isFullWidth: true,
content: <Promos />
},
{
name: 'Token Balances',
content: (
<TokenBalances
tokens={tokenBalances}
onAddCustomToken={this.props.addCustomToken}
onRemoveCustomToken={this.props.removeCustomToken}
/>
)
},
{
name: 'Equivalent Values',
content: (
<EquivalentValues
balance={balance}
rates={rates}
ratesError={ratesError}
/>
)
}
];
return (
<aside>
{blocks.map(block => (
<section
className={`Block ${block.isFullWidth ? 'is-full-width' : ''}`}
key={block.name}
>
{block.content}
</section>
))}
</aside>
);
}
}
function mapStateToProps(state: AppState) {
return {
wallet: getWalletInst(state),
balance: state.wallet.balance,
tokenBalances: getTokenBalances(state),
network: getNetworkConfig(state),
rates: state.rates.rates,
ratesError: state.rates.ratesError
};
}
export default connect(mapStateToProps, {
addCustomToken,
removeCustomToken,
showNotification,
fetchCCRates: dFetchCCRates
})(BalanceSidebar);