-
Notifications
You must be signed in to change notification settings - Fork 2.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Migrate E/App to use PlatformStackNavigation
#49937
Open
chrispader
wants to merge
62
commits into
Expensify:main
Choose a base branch
from
margelo:@chrispader/use-platform-stack-navigation-in-app
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
+1,532
−1,979
Open
Changes from 39 commits
Commits
Show all changes
62 commits
Select commit
Hold shift + click to select a range
1408a2d
feat: native-stack (initial changes)
kirillzyusko cf17480
fix: match previous behavior and close keyboard in chat navigator whe…
kirillzyusko 2f4363c
fix: prettier
kirillzyusko 2d2627a
fix: partially fix CI checks
kirillzyusko a42c014
fix: eslint
kirillzyusko e476b1b
fix: removed unused code
kirillzyusko db5ec12
fix: TS
kirillzyusko 9d30239
fix: rename functions to pass CI
kirillzyusko df0b5b6
fix: crashes in FlatList on goBack on Android
kirillzyusko 2eddd62
fix: crash when open and close image in chat
kirillzyusko 8f57acc
fix: incorrect merge conflic resolve
kirillzyusko 600088a
fix: not showing up keyboard in ChatFinder screen
kirillzyusko fb47d6f
fix: iOS un-natural transitions
kirillzyusko de1eda9
fix: new screen to use new interface
kirillzyusko a7293da
fix: remove header in FullScreenNavigator
chrispader 5fc7dd7
Merge branch 'main' into @chrispader/use-platform-stack-navigation-in…
chrispader 93d37cc
Merge branch 'main' into @chrispader/use-platform-stack-navigation-in…
chrispader 64ddf81
Merge branch 'main' into @chrispader/use-platform-stack-navigation-in…
chrispader 485fa25
Merge branch 'main' into @chrispader/use-platform-stack-navigation-in…
chrispader 1f98e64
Merge branch 'main' into @chrispader/use-platform-stack-navigation-in…
chrispader 1356eff
Merge branch 'main' into @chrispader/use-platform-stack-navigation-in…
chrispader a9b8ef3
Merge branch 'main' into @chrispader/use-platform-stack-navigation-in…
chrispader db5a9e3
Merge branch 'main' into @chrispader/use-platform-stack-navigation-in…
chrispader 711ae64
remove unused temporary navigator factories
chrispader 853349f
fix: improve naming of (side) modal navigator screen options generators
chrispader 028b62a
fix: further improve naming
chrispader 2516570
Merge branch 'main' into @chrispader/use-platform-stack-navigation-in…
chrispader 88ff047
Merge branch 'main' into @chrispader/use-platform-stack-navigation-in…
chrispader 1250fc4
fix: background flashing inverse color
chrispader f6409c4
fix: use correct Navigation theme based on theme
chrispader 6a7b166
remove unused onSubmit prop
chrispader 17a76e3
fix: remove onSubmit prop type
chrispader 4b420a5
fix: modal stack background style
chrispader 2409969
Merge branch 'main' into @chrispader/use-platform-stack-navigation-in…
chrispader 756fd60
fix: use `shouldUseNarrowLayout` instead of `isSmallScreenWidth`
chrispader 8538b30
fix: typo
chrispader 00a9c75
fix: unused onSubmit
chrispader 5485e44
add empty line at the end
chrispader a0404e6
Merge branch 'main' into @chrispader/use-platform-stack-navigation-in…
chrispader eeac6c3
Merge branch 'main' into @chrispader/use-platform-stack-navigation-in…
chrispader 88cd73d
fix: prettier
chrispader d29e08f
fix: Podfile.lock
chrispader 44c238d
fix: remove unused code
chrispader 3640bf2
fix: add `react-native-screens` patch for ios modal unmount flicker
chrispader e175aff
Merge branch 'main' into @chrispader/use-platform-stack-navigation-in…
chrispader 0106161
fix: add RNS patch for android keyboard resizing fix
chrispader 50abafc
fix: description field not automatically focused
chrispader 6437a86
fix: outdated BottomTabBar
chrispader 2210863
fix: improve navigation options file structure
chrispader 55d1eef
fix: fix animation direction and simplify code
chrispader 3e02e4d
fix: use const Presentation values
chrispader c5004dc
fix: disallow gesture in onboarding modal
chrispader 8e78f30
fix: prevent unnecessary home screen re-mount
chrispader 6f13505
feat: edge-to-edge mode on Android
kirillzyusko 3f60c7b
Merge branch 'main' into @chrispader/use-platform-stack-navigation-in…
chrispader c88ff39
fix: remove Podfile change
chrispader a98fcef
fix: remove Podfile.lock change
chrispader 23e9953
remove unused patch
chrispader df33cef
fix: update Podfile.lock checksum
chrispader 78d3bd5
Merge branch 'feat/edge-to-edge' into @chrispader/use-platform-stack-…
chrispader f03f765
Merge branch 'main' into @chrispader/use-platform-stack-navigation-in…
chrispader fab9a8b
chore: update pager view patches
chrispader File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
29 changes: 29 additions & 0 deletions
29
patches/react-native-pager-view+6.4.1+001+native-stack-recycle-crash.patch
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
diff --git a/node_modules/react-native-pager-view/android/src/main/java/com/reactnativepagerview/PagerViewViewManagerImpl.kt b/node_modules/react-native-pager-view/android/src/main/java/com/reactnativepagerview/PagerViewViewManagerImpl.kt | ||
index 0abf668..0bfca0a 100644 | ||
--- a/node_modules/react-native-pager-view/android/src/main/java/com/reactnativepagerview/PagerViewViewManagerImpl.kt | ||
+++ b/node_modules/react-native-pager-view/android/src/main/java/com/reactnativepagerview/PagerViewViewManagerImpl.kt | ||
@@ -151,10 +151,20 @@ object PagerViewViewManagerImpl { | ||
|
||
private fun refreshViewChildrenLayout(view: View) { | ||
view.post { | ||
- view.measure( | ||
+ try { | ||
+ view.measure( | ||
View.MeasureSpec.makeMeasureSpec(view.width, View.MeasureSpec.EXACTLY), | ||
- View.MeasureSpec.makeMeasureSpec(view.height, View.MeasureSpec.EXACTLY)) | ||
- view.layout(view.left, view.top, view.right, view.bottom) | ||
+ View.MeasureSpec.makeMeasureSpec(view.height, View.MeasureSpec.EXACTLY) | ||
+ ) | ||
+ view.layout(view.left, view.top, view.right, view.bottom) | ||
+ } catch (e: Exception) { | ||
+ // no-op | ||
+ // fixes a crash: java.lang.IllegalArgumentException: Scrapped or attached views may not be recycled. isScrap:false isAttached:true | ||
+ // It looks like we can not force layout on a recycled views. The safer solution would be simply call .requestLayout(), but I believe that | ||
+ // force layouting was added intentionally and fixes some issues, so we simply wrap the operation with try/catch to not crash the app | ||
+ // patch can be removed when https://github.com/callstack/react-native-pager-view/issues/882 or https://github.com/callstack/react-native-pager-view/issues/859 | ||
+ // will be fixed | ||
+ } | ||
} | ||
} | ||
} | ||
\ No newline at end of file |
57 changes: 57 additions & 0 deletions
57
patches/react-native-screens+3.34.0+003+fabric-flat-list-fix.patch
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
diff --git a/node_modules/react-native-screens/android/src/main/java/com/swmansion/rnscreens/Screen.kt b/node_modules/react-native-screens/android/src/main/java/com/swmansion/rnscreens/Screen.kt | ||
index 9d08d39..146b9c2 100644 | ||
--- a/node_modules/react-native-screens/android/src/main/java/com/swmansion/rnscreens/Screen.kt | ||
+++ b/node_modules/react-native-screens/android/src/main/java/com/swmansion/rnscreens/Screen.kt | ||
@@ -18,6 +18,7 @@ import com.facebook.react.uimanager.PixelUtil | ||
import com.facebook.react.uimanager.UIManagerHelper | ||
import com.facebook.react.uimanager.UIManagerModule | ||
import com.swmansion.rnscreens.events.HeaderHeightChangeEvent | ||
+import com.swmansion.rnscreens.ext.isInsideScrollViewWithRemoveClippedSubviews | ||
|
||
@SuppressLint("ViewConstructor") // Only we construct this view, it is never inflated. | ||
class Screen( | ||
@@ -310,6 +311,16 @@ class Screen( | ||
startTransitionRecursive(child.toolbar) | ||
} | ||
if (child is ViewGroup) { | ||
+ // a combination of https://github.com/software-mansion/react-native-screens/pull/2307/files and https://github.com/software-mansion/react-native-screens/pull/2383/files | ||
+ // The children are miscounted when there's a FlatList with | ||
+ // removeClippedSubviews set to true (default). | ||
+ // We add a simple view for each item in the list to make it work as expected. | ||
+ // See https://github.com/software-mansion/react-native-screens/issues/2282 | ||
+ if (child.isInsideScrollViewWithRemoveClippedSubviews()) { | ||
+ for (j in 0 until child.childCount) { | ||
+ child.addView(View(context)) | ||
+ } | ||
+ } | ||
startTransitionRecursive(child) | ||
} | ||
} | ||
diff --git a/node_modules/react-native-screens/android/src/main/java/com/swmansion/rnscreens/ext/ViewExt.kt b/node_modules/react-native-screens/android/src/main/java/com/swmansion/rnscreens/ext/ViewExt.kt | ||
new file mode 100644 | ||
index 0000000..9d9fbfd | ||
--- /dev/null | ||
+++ b/node_modules/react-native-screens/android/src/main/java/com/swmansion/rnscreens/ext/ViewExt.kt | ||
@@ -0,0 +1,21 @@ | ||
+package com.swmansion.rnscreens.ext | ||
+ | ||
+import android.view.View | ||
+import android.view.ViewGroup | ||
+import com.facebook.react.views.scroll.ReactHorizontalScrollView | ||
+import com.facebook.react.views.scroll.ReactScrollView | ||
+import com.swmansion.rnscreens.ScreenStack | ||
+ | ||
+internal fun View.isInsideScrollViewWithRemoveClippedSubviews(): Boolean { | ||
+ if (this is ReactHorizontalScrollView || this is ReactScrollView) { | ||
+ return false | ||
+ } | ||
+ var parentView = this.parent | ||
+ while (parentView is ViewGroup && parentView !is ScreenStack) { | ||
+ if (parentView is ReactScrollView) { | ||
+ return parentView.removeClippedSubviews | ||
+ } | ||
+ parentView = parentView.parent | ||
+ } | ||
+ return false | ||
+} | ||
\ No newline at end of file |
156 changes: 156 additions & 0 deletions
156
patches/react-native-screens+3.34.0+004+ios-custom-animations-native-transitions.patch
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,156 @@ | ||
diff --git a/node_modules/react-native-screens/ios/RNSScreenStackAnimator.mm b/node_modules/react-native-screens/ios/RNSScreenStackAnimator.mm | ||
index abb2cf6..fb81d52 100644 | ||
--- a/node_modules/react-native-screens/ios/RNSScreenStackAnimator.mm | ||
+++ b/node_modules/react-native-screens/ios/RNSScreenStackAnimator.mm | ||
@@ -5,13 +5,14 @@ | ||
|
||
// proportions to default transition duration | ||
static const float RNSSlideOpenTransitionDurationProportion = 1; | ||
-static const float RNSFadeOpenTransitionDurationProportion = 0.2 / 0.35; | ||
-static const float RNSSlideCloseTransitionDurationProportion = 0.25 / 0.35; | ||
-static const float RNSFadeCloseTransitionDurationProportion = 0.15 / 0.35; | ||
-static const float RNSFadeCloseDelayTransitionDurationProportion = 0.1 / 0.35; | ||
+static const float RNSFadeOpenTransitionDurationProportion = 0.2 / 0.5; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This patch can be removed if we switch to RNS 4.0
|
||
+static const float RNSSlideCloseTransitionDurationProportion = 0.25 / 0.5; | ||
+static const float RNSFadeCloseTransitionDurationProportion = 0.15 / 0.5; | ||
+static const float RNSFadeCloseDelayTransitionDurationProportion = 0.1 / 0.5; | ||
// same value is used in other projects using similar approach for transistions | ||
// and it looks the most similar to the value used by Apple | ||
static constexpr float RNSShadowViewMaxAlpha = 0.1; | ||
+static const int UIViewAnimationOptionCurveDefaultTransition = 7 << 16; | ||
|
||
@implementation RNSScreenStackAnimator { | ||
UINavigationControllerOperation _operation; | ||
@@ -22,7 +23,7 @@ - (instancetype)initWithOperation:(UINavigationControllerOperation)operation | ||
{ | ||
if (self = [super init]) { | ||
_operation = operation; | ||
- _transitionDuration = 0.35; // default duration in seconds | ||
+ _transitionDuration = 0.5; // default duration in seconds | ||
} | ||
return self; | ||
} | ||
@@ -129,6 +130,8 @@ - (void)animateSimplePushWithShadowEnabled:(BOOL)shadowEnabled | ||
} | ||
|
||
[UIView animateWithDuration:[self transitionDuration:transitionContext] | ||
+ delay:0 | ||
+ options:UIViewAnimationOptionCurveDefaultTransition | ||
animations:^{ | ||
fromViewController.view.transform = leftTransform; | ||
toViewController.view.transform = CGAffineTransformIdentity; | ||
@@ -170,6 +173,8 @@ - (void)animateSimplePushWithShadowEnabled:(BOOL)shadowEnabled | ||
|
||
if (!transitionContext.isInteractive) { | ||
[UIView animateWithDuration:[self transitionDuration:transitionContext] | ||
+ delay:0 | ||
+ options:UIViewAnimationOptionCurveDefaultTransition | ||
animations:animationBlock | ||
completion:completionBlock]; | ||
} else { | ||
@@ -203,6 +208,8 @@ - (void)animateSlideFromLeftWithTransitionContext:(id<UIViewControllerContextTra | ||
toViewController.view.transform = rightTransform; | ||
[[transitionContext containerView] addSubview:toViewController.view]; | ||
[UIView animateWithDuration:[self transitionDuration:transitionContext] | ||
+ delay:0 | ||
+ options:UIViewAnimationOptionCurveDefaultTransition | ||
animations:^{ | ||
fromViewController.view.transform = leftTransform; | ||
toViewController.view.transform = CGAffineTransformIdentity; | ||
@@ -228,6 +235,8 @@ - (void)animateSlideFromLeftWithTransitionContext:(id<UIViewControllerContextTra | ||
|
||
if (!transitionContext.isInteractive) { | ||
[UIView animateWithDuration:[self transitionDuration:transitionContext] | ||
+ delay:0 | ||
+ options:UIViewAnimationOptionCurveDefaultTransition | ||
animations:animationBlock | ||
completion:completionBlock]; | ||
} else { | ||
@@ -251,6 +260,8 @@ - (void)animateFadeWithTransitionContext:(id<UIViewControllerContextTransitionin | ||
[[transitionContext containerView] addSubview:toViewController.view]; | ||
toViewController.view.alpha = 0.0; | ||
[UIView animateWithDuration:[self transitionDuration:transitionContext] | ||
+ delay:0 | ||
+ options:UIViewAnimationOptionCurveDefaultTransition | ||
animations:^{ | ||
toViewController.view.alpha = 1.0; | ||
} | ||
@@ -262,6 +273,8 @@ - (void)animateFadeWithTransitionContext:(id<UIViewControllerContextTransitionin | ||
[[transitionContext containerView] insertSubview:toViewController.view belowSubview:fromViewController.view]; | ||
|
||
[UIView animateWithDuration:[self transitionDuration:transitionContext] | ||
+ delay:0 | ||
+ options:UIViewAnimationOptionCurveDefaultTransition | ||
animations:^{ | ||
fromViewController.view.alpha = 0.0; | ||
} | ||
@@ -284,6 +297,8 @@ - (void)animateSlideFromBottomWithTransitionContext:(id<UIViewControllerContextT | ||
toViewController.view.transform = topBottomTransform; | ||
[[transitionContext containerView] addSubview:toViewController.view]; | ||
[UIView animateWithDuration:[self transitionDuration:transitionContext] | ||
+ delay:0 | ||
+ options:UIViewAnimationOptionCurveDefaultTransition | ||
animations:^{ | ||
fromViewController.view.transform = CGAffineTransformIdentity; | ||
toViewController.view.transform = CGAffineTransformIdentity; | ||
@@ -309,6 +324,8 @@ - (void)animateSlideFromBottomWithTransitionContext:(id<UIViewControllerContextT | ||
|
||
if (!transitionContext.isInteractive) { | ||
[UIView animateWithDuration:[self transitionDuration:transitionContext] | ||
+ delay:0 | ||
+ options:UIViewAnimationOptionCurveDefaultTransition | ||
animations:animationBlock | ||
completion:completionBlock]; | ||
} else { | ||
diff --git a/node_modules/react-native-screens/lib/typescript/fabric/ModalScreenNativeComponent.d.ts b/node_modules/react-native-screens/lib/typescript/fabric/ModalScreenNativeComponent.d.ts | ||
index 28d6463..a1473e1 100644 | ||
--- a/node_modules/react-native-screens/lib/typescript/fabric/ModalScreenNativeComponent.d.ts | ||
+++ b/node_modules/react-native-screens/lib/typescript/fabric/ModalScreenNativeComponent.d.ts | ||
@@ -55,7 +55,7 @@ export interface NativeProps extends ViewProps { | ||
gestureResponseDistance?: GestureResponseDistanceType; | ||
stackPresentation?: WithDefault<StackPresentation, 'push'>; | ||
stackAnimation?: WithDefault<StackAnimation, 'default'>; | ||
- transitionDuration?: WithDefault<Int32, 350>; | ||
+ transitionDuration?: WithDefault<Int32, 500>; | ||
replaceAnimation?: WithDefault<ReplaceAnimation, 'pop'>; | ||
swipeDirection?: WithDefault<SwipeDirection, 'horizontal'>; | ||
hideKeyboardOnSwipe?: boolean; | ||
diff --git a/node_modules/react-native-screens/lib/typescript/fabric/ScreenNativeComponent.d.ts b/node_modules/react-native-screens/lib/typescript/fabric/ScreenNativeComponent.d.ts | ||
index 11ed190..f676e08 100644 | ||
--- a/node_modules/react-native-screens/lib/typescript/fabric/ScreenNativeComponent.d.ts | ||
+++ b/node_modules/react-native-screens/lib/typescript/fabric/ScreenNativeComponent.d.ts | ||
@@ -55,7 +55,7 @@ export interface NativeProps extends ViewProps { | ||
gestureResponseDistance?: GestureResponseDistanceType; | ||
stackPresentation?: WithDefault<StackPresentation, 'push'>; | ||
stackAnimation?: WithDefault<StackAnimation, 'default'>; | ||
- transitionDuration?: WithDefault<Int32, 350>; | ||
+ transitionDuration?: WithDefault<Int32, 500>; | ||
replaceAnimation?: WithDefault<ReplaceAnimation, 'pop'>; | ||
swipeDirection?: WithDefault<SwipeDirection, 'horizontal'>; | ||
hideKeyboardOnSwipe?: boolean; | ||
diff --git a/node_modules/react-native-screens/src/fabric/ModalScreenNativeComponent.ts b/node_modules/react-native-screens/src/fabric/ModalScreenNativeComponent.ts | ||
index bb59c4c..d4c14ee 100644 | ||
--- a/node_modules/react-native-screens/src/fabric/ModalScreenNativeComponent.ts | ||
+++ b/node_modules/react-native-screens/src/fabric/ModalScreenNativeComponent.ts | ||
@@ -90,7 +90,7 @@ export interface NativeProps extends ViewProps { | ||
gestureResponseDistance?: GestureResponseDistanceType; | ||
stackPresentation?: WithDefault<StackPresentation, 'push'>; | ||
stackAnimation?: WithDefault<StackAnimation, 'default'>; | ||
- transitionDuration?: WithDefault<Int32, 350>; | ||
+ transitionDuration?: WithDefault<Int32, 500>; | ||
replaceAnimation?: WithDefault<ReplaceAnimation, 'pop'>; | ||
swipeDirection?: WithDefault<SwipeDirection, 'horizontal'>; | ||
hideKeyboardOnSwipe?: boolean; | ||
diff --git a/node_modules/react-native-screens/src/fabric/ScreenNativeComponent.ts b/node_modules/react-native-screens/src/fabric/ScreenNativeComponent.ts | ||
index 4e39336..ab0b313 100644 | ||
--- a/node_modules/react-native-screens/src/fabric/ScreenNativeComponent.ts | ||
+++ b/node_modules/react-native-screens/src/fabric/ScreenNativeComponent.ts | ||
@@ -92,7 +92,7 @@ export interface NativeProps extends ViewProps { | ||
gestureResponseDistance?: GestureResponseDistanceType; | ||
stackPresentation?: WithDefault<StackPresentation, 'push'>; | ||
stackAnimation?: WithDefault<StackAnimation, 'default'>; | ||
- transitionDuration?: WithDefault<Int32, 350>; | ||
+ transitionDuration?: WithDefault<Int32, 500>; | ||
replaceAnimation?: WithDefault<ReplaceAnimation, 'pop'>; | ||
swipeDirection?: WithDefault<SwipeDirection, 'horizontal'>; | ||
hideKeyboardOnSwipe?: boolean; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This patch can be removed if we switch to RNS 4.0