diff --git a/example/ProgressChart/.flowconfig b/example/ProgressChart/.flowconfig index 05cad20..c3edaf9 100644 --- a/example/ProgressChart/.flowconfig +++ b/example/ProgressChart/.flowconfig @@ -7,12 +7,26 @@ # Some modules have their own node_modules with overlap .*/node_modules/node-haste/.* -# Ignore react-tools where there are overlaps, but don't ignore anything that -# react-native relies on -.*/node_modules/react-tools/src/React.js -.*/node_modules/react-tools/src/renderers/shared/event/EventPropagators.js -.*/node_modules/react-tools/src/renderers/shared/event/eventPlugins/ResponderEventPlugin.js -.*/node_modules/react-tools/src/shared/vendor/core/ExecutionEnvironment.js +# Ugh +.*/node_modules/babel.* +.*/node_modules/babylon.* +.*/node_modules/invariant.* + +# Ignore react and fbjs where there are overlaps, but don't ignore +# anything that react-native relies on +.*/node_modules/fbjs/lib/Map.js +.*/node_modules/fbjs/lib/Promise.js +.*/node_modules/fbjs/lib/fetch.js +.*/node_modules/fbjs/lib/ExecutionEnvironment.js +.*/node_modules/fbjs/lib/isEmpty.js +.*/node_modules/fbjs/lib/crc32.js +.*/node_modules/fbjs/lib/ErrorUtils.js + +# Flow has a built-in definition for the 'react' module which we prefer to use +# over the currently-untyped source +.*/node_modules/react/react.js +.*/node_modules/react/lib/React.js +.*/node_modules/react/lib/ReactDOM.js # Ignore commoner tests .*/node_modules/commoner/test/.* @@ -37,15 +51,15 @@ module.system=haste munge_underscores=true module.name_mapper='^image![a-zA-Z0-9$_-]+$' -> 'GlobalImageStub' -module.name_mapper='^[./a-zA-Z0-9$_-]+\.png$' -> 'RelativeImageStub' +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\)$' -> 'RelativeImageStub' suppress_type=$FlowIssue suppress_type=$FlowFixMe suppress_type=$FixMe -suppress_comment=\\(.\\|\n\\)*\\$FlowFixMe\\($\\|[^(]\\|(\\(>=0\\.\\(1[0-7]\\|[0-9]\\).[0-9]\\)? *\\(site=[a-z,_]*react_native[a-z,_]*\\)?)\\) -suppress_comment=\\(.\\|\n\\)*\\$FlowIssue\\((\\(>=0\\.\\(1[0-7]\\|[0-9]\\).[0-9]\\)? *\\(site=[a-z,_]*react_native[a-z,_]*\\)?)\\)? #[0-9]+ +suppress_comment=\\(.\\|\n\\)*\\$FlowFixMe\\($\\|[^(]\\|(\\(>=0\\.\\(2[0-1]\\|1[0-9]\\|[0-9]\\).[0-9]\\)? *\\(site=[a-z,_]*react_native[a-z,_]*\\)?)\\) +suppress_comment=\\(.\\|\n\\)*\\$FlowIssue\\((\\(>=0\\.\\(2[0-1]\\|1[0-9]\\|[0-9]\\).[0-9]\\)? *\\(site=[a-z,_]*react_native[a-z,_]*\\)?)\\)?:? #[0-9]+ suppress_comment=\\(.\\|\n\\)*\\$FlowFixedInNextDeploy [version] -0.17.0 +0.21.0 diff --git a/example/ProgressChart/android/app/build.gradle b/example/ProgressChart/android/app/build.gradle index 7429193..d89d4c8 100644 --- a/example/ProgressChart/android/app/build.gradle +++ b/example/ProgressChart/android/app/build.gradle @@ -1,4 +1,79 @@ -apply plugin: 'com.android.application' +apply plugin: "com.android.application" + +import com.android.build.OutputFile + +/** + * The react.gradle file registers a task for each build variant (e.g. bundleDebugJsAndAssets + * and bundleReleaseJsAndAssets). + * These basically call `react-native bundle` with the correct arguments during the Android build + * cycle. By default, bundleDebugJsAndAssets is skipped, as in debug/dev mode we prefer to load the + * bundle directly from the development server. Below you can see all the possible configurations + * and their defaults. If you decide to add a configuration block, make sure to add it before the + * `apply from: "react.gradle"` line. + * + * project.ext.react = [ + * // the name of the generated asset file containing your JS bundle + * bundleAssetName: "index.android.bundle", + * + * // the entry file for bundle generation + * entryFile: "index.android.js", + * + * // whether to bundle JS and assets in debug mode + * bundleInDebug: false, + * + * // whether to bundle JS and assets in release mode + * bundleInRelease: true, + * + * // whether to bundle JS and assets in another build variant (if configured). + * // See http://tools.android.com/tech-docs/new-build-system/user-guide#TOC-Build-Variants + * // The configuration property is in the format 'bundleIn${productFlavor}${buildType}' + * // bundleInFreeDebug: true, + * // bundleInPaidRelease: true, + * // bundleInBeta: true, + * + * // the root of your project, i.e. where "package.json" lives + * root: "../../", + * + * // where to put the JS bundle asset in debug mode + * jsBundleDirDebug: "$buildDir/intermediates/assets/debug", + * + * // where to put the JS bundle asset in release mode + * jsBundleDirRelease: "$buildDir/intermediates/assets/release", + * + * // where to put drawable resources / React Native assets, e.g. the ones you use via + * // require('./image.png')), in debug mode + * resourcesDirDebug: "$buildDir/intermediates/res/merged/debug", + * + * // where to put drawable resources / React Native assets, e.g. the ones you use via + * // require('./image.png')), in release mode + * resourcesDirRelease: "$buildDir/intermediates/res/merged/release", + * + * // by default the gradle tasks are skipped if none of the JS files or assets change; this means + * // that we don't look at files in android/ or ios/ to determine whether the tasks are up to + * // date; if you have any other folders that you want to ignore for performance reasons (gradle + * // indexes the entire tree), add them here. Alternatively, if you have JS files in android/ + * // for example, you might want to remove it from here. + * inputExcludes: ["android/**", "ios/**"] + * ] + */ + +apply from: "react.gradle" + +/** + * Set this to true to create three separate APKs instead of one: + * - A universal APK that works on all devices + * - An APK that only works on ARM devices + * - An APK that only works on x86 devices + * The advantage is the size of the APK is reduced by about 4MB. + * Upload all the APKs to the Play Store and people will download + * the correct one based on the CPU architecture of their device. + */ +def enableSeparateBuildPerCPUArchitecture = false + +/** + * Run Proguard to shrink the Java bytecode in release builds. + */ +def enableProguardInReleaseBuilds = false android { compileSdkVersion 23 @@ -14,16 +89,37 @@ android { abiFilters "armeabi-v7a", "x86" } } + splits { + abi { + enable enableSeparateBuildPerCPUArchitecture + universalApk false + reset() + include "armeabi-v7a", "x86" + } + } buildTypes { release { - minifyEnabled false // Set this to true to enable Proguard - proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' + minifyEnabled enableProguardInReleaseBuilds + proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro" + } + } + // applicationVariants are e.g. debug, release + applicationVariants.all { variant -> + variant.outputs.each { output -> + // For each separate APK per architecture, set a unique version code as described here: + // http://tools.android.com/tech-docs/new-build-system/user-guide/apk-splits + def versionCodes = ["armeabi-v7a":1, "x86":2] + def abi = output.getFilter(OutputFile.ABI) + if (abi != null) { // null for the universal-debug, universal-release variants + output.versionCodeOverride = + versionCodes.get(abi) * 1048576 + defaultConfig.versionCode + } } } } dependencies { - compile fileTree(dir: 'libs', include: ['*.jar']) - compile 'com.android.support:appcompat-v7:23.0.1' - compile 'com.facebook.react:react-native:0.13.+' + compile fileTree(dir: "libs", include: ["*.jar"]) + compile "com.android.support:appcompat-v7:23.0.1" + compile "com.facebook.react:react-native:0.20.+" } diff --git a/example/ProgressChart/android/app/proguard-rules.pro b/example/ProgressChart/android/app/proguard-rules.pro index ffa8c9f..7d72e46 100644 --- a/example/ProgressChart/android/app/proguard-rules.pro +++ b/example/ProgressChart/android/app/proguard-rules.pro @@ -40,9 +40,12 @@ -keep class * extends com.facebook.react.bridge.JavaScriptModule { *; } -keep class * extends com.facebook.react.bridge.NativeModule { *; } +-keepclassmembers,includedescriptorclasses class * { native ; } -keepclassmembers class * { @com.facebook.react.uimanager.UIProp ; } --keepclassmembers class * { @com.facebook.react.uimanager.ReactProp ; } --keepclassmembers class * { @com.facebook.react.uimanager.ReactPropGroup ; } +-keepclassmembers class * { @com.facebook.react.uimanager.annotations.ReactProp ; } +-keepclassmembers class * { @com.facebook.react.uimanager.annotations.ReactPropGroup ; } + +-dontwarn com.facebook.react.** # okhttp @@ -58,3 +61,7 @@ -dontwarn java.nio.file.* -dontwarn org.codehaus.mojo.animal_sniffer.IgnoreJRERequirement -dontwarn okio.** + +# stetho + +-dontwarn com.facebook.stetho.** diff --git a/example/ProgressChart/android/app/src/main/java/com/progresschart/MainActivity.java b/example/ProgressChart/android/app/src/main/java/com/progresschart/MainActivity.java index d6ccfb2..2f961ca 100644 --- a/example/ProgressChart/android/app/src/main/java/com/progresschart/MainActivity.java +++ b/example/ProgressChart/android/app/src/main/java/com/progresschart/MainActivity.java @@ -1,78 +1,40 @@ package com.progresschart; -import android.app.Activity; -import android.os.Bundle; -import android.view.KeyEvent; - -import com.facebook.react.LifecycleState; -import com.facebook.react.ReactInstanceManager; -import com.facebook.react.ReactRootView; -import com.facebook.react.modules.core.DefaultHardwareBackBtnHandler; +import com.facebook.react.ReactActivity; +import com.facebook.react.ReactPackage; import com.facebook.react.shell.MainReactPackage; -import com.facebook.soloader.SoLoader; -public class MainActivity extends Activity implements DefaultHardwareBackBtnHandler { +import java.util.Arrays; +import java.util.List; - private ReactInstanceManager mReactInstanceManager; - private ReactRootView mReactRootView; +public class MainActivity extends ReactActivity { + /** + * Returns the name of the main component registered from JavaScript. + * This is used to schedule rendering of the component. + */ @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - mReactRootView = new ReactRootView(this); - - mReactInstanceManager = ReactInstanceManager.builder() - .setApplication(getApplication()) - .setBundleAssetName("index.android.bundle") - .setJSMainModuleName("index.android") - .addPackage(new MainReactPackage()) - .setUseDeveloperSupport(BuildConfig.DEBUG) - .setInitialLifecycleState(LifecycleState.RESUMED) - .build(); - - mReactRootView.startReactApplication(mReactInstanceManager, "ProgressChart", null); - - setContentView(mReactRootView); + protected String getMainComponentName() { + return "ProgressChart"; } + /** + * Returns whether dev mode should be enabled. + * This enables e.g. the dev menu. + */ @Override - public boolean onKeyUp(int keyCode, KeyEvent event) { - if (keyCode == KeyEvent.KEYCODE_MENU && mReactInstanceManager != null) { - mReactInstanceManager.showDevOptionsDialog(); - return true; - } - return super.onKeyUp(keyCode, event); + protected boolean getUseDeveloperSupport() { + return BuildConfig.DEBUG; } + /** + * A list of packages used by the app. If the app uses additional views + * or modules besides the default ones, add more packages here. + */ @Override - public void onBackPressed() { - if (mReactInstanceManager != null) { - mReactInstanceManager.onBackPressed(); - } else { - super.onBackPressed(); - } - } - - @Override - public void invokeDefaultOnBackPressed() { - super.onBackPressed(); - } - - @Override - protected void onPause() { - super.onPause(); - - if (mReactInstanceManager != null) { - mReactInstanceManager.onPause(); - } - } - - @Override - protected void onResume() { - super.onResume(); - - if (mReactInstanceManager != null) { - mReactInstanceManager.onResume(this); - } + protected List getPackages() { + return Arrays.asList( + new MainReactPackage() + ); } } diff --git a/example/ProgressChart/index.android.js b/example/ProgressChart/index.android.js index 14641c5..8511a5e 100644 --- a/example/ProgressChart/index.android.js +++ b/example/ProgressChart/index.android.js @@ -1,52 +1,3 @@ -/** - * Sample React Native App - * https://github.com/facebook/react-native - */ 'use strict'; -var React = require('react-native'); -var { - AppRegistry, - StyleSheet, - Text, - View, -} = React; - -var ProgressChart = React.createClass({ - render: function() { - return ( - - - Welcome to React Native! - - - To get started, edit index.android.js - - - Shake or press menu button for dev menu - - - ); - } -}); - -var styles = StyleSheet.create({ - container: { - flex: 1, - justifyContent: 'center', - alignItems: 'center', - backgroundColor: '#F5FCFF', - }, - welcome: { - fontSize: 20, - textAlign: 'center', - margin: 10, - }, - instructions: { - textAlign: 'center', - color: '#333333', - marginBottom: 5, - }, -}); - -AppRegistry.registerComponent('ProgressChart', () => ProgressChart); +require('./main'); diff --git a/example/ProgressChart/index.ios.js b/example/ProgressChart/index.ios.js index 3bdf09a..8511a5e 100644 --- a/example/ProgressChart/index.ios.js +++ b/example/ProgressChart/index.ios.js @@ -1,122 +1,3 @@ -import React, { AppRegistry, StyleSheet, Text, View, PanResponder } from 'react-native'; -import { AnimatedCircularProgress } from 'react-native-circular-progress'; +'use strict'; -const MAX_POINTS = 500; - -class ProgressChart extends React.Component { - - constructor() { - super(); - this.state = { - isMoving: false, - pointsDelta: 0, - points: 325 - }; - } - - componentWillMount() { - console.log('WILL MOUNT'); - - this._panResponder = PanResponder.create({ - onStartShouldSetPanResponder: (evt, gestureState) => true, - onStartShouldSetPanResponderCapture: (evt, gestureState) => true, - onMoveShouldSetPanResponder: (evt, gestureState) => true, - onMoveShouldSetPanResponderCapture: (evt, gestureState) => true, - - onPanResponderGrant: (evt, gestureState) => { - this.setState({ isMoving: true, pointsDelta: 0 }); - }, - - onPanResponderMove: (evt, gestureState) => { - // For each 2 pixels add or subtract 1 point - this.setState({ pointsDelta: Math.round(-gestureState.dy / 2) }); - }, - onPanResponderTerminationRequest: (evt, gestureState) => true, - onPanResponderRelease: (evt, gestureState) => { - let points = this.state.points + this.state.pointsDelta; - console.log(Math.min(points, MAX_POINTS)); - this.setState({ - isMoving: false, - points: points > 0 ? Math.min(points, MAX_POINTS) : 0, - pointsDelta: 0 - }); - }, - }); - } - - render() { - const fill = this.state.points / MAX_POINTS * 100; - - return ( - - - { - (fill) => ( - - { Math.round(MAX_POINTS * fill / 100) } - - ) - } - - - - - - - - { this.state.pointsDelta >= 0 && '+' } - { this.state.pointsDelta } - - - ) - } -} - -const styles = StyleSheet.create({ - points: { - backgroundColor: 'transparent', - position: 'absolute', - top: 72, - left: 56, - width: 90, - fontSize: 14, - textAlign: 'center', - color: '#7591af', - fontSize: 50, - fontWeight: "100" - }, - container: { - flex: 1, - justifyContent: 'space-between', - alignItems: 'center', - backgroundColor: '#152d44', - padding: 50 - }, - pointsDelta: { - color: '#4c6479', - fontSize: 50, - fontWeight: "100" - }, - pointsDeltaActive: { - color: '#fff', - } -}); - -AppRegistry.registerComponent('ProgressChart', () => ProgressChart); +require('./main'); diff --git a/example/ProgressChart/ios/ProgressChart.xcodeproj/project.pbxproj b/example/ProgressChart/ios/ProgressChart.xcodeproj/project.pbxproj index 249999f..3f19e93 100644 --- a/example/ProgressChart/ios/ProgressChart.xcodeproj/project.pbxproj +++ b/example/ProgressChart/ios/ProgressChart.xcodeproj/project.pbxproj @@ -7,7 +7,6 @@ objects = { /* Begin PBXBuildFile section */ - 008F07F31AC5B25A0029DE68 /* main.jsbundle in Resources */ = {isa = PBXBuildFile; fileRef = 008F07F21AC5B25A0029DE68 /* main.jsbundle */; }; 00C302E51ABCBA2D00DB3ED1 /* libRCTActionSheet.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 00C302AC1ABCB8CE00DB3ED1 /* libRCTActionSheet.a */; }; 00C302E71ABCBA2D00DB3ED1 /* libRCTGeolocation.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 00C302BA1ABCB90400DB3ED1 /* libRCTGeolocation.a */; }; 00C302E81ABCBA2D00DB3ED1 /* libRCTImage.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 00C302C01ABCB91800DB3ED1 /* libRCTImage.a */; }; @@ -22,8 +21,8 @@ 13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB51A68108700A75B9A /* Images.xcassets */; }; 13B07FC11A68108700A75B9A /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB71A68108700A75B9A /* main.m */; }; 146834051AC3E58100842450 /* libReact.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 146834041AC3E56700842450 /* libReact.a */; }; + 5BA204191C7FFFBD002976EC /* libART.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5BA2040E1C7FFF1E002976EC /* libART.a */; }; 832341BD1AAA6AB300B99B32 /* libRCTText.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 832341B51AAA6A8300B99B32 /* libRCTText.a */; }; - CCB7F59F1BDF98910037D983 /* libART.a in Frameworks */ = {isa = PBXBuildFile; fileRef = CCB7F5931BDF973E0037D983 /* libART.a */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -90,6 +89,13 @@ remoteGlobalIDString = 83CBBA2E1A601D0E00E9B192; remoteInfo = React; }; + 5BA2040D1C7FFF1E002976EC /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 5BA204091C7FFF1E002976EC /* ART.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = 0CF68AC11AF0540F00FF9E5C; + remoteInfo = ART; + }; 78C398B81ACF4ADC00677621 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 78C398B01ACF4ADC00677621 /* RCTLinking.xcodeproj */; @@ -104,13 +110,6 @@ remoteGlobalIDString = 58B5119B1A9E6C1200147676; remoteInfo = RCTText; }; - CCB7F5921BDF973E0037D983 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = CCB7F58E1BDF973E0037D983 /* ART.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = 0CF68AC11AF0540F00FF9E5C; - remoteInfo = ART; - }; /* End PBXContainerItemProxy section */ /* Begin PBXFileReference section */ @@ -133,9 +132,9 @@ 13B07FB61A68108700A75B9A /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Info.plist; path = ProgressChart/Info.plist; sourceTree = ""; }; 13B07FB71A68108700A75B9A /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = main.m; path = ProgressChart/main.m; sourceTree = ""; }; 146833FF1AC3E56700842450 /* React.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = React.xcodeproj; path = "../node_modules/react-native/React/React.xcodeproj"; sourceTree = ""; }; + 5BA204091C7FFF1E002976EC /* ART.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = ART.xcodeproj; path = "../node_modules/react-native/Libraries/ART/ART.xcodeproj"; sourceTree = ""; }; 78C398B01ACF4ADC00677621 /* RCTLinking.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTLinking.xcodeproj; path = "../node_modules/react-native/Libraries/LinkingIOS/RCTLinking.xcodeproj"; sourceTree = ""; }; 832341B01AAA6A8300B99B32 /* RCTText.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTText.xcodeproj; path = "../node_modules/react-native/Libraries/Text/RCTText.xcodeproj"; sourceTree = ""; }; - CCB7F58E1BDF973E0037D983 /* ART.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = ART.xcodeproj; path = "../node_modules/react-native/Libraries/ART/ART.xcodeproj"; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -150,7 +149,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - CCB7F59F1BDF98910037D983 /* libART.a in Frameworks */, + 5BA204191C7FFFBD002976EC /* libART.a in Frameworks */, 146834051AC3E58100842450 /* libReact.a in Frameworks */, 00C302E51ABCBA2D00DB3ED1 /* libRCTActionSheet.a in Frameworks */, 00C302E71ABCBA2D00DB3ED1 /* libRCTGeolocation.a in Frameworks */, @@ -262,6 +261,14 @@ name = Products; sourceTree = ""; }; + 5BA2040A1C7FFF1E002976EC /* Products */ = { + isa = PBXGroup; + children = ( + 5BA2040E1C7FFF1E002976EC /* libART.a */, + ); + name = Products; + sourceTree = ""; + }; 78C398B11ACF4ADC00677621 /* Products */ = { isa = PBXGroup; children = ( @@ -273,7 +280,7 @@ 832341AE1AAA6A7D00B99B32 /* Libraries */ = { isa = PBXGroup; children = ( - CCB7F58E1BDF973E0037D983 /* ART.xcodeproj */, + 5BA204091C7FFF1E002976EC /* ART.xcodeproj */, 146833FF1AC3E56700842450 /* React.xcodeproj */, 00C302A71ABCB8CE00DB3ED1 /* RCTActionSheet.xcodeproj */, 00C302B51ABCB90400DB3ED1 /* RCTGeolocation.xcodeproj */, @@ -317,14 +324,6 @@ name = Products; sourceTree = ""; }; - CCB7F58F1BDF973E0037D983 /* Products */ = { - isa = PBXGroup; - children = ( - CCB7F5931BDF973E0037D983 /* libART.a */, - ); - name = Products; - sourceTree = ""; - }; /* End PBXGroup section */ /* Begin PBXNativeTarget section */ @@ -353,6 +352,7 @@ 13B07F871A680F5B00A75B9A /* Sources */, 13B07F8C1A680F5B00A75B9A /* Frameworks */, 13B07F8E1A680F5B00A75B9A /* Resources */, + 00DD1BFF1BD5951E006B06BC /* Bundle React Native code and images */, ); buildRules = ( ); @@ -391,8 +391,8 @@ projectDirPath = ""; projectReferences = ( { - ProductGroup = CCB7F58F1BDF973E0037D983 /* Products */; - ProjectRef = CCB7F58E1BDF973E0037D983 /* ART.xcodeproj */; + ProductGroup = 5BA2040A1C7FFF1E002976EC /* Products */; + ProjectRef = 5BA204091C7FFF1E002976EC /* ART.xcodeproj */; }, { ProductGroup = 00C302A81ABCB8CE00DB3ED1 /* Products */; @@ -500,6 +500,13 @@ remoteRef = 146834031AC3E56700842450 /* PBXContainerItemProxy */; sourceTree = BUILT_PRODUCTS_DIR; }; + 5BA2040E1C7FFF1E002976EC /* libART.a */ = { + isa = PBXReferenceProxy; + fileType = archive.ar; + path = libART.a; + remoteRef = 5BA2040D1C7FFF1E002976EC /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; 78C398B91ACF4ADC00677621 /* libRCTLinking.a */ = { isa = PBXReferenceProxy; fileType = archive.ar; @@ -514,13 +521,6 @@ remoteRef = 832341B41AAA6A8300B99B32 /* PBXContainerItemProxy */; sourceTree = BUILT_PRODUCTS_DIR; }; - CCB7F5931BDF973E0037D983 /* libART.a */ = { - isa = PBXReferenceProxy; - fileType = archive.ar; - path = libART.a; - remoteRef = CCB7F5921BDF973E0037D983 /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; /* End PBXReferenceProxy section */ /* Begin PBXResourcesBuildPhase section */ @@ -535,7 +535,6 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( - 008F07F31AC5B25A0029DE68 /* main.jsbundle in Resources */, 13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */, 13B07FBD1A68108700A75B9A /* LaunchScreen.xib in Resources */, ); @@ -543,6 +542,23 @@ }; /* End PBXResourcesBuildPhase section */ +/* Begin PBXShellScriptBuildPhase section */ + 00DD1BFF1BD5951E006B06BC /* Bundle React Native code and images */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "Bundle React Native code and images"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "export NODE_BINARY=node\n../node_modules/react-native/packager/react-native-xcode.sh"; + }; +/* End PBXShellScriptBuildPhase section */ + /* Begin PBXSourcesBuildPhase section */ 00E356EA1AD99517003FC87E /* Sources */ = { isa = PBXSourcesBuildPhase; diff --git a/example/ProgressChart/ios/ProgressChart/AppDelegate.m b/example/ProgressChart/ios/ProgressChart/AppDelegate.m index d36c3cc..5f3acf7 100644 --- a/example/ProgressChart/ios/ProgressChart/AppDelegate.m +++ b/example/ProgressChart/ios/ProgressChart/AppDelegate.m @@ -35,12 +35,8 @@ /** * OPTION 2 - * Load from pre-bundled file on disk. To re-generate the static bundle - * from the root of your project directory, run - * - * $ react-native bundle --minify - * - * see http://facebook.github.io/react-native/docs/runningondevice.html + * Load from pre-bundled file on disk. The static bundle is automatically + * generated by "Bundle React Native code and images" build step. */ // jsCodeLocation = [[NSBundle mainBundle] URLForResource:@"main" withExtension:@"jsbundle"]; @@ -51,7 +47,7 @@ launchOptions:launchOptions]; self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds]; - UIViewController *rootViewController = [[UIViewController alloc] init]; + UIViewController *rootViewController = [UIViewController new]; rootViewController.view = rootView; self.window.rootViewController = rootViewController; [self.window makeKeyAndVisible]; diff --git a/example/ProgressChart/ios/ProgressChart/Info.plist b/example/ProgressChart/ios/ProgressChart/Info.plist index cddf076..91963b2 100644 --- a/example/ProgressChart/ios/ProgressChart/Info.plist +++ b/example/ProgressChart/ios/ProgressChart/Info.plist @@ -40,7 +40,7 @@ NSAppTransportSecurity - + NSAllowsArbitraryLoads diff --git a/example/ProgressChart/ios/ProgressChartTests/ProgressChartTests.m b/example/ProgressChart/ios/ProgressChartTests/ProgressChartTests.m index cd352de..89abcd0 100644 --- a/example/ProgressChart/ios/ProgressChartTests/ProgressChartTests.m +++ b/example/ProgressChart/ios/ProgressChartTests/ProgressChartTests.m @@ -42,7 +42,7 @@ BOOL foundElement = NO; __block NSString *redboxError = nil; - RCTSetLogFunction(^(RCTLogLevel level, NSString *fileName, NSNumber *lineNumber, NSString *message) { + RCTSetLogFunction(^(RCTLogLevel level, RCTLogSource source, NSString *fileName, NSNumber *lineNumber, NSString *message) { if (level >= RCTLogLevelError) { redboxError = message; } diff --git a/example/ProgressChart/main.js b/example/ProgressChart/main.js new file mode 100644 index 0000000..3bdf09a --- /dev/null +++ b/example/ProgressChart/main.js @@ -0,0 +1,122 @@ +import React, { AppRegistry, StyleSheet, Text, View, PanResponder } from 'react-native'; +import { AnimatedCircularProgress } from 'react-native-circular-progress'; + +const MAX_POINTS = 500; + +class ProgressChart extends React.Component { + + constructor() { + super(); + this.state = { + isMoving: false, + pointsDelta: 0, + points: 325 + }; + } + + componentWillMount() { + console.log('WILL MOUNT'); + + this._panResponder = PanResponder.create({ + onStartShouldSetPanResponder: (evt, gestureState) => true, + onStartShouldSetPanResponderCapture: (evt, gestureState) => true, + onMoveShouldSetPanResponder: (evt, gestureState) => true, + onMoveShouldSetPanResponderCapture: (evt, gestureState) => true, + + onPanResponderGrant: (evt, gestureState) => { + this.setState({ isMoving: true, pointsDelta: 0 }); + }, + + onPanResponderMove: (evt, gestureState) => { + // For each 2 pixels add or subtract 1 point + this.setState({ pointsDelta: Math.round(-gestureState.dy / 2) }); + }, + onPanResponderTerminationRequest: (evt, gestureState) => true, + onPanResponderRelease: (evt, gestureState) => { + let points = this.state.points + this.state.pointsDelta; + console.log(Math.min(points, MAX_POINTS)); + this.setState({ + isMoving: false, + points: points > 0 ? Math.min(points, MAX_POINTS) : 0, + pointsDelta: 0 + }); + }, + }); + } + + render() { + const fill = this.state.points / MAX_POINTS * 100; + + return ( + + + { + (fill) => ( + + { Math.round(MAX_POINTS * fill / 100) } + + ) + } + + + + + + + + { this.state.pointsDelta >= 0 && '+' } + { this.state.pointsDelta } + + + ) + } +} + +const styles = StyleSheet.create({ + points: { + backgroundColor: 'transparent', + position: 'absolute', + top: 72, + left: 56, + width: 90, + fontSize: 14, + textAlign: 'center', + color: '#7591af', + fontSize: 50, + fontWeight: "100" + }, + container: { + flex: 1, + justifyContent: 'space-between', + alignItems: 'center', + backgroundColor: '#152d44', + padding: 50 + }, + pointsDelta: { + color: '#4c6479', + fontSize: 50, + fontWeight: "100" + }, + pointsDeltaActive: { + color: '#fff', + } +}); + +AppRegistry.registerComponent('ProgressChart', () => ProgressChart); diff --git a/example/ProgressChart/package.json b/example/ProgressChart/package.json index 4a11864..5f95d3b 100644 --- a/example/ProgressChart/package.json +++ b/example/ProgressChart/package.json @@ -7,7 +7,7 @@ }, "dependencies": { "art": "^0.10.0", - "react-native": "^0.13.2", - "react-native-circular-progress": "0.0.1" + "react-native": "^0.20.0", + "react-native-circular-progress": "latest" } } diff --git a/src/CircularProgress.js b/src/CircularProgress.js index 6b567fa..40d0a5a 100644 --- a/src/CircularProgress.js +++ b/src/CircularProgress.js @@ -1,18 +1,23 @@ -import React, { View, PropTypes } from 'react-native'; +import React, { View, PropTypes, Platform } from 'react-native'; import { Surface, Shape, Path, Group } from '../../react-native/Libraries/ART/ReactNativeART'; import MetricsPath from 'art/metrics/path'; - export default class CircularProgress extends React.Component { - circlePath(cx, cy, r) { + circlePath(cx, cy, r, startDegree, endDegree) { - return Path() - .moveTo(cx, cx) - .move(r, 0) - .arc(r * -2, 0, r, r) - .arc(r * 2, 0, r, r) - .close(); + let p = Path(); + if (Platform.OS === 'ios') { + p.path.push(0, cx + r, cy); + p.path.push(4, cx, cy, r, startDegree * Math.PI / 180, endDegree * Math.PI / 180, 1); + } else { + // For Android we have to resort to drawing low-level Path primitives, as ART does not support + // arbitrary circle segments. It also does not support strokeDash. + // Furthermore, the ART implementation seems to be buggy/different than the iOS one. + // MoveTo is not needed on Android + p.path.push(4, cx, cy, r, startDegree * Math.PI / 180, (startDegree - endDegree) * Math.PI / 180, 0); + } + return p; } extractFill(fill) { @@ -27,9 +32,10 @@ export default class CircularProgress extends React.Component { render() { const { size, width, tintColor, backgroundColor, style, rotation, children } = this.props; + const backgroundPath = this.circlePath(size / 2, size / 2, size / 2 - width / 2, 0, 360); - const circlePath = this.circlePath(size / 2, size / 2, size / 2 - width / 2); const fill = this.extractFill(this.props.fill); + const circlePath = this.circlePath(size / 2, size / 2, size / 2 - width / 2, 0, 360 * fill / 100); return ( @@ -37,14 +43,13 @@ export default class CircularProgress extends React.Component { width={size} height={size}> + - + stroke={tintColor} + strokeWidth={width} + strokeCap="butt"/> {