REF: Allow multiple submenus

This commit is contained in:
Marcos Rodriguez Vélez 2021-10-03 23:47:01 -04:00
parent 0d9c316fcc
commit f9a2e7a6e8
No known key found for this signature in database
GPG key ID: 0D64671698D11C5C
5 changed files with 74 additions and 63 deletions

View file

@ -13,11 +13,18 @@ const ToolTipMenu = props => {
}; };
const showMenu = () => { const showMenu = () => {
let actions = props.actions.map(action => ({ id: action.id, label: action.text })); const menu = [];
if (props.submenu) { for (const actions of props.actions) {
actions = actions.concat(props.submenu.menuItems.map(action => ({ id: action.actionKey, label: action.actionTitle }))); if (Array.isArray(actions)) {
for (const actionToMap of actions) {
menu.push({ id: actionToMap.id, label: actionToMap.text });
} }
showPopupMenu(actions, handleToolTipSelection, ref.current); } else {
menu.push({ id: actions.id, label: actions.text });
}
}
showPopupMenu(menu, handleToolTipSelection, ref.current);
}; };
const child = (Array.isArray(props.children) ? props.children[0] : props.children) || null; const child = (Array.isArray(props.children) ? props.children[0] : props.children) || null;
@ -36,7 +43,6 @@ export default ToolTipMenu;
ToolTipMenu.propTypes = { ToolTipMenu.propTypes = {
actions: PropTypes.arrayOf(PropTypes.shape).isRequired, actions: PropTypes.arrayOf(PropTypes.shape).isRequired,
children: PropTypes.node.isRequired, children: PropTypes.node.isRequired,
submenu: PropTypes.any,
onPress: PropTypes.func.isRequired, onPress: PropTypes.func.isRequired,
isMenuPrimaryAction: PropTypes.bool, isMenuPrimaryAction: PropTypes.bool,
}; };

View file

