mirror of
https://github.com/zhigang1992/react-navigation.git
synced 2026-01-24 21:08:15 +08:00
Compare commits
116 Commits
2.0.0-alph
...
2.0.0-beta
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
fd7fcfbc5b | ||
|
|
06b928f5c1 | ||
|
|
acb038e213 | ||
|
|
22d4400b93 | ||
|
|
f78c264419 | ||
|
|
65bd436cbe | ||
|
|
a0745762ba | ||
|
|
89658d9361 | ||
|
|
074aabc33e | ||
|
|
eb2a1ae8fd | ||
|
|
9721353e7b | ||
|
|
523b3d8f3a | ||
|
|
f851c26642 | ||
|
|
f8f5d66bf9 | ||
|
|
72037e20fb | ||
|
|
69a23f1c9f | ||
|
|
d32463ee83 | ||
|
|
2da04f37e6 | ||
|
|
623f9452cb | ||
|
|
c646a4e7ba | ||
|
|
a1311cd31d | ||
|
|
f044334464 | ||
|
|
1c7ebeba39 | ||
|
|
1493d6f1b8 | ||
|
|
8cf82d1cbe | ||
|
|
e8403582ae | ||
|
|
5832593980 | ||
|
|
78c7745049 | ||
|
|
350a80c29b | ||
|
|
c460341a68 | ||
|
|
3fc74e29ab | ||
|
|
518c094657 | ||
|
|
d71aa2c6ef | ||
|
|
f21ec66cb4 | ||
|
|
27ef6dc900 | ||
|
|
ce819f6356 | ||
|
|
1ac742610b | ||
|
|
28f57240c2 | ||
|
|
ca6319d26e | ||
|
|
2b1b726723 | ||
|
|
4ce9469571 | ||
|
|
cef9b8f393 | ||
|
|
ecc4056559 | ||
|
|
71a02af309 | ||
|
|
c88da09348 | ||
|
|
9aac0b89f2 | ||
|
|
a02dd46eec | ||
|
|
0919404b2e | ||
|
|
e61b8b3bd6 | ||
|
|
77d877f0c1 | ||
|
|
15c27e3fe7 | ||
|
|
ed478a829d | ||
|
|
a3335b1384 | ||
|
|
e00a08a3dc | ||
|
|
656e82de9f | ||
|
|
1958cf37ea | ||
|
|
75fb558cd3 | ||
|
|
2b55d60780 | ||
|
|
744b37fbc3 | ||
|
|
84d684b52d | ||
|
|
6f9c504627 | ||
|
|
953763f7d9 | ||
|
|
7c351df14d | ||
|
|
da9426b4b9 | ||
|
|
4169fad8b3 | ||
|
|
4f8efd2873 | ||
|
|
cbc86bb6d8 | ||
|
|
0927e03687 | ||
|
|
efaf0cd125 | ||
|
|
21e6a9732a | ||
|
|
31192250e1 | ||
|
|
124e8acb2d | ||
|
|
2c5f95cea6 | ||
|
|
0a2336d005 | ||
|
|
58d1791d4a | ||
|
|
3d56c5d4e2 | ||
|
|
47658d4d7d | ||
|
|
258ae419de | ||
|
|
62123f16f9 | ||
|
|
a94424192b | ||
|
|
752d6c0f04 | ||
|
|
a017713efc | ||
|
|
26384b625e | ||
|
|
5d5e8bfca6 | ||
|
|
2536837795 | ||
|
|
20650a8ede | ||
|
|
ee0dbfe8ae | ||
|
|
23cbc009d4 | ||
|
|
f21a093918 | ||
|
|
1d4712acbd | ||
|
|
09c71a45a2 | ||
|
|
79e664f11d | ||
|
|
b622abc935 | ||
|
|
7d4bbb8f88 | ||
|
|
7c304a007f | ||
|
|
adf3333462 | ||
|
|
d4636d3130 | ||
|
|
4749405d64 | ||
|
|
faff1138f7 | ||
|
|
b9473ccb04 | ||
|
|
5cfe3f2814 | ||
|
|
c7f5fe6554 | ||
|
|
535902014d | ||
|
|
4a9a3a877a | ||
|
|
c590283359 | ||
|
|
77b1e14288 | ||
|
|
cb710c63f7 | ||
|
|
2d54b76cb6 | ||
|
|
f5477eb9e0 | ||
|
|
b8dcda3f7a | ||
|
|
7620c541da | ||
|
|
a229904b57 | ||
|
|
0bf6a2c6cc | ||
|
|
8e71d75fe6 | ||
|
|
5a9b3d1408 | ||
|
|
5281c1b553 |
@@ -11,7 +11,7 @@ import {
|
||||
createSwitchNavigator,
|
||||
createAppContainer,
|
||||
} from 'react-navigation';
|
||||
import { useScreens } from 'react-native-screens';
|
||||
import { enableScreens } from 'react-native-screens';
|
||||
|
||||
import Stack from './stack';
|
||||
import NativeStack from './nativeStack';
|
||||
@@ -20,7 +20,7 @@ import Navigation from './navigation';
|
||||
import NativeNavigation from './nativeNavigation';
|
||||
import NavigationTabsAndStack from './navigationTabsAndStack';
|
||||
|
||||
useScreens();
|
||||
enableScreens();
|
||||
|
||||
const SCREENS = {
|
||||
Stack: { screen: Stack, title: 'Screen container based stack' },
|
||||
|
||||
@@ -175,7 +175,7 @@ dependencies {
|
||||
implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.1.0-alpha02'
|
||||
implementation 'com.facebook.react:react-native:+' // From node_modules
|
||||
|
||||
def hermesPath = "../../node_modules/hermesvm/android/";
|
||||
def hermesPath = "../../node_modules/hermes-engine/android/";
|
||||
debugImplementation files(hermesPath + "hermes-debug.aar")
|
||||
releaseImplementation files(hermesPath + "hermes-release.aar")
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
android:name=".MainApplication"
|
||||
android:label="@string/app_name"
|
||||
android:icon="@mipmap/ic_launcher"
|
||||
android:networkSecurityConfig="@xml/network_security_config"
|
||||
android:usesCleartextTraffic="true"
|
||||
android:allowBackup="false"
|
||||
android:theme="@style/AppTheme">
|
||||
<activity
|
||||
|
||||
@@ -3,6 +3,9 @@ package com.swmansion.rnscreens.example;
|
||||
import android.os.Bundle;
|
||||
|
||||
import com.facebook.react.ReactActivity;
|
||||
import com.facebook.react.ReactActivityDelegate;
|
||||
import com.facebook.react.ReactRootView;
|
||||
import com.swmansion.gesturehandler.react.RNGestureHandlerEnabledRootView;
|
||||
|
||||
public class MainActivity extends ReactActivity {
|
||||
|
||||
@@ -19,4 +22,14 @@ public class MainActivity extends ReactActivity {
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ReactActivityDelegate createReactActivityDelegate() {
|
||||
return new ReactActivityDelegate(this, getMainComponentName()) {
|
||||
@Override
|
||||
protected ReactRootView createRootView() {
|
||||
return new RNGestureHandlerEnabledRootView(MainActivity.this);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@ allprojects {
|
||||
url "$rootDir/../node_modules/react-native/android"
|
||||
}
|
||||
jcenter()
|
||||
maven { url 'https://jitpack.io' }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -2,9 +2,14 @@ platform :ios, '9.0'
|
||||
require_relative '../node_modules/@react-native-community/cli-platform-ios/native_modules'
|
||||
target 'ScreensExample' do
|
||||
# Pods for RnDiffApp
|
||||
pod 'FBLazyVector', :path => "../node_modules/react-native/Libraries/FBLazyVector"
|
||||
pod 'FBReactNativeSpec', :path => "../node_modules/react-native/Libraries/FBReactNativeSpec"
|
||||
pod 'RCTRequired', :path => "../node_modules/react-native/Libraries/RCTRequired"
|
||||
pod 'RCTTypeSafety', :path => "../node_modules/react-native/Libraries/TypeSafety"
|
||||
pod 'React', :path => '../node_modules/react-native/'
|
||||
pod 'React-Core', :path => '../node_modules/react-native/React'
|
||||
pod 'React-DevSupport', :path => '../node_modules/react-native/React'
|
||||
pod 'React-Core', :path => '../node_modules/react-native/'
|
||||
pod 'React-CoreModules', :path => '../node_modules/react-native/React/CoreModules'
|
||||
pod 'React-Core/DevSupport', :path => '../node_modules/react-native/'
|
||||
pod 'React-RCTActionSheet', :path => '../node_modules/react-native/Libraries/ActionSheetIOS'
|
||||
pod 'React-RCTAnimation', :path => '../node_modules/react-native/Libraries/NativeAnimation'
|
||||
pod 'React-RCTBlob', :path => '../node_modules/react-native/Libraries/Blob'
|
||||
@@ -14,12 +19,16 @@ target 'ScreensExample' do
|
||||
pod 'React-RCTSettings', :path => '../node_modules/react-native/Libraries/Settings'
|
||||
pod 'React-RCTText', :path => '../node_modules/react-native/Libraries/Text'
|
||||
pod 'React-RCTVibration', :path => '../node_modules/react-native/Libraries/Vibration'
|
||||
pod 'React-RCTWebSocket', :path => '../node_modules/react-native/Libraries/WebSocket'
|
||||
pod 'React-Core/RCTWebSocket', :path => '../node_modules/react-native/'
|
||||
|
||||
pod 'React-cxxreact', :path => '../node_modules/react-native/ReactCommon/cxxreact'
|
||||
pod 'React-jsi', :path => '../node_modules/react-native/ReactCommon/jsi'
|
||||
pod 'React-jsiexecutor', :path => '../node_modules/react-native/ReactCommon/jsiexecutor'
|
||||
pod 'React-jsinspector', :path => '../node_modules/react-native/ReactCommon/jsinspector'
|
||||
pod 'yoga', :path => '../node_modules/react-native/ReactCommon/yoga'
|
||||
pod 'ReactCommon/jscallinvoker', :path => "../node_modules/react-native/ReactCommon"
|
||||
pod 'ReactCommon/turbomodule/core', :path => "../node_modules/react-native/ReactCommon"
|
||||
pod 'Yoga', :path => '../node_modules/react-native/ReactCommon/yoga'
|
||||
|
||||
pod 'DoubleConversion', :podspec => '../node_modules/react-native/third-party-podspecs/DoubleConversion.podspec'
|
||||
pod 'glog', :podspec => '../node_modules/react-native/third-party-podspecs/glog.podspec'
|
||||
pod 'Folly', :podspec => '../node_modules/react-native/third-party-podspecs/Folly.podspec'
|
||||
|
||||
@@ -1,6 +1,14 @@
|
||||
PODS:
|
||||
- boost-for-react-native (1.63.0)
|
||||
- DoubleConversion (1.1.6)
|
||||
- FBLazyVector (0.61.2)
|
||||
- FBReactNativeSpec (0.61.2):
|
||||
- Folly (= 2018.10.22.00)
|
||||
- RCTRequired (= 0.61.2)
|
||||
- RCTTypeSafety (= 0.61.2)
|
||||
- React-Core (= 0.61.2)
|
||||
- React-jsi (= 0.61.2)
|
||||
- ReactCommon/turbomodule/core (= 0.61.2)
|
||||
- Folly (2018.10.22.00):
|
||||
- boost-for-react-native
|
||||
- DoubleConversion
|
||||
@@ -11,88 +19,224 @@ PODS:
|
||||
- DoubleConversion
|
||||
- glog
|
||||
- glog (0.3.5)
|
||||
- React (0.60.5):
|
||||
- React-Core (= 0.60.5)
|
||||
- React-DevSupport (= 0.60.5)
|
||||
- React-RCTActionSheet (= 0.60.5)
|
||||
- React-RCTAnimation (= 0.60.5)
|
||||
- React-RCTBlob (= 0.60.5)
|
||||
- React-RCTImage (= 0.60.5)
|
||||
- React-RCTLinking (= 0.60.5)
|
||||
- React-RCTNetwork (= 0.60.5)
|
||||
- React-RCTSettings (= 0.60.5)
|
||||
- React-RCTText (= 0.60.5)
|
||||
- React-RCTVibration (= 0.60.5)
|
||||
- React-RCTWebSocket (= 0.60.5)
|
||||
- React-Core (0.60.5):
|
||||
- RCTRequired (0.61.2)
|
||||
- RCTTypeSafety (0.61.2):
|
||||
- FBLazyVector (= 0.61.2)
|
||||
- Folly (= 2018.10.22.00)
|
||||
- React-cxxreact (= 0.60.5)
|
||||
- React-jsiexecutor (= 0.60.5)
|
||||
- yoga (= 0.60.5.React)
|
||||
- React-cxxreact (0.60.5):
|
||||
- RCTRequired (= 0.61.2)
|
||||
- React-Core (= 0.61.2)
|
||||
- React (0.61.2):
|
||||
- React-Core (= 0.61.2)
|
||||
- React-Core/DevSupport (= 0.61.2)
|
||||
- React-Core/RCTWebSocket (= 0.61.2)
|
||||
- React-RCTActionSheet (= 0.61.2)
|
||||
- React-RCTAnimation (= 0.61.2)
|
||||
- React-RCTBlob (= 0.61.2)
|
||||
- React-RCTImage (= 0.61.2)
|
||||
- React-RCTLinking (= 0.61.2)
|
||||
- React-RCTNetwork (= 0.61.2)
|
||||
- React-RCTSettings (= 0.61.2)
|
||||
- React-RCTText (= 0.61.2)
|
||||
- React-RCTVibration (= 0.61.2)
|
||||
- React-Core (0.61.2):
|
||||
- Folly (= 2018.10.22.00)
|
||||
- glog
|
||||
- React-Core/Default (= 0.61.2)
|
||||
- React-cxxreact (= 0.61.2)
|
||||
- React-jsi (= 0.61.2)
|
||||
- React-jsiexecutor (= 0.61.2)
|
||||
- Yoga
|
||||
- React-Core/CoreModulesHeaders (0.61.2):
|
||||
- Folly (= 2018.10.22.00)
|
||||
- glog
|
||||
- React-Core/Default
|
||||
- React-cxxreact (= 0.61.2)
|
||||
- React-jsi (= 0.61.2)
|
||||
- React-jsiexecutor (= 0.61.2)
|
||||
- Yoga
|
||||
- React-Core/Default (0.61.2):
|
||||
- Folly (= 2018.10.22.00)
|
||||
- glog
|
||||
- React-cxxreact (= 0.61.2)
|
||||
- React-jsi (= 0.61.2)
|
||||
- React-jsiexecutor (= 0.61.2)
|
||||
- Yoga
|
||||
- React-Core/DevSupport (0.61.2):
|
||||
- Folly (= 2018.10.22.00)
|
||||
- glog
|
||||
- React-Core/Default (= 0.61.2)
|
||||
- React-Core/RCTWebSocket (= 0.61.2)
|
||||
- React-cxxreact (= 0.61.2)
|
||||
- React-jsi (= 0.61.2)
|
||||
- React-jsiexecutor (= 0.61.2)
|
||||
- React-jsinspector (= 0.61.2)
|
||||
- Yoga
|
||||
- React-Core/RCTActionSheetHeaders (0.61.2):
|
||||
- Folly (= 2018.10.22.00)
|
||||
- glog
|
||||
- React-Core/Default
|
||||
- React-cxxreact (= 0.61.2)
|
||||
- React-jsi (= 0.61.2)
|
||||
- React-jsiexecutor (= 0.61.2)
|
||||
- Yoga
|
||||
- React-Core/RCTAnimationHeaders (0.61.2):
|
||||
- Folly (= 2018.10.22.00)
|
||||
- glog
|
||||
- React-Core/Default
|
||||
- React-cxxreact (= 0.61.2)
|
||||
- React-jsi (= 0.61.2)
|
||||
- React-jsiexecutor (= 0.61.2)
|
||||
- Yoga
|
||||
- React-Core/RCTBlobHeaders (0.61.2):
|
||||
- Folly (= 2018.10.22.00)
|
||||
- glog
|
||||
- React-Core/Default
|
||||
- React-cxxreact (= 0.61.2)
|
||||
- React-jsi (= 0.61.2)
|
||||
- React-jsiexecutor (= 0.61.2)
|
||||
- Yoga
|
||||
- React-Core/RCTImageHeaders (0.61.2):
|
||||
- Folly (= 2018.10.22.00)
|
||||
- glog
|
||||
- React-Core/Default
|
||||
- React-cxxreact (= 0.61.2)
|
||||
- React-jsi (= 0.61.2)
|
||||
- React-jsiexecutor (= 0.61.2)
|
||||
- Yoga
|
||||
- React-Core/RCTLinkingHeaders (0.61.2):
|
||||
- Folly (= 2018.10.22.00)
|
||||
- glog
|
||||
- React-Core/Default
|
||||
- React-cxxreact (= 0.61.2)
|
||||
- React-jsi (= 0.61.2)
|
||||
- React-jsiexecutor (= 0.61.2)
|
||||
- Yoga
|
||||
- React-Core/RCTNetworkHeaders (0.61.2):
|
||||
- Folly (= 2018.10.22.00)
|
||||
- glog
|
||||
- React-Core/Default
|
||||
- React-cxxreact (= 0.61.2)
|
||||
- React-jsi (= 0.61.2)
|
||||
- React-jsiexecutor (= 0.61.2)
|
||||
- Yoga
|
||||
- React-Core/RCTSettingsHeaders (0.61.2):
|
||||
- Folly (= 2018.10.22.00)
|
||||
- glog
|
||||
- React-Core/Default
|
||||
- React-cxxreact (= 0.61.2)
|
||||
- React-jsi (= 0.61.2)
|
||||
- React-jsiexecutor (= 0.61.2)
|
||||
- Yoga
|
||||
- React-Core/RCTTextHeaders (0.61.2):
|
||||
- Folly (= 2018.10.22.00)
|
||||
- glog
|
||||
- React-Core/Default
|
||||
- React-cxxreact (= 0.61.2)
|
||||
- React-jsi (= 0.61.2)
|
||||
- React-jsiexecutor (= 0.61.2)
|
||||
- Yoga
|
||||
- React-Core/RCTVibrationHeaders (0.61.2):
|
||||
- Folly (= 2018.10.22.00)
|
||||
- glog
|
||||
- React-Core/Default
|
||||
- React-cxxreact (= 0.61.2)
|
||||
- React-jsi (= 0.61.2)
|
||||
- React-jsiexecutor (= 0.61.2)
|
||||
- Yoga
|
||||
- React-Core/RCTWebSocket (0.61.2):
|
||||
- Folly (= 2018.10.22.00)
|
||||
- glog
|
||||
- React-Core/Default (= 0.61.2)
|
||||
- React-cxxreact (= 0.61.2)
|
||||
- React-jsi (= 0.61.2)
|
||||
- React-jsiexecutor (= 0.61.2)
|
||||
- Yoga
|
||||
- React-CoreModules (0.61.2):
|
||||
- FBReactNativeSpec (= 0.61.2)
|
||||
- Folly (= 2018.10.22.00)
|
||||
- RCTTypeSafety (= 0.61.2)
|
||||
- React-Core/CoreModulesHeaders (= 0.61.2)
|
||||
- React-RCTImage (= 0.61.2)
|
||||
- ReactCommon/turbomodule/core (= 0.61.2)
|
||||
- React-cxxreact (0.61.2):
|
||||
- boost-for-react-native (= 1.63.0)
|
||||
- DoubleConversion
|
||||
- Folly (= 2018.10.22.00)
|
||||
- glog
|
||||
- React-jsinspector (= 0.60.5)
|
||||
- React-DevSupport (0.60.5):
|
||||
- React-Core (= 0.60.5)
|
||||
- React-RCTWebSocket (= 0.60.5)
|
||||
- React-jsi (0.60.5):
|
||||
- React-jsinspector (= 0.61.2)
|
||||
- React-jsi (0.61.2):
|
||||
- boost-for-react-native (= 1.63.0)
|
||||
- DoubleConversion
|
||||
- Folly (= 2018.10.22.00)
|
||||
- glog
|
||||
- React-jsi/Default (= 0.60.5)
|
||||
- React-jsi/Default (0.60.5):
|
||||
- React-jsi/Default (= 0.61.2)
|
||||
- React-jsi/Default (0.61.2):
|
||||
- boost-for-react-native (= 1.63.0)
|
||||
- DoubleConversion
|
||||
- Folly (= 2018.10.22.00)
|
||||
- glog
|
||||
- React-jsiexecutor (0.60.5):
|
||||
- React-jsiexecutor (0.61.2):
|
||||
- DoubleConversion
|
||||
- Folly (= 2018.10.22.00)
|
||||
- glog
|
||||
- React-cxxreact (= 0.60.5)
|
||||
- React-jsi (= 0.60.5)
|
||||
- React-jsinspector (0.60.5)
|
||||
- React-RCTActionSheet (0.60.5):
|
||||
- React-Core (= 0.60.5)
|
||||
- React-RCTAnimation (0.60.5):
|
||||
- React-Core (= 0.60.5)
|
||||
- React-RCTBlob (0.60.5):
|
||||
- React-Core (= 0.60.5)
|
||||
- React-RCTNetwork (= 0.60.5)
|
||||
- React-RCTWebSocket (= 0.60.5)
|
||||
- React-RCTImage (0.60.5):
|
||||
- React-Core (= 0.60.5)
|
||||
- React-RCTNetwork (= 0.60.5)
|
||||
- React-RCTLinking (0.60.5):
|
||||
- React-Core (= 0.60.5)
|
||||
- React-RCTNetwork (0.60.5):
|
||||
- React-Core (= 0.60.5)
|
||||
- React-RCTSettings (0.60.5):
|
||||
- React-Core (= 0.60.5)
|
||||
- React-RCTText (0.60.5):
|
||||
- React-Core (= 0.60.5)
|
||||
- React-RCTVibration (0.60.5):
|
||||
- React-Core (= 0.60.5)
|
||||
- React-RCTWebSocket (0.60.5):
|
||||
- React-Core (= 0.60.5)
|
||||
- React-cxxreact (= 0.61.2)
|
||||
- React-jsi (= 0.61.2)
|
||||
- React-jsinspector (0.61.2)
|
||||
- React-RCTActionSheet (0.61.2):
|
||||
- React-Core/RCTActionSheetHeaders (= 0.61.2)
|
||||
- React-RCTAnimation (0.61.2):
|
||||
- React-Core/RCTAnimationHeaders (= 0.61.2)
|
||||
- React-RCTBlob (0.61.2):
|
||||
- React-Core/RCTBlobHeaders (= 0.61.2)
|
||||
- React-Core/RCTWebSocket (= 0.61.2)
|
||||
- React-jsi (= 0.61.2)
|
||||
- React-RCTNetwork (= 0.61.2)
|
||||
- React-RCTImage (0.61.2):
|
||||
- React-Core/RCTImageHeaders (= 0.61.2)
|
||||
- React-RCTNetwork (= 0.61.2)
|
||||
- React-RCTLinking (0.61.2):
|
||||
- React-Core/RCTLinkingHeaders (= 0.61.2)
|
||||
- React-RCTNetwork (0.61.2):
|
||||
- React-Core/RCTNetworkHeaders (= 0.61.2)
|
||||
- React-RCTSettings (0.61.2):
|
||||
- React-Core/RCTSettingsHeaders (= 0.61.2)
|
||||
- React-RCTText (0.61.2):
|
||||
- React-Core/RCTTextHeaders (= 0.61.2)
|
||||
- React-RCTVibration (0.61.2):
|
||||
- React-Core/RCTVibrationHeaders (= 0.61.2)
|
||||
- ReactCommon/jscallinvoker (0.61.2):
|
||||
- DoubleConversion
|
||||
- Folly (= 2018.10.22.00)
|
||||
- glog
|
||||
- React-cxxreact (= 0.61.2)
|
||||
- ReactCommon/turbomodule/core (0.61.2):
|
||||
- DoubleConversion
|
||||
- Folly (= 2018.10.22.00)
|
||||
- glog
|
||||
- React-Core (= 0.61.2)
|
||||
- React-cxxreact (= 0.61.2)
|
||||
- React-jsi (= 0.61.2)
|
||||
- ReactCommon/jscallinvoker (= 0.61.2)
|
||||
- RNGestureHandler (1.3.0):
|
||||
- React
|
||||
- RNScreens (1.0.0-alpha.22):
|
||||
- RNScreens (2.0.0-alpha.23):
|
||||
- React
|
||||
- yoga (0.60.5.React)
|
||||
- Yoga (1.14.0)
|
||||
|
||||
DEPENDENCIES:
|
||||
- DoubleConversion (from `../node_modules/react-native/third-party-podspecs/DoubleConversion.podspec`)
|
||||
- FBLazyVector (from `../node_modules/react-native/Libraries/FBLazyVector`)
|
||||
- FBReactNativeSpec (from `../node_modules/react-native/Libraries/FBReactNativeSpec`)
|
||||
- Folly (from `../node_modules/react-native/third-party-podspecs/Folly.podspec`)
|
||||
- glog (from `../node_modules/react-native/third-party-podspecs/glog.podspec`)
|
||||
- RCTRequired (from `../node_modules/react-native/Libraries/RCTRequired`)
|
||||
- RCTTypeSafety (from `../node_modules/react-native/Libraries/TypeSafety`)
|
||||
- React (from `../node_modules/react-native/`)
|
||||
- React-Core (from `../node_modules/react-native/React`)
|
||||
- React-Core (from `../node_modules/react-native/`)
|
||||
- React-Core/DevSupport (from `../node_modules/react-native/`)
|
||||
- React-Core/RCTWebSocket (from `../node_modules/react-native/`)
|
||||
- React-CoreModules (from `../node_modules/react-native/React/CoreModules`)
|
||||
- React-cxxreact (from `../node_modules/react-native/ReactCommon/cxxreact`)
|
||||
- React-DevSupport (from `../node_modules/react-native/React`)
|
||||
- React-jsi (from `../node_modules/react-native/ReactCommon/jsi`)
|
||||
- React-jsiexecutor (from `../node_modules/react-native/ReactCommon/jsiexecutor`)
|
||||
- React-jsinspector (from `../node_modules/react-native/ReactCommon/jsinspector`)
|
||||
@@ -105,30 +249,39 @@ DEPENDENCIES:
|
||||
- React-RCTSettings (from `../node_modules/react-native/Libraries/Settings`)
|
||||
- React-RCTText (from `../node_modules/react-native/Libraries/Text`)
|
||||
- React-RCTVibration (from `../node_modules/react-native/Libraries/Vibration`)
|
||||
- React-RCTWebSocket (from `../node_modules/react-native/Libraries/WebSocket`)
|
||||
- ReactCommon/jscallinvoker (from `../node_modules/react-native/ReactCommon`)
|
||||
- ReactCommon/turbomodule/core (from `../node_modules/react-native/ReactCommon`)
|
||||
- RNGestureHandler (from `../node_modules/react-native-gesture-handler`)
|
||||
- RNScreens (from `../node_modules/react-native-screens`)
|
||||
- yoga (from `../node_modules/react-native/ReactCommon/yoga`)
|
||||
- Yoga (from `../node_modules/react-native/ReactCommon/yoga`)
|
||||
|
||||
SPEC REPOS:
|
||||
https://github.com/cocoapods/specs.git:
|
||||
https://github.com/CocoaPods/Specs.git:
|
||||
- boost-for-react-native
|
||||
|
||||
EXTERNAL SOURCES:
|
||||
DoubleConversion:
|
||||
:podspec: "../node_modules/react-native/third-party-podspecs/DoubleConversion.podspec"
|
||||
FBLazyVector:
|
||||
:path: "../node_modules/react-native/Libraries/FBLazyVector"
|
||||
FBReactNativeSpec:
|
||||
:path: "../node_modules/react-native/Libraries/FBReactNativeSpec"
|
||||
Folly:
|
||||
:podspec: "../node_modules/react-native/third-party-podspecs/Folly.podspec"
|
||||
glog:
|
||||
:podspec: "../node_modules/react-native/third-party-podspecs/glog.podspec"
|
||||
RCTRequired:
|
||||
:path: "../node_modules/react-native/Libraries/RCTRequired"
|
||||
RCTTypeSafety:
|
||||
:path: "../node_modules/react-native/Libraries/TypeSafety"
|
||||
React:
|
||||
:path: "../node_modules/react-native/"
|
||||
React-Core:
|
||||
:path: "../node_modules/react-native/React"
|
||||
:path: "../node_modules/react-native/"
|
||||
React-CoreModules:
|
||||
:path: "../node_modules/react-native/React/CoreModules"
|
||||
React-cxxreact:
|
||||
:path: "../node_modules/react-native/ReactCommon/cxxreact"
|
||||
React-DevSupport:
|
||||
:path: "../node_modules/react-native/React"
|
||||
React-jsi:
|
||||
:path: "../node_modules/react-native/ReactCommon/jsi"
|
||||
React-jsiexecutor:
|
||||
@@ -153,41 +306,45 @@ EXTERNAL SOURCES:
|
||||
:path: "../node_modules/react-native/Libraries/Text"
|
||||
React-RCTVibration:
|
||||
:path: "../node_modules/react-native/Libraries/Vibration"
|
||||
React-RCTWebSocket:
|
||||
:path: "../node_modules/react-native/Libraries/WebSocket"
|
||||
ReactCommon:
|
||||
:path: "../node_modules/react-native/ReactCommon"
|
||||
RNGestureHandler:
|
||||
:path: "../node_modules/react-native-gesture-handler"
|
||||
RNScreens:
|
||||
:path: "../node_modules/react-native-screens"
|
||||
yoga:
|
||||
Yoga:
|
||||
:path: "../node_modules/react-native/ReactCommon/yoga"
|
||||
|
||||
SPEC CHECKSUMS:
|
||||
boost-for-react-native: 39c7adb57c4e60d6c5479dd8623128eb5b3f0f2c
|
||||
DoubleConversion: 5805e889d232975c086db112ece9ed034df7a0b2
|
||||
FBLazyVector: 68b6a76960fbd8ecd9fb7ce0aadd3329c3340a99
|
||||
FBReactNativeSpec: 5a764c60abdc3336a213e5310c40b74741f32839
|
||||
Folly: 30e7936e1c45c08d884aa59369ed951a8e68cf51
|
||||
glog: 1f3da668190260b06b429bb211bfbee5cd790c28
|
||||
React: 53c53c4d99097af47cf60594b8706b4e3321e722
|
||||
React-Core: ba421f6b4f4cbe2fb17c0b6fc675f87622e78a64
|
||||
React-cxxreact: 8384287780c4999351ad9b6e7a149d9ed10a2395
|
||||
React-DevSupport: 197fb409737cff2c4f9986e77c220d7452cb9f9f
|
||||
React-jsi: 4d8c9efb6312a9725b18d6fc818ffc103f60fec2
|
||||
React-jsiexecutor: 90ad2f9db09513fc763bc757fdc3c4ff8bde2a30
|
||||
React-jsinspector: e08662d1bf5b129a3d556eb9ea343a3f40353ae4
|
||||
React-RCTActionSheet: b0f1ea83f4bf75fb966eae9bfc47b78c8d3efd90
|
||||
React-RCTAnimation: 359ba1b5690b1e87cc173558a78e82d35919333e
|
||||
React-RCTBlob: 5e2b55f76e9a1c7ae52b826923502ddc3238df24
|
||||
React-RCTImage: f5f1c50922164e89bdda67bcd0153952a5cfe719
|
||||
React-RCTLinking: d0ecbd791e9ddddc41fa1f66b0255de90e8ee1e9
|
||||
React-RCTNetwork: e26946300b0ab7bb6c4a6348090e93fa21f33a9d
|
||||
React-RCTSettings: d0d37cb521b7470c998595a44f05847777cc3f42
|
||||
React-RCTText: b074d89033583d4f2eb5faf7ea2db3a13c7553a2
|
||||
React-RCTVibration: 2105b2e0e2b66a6408fc69a46c8a7fb5b2fdade0
|
||||
React-RCTWebSocket: cd932a16b7214898b6b7f788c8bddb3637246ac4
|
||||
RCTRequired: c639d59ed389cfb1f1203f65c2ea946d8ec586e2
|
||||
RCTTypeSafety: dc23fb655d6c77667c78e327bf661bc11e3b8aec
|
||||
React: 7e586e5d7bec12b91c1a096826b0fc9ab1da7865
|
||||
React-Core: 8ddb9770b4a30a6ab4a754e6ed5ec76454e3d699
|
||||
React-CoreModules: b3d9eece8ad7df36c917a41f05c1168c52fe0b34
|
||||
React-cxxreact: 1f972757c0bd08d962ef78068e06613c27489a3f
|
||||
React-jsi: 32285a21b1b24c36060493ed3057a34677d58d09
|
||||
React-jsiexecutor: 8909917ff7d8f21a57e443a866fd8d4560e50c65
|
||||
React-jsinspector: 111d7d342b07a904c400592e02a2b958f1098b60
|
||||
React-RCTActionSheet: 89b037c0fb7d2671607cb645760164e7e0c013f6
|
||||
React-RCTAnimation: e3cefa93c38c004c318f7ec04b883eb14b8b8235
|
||||
React-RCTBlob: d26ac0e313fbf14e7203473fd593ccaaeee8329e
|
||||
React-RCTImage: 4bdd9588783fa9e48ef669ccd4f747224e208edf
|
||||
React-RCTLinking: 65f0088ff463babd3d5d567964a65b74141eff3b
|
||||
React-RCTNetwork: 0c1a73576c1cfeafe68396556de1b17d93c0c595
|
||||
React-RCTSettings: 4194f1f0edbddf3fd44d1714dc6578bb20379b60
|
||||
React-RCTText: e3ef6191cdb627855ff7fe8fa0c1e14094967fb8
|
||||
React-RCTVibration: fb54c732fd20405a76598e431aa2f8c2bf527de9
|
||||
ReactCommon: 5848032ed2f274fcb40f6b9ec24067787c42d479
|
||||
RNGestureHandler: 5329a942fce3d41c68b84c2c2276ce06a696d8b0
|
||||
RNScreens: 720a9e6968beb73e8196239801e887d8401f86ed
|
||||
yoga: 312528f5bbbba37b4dcea5ef00e8b4033fdd9411
|
||||
RNScreens: 55c735f525774e894be67848c250c95a9c3194c0
|
||||
Yoga: 14927e37bd25376d216b150ab2a561773d57911f
|
||||
|
||||
PODFILE CHECKSUM: dda12850f41a6af688192ceed9b857af4868e401
|
||||
PODFILE CHECKSUM: 1a141b811c7076eb11c48f2e22336181f52531b5
|
||||
|
||||
COCOAPODS: 1.7.3
|
||||
COCOAPODS: 1.8.4
|
||||
|
||||
@@ -15,265 +15,10 @@
|
||||
44BCAFE3213FB64300CF39F1 /* RNSSampleLifecycleAwareView.m in Sources */ = {isa = PBXBuildFile; fileRef = 44BCAFBC213FB64200CF39F1 /* RNSSampleLifecycleAwareView.m */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXContainerItemProxy section */
|
||||
00C302AB1ABCB8CE00DB3ED1 /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = 00C302A71ABCB8CE00DB3ED1 /* RCTActionSheet.xcodeproj */;
|
||||
proxyType = 2;
|
||||
remoteGlobalIDString = 134814201AA4EA6300B7C361;
|
||||
remoteInfo = RCTActionSheet;
|
||||
};
|
||||
00C302B91ABCB90400DB3ED1 /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = 00C302B51ABCB90400DB3ED1 /* RCTGeolocation.xcodeproj */;
|
||||
proxyType = 2;
|
||||
remoteGlobalIDString = 134814201AA4EA6300B7C361;
|
||||
remoteInfo = RCTGeolocation;
|
||||
};
|
||||
00C302BF1ABCB91800DB3ED1 /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = 00C302BB1ABCB91800DB3ED1 /* RCTImage.xcodeproj */;
|
||||
proxyType = 2;
|
||||
remoteGlobalIDString = 58B5115D1A9E6B3D00147676;
|
||||
remoteInfo = RCTImage;
|
||||
};
|
||||
00C302DB1ABCB9D200DB3ED1 /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = 00C302D31ABCB9D200DB3ED1 /* RCTNetwork.xcodeproj */;
|
||||
proxyType = 2;
|
||||
remoteGlobalIDString = 58B511DB1A9E6C8500147676;
|
||||
remoteInfo = RCTNetwork;
|
||||
};
|
||||
00C302E31ABCB9EE00DB3ED1 /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = 00C302DF1ABCB9EE00DB3ED1 /* RCTVibration.xcodeproj */;
|
||||
proxyType = 2;
|
||||
remoteGlobalIDString = 832C81801AAF6DEF007FA2F7;
|
||||
remoteInfo = RCTVibration;
|
||||
};
|
||||
139105C01AF99BAD00B5F7CC /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = 139105B61AF99BAD00B5F7CC /* RCTSettings.xcodeproj */;
|
||||
proxyType = 2;
|
||||
remoteGlobalIDString = 134814201AA4EA6300B7C361;
|
||||
remoteInfo = RCTSettings;
|
||||
};
|
||||
139FDEF31B06529B00C62182 /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = 139FDEE61B06529A00C62182 /* RCTWebSocket.xcodeproj */;
|
||||
proxyType = 2;
|
||||
remoteGlobalIDString = 3C86DF461ADF2C930047B81A;
|
||||
remoteInfo = RCTWebSocket;
|
||||
};
|
||||
146834031AC3E56700842450 /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = 146833FF1AC3E56700842450 /* React.xcodeproj */;
|
||||
proxyType = 2;
|
||||
remoteGlobalIDString = 83CBBA2E1A601D0E00E9B192;
|
||||
remoteInfo = React;
|
||||
};
|
||||
2D16E6711FA4F8DC00B85C8A /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = ADBDB91F1DFEBF0600ED6528 /* RCTBlob.xcodeproj */;
|
||||
proxyType = 2;
|
||||
remoteGlobalIDString = ADD01A681E09402E00F6D226;
|
||||
remoteInfo = "RCTBlob-tvOS";
|
||||
};
|
||||
2DF0FFDE2056DD460020B375 /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = 146833FF1AC3E56700842450 /* React.xcodeproj */;
|
||||
proxyType = 2;
|
||||
remoteGlobalIDString = EBF21BDC1FC498900052F4D5;
|
||||
remoteInfo = jsinspector;
|
||||
};
|
||||
2DF0FFE02056DD460020B375 /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = 146833FF1AC3E56700842450 /* React.xcodeproj */;
|
||||
proxyType = 2;
|
||||
remoteGlobalIDString = EBF21BFA1FC4989A0052F4D5;
|
||||
remoteInfo = "jsinspector-tvOS";
|
||||
};
|
||||
2DF0FFE22056DD460020B375 /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = 146833FF1AC3E56700842450 /* React.xcodeproj */;
|
||||
proxyType = 2;
|
||||
remoteGlobalIDString = 139D7ECE1E25DB7D00323FB7;
|
||||
remoteInfo = "third-party";
|
||||
};
|
||||
2DF0FFE42056DD460020B375 /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = 146833FF1AC3E56700842450 /* React.xcodeproj */;
|
||||
proxyType = 2;
|
||||
remoteGlobalIDString = 3D383D3C1EBD27B6005632C8;
|
||||
remoteInfo = "third-party-tvOS";
|
||||
};
|
||||
2DF0FFE62056DD460020B375 /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = 146833FF1AC3E56700842450 /* React.xcodeproj */;
|
||||
proxyType = 2;
|
||||
remoteGlobalIDString = 139D7E881E25C6D100323FB7;
|
||||
remoteInfo = "double-conversion";
|
||||
};
|
||||
2DF0FFE82056DD460020B375 /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = 146833FF1AC3E56700842450 /* React.xcodeproj */;
|
||||
proxyType = 2;
|
||||
remoteGlobalIDString = 3D383D621EBD27B9005632C8;
|
||||
remoteInfo = "double-conversion-tvOS";
|
||||
};
|
||||
3DAD3E831DF850E9000B6D8A /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = 00C302BB1ABCB91800DB3ED1 /* RCTImage.xcodeproj */;
|
||||
proxyType = 2;
|
||||
remoteGlobalIDString = 2D2A283A1D9B042B00D4039D;
|
||||
remoteInfo = "RCTImage-tvOS";
|
||||
};
|
||||
3DAD3E871DF850E9000B6D8A /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = 78C398B01ACF4ADC00677621 /* RCTLinking.xcodeproj */;
|
||||
proxyType = 2;
|
||||
remoteGlobalIDString = 2D2A28471D9B043800D4039D;
|
||||
remoteInfo = "RCTLinking-tvOS";
|
||||
};
|
||||
3DAD3E8B1DF850E9000B6D8A /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = 00C302D31ABCB9D200DB3ED1 /* RCTNetwork.xcodeproj */;
|
||||
proxyType = 2;
|
||||
remoteGlobalIDString = 2D2A28541D9B044C00D4039D;
|
||||
remoteInfo = "RCTNetwork-tvOS";
|
||||
};
|
||||
3DAD3E8F1DF850E9000B6D8A /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = 139105B61AF99BAD00B5F7CC /* RCTSettings.xcodeproj */;
|
||||
proxyType = 2;
|
||||
remoteGlobalIDString = 2D2A28611D9B046600D4039D;
|
||||
remoteInfo = "RCTSettings-tvOS";
|
||||
};
|
||||
3DAD3E931DF850E9000B6D8A /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = 832341B01AAA6A8300B99B32 /* RCTText.xcodeproj */;
|
||||
proxyType = 2;
|
||||
remoteGlobalIDString = 2D2A287B1D9B048500D4039D;
|
||||
remoteInfo = "RCTText-tvOS";
|
||||
};
|
||||
3DAD3E981DF850E9000B6D8A /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = 139FDEE61B06529A00C62182 /* RCTWebSocket.xcodeproj */;
|
||||
proxyType = 2;
|
||||
remoteGlobalIDString = 2D2A28881D9B049200D4039D;
|
||||
remoteInfo = "RCTWebSocket-tvOS";
|
||||
};
|
||||
3DAD3EA21DF850E9000B6D8A /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = 146833FF1AC3E56700842450 /* React.xcodeproj */;
|
||||
proxyType = 2;
|
||||
remoteGlobalIDString = 2D2A28131D9B038B00D4039D;
|
||||
remoteInfo = "React-tvOS";
|
||||
};
|
||||
3DAD3EA41DF850E9000B6D8A /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = 146833FF1AC3E56700842450 /* React.xcodeproj */;
|
||||
proxyType = 2;
|
||||
remoteGlobalIDString = 3D3C059A1DE3340900C268FA;
|
||||
remoteInfo = yoga;
|
||||
};
|
||||
3DAD3EA61DF850E9000B6D8A /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = 146833FF1AC3E56700842450 /* React.xcodeproj */;
|
||||
proxyType = 2;
|
||||
remoteGlobalIDString = 3D3C06751DE3340C00C268FA;
|
||||
remoteInfo = "yoga-tvOS";
|
||||
};
|
||||
3DAD3EA81DF850E9000B6D8A /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = 146833FF1AC3E56700842450 /* React.xcodeproj */;
|
||||
proxyType = 2;
|
||||
remoteGlobalIDString = 3D3CD9251DE5FBEC00167DC4;
|
||||
remoteInfo = cxxreact;
|
||||
};
|
||||
3DAD3EAA1DF850E9000B6D8A /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = 146833FF1AC3E56700842450 /* React.xcodeproj */;
|
||||
proxyType = 2;
|
||||
remoteGlobalIDString = 3D3CD9321DE5FBEE00167DC4;
|
||||
remoteInfo = "cxxreact-tvOS";
|
||||
};
|
||||
44461E5D230FEE4700570C98 /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = 146833FF1AC3E56700842450 /* React.xcodeproj */;
|
||||
proxyType = 2;
|
||||
remoteGlobalIDString = EDEBC6D6214B3E7000DD5AC8;
|
||||
remoteInfo = jsi;
|
||||
};
|
||||
44461E5F230FEE4700570C98 /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = 146833FF1AC3E56700842450 /* React.xcodeproj */;
|
||||
proxyType = 2;
|
||||
remoteGlobalIDString = EDEBC73B214B45A300DD5AC8;
|
||||
remoteInfo = jsiexecutor;
|
||||
};
|
||||
44461E61230FEE4700570C98 /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = 146833FF1AC3E56700842450 /* React.xcodeproj */;
|
||||
proxyType = 2;
|
||||
remoteGlobalIDString = ED296FB6214C9A0900B7C4FE;
|
||||
remoteInfo = "jsi-tvOS";
|
||||
};
|
||||
44461E63230FEE4700570C98 /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = 146833FF1AC3E56700842450 /* React.xcodeproj */;
|
||||
proxyType = 2;
|
||||
remoteGlobalIDString = ED296FEE214C9CF800B7C4FE;
|
||||
remoteInfo = "jsiexecutor-tvOS";
|
||||
};
|
||||
5E9157321DD0AC6500FF2AA8 /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = 5E91572D1DD0AC6500FF2AA8 /* RCTAnimation.xcodeproj */;
|
||||
proxyType = 2;
|
||||
remoteGlobalIDString = 134814201AA4EA6300B7C361;
|
||||
remoteInfo = RCTAnimation;
|
||||
};
|
||||
5E9157341DD0AC6500FF2AA8 /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = 5E91572D1DD0AC6500FF2AA8 /* RCTAnimation.xcodeproj */;
|
||||
proxyType = 2;
|
||||
remoteGlobalIDString = 2D2A28201D9B03D100D4039D;
|
||||
remoteInfo = "RCTAnimation-tvOS";
|
||||
};
|
||||
78C398B81ACF4ADC00677621 /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = 78C398B01ACF4ADC00677621 /* RCTLinking.xcodeproj */;
|
||||
proxyType = 2;
|
||||
remoteGlobalIDString = 134814201AA4EA6300B7C361;
|
||||
remoteInfo = RCTLinking;
|
||||
};
|
||||
832341B41AAA6A8300B99B32 /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = 832341B01AAA6A8300B99B32 /* RCTText.xcodeproj */;
|
||||
proxyType = 2;
|
||||
remoteGlobalIDString = 58B5119B1A9E6C1200147676;
|
||||
remoteInfo = RCTText;
|
||||
};
|
||||
ADBDB9261DFEBF0700ED6528 /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = ADBDB91F1DFEBF0600ED6528 /* RCTBlob.xcodeproj */;
|
||||
proxyType = 2;
|
||||
remoteGlobalIDString = 358F4ED71D1E81A9004DF814;
|
||||
remoteInfo = RCTBlob;
|
||||
};
|
||||
/* End PBXContainerItemProxy section */
|
||||
|
||||
/* Begin PBXFileReference section */
|
||||
008F07F21AC5B25A0029DE68 /* main.jsbundle */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = main.jsbundle; sourceTree = "<group>"; };
|
||||
00C302A71ABCB8CE00DB3ED1 /* RCTActionSheet.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTActionSheet.xcodeproj; path = "../node_modules/react-native/Libraries/ActionSheetIOS/RCTActionSheet.xcodeproj"; sourceTree = "<group>"; };
|
||||
00C302B51ABCB90400DB3ED1 /* RCTGeolocation.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTGeolocation.xcodeproj; path = "../node_modules/react-native/Libraries/Geolocation/RCTGeolocation.xcodeproj"; sourceTree = "<group>"; };
|
||||
00C302BB1ABCB91800DB3ED1 /* RCTImage.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTImage.xcodeproj; path = "../node_modules/react-native/Libraries/Image/RCTImage.xcodeproj"; sourceTree = "<group>"; };
|
||||
00C302D31ABCB9D200DB3ED1 /* RCTNetwork.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTNetwork.xcodeproj; path = "../node_modules/react-native/Libraries/Network/RCTNetwork.xcodeproj"; sourceTree = "<group>"; };
|
||||
00C302DF1ABCB9EE00DB3ED1 /* RCTVibration.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTVibration.xcodeproj; path = "../node_modules/react-native/Libraries/Vibration/RCTVibration.xcodeproj"; sourceTree = "<group>"; };
|
||||
00E356F11AD99517003FC87E /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
||||
00E356F21AD99517003FC87E /* ScreensExampleTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ScreensExampleTests.m; sourceTree = "<group>"; };
|
||||
139105B61AF99BAD00B5F7CC /* RCTSettings.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTSettings.xcodeproj; path = "../node_modules/react-native/Libraries/Settings/RCTSettings.xcodeproj"; sourceTree = "<group>"; };
|
||||
139FDEE61B06529A00C62182 /* RCTWebSocket.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTWebSocket.xcodeproj; path = "../node_modules/react-native/Libraries/WebSocket/RCTWebSocket.xcodeproj"; sourceTree = "<group>"; };
|
||||
13B07F961A680F5B00A75B9A /* ScreensExample.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = ScreensExample.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
13B07FAF1A68108700A75B9A /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AppDelegate.h; path = ScreensExample/AppDelegate.h; sourceTree = "<group>"; };
|
||||
13B07FB01A68108700A75B9A /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = AppDelegate.m; path = ScreensExample/AppDelegate.m; sourceTree = "<group>"; };
|
||||
@@ -281,14 +26,9 @@
|
||||
13B07FB51A68108700A75B9A /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Images.xcassets; path = ScreensExample/Images.xcassets; sourceTree = "<group>"; };
|
||||
13B07FB61A68108700A75B9A /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Info.plist; path = ScreensExample/Info.plist; sourceTree = "<group>"; };
|
||||
13B07FB71A68108700A75B9A /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = main.m; path = ScreensExample/main.m; sourceTree = "<group>"; };
|
||||
146833FF1AC3E56700842450 /* React.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = React.xcodeproj; path = "../node_modules/react-native/React/React.xcodeproj"; sourceTree = "<group>"; };
|
||||
2D16E6891FA4F8E400B85C8A /* libReact.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; path = libReact.a; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
44BCAFBC213FB64200CF39F1 /* RNSSampleLifecycleAwareView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = RNSSampleLifecycleAwareView.m; path = ScreensExample/RNSSampleLifecycleAwareView.m; sourceTree = "<group>"; };
|
||||
5E91572D1DD0AC6500FF2AA8 /* RCTAnimation.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTAnimation.xcodeproj; path = "../node_modules/react-native/Libraries/NativeAnimation/RCTAnimation.xcodeproj"; sourceTree = "<group>"; };
|
||||
78C398B01ACF4ADC00677621 /* RCTLinking.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTLinking.xcodeproj; path = "../node_modules/react-native/Libraries/LinkingIOS/RCTLinking.xcodeproj"; sourceTree = "<group>"; };
|
||||
832341B01AAA6A8300B99B32 /* RCTText.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTText.xcodeproj; path = "../node_modules/react-native/Libraries/Text/RCTText.xcodeproj"; sourceTree = "<group>"; };
|
||||
8E2AA8F11B8C93DBCB5D2D3B /* Pods-ScreensExample.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ScreensExample.debug.xcconfig"; path = "Target Support Files/Pods-ScreensExample/Pods-ScreensExample.debug.xcconfig"; sourceTree = "<group>"; };
|
||||
ADBDB91F1DFEBF0600ED6528 /* RCTBlob.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTBlob.xcodeproj; path = "../node_modules/react-native/Libraries/Blob/RCTBlob.xcodeproj"; sourceTree = "<group>"; };
|
||||
EC21D5898029BA5732221EC7 /* libPods-ScreensExample.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-ScreensExample.a"; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
F4F2B14C46961C8C58D25AAF /* Pods-ScreensExample.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ScreensExample.release.xcconfig"; path = "Target Support Files/Pods-ScreensExample/Pods-ScreensExample.release.xcconfig"; sourceTree = "<group>"; };
|
||||
/* End PBXFileReference section */
|
||||
@@ -305,48 +45,6 @@
|
||||
/* End PBXFrameworksBuildPhase section */
|
||||
|
||||
/* Begin PBXGroup section */
|
||||
00C302A81ABCB8CE00DB3ED1 /* Products */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
00C302AC1ABCB8CE00DB3ED1 /* libRCTActionSheet.a */,
|
||||
);
|
||||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
00C302B61ABCB90400DB3ED1 /* Products */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
00C302BA1ABCB90400DB3ED1 /* libRCTGeolocation.a */,
|
||||
);
|
||||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
00C302BC1ABCB91800DB3ED1 /* Products */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
00C302C01ABCB91800DB3ED1 /* libRCTImage.a */,
|
||||
3DAD3E841DF850E9000B6D8A /* libRCTImage-tvOS.a */,
|
||||
);
|
||||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
00C302D41ABCB9D200DB3ED1 /* Products */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
00C302DC1ABCB9D200DB3ED1 /* libRCTNetwork.a */,
|
||||
3DAD3E8C1DF850E9000B6D8A /* libRCTNetwork-tvOS.a */,
|
||||
);
|
||||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
00C302E01ABCB9EE00DB3ED1 /* Products */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
00C302E41ABCB9EE00DB3ED1 /* libRCTVibration.a */,
|
||||
);
|
||||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
00E356EF1AD99517003FC87E /* ScreensExampleTests */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
@@ -364,24 +62,6 @@
|
||||
name = "Supporting Files";
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
139105B71AF99BAD00B5F7CC /* Products */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
139105C11AF99BAD00B5F7CC /* libRCTSettings.a */,
|
||||
3DAD3E901DF850E9000B6D8A /* libRCTSettings-tvOS.a */,
|
||||
);
|
||||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
139FDEE71B06529A00C62182 /* Products */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
139FDEF41B06529B00C62182 /* libRCTWebSocket.a */,
|
||||
3DAD3E991DF850E9000B6D8A /* libRCTWebSocket-tvOS.a */,
|
||||
);
|
||||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
13B07FAE1A68108700A75B9A /* ScreensExample */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
@@ -397,29 +77,6 @@
|
||||
name = ScreensExample;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
146834001AC3E56700842450 /* Products */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
146834041AC3E56700842450 /* libReact.a */,
|
||||
3DAD3EA31DF850E9000B6D8A /* libReact.a */,
|
||||
3DAD3EA51DF850E9000B6D8A /* libyoga.a */,
|
||||
3DAD3EA71DF850E9000B6D8A /* libyoga.a */,
|
||||
3DAD3EA91DF850E9000B6D8A /* libcxxreact.a */,
|
||||
3DAD3EAB1DF850E9000B6D8A /* libcxxreact.a */,
|
||||
2DF0FFDF2056DD460020B375 /* libjsinspector.a */,
|
||||
2DF0FFE12056DD460020B375 /* libjsinspector-tvOS.a */,
|
||||
2DF0FFE32056DD460020B375 /* libthird-party.a */,
|
||||
2DF0FFE52056DD460020B375 /* libthird-party.a */,
|
||||
2DF0FFE72056DD460020B375 /* libdouble-conversion.a */,
|
||||
2DF0FFE92056DD460020B375 /* libdouble-conversion.a */,
|
||||
44461E5E230FEE4700570C98 /* libjsi.a */,
|
||||
44461E60230FEE4700570C98 /* libjsiexecutor.a */,
|
||||
44461E62230FEE4700570C98 /* libjsi-tvOS.a */,
|
||||
44461E64230FEE4700570C98 /* libjsiexecutor-tvOS.a */,
|
||||
);
|
||||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
2D16E6871FA4F8E400B85C8A /* Frameworks */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
@@ -436,52 +93,13 @@
|
||||
name = "Recovered References";
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
5E91572E1DD0AC6500FF2AA8 /* Products */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
5E9157331DD0AC6500FF2AA8 /* libRCTAnimation.a */,
|
||||
5E9157351DD0AC6500FF2AA8 /* libRCTAnimation.a */,
|
||||
);
|
||||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
78C398B11ACF4ADC00677621 /* Products */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
78C398B91ACF4ADC00677621 /* libRCTLinking.a */,
|
||||
3DAD3E881DF850E9000B6D8A /* libRCTLinking-tvOS.a */,
|
||||
);
|
||||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
832341AE1AAA6A7D00B99B32 /* Libraries */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
5E91572D1DD0AC6500FF2AA8 /* RCTAnimation.xcodeproj */,
|
||||
146833FF1AC3E56700842450 /* React.xcodeproj */,
|
||||
00C302A71ABCB8CE00DB3ED1 /* RCTActionSheet.xcodeproj */,
|
||||
ADBDB91F1DFEBF0600ED6528 /* RCTBlob.xcodeproj */,
|
||||
00C302B51ABCB90400DB3ED1 /* RCTGeolocation.xcodeproj */,
|
||||
00C302BB1ABCB91800DB3ED1 /* RCTImage.xcodeproj */,
|
||||
78C398B01ACF4ADC00677621 /* RCTLinking.xcodeproj */,
|
||||
00C302D31ABCB9D200DB3ED1 /* RCTNetwork.xcodeproj */,
|
||||
139105B61AF99BAD00B5F7CC /* RCTSettings.xcodeproj */,
|
||||
832341B01AAA6A8300B99B32 /* RCTText.xcodeproj */,
|
||||
00C302DF1ABCB9EE00DB3ED1 /* RCTVibration.xcodeproj */,
|
||||
139FDEE61B06529A00C62182 /* RCTWebSocket.xcodeproj */,
|
||||
);
|
||||
name = Libraries;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
832341B11AAA6A8300B99B32 /* Products */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
832341B51AAA6A8300B99B32 /* libRCTText.a */,
|
||||
3DAD3E941DF850E9000B6D8A /* libRCTText-tvOS.a */,
|
||||
);
|
||||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
83CBB9F61A601CBA00E9B192 = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
@@ -506,15 +124,6 @@
|
||||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
ADBDB9201DFEBF0600ED6528 /* Products */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
ADBDB9271DFEBF0700ED6528 /* libRCTBlob.a */,
|
||||
2D16E6721FA4F8DC00B85C8A /* libRCTBlob-tvOS.a */,
|
||||
);
|
||||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
C619D43D8D751DD2D2582733 /* Pods */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
@@ -572,56 +181,6 @@
|
||||
mainGroup = 83CBB9F61A601CBA00E9B192;
|
||||
productRefGroup = 83CBBA001A601CBA00E9B192 /* Products */;
|
||||
projectDirPath = "";
|
||||
projectReferences = (
|
||||
{
|
||||
ProductGroup = 00C302A81ABCB8CE00DB3ED1 /* Products */;
|
||||
ProjectRef = 00C302A71ABCB8CE00DB3ED1 /* RCTActionSheet.xcodeproj */;
|
||||
},
|
||||
{
|
||||
ProductGroup = 5E91572E1DD0AC6500FF2AA8 /* Products */;
|
||||
ProjectRef = 5E91572D1DD0AC6500FF2AA8 /* RCTAnimation.xcodeproj */;
|
||||
},
|
||||
{
|
||||
ProductGroup = ADBDB9201DFEBF0600ED6528 /* Products */;
|
||||
ProjectRef = ADBDB91F1DFEBF0600ED6528 /* RCTBlob.xcodeproj */;
|
||||
},
|
||||
{
|
||||
ProductGroup = 00C302B61ABCB90400DB3ED1 /* Products */;
|
||||
ProjectRef = 00C302B51ABCB90400DB3ED1 /* RCTGeolocation.xcodeproj */;
|
||||
},
|
||||
{
|
||||
ProductGroup = 00C302BC1ABCB91800DB3ED1 /* Products */;
|
||||
ProjectRef = 00C302BB1ABCB91800DB3ED1 /* RCTImage.xcodeproj */;
|
||||
},
|
||||
{
|
||||
ProductGroup = 78C398B11ACF4ADC00677621 /* Products */;
|
||||
ProjectRef = 78C398B01ACF4ADC00677621 /* RCTLinking.xcodeproj */;
|
||||
},
|
||||
{
|
||||
ProductGroup = 00C302D41ABCB9D200DB3ED1 /* Products */;
|
||||
ProjectRef = 00C302D31ABCB9D200DB3ED1 /* RCTNetwork.xcodeproj */;
|
||||
},
|
||||
{
|
||||
ProductGroup = 139105B71AF99BAD00B5F7CC /* Products */;
|
||||
ProjectRef = 139105B61AF99BAD00B5F7CC /* RCTSettings.xcodeproj */;
|
||||
},
|
||||
{
|
||||
ProductGroup = 832341B11AAA6A8300B99B32 /* Products */;
|
||||
ProjectRef = 832341B01AAA6A8300B99B32 /* RCTText.xcodeproj */;
|
||||
},
|
||||
{
|
||||
ProductGroup = 00C302E01ABCB9EE00DB3ED1 /* Products */;
|
||||
ProjectRef = 00C302DF1ABCB9EE00DB3ED1 /* RCTVibration.xcodeproj */;
|
||||
},
|
||||
{
|
||||
ProductGroup = 139FDEE71B06529A00C62182 /* Products */;
|
||||
ProjectRef = 139FDEE61B06529A00C62182 /* RCTWebSocket.xcodeproj */;
|
||||
},
|
||||
{
|
||||
ProductGroup = 146834001AC3E56700842450 /* Products */;
|
||||
ProjectRef = 146833FF1AC3E56700842450 /* React.xcodeproj */;
|
||||
},
|
||||
);
|
||||
projectRoot = "";
|
||||
targets = (
|
||||
13B07F861A680F5B00A75B9A /* ScreensExample */,
|
||||
@@ -629,254 +188,6 @@
|
||||
};
|
||||
/* End PBXProject section */
|
||||
|
||||
/* Begin PBXReferenceProxy section */
|
||||
00C302AC1ABCB8CE00DB3ED1 /* libRCTActionSheet.a */ = {
|
||||
isa = PBXReferenceProxy;
|
||||
fileType = archive.ar;
|
||||
path = libRCTActionSheet.a;
|
||||
remoteRef = 00C302AB1ABCB8CE00DB3ED1 /* PBXContainerItemProxy */;
|
||||
sourceTree = BUILT_PRODUCTS_DIR;
|
||||
};
|
||||
00C302BA1ABCB90400DB3ED1 /* libRCTGeolocation.a */ = {
|
||||
isa = PBXReferenceProxy;
|
||||
fileType = archive.ar;
|
||||
path = libRCTGeolocation.a;
|
||||
remoteRef = 00C302B91ABCB90400DB3ED1 /* PBXContainerItemProxy */;
|
||||
sourceTree = BUILT_PRODUCTS_DIR;
|
||||
};
|
||||
00C302C01ABCB91800DB3ED1 /* libRCTImage.a */ = {
|
||||
isa = PBXReferenceProxy;
|
||||
fileType = archive.ar;
|
||||
path = libRCTImage.a;
|
||||
remoteRef = 00C302BF1ABCB91800DB3ED1 /* PBXContainerItemProxy */;
|
||||
sourceTree = BUILT_PRODUCTS_DIR;
|
||||
};
|
||||
00C302DC1ABCB9D200DB3ED1 /* libRCTNetwork.a */ = {
|
||||
isa = PBXReferenceProxy;
|
||||
fileType = archive.ar;
|
||||
path = libRCTNetwork.a;
|
||||
remoteRef = 00C302DB1ABCB9D200DB3ED1 /* PBXContainerItemProxy */;
|
||||
sourceTree = BUILT_PRODUCTS_DIR;
|
||||
};
|
||||
00C302E41ABCB9EE00DB3ED1 /* libRCTVibration.a */ = {
|
||||
isa = PBXReferenceProxy;
|
||||
fileType = archive.ar;
|
||||
path = libRCTVibration.a;
|
||||
remoteRef = 00C302E31ABCB9EE00DB3ED1 /* PBXContainerItemProxy */;
|
||||
sourceTree = BUILT_PRODUCTS_DIR;
|
||||
};
|
||||
139105C11AF99BAD00B5F7CC /* libRCTSettings.a */ = {
|
||||
isa = PBXReferenceProxy;
|
||||
fileType = archive.ar;
|
||||
path = libRCTSettings.a;
|
||||
remoteRef = 139105C01AF99BAD00B5F7CC /* PBXContainerItemProxy */;
|
||||
sourceTree = BUILT_PRODUCTS_DIR;
|
||||
};
|
||||
139FDEF41B06529B00C62182 /* libRCTWebSocket.a */ = {
|
||||
isa = PBXReferenceProxy;
|
||||
fileType = archive.ar;
|
||||
path = libRCTWebSocket.a;
|
||||
remoteRef = 139FDEF31B06529B00C62182 /* PBXContainerItemProxy */;
|
||||
sourceTree = BUILT_PRODUCTS_DIR;
|
||||
};
|
||||
146834041AC3E56700842450 /* libReact.a */ = {
|
||||
isa = PBXReferenceProxy;
|
||||
fileType = archive.ar;
|
||||
path = libReact.a;
|
||||
remoteRef = 146834031AC3E56700842450 /* PBXContainerItemProxy */;
|
||||
sourceTree = BUILT_PRODUCTS_DIR;
|
||||
};
|
||||
2D16E6721FA4F8DC00B85C8A /* libRCTBlob-tvOS.a */ = {
|
||||
isa = PBXReferenceProxy;
|
||||
fileType = archive.ar;
|
||||
path = "libRCTBlob-tvOS.a";
|
||||
remoteRef = 2D16E6711FA4F8DC00B85C8A /* PBXContainerItemProxy */;
|
||||
sourceTree = BUILT_PRODUCTS_DIR;
|
||||
};
|
||||
2DF0FFDF2056DD460020B375 /* libjsinspector.a */ = {
|
||||
isa = PBXReferenceProxy;
|
||||
fileType = archive.ar;
|
||||
path = libjsinspector.a;
|
||||
remoteRef = 2DF0FFDE2056DD460020B375 /* PBXContainerItemProxy */;
|
||||
sourceTree = BUILT_PRODUCTS_DIR;
|
||||
};
|
||||
2DF0FFE12056DD460020B375 /* libjsinspector-tvOS.a */ = {
|
||||
isa = PBXReferenceProxy;
|
||||
fileType = archive.ar;
|
||||
path = "libjsinspector-tvOS.a";
|
||||
remoteRef = 2DF0FFE02056DD460020B375 /* PBXContainerItemProxy */;
|
||||
sourceTree = BUILT_PRODUCTS_DIR;
|
||||
};
|
||||
2DF0FFE32056DD460020B375 /* libthird-party.a */ = {
|
||||
isa = PBXReferenceProxy;
|
||||
fileType = archive.ar;
|
||||
path = "libthird-party.a";
|
||||
remoteRef = 2DF0FFE22056DD460020B375 /* PBXContainerItemProxy */;
|
||||
sourceTree = BUILT_PRODUCTS_DIR;
|
||||
};
|
||||
2DF0FFE52056DD460020B375 /* libthird-party.a */ = {
|
||||
isa = PBXReferenceProxy;
|
||||
fileType = archive.ar;
|
||||
path = "libthird-party.a";
|
||||
remoteRef = 2DF0FFE42056DD460020B375 /* PBXContainerItemProxy */;
|
||||
sourceTree = BUILT_PRODUCTS_DIR;
|
||||
};
|
||||
2DF0FFE72056DD460020B375 /* libdouble-conversion.a */ = {
|
||||
isa = PBXReferenceProxy;
|
||||
fileType = archive.ar;
|
||||
path = "libdouble-conversion.a";
|
||||
remoteRef = 2DF0FFE62056DD460020B375 /* PBXContainerItemProxy */;
|
||||
sourceTree = BUILT_PRODUCTS_DIR;
|
||||
};
|
||||
2DF0FFE92056DD460020B375 /* libdouble-conversion.a */ = {
|
||||
isa = PBXReferenceProxy;
|
||||
fileType = archive.ar;
|
||||
path = "libdouble-conversion.a";
|
||||
remoteRef = 2DF0FFE82056DD460020B375 /* PBXContainerItemProxy */;
|
||||
sourceTree = BUILT_PRODUCTS_DIR;
|
||||
};
|
||||
3DAD3E841DF850E9000B6D8A /* libRCTImage-tvOS.a */ = {
|
||||
isa = PBXReferenceProxy;
|
||||
fileType = archive.ar;
|
||||
path = "libRCTImage-tvOS.a";
|
||||
remoteRef = 3DAD3E831DF850E9000B6D8A /* PBXContainerItemProxy */;
|
||||
sourceTree = BUILT_PRODUCTS_DIR;
|
||||
};
|
||||
3DAD3E881DF850E9000B6D8A /* libRCTLinking-tvOS.a */ = {
|
||||
isa = PBXReferenceProxy;
|
||||
fileType = archive.ar;
|
||||
path = "libRCTLinking-tvOS.a";
|
||||
remoteRef = 3DAD3E871DF850E9000B6D8A /* PBXContainerItemProxy */;
|
||||
sourceTree = BUILT_PRODUCTS_DIR;
|
||||
};
|
||||
3DAD3E8C1DF850E9000B6D8A /* libRCTNetwork-tvOS.a */ = {
|
||||
isa = PBXReferenceProxy;
|
||||
fileType = archive.ar;
|
||||
path = "libRCTNetwork-tvOS.a";
|
||||
remoteRef = 3DAD3E8B1DF850E9000B6D8A /* PBXContainerItemProxy */;
|
||||
sourceTree = BUILT_PRODUCTS_DIR;
|
||||
};
|
||||
3DAD3E901DF850E9000B6D8A /* libRCTSettings-tvOS.a */ = {
|
||||
isa = PBXReferenceProxy;
|
||||
fileType = archive.ar;
|
||||
path = "libRCTSettings-tvOS.a";
|
||||
remoteRef = 3DAD3E8F1DF850E9000B6D8A /* PBXContainerItemProxy */;
|
||||
sourceTree = BUILT_PRODUCTS_DIR;
|
||||
};
|
||||
3DAD3E941DF850E9000B6D8A /* libRCTText-tvOS.a */ = {
|
||||
isa = PBXReferenceProxy;
|
||||
fileType = archive.ar;
|
||||
path = "libRCTText-tvOS.a";
|
||||
remoteRef = 3DAD3E931DF850E9000B6D8A /* PBXContainerItemProxy */;
|
||||
sourceTree = BUILT_PRODUCTS_DIR;
|
||||
};
|
||||
3DAD3E991DF850E9000B6D8A /* libRCTWebSocket-tvOS.a */ = {
|
||||
isa = PBXReferenceProxy;
|
||||
fileType = archive.ar;
|
||||
path = "libRCTWebSocket-tvOS.a";
|
||||
remoteRef = 3DAD3E981DF850E9000B6D8A /* PBXContainerItemProxy */;
|
||||
sourceTree = BUILT_PRODUCTS_DIR;
|
||||
};
|
||||
3DAD3EA31DF850E9000B6D8A /* libReact.a */ = {
|
||||
isa = PBXReferenceProxy;
|
||||
fileType = archive.ar;
|
||||
path = libReact.a;
|
||||
remoteRef = 3DAD3EA21DF850E9000B6D8A /* PBXContainerItemProxy */;
|
||||
sourceTree = BUILT_PRODUCTS_DIR;
|
||||
};
|
||||
3DAD3EA51DF850E9000B6D8A /* libyoga.a */ = {
|
||||
isa = PBXReferenceProxy;
|
||||
fileType = archive.ar;
|
||||
path = libyoga.a;
|
||||
remoteRef = 3DAD3EA41DF850E9000B6D8A /* PBXContainerItemProxy */;
|
||||
sourceTree = BUILT_PRODUCTS_DIR;
|
||||
};
|
||||
3DAD3EA71DF850E9000B6D8A /* libyoga.a */ = {
|
||||
isa = PBXReferenceProxy;
|
||||
fileType = archive.ar;
|
||||
path = libyoga.a;
|
||||
remoteRef = 3DAD3EA61DF850E9000B6D8A /* PBXContainerItemProxy */;
|
||||
sourceTree = BUILT_PRODUCTS_DIR;
|
||||
};
|
||||
3DAD3EA91DF850E9000B6D8A /* libcxxreact.a */ = {
|
||||
isa = PBXReferenceProxy;
|
||||
fileType = archive.ar;
|
||||
path = libcxxreact.a;
|
||||
remoteRef = 3DAD3EA81DF850E9000B6D8A /* PBXContainerItemProxy */;
|
||||
sourceTree = BUILT_PRODUCTS_DIR;
|
||||
};
|
||||
3DAD3EAB1DF850E9000B6D8A /* libcxxreact.a */ = {
|
||||
isa = PBXReferenceProxy;
|
||||
fileType = archive.ar;
|
||||
path = libcxxreact.a;
|
||||
remoteRef = 3DAD3EAA1DF850E9000B6D8A /* PBXContainerItemProxy */;
|
||||
sourceTree = BUILT_PRODUCTS_DIR;
|
||||
};
|
||||
44461E5E230FEE4700570C98 /* libjsi.a */ = {
|
||||
isa = PBXReferenceProxy;
|
||||
fileType = archive.ar;
|
||||
path = libjsi.a;
|
||||
remoteRef = 44461E5D230FEE4700570C98 /* PBXContainerItemProxy */;
|
||||
sourceTree = BUILT_PRODUCTS_DIR;
|
||||
};
|
||||
44461E60230FEE4700570C98 /* libjsiexecutor.a */ = {
|
||||
isa = PBXReferenceProxy;
|
||||
fileType = archive.ar;
|
||||
path = libjsiexecutor.a;
|
||||
remoteRef = 44461E5F230FEE4700570C98 /* PBXContainerItemProxy */;
|
||||
sourceTree = BUILT_PRODUCTS_DIR;
|
||||
};
|
||||
44461E62230FEE4700570C98 /* libjsi-tvOS.a */ = {
|
||||
isa = PBXReferenceProxy;
|
||||
fileType = archive.ar;
|
||||
path = "libjsi-tvOS.a";
|
||||
remoteRef = 44461E61230FEE4700570C98 /* PBXContainerItemProxy */;
|
||||
sourceTree = BUILT_PRODUCTS_DIR;
|
||||
};
|
||||
44461E64230FEE4700570C98 /* libjsiexecutor-tvOS.a */ = {
|
||||
isa = PBXReferenceProxy;
|
||||
fileType = archive.ar;
|
||||
path = "libjsiexecutor-tvOS.a";
|
||||
remoteRef = 44461E63230FEE4700570C98 /* PBXContainerItemProxy */;
|
||||
sourceTree = BUILT_PRODUCTS_DIR;
|
||||
};
|
||||
5E9157331DD0AC6500FF2AA8 /* libRCTAnimation.a */ = {
|
||||
isa = PBXReferenceProxy;
|
||||
fileType = archive.ar;
|
||||
path = libRCTAnimation.a;
|
||||
remoteRef = 5E9157321DD0AC6500FF2AA8 /* PBXContainerItemProxy */;
|
||||
sourceTree = BUILT_PRODUCTS_DIR;
|
||||
};
|
||||
5E9157351DD0AC6500FF2AA8 /* libRCTAnimation.a */ = {
|
||||
isa = PBXReferenceProxy;
|
||||
fileType = archive.ar;
|
||||
path = libRCTAnimation.a;
|
||||
remoteRef = 5E9157341DD0AC6500FF2AA8 /* PBXContainerItemProxy */;
|
||||
sourceTree = BUILT_PRODUCTS_DIR;
|
||||
};
|
||||
78C398B91ACF4ADC00677621 /* libRCTLinking.a */ = {
|
||||
isa = PBXReferenceProxy;
|
||||
fileType = archive.ar;
|
||||
path = libRCTLinking.a;
|
||||
remoteRef = 78C398B81ACF4ADC00677621 /* PBXContainerItemProxy */;
|
||||
sourceTree = BUILT_PRODUCTS_DIR;
|
||||
};
|
||||
832341B51AAA6A8300B99B32 /* libRCTText.a */ = {
|
||||
isa = PBXReferenceProxy;
|
||||
fileType = archive.ar;
|
||||
path = libRCTText.a;
|
||||
remoteRef = 832341B41AAA6A8300B99B32 /* PBXContainerItemProxy */;
|
||||
sourceTree = BUILT_PRODUCTS_DIR;
|
||||
};
|
||||
ADBDB9271DFEBF0700ED6528 /* libRCTBlob.a */ = {
|
||||
isa = PBXReferenceProxy;
|
||||
fileType = archive.ar;
|
||||
path = libRCTBlob.a;
|
||||
remoteRef = ADBDB9261DFEBF0700ED6528 /* PBXContainerItemProxy */;
|
||||
sourceTree = BUILT_PRODUCTS_DIR;
|
||||
};
|
||||
/* End PBXReferenceProxy section */
|
||||
|
||||
/* Begin PBXResourcesBuildPhase section */
|
||||
13B07F8E1A680F5B00A75B9A /* Resources */ = {
|
||||
isa = PBXResourcesBuildPhase;
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
import * as React from 'react';
|
||||
import { Text, View, StyleSheet, Button } from 'react-native';
|
||||
import { useScreens } from 'react-native-screens';
|
||||
import { enableScreens } from 'react-native-screens';
|
||||
import {
|
||||
createAppContainer,
|
||||
createStackNavigator,
|
||||
createBottomTabNavigator,
|
||||
} from 'react-navigation';
|
||||
|
||||
useScreens();
|
||||
enableScreens();
|
||||
|
||||
class DetailsScreen extends React.Component {
|
||||
static navigationOptions = ({ navigation }) => {
|
||||
|
||||
@@ -8,8 +8,8 @@
|
||||
"postinstall": "rm -rf node_modules/react-native-screens/{.git,node_modules,Example}"
|
||||
},
|
||||
"dependencies": {
|
||||
"react": "16.5.1",
|
||||
"react-native": "^0.60.5",
|
||||
"react": "16.9.0",
|
||||
"react-native": "^0.61.2",
|
||||
"react-native-gesture-handler": "^1.0.12",
|
||||
"react-native-screens": "file:..",
|
||||
"react-navigation": "^3.0.8"
|
||||
@@ -20,7 +20,7 @@
|
||||
"babel-jest": "23.6.0",
|
||||
"jest": "23.6.0",
|
||||
"metro-react-native-babel-preset": "0.45.2",
|
||||
"react-test-renderer": "16.5.1"
|
||||
"react-test-renderer": "16.9.0"
|
||||
},
|
||||
"jest": {
|
||||
"preset": "react-native"
|
||||
|
||||
@@ -749,10 +749,10 @@
|
||||
"@types/istanbul-reports" "^1.1.1"
|
||||
"@types/yargs" "^13.0.0"
|
||||
|
||||
"@react-native-community/cli-platform-android@^2.6.0", "@react-native-community/cli-platform-android@^2.9.0":
|
||||
version "2.9.0"
|
||||
resolved "https://registry.yarnpkg.com/@react-native-community/cli-platform-android/-/cli-platform-android-2.9.0.tgz#28831e61ce565a2c7d1905852fce1eecfd33cb5e"
|
||||
integrity sha512-VEQs4Q6R5tnlYFrQIFoPEWjLc43whRHC9HeH+idbFymwDqysLVUffQbb9D6PJUj+C/AvrDhBhU6S3tDjGbSsag==
|
||||
"@react-native-community/cli-platform-android@^3.0.0-alpha.1", "@react-native-community/cli-platform-android@^3.0.0-alpha.2":
|
||||
version "3.0.0-alpha.2"
|
||||
resolved "https://registry.yarnpkg.com/@react-native-community/cli-platform-android/-/cli-platform-android-3.0.0-alpha.2.tgz#63cb00060c58a87d04b46229ef7140e056551dfa"
|
||||
integrity sha512-9HxWvBiK29AJQjavug658rEWHXVsqdAdL7rzMK9+gOid5zFoHrb1GoIeJm3byEowNZvqoy09nVcQvrUea41kQQ==
|
||||
dependencies:
|
||||
"@react-native-community/cli-tools" "^2.8.3"
|
||||
chalk "^2.4.2"
|
||||
@@ -762,10 +762,10 @@
|
||||
slash "^3.0.0"
|
||||
xmldoc "^1.1.2"
|
||||
|
||||
"@react-native-community/cli-platform-ios@^2.4.1", "@react-native-community/cli-platform-ios@^2.9.0":
|
||||
version "2.9.0"
|
||||
resolved "https://registry.yarnpkg.com/@react-native-community/cli-platform-ios/-/cli-platform-ios-2.9.0.tgz#21adb8ee813d6ca6fd9d4d9be63f92024f7e2fe7"
|
||||
integrity sha512-vg6EOamtFaaQ02FiWu+jzJTfeTJ0OVjJSAoR2rhJKNye6RgJLoQlfp0Hg3waF6XrO72a7afYZsPdKSlN3ewlHg==
|
||||
"@react-native-community/cli-platform-ios@^3.0.0-alpha.1", "@react-native-community/cli-platform-ios@^3.0.0-alpha.2":
|
||||
version "3.0.0-alpha.2"
|
||||
resolved "https://registry.yarnpkg.com/@react-native-community/cli-platform-ios/-/cli-platform-ios-3.0.0-alpha.2.tgz#c89e1a164f1dab62a8a024ae38b47eb0281e6ab9"
|
||||
integrity sha512-37FtnrWTUP0EzQ83raplcnOUlEzRCsDrsxGsUnBso33fNPBAJ4Ei6L/BuJPJZ+sCAWFbyO1XhVED0c1QuP0cww==
|
||||
dependencies:
|
||||
"@react-native-community/cli-tools" "^2.8.3"
|
||||
chalk "^2.4.2"
|
||||
@@ -781,14 +781,14 @@
|
||||
mime "^2.4.1"
|
||||
node-fetch "^2.5.0"
|
||||
|
||||
"@react-native-community/cli@^2.6.0":
|
||||
version "2.9.0"
|
||||
resolved "https://registry.yarnpkg.com/@react-native-community/cli/-/cli-2.9.0.tgz#f0d18dc3e5a8f68e3d6ad353c444dc2f08d3fbdc"
|
||||
integrity sha512-6TYkrR1pwIEPpiPZnOYscCGr5Xh8RijqBPVAOGTaEdpQQpc/J7GDPrePwbyTzwmCPtiK6XT+T5+1AiAK5bz/sw==
|
||||
"@react-native-community/cli@^3.0.0-alpha.1":
|
||||
version "3.0.0-alpha.2"
|
||||
resolved "https://registry.yarnpkg.com/@react-native-community/cli/-/cli-3.0.0-alpha.2.tgz#0f5b8aad800ab2633e699b3883534420e7926692"
|
||||
integrity sha512-bPl+Y3qX63QUTBnYYk2IAbNYjQnBeBPJz5jCBcxnOi8CWx4XQz7tN7Hh+vtqlwGoLQWs1hn7tMVh15sNmLYigw==
|
||||
dependencies:
|
||||
"@hapi/joi" "^15.0.3"
|
||||
"@react-native-community/cli-platform-android" "^2.9.0"
|
||||
"@react-native-community/cli-platform-ios" "^2.9.0"
|
||||
"@react-native-community/cli-platform-android" "^3.0.0-alpha.2"
|
||||
"@react-native-community/cli-platform-ios" "^3.0.0-alpha.2"
|
||||
"@react-native-community/cli-tools" "^2.8.3"
|
||||
chalk "^2.4.2"
|
||||
commander "^2.19.0"
|
||||
@@ -804,10 +804,10 @@
|
||||
graceful-fs "^4.1.3"
|
||||
inquirer "^3.0.6"
|
||||
lodash "^4.17.5"
|
||||
metro "^0.54.1"
|
||||
metro-config "^0.54.1"
|
||||
metro-core "^0.54.1"
|
||||
metro-react-native-babel-transformer "^0.54.1"
|
||||
metro "^0.56.0"
|
||||
metro-config "^0.56.0"
|
||||
metro-core "^0.56.0"
|
||||
metro-react-native-babel-transformer "^0.56.0"
|
||||
minimist "^1.2.0"
|
||||
mkdirp "^0.5.1"
|
||||
morgan "^1.9.0"
|
||||
@@ -1633,7 +1633,7 @@ combined-stream@~1.0.6:
|
||||
dependencies:
|
||||
delayed-stream "~1.0.0"
|
||||
|
||||
commander@^2.19.0, commander@~2.20.0:
|
||||
commander@^2.19.0:
|
||||
version "2.20.0"
|
||||
resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.0.tgz#d58bb2b5c1ee8f87b0d340027e9e94e222c5a422"
|
||||
integrity sha512-7j2y+40w61zy6YC2iRNpUe/NwhNyoXrYpHMrSunaMG64nRnaf96zO/KMQR4OyN/UnE5KLyEBnKHd4aG3rskjpQ==
|
||||
@@ -1642,6 +1642,11 @@ commander@~2.13.0:
|
||||
version "2.13.0"
|
||||
resolved "https://registry.yarnpkg.com/commander/-/commander-2.13.0.tgz#6964bca67685df7c1f1430c584f07d7597885b9c"
|
||||
|
||||
commander@~2.20.3:
|
||||
version "2.20.3"
|
||||
resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33"
|
||||
integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==
|
||||
|
||||
commondir@^1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b"
|
||||
@@ -1915,10 +1920,6 @@ diff@^3.2.0:
|
||||
version "3.5.0"
|
||||
resolved "https://registry.yarnpkg.com/diff/-/diff-3.5.0.tgz#800c0dd1e0a8bfbc95835c202ad220fe317e5a12"
|
||||
|
||||
dom-walk@^0.1.0:
|
||||
version "0.1.1"
|
||||
resolved "https://registry.yarnpkg.com/dom-walk/-/dom-walk-0.1.1.tgz#672226dc74c8f799ad35307df936aba11acd6018"
|
||||
|
||||
domexception@^1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/domexception/-/domexception-1.0.1.tgz#937442644ca6a31261ef36e3ec677fe805582c90"
|
||||
@@ -2468,13 +2469,6 @@ glob@^7.0.3, glob@^7.0.5, glob@^7.1.1, glob@^7.1.2:
|
||||
once "^1.3.0"
|
||||
path-is-absolute "^1.0.0"
|
||||
|
||||
global@^4.3.0:
|
||||
version "4.3.2"
|
||||
resolved "https://registry.yarnpkg.com/global/-/global-4.3.2.tgz#e76989268a6c74c38908b1305b10fc0e394e9d0f"
|
||||
dependencies:
|
||||
min-document "^2.19.0"
|
||||
process "~0.5.1"
|
||||
|
||||
globals@^11.1.0:
|
||||
version "11.12.0"
|
||||
resolved "https://registry.yarnpkg.com/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e"
|
||||
@@ -2498,9 +2492,9 @@ growly@^1.3.0:
|
||||
resolved "https://registry.yarnpkg.com/growly/-/growly-1.3.0.tgz#f10748cbe76af964b7c96c93c6bcc28af120c081"
|
||||
|
||||
handlebars@^4.0.3:
|
||||
version "4.2.0"
|
||||
resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.2.0.tgz#57ce8d2175b9bbb3d8b3cf3e4217b1aec8ddcb2e"
|
||||
integrity sha512-Kb4xn5Qh1cxAKvQnzNWZ512DhABzyFNmsaJf3OAkWNa4NkaqWcNI8Tao8Tasi0/F4JD9oyG0YxuFyvyR57d+Gw==
|
||||
version "4.5.3"
|
||||
resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.5.3.tgz#5cf75bd8714f7605713511a56be7c349becb0482"
|
||||
integrity sha512-3yPecJoJHK/4c6aZhSvxOyG4vJKDshV36VHp0iVCDVh7o9w2vwi3NSnL2MMPj3YdduqaBcu7cGbggJQM0br9xA==
|
||||
dependencies:
|
||||
neo-async "^2.6.0"
|
||||
optimist "^0.6.1"
|
||||
@@ -2575,10 +2569,10 @@ has@^1.0.1:
|
||||
dependencies:
|
||||
function-bind "^1.1.1"
|
||||
|
||||
hermesvm@^0.1.0:
|
||||
version "0.1.0"
|
||||
resolved "https://registry.yarnpkg.com/hermesvm/-/hermesvm-0.1.0.tgz#4bfaf4ac682a2fd407b862ab641eb8deb232de83"
|
||||
integrity sha512-GbP6dKaVW/V2QpB+DZPxcmhBhJVFa9cHS/xRX7FD1MGfa6Z1aHHD83VDCwo3SgcqNj5yHlVbe9UgrK1PFGCXpw==
|
||||
hermes-engine@^0.2.1:
|
||||
version "0.2.1"
|
||||
resolved "https://registry.yarnpkg.com/hermes-engine/-/hermes-engine-0.2.1.tgz#25c0f1ff852512a92cb5c5cc47cf967e1e722ea2"
|
||||
integrity sha512-eNHUQHuadDMJARpaqvlCZoK/Nitpj6oywq3vQ3wCwEsww5morX34mW5PmKWQTO7aU0ck0hgulxR+EVDlXygGxQ==
|
||||
|
||||
hoist-non-react-statics@^2.3.1, hoist-non-react-statics@^2.5.0:
|
||||
version "2.5.5"
|
||||
@@ -3421,7 +3415,7 @@ jsbn@~0.1.0:
|
||||
version "0.1.1"
|
||||
resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513"
|
||||
|
||||
jsc-android@245459.0.0:
|
||||
jsc-android@^245459.0.0:
|
||||
version "245459.0.0"
|
||||
resolved "https://registry.yarnpkg.com/jsc-android/-/jsc-android-245459.0.0.tgz#e584258dd0b04c9159a27fb104cd5d491fd202c9"
|
||||
integrity sha512-wkjURqwaB1daNkDi2OYYbsLnIdC/lUM2nPXQKRs5pqEU9chDg435bjvo+LSaHotDENygHQDHe+ntUkkw2gwMtg==
|
||||
@@ -3639,7 +3633,7 @@ lodash.throttle@^4.1.1:
|
||||
version "4.1.1"
|
||||
resolved "https://registry.yarnpkg.com/lodash.throttle/-/lodash.throttle-4.1.1.tgz#c23e91b710242ac70c37f1e1cda9274cc39bf2f4"
|
||||
|
||||
lodash@^4.13.1, lodash@^4.17.10, lodash@^4.17.13, lodash@^4.17.4, lodash@^4.17.5, lodash@^4.3.0, lodash@^4.6.1:
|
||||
lodash@^4.13.1, lodash@^4.17.10, lodash@^4.17.13, lodash@^4.17.4, lodash@^4.17.5, lodash@^4.3.0:
|
||||
version "4.17.15"
|
||||
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.15.tgz#b447f6670a0455bbfeedd11392eff330ea097548"
|
||||
integrity sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==
|
||||
@@ -3737,10 +3731,10 @@ merge@^1.2.0:
|
||||
resolved "https://registry.yarnpkg.com/merge/-/merge-1.2.1.tgz#38bebf80c3220a8a487b6fcfb3941bb11720c145"
|
||||
integrity sha512-VjFo4P5Whtj4vsLzsYBu5ayHhoHJ0UqNm7ibvShmbmoz7tGi0vXaoJbGdB+GmDMLUdg8DpQXEIeVDAe8MaABvQ==
|
||||
|
||||
metro-babel-register@0.54.1:
|
||||
version "0.54.1"
|
||||
resolved "https://registry.yarnpkg.com/metro-babel-register/-/metro-babel-register-0.54.1.tgz#7d2bfe444b1ccef8de99aedc7d9330891d806076"
|
||||
integrity sha512-j3VydgncUG8HP6AZala6GTIt3V01nptodnnOke3JMYLqgk8EJ1LOVOdotK9pXi80o7EmmNKFs/LyyH8z+uAJzQ==
|
||||
metro-babel-register@0.56.0, metro-babel-register@^0.56.0:
|
||||
version "0.56.0"
|
||||
resolved "https://registry.yarnpkg.com/metro-babel-register/-/metro-babel-register-0.56.0.tgz#f5eb41b2d7be4297367292dd545fda898e9158a7"
|
||||
integrity sha512-/jkfdFpmmyG8Y1ik01EEgqTBy6Y89exZmJi58ej/bVK7u0hhA7mrcqusOeVRlaH+rboecPG52ouuDxcnNSXwzQ==
|
||||
dependencies:
|
||||
"@babel/core" "^7.0.0"
|
||||
"@babel/plugin-proposal-class-properties" "^7.0.0"
|
||||
@@ -3755,12 +3749,13 @@ metro-babel-register@0.54.1:
|
||||
core-js "^2.2.2"
|
||||
escape-string-regexp "^1.0.5"
|
||||
|
||||
metro-babel-transformer@0.54.1:
|
||||
version "0.54.1"
|
||||
resolved "https://registry.yarnpkg.com/metro-babel-transformer/-/metro-babel-transformer-0.54.1.tgz#371ffa2d1118b22cc9e40b3c3ea6738c49dae9dc"
|
||||
integrity sha512-2aiAnuYBdcLV1VINb8ENAA4keIaJIepHgR9+iRvIde+9GSjKnexqx4nNmJN392285gRDp1fVZ7uY0uQawK/A5g==
|
||||
metro-babel-transformer@0.56.0:
|
||||
version "0.56.0"
|
||||
resolved "https://registry.yarnpkg.com/metro-babel-transformer/-/metro-babel-transformer-0.56.0.tgz#1ee73c7d97aee8671b7f0983a41e928f4802a08e"
|
||||
integrity sha512-8w/NpcKovmzkY4/++zX5v+OLOcBPXC9iygNI0ZdexA9U5/ncAY3U1VaF2ScFKzhrpkb8AJioYYioAgrRMLYStg==
|
||||
dependencies:
|
||||
"@babel/core" "^7.0.0"
|
||||
metro-source-map "0.56.0"
|
||||
|
||||
metro-babel7-plugin-react-transform@0.45.2:
|
||||
version "0.45.2"
|
||||
@@ -3768,49 +3763,42 @@ metro-babel7-plugin-react-transform@0.45.2:
|
||||
dependencies:
|
||||
"@babel/helper-module-imports" "^7.0.0"
|
||||
|
||||
metro-babel7-plugin-react-transform@0.54.1:
|
||||
version "0.54.1"
|
||||
resolved "https://registry.yarnpkg.com/metro-babel7-plugin-react-transform/-/metro-babel7-plugin-react-transform-0.54.1.tgz#5335b810284789724886dc483d5bde9c149a1996"
|
||||
integrity sha512-jWm5myuMoZAOhoPsa8ItfDxdTcOzKhTTzzhFlbZnRamE7i9qybeMdrZt8KHQpF7i2p/mKzE9Yhf4ouOz5K/jHg==
|
||||
dependencies:
|
||||
"@babel/helper-module-imports" "^7.0.0"
|
||||
|
||||
metro-cache@0.54.1:
|
||||
version "0.54.1"
|
||||
resolved "https://registry.yarnpkg.com/metro-cache/-/metro-cache-0.54.1.tgz#2e9017cbd11106837b8c385c9eb8c8175469a8c1"
|
||||
integrity sha512-RxCFoNcANHXZYi4MIQNnqh68gUnC3bMpzCFJY5pBoqqdrkkn8ibYglBweA0/DW7hx1OZTJWelwS1Dp8xxmE2CA==
|
||||
metro-cache@0.56.0:
|
||||
version "0.56.0"
|
||||
resolved "https://registry.yarnpkg.com/metro-cache/-/metro-cache-0.56.0.tgz#213a8d5fad6c695ece841e8ef961285607295511"
|
||||
integrity sha512-fjfdHGAog3SMEpWF6QE8lTeYUMMpvGYHBfc7DYkDvkEwvEympFzn6dWg7uOeh90F1kjUABtAgkan0SC4CWWF/g==
|
||||
dependencies:
|
||||
jest-serializer "^24.4.0"
|
||||
metro-core "0.54.1"
|
||||
metro-core "0.56.0"
|
||||
mkdirp "^0.5.1"
|
||||
rimraf "^2.5.4"
|
||||
|
||||
metro-config@0.54.1, metro-config@^0.54.1:
|
||||
version "0.54.1"
|
||||
resolved "https://registry.yarnpkg.com/metro-config/-/metro-config-0.54.1.tgz#808b4e17625d9f4e9afa34232778fdf8e63cc8dd"
|
||||
integrity sha512-FpxrA+63rGkPGvGI653dvuSreJzU+eOTILItVnnhmqwn2SAK5V00N/qGTOIJe2YIuWEFXwCzw9lXmANrXbwuGg==
|
||||
metro-config@0.56.0, metro-config@^0.56.0:
|
||||
version "0.56.0"
|
||||
resolved "https://registry.yarnpkg.com/metro-config/-/metro-config-0.56.0.tgz#8e4dae8df7bfa3d37b754240bc76db87aebc6348"
|
||||
integrity sha512-R7n41V9pkSeQe/7MdMoM1XiWZGNDHVAKKcR3QPoSdVhYFJkUbV2UsfJDBTohmTML07BkAQ1Bys5dGrQZfgeeNQ==
|
||||
dependencies:
|
||||
cosmiconfig "^5.0.5"
|
||||
jest-validate "^24.7.0"
|
||||
metro "0.54.1"
|
||||
metro-cache "0.54.1"
|
||||
metro-core "0.54.1"
|
||||
metro "0.56.0"
|
||||
metro-cache "0.56.0"
|
||||
metro-core "0.56.0"
|
||||
pretty-format "^24.7.0"
|
||||
|
||||
metro-core@0.54.1, metro-core@^0.54.1:
|
||||
version "0.54.1"
|
||||
resolved "https://registry.yarnpkg.com/metro-core/-/metro-core-0.54.1.tgz#17f6ecc167918da8819d4af5726349e55714954b"
|
||||
integrity sha512-8oz3Ck7QFBzW9dG9tKFhrXHKPu2Ajx3R7eatf61Gl6Jf/tF7PNouv3wHxPsJW3oXDFiwKLszd89+OgleTGkB5g==
|
||||
metro-core@0.56.0, metro-core@^0.56.0:
|
||||
version "0.56.0"
|
||||
resolved "https://registry.yarnpkg.com/metro-core/-/metro-core-0.56.0.tgz#ea1175fdfc1685bc62a28eca33edd48ec0030339"
|
||||
integrity sha512-R1RS1ZlBG2sjucjhAbRPb6FDB668as3/FuiARJGEsYXt3kpMz2thOpdgWG86sDygSM/U4qLhU3hQf1FU+NUP2w==
|
||||
dependencies:
|
||||
jest-haste-map "^24.7.1"
|
||||
lodash.throttle "^4.1.1"
|
||||
metro-resolver "0.54.1"
|
||||
metro-resolver "0.56.0"
|
||||
wordwrap "^1.0.0"
|
||||
|
||||
metro-inspector-proxy@0.54.1:
|
||||
version "0.54.1"
|
||||
resolved "https://registry.yarnpkg.com/metro-inspector-proxy/-/metro-inspector-proxy-0.54.1.tgz#0ef48ee3feb11c6da47aa100151a9bf2a7c358ee"
|
||||
integrity sha512-sf6kNu7PgFW6U+hU7YGZfbAUKAPVvCJhY8YVu/A1RMKH9nNULrCo+jlWh0gWgmFfWRQiAPCElevROg+5somk8A==
|
||||
metro-inspector-proxy@0.56.0:
|
||||
version "0.56.0"
|
||||
resolved "https://registry.yarnpkg.com/metro-inspector-proxy/-/metro-inspector-proxy-0.56.0.tgz#78a0590f018ea255f86824a425958b7dd74b84df"
|
||||
integrity sha512-p+m6rjB749i3P2N3B9BRy+pAkBnenb+ymFJR8CToLxQdbCk3iRwj1hlf4F2OXoM26eZZdm0AC+Z/zfiOCuePJA==
|
||||
dependencies:
|
||||
connect "^3.6.5"
|
||||
debug "^2.2.0"
|
||||
@@ -3818,10 +3806,10 @@ metro-inspector-proxy@0.54.1:
|
||||
ws "^1.1.5"
|
||||
yargs "^9.0.0"
|
||||
|
||||
metro-minify-uglify@0.54.1:
|
||||
version "0.54.1"
|
||||
resolved "https://registry.yarnpkg.com/metro-minify-uglify/-/metro-minify-uglify-0.54.1.tgz#54ed1cb349245ce82dba8cc662bbf69fbca142c3"
|
||||
integrity sha512-z+pOPna/8IxD4OhjW6Xo1mV2EszgqqQHqBm1FdmtdF6IpWkQp33qpDBNEi9NGZTOr7pp2bvcxZnvNJdC2lrK9Q==
|
||||
metro-minify-uglify@0.56.0:
|
||||
version "0.56.0"
|
||||
resolved "https://registry.yarnpkg.com/metro-minify-uglify/-/metro-minify-uglify-0.56.0.tgz#1a4aa32fb5326deb7c36eb8e0a113dc3daaf287a"
|
||||
integrity sha512-0u2ClTDuaxtWDpAZpnGUEvxJ/X3PzaaSQxPpsGSnBa0g+fqV8xyz8BGtFieQ+Ukuiw7SRwTkUQChkSVi+PAOdA==
|
||||
dependencies:
|
||||
uglify-es "^3.1.9"
|
||||
|
||||
@@ -3860,10 +3848,10 @@ metro-react-native-babel-preset@0.45.2:
|
||||
"@babel/template" "^7.0.0"
|
||||
metro-babel7-plugin-react-transform "0.45.2"
|
||||
|
||||
metro-react-native-babel-preset@0.54.1:
|
||||
version "0.54.1"
|
||||
resolved "https://registry.yarnpkg.com/metro-react-native-babel-preset/-/metro-react-native-babel-preset-0.54.1.tgz#b8f03865c381841d7f8912e7ba46804ea3a928b8"
|
||||
integrity sha512-Hfr32+u5yYl3qhYQJU8NQ26g4kQlc3yFMg7keVR/3H8rwBIbFqXgsKt8oe0dOrv7WvrMqBHhDtVdU9ls3sSq8g==
|
||||
metro-react-native-babel-preset@0.56.0:
|
||||
version "0.56.0"
|
||||
resolved "https://registry.yarnpkg.com/metro-react-native-babel-preset/-/metro-react-native-babel-preset-0.56.0.tgz#fa47dfd5f7678e89cffd1249020b8add6938fc48"
|
||||
integrity sha512-MAo1fm0dNn6MVZmylaz6k2HC1MINHLTLfE7O3a9Xz3fAtbGbApisp06rBUfK5uUqIJDmAaKgbiT34lHJSIiE6Q==
|
||||
dependencies:
|
||||
"@babel/plugin-proposal-class-properties" "^7.0.0"
|
||||
"@babel/plugin-proposal-export-default-from" "^7.0.0"
|
||||
@@ -3899,62 +3887,54 @@ metro-react-native-babel-preset@0.54.1:
|
||||
"@babel/plugin-transform-typescript" "^7.0.0"
|
||||
"@babel/plugin-transform-unicode-regex" "^7.0.0"
|
||||
"@babel/template" "^7.0.0"
|
||||
metro-babel7-plugin-react-transform "0.54.1"
|
||||
react-transform-hmr "^1.0.4"
|
||||
react-refresh "^0.4.0"
|
||||
|
||||
metro-react-native-babel-transformer@0.54.1, metro-react-native-babel-transformer@^0.54.1:
|
||||
version "0.54.1"
|
||||
resolved "https://registry.yarnpkg.com/metro-react-native-babel-transformer/-/metro-react-native-babel-transformer-0.54.1.tgz#45b56db004421134e10e739f69e8de50775fef17"
|
||||
integrity sha512-ECw7xG91t8dk/PHdiyoC5SP1s9OQzfmJzG5m0YOZaKtHMe534qTDbncxaKfTI3CP99yti2maXFBRVj+xyvph/g==
|
||||
metro-react-native-babel-transformer@^0.56.0:
|
||||
version "0.56.0"
|
||||
resolved "https://registry.yarnpkg.com/metro-react-native-babel-transformer/-/metro-react-native-babel-transformer-0.56.0.tgz#43198b54d9d88acfc9fa6cbdd22fec0e871966da"
|
||||
integrity sha512-9eJ6kzizy80KlqNryg9TjlHdA4PZPWw0TV8Ih7H6RmYmuMzac5gjIW9FUrXsVWI56kQf+L5SdD/dCOWDqez/lQ==
|
||||
dependencies:
|
||||
"@babel/core" "^7.0.0"
|
||||
babel-preset-fbjs "^3.1.2"
|
||||
metro-babel-transformer "0.54.1"
|
||||
metro-react-native-babel-preset "0.54.1"
|
||||
metro-babel-transformer "0.56.0"
|
||||
metro-react-native-babel-preset "0.56.0"
|
||||
metro-source-map "0.56.0"
|
||||
|
||||
metro-resolver@0.54.1:
|
||||
version "0.54.1"
|
||||
resolved "https://registry.yarnpkg.com/metro-resolver/-/metro-resolver-0.54.1.tgz#0295b38624b678b88b16bf11d47288845132b087"
|
||||
integrity sha512-Byv1LIawYAASy9CFRwzrncYnqaFGLe8vpw178EtzStqP05Hu6hXSqkNTrfoXa+3V9bPFGCrVzFx2NY3gFp2btg==
|
||||
metro-resolver@0.56.0:
|
||||
version "0.56.0"
|
||||
resolved "https://registry.yarnpkg.com/metro-resolver/-/metro-resolver-0.56.0.tgz#e9d69ae2daf8c25c19492f75bc55db85f6ec2b3e"
|
||||
integrity sha512-thI31ZLnRr6l8/uIQ3pemMOp0+5btvj8ntv6qcY0scqqTRxJvJL4OQMM8yNbq8t8kPH5/1U0N+PvvQQ5g2QeIA==
|
||||
dependencies:
|
||||
absolute-path "^0.0.0"
|
||||
|
||||
metro-source-map@0.54.1:
|
||||
version "0.54.1"
|
||||
resolved "https://registry.yarnpkg.com/metro-source-map/-/metro-source-map-0.54.1.tgz#e17bad53c11978197d3c05c9168d799c2e04dcc5"
|
||||
integrity sha512-E9iSYMSUSq5qYi1R2hTQtxH4Mxjzfgr/jaSmQIWi7h3fG2P1qOZNNSzeaeUeTK+s2N/ksVlkcL5kMikol8CDrQ==
|
||||
dependencies:
|
||||
"@babel/traverse" "^7.0.0"
|
||||
"@babel/types" "^7.0.0"
|
||||
source-map "^0.5.6"
|
||||
|
||||
metro-source-map@0.55.0, metro-source-map@^0.55.0:
|
||||
version "0.55.0"
|
||||
resolved "https://registry.yarnpkg.com/metro-source-map/-/metro-source-map-0.55.0.tgz#1f6289905f08277c398f2b9b9c13e7e0e5a6f540"
|
||||
integrity sha512-HZODA0KPl5onJNGIztfTHHWurR2nL6Je/X8wwj+bL4ZBB/hSMVeDk7rWReCAvO3twVz7Ztp8Si0jfMmmH4Ruuw==
|
||||
metro-source-map@0.56.0, metro-source-map@^0.56.0:
|
||||
version "0.56.0"
|
||||
resolved "https://registry.yarnpkg.com/metro-source-map/-/metro-source-map-0.56.0.tgz#dd2db425d8245661563045336d10c52bc8d4b27d"
|
||||
integrity sha512-W3c91L+CtbQTRxOrcVteCi5XlSXh+L0Zy85YBwm+FkWTKfrYjacr/yW1S9/LutpLgWE0W0VBeQeY++aRHwpx0g==
|
||||
dependencies:
|
||||
"@babel/traverse" "^7.0.0"
|
||||
"@babel/types" "^7.0.0"
|
||||
invariant "^2.2.4"
|
||||
metro-symbolicate "0.55.0"
|
||||
ob1 "0.55.0"
|
||||
metro-symbolicate "0.56.0"
|
||||
ob1 "0.56.0"
|
||||
source-map "^0.5.6"
|
||||
vlq "^1.0.0"
|
||||
|
||||
metro-symbolicate@0.55.0:
|
||||
version "0.55.0"
|
||||
resolved "https://registry.yarnpkg.com/metro-symbolicate/-/metro-symbolicate-0.55.0.tgz#4086a2adae54b5e44a4911ca572d8a7b03c71fa1"
|
||||
integrity sha512-3r3Gpv5L4U7rBGpIqw5S1nun5MelfUMLRiScJsPRGZVTX3WY1w+zpaQKlWBi5yuHf5dMQ+ZUVbhb02IdrfJ2Fg==
|
||||
metro-symbolicate@0.56.0:
|
||||
version "0.56.0"
|
||||
resolved "https://registry.yarnpkg.com/metro-symbolicate/-/metro-symbolicate-0.56.0.tgz#694701faee7dafc53bd4d8488495504546e9c5b4"
|
||||
integrity sha512-5gJtwdSS0eYlTYB7PXatohBknz1sWUTfMBhwjn6zbgoyR6Apkpl2t2TfZxwfDTauhcEV1gRLmuodrVENs01r8g==
|
||||
dependencies:
|
||||
metro-source-map "0.55.0"
|
||||
invariant "^2.2.4"
|
||||
metro-source-map "0.56.0"
|
||||
source-map "^0.5.6"
|
||||
through2 "^2.0.1"
|
||||
vlq "^1.0.0"
|
||||
|
||||
metro@0.54.1, metro@^0.54.1:
|
||||
version "0.54.1"
|
||||
resolved "https://registry.yarnpkg.com/metro/-/metro-0.54.1.tgz#a629be00abee5a450a25a8f71c24745f70cc9b44"
|
||||
integrity sha512-6ODPT4mEo4FCpbExRNnQAcZmf1VeNvYOTMj2Na03FjGqhNODHhI2U/wF/Ul5gqTyJ2dVdkXeyvKW3gl/LrnJRg==
|
||||
metro@0.56.0, metro@^0.56.0:
|
||||
version "0.56.0"
|
||||
resolved "https://registry.yarnpkg.com/metro/-/metro-0.56.0.tgz#66b77085ac4cb1e3d72569e851499a3d82d19316"
|
||||
integrity sha512-X0QEeoIgbVX9VdhtzNPd8/+WSIaqnQuRaZ1gA1UL2HHlsA23eMsqxP1LUeLtA7DJ1LGGbiJlp6+FdAF/D8IaNg==
|
||||
dependencies:
|
||||
"@babel/core" "^7.0.0"
|
||||
"@babel/generator" "^7.0.0"
|
||||
@@ -3983,21 +3963,21 @@ metro@0.54.1, metro@^0.54.1:
|
||||
json-stable-stringify "^1.0.1"
|
||||
lodash.throttle "^4.1.1"
|
||||
merge-stream "^1.0.1"
|
||||
metro-babel-register "0.54.1"
|
||||
metro-babel-transformer "0.54.1"
|
||||
metro-cache "0.54.1"
|
||||
metro-config "0.54.1"
|
||||
metro-core "0.54.1"
|
||||
metro-inspector-proxy "0.54.1"
|
||||
metro-minify-uglify "0.54.1"
|
||||
metro-react-native-babel-preset "0.54.1"
|
||||
metro-resolver "0.54.1"
|
||||
metro-source-map "0.54.1"
|
||||
metro-babel-register "0.56.0"
|
||||
metro-babel-transformer "0.56.0"
|
||||
metro-cache "0.56.0"
|
||||
metro-config "0.56.0"
|
||||
metro-core "0.56.0"
|
||||
metro-inspector-proxy "0.56.0"
|
||||
metro-minify-uglify "0.56.0"
|
||||
metro-react-native-babel-preset "0.56.0"
|
||||
metro-resolver "0.56.0"
|
||||
metro-source-map "0.56.0"
|
||||
metro-symbolicate "0.56.0"
|
||||
mime-types "2.1.11"
|
||||
mkdirp "^0.5.1"
|
||||
node-fetch "^2.2.0"
|
||||
nullthrows "^1.1.0"
|
||||
react-transform-hmr "^1.0.4"
|
||||
resolve "^1.5.0"
|
||||
rimraf "^2.5.4"
|
||||
serialize-error "^2.1.0"
|
||||
@@ -4084,12 +4064,6 @@ mimic-fn@^2.0.0:
|
||||
resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b"
|
||||
integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==
|
||||
|
||||
min-document@^2.19.0:
|
||||
version "2.19.0"
|
||||
resolved "https://registry.yarnpkg.com/min-document/-/min-document-2.19.0.tgz#7bd282e3f5842ed295bb748cdd9f1ffa2c824685"
|
||||
dependencies:
|
||||
dom-walk "^0.1.0"
|
||||
|
||||
minimatch@^3.0.3, minimatch@^3.0.4:
|
||||
version "3.0.4"
|
||||
resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083"
|
||||
@@ -4339,10 +4313,10 @@ oauth-sign@~0.9.0:
|
||||
version "0.9.0"
|
||||
resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.9.0.tgz#47a7b016baa68b5fa0ecf3dee08a85c679ac6455"
|
||||
|
||||
ob1@0.55.0:
|
||||
version "0.55.0"
|
||||
resolved "https://registry.yarnpkg.com/ob1/-/ob1-0.55.0.tgz#e393b4ae786ef442b3ef2a298ab70d6ec353dbdd"
|
||||
integrity sha512-pfyiMVsUItl8WiRKMT15eCi662pCRAuYTq2+V3UpE+PpFErJI/TvRh/M/l/9TaLlbFr7krJ7gdl+FXJNcybmvw==
|
||||
ob1@0.56.0:
|
||||
version "0.56.0"
|
||||
resolved "https://registry.yarnpkg.com/ob1/-/ob1-0.56.0.tgz#70107c65697e617e9e2728fdc03da9e3ab6afef8"
|
||||
integrity sha512-3rvepvXPw+OIkcut4MaRYIoy4thTWvWhTK+Hg4+y9fOBWVF9acpBvtm2NSbH9Vw9UBG/9v+T5euwPxUSUIDPWw==
|
||||
|
||||
object-assign@^4.0.1, object-assign@^4.1.0, object-assign@^4.1.1:
|
||||
version "4.1.1"
|
||||
@@ -4702,10 +4676,6 @@ process-nextick-args@~2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.0.tgz#a37d732f4271b4ab1ad070d35508e8290788ffaa"
|
||||
|
||||
process@~0.5.1:
|
||||
version "0.5.2"
|
||||
resolved "https://registry.yarnpkg.com/process/-/process-0.5.2.tgz#1638d8a8e34c2f440a91db95ab9aeb677fc185cf"
|
||||
|
||||
promise@^7.1.1:
|
||||
version "7.3.1"
|
||||
resolved "https://registry.yarnpkg.com/promise/-/promise-7.3.1.tgz#064b72602b18f90f29192b8b1bc418ffd1ebd3bf"
|
||||
@@ -4794,11 +4764,7 @@ rc@^1.2.7:
|
||||
minimist "^1.2.0"
|
||||
strip-json-comments "~2.0.1"
|
||||
|
||||
react-deep-force-update@^1.0.0:
|
||||
version "1.1.2"
|
||||
resolved "https://registry.yarnpkg.com/react-deep-force-update/-/react-deep-force-update-1.1.2.tgz#3d2ae45c2c9040cbb1772be52f8ea1ade6ca2ee1"
|
||||
|
||||
react-devtools-core@^3.6.1:
|
||||
react-devtools-core@^3.6.3:
|
||||
version "3.6.3"
|
||||
resolved "https://registry.yarnpkg.com/react-devtools-core/-/react-devtools-core-3.6.3.tgz#977d95b684c6ad28205f0c62e1e12c5f16675814"
|
||||
integrity sha512-+P+eFy/yo8Z/UH9J0DqHZuUM5+RI2wl249TNvMx3J2jpUomLQa4Zxl56GEotGfw3PIP1eI+hVf1s53FlUONStQ==
|
||||
@@ -4806,15 +4772,16 @@ react-devtools-core@^3.6.1:
|
||||
shell-quote "^1.6.1"
|
||||
ws "^3.3.1"
|
||||
|
||||
react-is@^16.5.1:
|
||||
version "16.5.2"
|
||||
resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.5.2.tgz#e2a7b7c3f5d48062eb769fcb123505eb928722e3"
|
||||
|
||||
react-is@^16.7.0, react-is@^16.8.1, react-is@^16.8.4, react-is@^16.8.6:
|
||||
version "16.9.0"
|
||||
resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.9.0.tgz#21ca9561399aad0ff1a7701c01683e8ca981edcb"
|
||||
integrity sha512-tJBzzzIgnnRfEm046qRcURvwQnZVXmuCbscxUO5RWrGTXpon2d4c8mI0D8WE6ydVIm29JiLB6+RslkIvym9Rjw==
|
||||
|
||||
react-is@^16.9.0:
|
||||
version "16.10.2"
|
||||
resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.10.2.tgz#984120fd4d16800e9a738208ab1fba422d23b5ab"
|
||||
integrity sha512-INBT1QEgtcCCgvccr5/86CfD71fw9EPmDxgiJX4I2Ddr6ZsV6iFXsuby+qWJPtmNuMY0zByTsG4468P7nHuNWA==
|
||||
|
||||
react-lifecycles-compat@^3.0.4:
|
||||
version "3.0.4"
|
||||
resolved "https://registry.yarnpkg.com/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz#4f1a273afdfc8f3488a8c516bfda78f872352362"
|
||||
@@ -4844,7 +4811,7 @@ react-native-safe-area-view@^0.14.1:
|
||||
debounce "^1.2.0"
|
||||
|
||||
"react-native-screens@file:..":
|
||||
version "2.0.0-alpha.2"
|
||||
version "2.0.0-alpha.22"
|
||||
dependencies:
|
||||
debounce "^1.2.0"
|
||||
|
||||
@@ -4855,15 +4822,15 @@ react-native-tab-view@^1.2.0, react-native-tab-view@^1.4.1:
|
||||
dependencies:
|
||||
prop-types "^15.6.1"
|
||||
|
||||
react-native@^0.60.5:
|
||||
version "0.60.5"
|
||||
resolved "https://registry.yarnpkg.com/react-native/-/react-native-0.60.5.tgz#3c1d9c06a0fbab9807220b6acac09488d39186ee"
|
||||
integrity sha512-cZwI0XzzihACN+7an1Dy46A83FRaAe2Xyd7laCalFFAppZIYeMVphZQWrVljJk5kIZBNtYG35TY1VsghQ0Oc2Q==
|
||||
react-native@^0.61.2:
|
||||
version "0.61.2"
|
||||
resolved "https://registry.yarnpkg.com/react-native/-/react-native-0.61.2.tgz#987b91b063557f8ebec803fdfea2044a24bdbe4d"
|
||||
integrity sha512-hhd8bYbkkZYHoOndxUwbjJ6Yd9HFn5PvwqqS41uJ1xADdw44rx/svuwmJNA1RKF7jH74uR2jpBViWYGd36zGyg==
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.0.0"
|
||||
"@react-native-community/cli" "^2.6.0"
|
||||
"@react-native-community/cli-platform-android" "^2.6.0"
|
||||
"@react-native-community/cli-platform-ios" "^2.4.1"
|
||||
"@react-native-community/cli" "^3.0.0-alpha.1"
|
||||
"@react-native-community/cli-platform-android" "^3.0.0-alpha.1"
|
||||
"@react-native-community/cli-platform-ios" "^3.0.0-alpha.1"
|
||||
abort-controller "^3.0.0"
|
||||
art "^0.10.0"
|
||||
base64-js "^1.1.2"
|
||||
@@ -4873,19 +4840,20 @@ react-native@^0.60.5:
|
||||
event-target-shim "^5.0.1"
|
||||
fbjs "^1.0.0"
|
||||
fbjs-scripts "^1.1.0"
|
||||
hermesvm "^0.1.0"
|
||||
hermes-engine "^0.2.1"
|
||||
invariant "^2.2.4"
|
||||
jsc-android "245459.0.0"
|
||||
metro-babel-register "0.54.1"
|
||||
metro-react-native-babel-transformer "0.54.1"
|
||||
metro-source-map "^0.55.0"
|
||||
jsc-android "^245459.0.0"
|
||||
metro-babel-register "^0.56.0"
|
||||
metro-react-native-babel-transformer "^0.56.0"
|
||||
metro-source-map "^0.56.0"
|
||||
nullthrows "^1.1.0"
|
||||
pretty-format "^24.7.0"
|
||||
promise "^7.1.1"
|
||||
prop-types "^15.7.2"
|
||||
react-devtools-core "^3.6.1"
|
||||
react-devtools-core "^3.6.3"
|
||||
react-refresh "^0.4.0"
|
||||
regenerator-runtime "^0.13.2"
|
||||
scheduler "0.14.0"
|
||||
scheduler "0.15.0"
|
||||
stacktrace-parser "^0.1.3"
|
||||
whatwg-fetch "^3.0.0"
|
||||
|
||||
@@ -4922,37 +4890,29 @@ react-navigation@^3.0.8:
|
||||
react-navigation-stack "~1.4.0"
|
||||
react-navigation-tabs "~1.1.4"
|
||||
|
||||
react-proxy@^1.1.7:
|
||||
version "1.1.8"
|
||||
resolved "https://registry.yarnpkg.com/react-proxy/-/react-proxy-1.1.8.tgz#9dbfd9d927528c3aa9f444e4558c37830ab8c26a"
|
||||
dependencies:
|
||||
lodash "^4.6.1"
|
||||
react-deep-force-update "^1.0.0"
|
||||
react-refresh@^0.4.0:
|
||||
version "0.4.2"
|
||||
resolved "https://registry.yarnpkg.com/react-refresh/-/react-refresh-0.4.2.tgz#54a277a6caaac2803d88f1d6f13c1dcfbd81e334"
|
||||
integrity sha512-kv5QlFFSZWo7OlJFNYbxRtY66JImuP2LcrFgyJfQaf85gSP+byzG21UbDQEYjU7f//ny8rwiEkO6py2Y+fEgAQ==
|
||||
|
||||
react-test-renderer@16.5.1:
|
||||
version "16.5.1"
|
||||
resolved "https://registry.yarnpkg.com/react-test-renderer/-/react-test-renderer-16.5.1.tgz#17f020fb0cf884cadebb5240d9d9c23452f18299"
|
||||
react-test-renderer@16.9.0:
|
||||
version "16.9.0"
|
||||
resolved "https://registry.yarnpkg.com/react-test-renderer/-/react-test-renderer-16.9.0.tgz#7ed657a374af47af88f66f33a3ef99c9610c8ae9"
|
||||
integrity sha512-R62stB73qZyhrJo7wmCW9jgl/07ai+YzvouvCXIJLBkRlRqLx4j9RqcLEAfNfU3OxTGucqR2Whmn3/Aad6L3hQ==
|
||||
dependencies:
|
||||
object-assign "^4.1.1"
|
||||
prop-types "^15.6.2"
|
||||
react-is "^16.5.1"
|
||||
schedule "^0.4.0"
|
||||
react-is "^16.9.0"
|
||||
scheduler "^0.15.0"
|
||||
|
||||
react-transform-hmr@^1.0.4:
|
||||
version "1.0.4"
|
||||
resolved "https://registry.yarnpkg.com/react-transform-hmr/-/react-transform-hmr-1.0.4.tgz#e1a40bd0aaefc72e8dfd7a7cda09af85066397bb"
|
||||
dependencies:
|
||||
global "^4.3.0"
|
||||
react-proxy "^1.1.7"
|
||||
|
||||
react@16.5.1:
|
||||
version "16.5.1"
|
||||
resolved "https://registry.yarnpkg.com/react/-/react-16.5.1.tgz#8cb8e9f8cdcb4bde41c9a138bfbf907e66132372"
|
||||
react@16.9.0:
|
||||
version "16.9.0"
|
||||
resolved "https://registry.yarnpkg.com/react/-/react-16.9.0.tgz#40ba2f9af13bc1a38d75dbf2f4359a5185c4f7aa"
|
||||
integrity sha512-+7LQnFBwkiw+BobzOF6N//BdoNw0ouwmSJTEm9cglOOmsg/TMiFHZLe2sEoN5M7LgJTj9oHH0gxklfnQe66S1w==
|
||||
dependencies:
|
||||
loose-envify "^1.1.0"
|
||||
object-assign "^4.1.1"
|
||||
prop-types "^15.6.2"
|
||||
schedule "^0.4.0"
|
||||
|
||||
read-pkg-up@^1.0.1:
|
||||
version "1.0.1"
|
||||
@@ -5259,16 +5219,10 @@ sax@^1.2.1, sax@^1.2.4:
|
||||
version "1.2.4"
|
||||
resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9"
|
||||
|
||||
schedule@^0.4.0:
|
||||
version "0.4.0"
|
||||
resolved "https://registry.yarnpkg.com/schedule/-/schedule-0.4.0.tgz#fa20cfd0bfbf91c47d02272fd7096780d3170bbb"
|
||||
dependencies:
|
||||
object-assign "^4.1.1"
|
||||
|
||||
scheduler@0.14.0:
|
||||
version "0.14.0"
|
||||
resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.14.0.tgz#b392c23c9c14bfa2933d4740ad5603cc0d59ea5b"
|
||||
integrity sha512-9CgbS06Kki2f4R9FjLSITjZo5BZxPsryiRNyL3LpvrM9WxcVmhlqAOc9E+KQbeI2nqej4JIIbOsfdL51cNb4Iw==
|
||||
scheduler@0.15.0, scheduler@^0.15.0:
|
||||
version "0.15.0"
|
||||
resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.15.0.tgz#6bfcf80ff850b280fed4aeecc6513bc0b4f17f8e"
|
||||
integrity sha512-xAefmSfN6jqAa7Kuq7LIJY0bwAPG3xlCj0HMEBQk1lxYiDKZscY2xJ5U/61ZTrYbmNQbXa+gc7czPkVo11tnCg==
|
||||
dependencies:
|
||||
loose-envify "^1.1.0"
|
||||
object-assign "^4.1.1"
|
||||
@@ -5812,11 +5766,11 @@ uglify-es@^3.1.9:
|
||||
source-map "~0.6.1"
|
||||
|
||||
uglify-js@^3.1.4:
|
||||
version "3.6.0"
|
||||
resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.6.0.tgz#704681345c53a8b2079fb6cec294b05ead242ff5"
|
||||
integrity sha512-W+jrUHJr3DXKhrsS7NUVxn3zqMOFn0hL/Ei6v0anCIMoKC93TjcflTagwIHLW7SfMFfiQuktQyFVCFHGUE0+yg==
|
||||
version "3.7.3"
|
||||
resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.7.3.tgz#f918fce9182f466d5140f24bb0ff35c2d32dcc6a"
|
||||
integrity sha512-7tINm46/3puUA4hCkKYo4Xdts+JDaVC9ZPRcG8Xw9R4nhO/gZgUM3TENq8IF4Vatk8qCig4MzP/c8G4u2BkVQg==
|
||||
dependencies:
|
||||
commander "~2.20.0"
|
||||
commander "~2.20.3"
|
||||
source-map "~0.6.1"
|
||||
|
||||
ultron@1.0.x:
|
||||
|
||||
68
README.md
68
README.md
@@ -17,23 +17,26 @@ Screens support is built into [react-navigation](https://github.com/react-naviga
|
||||
|
||||
To configure react-navigation to use screens instead of plain RN Views for rendering screen views, follow the steps below:
|
||||
|
||||
1. Add this library as a depedency to your project:
|
||||
```
|
||||
1. Add this library as a dependency to your project:
|
||||
|
||||
```bash
|
||||
yarn add react-native-screens
|
||||
```
|
||||
|
||||
2. Link native modules this library ships with into your app:
|
||||
```
|
||||
2.Link native modules this library ships with into your app:
|
||||
|
||||
```bash
|
||||
react-native link react-native-screens
|
||||
```
|
||||
|
||||
> If you are not familiar with the concept of linking libraries [read on here](https://facebook.github.io/react-native/docs/linking-libraries-ios).
|
||||
> If you are not familiar with the concept of linking libraries [read on here](https://facebook.github.io/react-native/docs/linking-libraries-ios).
|
||||
|
||||
3.Enable screens support before any of your navigation screen renders. Add the following code to your main application file (e.g. App.js):
|
||||
|
||||
3. Enable screens support before any of your navigation screen renders. Add the following code to your main application file (e.g. App.js):
|
||||
```js
|
||||
import { useScreens } from 'react-native-screens';
|
||||
import { enableScreens } from 'react-native-screens';
|
||||
|
||||
useScreens();
|
||||
enableScreens();
|
||||
```
|
||||
|
||||
Note that the above code need to execute before first render of a navigation screen. You can check Example's app [App.js](https://github.com/kmagiera/react-native-screens/blob/master/Example/App.js#L16) file as a reference.
|
||||
@@ -56,12 +59,14 @@ implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.1.0-alpha02'
|
||||
Screens support is built into Expo [SDK 30](https://blog.expo.io/expo-sdk-30-0-0-is-now-available-e64d8b1db2a7) and react-navigation starting from [2.14.0](https://github.com/react-navigation/react-navigation/releases/tag/2.14.0). Make sure your app use these versions before you start.
|
||||
|
||||
1. Add screens library as dependency to your project – you can skip this step when using snack as the dependency will be imported when you import it in one of the JS files
|
||||
```
|
||||
|
||||
```bash
|
||||
yarn add react-native-screens
|
||||
```
|
||||
|
||||
2. Open your App.js file and add the following snippet somewhere near the top of the file (e.g. right after import statements):
|
||||
```
|
||||
|
||||
```js
|
||||
import { useScreens } from 'react-native-screens';
|
||||
|
||||
useScreens();
|
||||
@@ -85,8 +90,7 @@ Then replace places when you use `createStackNavigator` with `createNativeStackN
|
||||
|
||||
## Interop with other libraries
|
||||
|
||||
This library should work out of the box with all existing react-native libraries. If you expirience problems with interoperability please [report an issue](https://github.com/kmagiera/react-native-screens/issues).
|
||||
|
||||
This library should work out of the box with all existing react-native libraries. If you experience problems with interoperability please [report an issue](https://github.com/kmagiera/react-native-screens/issues).
|
||||
|
||||
## Guide for navigation library authors
|
||||
|
||||
@@ -96,12 +100,12 @@ To do that react-native-screens provides you with two components documented belo
|
||||
### `<ScreenContainer/>`
|
||||
|
||||
This component is a container for one or more `Screen` components.
|
||||
It does not accept other component types are direct children.
|
||||
The role of container is to control which of its children screens should be attached to the view hierarchy.
|
||||
It does that by monitoring `active` property of each of its children.
|
||||
It it possible to have as many `active` children as you'd like but in order for the component to be the most efficient we should keep the number of active screens to the minimum.
|
||||
In a case of stack navigator or tabs navigator we only want to have one active screen (the top most view on a stack or the selected tab).
|
||||
Then for the time of transitioning between views we may want to activate a second screen for the duration of transition, and then go back to just one active screen.
|
||||
It does not accept other component types as direct children.
|
||||
The role of the container is to control which of its children screens should be attached to the view hierarchy.
|
||||
It does that by monitoring the `active` property of each of its children.
|
||||
It is possible to have as many `active` children as you'd like but in order for the component to be the most efficient we should keep the number of active screens to a minimum.
|
||||
In a case of a stack navigator or tabs navigator we only want to have one active screen (the top most view on a stack or the selected tab).
|
||||
While transitioning between views we may want to activate a second screen for the duration of the transition, and then go back to just one active screen.
|
||||
|
||||
### `<Screen/>`
|
||||
|
||||
@@ -123,11 +127,11 @@ Otherwise the views will be attached as long as the parent container is attached
|
||||
|
||||
### `<ScreenStack>`
|
||||
|
||||
Screen stack component expects one or more `Screen` components as direct children and renders them in a platform native stack container (for iOS it is `UINavigationController` and for Android inside `Fragment` container). For `Screen` components placed as children of `ScteenStack` the `active` property is ignored and instead the screen that corresponds to the last child is rendered as active. All type of updates done to the list of children are acceptable, when the top element is exchanged the container will use platform default (unless customized) animation to transition between screens.
|
||||
Screen stack component expects one or more `Screen` components as direct children and renders them in a platform native stack container (for iOS it is `UINavigationController` and for Android inside `Fragment` container). For `Screen` components placed as children of `ScreenStack` the `active` property is ignored and instead the screen that corresponds to the last child is rendered as active. All type of updates done to the list of children are acceptable, when the top element is exchanged the container will use platform default (unless customized) animation to transition between screens.
|
||||
|
||||
`StackScreen` extends the capabilities of `Screen` component to allow additional customizations and to make it possible to handle events such as using hardware back or back gesture to dismiss the top screen. Below is the list of additional properties that can be used for `Screen` component:
|
||||
|
||||
#### `onDismiss`
|
||||
#### `onDismissed`
|
||||
|
||||
A callback that gets called when the current screen is dismissed by hardware back (on Android) or dismiss gesture (swipe back or down). The callback takes no arguments.
|
||||
|
||||
@@ -136,6 +140,7 @@ A callback that gets called when the current screen is dismissed by hardware bac
|
||||
Allows for the customization of how the given screen should appear/dissapear when pushed or popped at the top of the stack. The followin values are currently supported:
|
||||
- `"default"` – uses a platform default animation
|
||||
- `"fade"` – fades screen in or out
|
||||
- `"flip"` – flips the screen, requires `stackPresentation: "modal"` (iOS only)
|
||||
- `"none"` – the screen appears/dissapears without an animation
|
||||
|
||||
#### `stackPresentation`
|
||||
@@ -143,16 +148,15 @@ Allows for the customization of how the given screen should appear/dissapear whe
|
||||
Defines how the method that should be used to present the given screen. It is a separate property from `stackAnimation` as the presentation mode can carry additional semantic. The allowed values are:
|
||||
- `"push"` – the new screen will be pushed onto a stack which on iOS means that the default animation will be slide from the side, the animation on Android may vary depending on the OS version and theme.
|
||||
- `"modal"` – the new screen will be presented modally. In addition this allow for a nested stack to be rendered inside such screens
|
||||
- `"transparentModal"` – the new screen will be presente modally but in addition the second to last screen will remain attached to the stack container such that if the top screen is non opaque the content below can still be seen. If `"modal"` is used instead the below screen will get unmounted as soon as the transition ends.
|
||||
- `"transparentModal"` – the new screen will be presented modally but in addition the second to last screen will remain attached to the stack container such that if the top screen is non opaque the content below can still be seen. If `"modal"` is used instead the below screen will get unmounted as soon as the transition ends.
|
||||
|
||||
### `<ScreenStackHeaderConfig>`
|
||||
|
||||
The config component is expected to be rendered as a direct children of `<Screen>`. It provides an ability to configure native navigation header that gets rendered as a part of native screen stack. The component acts as a "virtual" element that is not directly rendered under `Screen`. You can use its properties to customize platform native header for the parent screen and also render react-native components that you'd like to be displayed inside the header (e.g. in the title are or on the side).
|
||||
|
||||
Along with this component properties that can be used to customize header behavior one can also use one or the below component containers to render custom react-native content in different areas of the native header:
|
||||
- `ScreenStackHeaderTitleView` – react native views rendered as children will appear on the navigation bar in the place of title. Note that title is aligned next to back button on Android while it is centered on iOS.
|
||||
- `ScreenStackHeaderCenterView` – the childern will render in the center of the native navigation bar (on iOS this has the same behavior as `ScreenStackHeaderTitleView` container)
|
||||
- `ScreenStackHeaderRightView` – the children will render on the right hand side of the navigation bar (or on the left hand side in case LTR locales are set on the user's device)
|
||||
- `ScreenStackHeaderCenterView` – the childern will render in the center of the native navigation bar.
|
||||
- `ScreenStackHeaderRightView` – the children will render on the right hand side of the navigation bar (or on the left hand side in case LTR locales are set on the user's device).
|
||||
- `ScreenStackHeaderLeftView` – the children will render on the left hand side of the navigation bar (or on the right hand side in case LTR locales are set on the user's device).
|
||||
|
||||
Below is a list of properties that can be set with `ScreenStackHeaderConfig` component:
|
||||
@@ -214,6 +218,18 @@ Allows for customizing font family to be used for back button title on iOS.
|
||||
|
||||
Allows for customizing font size to be used for back button title on iOS.
|
||||
|
||||
#### `largeTitle` (iOS only)
|
||||
|
||||
When set to `true` it makes the title display using the large title effect.
|
||||
|
||||
#### `largeTitleFontFamily` (iOS only)
|
||||
|
||||
Customize font family to be used for the large title.
|
||||
|
||||
#### `largeTitleFontSize` (iOS only)
|
||||
|
||||
Customize the size of the font to be used for the large title.
|
||||
|
||||
## Guide for native component authors
|
||||
|
||||
If you are adding a new native component to be used from the React Native app, you may want it to respond to navigation lifecycle events.
|
||||
@@ -258,5 +274,5 @@ React native screens library is licensed under [The MIT License](LICENSE).
|
||||
|
||||
This project is supported by amazing people from [Expo.io](https://expo.io) and [Software Mansion](https://swmansion.com)
|
||||
|
||||
[](https://expo.io)
|
||||
[](https://swmansion.com)
|
||||
[](https://expo.io)
|
||||
[](https://swmansion.com)
|
||||
|
||||
@@ -13,7 +13,7 @@ Pod::Spec.new do |s|
|
||||
s.license = "MIT"
|
||||
# s.license = { :type => "MIT", :file => "FILE_LICENSE" }
|
||||
s.author = { "author" => "author@domain.cn" }
|
||||
s.platform = :ios, "7.0"
|
||||
s.platforms = { :ios => "9.0", :tvos => "11.0" }
|
||||
s.source = { :git => "https://github.com/kmagiera/react-native-screens.git", :tag => "#{s.version}" }
|
||||
|
||||
s.source_files = "ios/**/*.{h,m}"
|
||||
|
||||
@@ -48,7 +48,9 @@ repositories {
|
||||
|
||||
dependencies {
|
||||
implementation 'com.facebook.react:react-native:+'
|
||||
implementation 'androidx.appcompat:appcompat:1.1.0-rc01'
|
||||
implementation 'androidx.appcompat:appcompat:1.1.0'
|
||||
implementation 'androidx.coordinatorlayout:coordinatorlayout:1.0.0'
|
||||
implementation 'com.google.android.material:material:1.0.0'
|
||||
}
|
||||
|
||||
def configureReactNativePom(def pom) {
|
||||
|
||||
@@ -1,10 +1,7 @@
|
||||
package com.swmansion.rnscreens;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.content.Context;
|
||||
import android.graphics.Paint;
|
||||
import android.os.Bundle;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.inputmethod.InputMethodManager;
|
||||
@@ -13,13 +10,13 @@ import android.widget.TextView;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.fragment.app.Fragment;
|
||||
|
||||
import com.facebook.react.bridge.GuardedRunnable;
|
||||
import com.facebook.react.bridge.ReactContext;
|
||||
import com.facebook.react.uimanager.PointerEvents;
|
||||
import com.facebook.react.uimanager.ReactPointerEventsView;
|
||||
import com.facebook.react.uimanager.UIManagerModule;
|
||||
import com.facebook.react.uimanager.events.EventDispatcher;
|
||||
|
||||
public class Screen extends ViewGroup implements ReactPointerEventsView {
|
||||
public class Screen extends ViewGroup {
|
||||
|
||||
public enum StackPresentation {
|
||||
PUSH,
|
||||
@@ -33,34 +30,6 @@ public class Screen extends ViewGroup implements ReactPointerEventsView {
|
||||
FADE
|
||||
}
|
||||
|
||||
public static class ScreenFragment extends Fragment {
|
||||
|
||||
private Screen mScreenView;
|
||||
|
||||
public ScreenFragment() {
|
||||
throw new IllegalStateException("Screen fragments should never be restored");
|
||||
}
|
||||
|
||||
@SuppressLint("ValidFragment")
|
||||
public ScreenFragment(Screen screenView) {
|
||||
super();
|
||||
mScreenView = screenView;
|
||||
}
|
||||
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater,
|
||||
@Nullable ViewGroup container,
|
||||
@Nullable Bundle savedInstanceState) {
|
||||
return mScreenView;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroy() {
|
||||
super.onDestroy();
|
||||
mScreenView.mEventDispatcher.dispatchEvent(new ScreenDismissedEvent(mScreenView.getId()));
|
||||
}
|
||||
}
|
||||
|
||||
private static OnAttachStateChangeListener sShowSoftKeyboardOnAttach = new OnAttachStateChangeListener() {
|
||||
|
||||
@Override
|
||||
@@ -77,23 +46,33 @@ public class Screen extends ViewGroup implements ReactPointerEventsView {
|
||||
}
|
||||
};
|
||||
|
||||
private final Fragment mFragment;
|
||||
private final EventDispatcher mEventDispatcher;
|
||||
private @Nullable Fragment mFragment;
|
||||
private @Nullable ScreenContainer mContainer;
|
||||
private boolean mActive;
|
||||
private boolean mTransitioning;
|
||||
private StackPresentation mStackPresentation = StackPresentation.PUSH;
|
||||
private StackAnimation mStackAnimation = StackAnimation.DEFAULT;
|
||||
private boolean mGestureEnabled = true;
|
||||
|
||||
public Screen(ReactContext context) {
|
||||
super(context);
|
||||
mFragment = new ScreenFragment(this);
|
||||
mEventDispatcher = context.getNativeModule(UIManagerModule.class).getEventDispatcher();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onLayout(boolean changed, int l, int t, int b, int r) {
|
||||
// no-op
|
||||
protected void onLayout(boolean changed, int l, int t, int r, int b) {
|
||||
if (changed) {
|
||||
final int width = r - l;
|
||||
final int height = b - t;
|
||||
final ReactContext reactContext = (ReactContext) getContext();
|
||||
reactContext.runOnNativeModulesQueueThread(
|
||||
new GuardedRunnable(reactContext) {
|
||||
@Override
|
||||
public void runGuarded() {
|
||||
reactContext.getNativeModule(UIManagerModule.class)
|
||||
.updateNodeSize(getId(), width, height);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -144,6 +123,10 @@ public class Screen extends ViewGroup implements ReactPointerEventsView {
|
||||
mStackAnimation = stackAnimation;
|
||||
}
|
||||
|
||||
public void setGestureEnabled(boolean gestureEnabled) {
|
||||
mGestureEnabled = gestureEnabled;
|
||||
}
|
||||
|
||||
public StackAnimation getStackAnimation() {
|
||||
return mStackAnimation;
|
||||
}
|
||||
@@ -152,11 +135,6 @@ public class Screen extends ViewGroup implements ReactPointerEventsView {
|
||||
return mStackPresentation;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PointerEvents getPointerEvents() {
|
||||
return mTransitioning ? PointerEvents.NONE : PointerEvents.AUTO;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setLayerType(int layerType, @Nullable Paint paint) {
|
||||
// ignore - layer type is controlled by `transitioning` prop
|
||||
@@ -166,14 +144,18 @@ public class Screen extends ViewGroup implements ReactPointerEventsView {
|
||||
mContainer = container;
|
||||
}
|
||||
|
||||
protected @Nullable ScreenContainer getContainer() {
|
||||
return mContainer;
|
||||
protected void setFragment(Fragment fragment) {
|
||||
mFragment = fragment;
|
||||
}
|
||||
|
||||
protected Fragment getFragment() {
|
||||
protected @Nullable Fragment getFragment() {
|
||||
return mFragment;
|
||||
}
|
||||
|
||||
protected @Nullable ScreenContainer getContainer() {
|
||||
return mContainer;
|
||||
}
|
||||
|
||||
public void setActive(boolean active) {
|
||||
if (active == mActive) {
|
||||
return;
|
||||
@@ -187,4 +169,8 @@ public class Screen extends ViewGroup implements ReactPointerEventsView {
|
||||
public boolean isActive() {
|
||||
return mActive;
|
||||
}
|
||||
|
||||
public boolean isGestureEnabled() {
|
||||
return mGestureEnabled;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
package com.swmansion.rnscreens;
|
||||
|
||||
import com.facebook.react.bridge.Arguments;
|
||||
import com.facebook.react.uimanager.events.Event;
|
||||
import com.facebook.react.uimanager.events.RCTEventEmitter;
|
||||
|
||||
public class ScreenAppearEvent extends Event<ScreenAppearEvent> {
|
||||
|
||||
public static final String EVENT_NAME = "topAppear";
|
||||
|
||||
public ScreenAppearEvent(int viewId) {
|
||||
super(viewId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getEventName() {
|
||||
return EVENT_NAME;
|
||||
}
|
||||
|
||||
@Override
|
||||
public short getCoalescingKey() {
|
||||
// All events for a given view can be coalesced.
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispatch(RCTEventEmitter rctEventEmitter) {
|
||||
rctEventEmitter.receiveEvent(getViewTag(), getEventName(), Arguments.createMap());
|
||||
}
|
||||
}
|
||||
@@ -2,12 +2,13 @@ package com.swmansion.rnscreens;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.ContextWrapper;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.ViewParent;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.fragment.app.FragmentActivity;
|
||||
import androidx.fragment.app.FragmentManager;
|
||||
import androidx.fragment.app.FragmentTransaction;
|
||||
|
||||
import com.facebook.react.ReactRootView;
|
||||
@@ -16,32 +17,64 @@ import com.facebook.react.modules.core.ReactChoreographer;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
public class ScreenContainer extends ViewGroup {
|
||||
public class ScreenContainer<T extends ScreenFragment> extends ViewGroup {
|
||||
|
||||
protected final ArrayList<Screen> mScreens = new ArrayList<>();
|
||||
private final Set<Screen> mActiveScreens = new HashSet<>();
|
||||
protected final ArrayList<T> mScreenFragments = new ArrayList<>();
|
||||
private final Set<ScreenFragment> mActiveScreenFragments = new HashSet<>();
|
||||
private final ArrayList<Runnable> mAfterTransitionRunnables = new ArrayList<>(1);
|
||||
|
||||
protected @Nullable FragmentManager mFragmentManager;
|
||||
private @Nullable FragmentTransaction mCurrentTransaction;
|
||||
private @Nullable FragmentTransaction mProcessingTransaction;
|
||||
private boolean mNeedUpdate;
|
||||
private boolean mIsAttached;
|
||||
private boolean mIsTransitioning;
|
||||
private boolean mLayoutEnqueued = false;
|
||||
|
||||
private ChoreographerCompat.FrameCallback mFrameCallback = new ChoreographerCompat.FrameCallback() {
|
||||
|
||||
private final ChoreographerCompat.FrameCallback mFrameCallback = new ChoreographerCompat.FrameCallback() {
|
||||
@Override
|
||||
public void doFrame(long frameTimeNanos) {
|
||||
updateIfNeeded();
|
||||
}
|
||||
};
|
||||
|
||||
private final ChoreographerCompat.FrameCallback mLayoutCallback = new ChoreographerCompat.FrameCallback() {
|
||||
@Override
|
||||
public void doFrame(long frameTimeNanos) {
|
||||
mLayoutEnqueued = false;
|
||||
measure(
|
||||
MeasureSpec.makeMeasureSpec(getWidth(), MeasureSpec.EXACTLY),
|
||||
MeasureSpec.makeMeasureSpec(getHeight(), MeasureSpec.EXACTLY));
|
||||
layout(getLeft(), getTop(), getRight(), getBottom());
|
||||
}
|
||||
};
|
||||
|
||||
public ScreenContainer(Context context) {
|
||||
super(context);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onLayout(boolean b, int i, int i1, int i2, int i3) {
|
||||
// no-op
|
||||
protected void onLayout(boolean changed, int l, int t, int r, int b) {
|
||||
for (int i = 0, size = getChildCount(); i < size; i++) {
|
||||
getChildAt(i).layout(0, 0, getWidth(), getHeight());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void requestLayout() {
|
||||
super.requestLayout();
|
||||
|
||||
if (!mLayoutEnqueued && mLayoutCallback != null) {
|
||||
mLayoutEnqueued = true;
|
||||
// we use NATIVE_ANIMATED_MODULE choreographer queue because it allows us to catch the current
|
||||
// looper loop instead of enqueueing the update in the next loop causing a one frame delay.
|
||||
ReactChoreographer.getInstance().postFrameCallback(
|
||||
ReactChoreographer.CallbackType.NATIVE_ANIMATED_MODULE,
|
||||
mLayoutCallback);
|
||||
}
|
||||
}
|
||||
|
||||
protected void markUpdated() {
|
||||
@@ -59,31 +92,82 @@ public class ScreenContainer extends ViewGroup {
|
||||
markUpdated();
|
||||
}
|
||||
|
||||
protected T adapt(Screen screen) {
|
||||
return (T) new ScreenFragment(screen);
|
||||
}
|
||||
|
||||
protected void addScreen(Screen screen, int index) {
|
||||
mScreens.add(index, screen);
|
||||
T fragment = adapt(screen);
|
||||
screen.setFragment(fragment);
|
||||
mScreenFragments.add(index, fragment);
|
||||
screen.setContainer(this);
|
||||
markUpdated();
|
||||
}
|
||||
|
||||
protected void removeScreenAt(int index) {
|
||||
mScreens.get(index).setContainer(null);
|
||||
mScreens.remove(index);
|
||||
mScreenFragments.get(index).getScreen().setContainer(null);
|
||||
mScreenFragments.remove(index);
|
||||
markUpdated();
|
||||
}
|
||||
|
||||
protected void removeAllScreens() {
|
||||
for (int i = 0, size = mScreenFragments.size(); i < size; i++) {
|
||||
mScreenFragments.get(i).getScreen().setContainer(null);
|
||||
}
|
||||
mScreenFragments.clear();
|
||||
markUpdated();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void startViewTransition(View view) {
|
||||
super.startViewTransition(view);
|
||||
mIsTransitioning = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void endViewTransition(View view) {
|
||||
super.endViewTransition(view);
|
||||
if (mIsTransitioning) {
|
||||
mIsTransitioning = false;
|
||||
notifyTransitionFinished();
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isTransitioning() {
|
||||
return mIsTransitioning || mProcessingTransaction != null;
|
||||
}
|
||||
|
||||
public void postAfterTransition(Runnable runnable) {
|
||||
mAfterTransitionRunnables.add(runnable);
|
||||
}
|
||||
|
||||
protected void notifyTransitionFinished() {
|
||||
for (int i = 0, size = mAfterTransitionRunnables.size(); i < size; i++) {
|
||||
mAfterTransitionRunnables.get(i).run();
|
||||
}
|
||||
mAfterTransitionRunnables.clear();
|
||||
}
|
||||
|
||||
protected int getScreenCount() {
|
||||
return mScreens.size();
|
||||
return mScreenFragments.size();
|
||||
}
|
||||
|
||||
protected Screen getScreenAt(int index) {
|
||||
return mScreens.get(index);
|
||||
return mScreenFragments.get(index).getScreen();
|
||||
}
|
||||
|
||||
protected final FragmentActivity findRootFragmentActivity() {
|
||||
private FragmentManager findFragmentManager() {
|
||||
ViewParent parent = this;
|
||||
while (!(parent instanceof ReactRootView) && parent.getParent() != null) {
|
||||
// We traverse view hierarchy up until we find screen parent or a root view
|
||||
while (!(parent instanceof ReactRootView || parent instanceof Screen) && parent.getParent() != null) {
|
||||
parent = parent.getParent();
|
||||
}
|
||||
// If parent is of type Screen it means we are inside a nested fragment structure.
|
||||
// Otherwise we expect to connect directly with root view and get root fragment manager
|
||||
if (parent instanceof Screen) {
|
||||
return ((Screen) parent).getFragment().getChildFragmentManager();
|
||||
}
|
||||
|
||||
// we expect top level view to be of type ReactRootView, this isn't really necessary but in order
|
||||
// to find root view we test if parent is null. This could potentially happen also when the view
|
||||
// is detached from the hierarchy and that test would not correctly indicate the root view. So
|
||||
@@ -102,12 +186,12 @@ public class ScreenContainer extends ViewGroup {
|
||||
throw new IllegalStateException(
|
||||
"In order to use RNScreens components your app's activity need to extend ReactFragmentActivity or ReactCompatActivity");
|
||||
}
|
||||
return (FragmentActivity) context;
|
||||
return ((FragmentActivity) context).getSupportFragmentManager();
|
||||
}
|
||||
|
||||
protected FragmentTransaction getOrCreateTransaction() {
|
||||
if (mCurrentTransaction == null) {
|
||||
mCurrentTransaction = findRootFragmentActivity().getSupportFragmentManager().beginTransaction();
|
||||
mCurrentTransaction = mFragmentManager.beginTransaction();
|
||||
mCurrentTransaction.setReorderingAllowed(true);
|
||||
}
|
||||
return mCurrentTransaction;
|
||||
@@ -115,36 +199,54 @@ public class ScreenContainer extends ViewGroup {
|
||||
|
||||
protected void tryCommitTransaction() {
|
||||
if (mCurrentTransaction != null) {
|
||||
final FragmentTransaction transaction = mCurrentTransaction;
|
||||
mProcessingTransaction = transaction;
|
||||
mProcessingTransaction.runOnCommit(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (mProcessingTransaction == transaction) {
|
||||
// we need to take into account that commit is initiated with some other transaction while
|
||||
// the previous one is still processing. In this case mProcessingTransaction gets overwritten
|
||||
// and we don't want to set it to null until the second transaction is finished.
|
||||
mProcessingTransaction = null;
|
||||
}
|
||||
}
|
||||
});
|
||||
mCurrentTransaction.commitAllowingStateLoss();
|
||||
mCurrentTransaction = null;
|
||||
}
|
||||
}
|
||||
|
||||
private void attachScreen(Screen screen) {
|
||||
getOrCreateTransaction().add(getId(), screen.getFragment());
|
||||
mActiveScreens.add(screen);
|
||||
private void attachScreen(ScreenFragment screenFragment) {
|
||||
getOrCreateTransaction().add(getId(), screenFragment);
|
||||
mActiveScreenFragments.add(screenFragment);
|
||||
}
|
||||
|
||||
private void moveToFront(Screen screen) {
|
||||
private void moveToFront(ScreenFragment screenFragment) {
|
||||
FragmentTransaction transaction = getOrCreateTransaction();
|
||||
Fragment fragment = screen.getFragment();
|
||||
transaction.remove(fragment);
|
||||
transaction.add(getId(), fragment);
|
||||
transaction.remove(screenFragment);
|
||||
transaction.add(getId(), screenFragment);
|
||||
}
|
||||
|
||||
private void detachScreen(Screen screen) {
|
||||
getOrCreateTransaction().remove(screen.getFragment());
|
||||
mActiveScreens.remove(screen);
|
||||
private void detachScreen(ScreenFragment screenFragment) {
|
||||
getOrCreateTransaction().remove(screenFragment);
|
||||
mActiveScreenFragments.remove(screenFragment);
|
||||
}
|
||||
|
||||
protected boolean isScreenActive(Screen screen, List<Screen> allScreens) {
|
||||
return screen.isActive();
|
||||
protected boolean isScreenActive(ScreenFragment screenFragment) {
|
||||
return screenFragment.getScreen().isActive();
|
||||
}
|
||||
|
||||
protected boolean hasScreen(ScreenFragment screenFragment) {
|
||||
return mScreenFragments.contains(screenFragment);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onAttachedToWindow() {
|
||||
super.onAttachedToWindow();
|
||||
mIsAttached = true;
|
||||
mNeedUpdate = true;
|
||||
mFragmentManager = findFragmentManager();
|
||||
updateIfNeeded();
|
||||
}
|
||||
|
||||
@@ -152,6 +254,22 @@ public class ScreenContainer extends ViewGroup {
|
||||
protected void onDetachedFromWindow() {
|
||||
super.onDetachedFromWindow();
|
||||
mIsAttached = false;
|
||||
|
||||
// fragment manager is destroyed so we can't do anything with it anymore
|
||||
mFragmentManager = null;
|
||||
// so we don't add the same screen twice after re-attach
|
||||
removeAllViews();
|
||||
mActiveScreenFragments.clear();
|
||||
// after re-attach we'll update the screen and add views again
|
||||
markUpdated();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
|
||||
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
|
||||
for (int i = 0, size = getChildCount(); i < size; i++) {
|
||||
getChildAt(i).measure(widthMeasureSpec, heightMeasureSpec);
|
||||
}
|
||||
}
|
||||
|
||||
private void updateIfNeeded() {
|
||||
@@ -164,26 +282,26 @@ public class ScreenContainer extends ViewGroup {
|
||||
|
||||
protected void onUpdate() {
|
||||
// detach screens that are no longer active
|
||||
Set<Screen> orphaned = new HashSet<>(mActiveScreens);
|
||||
for (int i = 0, size = mScreens.size(); i < size; i++) {
|
||||
Screen screen = mScreens.get(i);
|
||||
boolean isActive = isScreenActive(screen, mScreens);
|
||||
if (!isActive && mActiveScreens.contains(screen)) {
|
||||
detachScreen(screen);
|
||||
Set<ScreenFragment> orphaned = new HashSet<>(mActiveScreenFragments);
|
||||
for (int i = 0, size = mScreenFragments.size(); i < size; i++) {
|
||||
ScreenFragment screenFragment = mScreenFragments.get(i);
|
||||
boolean isActive = isScreenActive(screenFragment);
|
||||
if (!isActive && mActiveScreenFragments.contains(screenFragment)) {
|
||||
detachScreen(screenFragment);
|
||||
}
|
||||
orphaned.remove(screen);
|
||||
orphaned.remove(screenFragment);
|
||||
}
|
||||
if (!orphaned.isEmpty()) {
|
||||
Object[] orphanedAry = orphaned.toArray();
|
||||
for (int i = 0; i < orphanedAry.length; i++) {
|
||||
detachScreen((Screen) orphanedAry[i]);
|
||||
detachScreen((ScreenFragment) orphanedAry[i]);
|
||||
}
|
||||
}
|
||||
|
||||
// detect if we are "transitioning" based on the number of active screens
|
||||
int activeScreens = 0;
|
||||
for (int i = 0, size = mScreens.size(); i < size; i++) {
|
||||
if (isScreenActive(mScreens.get(i), mScreens)) {
|
||||
for (int i = 0, size = mScreenFragments.size(); i < size; i++) {
|
||||
if (isScreenActive(mScreenFragments.get(i))) {
|
||||
activeScreens += 1;
|
||||
}
|
||||
}
|
||||
@@ -191,16 +309,16 @@ public class ScreenContainer extends ViewGroup {
|
||||
|
||||
// attach newly activated screens
|
||||
boolean addedBefore = false;
|
||||
for (int i = 0, size = mScreens.size(); i < size; i++) {
|
||||
Screen screen = mScreens.get(i);
|
||||
boolean isActive = isScreenActive(screen, mScreens);
|
||||
if (isActive && !mActiveScreens.contains(screen)) {
|
||||
for (int i = 0, size = mScreenFragments.size(); i < size; i++) {
|
||||
ScreenFragment screenFragment = mScreenFragments.get(i);
|
||||
boolean isActive = isScreenActive(screenFragment);
|
||||
if (isActive && !mActiveScreenFragments.contains(screenFragment)) {
|
||||
addedBefore = true;
|
||||
attachScreen(screen);
|
||||
attachScreen(screenFragment);
|
||||
} else if (isActive && addedBefore) {
|
||||
moveToFront(screen);
|
||||
moveToFront(screenFragment);
|
||||
}
|
||||
screen.setTransitioning(transitioning);
|
||||
screenFragment.getScreen().setTransitioning(transitioning);
|
||||
}
|
||||
tryCommitTransaction();
|
||||
}
|
||||
|
||||
@@ -34,6 +34,11 @@ public class ScreenContainerViewManager extends ViewGroupManager<ScreenContainer
|
||||
parent.removeScreenAt(index);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeAllViews(ScreenContainer parent) {
|
||||
parent.removeAllScreens();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getChildCount(ScreenContainer parent) {
|
||||
return parent.getScreenCount();
|
||||
@@ -43,4 +48,9 @@ public class ScreenContainerViewManager extends ViewGroupManager<ScreenContainer
|
||||
public View getChildAt(ScreenContainer parent, int index) {
|
||||
return parent.getScreenAt(index);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean needsCustomLayoutForChildren() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,75 @@
|
||||
package com.swmansion.rnscreens;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.os.Bundle;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.fragment.app.Fragment;
|
||||
|
||||
import com.facebook.react.bridge.ReactContext;
|
||||
import com.facebook.react.uimanager.UIManagerModule;
|
||||
|
||||
public class ScreenFragment extends Fragment {
|
||||
|
||||
protected Screen mScreenView;
|
||||
|
||||
public ScreenFragment() {
|
||||
throw new IllegalStateException("Screen fragments should never be restored");
|
||||
}
|
||||
|
||||
@SuppressLint("ValidFragment")
|
||||
public ScreenFragment(Screen screenView) {
|
||||
super();
|
||||
mScreenView = screenView;
|
||||
}
|
||||
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater,
|
||||
@Nullable ViewGroup container,
|
||||
@Nullable Bundle savedInstanceState) {
|
||||
return mScreenView;
|
||||
}
|
||||
|
||||
public Screen getScreen() {
|
||||
return mScreenView;
|
||||
}
|
||||
|
||||
private void dispatchOnAppear() {
|
||||
((ReactContext) mScreenView.getContext())
|
||||
.getNativeModule(UIManagerModule.class)
|
||||
.getEventDispatcher()
|
||||
.dispatchEvent(new ScreenAppearEvent(mScreenView.getId()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate(@Nullable Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
ScreenContainer container = mScreenView.getContainer();
|
||||
if (container.isTransitioning()) {
|
||||
container.postAfterTransition(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
dispatchOnAppear();
|
||||
}
|
||||
});
|
||||
} else {
|
||||
dispatchOnAppear();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroy() {
|
||||
super.onDestroy();
|
||||
ScreenContainer container = mScreenView.getContainer();
|
||||
if (container == null || !container.hasScreen(this)) {
|
||||
// we only send dismissed even when the screen has been removed from its container
|
||||
((ReactContext) mScreenView.getContext())
|
||||
.getNativeModule(UIManagerModule.class)
|
||||
.getEventDispatcher()
|
||||
.dispatchEvent(new ScreenDismissedEvent(mScreenView.getId()));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2,48 +2,94 @@ package com.swmansion.rnscreens;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.fragment.app.FragmentManager;
|
||||
import androidx.fragment.app.FragmentTransaction;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
public class ScreenStack extends ScreenContainer {
|
||||
public class ScreenStack extends ScreenContainer<ScreenStackFragment> {
|
||||
|
||||
private final ArrayList<Screen> mStack = new ArrayList<>();
|
||||
private final Set<Screen> mDismissed = new HashSet<>();
|
||||
private static final String BACK_STACK_TAG = "RN_SCREEN_LAST";
|
||||
|
||||
private Screen mTopScreen = null;
|
||||
private final ArrayList<ScreenStackFragment> mStack = new ArrayList<>();
|
||||
private final Set<ScreenStackFragment> mDismissed = new HashSet<>();
|
||||
|
||||
private ScreenStackFragment mTopScreen = null;
|
||||
|
||||
private final FragmentManager.OnBackStackChangedListener mBackStackListener = new FragmentManager.OnBackStackChangedListener() {
|
||||
@Override
|
||||
public void onBackStackChanged() {
|
||||
if (mFragmentManager.getBackStackEntryCount() == 0) {
|
||||
// when back stack entry count hits 0 it means the user's navigated back using hw back
|
||||
// button. As the "fake" transaction we installed on the back stack does nothing we need
|
||||
// to handle back navigation on our own.
|
||||
dismiss(mTopScreen);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
private final FragmentManager.FragmentLifecycleCallbacks mLifecycleCallbacks = new FragmentManager.FragmentLifecycleCallbacks() {
|
||||
@Override
|
||||
public void onFragmentResumed(FragmentManager fm, Fragment f) {
|
||||
if (mTopScreen == f) {
|
||||
setupBackHandlerIfNeeded(mTopScreen);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
public ScreenStack(Context context) {
|
||||
super(context);
|
||||
}
|
||||
|
||||
public void dismiss(Screen screen) {
|
||||
mDismissed.add(screen);
|
||||
public void dismiss(ScreenStackFragment screenFragment) {
|
||||
mDismissed.add(screenFragment);
|
||||
onUpdate();
|
||||
}
|
||||
|
||||
public Screen getTopScreen() {
|
||||
for (int i = getScreenCount() - 1; i >= 0; i--) {
|
||||
Screen screen = getScreenAt(i);
|
||||
if (!mDismissed.contains(screen)) {
|
||||
return screen;
|
||||
}
|
||||
}
|
||||
throw new IllegalStateException("Stack is empty");
|
||||
return mTopScreen.getScreen();
|
||||
}
|
||||
|
||||
public Screen getRootScreen() {
|
||||
for (int i = 0, size = getScreenCount(); i < size; i++) {
|
||||
Screen screen = getScreenAt(i);
|
||||
if (!mDismissed.contains(screen)) {
|
||||
if (!mDismissed.contains(screen.getFragment())) {
|
||||
return screen;
|
||||
}
|
||||
}
|
||||
throw new IllegalStateException("Stack has no root screen set");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ScreenStackFragment adapt(Screen screen) {
|
||||
return new ScreenStackFragment(screen);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDetachedFromWindow() {
|
||||
if (mFragmentManager != null) {
|
||||
mFragmentManager.removeOnBackStackChangedListener(mBackStackListener);
|
||||
mFragmentManager.unregisterFragmentLifecycleCallbacks(mLifecycleCallbacks);
|
||||
if (!mFragmentManager.isStateSaved()) {
|
||||
// state save means that the container where fragment manager was installed has been unmounted.
|
||||
// This could happen as a result of dismissing nested stack. In such a case we don't need to
|
||||
// reset back stack as it'd result in a crash caused by the fact the fragment manager is no
|
||||
// longer attached.
|
||||
mFragmentManager.popBackStack(BACK_STACK_TAG, FragmentManager.POP_BACK_STACK_INCLUSIVE);
|
||||
}
|
||||
}
|
||||
super.onDetachedFromWindow();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onAttachedToWindow() {
|
||||
super.onAttachedToWindow();
|
||||
mFragmentManager.registerFragmentLifecycleCallbacks(mLifecycleCallbacks, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void removeScreenAt(int index) {
|
||||
Screen toBeRemoved = getScreenAt(index);
|
||||
@@ -51,23 +97,38 @@ public class ScreenStack extends ScreenContainer {
|
||||
super.removeScreenAt(index);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void removeAllScreens() {
|
||||
mDismissed.clear();
|
||||
super.removeAllScreens();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean hasScreen(ScreenFragment screenFragment) {
|
||||
return super.hasScreen(screenFragment) && !mDismissed.contains(screenFragment);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onUpdate() {
|
||||
// remove all screens previously on stack
|
||||
for (Screen screen : mStack) {
|
||||
if (!mScreens.contains(screen) || mDismissed.contains(screen)) {
|
||||
getOrCreateTransaction().remove(screen.getFragment());
|
||||
for (ScreenStackFragment screen : mStack) {
|
||||
if (!mScreenFragments.contains(screen) || mDismissed.contains(screen)) {
|
||||
getOrCreateTransaction().remove(screen);
|
||||
}
|
||||
}
|
||||
Screen newTop = null;
|
||||
Screen belowTop = null; // this is only set if newTop has TRANSPARENT_MODAL presentation mode
|
||||
|
||||
for (int i = mScreens.size() - 1; i >= 0; i--) {
|
||||
Screen screen = mScreens.get(i);
|
||||
// When going back from a nested stack with a single screen on it, we may hit an edge case
|
||||
// when all screens are dismissed and no screen is to be displayed on top. We need to gracefully
|
||||
// handle the case of newTop being NULL, which happens in several places below
|
||||
ScreenStackFragment newTop = null; // newTop is nullable, see the above comment ^
|
||||
ScreenStackFragment belowTop = null; // this is only set if newTop has TRANSPARENT_MODAL presentation mode
|
||||
|
||||
for (int i = mScreenFragments.size() - 1; i >= 0; i--) {
|
||||
ScreenStackFragment screen = mScreenFragments.get(i);
|
||||
if (!mDismissed.contains(screen)) {
|
||||
if (newTop == null) {
|
||||
newTop = screen;
|
||||
if (newTop.getStackPresentation() != Screen.StackPresentation.TRANSPARENT_MODAL) {
|
||||
if (newTop.getScreen().getStackPresentation() != Screen.StackPresentation.TRANSPARENT_MODAL) {
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
@@ -77,35 +138,33 @@ public class ScreenStack extends ScreenContainer {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
for (Screen screen : mScreens) {
|
||||
// add all new views that weren't on stack before
|
||||
if (!mStack.contains(screen) && !mDismissed.contains(screen)) {
|
||||
getOrCreateTransaction().add(getId(), screen.getFragment());
|
||||
}
|
||||
for (ScreenStackFragment screen : mScreenFragments) {
|
||||
// detach all screens that should not be visible
|
||||
if (screen != newTop && screen != belowTop && !mDismissed.contains(screen)) {
|
||||
getOrCreateTransaction().hide(screen.getFragment());
|
||||
getOrCreateTransaction().remove(screen);
|
||||
}
|
||||
}
|
||||
// attach "below top" screen if set
|
||||
if (belowTop != null) {
|
||||
final Screen top = newTop;
|
||||
getOrCreateTransaction().show(belowTop.getFragment()).runOnCommit(new Runnable() {
|
||||
if (belowTop != null && !belowTop.isAdded()) {
|
||||
final ScreenStackFragment top = newTop;
|
||||
getOrCreateTransaction().add(getId(), belowTop).runOnCommit(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
top.bringToFront();
|
||||
top.getScreen().bringToFront();
|
||||
}
|
||||
});
|
||||
}
|
||||
getOrCreateTransaction().show(newTop.getFragment());
|
||||
|
||||
if (newTop != null && !newTop.isAdded()) {
|
||||
getOrCreateTransaction().add(getId(), newTop);
|
||||
}
|
||||
|
||||
if (!mStack.contains(newTop)) {
|
||||
// if new top screen wasn't on stack we do "open animation" so long it is not the very first screen on stack
|
||||
if (mTopScreen != null) {
|
||||
// there was some other screen attached before
|
||||
int transition = FragmentTransaction.TRANSIT_FRAGMENT_OPEN;
|
||||
switch (mTopScreen.getStackAnimation()) {
|
||||
switch (mTopScreen.getScreen().getStackAnimation()) {
|
||||
case NONE:
|
||||
transition = FragmentTransaction.TRANSIT_NONE;
|
||||
break;
|
||||
@@ -118,7 +177,7 @@ public class ScreenStack extends ScreenContainer {
|
||||
} else if (mTopScreen != null && !mTopScreen.equals(newTop)) {
|
||||
// otherwise if we are performing top screen change we do "back animation"
|
||||
int transition = FragmentTransaction.TRANSIT_FRAGMENT_CLOSE;
|
||||
switch (mTopScreen.getStackAnimation()) {
|
||||
switch (mTopScreen.getScreen().getStackAnimation()) {
|
||||
case NONE:
|
||||
transition = FragmentTransaction.TRANSIT_NONE;
|
||||
break;
|
||||
@@ -132,8 +191,63 @@ public class ScreenStack extends ScreenContainer {
|
||||
mTopScreen = newTop;
|
||||
|
||||
mStack.clear();
|
||||
mStack.addAll(mScreens);
|
||||
mStack.addAll(mScreenFragments);
|
||||
|
||||
tryCommitTransaction();
|
||||
|
||||
if (mTopScreen != null) {
|
||||
setupBackHandlerIfNeeded(mTopScreen);
|
||||
}
|
||||
|
||||
for (ScreenStackFragment screen : mStack) {
|
||||
screen.onStackUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The below method sets up fragment manager's back stack in a way that it'd trigger our back
|
||||
* stack change listener when hw back button is clicked.
|
||||
*
|
||||
* Because back stack by default rolls back the transaction the stack entry is associated with we
|
||||
* generate a "fake" transaction that hides and shows the top fragment. As a result when back
|
||||
* stack entry is rolled back nothing happens and we are free to handle back navigation on our
|
||||
* own in `mBackStackListener`.
|
||||
*
|
||||
* We pop that "fake" transaction each time we update stack and we add a new one in case the top
|
||||
* screen is allowed to be dismised using hw back button. This way in the listener we can tell
|
||||
* if back button was pressed based on the count of the items on back stack. We expect 0 items
|
||||
* in case hw back is pressed becakse we try to keep the number of items at 1 by always resetting
|
||||
* and adding new items. In case we don't add a new item to back stack we remove listener so that
|
||||
* it does not get triggered.
|
||||
*
|
||||
* It is important that we don't install back handler when stack contains a single screen as in
|
||||
* that case we want the parent navigator or activity handler to take over.
|
||||
*/
|
||||
private void setupBackHandlerIfNeeded(ScreenStackFragment topScreen) {
|
||||
if (!mTopScreen.isResumed()) {
|
||||
// if the top fragment is not in a resumed state, adding back stack transaction would throw.
|
||||
// In such a case we skip installing back handler and use FragmentLifecycleCallbacks to get
|
||||
// notified when it gets resumed so that we can install the handler.
|
||||
return;
|
||||
}
|
||||
mFragmentManager.removeOnBackStackChangedListener(mBackStackListener);
|
||||
mFragmentManager.popBackStack(BACK_STACK_TAG, FragmentManager.POP_BACK_STACK_INCLUSIVE);
|
||||
ScreenStackFragment firstScreen = null;
|
||||
for (int i = 0, size = mStack.size(); i < size; i++) {
|
||||
ScreenStackFragment screen = mStack.get(i);
|
||||
if (!mDismissed.contains(screen)) {
|
||||
firstScreen = screen;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (topScreen != firstScreen && topScreen.isDismissable()) {
|
||||
mFragmentManager
|
||||
.beginTransaction()
|
||||
.show(topScreen)
|
||||
.addToBackStack(BACK_STACK_TAG)
|
||||
.setPrimaryNavigationFragment(topScreen)
|
||||
.commitAllowingStateLoss();
|
||||
mFragmentManager.addOnBackStackChangedListener(mBackStackListener);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,132 @@
|
||||
package com.swmansion.rnscreens;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.graphics.Color;
|
||||
import android.os.Bundle;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.LinearLayout;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.appcompat.widget.Toolbar;
|
||||
import androidx.coordinatorlayout.widget.CoordinatorLayout;
|
||||
import androidx.fragment.app.Fragment;
|
||||
|
||||
import com.facebook.react.uimanager.PixelUtil;
|
||||
import com.google.android.material.appbar.AppBarLayout;
|
||||
|
||||
public class ScreenStackFragment extends ScreenFragment {
|
||||
|
||||
private static final float TOOLBAR_ELEVATION = PixelUtil.toPixelFromDIP(4);
|
||||
|
||||
private AppBarLayout mAppBarLayout;
|
||||
private Toolbar mToolbar;
|
||||
private boolean mShadowHidden;
|
||||
private CoordinatorLayout mScreenRootView;
|
||||
|
||||
@SuppressLint("ValidFragment")
|
||||
public ScreenStackFragment(Screen screenView) {
|
||||
super(screenView);
|
||||
}
|
||||
|
||||
public void removeToolbar() {
|
||||
if (mAppBarLayout != null) {
|
||||
((CoordinatorLayout) getView()).removeView(mAppBarLayout);
|
||||
}
|
||||
}
|
||||
|
||||
public void setToolbar(Toolbar toolbar) {
|
||||
if (mAppBarLayout != null) {
|
||||
mAppBarLayout.addView(toolbar);
|
||||
}
|
||||
mToolbar = toolbar;
|
||||
AppBarLayout.LayoutParams params = new AppBarLayout.LayoutParams(
|
||||
AppBarLayout.LayoutParams.MATCH_PARENT, AppBarLayout.LayoutParams.WRAP_CONTENT);
|
||||
params.setScrollFlags(0);
|
||||
mToolbar.setLayoutParams(params);
|
||||
}
|
||||
|
||||
public void setToolbarShadowHidden(boolean hidden) {
|
||||
if (mShadowHidden != hidden) {
|
||||
mAppBarLayout.setTargetElevation(hidden ? 0 : TOOLBAR_ELEVATION);
|
||||
mShadowHidden = hidden;
|
||||
}
|
||||
}
|
||||
|
||||
public void onStackUpdate() {
|
||||
View child = mScreenView.getChildAt(0);
|
||||
if (child instanceof ScreenStackHeaderConfig) {
|
||||
((ScreenStackHeaderConfig) child).onUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
private CoordinatorLayout configureView() {
|
||||
CoordinatorLayout view = new CoordinatorLayout(getContext());
|
||||
CoordinatorLayout.LayoutParams params = new CoordinatorLayout.LayoutParams(
|
||||
LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT);
|
||||
params.setBehavior(new AppBarLayout.ScrollingViewBehavior());
|
||||
mScreenView.setLayoutParams(params);
|
||||
view.addView(mScreenView);
|
||||
|
||||
mAppBarLayout = new AppBarLayout(getContext());
|
||||
// By default AppBarLayout will have a background color set but since we cover the whole layout
|
||||
// with toolbar (that can be semi-transparent) the bar layout background color does not pay a
|
||||
// role. On top of that it breaks screens animations when alfa offscreen compositing is off
|
||||
// (which is the default)
|
||||
mAppBarLayout.setBackgroundColor(Color.TRANSPARENT);
|
||||
mAppBarLayout.setLayoutParams(new AppBarLayout.LayoutParams(
|
||||
AppBarLayout.LayoutParams.MATCH_PARENT, AppBarLayout.LayoutParams.WRAP_CONTENT));
|
||||
view.addView(mAppBarLayout);
|
||||
|
||||
if (mToolbar != null) {
|
||||
mAppBarLayout.addView(mToolbar);
|
||||
}
|
||||
|
||||
return view;
|
||||
}
|
||||
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater,
|
||||
@Nullable ViewGroup container,
|
||||
@Nullable Bundle savedInstanceState) {
|
||||
if (mScreenRootView == null) {
|
||||
mScreenRootView = configureView();
|
||||
}
|
||||
|
||||
return mScreenRootView;
|
||||
}
|
||||
|
||||
public boolean isDismissable() {
|
||||
return mScreenView.isGestureEnabled();
|
||||
}
|
||||
|
||||
public boolean canNavigateBack() {
|
||||
ScreenContainer container = mScreenView.getContainer();
|
||||
if (container instanceof ScreenStack) {
|
||||
if (((ScreenStack) container).getRootScreen() == getScreen()) {
|
||||
// this screen is the root of the container, if it is nested we can check parent container
|
||||
// if it is also a root or not
|
||||
Fragment parentFragment = getParentFragment();
|
||||
if (parentFragment instanceof ScreenStackFragment) {
|
||||
return ((ScreenStackFragment) parentFragment).canNavigateBack();
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
throw new IllegalStateException("ScreenStackFragment added into a non-stack container");
|
||||
}
|
||||
}
|
||||
|
||||
public void dismiss() {
|
||||
ScreenContainer container = mScreenView.getContainer();
|
||||
if (container instanceof ScreenStack) {
|
||||
((ScreenStack) container).dismiss(this);
|
||||
} else {
|
||||
throw new IllegalStateException("ScreenStackFragment added into a non-stack container");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -8,75 +8,49 @@ import android.view.Gravity;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.ViewParent;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.activity.OnBackPressedCallback;
|
||||
import androidx.appcompat.app.ActionBar;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
import androidx.appcompat.widget.Toolbar;
|
||||
import androidx.fragment.app.Fragment;
|
||||
|
||||
import com.facebook.react.uimanager.PixelUtil;
|
||||
import com.facebook.react.bridge.JSApplicationIllegalArgumentException;
|
||||
import com.facebook.react.views.text.ReactFontManager;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class ScreenStackHeaderConfig extends ViewGroup {
|
||||
|
||||
private static final float TOOLBAR_ELEVATION = PixelUtil.toPixelFromDIP(4);
|
||||
|
||||
private static final class ToolbarWithLayoutLoop extends Toolbar {
|
||||
|
||||
private final Runnable mLayoutRunnable = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
mLayoutEnqueued = false;
|
||||
measure(
|
||||
MeasureSpec.makeMeasureSpec(getWidth(), MeasureSpec.EXACTLY),
|
||||
MeasureSpec.makeMeasureSpec(getHeight(), MeasureSpec.EXACTLY));
|
||||
layout(getLeft(), getTop(), getRight(), getBottom());
|
||||
}
|
||||
};
|
||||
private boolean mLayoutEnqueued = false;
|
||||
|
||||
public ToolbarWithLayoutLoop(Context context) {
|
||||
super(context);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void requestLayout() {
|
||||
super.requestLayout();
|
||||
|
||||
if (!mLayoutEnqueued) {
|
||||
mLayoutEnqueued = true;
|
||||
post(mLayoutRunnable);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private final ScreenStackHeaderSubview mConfigSubviews[] = new ScreenStackHeaderSubview[3];
|
||||
private int mSubviewsCount = 0;
|
||||
private final ArrayList<ScreenStackHeaderSubview> mConfigSubviews = new ArrayList<>(3);
|
||||
private String mTitle;
|
||||
private int mTitleColor;
|
||||
private String mTitleFontFamily;
|
||||
private int mTitleFontSize;
|
||||
private float mTitleFontSize;
|
||||
private int mBackgroundColor;
|
||||
private boolean mIsHidden;
|
||||
private boolean mIsBackButtonHidden;
|
||||
private boolean mIsShadowHidden;
|
||||
private boolean mDestroyed;
|
||||
private int mTintColor;
|
||||
private int mWidth;
|
||||
private int mHeight;
|
||||
private final Toolbar mToolbar;
|
||||
|
||||
private OnBackPressedCallback mBackCallback = new OnBackPressedCallback(false) {
|
||||
@Override
|
||||
public void handleOnBackPressed() {
|
||||
getScreenStack().dismiss(getScreen());
|
||||
}
|
||||
};
|
||||
private boolean mIsAttachedToWindow = false;
|
||||
|
||||
private OnClickListener mBackClickListener = new OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
getScreenStack().dismiss(getScreen());
|
||||
ScreenStack stack = getScreenStack();
|
||||
ScreenStackFragment fragment = getScreenFragment();
|
||||
if (stack.getRootScreen() == fragment.getScreen()) {
|
||||
Fragment parentFragment = fragment.getParentFragment();
|
||||
if (parentFragment instanceof ScreenStackFragment) {
|
||||
((ScreenStackFragment) parentFragment).dismiss();
|
||||
}
|
||||
} else {
|
||||
fragment.dismiss();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -84,42 +58,39 @@ public class ScreenStackHeaderConfig extends ViewGroup {
|
||||
super(context);
|
||||
setVisibility(View.GONE);
|
||||
|
||||
mToolbar = new ToolbarWithLayoutLoop(context);
|
||||
mToolbar = new Toolbar(context);
|
||||
// reset content insets to be 0 to allow react position custom navbar views. Note that this does
|
||||
// not affect platform native back button as toolbar does not apply left inset when navigation
|
||||
// button is specified
|
||||
mToolbar.setContentInsetsAbsolute(0, 0);
|
||||
|
||||
// set primary color as background by default
|
||||
TypedValue tv = new TypedValue();
|
||||
if (context.getTheme().resolveAttribute(android.R.attr.colorPrimary, tv, true)) {
|
||||
mToolbar.setBackgroundColor(tv.data);
|
||||
}
|
||||
|
||||
mWidth = 0;
|
||||
mHeight = 0;
|
||||
|
||||
if (context.getTheme().resolveAttribute(android.R.attr.actionBarSize, tv, true)) {
|
||||
mHeight = TypedValue.complexToDimensionPixelSize(tv.data, getResources().getDisplayMetrics());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void updateToolbarLayout() {
|
||||
mToolbar.measure(
|
||||
View.MeasureSpec.makeMeasureSpec(mWidth, View.MeasureSpec.EXACTLY),
|
||||
View.MeasureSpec.makeMeasureSpec(mHeight, View.MeasureSpec.EXACTLY));
|
||||
mToolbar.layout(0, 0, mWidth, mHeight);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onLayout(boolean changed, int l, int t, int r, int b) {
|
||||
if (mWidth != (r - l)) {
|
||||
mWidth = (r - l);
|
||||
updateToolbarLayout();
|
||||
}
|
||||
// no-op
|
||||
}
|
||||
|
||||
public void destroy() {
|
||||
mDestroyed = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onAttachedToWindow() {
|
||||
super.onAttachedToWindow();
|
||||
update();
|
||||
mIsAttachedToWindow = true;
|
||||
onUpdate();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDetachedFromWindow() {
|
||||
super.onDetachedFromWindow();
|
||||
mIsAttachedToWindow = false;
|
||||
}
|
||||
|
||||
private Screen getScreen() {
|
||||
@@ -141,45 +112,43 @@ public class ScreenStackHeaderConfig extends ViewGroup {
|
||||
return null;
|
||||
}
|
||||
|
||||
private Fragment getScreenFragment() {
|
||||
private ScreenStackFragment getScreenFragment() {
|
||||
ViewParent screen = getParent();
|
||||
if (screen instanceof Screen) {
|
||||
return ((Screen) screen).getFragment();
|
||||
Fragment fragment = ((Screen) screen).getFragment();
|
||||
if (fragment instanceof ScreenStackFragment) {
|
||||
return (ScreenStackFragment) fragment;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private void installBackCallback() {
|
||||
mBackCallback.remove();
|
||||
Fragment fragment = getScreenFragment();
|
||||
fragment.requireActivity().getOnBackPressedDispatcher().addCallback(fragment, mBackCallback);
|
||||
}
|
||||
|
||||
private void update() {
|
||||
public void onUpdate() {
|
||||
Screen parent = (Screen) getParent();
|
||||
final ScreenStack stack = getScreenStack();
|
||||
boolean isTop = stack == null ? true : stack.getTopScreen() == parent;
|
||||
|
||||
if (!mIsAttachedToWindow || !isTop || mDestroyed) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (mIsHidden) {
|
||||
if (mToolbar.getParent() != null) {
|
||||
parent.removeView(mToolbar);
|
||||
getScreenFragment().removeToolbar();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (mToolbar.getParent() == null) {
|
||||
parent.addView(mToolbar);
|
||||
getScreenFragment().setToolbar(mToolbar);
|
||||
}
|
||||
|
||||
AppCompatActivity activity = (AppCompatActivity) parent.getFragment().getActivity();
|
||||
AppCompatActivity activity = (AppCompatActivity) getScreenFragment().getActivity();
|
||||
activity.setSupportActionBar(mToolbar);
|
||||
ActionBar actionBar = activity.getSupportActionBar();
|
||||
|
||||
// hide back button
|
||||
final ScreenStack stack = getScreenStack();
|
||||
boolean isRoot = stack == null ? true : stack.getRootScreen() == parent;
|
||||
actionBar.setDisplayHomeAsUpEnabled(isRoot ? false : !mIsBackButtonHidden);
|
||||
if (!isRoot) {
|
||||
installBackCallback();
|
||||
}
|
||||
mBackCallback.setEnabled(!isRoot);
|
||||
actionBar.setDisplayHomeAsUpEnabled(getScreenFragment().canNavigateBack() ? !mIsBackButtonHidden : false);
|
||||
|
||||
// when setSupportActionBar is called a toolbar wrapper gets initialized that overwrites
|
||||
// navigation click listener. The default behavior set in the wrapper is to call into
|
||||
@@ -188,7 +157,7 @@ public class ScreenStackHeaderConfig extends ViewGroup {
|
||||
|
||||
|
||||
// shadow
|
||||
actionBar.setElevation(mIsShadowHidden ? 0 : TOOLBAR_ELEVATION);
|
||||
getScreenFragment().setToolbarShadowHidden(mIsShadowHidden);
|
||||
|
||||
// title
|
||||
actionBar.setTitle(mTitle);
|
||||
@@ -220,10 +189,26 @@ public class ScreenStackHeaderConfig extends ViewGroup {
|
||||
}
|
||||
|
||||
// subviews
|
||||
for (int i = 0; i < mSubviewsCount; i++) {
|
||||
ScreenStackHeaderSubview view = mConfigSubviews[i];
|
||||
for (int i = mToolbar.getChildCount() - 1; i >= 0; i--) {
|
||||
if (mToolbar.getChildAt(i) instanceof ScreenStackHeaderSubview) {
|
||||
mToolbar.removeViewAt(i);
|
||||
}
|
||||
}
|
||||
for (int i = 0, size = mConfigSubviews.size(); i < size; i++) {
|
||||
ScreenStackHeaderSubview view = mConfigSubviews.get(i);
|
||||
ScreenStackHeaderSubview.Type type = view.getType();
|
||||
|
||||
if (type == ScreenStackHeaderSubview.Type.BACK) {
|
||||
// we special case BACK button header config type as we don't add it as a view into toolbar
|
||||
// but instead just copy the drawable from imageview that's added as a first child to it.
|
||||
View firstChild = view.getChildAt(0);
|
||||
if (!(firstChild instanceof ImageView)) {
|
||||
throw new JSApplicationIllegalArgumentException("Back button header config view should have Image as first child");
|
||||
}
|
||||
actionBar.setHomeAsUpIndicator(((ImageView) firstChild).getDrawable());
|
||||
continue;
|
||||
}
|
||||
|
||||
Toolbar.LayoutParams params =
|
||||
new Toolbar.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT);
|
||||
|
||||
@@ -238,41 +223,45 @@ public class ScreenStackHeaderConfig extends ViewGroup {
|
||||
case RIGHT:
|
||||
params.gravity = Gravity.RIGHT;
|
||||
break;
|
||||
case TITLE:
|
||||
params.width = LayoutParams.MATCH_PARENT;
|
||||
mToolbar.setTitle(null);
|
||||
case CENTER:
|
||||
params.width = LayoutParams.MATCH_PARENT;
|
||||
params.gravity = Gravity.CENTER_HORIZONTAL;
|
||||
mToolbar.setTitle(null);
|
||||
break;
|
||||
}
|
||||
|
||||
view.setLayoutParams(params);
|
||||
if (view.getParent() == null) {
|
||||
mToolbar.addView(view);
|
||||
}
|
||||
mToolbar.addView(view);
|
||||
}
|
||||
}
|
||||
|
||||
private void maybeUpdate() {
|
||||
if (getParent() != null && !mDestroyed) {
|
||||
onUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
public ScreenStackHeaderSubview getConfigSubview(int index) {
|
||||
return mConfigSubviews[index];
|
||||
return mConfigSubviews.get(index);
|
||||
}
|
||||
|
||||
public int getConfigSubviewsCount() {
|
||||
return mSubviewsCount;
|
||||
return mConfigSubviews.size();
|
||||
}
|
||||
|
||||
public void removeConfigSubview(int index) {
|
||||
if (mConfigSubviews[index] != null) {
|
||||
mSubviewsCount--;
|
||||
}
|
||||
mConfigSubviews[index] = null;
|
||||
mConfigSubviews.remove(index);
|
||||
maybeUpdate();
|
||||
}
|
||||
|
||||
public void removeAllConfigSubviews() {
|
||||
mConfigSubviews.clear();
|
||||
maybeUpdate();
|
||||
}
|
||||
|
||||
public void addConfigSubview(ScreenStackHeaderSubview child, int index) {
|
||||
if (mConfigSubviews[index] == null) {
|
||||
mSubviewsCount++;
|
||||
}
|
||||
mConfigSubviews[index] = child;
|
||||
mConfigSubviews.add(index, child);
|
||||
maybeUpdate();
|
||||
}
|
||||
|
||||
private TextView getTitleTextView() {
|
||||
@@ -296,7 +285,7 @@ public class ScreenStackHeaderConfig extends ViewGroup {
|
||||
mTitleFontFamily = titleFontFamily;
|
||||
}
|
||||
|
||||
public void setTitleFontSize(int titleFontSize) {
|
||||
public void setTitleFontSize(float titleFontSize) {
|
||||
mTitleFontSize = titleFontSize;
|
||||
}
|
||||
|
||||
|
||||
@@ -4,11 +4,12 @@ import android.view.View;
|
||||
|
||||
import com.facebook.react.bridge.JSApplicationCausedNativeException;
|
||||
import com.facebook.react.module.annotations.ReactModule;
|
||||
import com.facebook.react.uimanager.PixelUtil;
|
||||
import com.facebook.react.uimanager.ThemedReactContext;
|
||||
import com.facebook.react.uimanager.ViewGroupManager;
|
||||
import com.facebook.react.uimanager.annotations.ReactProp;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
@ReactModule(name = ScreenStackHeaderConfigViewManager.REACT_CLASS)
|
||||
public class ScreenStackHeaderConfigViewManager extends ViewGroupManager<ScreenStackHeaderConfig> {
|
||||
|
||||
@@ -32,6 +33,16 @@ public class ScreenStackHeaderConfigViewManager extends ViewGroupManager<ScreenS
|
||||
parent.addConfigSubview((ScreenStackHeaderSubview) child, index);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDropViewInstance(@Nonnull ScreenStackHeaderConfig view) {
|
||||
view.destroy();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeAllViews(ScreenStackHeaderConfig parent) {
|
||||
parent.removeAllConfigSubviews();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeViewAt(ScreenStackHeaderConfig parent, int index) {
|
||||
parent.removeConfigSubview(index);
|
||||
@@ -52,6 +63,12 @@ public class ScreenStackHeaderConfigViewManager extends ViewGroupManager<ScreenS
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onAfterUpdateTransaction(ScreenStackHeaderConfig parent) {
|
||||
super.onAfterUpdateTransaction(parent);
|
||||
parent.onUpdate();
|
||||
}
|
||||
|
||||
@ReactProp(name = "title")
|
||||
public void setTitle(ScreenStackHeaderConfig config, String title) {
|
||||
config.setTitle(title);
|
||||
@@ -63,8 +80,8 @@ public class ScreenStackHeaderConfigViewManager extends ViewGroupManager<ScreenS
|
||||
}
|
||||
|
||||
@ReactProp(name = "titleFontSize")
|
||||
public void setTitleFontSize(ScreenStackHeaderConfig config, double titleFontSizeSP) {
|
||||
config.setTitleFontSize((int) PixelUtil.toPixelFromSP(titleFontSizeSP));
|
||||
public void setTitleFontSize(ScreenStackHeaderConfig config, float titleFontSize) {
|
||||
config.setTitleFontSize(titleFontSize);
|
||||
}
|
||||
|
||||
@ReactProp(name = "titleColor", customType = "Color")
|
||||
|
||||
@@ -9,20 +9,14 @@ import com.facebook.react.views.view.ReactViewGroup;
|
||||
|
||||
public class ScreenStackHeaderSubview extends ReactViewGroup {
|
||||
|
||||
public class Measurements {
|
||||
public int width;
|
||||
public int height;
|
||||
}
|
||||
|
||||
public enum Type {
|
||||
LEFT,
|
||||
CENTER,
|
||||
TITLE,
|
||||
RIGHT
|
||||
RIGHT,
|
||||
BACK
|
||||
}
|
||||
|
||||
private int mReactWidth, mReactHeight;
|
||||
private final UIManagerModule mUIManager;
|
||||
|
||||
@Override
|
||||
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
|
||||
@@ -42,29 +36,13 @@ public class ScreenStackHeaderSubview extends ReactViewGroup {
|
||||
|
||||
@Override
|
||||
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
|
||||
if (changed && (mType == Type.CENTER || mType == Type.TITLE)) {
|
||||
Measurements measurements = new Measurements();
|
||||
measurements.width = right - left;
|
||||
if (mType == Type.CENTER) {
|
||||
// if we want the view to be centered we need to account for the fact that right and left
|
||||
// paddings may not be equal.
|
||||
View parent = (View) getParent();
|
||||
int parentWidth = parent.getWidth();
|
||||
int rightPadding = parentWidth - right;
|
||||
int leftPadding = left;
|
||||
measurements.width = Math.max(0, parentWidth - 2 * Math.max(rightPadding, leftPadding));
|
||||
}
|
||||
measurements.height = bottom - top;
|
||||
mUIManager.setViewLocalData(getId(), measurements);
|
||||
}
|
||||
super.onLayout(changed, left, top, right, bottom);
|
||||
// no-op
|
||||
}
|
||||
|
||||
private Type mType = Type.RIGHT;
|
||||
|
||||
public ScreenStackHeaderSubview(ReactContext context) {
|
||||
super(context);
|
||||
mUIManager = context.getNativeModule(UIManagerModule.class);
|
||||
}
|
||||
|
||||
public void setType(Type type) {
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
package com.swmansion.rnscreens;
|
||||
|
||||
import com.facebook.react.bridge.ReactApplicationContext;
|
||||
import com.facebook.react.module.annotations.ReactModule;
|
||||
import com.facebook.react.uimanager.LayoutShadowNode;
|
||||
import com.facebook.react.uimanager.ThemedReactContext;
|
||||
import com.facebook.react.uimanager.annotations.ReactProp;
|
||||
import com.facebook.react.views.view.ReactViewGroup;
|
||||
@@ -11,15 +9,6 @@ import com.facebook.react.views.view.ReactViewManager;
|
||||
@ReactModule(name = ScreenStackHeaderSubviewManager.REACT_CLASS)
|
||||
public class ScreenStackHeaderSubviewManager extends ReactViewManager {
|
||||
|
||||
private static class SubviewShadowNode extends LayoutShadowNode {
|
||||
@Override
|
||||
public void setLocalData(Object data) {
|
||||
ScreenStackHeaderSubview.Measurements measurements = (ScreenStackHeaderSubview.Measurements) data;
|
||||
setStyleWidth(measurements.width);
|
||||
setStyleHeight(measurements.height);
|
||||
}
|
||||
}
|
||||
|
||||
protected static final String REACT_CLASS = "RNSScreenStackHeaderSubview";
|
||||
|
||||
@Override
|
||||
@@ -32,21 +21,16 @@ public class ScreenStackHeaderSubviewManager extends ReactViewManager {
|
||||
return new ScreenStackHeaderSubview(context);
|
||||
}
|
||||
|
||||
@Override
|
||||
public LayoutShadowNode createShadowNodeInstance(ReactApplicationContext context) {
|
||||
return new SubviewShadowNode();
|
||||
}
|
||||
|
||||
@ReactProp(name = "type")
|
||||
public void setType(ScreenStackHeaderSubview view, String type) {
|
||||
if ("left".equals(type)) {
|
||||
view.setType(ScreenStackHeaderSubview.Type.LEFT);
|
||||
} else if ("center".equals(type)) {
|
||||
view.setType(ScreenStackHeaderSubview.Type.CENTER);
|
||||
} else if ("title".equals(type)) {
|
||||
view.setType(ScreenStackHeaderSubview.Type.TITLE);
|
||||
} else if ("right".equals(type)) {
|
||||
view.setType(ScreenStackHeaderSubview.Type.RIGHT);
|
||||
} else if ("back".equals(type)) {
|
||||
view.setType(ScreenStackHeaderSubview.Type.BACK);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -59,4 +59,9 @@ public class ScreenStackViewManager extends ViewGroupManager<ScreenStack> {
|
||||
public View getChildAt(ScreenStack parent, int index) {
|
||||
return parent.getScreenAt(index);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean needsCustomLayoutForChildren() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -35,9 +35,11 @@ public class ScreenViewManager extends ViewGroupManager<Screen> {
|
||||
public void setStackPresentation(Screen view, String presentation) {
|
||||
if ("push".equals(presentation)) {
|
||||
view.setStackPresentation(Screen.StackPresentation.PUSH);
|
||||
} else if ("modal".equals(presentation)) {
|
||||
} else if ("modal".equals(presentation) || "containedModal".equals(presentation)) {
|
||||
// at the moment Android implementation does not handle contained vs regular modals
|
||||
view.setStackPresentation(Screen.StackPresentation.MODAL);
|
||||
} else if ("transparentModal".equals(presentation)) {
|
||||
} else if ("transparentModal".equals(presentation) || "containedTransparentModal".equals((presentation))) {
|
||||
// at the moment Android implementation does not handle contained vs regular modals
|
||||
view.setStackPresentation(Screen.StackPresentation.TRANSPARENT_MODAL);
|
||||
} else {
|
||||
throw new JSApplicationIllegalArgumentException("Unknown presentation type " + presentation);
|
||||
@@ -55,11 +57,18 @@ public class ScreenViewManager extends ViewGroupManager<Screen> {
|
||||
}
|
||||
}
|
||||
|
||||
@ReactProp(name = "gestureEnabled", defaultBoolean = true)
|
||||
public void setGestureEnabled(Screen view, boolean gestureEnabled) {
|
||||
view.setGestureEnabled(gestureEnabled);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public Map getExportedCustomDirectEventTypeConstants() {
|
||||
return MapBuilder.of(
|
||||
ScreenDismissedEvent.EVENT_NAME,
|
||||
MapBuilder.of("registrationName", "onDismissed"));
|
||||
MapBuilder.of("registrationName", "onDismissed"),
|
||||
ScreenAppearEvent.EVENT_NAME,
|
||||
MapBuilder.of("registrationName", "onAppear"));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,35 +4,44 @@ import {
|
||||
StackRouter,
|
||||
SceneView,
|
||||
StackActions,
|
||||
NavigationActions,
|
||||
createNavigator,
|
||||
} from '@react-navigation/core';
|
||||
import { createKeyboardAwareNavigator } from '@react-navigation/native';
|
||||
import { ScenesReducer, HeaderBackButton } from 'react-navigation-stack';
|
||||
import { HeaderBackButton } from 'react-navigation-stack';
|
||||
import {
|
||||
ScreenStack,
|
||||
Screen,
|
||||
ScreenStackHeaderConfig,
|
||||
ScreenStackHeaderBackButtonImage,
|
||||
ScreenStackHeaderLeftView,
|
||||
ScreenStackHeaderRightView,
|
||||
ScreenStackHeaderTitleView,
|
||||
ScreenStackHeaderCenterView,
|
||||
} from 'react-native-screens';
|
||||
|
||||
function renderComponentOrThunk(componentOrThunk, props) {
|
||||
if (typeof componentOrThunk === 'function') {
|
||||
return componentOrThunk(props);
|
||||
}
|
||||
return componentOrThunk;
|
||||
}
|
||||
|
||||
class StackView extends React.Component {
|
||||
_removeScene = scene => {
|
||||
const { navigation } = this.props;
|
||||
navigation.dispatch(
|
||||
NavigationActions.back({
|
||||
key: scene.route.key,
|
||||
immediate: true,
|
||||
})
|
||||
);
|
||||
navigation.dispatch(StackActions.completeTransition());
|
||||
_removeScene = route => {
|
||||
this.props.navigation.dispatch(StackActions.pop({ key: route.key }));
|
||||
};
|
||||
|
||||
_renderHeaderConfig = (scene, scenes) => {
|
||||
_onSceneFocus = (route, descriptor) => {
|
||||
descriptor.options &&
|
||||
descriptor.options.onAppear &&
|
||||
descriptor.options.onAppear();
|
||||
this.props.navigation.dispatch(
|
||||
StackActions.completeTransition({ toChildKey: route.key })
|
||||
);
|
||||
};
|
||||
|
||||
_renderHeaderConfig = (index, route, descriptor) => {
|
||||
const { navigationConfig } = this.props;
|
||||
const { options } = scene.descriptor;
|
||||
const { options } = descriptor;
|
||||
const { headerMode } = navigationConfig;
|
||||
|
||||
const {
|
||||
@@ -41,25 +50,38 @@ class StackView extends React.Component {
|
||||
headerTitleStyle,
|
||||
headerBackTitleStyle,
|
||||
headerBackTitle,
|
||||
headerBackTitleVisible,
|
||||
headerTintColor,
|
||||
gestureEnabled,
|
||||
largeTitle,
|
||||
headerLargeTitleStyle,
|
||||
translucent,
|
||||
hideShadow,
|
||||
} = options;
|
||||
|
||||
const scene = {
|
||||
index,
|
||||
key: route.key,
|
||||
route,
|
||||
descriptor,
|
||||
};
|
||||
|
||||
const headerOptions = {
|
||||
translucent: translucent === undefined ? false : translucent,
|
||||
title,
|
||||
titleFontFamily: headerTitleStyle && headerTitleStyle.fontFamily,
|
||||
titleColor: headerTintColor,
|
||||
titleFontSize: headerTitleStyle && headerTitleStyle.fontSize,
|
||||
backTitle: headerBackTitle,
|
||||
backTitle: headerBackTitleVisible === false ? '' : headerBackTitle,
|
||||
backTitleFontFamily:
|
||||
headerBackTitleStyle && headerBackTitleStyle.fontFamily,
|
||||
backTitleFontSize: headerBackTitleStyle && headerBackTitleStyle.fontSize,
|
||||
color: headerTintColor,
|
||||
gestureEnabled: gestureEnabled === undefined ? true : gestureEnabled,
|
||||
largeTitle,
|
||||
largeTitleFontFamily:
|
||||
headerLargeTitleStyle && headerLargeTitleStyle.fontFamily,
|
||||
largeTitleFontSize:
|
||||
headerLargeTitleStyle && headerLargeTitleStyle.fontSize,
|
||||
hideShadow,
|
||||
};
|
||||
|
||||
const hasHeader = headerMode !== 'none' && options.header !== null;
|
||||
@@ -73,17 +95,26 @@ class StackView extends React.Component {
|
||||
|
||||
const children = [];
|
||||
|
||||
if (options.backButtonImage) {
|
||||
children.push(
|
||||
<ScreenStackHeaderBackButtonImage
|
||||
key="backImage"
|
||||
source={options.backButtonImage}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
if (options.headerLeft !== undefined) {
|
||||
children.push(
|
||||
<ScreenStackHeaderLeftView key="left">
|
||||
{options.headerLeft({ scene })}
|
||||
{renderComponentOrThunk(options.headerLeft, { scene })}
|
||||
</ScreenStackHeaderLeftView>
|
||||
);
|
||||
} else if (options.headerBackImage !== undefined) {
|
||||
const goBack = () => {
|
||||
// Go back on next tick because button ripple effect needs to happen on Android
|
||||
requestAnimationFrame(() => {
|
||||
scene.descriptor.navigation.goBack(scene.descriptor.key);
|
||||
descriptor.navigation.goBack(descriptor.key);
|
||||
});
|
||||
};
|
||||
|
||||
@@ -106,17 +137,21 @@ class StackView extends React.Component {
|
||||
}
|
||||
|
||||
if (options.headerTitle) {
|
||||
children.push(
|
||||
<ScreenStackHeaderTitleView key="title">
|
||||
{options.headerTitle({ scene })}
|
||||
</ScreenStackHeaderTitleView>
|
||||
);
|
||||
if (title === undefined && typeof options.headerTitle === 'string') {
|
||||
headerOptions.title = options.headerTitle;
|
||||
} else {
|
||||
children.push(
|
||||
<ScreenStackHeaderCenterView key="center">
|
||||
{renderComponentOrThunk(options.headerTitle, { scene })}
|
||||
</ScreenStackHeaderCenterView>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if (options.headerRight) {
|
||||
children.push(
|
||||
<ScreenStackHeaderRightView key="right">
|
||||
{options.headerRight({ scene })}
|
||||
{renderComponentOrThunk(options.headerRight, { scene })}
|
||||
</ScreenStackHeaderRightView>
|
||||
);
|
||||
}
|
||||
@@ -128,24 +163,40 @@ class StackView extends React.Component {
|
||||
return <ScreenStackHeaderConfig {...headerOptions} />;
|
||||
};
|
||||
|
||||
_renderScene = (scene, scenes) => {
|
||||
const { navigation, getComponent } = scene.descriptor;
|
||||
_renderScene = (index, route, descriptor) => {
|
||||
const { navigation, getComponent, options } = descriptor;
|
||||
const { mode, transparentCard } = this.props.navigationConfig;
|
||||
const SceneComponent = getComponent();
|
||||
|
||||
let stackPresentation = 'push';
|
||||
if (mode === 'modal') {
|
||||
stackPresentation = transparentCard ? 'transparentModal' : 'modal';
|
||||
if (mode === 'modal' || mode === 'containedModal') {
|
||||
stackPresentation = mode;
|
||||
if (transparentCard || options.cardTransparent) {
|
||||
stackPresentation =
|
||||
mode === 'containedModal'
|
||||
? 'containedTransparentModal'
|
||||
: 'transparentModal';
|
||||
}
|
||||
}
|
||||
|
||||
let stackAnimation = options.stackAnimation;
|
||||
if (options.animationEnabled === false) {
|
||||
stackAnimation = 'none';
|
||||
}
|
||||
|
||||
const { screenProps } = this.props;
|
||||
return (
|
||||
<Screen
|
||||
key={`screen_${scene.key}`}
|
||||
style={StyleSheet.absoluteFill}
|
||||
key={`screen_${route.key}`}
|
||||
style={options.cardStyle}
|
||||
stackAnimation={stackAnimation}
|
||||
stackPresentation={stackPresentation}
|
||||
onDismissed={() => this._removeScene(scene)}>
|
||||
{this._renderHeaderConfig(scene, scenes)}
|
||||
gestureEnabled={
|
||||
options.gestureEnabled === undefined ? true : options.gestureEnabled
|
||||
}
|
||||
onAppear={() => this._onSceneFocus(route, descriptor)}
|
||||
onDismissed={() => this._removeScene(route)}>
|
||||
{this._renderHeaderConfig(index, route, descriptor)}
|
||||
<SceneView
|
||||
screenProps={screenProps}
|
||||
navigation={navigation}
|
||||
@@ -156,16 +207,13 @@ class StackView extends React.Component {
|
||||
};
|
||||
|
||||
render() {
|
||||
const scenes = ScenesReducer(
|
||||
[],
|
||||
this.props.navigation.state,
|
||||
null,
|
||||
this.props.descriptors
|
||||
);
|
||||
const { navigation, descriptors } = this.props;
|
||||
|
||||
return (
|
||||
<ScreenStack style={styles.scenes}>
|
||||
{scenes.map(scene => this._renderScene(scene, scenes))}
|
||||
{navigation.state.routes.map((route, i) =>
|
||||
this._renderScene(i, route, descriptors[route.key])
|
||||
)}
|
||||
</ScreenStack>
|
||||
);
|
||||
}
|
||||
@@ -177,7 +225,6 @@ const styles = StyleSheet.create({
|
||||
|
||||
function createStackNavigator(routeConfigMap, stackConfig = {}) {
|
||||
const router = StackRouter(routeConfigMap, stackConfig);
|
||||
|
||||
// Create a navigator with StackView as the view
|
||||
let Navigator = createNavigator(StackView, router, stackConfig);
|
||||
// if (!stackConfig.disableKeyboardHandling) {
|
||||
|
||||
@@ -9,12 +9,15 @@ typedef NS_ENUM(NSInteger, RNSScreenStackPresentation) {
|
||||
RNSScreenStackPresentationPush,
|
||||
RNSScreenStackPresentationModal,
|
||||
RNSScreenStackPresentationTransparentModal,
|
||||
RNSScreenStackPresentationContainedModal,
|
||||
RNSScreenStackPresentationContainedTransparentModal
|
||||
};
|
||||
|
||||
typedef NS_ENUM(NSInteger, RNSScreenStackAnimation) {
|
||||
RNSScreenStackAnimationDefault,
|
||||
RNSScreenStackAnimationNone,
|
||||
RNSScreenStackAnimationFade,
|
||||
RNSScreenStackAnimationFlip,
|
||||
};
|
||||
|
||||
@interface RCTConvert (RNSScreen)
|
||||
@@ -24,15 +27,24 @@ typedef NS_ENUM(NSInteger, RNSScreenStackAnimation) {
|
||||
|
||||
@end
|
||||
|
||||
@interface RNSScreen : UIViewController
|
||||
|
||||
- (instancetype)initWithView:(UIView *)view;
|
||||
- (void)notifyFinishTransitioning;
|
||||
|
||||
@end
|
||||
|
||||
@interface RNSScreenManager : RCTViewManager
|
||||
@end
|
||||
|
||||
@interface RNSScreenView : RCTView <RCTInvalidating>
|
||||
@interface RNSScreenView : RCTView
|
||||
|
||||
@property (nonatomic, copy) RCTDirectEventBlock onAppear;
|
||||
@property (nonatomic, copy) RCTDirectEventBlock onDismissed;
|
||||
@property (weak, nonatomic) UIView<RNSScreenContainerDelegate> *reactSuperview;
|
||||
@property (nonatomic, retain) UIViewController *controller;
|
||||
@property (nonatomic) BOOL active;
|
||||
@property (nonatomic) BOOL gestureEnabled;
|
||||
@property (nonatomic) RNSScreenStackAnimation stackAnimation;
|
||||
@property (nonatomic) RNSScreenStackPresentation stackPresentation;
|
||||
|
||||
|
||||
208
ios/RNSScreen.m
208
ios/RNSScreen.m
@@ -2,48 +2,19 @@
|
||||
|
||||
#import "RNSScreen.h"
|
||||
#import "RNSScreenContainer.h"
|
||||
#import "RNSScreenStackHeaderConfig.h"
|
||||
|
||||
#import <React/RCTUIManager.h>
|
||||
#import <React/RCTShadowView.h>
|
||||
#import <React/RCTTouchHandler.h>
|
||||
|
||||
@interface RNSScreenFrameData : NSObject
|
||||
@property (nonatomic, readonly) CGFloat rightInset;
|
||||
@property (nonatomic, readonly) CGFloat topInset;
|
||||
@property (nonatomic, readonly) CGFloat bottomInset;
|
||||
@property (nonatomic, readonly) CGFloat leftInset;
|
||||
@property (nonatomic, readonly) CGFloat navbarOffset;
|
||||
|
||||
- (instancetype)initWithInsets:(UIEdgeInsets)insets;
|
||||
|
||||
@end
|
||||
|
||||
@implementation RNSScreenFrameData
|
||||
|
||||
- (instancetype)initWithInsets:(UIEdgeInsets)insets andNavbarOffset:(CGFloat)navbarOffset
|
||||
{
|
||||
if (self = [super init]) {
|
||||
_topInset = insets.top;
|
||||
_bottomInset = insets.bottom;
|
||||
_leftInset = insets.left;
|
||||
_rightInset = insets.right;
|
||||
_navbarOffset = navbarOffset;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@interface RNSScreen : UIViewController
|
||||
|
||||
- (instancetype)initWithView:(UIView *)view;
|
||||
- (void)notifyFinishTransitioning;
|
||||
|
||||
@interface RNSScreenView () <UIAdaptivePresentationControllerDelegate>
|
||||
@end
|
||||
|
||||
@implementation RNSScreenView {
|
||||
__weak RCTBridge *_bridge;
|
||||
RNSScreen *_controller;
|
||||
BOOL _invalidated;
|
||||
RCTTouchHandler *_touchHandler;
|
||||
}
|
||||
|
||||
@synthesize controller = _controller;
|
||||
@@ -53,28 +24,26 @@
|
||||
if (self = [super init]) {
|
||||
_bridge = bridge;
|
||||
_controller = [[RNSScreen alloc] initWithView:self];
|
||||
_controller.modalPresentationStyle = UIModalPresentationOverCurrentContext;
|
||||
_stackPresentation = RNSScreenStackPresentationPush;
|
||||
_stackAnimation = RNSScreenStackAnimationDefault;
|
||||
_gestureEnabled = YES;
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)reactSetFrame:(CGRect)frame
|
||||
{
|
||||
if (_active) {
|
||||
[super reactSetFrame:frame];
|
||||
}
|
||||
// ignore setFrame call from react, the frame of this view
|
||||
// is controlled by the UIViewController it is contained in
|
||||
}
|
||||
|
||||
- (void)updateBounds
|
||||
{
|
||||
CGFloat navbarOffset = 0;
|
||||
UINavigationController *navctr = self.controller.navigationController;
|
||||
if (!navctr.isNavigationBarHidden && !navctr.navigationBar.isTranslucent) {
|
||||
CGRect navbarFrame = navctr.navigationBar.frame;
|
||||
navbarOffset = navbarFrame.origin.y + navbarFrame.size.height;
|
||||
}
|
||||
|
||||
[_bridge.uiManager
|
||||
setLocalData:[[RNSScreenFrameData alloc]
|
||||
initWithInsets:UIEdgeInsetsZero
|
||||
andNavbarOffset:navbarOffset]
|
||||
forView:self];
|
||||
[_bridge.uiManager setSize:self.bounds.size forView:self];
|
||||
}
|
||||
|
||||
- (void)setActive:(BOOL)active
|
||||
@@ -96,12 +65,48 @@
|
||||
_stackPresentation = stackPresentation;
|
||||
switch (stackPresentation) {
|
||||
case RNSScreenStackPresentationModal:
|
||||
_controller.modalPresentationStyle = UIModalPresentationCurrentContext;
|
||||
#ifdef __IPHONE_13_0
|
||||
if (@available(iOS 13.0, *)) {
|
||||
_controller.modalPresentationStyle = UIModalPresentationAutomatic;
|
||||
} else {
|
||||
_controller.modalPresentationStyle = UIModalPresentationFullScreen;
|
||||
}
|
||||
#else
|
||||
_controller.modalPresentationStyle = UIModalPresentationFullScreen;
|
||||
#endif
|
||||
break;
|
||||
case RNSScreenStackPresentationTransparentModal:
|
||||
_controller.modalPresentationStyle = UIModalPresentationOverFullScreen;
|
||||
break;
|
||||
case RNSScreenStackPresentationContainedModal:
|
||||
_controller.modalPresentationStyle = UIModalPresentationCurrentContext;
|
||||
break;
|
||||
case RNSScreenStackPresentationContainedTransparentModal:
|
||||
_controller.modalPresentationStyle = UIModalPresentationOverCurrentContext;
|
||||
break;
|
||||
}
|
||||
// `modalPresentationStyle` must be set before accessing `presentationController`
|
||||
// otherwise a default controller will be created and cannot be changed after.
|
||||
// Documented here: https://developer.apple.com/documentation/uikit/uiviewcontroller/1621426-presentationcontroller?language=objc
|
||||
_controller.presentationController.delegate = self;
|
||||
}
|
||||
|
||||
- (void)setStackAnimation:(RNSScreenStackAnimation)stackAnimation
|
||||
{
|
||||
_stackAnimation = stackAnimation;
|
||||
|
||||
switch (stackAnimation) {
|
||||
case RNSScreenStackAnimationFade:
|
||||
_controller.modalTransitionStyle = UIModalTransitionStyleCrossDissolve;
|
||||
break;
|
||||
case RNSScreenStackAnimationFlip:
|
||||
_controller.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
|
||||
break;
|
||||
case RNSScreenStackAnimationNone:
|
||||
case RNSScreenStackAnimationDefault:
|
||||
// Default
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
- (UIView *)reactSuperview
|
||||
@@ -109,9 +114,13 @@
|
||||
return _reactSuperview;
|
||||
}
|
||||
|
||||
- (void)invalidate
|
||||
- (void)addSubview:(UIView *)view
|
||||
{
|
||||
_invalidated = YES;
|
||||
if (![view isKindOfClass:[RNSScreenStackHeaderConfig class]]) {
|
||||
[super addSubview:view];
|
||||
} else {
|
||||
((RNSScreenStackHeaderConfig*) view).screenView = self;
|
||||
}
|
||||
}
|
||||
|
||||
- (void)notifyFinishTransitioning
|
||||
@@ -130,11 +139,64 @@
|
||||
}
|
||||
}
|
||||
|
||||
- (void)notifyAppear
|
||||
{
|
||||
if (self.onAppear) {
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
if (self.onAppear) {
|
||||
self.onAppear(nil);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
- (BOOL)isMountedUnderScreenOrReactRoot
|
||||
{
|
||||
for (UIView *parent = self.superview; parent != nil; parent = parent.superview) {
|
||||
if ([parent isKindOfClass:[RCTRootView class]] || [parent isKindOfClass:[RNSScreenView class]]) {
|
||||
return YES;
|
||||
}
|
||||
}
|
||||
return NO;
|
||||
}
|
||||
|
||||
- (void)didMoveToWindow
|
||||
{
|
||||
// For RN touches to work we need to instantiate and connect RCTTouchHandler. This only applies
|
||||
// for screens that aren't mounted under RCTRootView e.g., modals that are mounted directly to
|
||||
// root application window.
|
||||
if (self.window != nil && ![self isMountedUnderScreenOrReactRoot]) {
|
||||
if (_touchHandler == nil) {
|
||||
_touchHandler = [[RCTTouchHandler alloc] initWithBridge:_bridge];
|
||||
}
|
||||
[_touchHandler attachToView:self];
|
||||
} else {
|
||||
[_touchHandler detachFromView:self];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)presentationControllerWillDismiss:(UIPresentationController *)presentationController
|
||||
{
|
||||
// We need to call both "cancel" and "reset" here because RN's gesture recognizer
|
||||
// does not handle the scenario when it gets cancelled by other top
|
||||
// level gesture recognizer. In this case by the modal dismiss gesture.
|
||||
// Because of that, at the moment when this method gets called the React's
|
||||
// gesture recognizer is already in FAILED state but cancel events never gets
|
||||
// send to JS. Calling "reset" forces RCTTouchHanler to dispatch cancel event.
|
||||
// To test this behavior one need to open a dismissable modal and start
|
||||
// pulling down starting at some touchable item. Without "reset" the touchable
|
||||
// will never go back from highlighted state even when the modal start sliding
|
||||
// down.
|
||||
[_touchHandler cancel];
|
||||
[_touchHandler reset];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation RNSScreen {
|
||||
__weak UIView *_view;
|
||||
__weak id _previousFirstResponder;
|
||||
CGRect _lastViewFrame;
|
||||
}
|
||||
|
||||
- (instancetype)initWithView:(UIView *)view
|
||||
@@ -145,6 +207,16 @@
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)viewDidLayoutSubviews
|
||||
{
|
||||
[super viewDidLayoutSubviews];
|
||||
|
||||
if (!CGRectEqualToRect(_lastViewFrame, self.view.frame)) {
|
||||
_lastViewFrame = self.view.frame;
|
||||
[((RNSScreenView *)self.view) updateBounds];
|
||||
}
|
||||
}
|
||||
|
||||
- (id)findFirstResponder:(UIView*)parent
|
||||
{
|
||||
if (parent.isFirstResponder) {
|
||||
@@ -178,6 +250,12 @@
|
||||
}
|
||||
}
|
||||
|
||||
- (void)viewDidAppear:(BOOL)animated
|
||||
{
|
||||
[super viewDidAppear:animated];
|
||||
[((RNSScreenView *)self.view) notifyAppear];
|
||||
}
|
||||
|
||||
- (void)notifyFinishTransitioning
|
||||
{
|
||||
[_previousFirstResponder becomeFirstResponder];
|
||||
@@ -194,30 +272,15 @@
|
||||
|
||||
@end
|
||||
|
||||
@interface RNSScreenShadowView : RCTShadowView
|
||||
@end
|
||||
|
||||
@implementation RNSScreenShadowView
|
||||
|
||||
- (void)setLocalData:(RNSScreenFrameData *)data
|
||||
{
|
||||
self.paddingTop = (YGValue){data.topInset, YGUnitPoint};
|
||||
self.paddingBottom = (YGValue){data.bottomInset, YGUnitPoint};
|
||||
self.paddingLeft = (YGValue){data.leftInset, YGUnitPoint};
|
||||
self.paddingRight = (YGValue){data.rightInset, YGUnitPoint};
|
||||
self.top = (YGValue){data.navbarOffset, YGUnitPoint};
|
||||
[self didSetProps:@[@"paddingTop", @"paddingBottom", @"paddingLeft", @"paddingRight", @"top"]];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation RNSScreenManager
|
||||
|
||||
RCT_EXPORT_MODULE()
|
||||
|
||||
RCT_EXPORT_VIEW_PROPERTY(active, BOOL)
|
||||
RCT_EXPORT_VIEW_PROPERTY(gestureEnabled, BOOL)
|
||||
RCT_EXPORT_VIEW_PROPERTY(stackPresentation, RNSScreenStackPresentation)
|
||||
RCT_EXPORT_VIEW_PROPERTY(stackAnimation, RNSScreenStackAnimation)
|
||||
RCT_EXPORT_VIEW_PROPERTY(onAppear, RCTDirectEventBlock);
|
||||
RCT_EXPORT_VIEW_PROPERTY(onDismissed, RCTDirectEventBlock);
|
||||
|
||||
- (UIView *)view
|
||||
@@ -225,11 +288,6 @@ RCT_EXPORT_VIEW_PROPERTY(onDismissed, RCTDirectEventBlock);
|
||||
return [[RNSScreenView alloc] initWithBridge:self.bridge];
|
||||
}
|
||||
|
||||
- (RCTShadowView *)shadowView
|
||||
{
|
||||
return [RNSScreenShadowView new];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation RCTConvert (RNSScreen)
|
||||
@@ -237,14 +295,18 @@ RCT_EXPORT_VIEW_PROPERTY(onDismissed, RCTDirectEventBlock);
|
||||
RCT_ENUM_CONVERTER(RNSScreenStackPresentation, (@{
|
||||
@"push": @(RNSScreenStackPresentationPush),
|
||||
@"modal": @(RNSScreenStackPresentationModal),
|
||||
@"transparentModal": @(RNSScreenStackPresentationTransparentModal)
|
||||
@"containedModal": @(RNSScreenStackPresentationContainedModal),
|
||||
@"transparentModal": @(RNSScreenStackPresentationTransparentModal),
|
||||
@"containedTransparentModal": @(RNSScreenStackPresentationContainedTransparentModal)
|
||||
}), RNSScreenStackPresentationPush, integerValue)
|
||||
|
||||
RCT_ENUM_CONVERTER(RNSScreenStackAnimation, (@{
|
||||
@"default": @(RNSScreenStackAnimationDefault),
|
||||
@"none": @(RNSScreenStackAnimationNone),
|
||||
@"fade": @(RNSScreenStackAnimationFade)
|
||||
@"fade": @(RNSScreenStackAnimationFade),
|
||||
@"flip": @(RNSScreenStackAnimationFlip),
|
||||
}), RNSScreenStackAnimationDefault, integerValue)
|
||||
|
||||
|
||||
@end
|
||||
|
||||
|
||||
@@ -54,6 +54,7 @@
|
||||
{
|
||||
subview.reactSuperview = self;
|
||||
[_reactSubviews insertObject:subview atIndex:atIndex];
|
||||
subview.frame = CGRectMake(0, 0, self.bounds.size.width, self.bounds.size.height);
|
||||
}
|
||||
|
||||
- (void)removeReactSubview:(RNSScreenView *)subview
|
||||
@@ -159,6 +160,10 @@
|
||||
[super layoutSubviews];
|
||||
[self reactAddControllerToClosestParent:_controller];
|
||||
_controller.view.frame = self.bounds;
|
||||
for (RNSScreenView *subview in _reactSubviews) {
|
||||
subview.frame = CGRectMake(0, 0, self.bounds.size.width, self.bounds.size.height);
|
||||
[subview setNeedsLayout];
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -2,13 +2,13 @@
|
||||
#import <React/RCTUIManagerObserverCoordinator.h>
|
||||
#import "RNSScreenContainer.h"
|
||||
|
||||
@interface RNSScreenStackView : UIView <RNSScreenContainerDelegate>
|
||||
@interface RNSScreenStackView : UIView <RNSScreenContainerDelegate, RCTInvalidating>
|
||||
|
||||
- (void)markChildUpdated;
|
||||
- (void)didUpdateChildren;
|
||||
|
||||
@end
|
||||
|
||||
@interface RNSScreenStackManager : RCTViewManager
|
||||
@interface RNSScreenStackManager : RCTViewManager <RCTInvalidating>
|
||||
|
||||
@end
|
||||
|
||||
@@ -6,6 +6,8 @@
|
||||
#import <React/RCTUIManager.h>
|
||||
#import <React/RCTUIManagerUtils.h>
|
||||
#import <React/RCTShadowView.h>
|
||||
#import <React/RCTRootContentView.h>
|
||||
#import <React/RCTTouchHandler.h>
|
||||
|
||||
@interface RNSScreenStackView () <UINavigationControllerDelegate, UIGestureRecognizerDelegate>
|
||||
@end
|
||||
@@ -20,6 +22,7 @@
|
||||
NSMutableArray<RNSScreenView *> *_reactSubviews;
|
||||
NSMutableSet<RNSScreenView *> *_dismissedScreens;
|
||||
NSMutableArray<UIViewController *> *_presentedModals;
|
||||
__weak UIViewController* recentPopped;
|
||||
__weak RNSScreenStackManager *_manager;
|
||||
}
|
||||
|
||||
@@ -35,6 +38,12 @@
|
||||
_needUpdate = NO;
|
||||
[self addSubview:_controller.view];
|
||||
_controller.interactivePopGestureRecognizer.delegate = self;
|
||||
|
||||
// we have to initialize viewControllers with a non empty array for
|
||||
// largeTitle header to render in the opened state. If it is empty
|
||||
// the header will render in collapsed state which is perhaps a bug
|
||||
// in UIKit but ¯\_(ツ)_/¯
|
||||
[_controller setViewControllers:@[[UIViewController new]]];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
@@ -42,12 +51,14 @@
|
||||
- (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated
|
||||
{
|
||||
UIView *view = viewController.view;
|
||||
RNSScreenStackHeaderConfig *config = nil;
|
||||
for (UIView *subview in view.reactSubviews) {
|
||||
if ([subview isKindOfClass:[RNSScreenStackHeaderConfig class]]) {
|
||||
[((RNSScreenStackHeaderConfig*) subview) willShowViewController:viewController];
|
||||
config = (RNSScreenStackHeaderConfig*) subview;
|
||||
break;
|
||||
}
|
||||
}
|
||||
[RNSScreenStackHeaderConfig willShowViewController:viewController withConfig:config];
|
||||
}
|
||||
|
||||
- (void)navigationController:(UINavigationController *)navigationController didShowViewController:(UIViewController *)viewController animated:(BOOL)animated
|
||||
@@ -56,10 +67,13 @@
|
||||
if ([viewController isEqual:[_reactSubviews objectAtIndex:i - 1].controller]) {
|
||||
break;
|
||||
} else {
|
||||
// TODO: send dismiss event
|
||||
[_dismissedScreens addObject:[_reactSubviews objectAtIndex:i - 1]];
|
||||
}
|
||||
}
|
||||
if (recentPopped != nil) {
|
||||
recentPopped.view = nil;
|
||||
recentPopped = nil;
|
||||
}
|
||||
}
|
||||
|
||||
- (id<UIViewControllerAnimatedTransitioning>)navigationController:(UINavigationController *)navigationController animationControllerForOperation:(UINavigationControllerOperation)operation fromViewController:(UIViewController *)fromVC toViewController:(UIViewController *)toVC
|
||||
@@ -68,9 +82,10 @@
|
||||
if (operation == UINavigationControllerOperationPush) {
|
||||
screen = (RNSScreenView *) toVC.view;
|
||||
} else if (operation == UINavigationControllerOperationPop) {
|
||||
screen = (RNSScreenView *) fromVC.view;
|
||||
screen = (RNSScreenView *) fromVC.view;
|
||||
recentPopped = fromVC;
|
||||
}
|
||||
if (screen != nil && screen.stackAnimation != RNSScreenStackAnimationDefault) {
|
||||
if (screen != nil && (screen.stackAnimation == RNSScreenStackAnimationFade || screen.stackAnimation == RNSScreenStackAnimationNone)) {
|
||||
return [[RNSScreenStackAnimator alloc] initWithOperation:operation];
|
||||
}
|
||||
return nil;
|
||||
@@ -83,28 +98,13 @@
|
||||
// Without the below code the Touchable will remain active (highlighted) for the duration of back
|
||||
// gesture and onPress may fire when we release the finger.
|
||||
UIView *parent = _controller.view;
|
||||
while (parent != nil && ![parent isKindOfClass:[RCTRootView class]]) parent = parent.superview;
|
||||
RCTRootView *rootView = (RCTRootView *)parent;
|
||||
[rootView cancelTouches];
|
||||
while (parent != nil && ![parent isKindOfClass:[RCTRootContentView class]]) parent = parent.superview;
|
||||
RCTRootContentView *rootView = (RCTRootContentView *)parent;
|
||||
[rootView.touchHandler cancel];
|
||||
|
||||
return _controller.viewControllers.count > 1;
|
||||
}
|
||||
RNSScreenView *topScreen = (RNSScreenView *)_controller.viewControllers.lastObject.view;
|
||||
|
||||
- (void)markUpdated
|
||||
{
|
||||
// We want 'updateContainer' to be executed on main thread after all enqueued operations in
|
||||
// uimanager are complete. In order to achieve that we enqueue call on UIManagerQueue from which
|
||||
// we enqueue call on the main queue. This seems to be working ok in all the cases I've tried but
|
||||
// there is a chance it is not the correct way to do that.
|
||||
if (!_needUpdate) {
|
||||
_needUpdate = YES;
|
||||
RCTExecuteOnUIManagerQueue(^{
|
||||
RCTExecuteOnMainQueue(^{
|
||||
_needUpdate = NO;
|
||||
[self updateContainer];
|
||||
});
|
||||
});
|
||||
}
|
||||
return _controller.viewControllers.count > 1 && topScreen.gestureEnabled;
|
||||
}
|
||||
|
||||
- (void)markChildUpdated
|
||||
@@ -124,14 +124,12 @@
|
||||
return;
|
||||
}
|
||||
[_reactSubviews insertObject:subview atIndex:atIndex];
|
||||
[self markUpdated];
|
||||
}
|
||||
|
||||
- (void)removeReactSubview:(RNSScreenView *)subview
|
||||
{
|
||||
[_reactSubviews removeObject:subview];
|
||||
[_dismissedScreens removeObject:subview];
|
||||
[self markUpdated];
|
||||
}
|
||||
|
||||
- (NSArray<UIView *> *)reactSubviews
|
||||
@@ -142,53 +140,84 @@
|
||||
- (void)didUpdateReactSubviews
|
||||
{
|
||||
// do nothing
|
||||
[self updateContainer];
|
||||
}
|
||||
|
||||
- (void)setModalViewControllers:(NSArray<UIViewController *> *)controllers
|
||||
{
|
||||
// when there is no change we return immediately. This check is important because sometime we may
|
||||
// accidently trigger modal dismiss if we don't verify to run the below code only when an actual
|
||||
// change in the list of presented modal was made.
|
||||
if ([_presentedModals isEqualToArray:controllers]) {
|
||||
return;
|
||||
}
|
||||
|
||||
NSMutableArray<UIViewController *> *newControllers = [NSMutableArray arrayWithArray:controllers];
|
||||
[newControllers removeObjectsInArray:_presentedModals];
|
||||
|
||||
NSMutableArray<UIViewController *> *controllersToRemove = [NSMutableArray arrayWithArray:_presentedModals];
|
||||
[controllersToRemove removeObjectsInArray:controllers];
|
||||
|
||||
// presenting new controllers
|
||||
for (UIViewController *newController in newControllers) {
|
||||
[_presentedModals addObject:newController];
|
||||
if (_controller.presentedViewController != nil) {
|
||||
[_controller.presentedViewController presentViewController:newController animated:YES completion:nil];
|
||||
// find bottom-most controller that should stay on the stack for the duration of transition
|
||||
NSUInteger changeRootIndex = 0;
|
||||
UIViewController *changeRootController = _controller;
|
||||
for (NSUInteger i = 0; i < MIN(_presentedModals.count, controllers.count); i++) {
|
||||
if (_presentedModals[i] == controllers[i]) {
|
||||
changeRootController = controllers[i];
|
||||
changeRootIndex = i + 1;
|
||||
} else {
|
||||
[_controller presentViewController:newController animated:YES completion:nil];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// hiding old controllers
|
||||
for (UIViewController *controller in [controllersToRemove reverseObjectEnumerator]) {
|
||||
[_presentedModals removeObject:controller];
|
||||
if (controller.presentedViewController != nil) {
|
||||
UIViewController *restore = controller.presentedViewController;
|
||||
UIViewController *parent = controller.presentingViewController;
|
||||
[controller dismissViewControllerAnimated:NO completion:^{
|
||||
[parent dismissViewControllerAnimated:NO completion:^{
|
||||
[parent presentViewController:restore animated:NO completion:nil];
|
||||
}];
|
||||
}];
|
||||
} else {
|
||||
[controller.presentingViewController dismissViewControllerAnimated:YES completion:nil];
|
||||
// we verify that controllers added on top of changeRootIndex are all new. Unfortunately modal
|
||||
// VCs cannot be reshuffled (there are some visual glitches when we try to dismiss then show as
|
||||
// even non-animated dismissal has delay and updates the screen several times)
|
||||
for (NSUInteger i = changeRootIndex; i < controllers.count; i++) {
|
||||
if ([_presentedModals containsObject:controllers[i]]) {
|
||||
RCTAssert(false, @"Modally presented controllers are being reshuffled, this is not allowed");
|
||||
}
|
||||
}
|
||||
|
||||
void (^finish)(void) = ^{
|
||||
UIViewController *previous = changeRootController;
|
||||
for (NSUInteger i = changeRootIndex; i < controllers.count; i++) {
|
||||
UIViewController *next = controllers[i];
|
||||
[previous presentViewController:next
|
||||
animated:(i == controllers.count - 1)
|
||||
completion:nil];
|
||||
previous = next;
|
||||
}
|
||||
};
|
||||
|
||||
if (changeRootController.presentedViewController) {
|
||||
[changeRootController
|
||||
dismissViewControllerAnimated:(changeRootIndex == controllers.count)
|
||||
completion:finish];
|
||||
} else {
|
||||
finish();
|
||||
}
|
||||
[_presentedModals setArray:controllers];
|
||||
}
|
||||
|
||||
- (void)setPushViewControllers:(NSArray<UIViewController *> *)controllers
|
||||
{
|
||||
// when there is no change we return immediately
|
||||
if ([_controller.viewControllers isEqualToArray:controllers]) {
|
||||
return;
|
||||
}
|
||||
|
||||
UIViewController *top = controllers.lastObject;
|
||||
UIViewController *lastTop = _controller.viewControllers.lastObject;
|
||||
|
||||
BOOL shouldAnimate = ((RNSScreenView *) lastTop.view).stackAnimation != RNSScreenStackAnimationNone;
|
||||
// at the start we set viewControllers to contain a single UIVIewController
|
||||
// instance. This is a workaround for header height adjustment bug (see comment
|
||||
// in the init function). Here, we need to detect if the initial empty
|
||||
// controller is still there
|
||||
BOOL firstTimePush = ![lastTop isKindOfClass:[RNSScreen class]];
|
||||
|
||||
if (_controller.viewControllers.count == 0) {
|
||||
BOOL shouldAnimate = !firstTimePush && ((RNSScreenView *) lastTop.view).stackAnimation != RNSScreenStackAnimationNone && !_controller.presentedViewController;
|
||||
|
||||
if (firstTimePush) {
|
||||
// nothing pushed yet
|
||||
[_controller setViewControllers:@[top] animated:NO];
|
||||
[_controller setViewControllers:controllers animated:NO];
|
||||
} else if (top != lastTop) {
|
||||
if (![controllers containsObject:lastTop]) {
|
||||
// last top controller is no longer on stack
|
||||
@@ -227,14 +256,10 @@
|
||||
// first screen on the list needs to be places as "push controller"
|
||||
[pushControllers addObject:screen.controller];
|
||||
} else {
|
||||
switch (screen.stackPresentation) {
|
||||
case RNSScreenStackPresentationPush:
|
||||
[pushControllers addObject:screen.controller];
|
||||
break;
|
||||
case RNSScreenStackPresentationModal:
|
||||
case RNSScreenStackPresentationTransparentModal:
|
||||
[modalControllers addObject:screen.controller];
|
||||
break;
|
||||
if (screen.stackPresentation == RNSScreenStackPresentationPush) {
|
||||
[pushControllers addObject:screen.controller];
|
||||
} else {
|
||||
[modalControllers addObject:screen.controller];
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -251,9 +276,26 @@
|
||||
_controller.view.frame = self.bounds;
|
||||
}
|
||||
|
||||
- (void)invalidate
|
||||
{
|
||||
for (UIViewController *controller in _presentedModals) {
|
||||
[controller dismissViewControllerAnimated:NO completion:nil];
|
||||
}
|
||||
[_presentedModals removeAllObjects];
|
||||
}
|
||||
|
||||
- (void)dismissOnReload
|
||||
{
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
[self invalidate];
|
||||
});
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation RNSScreenStackManager
|
||||
@implementation RNSScreenStackManager {
|
||||
NSPointerArray *_stacks;
|
||||
}
|
||||
|
||||
RCT_EXPORT_MODULE()
|
||||
|
||||
@@ -262,7 +304,20 @@ RCT_EXPORT_VIEW_PROPERTY(progress, CGFloat)
|
||||
|
||||
- (UIView *)view
|
||||
{
|
||||
return [[RNSScreenStackView alloc] initWithManager:self];
|
||||
RNSScreenStackView *view = [[RNSScreenStackView alloc] initWithManager:self];
|
||||
if (!_stacks) {
|
||||
_stacks = [NSPointerArray weakObjectsPointerArray];
|
||||
}
|
||||
[_stacks addPointer:(__bridge void *)view];
|
||||
return view;
|
||||
}
|
||||
|
||||
- (void)invalidate
|
||||
{
|
||||
for (RNSScreenStackView *stack in _stacks) {
|
||||
[stack dismissOnReload];
|
||||
}
|
||||
_stacks = nil;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -1,8 +1,12 @@
|
||||
#import <React/RCTViewManager.h>
|
||||
#import <React/RCTConvert.h>
|
||||
|
||||
#import "RNSScreen.h"
|
||||
|
||||
@interface RNSScreenStackHeaderConfig : UIView
|
||||
|
||||
@property (nonatomic, weak) RNSScreenView *screenView;
|
||||
|
||||
@property (nonatomic, retain) NSString *title;
|
||||
@property (nonatomic, retain) NSString *titleFontFamily;
|
||||
@property (nonatomic, retain) NSNumber *titleFontSize;
|
||||
@@ -14,12 +18,13 @@
|
||||
@property (nonatomic, retain) UIColor *color;
|
||||
@property (nonatomic) BOOL hide;
|
||||
@property (nonatomic) BOOL largeTitle;
|
||||
@property (nonatomic, retain) NSString *largeTitleFontFamily;
|
||||
@property (nonatomic, retain) NSNumber *largeTitleFontSize;
|
||||
@property (nonatomic) BOOL hideBackButton;
|
||||
@property (nonatomic) BOOL hideShadow;
|
||||
@property (nonatomic) BOOL translucent;
|
||||
@property (nonatomic) BOOL gestureEnabled;
|
||||
|
||||
- (void)willShowViewController:(UIViewController *)vc;
|
||||
+ (void)willShowViewController:(UIViewController *)vc withConfig:(RNSScreenStackHeaderConfig*)config;
|
||||
|
||||
@end
|
||||
|
||||
@@ -28,6 +33,7 @@
|
||||
@end
|
||||
|
||||
typedef NS_ENUM(NSInteger, RNSScreenStackHeaderSubviewType) {
|
||||
RNSScreenStackHeaderSubviewTypeBackButton,
|
||||
RNSScreenStackHeaderSubviewTypeLeft,
|
||||
RNSScreenStackHeaderSubviewTypeRight,
|
||||
RNSScreenStackHeaderSubviewTypeTitle,
|
||||
|
||||
@@ -5,34 +5,41 @@
|
||||
#import <React/RCTUIManager.h>
|
||||
#import <React/RCTUIManagerUtils.h>
|
||||
#import <React/RCTShadowView.h>
|
||||
#import <React/RCTImageLoader.h>
|
||||
#import <React/RCTImageView.h>
|
||||
#import <React/RCTImageSource.h>
|
||||
|
||||
@interface RNSScreenHeaderItemMeasurements : NSObject
|
||||
@property (nonatomic, readonly) CGSize headerSize;
|
||||
@property (nonatomic, readonly) CGFloat leftPadding;
|
||||
@property (nonatomic, readonly) CGFloat rightPadding;
|
||||
|
||||
- (instancetype)initWithHeaderSize:(CGSize)headerSize leftPadding:(CGFloat)leftPadding rightPadding:(CGFloat)rightPadding;
|
||||
// Some RN private method hacking below. Couldn't figure out better way to access image data
|
||||
// of a given RCTImageView. See more comments in the code section processing SubviewTypeBackButton
|
||||
@interface RCTImageView (Private)
|
||||
- (UIImage*)image;
|
||||
@end
|
||||
|
||||
@implementation RNSScreenHeaderItemMeasurements
|
||||
|
||||
- (instancetype)initWithHeaderSize:(CGSize)headerSize leftPadding:(CGFloat)leftPadding rightPadding:(CGFloat)rightPadding
|
||||
{
|
||||
if (self = [super init]) {
|
||||
_headerSize = headerSize;
|
||||
_leftPadding = leftPadding;
|
||||
_rightPadding = rightPadding;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
@interface RCTImageLoader (Private)
|
||||
- (id<RCTImageCache>)imageCache;
|
||||
@end
|
||||
|
||||
|
||||
@interface RNSScreenStackHeaderSubview : UIView
|
||||
|
||||
@property (nonatomic, weak) RCTBridge *bridge;
|
||||
@property (nonatomic, weak) UIView *reactSuperview;
|
||||
@property (nonatomic) RNSScreenStackHeaderSubviewType type;
|
||||
|
||||
- (instancetype)initWithBridge:(RCTBridge*)bridge;
|
||||
|
||||
@end
|
||||
|
||||
@implementation RNSScreenStackHeaderSubview
|
||||
|
||||
- (instancetype)initWithBridge:(RCTBridge *)bridge
|
||||
{
|
||||
if (self = [super init]) {
|
||||
_bridge = bridge;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation RNSScreenStackHeaderConfig {
|
||||
@@ -45,7 +52,6 @@
|
||||
self.hidden = YES;
|
||||
_translucent = YES;
|
||||
_reactSubviews = [NSMutableArray new];
|
||||
_gestureEnabled = YES;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
@@ -66,50 +72,112 @@
|
||||
return _reactSubviews;
|
||||
}
|
||||
|
||||
- (UIViewController*)screen
|
||||
- (UIView *)reactSuperview
|
||||
{
|
||||
UIView *superview = self.superview;
|
||||
if ([superview isKindOfClass:[RNSScreenView class]]) {
|
||||
return ((RNSScreenView *)superview).controller;
|
||||
}
|
||||
return nil;
|
||||
return _screenView;
|
||||
}
|
||||
|
||||
- (void)setAnimatedConfig:(UIViewController *)vc
|
||||
- (void)removeFromSuperview
|
||||
{
|
||||
[super removeFromSuperview];
|
||||
_screenView = nil;
|
||||
}
|
||||
|
||||
- (void)updateViewControllerIfNeeded
|
||||
{
|
||||
UIViewController *vc = _screenView.controller;
|
||||
UINavigationController *nav = (UINavigationController*) vc.parentViewController;
|
||||
UIViewController *nextVC = nav.visibleViewController;
|
||||
if (nav.transitionCoordinator != nil) {
|
||||
// if navigator is performing transition instead of allowing to update of `visibleConttroller`
|
||||
// we look at `topController`. This is because during transitiong the `visibleController` won't
|
||||
// point to the controller that is going to be revealed after transition. This check fixes the
|
||||
// problem when config gets updated while the transition is ongoing.
|
||||
nextVC = nav.topViewController;
|
||||
}
|
||||
|
||||
if (vc != nil && nextVC == vc) {
|
||||
[RNSScreenStackHeaderConfig updateViewController:self.screenView.controller withConfig:self];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)didSetProps:(NSArray<NSString *> *)changedProps
|
||||
{
|
||||
[super didSetProps:changedProps];
|
||||
[self updateViewControllerIfNeeded];
|
||||
}
|
||||
|
||||
- (void)didUpdateReactSubviews
|
||||
{
|
||||
[super didUpdateReactSubviews];
|
||||
[self updateViewControllerIfNeeded];
|
||||
}
|
||||
|
||||
+ (void)setAnimatedConfig:(UIViewController *)vc withConfig:(RNSScreenStackHeaderConfig *)config
|
||||
{
|
||||
UINavigationBar *navbar = ((UINavigationController *)vc.parentViewController).navigationBar;
|
||||
BOOL hideShadow = _hideShadow;
|
||||
[navbar setTintColor:_color];
|
||||
if (_backgroundColor && CGColorGetAlpha(_backgroundColor.CGColor) == 0.) {
|
||||
[navbar setBackgroundImage:[UIImage new] forBarMetrics:UIBarMetricsDefault];
|
||||
[navbar setBarTintColor:[UIColor clearColor]];
|
||||
hideShadow = YES;
|
||||
[navbar setTintColor:config.color];
|
||||
|
||||
if (@available(iOS 13.0, *)) {
|
||||
// font customized on the navigation item level, so nothing to do here
|
||||
} else {
|
||||
[navbar setBackgroundImage:nil forBarMetrics:UIBarMetricsDefault];
|
||||
[navbar setBarTintColor:_backgroundColor];
|
||||
}
|
||||
[navbar setTranslucent:_translucent];
|
||||
[navbar setValue:@(hideShadow ? YES : NO) forKey:@"hidesShadow"];
|
||||
BOOL hideShadow = config.hideShadow;
|
||||
|
||||
if (_titleFontFamily || _titleFontSize || _titleColor) {
|
||||
NSMutableDictionary *attrs = [NSMutableDictionary new];
|
||||
|
||||
if (_titleColor) {
|
||||
attrs[NSForegroundColorAttributeName] = _titleColor;
|
||||
}
|
||||
|
||||
CGFloat size = _titleFontSize ? [_titleFontSize floatValue] : 17;
|
||||
if (_titleFontFamily) {
|
||||
attrs[NSFontAttributeName] = [UIFont fontWithName:_titleFontFamily size:size];
|
||||
if (config.backgroundColor && CGColorGetAlpha(config.backgroundColor.CGColor) == 0.) {
|
||||
[navbar setBackgroundImage:[UIImage new] forBarMetrics:UIBarMetricsDefault];
|
||||
[navbar setBarTintColor:[UIColor clearColor]];
|
||||
hideShadow = YES;
|
||||
} else {
|
||||
attrs[NSFontAttributeName] = [UIFont boldSystemFontOfSize:size];
|
||||
[navbar setBackgroundImage:nil forBarMetrics:UIBarMetricsDefault];
|
||||
[navbar setBarTintColor:config.backgroundColor];
|
||||
}
|
||||
[navbar setTitleTextAttributes:attrs];
|
||||
}
|
||||
[navbar setTranslucent:config.translucent];
|
||||
[navbar setValue:@(hideShadow ? YES : NO) forKey:@"hidesShadow"];
|
||||
|
||||
if (config.titleFontFamily || config.titleFontSize || config.titleColor) {
|
||||
NSMutableDictionary *attrs = [NSMutableDictionary new];
|
||||
|
||||
if (config.titleColor) {
|
||||
attrs[NSForegroundColorAttributeName] = config.titleColor;
|
||||
}
|
||||
|
||||
CGFloat size = config.titleFontSize ? [config.titleFontSize floatValue] : 17;
|
||||
if (config.titleFontFamily) {
|
||||
attrs[NSFontAttributeName] = [UIFont fontWithName:config.titleFontFamily size:size];
|
||||
} else {
|
||||
attrs[NSFontAttributeName] = [UIFont boldSystemFontOfSize:size];
|
||||
}
|
||||
[navbar setTitleTextAttributes:attrs];
|
||||
}
|
||||
|
||||
if (@available(iOS 11.0, *)) {
|
||||
if (config.largeTitle && (config.largeTitleFontFamily || config.largeTitleFontSize || config.titleColor)) {
|
||||
NSMutableDictionary *largeAttrs = [NSMutableDictionary new];
|
||||
if (config.titleColor) {
|
||||
largeAttrs[NSForegroundColorAttributeName] = config.titleColor;
|
||||
}
|
||||
CGFloat largeSize = config.largeTitleFontSize ? [config.largeTitleFontSize floatValue] : 34;
|
||||
if (config.largeTitleFontFamily) {
|
||||
largeAttrs[NSFontAttributeName] = [UIFont fontWithName:config.largeTitleFontFamily size:largeSize];
|
||||
} else {
|
||||
largeAttrs[NSFontAttributeName] = [UIFont boldSystemFontOfSize:largeSize];
|
||||
}
|
||||
[navbar setLargeTitleTextAttributes:largeAttrs];
|
||||
}
|
||||
}
|
||||
|
||||
UIImage *backButtonImage = [self loadBackButtonImageInViewController:vc withConfig:config];
|
||||
if (backButtonImage) {
|
||||
navbar.backIndicatorImage = backButtonImage;
|
||||
navbar.backIndicatorTransitionMaskImage = backButtonImage;
|
||||
} else if (navbar.backIndicatorImage) {
|
||||
navbar.backIndicatorImage = nil;
|
||||
navbar.backIndicatorTransitionMaskImage = nil;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (void)setTitleAttibutes:(NSDictionary *)attrs forButton:(UIBarButtonItem *)button
|
||||
+ (void)setTitleAttibutes:(NSDictionary *)attrs forButton:(UIBarButtonItem *)button
|
||||
{
|
||||
[button setTitleTextAttributes:attrs forState:UIControlStateNormal];
|
||||
[button setTitleTextAttributes:attrs forState:UIControlStateHighlighted];
|
||||
@@ -120,7 +188,65 @@
|
||||
}
|
||||
}
|
||||
|
||||
- (void)willShowViewController:(UIViewController *)vc
|
||||
+ (UIImage*)loadBackButtonImageInViewController:(UIViewController *)vc
|
||||
withConfig:(RNSScreenStackHeaderConfig *)config
|
||||
{
|
||||
BOOL hasBackButtonImage = NO;
|
||||
for (RNSScreenStackHeaderSubview *subview in config.reactSubviews) {
|
||||
if (subview.type == RNSScreenStackHeaderSubviewTypeBackButton && subview.subviews.count > 0) {
|
||||
hasBackButtonImage = YES;
|
||||
RCTImageView *imageView = subview.subviews[0];
|
||||
UIImage *image = imageView.image;
|
||||
// IMPORTANT!!!
|
||||
// image can be nil in DEV MODE ONLY
|
||||
//
|
||||
// It is so, because in dev mode images are loaded over HTTP from the packager. In that case
|
||||
// we first check if image is already loaded in cache and if it is, we take it from cache and
|
||||
// display immediately. Otherwise we wait for the transition to finish and retry updating
|
||||
// header config.
|
||||
// Unfortunately due to some problems in UIKit we cannot update the image while the screen
|
||||
// transition is ongoing. This results in the settings being reset after the transition is done
|
||||
// to the state from before the transition.
|
||||
if (image == nil) {
|
||||
// in DEV MODE we try to load from cache (we use private API for that as it is not exposed
|
||||
// publically in headers).
|
||||
RCTImageSource *source = imageView.imageSources[0];
|
||||
image = [subview.bridge.imageLoader.imageCache
|
||||
imageForUrl:source.request.URL.absoluteString
|
||||
size:source.size
|
||||
scale:source.scale
|
||||
resizeMode:imageView.resizeMode];
|
||||
}
|
||||
if (image == nil) {
|
||||
// This will be triggered if the image is not in the cache yet. What we do is we wait until
|
||||
// the end of transition and run header config updates again. We could potentially wait for
|
||||
// image on load to trigger, but that would require even more private method hacking.
|
||||
if (vc.transitionCoordinator) {
|
||||
[vc.transitionCoordinator animateAlongsideTransition:^(id<UIViewControllerTransitionCoordinatorContext> _Nonnull context) {
|
||||
// nothing, we just want completion
|
||||
} completion:^(id<UIViewControllerTransitionCoordinatorContext> _Nonnull context) {
|
||||
// in order for new back button image to be loaded we need to trigger another change
|
||||
// in back button props that'd make UIKit redraw the button. Otherwise the changes are
|
||||
// not reflected. Here we change back button visibility which is then immediately restored
|
||||
vc.navigationItem.hidesBackButton = YES;
|
||||
[config updateViewControllerIfNeeded];
|
||||
}];
|
||||
}
|
||||
return [UIImage new];
|
||||
} else {
|
||||
return image;
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil;
|
||||
}
|
||||
|
||||
+ (void)willShowViewController:(UIViewController *)vc withConfig:(RNSScreenStackHeaderConfig *)config
|
||||
{
|
||||
[self updateViewController:vc withConfig:config];
|
||||
}
|
||||
|
||||
+ (void)updateViewController:(UIViewController *)vc withConfig:(RNSScreenStackHeaderConfig *)config
|
||||
{
|
||||
UINavigationItem *navitem = vc.navigationItem;
|
||||
UINavigationController *navctr = (UINavigationController *)vc.parentViewController;
|
||||
@@ -129,26 +255,39 @@
|
||||
UINavigationItem *prevItem = currentIndex > 0 ? [navctr.viewControllers objectAtIndex:currentIndex - 1].navigationItem : nil;
|
||||
|
||||
BOOL wasHidden = navctr.navigationBarHidden;
|
||||
BOOL shouldHide = config == nil || config.hide;
|
||||
|
||||
[navctr setNavigationBarHidden:_hide animated:YES];
|
||||
navctr.interactivePopGestureRecognizer.enabled = _gestureEnabled;
|
||||
if (_hide) {
|
||||
if (!shouldHide && !config.translucent) {
|
||||
// when nav bar is not translucent we chage edgesForExtendedLayout to avoid system laying out
|
||||
// the screen underneath navigation controllers
|
||||
vc.edgesForExtendedLayout = UIRectEdgeNone;
|
||||
} else {
|
||||
// system default is UIRectEdgeAll
|
||||
vc.edgesForExtendedLayout = UIRectEdgeAll;
|
||||
}
|
||||
|
||||
[navctr setNavigationBarHidden:shouldHide animated:YES];
|
||||
#ifdef __IPHONE_13_0
|
||||
if (@available(iOS 13.0, *)) {
|
||||
vc.modalInPresentation = !config.screenView.gestureEnabled;
|
||||
}
|
||||
#endif
|
||||
if (shouldHide) {
|
||||
return;
|
||||
}
|
||||
|
||||
navitem.title = _title;
|
||||
navitem.hidesBackButton = _hideBackButton;
|
||||
if (_backTitle != nil) {
|
||||
navitem.title = config.title;
|
||||
if (config.backTitle != nil) {
|
||||
prevItem.backBarButtonItem = [[UIBarButtonItem alloc]
|
||||
initWithTitle:_backTitle
|
||||
initWithTitle:config.backTitle
|
||||
style:UIBarButtonItemStylePlain
|
||||
target:nil
|
||||
action:nil];
|
||||
if (_backTitleFontFamily || _backTitleFontSize) {
|
||||
if (config.backTitleFontFamily || config.backTitleFontSize) {
|
||||
NSMutableDictionary *attrs = [NSMutableDictionary new];
|
||||
CGFloat size = _backTitleFontSize ? [_backTitleFontSize floatValue] : 17;
|
||||
if (_backTitleFontFamily) {
|
||||
attrs[NSFontAttributeName] = [UIFont fontWithName:_backTitleFontFamily size:size];
|
||||
CGFloat size = config.backTitleFontSize ? [config.backTitleFontSize floatValue] : 17;
|
||||
if (config.backTitleFontFamily) {
|
||||
attrs[NSFontAttributeName] = [UIFont fontWithName:config.backTitleFontFamily size:size];
|
||||
} else {
|
||||
attrs[NSFontAttributeName] = [UIFont boldSystemFontOfSize:size];
|
||||
}
|
||||
@@ -159,13 +298,90 @@
|
||||
}
|
||||
|
||||
if (@available(iOS 11.0, *)) {
|
||||
if (self.largeTitle) {
|
||||
if (config.largeTitle) {
|
||||
navctr.navigationBar.prefersLargeTitles = YES;
|
||||
}
|
||||
navitem.largeTitleDisplayMode = self.largeTitle ? UINavigationItemLargeTitleDisplayModeAlways : UINavigationItemLargeTitleDisplayModeNever;
|
||||
navitem.largeTitleDisplayMode = config.largeTitle ? UINavigationItemLargeTitleDisplayModeAlways : UINavigationItemLargeTitleDisplayModeNever;
|
||||
}
|
||||
#ifdef __IPHONE_13_0
|
||||
if (@available(iOS 13.0, *)) {
|
||||
UINavigationBarAppearance *appearance = [UINavigationBarAppearance new];
|
||||
|
||||
for (RNSScreenStackHeaderSubview *subview in _reactSubviews) {
|
||||
if (config.backgroundColor && CGColorGetAlpha(config.backgroundColor.CGColor) == 0.) {
|
||||
// transparent background color
|
||||
[appearance configureWithTransparentBackground];
|
||||
} else {
|
||||
// non-transparent background or default background
|
||||
if (config.translucent) {
|
||||
[appearance configureWithDefaultBackground];
|
||||
} else {
|
||||
[appearance configureWithOpaqueBackground];
|
||||
}
|
||||
|
||||
// set background color if specified
|
||||
if (config.backgroundColor) {
|
||||
appearance.backgroundColor = config.backgroundColor;
|
||||
}
|
||||
}
|
||||
|
||||
if (config.backgroundColor && CGColorGetAlpha(config.backgroundColor.CGColor) == 0.) {
|
||||
appearance.backgroundColor = config.backgroundColor;
|
||||
}
|
||||
|
||||
if (config.hideShadow) {
|
||||
appearance.shadowColor = nil;
|
||||
}
|
||||
|
||||
if (config.titleFontFamily || config.titleFontSize || config.titleColor) {
|
||||
NSMutableDictionary *attrs = [NSMutableDictionary new];
|
||||
|
||||
if (config.titleColor) {
|
||||
attrs[NSForegroundColorAttributeName] = config.titleColor;
|
||||
}
|
||||
|
||||
CGFloat size = config.titleFontSize ? [config.titleFontSize floatValue] : 17;
|
||||
if (config.titleFontFamily) {
|
||||
attrs[NSFontAttributeName] = [UIFont fontWithName:config.titleFontFamily size:size];
|
||||
} else {
|
||||
attrs[NSFontAttributeName] = [UIFont boldSystemFontOfSize:size];
|
||||
}
|
||||
appearance.titleTextAttributes = attrs;
|
||||
}
|
||||
|
||||
if (config.largeTitleFontFamily || config.largeTitleFontSize || config.titleColor) {
|
||||
NSMutableDictionary *largeAttrs = [NSMutableDictionary new];
|
||||
|
||||
if (config.titleColor) {
|
||||
largeAttrs[NSForegroundColorAttributeName] = config.titleColor;
|
||||
}
|
||||
|
||||
CGFloat largeSize = config.largeTitleFontSize ? [config.largeTitleFontSize floatValue] : 34;
|
||||
if (config.largeTitleFontFamily) {
|
||||
largeAttrs[NSFontAttributeName] = [UIFont fontWithName:config.largeTitleFontFamily size:largeSize];
|
||||
} else {
|
||||
largeAttrs[NSFontAttributeName] = [UIFont boldSystemFontOfSize:largeSize];
|
||||
}
|
||||
|
||||
appearance.largeTitleTextAttributes = largeAttrs;
|
||||
}
|
||||
|
||||
UIImage *backButtonImage = [self loadBackButtonImageInViewController:vc withConfig:config];
|
||||
if (backButtonImage) {
|
||||
[appearance setBackIndicatorImage:backButtonImage transitionMaskImage:backButtonImage];
|
||||
} else if (appearance.backIndicatorImage) {
|
||||
[appearance setBackIndicatorImage:nil transitionMaskImage:nil];
|
||||
}
|
||||
|
||||
navitem.standardAppearance = appearance;
|
||||
navitem.compactAppearance = appearance;
|
||||
navitem.scrollEdgeAppearance = appearance;
|
||||
}
|
||||
#endif
|
||||
navitem.hidesBackButton = config.hideBackButton;
|
||||
navitem.leftBarButtonItem = nil;
|
||||
navitem.rightBarButtonItem = nil;
|
||||
navitem.titleView = nil;
|
||||
for (RNSScreenStackHeaderSubview *subview in config.reactSubviews) {
|
||||
switch (subview.type) {
|
||||
case RNSScreenStackHeaderSubviewTypeLeft: {
|
||||
UIBarButtonItem *buttonItem = [[UIBarButtonItem alloc] initWithCustomView:subview];
|
||||
@@ -179,32 +395,39 @@
|
||||
}
|
||||
case RNSScreenStackHeaderSubviewTypeCenter:
|
||||
case RNSScreenStackHeaderSubviewTypeTitle: {
|
||||
subview.translatesAutoresizingMaskIntoConstraints = NO;
|
||||
navitem.titleView = subview;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (vc.transitionCoordinator != nil && !wasHidden) {
|
||||
[vc.transitionCoordinator animateAlongsideTransition:^(id<UIViewControllerTransitionCoordinatorContext> _Nonnull context) {
|
||||
|
||||
} completion:nil];
|
||||
if (vc.transitionCoordinator != nil
|
||||
&& vc.transitionCoordinator.presentationStyle == UIModalPresentationNone
|
||||
&& !wasHidden) {
|
||||
// when there is an ongoing transition we may need to update navbar setting in animation block
|
||||
// using animateAlongsideTransition. However, we only do that given the transition is not a modal
|
||||
// transition (presentationStyle == UIModalPresentationNone) and that the bar was not previously
|
||||
// hidden. This is because both for modal transitions and transitions from screen with hidden bar
|
||||
// the transition animation block does not get triggered. This is ok, because with both of those
|
||||
// types of transitions there is no "shared" navigation bar that needs to be updated in an animated
|
||||
// way.
|
||||
[vc.transitionCoordinator animateAlongsideTransition:^(id<UIViewControllerTransitionCoordinatorContext> _Nonnull context) {
|
||||
[self setAnimatedConfig:vc];
|
||||
[self setAnimatedConfig:vc withConfig:config];
|
||||
} completion:^(id<UIViewControllerTransitionCoordinatorContext> _Nonnull context) {
|
||||
if ([context isCancelled]) {
|
||||
UIViewController* fromVC = [context viewControllerForKey:UITransitionContextFromViewControllerKey];
|
||||
RNSScreenStackHeaderConfig* config = nil;
|
||||
for (UIView *subview in fromVC.view.reactSubviews) {
|
||||
if ([subview isKindOfClass:[RNSScreenStackHeaderConfig class]]) {
|
||||
[((RNSScreenStackHeaderConfig*) subview) setAnimatedConfig:fromVC];
|
||||
config = (RNSScreenStackHeaderConfig*) subview;
|
||||
break;
|
||||
}
|
||||
}
|
||||
[self setAnimatedConfig:fromVC withConfig:config];
|
||||
}
|
||||
}];
|
||||
} else {
|
||||
[self setAnimatedConfig:vc];
|
||||
[self setAnimatedConfig:vc withConfig:config];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -229,18 +452,20 @@ RCT_EXPORT_VIEW_PROPERTY(backTitleFontSize, NSString)
|
||||
RCT_EXPORT_VIEW_PROPERTY(backgroundColor, UIColor)
|
||||
RCT_EXPORT_VIEW_PROPERTY(color, UIColor)
|
||||
RCT_EXPORT_VIEW_PROPERTY(largeTitle, BOOL)
|
||||
RCT_EXPORT_VIEW_PROPERTY(largeTitleFontFamily, NSString)
|
||||
RCT_EXPORT_VIEW_PROPERTY(largeTitleFontSize, NSNumber)
|
||||
RCT_EXPORT_VIEW_PROPERTY(hideBackButton, BOOL)
|
||||
RCT_EXPORT_VIEW_PROPERTY(hideShadow, BOOL)
|
||||
// `hidden` is an UIView property, we need to use different name internally
|
||||
RCT_REMAP_VIEW_PROPERTY(hidden, hide, BOOL)
|
||||
RCT_EXPORT_VIEW_PROPERTY(translucent, BOOL)
|
||||
RCT_EXPORT_VIEW_PROPERTY(gestureEnabled, BOOL)
|
||||
|
||||
@end
|
||||
|
||||
@implementation RCTConvert (RNSScreenStackHeader)
|
||||
|
||||
RCT_ENUM_CONVERTER(RNSScreenStackHeaderSubviewType, (@{
|
||||
@"back": @(RNSScreenStackHeaderSubviewTypeBackButton),
|
||||
@"left": @(RNSScreenStackHeaderSubviewTypeLeft),
|
||||
@"right": @(RNSScreenStackHeaderSubviewTypeRight),
|
||||
@"title": @(RNSScreenStackHeaderSubviewTypeTitle),
|
||||
@@ -249,69 +474,6 @@ RCT_ENUM_CONVERTER(RNSScreenStackHeaderSubviewType, (@{
|
||||
|
||||
@end
|
||||
|
||||
@implementation RNSScreenStackHeaderSubview {
|
||||
__weak RCTBridge *_bridge;
|
||||
}
|
||||
|
||||
- (instancetype)initWithBridge:(RCTBridge *)bridge
|
||||
{
|
||||
if (self = [super init]) {
|
||||
_bridge = bridge;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)layoutSubviews
|
||||
{
|
||||
[super layoutSubviews];
|
||||
if (!self.translatesAutoresizingMaskIntoConstraints) {
|
||||
CGSize size = self.superview.frame.size;
|
||||
CGFloat right = size.width - self.frame.size.width - self.frame.origin.x;
|
||||
CGFloat left = self.frame.origin.x;
|
||||
[_bridge.uiManager
|
||||
setLocalData:[[RNSScreenHeaderItemMeasurements alloc]
|
||||
initWithHeaderSize:size
|
||||
leftPadding:left rightPadding:right]
|
||||
forView:self];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)reactSetFrame:(CGRect)frame
|
||||
{
|
||||
if (self.translatesAutoresizingMaskIntoConstraints) {
|
||||
[super reactSetFrame:frame];
|
||||
}
|
||||
}
|
||||
|
||||
- (CGSize)intrinsicContentSize
|
||||
{
|
||||
return UILayoutFittingExpandedSize;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@interface RNSScreenStackHeaderSubviewShadow : RCTShadowView
|
||||
@end
|
||||
|
||||
@implementation RNSScreenStackHeaderSubviewShadow
|
||||
|
||||
- (void)setLocalData:(RNSScreenHeaderItemMeasurements *)data
|
||||
{
|
||||
self.width = (YGValue){data.headerSize.width - data.leftPadding - data.rightPadding, YGUnitPoint};
|
||||
self.height = (YGValue){data.headerSize.height, YGUnitPoint};
|
||||
|
||||
if (data.leftPadding > data.rightPadding) {
|
||||
self.paddingLeft = (YGValue){0, YGUnitPoint};
|
||||
self.paddingRight = (YGValue){data.leftPadding - data.rightPadding, YGUnitPoint};
|
||||
} else {
|
||||
self.paddingLeft = (YGValue){data.rightPadding - data.leftPadding, YGUnitPoint};
|
||||
self.paddingRight = (YGValue){0, YGUnitPoint};
|
||||
}
|
||||
[self didSetProps:@[@"width", @"height", @"paddingLeft", @"paddingRight"]];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation RNSScreenStackHeaderSubviewManager
|
||||
|
||||
RCT_EXPORT_MODULE()
|
||||
@@ -323,9 +485,4 @@ RCT_EXPORT_VIEW_PROPERTY(type, RNSScreenStackHeaderSubviewType)
|
||||
return [[RNSScreenStackHeaderSubview alloc] initWithBridge:self.bridge];
|
||||
}
|
||||
|
||||
- (RCTShadowView *)shadowView
|
||||
{
|
||||
return [RNSScreenStackHeaderSubviewShadow new];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "react-native-screens",
|
||||
"version": "2.0.0-alpha.3",
|
||||
"version": "2.0.0-beta.2",
|
||||
"description": "First incomplete navigation solution for your react-native app.",
|
||||
"scripts": {
|
||||
"start": "node node_modules/react-native/local-cli/cli.js start",
|
||||
|
||||
130
src/screens.d.ts
vendored
130
src/screens.d.ts
vendored
@@ -3,20 +3,144 @@
|
||||
|
||||
declare module 'react-native-screens' {
|
||||
import { ComponentClass } from 'react';
|
||||
import { ViewProps, Animated } from 'react-native';
|
||||
import {
|
||||
ViewProps,
|
||||
Animated,
|
||||
NativeSyntheticEvent,
|
||||
NativeTouchEvent,
|
||||
ImageProps,
|
||||
} from 'react-native';
|
||||
|
||||
export function useScreens(shouldUseScreens?: boolean): void;
|
||||
export function enableScreens(shouldEnableScreens?: boolean): void;
|
||||
export function screensEnabled(): boolean;
|
||||
|
||||
export type StackPresentationTypes = 'push' | 'modal' | 'transparentModal';
|
||||
export type StackAnimationTypes = 'default' | 'fade' | 'flip' | 'none';
|
||||
|
||||
export interface ScreenProps extends ViewProps {
|
||||
active?: 0 | 1 | Animated.AnimatedInterpolation;
|
||||
onComponentRef?: (view: any) => void;
|
||||
children?: React.ReactNode;
|
||||
onAppear?: (e: NativeSyntheticEvent<NativeTouchEvent>) => void;
|
||||
/**
|
||||
*@description A callback that gets called when the current screen is dismissed by hardware back (on Android) or dismiss gesture (swipe back or down). The callback takes no arguments.
|
||||
*/
|
||||
onDismissed?: (e: NativeSyntheticEvent<NativeTouchEvent>) => void;
|
||||
/**
|
||||
* @type "push" – the new screen will be pushed onto a stack which on iOS means that the default animation will be slide from the side, the animation on Android may vary depending on the OS version and theme.
|
||||
* @type "modal" – the new screen will be presented modally. In addition this allow for a nested stack to be rendered inside such screens
|
||||
* @type "transparentModal" – the new screen will be presented modally but in addition the second to last screen will remain attached to the stack container such that if the top screen is non opaque the content below can still be seen. If "modal" is used instead the below screen will get unmounted as soon as the transition ends.
|
||||
*/
|
||||
stackPresentation: StackPresentationTypes;
|
||||
/**
|
||||
*@description Allows for the customization of how the given screen should appear/dissapear when pushed or popped at the top of the stack. The followin values are currently supported:
|
||||
* @type "default" – uses a platform default animation
|
||||
* @type "fade" – fades screen in or out
|
||||
* @type "flip" – flips the screen, requires stackPresentation: "modal" (iOS only)
|
||||
* @type "none" – the screen appears/dissapears without an animation
|
||||
*/
|
||||
stackAnimation?: StackAnimationTypes;
|
||||
/**
|
||||
* @description When set to false the back swipe gesture will be disabled when the parent Screen is on top of the stack. The default value is true.
|
||||
*/
|
||||
gestureEnabled?: boolean;
|
||||
}
|
||||
export const Screen: ComponentClass<ScreenProps>;
|
||||
|
||||
export type ScreenContainerProps = ViewProps;
|
||||
export const ScreenContainer: ComponentClass<ScreenContainerProps>;
|
||||
|
||||
export interface ScreenStackProps extends ViewProps {
|
||||
transitioning?: number;
|
||||
progress?: number;
|
||||
}
|
||||
|
||||
export interface ScreenStackHeaderConfigProps extends ViewProps {
|
||||
/**
|
||||
*@description String that representing screen title that will get rendered in the middle section of the header. On iOS the title is centered on the header while on Android it is aligned to the left and placed next to back button (if one is present).
|
||||
*/
|
||||
title?: string;
|
||||
/**
|
||||
*@description When set to true the header will be hidden while the parent Screen is on the top of the stack. The default value is false.
|
||||
*/
|
||||
hidden?: boolean;
|
||||
/**
|
||||
*@description Controls the color of items rendered on the header. This includes back icon, back text (iOS only) and title text. If you want the title to have different color use titleColor property.
|
||||
*/
|
||||
color?: string;
|
||||
/**
|
||||
*@description Customize font family to be used for the title.
|
||||
*/
|
||||
titleFontFamily?: string;
|
||||
/**
|
||||
*@description Customize the size of the font to be used for the title.
|
||||
*/
|
||||
titleFontSize?: number;
|
||||
/**
|
||||
*@description Allows for setting text color of the title.
|
||||
*/
|
||||
titleColor?: string;
|
||||
/**
|
||||
*@description Controlls the color of the navigation header.
|
||||
*/
|
||||
backgroundColor?: string;
|
||||
/**
|
||||
* @description Boolean that allows for disabling drop shadow under navigation header. The default value is true.
|
||||
*/
|
||||
hideShadow?: boolean;
|
||||
/**
|
||||
* @description If set to true the back button will not be rendered as a part of navigation header.
|
||||
*/
|
||||
hideBackButton?: boolean;
|
||||
/**
|
||||
* @host (iOS only)
|
||||
* @description When set to true, it makes native navigation bar on iOS semi transparent with blur effect. It is a common way of presenting navigation bar introduced in iOS 11. The default value is false
|
||||
*/
|
||||
translucent?: boolean;
|
||||
/**
|
||||
* @host (iOS only)
|
||||
* @description Allows for controlling the string to be rendered next to back button. By default iOS uses the title of the previous screen.
|
||||
*/
|
||||
backTitle?: string;
|
||||
/**
|
||||
* @host (iOS only)
|
||||
* @description Allows for customizing font family to be used for back button title on iOS.
|
||||
*/
|
||||
backTitleFontFamily?: string;
|
||||
/**
|
||||
* @host (iOS only)
|
||||
* @description Allows for customizing font size to be used for back button title on iOS.
|
||||
*/
|
||||
backTitleFontSize?: number;
|
||||
/**
|
||||
* @host (iOS only)
|
||||
* @description When set to true it makes the title display using the large title effect.
|
||||
*/
|
||||
largeTitle?: boolean;
|
||||
/**
|
||||
* @host (iOS only)
|
||||
* @description Customize font family to be used for the large title.
|
||||
*/
|
||||
largeTitleFontFamily?: string;
|
||||
/**
|
||||
* @host (iOS only)
|
||||
* @description Customize the size of the font to be used for the large title.
|
||||
*/
|
||||
largeTitleFontSize?: number;
|
||||
/**
|
||||
* Pass HeaderLeft, HeaderRight and HeaderTitle
|
||||
*/
|
||||
children?: React.ReactNode;
|
||||
}
|
||||
|
||||
export const Screen: ComponentClass<ScreenProps>;
|
||||
export const ScreenContainer: ComponentClass<ScreenContainerProps>;
|
||||
export const NativeScreen: ComponentClass<ScreenProps>;
|
||||
export const NativeScreenContainer: ComponentClass<ScreenContainerProps>;
|
||||
export const ScreenStack: ComponentClass<ScreenStackProps>;
|
||||
export const ScreenStackHeaderBackButtonImage: ComponentClass<ImageProps>;
|
||||
export const ScreenStackHeaderLeftView: ComponentClass<ViewProps>;
|
||||
export const ScreenStackHeaderRightView: ComponentClass<ViewProps>;
|
||||
export const ScreenStackHeaderConfig: ComponentClass<
|
||||
ScreenStackHeaderConfigProps
|
||||
>;
|
||||
}
|
||||
|
||||
@@ -4,11 +4,12 @@ import {
|
||||
requireNativeComponent,
|
||||
View,
|
||||
UIManager,
|
||||
Image,
|
||||
StyleSheet,
|
||||
} from 'react-native';
|
||||
import { version } from 'react-native/Libraries/Core/ReactNativeVersion';
|
||||
|
||||
let USE_SCREENS = false;
|
||||
let ENABLE_SCREENS = false;
|
||||
|
||||
// UIManager[`${moduleName}`] is deprecated in RN 0.58 and `getViewManagerConfig` is added.
|
||||
// We can remove this when we drop support for RN < 0.58.
|
||||
@@ -17,17 +18,23 @@ const getViewManagerConfigCompat = name =>
|
||||
? UIManager.getViewManagerConfig(name)
|
||||
: UIManager[name];
|
||||
|
||||
function useScreens(shouldUseScreens = true) {
|
||||
USE_SCREENS = shouldUseScreens;
|
||||
if (USE_SCREENS && !getViewManagerConfigCompat('RNSScreen')) {
|
||||
function enableScreens(shouldEnableScreens = true) {
|
||||
ENABLE_SCREENS = shouldEnableScreens;
|
||||
if (ENABLE_SCREENS && !getViewManagerConfigCompat('RNSScreen')) {
|
||||
console.error(
|
||||
`Screen native module hasn't been linked. Please check the react-native-screens README for more details`
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// we should remove this at some point
|
||||
function useScreens(shouldUseScreens = true) {
|
||||
console.warn('Method `useScreens` is deprecated, please use `enableScreens`');
|
||||
enableScreens(shouldUseScreens);
|
||||
}
|
||||
|
||||
function screensEnabled() {
|
||||
return USE_SCREENS;
|
||||
return ENABLE_SCREENS;
|
||||
}
|
||||
|
||||
// We initialize these lazily so that importing the module doesn't throw error when not linked
|
||||
@@ -83,7 +90,7 @@ class Screen extends React.Component {
|
||||
this.props.onComponentRef && this.props.onComponentRef(ref);
|
||||
};
|
||||
render() {
|
||||
if (!USE_SCREENS) {
|
||||
if (!ENABLE_SCREENS) {
|
||||
// Filter out active prop in this case because it is unused and
|
||||
// can cause problems depending on react-native version:
|
||||
// https://github.com/react-navigation/react-navigation/issues/4886
|
||||
@@ -97,7 +104,8 @@ class Screen extends React.Component {
|
||||
AnimatedNativeScreen ||
|
||||
Animated.createAnimatedComponent(ScreensNativeModules.NativeScreen);
|
||||
|
||||
if (version.minor >= 57) {
|
||||
// When using RN from master version is 0.0.0
|
||||
if (version.minor >= 57 || version.minor === 0) {
|
||||
return <AnimatedNativeScreen {...this.props} ref={this.setRef} />;
|
||||
} else {
|
||||
// On RN version below 0.57 we need to wrap screen's children with an
|
||||
@@ -120,7 +128,7 @@ class Screen extends React.Component {
|
||||
|
||||
class ScreenContainer extends React.Component {
|
||||
render() {
|
||||
if (!USE_SCREENS) {
|
||||
if (!ENABLE_SCREENS) {
|
||||
return <View {...this.props} />;
|
||||
} else {
|
||||
return <ScreensNativeModules.NativeScreenContainer {...this.props} />;
|
||||
@@ -139,6 +147,14 @@ const styles = StyleSheet.create({
|
||||
},
|
||||
});
|
||||
|
||||
const ScreenStackHeaderBackButtonImage = props => (
|
||||
<ScreensNativeModules.NativeScreenStackHeaderSubview
|
||||
type="back"
|
||||
style={styles.headerSubview}>
|
||||
<Image resizeMode="center" fadeDuration={0} {...props} />
|
||||
</ScreensNativeModules.NativeScreenStackHeaderSubview>
|
||||
);
|
||||
|
||||
const ScreenStackHeaderRightView = props => (
|
||||
<ScreensNativeModules.NativeScreenStackHeaderSubview
|
||||
{...props}
|
||||
@@ -155,14 +171,6 @@ const ScreenStackHeaderLeftView = props => (
|
||||
/>
|
||||
);
|
||||
|
||||
const ScreenStackHeaderTitleView = props => (
|
||||
<ScreensNativeModules.NativeScreenStackHeaderSubview
|
||||
{...props}
|
||||
type="title"
|
||||
style={styles.headerSubview}
|
||||
/>
|
||||
);
|
||||
|
||||
const ScreenStackHeaderCenterView = props => (
|
||||
<ScreensNativeModules.NativeScreenStackHeaderSubview
|
||||
{...props}
|
||||
@@ -191,11 +199,12 @@ module.exports = {
|
||||
get ScreenStackHeaderSubview() {
|
||||
return ScreensNativeModules.NativeScreenStackHeaderSubview;
|
||||
},
|
||||
ScreenStackHeaderBackButtonImage,
|
||||
ScreenStackHeaderRightView,
|
||||
ScreenStackHeaderLeftView,
|
||||
ScreenStackHeaderTitleView,
|
||||
ScreenStackHeaderCenterView,
|
||||
|
||||
enableScreens,
|
||||
useScreens,
|
||||
screensEnabled,
|
||||
};
|
||||
|
||||
@@ -2,19 +2,19 @@ import debounce from 'debounce';
|
||||
import React from 'react';
|
||||
import { Animated, View } from 'react-native';
|
||||
|
||||
let _shouldUseScreens = true;
|
||||
let _shouldEnableScreens = true;
|
||||
|
||||
export function useScreens(shouldUseScreens = true) {
|
||||
if (shouldUseScreens) {
|
||||
export function enableScreens(shouldEnableScreens = true) {
|
||||
if (shouldEnableScreens) {
|
||||
console.warn(
|
||||
'react-native-screens is not fully supported on this platform yet.'
|
||||
);
|
||||
}
|
||||
_shouldUseScreens = shouldUseScreens;
|
||||
_shouldEnableScreens = shouldEnableScreens;
|
||||
}
|
||||
|
||||
export function screensEnabled() {
|
||||
return _shouldUseScreens;
|
||||
return _shouldEnableScreens;
|
||||
}
|
||||
|
||||
function isAnimatedValue(value) {
|
||||
|
||||
22
yarn.lock
22
yarn.lock
@@ -1741,10 +1741,10 @@ commander@~2.13.0:
|
||||
version "2.13.0"
|
||||
resolved "https://registry.yarnpkg.com/commander/-/commander-2.13.0.tgz#6964bca67685df7c1f1430c584f07d7597885b9c"
|
||||
|
||||
commander@~2.20.0:
|
||||
version "2.20.0"
|
||||
resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.0.tgz#d58bb2b5c1ee8f87b0d340027e9e94e222c5a422"
|
||||
integrity sha512-7j2y+40w61zy6YC2iRNpUe/NwhNyoXrYpHMrSunaMG64nRnaf96zO/KMQR4OyN/UnE5KLyEBnKHd4aG3rskjpQ==
|
||||
commander@~2.20.3:
|
||||
version "2.20.3"
|
||||
resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33"
|
||||
integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==
|
||||
|
||||
commondir@^1.0.1:
|
||||
version "1.0.1"
|
||||
@@ -2765,9 +2765,9 @@ growly@^1.3.0:
|
||||
resolved "https://registry.yarnpkg.com/growly/-/growly-1.3.0.tgz#f10748cbe76af964b7c96c93c6bcc28af120c081"
|
||||
|
||||
handlebars@^4.0.3:
|
||||
version "4.1.2"
|
||||
resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.1.2.tgz#b6b37c1ced0306b221e094fc7aca3ec23b131b67"
|
||||
integrity sha512-nvfrjqvt9xQ8Z/w0ijewdD/vvWDTOweBUm96NTr66Wfvo1mJenBLwcYmPs3TIBP5ruzYGD7Hx/DaM9RmhroGPw==
|
||||
version "4.5.3"
|
||||
resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.5.3.tgz#5cf75bd8714f7605713511a56be7c349becb0482"
|
||||
integrity sha512-3yPecJoJHK/4c6aZhSvxOyG4vJKDshV36VHp0iVCDVh7o9w2vwi3NSnL2MMPj3YdduqaBcu7cGbggJQM0br9xA==
|
||||
dependencies:
|
||||
neo-async "^2.6.0"
|
||||
optimist "^0.6.1"
|
||||
@@ -5855,11 +5855,11 @@ uglify-es@^3.1.9:
|
||||
source-map "~0.6.1"
|
||||
|
||||
uglify-js@^3.1.4:
|
||||
version "3.6.0"
|
||||
resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.6.0.tgz#704681345c53a8b2079fb6cec294b05ead242ff5"
|
||||
integrity sha512-W+jrUHJr3DXKhrsS7NUVxn3zqMOFn0hL/Ei6v0anCIMoKC93TjcflTagwIHLW7SfMFfiQuktQyFVCFHGUE0+yg==
|
||||
version "3.7.3"
|
||||
resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.7.3.tgz#f918fce9182f466d5140f24bb0ff35c2d32dcc6a"
|
||||
integrity sha512-7tINm46/3puUA4hCkKYo4Xdts+JDaVC9ZPRcG8Xw9R4nhO/gZgUM3TENq8IF4Vatk8qCig4MzP/c8G4u2BkVQg==
|
||||
dependencies:
|
||||
commander "~2.20.0"
|
||||
commander "~2.20.3"
|
||||
source-map "~0.6.1"
|
||||
|
||||
ultron@1.0.x:
|
||||
|
||||
Reference in New Issue
Block a user