mirror of
https://github.com/BlueWallet/BlueWallet.git
synced 2025-02-22 23:08:07 +01:00
REF: Transactions Header JS > TSX
This commit is contained in:
parent
d20b2ad007
commit
30609af527
13 changed files with 395 additions and 345 deletions
|
@ -559,10 +559,10 @@ export const BlueHeaderDefaultMain = props => {
|
|||
>
|
||||
{props.leftText}
|
||||
</Text>
|
||||
<PlusIcon
|
||||
<PlusIcon
|
||||
accessibilityRole="button"
|
||||
accessibilityLabel={loc.wallets.add_title}
|
||||
onPress={props.onNewWalletPress}
|
||||
onPress={props.onNewWalletPress}
|
||||
Component={TouchableOpacity}
|
||||
/>
|
||||
</View>
|
||||
|
|
|
@ -143,6 +143,10 @@ export class AbstractWallet {
|
|||
return BitcoinUnit.BTC;
|
||||
}
|
||||
|
||||
async allowOnchainAddress(): Promise<boolean> {
|
||||
throw new Error('allowOnchainAddress: Not implemented');
|
||||
}
|
||||
|
||||
allowBIP47(): boolean {
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -238,7 +238,12 @@ class AmountInput extends Component {
|
|||
});
|
||||
|
||||
return (
|
||||
<TouchableWithoutFeedback accessibilityRole="button" accessibilityLabel={loc._.enter_amount} disabled={this.props.pointerEvents === 'none'} onPress={() => this.textInput.focus()}>
|
||||
<TouchableWithoutFeedback
|
||||
accessibilityRole="button"
|
||||
accessibilityLabel={loc._.enter_amount}
|
||||
disabled={this.props.pointerEvents === 'none'}
|
||||
onPress={() => this.textInput.focus()}
|
||||
>
|
||||
<>
|
||||
<View style={styles.root}>
|
||||
{!disabled && <View style={[styles.center, stylesHook.center]} />}
|
||||
|
|
|
@ -59,7 +59,13 @@ const ToolTipMenu = (props, ref) => {
|
|||
}}
|
||||
style={buttonStyle}
|
||||
>
|
||||
{props.onPress ? <TouchableOpacity accessibilityRole="button" onPress={props.onPress}>{props.children}</TouchableOpacity> : props.children}
|
||||
{props.onPress ? (
|
||||
<TouchableOpacity accessibilityRole="button" onPress={props.onPress}>
|
||||
{props.children}
|
||||
</TouchableOpacity>
|
||||
) : (
|
||||
props.children
|
||||
)}
|
||||
</ContextMenuButton>
|
||||
) : (
|
||||
<ContextMenuView
|
||||
|
@ -82,7 +88,13 @@ const ToolTipMenu = (props, ref) => {
|
|||
}
|
||||
: {})}
|
||||
>
|
||||
{props.onPress ? <TouchableOpacity accessibilityRole="button" onPress={props.onPress}>{props.children}</TouchableOpacity> : props.children}
|
||||
{props.onPress ? (
|
||||
<TouchableOpacity accessibilityRole="button" onPress={props.onPress}>
|
||||
{props.children}
|
||||
</TouchableOpacity>
|
||||
) : (
|
||||
props.children
|
||||
)}
|
||||
</ContextMenuView>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -1,323 +0,0 @@
|
|||
import React, { Component } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { Image, Text, TouchableOpacity, View, InteractionManager, I18nManager, StyleSheet } from 'react-native';
|
||||
import Clipboard from '@react-native-clipboard/clipboard';
|
||||
import LinearGradient from 'react-native-linear-gradient';
|
||||
import { LightningCustodianWallet, LightningLdkWallet, MultisigHDWallet } from '../class';
|
||||
import { BitcoinUnit } from '../models/bitcoinUnits';
|
||||
import WalletGradient from '../class/wallet-gradient';
|
||||
import Biometric from '../class/biometrics';
|
||||
import loc, { formatBalance } from '../loc';
|
||||
import { BlueStorageContext } from '../blue_modules/storage-context';
|
||||
import ToolTipMenu from './TooltipMenu';
|
||||
import { BluePrivateBalance } from '../BlueComponents';
|
||||
|
||||
export default class TransactionsNavigationHeader extends Component {
|
||||
static propTypes = {
|
||||
wallet: PropTypes.shape().isRequired,
|
||||
onWalletUnitChange: PropTypes.func,
|
||||
navigation: PropTypes.shape({
|
||||
navigate: PropTypes.func,
|
||||
goBack: PropTypes.func,
|
||||
}),
|
||||
onManageFundsPressed: PropTypes.func,
|
||||
};
|
||||
|
||||
static actionKeys = {
|
||||
CopyToClipboard: 'copyToClipboard',
|
||||
WalletBalanceVisibility: 'walletBalanceVisibility',
|
||||
Refill: 'refill',
|
||||
RefillWithExternalWallet: 'qrcode',
|
||||
};
|
||||
|
||||
static actionIcons = {
|
||||
Eye: {
|
||||
iconType: 'SYSTEM',
|
||||
iconValue: 'eye',
|
||||
},
|
||||
EyeSlash: {
|
||||
iconType: 'SYSTEM',
|
||||
iconValue: 'eye.slash',
|
||||
},
|
||||
Clipboard: {
|
||||
iconType: 'SYSTEM',
|
||||
iconValue: 'doc.on.doc',
|
||||
},
|
||||
Refill: {
|
||||
iconType: 'SYSTEM',
|
||||
iconValue: 'goforward.plus',
|
||||
},
|
||||
RefillWithExternalWallet: {
|
||||
iconType: 'SYSTEM',
|
||||
iconValue: 'qrcode',
|
||||
},
|
||||
};
|
||||
|
||||
static getDerivedStateFromProps(props) {
|
||||
return { wallet: props.wallet, onWalletUnitChange: props.onWalletUnitChange };
|
||||
}
|
||||
|
||||
static contextType = BlueStorageContext;
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
wallet: props.wallet,
|
||||
walletPreviousPreferredUnit: props.wallet.getPreferredBalanceUnit(),
|
||||
allowOnchainAddress: false,
|
||||
};
|
||||
}
|
||||
|
||||
menuRef = React.createRef();
|
||||
|
||||
handleCopyPress = _item => {
|
||||
Clipboard.setString(formatBalance(this.state.wallet.getBalance(), this.state.wallet.getPreferredBalanceUnit()).toString());
|
||||
};
|
||||
|
||||
componentDidUpdate(prevState) {
|
||||
InteractionManager.runAfterInteractions(() => {
|
||||
if (prevState.wallet.getID() !== this.state.wallet.getID() && this.state.wallet.type === LightningCustodianWallet.type) {
|
||||
this.verifyIfWalletAllowsOnchainAddress();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
verifyIfWalletAllowsOnchainAddress = () => {
|
||||
if (this.state.wallet.type === LightningCustodianWallet.type) {
|
||||
this.state.wallet
|
||||
.allowOnchainAddress()
|
||||
.then(value => this.setState({ allowOnchainAddress: value }))
|
||||
.catch(e => {
|
||||
console.log('This Lndhub wallet does not have an onchain address API.');
|
||||
this.setState({ allowOnchainAddress: false });
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
componentDidMount() {
|
||||
this.verifyIfWalletAllowsOnchainAddress();
|
||||
}
|
||||
|
||||
handleBalanceVisibility = async _item => {
|
||||
const wallet = this.state.wallet;
|
||||
|
||||
const isBiometricsEnabled = await Biometric.isBiometricUseCapableAndEnabled();
|
||||
|
||||
if (isBiometricsEnabled && wallet.hideBalance) {
|
||||
if (!(await Biometric.unlockWithBiometrics())) {
|
||||
return this.props.navigation.goBack();
|
||||
}
|
||||
}
|
||||
|
||||
wallet.hideBalance = !wallet.hideBalance;
|
||||
this.setState({ wallet });
|
||||
await this.context.saveToDisk();
|
||||
};
|
||||
|
||||
changeWalletBalanceUnit = () => {
|
||||
this.menuRef.current?.dismissMenu();
|
||||
let walletPreviousPreferredUnit = this.state.wallet.getPreferredBalanceUnit();
|
||||
const wallet = this.state.wallet;
|
||||
if (walletPreviousPreferredUnit === BitcoinUnit.BTC) {
|
||||
wallet.preferredBalanceUnit = BitcoinUnit.SATS;
|
||||
walletPreviousPreferredUnit = BitcoinUnit.BTC;
|
||||
} else if (walletPreviousPreferredUnit === BitcoinUnit.SATS) {
|
||||
wallet.preferredBalanceUnit = BitcoinUnit.LOCAL_CURRENCY;
|
||||
walletPreviousPreferredUnit = BitcoinUnit.SATS;
|
||||
} else if (walletPreviousPreferredUnit === BitcoinUnit.LOCAL_CURRENCY) {
|
||||
wallet.preferredBalanceUnit = BitcoinUnit.BTC;
|
||||
walletPreviousPreferredUnit = BitcoinUnit.BTC;
|
||||
} else {
|
||||
wallet.preferredBalanceUnit = BitcoinUnit.BTC;
|
||||
walletPreviousPreferredUnit = BitcoinUnit.BTC;
|
||||
}
|
||||
|
||||
this.setState({ wallet, walletPreviousPreferredUnit }, () => {
|
||||
this.props.onWalletUnitChange(wallet);
|
||||
});
|
||||
};
|
||||
|
||||
manageFundsPressed = id => {
|
||||
this.props.onManageFundsPressed(id);
|
||||
};
|
||||
|
||||
onPressMenuItem = id => {
|
||||
if (id === TransactionsNavigationHeader.actionKeys.WalletBalanceVisibility) {
|
||||
this.handleBalanceVisibility();
|
||||
} else if (id === TransactionsNavigationHeader.actionKeys.CopyToClipboard) {
|
||||
this.handleCopyPress();
|
||||
}
|
||||
};
|
||||
|
||||
toolTipMenuActions = [
|
||||
{
|
||||
id: TransactionsNavigationHeader.actionKeys.Refill,
|
||||
text: loc.lnd.refill,
|
||||
icon: TransactionsNavigationHeader.actionIcons.Refill,
|
||||
},
|
||||
{
|
||||
id: TransactionsNavigationHeader.actionKeys.RefillWithExternalWallet,
|
||||
text: loc.lnd.refill_external,
|
||||
icon: TransactionsNavigationHeader.actionIcons.RefillWithExternalWallet,
|
||||
},
|
||||
];
|
||||
|
||||
render() {
|
||||
const balance =
|
||||
!this.state.wallet.hideBalance &&
|
||||
formatBalance(this.state.wallet.getBalance(), this.state.wallet.getPreferredBalanceUnit(), true).toString();
|
||||
|
||||
return (
|
||||
<LinearGradient
|
||||
colors={WalletGradient.gradientsFor(this.state.wallet.type)}
|
||||
style={styles.lineaderGradient}
|
||||
{...WalletGradient.linearGradientProps(this.state.wallet.type)}
|
||||
>
|
||||
<Image
|
||||
source={(() => {
|
||||
switch (this.state.wallet.type) {
|
||||
case LightningLdkWallet.type:
|
||||
case LightningCustodianWallet.type:
|
||||
return I18nManager.isRTL ? require('../img/lnd-shape-rtl.png') : require('../img/lnd-shape.png');
|
||||
case MultisigHDWallet.type:
|
||||
return I18nManager.isRTL ? require('../img/vault-shape-rtl.png') : require('../img/vault-shape.png');
|
||||
default:
|
||||
return I18nManager.isRTL ? require('../img/btc-shape-rtl.png') : require('../img/btc-shape.png');
|
||||
}
|
||||
})()}
|
||||
style={styles.chainIcon}
|
||||
/>
|
||||
<Text testID="WalletLabel" numberOfLines={1} style={styles.walletLabel}>
|
||||
{this.state.wallet.getLabel()}
|
||||
</Text>
|
||||
<ToolTipMenu
|
||||
onPress={this.changeWalletBalanceUnit}
|
||||
ref={this.menuRef}
|
||||
title={loc.wallets.balance}
|
||||
onPressMenuItem={this.onPressMenuItem}
|
||||
actions={
|
||||
this.state.wallet.hideBalance
|
||||
? [
|
||||
{
|
||||
id: TransactionsNavigationHeader.actionKeys.WalletBalanceVisibility,
|
||||
text: loc.transactions.details_balance_show,
|
||||
icon: TransactionsNavigationHeader.actionIcons.Eye,
|
||||
},
|
||||
]
|
||||
: [
|
||||
{
|
||||
id: TransactionsNavigationHeader.actionKeys.WalletBalanceVisibility,
|
||||
text: loc.transactions.details_balance_hide,
|
||||
icon: TransactionsNavigationHeader.actionIcons.EyeSlash,
|
||||
},
|
||||
{
|
||||
id: TransactionsNavigationHeader.actionKeys.CopyToClipboard,
|
||||
text: loc.transactions.details_copy,
|
||||
icon: TransactionsNavigationHeader.actionIcons.Clipboard,
|
||||
},
|
||||
]
|
||||
}
|
||||
>
|
||||
<View style={styles.balance}>
|
||||
{this.state.wallet.hideBalance ? (
|
||||
<BluePrivateBalance />
|
||||
) : (
|
||||
<Text
|
||||
testID="WalletBalance"
|
||||
key={balance} // force component recreation on balance change. To fix right-to-left languages, like Farsi
|
||||
numberOfLines={1}
|
||||
adjustsFontSizeToFit
|
||||
style={styles.walletBalance}
|
||||
>
|
||||
{balance}
|
||||
</Text>
|
||||
)}
|
||||
</View>
|
||||
</ToolTipMenu>
|
||||
{this.state.wallet.type === LightningCustodianWallet.type && this.state.allowOnchainAddress && (
|
||||
<ToolTipMenu
|
||||
isMenuPrimaryAction
|
||||
isButton
|
||||
onPressMenuItem={this.manageFundsPressed}
|
||||
actions={this.toolTipMenuActions}
|
||||
buttonStyle={styles.manageFundsButton}
|
||||
>
|
||||
<Text style={styles.manageFundsButtonText}>{loc.lnd.title}</Text>
|
||||
</ToolTipMenu>
|
||||
)}
|
||||
{this.state.wallet.allowBIP47() && this.state.wallet.isBIP47Enabled() && (
|
||||
<TouchableOpacity
|
||||
accessibilityRole="button"
|
||||
onPress={() => {
|
||||
this.props.navigation.navigate('PaymentCodeRoot', {
|
||||
screen: 'PaymentCode',
|
||||
params: { paymentCode: this.state.wallet.getBIP47PaymentCode() },
|
||||
});
|
||||
}}
|
||||
>
|
||||
<View style={styles.manageFundsButton}>
|
||||
<Text style={styles.manageFundsButtonText}>{loc.bip47.payment_code}</Text>
|
||||
</View>
|
||||
</TouchableOpacity>
|
||||
)}
|
||||
{this.state.wallet.type === LightningLdkWallet.type && (
|
||||
<TouchableOpacity accessibilityRole="button" accessibilityLabel={loc.lnd.title} onPress={this.manageFundsPressed}>
|
||||
<View style={styles.manageFundsButton}>
|
||||
<Text style={styles.manageFundsButtonText}>{loc.lnd.title}</Text>
|
||||
</View>
|
||||
</TouchableOpacity>
|
||||
)}
|
||||
{this.state.wallet.type === MultisigHDWallet.type && (
|
||||
<TouchableOpacity accessibilityRole="button" onPress={this.manageFundsPressed}>
|
||||
<View style={styles.manageFundsButton}>
|
||||
<Text style={styles.manageFundsButtonText}>{loc.multisig.manage_keys}</Text>
|
||||
</View>
|
||||
</TouchableOpacity>
|
||||
)}
|
||||
</LinearGradient>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
lineaderGradient: {
|
||||
padding: 15,
|
||||
minHeight: 140,
|
||||
justifyContent: 'center',
|
||||
},
|
||||
chainIcon: {
|
||||
width: 99,
|
||||
height: 94,
|
||||
position: 'absolute',
|
||||
bottom: 0,
|
||||
right: 0,
|
||||
},
|
||||
walletLabel: {
|
||||
backgroundColor: 'transparent',
|
||||
fontSize: 19,
|
||||
color: '#fff',
|
||||
writingDirection: I18nManager.isRTL ? 'rtl' : 'ltr',
|
||||
},
|
||||
walletBalance: {
|
||||
backgroundColor: 'transparent',
|
||||
fontWeight: 'bold',
|
||||
fontSize: 36,
|
||||
color: '#fff',
|
||||
writingDirection: I18nManager.isRTL ? 'rtl' : 'ltr',
|
||||
},
|
||||
manageFundsButton: {
|
||||
marginTop: 14,
|
||||
marginBottom: 10,
|
||||
backgroundColor: 'rgba(255,255,255,0.2)',
|
||||
borderRadius: 9,
|
||||
minHeight: 39,
|
||||
alignSelf: 'flex-start',
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
},
|
||||
manageFundsButtonText: {
|
||||
fontWeight: '500',
|
||||
fontSize: 14,
|
||||
color: '#FFFFFF',
|
||||
padding: 12,
|
||||
},
|
||||
});
|
315
components/TransactionsNavigationHeader.tsx
Normal file
315
components/TransactionsNavigationHeader.tsx
Normal file
|
@ -0,0 +1,315 @@
|
|||
import React, { useState, useEffect, useRef, useContext, useCallback, useMemo } from 'react';
|
||||
import { Image, Text, TouchableOpacity, View, I18nManager, StyleSheet } from 'react-native';
|
||||
import Clipboard from '@react-native-clipboard/clipboard';
|
||||
import LinearGradient from 'react-native-linear-gradient';
|
||||
import { AbstractWallet, LightningCustodianWallet, LightningLdkWallet, MultisigHDWallet } from '../class';
|
||||
import { BitcoinUnit } from '../models/bitcoinUnits';
|
||||
import WalletGradient from '../class/wallet-gradient';
|
||||
import Biometric from '../class/biometrics';
|
||||
import loc, { formatBalance } from '../loc';
|
||||
import { BlueStorageContext } from '../blue_modules/storage-context';
|
||||
import ToolTipMenu from './TooltipMenu';
|
||||
import { BluePrivateBalance } from '../BlueComponents';
|
||||
|
||||
interface TransactionsNavigationHeaderProps {
|
||||
wallet: AbstractWallet;
|
||||
onWalletUnitChange?: (wallet: any) => void;
|
||||
navigation: {
|
||||
navigate: (route: string, params?: any) => void;
|
||||
goBack: () => void;
|
||||
};
|
||||
onHandleManageFundsPressed?: (id: string) => void; // Add a type definition for this prop
|
||||
actionKeys: {
|
||||
CopyToClipboard: 'copyToClipboard';
|
||||
WalletBalanceVisibility: 'walletBalanceVisibility';
|
||||
Refill: 'refill';
|
||||
RefillWithExternalWallet: 'qrcode';
|
||||
};
|
||||
}
|
||||
|
||||
const TransactionsNavigationHeader: React.FC<TransactionsNavigationHeaderProps> = ({
|
||||
// @ts-ignore: Ugh
|
||||
wallet: initialWallet,
|
||||
// @ts-ignore: Ugh
|
||||
onWalletUnitChange,
|
||||
// @ts-ignore: Ugh
|
||||
navigation,
|
||||
// @ts-ignore: Ugh
|
||||
onHandleManageFundsPressed,
|
||||
}) => {
|
||||
const [wallet, setWallet] = useState(initialWallet);
|
||||
const [allowOnchainAddress, setAllowOnchainAddress] = useState(false);
|
||||
|
||||
const context = useContext(BlueStorageContext);
|
||||
const menuRef = useRef(null);
|
||||
|
||||
const verifyIfWalletAllowsOnchainAddress = useCallback(() => {
|
||||
if (wallet.type === LightningCustodianWallet.type) {
|
||||
wallet
|
||||
.allowOnchainAddress()
|
||||
.then((value: boolean) => setAllowOnchainAddress(value))
|
||||
.catch((e: any) => {
|
||||
console.log('This Lndhub wallet does not have an onchain address API.');
|
||||
setAllowOnchainAddress(false);
|
||||
});
|
||||
}
|
||||
}, [wallet]);
|
||||
|
||||
useEffect(() => {
|
||||
verifyIfWalletAllowsOnchainAddress();
|
||||
}, [wallet, verifyIfWalletAllowsOnchainAddress]);
|
||||
|
||||
const handleCopyPress = () => {
|
||||
Clipboard.setString(formatBalance(wallet.getBalance(), wallet.getPreferredBalanceUnit()).toString());
|
||||
};
|
||||
|
||||
const updateWalletVisibility = (wallet: AbstractWallet, newHideBalance: boolean) => {
|
||||
const clonedWallet = Object.assign(Object.create(Object.getPrototypeOf(wallet)), wallet);
|
||||
clonedWallet.hideBalance = newHideBalance;
|
||||
return clonedWallet;
|
||||
};
|
||||
|
||||
const handleBalanceVisibility = async () => {
|
||||
// @ts-ignore: Gotta update this class
|
||||
const isBiometricsEnabled = await Biometric.isBiometricUseCapableAndEnabled();
|
||||
|
||||
if (isBiometricsEnabled && wallet.hideBalance) {
|
||||
// @ts-ignore: Ugh
|
||||
if (!(await Biometric.unlockWithBiometrics())) {
|
||||
return navigation.goBack();
|
||||
}
|
||||
}
|
||||
|
||||
const updatedWallet = updateWalletVisibility(wallet, !wallet.hideBalance);
|
||||
setWallet(updatedWallet);
|
||||
await context.saveToDisk();
|
||||
};
|
||||
|
||||
const updateWalletWithNewUnit = (wallet: AbstractWallet, newPreferredUnit: BitcoinUnit) => {
|
||||
const clonedWallet = Object.assign(Object.create(Object.getPrototypeOf(wallet)), wallet);
|
||||
clonedWallet.preferredBalanceUnit = newPreferredUnit;
|
||||
return clonedWallet;
|
||||
};
|
||||
|
||||
const changeWalletBalanceUnit = () => {
|
||||
// @ts-ignore: Ugh
|
||||
menuRef.current?.dismissMenu();
|
||||
let newWalletPreferredUnit = wallet.getPreferredBalanceUnit();
|
||||
|
||||
if (newWalletPreferredUnit === BitcoinUnit.BTC) {
|
||||
newWalletPreferredUnit = BitcoinUnit.SATS;
|
||||
} else if (newWalletPreferredUnit === BitcoinUnit.SATS) {
|
||||
newWalletPreferredUnit = BitcoinUnit.LOCAL_CURRENCY;
|
||||
} else if (newWalletPreferredUnit === BitcoinUnit.LOCAL_CURRENCY) {
|
||||
newWalletPreferredUnit = BitcoinUnit.BTC;
|
||||
} else {
|
||||
newWalletPreferredUnit = BitcoinUnit.BTC;
|
||||
}
|
||||
|
||||
const updatedWallet = updateWalletWithNewUnit(wallet, newWalletPreferredUnit);
|
||||
setWallet(updatedWallet);
|
||||
onWalletUnitChange?.(updatedWallet);
|
||||
};
|
||||
|
||||
const handleManageFundsPressed = () => {
|
||||
onHandleManageFundsPressed?.(actionKeys.Refill);
|
||||
};
|
||||
|
||||
const onPressMenuItem = (id: string) => {
|
||||
if (id === 'walletBalanceVisibility') {
|
||||
handleBalanceVisibility();
|
||||
} else if (id === 'copyToClipboard') {
|
||||
handleCopyPress();
|
||||
}
|
||||
};
|
||||
|
||||
const balance = useMemo(() => {
|
||||
return !wallet.hideBalance && formatBalance(wallet.getBalance(), wallet.getPreferredBalanceUnit(), true).toString();
|
||||
}, [wallet]);
|
||||
|
||||
return (
|
||||
<LinearGradient
|
||||
colors={WalletGradient.gradientsFor(wallet.type)}
|
||||
style={styles.lineaderGradient}
|
||||
// @ts-ignore: Ugh
|
||||
{...WalletGradient.linearGradientProps(wallet.type)}
|
||||
>
|
||||
<Image
|
||||
source={(() => {
|
||||
switch (wallet.type) {
|
||||
case LightningLdkWallet.type:
|
||||
case LightningCustodianWallet.type:
|
||||
return I18nManager.isRTL ? require('../img/lnd-shape-rtl.png') : require('../img/lnd-shape.png');
|
||||
case MultisigHDWallet.type:
|
||||
return I18nManager.isRTL ? require('../img/vault-shape-rtl.png') : require('../img/vault-shape.png');
|
||||
default:
|
||||
return I18nManager.isRTL ? require('../img/btc-shape-rtl.png') : require('../img/btc-shape.png');
|
||||
}
|
||||
})()}
|
||||
style={styles.chainIcon}
|
||||
/>
|
||||
<Text testID="WalletLabel" numberOfLines={1} style={styles.walletLabel}>
|
||||
{wallet.getLabel()}
|
||||
</Text>
|
||||
<ToolTipMenu
|
||||
onPress={changeWalletBalanceUnit}
|
||||
ref={menuRef}
|
||||
title={loc.wallets.balance}
|
||||
onPressMenuItem={onPressMenuItem}
|
||||
actions={
|
||||
wallet.hideBalance
|
||||
? [
|
||||
{
|
||||
id: 'walletBalanceVisibility',
|
||||
text: loc.transactions.details_balance_show,
|
||||
icon: {
|
||||
iconType: 'SYSTEM',
|
||||
iconValue: 'eye',
|
||||
},
|
||||
},
|
||||
]
|
||||
: [
|
||||
{
|
||||
id: 'walletBalanceVisibility',
|
||||
text: loc.transactions.details_balance_hide,
|
||||
icon: {
|
||||
iconType: 'SYSTEM',
|
||||
iconValue: 'eye.slash',
|
||||
},
|
||||
},
|
||||
{
|
||||
id: 'copyToClipboard',
|
||||
text: loc.transactions.details_copy,
|
||||
icon: {
|
||||
iconType: 'SYSTEM',
|
||||
iconValue: 'doc.on.doc',
|
||||
},
|
||||
},
|
||||
]
|
||||
}
|
||||
>
|
||||
<View style={styles.walletBalance}>
|
||||
{wallet.hideBalance ? (
|
||||
<BluePrivateBalance />
|
||||
) : (
|
||||
<Text
|
||||
testID="WalletBalance"
|
||||
key={balance} // force component recreation on balance change. To fix right-to-left languages, like Farsi
|
||||
numberOfLines={1}
|
||||
adjustsFontSizeToFit
|
||||
style={styles.walletBalance}
|
||||
>
|
||||
{balance}
|
||||
</Text>
|
||||
)}
|
||||
</View>
|
||||
</ToolTipMenu>
|
||||
{wallet.type === LightningCustodianWallet.type && allowOnchainAddress && (
|
||||
<ToolTipMenu
|
||||
isMenuPrimaryAction
|
||||
isButton
|
||||
onPressMenuItem={handleManageFundsPressed}
|
||||
actions={[
|
||||
{
|
||||
id: actionKeys.Refill,
|
||||
text: loc.lnd.refill,
|
||||
icon: actionIcons.Refill,
|
||||
},
|
||||
{
|
||||
id: actionKeys.RefillWithExternalWallet,
|
||||
text: loc.lnd.refill_external,
|
||||
icon: actionIcons.RefillWithExternalWallet,
|
||||
},
|
||||
]}
|
||||
buttonStyle={styles.manageFundsButton}
|
||||
>
|
||||
<Text style={styles.manageFundsButtonText}>{loc.lnd.title}</Text>
|
||||
</ToolTipMenu>
|
||||
)}
|
||||
|
||||
{wallet.type === MultisigHDWallet.type && (
|
||||
<TouchableOpacity accessibilityRole="button" onPress={handleManageFundsPressed}>
|
||||
<View style={styles.manageFundsButton}>
|
||||
<Text style={styles.manageFundsButtonText}>{loc.multisig.manage_keys}</Text>
|
||||
</View>
|
||||
</TouchableOpacity>
|
||||
)}
|
||||
</LinearGradient>
|
||||
);
|
||||
};
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
lineaderGradient: {
|
||||
padding: 15,
|
||||
minHeight: 140,
|
||||
justifyContent: 'center',
|
||||
},
|
||||
chainIcon: {
|
||||
width: 99,
|
||||
height: 94,
|
||||
position: 'absolute',
|
||||
bottom: 0,
|
||||
right: 0,
|
||||
},
|
||||
walletLabel: {
|
||||
backgroundColor: 'transparent',
|
||||
fontSize: 19,
|
||||
color: '#fff',
|
||||
writingDirection: I18nManager.isRTL ? 'rtl' : 'ltr',
|
||||
},
|
||||
walletBalance: {
|
||||
backgroundColor: 'transparent',
|
||||
fontWeight: 'bold',
|
||||
fontSize: 36,
|
||||
color: '#fff',
|
||||
writingDirection: I18nManager.isRTL ? 'rtl' : 'ltr',
|
||||
},
|
||||
manageFundsButton: {
|
||||
marginTop: 14,
|
||||
marginBottom: 10,
|
||||
backgroundColor: 'rgba(255,255,255,0.2)',
|
||||
borderRadius: 9,
|
||||
minHeight: 39,
|
||||
alignSelf: 'flex-start',
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
},
|
||||
manageFundsButtonText: {
|
||||
fontWeight: '500',
|
||||
fontSize: 14,
|
||||
color: '#FFFFFF',
|
||||
padding: 12,
|
||||
},
|
||||
});
|
||||
|
||||
export const actionKeys = {
|
||||
CopyToClipboard: 'copyToClipboard',
|
||||
WalletBalanceVisibility: 'walletBalanceVisibility',
|
||||
Refill: 'refill',
|
||||
RefillWithExternalWallet: 'qrcode',
|
||||
};
|
||||
|
||||
export const actionIcons = {
|
||||
Eye: {
|
||||
iconType: 'SYSTEM',
|
||||
iconValue: 'eye',
|
||||
},
|
||||
EyeSlash: {
|
||||
iconType: 'SYSTEM',
|
||||
iconValue: 'eye.slash',
|
||||
},
|
||||
Clipboard: {
|
||||
iconType: 'SYSTEM',
|
||||
iconValue: 'doc.on.doc',
|
||||
},
|
||||
Refill: {
|
||||
iconType: 'SYSTEM',
|
||||
iconValue: 'goforward.plus',
|
||||
},
|
||||
RefillWithExternalWallet: {
|
||||
iconType: 'SYSTEM',
|
||||
iconValue: 'qrcode',
|
||||
},
|
||||
};
|
||||
|
||||
export default TransactionsNavigationHeader;
|
|
@ -42,6 +42,7 @@ const navigationStyle = (
|
|||
...opts
|
||||
}: NavigationOptions & {
|
||||
closeButton?: boolean;
|
||||
|
||||
closeButtonFunc?: (deps: { navigation: any; route: any }) => React.ReactElement;
|
||||
},
|
||||
formatter: OptionsFormatter,
|
||||
|
@ -57,7 +58,12 @@ const navigationStyle = (
|
|||
navigation.goBack(null);
|
||||
};
|
||||
headerRight = () => (
|
||||
<TouchableOpacity accessibilityRole="button" accessibilityLabel={loc._.close} style={styles.button} onPress={handleClose} testID="NavigationCloseButton"
|
||||
<TouchableOpacity
|
||||
accessibilityRole="button"
|
||||
accessibilityLabel={loc._.close}
|
||||
style={styles.button}
|
||||
onPress={handleClose}
|
||||
testID="NavigationCloseButton"
|
||||
>
|
||||
<Image source={theme.closeImage} />
|
||||
</TouchableOpacity>
|
||||
|
@ -108,7 +114,10 @@ export const navigationStyleTx = (opts: NavigationOptions, formatter: OptionsFor
|
|||
headerBackTitleVisible: false,
|
||||
headerTintColor: theme.colors.foregroundColor,
|
||||
headerLeft: () => (
|
||||
<TouchableOpacity accessibilityRole="button" accessibilityLabel={loc._.close} style={styles.button}
|
||||
<TouchableOpacity
|
||||
accessibilityRole="button"
|
||||
accessibilityLabel={loc._.close}
|
||||
style={styles.button}
|
||||
onPress={() => {
|
||||
Keyboard.dismiss();
|
||||
navigation.goBack(null);
|
||||
|
|
|
@ -919,7 +919,7 @@
|
|||
);
|
||||
mainGroup = 83CBB9F61A601CBA00E9B192;
|
||||
packageReferences = (
|
||||
6DFC806E24EA0B6C007B8700 /* XCRemoteSwiftPackageReference "EFQRCode" */,
|
||||
6DFC806E24EA0B6C007B8700 /* XCRemoteSwiftPackageReference "EFQRCode.git" */,
|
||||
);
|
||||
productRefGroup = 83CBBA001A601CBA00E9B192 /* Products */;
|
||||
projectDirPath = "";
|
||||
|
@ -1981,7 +1981,7 @@
|
|||
/* End XCConfigurationList section */
|
||||
|
||||
/* Begin XCRemoteSwiftPackageReference section */
|
||||
6DFC806E24EA0B6C007B8700 /* XCRemoteSwiftPackageReference "EFQRCode" */ = {
|
||||
6DFC806E24EA0B6C007B8700 /* XCRemoteSwiftPackageReference "EFQRCode.git" */ = {
|
||||
isa = XCRemoteSwiftPackageReference;
|
||||
repositoryURL = "https://github.com/EFPrefix/EFQRCode.git";
|
||||
requirement = {
|
||||
|
@ -1994,7 +1994,7 @@
|
|||
/* Begin XCSwiftPackageProductDependency section */
|
||||
6DFC806F24EA0B6C007B8700 /* EFQRCode */ = {
|
||||
isa = XCSwiftPackageProductDependency;
|
||||
package = 6DFC806E24EA0B6C007B8700 /* XCRemoteSwiftPackageReference "EFQRCode" */;
|
||||
package = 6DFC806E24EA0B6C007B8700 /* XCRemoteSwiftPackageReference "EFQRCode.git" */;
|
||||
productName = EFQRCode;
|
||||
};
|
||||
/* End XCSwiftPackageProductDependency section */
|
||||
|
|
|
@ -396,7 +396,7 @@ PODS:
|
|||
- React
|
||||
- rn-ldk (0.8.4):
|
||||
- React-Core
|
||||
- RNCAsyncStorage (1.18.0):
|
||||
- RNCAsyncStorage (1.18.1):
|
||||
- React-Core
|
||||
- RNCClipboard (1.11.2):
|
||||
- React-Core
|
||||
|
@ -456,7 +456,7 @@ PODS:
|
|||
- React-RCTImage
|
||||
- RNShare (8.2.1):
|
||||
- React-Core
|
||||
- RNSVG (13.8.0):
|
||||
- RNSVG (13.9.0):
|
||||
- React-Core
|
||||
- RNVectorIcons (9.2.0):
|
||||
- React-Core
|
||||
|
@ -764,7 +764,7 @@ SPEC CHECKSUMS:
|
|||
ReactNativeCameraKit: 9d46a5d7dd544ca64aa9c03c150d2348faf437eb
|
||||
RealmJS: 10958b8a9d1f3a981c1b50bdc1da8396002e75a4
|
||||
rn-ldk: 0d8749d98cc5ce67302a32831818c116b67f7643
|
||||
RNCAsyncStorage: a46ee6bf15cf1ba863d0a47287236f9c95d5b213
|
||||
RNCAsyncStorage: b90b71f45b8b97be43bc4284e71a6af48ac9f547
|
||||
RNCClipboard: 3f0451a8100393908bea5c5c5b16f96d45f30bfc
|
||||
RNCPushNotificationIOS: 87b8d16d3ede4532745e05b03c42cff33a36cc45
|
||||
RNDefaultPreference: 08bdb06cfa9188d5da97d4642dac745218d7fb31
|
||||
|
@ -781,7 +781,7 @@ SPEC CHECKSUMS:
|
|||
RNReanimated: cc5e3aa479cb9170bcccf8204291a6950a3be128
|
||||
RNScreens: 218801c16a2782546d30bd2026bb625c0302d70f
|
||||
RNShare: eaee3dd5a06dad397c7d3b14762007035c5de405
|
||||
RNSVG: c1e76b81c76cdcd34b4e1188852892dc280eb902
|
||||
RNSVG: 53c661b76829783cdaf9b7a57258f3d3b4c28315
|
||||
RNVectorIcons: fcc2f6cb32f5735b586e66d14103a74ce6ad61f8
|
||||
RNWatch: fd30ca40a5b5ef58dcbc195638e68219bc455236
|
||||
Yoga: cd7d7f509dbfac14ee7f31a6c750acb957cd5022
|
||||
|
|
|
@ -347,11 +347,21 @@ const ScanQRCode = () => {
|
|||
<TouchableOpacity accessibilityRole="button" accessibilityLabel={loc._.close} style={styles.closeTouch} onPress={dismiss}>
|
||||
<Image style={styles.closeImage} source={require('../../img/close-white.png')} />
|
||||
</TouchableOpacity>
|
||||
<TouchableOpacity accessibilityRole="button" accessibilityLabel={loc._.pick_image} style={styles.imagePickerTouch} onPress={showImagePicker}>
|
||||
<TouchableOpacity
|
||||
accessibilityRole="button"
|
||||
accessibilityLabel={loc._.pick_image}
|
||||
style={styles.imagePickerTouch}
|
||||
onPress={showImagePicker}
|
||||
>
|
||||
<Icon name="image" type="font-awesome" color="#ffffff" />
|
||||
</TouchableOpacity>
|
||||
{showFileImportButton && (
|
||||
<TouchableOpacity accessibilityRole="button" accessibilityLabel={loc._.pick_file} style={styles.filePickerTouch} onPress={showFilePicker}>
|
||||
<TouchableOpacity
|
||||
accessibilityRole="button"
|
||||
accessibilityLabel={loc._.pick_file}
|
||||
style={styles.filePickerTouch}
|
||||
onPress={showFilePicker}
|
||||
>
|
||||
<Icon name="file-import" type="font-awesome-5" color="#ffffff" />
|
||||
</TouchableOpacity>
|
||||
)}
|
||||
|
|
|
@ -39,7 +39,12 @@ const LdkViewLogs = () => {
|
|||
.finally(() => {
|
||||
setOptions({
|
||||
headerRight: () => (
|
||||
<TouchableOpacity accessibilityRole="button" accessibilityLabel={loc.wallets.list_tryagain} style={styles.reloadLogs} onPress={getLogs}>
|
||||
<TouchableOpacity
|
||||
accessibilityRole="button"
|
||||
accessibilityLabel={loc.wallets.list_tryagain}
|
||||
style={styles.reloadLogs}
|
||||
onPress={getLogs}
|
||||
>
|
||||
<Icon name="redo" type="font-awesome-5" size={22} color={colors.foregroundColor} />
|
||||
</TouchableOpacity>
|
||||
),
|
||||
|
|
|
@ -103,13 +103,25 @@ const WalletsList = () => {
|
|||
},
|
||||
headerRight: () =>
|
||||
I18nManager.isRTL ? null : (
|
||||
<TouchableOpacity accessibilityRole="button" accessibilityLabel={loc._.more} testID="SettingsButton" style={styles.headerTouch} onPress={navigateToSettings}>
|
||||
<TouchableOpacity
|
||||
accessibilityRole="button"
|
||||
accessibilityLabel={loc._.more}
|
||||
testID="SettingsButton"
|
||||
style={styles.headerTouch}
|
||||
onPress={navigateToSettings}
|
||||
>
|
||||
<Icon size={22} name="more-horiz" type="material" color={colors.foregroundColor} />
|
||||
</TouchableOpacity>
|
||||
),
|
||||
headerLeft: () =>
|
||||
I18nManager.isRTL ? (
|
||||
<TouchableOpacity accessibilityRole="button" accessibilityLabel={loc._.more} testID="SettingsButton" style={styles.headerTouch} onPress={navigateToSettings}>
|
||||
<TouchableOpacity
|
||||
accessibilityRole="button"
|
||||
accessibilityLabel={loc._.more}
|
||||
testID="SettingsButton"
|
||||
style={styles.headerTouch}
|
||||
onPress={navigateToSettings}
|
||||
>
|
||||
<Icon size={22} name="more-horiz" type="material" color={colors.foregroundColor} />
|
||||
</TouchableOpacity>
|
||||
) : null,
|
||||
|
|
|
@ -30,7 +30,7 @@ import { BlueStorageContext } from '../../blue_modules/storage-context';
|
|||
import { isDesktop } from '../../blue_modules/environment';
|
||||
import BlueClipboard from '../../blue_modules/clipboard';
|
||||
import LNNodeBar from '../../components/LNNodeBar';
|
||||
import TransactionsNavigationHeader from '../../components/TransactionsNavigationHeader';
|
||||
import TransactionsNavigationHeader, { actionKeys } from '../../components/TransactionsNavigationHeader';
|
||||
import { TransactionListItem } from '../../components/TransactionListItem';
|
||||
import alert from '../../components/Alert';
|
||||
import PropTypes from 'prop-types';
|
||||
|
@ -450,14 +450,14 @@ const WalletTransactions = ({ navigation }) => {
|
|||
};
|
||||
|
||||
const onManageFundsPressed = ({ id }) => {
|
||||
if (id === TransactionsNavigationHeader.actionKeys.Refill) {
|
||||
if (id === actionKeys.Refill) {
|
||||
const availableWallets = [...wallets.filter(item => item.chain === Chain.ONCHAIN && item.allowSend())];
|
||||
if (availableWallets.length === 0) {
|
||||
alert(loc.lnd.refill_create);
|
||||
} else {
|
||||
navigate('SelectWallet', { onWalletSelect, chainType: Chain.ONCHAIN });
|
||||
}
|
||||
} else if (id === TransactionsNavigationHeader.actionKeys.RefillWithExternalWallet) {
|
||||
} else if (id === actionKeys.RefillWithExternalWallet) {
|
||||
if (wallet.getUserHasSavedExport()) {
|
||||
navigate('ReceiveDetailsRoot', {
|
||||
screen: 'ReceiveDetails',
|
||||
|
@ -512,6 +512,7 @@ const WalletTransactions = ({ navigation }) => {
|
|||
<FlatList
|
||||
ListHeaderComponent={renderListHeaderComponent}
|
||||
onEndReachedThreshold={0.3}
|
||||
stickyHeaderHiddenOnScroll
|
||||
onEndReached={async () => {
|
||||
// pagination in works. in this block we will add more txs to FlatList
|
||||
// so as user scrolls closer to bottom it will render mode transactions
|
||||
|
|
Loading…
Add table
Reference in a new issue