mirror of
https://github.com/BlueWallet/BlueWallet.git
synced 2025-02-23 07:15:35 +01:00
Merge pull request #6549 from BlueWallet/storageuse
REF: useStorage useCallback and useMemo
This commit is contained in:
commit
1a6c777c36
1 changed files with 222 additions and 182 deletions
|
@ -1,4 +1,4 @@
|
|||
import React, { createContext, useContext, useEffect, useState } from 'react';
|
||||
import React, { createContext, useCallback, useContext, useEffect, useMemo, useRef, useState } from 'react';
|
||||
import { startAndDecrypt } from './start-and-decrypt';
|
||||
import Notifications from '../blue_modules/notifications';
|
||||
import { LegacyWallet, TTXMetadata, WatchOnlyWallet, BlueApp as BlueAppClass, TCounterpartyMetadata } from '../class';
|
||||
|
@ -62,149 +62,8 @@ export enum WalletTransactionsStatus {
|
|||
// @ts-ignore defaut value does not match the type
|
||||
export const BlueStorageContext = createContext<BlueStorageContextType>(undefined);
|
||||
export const BlueStorageProvider = ({ children }: { children: React.ReactNode }) => {
|
||||
const [wallets, setWallets] = useState<TWallet[]>([]);
|
||||
const [selectedWalletID, setSelectedWalletID] = useState<undefined | string>();
|
||||
const [walletTransactionUpdateStatus, setWalletTransactionUpdateStatus] = useState<WalletTransactionsStatus | string>(
|
||||
WalletTransactionsStatus.NONE,
|
||||
);
|
||||
const [walletsInitialized, setWalletsInitialized] = useState<boolean>(false);
|
||||
const [isElectrumDisabled, setIsElectrumDisabled] = useState<boolean>(true);
|
||||
const [currentSharedCosigner, setCurrentSharedCosigner] = useState<string>('');
|
||||
const [reloadTransactionsMenuActionFunction, setReloadTransactionsMenuActionFunction] = useState<() => void>(() => {});
|
||||
|
||||
useEffect(() => {
|
||||
setWallets(BlueApp.getWallets());
|
||||
(async () => {
|
||||
const isElectrumDisabledValue = await BlueElectrum.isDisabled();
|
||||
setIsElectrumDisabled(isElectrumDisabledValue);
|
||||
if (walletsInitialized && !isElectrumDisabledValue) {
|
||||
BlueElectrum.connectMain();
|
||||
}
|
||||
})();
|
||||
}, [walletsInitialized]);
|
||||
|
||||
const saveToDisk = async (force: boolean = false) => {
|
||||
InteractionManager.runAfterInteractions(async () => {
|
||||
if (BlueApp.getWallets().length === 0 && !force) {
|
||||
console.log('not saving empty wallets array');
|
||||
return;
|
||||
}
|
||||
BlueApp.tx_metadata = txMetadata;
|
||||
BlueApp.counterparty_metadata = counterpartyMetadata;
|
||||
await BlueApp.saveToDisk();
|
||||
setWallets([...BlueApp.getWallets()]);
|
||||
txMetadata = BlueApp.tx_metadata;
|
||||
counterpartyMetadata = BlueApp.counterparty_metadata;
|
||||
});
|
||||
};
|
||||
|
||||
const resetWallets = () => {
|
||||
setWallets(BlueApp.getWallets());
|
||||
};
|
||||
|
||||
const setWalletsWithNewOrder = (wlts: TWallet[]) => {
|
||||
BlueApp.wallets = wlts;
|
||||
saveToDisk();
|
||||
};
|
||||
|
||||
const refreshAllWalletTransactions = async (lastSnappedTo?: number, showUpdateStatusIndicator: boolean = true) => {
|
||||
InteractionManager.runAfterInteractions(async () => {
|
||||
let noErr = true;
|
||||
try {
|
||||
await BlueElectrum.waitTillConnected();
|
||||
if (showUpdateStatusIndicator) {
|
||||
setWalletTransactionUpdateStatus(WalletTransactionsStatus.ALL);
|
||||
}
|
||||
const paymentCodesStart = Date.now();
|
||||
await BlueApp.fetchSenderPaymentCodes(lastSnappedTo);
|
||||
const paymentCodesEnd = Date.now();
|
||||
console.log('fetch payment codes took', (paymentCodesEnd - paymentCodesStart) / 1000, 'sec');
|
||||
const balanceStart = +new Date();
|
||||
await fetchWalletBalances(lastSnappedTo);
|
||||
const balanceEnd = +new Date();
|
||||
console.log('fetch balance took', (balanceEnd - balanceStart) / 1000, 'sec');
|
||||
const start = +new Date();
|
||||
await fetchWalletTransactions(lastSnappedTo);
|
||||
const end = +new Date();
|
||||
console.log('fetch tx took', (end - start) / 1000, 'sec');
|
||||
} catch (err) {
|
||||
noErr = false;
|
||||
console.warn(err);
|
||||
} finally {
|
||||
setWalletTransactionUpdateStatus(WalletTransactionsStatus.NONE);
|
||||
}
|
||||
if (noErr) await saveToDisk(); // caching
|
||||
});
|
||||
};
|
||||
|
||||
const fetchAndSaveWalletTransactions = async (walletID: string) => {
|
||||
InteractionManager.runAfterInteractions(async () => {
|
||||
const index = wallets.findIndex(wallet => wallet.getID() === walletID);
|
||||
let noErr = true;
|
||||
try {
|
||||
// 5sec debounce:
|
||||
if (+new Date() - _lastTimeTriedToRefetchWallet[walletID] < 5000) {
|
||||
console.log('re-fetch wallet happens too fast; NOP');
|
||||
return;
|
||||
}
|
||||
_lastTimeTriedToRefetchWallet[walletID] = +new Date();
|
||||
|
||||
await BlueElectrum.waitTillConnected();
|
||||
setWalletTransactionUpdateStatus(walletID);
|
||||
const balanceStart = +new Date();
|
||||
await fetchWalletBalances(index);
|
||||
const balanceEnd = +new Date();
|
||||
console.log('fetch balance took', (balanceEnd - balanceStart) / 1000, 'sec');
|
||||
const start = +new Date();
|
||||
await fetchWalletTransactions(index);
|
||||
const end = +new Date();
|
||||
console.log('fetch tx took', (end - start) / 1000, 'sec');
|
||||
} catch (err) {
|
||||
noErr = false;
|
||||
console.warn(err);
|
||||
} finally {
|
||||
setWalletTransactionUpdateStatus(WalletTransactionsStatus.NONE);
|
||||
}
|
||||
if (noErr) await saveToDisk(); // caching
|
||||
});
|
||||
};
|
||||
|
||||
const addWallet = (wallet: TWallet) => {
|
||||
BlueApp.wallets.push(wallet);
|
||||
setWallets([...BlueApp.getWallets()]);
|
||||
};
|
||||
|
||||
const deleteWallet = (wallet: TWallet) => {
|
||||
BlueApp.deleteWallet(wallet);
|
||||
setWallets([...BlueApp.getWallets()]);
|
||||
};
|
||||
|
||||
const addAndSaveWallet = async (w: TWallet) => {
|
||||
if (wallets.some(i => i.getID() === w.getID())) {
|
||||
triggerHapticFeedback(HapticFeedbackTypes.NotificationError);
|
||||
presentAlert({ message: 'This wallet has been previously imported.' });
|
||||
return;
|
||||
}
|
||||
const emptyWalletLabel = new LegacyWallet().getLabel();
|
||||
triggerHapticFeedback(HapticFeedbackTypes.NotificationSuccess);
|
||||
if (w.getLabel() === emptyWalletLabel) w.setLabel(loc.wallets.import_imported + ' ' + w.typeReadable);
|
||||
w.setUserHasSavedExport(true);
|
||||
addWallet(w);
|
||||
await saveToDisk();
|
||||
A(A.ENUM.CREATED_WALLET);
|
||||
presentAlert({
|
||||
hapticFeedback: HapticFeedbackTypes.ImpactHeavy,
|
||||
message: w.type === WatchOnlyWallet.type ? loc.wallets.import_success_watchonly : loc.wallets.import_success,
|
||||
});
|
||||
// @ts-ignore need to type notifications first
|
||||
Notifications.majorTomToGroundControl(w.getAllExternalAddresses(), [], []);
|
||||
// start balance fetching at the background
|
||||
await w.fetchBalance();
|
||||
setWallets([...BlueApp.getWallets()]);
|
||||
};
|
||||
|
||||
let txMetadata = BlueApp.tx_metadata;
|
||||
let counterpartyMetadata = BlueApp.counterparty_metadata || {}; // init
|
||||
const txMetadata = useRef<TTXMetadata>(BlueApp.tx_metadata);
|
||||
const counterpartyMetadata = useRef<TCounterpartyMetadata>(BlueApp.counterparty_metadata || {}); // init
|
||||
const getTransactions = BlueApp.getTransactions;
|
||||
const fetchWalletBalances = BlueApp.fetchWalletBalances;
|
||||
const fetchWalletTransactions = BlueApp.fetchWalletTransactions;
|
||||
|
@ -220,46 +79,227 @@ export const BlueStorageProvider = ({ children }: { children: React.ReactNode })
|
|||
const getItem = BlueApp.getItem;
|
||||
const setItem = BlueApp.setItem;
|
||||
|
||||
const value: BlueStorageContextType = {
|
||||
wallets,
|
||||
setWalletsWithNewOrder,
|
||||
txMetadata,
|
||||
counterpartyMetadata,
|
||||
saveToDisk,
|
||||
getTransactions,
|
||||
selectedWalletID,
|
||||
setSelectedWalletID,
|
||||
addWallet,
|
||||
deleteWallet,
|
||||
currentSharedCosigner,
|
||||
setSharedCosigner: setCurrentSharedCosigner,
|
||||
addAndSaveWallet,
|
||||
setItem,
|
||||
getItem,
|
||||
fetchWalletBalances,
|
||||
fetchWalletTransactions,
|
||||
fetchAndSaveWalletTransactions,
|
||||
isStorageEncrypted,
|
||||
encryptStorage,
|
||||
startAndDecrypt,
|
||||
cachedPassword,
|
||||
getBalance,
|
||||
walletsInitialized,
|
||||
setWalletsInitialized,
|
||||
refreshAllWalletTransactions,
|
||||
sleep,
|
||||
createFakeStorage,
|
||||
resetWallets,
|
||||
decryptStorage,
|
||||
isPasswordInUse,
|
||||
walletTransactionUpdateStatus,
|
||||
setWalletTransactionUpdateStatus,
|
||||
isElectrumDisabled,
|
||||
setIsElectrumDisabled,
|
||||
reloadTransactionsMenuActionFunction,
|
||||
setReloadTransactionsMenuActionFunction,
|
||||
const [wallets, setWallets] = useState<TWallet[]>([]);
|
||||
const [selectedWalletID, setSelectedWalletID] = useState<undefined | string>();
|
||||
const [walletTransactionUpdateStatus, setWalletTransactionUpdateStatus] = useState<WalletTransactionsStatus | string>(
|
||||
WalletTransactionsStatus.NONE,
|
||||
);
|
||||
const [walletsInitialized, setWalletsInitialized] = useState<boolean>(false);
|
||||
const [isElectrumDisabled, setIsElectrumDisabled] = useState<boolean>(true);
|
||||
const [currentSharedCosigner, setCurrentSharedCosigner] = useState<string>('');
|
||||
const [reloadTransactionsMenuActionFunction, setReloadTransactionsMenuActionFunction] = useState<() => void>(() => {});
|
||||
|
||||
useEffect(() => {
|
||||
BlueElectrum.isDisabled().then(setIsElectrumDisabled);
|
||||
if (walletsInitialized) {
|
||||
setWallets(BlueApp.getWallets());
|
||||
BlueElectrum.connectMain();
|
||||
}
|
||||
}, [walletsInitialized]);
|
||||
|
||||
const saveToDisk = useCallback(async (force: boolean = false) => {
|
||||
InteractionManager.runAfterInteractions(async () => {
|
||||
if (BlueApp.getWallets().length === 0 && !force) {
|
||||
console.log('not saving empty wallets array');
|
||||
return;
|
||||
}
|
||||
BlueApp.tx_metadata = txMetadata.current;
|
||||
BlueApp.counterparty_metadata = counterpartyMetadata.current;
|
||||
await BlueApp.saveToDisk();
|
||||
setWallets([...BlueApp.getWallets()]);
|
||||
txMetadata.current = BlueApp.tx_metadata;
|
||||
counterpartyMetadata.current = BlueApp.counterparty_metadata;
|
||||
});
|
||||
}, []);
|
||||
|
||||
const resetWallets = () => {
|
||||
setWallets(BlueApp.getWallets());
|
||||
};
|
||||
|
||||
const setWalletsWithNewOrder = useCallback(
|
||||
(wlts: TWallet[]) => {
|
||||
BlueApp.wallets = wlts;
|
||||
saveToDisk();
|
||||
},
|
||||
[saveToDisk],
|
||||
);
|
||||
|
||||
const refreshAllWalletTransactions = useCallback(
|
||||
async (lastSnappedTo?: number, showUpdateStatusIndicator: boolean = true) => {
|
||||
InteractionManager.runAfterInteractions(async () => {
|
||||
let noErr = true;
|
||||
try {
|
||||
await BlueElectrum.waitTillConnected();
|
||||
if (showUpdateStatusIndicator) {
|
||||
setWalletTransactionUpdateStatus(WalletTransactionsStatus.ALL);
|
||||
}
|
||||
const paymentCodesStart = Date.now();
|
||||
await BlueApp.fetchSenderPaymentCodes(lastSnappedTo);
|
||||
const paymentCodesEnd = Date.now();
|
||||
console.log('fetch payment codes took', (paymentCodesEnd - paymentCodesStart) / 1000, 'sec');
|
||||
const balanceStart = +new Date();
|
||||
await fetchWalletBalances(lastSnappedTo);
|
||||
const balanceEnd = +new Date();
|
||||
console.log('fetch balance took', (balanceEnd - balanceStart) / 1000, 'sec');
|
||||
const start = +new Date();
|
||||
await fetchWalletTransactions(lastSnappedTo);
|
||||
const end = +new Date();
|
||||
console.log('fetch tx took', (end - start) / 1000, 'sec');
|
||||
} catch (err) {
|
||||
noErr = false;
|
||||
console.warn(err);
|
||||
} finally {
|
||||
setWalletTransactionUpdateStatus(WalletTransactionsStatus.NONE);
|
||||
}
|
||||
if (noErr) await saveToDisk(); // caching
|
||||
});
|
||||
},
|
||||
[fetchWalletBalances, fetchWalletTransactions, saveToDisk],
|
||||
);
|
||||
|
||||
const fetchAndSaveWalletTransactions = useCallback(
|
||||
async (walletID: string) => {
|
||||
InteractionManager.runAfterInteractions(async () => {
|
||||
const index = wallets.findIndex(wallet => wallet.getID() === walletID);
|
||||
let noErr = true;
|
||||
try {
|
||||
// 5sec debounce:
|
||||
if (+new Date() - _lastTimeTriedToRefetchWallet[walletID] < 5000) {
|
||||
console.log('re-fetch wallet happens too fast; NOP');
|
||||
return;
|
||||
}
|
||||
_lastTimeTriedToRefetchWallet[walletID] = +new Date();
|
||||
|
||||
await BlueElectrum.waitTillConnected();
|
||||
setWalletTransactionUpdateStatus(walletID);
|
||||
const balanceStart = +new Date();
|
||||
await fetchWalletBalances(index);
|
||||
const balanceEnd = +new Date();
|
||||
console.log('fetch balance took', (balanceEnd - balanceStart) / 1000, 'sec');
|
||||
const start = +new Date();
|
||||
await fetchWalletTransactions(index);
|
||||
const end = +new Date();
|
||||
console.log('fetch tx took', (end - start) / 1000, 'sec');
|
||||
} catch (err) {
|
||||
noErr = false;
|
||||
console.warn(err);
|
||||
} finally {
|
||||
setWalletTransactionUpdateStatus(WalletTransactionsStatus.NONE);
|
||||
}
|
||||
if (noErr) await saveToDisk(); // caching
|
||||
});
|
||||
},
|
||||
[fetchWalletBalances, fetchWalletTransactions, saveToDisk, wallets],
|
||||
);
|
||||
|
||||
const addWallet = useCallback((wallet: TWallet) => {
|
||||
BlueApp.wallets.push(wallet);
|
||||
setWallets([...BlueApp.getWallets()]);
|
||||
}, []);
|
||||
|
||||
const deleteWallet = useCallback((wallet: TWallet) => {
|
||||
BlueApp.deleteWallet(wallet);
|
||||
setWallets([...BlueApp.getWallets()]);
|
||||
}, []);
|
||||
|
||||
const addAndSaveWallet = useCallback(
|
||||
async (w: TWallet) => {
|
||||
if (wallets.some(i => i.getID() === w.getID())) {
|
||||
triggerHapticFeedback(HapticFeedbackTypes.NotificationError);
|
||||
presentAlert({ message: 'This wallet has been previously imported.' });
|
||||
return;
|
||||
}
|
||||
const emptyWalletLabel = new LegacyWallet().getLabel();
|
||||
triggerHapticFeedback(HapticFeedbackTypes.NotificationSuccess);
|
||||
if (w.getLabel() === emptyWalletLabel) w.setLabel(loc.wallets.import_imported + ' ' + w.typeReadable);
|
||||
w.setUserHasSavedExport(true);
|
||||
addWallet(w);
|
||||
await saveToDisk();
|
||||
A(A.ENUM.CREATED_WALLET);
|
||||
presentAlert({
|
||||
hapticFeedback: HapticFeedbackTypes.ImpactHeavy,
|
||||
message: w.type === WatchOnlyWallet.type ? loc.wallets.import_success_watchonly : loc.wallets.import_success,
|
||||
});
|
||||
// @ts-ignore need to type notifications first
|
||||
Notifications.majorTomToGroundControl(w.getAllExternalAddresses(), [], []);
|
||||
// start balance fetching at the background
|
||||
await w.fetchBalance();
|
||||
setWallets([...BlueApp.getWallets()]);
|
||||
},
|
||||
[addWallet, saveToDisk, wallets],
|
||||
);
|
||||
|
||||
const value: BlueStorageContextType = useMemo(
|
||||
() => ({
|
||||
wallets,
|
||||
setWalletsWithNewOrder,
|
||||
txMetadata: txMetadata.current,
|
||||
counterpartyMetadata: counterpartyMetadata.current,
|
||||
saveToDisk,
|
||||
getTransactions,
|
||||
selectedWalletID,
|
||||
setSelectedWalletID,
|
||||
addWallet,
|
||||
deleteWallet,
|
||||
currentSharedCosigner,
|
||||
setSharedCosigner: setCurrentSharedCosigner,
|
||||
addAndSaveWallet,
|
||||
setItem,
|
||||
getItem,
|
||||
fetchWalletBalances,
|
||||
fetchWalletTransactions,
|
||||
fetchAndSaveWalletTransactions,
|
||||
isStorageEncrypted,
|
||||
encryptStorage,
|
||||
startAndDecrypt,
|
||||
cachedPassword,
|
||||
getBalance,
|
||||
walletsInitialized,
|
||||
setWalletsInitialized,
|
||||
refreshAllWalletTransactions,
|
||||
sleep,
|
||||
createFakeStorage,
|
||||
resetWallets,
|
||||
decryptStorage,
|
||||
isPasswordInUse,
|
||||
walletTransactionUpdateStatus,
|
||||
setWalletTransactionUpdateStatus,
|
||||
isElectrumDisabled,
|
||||
setIsElectrumDisabled,
|
||||
reloadTransactionsMenuActionFunction,
|
||||
setReloadTransactionsMenuActionFunction,
|
||||
}),
|
||||
[
|
||||
wallets,
|
||||
setWalletsWithNewOrder,
|
||||
saveToDisk,
|
||||
getTransactions,
|
||||
selectedWalletID,
|
||||
addWallet,
|
||||
deleteWallet,
|
||||
currentSharedCosigner,
|
||||
addAndSaveWallet,
|
||||
setItem,
|
||||
getItem,
|
||||
fetchWalletBalances,
|
||||
fetchWalletTransactions,
|
||||
fetchAndSaveWalletTransactions,
|
||||
isStorageEncrypted,
|
||||
encryptStorage,
|
||||
cachedPassword,
|
||||
getBalance,
|
||||
walletsInitialized,
|
||||
refreshAllWalletTransactions,
|
||||
sleep,
|
||||
createFakeStorage,
|
||||
decryptStorage,
|
||||
isPasswordInUse,
|
||||
walletTransactionUpdateStatus,
|
||||
isElectrumDisabled,
|
||||
reloadTransactionsMenuActionFunction,
|
||||
],
|
||||
);
|
||||
|
||||
return <BlueStorageContext.Provider value={value}>{children}</BlueStorageContext.Provider>;
|
||||
};
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue