diff --git a/.circleci/config.yml b/.circleci/config.yml index 9722e70f612..e15b097b487 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -491,6 +491,9 @@ jobs: - store_artifacts: path: android/app/build/reports + - store_artifacts: + path: .gradle/daemon/ + - save_cache: key: << pipeline.parameters.android_native_cache_key >> paths: @@ -518,7 +521,7 @@ parameters: # Update Manually these versions below in order to hard overwrite the caches node_modules_cache_key: type: string - default: v28-node_modules-{{ checksum ".manifests/node_modules" }} + default: v29-node_modules-{{ checksum ".manifests/node_modules" }} gems_cache_key: type: string default: v13-gems-{{ checksum "Gemfile.lock" }}-{{ arch }} @@ -530,14 +533,14 @@ parameters: default: v30-app_build_ios-{{ checksum ".manifests/app_build" }} app_build_android_cache_key: type: string - default: v15-app_build_android-{{ checksum "../workspace/.manifests/app_build" }} + default: v16-app_build_android-{{ checksum "../workspace/.manifests/app_build" }} ios_native_code_cache_prefix: type: string # this one is not including the checksum due to path differences in the checksum default: v19-test-success android_native_cache_key: type: string - default: v18-test-success-{{ checksum "../workspace/.manifests/android_native" }} + default: v19-test-success-{{ checksum "../workspace/.manifests/android_native" }} workflows: nightly: diff --git a/.github/workflows/android-e2e-maestro.yml b/.github/workflows/android-e2e-maestro.yml index 61e0242fa6f..7fa28062729 100644 --- a/.github/workflows/android-e2e-maestro.yml +++ b/.github/workflows/android-e2e-maestro.yml @@ -65,6 +65,17 @@ jobs: - name: Add Maestro to PATH run: echo "$HOME/.maestro/bin" >> $GITHUB_PATH + - name: Free Disk Space + uses: jlumbroso/free-disk-space@54081f138730dfa15788a46383842cd2f914a1be + with: + tool-cache: false + android: false + dotnet: true + haskell: true + large-packages: true + docker-images: true + swap-storage: true + - name: Run tests with Android emulator uses: reactivecircus/android-emulator-runner@v2 with: @@ -72,7 +83,7 @@ jobs: arch: x86_64 ram-size: "8192M" heap-size: "4096M" - disk-size: "10G" + disk-size: "8G" cores: 4 disable-animations: false disable-spellchecker: true diff --git a/.github/workflows/build-maestro-ios.yml b/.github/workflows/build-maestro-ios.yml index 449cdd7952b..024649fcb82 100644 --- a/.github/workflows/build-maestro-ios.yml +++ b/.github/workflows/build-maestro-ios.yml @@ -9,7 +9,7 @@ jobs: build-ios-qa: if: github.ref == 'refs/heads/main' runs-on: macos-15 - timeout-minutes: 90 + timeout-minutes: 120 steps: - name: Checkout repository diff --git a/EXAMPLES.md b/EXAMPLES.md index ee0a064e3f8..645974a1f0c 100644 --- a/EXAMPLES.md +++ b/EXAMPLES.md @@ -114,5 +114,3 @@ Links: - [OnboardingWelcome.tsx](src/app/Scenes/Onboarding/OnboardingWelcome.tsx) - [Search.tsx](src/app/Scenes/Search/Search.tsx) -- [AnimatableHeaderLargeTitle.tsx](src/app/Components/AnimatableHeader/AnimatableHeaderLargeTitle.tsx) -- [AnimatableHeader.tsx](src/app/Components/AnimatableHeader/AnimatableHeader.tsx) diff --git a/HACKS.md b/HACKS.md index 0a89f2bfa88..c833499a8b2 100644 --- a/HACKS.md +++ b/HACKS.md @@ -283,3 +283,28 @@ not reset. This causes the module to never start listening again causing events #### When can we remove this: It can be removed once if we stop using the singleton pattern or get rid of ARNotificationsManagerModule, or it is fixed upstream. + +## react-native-reanimated package.json flags and react-native patch + +### USE_COMMIT_HOOK_ONLY_FOR_REACT_COMMITS + +#### Explanation/Context: + +This feature flag was added to fix performance issues with scrolling. See https://docs.swmansion.com/react-native-reanimated/docs/guides/performance/#%EF%B8%8F-lower-fps-while-scrolling + +We also added a patch to react-native to support this flag and temporarily enabled preventShadowTreeCommitExhaustion and enableCppPropsIteratorSetter flags to fix performance issues. + +#### When can we remove this: + +When reanimated adopts this by default. + +## react-native-webview passing constant for decelerationRate prop + +#### Explanation/Context: + +This is a bug on the new architecture on Android with this prop and react-native-webview. + +#### When can we remove this: + +When this is merged and we update react-native-webview to a version that contains it: +https://github.com/react-native-webview/react-native-webview/pull/3885 diff --git a/android/gradle.properties b/android/gradle.properties index 4042f1a591c..46d55964774 100644 --- a/android/gradle.properties +++ b/android/gradle.properties @@ -43,11 +43,12 @@ reactNativeArchitectures=armeabi-v7a,arm64-v8a,x86,x86_64 # your application. You should enable this flag either if you want # to write custom TurboModules/Fabric components OR use libraries that # are providing them. -newArchEnabled=false +newArchEnabled=true # Use this property to enable or disable the Hermes JS engine. # If set to false, you will be using JSC instead. hermesEnabled=true # Specify dotenv file name for access in build.gradle -dotenv.filename=../.env.shared \ No newline at end of file +dotenv.filename=../.env.shared + diff --git a/docs/best_practices.md b/docs/best_practices.md index fb96bf861d9..b587a2ad68d 100644 --- a/docs/best_practices.md +++ b/docs/best_practices.md @@ -225,7 +225,6 @@ const App = () => { return ( ) diff --git a/e2e/README.md b/e2e/README.md index 067681cad14..d5c0b69f99d 100644 --- a/e2e/README.md +++ b/e2e/README.md @@ -6,9 +6,19 @@ It is used like other tools such as Cypress, Appium, and Detox in order to run t ## Steps to run 1. install maestro by following the instructions [here](https://maestro.mobile.dev/getting-started/installing-maestro) - - `curl -Ls "https://get.maestro.mobile.dev" | bash` - - `brew tap facebook/fb` - - `brew install facebook/fb/idb-companion` + + - Using Curl + + ```bash + curl -Ls "https://get.maestro.mobile.dev" | bash + ``` + + - Using Homebrew + + ```bash + brew tap facebook/fb + brew install facebook/fb/idb-companion + ``` ### iOS diff --git a/e2e/perf/run-perf-tests.sh b/e2e/perf/run-perf-tests.sh index 6ed9495d69f..52389f6fc95 100755 --- a/e2e/perf/run-perf-tests.sh +++ b/e2e/perf/run-perf-tests.sh @@ -16,8 +16,9 @@ timestamp=$(date +"%Y-%m-%d_%H:%M:%S") # Note that this is only supported on android devices or emulators at the moment. flashlight test --bundleId net.artsy.app \ --testCommand "maestro test e2e/perf/perf-test-home.yml" \ + --beforeEachCommand "adb shell am force-stop net.artsy.app" \ --duration 10000 \ - --iterationCount 1 \ + --iterationCount 3 \ --skipRestart \ --record \ --resultsFilePath "flashlight_results_$timestamp.json" \ diff --git a/ios/Artsy.xcodeproj/project.pbxproj b/ios/Artsy.xcodeproj/project.pbxproj index 02e20f284b0..68b167e4b62 100644 --- a/ios/Artsy.xcodeproj/project.pbxproj +++ b/ios/Artsy.xcodeproj/project.pbxproj @@ -14,7 +14,7 @@ 1A4B97C1283CDD5A00878EAE /* ARTemporaryAPIModule.m in Sources */ = {isa = PBXBuildFile; fileRef = 1A4B979D283CDD5900878EAE /* ARTemporaryAPIModule.m */; }; 1A4B97C3283CDD5A00878EAE /* ARMediaPreviewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 1A4B97A1283CDD5900878EAE /* ARMediaPreviewController.m */; }; 1A4B97C6283CDD5A00878EAE /* ARComponentViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 1A4B97A9283CDD5900878EAE /* ARComponentViewController.m */; }; - 1A4B97C8283CDD5A00878EAE /* ARPHPhotoPickerModule.m in Sources */ = {isa = PBXBuildFile; fileRef = 1A4B97AF283CDD5900878EAE /* ARPHPhotoPickerModule.m */; }; + 1A4B97C8283CDD5A00878EAE /* ARPHPhotoPickerModule.mm in Sources */ = {isa = PBXBuildFile; fileRef = 1A4B97AF283CDD5900878EAE /* ARPHPhotoPickerModule.mm */; }; 1A4B97C9283CDD5A00878EAE /* ARNotificationsManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 1A4B97B0283CDD5900878EAE /* ARNotificationsManager.m */; }; 1A4E5119283F91BA0008EF35 /* Artsy+UILabels.m in Sources */ = {isa = PBXBuildFile; fileRef = 1A4E50FB283F91B90008EF35 /* Artsy+UILabels.m */; }; 1A4E511A283F91BA0008EF35 /* UIView+ARDrawing.m in Sources */ = {isa = PBXBuildFile; fileRef = 1A4E50FC283F91B90008EF35 /* UIView+ARDrawing.m */; }; @@ -216,7 +216,7 @@ CB762B3E2911A5E100881194 /* ar_vir_opening_frame.jpg in Resources */ = {isa = PBXBuildFile; fileRef = CB762B362911A5E100881194 /* ar_vir_opening_frame.jpg */; }; CBA500F32C654F8400DDBCC0 /* AppDelegate+DeeplinkTimeout.m in Sources */ = {isa = PBXBuildFile; fileRef = CBA500F22C654F8400DDBCC0 /* AppDelegate+DeeplinkTimeout.m */; }; CBA500F62C6553FF00DDBCC0 /* ARTDeeplinkTimeoutModule.m in Sources */ = {isa = PBXBuildFile; fileRef = CBA500F52C6553FF00DDBCC0 /* ARTDeeplinkTimeoutModule.m */; }; - CBC1F3F12E68CF11008CCF48 /* ARAppDelegateHelper.m in Sources */ = {isa = PBXBuildFile; fileRef = CBC1F3F02E68CF11008CCF48 /* ARAppDelegateHelper.m */; }; + CBC1F3F12E68CF11008CCF48 /* ARAppDelegateHelper.mm in Sources */ = {isa = PBXBuildFile; fileRef = CBC1F3F02E68CF11008CCF48 /* ARAppDelegateHelper.mm */; }; CBC1F3F42E68D0D7008CCF48 /* ARWindow.m in Sources */ = {isa = PBXBuildFile; fileRef = CBC1F3F32E68D0D4008CCF48 /* ARWindow.m */; }; CBD794D72BBB5622003B3CB5 /* StarscreamExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = CBD794D62BBB5622003B3CB5 /* StarscreamExtensions.swift */; }; CBD794DB2BBC40A4003B3CB5 /* PrivacyInfo.xcprivacy in Resources */ = {isa = PBXBuildFile; fileRef = CBD794DA2BBC40A4003B3CB5 /* PrivacyInfo.xcprivacy */; }; @@ -555,7 +555,7 @@ 1A4B97A9283CDD5900878EAE /* ARComponentViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ARComponentViewController.m; sourceTree = ""; }; 1A4B97AC283CDD5900878EAE /* ARPHPhotoPickerModule.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ARPHPhotoPickerModule.h; sourceTree = ""; }; 1A4B97AD283CDD5900878EAE /* ARNotificationsManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ARNotificationsManager.h; sourceTree = ""; }; - 1A4B97AF283CDD5900878EAE /* ARPHPhotoPickerModule.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ARPHPhotoPickerModule.m; sourceTree = ""; }; + 1A4B97AF283CDD5900878EAE /* ARPHPhotoPickerModule.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ARPHPhotoPickerModule.mm; sourceTree = ""; }; 1A4B97B0283CDD5900878EAE /* ARNotificationsManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ARNotificationsManager.m; sourceTree = ""; }; 1A4E50FB283F91B90008EF35 /* Artsy+UILabels.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "Artsy+UILabels.m"; sourceTree = ""; }; 1A4E50FC283F91B90008EF35 /* UIView+ARDrawing.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIView+ARDrawing.m"; sourceTree = ""; }; @@ -916,7 +916,7 @@ CBA500F52C6553FF00DDBCC0 /* ARTDeeplinkTimeoutModule.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ARTDeeplinkTimeoutModule.m; sourceTree = ""; }; CBA7CF22282BF6310025AEA5 /* Artsy_Tests-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "Artsy_Tests-Info.plist"; sourceTree = ""; }; CBC1F3EF2E68CF11008CCF48 /* ARAppDelegateHelper.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ARAppDelegateHelper.h; sourceTree = ""; }; - CBC1F3F02E68CF11008CCF48 /* ARAppDelegateHelper.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ARAppDelegateHelper.m; sourceTree = ""; }; + CBC1F3F02E68CF11008CCF48 /* ARAppDelegateHelper.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = ARAppDelegateHelper.mm; sourceTree = ""; }; CBC1F3F22E68D0CC008CCF48 /* ARWindow.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ARWindow.h; sourceTree = ""; }; CBC1F3F32E68D0D4008CCF48 /* ARWindow.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ARWindow.m; sourceTree = ""; }; CBD794D62BBB5622003B3CB5 /* StarscreamExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StarscreamExtensions.swift; sourceTree = ""; }; @@ -1429,7 +1429,7 @@ children = ( 1A4B97AC283CDD5900878EAE /* ARPHPhotoPickerModule.h */, 1A4B97AD283CDD5900878EAE /* ARNotificationsManager.h */, - 1A4B97AF283CDD5900878EAE /* ARPHPhotoPickerModule.m */, + 1A4B97AF283CDD5900878EAE /* ARPHPhotoPickerModule.mm */, 1A4B97B0283CDD5900878EAE /* ARNotificationsManager.m */, ); path = EigenCommunications; @@ -2543,7 +2543,7 @@ CBC1F3F22E68D0CC008CCF48 /* ARWindow.h */, CBC1F3F32E68D0D4008CCF48 /* ARWindow.m */, CBC1F3EF2E68CF11008CCF48 /* ARAppDelegateHelper.h */, - CBC1F3F02E68CF11008CCF48 /* ARAppDelegateHelper.m */, + CBC1F3F02E68CF11008CCF48 /* ARAppDelegateHelper.mm */, CB2033332E56593700A06281 /* main.swift */, CB51280D2DB2EBCE00C6A884 /* AppDelegateCategories */, CBE3249927E275A100395A93 /* ARTArtsyNativeModule.h */, @@ -3892,7 +3892,7 @@ CBD794D72BBB5622003B3CB5 /* StarscreamExtensions.swift in Sources */, CBE326AF27E275A300395A93 /* LiveAuctionLoadingView.swift in Sources */, CBE326E127E275A300395A93 /* ARFileUtils.m in Sources */, - 1A4B97C8283CDD5A00878EAE /* ARPHPhotoPickerModule.m in Sources */, + 1A4B97C8283CDD5A00878EAE /* ARPHPhotoPickerModule.mm in Sources */, CBE3269727E275A300395A93 /* AppDelegate+ShortcutItems.m in Sources */, CBE326E627E275A300395A93 /* UIApplicationStateEnum.m in Sources */, CBE3270E27E275A300395A93 /* AuctionTitleView.swift in Sources */, @@ -3944,7 +3944,7 @@ CBE3267727E275A300395A93 /* UIImageView+AsyncImageLoading.m in Sources */, CB18284829DF3F75006A0805 /* Utilities.swift in Sources */, CBE3271D27E275A300395A93 /* ARNotificationView.m in Sources */, - CBC1F3F12E68CF11008CCF48 /* ARAppDelegateHelper.m in Sources */, + CBC1F3F12E68CF11008CCF48 /* ARAppDelegateHelper.mm in Sources */, CBE3276C27E275A400395A93 /* MTLModel+Dictionary.m in Sources */, CBE326E427E275A300395A93 /* ARNetworkErrorManager.m in Sources */, CBE326A027E275A300395A93 /* ARUserActivity.m in Sources */, diff --git a/ios/Artsy/App/ARAppDelegateHelper.m b/ios/Artsy/App/ARAppDelegateHelper.mm similarity index 96% rename from ios/Artsy/App/ARAppDelegateHelper.m rename to ios/Artsy/App/ARAppDelegateHelper.mm index f1f473b9d73..71cb5ec91e5 100644 --- a/ios/Artsy/App/ARAppDelegateHelper.m +++ b/ios/Artsy/App/ARAppDelegateHelper.mm @@ -10,12 +10,19 @@ #import "ARUserManager.h" #import "Keys.h" #import "ARAppStatus.h" -#import + + +#import +#import +#import + + #import #import "BrazeReactBridge.h" #import "BrazeReactUtils.h" #import + @interface ARAppDelegateHelper () @property (strong, nonatomic, readwrite) NSString *referralURLRepresentation; @property (strong, nonatomic, readwrite) NSString *landingURLRepresentation; diff --git a/ios/Artsy/App_Resources/Info.plist b/ios/Artsy/App_Resources/Info.plist index 4a3984c016d..ee0fbaf7ab2 100644 --- a/ios/Artsy/App_Resources/Info.plist +++ b/ios/Artsy/App_Resources/Info.plist @@ -114,6 +114,8 @@ LSRequiresIPhoneOS + UIDesignRequiresCompatibility + LSSupportsOpeningDocumentsInPlace MGLGlyphsRasterizationMode @@ -144,7 +146,7 @@ NSPhotoLibraryUsageDescription Photos will be used to gauge the quality of the work you are submitting. RCTNewArchEnabled - + UIAppFonts Unica77LL-Italic.otf diff --git a/ios/Artsy/Emission/EigenCommunications/ARPHPhotoPickerModule.m b/ios/Artsy/Emission/EigenCommunications/ARPHPhotoPickerModule.mm similarity index 100% rename from ios/Artsy/Emission/EigenCommunications/ARPHPhotoPickerModule.m rename to ios/Artsy/Emission/EigenCommunications/ARPHPhotoPickerModule.mm diff --git a/ios/ArtsyStickers/Info.plist b/ios/ArtsyStickers/Info.plist index f7b5684bfc3..2e6a1fbfd69 100644 --- a/ios/ArtsyStickers/Info.plist +++ b/ios/ArtsyStickers/Info.plist @@ -14,6 +14,6 @@ StickerBrowserViewController RCTNewArchEnabled - + diff --git a/ios/ArtsyWidget/Info.plist b/ios/ArtsyWidget/Info.plist index 191171c7459..dcaf77ebeda 100644 --- a/ios/ArtsyWidget/Info.plist +++ b/ios/ArtsyWidget/Info.plist @@ -12,6 +12,6 @@ com.apple.widgetkit-extension RCTNewArchEnabled - + diff --git a/ios/BrazePushServiceExtension/Info.plist b/ios/BrazePushServiceExtension/Info.plist index bfdb202e319..e0f56bfcaf7 100644 --- a/ios/BrazePushServiceExtension/Info.plist +++ b/ios/BrazePushServiceExtension/Info.plist @@ -14,6 +14,6 @@ $(PRODUCT_MODULE_NAME).NotificationService RCTNewArchEnabled - + diff --git a/ios/Podfile b/ios/Podfile index e9209e5807e..592cc2c0750 100644 --- a/ios/Podfile +++ b/ios/Podfile @@ -107,7 +107,7 @@ target 'Artsy' do :production => ENV['CIRCLE_BUILD_NUM'], # An absolute path to your application root. :app_path => "#{Pod::Config.instance.installation_root}/..", - new_arch_enabled: false + new_arch_enabled: true ) # Networking diff --git a/ios/Podfile.lock b/ios/Podfile.lock index 6e227c134f8..1112fa8e66d 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -63,6 +63,10 @@ PODS: - CocoaLumberjack (3.9.0): - CocoaLumberjack/Core (= 3.9.0) - CocoaLumberjack/Core (3.9.0) + - ComputableLayout (0.7.0): + - DGSwiftUtilities (~> 0.11) + - ContextMenuAuxiliaryPreview (0.5.2): + - DGSwiftUtilities (~> 0.29) - CwlCatchException (2.2.1): - CwlCatchExceptionSupport (~> 2.2.1) - CwlCatchExceptionSupport (2.2.1) @@ -72,6 +76,7 @@ PODS: - CwlCatchException (~> 2.2.1) - CwlMachBadInstructionHandler (~> 2.2.2) - CwlPosixPreconditionTesting (~> 2.2.2) + - DGSwiftUtilities (0.47.0) - DoubleConversion (1.1.6) - EASClient (1.0.7): - ExpoModulesCore @@ -2108,7 +2113,33 @@ PODS: - ReactCommon/turbomodule/core - SocketRocket - react-native-blob-util (0.19.11): + - boost + - DoubleConversion + - fast_float + - fmt + - glog + - hermes-engine + - RCT-Folly + - RCT-Folly/Fabric + - RCTRequired + - RCTTypeSafety - React-Core + - React-debug + - React-Fabric + - React-featureflags + - React-graphics + - React-ImageManager + - React-jsi + - React-NativeModulesApple + - React-RCTFabric + - React-renderercss + - React-rendererdebug + - React-utils + - ReactCodegen + - ReactCommon/turbomodule/bridging + - ReactCommon/turbomodule/core + - SocketRocket + - Yoga - react-native-blurhash (2.1.1): - boost - DoubleConversion @@ -2137,8 +2168,6 @@ PODS: - ReactCommon/turbomodule/core - SocketRocket - Yoga - - react-native-context-menu-view (1.10.0): - - React - react-native-cookies (6.0.11): - React-Core - react-native-document-picker (10.1.5): @@ -2216,7 +2245,104 @@ PODS: - React-Core - react-native-in-app-review (4.3.3): - React-Core + - react-native-ios-context-menu (3.2.0): + - boost + - ContextMenuAuxiliaryPreview (~> 0.5) + - DGSwiftUtilities + - DoubleConversion + - fast_float + - fmt + - glog + - hermes-engine + - RCT-Folly + - RCT-Folly/Fabric + - RCTRequired + - RCTTypeSafety + - React-Core + - React-debug + - React-Fabric + - React-featureflags + - React-graphics + - React-ImageManager + - React-jsi + - React-jsinspector + - React-jsinspectortracing + - react-native-ios-utilities + - React-NativeModulesApple + - React-RCTAppDelegate + - React-RCTFabric + - React-renderercss + - React-rendererdebug + - React-utils + - ReactCodegen + - ReactCommon/turbomodule/bridging + - ReactCommon/turbomodule/core + - SocketRocket + - Yoga + - react-native-ios-utilities (5.2.0): + - boost + - ComputableLayout (~> 0.7) + - DGSwiftUtilities (~> 0.46) + - DoubleConversion + - fast_float + - fmt + - glog + - hermes-engine + - RCT-Folly + - RCT-Folly/Fabric + - RCTRequired + - RCTTypeSafety + - React-Core + - React-debug + - React-Fabric + - React-featureflags + - React-graphics + - React-ImageManager + - React-jsi + - React-jsinspector + - React-jsinspectortracing + - React-jsitooling + - React-NativeModulesApple + - React-RCTAppDelegate + - React-RCTFabric + - React-renderercss + - React-rendererdebug + - React-utils + - ReactCodegen + - ReactCommon/turbomodule/bridging + - ReactCommon/turbomodule/core + - SocketRocket + - Yoga - react-native-keyboard-controller (1.20.2): + - boost + - DoubleConversion + - fast_float + - fmt + - glog + - hermes-engine + - RCT-Folly + - RCT-Folly/Fabric + - RCTRequired + - RCTTypeSafety + - React-Core + - React-debug + - React-Fabric + - React-featureflags + - React-graphics + - React-ImageManager + - React-jsi + - react-native-keyboard-controller/common (= 1.20.2) + - React-NativeModulesApple + - React-RCTFabric + - React-renderercss + - React-rendererdebug + - React-utils + - ReactCodegen + - ReactCommon/turbomodule/bridging + - ReactCommon/turbomodule/core + - SocketRocket + - Yoga + - react-native-keyboard-controller/common (1.20.2): - boost - DoubleConversion - fast_float @@ -2274,10 +2400,64 @@ PODS: - SocketRocket - Yoga - react-native-launch-arguments (4.1.0): - - React + - boost + - DoubleConversion + - fast_float + - fmt + - glog + - hermes-engine + - RCT-Folly + - RCT-Folly/Fabric + - RCTRequired + - RCTTypeSafety + - React-Core + - React-debug + - React-Fabric + - React-featureflags + - React-graphics + - React-ImageManager + - React-jsi + - React-NativeModulesApple + - React-RCTFabric + - React-renderercss + - React-rendererdebug + - React-utils + - ReactCodegen + - ReactCommon/turbomodule/bridging + - ReactCommon/turbomodule/core + - SocketRocket + - Yoga + - react-native-menu (1.2.2): + - boost + - DoubleConversion + - fast_float + - fmt + - glog + - hermes-engine + - RCT-Folly + - RCT-Folly/Fabric + - RCTRequired + - RCTTypeSafety + - React-Core + - React-debug + - React-Fabric + - React-featureflags + - React-graphics + - React-ImageManager + - React-jsi + - React-NativeModulesApple + - React-RCTFabric + - React-renderercss + - React-rendererdebug + - React-utils + - ReactCodegen + - ReactCommon/turbomodule/bridging + - ReactCommon/turbomodule/core + - SocketRocket + - Yoga - react-native-netinfo (11.4.1): - React-Core - - react-native-pager-view (6.7.1): + - react-native-pager-view (7.0.1): - boost - DoubleConversion - fast_float @@ -2306,11 +2486,122 @@ PODS: - SocketRocket - Yoga - react-native-performance (5.1.4): + - boost + - DoubleConversion + - fast_float + - fmt + - glog + - hermes-engine + - RCT-Folly + - RCT-Folly/Fabric + - RCTRequired + - RCTTypeSafety - React-Core + - React-debug + - React-Fabric + - React-featureflags + - React-graphics + - React-ImageManager + - React-jsi + - React-NativeModulesApple + - React-RCTFabric + - React-renderercss + - React-rendererdebug + - React-utils + - ReactCodegen + - ReactCommon/turbomodule/bridging + - ReactCommon/turbomodule/core + - SocketRocket + - Yoga - react-native-render-html (6.3.4): - React-Core - react-native-safe-area-context (5.6.1): + - boost + - DoubleConversion + - fast_float + - fmt + - glog + - hermes-engine + - RCT-Folly + - RCT-Folly/Fabric + - RCTRequired + - RCTTypeSafety + - React-Core + - React-debug + - React-Fabric + - React-featureflags + - React-graphics + - React-ImageManager + - React-jsi + - react-native-safe-area-context/common (= 5.6.1) + - react-native-safe-area-context/fabric (= 5.6.1) + - React-NativeModulesApple + - React-RCTFabric + - React-renderercss + - React-rendererdebug + - React-utils + - ReactCodegen + - ReactCommon/turbomodule/bridging + - ReactCommon/turbomodule/core + - SocketRocket + - Yoga + - react-native-safe-area-context/common (5.6.1): + - boost + - DoubleConversion + - fast_float + - fmt + - glog + - hermes-engine + - RCT-Folly + - RCT-Folly/Fabric + - RCTRequired + - RCTTypeSafety - React-Core + - React-debug + - React-Fabric + - React-featureflags + - React-graphics + - React-ImageManager + - React-jsi + - React-NativeModulesApple + - React-RCTFabric + - React-renderercss + - React-rendererdebug + - React-utils + - ReactCodegen + - ReactCommon/turbomodule/bridging + - ReactCommon/turbomodule/core + - SocketRocket + - Yoga + - react-native-safe-area-context/fabric (5.6.1): + - boost + - DoubleConversion + - fast_float + - fmt + - glog + - hermes-engine + - RCT-Folly + - RCT-Folly/Fabric + - RCTRequired + - RCTTypeSafety + - React-Core + - React-debug + - React-Fabric + - React-featureflags + - React-graphics + - React-ImageManager + - React-jsi + - react-native-safe-area-context/common + - React-NativeModulesApple + - React-RCTFabric + - React-renderercss + - React-rendererdebug + - React-utils + - ReactCodegen + - ReactCommon/turbomodule/bridging + - ReactCommon/turbomodule/core + - SocketRocket + - Yoga - react-native-shake (6.8.1): - boost - DoubleConversion @@ -2889,34 +3180,138 @@ PODS: - fmt - glog - hermes-engine - - RCT-Folly - - RCT-Folly/Fabric - - React-callinvoker (= 0.81.5) - - React-cxxreact (= 0.81.5) - - React-debug (= 0.81.5) - - React-featureflags (= 0.81.5) - - React-jsi (= 0.81.5) - - React-logger (= 0.81.5) - - React-perflogger (= 0.81.5) - - React-utils (= 0.81.5) - - SocketRocket - - RNAppleAuthentication (2.1.5): - - React-Core - - RNBootSplash (6.3.10): - - React-Core - - RNCAsyncStorage (2.2.0): - - React-Core - - RNCClipboard (1.16.2): - - React-Core - - RNDeviceInfo (14.0.0): - - React-Core - - RNFastImage (8.12.0): + - RCT-Folly + - RCT-Folly/Fabric + - React-callinvoker (= 0.81.5) + - React-cxxreact (= 0.81.5) + - React-debug (= 0.81.5) + - React-featureflags (= 0.81.5) + - React-jsi (= 0.81.5) + - React-logger (= 0.81.5) + - React-perflogger (= 0.81.5) + - React-utils (= 0.81.5) + - SocketRocket + - RNAppleAuthentication (2.1.5): + - React-Core + - RNBootSplash (6.3.10): + - boost + - DoubleConversion + - fast_float + - fmt + - glog + - hermes-engine + - RCT-Folly + - RCT-Folly/Fabric + - RCTRequired + - RCTTypeSafety + - React-Core + - React-debug + - React-Fabric + - React-featureflags + - React-graphics + - React-ImageManager + - React-jsi + - React-NativeModulesApple + - React-RCTFabric + - React-renderercss + - React-rendererdebug + - React-utils + - ReactCodegen + - ReactCommon/turbomodule/bridging + - ReactCommon/turbomodule/core + - SocketRocket + - Yoga + - RNCAsyncStorage (2.2.0): + - boost + - DoubleConversion + - fast_float + - fmt + - glog + - hermes-engine + - RCT-Folly + - RCT-Folly/Fabric + - RCTRequired + - RCTTypeSafety + - React-Core + - React-debug + - React-Fabric + - React-featureflags + - React-graphics + - React-ImageManager + - React-jsi + - React-NativeModulesApple + - React-RCTFabric + - React-renderercss + - React-rendererdebug + - React-utils + - ReactCodegen + - ReactCommon/turbomodule/bridging + - ReactCommon/turbomodule/core + - SocketRocket + - Yoga + - RNCClipboard (1.16.2): + - boost + - DoubleConversion + - fast_float + - fmt + - glog + - hermes-engine + - RCT-Folly + - RCT-Folly/Fabric + - RCTRequired + - RCTTypeSafety + - React-Core + - React-debug + - React-Fabric + - React-featureflags + - React-graphics + - React-ImageManager + - React-jsi + - React-NativeModulesApple + - React-RCTFabric + - React-renderercss + - React-rendererdebug + - React-utils + - ReactCodegen + - ReactCommon/turbomodule/bridging + - ReactCommon/turbomodule/core + - SocketRocket + - Yoga + - RNDeviceInfo (14.0.0): + - React-Core + - RNFastImage (8.12.0): + - boost + - DoubleConversion + - fast_float + - fmt + - glog + - hermes-engine - libavif/core (~> 0.11.1) - libavif/libdav1d (~> 0.11.1) + - RCT-Folly + - RCT-Folly/Fabric + - RCTRequired + - RCTTypeSafety - React-Core + - React-debug + - React-Fabric + - React-featureflags + - React-graphics + - React-ImageManager + - React-jsi + - React-NativeModulesApple + - React-RCTFabric + - React-renderercss + - React-rendererdebug + - React-utils + - ReactCodegen + - ReactCommon/turbomodule/bridging + - ReactCommon/turbomodule/core - SDWebImage (>= 5.19.1) - SDWebImageAVIFCoder (~> 0.11.0) - SDWebImageWebPCoder (~> 0.14) + - SocketRocket + - Yoga - RNFBApp (23.1.0): - Firebase/CoreOnly (= 12.1.0) - React-Core @@ -2925,7 +3320,7 @@ PODS: - FirebaseCoreExtension - React-Core - RNFBApp - - RNFlashList (1.8.3): + - RNGestureHandler (2.28.0): - boost - DoubleConversion - fast_float @@ -2953,7 +3348,10 @@ PODS: - ReactCommon/turbomodule/core - SocketRocket - Yoga - - RNGestureHandler (2.28.0): + - RNGoogleSignin (11.0.1): + - GoogleSignIn (~> 7.0.0) + - React-Core + - RNImageCropPicker (0.51.0): - boost - DoubleConversion - fast_float @@ -2973,18 +3371,18 @@ PODS: - React-jsi - React-NativeModulesApple - React-RCTFabric + - React-RCTImage - React-renderercss - React-rendererdebug - React-utils - ReactCodegen - ReactCommon/turbomodule/bridging - ReactCommon/turbomodule/core + - RNImageCropPicker/QBImagePickerController (= 0.51.0) - SocketRocket + - TOCropViewController (~> 2.7.4) - Yoga - - RNGoogleSignin (11.0.1): - - GoogleSignIn (~> 7.0.0) - - React-Core - - RNImageCropPicker (0.51.0): + - RNImageCropPicker/QBImagePickerController (0.51.0): - boost - DoubleConversion - fast_float @@ -3011,11 +3409,10 @@ PODS: - ReactCodegen - ReactCommon/turbomodule/bridging - ReactCommon/turbomodule/core - - RNImageCropPicker/QBImagePickerController (= 0.51.0) - SocketRocket - TOCropViewController (~> 2.7.4) - Yoga - - RNImageCropPicker/QBImagePickerController (0.51.0): + - RNKeychain (10.0.0): - boost - DoubleConversion - fast_float @@ -3035,7 +3432,6 @@ PODS: - React-jsi - React-NativeModulesApple - React-RCTFabric - - React-RCTImage - React-renderercss - React-rendererdebug - React-utils @@ -3043,9 +3439,8 @@ PODS: - ReactCommon/turbomodule/bridging - ReactCommon/turbomodule/core - SocketRocket - - TOCropViewController (~> 2.7.4) - Yoga - - RNKeychain (10.0.0): + - RNLocalize (3.5.2): - boost - DoubleConversion - fast_float @@ -3073,8 +3468,6 @@ PODS: - ReactCommon/turbomodule/core - SocketRocket - Yoga - - RNLocalize (3.5.2): - - React-Core - rnmapbox-maps (10.1.44): - MapboxMaps (~> 10.19.0) - React @@ -3082,20 +3475,67 @@ PODS: - rnmapbox-maps/DynamicLibrary (= 10.1.44) - Turf - rnmapbox-maps/DynamicLibrary (10.1.44): + - boost + - DoubleConversion + - fast_float + - fmt + - hermes-engine - MapboxMaps (~> 10.19.0) + - RCT-Folly + - RCT-Folly/Fabric + - RCTRequired + - RCTTypeSafety - React - React-Core + - React-featureflags + - React-ImageManager + - React-jsi + - React-NativeModulesApple + - React-RCTFabric + - React-renderercss + - React-rendererdebug + - ReactCodegen + - ReactCommon/turbomodule/bridging + - ReactCommon/turbomodule/core + - SocketRocket - Turf + - Yoga - RNNotifee (9.1.8): - React-Core - RNNotifee/NotifeeCore (= 9.1.8) - RNNotifee/NotifeeCore (9.1.8): - React-Core - RNPermissions (5.4.4): + - boost + - DoubleConversion + - fast_float + - fmt + - glog + - hermes-engine + - RCT-Folly + - RCT-Folly/Fabric + - RCTRequired + - RCTTypeSafety - React-Core + - React-debug + - React-Fabric + - React-featureflags + - React-graphics + - React-ImageManager + - React-jsi + - React-NativeModulesApple + - React-RCTFabric + - React-renderercss + - React-rendererdebug + - React-utils + - ReactCodegen + - ReactCommon/turbomodule/bridging + - ReactCommon/turbomodule/core + - SocketRocket + - Yoga - RNReactNativeHapticFeedback (1.13.0): - React-Core - - RNReanimated (3.19.4): + - RNReanimated (3.19.5): - boost - DoubleConversion - fast_float @@ -3122,11 +3562,11 @@ PODS: - ReactCodegen - ReactCommon/turbomodule/bridging - ReactCommon/turbomodule/core - - RNReanimated/reanimated (= 3.19.4) - - RNReanimated/worklets (= 3.19.4) + - RNReanimated/reanimated (= 3.19.5) + - RNReanimated/worklets (= 3.19.5) - SocketRocket - Yoga - - RNReanimated/reanimated (3.19.4): + - RNReanimated/reanimated (3.19.5): - boost - DoubleConversion - fast_float @@ -3153,10 +3593,10 @@ PODS: - ReactCodegen - ReactCommon/turbomodule/bridging - ReactCommon/turbomodule/core - - RNReanimated/reanimated/apple (= 3.19.4) + - RNReanimated/reanimated/apple (= 3.19.5) - SocketRocket - Yoga - - RNReanimated/reanimated/apple (3.19.4): + - RNReanimated/reanimated/apple (3.19.5): - boost - DoubleConversion - fast_float @@ -3185,7 +3625,7 @@ PODS: - ReactCommon/turbomodule/core - SocketRocket - Yoga - - RNReanimated/worklets (3.19.4): + - RNReanimated/worklets (3.19.5): - boost - DoubleConversion - fast_float @@ -3212,10 +3652,10 @@ PODS: - ReactCodegen - ReactCommon/turbomodule/bridging - ReactCommon/turbomodule/core - - RNReanimated/worklets/apple (= 3.19.4) + - RNReanimated/worklets/apple (= 3.19.5) - SocketRocket - Yoga - - RNReanimated/worklets/apple (3.19.4): + - RNReanimated/worklets/apple (3.19.5): - boost - DoubleConversion - fast_float @@ -3245,6 +3685,36 @@ PODS: - SocketRocket - Yoga - RNScreens (4.16.0): + - boost + - DoubleConversion + - fast_float + - fmt + - glog + - hermes-engine + - RCT-Folly + - RCT-Folly/Fabric + - RCTRequired + - RCTTypeSafety + - React-Core + - React-debug + - React-Fabric + - React-featureflags + - React-graphics + - React-ImageManager + - React-jsi + - React-NativeModulesApple + - React-RCTFabric + - React-RCTImage + - React-renderercss + - React-rendererdebug + - React-utils + - ReactCodegen + - ReactCommon/turbomodule/bridging + - ReactCommon/turbomodule/core + - RNScreens/common (= 4.16.0) + - SocketRocket + - Yoga + - RNScreens/common (4.16.0): - boost - DoubleConversion - fast_float @@ -3332,7 +3802,62 @@ PODS: - SocketRocket - Yoga - RNSVG (15.14.0): + - boost + - DoubleConversion + - fast_float + - fmt + - glog + - hermes-engine + - RCT-Folly + - RCT-Folly/Fabric + - RCTRequired + - RCTTypeSafety + - React-Core + - React-debug + - React-Fabric + - React-featureflags + - React-graphics + - React-ImageManager + - React-jsi + - React-NativeModulesApple + - React-RCTFabric + - React-renderercss + - React-rendererdebug + - React-utils + - ReactCodegen + - ReactCommon/turbomodule/bridging + - ReactCommon/turbomodule/core + - RNSVG/common (= 15.14.0) + - SocketRocket + - Yoga + - RNSVG/common (15.14.0): + - boost + - DoubleConversion + - fast_float + - fmt + - glog + - hermes-engine + - RCT-Folly + - RCT-Folly/Fabric + - RCTRequired + - RCTTypeSafety - React-Core + - React-debug + - React-Fabric + - React-featureflags + - React-graphics + - React-ImageManager + - React-jsi + - React-NativeModulesApple + - React-RCTFabric + - React-renderercss + - React-rendererdebug + - React-utils + - ReactCodegen + - ReactCommon/turbomodule/bridging + - ReactCommon/turbomodule/core + - SocketRocket + - Yoga - SDWebImage (5.19.1): - SDWebImage/Core (= 5.19.1) - SDWebImage/Core (5.19.1) @@ -3362,13 +3887,74 @@ PODS: - StripePaymentsUI (= 24.19.0) - StripeUICore (= 24.19.0) - stripe-react-native (0.50.3): + - boost + - DoubleConversion + - fast_float + - fmt + - glog + - hermes-engine + - RCT-Folly + - RCT-Folly/Fabric + - RCTRequired + - RCTTypeSafety + - React-Core + - React-debug + - React-Fabric + - React-featureflags + - React-graphics + - React-ImageManager + - React-jsi + - React-NativeModulesApple + - React-RCTFabric + - React-renderercss + - React-rendererdebug + - React-utils + - ReactCodegen + - ReactCommon/turbomodule/bridging + - ReactCommon/turbomodule/core + - SocketRocket + - Stripe (~> 24.19.0) + - stripe-react-native/NewArch (= 0.50.3) + - StripeApplePay (~> 24.19.0) + - StripeFinancialConnections (~> 24.19.0) + - StripePayments (~> 24.19.0) + - StripePaymentSheet (~> 24.19.0) + - StripePaymentsUI (~> 24.19.0) + - Yoga + - stripe-react-native/NewArch (0.50.3): + - boost + - DoubleConversion + - fast_float + - fmt + - glog + - hermes-engine + - RCT-Folly + - RCT-Folly/Fabric + - RCTRequired + - RCTTypeSafety - React-Core + - React-debug + - React-Fabric + - React-featureflags + - React-graphics + - React-ImageManager + - React-jsi + - React-NativeModulesApple + - React-RCTFabric + - React-renderercss + - React-rendererdebug + - React-utils + - ReactCodegen + - ReactCommon/turbomodule/bridging + - ReactCommon/turbomodule/core + - SocketRocket - Stripe (~> 24.19.0) - StripeApplePay (~> 24.19.0) - StripeFinancialConnections (~> 24.19.0) - StripePayments (~> 24.19.0) - StripePaymentSheet (~> 24.19.0) - StripePaymentsUI (~> 24.19.0) + - Yoga - StripeApplePay (24.19.0): - StripeCore (= 24.19.0) - StripeCore (24.19.0) @@ -3496,16 +4082,18 @@ DEPENDENCIES: - React-microtasksnativemodule (from `../node_modules/react-native/ReactCommon/react/nativemodule/microtasks`) - react-native-blob-util (from `../node_modules/react-native-blob-util`) - react-native-blurhash (from `../node_modules/react-native-blurhash`) - - react-native-context-menu-view (from `../node_modules/react-native-context-menu-view`) - "react-native-cookies (from `../node_modules/@react-native-cookies/cookies`)" - "react-native-document-picker (from `../node_modules/@react-native-documents/picker`)" - react-native-fbsdk-next (from `../node_modules/react-native-fbsdk-next`) - "react-native-geolocation (from `../node_modules/@react-native-community/geolocation`)" - react-native-get-random-values (from `../node_modules/react-native-get-random-values`) - react-native-in-app-review (from `../node_modules/react-native-in-app-review`) + - react-native-ios-context-menu (from `../node_modules/react-native-ios-context-menu`) + - react-native-ios-utilities (from `../node_modules/react-native-ios-utilities`) - react-native-keyboard-controller (from `../node_modules/react-native-keyboard-controller`) - react-native-keys (from `../node_modules/react-native-keys`) - react-native-launch-arguments (from `../node_modules/react-native-launch-arguments`) + - "react-native-menu (from `../node_modules/@react-native-menu/menu`)" - "react-native-netinfo (from `../node_modules/@react-native-community/netinfo`)" - react-native-pager-view (from `../node_modules/react-native-pager-view`) - react-native-performance (from `../node_modules/react-native-performance`) @@ -3552,7 +4140,6 @@ DEPENDENCIES: - "RNFastImage (from `../node_modules/@d11/react-native-fast-image`)" - "RNFBApp (from `../node_modules/@react-native-firebase/app`)" - "RNFBMessaging (from `../node_modules/@react-native-firebase/messaging`)" - - "RNFlashList (from `../node_modules/@shopify/flash-list`)" - RNGestureHandler (from `../node_modules/react-native-gesture-handler`) - "RNGoogleSignin (from `../node_modules/@react-native-google-signin/google-signin`)" - RNImageCropPicker (from `../node_modules/react-native-image-crop-picker`) @@ -3590,11 +4177,14 @@ SPEC REPOS: - AFNetworking - AppAuth - CocoaLumberjack + - ComputableLayout + - ContextMenuAuxiliaryPreview - CwlCatchException - CwlCatchExceptionSupport - CwlMachBadInstructionHandler - CwlPosixPreconditionTesting - CwlPreconditionTesting + - DGSwiftUtilities - Expecta - "Expecta+Snapshots" - FBAEMKit @@ -3798,8 +4388,6 @@ EXTERNAL SOURCES: :path: "../node_modules/react-native-blob-util" react-native-blurhash: :path: "../node_modules/react-native-blurhash" - react-native-context-menu-view: - :path: "../node_modules/react-native-context-menu-view" react-native-cookies: :path: "../node_modules/@react-native-cookies/cookies" react-native-document-picker: @@ -3812,12 +4400,18 @@ EXTERNAL SOURCES: :path: "../node_modules/react-native-get-random-values" react-native-in-app-review: :path: "../node_modules/react-native-in-app-review" + react-native-ios-context-menu: + :path: "../node_modules/react-native-ios-context-menu" + react-native-ios-utilities: + :path: "../node_modules/react-native-ios-utilities" react-native-keyboard-controller: :path: "../node_modules/react-native-keyboard-controller" react-native-keys: :path: "../node_modules/react-native-keys" react-native-launch-arguments: :path: "../node_modules/react-native-launch-arguments" + react-native-menu: + :path: "../node_modules/@react-native-menu/menu" react-native-netinfo: :path: "../node_modules/@react-native-community/netinfo" react-native-pager-view: @@ -3910,8 +4504,6 @@ EXTERNAL SOURCES: :path: "../node_modules/@react-native-firebase/app" RNFBMessaging: :path: "../node_modules/@react-native-firebase/messaging" - RNFlashList: - :path: "../node_modules/@shopify/flash-list" RNGestureHandler: :path: "../node_modules/react-native-gesture-handler" RNGoogleSignin: @@ -3974,17 +4566,20 @@ SPEC CHECKSUMS: AFNetworking: 9d57de7506959955d82fb5274ee4bec86b930e52 AppAuth: d4f13a8fe0baf391b2108511793e4b479691fb73 boost: 7e761d76ca2ce687f7cc98e698152abd03a18f90 - braze-react-native-sdk: 85a849ef0e6a2d35cc261f982013d06f0e0907ef + braze-react-native-sdk: 06e01f3e619ee54edaae49ab6470f643df118422 BrazeKit: 4dff9532234bb6faa1721a87f7927cc4c2880f28 BrazeLocation: 7c828b42008203ae512e0ed846c4e0e294c27052 BrazeUI: df3abdd46d2fe158cac147e9a8651d56be67a337 BVLinearGradient: cb006ba232a1f3e4f341bb62c42d1098c284da70 CocoaLumberjack: 5644158777912b7de7469fa881f8a3f259c2512a + ComputableLayout: c50faffac4ed9f8f05b0ce5e6f3a60df1f6042c8 + ContextMenuAuxiliaryPreview: 20be0be795b783b68f8792732eed4bed9f202c1c CwlCatchException: 7acc161b299a6de7f0a46a6ed741eae2c8b4d75a CwlCatchExceptionSupport: 54ccab8d8c78907b57f99717fb19d4cc3bce02dc CwlMachBadInstructionHandler: dae4fdd124d45c9910ac240287cc7b898f4502a1 CwlPosixPreconditionTesting: ecd095aa2129e740b44301c34571e8d85906fb88 CwlPreconditionTesting: 67a0047dd4de4382b93442c0e3f25207f984f35a + DGSwiftUtilities: 567f8d5ee618f0b7afb185b17aa45ff356315a0f DoubleConversion: cb417026b2400c8f53ae97020b2be961b59470cb EASClient: 68127f1248d2b25fdc82dbbfb17be95d1c4700be EXConstants: fd688cef4e401dcf798a021cfb5d87c890c30ba3 @@ -3992,16 +4587,16 @@ SPEC CHECKSUMS: EXManifests: 224345a575fca389073c416297b6348163f28d1a Expecta: 3b6bd90a64b9a1dcb0b70aa0e10a7f8f631667d5 "Expecta+Snapshots": 7a3ac7ad2b9bae43aadb4dca08113bb495c98f3e - Expo: fcdc7d98a60a5762f18a47676b7245b1849cf3fb + Expo: 038e807e43fecf6e306f04df6542d22f2da92d5e ExpoAdapterFBSDKNext: 16c905ebd6449c37bd5dfbb2784a678ce084b26e ExpoAdapterGoogleSignIn: 3a02de846d07a35ed9d505bb45f66592d20c1de0 ExpoAsset: 9ba6fbd677fb8e241a3899ac00fa735bc911eadf ExpoFileSystem: b79eadbda7b7f285f378f95f959cc9313a1c9c61 ExpoFont: cf9d90ec1d3b97c4f513211905724c8171f82961 ExpoKeepAwake: 1a2e820692e933c94a565ec3fbbe38ac31658ffe - ExpoModulesCore: 891cb597118e80dd7f600153f2a7e643b9bca6f7 + ExpoModulesCore: c38e2b16c117698c4ac907d1b929d111601d5db8 EXStructuredHeaders: c951e77f2d936f88637421e9588c976da5827368 - EXUpdates: 0c59ecce7971e00c27785feededd97ef1aeaa14a + EXUpdates: 1751b113e229ba77c6dbb9c076a44a7d90917447 EXUpdatesInterface: 5adf50cb41e079c861da6d9b4b954c3db9a50734 fast_float: b32c788ed9c6a8c584d114d0047beda9664e7cc6 FBAEMKit: b2ed182002dbcb65d5a60059c9693d322186cd00 @@ -4088,40 +4683,42 @@ SPEC CHECKSUMS: React-logger: a913317214a26565cd4c045347edf1bcacb80a3f React-Mapbuffer: 94f4264de2cb156960cd82b338a403f4653f2fd9 React-microtasksnativemodule: 6c4ee39a36958c39c97b074d28f360246a335e84 - react-native-blob-util: f7234c91ad0e3faeee51b3edee80b61553f74993 - react-native-blurhash: b9ce90b66b73b8483cb4f510ece10b25d901ea33 - react-native-context-menu-view: 74fbcf8a5f842c4802d0121addda2f8ffca43604 + react-native-blob-util: 10c78778354e6c92b7a5afa4a1027cf0f18a9bb9 + react-native-blurhash: c1721deafe7a685088ea14ab4712a1c460be9fe4 react-native-cookies: b90327af903c8a7652100201d890c50a98697799 - react-native-document-picker: a5b16a4479790738a9536013121331d9108d25c0 + react-native-document-picker: f26f09a90cce65b5d682f21b511e8eb09a506fdc react-native-fbsdk-next: 52f81e60eb3e8e0e06cf9728b4572d3509ca9d01 - react-native-geolocation: 2679f2c50cc4923545b57024bebb58d78b134a57 + react-native-geolocation: 95e48fe2687e5a8280103085372fa62c2297c5d6 react-native-get-random-values: d16467cf726c618e9c7a8c3c39c31faa2244bbba react-native-in-app-review: b3d1eed3d1596ebf6539804778272c4c65e4a400 - react-native-keyboard-controller: ba0a651f81140c60882c9868969de4d1db8d5206 - react-native-keys: c61a7d6e52300fccb68a60b849940ad5cd904b98 - react-native-launch-arguments: 165260aba9544f00c66fae3e136b11484d0cb49b + react-native-ios-context-menu: afeb0ca80a48e6d13a5d712928ca3b2fdbef037e + react-native-ios-utilities: d9ed1f5ea011650e9c7e9cb7c82272c1f0363e44 + react-native-keyboard-controller: d8d31b877dada043156156497b242d9b1ce0d485 + react-native-keys: 80dc5f204b236ff384be06a514294eb24c65bd1f + react-native-launch-arguments: 26b9a5b2ec14819d3eb07150120e18feda572195 + react-native-menu: 5962c8b2413669b5013c3579554df4d8b856c887 react-native-netinfo: cec9c4e86083cb5b6aba0e0711f563e2fbbff187 - react-native-pager-view: 972919b76c6dbe92566554b2fb500d37ceca4f35 - react-native-performance: 49e245623a3ecee9dc6b228ad7870a98dbedf9ea + react-native-pager-view: 6132f46ae73440fa7c83ae9d8dfdda3edece5222 + react-native-performance: 1cff1830de6c7b64d56b5c0c92b6dbece74acc03 react-native-render-html: 5afc4751f1a98621b3009432ef84c47019dcb2bd - react-native-safe-area-context: 2243039f43d10cb1ea30ec5ac57fc6d1448413f4 - react-native-shake: 76be733c1142bd741fd5ebcf2a1c9dd2c9bca126 - react-native-view-shot: b5fc41b75f8ce016389105414e7d9225bc6a7cd3 - react-native-webview: 94ae920685a61c5e36438a30ce47fe521011c5bd + react-native-safe-area-context: c6e2edd1c1da07bdce287fa9d9e60c5f7b514616 + react-native-shake: a701ed43830d9d7940893f4f7b837970d322ae63 + react-native-view-shot: 6c008e58f4720de58370848201c5d4a082c6d4ca + react-native-webview: 4cbb7f05f2c50671a7dcff4012d3e85faad271e4 React-NativeModulesApple: ebf2ce72b35870036900d6498b33724386540a71 React-oscompat: eb0626e8ba1a2c61673c991bf9dc21834898475d React-perflogger: 509e1f9a3ee28df71b0a66de806ac515ce951246 React-performancetimeline: 43a1ea36ac47853b479ae85e04c1c339721e99f1 React-RCTActionSheet: 30fe8f9f8d86db4a25ff34595a658ecd837485fc React-RCTAnimation: 3126eb1cb8e7a6ca33a52fd833d8018aa9311af1 - React-RCTAppDelegate: 580873aef88cf9f054559f53193333c64844ed02 + React-RCTAppDelegate: b03981c790aa40cf26e0f78cc0f1f2df8287ead4 React-RCTBlob: 53c35e85c85d6bdaa55dc81a0b290d4e78431095 - React-RCTFabric: 2116086e4b0f9cdb3ae7882fab54af91add55675 - React-RCTFBReactNativeSpec: 6964bed5a0ee4cff46af08e8720e9f4732b72371 + React-RCTFabric: 4e2a4176f99b6b8f2d2eda9fc82453a3e6c3ef8e + React-RCTFBReactNativeSpec: 947126c649e04b95457a40bc97c4b2a76206534b React-RCTImage: 074b2faa71a152a456c974e118b60c9eeda94a64 React-RCTLinking: e5ca17a4f7ae2ad7b0c0483be77e1b383ecd0a8a React-RCTNetwork: c508d7548c9eceac30a8100a846ea00033a03366 - React-RCTRuntime: 90cad3ae18c9e8e273dea74a54068ded36e870b9 + React-RCTRuntime: 6813778046c775c124179d9e4d7b33d4129bbd84 React-RCTSettings: dd84c857a4fce42c1e08c1dabcda894e25af4a6e React-RCTText: 6e4b177d047f98bccb90d6fb1ebdd3391cf8b299 React-RCTVibration: 9572d4a06a0c92650bcc62913e50eb2a89f19fb6 @@ -4139,28 +4736,27 @@ SPEC CHECKSUMS: ReactCodegen: 6c26f8c25d0b5ae66f86a1cce1777076ac8bcbd8 ReactCommon: 5f0e5c09a64a2717215dd84380e1a747810406f2 RNAppleAuthentication: 98f367520bd647ea4c094dc3e133106ac523798a - RNBootSplash: 866866f2a3856cd76547a24c6a63be79aeca40f8 - RNCAsyncStorage: b44e8a4e798c3e1f56bffccd0f591f674fb9198f - RNCClipboard: e1d17c9d093d8129ef50b39b63a17a0e8ccd0ade + RNBootSplash: a3179e35cb328629176b7891e1ef1fb9ef364fc3 + RNCAsyncStorage: 29f0230e1a25f36c20b05f65e2eb8958d6526e82 + RNCClipboard: adba6334687b7fb2c37760e26dedd550b4846a72 RNDeviceInfo: f632df5f5d9262794c03eac265e4a0f6dbb14f0a - RNFastImage: d08eb15eaa651ba916e0304febfe2ee342afc65c + RNFastImage: 4b6aa4ec13de8dc57deef25f89f00aa93a2cf139 RNFBApp: fcac8339a5ffd5a735c62d5f0101f79e4d9a7670 RNFBMessaging: 8c72e2f7d5eb2cc24d87e60c8be21eb2c94da272 - RNFlashList: 3ff55e40f74f7cd92cb5bc7486390b8c5c9648b6 - RNGestureHandler: 12a436b5074378be95468a57b62c165a1e24cfc9 + RNGestureHandler: 3a73f098d74712952870e948b3d9cf7b6cae9961 RNGoogleSignin: b8f09e3ec56e09497e1e53b0ff66d5a45916c6b1 - RNImageCropPicker: f7969b3ba456deaab9ca771b457baa91088e1004 - RNKeychain: d9571527e40c1616307e6d213628b266fee8485b - RNLocalize: 3c4d0abd777a546fa77bdb6caef85a87fb9ea349 - rnmapbox-maps: e066ffa5925108bce9b965936d956fce32c1258b + RNImageCropPicker: 07691ec35bc874cf46b39d7710d82f63c9ca0817 + RNKeychain: a2c134ab796272c3d605e035ab727591000b30f3 + RNLocalize: a0ec66afe0980934cfe13f3bc30f476443388a36 + rnmapbox-maps: bc9868374cefc4778722375fcb3de859a9fff16f RNNotifee: 5e3b271e8ea7456a36eec994085543c9adca9168 - RNPermissions: 51e7cdc5926c997fd287160ee0f2d6bc3d999233 + RNPermissions: d1b50022f1cb4d183dc9b7e1e1764764e9dd5f2b RNReactNativeHapticFeedback: 7601768ee65ffc86fc93d7c30dd917031144ed3d - RNReanimated: 9282065c1fb748d2d1945ba46d6592c2cf4e5cc8 - RNScreens: 35525ebfe219c8709da0d26aebbc9a5e02e1077b - RNSentry: b0455dc51809e9dd714eb81081435b2ff428266c - RNShare: d6b60469ede41726ec1d6eadbcc83f07ffb6efb1 - RNSVG: ad69b385e35653fd9694935c48840117e96ccc1d + RNReanimated: 9af1b9f7d221d1cc2f99d935bab08419cae7c1ce + RNScreens: 0bbf16c074ae6bb1058a7bf2d1ae017f4306797c + RNSentry: 8dade4197bddd74024f1e8160669c0ee44dade5a + RNShare: 1dba46787d6e5543e05655efaefa0e4bb98380d9 + RNSVG: c5807de8e337c7a643f9bad2ecf48a15aefcc23c SDWebImage: 40b0b4053e36c660a764958bff99eed16610acbb SDWebImageAVIFCoder: afe194a084e851f70228e4be35ef651df0fc5c57 SDWebImageWebPCoder: e38c0a70396191361d60c092933e22c20d5b1380 @@ -4173,7 +4769,7 @@ SPEC CHECKSUMS: Specta: b79d84043684b35ffdc2680df578dc318ec2efc2 Starscream: 19b5533ddb925208db698f0ac508a100b884a1b9 Stripe: d1824162e4bcb6ead10401a0dc8e8a3d5ffee41f - stripe-react-native: 4f749e365d363c17224c422b8ca1a94bc5519171 + stripe-react-native: f2af1d3769363ae90b2a6c4bb9642232c2c4d2c9 StripeApplePay: eb64705d3c919492b1b28876652fd0aca2db38cc StripeCore: b5bee05167f0c8ccce936244a031a9972fdeade8 StripeFinancialConnections: fd6c661f86f47b1d26a32f588b3a0b09826aba84 @@ -4190,6 +4786,6 @@ SPEC CHECKSUMS: "XCTest+OHHTTPStubSuiteCleanUp": 4469ec8863c6bc022c5089a9b94233eb3416c5ee Yoga: 728df40394d49f3f471688747cf558158b3a3bd1 -PODFILE CHECKSUM: c79b1c455e28ea16a3418a8f20a84ddcbea49750 +PODFILE CHECKSUM: e79b62e95d139349ea9cc01566aeb6937415de47 COCOAPODS: 1.16.2 diff --git a/ios/Podfile.properties.json b/ios/Podfile.properties.json index b1bd45da51d..125dd1f27c3 100644 --- a/ios/Podfile.properties.json +++ b/ios/Podfile.properties.json @@ -1,3 +1,4 @@ { - "expo.jsEngine": "hermes" + "expo.jsEngine": "hermes", + "expo.newArchEnabled": true } diff --git a/package.json b/package.json index ab4bccf27ea..8d233e00160 100644 --- a/package.json +++ b/package.json @@ -108,7 +108,7 @@ "dependencies": { "@artsy/cohesion": "4.346.0", "@artsy/icons": "3.65.0", - "@artsy/palette-mobile": "22.10.0", + "@artsy/palette-mobile": "22.6.0--canary.425.5263.0", "@artsy/to-title-case": "1.2.0", "@braze/react-native-sdk": "16.1.0", "@d11/react-native-fast-image": "8.12.0", @@ -128,6 +128,7 @@ "@react-native-firebase/app": "23.1.0", "@react-native-firebase/messaging": "23.1.0", "@react-native-google-signin/google-signin": "11.0.1", + "@react-native-menu/menu": "1.2.2", "@react-navigation/bottom-tabs": "7.4.8", "@react-navigation/elements": "2.6.5", "@react-navigation/material-top-tabs": "7.3.8", @@ -139,7 +140,7 @@ "@segment/analytics-react-native-plugin-braze": "0.9.0", "@segment/sovran-react-native": "1.1.3", "@sentry/react-native": "7.9.0", - "@shopify/flash-list": "1.8.3", + "@shopify/flash-list": "2.2.0", "@stripe/stripe-react-native": "0.50.3", "@styled-system/theme-get": "5.1.2", "@unleash/proxy-client-react": "4.5.2", @@ -167,7 +168,6 @@ "react-native-blurhash": "2.1.1", "react-native-bootsplash": "6.3.10", "react-native-collapsible-tab-view": "8.0.1", - "react-native-context-menu-view": "git+https://github.com/artsy/react-native-context-menu-view.git#v1.10.10-artsy", "react-native-device-info": "14.0.0", "react-native-fbsdk-next": "13.4.1", "react-native-gesture-handler": "2.28.0", @@ -175,15 +175,17 @@ "react-native-haptic-feedback": "1.13.0", "react-native-image-crop-picker": "0.51.0", "react-native-in-app-review": "4.3.3", + "react-native-ios-context-menu": "3.2.0", + "react-native-ios-utilities": "5.2.0", "react-native-keyboard-controller": "^1.20.2", "react-native-keychain": "10.0.0", "react-native-keys": "0.7.13", - "react-native-launch-arguments": "4.1.0", + "react-native-launch-arguments": "git+https://github.com/artsy/react-native-launch-arguments.git#v4.1.0-new-architecture-2", "react-native-linear-gradient": "2.8.3", "react-native-localize": "3.5.2", - "react-native-pager-view": "6.7.1", + "react-native-pager-view": "7.0.1", "react-native-permissions": "5.4.4", - "react-native-reanimated": "3.19.4", + "react-native-reanimated": "3.19.5", "react-native-reanimated-zoom": "0.3.3", "react-native-render-html": "6.3.4", "react-native-safe-area-context": "5.6.1", @@ -210,7 +212,8 @@ "url": "0.11.3", "uuid": "10.0.0", "victory-native": "37.3.4", - "yup": "0.31.1" + "yup": "0.31.1", + "zeego": "^3.0.6" }, "devDependencies": { "@artsy/update-repo": "0.8.1", diff --git a/patches/react-native+0.81.5.patch b/patches/react-native+0.81.5.patch index 7f406048816..e9982948b11 100644 --- a/patches/react-native+0.81.5.patch +++ b/patches/react-native+0.81.5.patch @@ -3,7 +3,7 @@ index 6cdec32..8f7cf70 100644 --- a/node_modules/react-native/React/Modules/RCTEventEmitter.m +++ b/node_modules/react-native/React/Modules/RCTEventEmitter.m @@ -89,6 +89,10 @@ - + if (_listenerCount > 0) { [self stopObserving]; + // Reset listener count to allow proper re-initialization on bridge reload @@ -12,4 +12,17 @@ index 6cdec32..8f7cf70 100644 + _listenerCount = 0; } } - + +diff --git a/node_modules/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDefaults.h b/node_modules/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDefaults.h +index e0742c9..eae3d69 100644 +--- a/node_modules/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDefaults.h ++++ b/node_modules/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDefaults.h +@@ -72,7 +72,7 @@ class ReactNativeFeatureFlagsDefaults : public ReactNativeFeatureFlagsProvider { + } + + bool enableCppPropsIteratorSetter() override { +- return false; ++ return true; + } + + bool enableCustomFocusSearchOnClippedElementsAndroid() override { diff --git a/react-native.config.js b/react-native.config.js new file mode 100644 index 00000000000..87acebf6d5d --- /dev/null +++ b/react-native.config.js @@ -0,0 +1,16 @@ +module.exports = { + dependencies: { + zeego: { + platforms: { + // Skip auto-linking here because we don't use it on android + android: null, + }, + }, + "@react-native-menu/menu": { + platforms: { + // Skip auto-linking here because we don't use it on android + android: null, + }, + }, + }, +} diff --git a/scripts/ci/build-for-tests-android b/scripts/ci/build-for-tests-android index b774d1cc7bc..d9c7e23100b 100755 --- a/scripts/ci/build-for-tests-android +++ b/scripts/ci/build-for-tests-android @@ -3,10 +3,10 @@ set -exo pipefail BUILD_TYPE=${1:-release} # default to release if [ "$BUILD_TYPE" == "beta" ]; then - echo "Building Android App in Beta mode" + echo "Building Android App in Beta mode." MODE="beta" else - echo "Building Android App in Release mode" + echo "Building Android App in Release mode." MODE="release" fi CAPITALIZED_BUILD_TYPE="$(echo "$BUILD_TYPE" | awk '{print toupper(substr($0,1,1)) substr($0,2)}')" @@ -14,7 +14,7 @@ CAPITALIZED_BUILD_TYPE="$(echo "$BUILD_TYPE" | awk '{print toupper(substr($0,1,1 pushd android echo "Running Gradle task: assemble${CAPITALIZED_BUILD_TYPE}" -./gradlew assemble${CAPITALIZED_BUILD_TYPE} +./gradlew assemble${CAPITALIZED_BUILD_TYPE} --no-daemon --max-workers=2 popd diff --git a/scripts/setup/install b/scripts/setup/install index c311de0b940..5e6bf0c8119 100755 --- a/scripts/setup/install +++ b/scripts/setup/install @@ -1,7 +1,6 @@ #!/usr/bin/env bash set -euxo pipefail - bundle check || bundle install brew bundle yarn install diff --git a/scripts/utils/clean b/scripts/utils/clean index 10806960c30..aebe6257504 100755 --- a/scripts/utils/clean +++ b/scripts/utils/clean @@ -28,6 +28,9 @@ fi echo 'Clear node modules (┛ಠ_ಠ)┛彡┻━┻' rm -rf node_modules +echo "Reset watchman (ノಠ益ಠ)ノ彡┻━┻" +watchman watch-del . + echo "Clear caches (linting and metro) (┛◉Д◉)┛彡┻━┻" rm -rf .cache rm -rf "${TMPDIR%/}"/metro-* diff --git a/scripts/utils/cleaninstall.sh b/scripts/utils/cleaninstall.sh new file mode 100755 index 00000000000..f98571464da --- /dev/null +++ b/scripts/utils/cleaninstall.sh @@ -0,0 +1,67 @@ +#!/bin/bash + +### Script to clean install everything in order to ensure a fresh environment after +### merging the react native new architecture changes + + +echo "🧹 🧽 🧼 🧹" + + +echo "Clearing android specific caches" + +# rm -rf ~/.gradle/caches +# rm -rf ~/.gradle/daemon + +rm -rf .gradle +rm -rf build +rm -rf app/build + +echo 'Clear node modules (┛ಠ_ಠ)┛彡┻━┻' +rm -rf node_modules + +echo "Clear caches (linting and metro) (┛◉Д◉)┛彡┻━┻" +rm -rf .cache +rm -rf "$TMPDIR/metro*" + +echo "Reset watchman (ノಠ益ಠ)ノ彡┻━┻" +watchman watch-del . + +echo "Clear hastemap (╯ರ ~ ರ)╯︵ ┻━┻" +rm -rf "$TMPDIR/haste-map-*" + +echo "Clear CocoaPods cache (ノಠ益ಠ)ノ彡┻━┻" +rm -rf ~/Library/Caches/CocoaPods + +echo 'Clear Xcode derived data (╯°□°)╯︵ ┻━┻' +# sometimes this fails on first try even with -rf +# but a second try takes it home +if ! rm -rf ~/Library/Developer/Xcode/DerivedData; then + rm -rf ~/Library/Developer/Xcode/DerivedData +fi + +echo "Clear Gems (┛ಠ_ಠ)┛彡┻━┻" +rm -rf .vendor + +echo "Clear Yarn cache (ノಠ益ಠ)ノ彡┻━┻" +yarn cache clean + +echo '✅ Clean complete!' + +echo '📥 Starting fresh install...' + +yarn + +echo '🎨 Setting up Artsy environment' + +yarn setup:artsy + +echo '📥 Installing all dependencies' + +yarn install:all + +echo 'Explicit installation of react native reanimated and worklets to avoid any type of weirdness' + +yarn add react-native-reanimated@4.1.5 react-native-worklets@0.6.1 + + +echo "💫🫧 Everything is squishy clean 💫🫧" \ No newline at end of file diff --git a/src/__mocks__/react-native-ios-context-menu/index.js b/src/__mocks__/react-native-ios-context-menu/index.js new file mode 100644 index 00000000000..c0ac3490216 --- /dev/null +++ b/src/__mocks__/react-native-ios-context-menu/index.js @@ -0,0 +1,8 @@ +// Mock for Zeego's iOS dependency (react-native-ios-context-menu) +// This is a manual mock that Jest automatically uses when the module is imported +const { View } = require("react-native") + +module.exports = { + ContextMenuView: View, + ContextMenuButton: View, +} diff --git a/src/app/Components/Artist/ArtistAbout/ArtistAbout.tsx b/src/app/Components/Artist/ArtistAbout/ArtistAbout.tsx index 2439b6a16ae..ed2b15eb1a7 100644 --- a/src/app/Components/Artist/ArtistAbout/ArtistAbout.tsx +++ b/src/app/Components/Artist/ArtistAbout/ArtistAbout.tsx @@ -1,33 +1,40 @@ import { ContextModule, OwnerType } from "@artsy/cohesion" -import { Flex, Join, Spacer, Tabs } from "@artsy/palette-mobile" -import { ArtistAbout_artist$data } from "__generated__/ArtistAbout_artist.graphql" +import { Flex, Spacer, Spinner, Tabs, useSpace } from "@artsy/palette-mobile" +import { ArtistAboutQuery } from "__generated__/ArtistAboutQuery.graphql" +import { ArtistAbout_artist$key } from "__generated__/ArtistAbout_artist.graphql" import { Articles } from "app/Components/Artist/Articles/Articles" import { ArtistAboutEmpty } from "app/Components/Artist/ArtistAbout/ArtistAboutEmpty" import { ArtistAboutRelatedGenes } from "app/Components/Artist/ArtistAbout/ArtistAboutRelatedGenes" import { Biography, MAX_WIDTH_BIO } from "app/Components/Artist/Biography" import { RelatedArtistsRail } from "app/Components/Artist/RelatedArtistsRail" +import { LoadFailureView, LoadFailureViewProps } from "app/Components/LoadFailureView" import { SectionTitle } from "app/Components/SectionTitle" import { ArtistSeriesMoreSeriesFragmentContainer } from "app/Scenes/ArtistSeries/ArtistSeriesMoreSeries" import { extractNodes } from "app/utils/extractNodes" -import { createFragmentContainer, graphql } from "react-relay" +import { withSuspense } from "app/utils/hooks/withSuspense" +import { compact } from "lodash" +import { graphql, useFragment, useLazyLoadQuery } from "react-relay" import { ArtistAboutShowsFragmentContainer } from "./ArtistAboutShows" import { ArtistCareerHighlights } from "./ArtistCareerHighlights" -interface Props { - artist: ArtistAbout_artist$data +interface ArtistAboutProps { + artist: ArtistAbout_artist$key } -export const ArtistAbout: React.FC = ({ artist }) => { +export const ArtistAbout: React.FC = ({ artist: artistProp }) => { + const space = useSpace() + const artist = useFragment(artistAboutFragment, artistProp) + const articles = extractNodes(artist.articlesConnection) const relatedArtists = extractNodes(artist.related?.artistsConnection) const relatedGenes = extractNodes(artist.related?.genes) const hasInsights = artist.hasArtistInsights.length > 0 - const hasArtistSeries = artist.hasArtistSeriesConnection?.totalCount ?? 0 > 0 - const hasShows = artist.hasArtistShows?.totalCount ?? 0 > 0 + const hasArtistSeries = (artist.hasArtistSeriesConnection?.totalCount ?? 0) > 0 + const hasShows = (artist.hasArtistShows?.totalCount ?? 0) > 0 const hasBiography = !!artist.hasBiographyBlurb?.text - const hasArticles = artist.counts?.articles ?? 0 > 0 - const hasRelatedArtists = artist.counts?.relatedArtists ?? 0 > 0 + const hasArticles = (artist.counts?.articles ?? 0) > 0 + const hasRelatedArtists = (artist.counts?.relatedArtists ?? 0) > 0 const hasRelatedGenes = relatedGenes.length > 0 const isDisplayable = @@ -38,98 +45,178 @@ export const ArtistAbout: React.FC = ({ artist }) => { hasRelatedArtists || hasRelatedGenes - return ( - - {isDisplayable ? ( + const data = compact([ + hasBiography && { + key: "biography", + content: ( <> - - }> - {!!hasBiography && ( - <> - - - - - - - )} - {!!hasInsights && } - {!!hasArtistSeries && ( - - )} - {!!hasArticles && } - {!!hasShows && } - - {!!hasRelatedArtists && } - {!!hasRelatedGenes && } - - + + + + + - ) : ( - - )} - + ), + }, + + !!hasInsights && { + key: "insights", + content: , + }, + + !!hasArtistSeries && { + key: "artistSeries", + content: ( + + ), + }, + + !!hasArticles && { + key: "articles", + content: , + }, + + !!hasShows && { + key: "shows", + content: , + }, + + !!hasRelatedArtists && { + key: "relatedArtists", + content: , + }, + !!hasRelatedGenes && { + key: "relatedGenes", + content: , + }, + ]) + + return ( + item?.content} + keyExtractor={(item) => item?.key} + ItemSeparatorComponent={() => } + contentContainerStyle={{ paddingHorizontal: 0, paddingVertical: space(4) }} + ListEmptyComponent={() => } + /> ) } -export const ArtistAboutContainer = createFragmentContainer(ArtistAbout, { - artist: graphql` - fragment ArtistAbout_artist on Artist { - hasArtistSeriesConnection: artistSeriesConnection(first: 1) { - totalCount - } - hasBiographyBlurb: biographyBlurb(format: PLAIN, partnerBio: false) { - text - } - internalID - hasArtistInsights: insights { - entities - } - hasArtistShows: showsConnection(first: 1, sort: END_AT_ASC, status: "running") { - totalCount - } - slug - ...Biography_artist - ...ArtistSeriesMoreSeries_artist - ...Articles_artist - ...ArtistAboutShows_artist - ...ArtistCareerHighlights_artist - ...RelatedArtistsRailCell_artist - counts { - articles - relatedArtists - } - related { - artistsConnection(first: 12) { - edges { - node { - ...RelatedArtistsRail_artists - } - } - } - genes { - edges { - node { - ...ArtistAboutRelatedGenes_genes - } +const artistAboutFragment = graphql` + fragment ArtistAbout_artist on Artist { + hasArtistSeriesConnection: artistSeriesConnection(first: 1) { + totalCount + } + hasBiographyBlurb: biographyBlurb(format: PLAIN, partnerBio: false) { + text + } + internalID + hasArtistInsights: insights { + entities + } + hasArtistShows: showsConnection(first: 1, sort: END_AT_ASC, status: "running") { + totalCount + } + slug + ...Biography_artist + ...ArtistSeriesMoreSeries_artist + ...Articles_artist + ...ArtistAboutShows_artist + ...ArtistCareerHighlights_artist + ...RelatedArtistsRailCell_artist + counts { + articles + relatedArtists + } + related { + artistsConnection(first: 12) { + edges { + node { + ...RelatedArtistsRail_artists } } } - articlesConnection(first: 5) { + genes { edges { node { - ...Articles_articles + ...ArtistAboutRelatedGenes_genes } } } } - `, + articlesConnection(first: 5) { + edges { + node { + ...Articles_articles + } + } + } + } +` + +export const artistAboutQuery = graphql` + query ArtistAboutQuery($artistID: String!) { + artist(id: $artistID) { + ...ArtistAbout_artist + } + } +` + +interface ArtistAboutQueryRendererProps { + artistID: string +} + +export const ArtistAboutQueryRenderer = withSuspense({ + Component: ({ artistID }) => { + const data = useLazyLoadQuery(artistAboutQuery, { artistID }) + + if (!data.artist) { + return null + } + + return + }, + LoadingFallback: () => , + ErrorFallback: (fallbackProps) => , }) + +const ArtistAboutPlaceholder: React.FC = () => { + const space = useSpace() + + return ( + + + + + + ) +} + +const ArtistAboutError: React.FC = (fallbackProps) => { + const space = useSpace() + + return ( + + + + ) +} diff --git a/src/app/Components/Artist/ArtistAbout/__tests__/ArtistAbout.tests.tsx b/src/app/Components/Artist/ArtistAbout/__tests__/ArtistAbout.tests.tsx index 4119235a98d..021014a0893 100644 --- a/src/app/Components/Artist/ArtistAbout/__tests__/ArtistAbout.tests.tsx +++ b/src/app/Components/Artist/ArtistAbout/__tests__/ArtistAbout.tests.tsx @@ -1,6 +1,6 @@ import { screen } from "@testing-library/react-native" import { ArtistAboutTestsQuery } from "__generated__/ArtistAboutTestsQuery.graphql" -import { ArtistAboutContainer } from "app/Components/Artist/ArtistAbout/ArtistAbout" +import { ArtistAbout } from "app/Components/Artist/ArtistAbout/ArtistAbout" import { ArtistAboutShowsFragmentContainer } from "app/Components/Artist/ArtistAbout/ArtistAboutShows" import { Biography } from "app/Components/Artist/Biography" import { setupTestWrapper } from "app/utils/tests/setupTestWrapper" @@ -8,7 +8,7 @@ import { graphql } from "react-relay" describe("ArtistAbout", () => { const { renderWithRelay } = setupTestWrapper({ - Component: ({ artist }) => , + Component: ({ artist }) => , query: graphql` query ArtistAboutTestsQuery($artistID: String!) @relay_test_operation { artist(id: $artistID) { diff --git a/src/app/Components/Artist/ArtistArtworks/ArtistArtworks.tsx b/src/app/Components/Artist/ArtistArtworks/ArtistArtworks.tsx index 7726321ca96..c900968e09d 100644 --- a/src/app/Components/Artist/ArtistArtworks/ArtistArtworks.tsx +++ b/src/app/Components/Artist/ArtistArtworks/ArtistArtworks.tsx @@ -13,7 +13,7 @@ import { useScreenDimensions, useSpace, } from "@artsy/palette-mobile" -import { MasonryFlashListRef, MasonryListRenderItem } from "@shopify/flash-list" +import { FlashListRef, ListRenderItem } from "@shopify/flash-list" import { ArtistArtworksQuery, ArtistArtworksQuery$data, @@ -50,7 +50,6 @@ import { extractNodes } from "app/utils/extractNodes" import { useFeatureFlag } from "app/utils/hooks/useFeatureFlag" import { withSuspense } from "app/utils/hooks/withSuspense" import { - ESTIMATED_MASONRY_ITEM_SIZE, MASONRY_LIST_PAGE_SIZE, NUM_COLUMNS_MASONRY, ON_END_REACHED_THRESHOLD_MASONRY, @@ -106,7 +105,7 @@ const ArtworksGrid: React.FC = ({ const artworks = useMemo(() => extractNodes(artist.artworks), [artist.artworks]) const artworksCount = artist.artworks?.counts?.total ?? 0 - const gridRef = useRef>(null) + const gridRef = useRef>(null) const appliedFilters = ArtworksFiltersStore.useStoreState((state) => state.appliedFilters) @@ -181,32 +180,23 @@ const ArtworksGrid: React.FC = ({ } } - const renderItem: MasonryListRenderItem = useCallback( - ({ item, index, columnIndex }) => { - const imgAspectRatio = item.image?.aspectRatio ?? 1 - const imgWidth = width / NUM_COLUMNS_MASONRY - space(2) - space(1) - const imgHeight = imgWidth / imgAspectRatio - - return ( - - - - ) - }, - [] - ) + const renderItem: ListRenderItem = useCallback(({ item, index }) => { + const imgAspectRatio = item.image?.aspectRatio ?? 1 + const imgWidth = width / NUM_COLUMNS_MASONRY - space(2) - space(1) + const imgHeight = imgWidth / imgAspectRatio + + return ( + + ) + }, []) const listFooterComponent = useMemo( () => ( @@ -276,7 +266,6 @@ const ArtworksGrid: React.FC = ({ = ({ } keyExtractor={(item) => item.id} renderItem={renderItem} + contentContainerStyle={{ paddingHorizontal: space(1) }} onEndReached={loadMore} onEndReachedThreshold={ON_END_REACHED_THRESHOLD_MASONRY} // need to pass zIndex: 1 here in order for the SubTabBar to // be visible above list content ListHeaderComponentStyle={{ zIndex: 1 }} ListHeaderComponent={ - <> + @@ -320,7 +310,7 @@ const ArtworksGrid: React.FC = ({ artworksCount > 1 ? "s" : "" }:`} - + } ListFooterComponent={listFooterComponent} /> diff --git a/src/app/Components/Artist/ArtistHeaderNavRight.tsx b/src/app/Components/Artist/ArtistHeaderNavRight.tsx index 3943126a39a..b12c1c1ff29 100644 --- a/src/app/Components/Artist/ArtistHeaderNavRight.tsx +++ b/src/app/Components/Artist/ArtistHeaderNavRight.tsx @@ -50,33 +50,31 @@ export const ArtistHeaderNavRight: React.FC = ({ }) // convert the space into primitive types to be user on the UI thread - const space1 = space(1) const space2 = space(2) - const spacerWidth = useDerivedValue( - () => (displayFollowButton.value ? space1 : space2), - [space1, space2] - ) + const followButtonTranslateX = useDerivedValue(() => displayFollowButton.value ? 0 : followAreaDeltaX ) + const followButtonOpacity = useDerivedValue(() => (displayFollowButton.value ? 1 : 0)) const viewStyle = useAnimatedStyle( () => ({ transform: [ { - translateX: withTiming(followButtonTranslateX.value, { - duration: 200, - easing: Easing.sin, - }), + translateX: withTiming( + followButtonTranslateX.value - (displayFollowButton.value ? 0 : space2), + { + duration: 200, + easing: Easing.sin, + } + ), }, ], }), [followAreaDeltaX] ) - const spacerStyle = useAnimatedStyle(() => ({ - width: withTiming(spacerWidth.value, { duration: 200 }), - })) + const followButtonStyle = useAnimatedStyle(() => ({ opacity: withTiming(followButtonOpacity.value, { duration: 200 }), })) @@ -112,8 +110,6 @@ export const ArtistHeaderNavRight: React.FC = ({ - - = (props) => { - const { artist, relay, initialFilters } = props +export const ArtistInsights: React.FC = ({ + artist: artistProp, + initialFilters, +}) => { + const artist = useFragment(artistInsightsFragment, artistProp) const space = useSpace() const tracking = useTracking() @@ -71,7 +77,7 @@ export const ArtistInsights: React.FC = (props) => { Component: () => ( ), }, @@ -89,7 +95,7 @@ export const ArtistInsights: React.FC = (props) => { ), }, ], - [artist, relay.environment, scrollToTop, initialFilters, auctionResultsYCoordinate.current] + [artist, scrollToTop, initialFilters, auctionResultsYCoordinate.current] ) const focusedTab = useFocusedTab() @@ -102,7 +108,7 @@ export const ArtistInsights: React.FC = (props) => { return ( - = (props) => { data={components} keyExtractor={(_, index) => `ArtistInsight-FlatList-element-${index}`} renderItem={({ item: { Component } }) => } + scrollEventThrottle={0.000001} /> = (props) => { ) } -export const ArtistInsightsFragmentContainer = createFragmentContainer(ArtistInsights, { - artist: graphql` - fragment ArtistInsights_artist on Artist { - ...ArtistInsightsAuctionResults_artist - name - id - internalID - slug - statuses { - auctionLots - } +const artistInsightsFragment = graphql` + fragment ArtistInsights_artist on Artist { + ...ArtistInsightsAuctionResults_artist + name + id + internalID + slug + statuses { + auctionLots } - `, + } +` + +export const artistInsightsQuery = graphql` + query ArtistInsightsQuery($artistID: String!) { + artist(id: $artistID) { + ...ArtistInsights_artist + } + } +` + +interface ArtistInsightsQueryRendererProps { + artistID: string + initialFilters?: FilterArray +} + +export const ArtistInsightsQueryRenderer = withSuspense({ + Component: ({ artistID, initialFilters }) => { + const data = useLazyLoadQuery(artistInsightsQuery, { artistID }) + + if (!data.artist) { + return null + } + + return + }, + LoadingFallback: () => , + ErrorFallback: (fallbackProps) => , }) +const ArtistInsightsPlaceholder: React.FC = () => { + const space = useSpace() + + return ( + + + + + + ) +} + +const ArtistInsightsError: React.FC = (fallbackProps) => { + const space = useSpace() + + return ( + + + + ) +} + export const tracks = { openFilter: (id: string, slug: string) => { return { diff --git a/src/app/Components/Artist/ArtistInsights/ArtistInsightsAuctionResults.tsx b/src/app/Components/Artist/ArtistInsights/ArtistInsightsAuctionResults.tsx index 47be33e6f8b..ff9df634ee5 100644 --- a/src/app/Components/Artist/ArtistInsights/ArtistInsightsAuctionResults.tsx +++ b/src/app/Components/Artist/ArtistInsights/ArtistInsightsAuctionResults.tsx @@ -1,5 +1,5 @@ import { ActionType, ContextModule, OwnerType, TappedInfoBubble } from "@artsy/cohesion" -import { Box, bullet, Flex, Separator, Spacer, Text } from "@artsy/palette-mobile" +import { Box, bullet, Flex, Separator, Spacer, Text, useSpace } from "@artsy/palette-mobile" import { ArtistInsightsAuctionResults_artist$data } from "__generated__/ArtistInsightsAuctionResults_artist.graphql" import { ArtistInsightsEmpty } from "app/Components/Artist/ArtistInsights/ArtistsInsightsEmpty" import { @@ -52,6 +52,7 @@ const ArtistInsightsAuctionResults: React.FC = ({ onLayout, onScrollEndDragChange, }) => { + const space = useSpace() const tracking = useTracking() const { width: screenWidth, height: screenHeight } = useScreenDimensions() @@ -281,8 +282,9 @@ const ArtistInsightsAuctionResults: React.FC = ({ )} onScrollEndDrag={onScrollEndDragChange} + nestedScrollEnabled ItemSeparatorComponent={AuctionResultListSeparator} - style={{ width: screenWidth, left: -20 }} + style={{ width: screenWidth, left: -space(2), flexGrow: 1 }} onEndReached={loadMoreAuctionResults} ListFooterComponent={() => loadingMoreData ? ( @@ -291,7 +293,7 @@ const ArtistInsightsAuctionResults: React.FC = ({ ) : null } - contentContainerStyle={{ paddingBottom: 20 }} + contentContainerStyle={{ paddingBottom: space(2) }} /> ) : ( diff --git a/src/app/Components/Artist/ArtistInsights/MarketStats.tsx b/src/app/Components/Artist/ArtistInsights/MarketStats.tsx index a8b031c67bf..e48441cfce1 100644 --- a/src/app/Components/Artist/ArtistInsights/MarketStats.tsx +++ b/src/app/Components/Artist/ArtistInsights/MarketStats.tsx @@ -58,7 +58,7 @@ const MarketStats: React.FC = ({ priceInsightsConnection }) => return ( <> - + diff --git a/src/app/Components/Artist/ArtistInsights/__tests__/ArtistInsights.tests.tsx b/src/app/Components/Artist/ArtistInsights/__tests__/ArtistInsights.tests.tsx index d34c8a99a0a..2b11f08ceba 100644 --- a/src/app/Components/Artist/ArtistInsights/__tests__/ArtistInsights.tests.tsx +++ b/src/app/Components/Artist/ArtistInsights/__tests__/ArtistInsights.tests.tsx @@ -1,11 +1,10 @@ import { ArtistInsightsTestsQuery } from "__generated__/ArtistInsightsTestsQuery.graphql" -import { ArtistInsightsFragmentContainer } from "app/Components/Artist/ArtistInsights/ArtistInsights" +import { ArtistInsights } from "app/Components/Artist/ArtistInsights/ArtistInsights" import { ArtistInsightsAuctionResultsPaginationContainer } from "app/Components/Artist/ArtistInsights/ArtistInsightsAuctionResults" import { flushPromiseQueue } from "app/utils/tests/flushPromiseQueue" import { renderWithWrappersLEGACY } from "app/utils/tests/renderWithWrappers" import { resolveMostRecentRelayOperation } from "app/utils/tests/resolveMostRecentRelayOperation" import { graphql, QueryRenderer } from "react-relay" -import { act } from "react-test-renderer" import { useTracking } from "react-tracking" import { createMockEnvironment } from "relay-test-utils" @@ -40,7 +39,7 @@ describe("ArtistInsights", () => { if (!props?.artist) { return null } - return + return }} /> ) @@ -48,23 +47,18 @@ describe("ArtistInsights", () => { it("renders list auction results", async () => { const view = renderWithWrappersLEGACY() - await act(async () => { - mockEnvironment.mock.resolveMostRecentOperation(() => ({ - data: { - artist: { - internalID: "artist-id", - slug: "artist-slug", - statuses: { auctionLots: true }, - }, - }, - })) - await flushPromiseQueue() + resolveMostRecentRelayOperation(mockEnvironment, { + Artist: () => ({ + internalID: "artist-id", + slug: "artist-slug", + statuses: { auctionLots: true }, + }), }) - resolveMostRecentRelayOperation(mockEnvironment) + await flushPromiseQueue() // now safe to assert - const auctionResults = await view.root.findAllByType( + const auctionResults = view.root.findAllByType( ArtistInsightsAuctionResultsPaginationContainer ) expect(auctionResults.length).toEqual(1) diff --git a/src/app/Components/ArtsyWebView.tsx b/src/app/Components/ArtsyWebView.tsx index 58e194fa650..441712f32c1 100644 --- a/src/app/Components/ArtsyWebView.tsx +++ b/src/app/Components/ArtsyWebView.tsx @@ -344,7 +344,8 @@ export const ArtsyWebView = forwardRef< // sharedCookiesEnabled is required on iOS for the user to be implicitly logged into force/prediction // on android it works without it sharedCookiesEnabled - decelerationRate="normal" + // See HACKS.md for more details + decelerationRate={Platform.OS === "android" ? 0.985 : "normal"} source={{ uri, headers: { diff --git a/src/app/Components/ArtworkCard/ArtworkCardBottomSheetTabs.tsx b/src/app/Components/ArtworkCard/ArtworkCardBottomSheetTabs.tsx index aacfa38eb0d..0db227e0146 100644 --- a/src/app/Components/ArtworkCard/ArtworkCardBottomSheetTabs.tsx +++ b/src/app/Components/ArtworkCard/ArtworkCardBottomSheetTabs.tsx @@ -16,7 +16,7 @@ interface ArtworkCardBottomSheetTabsProps { onTabChange: TabsContainerProps["onTabChange"] } -const TABS = [ +export const TABS = [ { name: "About the work", analyticsName: ContextModule.infiniteDiscoveryArtworkAboutTab, diff --git a/src/app/Components/ArtworkGrids/ArtworkGridItem.tsx b/src/app/Components/ArtworkGrids/ArtworkGridItem.tsx index 7749794eea4..655747cbe41 100644 --- a/src/app/Components/ArtworkGrids/ArtworkGridItem.tsx +++ b/src/app/Components/ArtworkGrids/ArtworkGridItem.tsx @@ -75,7 +75,6 @@ export interface ArtworkProps extends ArtworkActionTrackingProps { showLotLabel?: boolean titleTextStyle?: TextProps trackTap?: (artworkSlug: string, index?: number) => void - trackingFlow?: string /** allows for artwork to be added to recent searches */ updateRecentSearchesOnTap?: boolean hideCreateAlertOnArtworkPreview?: boolean @@ -369,15 +368,17 @@ export const Artwork: React.FC = memo( )} {!hidePartner && !!artwork.partner?.name && ( - - {artwork.partner.name} - + + + {artwork.partner.name} + + )} {!!displayPriceOfferMessage && ( diff --git a/src/app/Components/ArtworkGrids/MasonryArtworkGridItem.tsx b/src/app/Components/ArtworkGrids/MasonryArtworkGridItem.tsx index 2f98af3b124..7313b68e66e 100644 --- a/src/app/Components/ArtworkGrids/MasonryArtworkGridItem.tsx +++ b/src/app/Components/ArtworkGrids/MasonryArtworkGridItem.tsx @@ -23,8 +23,8 @@ interface Artwork { } interface MasonryArtworkGridItemProps extends Omit { + fullWidth?: boolean artworkMetaStyle?: ViewProps["style"] - columnIndex: number contextModule?: ContextModule contextScreen?: ScreenOwnerType contextScreenOwnerId?: string @@ -41,8 +41,8 @@ interface MasonryArtworkGridItemProps extends Omit { } export const MasonryArtworkGridItem: React.FC = ({ + fullWidth = false, artworkMetaStyle = {}, - columnIndex, contextModule, contextScreen, contextScreenOwnerId, @@ -65,7 +65,15 @@ export const MasonryArtworkGridItem: React.FC = ({ const imgHeight = imgWidth / imgAspectRatio return ( - + , - "renderItem" | "data" -> +type MasonryFlashListOmittedProps = Omit, "renderItem" | "data"> interface MasonryInfiniteScrollArtworkGridProps extends MasonryFlashListOmittedProps { animated?: boolean + artistNamesTextStyle?: TextProps artworks: MasonryArtworkItem[] contextModule?: ContextModule contextScreen?: ScreenOwnerType @@ -35,10 +31,10 @@ interface MasonryInfiniteScrollArtworkGridProps extends MasonryFlashListOmittedP hideCreateAlertOnArtworkPreview?: boolean hideCuratorsPick?: boolean hideIncreasedInterest?: boolean - hideViewFollowsLink?: boolean hidePartner?: boolean hideSaleInfo?: boolean hideSaveIcon?: boolean + hideViewFollowsLink?: boolean isLoading?: boolean loadMore?: (pageSize: number) => void onPress?: (artworkID: string) => void @@ -59,6 +55,7 @@ interface MasonryInfiniteScrollArtworkGridProps extends MasonryFlashListOmittedP export const MasonryInfiniteScrollArtworkGrid: React.FC = ({ animated = false, + artistNamesTextStyle, artworks, contextModule, contextScreen, @@ -76,19 +73,19 @@ export const MasonryInfiniteScrollArtworkGrid: React.FC { const space = useSpace() @@ -101,12 +98,11 @@ export const MasonryInfiniteScrollArtworkGrid: React.FC ( + const renderItem: ListRenderItem = useCallback( + ({ item, index }) => ( ), [ @@ -143,12 +139,13 @@ export const MasonryInfiniteScrollArtworkGrid: React.FC { return rest.numColumns ?? NUM_COLUMNS_MASONRY @@ -174,10 +170,19 @@ export const MasonryInfiniteScrollArtworkGrid: React.FC, "numColumns" | "data" | "renderItem"> - }, [shouldDisplayHeader, ListHeaderComponent, ListEmptyComponent, refreshControl, rest.onScroll]) + }, [ + shouldDisplayHeader, + ListHeaderComponent, + ListEmptyComponent, + refreshControl, + scrollEnabled, + rest.onScroll, + ]) if (artworks.length === 0) { return ( @@ -197,7 +202,7 @@ export const MasonryInfiniteScrollArtworkGrid: React.FC item.id} numColumns={getAdjustedNumColumns()} renderItem={renderItem} @@ -206,11 +211,10 @@ export const MasonryInfiniteScrollArtworkGrid: React.FC ) : null } - estimatedItemSize={ESTIMATED_MASONRY_ITEM_SIZE} onEndReached={onEndReached} contentContainerStyle={{ // No paddings are needed for single column grids - paddingHorizontal: getAdjustedNumColumns() === 1 ? 0 : space(2), + paddingHorizontal: getAdjustedNumColumns() === 1 ? 0 : space(1), }} onViewableItemsChanged={onViewableItemsChanged} viewabilityConfig={viewabilityConfig} @@ -235,5 +239,5 @@ const Footer: FC<{ } const AnimatedMasonryFlashList = Animated.createAnimatedComponent( - MasonryFlashList -) as unknown as typeof MasonryFlashList + FlashList +) as unknown as typeof FlashList diff --git a/src/app/Components/ArtworkLists/components/ArtworkLists.tsx b/src/app/Components/ArtworkLists/components/ArtworkLists.tsx index 1dc13934376..6f5d81dcac7 100644 --- a/src/app/Components/ArtworkLists/components/ArtworkLists.tsx +++ b/src/app/Components/ArtworkLists/components/ArtworkLists.tsx @@ -132,8 +132,8 @@ export const ArtworkLists: FC = (props) => { return ( item.internalID} - renderItem={({ item }) => { + keyExtractor={(item: ArtworkList) => item.internalID} + renderItem={({ item }: { item: ArtworkList }) => { return ( = memo( onPress, onEndReached, onEndReachedThreshold, - ListHeaderComponent = , + ListHeaderComponent = , ListFooterComponent = , hideArtistName = false, listRef, @@ -108,9 +107,6 @@ export const ArtworkRail: React.FC = memo( item.internalID} ListFooterComponent={listFooterComponent} ListHeaderComponent={ListHeaderComponent} diff --git a/src/app/Components/ArtworkRail/ArtworkRailCard.tsx b/src/app/Components/ArtworkRail/ArtworkRailCard.tsx index c623263c9a3..b087d1a633b 100644 --- a/src/app/Components/ArtworkRail/ArtworkRailCard.tsx +++ b/src/app/Components/ArtworkRail/ArtworkRailCard.tsx @@ -1,8 +1,7 @@ -import { Box, Flex, Spacer, useSpace } from "@artsy/palette-mobile" +import { Box, Flex, Spacer } from "@artsy/palette-mobile" import { ArtworkRailCard_artwork$key } from "__generated__/ArtworkRailCard_artwork.graphql" import { CreateArtworkAlertModal } from "app/Components/Artist/ArtistArtworks/CreateArtworkAlertModal" import { - ARTWORK_RAIL_CARD_IMAGE_HEIGHT, ARTWORK_RAIL_CARD_MAX_WIDTH, ARTWORK_RAIL_CARD_MIN_WIDTH, ArtworkRailCardImage, @@ -56,7 +55,6 @@ export const ArtworkRailCard: React.FC = memo( const isIOS = Platform.OS === "ios" const { trackEvent } = useTracking() - const space = useSpace() const [showCreateArtworkAlertModal, setShowCreateArtworkAlertModal] = useState(false) const disappearableRef = useRef(null) @@ -76,7 +74,7 @@ export const ArtworkRailCard: React.FC = memo( contextScreenOwnerSlug={contextScreenOwnerSlug} contextScreenOwnerType={contextScreenOwnerType} > - + = memo( }} > - + {modalTitle ?? title} diff --git a/src/app/Components/CardRail/CardRailFlatList.tsx b/src/app/Components/CardRail/CardRailFlatList.tsx index 2293626da58..f2c06975cb9 100644 --- a/src/app/Components/CardRail/CardRailFlatList.tsx +++ b/src/app/Components/CardRail/CardRailFlatList.tsx @@ -8,15 +8,12 @@ import { Spacer, useSpace, } from "@artsy/palette-mobile" -import { - AboveTheFoldFlatList, - AboveTheFoldFlatListProps, -} from "app/Components/AboveTheFoldFlatList" +import { AboveTheFoldFlatListProps } from "app/Components/AboveTheFoldFlatList" import { CardRailCard, CardRailMetadataContainer } from "app/Components/CardRail/CardRailCard" import { LARGE_IMAGE_SIZE, SMALL_IMAGE_SIZE } from "app/Components/MultipleImageLayout" import Spinner from "app/Components/Spinner" import { Ref } from "react" -import { FlatListProps, View } from "react-native" +import { FlatList, FlatListProps, View } from "react-native" type CardRailFlatList = AboveTheFoldFlatListProps @@ -27,7 +24,7 @@ export function CardRailFlatList( const space = useSpace() return ( - + ListHeaderComponent={() => } ListFooterComponent={() => } ItemSeparatorComponent={() => } diff --git a/src/app/Components/ContextMenu/ContextMenuArtwork.tsx b/src/app/Components/ContextMenu/ContextMenuArtwork.tsx index bba24d321db..956942545e7 100644 --- a/src/app/Components/ContextMenu/ContextMenuArtwork.tsx +++ b/src/app/Components/ContextMenu/ContextMenuArtwork.tsx @@ -1,5 +1,14 @@ import { ActionType, ContextModule, LongPressedArtwork, ScreenOwnerType } from "@artsy/cohesion" -import { Box, Flex, Join, Separator, Text, Touchable, useColor } from "@artsy/palette-mobile" +import { + Box, + Flex, + Join, + Separator, + Text, + Touchable, + useColor, + useSpace, +} from "@artsy/palette-mobile" import { ContextMenuArtworkPreviewCard_artwork$key } from "__generated__/ContextMenuArtworkPreviewCard_artwork.graphql" import { ContextMenuArtwork_artwork$key } from "__generated__/ContextMenuArtwork_artwork.graphql" import { ArtworkRailCardProps } from "app/Components/ArtworkRail/ArtworkRailCard" @@ -14,14 +23,16 @@ import { useDislikeArtwork } from "app/utils/mutations/useDislikeArtwork" import { Schema } from "app/utils/track" import { useState } from "react" import { InteractionManager, Platform } from "react-native" -import ContextMenu, { ContextMenuAction, ContextMenuProps } from "react-native-context-menu-view" import { TouchableHighlight } from "react-native-gesture-handler" import { HapticFeedbackTypes, trigger } from "react-native-haptic-feedback" import { SafeAreaView } from "react-native-safe-area-context" import { graphql, useFragment } from "react-relay" import { useTracking } from "react-tracking" +import * as ContextMenu from "zeego/context-menu" -interface ContextAction extends Omit { +interface ContextAction { + title: string + systemIcon: string onPress?: () => void } @@ -175,14 +186,11 @@ export const ContextMenuArtwork: React.FC { + const handleItemPress = (onPress?: () => void) => { if (haptic) { trigger?.(haptic === true ? "impactLight" : haptic) } - - const onPressToCall = contextActions[event.nativeEvent.index].onPress - - onPressToCall?.() + onPress?.() } const artworkPreviewComponent = ( @@ -194,20 +202,39 @@ export const ContextMenuArtwork: React.FC - {children} - + + {children} + + + + {() => artworkPreviewComponent(artwork, artworkDisplayProps)} + + + {contextActions.map((action, index) => ( + handleItemPress(action.onPress)} + > + + {action.title} + + ))} + + ) } @@ -232,37 +259,40 @@ export const ContextMenuArtwork: React.FC {children} setAndroidVisible(false)}> - - + + {/* Always show light mode on Android for the bottom sheet */} {artworkPreviewComponent(artwork, { ...artworkDisplayProps, dark: false })} - }> - {contextActions.map((action, index) => { - return ( - { - setAndroidVisible(false) - - action.onPress?.() - }} - > - - {action.title} - - - ) - })} - + + }> + {contextActions.map((action, index) => { + return ( + { + setAndroidVisible(false) + + action.onPress?.() + }} + > + + {action.title} + + + ) + })} + + diff --git a/src/app/Components/ContextMenu/ContextMenuArtworkPreviewCard.tsx b/src/app/Components/ContextMenu/ContextMenuArtworkPreviewCard.tsx index 6ca9173ab47..3b81393ce43 100644 --- a/src/app/Components/ContextMenu/ContextMenuArtworkPreviewCard.tsx +++ b/src/app/Components/ContextMenu/ContextMenuArtworkPreviewCard.tsx @@ -53,8 +53,14 @@ export const ContextMenuArtworkPreviewCard: React.FC + { - const showing = useSharedValue(0) + const animatedValue = useRef(new Animated.Value(0)).current useEffect(() => { - showing.value = withDelay( + Animated.timing(animatedValue, { + toValue: 1, + duration, delay, - withTiming(1, { - duration, - }) - ) - }, []) + useNativeDriver: true, + }).start() + }, [animatedValue, delay, duration]) - const animatedStyle = useAnimatedStyle(() => { - return { - transform: [{ translateY: slide ? interpolate(showing.get(), [0, 1], [10, 0]) : 0 }], - opacity: showing.get(), - } - }) + const translateY = slide + ? animatedValue.interpolate({ + inputRange: [0, 1], + outputRange: [10, 0], + }) + : 0 - return {children} + return ( + + {children} + + ) } diff --git a/src/app/Components/Gene/GeneArtworks.tsx b/src/app/Components/Gene/GeneArtworks.tsx index f4aeee90953..d3db79b3845 100644 --- a/src/app/Components/Gene/GeneArtworks.tsx +++ b/src/app/Components/Gene/GeneArtworks.tsx @@ -8,7 +8,7 @@ import { useScreenDimensions, useSpace, } from "@artsy/palette-mobile" -import { MasonryListRenderItem } from "@shopify/flash-list" +import { ListRenderItem } from "@shopify/flash-list" import { GeneArtworks_gene$data } from "__generated__/GeneArtworks_gene.graphql" import { ArtworkFilterNavigator, FilterModalMode } from "app/Components/ArtworkFilter" import { useArtworkFilters } from "app/Components/ArtworkFilter/useArtworkFilters" @@ -17,7 +17,6 @@ import { FilteredArtworkGridZeroState } from "app/Components/ArtworkGrids/Filter import { GeneArtworksFilterHeader } from "app/Components/Gene/GeneArtworksFilterHeader" import { extractNodes } from "app/utils/extractNodes" import { - ESTIMATED_MASONRY_ITEM_SIZE, MASONRY_LIST_PAGE_SIZE, NUM_COLUMNS_MASONRY, ON_END_REACHED_THRESHOLD_MASONRY, @@ -85,25 +84,19 @@ export const GeneArtworksContainer: React.FC = ({ ge } }, [relay.hasMore(), relay.isLoading()]) - const renderItem: MasonryListRenderItem = useCallback(({ item, columnIndex }) => { + const renderItem: ListRenderItem = useCallback(({ item }) => { const imgAspectRatio = item.image?.aspectRatio ?? 1 const imgWidth = width / NUM_COLUMNS_MASONRY - space(2) - space(1) const imgHeight = imgWidth / imgAspectRatio return ( - - - + ) }, []) @@ -112,7 +105,6 @@ export const GeneArtworksContainer: React.FC = ({ ge = ({ ge // need to pass zIndex: 1 here in order for the SubTabBar to // be visible above list content ListHeaderComponentStyle={{ zIndex: 1 }} + contentContainerStyle={{ paddingHorizontal: space(1) }} ListHeaderComponent={ - <> + @@ -147,7 +140,7 @@ export const GeneArtworksContainer: React.FC = ({ ge {`Showing ${artworksTotal} work${artworksTotal > 1 ? "s" : ""}`} - + } /> { - style?: StyleProp> +interface HeaderButtonProps extends AnimatedProps { + style?: StyleProp> shouldHide?: boolean position: "left" | "right" applySafeAreaTopInsets?: boolean diff --git a/src/app/Components/InfiniteScrollFlashList.tsx b/src/app/Components/InfiniteScrollFlashList.tsx index b9cdcdb97c5..6750ed9d77d 100644 --- a/src/app/Components/InfiniteScrollFlashList.tsx +++ b/src/app/Components/InfiniteScrollFlashList.tsx @@ -7,8 +7,6 @@ export type InfiniteScrollFlashListProps = { initialNumToRender?: number } & FlashListProps -const ESTIMATED_ITEM_SIZE = 60 - export function InfiniteScrollFlashList(props: InfiniteScrollFlashListProps) { const { listRef, onScrollBeginDrag, ...restProps } = props @@ -17,7 +15,6 @@ export function InfiniteScrollFlashList(props: InfiniteScrollFlashList {...restProps} ref={listRef} - estimatedItemSize={ESTIMATED_ITEM_SIZE} onScrollBeginDrag={(event) => { if (onScrollBeginDrag) { onScrollBeginDrag(event) diff --git a/src/app/Components/ShareSheet/ShareSheet.tsx b/src/app/Components/ShareSheet/ShareSheet.tsx index 68595fd8dc8..2aa5760f403 100644 --- a/src/app/Components/ShareSheet/ShareSheet.tsx +++ b/src/app/Components/ShareSheet/ShareSheet.tsx @@ -189,7 +189,7 @@ export const ShareSheet = () => { diff --git a/src/app/Components/SwitchMenu.tsx b/src/app/Components/SwitchMenu.tsx index 4a3cb8f0ff9..0c2e8bf3cf4 100644 --- a/src/app/Components/SwitchMenu.tsx +++ b/src/app/Components/SwitchMenu.tsx @@ -29,7 +29,9 @@ export const SwitchMenu = ({ - + + + ) diff --git a/src/app/Components/WorksForYou/Notification.tsx b/src/app/Components/WorksForYou/Notification.tsx index 90e08f13da7..b6229817d12 100644 --- a/src/app/Components/WorksForYou/Notification.tsx +++ b/src/app/Components/WorksForYou/Notification.tsx @@ -1,18 +1,11 @@ -import { Text } from "@artsy/palette-mobile" +import { Flex, Text } from "@artsy/palette-mobile" import { Notification_notification$data } from "__generated__/Notification_notification.graphql" import GenericGrid from "app/Components/ArtworkGrids/GenericGrid" import { ThemeAwareClassTheme } from "app/Components/DarkModeClassTheme" import { navigate } from "app/system/navigation/navigate" import { extractNodes } from "app/utils/extractNodes" import React from "react" -import { - Image, - ImageStyle, - StyleSheet, - TouchableWithoutFeedback, - View, - ViewStyle, -} from "react-native" +import { Image, StyleSheet, TouchableWithoutFeedback, View } from "react-native" import { createFragmentContainer, graphql } from "react-relay" interface Props { @@ -65,9 +58,9 @@ export class Notification extends React.Component { - + - + )} @@ -75,15 +68,7 @@ export class Notification extends React.Component { } } -interface Styles { - container: ViewStyle - header: ViewStyle - artistAvatar: ImageStyle - metadataContainer: ViewStyle - gridContainer: ViewStyle -} - -const styles = StyleSheet.create({ +const styles = StyleSheet.create({ container: { marginTop: 20, marginHorizontal: HORIZONTAL_PADDING, @@ -102,10 +87,6 @@ const styles = StyleSheet.create({ alignSelf: "center", flex: 1, }, - gridContainer: { - marginTop: 20, - marginBottom: 20, - }, }) export default createFragmentContainer(Notification, { diff --git a/src/app/Components/WorksForYouArtworks.tsx b/src/app/Components/WorksForYouArtworks.tsx index d5dced15dbf..07e7f86c718 100644 --- a/src/app/Components/WorksForYouArtworks.tsx +++ b/src/app/Components/WorksForYouArtworks.tsx @@ -43,7 +43,6 @@ export const WorksForYouArtworks: React.FC = ({ viewer }) = loadMore={loadNext} hasMore={hasNext} numColumns={numColumns} - disableAutoLayout pageSize={PAGE_SIZE} contextModule={ContextModule.newWorksForYouRail} contextScreenOwnerType={OwnerType.newWorksForYou} diff --git a/src/app/Navigation/AuthenticatedRoutes/Tabs.tsx b/src/app/Navigation/AuthenticatedRoutes/Tabs.tsx index 2af8aa28727..1fddfcc9fdd 100644 --- a/src/app/Navigation/AuthenticatedRoutes/Tabs.tsx +++ b/src/app/Navigation/AuthenticatedRoutes/Tabs.tsx @@ -98,7 +98,7 @@ const AppTabs: React.FC = () => { currentRoute && modules[currentRoute as AppModule]?.options?.hidesBottomTabs return { - animation: "fade", + animation: "none", headerShown: false, tabBarStyle: { animate: true, diff --git a/src/app/Navigation/routes.tsx b/src/app/Navigation/routes.tsx index 4741f3f6a0d..4af2d331d8b 100644 --- a/src/app/Navigation/routes.tsx +++ b/src/app/Navigation/routes.tsx @@ -827,7 +827,6 @@ export const artsyDotNetRoutes = defineRoutes([ alwaysPresentModally: true, screenOptions: { headerTitle: "Dev Settings", - headerLargeTitle: true, headerLeft: () => { return }, diff --git a/src/app/Scenes/Activity/components/NotificationArtworkList.tsx b/src/app/Scenes/Activity/components/NotificationArtworkList.tsx index 9850f3c978b..a233c8da90d 100644 --- a/src/app/Scenes/Activity/components/NotificationArtworkList.tsx +++ b/src/app/Scenes/Activity/components/NotificationArtworkList.tsx @@ -32,7 +32,6 @@ export const NotificationArtworkList: FC = ({ animated artworks={artworks} numColumns={1} - disableAutoLayout contextScreenOwnerType={OwnerType.activity} contextScreen={OwnerType.activity} hasMore={false} diff --git a/src/app/Scenes/ArtQuiz/ArtQuizResults/ArtQuizResultsTabs/ArtQuizExploreArtists.tsx b/src/app/Scenes/ArtQuiz/ArtQuizResults/ArtQuizResultsTabs/ArtQuizExploreArtists.tsx index a614cc19caa..eecdb33e81f 100644 --- a/src/app/Scenes/ArtQuiz/ArtQuizResults/ArtQuizResultsTabs/ArtQuizExploreArtists.tsx +++ b/src/app/Scenes/ArtQuiz/ArtQuizResults/ArtQuizResultsTabs/ArtQuizExploreArtists.tsx @@ -16,10 +16,9 @@ export const ArtQuizExploreArtists = ({ ) return ( - { return }} diff --git a/src/app/Scenes/ArtQuiz/ArtQuizResults/ArtQuizResultsTabs/ArtQuizExploreArtworks.tsx b/src/app/Scenes/ArtQuiz/ArtQuizResults/ArtQuizResultsTabs/ArtQuizExploreArtworks.tsx index 7140c6e047f..35b611f75f5 100644 --- a/src/app/Scenes/ArtQuiz/ArtQuizResults/ArtQuizResultsTabs/ArtQuizExploreArtworks.tsx +++ b/src/app/Scenes/ArtQuiz/ArtQuizResults/ArtQuizResultsTabs/ArtQuizExploreArtworks.tsx @@ -1,4 +1,4 @@ -import { Tabs, Text, useSpace } from "@artsy/palette-mobile" +import { Flex, Tabs, Text, useSpace } from "@artsy/palette-mobile" import { ArtQuizExploreArtworksFragment_artwork$key } from "__generated__/ArtQuizExploreArtworksFragment_artwork.graphql" import { ArtQuizResultsTabs_me$data } from "__generated__/ArtQuizResultsTabs_me.graphql" import GenericGrid from "app/Components/ArtworkGrids/GenericGrid" @@ -22,7 +22,7 @@ export const ArtQuizExploreArtworks = ({ contentContainerStyle={{ marginVertical: space(2), paddingBottom: space(4), - paddingHorizontal: space(1), + paddingHorizontal: space(2), }} > {artworks.length ? ( @@ -33,9 +33,11 @@ export const ArtQuizExploreArtworks = ({ saleInfoTextStyle={{ weight: "medium", color: "mono100" }} /> ) : ( - - We don't have any recommendations for you at this time. - + + + We don't have any recommendations for you at this time. + + )} ) diff --git a/src/app/Scenes/ArtQuiz/ArtQuizResults/ArtQuizResultsTabs/ArtQuizLikedArtworks.tsx b/src/app/Scenes/ArtQuiz/ArtQuizResults/ArtQuizResultsTabs/ArtQuizLikedArtworks.tsx index 99f56e6de7d..ad22a793e3c 100644 --- a/src/app/Scenes/ArtQuiz/ArtQuizResults/ArtQuizResultsTabs/ArtQuizLikedArtworks.tsx +++ b/src/app/Scenes/ArtQuiz/ArtQuizResults/ArtQuizResultsTabs/ArtQuizLikedArtworks.tsx @@ -20,7 +20,8 @@ export const ArtQuizLikedArtworks = ({ ("worksYouLiked") - const savedArtworks = queryResult?.savedArtworks! - const recommendedArtworks = queryResult?.recommendedArtworks! + const savedArtworks = queryResult?.savedArtworks ?? [] + const recommendedArtworks = queryResult?.recommendedArtworks ?? [] const title = activeTab === "worksYouLiked" ? "Explore Your Quiz Results" : "Explore Art We Think You'll Love" diff --git a/src/app/Scenes/ArtQuiz/ArtQuizResults/ArtQuizResultsTabs/ArtQuizTrendingArtists.tsx b/src/app/Scenes/ArtQuiz/ArtQuizResults/ArtQuizResultsTabs/ArtQuizTrendingArtists.tsx index 60fee32d685..284277318f5 100644 --- a/src/app/Scenes/ArtQuiz/ArtQuizResults/ArtQuizResultsTabs/ArtQuizTrendingArtists.tsx +++ b/src/app/Scenes/ArtQuiz/ArtQuizResults/ArtQuizResultsTabs/ArtQuizTrendingArtists.tsx @@ -19,9 +19,8 @@ export const ArtQuizTrendingArtists = ({ const artists = extractNodes(viewerData?.curatedTrendingArtists) return ( - String(item?.internalID || index)} renderItem={({ item, index }) => { return diff --git a/src/app/Scenes/ArtQuiz/ArtQuizResults/ArtQuizResultsTabs/ArtQuizTrendingCollections.tsx b/src/app/Scenes/ArtQuiz/ArtQuizResults/ArtQuizResultsTabs/ArtQuizTrendingCollections.tsx index 5aeadf66c93..d7ea5bedc1b 100644 --- a/src/app/Scenes/ArtQuiz/ArtQuizResults/ArtQuizResultsTabs/ArtQuizTrendingCollections.tsx +++ b/src/app/Scenes/ArtQuiz/ArtQuizResults/ArtQuizResultsTabs/ArtQuizTrendingCollections.tsx @@ -18,9 +18,8 @@ export const ArtQuizTrendingCollections: React.FC String(item?.internalID || index)} renderItem={({ item, index }) => { return diff --git a/src/app/Scenes/ArticleSlideShow/Components/ArticleSlideShow.tsx b/src/app/Scenes/ArticleSlideShow/Components/ArticleSlideShow.tsx index e3f67e97d97..800e8b5e755 100644 --- a/src/app/Scenes/ArticleSlideShow/Components/ArticleSlideShow.tsx +++ b/src/app/Scenes/ArticleSlideShow/Components/ArticleSlideShow.tsx @@ -86,7 +86,6 @@ export const ArticleSlideShow: React.FC = ({ article, cov horizontal keyExtractor={({ id }) => `ArticleSlideShowItem-${id}`} snapToInterval={width} - estimatedItemSize={width} pagingEnabled initialScrollIndex={currentIndex} viewabilityConfig={{ diff --git a/src/app/Scenes/Artist/Artist.tsx b/src/app/Scenes/Artist/Artist.tsx index 987a77934bc..0ca48bda76d 100644 --- a/src/app/Scenes/Artist/Artist.tsx +++ b/src/app/Scenes/Artist/Artist.tsx @@ -12,11 +12,17 @@ import { useRoute } from "@react-navigation/native" import { ArtistAboveTheFoldQuery } from "__generated__/ArtistAboveTheFoldQuery.graphql" import { FilterArtworksInput } from "__generated__/ArtistArtworks_artistRefetch.graphql" import { ArtistBelowTheFoldQuery } from "__generated__/ArtistBelowTheFoldQuery.graphql" -import { ArtistAboutContainer } from "app/Components/Artist/ArtistAbout/ArtistAbout" +import { + artistAboutQuery, + ArtistAboutQueryRenderer, +} from "app/Components/Artist/ArtistAbout/ArtistAbout" import { ArtistArtworksQueryRenderer } from "app/Components/Artist/ArtistArtworks/ArtistArtworks" import { ArtistHeader, useArtistHeaderImageDimensions } from "app/Components/Artist/ArtistHeader" import { ArtistHeaderNavRightQueryRenderer } from "app/Components/Artist/ArtistHeaderNavRight" -import { ArtistInsightsFragmentContainer } from "app/Components/Artist/ArtistInsights/ArtistInsights" +import { + artistInsightsQuery, + ArtistInsightsQueryRenderer, +} from "app/Components/Artist/ArtistInsights/ArtistInsights" import { FilterArray, filterArtworksParams, @@ -36,9 +42,9 @@ import { goBack } from "app/system/navigation/navigate" import { getRelayEnvironment } from "app/system/relay/defaultEnvironment" import { AboveTheFoldQueryRenderer } from "app/utils/AboveTheFoldQueryRenderer" import { KeyboardAvoidingContainer } from "app/utils/keyboard/KeyboardAvoidingContainer" +import { prefetchQuery } from "app/utils/queryPrefetching" import { ProvideScreenTracking, Schema } from "app/utils/track" import React, { useCallback, useEffect, useMemo } from "react" -import { ActivityIndicator, View } from "react-native" import { Environment, graphql } from "react-relay" const INITIAL_TAB = "Artworks" @@ -52,7 +58,6 @@ interface RouteParams { interface ArtistProps { artistAboveTheFold: NonNullable - artistBelowTheFold?: ArtistBelowTheFoldQuery["response"]["artist"] auctionResultsInitialFilters?: FilterArray environment?: Environment fetchCriteriaError: Error | null @@ -65,7 +70,6 @@ interface ArtistProps { export const Artist: React.FC = ({ artistAboveTheFold, - artistBelowTheFold, auctionResultsInitialFilters, fetchCriteriaError, initialTab = INITIAL_TAB, @@ -87,6 +91,18 @@ export const Artist: React.FC = ({ } }, [fetchCriteriaError]) + // Prefetch the About and Insights tab queries on mount + useEffect(() => { + prefetchQuery({ + query: artistAboutQuery, + variables: { artistID: artistAboveTheFold.internalID }, + }) + prefetchQuery({ + query: artistInsightsQuery, + variables: { artistID: artistAboveTheFold.internalID }, + }) + }, [artistAboveTheFold.internalID]) + const renderBelowTheHeaderComponent = useCallback( () => , [artistAboveTheFold] @@ -111,6 +127,7 @@ export const Artist: React.FC = ({ disableKeyboardAvoidance initialTabName={initialTab} title={artistAboveTheFold.name ?? ""} + allowHeaderOverscroll showLargeHeaderText={false} BelowTitleHeaderComponent={renderBelowTheHeaderComponent} headerProps={{ @@ -132,24 +149,16 @@ export const Artist: React.FC = ({ - {artistBelowTheFold ? ( - - ) : ( - - )} + - {artistBelowTheFold ? ( - - ) : ( - - )} + @@ -256,8 +265,9 @@ export const ArtistQueryRenderer: React.FC = ({ query: graphql` query ArtistBelowTheFoldQuery($artistID: String!) @cacheable { artist(id: $artistID) { - ...ArtistAbout_artist - ...ArtistInsights_artist + # Below-the-fold tabs (Insights, About) now have their own query renderers + # This query is kept minimal for backward compatibility + id } } `, @@ -270,14 +280,13 @@ export const ArtistQueryRenderer: React.FC = ({ renderPlaceholder: () => ( ), - renderComponent: ({ above, below }) => { + renderComponent: ({ above }) => { if (!above.artist) { throw new Error("no artist data") } return ( = ({ ) } -/** - * Be lazy and just have a simple loading spinner for the below-the-fold tabs - * (as opposed to nice fancy placeholder screens) since people are really - * unlikely to tap into them quick enough to see the loading state - * @param param0 - */ -const LoadingPage: React.FC<{}> = ({}) => { - return ( - - - - ) -} - const ArtistSkeleton: React.FC<{ verifiedRepresentativesCount?: number }> = ({ verifiedRepresentativesCount = 0, }) => { diff --git a/src/app/Scenes/Artist/__tests__/Artist.tests.tsx b/src/app/Scenes/Artist/__tests__/Artist.tests.tsx index 2dab21c8fe1..0495ba5b470 100644 --- a/src/app/Scenes/Artist/__tests__/Artist.tests.tsx +++ b/src/app/Scenes/Artist/__tests__/Artist.tests.tsx @@ -10,11 +10,17 @@ import { MockResolvers } from "relay-test-utils/lib/RelayMockPayloadGenerator" jest.unmock("react-tracking") +jest.mock("app/utils/queryPrefetching", () => ({ + usePrefetch: jest.fn(() => jest.fn()), + prefetchQuery: jest.fn(), +})) + type ArtistQueries = | "SearchCriteriaQuery" | "ArtistAboveTheFoldQuery" | "ArtistBelowTheFoldQuery" | "MarketStatsQuery" + | "ArtistAboutQuery" describe("Artist", () => { let mockEnvironment: ReturnType @@ -58,7 +64,7 @@ describe("Artist", () => { return { entities: ["test"] } }, }) - mockMostRecentOperation("MarketStatsQuery") + mockMostRecentOperation("ArtistAboutQuery") await flushPromiseQueue() diff --git a/src/app/Scenes/Artist/__tests__/ArtistSavedSearch.tests.tsx b/src/app/Scenes/Artist/__tests__/ArtistSavedSearch.tests.tsx index 5aaa3ffed34..5cfc9e98538 100644 --- a/src/app/Scenes/Artist/__tests__/ArtistSavedSearch.tests.tsx +++ b/src/app/Scenes/Artist/__tests__/ArtistSavedSearch.tests.tsx @@ -9,6 +9,11 @@ import { MockResolvers } from "relay-test-utils/lib/RelayMockPayloadGenerator" jest.unmock("react-tracking") +jest.mock("app/utils/queryPrefetching", () => ({ + usePrefetch: jest.fn(() => jest.fn()), + prefetchQuery: jest.fn(), +})) + const mockUseIsFocusedMock = jest.fn() const mockAddListener = jest.fn((event, callback) => { @@ -40,6 +45,8 @@ type ArtistQueries = | "ArtistBelowTheFoldQuery" | "SearchCriteriaQuery" | "ArtistArtworksQuery" + | "ArtistAboutQuery" + | "ArtistInsightsQuery" | "MarketStatsQuery" | "ArtistInsightsAuctionResultsQuery" @@ -94,8 +101,10 @@ describe("Saved search banner on artist screen", () => { mockMostRecentOperation("SearchCriteriaQuery", MockSearchCriteriaQuery) mockMostRecentOperation("ArtistAboveTheFoldQuery", MockArtistAboveTheFoldQuery) mockMostRecentOperation("ArtistBelowTheFoldQuery", MockArtistBelowTheFoldQuery) - mockMostRecentOperation("MarketStatsQuery", MockMarketStatsQuery) + mockMostRecentOperation("ArtistAboutQuery") + mockMostRecentOperation("ArtistInsightsQuery") mockMostRecentOperation("ArtistArtworksQuery", MockArtistArtworksQuery) + mockMostRecentOperation("MarketStatsQuery", MockMarketStatsQuery) mockMostRecentOperation("ArtistInsightsAuctionResultsQuery") await flushPromiseQueue() @@ -125,8 +134,10 @@ describe("Saved search banner on artist screen", () => { mockMostRecentOperation("SearchCriteriaQuery", MockSearchCriteriaQuery) mockMostRecentOperation("ArtistAboveTheFoldQuery", MockArtistAboveTheFoldQuery) mockMostRecentOperation("ArtistBelowTheFoldQuery", MockArtistBelowTheFoldQuery) - mockMostRecentOperation("MarketStatsQuery", MockMarketStatsQuery) + mockMostRecentOperation("ArtistAboutQuery") + mockMostRecentOperation("ArtistInsightsQuery") mockMostRecentOperation("ArtistArtworksQuery", MockArtistArtworksQuery) + mockMostRecentOperation("MarketStatsQuery", MockMarketStatsQuery) await flushPromiseQueue() diff --git a/src/app/Scenes/ArtistSeries/ArtistSeriesArtworks.tsx b/src/app/Scenes/ArtistSeries/ArtistSeriesArtworks.tsx index 2988319aec3..ddeb8bcbf97 100644 --- a/src/app/Scenes/ArtistSeries/ArtistSeriesArtworks.tsx +++ b/src/app/Scenes/ArtistSeries/ArtistSeriesArtworks.tsx @@ -1,6 +1,6 @@ import { OwnerType } from "@artsy/cohesion" import { Box, Flex, Tabs, useScreenDimensions, useSpace } from "@artsy/palette-mobile" -import { MasonryFlashListRef, MasonryListRenderItem } from "@shopify/flash-list" +import { FlashListRef, ListRenderItem } from "@shopify/flash-list" import { ArtistSeriesArtworks_artistSeries$data, ArtistSeriesArtworks_artistSeries$key, @@ -12,11 +12,7 @@ import ArtworkGridItem from "app/Components/ArtworkGrids/ArtworkGridItem" import { FilteredArtworkGridZeroState } from "app/Components/ArtworkGrids/FilteredArtworkGridZeroState" import { HeaderArtworksFilterWithTotalArtworks } from "app/Components/HeaderArtworksFilter/HeaderArtworksFilterWithTotalArtworks" import { extractNodes } from "app/utils/extractNodes" -import { - ESTIMATED_MASONRY_ITEM_SIZE, - NUM_COLUMNS_MASONRY, - ON_END_REACHED_THRESHOLD_MASONRY, -} from "app/utils/masonryHelpers" +import { NUM_COLUMNS_MASONRY, ON_END_REACHED_THRESHOLD_MASONRY } from "app/utils/masonryHelpers" import { AnimatedMasonryListFooter } from "app/utils/masonryHelpers/AnimatedMasonryListFooter" import { ExtractNodeType } from "app/utils/relayHelpers" import { Schema } from "app/utils/track" @@ -49,7 +45,7 @@ export const ArtistSeriesArtworks: React.FC = ({ arti [data.artistSeriesArtworks] ) const shouldDisplaySpinner = isLoadingNext && hasNext - const gridRef = useRef>(null) + const gridRef = useRef>(null) const setFiltersCountAction = ArtworksFiltersStore.useStoreActions( (state) => state.setFiltersCountAction ) @@ -96,31 +92,22 @@ export const ArtistSeriesArtworks: React.FC = ({ arti tracking.trackEvent(tracks.clearFilters(id, slug)) } - const renderItem: MasonryListRenderItem = useCallback( - ({ item, index, columnIndex }) => { - const imgAspectRatio = item.image?.aspectRatio ?? 1 - const imgWidth = width / NUM_COLUMNS_MASONRY - space(2) - space(1) - const imgHeight = imgWidth / imgAspectRatio - - return ( - - - - ) - }, - [] - ) + const renderItem: ListRenderItem = useCallback(({ item, index }) => { + const imgAspectRatio = item.image?.aspectRatio ?? 1 + const imgWidth = width / NUM_COLUMNS_MASONRY - space(2) - space(1) + const imgHeight = imgWidth / imgAspectRatio + + return ( + + ) + }, []) return ( <> @@ -128,7 +115,6 @@ export const ArtistSeriesArtworks: React.FC = ({ arti testID="ArtistSeriesArtworksGrid" data={artworksList} numColumns={NUM_COLUMNS_MASONRY} - estimatedItemSize={ESTIMATED_MASONRY_ITEM_SIZE} keyboardShouldPersistTaps="handled" innerRef={gridRef} ListEmptyComponent={ @@ -147,10 +133,13 @@ export const ArtistSeriesArtworks: React.FC = ({ arti // need to pass zIndex: 1 here in order for the SubTabBar to // be visible above list content ListHeaderComponentStyle={{ zIndex: 1 }} + contentContainerStyle={{ paddingHorizontal: space(1) }} ListHeaderComponent={ - - - + + + + + } ListFooterComponent={() => ( diff --git a/src/app/Scenes/Artwork/Components/ArtworkScreenHeaderCreateAlert.tsx b/src/app/Scenes/Artwork/Components/ArtworkScreenHeaderCreateAlert.tsx index d5031b2be58..4f7bec9645f 100644 --- a/src/app/Scenes/Artwork/Components/ArtworkScreenHeaderCreateAlert.tsx +++ b/src/app/Scenes/Artwork/Components/ArtworkScreenHeaderCreateAlert.tsx @@ -1,6 +1,6 @@ import { ContextModule, OwnerType } from "@artsy/cohesion" import { BellStrokeIcon } from "@artsy/icons/native" -import { Button } from "@artsy/palette-mobile" +import { Button, Flex } from "@artsy/palette-mobile" import { ArtworkScreenHeaderCreateAlert_artwork$key } from "__generated__/ArtworkScreenHeaderCreateAlert_artwork.graphql" import { CreateArtworkAlertModal } from "app/Components/Artist/ArtistArtworks/CreateArtworkAlertModal" import { hasBiddingEnded } from "app/Scenes/Artwork/utils/hasBiddingEnded" @@ -44,7 +44,7 @@ export const ArtworkScreenHeaderCreateAlert: React.FC + )} @@ -291,7 +292,7 @@ const SocialLoginButtons: React.FC = () => { accessibilityLabel="Google" > - + diff --git a/src/app/Scenes/Onboarding/Screens/OnboardingQuiz/OnboardingMarketingCollection.tsx b/src/app/Scenes/Onboarding/Screens/OnboardingQuiz/OnboardingMarketingCollection.tsx index 96ad59468d3..6804d7d8641 100644 --- a/src/app/Scenes/Onboarding/Screens/OnboardingQuiz/OnboardingMarketingCollection.tsx +++ b/src/app/Scenes/Onboarding/Screens/OnboardingQuiz/OnboardingMarketingCollection.tsx @@ -58,7 +58,6 @@ const OnboardingMarketingCollection: React.FC null} hasMore={false} numColumns={NUM_COLUMNS_MASONRY} - disableAutoLayout onScroll={scrollHandler} ListHeaderComponent={ <> diff --git a/src/app/Scenes/Partner/Components/PartnerArtwork.tsx b/src/app/Scenes/Partner/Components/PartnerArtwork.tsx index 58e055a7454..a89558f4534 100644 --- a/src/app/Scenes/Partner/Components/PartnerArtwork.tsx +++ b/src/app/Scenes/Partner/Components/PartnerArtwork.tsx @@ -1,6 +1,6 @@ import { OwnerType } from "@artsy/cohesion" import { Box, Flex, Tabs, useScreenDimensions, useSpace } from "@artsy/palette-mobile" -import { MasonryListRenderItem } from "@shopify/flash-list" +import { ListRenderItem } from "@shopify/flash-list" import { PartnerArtwork_partner$data } from "__generated__/PartnerArtwork_partner.graphql" import { ArtworkFilterNavigator, FilterModalMode } from "app/Components/ArtworkFilter" import { @@ -13,7 +13,6 @@ import { TabEmptyState } from "app/Components/TabEmptyState" import { extractNodes } from "app/utils/extractNodes" import { - ESTIMATED_MASONRY_ITEM_SIZE, MASONRY_LIST_PAGE_SIZE, NUM_COLUMNS_MASONRY, ON_END_REACHED_THRESHOLD_MASONRY, @@ -62,38 +61,29 @@ export const PartnerArtwork: React.FC<{ const emptyText = "There are no matching works from this gallery.\nTry changing your search filters" - const renderItem: MasonryListRenderItem = useCallback( - ({ item, columnIndex }) => { - const imgAspectRatio = item.image?.aspectRatio ?? 1 - const imgWidth = width / NUM_COLUMNS_MASONRY - space(2) - space(1) - const imgHeight = imgWidth / imgAspectRatio + const renderItem: ListRenderItem = useCallback(({ item }) => { + const imgAspectRatio = item.image?.aspectRatio ?? 1 + const imgWidth = width / NUM_COLUMNS_MASONRY - space(2) - space(1) + const imgHeight = imgWidth / imgAspectRatio - return ( - - - - ) - }, - [] - ) + return ( + + ) + }, []) return ( <> @@ -110,12 +100,14 @@ export const PartnerArtwork: React.FC<{ // be visible above list content ListHeaderComponentStyle={{ zIndex: 1 }} ListHeaderComponent={ - - setIsFilterArtworksModalVisible(true)} - /> - + + + setIsFilterArtworksModalVisible(true)} + /> + + } /> diff --git a/src/app/Scenes/Partner/Components/PartnerOverviewList.tsx b/src/app/Scenes/Partner/Components/PartnerOverviewList.tsx index ec2d4358b6f..b18091ebb07 100644 --- a/src/app/Scenes/Partner/Components/PartnerOverviewList.tsx +++ b/src/app/Scenes/Partner/Components/PartnerOverviewList.tsx @@ -2,8 +2,8 @@ import { Flex, Spacer, Tabs, Text } from "@artsy/palette-mobile" import { ListRenderItem } from "@shopify/flash-list" import { PartnerOverviewListArtistsQuery } from "__generated__/PartnerOverviewListArtistsQuery.graphql" import { - PartnerOverviewListArtists_partner$key, PartnerOverviewListArtists_partner$data, + PartnerOverviewListArtists_partner$key, } from "__generated__/PartnerOverviewListArtists_partner.graphql" import { ArtistListItemContainer as ArtistListItem } from "app/Components/ArtistListItem" import { ReadMore } from "app/Components/ReadMore" @@ -55,7 +55,6 @@ export const PartnerOverviewList: React.FC = ({ return ( { diff --git a/src/app/Scenes/Partner/Partner.tsx b/src/app/Scenes/Partner/Partner.tsx index af079a9f086..abd098552c1 100644 --- a/src/app/Scenes/Partner/Partner.tsx +++ b/src/app/Scenes/Partner/Partner.tsx @@ -85,21 +85,15 @@ const Partner: React.FC = (props) => { headerProps={{ onBack: goBack }} > - - - + - - - - - + + + - - - + diff --git a/src/app/Scenes/SavedSearchAlert/AlertArtworksGrid.tsx b/src/app/Scenes/SavedSearchAlert/AlertArtworksGrid.tsx index 8fa370ae7cb..6f72f2bcba1 100644 --- a/src/app/Scenes/SavedSearchAlert/AlertArtworksGrid.tsx +++ b/src/app/Scenes/SavedSearchAlert/AlertArtworksGrid.tsx @@ -73,7 +73,9 @@ export const AlertArtworksGrid: FC = ({ alertId, fetchKe {numWorks} currently on Artsy match your criteria. See our top picks for you: - + + + )} {artworksCount === 0 && ( diff --git a/src/app/Scenes/SavedSearchAlert/Components/Form.tsx b/src/app/Scenes/SavedSearchAlert/Components/Form.tsx index 9fd4617fd66..7204b0cd4f4 100644 --- a/src/app/Scenes/SavedSearchAlert/Components/Form.tsx +++ b/src/app/Scenes/SavedSearchAlert/Components/Form.tsx @@ -22,7 +22,6 @@ import { import { navigate } from "app/system/navigation/navigate" import { KeyboardAwareForm } from "app/utils/keyboard/KeyboardAwareForm" import { useFormikContext } from "formik" -import { MotiView } from "moti" import { useCallback, useState } from "react" import { LayoutChangeEvent, Platform, StyleProp, ViewStyle } from "react-native" import { KeyboardStickyView } from "react-native-keyboard-controller" @@ -220,47 +219,45 @@ export const Form: React.FC = ({ - - + + {isEditMode ? "Save Alert" : "Create Alert"} + - {!!isEditMode && ( - <> - - - - )} + {!!isEditMode && ( + <> + + + + )} - {!isEditMode && ( - - Access all your alerts in your profile. - - )} - - + {!isEditMode && ( + + Access all your alerts in your profile. + + )} + ) diff --git a/src/app/Scenes/SavedSearchAlert/screens/ConfirmationScreen.tsx b/src/app/Scenes/SavedSearchAlert/screens/ConfirmationScreen.tsx index cdd71edc444..550de2d19d8 100644 --- a/src/app/Scenes/SavedSearchAlert/screens/ConfirmationScreen.tsx +++ b/src/app/Scenes/SavedSearchAlert/screens/ConfirmationScreen.tsx @@ -216,14 +216,16 @@ const MatchingArtworks: React.FC = ({ artworksConnection, - { - closeModal?.() - trackEvent(tracks.tappedArtworkGroup(slug, artwork?.collectorSignals)) - }} - /> + + { + closeModal?.() + trackEvent(tracks.tappedArtworkGroup(slug, artwork?.collectorSignals)) + }} + /> + diff --git a/src/app/Scenes/Search/SearchArtworksGrid.tsx b/src/app/Scenes/Search/SearchArtworksGrid.tsx index b73b11a79ff..1f9112cdd57 100644 --- a/src/app/Scenes/Search/SearchArtworksGrid.tsx +++ b/src/app/Scenes/Search/SearchArtworksGrid.tsx @@ -8,7 +8,7 @@ import { useScreenDimensions, useTheme, } from "@artsy/palette-mobile" -import { MasonryFlashList } from "@shopify/flash-list" +import { FlashList } from "@shopify/flash-list" import { SearchArtworksGrid_viewer$data } from "__generated__/SearchArtworksGrid_viewer.graphql" import { ArtworkFilterNavigator, FilterModalMode } from "app/Components/ArtworkFilter" import { ArtworksFiltersStore } from "app/Components/ArtworkFilter/ArtworkFilterStore" @@ -20,11 +20,7 @@ import ArtworkGridItem from "app/Components/ArtworkGrids/ArtworkGridItem" import { ArtworksFilterHeader } from "app/Components/ArtworkGrids/ArtworksFilterHeader" import { SCROLLVIEW_SEARCH_RESULTS_PADDING_BOTTOM_OFFSET } from "app/Components/constants" import { extractNodes } from "app/utils/extractNodes" -import { - ESTIMATED_MASONRY_ITEM_SIZE, - NUM_COLUMNS_MASONRY, - ON_END_REACHED_THRESHOLD_MASONRY, -} from "app/utils/masonryHelpers" +import { NUM_COLUMNS_MASONRY, ON_END_REACHED_THRESHOLD_MASONRY } from "app/utils/masonryHelpers" import { AnimatedMasonryListFooter } from "app/utils/masonryHelpers/AnimatedMasonryListFooter" import { Schema } from "app/utils/track" @@ -107,14 +103,13 @@ const SearchArtworksGrid: React.FC = ({ viewer, relay, - - + item.id} numColumns={NUM_COLUMNS_MASONRY} - // this number is the estimated size of the artworkGridItem component - estimatedItemSize={ESTIMATED_MASONRY_ITEM_SIZE} keyboardShouldPersistTaps="handled" keyboardDismissMode="on-drag" ListEmptyComponent={ @@ -135,30 +130,27 @@ const SearchArtworksGrid: React.FC = ({ viewer, relay, ListFooterComponent={() => ( )} - renderItem={({ item, index, columnIndex }) => { + renderItem={({ item, index }) => { const imgAspectRatio = item.image?.aspectRatio ?? 1 const imgWidth = width / NUM_COLUMNS_MASONRY - space(2) - space(1) const imgHeight = imgWidth / imgAspectRatio return ( - - - + ) }} - contentContainerStyle={{ paddingBottom: SCROLLVIEW_SEARCH_RESULTS_PADDING_BOTTOM_OFFSET }} + contentContainerStyle={{ + paddingBottom: SCROLLVIEW_SEARCH_RESULTS_PADDING_BOTTOM_OFFSET, + paddingHorizontal: space(1), + }} /> diff --git a/src/app/Scenes/Search/components/EntitySearchResults.tsx b/src/app/Scenes/Search/components/EntitySearchResults.tsx index fa294864803..3252ed5885a 100644 --- a/src/app/Scenes/Search/components/EntitySearchResults.tsx +++ b/src/app/Scenes/Search/components/EntitySearchResults.tsx @@ -1,5 +1,5 @@ import { Flex, Spacer, Spinner, useSpace } from "@artsy/palette-mobile" -import { FlashList, ListRenderItem } from "@shopify/flash-list" +import { FlashList, FlashListRef, ListRenderItem } from "@shopify/flash-list" import { EntitySearchResultsQuery } from "__generated__/EntitySearchResultsQuery.graphql" import { EntitySearchResults_searchConnection$key } from "__generated__/EntitySearchResults_searchConnection.graphql" import { SimpleErrorMessage } from "app/Components/ErrorView/SimpleErrorMessage" @@ -22,11 +22,10 @@ interface SearchResultsProps { } const PAGE_SIZE = isTablet() ? 40 : 20 -const ESTIMATED_ITEM_SIZE = 56 export const EntitySearchResults: React.FC = ({ query, selectedPill }) => { const space = useSpace() - const flashListRef = useRef>(null) + const flashListRef = useRef>(null) const { inputRef } = useContext(SearchContext) const selectedEntity = SEARCH_PILL_KEY_TO_SEARCH_ENTITY?.[selectedPill.key] @@ -94,7 +93,6 @@ export const EntitySearchResults: React.FC = ({ query, selec extraData={{ query, selectedPill }} keyExtractor={(item, index) => item.internalID ?? index.toString()} renderItem={renderItem} - estimatedItemSize={ESTIMATED_ITEM_SIZE} showsVerticalScrollIndicator={false} ItemSeparatorComponent={() => } keyboardDismissMode="on-drag" diff --git a/src/app/Scenes/Show/Components/ShowArtworks.tsx b/src/app/Scenes/Show/Components/ShowArtworks.tsx index cf6ec59e522..df8890e1a8d 100644 --- a/src/app/Scenes/Show/Components/ShowArtworks.tsx +++ b/src/app/Scenes/Show/Components/ShowArtworks.tsx @@ -110,7 +110,6 @@ export const ShowArtworks: React.FC = ({ show, initiallyAppliedFilter }) artworks={artworks} isLoading={isLoadingNext} hasMore={hasNext} - disableAutoLayout pageSize={PAGE_SIZE} contextScreenOwnerType={OwnerType.show} contextScreenOwnerId={data.internalID} diff --git a/src/app/Scenes/Tag/TagArtworks.tsx b/src/app/Scenes/Tag/TagArtworks.tsx index 7dba22d1bfb..03557153019 100644 --- a/src/app/Scenes/Tag/TagArtworks.tsx +++ b/src/app/Scenes/Tag/TagArtworks.tsx @@ -1,14 +1,14 @@ import { OwnerType } from "@artsy/cohesion" import { Box, - Text, + Flex, SimpleMessage, Tabs, + Text, useScreenDimensions, - Flex, useSpace, } from "@artsy/palette-mobile" -import { MasonryListRenderItem } from "@shopify/flash-list" +import { ListRenderItem } from "@shopify/flash-list" import { TagArtworks_tag$data } from "__generated__/TagArtworks_tag.graphql" import { ArtworkFilterNavigator } from "app/Components/ArtworkFilter" import { FilterModalMode } from "app/Components/ArtworkFilter/ArtworkFilterOptionsScreen" @@ -18,7 +18,6 @@ import { FilteredArtworkGridZeroState } from "app/Components/ArtworkGrids/Filter import { TagArtworksFilterHeader } from "app/Scenes/Tag/TagArtworksFilterHeader" import { extractNodes } from "app/utils/extractNodes" import { - ESTIMATED_MASONRY_ITEM_SIZE, MASONRY_LIST_PAGE_SIZE, NUM_COLUMNS_MASONRY, ON_END_REACHED_THRESHOLD_MASONRY, @@ -91,25 +90,19 @@ const TagArtworks: React.FC = ({ tag, relay }) => { } }, [relay.hasMore(), relay.isLoading()]) - const renderItem: MasonryListRenderItem = useCallback(({ item, columnIndex }) => { + const renderItem: ListRenderItem = useCallback(({ item }) => { const imgAspectRatio = item.image?.aspectRatio ?? 1 const imgWidth = width / NUM_COLUMNS_MASONRY - space(2) - space(1) const imgHeight = imgWidth / imgAspectRatio return ( - - - + ) }, []) @@ -118,8 +111,8 @@ const TagArtworks: React.FC = ({ tag, relay }) => { @@ -144,7 +137,7 @@ const TagArtworks: React.FC = ({ tag, relay }) => { // be visible above list content ListHeaderComponentStyle={{ zIndex: 1 }} ListHeaderComponent={ - <> + @@ -153,7 +146,7 @@ const TagArtworks: React.FC = ({ tag, relay }) => { Showing {artworksTotal} works - + } /> = () => { const fontScale = PixelRatio.getFontScale() const navigation = useNavigation>() const setDarkModeOption = GlobalStore.actions.devicePrefs.setDarkModeOption - + const isLoggedIn = GlobalStore.useAppState((state) => !!state.auth.userAccessToken) const handleBackButton = () => { goBack() return true @@ -79,7 +78,7 @@ export const DevMenu: React.FC<{}> = () => { { // The logged out stack is using a js react-navigation stack instead of a native stack // and it doesn't support large headers so we don't need this additional header - !__unsafe__onboardingNavigationRef.current ? : null + !isLoggedIn ? : null } Build:{" "} diff --git a/src/app/system/devTools/DevMenu/utils/navigateToDevMenu.ts b/src/app/system/devTools/DevMenu/utils/navigateToDevMenu.ts new file mode 100644 index 00000000000..ec4d80b5155 --- /dev/null +++ b/src/app/system/devTools/DevMenu/utils/navigateToDevMenu.ts @@ -0,0 +1,5 @@ +import { internal_navigationRef } from "app/Navigation/Navigation" + +export const navigateToDevMenu = () => { + internal_navigationRef.current?.navigate("DevMenu") +} diff --git a/src/app/system/flags/Components/WrappedFlagProvider.tsx b/src/app/system/flags/Components/WrappedFlagProvider.tsx index 102b33fbd26..a8a4936a2cb 100644 --- a/src/app/system/flags/Components/WrappedFlagProvider.tsx +++ b/src/app/system/flags/Components/WrappedFlagProvider.tsx @@ -39,7 +39,7 @@ export const WrappedFlagProvider: React.FC = ({ childre } return ( - + fn()} config={config} startClient={false}> {children} ) diff --git a/src/app/system/navigation/RouterLink.tsx b/src/app/system/navigation/RouterLink.tsx index b7fdc4c03a5..ce755c6ec10 100644 --- a/src/app/system/navigation/RouterLink.tsx +++ b/src/app/system/navigation/RouterLink.tsx @@ -4,7 +4,6 @@ import { navigate, NavigateOptions } from "app/system/navigation/navigate" import { Sentinel } from "app/utils/Sentinel" import { useDevToggle } from "app/utils/hooks/useDevToggle" import { useFeatureFlag } from "app/utils/hooks/useFeatureFlag" -import { isNewArchitectureEnabled } from "app/utils/isNewArchitectureEnabled" import { usePrefetch } from "app/utils/queryPrefetching" import React, { useState } from "react" import { GestureResponderEvent } from "react-native" @@ -41,8 +40,7 @@ export const RouterLink: React.FC = ({ const enableViewPortPrefetching = useFeatureFlag("AREnableViewPortPrefetching") const [prefetchState, setPrefetchState] = useState(null) - const isPrefetchingEnabled = - !disablePrefetch && enableViewPortPrefetching && to && !isNewArchitectureEnabled + const isPrefetchingEnabled = !disablePrefetch && enableViewPortPrefetching && to const handlePress = (event: GestureResponderEvent) => { onPress?.(event) diff --git a/src/app/system/navigation/__tests__/RouterLink.tests.tsx b/src/app/system/navigation/__tests__/RouterLink.tests.tsx index 1b014bba122..a3a32b83635 100644 --- a/src/app/system/navigation/__tests__/RouterLink.tests.tsx +++ b/src/app/system/navigation/__tests__/RouterLink.tests.tsx @@ -7,8 +7,6 @@ import { renderWithWrappers } from "app/utils/tests/renderWithWrappers" import { useEffect } from "react" import { TouchableWithoutFeedback, View } from "react-native" -let mockIsNewArchitectureEnabled = false - jest.mock("app/utils/queryPrefetching", () => ({ usePrefetch: () => mockPrefetch, })) @@ -18,12 +16,6 @@ jest.mock("app/utils/Sentinel", () => ({ Sentinel: (props: any) => , })) -jest.mock("app/utils/isNewArchitectureEnabled", () => ({ - get isNewArchitectureEnabled() { - return mockIsNewArchitectureEnabled - }, -})) - describe("RouterLink", () => { const touchableOnPress = jest.fn() beforeAll(() => { @@ -162,22 +154,6 @@ describe("RouterLink", () => { expect(mockPrefetch).not.toHaveBeenCalledWith("/test-route") }) }) - - describe("when isNewArchitectureEnabled is true", () => { - beforeAll(() => { - mockIsNewArchitectureEnabled = true - }) - - afterAll(() => { - mockIsNewArchitectureEnabled = false - }) - - it("does not prefetch", () => { - renderWithWrappers() - - expect(mockPrefetch).not.toHaveBeenCalled() - }) - }) }) }) diff --git a/src/app/utils/isNewArchitectureEnabled.ts b/src/app/utils/isNewArchitectureEnabled.ts deleted file mode 100644 index 85b064dd5d9..00000000000 --- a/src/app/utils/isNewArchitectureEnabled.ts +++ /dev/null @@ -1,4 +0,0 @@ -// Check if the global `nativeFabric` object exists. -// Its presence indicates that Fabric is running. -// @ts-expect-error nativeFabricUIManager is only available in the new architecture and isn't typed yet -export const isNewArchitectureEnabled = !!global.nativeFabricUIManager diff --git a/src/app/utils/masonryHelpers/index.tsx b/src/app/utils/masonryHelpers/index.tsx index 288d7c4c806..8a2f5dd17aa 100644 --- a/src/app/utils/masonryHelpers/index.tsx +++ b/src/app/utils/masonryHelpers/index.tsx @@ -1,9 +1,6 @@ import { isTablet } from "react-native-device-info" import { FragmentRefs } from "relay-runtime" -// https://shopify.github.io/flash-list/docs/fundamentals/performant-components#estimateditemsize -export const ESTIMATED_MASONRY_ITEM_SIZE = 272 - export const NUM_COLUMNS_MASONRY = isTablet() ? 3 : 2 export const ON_END_REACHED_THRESHOLD_MASONRY = 1.2 @@ -27,3 +24,7 @@ export interface MasonryArtworkItem { readonly slug: string readonly " $fragmentSpreads": FragmentRefs<"ArtworkGridItem_artwork"> } + +export const getColumnIndex = (index: number, numColumns: number = NUM_COLUMNS_MASONRY) => { + return index % numColumns +} diff --git a/src/app/utils/renderMarkdown.tsx b/src/app/utils/renderMarkdown.tsx index 7ddd26d0cb9..71f76f818ab 100644 --- a/src/app/utils/renderMarkdown.tsx +++ b/src/app/utils/renderMarkdown.tsx @@ -227,7 +227,7 @@ export function defaultRules({ ), }, hr: { - react: () => , + react: (_node, _output, state) => , }, ...ruleOverrides, }) diff --git a/src/setupJest.tsx b/src/setupJest.tsx index 68c7cf310d1..f625662bb4e 100644 --- a/src/setupJest.tsx +++ b/src/setupJest.tsx @@ -99,13 +99,6 @@ jest.mock("react-native-permissions", () => ({ requestNotifications: jest.fn(), })) -jest.mock("react-native-blurhash", () => { - const ReactNative = require("react-native") - return { - Blurhash: ReactNative.View as any, - } -}) - require("jest-fetch-mock").enableMocks() jest.mock("react-tracking") @@ -659,7 +652,6 @@ jest.mock("@shopify/flash-list", () => { const { FlatList } = require("react-native") return { ...jest.requireActual("@shopify/flash-list"), - MasonryFlashList: FlatList, FlashList: FlatList, } }) @@ -702,12 +694,6 @@ jest.mock("app/utils/Sentinel", () => { Sentinel: View, } }) -jest.mock("react-native-blurhash", () => { - const ReactNative = require("react-native") - return { - Blurhash: ReactNative.View as any, - } -}) jest.mock("app/system/notifications/getNotificationsPermissions", () => ({ getNotificationPermissionsStatus: mockFetchNotificationPermissions, diff --git a/yarn.lock b/yarn.lock index 21465672a53..3163cbc2bd2 100644 --- a/yarn.lock +++ b/yarn.lock @@ -54,15 +54,22 @@ __metadata: languageName: node linkType: hard -"@artsy/palette-mobile@npm:22.10.0": - version: 22.10.0 - resolution: "@artsy/palette-mobile@npm:22.10.0" +"@artsy/palette-mobile@npm:22.6.0--canary.425.5263.0": + version: 22.6.0--canary.425.5263.0 + resolution: "@artsy/palette-mobile@npm:22.6.0--canary.425.5263.0" dependencies: "@artsy/palette-tokens": "npm:7.0.0" - "@react-spring/native": "npm:10.0.3" + "@d11/react-native-fast-image": "npm:8.12.0" + "@react-spring/native": "npm:^10.0.3" + "@shopify/flash-list": "npm:2.2.0" "@styled-system/theme-get": "npm:^5.1.2" - events: "npm:3.3.0" - react-nanny: "npm:2.15.0" + events: "npm:^3.3.0" + lodash: "npm:^4.17.21" + moti: "npm:0.30.0" + react-nanny: "npm:^2.15.0" + react-native-blurhash: "npm:2.1.2" + react-native-collapsible-tab-view: "npm:8.0.1" + react-native-pager-view: "npm:6.7.1" react-native-popover-view: "npm:^6.1.0" peerDependencies: "@d11/react-native-fast-image": "*" @@ -76,7 +83,7 @@ __metadata: react-native-reanimated: "*" react-native-svg: "*" styled-components: ">= 5" - checksum: 10c0/906dda18cb3924f84dac6af802a8557ef6e055d41a9aba8d55bf9f2e270f653bd302e8de99b1c810318d8214bc6410c519ae80d627886eb367f1d9a3edf28ae8 + checksum: 10c0/18453ac43ec9bf58fcd3cc5c3f1eb3501e4ba118055d90d4fdcfce2c3452ac64be1ef971d69425373c61bc377627eae4cbcb3c72338dfab8dd353cf4b1a87e19 languageName: node linkType: hard @@ -3133,6 +3140,13 @@ __metadata: languageName: node linkType: hard +"@dominicstop/ts-event-emitter@npm:^1.1.0": + version: 1.1.0 + resolution: "@dominicstop/ts-event-emitter@npm:1.1.0" + checksum: 10c0/fe16c03132736a0a798c232636ab6b127fd8063509511ccafbd99405c224a106cfb7a8d4af13c4f6f412ec0ea3baae3678aa2c8c09d81c9985c423d476404e1a + languageName: node + linkType: hard + "@egjs/hammerjs@npm:^2.0.17": version: 2.0.17 resolution: "@egjs/hammerjs@npm:2.0.17" @@ -3349,7 +3363,7 @@ __metadata: languageName: node linkType: hard -"@eslint-community/eslint-utils@npm:^4.2.0, @eslint-community/eslint-utils@npm:^4.4.0": +"@eslint-community/eslint-utils@npm:^4.2.0": version: 4.4.0 resolution: "@eslint-community/eslint-utils@npm:4.4.0" dependencies: @@ -3360,6 +3374,17 @@ __metadata: languageName: node linkType: hard +"@eslint-community/eslint-utils@npm:^4.4.0": + version: 4.9.0 + resolution: "@eslint-community/eslint-utils@npm:4.9.0" + dependencies: + eslint-visitor-keys: "npm:^3.4.3" + peerDependencies: + eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 + checksum: 10c0/8881e22d519326e7dba85ea915ac7a143367c805e6ba1374c987aa2fbdd09195cc51183d2da72c0e2ff388f84363e1b220fd0d19bef10c272c63455162176817 + languageName: node + linkType: hard + "@eslint-community/regexpp@npm:^4.10.0": version: 4.11.1 resolution: "@eslint-community/regexpp@npm:4.11.1" @@ -3679,7 +3704,7 @@ __metadata: languageName: node linkType: hard -"@expo/metro-config@npm:54.0.7, @expo/metro-config@npm:~54.0.7": +"@expo/metro-config@npm:54.0.7": version: 54.0.7 resolution: "@expo/metro-config@npm:54.0.7" dependencies: @@ -3713,6 +3738,40 @@ __metadata: languageName: node linkType: hard +"@expo/metro-config@npm:~54.0.7": + version: 54.0.9 + resolution: "@expo/metro-config@npm:54.0.9" + dependencies: + "@babel/code-frame": "npm:^7.20.0" + "@babel/core": "npm:^7.20.0" + "@babel/generator": "npm:^7.20.5" + "@expo/config": "npm:~12.0.10" + "@expo/env": "npm:~2.0.7" + "@expo/json-file": "npm:~10.0.7" + "@expo/metro": "npm:~54.1.0" + "@expo/spawn-async": "npm:^1.7.2" + browserslist: "npm:^4.25.0" + chalk: "npm:^4.1.0" + debug: "npm:^4.3.2" + dotenv: "npm:~16.4.5" + dotenv-expand: "npm:~11.0.6" + getenv: "npm:^2.0.0" + glob: "npm:^10.4.2" + hermes-parser: "npm:^0.29.1" + jsc-safe-url: "npm:^0.2.4" + lightningcss: "npm:^1.30.1" + minimatch: "npm:^9.0.0" + postcss: "npm:~8.4.32" + resolve-from: "npm:^5.0.0" + peerDependencies: + expo: "*" + peerDependenciesMeta: + expo: + optional: true + checksum: 10c0/6833c594082a347ba6df0ad6d107c6b8f21363a06b4f5e4ffbac91bbfc14cf1d62b2fbb335bb146dddcad8bd53d7a09920fe928cc7312f9e50bd9138b2d4aacc + languageName: node + linkType: hard + "@expo/metro@npm:~54.1.0": version: 54.1.0 resolution: "@expo/metro@npm:54.1.0" @@ -4424,6 +4483,44 @@ __metadata: languageName: node linkType: hard +"@floating-ui/core@npm:^1.7.3": + version: 1.7.3 + resolution: "@floating-ui/core@npm:1.7.3" + dependencies: + "@floating-ui/utils": "npm:^0.2.10" + checksum: 10c0/edfc23800122d81df0df0fb780b7328ae6c5f00efbb55bd48ea340f4af8c5b3b121ceb4bb81220966ab0f87b443204d37105abdd93d94846468be3243984144c + languageName: node + linkType: hard + +"@floating-ui/dom@npm:^1.7.4": + version: 1.7.4 + resolution: "@floating-ui/dom@npm:1.7.4" + dependencies: + "@floating-ui/core": "npm:^1.7.3" + "@floating-ui/utils": "npm:^0.2.10" + checksum: 10c0/da6166c25f9b0729caa9f498685a73a0e28251613b35d27db8de8014bc9d045158a23c092b405321a3d67c2064909b6e2a7e6c1c9cc0f62967dca5779f5aef30 + languageName: node + linkType: hard + +"@floating-ui/react-dom@npm:^2.0.0": + version: 2.1.6 + resolution: "@floating-ui/react-dom@npm:2.1.6" + dependencies: + "@floating-ui/dom": "npm:^1.7.4" + peerDependencies: + react: ">=16.8.0" + react-dom: ">=16.8.0" + checksum: 10c0/6654834a8e73ecbdbc6cad2ad8f7abc698ac7c1800ded4d61113525c591c03d2e3b59d3cf9205859221465ea38c87af4f9e6e204703c5b7a7e85332d1eef2e18 + languageName: node + linkType: hard + +"@floating-ui/utils@npm:^0.2.10": + version: 0.2.10 + resolution: "@floating-ui/utils@npm:0.2.10" + checksum: 10c0/e9bc2a1730ede1ee25843937e911ab6e846a733a4488623cd353f94721b05ec2c9ec6437613a2ac9379a94c2fd40c797a2ba6fa1df2716f5ce4aa6ddb1cf9ea4 + languageName: node + linkType: hard + "@gitbeaker/core@npm:^21.7.0": version: 21.7.0 resolution: "@gitbeaker/core@npm:21.7.0" @@ -5570,6 +5667,488 @@ __metadata: languageName: node linkType: hard +"@radix-ui/primitive@npm:1.1.3": + version: 1.1.3 + resolution: "@radix-ui/primitive@npm:1.1.3" + checksum: 10c0/88860165ee7066fa2c179f32ffcd3ee6d527d9dcdc0e8be85e9cb0e2c84834be8e3c1a976c74ba44b193f709544e12f54455d892b28e32f0708d89deda6b9f1d + languageName: node + linkType: hard + +"@radix-ui/react-arrow@npm:1.1.7": + version: 1.1.7 + resolution: "@radix-ui/react-arrow@npm:1.1.7" + dependencies: + "@radix-ui/react-primitive": "npm:2.1.3" + peerDependencies: + "@types/react": "*" + "@types/react-dom": "*" + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + "@types/react": + optional: true + "@types/react-dom": + optional: true + checksum: 10c0/c3b46766238b3ee2a394d8806a5141432361bf1425110c9f0dcf480bda4ebd304453a53f294b5399c6ee3ccfcae6fd544921fd01ddc379cf5942acdd7168664b + languageName: node + linkType: hard + +"@radix-ui/react-collection@npm:1.1.7": + version: 1.1.7 + resolution: "@radix-ui/react-collection@npm:1.1.7" + dependencies: + "@radix-ui/react-compose-refs": "npm:1.1.2" + "@radix-ui/react-context": "npm:1.1.2" + "@radix-ui/react-primitive": "npm:2.1.3" + "@radix-ui/react-slot": "npm:1.2.3" + peerDependencies: + "@types/react": "*" + "@types/react-dom": "*" + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + "@types/react": + optional: true + "@types/react-dom": + optional: true + checksum: 10c0/fa321a7300095508491f75414f02b243f0c3f179dc0728cfd115e2ea9f6f48f1516532b59f526d9ac81bbab63cd98a052074b4703ec0b9428fac945ebabec5fd + languageName: node + linkType: hard + +"@radix-ui/react-compose-refs@npm:1.1.2": + version: 1.1.2 + resolution: "@radix-ui/react-compose-refs@npm:1.1.2" + peerDependencies: + "@types/react": "*" + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + "@types/react": + optional: true + checksum: 10c0/d36a9c589eb75d634b9b139c80f916aadaf8a68a7c1c4b8c6c6b88755af1a92f2e343457042089f04cc3f23073619d08bb65419ced1402e9d4e299576d970771 + languageName: node + linkType: hard + +"@radix-ui/react-context-menu@npm:^2.0.1": + version: 2.2.16 + resolution: "@radix-ui/react-context-menu@npm:2.2.16" + dependencies: + "@radix-ui/primitive": "npm:1.1.3" + "@radix-ui/react-context": "npm:1.1.2" + "@radix-ui/react-menu": "npm:2.1.16" + "@radix-ui/react-primitive": "npm:2.1.3" + "@radix-ui/react-use-callback-ref": "npm:1.1.1" + "@radix-ui/react-use-controllable-state": "npm:1.2.2" + peerDependencies: + "@types/react": "*" + "@types/react-dom": "*" + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + "@types/react": + optional: true + "@types/react-dom": + optional: true + checksum: 10c0/950f7559e65474a19145238cf44d744cb1e49be2221ff18436ba49b496b05ccf93bd3906aaa2c7ab76bc77daf694911a78442801e0053f57d2e57ebbfd281c49 + languageName: node + linkType: hard + +"@radix-ui/react-context@npm:1.1.2": + version: 1.1.2 + resolution: "@radix-ui/react-context@npm:1.1.2" + peerDependencies: + "@types/react": "*" + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + "@types/react": + optional: true + checksum: 10c0/cece731f8cc25d494c6589cc681e5c01a93867d895c75889973afa1a255f163c286e390baa7bc028858eaabe9f6b57270d0ca6377356f652c5557c1c7a41ccce + languageName: node + linkType: hard + +"@radix-ui/react-direction@npm:1.1.1": + version: 1.1.1 + resolution: "@radix-ui/react-direction@npm:1.1.1" + peerDependencies: + "@types/react": "*" + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + "@types/react": + optional: true + checksum: 10c0/7a89d9291f846a3105e45f4df98d6b7a08f8d7b30acdcd253005dc9db107ee83cbbebc9e47a9af1e400bcd47697f1511ceab23a399b0da854488fc7220482ac9 + languageName: node + linkType: hard + +"@radix-ui/react-dismissable-layer@npm:1.1.11": + version: 1.1.11 + resolution: "@radix-ui/react-dismissable-layer@npm:1.1.11" + dependencies: + "@radix-ui/primitive": "npm:1.1.3" + "@radix-ui/react-compose-refs": "npm:1.1.2" + "@radix-ui/react-primitive": "npm:2.1.3" + "@radix-ui/react-use-callback-ref": "npm:1.1.1" + "@radix-ui/react-use-escape-keydown": "npm:1.1.1" + peerDependencies: + "@types/react": "*" + "@types/react-dom": "*" + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + "@types/react": + optional: true + "@types/react-dom": + optional: true + checksum: 10c0/c825572a64073c4d3853702029979f6658770ffd6a98eabc4984e1dee1b226b4078a2a4dc7003f96475b438985e9b21a58e75f51db74dd06848dcae1f2d395dc + languageName: node + linkType: hard + +"@radix-ui/react-dropdown-menu@npm:^2.0.1": + version: 2.1.16 + resolution: "@radix-ui/react-dropdown-menu@npm:2.1.16" + dependencies: + "@radix-ui/primitive": "npm:1.1.3" + "@radix-ui/react-compose-refs": "npm:1.1.2" + "@radix-ui/react-context": "npm:1.1.2" + "@radix-ui/react-id": "npm:1.1.1" + "@radix-ui/react-menu": "npm:2.1.16" + "@radix-ui/react-primitive": "npm:2.1.3" + "@radix-ui/react-use-controllable-state": "npm:1.2.2" + peerDependencies: + "@types/react": "*" + "@types/react-dom": "*" + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + "@types/react": + optional: true + "@types/react-dom": + optional: true + checksum: 10c0/8caaa8dd791ccb284568720adafa59855e13860aa29eb20e10a04ba671cbbfa519a4c5d3a339a4d9fb08009eeb1065f4a8b5c3c8ef45e9753161cc560106b935 + languageName: node + linkType: hard + +"@radix-ui/react-focus-guards@npm:1.1.3": + version: 1.1.3 + resolution: "@radix-ui/react-focus-guards@npm:1.1.3" + peerDependencies: + "@types/react": "*" + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + "@types/react": + optional: true + checksum: 10c0/0bab65eb8d7e4f72f685d63de7fbba2450e3cb15ad6a20a16b42195e9d335c576356f5a47cb58d1ffc115393e46d7b14b12c5d4b10029b0ec090861255866985 + languageName: node + linkType: hard + +"@radix-ui/react-focus-scope@npm:1.1.7": + version: 1.1.7 + resolution: "@radix-ui/react-focus-scope@npm:1.1.7" + dependencies: + "@radix-ui/react-compose-refs": "npm:1.1.2" + "@radix-ui/react-primitive": "npm:2.1.3" + "@radix-ui/react-use-callback-ref": "npm:1.1.1" + peerDependencies: + "@types/react": "*" + "@types/react-dom": "*" + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + "@types/react": + optional: true + "@types/react-dom": + optional: true + checksum: 10c0/8a6071331bdeeb79b223463de75caf759b8ad19339cab838e537b8dbb2db236891a1f4df252445c854d375d43d9d315dfcce0a6b01553a2984ec372bb8f1300e + languageName: node + linkType: hard + +"@radix-ui/react-id@npm:1.1.1": + version: 1.1.1 + resolution: "@radix-ui/react-id@npm:1.1.1" + dependencies: + "@radix-ui/react-use-layout-effect": "npm:1.1.1" + peerDependencies: + "@types/react": "*" + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + "@types/react": + optional: true + checksum: 10c0/7d12e76818763d592c331277ef62b197e2e64945307e650bd058f0090e5ae48bbd07691b23b7e9e977901ef4eadcb3e2d5eaeb17a13859083384be83fc1292c7 + languageName: node + linkType: hard + +"@radix-ui/react-menu@npm:2.1.16": + version: 2.1.16 + resolution: "@radix-ui/react-menu@npm:2.1.16" + dependencies: + "@radix-ui/primitive": "npm:1.1.3" + "@radix-ui/react-collection": "npm:1.1.7" + "@radix-ui/react-compose-refs": "npm:1.1.2" + "@radix-ui/react-context": "npm:1.1.2" + "@radix-ui/react-direction": "npm:1.1.1" + "@radix-ui/react-dismissable-layer": "npm:1.1.11" + "@radix-ui/react-focus-guards": "npm:1.1.3" + "@radix-ui/react-focus-scope": "npm:1.1.7" + "@radix-ui/react-id": "npm:1.1.1" + "@radix-ui/react-popper": "npm:1.2.8" + "@radix-ui/react-portal": "npm:1.1.9" + "@radix-ui/react-presence": "npm:1.1.5" + "@radix-ui/react-primitive": "npm:2.1.3" + "@radix-ui/react-roving-focus": "npm:1.1.11" + "@radix-ui/react-slot": "npm:1.2.3" + "@radix-ui/react-use-callback-ref": "npm:1.1.1" + aria-hidden: "npm:^1.2.4" + react-remove-scroll: "npm:^2.6.3" + peerDependencies: + "@types/react": "*" + "@types/react-dom": "*" + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + "@types/react": + optional: true + "@types/react-dom": + optional: true + checksum: 10c0/27516b2b987fa9181c4da8645000af8f60691866a349d7a46b9505fa7d2e9d92b9e364db4f7305d08e9e57d0e1afc8df8354f8ee3c12aa05c0100c16b0e76c27 + languageName: node + linkType: hard + +"@radix-ui/react-popper@npm:1.2.8": + version: 1.2.8 + resolution: "@radix-ui/react-popper@npm:1.2.8" + dependencies: + "@floating-ui/react-dom": "npm:^2.0.0" + "@radix-ui/react-arrow": "npm:1.1.7" + "@radix-ui/react-compose-refs": "npm:1.1.2" + "@radix-ui/react-context": "npm:1.1.2" + "@radix-ui/react-primitive": "npm:2.1.3" + "@radix-ui/react-use-callback-ref": "npm:1.1.1" + "@radix-ui/react-use-layout-effect": "npm:1.1.1" + "@radix-ui/react-use-rect": "npm:1.1.1" + "@radix-ui/react-use-size": "npm:1.1.1" + "@radix-ui/rect": "npm:1.1.1" + peerDependencies: + "@types/react": "*" + "@types/react-dom": "*" + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + "@types/react": + optional: true + "@types/react-dom": + optional: true + checksum: 10c0/48e3f13eac3b8c13aca8ded37d74db17e1bb294da8d69f142ab6b8719a06c3f90051668bed64520bf9f3abdd77b382ce7ce209d056bb56137cecc949b69b421c + languageName: node + linkType: hard + +"@radix-ui/react-portal@npm:1.1.9": + version: 1.1.9 + resolution: "@radix-ui/react-portal@npm:1.1.9" + dependencies: + "@radix-ui/react-primitive": "npm:2.1.3" + "@radix-ui/react-use-layout-effect": "npm:1.1.1" + peerDependencies: + "@types/react": "*" + "@types/react-dom": "*" + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + "@types/react": + optional: true + "@types/react-dom": + optional: true + checksum: 10c0/45b432497c722720c72c493a29ef6085bc84b50eafe79d48b45c553121b63e94f9cdb77a3a74b9c49126f8feb3feee009fe400d48b7759d3552396356b192cd7 + languageName: node + linkType: hard + +"@radix-ui/react-presence@npm:1.1.5": + version: 1.1.5 + resolution: "@radix-ui/react-presence@npm:1.1.5" + dependencies: + "@radix-ui/react-compose-refs": "npm:1.1.2" + "@radix-ui/react-use-layout-effect": "npm:1.1.1" + peerDependencies: + "@types/react": "*" + "@types/react-dom": "*" + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + "@types/react": + optional: true + "@types/react-dom": + optional: true + checksum: 10c0/d0e61d314250eeaef5369983cb790701d667f51734bafd98cf759072755562018052c594e6cdc5389789f4543cb0a4d98f03ff4e8f37338d6b5bf51a1700c1d1 + languageName: node + linkType: hard + +"@radix-ui/react-primitive@npm:2.1.3": + version: 2.1.3 + resolution: "@radix-ui/react-primitive@npm:2.1.3" + dependencies: + "@radix-ui/react-slot": "npm:1.2.3" + peerDependencies: + "@types/react": "*" + "@types/react-dom": "*" + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + "@types/react": + optional: true + "@types/react-dom": + optional: true + checksum: 10c0/fdff9b84913bb4172ef6d3af7442fca5f9bba5f2709cba08950071f819d7057aec3a4a2d9ef44cf9cbfb8014d02573c6884a04cff175895823aaef809ebdb034 + languageName: node + linkType: hard + +"@radix-ui/react-roving-focus@npm:1.1.11": + version: 1.1.11 + resolution: "@radix-ui/react-roving-focus@npm:1.1.11" + dependencies: + "@radix-ui/primitive": "npm:1.1.3" + "@radix-ui/react-collection": "npm:1.1.7" + "@radix-ui/react-compose-refs": "npm:1.1.2" + "@radix-ui/react-context": "npm:1.1.2" + "@radix-ui/react-direction": "npm:1.1.1" + "@radix-ui/react-id": "npm:1.1.1" + "@radix-ui/react-primitive": "npm:2.1.3" + "@radix-ui/react-use-callback-ref": "npm:1.1.1" + "@radix-ui/react-use-controllable-state": "npm:1.2.2" + peerDependencies: + "@types/react": "*" + "@types/react-dom": "*" + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + "@types/react": + optional: true + "@types/react-dom": + optional: true + checksum: 10c0/2cd43339c36e89a3bf1db8aab34b939113dfbde56bf3a33df2d74757c78c9489b847b1962f1e2441c67e41817d120cb6177943e0f655f47bc1ff8e44fd55b1a2 + languageName: node + linkType: hard + +"@radix-ui/react-slot@npm:1.2.3": + version: 1.2.3 + resolution: "@radix-ui/react-slot@npm:1.2.3" + dependencies: + "@radix-ui/react-compose-refs": "npm:1.1.2" + peerDependencies: + "@types/react": "*" + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + "@types/react": + optional: true + checksum: 10c0/5913aa0d760f505905779515e4b1f0f71a422350f077cc8d26d1aafe53c97f177fec0e6d7fbbb50d8b5e498aa9df9f707ca75ae3801540c283b26b0136138eef + languageName: node + linkType: hard + +"@radix-ui/react-use-callback-ref@npm:1.1.1": + version: 1.1.1 + resolution: "@radix-ui/react-use-callback-ref@npm:1.1.1" + peerDependencies: + "@types/react": "*" + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + "@types/react": + optional: true + checksum: 10c0/5f6aff8592dea6a7e46589808912aba3fb3b626cf6edd2b14f01638b61dbbe49eeb9f67cd5601f4c15b2fb547b9a7e825f7c4961acd4dd70176c969ae405f8d8 + languageName: node + linkType: hard + +"@radix-ui/react-use-controllable-state@npm:1.2.2": + version: 1.2.2 + resolution: "@radix-ui/react-use-controllable-state@npm:1.2.2" + dependencies: + "@radix-ui/react-use-effect-event": "npm:0.0.2" + "@radix-ui/react-use-layout-effect": "npm:1.1.1" + peerDependencies: + "@types/react": "*" + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + "@types/react": + optional: true + checksum: 10c0/f55c4b06e895293aed4b44c9ef26fb24432539f5346fcd6519c7745800535b571058685314e83486a45bf61dc83887e24826490d3068acc317fb0a9010516e63 + languageName: node + linkType: hard + +"@radix-ui/react-use-effect-event@npm:0.0.2": + version: 0.0.2 + resolution: "@radix-ui/react-use-effect-event@npm:0.0.2" + dependencies: + "@radix-ui/react-use-layout-effect": "npm:1.1.1" + peerDependencies: + "@types/react": "*" + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + "@types/react": + optional: true + checksum: 10c0/e84ff72a3e76c5ae9c94941028bb4b6472f17d4104481b9eab773deab3da640ecea035e54da9d6f4df8d84c18ef6913baf92b7511bee06930dc58bd0c0add417 + languageName: node + linkType: hard + +"@radix-ui/react-use-escape-keydown@npm:1.1.1": + version: 1.1.1 + resolution: "@radix-ui/react-use-escape-keydown@npm:1.1.1" + dependencies: + "@radix-ui/react-use-callback-ref": "npm:1.1.1" + peerDependencies: + "@types/react": "*" + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + "@types/react": + optional: true + checksum: 10c0/bff53be99e940fef1d3c4df7d560e1d9133182e5a98336255d3063327d1d3dd4ec54a95dc5afe15cca4fb6c184f0a956c70de2815578c318cf995a7f9beabaa1 + languageName: node + linkType: hard + +"@radix-ui/react-use-layout-effect@npm:1.1.1": + version: 1.1.1 + resolution: "@radix-ui/react-use-layout-effect@npm:1.1.1" + peerDependencies: + "@types/react": "*" + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + "@types/react": + optional: true + checksum: 10c0/9f98fdaba008dfc58050de60a77670b885792df473cf82c1cef8daee919a5dd5a77d270209f5f0b0abfaac78cb1627396e3ff56c81b735be550409426fe8b040 + languageName: node + linkType: hard + +"@radix-ui/react-use-rect@npm:1.1.1": + version: 1.1.1 + resolution: "@radix-ui/react-use-rect@npm:1.1.1" + dependencies: + "@radix-ui/rect": "npm:1.1.1" + peerDependencies: + "@types/react": "*" + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + "@types/react": + optional: true + checksum: 10c0/271711404c05c589c8dbdaa748749e7daf44bcc6bffc9ecd910821c3ebca0ee245616cf5b39653ce690f53f875c3836fd3f36f51ab1c628273b6db599eee4864 + languageName: node + linkType: hard + +"@radix-ui/react-use-size@npm:1.1.1": + version: 1.1.1 + resolution: "@radix-ui/react-use-size@npm:1.1.1" + dependencies: + "@radix-ui/react-use-layout-effect": "npm:1.1.1" + peerDependencies: + "@types/react": "*" + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + "@types/react": + optional: true + checksum: 10c0/851d09a816f44282e0e9e2147b1b571410174cc048703a50c4fa54d672de994fd1dfff1da9d480ecfd12c77ae8f48d74f01adaf668f074156b8cd0043c6c21d8 + languageName: node + linkType: hard + +"@radix-ui/rect@npm:1.1.1": + version: 1.1.1 + resolution: "@radix-ui/rect@npm:1.1.1" + checksum: 10c0/0dac4f0f15691199abe6a0e067821ddd9d0349c0c05f39834e4eafc8403caf724106884035ae91bbc826e10367e6a5672e7bec4d4243860fa7649de246b1f60b + languageName: node + linkType: hard + "@react-native-async-storage/async-storage@npm:2.2.0": version: 2.2.0 resolution: "@react-native-async-storage/async-storage@npm:2.2.0" @@ -5901,6 +6480,16 @@ __metadata: languageName: node linkType: hard +"@react-native-menu/menu@npm:1.2.2": + version: 1.2.2 + resolution: "@react-native-menu/menu@npm:1.2.2" + peerDependencies: + react: "*" + react-native: "*" + checksum: 10c0/947e882524e7ee7c0ac77d81119c6eb0cb0c1f66156d61c1e1b50c46960a768f1b4e2149610a7a30a1f2a921c0694ecbbb401b5758785a0120f993006259d099 + languageName: node + linkType: hard + "@react-native/assets-registry@npm:0.81.5": version: 0.81.5 resolution: "@react-native/assets-registry@npm:0.81.5" @@ -6244,11 +6833,12 @@ __metadata: linkType: hard "@react-navigation/core@npm:^7.12.4": - version: 7.12.4 - resolution: "@react-navigation/core@npm:7.12.4" + version: 7.13.1 + resolution: "@react-navigation/core@npm:7.13.1" dependencies: "@react-navigation/routers": "npm:^7.5.1" escape-string-regexp: "npm:^4.0.0" + fast-deep-equal: "npm:^3.1.3" nanoid: "npm:^3.3.11" query-string: "npm:^7.1.3" react-is: "npm:^19.1.0" @@ -6256,7 +6846,7 @@ __metadata: use-sync-external-store: "npm:^1.5.0" peerDependencies: react: ">= 18.2.0" - checksum: 10c0/0e8231ced4f196c84db859760b9704b85eca156ba0d8d9802a89d46d96116fa10fa481dc482be6a807b33971682bce176a997391543d2404754e43af510201b8 + checksum: 10c0/d70a61dbd2e7898193cedcebf6d0759494eff676cf8c2977ffc005211cf0134e041787e3e8fffd16ed39fe740389504fa27e62e7fdbe1856a978df7e4c1bdbd5 languageName: node linkType: hard @@ -6294,22 +6884,22 @@ __metadata: linkType: hard "@react-navigation/elements@npm:^2.6.5": - version: 2.7.0 - resolution: "@react-navigation/elements@npm:2.7.0" + version: 2.8.2 + resolution: "@react-navigation/elements@npm:2.8.2" dependencies: color: "npm:^4.2.3" use-latest-callback: "npm:^0.2.4" use-sync-external-store: "npm:^1.5.0" peerDependencies: "@react-native-masked-view/masked-view": ">= 0.2.0" - "@react-navigation/native": ^7.1.18 + "@react-navigation/native": ^7.1.20 react: ">= 18.2.0" react-native: "*" react-native-safe-area-context: ">= 4.0.0" peerDependenciesMeta: "@react-native-masked-view/masked-view": optional: true - checksum: 10c0/4128146e14d812681deb885b4505745b2dc47596d4b15cc713fafcb95632efda61e5d1fc75dd9e4bbd503099a866fb1591e08356ebd47bde0405c7a30dc144cf + checksum: 10c0/0e5282f92f2946fd635c2a1c9b444d6d158663ad57669cb87e372587d2313df90cd092737305f999e6223aace75cb7829ef709b1198a8a6bc22aa40821a792e6 languageName: node linkType: hard @@ -6413,7 +7003,7 @@ __metadata: languageName: node linkType: hard -"@react-spring/native@npm:10.0.3": +"@react-spring/native@npm:^10.0.3": version: 10.0.3 resolution: "@react-spring/native@npm:10.0.3" dependencies: @@ -6867,17 +7457,14 @@ __metadata: languageName: node linkType: hard -"@shopify/flash-list@npm:1.8.3": - version: 1.8.3 - resolution: "@shopify/flash-list@npm:1.8.3" - dependencies: - recyclerlistview: "npm:4.2.3" - tslib: "npm:2.8.1" +"@shopify/flash-list@npm:2.2.0": + version: 2.2.0 + resolution: "@shopify/flash-list@npm:2.2.0" peerDependencies: "@babel/runtime": "*" react: "*" react-native: "*" - checksum: 10c0/0900250ce45157d144e3fef4d1cd8c5dfb03495ecb66da1f512697a6834f4eee7bf0755a3772b3c131135784757e5b36566ed365ea0890d9c10ad872885ef650 + checksum: 10c0/ce6bb2096abf1b826e716804106013955c145c0c37d3a277ce294eb0044047af1aeea410fd7c297cc1352b6029b853de5fca2503340f116ccd0281049290625e languageName: node linkType: hard @@ -9743,6 +10330,15 @@ __metadata: languageName: node linkType: hard +"aria-hidden@npm:^1.2.4": + version: 1.2.6 + resolution: "aria-hidden@npm:1.2.6" + dependencies: + tslib: "npm:^2.0.0" + checksum: 10c0/7720cb539497a9f760f68f98a4b30f22c6767aa0e72fa7d58279f7c164e258fc38b2699828f8de881aab0fc8e9c56d1313a3f1a965046fc0381a554dbc72b54a + languageName: node + linkType: hard + "arr-diff@npm:^4.0.0": version: 4.0.0 resolution: "arr-diff@npm:4.0.0" @@ -12308,6 +12904,13 @@ __metadata: languageName: node linkType: hard +"detect-node-es@npm:^1.1.0": + version: 1.1.0 + resolution: "detect-node-es@npm:1.1.0" + checksum: 10c0/e562f00de23f10c27d7119e1af0e7388407eb4b06596a25f6d79a360094a109ff285de317f02b090faae093d314cf6e73ac3214f8a5bb3a0def5bece94557fbe + languageName: node + linkType: hard + "diff-sequences@npm:^29.6.3": version: 29.6.3 resolution: "diff-sequences@npm:29.6.3" @@ -12543,7 +13146,7 @@ __metadata: dependencies: "@artsy/cohesion": "npm:4.346.0" "@artsy/icons": "npm:3.65.0" - "@artsy/palette-mobile": "npm:22.10.0" + "@artsy/palette-mobile": "npm:22.6.0--canary.425.5263.0" "@artsy/to-title-case": "npm:1.2.0" "@artsy/update-repo": "npm:0.8.1" "@babel/core": "npm:7.25.2" @@ -12576,6 +13179,7 @@ __metadata: "@react-native-firebase/app": "npm:23.1.0" "@react-native-firebase/messaging": "npm:23.1.0" "@react-native-google-signin/google-signin": "npm:11.0.1" + "@react-native-menu/menu": "npm:1.2.2" "@react-native/babel-preset": "npm:0.81.5" "@react-native/eslint-config": "npm:0.81.5" "@react-native/metro-config": "npm:0.81.5" @@ -12598,7 +13202,7 @@ __metadata: "@segment/analytics-react-native-plugin-braze": "npm:0.9.0" "@segment/sovran-react-native": "npm:1.1.3" "@sentry/react-native": "npm:7.9.0" - "@shopify/flash-list": "npm:1.8.3" + "@shopify/flash-list": "npm:2.2.0" "@stripe/stripe-react-native": "npm:0.50.3" "@styled-system/theme-get": "npm:5.1.2" "@testing-library/react-native": "npm:13.2.0" @@ -12705,7 +13309,6 @@ __metadata: react-native-blurhash: "npm:2.1.1" react-native-bootsplash: "npm:6.3.10" react-native-collapsible-tab-view: "npm:8.0.1" - react-native-context-menu-view: "git+https://github.com/artsy/react-native-context-menu-view.git#v1.10.10-artsy" react-native-device-info: "npm:14.0.0" react-native-fbsdk-next: "npm:13.4.1" react-native-gesture-handler: "npm:2.28.0" @@ -12713,16 +13316,18 @@ __metadata: react-native-haptic-feedback: "npm:1.13.0" react-native-image-crop-picker: "npm:0.51.0" react-native-in-app-review: "npm:4.3.3" + react-native-ios-context-menu: "npm:3.2.0" + react-native-ios-utilities: "npm:5.2.0" react-native-keyboard-controller: "npm:^1.20.2" react-native-keychain: "npm:10.0.0" react-native-keys: "npm:0.7.13" - react-native-launch-arguments: "npm:4.1.0" + react-native-launch-arguments: "git+https://github.com/artsy/react-native-launch-arguments.git#v4.1.0-new-architecture-2" react-native-linear-gradient: "npm:2.8.3" react-native-localize: "npm:3.5.2" - react-native-pager-view: "npm:6.7.1" + react-native-pager-view: "npm:7.0.1" react-native-performance: "npm:5.1.4" react-native-permissions: "npm:5.4.4" - react-native-reanimated: "npm:3.19.4" + react-native-reanimated: "npm:3.19.5" react-native-reanimated-zoom: "npm:0.3.3" react-native-render-html: "npm:6.3.4" react-native-safe-area-context: "npm:5.6.1" @@ -12764,6 +13369,7 @@ __metadata: victory-native: "npm:37.3.4" yargs: "npm:17.7.2" yup: "npm:0.31.1" + zeego: "npm:^3.0.6" languageName: unknown linkType: soft @@ -15088,6 +15694,13 @@ __metadata: languageName: node linkType: hard +"get-nonce@npm:^1.0.0": + version: 1.0.1 + resolution: "get-nonce@npm:1.0.1" + checksum: 10c0/2d7df55279060bf0568549e1ffc9b84bc32a32b7541675ca092dce56317cdd1a59a98dcc4072c9f6a980779440139a3221d7486f52c488e69dc0fd27b1efb162 + languageName: node + linkType: hard + "get-proto@npm:^1.0.1": version: 1.0.1 resolution: "get-proto@npm:1.0.1" @@ -18183,7 +18796,7 @@ __metadata: languageName: node linkType: hard -"lodash.debounce@npm:4.0.8, lodash.debounce@npm:^4.0.8": +"lodash.debounce@npm:^4.0.8": version: 4.0.8 resolution: "lodash.debounce@npm:4.0.8" checksum: 10c0/762998a63e095412b6099b8290903e0a8ddcb353ac6e2e0f2d7e7d03abd4275fe3c689d88960eb90b0dde4f177554d51a690f22a343932ecbc50a5d111849987 @@ -21012,7 +21625,7 @@ __metadata: languageName: node linkType: hard -"prop-types@npm:*, prop-types@npm:15.8.1, prop-types@npm:^15.5.7, prop-types@npm:^15.8.1": +"prop-types@npm:*, prop-types@npm:^15.5.7, prop-types@npm:^15.8.1": version: 15.8.1 resolution: "prop-types@npm:15.8.1" dependencies: @@ -21377,7 +21990,7 @@ __metadata: languageName: node linkType: hard -"react-nanny@npm:2.15.0": +"react-nanny@npm:^2.15.0": version: 2.15.0 resolution: "react-nanny@npm:2.15.0" peerDependencies: @@ -21409,6 +22022,16 @@ __metadata: languageName: node linkType: hard +"react-native-blurhash@npm:2.1.2": + version: 2.1.2 + resolution: "react-native-blurhash@npm:2.1.2" + peerDependencies: + react: ">=16.8.1" + react-native: ">=0.60.0-rc.0 <1.0.x" + checksum: 10c0/ebce5c07fdbedbe0704272057d0db9d7aa6fa0775d273ba9d080025ab4b60d49367a52c8839d07456bdc54765aaab37c5888c728db2db2bb1a4cce8eee736ed3 + languageName: node + linkType: hard + "react-native-bootsplash@npm:6.3.10": version: 6.3.10 resolution: "react-native-bootsplash@npm:6.3.10" @@ -21454,16 +22077,6 @@ __metadata: languageName: node linkType: hard -"react-native-context-menu-view@git+https://github.com/artsy/react-native-context-menu-view.git#v1.10.10-artsy": - version: 1.10.0 - resolution: "react-native-context-menu-view@https://github.com/artsy/react-native-context-menu-view.git#commit=e5a6bf3abba774936cac9ae2988704f0d7443c14" - peerDependencies: - react: ^16.8.1 || ^17.0.0 || ^18.0.0 - react-native: ">=0.60.0-rc.0 <1.0.x" - checksum: 10c0/d583a3508d9b35754ffddb5a971cf138f04cb3737ae9020a52b3b5a2552e9e2f35ff18491a5851202e211340c34dcffaeef31f2afe974481cb8d82f76d2cbb2e - languageName: node - linkType: hard - "react-native-device-info@npm:14.0.0": version: 14.0.0 resolution: "react-native-device-info@npm:14.0.0" @@ -21537,6 +22150,29 @@ __metadata: languageName: node linkType: hard +"react-native-ios-context-menu@npm:3.2.0": + version: 3.2.0 + resolution: "react-native-ios-context-menu@npm:3.2.0" + dependencies: + "@dominicstop/ts-event-emitter": "npm:^1.1.0" + peerDependencies: + react: "*" + react-native: "*" + react-native-ios-utilities: "*" + checksum: 10c0/1745b5b9722914a7c70cb1abf3111be89f9c67573a545a57c6d621d7ddb6e79e3371e7a1bf0dc1e9005e1013dd70f11f5e1d0ba980ae906af267e5a5755feae0 + languageName: node + linkType: hard + +"react-native-ios-utilities@npm:5.2.0": + version: 5.2.0 + resolution: "react-native-ios-utilities@npm:5.2.0" + peerDependencies: + react: "*" + react-native: "*" + checksum: 10c0/d5d7dadd0aa7bc66ab2cdf5cc39bd38e41f1f7011f34f3a6e7da25fb3e01a126848d415e0605859791ff0675e35a7aec0a3eb888389f25ab7508c72d2d9b8728 + languageName: node + linkType: hard + "react-native-is-edge-to-edge@npm:1.1.7": version: 1.1.7 resolution: "react-native-is-edge-to-edge@npm:1.1.7" @@ -21593,13 +22229,13 @@ __metadata: languageName: node linkType: hard -"react-native-launch-arguments@npm:4.1.0": +"react-native-launch-arguments@git+https://github.com/artsy/react-native-launch-arguments.git#v4.1.0-new-architecture-2": version: 4.1.0 - resolution: "react-native-launch-arguments@npm:4.1.0" + resolution: "react-native-launch-arguments@https://github.com/artsy/react-native-launch-arguments.git#commit=329441de0f5cecd0f421a601c9f9c8cfae8b017e" peerDependencies: react: ">=16.8.1" react-native: ">=0.60.0-rc.0 <1.0.x" - checksum: 10c0/9ab5247ec436dc7741bb4cd43ade834a84b47c6cbe660e8ce6fb042166eac5a1fffbdda1826061a9e3194f114643d5694b01315fd9b451c777dfdc1942d46df1 + checksum: 10c0/5688b748a5cd02a334675293b4748db2660120681586e9dbee04be712f59bc8e983dc3dc4f476ffe66bafaffa050f61bc16589eb0d685a47d8034a5f6ef22508 languageName: node linkType: hard @@ -21640,6 +22276,16 @@ __metadata: languageName: node linkType: hard +"react-native-pager-view@npm:7.0.1": + version: 7.0.1 + resolution: "react-native-pager-view@npm:7.0.1" + peerDependencies: + react: "*" + react-native: "*" + checksum: 10c0/94da200433156b33db6c3fe0b5f1e9c689155177298affd2aea4eef720343eb7d5a1897e211bdb438293e33917317e48a375e607ad9baa14a6d789bb03eccbc4 + languageName: node + linkType: hard + "react-native-performance@npm:5.1.4": version: 5.1.4 resolution: "react-native-performance@npm:5.1.4" @@ -21685,9 +22331,9 @@ __metadata: languageName: node linkType: hard -"react-native-reanimated@npm:3.19.4": - version: 3.19.4 - resolution: "react-native-reanimated@npm:3.19.4" +"react-native-reanimated@npm:3.19.5": + version: 3.19.5 + resolution: "react-native-reanimated@npm:3.19.5" dependencies: "@babel/plugin-transform-arrow-functions": "npm:^7.0.0-0" "@babel/plugin-transform-class-properties": "npm:^7.0.0-0" @@ -21705,7 +22351,7 @@ __metadata: "@babel/core": ^7.0.0-0 react: "*" react-native: "*" - checksum: 10c0/265946c8056812685874cfd502e340ffc289128b90b897f274068608b624a757045686c987403f4557c9bf92753864b205e895dbc8111c7fc995b0943c7c5879 + checksum: 10c0/5da1e142b5c2fefc118a2c6b2bba224deffb98048399b350c22e3496d36ff348ca0d72f7a0b8478db069b1d10e56f42c070c03807fa7e384cf12d9f35c8fc6cf languageName: node linkType: hard @@ -21948,6 +22594,57 @@ __metadata: languageName: node linkType: hard +"react-remove-scroll-bar@npm:^2.3.7": + version: 2.3.8 + resolution: "react-remove-scroll-bar@npm:2.3.8" + dependencies: + react-style-singleton: "npm:^2.2.2" + tslib: "npm:^2.0.0" + peerDependencies: + "@types/react": "*" + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + peerDependenciesMeta: + "@types/react": + optional: true + checksum: 10c0/9a0675c66cbb52c325bdbfaed80987a829c4504cefd8ff2dd3b6b3afc9a1500b8ec57b212e92c1fb654396d07bbe18830a8146fe77677d2a29ce40b5e1f78654 + languageName: node + linkType: hard + +"react-remove-scroll@npm:^2.6.3": + version: 2.7.1 + resolution: "react-remove-scroll@npm:2.7.1" + dependencies: + react-remove-scroll-bar: "npm:^2.3.7" + react-style-singleton: "npm:^2.2.3" + tslib: "npm:^2.1.0" + use-callback-ref: "npm:^1.3.3" + use-sidecar: "npm:^1.1.3" + peerDependencies: + "@types/react": "*" + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc + peerDependenciesMeta: + "@types/react": + optional: true + checksum: 10c0/7ad8f6ffd3e2aedf9b3d79f0c9088a9a3d7c5332d80c923427a6d97fe0626fb4cb33a6d9174d19fad57d860be69c96f68497a0619c3a8af0e8a5332e49bdde31 + languageName: node + linkType: hard + +"react-style-singleton@npm:^2.2.2, react-style-singleton@npm:^2.2.3": + version: 2.2.3 + resolution: "react-style-singleton@npm:2.2.3" + dependencies: + get-nonce: "npm:^1.0.0" + tslib: "npm:^2.0.0" + peerDependencies: + "@types/react": "*" + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc + peerDependenciesMeta: + "@types/react": + optional: true + checksum: 10c0/841938ff16d16a6b76895f4cb2e1fea957e5fe3b30febbf03a54892dae1c9153f2383e231dea0b3ba41192ad2f2849448fa859caccd288943bce32639e971bee + languageName: node + linkType: hard + "react-test-renderer@npm:19.1.0": version: 19.1.0 resolution: "react-test-renderer@npm:19.1.0" @@ -22134,20 +22831,6 @@ __metadata: languageName: node linkType: hard -"recyclerlistview@npm:4.2.3": - version: 4.2.3 - resolution: "recyclerlistview@npm:4.2.3" - dependencies: - lodash.debounce: "npm:4.0.8" - prop-types: "npm:15.8.1" - ts-object-utils: "npm:0.0.5" - peerDependencies: - react: ">= 15.2.1" - react-native: ">= 0.30.0" - checksum: 10c0/40b8b948d09f560ce98842e9141d2ce7ee5677ae2c20f7e30de901136d7764a42cc4e5ba3242fca0934055d5fef99c5b03430fcba28d7cfc27155b4ef97f70d5 - languageName: node - linkType: hard - "redent@npm:^3.0.0": version: 3.0.0 resolution: "redent@npm:3.0.0" @@ -23272,6 +23955,13 @@ __metadata: languageName: node linkType: hard +"sf-symbols-typescript@npm:^2.0.0": + version: 2.1.0 + resolution: "sf-symbols-typescript@npm:2.1.0" + checksum: 10c0/b6e2482c2b3ba785aa00770013e343a2175475b9cb7c8703c30a2ec1da8b41acd982db2d953877afb35af32a3dfba337d0b29e703c399cd2138c3cf68685c9c2 + languageName: node + linkType: hard + "shallowequal@npm:1.1.0": version: 1.1.0 resolution: "shallowequal@npm:1.1.0" @@ -24743,13 +25433,6 @@ __metadata: languageName: node linkType: hard -"ts-object-utils@npm:0.0.5": - version: 0.0.5 - resolution: "ts-object-utils@npm:0.0.5" - checksum: 10c0/0279f8a7504b3905f2b14769769985f214154f1aedc60077c3baaced078369ae465aecc6acc04c614f40893e559d05697f6f4ef9fc411e3b6d1d15e6269a5e14 - languageName: node - linkType: hard - "ts-toolbelt@npm:^6.15.1": version: 6.15.5 resolution: "ts-toolbelt@npm:6.15.5" @@ -24783,13 +25466,6 @@ __metadata: languageName: node linkType: hard -"tslib@npm:2.8.1, tslib@npm:^2.1.0, tslib@npm:^2.3.0, tslib@npm:^2.3.1": - version: 2.8.1 - resolution: "tslib@npm:2.8.1" - checksum: 10c0/9c4759110a19c53f992d9aae23aac5ced636e99887b51b9e61def52611732872ff7668757d4e4c61f19691e36f4da981cd9485e869b4a7408d689f6bf1f14e62 - languageName: node - linkType: hard - "tslib@npm:^1.10.0, tslib@npm:^1.8.1, tslib@npm:^1.9.0": version: 1.14.1 resolution: "tslib@npm:1.14.1" @@ -24797,6 +25473,13 @@ __metadata: languageName: node linkType: hard +"tslib@npm:^2.0.0, tslib@npm:^2.1.0, tslib@npm:^2.3.0, tslib@npm:^2.3.1": + version: 2.8.1 + resolution: "tslib@npm:2.8.1" + checksum: 10c0/9c4759110a19c53f992d9aae23aac5ced636e99887b51b9e61def52611732872ff7668757d4e4c61f19691e36f4da981cd9485e869b4a7408d689f6bf1f14e62 + languageName: node + linkType: hard + "tslib@npm:^2.0.1": version: 2.3.1 resolution: "tslib@npm:2.3.1" @@ -25335,6 +26018,21 @@ __metadata: languageName: node linkType: hard +"use-callback-ref@npm:^1.3.3": + version: 1.3.3 + resolution: "use-callback-ref@npm:1.3.3" + dependencies: + tslib: "npm:^2.0.0" + peerDependencies: + "@types/react": "*" + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc + peerDependenciesMeta: + "@types/react": + optional: true + checksum: 10c0/f887488c6e6075cdad4962979da1714b217bcb1ee009a9e57ce9a844bcfc4c3a99e93983dfc2e5af9e0913824d24e730090ff255e902c516dcb58d2d3837e01c + languageName: node + linkType: hard + "use-deep-compare@npm:^1.1.0": version: 1.3.0 resolution: "use-deep-compare@npm:1.3.0" @@ -25355,6 +26053,22 @@ __metadata: languageName: node linkType: hard +"use-sidecar@npm:^1.1.3": + version: 1.1.3 + resolution: "use-sidecar@npm:1.1.3" + dependencies: + detect-node-es: "npm:^1.1.0" + tslib: "npm:^2.0.0" + peerDependencies: + "@types/react": "*" + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc + peerDependenciesMeta: + "@types/react": + optional: true + checksum: 10c0/161599bf921cfaa41c85d2b01c871975ee99260f3e874c2d41c05890d41170297bdcf314bc5185e7a700de2034ac5b888e3efc8e9f35724f4918f53538d717c9 + languageName: node + linkType: hard + "use-sync-external-store@npm:^1.4.0": version: 1.6.0 resolution: "use-sync-external-store@npm:1.6.0" @@ -26646,6 +27360,23 @@ __metadata: languageName: node linkType: hard +"zeego@npm:^3.0.6": + version: 3.0.6 + resolution: "zeego@npm:3.0.6" + dependencies: + "@radix-ui/react-context-menu": "npm:^2.0.1" + "@radix-ui/react-dropdown-menu": "npm:^2.0.1" + sf-symbols-typescript: "npm:^2.0.0" + peerDependencies: + "@react-native-menu/menu": 1.2.2 + react: "*" + react-native: "*" + react-native-ios-context-menu: 3.1.0 + react-native-ios-utilities: 5.1.2 + checksum: 10c0/76eec9ca0cee085da0bb50188ee08d6d67e3b2b2ea17b0a30e34fb3e39cd67a75d2650bdd4f5c593aec89cd778622d083dd20c61fd6adebe5ca01d694ac30fd5 + languageName: node + linkType: hard + "zod-to-json-schema@npm:^3.24.6": version: 3.24.6 resolution: "zod-to-json-schema@npm:3.24.6"