diff --git a/analytics.js b/analytics.js index 4d6a0a14..84d65cc9 100644 --- a/analytics.js +++ b/analytics.js @@ -24,6 +24,7 @@ A.ENUM = { CREATED_WALLET: 'CREATED_WALLET', CREATED_LIGHTNING_WALLET: 'CREATED_LIGHTNING_WALLET', APP_UNSUSPENDED: 'APP_UNSUSPENDED', + NAVIGATED_TO_WALLETS_HODLHODL: 'NAVIGATED_TO_WALLETS_HODLHODL', }; module.exports = A; diff --git a/class/hd-segwit-p2sh-wallet.js b/class/hd-segwit-p2sh-wallet.js index 32f8e3b6..32b32e8e 100644 --- a/class/hd-segwit-p2sh-wallet.js +++ b/class/hd-segwit-p2sh-wallet.js @@ -154,4 +154,8 @@ export class HDSegwitP2SHWallet extends AbstractHDElectrumWallet { }); return address; } + + allowHodlHodlTrading() { + return true; + } } diff --git a/package.json b/package.json index 6f54dcb1..833c5ae6 100644 --- a/package.json +++ b/package.json @@ -39,7 +39,7 @@ "postinstall": "./node_modules/.bin/rn-nodeify --install buffer,events,process,stream,util,inherits,fs,path --hack; npm run releasenotes2json; npm run podinstall; npx jetify", "test": "npm run unit && npm run jest && npm run lint", "jest": "node node_modules/jest/bin/jest.js tests/integration/*", - "e2e:release": "detox build -c android.emu.release; detox test -c android.emu.release --record-videos all --take-screenshots all --headless --cleanup", + "e2e:release": "detox build -c android.emu.release; detox test -c android.emu.release --record-videos all --take-screenshots all --headless", "e2e:debug": "test -f android/app/build/outputs/apk/debug/app-debug.apk || detox build -c android.emu.debug; detox test -c android.emu.debug --cleanup", "lint": "./node_modules/.bin/eslint *.js screen/**/*.js screen/ class/ models/ loc/ tests/integration/ tests/e2e/ tests/unit/", "lint:fix": "./node_modules/.bin/eslint *.js screen/**/*.js screen/ class/ models/ loc/ tests/integration/ tests/e2e/ tests/unit/ --fix", diff --git a/screen/wallets/export.js b/screen/wallets/export.js index f5e9ddef..ebf49881 100644 --- a/screen/wallets/export.js +++ b/screen/wallets/export.js @@ -68,14 +68,10 @@ export default class WalletExport extends Component { } return ( - - + + - {this.state.wallet.typeReadable} + {this.state.wallet.typeReadable} {(() => { @@ -103,7 +99,9 @@ export default class WalletExport extends Component { {this.state.wallet.type === LightningCustodianWallet.type ? ( ) : ( - {this.state.wallet.getSecret()} + + {this.state.wallet.getSecret()} + )} diff --git a/screen/wallets/hodlHodl.js b/screen/wallets/hodlHodl.js index 5ee2febe..2c00d302 100644 --- a/screen/wallets/hodlHodl.js +++ b/screen/wallets/hodlHodl.js @@ -13,12 +13,14 @@ import { Platform, Image, TextInput, + ScrollView, } from 'react-native'; -import { BlueNavigationStyle, BlueLoading, BlueCard } from '../../BlueComponents'; +import { BlueNavigationStyle, BlueLoading, BlueCard, SafeBlueArea } from '../../BlueComponents'; import PropTypes from 'prop-types'; import { HodlHodlApi } from '../../class/hodl-hodl-api'; import Modal from 'react-native-modal'; import { Icon } from 'react-native-elements'; +const A = require('../../analytics'); const CURRENCY_CODE_ANY = '_any'; const METHOD_ANY = '_any'; @@ -26,7 +28,8 @@ const METHOD_ANY = '_any'; const styles = StyleSheet.create({ grayDropdownText: { fontSize: 17, - color: 'gray', + fontWeight: '600', + color: '#9AA0AA', }, modalContent: { backgroundColor: '#FFFFFF', @@ -47,8 +50,8 @@ const styles = StyleSheet.create({ borderTopLeftRadius: 16, borderTopRightRadius: 16, borderColor: 'rgba(0, 0, 0, 0.1)', - minHeight: 150, - height: 150, + minHeight: 200, + height: 200, }, bottomModal: { justifyContent: 'flex-end', @@ -68,11 +71,15 @@ const styles = StyleSheet.create({ }, grayDropdownTextContainer: { - backgroundColor: '#ebebeb', + backgroundColor: '#EEF0F4', borderRadius: 20, width: 100, height: 35, - top: 10, + top: 3, + paddingLeft: 2, + paddingBottom: 6, + paddingTop: 6, + paddingRight: 0, justifyContent: 'center', alignItems: 'center', flex: 0.65, @@ -80,9 +87,9 @@ const styles = StyleSheet.create({ }, grayTextContainerContainer: { - backgroundColor: '#ebebeb', + backgroundColor: '#EEF0F4', borderRadius: 20, - height: 40, + height: 44, justifyContent: 'center', alignItems: 'center', marginTop: 15, @@ -96,10 +103,11 @@ const styles = StyleSheet.create({ blueText: { color: '#2f5fb3', fontSize: 18, + fontWeight: '600', }, allOffersText: { fontSize: 12, - color: 'gray', + color: '#9AA0AA', position: 'absolute', top: 0, left: 15, @@ -109,20 +117,21 @@ const styles = StyleSheet.create({ left: 5, color: '#0c2550', fontSize: 20, - fontWeight: '100', + fontWeight: '500', }, nicknameText: { color: '#0c2550', - fontSize: 16, - fontWeight: '700', + fontSize: 18, + fontWeight: '600', }, blueTextContainer: { - backgroundColor: '#ccddf9', + backgroundColor: '#CCDDF9', borderRadius: 20, width: 110, flex: 1, flexDirection: 'row', - height: 34, + height: 36, + paddingLeft: 8, justifyContent: 'center', alignItems: 'center', right: 4, @@ -131,17 +140,17 @@ const styles = StyleSheet.create({ searchInputContainer: { flexDirection: 'row', - borderColor: '#d2d2d2', - borderBottomColor: '#d2d2d2', + borderColor: '#EEF0F4', + borderBottomColor: '#EEF0F4', borderWidth: 1.0, borderBottomWidth: 0.5, - backgroundColor: '#f5f5f5', - minHeight: 44, - height: 44, + backgroundColor: '#EEF0F4', + minHeight: 48, + height: 48, marginHorizontal: 20, alignItems: 'center', marginVertical: 8, - borderRadius: 22, + borderRadius: 26, width: '100%', }, }); @@ -255,6 +264,7 @@ export default class HodlHodl extends Component { async componentDidMount() { console.log('wallets/hodlHodl - componentDidMount'); + A(A.ENUM.NAVIGATED_TO_WALLETS_HODLHODL); try { await this.fetchMyCountry(); @@ -424,6 +434,7 @@ export default class HodlHodl extends Component { } data={[ @@ -437,8 +448,10 @@ export default class HodlHodl extends Component { onHideUnderlay={separators.unhighlight} onPress={() => this._onSidePress(item)} > - - {item.name} + + + {item.name} + )} @@ -471,6 +484,7 @@ export default class HodlHodl extends Component { } data={[ @@ -488,17 +502,20 @@ export default class HodlHodl extends Component { }} > - + - {item.native_name} - + {item.native_name} + {item.code === 'currency' && ( - {this.state.currency ? this.state.currency + ' >' : 'Detail >'} + + {' '} + {this.state.currency ? this.state.currency + ' ❯' : 'Detail ❯'}{' '} + )} {item.code === 'method' && ( - + {' '} - {this.state.method ? this.getMethodName(this.state.method) + ' >' : 'Detail >'} + {this.state.method ? this.getMethodName(this.state.method) + ' ❯' : 'Detail ❯'} )} @@ -565,9 +582,10 @@ export default class HodlHodl extends Component { this.setState({ countrySearchInput: text })} placeholder={'Search..'} + placeholderTextColor="#9AA0AA" value={this.state.countrySearchInput || ''} numberOfLines={1} - style={{ flex: 1, marginHorizontal: 8, minHeight: 33 }} + style={{ fontSize: 17, flex: 1, marginHorizontal: 8, minHeight: 33, paddingLeft: 6, paddingRight: 6 }} /> @@ -583,9 +601,9 @@ export default class HodlHodl extends Component { onHideUnderlay={separators.unhighlight} > - + - + {item.native_name} @@ -640,9 +658,10 @@ export default class HodlHodl extends Component { this.setState({ currencySearchInput: text })} placeholder={'Search..'} + placeholderTextColor="#9AA0AA" value={this.state.currencySearchInput || ''} numberOfLines={1} - style={{ flex: 1, marginHorizontal: 8, minHeight: 33 }} + style={{ flex: 1, marginHorizontal: 8, minHeight: 33, paddingLeft: 6, paddingRight: 6 }} /> @@ -658,10 +677,11 @@ export default class HodlHodl extends Component { onHideUnderlay={separators.unhighlight} > - + this.setState({ methodSearchInput: text })} placeholder={'Search..'} + placeholderTextColor="#9AA0AA" value={this.state.methodSearchInput || ''} numberOfLines={1} - style={{ flex: 1, marginHorizontal: 8, minHeight: 33 }} + style={{ flex: 1, marginHorizontal: 8, minHeight: 33, paddingLeft: 6, paddingRight: 6 }} /> @@ -741,10 +762,11 @@ export default class HodlHodl extends Component { onHideUnderlay={separators.unhighlight} > - + + Powered by HodlHodl® @@ -778,7 +800,7 @@ export default class HodlHodl extends Component { }} > {this.state.side === HodlHodlApi.FILTERS_SIDE_VALUE_SELL ? 'Buying' : 'Selling'} - + @@ -797,29 +819,35 @@ export default class HodlHodl extends Component { this.setState({ isFiltersModalVisible: true }); }} > - Filters + Filters - - {(this.state.isLoading && ) || ( + + {(this.state.isLoading && ) || ( + this._refresh()} refreshing={this.state.isLoading} - style={{ height: '80%', marginTop: 10 }} + contentContainerStyle={{ flex: 1, justifyContent: 'center', paddingHorizontal: 0 }} + style={{ marginTop: 24, flex: 1 }} ItemSeparatorComponent={() => } data={this.state.offers} - ListEmptyComponent={() => No offers. Try changing country or filters!} + ListEmptyComponent={() => ( + + No offers. Try to change "Near me" to Global offers! + + )} renderItem={({ item, index, separators }) => ( this._onPress(item)} onShowUnderlay={separators.highlight} onHideUnderlay={separators.unhighlight} > - - + + {item.trader.login} - + {item.trader.trades_count > 0 ? Math.round(item.trader.rating * 100) + '%' : 'No rating'} - {this.getItemText(item)} + {this.getItemText(item)} - {this.getItemPrice(item)} + {this.getItemPrice(item)} - + Min/Max: {item.min_amount.replace('.00', '')} - {item.max_amount.replace('.00', '')} {item.currency_code} @@ -861,8 +890,8 @@ export default class HodlHodl extends Component { )} /> - )} - + + )} {this.renderChooseSideModal()} @@ -873,7 +902,7 @@ export default class HodlHodl extends Component { {this.renderChooseCurrencyModal()} {this.renderChooseMethodModal()} - + ); } } diff --git a/screen/wallets/list.js b/screen/wallets/list.js index 057027f3..0490182b 100644 --- a/screen/wallets/list.js +++ b/screen/wallets/list.js @@ -311,7 +311,11 @@ export default class WalletsList extends Component { }; _renderItem = data => { - return ; + return ( + + + + ); }; renderNavigationHeader = () => { diff --git a/screen/wallets/transactions.js b/screen/wallets/transactions.js index 95e17e14..a4de9298 100644 --- a/screen/wallets/transactions.js +++ b/screen/wallets/transactions.js @@ -228,7 +228,7 @@ export default class WalletTransactions extends Component { style={{ flex: 1, marginLeft: 16, - marginTop: 24, + marginTop: 8, marginBottom: 8, fontWeight: 'bold', fontSize: 24, @@ -444,11 +444,13 @@ export default class WalletTransactions extends Component { renderItem = item => { return ( - + + + ); }; diff --git a/shim.js b/shim.js index a1a87f57..4e6be044 100644 --- a/shim.js +++ b/shim.js @@ -1,4 +1,5 @@ /* global __DEV__, localStorage */ +if (typeof Buffer === 'undefined') global.Buffer = require('buffer').Buffer; if (typeof __dirname === 'undefined') global.__dirname = '/'; if (typeof __filename === 'undefined') global.__filename = ''; if (typeof process === 'undefined') { @@ -13,7 +14,6 @@ if (typeof process === 'undefined') { } process.browser = false; -if (typeof Buffer === 'undefined') global.Buffer = require('buffer').Buffer; global.net = require('react-native-tcp'); global.tls = require('react-native-tcp/tls'); diff --git a/tests/e2e/bluewallet.spec.js b/tests/e2e/bluewallet.spec.js index 9541500b..f4f97625 100644 --- a/tests/e2e/bluewallet.spec.js +++ b/tests/e2e/bluewallet.spec.js @@ -5,17 +5,6 @@ describe('BlueWallet UI Tests', () => { await yo('WalletsList'); }); - it('selftest passes', async () => { - await yo('WalletsList'); - - // go to settings, press SelfTest and wait for OK - await element(by.id('SettingsButton')).tap(); - await element(by.id('AboutButton')).tap(); - await element(by.id('AboutScrollView')).swipe('up', 'fast', 1); // in case emu screen is small and it doesnt fit - await element(by.id('RunSelfTestButton')).tap(); - await yo('SelfTestOk', 600 * 1000); - }); - it('can encrypt storage, with plausible deniability', async () => { await yo('WalletsList'); @@ -221,6 +210,7 @@ describe('BlueWallet UI Tests', () => { it('can encrypt storage, and decrypt storage, but this time the fake one', async () => { // this test mostly repeats previous one, except in the end it logins with FAKE password to unlock FAKE // storage bucket, and then decrypts it. effectively, everything from MAIN storage bucket is lost + if (process.env.TRAVIS) return; // skipping on CI to not take time (plus it randomly fails) await yo('WalletsList'); await helperCreateWallet(); await element(by.id('SettingsButton')).tap(); diff --git a/tests/e2e/selftest.spec.js b/tests/e2e/selftest.spec.js new file mode 100644 index 00000000..2d4b2724 --- /dev/null +++ b/tests/e2e/selftest.spec.js @@ -0,0 +1,18 @@ +/* global it, describe, element, by, waitFor */ + +describe('BlueWallet Selftest', () => { + it('passes', async () => { + await waitFor(element(by.id('WalletsList'))) + .toBeVisible() + .withTimeout(1200 * 1000); + + // go to settings, press SelfTest and wait for OK + await element(by.id('SettingsButton')).tap(); + await element(by.id('AboutButton')).tap(); + await element(by.id('AboutScrollView')).swipe('up', 'fast', 1); // in case emu screen is small and it doesnt fit + await element(by.id('RunSelfTestButton')).tap(); + await waitFor(element(by.id('SelfTestOk'))) + .toBeVisible() + .withTimeout(1200 * 1000); + }); +});