diff --git a/blue_modules/showPopupMenu.android.ts b/blue_modules/showPopupMenu.android.ts deleted file mode 100644 index 3dcdfe16f..000000000 --- a/blue_modules/showPopupMenu.android.ts +++ /dev/null @@ -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; -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; diff --git a/components/TooltipMenu.android.tsx b/components/TooltipMenu.android.tsx index 9689d5a7f..bd4ecf345 100644 --- a/components/TooltipMenu.android.tsx +++ b/components/TooltipMenu.android.tsx @@ -1,14 +1,11 @@ -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 React, { forwardRef, Ref, useCallback, useMemo } from 'react'; +import { Pressable } from 'react-native'; +import { MenuView, NativeActionEvent } from '@react-native-menu/menu'; import { ToolTipMenuProps } from './types'; -const dismissMenu = () => { - console.log('dismissMenu Not implemented'); -}; +// Define a custom type for the nativeEvent parameter + const BaseToolTipMenu = (props: ToolTipMenuProps, ref: Ref<{ dismissMenu?: () => void }>) => { - const menuRef = useRef(null); const { actions, children, @@ -18,57 +15,54 @@ const BaseToolTipMenu = (props: ToolTipMenuProps, ref: Ref<{ dismissMenu?: () => enableAndroidRipple = true, disabled = false, onPress, + title = 'Menu', ...restProps } = props; - const handleToolTipSelection = useCallback( - (selection: PopupMenuItem) => { - if (selection.id) { - onPressMenuItem(selection.id); + const menuItems = useMemo(() => { + return actions.flatMap(action => { + if (Array.isArray(action)) { + return action.map(actionToMap => ({ + id: actionToMap.id.toString(), + title: actionToMap.text, + titleColor: actionToMap.disabled ? 'gray' : 'black', + image: actionToMap.icon.iconValue, + imageColor: actionToMap.disabled ? 'gray' : 'black', + attributes: { disabled: actionToMap.disabled }, + })); + } + return { + id: action.id.toString(), + title: action.text, + titleColor: action.disabled ? 'gray' : 'black', + image: action.icon.iconValue, + imageColor: action.disabled ? 'gray' : 'black', + attributes: { disabled: action.disabled }, + }; + }); + }, [actions]); + + const handleToolTipSelection = useCallback( + ({ nativeEvent }: NativeActionEvent) => { + if (nativeEvent) { + onPressMenuItem(nativeEvent.event); } }, [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 ( - - {children} - + + {} } : { onPress })} + {...restProps} + > + {children} + + ); }; diff --git a/ios/BlueWallet.xcodeproj/project.pbxproj b/ios/BlueWallet.xcodeproj/project.pbxproj index d42a8f0c9..d6483fd06 100644 --- a/ios/BlueWallet.xcodeproj/project.pbxproj +++ b/ios/BlueWallet.xcodeproj/project.pbxproj @@ -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; @@ -1164,9 +1164,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 = ""; @@ -1847,7 +1847,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"; }; @@ -1901,7 +1901,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"; }; @@ -2158,7 +2158,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; }; @@ -2216,7 +2216,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; @@ -2360,7 +2360,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; }; @@ -2407,7 +2407,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; }; @@ -2555,7 +2555,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"; }; @@ -2603,7 +2603,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"; }; @@ -2687,7 +2687,7 @@ /* End XCConfigurationList section */ /* Begin XCRemoteSwiftPackageReference section */ - 6DFC806E24EA0B6C007B8700 /* XCRemoteSwiftPackageReference "EFQRCode" */ = { + 6DFC806E24EA0B6C007B8700 /* XCRemoteSwiftPackageReference "EFQRCode.git" */ = { isa = XCRemoteSwiftPackageReference; repositoryURL = "https://github.com/EFPrefix/EFQRCode.git"; requirement = { @@ -2703,7 +2703,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 = { @@ -2716,7 +2716,7 @@ /* Begin XCSwiftPackageProductDependency section */ 6DFC806F24EA0B6C007B8700 /* EFQRCode */ = { isa = XCSwiftPackageProductDependency; - package = 6DFC806E24EA0B6C007B8700 /* XCRemoteSwiftPackageReference "EFQRCode" */; + package = 6DFC806E24EA0B6C007B8700 /* XCRemoteSwiftPackageReference "EFQRCode.git" */; productName = EFQRCode; }; B41B76842B66B2FF002C48D5 /* Bugsnag */ = { @@ -2731,7 +2731,7 @@ }; B48A6A282C1DF01000030AB9 /* KeychainSwift */ = { isa = XCSwiftPackageProductDependency; - package = B48A6A272C1DF01000030AB9 /* XCRemoteSwiftPackageReference "keychain-swift" */; + package = B48A6A272C1DF01000030AB9 /* XCRemoteSwiftPackageReference "keychain-swift.git" */; productName = KeychainSwift; }; /* End XCSwiftPackageProductDependency section */ diff --git a/ios/Podfile.lock b/ios/Podfile.lock index 2c7150bdb..e3f41c6c6 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -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): @@ -462,7 +464,7 @@ PODS: - React-perflogger (= 0.72.14) - ReactNativeCameraKit (13.0.0): - React-Core - - RealmJS (12.9.0): + - RealmJS (12.10.0): - React - rn-ldk (0.8.4): - React-Core @@ -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: 399a5859f6acbdf67f671c69b53113f535f3b5b0 @@ -824,7 +830,7 @@ SPEC CHECKSUMS: React-utils: 22a77b05da25ce49c744faa82e73856dcae1734e ReactCommon: ff94462e007c568d8cdebc32e3c97af86ec93bb5 ReactNativeCameraKit: 9d46a5d7dd544ca64aa9c03c150d2348faf437eb - RealmJS: 7aa0e7dcc8959d28cee3ab302415a8893e50ad12 + RealmJS: f86da4f2c5b089d976db335f370449903ddc8fbb rn-ldk: 0d8749d98cc5ce67302a32831818c116b67f7643 RNCAsyncStorage: 826b603ae9c0f88b5ac4e956801f755109fa4d5c RNCClipboard: 0a720adef5ec193aa0e3de24c3977222c7e52a37 diff --git a/package-lock.json b/package-lock.json index 3df0967f9..c5ae5346c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -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", @@ -26619,6 +26629,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", diff --git a/package.json b/package.json index 9bb6a6204..c7be0876e 100644 --- a/package.json +++ b/package.json @@ -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",