import React, { Component } from 'react';
import { View, Dimensions, Share, ScrollView, BackHandler } from 'react-native';
import {
BlueLoading,
BlueText,
SafeBlueArea,
BlueButton,
BlueCopyTextToClipboard,
BlueNavigationStyle,
BlueSpacing20,
} from '../../BlueComponents';
import PropTypes from 'prop-types';
import ReactNativeHapticFeedback from 'react-native-haptic-feedback';
import { Icon } from 'react-native-elements';
/** @type {AppStorage} */
let BlueApp = require('../../BlueApp');
const loc = require('../../loc');
const EV = require('../../events');
const QRFast = require('react-native-qrcode');
const { width, height } = Dimensions.get('window');
export default class LNDViewInvoice extends Component {
static navigationOptions = ({ navigation }) =>
navigation.getParam('isModal') === true
? {
...BlueNavigationStyle(navigation, true, () => navigation.dismiss()),
title: 'Lightning Invoice',
headerLeft: null,
}
: { ...BlueNavigationStyle(), title: 'Lightning Invoice' };
constructor(props) {
super(props);
const invoice = props.navigation.getParam('invoice');
const fromWallet = props.navigation.getParam('fromWallet');
this.state = {
invoice,
fromWallet,
isLoading: typeof invoice === 'string',
addressText: typeof invoice === 'object' && invoice.hasOwnProperty('payment_request') ? invoice.payment_request : invoice,
isFetchingInvoices: true,
qrCodeHeight: height > width ? width - 20 : width / 2,
};
this.fetchInvoiceInterval = undefined;
BackHandler.addEventListener('hardwareBackPress', this.handleBackButton);
}
async componentDidMount() {
this.fetchInvoiceInterval = setInterval(async () => {
if (this.state.isFetchingInvoices) {
try {
const userInvoices = await this.state.fromWallet.getUserInvoices(20);
// fetching only last 20 invoices
// for invoice that was created just now - that should be enough (it is basically the last one, so limit=1 would be sufficient)
// but that might not work as intended IF user creates 21 invoices, and then tries to check the status of invoice #0, it just wont be updated
const updatedUserInvoice = userInvoices.filter(invoice =>
typeof this.state.invoice === 'object'
? invoice.payment_request === this.state.invoice.payment_request
: invoice.payment_request === this.state.invoice,
)[0];
if (typeof updatedUserInvoice !== 'undefined') {
this.setState({ invoice: updatedUserInvoice, isLoading: false, addressText: updatedUserInvoice.payment_request });
if (updatedUserInvoice.ispaid) {
// we fetched the invoice, and it is paid :-)
this.setState({ isFetchingInvoices: false });
ReactNativeHapticFeedback.trigger('notificationSuccess', false);
clearInterval(this.fetchInvoiceInterval);
this.fetchInvoiceInterval = undefined;
EV(EV.enum.TRANSACTIONS_COUNT_CHANGED);
} else {
const currentDate = new Date();
const now = (currentDate.getTime() / 1000) | 0;
const invoiceExpiration = updatedUserInvoice.timestamp + updatedUserInvoice.expire_time;
if (invoiceExpiration < now && !updatedUserInvoice.ispaid) {
// invoice expired :-(
this.setState({ isFetchingInvoices: false });
ReactNativeHapticFeedback.trigger('notificationError', false);
clearInterval(this.fetchInvoiceInterval);
this.fetchInvoiceInterval = undefined;
EV(EV.enum.TRANSACTIONS_COUNT_CHANGED);
}
}
}
} catch (error) {
console.log(error);
}
}
}, 3000);
}
componentWillUnmount() {
clearInterval(this.fetchInvoiceInterval);
this.fetchInvoiceInterval = undefined;
BackHandler.removeEventListener('hardwareBackPress', this.handleBackButton);
}
handleBackButton() {
this.props.navigation.dismiss();
return true;
}
onLayout = () => {
const { height } = Dimensions.get('window');
this.setState({ qrCodeHeight: height > width ? width - 20 : width / 2 });
};
render() {
if (this.state.isLoading) {
return ;
}
const { invoice } = this.state;
if (typeof invoice === 'object') {
const currentDate = new Date();
const now = (currentDate.getTime() / 1000) | 0;
const invoiceExpiration = invoice.timestamp + invoice.expire_time;
if (invoice.ispaid || invoice.type === 'paid_invoice') {
return (
This invoice has been paid for
);
}
if (invoiceExpiration < now && !invoice.ispaid) {
return (
This invoice was not paid for and has expired
);
} else if (invoiceExpiration > now && invoice.ispaid) {
if (invoice.ispaid) {
return (
'This invoice has been paid for.'
);
}
}
}
// Invoice has not expired, nor has it been paid for.
return (
{invoice && invoice.amt && Please pay {invoice.amt} sats}
{invoice && invoice.description && For: {invoice.description}}
{
Share.share({
message: 'lightning:' + invoice.payment_request,
});
}}
title={loc.receive.details.share}
/>
this.props.navigation.navigate('LNDViewAdditionalInvoiceInformation', { fromWallet: this.state.fromWallet })}
title="Additional Information"
/>
);
}
}
LNDViewInvoice.propTypes = {
navigation: PropTypes.shape({
goBack: PropTypes.function,
navigate: PropTypes.function,
getParam: PropTypes.function,
dismiss: PropTypes.function,
}),
};