|
|
@ -33,6 +33,7 @@ import WalletGradient from './class/walletGradient'; |
|
|
|
import ToolTip from 'react-native-tooltip'; |
|
|
|
import { BlurView } from '@react-native-community/blur'; |
|
|
|
import showPopupMenu from 'react-native-popup-menu-android'; |
|
|
|
import NetworkTransactionFees, { NetworkTransactionFeeType } from './models/networkTransactionFees'; |
|
|
|
const LocalQRCode = require('@remobile/react-native-qrcode-local-image'); |
|
|
|
let loc = require('./loc/'); |
|
|
|
/** @type {AppStorage} */ |
|
|
@ -850,7 +851,7 @@ export class BlueDismissKeyboardInputAccessory extends Component { |
|
|
|
alignItems: 'center', |
|
|
|
}} |
|
|
|
> |
|
|
|
<BlueButtonLink title="Done" onPress={Keyboard.dismiss} /> |
|
|
|
<BlueButtonLink title="Done" onPress={() => Keyboard.dismiss()} /> |
|
|
|
</View> |
|
|
|
</InputAccessoryView> |
|
|
|
); |
|
|
@ -1956,6 +1957,118 @@ export class BlueAddressInput extends Component { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
export class BlueReplaceFeeSuggestions extends Component { |
|
|
|
static propTypes = { |
|
|
|
onFeeSelected: PropTypes.func.isRequired, |
|
|
|
transactionMinimum: PropTypes.number.isRequired, |
|
|
|
}; |
|
|
|
|
|
|
|
static defaultProps = { |
|
|
|
onFeeSelected: undefined, |
|
|
|
transactionMinimum: 1, |
|
|
|
}; |
|
|
|
|
|
|
|
state = { networkFees: undefined, selectedFeeType: NetworkTransactionFeeType.FAST, customFeeValue: 0 }; |
|
|
|
|
|
|
|
async componentDidMount() { |
|
|
|
const networkFees = await NetworkTransactionFees.recommendedFees(); |
|
|
|
this.setState({ networkFees }); |
|
|
|
} |
|
|
|
|
|
|
|
onFeeSelected = selectedFeeType => { |
|
|
|
if (selectedFeeType !== NetworkTransactionFeeType.CUSTOM) { |
|
|
|
Keyboard.dismiss(); |
|
|
|
} |
|
|
|
if (selectedFeeType === NetworkTransactionFeeType.FAST) { |
|
|
|
this.props.onFeeSelected(this.state.networkFees.fastestFee); |
|
|
|
this.setState({ selectedFeeType }, () => this.props.onFeeSelected(this.state.networkFees.fastestFee)); |
|
|
|
} else if (selectedFeeType === NetworkTransactionFeeType.MEDIUM) { |
|
|
|
this.setState({ selectedFeeType }, () => this.props.onFeeSelected(this.state.networkFees.halfHourFee)); |
|
|
|
} else if (selectedFeeType === NetworkTransactionFeeType.SLOW) { |
|
|
|
this.setState({ selectedFeeType }, () => this.props.onFeeSelected(this.state.networkFees.hourFee)); |
|
|
|
} else if (selectedFeeType === NetworkTransactionFeeType.CUSTOM) { |
|
|
|
this.props.onFeeSelected(this.state.customFeeValue); |
|
|
|
} |
|
|
|
}; |
|
|
|
|
|
|
|
onCustomFeeTextChange = customFee => { |
|
|
|
this.setState({ customFeeValue: Number(customFee), selectedFeeType: NetworkTransactionFeeType.CUSTOM }, () => { |
|
|
|
this.onFeeSelected(NetworkTransactionFeeType.CUSTOM); |
|
|
|
}); |
|
|
|
}; |
|
|
|
|
|
|
|
render() { |
|
|
|
return ( |
|
|
|
<View> |
|
|
|
{this.state.networkFees && ( |
|
|
|
<> |
|
|
|
<BlueText>Suggestions</BlueText> |
|
|
|
<TouchableOpacity onPress={() => this.onFeeSelected(NetworkTransactionFeeType.FAST)}> |
|
|
|
<BlueListItem |
|
|
|
title={'Fast'} |
|
|
|
rightTitle={`${this.state.networkFees.fastestFee} sat/b`} |
|
|
|
{...(this.state.selectedFeeType === NetworkTransactionFeeType.FAST |
|
|
|
? { rightIcon: <Icon name="check" type="font-awesome" color="#0c2550" /> } |
|
|
|
: { hideChevron: true })} |
|
|
|
/> |
|
|
|
</TouchableOpacity> |
|
|
|
<TouchableOpacity onPress={() => this.onFeeSelected(NetworkTransactionFeeType.MEDIUM)}> |
|
|
|
<BlueListItem |
|
|
|
title={'Medium'} |
|
|
|
rightTitle={`${this.state.networkFees.halfHourFee} sat/b`} |
|
|
|
{...(this.state.selectedFeeType === NetworkTransactionFeeType.MEDIUM |
|
|
|
? { rightIcon: <Icon name="check" type="font-awesome" color="#0c2550" /> } |
|
|
|
: { hideChevron: true })} |
|
|
|
/> |
|
|
|
</TouchableOpacity> |
|
|
|
<TouchableOpacity onPress={() => this.onFeeSelected(NetworkTransactionFeeType.SLOW)}> |
|
|
|
<BlueListItem |
|
|
|
title={'Slow'} |
|
|
|
rightTitle={`${this.state.networkFees.hourFee} sat/b`} |
|
|
|
{...(this.state.selectedFeeType === NetworkTransactionFeeType.SLOW |
|
|
|
? { rightIcon: <Icon name="check" type="font-awesome" color="#0c2550" /> } |
|
|
|
: { hideChevron: true })} |
|
|
|
/> |
|
|
|
</TouchableOpacity> |
|
|
|
</> |
|
|
|
)} |
|
|
|
<BlueSpacing20 /> |
|
|
|
<BlueText>Custom</BlueText> |
|
|
|
<View |
|
|
|
style={{ |
|
|
|
flexDirection: 'row', |
|
|
|
borderColor: '#d2d2d2', |
|
|
|
borderBottomColor: '#d2d2d2', |
|
|
|
borderWidth: 1.0, |
|
|
|
borderBottomWidth: 0.5, |
|
|
|
backgroundColor: '#f5f5f5', |
|
|
|
minHeight: 44, |
|
|
|
height: 44, |
|
|
|
alignItems: 'center', |
|
|
|
marginVertical: 8, |
|
|
|
borderRadius: 4, |
|
|
|
}} |
|
|
|
> |
|
|
|
<TextInput |
|
|
|
onChangeText={this.onCustomFeeTextChange} |
|
|
|
keyboardType={'numeric'} |
|
|
|
value={this.state.customFeeValue} |
|
|
|
style={{ flex: 1, minHeight: 33, marginHorizontal: 8 }} |
|
|
|
onFocus={() => this.onCustomFeeTextChange(this.state.customFeeValue)} |
|
|
|
defaultValue={`${this.props.transactionMinimum}`} |
|
|
|
placeholder="Custom sat/b" |
|
|
|
inputAccessoryViewID={BlueDismissKeyboardInputAccessory.InputAccessoryViewID} |
|
|
|
/> |
|
|
|
<BlueDismissKeyboardInputAccessory /> |
|
|
|
</View> |
|
|
|
<BlueText> |
|
|
|
The total fee rate (satoshi per byte) you want to pay should be higher than {this.props.transactionMinimum} sat/byte |
|
|
|
</BlueText> |
|
|
|
</View> |
|
|
|
); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
export class BlueBitcoinAmount extends Component { |
|
|
|
static propTypes = { |
|
|
|
isLoading: PropTypes.bool, |
|
|
|