@amazon-devices/react-native-screens 2.0.1758683737
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +7 -0
- package/README.md +223 -0
- package/RNScreens.podspec +53 -0
- package/SystemBundles/8f5a820b958535e533acb38dbc0c72c1837721b9db075f4a1740e42b9fee3910.bundle +33668 -0
- package/SystemBundles/8f5a820b958535e533acb38dbc0c72c1837721b9db075f4a1740e42b9fee3910.map +1 -0
- package/SystemModules/amzn__react-native-screens.modules.txt +101 -0
- package/SystemModules/amzn__react-native-screens.private.modules.txt +244 -0
- package/SystemModules/keplerscript-system-bundle-config.json +7 -0
- package/THIRD_PARTY_NOTICES.txt +707 -0
- package/android/build.gradle +133 -0
- package/android/src/fabric/java/com/swmansion/rnscreens/FabricEnabledViewGroup.kt +49 -0
- package/android/src/main/AndroidManifest.xml +5 -0
- package/android/src/main/java/com/swmansion/rnscreens/CustomSearchView.kt +77 -0
- package/android/src/main/java/com/swmansion/rnscreens/CustomToolbar.kt +7 -0
- package/android/src/main/java/com/swmansion/rnscreens/FragmentBackPressOverrider.kt +29 -0
- package/android/src/main/java/com/swmansion/rnscreens/FragmentHolder.kt +7 -0
- package/android/src/main/java/com/swmansion/rnscreens/RNScreensPackage.kt +21 -0
- package/android/src/main/java/com/swmansion/rnscreens/Screen.kt +289 -0
- package/android/src/main/java/com/swmansion/rnscreens/ScreenContainer.kt +372 -0
- package/android/src/main/java/com/swmansion/rnscreens/ScreenContainerViewManager.kt +40 -0
- package/android/src/main/java/com/swmansion/rnscreens/ScreenEventDispatcher.kt +21 -0
- package/android/src/main/java/com/swmansion/rnscreens/ScreenFragment.kt +331 -0
- package/android/src/main/java/com/swmansion/rnscreens/ScreenFragmentWrapper.kt +22 -0
- package/android/src/main/java/com/swmansion/rnscreens/ScreenStack.kt +336 -0
- package/android/src/main/java/com/swmansion/rnscreens/ScreenStackFragment.kt +282 -0
- package/android/src/main/java/com/swmansion/rnscreens/ScreenStackFragmentWrapper.kt +15 -0
- package/android/src/main/java/com/swmansion/rnscreens/ScreenStackHeaderConfig.kt +398 -0
- package/android/src/main/java/com/swmansion/rnscreens/ScreenStackHeaderConfigViewManager.kt +204 -0
- package/android/src/main/java/com/swmansion/rnscreens/ScreenStackHeaderSubview.kt +38 -0
- package/android/src/main/java/com/swmansion/rnscreens/ScreenStackHeaderSubviewManager.kt +41 -0
- package/android/src/main/java/com/swmansion/rnscreens/ScreenStackViewManager.kt +75 -0
- package/android/src/main/java/com/swmansion/rnscreens/ScreenViewManager.kt +186 -0
- package/android/src/main/java/com/swmansion/rnscreens/ScreenWindowTraits.kt +296 -0
- package/android/src/main/java/com/swmansion/rnscreens/ScreensShadowNode.kt +19 -0
- package/android/src/main/java/com/swmansion/rnscreens/SearchBarManager.kt +133 -0
- package/android/src/main/java/com/swmansion/rnscreens/SearchBarView.kt +178 -0
- package/android/src/main/java/com/swmansion/rnscreens/SearchViewFormatter.kt +67 -0
- package/android/src/main/java/com/swmansion/rnscreens/events/HeaderAttachedEvent.kt +22 -0
- package/android/src/main/java/com/swmansion/rnscreens/events/HeaderBackButtonClickedEvent.kt +22 -0
- package/android/src/main/java/com/swmansion/rnscreens/events/HeaderDetachedEvent.kt +22 -0
- package/android/src/main/java/com/swmansion/rnscreens/events/HeaderHeightChangeEvent.kt +26 -0
- package/android/src/main/java/com/swmansion/rnscreens/events/ScreenAppearEvent.kt +18 -0
- package/android/src/main/java/com/swmansion/rnscreens/events/ScreenDisappearEvent.kt +18 -0
- package/android/src/main/java/com/swmansion/rnscreens/events/ScreenDismissedEvent.kt +20 -0
- package/android/src/main/java/com/swmansion/rnscreens/events/ScreenTransitionProgressEvent.kt +32 -0
- package/android/src/main/java/com/swmansion/rnscreens/events/ScreenWillAppearEvent.kt +18 -0
- package/android/src/main/java/com/swmansion/rnscreens/events/ScreenWillDisappearEvent.kt +18 -0
- package/android/src/main/java/com/swmansion/rnscreens/events/SearchBarBlurEvent.kt +22 -0
- package/android/src/main/java/com/swmansion/rnscreens/events/SearchBarChangeTextEvent.kt +28 -0
- package/android/src/main/java/com/swmansion/rnscreens/events/SearchBarCloseEvent.kt +22 -0
- package/android/src/main/java/com/swmansion/rnscreens/events/SearchBarFocusEvent.kt +22 -0
- package/android/src/main/java/com/swmansion/rnscreens/events/SearchBarOpenEvent.kt +22 -0
- package/android/src/main/java/com/swmansion/rnscreens/events/SearchBarSearchButtonPressEvent.kt +24 -0
- package/android/src/main/java/com/swmansion/rnscreens/events/StackFinishTransitioningEvent.kt +18 -0
- package/android/src/main/java/com/swmansion/rnscreens/utils/DeviceUtils.kt +12 -0
- package/android/src/main/jni/CMakeLists.txt +72 -0
- package/android/src/main/jni/rnscreens.cpp +16 -0
- package/android/src/main/jni/rnscreens.h +28 -0
- package/android/src/main/res/base/anim/rns_default_enter_in.xml +18 -0
- package/android/src/main/res/base/anim/rns_default_enter_out.xml +19 -0
- package/android/src/main/res/base/anim/rns_default_exit_in.xml +17 -0
- package/android/src/main/res/base/anim/rns_default_exit_out.xml +18 -0
- package/android/src/main/res/base/anim/rns_fade_from_bottom.xml +14 -0
- package/android/src/main/res/base/anim/rns_fade_in.xml +7 -0
- package/android/src/main/res/base/anim/rns_fade_out.xml +7 -0
- package/android/src/main/res/base/anim/rns_fade_to_bottom.xml +15 -0
- package/android/src/main/res/base/anim/rns_no_animation_20.xml +6 -0
- package/android/src/main/res/base/anim/rns_no_animation_250.xml +7 -0
- package/android/src/main/res/base/anim/rns_no_animation_350.xml +6 -0
- package/android/src/main/res/base/anim/rns_no_animation_medium.xml +7 -0
- package/android/src/main/res/base/anim/rns_slide_in_from_bottom.xml +7 -0
- package/android/src/main/res/base/anim/rns_slide_in_from_left.xml +5 -0
- package/android/src/main/res/base/anim/rns_slide_in_from_right.xml +5 -0
- package/android/src/main/res/base/anim/rns_slide_out_to_bottom.xml +7 -0
- package/android/src/main/res/base/anim/rns_slide_out_to_left.xml +5 -0
- package/android/src/main/res/base/anim/rns_slide_out_to_right.xml +5 -0
- package/android/src/main/res/base/anim/rns_standard_accelerate_interpolator.xml +6 -0
- package/android/src/main/res/v33/anim-v33/rns_default_enter_in.xml +38 -0
- package/android/src/main/res/v33/anim-v33/rns_default_enter_out.xml +38 -0
- package/android/src/main/res/v33/anim-v33/rns_default_exit_in.xml +38 -0
- package/android/src/main/res/v33/anim-v33/rns_default_exit_out.xml +38 -0
- package/android/src/paper/java/com/facebook/react/viewmanagers/RNSScreenManagerDelegate.java +111 -0
- package/android/src/paper/java/com/facebook/react/viewmanagers/RNSScreenManagerInterface.java +44 -0
- package/android/src/paper/java/com/facebook/react/viewmanagers/RNSScreenStackHeaderConfigManagerDelegate.java +107 -0
- package/android/src/paper/java/com/facebook/react/viewmanagers/RNSScreenStackHeaderConfigManagerInterface.java +42 -0
- package/android/src/paper/java/com/facebook/react/viewmanagers/RNSScreenStackHeaderSubviewManagerDelegate.java +31 -0
- package/android/src/paper/java/com/facebook/react/viewmanagers/RNSScreenStackHeaderSubviewManagerInterface.java +17 -0
- package/android/src/paper/java/com/facebook/react/viewmanagers/RNSScreenStackManagerDelegate.java +25 -0
- package/android/src/paper/java/com/facebook/react/viewmanagers/RNSScreenStackManagerInterface.java +16 -0
- package/android/src/paper/java/com/swmansion/rnscreens/FabricEnabledViewGroup.kt +10 -0
- package/common/cpp/react/renderer/components/rnscreens/RNSScreenComponentDescriptor.h +41 -0
- package/common/cpp/react/renderer/components/rnscreens/RNSScreenShadowNode.cpp +9 -0
- package/common/cpp/react/renderer/components/rnscreens/RNSScreenShadowNode.h +30 -0
- package/common/cpp/react/renderer/components/rnscreens/RNSScreenState.cpp +14 -0
- package/common/cpp/react/renderer/components/rnscreens/RNSScreenState.h +45 -0
- package/ios/RCTImageComponentView+RNSScreenStackHeaderConfig.h +11 -0
- package/ios/RCTImageComponentView+RNSScreenStackHeaderConfig.mm +14 -0
- package/ios/RNSConvert.h +36 -0
- package/ios/RNSConvert.mm +154 -0
- package/ios/RNSEnums.h +71 -0
- package/ios/RNSFullWindowOverlay.h +34 -0
- package/ios/RNSFullWindowOverlay.mm +241 -0
- package/ios/RNSScreen.h +144 -0
- package/ios/RNSScreen.mm +1599 -0
- package/ios/RNSScreenContainer.h +45 -0
- package/ios/RNSScreenContainer.mm +343 -0
- package/ios/RNSScreenNavigationContainer.h +16 -0
- package/ios/RNSScreenNavigationContainer.mm +66 -0
- package/ios/RNSScreenStack.h +37 -0
- package/ios/RNSScreenStack.mm +1111 -0
- package/ios/RNSScreenStackAnimator.h +8 -0
- package/ios/RNSScreenStackAnimator.mm +320 -0
- package/ios/RNSScreenStackHeaderConfig.h +74 -0
- package/ios/RNSScreenStackHeaderConfig.mm +967 -0
- package/ios/RNSScreenStackHeaderSubview.h +44 -0
- package/ios/RNSScreenStackHeaderSubview.mm +147 -0
- package/ios/RNSScreenWindowTraits.h +26 -0
- package/ios/RNSScreenWindowTraits.mm +266 -0
- package/ios/RNSSearchBar.h +43 -0
- package/ios/RNSSearchBar.mm +465 -0
- package/ios/RNScreens.xcodeproj/project.pbxproj +461 -0
- package/ios/UIViewController+RNScreens.h +9 -0
- package/ios/UIViewController+RNScreens.mm +78 -0
- package/ios/UIWindow+RNScreens.h +9 -0
- package/ios/UIWindow+RNScreens.mm +17 -0
- package/ios/events/RNSHeaderHeightChangeEvent.h +8 -0
- package/ios/events/RNSHeaderHeightChangeEvent.mm +44 -0
- package/ios/events/RNSScreenViewEvent.h +12 -0
- package/ios/events/RNSScreenViewEvent.mm +59 -0
- package/ios/utils/RNSUIBarButtonItem.h +5 -0
- package/ios/utils/RNSUIBarButtonItem.mm +22 -0
- package/kepler-compatibility.json +8 -0
- package/kepler-transformed-package-info.json +3 -0
- package/lib/commonjs/TransitionProgressContext.js +11 -0
- package/lib/commonjs/TransitionProgressContext.js.map +1 -0
- package/lib/commonjs/fabric/FullWindowOverlayNativeComponent.js +11 -0
- package/lib/commonjs/fabric/FullWindowOverlayNativeComponent.js.map +1 -0
- package/lib/commonjs/fabric/ScreenContainerNativeComponent.js +33 -0
- package/lib/commonjs/fabric/ScreenContainerNativeComponent.js.map +1 -0
- package/lib/commonjs/fabric/ScreenNativeComponent.js +70 -0
- package/lib/commonjs/fabric/ScreenNativeComponent.js.map +1 -0
- package/lib/commonjs/fabric/ScreenNavigationContainerNativeComponent.js +11 -0
- package/lib/commonjs/fabric/ScreenNavigationContainerNativeComponent.js.map +1 -0
- package/lib/commonjs/fabric/ScreenStackHeaderConfigNativeComponent.js +31 -0
- package/lib/commonjs/fabric/ScreenStackHeaderConfigNativeComponent.js.map +1 -0
- package/lib/commonjs/fabric/ScreenStackHeaderSubviewNativeComponent.js +12 -0
- package/lib/commonjs/fabric/ScreenStackHeaderSubviewNativeComponent.js.map +1 -0
- package/lib/commonjs/fabric/ScreenStackNativeComponent.js +35 -0
- package/lib/commonjs/fabric/ScreenStackNativeComponent.js.map +1 -0
- package/lib/commonjs/fabric/SearchBarNativeComponent.js +19 -0
- package/lib/commonjs/fabric/SearchBarNativeComponent.js.map +1 -0
- package/lib/commonjs/index.js +147 -0
- package/lib/commonjs/index.js.map +1 -0
- package/lib/commonjs/index.native.js +407 -0
- package/lib/commonjs/index.native.js.map +1 -0
- package/lib/commonjs/native-stack/index.js +49 -0
- package/lib/commonjs/native-stack/index.js.map +1 -0
- package/lib/commonjs/native-stack/navigators/createNativeStackNavigator.js +75 -0
- package/lib/commonjs/native-stack/navigators/createNativeStackNavigator.js.map +1 -0
- package/lib/commonjs/native-stack/types.js +6 -0
- package/lib/commonjs/native-stack/types.js.map +1 -0
- package/lib/commonjs/native-stack/utils/AnimatedHeaderHeightContext.js +12 -0
- package/lib/commonjs/native-stack/utils/AnimatedHeaderHeightContext.js.map +1 -0
- package/lib/commonjs/native-stack/utils/HeaderHeightContext.js +12 -0
- package/lib/commonjs/native-stack/utils/HeaderHeightContext.js.map +1 -0
- package/lib/commonjs/native-stack/utils/SafeAreaProviderCompat.js +75 -0
- package/lib/commonjs/native-stack/utils/SafeAreaProviderCompat.js.map +1 -0
- package/lib/commonjs/native-stack/utils/getDefaultHeaderHeight.js +35 -0
- package/lib/commonjs/native-stack/utils/getDefaultHeaderHeight.js.map +1 -0
- package/lib/commonjs/native-stack/utils/useAnimatedHeaderHeight.js +19 -0
- package/lib/commonjs/native-stack/utils/useAnimatedHeaderHeight.js.map +1 -0
- package/lib/commonjs/native-stack/utils/useBackPressSubscription.js +54 -0
- package/lib/commonjs/native-stack/utils/useBackPressSubscription.js.map +1 -0
- package/lib/commonjs/native-stack/utils/useHeaderHeight.js +19 -0
- package/lib/commonjs/native-stack/utils/useHeaderHeight.js.map +1 -0
- package/lib/commonjs/native-stack/views/FontProcessor.js +21 -0
- package/lib/commonjs/native-stack/views/FontProcessor.js.map +1 -0
- package/lib/commonjs/native-stack/views/HeaderConfig.js +141 -0
- package/lib/commonjs/native-stack/views/HeaderConfig.js.map +1 -0
- package/lib/commonjs/native-stack/views/NativeStackView.js +354 -0
- package/lib/commonjs/native-stack/views/NativeStackView.js.map +1 -0
- package/lib/commonjs/reanimated/ReanimatedHeaderHeightContext.js +12 -0
- package/lib/commonjs/reanimated/ReanimatedHeaderHeightContext.js.map +1 -0
- package/lib/commonjs/reanimated/ReanimatedNativeStackScreen.js +101 -0
- package/lib/commonjs/reanimated/ReanimatedNativeStackScreen.js.map +1 -0
- package/lib/commonjs/reanimated/ReanimatedScreen.js +22 -0
- package/lib/commonjs/reanimated/ReanimatedScreen.js.map +1 -0
- package/lib/commonjs/reanimated/ReanimatedScreenProvider.js +47 -0
- package/lib/commonjs/reanimated/ReanimatedScreenProvider.js.map +1 -0
- package/lib/commonjs/reanimated/ReanimatedTransitionProgressContext.js +12 -0
- package/lib/commonjs/reanimated/ReanimatedTransitionProgressContext.js.map +1 -0
- package/lib/commonjs/reanimated/index.js +28 -0
- package/lib/commonjs/reanimated/index.js.map +1 -0
- package/lib/commonjs/reanimated/useReanimatedHeaderHeight.js +19 -0
- package/lib/commonjs/reanimated/useReanimatedHeaderHeight.js.map +1 -0
- package/lib/commonjs/reanimated/useReanimatedTransitionProgress.js +19 -0
- package/lib/commonjs/reanimated/useReanimatedTransitionProgress.js.map +1 -0
- package/lib/commonjs/types.js +6 -0
- package/lib/commonjs/types.js.map +1 -0
- package/lib/commonjs/useTransitionProgress.js +19 -0
- package/lib/commonjs/useTransitionProgress.js.map +1 -0
- package/lib/commonjs/utils.js +21 -0
- package/lib/commonjs/utils.js.map +1 -0
- package/lib/module/TransitionProgressContext.js +3 -0
- package/lib/module/TransitionProgressContext.js.map +1 -0
- package/lib/module/fabric/FullWindowOverlayNativeComponent.js +4 -0
- package/lib/module/fabric/FullWindowOverlayNativeComponent.js.map +1 -0
- package/lib/module/fabric/ScreenContainerNativeComponent.js +25 -0
- package/lib/module/fabric/ScreenContainerNativeComponent.js.map +1 -0
- package/lib/module/fabric/ScreenNativeComponent.js +63 -0
- package/lib/module/fabric/ScreenNativeComponent.js.map +1 -0
- package/lib/module/fabric/ScreenNavigationContainerNativeComponent.js +4 -0
- package/lib/module/fabric/ScreenNavigationContainerNativeComponent.js.map +1 -0
- package/lib/module/fabric/ScreenStackHeaderConfigNativeComponent.js +23 -0
- package/lib/module/fabric/ScreenStackHeaderConfigNativeComponent.js.map +1 -0
- package/lib/module/fabric/ScreenStackHeaderSubviewNativeComponent.js +7 -0
- package/lib/module/fabric/ScreenStackHeaderSubviewNativeComponent.js.map +1 -0
- package/lib/module/fabric/ScreenStackNativeComponent.js +28 -0
- package/lib/module/fabric/ScreenStackNativeComponent.js.map +1 -0
- package/lib/module/fabric/SearchBarNativeComponent.js +10 -0
- package/lib/module/fabric/SearchBarNativeComponent.js.map +1 -0
- package/lib/module/index.js +67 -0
- package/lib/module/index.js.map +1 -0
- package/lib/module/index.native.js +410 -0
- package/lib/module/index.native.js.map +1 -0
- package/lib/module/native-stack/index.js +22 -0
- package/lib/module/native-stack/index.js.map +1 -0
- package/lib/module/native-stack/navigators/createNativeStackNavigator.js +72 -0
- package/lib/module/native-stack/navigators/createNativeStackNavigator.js.map +1 -0
- package/lib/module/native-stack/types.js +2 -0
- package/lib/module/native-stack/types.js.map +1 -0
- package/lib/module/native-stack/utils/AnimatedHeaderHeightContext.js +4 -0
- package/lib/module/native-stack/utils/AnimatedHeaderHeightContext.js.map +1 -0
- package/lib/module/native-stack/utils/HeaderHeightContext.js +4 -0
- package/lib/module/native-stack/utils/HeaderHeightContext.js.map +1 -0
- package/lib/module/native-stack/utils/SafeAreaProviderCompat.js +68 -0
- package/lib/module/native-stack/utils/SafeAreaProviderCompat.js.map +1 -0
- package/lib/module/native-stack/utils/getDefaultHeaderHeight.js +29 -0
- package/lib/module/native-stack/utils/getDefaultHeaderHeight.js.map +1 -0
- package/lib/module/native-stack/utils/useAnimatedHeaderHeight.js +10 -0
- package/lib/module/native-stack/utils/useAnimatedHeaderHeight.js.map +1 -0
- package/lib/module/native-stack/utils/useBackPressSubscription.js +47 -0
- package/lib/module/native-stack/utils/useBackPressSubscription.js.map +1 -0
- package/lib/module/native-stack/utils/useHeaderHeight.js +10 -0
- package/lib/module/native-stack/utils/useHeaderHeight.js.map +1 -0
- package/lib/module/native-stack/views/FontProcessor.js +13 -0
- package/lib/module/native-stack/views/FontProcessor.js.map +1 -0
- package/lib/module/native-stack/views/HeaderConfig.js +132 -0
- package/lib/module/native-stack/views/HeaderConfig.js.map +1 -0
- package/lib/module/native-stack/views/NativeStackView.js +355 -0
- package/lib/module/native-stack/views/NativeStackView.js.map +1 -0
- package/lib/module/reanimated/ReanimatedHeaderHeightContext.js +5 -0
- package/lib/module/reanimated/ReanimatedHeaderHeightContext.js.map +1 -0
- package/lib/module/reanimated/ReanimatedNativeStackScreen.js +97 -0
- package/lib/module/reanimated/ReanimatedNativeStackScreen.js.map +1 -0
- package/lib/module/reanimated/ReanimatedScreen.js +17 -0
- package/lib/module/reanimated/ReanimatedScreen.js.map +1 -0
- package/lib/module/reanimated/ReanimatedScreenProvider.js +40 -0
- package/lib/module/reanimated/ReanimatedScreenProvider.js.map +1 -0
- package/lib/module/reanimated/ReanimatedTransitionProgressContext.js +5 -0
- package/lib/module/reanimated/ReanimatedTransitionProgressContext.js.map +1 -0
- package/lib/module/reanimated/index.js +4 -0
- package/lib/module/reanimated/index.js.map +1 -0
- package/lib/module/reanimated/useReanimatedHeaderHeight.js +10 -0
- package/lib/module/reanimated/useReanimatedHeaderHeight.js.map +1 -0
- package/lib/module/reanimated/useReanimatedTransitionProgress.js +10 -0
- package/lib/module/reanimated/useReanimatedTransitionProgress.js.map +1 -0
- package/lib/module/types.js +2 -0
- package/lib/module/types.js.map +1 -0
- package/lib/module/useTransitionProgress.js +10 -0
- package/lib/module/useTransitionProgress.js.map +1 -0
- package/lib/module/utils.js +14 -0
- package/lib/module/utils.js.map +1 -0
- package/lib/typescript/TransitionProgressContext.d.ts +9 -0
- package/lib/typescript/fabric/FullWindowOverlayNativeComponent.d.ts +7 -0
- package/lib/typescript/fabric/ScreenContainerNativeComponent.d.ts +5 -0
- package/lib/typescript/fabric/ScreenNativeComponent.d.ts +66 -0
- package/lib/typescript/fabric/ScreenNavigationContainerNativeComponent.d.ts +7 -0
- package/lib/typescript/fabric/ScreenStackHeaderConfigNativeComponent.d.ts +33 -0
- package/lib/typescript/fabric/ScreenStackHeaderSubviewNativeComponent.d.ts +10 -0
- package/lib/typescript/fabric/ScreenStackNativeComponent.d.ts +8 -0
- package/lib/typescript/fabric/SearchBarNativeComponent.d.ts +49 -0
- package/lib/typescript/index.d.ts +33 -0
- package/lib/typescript/index.native.d.ts +2 -0
- package/lib/typescript/native-stack/index.d.ts +19 -0
- package/lib/typescript/native-stack/navigators/createNativeStackNavigator.d.ts +6 -0
- package/lib/typescript/native-stack/types.d.ts +438 -0
- package/lib/typescript/native-stack/utils/AnimatedHeaderHeightContext.d.ts +4 -0
- package/lib/typescript/native-stack/utils/HeaderHeightContext.d.ts +3 -0
- package/lib/typescript/native-stack/utils/SafeAreaProviderCompat.d.ts +11 -0
- package/lib/typescript/native-stack/utils/getDefaultHeaderHeight.d.ts +7 -0
- package/lib/typescript/native-stack/utils/useAnimatedHeaderHeight.d.ts +1 -0
- package/lib/typescript/native-stack/utils/useBackPressSubscription.d.ts +16 -0
- package/lib/typescript/native-stack/utils/useHeaderHeight.d.ts +1 -0
- package/lib/typescript/native-stack/views/FontProcessor.d.ts +1 -0
- package/lib/typescript/native-stack/views/HeaderConfig.d.ts +8 -0
- package/lib/typescript/native-stack/views/NativeStackView.d.ts +10 -0
- package/lib/typescript/reanimated/ReanimatedHeaderHeightContext.d.ts +4 -0
- package/lib/typescript/reanimated/ReanimatedNativeStackScreen.d.ts +5 -0
- package/lib/typescript/reanimated/ReanimatedScreen.d.ts +5 -0
- package/lib/typescript/reanimated/ReanimatedScreenProvider.d.ts +2 -0
- package/lib/typescript/reanimated/ReanimatedTransitionProgressContext.d.ts +9 -0
- package/lib/typescript/reanimated/index.d.ts +3 -0
- package/lib/typescript/reanimated/useReanimatedHeaderHeight.d.ts +3 -0
- package/lib/typescript/reanimated/useReanimatedTransitionProgress.d.ts +11 -0
- package/lib/typescript/types.d.ts +612 -0
- package/lib/typescript/useTransitionProgress.d.ts +5 -0
- package/lib/typescript/utils.d.ts +3 -0
- package/native-stack/README.md +814 -0
- package/native-stack/package.json +6 -0
- package/package.json +1 -0
- package/react-native.config.js +42 -0
- package/reanimated/package.json +6 -0
- package/src/TransitionProgressContext.tsx +12 -0
- package/src/fabric/FullWindowOverlayNativeComponent.ts +7 -0
- package/src/fabric/ScreenContainerNativeComponent.ts +28 -0
- package/src/fabric/ScreenNativeComponent.ts +158 -0
- package/src/fabric/ScreenNavigationContainerNativeComponent.ts +10 -0
- package/src/fabric/ScreenStackHeaderConfigNativeComponent.ts +61 -0
- package/src/fabric/ScreenStackHeaderSubviewNativeComponent.ts +22 -0
- package/src/fabric/ScreenStackNativeComponent.ts +33 -0
- package/src/fabric/SearchBarNativeComponent.ts +79 -0
- package/src/index.native.tsx +599 -0
- package/src/index.tsx +119 -0
- package/src/native-stack/index.tsx +27 -0
- package/src/native-stack/navigators/createNativeStackNavigator.tsx +107 -0
- package/src/native-stack/types.tsx +486 -0
- package/src/native-stack/utils/AnimatedHeaderHeightContext.tsx +8 -0
- package/src/native-stack/utils/HeaderHeightContext.tsx +5 -0
- package/src/native-stack/utils/SafeAreaProviderCompat.tsx +78 -0
- package/src/native-stack/utils/getDefaultHeaderHeight.tsx +41 -0
- package/src/native-stack/utils/useAnimatedHeaderHeight.tsx +15 -0
- package/src/native-stack/utils/useBackPressSubscription.tsx +66 -0
- package/src/native-stack/utils/useHeaderHeight.tsx +15 -0
- package/src/native-stack/views/FontProcessor.tsx +14 -0
- package/src/native-stack/views/HeaderConfig.tsx +187 -0
- package/src/native-stack/views/NativeStackView.tsx +466 -0
- package/src/reanimated/ReanimatedHeaderHeightContext.tsx +7 -0
- package/src/reanimated/ReanimatedNativeStackScreen.tsx +130 -0
- package/src/reanimated/ReanimatedScreen.tsx +25 -0
- package/src/reanimated/ReanimatedScreenProvider.tsx +42 -0
- package/src/reanimated/ReanimatedTransitionProgressContext.tsx +13 -0
- package/src/reanimated/index.tsx +3 -0
- package/src/reanimated/useReanimatedHeaderHeight.tsx +14 -0
- package/src/reanimated/useReanimatedTransitionProgress.tsx +14 -0
- package/src/types.tsx +699 -0
- package/src/useTransitionProgress.tsx +15 -0
- package/src/utils.ts +18 -0
- package/windows/README.md +25 -0
- package/windows/RNScreens/PropertySheet.props +16 -0
- package/windows/RNScreens/RNScreens.cpp +66 -0
- package/windows/RNScreens/RNScreens.def +3 -0
- package/windows/RNScreens/RNScreens.h +41 -0
- package/windows/RNScreens/RNScreens.idl +8 -0
- package/windows/RNScreens/RNScreens.vcxproj +187 -0
- package/windows/RNScreens/RNScreens.vcxproj.filters +52 -0
- package/windows/RNScreens/ReactPackageProvider.cpp +30 -0
- package/windows/RNScreens/ReactPackageProvider.h +17 -0
- package/windows/RNScreens/ReactPackageProvider.idl +9 -0
- package/windows/RNScreens/Screen.cpp +122 -0
- package/windows/RNScreens/Screen.h +64 -0
- package/windows/RNScreens/ScreenContainer.cpp +49 -0
- package/windows/RNScreens/ScreenContainer.h +23 -0
- package/windows/RNScreens/ScreenContainerViewManager.cpp +133 -0
- package/windows/RNScreens/ScreenContainerViewManager.h +78 -0
- package/windows/RNScreens/ScreenStack.cpp +65 -0
- package/windows/RNScreens/ScreenStack.h +23 -0
- package/windows/RNScreens/ScreenStackHeaderConfig.cpp +19 -0
- package/windows/RNScreens/ScreenStackHeaderConfig.h +14 -0
- package/windows/RNScreens/ScreenStackHeaderConfigViewManager.cpp +89 -0
- package/windows/RNScreens/ScreenStackHeaderConfigViewManager.h +62 -0
- package/windows/RNScreens/ScreenStackViewManager.cpp +132 -0
- package/windows/RNScreens/ScreenStackViewManager.h +78 -0
- package/windows/RNScreens/ScreenViewManager.cpp +154 -0
- package/windows/RNScreens/ScreenViewManager.h +78 -0
- package/windows/RNScreens/packages.config +4 -0
- package/windows/RNScreens/pch.cpp +1 -0
- package/windows/RNScreens/pch.h +9 -0
- package/windows/RNScreens62.sln +254 -0
- package/windows/RNScreens63.sln +225 -0
- package/windows/RNScreens65.sln +144 -0
|
@@ -0,0 +1,331 @@
|
|
|
1
|
+
package com.swmansion.rnscreens
|
|
2
|
+
|
|
3
|
+
import android.annotation.SuppressLint
|
|
4
|
+
import android.app.Activity
|
|
5
|
+
import android.content.Context
|
|
6
|
+
import android.os.Bundle
|
|
7
|
+
import android.view.LayoutInflater
|
|
8
|
+
import android.view.View
|
|
9
|
+
import android.view.ViewGroup
|
|
10
|
+
import android.view.ViewParent
|
|
11
|
+
import android.widget.FrameLayout
|
|
12
|
+
import androidx.fragment.app.Fragment
|
|
13
|
+
import com.facebook.react.bridge.ReactContext
|
|
14
|
+
import com.facebook.react.bridge.UiThreadUtil
|
|
15
|
+
import com.facebook.react.uimanager.UIManagerHelper
|
|
16
|
+
import com.facebook.react.uimanager.events.Event
|
|
17
|
+
import com.facebook.react.uimanager.events.EventDispatcher
|
|
18
|
+
import com.swmansion.rnscreens.events.HeaderBackButtonClickedEvent
|
|
19
|
+
import com.swmansion.rnscreens.events.ScreenAppearEvent
|
|
20
|
+
import com.swmansion.rnscreens.events.ScreenDisappearEvent
|
|
21
|
+
import com.swmansion.rnscreens.events.ScreenDismissedEvent
|
|
22
|
+
import com.swmansion.rnscreens.events.ScreenTransitionProgressEvent
|
|
23
|
+
import com.swmansion.rnscreens.events.ScreenWillAppearEvent
|
|
24
|
+
import com.swmansion.rnscreens.events.ScreenWillDisappearEvent
|
|
25
|
+
import kotlin.math.max
|
|
26
|
+
import kotlin.math.min
|
|
27
|
+
|
|
28
|
+
open class ScreenFragment : Fragment, ScreenFragmentWrapper {
|
|
29
|
+
enum class ScreenLifecycleEvent {
|
|
30
|
+
Appear, WillAppear, Disappear, WillDisappear
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
override val fragment: Fragment
|
|
34
|
+
get() = this
|
|
35
|
+
|
|
36
|
+
// if we call empty constructor, there is no screen to be assigned so not sure why it is suggested
|
|
37
|
+
@Suppress("JoinDeclarationAndAssignment")
|
|
38
|
+
override lateinit var screen: Screen
|
|
39
|
+
private val mChildScreenContainers: MutableList<ScreenContainer> = ArrayList()
|
|
40
|
+
private var shouldUpdateOnResume = false
|
|
41
|
+
// if we don't set it, it will be 0.0f at the beginning so the progress will not be sent
|
|
42
|
+
// due to progress value being already 0.0f
|
|
43
|
+
private var mProgress = -1f
|
|
44
|
+
|
|
45
|
+
// those 2 vars are needed since sometimes the events would be dispatched twice in child containers
|
|
46
|
+
// (should only happen if parent has `NONE` animation) and we don't need too complicated logic.
|
|
47
|
+
// We just check if, after the event was dispatched, its "counter-event" has been also dispatched before sending the same event again.
|
|
48
|
+
// We do it for 'willAppear' -> 'willDisappear' and 'appear' -> 'disappear'
|
|
49
|
+
private var canDispatchWillAppear = true
|
|
50
|
+
private var canDispatchAppear = true
|
|
51
|
+
|
|
52
|
+
// we want to know if we are currently transitioning in order not to fire lifecycle events
|
|
53
|
+
// in nested fragments. See more explanation in dispatchViewAnimationEvent
|
|
54
|
+
private var isTransitioning = false
|
|
55
|
+
|
|
56
|
+
constructor() {
|
|
57
|
+
throw IllegalStateException(
|
|
58
|
+
"Screen fragments should never be restored. Follow instructions from https://github.com/software-mansion/react-native-screens/issues/17#issuecomment-424704067 to properly configure your main activity."
|
|
59
|
+
)
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
@SuppressLint("ValidFragment")
|
|
63
|
+
constructor(screenView: Screen) : super() {
|
|
64
|
+
screen = screenView
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
override fun onResume() {
|
|
68
|
+
super.onResume()
|
|
69
|
+
if (shouldUpdateOnResume) {
|
|
70
|
+
shouldUpdateOnResume = false
|
|
71
|
+
ScreenWindowTraits.trySetWindowTraits(screen, tryGetActivity(), tryGetContext())
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
override fun onCreateView(
|
|
76
|
+
inflater: LayoutInflater,
|
|
77
|
+
container: ViewGroup?,
|
|
78
|
+
savedInstanceState: Bundle?
|
|
79
|
+
): View? {
|
|
80
|
+
screen.layoutParams = FrameLayout.LayoutParams(
|
|
81
|
+
ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT
|
|
82
|
+
)
|
|
83
|
+
val wrapper = context?.let { ScreensFrameLayout(it) }?.apply {
|
|
84
|
+
addView(recycleView(screen))
|
|
85
|
+
}
|
|
86
|
+
return wrapper
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
private class ScreensFrameLayout(
|
|
90
|
+
context: Context,
|
|
91
|
+
) : FrameLayout(context) {
|
|
92
|
+
/**
|
|
93
|
+
* This method implements a workaround for RN's autoFocus functionality. Because of the way
|
|
94
|
+
* autoFocus is implemented it dismisses soft keyboard in fragment transition
|
|
95
|
+
* due to change of visibility of the view at the start of the transition. Here we override the
|
|
96
|
+
* call to `clearFocus` when the visibility of view is `INVISIBLE` since `clearFocus` triggers the
|
|
97
|
+
* hiding of the keyboard in `ReactEditText.java`.
|
|
98
|
+
*/
|
|
99
|
+
override fun clearFocus() {
|
|
100
|
+
if (visibility != INVISIBLE) {
|
|
101
|
+
super.clearFocus()
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
override fun onContainerUpdate() {
|
|
107
|
+
updateWindowTraits()
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
private fun updateWindowTraits() {
|
|
111
|
+
val activity: Activity? = activity
|
|
112
|
+
if (activity == null) {
|
|
113
|
+
shouldUpdateOnResume = true
|
|
114
|
+
return
|
|
115
|
+
}
|
|
116
|
+
ScreenWindowTraits.trySetWindowTraits(screen, activity, tryGetContext())
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
override fun tryGetActivity(): Activity? {
|
|
120
|
+
activity?.let { return it }
|
|
121
|
+
val context = screen.context
|
|
122
|
+
if (context is ReactContext && context.currentActivity != null) {
|
|
123
|
+
return context.currentActivity
|
|
124
|
+
}
|
|
125
|
+
var parent: ViewParent? = screen.container
|
|
126
|
+
while (parent != null) {
|
|
127
|
+
if (parent is Screen) {
|
|
128
|
+
val fragment = parent.fragment
|
|
129
|
+
fragment?.activity?.let { return it }
|
|
130
|
+
}
|
|
131
|
+
parent = parent.parent
|
|
132
|
+
}
|
|
133
|
+
return null
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
override fun tryGetContext(): ReactContext? {
|
|
137
|
+
if (context is ReactContext) {
|
|
138
|
+
return context as ReactContext
|
|
139
|
+
}
|
|
140
|
+
if (screen.context is ReactContext) {
|
|
141
|
+
return screen.context as ReactContext
|
|
142
|
+
}
|
|
143
|
+
var parent: ViewParent? = screen.container
|
|
144
|
+
while (parent != null) {
|
|
145
|
+
if (parent is Screen) {
|
|
146
|
+
if (parent.context is ReactContext) {
|
|
147
|
+
return parent.context as ReactContext
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
parent = parent.parent
|
|
151
|
+
}
|
|
152
|
+
return null
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
override val childScreenContainers: List<ScreenContainer>
|
|
156
|
+
get() = mChildScreenContainers
|
|
157
|
+
|
|
158
|
+
override fun canDispatchLifecycleEvent(event: ScreenLifecycleEvent): Boolean = when (event) {
|
|
159
|
+
ScreenLifecycleEvent.WillAppear -> canDispatchWillAppear
|
|
160
|
+
ScreenLifecycleEvent.Appear -> canDispatchAppear
|
|
161
|
+
ScreenLifecycleEvent.WillDisappear -> !canDispatchWillAppear
|
|
162
|
+
ScreenLifecycleEvent.Disappear -> !canDispatchAppear
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
override fun updateLastEventDispatched(event: ScreenLifecycleEvent) {
|
|
166
|
+
when (event) {
|
|
167
|
+
ScreenLifecycleEvent.WillAppear -> canDispatchWillAppear = false
|
|
168
|
+
ScreenLifecycleEvent.Appear -> canDispatchAppear = false
|
|
169
|
+
ScreenLifecycleEvent.WillDisappear -> canDispatchWillAppear = true
|
|
170
|
+
ScreenLifecycleEvent.Disappear -> canDispatchAppear = true
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
private fun dispatchOnWillAppear() {
|
|
175
|
+
dispatchLifecycleEvent(ScreenLifecycleEvent.WillAppear, this)
|
|
176
|
+
dispatchTransitionProgressEvent(0.0f, false)
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
private fun dispatchOnAppear() {
|
|
180
|
+
dispatchLifecycleEvent(ScreenLifecycleEvent.Appear, this)
|
|
181
|
+
dispatchTransitionProgressEvent(1.0f, false)
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
private fun dispatchOnWillDisappear() {
|
|
185
|
+
dispatchLifecycleEvent(ScreenLifecycleEvent.WillDisappear, this)
|
|
186
|
+
dispatchTransitionProgressEvent(0.0f, true)
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
private fun dispatchOnDisappear() {
|
|
190
|
+
dispatchLifecycleEvent(ScreenLifecycleEvent.Disappear, this)
|
|
191
|
+
dispatchTransitionProgressEvent(1.0f, true)
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
override fun dispatchLifecycleEvent(event: ScreenLifecycleEvent, fragmentWrapper: ScreenFragmentWrapper) {
|
|
195
|
+
val fragment = fragmentWrapper.fragment
|
|
196
|
+
if (fragment is ScreenStackFragment && fragment.canDispatchLifecycleEvent(event)) {
|
|
197
|
+
fragment.screen.let {
|
|
198
|
+
fragmentWrapper.updateLastEventDispatched(event)
|
|
199
|
+
val surfaceId = UIManagerHelper.getSurfaceId(it)
|
|
200
|
+
val lifecycleEvent: Event<*> = when (event) {
|
|
201
|
+
ScreenLifecycleEvent.WillAppear -> ScreenWillAppearEvent(surfaceId, it.id)
|
|
202
|
+
ScreenLifecycleEvent.Appear -> ScreenAppearEvent(surfaceId, it.id)
|
|
203
|
+
ScreenLifecycleEvent.WillDisappear -> ScreenWillDisappearEvent(surfaceId, it.id)
|
|
204
|
+
ScreenLifecycleEvent.Disappear -> ScreenDisappearEvent(surfaceId, it.id)
|
|
205
|
+
}
|
|
206
|
+
val screenContext = screen.context as ReactContext
|
|
207
|
+
val eventDispatcher: EventDispatcher? =
|
|
208
|
+
UIManagerHelper.getEventDispatcherForReactTag(screenContext, screen.id)
|
|
209
|
+
eventDispatcher?.dispatchEvent(lifecycleEvent)
|
|
210
|
+
fragmentWrapper.dispatchLifecycleEventInChildContainers(event)
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
override fun dispatchLifecycleEventInChildContainers(event: ScreenLifecycleEvent) {
|
|
216
|
+
mChildScreenContainers.filter { it.screenCount > 0 }.forEach {
|
|
217
|
+
it.topScreen?.fragmentWrapper?.let { fragment -> dispatchLifecycleEvent(event, fragment) }
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
override fun dispatchHeaderBackButtonClickedEvent() {
|
|
222
|
+
val screenContext = screen.context as ReactContext
|
|
223
|
+
val surfaceId = UIManagerHelper.getSurfaceId(screenContext)
|
|
224
|
+
UIManagerHelper
|
|
225
|
+
.getEventDispatcherForReactTag(screenContext, screen.id)
|
|
226
|
+
?.dispatchEvent(HeaderBackButtonClickedEvent(surfaceId, screen.id))
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
override fun dispatchTransitionProgressEvent(alpha: Float, closing: Boolean) {
|
|
230
|
+
if (this is ScreenStackFragment) {
|
|
231
|
+
if (mProgress != alpha) {
|
|
232
|
+
mProgress = max(0.0f, min(1.0f, alpha))
|
|
233
|
+
/* We want value of 0 and 1 to be always dispatched so we base coalescing key on the progress:
|
|
234
|
+
- progress is 0 -> key 1
|
|
235
|
+
- progress is 1 -> key 2
|
|
236
|
+
- progress is between 0 and 1 -> key 3
|
|
237
|
+
*/
|
|
238
|
+
val coalescingKey = (if (mProgress == 0.0f) 1 else if (mProgress == 1.0f) 2 else 3).toShort()
|
|
239
|
+
val container: ScreenContainer? = screen.container
|
|
240
|
+
val goingForward = if (container is ScreenStack) container.goingForward else false
|
|
241
|
+
val screenContext = screen.context as ReactContext
|
|
242
|
+
UIManagerHelper
|
|
243
|
+
.getEventDispatcherForReactTag(screenContext, screen.id)
|
|
244
|
+
?.dispatchEvent(
|
|
245
|
+
ScreenTransitionProgressEvent(
|
|
246
|
+
UIManagerHelper.getSurfaceId(screenContext),
|
|
247
|
+
screen.id, mProgress, closing, goingForward, coalescingKey
|
|
248
|
+
)
|
|
249
|
+
)
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
override fun addChildScreenContainer(container: ScreenContainer) {
|
|
255
|
+
mChildScreenContainers.add(container)
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
override fun removeChildScreenContainer(container: ScreenContainer) {
|
|
259
|
+
mChildScreenContainers.remove(container)
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
override fun onViewAnimationStart() {
|
|
263
|
+
dispatchViewAnimationEvent(false)
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
override fun onViewAnimationEnd() {
|
|
267
|
+
dispatchViewAnimationEvent(true)
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
private fun dispatchViewAnimationEvent(animationEnd: Boolean) {
|
|
271
|
+
isTransitioning = !animationEnd
|
|
272
|
+
// if parent fragment is transitioning, we do not want the events dispatched from the child,
|
|
273
|
+
// since we subscribe to parent's animation start/end and dispatch events in child from there
|
|
274
|
+
// check for `isTransitioning` should be enough since the child's animation should take only
|
|
275
|
+
// 20ms due to always being `StackAnimation.NONE` when nested stack being pushed
|
|
276
|
+
val parent = parentFragment
|
|
277
|
+
if (parent == null || (parent is ScreenFragment && !parent.isTransitioning)) {
|
|
278
|
+
// onViewAnimationStart/End is triggered from View#onAnimationStart/End method of the fragment's root
|
|
279
|
+
// view. We override an appropriate method of the StackFragment's
|
|
280
|
+
// root view in order to achieve this.
|
|
281
|
+
if (isResumed) {
|
|
282
|
+
// Android dispatches the animation start event for the fragment that is being added first
|
|
283
|
+
// however we want the one being dismissed first to match iOS. It also makes more sense from
|
|
284
|
+
// a navigation point of view to have the disappear event first.
|
|
285
|
+
// Since there are no explicit relationships between the fragment being added / removed the
|
|
286
|
+
// practical way to fix this is delaying dispatching the appear events at the end of the
|
|
287
|
+
// frame.
|
|
288
|
+
UiThreadUtil.runOnUiThread {
|
|
289
|
+
if (animationEnd) dispatchOnAppear() else dispatchOnWillAppear()
|
|
290
|
+
}
|
|
291
|
+
} else {
|
|
292
|
+
if (animationEnd) dispatchOnDisappear() else dispatchOnWillDisappear()
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
override fun onDestroy() {
|
|
298
|
+
super.onDestroy()
|
|
299
|
+
val container = screen.container
|
|
300
|
+
if (container == null || !container.hasScreen(this)) {
|
|
301
|
+
// we only send dismissed even when the screen has been removed from its container
|
|
302
|
+
val screenContext = screen.context
|
|
303
|
+
if (screenContext is ReactContext) {
|
|
304
|
+
val surfaceId = UIManagerHelper.getSurfaceId(screenContext)
|
|
305
|
+
UIManagerHelper
|
|
306
|
+
.getEventDispatcherForReactTag(screenContext, screen.id)
|
|
307
|
+
?.dispatchEvent(ScreenDismissedEvent(surfaceId, screen.id))
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
mChildScreenContainers.clear()
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
companion object {
|
|
314
|
+
@JvmStatic
|
|
315
|
+
protected fun recycleView(view: View): View {
|
|
316
|
+
// screen fragments reuse view instances instead of creating new ones. In order to reuse a given
|
|
317
|
+
// view it needs to be detached from the view hierarchy to allow the fragment to attach it back.
|
|
318
|
+
val parent = view.parent
|
|
319
|
+
if (parent != null) {
|
|
320
|
+
(parent as ViewGroup).endViewTransition(view)
|
|
321
|
+
parent.removeView(view)
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
// view detached from fragment manager get their visibility changed to GONE after their state is
|
|
325
|
+
// dumped. Since we don't restore the state but want to reuse the view we need to change
|
|
326
|
+
// visibility back to VISIBLE in order for the fragment manager to animate in the view.
|
|
327
|
+
view.visibility = View.VISIBLE
|
|
328
|
+
return view
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
package com.swmansion.rnscreens
|
|
2
|
+
|
|
3
|
+
import android.app.Activity
|
|
4
|
+
import com.facebook.react.bridge.ReactContext
|
|
5
|
+
|
|
6
|
+
interface ScreenFragmentWrapper : FragmentHolder, ScreenEventDispatcher {
|
|
7
|
+
var screen: Screen
|
|
8
|
+
|
|
9
|
+
// Communication with container
|
|
10
|
+
val childScreenContainers: List<ScreenContainer>
|
|
11
|
+
fun addChildScreenContainer(container: ScreenContainer)
|
|
12
|
+
fun removeChildScreenContainer(container: ScreenContainer)
|
|
13
|
+
fun onContainerUpdate()
|
|
14
|
+
|
|
15
|
+
// Animation phase callbacks
|
|
16
|
+
fun onViewAnimationStart()
|
|
17
|
+
fun onViewAnimationEnd()
|
|
18
|
+
|
|
19
|
+
// Helpers
|
|
20
|
+
fun tryGetActivity(): Activity?
|
|
21
|
+
fun tryGetContext(): ReactContext?
|
|
22
|
+
}
|
|
@@ -0,0 +1,336 @@
|
|
|
1
|
+
package com.swmansion.rnscreens
|
|
2
|
+
|
|
3
|
+
import android.content.Context
|
|
4
|
+
import android.graphics.Canvas
|
|
5
|
+
import android.view.View
|
|
6
|
+
import com.facebook.react.bridge.ReactContext
|
|
7
|
+
import com.facebook.react.uimanager.UIManagerHelper
|
|
8
|
+
import com.swmansion.rnscreens.Screen.StackAnimation
|
|
9
|
+
import com.swmansion.rnscreens.events.StackFinishTransitioningEvent
|
|
10
|
+
import java.util.Collections
|
|
11
|
+
import kotlin.collections.ArrayList
|
|
12
|
+
import kotlin.collections.HashSet
|
|
13
|
+
|
|
14
|
+
class ScreenStack(context: Context?) : ScreenContainer(context) {
|
|
15
|
+
private val mStack = ArrayList<ScreenStackFragmentWrapper>()
|
|
16
|
+
private val mDismissed: MutableSet<ScreenStackFragmentWrapper> = HashSet()
|
|
17
|
+
private val drawingOpPool: MutableList<DrawingOp> = ArrayList()
|
|
18
|
+
private var drawingOps: MutableList<DrawingOp> = ArrayList()
|
|
19
|
+
private var mTopScreen: ScreenStackFragmentWrapper? = null
|
|
20
|
+
private var mRemovalTransitionStarted = false
|
|
21
|
+
private var isDetachingCurrentScreen = false
|
|
22
|
+
private var reverseLastTwoChildren = false
|
|
23
|
+
private var previousChildrenCount = 0
|
|
24
|
+
var goingForward = false
|
|
25
|
+
|
|
26
|
+
fun dismiss(screenFragment: ScreenStackFragmentWrapper) {
|
|
27
|
+
mDismissed.add(screenFragment)
|
|
28
|
+
performUpdatesNow()
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
override val topScreen: Screen?
|
|
32
|
+
get() = mTopScreen?.screen
|
|
33
|
+
|
|
34
|
+
val rootScreen: Screen
|
|
35
|
+
get() {
|
|
36
|
+
for (i in 0 until screenCount) {
|
|
37
|
+
val screenWrapper = getScreenFragmentWrapperAt(i)
|
|
38
|
+
if (!mDismissed.contains(screenWrapper)) {
|
|
39
|
+
return screenWrapper.screen
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
throw IllegalStateException("Stack has no root screen set")
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
override fun adapt(screen: Screen) = ScreenStackFragment(screen)
|
|
46
|
+
|
|
47
|
+
override fun startViewTransition(view: View) {
|
|
48
|
+
super.startViewTransition(view)
|
|
49
|
+
mRemovalTransitionStarted = true
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
override fun endViewTransition(view: View) {
|
|
53
|
+
super.endViewTransition(view)
|
|
54
|
+
if (mRemovalTransitionStarted) {
|
|
55
|
+
mRemovalTransitionStarted = false
|
|
56
|
+
dispatchOnFinishTransitioning()
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
fun onViewAppearTransitionEnd() {
|
|
61
|
+
if (!mRemovalTransitionStarted) {
|
|
62
|
+
dispatchOnFinishTransitioning()
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
private fun dispatchOnFinishTransitioning() {
|
|
67
|
+
val surfaceId = UIManagerHelper.getSurfaceId(this)
|
|
68
|
+
UIManagerHelper
|
|
69
|
+
.getEventDispatcherForReactTag((context as ReactContext), id)
|
|
70
|
+
?.dispatchEvent(StackFinishTransitioningEvent(surfaceId, id))
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
override fun removeScreenAt(index: Int) {
|
|
74
|
+
mDismissed.remove(getScreenFragmentWrapperAt(index))
|
|
75
|
+
super.removeScreenAt(index)
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
override fun removeAllScreens() {
|
|
79
|
+
mDismissed.clear()
|
|
80
|
+
super.removeAllScreens()
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
override fun hasScreen(screenFragmentWrapper: ScreenFragmentWrapper?): Boolean =
|
|
84
|
+
super.hasScreen(screenFragmentWrapper) && !mDismissed.contains(screenFragmentWrapper)
|
|
85
|
+
|
|
86
|
+
override fun onUpdate() {
|
|
87
|
+
// When going back from a nested stack with a single screen on it, we may hit an edge case
|
|
88
|
+
// when all screens are dismissed and no screen is to be displayed on top. We need to gracefully
|
|
89
|
+
// handle the case of newTop being NULL, which happens in several places below
|
|
90
|
+
var newTop: ScreenFragmentWrapper? = null // newTop is nullable, see the above comment ^
|
|
91
|
+
var visibleBottom: ScreenFragmentWrapper? = null // this is only set if newTop has TRANSPARENT_MODAL presentation mode
|
|
92
|
+
isDetachingCurrentScreen = false // we reset it so the previous value is not used by mistake
|
|
93
|
+
for (i in mScreenFragments.indices.reversed()) {
|
|
94
|
+
val screen = getScreenFragmentWrapperAt(i)
|
|
95
|
+
if (!mDismissed.contains(screen)) {
|
|
96
|
+
if (newTop == null) {
|
|
97
|
+
newTop = screen
|
|
98
|
+
} else {
|
|
99
|
+
visibleBottom = screen
|
|
100
|
+
}
|
|
101
|
+
if (!isTransparent(screen)) {
|
|
102
|
+
break
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
var shouldUseOpenAnimation = true
|
|
107
|
+
var stackAnimation: StackAnimation? = null
|
|
108
|
+
if (!mStack.contains(newTop)) {
|
|
109
|
+
// if new top screen wasn't on stack we do "open animation" so long it is not the very first
|
|
110
|
+
// screen on stack
|
|
111
|
+
if (mTopScreen != null && newTop != null) {
|
|
112
|
+
// there was some other screen attached before
|
|
113
|
+
// if the previous top screen does not exist anymore and the new top was not on the stack
|
|
114
|
+
// before, probably replace or reset was called, so we play the "close animation".
|
|
115
|
+
// Otherwise it's open animation
|
|
116
|
+
val containsTopScreen = mTopScreen?.let { mScreenFragments.contains(it) } == true
|
|
117
|
+
val isPushReplace = newTop.screen.replaceAnimation === Screen.ReplaceAnimation.PUSH
|
|
118
|
+
shouldUseOpenAnimation = containsTopScreen || isPushReplace
|
|
119
|
+
// if the replace animation is `push`, the new top screen provides the animation, otherwise the previous one
|
|
120
|
+
stackAnimation = if (shouldUseOpenAnimation) newTop.screen.stackAnimation else mTopScreen?.screen?.stackAnimation
|
|
121
|
+
} else if (mTopScreen == null && newTop != null) {
|
|
122
|
+
// mTopScreen was not present before so newTop is the first screen added to a stack
|
|
123
|
+
// and we don't want the animation when it is entering
|
|
124
|
+
stackAnimation = StackAnimation.NONE
|
|
125
|
+
goingForward = true
|
|
126
|
+
}
|
|
127
|
+
} else if (mTopScreen != null && mTopScreen != newTop) {
|
|
128
|
+
// otherwise if we are performing top screen change we do "close animation"
|
|
129
|
+
shouldUseOpenAnimation = false
|
|
130
|
+
stackAnimation = mTopScreen?.screen?.stackAnimation
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
createTransaction().let {
|
|
134
|
+
// animation logic start
|
|
135
|
+
if (stackAnimation != null) {
|
|
136
|
+
if (shouldUseOpenAnimation) {
|
|
137
|
+
when (stackAnimation) {
|
|
138
|
+
StackAnimation.DEFAULT -> it.setCustomAnimations(R.anim.rns_default_enter_in, R.anim.rns_default_enter_out)
|
|
139
|
+
StackAnimation.NONE -> it.setCustomAnimations(R.anim.rns_no_animation_20, R.anim.rns_no_animation_20)
|
|
140
|
+
StackAnimation.FADE -> it.setCustomAnimations(R.anim.rns_fade_in, R.anim.rns_fade_out)
|
|
141
|
+
StackAnimation.SLIDE_FROM_RIGHT -> it.setCustomAnimations(R.anim.rns_slide_in_from_right, R.anim.rns_slide_out_to_left)
|
|
142
|
+
StackAnimation.SLIDE_FROM_LEFT -> it.setCustomAnimations(R.anim.rns_slide_in_from_left, R.anim.rns_slide_out_to_right)
|
|
143
|
+
StackAnimation.SLIDE_FROM_BOTTOM -> it.setCustomAnimations(
|
|
144
|
+
R.anim.rns_slide_in_from_bottom, R.anim.rns_no_animation_medium
|
|
145
|
+
)
|
|
146
|
+
StackAnimation.FADE_FROM_BOTTOM -> it.setCustomAnimations(R.anim.rns_fade_from_bottom, R.anim.rns_no_animation_350)
|
|
147
|
+
}
|
|
148
|
+
} else {
|
|
149
|
+
when (stackAnimation) {
|
|
150
|
+
StackAnimation.DEFAULT -> it.setCustomAnimations(R.anim.rns_default_exit_in, R.anim.rns_default_exit_out)
|
|
151
|
+
StackAnimation.NONE -> it.setCustomAnimations(R.anim.rns_no_animation_20, R.anim.rns_no_animation_20)
|
|
152
|
+
StackAnimation.FADE -> it.setCustomAnimations(R.anim.rns_fade_in, R.anim.rns_fade_out)
|
|
153
|
+
StackAnimation.SLIDE_FROM_RIGHT -> it.setCustomAnimations(R.anim.rns_slide_in_from_left, R.anim.rns_slide_out_to_right)
|
|
154
|
+
StackAnimation.SLIDE_FROM_LEFT -> it.setCustomAnimations(R.anim.rns_slide_in_from_right, R.anim.rns_slide_out_to_left)
|
|
155
|
+
StackAnimation.SLIDE_FROM_BOTTOM -> it.setCustomAnimations(
|
|
156
|
+
R.anim.rns_no_animation_medium, R.anim.rns_slide_out_to_bottom
|
|
157
|
+
)
|
|
158
|
+
StackAnimation.FADE_FROM_BOTTOM -> it.setCustomAnimations(R.anim.rns_no_animation_250, R.anim.rns_fade_to_bottom)
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
// animation logic end
|
|
164
|
+
goingForward = shouldUseOpenAnimation
|
|
165
|
+
|
|
166
|
+
if (shouldUseOpenAnimation &&
|
|
167
|
+
newTop != null && needsDrawReordering(newTop) &&
|
|
168
|
+
visibleBottom == null
|
|
169
|
+
) {
|
|
170
|
+
// When using an open animation in which two screens overlap (eg. fade_from_bottom or
|
|
171
|
+
// slide_from_bottom), we want to draw the previous screen under the new one,
|
|
172
|
+
// which is apparently not the default option. Android always draws the disappearing view
|
|
173
|
+
// on top of the appearing one. We then reverse the order of the views so the new screen
|
|
174
|
+
// appears on top of the previous one. You can read more about in the comment
|
|
175
|
+
// for the code we use to change that behavior:
|
|
176
|
+
// https://github.com/airbnb/native-navigation/blob/9cf50bf9b751b40778f473f3b19fcfe2c4d40599/lib/android/src/main/java/com/airbnb/android/react/navigation/ScreenCoordinatorLayout.java#L18
|
|
177
|
+
isDetachingCurrentScreen = true
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
// remove all screens previously on stack
|
|
181
|
+
for (fragmentWrapper in mStack) {
|
|
182
|
+
if (!mScreenFragments.contains(fragmentWrapper) || mDismissed.contains(fragmentWrapper)) {
|
|
183
|
+
it.remove(fragmentWrapper.fragment)
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
for (fragmentWrapper in mScreenFragments) {
|
|
187
|
+
// Stop detaching screens when reaching visible bottom. All screens above bottom should be
|
|
188
|
+
// visible.
|
|
189
|
+
if (fragmentWrapper === visibleBottom) {
|
|
190
|
+
break
|
|
191
|
+
}
|
|
192
|
+
// detach all screens that should not be visible
|
|
193
|
+
if (fragmentWrapper !== newTop && !mDismissed.contains(fragmentWrapper)) {
|
|
194
|
+
it.remove(fragmentWrapper.fragment)
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
// attach screens that just became visible
|
|
199
|
+
if (visibleBottom != null && !visibleBottom.fragment.isAdded) {
|
|
200
|
+
val top = newTop
|
|
201
|
+
var beneathVisibleBottom = true
|
|
202
|
+
for (fragmentWrapper in mScreenFragments) {
|
|
203
|
+
// ignore all screens beneath the visible bottom
|
|
204
|
+
if (beneathVisibleBottom) {
|
|
205
|
+
beneathVisibleBottom = if (fragmentWrapper === visibleBottom) {
|
|
206
|
+
false
|
|
207
|
+
} else continue
|
|
208
|
+
}
|
|
209
|
+
// when first visible screen found, make all screens after that visible
|
|
210
|
+
it.add(id, fragmentWrapper.fragment).runOnCommit { top?.screen?.bringToFront() }
|
|
211
|
+
}
|
|
212
|
+
} else if (newTop != null && !newTop.fragment.isAdded) {
|
|
213
|
+
it.add(id, newTop.fragment)
|
|
214
|
+
}
|
|
215
|
+
mTopScreen = newTop as? ScreenStackFragmentWrapper
|
|
216
|
+
mStack.clear()
|
|
217
|
+
mStack.addAll(mScreenFragments.map { it as ScreenStackFragmentWrapper })
|
|
218
|
+
|
|
219
|
+
turnOffA11yUnderTransparentScreen(visibleBottom)
|
|
220
|
+
|
|
221
|
+
it.commitNowAllowingStateLoss()
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
// only top visible screen should be accessible
|
|
226
|
+
private fun turnOffA11yUnderTransparentScreen(visibleBottom: ScreenFragmentWrapper?) {
|
|
227
|
+
if (mScreenFragments.size > 1 && visibleBottom != null) {
|
|
228
|
+
mTopScreen?.let {
|
|
229
|
+
if (isTransparent(it)) {
|
|
230
|
+
val screenFragmentsBeneathTop = mScreenFragments.slice(0 until mScreenFragments.size - 1).asReversed()
|
|
231
|
+
// go from the top of the stack excluding the top screen
|
|
232
|
+
for (fragmentWrapper in screenFragmentsBeneathTop) {
|
|
233
|
+
fragmentWrapper.screen.changeAccessibilityMode(IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS)
|
|
234
|
+
|
|
235
|
+
// don't change a11y below non-transparent screens
|
|
236
|
+
if (fragmentWrapper == visibleBottom) {
|
|
237
|
+
break
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
topScreen?.changeAccessibilityMode(IMPORTANT_FOR_ACCESSIBILITY_AUTO)
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
override fun notifyContainerUpdate() {
|
|
248
|
+
mStack.forEach { it.onContainerUpdate() }
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
// below methods are taken from
|
|
252
|
+
// https://github.com/airbnb/native-navigation/blob/9cf50bf9b751b40778f473f3b19fcfe2c4d40599/lib/android/src/main/java/com/airbnb/android/react/navigation/ScreenCoordinatorLayout.java#L43
|
|
253
|
+
// and are used to swap the order of drawing views when navigating forward with the transitions
|
|
254
|
+
// that are making transitioning fragments appear one on another. See more info in the comment to
|
|
255
|
+
// the linked class.
|
|
256
|
+
override fun removeView(view: View) {
|
|
257
|
+
// we set this property to reverse the order of drawing views
|
|
258
|
+
// when we want to push new fragment on top of the previous one and their animations collide.
|
|
259
|
+
// More information in:
|
|
260
|
+
// https://github.com/airbnb/native-navigation/blob/9cf50bf9b751b40778f473f3b19fcfe2c4d40599/lib/android/src/main/java/com/airbnb/android/react/navigation/ScreenCoordinatorLayout.java#L17
|
|
261
|
+
if (isDetachingCurrentScreen) {
|
|
262
|
+
isDetachingCurrentScreen = false
|
|
263
|
+
reverseLastTwoChildren = true
|
|
264
|
+
}
|
|
265
|
+
super.removeView(view)
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
private fun drawAndRelease() {
|
|
269
|
+
// We make a copy of the drawingOps and use it to dispatch draws in order to be sure
|
|
270
|
+
// that we do not modify the original list. There are cases when `op.draw` can call
|
|
271
|
+
// `drawChild` which would modify the list through which we are iterating. See more:
|
|
272
|
+
// https://github.com/software-mansion/react-native-screens/pull/1406
|
|
273
|
+
val drawingOpsCopy = drawingOps
|
|
274
|
+
drawingOps = ArrayList()
|
|
275
|
+
for (op in drawingOpsCopy) {
|
|
276
|
+
op.draw()
|
|
277
|
+
drawingOpPool.add(op)
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
override fun dispatchDraw(canvas: Canvas) {
|
|
282
|
+
super.dispatchDraw(canvas)
|
|
283
|
+
|
|
284
|
+
// check the view removal is completed (by comparing the previous children count)
|
|
285
|
+
if (drawingOps.size < previousChildrenCount) {
|
|
286
|
+
reverseLastTwoChildren = false
|
|
287
|
+
}
|
|
288
|
+
previousChildrenCount = drawingOps.size
|
|
289
|
+
if (reverseLastTwoChildren && drawingOps.size >= 2) {
|
|
290
|
+
Collections.swap(drawingOps, drawingOps.size - 1, drawingOps.size - 2)
|
|
291
|
+
}
|
|
292
|
+
drawAndRelease()
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
override fun drawChild(canvas: Canvas, child: View, drawingTime: Long): Boolean {
|
|
296
|
+
drawingOps.add(
|
|
297
|
+
obtainDrawingOp().apply {
|
|
298
|
+
this.canvas = canvas
|
|
299
|
+
this.child = child
|
|
300
|
+
this.drawingTime = drawingTime
|
|
301
|
+
}
|
|
302
|
+
)
|
|
303
|
+
return true
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
private fun performDraw(op: DrawingOp) {
|
|
307
|
+
// Canvas parameter can not be null here https://developer.android.com/reference/android/view/ViewGroup#drawChild(android.graphics.Canvas,%20android.view.View,%20long)
|
|
308
|
+
// So if we are passing null here, we would crash anyway
|
|
309
|
+
super.drawChild(op.canvas!!, op.child, op.drawingTime)
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
private fun obtainDrawingOp(): DrawingOp =
|
|
313
|
+
if (drawingOpPool.isEmpty()) DrawingOp() else drawingOpPool.removeLast()
|
|
314
|
+
|
|
315
|
+
private inner class DrawingOp {
|
|
316
|
+
var canvas: Canvas? = null
|
|
317
|
+
var child: View? = null
|
|
318
|
+
var drawingTime: Long = 0
|
|
319
|
+
|
|
320
|
+
fun draw() {
|
|
321
|
+
performDraw(this)
|
|
322
|
+
canvas = null
|
|
323
|
+
child = null
|
|
324
|
+
drawingTime = 0
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
companion object {
|
|
329
|
+
private fun isTransparent(fragmentWrapper: ScreenFragmentWrapper): Boolean =
|
|
330
|
+
fragmentWrapper.screen.stackPresentation === Screen.StackPresentation.TRANSPARENT_MODAL
|
|
331
|
+
|
|
332
|
+
private fun needsDrawReordering(fragmentWrapper: ScreenFragmentWrapper): Boolean =
|
|
333
|
+
fragmentWrapper.screen.stackAnimation === StackAnimation.SLIDE_FROM_BOTTOM ||
|
|
334
|
+
fragmentWrapper.screen.stackAnimation === StackAnimation.FADE_FROM_BOTTOM
|
|
335
|
+
}
|
|
336
|
+
}
|