mirror of
https://github.com/BlueWallet/BlueWallet.git
synced 2025-01-18 21:35:21 +01:00
WIP
This commit is contained in:
parent
761b4dc531
commit
5e4b2eb37b
@ -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' }} />;
|
||||
};
|
||||
|
@ -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>
|
||||
);
|
||||
|
||||
|
@ -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: {
|
||||
|
@ -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,
|
||||
|
@ -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 />
|
||||
|
Loading…
Reference in New Issue
Block a user