mirror of
https://github.com/BlueWallet/BlueWallet.git
synced 2025-03-26 08:55:56 +01:00
REF: Move some Wallet Details options to menu
This commit is contained in:
parent
79f05ec12a
commit
ba5e566b90
4 changed files with 193 additions and 193 deletions
|
@ -269,6 +269,7 @@ const WalletsAdd: React.FC = () => {
|
|||
|
||||
return selectedWalletType === ButtonSelected.ONCHAIN ? [walletAction, entropyActions] : [walletAction];
|
||||
}, [entropy, entropyButtonText, selectedIndex, selectedWalletType]);
|
||||
|
||||
const handleOnLightningButtonPressed = useCallback(() => {
|
||||
confirmResetEntropy(ButtonSelected.OFFCHAIN);
|
||||
}, [confirmResetEntropy]);
|
||||
|
|
|
@ -30,7 +30,6 @@ import { LightningCustodianWallet } from '../../class/wallets/lightning-custodia
|
|||
import presentAlert from '../../components/Alert';
|
||||
import Button from '../../components/Button';
|
||||
import ListItem from '../../components/ListItem';
|
||||
import SaveFileButton from '../../components/SaveFileButton';
|
||||
import { SecondButton } from '../../components/SecondButton';
|
||||
import { useTheme } from '../../components/themes';
|
||||
import prompt from '../../helpers/prompt';
|
||||
|
@ -44,6 +43,9 @@ import { useFocusEffect, useRoute, RouteProp } from '@react-navigation/native';
|
|||
import { LightningTransaction, Transaction, TWallet } from '../../class/wallets/types';
|
||||
import { DetailViewStackParamList } from '../../navigation/DetailViewStackParamList';
|
||||
import { unsubscribe } from '../../blue_modules/notifications';
|
||||
import HeaderMenuButton from '../../components/HeaderMenuButton';
|
||||
import { Action } from '../../components/types';
|
||||
import { CommonToolTipActions } from '../../typings/CommonToolTipActions';
|
||||
|
||||
type RouteProps = RouteProp<DetailViewStackParamList, 'WalletDetails'>;
|
||||
const WalletDetails: React.FC = () => {
|
||||
|
@ -85,67 +87,8 @@ const WalletDetails: React.FC = () => {
|
|||
return null;
|
||||
}
|
||||
}, [wallet]);
|
||||
const [isToolTipMenuVisible, setIsToolTipMenuVisible] = useState<boolean>(false);
|
||||
const [isMasterFingerPrintVisible, setIsMasterFingerPrintVisible] = useState<boolean>(false);
|
||||
|
||||
const onMenuWillShow = () => setIsToolTipMenuVisible(true);
|
||||
const onMenuWillHide = () => setIsToolTipMenuVisible(false);
|
||||
|
||||
useEffect(() => {
|
||||
setIsContactsVisible(wallet.allowBIP47 && wallet.allowBIP47() && isBIP47Enabled);
|
||||
}, [isBIP47Enabled, wallet]);
|
||||
|
||||
useFocusEffect(
|
||||
useCallback(() => {
|
||||
const task = InteractionManager.runAfterInteractions(() => {
|
||||
if (isMasterFingerPrintVisible && wallet.allowMasterFingerprint && wallet.allowMasterFingerprint()) {
|
||||
// @ts-expect-error: Need to fix later
|
||||
if (wallet.getMasterFingerprintHex) {
|
||||
// @ts-expect-error: Need to fix later
|
||||
setMasterFingerprint(wallet.getMasterFingerprintHex());
|
||||
}
|
||||
} else {
|
||||
setMasterFingerprint(undefined);
|
||||
}
|
||||
});
|
||||
|
||||
return () => task.cancel();
|
||||
}, [isMasterFingerPrintVisible, wallet]),
|
||||
);
|
||||
|
||||
const stylesHook = StyleSheet.create({
|
||||
textLabel1: {
|
||||
color: colors.feeText,
|
||||
},
|
||||
textLabel2: {
|
||||
color: colors.feeText,
|
||||
},
|
||||
textValue: {
|
||||
color: colors.outputValue,
|
||||
},
|
||||
input: {
|
||||
borderColor: colors.formBorder,
|
||||
borderBottomColor: colors.formBorder,
|
||||
backgroundColor: colors.inputBackgroundColor,
|
||||
},
|
||||
delete: {
|
||||
color: isToolTipMenuVisible ? colors.buttonDisabledTextColor : '#d0021b',
|
||||
},
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
setOptions({
|
||||
headerBackTitleVisible: true,
|
||||
});
|
||||
}, [setOptions]);
|
||||
|
||||
useEffect(() => {
|
||||
if (wallets.some(w => w.getID() === walletID)) {
|
||||
setSelectedWalletID(walletID);
|
||||
}
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [walletID]);
|
||||
|
||||
const navigateToOverviewAndDeleteWallet = useCallback(async () => {
|
||||
setIsLoading(true);
|
||||
|
||||
|
@ -192,6 +135,170 @@ const WalletDetails: React.FC = () => {
|
|||
} catch (_) {}
|
||||
}, [navigateToOverviewAndDeleteWallet, wallet]);
|
||||
|
||||
const handleDeleteButtonTapped = useCallback(() => {
|
||||
triggerHapticFeedback(HapticFeedbackTypes.NotificationWarning);
|
||||
Alert.alert(
|
||||
loc.wallets.details_delete_wallet,
|
||||
loc.wallets.details_are_you_sure,
|
||||
[
|
||||
{
|
||||
text: loc.wallets.details_yes_delete,
|
||||
onPress: async () => {
|
||||
const isBiometricsEnabled = await isBiometricUseCapableAndEnabled();
|
||||
|
||||
if (isBiometricsEnabled) {
|
||||
if (!(await unlockWithBiometrics())) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (wallet.getBalance && wallet.getBalance() > 0 && wallet.allowSend && wallet.allowSend()) {
|
||||
presentWalletHasBalanceAlert();
|
||||
} else {
|
||||
navigateToOverviewAndDeleteWallet();
|
||||
}
|
||||
},
|
||||
style: 'destructive',
|
||||
},
|
||||
{ text: loc.wallets.details_no_cancel, onPress: () => {}, style: 'cancel' },
|
||||
],
|
||||
{ cancelable: false },
|
||||
);
|
||||
}, [isBiometricUseCapableAndEnabled, navigateToOverviewAndDeleteWallet, presentWalletHasBalanceAlert, wallet]);
|
||||
|
||||
const exportHistoryContent = useCallback(() => {
|
||||
const headers = [loc.transactions.date, loc.transactions.txid, `${loc.send.create_amount} (${BitcoinUnit.BTC})`, loc.send.create_memo];
|
||||
if (wallet.chain === Chain.OFFCHAIN) {
|
||||
headers.push(loc.lnd.payment);
|
||||
}
|
||||
|
||||
const rows = [headers.join(',')];
|
||||
const transactions = wallet.getTransactions();
|
||||
|
||||
transactions.forEach((transaction: Transaction & LightningTransaction) => {
|
||||
const value = formatBalanceWithoutSuffix(transaction.value || 0, BitcoinUnit.BTC, true);
|
||||
let hash: string = transaction.hash || '';
|
||||
let memo = (transaction.hash && txMetadata[transaction.hash]?.memo?.trim()) || '';
|
||||
let status = '';
|
||||
|
||||
if (wallet.chain === Chain.OFFCHAIN) {
|
||||
hash = transaction.payment_hash ? transaction.payment_hash.toString() : '';
|
||||
memo = transaction.memo || '';
|
||||
status = transaction.ispaid ? loc._.success : loc.lnd.expired;
|
||||
if (typeof hash !== 'string' && (hash as any)?.type === 'Buffer' && (hash as any)?.data) {
|
||||
hash = Buffer.from((hash as any).data).toString('hex');
|
||||
}
|
||||
}
|
||||
|
||||
const date = transaction.received ? new Date(transaction.received).toString() : '';
|
||||
const data = [date, hash, value, memo];
|
||||
|
||||
if (wallet.chain === Chain.OFFCHAIN) {
|
||||
data.push(status);
|
||||
}
|
||||
|
||||
rows.push(data.join(','));
|
||||
});
|
||||
|
||||
return rows.join('\n');
|
||||
}, [wallet, txMetadata]);
|
||||
|
||||
const fileName = useMemo(() => {
|
||||
const label = wallet.getLabel().replace(' ', '-');
|
||||
return `${label}-history.csv`;
|
||||
}, [wallet]);
|
||||
|
||||
const toolTipOnPressMenuItem = useCallback(
|
||||
async (id: string) => {
|
||||
if (id === CommonToolTipActions.Delete.id) {
|
||||
handleDeleteButtonTapped();
|
||||
} else if (id === CommonToolTipActions.Share.id) {
|
||||
await writeFileAndExport(fileName, exportHistoryContent(), true);
|
||||
} else if (id === CommonToolTipActions.SaveFile.id) {
|
||||
await writeFileAndExport(fileName, exportHistoryContent(), false);
|
||||
}
|
||||
},
|
||||
[exportHistoryContent, fileName, handleDeleteButtonTapped],
|
||||
);
|
||||
|
||||
const toolTipActions = useMemo(() => {
|
||||
const actions: Action[] = [
|
||||
{
|
||||
id: loc.wallets.details_export_history,
|
||||
text: loc.wallets.details_export_history,
|
||||
displayInline: true,
|
||||
hidden: walletTransactionsLength === 0,
|
||||
subactions: [CommonToolTipActions.Share, CommonToolTipActions.SaveFile],
|
||||
},
|
||||
CommonToolTipActions.Delete,
|
||||
];
|
||||
|
||||
return actions;
|
||||
}, [walletTransactionsLength]);
|
||||
|
||||
const HeaderRight = useMemo(
|
||||
() => <HeaderMenuButton disabled={isLoading} onPressMenuItem={toolTipOnPressMenuItem} actions={toolTipActions} />,
|
||||
[toolTipOnPressMenuItem, toolTipActions, isLoading],
|
||||
);
|
||||
|
||||
// Adding the ToolTipMenu to the header
|
||||
useEffect(() => {
|
||||
setOptions({
|
||||
headerRight: () => HeaderRight,
|
||||
});
|
||||
}, [HeaderRight, setOptions]);
|
||||
|
||||
useEffect(() => {
|
||||
setIsContactsVisible(wallet.allowBIP47 && wallet.allowBIP47() && isBIP47Enabled);
|
||||
}, [isBIP47Enabled, wallet]);
|
||||
|
||||
useFocusEffect(
|
||||
useCallback(() => {
|
||||
const task = InteractionManager.runAfterInteractions(() => {
|
||||
if (isMasterFingerPrintVisible && wallet.allowMasterFingerprint && wallet.allowMasterFingerprint()) {
|
||||
// @ts-expect-error: Need to fix later
|
||||
if (wallet.getMasterFingerprintHex) {
|
||||
// @ts-expect-error: Need to fix later
|
||||
setMasterFingerprint(wallet.getMasterFingerprintHex());
|
||||
}
|
||||
} else {
|
||||
setMasterFingerprint(undefined);
|
||||
}
|
||||
});
|
||||
|
||||
return () => task.cancel();
|
||||
}, [isMasterFingerPrintVisible, wallet]),
|
||||
);
|
||||
|
||||
const stylesHook = StyleSheet.create({
|
||||
textLabel1: {
|
||||
color: colors.feeText,
|
||||
},
|
||||
textLabel2: {
|
||||
color: colors.feeText,
|
||||
},
|
||||
textValue: {
|
||||
color: colors.outputValue,
|
||||
},
|
||||
input: {
|
||||
borderColor: colors.formBorder,
|
||||
borderBottomColor: colors.formBorder,
|
||||
backgroundColor: colors.inputBackgroundColor,
|
||||
},
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
setOptions({
|
||||
headerBackTitleVisible: true,
|
||||
});
|
||||
}, [setOptions]);
|
||||
|
||||
useEffect(() => {
|
||||
if (wallets.some(w => w.getID() === walletID)) {
|
||||
setSelectedWalletID(walletID);
|
||||
}
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [walletID]);
|
||||
|
||||
const navigateToWalletExport = () => {
|
||||
navigate('WalletExportRoot', {
|
||||
screen: 'WalletExport',
|
||||
|
@ -243,7 +350,7 @@ const WalletDetails: React.FC = () => {
|
|||
if (backdoorPressed < 10) return setBackdoorPressed(backdoorPressed + 1);
|
||||
setBackdoorPressed(0);
|
||||
if (wallet.type !== HDSegwitBech32Wallet.type) return;
|
||||
const fileName = 'wallet-externals.json';
|
||||
const fileNameExternals = 'wallet-externals.json';
|
||||
const contents = JSON.stringify(
|
||||
{
|
||||
_balances_by_external_index: wallet._balances_by_external_index,
|
||||
|
@ -265,7 +372,7 @@ const WalletDetails: React.FC = () => {
|
|||
2,
|
||||
);
|
||||
|
||||
await writeFileAndExport(fileName, contents, false);
|
||||
await writeFileAndExport(fileNameExternals, contents, false);
|
||||
};
|
||||
|
||||
const purgeTransactions = async () => {
|
||||
|
@ -314,78 +421,6 @@ const WalletDetails: React.FC = () => {
|
|||
return subscribe;
|
||||
}, [addListener, walletName, walletNameTextInputOnBlur]);
|
||||
|
||||
const exportHistoryContent = useCallback(() => {
|
||||
const headers = [loc.transactions.date, loc.transactions.txid, `${loc.send.create_amount} (${BitcoinUnit.BTC})`, loc.send.create_memo];
|
||||
if (wallet.chain === Chain.OFFCHAIN) {
|
||||
headers.push(loc.lnd.payment);
|
||||
}
|
||||
|
||||
const rows = [headers.join(',')];
|
||||
const transactions = wallet.getTransactions();
|
||||
|
||||
transactions.forEach((transaction: Transaction & LightningTransaction) => {
|
||||
const value = formatBalanceWithoutSuffix(transaction.value || 0, BitcoinUnit.BTC, true);
|
||||
let hash: string = transaction.hash || '';
|
||||
let memo = (transaction.hash && txMetadata[transaction.hash]?.memo?.trim()) || '';
|
||||
let status = '';
|
||||
|
||||
if (wallet.chain === Chain.OFFCHAIN) {
|
||||
hash = transaction.payment_hash ? transaction.payment_hash.toString() : '';
|
||||
memo = transaction.memo || '';
|
||||
status = transaction.ispaid ? loc._.success : loc.lnd.expired;
|
||||
if (typeof hash !== 'string' && (hash as any)?.type === 'Buffer' && (hash as any)?.data) {
|
||||
hash = Buffer.from((hash as any).data).toString('hex');
|
||||
}
|
||||
}
|
||||
|
||||
const date = transaction.received ? new Date(transaction.received).toString() : '';
|
||||
const data = [date, hash, value, memo];
|
||||
|
||||
if (wallet.chain === Chain.OFFCHAIN) {
|
||||
data.push(status);
|
||||
}
|
||||
|
||||
rows.push(data.join(','));
|
||||
});
|
||||
|
||||
return rows.join('\n');
|
||||
}, [wallet, txMetadata]);
|
||||
|
||||
const handleDeleteButtonTapped = () => {
|
||||
triggerHapticFeedback(HapticFeedbackTypes.NotificationWarning);
|
||||
Alert.alert(
|
||||
loc.wallets.details_delete_wallet,
|
||||
loc.wallets.details_are_you_sure,
|
||||
[
|
||||
{
|
||||
text: loc.wallets.details_yes_delete,
|
||||
onPress: async () => {
|
||||
const isBiometricsEnabled = await isBiometricUseCapableAndEnabled();
|
||||
|
||||
if (isBiometricsEnabled) {
|
||||
if (!(await unlockWithBiometrics())) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (wallet.getBalance && wallet.getBalance() > 0 && wallet.allowSend && wallet.allowSend()) {
|
||||
presentWalletHasBalanceAlert();
|
||||
} else {
|
||||
navigateToOverviewAndDeleteWallet();
|
||||
}
|
||||
},
|
||||
style: 'destructive',
|
||||
},
|
||||
{ text: loc.wallets.details_no_cancel, onPress: () => {}, style: 'cancel' },
|
||||
],
|
||||
{ cancelable: false },
|
||||
);
|
||||
};
|
||||
|
||||
const fileName = useMemo(() => {
|
||||
const label = wallet.getLabel().replace(' ', '-');
|
||||
return `${label}-history.csv`;
|
||||
}, [wallet]);
|
||||
|
||||
const onViewMasterFingerPrintPress = () => {
|
||||
LayoutAnimation.configureNext(LayoutAnimation.Presets.easeInEaseOut);
|
||||
setIsMasterFingerPrintVisible(true);
|
||||
|
@ -490,7 +525,6 @@ const WalletDetails: React.FC = () => {
|
|||
<View style={styles.hardware}>
|
||||
<BlueText>{loc.wallets.details_display}</BlueText>
|
||||
<Switch
|
||||
disabled={isToolTipMenuVisible}
|
||||
value={hideTransactionsInWalletsList}
|
||||
onValueChange={async (value: boolean) => {
|
||||
if (wallet.setHideTransactionsInWalletsList) {
|
||||
|
@ -593,38 +627,17 @@ const WalletDetails: React.FC = () => {
|
|||
</View>
|
||||
</BlueCard>
|
||||
{(wallet instanceof AbstractHDElectrumWallet || (wallet.type === WatchOnlyWallet.type && wallet.isHd && wallet.isHd())) && (
|
||||
<ListItem disabled={isToolTipMenuVisible} onPress={navigateToAddresses} title={loc.wallets.details_show_addresses} chevron />
|
||||
<ListItem onPress={navigateToAddresses} title={loc.wallets.details_show_addresses} chevron />
|
||||
)}
|
||||
{isContactsVisible ? (
|
||||
<ListItem disabled={isToolTipMenuVisible} onPress={navigateToContacts} title={loc.bip47.contacts} chevron />
|
||||
) : null}
|
||||
{isContactsVisible ? <ListItem onPress={navigateToContacts} title={loc.bip47.contacts} chevron /> : null}
|
||||
<BlueCard style={styles.address}>
|
||||
<View>
|
||||
<BlueSpacing20 />
|
||||
<Button
|
||||
disabled={isToolTipMenuVisible}
|
||||
onPress={navigateToWalletExport}
|
||||
testID="WalletExport"
|
||||
title={loc.wallets.details_export_backup}
|
||||
/>
|
||||
{walletTransactionsLength > 0 && (
|
||||
<>
|
||||
<BlueSpacing20 />
|
||||
<SaveFileButton
|
||||
onMenuWillHide={onMenuWillHide}
|
||||
onMenuWillShow={onMenuWillShow}
|
||||
fileName={fileName}
|
||||
fileContent={exportHistoryContent()}
|
||||
>
|
||||
<SecondButton title={loc.wallets.details_export_history} />
|
||||
</SaveFileButton>
|
||||
</>
|
||||
)}
|
||||
<Button onPress={navigateToWalletExport} testID="WalletExport" title={loc.wallets.details_export_backup} />
|
||||
{wallet.type === MultisigHDWallet.type && (
|
||||
<>
|
||||
<BlueSpacing20 />
|
||||
<SecondButton
|
||||
disabled={isToolTipMenuVisible}
|
||||
onPress={navigateToMultisigCoordinationSetup}
|
||||
testID="MultisigCoordinationSetup"
|
||||
title={loc.multisig.export_coordination_setup.replace(/^\w/, (c: string) => c.toUpperCase())}
|
||||
|
@ -635,49 +648,24 @@ const WalletDetails: React.FC = () => {
|
|||
{wallet.type === MultisigHDWallet.type && (
|
||||
<>
|
||||
<BlueSpacing20 />
|
||||
<SecondButton
|
||||
disabled={isToolTipMenuVisible}
|
||||
onPress={navigateToViewEditCosigners}
|
||||
testID="ViewEditCosigners"
|
||||
title={loc.multisig.view_edit_cosigners}
|
||||
/>
|
||||
<SecondButton onPress={navigateToViewEditCosigners} testID="ViewEditCosigners" title={loc.multisig.view_edit_cosigners} />
|
||||
</>
|
||||
)}
|
||||
|
||||
{wallet.allowXpub && wallet.allowXpub() && (
|
||||
<>
|
||||
<BlueSpacing20 />
|
||||
<SecondButton
|
||||
disabled={isToolTipMenuVisible}
|
||||
onPress={navigateToXPub}
|
||||
testID="XPub"
|
||||
title={loc.wallets.details_show_xpub}
|
||||
/>
|
||||
<SecondButton onPress={navigateToXPub} testID="XPub" title={loc.wallets.details_show_xpub} />
|
||||
</>
|
||||
)}
|
||||
{wallet.allowSignVerifyMessage && wallet.allowSignVerifyMessage() && (
|
||||
<>
|
||||
<BlueSpacing20 />
|
||||
<SecondButton
|
||||
disabled={isToolTipMenuVisible}
|
||||
onPress={navigateToSignVerify}
|
||||
testID="SignVerify"
|
||||
title={loc.addresses.sign_title}
|
||||
/>
|
||||
<SecondButton onPress={navigateToSignVerify} testID="SignVerify" title={loc.addresses.sign_title} />
|
||||
</>
|
||||
)}
|
||||
<BlueSpacing20 />
|
||||
<BlueSpacing20 />
|
||||
<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 />
|
||||
</View>
|
||||
</BlueCard>
|
||||
</View>
|
||||
|
@ -728,11 +716,6 @@ const styles = StyleSheet.create({
|
|||
alignItems: 'center',
|
||||
justifyContent: 'space-between',
|
||||
},
|
||||
delete: {
|
||||
fontSize: 15,
|
||||
fontWeight: '500',
|
||||
textAlign: 'center',
|
||||
},
|
||||
row: {
|
||||
flexDirection: 'row',
|
||||
},
|
||||
|
|
|
@ -61,7 +61,8 @@ export async function helperDeleteWallet(label, remainingBalanceSat = false) {
|
|||
await element(by.text(label)).tap();
|
||||
await element(by.id('WalletDetails')).tap();
|
||||
await element(by.id('WalletDetailsScroll')).swipe('up', 'fast', 1);
|
||||
await element(by.id('DeleteButton')).tap();
|
||||
await element(by.id('HeaderMenuButton')).tap();
|
||||
await element(by.text('Delete')).tap();
|
||||
await sup('Yes, delete');
|
||||
await element(by.text('Yes, delete')).tap();
|
||||
if (remainingBalanceSat) {
|
||||
|
|
|
@ -40,6 +40,7 @@ const keys = {
|
|||
CoSignTransaction: 'co_sign_transaction',
|
||||
CopyToClipboard: 'copyToClipboard',
|
||||
Share: 'share',
|
||||
SaveFile: 'saveFile',
|
||||
SignVerify: 'signVerify',
|
||||
ExportPrivateKey: 'exportPrivateKey',
|
||||
PasteFromClipboard: 'pasteFromClipboard',
|
||||
|
@ -50,6 +51,7 @@ const keys = {
|
|||
SortValue: 'sortValue',
|
||||
SortLabel: 'sortLabel',
|
||||
SortStatus: 'sortStatus',
|
||||
Delete: 'delete',
|
||||
} as const;
|
||||
|
||||
const icons = {
|
||||
|
@ -94,6 +96,8 @@ const icons = {
|
|||
ClearClipboard: { iconValue: 'clipboard' },
|
||||
SortASC: { iconValue: 'arrow.down.to.line' },
|
||||
SortDESC: { iconValue: 'arrow.up.to.line' },
|
||||
SaveFile: { iconValue: 'square.and.arrow.down' },
|
||||
Delete: { iconValue: 'trash' },
|
||||
} as const;
|
||||
|
||||
export const CommonToolTipActions = {
|
||||
|
@ -353,4 +357,15 @@ export const CommonToolTipActions = {
|
|||
id: keys.SortStatus,
|
||||
text: loc.cc.sort_status,
|
||||
},
|
||||
SaveFile: {
|
||||
id: keys.SaveFile,
|
||||
text: loc._.save,
|
||||
icon: icons.SaveFile,
|
||||
},
|
||||
Delete: {
|
||||
id: keys.Delete,
|
||||
text: loc.wallets.details_delete,
|
||||
icon: icons.Delete,
|
||||
destructive: true,
|
||||
},
|
||||
} as const;
|
||||
|
|
Loading…
Add table
Reference in a new issue