├── .buckconfig ├── .flowconfig ├── .gitignore ├── .watchmanconfig ├── README.md ├── android ├── app │ ├── BUCK │ ├── app-release.apk │ ├── build.gradle │ ├── proguard-rules.pro │ └── src │ │ └── main │ │ ├── AndroidManifest.xml │ │ ├── assets │ │ └── index.android.bundle │ │ ├── java │ │ └── com │ │ │ └── marvel │ │ │ └── MainActivity.java │ │ └── res │ │ ├── drawable-hdpi │ │ └── node_modules_reactnative_libraries_customcomponents_navigationexperimental_assets_backicon.png │ │ ├── drawable-mdpi │ │ ├── js_splash_img_marvel_logo.png │ │ ├── js_splash_img_splash_background.png │ │ ├── js_tabs_img_about_marvel_logo.png │ │ ├── js_tabs_img_back.png │ │ ├── js_tabs_img_batman.png │ │ ├── js_tabs_img_batmancolor.png │ │ ├── js_tabs_img_head_2.png │ │ ├── js_tabs_img_shield.png │ │ ├── js_tabs_img_shieldcolor.png │ │ ├── js_tabs_img_star.png │ │ ├── js_tabs_img_unstar.png │ │ └── node_modules_reactnative_libraries_customcomponents_navigationexperimental_assets_backicon.png │ │ ├── drawable-xhdpi │ │ ├── js_tabs_img_back.png │ │ ├── js_tabs_img_batman.png │ │ ├── js_tabs_img_batmancolor.png │ │ ├── js_tabs_img_shield.png │ │ ├── js_tabs_img_shieldcolor.png │ │ ├── js_tabs_img_star.png │ │ ├── js_tabs_img_unstar.png │ │ └── node_modules_reactnative_libraries_customcomponents_navigationexperimental_assets_backicon.png │ │ ├── drawable-xxhdpi │ │ ├── js_tabs_img_back.png │ │ ├── js_tabs_img_batman.png │ │ ├── js_tabs_img_batmancolor.png │ │ ├── js_tabs_img_shield.png │ │ ├── js_tabs_img_shieldcolor.png │ │ └── node_modules_reactnative_libraries_customcomponents_navigationexperimental_assets_backicon.png │ │ ├── drawable-xxxhdpi │ │ └── node_modules_reactnative_libraries_customcomponents_navigationexperimental_assets_backicon.png │ │ ├── mipmap-hdpi │ │ └── ic_launcher.png │ │ ├── mipmap-mdpi │ │ └── ic_launcher.png │ │ ├── mipmap-xhdpi │ │ └── ic_launcher.png │ │ ├── mipmap-xxhdpi │ │ └── ic_launcher.png │ │ └── values │ │ ├── strings.xml │ │ └── styles.xml ├── build.gradle ├── gradle.properties ├── gradle │ └── wrapper │ │ ├── gradle-wrapper.jar │ │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── keystores │ ├── BUCK │ └── debug.keystore.properties └── settings.gradle ├── apk └── app-release.apk ├── buildandroid.sh ├── index.android.js ├── index.ios.js ├── ios ├── marvel.xcodeproj │ ├── project.pbxproj │ └── xcshareddata │ │ └── xcschemes │ │ └── marvel.xcscheme ├── marvel │ ├── AppDelegate.h │ ├── AppDelegate.m │ ├── Base.lproj │ │ └── LaunchScreen.xib │ ├── Images.xcassets │ │ └── AppIcon.appiconset │ │ │ ├── Contents.json │ │ │ ├── ic_launcher120-1.png │ │ │ ├── ic_launcher120.png │ │ │ ├── ic_launcher180.png │ │ │ ├── ic_launcher58.png │ │ │ ├── ic_launcher80.png │ │ │ └── ic_launcher87.png │ ├── Info.plist │ └── main.m └── marvelTests │ ├── Info.plist │ └── marvelTests.m ├── js ├── MarvelApp.js ├── MarvelNavigator.js ├── actions │ ├── index.js │ ├── mainentry.js │ ├── marvel.js │ ├── navigation.js │ └── types.js ├── common │ ├── F8Colors.js │ ├── F8Text.js │ ├── F8Touchable.js │ ├── MarvelDrawerLayout.js │ ├── MarvelHeader.js │ ├── MarvelInfoView.js │ └── constant.js ├── env.js ├── marvelapi │ ├── MarvelAPI.js │ ├── Util.js │ ├── model.js │ └── realmModel.js ├── reducers │ ├── index.js │ ├── mainentry.js │ ├── marvel.js │ └── navigation.js ├── setup.js ├── splash │ ├── SplashScreen.js │ └── img │ │ ├── marvel_logo.png │ │ └── splash_background.png ├── store │ ├── configureStore.js │ └── promise.js └── tabs │ ├── MarvelTabsView.android.js │ ├── MarvelTabsView.ios.js │ ├── MenuItem.js │ ├── about │ └── AboutContentView.js │ ├── characters │ ├── CharacterDetailView.js │ ├── CharactersContentView.js │ └── SearchView.js │ └── img │ ├── about_marvel_logo.png │ ├── back.png │ ├── back@2x.png │ ├── back@3x.png │ ├── batman.png │ ├── batman@2x.png │ ├── batman@3x.png │ ├── batmancolor.png │ ├── batmancolor@2x.png │ ├── batmancolor@3x.png │ ├── head_2.png │ ├── share.png │ ├── share@2x.png │ ├── shield.png │ ├── shield@2x.png │ ├── shield@3x.png │ ├── shieldcolor.png │ ├── shieldcolor@2x.png │ ├── shieldcolor@3x.png │ ├── star.png │ ├── star@2x.png │ ├── unstar.png │ ├── unstar@2x.png │ ├── wolve.png │ ├── wolve@2x.png │ ├── wolve@3x.png │ ├── wolvecolor.png │ ├── wolvecolor@2x.png │ └── wolvecolor@3x.png ├── package.json └── screenshot ├── 1.png ├── 2.png ├── 3.png ├── 4.png ├── 5.png ├── 6.png └── 7.png /.buckconfig: -------------------------------------------------------------------------------- 1 | 2 | [android] 3 | target = Google Inc.:Google APIs:23 4 | 5 | [maven_repositories] 6 | central = https://repo1.maven.org/maven2 7 | -------------------------------------------------------------------------------- /.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 | # Ugh 11 | .*/node_modules/babel.* 12 | .*/node_modules/babylon.* 13 | .*/node_modules/invariant.* 14 | 15 | # Ignore react and fbjs where there are overlaps, but don't ignore 16 | # anything that react-native relies on 17 | .*/node_modules/fbjs/lib/Map.js 18 | .*/node_modules/fbjs/lib/ErrorUtils.js 19 | 20 | # Flow has a built-in definition for the 'react' module which we prefer to use 21 | # over the currently-untyped source 22 | .*/node_modules/react/react.js 23 | .*/node_modules/react/lib/React.js 24 | .*/node_modules/react/lib/ReactDOM.js 25 | 26 | .*/__mocks__/.* 27 | .*/__tests__/.* 28 | 29 | .*/commoner/test/source/widget/share.js 30 | 31 | # Ignore commoner tests 32 | .*/node_modules/commoner/test/.* 33 | 34 | # See https://github.com/facebook/flow/issues/442 35 | .*/react-tools/node_modules/commoner/lib/reader.js 36 | 37 | # Ignore jest 38 | .*/node_modules/jest-cli/.* 39 | 40 | # Ignore Website 41 | .*/website/.* 42 | 43 | # Ignore generators 44 | .*/local-cli/generator.* 45 | 46 | # Ignore BUCK generated folders 47 | .*\.buckd/ 48 | 49 | # Ignore RNPM 50 | .*/local-cli/rnpm/.* 51 | 52 | .*/node_modules/is-my-json-valid/test/.*\.json 53 | .*/node_modules/iconv-lite/encodings/tables/.*\.json 54 | .*/node_modules/y18n/test/.*\.json 55 | .*/node_modules/spdx-license-ids/spdx-license-ids.json 56 | .*/node_modules/spdx-exceptions/index.json 57 | .*/node_modules/resolve/test/subdirs/node_modules/a/b/c/x.json 58 | .*/node_modules/resolve/lib/core.json 59 | .*/node_modules/jsonparse/samplejson/.*\.json 60 | .*/node_modules/json5/test/.*\.json 61 | .*/node_modules/ua-parser-js/test/.*\.json 62 | .*/node_modules/builtin-modules/builtin-modules.json 63 | .*/node_modules/binary-extensions/binary-extensions.json 64 | .*/node_modules/url-regex/tlds.json 65 | .*/node_modules/joi/.*\.json 66 | .*/node_modules/isemail/.*\.json 67 | .*/node_modules/tr46/.*\.json 68 | 69 | 70 | [include] 71 | 72 | [libs] 73 | node_modules/react-native/Libraries/react-native/react-native-interface.js 74 | node_modules/react-native/flow 75 | flow/ 76 | 77 | [options] 78 | module.system=haste 79 | 80 | esproposal.class_static_fields=enable 81 | esproposal.class_instance_fields=enable 82 | 83 | experimental.strict_type_args=true 84 | 85 | munge_underscores=true 86 | 87 | module.name_mapper='^image![a-zA-Z0-9$_-]+$' -> 'GlobalImageStub' 88 | module.name_mapper='^[./a-zA-Z0-9$_-]+\.\(bmp\|gif\|jpg\|jpeg\|png\|psd\|svg\|webp\|m4v\|mov\|mp4\|mpeg\|mpg\|webm\|aac\|aiff\|caf\|m4a\|mp3\|wav\|html\|pdf\)$' -> 'RelativeImageStub' 89 | 90 | suppress_type=$FlowIssue 91 | suppress_type=$FlowFixMe 92 | suppress_type=$FixMe 93 | 94 | suppress_comment=\\(.\\|\n\\)*\\$FlowFixMe\\($\\|[^(]\\|(\\(>=0\\.\\(2[0-6]\\|1[0-9]\\|[0-9]\\).[0-9]\\)? *\\(site=[a-z,_]*react_native[a-z,_]*\\)?)\\) 95 | suppress_comment=\\(.\\|\n\\)*\\$FlowIssue\\((\\(>=0\\.\\(2[0-6]\\|1[0-9]\\|[0-9]\\).[0-9]\\)? *\\(site=[a-z,_]*react_native[a-z,_]*\\)?)\\)?:? #[0-9]+ 96 | suppress_comment=\\(.\\|\n\\)*\\$FlowFixedInNextDeploy 97 | 98 | [version] 99 | ^0.27.0 100 | -------------------------------------------------------------------------------- /.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 | *.iml 28 | .idea 29 | .gradle 30 | local.properties 31 | 32 | # node.js 33 | # 34 | node_modules/ 35 | npm-debug.log 36 | 37 | # BUCK 38 | buck-out/ 39 | \.buckd/ 40 | android/app/libs 41 | android/keystores/debug.keystore 42 | -------------------------------------------------------------------------------- /.watchmanconfig: -------------------------------------------------------------------------------- 1 | {} -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Marvel 2 | 3 | 一个在F8基础上照猫画虎的漫威React Native App. 支持Android和IOS。采用redux来解耦View(React.Component)和业务逻辑(Marvel API, Store) 4 | 5 | 代码目录: 6 | - js/actions 所有的action 7 | - js/common 通用的一些控件,或者常量 8 | - js/marvelapi marvel api接口,以及暴露的数据结构,realm用于缓存popular角色的数据 9 | - js/reducers 处理action,返回结果 10 | - js/splash splash页面 11 | - js/store redux的store 12 | - js/tabs 主页面 13 | 14 | 15 | # Screenshot 16 | ![alt tag](./screenshot/1.png) 17 | ![alt tag](./screenshot/2.png) 18 | ![alt tag](./screenshot/5.png) 19 | ![alt tag](./screenshot/6.png) 20 | ![alt tag](./screenshot/7.png) 21 | 22 | # Download 23 | [APK](./apk/app-release.apk) 24 | 25 | # Run 26 | npm install; rnpm link realm; rnpm link react-native-share; 27 | - android 28 | react-native run-android 29 | - ios 30 | react-native run-ios 31 | 32 | # Features 33 | - 显示流行的漫威角色 34 | - 搜索漫威character, event, story, series 35 | 36 | # IDE 37 | - Nuclide & Visual studio code 38 | 39 | # Dev/Libs 40 | - F8 app 41 | - Realm 42 | - react-redux 43 | - react-native-action-button 44 | - react-native-hyperlink 45 | - crypto-js 46 | - redux-logger 47 | - react-native-share 48 | - flow 49 | 50 | # Feedback 51 | - feedback or any suggestion is welcome. 52 | -------------------------------------------------------------------------------- /android/app/BUCK: -------------------------------------------------------------------------------- 1 | import re 2 | 3 | # To learn about Buck see [Docs](https://buckbuild.com/). 4 | # To run your application with Buck: 5 | # - install Buck 6 | # - `npm start` - to start the packager 7 | # - `cd android` 8 | # - `keytool -genkey -v -keystore keystores/debug.keystore -storepass android -alias androiddebugkey -keypass android -dname "CN=Android Debug,O=Android,C=US` 9 | # - `./gradlew :app:copyDownloadableDepsToLibs` - make all Gradle compile dependencies available to Buck 10 | # - `buck install -r android/app` - compile, install and run application 11 | # 12 | 13 | lib_deps = [] 14 | for jarfile in glob(['libs/*.jar']): 15 | name = 'jars__' + re.sub(r'^.*/([^/]+)\.jar$', r'\1', jarfile) 16 | lib_deps.append(':' + name) 17 | prebuilt_jar( 18 | name = name, 19 | binary_jar = jarfile, 20 | ) 21 | 22 | for aarfile in glob(['libs/*.aar']): 23 | name = 'aars__' + re.sub(r'^.*/([^/]+)\.aar$', r'\1', aarfile) 24 | lib_deps.append(':' + name) 25 | android_prebuilt_aar( 26 | name = name, 27 | aar = aarfile, 28 | ) 29 | 30 | android_library( 31 | name = 'all-libs', 32 | exported_deps = lib_deps 33 | ) 34 | 35 | android_library( 36 | name = 'app-code', 37 | srcs = glob([ 38 | 'src/main/java/**/*.java', 39 | ]), 40 | deps = [ 41 | ':all-libs', 42 | ':build_config', 43 | ':res', 44 | ], 45 | ) 46 | 47 | android_build_config( 48 | name = 'build_config', 49 | package = 'com.marvel', 50 | ) 51 | 52 | android_resource( 53 | name = 'res', 54 | res = 'src/main/res', 55 | package = 'com.marvel', 56 | ) 57 | 58 | android_binary( 59 | name = 'app', 60 | package_type = 'debug', 61 | manifest = 'src/main/AndroidManifest.xml', 62 | keystore = '//android/keystores:debug', 63 | deps = [ 64 | ':app-code', 65 | ], 66 | ) 67 | -------------------------------------------------------------------------------- /android/app/app-release.apk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Shuijwan/marvel/47f2a96ed37af852892b10a07512f61a3070d99f/android/app/app-release.apk -------------------------------------------------------------------------------- /android/app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: "com.android.application" 2 | 3 | import com.android.build.OutputFile 4 | 5 | /** 6 | * The react.gradle file registers a task for each build variant (e.g. bundleDebugJsAndAssets 7 | * and bundleReleaseJsAndAssets). 8 | * These basically call `react-native bundle` with the correct arguments during the Android build 9 | * cycle. By default, bundleDebugJsAndAssets is skipped, as in debug/dev mode we prefer to load the 10 | * bundle directly from the development server. Below you can see all the possible configurations 11 | * and their defaults. If you decide to add a configuration block, make sure to add it before the 12 | * `apply from: "../../node_modules/react-native/react.gradle"` line. 13 | * 14 | * project.ext.react = [ 15 | * // the name of the generated asset file containing your JS bundle 16 | * bundleAssetName: "index.android.bundle", 17 | * 18 | * // the entry file for bundle generation 19 | * entryFile: "index.android.js", 20 | * 21 | * // whether to bundle JS and assets in debug mode 22 | * bundleInDebug: false, 23 | * 24 | * // whether to bundle JS and assets in release mode 25 | * bundleInRelease: true, 26 | * 27 | * // whether to bundle JS and assets in another build variant (if configured). 28 | * // See http://tools.android.com/tech-docs/new-build-system/user-guide#TOC-Build-Variants 29 | * // The configuration property can be in the following formats 30 | * // 'bundleIn${productFlavor}${buildType}' 31 | * // 'bundleIn${buildType}' 32 | * // bundleInFreeDebug: true, 33 | * // bundleInPaidRelease: true, 34 | * // bundleInBeta: true, 35 | * 36 | * // the root of your project, i.e. where "package.json" lives 37 | * root: "../../", 38 | * 39 | * // where to put the JS bundle asset in debug mode 40 | * jsBundleDirDebug: "$buildDir/intermediates/assets/debug", 41 | * 42 | * // where to put the JS bundle asset in release mode 43 | * jsBundleDirRelease: "$buildDir/intermediates/assets/release", 44 | * 45 | * // where to put drawable resources / React Native assets, e.g. the ones you use via 46 | * // require('./image.png')), in debug mode 47 | * resourcesDirDebug: "$buildDir/intermediates/res/merged/debug", 48 | * 49 | * // where to put drawable resources / React Native assets, e.g. the ones you use via 50 | * // require('./image.png')), in release mode 51 | * resourcesDirRelease: "$buildDir/intermediates/res/merged/release", 52 | * 53 | * // by default the gradle tasks are skipped if none of the JS files or assets change; this means 54 | * // that we don't look at files in android/ or ios/ to determine whether the tasks are up to 55 | * // date; if you have any other folders that you want to ignore for performance reasons (gradle 56 | * // indexes the entire tree), add them here. Alternatively, if you have JS files in android/ 57 | * // for example, you might want to remove it from here. 58 | * inputExcludes: ["android/**", "ios/**"], 59 | * 60 | * // override which node gets called and with what additional arguments 61 | * nodeExecutableAndArgs: ["node"] 62 | * 63 | * // supply additional arguments to the packager 64 | * extraPackagerArgs: [] 65 | * ] 66 | */ 67 | 68 | apply from: "../../node_modules/react-native/react.gradle" 69 | 70 | /** 71 | * Set this to true to create two separate APKs instead of one: 72 | * - An APK that only works on ARM devices 73 | * - An APK that only works on x86 devices 74 | * The advantage is the size of the APK is reduced by about 4MB. 75 | * Upload all the APKs to the Play Store and people will download 76 | * the correct one based on the CPU architecture of their device. 77 | */ 78 | def enableSeparateBuildPerCPUArchitecture = false 79 | 80 | /** 81 | * Run Proguard to shrink the Java bytecode in release builds. 82 | */ 83 | def enableProguardInReleaseBuilds = false 84 | 85 | android { 86 | compileSdkVersion 23 87 | buildToolsVersion "23.0.1" 88 | 89 | defaultConfig { 90 | applicationId "com.marvel" 91 | minSdkVersion 16 92 | targetSdkVersion 22 93 | versionCode 1 94 | versionName "1.0" 95 | ndk { 96 | abiFilters "armeabi-v7a", "x86" 97 | } 98 | } 99 | splits { 100 | abi { 101 | reset() 102 | enable enableSeparateBuildPerCPUArchitecture 103 | universalApk false // If true, also generate a universal APK 104 | include "armeabi-v7a", "x86" 105 | } 106 | } 107 | buildTypes { 108 | release { 109 | minifyEnabled enableProguardInReleaseBuilds 110 | proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro" 111 | } 112 | } 113 | // applicationVariants are e.g. debug, release 114 | applicationVariants.all { variant -> 115 | variant.outputs.each { output -> 116 | // For each separate APK per architecture, set a unique version code as described here: 117 | // http://tools.android.com/tech-docs/new-build-system/user-guide/apk-splits 118 | def versionCodes = ["armeabi-v7a":1, "x86":2] 119 | def abi = output.getFilter(OutputFile.ABI) 120 | if (abi != null) { // null for the universal-debug, universal-release variants 121 | output.versionCodeOverride = 122 | versionCodes.get(abi) * 1048576 + defaultConfig.versionCode 123 | } 124 | } 125 | } 126 | } 127 | 128 | dependencies { 129 | compile project(':react-native-share') 130 | compile project(':realm') 131 | compile fileTree(dir: "libs", include: ["*.jar"]) 132 | compile "com.android.support:appcompat-v7:23.0.1" 133 | compile "com.facebook.react:react-native:+" // From node_modules 134 | } 135 | 136 | // Run this once to be able to run the application with BUCK 137 | // puts all compile dependencies into folder libs for BUCK to use 138 | task copyDownloadableDepsToLibs(type: Copy) { 139 | from configurations.compile 140 | into 'libs' 141 | } 142 | -------------------------------------------------------------------------------- /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 | -keep,allowobfuscation @interface com.facebook.common.internal.DoNotStrip 30 | 31 | # Do not strip any method/class that is annotated with @DoNotStrip 32 | -keep @com.facebook.proguard.annotations.DoNotStrip class * 33 | -keep @com.facebook.common.internal.DoNotStrip class * 34 | -keepclassmembers class * { 35 | @com.facebook.proguard.annotations.DoNotStrip *; 36 | @com.facebook.common.internal.DoNotStrip *; 37 | } 38 | 39 | -keepclassmembers @com.facebook.proguard.annotations.KeepGettersAndSetters class * { 40 | void set*(***); 41 | *** get*(); 42 | } 43 | 44 | -keep class * extends com.facebook.react.bridge.JavaScriptModule { *; } 45 | -keep class * extends com.facebook.react.bridge.NativeModule { *; } 46 | -keepclassmembers,includedescriptorclasses class * { native ; } 47 | -keepclassmembers class * { @com.facebook.react.uimanager.UIProp ; } 48 | -keepclassmembers class * { @com.facebook.react.uimanager.annotations.ReactProp ; } 49 | -keepclassmembers class * { @com.facebook.react.uimanager.annotations.ReactPropGroup ; } 50 | 51 | -dontwarn com.facebook.react.** 52 | 53 | # okhttp 54 | 55 | -keepattributes Signature 56 | -keepattributes *Annotation* 57 | -keep class okhttp3.** { *; } 58 | -keep interface okhttp3.** { *; } 59 | -dontwarn okhttp3.** 60 | 61 | # okio 62 | 63 | -keep class sun.misc.Unsafe { *; } 64 | -dontwarn java.nio.file.* 65 | -dontwarn org.codehaus.mojo.animal_sniffer.IgnoreJRERequirement 66 | -dontwarn okio.** 67 | -------------------------------------------------------------------------------- /android/app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 5 | 6 | 7 | 8 | 9 | 12 | 13 | 18 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /android/app/src/main/java/com/marvel/MainActivity.java: -------------------------------------------------------------------------------- 1 | package com.marvel; 2 | 3 | import com.facebook.react.ReactActivity; 4 | import cl.json.RNSharePackage; 5 | import io.realm.react.RealmReactPackage; 6 | import com.facebook.react.ReactPackage; 7 | import com.facebook.react.shell.MainReactPackage; 8 | 9 | import java.util.Arrays; 10 | import java.util.List; 11 | 12 | public class MainActivity extends ReactActivity { 13 | 14 | /** 15 | * Returns the name of the main component registered from JavaScript. 16 | * This is used to schedule rendering of the component. 17 | */ 18 | @Override 19 | protected String getMainComponentName() { 20 | return "marvel"; 21 | } 22 | 23 | /** 24 | * Returns whether dev mode should be enabled. 25 | * This enables e.g. the dev menu. 26 | */ 27 | @Override 28 | protected boolean getUseDeveloperSupport() { 29 | return BuildConfig.DEBUG; 30 | } 31 | 32 | /** 33 | * A list of packages used by the app. If the app uses additional views 34 | * or modules besides the default ones, add more packages here. 35 | */ 36 | @Override 37 | protected List getPackages() { 38 | return Arrays.asList( 39 | new MainReactPackage(), 40 | new RNSharePackage(), 41 | new RealmReactPackage() 42 | ); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /android/app/src/main/res/drawable-hdpi/node_modules_reactnative_libraries_customcomponents_navigationexperimental_assets_backicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Shuijwan/marvel/47f2a96ed37af852892b10a07512f61a3070d99f/android/app/src/main/res/drawable-hdpi/node_modules_reactnative_libraries_customcomponents_navigationexperimental_assets_backicon.png -------------------------------------------------------------------------------- /android/app/src/main/res/drawable-mdpi/js_splash_img_marvel_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Shuijwan/marvel/47f2a96ed37af852892b10a07512f61a3070d99f/android/app/src/main/res/drawable-mdpi/js_splash_img_marvel_logo.png -------------------------------------------------------------------------------- /android/app/src/main/res/drawable-mdpi/js_splash_img_splash_background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Shuijwan/marvel/47f2a96ed37af852892b10a07512f61a3070d99f/android/app/src/main/res/drawable-mdpi/js_splash_img_splash_background.png -------------------------------------------------------------------------------- /android/app/src/main/res/drawable-mdpi/js_tabs_img_about_marvel_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Shuijwan/marvel/47f2a96ed37af852892b10a07512f61a3070d99f/android/app/src/main/res/drawable-mdpi/js_tabs_img_about_marvel_logo.png -------------------------------------------------------------------------------- /android/app/src/main/res/drawable-mdpi/js_tabs_img_back.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Shuijwan/marvel/47f2a96ed37af852892b10a07512f61a3070d99f/android/app/src/main/res/drawable-mdpi/js_tabs_img_back.png -------------------------------------------------------------------------------- /android/app/src/main/res/drawable-mdpi/js_tabs_img_batman.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Shuijwan/marvel/47f2a96ed37af852892b10a07512f61a3070d99f/android/app/src/main/res/drawable-mdpi/js_tabs_img_batman.png -------------------------------------------------------------------------------- /android/app/src/main/res/drawable-mdpi/js_tabs_img_batmancolor.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Shuijwan/marvel/47f2a96ed37af852892b10a07512f61a3070d99f/android/app/src/main/res/drawable-mdpi/js_tabs_img_batmancolor.png -------------------------------------------------------------------------------- /android/app/src/main/res/drawable-mdpi/js_tabs_img_head_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Shuijwan/marvel/47f2a96ed37af852892b10a07512f61a3070d99f/android/app/src/main/res/drawable-mdpi/js_tabs_img_head_2.png -------------------------------------------------------------------------------- /android/app/src/main/res/drawable-mdpi/js_tabs_img_shield.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Shuijwan/marvel/47f2a96ed37af852892b10a07512f61a3070d99f/android/app/src/main/res/drawable-mdpi/js_tabs_img_shield.png -------------------------------------------------------------------------------- /android/app/src/main/res/drawable-mdpi/js_tabs_img_shieldcolor.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Shuijwan/marvel/47f2a96ed37af852892b10a07512f61a3070d99f/android/app/src/main/res/drawable-mdpi/js_tabs_img_shieldcolor.png -------------------------------------------------------------------------------- /android/app/src/main/res/drawable-mdpi/js_tabs_img_star.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Shuijwan/marvel/47f2a96ed37af852892b10a07512f61a3070d99f/android/app/src/main/res/drawable-mdpi/js_tabs_img_star.png -------------------------------------------------------------------------------- /android/app/src/main/res/drawable-mdpi/js_tabs_img_unstar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Shuijwan/marvel/47f2a96ed37af852892b10a07512f61a3070d99f/android/app/src/main/res/drawable-mdpi/js_tabs_img_unstar.png -------------------------------------------------------------------------------- /android/app/src/main/res/drawable-mdpi/node_modules_reactnative_libraries_customcomponents_navigationexperimental_assets_backicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Shuijwan/marvel/47f2a96ed37af852892b10a07512f61a3070d99f/android/app/src/main/res/drawable-mdpi/node_modules_reactnative_libraries_customcomponents_navigationexperimental_assets_backicon.png -------------------------------------------------------------------------------- /android/app/src/main/res/drawable-xhdpi/js_tabs_img_back.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Shuijwan/marvel/47f2a96ed37af852892b10a07512f61a3070d99f/android/app/src/main/res/drawable-xhdpi/js_tabs_img_back.png -------------------------------------------------------------------------------- /android/app/src/main/res/drawable-xhdpi/js_tabs_img_batman.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Shuijwan/marvel/47f2a96ed37af852892b10a07512f61a3070d99f/android/app/src/main/res/drawable-xhdpi/js_tabs_img_batman.png -------------------------------------------------------------------------------- /android/app/src/main/res/drawable-xhdpi/js_tabs_img_batmancolor.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Shuijwan/marvel/47f2a96ed37af852892b10a07512f61a3070d99f/android/app/src/main/res/drawable-xhdpi/js_tabs_img_batmancolor.png -------------------------------------------------------------------------------- /android/app/src/main/res/drawable-xhdpi/js_tabs_img_shield.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Shuijwan/marvel/47f2a96ed37af852892b10a07512f61a3070d99f/android/app/src/main/res/drawable-xhdpi/js_tabs_img_shield.png -------------------------------------------------------------------------------- /android/app/src/main/res/drawable-xhdpi/js_tabs_img_shieldcolor.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Shuijwan/marvel/47f2a96ed37af852892b10a07512f61a3070d99f/android/app/src/main/res/drawable-xhdpi/js_tabs_img_shieldcolor.png -------------------------------------------------------------------------------- /android/app/src/main/res/drawable-xhdpi/js_tabs_img_star.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Shuijwan/marvel/47f2a96ed37af852892b10a07512f61a3070d99f/android/app/src/main/res/drawable-xhdpi/js_tabs_img_star.png -------------------------------------------------------------------------------- /android/app/src/main/res/drawable-xhdpi/js_tabs_img_unstar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Shuijwan/marvel/47f2a96ed37af852892b10a07512f61a3070d99f/android/app/src/main/res/drawable-xhdpi/js_tabs_img_unstar.png -------------------------------------------------------------------------------- /android/app/src/main/res/drawable-xhdpi/node_modules_reactnative_libraries_customcomponents_navigationexperimental_assets_backicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Shuijwan/marvel/47f2a96ed37af852892b10a07512f61a3070d99f/android/app/src/main/res/drawable-xhdpi/node_modules_reactnative_libraries_customcomponents_navigationexperimental_assets_backicon.png -------------------------------------------------------------------------------- /android/app/src/main/res/drawable-xxhdpi/js_tabs_img_back.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Shuijwan/marvel/47f2a96ed37af852892b10a07512f61a3070d99f/android/app/src/main/res/drawable-xxhdpi/js_tabs_img_back.png -------------------------------------------------------------------------------- /android/app/src/main/res/drawable-xxhdpi/js_tabs_img_batman.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Shuijwan/marvel/47f2a96ed37af852892b10a07512f61a3070d99f/android/app/src/main/res/drawable-xxhdpi/js_tabs_img_batman.png -------------------------------------------------------------------------------- /android/app/src/main/res/drawable-xxhdpi/js_tabs_img_batmancolor.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Shuijwan/marvel/47f2a96ed37af852892b10a07512f61a3070d99f/android/app/src/main/res/drawable-xxhdpi/js_tabs_img_batmancolor.png -------------------------------------------------------------------------------- /android/app/src/main/res/drawable-xxhdpi/js_tabs_img_shield.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Shuijwan/marvel/47f2a96ed37af852892b10a07512f61a3070d99f/android/app/src/main/res/drawable-xxhdpi/js_tabs_img_shield.png -------------------------------------------------------------------------------- /android/app/src/main/res/drawable-xxhdpi/js_tabs_img_shieldcolor.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Shuijwan/marvel/47f2a96ed37af852892b10a07512f61a3070d99f/android/app/src/main/res/drawable-xxhdpi/js_tabs_img_shieldcolor.png -------------------------------------------------------------------------------- /android/app/src/main/res/drawable-xxhdpi/node_modules_reactnative_libraries_customcomponents_navigationexperimental_assets_backicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Shuijwan/marvel/47f2a96ed37af852892b10a07512f61a3070d99f/android/app/src/main/res/drawable-xxhdpi/node_modules_reactnative_libraries_customcomponents_navigationexperimental_assets_backicon.png -------------------------------------------------------------------------------- /android/app/src/main/res/drawable-xxxhdpi/node_modules_reactnative_libraries_customcomponents_navigationexperimental_assets_backicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Shuijwan/marvel/47f2a96ed37af852892b10a07512f61a3070d99f/android/app/src/main/res/drawable-xxxhdpi/node_modules_reactnative_libraries_customcomponents_navigationexperimental_assets_backicon.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Shuijwan/marvel/47f2a96ed37af852892b10a07512f61a3070d99f/android/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Shuijwan/marvel/47f2a96ed37af852892b10a07512f61a3070d99f/android/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Shuijwan/marvel/47f2a96ed37af852892b10a07512f61a3070d99f/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Shuijwan/marvel/47f2a96ed37af852892b10a07512f61a3070d99f/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 漫威 6 | 7 | -------------------------------------------------------------------------------- /android/app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /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 | maven { 20 | // All of React Native (JS, Obj-C sources, Android binaries) is installed from npm 21 | url "$rootDir/../node_modules/react-native/android" 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /android/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Shuijwan/marvel/47f2a96ed37af852892b10a07512f61a3070d99f/android/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /android/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | zipStoreBase=GRADLE_USER_HOME 4 | zipStorePath=wrapper/dists 5 | distributionUrl=https\://services.gradle.org/distributions/gradle-2.4-all.zip 6 | -------------------------------------------------------------------------------- /android/gradlew: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | ############################################################################## 4 | ## 5 | ## Gradle start up script for UN*X 6 | ## 7 | ############################################################################## 8 | 9 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 10 | DEFAULT_JVM_OPTS="" 11 | 12 | APP_NAME="Gradle" 13 | APP_BASE_NAME=`basename "$0"` 14 | 15 | # Use the maximum available, or set MAX_FD != -1 to use that value. 16 | MAX_FD="maximum" 17 | 18 | warn ( ) { 19 | echo "$*" 20 | } 21 | 22 | die ( ) { 23 | echo 24 | echo "$*" 25 | echo 26 | exit 1 27 | } 28 | 29 | # OS specific support (must be 'true' or 'false'). 30 | cygwin=false 31 | msys=false 32 | darwin=false 33 | case "`uname`" in 34 | CYGWIN* ) 35 | cygwin=true 36 | ;; 37 | Darwin* ) 38 | darwin=true 39 | ;; 40 | MINGW* ) 41 | msys=true 42 | ;; 43 | esac 44 | 45 | # For Cygwin, ensure paths are in UNIX format before anything is touched. 46 | if $cygwin ; then 47 | [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"` 48 | fi 49 | 50 | # Attempt to set APP_HOME 51 | # Resolve links: $0 may be a link 52 | PRG="$0" 53 | # Need this for relative symlinks. 54 | while [ -h "$PRG" ] ; do 55 | ls=`ls -ld "$PRG"` 56 | link=`expr "$ls" : '.*-> \(.*\)$'` 57 | if expr "$link" : '/.*' > /dev/null; then 58 | PRG="$link" 59 | else 60 | PRG=`dirname "$PRG"`"/$link" 61 | fi 62 | done 63 | SAVED="`pwd`" 64 | cd "`dirname \"$PRG\"`/" >&- 65 | APP_HOME="`pwd -P`" 66 | cd "$SAVED" >&- 67 | 68 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 69 | 70 | # Determine the Java command to use to start the JVM. 71 | if [ -n "$JAVA_HOME" ] ; then 72 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 73 | # IBM's JDK on AIX uses strange locations for the executables 74 | JAVACMD="$JAVA_HOME/jre/sh/java" 75 | else 76 | JAVACMD="$JAVA_HOME/bin/java" 77 | fi 78 | if [ ! -x "$JAVACMD" ] ; then 79 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 80 | 81 | Please set the JAVA_HOME variable in your environment to match the 82 | location of your Java installation." 83 | fi 84 | else 85 | JAVACMD="java" 86 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 87 | 88 | Please set the JAVA_HOME variable in your environment to match the 89 | location of your Java installation." 90 | fi 91 | 92 | # Increase the maximum file descriptors if we can. 93 | if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then 94 | MAX_FD_LIMIT=`ulimit -H -n` 95 | if [ $? -eq 0 ] ; then 96 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then 97 | MAX_FD="$MAX_FD_LIMIT" 98 | fi 99 | ulimit -n $MAX_FD 100 | if [ $? -ne 0 ] ; then 101 | warn "Could not set maximum file descriptor limit: $MAX_FD" 102 | fi 103 | else 104 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" 105 | fi 106 | fi 107 | 108 | # For Darwin, add options to specify how the application appears in the dock 109 | if $darwin; then 110 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" 111 | fi 112 | 113 | # For Cygwin, switch paths to Windows format before running java 114 | if $cygwin ; then 115 | APP_HOME=`cygpath --path --mixed "$APP_HOME"` 116 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` 117 | 118 | # We build the pattern for arguments to be converted via cygpath 119 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` 120 | SEP="" 121 | for dir in $ROOTDIRSRAW ; do 122 | ROOTDIRS="$ROOTDIRS$SEP$dir" 123 | SEP="|" 124 | done 125 | OURCYGPATTERN="(^($ROOTDIRS))" 126 | # Add a user-defined pattern to the cygpath arguments 127 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then 128 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" 129 | fi 130 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 131 | i=0 132 | for arg in "$@" ; do 133 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` 134 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option 135 | 136 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition 137 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` 138 | else 139 | eval `echo args$i`="\"$arg\"" 140 | fi 141 | i=$((i+1)) 142 | done 143 | case $i in 144 | (0) set -- ;; 145 | (1) set -- "$args0" ;; 146 | (2) set -- "$args0" "$args1" ;; 147 | (3) set -- "$args0" "$args1" "$args2" ;; 148 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;; 149 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; 150 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; 151 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; 152 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; 153 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; 154 | esac 155 | fi 156 | 157 | # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules 158 | function splitJvmOpts() { 159 | JVM_OPTS=("$@") 160 | } 161 | eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS 162 | JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME" 163 | 164 | exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" 165 | -------------------------------------------------------------------------------- /android/gradlew.bat: -------------------------------------------------------------------------------- 1 | @if "%DEBUG%" == "" @echo off 2 | @rem ########################################################################## 3 | @rem 4 | @rem Gradle startup script for Windows 5 | @rem 6 | @rem ########################################################################## 7 | 8 | @rem Set local scope for the variables with windows NT shell 9 | if "%OS%"=="Windows_NT" setlocal 10 | 11 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 12 | set DEFAULT_JVM_OPTS= 13 | 14 | set DIRNAME=%~dp0 15 | if "%DIRNAME%" == "" set DIRNAME=. 16 | set APP_BASE_NAME=%~n0 17 | set APP_HOME=%DIRNAME% 18 | 19 | @rem Find java.exe 20 | if defined JAVA_HOME goto findJavaFromJavaHome 21 | 22 | set JAVA_EXE=java.exe 23 | %JAVA_EXE% -version >NUL 2>&1 24 | if "%ERRORLEVEL%" == "0" goto init 25 | 26 | echo. 27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 28 | echo. 29 | echo Please set the JAVA_HOME variable in your environment to match the 30 | echo location of your Java installation. 31 | 32 | goto fail 33 | 34 | :findJavaFromJavaHome 35 | set JAVA_HOME=%JAVA_HOME:"=% 36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 37 | 38 | if exist "%JAVA_EXE%" goto init 39 | 40 | echo. 41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 42 | echo. 43 | echo Please set the JAVA_HOME variable in your environment to match the 44 | echo location of your Java installation. 45 | 46 | goto fail 47 | 48 | :init 49 | @rem Get command-line arguments, handling Windowz variants 50 | 51 | if not "%OS%" == "Windows_NT" goto win9xME_args 52 | if "%@eval[2+2]" == "4" goto 4NT_args 53 | 54 | :win9xME_args 55 | @rem Slurp the command line arguments. 56 | set CMD_LINE_ARGS= 57 | set _SKIP=2 58 | 59 | :win9xME_args_slurp 60 | if "x%~1" == "x" goto execute 61 | 62 | set CMD_LINE_ARGS=%* 63 | goto execute 64 | 65 | :4NT_args 66 | @rem Get arguments from the 4NT Shell from JP Software 67 | set CMD_LINE_ARGS=%$ 68 | 69 | :execute 70 | @rem Setup the command line 71 | 72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 73 | 74 | @rem Execute Gradle 75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 76 | 77 | :end 78 | @rem End local scope for the variables with windows NT shell 79 | if "%ERRORLEVEL%"=="0" goto mainEnd 80 | 81 | :fail 82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 83 | rem the _cmd.exe /c_ return code! 84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 85 | exit /b 1 86 | 87 | :mainEnd 88 | if "%OS%"=="Windows_NT" endlocal 89 | 90 | :omega 91 | -------------------------------------------------------------------------------- /android/keystores/BUCK: -------------------------------------------------------------------------------- 1 | keystore( 2 | name = 'debug', 3 | store = 'debug.keystore', 4 | properties = 'debug.keystore.properties', 5 | visibility = [ 6 | 'PUBLIC', 7 | ], 8 | ) 9 | -------------------------------------------------------------------------------- /android/keystores/debug.keystore.properties: -------------------------------------------------------------------------------- 1 | key.store=debug.keystore 2 | key.alias=androiddebugkey 3 | key.store.password=android 4 | key.alias.password=android 5 | -------------------------------------------------------------------------------- /android/settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name = 'marvel' 2 | 3 | include ':app' 4 | include ':react-native-share' 5 | project(':react-native-share').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-share/android') 6 | include ':realm' 7 | project(':realm').projectDir = new File(rootProject.projectDir, '../node_modules/realm/android') 8 | -------------------------------------------------------------------------------- /apk/app-release.apk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Shuijwan/marvel/47f2a96ed37af852892b10a07512f61a3070d99f/apk/app-release.apk -------------------------------------------------------------------------------- /buildandroid.sh: -------------------------------------------------------------------------------- 1 | react-native bundle --platform android --dev false --entry-file index.android.js --bundle-output android/app/src/main/assets/index.android.bundle --assets-dest android/app/src/main/res/ 2 | -------------------------------------------------------------------------------- /index.android.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Sample React Native App 3 | * https://github.com/facebook/react-native 4 | * @flow 5 | */ 6 | 'use strict'; 7 | const {AppRegistry} = require('react-native'); 8 | const setup = require('./js/setup'); 9 | 10 | AppRegistry.registerComponent('marvel', setup); 11 | -------------------------------------------------------------------------------- /index.ios.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Sample React Native App 3 | * https://github.com/facebook/react-native 4 | * @flow 5 | */ 6 | 'use strict'; 7 | const {AppRegistry} = require('react-native'); 8 | const setup = require('./js/setup'); 9 | 10 | AppRegistry.registerComponent('marvel', setup); 11 | -------------------------------------------------------------------------------- /ios/marvel.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 | 00E356F31AD99517003FC87E /* marvelTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 00E356F21AD99517003FC87E /* marvelTests.m */; }; 16 | 133E29F31AD74F7200F7D852 /* libRCTLinking.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 78C398B91ACF4ADC00677621 /* libRCTLinking.a */; }; 17 | 139105C61AF99C1200B5F7CC /* libRCTSettings.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 139105C11AF99BAD00B5F7CC /* libRCTSettings.a */; }; 18 | 139FDEF61B0652A700C62182 /* libRCTWebSocket.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 139FDEF41B06529B00C62182 /* libRCTWebSocket.a */; }; 19 | 13B07FBC1A68108700A75B9A /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB01A68108700A75B9A /* AppDelegate.m */; }; 20 | 13B07FBD1A68108700A75B9A /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB11A68108700A75B9A /* LaunchScreen.xib */; }; 21 | 13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB51A68108700A75B9A /* Images.xcassets */; }; 22 | 13B07FC11A68108700A75B9A /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB71A68108700A75B9A /* main.m */; }; 23 | 140ED2AC1D01E1AD002B40FF /* libReact.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 146834041AC3E56700842450 /* libReact.a */; }; 24 | 146834051AC3E58100842450 /* libReact.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 146834041AC3E56700842450 /* libReact.a */; }; 25 | 1B7B682E03494510B314FE30 /* libRealmReact.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 984FF4D5307741BDA11A8F3C /* libRealmReact.a */; }; 26 | 66042F8050C042D191A67066 /* libc++.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 42EFFF3EB6DF4AEC84E246D4 /* libc++.tbd */; }; 27 | 832341BD1AAA6AB300B99B32 /* libRCTText.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 832341B51AAA6A8300B99B32 /* libRCTText.a */; }; 28 | 8F2A940722B846A3975E9306 /* libRNShare.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5D649B0C4C16433BA8E249FE /* libRNShare.a */; }; 29 | D7368AF80EDE41E98807AE61 /* libz.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = A0D5E1A21E67465B91DDFD72 /* libz.tbd */; }; 30 | /* End PBXBuildFile section */ 31 | 32 | /* Begin PBXContainerItemProxy section */ 33 | 00C302AB1ABCB8CE00DB3ED1 /* PBXContainerItemProxy */ = { 34 | isa = PBXContainerItemProxy; 35 | containerPortal = 00C302A71ABCB8CE00DB3ED1 /* RCTActionSheet.xcodeproj */; 36 | proxyType = 2; 37 | remoteGlobalIDString = 134814201AA4EA6300B7C361; 38 | remoteInfo = RCTActionSheet; 39 | }; 40 | 00C302B91ABCB90400DB3ED1 /* PBXContainerItemProxy */ = { 41 | isa = PBXContainerItemProxy; 42 | containerPortal = 00C302B51ABCB90400DB3ED1 /* RCTGeolocation.xcodeproj */; 43 | proxyType = 2; 44 | remoteGlobalIDString = 134814201AA4EA6300B7C361; 45 | remoteInfo = RCTGeolocation; 46 | }; 47 | 00C302BF1ABCB91800DB3ED1 /* PBXContainerItemProxy */ = { 48 | isa = PBXContainerItemProxy; 49 | containerPortal = 00C302BB1ABCB91800DB3ED1 /* RCTImage.xcodeproj */; 50 | proxyType = 2; 51 | remoteGlobalIDString = 58B5115D1A9E6B3D00147676; 52 | remoteInfo = RCTImage; 53 | }; 54 | 00C302DB1ABCB9D200DB3ED1 /* PBXContainerItemProxy */ = { 55 | isa = PBXContainerItemProxy; 56 | containerPortal = 00C302D31ABCB9D200DB3ED1 /* RCTNetwork.xcodeproj */; 57 | proxyType = 2; 58 | remoteGlobalIDString = 58B511DB1A9E6C8500147676; 59 | remoteInfo = RCTNetwork; 60 | }; 61 | 00C302E31ABCB9EE00DB3ED1 /* PBXContainerItemProxy */ = { 62 | isa = PBXContainerItemProxy; 63 | containerPortal = 00C302DF1ABCB9EE00DB3ED1 /* RCTVibration.xcodeproj */; 64 | proxyType = 2; 65 | remoteGlobalIDString = 832C81801AAF6DEF007FA2F7; 66 | remoteInfo = RCTVibration; 67 | }; 68 | 00E356F41AD99517003FC87E /* PBXContainerItemProxy */ = { 69 | isa = PBXContainerItemProxy; 70 | containerPortal = 83CBB9F71A601CBA00E9B192 /* Project object */; 71 | proxyType = 1; 72 | remoteGlobalIDString = 13B07F861A680F5B00A75B9A; 73 | remoteInfo = marvel; 74 | }; 75 | 139105C01AF99BAD00B5F7CC /* PBXContainerItemProxy */ = { 76 | isa = PBXContainerItemProxy; 77 | containerPortal = 139105B61AF99BAD00B5F7CC /* RCTSettings.xcodeproj */; 78 | proxyType = 2; 79 | remoteGlobalIDString = 134814201AA4EA6300B7C361; 80 | remoteInfo = RCTSettings; 81 | }; 82 | 139FDEF31B06529B00C62182 /* PBXContainerItemProxy */ = { 83 | isa = PBXContainerItemProxy; 84 | containerPortal = 139FDEE61B06529A00C62182 /* RCTWebSocket.xcodeproj */; 85 | proxyType = 2; 86 | remoteGlobalIDString = 3C86DF461ADF2C930047B81A; 87 | remoteInfo = RCTWebSocket; 88 | }; 89 | 146834031AC3E56700842450 /* PBXContainerItemProxy */ = { 90 | isa = PBXContainerItemProxy; 91 | containerPortal = 146833FF1AC3E56700842450 /* React.xcodeproj */; 92 | proxyType = 2; 93 | remoteGlobalIDString = 83CBBA2E1A601D0E00E9B192; 94 | remoteInfo = React; 95 | }; 96 | 78C398B81ACF4ADC00677621 /* PBXContainerItemProxy */ = { 97 | isa = PBXContainerItemProxy; 98 | containerPortal = 78C398B01ACF4ADC00677621 /* RCTLinking.xcodeproj */; 99 | proxyType = 2; 100 | remoteGlobalIDString = 134814201AA4EA6300B7C361; 101 | remoteInfo = RCTLinking; 102 | }; 103 | 832341B41AAA6A8300B99B32 /* PBXContainerItemProxy */ = { 104 | isa = PBXContainerItemProxy; 105 | containerPortal = 832341B01AAA6A8300B99B32 /* RCTText.xcodeproj */; 106 | proxyType = 2; 107 | remoteGlobalIDString = 58B5119B1A9E6C1200147676; 108 | remoteInfo = RCTText; 109 | }; 110 | 933F86C01D21585C00E952A2 /* PBXContainerItemProxy */ = { 111 | isa = PBXContainerItemProxy; 112 | containerPortal = 1CDF97DEBB87431A98112D3D /* RealmReact.xcodeproj */; 113 | proxyType = 2; 114 | remoteGlobalIDString = F60690131CA2766F0003FB26; 115 | remoteInfo = RealmReact; 116 | }; 117 | 93747F361D2A841B00673B55 /* PBXContainerItemProxy */ = { 118 | isa = PBXContainerItemProxy; 119 | containerPortal = F1B396788B9A49E0BC62F132 /* RNShare.xcodeproj */; 120 | proxyType = 2; 121 | remoteGlobalIDString = 134814201AA4EA6300B7C361; 122 | remoteInfo = RNShare; 123 | }; 124 | /* End PBXContainerItemProxy section */ 125 | 126 | /* Begin PBXFileReference section */ 127 | 008F07F21AC5B25A0029DE68 /* main.jsbundle */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = main.jsbundle; sourceTree = ""; }; 128 | 00C302A71ABCB8CE00DB3ED1 /* RCTActionSheet.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTActionSheet.xcodeproj; path = "../node_modules/react-native/Libraries/ActionSheetIOS/RCTActionSheet.xcodeproj"; sourceTree = ""; }; 129 | 00C302B51ABCB90400DB3ED1 /* RCTGeolocation.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTGeolocation.xcodeproj; path = "../node_modules/react-native/Libraries/Geolocation/RCTGeolocation.xcodeproj"; sourceTree = ""; }; 130 | 00C302BB1ABCB91800DB3ED1 /* RCTImage.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTImage.xcodeproj; path = "../node_modules/react-native/Libraries/Image/RCTImage.xcodeproj"; sourceTree = ""; }; 131 | 00C302D31ABCB9D200DB3ED1 /* RCTNetwork.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTNetwork.xcodeproj; path = "../node_modules/react-native/Libraries/Network/RCTNetwork.xcodeproj"; sourceTree = ""; }; 132 | 00C302DF1ABCB9EE00DB3ED1 /* RCTVibration.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTVibration.xcodeproj; path = "../node_modules/react-native/Libraries/Vibration/RCTVibration.xcodeproj"; sourceTree = ""; }; 133 | 00E356EE1AD99517003FC87E /* marvelTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = marvelTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 134 | 00E356F11AD99517003FC87E /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 135 | 00E356F21AD99517003FC87E /* marvelTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = marvelTests.m; sourceTree = ""; }; 136 | 139105B61AF99BAD00B5F7CC /* RCTSettings.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTSettings.xcodeproj; path = "../node_modules/react-native/Libraries/Settings/RCTSettings.xcodeproj"; sourceTree = ""; }; 137 | 139FDEE61B06529A00C62182 /* RCTWebSocket.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTWebSocket.xcodeproj; path = "../node_modules/react-native/Libraries/WebSocket/RCTWebSocket.xcodeproj"; sourceTree = ""; }; 138 | 13B07F961A680F5B00A75B9A /* marvel.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = marvel.app; sourceTree = BUILT_PRODUCTS_DIR; }; 139 | 13B07FAF1A68108700A75B9A /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AppDelegate.h; path = marvel/AppDelegate.h; sourceTree = ""; }; 140 | 13B07FB01A68108700A75B9A /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = AppDelegate.m; path = marvel/AppDelegate.m; sourceTree = ""; }; 141 | 13B07FB21A68108700A75B9A /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/LaunchScreen.xib; sourceTree = ""; }; 142 | 13B07FB51A68108700A75B9A /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Images.xcassets; path = marvel/Images.xcassets; sourceTree = ""; }; 143 | 13B07FB61A68108700A75B9A /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Info.plist; path = marvel/Info.plist; sourceTree = ""; }; 144 | 13B07FB71A68108700A75B9A /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = main.m; path = marvel/main.m; sourceTree = ""; }; 145 | 146833FF1AC3E56700842450 /* React.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = React.xcodeproj; path = "../node_modules/react-native/React/React.xcodeproj"; sourceTree = ""; }; 146 | 1CDF97DEBB87431A98112D3D /* RealmReact.xcodeproj */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = "wrapper.pb-project"; name = RealmReact.xcodeproj; path = "../node_modules/realm/react-native/ios/RealmReact.xcodeproj"; sourceTree = ""; }; 147 | 42EFFF3EB6DF4AEC84E246D4 /* libc++.tbd */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = "libc++.tbd"; path = "usr/lib/libc++.tbd"; sourceTree = SDKROOT; }; 148 | 5D649B0C4C16433BA8E249FE /* libRNShare.a */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = archive.ar; path = libRNShare.a; sourceTree = ""; }; 149 | 78C398B01ACF4ADC00677621 /* RCTLinking.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTLinking.xcodeproj; path = "../node_modules/react-native/Libraries/LinkingIOS/RCTLinking.xcodeproj"; sourceTree = ""; }; 150 | 832341B01AAA6A8300B99B32 /* RCTText.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTText.xcodeproj; path = "../node_modules/react-native/Libraries/Text/RCTText.xcodeproj"; sourceTree = ""; }; 151 | 984FF4D5307741BDA11A8F3C /* libRealmReact.a */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = archive.ar; path = libRealmReact.a; sourceTree = ""; }; 152 | A0D5E1A21E67465B91DDFD72 /* libz.tbd */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libz.tbd; path = usr/lib/libz.tbd; sourceTree = SDKROOT; }; 153 | F1B396788B9A49E0BC62F132 /* RNShare.xcodeproj */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = "wrapper.pb-project"; name = RNShare.xcodeproj; path = "../node_modules/react-native-share/ios/RNShare.xcodeproj"; sourceTree = ""; }; 154 | /* End PBXFileReference section */ 155 | 156 | /* Begin PBXFrameworksBuildPhase section */ 157 | 00E356EB1AD99517003FC87E /* Frameworks */ = { 158 | isa = PBXFrameworksBuildPhase; 159 | buildActionMask = 2147483647; 160 | files = ( 161 | 140ED2AC1D01E1AD002B40FF /* libReact.a in Frameworks */, 162 | ); 163 | runOnlyForDeploymentPostprocessing = 0; 164 | }; 165 | 13B07F8C1A680F5B00A75B9A /* Frameworks */ = { 166 | isa = PBXFrameworksBuildPhase; 167 | buildActionMask = 2147483647; 168 | files = ( 169 | 146834051AC3E58100842450 /* libReact.a in Frameworks */, 170 | 00C302E51ABCBA2D00DB3ED1 /* libRCTActionSheet.a in Frameworks */, 171 | 00C302E71ABCBA2D00DB3ED1 /* libRCTGeolocation.a in Frameworks */, 172 | 00C302E81ABCBA2D00DB3ED1 /* libRCTImage.a in Frameworks */, 173 | 133E29F31AD74F7200F7D852 /* libRCTLinking.a in Frameworks */, 174 | 00C302E91ABCBA2D00DB3ED1 /* libRCTNetwork.a in Frameworks */, 175 | 139105C61AF99C1200B5F7CC /* libRCTSettings.a in Frameworks */, 176 | 832341BD1AAA6AB300B99B32 /* libRCTText.a in Frameworks */, 177 | 00C302EA1ABCBA2D00DB3ED1 /* libRCTVibration.a in Frameworks */, 178 | 139FDEF61B0652A700C62182 /* libRCTWebSocket.a in Frameworks */, 179 | 1B7B682E03494510B314FE30 /* libRealmReact.a in Frameworks */, 180 | 66042F8050C042D191A67066 /* libc++.tbd in Frameworks */, 181 | D7368AF80EDE41E98807AE61 /* libz.tbd in Frameworks */, 182 | 8F2A940722B846A3975E9306 /* libRNShare.a in Frameworks */, 183 | ); 184 | runOnlyForDeploymentPostprocessing = 0; 185 | }; 186 | /* End PBXFrameworksBuildPhase section */ 187 | 188 | /* Begin PBXGroup section */ 189 | 00C302A81ABCB8CE00DB3ED1 /* Products */ = { 190 | isa = PBXGroup; 191 | children = ( 192 | 00C302AC1ABCB8CE00DB3ED1 /* libRCTActionSheet.a */, 193 | ); 194 | name = Products; 195 | sourceTree = ""; 196 | }; 197 | 00C302B61ABCB90400DB3ED1 /* Products */ = { 198 | isa = PBXGroup; 199 | children = ( 200 | 00C302BA1ABCB90400DB3ED1 /* libRCTGeolocation.a */, 201 | ); 202 | name = Products; 203 | sourceTree = ""; 204 | }; 205 | 00C302BC1ABCB91800DB3ED1 /* Products */ = { 206 | isa = PBXGroup; 207 | children = ( 208 | 00C302C01ABCB91800DB3ED1 /* libRCTImage.a */, 209 | ); 210 | name = Products; 211 | sourceTree = ""; 212 | }; 213 | 00C302D41ABCB9D200DB3ED1 /* Products */ = { 214 | isa = PBXGroup; 215 | children = ( 216 | 00C302DC1ABCB9D200DB3ED1 /* libRCTNetwork.a */, 217 | ); 218 | name = Products; 219 | sourceTree = ""; 220 | }; 221 | 00C302E01ABCB9EE00DB3ED1 /* Products */ = { 222 | isa = PBXGroup; 223 | children = ( 224 | 00C302E41ABCB9EE00DB3ED1 /* libRCTVibration.a */, 225 | ); 226 | name = Products; 227 | sourceTree = ""; 228 | }; 229 | 00E356EF1AD99517003FC87E /* marvelTests */ = { 230 | isa = PBXGroup; 231 | children = ( 232 | 00E356F21AD99517003FC87E /* marvelTests.m */, 233 | 00E356F01AD99517003FC87E /* Supporting Files */, 234 | ); 235 | path = marvelTests; 236 | sourceTree = ""; 237 | }; 238 | 00E356F01AD99517003FC87E /* Supporting Files */ = { 239 | isa = PBXGroup; 240 | children = ( 241 | 00E356F11AD99517003FC87E /* Info.plist */, 242 | ); 243 | name = "Supporting Files"; 244 | sourceTree = ""; 245 | }; 246 | 139105B71AF99BAD00B5F7CC /* Products */ = { 247 | isa = PBXGroup; 248 | children = ( 249 | 139105C11AF99BAD00B5F7CC /* libRCTSettings.a */, 250 | ); 251 | name = Products; 252 | sourceTree = ""; 253 | }; 254 | 139FDEE71B06529A00C62182 /* Products */ = { 255 | isa = PBXGroup; 256 | children = ( 257 | 139FDEF41B06529B00C62182 /* libRCTWebSocket.a */, 258 | ); 259 | name = Products; 260 | sourceTree = ""; 261 | }; 262 | 13B07FAE1A68108700A75B9A /* marvel */ = { 263 | isa = PBXGroup; 264 | children = ( 265 | 008F07F21AC5B25A0029DE68 /* main.jsbundle */, 266 | 13B07FAF1A68108700A75B9A /* AppDelegate.h */, 267 | 13B07FB01A68108700A75B9A /* AppDelegate.m */, 268 | 13B07FB51A68108700A75B9A /* Images.xcassets */, 269 | 13B07FB61A68108700A75B9A /* Info.plist */, 270 | 13B07FB11A68108700A75B9A /* LaunchScreen.xib */, 271 | 13B07FB71A68108700A75B9A /* main.m */, 272 | ); 273 | name = marvel; 274 | sourceTree = ""; 275 | }; 276 | 146834001AC3E56700842450 /* Products */ = { 277 | isa = PBXGroup; 278 | children = ( 279 | 146834041AC3E56700842450 /* libReact.a */, 280 | ); 281 | name = Products; 282 | sourceTree = ""; 283 | }; 284 | 78C398B11ACF4ADC00677621 /* Products */ = { 285 | isa = PBXGroup; 286 | children = ( 287 | 78C398B91ACF4ADC00677621 /* libRCTLinking.a */, 288 | ); 289 | name = Products; 290 | sourceTree = ""; 291 | }; 292 | 832341AE1AAA6A7D00B99B32 /* Libraries */ = { 293 | isa = PBXGroup; 294 | children = ( 295 | 146833FF1AC3E56700842450 /* React.xcodeproj */, 296 | 00C302A71ABCB8CE00DB3ED1 /* RCTActionSheet.xcodeproj */, 297 | 00C302B51ABCB90400DB3ED1 /* RCTGeolocation.xcodeproj */, 298 | 00C302BB1ABCB91800DB3ED1 /* RCTImage.xcodeproj */, 299 | 78C398B01ACF4ADC00677621 /* RCTLinking.xcodeproj */, 300 | 00C302D31ABCB9D200DB3ED1 /* RCTNetwork.xcodeproj */, 301 | 139105B61AF99BAD00B5F7CC /* RCTSettings.xcodeproj */, 302 | 832341B01AAA6A8300B99B32 /* RCTText.xcodeproj */, 303 | 00C302DF1ABCB9EE00DB3ED1 /* RCTVibration.xcodeproj */, 304 | 139FDEE61B06529A00C62182 /* RCTWebSocket.xcodeproj */, 305 | 1CDF97DEBB87431A98112D3D /* RealmReact.xcodeproj */, 306 | F1B396788B9A49E0BC62F132 /* RNShare.xcodeproj */, 307 | ); 308 | name = Libraries; 309 | sourceTree = ""; 310 | }; 311 | 832341B11AAA6A8300B99B32 /* Products */ = { 312 | isa = PBXGroup; 313 | children = ( 314 | 832341B51AAA6A8300B99B32 /* libRCTText.a */, 315 | ); 316 | name = Products; 317 | sourceTree = ""; 318 | }; 319 | 83CBB9F61A601CBA00E9B192 = { 320 | isa = PBXGroup; 321 | children = ( 322 | 13B07FAE1A68108700A75B9A /* marvel */, 323 | 832341AE1AAA6A7D00B99B32 /* Libraries */, 324 | 00E356EF1AD99517003FC87E /* marvelTests */, 325 | 83CBBA001A601CBA00E9B192 /* Products */, 326 | BD3F67DC11D941A38C16B943 /* Frameworks */, 327 | ); 328 | indentWidth = 2; 329 | sourceTree = ""; 330 | tabWidth = 2; 331 | }; 332 | 83CBBA001A601CBA00E9B192 /* Products */ = { 333 | isa = PBXGroup; 334 | children = ( 335 | 13B07F961A680F5B00A75B9A /* marvel.app */, 336 | 00E356EE1AD99517003FC87E /* marvelTests.xctest */, 337 | ); 338 | name = Products; 339 | sourceTree = ""; 340 | }; 341 | 933F86B31D21585C00E952A2 /* Products */ = { 342 | isa = PBXGroup; 343 | children = ( 344 | 933F86C11D21585C00E952A2 /* libRealmReact.a */, 345 | ); 346 | name = Products; 347 | sourceTree = ""; 348 | }; 349 | 93747F281D2A841B00673B55 /* Products */ = { 350 | isa = PBXGroup; 351 | children = ( 352 | 93747F371D2A841B00673B55 /* libRNShare.a */, 353 | ); 354 | name = Products; 355 | sourceTree = ""; 356 | }; 357 | BD3F67DC11D941A38C16B943 /* Frameworks */ = { 358 | isa = PBXGroup; 359 | children = ( 360 | 42EFFF3EB6DF4AEC84E246D4 /* libc++.tbd */, 361 | A0D5E1A21E67465B91DDFD72 /* libz.tbd */, 362 | ); 363 | name = Frameworks; 364 | sourceTree = ""; 365 | }; 366 | /* End PBXGroup section */ 367 | 368 | /* Begin PBXNativeTarget section */ 369 | 00E356ED1AD99517003FC87E /* marvelTests */ = { 370 | isa = PBXNativeTarget; 371 | buildConfigurationList = 00E357021AD99517003FC87E /* Build configuration list for PBXNativeTarget "marvelTests" */; 372 | buildPhases = ( 373 | 00E356EA1AD99517003FC87E /* Sources */, 374 | 00E356EB1AD99517003FC87E /* Frameworks */, 375 | 00E356EC1AD99517003FC87E /* Resources */, 376 | ); 377 | buildRules = ( 378 | ); 379 | dependencies = ( 380 | 00E356F51AD99517003FC87E /* PBXTargetDependency */, 381 | ); 382 | name = marvelTests; 383 | productName = marvelTests; 384 | productReference = 00E356EE1AD99517003FC87E /* marvelTests.xctest */; 385 | productType = "com.apple.product-type.bundle.unit-test"; 386 | }; 387 | 13B07F861A680F5B00A75B9A /* marvel */ = { 388 | isa = PBXNativeTarget; 389 | buildConfigurationList = 13B07F931A680F5B00A75B9A /* Build configuration list for PBXNativeTarget "marvel" */; 390 | buildPhases = ( 391 | 13B07F871A680F5B00A75B9A /* Sources */, 392 | 13B07F8C1A680F5B00A75B9A /* Frameworks */, 393 | 13B07F8E1A680F5B00A75B9A /* Resources */, 394 | 00DD1BFF1BD5951E006B06BC /* Bundle React Native code and images */, 395 | ); 396 | buildRules = ( 397 | ); 398 | dependencies = ( 399 | ); 400 | name = marvel; 401 | productName = "Hello World"; 402 | productReference = 13B07F961A680F5B00A75B9A /* marvel.app */; 403 | productType = "com.apple.product-type.application"; 404 | }; 405 | /* End PBXNativeTarget section */ 406 | 407 | /* Begin PBXProject section */ 408 | 83CBB9F71A601CBA00E9B192 /* Project object */ = { 409 | isa = PBXProject; 410 | attributes = { 411 | LastUpgradeCheck = 0720; 412 | ORGANIZATIONNAME = Facebook; 413 | TargetAttributes = { 414 | 00E356ED1AD99517003FC87E = { 415 | CreatedOnToolsVersion = 6.2; 416 | TestTargetID = 13B07F861A680F5B00A75B9A; 417 | }; 418 | }; 419 | }; 420 | buildConfigurationList = 83CBB9FA1A601CBA00E9B192 /* Build configuration list for PBXProject "marvel" */; 421 | compatibilityVersion = "Xcode 3.2"; 422 | developmentRegion = English; 423 | hasScannedForEncodings = 0; 424 | knownRegions = ( 425 | en, 426 | Base, 427 | ); 428 | mainGroup = 83CBB9F61A601CBA00E9B192; 429 | productRefGroup = 83CBBA001A601CBA00E9B192 /* Products */; 430 | projectDirPath = ""; 431 | projectReferences = ( 432 | { 433 | ProductGroup = 00C302A81ABCB8CE00DB3ED1 /* Products */; 434 | ProjectRef = 00C302A71ABCB8CE00DB3ED1 /* RCTActionSheet.xcodeproj */; 435 | }, 436 | { 437 | ProductGroup = 00C302B61ABCB90400DB3ED1 /* Products */; 438 | ProjectRef = 00C302B51ABCB90400DB3ED1 /* RCTGeolocation.xcodeproj */; 439 | }, 440 | { 441 | ProductGroup = 00C302BC1ABCB91800DB3ED1 /* Products */; 442 | ProjectRef = 00C302BB1ABCB91800DB3ED1 /* RCTImage.xcodeproj */; 443 | }, 444 | { 445 | ProductGroup = 78C398B11ACF4ADC00677621 /* Products */; 446 | ProjectRef = 78C398B01ACF4ADC00677621 /* RCTLinking.xcodeproj */; 447 | }, 448 | { 449 | ProductGroup = 00C302D41ABCB9D200DB3ED1 /* Products */; 450 | ProjectRef = 00C302D31ABCB9D200DB3ED1 /* RCTNetwork.xcodeproj */; 451 | }, 452 | { 453 | ProductGroup = 139105B71AF99BAD00B5F7CC /* Products */; 454 | ProjectRef = 139105B61AF99BAD00B5F7CC /* RCTSettings.xcodeproj */; 455 | }, 456 | { 457 | ProductGroup = 832341B11AAA6A8300B99B32 /* Products */; 458 | ProjectRef = 832341B01AAA6A8300B99B32 /* RCTText.xcodeproj */; 459 | }, 460 | { 461 | ProductGroup = 00C302E01ABCB9EE00DB3ED1 /* Products */; 462 | ProjectRef = 00C302DF1ABCB9EE00DB3ED1 /* RCTVibration.xcodeproj */; 463 | }, 464 | { 465 | ProductGroup = 139FDEE71B06529A00C62182 /* Products */; 466 | ProjectRef = 139FDEE61B06529A00C62182 /* RCTWebSocket.xcodeproj */; 467 | }, 468 | { 469 | ProductGroup = 146834001AC3E56700842450 /* Products */; 470 | ProjectRef = 146833FF1AC3E56700842450 /* React.xcodeproj */; 471 | }, 472 | { 473 | ProductGroup = 933F86B31D21585C00E952A2 /* Products */; 474 | ProjectRef = 1CDF97DEBB87431A98112D3D /* RealmReact.xcodeproj */; 475 | }, 476 | { 477 | ProductGroup = 93747F281D2A841B00673B55 /* Products */; 478 | ProjectRef = F1B396788B9A49E0BC62F132 /* RNShare.xcodeproj */; 479 | }, 480 | ); 481 | projectRoot = ""; 482 | targets = ( 483 | 13B07F861A680F5B00A75B9A /* marvel */, 484 | 00E356ED1AD99517003FC87E /* marvelTests */, 485 | ); 486 | }; 487 | /* End PBXProject section */ 488 | 489 | /* Begin PBXReferenceProxy section */ 490 | 00C302AC1ABCB8CE00DB3ED1 /* libRCTActionSheet.a */ = { 491 | isa = PBXReferenceProxy; 492 | fileType = archive.ar; 493 | path = libRCTActionSheet.a; 494 | remoteRef = 00C302AB1ABCB8CE00DB3ED1 /* PBXContainerItemProxy */; 495 | sourceTree = BUILT_PRODUCTS_DIR; 496 | }; 497 | 00C302BA1ABCB90400DB3ED1 /* libRCTGeolocation.a */ = { 498 | isa = PBXReferenceProxy; 499 | fileType = archive.ar; 500 | path = libRCTGeolocation.a; 501 | remoteRef = 00C302B91ABCB90400DB3ED1 /* PBXContainerItemProxy */; 502 | sourceTree = BUILT_PRODUCTS_DIR; 503 | }; 504 | 00C302C01ABCB91800DB3ED1 /* libRCTImage.a */ = { 505 | isa = PBXReferenceProxy; 506 | fileType = archive.ar; 507 | path = libRCTImage.a; 508 | remoteRef = 00C302BF1ABCB91800DB3ED1 /* PBXContainerItemProxy */; 509 | sourceTree = BUILT_PRODUCTS_DIR; 510 | }; 511 | 00C302DC1ABCB9D200DB3ED1 /* libRCTNetwork.a */ = { 512 | isa = PBXReferenceProxy; 513 | fileType = archive.ar; 514 | path = libRCTNetwork.a; 515 | remoteRef = 00C302DB1ABCB9D200DB3ED1 /* PBXContainerItemProxy */; 516 | sourceTree = BUILT_PRODUCTS_DIR; 517 | }; 518 | 00C302E41ABCB9EE00DB3ED1 /* libRCTVibration.a */ = { 519 | isa = PBXReferenceProxy; 520 | fileType = archive.ar; 521 | path = libRCTVibration.a; 522 | remoteRef = 00C302E31ABCB9EE00DB3ED1 /* PBXContainerItemProxy */; 523 | sourceTree = BUILT_PRODUCTS_DIR; 524 | }; 525 | 139105C11AF99BAD00B5F7CC /* libRCTSettings.a */ = { 526 | isa = PBXReferenceProxy; 527 | fileType = archive.ar; 528 | path = libRCTSettings.a; 529 | remoteRef = 139105C01AF99BAD00B5F7CC /* PBXContainerItemProxy */; 530 | sourceTree = BUILT_PRODUCTS_DIR; 531 | }; 532 | 139FDEF41B06529B00C62182 /* libRCTWebSocket.a */ = { 533 | isa = PBXReferenceProxy; 534 | fileType = archive.ar; 535 | path = libRCTWebSocket.a; 536 | remoteRef = 139FDEF31B06529B00C62182 /* PBXContainerItemProxy */; 537 | sourceTree = BUILT_PRODUCTS_DIR; 538 | }; 539 | 146834041AC3E56700842450 /* libReact.a */ = { 540 | isa = PBXReferenceProxy; 541 | fileType = archive.ar; 542 | path = libReact.a; 543 | remoteRef = 146834031AC3E56700842450 /* PBXContainerItemProxy */; 544 | sourceTree = BUILT_PRODUCTS_DIR; 545 | }; 546 | 78C398B91ACF4ADC00677621 /* libRCTLinking.a */ = { 547 | isa = PBXReferenceProxy; 548 | fileType = archive.ar; 549 | path = libRCTLinking.a; 550 | remoteRef = 78C398B81ACF4ADC00677621 /* PBXContainerItemProxy */; 551 | sourceTree = BUILT_PRODUCTS_DIR; 552 | }; 553 | 832341B51AAA6A8300B99B32 /* libRCTText.a */ = { 554 | isa = PBXReferenceProxy; 555 | fileType = archive.ar; 556 | path = libRCTText.a; 557 | remoteRef = 832341B41AAA6A8300B99B32 /* PBXContainerItemProxy */; 558 | sourceTree = BUILT_PRODUCTS_DIR; 559 | }; 560 | 933F86C11D21585C00E952A2 /* libRealmReact.a */ = { 561 | isa = PBXReferenceProxy; 562 | fileType = archive.ar; 563 | path = libRealmReact.a; 564 | remoteRef = 933F86C01D21585C00E952A2 /* PBXContainerItemProxy */; 565 | sourceTree = BUILT_PRODUCTS_DIR; 566 | }; 567 | 93747F371D2A841B00673B55 /* libRNShare.a */ = { 568 | isa = PBXReferenceProxy; 569 | fileType = archive.ar; 570 | path = libRNShare.a; 571 | remoteRef = 93747F361D2A841B00673B55 /* PBXContainerItemProxy */; 572 | sourceTree = BUILT_PRODUCTS_DIR; 573 | }; 574 | /* End PBXReferenceProxy section */ 575 | 576 | /* Begin PBXResourcesBuildPhase section */ 577 | 00E356EC1AD99517003FC87E /* Resources */ = { 578 | isa = PBXResourcesBuildPhase; 579 | buildActionMask = 2147483647; 580 | files = ( 581 | ); 582 | runOnlyForDeploymentPostprocessing = 0; 583 | }; 584 | 13B07F8E1A680F5B00A75B9A /* Resources */ = { 585 | isa = PBXResourcesBuildPhase; 586 | buildActionMask = 2147483647; 587 | files = ( 588 | 13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */, 589 | 13B07FBD1A68108700A75B9A /* LaunchScreen.xib in Resources */, 590 | ); 591 | runOnlyForDeploymentPostprocessing = 0; 592 | }; 593 | /* End PBXResourcesBuildPhase section */ 594 | 595 | /* Begin PBXShellScriptBuildPhase section */ 596 | 00DD1BFF1BD5951E006B06BC /* Bundle React Native code and images */ = { 597 | isa = PBXShellScriptBuildPhase; 598 | buildActionMask = 2147483647; 599 | files = ( 600 | ); 601 | inputPaths = ( 602 | ); 603 | name = "Bundle React Native code and images"; 604 | outputPaths = ( 605 | ); 606 | runOnlyForDeploymentPostprocessing = 0; 607 | shellPath = /bin/sh; 608 | shellScript = "export NODE_BINARY=node\n../node_modules/react-native/packager/react-native-xcode.sh"; 609 | }; 610 | /* End PBXShellScriptBuildPhase section */ 611 | 612 | /* Begin PBXSourcesBuildPhase section */ 613 | 00E356EA1AD99517003FC87E /* Sources */ = { 614 | isa = PBXSourcesBuildPhase; 615 | buildActionMask = 2147483647; 616 | files = ( 617 | 00E356F31AD99517003FC87E /* marvelTests.m in Sources */, 618 | ); 619 | runOnlyForDeploymentPostprocessing = 0; 620 | }; 621 | 13B07F871A680F5B00A75B9A /* Sources */ = { 622 | isa = PBXSourcesBuildPhase; 623 | buildActionMask = 2147483647; 624 | files = ( 625 | 13B07FBC1A68108700A75B9A /* AppDelegate.m in Sources */, 626 | 13B07FC11A68108700A75B9A /* main.m in Sources */, 627 | ); 628 | runOnlyForDeploymentPostprocessing = 0; 629 | }; 630 | /* End PBXSourcesBuildPhase section */ 631 | 632 | /* Begin PBXTargetDependency section */ 633 | 00E356F51AD99517003FC87E /* PBXTargetDependency */ = { 634 | isa = PBXTargetDependency; 635 | target = 13B07F861A680F5B00A75B9A /* marvel */; 636 | targetProxy = 00E356F41AD99517003FC87E /* PBXContainerItemProxy */; 637 | }; 638 | /* End PBXTargetDependency section */ 639 | 640 | /* Begin PBXVariantGroup section */ 641 | 13B07FB11A68108700A75B9A /* LaunchScreen.xib */ = { 642 | isa = PBXVariantGroup; 643 | children = ( 644 | 13B07FB21A68108700A75B9A /* Base */, 645 | ); 646 | name = LaunchScreen.xib; 647 | path = marvel; 648 | sourceTree = ""; 649 | }; 650 | /* End PBXVariantGroup section */ 651 | 652 | /* Begin XCBuildConfiguration section */ 653 | 00E356F61AD99517003FC87E /* Debug */ = { 654 | isa = XCBuildConfiguration; 655 | buildSettings = { 656 | BUNDLE_LOADER = "$(TEST_HOST)"; 657 | GCC_PREPROCESSOR_DEFINITIONS = ( 658 | "DEBUG=1", 659 | "$(inherited)", 660 | ); 661 | INFOPLIST_FILE = marvelTests/Info.plist; 662 | IPHONEOS_DEPLOYMENT_TARGET = 8.2; 663 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 664 | LIBRARY_SEARCH_PATHS = ( 665 | "$(inherited)", 666 | "\"$(SRCROOT)/$(TARGET_NAME)\"", 667 | "\"$(SRCROOT)/$(TARGET_NAME)\"", 668 | ); 669 | PRODUCT_BUNDLE_IDENTIFIER = "org.reactjs.native.example.$(PRODUCT_NAME:rfc1034identifier)"; 670 | PRODUCT_NAME = "$(TARGET_NAME)"; 671 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/marvel.app/marvel"; 672 | }; 673 | name = Debug; 674 | }; 675 | 00E356F71AD99517003FC87E /* Release */ = { 676 | isa = XCBuildConfiguration; 677 | buildSettings = { 678 | BUNDLE_LOADER = "$(TEST_HOST)"; 679 | COPY_PHASE_STRIP = NO; 680 | INFOPLIST_FILE = marvelTests/Info.plist; 681 | IPHONEOS_DEPLOYMENT_TARGET = 8.2; 682 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 683 | LIBRARY_SEARCH_PATHS = ( 684 | "$(inherited)", 685 | "\"$(SRCROOT)/$(TARGET_NAME)\"", 686 | "\"$(SRCROOT)/$(TARGET_NAME)\"", 687 | ); 688 | PRODUCT_BUNDLE_IDENTIFIER = "org.reactjs.native.example.$(PRODUCT_NAME:rfc1034identifier)"; 689 | PRODUCT_NAME = "$(TARGET_NAME)"; 690 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/marvel.app/marvel"; 691 | }; 692 | name = Release; 693 | }; 694 | 13B07F941A680F5B00A75B9A /* Debug */ = { 695 | isa = XCBuildConfiguration; 696 | buildSettings = { 697 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 698 | DEAD_CODE_STRIPPING = NO; 699 | HEADER_SEARCH_PATHS = ( 700 | "$(inherited)", 701 | /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include, 702 | "$(SRCROOT)/../node_modules/react-native/React/**", 703 | "$(SRCROOT)/../node_modules/realm/src/**", 704 | "$(SRCROOT)/../node_modules/react-native-share/ios", 705 | ); 706 | INFOPLIST_FILE = marvel/Info.plist; 707 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 708 | OTHER_LDFLAGS = ( 709 | "-ObjC", 710 | "-lc++", 711 | ); 712 | PRODUCT_BUNDLE_IDENTIFIER = "org.reactjs.native.example.$(PRODUCT_NAME:rfc1034identifier)"; 713 | PRODUCT_NAME = marvel; 714 | }; 715 | name = Debug; 716 | }; 717 | 13B07F951A680F5B00A75B9A /* Release */ = { 718 | isa = XCBuildConfiguration; 719 | buildSettings = { 720 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 721 | HEADER_SEARCH_PATHS = ( 722 | "$(inherited)", 723 | /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include, 724 | "$(SRCROOT)/../node_modules/react-native/React/**", 725 | "$(SRCROOT)/../node_modules/realm/src/**", 726 | "$(SRCROOT)/../node_modules/react-native-share/ios", 727 | ); 728 | INFOPLIST_FILE = marvel/Info.plist; 729 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 730 | OTHER_LDFLAGS = ( 731 | "-ObjC", 732 | "-lc++", 733 | ); 734 | PRODUCT_BUNDLE_IDENTIFIER = "org.reactjs.native.example.$(PRODUCT_NAME:rfc1034identifier)"; 735 | PRODUCT_NAME = marvel; 736 | }; 737 | name = Release; 738 | }; 739 | 83CBBA201A601CBA00E9B192 /* Debug */ = { 740 | isa = XCBuildConfiguration; 741 | buildSettings = { 742 | ALWAYS_SEARCH_USER_PATHS = NO; 743 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 744 | CLANG_CXX_LIBRARY = "libc++"; 745 | CLANG_ENABLE_MODULES = YES; 746 | CLANG_ENABLE_OBJC_ARC = YES; 747 | CLANG_WARN_BOOL_CONVERSION = YES; 748 | CLANG_WARN_CONSTANT_CONVERSION = YES; 749 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 750 | CLANG_WARN_EMPTY_BODY = YES; 751 | CLANG_WARN_ENUM_CONVERSION = YES; 752 | CLANG_WARN_INT_CONVERSION = YES; 753 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 754 | CLANG_WARN_UNREACHABLE_CODE = YES; 755 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 756 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 757 | COPY_PHASE_STRIP = NO; 758 | ENABLE_STRICT_OBJC_MSGSEND = YES; 759 | ENABLE_TESTABILITY = YES; 760 | GCC_C_LANGUAGE_STANDARD = gnu99; 761 | GCC_DYNAMIC_NO_PIC = NO; 762 | GCC_OPTIMIZATION_LEVEL = 0; 763 | GCC_PREPROCESSOR_DEFINITIONS = ( 764 | "DEBUG=1", 765 | "$(inherited)", 766 | ); 767 | GCC_SYMBOLS_PRIVATE_EXTERN = NO; 768 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 769 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 770 | GCC_WARN_UNDECLARED_SELECTOR = YES; 771 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 772 | GCC_WARN_UNUSED_FUNCTION = YES; 773 | GCC_WARN_UNUSED_VARIABLE = YES; 774 | HEADER_SEARCH_PATHS = ( 775 | "$(inherited)", 776 | /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include, 777 | "$(SRCROOT)/../node_modules/react-native/React/**", 778 | "$(SRCROOT)/../node_modules/realm/src/**", 779 | "$(SRCROOT)/../node_modules/react-native-share/ios", 780 | ); 781 | IPHONEOS_DEPLOYMENT_TARGET = 7.0; 782 | MTL_ENABLE_DEBUG_INFO = YES; 783 | ONLY_ACTIVE_ARCH = YES; 784 | SDKROOT = iphoneos; 785 | }; 786 | name = Debug; 787 | }; 788 | 83CBBA211A601CBA00E9B192 /* Release */ = { 789 | isa = XCBuildConfiguration; 790 | buildSettings = { 791 | ALWAYS_SEARCH_USER_PATHS = NO; 792 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 793 | CLANG_CXX_LIBRARY = "libc++"; 794 | CLANG_ENABLE_MODULES = YES; 795 | CLANG_ENABLE_OBJC_ARC = YES; 796 | CLANG_WARN_BOOL_CONVERSION = YES; 797 | CLANG_WARN_CONSTANT_CONVERSION = YES; 798 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 799 | CLANG_WARN_EMPTY_BODY = YES; 800 | CLANG_WARN_ENUM_CONVERSION = YES; 801 | CLANG_WARN_INT_CONVERSION = YES; 802 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 803 | CLANG_WARN_UNREACHABLE_CODE = YES; 804 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 805 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 806 | COPY_PHASE_STRIP = YES; 807 | ENABLE_NS_ASSERTIONS = NO; 808 | ENABLE_STRICT_OBJC_MSGSEND = YES; 809 | GCC_C_LANGUAGE_STANDARD = gnu99; 810 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 811 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 812 | GCC_WARN_UNDECLARED_SELECTOR = YES; 813 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 814 | GCC_WARN_UNUSED_FUNCTION = YES; 815 | GCC_WARN_UNUSED_VARIABLE = YES; 816 | HEADER_SEARCH_PATHS = ( 817 | "$(inherited)", 818 | /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include, 819 | "$(SRCROOT)/../node_modules/react-native/React/**", 820 | "$(SRCROOT)/../node_modules/realm/src/**", 821 | "$(SRCROOT)/../node_modules/react-native-share/ios", 822 | ); 823 | IPHONEOS_DEPLOYMENT_TARGET = 7.0; 824 | MTL_ENABLE_DEBUG_INFO = NO; 825 | SDKROOT = iphoneos; 826 | VALIDATE_PRODUCT = YES; 827 | }; 828 | name = Release; 829 | }; 830 | /* End XCBuildConfiguration section */ 831 | 832 | /* Begin XCConfigurationList section */ 833 | 00E357021AD99517003FC87E /* Build configuration list for PBXNativeTarget "marvelTests" */ = { 834 | isa = XCConfigurationList; 835 | buildConfigurations = ( 836 | 00E356F61AD99517003FC87E /* Debug */, 837 | 00E356F71AD99517003FC87E /* Release */, 838 | ); 839 | defaultConfigurationIsVisible = 0; 840 | defaultConfigurationName = Release; 841 | }; 842 | 13B07F931A680F5B00A75B9A /* Build configuration list for PBXNativeTarget "marvel" */ = { 843 | isa = XCConfigurationList; 844 | buildConfigurations = ( 845 | 13B07F941A680F5B00A75B9A /* Debug */, 846 | 13B07F951A680F5B00A75B9A /* Release */, 847 | ); 848 | defaultConfigurationIsVisible = 0; 849 | defaultConfigurationName = Release; 850 | }; 851 | 83CBB9FA1A601CBA00E9B192 /* Build configuration list for PBXProject "marvel" */ = { 852 | isa = XCConfigurationList; 853 | buildConfigurations = ( 854 | 83CBBA201A601CBA00E9B192 /* Debug */, 855 | 83CBBA211A601CBA00E9B192 /* Release */, 856 | ); 857 | defaultConfigurationIsVisible = 0; 858 | defaultConfigurationName = Release; 859 | }; 860 | /* End XCConfigurationList section */ 861 | }; 862 | rootObject = 83CBB9F71A601CBA00E9B192 /* Project object */; 863 | } 864 | -------------------------------------------------------------------------------- /ios/marvel.xcodeproj/xcshareddata/xcschemes/marvel.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 | 67 | 68 | 78 | 80 | 86 | 87 | 88 | 89 | 90 | 91 | 97 | 99 | 105 | 106 | 107 | 108 | 110 | 111 | 114 | 115 | 116 | -------------------------------------------------------------------------------- /ios/marvel/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 | -------------------------------------------------------------------------------- /ios/marvel/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 the "Bundle React Native code and images" build step when 40 | * running the project on an actual device or running the project on the 41 | * simulator in the "Release" build configuration. 42 | */ 43 | 44 | // jsCodeLocation = [[NSBundle mainBundle] URLForResource:@"main" withExtension:@"jsbundle"]; 45 | 46 | RCTRootView *rootView = [[RCTRootView alloc] initWithBundleURL:jsCodeLocation 47 | moduleName:@"marvel" 48 | initialProperties:nil 49 | launchOptions:launchOptions]; 50 | rootView.backgroundColor = [[UIColor alloc] initWithRed:1.0f green:1.0f blue:1.0f alpha:1]; 51 | 52 | self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds]; 53 | UIViewController *rootViewController = [UIViewController new]; 54 | rootViewController.view = rootView; 55 | self.window.rootViewController = rootViewController; 56 | [self.window makeKeyAndVisible]; 57 | return YES; 58 | } 59 | 60 | @end 61 | -------------------------------------------------------------------------------- /ios/marvel/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 | -------------------------------------------------------------------------------- /ios/marvel/Images.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "size" : "29x29", 5 | "idiom" : "iphone", 6 | "filename" : "ic_launcher58.png", 7 | "scale" : "2x" 8 | }, 9 | { 10 | "size" : "29x29", 11 | "idiom" : "iphone", 12 | "filename" : "ic_launcher87.png", 13 | "scale" : "3x" 14 | }, 15 | { 16 | "size" : "40x40", 17 | "idiom" : "iphone", 18 | "filename" : "ic_launcher80.png", 19 | "scale" : "2x" 20 | }, 21 | { 22 | "size" : "40x40", 23 | "idiom" : "iphone", 24 | "filename" : "ic_launcher120-1.png", 25 | "scale" : "3x" 26 | }, 27 | { 28 | "size" : "60x60", 29 | "idiom" : "iphone", 30 | "filename" : "ic_launcher120.png", 31 | "scale" : "2x" 32 | }, 33 | { 34 | "size" : "60x60", 35 | "idiom" : "iphone", 36 | "filename" : "ic_launcher180.png", 37 | "scale" : "3x" 38 | } 39 | ], 40 | "info" : { 41 | "version" : 1, 42 | "author" : "xcode" 43 | } 44 | } -------------------------------------------------------------------------------- /ios/marvel/Images.xcassets/AppIcon.appiconset/ic_launcher120-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Shuijwan/marvel/47f2a96ed37af852892b10a07512f61a3070d99f/ios/marvel/Images.xcassets/AppIcon.appiconset/ic_launcher120-1.png -------------------------------------------------------------------------------- /ios/marvel/Images.xcassets/AppIcon.appiconset/ic_launcher120.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Shuijwan/marvel/47f2a96ed37af852892b10a07512f61a3070d99f/ios/marvel/Images.xcassets/AppIcon.appiconset/ic_launcher120.png -------------------------------------------------------------------------------- /ios/marvel/Images.xcassets/AppIcon.appiconset/ic_launcher180.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Shuijwan/marvel/47f2a96ed37af852892b10a07512f61a3070d99f/ios/marvel/Images.xcassets/AppIcon.appiconset/ic_launcher180.png -------------------------------------------------------------------------------- /ios/marvel/Images.xcassets/AppIcon.appiconset/ic_launcher58.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Shuijwan/marvel/47f2a96ed37af852892b10a07512f61a3070d99f/ios/marvel/Images.xcassets/AppIcon.appiconset/ic_launcher58.png -------------------------------------------------------------------------------- /ios/marvel/Images.xcassets/AppIcon.appiconset/ic_launcher80.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Shuijwan/marvel/47f2a96ed37af852892b10a07512f61a3070d99f/ios/marvel/Images.xcassets/AppIcon.appiconset/ic_launcher80.png -------------------------------------------------------------------------------- /ios/marvel/Images.xcassets/AppIcon.appiconset/ic_launcher87.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Shuijwan/marvel/47f2a96ed37af852892b10a07512f61a3070d99f/ios/marvel/Images.xcassets/AppIcon.appiconset/ic_launcher87.png -------------------------------------------------------------------------------- /ios/marvel/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 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 | NSAppTransportSecurity 26 | 27 | NSAllowsArbitraryLoads 28 | 29 | NSExceptionDomains 30 | 31 | localhost 32 | 33 | NSTemporaryExceptionAllowsInsecureHTTPLoads 34 | 35 | 36 | 37 | 38 | NSLocationWhenInUseUsageDescription 39 | 40 | UILaunchStoryboardName 41 | LaunchScreen 42 | UIRequiredDeviceCapabilities 43 | 44 | armv7 45 | 46 | UISupportedInterfaceOrientations 47 | 48 | UIInterfaceOrientationPortrait 49 | UIInterfaceOrientationLandscapeLeft 50 | UIInterfaceOrientationLandscapeRight 51 | 52 | UIViewControllerBasedStatusBarAppearance 53 | 54 | 55 | 56 | -------------------------------------------------------------------------------- /ios/marvel/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 | -------------------------------------------------------------------------------- /ios/marvelTests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 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 | -------------------------------------------------------------------------------- /ios/marvelTests/marvelTests.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 600 17 | #define TEXT_TO_LOOK_FOR @"Welcome to React Native!" 18 | 19 | @interface marvelTests : XCTestCase 20 | 21 | @end 22 | 23 | @implementation marvelTests 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, RCTLogSource source, 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 | -------------------------------------------------------------------------------- /js/MarvelApp.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @providesModule MarvelApp 3 | * @flow 4 | */ 5 | 6 | 'use strict'; 7 | 8 | var React = require('react'); 9 | // var AppState = require('AppState'); 10 | var SplashScreen = require('./splash/SplashScreen'); 11 | var MarvelNavigator = require('./MarvelNavigator'); 12 | var StatusBar = require('StatusBar'); 13 | var StyleSheet = require('StyleSheet'); 14 | var View = require('View'); 15 | 16 | var {connect} = require('react-redux'); 17 | var { getPopularCharacters } = require('./actions'); 18 | 19 | class MarvelApp extends React.Component { 20 | componentDidMount() { 21 | // AppState.addEventListener('change', this.handleAppStateChange); 22 | this.props.dispatch(getPopularCharacters()); 23 | } 24 | 25 | componentWillUnmount() { 26 | // AppState.removeEventListener('change', this.handleAppStateChange); 27 | } 28 | 29 | handleAppStateChange(appState) { 30 | if(appState == 'active') { 31 | 32 | } 33 | } 34 | 35 | render() { 36 | var content; 37 | if(this.props.inSplash) { 38 | content = ; 39 | } else { 40 | content = ; 41 | } 42 | 43 | return ( 44 | 45 | 50 | {content} 51 | 52 | ); 53 | } 54 | } 55 | 56 | var styles = StyleSheet.create({ 57 | container:{ 58 | flex: 1, 59 | }, 60 | }); 61 | 62 | function select(store) { 63 | return { 64 | inSplash: store.mainentry.inSplash, 65 | }; 66 | } 67 | 68 | module.exports = connect(select)(MarvelApp); 69 | -------------------------------------------------------------------------------- /js/MarvelNavigator.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @flow 3 | */ 4 | 5 | 'use strict'; 6 | 7 | var React = require('react'); 8 | var Platform = require('Platform'); 9 | var BackAndroid = require('BackAndroid'); 10 | var StyleSheet = require('StyleSheet'); 11 | var Navigator = require('Navigator'); 12 | var { connect } = require('react-redux'); 13 | var MarvelTabsView = require('MarvelTabsView'); 14 | var CharacterDetailView = require('./tabs/characters/CharacterDetailView'); 15 | var SearchView = require('./tabs/characters/SearchView'); 16 | var Platform = require('Platform'); 17 | 18 | var self; 19 | 20 | class MarvelNavigator extends React.Component { 21 | 22 | _backHandlers: Array<() => boolean>; 23 | 24 | constructor(props) { 25 | super(props); 26 | this._backHandlers = []; 27 | self = this; 28 | } 29 | 30 | componentDidMount() { 31 | if(Platform.OS === 'android') { 32 | BackAndroid.addEventListener('hardwareBackPress', this.handleBackPressed); 33 | } 34 | } 35 | 36 | componentWillUnmount() { 37 | if(Platform.OS === 'android') { 38 | BackAndroid.removeEventListener('hardwareBackPress', this.handleBackPressed); 39 | } 40 | } 41 | 42 | getChildContext() { 43 | return { 44 | addBackButtonListener: this.addBackButtonListener, 45 | removeBackButtonListener: this.removeBackButtonListener, 46 | }; 47 | } 48 | 49 | addBackButtonListener(listener) { 50 | self._backHandlers.push(listener); 51 | } 52 | 53 | removeBackButtonListener(listener) { 54 | self._backHandlers = self._backHandlers.filter((handler) => handler !== listener); 55 | } 56 | 57 | handleBackPressed() { 58 | for(let i=self._backHandlers.length-1; i>=0; i--) { 59 | if(self._backHandlers[i]()) { 60 | return true; 61 | } 62 | } 63 | 64 | var navigator = self.refs.navigator; 65 | if(navigator && navigator.getCurrentRoutes().length > 1) { 66 | navigator.pop(); 67 | return true; 68 | } 69 | 70 | return false; 71 | } 72 | 73 | render() { 74 | return ( 75 | { 79 | if(route.character) { 80 | return Navigator.SceneConfigs.PushFromRight; 81 | } 82 | if (Platform.OS === 'android') { 83 | return Navigator.SceneConfigs.FloatFromBottomAndroid; 84 | } 85 | 86 | return Navigator.SceneConfigs.FloatFromBottom; 87 | 88 | }} 89 | initialRoute={{}} 90 | renderScene={this.renderScene} 91 | /> 92 | 93 | ); 94 | } 95 | 96 | renderScene(route, navigator) { 97 | if(route.character) { 98 | return ( 99 | 100 | ); 101 | } 102 | 103 | if(route.search) { 104 | return ( 105 | 106 | ); 107 | } 108 | 109 | return ( 110 | 111 | ); 112 | } 113 | } 114 | 115 | MarvelNavigator.childContextTypes = { 116 | addBackButtonListener: React.PropTypes.func, 117 | removeBackButtonListener: React.PropTypes.func, 118 | }; 119 | 120 | var styles = StyleSheet.create({ 121 | container: { 122 | flex: 1, 123 | }, 124 | }); 125 | 126 | module.exports = connect()(MarvelNavigator); 127 | -------------------------------------------------------------------------------- /js/actions/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @flow 3 | */ 4 | 5 | 'use strict'; 6 | 7 | const mainentryActions = require('./mainentry'); 8 | const navigationActions = require('./navigation'); 9 | const marvelActions = require('./marvel'); 10 | 11 | module.exports = { 12 | ...mainentryActions, 13 | ...navigationActions, 14 | ...marvelActions, 15 | }; 16 | -------------------------------------------------------------------------------- /js/actions/mainentry.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @flow 3 | */ 4 | 5 | 'use strict'; 6 | 7 | import type {Action} from './types'; 8 | 9 | function enterMainPage(): Action { 10 | return { 11 | type: 'MAIN_ENTRY', 12 | }; 13 | } 14 | 15 | module.exports = {enterMainPage}; 16 | -------------------------------------------------------------------------------- /js/actions/marvel.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @flow 3 | */ 4 | 'use strict'; 5 | 6 | import type {Action} from './types'; 7 | import MarvelAPI from '../marvelapi/MarvelAPI'; 8 | import {writeCharacterToRealm, removePopularCharacter} from '../marvelapi/realmModel'; 9 | import type {Character} from '../marvelapi/model'; 10 | 11 | const marvel = new MarvelAPI(); 12 | 13 | async function getPopularCharacters(): Promise { 14 | const result = await marvel.getPopularCharacters(); 15 | return { 16 | type: 'GET_POPULAR_CHARACTERS', 17 | data: result 18 | }; 19 | } 20 | 21 | async function searchCharacterByName(name: string): Promise { 22 | const result = await marvel.searchCharacterByName(name); 23 | return { 24 | type: 'SEARCH_CHARACTER_BY_NAME', 25 | data: result 26 | }; 27 | } 28 | 29 | function clearSearchResult(): Action { 30 | return { 31 | type: 'SEARCH_CHARACTER_BY_NAME', 32 | data: null 33 | }; 34 | } 35 | 36 | async function getCharacterDetail(url: string): Promise { 37 | const result = await marvel.getDetail(url); 38 | return { 39 | type: 'GET_CHARACTER_DETAIL', 40 | data: result 41 | }; 42 | } 43 | 44 | async function markAsPopularCharacter(character: Character, mark: boolean): Promise { 45 | if(mark) { 46 | writeCharacterToRealm(character); 47 | } else { 48 | removePopularCharacter(character); 49 | } 50 | 51 | const result = await marvel.getPopularCharacters(); 52 | return { 53 | type: 'GET_POPULAR_CHARACTERS', 54 | data: result 55 | }; 56 | } 57 | 58 | 59 | module.exports = { getPopularCharacters, searchCharacterByName, getCharacterDetail, clearSearchResult, markAsPopularCharacter }; 60 | -------------------------------------------------------------------------------- /js/actions/navigation.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @flow 3 | */ 4 | 5 | 'use strict'; 6 | 7 | import type {Action} from './types'; 8 | import type {Tab} from '../reducers'; 9 | 10 | module.exports = { 11 | switchTab: (tab: Tab): Action => ({ 12 | type: 'SWITCH_TAB', 13 | tab, 14 | }), 15 | }; 16 | -------------------------------------------------------------------------------- /js/actions/types.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @flow 3 | */ 4 | 5 | 'use strict'; 6 | 7 | import type {Character} from '../marvelapi/model'; 8 | 9 | export type Action = 10 | { type: 'SWITCH_TAB', tab: 'characters' | 'search' | 'about' } 11 | | { type: 'MAIN_ENTRY' } 12 | | { type: 'GET_POPULAR_CHARACTERS', data: Array } 13 | | { type: 'SEARCH_CHARACTER_BY_NAME', data: ?Array } 14 | | { type: 'GET_CHARACTER_DETAIL', data: string } 15 | ; 16 | -------------------------------------------------------------------------------- /js/common/F8Colors.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2016 Facebook, Inc. 3 | * 4 | * You are hereby granted a non-exclusive, worldwide, royalty-free license to 5 | * use, copy, modify, and distribute this software in source code or binary 6 | * form for use in connection with the web services and APIs provided by 7 | * Facebook. 8 | * 9 | * As with any software that integrates with the Facebook platform, your use 10 | * of this software is subject to the Facebook Developer Principles and 11 | * Policies [http://developers.facebook.com/policy/]. This copyright notice 12 | * shall be included in all copies or substantial portions of the software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 17 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 19 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 20 | * DEALINGS IN THE SOFTWARE 21 | * 22 | * @providesModule F8Colors 23 | * @flow 24 | */ 25 | 26 | 'use strict'; 27 | 28 | const LOCATION_COLORS = { 29 | 'HERBST': '#00E3AD', 30 | 'HERBST A': '#00E3AD', 31 | 'HERBST B': '#00E3AD', 32 | 'HACKER X': '#4D99EF', 33 | 'HACKER Y': '#CF72B1', 34 | 'COWELL': '#6A6AD5', 35 | 'COWELL C': '#6A6AD5', 36 | 'FOOD TENT': '#FFCD3B', 37 | }; 38 | 39 | function colorForLocation(location: ?string): string { 40 | if (!location) { 41 | return 'black'; 42 | } 43 | 44 | var color = LOCATION_COLORS[location.toUpperCase()]; 45 | if (!color) { 46 | console.warn(`Location '${location}' has no color`); 47 | color = 'black'; 48 | } 49 | return color; 50 | } 51 | 52 | function colorForTopic(count: number, index: number): string { 53 | const hue = Math.round(360 * index / (count + 1)); 54 | return `hsl(${hue}, 74%, 65%)`; 55 | } 56 | 57 | module.exports = { 58 | actionText: '#3FB4CF', 59 | inactiveText: '#9B9B9B', 60 | darkText: '#032250', 61 | lightText: '#7F91A7', 62 | cellBorder: '#EEEEEE', 63 | darkBackground: '#183E63', 64 | colorForLocation, 65 | colorForTopic, 66 | }; 67 | -------------------------------------------------------------------------------- /js/common/F8Text.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2016 Facebook, Inc. 3 | * 4 | * You are hereby granted a non-exclusive, worldwide, royalty-free license to 5 | * use, copy, modify, and distribute this software in source code or binary 6 | * form for use in connection with the web services and APIs provided by 7 | * Facebook. 8 | * 9 | * As with any software that integrates with the Facebook platform, your use 10 | * of this software is subject to the Facebook Developer Principles and 11 | * Policies [http://developers.facebook.com/policy/]. This copyright notice 12 | * shall be included in all copies or substantial portions of the software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 17 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 19 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 20 | * DEALINGS IN THE SOFTWARE 21 | * 22 | * @providesModule F8Text 23 | * @flow 24 | */ 25 | 26 | 'use strict'; 27 | 28 | import {StyleSheet, Dimensions} from 'react-native'; 29 | import F8Colors from 'F8Colors'; 30 | 31 | import React from 'react'; 32 | var Text = require('Text'); 33 | 34 | export function Text({style, ...props}: Object): ReactElement { 35 | return ; 36 | } 37 | 38 | export function Heading1({style, ...props}: Object): ReactElement { 39 | return ; 40 | } 41 | 42 | export function Paragraph({style, ...props}: Object): ReactElement { 43 | return ; 44 | } 45 | 46 | const scale = Dimensions.get('window').width / 375; 47 | 48 | function normalize(size: number): number { 49 | return Math.round(scale * size); 50 | } 51 | 52 | const styles = StyleSheet.create({ 53 | font: { 54 | fontFamily: 'Cochin', 55 | }, 56 | h1: { 57 | fontSize: normalize(24), 58 | lineHeight: normalize(27), 59 | color: F8Colors.darkText, 60 | fontWeight: 'bold', 61 | letterSpacing: -1, 62 | }, 63 | p: { 64 | fontSize: normalize(15), 65 | lineHeight: normalize(23), 66 | color: F8Colors.lightText, 67 | }, 68 | }); 69 | -------------------------------------------------------------------------------- /js/common/F8Touchable.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2016 Facebook, Inc. 3 | * 4 | * You are hereby granted a non-exclusive, worldwide, royalty-free license to 5 | * use, copy, modify, and distribute this software in source code or binary 6 | * form for use in connection with the web services and APIs provided by 7 | * Facebook. 8 | * 9 | * As with any software that integrates with the Facebook platform, your use 10 | * of this software is subject to the Facebook Developer Principles and 11 | * Policies [http://developers.facebook.com/policy/]. This copyright notice 12 | * shall be included in all copies or substantial portions of the software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 17 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 19 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 20 | * DEALINGS IN THE SOFTWARE 21 | * 22 | * @providesModule F8Touchable 23 | * @flow 24 | */ 25 | 26 | 'use strict'; 27 | 28 | import { 29 | TouchableHighlight, 30 | TouchableNativeFeedback, 31 | Platform, 32 | } from 'react-native'; 33 | 34 | import React from 'react'; 35 | 36 | 37 | function F8TouchableIOS(props: Object): ReactElement { 38 | return ( 39 | 44 | ); 45 | } 46 | 47 | const F8Touchable = Platform.OS === 'android' 48 | ? TouchableNativeFeedback 49 | : F8TouchableIOS; 50 | 51 | module.exports = F8Touchable; 52 | -------------------------------------------------------------------------------- /js/common/MarvelDrawerLayout.js: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * Copyright 2016 Facebook, Inc. 4 | * 5 | * You are hereby granted a non-exclusive, worldwide, royalty-free license to 6 | * use, copy, modify, and distribute this software in source code or binary 7 | * form for use in connection with the web services and APIs provided by 8 | * Facebook. 9 | * 10 | * As with any software that integrates with the Facebook platform, your use 11 | * of this software is subject to the Facebook Developer Principles and 12 | * Policies [http://developers.facebook.com/policy/]. This copyright notice 13 | * shall be included in all copies or substantial portions of the software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 21 | * DEALINGS IN THE SOFTWARE 22 | * 23 | * @flow 24 | * @providesModule MarvelDrawerLayout 25 | */ 26 | 'use strict'; 27 | 28 | var React = require('react'); 29 | var DrawerLayoutAndroid = require('DrawerLayoutAndroid'); 30 | 31 | class MarvelDrawerLayout extends React.Component { 32 | _drawer: ?DrawerLayoutAndroid; 33 | openDrawer: () => void; 34 | onDrawerOpen: () => void; 35 | closeDrawer: () => void; 36 | onDrawerClose: () => void; 37 | handleBackButton: () => void; 38 | 39 | constructor(props: any, context: any) { 40 | super(props, context); 41 | 42 | this.openDrawer = this.openDrawer.bind(this); 43 | this.closeDrawer = this.closeDrawer.bind(this); 44 | this.onDrawerOpen = this.onDrawerOpen.bind(this); 45 | this.onDrawerClose = this.onDrawerClose.bind(this); 46 | this.handleBackButton = this.handleBackButton.bind(this); 47 | } 48 | 49 | render() { 50 | const {drawerPosition, ...props} = this.props; 51 | const {Right, Left} = DrawerLayoutAndroid.positions; 52 | return ( 53 | this._drawer = drawer} 55 | {...props} 56 | drawerPosition={drawerPosition === 'right' ? Right : Left} 57 | onDrawerOpen={this.onDrawerOpen} 58 | onDrawerClose={this.onDrawerClose} 59 | /> 60 | ); 61 | } 62 | 63 | componentWillUnmount() { 64 | this.context.removeBackButtonListener(this.handleBackButton); 65 | this._drawer = null; 66 | } 67 | 68 | handleBackButton(): boolean { 69 | this.closeDrawer(); 70 | return true; 71 | } 72 | 73 | onDrawerOpen() { 74 | this.context.addBackButtonListener(this.handleBackButton); 75 | this.props.onDrawerOpen && this.props.onDrawerOpen(); 76 | } 77 | 78 | onDrawerClose() { 79 | this.context.removeBackButtonListener(this.handleBackButton); 80 | this.props.onDrawerClose && this.props.onDrawerClose(); 81 | } 82 | 83 | closeDrawer() { 84 | this._drawer && this._drawer.closeDrawer(); 85 | } 86 | 87 | openDrawer() { 88 | this._drawer && this._drawer.openDrawer(); 89 | } 90 | } 91 | 92 | MarvelDrawerLayout.contextTypes = { 93 | addBackButtonListener: React.PropTypes.func, 94 | removeBackButtonListener: React.PropTypes.func, 95 | }; 96 | 97 | module.exports = MarvelDrawerLayout; 98 | -------------------------------------------------------------------------------- /js/common/MarvelHeader.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2016 Facebook, Inc. 3 | * 4 | * You are hereby granted a non-exclusive, worldwide, royalty-free license to 5 | * use, copy, modify, and distribute this software in source code or binary 6 | * form for use in connection with the web services and APIs provided by 7 | * Facebook. 8 | * 9 | * As with any software that integrates with the Facebook platform, your use 10 | * of this software is subject to the Facebook Developer Principles and 11 | * Policies [http://developers.facebook.com/policy/]. This copyright notice 12 | * shall be included in all copies or substantial portions of the software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 17 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 19 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 20 | * DEALINGS IN THE SOFTWARE 21 | * 22 | * @providesModule MarvelHeader 23 | * @flow 24 | */ 25 | 26 | 'use strict'; 27 | 28 | var F8Colors = require('F8Colors'); 29 | var React = require('React'); 30 | var Platform = require('Platform'); 31 | var StyleSheet = require('StyleSheet'); 32 | var { Text } = require('F8Text'); 33 | var TouchableOpacity = require('TouchableOpacity'); 34 | var View = require('View'); 35 | var Image = require('Image'); 36 | var ToolbarAndroid = require('ToolbarAndroid'); 37 | 38 | export type Layout = 39 | 'default' // Use platform defaults (icon on Android, text on iOS) 40 | | 'icon' // Always use icon 41 | | 'title'; // Always use title 42 | 43 | export type Foreground = 'light' | 'dark'; 44 | 45 | export type Item = { 46 | title?: string; 47 | icon?: number; 48 | layout?: Layout; 49 | onPress?: () => void; 50 | }; 51 | 52 | export type Props = { 53 | title?: string; 54 | leftItem?: Item; 55 | rightItem?: Item; 56 | extraItems?: Array; 57 | foreground?: Foreground; 58 | style?: any; 59 | children?: any; 60 | }; 61 | 62 | class F8HeaderAndroid extends React.Component { 63 | 64 | props: Props; 65 | 66 | render() { 67 | const {leftItem, rightItem, extraItems} = this.props; 68 | let actions = []; 69 | if (rightItem) { 70 | const {title, icon, layout} = rightItem; 71 | actions.push({ 72 | icon: layout !== 'title' ? icon : undefined, 73 | title: title, 74 | show: 'always', 75 | }); 76 | } 77 | if (extraItems) { 78 | actions = actions.concat(extraItems.map((item) => ({ 79 | title: item.title, 80 | show: 'never', 81 | }))); 82 | } 83 | 84 | const textColor = this.props.foreground === 'dark' 85 | ? F8Colors.darkText 86 | : 'white'; 87 | 88 | let content; 89 | if (React.Children.count(this.props.children) > 0) { 90 | content = ( 91 | 92 | {this.props.children} 93 | 94 | ); 95 | } 96 | 97 | return ( 98 | 99 | 108 | {content} 109 | 110 | 111 | ); 112 | } 113 | 114 | handleActionSelected(position: number) { 115 | let items = this.props.extraItems || []; 116 | if (this.props.rightItem) { 117 | items = [this.props.rightItem, ...items]; 118 | } 119 | const item = items[position]; 120 | item && item.onPress && item.onPress(); 121 | } 122 | } 123 | 124 | 125 | class F8HeaderIOS extends React.Component { 126 | props: Props; 127 | 128 | render() { 129 | const {leftItem, title, rightItem, foreground} = this.props; 130 | const titleColor = foreground === 'dark' ? F8Colors.darkText : 'white'; 131 | const itemsColor = foreground === 'dark' ? F8Colors.lightText : 'white'; 132 | 133 | const content = React.Children.count(this.props.children) === 0 134 | ? 135 | {title} 136 | 137 | : this.props.children; 138 | return ( 139 | 140 | 141 | 142 | 143 | 148 | {content} 149 | 150 | 151 | 152 | 153 | 154 | ); 155 | } 156 | 157 | } 158 | 159 | class ItemWrapperIOS extends React.Component { 160 | props: { 161 | item: Item; 162 | color: string; 163 | }; 164 | 165 | render() { 166 | const {item, color} = this.props; 167 | if (!item) { 168 | return null; 169 | } 170 | 171 | let content; 172 | const {title, icon, layout, onPress} = item; 173 | 174 | if (layout !== 'icon' && title) { 175 | content = ( 176 | 177 | {title.toUpperCase()} 178 | 179 | ); 180 | } else if (icon) { 181 | content = ; 182 | } 183 | 184 | return ( 185 | 190 | {content} 191 | 192 | ); 193 | } 194 | } 195 | 196 | 197 | var STATUS_BAR_HEIGHT = Platform.OS === 'ios' ? 20 : 25; 198 | var HEADER_HEIGHT = Platform.OS === 'ios' ? 44 + STATUS_BAR_HEIGHT : 56 + STATUS_BAR_HEIGHT; 199 | 200 | var styles = StyleSheet.create({ 201 | toolbarContainer: { 202 | paddingTop: STATUS_BAR_HEIGHT, 203 | }, 204 | toolbar: { 205 | height: HEADER_HEIGHT - STATUS_BAR_HEIGHT, 206 | }, 207 | header: { 208 | backgroundColor: 'transparent', 209 | paddingTop: STATUS_BAR_HEIGHT, 210 | height: HEADER_HEIGHT, 211 | flexDirection: 'row', 212 | justifyContent: 'space-between', 213 | alignItems: 'center', 214 | }, 215 | titleText: { 216 | color: 'white', 217 | fontWeight: 'bold', 218 | fontSize: 20, 219 | }, 220 | leftItem: { 221 | flex: 1, 222 | alignItems: 'flex-start', 223 | }, 224 | centerItem: { 225 | flex: 2, 226 | alignItems: 'center', 227 | }, 228 | rightItem: { 229 | flex: 1, 230 | alignItems: 'flex-end', 231 | }, 232 | itemWrapper: { 233 | padding: 11, 234 | }, 235 | itemText: { 236 | letterSpacing: 1, 237 | fontSize: 12, 238 | color: 'white', 239 | }, 240 | }); 241 | 242 | const MarvelHeader = Platform.OS === 'ios' ? F8HeaderIOS : F8HeaderAndroid; 243 | MarvelHeader.height = HEADER_HEIGHT; 244 | 245 | module.exports = MarvelHeader; 246 | module.exports.__cards__ = (define) => { 247 | const menuItem = { 248 | title: 'Menu', 249 | // icon: require('./img/hamburger.png'), 250 | onPress: () => alert('Menu button pressed!'), 251 | }; 252 | const filterItem = { 253 | title: 'Filter', 254 | // icon: require('./img/filter.png'), 255 | onPress: () => alert('Filter button pressed!'), 256 | }; 257 | 258 | define('Simple', () => ); 259 | define('With items', () => ( 260 | 265 | )); 266 | define('Forcing icons', () => ( 267 | 272 | )); 273 | define('Forcing title', () => ( 274 | 279 | )); 280 | define('With content', () => ( 281 | 282 | 283 | 284 | Yellow text as title 285 | 286 | 287 | 288 | )); 289 | define('With Background', () => ( 290 | 296 | )); 297 | define('With light background', () => ( 298 | 305 | )); 306 | }; 307 | -------------------------------------------------------------------------------- /js/common/MarvelInfoView.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @providesModule MarvelInfoView 3 | * @flow 4 | */ 5 | 6 | 'use strict'; 7 | var React = require('react'); 8 | var StyleSheet = require('StyleSheet'); 9 | var Text = require('Text'); 10 | 11 | class MarvelInfoView extends React.Component { 12 | render() { 13 | return ( 14 | 15 | Data provided by Marvel. © 2016 Marvel. 16 | 17 | ); 18 | } 19 | } 20 | 21 | var styles = StyleSheet.create({ 22 | marvelinfo: { 23 | marginBottom: 24, 24 | fontSize: 12, 25 | color: '#032250', 26 | textAlign: 'center', 27 | }, 28 | }); 29 | 30 | module.exports = MarvelInfoView; 31 | -------------------------------------------------------------------------------- /js/common/constant.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @providesModule constant 3 | * @flow 4 | */ 5 | 6 | 'use strict'; 7 | 8 | var Dimensions = require('Dimensions'); 9 | 10 | export const windowWidth = Dimensions.get('window').width; 11 | -------------------------------------------------------------------------------- /js/env.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @flow 3 | */ 4 | 5 | 'use strict'; 6 | var Platform = require('Platform'); 7 | 8 | module.exports = { 9 | PublicKey: 'd128928f89eab7dca3a7f3c003c48f80', 10 | PrivateKey: 'cd4ff2b15d809de5f84e369e03a7d399c52e4772', 11 | serverUrl: 'http://gateway.marvel.com:80/v1/public/', 12 | }; 13 | -------------------------------------------------------------------------------- /js/marvelapi/MarvelAPI.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @flow 3 | */ 4 | 'use strict'; 5 | 6 | // For example, a user with a public key of "1234" and a private key of "abcd" 7 | // could construct a valid call as follows: 8 | // http://gateway.marvel.com/v1/comics?ts=1&apikey=1234&hash=ffd275c5130566a2916217b101f26150 9 | // (the hash value is the md5 digest of 1abcd1234) 10 | var {serverUrl} = require('../env'); 11 | var {getMarvelRequestParam} = require('./Util'); 12 | var {writeCharacterToRealm, getCharacterFromRealm, getPopularCharactersInRealm} = require('./realmModel'); 13 | var Platform = require('Platform'); 14 | 15 | import type {Character} from './model'; 16 | 17 | class MarvelAPI { 18 | 19 | async searchCharacterByName(startWith: string): Promise> { 20 | var generalParam = getMarvelRequestParam(); 21 | var request = `${serverUrl}characters?nameStartsWith=${startWith}&${generalParam}`; 22 | var result = []; 23 | try { 24 | let response = await fetch(request); 25 | const responseJson = await response.json(); 26 | 27 | if(responseJson.code === 200) { 28 | var results = responseJson.data.results; 29 | 30 | results.map((item, index) => { 31 | var character = this.parseCharacter(item); 32 | result.push(character); 33 | }); 34 | 35 | return result; 36 | } 37 | } catch(error) { 38 | global.LOG(error, request); 39 | } 40 | 41 | return result; 42 | } 43 | 44 | async getPopularCharacters(): Promise> { 45 | 46 | var populars = ['Spider-Man','Hulk', 'Captain America','Iron Man','Avengers','X-Men', 'Deadpool', 'Guardians of the Galaxy']; 47 | var charactersInRealm = await getPopularCharactersInRealm(); 48 | if(charactersInRealm && charactersInRealm.length > 0) { 49 | return charactersInRealm; 50 | } 51 | 52 | var result = []; 53 | for(var index=0; index { 64 | var generalParam = getMarvelRequestParam(); 65 | var request = `${serverUrl}characters?${generalParam}&name=${name}`; 66 | try { 67 | let response = await fetch(request); 68 | const result = await response.json(); 69 | if(result.code === 200) { 70 | var results = result.data.results[0]; 71 | return this.parseCharacter(results); 72 | } 73 | 74 | } catch(error) { 75 | global.LOG(error, request); 76 | } 77 | 78 | return null; 79 | } 80 | 81 | parseCharacter(data: Object): Character { 82 | var name = data.name; 83 | var id = data.id; 84 | var description = data.description; 85 | var serverPath = data.thumbnail.path; 86 | 87 | var thumbnail = `${serverPath}/standard_medium.${data.thumbnail.extension}`; 88 | var portraitImg = `${serverPath}/portrait_xlarge.${data.thumbnail.extension}`; 89 | 90 | var comics = []; 91 | var comicsitems = data.comics.items; 92 | comicsitems.map((item, index) => { 93 | comics.push(item); 94 | }); 95 | 96 | var events = []; 97 | var eventsitems = data.events.items; 98 | eventsitems.map((item, index) => { 99 | events.push(item); 100 | }); 101 | 102 | var stories = []; 103 | var storiesitems = data.stories.items; 104 | storiesitems.map((item, index) => { 105 | stories.push(item); 106 | }); 107 | 108 | var urls = []; 109 | var urlsitems = data.urls; 110 | var wiki; 111 | urlsitems.map((item, index) => { 112 | if(item.type === 'detail') { 113 | wiki = item.url; 114 | } 115 | urls.push(item); 116 | }); 117 | 118 | var series = []; 119 | var seriesitems = data.series.items; 120 | seriesitems.map((item, index) => { 121 | series.push(item); 122 | }); 123 | 124 | return { 125 | id: id, 126 | name: name, 127 | description: description, 128 | wiki: wiki, 129 | thumbnail: thumbnail, 130 | portraitImg: portraitImg, 131 | comics: comics, 132 | events: events, 133 | stories: stories, 134 | series: series, 135 | urls: urls, 136 | }; 137 | } 138 | 139 | async getDetail(url: string): Promise { 140 | var generalParam = getMarvelRequestParam(); 141 | var request = `${url}?${generalParam}`; 142 | try { 143 | let response = await fetch(request); 144 | const result = await response.json(); 145 | if(result.code === 200) { 146 | var results = result.data.results[0]; 147 | var urlsitems = results.urls; 148 | var detailUrl; 149 | urlsitems.map((item, index) => { 150 | if(item.type === 'detail') { 151 | detailUrl = item.url; 152 | } 153 | }); 154 | 155 | return detailUrl; 156 | } 157 | 158 | } catch(error) { 159 | global.LOG(error, request); 160 | } 161 | 162 | return request; 163 | } 164 | } 165 | 166 | module.exports = MarvelAPI; 167 | -------------------------------------------------------------------------------- /js/marvelapi/Util.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @flow 3 | */ 4 | 5 | 'use strict'; 6 | 7 | var {PublicKey, PrivateKey} = require('../env'); 8 | var MD5 = require('crypto-js/md5'); 9 | 10 | function md5(ts: string) { 11 | var value = `${ts}${PrivateKey}${PublicKey}`; 12 | return MD5(value); 13 | } 14 | 15 | export function getMarvelRequestParam() { 16 | var ts = new Date().getTime().toString(); 17 | var md5value = md5(ts); 18 | return `ts=${ts}&apikey=${PublicKey}&hash=${md5value}`; 19 | } 20 | -------------------------------------------------------------------------------- /js/marvelapi/model.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @flow 3 | */ 4 | 5 | 'use strict'; 6 | 7 | export type Character = { 8 | id: number; 9 | name: string; 10 | description: string; 11 | wiki: ?string; 12 | thumbnail: string; 13 | portraitImg: string; 14 | comics: Array; 15 | series: Array; 16 | stories: Array; 17 | events: Array; 18 | urls: Array; 19 | }; 20 | 21 | export type Comic = { 22 | resourceURI: string; 23 | name: string; 24 | }; 25 | 26 | export type Series = { 27 | resourceURI: string; 28 | name: string; 29 | }; 30 | 31 | export type Story = { 32 | resourceURI: string; 33 | name: string; 34 | type: string; 35 | }; 36 | 37 | export type Event = { 38 | resourceURI: string; 39 | name: string; 40 | }; 41 | 42 | export type Url = { 43 | type: string; 44 | url: string; 45 | }; 46 | -------------------------------------------------------------------------------- /js/marvelapi/realmModel.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @flow 3 | */ 4 | 5 | 'use strict'; 6 | import type {Character} from './model'; 7 | 8 | var Realm = require('realm'); 9 | 10 | const ComicSchema = { 11 | name: 'Comic', 12 | properties: { 13 | resourceURI: 'string', 14 | name: 'string', 15 | } 16 | } 17 | 18 | const SeriesSchema = { 19 | name: 'Series', 20 | properties: { 21 | resourceURI: 'string', 22 | name: 'string', 23 | } 24 | } 25 | 26 | const StorySchema = { 27 | name: 'Story', 28 | properties: { 29 | resourceURI: 'string', 30 | name: 'string', 31 | type: 'string', 32 | } 33 | } 34 | 35 | const EventSchema = { 36 | name: 'Event', 37 | properties: { 38 | resourceURI: 'string', 39 | name: 'string', 40 | } 41 | } 42 | 43 | const UrlSchema = { 44 | name: 'Url', 45 | properties: { 46 | type: 'string', 47 | url: 'string', 48 | } 49 | } 50 | 51 | const CharacterSchema = { 52 | name: 'Character', 53 | properties: { 54 | id: 'int', 55 | name: 'string', 56 | description: 'string', 57 | wiki: 'string', 58 | thumbnail: 'string', 59 | portraitImg: 'string', 60 | comics: {type: 'list', objectType: 'Comic'}, 61 | series: {type: 'list', objectType: 'Series'}, 62 | stories: {type: 'list', objectType: 'Story'}, 63 | events: {type: 'list', objectType: 'Event'}, 64 | urls: {type: 'list', objectType: 'Url'}, 65 | } 66 | } 67 | 68 | let realm = new Realm({schema:[ComicSchema, SeriesSchema, StorySchema, EventSchema, UrlSchema, CharacterSchema]}); 69 | 70 | function writeCharacterToRealm(character: Character) { 71 | realm.write(() => { 72 | let realmobject = realm.create('Character', { 73 | id: character.id, 74 | name: character.name, 75 | description: character.description, 76 | wiki: character.wiki, 77 | thumbnail: character.thumbnail, 78 | portraitImg: character.portraitImg, 79 | }); 80 | character.comics.map((item, index) => { 81 | realmobject.comics.push(item); 82 | }); 83 | 84 | character.series.map((item, index) => { 85 | realmobject.series.push(item); 86 | }); 87 | 88 | character.stories.map((item, index) => { 89 | realmobject.stories.push(item); 90 | }); 91 | 92 | character.events.map((item, index) => { 93 | realmobject.events.push(item); 94 | }); 95 | 96 | character.urls.map((item, index) => { 97 | realmobject.urls.push(item); 98 | }); 99 | }); 100 | } 101 | 102 | function getCharacterFromRealm(name: string): ?Character { 103 | 104 | var query = `name = "${name}"`; 105 | let character = realm.objects('Character').filtered(query); 106 | if(character && character.length > 0) { 107 | return parseRealmObject(character[0]); 108 | } 109 | 110 | return null; 111 | } 112 | 113 | function parseRealmObject(character: any): Character { 114 | var comics = []; 115 | for(var index=0; index < character.comics.length; index++) { 116 | comics.push(character.comics[index]); 117 | } 118 | 119 | var series = []; 120 | for(var index=0; index < character.series.length; index++) { 121 | series.push(character.series[index]); 122 | } 123 | 124 | var stories = []; 125 | for(var index=0; index < character.stories.length; index++) { 126 | stories.push(character.stories[index]); 127 | } 128 | 129 | var events = []; 130 | for(var index=0; index < character.events.length; index++) { 131 | events.push(character.events[index]); 132 | } 133 | 134 | var urls = []; 135 | for(var index=0; index < character.urls.length; index++) { 136 | urls.push(character.urls[index]); 137 | } 138 | return { 139 | id: character.id, 140 | name: character.name, 141 | description: character.description, 142 | wiki: character.wiki, 143 | thumbnail: character.thumbnail, 144 | portraitImg: character.portraitImg, 145 | comics: comics, 146 | series: series, 147 | stories: stories, 148 | events: events, 149 | urls: urls, 150 | }; 151 | } 152 | 153 | function isPopularCharacter(char: Character) { 154 | var query = `id = "${char.id}"`; 155 | let character = realm.objects('Character').filtered(query); 156 | return character && character.length > 0; 157 | } 158 | 159 | function removePopularCharacter(char: Character) { 160 | realm.write(() => { 161 | var query = `id = "${char.id}"`; 162 | let character = realm.objects('Character').filtered(query); 163 | realm.delete(character); 164 | }); 165 | } 166 | 167 | function getPopularCharactersInRealm(): Array { 168 | var result = []; 169 | let characters = realm.objects('Character'); 170 | for(var index=0; index; 12 | searchResult: ?Array; 13 | detailUrl: ?string; 14 | }; 15 | 16 | const initialState: State = {popularcharacters: null, searchResult: null, detailUrl: null}; 17 | 18 | function marvel(state: State = initialState, action: Action): State { 19 | if (action.type === 'GET_POPULAR_CHARACTERS') { 20 | return {...state, popularcharacters: action.data}; 21 | } 22 | if(action.type === 'SEARCH_CHARACTER_BY_NAME') { 23 | return {...state, searchResult: action.data}; 24 | } 25 | 26 | if(action.type === 'GET_CHARACTER_DETAIL') { 27 | return {...state, detailUrl: action.data}; 28 | } 29 | 30 | return state; 31 | } 32 | 33 | module.exports = marvel; 34 | -------------------------------------------------------------------------------- /js/reducers/navigation.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @flow 3 | */ 4 | 5 | 'use strict'; 6 | 7 | import type {Action} from '../actions/types'; 8 | 9 | export type Tab = 'characters' | 'search' | 'about'; 10 | 11 | type State = { 12 | tab: Tab; 13 | }; 14 | 15 | const initialState: State = {tab: 'characters'}; 16 | 17 | function navigation(state: State = initialState, action: Action): State { 18 | if (action.type === 'SWITCH_TAB') { 19 | return {...state, tab: action.tab}; 20 | } 21 | return state; 22 | } 23 | 24 | module.exports = navigation; 25 | -------------------------------------------------------------------------------- /js/setup.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @flow 3 | */ 4 | 5 | 'use strict'; 6 | 7 | var MarvelApp = require('MarvelApp'); 8 | var React = require('react'); 9 | var {Provider} = require('react-redux'); 10 | var configureStore = require('./store/configureStore'); 11 | 12 | function setup() : React.Component { 13 | class Root extends React.Component { 14 | state: { 15 | store: ?any; 16 | }; 17 | 18 | 19 | constructor() { 20 | super(); 21 | this.state = { 22 | store: configureStore(), 23 | }; 24 | } 25 | 26 | render() { 27 | return ( 28 | 29 | 30 | 31 | ); 32 | } 33 | } 34 | 35 | return Root; 36 | } 37 | 38 | global.LOG = (...args) => { 39 | console.log('/---------------------\\'); 40 | console.log(...args); 41 | console.log('\\---------------------/'); 42 | 43 | return args[args.length-1]; 44 | }; 45 | 46 | 47 | module.exports = setup; 48 | -------------------------------------------------------------------------------- /js/splash/SplashScreen.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @flow 3 | */ 4 | 5 | 'use strict'; 6 | var React = require('react'); 7 | var StyleSheet = require('StyleSheet'); 8 | var Animated = require('Animated'); 9 | var Image = require('Image'); 10 | var Text = require('Text'); 11 | var {connect} = require('react-redux'); 12 | var View = require('View'); 13 | 14 | var { enterMainPage } = require('../actions'); 15 | 16 | class SplashScreen extends React.Component { 17 | state: { 18 | anim: Animated.Value; 19 | }; 20 | 21 | onAnimatedCompleted: () => void; 22 | 23 | constructor(props) { 24 | super(props); 25 | this.state = { 26 | anim : new Animated.Value(0), 27 | }; 28 | 29 | this.onAnimatedCompleted = this.onAnimatedCompleted.bind(this); 30 | } 31 | 32 | componentDidMount() { 33 | Animated.timing(this.state.anim, {toValue:3000, duration:3000}).start(); 34 | this.state.anim.addListener(this.onAnimatedCompleted); 35 | } 36 | 37 | componentWillUnmount() { 38 | this.state.anim.removeAllListeners(); 39 | } 40 | 41 | onAnimatedCompleted(value) { 42 | if(value.value === 3000) { 43 | this.props.dispatch(enterMainPage()); 44 | } 45 | } 46 | 47 | render() { 48 | return ( 49 | 51 | 52 | 53 | 55 | 56 | Data provided by Marvel. © 2016 Marvel. 57 | 58 | 59 | 60 | ); 61 | } 62 | 63 | fadeIn(delay, from=0) { 64 | const {anim} = this.state; 65 | return { 66 | opacity: anim.interpolate({ 67 | inputRange:[delay, Math.min(delay + 500, 3000)], 68 | outputRange:[0, 1], 69 | extrapolate:'clamp', 70 | }), 71 | 72 | transform: [{ 73 | translateY: anim.interpolate({ 74 | inputRange:[delay, Math.min(delay+500, 3000)], 75 | outputRange:[from, 0], 76 | extrapolate:'clamp', 77 | }), 78 | }], 79 | }; 80 | } 81 | } 82 | 83 | var styles = StyleSheet.create({ 84 | container:{ 85 | flex: 1, 86 | backgroundColor: 'transparent', 87 | width: undefined, 88 | height: undefined, 89 | flexDirection: 'column', 90 | }, 91 | 92 | marvellogo: { 93 | alignSelf: 'center', 94 | alignItems: 'center', 95 | marginBottom: 10, 96 | }, 97 | 98 | marvelinfo: { 99 | marginBottom: 24, 100 | fontSize: 12, 101 | color: '#032250', 102 | textAlign: 'center', 103 | }, 104 | }); 105 | 106 | module.exports = connect()(SplashScreen); 107 | -------------------------------------------------------------------------------- /js/splash/img/marvel_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Shuijwan/marvel/47f2a96ed37af852892b10a07512f61a3070d99f/js/splash/img/marvel_logo.png -------------------------------------------------------------------------------- /js/splash/img/splash_background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Shuijwan/marvel/47f2a96ed37af852892b10a07512f61a3070d99f/js/splash/img/splash_background.png -------------------------------------------------------------------------------- /js/store/configureStore.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @flow 3 | */ 4 | 5 | 'use strict'; 6 | 7 | var {applyMiddleware, createStore} = require('redux'); 8 | var reducers = require('../reducers'); 9 | var createLogger = require('redux-logger'); 10 | 11 | import promise from './promise'; 12 | 13 | var isDebuggingInChrome = __DEV__ && !!window.navigator.userAgent; 14 | 15 | var logger = createLogger({ 16 | predicate: () => isDebuggingInChrome, 17 | collapsed: true, 18 | duration: true, 19 | }); 20 | 21 | var store = applyMiddleware(promise, logger)(createStore)(reducers); 22 | 23 | function configureStore() { 24 | if(isDebuggingInChrome) { 25 | window.store = store; 26 | } 27 | 28 | return store; 29 | } 30 | 31 | module.exports = configureStore; 32 | -------------------------------------------------------------------------------- /js/store/promise.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @flow 3 | */ 4 | 5 | 'use strict'; 6 | 7 | function warn(error) { 8 | console.warn(error.message || error); 9 | throw error; // To let the caller handle the rejection 10 | } 11 | 12 | // function parseStore(store: any) { 13 | // return function doNext(next: any) { 14 | // // global.LOG('next', next); 15 | // return function doAction(action: any) { 16 | // global.LOG('action', next, action.then, action); 17 | // if(typeof action.then === 'function') { 18 | // Promise.resolve(action).then(next, warn) 19 | // } else { 20 | // next(action); 21 | // } 22 | // } 23 | // } 24 | // } 25 | 26 | module.exports = (store: any) => (next: any) => (action: any) => 27 | typeof action.then === 'function' 28 | ? Promise.resolve(action).then(next, warn) 29 | : next(action); 30 | -------------------------------------------------------------------------------- /js/tabs/MarvelTabsView.android.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @providesModule MarvelTabsView 3 | * @flow 4 | */ 5 | 6 | 'use strict'; 7 | 8 | var React = require('react'); 9 | var Navigator = require('Navigator'); 10 | var CharactersContentView = require('./characters/CharactersContentView'); 11 | var AboutContentView = require('./about/AboutContentView'); 12 | var StyleSheet = require('StyleSheet'); 13 | var MarvelDrawerLayout = require('MarvelDrawerLayout'); 14 | var View = require('View'); 15 | var MenuItem = require('./MenuItem'); 16 | var Text = require('Text'); 17 | var Image = require('Image'); 18 | var MarvelInfoView = require('MarvelInfoView'); 19 | 20 | var {connect} = require('react-redux'); 21 | var {switchTab} = require('../actions'); 22 | 23 | import type {Tab} from '../reducers/navigation'; 24 | 25 | class MarvelTabsView extends React.Component { 26 | props: { 27 | tab: Tab; 28 | navigator: Navigator; 29 | onTabSelected: (tab: Tab) => void; 30 | }; 31 | 32 | constructor(props) { 33 | super(props); 34 | this.renderNavigationView = this.renderNavigationView.bind(this); 35 | this.openDrawer = this.openDrawer.bind(this); 36 | } 37 | 38 | getChildContext() { 39 | return { 40 | openDrawer: this.openDrawer, 41 | }; 42 | } 43 | 44 | openDrawer() { 45 | this.refs.drawer.openDrawer(); 46 | } 47 | 48 | onTabSelected(tab: Tab) { 49 | if(this.props.tab !== tab) { 50 | this.props.onTabSelected(tab); 51 | } 52 | 53 | this.refs.drawer.closeDrawer(); 54 | } 55 | 56 | renderNavigationView() { 57 | return ( 58 | 59 | 60 | 66 | 72 | 73 | 74 | 75 | ); 76 | } 77 | 78 | renderContent() { 79 | switch(this.props.tab) { 80 | case 'characters': 81 | return ( 82 | 83 | ); 84 | case 'about': 85 | return ( 86 | 87 | ); 88 | } 89 | } 90 | 91 | render() { 92 | return ( 93 | 98 | 99 | {this.renderContent()} 100 | 101 | 102 | ); 103 | } 104 | } 105 | 106 | MarvelTabsView.childContextTypes = { 107 | openDrawer: React.PropTypes.func, 108 | }; 109 | 110 | function select(store) { 111 | return { 112 | tab: store.navigation.tab, 113 | }; 114 | } 115 | 116 | function actions(dispatch) { 117 | return { 118 | onTabSelected: (tab) => dispatch(switchTab(tab)), 119 | }; 120 | } 121 | 122 | var styles = StyleSheet.create({ 123 | content: { 124 | flex: 1, 125 | }, 126 | 127 | head:{ 128 | width: 290, 129 | height: 200, 130 | }, 131 | 132 | navigation: { 133 | flex: 1, 134 | flexDirection: 'column', 135 | backgroundColor: 'transparent' 136 | }, 137 | }); 138 | 139 | module.exports = connect(select, actions)(MarvelTabsView); 140 | -------------------------------------------------------------------------------- /js/tabs/MarvelTabsView.ios.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @providesModule MarvelTabsView 3 | * @flow 4 | */ 5 | 6 | 'use strict'; 7 | 8 | var React = require('react'); 9 | var Navigator = require('Navigator'); 10 | var CharactersContentView = require('./characters/CharactersContentView'); 11 | var SearchView = require('./characters/SearchView'); 12 | var AboutView = require('./about/AboutContentView'); 13 | var TabBarIOS = require('TabBarIOS'); 14 | 15 | var {connect} = require('react-redux'); 16 | var F8Colors = require('F8Colors'); 17 | var {switchTab} = require('../actions'); 18 | 19 | import type {Tab} from '../reducers/navigation'; 20 | 21 | class MarvelTabsView extends React.Component { 22 | props: { 23 | tab: Tab; 24 | navigator: Navigator; 25 | onTabSelected: (tab: Tab) => void; 26 | }; 27 | 28 | constructor(props) { 29 | super(props); 30 | } 31 | 32 | onTabSelected(tab: Tab) { 33 | if(this.props.tab !== tab) { 34 | this.props.onTabSelected(tab); 35 | } 36 | } 37 | 38 | render() { 39 | return ( 40 | 41 | 48 | 51 | 52 | 59 | 62 | 63 | 70 | 71 | 72 | 73 | ); 74 | } 75 | } 76 | 77 | function select(store) { 78 | return { 79 | tab: store.navigation.tab, 80 | }; 81 | } 82 | 83 | function actions(dispatch) { 84 | return { 85 | onTabSelected: (tab) => dispatch(switchTab(tab)), 86 | }; 87 | } 88 | 89 | module.exports = connect(select, actions)(MarvelTabsView); 90 | -------------------------------------------------------------------------------- /js/tabs/MenuItem.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2016 Facebook, Inc. 3 | * 4 | * You are hereby granted a non-exclusive, worldwide, royalty-free license to 5 | * use, copy, modify, and distribute this software in source code or binary 6 | * form for use in connection with the web services and APIs provided by 7 | * Facebook. 8 | * 9 | * As with any software that integrates with the Facebook platform, your use 10 | * of this software is subject to the Facebook Developer Principles and 11 | * Policies [http://developers.facebook.com/policy/]. This copyright notice 12 | * shall be included in all copies or substantial portions of the software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 17 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 19 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 20 | * DEALINGS IN THE SOFTWARE 21 | * 22 | * @flow 23 | */ 24 | 25 | 'use strict'; 26 | 27 | var F8Colors = require('F8Colors'); 28 | var React = require('React'); 29 | var View = require('View'); 30 | var { Text } = require('F8Text'); 31 | var F8Touchable = require('F8Touchable'); 32 | var Image = require('Image'); 33 | var StyleSheet = require('StyleSheet'); 34 | 35 | 36 | class MenuItem extends React.Component { 37 | props: { 38 | icon: number; 39 | selectedIcon: number; 40 | selected: boolean; 41 | title: string; 42 | badge: ?string; 43 | onPress: () => void; 44 | }; 45 | 46 | render() { 47 | var icon = this.props.selected ? this.props.selectedIcon : this.props.icon; 48 | if(!this.props.selectedIcon) { 49 | icon = this.props.icon; 50 | } 51 | var selectedTitleStyle = this.props.selected && styles.selectedTitle; 52 | var badge; 53 | if (this.props.badge) { 54 | badge = ( 55 | 56 | 57 | {this.props.badge} 58 | 59 | 60 | ); 61 | } 62 | return ( 63 | 64 | 65 | 66 | 67 | {this.props.title} 68 | 69 | {badge} 70 | 71 | 72 | ); 73 | } 74 | } 75 | 76 | var styles = StyleSheet.create({ 77 | container: { 78 | flexDirection: 'row', 79 | height: 50, 80 | alignItems: 'center', 81 | paddingHorizontal: 20, 82 | }, 83 | icon: { 84 | width: 32, 85 | height: 32, 86 | marginRight: 20, 87 | padding: 3, 88 | }, 89 | title: { 90 | flex: 1, 91 | fontSize: 17, 92 | color: F8Colors.lightText, 93 | }, 94 | selectedTitle: { 95 | color: F8Colors.darkText, 96 | }, 97 | badge: { 98 | backgroundColor: '#DC3883', 99 | paddingHorizontal: 10, 100 | paddingVertical: 2, 101 | borderRadius: 10, 102 | }, 103 | badgeText: { 104 | fontSize: 12, 105 | color: 'white', 106 | }, 107 | }); 108 | 109 | module.exports = MenuItem; 110 | -------------------------------------------------------------------------------- /js/tabs/about/AboutContentView.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @flow 3 | */ 4 | 'use strict'; 5 | 6 | var MarvelInfoView = require('MarvelInfoView'); 7 | var React = require('react'); 8 | var View = require('View'); 9 | var {Text} = require('F8Text'); 10 | var F8Touchable = require('F8Touchable'); 11 | var StyleSheet = require('StyleSheet'); 12 | var ToolbarAndroid = require('ToolbarAndroid'); 13 | var Image = require('Image'); 14 | var {windowWidth} = require('constant'); 15 | var Linking = require('Linking'); 16 | var MarvelHeader = require('MarvelHeader'); 17 | var Platform = require('Platform'); 18 | 19 | import Hyperlink from 'react-native-hyperlink'; 20 | import Share from 'react-native-share'; 21 | 22 | 23 | const shield = require('../img/shieldcolor.png'); 24 | 25 | class AboutContentView extends React.Component { 26 | handleIconClicked: () => void; 27 | onShare: () => void; 28 | 29 | constructor(props: any) { 30 | super(props); 31 | this.handleIconClicked = this.handleIconClicked.bind(this); 32 | this.onShare = this.onShare.bind(this); 33 | } 34 | 35 | handleIconClicked() { 36 | this.context.openDrawer(); 37 | } 38 | 39 | onShare() { 40 | Share.open({ 41 | share_text: "漫威React Native APP", 42 | share_URL: "https://github.com/Shuijwan/marvel", 43 | title: "漫威" 44 | }, (e) => { 45 | 46 | }); 47 | } 48 | 49 | render() { 50 | var head; 51 | if(Platform.OS === 'android') { 52 | head = 53 | } else { 54 | head = ; 55 | } 56 | 57 | return ( 58 | 59 | {head} 60 | 64 | 65 | This is a React Native App based on the coolest Marvel API. You can search the Marvel Heros here. 66 | 67 | 68 | 69 | Linking.openURL(url)}> 70 | 71 | Github: https://github.com/Shuijwan/marvel 72 | 73 | 74 | 75 | 76 | 77 | 78 | Linking.openURL(url)}> 79 | 80 | Marvel: http://developer.marvel.com/ 81 | 82 | 83 | 84 | 85 | 86 | 87 | Share 88 | 89 | 90 | 91 | 92 | 93 | 94 | ); 95 | } 96 | 97 | } 98 | 99 | AboutContentView.contextTypes = { 100 | openDrawer: React.PropTypes.func, 101 | }; 102 | 103 | var styles = StyleSheet.create({ 104 | 105 | item: { 106 | height: 60, 107 | width: undefined, 108 | }, 109 | 110 | description: { 111 | marginTop: 10, 112 | marginBottom: 40, 113 | fontSize: 18, 114 | fontWeight: 'bold', 115 | textAlign:'center' 116 | }, 117 | 118 | itemtext: { 119 | fontSize: 16, 120 | textAlign: 'center', 121 | marginTop: 10, 122 | marginBottom: 10, 123 | paddingLeft: 20 124 | }, 125 | 126 | toolbar: { 127 | height: 56, 128 | backgroundColor: 'rgb(168, 31, 26)',//red 129 | elevation: 2, 130 | borderRightWidth: 1, 131 | marginRight: -1, 132 | borderRightColor: 'transparent', 133 | }, 134 | 135 | share: { 136 | width: 32, 137 | height: 32, 138 | alignSelf:'center', 139 | marginLeft: 10, 140 | } 141 | }); 142 | 143 | module.exports = AboutContentView; 144 | -------------------------------------------------------------------------------- /js/tabs/characters/CharacterDetailView.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @flow 3 | */ 4 | 5 | 'use strict'; 6 | 7 | var React = require('react'); 8 | var StyleSheet = require('StyleSheet'); 9 | var View = require('View'); 10 | var ToolbarAndroid = require('ToolbarAndroid'); 11 | var Image = require('Image'); 12 | var {windowWidth} = require('constant'); 13 | var Text = require('Text'); 14 | var Linking = require('Linking'); 15 | var ScrollView = require('ScrollView'); 16 | var {getMarvelRequestParam} = require('../../marvelapi/Util'); 17 | var {isPopularCharacter, writeCharacterToRealm } = require('../../marvelapi/realmModel'); 18 | var Platform = require('Platform'); 19 | var MarvelHeader = require('MarvelHeader'); 20 | var TouchableHighlight = require('TouchableHighlight'); 21 | var {connect} = require('react-redux'); 22 | var ActivityIndicator = require('ActivityIndicator'); 23 | 24 | var {markAsPopularCharacter, getCharacterDetail} = require('../../actions'); 25 | 26 | import Hyperlink from 'react-native-hyperlink'; 27 | 28 | class CharacterDetailView extends React.Component { 29 | state: { 30 | isLoading: boolean; 31 | }; 32 | 33 | handleIconClicked: () => void; 34 | 35 | constructor(props) { 36 | super(props); 37 | this.handleIconClicked = this.handleIconClicked.bind(this); 38 | this.state = { 39 | isLoading: false, 40 | }; 41 | } 42 | 43 | componentWillReceiveProps(nextProps) { 44 | if(nextProps.detailUrl) { 45 | this.setState({isLoading: false}); 46 | Linking.openURL(nextProps.detailUrl) 47 | } 48 | } 49 | 50 | render() { 51 | var head; 52 | if(Platform.OS === 'android') { 53 | head = 54 | } else { 55 | head = 56 | } 57 | 58 | var isPopular; 59 | var star = require('../img/unstar.png'); 60 | if(isPopular = isPopularCharacter(this.props.character)) { 61 | star = require('../img/star.png'); 62 | } 63 | 64 | var loading; 65 | if(this.state.isLoading) { 66 | loading = ; 67 | } 68 | 69 | return ( 70 | 71 | {head} 72 | 73 | 74 | 75 | 76 | 77 | {this.props.character.name} 78 | 79 | {this.props.dispatch(markAsPopularCharacter(this.props.character, !isPopular)); this.forceUpdate();}}> 80 | 81 | 82 | 83 | 84 | {this.props.character.description} 85 | 86 | 87 | Linking.openURL(url)}> 88 | 89 | {'More: '+ this.props.character.wiki} 90 | 91 | 92 | 93 | 94 | 95 | 96 | {this.renderBody()} 97 | 98 | 99 | {loading} 100 | 101 | ); 102 | } 103 | 104 | handleIconClicked() { 105 | this.props.navigator.pop(); 106 | } 107 | 108 | renderBody() { 109 | var body= ['Comics', 'Events', 'Series', 'Stories']; 110 | var bodyLayout = body.map((item, index) => { 111 | var content; 112 | switch(index) { 113 | case 0: 114 | content = this.props.character.comics; 115 | break; 116 | case 1: 117 | content = this.props.character.events; 118 | break; 119 | case 2: 120 | content = this.props.character.series; 121 | break; 122 | case 3: 123 | content = this.props.character.stories; 124 | break; 125 | } 126 | var contentlayout = content.map((item, index) => { 127 | var key = `${item.name}-item-${index}`; 128 | return ({ this.setState({isLoading: true}); this.props.dispatch(getCharacterDetail(item.resourceURI))}} > { item.name } ); 129 | } 130 | ); 131 | var key = `${item}`; 132 | 133 | return ( 134 | 135 | 136 | {item} 137 | 138 | 139 | {contentlayout} 140 | 141 | 142 | ); 143 | }); 144 | 145 | return ( 146 | 147 | {bodyLayout} 148 | 149 | ); 150 | } 151 | } 152 | 153 | var styles = StyleSheet.create({ 154 | container:{ 155 | flex: 1, 156 | flexDirection: 'column', 157 | backgroundColor: 'rgb(244,245,246)', 158 | }, 159 | toolbar: { 160 | height: 56, 161 | backgroundColor: 'rgb(18, 134, 117)',//green 162 | elevation: 2, 163 | borderRightWidth: 1, 164 | marginRight: -1, 165 | borderRightColor: 'transparent', 166 | }, 167 | 168 | head: { 169 | marginTop: 5, 170 | marginBottom: 5, 171 | paddingLeft: 5, 172 | paddingRight: 5, 173 | height: 180, 174 | width: undefined, 175 | flexDirection: 'row', 176 | backgroundColor:'white', 177 | borderColor: 'white', 178 | borderWidth: 1, 179 | borderRadius: 1, 180 | elevation: 2, 181 | }, 182 | 183 | img: { 184 | width: 120, 185 | height: undefined, 186 | alignItems: 'center', 187 | resizeMode:Image.resizeMode.contain, 188 | marginRight: 10, 189 | }, 190 | 191 | title: { 192 | fontSize: 18, 193 | fontWeight:'bold', 194 | alignItems: 'center', 195 | width: 200, 196 | flex: 1, 197 | }, 198 | 199 | description: { 200 | fontSize: 16, 201 | paddingRight: 5, 202 | width: windowWidth-130,//TODO, how to let Text autofit the view width? 203 | }, 204 | 205 | wiki: { 206 | fontSize: 15, 207 | marginBottom: 24, 208 | }, 209 | 210 | body: { 211 | marginBottom: 5, 212 | paddingLeft: 5, 213 | paddingRight: 5, 214 | height: undefined, 215 | width: undefined, 216 | flexDirection: 'column', 217 | backgroundColor:'white', 218 | borderColor: 'white', 219 | borderWidth: 1, 220 | borderRadius: 1, 221 | elevation: 2, 222 | }, 223 | 224 | bodyTitle: { 225 | width: undefined, 226 | height: undefined, 227 | fontWeight:'bold', 228 | fontSize: 16, 229 | }, 230 | 231 | bodyItem: { 232 | width: undefined, 233 | height: undefined, 234 | color: 'blue', 235 | }, 236 | 237 | star: { 238 | width: 24, 239 | height: 24, 240 | }, 241 | 242 | loading: { 243 | position: 'absolute', 244 | bottom: 0, 245 | left: 0, 246 | right: 0, 247 | top: 0, 248 | backgroundColor: 'transparent', 249 | alignSelf: 'center', 250 | }, 251 | }); 252 | 253 | function select(store) { 254 | return { 255 | detailUrl: store.marvel.detailUrl, 256 | }; 257 | } 258 | 259 | module.exports = connect(select)(CharacterDetailView); 260 | -------------------------------------------------------------------------------- /js/tabs/characters/CharactersContentView.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @flow 3 | */ 4 | 'use strict'; 5 | 6 | var React = require('React'); 7 | var Text = require('Text'); 8 | var View = require('View'); 9 | var ToolbarAndroid = require('ToolbarAndroid'); 10 | var StyleSheet = require('StyleSheet'); 11 | var TextInput = require('TextInput'); 12 | var Image = require('Image'); 13 | var {connect} = require('react-redux'); 14 | var ListView = require('ListView'); 15 | var TouchableHighlight = require('TouchableHighlight'); 16 | var RecyclerViewBackedScrollView = require('RecyclerViewBackedScrollView'); 17 | var MarvelHeader = require('MarvelHeader'); 18 | var {windowWidth} = require('constant'); 19 | var Platform = require('Platform'); 20 | 21 | import ActionButton from 'react-native-action-button'; 22 | import type {Character} from '../../marvelapi/model'; 23 | 24 | var batman = require('../img/batmancolor.png'); 25 | var ds = new ListView.DataSource({rowHasChanged: (r1, r2) => r1 !== r2}); 26 | 27 | class CharactersContentView extends React.Component { 28 | 29 | handleIconClicked: () => void; 30 | renderRow: (rowData: any, sectionID: number, rowID: number, highlightRow: (sectionID: number, rowID: number) => void) => React.Element; 31 | 32 | constructor(props: any) { 33 | super(props); 34 | this.handleIconClicked = this.handleIconClicked.bind(this); 35 | this.renderRow = this.renderRow.bind(this); 36 | } 37 | 38 | render() { 39 | if(this.props.characters && this.props.characters.length > 0) { 40 | ds = ds.cloneWithRows(this.props.characters); 41 | } 42 | 43 | var actionButton; 44 | var head; 45 | 46 | if(Platform.OS === 'android') { 47 | head = 48 | 49 | actionButton = { this.handleSearchIconClicked()}} 52 | />; 53 | } else { 54 | head = 55 | } 56 | 57 | return ( 58 | 59 | {head} 60 | } 65 | /> 66 | {actionButton} 67 | 68 | ); 69 | } 70 | 71 | handleCharacterClicked(selectedItem: Character) { 72 | this.props.navigator.push({ character: selectedItem }); 73 | } 74 | 75 | renderRow(rowData: Character, sectionID: number, rowID: number, highlightRow: (sectionID: number, rowID: number) => void) { 76 | return ( 77 | { 78 | highlightRow(sectionID, rowID); 79 | this.handleCharacterClicked(rowData); 80 | }}> 81 | 82 | 83 | 84 | 85 | {rowData.name} 86 | 87 | 88 | {rowData.description} 89 | 90 | 91 | 92 | 93 | ); 94 | } 95 | 96 | handleIconClicked() { 97 | this.context.openDrawer(); 98 | } 99 | 100 | handleSearchIconClicked() { 101 | this.props.navigator.push({ search: "search hero" }); 102 | } 103 | } 104 | 105 | CharactersContentView.contextTypes = { 106 | openDrawer: React.PropTypes.func, 107 | }; 108 | 109 | var styles = StyleSheet.create({ 110 | container:{ 111 | flex: 1, 112 | flexDirection: 'column', 113 | backgroundColor: 'transparent', 114 | }, 115 | toolbar: { 116 | height: 56, 117 | backgroundColor: 'rgb(18, 134, 117)',//green 118 | elevation: 2, 119 | borderRightWidth: 1, 120 | marginRight: -1, 121 | borderRightColor: 'transparent', 122 | }, 123 | 124 | searchbox: { 125 | height: 56, 126 | width: 290, 127 | alignSelf: 'center', 128 | fontSize: 15, 129 | }, 130 | 131 | row: { 132 | marginLeft: 10, 133 | marginRight: 10, 134 | marginTop: 5, 135 | marginBottom: 5, 136 | paddingLeft: 5, 137 | paddingRight: 5, 138 | height: 100, 139 | width: undefined, 140 | flexDirection: 'row', 141 | backgroundColor:'white', 142 | borderColor: 'white', 143 | borderWidth: 1, 144 | borderRadius: 1, 145 | elevation: 2, 146 | }, 147 | 148 | thumb: { 149 | width: 80, 150 | height: undefined, 151 | alignItems: 'center', 152 | resizeMode:Image.resizeMode.contain, 153 | marginRight: 10, 154 | }, 155 | 156 | title: { 157 | marginTop: 15, 158 | fontSize: 18, 159 | fontWeight:'bold', 160 | }, 161 | 162 | text: { 163 | fontSize: 16, 164 | paddingRight: 5, 165 | width: windowWidth-130,//TODO, how to let Text autofit the view width? 166 | } 167 | }); 168 | 169 | function select(store) { 170 | return { 171 | characters: store.marvel.popularcharacters, 172 | }; 173 | } 174 | 175 | module.exports = connect(select)(CharactersContentView); 176 | -------------------------------------------------------------------------------- /js/tabs/characters/SearchView.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @flow 3 | */ 4 | 5 | 'use strict'; 6 | var React = require('react'); 7 | var Text = require('Text'); 8 | var View = require('View'); 9 | var ToolbarAndroid = require('ToolbarAndroid'); 10 | var StyleSheet = require('StyleSheet'); 11 | var TextInput = require('TextInput'); 12 | var Image = require('Image'); 13 | var TouchableHighlight = require('TouchableHighlight'); 14 | var {connect} = require('react-redux'); 15 | var ListView = require('ListView'); 16 | var RecyclerViewBackedScrollView = require('RecyclerViewBackedScrollView'); 17 | var {windowWidth} = require('constant'); 18 | var ProgressBar = require('ActivityIndicator'); 19 | var Platform = require('Platform'); 20 | 21 | import type {Character} from '../../marvelapi/model'; 22 | 23 | var {searchCharacterByName, clearSearchResult} = require('../../actions'); 24 | 25 | import TimerMixin from 'react-timer-mixin'; 26 | 27 | var ds = new ListView.DataSource({rowHasChanged: (r1, r2) => r1 !== r2}); 28 | var timerId = 0; 29 | 30 | var titleBarBackgroundColor = Platform.OS === 'android' ? 'rgb(18, 134, 117)' : 'rgb(23, 96, 157)'; 31 | 32 | class SearchView extends React.Component { 33 | state: { 34 | isSearching: boolean; 35 | searchText: string; 36 | }; 37 | 38 | handleBackPressed: () => void; 39 | onChangeText: (text: string) => void; 40 | renderRow: (rowData: any, sectionID: number, rowID: number, highlightRow: (sectionID: number, rowID: number) => void) => React.Element; 41 | 42 | constructor(props) { 43 | super(props); 44 | this.handleBackPressed = this.handleBackPressed.bind(this); 45 | this.onChangeText = this.onChangeText.bind(this); 46 | this.renderRow = this.renderRow.bind(this); 47 | this.state = { 48 | isSearching: false, 49 | searchText: "", 50 | } 51 | } 52 | 53 | componentDidMount() { 54 | this.props.dispatch(clearSearchResult()); 55 | } 56 | 57 | componentWillReceiveProps(nextProps) { 58 | this.setState({ 59 | isSearching: false 60 | }); 61 | } 62 | 63 | render() { 64 | var empty; 65 | if(this.props.result !== null && this.props.result.length > 0) { 66 | ds = ds.cloneWithRows(this.props.result); 67 | empty = false; 68 | } else { 69 | ds = ds.cloneWithRows([]); 70 | empty = true; 71 | } 72 | 73 | var progress; 74 | var content; 75 | var back; 76 | if(Platform.OS === 'android') { 77 | back = 78 | 79 | 80 | } 81 | 82 | var input = 88 | 89 | if(this.state.isSearching) { 90 | progress = ; 91 | } else { 92 | if(empty) { 93 | if(this.state.searchText === null || this.state.searchText.length === 0) { 94 | content = Type the Hero name to search 95 | } else { 96 | content = Not Found 97 | } 98 | } else { 99 | content = } 104 | enableEmptySections 105 | /> 106 | } 107 | } 108 | 109 | return ( 110 | 111 | 113 | 114 | {back} 115 | {input} 116 | 117 | {progress} 118 | {content} 119 | 120 | ); 121 | } 122 | 123 | handleCharacterClicked(selectedItem: Character) { 124 | this.props.navigator.push({ character: selectedItem }); 125 | } 126 | 127 | renderRow(rowData: Character, sectionID: number, rowID: number, highlightRow: (sectionID: number, rowID: number) => void) { 128 | return ( 129 | { 130 | highlightRow(sectionID, rowID); 131 | this.handleCharacterClicked(rowData); 132 | }}> 133 | 134 | 135 | 136 | 137 | {rowData.name} 138 | 139 | 140 | {rowData.description} 141 | 142 | 143 | 144 | 145 | ); 146 | } 147 | 148 | handleBackPressed() { 149 | this.props.navigator.pop(); 150 | } 151 | 152 | onChangeText(text: string) { 153 | TimerMixin.clearTimeout(timerId); 154 | timerId = TimerMixin.setTimeout(() => {this.searchCharacter(text)}, 1000); 155 | 156 | } 157 | 158 | searchCharacter(name: string) { 159 | 160 | if(name.length > 0) { 161 | this.props.dispatch(searchCharacterByName(name)); 162 | this.setState({ 163 | isSearching: true, 164 | searchText: name, 165 | }); 166 | } else { 167 | this.props.dispatch(clearSearchResult()); 168 | this.setState({ 169 | isSearching: false, 170 | searchText: name, 171 | }); 172 | } 173 | } 174 | } 175 | 176 | var styles = StyleSheet.create({ 177 | toolbar: { 178 | height: 56, 179 | backgroundColor: titleBarBackgroundColor, 180 | elevation: 2, 181 | borderRightWidth: 1, 182 | marginRight: -1, 183 | borderRightColor: 'transparent', 184 | flexDirection: 'row', 185 | }, 186 | 187 | back: { 188 | alignItems: 'center', 189 | margin: 20, 190 | }, 191 | 192 | search: { 193 | height: 50, 194 | width: 250, 195 | alignSelf: 'center', 196 | color: 'white', 197 | marginLeft: 20, 198 | }, 199 | 200 | content: { 201 | fontSize: 18, 202 | alignSelf: 'center', 203 | marginTop: 150, 204 | }, 205 | 206 | row: { 207 | marginLeft: 10, 208 | marginRight: 10, 209 | marginTop: 5, 210 | marginBottom: 5, 211 | paddingLeft: 5, 212 | paddingRight: 5, 213 | height: 100, 214 | width: undefined, 215 | flexDirection: 'row', 216 | backgroundColor:'white', 217 | borderColor: 'white', 218 | borderWidth: 1, 219 | borderRadius: 1, 220 | elevation: 2, 221 | }, 222 | 223 | thumb: { 224 | width: 80, 225 | height: undefined, 226 | alignItems: 'center', 227 | resizeMode:Image.resizeMode.contain, 228 | marginRight: 10, 229 | }, 230 | 231 | title: { 232 | marginTop: 15, 233 | fontSize: 18, 234 | fontWeight:'bold', 235 | }, 236 | 237 | text: { 238 | fontSize: 16, 239 | paddingRight: 5, 240 | width: windowWidth-130,//TODO, how to let Text autofit the view width? 241 | } 242 | }); 243 | 244 | function select(store) { 245 | return { 246 | result: store.marvel.searchResult, 247 | }; 248 | } 249 | 250 | module.exports = connect(select)(SearchView); 251 | -------------------------------------------------------------------------------- /js/tabs/img/about_marvel_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Shuijwan/marvel/47f2a96ed37af852892b10a07512f61a3070d99f/js/tabs/img/about_marvel_logo.png -------------------------------------------------------------------------------- /js/tabs/img/back.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Shuijwan/marvel/47f2a96ed37af852892b10a07512f61a3070d99f/js/tabs/img/back.png -------------------------------------------------------------------------------- /js/tabs/img/back@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Shuijwan/marvel/47f2a96ed37af852892b10a07512f61a3070d99f/js/tabs/img/back@2x.png -------------------------------------------------------------------------------- /js/tabs/img/back@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Shuijwan/marvel/47f2a96ed37af852892b10a07512f61a3070d99f/js/tabs/img/back@3x.png -------------------------------------------------------------------------------- /js/tabs/img/batman.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Shuijwan/marvel/47f2a96ed37af852892b10a07512f61a3070d99f/js/tabs/img/batman.png -------------------------------------------------------------------------------- /js/tabs/img/batman@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Shuijwan/marvel/47f2a96ed37af852892b10a07512f61a3070d99f/js/tabs/img/batman@2x.png -------------------------------------------------------------------------------- /js/tabs/img/batman@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Shuijwan/marvel/47f2a96ed37af852892b10a07512f61a3070d99f/js/tabs/img/batman@3x.png -------------------------------------------------------------------------------- /js/tabs/img/batmancolor.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Shuijwan/marvel/47f2a96ed37af852892b10a07512f61a3070d99f/js/tabs/img/batmancolor.png -------------------------------------------------------------------------------- /js/tabs/img/batmancolor@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Shuijwan/marvel/47f2a96ed37af852892b10a07512f61a3070d99f/js/tabs/img/batmancolor@2x.png -------------------------------------------------------------------------------- /js/tabs/img/batmancolor@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Shuijwan/marvel/47f2a96ed37af852892b10a07512f61a3070d99f/js/tabs/img/batmancolor@3x.png -------------------------------------------------------------------------------- /js/tabs/img/head_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Shuijwan/marvel/47f2a96ed37af852892b10a07512f61a3070d99f/js/tabs/img/head_2.png -------------------------------------------------------------------------------- /js/tabs/img/share.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Shuijwan/marvel/47f2a96ed37af852892b10a07512f61a3070d99f/js/tabs/img/share.png -------------------------------------------------------------------------------- /js/tabs/img/share@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Shuijwan/marvel/47f2a96ed37af852892b10a07512f61a3070d99f/js/tabs/img/share@2x.png -------------------------------------------------------------------------------- /js/tabs/img/shield.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Shuijwan/marvel/47f2a96ed37af852892b10a07512f61a3070d99f/js/tabs/img/shield.png -------------------------------------------------------------------------------- /js/tabs/img/shield@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Shuijwan/marvel/47f2a96ed37af852892b10a07512f61a3070d99f/js/tabs/img/shield@2x.png -------------------------------------------------------------------------------- /js/tabs/img/shield@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Shuijwan/marvel/47f2a96ed37af852892b10a07512f61a3070d99f/js/tabs/img/shield@3x.png -------------------------------------------------------------------------------- /js/tabs/img/shieldcolor.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Shuijwan/marvel/47f2a96ed37af852892b10a07512f61a3070d99f/js/tabs/img/shieldcolor.png -------------------------------------------------------------------------------- /js/tabs/img/shieldcolor@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Shuijwan/marvel/47f2a96ed37af852892b10a07512f61a3070d99f/js/tabs/img/shieldcolor@2x.png -------------------------------------------------------------------------------- /js/tabs/img/shieldcolor@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Shuijwan/marvel/47f2a96ed37af852892b10a07512f61a3070d99f/js/tabs/img/shieldcolor@3x.png -------------------------------------------------------------------------------- /js/tabs/img/star.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Shuijwan/marvel/47f2a96ed37af852892b10a07512f61a3070d99f/js/tabs/img/star.png -------------------------------------------------------------------------------- /js/tabs/img/star@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Shuijwan/marvel/47f2a96ed37af852892b10a07512f61a3070d99f/js/tabs/img/star@2x.png -------------------------------------------------------------------------------- /js/tabs/img/unstar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Shuijwan/marvel/47f2a96ed37af852892b10a07512f61a3070d99f/js/tabs/img/unstar.png -------------------------------------------------------------------------------- /js/tabs/img/unstar@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Shuijwan/marvel/47f2a96ed37af852892b10a07512f61a3070d99f/js/tabs/img/unstar@2x.png -------------------------------------------------------------------------------- /js/tabs/img/wolve.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Shuijwan/marvel/47f2a96ed37af852892b10a07512f61a3070d99f/js/tabs/img/wolve.png -------------------------------------------------------------------------------- /js/tabs/img/wolve@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Shuijwan/marvel/47f2a96ed37af852892b10a07512f61a3070d99f/js/tabs/img/wolve@2x.png -------------------------------------------------------------------------------- /js/tabs/img/wolve@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Shuijwan/marvel/47f2a96ed37af852892b10a07512f61a3070d99f/js/tabs/img/wolve@3x.png -------------------------------------------------------------------------------- /js/tabs/img/wolvecolor.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Shuijwan/marvel/47f2a96ed37af852892b10a07512f61a3070d99f/js/tabs/img/wolvecolor.png -------------------------------------------------------------------------------- /js/tabs/img/wolvecolor@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Shuijwan/marvel/47f2a96ed37af852892b10a07512f61a3070d99f/js/tabs/img/wolvecolor@2x.png -------------------------------------------------------------------------------- /js/tabs/img/wolvecolor@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Shuijwan/marvel/47f2a96ed37af852892b10a07512f61a3070d99f/js/tabs/img/wolvecolor@3x.png -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "marvel", 3 | "version": "0.0.1", 4 | "private": true, 5 | "scripts": { 6 | "start": "react-native start" 7 | }, 8 | "dependencies": { 9 | "crypto-js": "~3.1.6", 10 | "react": "^15.1.0", 11 | "react-native": "^0.28.0", 12 | "redux": "^2.0.0", 13 | "react-redux": "~4.4.5", 14 | "redux-logger": "~2.5.0", 15 | "react-native-action-button": "~1.1.5", 16 | "react-native-hyperlink": "~0.0.5", 17 | "react-timer-mixin": "~0.13.3", 18 | "realm": "~0.13.2", 19 | "react-native-share": "~1.0.11" 20 | }, 21 | "devDependencies": { 22 | "flow-bin": "^0.27.0" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /screenshot/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Shuijwan/marvel/47f2a96ed37af852892b10a07512f61a3070d99f/screenshot/1.png -------------------------------------------------------------------------------- /screenshot/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Shuijwan/marvel/47f2a96ed37af852892b10a07512f61a3070d99f/screenshot/2.png -------------------------------------------------------------------------------- /screenshot/3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Shuijwan/marvel/47f2a96ed37af852892b10a07512f61a3070d99f/screenshot/3.png -------------------------------------------------------------------------------- /screenshot/4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Shuijwan/marvel/47f2a96ed37af852892b10a07512f61a3070d99f/screenshot/4.png -------------------------------------------------------------------------------- /screenshot/5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Shuijwan/marvel/47f2a96ed37af852892b10a07512f61a3070d99f/screenshot/5.png -------------------------------------------------------------------------------- /screenshot/6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Shuijwan/marvel/47f2a96ed37af852892b10a07512f61a3070d99f/screenshot/6.png -------------------------------------------------------------------------------- /screenshot/7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Shuijwan/marvel/47f2a96ed37af852892b10a07512f61a3070d99f/screenshot/7.png --------------------------------------------------------------------------------