Skip to content

Commit

Permalink
Feature: address book + new send flow (#1239)
Browse files Browse the repository at this point in the history
* basic components

* basic components

* updates

* wip

* between my accounts

* basic add contact

* render list

* inputs func components

* handle from selection

* from identicon

* onchangetoaddress

* add to address book modal

* add from modal and parse asdress book

* scan qr

* select own accounts

* reverse ens and better state

* handle parse

* clear to

* handle account label

* next and redux

* handle to ens

* parse address book

* handle send flow navigation

* amount view

* render only tokens

* pick selected asset

* redux set selected address

* use max

* switch currency

* confirm

* clean

* init confirm

* confirm view

* render fiat in confirm

* handle eth txs

* handle erc20 txs

* parseTransactionData

* wait for gas estimation

* custom gas modal

* handle gas selection

* handle advanced tx fee

* custom gas improvs

* handle gas selected

* handle current selected when cancel

* use time estimates

* handle amount errors

* address search

* typo

* recents

* parsedRecents

* cleaner code

* handle address errors

* handle more error cases

* fix usemax

* handle global primary currency

* handle use max with fiat as prim currency

* switch currency working

* set asset before and fix switched symbol

* render gas wait time

* improve gas selectors

* add weeks and days

* better parsewaittime

* fix selected asset change

* improve conversion

* parseTransactionData
"

* validate gas on confirm

* handle use max with gas for eth

* add gas estimation in amount

* estimatedTotalGas once on mount

* send tx

* gas bug on amount

* render collectibles in list

* handle collectibles list and data

* handle collectible on confirm

* ignore No stops in gradient

* handle focus

* handle tradable collectibles and sort them

* handle tokens without exchange rate

* check collectible removal

* start tx from asset

* go to new send flow from everywhere

* hex data modal

* reset tx on unmount

* delete unused files

* reset tx

* start tx with asset

* redux update

* clean state

* isETH

* highlight address to

* use currency symbols and texttransfor uppercase

* handle currency code in amount input

* send to up to date design

* amount up to date design

* confirm up to date design

* send to up to date design android

* next buttons margin bottom

* input amount font

* fix texts color

* fix androi dpaste

* alignments

* handle mmm txs

* handle ens name when resolved

* formatting and locales

* add contacts from settings

* no need for edit component

* handle add validation

* locales

* rename route

* delete contact

* spanish

* handle scan and android'

* more locales

* address ready when edit

* snappppppsSs

* others

* fix reverse ens

* disable add address without an alias

* fixes

* address elemenr

* snaps

* custom gas validation

* locale missing

* check decimal

* comments

* snaps

* fix key

* fix assets

* fix use mac

* renderFiatAddition

* fix empty data

* snaps

* fix gas calculation for erc721

* rm logs

* validation

* handle change from without asset

* use flat list

* rm unused code

* rename

* fix delete

* fix empty bug

* fix margin issue 10

* issue 11

* 12

* send qr to old sendflow 13

* snaps

* fix others contacts

* fix edit

* use mac

* lte

* bn(0)

* fix 13

* handle space and emojis

* fix validation

* contact form with refs

* snapS
  • Loading branch information
estebanmino authored Jan 22, 2020
1 parent 52fea8c commit e0c0b07
Show file tree
Hide file tree
Showing 73 changed files with 6,249 additions and 178 deletions.
72 changes: 72 additions & 0 deletions app/actions/newTransaction/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
import TransactionTypes from '../../core/TransactionTypes';

const {
ASSET: { ETH, ERC20, ERC721 }
} = TransactionTypes;

/**
* Clears transaction object completely
*/
export function resetTransaction() {
return {
type: 'RESET_TRANSACTION'
};
}

/**
* Starts a new transaction state with an asset
*
* @param {object} selectedAsset - Asset to start the transaction with
*/
export function newAssetTransaction(selectedAsset) {
return {
type: 'NEW_ASSET_TRANSACTION',
selectedAsset,
assetType: selectedAsset.isETH ? ETH : selectedAsset.tokenId ? ERC721 : ERC20
};
}

/**
* Sets transaction to address and ensRecipient in case is available
*
* @param {string} from - Address to send the transaction from
* @param {string} to - Address to send the transaction to
* @param {string} ensRecipient - Resolved ens name to send the transaction to
* @param {string} transactionToName - Resolved address book name for to address
* @param {string} transactionFromName - Resolved address book name for from address
*/
export function setRecipient(from, to, ensRecipient, transactionToName, transactionFromName) {
return {
type: 'SET_RECIPIENT',
from,
to,
ensRecipient,
transactionToName,
transactionFromName
};
}

/**
* Sets asset as selectedAsset
*
* @param {object} selectedAsset - Asset to start the transaction with
*/
export function setSelectedAsset(selectedAsset) {
return {
type: 'SET_SELECTED_ASSET',
selectedAsset,
assetType: selectedAsset.isETH ? ETH : selectedAsset.tokenId ? ERC721 : ERC20
};
}

/**
* Sets transaction object to be sent
*
* @param {object} transaction - Transaction object with from, to, data, gas, gasPrice, value
*/
export function prepareTransaction(transaction) {
return {
type: 'PREPARE_TRANSACTION',
transaction
};
}
32 changes: 32 additions & 0 deletions app/components/Nav/App/__snapshots__/index.test.js.snap
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,20 @@ exports[`App should render correctly 1`] = `
"getStateForAction": [Function],
},
"QRScanner": null,
"SendFlowView": Object {
"childRouters": Object {
"Amount": null,
"Confirm": null,
"SendTo": null,
},
"getActionCreators": [Function],
"getActionForPathAndParams": [Function],
"getComponentForRouteName": [Function],
"getComponentForState": [Function],
"getPathAndParamsForState": [Function],
"getScreenOptions": [Function],
"getStateForAction": [Function],
},
"SendView": Object {
"childRouters": Object {
"Send": null,
Expand Down Expand Up @@ -191,6 +205,8 @@ exports[`App should render correctly 1`] = `
"AdvancedSettings": null,
"ChoosePasswordSimple": null,
"CompanySettings": null,
"ContactForm": null,
"ContactsSettings": null,
"EnterPasswordSimple": null,
"ExperimentalSettings": null,
"GeneralSettings": null,
Expand Down Expand Up @@ -581,6 +597,20 @@ exports[`App should render correctly 1`] = `
"getStateForAction": [Function],
},
"QRScanner": null,
"SendFlowView": Object {
"childRouters": Object {
"Amount": null,
"Confirm": null,
"SendTo": null,
},
"getActionCreators": [Function],
"getActionForPathAndParams": [Function],
"getComponentForRouteName": [Function],
"getComponentForState": [Function],
"getPathAndParamsForState": [Function],
"getScreenOptions": [Function],
"getStateForAction": [Function],
},
"SendView": Object {
"childRouters": Object {
"Send": null,
Expand Down Expand Up @@ -617,6 +647,8 @@ exports[`App should render correctly 1`] = `
"AdvancedSettings": null,
"ChoosePasswordSimple": null,
"CompanySettings": null,
"ContactForm": null,
"ContactsSettings": null,
"EnterPasswordSimple": null,
"ExperimentalSettings": null,
"GeneralSettings": null,
Expand Down
32 changes: 32 additions & 0 deletions app/components/Nav/Main/__snapshots__/index.test.js.snap
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,20 @@ exports[`Main should render correctly 1`] = `
"getStateForAction": [Function],
},
"QRScanner": null,
"SendFlowView": Object {
"childRouters": Object {
"Amount": null,
"Confirm": null,
"SendTo": null,
},
"getActionCreators": [Function],
"getActionForPathAndParams": [Function],
"getComponentForRouteName": [Function],
"getComponentForState": [Function],
"getPathAndParamsForState": [Function],
"getScreenOptions": [Function],
"getStateForAction": [Function],
},
"SendView": Object {
"childRouters": Object {
"Send": null,
Expand Down Expand Up @@ -199,6 +213,8 @@ exports[`Main should render correctly 1`] = `
"AdvancedSettings": null,
"ChoosePasswordSimple": null,
"CompanySettings": null,
"ContactForm": null,
"ContactsSettings": null,
"EnterPasswordSimple": null,
"ExperimentalSettings": null,
"GeneralSettings": null,
Expand Down Expand Up @@ -469,6 +485,20 @@ exports[`Main should render correctly 1`] = `
"getStateForAction": [Function],
},
"QRScanner": null,
"SendFlowView": Object {
"childRouters": Object {
"Amount": null,
"Confirm": null,
"SendTo": null,
},
"getActionCreators": [Function],
"getActionForPathAndParams": [Function],
"getComponentForRouteName": [Function],
"getComponentForState": [Function],
"getPathAndParamsForState": [Function],
"getScreenOptions": [Function],
"getStateForAction": [Function],
},
"SendView": Object {
"childRouters": Object {
"Send": null,
Expand Down Expand Up @@ -505,6 +535,8 @@ exports[`Main should render correctly 1`] = `
"AdvancedSettings": null,
"ChoosePasswordSimple": null,
"CompanySettings": null,
"ContactForm": null,
"ContactsSettings": null,
"EnterPasswordSimple": null,
"ExperimentalSettings": null,
"GeneralSettings": null,
Expand Down
35 changes: 33 additions & 2 deletions app/components/Nav/Main/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import ExperimentalSettings from '../../Views/Settings/ExperimentalSettings';
import NetworksSettings from '../../Views/Settings/NetworksSettings';
import NetworkSettings from '../../Views/Settings/NetworksSettings/NetworkSettings';
import AppInformation from '../../Views/Settings/AppInformation';
import Contacts from '../../Views/Settings/Contacts';
import Wallet from '../../Views/Wallet';
import TransactionsView from '../../Views/TransactionsView';
import SyncWithExtension from '../../Views/SyncWithExtension';
Expand All @@ -38,6 +39,7 @@ import AddAsset from '../../Views/AddAsset';
import Collectible from '../../Views/Collectible';
import CollectibleView from '../../Views/CollectibleView';
import Send from '../../Views/Send';
import SendTo from '../../Views/SendFlow/SendTo';
import RevealPrivateCredential from '../../Views/RevealPrivateCredential';
import WalletConnectSessions from '../../Views/WalletConnectSessions';
import OfflineMode from '../../Views/OfflineMode';
Expand Down Expand Up @@ -87,6 +89,10 @@ import contractMap from 'eth-contract-metadata';
import MessageSign from '../../UI/MessageSign';
import WalletConnectReturnToBrowserModal from '../../UI/WalletConnectReturnToBrowserModal';
import AsyncStorage from '@react-native-community/async-storage';
import Amount from '../../Views/SendFlow/Amount';
import Confirm from '../../Views/SendFlow/Confirm';
import ContactForm from '../../Views/Settings/Contacts/ContactForm';
import TransactionTypes from '../../../core/TransactionTypes';

const styles = StyleSheet.create({
flex: {
Expand Down Expand Up @@ -203,6 +209,12 @@ const MainNavigator = createStackNavigator(
CompanySettings: {
screen: AppInformation
},
ContactsSettings: {
screen: Contacts
},
ContactForm: {
screen: ContactForm
},
SyncWithExtensionView: {
screen: SyncWithExtension
},
Expand Down Expand Up @@ -242,6 +254,19 @@ const MainNavigator = createStackNavigator(
}
})
},
SendFlowView: {
screen: createStackNavigator({
SendTo: {
screen: SendTo
},
Amount: {
screen: Amount
},
Confirm: {
screen: Confirm
}
})
},
ApprovalView: {
screen: createStackNavigator({
Approval: {
Expand Down Expand Up @@ -728,13 +753,19 @@ class Main extends PureComponent {
await TransactionController.updateTransaction(updatedTx);
await TransactionController.approveTransaction(transactionMeta.id);
} catch (error) {
Alert.alert(strings('transactions.transaction_error'), error && error.message, [{ text: 'OK' }]);
Alert.alert(strings('transactions.transaction_error'), error && error.message, [
{ text: strings('navigation.ok') }
]);
this.setState({ transactionHandled: false });
}
};

onUnapprovedTransaction = async transactionMeta => {
if (this.props.transaction.value || this.props.transaction.to) {
if (
this.props.transaction.value ||
this.props.transaction.to ||
transactionMeta.origin === TransactionTypes.MMM
) {
return;
}
// Check if it's a payment channel deposit transaction to sign
Expand Down
60 changes: 38 additions & 22 deletions app/components/UI/AccountList/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,11 @@ class AccountList extends PureComponent {
/**
* Current provider ticker
*/
ticker: PropTypes.string
ticker: PropTypes.string,
/**
* Whether it will show options to create or import accounts
*/
enableAccountsAddition: PropTypes.bool
};

state = {
Expand Down Expand Up @@ -150,6 +154,7 @@ class AccountList extends PureComponent {
const previousIndex = this.state.selectedAccountIndex;
const { PreferencesController } = Engine.context;
const { keyrings } = this.props;

requestAnimationFrame(async () => {
try {
this.mounted && this.setState({ selectedAccountIndex: newIndex });
Expand All @@ -158,6 +163,14 @@ class AccountList extends PureComponent {
keyrings && keyrings.length ? keyrings : Engine.context.KeyringController.state.keyrings;
const accountsOrdered = allKeyrings.reduce((list, keyring) => list.concat(keyring.accounts), []);

// If not enabled is used from address book so we don't change accounts
if (!this.props.enableAccountsAddition) {
this.props.onAccountChange(accountsOrdered[newIndex]);
const orderedAccounts = this.getAccounts();
this.mounted && this.setState({ orderedAccounts });
return;
}

PreferencesController.setSelectedAddress(accountsOrdered[newIndex]);

this.props.onAccountChange();
Expand Down Expand Up @@ -281,6 +294,7 @@ class AccountList extends PureComponent {

render() {
const { orderedAccounts } = this.state;
const { enableAccountsAddition } = this.props;
return (
<SafeAreaView style={styles.wrapper} testID={'account-list'}>
<View style={styles.titleWrapper}>
Expand All @@ -293,28 +307,30 @@ class AccountList extends PureComponent {
ref={this.flatList}
style={styles.accountsWrapper}
testID={'account-number-button'}
getItemLayout={(data, index) => ({ length: 80, offset: 80 * index, index })} // eslint-disable-line
getItemLayout={(_, index) => ({ length: 80, offset: 80 * index, index })} // eslint-disable-line
/>
<View style={styles.footer}>
<TouchableOpacity
style={styles.footerButton}
testID={'create-account-button'}
onPress={this.addAccount}
>
{this.state.loading ? (
<ActivityIndicator size="small" color={colors.blue} />
) : (
<Text style={styles.btnText}>{strings('accounts.create_new_account')}</Text>
)}
</TouchableOpacity>
<TouchableOpacity
onPress={this.importAccount}
style={styles.footerButton}
testID={'import-account-button'}
>
<Text style={styles.btnText}>{strings('accounts.import_account')}</Text>
</TouchableOpacity>
</View>
{enableAccountsAddition && (
<View style={styles.footer}>
<TouchableOpacity
style={styles.footerButton}
testID={'create-account-button'}
onPress={this.addAccount}
>
{this.state.loading ? (
<ActivityIndicator size="small" color={colors.blue} />
) : (
<Text style={styles.btnText}>{strings('accounts.create_new_account')}</Text>
)}
</TouchableOpacity>
<TouchableOpacity
onPress={this.importAccount}
style={styles.footerButton}
testID={'import-account-button'}
>
<Text style={styles.btnText}>{strings('accounts.import_account')}</Text>
</TouchableOpacity>
</View>
)}
</SafeAreaView>
);
}
Expand Down
8 changes: 4 additions & 4 deletions app/components/UI/AccountSelect/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -176,11 +176,11 @@ class AccountSelect extends PureComponent {
const state = PaymentChannelsClient.getState();
mainBalance = `${state.balance} ${strings('unit.sai')}`;
} else if (primaryCurrency === 'ETH') {
mainBalance = renderFromWei(balance) + ' ' + getTicker(ticker);
secondaryBalance = weiToFiat(balance, conversionRate, currentCurrency.toUpperCase());
mainBalance = `${renderFromWei(balance)} ${getTicker(ticker)}`;
secondaryBalance = weiToFiat(balance, conversionRate, currentCurrency);
} else {
mainBalance = weiToFiat(balance, conversionRate, currentCurrency.toUpperCase());
secondaryBalance = renderFromWei(balance) + ' ' + getTicker(ticker);
mainBalance = weiToFiat(balance, conversionRate, currentCurrency);
secondaryBalance = `${renderFromWei(balance)} ${getTicker(ticker)}`;
}

return (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,6 @@ exports[`ActionModal should render correctly 1`] = `
Object {
"borderTopColor": "#bbc0c5",
"borderTopWidth": 1,
"flex": 0,
"flexDirection": "row",
"padding": 16,
}
Expand Down
Loading

0 comments on commit e0c0b07

Please sign in to comment.