mirror of
https://github.com/BlueWallet/BlueWallet.git
synced 2025-02-23 15:20:55 +01:00
Merge branch 'master' into electrum-improve
This commit is contained in:
commit
4089933dbe
37 changed files with 3287 additions and 2579 deletions
|
@ -67,4 +67,4 @@ suppress_comment=\\(.\\|\n\\)*\\$FlowFixedInNextDeploy
|
||||||
suppress_comment=\\(.\\|\n\\)*\\$FlowExpectedError
|
suppress_comment=\\(.\\|\n\\)*\\$FlowExpectedError
|
||||||
|
|
||||||
[version]
|
[version]
|
||||||
^0.85.0
|
^0.86.0
|
||||||
|
|
4
.gitignore
vendored
4
.gitignore
vendored
|
@ -54,3 +54,7 @@ buck-out/
|
||||||
|
|
||||||
# Bundle artifact
|
# Bundle artifact
|
||||||
*.jsbundle
|
*.jsbundle
|
||||||
|
|
||||||
|
#BlueWallet
|
||||||
|
release-notes.json
|
||||||
|
release-notes.txt
|
|
@ -4,7 +4,7 @@
|
||||||
import React, { Component } from 'react';
|
import React, { Component } from 'react';
|
||||||
import Ionicons from 'react-native-vector-icons/Ionicons';
|
import Ionicons from 'react-native-vector-icons/Ionicons';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import { Icon, Button, FormLabel, FormInput, Text, Header, List, ListItem } from 'react-native-elements';
|
import { Icon, FormLabel, FormInput, Text, Header, List, ListItem } from 'react-native-elements';
|
||||||
import {
|
import {
|
||||||
TouchableOpacity,
|
TouchableOpacity,
|
||||||
TouchableWithoutFeedback,
|
TouchableWithoutFeedback,
|
||||||
|
@ -16,9 +16,9 @@ import {
|
||||||
Dimensions,
|
Dimensions,
|
||||||
Image,
|
Image,
|
||||||
SafeAreaView,
|
SafeAreaView,
|
||||||
|
InputAccessoryView,
|
||||||
Clipboard,
|
Clipboard,
|
||||||
Platform,
|
Platform,
|
||||||
LayoutAnimation,
|
|
||||||
TextInput,
|
TextInput,
|
||||||
} from 'react-native';
|
} from 'react-native';
|
||||||
import LinearGradient from 'react-native-linear-gradient';
|
import LinearGradient from 'react-native-linear-gradient';
|
||||||
|
@ -44,10 +44,11 @@ if (aspectRatio > 1.6) {
|
||||||
|
|
||||||
export class BlueButton extends Component {
|
export class BlueButton extends Component {
|
||||||
render() {
|
render() {
|
||||||
const disabled = this.props.hasOwnProperty('disabled');
|
|
||||||
let backgroundColor = '#ccddf9';
|
let backgroundColor = '#ccddf9';
|
||||||
if (disabled === true) {
|
let fontColor = '#0c2550';
|
||||||
backgroundColor = '#99a0ab';
|
if (this.props.hasOwnProperty('disabled') && this.props.disabled === true) {
|
||||||
|
backgroundColor = '#eef0f4';
|
||||||
|
fontColor = '#9aa0aa';
|
||||||
}
|
}
|
||||||
return (
|
return (
|
||||||
<TouchableOpacity
|
<TouchableOpacity
|
||||||
|
@ -55,7 +56,7 @@ export class BlueButton extends Component {
|
||||||
flex: 1,
|
flex: 1,
|
||||||
borderWidth: 0.7,
|
borderWidth: 0.7,
|
||||||
borderColor: 'transparent',
|
borderColor: 'transparent',
|
||||||
backgroundColor: this.props.hasOwnProperty('backgroundColor') ? this.props.backgroundColor : backgroundColor,
|
backgroundColor: backgroundColor,
|
||||||
minHeight: 45,
|
minHeight: 45,
|
||||||
height: 45,
|
height: 45,
|
||||||
maxHeight: 45,
|
maxHeight: 45,
|
||||||
|
@ -68,7 +69,7 @@ export class BlueButton extends Component {
|
||||||
>
|
>
|
||||||
<View style={{ flexDirection: 'row', justifyContent: 'center', alignItems: 'center' }}>
|
<View style={{ flexDirection: 'row', justifyContent: 'center', alignItems: 'center' }}>
|
||||||
{this.props.icon && <Icon name={this.props.icon.name} type={this.props.icon.type} color={this.props.icon.color} />}
|
{this.props.icon && <Icon name={this.props.icon.name} type={this.props.icon.type} color={this.props.icon.color} />}
|
||||||
{this.props.title && <Text style={{ marginHorizontal: 8, fontSize: 16, color: '#0c2550' }}>{this.props.title}</Text>}
|
{this.props.title && <Text style={{ marginHorizontal: 8, fontSize: 16, color: fontColor }}>{this.props.title}</Text>}
|
||||||
</View>
|
</View>
|
||||||
</TouchableOpacity>
|
</TouchableOpacity>
|
||||||
);
|
);
|
||||||
|
@ -145,26 +146,18 @@ export class LightningButton extends Component {
|
||||||
|
|
||||||
export class BlueButtonLink extends Component {
|
export class BlueButtonLink extends Component {
|
||||||
render() {
|
render() {
|
||||||
// eslint-disable-next-line
|
|
||||||
this.props.buttonStyle = this.props.buttonStyle || {};
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Button
|
<TouchableOpacity
|
||||||
activeOpacity={0.1}
|
|
||||||
delayPressIn={0}
|
|
||||||
{...this.props}
|
|
||||||
style={{
|
style={{
|
||||||
marginTop: 20,
|
minHeight: 60,
|
||||||
borderWidth: 0.7,
|
minWidth: 100,
|
||||||
borderColor: 'transparent',
|
height: 60,
|
||||||
|
justifyContent: 'center',
|
||||||
}}
|
}}
|
||||||
buttonStyle={{
|
{...this.props}
|
||||||
height: 45,
|
>
|
||||||
width: width / 1.5,
|
<Text style={{ color: '#0c2550', textAlign: 'center', fontSize: 16 }}>{this.props.title}</Text>
|
||||||
}}
|
</TouchableOpacity>
|
||||||
backgroundColor="transparent"
|
|
||||||
color="#0c2550"
|
|
||||||
/>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -208,36 +201,32 @@ export class BlueCopyTextToClipboard extends Component {
|
||||||
text: '',
|
text: '',
|
||||||
};
|
};
|
||||||
|
|
||||||
state = { hasTappedText: false };
|
constructor(props) {
|
||||||
|
super(props);
|
||||||
constructor() {
|
if (Platform.OS === 'android') {
|
||||||
super();
|
UIManager.setLayoutAnimationEnabledExperimental && UIManager.setLayoutAnimationEnabledExperimental(true);
|
||||||
if (Platform.OS === 'android') UIManager.setLayoutAnimationEnabledExperimental && UIManager.setLayoutAnimationEnabledExperimental(true);
|
}
|
||||||
|
this.state = { hasTappedText: false, address: props.text };
|
||||||
}
|
}
|
||||||
|
|
||||||
copyToClipboard = () => {
|
copyToClipboard = () => {
|
||||||
LayoutAnimation.configureNext(LayoutAnimation.Presets.spring, () => {
|
this.setState({ hasTappedText: true }, () => {
|
||||||
Clipboard.setString(this.props.text);
|
Clipboard.setString(this.props.text);
|
||||||
setTimeout(() => {
|
this.setState({ address: loc.wallets.xpub.copiedToClipboard }, () => {
|
||||||
LayoutAnimation.configureNext(LayoutAnimation.Presets.spring);
|
setTimeout(() => {
|
||||||
this.setState({ hasTappedText: false });
|
this.setState({ hasTappedText: false, address: this.props.text });
|
||||||
}, 1000);
|
}, 1000);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
this.setState({ hasTappedText: true });
|
|
||||||
};
|
};
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<View style={{ justifyContent: 'center', alignItems: 'center', paddingHorizontal: 16 }}>
|
<View style={{ justifyContent: 'center', alignItems: 'center', paddingHorizontal: 16 }}>
|
||||||
<TouchableOpacity onPress={this.copyToClipboard} disabled={this.state.hasTappedText}>
|
<TouchableOpacity onPress={this.copyToClipboard} disabled={this.state.hasTappedText}>
|
||||||
<Text style={styleCopyTextToClipboard.address} numberOfLines={0}>
|
<Animated.Text style={styleCopyTextToClipboard.address} numberOfLines={0}>
|
||||||
{this.props.text}
|
{this.state.address}
|
||||||
</Text>
|
</Animated.Text>
|
||||||
{this.state.hasTappedText && (
|
|
||||||
<Text style={styleCopyTextToClipboard.address} numberOfLines={0}>
|
|
||||||
{loc.wallets.xpub.copiedToClipboard}
|
|
||||||
</Text>
|
|
||||||
)}
|
|
||||||
</TouchableOpacity>
|
</TouchableOpacity>
|
||||||
</View>
|
</View>
|
||||||
);
|
);
|
||||||
|
@ -555,6 +544,27 @@ export class BlueList extends Component {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export class BlueUseAllFundsButton extends Component {
|
||||||
|
static InputAccessoryViewID = 'useMaxInputAccessoryViewID';
|
||||||
|
static propTypes = {
|
||||||
|
wallet: PropTypes.shape().isRequired,
|
||||||
|
onUseAllPressed: PropTypes.func.isRequired,
|
||||||
|
};
|
||||||
|
|
||||||
|
render() {
|
||||||
|
return (
|
||||||
|
<InputAccessoryView nativeID={BlueUseAllFundsButton.InputAccessoryViewID}>
|
||||||
|
<View style={{ flex: 1, flexDirection: 'row', justifyContent: 'space-between', alignItems: 'center' }}>
|
||||||
|
<Text style={{ color: '#9aa0aa', fontSize: 16, marginHorizontal: 8 }}>
|
||||||
|
Total: {this.props.wallet.getBalance()} {BitcoinUnit.BTC}
|
||||||
|
</Text>
|
||||||
|
<BlueButtonLink title="Use All" onPress={this.props.onUseAllPressed} />
|
||||||
|
</View>
|
||||||
|
</InputAccessoryView>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export class BlueLoading extends Component {
|
export class BlueLoading extends Component {
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
|
@ -580,7 +590,7 @@ const stylesBlueIcon = StyleSheet.create({
|
||||||
paddingHorizontal: 14,
|
paddingHorizontal: 14,
|
||||||
paddingTop: 8,
|
paddingTop: 8,
|
||||||
},
|
},
|
||||||
boxIncomming: {
|
boxIncoming: {
|
||||||
position: 'relative',
|
position: 'relative',
|
||||||
},
|
},
|
||||||
ball: {
|
ball: {
|
||||||
|
@ -589,14 +599,14 @@ const stylesBlueIcon = StyleSheet.create({
|
||||||
borderRadius: 15,
|
borderRadius: 15,
|
||||||
backgroundColor: '#ccddf9',
|
backgroundColor: '#ccddf9',
|
||||||
},
|
},
|
||||||
ballIncomming: {
|
ballIncoming: {
|
||||||
width: 30,
|
width: 30,
|
||||||
height: 30,
|
height: 30,
|
||||||
borderRadius: 15,
|
borderRadius: 15,
|
||||||
backgroundColor: '#d2f8d6',
|
backgroundColor: '#d2f8d6',
|
||||||
transform: [{ rotate: '-45deg' }],
|
transform: [{ rotate: '-45deg' }],
|
||||||
},
|
},
|
||||||
ballIncommingWithoutRotate: {
|
ballIncomingWithoutRotate: {
|
||||||
width: 30,
|
width: 30,
|
||||||
height: 30,
|
height: 30,
|
||||||
borderRadius: 15,
|
borderRadius: 15,
|
||||||
|
@ -659,12 +669,12 @@ export class BluePlusIcon extends Component {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export class BlueTransactionIncommingIcon extends Component {
|
export class BlueTransactionIncomingIcon extends Component {
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<View {...this.props}>
|
<View {...this.props}>
|
||||||
<View style={stylesBlueIcon.boxIncomming}>
|
<View style={stylesBlueIcon.boxIncoming}>
|
||||||
<View style={stylesBlueIcon.ballIncomming}>
|
<View style={stylesBlueIcon.ballIncoming}>
|
||||||
<Icon {...this.props} name="arrow-down" size={16} type="font-awesome" color="#37c0a1" iconStyle={{ left: 0, top: 8 }} />
|
<Icon {...this.props} name="arrow-down" size={16} type="font-awesome" color="#37c0a1" iconStyle={{ left: 0, top: 8 }} />
|
||||||
</View>
|
</View>
|
||||||
</View>
|
</View>
|
||||||
|
@ -677,7 +687,7 @@ export class BlueTransactionPendingIcon extends Component {
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<View {...this.props}>
|
<View {...this.props}>
|
||||||
<View style={stylesBlueIcon.boxIncomming}>
|
<View style={stylesBlueIcon.boxIncoming}>
|
||||||
<View style={stylesBlueIcon.ball}>
|
<View style={stylesBlueIcon.ball}>
|
||||||
<Icon
|
<Icon
|
||||||
{...this.props}
|
{...this.props}
|
||||||
|
@ -698,7 +708,7 @@ export class BlueTransactionExpiredIcon extends Component {
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<View {...this.props}>
|
<View {...this.props}>
|
||||||
<View style={stylesBlueIcon.boxIncomming}>
|
<View style={stylesBlueIcon.boxIncoming}>
|
||||||
<View style={stylesBlueIcon.ballOutgoingWithoutRotate}>
|
<View style={stylesBlueIcon.ballOutgoingWithoutRotate}>
|
||||||
<Icon {...this.props} name="hourglass-end" size={16} type="font-awesome" color="#d0021b" iconStyle={{ left: 0, top: 6 }} />
|
<Icon {...this.props} name="hourglass-end" size={16} type="font-awesome" color="#d0021b" iconStyle={{ left: 0, top: 6 }} />
|
||||||
</View>
|
</View>
|
||||||
|
@ -712,8 +722,8 @@ export class BlueTransactionOnchainIcon extends Component {
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<View {...this.props}>
|
<View {...this.props}>
|
||||||
<View style={stylesBlueIcon.boxIncomming}>
|
<View style={stylesBlueIcon.boxIncoming}>
|
||||||
<View style={stylesBlueIcon.ballIncomming}>
|
<View style={stylesBlueIcon.ballIncoming}>
|
||||||
<Icon
|
<Icon
|
||||||
{...this.props}
|
{...this.props}
|
||||||
name="link"
|
name="link"
|
||||||
|
@ -733,7 +743,7 @@ export class BlueTransactionOffchainIcon extends Component {
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<View {...this.props}>
|
<View {...this.props}>
|
||||||
<View style={stylesBlueIcon.boxIncomming}>
|
<View style={stylesBlueIcon.boxIncoming}>
|
||||||
<View style={stylesBlueIcon.ballOutgoingWithoutRotate}>
|
<View style={stylesBlueIcon.ballOutgoingWithoutRotate}>
|
||||||
<Icon {...this.props} name="bolt" size={16} type="font-awesome" color="#d0021b" iconStyle={{ left: 0, top: 7 }} />
|
<Icon {...this.props} name="bolt" size={16} type="font-awesome" color="#d0021b" iconStyle={{ left: 0, top: 7 }} />
|
||||||
</View>
|
</View>
|
||||||
|
@ -747,8 +757,8 @@ export class BlueTransactionOffchainIncomingIcon extends Component {
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<View {...this.props}>
|
<View {...this.props}>
|
||||||
<View style={stylesBlueIcon.boxIncomming}>
|
<View style={stylesBlueIcon.boxIncoming}>
|
||||||
<View style={stylesBlueIcon.ballIncommingWithoutRotate}>
|
<View style={stylesBlueIcon.ballIncomingWithoutRotate}>
|
||||||
<Icon {...this.props} name="bolt" size={16} type="font-awesome" color="#37c0a1" iconStyle={{ left: 0, top: 7 }} />
|
<Icon {...this.props} name="bolt" size={16} type="font-awesome" color="#37c0a1" iconStyle={{ left: 0, top: 7 }} />
|
||||||
</View>
|
</View>
|
||||||
</View>
|
</View>
|
||||||
|
@ -761,7 +771,7 @@ export class BlueTransactionOutgoingIcon extends Component {
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<View {...this.props}>
|
<View {...this.props}>
|
||||||
<View style={stylesBlueIcon.boxIncomming}>
|
<View style={stylesBlueIcon.boxIncoming}>
|
||||||
<View style={stylesBlueIcon.ballOutgoing}>
|
<View style={stylesBlueIcon.ballOutgoing}>
|
||||||
<Icon {...this.props} name="arrow-down" size={16} type="font-awesome" color="#d0021b" iconStyle={{ left: 0, top: 8 }} />
|
<Icon {...this.props} name="arrow-down" size={16} type="font-awesome" color="#d0021b" iconStyle={{ left: 0, top: 8 }} />
|
||||||
</View>
|
</View>
|
||||||
|
@ -987,6 +997,386 @@ export class NewWalletPanel extends Component {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export class BlueTransactionListItem extends Component {
|
||||||
|
static propTypes = {
|
||||||
|
item: PropTypes.shape().isRequired,
|
||||||
|
itemPriceUnit: PropTypes.string,
|
||||||
|
};
|
||||||
|
|
||||||
|
static defaultProps = {
|
||||||
|
itemPriceUnit: BitcoinUnit.BTC,
|
||||||
|
};
|
||||||
|
|
||||||
|
txMemo = () => {
|
||||||
|
if (BlueApp.tx_metadata[this.props.item.hash] && BlueApp.tx_metadata[this.props.item.hash]['memo']) {
|
||||||
|
return BlueApp.tx_metadata[this.props.item.hash]['memo'];
|
||||||
|
}
|
||||||
|
return '';
|
||||||
|
};
|
||||||
|
|
||||||
|
rowTitle = () => {
|
||||||
|
const item = this.props.item;
|
||||||
|
if (item.type === 'user_invoice' || item.type === 'payment_request') {
|
||||||
|
if (isNaN(item.value)) {
|
||||||
|
item.value = '0';
|
||||||
|
}
|
||||||
|
const currentDate = new Date();
|
||||||
|
const now = (currentDate.getTime() / 1000) | 0;
|
||||||
|
const invoiceExpiration = item.timestamp + item.expire_time;
|
||||||
|
|
||||||
|
if (invoiceExpiration > now) {
|
||||||
|
return loc.formatBalanceWithoutSuffix(item.value && item.value, this.props.itemPriceUnit, true).toString();
|
||||||
|
} else if (invoiceExpiration < now) {
|
||||||
|
if (item.ispaid) {
|
||||||
|
return loc.formatBalanceWithoutSuffix(item.value && item.value, this.props.itemPriceUnit, true).toString();
|
||||||
|
} else {
|
||||||
|
return loc.lnd.expired;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return loc.formatBalanceWithoutSuffix(item.value && item.value, this.props.itemPriceUnit, true).toString();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
rowTitleStyle = () => {
|
||||||
|
const item = this.props.item;
|
||||||
|
let color = '#37c0a1';
|
||||||
|
|
||||||
|
if (item.type === 'user_invoice' || item.type === 'payment_request') {
|
||||||
|
const currentDate = new Date();
|
||||||
|
const now = (currentDate.getTime() / 1000) | 0;
|
||||||
|
const invoiceExpiration = item.timestamp + item.expire_time;
|
||||||
|
|
||||||
|
if (invoiceExpiration > now) {
|
||||||
|
color = '#37c0a1';
|
||||||
|
} else if (invoiceExpiration < now) {
|
||||||
|
if (item.ispaid) {
|
||||||
|
color = '#37c0a1';
|
||||||
|
} else {
|
||||||
|
color = '#FF0000';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (item.value / 100000000 < 0) {
|
||||||
|
color = BlueApp.settings.foregroundColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
fontWeight: '600',
|
||||||
|
fontSize: 16,
|
||||||
|
color: color,
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
avatar = () => {
|
||||||
|
// is it lightning refill tx?
|
||||||
|
if (this.props.item.category === 'receive' && this.props.item.confirmations < 3) {
|
||||||
|
return (
|
||||||
|
<View style={{ width: 25 }}>
|
||||||
|
<BlueTransactionPendingIcon />
|
||||||
|
</View>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.props.item.type && this.props.item.type === 'bitcoind_tx') {
|
||||||
|
return (
|
||||||
|
<View style={{ width: 25 }}>
|
||||||
|
<BlueTransactionOnchainIcon />
|
||||||
|
</View>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if (this.props.item.type === 'paid_invoice') {
|
||||||
|
// is it lightning offchain payment?
|
||||||
|
return (
|
||||||
|
<View style={{ width: 25 }}>
|
||||||
|
<BlueTransactionOffchainIcon />
|
||||||
|
</View>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.props.item.type === 'user_invoice' || this.props.item.type === 'payment_request') {
|
||||||
|
if (!this.props.item.ispaid) {
|
||||||
|
const currentDate = new Date();
|
||||||
|
const now = (currentDate.getTime() / 1000) | 0;
|
||||||
|
const invoiceExpiration = this.props.item.timestamp + this.props.item.expire_time;
|
||||||
|
if (invoiceExpiration < now) {
|
||||||
|
return (
|
||||||
|
<View style={{ width: 25 }}>
|
||||||
|
<BlueTransactionExpiredIcon />
|
||||||
|
</View>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return (
|
||||||
|
<View style={{ width: 25 }}>
|
||||||
|
<BlueTransactionOffchainIncomingIcon />
|
||||||
|
</View>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!this.props.item.confirmations) {
|
||||||
|
return (
|
||||||
|
<View style={{ width: 25 }}>
|
||||||
|
<BlueTransactionPendingIcon />
|
||||||
|
</View>
|
||||||
|
);
|
||||||
|
} else if (this.props.item.value < 0) {
|
||||||
|
return (
|
||||||
|
<View style={{ width: 25 }}>
|
||||||
|
<BlueTransactionOutgoingIcon />
|
||||||
|
</View>
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
return (
|
||||||
|
<View style={{ width: 25 }}>
|
||||||
|
<BlueTransactionIncomingIcon />
|
||||||
|
</View>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
subtitle = () => {
|
||||||
|
return (
|
||||||
|
(this.props.item.confirmations < 7 ? loc.transactions.list.conf + ': ' + this.props.item.confirmations + ' ' : '') +
|
||||||
|
this.txMemo() +
|
||||||
|
(this.props.item.memo || '')
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
onPress = () => {
|
||||||
|
if (this.props.item.hash) {
|
||||||
|
NavigationService.navigate('TransactionDetails', { hash: this.props.item.hash });
|
||||||
|
} else if (
|
||||||
|
this.props.item.type === 'user_invoice' ||
|
||||||
|
this.props.item.type === 'payment_request' ||
|
||||||
|
this.props.item.type === 'paid_invoice'
|
||||||
|
) {
|
||||||
|
const lightningWallet = BlueApp.getWallets().filter(wallet => {
|
||||||
|
if (typeof wallet === 'object') {
|
||||||
|
if (wallet.hasOwnProperty('secret')) {
|
||||||
|
return wallet.getSecret() === this.props.item.fromWallet;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if (lightningWallet.length === 1) {
|
||||||
|
NavigationService.navigate('LNDViewInvoice', {
|
||||||
|
invoice: this.props.item,
|
||||||
|
fromWallet: lightningWallet[0],
|
||||||
|
isModal: false,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
render() {
|
||||||
|
return (
|
||||||
|
<BlueListItem
|
||||||
|
avatar={this.avatar()}
|
||||||
|
title={loc.transactionTimeToReadable(this.props.item.received)}
|
||||||
|
subtitle={this.subtitle()}
|
||||||
|
onPress={this.onPress}
|
||||||
|
badge={{
|
||||||
|
value: 3,
|
||||||
|
textStyle: { color: 'orange' },
|
||||||
|
containerStyle: { marginTop: 0 },
|
||||||
|
}}
|
||||||
|
hideChevron
|
||||||
|
rightTitle={this.rowTitle()}
|
||||||
|
rightTitleStyle={this.rowTitleStyle()}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class BlueListTransactionItem extends Component {
|
||||||
|
static propTypes = {
|
||||||
|
item: PropTypes.shape().isRequired,
|
||||||
|
itemPriceUnit: PropTypes.string,
|
||||||
|
};
|
||||||
|
|
||||||
|
static defaultProps = {
|
||||||
|
itemPriceUnit: BitcoinUnit.BTC,
|
||||||
|
};
|
||||||
|
|
||||||
|
txMemo = () => {
|
||||||
|
if (BlueApp.tx_metadata[this.props.item.hash] && BlueApp.tx_metadata[this.props.item.hash]['memo']) {
|
||||||
|
return BlueApp.tx_metadata[this.props.item.hash]['memo'];
|
||||||
|
}
|
||||||
|
return '';
|
||||||
|
};
|
||||||
|
|
||||||
|
rowTitle = () => {
|
||||||
|
const item = this.props.item;
|
||||||
|
if (item.type === 'user_invoice' || item.type === 'payment_request') {
|
||||||
|
if (isNaN(item.value)) {
|
||||||
|
item.value = '0';
|
||||||
|
}
|
||||||
|
const currentDate = new Date();
|
||||||
|
const now = (currentDate.getTime() / 1000) | 0;
|
||||||
|
const invoiceExpiration = item.timestamp + item.expire_time;
|
||||||
|
|
||||||
|
if (invoiceExpiration > now) {
|
||||||
|
return loc.formatBalanceWithoutSuffix(item.value && item.value, this.props.itemPriceUnit, true).toString();
|
||||||
|
} else if (invoiceExpiration < now) {
|
||||||
|
if (item.ispaid) {
|
||||||
|
return loc.formatBalanceWithoutSuffix(item.value && item.value, this.props.itemPriceUnit, true).toString();
|
||||||
|
} else {
|
||||||
|
return loc.lnd.expired;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return loc.formatBalanceWithoutSuffix(item.value && item.value, this.props.itemPriceUnit, true).toString();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
rowTitleStyle = () => {
|
||||||
|
const item = this.props.item;
|
||||||
|
let color = '#37c0a1';
|
||||||
|
|
||||||
|
if (item.type === 'user_invoice' || item.type === 'payment_request') {
|
||||||
|
const currentDate = new Date();
|
||||||
|
const now = (currentDate.getTime() / 1000) | 0;
|
||||||
|
const invoiceExpiration = item.timestamp + item.expire_time;
|
||||||
|
|
||||||
|
if (invoiceExpiration > now) {
|
||||||
|
color = '#37c0a1';
|
||||||
|
} else if (invoiceExpiration < now) {
|
||||||
|
if (item.ispaid) {
|
||||||
|
color = '#37c0a1';
|
||||||
|
} else {
|
||||||
|
color = '#FF0000';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (item.value / 100000000 < 0) {
|
||||||
|
color = BlueApp.settings.foregroundColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
fontWeight: '600',
|
||||||
|
fontSize: 16,
|
||||||
|
color: color,
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
avatar = () => {
|
||||||
|
// is it lightning refill tx?
|
||||||
|
if (this.props.item.category === 'receive' && this.props.item.confirmations < 3) {
|
||||||
|
return (
|
||||||
|
<View style={{ width: 25 }}>
|
||||||
|
<BlueTransactionPendingIcon />
|
||||||
|
</View>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.props.item.type && this.props.item.type === 'bitcoind_tx') {
|
||||||
|
return (
|
||||||
|
<View style={{ width: 25 }}>
|
||||||
|
<BlueTransactionOnchainIcon />
|
||||||
|
</View>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if (this.props.item.type === 'paid_invoice') {
|
||||||
|
// is it lightning offchain payment?
|
||||||
|
return (
|
||||||
|
<View style={{ width: 25 }}>
|
||||||
|
<BlueTransactionOffchainIcon />
|
||||||
|
</View>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.props.item.type === 'user_invoice' || this.props.item.type === 'payment_request') {
|
||||||
|
if (!this.props.item.ispaid) {
|
||||||
|
const currentDate = new Date();
|
||||||
|
const now = (currentDate.getTime() / 1000) | 0;
|
||||||
|
const invoiceExpiration = this.props.item.timestamp + this.props.item.expire_time;
|
||||||
|
if (invoiceExpiration < now) {
|
||||||
|
return (
|
||||||
|
<View style={{ width: 25 }}>
|
||||||
|
<BlueTransactionExpiredIcon />
|
||||||
|
</View>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return (
|
||||||
|
<View style={{ width: 25 }}>
|
||||||
|
<BlueTransactionOffchainIncomingIcon />
|
||||||
|
</View>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!this.props.item.confirmations) {
|
||||||
|
return (
|
||||||
|
<View style={{ width: 25 }}>
|
||||||
|
<BlueTransactionPendingIcon />
|
||||||
|
</View>
|
||||||
|
);
|
||||||
|
} else if (this.props.item.value < 0) {
|
||||||
|
return (
|
||||||
|
<View style={{ width: 25 }}>
|
||||||
|
<BlueTransactionOutgoingIcon />
|
||||||
|
</View>
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
return (
|
||||||
|
<View style={{ width: 25 }}>
|
||||||
|
<BlueTransactionIncomingIcon />
|
||||||
|
</View>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
subtitle = () => {
|
||||||
|
return (
|
||||||
|
(this.props.item.confirmations < 7 ? loc.transactions.list.conf + ': ' + this.props.item.confirmations + ' ' : '') +
|
||||||
|
this.txMemo() +
|
||||||
|
(this.props.item.memo || '')
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
onPress = () => {
|
||||||
|
if (this.props.item.hash) {
|
||||||
|
NavigationService.navigate('TransactionDetails', { hash: this.props.item.hash });
|
||||||
|
} else if (
|
||||||
|
this.props.item.type === 'user_invoice' ||
|
||||||
|
this.props.item.type === 'payment_request' ||
|
||||||
|
this.props.item.type === 'paid_invoice'
|
||||||
|
) {
|
||||||
|
const lightningWallet = BlueApp.getWallets().filter(wallet => {
|
||||||
|
if (typeof wallet === 'object') {
|
||||||
|
if (wallet.hasOwnProperty('secret')) {
|
||||||
|
return wallet.getSecret() === this.props.item.fromWallet;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
NavigationService.navigate('LNDViewInvoice', {
|
||||||
|
invoice: this.props.item,
|
||||||
|
fromWallet: lightningWallet[0],
|
||||||
|
isModal: false,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
render() {
|
||||||
|
return (
|
||||||
|
<BlueListItem
|
||||||
|
avatar={this.avatar()}
|
||||||
|
title={loc.transactionTimeToReadable(this.props.item.received)}
|
||||||
|
subtitle={this.subtitle()}
|
||||||
|
onPress={this.onPress}
|
||||||
|
badge={{
|
||||||
|
value: 3,
|
||||||
|
textStyle: { color: 'orange' },
|
||||||
|
containerStyle: { marginTop: 0 },
|
||||||
|
}}
|
||||||
|
hideChevron
|
||||||
|
rightTitle={this.rowTitle()}
|
||||||
|
rightTitleStyle={this.rowTitleStyle()}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const sliderWidth = width * 1;
|
const sliderWidth = width * 1;
|
||||||
const itemWidth = width * 0.82;
|
const itemWidth = width * 0.82;
|
||||||
const sliderHeight = 190;
|
const sliderHeight = 190;
|
||||||
|
@ -1003,12 +1393,17 @@ export class WalletsCarousel extends Component {
|
||||||
|
|
||||||
_renderItem({ item, index }) {
|
_renderItem({ item, index }) {
|
||||||
let scaleValue = new Animated.Value(1.0);
|
let scaleValue = new Animated.Value(1.0);
|
||||||
|
let props = { duration: 50 };
|
||||||
|
if (Platform.OS === 'android') {
|
||||||
|
props['useNativeDriver'] = true;
|
||||||
|
}
|
||||||
this.onPressedIn = () => {
|
this.onPressedIn = () => {
|
||||||
Animated.spring(scaleValue, { toValue: 0.9, duration: 100, useNativeDriver: Platform.OS === 'android' }).start();
|
props.toValue = 0.9;
|
||||||
|
Animated.spring(scaleValue, props).start();
|
||||||
};
|
};
|
||||||
this.onPressedOut = () => {
|
this.onPressedOut = () => {
|
||||||
Animated.spring(scaleValue, { toValue: 1.0, duration: 100, useNativeDriver: Platform.OS === 'android' }).start();
|
props.toValue = 1.0;
|
||||||
|
Animated.spring(scaleValue, props).start();
|
||||||
};
|
};
|
||||||
|
|
||||||
if (!item) {
|
if (!item) {
|
||||||
|
@ -1262,7 +1657,6 @@ export class BlueBitcoinAmount extends Component {
|
||||||
ref={textInput => (this.textInput = textInput)}
|
ref={textInput => (this.textInput = textInput)}
|
||||||
editable={!this.props.isLoading && !this.props.disabled}
|
editable={!this.props.isLoading && !this.props.disabled}
|
||||||
value={amount}
|
value={amount}
|
||||||
autoFocus={this.props.pointerEvents !== 'none'}
|
|
||||||
placeholderTextColor={this.props.disabled ? '#99a0ab' : '#0f5cc0'}
|
placeholderTextColor={this.props.disabled ? '#99a0ab' : '#0f5cc0'}
|
||||||
style={{
|
style={{
|
||||||
color: this.props.disabled ? '#99a0ab' : '#0f5cc0',
|
color: this.props.disabled ? '#99a0ab' : '#0f5cc0',
|
||||||
|
|
|
@ -2,7 +2,7 @@ import { createStackNavigator, createAppContainer } from 'react-navigation';
|
||||||
|
|
||||||
import Settings from './screen/settings/settings';
|
import Settings from './screen/settings/settings';
|
||||||
import About from './screen/settings/about';
|
import About from './screen/settings/about';
|
||||||
import Releasenotes from './screen/settings/releasenotes';
|
import ReleaseNotes from './screen/settings/releasenotes';
|
||||||
import Selftest from './screen/selftest';
|
import Selftest from './screen/selftest';
|
||||||
import Language from './screen/settings/language';
|
import Language from './screen/settings/language';
|
||||||
import Currency from './screen/settings/currency';
|
import Currency from './screen/settings/currency';
|
||||||
|
@ -87,9 +87,9 @@ const WalletsStackNavigator = createStackNavigator(
|
||||||
screen: About,
|
screen: About,
|
||||||
path: 'About',
|
path: 'About',
|
||||||
},
|
},
|
||||||
Releasenotes: {
|
ReleaseNotes: {
|
||||||
screen: Releasenotes,
|
screen: ReleaseNotes,
|
||||||
path: 'Releasenotes',
|
path: 'ReleaseNotes',
|
||||||
},
|
},
|
||||||
Selftest: {
|
Selftest: {
|
||||||
screen: Selftest,
|
screen: Selftest,
|
||||||
|
@ -185,6 +185,15 @@ const CreateWalletStackNavigator = createStackNavigator({
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const LightningScanInvoiceStackNavigator = createStackNavigator({
|
||||||
|
ScanLndInvoice: {
|
||||||
|
screen: ScanLndInvoice,
|
||||||
|
},
|
||||||
|
Success: {
|
||||||
|
screen: Success,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
const MainBottomTabs = createStackNavigator(
|
const MainBottomTabs = createStackNavigator(
|
||||||
{
|
{
|
||||||
Wallets: {
|
Wallets: {
|
||||||
|
@ -241,7 +250,10 @@ const MainBottomTabs = createStackNavigator(
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
ScanLndInvoice: {
|
ScanLndInvoice: {
|
||||||
screen: ScanLndInvoice,
|
screen: LightningScanInvoiceStackNavigator,
|
||||||
|
navigationOptions: {
|
||||||
|
header: null,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
ScanQrAddress: {
|
ScanQrAddress: {
|
||||||
screen: sendScanQrAddress,
|
screen: sendScanQrAddress,
|
||||||
|
|
|
@ -108,7 +108,10 @@
|
||||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/javaPrecompile" />
|
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/javaPrecompile" />
|
||||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/javac" />
|
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/javac" />
|
||||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/jniLibs" />
|
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/jniLibs" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/legacy_multidex_aapt_derived_proguard_rules" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/legacy_multidex_main_dex_list" />
|
||||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/linked_res_for_bundle" />
|
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/linked_res_for_bundle" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/lint_jar" />
|
||||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/manifest-checker" />
|
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/manifest-checker" />
|
||||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/manifests" />
|
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/manifests" />
|
||||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/merged_assets" />
|
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/merged_assets" />
|
||||||
|
|
6
index.js
6
index.js
|
@ -24,13 +24,13 @@ class BlueAppComponent extends React.Component {
|
||||||
this.state = { isMigratingData: true };
|
this.state = { isMigratingData: true };
|
||||||
}
|
}
|
||||||
|
|
||||||
async setIsMigratingData() {
|
setIsMigratingData = async () => {
|
||||||
await BlueApp.startAndDecrypt();
|
await BlueApp.startAndDecrypt();
|
||||||
this.setState({ isMigratingData: false });
|
this.setState({ isMigratingData: false });
|
||||||
}
|
};
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return this.state.isMigratingData ? <WalletMigrate onComplete={() => this.setIsMigratingData()} /> : <App />;
|
return this.state.isMigratingData ? <WalletMigrate onComplete={this.setIsMigratingData} /> : <App />;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
};
|
};
|
||||||
objectVersion = 46;
|
objectVersion = 46;
|
||||||
objects = {
|
objects = {
|
||||||
|
|
||||||
/* Begin PBXBuildFile section */
|
/* Begin PBXBuildFile section */
|
||||||
00C302E51ABCBA2D00DB3ED1 /* libRCTActionSheet.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 00C302AC1ABCB8CE00DB3ED1 /* libRCTActionSheet.a */; };
|
00C302E51ABCBA2D00DB3ED1 /* libRCTActionSheet.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 00C302AC1ABCB8CE00DB3ED1 /* libRCTActionSheet.a */; };
|
||||||
00C302E71ABCBA2D00DB3ED1 /* libRCTGeolocation.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 00C302BA1ABCB90400DB3ED1 /* libRCTGeolocation.a */; };
|
00C302E71ABCBA2D00DB3ED1 /* libRCTGeolocation.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 00C302BA1ABCB90400DB3ED1 /* libRCTGeolocation.a */; };
|
||||||
|
@ -42,6 +43,7 @@
|
||||||
2DCD954D1E0B4F2C00145EB5 /* BlueWalletTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 00E356F21AD99517003FC87E /* BlueWalletTests.m */; };
|
2DCD954D1E0B4F2C00145EB5 /* BlueWalletTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 00E356F21AD99517003FC87E /* BlueWalletTests.m */; };
|
||||||
2DF0FFEE2056DD460020B375 /* libReact.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 3DAD3EA31DF850E9000B6D8A /* libReact.a */; };
|
2DF0FFEE2056DD460020B375 /* libReact.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 3DAD3EA31DF850E9000B6D8A /* libReact.a */; };
|
||||||
2F707BDB2EF14D17AF9A2908 /* libReactNativePermissions.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 1DD63E4B5C8344BB9880C9EC /* libReactNativePermissions.a */; };
|
2F707BDB2EF14D17AF9A2908 /* libReactNativePermissions.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 1DD63E4B5C8344BB9880C9EC /* libReactNativePermissions.a */; };
|
||||||
|
34582CAA4AD140F7B80C961A /* libTcpSockets.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 9DF4E6C040764E4BA1ACC1EB /* libTcpSockets.a */; };
|
||||||
34CC55B441594DBB95AD1B50 /* Octicons.ttf in Resources */ = {isa = PBXBuildFile; fileRef = E8E8CE89B3D142C6A8A56C34 /* Octicons.ttf */; };
|
34CC55B441594DBB95AD1B50 /* Octicons.ttf in Resources */ = {isa = PBXBuildFile; fileRef = E8E8CE89B3D142C6A8A56C34 /* Octicons.ttf */; };
|
||||||
3EEBC6F85642487DA7C4EE35 /* AntDesign.ttf in Resources */ = {isa = PBXBuildFile; fileRef = C4496FB303574862B40A878A /* AntDesign.ttf */; };
|
3EEBC6F85642487DA7C4EE35 /* AntDesign.ttf in Resources */ = {isa = PBXBuildFile; fileRef = C4496FB303574862B40A878A /* AntDesign.ttf */; };
|
||||||
4D6390DDA5B7485F91A6C750 /* CoreData.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2654894D4DE44A4C8F71773D /* CoreData.framework */; };
|
4D6390DDA5B7485F91A6C750 /* CoreData.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2654894D4DE44A4C8F71773D /* CoreData.framework */; };
|
||||||
|
@ -79,7 +81,6 @@
|
||||||
ED2971652150620600B7C4FE /* JavaScriptCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = ED2971642150620600B7C4FE /* JavaScriptCore.framework */; };
|
ED2971652150620600B7C4FE /* JavaScriptCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = ED2971642150620600B7C4FE /* JavaScriptCore.framework */; };
|
||||||
F21429E1449249038A7F3444 /* FontAwesome.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 334051161886419EA186F4BA /* FontAwesome.ttf */; };
|
F21429E1449249038A7F3444 /* FontAwesome.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 334051161886419EA186F4BA /* FontAwesome.ttf */; };
|
||||||
FBB34FB8F9B248A89346FE61 /* libRNDeviceInfo-tvOS.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 6EB3338E347F4AFAA8C85C04 /* libRNDeviceInfo-tvOS.a */; };
|
FBB34FB8F9B248A89346FE61 /* libRNDeviceInfo-tvOS.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 6EB3338E347F4AFAA8C85C04 /* libRNDeviceInfo-tvOS.a */; };
|
||||||
34582CAA4AD140F7B80C961A /* libTcpSockets.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 9DF4E6C040764E4BA1ACC1EB /* libTcpSockets.a */; };
|
|
||||||
/* End PBXBuildFile section */
|
/* End PBXBuildFile section */
|
||||||
|
|
||||||
/* Begin PBXContainerItemProxy section */
|
/* Begin PBXContainerItemProxy section */
|
||||||
|
@ -524,6 +525,13 @@
|
||||||
remoteGlobalIDString = 32D980DD1BE9F11C00FA27E5;
|
remoteGlobalIDString = 32D980DD1BE9F11C00FA27E5;
|
||||||
remoteInfo = RCTQRCodeLocalImage;
|
remoteInfo = RCTQRCodeLocalImage;
|
||||||
};
|
};
|
||||||
|
B47720652202510900DD0E81 /* PBXContainerItemProxy */ = {
|
||||||
|
isa = PBXContainerItemProxy;
|
||||||
|
containerPortal = 910283A2A9EB4D00902DE78E /* TcpSockets.xcodeproj */;
|
||||||
|
proxyType = 2;
|
||||||
|
remoteGlobalIDString = 134814201AA4EA6300B7C361;
|
||||||
|
remoteInfo = TcpSockets;
|
||||||
|
};
|
||||||
/* End PBXContainerItemProxy section */
|
/* End PBXContainerItemProxy section */
|
||||||
|
|
||||||
/* Begin PBXFileReference section */
|
/* Begin PBXFileReference section */
|
||||||
|
@ -579,8 +587,10 @@
|
||||||
7EA61BC8FF6E4AD2A67F1557 /* RCTQRCodeLocalImage.xcodeproj */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = "wrapper.pb-project"; name = RCTQRCodeLocalImage.xcodeproj; path = "../node_modules/@remobile/react-native-qrcode-local-image/ios/RCTQRCodeLocalImage.xcodeproj"; sourceTree = "<group>"; };
|
7EA61BC8FF6E4AD2A67F1557 /* RCTQRCodeLocalImage.xcodeproj */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = "wrapper.pb-project"; name = RCTQRCodeLocalImage.xcodeproj; path = "../node_modules/@remobile/react-native-qrcode-local-image/ios/RCTQRCodeLocalImage.xcodeproj"; sourceTree = "<group>"; };
|
||||||
832341B01AAA6A8300B99B32 /* RCTText.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTText.xcodeproj; path = "../node_modules/react-native/Libraries/Text/RCTText.xcodeproj"; sourceTree = "<group>"; };
|
832341B01AAA6A8300B99B32 /* RCTText.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTText.xcodeproj; path = "../node_modules/react-native/Libraries/Text/RCTText.xcodeproj"; sourceTree = "<group>"; };
|
||||||
8637D4B5E14D443A9031DA95 /* libRNFS.a */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = archive.ar; path = libRNFS.a; sourceTree = "<group>"; };
|
8637D4B5E14D443A9031DA95 /* libRNFS.a */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = archive.ar; path = libRNFS.a; sourceTree = "<group>"; };
|
||||||
|
910283A2A9EB4D00902DE78E /* TcpSockets.xcodeproj */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = "wrapper.pb-project"; name = TcpSockets.xcodeproj; path = "../node_modules/react-native-tcp/ios/TcpSockets.xcodeproj"; sourceTree = "<group>"; };
|
||||||
94565BFC6A0C4235B3EC7B01 /* libRNSVG.a */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = archive.ar; path = libRNSVG.a; sourceTree = "<group>"; };
|
94565BFC6A0C4235B3EC7B01 /* libRNSVG.a */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = archive.ar; path = libRNSVG.a; sourceTree = "<group>"; };
|
||||||
95208B2A05884A76B5BB99C0 /* libRCTGoogleAnalyticsBridge.a */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = archive.ar; path = libRCTGoogleAnalyticsBridge.a; sourceTree = "<group>"; };
|
95208B2A05884A76B5BB99C0 /* libRCTGoogleAnalyticsBridge.a */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = archive.ar; path = libRCTGoogleAnalyticsBridge.a; sourceTree = "<group>"; };
|
||||||
|
9DF4E6C040764E4BA1ACC1EB /* libTcpSockets.a */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = archive.ar; path = libTcpSockets.a; sourceTree = "<group>"; };
|
||||||
9EA3788F4C6643B7B0182587 /* RNVectorIcons.xcodeproj */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = "wrapper.pb-project"; name = RNVectorIcons.xcodeproj; path = "../node_modules/react-native-vector-icons/RNVectorIcons.xcodeproj"; sourceTree = "<group>"; };
|
9EA3788F4C6643B7B0182587 /* RNVectorIcons.xcodeproj */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = "wrapper.pb-project"; name = RNVectorIcons.xcodeproj; path = "../node_modules/react-native-vector-icons/RNVectorIcons.xcodeproj"; sourceTree = "<group>"; };
|
||||||
9F1F51A83D044F3BB26A35FC /* libRNSVG-tvOS.a */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = archive.ar; path = "libRNSVG-tvOS.a"; sourceTree = "<group>"; };
|
9F1F51A83D044F3BB26A35FC /* libRNSVG-tvOS.a */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = archive.ar; path = "libRNSVG-tvOS.a"; sourceTree = "<group>"; };
|
||||||
A71D2FDE64CF4F729C7298EA /* RNFS.xcodeproj */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = "wrapper.pb-project"; name = RNFS.xcodeproj; path = "../node_modules/react-native-fs/RNFS.xcodeproj"; sourceTree = "<group>"; };
|
A71D2FDE64CF4F729C7298EA /* RNFS.xcodeproj */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = "wrapper.pb-project"; name = RNFS.xcodeproj; path = "../node_modules/react-native-fs/RNFS.xcodeproj"; sourceTree = "<group>"; };
|
||||||
|
@ -613,8 +623,6 @@
|
||||||
F9065403A26440679749C7AA /* BVLinearGradient.xcodeproj */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = "wrapper.pb-project"; name = BVLinearGradient.xcodeproj; path = "../node_modules/react-native-linear-gradient/BVLinearGradient.xcodeproj"; sourceTree = "<group>"; };
|
F9065403A26440679749C7AA /* BVLinearGradient.xcodeproj */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = "wrapper.pb-project"; name = BVLinearGradient.xcodeproj; path = "../node_modules/react-native-linear-gradient/BVLinearGradient.xcodeproj"; sourceTree = "<group>"; };
|
||||||
FC98DC24A81A463AB8B2E6B1 /* libRNImagePicker.a */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = archive.ar; path = libRNImagePicker.a; sourceTree = "<group>"; };
|
FC98DC24A81A463AB8B2E6B1 /* libRNImagePicker.a */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = archive.ar; path = libRNImagePicker.a; sourceTree = "<group>"; };
|
||||||
FD7977067E1A496F94D8B1B7 /* libRNDeviceInfo.a */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = archive.ar; path = libRNDeviceInfo.a; sourceTree = "<group>"; };
|
FD7977067E1A496F94D8B1B7 /* libRNDeviceInfo.a */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = archive.ar; path = libRNDeviceInfo.a; sourceTree = "<group>"; };
|
||||||
910283A2A9EB4D00902DE78E /* TcpSockets.xcodeproj */ = {isa = PBXFileReference; name = "TcpSockets.xcodeproj"; path = "../node_modules/react-native-tcp/ios/TcpSockets.xcodeproj"; sourceTree = "<group>"; fileEncoding = undefined; lastKnownFileType = wrapper.pb-project; explicitFileType = undefined; includeInIndex = 0; };
|
|
||||||
9DF4E6C040764E4BA1ACC1EB /* libTcpSockets.a */ = {isa = PBXFileReference; name = "libTcpSockets.a"; path = "libTcpSockets.a"; sourceTree = "<group>"; fileEncoding = undefined; lastKnownFileType = archive.ar; explicitFileType = undefined; includeInIndex = 0; };
|
|
||||||
/* End PBXFileReference section */
|
/* End PBXFileReference section */
|
||||||
|
|
||||||
/* Begin PBXFrameworksBuildPhase section */
|
/* Begin PBXFrameworksBuildPhase section */
|
||||||
|
@ -976,6 +984,7 @@
|
||||||
E7078D2FED444DA4B0BD57F9 /* libRCTWKWebView.a */,
|
E7078D2FED444DA4B0BD57F9 /* libRCTWKWebView.a */,
|
||||||
FC98DC24A81A463AB8B2E6B1 /* libRNImagePicker.a */,
|
FC98DC24A81A463AB8B2E6B1 /* libRNImagePicker.a */,
|
||||||
B642AFB13483418CAB6FF25E /* libRCTQRCodeLocalImage.a */,
|
B642AFB13483418CAB6FF25E /* libRCTQRCodeLocalImage.a */,
|
||||||
|
9DF4E6C040764E4BA1ACC1EB /* libTcpSockets.a */,
|
||||||
);
|
);
|
||||||
name = "Recovered References";
|
name = "Recovered References";
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
|
@ -1123,6 +1132,14 @@
|
||||||
name = Products;
|
name = Products;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
};
|
};
|
||||||
|
B47720622202510900DD0E81 /* Products */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
B47720662202510900DD0E81 /* libTcpSockets.a */,
|
||||||
|
);
|
||||||
|
name = Products;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
/* End PBXGroup section */
|
/* End PBXGroup section */
|
||||||
|
|
||||||
/* Begin PBXNativeTarget section */
|
/* Begin PBXNativeTarget section */
|
||||||
|
@ -1356,6 +1373,10 @@
|
||||||
ProductGroup = B40FE5CC21FAD27D005D5578 /* Products */;
|
ProductGroup = B40FE5CC21FAD27D005D5578 /* Products */;
|
||||||
ProjectRef = 9EA3788F4C6643B7B0182587 /* RNVectorIcons.xcodeproj */;
|
ProjectRef = 9EA3788F4C6643B7B0182587 /* RNVectorIcons.xcodeproj */;
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
ProductGroup = B47720622202510900DD0E81 /* Products */;
|
||||||
|
ProjectRef = 910283A2A9EB4D00902DE78E /* TcpSockets.xcodeproj */;
|
||||||
|
},
|
||||||
);
|
);
|
||||||
projectRoot = "";
|
projectRoot = "";
|
||||||
targets = (
|
targets = (
|
||||||
|
@ -1795,6 +1816,13 @@
|
||||||
remoteRef = B4327F5021FC1B9300F7ADFA /* PBXContainerItemProxy */;
|
remoteRef = B4327F5021FC1B9300F7ADFA /* PBXContainerItemProxy */;
|
||||||
sourceTree = BUILT_PRODUCTS_DIR;
|
sourceTree = BUILT_PRODUCTS_DIR;
|
||||||
};
|
};
|
||||||
|
B47720662202510900DD0E81 /* libTcpSockets.a */ = {
|
||||||
|
isa = PBXReferenceProxy;
|
||||||
|
fileType = archive.ar;
|
||||||
|
path = libTcpSockets.a;
|
||||||
|
remoteRef = B47720652202510900DD0E81 /* PBXContainerItemProxy */;
|
||||||
|
sourceTree = BUILT_PRODUCTS_DIR;
|
||||||
|
};
|
||||||
/* End PBXReferenceProxy section */
|
/* End PBXReferenceProxy section */
|
||||||
|
|
||||||
/* Begin PBXResourcesBuildPhase section */
|
/* Begin PBXResourcesBuildPhase section */
|
||||||
|
@ -2111,7 +2139,7 @@
|
||||||
"-ObjC",
|
"-ObjC",
|
||||||
"-lc++",
|
"-lc++",
|
||||||
);
|
);
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = "org.reactjs.native.example.$(PRODUCT_NAME:rfc1034identifier)";
|
PRODUCT_BUNDLE_IDENTIFIER = io.bluewallet.bluewallet;
|
||||||
PRODUCT_NAME = BlueWallet;
|
PRODUCT_NAME = BlueWallet;
|
||||||
TARGETED_DEVICE_FAMILY = "1,2";
|
TARGETED_DEVICE_FAMILY = "1,2";
|
||||||
VERSIONING_SYSTEM = "apple-generic";
|
VERSIONING_SYSTEM = "apple-generic";
|
||||||
|
@ -2153,7 +2181,7 @@
|
||||||
"-ObjC",
|
"-ObjC",
|
||||||
"-lc++",
|
"-lc++",
|
||||||
);
|
);
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = "org.reactjs.native.example.$(PRODUCT_NAME:rfc1034identifier)";
|
PRODUCT_BUNDLE_IDENTIFIER = io.bluewallet.bluewallet;
|
||||||
PRODUCT_NAME = BlueWallet;
|
PRODUCT_NAME = BlueWallet;
|
||||||
TARGETED_DEVICE_FAMILY = "1,2";
|
TARGETED_DEVICE_FAMILY = "1,2";
|
||||||
VERSIONING_SYSTEM = "apple-generic";
|
VERSIONING_SYSTEM = "apple-generic";
|
||||||
|
|
|
@ -28,7 +28,7 @@
|
||||||
moduleName:@"BlueWallet"
|
moduleName:@"BlueWallet"
|
||||||
initialProperties:nil
|
initialProperties:nil
|
||||||
launchOptions:launchOptions];
|
launchOptions:launchOptions];
|
||||||
rootView.backgroundColor = [UIColor blackColor];
|
rootView.backgroundColor = [UIColor whiteColor];
|
||||||
|
|
||||||
self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
|
self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
|
||||||
UIViewController *rootViewController = [UIViewController new];
|
UIViewController *rootViewController = [UIViewController new];
|
||||||
|
|
|
@ -56,9 +56,11 @@
|
||||||
<key>NSCalendarsUsageDescription</key>
|
<key>NSCalendarsUsageDescription</key>
|
||||||
<string>This alert should not show up as we do not require this data</string>
|
<string>This alert should not show up as we do not require this data</string>
|
||||||
<key>NSCameraUsageDescription</key>
|
<key>NSCameraUsageDescription</key>
|
||||||
<string>In order to quickly scan the recipient's address, we need your permission to use the camera to scan their QR Code.</string>
|
<string>In order to quickly scan the recipient's address, we need your permission to use the camera to scan their QR Code.</string>
|
||||||
<key>NSLocationWhenInUseUsageDescription</key>
|
<key>NSLocationWhenInUseUsageDescription</key>
|
||||||
<string>This alert should not show up as we do not require this data</string>
|
<string>This alert should not show up as we do not require this data</string>
|
||||||
|
<key>NSMicrophoneUsageDescription</key>
|
||||||
|
<string>This alert should not show up as we do not require this data</string>
|
||||||
<key>NSMotionUsageDescription</key>
|
<key>NSMotionUsageDescription</key>
|
||||||
<string>This alert should not show up as we do not require this data</string>
|
<string>This alert should not show up as we do not require this data</string>
|
||||||
<key>NSPhotoLibraryAddUsageDescription</key>
|
<key>NSPhotoLibraryAddUsageDescription</key>
|
||||||
|
@ -67,8 +69,6 @@
|
||||||
<string>In order to import an image for scanning, we need your permission to access your photo library.</string>
|
<string>In order to import an image for scanning, we need your permission to access your photo library.</string>
|
||||||
<key>NSSpeechRecognitionUsageDescription</key>
|
<key>NSSpeechRecognitionUsageDescription</key>
|
||||||
<string>This alert should not show up as we do not require this data</string>
|
<string>This alert should not show up as we do not require this data</string>
|
||||||
<key>NSMicrophoneUsageDescription</key>
|
|
||||||
<string>This alert should not show up as we do not require this data</string>
|
|
||||||
<key>UIAppFonts</key>
|
<key>UIAppFonts</key>
|
||||||
<array>
|
<array>
|
||||||
<string>AntDesign.ttf</string>
|
<string>AntDesign.ttf</string>
|
||||||
|
|
|
@ -217,6 +217,7 @@ module.exports = {
|
||||||
refill_lnd_balance: 'Lade deine Lightning Wallet auf',
|
refill_lnd_balance: 'Lade deine Lightning Wallet auf',
|
||||||
refill: 'Aufladen',
|
refill: 'Aufladen',
|
||||||
withdraw: 'Abheben',
|
withdraw: 'Abheben',
|
||||||
sameWalletAsInvoiceError: 'Du kannst nicht die Rechnung mit der Wallet begleichen, die du für die Erstellung dieser Rechnung verwendet hast.',
|
sameWalletAsInvoiceError:
|
||||||
|
'Du kannst nicht die Rechnung mit der Wallet begleichen, die du für die Erstellung dieser Rechnung verwendet hast.',
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
|
@ -11,6 +11,7 @@ export const FiatUnit = Object.freeze({
|
||||||
INR: { endPointKey: 'INR', symbol: '₹', locale: 'hi-HN' },
|
INR: { endPointKey: 'INR', symbol: '₹', locale: 'hi-HN' },
|
||||||
JPY: { endPointKey: 'JPY', symbol: '¥', locale: 'ja-JP' },
|
JPY: { endPointKey: 'JPY', symbol: '¥', locale: 'ja-JP' },
|
||||||
MXN: { endPointKey: 'MXN', symbol: '$', locale: 'es-MX' },
|
MXN: { endPointKey: 'MXN', symbol: '$', locale: 'es-MX' },
|
||||||
|
MYR: { endPointKey: 'MYR', symbol: 'RM', locale: 'ms-MY' },
|
||||||
PLN: { endPointKey: 'PLN', symbol: 'zł', locale: 'pl-PL' },
|
PLN: { endPointKey: 'PLN', symbol: 'zł', locale: 'pl-PL' },
|
||||||
RUB: { endPointKey: 'RUB', symbol: '₽', locale: 'ru-RU' },
|
RUB: { endPointKey: 'RUB', symbol: '₽', locale: 'ru-RU' },
|
||||||
SGD: { endPointKey: 'SGD', symbol: 'S$', locale: 'zh-SG' },
|
SGD: { endPointKey: 'SGD', symbol: 'S$', locale: 'zh-SG' },
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
import Frisbee from 'frisbee';
|
import Frisbee from 'frisbee';
|
||||||
|
|
||||||
export class NetworkTransactionFee {
|
export class NetworkTransactionFee {
|
||||||
|
static StorageKey = 'NetworkTransactionFee';
|
||||||
|
|
||||||
constructor(fastestFee = 1, halfHourFee = 1, hourFee = 1) {
|
constructor(fastestFee = 1, halfHourFee = 1, hourFee = 1) {
|
||||||
this.fastestFee = fastestFee;
|
this.fastestFee = fastestFee;
|
||||||
this.halfHourFee = halfHourFee;
|
this.halfHourFee = halfHourFee;
|
||||||
|
|
4471
package-lock.json
generated
4471
package-lock.json
generated
File diff suppressed because it is too large
Load diff
28
package.json
28
package.json
|
@ -4,7 +4,7 @@
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"babel-eslint": "^10.0.1",
|
"babel-eslint": "^10.0.1",
|
||||||
"babel-jest": "^24.0.0",
|
"babel-jest": "^24.0.0",
|
||||||
"eslint": "^5.12.1",
|
"eslint": "^5.13.0",
|
||||||
"eslint-plugin-babel": "^5.3.0",
|
"eslint-plugin-babel": "^5.3.0",
|
||||||
"eslint-plugin-import": "^2.15.0",
|
"eslint-plugin-import": "^2.15.0",
|
||||||
"eslint-plugin-node": "^8.0.1",
|
"eslint-plugin-node": "^8.0.1",
|
||||||
|
@ -47,31 +47,31 @@
|
||||||
"crypto-js": "^3.1.9-1",
|
"crypto-js": "^3.1.9-1",
|
||||||
"dayjs": "^1.8.0",
|
"dayjs": "^1.8.0",
|
||||||
"electrum-client": "git+https://github.com/Overtorment/node-electrum-client.git",
|
"electrum-client": "git+https://github.com/Overtorment/node-electrum-client.git",
|
||||||
"eslint-config-prettier": "^3.6.0",
|
"eslint-config-prettier": "^4.0.0",
|
||||||
"eslint-config-standard": "^12.0.0",
|
"eslint-config-standard": "^12.0.0",
|
||||||
"eslint-config-standard-react": "^7.0.2",
|
"eslint-config-standard-react": "^7.0.2",
|
||||||
"eslint-plugin-prettier": "^3.0.1",
|
"eslint-plugin-prettier": "^3.0.1",
|
||||||
"eslint-plugin-standard": "^4.0.0",
|
"eslint-plugin-standard": "^4.0.0",
|
||||||
"frisbee": "^1.6.4",
|
"frisbee": "^2.0.5",
|
||||||
"intl": "^1.2.5",
|
"intl": "^1.2.5",
|
||||||
"mocha": "^5.2.0",
|
"mocha": "^5.2.0",
|
||||||
"node-libs-react-native": "^1.0.1",
|
"node-libs-react-native": "^1.0.1",
|
||||||
"path-browserify": "0.0.0",
|
"path-browserify": "^1.0.0",
|
||||||
"prettier": "^1.16.1",
|
"prettier": "^1.16.3",
|
||||||
"process": "^0.11.10",
|
"process": "^0.11.10",
|
||||||
"prop-types": "^15.6.2",
|
"prop-types": "^15.6.2",
|
||||||
"react": "^16.7.0",
|
"react": "^16.7.0",
|
||||||
"react-localization": "^1.0.10",
|
"react-localization": "^1.0.10",
|
||||||
"react-native": "^0.58.1",
|
"react-native": "^0.58.1",
|
||||||
"react-native-camera": "^1.9.2",
|
"react-native-camera": "^1.10.0",
|
||||||
"react-native-custom-qr-codes": "^2.0.0",
|
"react-native-custom-qr-codes": "^2.0.0",
|
||||||
"react-native-device-info": "^0.25.1",
|
"react-native-device-info": "^0.26.1",
|
||||||
"react-native-elements": "^0.19.0",
|
"react-native-elements": "^0.19.0",
|
||||||
"react-native-flexi-radio-button": "^0.2.2",
|
"react-native-flexi-radio-button": "^0.2.2",
|
||||||
"react-native-fs": "^2.13.3",
|
"react-native-fs": "^2.13.3",
|
||||||
"react-native-gesture-handler": "^1.0.15",
|
"react-native-gesture-handler": "^1.0.15",
|
||||||
"react-native-google-analytics-bridge": "^7.0.0",
|
"react-native-google-analytics-bridge": "^7.0.0",
|
||||||
"react-native-haptic-feedback": "^1.4.2",
|
"react-native-haptic-feedback": "^1.5.0",
|
||||||
"react-native-image-picker": "^0.28.0",
|
"react-native-image-picker": "^0.28.0",
|
||||||
"react-native-level-fs": "^3.0.1",
|
"react-native-level-fs": "^3.0.1",
|
||||||
"react-native-linear-gradient": "^2.5.3",
|
"react-native-linear-gradient": "^2.5.3",
|
||||||
|
@ -81,20 +81,20 @@
|
||||||
"react-native-qrcode": "^0.2.7",
|
"react-native-qrcode": "^0.2.7",
|
||||||
"react-native-randombytes": "^3.5.2",
|
"react-native-randombytes": "^3.5.2",
|
||||||
"react-native-rate": "^1.1.6",
|
"react-native-rate": "^1.1.6",
|
||||||
"react-native-sentry": "^0.40.2",
|
"react-native-sentry": "^0.41.1",
|
||||||
"react-native-snap-carousel": "^3.7.5",
|
"react-native-snap-carousel": "^3.7.5",
|
||||||
"react-native-sortable-list": "0.0.22",
|
"react-native-sortable-list": "0.0.22",
|
||||||
"react-native-svg": "^9.0.4",
|
"react-native-svg": "^9.1.1",
|
||||||
"react-native-tcp": "^3.3.0",
|
"react-native-tcp": "^3.3.0",
|
||||||
"react-native-vector-icons": "^6.2.0",
|
"react-native-vector-icons": "^6.2.0",
|
||||||
"react-native-webview": "^3.2.1",
|
"react-native-webview": "4.1.0",
|
||||||
"react-native-wkwebview-reborn": "^2.0.0",
|
"react-native-wkwebview-reborn": "^2.0.0",
|
||||||
"react-navigation": "^3.0.9",
|
"react-navigation": "^3.1.2",
|
||||||
"react-test-render": "^1.1.1",
|
"react-test-render": "^1.1.1",
|
||||||
"readable-stream": "^1.1.14",
|
"readable-stream": "^3.1.1",
|
||||||
"request-promise-native": "^1.0.5",
|
"request-promise-native": "^1.0.5",
|
||||||
"secure-random": "^1.1.1",
|
"secure-random": "^1.1.1",
|
||||||
"stream-browserify": "^1.0.0",
|
"stream-browserify": "^2.0.2",
|
||||||
"util": "^0.11.1",
|
"util": "^0.11.1",
|
||||||
"wif": "^2.0.1"
|
"wif": "^2.0.1"
|
||||||
},
|
},
|
||||||
|
|
|
@ -495,7 +495,7 @@ export default class Browser extends Component {
|
||||||
|
|
||||||
Browser.propTypes = {
|
Browser.propTypes = {
|
||||||
navigation: PropTypes.shape({
|
navigation: PropTypes.shape({
|
||||||
getParam: PropTypes.function,
|
getParam: PropTypes.func,
|
||||||
navigate: PropTypes.func,
|
navigate: PropTypes.func,
|
||||||
}),
|
}),
|
||||||
};
|
};
|
||||||
|
|
|
@ -116,7 +116,7 @@ export default class LNDCreateInvoice extends Component {
|
||||||
|
|
||||||
LNDCreateInvoice.propTypes = {
|
LNDCreateInvoice.propTypes = {
|
||||||
navigation: PropTypes.shape({
|
navigation: PropTypes.shape({
|
||||||
goBack: PropTypes.function,
|
goBack: PropTypes.func,
|
||||||
navigate: PropTypes.func,
|
navigate: PropTypes.func,
|
||||||
getParam: PropTypes.func,
|
getParam: PropTypes.func,
|
||||||
}),
|
}),
|
||||||
|
|
|
@ -82,8 +82,8 @@ export default class LNDViewAdditionalInvoiceInformation extends Component {
|
||||||
|
|
||||||
LNDViewAdditionalInvoiceInformation.propTypes = {
|
LNDViewAdditionalInvoiceInformation.propTypes = {
|
||||||
navigation: PropTypes.shape({
|
navigation: PropTypes.shape({
|
||||||
goBack: PropTypes.function,
|
goBack: PropTypes.func,
|
||||||
getParam: PropTypes.function,
|
getParam: PropTypes.func,
|
||||||
dismiss: PropTypes.function,
|
dismiss: PropTypes.func,
|
||||||
}),
|
}),
|
||||||
};
|
};
|
||||||
|
|
|
@ -236,9 +236,9 @@ export default class LNDViewInvoice extends Component {
|
||||||
|
|
||||||
LNDViewInvoice.propTypes = {
|
LNDViewInvoice.propTypes = {
|
||||||
navigation: PropTypes.shape({
|
navigation: PropTypes.shape({
|
||||||
goBack: PropTypes.function,
|
goBack: PropTypes.func,
|
||||||
navigate: PropTypes.function,
|
navigate: PropTypes.func,
|
||||||
getParam: PropTypes.function,
|
getParam: PropTypes.func,
|
||||||
dismiss: PropTypes.function,
|
dismiss: PropTypes.func,
|
||||||
}),
|
}),
|
||||||
};
|
};
|
||||||
|
|
|
@ -83,10 +83,10 @@ export default class ManageFunds extends Component {
|
||||||
|
|
||||||
ManageFunds.propTypes = {
|
ManageFunds.propTypes = {
|
||||||
navigation: PropTypes.shape({
|
navigation: PropTypes.shape({
|
||||||
goBack: PropTypes.function,
|
goBack: PropTypes.func,
|
||||||
dismiss: PropTypes.function,
|
dismiss: PropTypes.func,
|
||||||
navigate: PropTypes.function,
|
navigate: PropTypes.func,
|
||||||
getParam: PropTypes.function,
|
getParam: PropTypes.func,
|
||||||
state: PropTypes.shape({
|
state: PropTypes.shape({
|
||||||
params: PropTypes.shape({
|
params: PropTypes.shape({
|
||||||
fromSecret: PropTypes.string,
|
fromSecret: PropTypes.string,
|
||||||
|
|
|
@ -72,12 +72,6 @@ export default class ScanLndInvoice extends React.Component {
|
||||||
|
|
||||||
processInvoice = data => {
|
processInvoice = data => {
|
||||||
this.setState({ isLoading: true }, async () => {
|
this.setState({ isLoading: true }, async () => {
|
||||||
if (this.ignoreRead) return;
|
|
||||||
this.ignoreRead = true;
|
|
||||||
setTimeout(() => {
|
|
||||||
this.ignoreRead = false;
|
|
||||||
}, 6000);
|
|
||||||
|
|
||||||
if (!this.state.fromWallet) {
|
if (!this.state.fromWallet) {
|
||||||
alert('Before paying a Lightning invoice, you must first add a Lightning wallet.');
|
alert('Before paying a Lightning invoice, you must first add a Lightning wallet.');
|
||||||
return this.props.navigation.goBack();
|
return this.props.navigation.goBack();
|
||||||
|
@ -149,11 +143,8 @@ export default class ScanLndInvoice extends React.Component {
|
||||||
return alert(loc.lnd.sameWalletAsInvoiceError);
|
return alert(loc.lnd.sameWalletAsInvoiceError);
|
||||||
}
|
}
|
||||||
|
|
||||||
let start = +new Date();
|
|
||||||
let end;
|
|
||||||
try {
|
try {
|
||||||
await fromWallet.payInvoice(this.state.invoice, this.state.decoded.num_satoshis);
|
await fromWallet.payInvoice(this.state.invoice, this.state.decoded.num_satoshis);
|
||||||
end = +new Date();
|
|
||||||
} catch (Err) {
|
} catch (Err) {
|
||||||
console.log(Err.message);
|
console.log(Err.message);
|
||||||
this.setState({ isLoading: false });
|
this.setState({ isLoading: false });
|
||||||
|
@ -161,11 +152,12 @@ export default class ScanLndInvoice extends React.Component {
|
||||||
return alert('Error');
|
return alert('Error');
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log('payInvoice took', (end - start) / 1000, 'sec');
|
|
||||||
EV(EV.enum.REMOTE_TRANSACTIONS_COUNT_CHANGED); // someone should fetch txs
|
EV(EV.enum.REMOTE_TRANSACTIONS_COUNT_CHANGED); // someone should fetch txs
|
||||||
|
this.props.navigation.navigate('Success', {
|
||||||
alert('Success');
|
amount: this.state.decoded.num_satoshis,
|
||||||
this.props.navigation.goBack();
|
amountUnit: BitcoinUnit.SATS,
|
||||||
|
invoiceDescription: this.state.decoded.description,
|
||||||
|
});
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -237,24 +229,26 @@ export default class ScanLndInvoice extends React.Component {
|
||||||
)}
|
)}
|
||||||
<BlueSpacing20 />
|
<BlueSpacing20 />
|
||||||
<BlueSpacing20 />
|
<BlueSpacing20 />
|
||||||
{this.state.isLoading ? (
|
<BlueCard>
|
||||||
<View>
|
{this.state.isLoading ? (
|
||||||
<ActivityIndicator />
|
<View>
|
||||||
</View>
|
<ActivityIndicator />
|
||||||
) : (
|
</View>
|
||||||
<BlueButton
|
) : (
|
||||||
icon={{
|
<BlueButton
|
||||||
name: 'bolt',
|
icon={{
|
||||||
type: 'font-awesome',
|
name: 'bolt',
|
||||||
color: BlueApp.settings.buttonTextColor,
|
type: 'font-awesome',
|
||||||
}}
|
color: BlueApp.settings.buttonTextColor,
|
||||||
title={'Pay'}
|
}}
|
||||||
onPress={() => {
|
title={'Pay'}
|
||||||
this.pay();
|
onPress={() => {
|
||||||
}}
|
this.pay();
|
||||||
disabled={this.shouldDisablePayButton()}
|
}}
|
||||||
/>
|
disabled={this.shouldDisablePayButton()}
|
||||||
)}
|
/>
|
||||||
|
)}
|
||||||
|
</BlueCard>
|
||||||
</BlueCard>
|
</BlueCard>
|
||||||
</SafeBlueArea>
|
</SafeBlueArea>
|
||||||
</TouchableWithoutFeedback>
|
</TouchableWithoutFeedback>
|
||||||
|
@ -264,10 +258,10 @@ export default class ScanLndInvoice extends React.Component {
|
||||||
|
|
||||||
ScanLndInvoice.propTypes = {
|
ScanLndInvoice.propTypes = {
|
||||||
navigation: PropTypes.shape({
|
navigation: PropTypes.shape({
|
||||||
goBack: PropTypes.function,
|
goBack: PropTypes.func,
|
||||||
navigate: PropTypes.function,
|
navigate: PropTypes.func,
|
||||||
getParam: PropTypes.function,
|
getParam: PropTypes.func,
|
||||||
dismiss: PropTypes.function,
|
dismiss: PropTypes.func,
|
||||||
state: PropTypes.shape({
|
state: PropTypes.shape({
|
||||||
params: PropTypes.shape({
|
params: PropTypes.shape({
|
||||||
uri: PropTypes.string,
|
uri: PropTypes.string,
|
||||||
|
|
|
@ -10,7 +10,6 @@ import {
|
||||||
BlueButtonLink,
|
BlueButtonLink,
|
||||||
BlueNavigationStyle,
|
BlueNavigationStyle,
|
||||||
is,
|
is,
|
||||||
BlueSpacing20,
|
|
||||||
} from '../../BlueComponents';
|
} from '../../BlueComponents';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
/** @type {AppStorage} */
|
/** @type {AppStorage} */
|
||||||
|
@ -107,7 +106,6 @@ export default class ReceiveDetails extends Component {
|
||||||
});
|
});
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
<BlueSpacing20 />
|
|
||||||
<BlueButton
|
<BlueButton
|
||||||
icon={{
|
icon={{
|
||||||
name: 'share-alternative',
|
name: 'share-alternative',
|
||||||
|
@ -130,8 +128,8 @@ export default class ReceiveDetails extends Component {
|
||||||
|
|
||||||
ReceiveDetails.propTypes = {
|
ReceiveDetails.propTypes = {
|
||||||
navigation: PropTypes.shape({
|
navigation: PropTypes.shape({
|
||||||
goBack: PropTypes.function,
|
goBack: PropTypes.func,
|
||||||
navigate: PropTypes.function,
|
navigate: PropTypes.func,
|
||||||
state: PropTypes.shape({
|
state: PropTypes.shape({
|
||||||
params: PropTypes.shape({
|
params: PropTypes.shape({
|
||||||
address: PropTypes.string,
|
address: PropTypes.string,
|
||||||
|
|
|
@ -146,10 +146,10 @@ const styles = StyleSheet.create({
|
||||||
|
|
||||||
Confirm.propTypes = {
|
Confirm.propTypes = {
|
||||||
navigation: PropTypes.shape({
|
navigation: PropTypes.shape({
|
||||||
goBack: PropTypes.function,
|
goBack: PropTypes.func,
|
||||||
getParam: PropTypes.function,
|
getParam: PropTypes.func,
|
||||||
navigate: PropTypes.function,
|
navigate: PropTypes.func,
|
||||||
dismiss: PropTypes.function,
|
dismiss: PropTypes.func,
|
||||||
state: PropTypes.shape({
|
state: PropTypes.shape({
|
||||||
params: PropTypes.shape({
|
params: PropTypes.shape({
|
||||||
amount: PropTypes.string,
|
amount: PropTypes.string,
|
||||||
|
|
|
@ -108,10 +108,10 @@ const styles = StyleSheet.create({
|
||||||
|
|
||||||
SendCreate.propTypes = {
|
SendCreate.propTypes = {
|
||||||
navigation: PropTypes.shape({
|
navigation: PropTypes.shape({
|
||||||
goBack: PropTypes.function,
|
goBack: PropTypes.func,
|
||||||
getParam: PropTypes.function,
|
getParam: PropTypes.func,
|
||||||
navigate: PropTypes.function,
|
navigate: PropTypes.func,
|
||||||
dismiss: PropTypes.function,
|
dismiss: PropTypes.func,
|
||||||
state: PropTypes.shape({
|
state: PropTypes.shape({
|
||||||
params: PropTypes.shape({
|
params: PropTypes.shape({
|
||||||
amount: PropTypes.string,
|
amount: PropTypes.string,
|
||||||
|
|
|
@ -11,6 +11,7 @@ import {
|
||||||
StyleSheet,
|
StyleSheet,
|
||||||
Platform,
|
Platform,
|
||||||
Slider,
|
Slider,
|
||||||
|
AsyncStorage,
|
||||||
Text,
|
Text,
|
||||||
} from 'react-native';
|
} from 'react-native';
|
||||||
import { Icon } from 'react-native-elements';
|
import { Icon } from 'react-native-elements';
|
||||||
|
@ -71,13 +72,14 @@ export default class SendDetails extends Component {
|
||||||
fromAddress,
|
fromAddress,
|
||||||
fromWallet,
|
fromWallet,
|
||||||
fromSecret,
|
fromSecret,
|
||||||
isLoading: true,
|
isLoading: false,
|
||||||
address,
|
address,
|
||||||
memo,
|
memo,
|
||||||
fee: 1,
|
fee: 1,
|
||||||
networkTransactionFees: new NetworkTransactionFee(1, 1, 1),
|
networkTransactionFees: new NetworkTransactionFee(1, 1, 1),
|
||||||
feeSliderValue: 1,
|
feeSliderValue: 1,
|
||||||
bip70TransactionExpiration: null,
|
bip70TransactionExpiration: null,
|
||||||
|
renderWalletSelectionButtonHidden: false,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -91,7 +93,7 @@ export default class SendDetails extends Component {
|
||||||
const dataWithoutSchema = data.replace('bitcoin:', '');
|
const dataWithoutSchema = data.replace('bitcoin:', '');
|
||||||
if (btcAddressRx.test(dataWithoutSchema) || dataWithoutSchema.indexOf('bc1') === 0) {
|
if (btcAddressRx.test(dataWithoutSchema) || dataWithoutSchema.indexOf('bc1') === 0) {
|
||||||
this.setState({
|
this.setState({
|
||||||
address: data,
|
address: dataWithoutSchema,
|
||||||
bip70TransactionExpiration: null,
|
bip70TransactionExpiration: null,
|
||||||
isLoading: false,
|
isLoading: false,
|
||||||
});
|
});
|
||||||
|
@ -126,20 +128,27 @@ export default class SendDetails extends Component {
|
||||||
};
|
};
|
||||||
|
|
||||||
async componentDidMount() {
|
async componentDidMount() {
|
||||||
let recommendedFees = await NetworkTransactionFees.recommendedFees().catch(response => {
|
this.keyboardDidShowListener = Keyboard.addListener('keyboardDidShow', this._keyboardDidShow);
|
||||||
this.setState({
|
this.keyboardDidHideListener = Keyboard.addListener('keyboardDidHide', this._keyboardDidHide);
|
||||||
fee: response.halfHourFee,
|
try {
|
||||||
networkTransactionFees: response,
|
const cachedNetworkTransactionFees = JSON.parse(await AsyncStorage.getItem(NetworkTransactionFee.StorageKey));
|
||||||
feeSliderValue: response.halfHourFee,
|
|
||||||
isLoading: false,
|
if (cachedNetworkTransactionFees && cachedNetworkTransactionFees.hasOwnProperty('halfHourFee')) {
|
||||||
});
|
this.setState({
|
||||||
});
|
fee: cachedNetworkTransactionFees.halfHourFee,
|
||||||
if (recommendedFees) {
|
networkTransactionFees: cachedNetworkTransactionFees,
|
||||||
|
feeSliderValue: cachedNetworkTransactionFees.halfHourFee,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} catch (_) {}
|
||||||
|
|
||||||
|
let recommendedFees = await NetworkTransactionFees.recommendedFees();
|
||||||
|
if (recommendedFees && recommendedFees.hasOwnProperty('halfHourFee')) {
|
||||||
|
await AsyncStorage.setItem(NetworkTransactionFee.StorageKey, JSON.stringify(recommendedFees));
|
||||||
this.setState({
|
this.setState({
|
||||||
fee: recommendedFees.halfHourFee,
|
fee: recommendedFees.halfHourFee,
|
||||||
networkTransactionFees: recommendedFees,
|
networkTransactionFees: recommendedFees,
|
||||||
feeSliderValue: recommendedFees.halfHourFee,
|
feeSliderValue: recommendedFees.halfHourFee,
|
||||||
isLoading: false,
|
|
||||||
});
|
});
|
||||||
|
|
||||||
if (this.props.navigation.state.params.uri) {
|
if (this.props.navigation.state.params.uri) {
|
||||||
|
@ -148,16 +157,34 @@ export default class SendDetails extends Component {
|
||||||
} else {
|
} else {
|
||||||
try {
|
try {
|
||||||
const { address, amount, memo } = this.decodeBitcoinUri(this.props.navigation.getParam('uri'));
|
const { address, amount, memo } = this.decodeBitcoinUri(this.props.navigation.getParam('uri'));
|
||||||
this.setState({ address, amount, memo });
|
this.setState({ address, amount, memo, isLoading: false });
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log(error);
|
console.log(error);
|
||||||
|
this.setState({ isLoading: false });
|
||||||
alert('Error: Unable to decode Bitcoin address');
|
alert('Error: Unable to decode Bitcoin address');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
this.setState({ isLoading: false });
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
this.setState({ isLoading: false });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
componentWillUnmount() {
|
||||||
|
this.keyboardDidShowListener.remove();
|
||||||
|
this.keyboardDidHideListener.remove();
|
||||||
|
}
|
||||||
|
|
||||||
|
_keyboardDidShow = () => {
|
||||||
|
this.setState({ renderWalletSelectionButtonHidden: true });
|
||||||
|
};
|
||||||
|
|
||||||
|
_keyboardDidHide = () => {
|
||||||
|
this.setState({ renderWalletSelectionButtonHidden: false });
|
||||||
|
};
|
||||||
|
|
||||||
decodeBitcoinUri(uri) {
|
decodeBitcoinUri(uri) {
|
||||||
try {
|
try {
|
||||||
let amount = '';
|
let amount = '';
|
||||||
|
@ -382,9 +409,9 @@ export default class SendDetails extends Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
onWalletSelect = wallet => {
|
onWalletSelect = wallet => {
|
||||||
this.setState({ fromAddress: wallet.getAddress(), fromSecret: wallet.getSecret(), fromWallet: wallet }, () =>
|
this.setState({ fromAddress: wallet.getAddress(), fromSecret: wallet.getSecret(), fromWallet: wallet }, () => {
|
||||||
this.props.navigation.goBack(null),
|
this.props.navigation.pop();
|
||||||
);
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
renderFeeSelectionModal = () => {
|
renderFeeSelectionModal = () => {
|
||||||
|
@ -392,7 +419,13 @@ export default class SendDetails extends Component {
|
||||||
<Modal
|
<Modal
|
||||||
isVisible={this.state.isFeeSelectionModalVisible}
|
isVisible={this.state.isFeeSelectionModalVisible}
|
||||||
style={styles.bottomModal}
|
style={styles.bottomModal}
|
||||||
onBackdropPress={() => this.setState({ isFeeSelectionModalVisible: false })}
|
onBackdropPress={() => {
|
||||||
|
if (this.state.fee < 1 || this.state.feeSliderValue < 1) {
|
||||||
|
this.setState({ fee: Number(1), feeSliderValue: Number(1) });
|
||||||
|
}
|
||||||
|
Keyboard.dismiss();
|
||||||
|
this.setState({ isFeeSelectionModalVisible: false });
|
||||||
|
}}
|
||||||
>
|
>
|
||||||
<KeyboardAvoidingView behavior={Platform.OS === 'ios' ? 'position' : null}>
|
<KeyboardAvoidingView behavior={Platform.OS === 'ios' ? 'position' : null}>
|
||||||
<View style={styles.modalContent}>
|
<View style={styles.modalContent}>
|
||||||
|
@ -403,12 +436,14 @@ export default class SendDetails extends Component {
|
||||||
this.textInput = ref;
|
this.textInput = ref;
|
||||||
}}
|
}}
|
||||||
value={this.state.fee.toString()}
|
value={this.state.fee.toString()}
|
||||||
|
onEndEditing={() => {
|
||||||
|
if (this.state.fee < 1 || this.state.feeSliderValue < 1) {
|
||||||
|
this.setState({ fee: Number(1), feeSliderValue: Number(1) });
|
||||||
|
}
|
||||||
|
}}
|
||||||
onChangeText={value => {
|
onChangeText={value => {
|
||||||
let newValue = value.replace(/\D/g, '');
|
let newValue = value.replace(/\D/g, '');
|
||||||
if (newValue.length === 0) {
|
this.setState({ fee: Number(newValue), feeSliderValue: Number(newValue) });
|
||||||
newValue = 1;
|
|
||||||
}
|
|
||||||
this.setState({ fee: newValue, feeSliderValue: newValue });
|
|
||||||
}}
|
}}
|
||||||
maxLength={9}
|
maxLength={9}
|
||||||
editable={!this.state.isLoading}
|
editable={!this.state.isLoading}
|
||||||
|
@ -466,6 +501,7 @@ export default class SendDetails extends Component {
|
||||||
};
|
};
|
||||||
|
|
||||||
renderWalletSelectionButton = () => {
|
renderWalletSelectionButton = () => {
|
||||||
|
if (this.state.renderWalletSelectionButtonHidden) return;
|
||||||
return (
|
return (
|
||||||
<View style={{ marginBottom: 24, alignItems: 'center' }}>
|
<View style={{ marginBottom: 24, alignItems: 'center' }}>
|
||||||
{!this.state.isLoading && (
|
{!this.state.isLoading && (
|
||||||
|
@ -500,7 +536,6 @@ export default class SendDetails extends Component {
|
||||||
</View>
|
</View>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<TouchableWithoutFeedback onPress={Keyboard.dismiss} accessible={false}>
|
<TouchableWithoutFeedback onPress={Keyboard.dismiss} accessible={false}>
|
||||||
<View style={{ flex: 1, justifyContent: 'space-between' }}>
|
<View style={{ flex: 1, justifyContent: 'space-between' }}>
|
||||||
|
@ -620,7 +655,7 @@ const styles = StyleSheet.create({
|
||||||
|
|
||||||
SendDetails.propTypes = {
|
SendDetails.propTypes = {
|
||||||
navigation: PropTypes.shape({
|
navigation: PropTypes.shape({
|
||||||
goBack: PropTypes.func,
|
pop: PropTypes.func,
|
||||||
navigate: PropTypes.func,
|
navigate: PropTypes.func,
|
||||||
getParam: PropTypes.func,
|
getParam: PropTypes.func,
|
||||||
state: PropTypes.shape({
|
state: PropTypes.shape({
|
||||||
|
|
|
@ -16,10 +16,12 @@ export default class CameraExample extends React.Component {
|
||||||
};
|
};
|
||||||
|
|
||||||
onBarCodeScanned(ret) {
|
onBarCodeScanned(ret) {
|
||||||
console.warn(ret);
|
if (this.state.isLoading) return;
|
||||||
const onBarScanned = this.props.navigation.getParam('onBarScanned');
|
this.setState({ isLoading: true }, () => {
|
||||||
onBarScanned(ret.data);
|
const onBarScanned = this.props.navigation.getParam('onBarScanned');
|
||||||
this.props.navigation.goBack(null);
|
this.props.navigation.goBack();
|
||||||
|
onBarScanned(ret.data);
|
||||||
|
});
|
||||||
} // end
|
} // end
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
|
|
|
@ -18,7 +18,9 @@ export default class Success extends Component {
|
||||||
|
|
||||||
this.state = {
|
this.state = {
|
||||||
amount: props.navigation.getParam('amount'),
|
amount: props.navigation.getParam('amount'),
|
||||||
fee: props.navigation.getParam('fee'),
|
fee: props.navigation.getParam('fee') || 0,
|
||||||
|
amountUnit: props.navigation.getParam('amountUnit') || BitcoinUnit.BTC,
|
||||||
|
invoiceDescription: props.navigation.getParam('invoiceDescription') || '',
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -51,21 +53,38 @@ export default class Success extends Component {
|
||||||
alignSelf: 'flex-end',
|
alignSelf: 'flex-end',
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{' ' + BitcoinUnit.BTC}
|
{' ' + this.state.amountUnit}
|
||||||
</Text>
|
</Text>
|
||||||
</View>
|
</View>
|
||||||
<Text
|
{this.state.fee > 0 && (
|
||||||
style={{
|
<Text
|
||||||
color: '#37c0a1',
|
style={{
|
||||||
fontSize: 14,
|
color: '#37c0a1',
|
||||||
marginHorizontal: 4,
|
fontSize: 14,
|
||||||
paddingBottom: 6,
|
marginHorizontal: 4,
|
||||||
fontWeight: '500',
|
paddingBottom: 6,
|
||||||
alignSelf: 'center',
|
fontWeight: '500',
|
||||||
}}
|
alignSelf: 'center',
|
||||||
>
|
}}
|
||||||
{loc.send.create.fee}: {loc.formatBalance(this.state.fee, BitcoinUnit.SATS)}
|
>
|
||||||
</Text>
|
{loc.send.create.fee}: {loc.formatBalance(this.state.fee, BitcoinUnit.SATS)}
|
||||||
|
</Text>
|
||||||
|
)}
|
||||||
|
{this.state.fee <= 0 && (
|
||||||
|
<Text
|
||||||
|
numberOfLines={0}
|
||||||
|
style={{
|
||||||
|
color: '#37c0a1',
|
||||||
|
fontSize: 14,
|
||||||
|
marginHorizontal: 4,
|
||||||
|
paddingBottom: 6,
|
||||||
|
fontWeight: '500',
|
||||||
|
alignSelf: 'center',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{this.state.invoiceDescription}
|
||||||
|
</Text>
|
||||||
|
)}
|
||||||
</BlueCard>
|
</BlueCard>
|
||||||
<View
|
<View
|
||||||
style={{
|
style={{
|
||||||
|
@ -87,7 +106,6 @@ export default class Success extends Component {
|
||||||
this.props.navigation.dismiss();
|
this.props.navigation.dismiss();
|
||||||
}}
|
}}
|
||||||
title={loc.send.success.done}
|
title={loc.send.success.done}
|
||||||
style={{ maxWidth: 263, paddingHorizontal: 56 }}
|
|
||||||
/>
|
/>
|
||||||
</BlueCard>
|
</BlueCard>
|
||||||
</SafeBlueArea>
|
</SafeBlueArea>
|
||||||
|
@ -97,10 +115,10 @@ export default class Success extends Component {
|
||||||
|
|
||||||
Success.propTypes = {
|
Success.propTypes = {
|
||||||
navigation: PropTypes.shape({
|
navigation: PropTypes.shape({
|
||||||
goBack: PropTypes.function,
|
goBack: PropTypes.func,
|
||||||
getParam: PropTypes.function,
|
getParam: PropTypes.func,
|
||||||
navigate: PropTypes.function,
|
navigate: PropTypes.func,
|
||||||
dismiss: PropTypes.function,
|
dismiss: PropTypes.func,
|
||||||
state: PropTypes.shape({
|
state: PropTypes.shape({
|
||||||
params: PropTypes.shape({
|
params: PropTypes.shape({
|
||||||
amount: PropTypes.string,
|
amount: PropTypes.string,
|
||||||
|
|
|
@ -129,7 +129,7 @@ export default class About extends Component {
|
||||||
|
|
||||||
<BlueButton
|
<BlueButton
|
||||||
onPress={() => {
|
onPress={() => {
|
||||||
this.props.navigation.navigate('Releasenotes');
|
this.props.navigation.navigate('ReleaseNotes');
|
||||||
}}
|
}}
|
||||||
title="Release notes"
|
title="Release notes"
|
||||||
/>
|
/>
|
||||||
|
|
|
@ -5,7 +5,7 @@ import PropTypes from 'prop-types';
|
||||||
/** @type {AppStorage} */
|
/** @type {AppStorage} */
|
||||||
const notes = require('../../release-notes');
|
const notes = require('../../release-notes');
|
||||||
|
|
||||||
export default class Releasenotes extends Component {
|
export default class ReleaseNotes extends Component {
|
||||||
static navigationOptions = () => ({
|
static navigationOptions = () => ({
|
||||||
...BlueNavigationStyle(),
|
...BlueNavigationStyle(),
|
||||||
title: 'Release notes',
|
title: 'Release notes',
|
||||||
|
@ -43,7 +43,7 @@ export default class Releasenotes extends Component {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Releasenotes.propTypes = {
|
ReleaseNotes.propTypes = {
|
||||||
navigation: PropTypes.shape({
|
navigation: PropTypes.shape({
|
||||||
navigate: PropTypes.func,
|
navigate: PropTypes.func,
|
||||||
goBack: PropTypes.func,
|
goBack: PropTypes.func,
|
||||||
|
|
|
@ -234,7 +234,7 @@ export default class SendCreate extends Component {
|
||||||
|
|
||||||
SendCreate.propTypes = {
|
SendCreate.propTypes = {
|
||||||
navigation: PropTypes.shape({
|
navigation: PropTypes.shape({
|
||||||
goBack: PropTypes.function,
|
goBack: PropTypes.func,
|
||||||
navigate: PropTypes.func,
|
navigate: PropTypes.func,
|
||||||
state: PropTypes.shape({
|
state: PropTypes.shape({
|
||||||
params: PropTypes.shape({
|
params: PropTypes.shape({
|
||||||
|
|
|
@ -191,7 +191,7 @@ export default class RBF extends Component {
|
||||||
|
|
||||||
RBF.propTypes = {
|
RBF.propTypes = {
|
||||||
navigation: PropTypes.shape({
|
navigation: PropTypes.shape({
|
||||||
goBack: PropTypes.function,
|
goBack: PropTypes.func,
|
||||||
navigate: PropTypes.func,
|
navigate: PropTypes.func,
|
||||||
state: PropTypes.shape({
|
state: PropTypes.shape({
|
||||||
params: PropTypes.shape({
|
params: PropTypes.shape({
|
||||||
|
|
|
@ -89,22 +89,25 @@ export default class TransactionsDetails extends Component {
|
||||||
<SafeBlueArea forceInset={{ horizontal: 'always' }} style={{ flex: 1 }}>
|
<SafeBlueArea forceInset={{ horizontal: 'always' }} style={{ flex: 1 }}>
|
||||||
<BlueHeaderDefaultSub leftText={loc.transactions.details.title} rightComponent={null} />
|
<BlueHeaderDefaultSub leftText={loc.transactions.details.title} rightComponent={null} />
|
||||||
<ScrollView style={{ flex: 1 }}>
|
<ScrollView style={{ flex: 1 }}>
|
||||||
{(() => {
|
|
||||||
if (this.state.tx.confirmations === 0 && this.state.wallet && this.state.wallet.allowRBF()) {
|
|
||||||
return (
|
|
||||||
<BlueButton
|
|
||||||
onPress={() =>
|
|
||||||
this.props.navigation.navigate('RBF', {
|
|
||||||
txid: this.state.tx.hash,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
title="Replace-By-Fee (RBF)"
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
})()}
|
|
||||||
|
|
||||||
<BlueCard>
|
<BlueCard>
|
||||||
|
{(() => {
|
||||||
|
if (this.state.tx.confirmations === 0 && this.state.wallet && this.state.wallet.allowRBF()) {
|
||||||
|
return (
|
||||||
|
<React.Fragment>
|
||||||
|
<BlueButton
|
||||||
|
onPress={() =>
|
||||||
|
this.props.navigation.navigate('RBF', {
|
||||||
|
txid: this.state.tx.hash,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
title="Replace-By-Fee (RBF)"
|
||||||
|
/>
|
||||||
|
<BlueSpacing20 />
|
||||||
|
</React.Fragment>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
})()}
|
||||||
|
|
||||||
{(() => {
|
{(() => {
|
||||||
if (BlueApp.tx_metadata[this.state.tx.hash]) {
|
if (BlueApp.tx_metadata[this.state.tx.hash]) {
|
||||||
if (BlueApp.tx_metadata[this.state.tx.hash]['memo']) {
|
if (BlueApp.tx_metadata[this.state.tx.hash]['memo']) {
|
||||||
|
@ -176,14 +179,14 @@ export default class TransactionsDetails extends Component {
|
||||||
</React.Fragment>
|
</React.Fragment>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{this.state.tx.hasOwnProperty('block_height') && this.state.block_height > 0 && (
|
{this.state.tx.hasOwnProperty('block_height') && this.state.tx.block_height > 0 && (
|
||||||
<React.Fragment>
|
<React.Fragment>
|
||||||
<BlueText style={{ fontSize: 16, fontWeight: '500', marginBottom: 4 }}>Block Height</BlueText>
|
<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={{ marginBottom: 26, color: 'grey' }}>{this.state.tx.block_height}</BlueText>
|
||||||
</React.Fragment>
|
</React.Fragment>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{this.state.tx.hasOwnProperty('confirmations') && (
|
{this.state.tx.hasOwnProperty('confirmations') && this.state.tx.confirmations > 0 && (
|
||||||
<React.Fragment>
|
<React.Fragment>
|
||||||
<BlueText style={{ fontSize: 16, fontWeight: '500', marginBottom: 4 }}>Confirmations</BlueText>
|
<BlueText style={{ fontSize: 16, fontWeight: '500', marginBottom: 4 }}>Confirmations</BlueText>
|
||||||
<BlueText style={{ marginBottom: 26, color: 'grey' }}>{this.state.tx.confirmations}</BlueText>
|
<BlueText style={{ marginBottom: 26, color: 'grey' }}>{this.state.tx.confirmations}</BlueText>
|
||||||
|
@ -197,7 +200,7 @@ export default class TransactionsDetails extends Component {
|
||||||
</React.Fragment>
|
</React.Fragment>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{this.state.tx.hasOwnProperty('outputs') && (
|
{this.state.tx.hasOwnProperty('outputs') && this.state.tx.outputs.length > 0 && (
|
||||||
<React.Fragment>
|
<React.Fragment>
|
||||||
<BlueText style={{ fontSize: 16, fontWeight: '500', marginBottom: 4 }}>Outputs</BlueText>
|
<BlueText style={{ fontSize: 16, fontWeight: '500', marginBottom: 4 }}>Outputs</BlueText>
|
||||||
<BlueText style={{ marginBottom: 26, color: 'grey' }}>{this.state.tx.outputs.length}</BlueText>
|
<BlueText style={{ marginBottom: 26, color: 'grey' }}>{this.state.tx.outputs.length}</BlueText>
|
||||||
|
@ -212,7 +215,7 @@ export default class TransactionsDetails extends Component {
|
||||||
|
|
||||||
TransactionsDetails.propTypes = {
|
TransactionsDetails.propTypes = {
|
||||||
navigation: PropTypes.shape({
|
navigation: PropTypes.shape({
|
||||||
goBack: PropTypes.function,
|
goBack: PropTypes.func,
|
||||||
navigate: PropTypes.func,
|
navigate: PropTypes.func,
|
||||||
state: PropTypes.shape({
|
state: PropTypes.shape({
|
||||||
params: PropTypes.shape({
|
params: PropTypes.shape({
|
||||||
|
|
|
@ -72,7 +72,7 @@ export default class WalletsAdd extends Component {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<SafeBlueArea forceInset={{ horizontal: 'always' }} style={{ flex: 1, paddingTop: 40 }}>
|
<SafeBlueArea forceInset={{ horizontal: 'always' }} style={{ flex: 1, paddingTop: 40 }}>
|
||||||
<TouchableWithoutFeedback onPress={Keyboard.dismiss} accessible={false}>
|
<TouchableWithoutFeedback onPress={Keyboard.dismiss} accessible={false} style={{ flex: 1 }}>
|
||||||
<BlueCard>
|
<BlueCard>
|
||||||
<BlueFormLabel>{loc.wallets.add.wallet_name}</BlueFormLabel>
|
<BlueFormLabel>{loc.wallets.add.wallet_name}</BlueFormLabel>
|
||||||
<View
|
<View
|
||||||
|
|
|
@ -107,7 +107,7 @@ export default class BuyBitcoin extends Component {
|
||||||
|
|
||||||
BuyBitcoin.propTypes = {
|
BuyBitcoin.propTypes = {
|
||||||
navigation: PropTypes.shape({
|
navigation: PropTypes.shape({
|
||||||
goBack: PropTypes.function,
|
goBack: PropTypes.func,
|
||||||
state: PropTypes.shape({
|
state: PropTypes.shape({
|
||||||
params: PropTypes.shape({
|
params: PropTypes.shape({
|
||||||
address: PropTypes.string,
|
address: PropTypes.string,
|
||||||
|
|
|
@ -215,38 +215,39 @@ export default class WalletsImport extends Component {
|
||||||
this.setLabel(text);
|
this.setLabel(text);
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
<BlueSpacing20 />
|
|
||||||
<View
|
|
||||||
style={{
|
|
||||||
alignItems: 'center',
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<BlueButton
|
|
||||||
disabled={!this.state.label}
|
|
||||||
title={loc.wallets.import.do_import}
|
|
||||||
buttonStyle={{
|
|
||||||
width: width / 1.5,
|
|
||||||
}}
|
|
||||||
onPress={async () => {
|
|
||||||
if (!this.state.label) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
this.setState({ isLoading: true });
|
|
||||||
setTimeout(async () => {
|
|
||||||
await this.importMnemonic(this.state.label.trim());
|
|
||||||
this.setState({ isLoading: false });
|
|
||||||
}, 1);
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
<BlueButtonLink
|
|
||||||
title={loc.wallets.import.scan_qr}
|
|
||||||
onPress={() => {
|
|
||||||
this.props.navigation.navigate('ScanQrWif');
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</View>
|
|
||||||
</KeyboardAvoidingView>
|
</KeyboardAvoidingView>
|
||||||
</TouchableWithoutFeedback>
|
</TouchableWithoutFeedback>
|
||||||
|
|
||||||
|
<BlueSpacing20 />
|
||||||
|
<View
|
||||||
|
style={{
|
||||||
|
alignItems: 'center',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<BlueButton
|
||||||
|
disabled={!this.state.label}
|
||||||
|
title={loc.wallets.import.do_import}
|
||||||
|
buttonStyle={{
|
||||||
|
width: width / 1.5,
|
||||||
|
}}
|
||||||
|
onPress={async () => {
|
||||||
|
if (!this.state.label) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.setState({ isLoading: true });
|
||||||
|
setTimeout(async () => {
|
||||||
|
await this.importMnemonic(this.state.label.trim());
|
||||||
|
this.setState({ isLoading: false });
|
||||||
|
}, 1);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<BlueButtonLink
|
||||||
|
title={loc.wallets.import.scan_qr}
|
||||||
|
onPress={() => {
|
||||||
|
this.props.navigation.navigate('ScanQrWif');
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</View>
|
||||||
</SafeBlueArea>
|
</SafeBlueArea>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,20 +1,6 @@
|
||||||
import React, { Component } from 'react';
|
import React, { Component } from 'react';
|
||||||
import { View, TouchableOpacity, Text, FlatList, RefreshControl, ScrollView } from 'react-native';
|
import { View, TouchableOpacity, Text, FlatList, RefreshControl, ScrollView } from 'react-native';
|
||||||
import {
|
import { BlueLoading, SafeBlueArea, WalletsCarousel, BlueList, BlueHeaderDefaultMain, BlueListTransactionItem } from '../../BlueComponents';
|
||||||
BlueTransactionOnchainIcon,
|
|
||||||
BlueLoading,
|
|
||||||
SafeBlueArea,
|
|
||||||
WalletsCarousel,
|
|
||||||
BlueTransactionIncommingIcon,
|
|
||||||
BlueTransactionOutgoingIcon,
|
|
||||||
BlueTransactionPendingIcon,
|
|
||||||
BlueTransactionOffchainIcon,
|
|
||||||
BlueTransactionExpiredIcon,
|
|
||||||
BlueList,
|
|
||||||
BlueListItem,
|
|
||||||
BlueHeaderDefaultMain,
|
|
||||||
BlueTransactionOffchainIncomingIcon,
|
|
||||||
} from '../../BlueComponents';
|
|
||||||
import { Icon } from 'react-native-elements';
|
import { Icon } from 'react-native-elements';
|
||||||
import { NavigationEvents } from 'react-navigation';
|
import { NavigationEvents } from 'react-navigation';
|
||||||
import ReactNativeHapticFeedback from 'react-native-haptic-feedback';
|
import ReactNativeHapticFeedback from 'react-native-haptic-feedback';
|
||||||
|
@ -232,60 +218,9 @@ export default class WalletsList extends Component {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
rowTitle = item => {
|
_renderItem = data => <BlueListTransactionItem item={data.item} itemPriceUnit={data.item.walletPreferredBalanceUnit} />;
|
||||||
if (item.type === 'user_invoice' || item.type === 'payment_request') {
|
|
||||||
if (isNaN(item.value)) {
|
|
||||||
item.value = '0';
|
|
||||||
}
|
|
||||||
const currentDate = new Date();
|
|
||||||
const now = (currentDate.getTime() / 1000) | 0;
|
|
||||||
const invoiceExpiration = item.timestamp + item.expire_time;
|
|
||||||
|
|
||||||
if (invoiceExpiration > now) {
|
|
||||||
return loc.formatBalanceWithoutSuffix(item.value && item.value, item.walletPreferredBalanceUnit, true).toString();
|
|
||||||
} else if (invoiceExpiration < now) {
|
|
||||||
if (item.ispaid) {
|
|
||||||
return loc.formatBalanceWithoutSuffix(item.value && item.value, item.walletPreferredBalanceUnit, true).toString();
|
|
||||||
} else {
|
|
||||||
return loc.lnd.expired;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return loc.formatBalanceWithoutSuffix(item.value && item.value, item.walletPreferredBalanceUnit, true).toString();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
rowTitleStyle = item => {
|
|
||||||
let color = '#37c0a1';
|
|
||||||
|
|
||||||
if (item.type === 'user_invoice' || item.type === 'payment_request') {
|
|
||||||
const currentDate = new Date();
|
|
||||||
const now = (currentDate.getTime() / 1000) | 0;
|
|
||||||
const invoiceExpiration = item.timestamp + item.expire_time;
|
|
||||||
|
|
||||||
if (invoiceExpiration > now) {
|
|
||||||
color = '#37c0a1';
|
|
||||||
} else if (invoiceExpiration < now) {
|
|
||||||
if (item.ispaid) {
|
|
||||||
color = '#37c0a1';
|
|
||||||
} else {
|
|
||||||
color = '#FF0000';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (item.value / 100000000 < 0) {
|
|
||||||
color = BlueApp.settings.foregroundColor;
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
fontWeight: '600',
|
|
||||||
fontSize: 16,
|
|
||||||
color: color,
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { navigate } = this.props.navigation;
|
|
||||||
|
|
||||||
if (this.state.isLoading) {
|
if (this.state.isLoading) {
|
||||||
return <BlueLoading />;
|
return <BlueLoading />;
|
||||||
}
|
}
|
||||||
|
@ -338,117 +273,7 @@ export default class WalletsList extends Component {
|
||||||
data={this.state.dataSource}
|
data={this.state.dataSource}
|
||||||
extraData={this.state.dataSource}
|
extraData={this.state.dataSource}
|
||||||
keyExtractor={this._keyExtractor}
|
keyExtractor={this._keyExtractor}
|
||||||
renderItem={rowData => {
|
renderItem={this._renderItem}
|
||||||
return (
|
|
||||||
<BlueListItem
|
|
||||||
avatar={(() => {
|
|
||||||
// is it lightning refill tx?
|
|
||||||
if (rowData.item.category === 'receive' && rowData.item.confirmations < 3) {
|
|
||||||
return (
|
|
||||||
<View style={{ width: 25 }}>
|
|
||||||
<BlueTransactionPendingIcon />
|
|
||||||
</View>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (rowData.item.type && rowData.item.type === 'bitcoind_tx') {
|
|
||||||
return (
|
|
||||||
<View style={{ width: 25 }}>
|
|
||||||
<BlueTransactionOnchainIcon />
|
|
||||||
</View>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
if (rowData.item.type === 'paid_invoice') {
|
|
||||||
// is it lightning offchain payment?
|
|
||||||
return (
|
|
||||||
<View style={{ width: 25 }}>
|
|
||||||
<BlueTransactionOffchainIcon />
|
|
||||||
</View>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (rowData.item.type === 'user_invoice' || rowData.item.type === 'payment_request') {
|
|
||||||
if (!rowData.item.ispaid) {
|
|
||||||
const currentDate = new Date();
|
|
||||||
const now = (currentDate.getTime() / 1000) | 0;
|
|
||||||
const invoiceExpiration = rowData.item.timestamp + rowData.item.expire_time;
|
|
||||||
if (invoiceExpiration < now) {
|
|
||||||
return (
|
|
||||||
<View style={{ width: 25 }}>
|
|
||||||
<BlueTransactionExpiredIcon />
|
|
||||||
</View>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return (
|
|
||||||
<View style={{ width: 25 }}>
|
|
||||||
<BlueTransactionOffchainIncomingIcon />
|
|
||||||
</View>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!rowData.item.confirmations) {
|
|
||||||
return (
|
|
||||||
<View style={{ width: 25 }}>
|
|
||||||
<BlueTransactionPendingIcon />
|
|
||||||
</View>
|
|
||||||
);
|
|
||||||
} else if (rowData.item.value < 0) {
|
|
||||||
return (
|
|
||||||
<View style={{ width: 25 }}>
|
|
||||||
<BlueTransactionOutgoingIcon />
|
|
||||||
</View>
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
return (
|
|
||||||
<View style={{ width: 25 }}>
|
|
||||||
<BlueTransactionIncommingIcon />
|
|
||||||
</View>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
})()}
|
|
||||||
title={loc.transactionTimeToReadable(rowData.item.received)}
|
|
||||||
subtitle={
|
|
||||||
(rowData.item.confirmations < 7 ? loc.transactions.list.conf + ': ' + rowData.item.confirmations + ' ' : '') +
|
|
||||||
this.txMemo(rowData.item.hash) +
|
|
||||||
(rowData.item.memo || '')
|
|
||||||
}
|
|
||||||
onPress={() => {
|
|
||||||
if (rowData.item.hash) {
|
|
||||||
navigate('TransactionDetails', {
|
|
||||||
hash: rowData.item.hash,
|
|
||||||
});
|
|
||||||
} else if (
|
|
||||||
rowData.item.type === 'user_invoice' ||
|
|
||||||
rowData.item.type === 'payment_request' ||
|
|
||||||
rowData.item.type === 'paid_invoice'
|
|
||||||
) {
|
|
||||||
const lightningWallet = this.state.wallets.filter(wallet => {
|
|
||||||
if (typeof wallet === 'object') {
|
|
||||||
if (wallet.hasOwnProperty('secret')) {
|
|
||||||
return wallet.getSecret() === rowData.item.fromWallet;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
this.props.navigation.navigate('LNDViewInvoice', {
|
|
||||||
invoice: rowData.item,
|
|
||||||
fromWallet: lightningWallet[0],
|
|
||||||
isModal: false,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
badge={{
|
|
||||||
value: 3,
|
|
||||||
textStyle: { color: 'orange' },
|
|
||||||
containerStyle: { marginTop: 0 },
|
|
||||||
}}
|
|
||||||
hideChevron
|
|
||||||
rightTitle={this.rowTitle(rowData.item)}
|
|
||||||
rightTitleStyle={this.rowTitleStyle(rowData.item)}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
}}
|
|
||||||
/>
|
/>
|
||||||
</BlueList>
|
</BlueList>
|
||||||
</ScrollView>
|
</ScrollView>
|
||||||
|
|
|
@ -28,6 +28,7 @@ export default class ScanQrWif extends React.Component {
|
||||||
};
|
};
|
||||||
|
|
||||||
async onBarCodeScanned(ret) {
|
async onBarCodeScanned(ret) {
|
||||||
|
this.setState({ isLoading: true });
|
||||||
if (+new Date() - this.lastTimeIveBeenHere < 6000) {
|
if (+new Date() - this.lastTimeIveBeenHere < 6000) {
|
||||||
this.lastTimeIveBeenHere = +new Date();
|
this.lastTimeIveBeenHere = +new Date();
|
||||||
return;
|
return;
|
||||||
|
@ -57,16 +58,17 @@ export default class ScanQrWif extends React.Component {
|
||||||
ret.data = wif.encode(0x80, decryptedKey.privateKey, decryptedKey.compressed);
|
ret.data = wif.encode(0x80, decryptedKey.privateKey, decryptedKey.compressed);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.log(e.message);
|
console.log(e.message);
|
||||||
this.setState({ message: false });
|
this.setState({ message: false, isLoading: false });
|
||||||
return alert(loc.wallets.scanQrWif.bad_password);
|
return alert(loc.wallets.scanQrWif.bad_password);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.setState({ message: false });
|
this.setState({ message: false, isLoading: false });
|
||||||
}
|
}
|
||||||
|
|
||||||
for (let w of BlueApp.wallets) {
|
for (let w of BlueApp.wallets) {
|
||||||
if (w.getSecret() === ret.data) {
|
if (w.getSecret() === ret.data) {
|
||||||
// lookig for duplicates
|
// lookig for duplicates
|
||||||
|
this.setState({ isLoading: false });
|
||||||
return alert(loc.wallets.scanQrWif.wallet_already_exists); // duplicate, not adding
|
return alert(loc.wallets.scanQrWif.wallet_already_exists); // duplicate, not adding
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -78,10 +80,10 @@ export default class ScanQrWif extends React.Component {
|
||||||
for (let w of BlueApp.wallets) {
|
for (let w of BlueApp.wallets) {
|
||||||
if (w.getSecret() === hd.getSecret()) {
|
if (w.getSecret() === hd.getSecret()) {
|
||||||
// lookig for duplicates
|
// lookig for duplicates
|
||||||
|
this.setState({ isLoading: false });
|
||||||
return alert(loc.wallets.scanQrWif.wallet_already_exists); // duplicate, not adding
|
return alert(loc.wallets.scanQrWif.wallet_already_exists); // duplicate, not adding
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
this.setState({ isLoading: true });
|
|
||||||
await hd.fetchTransactions();
|
await hd.fetchTransactions();
|
||||||
if (hd.getTransactions().length !== 0) {
|
if (hd.getTransactions().length !== 0) {
|
||||||
await hd.fetchBalance();
|
await hd.fetchBalance();
|
||||||
|
@ -91,6 +93,7 @@ export default class ScanQrWif extends React.Component {
|
||||||
alert(loc.wallets.import.success);
|
alert(loc.wallets.import.success);
|
||||||
this.props.navigation.popToTop();
|
this.props.navigation.popToTop();
|
||||||
setTimeout(() => EV(EV.enum.WALLETS_COUNT_CHANGED), 500);
|
setTimeout(() => EV(EV.enum.WALLETS_COUNT_CHANGED), 500);
|
||||||
|
this.setState({ isLoading: false });
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -103,6 +106,7 @@ export default class ScanQrWif extends React.Component {
|
||||||
for (let w of BlueApp.wallets) {
|
for (let w of BlueApp.wallets) {
|
||||||
if (w.getSecret() === hd.getSecret()) {
|
if (w.getSecret() === hd.getSecret()) {
|
||||||
// lookig for duplicates
|
// lookig for duplicates
|
||||||
|
this.setState({ isLoading: false });
|
||||||
return alert(loc.wallets.scanQrWif.wallet_already_exists); // duplicate, not adding
|
return alert(loc.wallets.scanQrWif.wallet_already_exists); // duplicate, not adding
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -115,6 +119,7 @@ export default class ScanQrWif extends React.Component {
|
||||||
alert(loc.wallets.import.success);
|
alert(loc.wallets.import.success);
|
||||||
this.props.navigation.popToTop();
|
this.props.navigation.popToTop();
|
||||||
setTimeout(() => EV(EV.enum.WALLETS_COUNT_CHANGED), 500);
|
setTimeout(() => EV(EV.enum.WALLETS_COUNT_CHANGED), 500);
|
||||||
|
this.setState({ isLoading: false });
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// nope
|
// nope
|
||||||
|
@ -130,6 +135,7 @@ export default class ScanQrWif extends React.Component {
|
||||||
await lnd.fetchBalance();
|
await lnd.fetchBalance();
|
||||||
} catch (Err) {
|
} catch (Err) {
|
||||||
console.log(Err);
|
console.log(Err);
|
||||||
|
this.setState({ isLoading: false });
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -138,6 +144,7 @@ export default class ScanQrWif extends React.Component {
|
||||||
this.props.navigation.popToTop();
|
this.props.navigation.popToTop();
|
||||||
alert(loc.wallets.import.success);
|
alert(loc.wallets.import.success);
|
||||||
setTimeout(() => EV(EV.enum.WALLETS_COUNT_CHANGED), 500);
|
setTimeout(() => EV(EV.enum.WALLETS_COUNT_CHANGED), 500);
|
||||||
|
this.setState({ isLoading: false });
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// nope
|
// nope
|
||||||
|
@ -165,6 +172,7 @@ export default class ScanQrWif extends React.Component {
|
||||||
await watchOnly.fetchTransactions();
|
await watchOnly.fetchTransactions();
|
||||||
await BlueApp.saveToDisk();
|
await BlueApp.saveToDisk();
|
||||||
setTimeout(() => EV(EV.enum.WALLETS_COUNT_CHANGED), 500);
|
setTimeout(() => EV(EV.enum.WALLETS_COUNT_CHANGED), 500);
|
||||||
|
this.setState({ isLoading: false });
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// nope
|
// nope
|
||||||
|
@ -176,6 +184,7 @@ export default class ScanQrWif extends React.Component {
|
||||||
|
|
||||||
if (newWallet.getAddress() === false || newLegacyWallet.getAddress() === false) {
|
if (newWallet.getAddress() === false || newLegacyWallet.getAddress() === false) {
|
||||||
alert(loc.wallets.scanQrWif.bad_wif);
|
alert(loc.wallets.scanQrWif.bad_wif);
|
||||||
|
this.setState({ isLoading: false });
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -196,7 +205,7 @@ export default class ScanQrWif extends React.Component {
|
||||||
alert(loc.wallets.scanQrWif.imported_wif + ret.data + loc.wallets.scanQrWif.with_address + newWallet.getAddress());
|
alert(loc.wallets.scanQrWif.imported_wif + ret.data + loc.wallets.scanQrWif.with_address + newWallet.getAddress());
|
||||||
}
|
}
|
||||||
await BlueApp.saveToDisk();
|
await BlueApp.saveToDisk();
|
||||||
this.props.navigation.popToTop();
|
this.props.navigation.dismiss();
|
||||||
setTimeout(() => EV(EV.enum.WALLETS_COUNT_CHANGED), 500);
|
setTimeout(() => EV(EV.enum.WALLETS_COUNT_CHANGED), 500);
|
||||||
} // end
|
} // end
|
||||||
|
|
||||||
|
@ -210,7 +219,7 @@ export default class ScanQrWif extends React.Component {
|
||||||
render() {
|
render() {
|
||||||
if (this.state.isLoading) {
|
if (this.state.isLoading) {
|
||||||
return (
|
return (
|
||||||
<View style={{ flex: 1, paddingTop: 20 }}>
|
<View style={{ flex: 1, paddingTop: 20, justifyContent: 'center', alignContent: 'center' }}>
|
||||||
<ActivityIndicator />
|
<ActivityIndicator />
|
||||||
</View>
|
</View>
|
||||||
);
|
);
|
||||||
|
@ -275,6 +284,7 @@ ScanQrWif.propTypes = {
|
||||||
navigation: PropTypes.shape({
|
navigation: PropTypes.shape({
|
||||||
goBack: PropTypes.func,
|
goBack: PropTypes.func,
|
||||||
popToTop: PropTypes.func,
|
popToTop: PropTypes.func,
|
||||||
|
dismiss: PropTypes.func,
|
||||||
navigate: PropTypes.func,
|
navigate: PropTypes.func,
|
||||||
}),
|
}),
|
||||||
};
|
};
|
||||||
|
|
|
@ -3,20 +3,7 @@ import { Text, View, Image, FlatList, RefreshControl, TouchableOpacity, StatusBa
|
||||||
import LinearGradient from 'react-native-linear-gradient';
|
import LinearGradient from 'react-native-linear-gradient';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import { NavigationEvents } from 'react-navigation';
|
import { NavigationEvents } from 'react-navigation';
|
||||||
import {
|
import { BlueText, ManageFundsBigButton, BlueSendButtonIcon, BlueReceiveButtonIcon, BlueTransactionListItem } from '../../BlueComponents';
|
||||||
BlueText,
|
|
||||||
BlueTransactionOnchainIcon,
|
|
||||||
ManageFundsBigButton,
|
|
||||||
BlueTransactionExpiredIcon,
|
|
||||||
BlueTransactionIncommingIcon,
|
|
||||||
BlueTransactionOutgoingIcon,
|
|
||||||
BlueTransactionPendingIcon,
|
|
||||||
BlueTransactionOffchainIcon,
|
|
||||||
BlueSendButtonIcon,
|
|
||||||
BlueReceiveButtonIcon,
|
|
||||||
BlueListItem,
|
|
||||||
BlueTransactionOffchainIncomingIcon,
|
|
||||||
} from '../../BlueComponents';
|
|
||||||
import { Icon } from 'react-native-elements';
|
import { Icon } from 'react-native-elements';
|
||||||
import { BitcoinUnit } from '../../models/bitcoinUnits';
|
import { BitcoinUnit } from '../../models/bitcoinUnits';
|
||||||
import { LightningCustodianWallet } from '../../class';
|
import { LightningCustodianWallet } from '../../class';
|
||||||
|
@ -272,13 +259,6 @@ export default class WalletTransactions extends Component {
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
txMemo(hash) {
|
|
||||||
if (BlueApp.tx_metadata[hash] && BlueApp.tx_metadata[hash]['memo']) {
|
|
||||||
return BlueApp.tx_metadata[hash]['memo'];
|
|
||||||
}
|
|
||||||
return '';
|
|
||||||
}
|
|
||||||
|
|
||||||
_keyExtractor = (_item, index) => index.toString();
|
_keyExtractor = (_item, index) => index.toString();
|
||||||
|
|
||||||
renderListHeaderComponent = () => {
|
renderListHeaderComponent = () => {
|
||||||
|
@ -308,55 +288,8 @@ export default class WalletTransactions extends Component {
|
||||||
this.onWillBlur();
|
this.onWillBlur();
|
||||||
}
|
}
|
||||||
|
|
||||||
rowTitle = item => {
|
renderItem = item => {
|
||||||
if (item.type === 'user_invoice' || item.type === 'payment_request') {
|
return <BlueTransactionListItem item={item.item} itemPriceUnit={this.state.wallet.getPreferredBalanceUnit()} />;
|
||||||
if (isNaN(item.value)) {
|
|
||||||
item.value = 0;
|
|
||||||
}
|
|
||||||
const currentDate = new Date();
|
|
||||||
const now = (currentDate.getTime() / 1000) | 0;
|
|
||||||
const invoiceExpiration = item.timestamp + item.expire_time;
|
|
||||||
|
|
||||||
if (invoiceExpiration > now) {
|
|
||||||
return loc.formatBalanceWithoutSuffix(item.value && item.value, this.state.wallet.getPreferredBalanceUnit(), true).toString();
|
|
||||||
} else if (invoiceExpiration < now) {
|
|
||||||
if (item.ispaid) {
|
|
||||||
return loc.formatBalanceWithoutSuffix(item.value && item.value, this.state.wallet.getPreferredBalanceUnit(), true).toString();
|
|
||||||
} else {
|
|
||||||
return loc.lnd.expired;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return loc.formatBalanceWithoutSuffix(item.value && item.value, this.state.wallet.getPreferredBalanceUnit(), true).toString();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
rowTitleStyle = item => {
|
|
||||||
let color = '#37c0a1';
|
|
||||||
|
|
||||||
if (item.type === 'user_invoice' || item.type === 'payment_request') {
|
|
||||||
const currentDate = new Date();
|
|
||||||
const now = (currentDate.getTime() / 1000) | 0;
|
|
||||||
const invoiceExpiration = item.timestamp + item.expire_time;
|
|
||||||
|
|
||||||
if (invoiceExpiration > now) {
|
|
||||||
color = '#37c0a1';
|
|
||||||
} else if (invoiceExpiration < now) {
|
|
||||||
if (item.ispaid) {
|
|
||||||
color = '#37c0a1';
|
|
||||||
} else {
|
|
||||||
color = '#FF0000';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (item.value / 100000000 < 0) {
|
|
||||||
color = BlueApp.settings.foregroundColor;
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
fontWeight: '600',
|
|
||||||
fontSize: 16,
|
|
||||||
color: color,
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
|
@ -416,8 +349,9 @@ export default class WalletTransactions extends Component {
|
||||||
<FlatList
|
<FlatList
|
||||||
ListHeaderComponent={this.renderListHeaderComponent}
|
ListHeaderComponent={this.renderListHeaderComponent}
|
||||||
ListEmptyComponent={
|
ListEmptyComponent={
|
||||||
<View style={{ top: 50, minHeight: 200 }}>
|
<View style={{ top: 50, minHeight: 200, paddingHorizontal: 16 }}>
|
||||||
<Text
|
<Text
|
||||||
|
numberOfLines={0}
|
||||||
style={{
|
style={{
|
||||||
fontSize: 18,
|
fontSize: 18,
|
||||||
color: '#9aa0aa',
|
color: '#9aa0aa',
|
||||||
|
@ -425,7 +359,7 @@ export default class WalletTransactions extends Component {
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{(this.isLightning() &&
|
{(this.isLightning() &&
|
||||||
'Lightning wallet should be used for your daily\ntransactions. Fees are unfairly cheap and\nspeed is blazing fast.') ||
|
'Lightning wallet should be used for your daily transactions. Fees are unfairly cheap and speed is blazing fast.') ||
|
||||||
loc.wallets.list.empty_txs1}
|
loc.wallets.list.empty_txs1}
|
||||||
</Text>
|
</Text>
|
||||||
<Text
|
<Text
|
||||||
|
@ -435,7 +369,7 @@ export default class WalletTransactions extends Component {
|
||||||
textAlign: 'center',
|
textAlign: 'center',
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{(this.isLightning() && '\nTo start using it tap on "manage funds"\nand topup your balance') ||
|
{(this.isLightning() && '\nTo start using it tap on "manage funds" and topup your balance') ||
|
||||||
loc.wallets.list.empty_txs2}
|
loc.wallets.list.empty_txs2}
|
||||||
</Text>
|
</Text>
|
||||||
|
|
||||||
|
@ -465,110 +399,8 @@ export default class WalletTransactions extends Component {
|
||||||
refreshControl={<RefreshControl onRefresh={() => this.refreshTransactions()} refreshing={this.state.isTransactionsLoading} />}
|
refreshControl={<RefreshControl onRefresh={() => this.refreshTransactions()} refreshing={this.state.isTransactionsLoading} />}
|
||||||
data={this.state.dataSource}
|
data={this.state.dataSource}
|
||||||
keyExtractor={this._keyExtractor}
|
keyExtractor={this._keyExtractor}
|
||||||
renderItem={rowData => {
|
initialNumToRender={10}
|
||||||
return (
|
renderItem={this.renderItem}
|
||||||
<BlueListItem
|
|
||||||
avatar={(() => {
|
|
||||||
// is it lightning refill tx?
|
|
||||||
if (rowData.item.category === 'receive' && rowData.item.confirmations < 3) {
|
|
||||||
return (
|
|
||||||
<View style={{ width: 25 }}>
|
|
||||||
<BlueTransactionPendingIcon />
|
|
||||||
</View>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (rowData.item.type && rowData.item.type === 'bitcoind_tx') {
|
|
||||||
return (
|
|
||||||
<View style={{ width: 25 }}>
|
|
||||||
<BlueTransactionOnchainIcon />
|
|
||||||
</View>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
if (rowData.item.type === 'paid_invoice') {
|
|
||||||
// is it lightning offchain payment?
|
|
||||||
return (
|
|
||||||
<View style={{ width: 25 }}>
|
|
||||||
<BlueTransactionOffchainIcon />
|
|
||||||
</View>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (rowData.item.type === 'user_invoice' || rowData.item.type === 'payment_request') {
|
|
||||||
if (!rowData.item.ispaid) {
|
|
||||||
const currentDate = new Date();
|
|
||||||
const now = (currentDate.getTime() / 1000) | 0;
|
|
||||||
const invoiceExpiration = rowData.item.timestamp + rowData.item.expire_time;
|
|
||||||
if (invoiceExpiration < now) {
|
|
||||||
return (
|
|
||||||
<View style={{ width: 25 }}>
|
|
||||||
<BlueTransactionExpiredIcon />
|
|
||||||
</View>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return (
|
|
||||||
<View style={{ width: 25 }}>
|
|
||||||
<BlueTransactionOffchainIncomingIcon />
|
|
||||||
</View>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!rowData.item.confirmations) {
|
|
||||||
return (
|
|
||||||
<View style={{ width: 25 }}>
|
|
||||||
<BlueTransactionPendingIcon />
|
|
||||||
</View>
|
|
||||||
);
|
|
||||||
} else if (rowData.item.value < 0) {
|
|
||||||
return (
|
|
||||||
<View style={{ width: 25 }}>
|
|
||||||
<BlueTransactionOutgoingIcon />
|
|
||||||
</View>
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
return (
|
|
||||||
<View style={{ width: 25 }}>
|
|
||||||
<BlueTransactionIncommingIcon />
|
|
||||||
</View>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
})()}
|
|
||||||
title={loc.transactionTimeToReadable(rowData.item.received)}
|
|
||||||
subtitle={
|
|
||||||
(rowData.item.confirmations < 7 ? loc.transactions.list.conf + ': ' + rowData.item.confirmations + ' ' : '') +
|
|
||||||
this.txMemo(rowData.item.hash) +
|
|
||||||
(rowData.item.memo || '')
|
|
||||||
}
|
|
||||||
onPress={() => {
|
|
||||||
if (rowData.item.hash) {
|
|
||||||
navigate('TransactionDetails', {
|
|
||||||
hash: rowData.item.hash,
|
|
||||||
});
|
|
||||||
} else if (
|
|
||||||
rowData.item.type === 'user_invoice' ||
|
|
||||||
rowData.item.type === 'payment_request' ||
|
|
||||||
rowData.item.type === 'paid_invoice'
|
|
||||||
) {
|
|
||||||
this.props.navigation.navigate('LNDViewInvoice', {
|
|
||||||
invoice: rowData.item,
|
|
||||||
fromWallet: this.state.wallet,
|
|
||||||
isModal: false,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
badge={{
|
|
||||||
value: 3,
|
|
||||||
textStyle: { color: 'orange' },
|
|
||||||
containerStyle: { marginTop: 0 },
|
|
||||||
}}
|
|
||||||
hideChevron
|
|
||||||
rightTitle={this.rowTitle(rowData.item)}
|
|
||||||
rightTitleStyle={this.rowTitleStyle(rowData.item)}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
}}
|
|
||||||
/>
|
/>
|
||||||
</View>
|
</View>
|
||||||
<View
|
<View
|
||||||
|
|
Loading…
Add table
Reference in a new issue