REF: move all inline styles to StyleSheet.create

This commit is contained in:
Ivan Vershigora 2020-05-24 12:17:26 +03:00
parent 6a6ac478cc
commit 68e10cd7f1
45 changed files with 2714 additions and 1597 deletions

View file

@ -1,5 +1,5 @@
import React, { Component } from 'react';
import { TouchableOpacity, ActivityIndicator, TextInput, Keyboard, BackHandler, View, Alert, Platform } from 'react-native';
import { TouchableOpacity, ActivityIndicator, TextInput, Keyboard, BackHandler, View, Alert, Platform, StyleSheet } from 'react-native';
import { WebView } from 'react-native-webview';
import { BlueNavigationStyle, SafeBlueArea } from '../../BlueComponents';
import Ionicons from 'react-native-vector-icons/Ionicons';
@ -205,6 +205,75 @@ window.ReactNativeWebView.postMessage('interval');
`;
const styles = StyleSheet.create({
safeRoot: {
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'space-between',
minHeight: 44,
},
safeBack: {
marginHorizontal: 8,
},
safeURL: {
flex: 1,
marginHorizontal: 8,
alignItems: 'center',
justifyContent: 'center',
},
safeURLTextWrap: {
flexDirection: 'row',
borderColor: '#d2d2d2',
borderBottomColor: '#d2d2d2',
borderWidth: 1.0,
borderBottomWidth: 0.5,
backgroundColor: '#f5f5f5',
minHeight: 44,
height: 44,
alignItems: 'center',
marginVertical: 8,
borderRadius: 4,
},
safeURLText: {
flex: 1,
marginLeft: 4,
minHeight: 33,
},
safeURLHome: {
alignContent: 'flex-end',
height: 44,
flexDirection: 'row',
marginHorizontal: 8,
},
sync: {
color: 'red',
backgroundColor: 'transparent',
paddingLeft: 15,
},
activity: {
flex: 1,
justifyContent: 'center',
paddingLeft: 20,
alignContent: 'center',
},
goBack: {
backgroundColor: 'transparent',
paddingLeft: 10,
},
colorRed: {
color: 'red',
},
colorGray: {
color: 'gray',
},
transparent: {
backgroundColor: 'transparent',
},
colorGreen: {
color: 'green',
},
});
export default class Browser extends Component {
static navigationOptions = ({ navigation }) => ({
...BlueNavigationStyle(navigation, true),
@ -353,46 +422,28 @@ export default class Browser extends Component {
render() {
return (
<SafeBlueArea>
<View style={{ flexDirection: 'row', alignItems: 'center', justifyContent: 'space-between', minHeight: 44 }}>
<View style={styles.safeRoot}>
<TouchableOpacity
disabled={!this.state.canGoBack}
onPress={() => {
this.webview.goBack();
}}
style={{ marginHorizontal: 8 }}
style={styles.safeBack}
>
<Ionicons
name={'ios-arrow-round-back'}
name="ios-arrow-round-back"
size={36}
style={{
color: this.state.canGoBack ? 'red' : 'gray',
backgroundColor: 'transparent',
paddingLeft: 10,
}}
style={[styles.goBack, this.state.canGoBack ? styles.colorRed : styles.colorGray]}
/>
</TouchableOpacity>
<View style={{ flex: 1, marginHorizontal: 8, alignItems: 'center', justifyContent: 'center' }}>
<View
style={{
flexDirection: 'row',
borderColor: '#d2d2d2',
borderBottomColor: '#d2d2d2',
borderWidth: 1.0,
borderBottomWidth: 0.5,
backgroundColor: '#f5f5f5',
minHeight: 44,
height: 44,
alignItems: 'center',
marginVertical: 8,
borderRadius: 4,
}}
>
<View style={styles.safeURL}>
<View style={styles.safeURLTextWrap}>
<TextInput
onChangeText={text => this.setState({ stateURL: text })}
value={this.state.stateURL}
numberOfLines={1}
style={{ flex: 1, marginLeft: 4, minHeight: 33 }}
style={styles.safeURLText}
editable
onSubmitEditing={() => {
Keyboard.dismiss();
@ -405,7 +456,7 @@ export default class Browser extends Component {
/>
</View>
</View>
<View style={{ alignContent: 'flex-end', height: 44, flexDirection: 'row', marginHorizontal: 8 }}>
<View style={styles.safeURLHome}>
{Platform.OS !== 'ios' && ( // on iOS lappbrowser opens blank page, thus, no HOME button
<TouchableOpacity
onPress={() => {
@ -414,12 +465,9 @@ export default class Browser extends Component {
}}
>
<Ionicons
name={'ios-home'}
name="ios-home"
size={36}
style={{
color: this.state.weblnEnabled ? 'green' : 'red',
backgroundColor: 'transparent',
}}
style={[styles.transparent, this.state.weblnEnabled ? styles.colorGreen : styles.colorRed]}
/>
</TouchableOpacity>
)}
@ -434,17 +482,9 @@ export default class Browser extends Component {
}}
>
{!this.state.pageIsLoading ? (
<Ionicons
name={'ios-sync'}
size={36}
style={{
color: 'red',
backgroundColor: 'transparent',
paddingLeft: 15,
}}
/>
<Ionicons name="ios-sync" size={36} style={styles.sync} />
) : (
<View style={{ flex: 1, justifyContent: 'center', paddingLeft: 20, alignContent: 'center' }}>
<View style={styles.activity}>
<ActivityIndicator />
</View>
)}

View file

@ -9,6 +9,7 @@ import {
TouchableWithoutFeedback,
TouchableOpacity,
Text,
StyleSheet,
} from 'react-native';
import {
BlueNavigationStyle,
@ -28,6 +29,103 @@ let BlueApp = require('../../BlueApp');
let EV = require('../../events');
let loc = require('../../loc');
const styles = StyleSheet.create({
createButton: {
marginHorizontal: 56,
marginVertical: 16,
minHeight: 45,
alignContent: 'center',
backgroundColor: '#FFFFFF',
},
scanRoot: {
height: 36,
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'space-between',
backgroundColor: '#9AA0AA',
borderRadius: 4,
paddingVertical: 4,
paddingHorizontal: 8,
marginHorizontal: 4,
},
scanClick: {
marginLeft: 4,
color: BlueApp.settings.inverseForegroundColor,
},
walletRoot: {
marginBottom: 16,
alignItems: 'center',
justifyContent: 'center',
},
walletChooseWrap: {
flexDirection: 'row',
alignItems: 'center',
},
walletChooseText: {
color: '#9aa0aa',
fontSize: 14,
marginRight: 8,
},
walletNameWrap: {
flexDirection: 'row',
alignItems: 'center',
marginVertical: 4,
},
walletNameTouch: {
flexDirection: 'row',
alignItems: 'center',
},
walletNameText: {
color: '#0c2550',
fontSize: 14,
},
walletNameBalance: {
color: '#0c2550',
fontSize: 14,
fontWeight: '600',
marginLeft: 8,
marginRight: 4,
},
walletNameSats: {
color: '#0c2550',
fontSize: 11,
fontWeight: '600',
textAlignVertical: 'bottom',
marginTop: 2,
},
error: {
flex: 1,
paddingTop: 20,
},
root: {
flex: 1,
justifyContent: 'space-between',
},
amount: {
flex: 1,
backgroundColor: '#FFFFFF',
},
fiat: {
flexDirection: 'row',
borderColor: '#d2d2d2',
borderBottomColor: '#d2d2d2',
borderWidth: 1.0,
borderBottomWidth: 0.5,
backgroundColor: '#f5f5f5',
minHeight: 44,
height: 44,
marginHorizontal: 20,
alignItems: 'center',
marginVertical: 8,
borderRadius: 4,
},
fiat2: {
flex: 1,
marginHorizontal: 8,
minHeight: 33,
},
});
export default class LNDCreateInvoice extends Component {
static navigationOptions = ({ navigation }) => ({
...BlueNavigationStyle(navigation, true),
@ -194,7 +292,7 @@ export default class LNDCreateInvoice extends Component {
renderCreateButton = () => {
return (
<View style={{ marginHorizontal: 56, marginVertical: 16, minHeight: 45, alignContent: 'center', backgroundColor: '#FFFFFF' }}>
<View style={styles.createButton}>
{this.state.isLoading ? (
<ActivityIndicator />
) : (
@ -215,20 +313,10 @@ export default class LNDCreateInvoice extends Component {
});
Keyboard.dismiss();
}}
style={{
height: 36,
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'space-between',
backgroundColor: '#9AA0AA',
borderRadius: 4,
paddingVertical: 4,
paddingHorizontal: 8,
marginHorizontal: 4,
}}
style={styles.scanRoot}
>
<Icon name="qrcode" size={22} type="font-awesome" color={BlueApp.settings.inverseForegroundColor} />
<Text style={{ marginLeft: 4, color: BlueApp.settings.inverseForegroundColor }}>{loc.send.details.scan}</Text>
<Text style={styles.scanClick}>{loc.send.details.scan}</Text>
</TouchableOpacity>
);
};
@ -236,32 +324,30 @@ export default class LNDCreateInvoice extends Component {
renderWalletSelectionButton = () => {
if (this.state.renderWalletSelectionButtonHidden) return;
return (
<View style={{ marginBottom: 16, alignItems: 'center', justifyContent: 'center' }}>
<View style={styles.walletRoot}>
{!this.state.isLoading && (
<TouchableOpacity
style={{ flexDirection: 'row', alignItems: 'center' }}
style={styles.walletChooseWrap}
onPress={() =>
this.props.navigation.navigate('SelectWallet', { onWalletSelect: this.onWalletSelect, chainType: Chain.OFFCHAIN })
}
>
<Text style={{ color: '#9aa0aa', fontSize: 14, marginRight: 8 }}>{loc.wallets.select_wallet.toLowerCase()}</Text>
<Text style={styles.walletChooseText}>{loc.wallets.select_wallet.toLowerCase()}</Text>
<Icon name="angle-right" size={18} type="font-awesome" color="#9aa0aa" />
</TouchableOpacity>
)}
<View style={{ flexDirection: 'row', alignItems: 'center', marginVertical: 4 }}>
<View style={styles.walletNameWrap}>
<TouchableOpacity
style={{ flexDirection: 'row', alignItems: 'center' }}
style={styles.walletNameTouch}
onPress={() =>
this.props.navigation.navigate('SelectWallet', { onWalletSelect: this.onWalletSelect, chainType: Chain.OFFCHAIN })
}
>
<Text style={{ color: '#0c2550', fontSize: 14 }}>{this.state.fromWallet.getLabel()}</Text>
<Text style={{ color: '#0c2550', fontSize: 14, fontWeight: '600', marginLeft: 8, marginRight: 4 }}>
<Text style={styles.walletNameText}>{this.state.fromWallet.getLabel()}</Text>
<Text style={styles.walletNameBalance}>
{loc.formatBalanceWithoutSuffix(this.state.fromWallet.getBalance(), BitcoinUnit.SATS, false)}
</Text>
<Text style={{ color: '#0c2550', fontSize: 11, fontWeight: '600', textAlignVertical: 'bottom', marginTop: 2 }}>
{BitcoinUnit.SATS}
</Text>
<Text style={styles.walletNameSats}>{BitcoinUnit.SATS}</Text>
</TouchableOpacity>
</View>
</View>
@ -275,7 +361,7 @@ export default class LNDCreateInvoice extends Component {
render() {
if (!this.state.fromWallet) {
return (
<View style={{ flex: 1, paddingTop: 20 }}>
<View style={styles.error}>
<Text>System error: Source wallet not found (this should never happen)</Text>
</View>
);
@ -283,8 +369,8 @@ export default class LNDCreateInvoice extends Component {
return (
<TouchableWithoutFeedback onPress={Keyboard.dismiss} accessible={false}>
<View style={{ flex: 1, justifyContent: 'space-between' }}>
<View style={{ flex: 1, backgroundColor: '#FFFFFF' }}>
<View style={styles.root}>
<View style={styles.amount}>
<KeyboardAvoidingView behavior="position">
<BlueBitcoinAmount
isLoading={this.state.isLoading}
@ -307,28 +393,13 @@ export default class LNDCreateInvoice extends Component {
unit={BitcoinUnit.SATS}
inputAccessoryViewID={BlueDismissKeyboardInputAccessory.InputAccessoryViewID}
/>
<View
style={{
flexDirection: 'row',
borderColor: '#d2d2d2',
borderBottomColor: '#d2d2d2',
borderWidth: 1.0,
borderBottomWidth: 0.5,
backgroundColor: '#f5f5f5',
minHeight: 44,
height: 44,
marginHorizontal: 20,
alignItems: 'center',
marginVertical: 8,
borderRadius: 4,
}}
>
<View style={styles.fiat}>
<TextInput
onChangeText={text => this.setState({ description: text })}
placeholder={loc.receive.details.label}
value={this.state.description}
numberOfLines={1}
style={{ flex: 1, marginHorizontal: 8, minHeight: 33 }}
style={styles.fiat2}
editable={!this.state.isLoading}
onSubmitEditing={Keyboard.dismiss}
inputAccessoryViewID={BlueDismissKeyboardInputAccessory.InputAccessoryViewID}

View file

@ -1,6 +1,6 @@
/* global alert */
import React, { Component } from 'react';
import { View, Share } from 'react-native';
import { View, Share, StyleSheet } from 'react-native';
import {
BlueLoading,
BlueCopyTextToClipboard,
@ -16,6 +16,31 @@ import QRCode from 'react-native-qrcode-svg';
let BlueApp = require('../../BlueApp');
const loc = require('../../loc');
const styles = StyleSheet.create({
loading: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
},
root: {
flex: 1,
},
wrapper: {
flex: 1,
justifyContent: 'space-between',
alignItems: 'center',
},
qrcode: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
paddingHorizontal: 16,
},
share: {
marginBottom: 25,
},
});
export default class LNDViewAdditionalInvoiceInformation extends Component {
static navigationOptions = ({ navigation }) => ({
...BlueNavigationStyle(),
@ -38,16 +63,16 @@ export default class LNDViewAdditionalInvoiceInformation extends Component {
render() {
if (typeof this.state.walletInfo === 'undefined') {
return (
<SafeBlueArea style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<SafeBlueArea style={styles.loading}>
<BlueLoading />
</SafeBlueArea>
);
}
return (
<SafeBlueArea style={{ flex: 1 }}>
<View style={{ flex: 1, justifyContent: 'space-between', alignItems: 'center' }}>
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center', paddingHorizontal: 16 }}>
<SafeBlueArea style={styles.root}>
<View style={styles.wrapper}>
<View style={styles.qrcode}>
<QRCode
value={this.state.walletInfo.uris[0]}
logo={require('../../img/qr-code.png')}
@ -60,7 +85,7 @@ export default class LNDViewAdditionalInvoiceInformation extends Component {
<BlueText>{loc.lndViewInvoice.open_direct_channel}</BlueText>
<BlueCopyTextToClipboard text={this.state.walletInfo.uris[0]} />
</View>
<View style={{ marginBottom: 25 }}>
<View style={styles.share}>
<BlueButton
icon={{
name: 'share-alternative',

View file

@ -1,5 +1,5 @@
import React, { Component } from 'react';
import { View, Text, Dimensions, ScrollView, BackHandler, InteractionManager, TouchableOpacity } from 'react-native';
import { View, Text, Dimensions, ScrollView, BackHandler, InteractionManager, TouchableOpacity, StyleSheet } from 'react-native';
import Share from 'react-native-share';
import {
BlueLoading,
@ -21,6 +21,97 @@ const loc = require('../../loc');
const EV = require('../../events');
const { width, height } = Dimensions.get('window');
const styles = StyleSheet.create({
root: {
flex: 1,
},
center: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
},
valueRoot: {
flex: 2,
flexDirection: 'column',
justifyContent: 'center',
},
valueAmount: {
flexDirection: 'row',
justifyContent: 'center',
paddingBottom: 8,
},
valueText: {
color: '#0f5cc0',
fontSize: 32,
fontWeight: '600',
},
valueSats: {
color: '#0f5cc0',
fontSize: 16,
marginHorizontal: 4,
paddingBottom: 3,
fontWeight: '600',
alignSelf: 'flex-end',
},
memo: {
color: '#9aa0aa',
fontSize: 14,
marginHorizontal: 4,
paddingBottom: 6,
fontWeight: '400',
alignSelf: 'center',
},
paid: {
flex: 3,
alignItems: 'center',
justifyContent: 'center',
},
paidMark: {
marginTop: -100,
marginBottom: 16,
},
detailsRoot: {
flex: 1,
justifyContent: 'flex-end',
marginBottom: 24,
alignItems: 'center',
},
detailsTouch: {
flexDirection: 'row',
alignItems: 'center',
},
detailsText: {
color: '#9aa0aa',
fontSize: 14,
marginRight: 8,
},
expired: {
backgroundColor: '#ccddf9',
width: 120,
height: 120,
borderRadius: 60,
alignSelf: 'center',
justifyContent: 'center',
marginTop: -100,
marginBottom: 30,
},
activeRoot: {
flex: 1,
alignItems: 'center',
marginTop: 8,
justifyContent: 'space-between',
},
activeQrcode: {
flex: 1,
alignItems: 'center',
justifyContent: 'center',
paddingHorizontal: 16,
},
additionalInfo: {
backgroundColor: BlueApp.settings.brandingColor,
},
});
export default class LNDViewInvoice extends Component {
static navigationOptions = ({ navigation }) =>
navigation.getParam('isModal') === true
@ -120,8 +211,8 @@ export default class LNDViewInvoice extends Component {
if (this.state.showPreimageQr) {
return (
<SafeBlueArea style={{ flex: 1 }}>
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<SafeBlueArea style={styles.root}>
<View style={styles.center}>
<BlueText>Preimage:</BlueText>
<BlueSpacing20 />
<QRCode
@ -144,62 +235,31 @@ export default class LNDViewInvoice extends Component {
if (invoice.ispaid || invoice.type === 'paid_invoice') {
return (
<SafeBlueArea style={{ flex: 1 }}>
<View style={{ flex: 2, flexDirection: 'column', justifyContent: 'center' }}>
<SafeBlueArea style={styles.root}>
<View style={styles.valueRoot}>
{invoice.type === 'paid_invoice' && invoice.value && (
<View style={{ flexDirection: 'row', justifyContent: 'center', paddingBottom: 8 }}>
<Text style={{ color: '#0f5cc0', fontSize: 32, fontWeight: '600' }}>{invoice.value}</Text>
<Text
style={{
color: '#0f5cc0',
fontSize: 16,
marginHorizontal: 4,
paddingBottom: 3,
fontWeight: '600',
alignSelf: 'flex-end',
}}
>
{loc.lndViewInvoice.sats}
</Text>
<View style={styles.valueAmount}>
<Text style={styles.valueText}>{invoice.value}</Text>
<Text style={styles.valueSats}>{loc.lndViewInvoice.sats}</Text>
</View>
)}
{invoice.type === 'user_invoice' && invoice.amt && (
<View style={{ flexDirection: 'row', justifyContent: 'center', paddingBottom: 8 }}>
<Text style={{ color: '#0f5cc0', fontSize: 32, fontWeight: '600' }}>{invoice.amt}</Text>
<Text
style={{
color: '#0f5cc0',
fontSize: 16,
marginHorizontal: 4,
paddingBottom: 3,
fontWeight: '600',
alignSelf: 'flex-end',
}}
>
{loc.lndViewInvoice.sats}
</Text>
<View style={styles.valueAmount}>
<Text style={styles.valueText}>{invoice.amt}</Text>
<Text style={styles.valueSats}>{loc.lndViewInvoice.sats}</Text>
</View>
)}
{!invoice.ispaid && invoice.memo && invoice.memo.length > 0 && (
<Text
style={{ color: '#9aa0aa', fontSize: 14, marginHorizontal: 4, paddingBottom: 6, fontWeight: '400', alignSelf: 'center' }}
>
{invoice.memo}
</Text>
)}
{!invoice.ispaid && invoice.memo && invoice.memo.length > 0 && <Text style={styles.memo}>{invoice.memo}</Text>}
</View>
<View style={{ flex: 3, alignItems: 'center', justifyContent: 'center' }}>
<BlueBigCheckmark style={{ marginTop: -100, marginBottom: 16 }} />
<View style={styles.paid}>
<BlueBigCheckmark style={styles.paidMark} />
<BlueText>{loc.lndViewInvoice.has_been_paid}</BlueText>
</View>
<View style={{ flex: 1, justifyContent: 'flex-end', marginBottom: 24, alignItems: 'center' }}>
<View style={styles.detailsRoot}>
{invoice.payment_preimage && typeof invoice.payment_preimage === 'string' ? (
<TouchableOpacity
style={{ flexDirection: 'row', alignItems: 'center' }}
onPress={() => this.setState({ showPreimageQr: true })}
>
<Text style={{ color: '#9aa0aa', fontSize: 14, marginRight: 8 }}>{loc.send.create.details}</Text>
<TouchableOpacity style={styles.detailsTouch} onPress={() => this.setState({ showPreimageQr: true })}>
<Text style={styles.detailsText}>{loc.send.create.details}</Text>
<Icon name="angle-right" size={18} type="font-awesome" color="#9aa0aa" />
</TouchableOpacity>
) : (
@ -211,20 +271,9 @@ export default class LNDViewInvoice extends Component {
}
if (invoiceExpiration < now && !invoice.ispaid) {
return (
<SafeBlueArea style={{ flex: 1 }}>
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<View
style={{
backgroundColor: '#ccddf9',
width: 120,
height: 120,
borderRadius: 60,
alignSelf: 'center',
justifyContent: 'center',
marginTop: -100,
marginBottom: 30,
}}
>
<SafeBlueArea style={styles.root}>
<View style={styles.center}>
<View style={styles.expired}>
<Icon name="times" size={50} type="font-awesome" color="#0f5cc0" />
</View>
<BlueText>{loc.lndViewInvoice.wasnt_paid_and_expired}</BlueText>
@ -234,8 +283,8 @@ export default class LNDViewInvoice extends Component {
} else if (invoiceExpiration > now && invoice.ispaid) {
if (invoice.ispaid) {
return (
<SafeBlueArea style={{ flex: 1 }}>
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<SafeBlueArea style={styles.root}>
<View style={styles.center}>
<BlueText>{loc.lndViewInvoice.has_been_paid}</BlueText>
</View>
</SafeBlueArea>
@ -247,16 +296,8 @@ export default class LNDViewInvoice extends Component {
return (
<SafeBlueArea>
<ScrollView>
<View
style={{
flex: 1,
alignItems: 'center',
marginTop: 8,
justifyContent: 'space-between',
}}
onLayout={this.onLayout}
>
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center', paddingHorizontal: 16 }}>
<View style={styles.activeRoot} onLayout={this.onLayout}>
<View style={styles.activeQrcode}>
<QRCode
value={typeof this.state.invoice === 'object' ? invoice.payment_request : invoice}
logo={require('../../img/qr-code.png')}
@ -305,9 +346,7 @@ export default class LNDViewInvoice extends Component {
/>
<BlueSpacing20 />
<BlueButton
style={{
backgroundColor: BlueApp.settings.brandingColor,
}}
style={styles.additionalInfo}
onPress={() => this.props.navigation.navigate('LNDViewAdditionalInvoiceInformation', { fromWallet: this.state.fromWallet })}
title={loc.lndViewInvoice.additional_info}
/>

View file

@ -1,6 +1,6 @@
/* global alert */
import React from 'react';
import { Text, ActivityIndicator, KeyboardAvoidingView, View, TouchableOpacity, Keyboard, ScrollView } from 'react-native';
import { Text, ActivityIndicator, KeyboardAvoidingView, View, TouchableOpacity, Keyboard, ScrollView, StyleSheet } from 'react-native';
import PropTypes from 'prop-types';
import {
BlueButton,
@ -22,6 +22,78 @@ let BlueApp = require('../../BlueApp');
let EV = require('../../events');
const loc = require('../../loc');
const styles = StyleSheet.create({
walletSelectRoot: {
marginBottom: 16,
alignItems: 'center',
justifyContent: 'flex-end',
},
walletSelectTouch: {
flexDirection: 'row',
alignItems: 'center',
},
walletSelectText: {
color: '#9aa0aa',
fontSize: 14,
marginRight: 8,
},
walletWrap: {
flexDirection: 'row',
alignItems: 'center',
marginVertical: 4,
},
walletWrapTouch: {
flexDirection: 'row',
alignItems: 'center',
},
walletWrapLabel: {
color: '#0c2550',
fontSize: 14,
},
walletWrapBalance: {
color: '#0c2550',
fontSize: 14,
fontWeight: '600',
marginLeft: 4,
marginRight: 4,
},
walletWrapSats: {
color: '#0c2550',
fontSize: 11,
fontWeight: '600',
textAlignVertical: 'bottom',
marginTop: 2,
},
root: {
flex: 1,
},
scroll: {
flex: 1,
justifyContent: 'space-between',
},
scrollMargin: {
marginTop: 60,
},
description: {
flexDirection: 'row',
marginHorizontal: 20,
alignItems: 'center',
marginVertical: 0,
borderRadius: 4,
},
descriptionText: {
color: '#81868e',
fontWeight: '500',
fontSize: 14,
},
expiresIn: {
color: '#81868e',
fontSize: 12,
left: 20,
top: 10,
},
});
export default class ScanLndInvoice extends React.Component {
static navigationOptions = ({ navigation }) => ({
...BlueNavigationStyle(navigation, true),
@ -213,32 +285,30 @@ export default class ScanLndInvoice extends React.Component {
renderWalletSelectionButton = () => {
if (this.state.renderWalletSelectionButtonHidden) return;
return (
<View style={{ marginBottom: 16, alignItems: 'center', justifyContent: 'flex-end' }}>
<View style={styles.walletSelectRoot}>
{!this.state.isLoading && (
<TouchableOpacity
style={{ flexDirection: 'row', alignItems: 'center' }}
style={styles.walletSelectTouch}
onPress={() =>
this.props.navigation.navigate('SelectWallet', { onWalletSelect: this.onWalletSelect, chainType: Chain.OFFCHAIN })
}
>
<Text style={{ color: '#9aa0aa', fontSize: 14, marginRight: 8 }}>{loc.wallets.select_wallet.toLowerCase()}</Text>
<Text style={styles.walletSelectText}>{loc.wallets.select_wallet.toLowerCase()}</Text>
<Icon name="angle-right" size={18} type="font-awesome" color="#9aa0aa" />
</TouchableOpacity>
)}
<View style={{ flexDirection: 'row', alignItems: 'center', marginVertical: 4 }}>
<View style={styles.walletWrap}>
<TouchableOpacity
style={{ flexDirection: 'row', alignItems: 'center' }}
style={styles.walletWrapTouch}
onPress={() =>
this.props.navigation.navigate('SelectWallet', { onWalletSelect: this.onWalletSelect, chainType: Chain.OFFCHAIN })
}
>
<Text style={{ color: '#0c2550', fontSize: 14 }}>{this.state.fromWallet.getLabel()}</Text>
<Text style={{ color: '#0c2550', fontSize: 14, fontWeight: '600', marginLeft: 4, marginRight: 4 }}>
<Text style={styles.walletWrapLabel}>{this.state.fromWallet.getLabel()}</Text>
<Text style={styles.walletWrapBalance}>
{loc.formatBalanceWithoutSuffix(this.state.fromWallet.getBalance(), BitcoinUnit.SATS, false)}
</Text>
<Text style={{ color: '#0c2550', fontSize: 11, fontWeight: '600', textAlignVertical: 'bottom', marginTop: 2 }}>
{BitcoinUnit.SATS}
</Text>
<Text style={styles.walletWrapSats}>{BitcoinUnit.SATS}</Text>
</TouchableOpacity>
</View>
</View>
@ -256,11 +326,11 @@ export default class ScanLndInvoice extends React.Component {
return <BlueLoading />;
}
return (
<SafeBlueArea forceInset={{ horizontal: 'always' }} style={{ flex: 1 }}>
<View style={{ flex: 1 }}>
<ScrollView contentContainerStyle={{ flex: 1, justifyContent: 'space-between' }}>
<SafeBlueArea forceInset={{ horizontal: 'always' }} style={styles.root}>
<View style={styles.root}>
<ScrollView contentContainerStyle={styles.scroll}>
<KeyboardAvoidingView enabled behavior="position" keyboardVerticalOffset={20}>
<View style={{ marginTop: 60 }}>
<View style={styles.scrollMargin}>
<BlueBitcoinAmount
pointerEvents={this.state.isAmountInitiallyEmpty ? 'auto' : 'none'}
isLoading={this.state.isLoading}
@ -292,22 +362,12 @@ export default class ScanLndInvoice extends React.Component {
inputAccessoryViewID={BlueDismissKeyboardInputAccessory.InputAccessoryViewID}
launchedBy={this.props.navigation.state.routeName}
/>
<View
style={{
flexDirection: 'row',
marginHorizontal: 20,
alignItems: 'center',
marginVertical: 0,
borderRadius: 4,
}}
>
<Text numberOfLines={0} style={{ color: '#81868e', fontWeight: '500', fontSize: 14 }}>
<View style={styles.description}>
<Text numberOfLines={0} style={styles.descriptionText}>
{this.state.hasOwnProperty('decoded') && this.state.decoded !== undefined ? this.state.decoded.description : ''}
</Text>
</View>
{this.state.expiresIn !== undefined && (
<Text style={{ color: '#81868e', fontSize: 12, left: 20, top: 10 }}>Expires in: {this.state.expiresIn}</Text>
)}
{this.state.expiresIn !== undefined && <Text style={styles.expiresIn}>Expires in: {this.state.expiresIn}</Text>}
<BlueCard>
{this.state.isLoading ? (

View file

@ -1,6 +1,6 @@
/* global alert */
import React, { Component } from 'react';
import { ScrollView } from 'react-native';
import { ScrollView, StyleSheet } from 'react-native';
import { BlueLoading, BlueButton, SafeBlueArea, BlueCard, BlueText, BlueNavigationStyle, BlueSpacing20 } from '../BlueComponents';
import PropTypes from 'prop-types';
import ReactNativeHapticFeedback from 'react-native-haptic-feedback';
@ -10,6 +10,12 @@ let prompt = require('../prompt');
let EV = require('../events');
let loc = require('../loc');
const styles = StyleSheet.create({
root: {
flex: 1,
},
});
export default class PlausibleDeniability extends Component {
static navigationOptions = {
...BlueNavigationStyle(),
@ -35,7 +41,7 @@ export default class PlausibleDeniability extends Component {
}
return (
<SafeBlueArea forceInset={{ horizontal: 'always' }} style={{ flex: 1 }}>
<SafeBlueArea forceInset={{ horizontal: 'always' }} style={styles.root}>
<BlueCard>
<ScrollView maxHeight={450}>
<BlueText>{loc.plausibledeniability.help}</BlueText>

View file

@ -133,28 +133,13 @@ const ReceiveDetails = () => {
<KeyboardAvoidingView behavior={Platform.OS === 'ios' ? 'position' : null}>
<View style={styles.modalContent}>
<BlueBitcoinAmount amount={customAmount || ''} onChangeText={setCustomAmount} />
<View
style={{
flexDirection: 'row',
borderColor: '#d2d2d2',
borderBottomColor: '#d2d2d2',
borderWidth: 1.0,
borderBottomWidth: 0.5,
backgroundColor: '#f5f5f5',
minHeight: 44,
height: 44,
marginHorizontal: 20,
alignItems: 'center',
marginVertical: 8,
borderRadius: 4,
}}
>
<View style={styles.customAmount}>
<TextInput
onChangeText={setCustomLabel}
placeholder={loc.receive.details.label}
value={customLabel || ''}
numberOfLines={1}
style={{ flex: 1, marginHorizontal: 8, minHeight: 33 }}
style={styles.customAmountText}
/>
</View>
<BlueSpacing20 />
@ -187,7 +172,7 @@ const ReceiveDetails = () => {
};
return (
<SafeBlueArea style={{ flex: 1 }}>
<SafeBlueArea style={styles.root}>
{isHandOffUseEnabled && address !== undefined && (
<Handoff
title={`Bitcoin Transaction ${address}`}
@ -195,23 +180,20 @@ const ReceiveDetails = () => {
url={`https://blockstream.info/address/${address}`}
/>
)}
<ScrollView contentContainerStyle={{ justifyContent: 'space-between' }}>
<View style={{ marginTop: 32, alignItems: 'center', paddingHorizontal: 16 }}>
<ScrollView contentContainerStyle={styles.scroll}>
<View style={styles.scrollBody}>
{isCustom && (
<>
<BlueText
style={{ color: '#0c2550', fontWeight: '600', fontSize: 36, textAlign: 'center', paddingBottom: 24 }}
numberOfLines={1}
>
<BlueText style={styles.amount} numberOfLines={1}>
{customAmount} {BitcoinUnit.BTC}
</BlueText>
<BlueText style={{ color: '#0c2550', fontWeight: '600', textAlign: 'center', paddingBottom: 24 }} numberOfLines={1}>
<BlueText style={styles.label} numberOfLines={1}>
{customLabel}
</BlueText>
</>
)}
{bip21encoded === undefined ? (
<View style={{ alignItems: 'center', width: 300, height: 300 }}>
<View style={styles.loading}>
<BlueLoading />
</View>
) : (
@ -228,7 +210,7 @@ const ReceiveDetails = () => {
)}
<BlueCopyTextToClipboard text={isCustom ? bip21encoded : address} />
</View>
<View style={{ alignItems: 'center', alignContent: 'flex-end', marginBottom: 24 }}>
<View style={styles.share}>
<BlueButtonLink title={loc.receive.details.setAmount} onPress={showCustomAmountModal} />
<View>
<BlueButton
@ -272,4 +254,57 @@ const styles = StyleSheet.create({
justifyContent: 'flex-end',
margin: 0,
},
customAmount: {
flexDirection: 'row',
borderColor: '#d2d2d2',
borderBottomColor: '#d2d2d2',
borderWidth: 1.0,
borderBottomWidth: 0.5,
backgroundColor: '#f5f5f5',
minHeight: 44,
height: 44,
marginHorizontal: 20,
alignItems: 'center',
marginVertical: 8,
borderRadius: 4,
},
customAmountText: {
flex: 1,
marginHorizontal: 8,
minHeight: 33,
},
root: {
flex: 1,
},
scroll: {
justifyContent: 'space-between',
},
scrollBody: {
marginTop: 32,
alignItems: 'center',
paddingHorizontal: 16,
},
amount: {
color: '#0c2550',
fontWeight: '600',
fontSize: 36,
textAlign: 'center',
paddingBottom: 24,
},
label: {
color: '#0c2550',
fontWeight: '600',
textAlign: 'center',
paddingBottom: 24,
},
loading: {
alignItems: 'center',
width: 300,
height: 300,
},
share: {
alignItems: 'center',
alignContent: 'flex-end',
marginBottom: 24,
},
});