@ -4,13 +4,13 @@ import PropTypes from 'prop-types';
import QRCodeComponent from './QRCodeComponent'; import QRCodeComponent from './QRCodeComponent';
const ToolTipMenu = props => { const ToolTipMenu = props => {
const menuItems = props.actions.map(action => { const menuItemMapped = ({ action, menuOptions }) => {
const item = { const item = {
actionKey: action.id, actionKey: action.id,
actionTitle: action.text, actionTitle: action.text,
actionOnPress: action.onPress, actionOnPress: action.onPress,
icon: action.icon, icon: action.icon,
menuOptions: action.menuOptions, menuOptions,
menuTitle: action.menuTitle, menuTitle: action.menuTitle,
}; };
item.menuState = action.menuStateOn ? 'on' : 'off'; item.menuState = action.menuStateOn ? 'on' : 'off';
@ -19,9 +19,25 @@ const ToolTipMenu = props => {
item.menuAttributes = ['disabled']; item.menuAttributes = ['disabled'];
} }
return item; return item;
};
const menuItems = props.actions.map(action => {
if (Array.isArray(action)) {
const mapped = [];
for (const actionToMap of action) {
mapped.push(menuItemMapped({ action: actionToMap }));
}
const submenu = {
menuOptions: ['displayInline'],
menuItems: mapped,
menuTitle: '',
};
return submenu;
} else {
return menuItemMapped({ action });
}
}); });
const menuTitle = props.title ?? ''; const menuTitle = props.title ?? '';
const submenu = props.submenu;
const isButton = !!props.isButton; const isButton = !!props.isButton;
const isMenuPrimaryAction = props.isMenuPrimaryAction ? props.isMenuPrimaryAction : false; const isMenuPrimaryAction = props.isMenuPrimaryAction ? props.isMenuPrimaryAction : false;
const previewQRCode = props.previewQRCode ?? false; const previewQRCode = props.previewQRCode ?? false;
@ -36,7 +52,7 @@ const ToolTipMenu = props => {
isMenuPrimaryAction={isMenuPrimaryAction} isMenuPrimaryAction={isMenuPrimaryAction}
menuConfig={{ menuConfig={{
menuTitle, menuTitle,
menuItems: menuItems.concat(submenu), menuItems,
}} }}
style={buttonStyle} style={buttonStyle}
> >
@ -49,7 +65,7 @@ const ToolTipMenu = props => {
}} }}
menuConfig={{ menuConfig={{
menuTitle, menuTitle,
menuItems: menuItems.concat(submenu), menuItems,
}} }}
{...(previewQRCode {...(previewQRCode
? { ? {
@ -70,7 +86,6 @@ export default ToolTipMenu;
ToolTipMenu.propTypes = { ToolTipMenu.propTypes = {
actions: PropTypes.arrayOf(PropTypes.shape).isRequired, actions: PropTypes.arrayOf(PropTypes.shape).isRequired,
title: PropTypes.string, title: PropTypes.string,
submenu: PropTypes.object,
children: PropTypes.node.isRequired, children: PropTypes.node.isRequired,
onPress: PropTypes.func.isRequired, onPress: PropTypes.func.isRequired,
isMenuPrimaryAction: PropTypes.bool, isMenuPrimaryAction: PropTypes.bool,

View file

@ -287,40 +287,33 @@ export const TransactionListItem = React.memo(({ item, itemPriceUnit = BitcoinUn
text: loc.transactions.details_copy_block_explorer_link, text: loc.transactions.details_copy_block_explorer_link,
icon: TransactionListItem.actionIcons.Clipboard, icon: TransactionListItem.actionIcons.Clipboard,
}, },
[
{
id: TransactionListItem.actionKeys.OpenInBlockExplorer,
text: loc.transactions.details_show_in_block_explorer,
icon: TransactionListItem.actionIcons.Link,
},
],
); );
} }
if (subtitle && subtitleNumberOfLines === 1) {
actions.push([
{
id: TransactionListItem.actionKeys.ExpandNote,
text: loc.transactions.expand_note,
icon: TransactionListItem.actionIcons.Note,
},
]);
}
return actions; return actions;
// eslint-disable-next-line react-hooks/exhaustive-deps // eslint-disable-next-line react-hooks/exhaustive-deps
}, [item.hash, subtitle, rowTitle, subtitleNumberOfLines, txMetadata]); }, [item.hash, subtitle, rowTitle, subtitleNumberOfLines, txMetadata]);
const toolTipSubMenu = useMemo(() => {
const submenu = {
menuOptions: ['displayInline'], // <- set the `menuOptions` property
menuItems: [],
menuTitle: '',
};
if (item.hash) {
submenu.menuItems.push({
actionKey: TransactionListItem.actionKeys.OpenInBlockExplorer,
actionTitle: loc.transactions.details_show_in_block_explorer,
icon: TransactionListItem.actionIcons.Link,
});
}
if (subtitle && subtitleNumberOfLines === 1) {
submenu.menuItems.push({
actionKey: TransactionListItem.actionKeys.ExpandNote,
actionTitle: loc.transactions.expand_note,
icon: TransactionListItem.actionIcons.Note,
});
}
return submenu;
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [item.hash, subtitle, subtitleNumberOfLines]);
return ( return (
<View style={styles.container}> <View style={styles.container}>
<ToolTipMenu actions={toolTipActions} submenu={toolTipSubMenu} onPress={onToolTipPress}> <ToolTipMenu actions={toolTipActions} onPress={onToolTipPress}>
<BlueListItem <BlueListItem
leftAvatar={avatar} leftAvatar={avatar}
title={title} title={title}

View file

@ -168,19 +168,14 @@ export default class TransactionsNavigationHeader extends Component {
text: loc.lnd.refill_card, text: loc.lnd.refill_card,
icon: TransactionsNavigationHeader.actionIcons.RefillWithBank, icon: TransactionsNavigationHeader.actionIcons.RefillWithBank,
}, },
]; [
toolTipSubmenuActions = {
menuOptions: ['displayInline'], // <- set the `menuOptions` property
menuTitle: '',
menuItems: [
{ {
actionKey: TransactionsNavigationHeader.actionKeys.Exchange, id: TransactionsNavigationHeader.actionKeys.Exchange,
actionTitle: loc.lnd.exchange, text: loc.lnd.exchange,
icon: TransactionsNavigationHeader.actionIcons.Exchange, icon: TransactionsNavigationHeader.actionIcons.Exchange,
}, },
], ],
}; ];
render() { render() {
const balance = const balance =
@ -258,7 +253,6 @@ export default class TransactionsNavigationHeader extends Component {
isButton isButton
onPress={this.manageFundsPressed} onPress={this.manageFundsPressed}
actions={this.toolTipMenuActions} actions={this.toolTipMenuActions}
submenu={this.toolTipSubmenuActions}
buttonStyle={styles.manageFundsButton} buttonStyle={styles.manageFundsButton}
> >
<Text style={styles.manageFundsButtonText}>{loc.lnd.title}</Text> <Text style={styles.manageFundsButtonText}>{loc.lnd.title}</Text>

View file

@ -873,10 +873,11 @@ const SendDetails = () => {
actions.push([{ id: SendDetails.actionKeys.SendMax, text: loc.send.details_adv_full, disabled: balance === 0 || isSendMaxUsed }]); actions.push([{ id: SendDetails.actionKeys.SendMax, text: loc.send.details_adv_full, disabled: balance === 0 || isSendMaxUsed }]);
if (wallet.type === HDSegwitBech32Wallet.type) { if (wallet.type === HDSegwitBech32Wallet.type) {
actions.push({ id: SendDetails.actionKeys.AllowRBF, text: loc.send.details_adv_fee_bump, menuStateOn: isTransactionReplaceable }); actions.push([{ id: SendDetails.actionKeys.AllowRBF, text: loc.send.details_adv_fee_bump, menuStateOn: isTransactionReplaceable }]);
} }
const transactionActions = [];
if (wallet.type === WatchOnlyWallet.type && wallet.isHd()) { if (wallet.type === WatchOnlyWallet.type && wallet.isHd()) {
actions.push( transactionActions.push(
{ {
id: SendDetails.actionKeys.ImportTransaction, id: SendDetails.actionKeys.ImportTransaction,
text: loc.send.details_adv_import, text: loc.send.details_adv_import,
@ -890,34 +891,36 @@ const SendDetails = () => {
); );
} }
if (wallet.type === MultisigHDWallet.type) { if (wallet.type === MultisigHDWallet.type) {
actions.push({ transactionActions.push({
id: SendDetails.actionKeys.ImportTransactionMultsig, id: SendDetails.actionKeys.ImportTransactionMultsig,
text: loc.send.details_adv_import, text: loc.send.details_adv_import,
icon: SendDetails.actionIcons.ImportTransactionMultsig, icon: SendDetails.actionIcons.ImportTransactionMultsig,
}); });
} }
if (wallet.type === MultisigHDWallet.type && wallet.howManySignaturesCanWeMake() > 0) { if (wallet.type === MultisigHDWallet.type && wallet.howManySignaturesCanWeMake() > 0) {
actions.push({ transactionActions.push({
id: SendDetails.actionKeys.CoSignTransaction, id: SendDetails.actionKeys.CoSignTransaction,
text: loc.multisig.co_sign_transaction, text: loc.multisig.co_sign_transaction,
icon: SendDetails.actionIcons.SignPSBT, icon: SendDetails.actionIcons.SignPSBT,
}); });
} }
if (wallet.allowCosignPsbt()) { if (wallet.allowCosignPsbt()) {
actions.push({ id: SendDetails.actionKeys.SignPSBT, text: loc.send.psbt_sign, icon: SendDetails.actionIcons.SignPSBT }); transactionActions.push({ id: SendDetails.actionKeys.SignPSBT, text: loc.send.psbt_sign, icon: SendDetails.actionIcons.SignPSBT });
} }
actions.push({ actions.push(transactionActions, [
{
id: SendDetails.actionKeys.AddRecipient, id: SendDetails.actionKeys.AddRecipient,
text: loc.send.details_add_rec_add, text: loc.send.details_add_rec_add,
icon: SendDetails.actionIcons.AddRecipient, icon: SendDetails.actionIcons.AddRecipient,
disabled: isSendMaxUsed, disabled: isSendMaxUsed,
}); },
actions.push({ {
id: SendDetails.actionKeys.RemoveRecipient, id: SendDetails.actionKeys.RemoveRecipient,
text: loc.send.details_add_rec_rem, text: loc.send.details_add_rec_rem,
disabled: addresses.length < 2, disabled: addresses.length < 2,
icon: SendDetails.actionIcons.RemoveRecipient, icon: SendDetails.actionIcons.RemoveRecipient,
}); },
]);
} }
actions.push({ id: SendDetails.actionKeys.CoinControl, text: loc.cc.header, icon: SendDetails.actionIcons.CoinControl }); actions.push({ id: SendDetails.actionKeys.CoinControl, text: loc.cc.header, icon: SendDetails.actionIcons.CoinControl });