mirror of
https://github.com/BlueWallet/BlueWallet.git
synced 2025-02-20 14:05:27 +01:00
REF: move all inline styles to StyleSheet.create
This commit is contained in:
parent
6a6ac478cc
commit
68e10cd7f1
45 changed files with 2714 additions and 1597 deletions
|
@ -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';
|
||||
|
@ -30,9 +30,9 @@ var webln = {
|
|||
window.ReactNativeWebView.postMessage(JSON.stringify({ sendPayment: paymentRequest }));
|
||||
return new Promise(function(resolve, reject) {
|
||||
/* nop. intentionally, forever hang promise.
|
||||
lapp page usually asynchroniously checks payment itself, via ajax,
|
||||
so atm there's no need to pass payment preimage from RN to webview and fullfill promise.
|
||||
might change in future */
|
||||
lapp page usually asynchroniously checks payment itself, via ajax,
|
||||
so atm there's no need to pass payment preimage from RN to webview and fullfill promise.
|
||||
might change in future */
|
||||
});
|
||||
},
|
||||
makeInvoice: function(RequestInvoiceArgs) {
|
||||
|
@ -90,51 +90,51 @@ bluewalletResponses = {};
|
|||
|
||||
|
||||
webln = {
|
||||
enable : function () {
|
||||
window.ReactNativeWebView.postMessage(JSON.stringify({'enable': true}));
|
||||
return new Promise(function(resolve, reject){
|
||||
resolve(true);
|
||||
})
|
||||
},
|
||||
getInfo : function () {
|
||||
window.ReactNativeWebView.postMessage('getInfo');
|
||||
return new Promise(function(resolve, reject){
|
||||
reject('not implemented');
|
||||
})
|
||||
},
|
||||
sendPayment: function(paymentRequest) {
|
||||
window.ReactNativeWebView.postMessage(JSON.stringify({ sendPayment: paymentRequest }));
|
||||
return new Promise(function(resolve, reject) {
|
||||
/* nop. intentionally, forever hang promise.
|
||||
lapp page usually asynchroniously checks payment itself, via ajax,
|
||||
so atm there's no need to pass payment preimage from RN to webview and fullfill promise.
|
||||
might change in future */
|
||||
});
|
||||
},
|
||||
makeInvoice: function (RequestInvoiceArgs) {
|
||||
var id = Math.random();
|
||||
window.ReactNativeWebView.postMessage(JSON.stringify({makeInvoice: RequestInvoiceArgs, id: id}));
|
||||
return new Promise(function(resolve, reject) {
|
||||
var interval = setInterval(function () {
|
||||
if (bluewalletResponses[id]) {
|
||||
clearInterval(interval);
|
||||
resolve(bluewalletResponses[id]);
|
||||
}
|
||||
}, 1000);
|
||||
});
|
||||
},
|
||||
signMessage: function () {
|
||||
window.ReactNativeWebView.postMessage('signMessage');
|
||||
return new Promise(function(resolve, reject){
|
||||
reject('not implemented');
|
||||
})
|
||||
},
|
||||
verifyMessage: function () {
|
||||
window.ReactNativeWebView.postMessage('verifyMessage');
|
||||
return new Promise(function(resolve, reject){
|
||||
reject('not implemented');
|
||||
})
|
||||
},
|
||||
enable : function () {
|
||||
window.ReactNativeWebView.postMessage(JSON.stringify({'enable': true}));
|
||||
return new Promise(function(resolve, reject){
|
||||
resolve(true);
|
||||
})
|
||||
},
|
||||
getInfo : function () {
|
||||
window.ReactNativeWebView.postMessage('getInfo');
|
||||
return new Promise(function(resolve, reject){
|
||||
reject('not implemented');
|
||||
})
|
||||
},
|
||||
sendPayment: function(paymentRequest) {
|
||||
window.ReactNativeWebView.postMessage(JSON.stringify({ sendPayment: paymentRequest }));
|
||||
return new Promise(function(resolve, reject) {
|
||||
/* nop. intentionally, forever hang promise.
|
||||
lapp page usually asynchroniously checks payment itself, via ajax,
|
||||
so atm there's no need to pass payment preimage from RN to webview and fullfill promise.
|
||||
might change in future */
|
||||
});
|
||||
},
|
||||
makeInvoice: function (RequestInvoiceArgs) {
|
||||
var id = Math.random();
|
||||
window.ReactNativeWebView.postMessage(JSON.stringify({makeInvoice: RequestInvoiceArgs, id: id}));
|
||||
return new Promise(function(resolve, reject) {
|
||||
var interval = setInterval(function () {
|
||||
if (bluewalletResponses[id]) {
|
||||
clearInterval(interval);
|
||||
resolve(bluewalletResponses[id]);
|
||||
}
|
||||
}, 1000);
|
||||
});
|
||||
},
|
||||
signMessage: function () {
|
||||
window.ReactNativeWebView.postMessage('signMessage');
|
||||
return new Promise(function(resolve, reject){
|
||||
reject('not implemented');
|
||||
})
|
||||
},
|
||||
verifyMessage: function () {
|
||||
window.ReactNativeWebView.postMessage('verifyMessage');
|
||||
return new Promise(function(resolve, reject){
|
||||
reject('not implemented');
|
||||
})
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
|
@ -142,17 +142,17 @@ webln = {
|
|||
|
||||
/* listening to events that might come from RN: */
|
||||
document.addEventListener("message", function(event) {
|
||||
window.ReactNativeWebView.postMessage("inside webview, received post message: " + event.detail);
|
||||
var json;
|
||||
try {
|
||||
json = JSON.parse(event.detail);
|
||||
} catch (_) {}
|
||||
window.ReactNativeWebView.postMessage("inside webview, received post message: " + event.detail);
|
||||
var json;
|
||||
try {
|
||||
json = JSON.parse(event.detail);
|
||||
} catch (_) {}
|
||||
|
||||
if (json && json.bluewalletResponse) {
|
||||
/* this is an answer to one of our inside-webview calls.
|
||||
we store it in answers hashmap for someone who cares about it */
|
||||
bluewalletResponses[json.id] = json.bluewalletResponse
|
||||
}
|
||||
if (json && json.bluewalletResponse) {
|
||||
/* this is an answer to one of our inside-webview calls.
|
||||
we store it in answers hashmap for someone who cares about it */
|
||||
bluewalletResponses[json.id] = json.bluewalletResponse
|
||||
}
|
||||
|
||||
}, false);
|
||||
|
||||
|
@ -160,50 +160,119 @@ document.addEventListener("message", function(event) {
|
|||
|
||||
|
||||
function tryToPay(invoice) {
|
||||
window.ReactNativeWebView.postMessage(JSON.stringify({sendPayment:invoice}));
|
||||
window.ReactNativeWebView.postMessage(JSON.stringify({sendPayment:invoice}));
|
||||
}
|
||||
|
||||
/* for non-webln compatible pages we do it oldschool,
|
||||
searching for all bolt11 manually */
|
||||
searching for all bolt11 manually */
|
||||
|
||||
setInterval(function() {
|
||||
window.ReactNativeWebView.postMessage('interval');
|
||||
|
||||
var searchText = "lnbc";
|
||||
var searchText = "lnbc";
|
||||
|
||||
var aTags = document.getElementsByTagName("span");
|
||||
var i;
|
||||
for (i = 0; i < aTags.length; i++) {
|
||||
if (aTags[i].textContent.indexOf(searchText) === 0) {
|
||||
tryToPay(aTags[i].textContent);
|
||||
}
|
||||
}
|
||||
var aTags = document.getElementsByTagName("span");
|
||||
var i;
|
||||
for (i = 0; i < aTags.length; i++) {
|
||||
if (aTags[i].textContent.indexOf(searchText) === 0) {
|
||||
tryToPay(aTags[i].textContent);
|
||||
}
|
||||
}
|
||||
|
||||
/* ------------------------- */
|
||||
/* ------------------------- */
|
||||
|
||||
aTags = document.getElementsByTagName("input");
|
||||
for (i = 0; i < aTags.length; i++) {
|
||||
if (aTags[i].value.indexOf(searchText) === 0) {
|
||||
tryToPay(aTags[i].value);
|
||||
}
|
||||
}
|
||||
aTags = document.getElementsByTagName("input");
|
||||
for (i = 0; i < aTags.length; i++) {
|
||||
if (aTags[i].value.indexOf(searchText) === 0) {
|
||||
tryToPay(aTags[i].value);
|
||||
}
|
||||
}
|
||||
|
||||
/* ------------------------- */
|
||||
/* ------------------------- */
|
||||
|
||||
aTags = document.getElementsByTagName("a");
|
||||
searchText = "lightning:lnbc";
|
||||
aTags = document.getElementsByTagName("a");
|
||||
searchText = "lightning:lnbc";
|
||||
|
||||
|
||||
for (i = 0; i < aTags.length; i++) {
|
||||
var href = aTags[i].getAttribute('href') + '';
|
||||
if (href.indexOf(searchText) === 0) {
|
||||
tryToPay(href.replace('lightning:', ''));
|
||||
}
|
||||
}
|
||||
for (i = 0; i < aTags.length; i++) {
|
||||
var href = aTags[i].getAttribute('href') + '';
|
||||
if (href.indexOf(searchText) === 0) {
|
||||
tryToPay(href.replace('lightning:', ''));
|
||||
}
|
||||
}
|
||||
|
||||
}, 1000);
|
||||
|
||||
`;
|
||||
`;
|
||||
|
||||
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 }) => ({
|
||||
|
@ -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>
|
||||
)}
|
||||
|
|
|
@ -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}
|
||||
|
|
|
@ -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',
|
||||
|
|
|
@ -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}
|
||||
/>
|
||||
|
|
|
@ -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 ? (
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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,
|
||||
},
|
||||
});
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
)}
|
||||
|
|
|
@ -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 }) {
|
||||
|
|
|
@ -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 = {
|
||||
|
|
|
@ -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 = {
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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'}
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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 && (
|
||||
<>
|
||||
|
|
|
@ -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')} />
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
);
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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"
|
||||
/>
|
||||
|
|
|
@ -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 && (
|
||||
<>
|
||||
|
|
|
@ -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}
|
||||
|
|
|
@ -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>
|
||||
);
|
||||
};
|
||||
|
||||
|
|
|
@ -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"
|
||||
/>
|
||||
|
|
|
@ -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>
|
||||
);
|
||||
};
|
||||
|
||||
|
|
|
@ -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 />
|
||||
|
|
|
@ -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} />
|
||||
|
|
|
@ -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.',
|
||||
|
|
|
@ -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 />
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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');
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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
|
@ -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}
|
||||
|
|
|
@ -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 = {
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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={() => {
|
||||
|
|
|
@ -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>
|
||||
);
|
||||
|
|
|
@ -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
|
||||
|
@ -230,7 +361,7 @@ export default class WalletTransactions extends Component {
|
|||
- Shows Marketplace button to open in browser (iOS)
|
||||
|
||||
The idea is to avoid showing on iOS an appstore/market style app that goes against the TOS.
|
||||
|
||||
|
||||
*/}
|
||||
{this.state.wallet.getTransactions().length > 0 &&
|
||||
this.state.wallet.type !== LightningCustodianWallet.type &&
|
||||
|
@ -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,
|
||||
|
|
|
@ -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>
|
||||
|
|
Loading…
Add table
Reference in a new issue