mirror of
https://github.com/BlueWallet/BlueWallet.git
synced 2025-02-23 07:15:35 +01:00
Merge branch 'master' into realmtmp
This commit is contained in:
commit
80a3318780
24 changed files with 239 additions and 146 deletions
2
App.js
2
App.js
|
@ -27,7 +27,7 @@ import WatchConnectivity from './WatchConnectivity';
|
|||
import DeviceQuickActions from './class/quick-actions';
|
||||
import Notifications from './blue_modules/notifications';
|
||||
import Biometric from './class/biometrics';
|
||||
import WidgetCommunication from './blue_modules/WidgetCommunication';
|
||||
import WidgetCommunication from './components/WidgetCommunication';
|
||||
import ActionSheet from './screen/ActionSheet';
|
||||
import triggerHapticFeedback, { HapticFeedbackTypes } from './blue_modules/hapticFeedback';
|
||||
import MenuElements from './components/MenuElements';
|
||||
|
|
|
@ -4,11 +4,10 @@ import * as bitcoin from 'bitcoinjs-lib';
|
|||
import { Alert } from 'react-native';
|
||||
import DefaultPreference from 'react-native-default-preference';
|
||||
import Realm from 'realm';
|
||||
import RNFS from 'react-native-fs';
|
||||
import { LegacyWallet, SegwitBech32Wallet, SegwitP2SHWallet, TaprootWallet } from '../class';
|
||||
import presentAlert from '../components/Alert';
|
||||
import loc from '../loc';
|
||||
import WidgetCommunication from './WidgetCommunication';
|
||||
import { reloadAllTimelines } from '../components/WidgetCommunication';
|
||||
|
||||
const ElectrumClient = require('electrum-client');
|
||||
const net = require('net');
|
||||
|
@ -213,7 +212,7 @@ export async function connectMain(): Promise<void> {
|
|||
await DefaultPreference.set(ELECTRUM_SSL_PORT, usingPeer.ssl ?? '');
|
||||
}
|
||||
|
||||
WidgetCommunication.reloadAllTimelines();
|
||||
reloadAllTimelines();
|
||||
} catch (e) {
|
||||
// Must be running on Android
|
||||
console.log(e);
|
||||
|
@ -340,7 +339,7 @@ const presentNetworkErrorAlert = async (usingPeer?: Peer) => {
|
|||
await DefaultPreference.clear(ELECTRUM_HOST);
|
||||
await DefaultPreference.clear(ELECTRUM_SSL_PORT);
|
||||
await DefaultPreference.clear(ELECTRUM_TCP_PORT);
|
||||
WidgetCommunication.reloadAllTimelines();
|
||||
reloadAllTimelines();
|
||||
} catch (e) {
|
||||
// Must be running on Android
|
||||
console.log(e);
|
||||
|
|
|
@ -1,79 +0,0 @@
|
|||
import { useContext, useEffect } from 'react';
|
||||
import { BlueStorageContext } from './storage-context';
|
||||
import DefaultPreference from 'react-native-default-preference';
|
||||
import RNWidgetCenter from 'react-native-widget-center';
|
||||
import AsyncStorage from '@react-native-async-storage/async-storage';
|
||||
|
||||
function WidgetCommunication() {
|
||||
WidgetCommunication.WidgetCommunicationAllWalletsSatoshiBalance = 'WidgetCommunicationAllWalletsSatoshiBalance';
|
||||
WidgetCommunication.WidgetCommunicationAllWalletsLatestTransactionTime = 'WidgetCommunicationAllWalletsLatestTransactionTime';
|
||||
WidgetCommunication.WidgetCommunicationDisplayBalanceAllowed = 'WidgetCommunicationDisplayBalanceAllowed';
|
||||
WidgetCommunication.LatestTransactionIsUnconfirmed = 'WidgetCommunicationLatestTransactionIsUnconfirmed';
|
||||
const { wallets, walletsInitialized, isStorageEncrypted } = useContext(BlueStorageContext);
|
||||
|
||||
WidgetCommunication.isBalanceDisplayAllowed = async () => {
|
||||
try {
|
||||
const displayBalance = JSON.parse(await AsyncStorage.getItem(WidgetCommunication.WidgetCommunicationDisplayBalanceAllowed));
|
||||
if (displayBalance !== null) {
|
||||
return displayBalance;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
} catch (e) {
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
WidgetCommunication.setBalanceDisplayAllowed = async value => {
|
||||
await AsyncStorage.setItem(WidgetCommunication.WidgetCommunicationDisplayBalanceAllowed, JSON.stringify(value));
|
||||
setValues();
|
||||
};
|
||||
|
||||
WidgetCommunication.reloadAllTimelines = () => {
|
||||
RNWidgetCenter.reloadAllTimelines();
|
||||
};
|
||||
|
||||
const allWalletsBalanceAndTransactionTime = async () => {
|
||||
if ((await isStorageEncrypted()) || !(await WidgetCommunication.isBalanceDisplayAllowed())) {
|
||||
return { allWalletsBalance: 0, latestTransactionTime: 0 };
|
||||
} else {
|
||||
let balance = 0;
|
||||
let latestTransactionTime = 0;
|
||||
for (const wallet of wallets) {
|
||||
if (wallet.hideBalance) {
|
||||
continue;
|
||||
}
|
||||
balance += wallet.getBalance();
|
||||
if (wallet.getLatestTransactionTimeEpoch() > latestTransactionTime) {
|
||||
if (wallet.getTransactions()[0].confirmations === 0) {
|
||||
latestTransactionTime = WidgetCommunication.LatestTransactionIsUnconfirmed;
|
||||
} else {
|
||||
latestTransactionTime = wallet.getLatestTransactionTimeEpoch();
|
||||
}
|
||||
}
|
||||
}
|
||||
return { allWalletsBalance: balance, latestTransactionTime };
|
||||
}
|
||||
};
|
||||
const setValues = async () => {
|
||||
await DefaultPreference.setName('group.io.bluewallet.bluewallet');
|
||||
const { allWalletsBalance, latestTransactionTime } = await allWalletsBalanceAndTransactionTime();
|
||||
await DefaultPreference.set(WidgetCommunication.WidgetCommunicationAllWalletsSatoshiBalance, JSON.stringify(allWalletsBalance));
|
||||
await DefaultPreference.set(
|
||||
WidgetCommunication.WidgetCommunicationAllWalletsLatestTransactionTime,
|
||||
JSON.stringify(latestTransactionTime),
|
||||
);
|
||||
RNWidgetCenter.reloadAllTimelines();
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
if (walletsInitialized) {
|
||||
setValues();
|
||||
}
|
||||
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [wallets, walletsInitialized]);
|
||||
return null;
|
||||
}
|
||||
|
||||
export default WidgetCommunication;
|
|
@ -3,7 +3,7 @@ import DefaultPreference from 'react-native-default-preference';
|
|||
import * as RNLocalize from 'react-native-localize';
|
||||
import BigNumber from 'bignumber.js';
|
||||
import { FiatUnit, FiatUnitType, getFiatRate } from '../models/fiatUnit';
|
||||
import WidgetCommunication from './WidgetCommunication';
|
||||
import { reloadAllTimelines } from '../components/WidgetCommunication';
|
||||
|
||||
const PREFERRED_CURRENCY_STORAGE_KEY = 'preferredCurrency';
|
||||
const PREFERRED_CURRENCY_LOCALE_STORAGE_KEY = 'preferredCurrencyLocale';
|
||||
|
@ -33,7 +33,7 @@ async function setPreferredCurrency(item: FiatUnitType): Promise<void> {
|
|||
await DefaultPreference.set(PREFERRED_CURRENCY_STORAGE_KEY, item.endPointKey);
|
||||
await DefaultPreference.set(PREFERRED_CURRENCY_LOCALE_STORAGE_KEY, item.locale.replace('-', '_'));
|
||||
// @ts-ignore: Convert to TSX later
|
||||
WidgetCommunication.reloadAllTimelines();
|
||||
reloadAllTimelines();
|
||||
}
|
||||
|
||||
async function getPreferredCurrency(): Promise<FiatUnitType> {
|
||||
|
|
|
@ -41,7 +41,7 @@ export class DynamicQRCode extends Component<DynamicQRCodeProps, DynamicQRCodeSt
|
|||
fragments: string[] = [];
|
||||
|
||||
componentDidMount() {
|
||||
const { value, capacity = 200, hideControls = true } = this.props;
|
||||
const { value, capacity = 175, hideControls = true } = this.props;
|
||||
try {
|
||||
this.fragments = encodeUR(value, capacity);
|
||||
this.setState(
|
||||
|
|
|
@ -12,9 +12,20 @@ interface SaveFileButtonProps {
|
|||
style?: StyleProp<ViewStyle>;
|
||||
afterOnPress?: () => void;
|
||||
beforeOnPress?: () => Promise<void>; // Changed this line
|
||||
onMenuWillHide?: () => void;
|
||||
onMenuWillShow?: () => void;
|
||||
}
|
||||
|
||||
const SaveFileButton: React.FC<SaveFileButtonProps> = ({ fileName, fileContent, children, style, beforeOnPress, afterOnPress }) => {
|
||||
const SaveFileButton: React.FC<SaveFileButtonProps> = ({
|
||||
fileName,
|
||||
fileContent,
|
||||
children,
|
||||
style,
|
||||
beforeOnPress,
|
||||
afterOnPress,
|
||||
onMenuWillHide,
|
||||
onMenuWillShow,
|
||||
}) => {
|
||||
const actions = [
|
||||
{ id: 'save', text: loc._.save, icon: actionIcons.Save },
|
||||
{ id: 'share', text: loc.receive.details_share, icon: actionIcons.Share },
|
||||
|
@ -39,7 +50,15 @@ const SaveFileButton: React.FC<SaveFileButtonProps> = ({ fileName, fileContent,
|
|||
|
||||
return (
|
||||
// @ts-ignore: Tooltip must be refactored to use TSX}
|
||||
<ToolTipMenu isButton isMenuPrimaryAction actions={actions} onPressMenuItem={handlePressMenuItem} buttonStyle={style}>
|
||||
<ToolTipMenu
|
||||
onMenuWillHide={onMenuWillHide}
|
||||
onMenuWillShow={onMenuWillShow}
|
||||
isButton
|
||||
isMenuPrimaryAction
|
||||
actions={actions}
|
||||
onPressMenuItem={handlePressMenuItem}
|
||||
buttonStyle={style}
|
||||
>
|
||||
{children}
|
||||
</ToolTipMenu>
|
||||
);
|
||||
|
|
|
@ -34,7 +34,13 @@ export const SecondButton = forwardRef<TouchableOpacity, SecondButtonProps>((pro
|
|||
);
|
||||
|
||||
return props.onPress ? (
|
||||
<TouchableOpacity accessibilityRole="button" style={[styles.button, { backgroundColor }]} {...props} ref={ref}>
|
||||
<TouchableOpacity
|
||||
disabled={props.disabled}
|
||||
accessibilityRole="button"
|
||||
style={[styles.button, { backgroundColor }]}
|
||||
{...props}
|
||||
ref={ref}
|
||||
>
|
||||
{buttonView}
|
||||
</TouchableOpacity>
|
||||
) : (
|
||||
|
|
|
@ -42,12 +42,16 @@ const BaseToolTipMenu = (props, ref) => {
|
|||
const renderPreview = props.renderPreview ?? undefined;
|
||||
const disabled = props.disabled ?? false;
|
||||
const onPress = props.onPress ?? undefined;
|
||||
const onMenuWillShow = props.onMenuWillShow ?? undefined;
|
||||
const onMenuWillHide = props.onMenuWillHide ?? undefined;
|
||||
|
||||
const buttonStyle = props.buttonStyle;
|
||||
return isButton ? (
|
||||
<TouchableOpacity onPress={onPress} disabled={disabled} accessibilityRole="button" style={buttonStyle}>
|
||||
<ContextMenuButton
|
||||
ref={ref}
|
||||
onMenuWillShow={onMenuWillShow}
|
||||
onMenuWillHide={onMenuWillHide}
|
||||
useActionSheetFallback={false}
|
||||
onPressMenuItem={({ nativeEvent }) => {
|
||||
props.onPressMenuItem(nativeEvent.actionKey);
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { forwardRef } from 'react';
|
||||
|
||||
const BaseToolTipMenu = props => {
|
||||
const BaseToolTipMenu = (props, _ref) => {
|
||||
return props.children;
|
||||
};
|
||||
|
||||
|
|
|
@ -227,10 +227,10 @@ export const WalletCarouselItem = ({ item, _, onPress, handleLongPress, isSelect
|
|||
<Text
|
||||
numberOfLines={1}
|
||||
key={balance} // force component recreation on balance change. To fix right-to-left languages, like Farsi
|
||||
adjustsFontSizeToFit
|
||||
ellipsizeMode='middle'
|
||||
style={[iStyles.balance, { color: colors.inverseForegroundColor }]}
|
||||
>
|
||||
{balance}
|
||||
{`${balance} `}
|
||||
</Text>
|
||||
)}
|
||||
<Text style={iStyles.br} />
|
||||
|
|
80
components/WidgetCommunication.ios.tsx
Normal file
80
components/WidgetCommunication.ios.tsx
Normal file
|
@ -0,0 +1,80 @@
|
|||
import React, { useContext, useEffect } from 'react';
|
||||
import DefaultPreference from 'react-native-default-preference';
|
||||
// @ts-ignore: fix later
|
||||
import RNWidgetCenter from 'react-native-widget-center';
|
||||
import { BlueStorageContext } from '../blue_modules/storage-context';
|
||||
import { TWallet } from '../class/wallets/types';
|
||||
|
||||
enum WidgetCommunicationKeys {
|
||||
AllWalletsSatoshiBalance = 'WidgetCommunicationAllWalletsSatoshiBalance',
|
||||
AllWalletsLatestTransactionTime = 'WidgetCommunicationAllWalletsLatestTransactionTime',
|
||||
DisplayBalanceAllowed = 'WidgetCommunicationDisplayBalanceAllowed',
|
||||
LatestTransactionIsUnconfirmed = 'WidgetCommunicationLatestTransactionIsUnconfirmed',
|
||||
}
|
||||
|
||||
export const reloadAllTimelines = (): void => {
|
||||
RNWidgetCenter.reloadAllTimelines();
|
||||
};
|
||||
|
||||
export const isBalanceDisplayAllowed = async (): Promise<boolean> => {
|
||||
try {
|
||||
const displayBalance = await DefaultPreference.get(WidgetCommunicationKeys.DisplayBalanceAllowed);
|
||||
return displayBalance === '1';
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
export const setBalanceDisplayAllowed = async (value: boolean): Promise<void> => {
|
||||
if (value) {
|
||||
await DefaultPreference.set(WidgetCommunicationKeys.DisplayBalanceAllowed, '1');
|
||||
} else {
|
||||
await DefaultPreference.clear(WidgetCommunicationKeys.DisplayBalanceAllowed);
|
||||
}
|
||||
reloadAllTimelines();
|
||||
};
|
||||
|
||||
const WidgetCommunication: React.FC = () => {
|
||||
const { wallets, walletsInitialized } = useContext(BlueStorageContext);
|
||||
|
||||
useEffect(() => {
|
||||
const allWalletsBalanceAndTransactionTime = async (): Promise<{
|
||||
allWalletsBalance: number;
|
||||
latestTransactionTime: number | string;
|
||||
}> => {
|
||||
if (!walletsInitialized || !(await isBalanceDisplayAllowed())) {
|
||||
return { allWalletsBalance: 0, latestTransactionTime: 0 };
|
||||
} else {
|
||||
let balance = 0;
|
||||
let latestTransactionTime: number | string = 0;
|
||||
wallets.forEach((wallet: TWallet) => {
|
||||
if (wallet.hideBalance) return;
|
||||
balance += wallet.getBalance();
|
||||
const walletLatestTime = wallet.getLatestTransactionTimeEpoch();
|
||||
|
||||
if (typeof latestTransactionTime === 'number' && walletLatestTime > latestTransactionTime) {
|
||||
latestTransactionTime =
|
||||
wallet.getTransactions()[0]?.confirmations === 0 ? WidgetCommunicationKeys.LatestTransactionIsUnconfirmed : walletLatestTime;
|
||||
}
|
||||
});
|
||||
return { allWalletsBalance: balance, latestTransactionTime };
|
||||
}
|
||||
};
|
||||
|
||||
const setValues = async (): Promise<void> => {
|
||||
await DefaultPreference.setName('group.io.bluewallet.bluewallet');
|
||||
const { allWalletsBalance, latestTransactionTime } = await allWalletsBalanceAndTransactionTime();
|
||||
await DefaultPreference.set(WidgetCommunicationKeys.AllWalletsSatoshiBalance, String(allWalletsBalance));
|
||||
await DefaultPreference.set(WidgetCommunicationKeys.AllWalletsLatestTransactionTime, String(latestTransactionTime));
|
||||
reloadAllTimelines();
|
||||
};
|
||||
|
||||
if (walletsInitialized) {
|
||||
setValues();
|
||||
}
|
||||
}, [wallets, walletsInitialized]);
|
||||
|
||||
return null;
|
||||
};
|
||||
|
||||
export default WidgetCommunication;
|
15
components/WidgetCommunication.tsx
Normal file
15
components/WidgetCommunication.tsx
Normal file
|
@ -0,0 +1,15 @@
|
|||
import React from 'react';
|
||||
|
||||
export const isBalanceDisplayAllowed = async (): Promise<boolean> => {
|
||||
return true;
|
||||
};
|
||||
|
||||
export const setBalanceDisplayAllowed = async (value: boolean): Promise<void> => {};
|
||||
|
||||
export const reloadAllTimelines = (): void => {};
|
||||
|
||||
const WidgetCommunication: React.FC = () => {
|
||||
return null; // This component does not render anything.
|
||||
};
|
||||
|
||||
export default WidgetCommunication;
|
|
@ -8,9 +8,10 @@ export const presentWalletExportReminder = (): Promise<void> => {
|
|||
loc.pleasebackup.ask,
|
||||
[
|
||||
{ text: loc.pleasebackup.ask_yes, onPress: () => resolve(), style: 'default' },
|
||||
{ text: loc.pleasebackup.ask_no, onPress: () => reject(new Error('User has denied saving the wallet backup.')), style: 'cancel' },
|
||||
{ text: loc.pleasebackup.ask_no, onPress: () => reject(new Error('User has denied saving the wallet backup.')) },
|
||||
{ text: loc._.cancel, style: 'cancel' },
|
||||
],
|
||||
{ cancelable: false },
|
||||
{ cancelable: true },
|
||||
);
|
||||
});
|
||||
};
|
||||
|
|
|
@ -74,11 +74,13 @@ export const useExtendedNavigation = (): NavigationProp<ParamListBase> => {
|
|||
wallet.setUserHasSavedExport(true);
|
||||
await saveToDisk(); // Assuming saveToDisk() returns a Promise.
|
||||
proceedWithNavigation();
|
||||
} catch {
|
||||
originalNavigation.navigate('WalletExportRoot', {
|
||||
screen: 'WalletExport',
|
||||
params: { walletID },
|
||||
});
|
||||
} catch (error) {
|
||||
if (error) {
|
||||
originalNavigation.navigate('WalletExportRoot', {
|
||||
screen: 'WalletExport',
|
||||
params: { walletID },
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return; // Prevent proceeding with the original navigation if the reminder is shown
|
||||
|
|
|
@ -30,22 +30,15 @@ NSUserDefaults *group = [[NSUserDefaults alloc] initWithSuiteName:@"group.io.blu
|
|||
config.appType = @"macOS";
|
||||
// Start Bugsnag with the configuration
|
||||
[Bugsnag startWithConfiguration:config];
|
||||
[self copyDeviceUID];
|
||||
|
||||
#else
|
||||
[Bugsnag start];
|
||||
[self copyDeviceUID];
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
[self copyDeviceUID];
|
||||
|
||||
[[NSUserDefaults standardUserDefaults] addObserver:self
|
||||
forKeyPath:@"deviceUID"
|
||||
options:NSKeyValueObservingOptionNew
|
||||
context:NULL];
|
||||
[[NSUserDefaults standardUserDefaults] addObserver:self
|
||||
forKeyPath:@"deviceUIDCopy"
|
||||
options:NSKeyValueObservingOptionNew
|
||||
context:NULL];
|
||||
[self addSplashScreenView];
|
||||
|
||||
self.moduleName = @"BlueWallet";
|
||||
|
@ -95,6 +88,14 @@ NSUserDefaults *group = [[NSUserDefaults alloc] initWithSuiteName:@"group.io.blu
|
|||
}
|
||||
|
||||
- (void)copyDeviceUID {
|
||||
[[NSUserDefaults standardUserDefaults] addObserver:self
|
||||
forKeyPath:@"deviceUID"
|
||||
options:NSKeyValueObservingOptionNew
|
||||
context:NULL];
|
||||
[[NSUserDefaults standardUserDefaults] addObserver:self
|
||||
forKeyPath:@"deviceUIDCopy"
|
||||
options:NSKeyValueObservingOptionNew
|
||||
context:NULL];
|
||||
NSString *deviceUID = [[NSUserDefaults standardUserDefaults] stringForKey:@"deviceUID"];
|
||||
if (deviceUID && deviceUID.length > 0) {
|
||||
[NSUserDefaults.standardUserDefaults setValue:deviceUID forKey:@"deviceUIDCopy"];
|
||||
|
|
|
@ -20,9 +20,9 @@ PODS:
|
|||
- hermes-engine/Pre-built (= 0.72.12)
|
||||
- hermes-engine/Pre-built (0.72.12)
|
||||
- libevent (2.1.12)
|
||||
- lottie-ios (4.4.2)
|
||||
- lottie-react-native (6.7.0):
|
||||
- lottie-ios (~> 4.4.1)
|
||||
- lottie-ios (4.4.1)
|
||||
- lottie-react-native (6.7.2):
|
||||
- lottie-ios (= 4.4.1)
|
||||
- React-Core
|
||||
- PasscodeAuth (1.0.0):
|
||||
- React
|
||||
|
@ -792,8 +792,8 @@ SPEC CHECKSUMS:
|
|||
glog: 04b94705f318337d7ead9e6d17c019bd9b1f6b1b
|
||||
hermes-engine: e89344b9e9e54351c3c5cac075e0275148fb37ba
|
||||
libevent: 4049cae6c81cdb3654a443be001fb9bdceff7913
|
||||
lottie-ios: 4445b0bdb583c7a5325529f62246d311ee85fcd0
|
||||
lottie-react-native: e3205322282d72e23efb3bff3287d0bd16fb1b01
|
||||
lottie-ios: e047b1d2e6239b787cc5e9755b988869cf190494
|
||||
lottie-react-native: 17547b2f3c7034e2ae8672833fdb63262164d18a
|
||||
PasscodeAuth: 3e88093ff46c31a952d8b36c488240de980517be
|
||||
RCT-Folly: 424b8c9a7a0b9ab2886ffe9c3b041ef628fd4fb1
|
||||
RCTRequired: b6cea797b684c6d8d82ba0107cef58cbb679afdb
|
||||
|
|
|
@ -104,7 +104,7 @@ struct WalletInformationWidget: Widget {
|
|||
|
||||
struct WalletInformationWidget_Previews: PreviewProvider {
|
||||
static var previews: some View {
|
||||
WalletInformationWidgetEntryView(entry: WalletInformationWidgetEntry(date: Date(), marketData: MarketData(nextBlock: "26", sats: "9 134", price: "$10,000", rate: Double(0)), allWalletsBalance: WalletData(balance: 10000, latestTransactionTime: LatestTransaction(isUnconfirmed: false, epochValue: 1568804029000))))
|
||||
WalletInformationWidgetEntryView(entry: WalletInformationWidgetEntry(date: Date(), marketData: MarketData(nextBlock: "26", sats: "9 134", price: "$10,000", rate: Double(0)), allWalletsBalance: WalletData(balance: 0, latestTransactionTime: LatestTransaction(isUnconfirmed: nil, epochValue: nil))))
|
||||
.previewContext(WidgetPreviewContext(family: .systemSmall))
|
||||
}
|
||||
}
|
||||
|
|
14
package-lock.json
generated
14
package-lock.json
generated
|
@ -49,7 +49,7 @@
|
|||
"events": "3.3.0",
|
||||
"frisbee": "3.1.0",
|
||||
"junderw-crc32c": "1.2.0",
|
||||
"lottie-react-native": "6.7.0",
|
||||
"lottie-react-native": "6.7.2",
|
||||
"metro-react-native-babel-preset": "0.77.0",
|
||||
"path-browserify": "1.0.1",
|
||||
"payjoin-client": "1.0.1",
|
||||
|
@ -16909,9 +16909,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/lottie-react-native": {
|
||||
"version": "6.7.0",
|
||||
"resolved": "https://registry.npmjs.org/lottie-react-native/-/lottie-react-native-6.7.0.tgz",
|
||||
"integrity": "sha512-doiF/36LaKkzo0XkgUIK8egxALNY6jGjCI4szpRuwop15LTW3DFtIA2L3pusNdaH7oM797aSH5UylIJw2k+Hgw==",
|
||||
"version": "6.7.2",
|
||||
"resolved": "https://registry.npmjs.org/lottie-react-native/-/lottie-react-native-6.7.2.tgz",
|
||||
"integrity": "sha512-MZVx6N1EeO/EaSx8T44mJ0aHc5Mqee+xIfWwszni0oz8U2wlHdaWGjES44dHxaxgAp/0dRaFt3PkpZ6egTzcBg==",
|
||||
"peerDependencies": {
|
||||
"@dotlottie/react-player": "^1.6.1",
|
||||
"@lottiefiles/react-lottie-player": "^3.5.3",
|
||||
|
@ -35090,9 +35090,9 @@
|
|||
}
|
||||
},
|
||||
"lottie-react-native": {
|
||||
"version": "6.7.0",
|
||||
"resolved": "https://registry.npmjs.org/lottie-react-native/-/lottie-react-native-6.7.0.tgz",
|
||||
"integrity": "sha512-doiF/36LaKkzo0XkgUIK8egxALNY6jGjCI4szpRuwop15LTW3DFtIA2L3pusNdaH7oM797aSH5UylIJw2k+Hgw=="
|
||||
"version": "6.7.2",
|
||||
"resolved": "https://registry.npmjs.org/lottie-react-native/-/lottie-react-native-6.7.2.tgz",
|
||||
"integrity": "sha512-MZVx6N1EeO/EaSx8T44mJ0aHc5Mqee+xIfWwszni0oz8U2wlHdaWGjES44dHxaxgAp/0dRaFt3PkpZ6egTzcBg=="
|
||||
},
|
||||
"lru-cache": {
|
||||
"version": "5.1.1",
|
||||
|
|
|
@ -135,7 +135,7 @@
|
|||
"events": "3.3.0",
|
||||
"frisbee": "3.1.0",
|
||||
"junderw-crc32c": "1.2.0",
|
||||
"lottie-react-native": "6.7.0",
|
||||
"lottie-react-native": "6.7.2",
|
||||
"metro-react-native-babel-preset": "0.77.0",
|
||||
"path-browserify": "1.0.1",
|
||||
"payjoin-client": "1.0.1",
|
||||
|
|
|
@ -8,7 +8,7 @@ import loc from '../../loc';
|
|||
import DeviceQuickActions from '../../class/quick-actions';
|
||||
import BlueClipboard from '../../blue_modules/clipboard';
|
||||
import { BlueStorageContext } from '../../blue_modules/storage-context';
|
||||
import WidgetCommunication from '../../blue_modules/WidgetCommunication';
|
||||
import { isBalanceDisplayAllowed, setBalanceDisplayAllowed } from '../../components/WidgetCommunication';
|
||||
import { useTheme } from '../../components/themes';
|
||||
import ListItem from '../../components/ListItem';
|
||||
import A from '../../blue_modules/analytics';
|
||||
|
@ -38,7 +38,7 @@ const SettingsPrivacy = () => {
|
|||
setIsReadClipboardAllowed(await BlueClipboard().isReadClipboardAllowed());
|
||||
setStorageIsEncrypted(await isStorageEncrypted());
|
||||
setIsQuickActionsEnabled(await DeviceQuickActions.getEnabled());
|
||||
setIsDisplayWidgetBalanceAllowed(await WidgetCommunication.isBalanceDisplayAllowed());
|
||||
setIsDisplayWidgetBalanceAllowed(await isBalanceDisplayAllowed());
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
|
@ -84,7 +84,7 @@ const SettingsPrivacy = () => {
|
|||
const onWidgetsTotalBalanceValueChange = async value => {
|
||||
setIsLoading(sections.WIDGETS);
|
||||
try {
|
||||
await WidgetCommunication.setBalanceDisplayAllowed(value);
|
||||
await setBalanceDisplayAllowed(value);
|
||||
setIsDisplayWidgetBalanceAllowed(value);
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
|
|
|
@ -29,7 +29,7 @@ import {
|
|||
BlueDismissKeyboardInputAccessory,
|
||||
} from '../../BlueComponents';
|
||||
import { BlueCurrentTheme } from '../../components/themes';
|
||||
import WidgetCommunication from '../../blue_modules/WidgetCommunication';
|
||||
import { reloadAllTimelines } from '../../components/WidgetCommunication';
|
||||
import { BlueStorageContext } from '../../blue_modules/storage-context';
|
||||
import presentAlert from '../../components/Alert';
|
||||
import { requestCameraAuthorization } from '../../helpers/scan-qr';
|
||||
|
@ -170,7 +170,7 @@ export default class ElectrumSettings extends Component {
|
|||
await DefaultPreference.clear(BlueElectrum.ELECTRUM_HOST);
|
||||
await DefaultPreference.clear(BlueElectrum.ELECTRUM_SSL_PORT);
|
||||
await DefaultPreference.clear(BlueElectrum.ELECTRUM_TCP_PORT);
|
||||
WidgetCommunication.reloadAllTimelines();
|
||||
reloadAllTimelines();
|
||||
} catch (e) {
|
||||
// Must be running on Android
|
||||
console.log(e);
|
||||
|
@ -199,7 +199,7 @@ export default class ElectrumSettings extends Component {
|
|||
await DefaultPreference.set(BlueElectrum.ELECTRUM_HOST, host);
|
||||
await DefaultPreference.set(BlueElectrum.ELECTRUM_TCP_PORT, port);
|
||||
await DefaultPreference.set(BlueElectrum.ELECTRUM_SSL_PORT, sslPort);
|
||||
WidgetCommunication.reloadAllTimelines();
|
||||
reloadAllTimelines();
|
||||
} catch (e) {
|
||||
// Must be running on Android
|
||||
console.log(e);
|
||||
|
|
|
@ -97,7 +97,6 @@ const styles = StyleSheet.create({
|
|||
justifyContent: 'space-between',
|
||||
},
|
||||
delete: {
|
||||
color: '#d0021b',
|
||||
fontSize: 15,
|
||||
fontWeight: '500',
|
||||
textAlign: 'center',
|
||||
|
@ -147,6 +146,10 @@ const WalletDetails = () => {
|
|||
}
|
||||
}, [wallet]);
|
||||
const [lightningWalletInfo, setLightningWalletInfo] = useState({});
|
||||
const [isToolTipMenuVisible, setIsToolTipMenuVisible] = useState(false);
|
||||
|
||||
const onMenuWillShow = () => setIsToolTipMenuVisible(true);
|
||||
const onMenuWillHide = () => setIsToolTipMenuVisible(false);
|
||||
|
||||
useEffect(() => {
|
||||
if (isAdvancedModeEnabledRender && wallet.allowMasterFingerprint()) {
|
||||
|
@ -177,6 +180,9 @@ const WalletDetails = () => {
|
|||
saveText: {
|
||||
color: colors.buttonTextColor,
|
||||
},
|
||||
delete: {
|
||||
color: isToolTipMenuVisible ? colors.buttonDisabledTextColor : '#d0021b',
|
||||
},
|
||||
});
|
||||
useEffect(() => {
|
||||
if (wallet.type === LightningLdkWallet.type) {
|
||||
|
@ -216,7 +222,7 @@ const WalletDetails = () => {
|
|||
<TouchableOpacity
|
||||
accessibilityRole="button"
|
||||
testID="Save"
|
||||
disabled={isLoading}
|
||||
disabled={isLoading || isToolTipMenuVisible}
|
||||
style={[styles.save, stylesHook.save]}
|
||||
onPress={save}
|
||||
>
|
||||
|
@ -225,7 +231,7 @@ const WalletDetails = () => {
|
|||
),
|
||||
});
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [isLoading, colors, walletName, useWithHardwareWallet, hideTransactionsInWalletsList, isBIP47Enabled]);
|
||||
}, [isLoading, colors, walletName, useWithHardwareWallet, hideTransactionsInWalletsList, isBIP47Enabled, isToolTipMenuVisible]);
|
||||
|
||||
useEffect(() => {
|
||||
if (wallets.some(w => w.getID() === walletID)) {
|
||||
|
@ -594,7 +600,11 @@ const WalletDetails = () => {
|
|||
</Text>
|
||||
<View style={styles.hardware}>
|
||||
<BlueText onPress={() => setBackdoorBip47Pressed(prevState => prevState + 1)}>{loc.wallets.details_display}</BlueText>
|
||||
<Switch value={hideTransactionsInWalletsList} onValueChange={setHideTransactionsInWalletsList} />
|
||||
<Switch
|
||||
disabled={isToolTipMenuVisible}
|
||||
value={hideTransactionsInWalletsList}
|
||||
onValueChange={setHideTransactionsInWalletsList}
|
||||
/>
|
||||
</View>
|
||||
</>
|
||||
<>
|
||||
|
@ -647,17 +657,27 @@ const WalletDetails = () => {
|
|||
</View>
|
||||
</BlueCard>
|
||||
{(wallet instanceof AbstractHDElectrumWallet || (wallet.type === WatchOnlyWallet.type && wallet.isHd())) && (
|
||||
<ListItem onPress={navigateToAddresses} title={loc.wallets.details_show_addresses} chevron />
|
||||
<ListItem disabled={isToolTipMenuVisible} onPress={navigateToAddresses} title={loc.wallets.details_show_addresses} chevron />
|
||||
)}
|
||||
{wallet.allowBIP47() && isBIP47Enabled && <ListItem onPress={navigateToPaymentCodes} title="Show payment codes" chevron />}
|
||||
<BlueCard style={styles.address}>
|
||||
<View>
|
||||
<BlueSpacing20 />
|
||||
<Button onPress={navigateToWalletExport} testID="WalletExport" title={loc.wallets.details_export_backup} />
|
||||
<Button
|
||||
disabled={isToolTipMenuVisible}
|
||||
onPress={navigateToWalletExport}
|
||||
testID="WalletExport"
|
||||
title={loc.wallets.details_export_backup}
|
||||
/>
|
||||
{walletTransactionsLength > 0 && (
|
||||
<>
|
||||
<BlueSpacing20 />
|
||||
<SaveFileButton fileName={fileName} fileContent={exportHistoryContent()}>
|
||||
<SaveFileButton
|
||||
onMenuWillHide={onMenuWillHide}
|
||||
onMenuWillShow={onMenuWillShow}
|
||||
fileName={fileName}
|
||||
fileContent={exportHistoryContent()}
|
||||
>
|
||||
<SecondButton title={loc.wallets.details_export_history} />
|
||||
</SaveFileButton>
|
||||
</>
|
||||
|
@ -666,6 +686,7 @@ const WalletDetails = () => {
|
|||
<>
|
||||
<BlueSpacing20 />
|
||||
<SecondButton
|
||||
disabled={isToolTipMenuVisible}
|
||||
onPress={navigateToMultisigCoordinationSetup}
|
||||
testID="MultisigCoordinationSetup"
|
||||
title={loc.multisig.export_coordination_setup.replace(/^\w/, c => c.toUpperCase())}
|
||||
|
@ -677,6 +698,7 @@ const WalletDetails = () => {
|
|||
<>
|
||||
<BlueSpacing20 />
|
||||
<SecondButton
|
||||
disabled={isToolTipMenuVisible}
|
||||
onPress={navigateToViewEditCosigners}
|
||||
testID="ViewEditCosigners"
|
||||
title={loc.multisig.view_edit_cosigners}
|
||||
|
@ -687,25 +709,48 @@ const WalletDetails = () => {
|
|||
{wallet.allowXpub() && (
|
||||
<>
|
||||
<BlueSpacing20 />
|
||||
<SecondButton onPress={navigateToXPub} testID="XPub" title={loc.wallets.details_show_xpub} />
|
||||
<SecondButton
|
||||
disabled={isToolTipMenuVisible}
|
||||
onPress={navigateToXPub}
|
||||
testID="XPub"
|
||||
title={loc.wallets.details_show_xpub}
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
{wallet.allowSignVerifyMessage() && (
|
||||
<>
|
||||
<BlueSpacing20 />
|
||||
<SecondButton onPress={navigateToSignVerify} testID="SignVerify" title={loc.addresses.sign_title} />
|
||||
<SecondButton
|
||||
disabled={isToolTipMenuVisible}
|
||||
onPress={navigateToSignVerify}
|
||||
testID="SignVerify"
|
||||
title={loc.addresses.sign_title}
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
{wallet.type === LightningLdkWallet.type && (
|
||||
<>
|
||||
<BlueSpacing20 />
|
||||
<SecondButton onPress={navigateToLdkViewLogs} testID="LdkLogs" title={loc.lnd.view_logs} />
|
||||
<SecondButton
|
||||
disabled={isToolTipMenuVisible}
|
||||
onPress={navigateToLdkViewLogs}
|
||||
testID="LdkLogs"
|
||||
title={loc.lnd.view_logs}
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
<BlueSpacing20 />
|
||||
<BlueSpacing20 />
|
||||
<TouchableOpacity accessibilityRole="button" onPress={handleDeleteButtonTapped} testID="DeleteButton">
|
||||
<Text textBreakStrategy="simple" style={styles.delete}>{`${loc.wallets.details_delete}${' '}`}</Text>
|
||||
<TouchableOpacity
|
||||
disabled={isToolTipMenuVisible}
|
||||
accessibilityRole="button"
|
||||
onPress={handleDeleteButtonTapped}
|
||||
testID="DeleteButton"
|
||||
>
|
||||
<Text
|
||||
textBreakStrategy="simple"
|
||||
style={[styles.delete, stylesHook.delete]}
|
||||
>{`${loc.wallets.details_delete}${' '}`}</Text>
|
||||
</TouchableOpacity>
|
||||
<BlueSpacing20 />
|
||||
<BlueSpacing20 />
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import React, { useEffect, useRef, useContext, useState } from 'react';
|
||||
import React, { useEffect, useRef, useContext, useState, useLayoutEffect } from 'react';
|
||||
import { StyleSheet, useColorScheme, Platform } from 'react-native';
|
||||
import DraggableFlatList, { ScaleDecorator } from 'react-native-draggable-flatlist';
|
||||
import navigationStyle from '../../components/navigationStyle';
|
||||
|
@ -54,7 +54,7 @@ const ReorderWallets = () => {
|
|||
setWalletData(filteredWallets);
|
||||
}, [wallets, searchQuery]);
|
||||
|
||||
useEffect(() => {
|
||||
useLayoutEffect(() => {
|
||||
// Set navigation options dynamically
|
||||
setOptions({
|
||||
headerSearchBarOptions: {
|
||||
|
|
|
@ -187,7 +187,7 @@ jest.mock('react-native-share', () => {
|
|||
};
|
||||
});
|
||||
|
||||
jest.mock('../blue_modules/WidgetCommunication', () => {
|
||||
jest.mock('../components/WidgetCommunication', () => {
|
||||
return {
|
||||
reloadAllTimelines: jest.fn(),
|
||||
};
|
||||
|
|
Loading…
Add table
Reference in a new issue