From ed7501c4fc8e9601bbaff0bd26eff79ed5139ea4 Mon Sep 17 00:00:00 2001 From: Szymon Lesisz Date: Mon, 15 Oct 2018 15:44:10 +0200 Subject: [PATCH 01/12] refactor Coin > Network --- public/data/appConfig.json | 8 ++-- public/data/ropstenTokens.json | 6 +++ src/actions/DiscoveryActions.js | 10 ++-- src/actions/LocalStorageActions.js | 47 +++---------------- src/actions/RouterActions.js | 4 +- src/actions/SelectedAccountActions.js | 2 +- src/actions/SendFormActions.js | 10 ++-- src/actions/SendFormValidationActions.js | 6 +-- src/actions/TrezorConnectActions.js | 2 +- src/actions/Web3Actions.js | 10 ++-- src/actions/constants/TrezorConnect.js | 2 +- src/components/images/CoinLogo/index.js | 24 +++------- .../Context/components/Account/index.js | 2 +- src/flowtype/index.js | 2 +- src/reducers/BlockchainReducer.js | 16 +++---- src/reducers/LocalStorageReducer.js | 21 ++------- src/reducers/SelectedAccountReducer.js | 4 +- src/reducers/utils/index.js | 8 ++-- src/services/WalletService.js | 4 +- .../components/AccountMenu/index.js | 40 ++++++++-------- .../components/CoinMenu/index.js | 14 +++--- .../components/RowCoin/index.js | 14 ++---- .../components/PendingTransactions/index.js | 4 +- .../Summary/components/Balance/index.js | 18 +++---- .../Wallet/views/Account/Summary/index.js | 12 +---- 25 files changed, 111 insertions(+), 179 deletions(-) diff --git a/public/data/appConfig.json b/public/data/appConfig.json index 93b1520b..08460609 100644 --- a/public/data/appConfig.json +++ b/public/data/appConfig.json @@ -1,9 +1,9 @@ { - "coins": [ + "networks": [ { "name": "Ethereum", "symbol": "ETH", - "network": "eth", + "shortcut": "eth", "bip44": "m/44'/60'/0'/0", "chainId": 1, "defaultGasPrice": 64, @@ -21,7 +21,7 @@ { "name": "Ethereum Classic", "symbol": "ETC", - "network": "etc", + "shortcut": "etc", "chainId": 61, "bip44": "m/44'/61'/0'/0", "defaultGasPrice": 64, @@ -39,7 +39,7 @@ { "name": "Ethereum Ropsten", "symbol": "tROP", - "network": "trop", + "shortcut": "trop", "chainId": 3, "bip44": "m/44'/60'/0'/0", "defaultGasPrice": 64, diff --git a/public/data/ropstenTokens.json b/public/data/ropstenTokens.json index f4d716ae..ae6aa8cb 100644 --- a/public/data/ropstenTokens.json +++ b/public/data/ropstenTokens.json @@ -16,5 +16,11 @@ "name": "Trezor13", "symbol": "T013", "decimals": 13 + }, + { + "address": "0x58cda554935e4a1f2acbe15f8757400af275e084", + "name": "LahodCoin", + "symbol": "LAHOD", + "decimals": 13 } ] \ No newline at end of file diff --git a/src/actions/DiscoveryActions.js b/src/actions/DiscoveryActions.js index 596bc335..3c497f2e 100644 --- a/src/actions/DiscoveryActions.js +++ b/src/actions/DiscoveryActions.js @@ -92,7 +92,7 @@ const start = (device: TrezorDevice, network: string, ignoreCompleted?: boolean) return; } - const blockchain = getState().blockchain.find(b => b.name === network); + const blockchain = getState().blockchain.find(b => b.shortcut === network); if (blockchain && !blockchain.connected && (!discoveryProcess || !discoveryProcess.completed)) { dispatch({ type: DISCOVERY.WAITING_FOR_BLOCKCHAIN, @@ -124,8 +124,8 @@ const start = (device: TrezorDevice, network: string, ignoreCompleted?: boolean) // start discovery process const begin = (device: TrezorDevice, network: string): AsyncAction => async (dispatch: Dispatch, getState: GetState): Promise => { const { config } = getState().localStorage; - const coinToDiscover = config.coins.find(c => c.network === network); - if (!coinToDiscover) return; + const networkData = config.networks.find(c => c.shortcut === network); + if (!networkData) return; dispatch({ type: DISCOVERY.WAITING_FOR_DEVICE, @@ -140,7 +140,7 @@ const begin = (device: TrezorDevice, network: string): AsyncAction => async (dis instance: device.instance, state: device.state, }, - path: coinToDiscover.bip44, + path: networkData.bip44, keepSession: true, // acquire and hold session //useEmptyPassphrase: !device.instance, useEmptyPassphrase: device.useEmptyPassphrase, @@ -179,7 +179,7 @@ const begin = (device: TrezorDevice, network: string): AsyncAction => async (dis // send data to reducer dispatch({ type: DISCOVERY.START, - network: coinToDiscover.network, + network, device, publicKey: response.payload.publicKey, chainCode: response.payload.chainCode, diff --git a/src/actions/LocalStorageActions.js b/src/actions/LocalStorageActions.js index d7d32a1f..ae1c04c2 100644 --- a/src/actions/LocalStorageActions.js +++ b/src/actions/LocalStorageActions.js @@ -13,7 +13,7 @@ import * as buildUtils from 'utils/build'; import type { ThunkAction, AsyncAction, /* GetState, */ Dispatch, } from 'flowtype'; -import type { Config, Coin, TokensCollection } from 'reducers/LocalStorageReducer'; +import type { Config, Network, TokensCollection } from 'reducers/LocalStorageReducer'; import Erc20AbiJSON from 'public/data/ERC20Abi.json'; import AppConfigJSON from 'public/data/appConfig.json'; @@ -99,8 +99,8 @@ export function loadTokensFromJSON(): AsyncAction { const config: Config = await httpRequest(AppConfigJSON, 'json'); if (!buildUtils.isDev()) { - const index = config.coins.findIndex(c => c.network === 'trop'); - delete config.coins[index]; + const index = config.networks.findIndex(c => c.shortcut === 'trop'); + delete config.networks[index]; } const ERC20Abi = await httpRequest(Erc20AbiJSON, 'json'); @@ -117,10 +117,10 @@ export function loadTokensFromJSON(): AsyncAction { } // load tokens - const tokens = await config.coins.reduce(async (promise: Promise, coin: Coin): Promise => { + const tokens = await config.networks.reduce(async (promise: Promise, network: Network): Promise => { const collection: TokensCollection = await promise; - const json = await httpRequest(coin.tokens, 'json'); - collection[coin.network] = json; + const json = await httpRequest(network.tokens, 'json'); + collection[network.shortcut] = json; return collection; }, Promise.resolve({})); @@ -195,41 +195,6 @@ export const loadData = (): ThunkAction => (dispatch: Dispatch): void => { dispatch(loadTokensFromJSON()); }; -// const parseConfig = (json: JSON): Config => { - -// if (json['coins']) { - -// } - -// for (let key in json) { -// if (key === 'coins') { - -// } -// } - -// const coins: Array = json.coins || []; - -// if ("coins" in json){ -// json.coins -// } -// if (!json.hasOwnProperty("fiatValueTickers")) throw new Error(`Property "fiatValueTickers" is missing in appConfig.json`); -// if (json.config && json.hasOwnProperty('coins') && Array.isArray(json.coins)) { -// json.coins.map(c => { -// return { - -// } -// }) -// } else { -// throw new Error(`Property "coins" is missing in appConfig.json`); -// } - - -// return { -// coins: [], -// fiatValueTickers: [] -// } -// } - export const save = (key: string, value: string): ThunkAction => (): void => { if (typeof window.localStorage !== 'undefined') { try { diff --git a/src/actions/RouterActions.js b/src/actions/RouterActions.js index b764dcb9..4e744df7 100644 --- a/src/actions/RouterActions.js +++ b/src/actions/RouterActions.js @@ -71,8 +71,8 @@ export const paramsValidation = (params: RouterLocationState): PayloadAction c.network === params.network); - if (!coin) return false; + const network = config.networks.find(c => c.shortcut === params.network); + if (!network) return false; if (!params.account) return false; } diff --git a/src/actions/SelectedAccountActions.js b/src/actions/SelectedAccountActions.js index a075906e..995e1cf8 100644 --- a/src/actions/SelectedAccountActions.js +++ b/src/actions/SelectedAccountActions.js @@ -63,7 +63,7 @@ const getAccountStatus = (state: State, selectedAccount: SelectedAccountState): }; } - const blockchain = state.blockchain.find(b => b.name === network.network); + const blockchain = state.blockchain.find(b => b.shortcut === network.shortcut); if (blockchain && !blockchain.connected) { return { type: 'backend', diff --git a/src/actions/SendFormActions.js b/src/actions/SendFormActions.js index 39301c7b..3413ed36 100644 --- a/src/actions/SendFormActions.js +++ b/src/actions/SendFormActions.js @@ -130,7 +130,7 @@ export const init = (): AsyncAction => async (dispatch: Dispatch, getState: GetS return; } - const gasPrice: BigNumber = await dispatch(BlockchainActions.getGasPrice(network.network, network.defaultGasPrice)); + const gasPrice: BigNumber = await dispatch(BlockchainActions.getGasPrice(network.shortcut, network.defaultGasPrice)); const gasLimit = network.defaultGasLimit.toString(); const feeLevels = ValidationActions.getFeeLevels(network.symbol, gasPrice, gasLimit); const selectedFeeLevel = ValidationActions.getSelectedFeeLevel(feeLevels, initialState.selectedFeeLevel); @@ -139,7 +139,7 @@ export const init = (): AsyncAction => async (dispatch: Dispatch, getState: GetS type: SEND.INIT, state: { ...initialState, - networkName: network.network, + networkName: network.shortcut, networkSymbol: network.symbol, currency: network.symbol, feeLevels, @@ -411,7 +411,7 @@ const estimateGasPrice = (): AsyncAction => async (dispatch: Dispatch, getState: return; } - const gasLimit = await dispatch(BlockchainActions.estimateGasLimit(network.network, state.data, state.amount, state.gasPrice)); + const gasLimit = await dispatch(BlockchainActions.estimateGasLimit(network.shortcut, state.data, state.amount, state.gasPrice)); // double check "data" field // possible race condition when data changed before backend respond @@ -439,7 +439,7 @@ export const onSend = (): AsyncAction => async (dispatch: Dispatch, getState: Ge const nonce = pendingNonce > 0 && pendingNonce >= account.nonce ? pendingNonce : account.nonce; const txData = await dispatch(prepareEthereumTx({ - network: network.network, + network: network.shortcut, token: isToken ? findToken(getState().tokens, account.address, currentState.currency, account.deviceState) : null, from: account.address, to: currentState.address, @@ -487,7 +487,7 @@ export const onSend = (): AsyncAction => async (dispatch: Dispatch, getState: Ge const serializedTx: string = await dispatch(serializeEthereumTx(txData)); const push = await TrezorConnect.pushTransaction({ tx: serializedTx, - coin: network.network, + coin: network.shortcut, }); if (!push.success) { diff --git a/src/actions/SendFormValidationActions.js b/src/actions/SendFormValidationActions.js index 327ccff3..c1a4fe9c 100644 --- a/src/actions/SendFormValidationActions.js +++ b/src/actions/SendFormValidationActions.js @@ -174,7 +174,7 @@ export const addressLabel = ($state: State): PayloadAction => (dispatch: const savedAccounts = getState().accounts.filter(a => a.address.toLowerCase() === address.toLowerCase()); if (savedAccounts.length > 0) { // check if found account belongs to this network - const currentNetworkAccount = savedAccounts.find(a => a.network === network.network); + const currentNetworkAccount = savedAccounts.find(a => a.network === network.shortcut); if (currentNetworkAccount) { const device = findDevice(getState().devices, currentNetworkAccount.deviceID, currentNetworkAccount.deviceState); if (device) { @@ -184,8 +184,8 @@ export const addressLabel = ($state: State): PayloadAction => (dispatch: // corner-case: the same derivation path is used on different networks const otherNetworkAccount = savedAccounts[0]; const device = findDevice(getState().devices, otherNetworkAccount.deviceID, otherNetworkAccount.deviceState); - const { coins } = getState().localStorage.config; - const otherNetwork = coins.find(c => c.network === otherNetworkAccount.network); + const { networks } = getState().localStorage.config; + const otherNetwork = networks.find(c => c.shortcut === otherNetworkAccount.network); if (device && otherNetwork) { state.warnings.address = `Looks like it's ${device.instanceLabel} Account #${(otherNetworkAccount.index + 1)} address of ${otherNetwork.name} network`; } diff --git a/src/actions/TrezorConnectActions.js b/src/actions/TrezorConnectActions.js index b7320a2e..cc51ffab 100644 --- a/src/actions/TrezorConnectActions.js +++ b/src/actions/TrezorConnectActions.js @@ -36,7 +36,7 @@ export type TrezorConnectAction = { type: typeof CONNECT.INITIALIZATION_ERROR, error: string } | { - type: typeof CONNECT.COIN_CHANGED, + type: typeof CONNECT.NETWORK_CHANGED, payload: { network: string } diff --git a/src/actions/Web3Actions.js b/src/actions/Web3Actions.js index 2c3d9131..5cf2607e 100644 --- a/src/actions/Web3Actions.js +++ b/src/actions/Web3Actions.js @@ -57,15 +57,15 @@ export const initWeb3 = (network: string, urlIndex: number = 0): PromiseAction c.network === network); - if (!coin) { - // coin not found + const networkData = config.networks.find(c => c.shortcut === network); + if (!networkData) { + // network not found reject(new Error(`Network ${network} not found in application config.`)); return; } // get first url - const url = coin.web3[urlIndex]; + const url = networkData.web3[urlIndex]; if (!url) { reject(new Error('Web3 backend is not responding')); return; @@ -80,7 +80,7 @@ export const initWeb3 = (network: string, urlIndex: number = 0): PromiseAction ); @@ -52,8 +41,7 @@ class CoinLogo extends PureComponent { } CoinLogo.propTypes = { - coinId: PropTypes.string, - coinNetwork: PropTypes.string, + network: PropTypes.string, }; export default CoinLogo; diff --git a/src/components/notifications/Context/components/Account/index.js b/src/components/notifications/Context/components/Account/index.js index bb980931..5dbddcbc 100644 --- a/src/components/notifications/Context/components/Account/index.js +++ b/src/components/notifications/Context/components/Account/index.js @@ -20,7 +20,7 @@ export default (props: Props) => { [{ label: 'Connect', callback: async () => { - await props.blockchainReconnect(network.network); + await props.blockchainReconnect(network.shortcut); }, }] } diff --git a/src/flowtype/index.js b/src/flowtype/index.js index 44bd5556..f262aa49 100644 --- a/src/flowtype/index.js +++ b/src/flowtype/index.js @@ -150,7 +150,7 @@ export type Action = export type State = ReducersState; // reexport reduces types -export type { Coin } from 'reducers/LocalStorageReducer'; +export type { Network } from 'reducers/LocalStorageReducer'; export type { Account } from 'reducers/AccountsReducer'; export type { Discovery } from 'reducers/DiscoveryReducer'; export type { Token } from 'reducers/TokensReducer'; diff --git a/src/reducers/BlockchainReducer.js b/src/reducers/BlockchainReducer.js index 570c02a5..1b863232 100644 --- a/src/reducers/BlockchainReducer.js +++ b/src/reducers/BlockchainReducer.js @@ -5,7 +5,7 @@ import { BLOCKCHAIN } from 'trezor-connect'; import type { Action } from 'flowtype'; export type BlockchainNetwork = { - +name: string; + +shortcut: string; connected: boolean; } @@ -13,16 +13,16 @@ export type State = Array; export const initialState: State = []; -const find = (state: State, name: string): number => state.findIndex(b => b.name === name); +const find = (state: State, shortcut: string): number => state.findIndex(b => b.shortcut === shortcut); const connect = (state: State, action: any): State => { - const name = action.payload.coin.shortcut.toLowerCase(); + const shortcut = action.payload.coin.shortcut.toLowerCase(); const network: BlockchainNetwork = { - name, + shortcut, connected: true, }; const newState: State = [...state]; - const index: number = find(newState, name); + const index: number = find(newState, shortcut); if (index >= 0) { newState[index] = network; } else { @@ -32,13 +32,13 @@ const connect = (state: State, action: any): State => { }; const disconnect = (state: State, action: any): State => { - const name = action.payload.coin.shortcut.toLowerCase(); + const shortcut = action.payload.coin.shortcut.toLowerCase(); const network: BlockchainNetwork = { - name, + shortcut, connected: false, }; const newState: State = [...state]; - const index: number = find(newState, name); + const index: number = find(newState, shortcut); if (index >= 0) { newState[index] = network; } else { diff --git a/src/reducers/LocalStorageReducer.js b/src/reducers/LocalStorageReducer.js index 27b3d9e2..c9d81925 100644 --- a/src/reducers/LocalStorageReducer.js +++ b/src/reducers/LocalStorageReducer.js @@ -5,9 +5,9 @@ import * as STORAGE from 'actions/constants/localStorage'; import type { Action } from 'flowtype'; -export type Coin = { +export type Network = { name: string; - network: string; + shortcut: string; symbol: string; bip44: string; defaultGasLimit: number; @@ -57,40 +57,27 @@ export type FiatValueTicker = { } export type Config = { - coins: Array; + networks: Array; fiatValueTickers: Array; } -export type CustomBackend = { - name: string; - url: string; -} - export type State = { initialized: boolean; error: ?string; config: Config; ERC20Abi: Array; tokens: TokensCollection; - customBackend: Array; } const initialState: State = { initialized: false, error: null, config: { - coins: [], + networks: [], fiatValueTickers: [], }, ERC20Abi: [], tokens: {}, - customBackend: [ - { - name: 'Custom1', - slug: 'custom1', - url: 'http://google.com', - }, - ], }; export default function localStorage(state: State = initialState, action: Action): State { diff --git a/src/reducers/SelectedAccountReducer.js b/src/reducers/SelectedAccountReducer.js index d00d5f00..fbd4f643 100644 --- a/src/reducers/SelectedAccountReducer.js +++ b/src/reducers/SelectedAccountReducer.js @@ -4,7 +4,7 @@ import * as ACCOUNT from 'actions/constants/account'; import type { Action, Account, - Coin, + Network, Token, PendingTx, Discovery, @@ -13,7 +13,7 @@ import type { export type State = { location: string; account: ?Account; - network: ?Coin; + network: ?Network; tokens: Array, pending: Array, discovery: ?Discovery, diff --git a/src/reducers/utils/index.js b/src/reducers/utils/index.js index 5de5aece..c56cebdd 100644 --- a/src/reducers/utils/index.js +++ b/src/reducers/utils/index.js @@ -6,7 +6,7 @@ import type { Device, TrezorDevice, Account, - Coin, + Network, Discovery, Token, PendingTx, @@ -66,13 +66,13 @@ export const getSelectedAccount = (state: State): ?Account => { return state.accounts.find(a => a.deviceState === device.state && a.index === index && a.network === locationState.network); }; -export const getSelectedNetwork = (state: State): ?Coin => { +export const getSelectedNetwork = (state: State): ?Network => { const device = state.wallet.selectedDevice; - const { coins } = state.localStorage.config; + const { networks } = state.localStorage.config; const locationState = state.router.location.state; if (!device || !locationState.network) return null; - return coins.find(c => c.network === locationState.network); + return networks.find(c => c.shortcut === locationState.network); }; export const getDiscoveryProcess = (state: State): ?Discovery => { diff --git a/src/services/WalletService.js b/src/services/WalletService.js index 24b35496..597f1b3c 100644 --- a/src/services/WalletService.js +++ b/src/services/WalletService.js @@ -70,10 +70,10 @@ const WalletService: Middleware = (api: MiddlewareAPI) => (next: MiddlewareDispa const prevLocation = prevState.router.location; const currentLocation = api.getState().router.location; if (action.type === LOCATION_CHANGE && prevLocation.pathname !== currentLocation.pathname) { - // watch for coin change + // watch for network change if (prevLocation.state.network !== currentLocation.state.network) { api.dispatch({ - type: CONNECT.COIN_CHANGED, + type: CONNECT.NETWORK_CHANGED, payload: { network: currentLocation.state.network, }, diff --git a/src/views/Wallet/components/LeftNavigation/components/AccountMenu/index.js b/src/views/Wallet/components/LeftNavigation/components/AccountMenu/index.js index ba6cf83a..dfd38016 100644 --- a/src/views/Wallet/components/LeftNavigation/components/AccountMenu/index.js +++ b/src/views/Wallet/components/LeftNavigation/components/AccountMenu/index.js @@ -115,11 +115,11 @@ const AccountMenu = (props: Props) => { const baseUrl: string = urlParams.deviceInstance ? `/device/${urlParams.device}:${urlParams.deviceInstance}` : `/device/${urlParams.device}`; const { config } = props.localStorage; - const selectedCoin = config.coins.find(c => c.network === location.state.network); + const network = config.networks.find(c => c.shortcut === location.state.network); - if (!selected || !selectedCoin) return null; + if (!selected || !network) return null; - const fiatRate = props.fiat.find(f => f.network === selectedCoin.network); + const fiatRate = props.fiat.find(f => f.network === network.shortcut); const deviceAccounts: Accounts = findDeviceAccounts(accounts, selected, location.state.network); @@ -130,14 +130,14 @@ const AccountMenu = (props: Props) => { let balance: string = 'Loading...'; if (account.balance !== '') { const pending = stateUtils.getAccountPendingTx(props.pending, account); - const pendingAmount: BigNumber = stateUtils.getPendingAmount(pending, selectedCoin.symbol); + const pendingAmount: BigNumber = stateUtils.getPendingAmount(pending, network.symbol); const availableBalance: string = new BigNumber(account.balance).minus(pendingAmount).toString(10); - balance = `${availableBalance} ${selectedCoin.symbol}`; + balance = `${availableBalance} ${network.symbol}`; if (fiatRate) { const accountBalance = new BigNumber(availableBalance); const fiat = accountBalance.times(fiatRate.value).toFixed(2); - balance = `${availableBalance} ${selectedCoin.symbol} / $${fiat}`; + balance = `${availableBalance} ${network.symbol} / $${fiat}`; } } @@ -233,21 +233,19 @@ const AccountMenu = (props: Props) => { return ( - {selectedCoin && ( - - - - )} + + + {selectedAccounts} diff --git a/src/views/Wallet/components/LeftNavigation/components/CoinMenu/index.js b/src/views/Wallet/components/LeftNavigation/components/CoinMenu/index.js index 8391bc17..6d262662 100644 --- a/src/views/Wallet/components/LeftNavigation/components/CoinMenu/index.js +++ b/src/views/Wallet/components/LeftNavigation/components/CoinMenu/index.js @@ -37,9 +37,9 @@ class CoinMenu extends PureComponent { return coins.map((coin) => { const row = ( { const { config } = this.props.localStorage; return ( - {config.coins.map(item => ( + {config.networks.map(item => ( diff --git a/src/views/Wallet/components/LeftNavigation/components/RowCoin/index.js b/src/views/Wallet/components/LeftNavigation/components/RowCoin/index.js index 4ffc780b..472f6d1a 100644 --- a/src/views/Wallet/components/LeftNavigation/components/RowCoin/index.js +++ b/src/views/Wallet/components/LeftNavigation/components/RowCoin/index.js @@ -38,7 +38,7 @@ const IconWrapper = styled.div` `; const RowCoin = ({ - coin, iconLeft, iconRight, + network, iconLeft, iconRight, }) => ( @@ -53,11 +53,8 @@ const RowCoin = ({ )} - -

{coin.name}

+ +

{network.name}

{iconRight && ( @@ -77,10 +74,9 @@ const iconShape = { size: PropTypes.number.isRequired, }; RowCoin.propTypes = { - coin: PropTypes.shape({ + network: PropTypes.shape({ name: PropTypes.string.isRequired, - network: PropTypes.string, - id: PropTypes.string, + shortcut: PropTypes.string, }).isRequired, iconLeft: PropTypes.shape(iconShape), iconRight: PropTypes.shape(iconShape), diff --git a/src/views/Wallet/views/Account/Send/components/PendingTransactions/index.js b/src/views/Wallet/views/Account/Send/components/PendingTransactions/index.js index 418c3a0c..63c5dfb8 100644 --- a/src/views/Wallet/views/Account/Send/components/PendingTransactions/index.js +++ b/src/views/Wallet/views/Account/Send/components/PendingTransactions/index.js @@ -7,14 +7,14 @@ import { H2 } from 'components/Heading'; import Link from 'components/Link'; import ScaleText from 'react-scale-text'; -import type { Coin } from 'reducers/LocalStorageReducer'; +import type { Network } from 'reducers/LocalStorageReducer'; import type { Token } from 'reducers/TokensReducer'; import type { Props as BaseProps } from '../../Container'; type Props = { pending: $PropertyType<$ElementType, 'pending'>, tokens: $PropertyType<$ElementType, 'tokens'>, - network: Coin + network: Network } const Wrapper = styled.div` diff --git a/src/views/Wallet/views/Account/Summary/components/Balance/index.js b/src/views/Wallet/views/Account/Summary/components/Balance/index.js index 09e38769..1968abe1 100644 --- a/src/views/Wallet/views/Account/Summary/components/Balance/index.js +++ b/src/views/Wallet/views/Account/Summary/components/Balance/index.js @@ -7,11 +7,11 @@ import colors from 'config/colors'; import ICONS from 'config/icons'; import { FONT_SIZE, FONT_WEIGHT } from 'config/variables'; -import type { Coin } from 'reducers/LocalStorageReducer'; +import type { Network } from 'flowtype'; import type { Props as BaseProps } from '../../Container'; type Props = { - coin: Coin, + network: Network, balance: string, fiat: $ElementType, } @@ -77,7 +77,7 @@ const BalanceRateWrapper = styled(BalanceWrapper)` padding-left: 50px; `; -const CoinBalace = styled.div` +const CoinBalance = styled.div` font-size: ${FONT_SIZE.SMALLER}; color: ${colors.TEXT_SECONDARY}; `; @@ -97,7 +97,7 @@ class AccountBalance extends PureComponent { }; } - handleHideBallanceIconClick() { + handleHideBalanceIconClick() { this.setState(previousState => ({ isHidden: !previousState.isHidden, canAnimateHideBalanceIcon: true, @@ -105,8 +105,8 @@ class AccountBalance extends PureComponent { } render() { - const selectedCoin = this.props.coin; - const fiatRate: any = this.props.fiat.find(f => f.network === selectedCoin.network); + const { network } = this.props; + const fiatRate: any = this.props.fiat.find(f => f.network === network.shortcut); let accountBalance = ''; let fiatRateValue = ''; @@ -121,7 +121,7 @@ class AccountBalance extends PureComponent { return ( this.handleHideBallanceIconClick()} + onClick={() => this.handleHideBalanceIconClick()} > { {fiatRate && ( ${fiat} )} - {this.props.balance} {selectedCoin.symbol} + {this.props.balance} {network.symbol} {fiatRate && ( ${fiatRateValue} - 1.00 {selectedCoin.symbol} + 1.00 {network.symbol} )} diff --git a/src/views/Wallet/views/Account/Summary/index.js b/src/views/Wallet/views/Account/Summary/index.js index 3be7a769..6dc91de2 100644 --- a/src/views/Wallet/views/Account/Summary/index.js +++ b/src/views/Wallet/views/Account/Summary/index.js @@ -81,18 +81,15 @@ const AccountSummary = (props: Props) => { - +

Account #{parseInt(account.index, 10) + 1}

See full transaction history

Tokens

@@ -108,11 +105,6 @@ const AccountSummary = (props: Props) => { />
- {/* 0x58cda554935e4a1f2acbe15f8757400af275e084 Lahod */} - {/* 0x58cda554935e4a1f2acbe15f8757400af275e084 T01 */} - - {/* TOOO: AsyncSelect is lagging when dropdown menu must show more than 200 items */} - {/* TODO: Input's box-shadow */} Date: Tue, 16 Oct 2018 11:28:46 +0200 Subject: [PATCH 02/12] quickfix: Receive tab modal context condition --- src/views/Wallet/views/Account/Receive/index.js | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/views/Wallet/views/Account/Receive/index.js b/src/views/Wallet/views/Account/Receive/index.js index 99830694..3f2eb160 100644 --- a/src/views/Wallet/views/Account/Receive/index.js +++ b/src/views/Wallet/views/Account/Receive/index.js @@ -1,17 +1,19 @@ /* @flow */ import React from 'react'; +import { QRCode } from 'react-qr-svg'; import styled, { css } from 'styled-components'; + import { H2 } from 'components/Heading'; import Button from 'components/Button'; import Icon from 'components/Icon'; -import ICONS from 'config/icons'; -import Content from 'views/Wallet/components/Content'; -import colors from 'config/colors'; - import Tooltip from 'components/Tooltip'; -import { QRCode } from 'react-qr-svg'; +import ICONS from 'config/icons'; +import colors from 'config/colors'; import { FONT_SIZE, FONT_WEIGHT, FONT_FAMILY } from 'config/variables'; +import { CONTEXT_DEVICE } from 'actions/constants/modal'; + +import Content from 'views/Wallet/components/Content'; import VerifyAddressTooltip from './components/VerifyAddressTooltip'; import type { Props } from './Container'; @@ -148,7 +150,7 @@ const AccountReceive = (props: Props) => { addressUnverified, } = props.receive; - const isAddressVerifying = props.modal.context === 'device' && props.modal.windowType === 'ButtonRequest_Address'; + const isAddressVerifying = props.modal.context === CONTEXT_DEVICE && props.modal.windowType === 'ButtonRequest_Address'; const isAddressHidden = !isAddressVerifying && !addressVerified && !addressUnverified; let address = `${account.address.substring(0, 20)}...`; From 5a686cf9dff4c4c27aab3d3db77eea609b9ea68e Mon Sep 17 00:00:00 2001 From: Szymon Lesisz Date: Tue, 16 Oct 2018 16:15:06 +0200 Subject: [PATCH 03/12] indicator fixes - indicator animation ignored on 'resize' event - fixed initial rendering - working with element ref insead of document.querySelector --- .../components/Indicator/index.js | 60 ++++++++++++------- .../components/TopNavigationAccount/index.js | 34 ++++++----- 2 files changed, 57 insertions(+), 37 deletions(-) diff --git a/src/views/Wallet/components/TopNavigationAccount/components/Indicator/index.js b/src/views/Wallet/components/TopNavigationAccount/components/Indicator/index.js index 75045d74..9a414a7d 100644 --- a/src/views/Wallet/components/TopNavigationAccount/components/Indicator/index.js +++ b/src/views/Wallet/components/TopNavigationAccount/components/Indicator/index.js @@ -1,18 +1,20 @@ /* @flow */ -import styled from 'styled-components'; +import styled, { css } from 'styled-components'; import colors from 'config/colors'; import React, { PureComponent } from 'react'; type Props = { - + pathname: string; + wrapper: ?HTMLElement; } type State = { style: { width: number; left: number; - } + }, + shouldAnimate: boolean, } const Wrapper = styled.div` @@ -22,7 +24,9 @@ const Wrapper = styled.div` width: 100px; height: 2px; background: ${colors.GREEN_PRIMARY}; - transition: all 0.3s ease-in-out; + ${props => props.animation && css` + transition: all 0.3s ease-in-out; + `} `; class Indicator extends PureComponent { @@ -34,52 +38,62 @@ class Indicator extends PureComponent { width: 0, left: 0, }, + shouldAnimate: false, }; - this.reposition = this.reposition.bind(this); + this.handleResize = this.handleResize.bind(this); } componentDidMount() { - this.reposition(); - window.addEventListener('resize', this.reposition, false); + window.addEventListener('resize', this.handleResize, false); + } + + componentWillReceiveProps(newProps: Props) { + if (this.props.pathname !== newProps.pathname) { + this.setState({ + shouldAnimate: true, + }); + } } componentDidUpdate() { - this.reposition(); + this.reposition(false); } componentWillUnmount() { - window.removeEventListener('resize', this.reposition, false); + window.removeEventListener('resize', this.handleResize, false); + } + + handleResize() { + this.reposition(); } - reposition() { - const tabs = document.querySelector('.account-tabs'); - if (!tabs) return; - const active = tabs.querySelector('.active'); + handleResize: () => void; + + reposition(resetAnimation: boolean = true) { + if (!this.props.wrapper) return; + const { wrapper } = this.props; + const active = wrapper.querySelector('.active'); if (!active) return; const bounds = active.getBoundingClientRect(); + const left = bounds.left - wrapper.getBoundingClientRect().left; + const { state } = this; - const left = bounds.left - tabs.getBoundingClientRect().left; - - if (this.state.style.left !== left) { + if (state.style.left !== left) { this.setState({ style: { width: bounds.width, left, }, + shouldAnimate: resetAnimation ? false : state.shouldAnimate, }); } } - reposition: () => void; - - handleResize() { - this.reposition(); - } - render() { + if (!this.props.wrapper) return null; return ( - + ); } } diff --git a/src/views/Wallet/components/TopNavigationAccount/index.js b/src/views/Wallet/components/TopNavigationAccount/index.js index aef26440..2d0f105e 100644 --- a/src/views/Wallet/components/TopNavigationAccount/index.js +++ b/src/views/Wallet/components/TopNavigationAccount/index.js @@ -47,22 +47,28 @@ const StyledNavLink = styled(NavLink)` } `; +class TopNavigationAccount extends React.PureComponent { + wrapperRefCallback = (element: ?HTMLElement) => { + this.wrapper = element; + } -const TopNavigationAccount = (props: Props) => { - const { state, pathname } = props.location; - if (!state) return null; + wrapper: ?HTMLElement; - const basePath = `/device/${state.device}/network/${state.network}/account/${state.account}`; + render() { + const { state, pathname } = this.props.location; + if (!state) return null; - return ( - - Summary - Receive - Send - {/* Sign & Verify */} - - - ); -}; + const basePath = `/device/${state.device}/network/${state.network}/account/${state.account}`; + return ( + + Summary + Receive + Send + {/* Sign & Verify */} + + + ); + } +} export default TopNavigationAccount; \ No newline at end of file From 254d1c54842dce48ed05dc08cb43a117a8ab64a9 Mon Sep 17 00:00:00 2001 From: Vladimir Volek Date: Wed, 17 Oct 2018 00:36:08 +0200 Subject: [PATCH 04/12] TREZOR -> Trezor --- src/components/Header/index.js | 2 +- src/components/modals/confirm/Address/index.js | 2 +- .../modals/confirm/UnverifiedAddress/index.js | 2 +- src/components/modals/device/Forget/index.js | 2 +- src/components/modals/device/Remember/index.js | 2 +- src/components/modals/external/NemWallet/index.js | 2 +- src/components/modals/pin/Pin/index.js | 2 +- src/index.html | 2 +- src/views/Landing/components/ConnectDevice/index.js | 10 +++++----- src/views/Landing/views/InstallBridge/index.js | 4 ++-- .../Receive/components/VerifyAddressTooltip/index.js | 4 ++-- src/views/Wallet/views/Account/Receive/index.js | 2 +- 12 files changed, 18 insertions(+), 18 deletions(-) diff --git a/src/components/Header/index.js b/src/components/Header/index.js index 798b9d2b..823701a7 100644 --- a/src/components/Header/index.js +++ b/src/components/Header/index.js @@ -75,7 +75,7 @@ const Header = (): React$Element => ( - TREZOR + Trezor Wiki Blog Support diff --git a/src/components/modals/confirm/Address/index.js b/src/components/modals/confirm/Address/index.js index 9581561d..05314500 100644 --- a/src/components/modals/confirm/Address/index.js +++ b/src/components/modals/confirm/Address/index.js @@ -41,7 +41,7 @@ const ConfirmAddress = (props: Props) => { return (
-

Confirm address on TREZOR

+

Confirm address on Trezor

Please compare your address on device with address shown bellow.

diff --git a/src/components/modals/confirm/UnverifiedAddress/index.js b/src/components/modals/confirm/UnverifiedAddress/index.js index 992d3325..cb7c7e7b 100644 --- a/src/components/modals/confirm/UnverifiedAddress/index.js +++ b/src/components/modals/confirm/UnverifiedAddress/index.js @@ -102,7 +102,7 @@ class ConfirmUnverifiedAddress extends PureComponent {

{ deviceStatus }

- To prevent phishing attacks, you should verify the address on your TREZOR first. { claim } to continue with the verification process. + To prevent phishing attacks, you should verify the address on your Trezor first. { claim } to continue with the verification process. (!account ? this.verifyAddress() : 'false')}>Try again this.showUnverifiedAddress()}>Show unverified address diff --git a/src/components/modals/device/Forget/index.js b/src/components/modals/device/Forget/index.js index d20702ca..b0607d4d 100644 --- a/src/components/modals/device/Forget/index.js +++ b/src/components/modals/device/Forget/index.js @@ -63,7 +63,7 @@ class ForgetDevice extends PureComponent { return (

Forget { this.props.device.instanceLabel }?

- Forgetting only removes the device from the list on the left, your coins are still safe and you can access them by reconnecting your TREZOR again. + Forgetting only removes the device from the list on the left, your coins are still safe and you can access them by reconnecting your Trezor again. this.forget()}>Forget Don't forget diff --git a/src/components/modals/device/Remember/index.js b/src/components/modals/device/Remember/index.js index 937e04bc..38de9115 100644 --- a/src/components/modals/device/Remember/index.js +++ b/src/components/modals/device/Remember/index.js @@ -126,7 +126,7 @@ class RememberDevice extends PureComponent { return (

Forget {label}?

- Would you like TREZOR Wallet to forget your { devicePlural }, so that it is still visible even while disconnected? + Would you like Trezor Wallet to forget your { devicePlural }, so that it is still visible even while disconnected? this.forget()}> diff --git a/src/components/modals/external/NemWallet/index.js b/src/components/modals/external/NemWallet/index.js index 468fe3a0..74fcefd0 100644 --- a/src/components/modals/external/NemWallet/index.js +++ b/src/components/modals/external/NemWallet/index.js @@ -53,7 +53,7 @@ const NemWallet = (props: Props) => (

NEM Wallet

We have partnered up with the NEM Foundation to provide you with a full-fledged NEM Wallet.

-

Make sure you download the Universal Client for TREZOR support.

+

Make sure you download the Universal Client for Trezor support.

i.id === 'xem').url}> Go to nem.io diff --git a/src/components/modals/pin/Pin/index.js b/src/components/modals/pin/Pin/index.js index 7a8eed98..ed74e834 100644 --- a/src/components/modals/pin/Pin/index.js +++ b/src/components/modals/pin/Pin/index.js @@ -147,7 +147,7 @@ class Pin extends PureComponent { return (

Enter { device.label } PIN

-

The PIN layout is displayed on your TREZOR.

+

The PIN layout is displayed on your Trezor.

this.onPinBackspace()} /> diff --git a/src/index.html b/src/index.html index 348f47f1..7278523f 100644 --- a/src/index.html +++ b/src/index.html @@ -4,7 +4,7 @@ - Ethereum Wallet | TREZOR + Ethereum Wallet | Trezor diff --git a/src/views/Landing/components/ConnectDevice/index.js b/src/views/Landing/components/ConnectDevice/index.js index 83c73cfb..7fb3c21f 100644 --- a/src/views/Landing/components/ConnectDevice/index.js +++ b/src/views/Landing/components/ConnectDevice/index.js @@ -108,8 +108,8 @@ class ConnectDevice extends PureComponent {
<H2 claim>The private bank in your hands.</H2> - <P>TREZOR Wallet is an easy-to-use interface for your TREZOR.</P> - <P>TREZOR Wallet allows you to easily control your funds, manage your balance and initiate transfers.</P> + <P>Trezor Wallet is an easy-to-use interface for your Trezor.</P> + <P>Trezor Wallet allows you to easily control your funds, manage your balance and initiate transfers.</P> @@ -118,7 +118,7 @@ class ConnectDevice extends PureComponent { {!this.props.showDisconnect && ( {this.getTrezorDeviceImage()} - Connect TREZOR + Connect Trezor )} @@ -141,13 +141,13 @@ class ConnectDevice extends PureComponent { Try installing the TREZOR Bridge. + >Try installing the Trezor Bridge.

)}

- Don't have TREZOR? + Don't have Trezor? { - TREZOR Bridge{this.state.currentVersion} -

New communication tool to facilitate the connection between your TREZOR and your internet browser.

+ Trezor Bridge{this.state.currentVersion} +

New communication tool to facilitate the connection between your Trezor and your internet browser.

{addressUnverified && ( - Unverified address. {isConnected && isAvailable ? 'Show on TREZOR' : 'Connect your TREZOR to verify it.'} + Unverified address. {isConnected && isAvailable ? 'Show on Trezor' : 'Connect your Trezor to verify it.'} )} {!addressUnverified && ( - {isConnected ? 'Show on TREZOR' : 'Connect your TREZOR to verify address.'} + {isConnected ? 'Show on Trezor' : 'Connect your Trezor to verify address.'} )}
diff --git a/src/views/Wallet/views/Account/Receive/index.js b/src/views/Wallet/views/Account/Receive/index.js index 3f2eb160..0ab6b908 100644 --- a/src/views/Wallet/views/Account/Receive/index.js +++ b/src/views/Wallet/views/Account/Receive/index.js @@ -166,7 +166,7 @@ const AccountReceive = (props: Props) => { isShowingQrCode={addressVerified || addressUnverified} > {isAddressVerifying && ( - Confirm address on TREZOR + Confirm address on Trezor )} {((addressVerified || addressUnverified) && !isAddressVerifying) && ( Date: Wed, 17 Oct 2018 00:36:08 +0200 Subject: [PATCH 05/12] TREZOR -> Trezor --- src/components/Header/index.js | 2 +- src/components/modals/confirm/Address/index.js | 2 +- .../modals/confirm/UnverifiedAddress/index.js | 2 +- src/components/modals/device/Forget/index.js | 2 +- src/components/modals/device/Remember/index.js | 2 +- src/components/modals/external/NemWallet/index.js | 2 +- src/components/modals/pin/Pin/index.js | 2 +- src/index.html | 2 +- src/views/Landing/components/ConnectDevice/index.js | 10 +++++----- src/views/Landing/views/InstallBridge/index.js | 4 ++-- .../Receive/components/VerifyAddressTooltip/index.js | 4 ++-- src/views/Wallet/views/Account/Receive/index.js | 2 +- 12 files changed, 18 insertions(+), 18 deletions(-) diff --git a/src/components/Header/index.js b/src/components/Header/index.js index 798b9d2b..823701a7 100644 --- a/src/components/Header/index.js +++ b/src/components/Header/index.js @@ -75,7 +75,7 @@ const Header = (): React$Element => ( - TREZOR + Trezor Wiki Blog Support diff --git a/src/components/modals/confirm/Address/index.js b/src/components/modals/confirm/Address/index.js index 9581561d..05314500 100644 --- a/src/components/modals/confirm/Address/index.js +++ b/src/components/modals/confirm/Address/index.js @@ -41,7 +41,7 @@ const ConfirmAddress = (props: Props) => { return (
-

Confirm address on TREZOR

+

Confirm address on Trezor

Please compare your address on device with address shown bellow.

diff --git a/src/components/modals/confirm/UnverifiedAddress/index.js b/src/components/modals/confirm/UnverifiedAddress/index.js index 992d3325..cb7c7e7b 100644 --- a/src/components/modals/confirm/UnverifiedAddress/index.js +++ b/src/components/modals/confirm/UnverifiedAddress/index.js @@ -102,7 +102,7 @@ class ConfirmUnverifiedAddress extends PureComponent {

{ deviceStatus }

- To prevent phishing attacks, you should verify the address on your TREZOR first. { claim } to continue with the verification process. + To prevent phishing attacks, you should verify the address on your Trezor first. { claim } to continue with the verification process. (!account ? this.verifyAddress() : 'false')}>Try again this.showUnverifiedAddress()}>Show unverified address diff --git a/src/components/modals/device/Forget/index.js b/src/components/modals/device/Forget/index.js index d20702ca..b0607d4d 100644 --- a/src/components/modals/device/Forget/index.js +++ b/src/components/modals/device/Forget/index.js @@ -63,7 +63,7 @@ class ForgetDevice extends PureComponent { return (

Forget { this.props.device.instanceLabel }?

- Forgetting only removes the device from the list on the left, your coins are still safe and you can access them by reconnecting your TREZOR again. + Forgetting only removes the device from the list on the left, your coins are still safe and you can access them by reconnecting your Trezor again. this.forget()}>Forget Don't forget diff --git a/src/components/modals/device/Remember/index.js b/src/components/modals/device/Remember/index.js index 937e04bc..38de9115 100644 --- a/src/components/modals/device/Remember/index.js +++ b/src/components/modals/device/Remember/index.js @@ -126,7 +126,7 @@ class RememberDevice extends PureComponent { return (

Forget {label}?

- Would you like TREZOR Wallet to forget your { devicePlural }, so that it is still visible even while disconnected? + Would you like Trezor Wallet to forget your { devicePlural }, so that it is still visible even while disconnected? this.forget()}> diff --git a/src/components/modals/external/NemWallet/index.js b/src/components/modals/external/NemWallet/index.js index 468fe3a0..74fcefd0 100644 --- a/src/components/modals/external/NemWallet/index.js +++ b/src/components/modals/external/NemWallet/index.js @@ -53,7 +53,7 @@ const NemWallet = (props: Props) => (

NEM Wallet

We have partnered up with the NEM Foundation to provide you with a full-fledged NEM Wallet.

-

Make sure you download the Universal Client for TREZOR support.

+

Make sure you download the Universal Client for Trezor support.

i.id === 'xem').url}> Go to nem.io diff --git a/src/components/modals/pin/Pin/index.js b/src/components/modals/pin/Pin/index.js index 7a8eed98..ed74e834 100644 --- a/src/components/modals/pin/Pin/index.js +++ b/src/components/modals/pin/Pin/index.js @@ -147,7 +147,7 @@ class Pin extends PureComponent { return (

Enter { device.label } PIN

-

The PIN layout is displayed on your TREZOR.

+

The PIN layout is displayed on your Trezor.

this.onPinBackspace()} /> diff --git a/src/index.html b/src/index.html index 348f47f1..7278523f 100644 --- a/src/index.html +++ b/src/index.html @@ -4,7 +4,7 @@ - Ethereum Wallet | TREZOR + Ethereum Wallet | Trezor diff --git a/src/views/Landing/components/ConnectDevice/index.js b/src/views/Landing/components/ConnectDevice/index.js index 83c73cfb..7fb3c21f 100644 --- a/src/views/Landing/components/ConnectDevice/index.js +++ b/src/views/Landing/components/ConnectDevice/index.js @@ -108,8 +108,8 @@ class ConnectDevice extends PureComponent {
<H2 claim>The private bank in your hands.</H2> - <P>TREZOR Wallet is an easy-to-use interface for your TREZOR.</P> - <P>TREZOR Wallet allows you to easily control your funds, manage your balance and initiate transfers.</P> + <P>Trezor Wallet is an easy-to-use interface for your Trezor.</P> + <P>Trezor Wallet allows you to easily control your funds, manage your balance and initiate transfers.</P> @@ -118,7 +118,7 @@ class ConnectDevice extends PureComponent { {!this.props.showDisconnect && ( {this.getTrezorDeviceImage()} - Connect TREZOR + Connect Trezor )} @@ -141,13 +141,13 @@ class ConnectDevice extends PureComponent { Try installing the TREZOR Bridge. + >Try installing the Trezor Bridge.

)}

- Don't have TREZOR? + Don't have Trezor? { - TREZOR Bridge{this.state.currentVersion} -

New communication tool to facilitate the connection between your TREZOR and your internet browser.

+ Trezor Bridge{this.state.currentVersion} +

New communication tool to facilitate the connection between your Trezor and your internet browser.

{addressUnverified && ( - Unverified address. {isConnected && isAvailable ? 'Show on TREZOR' : 'Connect your TREZOR to verify it.'} + Unverified address. {isConnected && isAvailable ? 'Show on Trezor' : 'Connect your Trezor to verify it.'} )} {!addressUnverified && ( - {isConnected ? 'Show on TREZOR' : 'Connect your TREZOR to verify address.'} + {isConnected ? 'Show on Trezor' : 'Connect your Trezor to verify address.'} )}
diff --git a/src/views/Wallet/views/Account/Receive/index.js b/src/views/Wallet/views/Account/Receive/index.js index 3f2eb160..0ab6b908 100644 --- a/src/views/Wallet/views/Account/Receive/index.js +++ b/src/views/Wallet/views/Account/Receive/index.js @@ -166,7 +166,7 @@ const AccountReceive = (props: Props) => { isShowingQrCode={addressVerified || addressUnverified} > {isAddressVerifying && ( - Confirm address on TREZOR + Confirm address on Trezor )} {((addressVerified || addressUnverified) && !isAddressVerifying) && ( Date: Wed, 17 Oct 2018 12:09:25 +0200 Subject: [PATCH 06/12] added beta-wallet disclaimer - Added BetaDiscialmer component used in Landing/RootView - refactoring LocalStorageActions (moved logic from LocalStorageService) --- src/actions/LocalStorageActions.js | 332 ++++++++++-------- src/actions/ModalActions.js | 2 - src/actions/RouterActions.js | 2 +- src/actions/WalletActions.js | 6 + src/actions/constants/wallet.js | 2 + src/reducers/WalletReducer.js | 14 +- src/services/LocalStorageService.js | 75 +--- .../components/BetaDisclaimer/index.js | 80 +++++ src/views/Landing/views/Root/index.js | 3 + 9 files changed, 311 insertions(+), 205 deletions(-) create mode 100644 src/views/Landing/components/BetaDisclaimer/index.js diff --git a/src/actions/LocalStorageActions.js b/src/actions/LocalStorageActions.js index ae1c04c2..49fbf0fa 100644 --- a/src/actions/LocalStorageActions.js +++ b/src/actions/LocalStorageActions.js @@ -7,11 +7,23 @@ import * as TOKEN from 'actions/constants/token'; import * as DISCOVERY from 'actions/constants/discovery'; import * as STORAGE from 'actions/constants/localStorage'; import * as PENDING from 'actions/constants/pendingTx'; +import * as WALLET from 'actions/constants/wallet'; import { httpRequest } from 'utils/networkUtils'; import * as buildUtils from 'utils/build'; +import { findAccountTokens } from 'reducers/TokensReducer'; +import type { Account } from 'reducers/AccountsReducer'; +import type { Token } from 'reducers/TokensReducer'; +import type { PendingTx } from 'reducers/PendingTxReducer'; +import type { Discovery } from 'reducers/DiscoveryReducer'; + + import type { - ThunkAction, AsyncAction, /* GetState, */ Dispatch, + TrezorDevice, + ThunkAction, + AsyncAction, + GetState, + Dispatch, } from 'flowtype'; import type { Config, Network, TokensCollection } from 'reducers/LocalStorageReducer'; @@ -31,7 +43,7 @@ export type StorageAction = { error: string, }; -export const get = (key: string): ?string => { +const get = (key: string): ?string => { try { return window.localStorage.getItem(key); } catch (error) { @@ -40,168 +52,212 @@ export const get = (key: string): ?string => { } }; -export function update(event: StorageEvent): AsyncAction { - return async (dispatch: Dispatch/* , getState: GetState */): Promise => { - if (!event.newValue) return; +const set = (key: string, value: string | boolean): void => { + try { + window.localStorage.setItem(key, value); + } catch (error) { + console.error(`Local Storage ERROR: ${error}`); + } +}; - if (event.key === 'devices') { - // check if device was added/ removed - // const newDevices: Array = JSON.parse(event.newValue); - // const myDevices: Array = getState().connect.devices.filter(d => d.features); +// https://github.com/STRML/react-localstorage/blob/master/react-localstorage.js +// or +// https://www.npmjs.com/package/redux-react-session - // if (newDevices.length !== myDevices.length) { - // const diff = myDevices.filter(d => newDevices.indexOf(d) < 0) - // console.warn("DEV LIST CHANGED!", newDevices.length, myDevices.length, diff) - // // check if difference is caused by local device which is not saved - // // or device which was saved in other tab - // } +const findAccounts = (devices: Array, accounts: Array): Array => devices.reduce((arr, dev) => arr.concat(accounts.filter(a => a.deviceState === dev.state)), []); - // const diff = oldDevices.filter(d => newDevices.indexOf()) - } +const findTokens = (accounts: Array, tokens: Array): Array => accounts.reduce((arr, account) => arr.concat(findAccountTokens(tokens, account)), []); - if (event.key === 'accounts') { - dispatch({ - type: ACCOUNT.FROM_STORAGE, - payload: JSON.parse(event.newValue), - }); - } +const findDiscovery = (devices: Array, discovery: Array): Array => devices.reduce((arr, dev) => arr.concat(discovery.filter(a => a.deviceState === dev.state && a.publicKey.length > 0)), []); - if (event.key === 'tokens') { - dispatch({ - type: TOKEN.FROM_STORAGE, - payload: JSON.parse(event.newValue), - }); - } +const findPendingTxs = (accounts: Array, pending: Array): Array => accounts.reduce((result, account) => result.concat(pending.filter(p => p.address === account.address && p.network === account.network)), []); - if (event.key === 'pending') { - dispatch({ - type: PENDING.FROM_STORAGE, - payload: JSON.parse(event.newValue), - }); - } +export const save = (): ThunkAction => (dispatch: Dispatch, getState: GetState): void => { + const devices: Array = getState().devices.filter(d => d.features && d.remember === true); + const accounts: Array = findAccounts(devices, getState().accounts); + const tokens: Array = findTokens(accounts, getState().tokens); + const pending: Array = findPendingTxs(accounts, getState().pending); + const discovery: Array = findDiscovery(devices, getState().discovery); - if (event.key === 'discovery') { - dispatch({ - type: DISCOVERY.FROM_STORAGE, - payload: JSON.parse(event.newValue), - }); - } - }; -} + // save devices + set('devices', JSON.stringify(devices)); + + // save already preloaded accounts + set('accounts', JSON.stringify(accounts)); + + // save discovery state + set('discovery', JSON.stringify(discovery)); + + // tokens + set('tokens', JSON.stringify(tokens)); + + // pending transactions + set('pending', JSON.stringify(pending)); +}; + +export const update = (event: StorageEvent): ThunkAction => (dispatch: Dispatch): void => { + if (!event.newValue) return; + + if (event.key === 'devices') { + // check if device was added/ removed + // const newDevices: Array = JSON.parse(event.newValue); + // const myDevices: Array = getState().connect.devices.filter(d => d.features); + + // if (newDevices.length !== myDevices.length) { + // const diff = myDevices.filter(d => newDevices.indexOf(d) < 0) + // console.warn("DEV LIST CHANGED!", newDevices.length, myDevices.length, diff) + // // check if difference is caused by local device which is not saved + // // or device which was saved in other tab + // } + + // const diff = oldDevices.filter(d => newDevices.indexOf()) + } + + if (event.key === 'accounts') { + dispatch({ + type: ACCOUNT.FROM_STORAGE, + payload: JSON.parse(event.newValue), + }); + } + + if (event.key === 'tokens') { + dispatch({ + type: TOKEN.FROM_STORAGE, + payload: JSON.parse(event.newValue), + }); + } + + if (event.key === 'pending') { + dispatch({ + type: PENDING.FROM_STORAGE, + payload: JSON.parse(event.newValue), + }); + } + + if (event.key === 'discovery') { + dispatch({ + type: DISCOVERY.FROM_STORAGE, + payload: JSON.parse(event.newValue), + }); + } +}; const VERSION: string = '1'; -export function loadTokensFromJSON(): AsyncAction { - return async (dispatch: Dispatch): Promise => { - if (typeof window.localStorage === 'undefined') return; +const loadJSON = (): AsyncAction => async (dispatch: Dispatch): Promise => { + if (typeof window.localStorage === 'undefined') return; - try { - const config: Config = await httpRequest(AppConfigJSON, 'json'); + try { + const config: Config = await httpRequest(AppConfigJSON, 'json'); - if (!buildUtils.isDev()) { - const index = config.networks.findIndex(c => c.shortcut === 'trop'); - delete config.networks[index]; - } + if (!buildUtils.isDev()) { + const index = config.networks.findIndex(c => c.shortcut === 'trop'); + delete config.networks[index]; + } - const ERC20Abi = await httpRequest(Erc20AbiJSON, 'json'); + const ERC20Abi = await httpRequest(Erc20AbiJSON, 'json'); - window.addEventListener('storage', (event) => { - dispatch(update(event)); - }); + window.addEventListener('storage', (event) => { + dispatch(update(event)); + }); - // validate version - const version: ?string = get('version'); - if (version !== VERSION) { + // validate version + const version: ?string = get('version'); + if (version !== VERSION) { + try { window.localStorage.clear(); - dispatch(save('version', VERSION)); + window.sessionStorage.clear(); + } catch (error) { + // empty } + set('version', VERSION); + } - // load tokens - const tokens = await config.networks.reduce(async (promise: Promise, network: Network): Promise => { - const collection: TokensCollection = await promise; - const json = await httpRequest(network.tokens, 'json'); - collection[network.shortcut] = json; - return collection; - }, Promise.resolve({})); - - const devices: ?string = get('devices'); - if (devices) { - dispatch({ - type: CONNECT.DEVICE_FROM_STORAGE, - payload: JSON.parse(devices), - }); - } + // load tokens + const tokens = await config.networks.reduce(async (promise: Promise, network: Network): Promise => { + const collection: TokensCollection = await promise; + const json = await httpRequest(network.tokens, 'json'); + collection[network.shortcut] = json; + return collection; + }, Promise.resolve({})); - const accounts: ?string = get('accounts'); - if (accounts) { - dispatch({ - type: ACCOUNT.FROM_STORAGE, - payload: JSON.parse(accounts), - }); - } + dispatch({ + type: STORAGE.READY, + config, + tokens, + ERC20Abi, + }); + } catch (error) { + dispatch({ + type: STORAGE.ERROR, + error, + }); + } +}; - const userTokens: ?string = get('tokens'); - if (userTokens) { - dispatch({ - type: TOKEN.FROM_STORAGE, - payload: JSON.parse(userTokens), - }); - } - const pending: ?string = get('pending'); - if (pending) { - dispatch({ - type: PENDING.FROM_STORAGE, - payload: JSON.parse(pending), - }); - } +const loadStorageData = (): ThunkAction => (dispatch: Dispatch): void => { + const devices: ?string = get('devices'); + if (devices) { + dispatch({ + type: CONNECT.DEVICE_FROM_STORAGE, + payload: JSON.parse(devices), + }); + } - const discovery: ?string = get('discovery'); - if (discovery) { - dispatch({ - type: DISCOVERY.FROM_STORAGE, - payload: JSON.parse(discovery), - }); - } + const accounts: ?string = get('accounts'); + if (accounts) { + dispatch({ + type: ACCOUNT.FROM_STORAGE, + payload: JSON.parse(accounts), + }); + } + const userTokens: ?string = get('tokens'); + if (userTokens) { + dispatch({ + type: TOKEN.FROM_STORAGE, + payload: JSON.parse(userTokens), + }); + } + + const pending: ?string = get('pending'); + if (pending) { + dispatch({ + type: PENDING.FROM_STORAGE, + payload: JSON.parse(pending), + }); + } + + const discovery: ?string = get('discovery'); + if (discovery) { + dispatch({ + type: DISCOVERY.FROM_STORAGE, + payload: JSON.parse(discovery), + }); + } + + if (buildUtils.isDev() || buildUtils.isBeta()) { + const betaModal = get('/betaModalPrivacy'); + if (!betaModal) { dispatch({ - type: STORAGE.READY, - config, - tokens, - ERC20Abi, - }); - } catch (error) { - dispatch({ - type: STORAGE.ERROR, - error, + type: WALLET.SHOW_BETA_DISCLAIMER, + show: true, }); } - }; -} - -export const loadData = (): ThunkAction => (dispatch: Dispatch): void => { - // check if local storage is available - // let available: boolean = true; - // if (typeof window.localStorage === 'undefined') { - // available = false; - // } else { - // try { - // window.localStorage.setItem('ethereum_wallet', true); - // } catch (error) { - // available = false; - // } - // } - - dispatch(loadTokensFromJSON()); + } }; -export const save = (key: string, value: string): ThunkAction => (): void => { - if (typeof window.localStorage !== 'undefined') { - try { - window.localStorage.setItem(key, value); - } catch (error) { - // available = false; - console.error(`Local Storage ERROR: ${error}`); - } +export const loadData = (): ThunkAction => (dispatch: Dispatch, getState: GetState): void => { + dispatch(loadStorageData()); + + // stop loading resources and wait for user action + if (!getState().wallet.showBetaDisclaimer) { + dispatch(loadJSON()); } -}; \ No newline at end of file +}; + +export const hideBetaDisclaimer = (): ThunkAction => (dispatch: Dispatch): void => { + set('/betaModalPrivacy', true); + dispatch(loadJSON()); +}; diff --git a/src/actions/ModalActions.js b/src/actions/ModalActions.js index a9def9fe..c0856481 100644 --- a/src/actions/ModalActions.js +++ b/src/actions/ModalActions.js @@ -119,7 +119,6 @@ export const onWalletTypeRequest = (device: TrezorDevice, hidden: boolean, state }; export const gotoExternalWallet = (id: string, url: string): ThunkAction => (dispatch: Dispatch): void => { - console.warn('OPEN', id, url); dispatch({ type: MODAL.OPEN_EXTERNAL_WALLET, id, @@ -127,7 +126,6 @@ export const gotoExternalWallet = (id: string, url: string): ThunkAction => (dis }); }; - export default { onPinSubmit, onPassphraseSubmit, diff --git a/src/actions/RouterActions.js b/src/actions/RouterActions.js index 4e744df7..d4c5842b 100644 --- a/src/actions/RouterActions.js +++ b/src/actions/RouterActions.js @@ -153,7 +153,7 @@ export const getValidUrl = (action: RouterAction): PayloadAction => (dis const shouldBeLandingPage = getState().devices.length < 1 || !getState().wallet.ready || getState().connect.error !== null; const landingPageUrl = dispatch(isLandingPageUrl(requestedUrl)); if (shouldBeLandingPage) { - const landingPageRoute = dispatch(isLandingPageUrl(requestedUrl, true)); + const landingPageRoute = dispatch(isLandingPageUrl(requestedUrl, getState().wallet.ready)); return !landingPageRoute ? '/' : requestedUrl; } diff --git a/src/actions/WalletActions.js b/src/actions/WalletActions.js index 0cd065d3..f0d72a1b 100644 --- a/src/actions/WalletActions.js +++ b/src/actions/WalletActions.js @@ -38,6 +38,8 @@ export type WalletAction = { } | { type: typeof WALLET.CLEAR_UNAVAILABLE_DEVICE_DATA, devices: Array +} | { + type: typeof WALLET.SHOW_BETA_DISCLAIMER | typeof WALLET.HIDE_BETA_DISCLAIMER, } export const init = (): ThunkAction => (dispatch: Dispatch): void => { @@ -51,6 +53,10 @@ export const init = (): ThunkAction => (dispatch: Dispatch): void => { window.addEventListener('offline', updateOnlineStatus); }; +export const hideBetaDisclaimer = (): WalletAction => ({ + type: WALLET.HIDE_BETA_DISCLAIMER, +}); + export const toggleDeviceDropdown = (opened: boolean): WalletAction => ({ type: WALLET.TOGGLE_DEVICE_DROPDOWN, opened, diff --git a/src/actions/constants/wallet.js b/src/actions/constants/wallet.js index 84cb4011..6f449a7a 100644 --- a/src/actions/constants/wallet.js +++ b/src/actions/constants/wallet.js @@ -6,5 +6,7 @@ export const ONLINE_STATUS: 'wallet__online_status' = 'wallet__online_status'; export const SET_SELECTED_DEVICE: 'wallet__set_selected_device' = 'wallet__set_selected_device'; export const UPDATE_SELECTED_DEVICE: 'wallet__update_selected_device' = 'wallet__update_selected_device'; +export const SHOW_BETA_DISCLAIMER: 'wallet__show_beta_disclaimer' = 'wallet__show_beta_disclaimer'; +export const HIDE_BETA_DISCLAIMER: 'wallet__hide_beta_disclaimer' = 'wallet__hide_beta_disclaimer'; export const CLEAR_UNAVAILABLE_DEVICE_DATA: 'wallet__clear_unavailable_device_data' = 'wallet__clear_unavailable_device_data'; \ No newline at end of file diff --git a/src/reducers/WalletReducer.js b/src/reducers/WalletReducer.js index 4e13807f..37fd38fd 100644 --- a/src/reducers/WalletReducer.js +++ b/src/reducers/WalletReducer.js @@ -7,13 +7,13 @@ import * as MODAL from 'actions/constants/modal'; import * as WALLET from 'actions/constants/wallet'; import * as CONNECT from 'actions/constants/TrezorConnect'; - import type { Action, RouterLocationState, TrezorDevice } from 'flowtype'; type State = { ready: boolean; online: boolean; dropdownOpened: boolean; + showBetaDisclaimer: boolean; initialParams: ?RouterLocationState; initialPathname: ?string; disconnectRequest: ?TrezorDevice; @@ -24,6 +24,7 @@ const initialState: State = { ready: false, online: navigator.onLine, dropdownOpened: false, + showBetaDisclaimer: false, initialParams: null, initialPathname: null, disconnectRequest: null, @@ -86,6 +87,17 @@ export default function wallet(state: State = initialState, action: Action): Sta selectedDevice: action.device, }; + case WALLET.SHOW_BETA_DISCLAIMER: + return { + ...state, + showBetaDisclaimer: true, + }; + case WALLET.HIDE_BETA_DISCLAIMER: + return { + ...state, + showBetaDisclaimer: false, + }; + default: return state; } diff --git a/src/services/LocalStorageService.js b/src/services/LocalStorageService.js index b98fbf62..ffd984e0 100644 --- a/src/services/LocalStorageService.js +++ b/src/services/LocalStorageService.js @@ -1,7 +1,6 @@ /* @flow */ import { DEVICE } from 'trezor-connect'; import * as LocalStorageActions from 'actions/LocalStorageActions'; -// import * as WalletActions from 'actions/WalletActions'; import * as CONNECT from 'actions/constants/TrezorConnect'; import * as TOKEN from 'actions/constants/token'; @@ -9,95 +8,45 @@ import * as ACCOUNT from 'actions/constants/account'; import * as DISCOVERY from 'actions/constants/discovery'; import * as SEND from 'actions/constants/send'; import * as PENDING from 'actions/constants/pendingTx'; -import { findAccountTokens } from 'reducers/TokensReducer'; +import * as WALLET from 'actions/constants/wallet'; + import type { Middleware, MiddlewareAPI, MiddlewareDispatch, - Dispatch, Action, - GetState, - TrezorDevice, } from 'flowtype'; -import type { Account } from 'reducers/AccountsReducer'; -import type { Token } from 'reducers/TokensReducer'; -import type { PendingTx } from 'reducers/PendingTxReducer'; -import type { Discovery } from 'reducers/DiscoveryReducer'; - - -// https://github.com/STRML/react-localstorage/blob/master/react-localstorage.js -// or -// https://www.npmjs.com/package/redux-react-session - -const findAccounts = (devices: Array, accounts: Array): Array => devices.reduce((arr, dev) => arr.concat(accounts.filter(a => a.deviceState === dev.state)), []); - -const findTokens = (accounts: Array, tokens: Array): Array => accounts.reduce((arr, account) => arr.concat(findAccountTokens(tokens, account)), []); - -const findDiscovery = (devices: Array, discovery: Array): Array => devices.reduce((arr, dev) => arr.concat(discovery.filter(a => a.deviceState === dev.state && a.publicKey.length > 0)), []); - -const findPendingTxs = (accounts: Array, pending: Array): Array => accounts.reduce((result, account) => result.concat(pending.filter(p => p.address === account.address && p.network === account.network)), []); - -const save = (dispatch: Dispatch, getState: GetState): void => { - const devices: Array = getState().devices.filter(d => d.features && d.remember === true); - const accounts: Array = findAccounts(devices, getState().accounts); - const tokens: Array = findTokens(accounts, getState().tokens); - const pending: Array = findPendingTxs(accounts, getState().pending); - const discovery: Array = findDiscovery(devices, getState().discovery); - - // save devices - dispatch(LocalStorageActions.save('devices', JSON.stringify(devices))); - - // save already preloaded accounts - dispatch(LocalStorageActions.save('accounts', JSON.stringify(accounts))); - - // save discovery state - dispatch(LocalStorageActions.save('discovery', JSON.stringify(discovery))); - - // tokens - dispatch(LocalStorageActions.save('tokens', JSON.stringify(tokens))); - - // pending transactions - dispatch(LocalStorageActions.save('pending', JSON.stringify(pending))); -}; - - const LocalStorageService: Middleware = (api: MiddlewareAPI) => (next: MiddlewareDispatch) => (action: Action): Action => { - // Application live cycle starts here - // if (action.type === LOCATION_CHANGE) { - // const { location } = api.getState().router; - // if (!location) { - // api.dispatch( WalletActions.init() ); - // // load data from config.json and local storage - // api.dispatch( LocalStorageActions.loadData() ); - // } - // } - + // pass action next(action); switch (action.type) { + case WALLET.HIDE_BETA_DISCLAIMER: + api.dispatch(LocalStorageActions.hideBetaDisclaimer()); + break; // first time saving case CONNECT.REMEMBER: - save(api.dispatch, api.getState); + api.dispatch(LocalStorageActions.save()); break; case TOKEN.ADD: case TOKEN.REMOVE: case TOKEN.SET_BALANCE: - save(api.dispatch, api.getState); + api.dispatch(LocalStorageActions.save()); break; case ACCOUNT.CREATE: case ACCOUNT.SET_BALANCE: case ACCOUNT.SET_NONCE: - save(api.dispatch, api.getState); + api.dispatch(LocalStorageActions.save()); break; case DISCOVERY.START: case DISCOVERY.STOP: case DISCOVERY.COMPLETE: - save(api.dispatch, api.getState); + api.dispatch(LocalStorageActions.save()); break; case CONNECT.FORGET: @@ -107,13 +56,13 @@ const LocalStorageService: Middleware = (api: MiddlewareAPI) => (next: Middlewar case DEVICE.CHANGED: case DEVICE.DISCONNECT: case CONNECT.AUTH_DEVICE: - save(api.dispatch, api.getState); + api.dispatch(LocalStorageActions.save()); break; case SEND.TX_COMPLETE: case PENDING.TX_RESOLVED: case PENDING.TX_REJECTED: - save(api.dispatch, api.getState); + api.dispatch(LocalStorageActions.save()); break; default: diff --git a/src/views/Landing/components/BetaDisclaimer/index.js b/src/views/Landing/components/BetaDisclaimer/index.js new file mode 100644 index 00000000..64177997 --- /dev/null +++ b/src/views/Landing/components/BetaDisclaimer/index.js @@ -0,0 +1,80 @@ +/* @flow */ + +import React from 'react'; +import styled from 'styled-components'; +import { connect } from 'react-redux'; +import { bindActionCreators } from 'redux'; + +import colors from 'config/colors'; +import icons from 'config/icons'; + +import Icon from 'components/Icon'; +import Button from 'components/Button'; +import P from 'components/Paragraph'; +import { H2 } from 'components/Heading'; +import * as WalletActions from 'actions/WalletActions'; + +const Wrapper = styled.div` + width: 100%; + height: 100%; + top: 0px; + left: 0px; + background: rgba(0, 0, 0, 0.35); + display: flex; + flex-direction: column; + align-items: center; + overflow: auto; + padding: 20px; +`; + +const ModalWindow = styled.div` + margin: auto; + position: relative; + border-radius: 4px; + background-color: ${colors.WHITE}; + text-align: center; + width: 100%; + max-width: 620px; + padding: 24px 48px; +`; + +const StyledP = styled(P)` + padding: 10px 0px; + font-size: 14px; +`; + +const StyledButton = styled(Button)` + margin: 10px 0px; + width: 100%; +`; + +const StyledIcon = styled(Icon)` + position: relative; + top: -1px; +`; + +const BetaDisclaimer = (props: { close: () => void }) => ( + + +

You are opening Trezor Beta Wallet

+ Trezor Beta Wallet is a public feature-testing version of the Trezor Wallet, offering the newest features before they are available to the general public. + In contrast, Trezor Wallet is feature-conservative, making sure that its functionality is maximally reliable and dependable for the general public. + + + Please note that the Trezor Beta Wallet might be collecting anonymized usage data, especially error logs, for development purposes. The Trezor Wallet does not log any data. + + OK, I understand +
+
+); + +export default connect( + null, + (dispatch: Dispatch) => ({ + close: bindActionCreators(WalletActions.hideBetaDisclaimer, dispatch), + }), +)(BetaDisclaimer); \ No newline at end of file diff --git a/src/views/Landing/views/Root/index.js b/src/views/Landing/views/Root/index.js index f6c70272..bb55d146 100644 --- a/src/views/Landing/views/Root/index.js +++ b/src/views/Landing/views/Root/index.js @@ -4,6 +4,7 @@ import React from 'react'; import { isWebUSB } from 'utils/device'; import LandingWrapper from 'views/Landing/components/LandingWrapper'; +import BetaDisclaimer from 'views/Landing/components/BetaDisclaimer'; import BrowserNotSupported from 'views/Landing/components/BrowserNotSupported'; import ConnectDevice from 'views/Landing/components/ConnectDevice'; import InstallBridge from 'views/Landing/views/InstallBridge/Container'; @@ -16,6 +17,8 @@ const Root = (props: Props) => { const localStorageError = props.localStorage.error; const connectError = props.connect.error; + if (props.wallet.showBetaDisclaimer) return ; + const error = !initialized ? (localStorageError || connectError) : null; const shouldShowUnsupportedBrowser = browserState.supported === false; const shouldShowInstallBridge = initialized && connectError; From 2fd2ef7735467a8b730fdfc1c3c739246f9f95ca Mon Sep 17 00:00:00 2001 From: Vladimir Volek Date: Mon, 15 Oct 2018 17:56:46 +0200 Subject: [PATCH 07/12] Added test for notificstions --- .../__snapshots__/notification.test.js.snap | 41 +++++++++++++++++++ src/utils/__tests__/notification.test.js | 32 +++++++++++++++ 2 files changed, 73 insertions(+) create mode 100644 src/utils/__tests__/__snapshots__/notification.test.js.snap create mode 100644 src/utils/__tests__/notification.test.js diff --git a/src/utils/__tests__/__snapshots__/notification.test.js.snap b/src/utils/__tests__/__snapshots__/notification.test.js.snap new file mode 100644 index 00000000..35cabc6c --- /dev/null +++ b/src/utils/__tests__/__snapshots__/notification.test.js.snap @@ -0,0 +1,41 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`device utils get icon 1`] = ` +Array [ + "M693.024 330.944c-99.968-99.936-262.080-99.936-362.048 0s-99.968 262.112 0 362.080c99.968 100 262.144 99.936 362.048 0 99.968-99.904 99.968-262.176 0-362.080zM507.904 300.192c27.008 0 48.992 21.984 48.992 49.088 0 27.296-21.984 49.472-48.992 49.472-27.264 0-49.536-22.176-49.536-49.472 0-27.552 21.728-49.088 49.536-49.088zM586.656 660.8c0 10.304-4.96 15.328-15.264 15.328h-126.464c-10.304 0-15.328-5.024-15.328-15.328v-32.256c0-10.304 5.024-15.264 15.328-15.264h23.36v-136.064h-23.872c-10.304 0-15.264-5.024-15.264-15.328v-32.224c0-10.304 4.96-15.264 15.264-15.264h88.288c10.304 0 15.264 4.96 15.264 15.264v183.648h23.424c10.304 0 15.264 4.96 15.264 15.264v32.224z", +] +`; + +exports[`device utils get icon 2`] = ` +Array [ + "M693.12 330.88c-46.317-46.267-110.276-74.88-180.919-74.88-141.385 0-256 114.615-256 256s114.615 256 256 256c70.642 0 134.602-28.613 180.921-74.882l-0.002 0.002c46.387-46.337 75.081-110.377 75.081-181.12s-28.694-134.783-75.079-181.118l-0.002-0.002zM494.080 344.32h53.12c16 0 18.24 9.28 18.24 14.72v10.24l-10.88 194.56c0 14.4-8 17.28-18.88 17.28h-28.16c-10.56 0-17.28-2.88-18.88-17.92l-10.88-193.92v-10.56c-1.28-4.8 2.24-14.080 16.32-14.080zM521.28 717.76c-0.095 0.001-0.207 0.001-0.319 0.001-27.747 0-50.24-22.493-50.24-50.24s22.493-50.24 50.24-50.24c27.747 0 50.24 22.493 50.24 50.24 0 0.112 0 0.224-0.001 0.336v-0.017c0 0 0 0.001 0 0.001 0 27.634-22.311 50.057-49.903 50.239h-0.017z", +] +`; + +exports[`device utils get icon 3`] = ` +Array [ + "M795.616 735.008l-264.896-465.44c-10.272-18.080-27.168-18.080-37.504 0l-264.864 465.44c-10.272 18.176-1.696 32.992 19.040 32.992h529.184c20.8 0 29.376-14.816 19.040-32.992zM549.76 673.12c0 10.464-8.48 18.976-18.912 18.976h-37.792c-10.336 0-18.912-8.512-18.912-18.976v-37.952c0-10.464 8.576-18.976 18.912-18.976h37.792c10.4 0 18.912 8.544 18.912 18.976v37.952zM549.76 559.264c0 10.464-8.48 18.976-18.912 18.976h-37.792c-10.336 0-18.912-8.512-18.912-18.976v-113.856c0-10.464 8.576-18.976 18.912-18.976h37.792c10.4 0 18.912 8.544 18.912 18.976v113.856z", +] +`; + +exports[`device utils get icon 4`] = ` +Array [ + "M692.8 313.92l-1.92-1.92c-6.246-7.057-15.326-11.484-25.44-11.484s-19.194 4.427-25.409 11.448l-0.031 0.036-196.48 224-3.84 1.6-3.84-1.92-48.64-57.28c-7.010-7.905-17.193-12.862-28.533-12.862-21.031 0-38.080 17.049-38.080 38.080 0 7.495 2.165 14.485 5.905 20.377l-0.092-0.155 100.8 148.16c5.391 8.036 14.386 13.292 24.618 13.44h8.662c17.251-0.146 32.385-9.075 41.163-22.529l0.117-0.191 195.2-296.32c4.473-6.632 7.141-14.803 7.141-23.597 0-11.162-4.297-21.32-11.326-28.911l0.025 0.028z", +] +`; + +exports[`device utils get icon 5`] = `undefined`; + +exports[`device utils get icon 6`] = `undefined`; + +exports[`device utils get status 1`] = `"#1E7FF0"`; + +exports[`device utils get status 2`] = `"#ED1212"`; + +exports[`device utils get status 3`] = `"#EB8A00"`; + +exports[`device utils get status 4`] = `"#01B757"`; + +exports[`device utils get status 5`] = `null`; + +exports[`device utils get status 6`] = `null`; diff --git a/src/utils/__tests__/notification.test.js b/src/utils/__tests__/notification.test.js new file mode 100644 index 00000000..ca4eb5f1 --- /dev/null +++ b/src/utils/__tests__/notification.test.js @@ -0,0 +1,32 @@ +import * as nUtils from 'utils/notification'; + +describe('device utils', () => { + it('get status', () => { + const types = [ + 'info', + 'error', + 'warning', + 'success', + 'kdsjflds', + '', + ]; + + types.forEach((type) => { + expect(nUtils.getColor(type)).toMatchSnapshot(); + }); + }); + it('get icon', () => { + const types = [ + 'info', + 'error', + 'warning', + 'success', + 'kdsjflds', + '', + ]; + + types.forEach((type) => { + expect(nUtils.getIcon(type)).toMatchSnapshot(); + }); + }); +}); From a9883727f360760bb1f502aa7d2bb22a81008c8f Mon Sep 17 00:00:00 2001 From: Szymon Lesisz Date: Thu, 18 Oct 2018 13:28:35 +0200 Subject: [PATCH 08/12] quickfix: SendForm currency select value --- src/views/Wallet/views/Account/Send/index.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/views/Wallet/views/Account/Send/index.js b/src/views/Wallet/views/Account/Send/index.js index 0f1a726b..80e01ed5 100644 --- a/src/views/Wallet/views/Account/Send/index.js +++ b/src/views/Wallet/views/Account/Send/index.js @@ -243,6 +243,7 @@ const AccountSend = (props: Props) => { } const tokensSelectData = getTokensSelectData(tokens, network); + const tokensSelectValue = tokensSelectData.find(t => t.value === currency) const isAdvancedSettingsHidden = !advanced; return ( @@ -310,7 +311,7 @@ const AccountSend = (props: Props) => { key="currency" isSearchable={false} isClearable={false} - defaultValue={tokensSelectData[0]} + value={tokensSelectValue} isDisabled={tokensSelectData.length < 2} onChange={onCurrencyChange} options={tokensSelectData} From 835d1724838de0e39c860ec57275fde4bf7b1a7c Mon Sep 17 00:00:00 2001 From: Szymon Lesisz Date: Thu, 18 Oct 2018 14:17:52 +0200 Subject: [PATCH 09/12] quickfix: update token balance on token added --- src/actions/TokenActions.js | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/src/actions/TokenActions.js b/src/actions/TokenActions.js index eea041e8..d0528ca1 100644 --- a/src/actions/TokenActions.js +++ b/src/actions/TokenActions.js @@ -56,14 +56,16 @@ export const setBalance = (tokenAddress: string, ethAddress: string, balance: st const newState: Array = [...getState().tokens]; const token: ?Token = newState.find(t => t.address === tokenAddress && t.ethAddress === ethAddress); if (token) { - token.loaded = true; - token.balance = balance; + const others = newState.filter(t => t !== token); + dispatch({ + type: TOKEN.SET_BALANCE, + payload: others.concat([{ + ...token, + loaded: true, + balance, + }]), + }); } - - dispatch({ - type: TOKEN.SET_BALANCE, - payload: newState, - }); }; export const add = (token: NetworkToken, account: Account): AsyncAction => async (dispatch: Dispatch): Promise => { From 6ad65dd6f1652a67b25e500bd8fd90a4d06013ee Mon Sep 17 00:00:00 2001 From: Szymon Lesisz Date: Thu, 18 Oct 2018 14:18:10 +0200 Subject: [PATCH 10/12] SendForm eslint fix --- src/views/Wallet/views/Account/Send/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/views/Wallet/views/Account/Send/index.js b/src/views/Wallet/views/Account/Send/index.js index 80e01ed5..f57bab8c 100644 --- a/src/views/Wallet/views/Account/Send/index.js +++ b/src/views/Wallet/views/Account/Send/index.js @@ -243,7 +243,7 @@ const AccountSend = (props: Props) => { } const tokensSelectData = getTokensSelectData(tokens, network); - const tokensSelectValue = tokensSelectData.find(t => t.value === currency) + const tokensSelectValue = tokensSelectData.find(t => t.value === currency); const isAdvancedSettingsHidden = !advanced; return ( From 22708cc088fee91b3e5870910b4fddc5fba27a07 Mon Sep 17 00:00:00 2001 From: Szymon Lesisz Date: Thu, 18 Oct 2018 14:18:39 +0200 Subject: [PATCH 11/12] changed old-wallet links to relative levelup --- src/constants/coins.js | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/constants/coins.js b/src/constants/coins.js index 0e065b3f..ac70469c 100644 --- a/src/constants/coins.js +++ b/src/constants/coins.js @@ -2,47 +2,47 @@ export default [ { id: 'btc', coinName: 'Bitcoin', - url: 'https://wallet.trezor.io/#/?coin=btc', + url: '../#/?coin=btc', }, { id: 'bch', coinName: 'Bitcoin Cash', - url: 'https://wallet.trezor.io/#/?coin=bch', + url: '../#/?coin=bch', }, { id: 'btg', coinName: 'Bitcoin Gold', - url: 'https://wallet.trezor.io/#/?coin=btg', + url: '../#/?coin=btg', }, { id: 'dash', coinName: 'Dash', - url: 'https://wallet.trezor.io/#/?coin=dash', + url: '../#/?coin=dash', }, { id: 'doge', coinName: 'Dogecoin', - url: 'https://wallet.trezor.io/#/?coin=doge', + url: '../#/?coin=doge', }, { id: 'ltc', coinName: 'Litecoin', - url: 'https://wallet.trezor.io/#/?coin=ltc', + url: '../#/?coin=ltc', }, { id: 'nmc', coinName: 'Namecoin', - url: 'https://wallet.trezor.io/#/?coin=nmc', + url: '../#/?coin=nmc', }, { id: 'vtc', coinName: 'Vertcoin', - url: 'https://wallet.trezor.io/#/?coin=vtc', + url: '../#/?coin=vtc', }, { id: 'zec', coinName: 'Zcash', - url: 'https://wallet.trezor.io/#/?coin=zec', + url: '../#/?coin=zec', }, { id: 'xem', From d8a4e9fed9ec220725c51591554b208b3bffdbf6 Mon Sep 17 00:00:00 2001 From: Pavol Rusnak Date: Thu, 18 Oct 2018 17:41:22 +0200 Subject: [PATCH 12/12] fix license in package.json --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index b22a1998..9db39d70 100644 --- a/package.json +++ b/package.json @@ -6,7 +6,7 @@ "bin": { "flow": "./node_modules/flow-bin" }, - "license": "LGPL-3.0+", + "license": "T-RSL", "scripts": { "dev": "npx webpack-dev-server --config webpack/dev.babel.js", "dev:local": "npx webpack-dev-server --config webpack/local.babel.js",