From 38970012e68440290fbe3546cb75ec19a6d841e6 Mon Sep 17 00:00:00 2001 From: gregs Date: Tue, 22 Oct 2024 14:17:38 -0300 Subject: [PATCH] nfts sort direction (#6068) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * sortDirection * asc/desc menu * imports * imports * i18n * Merge remote-tracking branch origin/develop into gregs/app-1756-sorting-nfts-on-android-is-broken * Merge remote-tracking branch origin/develop into gregs/app-1756-sorting-nfts-on-android-is-broken * fix types * update ts * add back isAnchoredToRight * ?? * grey out the selected option * android * Fix iOS 18 cool-modals context menu bug (#6112) * Fix send crashes / blank screen (#6116) * Fix disabled paste button on Android (#6118) * imageVariants (#6114) * Fix send sheet stuck on loading (#6119) * fix stuck loading phase * Update src/screens/SendSheet.js * fix deleting contact resetting toAddress to undefined * fix some shit with ens names * rm logs * fix failed to send * fix lint * prefer contact name over wallet label * force linter 2 re-rerun --------- Co-authored-by: Bruno Barbieri * Support typing into native inputs in swap (#6100) * Remove unused TODO as build quote params should always rely on the corresponding input output amounts even if native values are updated * Support input native changes in swap inputs controller animated reaction * Temp cleanup on SwapInputAsset to pull out SwapInputAmountCaret and SwapInputNativeAmount * Temp cleanup on SwapOutputAsset to pull out SwapOutputAmountCaret and SwapOutputNativeAmount * Placeholder: generic SwapInputValuesCaret that still need to be hooked up with native inputs * Add caret animatedStyle to SwapInputValuesCaret * Use SwapInputValuesCaret component in SwapInputAsset and SwapOutputAsset * Remove old input and output caret styles from useSwapTextStyles * Cleanup of unused imports in swaps types * Add assetToSellCaretStyle and assetToBuyCaretStyle to caret component * Remove now unused assetToSell/BuyCaretStyles from useAnimatedSwapStyles * Update native input in SwapInputAsset to be typeable * Define size style for native caret in SwapInputValuesCaret * Update swap number pad Remove formatting that isn't a decimal or number on inputs. Previously, we were removing only commas, but now that we support native inputs, we want to remove the native currency symbols. Prevent updating of the native inputs if their is no corresponding price for the input / output asset. * Create separate SwapNativeInput component * Remove unused caret styles from SwapInputAsset and SwapOutputAsset * Add param to ignore alignment for native currency formatting and add handler for basic currency formatting * Update width on nativeCaret * Add support for changes to native output value * Fix missing checks for inputNativeValue and outputNativeValue * Split native currency symbol from value in native input component * Disable caret when correponding asset does not have price for native input * Update formatting for input amount if input method is native inputs * Disable pointer events when no price on native inputs * Distinguish between placeholder values vs typed inputs for native input values * Update checks for color for zero value in swap text styles * Disable focus and pointer events on native output if output based quotes disabled * Support showing explainer if output quotes disabled and user tries to update output native amount * Ignore native input changes if native currency decimals exceeded * Update add decimal in swap number pad to also handle scenarios where there are no native currency decimals * Update South Korea and Japan currencies as they do not use decimals * Fix numbers test after JPY decimal changes * Update numbers test value which should get rounded up * Fix: check for native placeholder value while checking native input decimal places * Fix chainId not being passed in for dapp browser getProvider function (#6121) * Update rainbow provider package to latest 0.1.1 * Fix: getProvider function needs to use an object param * Cleanup * Update arbitrum default back to mainnet for WC message signing (#6122) * Bump deps for Xcode 16 compatibility (#6110) * RN upgrade * update ios files * fixes for android * iOS working fine * bump sentry again * patches and missing dep bump * bump more deps * update lockfile * fix android * changes to pbxproj * revert RN upgrade * new line missing * force linter 2 re-rerun * update pod lock * bump iOS and Android to v1.9.40 (#6131) * Update CI to work with Xcode 16 / iOS 18 (#6129) * omit_from_total (#6103) * Fix speed up and cancel bug (#6133) * change txTo -> to * idk * bump iOS and Android to v1.9.41 (#6136) * MWP (#6142) * mwp compat * prettier * log only if there is an error * Dapp browser url updates fix (#6150) * remove unused import * restrict JS nav from SPA to same domain * clean up * Update src/components/DappBrowser/BrowserTab.tsx * Internal networks filtering (#6148) * filter internal networks out * rm apechains refs * Fix token search crash for newly added chains (#6147) * fix token search crash * rm assets * Claimables [PR #1]: updates to query, types, utils, wallet screen rendering logic + wallet screen components (#6140) * updates to query, types, & wallet screen components * rm onPress * thanks greg * Fix improper gas fee calculation (#6125) * add missing mul to eip1559 * use preferred network if available * another NaN check guard * Claimables [PR #2]: claim panel ui (#6141) * raps * nit * comments * nit * nit * prettier * updates to query, types, & wallet screen components * rm onPress * rm logic * claim panel ui * nav * onPress -> onLongPress * i18n * pending state, i18n * comment * shimmer * tweak gas fee formatting * number formatting * wallet screen number format * route types * do not require long press for goBack * tweak button text * nit * formatting * thanks greg * revert * fix android button width * rm memo * try catch gas * rm functionality from tx * rm rapsv2 * raps v2 (#6138) * raps * nit * comments * nit * nit * prettier * updates to query, types, & wallet screen components * rm onPress * rm logic * thanks greg * Claimables [PR #3]: claim functionality (#6146) * raps * nit * comments * nit * nit * prettier * updates to query, types, & wallet screen components * rm onPress * rm logic * claim panel ui * nav * onPress -> onLongPress * i18n * pending state, i18n * comment * shimmer * functionality * tweak gas fee formatting * number formatting * wallet screen number format * route types * set pending state if no tx hash * do not require long press for goBack * tweak button text * nit * fix pending tx * disable read only wallet * formatting * thanks greg * revert * fix android button width * rm memo * try catch gas * rm functionality from tx * [APP-1907] Add Claiming Status to Pending Claimable TX's (plus types and unused code cleanup) (#6155) * fix: use claim type for pending claimable tx * [APP-1909] Await Claimable TX Before Resolving Rap (#6156) * fix: await claimable tx mining before displaying success * fix: add pending tx prior to waiting for mining * Claimables fixes (#6158) * number formatting * fix border radius for claim dapp icon * poll gas by chain id * haptics * adjust button enabled logic + shadows * fix (#6159) * convert sends to typescript (#6120) * convert sends to typescript * more conversions * fix lint * fix optimism security fee * fix file renaming weirdness * fix rotation from max asset to nft not working * fix some typescript bs * fix lint * fix nft sends * comments watchdog action (#6153) * pod unlock (#6168) * Fix WalletconnectV2 changeAccount issues (#6160) * fix wc v2 change account issues * Update src/walletConnect/index.tsx * Update src/components/walletconnect-list/WalletConnectV2ListItem.tsx * Update src/components/walletconnect-list/WalletConnectV2ListItem.tsx * fix deps array * bump android and iOS to version v1.9.42 (#6170) * fix approval sheet not using verifiedData incoming from walletconnect (#6162) * network expansion (#6149) * init apechain support * fix wrong images * Apply suggestions from code review * Update chain badge * Update chain colors * Add all badge assets * add backend networks runtime * added back internal flag * remove unused NATIVE_ASSETS_PER_CHAIN * fix some discrepancies --------- Co-authored-by: Christian Baroni <7061887+christianbaroni@users.noreply.github.com> * Analytics changes (#6169) * analytics changes * idk * watched wallets cohort + properly track watched wallets * [CHORE]: Walletconnect Approval / Redirect sheet typescript conversion (#6167) * wc ts conversion * remove memo and fix lint * nft expanded state fix crash (#6115) * fix crash * destructure in same line * fix lint issues on develop (#6174) * Fix MWP from failing to prompt if dapp metadata retrieval fails (#6164) * prevent mwp flow from failing if failed to fetch dapp metadata * prevent logging user rejections * ignore logging some user errors * lel wtf (#6166) * WC migration to WalletKit (#6163) * Fix networks crash (#6176) * fix networks crash * remove duplicated walletconnect chain ids * use all supported chains for walletconnect * fix weird space on approval sheet * Update src/screens/WalletConnectApprovalSheet.tsx * hide send button when not transferable (#6123) * Claim button fixes (#6165) * hold -> tap * debounce * fix lint (#6180) * chore: use new fields from swap sdk and remove extraneous code (#6171) * chore: update swaps * chore: replace extraneous crosschain logic with needsAllowance field * chore: get rid of all WRAPPED_ASSET references and use quote swap type * chore: remove swapType as a param to get quotes * chore: replace swap unlock logic with needsAllowance field * chore: code review changes * Zeego Dropdown Menus [MintFilters] (#6143) * zeego setup * bump react-native-menu/menu * fix android settings menu * update deps * fix type inference * mvp to fix android context menus * fix some inconsistencies on Android * remove debug logs * Update src/components/asset-list/RecyclerAssetList2/core/RawRecyclerList.tsx * Update src/components/DropdownMenu.tsx * remove unused deps * fix build maybe * update lock * Claim bug fix (#6182) * fixes * fix experimental config usage * nits * use setTimeout * defaultConfig fix * fix ledger image blocking text * 👍 * lint * lint --------- Co-authored-by: Christian Baroni <7061887+christianbaroni@users.noreply.github.com> Co-authored-by: Matthew Wall Co-authored-by: Bruno Barbieri Co-authored-by: Jin Co-authored-by: Bruno Barbieri <1247834+brunobar79@users.noreply.github.com> Co-authored-by: Ibrahim Taveras Co-authored-by: Ben Goldberg Co-authored-by: Christopher Howard Co-authored-by: Wayne Cheng <677680+welps@users.noreply.github.com> --- ios/Rainbow.xcodeproj/project.pbxproj | 381 ------------------ package.json | 2 +- src/App.tsx | 2 +- .../screens/Swap/components/GasButton.tsx | 10 +- .../search/results/SearchResults.tsx | 4 - .../ButtonPressAnimation.android.tsx | 144 ++++--- .../WrappedCollectiblesHeader.tsx | 54 ++- .../profile-header/ProfileAvatarRow.tsx | 6 +- src/components/change-wallet/AddressRow.tsx | 12 +- .../ens-profile/ActionButtons/MoreButton.tsx | 23 +- .../UniqueTokenExpandedStateHeader.tsx | 13 +- src/components/gas/GasSpeedButton.tsx | 13 +- src/components/list/ListHeaderMenu.tsx | 20 +- ...enu.android.js => contextMenu.android.tsx} | 33 +- .../native-context-menu/contextMenu.js | 6 - .../native-context-menu/contextMenu.tsx | 58 +++ src/hooks/useNFTsSortBy.ts | 36 +- src/hooks/useRefreshAccountData.ts | 8 +- src/hooks/useWalletSectionsData.ts | 5 +- src/hooks/useWatchPendingTxs.ts | 11 +- src/languages/en_US.json | 6 +- src/resources/nfts/index.ts | 27 +- src/screens/ENSIntroSheet.tsx | 3 +- src/screens/ExchangeModal.tsx | 1 + .../components/Backups/ViewWalletBackup.tsx | 3 +- .../points/components/LeaderboardRow.tsx | 23 +- .../TransactionDetailsAddressRow.tsx | 2 +- ...etailsStatusActionsAndTimestampSection.tsx | 59 +-- yarn.lock | 18 +- 29 files changed, 345 insertions(+), 638 deletions(-) rename src/components/native-context-menu/{contextMenu.android.js => contextMenu.android.tsx} (56%) delete mode 100644 src/components/native-context-menu/contextMenu.js create mode 100644 src/components/native-context-menu/contextMenu.tsx diff --git a/ios/Rainbow.xcodeproj/project.pbxproj b/ios/Rainbow.xcodeproj/project.pbxproj index 0da57dbe0d2..5428d264f73 100644 --- a/ios/Rainbow.xcodeproj/project.pbxproj +++ b/ios/Rainbow.xcodeproj/project.pbxproj @@ -9,7 +9,6 @@ /* Begin PBXBuildFile section */ 0299CE7B2886202800B5C7E7 /* NotificationService.m in Sources */ = {isa = PBXBuildFile; fileRef = 0299CE7A2886202800B5C7E7 /* NotificationService.m */; }; 0299CE7F2886202800B5C7E7 /* ImageNotification.appex in Embed App Extensions */ = {isa = PBXBuildFile; fileRef = 0299CE772886202800B5C7E7 /* ImageNotification.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; - 135F623E8FF08A7A779DBB59 /* libPods-Rainbow.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4AC56C617B9C2032ED43DBD5 /* libPods-Rainbow.a */; }; 13B07FBC1A68108700A75B9A /* AppDelegate.mm in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB01A68108700A75B9A /* AppDelegate.mm */; }; 13B07FBD1A68108700A75B9A /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB11A68108700A75B9A /* LaunchScreen.xib */; }; 13B07FC11A68108700A75B9A /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB71A68108700A75B9A /* main.m */; }; @@ -25,11 +24,8 @@ 15D66137277A751C0082F041 /* SelectTokenIntent.intentdefinition in Sources */ = {isa = PBXBuildFile; fileRef = 15D66139277A751C0082F041 /* SelectTokenIntent.intentdefinition */; }; 15E531D5242B28EF00797B89 /* UIImageViewWithPersistentAnimations.swift in Sources */ = {isa = PBXBuildFile; fileRef = 15E531D4242B28EF00797B89 /* UIImageViewWithPersistentAnimations.swift */; }; 15E531DA242DAB7100797B89 /* NotificationManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 15E531D9242DAB7100797B89 /* NotificationManager.m */; }; - 1A546771DB0C32A214F8DA75 /* libPods-ImageNotification.a in Frameworks */ = {isa = PBXBuildFile; fileRef = FAF343BC9A04F7FB981F2D3F /* libPods-ImageNotification.a */; }; 24979E8920F84250007EB0DA /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 24979E7720F84004007EB0DA /* GoogleService-Info.plist */; }; - 267E162D22C3B7F129888447 /* libPods-PriceWidgetExtension.a in Frameworks */ = {isa = PBXBuildFile; fileRef = FDA33853985FF984942F1070 /* libPods-PriceWidgetExtension.a */; }; 4D098C2F2811A9A5006A801A /* RNStartTime.m in Sources */ = {isa = PBXBuildFile; fileRef = 4D098C2E2811A9A5006A801A /* RNStartTime.m */; }; - 4D337D44AABFFB7BFABDD027 /* libPods-SelectTokenIntent.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 933E17FCCFBF5FB66A730E0B /* libPods-SelectTokenIntent.a */; }; 6630540924A38A1900E5B030 /* RainbowText.m in Sources */ = {isa = PBXBuildFile; fileRef = 6630540824A38A1900E5B030 /* RainbowText.m */; }; 6635730624939991006ACFA6 /* SafeStoreReview.m in Sources */ = {isa = PBXBuildFile; fileRef = 6635730524939991006ACFA6 /* SafeStoreReview.m */; }; 6655FFB425BB2B0700642961 /* ThemeModule.m in Sources */ = {isa = PBXBuildFile; fileRef = 6655FFB325BB2B0700642961 /* ThemeModule.m */; }; @@ -202,7 +198,6 @@ /* Begin PBXFileReference section */ 008F07F21AC5B25A0029DE68 /* main.jsbundle */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = main.jsbundle; sourceTree = ""; }; - 00A32D3367A149262C6C4D33 /* Pods-PriceWidgetExtension.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-PriceWidgetExtension.debug.xcconfig"; path = "Target Support Files/Pods-PriceWidgetExtension/Pods-PriceWidgetExtension.debug.xcconfig"; sourceTree = ""; }; 00E356F11AD99517003FC87E /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 00E356F21AD99517003FC87E /* RainbowTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RainbowTests.m; sourceTree = ""; }; 0299CE772886202800B5C7E7 /* ImageNotification.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = ImageNotification.appex; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -210,14 +205,12 @@ 0299CE7A2886202800B5C7E7 /* NotificationService.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = NotificationService.m; sourceTree = ""; }; 0299CE7C2886202800B5C7E7 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 0299CE852886246C00B5C7E7 /* libFirebaseCore.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; path = libFirebaseCore.a; sourceTree = BUILT_PRODUCTS_DIR; }; - 11D30486FEF77968C16FDF7D /* Pods-PriceWidgetExtension.staging.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-PriceWidgetExtension.staging.xcconfig"; path = "Target Support Files/Pods-PriceWidgetExtension/Pods-PriceWidgetExtension.staging.xcconfig"; sourceTree = ""; }; 13B07F961A680F5B00A75B9A /* Rainbow.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Rainbow.app; sourceTree = BUILT_PRODUCTS_DIR; }; 13B07FAF1A68108700A75B9A /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AppDelegate.h; path = Rainbow/AppDelegate.h; sourceTree = ""; }; 13B07FB01A68108700A75B9A /* AppDelegate.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = AppDelegate.mm; path = Rainbow/AppDelegate.mm; sourceTree = ""; }; 13B07FB21A68108700A75B9A /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/LaunchScreen.xib; sourceTree = ""; }; 13B07FB61A68108700A75B9A /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Info.plist; path = Rainbow/Info.plist; sourceTree = ""; }; 13B07FB71A68108700A75B9A /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = main.m; path = Rainbow/main.m; sourceTree = ""; }; - 15004743AF62EF3EE384E855 /* Pods-Rainbow.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Rainbow.release.xcconfig"; path = "Target Support Files/Pods-Rainbow/Pods-Rainbow.release.xcconfig"; sourceTree = ""; }; 152643462B9AD97E004AC9AA /* InjectedJSBundle.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; name = InjectedJSBundle.js; path = ../InjectedJSBundle.js; sourceTree = ""; }; 157155032418733F009B698B /* RainbowRelease.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; name = RainbowRelease.entitlements; path = Rainbow/RainbowRelease.entitlements; sourceTree = ""; }; 157155042418734C009B698B /* RainbowDebug.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; name = RainbowDebug.entitlements; path = Rainbow/RainbowDebug.entitlements; sourceTree = ""; }; @@ -237,7 +230,6 @@ 15E531D4242B28EF00797B89 /* UIImageViewWithPersistentAnimations.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIImageViewWithPersistentAnimations.swift; sourceTree = ""; }; 15E531D8242DAB7100797B89 /* NotificationManager.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = NotificationManager.h; sourceTree = ""; }; 15E531D9242DAB7100797B89 /* NotificationManager.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = NotificationManager.m; sourceTree = ""; }; - 239585D5B37F4FBD1470F62D /* Pods-ImageNotification.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ImageNotification.debug.xcconfig"; path = "Target Support Files/Pods-ImageNotification/Pods-ImageNotification.debug.xcconfig"; sourceTree = ""; }; 24979E3620F84003007EB0DA /* Protobuf.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Protobuf.framework; path = Frameworks/Protobuf.framework; sourceTree = ""; }; 24979E7420F84004007EB0DA /* FirebaseAnalytics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = FirebaseAnalytics.framework; path = Frameworks/FirebaseAnalytics.framework; sourceTree = ""; }; 24979E7520F84004007EB0DA /* FirebaseCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = FirebaseCore.framework; path = Frameworks/FirebaseCore.framework; sourceTree = ""; }; @@ -250,16 +242,11 @@ 24979E7C20F84004007EB0DA /* FirebaseCoreDiagnostics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = FirebaseCoreDiagnostics.framework; path = Frameworks/FirebaseCoreDiagnostics.framework; sourceTree = ""; }; 24979E7D20F84005007EB0DA /* module.modulemap */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = "sourcecode.module-map"; name = module.modulemap; path = Frameworks/module.modulemap; sourceTree = ""; }; 24979E7E20F84005007EB0DA /* nanopb.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = nanopb.framework; path = Frameworks/nanopb.framework; sourceTree = ""; }; - 388CCCEFC8BB73A757574C99 /* Pods-SelectTokenIntent.localrelease.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-SelectTokenIntent.localrelease.xcconfig"; path = "Target Support Files/Pods-SelectTokenIntent/Pods-SelectTokenIntent.localrelease.xcconfig"; sourceTree = ""; }; - 3BBE9F9F842B95CFF7E85DB8 /* Pods-Rainbow.localrelease.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Rainbow.localrelease.xcconfig"; path = "Target Support Files/Pods-Rainbow/Pods-Rainbow.localrelease.xcconfig"; sourceTree = ""; }; 3C379D5D20FD1F92009AF81F /* Rainbow.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; name = Rainbow.entitlements; path = Rainbow/Rainbow.entitlements; sourceTree = ""; }; 3CBE29CB2381E43800BE05AC /* Rainbow-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Rainbow-Bridging-Header.h"; sourceTree = ""; }; - 3FEB7D565693086934123364 /* Pods-ImageNotification.localrelease.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ImageNotification.localrelease.xcconfig"; path = "Target Support Files/Pods-ImageNotification/Pods-ImageNotification.localrelease.xcconfig"; sourceTree = ""; }; 43C92E589571C27FFE89AB10 /* ExpoModulesProvider.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ExpoModulesProvider.swift; path = "Pods/Target Support Files/Pods-Rainbow/ExpoModulesProvider.swift"; sourceTree = ""; }; - 4AC56C617B9C2032ED43DBD5 /* libPods-Rainbow.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-Rainbow.a"; sourceTree = BUILT_PRODUCTS_DIR; }; 4D098C2D2811A979006A801A /* RNStartTime.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RNStartTime.h; sourceTree = ""; }; 4D098C2E2811A9A5006A801A /* RNStartTime.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RNStartTime.m; sourceTree = ""; }; - 5D4F7BDB5458BA6BF08E99B6 /* Pods-ImageNotification.staging.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ImageNotification.staging.xcconfig"; path = "Target Support Files/Pods-ImageNotification/Pods-ImageNotification.staging.xcconfig"; sourceTree = ""; }; 6630540824A38A1900E5B030 /* RainbowText.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RainbowText.m; sourceTree = ""; }; 6635730524939991006ACFA6 /* SafeStoreReview.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SafeStoreReview.m; sourceTree = ""; }; 664612EC2748489B00B43F5A /* PriceWidgetExtension.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = PriceWidgetExtension.entitlements; sourceTree = ""; }; @@ -275,14 +262,10 @@ 66A1FEBB24ACBBE600C3F539 /* RNCMPortal.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = RNCMPortal.m; path = "../src/react-native-cool-modals/ios/RNCMPortal.m"; sourceTree = ""; }; 66A28EAF24CAF1B500410A88 /* TestFlight.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = TestFlight.m; sourceTree = ""; }; 66A29CCA2511074500481F4A /* ReaHeader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ReaHeader.h; sourceTree = SOURCE_ROOT; }; - 6B24FBC9AFF649E6E37FF985 /* Pods-PriceWidgetExtension.localrelease.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-PriceWidgetExtension.localrelease.xcconfig"; path = "Target Support Files/Pods-PriceWidgetExtension/Pods-PriceWidgetExtension.localrelease.xcconfig"; sourceTree = ""; }; - 933E17FCCFBF5FB66A730E0B /* libPods-SelectTokenIntent.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-SelectTokenIntent.a"; sourceTree = BUILT_PRODUCTS_DIR; }; 98AED33BAB4247CEBEF8464D /* libz.tbd */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libz.tbd; path = usr/lib/libz.tbd; sourceTree = SDKROOT; }; 9DEADFA4826D4D0BAA950D21 /* libRNFIRMessaging.a */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = archive.ar; path = libRNFIRMessaging.a; sourceTree = ""; }; - 9E9F7E918EFBFBAF381621C7 /* Pods-Rainbow.staging.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Rainbow.staging.xcconfig"; path = "Target Support Files/Pods-Rainbow/Pods-Rainbow.staging.xcconfig"; sourceTree = ""; }; A4277D9E23CBD1910042BAF4 /* Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Extensions.swift; sourceTree = ""; }; A4277DA223CFE85F0042BAF4 /* Theme.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Theme.swift; sourceTree = ""; }; - A4C7384F262FF1BCFABB462D /* Pods-Rainbow.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Rainbow.debug.xcconfig"; path = "Target Support Files/Pods-Rainbow/Pods-Rainbow.debug.xcconfig"; sourceTree = ""; }; A4D04BA823D12F99008C1DEC /* Button.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Button.swift; sourceTree = ""; }; A4D04BAB23D12FD5008C1DEC /* ButtonManager.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ButtonManager.m; sourceTree = ""; }; AA0B1CB82B00C5E100EAF77D /* SF-Mono-Semibold.otf */ = {isa = PBXFileReference; lastKnownFileType = file; name = "SF-Mono-Semibold.otf"; path = "../src/assets/fonts/SF-Mono-Semibold.otf"; sourceTree = ""; }; @@ -294,7 +277,6 @@ AA6228ED24272B200078BDAA /* SF-Pro-Rounded-Medium.otf */ = {isa = PBXFileReference; lastKnownFileType = file; name = "SF-Pro-Rounded-Medium.otf"; path = "../src/assets/fonts/SF-Pro-Rounded-Medium.otf"; sourceTree = ""; }; AA6228EE24272B200078BDAA /* SF-Pro-Rounded-Regular.otf */ = {isa = PBXFileReference; lastKnownFileType = file; name = "SF-Pro-Rounded-Regular.otf"; path = "../src/assets/fonts/SF-Pro-Rounded-Regular.otf"; sourceTree = ""; }; AAA0EF342BF5A4AD00A19A53 /* PrivacyInfo.xcprivacy */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = PrivacyInfo.xcprivacy; sourceTree = ""; }; - AE024FCA8C28D21E9E1EA378 /* Pods-SelectTokenIntent.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-SelectTokenIntent.debug.xcconfig"; path = "Target Support Files/Pods-SelectTokenIntent/Pods-SelectTokenIntent.debug.xcconfig"; sourceTree = ""; }; B0C692B061D7430D8194DC98 /* ToolTipMenuTests.xctest */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = wrapper.cfbundle; path = ToolTipMenuTests.xctest; sourceTree = ""; }; B50C9AE92A9D18DC00EB0019 /* adworld@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "adworld@3x.png"; sourceTree = ""; }; B50C9AEA2A9D18DC00EB0019 /* adworld@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "adworld@2x.png"; sourceTree = ""; }; @@ -355,15 +337,9 @@ C9B378BA2C515A860085E5D0 /* ShareViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShareViewController.swift; sourceTree = ""; }; C9B378BD2C515A860085E5D0 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/MainInterface.storyboard; sourceTree = ""; }; C9B378BF2C515A860085E5D0 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - CF8B843EAE21E6291C0C6702 /* Pods-SelectTokenIntent.staging.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-SelectTokenIntent.staging.xcconfig"; path = "Target Support Files/Pods-SelectTokenIntent/Pods-SelectTokenIntent.staging.xcconfig"; sourceTree = ""; }; - D657340CCBF77C82579CE8A1 /* Pods-SelectTokenIntent.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-SelectTokenIntent.release.xcconfig"; path = "Target Support Files/Pods-SelectTokenIntent/Pods-SelectTokenIntent.release.xcconfig"; sourceTree = ""; }; D755E71324B04FEE9C691D14 /* libRNFirebase.a */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = archive.ar; path = libRNFirebase.a; sourceTree = ""; }; - E060F33194FF363EC0431250 /* Pods-ImageNotification.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ImageNotification.release.xcconfig"; path = "Target Support Files/Pods-ImageNotification/Pods-ImageNotification.release.xcconfig"; sourceTree = ""; }; - EAF3EBD98BA704022718B359 /* Pods-PriceWidgetExtension.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-PriceWidgetExtension.release.xcconfig"; path = "Target Support Files/Pods-PriceWidgetExtension/Pods-PriceWidgetExtension.release.xcconfig"; sourceTree = ""; }; ED297162215061F000B7C4FE /* JavaScriptCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = JavaScriptCore.framework; path = System/Library/Frameworks/JavaScriptCore.framework; sourceTree = SDKROOT; }; ED2971642150620600B7C4FE /* JavaScriptCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = JavaScriptCore.framework; path = Platforms/AppleTVOS.platform/Developer/SDKs/AppleTVOS12.0.sdk/System/Library/Frameworks/JavaScriptCore.framework; sourceTree = DEVELOPER_DIR; }; - FAF343BC9A04F7FB981F2D3F /* libPods-ImageNotification.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-ImageNotification.a"; sourceTree = BUILT_PRODUCTS_DIR; }; - FDA33853985FF984942F1070 /* libPods-PriceWidgetExtension.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-PriceWidgetExtension.a"; sourceTree = BUILT_PRODUCTS_DIR; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -371,7 +347,6 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 1A546771DB0C32A214F8DA75 /* libPods-ImageNotification.a in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -381,7 +356,6 @@ files = ( ED2971652150620600B7C4FE /* JavaScriptCore.framework in Frameworks */, C72F456C99A646399192517D /* libz.tbd in Frameworks */, - 135F623E8FF08A7A779DBB59 /* libPods-Rainbow.a in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -391,7 +365,6 @@ files = ( C16DCF60272BA6EF00FF5C78 /* SwiftUI.framework in Frameworks */, C16DCF5E272BA6EF00FF5C78 /* WidgetKit.framework in Frameworks */, - 267E162D22C3B7F129888447 /* libPods-PriceWidgetExtension.a in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -400,7 +373,6 @@ buildActionMask = 2147483647; files = ( C16DCF81272BAB9500FF5C78 /* Intents.framework in Frameworks */, - 4D337D44AABFFB7BFABDD027 /* libPods-SelectTokenIntent.a in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -577,10 +549,6 @@ C16DCF80272BAB9500FF5C78 /* Intents.framework */, C16DCF8B272BAB9600FF5C78 /* IntentsUI.framework */, C9B378A12C5159880085E5D0 /* UniformTypeIdentifiers.framework */, - FAF343BC9A04F7FB981F2D3F /* libPods-ImageNotification.a */, - FDA33853985FF984942F1070 /* libPods-PriceWidgetExtension.a */, - 4AC56C617B9C2032ED43DBD5 /* libPods-Rainbow.a */, - 933E17FCCFBF5FB66A730E0B /* libPods-SelectTokenIntent.a */, ); name = Frameworks; sourceTree = ""; @@ -744,22 +712,6 @@ C640359C0E6575CE0A7ECD73 /* Pods */ = { isa = PBXGroup; children = ( - 239585D5B37F4FBD1470F62D /* Pods-ImageNotification.debug.xcconfig */, - E060F33194FF363EC0431250 /* Pods-ImageNotification.release.xcconfig */, - 3FEB7D565693086934123364 /* Pods-ImageNotification.localrelease.xcconfig */, - 5D4F7BDB5458BA6BF08E99B6 /* Pods-ImageNotification.staging.xcconfig */, - 00A32D3367A149262C6C4D33 /* Pods-PriceWidgetExtension.debug.xcconfig */, - EAF3EBD98BA704022718B359 /* Pods-PriceWidgetExtension.release.xcconfig */, - 6B24FBC9AFF649E6E37FF985 /* Pods-PriceWidgetExtension.localrelease.xcconfig */, - 11D30486FEF77968C16FDF7D /* Pods-PriceWidgetExtension.staging.xcconfig */, - A4C7384F262FF1BCFABB462D /* Pods-Rainbow.debug.xcconfig */, - 15004743AF62EF3EE384E855 /* Pods-Rainbow.release.xcconfig */, - 3BBE9F9F842B95CFF7E85DB8 /* Pods-Rainbow.localrelease.xcconfig */, - 9E9F7E918EFBFBAF381621C7 /* Pods-Rainbow.staging.xcconfig */, - AE024FCA8C28D21E9E1EA378 /* Pods-SelectTokenIntent.debug.xcconfig */, - D657340CCBF77C82579CE8A1 /* Pods-SelectTokenIntent.release.xcconfig */, - 388CCCEFC8BB73A757574C99 /* Pods-SelectTokenIntent.localrelease.xcconfig */, - CF8B843EAE21E6291C0C6702 /* Pods-SelectTokenIntent.staging.xcconfig */, ); path = Pods; sourceTree = ""; @@ -815,11 +767,9 @@ isa = PBXNativeTarget; buildConfigurationList = 0299CE842886202800B5C7E7 /* Build configuration list for PBXNativeTarget "ImageNotification" */; buildPhases = ( - 1A70A0F491DB72617BEC1E3E /* [CP] Check Pods Manifest.lock */, 0299CE732886202800B5C7E7 /* Sources */, 0299CE742886202800B5C7E7 /* Frameworks */, 0299CE752886202800B5C7E7 /* Resources */, - CC6F07DBBF6C5DBF6BE2736C /* [CP] Copy Pods Resources */, ); buildRules = ( ); @@ -834,17 +784,12 @@ isa = PBXNativeTarget; buildConfigurationList = 13B07F931A680F5B00A75B9A /* Build configuration list for PBXNativeTarget "Rainbow" */; buildPhases = ( - B84C4CAD33EC131FD4694010 /* [CP] Check Pods Manifest.lock */, AEAD56A917FF4051986EE3E6 /* [Expo] Configure project */, 13B07F871A680F5B00A75B9A /* Sources */, 13B07F8C1A680F5B00A75B9A /* Frameworks */, 13B07F8E1A680F5B00A75B9A /* Resources */, 00DD1BFF1BD5951E006B06BC /* Bundle React Native code and images */, - 9FF961FEA7AF435FA18ED988 /* Upload Debug Symbols to Sentry */, 668ADB3225A4E3A40050859D /* Embed App Extensions */, - 727A03F9C34280788B4EB7B0 /* [CP] Embed Pods Frameworks */, - 64400C8C24B919E9DC12C927 /* [CP] Copy Pods Resources */, - 9CC18903234C511474C4FE5A /* [CP-User] [RNFB] Core Configuration */, ); buildRules = ( ); @@ -864,11 +809,9 @@ isa = PBXNativeTarget; buildConfigurationList = C16DCF6E272BA6F100FF5C78 /* Build configuration list for PBXNativeTarget "PriceWidgetExtension" */; buildPhases = ( - 24E3DE0C1A318179029F909F /* [CP] Check Pods Manifest.lock */, C16DCF58272BA6EF00FF5C78 /* Sources */, C16DCF59272BA6EF00FF5C78 /* Frameworks */, C16DCF5A272BA6EF00FF5C78 /* Resources */, - E5478161AB3BE9AD9BFD4290 /* [CP] Copy Pods Resources */, ); buildRules = ( ); @@ -883,11 +826,9 @@ isa = PBXNativeTarget; buildConfigurationList = C16DCF9F272BAB9600FF5C78 /* Build configuration list for PBXNativeTarget "SelectTokenIntent" */; buildPhases = ( - C239424DF07543274D084131 /* [CP] Check Pods Manifest.lock */, C16DCF7B272BAB9500FF5C78 /* Sources */, C16DCF7C272BAB9500FF5C78 /* Frameworks */, C16DCF7D272BAB9500FF5C78 /* Resources */, - 82752F7D7CA23C0EBC84AF92 /* [CP] Copy Pods Resources */, ); buildRules = ( ); @@ -1118,194 +1059,6 @@ shellScript = "if [[ -f \"$PODS_ROOT/../.xcode.env\" ]]; then\n source \"$PODS_ROOT/../.xcode.env\"\nfi\nif [[ -f \"$PODS_ROOT/../.xcode.env.local\" ]]; then\n source \"$PODS_ROOT/../.xcode.env.local\"\nfi\n\n# The project root by default is one level up from the ios directory\nexport PROJECT_ROOT=\"$PROJECT_DIR\"/..\n\nif [[ \"$CONFIGURATION\" = *Debug* ]]; then\n export SKIP_BUNDLING=1\nfi\nif [[ -z \"$ENTRY_FILE\" ]]; then\n # Set the entry JS file using the bundler's entry resolution.\n export ENTRY_FILE=\"$(\"$NODE_BINARY\" -e \"require('expo/scripts/resolveAppEntry')\" \"$PROJECT_ROOT\" ios absolute | tail -n 1)\"\nfi\n\nif [[ -z \"$CLI_PATH\" ]]; then\n # Use Expo CLI\n export CLI_PATH=\"$(\"$NODE_BINARY\" --print \"require.resolve('@expo/cli')\")\"\nfi\nif [[ -z \"$BUNDLE_COMMAND\" ]]; then\n # Default Expo CLI command for bundling\n export BUNDLE_COMMAND=\"export:embed\"\nfi\n\n`\"$NODE_BINARY\" --print \"require('path').dirname(require.resolve('react-native/package.json')) + '/scripts/react-native-xcode.sh'\"`\n"; showEnvVarsInLog = 0; }; - 1A70A0F491DB72617BEC1E3E /* [CP] Check Pods Manifest.lock */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputFileListPaths = ( - ); - inputPaths = ( - "${PODS_PODFILE_DIR_PATH}/Podfile.lock", - "${PODS_ROOT}/Manifest.lock", - ); - name = "[CP] Check Pods Manifest.lock"; - outputFileListPaths = ( - ); - outputPaths = ( - "$(DERIVED_FILE_DIR)/Pods-ImageNotification-checkManifestLockResult.txt", - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; - showEnvVarsInLog = 0; - }; - 24E3DE0C1A318179029F909F /* [CP] Check Pods Manifest.lock */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputFileListPaths = ( - ); - inputPaths = ( - "${PODS_PODFILE_DIR_PATH}/Podfile.lock", - "${PODS_ROOT}/Manifest.lock", - ); - name = "[CP] Check Pods Manifest.lock"; - outputFileListPaths = ( - ); - outputPaths = ( - "$(DERIVED_FILE_DIR)/Pods-PriceWidgetExtension-checkManifestLockResult.txt", - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; - showEnvVarsInLog = 0; - }; - 64400C8C24B919E9DC12C927 /* [CP] Copy Pods Resources */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-Rainbow/Pods-Rainbow-resources.sh", - "${PODS_CONFIGURATION_BUILD_DIR}/FirebaseABTesting/FirebaseABTesting_Privacy.bundle", - "${PODS_CONFIGURATION_BUILD_DIR}/FirebaseCore/FirebaseCore_Privacy.bundle", - "${PODS_CONFIGURATION_BUILD_DIR}/FirebaseCoreExtension/FirebaseCoreExtension_Privacy.bundle", - "${PODS_CONFIGURATION_BUILD_DIR}/FirebaseCoreInternal/FirebaseCoreInternal_Privacy.bundle", - "${PODS_CONFIGURATION_BUILD_DIR}/FirebaseInstallations/FirebaseInstallations_Privacy.bundle", - "${PODS_CONFIGURATION_BUILD_DIR}/FirebaseRemoteConfig/FirebaseRemoteConfig_Privacy.bundle", - "${PODS_CONFIGURATION_BUILD_DIR}/GoogleDataTransport/GoogleDataTransport_Privacy.bundle", - "${PODS_CONFIGURATION_BUILD_DIR}/GoogleUtilities/GoogleUtilities_Privacy.bundle", - "${PODS_CONFIGURATION_BUILD_DIR}/PromisesObjC/FBLPromises_Privacy.bundle", - "${PODS_CONFIGURATION_BUILD_DIR}/nanopb/nanopb_Privacy.bundle", - "${PODS_CONFIGURATION_BUILD_DIR}/FirebaseMessaging/FirebaseMessaging_Privacy.bundle", - "${PODS_CONFIGURATION_BUILD_DIR}/EXConstants/EXConstants.bundle", - "${PODS_CONFIGURATION_BUILD_DIR}/EXConstants/ExpoConstants_privacy.bundle", - "${PODS_CONFIGURATION_BUILD_DIR}/ExpoFileSystem/ExpoFileSystem_privacy.bundle", - "${PODS_CONFIGURATION_BUILD_DIR}/RNCAsyncStorage/RNCAsyncStorage_resources.bundle", - "${PODS_CONFIGURATION_BUILD_DIR}/RNImageCropPicker/RNImageCropPickerPrivacyInfo.bundle", - "${PODS_CONFIGURATION_BUILD_DIR}/RNImageCropPicker/QBImagePicker.bundle", - "${PODS_CONFIGURATION_BUILD_DIR}/React-Core/RCTI18nStrings.bundle", - "${PODS_CONFIGURATION_BUILD_DIR}/Rudder/Rudder.bundle", - "${PODS_CONFIGURATION_BUILD_DIR}/SDWebImage/SDWebImage.bundle", - "${PODS_CONFIGURATION_BUILD_DIR}/Sentry/Sentry.bundle", - "${PODS_CONFIGURATION_BUILD_DIR}/TOCropViewController/TOCropViewControllerBundle.bundle", - "${PODS_CONFIGURATION_BUILD_DIR}/react-native-cameraroll/RNCameraRollPrivacyInfo.bundle", - ); - name = "[CP] Copy Pods Resources"; - outputPaths = ( - "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/FirebaseABTesting_Privacy.bundle", - "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/FirebaseCore_Privacy.bundle", - "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/FirebaseCoreExtension_Privacy.bundle", - "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/FirebaseCoreInternal_Privacy.bundle", - "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/FirebaseInstallations_Privacy.bundle", - "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/FirebaseRemoteConfig_Privacy.bundle", - "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/GoogleDataTransport_Privacy.bundle", - "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/GoogleUtilities_Privacy.bundle", - "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/FBLPromises_Privacy.bundle", - "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/nanopb_Privacy.bundle", - "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/FirebaseMessaging_Privacy.bundle", - "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/EXConstants.bundle", - "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/ExpoConstants_privacy.bundle", - "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/ExpoFileSystem_privacy.bundle", - "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/RNCAsyncStorage_resources.bundle", - "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/RNImageCropPickerPrivacyInfo.bundle", - "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/QBImagePicker.bundle", - "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/RCTI18nStrings.bundle", - "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/Rudder.bundle", - "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/SDWebImage.bundle", - "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/Sentry.bundle", - "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/TOCropViewControllerBundle.bundle", - "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/RNCameraRollPrivacyInfo.bundle", - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Rainbow/Pods-Rainbow-resources.sh\"\n"; - showEnvVarsInLog = 0; - }; - 727A03F9C34280788B4EB7B0 /* [CP] Embed Pods Frameworks */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-Rainbow/Pods-Rainbow-frameworks.sh", - "${PODS_XCFRAMEWORKS_BUILD_DIR}/hermes-engine/Pre-built/hermes.framework/hermes", - ); - name = "[CP] Embed Pods Frameworks"; - outputPaths = ( - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/hermes.framework", - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Rainbow/Pods-Rainbow-frameworks.sh\"\n"; - showEnvVarsInLog = 0; - }; - 82752F7D7CA23C0EBC84AF92 /* [CP] Copy Pods Resources */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-SelectTokenIntent/Pods-SelectTokenIntent-resources.sh", - "${PODS_CONFIGURATION_BUILD_DIR}/FirebaseABTesting/FirebaseABTesting_Privacy.bundle", - "${PODS_CONFIGURATION_BUILD_DIR}/FirebaseCore/FirebaseCore_Privacy.bundle", - "${PODS_CONFIGURATION_BUILD_DIR}/FirebaseCoreExtension/FirebaseCoreExtension_Privacy.bundle", - "${PODS_CONFIGURATION_BUILD_DIR}/FirebaseCoreInternal/FirebaseCoreInternal_Privacy.bundle", - "${PODS_CONFIGURATION_BUILD_DIR}/FirebaseInstallations/FirebaseInstallations_Privacy.bundle", - "${PODS_CONFIGURATION_BUILD_DIR}/FirebaseRemoteConfig/FirebaseRemoteConfig_Privacy.bundle", - "${PODS_CONFIGURATION_BUILD_DIR}/GoogleDataTransport/GoogleDataTransport_Privacy.bundle", - "${PODS_CONFIGURATION_BUILD_DIR}/GoogleUtilities/GoogleUtilities_Privacy.bundle", - "${PODS_CONFIGURATION_BUILD_DIR}/PromisesObjC/FBLPromises_Privacy.bundle", - "${PODS_CONFIGURATION_BUILD_DIR}/nanopb/nanopb_Privacy.bundle", - ); - name = "[CP] Copy Pods Resources"; - outputPaths = ( - "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/FirebaseABTesting_Privacy.bundle", - "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/FirebaseCore_Privacy.bundle", - "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/FirebaseCoreExtension_Privacy.bundle", - "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/FirebaseCoreInternal_Privacy.bundle", - "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/FirebaseInstallations_Privacy.bundle", - "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/FirebaseRemoteConfig_Privacy.bundle", - "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/GoogleDataTransport_Privacy.bundle", - "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/GoogleUtilities_Privacy.bundle", - "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/FBLPromises_Privacy.bundle", - "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/nanopb_Privacy.bundle", - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-SelectTokenIntent/Pods-SelectTokenIntent-resources.sh\"\n"; - showEnvVarsInLog = 0; - }; - 9CC18903234C511474C4FE5A /* [CP-User] [RNFB] Core Configuration */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - "$(BUILT_PRODUCTS_DIR)/$(INFOPLIST_PATH)", - ); - name = "[CP-User] [RNFB] Core Configuration"; - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "#!/usr/bin/env bash\n#\n# Copyright (c) 2016-present Invertase Limited & Contributors\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this library except in compliance with the License.\n# You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n\n##########################################################################\n##########################################################################\n#\n# NOTE THAT IF YOU CHANGE THIS FILE YOU MUST RUN pod install AFTERWARDS\n#\n# This file is installed as an Xcode build script in the project file\n# by cocoapods, and you will not see your changes until you pod install\n#\n##########################################################################\n##########################################################################\n\nset -e\n\n_MAX_LOOKUPS=2;\n_SEARCH_RESULT=''\n_RN_ROOT_EXISTS=''\n_CURRENT_LOOKUPS=1\n_JSON_ROOT=\"'react-native'\"\n_JSON_FILE_NAME='firebase.json'\n_JSON_OUTPUT_BASE64='e30=' # { }\n_CURRENT_SEARCH_DIR=${PROJECT_DIR}\n_PLIST_BUDDY=/usr/libexec/PlistBuddy\n_TARGET_PLIST=\"${BUILT_PRODUCTS_DIR}/${INFOPLIST_PATH}\"\n_DSYM_PLIST=\"${DWARF_DSYM_FOLDER_PATH}/${DWARF_DSYM_FILE_NAME}/Contents/Info.plist\"\n\n# plist arrays\n_PLIST_ENTRY_KEYS=()\n_PLIST_ENTRY_TYPES=()\n_PLIST_ENTRY_VALUES=()\n\nfunction setPlistValue {\n echo \"info: setting plist entry '$1' of type '$2' in file '$4'\"\n ${_PLIST_BUDDY} -c \"Add :$1 $2 '$3'\" $4 || echo \"info: '$1' already exists\"\n}\n\nfunction getFirebaseJsonKeyValue () {\n if [[ ${_RN_ROOT_EXISTS} ]]; then\n ruby -Ku -e \"require 'rubygems';require 'json'; output=JSON.parse('$1'); puts output[$_JSON_ROOT]['$2']\"\n else\n echo \"\"\n fi;\n}\n\nfunction jsonBoolToYesNo () {\n if [[ $1 == \"false\" ]]; then\n echo \"NO\"\n elif [[ $1 == \"true\" ]]; then\n echo \"YES\"\n else echo \"NO\"\n fi\n}\n\necho \"info: -> RNFB build script started\"\necho \"info: 1) Locating ${_JSON_FILE_NAME} file:\"\n\nif [[ -z ${_CURRENT_SEARCH_DIR} ]]; then\n _CURRENT_SEARCH_DIR=$(pwd)\nfi;\n\nwhile true; do\n _CURRENT_SEARCH_DIR=$(dirname \"$_CURRENT_SEARCH_DIR\")\n if [[ \"$_CURRENT_SEARCH_DIR\" == \"/\" ]] || [[ ${_CURRENT_LOOKUPS} -gt ${_MAX_LOOKUPS} ]]; then break; fi;\n echo \"info: ($_CURRENT_LOOKUPS of $_MAX_LOOKUPS) Searching in '$_CURRENT_SEARCH_DIR' for a ${_JSON_FILE_NAME} file.\"\n _SEARCH_RESULT=$(find \"$_CURRENT_SEARCH_DIR\" -maxdepth 2 -name ${_JSON_FILE_NAME} -print | /usr/bin/head -n 1)\n if [[ ${_SEARCH_RESULT} ]]; then\n echo \"info: ${_JSON_FILE_NAME} found at $_SEARCH_RESULT\"\n break;\n fi;\n _CURRENT_LOOKUPS=$((_CURRENT_LOOKUPS+1))\ndone\n\nif [[ ${_SEARCH_RESULT} ]]; then\n _JSON_OUTPUT_RAW=$(cat \"${_SEARCH_RESULT}\")\n _RN_ROOT_EXISTS=$(ruby -Ku -e \"require 'rubygems';require 'json'; output=JSON.parse('$_JSON_OUTPUT_RAW'); puts output[$_JSON_ROOT]\" || echo '')\n\n if [[ ${_RN_ROOT_EXISTS} ]]; then\n if ! python3 --version >/dev/null 2>&1; then echo \"python3 not found, firebase.json file processing error.\" && exit 1; fi\n _JSON_OUTPUT_BASE64=$(python3 -c 'import json,sys,base64;print(base64.b64encode(bytes(json.dumps(json.loads(open('\"'${_SEARCH_RESULT}'\"', '\"'rb'\"').read())['${_JSON_ROOT}']), '\"'utf-8'\"')).decode())' || echo \"e30=\")\n fi\n\n _PLIST_ENTRY_KEYS+=(\"firebase_json_raw\")\n _PLIST_ENTRY_TYPES+=(\"string\")\n _PLIST_ENTRY_VALUES+=(\"$_JSON_OUTPUT_BASE64\")\n\n # config.app_data_collection_default_enabled\n _APP_DATA_COLLECTION_ENABLED=$(getFirebaseJsonKeyValue \"$_JSON_OUTPUT_RAW\" \"app_data_collection_default_enabled\")\n if [[ $_APP_DATA_COLLECTION_ENABLED ]]; then\n _PLIST_ENTRY_KEYS+=(\"FirebaseDataCollectionDefaultEnabled\")\n _PLIST_ENTRY_TYPES+=(\"bool\")\n _PLIST_ENTRY_VALUES+=(\"$(jsonBoolToYesNo \"$_APP_DATA_COLLECTION_ENABLED\")\")\n fi\n\n # config.analytics_auto_collection_enabled\n _ANALYTICS_AUTO_COLLECTION=$(getFirebaseJsonKeyValue \"$_JSON_OUTPUT_RAW\" \"analytics_auto_collection_enabled\")\n if [[ $_ANALYTICS_AUTO_COLLECTION ]]; then\n _PLIST_ENTRY_KEYS+=(\"FIREBASE_ANALYTICS_COLLECTION_ENABLED\")\n _PLIST_ENTRY_TYPES+=(\"bool\")\n _PLIST_ENTRY_VALUES+=(\"$(jsonBoolToYesNo \"$_ANALYTICS_AUTO_COLLECTION\")\")\n fi\n\n # config.analytics_collection_deactivated\n _ANALYTICS_DEACTIVATED=$(getFirebaseJsonKeyValue \"$_JSON_OUTPUT_RAW\" \"analytics_collection_deactivated\")\n if [[ $_ANALYTICS_DEACTIVATED ]]; then\n _PLIST_ENTRY_KEYS+=(\"FIREBASE_ANALYTICS_COLLECTION_DEACTIVATED\")\n _PLIST_ENTRY_TYPES+=(\"bool\")\n _PLIST_ENTRY_VALUES+=(\"$(jsonBoolToYesNo \"$_ANALYTICS_DEACTIVATED\")\")\n fi\n\n # config.analytics_idfv_collection_enabled\n _ANALYTICS_IDFV_COLLECTION=$(getFirebaseJsonKeyValue \"$_JSON_OUTPUT_RAW\" \"analytics_idfv_collection_enabled\")\n if [[ $_ANALYTICS_IDFV_COLLECTION ]]; then\n _PLIST_ENTRY_KEYS+=(\"GOOGLE_ANALYTICS_IDFV_COLLECTION_ENABLED\")\n _PLIST_ENTRY_TYPES+=(\"bool\")\n _PLIST_ENTRY_VALUES+=(\"$(jsonBoolToYesNo \"$_ANALYTICS_IDFV_COLLECTION\")\")\n fi\n\n # config.analytics_default_allow_analytics_storage\n _ANALYTICS_STORAGE=$(getFirebaseJsonKeyValue \"$_JSON_OUTPUT_RAW\" \"analytics_default_allow_analytics_storage\")\n if [[ $_ANALYTICS_STORAGE ]]; then\n _PLIST_ENTRY_KEYS+=(\"GOOGLE_ANALYTICS_DEFAULT_ALLOW_ANALYTICS_STORAGE\")\n _PLIST_ENTRY_TYPES+=(\"bool\")\n _PLIST_ENTRY_VALUES+=(\"$(jsonBoolToYesNo \"$_ANALYTICS_STORAGE\")\")\n fi\n\n # config.analytics_default_allow_ad_storage\n _ANALYTICS_AD_STORAGE=$(getFirebaseJsonKeyValue \"$_JSON_OUTPUT_RAW\" \"analytics_default_allow_ad_storage\")\n if [[ $_ANALYTICS_AD_STORAGE ]]; then\n _PLIST_ENTRY_KEYS+=(\"GOOGLE_ANALYTICS_DEFAULT_ALLOW_AD_STORAGE\")\n _PLIST_ENTRY_TYPES+=(\"bool\")\n _PLIST_ENTRY_VALUES+=(\"$(jsonBoolToYesNo \"$_ANALYTICS_AD_STORAGE\")\")\n fi\n\n # config.analytics_default_allow_ad_user_data\n _ANALYTICS_AD_USER_DATA=$(getFirebaseJsonKeyValue \"$_JSON_OUTPUT_RAW\" \"analytics_default_allow_ad_user_data\")\n if [[ $_ANALYTICS_AD_USER_DATA ]]; then\n _PLIST_ENTRY_KEYS+=(\"GOOGLE_ANALYTICS_DEFAULT_ALLOW_AD_USER_DATA\")\n _PLIST_ENTRY_TYPES+=(\"bool\")\n _PLIST_ENTRY_VALUES+=(\"$(jsonBoolToYesNo \"$_ANALYTICS_AD_USER_DATA\")\")\n fi\n\n # config.analytics_default_allow_ad_personalization_signals\n _ANALYTICS_PERSONALIZATION=$(getFirebaseJsonKeyValue \"$_JSON_OUTPUT_RAW\" \"analytics_default_allow_ad_personalization_signals\")\n if [[ $_ANALYTICS_PERSONALIZATION ]]; then\n _PLIST_ENTRY_KEYS+=(\"GOOGLE_ANALYTICS_DEFAULT_ALLOW_AD_PERSONALIZATION_SIGNALS\")\n _PLIST_ENTRY_TYPES+=(\"bool\")\n _PLIST_ENTRY_VALUES+=(\"$(jsonBoolToYesNo \"$_ANALYTICS_PERSONALIZATION\")\")\n fi\n\n # config.analytics_registration_with_ad_network_enabled\n _ANALYTICS_REGISTRATION_WITH_AD_NETWORK=$(getFirebaseJsonKeyValue \"$_JSON_OUTPUT_RAW\" \"google_analytics_registration_with_ad_network_enabled\")\n if [[ $_ANALYTICS_REGISTRATION_WITH_AD_NETWORK ]]; then\n _PLIST_ENTRY_KEYS+=(\"GOOGLE_ANALYTICS_REGISTRATION_WITH_AD_NETWORK_ENABLED\")\n _PLIST_ENTRY_TYPES+=(\"bool\")\n _PLIST_ENTRY_VALUES+=(\"$(jsonBoolToYesNo \"$_ANALYTICS_REGISTRATION_WITH_AD_NETWORK\")\")\n fi\n\n # config.google_analytics_automatic_screen_reporting_enabled\n _ANALYTICS_AUTO_SCREEN_REPORTING=$(getFirebaseJsonKeyValue \"$_JSON_OUTPUT_RAW\" \"google_analytics_automatic_screen_reporting_enabled\")\n if [[ $_ANALYTICS_AUTO_SCREEN_REPORTING ]]; then\n _PLIST_ENTRY_KEYS+=(\"FirebaseAutomaticScreenReportingEnabled\")\n _PLIST_ENTRY_TYPES+=(\"bool\")\n _PLIST_ENTRY_VALUES+=(\"$(jsonBoolToYesNo \"$_ANALYTICS_AUTO_SCREEN_REPORTING\")\")\n fi\n\n # config.perf_auto_collection_enabled\n _PERF_AUTO_COLLECTION=$(getFirebaseJsonKeyValue \"$_JSON_OUTPUT_RAW\" \"perf_auto_collection_enabled\")\n if [[ $_PERF_AUTO_COLLECTION ]]; then\n _PLIST_ENTRY_KEYS+=(\"firebase_performance_collection_enabled\")\n _PLIST_ENTRY_TYPES+=(\"bool\")\n _PLIST_ENTRY_VALUES+=(\"$(jsonBoolToYesNo \"$_PERF_AUTO_COLLECTION\")\")\n fi\n\n # config.perf_collection_deactivated\n _PERF_DEACTIVATED=$(getFirebaseJsonKeyValue \"$_JSON_OUTPUT_RAW\" \"perf_collection_deactivated\")\n if [[ $_PERF_DEACTIVATED ]]; then\n _PLIST_ENTRY_KEYS+=(\"firebase_performance_collection_deactivated\")\n _PLIST_ENTRY_TYPES+=(\"bool\")\n _PLIST_ENTRY_VALUES+=(\"$(jsonBoolToYesNo \"$_PERF_DEACTIVATED\")\")\n fi\n\n # config.messaging_auto_init_enabled\n _MESSAGING_AUTO_INIT=$(getFirebaseJsonKeyValue \"$_JSON_OUTPUT_RAW\" \"messaging_auto_init_enabled\")\n if [[ $_MESSAGING_AUTO_INIT ]]; then\n _PLIST_ENTRY_KEYS+=(\"FirebaseMessagingAutoInitEnabled\")\n _PLIST_ENTRY_TYPES+=(\"bool\")\n _PLIST_ENTRY_VALUES+=(\"$(jsonBoolToYesNo \"$_MESSAGING_AUTO_INIT\")\")\n fi\n\n # config.in_app_messaging_auto_colllection_enabled\n _FIAM_AUTO_INIT=$(getFirebaseJsonKeyValue \"$_JSON_OUTPUT_RAW\" \"in_app_messaging_auto_collection_enabled\")\n if [[ $_FIAM_AUTO_INIT ]]; then\n _PLIST_ENTRY_KEYS+=(\"FirebaseInAppMessagingAutomaticDataCollectionEnabled\")\n _PLIST_ENTRY_TYPES+=(\"bool\")\n _PLIST_ENTRY_VALUES+=(\"$(jsonBoolToYesNo \"$_FIAM_AUTO_INIT\")\")\n fi\n\n # config.app_check_token_auto_refresh\n _APP_CHECK_TOKEN_AUTO_REFRESH=$(getFirebaseJsonKeyValue \"$_JSON_OUTPUT_RAW\" \"app_check_token_auto_refresh\")\n if [[ $_APP_CHECK_TOKEN_AUTO_REFRESH ]]; then\n _PLIST_ENTRY_KEYS+=(\"FirebaseAppCheckTokenAutoRefreshEnabled\")\n _PLIST_ENTRY_TYPES+=(\"bool\")\n _PLIST_ENTRY_VALUES+=(\"$(jsonBoolToYesNo \"$_APP_CHECK_TOKEN_AUTO_REFRESH\")\")\n fi\n\n # config.crashlytics_disable_auto_disabler - undocumented for now - mainly for debugging, document if becomes useful\n _CRASHLYTICS_AUTO_DISABLE_ENABLED=$(getFirebaseJsonKeyValue \"$_JSON_OUTPUT_RAW\" \"crashlytics_disable_auto_disabler\")\n if [[ $_CRASHLYTICS_AUTO_DISABLE_ENABLED == \"true\" ]]; then\n echo \"Disabled Crashlytics auto disabler.\" # do nothing\n else\n _PLIST_ENTRY_KEYS+=(\"FirebaseCrashlyticsCollectionEnabled\")\n _PLIST_ENTRY_TYPES+=(\"bool\")\n _PLIST_ENTRY_VALUES+=(\"NO\")\n fi\nelse\n _PLIST_ENTRY_KEYS+=(\"firebase_json_raw\")\n _PLIST_ENTRY_TYPES+=(\"string\")\n _PLIST_ENTRY_VALUES+=(\"$_JSON_OUTPUT_BASE64\")\n echo \"warning: A firebase.json file was not found, whilst this file is optional it is recommended to include it to configure firebase services in React Native Firebase.\"\nfi;\n\necho \"info: 2) Injecting Info.plist entries: \"\n\n# Log out the keys we're adding\nfor i in \"${!_PLIST_ENTRY_KEYS[@]}\"; do\n echo \" -> $i) ${_PLIST_ENTRY_KEYS[$i]}\" \"${_PLIST_ENTRY_TYPES[$i]}\" \"${_PLIST_ENTRY_VALUES[$i]}\"\ndone\n\nfor plist in \"${_TARGET_PLIST}\" \"${_DSYM_PLIST}\" ; do\n if [[ -f \"${plist}\" ]]; then\n\n # paths with spaces break the call to setPlistValue. temporarily modify\n # the shell internal field separator variable (IFS), which normally\n # includes spaces, to consist only of line breaks\n oldifs=$IFS\n IFS=\"\n\"\n\n for i in \"${!_PLIST_ENTRY_KEYS[@]}\"; do\n setPlistValue \"${_PLIST_ENTRY_KEYS[$i]}\" \"${_PLIST_ENTRY_TYPES[$i]}\" \"${_PLIST_ENTRY_VALUES[$i]}\" \"${plist}\"\n done\n\n # restore the original internal field separator value\n IFS=$oldifs\n else\n echo \"warning: A Info.plist build output file was not found (${plist})\"\n fi\ndone\n\necho \"info: <- RNFB build script finished\"\n"; - }; - 9FF961FEA7AF435FA18ED988 /* Upload Debug Symbols to Sentry */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - ); - name = "Upload Debug Symbols to Sentry"; - outputPaths = ( - "$(DERIVED_FILE_DIR)/Pods-SelectTokenIntent-checkManifestLockResult.txt", - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "export SENTRY_PROPERTIES=sentry.properties\n../node_modules/@sentry/cli/bin/sentry-cli upload-dsym\n"; - }; AEAD56A917FF4051986EE3E6 /* [Expo] Configure project */ = { isa = PBXShellScriptBuildPhase; alwaysOutOfDate = 1; @@ -1325,124 +1078,6 @@ shellPath = /bin/sh; shellScript = "# This script configures Expo modules and generates the modules provider file.\nbash -l -c \"./Pods/Target\\ Support\\ Files/Pods-Rainbow/expo-configure-project.sh\"\n"; }; - B84C4CAD33EC131FD4694010 /* [CP] Check Pods Manifest.lock */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputFileListPaths = ( - ); - inputPaths = ( - "${PODS_PODFILE_DIR_PATH}/Podfile.lock", - "${PODS_ROOT}/Manifest.lock", - ); - name = "[CP] Check Pods Manifest.lock"; - outputFileListPaths = ( - ); - outputPaths = ( - "$(DERIVED_FILE_DIR)/Pods-Rainbow-checkManifestLockResult.txt", - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; - showEnvVarsInLog = 0; - }; - C239424DF07543274D084131 /* [CP] Check Pods Manifest.lock */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputFileListPaths = ( - ); - inputPaths = ( - "${PODS_PODFILE_DIR_PATH}/Podfile.lock", - "${PODS_ROOT}/Manifest.lock", - ); - name = "[CP] Check Pods Manifest.lock"; - outputFileListPaths = ( - ); - outputPaths = ( - "$(DERIVED_FILE_DIR)/Pods-SelectTokenIntent-checkManifestLockResult.txt", - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; - showEnvVarsInLog = 0; - }; - CC6F07DBBF6C5DBF6BE2736C /* [CP] Copy Pods Resources */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-ImageNotification/Pods-ImageNotification-resources.sh", - "${PODS_CONFIGURATION_BUILD_DIR}/FirebaseABTesting/FirebaseABTesting_Privacy.bundle", - "${PODS_CONFIGURATION_BUILD_DIR}/FirebaseCore/FirebaseCore_Privacy.bundle", - "${PODS_CONFIGURATION_BUILD_DIR}/FirebaseCoreExtension/FirebaseCoreExtension_Privacy.bundle", - "${PODS_CONFIGURATION_BUILD_DIR}/FirebaseCoreInternal/FirebaseCoreInternal_Privacy.bundle", - "${PODS_CONFIGURATION_BUILD_DIR}/FirebaseInstallations/FirebaseInstallations_Privacy.bundle", - "${PODS_CONFIGURATION_BUILD_DIR}/FirebaseRemoteConfig/FirebaseRemoteConfig_Privacy.bundle", - "${PODS_CONFIGURATION_BUILD_DIR}/GoogleDataTransport/GoogleDataTransport_Privacy.bundle", - "${PODS_CONFIGURATION_BUILD_DIR}/GoogleUtilities/GoogleUtilities_Privacy.bundle", - "${PODS_CONFIGURATION_BUILD_DIR}/PromisesObjC/FBLPromises_Privacy.bundle", - "${PODS_CONFIGURATION_BUILD_DIR}/nanopb/nanopb_Privacy.bundle", - "${PODS_CONFIGURATION_BUILD_DIR}/FirebaseMessaging/FirebaseMessaging_Privacy.bundle", - ); - name = "[CP] Copy Pods Resources"; - outputPaths = ( - "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/FirebaseABTesting_Privacy.bundle", - "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/FirebaseCore_Privacy.bundle", - "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/FirebaseCoreExtension_Privacy.bundle", - "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/FirebaseCoreInternal_Privacy.bundle", - "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/FirebaseInstallations_Privacy.bundle", - "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/FirebaseRemoteConfig_Privacy.bundle", - "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/GoogleDataTransport_Privacy.bundle", - "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/GoogleUtilities_Privacy.bundle", - "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/FBLPromises_Privacy.bundle", - "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/nanopb_Privacy.bundle", - "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/FirebaseMessaging_Privacy.bundle", - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-ImageNotification/Pods-ImageNotification-resources.sh\"\n"; - showEnvVarsInLog = 0; - }; - E5478161AB3BE9AD9BFD4290 /* [CP] Copy Pods Resources */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-PriceWidgetExtension/Pods-PriceWidgetExtension-resources.sh", - "${PODS_CONFIGURATION_BUILD_DIR}/FirebaseABTesting/FirebaseABTesting_Privacy.bundle", - "${PODS_CONFIGURATION_BUILD_DIR}/FirebaseCore/FirebaseCore_Privacy.bundle", - "${PODS_CONFIGURATION_BUILD_DIR}/FirebaseCoreExtension/FirebaseCoreExtension_Privacy.bundle", - "${PODS_CONFIGURATION_BUILD_DIR}/FirebaseCoreInternal/FirebaseCoreInternal_Privacy.bundle", - "${PODS_CONFIGURATION_BUILD_DIR}/FirebaseInstallations/FirebaseInstallations_Privacy.bundle", - "${PODS_CONFIGURATION_BUILD_DIR}/FirebaseRemoteConfig/FirebaseRemoteConfig_Privacy.bundle", - "${PODS_CONFIGURATION_BUILD_DIR}/GoogleDataTransport/GoogleDataTransport_Privacy.bundle", - "${PODS_CONFIGURATION_BUILD_DIR}/GoogleUtilities/GoogleUtilities_Privacy.bundle", - "${PODS_CONFIGURATION_BUILD_DIR}/PromisesObjC/FBLPromises_Privacy.bundle", - "${PODS_CONFIGURATION_BUILD_DIR}/nanopb/nanopb_Privacy.bundle", - ); - name = "[CP] Copy Pods Resources"; - outputPaths = ( - "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/FirebaseABTesting_Privacy.bundle", - "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/FirebaseCore_Privacy.bundle", - "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/FirebaseCoreExtension_Privacy.bundle", - "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/FirebaseCoreInternal_Privacy.bundle", - "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/FirebaseInstallations_Privacy.bundle", - "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/FirebaseRemoteConfig_Privacy.bundle", - "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/GoogleDataTransport_Privacy.bundle", - "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/GoogleUtilities_Privacy.bundle", - "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/FBLPromises_Privacy.bundle", - "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/nanopb_Privacy.bundle", - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-PriceWidgetExtension/Pods-PriceWidgetExtension-resources.sh\"\n"; - showEnvVarsInLog = 0; - }; /* End PBXShellScriptBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ @@ -1629,7 +1264,6 @@ /* Begin XCBuildConfiguration section */ 0299CE802886202800B5C7E7 /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 239585D5B37F4FBD1470F62D /* Pods-ImageNotification.debug.xcconfig */; buildSettings = { APPLICATION_EXTENSION_API_ONLY = YES; CLANG_ANALYZER_NONNULL = YES; @@ -1680,7 +1314,6 @@ }; 0299CE812886202800B5C7E7 /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = E060F33194FF363EC0431250 /* Pods-ImageNotification.release.xcconfig */; buildSettings = { APPLICATION_EXTENSION_API_ONLY = YES; CLANG_ANALYZER_NONNULL = YES; @@ -1732,7 +1365,6 @@ }; 0299CE822886202800B5C7E7 /* LocalRelease */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 3FEB7D565693086934123364 /* Pods-ImageNotification.localrelease.xcconfig */; buildSettings = { APPLICATION_EXTENSION_API_ONLY = YES; CLANG_ANALYZER_NONNULL = YES; @@ -1781,7 +1413,6 @@ }; 0299CE832886202800B5C7E7 /* Staging */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 5D4F7BDB5458BA6BF08E99B6 /* Pods-ImageNotification.staging.xcconfig */; buildSettings = { APPLICATION_EXTENSION_API_ONLY = YES; CLANG_ANALYZER_NONNULL = YES; @@ -1830,7 +1461,6 @@ }; 13B07F941A680F5B00A75B9A /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = A4C7384F262FF1BCFABB462D /* Pods-Rainbow.debug.xcconfig */; buildSettings = { ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; APPLICATION_EXTENSION_API_ONLY = NO; @@ -1908,7 +1538,6 @@ }; 13B07F951A680F5B00A75B9A /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 15004743AF62EF3EE384E855 /* Pods-Rainbow.release.xcconfig */; buildSettings = { ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; APPLICATION_EXTENSION_API_ONLY = NO; @@ -2029,7 +1658,6 @@ }; 2C6A799821127ED9003AFB37 /* Staging */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 9E9F7E918EFBFBAF381621C7 /* Pods-Rainbow.staging.xcconfig */; buildSettings = { ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; APPLICATION_EXTENSION_API_ONLY = NO; @@ -2146,7 +1774,6 @@ }; 2C87B79A2197FA1900682EC4 /* LocalRelease */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 3BBE9F9F842B95CFF7E85DB8 /* Pods-Rainbow.localrelease.xcconfig */; buildSettings = { ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; APPLICATION_EXTENSION_API_ONLY = NO; @@ -2320,7 +1947,6 @@ }; C16DCF6A272BA6F100FF5C78 /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 00A32D3367A149262C6C4D33 /* Pods-PriceWidgetExtension.debug.xcconfig */; buildSettings = { APPLICATION_EXTENSION_API_ONLY = YES; ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; @@ -2370,7 +1996,6 @@ }; C16DCF6B272BA6F100FF5C78 /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = EAF3EBD98BA704022718B359 /* Pods-PriceWidgetExtension.release.xcconfig */; buildSettings = { APPLICATION_EXTENSION_API_ONLY = YES; ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; @@ -2421,7 +2046,6 @@ }; C16DCF6C272BA6F100FF5C78 /* LocalRelease */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 6B24FBC9AFF649E6E37FF985 /* Pods-PriceWidgetExtension.localrelease.xcconfig */; buildSettings = { APPLICATION_EXTENSION_API_ONLY = YES; ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; @@ -2469,7 +2093,6 @@ }; C16DCF6D272BA6F100FF5C78 /* Staging */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 11D30486FEF77968C16FDF7D /* Pods-PriceWidgetExtension.staging.xcconfig */; buildSettings = { APPLICATION_EXTENSION_API_ONLY = YES; ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; @@ -2517,7 +2140,6 @@ }; C16DCFA0272BAB9600FF5C78 /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = AE024FCA8C28D21E9E1EA378 /* Pods-SelectTokenIntent.debug.xcconfig */; buildSettings = { APPLICATION_EXTENSION_API_ONLY = YES; CLANG_ANALYZER_NONNULL = YES; @@ -2565,7 +2187,6 @@ }; C16DCFA1272BAB9600FF5C78 /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = D657340CCBF77C82579CE8A1 /* Pods-SelectTokenIntent.release.xcconfig */; buildSettings = { APPLICATION_EXTENSION_API_ONLY = YES; CLANG_ANALYZER_NONNULL = YES; @@ -2614,7 +2235,6 @@ }; C16DCFA2272BAB9600FF5C78 /* LocalRelease */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 388CCCEFC8BB73A757574C99 /* Pods-SelectTokenIntent.localrelease.xcconfig */; buildSettings = { APPLICATION_EXTENSION_API_ONLY = YES; CLANG_ANALYZER_NONNULL = YES; @@ -2660,7 +2280,6 @@ }; C16DCFA3272BAB9600FF5C78 /* Staging */ = { isa = XCBuildConfiguration; - baseConfigurationReference = CF8B843EAE21E6291C0C6702 /* Pods-SelectTokenIntent.staging.xcconfig */; buildSettings = { APPLICATION_EXTENSION_API_ONLY = YES; CLANG_ANALYZER_NONNULL = YES; diff --git a/package.json b/package.json index 6db7ad5fdfe..c5d97861b98 100644 --- a/package.json +++ b/package.json @@ -377,7 +377,7 @@ "ts-jest": "29.1.1", "ts-loader": "9.5.1", "ts-migrate": "0.1.26", - "typescript": "5.1.6", + "typescript": "5.5.4", "typescript-coverage-report": "0.6.1", "webpack": "5.94.0", "webpack-cli": "5.1.4" diff --git a/src/App.tsx b/src/App.tsx index 9468d237947..0e9ff68698e 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -23,7 +23,7 @@ import * as keychain from '@/model/keychain'; import { Navigation } from '@/navigation'; import { PersistQueryClientProvider, persistOptions, queryClient } from '@/react-query'; import store, { AppDispatch, type AppState } from '@/redux/store'; -import { MainThemeProvider } from '@/theme/ThemeContext'; +import { MainThemeProvider, useTheme } from '@/theme/ThemeContext'; import { addressKey } from '@/utils/keychainConstants'; import { SharedValuesProvider } from '@/helpers/SharedValuesContext'; import { InitialRouteContext } from '@/navigation/initialRoute'; diff --git a/src/__swaps__/screens/Swap/components/GasButton.tsx b/src/__swaps__/screens/Swap/components/GasButton.tsx index 02532433b44..384e3e2f232 100644 --- a/src/__swaps__/screens/Swap/components/GasButton.tsx +++ b/src/__swaps__/screens/Swap/components/GasButton.tsx @@ -14,7 +14,6 @@ import { swapsStore } from '@/state/swaps/swapsStore'; import { gasUtils } from '@/utils'; import React, { PropsWithChildren, ReactNode, useCallback, useMemo } from 'react'; import { StyleSheet } from 'react-native'; -import { OnPressMenuItemEventObject } from 'react-native-ios-context-menu'; import Animated, { runOnUI, useAnimatedStyle } from 'react-native-reanimated'; import { THICK_BORDER_WIDTH } from '../constants'; import { GasSettings, useCustomGasSettings } from '../hooks/useCustomGas'; @@ -135,7 +134,7 @@ const GasMenu = ({ backToReview = false, children }: { backToReview?: boolean; c ); const handlePressMenuItem = useCallback( - ({ nativeEvent: { actionKey } }: OnPressMenuItemEventObject) => handlePressSpeedOption(actionKey as GasSpeed), + ({ nativeEvent: { actionKey } }: { nativeEvent: { actionKey: GasSpeed } }) => handlePressSpeedOption(actionKey), [handlePressSpeedOption] ); @@ -149,8 +148,6 @@ const GasMenu = ({ backToReview = false, children }: { backToReview?: boolean; c const menuConfig = useMemo(() => { const menuItems = menuOptions.map(gasOption => { - if (IS_ANDROID) return gasOption; - const currentBaseFee = getCachedCurrentBaseFee(chainId); const gasSettings = gasOption === GasSpeed.CUSTOM ? customGasSettings : metereologySuggestions.data?.[gasOption]; const subtitle = getEstimatedFeeRangeInGwei(gasSettings, currentBaseFee); @@ -176,7 +173,7 @@ const GasMenu = ({ backToReview = false, children }: { backToReview?: boolean; c isAnchoredToRight isMenuPrimaryAction onPressActionSheet={handlePressActionSheet} - options={menuConfig.menuItems} + options={menuOptions} useActionSheetFallback={false} wrapNativeComponent={false} > @@ -186,14 +183,11 @@ const GasMenu = ({ backToReview = false, children }: { backToReview?: boolean; c ) : ( {children} diff --git a/src/components/DappBrowser/search/results/SearchResults.tsx b/src/components/DappBrowser/search/results/SearchResults.tsx index e7bf159980f..44203c49bec 100644 --- a/src/components/DappBrowser/search/results/SearchResults.tsx +++ b/src/components/DappBrowser/search/results/SearchResults.tsx @@ -54,12 +54,9 @@ const search = (query: string, dapps: Dapp[], numberOfResults = 4): Dapp[] => { if (b?.trending === true && a?.trending !== true) return 1; if (a?.trending === true && b?.trending !== true) return -1; - // @ts-expect-error: Need to fix these types const relevanceDiff = b.relevance - a.relevance; if (relevanceDiff === 0) { - // @ts-expect-error: Same here const aWordCount = a.name.split(' ').length; - // @ts-expect-error: Same here const bWordCount = b.name.split(' ').length; return aWordCount - bWordCount; } @@ -74,7 +71,6 @@ const search = (query: string, dapps: Dapp[], numberOfResults = 4): Dapp[] => { return [{ url: query, urlDisplay: query, name: query, isDirect: true } as unknown as Dapp, ...(dappResults as Dapp[])]; } - // @ts-expect-error: Same here return filteredDapps; }; diff --git a/src/components/animations/ButtonPressAnimation/ButtonPressAnimation.android.tsx b/src/components/animations/ButtonPressAnimation/ButtonPressAnimation.android.tsx index 9bdecba75e5..e2b0276fbe8 100644 --- a/src/components/animations/ButtonPressAnimation/ButtonPressAnimation.android.tsx +++ b/src/components/animations/ButtonPressAnimation/ButtonPressAnimation.android.tsx @@ -1,6 +1,6 @@ /* eslint-disable react/no-unused-prop-types */ /* 👆 Had to disable this ESLint rule it was false positive on shared Props interface */ -import React, { PropsWithChildren, useCallback, useContext, useMemo } from 'react'; +import React, { forwardRef, PropsWithChildren, useCallback, useContext, useMemo } from 'react'; import { processColor, requireNativeComponent, StyleProp, StyleSheet, View, ViewStyle } from 'react-native'; import { createNativeWrapper, NativeViewGestureHandlerGestureEvent, RawButtonProps } from 'react-native-gesture-handler'; import { PureNativeButton } from 'react-native-gesture-handler/src/components/GestureButtons'; @@ -62,19 +62,22 @@ const OVERFLOW_MARGIN = 5; const transparentColor = processColor('transparent'); -const ScaleButton = ({ - children, - contentContainerStyle, - duration, - exclusive, - minLongPressDuration, - onLongPress, - onPress, - overflowMargin, - scaleTo = 0.86, - wrapperStyle, - testID, -}: PropsWithChildren) => { +const ScaleButton = forwardRef(function ScaleButton( + { + children, + contentContainerStyle, + duration, + exclusive, + minLongPressDuration, + onLongPress, + onPress, + overflowMargin, + scaleTo = 0.86, + wrapperStyle, + testID, + }: PropsWithChildren, + ref +) { const parentScale = useContext(ScaleButtonContext); const childScale = useSharedValue(1); const scale = parentScale || childScale; @@ -128,8 +131,11 @@ const ScaleButton = ({ runOnJS(handleCancel)(); }, }); + return ( - + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-ignore + @@ -141,26 +147,29 @@ const ScaleButton = ({ ); -}; +}); -const SimpleScaleButton = ({ - children, - duration, - exclusive, - minLongPressDuration, - onLongPress, - onLongPressEnded, - shouldLongPressHoldPress, - isLongPress, - hapticType, - enableHapticFeedback, - onPress, - scaleTo, - transformOrigin, - wrapperStyle, - testID, - disallowInterruption, -}: Props) => { +const SimpleScaleButton = forwardRef(function SimpleScaleButton( + { + children, + duration, + exclusive, + minLongPressDuration, + onLongPress, + onLongPressEnded, + shouldLongPressHoldPress, + isLongPress, + hapticType, + enableHapticFeedback, + onPress, + scaleTo, + transformOrigin, + wrapperStyle, + testID, + disallowInterruption, + }: Props, + ref +) { const onNativePress = useCallback( ({ nativeEvent: { type } }: any) => { if (type === 'longPress') { @@ -191,43 +200,51 @@ const SimpleScaleButton = ({ testID={testID} transformOrigin={transformOrigin} disallowInterruption={disallowInterruption} + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-ignore + ref={ref} > {children} ); -}; +}); -export default function ButtonPressAnimation({ - backgroundColor = 'transparent', - borderRadius = 0, - children, - contentContainerStyle, - disabled, - duration = 160, - exclusive, - minLongPressDuration = 500, - onLayout, - onLongPress, - onLongPressEnded, - shouldLongPressHoldPress, - onPress, - overflowMargin = OVERFLOW_MARGIN, - reanimatedButton, - scaleTo = 0.86, - skipTopMargin, - style, - testID, - transformOrigin, - wrapperStyle, - hapticType = 'selection', - enableHapticFeedback = true, - disallowInterruption = false, -}: Props) { +export default forwardRef(function ButtonPressAnimation( + { + backgroundColor = 'transparent', + borderRadius = 0, + children, + contentContainerStyle, + disabled, + duration = 160, + exclusive, + minLongPressDuration = 500, + onLayout, + onLongPress, + onLongPressEnded, + shouldLongPressHoldPress, + onPress, + overflowMargin = OVERFLOW_MARGIN, + reanimatedButton, + scaleTo = 0.86, + skipTopMargin, + style, + testID, + transformOrigin, + wrapperStyle, + hapticType = 'selection', + enableHapticFeedback = true, + disallowInterruption = false, + }: Props, + ref +) { const normalizedTransformOrigin = useMemo(() => normalizeTransformOrigin(transformOrigin), [transformOrigin]); const ButtonElement = reanimatedButton ? ScaleButton : SimpleScaleButton; return disabled ? ( - + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-ignore + {children} ) : ( @@ -253,13 +270,14 @@ export default function ButtonPressAnimation({ transformOrigin={normalizedTransformOrigin} wrapperStyle={wrapperStyle} disallowInterruption={disallowInterruption} + ref={ref} > {children} ); -} +}); const sx = StyleSheet.create({ overflow: { diff --git a/src/components/asset-list/RecyclerAssetList2/WrappedCollectiblesHeader.tsx b/src/components/asset-list/RecyclerAssetList2/WrappedCollectiblesHeader.tsx index dd2e35bc445..d63f31eb009 100644 --- a/src/components/asset-list/RecyclerAssetList2/WrappedCollectiblesHeader.tsx +++ b/src/components/asset-list/RecyclerAssetList2/WrappedCollectiblesHeader.tsx @@ -2,10 +2,12 @@ import React from 'react'; import { Box, Inline, Text } from '@/design-system'; import * as i18n from '@/languages'; import { ListHeaderMenu } from '@/components/list/ListHeaderMenu'; -import { NftCollectionSortCriterion } from '@/graphql/__generated__/arc'; -import useNftSort from '@/hooks/useNFTsSortBy'; +import { NftCollectionSortCriterion, SortDirection } from '@/graphql/__generated__/arc'; +import { NftSort, parseNftSort, useNftSort } from '@/hooks/useNFTsSortBy'; +import { colors } from '@/styles'; import { useRemoteConfig } from '@/model/remoteConfig'; import { NFTS_ENABLED, useExperimentalFlag } from '@/config'; +import { IS_ANDROID, IS_IOS } from '@/env'; const TokenFamilyHeaderHeight = 48; @@ -32,9 +34,9 @@ const getMenuItemIcon = (value: NftCollectionSortCriterion) => { }; const CollectiblesHeader = () => { + const { nftSort, nftSortDirection, updateNFTSort } = useNftSort(); const { nfts_enabled } = useRemoteConfig(); const nftsEnabled = useExperimentalFlag(NFTS_ENABLED) || nfts_enabled; - const { nftSort, updateNFTSort } = useNftSort(); if (!nftsEnabled) return null; @@ -53,14 +55,44 @@ const CollectiblesHeader = () => { ({ - actionKey: value, - actionTitle: i18n.t(i18n.l.nfts.sort[value]), - icon: { iconType: 'SYSTEM', iconValue: getMenuItemIcon(value) }, - menuState: nftSort === key ? 'on' : 'off', - }))} - selectItem={string => updateNFTSort(string as NftCollectionSortCriterion)} + selected={`${nftSort}|${nftSortDirection}`} + menuItems={Object.values(NftCollectionSortCriterion).map(sortCriterion => { + return { + icon: { iconType: 'SYSTEM', iconValue: getMenuItemIcon(sortCriterion) }, + ...(nftSort === sortCriterion && IS_IOS // submenus look weird in android, so it toggles when clicking the same item + ? { + menuTitle: i18n.t(i18n.l.nfts.sort[sortCriterion]), + menuPreferredElementSize: 'small', + menuState: 'on', + menuItems: [ + { + actionKey: `${sortCriterion}|${SortDirection.Asc}`, + actionTitle: i18n.t(i18n.l.nfts.sort.order.asc), + icon: { + iconType: 'SYSTEM', + iconValue: 'arrow.up.circle', + iconTint: nftSortDirection === SortDirection.Asc ? colors.grey : undefined, + }, + }, + { + actionKey: `${sortCriterion}|${SortDirection.Desc}`, + actionTitle: i18n.t(i18n.l.nfts.sort.order.desc), + icon: { + iconType: 'SYSTEM', + iconValue: 'arrow.down.circle', + iconTint: nftSortDirection === SortDirection.Desc ? colors.grey : undefined, + }, + }, + ], + } + : { + actionKey: `${sortCriterion}|${nftSortDirection === SortDirection.Asc ? SortDirection.Desc : SortDirection.Asc}`, + actionTitle: i18n.t(i18n.l.nfts.sort[sortCriterion]), + menuState: 'off', + }), + }; + })} + selectItem={updateNFTSort} icon={getIconForSortType(nftSort)} text={i18n.t(i18n.l.nfts.sort[nftSort])} /> diff --git a/src/components/asset-list/RecyclerAssetList2/profile-header/ProfileAvatarRow.tsx b/src/components/asset-list/RecyclerAssetList2/profile-header/ProfileAvatarRow.tsx index 19d0760d3c1..2fd5952179c 100644 --- a/src/components/asset-list/RecyclerAssetList2/profile-header/ProfileAvatarRow.tsx +++ b/src/components/asset-list/RecyclerAssetList2/profile-header/ProfileAvatarRow.tsx @@ -118,11 +118,7 @@ export function ProfileAvatarRow({ size = ProfileAvatarSize }: { size?: number } - + undefined; @@ -157,7 +158,7 @@ export default function AddressRow({ contextMenuActions, data, editMode, onPress }, ...(notificationsEnabled - ? [ + ? ([ { actionKey: ContextMenuKeys.Notifications, actionTitle: lang.t('wallet.action.notifications.action_title'), @@ -166,18 +167,15 @@ export default function AddressRow({ contextMenuActions, data, editMode, onPress iconValue: 'bell.fill', }, }, - ] + ] as const) : []), { actionKey: ContextMenuKeys.Remove, actionTitle: lang.t('wallet.action.remove'), - icon: { - iconType: 'SYSTEM', - iconValue: 'trash.fill', - }, + icon: { iconType: 'SYSTEM', iconValue: 'trash.fill' }, menuAttributes: ['destructive'], }, - ]; + ] satisfies MenuActionConfig[]; const menuConfig = { menuItems: contextMenuItems, diff --git a/src/components/ens-profile/ActionButtons/MoreButton.tsx b/src/components/ens-profile/ActionButtons/MoreButton.tsx index dd4dc741f51..1e662c71302 100644 --- a/src/components/ens-profile/ActionButtons/MoreButton.tsx +++ b/src/components/ens-profile/ActionButtons/MoreButton.tsx @@ -2,7 +2,6 @@ import { useRoute } from '@react-navigation/native'; import lang from 'i18n-js'; import React, { useCallback, useMemo } from 'react'; import { Keyboard, Share } from 'react-native'; -import { MenuActionConfig } from 'react-native-ios-context-menu'; import { showDeleteContactActionSheet } from '../../contacts'; import More from '../MoreButton/MoreButton'; import ContextMenuButton from '@/components/native-context-menu/contextMenu'; @@ -45,14 +44,18 @@ export default function MoreButton({ address, ensName }: { address?: string; ens const menuItems = useMemo(() => { return [ - isWatching && { - actionKey: ACTIONS.OPEN_WALLET, - actionTitle: lang.t('profiles.details.open_wallet'), - icon: { - iconType: 'SYSTEM', - iconValue: 'iphone.and.arrow.forward', - }, - }, + ...(isWatching + ? [ + { + actionKey: ACTIONS.OPEN_WALLET, + actionTitle: lang.t('profiles.details.open_wallet'), + icon: { + iconType: 'SYSTEM', + iconValue: 'iphone.and.arrow.forward', + }, + }, + ] + : []), { actionKey: ACTIONS.COPY_ADDRESS, actionTitle: lang.t('profiles.details.copy_address'), @@ -95,7 +98,7 @@ export default function MoreButton({ address, ensName }: { address?: string; ens iconValue: 'square.and.arrow.up', }, }, - ].filter(Boolean) as MenuActionConfig[]; + ].filter(Boolean); }, [isWatching, formattedAddress, contact]); const handlePressMenuItem = useCallback( diff --git a/src/components/expanded-state/unique-token/UniqueTokenExpandedStateHeader.tsx b/src/components/expanded-state/unique-token/UniqueTokenExpandedStateHeader.tsx index fc66ccb8987..990158f132b 100644 --- a/src/components/expanded-state/unique-token/UniqueTokenExpandedStateHeader.tsx +++ b/src/components/expanded-state/unique-token/UniqueTokenExpandedStateHeader.tsx @@ -21,7 +21,6 @@ import isSVGImage from '@/utils/isSVG'; import { refreshNFTContractMetadata, reportNFT } from '@/resources/nfts/simplehash'; import { ContextCircleButton } from '@/components/context-menu'; import { IS_ANDROID, IS_IOS } from '@/env'; -import { MenuActionConfig, MenuConfig } from 'react-native-ios-context-menu'; import { ChainId } from '@/chains/types'; const AssetActionsEnum = { @@ -262,7 +261,7 @@ const UniqueTokenExpandedStateHeader = ({ const isENS = asset.asset_contract?.address?.toLowerCase() === ENS_NFT_CONTRACT_ADDRESS.toLowerCase(); const isPhotoDownloadAvailable = !isSVG && !isENS; - const assetMenuConfig: MenuConfig = useMemo(() => { + const assetMenuConfig = useMemo(() => { const AssetActions = getAssetActions({ chainId: asset.chainId }); return { @@ -443,11 +442,7 @@ const UniqueTokenExpandedStateHeader = ({ const familyNameHitSlop: Space = '19px (Deprecated)'; const assetMenuOptions = useMemo(() => { - return ( - assetMenuConfig?.menuItems - ?.filter((item): item is MenuActionConfig => 'actionTitle' in item) - .map((item: MenuActionConfig) => item.actionTitle) ?? [] - ); + return assetMenuConfig?.menuItems?.filter(item => 'actionTitle' in item).map(item => item.actionTitle) ?? []; }, [assetMenuConfig]); return ( @@ -463,8 +458,8 @@ const UniqueTokenExpandedStateHeader = ({ { - const actionItems = (assetMenuConfig?.menuItems || []).filter((item): item is MenuActionConfig => 'actionTitle' in item); - const actionKey: MenuActionConfig = actionItems[index]; + const actionItems = (assetMenuConfig?.menuItems || []).filter(item => 'actionTitle' in item); + const actionKey = actionItems[index]; if (!actionKey) return; handlePressAssetMenuItem({ nativeEvent: { actionKey: actionKey.actionKey }, diff --git a/src/components/gas/GasSpeedButton.tsx b/src/components/gas/GasSpeedButton.tsx index 6157eed4389..d1c11840748 100644 --- a/src/components/gas/GasSpeedButton.tsx +++ b/src/components/gas/GasSpeedButton.tsx @@ -29,8 +29,8 @@ import { EthCoinIcon } from '../coin-icon/EthCoinIcon'; import { ChainId } from '@/chains/types'; import { chainsGasSpeeds } from '@/chains'; import { ThemeContextProps, useTheme } from '@/theme'; -import { OnPressMenuItemEventObject } from 'react-native-ios-context-menu'; import { ParsedAddressAsset } from '@/entities'; +import { GasSpeed } from '@/__swaps__/types/gas'; const { GAS_EMOJIS, GAS_ICONS, GasSpeedOrder, CUSTOM, URGENT, NORMAL, FAST, getGasLabel } = gasUtils; @@ -365,9 +365,7 @@ const GasSpeedButton = ({ }, [chainId, crossChainServiceTime, inputCurrency, navigate, outputCurrency]); const handlePressMenuItem = useCallback( - ({ nativeEvent: { actionKey } }: OnPressMenuItemEventObject) => { - handlePressSpeedOption(actionKey); - }, + ({ nativeEvent: { actionKey } }: { nativeEvent: { actionKey: GasSpeed } }) => handlePressSpeedOption(actionKey), [handlePressSpeedOption] ); @@ -397,8 +395,6 @@ const GasSpeedButton = ({ const menuConfig = useMemo(() => { const menuOptions = speedOptions?.map(gasOption => { - if (IS_ANDROID) return gasOption; - const totalGwei = add(gasFeeParamsBySpeed[gasOption]?.maxBaseFee?.gwei, gasFeeParamsBySpeed[gasOption]?.maxPriorityFeePerGas?.gwei); const estimatedGwei = add(currentBlockParams?.baseFeePerGas?.gwei, gasFeeParamsBySpeed[gasOption]?.maxPriorityFeePerGas?.gwei); @@ -463,7 +459,7 @@ const GasSpeedButton = ({ isAnchoredToRight isMenuPrimaryAction onPressActionSheet={handlePressActionSheet} - options={menuConfig.menuItems} + options={speedOptions} useActionSheetFallback={false} wrapNativeComponent={false} > @@ -474,14 +470,12 @@ const GasSpeedButton = ({ return ( {pager} @@ -493,6 +487,7 @@ const GasSpeedButton = ({ handlePressActionSheet, handlePressMenuItem, menuConfig, + speedOptions, rawColorForAsset, selectedGasFeeOption, showGasOptions, diff --git a/src/components/list/ListHeaderMenu.tsx b/src/components/list/ListHeaderMenu.tsx index f39df68a365..d95d80c091a 100644 --- a/src/components/list/ListHeaderMenu.tsx +++ b/src/components/list/ListHeaderMenu.tsx @@ -1,20 +1,14 @@ import React from 'react'; -import ContextMenuButton from '@/components/native-context-menu/contextMenu'; +import ContextMenuButton, { MenuConfig } from '@/components/native-context-menu/contextMenu'; import { ButtonPressAnimation } from '@/components/animations'; import { Bleed, Box, Inline, Text, useForegroundColor } from '@/design-system'; +import { NftSort } from '@/hooks/useNFTsSortBy'; import { haptics } from '@/utils'; -import { NftCollectionSortCriterion } from '@/graphql/__generated__/arc'; - -type MenuItem = { - actionKey: string; - actionTitle: string; - menuState?: 'on' | 'off'; -}; type ListHeaderMenuProps = { - selected: NftCollectionSortCriterion; - menuItems: MenuItem[]; - selectItem: (item: string) => void; + selected: NftSort; + menuItems: MenuConfig['menuItems']; + selectItem: (item: NftSort) => void; icon: string; text: string; }; @@ -29,12 +23,12 @@ export function ListHeaderMenu({ menuItems, selectItem, icon, text }: ListHeader const onPressMenuItem = ({ nativeEvent: { actionKey: item } }: { nativeEvent: { actionKey: string } }) => { haptics.selection(); - selectItem(item); + selectItem(item as NftSort); }; return ( - + void; + shouldOpenOnLongPress?: boolean; + style?: NativeMenuComponentProps['style']; +}>) { const actions = useMemo(() => { const items = []; if (menuTitle) { items.push({ - attributes: { - disabled: true, - }, + attributes: { disabled: true }, id: 'title', title: menuTitle, }); @@ -29,13 +34,13 @@ export default function ContextMenuAndroid({ ...(menuItems || []).map(item => ({ id: item.actionKey, image: item.icon?.iconValue, - title: item.actionTitle || item.menuTitle, + title: item.actionTitle || item.menuTitle || '', ...(item.menuTitle && { titleColor: 'black', subactions: item.menuItems.map(item => ({ id: item.actionKey, image: item.icon?.iconValue, - title: item.actionTitle, + title: item.actionTitle || '', })), }), })) @@ -45,12 +50,9 @@ export default function ContextMenuAndroid({ return items; }, [menuItems, menuTitle]); - const onPressAction = useLatestCallback( - ({ nativeEvent: { event } }) => { - return onPressMenuItem({ nativeEvent: { actionKey: event } }); - }, - [onPressMenuItem] - ); + const onPressAction = useLatestCallback<({ nativeEvent }: NativeActionEvent) => void>(({ nativeEvent: { event } }) => { + return onPressMenuItem({ nativeEvent: { actionKey: event } }); + }); return ( {children} diff --git a/src/components/native-context-menu/contextMenu.js b/src/components/native-context-menu/contextMenu.js deleted file mode 100644 index fbe320a1a44..00000000000 --- a/src/components/native-context-menu/contextMenu.js +++ /dev/null @@ -1,6 +0,0 @@ -import React from 'react'; -import { ContextMenuButton } from 'react-native-ios-context-menu'; - -export default function ContextMenu(props) { - return ; -} diff --git a/src/components/native-context-menu/contextMenu.tsx b/src/components/native-context-menu/contextMenu.tsx new file mode 100644 index 00000000000..e2f304d0cf4 --- /dev/null +++ b/src/components/native-context-menu/contextMenu.tsx @@ -0,0 +1,58 @@ +/* eslint-disable react/jsx-props-no-spreading */ +import React, { PropsWithChildren } from 'react'; +import { + ContextMenuButton, + ContextMenuButtonProps, + DynamicColor, + MenuAttributes, + MenuElementSize, + MenuState, + UIMenuOptions, +} from 'react-native-ios-context-menu'; + +/** + * This components was widely used throughout the app but without types (.js file all as any) + * even tho it works fine, transitioning to typescript makes a lot scream + * so I recreate the 'react-native-ios-context-menu' types here in a less strict way + * just to not have to deal with the strictness of the original types + */ + +// eslint-disable-next-line @typescript-eslint/ban-types +type IconConfig = { iconType: 'ASSET' | 'SYSTEM' | (string & {}); iconValue: string; iconTint?: string | DynamicColor }; + +type MenuActionConfig = Readonly< + { + actionSubtitle?: string; + // eslint-disable-next-line @typescript-eslint/ban-types + menuState?: MenuState | (string & {}); + menuAttributes?: Array; + discoverabilityTitle?: string; + icon?: IconConfig; + } & ( + | { menuTitle: string; menuItems: Readonly>; actionKey?: never; actionTitle?: never } + | { menuTitle?: never; menuItems?: never; actionKey: string; actionTitle: string } + ) +>; + +export type MenuConfig = Readonly<{ + menuTitle?: string; + menuItems: Readonly>; + menuSubtitle?: string; + menuOptions?: Array; + menuPreferredElementSize?: MenuElementSize; + icon?: IconConfig; +}>; + +export default function ContextMenu( + props: PropsWithChildren< + Omit & { + menuConfig: MenuConfig; + onPressMenuItem: (e: { nativeEvent: Omit & { actionKey: any } }) => void; + isAnchoredToRight?: boolean; // this only used in android check contextMenu.android.tsx in this same folder + } + > +) { + // @ts-expect-error `activeOpacity` and `wrapNativeComponent` are missing in the `ContextMenuButtonProps` type but are valid + // https://www.npmjs.com/package/react-native-ios-context-menu/v/1.2.1#312-contextmenubutton-component + return ; +} diff --git a/src/hooks/useNFTsSortBy.ts b/src/hooks/useNFTsSortBy.ts index 345f20132a7..2fb5f83531b 100644 --- a/src/hooks/useNFTsSortBy.ts +++ b/src/hooks/useNFTsSortBy.ts @@ -1,31 +1,27 @@ -import { useCallback } from 'react'; -import { MMKV, useMMKVString } from 'react-native-mmkv'; +import { NftCollectionSortCriterion, SortDirection } from '@/graphql/__generated__/arc'; +import { useMMKVString } from 'react-native-mmkv'; import useAccountSettings from './useAccountSettings'; -import { NftCollectionSortCriterion } from '@/graphql/__generated__/arc'; -const mmkv = new MMKV(); const getStorageKey = (accountAddress: string) => `nfts-sort-${accountAddress}`; -export const getNftSortForAddress = (accountAddress: string) => { - return mmkv.getString(getStorageKey(accountAddress)) as NftCollectionSortCriterion; +export const parseNftSort = (s: string | undefined) => { + const [sortBy = NftCollectionSortCriterion.MostRecent, sortDirection = SortDirection.Desc] = (s?.split('|') || []) as [ + sortBy?: NftCollectionSortCriterion, + sortDirection?: SortDirection, + ]; + return [sortBy, sortDirection] as const; }; -export default function useNftSort(): { - nftSort: NftCollectionSortCriterion; - updateNFTSort: (sortBy: NftCollectionSortCriterion) => void; -} { - const { accountAddress } = useAccountSettings(); - const [nftSort, setNftSort] = useMMKVString(getStorageKey(accountAddress)); +export type NftSort = `${NftCollectionSortCriterion}|${SortDirection}`; - const updateNFTSort = useCallback( - (sortBy: NftCollectionSortCriterion) => { - setNftSort(sortBy); - }, - [setNftSort] - ); +export function useNftSort() { + const { accountAddress } = useAccountSettings(); + const [nftSortData, setNftSortData] = useMMKVString(getStorageKey(accountAddress)); + const [sortBy, sortDirection] = parseNftSort(nftSortData); return { - updateNFTSort, - nftSort: (nftSort as NftCollectionSortCriterion) || NftCollectionSortCriterion.MostRecent, + updateNFTSort: (nftSort: NftSort) => setNftSortData(nftSort), + nftSort: sortBy, + nftSortDirection: sortDirection, }; } diff --git a/src/hooks/useRefreshAccountData.ts b/src/hooks/useRefreshAccountData.ts index d33f98b97b0..7b550a7d559 100644 --- a/src/hooks/useRefreshAccountData.ts +++ b/src/hooks/useRefreshAccountData.ts @@ -9,9 +9,8 @@ import { logger, RainbowError } from '@/logger'; import { queryClient } from '@/react-query'; import { userAssetsQueryKey } from '@/resources/assets/UserAssetsQuery'; import { userAssetsQueryKey as swapsUserAssetsQueryKey } from '@/__swaps__/screens/Swap/resources/assets/userAssets'; -import { nftsQueryKey } from '@/resources/nfts'; +import { invalidateAddressNftsQueries } from '@/resources/nfts'; import { positionsQueryKey } from '@/resources/defi/PositionsQuery'; -import useNftSort from './useNFTsSortBy'; import { Address } from 'viem'; import { addysSummaryQueryKey } from '@/resources/summary/summary'; import useWallets from './useWallets'; @@ -23,7 +22,6 @@ export default function useRefreshAccountData() { const { accountAddress, nativeCurrency } = useAccountSettings(); const [isRefreshing, setIsRefreshing] = useState(false); const profilesEnabled = useExperimentalFlag(PROFILES); - const { nftSort } = useNftSort(); const { connectedToHardhat } = useConnectedToHardhatStore(); const { wallets } = useWallets(); @@ -34,7 +32,7 @@ export default function useRefreshAccountData() { ); const fetchAccountData = useCallback(async () => { - queryClient.invalidateQueries(nftsQueryKey({ address: accountAddress, sortBy: nftSort })); + invalidateAddressNftsQueries(accountAddress); queryClient.invalidateQueries(positionsQueryKey({ address: accountAddress as Address, currency: nativeCurrency })); queryClient.invalidateQueries(claimablesQueryKey({ address: accountAddress, currency: nativeCurrency })); queryClient.invalidateQueries(addysSummaryQueryKey({ addresses: allAddresses, currency: nativeCurrency })); @@ -57,7 +55,7 @@ export default function useRefreshAccountData() { logger.error(new RainbowError(`[useRefreshAccountData]: Error refreshing data: ${error}`)); throw error; } - }, [accountAddress, allAddresses, connectedToHardhat, dispatch, nativeCurrency, nftSort, profilesEnabled]); + }, [accountAddress, allAddresses, connectedToHardhat, dispatch, nativeCurrency, profilesEnabled]); const refresh = useCallback(async () => { if (isRefreshing) return; diff --git a/src/hooks/useWalletSectionsData.ts b/src/hooks/useWalletSectionsData.ts index aced536088e..173dd795a36 100644 --- a/src/hooks/useWalletSectionsData.ts +++ b/src/hooks/useWalletSectionsData.ts @@ -4,13 +4,13 @@ import useCoinListEditOptions from './useCoinListEditOptions'; import useCoinListEdited from './useCoinListEdited'; import useHiddenTokens from './useHiddenTokens'; import useIsWalletEthZero from './useIsWalletEthZero'; +import { useNftSort } from './useNFTsSortBy'; import useSendableUniqueTokens from './useSendableUniqueTokens'; import useShowcaseTokens from './useShowcaseTokens'; import useWallets from './useWallets'; import { buildBriefWalletSectionsSelector } from '@/helpers/buildWalletSections'; import { useSortedUserAssets } from '@/resources/assets/useSortedUserAssets'; import { useLegacyNFTs } from '@/resources/nfts'; -import useNftSort from './useNFTsSortBy'; import useWalletsWithBalancesAndNames from './useWalletsWithBalancesAndNames'; import { useRemoteConfig } from '@/model/remoteConfig'; import { usePositions } from '@/resources/defi/PositionsQuery'; @@ -54,7 +54,7 @@ export default function useWalletSectionsData({ const { isLoading: isLoadingUserAssets, data: sortedAssets = [] } = useSortedUserAssets(); const isWalletEthZero = useIsWalletEthZero(); - const { nftSort } = useNftSort(); + const { nftSort, nftSortDirection } = useNftSort(); const { accountAddress, language, network, nativeCurrency } = useAccountSettings(); const { sendableUniqueTokens } = useSendableUniqueTokens(); @@ -64,6 +64,7 @@ export default function useWalletSectionsData({ } = useLegacyNFTs({ address: accountAddress, sortBy: nftSort, + sortDirection: nftSortDirection, }); const { data: positions } = usePositions({ address: accountAddress, currency: nativeCurrency }); const { data: claimables } = useClaimables({ address: accountAddress, currency: nativeCurrency }); diff --git a/src/hooks/useWatchPendingTxs.ts b/src/hooks/useWatchPendingTxs.ts index 9d5c6fc825c..afffad810da 100644 --- a/src/hooks/useWatchPendingTxs.ts +++ b/src/hooks/useWatchPendingTxs.ts @@ -1,4 +1,4 @@ -import { useCallback, useMemo } from 'react'; +import { useMemo, useCallback } from 'react'; import useAccountSettings from './useAccountSettings'; import { RainbowTransaction, MinedTransaction, TransactionStatus, FlashbotsStatus } from '@/entities'; import { userAssetsQueryKey } from '@/resources/assets/UserAssetsQuery'; @@ -9,12 +9,11 @@ import { getProvider } from '@/handlers/web3'; import { consolidatedTransactionsQueryKey } from '@/resources/transactions/consolidatedTransactions'; import { queryClient } from '@/react-query/queryClient'; import { getTransactionFlashbotStatus } from '@/handlers/transactions'; -import { usePendingTransactionsStore } from '@/state/pendingTransactions'; +import { ChainId } from '@/chains/types'; +import { invalidateAddressNftsQueries } from '@/resources/nfts'; import { useNonceStore } from '@/state/nonces'; +import { usePendingTransactionsStore } from '@/state/pendingTransactions'; import { Address } from 'viem'; -import { nftsQueryKey } from '@/resources/nfts'; -import { getNftSortForAddress } from './useNFTsSortBy'; -import { ChainId } from '@/chains/types'; import { staleBalancesStore } from '@/state/staleBalances'; import { useConnectedToHardhatStore } from '@/state/connectedToHardhat'; import { SUPPORTED_MAINNET_CHAIN_IDS } from '@/chains'; @@ -49,7 +48,7 @@ export const useWatchPendingTransactions = ({ address }: { address: string }) => testnetMode: !!connectedToHardhat, }) ); - queryClient.invalidateQueries(nftsQueryKey({ address, sortBy: getNftSortForAddress(address) })); + invalidateAddressNftsQueries(address); }, [address, connectedToHardhat, nativeCurrency] ); diff --git a/src/languages/en_US.json b/src/languages/en_US.json index 58c9a75808f..d966a6040e9 100644 --- a/src/languages/en_US.json +++ b/src/languages/en_US.json @@ -1342,7 +1342,11 @@ "MOST_RECENT": "Recent", "most_recent": "Recent", "FLOOR_PRICE": "Floor Price", - "floor_price": "Floor Price" + "floor_price": "Floor Price", + "order": { + "asc": "Ascending order", + "desc": "Descending order" + } }, "empty": "Collectibles", "collect_now": "Collect Now", diff --git a/src/resources/nfts/index.ts b/src/resources/nfts/index.ts index 27a94f1db80..d5585f29197 100644 --- a/src/resources/nfts/index.ts +++ b/src/resources/nfts/index.ts @@ -1,21 +1,32 @@ import { QueryFunction, useQuery } from '@tanstack/react-query'; -import { QueryConfigWithSelect, createQueryKey } from '@/react-query'; +import { QueryConfigWithSelect, createQueryKey, queryClient } from '@/react-query'; import { fetchSimpleHashNFTListing } from '@/resources/nfts/simplehash'; import { simpleHashNFTToUniqueAsset } from '@/resources/nfts/simplehash/utils'; import { useSelector } from 'react-redux'; import { AppState } from '@/redux/store'; import { UniqueAsset } from '@/entities'; import { arcClient } from '@/graphql'; +import { NftCollectionSortCriterion, SortDirection } from '@/graphql/__generated__/arc'; import { createSelector } from 'reselect'; -import { NftCollectionSortCriterion } from '@/graphql/__generated__/arc'; import { ChainId } from '@/chains/types'; const NFTS_STALE_TIME = 600000; // 10 minutes const NFTS_CACHE_TIME_EXTERNAL = 3600000; // 1 hour const NFTS_CACHE_TIME_INTERNAL = 604800000; // 1 week -export const nftsQueryKey = ({ address, sortBy }: { address: string; sortBy: NftCollectionSortCriterion }) => - createQueryKey('nfts', { address, sortBy }, { persisterVersion: 4 }); +export const nftsQueryKey = ({ + address, + sortBy, + sortDirection, +}: { + address: string; + sortBy: NftCollectionSortCriterion; + sortDirection: SortDirection; +}) => createQueryKey('nfts', { address, sortBy, sortDirection }, { persisterVersion: 1 }); + +export const invalidateAddressNftsQueries = (address: string) => { + queryClient.invalidateQueries(createQueryKey('nfts', { address })); +}; export const nftListingQueryKey = ({ contractAddress, @@ -53,8 +64,8 @@ interface NFTData { type NFTQueryKey = ReturnType; const fetchNFTData: QueryFunction = async ({ queryKey }) => { - const [{ address, sortBy }] = queryKey; - const queryResponse = await arcClient.getNFTs({ walletAddress: address, sortBy }); + const [{ address, sortBy, sortDirection }] = queryKey; + const queryResponse = await arcClient.getNFTs({ walletAddress: address, sortBy, sortDirection }); const nfts = queryResponse?.nftsV2?.map(nft => simpleHashNFTToUniqueAsset(nft, address)); @@ -77,15 +88,17 @@ const FALLBACK_DATA: NFTData = { nfts: [], nftsMap: {} }; export function useLegacyNFTs({ address, sortBy = NftCollectionSortCriterion.MostRecent, + sortDirection = SortDirection.Desc, config, }: { address: string; sortBy?: NftCollectionSortCriterion; + sortDirection?: SortDirection; config?: QueryConfigWithSelect; }) { const isImportedWallet = useSelector((state: AppState) => isImportedWalletSelector(state, address)); - const { data, error, isLoading, isInitialLoading } = useQuery(nftsQueryKey({ address, sortBy }), fetchNFTData, { + const { data, error, isLoading, isInitialLoading } = useQuery(nftsQueryKey({ address, sortBy, sortDirection }), fetchNFTData, { cacheTime: isImportedWallet ? NFTS_CACHE_TIME_INTERNAL : NFTS_CACHE_TIME_EXTERNAL, enabled: !!address, retry: 3, diff --git a/src/screens/ENSIntroSheet.tsx b/src/screens/ENSIntroSheet.tsx index e90ec57ebe5..edcd087e44f 100644 --- a/src/screens/ENSIntroSheet.tsx +++ b/src/screens/ENSIntroSheet.tsx @@ -4,7 +4,6 @@ import { IS_TESTING } from 'react-native-dotenv'; import lang from 'i18n-js'; import React, { useCallback, useMemo } from 'react'; import { InteractionManager, View } from 'react-native'; -import { MenuActionConfig } from 'react-native-ios-context-menu'; import LinearGradient from 'react-native-linear-gradient'; import ActivityIndicator from '../components/ActivityIndicator'; import IntroMarquee from '../components/ens-registration/IntroMarquee/IntroMarquee'; @@ -55,7 +54,7 @@ const ContextMenuRenderer = ({ children, handleSelectExistingName, handleNavigat iconValue: 'magnifyingglass', }, }, - ] as MenuActionConfig[], + ], menuTitle: '', }; }, []); diff --git a/src/screens/ExchangeModal.tsx b/src/screens/ExchangeModal.tsx index 2f8aa2c28df..5925bd822d7 100644 --- a/src/screens/ExchangeModal.tsx +++ b/src/screens/ExchangeModal.tsx @@ -905,6 +905,7 @@ export function ExchangeModal({ fromDiscover, ignoreInitialTypeCheck, testID, ty marginBottom={0} marginTop={0} testID={`${testID}-gas`} + // @ts-expect-error - invalid prop type but fixed in the next PR crossChainServiceTime={getCrosschainSwapServiceTime(tradeDetails as CrosschainQuote)} /> diff --git a/src/screens/SettingsSheet/components/Backups/ViewWalletBackup.tsx b/src/screens/SettingsSheet/components/Backups/ViewWalletBackup.tsx index 6ea5ddbc87a..d085c3f62fd 100644 --- a/src/screens/SettingsSheet/components/Backups/ViewWalletBackup.tsx +++ b/src/screens/SettingsSheet/components/Backups/ViewWalletBackup.tsx @@ -40,7 +40,6 @@ import { login, } from '@/handlers/cloudBackup'; import { logger, RainbowError } from '@/logger'; -import { captureException } from '@sentry/react-native'; import { RainbowAccount, createWallet } from '@/model/wallet'; import { PROFILES, useExperimentalFlag } from '@/config'; import showWalletErrorAlert from '@/helpers/support'; @@ -108,7 +107,7 @@ type ContextMenuWrapperProps = { const ContextMenuWrapper = ({ children, account, menuConfig, onPressMenuItem }: ContextMenuWrapperProps) => { return IS_IOS ? ( - onPressMenuItem({ ...e, account })}> + onPressMenuItem({ ...e, account })}> {children} ) : ( diff --git a/src/screens/points/components/LeaderboardRow.tsx b/src/screens/points/components/LeaderboardRow.tsx index 1a7c9828a8c..8d2d451ba3e 100644 --- a/src/screens/points/components/LeaderboardRow.tsx +++ b/src/screens/points/components/LeaderboardRow.tsx @@ -1,7 +1,6 @@ import * as i18n from '@/languages'; import React, { memo, useCallback, useMemo } from 'react'; import { Keyboard, Share } from 'react-native'; -import { MenuActionConfig } from 'react-native-ios-context-menu'; import ContextMenuButton from '@/components/native-context-menu/contextMenu'; import { useClipboard, useContacts, useSwitchWallet, useWallets, useWatchWallet } from '@/hooks'; import { useNavigation } from '@/navigation'; @@ -61,14 +60,18 @@ export const LeaderboardRow = memo(function LeaderboardRow({ const menuItems = useMemo(() => { return [ - isWatching && { - actionKey: ACTIONS.OPEN_WALLET, - actionTitle: i18n.t(i18n.l.profiles.details.open_wallet), - icon: { - iconType: 'SYSTEM', - iconValue: 'iphone.and.arrow.forward', - }, - }, + ...(isWatching + ? [ + { + actionKey: ACTIONS.OPEN_WALLET, + actionTitle: i18n.t(i18n.l.profiles.details.open_wallet), + icon: { + iconType: 'SYSTEM', + iconValue: 'iphone.and.arrow.forward', + }, + }, + ] + : []), { actionKey: ACTIONS.COPY_ADDRESS, actionTitle: i18n.t(i18n.l.profiles.details.copy_address), @@ -111,7 +114,7 @@ export const LeaderboardRow = memo(function LeaderboardRow({ iconValue: 'square.and.arrow.up', }, }, - ].filter(Boolean) as MenuActionConfig[]; + ]; }, [isWatching, formattedAddress, contact]); const handlePressMenuItem = useCallback( diff --git a/src/screens/transaction-details/components/TransactionDetailsAddressRow.tsx b/src/screens/transaction-details/components/TransactionDetailsAddressRow.tsx index c3fec380ce7..8dd64832ddd 100644 --- a/src/screens/transaction-details/components/TransactionDetailsAddressRow.tsx +++ b/src/screens/transaction-details/components/TransactionDetailsAddressRow.tsx @@ -169,7 +169,7 @@ const ContextMenuRenderer = ({ } return ( - + {children} ); diff --git a/src/screens/transaction-details/components/TransactionDetailsStatusActionsAndTimestampSection.tsx b/src/screens/transaction-details/components/TransactionDetailsStatusActionsAndTimestampSection.tsx index 728f6d2947b..dfa51c7eabc 100644 --- a/src/screens/transaction-details/components/TransactionDetailsStatusActionsAndTimestampSection.tsx +++ b/src/screens/transaction-details/components/TransactionDetailsStatusActionsAndTimestampSection.tsx @@ -5,7 +5,7 @@ import { formatTransactionDetailsDate } from '@/screens/transaction-details/help import { getIconColorAndGradientForTransactionStatus } from '@/screens/transaction-details/helpers/getIconColorAndGradientForTransactionStatus'; import RadialGradient from 'react-native-radial-gradient'; import { useTheme } from '@/theme'; -import ContextMenuButton from '@/components/native-context-menu/contextMenu'; +import ContextMenuButton, { MenuConfig } from '@/components/native-context-menu/contextMenu'; import { StyleSheet } from 'react-native'; import { ButtonPressAnimation } from '@/components/animations'; import { haptics } from '@/utils'; @@ -35,36 +35,37 @@ export const TransactionDetailsStatusActionsAndTimestampSection: React.FC const canBeCancelled = canBeResubmitted && status !== TransactionStatus.cancelling; const menuConfig = useMemo( - () => ({ - menuTitle: '', - menuItems: [ - ...(canBeResubmitted - ? [ - { - actionKey: 'speedUp', - actionTitle: i18n.t(i18n.l.transaction_details.actions_menu.speed_up), - icon: { - iconType: 'SYSTEM', - iconValue: 'speedometer', + () => + ({ + menuTitle: '', + menuItems: [ + ...(canBeResubmitted + ? [ + { + actionKey: 'speedUp', + actionTitle: i18n.t(i18n.l.transaction_details.actions_menu.speed_up), + icon: { + iconType: 'SYSTEM', + iconValue: 'speedometer', + }, }, - }, - ] - : []), - ...(canBeCancelled - ? [ - { - actionKey: 'cancel', - actionTitle: i18n.t(i18n.l.transaction_details.actions_menu.cancel), - menuAttributes: ['destructive'], - icon: { - iconType: 'SYSTEM', - iconValue: 'xmark.circle', + ] + : []), + ...(canBeCancelled + ? [ + { + actionKey: 'cancel', + actionTitle: i18n.t(i18n.l.transaction_details.actions_menu.cancel), + menuAttributes: ['destructive' as const], + icon: { + iconType: 'SYSTEM', + iconValue: 'xmark.circle', + }, }, - }, - ] - : []), - ], - }), + ] + : []), + ], + }) satisfies MenuConfig, [canBeCancelled, canBeResubmitted] ); diff --git a/yarn.lock b/yarn.lock index 84b800a7f58..cb5669f2082 100644 --- a/yarn.lock +++ b/yarn.lock @@ -9439,7 +9439,7 @@ __metadata: ts-loader: "npm:9.5.1" ts-migrate: "npm:0.1.26" tty-browserify: "npm:0.0.0" - typescript: "npm:5.1.6" + typescript: "npm:5.5.4" typescript-coverage-report: "npm:0.6.1" url: "npm:0.10.3" url-join: "npm:4.0.1" @@ -27365,13 +27365,13 @@ react-native-safe-area-view@rainbow-me/react-native-safe-area-view: languageName: node linkType: hard -"typescript@npm:5.1.6": - version: 5.1.6 - resolution: "typescript@npm:5.1.6" +"typescript@npm:5.5.4": + version: 5.5.4 + resolution: "typescript@npm:5.5.4" bin: tsc: bin/tsc tsserver: bin/tsserver - checksum: 10c0/45ac28e2df8365fd28dac42f5d62edfe69a7203d5ec646732cadc04065331f34f9078f81f150fde42ed9754eed6fa3b06a8f3523c40b821e557b727f1992e025 + checksum: 10c0/422be60f89e661eab29ac488c974b6cc0a660fb2228003b297c3d10c32c90f3bcffc1009b43876a082515a3c376b1eefcce823d6e78982e6878408b9a923199c languageName: node linkType: hard @@ -27395,13 +27395,13 @@ react-native-safe-area-view@rainbow-me/react-native-safe-area-view: languageName: node linkType: hard -"typescript@patch:typescript@npm%3A5.1.6#optional!builtin": - version: 5.1.6 - resolution: "typescript@patch:typescript@npm%3A5.1.6#optional!builtin::version=5.1.6&hash=5da071" +"typescript@patch:typescript@npm%3A5.5.4#optional!builtin": + version: 5.5.4 + resolution: "typescript@patch:typescript@npm%3A5.5.4#optional!builtin::version=5.5.4&hash=b45daf" bin: tsc: bin/tsc tsserver: bin/tsserver - checksum: 10c0/c2bded58ab897a8341fdbb0c1d92ea2362f498cfffebdc8a529d03e15ea2454142dfbf122dabbd9a5cb79b7123790d27def16e11844887d20636226773ed329a + checksum: 10c0/10dd9881baba22763de859e8050d6cb6e2db854197495c6f1929b08d1eb2b2b00d0b5d9b0bcee8472f1c3f4a7ef6a5d7ebe0cfd703f853aa5ae465b8404bc1ba languageName: node linkType: hard