diff --git a/packages/mobile/patches/@react-navigation+drawer+6.3.1.patch b/packages/mobile/patches/@react-navigation+drawer+6.3.1.patch new file mode 100644 index 0000000000..81d732a79b --- /dev/null +++ b/packages/mobile/patches/@react-navigation+drawer+6.3.1.patch @@ -0,0 +1,19 @@ +diff --git a/node_modules/@react-navigation/drawer/src/views/legacy/Drawer.tsx b/node_modules/@react-navigation/drawer/src/views/legacy/Drawer.tsx +index bebfcbf..0211168 100644 +--- a/node_modules/@react-navigation/drawer/src/views/legacy/Drawer.tsx ++++ b/node_modules/@react-navigation/drawer/src/views/legacy/Drawer.tsx +@@ -530,7 +530,13 @@ export default class DrawerView extends React.Component { + return ( + + *)getGestureHandlers; ++ + @end + +diff --git a/node_modules/react-native-gesture-handler/ios/RNGestureHandler.m b/node_modules/react-native-gesture-handler/ios/RNGestureHandler.m +index 998c059..b239ba7 100644 +--- a/node_modules/react-native-gesture-handler/ios/RNGestureHandler.m ++++ b/node_modules/react-native-gesture-handler/ios/RNGestureHandler.m +@@ -73,6 +73,7 @@ - (instancetype)initWithTag:(NSNumber *)tag + _tag = tag; + _lastState = RNGestureHandlerStateUndetermined; + _hitSlop = RNGHHitSlopEmpty; ++ _frozen = NO; + + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ +@@ -132,8 +133,10 @@ - (void)configure:(NSDictionary *)config + + - (void)setEnabled:(BOOL)enabled + { +- _enabled = enabled; +- self.recognizer.enabled = enabled; ++ if (_frozen == NO) { ++ _enabled = enabled; ++ self.recognizer.enabled = enabled; ++ } + } + + - (void)bindToView:(UIView *)view +@@ -341,4 +344,9 @@ - (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceive + return YES; + } + +++ (NSHashTable *)getGestureHandlers ++{ ++ return allGestureHandlers; ++} ++ + @end diff --git a/packages/mobile/patches/react-native-pager-view+5.4.6.patch b/packages/mobile/patches/react-native-pager-view+5.4.6.patch index 0329c9a672..489def0d90 100644 --- a/packages/mobile/patches/react-native-pager-view+5.4.6.patch +++ b/packages/mobile/patches/react-native-pager-view+5.4.6.patch @@ -1,44 +1,186 @@ +diff --git a/node_modules/react-native-pager-view/ios/ReactNativePageView.h b/node_modules/react-native-pager-view/ios/ReactNativePageView.h +index f7f31a5..c6a0356 100644 +--- a/node_modules/react-native-pager-view/ios/ReactNativePageView.h ++++ b/node_modules/react-native-pager-view/ios/ReactNativePageView.h +@@ -23,7 +23,7 @@ NS_ASSUME_NONNULL_BEGIN + @property(nonatomic, copy) RCTDirectEventBlock onPageScrollStateChanged; + @property(nonatomic) BOOL overdrag; + @property(nonatomic) NSString* layoutDirection; +- ++@property(nonatomic) NSUInteger previousNavigationStackCount; + + - (void)goTo:(NSInteger)index animated:(BOOL)animated; + - (void)shouldScroll:(BOOL)scrollEnabled; diff --git a/node_modules/react-native-pager-view/ios/ReactNativePageView.m b/node_modules/react-native-pager-view/ios/ReactNativePageView.m -index 78f266b..cc094a3 100644 +index 78f266b..b3a2585 100644 --- a/node_modules/react-native-pager-view/ios/ReactNativePageView.m +++ b/node_modules/react-native-pager-view/ios/ReactNativePageView.m -@@ -83,6 +83,16 @@ - (void)didMoveToWindow { +@@ -3,6 +3,7 @@ + #import "React/RCTLog.h" + #import + ++#import "RNGestureHandler.h" + #import "UIViewController+CreateExtension.h" + #import "RCTOnPageScrollEvent.h" + #import "RCTOnPageScrollStateChanged.h" +@@ -47,6 +48,7 @@ - (instancetype)initWithEventDispatcher:(RCTEventDispatcher *)eventDispatcher { + _cachedControllers = [NSHashTable weakObjectsHashTable]; + _overdrag = NO; + _layoutDirection = @"ltr"; ++ _previousNavigationStackCount = 1; + } + return self; + } +@@ -83,6 +85,59 @@ - (void)didMoveToWindow { [self embed]; [self setupInitialController]; } -+ + if (self.reactViewController.navigationController != nil) { -+ for (UIGestureRecognizer *recognizer in self.reactViewController.navigationController.view.gestureRecognizers) { -+ [self.scrollView.panGestureRecognizer requireGestureRecognizerToFail:recognizer]; ++ NSUInteger count = [self.reactViewController.navigationController.viewControllers count]; ++ ++ if (count >= _previousNavigationStackCount) { ++ // We are pushing to the stack, always enable the stack navigator ++ for (UIGestureRecognizer *recognizer in self.reactViewController.navigationController.view.gestureRecognizers) { ++ recognizer.enabled = YES; ++ } ++ } else { ++ // We are popping from the stack, only enable stack if we're on the first tab ++ if (self.currentIndex == 0) { ++ for (UIGestureRecognizer *recognizer in self.reactViewController.navigationController.view.gestureRecognizers) { ++ recognizer.enabled = YES; ++ } ++ } else { ++ for (UIGestureRecognizer *recognizer in self.reactViewController.navigationController.view.gestureRecognizers) { ++ // Do not disable the gesture immediately as the window is popping. ++ NSTimeInterval delayInSeconds = 0.1; ++ dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC)); ++ dispatch_after(popTime, dispatch_get_main_queue(), ^(void){ ++ recognizer.enabled = NO; ++ }); ++ } ++ } ++ } ++ ++ if (self.currentIndex == 0) { ++ // On the first tab, we want to listen to the drawer's gestures, so ++ // swiping it open works. ++ NSHashTable *handlers = [RNGestureHandler getGestureHandlers]; ++ NSEnumerator *enumerator = [handlers objectEnumerator]; ++ RNGestureHandler* handler; ++ while ((handler = [enumerator nextObject])) { ++ handler.recognizer.enabled = YES; ++ handler.frozen = NO; ++ [self.scrollView.panGestureRecognizer requireGestureRecognizerToFail:handler.recognizer]; ++ } ++ } else { ++ // On the other tabs tab, we should disable the drawer's gestures. ++ NSHashTable *handlers = [RNGestureHandler getGestureHandlers]; ++ NSEnumerator *enumerator = [handlers objectEnumerator]; ++ RNGestureHandler* handler; ++ while ((handler = [enumerator nextObject])) { ++ handler.recognizer.enabled = NO; ++ handler.frozen = YES; ++ } + } + } + ++ // Disable tab swipes when the stack navigator receives a "pop" gesture + if (self.reactViewController.navigationController != nil && self.reactViewController.navigationController.interactivePopGestureRecognizer != nil) { + [self.scrollView.panGestureRecognizer requireGestureRecognizerToFail:self.reactViewController.navigationController.interactivePopGestureRecognizer]; + } } - (void)embed { -@@ -333,6 +343,23 @@ - (void)pageViewController:(UIPageViewController *)pageViewController +@@ -191,6 +246,42 @@ - (void)setReactViewControllers:(NSInteger)index + strongSelf.lastReportedIndex = strongSelf.currentIndex; + } + } ++ ++ if (self.reactViewController.navigationController != nil) { ++ if (strongSelf.currentIndex == 0) { ++ // On the first tab, we want to listen to the navigation's gestures, so ++ // swipe back works. ++ for (UIGestureRecognizer *recognizer in self.reactViewController.navigationController.view.gestureRecognizers) { ++ recognizer.enabled = YES; ++ [self.scrollView.panGestureRecognizer requireGestureRecognizerToFail:recognizer]; ++ } ++ ++ // On the first tab, we want to listen to the drawer's gestures, so ++ // swiping it open works. ++ NSHashTable *handlers = [RNGestureHandler getGestureHandlers]; ++ NSEnumerator *enumerator = [handlers objectEnumerator]; ++ RNGestureHandler* handler; ++ while ((handler = [enumerator nextObject])) { ++ handler.recognizer.enabled = YES; ++ handler.frozen = NO; ++ [self.scrollView.panGestureRecognizer requireGestureRecognizerToFail:handler.recognizer]; ++ } ++ } else { ++ // On other tabs, we should disable the navigations's gestures ++ for (UIGestureRecognizer *recognizer in self.reactViewController.navigationController.view.gestureRecognizers) { ++ recognizer.enabled = NO; ++ } ++ ++ // On the other tabs tab, we should disable the drawer's gestures. ++ NSHashTable *handlers = [RNGestureHandler getGestureHandlers]; ++ NSEnumerator *enumerator = [handlers objectEnumerator]; ++ RNGestureHandler* handler; ++ while ((handler = [enumerator nextObject])) { ++ handler.recognizer.enabled = NO; ++ handler.frozen = YES; ++ } ++ } ++ } + }]; + } + +@@ -322,7 +413,6 @@ - (void)pageViewController:(UIPageViewController *)pageViewController + didFinishAnimating:(BOOL)finished + previousViewControllers:(nonnull NSArray *)previousViewControllers + transitionCompleted:(BOOL)completed { +- + if (completed) { + UIViewController* currentVC = [self currentlyDisplayed]; + NSUInteger currentIndex = [self.reactSubviews indexOfObject:currentVC.view]; +@@ -333,6 +423,42 @@ - (void)pageViewController:(UIPageViewController *)pageViewController [self.eventDispatcher sendEvent:[[RCTOnPageSelected alloc] initWithReactTag:self.reactTag position:@(currentIndex) coalescingKey:_coalescingKey++]]; [self.eventDispatcher sendEvent:[[RCTOnPageScrollEvent alloc] initWithReactTag:self.reactTag position:@(currentIndex) offset:@(0.0)]]; self.lastReportedIndex = currentIndex; + + if (self.reactViewController.navigationController != nil) { -+ if (currentIndex == 0) { ++ if (self.currentIndex == 0) { + // On the first tab, we want to listen to the navigation's gestures, so + // swipe back works. + for (UIGestureRecognizer *recognizer in self.reactViewController.navigationController.view.gestureRecognizers) { + recognizer.enabled = YES; + [self.scrollView.panGestureRecognizer requireGestureRecognizerToFail:recognizer]; + } ++ ++ // On the first tab, we want to listen to the drawer's gestures, so ++ // swiping it open works. ++ NSHashTable *handlers = [RNGestureHandler getGestureHandlers]; ++ NSEnumerator *enumerator = [handlers objectEnumerator]; ++ RNGestureHandler* handler; ++ while ((handler = [enumerator nextObject])) { ++ handler.recognizer.enabled = YES; ++ handler.frozen = NO; ++ [self.scrollView.panGestureRecognizer requireGestureRecognizerToFail:handler.recognizer]; ++ } + } else { + // On other tabs, we should disable the navigations's gestures + for (UIGestureRecognizer *recognizer in self.reactViewController.navigationController.view.gestureRecognizers) { + recognizer.enabled = NO; + } -+ } + ++ // On the other tabs tab, we should disable the drawer's gestures. ++ NSHashTable *handlers = [RNGestureHandler getGestureHandlers]; ++ NSEnumerator *enumerator = [handlers objectEnumerator]; ++ RNGestureHandler* handler; ++ while ((handler = [enumerator nextObject])) { ++ handler.recognizer.enabled = NO; ++ handler.frozen = YES; ++ } ++ } + } } } diff --git a/packages/mobile/src/screens/app-screen/useAppScreenOptions.tsx b/packages/mobile/src/screens/app-screen/useAppScreenOptions.tsx index 70fc401b05..1b1b6b63f9 100644 --- a/packages/mobile/src/screens/app-screen/useAppScreenOptions.tsx +++ b/packages/mobile/src/screens/app-screen/useAppScreenOptions.tsx @@ -174,8 +174,7 @@ export const useAppScreenOptions = () => { styles, neutralLight4, accentOrangeLight1, - notificationCount, - goBack + notificationCount ] )