Merge pull request #7117 from BlueWallet/headm

REF: HeaderMenuButton
This commit is contained in:
GLaDOS 2024-10-01 13:12:12 +00:00 committed by GitHub
commit 1050619fb4
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
8 changed files with 61 additions and 67 deletions

View File

@ -0,0 +1,31 @@
import React from 'react';
import ToolTipMenu from './TooltipMenu';
import { useTheme } from './themes';
import { Icon } from '@rneui/themed';
import { Platform } from 'react-native';
import { Action } from './types';
interface HeaderMenuButtonProps {
onPressMenuItem: (id: string) => void;
actions: Action[];
disabled?: boolean;
}
const HeaderMenuButton: React.FC<HeaderMenuButtonProps> = ({ onPressMenuItem, actions, disabled }) => {
const { colors } = useTheme();
const styleProps = Platform.OS === 'android' ? { iconStyle: { transform: [{ rotate: '90deg' }] } } : {};
return (
<ToolTipMenu
testID="HeaderMenuButton"
disabled={disabled}
isButton
isMenuPrimaryAction
onPressMenuItem={onPressMenuItem}
actions={actions}
>
<Icon size={22} name="more-horiz" type="material" color={colors.foregroundColor} {...styleProps} />
</ToolTipMenu>
);
};
export default HeaderMenuButton;

View File

