mirror of
https://github.com/BlueWallet/BlueWallet.git
synced 2024-11-19 09:50:15 +01:00
Merge pull request #6711 from BlueWallet/pop
REF: Use menu package since showPopmenu is being removed
This commit is contained in:
commit
456582a282
@ -1,32 +0,0 @@
|
||||
// @ts-ignore: Ignore
|
||||
import type { Element } from 'react';
|
||||
import { findNodeHandle, Text, TouchableNativeFeedback, TouchableWithoutFeedback, UIManager, View } from 'react-native';
|
||||
|
||||
type PopupMenuItem = { id?: any; label: string };
|
||||
type OnPopupMenuItemSelect = (selectedPopupMenuItem: PopupMenuItem) => void;
|
||||
type PopupAnchor = Element<typeof Text | typeof TouchableNativeFeedback | typeof TouchableWithoutFeedback | typeof View>;
|
||||
type PopupMenuOptions = { onCancel?: () => void };
|
||||
|
||||
function showPopupMenu(
|
||||
items: PopupMenuItem[],
|
||||
onSelect: OnPopupMenuItemSelect,
|
||||
anchor: PopupAnchor,
|
||||
{ onCancel }: PopupMenuOptions = {},
|
||||
): void {
|
||||
UIManager.showPopupMenu(
|
||||
// @ts-ignore: Ignore
|
||||
findNodeHandle(anchor),
|
||||
items.map(item => item.label),
|
||||
function () {
|
||||
if (onCancel) onCancel();
|
||||
},
|
||||
function (eventName: 'dismissed' | 'itemSelected', selectedIndex?: number) {
|
||||
// @ts-ignore: Ignore
|
||||
if (eventName === 'itemSelected') onSelect(items[selectedIndex]);
|
||||
else onCancel && onCancel();
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
export type { OnPopupMenuItemSelect, PopupMenuItem, PopupMenuOptions };
|
||||
export default showPopupMenu;
|
@ -1,13 +1,13 @@
|
||||
import React from 'react';
|
||||
import { Image, Keyboard, StyleSheet, Text, TextInput, View } from 'react-native';
|
||||
import React, { useCallback, useMemo } from 'react';
|
||||
import { Image, Keyboard, Platform, StyleSheet, Text, TextInput, View } from 'react-native';
|
||||
|
||||
import { scanQrHelper } from '../helpers/scan-qr';
|
||||
import loc from '../loc';
|
||||
import { useTheme } from './themes';
|
||||
import ToolTipMenu from './TooltipMenu';
|
||||
import { showFilePickerAndReadFile, showImagePickerAndReadImage } from '../blue_modules/fs';
|
||||
import Clipboard from '@react-native-clipboard/clipboard';
|
||||
import presentAlert from './Alert';
|
||||
import ToolTipMenu from './TooltipMenu';
|
||||
|
||||
interface AddressInputProps {
|
||||
isLoading?: boolean;
|
||||
@ -69,52 +69,63 @@ const AddressInput = ({
|
||||
Keyboard.dismiss();
|
||||
};
|
||||
|
||||
const onMenuItemPressed = (action: string) => {
|
||||
if (onBarScanned === undefined) throw new Error('onBarScanned is required');
|
||||
switch (action) {
|
||||
case actionKeys.ScanQR:
|
||||
scanButtonTapped();
|
||||
if (launchedBy) {
|
||||
scanQrHelper(launchedBy)
|
||||
.then(value => onBarScanned({ data: value }))
|
||||
const toolTipOnPress = useCallback(async () => {
|
||||
await scanButtonTapped();
|
||||
Keyboard.dismiss();
|
||||
if (launchedBy) scanQrHelper(launchedBy).then(value => onBarScanned({ data: value }));
|
||||
}, [launchedBy, onBarScanned, scanButtonTapped]);
|
||||
|
||||
const onMenuItemPressed = useCallback(
|
||||
(action: string) => {
|
||||
if (onBarScanned === undefined) throw new Error('onBarScanned is required');
|
||||
switch (action) {
|
||||
case actionKeys.ScanQR:
|
||||
scanButtonTapped();
|
||||
if (launchedBy) {
|
||||
scanQrHelper(launchedBy)
|
||||
.then(value => onBarScanned({ data: value }))
|
||||
.catch(error => {
|
||||
presentAlert({ message: error.message });
|
||||
});
|
||||
}
|
||||
|
||||
break;
|
||||
case actionKeys.CopyFromClipboard:
|
||||
Clipboard.getString()
|
||||
.then(onChangeText)
|
||||
.catch(error => {
|
||||
presentAlert({ message: error.message });
|
||||
});
|
||||
}
|
||||
break;
|
||||
case actionKeys.ChoosePhoto:
|
||||
showImagePickerAndReadImage()
|
||||
.then(value => {
|
||||
if (value) {
|
||||
onChangeText(value);
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
presentAlert({ message: error.message });
|
||||
});
|
||||
break;
|
||||
case actionKeys.ImportFile:
|
||||
showFilePickerAndReadFile()
|
||||
.then(value => {
|
||||
if (value.data) {
|
||||
onChangeText(value.data);
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
presentAlert({ message: error.message });
|
||||
});
|
||||
break;
|
||||
}
|
||||
Keyboard.dismiss();
|
||||
},
|
||||
[launchedBy, onBarScanned, onChangeText, scanButtonTapped],
|
||||
);
|
||||
|
||||
break;
|
||||
case actionKeys.CopyFromClipboard:
|
||||
Clipboard.getString()
|
||||
.then(onChangeText)
|
||||
.catch(error => {
|
||||
presentAlert({ message: error.message });
|
||||
});
|
||||
break;
|
||||
case actionKeys.ChoosePhoto:
|
||||
showImagePickerAndReadImage()
|
||||
.then(value => {
|
||||
if (value) {
|
||||
onChangeText(value);
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
presentAlert({ message: error.message });
|
||||
});
|
||||
break;
|
||||
case actionKeys.ImportFile:
|
||||
showFilePickerAndReadFile()
|
||||
.then(value => {
|
||||
if (value.data) {
|
||||
onChangeText(value.data);
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
presentAlert({ message: error.message });
|
||||
});
|
||||
break;
|
||||
}
|
||||
Keyboard.dismiss();
|
||||
};
|
||||
const buttonStyle = useMemo(() => [styles.scan, stylesHook.scan], [stylesHook.scan]);
|
||||
|
||||
return (
|
||||
<View style={[styles.root, stylesHook.root]}>
|
||||
@ -141,12 +152,8 @@ const AddressInput = ({
|
||||
onPressMenuItem={onMenuItemPressed}
|
||||
testID="BlueAddressInputScanQrButton"
|
||||
disabled={isLoading}
|
||||
onPress={async () => {
|
||||
await scanButtonTapped();
|
||||
Keyboard.dismiss();
|
||||
if (launchedBy) scanQrHelper(launchedBy).then(value => onBarScanned({ data: value }));
|
||||
}}
|
||||
style={[styles.scan, stylesHook.scan]}
|
||||
onPress={toolTipOnPress}
|
||||
buttonStyle={buttonStyle}
|
||||
accessibilityLabel={loc.send.details_scan}
|
||||
accessibilityHint={loc.send.details_scan_hint}
|
||||
>
|
||||
@ -202,20 +209,16 @@ const actionKeys = {
|
||||
|
||||
const actionIcons = {
|
||||
ScanQR: {
|
||||
iconType: 'SYSTEM',
|
||||
iconValue: 'qrcode',
|
||||
iconValue: Platform.OS === 'ios' ? 'qrcode' : 'ic_menu_camera',
|
||||
},
|
||||
ImportFile: {
|
||||
iconType: 'SYSTEM',
|
||||
iconValue: 'doc',
|
||||
},
|
||||
ChoosePhoto: {
|
||||
iconType: 'SYSTEM',
|
||||
iconValue: 'photo',
|
||||
iconValue: Platform.OS === 'ios' ? 'photo' : 'ic_menu_gallery',
|
||||
},
|
||||
Clipboard: {
|
||||
iconType: 'SYSTEM',
|
||||
iconValue: 'doc.on.doc',
|
||||
iconValue: Platform.OS === 'ios' ? 'doc' : 'ic_menu_file',
|
||||
},
|
||||
};
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
import Clipboard from '@react-native-clipboard/clipboard';
|
||||
import React, { useRef } from 'react';
|
||||
import React, { useCallback, useRef } from 'react';
|
||||
import { Platform, StyleSheet, View } from 'react-native';
|
||||
import QRCode from 'react-native-qrcode-svg';
|
||||
import Share from 'react-native-share';
|
||||
@ -22,11 +22,9 @@ interface QRCodeComponentProps {
|
||||
|
||||
const actionIcons: { [key: string]: ActionIcons } = {
|
||||
Share: {
|
||||
iconType: 'SYSTEM',
|
||||
iconValue: 'square.and.arrow.up',
|
||||
},
|
||||
Copy: {
|
||||
iconType: 'SYSTEM',
|
||||
iconValue: 'doc.on.doc',
|
||||
},
|
||||
};
|
||||
@ -76,13 +74,13 @@ const QRCodeComponent: React.FC<QRCodeComponentProps> = ({
|
||||
});
|
||||
};
|
||||
|
||||
const onPressMenuItem = (id: string) => {
|
||||
const onPressMenuItem = useCallback((id: string) => {
|
||||
if (id === actionKeys.Share) {
|
||||
handleShareQRCode();
|
||||
} else if (id === actionKeys.Copy) {
|
||||
qrCode.current.toDataURL(Clipboard.setImage);
|
||||
}
|
||||
};
|
||||
}, []);
|
||||
|
||||
const renderQRCode = (
|
||||
<QRCode
|
||||
|
@ -1,4 +1,4 @@
|
||||
import React, { ReactNode } from 'react';
|
||||
import React, { ReactNode, useCallback } from 'react';
|
||||
import { StyleProp, ViewStyle } from 'react-native';
|
||||
|
||||
import * as fs from '../blue_modules/fs';
|
||||
@ -28,22 +28,25 @@ const SaveFileButton: React.FC<SaveFileButtonProps> = ({
|
||||
onMenuWillHide,
|
||||
onMenuWillShow,
|
||||
}) => {
|
||||
const handlePressMenuItem = async (actionId: string) => {
|
||||
if (beforeOnPress) {
|
||||
await beforeOnPress();
|
||||
}
|
||||
const action = actions.find(a => a.id === actionId);
|
||||
const handlePressMenuItem = useCallback(
|
||||
async (actionId: string) => {
|
||||
if (beforeOnPress) {
|
||||
await beforeOnPress();
|
||||
}
|
||||
const action = actions.find(a => a.id === actionId);
|
||||
|
||||
if (action?.id === 'save') {
|
||||
await fs.writeFileAndExport(fileName, fileContent, false).finally(() => {
|
||||
afterOnPress?.();
|
||||
});
|
||||
} else if (action?.id === 'share') {
|
||||
await fs.writeFileAndExport(fileName, fileContent, true).finally(() => {
|
||||
afterOnPress?.();
|
||||
});
|
||||
}
|
||||
};
|
||||
if (action?.id === 'save') {
|
||||
await fs.writeFileAndExport(fileName, fileContent, false).finally(() => {
|
||||
afterOnPress?.();
|
||||
});
|
||||
} else if (action?.id === 'share') {
|
||||
await fs.writeFileAndExport(fileName, fileContent, true).finally(() => {
|
||||
afterOnPress?.();
|
||||
});
|
||||
}
|
||||
},
|
||||
[afterOnPress, beforeOnPress, fileContent, fileName],
|
||||
);
|
||||
|
||||
return (
|
||||
<ToolTipMenu
|
||||
@ -64,11 +67,9 @@ export default SaveFileButton;
|
||||
|
||||
const actionIcons: { [key: string]: ActionIcons } = {
|
||||
Share: {
|
||||
iconType: 'SYSTEM',
|
||||
iconValue: 'square.and.arrow.up',
|
||||
},
|
||||
Save: {
|
||||
iconType: 'SYSTEM',
|
||||
iconValue: 'square.and.arrow.down',
|
||||
},
|
||||
};
|
||||
|
@ -1,77 +0,0 @@
|
||||
import React, { forwardRef, Ref, useCallback, useEffect, useMemo, useRef } from 'react';
|
||||
import { Pressable, View } from 'react-native';
|
||||
|
||||
import showPopupMenu, { OnPopupMenuItemSelect, PopupMenuItem } from '../blue_modules/showPopupMenu.android';
|
||||
import { ToolTipMenuProps } from './types';
|
||||
|
||||
const dismissMenu = () => {
|
||||
console.log('dismissMenu Not implemented');
|
||||
};
|
||||
const BaseToolTipMenu = (props: ToolTipMenuProps, ref: Ref<{ dismissMenu?: () => void }>) => {
|
||||
const menuRef = useRef<View>(null);
|
||||
const {
|
||||
actions,
|
||||
children,
|
||||
onPressMenuItem,
|
||||
isMenuPrimaryAction = false,
|
||||
buttonStyle = {},
|
||||
enableAndroidRipple = true,
|
||||
disabled = false,
|
||||
onPress,
|
||||
...restProps
|
||||
} = props;
|
||||
|
||||
const handleToolTipSelection = useCallback<OnPopupMenuItemSelect>(
|
||||
(selection: PopupMenuItem) => {
|
||||
if (selection.id) {
|
||||
onPressMenuItem(selection.id);
|
||||
}
|
||||
},
|
||||
[onPressMenuItem],
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
// @ts-ignore: fix later
|
||||
if (ref && ref.current) {
|
||||
// @ts-ignore: fix later
|
||||
ref.current.dismissMenu = dismissMenu;
|
||||
}
|
||||
}, [ref]);
|
||||
|
||||
const menuItems = useMemo(() => {
|
||||
const menu: { id: string; label: string }[] = [];
|
||||
actions.forEach(action => {
|
||||
if (Array.isArray(action)) {
|
||||
action.forEach(actionToMap => {
|
||||
menu.push({ id: actionToMap.id.toString(), label: actionToMap.text });
|
||||
});
|
||||
} else {
|
||||
menu.push({ id: action.id.toString(), label: action.text });
|
||||
}
|
||||
});
|
||||
return menu;
|
||||
}, [actions]);
|
||||
|
||||
const showMenu = useCallback(() => {
|
||||
if (menuRef.current) {
|
||||
showPopupMenu(menuItems, handleToolTipSelection, menuRef.current);
|
||||
}
|
||||
}, [menuItems, handleToolTipSelection]);
|
||||
|
||||
return (
|
||||
<Pressable
|
||||
{...(enableAndroidRipple ? { android_ripple: { color: 'lightgrey' } } : {})}
|
||||
ref={menuRef}
|
||||
disabled={disabled}
|
||||
style={buttonStyle}
|
||||
{...(isMenuPrimaryAction ? { onPress: showMenu } : { onPress, onLongPress: showMenu })}
|
||||
{...restProps}
|
||||
>
|
||||
{children}
|
||||
</Pressable>
|
||||
);
|
||||
};
|
||||
|
||||
const ToolTipMenu = forwardRef(BaseToolTipMenu);
|
||||
|
||||
export default ToolTipMenu;
|
@ -1,128 +0,0 @@
|
||||
import React, { forwardRef, Ref, useCallback, useMemo } from 'react';
|
||||
import { TouchableOpacity } from 'react-native';
|
||||
import { ContextMenuButton, ContextMenuView, RenderItem } from 'react-native-ios-context-menu';
|
||||
|
||||
import { Action, ToolTipMenuProps } from './types';
|
||||
|
||||
const BaseToolTipMenu = (props: ToolTipMenuProps, ref: Ref<any>) => {
|
||||
const {
|
||||
title = '',
|
||||
isButton = false,
|
||||
isMenuPrimaryAction = false,
|
||||
renderPreview,
|
||||
disabled = false,
|
||||
onPress,
|
||||
onMenuWillShow,
|
||||
onMenuWillHide,
|
||||
buttonStyle,
|
||||
onPressMenuItem,
|
||||
...restProps
|
||||
} = props;
|
||||
|
||||
const menuItemMapped = useCallback(({ action, menuOptions }: { action: Action; menuOptions?: string[] }) => {
|
||||
const item: any = {
|
||||
actionKey: action.id.toString(),
|
||||
actionTitle: action.text,
|
||||
icon: action.icon,
|
||||
menuOptions,
|
||||
menuTitle: action.menuTitle,
|
||||
};
|
||||
item.menuState = action.menuStateOn ? 'on' : 'off';
|
||||
|
||||
if (action.disabled) {
|
||||
item.menuAttributes = ['disabled'];
|
||||
}
|
||||
return item;
|
||||
}, []);
|
||||
|
||||
const menuItems = useMemo(
|
||||
() =>
|
||||
props.actions.map(action => {
|
||||
if (Array.isArray(action)) {
|
||||
const mapped = action.map(actionToMap => menuItemMapped({ action: actionToMap }));
|
||||
return {
|
||||
menuOptions: ['displayInline'],
|
||||
menuItems: mapped,
|
||||
menuTitle: '',
|
||||
};
|
||||
} else {
|
||||
return menuItemMapped({ action });
|
||||
}
|
||||
}),
|
||||
[props.actions, menuItemMapped],
|
||||
);
|
||||
|
||||
const handlePressMenuItem = useCallback(
|
||||
({ nativeEvent }: { nativeEvent: { actionKey: string } }) => {
|
||||
onPressMenuItem(nativeEvent.actionKey);
|
||||
},
|
||||
[onPressMenuItem],
|
||||
);
|
||||
|
||||
const renderContextMenuButton = () => (
|
||||
<ContextMenuButton
|
||||
ref={ref}
|
||||
onMenuWillShow={onMenuWillShow}
|
||||
onMenuWillHide={onMenuWillHide}
|
||||
useActionSheetFallback={false}
|
||||
onPressMenuItem={handlePressMenuItem}
|
||||
isMenuPrimaryAction={isMenuPrimaryAction}
|
||||
menuConfig={{
|
||||
menuTitle: title,
|
||||
menuItems,
|
||||
}}
|
||||
{...restProps}
|
||||
style={buttonStyle}
|
||||
>
|
||||
<TouchableOpacity onPress={onPress} disabled={disabled} accessibilityRole="button" {...restProps}>
|
||||
{props.children}
|
||||
</TouchableOpacity>
|
||||
</ContextMenuButton>
|
||||
);
|
||||
|
||||
const renderContextMenuView = () => (
|
||||
<ContextMenuView
|
||||
ref={ref}
|
||||
lazyPreview
|
||||
shouldEnableAggressiveCleanup
|
||||
internalCleanupMode="automatic"
|
||||
onPressMenuItem={handlePressMenuItem}
|
||||
useActionSheetFallback={false}
|
||||
menuConfig={{
|
||||
menuTitle: title,
|
||||
menuItems,
|
||||
}}
|
||||
{...(renderPreview
|
||||
? {
|
||||
previewConfig: {
|
||||
previewType: 'CUSTOM',
|
||||
backgroundColor: 'white',
|
||||
},
|
||||
renderPreview: renderPreview as RenderItem,
|
||||
}
|
||||
: {})}
|
||||
>
|
||||
{onPress ? (
|
||||
<TouchableOpacity accessibilityRole="button" onPress={onPress} {...restProps}>
|
||||
{props.children}
|
||||
</TouchableOpacity>
|
||||
) : (
|
||||
props.children
|
||||
)}
|
||||
</ContextMenuView>
|
||||
);
|
||||
|
||||
return isMenuPrimaryAction && onPress ? (
|
||||
<TouchableOpacity onPress={onPress} disabled={disabled} accessibilityRole="button" {...restProps}>
|
||||
{renderContextMenuButton()}
|
||||
</TouchableOpacity>
|
||||
) : isButton ? (
|
||||
renderContextMenuButton()
|
||||
) : (
|
||||
renderContextMenuView()
|
||||
);
|
||||
};
|
||||
|
||||
const ToolTipMenu = forwardRef(BaseToolTipMenu);
|
||||
|
||||
export default ToolTipMenu;
|
@ -1,12 +1,144 @@
|
||||
import { forwardRef, Ref } from 'react';
|
||||
import React, { Ref, useCallback, useMemo } from 'react';
|
||||
import { Platform, Pressable, TouchableOpacity, View } from 'react-native';
|
||||
import { ContextMenuView, RenderItem, OnPressMenuItemEventObject, MenuState, IconConfig } from 'react-native-ios-context-menu';
|
||||
import { MenuView, MenuAction, NativeActionEvent } from '@react-native-menu/menu';
|
||||
import { ToolTipMenuProps, Action } from './types';
|
||||
|
||||
import { ToolTipMenuProps } from './types';
|
||||
const ToolTipMenu = React.memo((props: ToolTipMenuProps, ref?: Ref<any>) => {
|
||||
const {
|
||||
title = '',
|
||||
isMenuPrimaryAction = false,
|
||||
renderPreview,
|
||||
disabled = false,
|
||||
onPress,
|
||||
onMenuWillShow,
|
||||
onMenuWillHide,
|
||||
buttonStyle,
|
||||
onPressMenuItem,
|
||||
children,
|
||||
isButton = false,
|
||||
...restProps
|
||||
} = props;
|
||||
|
||||
const BaseToolTipMenu = (props: ToolTipMenuProps, ref: Ref<any>) => {
|
||||
console.debug('ToolTipMenu.tsx ref:', ref);
|
||||
return props.children;
|
||||
};
|
||||
const mapMenuItemForContextMenuView = useCallback((action: Action) => {
|
||||
return {
|
||||
actionKey: action.id.toString(),
|
||||
actionTitle: action.text,
|
||||
icon: action.icon?.iconValue ? ({ iconType: 'SYSTEM', iconValue: action.icon.iconValue } as IconConfig) : undefined,
|
||||
state: action.menuStateOn ? ('on' as MenuState) : ('off' as MenuState),
|
||||
attributes: action.disabled ? ['disabled'] : [],
|
||||
};
|
||||
}, []);
|
||||
|
||||
const ToolTipMenu = forwardRef(BaseToolTipMenu);
|
||||
const mapMenuItemForMenuView = useCallback((action: Action): MenuAction => {
|
||||
return {
|
||||
id: action.id.toString(),
|
||||
title: action.text,
|
||||
image: action.menuStateOn && Platform.OS === 'android' ? 'checkbox_on_background' : action.icon?.iconValue || undefined,
|
||||
state: action.menuStateOn ? ('on' as MenuState) : undefined,
|
||||
attributes: { disabled: action.disabled },
|
||||
};
|
||||
}, []);
|
||||
|
||||
const contextMenuItems = useMemo(() => {
|
||||
const flattenedActions = props.actions.flat();
|
||||
return flattenedActions.map(mapMenuItemForContextMenuView);
|
||||
}, [props.actions, mapMenuItemForContextMenuView]);
|
||||
|
||||
const menuViewItemsIOS = useMemo(() => {
|
||||
return props.actions.map(actionGroup => {
|
||||
if (Array.isArray(actionGroup)) {
|
||||
return {
|
||||
id: actionGroup[0].id.toString(),
|
||||
title: '',
|
||||
subactions: actionGroup.map(mapMenuItemForMenuView),
|
||||
displayInline: true,
|
||||
};
|
||||
} else {
|
||||
return mapMenuItemForMenuView(actionGroup);
|
||||
}
|
||||
});
|
||||
}, [props.actions, mapMenuItemForMenuView]);
|
||||
|
||||
const menuViewItemsAndroid = useMemo(() => {
|
||||
const mergedActions = props.actions.flat();
|
||||
return mergedActions.map(mapMenuItemForMenuView);
|
||||
}, [props.actions, mapMenuItemForMenuView]);
|
||||
|
||||
const handlePressMenuItemForContextMenuView = useCallback(
|
||||
(event: OnPressMenuItemEventObject) => {
|
||||
onPressMenuItem(event.nativeEvent.actionKey);
|
||||
},
|
||||
[onPressMenuItem],
|
||||
);
|
||||
|
||||
const handlePressMenuItemForMenuView = useCallback(
|
||||
({ nativeEvent }: NativeActionEvent) => {
|
||||
onPressMenuItem(nativeEvent.event);
|
||||
},
|
||||
[onPressMenuItem],
|
||||
);
|
||||
|
||||
const renderContextMenuView = () => {
|
||||
console.debug('ToolTipMenu.tsx rendering: renderContextMenuView');
|
||||
return (
|
||||
<ContextMenuView
|
||||
lazyPreview
|
||||
shouldEnableAggressiveCleanup
|
||||
internalCleanupMode="automatic"
|
||||
onPressMenuItem={handlePressMenuItemForContextMenuView}
|
||||
onMenuWillShow={onMenuWillShow}
|
||||
onMenuWillHide={onMenuWillHide}
|
||||
useActionSheetFallback={false}
|
||||
menuConfig={{
|
||||
menuTitle: title,
|
||||
menuItems: contextMenuItems,
|
||||
}}
|
||||
{...(renderPreview
|
||||
? {
|
||||
previewConfig: {
|
||||
previewType: 'CUSTOM',
|
||||
backgroundColor: 'white',
|
||||
},
|
||||
renderPreview: renderPreview as RenderItem,
|
||||
}
|
||||
: {})}
|
||||
>
|
||||
{onPress ? (
|
||||
<Pressable accessibilityRole="button" onPress={onPress} {...restProps}>
|
||||
{children}
|
||||
</Pressable>
|
||||
) : (
|
||||
children
|
||||
)}
|
||||
</ContextMenuView>
|
||||
);
|
||||
};
|
||||
|
||||
const renderMenuView = () => {
|
||||
console.debug('ToolTipMenu.tsx rendering: renderMenuView');
|
||||
return (
|
||||
<View>
|
||||
<MenuView
|
||||
title={title}
|
||||
isAnchoredToRight
|
||||
onPressAction={handlePressMenuItemForMenuView}
|
||||
actions={Platform.OS === 'ios' ? menuViewItemsIOS : menuViewItemsAndroid}
|
||||
shouldOpenOnLongPress={!isMenuPrimaryAction}
|
||||
>
|
||||
{isMenuPrimaryAction || isButton ? (
|
||||
<TouchableOpacity style={buttonStyle} disabled={disabled} onPress={onPress} {...restProps}>
|
||||
{children}
|
||||
</TouchableOpacity>
|
||||
) : (
|
||||
children
|
||||
)}
|
||||
</MenuView>
|
||||
</View>
|
||||
);
|
||||
};
|
||||
|
||||
return Platform.OS === 'ios' && renderPreview ? renderContextMenuView() : renderMenuView();
|
||||
});
|
||||
|
||||
export default ToolTipMenu;
|
||||
|
@ -16,12 +16,12 @@ import { BitcoinUnit } from '../models/bitcoinUnits';
|
||||
import { useSettings } from '../hooks/context/useSettings';
|
||||
import ListItem from './ListItem';
|
||||
import { useTheme } from './themes';
|
||||
import ToolTipMenu from './TooltipMenu';
|
||||
import { Action, ToolTipMenuProps } from './types';
|
||||
import { useExtendedNavigation } from '../hooks/useExtendedNavigation';
|
||||
import { NativeStackNavigationProp } from '@react-navigation/native-stack';
|
||||
import { DetailViewStackParamList } from '../navigation/DetailViewStackParamList';
|
||||
import { useStorage } from '../hooks/context/useStorage';
|
||||
import ToolTipMenu from './TooltipMenu';
|
||||
|
||||
interface TransactionListItemProps {
|
||||
itemPriceUnit: BitcoinUnit;
|
||||
@ -339,7 +339,7 @@ export const TransactionListItem: React.FC<TransactionListItemProps> = React.mem
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [item.hash, subtitle, rowTitle, subtitleNumberOfLines, txMetadata]);
|
||||
return (
|
||||
<ToolTipMenu ref={menuRef} actions={toolTipActions} onPressMenuItem={onToolTipPress} onPress={onPress}>
|
||||
<ToolTipMenu isButton actions={toolTipActions} onPressMenuItem={onToolTipPress} onPress={onPress}>
|
||||
<ListItem
|
||||
leftAvatar={avatar}
|
||||
title={title}
|
||||
@ -367,23 +367,18 @@ const actionKeys = {
|
||||
|
||||
const actionIcons = {
|
||||
Eye: {
|
||||
iconType: 'SYSTEM',
|
||||
iconValue: 'eye',
|
||||
},
|
||||
EyeSlash: {
|
||||
iconType: 'SYSTEM',
|
||||
iconValue: 'eye.slash',
|
||||
},
|
||||
Clipboard: {
|
||||
iconType: 'SYSTEM',
|
||||
iconValue: 'doc.on.doc',
|
||||
},
|
||||
Link: {
|
||||
iconType: 'SYSTEM',
|
||||
iconValue: 'link',
|
||||
},
|
||||
Note: {
|
||||
iconType: 'SYSTEM',
|
||||
iconValue: 'note.text',
|
||||
},
|
||||
};
|
||||
|
@ -1,8 +1,7 @@
|
||||
import Clipboard from '@react-native-clipboard/clipboard';
|
||||
import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
||||
import Clipboard from '@react-native-clipboard/clipboard';
|
||||
import { I18nManager, Image, LayoutAnimation, StyleSheet, Text, TouchableOpacity, View } from 'react-native';
|
||||
import LinearGradient from 'react-native-linear-gradient';
|
||||
|
||||
import { LightningCustodianWallet, LightningLdkWallet, MultisigHDWallet } from '../class';
|
||||
import WalletGradient from '../class/wallet-gradient';
|
||||
import { TWallet } from '../class/wallets/types';
|
||||
@ -11,8 +10,8 @@ import { BitcoinUnit } from '../models/bitcoinUnits';
|
||||
import { FiatUnit } from '../models/fiatUnit';
|
||||
import { BlurredBalanceView } from './BlurredBalanceView';
|
||||
import { useSettings } from '../hooks/context/useSettings';
|
||||
import ToolTipMenu from './TooltipMenu';
|
||||
import { ToolTipMenuProps } from './types';
|
||||
import ToolTipMenu from './TooltipMenu';
|
||||
|
||||
interface TransactionsNavigationHeaderProps {
|
||||
wallet: TWallet;
|
||||
@ -64,16 +63,16 @@ const TransactionsNavigationHeader: React.FC<TransactionsNavigationHeaderProps>
|
||||
verifyIfWalletAllowsOnchainAddress();
|
||||
}, [wallet, verifyIfWalletAllowsOnchainAddress]);
|
||||
|
||||
const handleCopyPress = () => {
|
||||
const handleCopyPress = useCallback(() => {
|
||||
const value = formatBalance(wallet.getBalance(), wallet.getPreferredBalanceUnit());
|
||||
if (value) {
|
||||
Clipboard.setString(value);
|
||||
}
|
||||
};
|
||||
}, [wallet]);
|
||||
|
||||
const handleBalanceVisibility = () => {
|
||||
const handleBalanceVisibility = useCallback(() => {
|
||||
onWalletBalanceVisibilityChange?.(!wallet.hideBalance);
|
||||
};
|
||||
}, [onWalletBalanceVisibilityChange, wallet.hideBalance]);
|
||||
|
||||
const updateWalletWithNewUnit = (w: TWallet, newPreferredUnit: BitcoinUnit) => {
|
||||
w.preferredBalanceUnit = newPreferredUnit;
|
||||
@ -101,19 +100,40 @@ const TransactionsNavigationHeader: React.FC<TransactionsNavigationHeaderProps>
|
||||
onWalletUnitChange?.(updatedWallet);
|
||||
};
|
||||
|
||||
const handleManageFundsPressed = (actionKeyID?: string) => {
|
||||
if (onManageFundsPressed) {
|
||||
onManageFundsPressed(actionKeyID);
|
||||
}
|
||||
};
|
||||
const handleManageFundsPressed = useCallback(
|
||||
(actionKeyID?: string) => {
|
||||
if (onManageFundsPressed) {
|
||||
onManageFundsPressed(actionKeyID);
|
||||
}
|
||||
},
|
||||
[onManageFundsPressed],
|
||||
);
|
||||
|
||||
const onPressMenuItem = (id: string) => {
|
||||
if (id === 'walletBalanceVisibility') {
|
||||
handleBalanceVisibility();
|
||||
} else if (id === 'copyToClipboard') {
|
||||
handleCopyPress();
|
||||
}
|
||||
};
|
||||
const onPressMenuItem = useCallback(
|
||||
(id: string) => {
|
||||
if (id === 'walletBalanceVisibility') {
|
||||
handleBalanceVisibility();
|
||||
} else if (id === 'copyToClipboard') {
|
||||
handleCopyPress();
|
||||
}
|
||||
},
|
||||
[handleBalanceVisibility, handleCopyPress],
|
||||
);
|
||||
|
||||
const toolTipActions = useMemo(() => {
|
||||
return [
|
||||
{
|
||||
id: actionKeys.Refill,
|
||||
text: loc.lnd.refill,
|
||||
icon: actionIcons.Refill,
|
||||
},
|
||||
{
|
||||
id: actionKeys.RefillWithExternalWallet,
|
||||
text: loc.lnd.refill_external,
|
||||
icon: actionIcons.RefillWithExternalWallet,
|
||||
},
|
||||
];
|
||||
}, []);
|
||||
|
||||
const balance = useMemo(() => {
|
||||
const hideBalance = wallet.hideBalance;
|
||||
@ -126,6 +146,35 @@ const TransactionsNavigationHeader: React.FC<TransactionsNavigationHeaderProps>
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [wallet.hideBalance, wallet.getPreferredBalanceUnit()]);
|
||||
|
||||
const toolTipWalletBalanceActions = useMemo(() => {
|
||||
return wallet.hideBalance
|
||||
? [
|
||||
{
|
||||
id: 'walletBalanceVisibility',
|
||||
text: loc.transactions.details_balance_show,
|
||||
icon: {
|
||||
iconValue: 'eye',
|
||||
},
|
||||
},
|
||||
]
|
||||
: [
|
||||
{
|
||||
id: 'walletBalanceVisibility',
|
||||
text: loc.transactions.details_balance_hide,
|
||||
icon: {
|
||||
iconValue: 'eye.slash',
|
||||
},
|
||||
},
|
||||
{
|
||||
id: 'copyToClipboard',
|
||||
text: loc.transactions.details_copy,
|
||||
icon: {
|
||||
iconValue: 'doc.on.doc',
|
||||
},
|
||||
},
|
||||
];
|
||||
}, [wallet.hideBalance]);
|
||||
|
||||
return (
|
||||
<LinearGradient
|
||||
colors={WalletGradient.gradientsFor(wallet.type)}
|
||||
@ -155,40 +204,9 @@ const TransactionsNavigationHeader: React.FC<TransactionsNavigationHeaderProps>
|
||||
isMenuPrimaryAction
|
||||
isButton
|
||||
enableAndroidRipple={false}
|
||||
ref={menuRef}
|
||||
buttonStyle={styles.walletBalance}
|
||||
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',
|
||||
},
|
||||
},
|
||||
]
|
||||
}
|
||||
actions={toolTipWalletBalanceActions}
|
||||
>
|
||||
<View style={styles.walletBalance}>
|
||||
{wallet.hideBalance ? (
|
||||
@ -223,18 +241,7 @@ const TransactionsNavigationHeader: React.FC<TransactionsNavigationHeaderProps>
|
||||
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,
|
||||
},
|
||||
]}
|
||||
actions={toolTipActions}
|
||||
buttonStyle={styles.manageFundsButton}
|
||||
>
|
||||
<Text style={styles.manageFundsButtonText}>{loc.lnd.title}</Text>
|
||||
@ -333,23 +340,18 @@ export const actionKeys = {
|
||||
|
||||
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',
|
||||
},
|
||||
};
|
||||
|
@ -1,4 +1,4 @@
|
||||
import React, { useMemo, useRef } from 'react';
|
||||
import React, { useMemo } from 'react';
|
||||
import Clipboard from '@react-native-clipboard/clipboard';
|
||||
import { useNavigation } from '@react-navigation/native';
|
||||
import { StyleSheet, Text, View } from 'react-native';
|
||||
@ -12,12 +12,12 @@ import { BitcoinUnit } from '../../models/bitcoinUnits';
|
||||
import presentAlert from '../Alert';
|
||||
import QRCodeComponent from '../QRCodeComponent';
|
||||
import { useTheme } from '../themes';
|
||||
import TooltipMenu from '../TooltipMenu';
|
||||
import { Action, ToolTipMenuProps } from '../types';
|
||||
import { Action } from '../types';
|
||||
import { AddressTypeBadge } from './AddressTypeBadge';
|
||||
import { NativeStackNavigationProp } from '@react-navigation/native-stack';
|
||||
import { DetailViewStackParamList } from '../../navigation/DetailViewStackParamList';
|
||||
import { useStorage } from '../../hooks/context/useStorage';
|
||||
import ToolTipMenu from '../TooltipMenu';
|
||||
|
||||
interface AddressItemProps {
|
||||
// todo: fix `any` after addresses.js is converted to the church of holy typescript
|
||||
@ -57,16 +57,7 @@ const AddressItem = ({ item, balanceUnit, walletID, allowSignVerifyMessage }: Ad
|
||||
|
||||
const { navigate } = useNavigation<NavigationProps>();
|
||||
|
||||
const menuRef = useRef<ToolTipMenuProps>();
|
||||
|
||||
const dismissMenu = () => {
|
||||
if (menuRef.current?.dismissMenu) {
|
||||
menuRef.current.dismissMenu();
|
||||
}
|
||||
};
|
||||
|
||||
const navigateToReceive = () => {
|
||||
dismissMenu();
|
||||
navigate('ReceiveDetailsRoot', {
|
||||
screen: 'ReceiveDetails',
|
||||
params: {
|
||||
@ -77,7 +68,6 @@ const AddressItem = ({ item, balanceUnit, walletID, allowSignVerifyMessage }: Ad
|
||||
};
|
||||
|
||||
const navigateToSignVerify = () => {
|
||||
dismissMenu();
|
||||
navigate('SignVerifyRoot', {
|
||||
screen: 'SignVerify',
|
||||
params: {
|
||||
@ -145,13 +135,13 @@ const AddressItem = ({ item, balanceUnit, walletID, allowSignVerifyMessage }: Ad
|
||||
|
||||
const render = () => {
|
||||
return (
|
||||
<TooltipMenu
|
||||
<ToolTipMenu
|
||||
title={item.address}
|
||||
ref={menuRef}
|
||||
actions={menuActions}
|
||||
onPressMenuItem={onToolTipPress}
|
||||
renderPreview={renderPreview}
|
||||
onPress={navigateToReceive}
|
||||
isButton
|
||||
>
|
||||
<ListItem key={item.key} containerStyle={stylesHook.container}>
|
||||
<ListItem.Content style={stylesHook.list}>
|
||||
@ -170,7 +160,7 @@ const AddressItem = ({ item, balanceUnit, walletID, allowSignVerifyMessage }: Ad
|
||||
</Text>
|
||||
</View>
|
||||
</ListItem>
|
||||
</TooltipMenu>
|
||||
</ToolTipMenu>
|
||||
);
|
||||
};
|
||||
|
||||
@ -186,19 +176,15 @@ const actionKeys = {
|
||||
|
||||
const actionIcons = {
|
||||
Signature: {
|
||||
iconType: 'SYSTEM',
|
||||
iconValue: 'signature',
|
||||
},
|
||||
Share: {
|
||||
iconType: 'SYSTEM',
|
||||
iconValue: 'square.and.arrow.up',
|
||||
},
|
||||
Clipboard: {
|
||||
iconType: 'SYSTEM',
|
||||
iconValue: 'doc.on.doc',
|
||||
},
|
||||
ExportPrivateKey: {
|
||||
iconType: 'SYSTEM',
|
||||
iconValue: 'key',
|
||||
},
|
||||
};
|
||||
|
@ -3,13 +3,13 @@ import { AccessibilityRole, ViewStyle } from 'react-native';
|
||||
export interface Action {
|
||||
id: string | number;
|
||||
text: string;
|
||||
icon: {
|
||||
iconType: string;
|
||||
icon?: {
|
||||
iconValue: string;
|
||||
};
|
||||
menuTitle?: string;
|
||||
menuStateOn?: boolean;
|
||||
disabled?: boolean;
|
||||
displayInline?: boolean;
|
||||
}
|
||||
|
||||
export interface ToolTipMenuProps {
|
||||
@ -30,7 +30,7 @@ export interface ToolTipMenuProps {
|
||||
style?: ViewStyle | ViewStyle[];
|
||||
accessibilityLabel?: string;
|
||||
accessibilityHint?: string;
|
||||
buttonStyle?: ViewStyle;
|
||||
buttonStyle?: ViewStyle | ViewStyle[];
|
||||
onMenuWillShow?: () => void;
|
||||
onMenuWillHide?: () => void;
|
||||
}
|
||||
|
@ -169,7 +169,7 @@
|
||||
B4D0B2682C1DED67006B6B1B /* ReceiveMethod.swift in Sources */ = {isa = PBXBuildFile; fileRef = B4D0B2672C1DED67006B6B1B /* ReceiveMethod.swift */; };
|
||||
B4EE583C226703320003363C /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = B40D4E35225841ED00428FCC /* Assets.xcassets */; };
|
||||
C59F90CE0D04D3E4BB39BC5D /* libPods-BlueWalletUITests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 6F02C2F7CA3591E4E0B06EBA /* libPods-BlueWalletUITests.a */; };
|
||||
C978A716948AB7DEC5B6F677 /* (null) in Frameworks */ = {isa = PBXBuildFile; };
|
||||
C978A716948AB7DEC5B6F677 /* BuildFile in Frameworks */ = {isa = PBXBuildFile; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXContainerItemProxy section */
|
||||
@ -491,7 +491,7 @@
|
||||
files = (
|
||||
782F075B5DD048449E2DECE9 /* libz.tbd in Frameworks */,
|
||||
764B49B1420D4AEB8109BF62 /* libsqlite3.0.tbd in Frameworks */,
|
||||
C978A716948AB7DEC5B6F677 /* (null) in Frameworks */,
|
||||
C978A716948AB7DEC5B6F677 /* BuildFile in Frameworks */,
|
||||
773E382FE62E836172AAB98B /* libPods-BlueWallet.a in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
@ -1156,9 +1156,9 @@
|
||||
);
|
||||
mainGroup = 83CBB9F61A601CBA00E9B192;
|
||||
packageReferences = (
|
||||
6DFC806E24EA0B6C007B8700 /* XCRemoteSwiftPackageReference "EFQRCode" */,
|
||||
6DFC806E24EA0B6C007B8700 /* XCRemoteSwiftPackageReference "EFQRCode.git" */,
|
||||
B41B76832B66B2FF002C48D5 /* XCRemoteSwiftPackageReference "bugsnag-cocoa" */,
|
||||
B48A6A272C1DF01000030AB9 /* XCRemoteSwiftPackageReference "keychain-swift" */,
|
||||
B48A6A272C1DF01000030AB9 /* XCRemoteSwiftPackageReference "keychain-swift.git" */,
|
||||
);
|
||||
productRefGroup = 83CBBA001A601CBA00E9B192 /* Products */;
|
||||
projectDirPath = "";
|
||||
@ -1839,7 +1839,7 @@
|
||||
SUPPORTS_XR_DESIGNED_FOR_IPHONE_IPAD = NO;
|
||||
SWIFT_OBJC_BRIDGING_HEADER = "BlueWallet-Bridging-Header.h";
|
||||
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
||||
SWIFT_VERSION = 4.2;
|
||||
SWIFT_VERSION = 5.0;
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
VERSIONING_SYSTEM = "apple-generic";
|
||||
};
|
||||
@ -1893,7 +1893,7 @@
|
||||
SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO;
|
||||
SUPPORTS_XR_DESIGNED_FOR_IPHONE_IPAD = NO;
|
||||
SWIFT_OBJC_BRIDGING_HEADER = "BlueWallet-Bridging-Header.h";
|
||||
SWIFT_VERSION = 4.2;
|
||||
SWIFT_VERSION = 5.0;
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
VERSIONING_SYSTEM = "apple-generic";
|
||||
};
|
||||
@ -2150,7 +2150,7 @@
|
||||
OTHER_LDFLAGS = "$(inherited)";
|
||||
REACT_NATIVE_PATH = "${PODS_ROOT}/../../node_modules/react-native";
|
||||
SDKROOT = iphoneos;
|
||||
SWIFT_VERSION = 4.2;
|
||||
SWIFT_VERSION = 5.0;
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
@ -2208,7 +2208,7 @@
|
||||
REACT_NATIVE_PATH = "${PODS_ROOT}/../../node_modules/react-native";
|
||||
SDKROOT = iphoneos;
|
||||
SWIFT_COMPILATION_MODE = wholemodule;
|
||||
SWIFT_VERSION = 4.2;
|
||||
SWIFT_VERSION = 5.0;
|
||||
VALIDATE_PRODUCT = YES;
|
||||
};
|
||||
name = Release;
|
||||
@ -2352,7 +2352,7 @@
|
||||
SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
|
||||
SWIFT_OBJC_BRIDGING_HEADER = "WalletInformationWidget/Widgets/Shared/BlueWalletWatch-Bridging-Header.h";
|
||||
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
||||
SWIFT_VERSION = 4.2;
|
||||
SWIFT_VERSION = 5.0;
|
||||
TARGETED_DEVICE_FAMILY = 4;
|
||||
WATCHOS_DEPLOYMENT_TARGET = 7.0;
|
||||
};
|
||||
@ -2399,7 +2399,7 @@
|
||||
SWIFT_COMPILATION_MODE = wholemodule;
|
||||
SWIFT_OBJC_BRIDGING_HEADER = "WalletInformationWidget/Widgets/Shared/BlueWalletWatch-Bridging-Header.h";
|
||||
SWIFT_OPTIMIZATION_LEVEL = "-O";
|
||||
SWIFT_VERSION = 4.2;
|
||||
SWIFT_VERSION = 5.0;
|
||||
TARGETED_DEVICE_FAMILY = 4;
|
||||
WATCHOS_DEPLOYMENT_TARGET = 7.0;
|
||||
};
|
||||
@ -2547,7 +2547,7 @@
|
||||
SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO;
|
||||
SWIFT_OBJC_BRIDGING_HEADER = "BlueWallet-Bridging-Header.h";
|
||||
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
||||
SWIFT_VERSION = 4.2;
|
||||
SWIFT_VERSION = 5.0;
|
||||
TARGETED_DEVICE_FAMILY = "1,2,6";
|
||||
VERSIONING_SYSTEM = "apple-generic";
|
||||
};
|
||||
@ -2595,7 +2595,7 @@
|
||||
SUPPORTS_MACCATALYST = YES;
|
||||
SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO;
|
||||
SWIFT_OBJC_BRIDGING_HEADER = "BlueWallet-Bridging-Header.h";
|
||||
SWIFT_VERSION = 4.2;
|
||||
SWIFT_VERSION = 5.0;
|
||||
TARGETED_DEVICE_FAMILY = "1,2,6";
|
||||
VERSIONING_SYSTEM = "apple-generic";
|
||||
};
|
||||
@ -2679,7 +2679,7 @@
|
||||
/* End XCConfigurationList section */
|
||||
|
||||
/* Begin XCRemoteSwiftPackageReference section */
|
||||
6DFC806E24EA0B6C007B8700 /* XCRemoteSwiftPackageReference "EFQRCode" */ = {
|
||||
6DFC806E24EA0B6C007B8700 /* XCRemoteSwiftPackageReference "EFQRCode.git" */ = {
|
||||
isa = XCRemoteSwiftPackageReference;
|
||||
repositoryURL = "https://github.com/EFPrefix/EFQRCode.git";
|
||||
requirement = {
|
||||
@ -2695,7 +2695,7 @@
|
||||
version = 6.28.1;
|
||||
};
|
||||
};
|
||||
B48A6A272C1DF01000030AB9 /* XCRemoteSwiftPackageReference "keychain-swift" */ = {
|
||||
B48A6A272C1DF01000030AB9 /* XCRemoteSwiftPackageReference "keychain-swift.git" */ = {
|
||||
isa = XCRemoteSwiftPackageReference;
|
||||
repositoryURL = "https://github.com/evgenyneu/keychain-swift.git";
|
||||
requirement = {
|
||||
@ -2708,7 +2708,7 @@
|
||||
/* Begin XCSwiftPackageProductDependency section */
|
||||
6DFC806F24EA0B6C007B8700 /* EFQRCode */ = {
|
||||
isa = XCSwiftPackageProductDependency;
|
||||
package = 6DFC806E24EA0B6C007B8700 /* XCRemoteSwiftPackageReference "EFQRCode" */;
|
||||
package = 6DFC806E24EA0B6C007B8700 /* XCRemoteSwiftPackageReference "EFQRCode.git" */;
|
||||
productName = EFQRCode;
|
||||
};
|
||||
B41B76842B66B2FF002C48D5 /* Bugsnag */ = {
|
||||
@ -2723,7 +2723,7 @@
|
||||
};
|
||||
B48A6A282C1DF01000030AB9 /* KeychainSwift */ = {
|
||||
isa = XCSwiftPackageProductDependency;
|
||||
package = B48A6A272C1DF01000030AB9 /* XCRemoteSwiftPackageReference "keychain-swift" */;
|
||||
package = B48A6A272C1DF01000030AB9 /* XCRemoteSwiftPackageReference "keychain-swift.git" */;
|
||||
productName = KeychainSwift;
|
||||
};
|
||||
/* End XCSwiftPackageProductDependency section */
|
||||
|
@ -339,6 +339,8 @@ PODS:
|
||||
- React-Core
|
||||
- react-native-ios-context-menu (1.15.3):
|
||||
- React-Core
|
||||
- react-native-menu (1.1.2):
|
||||
- React
|
||||
- react-native-qrcode-local-image (1.0.4):
|
||||
- React
|
||||
- react-native-randombytes (3.6.1):
|
||||
@ -551,6 +553,7 @@ DEPENDENCIES:
|
||||
- react-native-idle-timer (from `../node_modules/react-native-idle-timer`)
|
||||
- react-native-image-picker (from `../node_modules/react-native-image-picker`)
|
||||
- react-native-ios-context-menu (from `../node_modules/react-native-ios-context-menu`)
|
||||
- "react-native-menu (from `../node_modules/@react-native-menu/menu`)"
|
||||
- "react-native-qrcode-local-image (from `../node_modules/@remobile/react-native-qrcode-local-image`)"
|
||||
- react-native-randombytes (from `../node_modules/react-native-randombytes`)
|
||||
- react-native-safe-area-context (from `../node_modules/react-native-safe-area-context`)
|
||||
@ -670,6 +673,8 @@ EXTERNAL SOURCES:
|
||||
:path: "../node_modules/react-native-image-picker"
|
||||
react-native-ios-context-menu:
|
||||
:path: "../node_modules/react-native-ios-context-menu"
|
||||
react-native-menu:
|
||||
:path: "../node_modules/@react-native-menu/menu"
|
||||
react-native-qrcode-local-image:
|
||||
:path: "../node_modules/@remobile/react-native-qrcode-local-image"
|
||||
react-native-randombytes:
|
||||
@ -801,6 +806,7 @@ SPEC CHECKSUMS:
|
||||
react-native-idle-timer: ee2053f2cd458f6fef1db7bebe5098ca281cce07
|
||||
react-native-image-picker: 1889c342e6a4ba089ff11ae0c3bf5cc30a3134d0
|
||||
react-native-ios-context-menu: e529171ba760a1af7f2ef0729f5a7f4d226171c5
|
||||
react-native-menu: d32728a357dfb360cf01cd5979cf7713c5acbb95
|
||||
react-native-qrcode-local-image: 35ccb306e4265bc5545f813e54cc830b5d75bcfc
|
||||
react-native-randombytes: 421f1c7d48c0af8dbcd471b0324393ebf8fe7846
|
||||
react-native-safe-area-context: a240ad4b683349e48b1d51fed1611138d1bdad97
|
||||
|
15
package-lock.json
generated
15
package-lock.json
generated
@ -19,6 +19,7 @@
|
||||
"@react-native-async-storage/async-storage": "1.23.1",
|
||||
"@react-native-clipboard/clipboard": "1.14.1",
|
||||
"@react-native-community/push-notification-ios": "1.11.0",
|
||||
"@react-native-menu/menu": "1.1.2",
|
||||
"@react-navigation/drawer": "6.6.15",
|
||||
"@react-navigation/native": "6.1.17",
|
||||
"@react-navigation/native-stack": "6.9.26",
|
||||
@ -5402,6 +5403,15 @@
|
||||
"react-native": ">=0.58.4"
|
||||
}
|
||||
},
|
||||
"node_modules/@react-native-menu/menu": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/@react-native-menu/menu/-/menu-1.1.2.tgz",
|
||||
"integrity": "sha512-I7JWiwmIwRp+Tee2OJHPwzVKdLjzgUkdChHQ75oyEWo1YcVsXEjLVGmxWCTA6JExzS6SQW/ACmjuXLJFTvu9Pw==",
|
||||
"peerDependencies": {
|
||||
"react": "*",
|
||||
"react-native": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@react-native/assets-registry": {
|
||||
"version": "0.72.0",
|
||||
"resolved": "https://registry.npmjs.org/@react-native/assets-registry/-/assets-registry-0.72.0.tgz",
|
||||
@ -26621,6 +26631,11 @@
|
||||
"invariant": "^2.2.4"
|
||||
}
|
||||
},
|
||||
"@react-native-menu/menu": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/@react-native-menu/menu/-/menu-1.1.2.tgz",
|
||||
"integrity": "sha512-I7JWiwmIwRp+Tee2OJHPwzVKdLjzgUkdChHQ75oyEWo1YcVsXEjLVGmxWCTA6JExzS6SQW/ACmjuXLJFTvu9Pw=="
|
||||
},
|
||||
"@react-native/assets-registry": {
|
||||
"version": "0.72.0",
|
||||
"resolved": "https://registry.npmjs.org/@react-native/assets-registry/-/assets-registry-0.72.0.tgz",
|
||||
|
@ -104,6 +104,7 @@
|
||||
"@react-native-async-storage/async-storage": "1.23.1",
|
||||
"@react-native-clipboard/clipboard": "1.14.1",
|
||||
"@react-native-community/push-notification-ios": "1.11.0",
|
||||
"@react-native-menu/menu": "1.1.2",
|
||||
"@react-navigation/drawer": "6.6.15",
|
||||
"@react-navigation/native": "6.1.17",
|
||||
"@react-navigation/native-stack": "6.9.26",
|
||||
|
@ -271,8 +271,6 @@ const ReceiveDetails = () => {
|
||||
|
||||
const obtainWalletAddress = useCallback(async () => {
|
||||
console.log('receive/details - componentDidMount');
|
||||
wallet.setUserHasSavedExport(true);
|
||||
await saveToDisk();
|
||||
let newAddress;
|
||||
if (address) {
|
||||
setAddressBIP21Encoded(address);
|
||||
|
@ -57,6 +57,7 @@ import { isTablet } from '../../blue_modules/environment';
|
||||
import { useExtendedNavigation } from '../../hooks/useExtendedNavigation';
|
||||
import { ContactList } from '../../class/contact-list';
|
||||
import { useStorage } from '../../hooks/context/useStorage';
|
||||
import { Action } from '../../components/types';
|
||||
|
||||
interface IPaymentDestinations {
|
||||
address: string; // btc address or payment code
|
||||
@ -990,7 +991,7 @@ const SendDetails = () => {
|
||||
};
|
||||
|
||||
const headerRightActions = () => {
|
||||
const actions = [];
|
||||
const actions: Action[] & Action[][] = [];
|
||||
if (isEditable) {
|
||||
if (wallet?.allowBIP47() && wallet?.isBIP47Enabled()) {
|
||||
actions.push([
|
||||
@ -1620,16 +1621,16 @@ SendDetails.actionKeys = {
|
||||
};
|
||||
|
||||
SendDetails.actionIcons = {
|
||||
InsertContact: { iconType: 'SYSTEM', iconValue: 'at.badge.plus' },
|
||||
SignPSBT: { iconType: 'SYSTEM', iconValue: 'signature' },
|
||||
InsertContact: { iconValue: 'at.badge.plus' },
|
||||
SignPSBT: { iconValue: 'signature' },
|
||||
SendMax: 'SendMax',
|
||||
AddRecipient: { iconType: 'SYSTEM', iconValue: 'person.badge.plus' },
|
||||
RemoveRecipient: { iconType: 'SYSTEM', iconValue: 'person.badge.minus' },
|
||||
AddRecipient: { iconValue: 'person.badge.plus' },
|
||||
RemoveRecipient: { iconValue: 'person.badge.minus' },
|
||||
AllowRBF: 'AllowRBF',
|
||||
ImportTransaction: { iconType: 'SYSTEM', iconValue: 'square.and.arrow.down' },
|
||||
ImportTransactionMultsig: { iconType: 'SYSTEM', iconValue: 'square.and.arrow.down.on.square' },
|
||||
ImportTransactionQR: { iconType: 'SYSTEM', iconValue: 'qrcode.viewfinder' },
|
||||
CoinControl: { iconType: 'SYSTEM', iconValue: 'switch.2' },
|
||||
ImportTransaction: { iconValue: 'square.and.arrow.down' },
|
||||
ImportTransactionMultsig: { iconValue: 'square.and.arrow.down.on.square' },
|
||||
ImportTransactionQR: { iconValue: 'qrcode.viewfinder' },
|
||||
CoinControl: { iconValue: 'switch.2' },
|
||||
};
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
|
@ -32,11 +32,9 @@ const actionKeys = {
|
||||
|
||||
const actionIcons = {
|
||||
Clipboard: {
|
||||
iconType: 'SYSTEM',
|
||||
iconValue: 'doc.on.doc',
|
||||
},
|
||||
GoToWallet: {
|
||||
iconType: 'SYSTEM',
|
||||
iconValue: 'wallet.pass',
|
||||
},
|
||||
};
|
||||
|
@ -42,7 +42,6 @@ const actionKeys: Action[] = [
|
||||
id: Actions.pay,
|
||||
text: loc.bip47.pay_this_contact,
|
||||
icon: {
|
||||
iconType: 'SYSTEM',
|
||||
iconValue: 'paperplane',
|
||||
},
|
||||
},
|
||||
@ -50,7 +49,6 @@ const actionKeys: Action[] = [
|
||||
id: Actions.rename,
|
||||
text: loc.bip47.rename_contact,
|
||||
icon: {
|
||||
iconType: 'SYSTEM',
|
||||
iconValue: 'pencil',
|
||||
},
|
||||
},
|
||||
@ -58,7 +56,6 @@ const actionKeys: Action[] = [
|
||||
id: Actions.copyToClipboard,
|
||||
text: loc.bip47.copy_payment_code,
|
||||
icon: {
|
||||
iconType: 'SYSTEM',
|
||||
iconValue: 'doc.on.doc',
|
||||
},
|
||||
},
|
||||
@ -66,7 +63,6 @@ const actionKeys: Action[] = [
|
||||
id: Actions.hide,
|
||||
text: loc.bip47.hide_contact,
|
||||
icon: {
|
||||
iconType: 'SYSTEM',
|
||||
iconValue: 'eye.slash',
|
||||
},
|
||||
},
|
||||
|
@ -200,6 +200,4 @@ jest.mock('react-native-keychain', () => mockKeychain);
|
||||
|
||||
jest.mock('react-native-tcp-socket', () => mockKeychain);
|
||||
|
||||
jest.mock('../components/TooltipMenu.ios.tsx', () => require('../components/TooltipMenu.tsx'));
|
||||
|
||||
global.alert = () => {};
|
||||
|
@ -1,4 +1,3 @@
|
||||
export interface ActionIcons {
|
||||
iconType: 'SYSTEM';
|
||||
iconValue: string;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user