diff --git a/BlueComponents.js b/BlueComponents.js index b442c60e..2ce9b3b1 100644 --- a/BlueComponents.js +++ b/BlueComponents.js @@ -11,8 +11,16 @@ import { List, ListItem, } from 'react-native-elements'; -import { ActivityIndicator, ListView, View } from 'react-native'; +import { ActivityIndicator, ListView, View, Dimensions } from 'react-native'; let BlueApp = require('./BlueApp'); +const { height, width } = Dimensions.get('window'); +const aspectRatio = height / width; +let isIpad; +if (aspectRatio > 1.6) { + isIpad = false; +} else { + isIpad = true; +} export class BlueButton extends Component { render() { @@ -104,7 +112,7 @@ export class BlueFormInputAddress extends Component { return ( ); @@ -132,6 +140,16 @@ export class BlueSpacing extends Component { ); } } +export class BlueSpacing40 extends Component { + render() { + return ( + + ); + } +} export class BlueSpacing20 extends Component { render() { diff --git a/app.json b/app.json index 1de23f8b..392912a9 100644 --- a/app.json +++ b/app.json @@ -7,13 +7,14 @@ "ios" ], "ios": { - "buildNumber": 14, + "buildNumber": "25", + "supportsTablet": false, "isRemoteJSEnabled": false, "bundleIdentifier": "io.bluewallet.bluewallet", "infoPlist": { "NSLocationWhenInUseUsageDescription": "Discover local stores nearby that accept Bitcoin", "NSCameraUsageDescription": "Allow BlueWallet to scan QR codes", - "ITSAppUsesNonExemptEncryption": true + "ITSAppUsesNonExemptEncryption": false } }, "name": "Blue Wallet", diff --git a/gif.gif b/gif.gif index 75f748d1..aa8ead24 100644 Binary files a/gif.gif and b/gif.gif differ diff --git a/screen/about.js b/screen/about.js index afd8a02d..78fa32c1 100644 --- a/screen/about.js +++ b/screen/about.js @@ -1,5 +1,5 @@ import React, { Component } from 'react'; -import { ScrollView, Linking } from 'react-native'; +import { ScrollView, Linking, Dimensions } from 'react-native'; import Ionicons from 'react-native-vector-icons/Ionicons'; import { Icon } from 'react-native-elements'; import { @@ -14,6 +14,7 @@ import { import PropTypes from 'prop-types'; /** @type {AppStorage} */ let BlueApp = require('../BlueApp'); +const { height } = Dimensions.get('window'); export default class About extends Component { static navigationOptions = { @@ -58,21 +59,16 @@ export default class About extends Component { } centerComponent={{ text: 'About', - style: { color: '#fff', fontSize: 25 }, + style: { color: '#fff', fontSize: 23 }, }} /> - - About - - + Blue Wallet is free and opensource Bitcoin wallet - - Warning: Alpha version, don't use to store large amouts! - + { diff --git a/screen/plausibledeniability.js b/screen/plausibledeniability.js index 0bcb523d..9c38db94 100644 --- a/screen/plausibledeniability.js +++ b/screen/plausibledeniability.js @@ -60,7 +60,7 @@ export default class PlausibleDeniability extends Component { } centerComponent={{ text: 'Plausible Deniability', - style: { color: '#fff', fontSize: 25 }, + style: { color: '#fff', fontSize: 23 }, }} /> diff --git a/screen/receive/details.js b/screen/receive/details.js index ae8ffa35..81240e6e 100644 --- a/screen/receive/details.js +++ b/screen/receive/details.js @@ -1,16 +1,25 @@ import React, { Component } from 'react'; -import { TextInput } from 'react-native'; +import { Dimensions } from 'react-native'; import Ionicons from 'react-native-vector-icons/Ionicons'; import QRCode from 'react-native-qrcode'; import { BlueLoading, - BlueButton, + BlueSpacing40, + BlueFormInputAddress, SafeBlueArea, BlueCard, BlueSpacing, } from '../../BlueComponents'; import PropTypes from 'prop-types'; let BlueApp = require('../../BlueApp'); +const { height, width } = Dimensions.get('window'); +const aspectRatio = height / width; +let isIpad; +if (aspectRatio > 1.6) { + isIpad = false; +} else { + isIpad = true; +} export default class ReceiveDetails extends Component { static navigationOptions = { @@ -47,34 +56,27 @@ export default class ReceiveDetails extends Component { } return ( - - + + {(() => { + if (isIpad) { + return ; + } else { + return ; + } + })()} + - + - - this.props.navigation.goBack()} - title="Go back" - /> ); } diff --git a/screen/receive/list.js b/screen/receive/list.js index 2e7186f2..d48d091c 100644 --- a/screen/receive/list.js +++ b/screen/receive/list.js @@ -1,5 +1,6 @@ /** @type {AppStorage} */ import React, { Component } from 'react'; +import { ListView, Dimensions } from 'react-native'; import Ionicons from 'react-native-vector-icons/Ionicons'; import { BlueLoading, @@ -11,6 +12,8 @@ import { import PropTypes from 'prop-types'; let BlueApp = require('../../BlueApp'); let EV = require('../../events'); +const { height } = Dimensions.get('window'); +let ds = new ListView.DataSource({ rowHasChanged: (r1, r2) => r1 !== r2 }); export default class ReceiveList extends Component { static navigationOptions = { @@ -51,6 +54,7 @@ export default class ReceiveList extends Component { this.setState({ isLoading: false, list: list, + dataSource: ds.cloneWithRows(list), }); } @@ -64,29 +68,34 @@ export default class ReceiveList extends Component { return ( - {this.state.list.map((item, i) => ( - { - navigate('ReceiveDetails', { address: item.title }); - }} - key={i} - title={item.title} - subtitle={item.subtitle} - leftIcon={{ - name: 'bitcoin', - type: 'font-awesome', - color: 'white', - }} - /> - ))} + { + return ( + { + navigate('ReceiveDetails', { address: item.title }); + }} + leftIcon={{ + name: 'bitcoin', + type: 'font-awesome', + color: 'white', + }} + /> + ); + }} + /> ); diff --git a/screen/selftest.js b/screen/selftest.js index af56941e..ea5f74a0 100644 --- a/screen/selftest.js +++ b/screen/selftest.js @@ -150,7 +150,7 @@ export default class Selftest extends Component { backgroundColor={BlueApp.settings.brandingColor} centerComponent={{ text: 'Self test', - style: { color: '#fff', fontSize: 25 }, + style: { color: '#fff', fontSize: 23 }, }} /> diff --git a/screen/send/details.js b/screen/send/details.js index 8c7f69f6..e44b040b 100644 --- a/screen/send/details.js +++ b/screen/send/details.js @@ -1,9 +1,10 @@ import React, { Component } from 'react'; -import { ActivityIndicator, View } from 'react-native'; +import { ActivityIndicator, View, Dimensions } from 'react-native'; import Ionicons from 'react-native-vector-icons/Ionicons'; import { Text, FormValidationMessage } from 'react-native-elements'; import { BlueSpacing20, + BlueSpacing40, BlueButton, SafeBlueArea, BlueCard, @@ -17,6 +18,14 @@ const bip21 = require('bip21'); let EV = require('../../events'); let BigNumber = require('bignumber.js'); let BlueApp = require('../../BlueApp'); +const { height, width } = Dimensions.get('window'); +const aspectRatio = height / width; +let isIpad; +if (aspectRatio > 1.6) { + isIpad = false; +} else { + isIpad = true; +} const btcAddressRx = /^[a-zA-Z0-9]{26,35}$/; @@ -170,7 +179,13 @@ export default class SendDetails extends Component { return ( - + {(() => { + if (isIpad) { + return ; + } else { + return ; + } + })()} {this.state.errorMessage} - + this.props.navigation.goBack()} diff --git a/screen/send/list.js b/screen/send/list.js index ffec37bb..21f0b764 100644 --- a/screen/send/list.js +++ b/screen/send/list.js @@ -1,5 +1,5 @@ import React, { Component } from 'react'; -import { ActivityIndicator, View } from 'react-native'; +import { Dimensions, ActivityIndicator, View, ListView } from 'react-native'; import Ionicons from 'react-native-vector-icons/Ionicons'; import { SafeBlueArea, @@ -11,6 +11,8 @@ import PropTypes from 'prop-types'; let EV = require('../../events'); /** @type {AppStorage} */ let BlueApp = require('../../BlueApp'); +const { height } = Dimensions.get('window'); +let ds = new ListView.DataSource({ rowHasChanged: (r1, r2) => r1 !== r2 }); export default class SendList extends Component { static navigationOptions = { @@ -51,6 +53,7 @@ export default class SendList extends Component { this.setState({ isLoading: false, list: list, + dataSource: ds.cloneWithRows(list), }); } @@ -69,27 +72,33 @@ export default class SendList extends Component { - {this.state.list.map((item, i) => ( - { - navigate('SendDetails', { fromAddress: item.title }); - }} - key={i} - title={item.title} - subtitle={item.subtitle} - leftIcon={{ - name: 'bitcoin', - type: 'font-awesome', - color: 'white', - }} - /> - ))} + { + return ( + { + navigate('SendDetails', { fromAddress: item.title }); + }} + leftIcon={{ + name: 'bitcoin', + type: 'font-awesome', + color: 'white', + }} + /> + ); + }} + /> ); diff --git a/screen/send/scanQrAddress.js b/screen/send/scanQrAddress.js index 51519d91..05020f20 100644 --- a/screen/send/scanQrAddress.js +++ b/screen/send/scanQrAddress.js @@ -8,10 +8,22 @@ import { TouchableOpacity, } from 'react-native'; import { Camera, Permissions } from 'expo'; +import Ionicons from 'react-native-vector-icons/Ionicons'; import PropTypes from 'prop-types'; let EV = require('../../events'); export default class CameraExample extends React.Component { + static navigationOptions = { + tabBarLabel: 'Send', + tabBarIcon: ({ tintColor, focused }) => ( + + ), + }; + state = { isLoading: false, hasCameraPermission: null, diff --git a/screen/settings.js b/screen/settings.js index 34625e82..ec5f8f3b 100644 --- a/screen/settings.js +++ b/screen/settings.js @@ -61,7 +61,7 @@ export default class Settings extends Component { } centerComponent={{ text: 'Settings', - style: { color: '#fff', fontSize: 25 }, + style: { color: '#fff', fontSize: 23 }, }} /> diff --git a/screen/transactions/details.js b/screen/transactions/details.js index a52e8175..cf4c8f6e 100644 --- a/screen/transactions/details.js +++ b/screen/transactions/details.js @@ -123,12 +123,6 @@ export default class TransactionsDetails extends Component { ); } })()} - - this.props.navigation.goBack()} - title="Go back" - /> ); } diff --git a/screen/transactions/list.js b/screen/transactions/list.js index c67509bc..8525aded 100644 --- a/screen/transactions/list.js +++ b/screen/transactions/list.js @@ -1,5 +1,5 @@ import React, { Component } from 'react'; -import { ListView } from 'react-native'; +import { ListView, Dimensions } from 'react-native'; import Ionicons from 'react-native-vector-icons/Ionicons'; import { Header, Icon } from 'react-native-elements'; import { @@ -14,6 +14,7 @@ import PropTypes from 'prop-types'; let EV = require('../../events'); /** @type {AppStorage} */ let BlueApp = require('../../BlueApp'); +const { height } = Dimensions.get('window'); let ds = new ListView.DataSource({ rowHasChanged: (r1, r2) => r1 !== r2 }); @@ -123,7 +124,7 @@ export default class TransactionsList extends Component { { diff --git a/screen/wallets/add.js b/screen/wallets/add.js index ebfa05fd..23acd89f 100644 --- a/screen/wallets/add.js +++ b/screen/wallets/add.js @@ -95,14 +95,6 @@ export default class WalletsAdd extends Component { }} /> - - { - this.props.navigation.goBack(); - }} - /> ); } diff --git a/screen/wallets/details.js b/screen/wallets/details.js index d2779689..55b3cf88 100644 --- a/screen/wallets/details.js +++ b/screen/wallets/details.js @@ -1,8 +1,9 @@ import React, { Component } from 'react'; -import { ActivityIndicator, View } from 'react-native'; +import { Dimensions, ActivityIndicator, View } from 'react-native'; import Ionicons from 'react-native-vector-icons/Ionicons'; import { BlueSpacing, + BlueSpacing40, BlueFormInput, BlueButton, SafeBlueArea, @@ -15,6 +16,14 @@ import PropTypes from 'prop-types'; let EV = require('../../events'); /** @type {AppStorage} */ let BlueApp = require('../../BlueApp'); +const { height, width } = Dimensions.get('window'); +const aspectRatio = height / width; +let isIpad; +if (aspectRatio > 1.6) { + isIpad = false; +} else { + isIpad = true; +} export default class WalletDetails extends Component { static navigationOptions = { @@ -65,15 +74,22 @@ export default class WalletDetails extends Component { render() { if (this.state.isLoading) { return ( - + ); } return ( - - + + {(() => { + if (isIpad) { + return ; + } else { + return ; + } + })()} + - Are you sure? - { - BlueApp.deleteWallet(this.state.wallet); - await BlueApp.saveToDisk(); - EV(EV.enum.TRANSACTIONS_COUNT_CHANGED); - EV(EV.enum.WALLETS_COUNT_CHANGED); - this.props.navigation.goBack(); - }} - title="Yes, delete" - /> - { - this.setState({ confirmDelete: false }); - }} - title="No, cancel" - /> + Are you sure? + + + { + BlueApp.deleteWallet(this.state.wallet); + await BlueApp.saveToDisk(); + EV(EV.enum.TRANSACTIONS_COUNT_CHANGED); + EV(EV.enum.WALLETS_COUNT_CHANGED); + this.props.navigation.goBack(); + }} + title="Yes, delete" + /> + + + { + this.setState({ confirmDelete: false }); + }} + title="No, cancel" + /> + + ); } else { @@ -133,25 +155,23 @@ export default class WalletDetails extends Component { }} title="Delete this wallet" /> - - this.props.navigation.navigate('WalletExport', { - address: this.state.wallet.getAddress(), - }) + + {(() => { + if (isIpad) { + return ; + } else { + return ( + + this.props.navigation.navigate('WalletExport', { + address: this.state.wallet.getAddress(), + }) + } + title="Export / backup" + /> + ); } - title="Export / backup" - /> - { - if (this.state.labelChanged) { - await BlueApp.saveToDisk(); - EV(EV.enum.WALLETS_COUNT_CHANGED); // TODO: some other event type? - } - this.props.navigation.goBack(); - }} - title="Go back" - /> + })()} ); } diff --git a/screen/wallets/export.js b/screen/wallets/export.js index d900a488..6e51df1d 100644 --- a/screen/wallets/export.js +++ b/screen/wallets/export.js @@ -4,7 +4,6 @@ import Ionicons from 'react-native-vector-icons/Ionicons'; import QRCode from 'react-native-qrcode'; import { BlueSpacing, - BlueButton, SafeBlueArea, BlueCard, BlueText, @@ -86,12 +85,6 @@ export default class WalletExport extends Component { {this.state.wallet.getSecret()} [Wallet Import Format] - - this.props.navigation.goBack()} - title="Go back" - /> ); } diff --git a/screen/wallets/list.js b/screen/wallets/list.js index 8d298a9b..29ae5503 100644 --- a/screen/wallets/list.js +++ b/screen/wallets/list.js @@ -1,5 +1,5 @@ import React, { Component } from 'react'; -import { ListView } from 'react-native'; +import { ListView, Dimensions } from 'react-native'; import Ionicons from 'react-native-vector-icons/Ionicons'; import { BlueLoading, @@ -15,6 +15,14 @@ import PropTypes from 'prop-types'; let EV = require('../../events'); /** @type {AppStorage} */ let BlueApp = require('../../BlueApp'); +const { height, width } = Dimensions.get('window'); +const aspectRatio = height / width; +let isIpad; +if (aspectRatio > 1.6) { + isIpad = false; +} else { + isIpad = true; +} let ds = new ListView.DataSource({ rowHasChanged: (r1, r2) => r1 !== r2 }); @@ -70,7 +78,7 @@ export default class WalletsList extends Component { @@ -82,7 +90,7 @@ export default class WalletsList extends Component { { return ( diff --git a/up-build-number.js b/up-build-number.js index d235a7c1..66c99998 100644 --- a/up-build-number.js +++ b/up-build-number.js @@ -1,4 +1,5 @@ let fs = require('fs'); var appjson = require('./app.json'); appjson.expo.ios.buildNumber++; +appjson.expo.ios.buildNumber = appjson.expo.ios.buildNumber + ''; // casting to string fs.writeFileSync('./app.json', JSON.stringify(appjson, null, 2));