@ -35,9 +35,8 @@ import { SuccessView } from '../send/success';
import { useStorage } from '../../hooks/context/useStorage'; import { useStorage } from '../../hooks/context/useStorage';
import { HandOffActivityType } from '../../components/types'; import { HandOffActivityType } from '../../components/types';
import SegmentedControl from '../../components/SegmentControl'; import SegmentedControl from '../../components/SegmentControl';
import ToolTipMenu from '../../components/TooltipMenu';
import { Icon } from '@rneui/themed';
import { CommonToolTipActions } from '../../typings/CommonToolTipActions'; import { CommonToolTipActions } from '../../typings/CommonToolTipActions';
import HeaderMenuButton from '../../components/HeaderMenuButton';
const segmentControlValues = [loc.wallets.details_address, loc.bip47.payment_code]; const segmentControlValues = [loc.wallets.details_address, loc.bip47.payment_code];
@ -167,12 +166,9 @@ const ReceiveDetails = () => {
}, [onEnablePaymentsCodeSwitchValue]); }, [onEnablePaymentsCodeSwitchValue]);
const HeaderRight = useMemo( const HeaderRight = useMemo(
() => ( () => <HeaderMenuButton actions={toolTipActions} onPressMenuItem={onPressMenuItem} />,
<ToolTipMenu isButton isMenuPrimaryAction onPressMenuItem={onPressMenuItem} actions={[toolTipActions]}>
<Icon size={22} name="more-horiz" type="material" color={colors.foregroundColor} /> [onPressMenuItem, toolTipActions],
</ToolTipMenu>
),
[colors.foregroundColor, onPressMenuItem, toolTipActions],
); );
const handleClose = useCallback(() => { const handleClose = useCallback(() => {

View File

@ -24,7 +24,6 @@ import {
import DocumentPicker from 'react-native-document-picker'; import DocumentPicker from 'react-native-document-picker';
import { Icon } from '@rneui/themed'; import { Icon } from '@rneui/themed';
import RNFS from 'react-native-fs'; import RNFS from 'react-native-fs';
import { btcToSatoshi, fiatToBTC } from '../../blue_modules/currency'; import { btcToSatoshi, fiatToBTC } from '../../blue_modules/currency';
import * as fs from '../../blue_modules/fs'; import * as fs from '../../blue_modules/fs';
import triggerHapticFeedback, { HapticFeedbackTypes } from '../../blue_modules/hapticFeedback'; import triggerHapticFeedback, { HapticFeedbackTypes } from '../../blue_modules/hapticFeedback';
@ -40,7 +39,6 @@ import Button from '../../components/Button';
import CoinsSelected from '../../components/CoinsSelected'; import CoinsSelected from '../../components/CoinsSelected';
import InputAccessoryAllFunds, { InputAccessoryAllFundsAccessoryViewID } from '../../components/InputAccessoryAllFunds'; import InputAccessoryAllFunds, { InputAccessoryAllFundsAccessoryViewID } from '../../components/InputAccessoryAllFunds';
import { useTheme } from '../../components/themes'; import { useTheme } from '../../components/themes';
import ToolTipMenu from '../../components/TooltipMenu';
import { requestCameraAuthorization, scanQrHelper } from '../../helpers/scan-qr'; import { requestCameraAuthorization, scanQrHelper } from '../../helpers/scan-qr';
import loc, { formatBalance, formatBalanceWithoutSuffix } from '../../loc'; import loc, { formatBalance, formatBalanceWithoutSuffix } from '../../loc';
import { BitcoinUnit, Chain } from '../../models/bitcoinUnits'; import { BitcoinUnit, Chain } from '../../models/bitcoinUnits';
@ -58,6 +56,7 @@ import SelectFeeModal from '../../components/SelectFeeModal';
import { useKeyboard } from '../../hooks/useKeyboard'; import { useKeyboard } from '../../hooks/useKeyboard';
import { DismissKeyboardInputAccessory, DismissKeyboardInputAccessoryViewID } from '../../components/DismissKeyboardInputAccessory'; import { DismissKeyboardInputAccessory, DismissKeyboardInputAccessoryViewID } from '../../components/DismissKeyboardInputAccessory';
import ActionSheet from '../ActionSheet'; import ActionSheet from '../ActionSheet';
import HeaderMenuButton from '../../components/HeaderMenuButton';
interface IPaymentDestinations { interface IPaymentDestinations {
address: string; // btc address or payment code address: string; // btc address or payment code
@ -1055,18 +1054,7 @@ const SendDetails = () => {
const setHeaderRightOptions = () => { const setHeaderRightOptions = () => {
navigation.setOptions({ navigation.setOptions({
// eslint-disable-next-line react/no-unstable-nested-components // eslint-disable-next-line react/no-unstable-nested-components
headerRight: () => ( headerRight: () => <HeaderMenuButton disabled={isLoading} onPressMenuItem={headerRightOnPress} actions={headerRightActions()} />,
<ToolTipMenu
disabled={isLoading}
isButton
isMenuPrimaryAction
onPressMenuItem={headerRightOnPress}
actions={headerRightActions()}
testID="advancedOptionsMenuButton"
>
<Icon size={22} name="more-horiz" type="material" color={colors.foregroundColor} style={styles.advancedOptions} />
</ToolTipMenu>
),
}); });
}; };
@ -1499,11 +1487,6 @@ const styles = StyleSheet.create({
alignItems: 'center', alignItems: 'center',
paddingHorizontal: 10, paddingHorizontal: 10,
}, },
advancedOptions: {
minWidth: 40,
height: 40,
justifyContent: 'center',
},
frozenContainer: { frozenContainer: {
flexDirection: 'row', flexDirection: 'row',
justifyContent: 'center', justifyContent: 'center',

View File

@ -25,11 +25,10 @@ import WalletButton from '../../components/WalletButton';
import loc from '../../loc'; import loc from '../../loc';
import { Chain } from '../../models/bitcoinUnits'; import { Chain } from '../../models/bitcoinUnits';
import { useStorage } from '../../hooks/context/useStorage'; import { useStorage } from '../../hooks/context/useStorage';
import ToolTipMenu from '../../components/TooltipMenu';
import { Icon } from '@rneui/themed';
import { CommonToolTipActions } from '../../typings/CommonToolTipActions'; import { CommonToolTipActions } from '../../typings/CommonToolTipActions';
import { Action } from '../../components/types'; import { Action } from '../../components/types';
import { getLNDHub } from '../../helpers/lndHub'; import { getLNDHub } from '../../helpers/lndHub';
import HeaderMenuButton from '../../components/HeaderMenuButton';
enum ButtonSelected { enum ButtonSelected {
// @ts-ignore: Return later to update // @ts-ignore: Return later to update
@ -228,9 +227,7 @@ const WalletsAdd: React.FC = () => {
const HeaderRight = useMemo( const HeaderRight = useMemo(
() => ( () => (
<ToolTipMenu <HeaderMenuButton
isButton
isMenuPrimaryAction
onPressMenuItem={(id: string) => { onPressMenuItem={(id: string) => {
LayoutAnimation.configureNext(LayoutAnimation.Presets.easeInEaseOut); LayoutAnimation.configureNext(LayoutAnimation.Presets.easeInEaseOut);
if (id === HDSegwitBech32Wallet.type) { if (id === HDSegwitBech32Wallet.type) {
@ -246,11 +243,9 @@ const WalletsAdd: React.FC = () => {
} }
}} }}
actions={toolTipActions} actions={toolTipActions}
> />
<Icon size={22} name="more-horiz" type="material" color={colors.foregroundColor} />
</ToolTipMenu>
), ),
[colors.foregroundColor, handleOnLightningButtonPressed, navigateToEntropy, toolTipActions], [handleOnLightningButtonPressed, navigateToEntropy, toolTipActions],
); );
useEffect(() => { useEffect(() => {

View File

@ -11,11 +11,10 @@ import {
DoneAndDismissKeyboardInputAccessory, DoneAndDismissKeyboardInputAccessory,
DoneAndDismissKeyboardInputAccessoryViewID, DoneAndDismissKeyboardInputAccessoryViewID,
} from '../../components/DoneAndDismissKeyboardInputAccessory'; } from '../../components/DoneAndDismissKeyboardInputAccessory';
import { Icon } from '@rneui/themed';
import { CommonToolTipActions } from '../../typings/CommonToolTipActions'; import { CommonToolTipActions } from '../../typings/CommonToolTipActions';
import { useKeyboard } from '../../hooks/useKeyboard'; import { useKeyboard } from '../../hooks/useKeyboard';
import ToolTipMenu from '../../components/TooltipMenu';
import { useExtendedNavigation } from '../../hooks/useExtendedNavigation'; import { useExtendedNavigation } from '../../hooks/useExtendedNavigation';
import HeaderMenuButton from '../../components/HeaderMenuButton';
const WalletsImport = () => { const WalletsImport = () => {
const navigation = useExtendedNavigation(); const navigation = useExtendedNavigation();
@ -140,18 +139,8 @@ const WalletsImport = () => {
}, [askPassphrase, searchAccounts]); }, [askPassphrase, searchAccounts]);
const HeaderRight = useMemo( const HeaderRight = useMemo(
() => ( () => <HeaderMenuButton onPressMenuItem={toolTipOnPressMenuItem} actions={toolTipActions} />,
<ToolTipMenu [toolTipOnPressMenuItem, toolTipActions],
isButton
testID="HeaderRightButton"
isMenuPrimaryAction
onPressMenuItem={toolTipOnPressMenuItem}
actions={toolTipActions}
>
<Icon size={22} name="more-horiz" type="material" color={colors.foregroundColor} />
</ToolTipMenu>
),
[toolTipOnPressMenuItem, toolTipActions, colors.foregroundColor],
); );
// Adding the ToolTipMenu to the header // Adding the ToolTipMenu to the header

View File

@ -677,9 +677,9 @@ describe('BlueWallet UI Tests - no wallets', () => {
await element(by.id('MnemonicInput')).replaceText( await element(by.id('MnemonicInput')).replaceText(
'abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about', 'abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about',
); );
await element(by.id('HeaderRightButton')).tap(); await element(by.id('HeaderMenuButton')).tap();
await element(by.text('Passphrase')).tap(); await element(by.text('Passphrase')).tap();
await element(by.id('HeaderRightButton')).tap(); await element(by.id('HeaderMenuButton')).tap();
await element(by.text('Search accounts')).tap(); await element(by.text('Search accounts')).tap();
await element(by.id('DoImport')).tap(); await element(by.id('DoImport')).tap();
await sleep(1000); await sleep(1000);

View File

@ -202,23 +202,23 @@ describe('BlueWallet UI Tests - import BIP84 wallet', () => {
await element(by.text('OK')).tap(); await element(by.text('OK')).tap();
// lest add another two outputs // lest add another two outputs
await element(by.id('advancedOptionsMenuButton')).tap(); await element(by.id('HeaderMenuButton')).tap();
await element(by.text('Add Recipient')).tap(); await element(by.text('Add Recipient')).tap();
await yo('Transaction1'); // adding a recipient autoscrolls it to the last one await yo('Transaction1'); // adding a recipient autoscrolls it to the last one
await element(by.id('AddressInput').withAncestor(by.id('Transaction1'))).replaceText('bc1q063ctu6jhe5k4v8ka99qac8rcm2tzjjnuktyrl'); await element(by.id('AddressInput').withAncestor(by.id('Transaction1'))).replaceText('bc1q063ctu6jhe5k4v8ka99qac8rcm2tzjjnuktyrl');
await element(by.id('BitcoinAmountInput').withAncestor(by.id('Transaction1'))).replaceText('0.0002\n'); await element(by.id('BitcoinAmountInput').withAncestor(by.id('Transaction1'))).replaceText('0.0002\n');
await element(by.id('advancedOptionsMenuButton')).tap(); await element(by.id('HeaderMenuButton')).tap();
await element(by.text('Add Recipient')).tap(); await element(by.text('Add Recipient')).tap();
await yo('Transaction2'); // adding a recipient autoscrolls it to the last one await yo('Transaction2'); // adding a recipient autoscrolls it to the last one
// remove last output, check if second output is shown // remove last output, check if second output is shown
await element(by.id('advancedOptionsMenuButton')).tap(); await element(by.id('HeaderMenuButton')).tap();
await element(by.text('Remove Recipient')).tap(); await element(by.text('Remove Recipient')).tap();
await yo('Transaction1'); await yo('Transaction1');
// adding it again // adding it again
await element(by.id('advancedOptionsMenuButton')).tap(); await element(by.id('HeaderMenuButton')).tap();
await element(by.text('Add Recipient')).tap(); await element(by.text('Add Recipient')).tap();
await yo('Transaction2'); // adding a recipient autoscrolls it to the last one await yo('Transaction2'); // adding a recipient autoscrolls it to the last one
await element(by.id('AddressInput').withAncestor(by.id('Transaction2'))).replaceText('bc1qh6tf004ty7z7un2v5ntu4mkf630545gvhs45u7'); await element(by.id('AddressInput').withAncestor(by.id('Transaction2'))).replaceText('bc1qh6tf004ty7z7un2v5ntu4mkf630545gvhs45u7');
@ -227,7 +227,7 @@ describe('BlueWallet UI Tests - import BIP84 wallet', () => {
// remove second output // remove second output
await element(by.id('Transaction2')).swipe('right', 'fast', NaN, 0.2); await element(by.id('Transaction2')).swipe('right', 'fast', NaN, 0.2);
await sleep(5000); await sleep(5000);
await element(by.id('advancedOptionsMenuButton')).tap(); await element(by.id('HeaderMenuButton')).tap();
await element(by.text('Remove Recipient')).tap(); await element(by.text('Remove Recipient')).tap();
// creating and verifying. tx should have 3 outputs // creating and verifying. tx should have 3 outputs
@ -275,7 +275,7 @@ describe('BlueWallet UI Tests - import BIP84 wallet', () => {
// first send MAX output // first send MAX output
await element(by.id('AddressInput')).replaceText('bc1qnapskphjnwzw2w3dk4anpxntunc77v6qrua0f7'); await element(by.id('AddressInput')).replaceText('bc1qnapskphjnwzw2w3dk4anpxntunc77v6qrua0f7');
await element(by.id('BitcoinAmountInput')).typeText('0.0001\n'); await element(by.id('BitcoinAmountInput')).typeText('0.0001\n');
await element(by.id('advancedOptionsMenuButton')).tap(); await element(by.id('HeaderMenuButton')).tap();
await element(by.text('Use Full Balance')).tap(); await element(by.text('Use Full Balance')).tap();
await element(by.text('OK')).tap(); await element(by.text('OK')).tap();
@ -294,7 +294,7 @@ describe('BlueWallet UI Tests - import BIP84 wallet', () => {
// add second output with amount // add second output with amount
await device.pressBack(); await device.pressBack();
await device.pressBack(); await device.pressBack();
await element(by.id('advancedOptionsMenuButton')).tap(); await element(by.id('HeaderMenuButton')).tap();
await element(by.text('Add Recipient')).tap(); await element(by.text('Add Recipient')).tap();
await yo('Transaction1'); await yo('Transaction1');
await element(by.id('AddressInput').withAncestor(by.id('Transaction1'))).replaceText('bc1q063ctu6jhe5k4v8ka99qac8rcm2tzjjnuktyrl'); await element(by.id('AddressInput').withAncestor(by.id('Transaction1'))).replaceText('bc1q063ctu6jhe5k4v8ka99qac8rcm2tzjjnuktyrl');
@ -334,7 +334,7 @@ describe('BlueWallet UI Tests - import BIP84 wallet', () => {
await element(by.text('Imported HD SegWit (BIP84 Bech32 Native)')).tap(); await element(by.text('Imported HD SegWit (BIP84 Bech32 Native)')).tap();
await element(by.id('SendButton')).tap(); await element(by.id('SendButton')).tap();
await element(by.id('advancedOptionsMenuButton')).tap(); await element(by.id('HeaderMenuButton')).tap();
await element(by.text('Sign a transaction')).tap(); await element(by.text('Sign a transaction')).tap();
// tapping 5 times invisible button is a backdoor: // tapping 5 times invisible button is a backdoor:
@ -452,14 +452,14 @@ describe('BlueWallet UI Tests - import BIP84 wallet', () => {
await device.pressBack(); await device.pressBack();
await element(by.text('Imported HD SegWit (BIP84 Bech32 Native)')).tap(); await element(by.text('Imported HD SegWit (BIP84 Bech32 Native)')).tap();
await element(by.id('SendButton')).tap(); await element(by.id('SendButton')).tap();
await element(by.id('advancedOptionsMenuButton')).tap(); await element(by.id('HeaderMenuButton')).tap();
await element(by.text('Insert Contact')).tap(); await element(by.text('Insert Contact')).tap();
await element(by.id('ContactListItem0')).tap(); await element(by.id('ContactListItem0')).tap();
await element(by.id('BitcoinAmountInput')).typeText('0.0001\n'); await element(by.id('BitcoinAmountInput')).typeText('0.0001\n');
await element(by.id('advancedOptionsMenuButton')).tap(); await element(by.id('HeaderMenuButton')).tap();
await element(by.text('Add Recipient')).tap(); await element(by.text('Add Recipient')).tap();
await element(by.id('advancedOptionsMenuButton')).tap(); await element(by.id('HeaderMenuButton')).tap();
await element(by.text('Insert Contact')).tap(); await element(by.text('Insert Contact')).tap();
await element(by.id('ContactListItem1')).tap(); await element(by.id('ContactListItem1')).tap();
await element(by.id('BitcoinAmountInput')).atIndex(1).typeText('0.0002\n'); await element(by.id('BitcoinAmountInput')).atIndex(1).typeText('0.0002\n');
@ -601,7 +601,7 @@ describe('BlueWallet UI Tests - import BIP84 wallet', () => {
await yo('WalletsList'); await yo('WalletsList');
await element(by.text('Imported HD SegWit (BIP84 Bech32 Native)')).tap(); await element(by.text('Imported HD SegWit (BIP84 Bech32 Native)')).tap();
await element(by.id('SendButton')).tap(); await element(by.id('SendButton')).tap();
await element(by.id('advancedOptionsMenuButton')).tap(); await element(by.id('HeaderMenuButton')).tap();
await element(by.text('Coin Control')).tap(); await element(by.text('Coin Control')).tap();
await waitFor(element(by.id('Loading'))) // wait for outputs to be loaded await waitFor(element(by.id('Loading'))) // wait for outputs to be loaded
.not.toExist() .not.toExist()
@ -620,7 +620,7 @@ describe('BlueWallet UI Tests - import BIP84 wallet', () => {
await element(by.text('test2')).atIndex(0).tap(); await element(by.text('test2')).atIndex(0).tap();
await element(by.id('UseCoin')).tap(); await element(by.id('UseCoin')).tap();
await element(by.id('AddressInput')).replaceText('bc1q063ctu6jhe5k4v8ka99qac8rcm2tzjjnuktyrl'); await element(by.id('AddressInput')).replaceText('bc1q063ctu6jhe5k4v8ka99qac8rcm2tzjjnuktyrl');
await element(by.id('advancedOptionsMenuButton')).tap(); await element(by.id('HeaderMenuButton')).tap();
await element(by.text('Use Full Balance')).tap(); await element(by.text('Use Full Balance')).tap();
await element(by.text('OK')).tap(); await element(by.text('OK')).tap();
// setting fee rate: // setting fee rate:
@ -649,7 +649,7 @@ describe('BlueWallet UI Tests - import BIP84 wallet', () => {
// create tx with unfrozen input // create tx with unfrozen input
await element(by.id('SendButton')).tap(); await element(by.id('SendButton')).tap();
await element(by.id('AddressInput')).replaceText('bc1q063ctu6jhe5k4v8ka99qac8rcm2tzjjnuktyrl'); await element(by.id('AddressInput')).replaceText('bc1q063ctu6jhe5k4v8ka99qac8rcm2tzjjnuktyrl');
await element(by.id('advancedOptionsMenuButton')).tap(); await element(by.id('HeaderMenuButton')).tap();
await element(by.text('Use Full Balance')).tap(); await element(by.text('Use Full Balance')).tap();
await element(by.text('OK')).tap(); await element(by.text('OK')).tap();
// setting fee rate: // setting fee rate:

View File

@ -55,7 +55,7 @@ describe('BlueWallet UI Tests - import Watch-only wallet (zpub)', () => {
await element(by.id('SendButton')).tap(); await element(by.id('SendButton')).tap();
await element(by.text('OK')).tap(); await element(by.text('OK')).tap();
await element(by.id('advancedOptionsMenuButton')).tap(); await element(by.id('HeaderMenuButton')).tap();
await element(by.text('Import Transaction (QR)')).tap(); // opens camera await element(by.text('Import Transaction (QR)')).tap(); // opens camera
// produced by real Keystone device using MNEMONICS_KEYSTONE // produced by real Keystone device using MNEMONICS_KEYSTONE