View file

@ -1,5 +1,5 @@
import React, { Component } from 'react';
import { ScrollView, View } from 'react-native';
import { ScrollView, View, StyleSheet } from 'react-native';
import { BlueLoading, BlueSpacing20, SafeBlueArea, BlueCard, BlueText, BlueNavigationStyle } from '../BlueComponents';
import PropTypes from 'prop-types';
import { SegwitP2SHWallet, LegacyWallet, HDSegwitP2SHWallet, HDSegwitBech32Wallet } from '../class';
@ -8,6 +8,15 @@ const BlueCrypto = require('react-native-blue-crypto');
let encryption = require('../encryption');
let BlueElectrum = require('../BlueElectrum');
const styles = StyleSheet.create({
root: {
flex: 1,
},
center: {
alignItems: 'center',
},
});
export default class Selftest extends Component {
static navigationOptions = () => ({
...BlueNavigationStyle(),
@ -208,7 +217,7 @@ export default class Selftest extends Component {
}
return (
<SafeBlueArea forceInset={{ horizontal: 'always' }} style={{ flex: 1 }}>
<SafeBlueArea forceInset={{ horizontal: 'always' }} style={styles.root}>
<BlueCard>
<ScrollView>
<BlueSpacing20 />
@ -216,7 +225,7 @@ export default class Selftest extends Component {
{(() => {
if (this.state.isOk) {
return (
<View style={{ alignItems: 'center' }}>
<View style={styles.center}>
<BlueText testID="SelfTestOk" h4>
OK
</BlueText>
@ -224,7 +233,7 @@ export default class Selftest extends Component {
);
} else {
return (
<View style={{ alignItems: 'center' }}>
<View style={styles.center}>
<BlueText h4 numberOfLines={0}>
{this.state.errorMessage}
</BlueText>

View file

@ -1,6 +1,6 @@
/* global alert */
import React, { useState } from 'react';
import { Image, View, TouchableOpacity, Platform } from 'react-native';
import { Image, View, TouchableOpacity, Platform, StyleSheet } from 'react-native';
import { RNCamera } from 'react-native-camera';
import { Icon } from 'react-native-elements';
import ImagePicker from 'react-native-image-picker';
@ -11,6 +11,51 @@ import RNFS from 'react-native-fs';
const LocalQRCode = require('@remobile/react-native-qrcode-local-image');
const createHash = require('create-hash');
const styles = StyleSheet.create({
root: {
flex: 1,
backgroundColor: '#000000',
},
rnCamera: {
flex: 1,
justifyContent: 'space-between',
backgroundColor: '#000000',
},
closeTouch: {
width: 40,
height: 40,
backgroundColor: 'rgba(0,0,0,0.4)',
justifyContent: 'center',
borderRadius: 20,
position: 'absolute',
right: 16,
top: 44,
},
closeImage: {
alignSelf: 'center',
},
imagePickerTouch: {
width: 40,
height: 40,
backgroundColor: 'rgba(0,0,0,0.4)',
justifyContent: 'center',
borderRadius: 20,
position: 'absolute',
left: 24,
bottom: 48,
},
filePickerTouch: {
width: 40,
height: 40,
backgroundColor: 'rgba(0,0,0,0.4)',
justifyContent: 'center',
borderRadius: 20,
position: 'absolute',
left: 96,
bottom: 48,
},
});
const ScanQRCode = ({
showCloseButton = true,
// eslint-disable-next-line react-hooks/rules-of-hooks
@ -80,7 +125,7 @@ const ScanQRCode = ({
};
return (
<View style={{ flex: 1, backgroundColor: '#000000' }}>
<View style={styles.root}>
{!isLoading && (
<RNCamera
captureAudio={false}
@ -90,39 +135,18 @@ const ScanQRCode = ({
buttonPositive: 'OK',
buttonNegative: 'Cancel',
}}
style={{ flex: 1, justifyContent: 'space-between', backgroundColor: '#000000' }}
style={styles.rnCamera}
onBarCodeRead={onBarCodeRead}
barCodeTypes={[RNCamera.Constants.BarCodeType.qr]}
/>
)}
{showCloseButton && (
<TouchableOpacity
style={{
width: 40,
height: 40,
backgroundColor: 'rgba(0,0,0,0.4)',
justifyContent: 'center',
borderRadius: 20,
position: 'absolute',
right: 16,
top: 44,
}}
onPress={() => navigate(launchedBy)}
>
<Image style={{ alignSelf: 'center' }} source={require('../../img/close-white.png')} />
<TouchableOpacity style={styles.closeTouch} onPress={() => navigate(launchedBy)}>
<Image style={styles.closeImage} source={require('../../img/close-white.png')} />
</TouchableOpacity>
)}
<TouchableOpacity
style={{
width: 40,
height: 40,
backgroundColor: 'rgba(0,0,0,0.4)',
justifyContent: 'center',
borderRadius: 20,
position: 'absolute',
left: 24,
bottom: 48,
}}
style={styles.imagePickerTouch}
onPress={() => {
if (!isLoading) {
setIsLoading(true);
@ -152,19 +176,7 @@ const ScanQRCode = ({
<Icon name="image" type="font-awesome" color="#ffffff" />
</TouchableOpacity>
{showFileImportButton && (
<TouchableOpacity
style={{
width: 40,
height: 40,
backgroundColor: 'rgba(0,0,0,0.4)',
justifyContent: 'center',
borderRadius: 20,
position: 'absolute',
left: 96,
bottom: 48,
}}
onPress={showFilePicker}
>
<TouchableOpacity style={styles.filePickerTouch} onPress={showFilePicker}>
<Icon name="file-import" type="material-community" color="#ffffff" />
</TouchableOpacity>
)}

View file

@ -60,19 +60,7 @@ export default function Broadcast() {
{BROADCAST_RESULT.pending === broadcastResult && <ActivityIndicator size="small" />}
</View>
<TextInput
style={{
flex: 1,
borderColor: '#ebebeb',
backgroundColor: '#d2f8d6',
borderRadius: 4,
marginTop: 20,
color: '#37c0a1',
fontWeight: '500',
fontSize: 14,
paddingHorizontal: 16,
paddingBottom: 16,
paddingTop: 16,
}}
style={styles.text}
maxHeight={100}
minHeight={100}
maxWidth={'100%'}
@ -134,6 +122,19 @@ const styles = StyleSheet.create({
height: 30,
maxHeight: 30,
},
text: {
flex: 1,
borderColor: '#ebebeb',
backgroundColor: '#d2f8d6',
borderRadius: 4,
marginTop: 20,
color: '#37c0a1',
fontWeight: '500',
fontSize: 14,
paddingHorizontal: 16,
paddingBottom: 16,
paddingTop: 16,
},
});
function SuccessScreen({ tx }) {

View file

@ -105,7 +105,9 @@ export default class Confirm extends Component {
this.setState({ isLoading: false });
}
} catch (error) {
ReactNativeHapticFeedback.trigger('notificationError', { ignoreAndroidSystemSettings: false });
ReactNativeHapticFeedback.trigger('notificationError', {
ignoreAndroidSystemSettings: false,
});
this.setState({ isLoading: false });
alert(error.message);
}
@ -115,38 +117,20 @@ export default class Confirm extends Component {
_renderItem = ({ index, item }) => {
return (
<>
<View style={{ flexDirection: 'row', justifyContent: 'center' }}>
<Text
testID={'TransactionValue'}
style={{
color: '#0f5cc0',
fontSize: 36,
fontWeight: '600',
}}
>
<View style={styles.valueWrap}>
<Text testID={'TransactionValue'} style={styles.valueValue}>
{!item.value || item.value === BitcoinUnit.MAX
? currency.satoshiToBTC(this.state.fromWallet.getBalance() - this.state.feeSatoshi)
: item.amount || currency.satoshiToBTC(item.value)}
</Text>
<Text
style={{
color: '#0f5cc0',
fontSize: 16,
marginHorizontal: 4,
paddingBottom: 6,
fontWeight: '600',
alignSelf: 'flex-end',
}}
>
{' ' + BitcoinUnit.BTC}
</Text>
<Text style={styles.valueUnit}>{' ' + BitcoinUnit.BTC}</Text>
</View>
<BlueCard>
<Text style={styles.transactionDetailsTitle}>{loc.send.create.to}</Text>
<Text style={styles.transactionDetailsSubtitle}>{item.address}</Text>
</BlueCard>
{this.state.recipients.length > 1 && (
<BlueText style={{ alignSelf: 'flex-end', marginRight: 18, marginVertical: 8 }}>
<BlueText style={styles.valueOf}>
{index + 1} of {this.state.recipients.length}
</BlueText>
)}
@ -155,13 +139,13 @@ export default class Confirm extends Component {
};
renderSeparator = () => {
return <View style={{ backgroundColor: BlueApp.settings.inputBorderColor, height: 0.5, margin: 16 }} />;
return <View style={styles.separator} />;
};
render() {
return (
<SafeBlueArea style={{ flex: 1, paddingTop: 19 }}>
<View style={{ marginTop: 16, alignItems: 'center', justifyContent: 'space-between' }}>
<SafeBlueArea style={styles.root}>
<View style={styles.rootWrap}>
<FlatList
scrollEnabled={this.state.recipients.length > 1}
extraData={this.state.recipients}
@ -169,20 +153,11 @@ export default class Confirm extends Component {
renderItem={this._renderItem}
keyExtractor={(_item, index) => `${index}`}
ItemSeparatorComponent={this.renderSeparator}
style={{ maxHeight: '55%' }}
style={styles.flat}
/>
<View style={{ flexDirection: 'row', justifyContent: 'center', paddingTop: 16, paddingBottom: 16 }}>
<View style={styles.cardContainer}>
<BlueCard>
<Text
style={{
color: '#37c0a1',
fontSize: 14,
marginHorizontal: 4,
paddingBottom: 6,
fontWeight: '500',
alignSelf: 'center',
}}
>
<Text style={styles.cardText}>
{loc.send.create.fee}: {loc.formatBalance(this.state.feeSatoshi, BitcoinUnit.BTC)} (
{currency.satoshiToLocalCurrency(this.state.feeSatoshi)})
</Text>
@ -195,7 +170,7 @@ export default class Confirm extends Component {
<TouchableOpacity
testID={'TransactionDetailsButton'}
style={{ marginVertical: 24 }}
style={styles.txDetails}
onPress={async () => {
if (this.isBiometricUseCapableAndEnabled) {
if (!(await Biometric.unlockWithBiometrics())) {
@ -214,9 +189,7 @@ export default class Confirm extends Component {
});
}}
>
<Text style={{ color: '#0c2550', fontSize: 15, fontWeight: '500', alignSelf: 'center' }}>
{loc.transactions.details.transaction_details}
</Text>
<Text style={styles.txText}>{loc.transactions.details.transaction_details}</Text>
</TouchableOpacity>
</BlueCard>
</View>
@ -239,6 +212,68 @@ const styles = StyleSheet.create({
fontSize: 15,
marginBottom: 20,
},
valueWrap: {
flexDirection: 'row',
justifyContent: 'center',
},
valueValue: {
color: '#0f5cc0',
fontSize: 36,
fontWeight: '600',
},
valueUnit: {
color: '#0f5cc0',
fontSize: 16,
marginHorizontal: 4,
paddingBottom: 6,
fontWeight: '600',
alignSelf: 'flex-end',
},
valueOf: {
alignSelf: 'flex-end',
marginRight: 18,
marginVertical: 8,
},
separator: {
backgroundColor: BlueApp.settings.inputBorderColor,
height: 0.5,
margin: 16,
},
root: {
flex: 1,
paddingTop: 19,
},
rootWrap: {
marginTop: 16,
alignItems: 'center',
justifyContent: 'space-between',
},
flat: {
maxHeight: '55%',
},
cardContainer: {
flexDirection: 'row',
justifyContent: 'center',
paddingTop: 16,
paddingBottom: 16,
},
cardText: {
color: '#37c0a1',
fontSize: 14,
marginHorizontal: 4,
paddingBottom: 6,
fontWeight: '500',
alignSelf: 'center',
},
txDetails: {
marginVertical: 24,
},
txText: {
color: '#0c2550',
fontSize: 15,
fontWeight: '500',
alignSelf: 'center',
},
});
Confirm.propTypes = {

View file

@ -32,7 +32,7 @@ export default class SendCreate extends Component {
...BlueNavigationStyle,
title: loc.send.create.details,
headerRight: navigation.state.params.exportTXN ? (
<TouchableOpacity style={{ marginRight: 16 }} onPress={navigation.state.params.exportTXN}>
<TouchableOpacity style={styles.export} onPress={navigation.state.params.exportTXN}>
<Icon size={22} name="share-alternative" type="entypo" color={BlueApp.settings.foregroundColor} />
</TouchableOpacity>
) : null,
@ -110,7 +110,7 @@ export default class SendCreate extends Component {
{BitcoinUnit.BTC}
</Text>
{this.state.recipients.length > 1 && (
<BlueText style={{ alignSelf: 'flex-end' }}>
<BlueText style={styles.itemOf}>
{index + 1} of {this.state.recipients.length}
</BlueText>
)}
@ -120,41 +120,23 @@ export default class SendCreate extends Component {
};
renderSeparator = () => {
return <View style={{ backgroundColor: BlueApp.settings.inputBorderColor, height: 0.5, marginVertical: 16 }} />;
return <View style={styles.separator} />;
};
render() {
return (
<SafeBlueArea style={{ flex: 1, paddingTop: 19 }}>
<SafeBlueArea style={styles.root}>
<TouchableWithoutFeedback onPress={Keyboard.dismiss} accessible={false}>
<ScrollView>
<BlueCard style={{ alignItems: 'center', flex: 1 }}>
<BlueText style={{ color: '#0c2550', fontWeight: '500' }}>{loc.send.create.this_is_hex}</BlueText>
<TextInput
testID={'TxhexInput'}
style={{
borderColor: '#ebebeb',
backgroundColor: '#d2f8d6',
borderRadius: 4,
marginTop: 20,
color: '#37c0a1',
fontWeight: '500',
fontSize: 14,
paddingHorizontal: 16,
paddingBottom: 16,
paddingTop: 16,
}}
height={72}
multiline
editable
value={this.state.tx}
/>
<BlueCard style={styles.card}>
<BlueText style={styles.cardText}>{loc.send.create.this_is_hex}</BlueText>
<TextInput testID={'TxhexInput'} style={styles.cardTx} height={72} multiline editable value={this.state.tx} />
<TouchableOpacity style={{ marginVertical: 24 }} onPress={() => Clipboard.setString(this.state.tx)}>
<Text style={{ color: '#9aa0aa', fontSize: 15, fontWeight: '500', alignSelf: 'center' }}>Copy and broadcast later</Text>
<TouchableOpacity style={styles.actionTouch} onPress={() => Clipboard.setString(this.state.tx)}>
<Text style={styles.actionText}>Copy and broadcast later</Text>
</TouchableOpacity>
<TouchableOpacity style={{ marginVertical: 24 }} onPress={() => Linking.openURL('https://coinb.in/?verify=' + this.state.tx)}>
<Text style={{ color: '#9aa0aa', fontSize: 15, fontWeight: '500', alignSelf: 'center' }}>Verify on coinb.in</Text>
<TouchableOpacity style={styles.actionTouch} onPress={() => Linking.openURL('https://coinb.in/?verify=' + this.state.tx)}>
<Text style={styles.actionText}>Verify on coinb.in</Text>
</TouchableOpacity>
</BlueCard>
<BlueCard>
@ -203,6 +185,50 @@ const styles = StyleSheet.create({
fontSize: 15,
marginBottom: 20,
},
export: {
marginRight: 16,
},
itemOf: {
alignSelf: 'flex-end',
},
separator: {
backgroundColor: BlueApp.settings.inputBorderColor,
height: 0.5,
marginVertical: 16,
},
root: {
flex: 1,
paddingTop: 19,
},
card: {
alignItems: 'center',
flex: 1,
},
cardText: {
color: '#0c2550',
fontWeight: '500',
},
cardTx: {
borderColor: '#ebebeb',
backgroundColor: '#d2f8d6',
borderRadius: 4,
marginTop: 20,
color: '#37c0a1',
fontWeight: '500',
fontSize: 14,
paddingHorizontal: 16,
paddingBottom: 16,
paddingTop: 16,
},
actionTouch: {
marginVertical: 24,
},
actionText: {
color: '#9aa0aa',
fontSize: 15,
fontWeight: '500',
alignSelf: 'center',
},
});
SendCreate.propTypes = {

View file

@ -49,6 +49,174 @@ let loc = require('../../loc');
const btcAddressRx = /^[a-zA-Z0-9]{26,35}$/;
const styles = StyleSheet.create({
loading: {
flex: 1,
paddingTop: 20,
},
root: {
flex: 1,
justifyContent: 'space-between',
},
scrollViewContent: {
flexWrap: 'wrap',
flexDirection: 'row',
},
modalContent: {
backgroundColor: '#FFFFFF',
padding: 22,
justifyContent: 'center',
alignItems: 'center',
borderTopLeftRadius: 16,
borderTopRightRadius: 16,
borderColor: 'rgba(0, 0, 0, 0.1)',
minHeight: 200,
height: 200,
},
advancedTransactionOptionsModalContent: {
backgroundColor: '#FFFFFF',
padding: 22,
borderTopLeftRadius: 16,
borderTopRightRadius: 16,
borderColor: 'rgba(0, 0, 0, 0.1)',
minHeight: 130,
},
bottomModal: {
justifyContent: 'flex-end',
margin: 0,
},
feeSliderInput: {
backgroundColor: '#d2f8d6',
minWidth: 127,
height: 60,
borderRadius: 8,
flexDirection: 'row',
justifyContent: 'center',
paddingHorizontal: 8,
},
feeSliderText: {
fontWeight: '600',
color: '#37c0a1',
marginBottom: 0,
marginRight: 4,
textAlign: 'right',
fontSize: 36,
},
feeSliderUnit: {
fontWeight: '600',
color: '#37c0a1',
paddingRight: 4,
textAlign: 'left',
fontSize: 16,
alignSelf: 'flex-end',
marginBottom: 14,
},
sliderContainer: {
flex: 1,
marginTop: 32,
minWidth: 240,
width: 240,
},
slider: {
flex: 1,
},
sliderLabels: {
flex: 1,
flexDirection: 'row',
justifyContent: 'space-between',
marginTop: 14,
},
sliderLabel: {
fontWeight: '500',
fontSize: 13,
color: '#37c0a1',
},
createButton: {
marginHorizontal: 56,
marginVertical: 16,
alignContent: 'center',
backgroundColor: '#FFFFFF',
minHeight: 44,
},
select: {
marginBottom: 24,
alignItems: 'center',
},
selectTouch: {
flexDirection: 'row',
alignItems: 'center',
},
selectText: {
color: '#9aa0aa',
fontSize: 14,
marginRight: 8,
},
selectWrap: {
flexDirection: 'row',
alignItems: 'center',
marginVertical: 4,
},
selectLabel: {
color: '#0c2550',
fontSize: 14,
},
of: {
alignSelf: 'flex-end',
marginRight: 18,
marginVertical: 8,
},
memo: {
flexDirection: 'row',
borderColor: '#d2d2d2',
borderBottomColor: '#d2d2d2',
borderWidth: 1,
borderBottomWidth: 0.5,
backgroundColor: '#f5f5f5',
minHeight: 44,
height: 44,
marginHorizontal: 20,
alignItems: 'center',
marginVertical: 8,
borderRadius: 4,
},
memoText: {
flex: 1,
marginHorizontal: 8,
minHeight: 33,
},
fee: {
flexDirection: 'row',
marginHorizontal: 20,
justifyContent: 'space-between',
alignItems: 'center',
},
feeLabel: {
color: '#81868e',
fontSize: 14,
},
feeRow: {
backgroundColor: '#d2f8d6',
minWidth: 40,
height: 25,
borderRadius: 4,
justifyContent: 'space-between',
flexDirection: 'row',
alignItems: 'center',
paddingHorizontal: 10,
},
feeValue: {
color: '#37c0a1',
marginBottom: 0,
marginRight: 4,
textAlign: 'right',
},
feeUnit: {
color: '#37c0a1',
paddingRight: 4,
textAlign: 'left',
},
});
export default class SendDetails extends Component {
static navigationOptions = ({ navigation }) => ({
...BlueCreateTxNavigationStyle(
@ -527,7 +695,7 @@ export default class SendDetails extends Component {
>
<KeyboardAvoidingView behavior={Platform.OS === 'ios' ? 'position' : null}>
<View style={styles.modalContent}>
<TouchableOpacity style={styles.satoshisTextInput} onPress={() => this.textInput.focus()}>
<TouchableOpacity style={styles.feeSliderInput} onPress={() => this.textInput.focus()}>
<TextInput
keyboardType="numeric"
ref={ref => {
@ -547,25 +715,13 @@ export default class SendDetails extends Component {
editable={!this.state.isLoading}
placeholderTextColor="#37c0a1"
placeholder={this.state.networkTransactionFees.mediumFee.toString()}
style={{ fontWeight: '600', color: '#37c0a1', marginBottom: 0, marginRight: 4, textAlign: 'right', fontSize: 36 }}
style={styles.feeSliderText}
inputAccessoryViewID={BlueDismissKeyboardInputAccessory.InputAccessoryViewID}
/>
<Text
style={{
fontWeight: '600',
color: '#37c0a1',
paddingRight: 4,
textAlign: 'left',
fontSize: 16,
alignSelf: 'flex-end',
marginBottom: 14,
}}
>
sat/b
</Text>
<Text style={styles.feeSliderUnit}>sat/b</Text>
</TouchableOpacity>
{this.state.networkTransactionFees.fastestFee > 1 && (
<View style={{ flex: 1, marginTop: 32, minWidth: 240, width: 240 }}>
<View style={styles.sliderContainer}>
<Slider
onValueChange={value => this.setState({ feeSliderValue: value.toFixed(0), fee: value.toFixed(0) })}
minimumValue={1}
@ -573,11 +729,11 @@ export default class SendDetails extends Component {
value={Number(this.state.feeSliderValue)}
maximumTrackTintColor="#d8d8d8"
minimumTrackTintColor="#37c0a1"
style={{ flex: 1 }}
style={styles.slider}
/>
<View style={{ flex: 1, flexDirection: 'row', justifyContent: 'space-between', marginTop: 14 }}>
<Text style={{ fontWeight: '500', fontSize: 13, color: '#37c0a1' }}>slow</Text>
<Text style={{ fontWeight: '500', fontSize: 13, color: '#37c0a1' }}>fast</Text>
<View style={styles.sliderLabels}>
<Text style={styles.sliderLabel}>slow</Text>
<Text style={styles.sliderLabel}>fast</Text>
</View>
</View>
)}
@ -720,7 +876,7 @@ export default class SendDetails extends Component {
renderCreateButton = () => {
return (
<View style={{ marginHorizontal: 56, marginVertical: 16, alignContent: 'center', backgroundColor: '#FFFFFF', minHeight: 44 }}>
<View style={styles.createButton}>
{this.state.isLoading ? (
<ActivityIndicator />
) : (
@ -733,26 +889,26 @@ export default class SendDetails extends Component {
renderWalletSelectionButton = () => {
if (this.state.renderWalletSelectionButtonHidden) return;
return (
<View style={{ marginBottom: 24, alignItems: 'center' }}>
<View style={styles.select}>
{!this.state.isLoading && (
<TouchableOpacity
style={{ flexDirection: 'row', alignItems: 'center' }}
style={styles.selectTouch}
onPress={() =>
this.props.navigation.navigate('SelectWallet', { onWalletSelect: this.onWalletSelect, chainType: Chain.ONCHAIN })
}
>
<Text style={{ color: '#9aa0aa', fontSize: 14, marginRight: 8 }}>{loc.wallets.select_wallet.toLowerCase()}</Text>
<Text style={styles.selectText}>{loc.wallets.select_wallet.toLowerCase()}</Text>
<Icon name="angle-right" size={18} type="font-awesome" color="#9aa0aa" />
</TouchableOpacity>
)}
<View style={{ flexDirection: 'row', alignItems: 'center', marginVertical: 4 }}>
<View style={styles.selectWrap}>
<TouchableOpacity
style={{ flexDirection: 'row', alignItems: 'center' }}
style={styles.selectTouch}
onPress={() =>
this.props.navigation.navigate('SelectWallet', { onWalletSelect: this.onWalletSelect, chainType: Chain.ONCHAIN })
}
>
<Text style={{ color: '#0c2550', fontSize: 14 }}>{this.state.fromWallet.getLabel()}</Text>
<Text style={styles.selectLabel}>{this.state.fromWallet.getLabel()}</Text>
</TouchableOpacity>
</View>
</View>
@ -784,7 +940,13 @@ export default class SendDetails extends Component {
let rows = [];
for (let [index, item] of this.state.addresses.entries()) {
rows.push(
<View style={{ minWidth: width, maxWidth: width, width: width }}>
<View
style={{
minWidth: width,
maxWidth: width,
width: width,
}}
>
<BlueBitcoinAmount
isLoading={this.state.isLoading}
amount={item.amount ? item.amount.toString() : null}
@ -825,7 +987,7 @@ export default class SendDetails extends Component {
launchedBy={this.props.navigation.state.routeName}
/>
{this.state.addresses.length > 1 && (
<BlueText style={{ alignSelf: 'flex-end', marginRight: 18, marginVertical: 8 }}>
<BlueText style={styles.of}>
{index + 1} of {this.state.addresses.length}
</BlueText>
)}
@ -862,20 +1024,20 @@ export default class SendDetails extends Component {
render() {
if (this.state.isLoading || typeof this.state.fromWallet === 'undefined') {
return (
<View style={{ flex: 1, paddingTop: 20 }}>
<View style={styles.loading}>
<BlueLoading />
</View>
);
}
return (
<TouchableWithoutFeedback onPress={Keyboard.dismiss} accessible={false}>
<View style={{ flex: 1, justifyContent: 'space-between' }}>
<View style={styles.root}>
<View>
<KeyboardAvoidingView behavior="position">
<ScrollView
pagingEnabled
horizontal
contentContainerStyle={{ flexWrap: 'wrap', flexDirection: 'row' }}
contentContainerStyle={styles.scrollViewContent}
ref={ref => (this.scrollView = ref)}
onContentSizeChange={() => this.scrollView.scrollToEnd()}
onLayout={() => this.scrollView.scrollToEnd()}
@ -885,29 +1047,13 @@ export default class SendDetails extends Component {
>
{this.renderBitcoinTransactionInfoFields()}
</ScrollView>
<View
hide={!this.state.showMemoRow}
style={{
flexDirection: 'row',
borderColor: '#d2d2d2',
borderBottomColor: '#d2d2d2',
borderWidth: 1.0,
borderBottomWidth: 0.5,
backgroundColor: '#f5f5f5',
minHeight: 44,
height: 44,
marginHorizontal: 20,
alignItems: 'center',
marginVertical: 8,
borderRadius: 4,
}}
>
<View hide={!this.state.showMemoRow} style={styles.memo}>
<TextInput
onChangeText={text => this.setState({ memo: text })}
placeholder={loc.send.details.note_placeholder}
value={this.state.memo}
numberOfLines={1}
style={{ flex: 1, marginHorizontal: 8, minHeight: 33 }}
style={styles.memoText}
editable={!this.state.isLoading}
onSubmitEditing={Keyboard.dismiss}
inputAccessoryViewID={BlueDismissKeyboardInputAccessory.InputAccessoryViewID}
@ -916,23 +1062,12 @@ export default class SendDetails extends Component {
<TouchableOpacity
onPress={() => this.setState({ isFeeSelectionModalVisible: true })}
disabled={this.state.isLoading}
style={{ flexDirection: 'row', marginHorizontal: 20, justifyContent: 'space-between', alignItems: 'center' }}
style={styles.fee}
>
<Text style={{ color: '#81868e', fontSize: 14 }}>Fee</Text>
<View
style={{
backgroundColor: '#d2f8d6',
minWidth: 40,
height: 25,
borderRadius: 4,
justifyContent: 'space-between',
flexDirection: 'row',
alignItems: 'center',
paddingHorizontal: 10,
}}
>
<Text style={{ color: '#37c0a1', marginBottom: 0, marginRight: 4, textAlign: 'right' }}>{this.state.fee}</Text>
<Text style={{ color: '#37c0a1', paddingRight: 4, textAlign: 'left' }}>sat/b</Text>
<Text style={styles.feeLabel}>Fee</Text>
<View style={styles.feeRow}>
<Text style={styles.feeValue}>{this.state.fee}</Text>
<Text style={styles.feeUnit}>sat/b</Text>
</View>
</TouchableOpacity>
{this.renderCreateButton()}
@ -955,41 +1090,6 @@ export default class SendDetails extends Component {
}
}
const styles = StyleSheet.create({
modalContent: {
backgroundColor: '#FFFFFF',
padding: 22,
justifyContent: 'center',
alignItems: 'center',
borderTopLeftRadius: 16,
borderTopRightRadius: 16,
borderColor: 'rgba(0, 0, 0, 0.1)',
minHeight: 200,
height: 200,
},
advancedTransactionOptionsModalContent: {
backgroundColor: '#FFFFFF',
padding: 22,
borderTopLeftRadius: 16,
borderTopRightRadius: 16,
borderColor: 'rgba(0, 0, 0, 0.1)',
minHeight: 130,
},
bottomModal: {
justifyContent: 'flex-end',
margin: 0,
},
satoshisTextInput: {
backgroundColor: '#d2f8d6',
minWidth: 127,
height: 60,
borderRadius: 8,
flexDirection: 'row',
justifyContent: 'center',
paddingHorizontal: 8,
},
});
SendDetails.propTypes = {
navigation: PropTypes.shape({
pop: PropTypes.func,

View file

@ -12,6 +12,7 @@ import {
Linking,
Platform,
PermissionsAndroid,
StyleSheet,
} from 'react-native';
import QRCode from 'react-native-qrcode-svg';
import { Text } from 'react-native-elements';
@ -39,6 +40,80 @@ const BlueApp = require('../../BlueApp');
const bitcoin = require('bitcoinjs-lib');
const { height, width } = Dimensions.get('window');
const styles = StyleSheet.create({
root: {
flex: 1,
},
scrollViewContent: {
flexGrow: 1,
justifyContent: 'space-between',
},
container: {
flexDirection: 'row',
justifyContent: 'center',
paddingTop: 16,
paddingBottom: 16,
},
rootCamera: {
flex: 1,
justifyContent: 'space-between',
},
rootPadding: {
flex: 1,
paddingTop: 20,
},
closeCamera: {
width: 40,
height: 40,
backgroundColor: 'rgba(0,0,0,0.4)',
justifyContent: 'center',
borderRadius: 20,
position: 'absolute',
right: 16,
top: 64,
},
closeCameraImage: {
alignSelf: 'center',
},
blueBigCheckmark: {
marginTop: 143,
marginBottom: 53,
},
hexWrap: {
alignItems: 'center',
flex: 1,
},
hexLabel: {
color: '#0c2550',
fontWeight: '500',
},
hexInput: {
borderColor: '#ebebeb',
backgroundColor: '#d2f8d6',
borderRadius: 4,
marginTop: 20,
color: '#37c0a1',
fontWeight: '500',
fontSize: 14,
paddingHorizontal: 16,
paddingBottom: 16,
paddingTop: 16,
},
hexTouch: {
marginVertical: 24,
},
hexText: {
color: '#9aa0aa',
fontSize: 15,
fontWeight: '500',
alignSelf: 'center',
},
copyToClipboard: {
justifyContent: 'center',
alignItems: 'center',
},
});
export default class PsbtWithHardwareWallet extends Component {
static navigationOptions = () => ({
...BlueNavigationStyle(null, false),
@ -144,7 +219,7 @@ export default class PsbtWithHardwareWallet extends Component {
_renderScanner() {
return (
<SafeBlueArea style={{ flex: 1 }}>
<SafeBlueArea style={styles.root}>
<RNCamera
captureAudio={false}
androidCameraPermissionOptions={{
@ -154,24 +229,12 @@ export default class PsbtWithHardwareWallet extends Component {
buttonNegative: 'Cancel',
}}
ref={ref => (this.cameraRef = ref)}
style={{ flex: 1, justifyContent: 'space-between' }}
style={styles.rootCamera}
onBarCodeRead={this.onBarCodeRead}
barCodeTypes={[RNCamera.Constants.BarCodeType.qr]}
/>
<TouchableOpacity
style={{
width: 40,
height: 40,
backgroundColor: 'rgba(0,0,0,0.4)',
justifyContent: 'center',
borderRadius: 20,
position: 'absolute',
right: 16,
top: 64,
}}
onPress={() => this.setState({ renderScanner: false })}
>
<Image style={{ alignSelf: 'center' }} source={require('../../img/close-white.png')} />
<TouchableOpacity style={styles.closeCamera} onPress={() => this.setState({ renderScanner: false })}>
<Image style={styles.closeCameraImage} source={require('../../img/close-white.png')} />
</TouchableOpacity>
</SafeBlueArea>
);
@ -179,8 +242,8 @@ export default class PsbtWithHardwareWallet extends Component {
_renderSuccess() {
return (
<SafeBlueArea style={{ flex: 1 }}>
<BlueBigCheckmark style={{ marginTop: 143, marginBottom: 53 }} />
<SafeBlueArea style={styles.root}>
<BlueBigCheckmark style={styles.blueBigCheckmark} />
<BlueCard>
<BlueButton onPress={this.props.navigation.dismiss} title={loc.send.success.done} />
</BlueCard>
@ -190,33 +253,16 @@ export default class PsbtWithHardwareWallet extends Component {
_renderBroadcastHex() {
return (
<View style={{ flex: 1, paddingTop: 20 }}>
<BlueCard style={{ alignItems: 'center', flex: 1 }}>
<BlueText style={{ color: '#0c2550', fontWeight: '500' }}>{loc.send.create.this_is_hex}</BlueText>
<TextInput
style={{
borderColor: '#ebebeb',
backgroundColor: '#d2f8d6',
borderRadius: 4,
marginTop: 20,
color: '#37c0a1',
fontWeight: '500',
fontSize: 14,
paddingHorizontal: 16,
paddingBottom: 16,
paddingTop: 16,
}}
height={112}
multiline
editable
value={this.state.txhex}
/>
<View style={styles.rootPadding}>
<BlueCard style={styles.hexWrap}>
<BlueText style={styles.hexLabel}>{loc.send.create.this_is_hex}</BlueText>
<TextInput style={styles.hexInput} height={112} multiline editable value={this.state.txhex} />
<TouchableOpacity style={{ marginVertical: 24 }} onPress={() => Clipboard.setString(this.state.txhex)}>
<Text style={{ color: '#9aa0aa', fontSize: 15, fontWeight: '500', alignSelf: 'center' }}>Copy and broadcast later</Text>
<TouchableOpacity style={styles.hexTouch} onPress={() => Clipboard.setString(this.state.txhex)}>
<Text style={styles.hexText}>Copy and broadcast later</Text>
</TouchableOpacity>
<TouchableOpacity style={{ marginVertical: 24 }} onPress={() => Linking.openURL('https://coinb.in/?verify=' + this.state.txhex)}>
<Text style={{ color: '#9aa0aa', fontSize: 15, fontWeight: '500', alignSelf: 'center' }}>Verify on coinb.in</Text>
<TouchableOpacity style={styles.hexTouch} onPress={() => Linking.openURL('https://coinb.in/?verify=' + this.state.txhex)}>
<Text style={styles.hexText}>Verify on coinb.in</Text>
</TouchableOpacity>
<BlueSpacing20 />
<BlueButton onPress={this.broadcast} title={loc.send.confirm.sendNow} />
@ -278,7 +324,7 @@ export default class PsbtWithHardwareWallet extends Component {
render() {
if (this.state.isLoading) {
return (
<View style={{ flex: 1, paddingTop: 20 }}>
<View style={styles.rootPadding}>
<ActivityIndicator />
</View>
);
@ -289,9 +335,9 @@ export default class PsbtWithHardwareWallet extends Component {
if (this.state.txhex) return this._renderBroadcastHex();
return (
<SafeBlueArea style={{ flex: 1 }}>
<ScrollView centerContent contentContainerStyle={{ flexGrow: 1, justifyContent: 'space-between' }}>
<View style={{ flexDirection: 'row', justifyContent: 'center', paddingTop: 16, paddingBottom: 16 }}>
<SafeBlueArea style={styles.root}>
<ScrollView centerContent contentContainerStyle={styles.scrollViewContent}>
<View style={styles.container}>
<BlueCard>
<BlueText testID={'TextHelperForPSBT'}>
This is partially signed bitcoin transaction (PSBT). Please finish signing it with your hardware wallet.
@ -335,7 +381,7 @@ export default class PsbtWithHardwareWallet extends Component {
title={'Export to file'}
/>
<BlueSpacing20 />
<View style={{ justifyContent: 'center', alignItems: 'center' }}>
<View style={styles.copyToClipboard}>
<BlueCopyToClipboardButton
stringToCopy={this.state.isFirstPSBTAlreadyBase64 ? this.state.psbt : this.state.psbt.toBase64()}
displayText={'Copy to Clipboard'}

View file

@ -1,12 +1,60 @@
import React, { Component } from 'react';
import ReactNativeHapticFeedback from 'react-native-haptic-feedback';
import { View } from 'react-native';
import { View, StyleSheet } from 'react-native';
import { Text, Icon } from 'react-native-elements';
import { BlueButton, SafeBlueArea, BlueCard } from '../../BlueComponents';
import { BitcoinUnit } from '../../models/bitcoinUnits';
import PropTypes from 'prop-types';
let loc = require('../../loc');
const styles = StyleSheet.create({
root: {
flex: 1,
paddingTop: 19,
},
amout: {
alignItems: 'center',
flex: 1,
},
view: {
flexDirection: 'row',
justifyContent: 'center',
paddingTop: 76,
paddingBottom: 16,
},
amountValue: {
color: '#0f5cc0',
fontSize: 36,
fontWeight: '600',
},
amountUnit: {
color: '#0f5cc0',
fontSize: 16,
marginHorizontal: 4,
paddingBottom: 6,
fontWeight: '600',
alignSelf: 'flex-end',
},
feeText: {
color: '#37c0a1',
fontSize: 14,
marginHorizontal: 4,
paddingBottom: 6,
fontWeight: '500',
alignSelf: 'center',
},
ready: {
backgroundColor: '#ccddf9',
width: 120,
height: 120,
borderRadius: 60,
alignSelf: 'center',
justifyContent: 'center',
marginTop: 43,
marginBottom: 53,
},
});
export default class Success extends Component {
static navigationOptions = {
header: null,
@ -32,73 +80,24 @@ export default class Success extends Component {
render() {
return (
<SafeBlueArea style={{ flex: 1, paddingTop: 19 }}>
<BlueCard style={{ alignItems: 'center', flex: 1 }}>
<View style={{ flexDirection: 'row', justifyContent: 'center', paddingTop: 76, paddingBottom: 16 }}>
<Text
style={{
color: '#0f5cc0',
fontSize: 36,
fontWeight: '600',
}}
>
{this.state.amount}
</Text>
<Text
style={{
color: '#0f5cc0',
fontSize: 16,
marginHorizontal: 4,
paddingBottom: 6,
fontWeight: '600',
alignSelf: 'flex-end',
}}
>
{' ' + this.state.amountUnit}
</Text>
<SafeBlueArea style={styles.root}>
<BlueCard style={styles.amout}>
<View style={styles.view}>
<Text style={styles.amountValue}>{this.state.amount}</Text>
<Text style={styles.amountUnit}>{' ' + this.state.amountUnit}</Text>
</View>
{this.state.fee > 0 && (
<Text
style={{
color: '#37c0a1',
fontSize: 14,
marginHorizontal: 4,
paddingBottom: 6,
fontWeight: '500',
alignSelf: 'center',
}}
>
<Text style={styles.feeText}>
{loc.send.create.fee}: {this.state.fee} {BitcoinUnit.BTC}
</Text>
)}
{this.state.fee <= 0 && (
<Text
numberOfLines={0}
style={{
color: '#37c0a1',
fontSize: 14,
marginHorizontal: 4,
paddingBottom: 6,
fontWeight: '500',
alignSelf: 'center',
}}
>
<Text numberOfLines={0} style={styles.feeText}>
{this.state.invoiceDescription}
</Text>
)}
</BlueCard>
<View
style={{
backgroundColor: '#ccddf9',
width: 120,
height: 120,
borderRadius: 60,
alignSelf: 'center',
justifyContent: 'center',
marginTop: 43,
marginBottom: 53,
}}
>
<View style={styles.ready}>
<Icon name="check" size={50} type="font-awesome" color="#0f5cc0" />
</View>
<BlueCard>

View file

@ -1,5 +1,5 @@
import React, { useEffect, useState } from 'react';
import { ScrollView, Platform, TouchableWithoutFeedback, TouchableOpacity } from 'react-native';
import { ScrollView, Platform, TouchableWithoutFeedback, TouchableOpacity, StyleSheet } from 'react-native';
import { BlueLoading, BlueText, BlueSpacing20, BlueListItem, SafeBlueArea, BlueNavigationStyle, BlueCard } from '../../BlueComponents';
import PropTypes from 'prop-types';
import { AppStorage } from '../../class';
@ -8,6 +8,12 @@ import HandoffSettings from '../../class/handoff';
let BlueApp: AppStorage = require('../../BlueApp');
let loc = require('../../loc');
const styles = StyleSheet.create({
root: {
flex: 1,
},
});
const GeneralSettings = () => {
const [isLoading, setIsLoading] = useState(true);
const [isAdancedModeEnabled, setIsAdancedModeEnabled] = useState(false);
@ -34,7 +40,7 @@ const GeneralSettings = () => {
return isLoading ? (
<BlueLoading />
) : (
<SafeBlueArea forceInset={{ horizontal: 'always' }} style={{ flex: 1 }}>
<SafeBlueArea forceInset={{ horizontal: 'always' }} style={styles.root}>
<ScrollView>
{BlueApp.getWallets().length > 1 && (
<>

View file

@ -1,9 +1,15 @@
import React, { useEffect, useState } from 'react';
import { ScrollView, TouchableOpacity } from 'react-native';
import { ScrollView, TouchableOpacity, StyleSheet } from 'react-native';
import { BlueNavigationStyle, BlueLoading, SafeBlueArea, BlueListItem } from '../../BlueComponents';
import { useNavigation } from 'react-navigation-hooks';
const loc = require('../../loc');
const styles = StyleSheet.create({
root: {
flex: 1,
},
});
const NetworkSettings = () => {
const [isLoading, setIsLoading] = useState(true);
const { navigate } = useNavigation();
@ -15,7 +21,7 @@ const NetworkSettings = () => {
return isLoading ? (
<BlueLoading />
) : (
<SafeBlueArea forceInset={{ horizontal: 'always' }} style={{ flex: 1 }}>
<SafeBlueArea forceInset={{ horizontal: 'always' }} style={styles.root}>
<ScrollView>
<BlueListItem title={'Electrum server'} component={TouchableOpacity} onPress={() => navigate('ElectrumSettings')} />
<BlueListItem title={loc.settings.lightning_settings} component={TouchableOpacity} onPress={() => navigate('LightningSettings')} />

View file

@ -1,5 +1,5 @@
import React, { useEffect, useState } from 'react';
import { ScrollView, Linking, Dimensions, Image, View, Text } from 'react-native';
import { ScrollView, Linking, Dimensions, Image, View, Text, StyleSheet } from 'react-native';
import { useNavigation } from 'react-navigation-hooks';
import {
BlueTextCentered,
@ -17,6 +17,43 @@ import Rate, { AndroidMarket } from 'react-native-rate';
const { width, height } = Dimensions.get('window');
const loc = require('../../loc/');
const styles = StyleSheet.create({
root: {
flex: 1,
},
center: {
justifyContent: 'center',
alignItems: 'center',
marginTop: 54,
},
logo: {
width: 102,
height: 124,
},
textFree: {
maxWidth: 260,
marginVertical: 24,
color: '#9AA0AA',
fontSize: 15,
textAlign: 'center',
fontWeight: '500',
},
textBackup: {
maxWidth: 260,
marginBottom: 40,
color: '#0C2550',
fontSize: 15,
textAlign: 'center',
fontWeight: '500',
},
buildWith: {
backgroundColor: '#f9f9f9',
padding: 16,
paddingTop: 0,
borderRadius: 8,
},
});
const About = () => {
const [isLoading, setIsLoading] = useState(true);
const { navigate } = useNavigation();
@ -68,23 +105,13 @@ const About = () => {
return isLoading ? (
<BlueLoading />
) : (
<SafeBlueArea style={{ flex: 1 }}>
<SafeBlueArea style={styles.root}>
<ScrollView testID="AboutScrollView">
<BlueCard>
<View style={{ justifyContent: 'center', alignItems: 'center', marginTop: 54 }}>
<Image
source={require('../../img/bluebeast.png')}
style={{
width: 102,
height: 124,
}}
/>
<Text style={{ maxWidth: 260, marginVertical: 24, color: '#9AA0AA', fontSize: 15, textAlign: 'center', fontWeight: '500' }}>
BlueWallet is a free and open source project. Crafted by Bitcoin users.
</Text>
<Text style={{ maxWidth: 260, marginBottom: 40, color: '#0C2550', fontSize: 15, textAlign: 'center', fontWeight: '500' }}>
Always backup your keys!
</Text>
<View style={styles.center}>
<Image style={styles.logo} source={require('../../img/bluebeast.png')} />
<Text style={styles.textFree}>BlueWallet is a free and open source project. Crafted by Bitcoin users.</Text>
<Text style={styles.textBackup}>Always backup your keys!</Text>
<BlueButton onPress={handleOnRatePress} title="help with a review ⭐🙏" />
</View>
</BlueCard>
@ -116,7 +143,7 @@ const About = () => {
title="GitHub"
/>
<BlueCard>
<View style={{ backgroundColor: '#f9f9f9', padding: 16, paddingTop: 0, borderRadius: 8 }}>
<View style={styles.buildWith}>
<BlueSpacing20 />
<BlueTextCentered>Built with the awesome 👍</BlueTextCentered>

View file

@ -1,5 +1,5 @@
import React, { useState, useEffect } from 'react';
import { FlatList, TouchableOpacity, ActivityIndicator, View } from 'react-native';
import { FlatList, TouchableOpacity, ActivityIndicator, View, StyleSheet } from 'react-native';
import { SafeBlueArea, BlueNavigationStyle, BlueListItem, BlueText, BlueCard } from '../../BlueComponents';
import PropTypes from 'prop-types';
import { Icon } from 'react-native-elements';
@ -9,6 +9,17 @@ let currency = require('../../currency');
const data = Object.values(FiatUnit);
const styles = StyleSheet.create({
flex: {
flex: 1,
},
activity: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
},
});
const Currency = () => {
const [isSavingNewPreferredCurrency, setIsSavingNewPreferredCurrency] = useState(false);
const [selectedCurrency, setSelectedCurrency] = useState(null);
@ -30,9 +41,9 @@ const Currency = () => {
if (selectedCurrency !== null && selectedCurrency !== undefined) {
return (
<SafeBlueArea forceInset={{ horizontal: 'always' }} style={{ flex: 1 }}>
<SafeBlueArea forceInset={{ horizontal: 'always' }} style={styles.flex}>
<FlatList
style={{ flex: 1 }}
style={styles.flex}
keyExtractor={(_item, index) => `${index}`}
data={data}
extraData={data}
@ -63,7 +74,7 @@ const Currency = () => {
);
}
return (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<View style={styles.activity}>
<ActivityIndicator />
</View>
);

View file

@ -1,10 +1,16 @@
import React, { useEffect, useState } from 'react';
import { TouchableOpacity, View, TouchableWithoutFeedback } from 'react-native';
import { TouchableOpacity, View, TouchableWithoutFeedback, StyleSheet } from 'react-native';
import { SafeBlueArea, BlueCard, BlueText, BlueNavigationStyle, BlueListItem } from '../../BlueComponents';
import OnAppLaunch from '../../class/onAppLaunch';
import { useNavigation } from 'react-navigation-hooks';
const BlueApp = require('../../BlueApp');
const styles = StyleSheet.create({
flex: {
flex: 1,
},
});
const DefaultView = () => {
const [defaultWalletLabel, setDefaultWalletLabel] = useState('');
const [viewAllWalletsEnabled, setViewAllWalletsEnabled] = useState(true);
@ -48,7 +54,7 @@ const DefaultView = () => {
};
return (
<SafeBlueArea forceInset={{ horizontal: 'always' }} style={{ flex: 1 }}>
<SafeBlueArea forceInset={{ horizontal: 'always' }} style={styles.flex}>
<View>
<BlueListItem
title="View All Wallets"

View file

@ -1,6 +1,6 @@
/* global alert */
import React, { Component } from 'react';
import { View, TextInput } from 'react-native';
import { View, TextInput, StyleSheet } from 'react-native';
import { AppStorage } from '../../class';
import AsyncStorage from '@react-native-community/async-storage';
import { ScrollView } from 'react-native-gesture-handler';
@ -9,6 +9,72 @@ import PropTypes from 'prop-types';
let loc = require('../../loc');
let BlueElectrum = require('../../BlueElectrum');
const styles = StyleSheet.create({
root: {
flex: 1,
},
status: {
textAlign: 'center',
color: '#9AA0AA',
marginBottom: 4,
},
connectWrap: {
width: 'auto',
height: 34,
flexWrap: 'wrap',
justifyContent: 'center',
flexDirection: 'row',
},
container: {
paddingTop: 6,
paddingBottom: 6,
paddingLeft: 16,
paddingRight: 16,
borderRadius: 20,
},
connectText: {
fontWeight: '600',
},
containerConnected: {
backgroundColor: '#D2F8D6',
},
containerDisconnected: {
backgroundColor: '#F8D2D2',
},
textConnected: {
color: '#37C0A1',
},
textDisconnected: {
color: '#D0021B',
},
hostname: {
textAlign: 'center',
color: '#0C2550',
},
explain: {
color: '#9AA0AA',
marginBottom: -24,
},
inputWrap: {
flexDirection: 'row',
borderColor: '#d2d2d2',
borderBottomColor: '#d2d2d2',
borderWidth: 1,
borderBottomWidth: 0.5,
backgroundColor: '#f5f5f5',
minHeight: 44,
height: 44,
alignItems: 'center',
borderRadius: 4,
},
inputText: {
flex: 1,
marginHorizontal: 8,
minHeight: 36,
height: 36,
},
});
export default class ElectrumSettings extends Component {
static navigationOptions = () => ({
...BlueNavigationStyle(),
@ -86,106 +152,58 @@ export default class ElectrumSettings extends Component {
render() {
return (
<SafeBlueArea forceInset={{ horizontal: 'always' }} style={{ flex: 1 }}>
<SafeBlueArea forceInset={{ horizontal: 'always' }} style={styles.root}>
<ScrollView>
<BlueCard>
<BlueText style={{ textAlign: 'center', color: '#9AA0AA', marginBottom: 4 }}>Status</BlueText>
<View style={{ width: 'auto', height: 34, flexWrap: 'wrap', justifyContent: 'center', flexDirection: 'row' }}>
<View
style={{
backgroundColor: this.state.config.status === 1 ? '#D2F8D6' : '#F8D2D2',
paddingTop: 6,
paddingBottom: 6,
paddingLeft: 16,
paddingRight: 16,
borderRadius: 20,
}}
>
<BlueText style={{ fontWeight: '600', color: this.state.config.status === 1 ? '#37C0A1' : '#D0021B' }}>
<BlueText style={styles.status}>Status</BlueText>
<View style={styles.connectWrap}>
<View style={[styles.container, this.state.config.status === 1 ? styles.containerConnected : styles.containerDisconnected]}>
<BlueText style={[styles.connectText, this.state.config.status === 1 ? styles.textConnected : styles.textDisconnected]}>
{(this.state.config.status === 1 && 'Connected') || 'Not Connected'}
</BlueText>
</View>
</View>
<BlueSpacing20 />
<BlueText style={{ textAlign: 'center', color: '#0C2550' }} onPress={this.checkServer}>
<BlueText style={styles.hostname} onPress={this.checkServer}>
{this.state.config.host}:{this.state.config.port}
</BlueText>
<BlueSpacing20 />
</BlueCard>
<BlueCard>
<BlueText style={{ color: '#9AA0AA', marginBottom: -24 }}>{loc.settings.electrum_settings_explain}</BlueText>
<BlueText style={styles.explain}>{loc.settings.electrum_settings_explain}</BlueText>
</BlueCard>
<BlueCard>
<View
style={{
flexDirection: 'row',
borderColor: '#d2d2d2',
borderBottomColor: '#d2d2d2',
borderWidth: 1.0,
borderBottomWidth: 0.5,
backgroundColor: '#f5f5f5',
minHeight: 44,
height: 44,
alignItems: 'center',
borderRadius: 4,
}}
>
<View style={styles.inputWrap}>
<TextInput
placeholder={'host, for example 111.222.333.444'}
value={this.state.host}
onChangeText={text => this.setState({ host: text })}
numberOfLines={1}
style={{ flex: 1, marginHorizontal: 8, minHeight: 36, height: 36 }}
style={styles.inputText}
editable={!this.state.isLoading}
underlineColorAndroid="transparent"
/>
</View>
<BlueSpacing20 />
<View
style={{
flexDirection: 'row',
borderColor: '#d2d2d2',
borderBottomColor: '#d2d2d2',
borderWidth: 1.0,
borderBottomWidth: 0.5,
backgroundColor: '#f5f5f5',
minHeight: 44,
height: 44,
alignItems: 'center',
borderRadius: 4,
}}
>
<View style={styles.inputWrap}>
<TextInput
placeholder={'TCP port, usually 50001'}
value={this.state.port}
onChangeText={text => this.setState({ port: text })}
numberOfLines={1}
style={{ flex: 1, marginHorizontal: 8, minHeight: 36, height: 36 }}
style={styles.inputText}
editable={!this.state.isLoading}
underlineColorAndroid="transparent"
/>
</View>
<BlueSpacing20 />
<View
style={{
flexDirection: 'row',
borderColor: '#d2d2d2',
borderBottomColor: '#d2d2d2',
borderWidth: 1.0,
borderBottomWidth: 0.5,
backgroundColor: '#f5f5f5',
minHeight: 44,
height: 44,
alignItems: 'center',
borderRadius: 4,
}}
>
<View style={styles.inputWrap}>
<TextInput
placeholder={'SSL port, usually 50002'}
value={this.state.sslPort}
onChangeText={text => this.setState({ sslPort: text })}
numberOfLines={1}
style={{ flex: 1, marginHorizontal: 8, minHeight: 36, height: 36 }}
style={styles.inputText}
editable={!this.state.isLoading}
underlineColorAndroid="transparent"
/>

View file

@ -1,6 +1,6 @@
/* global alert */
import React, { Component } from 'react';
import { ScrollView, Alert, Platform, TouchableOpacity, TouchableWithoutFeedback } from 'react-native';
import { ScrollView, Alert, Platform, TouchableOpacity, TouchableWithoutFeedback, StyleSheet } from 'react-native';
import {
BlueLoading,
BlueHeaderDefaultSub,
@ -19,6 +19,12 @@ let BlueApp: AppStorage = require('../../BlueApp');
let prompt = require('../../prompt');
let loc = require('../../loc');
const styles = StyleSheet.create({
root: {
flex: 1,
},
});
export default class EncryptStorage extends Component {
static navigationOptions = () => ({
...BlueNavigationStyle(),
@ -134,7 +140,7 @@ export default class EncryptStorage extends Component {
}
return (
<SafeBlueArea forceInset={{ horizontal: 'always' }} style={{ flex: 1 }}>
<SafeBlueArea forceInset={{ horizontal: 'always' }} style={styles.root}>
<ScrollView>
{this.state.biometrics.isDeviceBiometricCapable && (
<>

View file

@ -1,10 +1,16 @@
import React, { Component } from 'react';
import { FlatList } from 'react-native';
import { FlatList, StyleSheet } from 'react-native';
import { BlueLoading, BlueText, SafeBlueArea, BlueListItem, BlueCard, BlueNavigationStyle } from '../../BlueComponents';
import PropTypes from 'prop-types';
import { Icon } from 'react-native-elements';
let loc = require('../../loc');
const styles = StyleSheet.create({
flex: {
flex: 1,
},
});
export default class Language extends Component {
static navigationOptions = () => ({
...BlueNavigationStyle(),
@ -78,9 +84,9 @@ export default class Language extends Component {
}
return (
<SafeBlueArea forceInset={{ horizontal: 'always' }} style={{ flex: 1 }}>
<SafeBlueArea forceInset={{ horizontal: 'always' }} style={styles.flex}>
<FlatList
style={{ flex: 1 }}
style={styles.flex}
keyExtractor={(_item, index) => `${index}`}
data={this.state.availableLanguages}
extraData={this.state.availableLanguages}

View file

@ -1,8 +1,14 @@
import React, { useState, useEffect } from 'react';
import { ScrollView } from 'react-native';
import { ScrollView, StyleSheet } from 'react-native';
import { BlueLoading, SafeBlueArea, BlueCard, BlueText, BlueNavigationStyle, BlueSpacing20 } from '../../BlueComponents';
/** @type {AppStorage} */
const styles = StyleSheet.create({
root: {
flex: 1,
},
});
const Licensing = () => {
const [isLoading, setIsLoading] = useState(true);
@ -11,9 +17,9 @@ const Licensing = () => {
}, []);
return isLoading ? (
(<BlueLoading />)
<BlueLoading />
) : (
(<SafeBlueArea forceInset={{ horizontal: 'always' }} style={{ flex: 1 }}>
<SafeBlueArea forceInset={{ horizontal: 'always' }} style={styles.root}>
<ScrollView>
<BlueCard>
<BlueText>MIT License</BlueText>
@ -41,7 +47,7 @@ const Licensing = () => {
</BlueText>
</BlueCard>
</ScrollView>
</SafeBlueArea>)
</SafeBlueArea>
);
};

View file

@ -1,6 +1,6 @@
/* global alert */
import React, { Component } from 'react';
import { View, TextInput, Linking } from 'react-native';
import { View, TextInput, Linking, StyleSheet } from 'react-native';
import { AppStorage } from '../../class';
import AsyncStorage from '@react-native-community/async-storage';
import { BlueLoading, BlueSpacing20, BlueButton, SafeBlueArea, BlueCard, BlueNavigationStyle, BlueText } from '../../BlueComponents';
@ -11,6 +11,30 @@ import { LightningCustodianWallet } from '../../class/lightning-custodian-wallet
let BlueApp = require('../../BlueApp');
let loc = require('../../loc');
const styles = StyleSheet.create({
root: {
flex: 1,
},
uri: {
flexDirection: 'row',
borderColor: '#d2d2d2',
borderBottomColor: '#d2d2d2',
borderWidth: 1,
borderBottomWidth: 0.5,
backgroundColor: '#f5f5f5',
minHeight: 44,
height: 44,
alignItems: 'center',
borderRadius: 4,
},
uriText: {
flex: 1,
marginHorizontal: 8,
minHeight: 36,
height: 36,
},
});
export default class LightningSettings extends Component {
static navigationOptions = () => ({
...BlueNavigationStyle(),
@ -53,7 +77,7 @@ export default class LightningSettings extends Component {
render() {
return (
<SafeBlueArea forceInset={{ horizontal: 'always' }} style={{ flex: 1 }}>
<SafeBlueArea forceInset={{ horizontal: 'always' }} style={styles.root}>
<BlueCard>
<BlueText>{loc.settings.lightning_settings_explain}</BlueText>
</BlueCard>
@ -77,26 +101,13 @@ export default class LightningSettings extends Component {
/>
<BlueCard>
<View
style={{
flexDirection: 'row',
borderColor: '#d2d2d2',
borderBottomColor: '#d2d2d2',
borderWidth: 1.0,
borderBottomWidth: 0.5,
backgroundColor: '#f5f5f5',
minHeight: 44,
height: 44,
alignItems: 'center',
borderRadius: 4,
}}
>
<View style={styles.uri}>
<TextInput
placeholder={LightningCustodianWallet.defaultBaseUri}
value={this.state.URI}
onChangeText={text => this.setState({ URI: text })}
numberOfLines={1}
style={{ flex: 1, marginHorizontal: 8, minHeight: 36, height: 36 }}
style={styles.uriText}
editable={!this.state.isLoading}
underlineColorAndroid="transparent"
/>

View file

@ -1,8 +1,14 @@
import React, { useState, useEffect } from 'react';
import { ScrollView } from 'react-native';
import { ScrollView, StyleSheet } from 'react-native';
import { BlueLoading, SafeBlueArea, BlueCard, BlueText, BlueNavigationStyle } from '../../BlueComponents';
/** @type {AppStorage} */
const styles = StyleSheet.create({
root: {
flex: 1,
},
});
const ReleaseNotes = () => {
const [isLoading, setIsLoading] = useState(true);
const notes = require('../../release-notes');
@ -12,15 +18,15 @@ const ReleaseNotes = () => {
}, []);
return isLoading ? (
(<BlueLoading />)
<BlueLoading />
) : (
(<SafeBlueArea forceInset={{ horizontal: 'always' }} style={{ flex: 1 }}>
<SafeBlueArea forceInset={{ horizontal: 'always' }} style={styles.root}>
<ScrollView>
<BlueCard>
<BlueText>{notes}</BlueText>
</BlueCard>
</ScrollView>
</SafeBlueArea>)
</SafeBlueArea>
);
};

View file

@ -1,9 +1,15 @@
import React, { useEffect, useState } from 'react';
import { ScrollView, TouchableOpacity } from 'react-native';
import { ScrollView, TouchableOpacity, StyleSheet } from 'react-native';
import { BlueNavigationStyle, BlueLoading, SafeBlueArea, BlueHeaderDefaultSub, BlueListItem } from '../../BlueComponents';
import { useNavigation } from 'react-navigation-hooks';
const loc = require('../../loc');
const styles = StyleSheet.create({
root: {
flex: 1,
},
});
const Settings = () => {
const [isLoading, setIsLoading] = useState(true);
const { navigate } = useNavigation();
@ -15,7 +21,7 @@ const Settings = () => {
return isLoading ? (
<BlueLoading />
) : (
<SafeBlueArea forceInset={{ horizontal: 'always' }} style={{ flex: 1 }}>
<SafeBlueArea forceInset={{ horizontal: 'always' }} style={styles.root}>
<ScrollView>
<BlueHeaderDefaultSub leftText={loc.settings.header} rightComponent={null} />
<BlueListItem title={'General'} component={TouchableOpacity} onPress={() => navigate('GeneralSettings')} chevron />

View file

@ -1,6 +1,6 @@
/* global alert */
import React, { Component } from 'react';
import { ActivityIndicator, View, TextInput, TouchableOpacity, Linking, Clipboard, ScrollView } from 'react-native';
import { ActivityIndicator, View, TextInput, TouchableOpacity, Linking, Clipboard, ScrollView, StyleSheet } from 'react-native';
import {
BlueSpacing20,
BlueReplaceFeeSuggestions,
@ -23,6 +23,60 @@ let loc = require('../../loc');
/** @type {AppStorage} */
let BlueApp = require('../../BlueApp');
const styles = StyleSheet.create({
root: {
flex: 1,
paddingTop: 20,
},
explain: {
flex: 1,
paddingBottom: 16,
},
center: {
alignItems: 'center',
flex: 1,
},
hex: {
color: '#0c2550',
fontWeight: '500',
},
hexInput: {
borderColor: '#ebebeb',
backgroundColor: '#d2f8d6',
borderRadius: 4,
marginTop: 20,
color: '#37c0a1',
fontWeight: '500',
fontSize: 14,
paddingHorizontal: 16,
paddingBottom: 16,
paddingTop: 16,
},
action: {
marginVertical: 24,
},
actionText: {
color: '#9aa0aa',
fontSize: 15,
fontWeight: '500',
alignSelf: 'center',
},
doneWrap: {
flex: 1,
paddingTop: 19,
},
doneCard: {
flexDirection: 'row',
justifyContent: 'center',
paddingTop: 76,
paddingBottom: 16,
},
blueBigCheckmark: {
marginTop: 43,
marginBottom: 53,
},
});
export default class CPFP extends Component {
static navigationOptions = () => ({
...BlueNavigationStyle(null, false),
@ -116,7 +170,7 @@ export default class CPFP extends Component {
render() {
if (this.state.isLoading) {
return (
<View style={{ flex: 1, paddingTop: 20 }}>
<View style={styles.root}>
<ActivityIndicator />
</View>
);
@ -132,7 +186,7 @@ export default class CPFP extends Component {
if (this.state.nonReplaceable) {
return (
<SafeBlueArea style={{ flex: 1, paddingTop: 20 }}>
<SafeBlueArea style={styles.root}>
<BlueSpacing20 />
<BlueSpacing20 />
<BlueSpacing20 />
@ -145,7 +199,7 @@ export default class CPFP extends Component {
}
return (
<SafeBlueArea style={{ flex: 1, paddingBottom: 16 }}>
<SafeBlueArea style={styles.explain}>
<ScrollView>
{this.renderStage1(
'We will create another transaction that spends your unconfirmed transaction. The total fee will be higher than the original transaction fee, so it should be mined faster. This is called CPFP - Child Pays For Parent.',
@ -157,33 +211,16 @@ export default class CPFP extends Component {
renderStage2() {
return (
<View style={{ flex: 1, paddingTop: 20 }}>
<BlueCard style={{ alignItems: 'center', flex: 1 }}>
<BlueText style={{ color: '#0c2550', fontWeight: '500' }}>{loc.send.create.this_is_hex}</BlueText>
<TextInput
style={{
borderColor: '#ebebeb',
backgroundColor: '#d2f8d6',
borderRadius: 4,
marginTop: 20,
color: '#37c0a1',
fontWeight: '500',
fontSize: 14,
paddingHorizontal: 16,
paddingBottom: 16,
paddingTop: 16,
}}
height={112}
multiline
editable
value={this.state.txhex}
/>
<View style={styles.root}>
<BlueCard style={styles.center}>
<BlueText style={styles.hex}>{loc.send.create.this_is_hex}</BlueText>
<TextInput style={styles.hexInput} height={112} multiline editable value={this.state.txhex} />
<TouchableOpacity style={{ marginVertical: 24 }} onPress={() => Clipboard.setString(this.state.txhex)}>
<Text style={{ color: '#9aa0aa', fontSize: 15, fontWeight: '500', alignSelf: 'center' }}>Copy and broadcast later</Text>
<TouchableOpacity style={styles.action} onPress={() => Clipboard.setString(this.state.txhex)}>
<Text style={styles.actionText}>Copy and broadcast later</Text>
</TouchableOpacity>
<TouchableOpacity style={{ marginVertical: 24 }} onPress={() => Linking.openURL('https://coinb.in/?verify=' + this.state.txhex)}>
<Text style={{ color: '#9aa0aa', fontSize: 15, fontWeight: '500', alignSelf: 'center' }}>Verify on coinb.in</Text>
<TouchableOpacity style={styles.action} onPress={() => Linking.openURL('https://coinb.in/?verify=' + this.state.txhex)}>
<Text style={styles.actionText}>Verify on coinb.in</Text>
</TouchableOpacity>
<BlueButton onPress={() => this.broadcast()} title={loc.send.confirm.sendNow} />
</BlueCard>
@ -193,11 +230,11 @@ export default class CPFP extends Component {
renderStage3() {
return (
<SafeBlueArea style={{ flex: 1, paddingTop: 19 }}>
<BlueCard style={{ alignItems: 'center', flex: 1 }}>
<View style={{ flexDirection: 'row', justifyContent: 'center', paddingTop: 76, paddingBottom: 16 }} />
<SafeBlueArea style={styles.doneWrap}>
<BlueCard style={styles.center}>
<View style={styles.doneCard} />
</BlueCard>
<BlueBigCheckmark style={{ marginTop: 43, marginBottom: 53 }} />
<BlueBigCheckmark style={styles.blueBigCheckmark} />
<BlueCard>
<BlueButton
onPress={() => {
@ -212,9 +249,9 @@ export default class CPFP extends Component {
renderStage1(text) {
return (
<SafeBlueArea style={{ flex: 1, paddingTop: 20 }}>
<SafeBlueArea style={styles.root}>
<BlueSpacing />
<BlueCard style={{ alignItems: 'center', flex: 1 }}>
<BlueCard style={styles.center}>
<BlueText>{text}</BlueText>
<BlueSpacing20 />
<BlueReplaceFeeSuggestions onFeeSelected={fee => this.setState({ newFeeRate: fee })} transactionMinimum={this.state.feeRate} />

View file

@ -1,6 +1,6 @@
/* global alert */
import React from 'react';
import { ActivityIndicator, View, ScrollView } from 'react-native';
import { ActivityIndicator, View, ScrollView, StyleSheet } from 'react-native';
import { BlueSpacing20, SafeBlueArea, BlueText, BlueNavigationStyle } from '../../BlueComponents';
import PropTypes from 'prop-types';
import { HDSegwitBech32Transaction, HDSegwitBech32Wallet } from '../../class';
@ -8,6 +8,13 @@ import CPFP from './CPFP';
/** @type {AppStorage} */
let BlueApp = require('../../BlueApp');
const styles = StyleSheet.create({
root: {
flex: 1,
paddingTop: 16,
},
});
export default class RBFBumpFee extends CPFP {
static navigationOptions = () => ({
...BlueNavigationStyle(null, false),
@ -66,7 +73,7 @@ export default class RBFBumpFee extends CPFP {
render() {
if (this.state.isLoading) {
return (
<View style={{ flex: 1, paddingTop: 16 }}>
<View style={styles.root}>
<ActivityIndicator />
</View>
);
@ -82,7 +89,7 @@ export default class RBFBumpFee extends CPFP {
if (this.state.nonReplaceable) {
return (
<SafeBlueArea style={{ flex: 1, paddingTop: 16 }}>
<SafeBlueArea style={styles.root}>
<BlueSpacing20 />
<BlueSpacing20 />
<BlueSpacing20 />
@ -95,7 +102,7 @@ export default class RBFBumpFee extends CPFP {
}
return (
<SafeBlueArea style={{ flex: 1, paddingBottom: 16 }}>
<SafeBlueArea style={styles.root}>
<ScrollView>
{this.renderStage1(
'We will replace this transaction with the one with a higher fee, so it should be mined faster. This is called RBF - Replace By Fee.',

View file

@ -1,6 +1,6 @@
/* global alert */
import React from 'react';
import { ActivityIndicator, View } from 'react-native';
import { ActivityIndicator, View, StyleSheet } from 'react-native';
import { BlueSpacing20, SafeBlueArea, BlueText, BlueNavigationStyle } from '../../BlueComponents';
import PropTypes from 'prop-types';
import { HDSegwitBech32Transaction, HDSegwitBech32Wallet } from '../../class';
@ -8,6 +8,13 @@ import CPFP from './CPFP';
/** @type {AppStorage} */
let BlueApp = require('../../BlueApp');
const styles = StyleSheet.create({
common: {
flex: 1,
paddingTop: 20,
},
});
export default class RBFCancel extends CPFP {
static navigationOptions = () => ({
...BlueNavigationStyle(null, false),
@ -77,7 +84,7 @@ export default class RBFCancel extends CPFP {
render() {
if (this.state.isLoading) {
return (
<View style={{ flex: 1, paddingTop: 20 }}>
<View style={styles.root}>
<ActivityIndicator />
</View>
);
@ -93,7 +100,7 @@ export default class RBFCancel extends CPFP {
if (this.state.nonReplaceable) {
return (
<SafeBlueArea style={{ flex: 1, paddingTop: 20 }}>
<SafeBlueArea style={styles.root}>
<BlueSpacing20 />
<BlueSpacing20 />
<BlueSpacing20 />

View file

@ -1,5 +1,5 @@
import React, { Component } from 'react';
import { View, ScrollView, TouchableOpacity, Linking } from 'react-native';
import { View, ScrollView, TouchableOpacity, Linking, StyleSheet } from 'react-native';
import {
SafeBlueArea,
BlueCard,
@ -18,6 +18,42 @@ let BlueApp = require('../../BlueApp');
let loc = require('../../loc');
const dayjs = require('dayjs');
const styles = StyleSheet.create({
root: {
flex: 1,
},
scroll: {
flex: 1,
},
rowHeader: {
flex: 1,
flexDirection: 'row',
marginBottom: 4,
justifyContent: 'space-between',
},
rowCaption: {
fontSize: 16,
fontWeight: '500',
marginBottom: 4,
},
rowValue: {
marginBottom: 26,
color: 'grey',
},
txId: {
fontSize: 16,
fontWeight: '500',
},
txHash: {
marginBottom: 8,
color: 'grey',
},
txLink: {
marginBottom: 26,
color: '#2f5fb3',
},
});
function onlyUnique(value, index, self) {
return self.indexOf(value) === index;
}
@ -90,7 +126,7 @@ export default class TransactionsDetails extends Component {
}
return (
<SafeBlueArea forceInset={{ horizontal: 'always' }} style={{ flex: 1 }}>
<SafeBlueArea forceInset={{ horizontal: 'always' }} style={styles.root}>
{this.state.isHandOffUseEnabled && (
<Handoff
title={`Bitcoin Transaction ${this.state.tx.hash}`}
@ -99,7 +135,7 @@ export default class TransactionsDetails extends Component {
/>
)}
<BlueHeaderDefaultSub leftText={loc.transactions.details.title} rightComponent={null} />
<ScrollView style={{ flex: 1 }}>
<ScrollView style={styles.scroll}>
<BlueCard>
{(() => {
if (BlueApp.tx_metadata[this.state.tx.hash]) {
@ -116,40 +152,38 @@ export default class TransactionsDetails extends Component {
{this.state.hasOwnProperty('from') && (
<React.Fragment>
<View style={{ flex: 1, flexDirection: 'row', marginBottom: 4, justifyContent: 'space-between' }}>
<BlueText style={{ fontSize: 16, fontWeight: '500', marginBottom: 4 }}>{loc.transactions.details.from}</BlueText>
<View style={styles.rowHeader}>
<BlueText style={styles.rowCaption}>{loc.transactions.details.from}</BlueText>
<BlueCopyToClipboardButton stringToCopy={this.state.from.filter(onlyUnique).join(', ')} />
</View>
<BlueText style={{ marginBottom: 26, color: 'grey' }}>{this.state.from.filter(onlyUnique).join(', ')}</BlueText>
<BlueText style={styles.rowValue}>{this.state.from.filter(onlyUnique).join(', ')}</BlueText>
</React.Fragment>
)}
{this.state.hasOwnProperty('to') && (
<React.Fragment>
<View style={{ flex: 1, flexDirection: 'row', marginBottom: 4, justifyContent: 'space-between' }}>
<BlueText style={{ fontSize: 16, fontWeight: '500', marginBottom: 4 }}>{loc.transactions.details.to}</BlueText>
<View style={styles.rowHeader}>
<BlueText style={styles.rowCaption}>{loc.transactions.details.to}</BlueText>
<BlueCopyToClipboardButton stringToCopy={this.state.to.filter(onlyUnique).join(', ')} />
</View>
<BlueText style={{ marginBottom: 26, color: 'grey' }}>
{arrDiff(this.state.from, this.state.to.filter(onlyUnique)).join(', ')}
</BlueText>
<BlueText style={styles.rowValue}>{arrDiff(this.state.from, this.state.to.filter(onlyUnique)).join(', ')}</BlueText>
</React.Fragment>
)}
{this.state.tx.hasOwnProperty('fee') && (
<React.Fragment>
<BlueText style={{ fontSize: 16, fontWeight: '500', marginBottom: 4 }}>{loc.send.create.fee}</BlueText>
<BlueText style={{ marginBottom: 26, color: 'grey' }}>{this.state.tx.fee + ' sats'}</BlueText>
<BlueText style={styles.rowCaption}>{loc.send.create.fee}</BlueText>
<BlueText style={styles.rowValue}>{this.state.tx.fee + ' sats'}</BlueText>
</React.Fragment>
)}
{this.state.tx.hasOwnProperty('hash') && (
<React.Fragment>
<View style={{ flex: 1, flexDirection: 'row', marginBottom: 4, justifyContent: 'space-between' }}>
<BlueText style={{ fontSize: 16, fontWeight: '500' }}>Txid</BlueText>
<View style={styles.rowHeader}>
<BlueText style={styles.txId}>Txid</BlueText>
<BlueCopyToClipboardButton stringToCopy={this.state.tx.hash} />
</View>
<BlueText style={{ marginBottom: 8, color: 'grey' }}>{this.state.tx.hash}</BlueText>
<BlueText style={styles.txHash}>{this.state.tx.hash}</BlueText>
<TouchableOpacity
onPress={() => {
const url = `https://blockstream.info/tx/${this.state.tx.hash}`;
@ -160,36 +194,36 @@ export default class TransactionsDetails extends Component {
});
}}
>
<BlueText style={{ marginBottom: 26, color: '#2f5fb3' }}>{loc.transactions.details.show_in_block_explorer}</BlueText>
<BlueText style={styles.txLink}>{loc.transactions.details.show_in_block_explorer}</BlueText>
</TouchableOpacity>
</React.Fragment>
)}
{this.state.tx.hasOwnProperty('received') && (
<React.Fragment>
<BlueText style={{ fontSize: 16, fontWeight: '500', marginBottom: 4 }}>Received</BlueText>
<BlueText style={{ marginBottom: 26, color: 'grey' }}>{dayjs(this.state.tx.received).format('MM/DD/YYYY h:mm A')}</BlueText>
<BlueText style={styles.rowCaption}>Received</BlueText>
<BlueText style={styles.rowValue}>{dayjs(this.state.tx.received).format('MM/DD/YYYY h:mm A')}</BlueText>
</React.Fragment>
)}
{this.state.tx.hasOwnProperty('block_height') && this.state.tx.block_height > 0 && (
<React.Fragment>
<BlueText style={{ fontSize: 16, fontWeight: '500', marginBottom: 4 }}>Block Height</BlueText>
<BlueText style={{ marginBottom: 26, color: 'grey' }}>{this.state.tx.block_height}</BlueText>
<BlueText style={styles.rowCaption}>Block Height</BlueText>
<BlueText style={styles.rowValue}>{this.state.tx.block_height}</BlueText>
</React.Fragment>
)}
{this.state.tx.hasOwnProperty('inputs') && (
<React.Fragment>
<BlueText style={{ fontSize: 16, fontWeight: '500', marginBottom: 4 }}>Inputs</BlueText>
<BlueText style={{ marginBottom: 26, color: 'grey' }}>{this.state.tx.inputs.length}</BlueText>
<BlueText style={styles.rowCaption}>Inputs</BlueText>
<BlueText style={styles.rowValue}>{this.state.tx.inputs.length}</BlueText>
</React.Fragment>
)}
{this.state.tx.hasOwnProperty('outputs') && this.state.tx.outputs.length > 0 && (
<React.Fragment>
<BlueText style={{ fontSize: 16, fontWeight: '500', marginBottom: 4 }}>Outputs</BlueText>
<BlueText style={{ marginBottom: 26, color: 'grey' }}>{this.state.tx.outputs.length}</BlueText>
<BlueText style={styles.rowCaption}>Outputs</BlueText>
<BlueText style={styles.rowValue}>{this.state.tx.outputs.length}</BlueText>
</React.Fragment>
)}
</BlueCard>

View file

@ -1,5 +1,5 @@
import React, { Component } from 'react';
import { View, ActivityIndicator, Text, TouchableOpacity } from 'react-native';
import { View, ActivityIndicator, Text, TouchableOpacity, StyleSheet } from 'react-native';
import {
BlueButton,
SafeBlueArea,
@ -28,6 +28,109 @@ const buttonStatus = Object.freeze({
notPossible: 3,
});
const styles = StyleSheet.create({
root: {
flex: 1,
},
container: {
flex: 1,
justifyContent: 'space-between',
},
center: {
alignItems: 'center',
},
value: {
color: '#2f5fb3',
fontSize: 36,
fontWeight: '600',
},
valueUnit: {
color: '#2f5fb3',
fontSize: 16,
fontWeight: '600',
},
memo: {
alignItems: 'center',
marginVertical: 8,
},
memoText: {
color: '#9aa0aa',
fontSize: 14,
},
iconRoot: {
backgroundColor: '#ccddf9',
width: 120,
height: 120,
borderRadius: 60,
alignSelf: 'center',
justifyContent: 'center',
marginTop: 43,
marginBottom: 53,
},
iconWrap: {
minWidth: 30,
minHeight: 30,
alignItems: 'center',
justifyContent: 'center',
alignSelf: 'flex-end',
borderRadius: 15,
},
margin: {
marginBottom: -40,
},
icon: {
width: 25,
},
fee: {
marginTop: 15,
marginBottom: 13,
},
feeText: {
fontSize: 11,
fontWeight: '500',
marginBottom: 4,
color: '#00c49f',
alignSelf: 'center',
},
confirmations: {
borderRadius: 11,
backgroundColor: '#eef0f4',
width: 109,
height: 21,
alignSelf: 'center',
alignItems: 'center',
justifyContent: 'center',
},
confirmationsText: {
color: '#9aa0aa',
fontSize: 11,
},
actions: {
alignSelf: 'center',
justifyContent: 'center',
},
cancel: {
marginVertical: 16,
},
cancelText: {
color: '#d0021b',
fontSize: 15,
fontWeight: '500',
textAlign: 'center',
},
details: {
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'center',
marginBottom: 16,
},
detailsText: {
color: '#9aa0aa',
fontSize: 14,
marginRight: 8,
},
});
export default class TransactionsStatus extends Component {
static navigationOptions = () => ({
...BlueNavigationStyle(),
@ -146,7 +249,7 @@ export default class TransactionsStatus extends Component {
}
return (
<SafeBlueArea forceInset={{ horizontal: 'always' }} style={{ flex: 1 }}>
<SafeBlueArea forceInset={{ horizontal: 'always' }} style={styles.root}>
{this.state.isHandOffUseEnabled && (
<Handoff
title={`Bitcoin Transaction ${this.state.tx.hash}`}
@ -154,13 +257,13 @@ export default class TransactionsStatus extends Component {
url={`https://blockstream.info/tx/${this.state.tx.hash}`}
/>
)}
<View style={{ flex: 1, justifyContent: 'space-between' }}>
<View style={styles.container}>
<BlueCard>
<View style={{ alignItems: 'center' }}>
<Text style={{ color: '#2f5fb3', fontSize: 36, fontWeight: '600' }}>
<View style={styles.center}>
<Text style={styles.value}>
{loc.formatBalanceWithoutSuffix(this.state.tx.value, this.state.wallet.preferredBalanceUnit, true)}{' '}
{this.state.wallet.preferredBalanceUnit !== BitcoinUnit.LOCAL_CURRENCY && (
<Text style={{ color: '#2f5fb3', fontSize: 16, fontWeight: '600' }}>{this.state.wallet.preferredBalanceUnit}</Text>
<Text style={styles.valueUnit}>{this.state.wallet.preferredBalanceUnit}</Text>
)}
</Text>
</View>
@ -169,8 +272,8 @@ export default class TransactionsStatus extends Component {
if (BlueApp.tx_metadata[this.state.tx.hash]) {
if (BlueApp.tx_metadata[this.state.tx.hash]['memo']) {
return (
<View style={{ alignItems: 'center', marginVertical: 8 }}>
<Text style={{ color: '#9aa0aa', fontSize: 14 }}>{BlueApp.tx_metadata[this.state.tx.hash]['memo']}</Text>
<View style={styles.memo}>
<Text style={styles.memoText}>{BlueApp.tx_metadata[this.state.tx.hash]['memo']}</Text>
<BlueSpacing20 />
</View>
);
@ -178,48 +281,27 @@ export default class TransactionsStatus extends Component {
}
})()}
<View
style={{
backgroundColor: '#ccddf9',
width: 120,
height: 120,
borderRadius: 60,
alignSelf: 'center',
justifyContent: 'center',
marginTop: 43,
marginBottom: 53,
}}
>
<View style={styles.iconRoot}>
<View>
<Icon name="check" size={50} type="font-awesome" color="#0f5cc0" />
</View>
<View
style={{
marginBottom: -40,
minWidth: 30,
minHeight: 30,
alignItems: 'center',
justifyContent: 'center',
alignSelf: 'flex-end',
borderRadius: 15,
}}
>
<View style={[styles.iconWrap, styles.margin]}>
{(() => {
if (!this.state.tx.confirmations) {
return (
<View style={{ width: 25 }}>
<View style={styles.icon}>
<BlueTransactionPendingIcon />
</View>
);
} else if (this.state.tx.value < 0) {
return (
<View style={{ width: 25 }}>
<View style={styles.icon}>
<BlueTransactionOutgoingIcon />
</View>
);
} else {
return (
<View style={{ width: 25 }}>
<View style={styles.icon}>
<BlueTransactionIncomingIcon />
</View>
);
@ -229,8 +311,8 @@ export default class TransactionsStatus extends Component {
</View>
{this.state.tx.hasOwnProperty('fee') && (
<View style={{ marginTop: 15, marginBottom: 13 }}>
<BlueText style={{ fontSize: 11, fontWeight: '500', marginBottom: 4, color: '#00c49f', alignSelf: 'center' }}>
<View style={styles.fee}>
<BlueText style={styles.feeText}>
{loc.send.create.fee.toLowerCase()}{' '}
{loc.formatBalanceWithoutSuffix(this.state.tx.fee, this.state.wallet.preferredBalanceUnit, true)}{' '}
{this.state.wallet.preferredBalanceUnit !== BitcoinUnit.LOCAL_CURRENCY && this.state.wallet.preferredBalanceUnit}
@ -238,24 +320,14 @@ export default class TransactionsStatus extends Component {
</View>
)}
<View
style={{
borderRadius: 11,
backgroundColor: '#eef0f4',
width: 109,
height: 21,
alignSelf: 'center',
alignItems: 'center',
justifyContent: 'center',
}}
>
<Text style={{ color: '#9aa0aa', fontSize: 11 }}>
<View style={styles.confirmations}>
<Text style={styles.confirmationsText}>
{this.state.tx.confirmations > 6 ? '6+' : this.state.tx.confirmations} confirmations
</Text>
</View>
</BlueCard>
<View style={{ alignSelf: 'center', justifyContent: 'center' }}>
<View style={styles.actions}>
{(() => {
if (this.state.isCPFPpossible === buttonStatus.unknown) {
return (
@ -316,7 +388,7 @@ export default class TransactionsStatus extends Component {
} else if (this.state.isRBFCancelPossible === buttonStatus.possible) {
return (
<React.Fragment>
<TouchableOpacity style={{ marginVertical: 16 }}>
<TouchableOpacity style={styles.cancel}>
<Text
onPress={() =>
this.props.navigation.navigate('RBFCancel', {
@ -324,7 +396,7 @@ export default class TransactionsStatus extends Component {
wallet: this.state.wallet,
})
}
style={{ color: '#d0021b', fontSize: 15, fontWeight: '500', textAlign: 'center' }}
style={styles.cancelText}
>
{'Cancel Transaction'}
</Text>
@ -335,10 +407,10 @@ export default class TransactionsStatus extends Component {
})()}
<TouchableOpacity
style={{ flexDirection: 'row', alignItems: 'center', justifyContent: 'center', marginBottom: 16 }}
style={styles.details}
onPress={() => this.props.navigation.navigate('TransactionDetails', { hash: this.state.tx.hash })}
>
<Text style={{ color: '#9aa0aa', fontSize: 14, marginRight: 8 }}>{loc.send.create.details.toLowerCase()}</Text>
<Text style={styles.detailsText}>{loc.send.create.details.toLowerCase()}</Text>
<Icon name="angle-right" size={18} type="font-awesome" color="#9aa0aa" />
</TouchableOpacity>
</View>

View file

@ -10,6 +10,7 @@ import {
Platform,
View,
TextInput,
StyleSheet,
} from 'react-native';
import AsyncStorage from '@react-native-community/async-storage';
import {
@ -35,6 +36,83 @@ let EV = require('../../events');
let A = require('../../analytics');
let BlueApp: AppStorage = require('../../BlueApp');
let loc = require('../../loc');
const styles = StyleSheet.create({
loading: {
flex: 1,
paddingTop: 20,
},
label: {
flexDirection: 'row',
borderColor: '#d2d2d2',
borderBottomColor: '#d2d2d2',
borderWidth: 1,
borderBottomWidth: 0.5,
backgroundColor: '#f5f5f5',
minHeight: 44,
height: 44,
marginHorizontal: 20,
alignItems: 'center',
marginVertical: 16,
borderRadius: 4,
},
textInputCommon: {
flex: 1,
marginHorizontal: 8,
color: '#81868e',
},
buttons: {
flexDirection: 'row',
justifyContent: 'space-between',
paddingTop: 10,
marginHorizontal: 20,
borderWidth: 0,
minHeight: 100,
},
button: {
width: '45%',
height: 88,
},
or: {
borderWidth: 0,
justifyContent: 'center',
marginHorizontal: 8,
alignSelf: 'center',
},
orCenter: {
color: '#0c2550',
},
advanced: {
marginHorizontal: 20,
},
advancedText: {
color: '#0c2550',
fontWeight: '500',
},
lndUri: {
flexDirection: 'row',
borderColor: '#d2d2d2',
borderBottomColor: '#d2d2d2',
borderWidth: 1,
borderBottomWidth: 0.5,
backgroundColor: '#f5f5f5',
minHeight: 44,
height: 44,
alignItems: 'center',
marginVertical: 16,
borderRadius: 4,
},
createButton: {
alignItems: 'center',
flex: 1,
marginTop: 32,
},
import: {
marginBottom: 0,
marginTop: 24,
},
});
export default class WalletsAdd extends Component {
static navigationOptions = ({ navigation }) => ({
...BlueNavigationStyle(navigation, true),
@ -85,7 +163,7 @@ export default class WalletsAdd extends Component {
render() {
if (this.state.isLoading) {
return (
<View style={{ flex: 1, paddingTop: 20 }}>
<View style={styles.loading}>
<ActivityIndicator />
</View>
);
@ -96,22 +174,7 @@ export default class WalletsAdd extends Component {
<ScrollView>
<KeyboardAvoidingView enabled behavior={Platform.OS === 'ios' ? 'padding' : null} keyboardVerticalOffset={62}>
<BlueFormLabel>{loc.wallets.add.wallet_name}</BlueFormLabel>
<View
style={{
flexDirection: 'row',
borderColor: '#d2d2d2',
borderBottomColor: '#d2d2d2',
borderWidth: 1.0,
borderBottomWidth: 0.5,
backgroundColor: '#f5f5f5',
minHeight: 44,
height: 44,
marginHorizontal: 20,
alignItems: 'center',
marginVertical: 16,
borderRadius: 4,
}}
>
<View style={styles.label}>
<TextInput
testID="WalletNameInput"
value={this.state.label}
@ -120,23 +183,14 @@ export default class WalletsAdd extends Component {
onChangeText={text => {
this.setLabel(text);
}}
style={{ flex: 1, marginHorizontal: 8, color: '#81868e' }}
style={styles.textInputCommon}
editable={!this.state.isLoading}
underlineColorAndroid="transparent"
/>
</View>
<BlueFormLabel>{loc.wallets.add.wallet_type}</BlueFormLabel>
<View
style={{
flexDirection: 'row',
justifyContent: 'space-between',
paddingTop: 10,
marginHorizontal: 20,
borderWidth: 0,
minHeight: 100,
}}
>
<View style={styles.buttons}>
<BitcoinButton
testID="ActivateBitcoinButton"
active={this.state.activeBitcoin}
@ -147,13 +201,10 @@ export default class WalletsAdd extends Component {
activeLightning: false,
});
}}
style={{
width: '45%',
height: 88,
}}
style={styles.button}
/>
<View style={{ borderWidth: 0, justifyContent: 'center', marginHorizontal: 8, alignSelf: 'center' }}>
<BlueTextCentered style={{ color: '#0c2550' }}>{loc.wallets.add.or}</BlueTextCentered>
<View style={styles.or}>
<BlueTextCentered style={styles.orCenter}>{loc.wallets.add.or}</BlueTextCentered>
</View>
<LightningButton
active={this.state.activeLightning}
@ -164,20 +215,17 @@ export default class WalletsAdd extends Component {
activeLightning: true,
});
}}
style={{
width: '45%',
height: 88,
}}
style={styles.button}
/>
</View>
<View style={{ marginHorizontal: 20 }}>
<View style={styles.advanced}>
{(() => {
if (this.state.activeBitcoin && this.state.isAdvancedOptionsEnabled) {
return (
<View>
<BlueSpacing20 />
<Text style={{ color: '#0c2550', fontWeight: '500' }}>{loc.settings.advanced_options}</Text>
<Text style={styles.advancedText}>{loc.settings.advanced_options}</Text>
<BlueListItem
onPress={() => {
this.onSelect(0, HDSegwitBech32Wallet.type);
@ -217,24 +265,10 @@ export default class WalletsAdd extends Component {
return (
<React.Fragment>
<BlueSpacing20 />
<Text style={{ color: '#0c2550', fontWeight: '500' }}>{loc.settings.advanced_options}</Text>
<Text style={styles.advancedText}>{loc.settings.advanced_options}</Text>
<BlueSpacing20 />
<BlueText>Connect to your LNDHub</BlueText>
<View
style={{
flexDirection: 'row',
borderColor: '#d2d2d2',
borderBottomColor: '#d2d2d2',
borderWidth: 1.0,
borderBottomWidth: 0.5,
backgroundColor: '#f5f5f5',
minHeight: 44,
height: 44,
alignItems: 'center',
marginVertical: 16,
borderRadius: 4,
}}
>
<View style={styles.lndUri}>
<TextInput
value={this.state.walletBaseURI}
onChangeText={text => {
@ -245,7 +279,7 @@ export default class WalletsAdd extends Component {
clearButtonMode="while-editing"
autoCapitalize="none"
placeholderTextColor="#81868e"
style={{ flex: 1, marginHorizontal: 8, color: '#81868e' }}
style={styles.textInputCommon}
editable={!this.state.isLoading}
underlineColorAndroid="transparent"
/>
@ -256,13 +290,7 @@ export default class WalletsAdd extends Component {
return <View />;
}
})()}
<View
style={{
alignItems: 'center',
flex: 1,
marginTop: 32,
}}
>
<View style={styles.createButton}>
{!this.state.isLoading ? (
<BlueButton
testID="Create"
@ -352,7 +380,7 @@ export default class WalletsAdd extends Component {
</View>
<BlueButtonLink
testID="ImportWallet"
style={{ marginBottom: 0, marginTop: 24 }}
style={styles.import}
title={loc.wallets.add.import_wallet}
onPress={() => {
this.props.navigation.navigate('ImportWallet');

View file

@ -1,4 +1,5 @@
import React, { Component } from 'react';
import { StyleSheet } from 'react-native';
import { BlueNavigationStyle, BlueLoading, SafeBlueArea } from '../../BlueComponents';
import PropTypes from 'prop-types';
import { WebView } from 'react-native-webview';
@ -7,6 +8,12 @@ const currency = require('../../currency');
let BlueApp: AppStorage = require('../../BlueApp');
let loc = require('../../loc');
const styles = StyleSheet.create({
root: {
flex: 1,
},
});
export default class BuyBitcoin extends Component {
static navigationOptions = ({ navigation }) => ({
...BlueNavigationStyle(navigation, true),
@ -90,7 +97,7 @@ export default class BuyBitcoin extends Component {
}
return (
<SafeBlueArea style={{ flex: 1 }}>
<SafeBlueArea style={styles.root}>
<WebView
source={{
uri,

View file

@ -13,6 +13,7 @@ import {
Switch,
Platform,
Linking,
StyleSheet,
} from 'react-native';
import { BlueButton, SafeBlueArea, BlueCard, BlueSpacing20, BlueNavigationStyle, BlueText } from '../../BlueComponents';
import PropTypes from 'prop-types';
@ -30,6 +31,74 @@ const prompt = require('../../prompt');
const BlueApp = require('../../BlueApp');
const loc = require('../../loc');
const styles = StyleSheet.create({
root: {
flex: 1,
},
scrollViewContent: {
flexGrow: 1,
},
save: {
marginHorizontal: 16,
justifyContent: 'center',
alignItems: 'center',
},
saveText: {
color: '#0c2550',
},
address: {
alignItems: 'center',
flex: 1,
},
textLabel1: {
color: '#0c2550',
fontWeight: '500',
fontSize: 14,
marginVertical: 12,
},
textLabel2: {
color: '#0c2550',
fontWeight: '500',
fontSize: 14,
marginVertical: 16,
},
textValue: {
color: '#81868e',
fontWeight: '500',
fontSize: 14,
},
input: {
flexDirection: 'row',
borderColor: '#d2d2d2',
borderBottomColor: '#d2d2d2',
borderWidth: 1,
borderBottomWidth: 0.5,
backgroundColor: '#f5f5f5',
minHeight: 44,
height: 44,
alignItems: 'center',
borderRadius: 4,
},
inputText: {
flex: 1,
marginHorizontal: 8,
minHeight: 33,
},
hardware: {
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'space-between',
},
center: {
alignItems: 'center',
},
delete: {
color: '#d0021b',
fontSize: 15,
fontWeight: '500',
},
});
export default class WalletDetails extends Component {
static navigationOptions = ({ navigation }) => ({
...BlueNavigationStyle(),
@ -37,14 +106,14 @@ export default class WalletDetails extends Component {
headerRight: (
<TouchableOpacity
disabled={navigation.getParam('isLoading') === true}
style={{ marginHorizontal: 16, justifyContent: 'center', alignItems: 'center' }}
style={styles.save}
onPress={() => {
if (navigation.state.params.saveAction) {
navigation.getParam('saveAction')();
}
}}
>
<Text style={{ color: '#0c2550' }}>{loc.wallets.details.save}</Text>
<Text style={styles.saveText}>{loc.wallets.details.save}</Text>
</TouchableOpacity>
),
});
@ -143,17 +212,17 @@ export default class WalletDetails extends Component {
render() {
if (this.state.isLoading) {
return (
<View style={{ flex: 1 }}>
<View style={styles.root}>
<ActivityIndicator />
</View>
);
}
return (
<SafeBlueArea style={{ flex: 1 }}>
<SafeBlueArea style={styles.root}>
<TouchableWithoutFeedback onPress={Keyboard.dismiss} accessible={false}>
<KeyboardAvoidingView behavior="position">
<ScrollView contentContainerStyle={{ flexGrow: 1 }}>
<BlueCard style={{ alignItems: 'center', flex: 1 }}>
<ScrollView contentContainerStyle={styles.scrollViewContent}>
<BlueCard style={styles.address}>
{(() => {
if (
[LegacyWallet.type, SegwitBech32Wallet.type, SegwitP2SHWallet.type].includes(this.state.wallet.type) ||
@ -161,32 +230,15 @@ export default class WalletDetails extends Component {
) {
return (
<React.Fragment>
<Text style={{ color: '#0c2550', fontWeight: '500', fontSize: 14, marginVertical: 12 }}>
{loc.wallets.details.address.toLowerCase()}
</Text>
<Text style={{ color: '#81868e', fontWeight: '500', fontSize: 14 }}>{this.state.wallet.getAddress()}</Text>
<Text style={styles.textLabel1}>{loc.wallets.details.address.toLowerCase()}</Text>
<Text style={styles.textValue}>{this.state.wallet.getAddress()}</Text>
</React.Fragment>
);
}
})()}
<Text style={{ color: '#0c2550', fontWeight: '500', fontSize: 14, marginVertical: 16 }}>
{loc.wallets.add.wallet_name.toLowerCase()}
</Text>
<Text style={styles.textLabel2}>{loc.wallets.add.wallet_name.toLowerCase()}</Text>
<View
style={{
flexDirection: 'row',
borderColor: '#d2d2d2',
borderBottomColor: '#d2d2d2',
borderWidth: 1.0,
borderBottomWidth: 0.5,
backgroundColor: '#f5f5f5',
minHeight: 44,
height: 44,
alignItems: 'center',
borderRadius: 4,
}}
>
<View style={styles.input}>
<TextInput
placeholder={loc.send.details.note_placeholder}
value={this.state.walletName}
@ -200,21 +252,17 @@ export default class WalletDetails extends Component {
}
}}
numberOfLines={1}
style={{ flex: 1, marginHorizontal: 8, minHeight: 33 }}
style={styles.inputText}
editable={!this.state.isLoading}
underlineColorAndroid="transparent"
/>
</View>
<BlueSpacing20 />
<Text style={{ color: '#0c2550', fontWeight: '500', fontSize: 14, marginVertical: 12 }}>
{loc.wallets.details.type.toLowerCase()}
</Text>
<Text style={{ color: '#81868e', fontWeight: '500', fontSize: 14 }}>{this.state.wallet.typeReadable}</Text>
<Text style={styles.textLabel1}>{loc.wallets.details.type.toLowerCase()}</Text>
<Text style={styles.textValue}>{this.state.wallet.typeReadable}</Text>
{this.state.wallet.type === LightningCustodianWallet.type && (
<React.Fragment>
<Text style={{ color: '#0c2550', fontWeight: '500', fontSize: 14, marginVertical: 12 }}>
{loc.wallets.details.connected_to.toLowerCase()}
</Text>
<Text style={styles.textLabel1}>{loc.wallets.details.connected_to.toLowerCase()}</Text>
<BlueText>{this.state.wallet.getBaseURI()}</BlueText>
</React.Fragment>
)}
@ -222,10 +270,8 @@ export default class WalletDetails extends Component {
<BlueSpacing20 />
{this.state.wallet.type === WatchOnlyWallet.type && this.state.wallet.getSecret().startsWith('zpub') && (
<>
<Text style={{ color: '#0c2550', fontWeight: '500', fontSize: 14, marginVertical: 16 }}>
{loc.wallets.details.advanced.toLowerCase()}
</Text>
<View style={{ flexDirection: 'row', alignItems: 'center', justifyContent: 'space-between' }}>
<Text style={styles.textLabel2}>{loc.wallets.details.advanced.toLowerCase()}</Text>
<View style={styles.hardware}>
<BlueText>{loc.wallets.details.use_with_hardware_wallet}</BlueText>
<Switch
value={this.state.useWithHardwareWallet}
@ -233,12 +279,8 @@ export default class WalletDetails extends Component {
/>
</View>
<React.Fragment>
<Text style={{ color: '#0c2550', fontWeight: '500', fontSize: 14, marginVertical: 12 }}>
{loc.wallets.details.master_fingerprint.toLowerCase()}
</Text>
<Text style={{ color: '#81868e', fontWeight: '500', fontSize: 14 }}>
{this.state.wallet.getMasterFingerprintHex()}
</Text>
<Text style={styles.textLabel1}>{loc.wallets.details.master_fingerprint.toLowerCase()}</Text>
<Text style={styles.textValue}>{this.state.wallet.getMasterFingerprintHex()}</Text>
</React.Fragment>
<BlueSpacing20 />
</>
@ -281,7 +323,7 @@ export default class WalletDetails extends Component {
)}
<BlueSpacing20 />
<TouchableOpacity
style={{ alignItems: 'center' }}
style={styles.center}
onPress={() => {
ReactNativeHapticFeedback.trigger('notificationWarning', { ignoreAndroidSystemSettings: false });
Alert.alert(
@ -319,7 +361,7 @@ export default class WalletDetails extends Component {
);
}}
>
<Text style={{ color: '#d0021b', fontSize: 15, fontWeight: '500' }}>{loc.wallets.details.delete}</Text>
<Text style={styles.delete}>{loc.wallets.details.delete}</Text>
</TouchableOpacity>
</View>
</BlueCard>

View file

@ -1,5 +1,5 @@
import React, { Component } from 'react';
import { Dimensions, ScrollView, ActivityIndicator, View } from 'react-native';
import { Dimensions, ScrollView, ActivityIndicator, View, StyleSheet } from 'react-native';
import QRCode from 'react-native-qrcode-svg';
import { BlueSpacing20, SafeBlueArea, BlueNavigationStyle, BlueText, BlueCopyTextToClipboard, BlueCard } from '../../BlueComponents';
import PropTypes from 'prop-types';
@ -11,6 +11,33 @@ let BlueApp = require('../../BlueApp');
let loc = require('../../loc');
const { height, width } = Dimensions.get('window');
const styles = StyleSheet.create({
loading: {
flex: 1,
paddingTop: 20,
},
root: {
flex: 1,
},
scrollViewContent: {
alignItems: 'center',
justifyContent: 'center',
flexGrow: 1,
},
type: {
fontSize: 17,
fontWeight: '700',
color: '#0c2550',
},
secret: {
alignItems: 'center',
paddingHorizontal: 16,
fontSize: 16,
color: '#0C2550',
lineHeight: 24,
},
});
export default class WalletExport extends Component {
static navigationOptions = ({ navigation }) => ({
...BlueNavigationStyle(navigation, true),
@ -61,17 +88,17 @@ export default class WalletExport extends Component {
render() {
if (this.state.isLoading) {
return (
<View style={{ flex: 1, paddingTop: 20 }} onLayout={this.onLayout}>
<View style={styles.loading} onLayout={this.onLayout}>
<ActivityIndicator />
</View>
);
}
return (
<SafeBlueArea style={{ flex: 1 }}>
<ScrollView contentContainerStyle={{ alignItems: 'center', justifyContent: 'center', flexGrow: 1 }} onLayout={this.onLayout}>
<SafeBlueArea style={styles.root}>
<ScrollView contentContainerStyle={styles.scrollViewContent} onLayout={this.onLayout}>
<View>
<BlueText style={{ fontSize: 17, fontWeight: '700', color: '#0c2550' }}>{this.state.wallet.typeReadable}</BlueText>
<BlueText style={styles.type}>{this.state.wallet.typeReadable}</BlueText>
</View>
{(() => {
@ -99,9 +126,7 @@ export default class WalletExport extends Component {
{this.state.wallet.type === LightningCustodianWallet.type || this.state.wallet.type === WatchOnlyWallet.type ? (
<BlueCopyTextToClipboard text={this.state.wallet.getSecret()} />
) : (
<BlueText style={{ alignItems: 'center', paddingHorizontal: 16, fontSize: 16, color: '#0C2550', lineHeight: 24 }}>
{this.state.wallet.getSecret()}
</BlueText>
<BlueText style={styles.secret}>{this.state.wallet.getSecret()}</BlueText>
)}
</ScrollView>
</SafeBlueArea>

File diff suppressed because one or more lines are too long

View file

@ -1,6 +1,6 @@
/* global alert */
import React, { useEffect, useState } from 'react';
import { Platform, Dimensions, View, Keyboard } from 'react-native';
import { Platform, Dimensions, View, Keyboard, StyleSheet } from 'react-native';
import {
BlueFormMultiInput,
BlueButtonLink,
@ -18,6 +18,17 @@ import WalletImport from '../../class/walletImport';
let loc = require('../../loc');
const { width } = Dimensions.get('window');
const styles = StyleSheet.create({
root: {
flex: 1,
paddingTop: 40,
},
center: {
flex: 1,
alignItems: 'center',
},
});
const WalletsImport = () => {
const [isToolbarVisibleForAndroid, setIsToolbarVisibleForAndroid] = useState(false);
const [importText, setImportText] = useState(useNavigationParam('label') || '');
@ -67,7 +78,7 @@ const WalletsImport = () => {
};
return (
<SafeBlueArea forceInset={{ horizontal: 'always' }} style={{ flex: 1, paddingTop: 40 }}>
<SafeBlueArea forceInset={{ horizontal: 'always' }} style={styles.root}>
<BlueFormLabel>{loc.wallets.import.explanation}</BlueFormLabel>
<BlueSpacing20 />
<BlueFormMultiInput
@ -79,7 +90,7 @@ const WalletsImport = () => {
/>
<BlueSpacing20 />
<View style={{ flex: 1, alignItems: 'center' }}>
<View style={styles.center}>
<BlueButton
testID="DoImport"
disabled={importText.trim().length === 0}

View file

@ -257,18 +257,8 @@ export default class WalletsList extends Component {
renderListHeaderComponent = () => {
return (
<View style={{ backgroundColor: '#FFFFFF' }}>
<Text
style={{
paddingLeft: 16,
fontWeight: 'bold',
fontSize: 24,
marginVertical: 8,
color: BlueApp.settings.foregroundColor,
}}
>
{loc.transactions.list.title}
</Text>
<View style={styles.listHeader}>
<Text style={styles.listHeaderText}>{loc.transactions.list.title}</Text>
</View>
);
};
@ -283,7 +273,7 @@ export default class WalletsList extends Component {
renderTransactionListsRow = data => {
return (
<View style={{ marginHorizontal: 4 }}>
<View style={styles.transaction}>
<BlueTransactionListItem item={data.item} itemPriceUnit={data.item.walletPreferredBalanceUnit} />
</View>
);
@ -292,11 +282,7 @@ export default class WalletsList extends Component {
renderNavigationHeader = () => {
return (
<View style={styles.headerStyle}>
<TouchableOpacity
testID="SettingsButton"
style={{ marginHorizontal: 16 }}
onPress={() => this.props.navigation.navigate('Settings')}
>
<TouchableOpacity testID="SettingsButton" style={styles.headerTouch} onPress={() => this.props.navigation.navigate('Settings')}>
<Icon size={22} name="kebab-horizontal" type="octicon" color={BlueApp.settings.foregroundColor} />
</TouchableOpacity>
</View>
@ -310,23 +296,14 @@ export default class WalletsList extends Component {
onPress={() => {
this.props.navigation.navigate('HodlHodl', { fromWallet: this.state.wallet });
}}
style={{
flexDirection: 'row',
justifyContent: 'space-between',
alignItems: 'center',
marginHorizontal: 16,
marginVertical: 16,
backgroundColor: '#eef0f4',
padding: 16,
borderRadius: 6,
}}
style={styles.ltRoot}
>
<View style={{ flexDirection: 'column' }}>
<Text style={{ fontSize: 16, fontWeight: '600', color: '#0C2550' }}>Local Trader</Text>
<Text style={{ fontSize: 13, fontWeight: '500', color: '#9AA0AA' }}>A p2p exchange</Text>
<View style={styles.ltTextWrap}>
<Text style={styles.ltTextBig}>Local Trader</Text>
<Text style={styles.ltTextSmall}>A p2p exchange</Text>
</View>
<View style={{ flexDirection: 'column', backgroundColor: '#007AFF', borderRadius: 16 }}>
<Text style={{ paddingHorizontal: 16, paddingVertical: 8, fontSize: 13, color: '#fff', fontWeight: '600' }}>New</Text>
<View style={styles.ltButtonWrap}>
<Text style={styles.ltButton}>New</Text>
</View>
</TouchableOpacity>
);
@ -387,26 +364,9 @@ export default class WalletsList extends Component {
case WalletsListSections.TRANSACTIONS:
if (this.state.dataSource.length === 0 && !this.state.isLoading) {
return (
<View style={{ top: 80, height: 160, marginBottom: 80 }}>
<Text
style={{
fontSize: 18,
color: '#9aa0aa',
textAlign: 'center',
}}
>
{loc.wallets.list.empty_txs1}
</Text>
<Text
style={{
fontSize: 18,
color: '#9aa0aa',
textAlign: 'center',
fontWeight: '600',
}}
>
{loc.wallets.list.empty_txs2}
</Text>
<View style={styles.footerRoot}>
<Text style={styles.footerEmpty}>{loc.wallets.list.empty_txs1}</Text>
<Text style={styles.footerStart}>{loc.wallets.list.empty_txs2}</Text>
</View>
);
} else {
@ -420,18 +380,7 @@ export default class WalletsList extends Component {
renderScanButton = () => {
if (BlueApp.getWallets().length > 0 && !BlueApp.getWallets().some(wallet => wallet.type === PlaceholderWallet.type)) {
return (
<View
style={{
flexDirection: 'row',
alignSelf: 'center',
backgroundColor: 'transparent',
position: 'absolute',
bottom: 30,
borderRadius: 30,
minHeight: 48,
overflow: 'hidden',
}}
>
<View style={styles.scanButton}>
<BlueScanButton onPress={this.onScanButtonPressed} />
</View>
);
@ -461,7 +410,7 @@ export default class WalletsList extends Component {
render() {
return (
<View style={{ flex: 1 }}>
<View style={styles.root}>
<NavigationEvents
onDidFocus={() => {
this.redrawScreen();
@ -476,7 +425,7 @@ export default class WalletsList extends Component {
renderItem={this.renderSectionItem}
keyExtractor={this.sectionListKeyExtractor}
renderSectionHeader={this.renderSectionHeader}
contentInset={{ top: 0, left: 0, bottom: 60, right: 0 }}
contentInset={styles.scrollContent}
renderSectionFooter={this.renderSectionFooter}
sections={[
{ key: WalletsListSections.CAROUSEL, data: [WalletsListSections.CAROUSEL] },
@ -491,6 +440,15 @@ export default class WalletsList extends Component {
}
}
const styles = StyleSheet.create({
root: {
flex: 1,
},
scrollContent: {
top: 0,
left: 0,
bottom: 60,
right: 0,
},
wrapper: {
backgroundColor: '#FFFFFF',
flex: 1,
@ -515,6 +473,83 @@ const styles = StyleSheet.create({
},
}),
},
headerTouch: {
marginHorizontal: 16,
},
listHeaderText: {
paddingLeft: 16,
fontWeight: 'bold',
fontSize: 24,
marginVertical: 8,
color: BlueApp.settings.foregroundColor,
},
ltRoot: {
flexDirection: 'row',
justifyContent: 'space-between',
alignItems: 'center',
marginHorizontal: 16,
marginVertical: 16,
backgroundColor: '#eef0f4',
padding: 16,
borderRadius: 6,
},
ltTextWrap: {
flexDirection: 'column',
},
ltTextBig: {
fontSize: 16,
fontWeight: '600',
color: '#0C2550',
},
ltTextSmall: {
fontSize: 13,
fontWeight: '500',
color: '#9AA0AA',
},
ltButtonWrap: {
flexDirection: 'column',
backgroundColor: '#007AFF',
borderRadius: 16,
},
ltButton: {
paddingHorizontal: 16,
paddingVertical: 8,
fontSize: 13,
color: '#fff',
fontWeight: '600',
},
footerRoot: {
top: 80,
height: 160,
marginBottom: 80,
},
footerEmpty: {
fontSize: 18,
color: '#9aa0aa',
textAlign: 'center',
},
footerStart: {
fontSize: 18,
color: '#9aa0aa',
textAlign: 'center',
fontWeight: '600',
},
scanButton: {
flexDirection: 'row',
alignSelf: 'center',
backgroundColor: 'transparent',
position: 'absolute',
bottom: 30,
borderRadius: 30,
minHeight: 48,
overflow: 'hidden',
},
listHeader: {
backgroundColor: '#FFFFFF',
},
transaction: {
marginHorizontal: 4,
},
});
WalletsList.propTypes = {

View file

@ -1,10 +1,66 @@
import React, { useEffect, useState, useCallback } from 'react';
import { ActivityIndicator, View, BackHandler, Text, ScrollView } from 'react-native';
import { ActivityIndicator, View, BackHandler, Text, ScrollView, StyleSheet } from 'react-native';
import { BlueSpacing20, SafeBlueArea, BlueNavigationStyle, BlueText, BlueButton } from '../../BlueComponents';
import Privacy from '../../Privacy';
import { useNavigation, useNavigationParam } from 'react-navigation-hooks';
const loc = require('../../loc');
const styles = StyleSheet.create({
word: {
width: 'auto',
marginRight: 8,
marginBottom: 8,
backgroundColor: '#f5f5f5',
paddingTop: 6,
paddingBottom: 6,
paddingLeft: 8,
paddingRight: 8,
borderRadius: 4,
},
wortText: {
color: '#81868E',
fontWeight: 'bold',
},
loading: {
flex: 1,
paddingTop: 20,
},
flex: {
flex: 1,
},
scrollViewContent: {
justifyContent: 'space-between',
},
please: {
alignItems: 'center',
paddingHorizontal: 16,
},
successText: {
textAlign: 'center',
fontWeight: 'bold',
color: '#0C2550',
},
pleaseText: {
paddingBottom: 10,
paddingRight: 0,
paddingLeft: 0,
color: '#0C2550',
},
secret: {
flex: 1,
flexDirection: 'row',
justifyContent: 'center',
flexWrap: 'wrap',
marginTop: 14,
},
ok: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
flexWrap: 'wrap',
},
});
const PleaseBackup = () => {
const [isLoading, setIsLoading] = useState(true);
const words = useNavigationParam('secret').split(' ');
@ -28,21 +84,8 @@ const PleaseBackup = () => {
let component = [];
for (const [index, secret] of words.entries()) {
component.push(
<View
style={{
width: 'auto',
marginRight: 8,
marginBottom: 8,
backgroundColor: '#f5f5f5',
paddingTop: 6,
paddingBottom: 6,
paddingLeft: 8,
paddingRight: 8,
borderRadius: 4,
}}
key={`${secret}${index}`}
>
<Text style={{ color: '#81868E', fontWeight: 'bold' }}>
<View style={styles.word} key={`${secret}${index}`}>
<Text style={styles.wortText}>
{`${index}`}. {secret}
</Text>
</View>,
@ -52,30 +95,20 @@ const PleaseBackup = () => {
};
return isLoading ? (
<View style={{ flex: 1, paddingTop: 20 }}>
<View style={styles.loading}>
<ActivityIndicator />
</View>
) : (
<SafeBlueArea style={{ flex: 1 }}>
<ScrollView contentContainerStyle={{ justifyContent: 'space-between' }} testID="PleaseBackupScrollView">
<View style={{ alignItems: 'center', paddingHorizontal: 16 }}>
<BlueText style={{ textAlign: 'center', fontWeight: 'bold', color: '#0C2550' }}>{loc.pleasebackup.success}</BlueText>
<BlueText style={{ paddingBottom: 10, paddingRight: 0, paddingLeft: 0, color: '#0C2550' }}>{loc.pleasebackup.text}</BlueText>
<SafeBlueArea style={styles.flex}>
<ScrollView contentContainerStyle={styles.scrollViewContent} testID="PleaseBackupScrollView">
<View style={styles.please}>
<BlueText style={styles.successText}>{loc.pleasebackup.success}</BlueText>
<BlueText style={styles.pleaseText}>{loc.pleasebackup.text}</BlueText>
<View
style={{
flex: 1,
flexDirection: 'row',
justifyContent: 'center',
flexWrap: 'wrap',
marginTop: 14,
}}
>
{renderSecret()}
</View>
<View style={styles.secret}>{renderSecret()}</View>
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center', flexWrap: 'wrap' }}>
<View style={{ flex: 1 }}>
<View style={styles.ok}>
<View style={styles.flex}>
<BlueSpacing20 />
<BlueButton testID="PleasebackupOk" onPress={dismiss} title={loc.pleasebackup.ok} />
</View>

View file

@ -1,12 +1,21 @@
import React, { useState } from 'react';
import { useNavigation, useNavigationParam } from 'react-navigation-hooks';
import { View, Dimensions } from 'react-native';
import { View, Dimensions, StyleSheet } from 'react-native';
import { SafeBlueArea, BlueSpacing20, BlueCopyTextToClipboard, BlueButton, BlueCard, BlueTextCentered } from '../../BlueComponents';
import QRCode from 'react-native-qrcode-svg';
import { ScrollView } from 'react-native-gesture-handler';
const { height, width } = Dimensions.get('window');
const BlueApp = require('../../BlueApp');
const styles = StyleSheet.create({
root: {
flex: 1,
},
scrollViewContent: {
flexGrow: 1,
},
});
const PleaseBackupLNDHub = () => {
const wallet = useNavigationParam('wallet');
const navigation = useNavigation();
@ -18,8 +27,8 @@ const PleaseBackupLNDHub = () => {
};
return (
<SafeBlueArea style={{ flex: 1 }}>
<ScrollView centerContent contentContainerStyle={{ flexGrow: 1 }} onLayout={onLayout}>
<SafeBlueArea style={styles.root}>
<ScrollView centerContent contentContainerStyle={styles.scrollViewContent} onLayout={onLayout}>
<BlueCard>
<View>
<BlueTextCentered>

View file

@ -1,5 +1,5 @@
import React, { Component } from 'react';
import { View, ActivityIndicator, Image, Text } from 'react-native';
import { View, ActivityIndicator, Image, Text, StyleSheet } from 'react-native';
import { SafeBlueArea, BlueNavigationStyle } from '../../BlueComponents';
import SortableList from 'react-native-sortable-list';
import LinearGradient from 'react-native-linear-gradient';
@ -12,6 +12,59 @@ let EV = require('../../events');
let BlueApp = require('../../BlueApp');
let loc = require('../../loc/');
const styles = StyleSheet.create({
loading: {
flex: 1,
paddingTop: 20,
},
root: {
flex: 1,
},
itemRoot: {
backgroundColor: 'transparent',
padding: 10,
marginVertical: 17,
},
gradient: {
padding: 15,
borderRadius: 10,
minHeight: 164,
elevation: 5,
},
image: {
width: 99,
height: 94,
position: 'absolute',
bottom: 0,
right: 0,
},
transparentText: {
backgroundColor: 'transparent',
},
label: {
backgroundColor: 'transparent',
fontSize: 19,
color: '#fff',
},
balance: {
backgroundColor: 'transparent',
fontWeight: 'bold',
fontSize: 36,
color: '#fff',
},
latestTxLabel: {
backgroundColor: 'transparent',
fontSize: 13,
color: '#fff',
},
latestTxValue: {
backgroundColor: 'transparent',
fontWeight: 'bold',
fontSize: 16,
color: '#fff',
},
});
export default class ReorderWallets extends Component {
static navigationOptions = ({ navigation }) => ({
...BlueNavigationStyle(
@ -65,78 +118,27 @@ export default class ReorderWallets extends Component {
item = item.data;
return (
<View
shadowOpacity={40 / 100}
shadowOffset={{ width: 0, height: 0 }}
shadowRadius={5}
style={{ backgroundColor: 'transparent', padding: 10, marginVertical: 17 }}
>
<LinearGradient
shadowColor="#000000"
colors={WalletGradient.gradientsFor(item.type)}
style={{
padding: 15,
borderRadius: 10,
minHeight: 164,
elevation: 5,
}}
>
<View shadowOpacity={40 / 100} shadowOffset={{ width: 0, height: 0 }} shadowRadius={5} style={styles.itemRoot}>
<LinearGradient shadowColor="#000000" colors={WalletGradient.gradientsFor(item.type)} style={styles.gradient}>
<Image
source={
(LightningCustodianWallet.type === item.type && require('../../img/lnd-shape.png')) || require('../../img/btc-shape.png')
}
style={{
width: 99,
height: 94,
position: 'absolute',
bottom: 0,
right: 0,
}}
style={styles.image}
/>
<Text style={{ backgroundColor: 'transparent' }} />
<Text
numberOfLines={1}
style={{
backgroundColor: 'transparent',
fontSize: 19,
color: '#fff',
}}
>
<Text style={styles.transparentText} />
<Text numberOfLines={1} style={styles.label}>
{item.getLabel()}
</Text>
<Text
numberOfLines={1}
adjustsFontSizeToFit
style={{
backgroundColor: 'transparent',
fontWeight: 'bold',
fontSize: 36,
color: '#fff',
}}
>
<Text numberOfLines={1} adjustsFontSizeToFit style={styles.balance}>
{loc.formatBalance(Number(item.getBalance()), item.getPreferredBalanceUnit(), true)}
</Text>
<Text style={{ backgroundColor: 'transparent' }} />
<Text
numberOfLines={1}
style={{
backgroundColor: 'transparent',
fontSize: 13,
color: '#fff',
}}
>
<Text style={styles.transparentText} />
<Text numberOfLines={1} style={styles.latestTxLabel}>
{loc.wallets.list.latest_transaction}
</Text>
<Text
numberOfLines={1}
style={{
backgroundColor: 'transparent',
fontWeight: 'bold',
fontSize: 16,
color: '#fff',
}}
>
<Text numberOfLines={1} style={styles.latestTxValue}>
{loc.transactionTimeToReadable(item.getLatestTransactionTime())}
</Text>
</LinearGradient>
@ -147,7 +149,7 @@ export default class ReorderWallets extends Component {
render() {
if (this.state.isLoading) {
return (
<View style={{ flex: 1, paddingTop: 20 }}>
<View style={styles.loading}>
<ActivityIndicator />
</View>
);
@ -157,7 +159,7 @@ export default class ReorderWallets extends Component {
<SafeBlueArea>
<SortableList
ref={ref => (this.sortableList = ref)}
style={{ flex: 1 }}
style={styles.root}
data={this.state.data}
renderRow={this._renderItem}
onChangeOrder={() => {

View file

@ -1,6 +1,6 @@
/* eslint-disable react/prop-types */
import React, { useEffect, useState } from 'react';
import { View, ActivityIndicator, Image, Text, TouchableOpacity, FlatList } from 'react-native';
import { View, ActivityIndicator, Image, Text, TouchableOpacity, FlatList, StyleSheet } from 'react-native';
import { SafeBlueArea, BlueNavigationStyle, BlueText, BlueSpacing20, BluePrivateBalance } from '../../BlueComponents';
import LinearGradient from 'react-native-linear-gradient';
import { LightningCustodianWallet } from '../../class/lightning-custodian-wallet';
@ -11,6 +11,70 @@ import { useNavigationParam } from 'react-navigation-hooks';
const BlueApp = require('../../BlueApp');
const loc = require('../../loc');
const styles = StyleSheet.create({
root: {
flex: 1,
},
loading: {
flex: 1,
justifyContent: 'center',
alignContent: 'center',
paddingTop: 20,
},
itemRoot: {
backgroundColor: 'transparent',
padding: 10,
marginVertical: 17,
},
gradient: {
padding: 15,
borderRadius: 10,
minHeight: 164,
elevation: 5,
},
image: {
width: 99,
height: 94,
position: 'absolute',
bottom: 0,
right: 0,
},
transparentText: {
backgroundColor: 'transparent',
},
label: {
backgroundColor: 'transparent',
fontSize: 19,
color: '#fff',
},
balance: {
backgroundColor: 'transparent',
fontWeight: 'bold',
fontSize: 36,
color: '#fff',
},
latestTxLabel: {
backgroundColor: 'transparent',
fontSize: 13,
color: '#fff',
},
latestTxValue: {
backgroundColor: 'transparent',
fontWeight: 'bold',
fontSize: 16,
color: '#fff',
},
noWallets: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
paddingTop: 20,
},
center: {
textAlign: 'center',
},
});
const SelectWallet = () => {
const chainType = useNavigationParam('chainType');
const onWalletSelect = useNavigationParam('onWalletSelect');
@ -31,82 +95,31 @@ const SelectWallet = () => {
onWalletSelect(item);
}}
>
<View
shadowOpacity={40 / 100}
shadowOffset={{ width: 0, height: 0 }}
shadowRadius={5}
style={{ backgroundColor: 'transparent', padding: 10, marginVertical: 17 }}
>
<LinearGradient
shadowColor="#000000"
colors={WalletGradient.gradientsFor(item.type)}
style={{
padding: 15,
borderRadius: 10,
minHeight: 164,
elevation: 5,
}}
>
<View shadowOpacity={40 / 100} shadowOffset={{ width: 0, height: 0 }} shadowRadius={5} style={styles.itemRoot}>
<LinearGradient shadowColor="#000000" colors={WalletGradient.gradientsFor(item.type)} style={styles.gradient}>
<Image
source={
(LightningCustodianWallet.type === item.type && require('../../img/lnd-shape.png')) || require('../../img/btc-shape.png')
}
style={{
width: 99,
height: 94,
position: 'absolute',
bottom: 0,
right: 0,
}}
style={styles.image}
/>
<Text style={{ backgroundColor: 'transparent' }} />
<Text
numberOfLines={1}
style={{
backgroundColor: 'transparent',
fontSize: 19,
color: '#fff',
}}
>
<Text style={styles.transparentText} />
<Text numberOfLines={1} style={styles.label}>
{item.getLabel()}
</Text>
{item.hideBalance ? (
<BluePrivateBalance />
) : (
<Text
numberOfLines={1}
adjustsFontSizeToFit
style={{
backgroundColor: 'transparent',
fontWeight: 'bold',
fontSize: 36,
color: '#fff',
}}
>
<Text numberOfLines={1} adjustsFontSizeToFit style={styles.balance}>
{loc.formatBalance(Number(item.getBalance()), item.getPreferredBalanceUnit(), true)}
</Text>
)}
<Text style={{ backgroundColor: 'transparent' }} />
<Text
numberOfLines={1}
style={{
backgroundColor: 'transparent',
fontSize: 13,
color: '#fff',
}}
>
<Text style={styles.transparentText} />
<Text numberOfLines={1} style={styles.latestTxLabel}>
{loc.wallets.list.latest_transaction}
</Text>
<Text
numberOfLines={1}
style={{
backgroundColor: 'transparent',
fontWeight: 'bold',
fontSize: 16,
color: '#fff',
}}
>
<Text numberOfLines={1} style={styles.latestTxValue}>
{loc.transactionTimeToReadable(item.getLatestTransactionTime())}
</Text>
</LinearGradient>
@ -117,25 +130,23 @@ const SelectWallet = () => {
if (isLoading) {
return (
<View style={{ flex: 1, justifyContent: 'center', alignContent: 'center', paddingTop: 20 }}>
<View style={styles.loading}>
<ActivityIndicator />
</View>
);
} else if (data.length <= 0) {
return (
<SafeBlueArea style={{ flex: 1 }}>
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center', paddingTop: 20 }}>
<BlueText style={{ textAlign: 'center' }}>There are currently no Bitcoin wallets available.</BlueText>
<SafeBlueArea style={styles.root}>
<View style={styles.noWallets}>
<BlueText style={styles.center}>There are currently no Bitcoin wallets available.</BlueText>
<BlueSpacing20 />
<BlueText style={{ textAlign: 'center' }}>
A Bitcoin wallet is required to refill Lightning wallets. Please, create or import one.
</BlueText>
<BlueText style={styles.center}>A Bitcoin wallet is required to refill Lightning wallets. Please, create or import one.</BlueText>
</View>
</SafeBlueArea>
);
} else {
return (
<SafeBlueArea style={{ flex: 1 }}>
<SafeBlueArea style={styles.root}>
<FlatList extraData={data} data={data} renderItem={renderItem} keyExtractor={(_item, index) => `${index}`} />
</SafeBlueArea>
);

View file

@ -45,13 +45,144 @@ let EV = require('../../events');
let BlueElectrum = require('../../BlueElectrum');
const LocalQRCode = require('@remobile/react-native-qrcode-local-image');
const styles = StyleSheet.create({
flex: {
flex: 1,
},
scrollViewContent: {
flex: 1,
justifyContent: 'center',
paddingHorizontal: 16,
paddingVertical: 40,
},
modalContent: {
backgroundColor: '#FFFFFF',
padding: 22,
justifyContent: 'center',
alignItems: 'center',
borderTopLeftRadius: 16,
borderTopRightRadius: 16,
borderColor: 'rgba(0, 0, 0, 0.1)',
minHeight: 200,
height: 200,
},
advancedTransactionOptionsModalContent: {
backgroundColor: '#FFFFFF',
padding: 22,
borderTopLeftRadius: 16,
borderTopRightRadius: 16,
borderColor: 'rgba(0, 0, 0, 0.1)',
minHeight: 130,
},
bottomModal: {
justifyContent: 'flex-end',
margin: 0,
},
walletDetails: {
marginHorizontal: 16,
minWidth: 150,
justifyContent: 'center',
alignItems: 'flex-end',
},
activityIndicator: {
marginVertical: 20,
},
listHeader: {
flexDirection: 'row',
margin: 16,
justifyContent: 'space-evenly',
},
listHeaderText: {
flex: 1,
marginLeft: 16,
marginTop: 8,
marginBottom: 8,
fontWeight: 'bold',
fontSize: 24,
color: BlueApp.settings.foregroundColor,
},
marketplaceButton1: {
backgroundColor: '#f2f2f2',
borderRadius: 9,
minHeight: 49,
flex: 1,
paddingHorizontal: 8,
justifyContent: 'center',
flexDirection: 'row',
alignItems: 'center',
},
marketplaceButton2: {
marginLeft: 5,
backgroundColor: '#f2f2f2',
borderRadius: 9,
minHeight: 49,
flex: 1,
paddingHorizontal: 8,
justifyContent: 'center',
flexDirection: 'row',
alignItems: 'center',
},
marketpalceText1: {
color: '#062453',
fontSize: 18,
},
marketpalceText2: {
color: '#062453',
fontSize: 18,
marginHorizontal: 8,
},
item: {
marginHorizontal: 4,
},
list: {
backgroundColor: '#FFFFFF',
flex: 1,
},
emptyTxs: {
fontSize: 18,
color: '#9aa0aa',
textAlign: 'center',
marginVertical: 16,
},
emptyTxsLightning: {
fontSize: 18,
color: '#9aa0aa',
textAlign: 'center',
fontWeight: '600',
},
buyBitcoin: {
backgroundColor: '#007AFF',
minWidth: 260,
borderRadius: 8,
alignSelf: 'center',
paddingVertical: 14,
paddingHorizontal: 32,
},
buyBitcoinText: {
fontSize: 15,
color: '#fff',
textAlign: 'center',
fontWeight: '600',
},
floatButtons: {
flexDirection: 'row',
alignSelf: 'center',
backgroundColor: 'transparent',
position: 'absolute',
bottom: 30,
borderRadius: 30,
minHeight: 48,
overflow: 'hidden',
},
});
export default class WalletTransactions extends Component {
static navigationOptions = ({ navigation }) => {
return {
headerRight: (
<TouchableOpacity
disabled={navigation.getParam('isLoading') === true}
style={{ marginHorizontal: 16, minWidth: 150, justifyContent: 'center', alignItems: 'flex-end' }}
style={styles.walletDetails}
onPress={() =>
navigation.navigate('WalletDetails', {
wallet: navigation.state.params.wallet,
@ -211,13 +342,13 @@ export default class WalletTransactions extends Component {
renderListFooterComponent = () => {
// if not all txs rendered - display indicator
return (this.getTransactions(Infinity).length > this.state.limit && <ActivityIndicator style={{ marginVertical: 20 }} />) || <View />;
return (this.getTransactions(Infinity).length > this.state.limit && <ActivityIndicator style={styles.activityIndicator} />) || <View />;
};
renderListHeaderComponent = () => {
return (
<View style={{ flex: 1 }}>
<View style={{ flexDirection: 'row', margin: 16, justifyContent: 'space-evenly' }}>
<View style={styles.flex}>
<View style={styles.listHeader}>
{/*
Current logic - Onchain:
- Shows buy button on middle when empty
@ -238,19 +369,7 @@ export default class WalletTransactions extends Component {
{this.state.wallet.type === LightningCustodianWallet.type && this.renderMarketplaceButton()}
{this.state.wallet.type === LightningCustodianWallet.type && Platform.OS === 'ios' && this.renderLappBrowserButton()}
</View>
<Text
style={{
flex: 1,
marginLeft: 16,
marginTop: 8,
marginBottom: 8,
fontWeight: 'bold',
fontSize: 24,
color: BlueApp.settings.foregroundColor,
}}
>
{loc.transactions.list.title}
</Text>
<Text style={styles.listHeaderText}>{loc.transactions.list.title}</Text>
</View>
);
};
@ -333,18 +452,9 @@ export default class WalletTransactions extends Component {
this.props.navigation.navigate('Marketplace', { fromWallet: this.state.wallet });
}
}}
style={{
backgroundColor: '#f2f2f2',
borderRadius: 9,
minHeight: 49,
flex: 1,
paddingHorizontal: 8,
justifyContent: 'center',
flexDirection: 'row',
alignItems: 'center',
}}
style={styles.marketplaceButton1}
>
<Text style={{ color: '#062453', fontSize: 18 }}>marketplace</Text>
<Text style={styles.marketpalceText1}>marketplace</Text>
</TouchableOpacity>
),
ios:
@ -353,19 +463,10 @@ export default class WalletTransactions extends Component {
onPress={async () => {
Linking.openURL('https://bluewallet.io/marketplace/');
}}
style={{
backgroundColor: '#f2f2f2',
borderRadius: 9,
minHeight: 49,
flex: 1,
paddingHorizontal: 8,
justifyContent: 'center',
flexDirection: 'row',
alignItems: 'center',
}}
style={styles.marketplaceButton1}
>
<Icon name="external-link" size={18} type="font-awesome" color="#9aa0aa" />
<Text style={{ color: '#062453', fontSize: 18, marginHorizontal: 8 }}>marketplace</Text>
<Text style={styles.marketpalceText2}>marketplace</Text>
</TouchableOpacity>
) : null,
});
@ -381,19 +482,9 @@ export default class WalletTransactions extends Component {
url: 'https://duckduckgo.com',
});
}}
style={{
marginLeft: 5,
backgroundColor: '#f2f2f2',
borderRadius: 9,
minHeight: 49,
flex: 1,
paddingHorizontal: 8,
justifyContent: 'center',
flexDirection: 'row',
alignItems: 'center',
}}
style={styles.marketplaceButton2}
>
<Text style={{ color: '#062453', fontSize: 18 }}>LApp Browser</Text>
<Text style={styles.marketpalceText1}>LApp Browser</Text>
</TouchableOpacity>
);
};
@ -405,26 +496,9 @@ export default class WalletTransactions extends Component {
wallet: this.state.wallet,
})
}
style={{
marginLeft: 5,
backgroundColor: '#f2f2f2',
borderRadius: 9,
minHeight: 49,
flex: 1,
paddingHorizontal: 8,
justifyContent: 'center',
flexDirection: 'row',
alignItems: 'center',
}}
style={styles.marketplaceButton2}
>
<Text
style={{
color: '#062453',
fontSize: 18,
}}
>
{loc.wallets.list.tap_here_to_buy}
</Text>
<Text style={styles.marketpalceText1}>{loc.wallets.list.tap_here_to_buy}</Text>
</TouchableOpacity>
);
};
@ -471,7 +545,7 @@ export default class WalletTransactions extends Component {
renderItem = item => {
return (
<View style={{ marginHorizontal: 4 }}>
<View style={styles.item}>
<BlueTransactionListItem
item={item.item}
itemPriceUnit={this.state.wallet.getPreferredBalanceUnit()}
@ -574,7 +648,7 @@ export default class WalletTransactions extends Component {
render() {
const { navigate } = this.props.navigation;
return (
<View style={{ flex: 1 }}>
<View style={styles.flex}>
{this.state.wallet.chain === Chain.ONCHAIN && this.state.isHandOffUseEnabled && (
<Handoff
title={`Bitcoin Wallet ${this.state.wallet.getLabel()}`}
@ -615,7 +689,7 @@ export default class WalletTransactions extends Component {
}
}}
/>
<View style={{ backgroundColor: '#FFFFFF', flex: 1 }}>
<View style={styles.list}>
<FlatList
ListHeaderComponent={this.renderListHeaderComponent}
onEndReachedThreshold={0.3}
@ -636,33 +710,11 @@ export default class WalletTransactions extends Component {
}}
ListFooterComponent={this.renderListFooterComponent}
ListEmptyComponent={
<ScrollView
style={{ flex: 1 }}
contentContainerStyle={{ flex: 1, justifyContent: 'center', paddingHorizontal: 16, paddingVertical: 40 }}
>
<Text
numberOfLines={0}
style={{
fontSize: 18,
color: '#9aa0aa',
textAlign: 'center',
marginVertical: 16,
}}
>
<ScrollView style={styles.flex} contentContainerStyle={styles.scrollViewContent}>
<Text numberOfLines={0} style={styles.emptyTxs}>
{(this.isLightning() && loc.wallets.list.empty_txs1_lightning) || loc.wallets.list.empty_txs1}
</Text>
{this.isLightning() && (
<Text
style={{
fontSize: 18,
color: '#9aa0aa',
textAlign: 'center',
fontWeight: '600',
}}
>
{loc.wallets.list.empty_txs2_lightning}
</Text>
)}
{this.isLightning() && <Text style={styles.emptyTxsLightning}>{loc.wallets.list.empty_txs2_lightning}</Text>}
{!this.isLightning() && (
<TouchableOpacity
@ -671,25 +723,9 @@ export default class WalletTransactions extends Component {
wallet: this.state.wallet,
})
}
style={{
backgroundColor: '#007AFF',
minWidth: 260,
borderRadius: 8,
alignSelf: 'center',
paddingVertical: 14,
paddingHorizontal: 32,
}}
style={styles.buyBitcoin}
>
<Text
style={{
fontSize: 15,
color: '#fff',
textAlign: 'center',
fontWeight: '600',
}}
>
{loc.wallets.list.tap_here_to_buy}
</Text>
<Text style={styles.buyBitcoinText}>{loc.wallets.list.tap_here_to_buy}</Text>
</TouchableOpacity>
)}
</ScrollView>
@ -705,18 +741,7 @@ export default class WalletTransactions extends Component {
/>
{this.renderManageFundsModal()}
</View>
<View
style={{
flexDirection: 'row',
alignSelf: 'center',
backgroundColor: 'transparent',
position: 'absolute',
bottom: 30,
borderRadius: 30,
minHeight: 48,
overflow: 'hidden',
}}
>
<View style={styles.floatButtons}>
{(() => {
if (this.state.wallet.allowReceive()) {
return (
@ -792,32 +817,6 @@ export default class WalletTransactions extends Component {
}
}
const styles = StyleSheet.create({
modalContent: {
backgroundColor: '#FFFFFF',
padding: 22,
justifyContent: 'center',
alignItems: 'center',
borderTopLeftRadius: 16,
borderTopRightRadius: 16,
borderColor: 'rgba(0, 0, 0, 0.1)',
minHeight: 200,
height: 200,
},
advancedTransactionOptionsModalContent: {
backgroundColor: '#FFFFFF',
padding: 22,
borderTopLeftRadius: 16,
borderTopRightRadius: 16,
borderColor: 'rgba(0, 0, 0, 0.1)',
minHeight: 130,
},
bottomModal: {
justifyContent: 'flex-end',
margin: 0,
},
});
WalletTransactions.propTypes = {
navigation: PropTypes.shape({
navigate: PropTypes.func,

View file

@ -1,5 +1,5 @@
import React, { Component } from 'react';
import { Dimensions, ActivityIndicator, View } from 'react-native';
import { Dimensions, ActivityIndicator, View, StyleSheet } from 'react-native';
import QRCode from 'react-native-qrcode-svg';
import { BlueSpacing20, SafeBlueArea, BlueText, BlueNavigationStyle, BlueCopyTextToClipboard } from '../../BlueComponents';
import PropTypes from 'prop-types';
@ -10,6 +10,18 @@ let BlueApp = require('../../BlueApp');
let loc = require('../../loc');
const { height, width } = Dimensions.get('window');
const styles = StyleSheet.create({
root: {
flex: 1,
paddingTop: 20,
},
container: {
alignItems: 'center',
flex: 1,
justifyContent: 'center',
},
});
export default class WalletXpub extends Component {
static navigationOptions = ({ navigation }) => ({
...BlueNavigationStyle(navigation, true),
@ -66,15 +78,15 @@ export default class WalletXpub extends Component {
render() {
if (this.state.isLoading) {
return (
<View style={{ flex: 1, paddingTop: 20 }}>
<View style={styles.root}>
<ActivityIndicator />
</View>
);
}
return (
<SafeBlueArea style={{ flex: 1, paddingTop: 20 }}>
<View style={{ alignItems: 'center', flex: 1, justifyContent: 'center' }} onLayout={this.onLayout}>
<SafeBlueArea style={styles.root}>
<View style={styles.container} onLayout={this.onLayout}>
<View>
<BlueText>{this.state.wallet.typeReadable}</BlueText>
</View>