├── .gitignore ├── .npmignore ├── Animations.js ├── Example ├── .flowconfig ├── .gitignore ├── .npmignore ├── .watchmanconfig ├── android │ ├── app │ │ ├── build.gradle │ │ ├── proguard-rules.pro │ │ ├── react.gradle │ │ └── src │ │ │ └── main │ │ │ └── java │ │ │ └── com │ │ │ └── example │ │ │ └── MainActivity.java │ ├── build.gradle │ ├── gradle.properties │ └── settings.gradle ├── components │ ├── Error.js │ ├── Home.js │ ├── Launch.js │ ├── Login.js │ ├── NavBar.js │ └── Register.js ├── iOS │ ├── AppDelegate.h │ ├── AppDelegate.m │ ├── Base.lproj │ │ └── LaunchScreen.xib │ ├── Example.xcodeproj │ │ ├── project.pbxproj │ │ └── xcshareddata │ │ │ └── xcschemes │ │ │ └── Example.xcscheme │ ├── Example │ │ ├── AppDelegate.h │ │ ├── AppDelegate.m │ │ ├── Base.lproj │ │ │ └── LaunchScreen.xib │ │ ├── Images.xcassets │ │ │ └── AppIcon.appiconset │ │ │ │ └── Contents.json │ │ ├── Info.plist │ │ └── main.m │ ├── ExampleTests │ │ ├── ExampleTests.m │ │ └── Info.plist │ ├── Images.xcassets │ │ └── AppIcon.appiconset │ │ │ └── Contents.json │ ├── Info.plist │ ├── main.jsbundle │ └── main.m ├── index.ios.js └── package.json ├── LICENSE ├── README.md ├── actions.js ├── index.js ├── package.json ├── reducer.js └── test └── RouterReducer.Test.js /.gitignore: -------------------------------------------------------------------------------- 1 | # OSX 2 | # 3 | .DS_Store 4 | 5 | # Xcode 6 | # 7 | build/ 8 | *.pbxuser 9 | !default.pbxuser 10 | *.mode1v3 11 | !default.mode1v3 12 | *.mode2v3 13 | !default.mode2v3 14 | *.perspectivev3 15 | !default.perspectivev3 16 | xcuserdata 17 | *.xccheckout 18 | *.moved-aside 19 | DerivedData 20 | *.hmap 21 | *.ipa 22 | *.xcuserstate 23 | project.xcworkspace 24 | 25 | # node.js 26 | # 27 | node_modules/ 28 | npm-debug.log 29 | .idea -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | Example/ 2 | -------------------------------------------------------------------------------- /Animations.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | // Scene Config 4 | var {Navigator,Dimensions,PixelRatio} = require('react-native'); 5 | var buildStyleInterpolator = require('react-native/Libraries/Utilities/buildStyleInterpolator'); 6 | var FlatFloatFromRight = Object.assign({}, Navigator.SceneConfigs.FloatFromRight); 7 | var FlatFloatFromBottom = Object.assign({}, Navigator.SceneConfigs.FloatFromBottom); 8 | FlatFloatFromRight.gestures = {}; 9 | 10 | var FlatFadeToTheLeft = { 11 | transformTranslate: { 12 | from: {x: 0, y: 0, z: 0}, 13 | to: {x: -Math.round(Dimensions.get('window').width * 0.3), y: 0, z: 0}, 14 | min: 0, 15 | max: 1, 16 | type: 'linear', 17 | extrapolate: true, 18 | round: PixelRatio.get(), 19 | }, 20 | opacity: { 21 | from: 1, 22 | to: 0.3, 23 | min: 0, 24 | max: 1, 25 | type: 'linear', 26 | extrapolate: false, 27 | round: 100, 28 | }, 29 | translateX: { 30 | from: 0, 31 | to: -Math.round(Dimensions.get('window').width * 0.3), 32 | min: 0, 33 | max: 1, 34 | type: 'linear', 35 | extrapolate: true, 36 | round: PixelRatio.get(), 37 | }, 38 | }; 39 | var FlatFadeToTheUp = { 40 | opacity: { 41 | value: 1.0, 42 | type: 'constant', 43 | }, 44 | 45 | translateY: { 46 | from: 0, 47 | to: -Math.round(Dimensions.get('window').height * 0.3), 48 | min: 0, 49 | max: 1, 50 | type: 'linear', 51 | extrapolate: true, 52 | round: PixelRatio.get(), 53 | }, 54 | }; 55 | 56 | FlatFloatFromBottom.animationInterpolators.out = buildStyleInterpolator(FlatFadeToTheUp); 57 | FlatFloatFromRight.animationInterpolators.out = buildStyleInterpolator(FlatFadeToTheLeft); 58 | 59 | var None = { 60 | gestures: { 61 | }, 62 | 63 | // Rebound spring parameters when transitioning FROM this scene 64 | springFriction: 0, 65 | springTension: 2000, 66 | 67 | // Velocity to start at when transitioning without gesture 68 | defaultTransitionVelocity: 1.5, 69 | 70 | // Animation interpolators for horizontal transitioning: 71 | animationInterpolators: { 72 | into: buildStyleInterpolator(FlatFadeToTheUp), 73 | out: buildStyleInterpolator(FlatFadeToTheUp), 74 | }, 75 | }; 76 | 77 | module.exports = {FlatFloatFromRight, FlatFloatFromBottom, None}; 78 | -------------------------------------------------------------------------------- /Example/.flowconfig: -------------------------------------------------------------------------------- 1 | [ignore] 2 | 3 | # We fork some components by platform. 4 | .*/*.web.js 5 | .*/*.android.js 6 | 7 | # Some modules have their own node_modules with overlap 8 | .*/node_modules/node-haste/.* 9 | 10 | # Ignore react-tools where there are overlaps, but don't ignore anything that 11 | # react-native relies on 12 | .*/node_modules/react-tools/src/React.js 13 | .*/node_modules/react-tools/src/renderers/shared/event/EventPropagators.js 14 | .*/node_modules/react-tools/src/renderers/shared/event/eventPlugins/ResponderEventPlugin.js 15 | .*/node_modules/react-tools/src/shared/vendor/core/ExecutionEnvironment.js 16 | 17 | # Ignore commoner tests 18 | .*/node_modules/commoner/test/.* 19 | 20 | # See https://github.com/facebook/flow/issues/442 21 | .*/react-tools/node_modules/commoner/lib/reader.js 22 | 23 | # Ignore jest 24 | .*/node_modules/jest-cli/.* 25 | 26 | # Ignore Website 27 | .*/website/.* 28 | 29 | [include] 30 | 31 | [libs] 32 | node_modules/react-native/Libraries/react-native/react-native-interface.js 33 | 34 | [options] 35 | module.system=haste 36 | 37 | munge_underscores=true 38 | 39 | module.name_mapper='^image![a-zA-Z0-9$_-]+$' -> 'GlobalImageStub' 40 | module.name_mapper='^[./a-zA-Z0-9$_-]+\.png$' -> 'RelativeImageStub' 41 | 42 | suppress_type=$FlowIssue 43 | suppress_type=$FlowFixMe 44 | suppress_type=$FixMe 45 | 46 | suppress_comment=\\(.\\|\n\\)*\\$FlowFixMe\\($\\|[^(]\\|(\\(>=0\\.\\(1[0-7]\\|[0-9]\\).[0-9]\\)? *\\(site=[a-z,_]*react_native[a-z,_]*\\)?)\\) 47 | suppress_comment=\\(.\\|\n\\)*\\$FlowIssue\\((\\(>=0\\.\\(1[0-7]\\|[0-9]\\).[0-9]\\)? *\\(site=[a-z,_]*react_native[a-z,_]*\\)?)\\)? #[0-9]+ 48 | suppress_comment=\\(.\\|\n\\)*\\$FlowFixedInNextDeploy 49 | 50 | [version] 51 | 0.17.0 52 | -------------------------------------------------------------------------------- /Example/.gitignore: -------------------------------------------------------------------------------- 1 | # OSX 2 | # 3 | .DS_Store 4 | 5 | # Xcode 6 | # 7 | build/ 8 | *.pbxuser 9 | !default.pbxuser 10 | *.mode1v3 11 | !default.mode1v3 12 | *.mode2v3 13 | !default.mode2v3 14 | *.perspectivev3 15 | !default.perspectivev3 16 | xcuserdata 17 | *.xccheckout 18 | *.moved-aside 19 | DerivedData 20 | *.hmap 21 | *.ipa 22 | *.xcuserstate 23 | project.xcworkspace 24 | 25 | # Android/IJ 26 | # 27 | .idea 28 | .gradle 29 | local.properties 30 | 31 | # node.js 32 | # 33 | node_modules/ 34 | npm-debug.log 35 | -------------------------------------------------------------------------------- /Example/.npmignore: -------------------------------------------------------------------------------- 1 | # OSX 2 | # 3 | .DS_Store 4 | 5 | # Xcode 6 | # 7 | build/ 8 | *.pbxuser 9 | !default.pbxuser 10 | *.mode1v3 11 | !default.mode1v3 12 | *.mode2v3 13 | !default.mode2v3 14 | *.perspectivev3 15 | !default.perspectivev3 16 | xcuserdata 17 | *.xccheckout 18 | *.moved-aside 19 | DerivedData 20 | *.hmap 21 | *.ipa 22 | *.xcuserstate 23 | 24 | # node.js 25 | # 26 | node_modules/ 27 | npm-debug.log 28 | -------------------------------------------------------------------------------- /Example/.watchmanconfig: -------------------------------------------------------------------------------- 1 | {} -------------------------------------------------------------------------------- /Example/android/app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: "com.android.application" 2 | 3 | /** 4 | * The react.gradle file registers two tasks: bundleDebugJsAndAssets and bundleReleaseJsAndAssets. 5 | * These basically call `react-native bundle` with the correct arguments during the Android build 6 | * cycle. By default, bundleDebugJsAndAssets is skipped, as in debug/dev mode we prefer to load the 7 | * bundle directly from the development server. Below you can see all the possible configurations 8 | * and their defaults. If you decide to add a configuration block, make sure to add it before the 9 | * `apply from: "react.gradle"` line. 10 | * 11 | * project.ext.react = [ 12 | * // the name of the generated asset file containing your JS bundle 13 | * bundleAssetName: "index.android.bundle", 14 | * 15 | * // the entry file for bundle generation 16 | * entryFile: "index.android.js", 17 | * 18 | * // whether to bundle JS and assets in debug mode 19 | * bundleInDebug: false, 20 | * 21 | * // whether to bundle JS and assets in release mode 22 | * bundleInRelease: true, 23 | * 24 | * // the root of your project, i.e. where "package.json" lives 25 | * root: "../../", 26 | * 27 | * // where to put the JS bundle asset in debug mode 28 | * jsBundleDirDebug: "$buildDir/intermediates/assets/debug", 29 | * 30 | * // where to put the JS bundle asset in release mode 31 | * jsBundleDirRelease: "$buildDir/intermediates/assets/release", 32 | * 33 | * // where to put drawable resources / React Native assets, e.g. the ones you use via 34 | * // require('./image.png')), in debug mode 35 | * resourcesDirDebug: "$buildDir/intermediates/res/merged/debug", 36 | * 37 | * // where to put drawable resources / React Native assets, e.g. the ones you use via 38 | * // require('./image.png')), in release mode 39 | * resourcesDirRelease: "$buildDir/intermediates/res/merged/release", 40 | * 41 | * // by default the gradle tasks are skipped if none of the JS files or assets change; this means 42 | * // that we don't look at files in android/ or ios/ to determine whether the tasks are up to 43 | * // date; if you have any other folders that you want to ignore for performance reasons (gradle 44 | * // indexes the entire tree), add them here. Alternatively, if you have JS files in android/ 45 | * // for example, you might want to remove it from here. 46 | * inputExcludes: ["android/**", "ios/**"] 47 | * ] 48 | */ 49 | 50 | apply from: "react.gradle" 51 | 52 | android { 53 | compileSdkVersion 23 54 | buildToolsVersion "23.0.1" 55 | 56 | defaultConfig { 57 | applicationId "com.example" 58 | minSdkVersion 16 59 | targetSdkVersion 22 60 | versionCode 1 61 | versionName "1.0" 62 | ndk { 63 | abiFilters "armeabi-v7a", "x86" 64 | } 65 | } 66 | buildTypes { 67 | release { 68 | minifyEnabled false // Set this to true to enable Proguard 69 | proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro" 70 | } 71 | } 72 | } 73 | 74 | dependencies { 75 | compile fileTree(dir: "libs", include: ["*.jar"]) 76 | compile "com.android.support:appcompat-v7:23.0.1" 77 | compile "com.facebook.react:react-native:0.14.+" 78 | } 79 | -------------------------------------------------------------------------------- /Example/android/app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in /usr/local/Cellar/android-sdk/24.3.3/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the proguardFiles 5 | # directive in build.gradle. 6 | # 7 | # For more details, see 8 | # http://developer.android.com/guide/developing/tools/proguard.html 9 | 10 | # Add any project specific keep options here: 11 | 12 | # If your project uses WebView with JS, uncomment the following 13 | # and specify the fully qualified class name to the JavaScript interface 14 | # class: 15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 16 | # public *; 17 | #} 18 | 19 | # Disabling obfuscation is useful if you collect stack traces from production crashes 20 | # (unless you are using a system that supports de-obfuscate the stack traces). 21 | -dontobfuscate 22 | 23 | # React Native 24 | 25 | # Keep our interfaces so they can be used by other ProGuard rules. 26 | # See http://sourceforge.net/p/proguard/bugs/466/ 27 | -keep,allowobfuscation @interface com.facebook.proguard.annotations.DoNotStrip 28 | -keep,allowobfuscation @interface com.facebook.proguard.annotations.KeepGettersAndSetters 29 | 30 | # Do not strip any method/class that is annotated with @DoNotStrip 31 | -keep @com.facebook.proguard.annotations.DoNotStrip class * 32 | -keepclassmembers class * { 33 | @com.facebook.proguard.annotations.DoNotStrip *; 34 | } 35 | 36 | -keepclassmembers @com.facebook.proguard.annotations.KeepGettersAndSetters class * { 37 | void set*(***); 38 | *** get*(); 39 | } 40 | 41 | -keep class * extends com.facebook.react.bridge.JavaScriptModule { *; } 42 | -keep class * extends com.facebook.react.bridge.NativeModule { *; } 43 | -keepclassmembers class * { @com.facebook.react.uimanager.UIProp ; } 44 | -keepclassmembers class * { @com.facebook.react.uimanager.ReactProp ; } 45 | -keepclassmembers class * { @com.facebook.react.uimanager.ReactPropGroup ; } 46 | 47 | # okhttp 48 | 49 | -keepattributes Signature 50 | -keepattributes *Annotation* 51 | -keep class com.squareup.okhttp.** { *; } 52 | -keep interface com.squareup.okhttp.** { *; } 53 | -dontwarn com.squareup.okhttp.** 54 | 55 | # okio 56 | 57 | -keep class sun.misc.Unsafe { *; } 58 | -dontwarn java.nio.file.* 59 | -dontwarn org.codehaus.mojo.animal_sniffer.IgnoreJRERequirement 60 | -dontwarn okio.** 61 | -------------------------------------------------------------------------------- /Example/android/app/react.gradle: -------------------------------------------------------------------------------- 1 | def config = project.hasProperty("react") ? project.react : []; 2 | 3 | def bundleAssetName = config.bundleAssetName ?: "index.android.bundle" 4 | def entryFile = config.entryFile ?: "index.android.js" 5 | 6 | // because elvis operator 7 | def elvisFile(thing) { 8 | return thing ? file(thing) : null; 9 | } 10 | 11 | def reactRoot = elvisFile(config.root) ?: file("../../") 12 | def jsBundleDirDebug = elvisFile(config.jsBundleDirDebug) ?: 13 | file("$buildDir/intermediates/assets/debug") 14 | def jsBundleDirRelease = elvisFile(config.jsBundleDirRelease) ?: 15 | file("$buildDir/intermediates/assets/release") 16 | def resourcesDirDebug = elvisFile(config.resourcesDirDebug) ?: 17 | file("$buildDir/intermediates/res/merged/debug") 18 | def resourcesDirRelease = elvisFile(config.resourcesDirRelease) ?: 19 | file("$buildDir/intermediates/res/merged/release") 20 | def inputExcludes = config.inputExcludes ?: ["android/**", "ios/**"] 21 | 22 | def jsBundleFileDebug = file("$jsBundleDirDebug/$bundleAssetName") 23 | def jsBundleFileRelease = file("$jsBundleDirRelease/$bundleAssetName") 24 | 25 | task bundleDebugJsAndAssets(type: Exec) { 26 | // create dirs if they are not there (e.g. the "clean" task just ran) 27 | doFirst { 28 | jsBundleDirDebug.mkdirs() 29 | resourcesDirDebug.mkdirs() 30 | } 31 | 32 | // set up inputs and outputs so gradle can cache the result 33 | inputs.files fileTree(dir: reactRoot, excludes: inputExcludes) 34 | outputs.dir jsBundleDirDebug 35 | outputs.dir resourcesDirDebug 36 | 37 | // set up the call to the react-native cli 38 | workingDir reactRoot 39 | commandLine "react-native", "bundle", "--platform", "android", "--dev", "true", "--entry-file", 40 | entryFile, "--bundle-output", jsBundleFileDebug, "--assets-dest", resourcesDirDebug 41 | 42 | enabled config.bundleInDebug ?: false 43 | } 44 | 45 | task bundleReleaseJsAndAssets(type: Exec) { 46 | // create dirs if they are not there (e.g. the "clean" task just ran) 47 | doFirst { 48 | jsBundleDirRelease.mkdirs() 49 | resourcesDirRelease.mkdirs() 50 | } 51 | 52 | // set up inputs and outputs so gradle can cache the result 53 | inputs.files fileTree(dir: reactRoot, excludes: inputExcludes) 54 | outputs.dir jsBundleDirRelease 55 | outputs.dir resourcesDirRelease 56 | 57 | // set up the call to the react-native cli 58 | workingDir reactRoot 59 | commandLine "react-native", "bundle", "--platform", "android", "--dev", "false", "--entry-file", 60 | entryFile, "--bundle-output", jsBundleFileRelease, "--assets-dest", resourcesDirRelease 61 | 62 | enabled config.bundleInRelease ?: true 63 | } 64 | 65 | gradle.projectsEvaluated { 66 | // hook bundleDebugJsAndAssets into the android build process 67 | bundleDebugJsAndAssets.dependsOn mergeDebugResources 68 | bundleDebugJsAndAssets.dependsOn mergeDebugAssets 69 | processDebugResources.dependsOn bundleDebugJsAndAssets 70 | 71 | // hook bundleReleaseJsAndAssets into the android build process 72 | bundleReleaseJsAndAssets.dependsOn mergeReleaseResources 73 | bundleReleaseJsAndAssets.dependsOn mergeReleaseAssets 74 | processReleaseResources.dependsOn bundleReleaseJsAndAssets 75 | } 76 | -------------------------------------------------------------------------------- /Example/android/app/src/main/java/com/example/MainActivity.java: -------------------------------------------------------------------------------- 1 | package com.example; 2 | 3 | import android.app.Activity; 4 | import android.os.Bundle; 5 | import android.view.KeyEvent; 6 | 7 | import com.facebook.react.LifecycleState; 8 | import com.facebook.react.ReactInstanceManager; 9 | import com.facebook.react.ReactRootView; 10 | import com.facebook.react.modules.core.DefaultHardwareBackBtnHandler; 11 | import com.facebook.react.shell.MainReactPackage; 12 | import com.facebook.soloader.SoLoader; 13 | 14 | public class MainActivity extends Activity implements DefaultHardwareBackBtnHandler { 15 | 16 | private ReactInstanceManager mReactInstanceManager; 17 | private ReactRootView mReactRootView; 18 | 19 | @Override 20 | protected void onCreate(Bundle savedInstanceState) { 21 | super.onCreate(savedInstanceState); 22 | mReactRootView = new ReactRootView(this); 23 | 24 | mReactInstanceManager = ReactInstanceManager.builder() 25 | .setApplication(getApplication()) 26 | .setBundleAssetName("index.android.bundle") 27 | .setJSMainModuleName("index.android") 28 | .addPackage(new MainReactPackage()) 29 | .setUseDeveloperSupport(BuildConfig.DEBUG) 30 | .setInitialLifecycleState(LifecycleState.RESUMED) 31 | .build(); 32 | 33 | mReactRootView.startReactApplication(mReactInstanceManager, "Example", null); 34 | 35 | setContentView(mReactRootView); 36 | } 37 | 38 | @Override 39 | public boolean onKeyUp(int keyCode, KeyEvent event) { 40 | if (keyCode == KeyEvent.KEYCODE_MENU && mReactInstanceManager != null) { 41 | mReactInstanceManager.showDevOptionsDialog(); 42 | return true; 43 | } 44 | return super.onKeyUp(keyCode, event); 45 | } 46 | 47 | @Override 48 | public void onBackPressed() { 49 | if (mReactInstanceManager != null) { 50 | mReactInstanceManager.onBackPressed(); 51 | } else { 52 | super.onBackPressed(); 53 | } 54 | } 55 | 56 | @Override 57 | public void invokeDefaultOnBackPressed() { 58 | super.onBackPressed(); 59 | } 60 | 61 | @Override 62 | protected void onPause() { 63 | super.onPause(); 64 | 65 | if (mReactInstanceManager != null) { 66 | mReactInstanceManager.onPause(); 67 | } 68 | } 69 | 70 | @Override 71 | protected void onResume() { 72 | super.onResume(); 73 | 74 | if (mReactInstanceManager != null) { 75 | mReactInstanceManager.onResume(this); 76 | } 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /Example/android/build.gradle: -------------------------------------------------------------------------------- 1 | // Top-level build file where you can add configuration options common to all sub-projects/modules. 2 | 3 | buildscript { 4 | repositories { 5 | jcenter() 6 | } 7 | dependencies { 8 | classpath 'com.android.tools.build:gradle:1.3.1' 9 | 10 | // NOTE: Do not place your application dependencies here; they belong 11 | // in the individual module build.gradle files 12 | } 13 | } 14 | 15 | allprojects { 16 | repositories { 17 | mavenLocal() 18 | jcenter() 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /Example/android/gradle.properties: -------------------------------------------------------------------------------- 1 | # Project-wide Gradle settings. 2 | 3 | # IDE (e.g. Android Studio) users: 4 | # Gradle settings configured through the IDE *will override* 5 | # any settings specified in this file. 6 | 7 | # For more details on how to configure your build environment visit 8 | # http://www.gradle.org/docs/current/userguide/build_environment.html 9 | 10 | # Specifies the JVM arguments used for the daemon process. 11 | # The setting is particularly useful for tweaking memory settings. 12 | # Default value: -Xmx10248m -XX:MaxPermSize=256m 13 | # org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8 14 | 15 | # When configured, Gradle will run in incubating parallel mode. 16 | # This option should only be used with decoupled projects. More details, visit 17 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects 18 | # org.gradle.parallel=true 19 | 20 | android.useDeprecatedNdk=true 21 | -------------------------------------------------------------------------------- /Example/android/settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name = 'Example' 2 | 3 | include ':app' 4 | -------------------------------------------------------------------------------- /Example/components/Error.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var React = require('react-native'); 4 | var {View, Text, StyleSheet} = React; 5 | var Button = require('react-native-button'); 6 | 7 | class Error extends React.Component { 8 | render(){ 9 | let Actions = this.props.routes; 10 | return ( 11 | 13 | {this.props.data} 14 | 15 | 16 | ); 17 | } 18 | } 19 | 20 | 21 | module.exports = Error; -------------------------------------------------------------------------------- /Example/components/Home.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var React = require('react-native'); 4 | var {View, Text, StyleSheet} = React; 5 | var Button = require('react-native-button'); 6 | 7 | class Register extends React.Component { 8 | render(){ 9 | let Actions = this.props.routes; 10 | return ( 11 | 12 | Home 13 | 14 | 15 | ); 16 | } 17 | } 18 | 19 | var styles = StyleSheet.create({ 20 | container: { 21 | flex: 1, 22 | justifyContent: 'center', 23 | alignItems: 'center', 24 | backgroundColor: '#F5FCFF', 25 | }, 26 | welcome: { 27 | fontSize: 20, 28 | textAlign: 'center', 29 | margin: 10, 30 | }, 31 | instructions: { 32 | textAlign: 'center', 33 | color: '#333333', 34 | marginBottom: 5, 35 | }, 36 | }); 37 | 38 | module.exports = Register; -------------------------------------------------------------------------------- /Example/components/Launch.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var React = require('react-native'); 4 | var {View, Text, StyleSheet, TouchableHighlight} = React; 5 | var Button = require('react-native-button'); 6 | 7 | class Launch extends React.Component { 8 | render(){ 9 | var Actions = this.props.routes; 10 | return ( 11 | 12 | Launch page 13 | 14 | 15 | 16 | 17 | 18 | ); 19 | } 20 | } 21 | 22 | var styles = StyleSheet.create({ 23 | container: { 24 | flex: 1, 25 | justifyContent: 'center', 26 | alignItems: 'center', 27 | backgroundColor: 'transparent', 28 | } 29 | }); 30 | 31 | module.exports = Launch; 32 | -------------------------------------------------------------------------------- /Example/components/Login.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var React = require('react-native'); 4 | var {View, Text, StyleSheet} = React; 5 | var Button = require('react-native-button'); 6 | 7 | class Login extends React.Component { 8 | render(){ 9 | let Actions = this.props.routes; 10 | 11 | return ( 12 | 13 | Login page: {this.props.data} 14 | 15 | 16 | ); 17 | } 18 | } 19 | 20 | var styles = StyleSheet.create({ 21 | container: { 22 | flex: 1, 23 | justifyContent: 'center', 24 | alignItems: 'center', 25 | backgroundColor: '#F5FCFF', 26 | }, 27 | welcome: { 28 | fontSize: 20, 29 | textAlign: 'center', 30 | margin: 10, 31 | }, 32 | instructions: { 33 | textAlign: 'center', 34 | color: '#333333', 35 | marginBottom: 5, 36 | }, 37 | }); 38 | 39 | 40 | 41 | module.exports = Login; -------------------------------------------------------------------------------- /Example/components/NavBar.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var NavigationBar = require('react-native-navbar'); 4 | var React = require('react-native'); 5 | var {StyleSheet,View} = React; 6 | var {Router, Route, Animations, Schema} = require('react-native-redux-router'); 7 | 8 | class NavBarBase extends React.Component { 9 | onPrev(){ 10 | var Actions = this.props.routes; 11 | if (this.props.onPrev){ 12 | this.props.onPrev(); 13 | return; 14 | } 15 | if (this.props.navigator && this.props.navigator.getCurrentRoutes().length > 1){ 16 | Actions.pop(); 17 | } 18 | } 19 | render() { 20 | var Actions = this.props.routes; 21 | console.log("Props : " + this.props); 22 | return 34 | } 35 | } 36 | class NavBar extends React.Component { 37 | render() { 38 | var Actions = this.props.routes; 39 | return } {...this.props} leftButton={{title:'Left', handler:this.props.onPrev || Actions.pop}}/> 40 | } 41 | } 42 | 43 | 44 | class NavBarModal extends React.Component { 45 | render() { 46 | var Actions = this.props.routes; 47 | return } nextTitle="Close" {...this.props} rightButton={{title:'Close', handler:this.props.onNext || Actions.pop}}/> 48 | } 49 | } 50 | 51 | var styles = StyleSheet.create({ 52 | navBar: { 53 | backgroundColor: '#0db0d9' 54 | }, 55 | }); 56 | 57 | 58 | module.exports = {NavBar, NavBarModal}; 59 | -------------------------------------------------------------------------------- /Example/components/Register.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var React = require('react-native'); 4 | var {View, Text, StyleSheet} = React; 5 | var Button = require('react-native-button'); 6 | 7 | class Register extends React.Component { 8 | render(){ 9 | let Actions = this.props.routes; 10 | return ( 11 | 12 | Register page 13 | 14 | 15 | 16 | ); 17 | } 18 | } 19 | 20 | var styles = StyleSheet.create({ 21 | container: { 22 | flex: 1, 23 | justifyContent: 'center', 24 | alignItems: 'center', 25 | backgroundColor: '#F5FCFF', 26 | }, 27 | welcome: { 28 | fontSize: 20, 29 | textAlign: 'center', 30 | margin: 10, 31 | }, 32 | instructions: { 33 | textAlign: 'center', 34 | color: '#333333', 35 | marginBottom: 5, 36 | }, 37 | }); 38 | 39 | module.exports = Register; -------------------------------------------------------------------------------- /Example/iOS/AppDelegate.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015-present, Facebook, Inc. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | */ 9 | 10 | #import 11 | 12 | @interface AppDelegate : UIResponder 13 | 14 | @property (nonatomic, strong) UIWindow *window; 15 | 16 | @end 17 | -------------------------------------------------------------------------------- /Example/iOS/AppDelegate.m: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015-present, Facebook, Inc. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | */ 9 | 10 | #import "AppDelegate.h" 11 | 12 | #import "RCTRootView.h" 13 | 14 | @implementation AppDelegate 15 | 16 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 17 | { 18 | NSURL *jsCodeLocation; 19 | 20 | /** 21 | * Loading JavaScript code - uncomment the one you want. 22 | * 23 | * OPTION 1 24 | * Load from development server. Start the server from the repository root: 25 | * 26 | * $ npm start 27 | * 28 | * To run on device, change `localhost` to the IP address of your computer 29 | * (you can get this by typing `ifconfig` into the terminal and selecting the 30 | * `inet` value under `en0:`) and make sure your computer and iOS device are 31 | * on the same Wi-Fi network. 32 | */ 33 | 34 | jsCodeLocation = [NSURL URLWithString:@"http://localhost:8081/index.ios.bundle?platform=ios&debug=true"]; 35 | 36 | /** 37 | * OPTION 2 38 | * Load from pre-bundled file on disk. To re-generate the static bundle 39 | * from the root of your project directory, run 40 | * 41 | * $ react-native bundle --minify 42 | * 43 | * see http://facebook.github.io/react-native/docs/runningondevice.html 44 | */ 45 | 46 | // jsCodeLocation = [[NSBundle mainBundle] URLForResource:@"main" withExtension:@"jsbundle"]; 47 | 48 | RCTRootView *rootView = [[RCTRootView alloc] initWithBundleURL:jsCodeLocation 49 | moduleName:@"Example" 50 | initialProperties:nil 51 | launchOptions:launchOptions]; 52 | 53 | self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds]; 54 | UIViewController *rootViewController = [[UIViewController alloc] init]; 55 | rootViewController.view = rootView; 56 | self.window.rootViewController = rootViewController; 57 | [self.window makeKeyAndVisible]; 58 | return YES; 59 | } 60 | 61 | @end 62 | -------------------------------------------------------------------------------- /Example/iOS/Base.lproj/LaunchScreen.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 21 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /Example/iOS/Example.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 00C302E51ABCBA2D00DB3ED1 /* libRCTActionSheet.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 00C302AC1ABCB8CE00DB3ED1 /* libRCTActionSheet.a */; }; 11 | 00C302E71ABCBA2D00DB3ED1 /* libRCTGeolocation.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 00C302BA1ABCB90400DB3ED1 /* libRCTGeolocation.a */; }; 12 | 00C302E81ABCBA2D00DB3ED1 /* libRCTImage.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 00C302C01ABCB91800DB3ED1 /* libRCTImage.a */; }; 13 | 00C302E91ABCBA2D00DB3ED1 /* libRCTNetwork.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 00C302DC1ABCB9D200DB3ED1 /* libRCTNetwork.a */; }; 14 | 00C302EA1ABCBA2D00DB3ED1 /* libRCTVibration.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 00C302E41ABCB9EE00DB3ED1 /* libRCTVibration.a */; }; 15 | 133E29F31AD74F7200F7D852 /* libRCTLinking.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 78C398B91ACF4ADC00677621 /* libRCTLinking.a */; }; 16 | 139105C61AF99C1200B5F7CC /* libRCTSettings.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 139105C11AF99BAD00B5F7CC /* libRCTSettings.a */; }; 17 | 139FDEF61B0652A700C62182 /* libRCTWebSocket.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 139FDEF41B06529B00C62182 /* libRCTWebSocket.a */; }; 18 | 13B07FBC1A68108700A75B9A /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB01A68108700A75B9A /* AppDelegate.m */; }; 19 | 13B07FBD1A68108700A75B9A /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB11A68108700A75B9A /* LaunchScreen.xib */; }; 20 | 13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB51A68108700A75B9A /* Images.xcassets */; }; 21 | 13B07FC11A68108700A75B9A /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB71A68108700A75B9A /* main.m */; }; 22 | 146834051AC3E58100842450 /* libReact.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 146834041AC3E56700842450 /* libReact.a */; }; 23 | 832341BD1AAA6AB300B99B32 /* libRCTText.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 832341B51AAA6A8300B99B32 /* libRCTText.a */; }; 24 | /* End PBXBuildFile section */ 25 | 26 | /* Begin PBXContainerItemProxy section */ 27 | 00C302AB1ABCB8CE00DB3ED1 /* PBXContainerItemProxy */ = { 28 | isa = PBXContainerItemProxy; 29 | containerPortal = 00C302A71ABCB8CE00DB3ED1 /* RCTActionSheet.xcodeproj */; 30 | proxyType = 2; 31 | remoteGlobalIDString = 134814201AA4EA6300B7C361; 32 | remoteInfo = RCTActionSheet; 33 | }; 34 | 00C302B91ABCB90400DB3ED1 /* PBXContainerItemProxy */ = { 35 | isa = PBXContainerItemProxy; 36 | containerPortal = 00C302B51ABCB90400DB3ED1 /* RCTGeolocation.xcodeproj */; 37 | proxyType = 2; 38 | remoteGlobalIDString = 134814201AA4EA6300B7C361; 39 | remoteInfo = RCTGeolocation; 40 | }; 41 | 00C302BF1ABCB91800DB3ED1 /* PBXContainerItemProxy */ = { 42 | isa = PBXContainerItemProxy; 43 | containerPortal = 00C302BB1ABCB91800DB3ED1 /* RCTImage.xcodeproj */; 44 | proxyType = 2; 45 | remoteGlobalIDString = 58B5115D1A9E6B3D00147676; 46 | remoteInfo = RCTImage; 47 | }; 48 | 00C302DB1ABCB9D200DB3ED1 /* PBXContainerItemProxy */ = { 49 | isa = PBXContainerItemProxy; 50 | containerPortal = 00C302D31ABCB9D200DB3ED1 /* RCTNetwork.xcodeproj */; 51 | proxyType = 2; 52 | remoteGlobalIDString = 58B511DB1A9E6C8500147676; 53 | remoteInfo = RCTNetwork; 54 | }; 55 | 00C302E31ABCB9EE00DB3ED1 /* PBXContainerItemProxy */ = { 56 | isa = PBXContainerItemProxy; 57 | containerPortal = 00C302DF1ABCB9EE00DB3ED1 /* RCTVibration.xcodeproj */; 58 | proxyType = 2; 59 | remoteGlobalIDString = 832C81801AAF6DEF007FA2F7; 60 | remoteInfo = RCTVibration; 61 | }; 62 | 139105C01AF99BAD00B5F7CC /* PBXContainerItemProxy */ = { 63 | isa = PBXContainerItemProxy; 64 | containerPortal = 139105B61AF99BAD00B5F7CC /* RCTSettings.xcodeproj */; 65 | proxyType = 2; 66 | remoteGlobalIDString = 134814201AA4EA6300B7C361; 67 | remoteInfo = RCTSettings; 68 | }; 69 | 139FDEF31B06529B00C62182 /* PBXContainerItemProxy */ = { 70 | isa = PBXContainerItemProxy; 71 | containerPortal = 139FDEE61B06529A00C62182 /* RCTWebSocket.xcodeproj */; 72 | proxyType = 2; 73 | remoteGlobalIDString = 3C86DF461ADF2C930047B81A; 74 | remoteInfo = RCTWebSocket; 75 | }; 76 | 146834031AC3E56700842450 /* PBXContainerItemProxy */ = { 77 | isa = PBXContainerItemProxy; 78 | containerPortal = 146833FF1AC3E56700842450 /* React.xcodeproj */; 79 | proxyType = 2; 80 | remoteGlobalIDString = 83CBBA2E1A601D0E00E9B192; 81 | remoteInfo = React; 82 | }; 83 | 78C398B81ACF4ADC00677621 /* PBXContainerItemProxy */ = { 84 | isa = PBXContainerItemProxy; 85 | containerPortal = 78C398B01ACF4ADC00677621 /* RCTLinking.xcodeproj */; 86 | proxyType = 2; 87 | remoteGlobalIDString = 134814201AA4EA6300B7C361; 88 | remoteInfo = RCTLinking; 89 | }; 90 | 832341B41AAA6A8300B99B32 /* PBXContainerItemProxy */ = { 91 | isa = PBXContainerItemProxy; 92 | containerPortal = 832341B01AAA6A8300B99B32 /* RCTText.xcodeproj */; 93 | proxyType = 2; 94 | remoteGlobalIDString = 58B5119B1A9E6C1200147676; 95 | remoteInfo = RCTText; 96 | }; 97 | /* End PBXContainerItemProxy section */ 98 | 99 | /* Begin PBXFileReference section */ 100 | 008F07F21AC5B25A0029DE68 /* main.jsbundle */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = main.jsbundle; sourceTree = ""; }; 101 | 00C302A71ABCB8CE00DB3ED1 /* RCTActionSheet.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTActionSheet.xcodeproj; path = "../node_modules/react-native/Libraries/ActionSheetIOS/RCTActionSheet.xcodeproj"; sourceTree = ""; }; 102 | 00C302B51ABCB90400DB3ED1 /* RCTGeolocation.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTGeolocation.xcodeproj; path = "../node_modules/react-native/Libraries/Geolocation/RCTGeolocation.xcodeproj"; sourceTree = ""; }; 103 | 00C302BB1ABCB91800DB3ED1 /* RCTImage.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTImage.xcodeproj; path = "../node_modules/react-native/Libraries/Image/RCTImage.xcodeproj"; sourceTree = ""; }; 104 | 00C302D31ABCB9D200DB3ED1 /* RCTNetwork.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTNetwork.xcodeproj; path = "../node_modules/react-native/Libraries/Network/RCTNetwork.xcodeproj"; sourceTree = ""; }; 105 | 00C302DF1ABCB9EE00DB3ED1 /* RCTVibration.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTVibration.xcodeproj; path = "../node_modules/react-native/Libraries/Vibration/RCTVibration.xcodeproj"; sourceTree = ""; }; 106 | 00E356F11AD99517003FC87E /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 107 | 00E356F21AD99517003FC87E /* ExampleTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ExampleTests.m; sourceTree = ""; }; 108 | 139105B61AF99BAD00B5F7CC /* RCTSettings.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTSettings.xcodeproj; path = "../node_modules/react-native/Libraries/Settings/RCTSettings.xcodeproj"; sourceTree = ""; }; 109 | 139FDEE61B06529A00C62182 /* RCTWebSocket.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTWebSocket.xcodeproj; path = "../node_modules/react-native/Libraries/WebSocket/RCTWebSocket.xcodeproj"; sourceTree = ""; }; 110 | 13B07F961A680F5B00A75B9A /* Example.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Example.app; sourceTree = BUILT_PRODUCTS_DIR; }; 111 | 13B07FAF1A68108700A75B9A /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AppDelegate.h; path = Example/AppDelegate.h; sourceTree = ""; }; 112 | 13B07FB01A68108700A75B9A /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = AppDelegate.m; path = Example/AppDelegate.m; sourceTree = ""; }; 113 | 13B07FB21A68108700A75B9A /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/LaunchScreen.xib; sourceTree = ""; }; 114 | 13B07FB51A68108700A75B9A /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Images.xcassets; path = Example/Images.xcassets; sourceTree = ""; }; 115 | 13B07FB61A68108700A75B9A /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Info.plist; path = Example/Info.plist; sourceTree = ""; }; 116 | 13B07FB71A68108700A75B9A /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = main.m; path = Example/main.m; sourceTree = ""; }; 117 | 146833FF1AC3E56700842450 /* React.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = React.xcodeproj; path = "../node_modules/react-native/React/React.xcodeproj"; sourceTree = ""; }; 118 | 78C398B01ACF4ADC00677621 /* RCTLinking.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTLinking.xcodeproj; path = "../node_modules/react-native/Libraries/LinkingIOS/RCTLinking.xcodeproj"; sourceTree = ""; }; 119 | 832341B01AAA6A8300B99B32 /* RCTText.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTText.xcodeproj; path = "../node_modules/react-native/Libraries/Text/RCTText.xcodeproj"; sourceTree = ""; }; 120 | /* End PBXFileReference section */ 121 | 122 | /* Begin PBXFrameworksBuildPhase section */ 123 | 13B07F8C1A680F5B00A75B9A /* Frameworks */ = { 124 | isa = PBXFrameworksBuildPhase; 125 | buildActionMask = 2147483647; 126 | files = ( 127 | 146834051AC3E58100842450 /* libReact.a in Frameworks */, 128 | 00C302E51ABCBA2D00DB3ED1 /* libRCTActionSheet.a in Frameworks */, 129 | 00C302E71ABCBA2D00DB3ED1 /* libRCTGeolocation.a in Frameworks */, 130 | 00C302E81ABCBA2D00DB3ED1 /* libRCTImage.a in Frameworks */, 131 | 133E29F31AD74F7200F7D852 /* libRCTLinking.a in Frameworks */, 132 | 00C302E91ABCBA2D00DB3ED1 /* libRCTNetwork.a in Frameworks */, 133 | 139105C61AF99C1200B5F7CC /* libRCTSettings.a in Frameworks */, 134 | 832341BD1AAA6AB300B99B32 /* libRCTText.a in Frameworks */, 135 | 00C302EA1ABCBA2D00DB3ED1 /* libRCTVibration.a in Frameworks */, 136 | 139FDEF61B0652A700C62182 /* libRCTWebSocket.a in Frameworks */, 137 | ); 138 | runOnlyForDeploymentPostprocessing = 0; 139 | }; 140 | /* End PBXFrameworksBuildPhase section */ 141 | 142 | /* Begin PBXGroup section */ 143 | 00C302A81ABCB8CE00DB3ED1 /* Products */ = { 144 | isa = PBXGroup; 145 | children = ( 146 | 00C302AC1ABCB8CE00DB3ED1 /* libRCTActionSheet.a */, 147 | ); 148 | name = Products; 149 | sourceTree = ""; 150 | }; 151 | 00C302B61ABCB90400DB3ED1 /* Products */ = { 152 | isa = PBXGroup; 153 | children = ( 154 | 00C302BA1ABCB90400DB3ED1 /* libRCTGeolocation.a */, 155 | ); 156 | name = Products; 157 | sourceTree = ""; 158 | }; 159 | 00C302BC1ABCB91800DB3ED1 /* Products */ = { 160 | isa = PBXGroup; 161 | children = ( 162 | 00C302C01ABCB91800DB3ED1 /* libRCTImage.a */, 163 | ); 164 | name = Products; 165 | sourceTree = ""; 166 | }; 167 | 00C302D41ABCB9D200DB3ED1 /* Products */ = { 168 | isa = PBXGroup; 169 | children = ( 170 | 00C302DC1ABCB9D200DB3ED1 /* libRCTNetwork.a */, 171 | ); 172 | name = Products; 173 | sourceTree = ""; 174 | }; 175 | 00C302E01ABCB9EE00DB3ED1 /* Products */ = { 176 | isa = PBXGroup; 177 | children = ( 178 | 00C302E41ABCB9EE00DB3ED1 /* libRCTVibration.a */, 179 | ); 180 | name = Products; 181 | sourceTree = ""; 182 | }; 183 | 00E356EF1AD99517003FC87E /* ExampleTests */ = { 184 | isa = PBXGroup; 185 | children = ( 186 | 00E356F21AD99517003FC87E /* ExampleTests.m */, 187 | 00E356F01AD99517003FC87E /* Supporting Files */, 188 | ); 189 | path = ExampleTests; 190 | sourceTree = ""; 191 | }; 192 | 00E356F01AD99517003FC87E /* Supporting Files */ = { 193 | isa = PBXGroup; 194 | children = ( 195 | 00E356F11AD99517003FC87E /* Info.plist */, 196 | ); 197 | name = "Supporting Files"; 198 | sourceTree = ""; 199 | }; 200 | 139105B71AF99BAD00B5F7CC /* Products */ = { 201 | isa = PBXGroup; 202 | children = ( 203 | 139105C11AF99BAD00B5F7CC /* libRCTSettings.a */, 204 | ); 205 | name = Products; 206 | sourceTree = ""; 207 | }; 208 | 139FDEE71B06529A00C62182 /* Products */ = { 209 | isa = PBXGroup; 210 | children = ( 211 | 139FDEF41B06529B00C62182 /* libRCTWebSocket.a */, 212 | ); 213 | name = Products; 214 | sourceTree = ""; 215 | }; 216 | 13B07FAE1A68108700A75B9A /* Example */ = { 217 | isa = PBXGroup; 218 | children = ( 219 | 008F07F21AC5B25A0029DE68 /* main.jsbundle */, 220 | 13B07FAF1A68108700A75B9A /* AppDelegate.h */, 221 | 13B07FB01A68108700A75B9A /* AppDelegate.m */, 222 | 13B07FB51A68108700A75B9A /* Images.xcassets */, 223 | 13B07FB61A68108700A75B9A /* Info.plist */, 224 | 13B07FB11A68108700A75B9A /* LaunchScreen.xib */, 225 | 13B07FB71A68108700A75B9A /* main.m */, 226 | ); 227 | name = Example; 228 | sourceTree = ""; 229 | }; 230 | 146834001AC3E56700842450 /* Products */ = { 231 | isa = PBXGroup; 232 | children = ( 233 | 146834041AC3E56700842450 /* libReact.a */, 234 | ); 235 | name = Products; 236 | sourceTree = ""; 237 | }; 238 | 78C398B11ACF4ADC00677621 /* Products */ = { 239 | isa = PBXGroup; 240 | children = ( 241 | 78C398B91ACF4ADC00677621 /* libRCTLinking.a */, 242 | ); 243 | name = Products; 244 | sourceTree = ""; 245 | }; 246 | 832341AE1AAA6A7D00B99B32 /* Libraries */ = { 247 | isa = PBXGroup; 248 | children = ( 249 | 146833FF1AC3E56700842450 /* React.xcodeproj */, 250 | 00C302A71ABCB8CE00DB3ED1 /* RCTActionSheet.xcodeproj */, 251 | 00C302B51ABCB90400DB3ED1 /* RCTGeolocation.xcodeproj */, 252 | 00C302BB1ABCB91800DB3ED1 /* RCTImage.xcodeproj */, 253 | 78C398B01ACF4ADC00677621 /* RCTLinking.xcodeproj */, 254 | 00C302D31ABCB9D200DB3ED1 /* RCTNetwork.xcodeproj */, 255 | 139105B61AF99BAD00B5F7CC /* RCTSettings.xcodeproj */, 256 | 832341B01AAA6A8300B99B32 /* RCTText.xcodeproj */, 257 | 00C302DF1ABCB9EE00DB3ED1 /* RCTVibration.xcodeproj */, 258 | 139FDEE61B06529A00C62182 /* RCTWebSocket.xcodeproj */, 259 | ); 260 | name = Libraries; 261 | sourceTree = ""; 262 | }; 263 | 832341B11AAA6A8300B99B32 /* Products */ = { 264 | isa = PBXGroup; 265 | children = ( 266 | 832341B51AAA6A8300B99B32 /* libRCTText.a */, 267 | ); 268 | name = Products; 269 | sourceTree = ""; 270 | }; 271 | 83CBB9F61A601CBA00E9B192 = { 272 | isa = PBXGroup; 273 | children = ( 274 | 13B07FAE1A68108700A75B9A /* Example */, 275 | 832341AE1AAA6A7D00B99B32 /* Libraries */, 276 | 00E356EF1AD99517003FC87E /* ExampleTests */, 277 | 83CBBA001A601CBA00E9B192 /* Products */, 278 | ); 279 | indentWidth = 2; 280 | sourceTree = ""; 281 | tabWidth = 2; 282 | }; 283 | 83CBBA001A601CBA00E9B192 /* Products */ = { 284 | isa = PBXGroup; 285 | children = ( 286 | 13B07F961A680F5B00A75B9A /* Example.app */, 287 | ); 288 | name = Products; 289 | sourceTree = ""; 290 | }; 291 | /* End PBXGroup section */ 292 | 293 | /* Begin PBXNativeTarget section */ 294 | 13B07F861A680F5B00A75B9A /* Example */ = { 295 | isa = PBXNativeTarget; 296 | buildConfigurationList = 13B07F931A680F5B00A75B9A /* Build configuration list for PBXNativeTarget "Example" */; 297 | buildPhases = ( 298 | 13B07F871A680F5B00A75B9A /* Sources */, 299 | 13B07F8C1A680F5B00A75B9A /* Frameworks */, 300 | 13B07F8E1A680F5B00A75B9A /* Resources */, 301 | 00DD1BFF1BD5951E006B06BC /* Bundle React Native code and images */, 302 | ); 303 | buildRules = ( 304 | ); 305 | dependencies = ( 306 | ); 307 | name = Example; 308 | productName = "Hello World"; 309 | productReference = 13B07F961A680F5B00A75B9A /* Example.app */; 310 | productType = "com.apple.product-type.application"; 311 | }; 312 | /* End PBXNativeTarget section */ 313 | 314 | /* Begin PBXProject section */ 315 | 83CBB9F71A601CBA00E9B192 /* Project object */ = { 316 | isa = PBXProject; 317 | attributes = { 318 | LastUpgradeCheck = 0610; 319 | ORGANIZATIONNAME = Facebook; 320 | }; 321 | buildConfigurationList = 83CBB9FA1A601CBA00E9B192 /* Build configuration list for PBXProject "Example" */; 322 | compatibilityVersion = "Xcode 3.2"; 323 | developmentRegion = English; 324 | hasScannedForEncodings = 0; 325 | knownRegions = ( 326 | en, 327 | Base, 328 | ); 329 | mainGroup = 83CBB9F61A601CBA00E9B192; 330 | productRefGroup = 83CBBA001A601CBA00E9B192 /* Products */; 331 | projectDirPath = ""; 332 | projectReferences = ( 333 | { 334 | ProductGroup = 00C302A81ABCB8CE00DB3ED1 /* Products */; 335 | ProjectRef = 00C302A71ABCB8CE00DB3ED1 /* RCTActionSheet.xcodeproj */; 336 | }, 337 | { 338 | ProductGroup = 00C302B61ABCB90400DB3ED1 /* Products */; 339 | ProjectRef = 00C302B51ABCB90400DB3ED1 /* RCTGeolocation.xcodeproj */; 340 | }, 341 | { 342 | ProductGroup = 00C302BC1ABCB91800DB3ED1 /* Products */; 343 | ProjectRef = 00C302BB1ABCB91800DB3ED1 /* RCTImage.xcodeproj */; 344 | }, 345 | { 346 | ProductGroup = 78C398B11ACF4ADC00677621 /* Products */; 347 | ProjectRef = 78C398B01ACF4ADC00677621 /* RCTLinking.xcodeproj */; 348 | }, 349 | { 350 | ProductGroup = 00C302D41ABCB9D200DB3ED1 /* Products */; 351 | ProjectRef = 00C302D31ABCB9D200DB3ED1 /* RCTNetwork.xcodeproj */; 352 | }, 353 | { 354 | ProductGroup = 139105B71AF99BAD00B5F7CC /* Products */; 355 | ProjectRef = 139105B61AF99BAD00B5F7CC /* RCTSettings.xcodeproj */; 356 | }, 357 | { 358 | ProductGroup = 832341B11AAA6A8300B99B32 /* Products */; 359 | ProjectRef = 832341B01AAA6A8300B99B32 /* RCTText.xcodeproj */; 360 | }, 361 | { 362 | ProductGroup = 00C302E01ABCB9EE00DB3ED1 /* Products */; 363 | ProjectRef = 00C302DF1ABCB9EE00DB3ED1 /* RCTVibration.xcodeproj */; 364 | }, 365 | { 366 | ProductGroup = 139FDEE71B06529A00C62182 /* Products */; 367 | ProjectRef = 139FDEE61B06529A00C62182 /* RCTWebSocket.xcodeproj */; 368 | }, 369 | { 370 | ProductGroup = 146834001AC3E56700842450 /* Products */; 371 | ProjectRef = 146833FF1AC3E56700842450 /* React.xcodeproj */; 372 | }, 373 | ); 374 | projectRoot = ""; 375 | targets = ( 376 | 13B07F861A680F5B00A75B9A /* Example */, 377 | ); 378 | }; 379 | /* End PBXProject section */ 380 | 381 | /* Begin PBXReferenceProxy section */ 382 | 00C302AC1ABCB8CE00DB3ED1 /* libRCTActionSheet.a */ = { 383 | isa = PBXReferenceProxy; 384 | fileType = archive.ar; 385 | path = libRCTActionSheet.a; 386 | remoteRef = 00C302AB1ABCB8CE00DB3ED1 /* PBXContainerItemProxy */; 387 | sourceTree = BUILT_PRODUCTS_DIR; 388 | }; 389 | 00C302BA1ABCB90400DB3ED1 /* libRCTGeolocation.a */ = { 390 | isa = PBXReferenceProxy; 391 | fileType = archive.ar; 392 | path = libRCTGeolocation.a; 393 | remoteRef = 00C302B91ABCB90400DB3ED1 /* PBXContainerItemProxy */; 394 | sourceTree = BUILT_PRODUCTS_DIR; 395 | }; 396 | 00C302C01ABCB91800DB3ED1 /* libRCTImage.a */ = { 397 | isa = PBXReferenceProxy; 398 | fileType = archive.ar; 399 | path = libRCTImage.a; 400 | remoteRef = 00C302BF1ABCB91800DB3ED1 /* PBXContainerItemProxy */; 401 | sourceTree = BUILT_PRODUCTS_DIR; 402 | }; 403 | 00C302DC1ABCB9D200DB3ED1 /* libRCTNetwork.a */ = { 404 | isa = PBXReferenceProxy; 405 | fileType = archive.ar; 406 | path = libRCTNetwork.a; 407 | remoteRef = 00C302DB1ABCB9D200DB3ED1 /* PBXContainerItemProxy */; 408 | sourceTree = BUILT_PRODUCTS_DIR; 409 | }; 410 | 00C302E41ABCB9EE00DB3ED1 /* libRCTVibration.a */ = { 411 | isa = PBXReferenceProxy; 412 | fileType = archive.ar; 413 | path = libRCTVibration.a; 414 | remoteRef = 00C302E31ABCB9EE00DB3ED1 /* PBXContainerItemProxy */; 415 | sourceTree = BUILT_PRODUCTS_DIR; 416 | }; 417 | 139105C11AF99BAD00B5F7CC /* libRCTSettings.a */ = { 418 | isa = PBXReferenceProxy; 419 | fileType = archive.ar; 420 | path = libRCTSettings.a; 421 | remoteRef = 139105C01AF99BAD00B5F7CC /* PBXContainerItemProxy */; 422 | sourceTree = BUILT_PRODUCTS_DIR; 423 | }; 424 | 139FDEF41B06529B00C62182 /* libRCTWebSocket.a */ = { 425 | isa = PBXReferenceProxy; 426 | fileType = archive.ar; 427 | path = libRCTWebSocket.a; 428 | remoteRef = 139FDEF31B06529B00C62182 /* PBXContainerItemProxy */; 429 | sourceTree = BUILT_PRODUCTS_DIR; 430 | }; 431 | 146834041AC3E56700842450 /* libReact.a */ = { 432 | isa = PBXReferenceProxy; 433 | fileType = archive.ar; 434 | path = libReact.a; 435 | remoteRef = 146834031AC3E56700842450 /* PBXContainerItemProxy */; 436 | sourceTree = BUILT_PRODUCTS_DIR; 437 | }; 438 | 78C398B91ACF4ADC00677621 /* libRCTLinking.a */ = { 439 | isa = PBXReferenceProxy; 440 | fileType = archive.ar; 441 | path = libRCTLinking.a; 442 | remoteRef = 78C398B81ACF4ADC00677621 /* PBXContainerItemProxy */; 443 | sourceTree = BUILT_PRODUCTS_DIR; 444 | }; 445 | 832341B51AAA6A8300B99B32 /* libRCTText.a */ = { 446 | isa = PBXReferenceProxy; 447 | fileType = archive.ar; 448 | path = libRCTText.a; 449 | remoteRef = 832341B41AAA6A8300B99B32 /* PBXContainerItemProxy */; 450 | sourceTree = BUILT_PRODUCTS_DIR; 451 | }; 452 | /* End PBXReferenceProxy section */ 453 | 454 | /* Begin PBXResourcesBuildPhase section */ 455 | 13B07F8E1A680F5B00A75B9A /* Resources */ = { 456 | isa = PBXResourcesBuildPhase; 457 | buildActionMask = 2147483647; 458 | files = ( 459 | 13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */, 460 | 13B07FBD1A68108700A75B9A /* LaunchScreen.xib in Resources */, 461 | ); 462 | runOnlyForDeploymentPostprocessing = 0; 463 | }; 464 | /* End PBXResourcesBuildPhase section */ 465 | 466 | /* Begin PBXShellScriptBuildPhase section */ 467 | 00DD1BFF1BD5951E006B06BC /* Bundle React Native code and images */ = { 468 | isa = PBXShellScriptBuildPhase; 469 | buildActionMask = 2147483647; 470 | files = ( 471 | ); 472 | inputPaths = ( 473 | ); 474 | name = "Bundle React Native code and images"; 475 | outputPaths = ( 476 | ); 477 | runOnlyForDeploymentPostprocessing = 0; 478 | shellPath = /bin/sh; 479 | shellScript = "../node_modules/react-native/packager/react-native-xcode.sh"; 480 | }; 481 | /* End PBXShellScriptBuildPhase section */ 482 | 483 | /* Begin PBXSourcesBuildPhase section */ 484 | 13B07F871A680F5B00A75B9A /* Sources */ = { 485 | isa = PBXSourcesBuildPhase; 486 | buildActionMask = 2147483647; 487 | files = ( 488 | 13B07FBC1A68108700A75B9A /* AppDelegate.m in Sources */, 489 | 13B07FC11A68108700A75B9A /* main.m in Sources */, 490 | ); 491 | runOnlyForDeploymentPostprocessing = 0; 492 | }; 493 | /* End PBXSourcesBuildPhase section */ 494 | 495 | /* Begin PBXVariantGroup section */ 496 | 13B07FB11A68108700A75B9A /* LaunchScreen.xib */ = { 497 | isa = PBXVariantGroup; 498 | children = ( 499 | 13B07FB21A68108700A75B9A /* Base */, 500 | ); 501 | name = LaunchScreen.xib; 502 | path = Example; 503 | sourceTree = ""; 504 | }; 505 | /* End PBXVariantGroup section */ 506 | 507 | /* Begin XCBuildConfiguration section */ 508 | 13B07F941A680F5B00A75B9A /* Debug */ = { 509 | isa = XCBuildConfiguration; 510 | buildSettings = { 511 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 512 | DEAD_CODE_STRIPPING = NO; 513 | HEADER_SEARCH_PATHS = ( 514 | "$(inherited)", 515 | /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include, 516 | "$(SRCROOT)/../node_modules/react-native/React/**", 517 | ); 518 | INFOPLIST_FILE = Example/Info.plist; 519 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 520 | OTHER_LDFLAGS = "-ObjC"; 521 | PRODUCT_NAME = Example; 522 | }; 523 | name = Debug; 524 | }; 525 | 13B07F951A680F5B00A75B9A /* Release */ = { 526 | isa = XCBuildConfiguration; 527 | buildSettings = { 528 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 529 | HEADER_SEARCH_PATHS = ( 530 | "$(inherited)", 531 | /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include, 532 | "$(SRCROOT)/../node_modules/react-native/React/**", 533 | ); 534 | INFOPLIST_FILE = Example/Info.plist; 535 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 536 | OTHER_LDFLAGS = "-ObjC"; 537 | PRODUCT_NAME = Example; 538 | }; 539 | name = Release; 540 | }; 541 | 83CBBA201A601CBA00E9B192 /* Debug */ = { 542 | isa = XCBuildConfiguration; 543 | buildSettings = { 544 | ALWAYS_SEARCH_USER_PATHS = NO; 545 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 546 | CLANG_CXX_LIBRARY = "libc++"; 547 | CLANG_ENABLE_MODULES = YES; 548 | CLANG_ENABLE_OBJC_ARC = YES; 549 | CLANG_WARN_BOOL_CONVERSION = YES; 550 | CLANG_WARN_CONSTANT_CONVERSION = YES; 551 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 552 | CLANG_WARN_EMPTY_BODY = YES; 553 | CLANG_WARN_ENUM_CONVERSION = YES; 554 | CLANG_WARN_INT_CONVERSION = YES; 555 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 556 | CLANG_WARN_UNREACHABLE_CODE = YES; 557 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 558 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 559 | COPY_PHASE_STRIP = NO; 560 | ENABLE_STRICT_OBJC_MSGSEND = YES; 561 | GCC_C_LANGUAGE_STANDARD = gnu99; 562 | GCC_DYNAMIC_NO_PIC = NO; 563 | GCC_OPTIMIZATION_LEVEL = 0; 564 | GCC_PREPROCESSOR_DEFINITIONS = ( 565 | "DEBUG=1", 566 | "$(inherited)", 567 | ); 568 | GCC_SYMBOLS_PRIVATE_EXTERN = NO; 569 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 570 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 571 | GCC_WARN_UNDECLARED_SELECTOR = YES; 572 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 573 | GCC_WARN_UNUSED_FUNCTION = YES; 574 | GCC_WARN_UNUSED_VARIABLE = YES; 575 | HEADER_SEARCH_PATHS = ( 576 | "$(inherited)", 577 | /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include, 578 | "$(SRCROOT)/../node_modules/react-native/React/**", 579 | ); 580 | IPHONEOS_DEPLOYMENT_TARGET = 7.0; 581 | MTL_ENABLE_DEBUG_INFO = YES; 582 | ONLY_ACTIVE_ARCH = YES; 583 | SDKROOT = iphoneos; 584 | }; 585 | name = Debug; 586 | }; 587 | 83CBBA211A601CBA00E9B192 /* Release */ = { 588 | isa = XCBuildConfiguration; 589 | buildSettings = { 590 | ALWAYS_SEARCH_USER_PATHS = NO; 591 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 592 | CLANG_CXX_LIBRARY = "libc++"; 593 | CLANG_ENABLE_MODULES = YES; 594 | CLANG_ENABLE_OBJC_ARC = YES; 595 | CLANG_WARN_BOOL_CONVERSION = YES; 596 | CLANG_WARN_CONSTANT_CONVERSION = YES; 597 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 598 | CLANG_WARN_EMPTY_BODY = YES; 599 | CLANG_WARN_ENUM_CONVERSION = YES; 600 | CLANG_WARN_INT_CONVERSION = YES; 601 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 602 | CLANG_WARN_UNREACHABLE_CODE = YES; 603 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 604 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 605 | COPY_PHASE_STRIP = YES; 606 | ENABLE_NS_ASSERTIONS = NO; 607 | ENABLE_STRICT_OBJC_MSGSEND = YES; 608 | GCC_C_LANGUAGE_STANDARD = gnu99; 609 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 610 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 611 | GCC_WARN_UNDECLARED_SELECTOR = YES; 612 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 613 | GCC_WARN_UNUSED_FUNCTION = YES; 614 | GCC_WARN_UNUSED_VARIABLE = YES; 615 | HEADER_SEARCH_PATHS = ( 616 | "$(inherited)", 617 | /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include, 618 | "$(SRCROOT)/../node_modules/react-native/React/**", 619 | ); 620 | IPHONEOS_DEPLOYMENT_TARGET = 7.0; 621 | MTL_ENABLE_DEBUG_INFO = NO; 622 | SDKROOT = iphoneos; 623 | VALIDATE_PRODUCT = YES; 624 | }; 625 | name = Release; 626 | }; 627 | /* End XCBuildConfiguration section */ 628 | 629 | /* Begin XCConfigurationList section */ 630 | 13B07F931A680F5B00A75B9A /* Build configuration list for PBXNativeTarget "Example" */ = { 631 | isa = XCConfigurationList; 632 | buildConfigurations = ( 633 | 13B07F941A680F5B00A75B9A /* Debug */, 634 | 13B07F951A680F5B00A75B9A /* Release */, 635 | ); 636 | defaultConfigurationIsVisible = 0; 637 | defaultConfigurationName = Release; 638 | }; 639 | 83CBB9FA1A601CBA00E9B192 /* Build configuration list for PBXProject "Example" */ = { 640 | isa = XCConfigurationList; 641 | buildConfigurations = ( 642 | 83CBBA201A601CBA00E9B192 /* Debug */, 643 | 83CBBA211A601CBA00E9B192 /* Release */, 644 | ); 645 | defaultConfigurationIsVisible = 0; 646 | defaultConfigurationName = Release; 647 | }; 648 | /* End XCConfigurationList section */ 649 | }; 650 | rootObject = 83CBB9F71A601CBA00E9B192 /* Project object */; 651 | } 652 | -------------------------------------------------------------------------------- /Example/iOS/Example.xcodeproj/xcshareddata/xcschemes/Example.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 29 | 35 | 36 | 37 | 38 | 39 | 44 | 45 | 47 | 53 | 54 | 55 | 56 | 57 | 63 | 64 | 65 | 66 | 75 | 77 | 83 | 84 | 85 | 86 | 87 | 88 | 94 | 96 | 102 | 103 | 104 | 105 | 107 | 108 | 111 | 112 | 113 | -------------------------------------------------------------------------------- /Example/iOS/Example/AppDelegate.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015-present, Facebook, Inc. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | */ 9 | 10 | #import 11 | 12 | @interface AppDelegate : UIResponder 13 | 14 | @property (nonatomic, strong) UIWindow *window; 15 | 16 | @end 17 | -------------------------------------------------------------------------------- /Example/iOS/Example/AppDelegate.m: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015-present, Facebook, Inc. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | */ 9 | 10 | #import "AppDelegate.h" 11 | 12 | #import "RCTRootView.h" 13 | 14 | @implementation AppDelegate 15 | 16 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 17 | { 18 | NSURL *jsCodeLocation; 19 | 20 | /** 21 | * Loading JavaScript code - uncomment the one you want. 22 | * 23 | * OPTION 1 24 | * Load from development server. Start the server from the repository root: 25 | * 26 | * $ npm start 27 | * 28 | * To run on device, change `localhost` to the IP address of your computer 29 | * (you can get this by typing `ifconfig` into the terminal and selecting the 30 | * `inet` value under `en0:`) and make sure your computer and iOS device are 31 | * on the same Wi-Fi network. 32 | */ 33 | 34 | jsCodeLocation = [NSURL URLWithString:@"http://localhost:8081/index.ios.bundle?platform=ios&dev=true"]; 35 | 36 | /** 37 | * OPTION 2 38 | * Load from pre-bundled file on disk. The static bundle is automatically 39 | * generated by "Bundle React Native code and images" build step. 40 | */ 41 | 42 | // jsCodeLocation = [[NSBundle mainBundle] URLForResource:@"main" withExtension:@"jsbundle"]; 43 | 44 | RCTRootView *rootView = [[RCTRootView alloc] initWithBundleURL:jsCodeLocation 45 | moduleName:@"Example" 46 | initialProperties:nil 47 | launchOptions:launchOptions]; 48 | 49 | self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds]; 50 | UIViewController *rootViewController = [[UIViewController alloc] init]; 51 | rootViewController.view = rootView; 52 | self.window.rootViewController = rootViewController; 53 | [self.window makeKeyAndVisible]; 54 | return YES; 55 | } 56 | 57 | @end 58 | -------------------------------------------------------------------------------- /Example/iOS/Example/Base.lproj/LaunchScreen.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 21 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /Example/iOS/Example/Images.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "29x29", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "29x29", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "40x40", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "40x40", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "size" : "60x60", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "size" : "60x60", 31 | "scale" : "3x" 32 | } 33 | ], 34 | "info" : { 35 | "version" : 1, 36 | "author" : "xcode" 37 | } 38 | } -------------------------------------------------------------------------------- /Example/iOS/Example/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | org.reactjs.native.example.$(PRODUCT_NAME:rfc1034identifier) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | LSRequiresIPhoneOS 24 | 25 | UILaunchStoryboardName 26 | LaunchScreen 27 | UIRequiredDeviceCapabilities 28 | 29 | armv7 30 | 31 | UISupportedInterfaceOrientations 32 | 33 | UIInterfaceOrientationPortrait 34 | UIInterfaceOrientationLandscapeLeft 35 | UIInterfaceOrientationLandscapeRight 36 | 37 | UIViewControllerBasedStatusBarAppearance 38 | 39 | NSLocationWhenInUseUsageDescription 40 | 41 | NSAppTransportSecurity 42 | 43 | 44 | NSAllowsArbitraryLoads 45 | 46 | 47 | 48 | 49 | -------------------------------------------------------------------------------- /Example/iOS/Example/main.m: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015-present, Facebook, Inc. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | */ 9 | 10 | #import 11 | 12 | #import "AppDelegate.h" 13 | 14 | int main(int argc, char * argv[]) { 15 | @autoreleasepool { 16 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /Example/iOS/ExampleTests/ExampleTests.m: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015-present, Facebook, Inc. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | */ 9 | 10 | #import 11 | #import 12 | 13 | #import "RCTLog.h" 14 | #import "RCTRootView.h" 15 | 16 | #define TIMEOUT_SECONDS 240 17 | #define TEXT_TO_LOOK_FOR @"Welcome to React Native!" 18 | 19 | @interface ExampleTests : XCTestCase 20 | 21 | @end 22 | 23 | @implementation ExampleTests 24 | 25 | - (BOOL)findSubviewInView:(UIView *)view matching:(BOOL(^)(UIView *view))test 26 | { 27 | if (test(view)) { 28 | return YES; 29 | } 30 | for (UIView *subview in [view subviews]) { 31 | if ([self findSubviewInView:subview matching:test]) { 32 | return YES; 33 | } 34 | } 35 | return NO; 36 | } 37 | 38 | - (void)testRendersWelcomeScreen 39 | { 40 | UIViewController *vc = [[[[UIApplication sharedApplication] delegate] window] rootViewController]; 41 | NSDate *date = [NSDate dateWithTimeIntervalSinceNow:TIMEOUT_SECONDS]; 42 | BOOL foundElement = NO; 43 | 44 | __block NSString *redboxError = nil; 45 | RCTSetLogFunction(^(RCTLogLevel level, NSString *fileName, NSNumber *lineNumber, NSString *message) { 46 | if (level >= RCTLogLevelError) { 47 | redboxError = message; 48 | } 49 | }); 50 | 51 | while ([date timeIntervalSinceNow] > 0 && !foundElement && !redboxError) { 52 | [[NSRunLoop mainRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate dateWithTimeIntervalSinceNow:0.1]]; 53 | [[NSRunLoop mainRunLoop] runMode:NSRunLoopCommonModes beforeDate:[NSDate dateWithTimeIntervalSinceNow:0.1]]; 54 | 55 | foundElement = [self findSubviewInView:vc.view matching:^BOOL(UIView *view) { 56 | if ([view.accessibilityLabel isEqualToString:TEXT_TO_LOOK_FOR]) { 57 | return YES; 58 | } 59 | return NO; 60 | }]; 61 | } 62 | 63 | RCTSetLogFunction(RCTDefaultLogFunction); 64 | 65 | XCTAssertNil(redboxError, @"RedBox error: %@", redboxError); 66 | XCTAssertTrue(foundElement, @"Couldn't find element with text '%@' in %d seconds", TEXT_TO_LOOK_FOR, TIMEOUT_SECONDS); 67 | } 68 | 69 | 70 | @end 71 | -------------------------------------------------------------------------------- /Example/iOS/ExampleTests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | org.reactjs.native.example.$(PRODUCT_NAME:rfc1034identifier) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | 24 | 25 | -------------------------------------------------------------------------------- /Example/iOS/Images.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "29x29", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "29x29", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "40x40", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "40x40", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "size" : "60x60", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "size" : "60x60", 31 | "scale" : "3x" 32 | } 33 | ], 34 | "info" : { 35 | "version" : 1, 36 | "author" : "xcode" 37 | } 38 | } -------------------------------------------------------------------------------- /Example/iOS/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | org.reactjs.native.example.$(PRODUCT_NAME:rfc1034identifier) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | LSRequiresIPhoneOS 24 | 25 | UILaunchStoryboardName 26 | LaunchScreen 27 | UIRequiredDeviceCapabilities 28 | 29 | armv7 30 | 31 | UISupportedInterfaceOrientations 32 | 33 | UIInterfaceOrientationPortrait 34 | UIInterfaceOrientationLandscapeLeft 35 | UIInterfaceOrientationLandscapeRight 36 | 37 | UIViewControllerBasedStatusBarAppearance 38 | 39 | NSLocationWhenInUseUsageDescription 40 | 41 | NSAppTransportSecurity 42 | 43 | NSAllowsArbitraryLoads 44 | 45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /Example/iOS/main.m: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015-present, Facebook, Inc. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | */ 9 | 10 | #import 11 | 12 | #import "AppDelegate.h" 13 | 14 | int main(int argc, char * argv[]) { 15 | @autoreleasepool { 16 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /Example/index.ios.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var React = require('react-native'); 4 | var {AppRegistry, StyleSheet,Text,View} = React; 5 | var Launch = require('./components/Launch'); 6 | var Register = require('./components/Register'); 7 | var Login = require('./components/Login'); 8 | var {Router, routerReducer, Route, Container, Animations, Schema} = require('react-native-redux-router'); 9 | var {NavBar, NavBarModal} = require('./components/NavBar'); 10 | var Error = require('./components/Error'); 11 | var Home = require('./components/Home'); 12 | 13 | import { createStore, combineReducers, applyMiddleware } from 'redux'; 14 | import { Provider } from 'react-redux/native'; 15 | import createLogger from 'redux-logger'; 16 | 17 | const loggerMiddleWare = createLogger(); 18 | 19 | const createStoreWithMiddleware = applyMiddleware(loggerMiddleWare)(createStore); 20 | const reducer = combineReducers({routerReducer}); 21 | let store = createStoreWithMiddleware(reducer); 22 | 23 | class App extends React.Component { 24 | render(){ 25 | return ( 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | ); 44 | } 45 | } 46 | class Example extends React.Component { 47 | render() { 48 | return ( 49 | 50 | {() => } 51 | 52 | ); 53 | } 54 | } 55 | 56 | AppRegistry.registerComponent('Example', () => Example); 57 | -------------------------------------------------------------------------------- /Example/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Example", 3 | "version": "0.0.1", 4 | "private": true, 5 | "scripts": { 6 | "start": "node_modules/react-native/packager/packager.sh", 7 | "clean": "cd node_modules; find . -name .babelrc | grep -v packager | xargs rm" 8 | }, 9 | "dependencies": { 10 | "react-native": "0.17.0", 11 | "react-native-button": "~1.2.1", 12 | "react-native-navbar": "~1.1.6", 13 | "react-native-redux-router": "^1.0.0", 14 | "react-native-tabs": "^0.1.10", 15 | "react-redux": "^3.1.2", 16 | "redux": "^3.0.5", 17 | "redux-logger": "*" 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2015, aksonov 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are met: 6 | 7 | * Redistributions of source code must retain the above copyright notice, this 8 | list of conditions and the following disclaimer. 9 | 10 | * Redistributions in binary form must reproduce the above copyright notice, 11 | this list of conditions and the following disclaimer in the documentation 12 | and/or other materials provided with the distribution. 13 | 14 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 15 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 17 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 18 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 20 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 21 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 22 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 23 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 | 25 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # react-native-redux-router 2 | React Native Router using Redux architecture 3 | 4 | ## Important notice 5 | I've decided to stop supporting this component in favor to new release react-native-router-flux (https://github.com/aksonov/react-native-router-flux). 6 | The new version doesn't depend from concrete Flux/Redux implementation and allow you to build nested navigators easily. Also it allows to intercept route 'actions' 7 | from your store(s). 8 | 9 | ## Why I need to use it? 10 | - Use Redux actions to replace/push/pop screens with easy syntax like Actions.login for navigation to login screen 11 | - Forget about passing navigator object to all React elements, use actions from anywhere in your UI code. 12 | - Configure all of your screens ("routes") once (define animations, nav bars, etc.), at one place and then just use short actions commands. For example if you use some special animation for Login screen, you don't need to code it anywhere where an user should be redirected to login screen. 13 | - Use route "schemas" to define common property for some screens. For example some screens are "modal" (i.e. have animation from bottom and have Cancel/Close nav button), so you could define group for them to avoid any code repetition. 14 | - Use popup with Redux actions (see Error popup within Example project) 15 | - Hide nav bar for some screens easily 16 | 17 | ## Example 18 | ![demo-2](https://cloud.githubusercontent.com/assets/1321329/9466261/de64558e-4b33-11e5-8ada-0fcd49442769.gif) 19 | 20 | 21 | ```javascript 22 | 'use strict'; 23 | 24 | var React = require('react-native'); 25 | var {AppRegistry, StyleSheet,Text,View} = React; 26 | var Launch = require('./components/Launch'); 27 | var Register = require('./components/Register'); 28 | var Login = require('./components/Login'); 29 | var {Router, routerReducer, Route, Container, Animations, Schema} = require('react-native-redux-router'); 30 | var {NavBar, NavBarModal} = require('./components/NavBar'); 31 | var Error = require('./components/Error'); 32 | var Home = require('./components/Home'); 33 | 34 | import { createStore, combineReducers } from 'redux'; 35 | import { Provider } from 'react-redux/native'; 36 | 37 | let store = createStore(combineReducers({routerReducer})); 38 | 39 | class App extends React.Component { 40 | render(){ 41 | return ( 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | ); 60 | } 61 | } 62 | class Example extends React.Component { 63 | render() { 64 | return ( 65 | 66 | {() => } 67 | 68 | ); 69 | } 70 | } 71 | 72 | AppRegistry.registerComponent('Example', () => Example); 73 | ``` 74 | 75 | components/Launch.js (initial screen) 76 | ```javascript 77 | 'use strict'; 78 | 79 | var React = require('react-native'); 80 | var {View, Text, StyleSheet, TouchableHighlight} = React; 81 | var Button = require('react-native-button'); 82 | var {Actions} = require('react-native-redux-router'); 83 | 84 | class Launch extends React.Component { 85 | render(){ 86 | return ( 87 | 88 | Launch page 89 | 90 | 91 | 92 | 93 | 94 | ); 95 | 96 | } 97 | } 98 | 99 | var styles = StyleSheet.create({ 100 | container: { 101 | flex: 1, 102 | justifyContent: 'center', 103 | alignItems: 'center', 104 | backgroundColor: 'transparent', 105 | } 106 | }); 107 | 108 | module.exports = Launch; 109 | ``` 110 | 111 | ## Getting started 112 | 1. `npm install react-native-redux-router --save` 113 | 2. In top-level index.js: 114 | * Define Route for each app screen. Its 'type' attribute is 'push' by default, but you also could define 'replace', so navigator will replace current route with new route. 115 | 'component' attribute is React component class which will be created for this route and all route attributes will be passed to it. 116 | 'name' is unique name of Route. 117 | * If some your Routes have common attributes, you may define Schema element and just use 'schema' attribute for 'route' 118 | * If you want to define some your custom actions, just add 'Action' element inside Router. 119 | 3. In any component: 120 | * var {Actions} = require('react-native-redux-router'); 121 | * Actions.ACTION_NAME(PARAMS) will call appropriate action and params will be passed to next screen. In case you want to fire 'route' actions from inner component, you should use redux import Actions from this component (not from props), use connect method for your component and use ()=>this.props.dispatch(Actions.ACTION_NAME(PARAM) 122 | 123 | 124 | -------------------------------------------------------------------------------- /actions.js: -------------------------------------------------------------------------------- 1 | export const PUSH = 'PUSH'; 2 | export const POP = 'POP'; 3 | export const DISMISS = 'DISMISS'; 4 | export const RESET = 'RESET' 5 | export const INIT = 'INIT' 6 | export const CUSTOM = 'CUSTOM' 7 | export const REPLACE = 'REPLACE' 8 | export const SELECT = 'SELECT' 9 | 10 | function filterParam(data){ 11 | if (typeof(data)!='object') 12 | return data; 13 | if (!data){ 14 | return; 15 | } 16 | var proto = (data||{}).constructor.name; 17 | // avoid passing React Native parameters 18 | if (proto != 'Object'){ 19 | data = {}; 20 | } 21 | if (data.data){ 22 | data.data = filterParam(data.data); 23 | } 24 | return data; 25 | } 26 | 27 | let CoreActions = { 28 | push: function(data) { 29 | return { 30 | ... filterParam(data), 31 | type: PUSH 32 | } 33 | }, 34 | 35 | pop: function(data = {}) { 36 | return { 37 | ... filterParam(data), 38 | type: POP 39 | } 40 | }, 41 | 42 | dismiss: function(data) { 43 | return { 44 | ... filterParam(data), 45 | type: DISMISS 46 | } 47 | }, 48 | 49 | reset: function(initial) { 50 | if (!initial) { 51 | throw new Error("Param should be non-empty"); 52 | } 53 | return { 54 | initial, 55 | type: RESET 56 | } 57 | }, 58 | 59 | init: function(initial) { 60 | return { 61 | initial, 62 | type: INIT 63 | } 64 | }, 65 | 66 | custom: function(data) { 67 | return { 68 | ... filterParam(data), 69 | type: CUSTOM 70 | } 71 | }, 72 | 73 | replace: function(data) { 74 | return { 75 | ... filterParam(data), 76 | type: REPLACE 77 | } 78 | }, 79 | 80 | select: function(data) { 81 | return { 82 | ... filterParam(data), 83 | type: SELECT 84 | } 85 | } 86 | } 87 | 88 | let Actions = {... CoreActions} 89 | 90 | export {CoreActions, Actions}; 91 | 92 | 93 | 94 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactNative from 'react-native'; 3 | const {View, Navigator, Text, TouchableWithoutFeedback, StyleSheet} = ReactNative; 4 | import {Actions, CoreActions} from './actions'; 5 | import {INIT, PUSH, REPLACE, POP, DISMISS, RESET} from './actions'; 6 | 7 | import routerReducer from './reducer'; 8 | import Animations from './Animations'; 9 | import { connect } from 'react-redux'; 10 | import { bindActionCreators } from 'redux'; 11 | 12 | // schema class represents schema for routes and it is processed inside Router component 13 | class Schema extends React.Component { 14 | className(){ 15 | return "Schema"; 16 | } 17 | render(){ 18 | return null; 19 | } 20 | } 21 | 22 | // action class represents simple action which will be handled by user-defined stores 23 | class Action extends React.Component { 24 | className(){ 25 | return "Action"; 26 | } 27 | render(){ 28 | return null; 29 | } 30 | } 31 | 32 | // route class processed inside Router component 33 | class Route extends React.Component { 34 | className(){ 35 | return "Route"; 36 | } 37 | render(){ 38 | return null; 39 | } 40 | 41 | } 42 | 43 | class Router extends React.Component { 44 | constructor(props){ 45 | super(props); 46 | this.routes = {}; 47 | this.schemas = {}; 48 | var {dispatch} = props; 49 | if (!dispatch){ 50 | throw new Error("No redux dispatch is provided to Router!"); 51 | } 52 | 53 | var self = this; 54 | this.initial = props.initial; 55 | var RouterActions = props.actions || Actions; 56 | 57 | React.Children.forEach(props.children, function (child, index){ 58 | var name = child.props.name; 59 | if (!name){ 60 | throw new Error("Name is not defined for "+child.type.prototype.className()) 61 | } 62 | if (child.type.prototype.className() == "Schema") { 63 | self.schemas[name] = child.props; 64 | } else if (child.type.prototype.className() == "Route") { 65 | if (child.props.initial || !self.initial) { 66 | self.initial = name; 67 | } 68 | if (!(RouterActions[name])) { 69 | RouterActions[name] = function (data) { 70 | if (typeof(data)!='object'){ 71 | data={data:data}; 72 | } 73 | var args = {name: name, data:data}; 74 | var action = child.props.type || 'push'; 75 | dispatch(CoreActions[action](args)); 76 | }; 77 | } 78 | self.routes[name] = child.props; 79 | if (!child.props.component && !child.props.children){ 80 | console.error("No route component is defined for name: "+name); 81 | return; 82 | } 83 | 84 | } else if (child.type.prototype.className() == "Action") { 85 | //console.log("Added action: " + name); 86 | if (!(RouterActions[name])) { 87 | RouterActions[name] = function(data){ 88 | var props = self.extend({}, self.props); 89 | props = self.extend(props, child.props); 90 | dispatch(CoreActions.custom({name, props, data})); 91 | }; 92 | } 93 | } 94 | }); 95 | let dispatched = bindActionCreators(CoreActions, dispatch); 96 | for (var i in dispatched) 97 | RouterActions[i] = dispatched[i]; 98 | this.routerActions = RouterActions; 99 | this.initialRoute = this.routes[this.initial] || console.error("No initial route "+this.initial); 100 | this.state = {initial: this.initial}; 101 | } 102 | 103 | componentWillReceiveProps(props){ 104 | if (props.mode){ 105 | this.onChange(props) 106 | } 107 | } 108 | 109 | onChange(page){ 110 | if (page.mode==PUSH || page.mode==REPLACE){ 111 | var route = this.routes[page.currentRoute]; 112 | if (!route){ 113 | console.error("No route is defined for name: "+page.currentRoute); 114 | return; 115 | } 116 | // check if route is popup 117 | if (route.schema=='popup'){ 118 | var element = React.createElement(route.component, Object.assign({}, route, page.data, {dispatch: this.props.dispatch, routes:this.routerActions})); 119 | this.setState({modal: element}); 120 | } else { 121 | if (page.mode == REPLACE){ 122 | this.refs.nav.replace(this.getRoute(route, page.data)) 123 | } else { 124 | this.refs.nav.push(this.getRoute(route, page.data)) 125 | } 126 | } 127 | } 128 | if (page.mode==POP){ 129 | var routes = this.refs.nav.getCurrentRoutes(); 130 | var num = page.num || (routes.length - page.routes.length); 131 | // pop only existing routes! 132 | if (num < routes.length) { 133 | this.refs.nav.popToRoute(routes[routes.length - 1 - num]); 134 | } else { 135 | if (this.props.onExit){ 136 | this.props.onExit(routes[0], page.data || {}); 137 | } 138 | } 139 | } 140 | if (page.mode==DISMISS) { 141 | this.setState({modal: null}); 142 | } 143 | 144 | if (page.mode==RESET){ 145 | // reset navigation stack 146 | this.refs.nav.immediatelyResetRouteStack([this.getRoute(this.routes[page.initial], {})]) 147 | } 148 | } 149 | 150 | componentDidMount(){ 151 | this.props.dispatch(Actions.init(this.initial)); 152 | } 153 | 154 | renderScene(route, navigator) { 155 | var Component = route.component; 156 | var navBar = route.navigationBar; 157 | var footer = route.footer; 158 | 159 | if (navBar) { 160 | navBar = React.cloneElement(navBar, { 161 | navigator: navigator, 162 | route: route, 163 | dispatch:this.props.dispatch, 164 | routes:this.routerActions 165 | }); 166 | } 167 | if (footer){ 168 | footer = React.cloneElement(footer, { 169 | navigator: navigator, 170 | route: route, 171 | dispatch:this.props.dispatch, 172 | routes:this.routerActions 173 | }); 174 | } 175 | var child = null; 176 | if (Component){ 177 | child = 178 | } else { 179 | child = React.Children.only(this.routes[route.name].children); 180 | child = React.cloneElement(child, {schemas: this.schemas}); 181 | } 182 | 183 | return ( 184 | 185 | {navBar} 186 | {child} 187 | {footer} 188 | 189 | ) 190 | } 191 | 192 | extend(destination, source) { 193 | for (var property in source) { 194 | if (source.hasOwnProperty(property)) { 195 | destination[property] = source[property]; 196 | } 197 | } 198 | return destination; 199 | } 200 | 201 | getRoute(route, data) { 202 | if (!route){ 203 | console.error("No route for data:"+JSON.stringify(data)); 204 | } 205 | var schema = this.schemas[route.schema || 'default'] || {}; 206 | var sceneConfig = route.sceneConfig || schema.sceneConfig || Animations.None; 207 | var NavBar = route.navBar || schema.navBar; 208 | var Footer = route.footer || schema.footer; 209 | 210 | var navBar; 211 | if (NavBar){ 212 | navBar = 213 | } 214 | 215 | var footer; 216 | if (Footer){ 217 | footer =