diff --git a/package.json b/package.json index c1a3bb47b2..1772d619fe 100644 --- a/package.json +++ b/package.json @@ -98,10 +98,9 @@ "@miblanchard/react-native-slider": "^2.6.0", "@mozzius/expo-dynamic-app-icon": "^1.8.0", "@react-native-async-storage/async-storage": "2.2.0", - "@react-navigation/bottom-tabs": "^7.3.13", - "@react-navigation/drawer": "^7.3.12", - "@react-navigation/native": "^7.1.9", - "@react-navigation/native-stack": "^7.3.13", + "@react-navigation/bottom-tabs": "^7.9.0", + "@react-navigation/native": "^7.1.26", + "@react-navigation/native-stack": "^7.9.0", "@sentry/react-native": "~6.20.0", "@tanstack/query-async-storage-persister": "^5.25.0", "@tanstack/react-query": "5.25.0", @@ -194,7 +193,7 @@ "react-native-compressor": "^1.13.0", "react-native-date-picker": "^5.0.13", "react-native-device-attest": "^0.1.6", - "react-native-drawer-layout": "^4.1.8", + "react-native-drawer-layout": "^4.2.1", "react-native-edge-to-edge": "^1.6.0", "react-native-gesture-handler": "~2.28.0", "react-native-get-random-values": "~1.11.0", @@ -204,7 +203,7 @@ "react-native-qrcode-styled": "^0.3.3", "react-native-reanimated": "^3.19.1", "react-native-safe-area-context": "~5.6.0", - "react-native-screens": "~4.16.0", + "react-native-screens": "^4.19.0", "react-native-svg": "15.12.1", "react-native-uitextview": "^1.4.0", "react-native-url-polyfill": "^1.3.0", diff --git a/patches/react-native-drawer-layout+4.1.10.patch b/patches/react-native-drawer-layout+4.2.1.patch similarity index 94% rename from patches/react-native-drawer-layout+4.1.10.patch rename to patches/react-native-drawer-layout+4.2.1.patch index d4c0731f5e..ffa36db105 100644 --- a/patches/react-native-drawer-layout+4.1.10.patch +++ b/patches/react-native-drawer-layout+4.2.1.patch @@ -1,5 +1,5 @@ diff --git a/node_modules/react-native-drawer-layout/lib/module/views/Drawer.native.js b/node_modules/react-native-drawer-layout/lib/module/views/Drawer.native.js -index efa71f9..a23c624 100644 +index 40fdcdb..770fd67 100644 --- a/node_modules/react-native-drawer-layout/lib/module/views/Drawer.native.js +++ b/node_modules/react-native-drawer-layout/lib/module/views/Drawer.native.js @@ -124,15 +124,21 @@ export function Drawer({ @@ -31,7 +31,7 @@ index efa71f9..a23c624 100644 - }, finished => runOnJS(onAnimationEnd)(open, finished)); + }, finished => { + animatingTo.value = null; -+ runOnJS(onAnimationEnd)(open, finished) ++ runOnJS(onAnimationEnd)(open, finished); + }); if (open) { runOnJS(onOpen)(); diff --git a/patches/react-native-screens+4.16.0.patch b/patches/react-native-screens+4.16.0.patch deleted file mode 100644 index 8be75c770f..0000000000 --- a/patches/react-native-screens+4.16.0.patch +++ /dev/null @@ -1,326 +0,0 @@ -diff --git a/node_modules/react-native-screens/ios/RNSScreen.mm b/node_modules/react-native-screens/ios/RNSScreen.mm -index b62a2e2..cb469db 100644 ---- a/node_modules/react-native-screens/ios/RNSScreen.mm -+++ b/node_modules/react-native-screens/ios/RNSScreen.mm -@@ -729,9 +729,26 @@ - (void)notifyTransitionProgress:(double)progress closing:(BOOL)closing goingFor - #endif - } - --#if !RCT_NEW_ARCH_ENABLED -+- (void)willMoveToWindow:(UIWindow *)newWindow -+{ -+ if (@available(iOS 26, *)) { -+ // In iOS 26, as soon as another screen appears in transition, it is interactable -+ // To avoid glitches resulting from clicking buttons mid transition, we temporarily disable all interactions -+ // Disabling interactions for parent navigation controller won't be enough in case of nested stack -+ // Furthermore, a stack put inside a modal will exist in an entirely different hierarchy -+ // To be sure, we block interactions on the whole window. -+ // Note that newWindows is nil when moving from instead of moving to, and Obj-C handles nil correctly -+ newWindow.userInteractionEnabled = false; -+ } -+} -+ - - (void)presentationControllerWillDismiss:(UIPresentationController *)presentationController - { -+ if (@available(iOS 26, *)) { -+ // Disable interactions to disallow multiple modals dismissed at once; see willMoveToWindow -+ presentationController.containerView.window.userInteractionEnabled = false; -+ } -+#if !RCT_NEW_ARCH_ENABLED - // On Paper, we need to call both "cancel" and "reset" here because RN's gesture - // recognizer does not handle the scenario when it gets cancelled by other top - // level gesture recognizer. In this case by the modal dismiss gesture. -@@ -744,8 +761,8 @@ - (void)presentationControllerWillDismiss:(UIPresentationController *)presentati - // down. - [_touchHandler cancel]; - [_touchHandler reset]; --} - #endif // !RCT_NEW_ARCH_ENABLED -+} - - - (BOOL)presentationControllerShouldDismiss:(UIPresentationController *)presentationController - { -@@ -757,6 +774,10 @@ - (BOOL)presentationControllerShouldDismiss:(UIPresentationController *)presenta - - - (void)presentationControllerDidAttemptToDismiss:(UIPresentationController *)presentationController - { -+ if (@available(iOS 26, *)) { -+ // Reenable interactions; see presentationControllerWillDismiss -+ presentationController.containerView.window.userInteractionEnabled = true; -+ } - // NOTE(kkafar): We should consider depracating the use of gesture cancel here & align - // with usePreventRemove API of react-navigation v7. - [self notifyGestureCancel]; -@@ -767,6 +788,11 @@ - (void)presentationControllerDidAttemptToDismiss:(UIPresentationController *)pr - - - (void)presentationControllerDidDismiss:(UIPresentationController *)presentationController - { -+ if (@available(iOS 26, *)) { -+ // Reenable interactions; see presentationControllerWillDismiss -+ // Dismissed screen doesn't hold a reference to window, but presentingViewController.view does -+ presentationController.presentingViewController.view.window.userInteractionEnabled = true; -+ } - if ([_reactSuperview respondsToSelector:@selector(presentationControllerDidDismiss:)]) { - [_reactSuperview performSelector:@selector(presentationControllerDidDismiss:) withObject:presentationController]; - } -@@ -1518,6 +1544,10 @@ - (void)viewWillDisappear:(BOOL)animated - - - (void)viewDidAppear:(BOOL)animated - { -+ if (@available(iOS 26, *)) { -+ // Reenable interactions, see willMoveToWindow -+ self.view.window.userInteractionEnabled = true; -+ } - [super viewDidAppear:animated]; - if (!_isSwiping || _shouldNotify) { - // we are going forward or dismissing without swipe -diff --git a/node_modules/react-native-screens/ios/RNSScreenStack.mm b/node_modules/react-native-screens/ios/RNSScreenStack.mm -index 229dc58..10b365b 100644 ---- a/node_modules/react-native-screens/ios/RNSScreenStack.mm -+++ b/node_modules/react-native-screens/ios/RNSScreenStack.mm -@@ -62,26 +62,6 @@ @interface RNSScreenStackView () < - - @implementation RNSNavigationController - --#if RNS_IPHONE_OS_VERSION_AVAILABLE(26_0) --- (void)viewDidLoad --{ -- // iOS 26 introduces new gesture recognizer which replaces our RNSPanGestureRecognizer. -- // The problem is that we are not able to handle it here for various reasons: -- // - the new recognizer comes with its own delegate and our current approach is to wire -- // all recognizers to RNSScreenStackView; to be 100% sure we don't break the logic, -- // we would have to decorate its delegate and call it after our code, which would -- // break other recognizers that the stack view is the delegate for -- // - when RNSScreenStackView.setupGestureHandler method is called, the recognizer hasn't been -- // loaded yet and there is no other place to configure in a not "hacky" way -- // - the official docs warn us to not use it for anything other than "setting up failure requirements with it" -- // - we expose fullScreenGestureEnabled prop to enable/disable the feature, -- // so we need control over the delegate -- if (@available(iOS 26.0, *)) { -- self.interactiveContentPopGestureRecognizer.enabled = NO; -- } --} --#endif // iOS 26 -- - #if !TARGET_OS_TV - - (UIViewController *)childViewControllerForStatusBarStyle - { -@@ -219,50 +199,6 @@ - (bool)onRepeatedTabSelectionOfTabScreenController:(RNSTabsScreenViewController - return false; - } - --#pragma mark - UINavigationBarDelegate -- --#if RNS_IPHONE_OS_VERSION_AVAILABLE(26_0) --- (BOOL)navigationBar:(UINavigationBar *)navigationBar shouldPopItem:(UINavigationItem *)item --{ -- if (@available(iOS 26, *)) { -- // To prevent popping multiple screens when back button is pressed repeatedly, -- // We allow for pop operation to proceed only if no transition is in progress, -- // which we check indirectly by checking if transitionCoordinator is set. -- // If it's not, we are safe to proceed. -- if (self.transitionCoordinator == nil) { -- // We still need to disable interactions for back button so click effects are not applied, -- // and there is unfortunately no better place for it currently -- UIView *button = [navigationBar rnscreens_findBackButtonWrapperView]; -- if (button != nil) { -- button.userInteractionEnabled = false; -- } -- -- return true; -- } -- -- return false; -- } -- -- return true; --} -- --- (void)navigationBar:(UINavigationBar *)navigationBar didPopItem:(UINavigationItem *)item --{ -- if (@available(iOS 26, *)) { -- // Reset interactions on back button -> see navigationBar:shouldPopItem -- // IMPORTANT: This reset won't execute when preventNativeDismiss is on. -- // However, on iOS 26, unlike in previous versions, the back button instance changes -- // when handling preventNativeDismiss and userIteractionEnabled is reset. -- // The instance also changes when regular screen pop happens, but in that case -- // the value of userInteractionEnabled is carried on, and we reset it here. -- UIView *button = [navigationBar rnscreens_findBackButtonWrapperView]; -- if (button != nil) { -- button.userInteractionEnabled = true; -- } -- } --} --#endif // Check for iOS >= 26 -- - #pragma mark - RNSFrameCorrectionProvider - - #ifdef RNS_GAMMA_ENABLED -@@ -327,7 +263,7 @@ @implementation RNSScreenStackView { - UINavigationController *_controller; - NSMutableArray *_reactSubviews; - BOOL _invalidated; -- BOOL _isFullWidthSwiping; -+ BOOL _isFullWidthSwipingWithPanGesture; // used only for content swipe with RNSPanGestureRecognizer - RNSPercentDrivenInteractiveTransition *_interactionController; - __weak RNSScreenStackManager *_manager; - BOOL _updateScheduled; -@@ -522,6 +458,11 @@ - (void)reactAddControllerToClosestParent:(UIViewController *)controller - [self addSubview:controller.view]; - #if !TARGET_OS_TV - _controller.interactivePopGestureRecognizer.delegate = self; -+ #if RNS_IPHONE_OS_VERSION_AVAILABLE(26_0) -+ if (@available(iOS 26, *)) { -+ _controller.interactiveContentPopGestureRecognizer.delegate = self; -+ } -+#endif // Check for iOS >= 26.0 - #endif - [controller didMoveToParentViewController:parentView.reactViewController]; - // On iOS pre 12 we observed that `willShowViewController` delegate method does not always -@@ -943,7 +884,7 @@ - (void)dismissOnReload - // when preventing the native dismiss with back button, we have to return the animator. - // Also, we need to return the animator when full width swiping even if the animation is not custom, - // otherwise the screen will be just popped immediately due to no animation -- ((operation == UINavigationControllerOperationPop && shouldCancelDismiss) || _isFullWidthSwiping || -+ ((operation == UINavigationControllerOperationPop && shouldCancelDismiss) || _isFullWidthSwipingWithPanGesture || - [RNSScreenStackAnimator isCustomAnimation:screen.stackAnimation] || _customAnimation)) { - return [[RNSScreenStackAnimator alloc] initWithOperation:operation]; - } -@@ -967,23 +908,39 @@ - (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer - } - RNSScreenView *topScreen = _reactSubviews.lastObject; - -+ BOOL customAnimationOnSwipePropSetAndSelectedAnimationIsCustom = -+ topScreen.customAnimationOnSwipe && [RNSScreenStackAnimator isCustomAnimation:topScreen.stackAnimation]; -+ - #if TARGET_OS_TV || TARGET_OS_VISION - [self cancelTouchesInParent]; - return YES; - #else -- // RNSPanGestureRecognizer will receive events iff topScreen.fullScreenSwipeEnabled == YES; -- // Events are filtered in gestureRecognizer:shouldReceivePressOrTouchEvent: method - if ([gestureRecognizer isKindOfClass:[RNSPanGestureRecognizer class]]) { -- if ([self isInGestureResponseDistance:gestureRecognizer topScreen:topScreen]) { -- _isFullWidthSwiping = YES; -- [self cancelTouchesInParent]; -- return YES; -+ // On iOS < 26, we have a custom full screen swipe recognizer that functions similarily -+ // to interactiveContentPopGestureRecognizer introduced in iOS 26. -+ // On iOS >= 26, we want to use the native one, but we are unable to handle custom animations -+ // with native interactiveContentPopGestureRecognizer, so we have to fallback to the old implementation. -+ // In this case, the old one should behave as close as the new native one, having only the difference -+ // in animation, and without any customization that is exclusive for it (e.g. gestureResponseDistance). -+ if (@available(iOS 26, *)) { -+ if (customAnimationOnSwipePropSetAndSelectedAnimationIsCustom) { -+ _isFullWidthSwipingWithPanGesture = YES; -+ [self cancelTouchesInParent]; -+ return YES; -+ } -+ return NO; -+ } else { -+ if ([self isInGestureResponseDistance:gestureRecognizer topScreen:topScreen]) { -+ _isFullWidthSwipingWithPanGesture = YES; -+ [self cancelTouchesInParent]; -+ return YES; -+ } -+ return NO; - } -- return NO; - } - - // Now we're dealing with RNSScreenEdgeGestureRecognizer (or _UIParallaxTransitionPanGestureRecognizer) -- if (topScreen.customAnimationOnSwipe && [RNSScreenStackAnimator isCustomAnimation:topScreen.stackAnimation]) { -+ if (customAnimationOnSwipePropSetAndSelectedAnimationIsCustom) { - if ([gestureRecognizer isKindOfClass:[RNSScreenEdgeGestureRecognizer class]]) { - UIRectEdge edges = ((RNSScreenEdgeGestureRecognizer *)gestureRecognizer).edges; - BOOL isRTL = _controller.view.semanticContentAttribute == UISemanticContentAttributeForceRightToLeft; -@@ -1028,7 +985,9 @@ - (void)setupGestureHandlers - rightEdgeSwipeGestureRecognizer.delegate = self; - [self addGestureRecognizer:rightEdgeSwipeGestureRecognizer]; - -- // gesture recognizer for full width swipe gesture -+ // Starting from iOS 26, RNSPanGestureRecognizer has been mostly replaced by native -+ // interactiveContentPopGestureRecognizer. It still needs to handle custom dismiss animations, -+ // which we are not able to handle with the latter. - RNSPanGestureRecognizer *panRecognizer = [[RNSPanGestureRecognizer alloc] initWithTarget:self - action:@selector(handleSwipe:)]; - panRecognizer.delegate = self; -@@ -1091,7 +1050,7 @@ - (void)handleSwipe:(UIPanGestureRecognizer *)gestureRecognizer - [_interactionController cancelInteractiveTransition]; - } - _interactionController = nil; -- _isFullWidthSwiping = NO; -+ _isFullWidthSwipingWithPanGesture = NO; - } - default: { - break; -@@ -1225,14 +1184,6 @@ - (BOOL)isScrollViewPanGestureRecognizer:(UIGestureRecognizer *)gestureRecognize - // Be careful when adding another type of gesture recognizer. - - (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceivePressOrTouchEvent:(NSObject *)event - { -- if (@available(iOS 26, *)) { -- // in iOS 26, you can swipe to pop screen before the previous one finished transitioning; -- // this prevents from registering the second gesture -- if ([self isTransitionInProgress]) { -- return NO; -- } -- } -- - RNSScreenView *topScreen = _reactSubviews.lastObject; - - for (RNSScreenView *s in _reactSubviews.reverseObjectEnumerator) { -@@ -1249,10 +1200,30 @@ - (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceive - return NO; - } - -+ BOOL customAnimationOnSwipePropSetAndSelectedAnimationIsCustom = -+ topScreen.customAnimationOnSwipe && [RNSScreenStackAnimator isCustomAnimation:topScreen.stackAnimation]; -+#if RNS_IPHONE_OS_VERSION_AVAILABLE(26_0) -+ if (@available(iOS 26, *)) { -+ // On iOS 26, fullScreenSwipeEnabled takes no effect, and depending on whether custom animations are on, -+ // we select either interactiveContentPopGestureRecognizer or RNSPanGestureRecognizer -+ if (([gestureRecognizer isKindOfClass:[RNSPanGestureRecognizer class]] && -+ !customAnimationOnSwipePropSetAndSelectedAnimationIsCustom) || -+ (gestureRecognizer == _controller.interactiveContentPopGestureRecognizer && -+ customAnimationOnSwipePropSetAndSelectedAnimationIsCustom)) { -+ return NO; -+ } -+ } else { -+ // We want to pass events to RNSPanGestureRecognizer iff full screen swipe is enabled. -+ if ([gestureRecognizer isKindOfClass:[RNSPanGestureRecognizer class]]) { -+ return topScreen.fullScreenSwipeEnabled; -+ } -+ } -+#else // check for iOS >= 26 - // We want to pass events to RNSPanGestureRecognizer iff full screen swipe is enabled. - if ([gestureRecognizer isKindOfClass:[RNSPanGestureRecognizer class]]) { - return topScreen.fullScreenSwipeEnabled; - } -+#endif // check for iOS >= 26 - - // RNSScreenEdgeGestureRecognizer || _UIParallaxTransitionPanGestureRecognizer - return YES; -@@ -1268,15 +1239,6 @@ - (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceive - return [self gestureRecognizer:gestureRecognizer shouldReceivePressOrTouchEvent:touch]; - } - --- (BOOL)isTransitionInProgress --{ -- if (_controller.transitionCoordinator != nil) { -- return YES; -- } -- -- return NO; --} -- - - (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer - shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer - { -@@ -1289,7 +1251,6 @@ - (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer - if (gestureRecognizer.state == UIGestureRecognizerStateBegan || isBackGesture) { - return NO; - } -- - return YES; - } - return NO; diff --git a/src/Navigation.tsx b/src/Navigation.tsx index 3e68bd07df..fda4f41529 100644 --- a/src/Navigation.tsx +++ b/src/Navigation.tsx @@ -5,6 +5,7 @@ import {i18n, type MessageDescriptor} from '@lingui/core' import {msg} from '@lingui/macro' import { type BottomTabBarProps, + type BottomTabNavigatorProps, createBottomTabNavigator, } from '@react-navigation/bottom-tabs' import { @@ -636,7 +637,7 @@ function commonScreens(Stack: typeof Flat, unreadCountLabel?: string) { * The TabsNavigator is used by native mobile to represent the routes * in 3 distinct tab-stacks with a different root screen on each. */ -function TabsNavigator() { +function TabsNavigator({layout}: {layout: BottomTabNavigatorProps['layout']}) { const tabBar = useCallback( (props: JSX.IntrinsicAttributes & BottomTabBarProps) => ( @@ -649,7 +650,8 @@ function TabsNavigator() { initialRouteName="HomeTab" backBehavior="initialRoute" screenOptions={{headerShown: false, lazy: true}} - tabBar={tabBar}> + tabBar={tabBar} + layout={layout}> HomeTabNavigator} /> SearchTabNavigator} /> (StackRouter, { id, initialRouteName, + UNSTABLE_routeNamesChangeBehavior, children, layout, screenListeners, screenOptions, screenLayout, + UNSTABLE_router, }) React.useEffect( @@ -169,7 +173,7 @@ function NativeStackNavigator({ export function createNativeStackNavigatorWithAuth< const ParamList extends ParamListBase, - const NavigatorID extends string | undefined = undefined, + const NavigatorID extends string | undefined = string | undefined, const TypeBag extends NavigatorTypeBagBase = { ParamList: ParamList NavigatorID: NavigatorID diff --git a/src/view/shell/index.tsx b/src/view/shell/index.tsx index 7f53755fcf..e316537bc0 100644 --- a/src/view/shell/index.tsx +++ b/src/view/shell/index.tsx @@ -91,14 +91,19 @@ function ShellInner() { } }, [dedupe, navigation]) + const drawerLayout = useCallback( + ({children}: {children: React.ReactNode}) => ( + {children} + ), + [], + ) + return ( <> - - - + diff --git a/yarn.lock b/yarn.lock index 1d0533bca6..f38ca739e9 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6549,67 +6549,63 @@ invariant "^2.2.4" nullthrows "^1.1.1" -"@react-navigation/bottom-tabs@^7.3.13": - version "7.3.14" - resolved "https://registry.yarnpkg.com/@react-navigation/bottom-tabs/-/bottom-tabs-7.3.14.tgz#9ee02baea86ab24abe267726665bc69c6df0bf4c" - integrity sha512-s2qinJggS2HYZdCOey9A+fN+bNpWeEKwiL/FjAVOTcv+uofxPWN6CtEZUZGPEjfRjis/srURBmCmpNZSI6sQ9Q== +"@react-navigation/bottom-tabs@^7.9.0": + version "7.9.0" + resolved "https://registry.yarnpkg.com/@react-navigation/bottom-tabs/-/bottom-tabs-7.9.0.tgz#b546adb0cedd72a1f0179e00b74039b3c8abb6bd" + integrity sha512-024FWdHp3ZsE5rP8tmGI4vh+1z3wg8u8E9Frep8eeGoYo1h9rQhvgofQDGxknmrKsb7t8o8Dim+IZSvl57cPFQ== dependencies: - "@react-navigation/elements" "^2.4.3" + "@react-navigation/elements" "^2.9.3" color "^4.2.3" + sf-symbols-typescript "^2.1.0" -"@react-navigation/core@^7.10.0": - version "7.10.0" - resolved "https://registry.yarnpkg.com/@react-navigation/core/-/core-7.10.0.tgz#8205ea6b84ce34b2fc2c196701b4cd9b434211b9" - integrity sha512-qZBA5gGm+9liT4+EHk+kl9apwvqh7HqhLF1XeX6SQRmC/n2QI0u1B8OevKc+EPUDEM9Od15IuwT/GRbSs7/Umw== +"@react-navigation/core@^7.13.7": + version "7.13.7" + resolved "https://registry.yarnpkg.com/@react-navigation/core/-/core-7.13.7.tgz#1263903a703b5f183a08c22dfc5c3735ac4ef91c" + integrity sha512-k2ABo3250vq1ovOh/iVwXS6Hwr5PVRGXoPh/ewVFOOuEKTvOx9i//OBzt8EF+HokBxS2HBRlR2b+aCOmscRqBw== dependencies: - "@react-navigation/routers" "^7.4.0" - escape-string-regexp "^4.0.0" - nanoid "^3.3.11" - query-string "^7.1.3" - react-is "^19.1.0" - use-latest-callback "^0.2.3" - use-sync-external-store "^1.5.0" - -"@react-navigation/drawer@^7.3.12": - version "7.4.1" - resolved "https://registry.yarnpkg.com/@react-navigation/drawer/-/drawer-7.4.1.tgz#50517d8c57f09cdbfc20a485c47016066b918e76" - integrity sha512-kj5wL31smDLw/6l+0KPR5cjaOZg6oHJCl3RPQonFPuYolUPZBVnuS++uvlifWcD/mqdGmhl3rgLTircRH4vQ7Q== - dependencies: - "@react-navigation/elements" "^2.4.3" - color "^4.2.3" - react-native-drawer-layout "^4.1.10" - use-latest-callback "^0.2.3" - -"@react-navigation/elements@^2.4.3": - version "2.4.3" - resolved "https://registry.yarnpkg.com/@react-navigation/elements/-/elements-2.4.3.tgz#cc1dde4c98739d35a0c9c23872316063962cfaee" - integrity sha512-psoNmnZ0DQIt9nxxPITVLtYW04PGCAfnmd/Pcd3yhiBs93aj+HYKH+SDZDpUnXMf3BN7Wvo4+jPI+/Xjqb+m9w== - dependencies: - color "^4.2.3" - -"@react-navigation/native-stack@^7.3.13": - version "7.3.14" - resolved "https://registry.yarnpkg.com/@react-navigation/native-stack/-/native-stack-7.3.14.tgz#d1c90f2e50cd13bbced923991cf2faee8083f725" - integrity sha512-45Sf7ReqSCIySXS5nrKtLGmNlFXm5x+u32YQMwKDONCqVGOBCfo4ryKqeQq1EMJ7Py6IDyOwHMhA+jhNOxnfPw== - dependencies: - "@react-navigation/elements" "^2.4.3" - warn-once "^0.1.1" - -"@react-navigation/native@^7.1.9": - version "7.1.10" - resolved "https://registry.yarnpkg.com/@react-navigation/native/-/native-7.1.10.tgz#768f674f7c09b6a57215762052aa62a7dc107402" - integrity sha512-Ug4IML0DkAxZTMF/E7lyyLXSclkGAYElY2cxZWITwfBjtlVeda0NjsdnTWY5EGjnd7bwvhTIUC+CO6qSlrDn5A== - dependencies: - "@react-navigation/core" "^7.10.0" + "@react-navigation/routers" "^7.5.3" escape-string-regexp "^4.0.0" fast-deep-equal "^3.1.3" nanoid "^3.3.11" - use-latest-callback "^0.2.3" + query-string "^7.1.3" + react-is "^19.1.0" + use-latest-callback "^0.2.4" + use-sync-external-store "^1.5.0" -"@react-navigation/routers@^7.4.0": - version "7.4.0" - resolved "https://registry.yarnpkg.com/@react-navigation/routers/-/routers-7.4.0.tgz#5bace799713ac163310c18711b98dfbe418c6b36" - integrity sha512-th5THnuWKJlmr7GGHiicy979di11ycDWub9iIXbEDvQwmwmsRzppmVbfs2nD8bC/MgyMgqWu/gxfys+HqN+kcw== +"@react-navigation/elements@^2.9.3": + version "2.9.3" + resolved "https://registry.yarnpkg.com/@react-navigation/elements/-/elements-2.9.3.tgz#505ae38af347a0bc5326155318a3d9a54e2071e3" + integrity sha512-3+eyvWiVPIEf6tN9UdduhOEHcTuNe3R5WovgiVkfH9+jApHMTZDc2loePTpY/i2HDJhObhhChpJzO6BVjrpdYQ== + dependencies: + color "^4.2.3" + use-latest-callback "^0.2.4" + use-sync-external-store "^1.5.0" + +"@react-navigation/native-stack@^7.9.0": + version "7.9.0" + resolved "https://registry.yarnpkg.com/@react-navigation/native-stack/-/native-stack-7.9.0.tgz#4fcd08a403ff86c465a908f3b49f86ab3f66d06a" + integrity sha512-C/mNPhI0Pnerl7C2cB+6fAkdgSmfKECMERrbyfjx3P6JmEuTC54o+GV1c62FUmlRaRUassVHbtw4EeaY2uLh0g== + dependencies: + "@react-navigation/elements" "^2.9.3" + color "^4.2.3" + sf-symbols-typescript "^2.1.0" + warn-once "^0.1.1" + +"@react-navigation/native@^7.1.26": + version "7.1.26" + resolved "https://registry.yarnpkg.com/@react-navigation/native/-/native-7.1.26.tgz#220672e115f39014b95ca3ce8f2c37076a0e74f4" + integrity sha512-RhKmeD0E2ejzKS6z8elAfdfwShpcdkYY8zJzvHYLq+wv183BBcElTeyMLcIX6wIn7QutXeI92Yi21t7aUWfqNQ== + dependencies: + "@react-navigation/core" "^7.13.7" + escape-string-regexp "^4.0.0" + fast-deep-equal "^3.1.3" + nanoid "^3.3.11" + use-latest-callback "^0.2.4" + +"@react-navigation/routers@^7.5.3": + version "7.5.3" + resolved "https://registry.yarnpkg.com/@react-navigation/routers/-/routers-7.5.3.tgz#8002930ef5f62351be2475d0dffde3ffaee174d7" + integrity sha512-1tJHg4KKRJuQ1/EvJxatrMef3NZXEPzwUIUZ3n1yJ2t7Q97siwRtbynRpQG9/69ebbtiZ8W3ScOZF/OmhvM4Rg== dependencies: nanoid "^3.3.11" @@ -17055,12 +17051,13 @@ react-native-dotenv@^3.4.11: dependencies: dotenv "^16.4.5" -react-native-drawer-layout@^4.1.10, react-native-drawer-layout@^4.1.8: - version "4.1.10" - resolved "https://registry.yarnpkg.com/react-native-drawer-layout/-/react-native-drawer-layout-4.1.10.tgz#9007cb747767ca8e1c9c3337671ad35ed95ad4d9" - integrity sha512-wejQo0F+EffCkOkRh+DP6ENWMB+aWEHkXV8Pd564PmtoySZLUsV/ksYrh/mrufh7T7EuvGT8+fNHz7mMRYftWg== +react-native-drawer-layout@^4.2.1: + version "4.2.1" + resolved "https://registry.yarnpkg.com/react-native-drawer-layout/-/react-native-drawer-layout-4.2.1.tgz#5c89425662c9b5216a227dbc87bc7f38c4ec8719" + integrity sha512-liwRJ7ynRU/ogRlUdiK1Yoi1VzUSq2Vu/RU+UgqlMB3XduslZ1DZg/mTX0f1uCEV2dJ4ec+1fRa3OlIierfyZg== dependencies: - use-latest-callback "^0.2.3" + color "^4.2.3" + use-latest-callback "^0.2.4" react-native-edge-to-edge@^1.6.0: version "1.6.0" @@ -17149,13 +17146,12 @@ react-native-safe-area-context@~5.6.0: resolved "https://registry.yarnpkg.com/react-native-safe-area-context/-/react-native-safe-area-context-5.6.1.tgz#cb4d249ef1a6f7e8fd0cfdfa9764838dffda26b6" integrity sha512-/wJE58HLEAkATzhhX1xSr+fostLsK8Q97EfpfMDKo8jlOc1QKESSX/FQrhk7HhQH/2uSaox4Y86sNaI02kteiA== -react-native-screens@~4.16.0: - version "4.16.0" - resolved "https://registry.yarnpkg.com/react-native-screens/-/react-native-screens-4.16.0.tgz#efa42e77a092aa0b5277c9ae41391ea0240e0870" - integrity sha512-yIAyh7F/9uWkOzCi1/2FqvNvK6Wb9Y1+Kzn16SuGfN9YFJDTbwlzGRvePCNTOX0recpLQF3kc2FmvMUhyTCH1Q== +react-native-screens@^4.19.0: + version "4.19.0" + resolved "https://registry.yarnpkg.com/react-native-screens/-/react-native-screens-4.19.0.tgz#d00f2ec070d7426204eaf34ef6c64396a6871e1d" + integrity sha512-qSDAO3AL5bti0Ri7KZRSVmWlhDr8MV86N5GruiKVQfEL7Zx2nUi3Dl62lqHUAD/LnDvOPuDDsMHCfIpYSv3hPQ== dependencies: react-freeze "^1.0.0" - react-native-is-edge-to-edge "^1.2.1" warn-once "^0.1.0" react-native-svg@15.12.1: @@ -18129,6 +18125,11 @@ setprototypeof@1.2.0: resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.2.0.tgz#66c9a24a73f9fc28cbe66b09fed3d33dcaf1b424" integrity sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw== +sf-symbols-typescript@^2.1.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/sf-symbols-typescript/-/sf-symbols-typescript-2.2.0.tgz#926d6e0715e3d8784cadf7658431e36581254208" + integrity sha512-TPbeg0b7ylrswdGCji8FRGFAKuqbpQlLbL8SOle3j1iHSs5Ob5mhvMAxWN2UItOjgALAB5Zp3fmMfj8mbWvXKw== + shallow-equal@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/shallow-equal/-/shallow-equal-3.1.0.tgz#e7a54bac629c7f248eff6c2f5b63122ba4320bec" @@ -19630,10 +19631,10 @@ use-isomorphic-layout-effect@^1.1.1: resolved "https://registry.yarnpkg.com/use-isomorphic-layout-effect/-/use-isomorphic-layout-effect-1.1.2.tgz#497cefb13d863d687b08477d9e5a164ad8c1a6fb" integrity sha512-49L8yCO3iGT/ZF9QttjwLF/ZD9Iwto5LnH5LmEdk/6cFmXddqi2ulF0edxTwjj+7mqvpVVGQWvbXZdn32wRSHA== -use-latest-callback@^0.2.3: - version "0.2.3" - resolved "https://registry.yarnpkg.com/use-latest-callback/-/use-latest-callback-0.2.3.tgz#2d644d3063040b9bc2d4c55bb525a13ae3de9e16" - integrity sha512-7vI3fBuyRcP91pazVboc4qu+6ZqM8izPWX9k7cRnT8hbD5svslcknsh3S9BUhaK11OmgTV4oWZZVSeQAiV53SQ== +use-latest-callback@^0.2.4: + version "0.2.6" + resolved "https://registry.yarnpkg.com/use-latest-callback/-/use-latest-callback-0.2.6.tgz#e5ea752808c86219acc179ace0ae3c1203255e77" + integrity sha512-FvRG9i1HSo0wagmX63Vrm8SnlUU3LMM3WyZkQ76RnslpBrX694AdG4A0zQBx2B3ZifFA0yv/BaEHGBnEax5rZg== use-latest@^1.2.1: version "1.2.1"