diff --git a/BlueComponents.js b/BlueComponents.js
index 847c7bd12..315743f3a 100644
--- a/BlueComponents.js
+++ b/BlueComponents.js
@@ -1,6 +1,6 @@
/* eslint react/prop-types: "off", react-native/no-inline-styles: "off" */
/* global alert */
-import React, { Component, useState } from 'react';
+import React, { Component, useState, useMemo, useCallback } from 'react';
import Ionicons from 'react-native-vector-icons/Ionicons';
import PropTypes from 'prop-types';
import { Icon, Input, Text, Header, ListItem, Avatar } from 'react-native-elements';
@@ -1670,15 +1670,27 @@ export const NewWalletPanel = props => {
export const BlueTransactionListItem = React.memo(({ item, itemPriceUnit = BitcoinUnit.BTC, timeElapsed }) => {
const [subtitleNumberOfLines, setSubtitleNumberOfLines] = useState(1);
const { colors } = useTheme();
+ const containerStyle = useMemo(
+ () => ({
+ backgroundColor: 'transparent',
+ borderBottomColor: colors.lightBorder,
+ paddingTop: 16,
+ paddingBottom: 16,
+ }),
+ [colors.lightBorder],
+ );
- const txMemo = () => {
- if (BlueApp.tx_metadata[item.hash] && BlueApp.tx_metadata[item.hash].memo) {
- return BlueApp.tx_metadata[item.hash].memo;
- }
- return '';
- };
+ const title = useMemo(() => transactionTimeToReadable(item.received), [item.received]);
+ const txMemo = BlueApp.tx_metadata[item.hash]?.memo ?? '';
+ const subtitle = useMemo(() => {
+ let sub = item.confirmations < 7 ? loc.formatString(loc.transactions.list_conf, { number: item.confirmations }) : '';
+ if (sub !== '') sub += ' ';
+ sub += txMemo;
+ if (item.memo) sub += item.memo;
+ return sub || null;
+ }, [txMemo, item.confirmations, item.memo]);
- const rowTitle = () => {
+ const rowTitle = useMemo(() => {
if (item.type === 'user_invoice' || item.type === 'payment_request') {
if (isNaN(item.value)) {
item.value = '0';
@@ -1699,9 +1711,9 @@ export const BlueTransactionListItem = React.memo(({ item, itemPriceUnit = Bitco
} else {
return formatBalanceWithoutSuffix(item.value && item.value, itemPriceUnit, true).toString();
}
- };
+ }, [item, itemPriceUnit]);
- const rowTitleStyle = () => {
+ const rowTitleStyle = useMemo(() => {
let color = colors.successColor;
if (item.type === 'user_invoice' || item.type === 'payment_request') {
@@ -1723,15 +1735,15 @@ export const BlueTransactionListItem = React.memo(({ item, itemPriceUnit = Bitco
}
return {
- fontWeight: '600',
+ color,
fontSize: 14,
- color: color,
+ fontWeight: '600',
textAlign: 'right',
width: 96,
};
- };
+ }, [item, colors.foregroundColor, colors.successColor]);
- const avatar = () => {
+ const avatar = useMemo(() => {
// is it lightning refill tx?
if (item.category === 'receive' && item.confirmations < 3) {
return (
@@ -1797,13 +1809,9 @@ export const BlueTransactionListItem = React.memo(({ item, itemPriceUnit = Bitco
);
}
- };
+ }, [item]);
- const subtitle = () => {
- return (item.confirmations < 7 ? loc.transactions.list_conf + ': ' + item.confirmations + ' ' : '') + txMemo() + (item.memo || '');
- };
-
- const onPress = async () => {
+ const onPress = useCallback(async () => {
if (item.hash) {
NavigationService.navigate('TransactionStatus', { hash: item.hash });
} else if (item.type === 'user_invoice' || item.type === 'payment_request' || item.type === 'paid_invoice') {
@@ -1826,7 +1834,7 @@ export const BlueTransactionListItem = React.memo(({ item, itemPriceUnit = Bitco
NavigationService.navigate('ScanLndInvoiceRoot', {
screen: 'LnurlPaySuccess',
params: {
- paymentHash: paymentHash,
+ paymentHash,
justPaid: false,
fromWalletID: lightningWallet[0].getID(),
},
@@ -1841,34 +1849,31 @@ export const BlueTransactionListItem = React.memo(({ item, itemPriceUnit = Bitco
});
}
}
- };
+ }, [item]);
- const onLongPress = () => {
+ const onLongPress = useCallback(() => {
if (subtitleNumberOfLines === 1) {
setSubtitleNumberOfLines(0);
}
- };
+ }, [subtitleNumberOfLines]);
+
+ const subtitleProps = useMemo(() => ({ numberOfLines: subtitleNumberOfLines }), [subtitleNumberOfLines]);
return (
);
diff --git a/loc/en.json b/loc/en.json
index 5be7915cf..ebe0880c9 100644
--- a/loc/en.json
+++ b/loc/en.json
@@ -293,7 +293,7 @@
"details_to": "Output",
"details_transaction_details": "Transaction details",
"enable_hw": "This wallet is not being used in conjunction with a hardwarde wallet. Would you like to enable hardware wallet use?",
- "list_conf": "conf",
+ "list_conf": "conf: {number}",
"list_title": "transactions",
"rbf_explain": "We will replace this transaction with the one with a higher fee, so it should be mined faster. This is called RBF - Replace By Fee.",
"rbf_title": "Bump fee (RBF)",
diff --git a/screen/send/details.js b/screen/send/details.js
index 940326a22..989dfc98d 100644
--- a/screen/send/details.js
+++ b/screen/send/details.js
@@ -816,6 +816,39 @@ export default class SendDetails extends Component {
}
};
+ handleAddRecipient = () => {
+ const { addresses } = this.state;
+ addresses.push(new BitcoinTransaction());
+ this.setState(
+ {
+ addresses,
+ isAdvancedTransactionOptionsVisible: false,
+ },
+ () => {
+ this.scrollView.scrollToEnd();
+ if (this.state.addresses.length > 1) this.scrollView.flashScrollIndicators();
+ // after adding recipient it automatically scrolls to the last one
+ this.setState({ recipientsScrollIndex: this.state.addresses.length - 1 });
+ },
+ );
+ };
+
+ handleRemoveRecipient = () => {
+ const { addresses } = this.state;
+ addresses.splice(this.state.recipientsScrollIndex, 1);
+ this.setState(
+ {
+ addresses,
+ isAdvancedTransactionOptionsVisible: false,
+ },
+ () => {
+ if (this.state.addresses.length > 1) this.scrollView.flashScrollIndicators();
+ // after deletion it automatically scrolls to the last one
+ this.setState({ recipientsScrollIndex: this.state.addresses.length - 1 });
+ },
+ );
+ };
+
renderAdvancedTransactionOptionsModal = () => {
const isSendMaxUsed = this.state.addresses.some(element => element.amount === BitcoinUnit.MAX);
return (
@@ -865,43 +898,14 @@ export default class SendDetails extends Component {
title={loc.send.details_add_rec_add}
hideChevron
component={TouchableOpacity}
- onPress={() => {
- const addresses = this.state.addresses;
- addresses.push(new BitcoinTransaction());
- this.setState(
- {
- addresses,
- isAdvancedTransactionOptionsVisible: false,
- },
- () => {
- this.scrollView.scrollToEnd();
- if (this.state.addresses.length > 1) this.scrollView.flashScrollIndicators();
- // after adding recipient it automatically scrolls to the last one
- this.setState({ recipientsScrollIndex: this.state.addresses.length - 1 });
- },
- );
- }}
+ onPress={this.handleAddRecipient}
/>
{
- const addresses = this.state.addresses;
- addresses.splice(this.state.recipientsScrollIndex, 1);
- this.setState(
- {
- addresses,
- isAdvancedTransactionOptionsVisible: false,
- },
- () => {
- if (this.state.addresses.length > 1) this.scrollView.flashScrollIndicators();
- // after deletion it automatically scrolls to the last one
- this.setState({ recipientsScrollIndex: this.state.addresses.length - 1 });
- },
- );
- }}
+ onPress={this.handleRemoveRecipient}
/>
>
)}
diff --git a/screen/wallets/transactions.js b/screen/wallets/transactions.js
index 08e39879a..3fd02c491 100644
--- a/screen/wallets/transactions.js
+++ b/screen/wallets/transactions.js
@@ -1,5 +1,5 @@
/* global alert */
-import React, { useEffect, useState } from 'react';
+import React, { useEffect, useState, useCallback } from 'react';
import { Chain } from '../../models/bitcoinUnits';
import {
Text,
@@ -37,7 +37,7 @@ import Handoff from 'react-native-handoff';
import ActionSheet from '../ActionSheet';
import loc from '../../loc';
import { getSystemName } from 'react-native-device-info';
-import { useRoute, useNavigation, useTheme } from '@react-navigation/native';
+import { useRoute, useNavigation, useTheme, useFocusEffect } from '@react-navigation/native';
import BuyBitcoin from './buyBitcoin';
const BlueApp = require('../../BlueApp');
const EV = require('../../blue_modules/events');
@@ -230,7 +230,6 @@ const WalletTransactions = () => {
return b.sort_ts - a.sort_ts;
});
return txs.slice(0, limit);
- // eslint-disable-next-line react-hooks/exhaustive-deps
};
useEffect(() => {
@@ -257,6 +256,13 @@ const WalletTransactions = () => {
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [wallet]);
+ // if description of transaction has been changed we want to show new one
+ useFocusEffect(
+ useCallback(() => {
+ setTimeElapsed(prev => prev + 1);
+ }, []),
+ );
+
/**
* Forcefully fetches TXs and balance for wallet
*/