mirror of
https://github.com/BlueWallet/BlueWallet.git
synced 2025-03-04 04:13:49 +01:00
FIX: TX details screen would hang when loading large data
This commit is contained in:
parent
538a1327b6
commit
b395e1b782
2 changed files with 80 additions and 74 deletions
|
@ -8,6 +8,7 @@ import loc from '../loc';
|
||||||
import * as BlueElectrum from './BlueElectrum';
|
import * as BlueElectrum from './BlueElectrum';
|
||||||
import triggerHapticFeedback, { HapticFeedbackTypes } from './hapticFeedback';
|
import triggerHapticFeedback, { HapticFeedbackTypes } from './hapticFeedback';
|
||||||
import A from '../blue_modules/analytics';
|
import A from '../blue_modules/analytics';
|
||||||
|
import { InteractionManager } from 'react-native';
|
||||||
|
|
||||||
const BlueApp = BlueAppClass.getInstance();
|
const BlueApp = BlueAppClass.getInstance();
|
||||||
|
|
||||||
|
@ -71,30 +72,27 @@ export const BlueStorageProvider = ({ children }: { children: React.ReactNode })
|
||||||
const [reloadTransactionsMenuActionFunction, setReloadTransactionsMenuActionFunction] = useState<() => void>(() => {});
|
const [reloadTransactionsMenuActionFunction, setReloadTransactionsMenuActionFunction] = useState<() => void>(() => {});
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
BlueElectrum.isDisabled().then(setIsElectrumDisabled);
|
setWallets(BlueApp.getWallets());
|
||||||
}, []);
|
|
||||||
|
|
||||||
useEffect(() => {
|
BlueElectrum.isDisabled().then(setIsElectrumDisabled);
|
||||||
if (walletsInitialized) {
|
if (walletsInitialized) {
|
||||||
BlueElectrum.connectMain();
|
BlueElectrum.connectMain();
|
||||||
}
|
}
|
||||||
}, [walletsInitialized]);
|
}, [walletsInitialized]);
|
||||||
|
|
||||||
const saveToDisk = async (force: boolean = false) => {
|
const saveToDisk = async (force: boolean = false) => {
|
||||||
if (BlueApp.getWallets().length === 0 && !force) {
|
InteractionManager.runAfterInteractions(async () => {
|
||||||
console.log('not saving empty wallets array');
|
if (BlueApp.getWallets().length === 0 && !force) {
|
||||||
return;
|
console.log('not saving empty wallets array');
|
||||||
}
|
return;
|
||||||
BlueApp.tx_metadata = txMetadata;
|
}
|
||||||
await BlueApp.saveToDisk();
|
BlueApp.tx_metadata = txMetadata;
|
||||||
setWallets([...BlueApp.getWallets()]);
|
await BlueApp.saveToDisk();
|
||||||
txMetadata = BlueApp.tx_metadata;
|
setWallets([...BlueApp.getWallets()]);
|
||||||
|
txMetadata = BlueApp.tx_metadata;
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
setWallets(BlueApp.getWallets());
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
const resetWallets = () => {
|
const resetWallets = () => {
|
||||||
setWallets(BlueApp.getWallets());
|
setWallets(BlueApp.getWallets());
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import React, { useContext, useEffect, useLayoutEffect, useState } from 'react';
|
import React, { useCallback, useContext, useEffect, useMemo, useState } from 'react';
|
||||||
import { View, ScrollView, TouchableOpacity, Text, TextInput, Linking, StyleSheet, Keyboard } from 'react-native';
|
import { View, ScrollView, TouchableOpacity, Text, TextInput, Linking, StyleSheet, Keyboard, InteractionManager } from 'react-native';
|
||||||
import { useNavigation, useRoute } from '@react-navigation/native';
|
import { useFocusEffect, useNavigation, useRoute } from '@react-navigation/native';
|
||||||
import Clipboard from '@react-native-clipboard/clipboard';
|
import Clipboard from '@react-native-clipboard/clipboard';
|
||||||
import dayjs from 'dayjs';
|
import dayjs from 'dayjs';
|
||||||
import { BlueCard, BlueLoading, BlueSpacing20, BlueText } from '../../BlueComponents';
|
import { BlueCard, BlueLoading, BlueSpacing20, BlueText } from '../../BlueComponents';
|
||||||
|
@ -59,68 +59,76 @@ const TransactionsDetails = () => {
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
useLayoutEffect(() => {
|
const handleOnSaveButtonTapped = useCallback(() => {
|
||||||
setOptions({
|
|
||||||
// eslint-disable-next-line react/no-unstable-nested-components
|
|
||||||
headerRight: () => (
|
|
||||||
<TouchableOpacity
|
|
||||||
accessibilityRole="button"
|
|
||||||
disabled={isLoading}
|
|
||||||
style={[styles.save, stylesHooks.save]}
|
|
||||||
onPress={handleOnSaveButtonTapped}
|
|
||||||
>
|
|
||||||
<Text style={[styles.saveText, stylesHooks.saveText]}>{loc.wallets.details_save}</Text>
|
|
||||||
</TouchableOpacity>
|
|
||||||
),
|
|
||||||
});
|
|
||||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
||||||
}, [colors, isLoading, memo]);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
let foundTx = {};
|
|
||||||
let newFrom = [];
|
|
||||||
let newTo = [];
|
|
||||||
for (const transaction of getTransactions(null, Infinity, true)) {
|
|
||||||
if (transaction.hash === hash) {
|
|
||||||
foundTx = transaction;
|
|
||||||
for (const input of foundTx.inputs) {
|
|
||||||
newFrom = newFrom.concat(input.addresses);
|
|
||||||
}
|
|
||||||
for (const output of foundTx.outputs) {
|
|
||||||
if (output.addresses) newTo = newTo.concat(output.addresses);
|
|
||||||
if (output.scriptPubKey && output.scriptPubKey.addresses) newTo = newTo.concat(output.scriptPubKey.addresses);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (const w of wallets) {
|
|
||||||
for (const t of w.getTransactions()) {
|
|
||||||
if (t.hash === hash) {
|
|
||||||
console.log('tx', hash, 'belongs to', w.getLabel());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (txMetadata[foundTx.hash]) {
|
|
||||||
if (txMetadata[foundTx.hash].memo) {
|
|
||||||
setMemo(txMetadata[foundTx.hash].memo);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
setTX(foundTx);
|
|
||||||
setFrom(newFrom);
|
|
||||||
setTo(newTo);
|
|
||||||
setIsLoading(false);
|
|
||||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
||||||
}, [hash, wallets]);
|
|
||||||
|
|
||||||
const handleOnSaveButtonTapped = () => {
|
|
||||||
Keyboard.dismiss();
|
Keyboard.dismiss();
|
||||||
txMetadata[tx.hash] = { memo };
|
txMetadata[tx.hash] = { memo };
|
||||||
saveToDisk().then(_success => {
|
saveToDisk().then(_success => {
|
||||||
triggerHapticFeedback(HapticFeedbackTypes.Success);
|
triggerHapticFeedback(HapticFeedbackTypes.Success);
|
||||||
presentAlert({ message: loc.transactions.transaction_note_saved });
|
presentAlert({ message: loc.transactions.transaction_note_saved });
|
||||||
});
|
});
|
||||||
};
|
}, [tx, memo, saveToDisk, txMetadata]);
|
||||||
|
|
||||||
|
const HeaderRightButton = useMemo(() => {
|
||||||
|
return (
|
||||||
|
<TouchableOpacity
|
||||||
|
accessibilityRole="button"
|
||||||
|
disabled={isLoading}
|
||||||
|
style={[styles.save, stylesHooks.save]}
|
||||||
|
onPress={handleOnSaveButtonTapped}
|
||||||
|
>
|
||||||
|
<Text style={[styles.saveText, stylesHooks.saveText]}>{loc.wallets.details_save}</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
);
|
||||||
|
}, [isLoading, stylesHooks.save, stylesHooks.saveText, handleOnSaveButtonTapped]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
// This effect only handles changes in `colors`
|
||||||
|
setOptions({ headerRight: () => HeaderRightButton });
|
||||||
|
}, [colors, HeaderRightButton, setOptions]);
|
||||||
|
|
||||||
|
useFocusEffect(
|
||||||
|
useCallback(() => {
|
||||||
|
const task = InteractionManager.runAfterInteractions(() => {
|
||||||
|
let foundTx = {};
|
||||||
|
let newFrom = [];
|
||||||
|
let newTo = [];
|
||||||
|
for (const transaction of getTransactions(null, Infinity, true)) {
|
||||||
|
if (transaction.hash === hash) {
|
||||||
|
foundTx = transaction;
|
||||||
|
for (const input of foundTx.inputs) {
|
||||||
|
newFrom = newFrom.concat(input.addresses);
|
||||||
|
}
|
||||||
|
for (const output of foundTx.outputs) {
|
||||||
|
if (output.addresses) newTo = newTo.concat(output.addresses);
|
||||||
|
if (output.scriptPubKey && output.scriptPubKey.addresses) newTo = newTo.concat(output.scriptPubKey.addresses);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const w of wallets) {
|
||||||
|
for (const t of w.getTransactions()) {
|
||||||
|
if (t.hash === hash) {
|
||||||
|
console.log('tx', hash, 'belongs to', w.getLabel());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (txMetadata[foundTx.hash]) {
|
||||||
|
if (txMetadata[foundTx.hash].memo) {
|
||||||
|
setMemo(txMetadata[foundTx.hash].memo);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
setTX(foundTx);
|
||||||
|
setFrom(newFrom);
|
||||||
|
setTo(newTo);
|
||||||
|
setIsLoading(false);
|
||||||
|
});
|
||||||
|
return () => {
|
||||||
|
task.cancel();
|
||||||
|
};
|
||||||
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
|
}, [hash, wallets]),
|
||||||
|
);
|
||||||
|
|
||||||
const handleOnOpenTransactionOnBlockExplorerTapped = () => {
|
const handleOnOpenTransactionOnBlockExplorerTapped = () => {
|
||||||
const url = `https://mempool.space/tx/${tx.hash}`;
|
const url = `https://mempool.space/tx/${tx.hash}`;
|
||||||
|
|
Loading…
Add table
Reference in a new issue