This commit is contained in:
marcosrdz 2020-11-24 22:01:51 -05:00
parent 761b4dc531
commit 5e4b2eb37b
5 changed files with 124 additions and 121 deletions

View File

@ -714,13 +714,8 @@ export const BlueTextHooks = props => {
/>
);
};
export class BlueTextCentered extends Component {
render() {
return <Text {...this.props} style={{ color: BlueCurrentTheme.colors.foregroundColor, textAlign: 'center' }} />;
}
}
export const BlueTextCenteredHooks = props => {
export const BlueTextCentered = props => {
const { colors } = useTheme();
return <Text {...props} style={{ color: colors.foregroundColor, textAlign: 'center' }} />;
};

View File

@ -134,14 +134,6 @@ const WalletsRoot = () => (
<WalletsStack.Screen name="ElectrumSettings" component={ElectrumSettings} options={ElectrumSettings.navigationOptions} />
<WalletsStack.Screen name="SettingsPrivacy" component={SettingsPrivacy} options={SettingsPrivacy.navigationOptions} />
<WalletsStack.Screen name="LNDViewInvoice" component={LNDViewInvoice} options={LNDViewInvoice.navigationOptions} />
<WalletsStack.Screen
name="Success"
component={Success}
options={{
headerShown: false,
gestureEnabled: false,
}}
/>
<WalletsStack.Screen
name="LNDViewAdditionalInvoiceInformation"
component={LNDViewAdditionalInvoiceInformation}
@ -151,14 +143,6 @@ const WalletsRoot = () => (
<WalletsStack.Screen name="Broadcast" component={Broadcast} options={Broadcast.navigationOptions} />
<WalletsStack.Screen name="LnurlPay" component={LnurlPay} options={LnurlPay.navigationOptions} />
<WalletsStack.Screen name="LnurlPaySuccess" component={LnurlPaySuccess} options={LnurlPaySuccess.navigationOptions} />
<WalletsStack.Screen
name="Success"
component={Success}
options={{
headerShown: false,
gestureEnabled: false,
}}
/>
</WalletsStack.Navigator>
);

View File

@ -10,7 +10,7 @@ import {
BlueCopyTextToClipboard,
BlueNavigationStyle,
BlueSpacing20,
BlueBigCheckmark,
BlueTextCentered,
} from '../../BlueComponents';
import ReactNativeHapticFeedback from 'react-native-haptic-feedback';
import { Icon } from 'react-native-elements';
@ -19,17 +19,18 @@ import loc from '../../loc';
import { BlueStorageContext } from '../../blue_modules/storage-context';
import { useNavigation, useRoute, useTheme } from '@react-navigation/native';
import { BitcoinUnit } from '../../models/bitcoinUnits';
//import Success from '../send/success';
import { SuccessView } from '../send/success';
const LNDViewInvoice = () => {
const { invoice, fromWallet, isModal } = useRoute().params;
const { setSelectedWallet, fetchAndSaveWalletTransactions } = useContext(BlueStorageContext);
const { width, height } = useWindowDimensions();
const { colors } = useTheme();
const { goBack, popToRoot, navigate, setParams, setOptions } = useNavigation();
const { goBack, navigate, setParams, setOptions } = useNavigation();
const [isLoading, setIsLoading] = useState(typeof invoice === 'string');
const [isFetchingInvoices, setIsFetchingInvoices] = useState(true);
const [showPreimageQr, setShowPreimageQr] = useState(false);
const [invoiceStatusChanged, setInvoiceStatusChanged] = useState(false);
const qrCodeHeight = height > width ? width - 20 : width / 2;
const fetchInvoiceInterval = useRef();
const stylesHook = StyleSheet.create({
@ -91,47 +92,52 @@ const LNDViewInvoice = () => {
useEffect(() => {
setSelectedWallet(fromWallet.getID());
console.log('LNDViewInvoice - useEffect');
fetchInvoiceInterval.current = setInterval(async () => {
if (isFetchingInvoices) {
try {
const userInvoices = await 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(filteredInvoice =>
typeof invoice === 'object'
? filteredInvoice.payment_request === invoice.payment_request
: filteredInvoice.payment_request === invoice,
)[0];
if (typeof updatedUserInvoice !== 'undefined') {
setParams({ invoice: updatedUserInvoice });
setIsLoading(false);
if (updatedUserInvoice.ispaid) {
// we fetched the invoice, and it is paid :-)
setIsFetchingInvoices(false);
ReactNativeHapticFeedback.trigger('notificationSuccess', { ignoreAndroidSystemSettings: false });
clearInterval(fetchInvoiceInterval.current);
fetchInvoiceInterval.current = undefined;
fetchAndSaveWalletTransactions(fromWallet.getID());
} 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 :-(
fetchAndSaveWalletTransactions(fromWallet.getID());
if (!invoice.ispaid) {
fetchInvoiceInterval.current = setInterval(async () => {
if (isFetchingInvoices) {
try {
const userInvoices = await 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(filteredInvoice =>
typeof invoice === 'object'
? filteredInvoice.payment_request === invoice.payment_request
: filteredInvoice.payment_request === invoice,
)[0];
if (typeof updatedUserInvoice !== 'undefined') {
setInvoiceStatusChanged(true);
setParams({ invoice: updatedUserInvoice });
setIsLoading(false);
if (updatedUserInvoice.ispaid) {
// we fetched the invoice, and it is paid :-)
setIsFetchingInvoices(false);
ReactNativeHapticFeedback.trigger('notificationError', { ignoreAndroidSystemSettings: false });
clearInterval(fetchInvoiceInterval.current);
fetchInvoiceInterval.current = undefined;
fetchAndSaveWalletTransactions(fromWallet.getID());
} 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 :-(
fetchAndSaveWalletTransactions(fromWallet.getID());
setIsFetchingInvoices(false);
ReactNativeHapticFeedback.trigger('notificationError', { ignoreAndroidSystemSettings: false });
clearInterval(fetchInvoiceInterval.current);
fetchInvoiceInterval.current = undefined;
}
}
}
} catch (error) {
console.log(error);
}
} catch (error) {
console.log(error);
}
}
}, 3000);
}, 3000);
} else {
setIsFetchingInvoices(false);
clearInterval(fetchInvoiceInterval.current);
fetchInvoiceInterval.current = undefined;
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
@ -153,13 +159,9 @@ const LNDViewInvoice = () => {
};
useEffect(() => {
if (invoice.ispaid) {
navigate('Success', {
amount: invoice.amt,
amountUnit: BitcoinUnit.SATS,
invoiceDescription: invoice.description,
onDonePressed: popToRoot,
});
if (invoice.ispaid && invoiceStatusChanged) {
ReactNativeHapticFeedback.trigger('notificationSuccess', { ignoreAndroidSystemSettings: false });
setInvoiceStatusChanged(true);
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [invoice]);
@ -180,7 +182,7 @@ const LNDViewInvoice = () => {
if (showPreimageQr) {
return (
<View>
<View style={styles.root}>
<BlueText>{loc.lndViewInvoice.preimage}:</BlueText>
<BlueSpacing20 />
<View style={styles.qrCodeContainer}>
@ -203,39 +205,33 @@ const LNDViewInvoice = () => {
}
if (invoice.ispaid || invoice.type === 'paid_invoice') {
let amount = 0;
if (invoice.type === 'paid_invoice' && invoice.value) {
amount = invoice.value;
} else if (invoice.type === 'user_invoice' && invoice.amt) {
amount = invoice.amt;
}
let description = invoice.description;
if (invoice.memo && invoice.memo.length > 0) {
description = invoice.memo;
}
return (
<>
<View style={[styles.valueRoot, stylesHook.valueRoot]}>
{invoice.type === 'paid_invoice' && invoice.value && (
<View style={styles.valueAmount}>
<Text style={[styles.valueText, stylesHook.valueText]}>{invoice.value}</Text>
<Text style={[styles.valueSats, stylesHook.valueSats]}>{loc.lndViewInvoice.sats}</Text>
</View>
)}
{invoice.type === 'user_invoice' && invoice.amt && (
<View style={styles.valueAmount}>
<Text style={[styles.valueText, stylesHook.valueText]}>{invoice.amt}</Text>
<Text style={[styles.valueSats, stylesHook.valueSats]}>{loc.lndViewInvoice.sats}</Text>
</View>
)}
{!invoice.ispaid && invoice.memo && invoice.memo.length > 0 && <Text style={styles.memo}>{invoice.memo}</Text>}
</View>
<View style={styles.paid}>
<BlueBigCheckmark style={styles.paidMark} />
<BlueText>{loc.lndViewInvoice.has_been_paid}</BlueText>
</View>
<View style={[styles.root, stylesHook.root]}>
<SuccessView
amount={amount}
amountUnit={BitcoinUnit.SATS}
invoiceDescription={description}
shouldAnimate={invoiceStatusChanged}
/>
<View style={styles.detailsRoot}>
{invoice.payment_preimage && typeof invoice.payment_preimage === 'string' ? (
<TouchableOpacity style={styles.detailsTouch} onPress={setShowPreimageQrTrue}>
<Text style={[styles.detailsText, stylesHook.detailsText]}>{loc.send.create_details}</Text>
<Icon name="angle-right" size={18} type="font-awesome" color={colors.alternativeTextColor} />
</TouchableOpacity>
) : (
<View />
)}
) : undefined}
</View>
</>
</View>
);
}
if (invoiceExpiration < now && !invoice.ispaid) {
@ -244,7 +240,7 @@ const LNDViewInvoice = () => {
<View style={[styles.expired, stylesHook.expired]}>
<Icon name="times" size={50} type="font-awesome" color={colors.successCheck} />
</View>
<BlueText>{loc.lndViewInvoice.wasnt_paid_and_expired}</BlueText>
<BlueTextCentered>{loc.lndViewInvoice.wasnt_paid_and_expired}</BlueTextCentered>
</View>
);
}
@ -290,7 +286,7 @@ const LNDViewInvoice = () => {
return (
<SafeBlueArea styles={[styles.root, stylesHook.root]}>
<StatusBar barStyle="default" />
<ScrollView style={stylesHook.root} centerContent contentContainerStyle={stylesHook.root}>
<ScrollView style={[styles.root, stylesHook.root]} centerContent contentContainerStyle={stylesHook.root}>
{render()}
</ScrollView>
</SafeBlueArea>
@ -302,11 +298,6 @@ const styles = StyleSheet.create({
flex: 1,
},
qrCodeContainer: { borderWidth: 6, borderRadius: 8, borderColor: '#FFFFFF' },
valueRoot: {
flex: 2,
flexDirection: 'column',
justifyContent: 'center',
},
valueAmount: {
flexDirection: 'row',
justifyContent: 'center',
@ -360,7 +351,6 @@ const styles = StyleSheet.create({
borderRadius: 60,
alignSelf: 'center',
justifyContent: 'center',
marginTop: -100,
marginBottom: 30,
},
activeRoot: {

View File

@ -6,17 +6,16 @@ import { Text } from 'react-native-elements';
import { BlueButton, BlueCard } from '../../BlueComponents';
import { BitcoinUnit } from '../../models/bitcoinUnits';
import loc from '../../loc';
import PropTypes from 'prop-types';
import { useNavigation, useRoute, useTheme } from '@react-navigation/native';
const Success = () => {
const pop = () => {
dangerouslyGetParent().pop();
};
const { colors } = useTheme();
const { dangerouslyGetParent } = useNavigation();
const { amount = 0, fee = 0, amountUnit = BitcoinUnit.BTC, invoiceDescription = '', onDonePressed = pop } = useRoute().params;
const animationRef = useRef();
const stylesHook = StyleSheet.create({
root: {
backgroundColor: colors.elevated,
@ -34,13 +33,47 @@ const Success = () => {
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
return (
<SafeAreaView style={[styles.root, stylesHook.root]}>
<SuccessView
amount={amount}
amountUnit={amountUnit}
fee={fee}
invoiceDescription={invoiceDescription}
onDonePressed={onDonePressed}
/>
<View style={styles.buttonContainer}>
<BlueButton onPress={onDonePressed} title={loc.send.success_done} />
</View>
</SafeAreaView>
);
};
export default Success;
export const SuccessView = ({ amount, amountUnit, fee, invoiceDescription, shouldAnimate = true }) => {
const animationRef = useRef();
const { colors } = useTheme();
const stylesHook = StyleSheet.create({
amountValue: {
color: colors.alternativeTextColor2,
},
amountUnit: {
color: colors.alternativeTextColor2,
},
});
useEffect(() => {
animationRef.current.reset();
animationRef.current.resume();
if (shouldAnimate) {
animationRef.current.reset();
animationRef.current.resume();
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [colors]);
return (
<SafeAreaView style={[styles.root, stylesHook.root]}>
<View style={styles.root}>
<BlueCard style={styles.amount}>
<View style={styles.view}>
{amount > 0 && (
@ -55,19 +88,18 @@ const Success = () => {
{loc.send.create_fee}: {fee} {BitcoinUnit.BTC}
</Text>
)}
{fee <= 0 && (
<Text numberOfLines={0} style={styles.feeText}>
{invoiceDescription}
</Text>
)}
<Text numberOfLines={0} style={styles.feeText}>
{invoiceDescription}
</Text>
</BlueCard>
<View style={styles.ready}>
<LottieView
style={styles.lottie}
source={require('../../img/bluenice.json')}
autoPlay
autoPlay={shouldAnimate}
ref={animationRef}
loop={false}
progress={shouldAnimate ? 0 : 1}
colorFilters={[
{
keypath: 'spark',
@ -84,20 +116,22 @@ const Success = () => {
]}
/>
</View>
<View style={styles.buttonContainer}>
<BlueButton onPress={onDonePressed} title={loc.send.success_done} />
</View>
</SafeAreaView>
</View>
);
};
export default Success;
SuccessView.propTypes = {
amount: PropTypes.number,
amountUnit: PropTypes.string,
fee: PropTypes.number,
invoiceDescription: PropTypes.string,
shouldAnimate: PropTypes.bool,
};
const styles = StyleSheet.create({
root: {
flex: 1,
paddingTop: 19,
justifyContent: 'space-between',
},
buttonContainer: {
padding: 58,

View File

@ -22,7 +22,7 @@ import {
BlueSpacing10,
BlueSpacing20,
BlueSpacing40,
BlueTextCenteredHooks,
BlueTextCentered,
} from '../../BlueComponents';
import { Icon } from 'react-native-elements';
import { HDSegwitBech32Wallet, MultisigCosigner, MultisigHDWallet } from '../../class';
@ -534,7 +534,7 @@ const WalletsAddMultisigStep2 = () => {
<BottomModal isVisible={isProvideMnemonicsModalVisible} onClose={hideProvideMnemonicsModal}>
<KeyboardAvoidingView behavior={Platform.OS === 'ios' ? 'position' : null}>
<View style={[styles.modalContent, stylesHook.modalContent]}>
<BlueTextCenteredHooks>{loc.multisig.type_your_mnemonics}</BlueTextCenteredHooks>
<BlueTextCentered>{loc.multisig.type_your_mnemonics}</BlueTextCentered>
<BlueSpacing20 />
<BlueFormMultiInput value={importText} onChangeText={setImportText} />
<BlueSpacing40 />