diff --git a/.gitignore b/.gitignore index 101931f..a989312 100644 --- a/.gitignore +++ b/.gitignore @@ -64,3 +64,13 @@ Carthage/Build fastlane/report.xml fastlane/screenshots + +# Android specific +.idea +local.properties +android/RNSketch.iml +.settings +.project +/build +.gradle +proguard-rules.pro diff --git a/android/android.iml b/android/android.iml new file mode 100644 index 0000000..686bd2a --- /dev/null +++ b/android/android.iml @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/android/app/.classpath b/android/app/.classpath new file mode 100644 index 0000000..c93a0dd --- /dev/null +++ b/android/app/.classpath @@ -0,0 +1,6 @@ + + + + + + diff --git a/android/app/.gitignore b/android/app/.gitignore new file mode 100644 index 0000000..796b96d --- /dev/null +++ b/android/app/.gitignore @@ -0,0 +1 @@ +/build diff --git a/android/app/app.iml b/android/app/app.iml new file mode 100644 index 0000000..f453151 --- /dev/null +++ b/android/app/app.iml @@ -0,0 +1,147 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/android/app/build.gradle b/android/app/build.gradle new file mode 100644 index 0000000..731d44c --- /dev/null +++ b/android/app/build.gradle @@ -0,0 +1,24 @@ +apply plugin: 'com.android.library' + +android { + compileSdkVersion 26 + defaultConfig { + buildToolsVersion="26.0.2" + minSdkVersion 16 + targetSdkVersion 26 + versionCode 1 + versionName "1.0" + testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" + } + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' + } + } +} + +dependencies { + compile fileTree(dir: 'libs', include: ['*.jar']) + compile 'com.facebook.react:react-native:0.20.1' +} diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..8dc536c --- /dev/null +++ b/android/app/src/main/AndroidManifest.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/android/app/src/main/java/com/stefannew/rnsketch/RNSketchManager.java b/android/app/src/main/java/com/stefannew/rnsketch/RNSketchManager.java new file mode 100644 index 0000000..77f8add --- /dev/null +++ b/android/app/src/main/java/com/stefannew/rnsketch/RNSketchManager.java @@ -0,0 +1,33 @@ +package com.stefannew.rnsketch; + +import com.facebook.react.ReactPackage; +import com.facebook.react.bridge.JavaScriptModule; +import com.facebook.react.bridge.NativeModule; +import com.facebook.react.bridge.ReactApplicationContext; +import com.facebook.react.uimanager.ViewManager; + +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +public class RNSketchManager implements ReactPackage { + + @Override + public List createNativeModules(ReactApplicationContext reactContext) { + return Arrays.asList( + new RNSketchModule(reactContext) + ); + } + + @Override + public List> createJSModules() { + return Collections.emptyList(); + } + + @Override + public List createViewManagers(ReactApplicationContext reactContext) { + return Arrays.asList( + new RNSketchViewManager() + ); + } +} diff --git a/android/app/src/main/java/com/stefannew/rnsketch/RNSketchModule.java b/android/app/src/main/java/com/stefannew/rnsketch/RNSketchModule.java new file mode 100644 index 0000000..ccdac9c --- /dev/null +++ b/android/app/src/main/java/com/stefannew/rnsketch/RNSketchModule.java @@ -0,0 +1,56 @@ +package com.stefannew.rnsketch; + +import android.widget.Toast; + +import com.facebook.react.bridge.Arguments; +import com.facebook.react.bridge.Promise; +import com.facebook.react.bridge.ReactApplicationContext; +import com.facebook.react.bridge.ReactContextBaseJavaModule; +import com.facebook.react.bridge.ReactMethod; +import com.facebook.react.bridge.WritableMap; + +import org.json.JSONException; +import org.json.JSONObject; + +import java.io.IOException; + +public class RNSketchModule extends ReactContextBaseJavaModule { + + RNSketchModule(ReactApplicationContext reactContext) { + super(reactContext); + } + + @Override + public String getName() { + return "RNSketchManager"; + } + + @ReactMethod + public void clearDrawing(final Promise promise) { + RNSketchView sketchView = new ViewInstanceManager().getView(); + sketchView.clearDrawing(); + promise.resolve(null); + } + + @ReactMethod + public void setStrokeColor(String strokeColor) { + RNSketchView sketchView = new ViewInstanceManager().getView(); + sketchView.setStrokeColor(strokeColor); + } + + @ReactMethod + public void saveDrawing(String imageData, String imageType, final Promise promise) { + RNSketchView sketchView = new ViewInstanceManager().getView(); + + try { + String path = sketchView.saveDrawing(imageData, imageType); + WritableMap map = Arguments.createMap(); + + map.putString("path", path); + + promise.resolve(map); + } catch (IOException e) { + promise.reject("FILE_SAVE_ERROR", e.getMessage()); + } + } +} diff --git a/android/app/src/main/java/com/stefannew/rnsketch/RNSketchView.java b/android/app/src/main/java/com/stefannew/rnsketch/RNSketchView.java new file mode 100644 index 0000000..4d35eca --- /dev/null +++ b/android/app/src/main/java/com/stefannew/rnsketch/RNSketchView.java @@ -0,0 +1,191 @@ +package com.stefannew.rnsketch; + +import android.annotation.SuppressLint; +import android.graphics.Bitmap; +import android.graphics.BitmapFactory; +import android.graphics.Canvas; +import android.graphics.Color; +import android.graphics.Paint; +import android.graphics.Path; +import android.util.Base64; +import android.view.MotionEvent; +import android.view.View; + +import com.facebook.react.bridge.Arguments; +import com.facebook.react.bridge.ReactContext; +import com.facebook.react.bridge.WritableMap; +import com.facebook.react.modules.core.DeviceEventManagerModule; +import com.facebook.react.uimanager.events.RCTEventEmitter; + +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Map; +import java.util.UUID; + +@SuppressLint("ViewConstructor") +public class RNSketchView extends View { + private ReactContext context; + private Path path; + private ArrayList paths = new ArrayList(); + private Paint paint; + private String imageType = "png"; + private Map colorMap = new HashMap(); + private ArrayList strokeWidths = new ArrayList<>(); + private float strokeThickness = 1f; + + int paintColor = Color.BLACK; + + public RNSketchView(ReactContext context) { + super(context); + + this.context = context; + + paint = new Paint(); + path = new Path(); + + paint.setAntiAlias(true); + paint.setStrokeCap(Paint.Cap.ROUND); + paint.setStrokeWidth(strokeThickness); + paint.setStrokeJoin(Paint.Join.ROUND); + paint.setStyle(Paint.Style.STROKE); + + setDrawingCacheEnabled(true); + } + + private void touchStart(float x, float y) { + path.reset(); + path.moveTo(x, y); + } + + private void touchMove(float x, float y) { + path.lineTo(x, y); + } + + private void touchUp(float x, float y) { + path.lineTo(x, y); + paths.add(path); + colorMap.put(path, paintColor); + path = new Path(); + strokeWidths.add(strokeThickness); + + WritableMap events = Arguments.createMap(); + events.putString("imageData", drawingToString(getDrawingCache())); + context.getJSModule(RCTEventEmitter.class).receiveEvent( + getId(), + "topChange", + events + ); + } + + @Override + protected void onDraw(Canvas canvas) { + for (int i = 0; i < paths.size(); i++) { + Path path = paths.get(i); + + paint.setColor(colorMap.get(path)); + paint.setStrokeWidth(strokeWidths.get(i)); + canvas.drawPath(path, paint); + } + + paint.setColor(paintColor); + paint.setStrokeWidth(strokeThickness); + canvas.drawPath(path, paint); + } + + @SuppressLint("ClickableViewAccessibility") + public boolean onTouchEvent(MotionEvent event) { + float x = event.getX(); + float y = event.getY(); + int pointerCount = event.getPointerCount(); + + if (pointerCount > 1) { + event.setAction(MotionEvent.ACTION_CANCEL); + return true; + } + + switch (event.getAction()) { + case MotionEvent.ACTION_DOWN: + touchStart(x, y); + return true; + case MotionEvent.ACTION_MOVE: + touchMove(x, y); + break; + case MotionEvent.ACTION_UP: + touchUp(x, y); + break; + default: + return false; + } + + postInvalidate(); + return true; + } + + public void setStrokeColor(String strokeColor) { + paintColor = Color.parseColor(strokeColor); + } + + public void setFillColor(String fillColor) {} + + public void setStrokeThickness(int strokeThickness) { + this.strokeThickness = (float) strokeThickness; + } + + public void setImageType(String imageType) { + this.imageType = imageType; + } + + public void clearDrawing() { + paths.clear(); + strokeWidths.clear(); + invalidate(); + + WritableMap events = Arguments.createMap(); + context.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class).emit( + "onClear", + events + ); + } + + public Bitmap.CompressFormat getImageFormat(String imageType) { + Bitmap.CompressFormat format; + + switch (imageType) { + case "png": + format = Bitmap.CompressFormat.PNG; + break; + case "jpg": + format = Bitmap.CompressFormat.JPEG; + break; + default: + throw new Error("imageType " + imageType + " is not a valid image type for exporting the drawing."); + } + + return format; + } + + public String saveDrawing(String imageData, String imageType) throws IOException { + File directory = context.getFilesDir(); + File filename = new File(directory, UUID.randomUUID().toString() + "." + imageType); + FileOutputStream fileOutputStream; + + fileOutputStream = new FileOutputStream(filename); + byte[] decodedString = Base64.decode(imageData, Base64.DEFAULT); + Bitmap decodedByte = BitmapFactory.decodeByteArray(decodedString, 0, decodedString.length); + decodedByte.compress(getImageFormat(imageType), 100, fileOutputStream); + + fileOutputStream.close(); + + return filename.getAbsolutePath(); + } + + public String drawingToString(Bitmap bitmap) { + ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); + bitmap.compress(getImageFormat(imageType), 100, byteArrayOutputStream); + return Base64.encodeToString(byteArrayOutputStream.toByteArray(), Base64.DEFAULT); + } +} diff --git a/android/app/src/main/java/com/stefannew/rnsketch/RNSketchViewManager.java b/android/app/src/main/java/com/stefannew/rnsketch/RNSketchViewManager.java new file mode 100644 index 0000000..0b6c103 --- /dev/null +++ b/android/app/src/main/java/com/stefannew/rnsketch/RNSketchViewManager.java @@ -0,0 +1,42 @@ +package com.stefannew.rnsketch; + +import com.facebook.react.uimanager.annotations.ReactProp; +import com.facebook.react.uimanager.SimpleViewManager; +import com.facebook.react.uimanager.ThemedReactContext; + +public class RNSketchViewManager extends SimpleViewManager { + + private static final String REACT_CLASS = "RNSketch"; + + @Override + public String getName() { + return REACT_CLASS; + } + + @Override + protected RNSketchView createViewInstance(ThemedReactContext reactContext) { + RNSketchView rnSketchView = new RNSketchView(reactContext); + new ViewInstanceManager().setView(rnSketchView); + return rnSketchView; + } + + @ReactProp(name = "fillColor") + public void setFillColor(RNSketchView view, String fillColor) { + view.setFillColor(fillColor); + } + + @ReactProp(name = "strokeColor") + public void setStrokeColor(RNSketchView view, String strokeColor) { + view.setStrokeColor(strokeColor); + } + + @ReactProp(name = "strokeThickness") + public void setStrokeThickness(RNSketchView view, int strokeThickness) { + view.setStrokeThickness(strokeThickness); + } + + @ReactProp(name = "imageType") + public void setImageType(RNSketchView view, String imageType) { + view.setImageType(imageType); + } +} diff --git a/android/app/src/main/java/com/stefannew/rnsketch/ViewInstanceManager.java b/android/app/src/main/java/com/stefannew/rnsketch/ViewInstanceManager.java new file mode 100644 index 0000000..b6b7ec4 --- /dev/null +++ b/android/app/src/main/java/com/stefannew/rnsketch/ViewInstanceManager.java @@ -0,0 +1,14 @@ +package com.stefannew.rnsketch; + +class ViewInstanceManager { + + private static RNSketchView sketchView; + + void setView(RNSketchView view) { + sketchView = view; + } + + RNSketchView getView() { + return sketchView; + } +} diff --git a/android/app/src/main/res/values/values.xml b/android/app/src/main/res/values/values.xml new file mode 100644 index 0000000..436b94c --- /dev/null +++ b/android/app/src/main/res/values/values.xml @@ -0,0 +1,4 @@ + + + + diff --git a/android/build.gradle b/android/build.gradle new file mode 100644 index 0000000..e6b32bc --- /dev/null +++ b/android/build.gradle @@ -0,0 +1,27 @@ +// Top-level build file where you can add configuration options common to all sub-projects/modules. + +buildscript { + + repositories { + google() + jcenter() + } + dependencies { + classpath 'com.android.tools.build:gradle:3.0.1' + + + // NOTE: Do not place your application dependencies here; they belong + // in the individual module build.gradle files + } +} + +allprojects { + repositories { + google() + jcenter() + } +} + +task clean(type: Delete) { + delete rootProject.buildDir +} diff --git a/android/gradle.properties b/android/gradle.properties new file mode 100644 index 0000000..aac7c9b --- /dev/null +++ b/android/gradle.properties @@ -0,0 +1,17 @@ +# Project-wide Gradle settings. + +# IDE (e.g. Android Studio) users: +# Gradle settings configured through the IDE *will override* +# any settings specified in this file. + +# For more details on how to configure your build environment visit +# http://www.gradle.org/docs/current/userguide/build_environment.html + +# Specifies the JVM arguments used for the daemon process. +# The setting is particularly useful for tweaking memory settings. +org.gradle.jvmargs=-Xmx1536m + +# When configured, Gradle will run in incubating parallel mode. +# This option should only be used with decoupled projects. More details, visit +# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects +# org.gradle.parallel=true diff --git a/android/gradle/wrapper/gradle-wrapper.jar b/android/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000..13372ae Binary files /dev/null and b/android/gradle/wrapper/gradle-wrapper.jar differ diff --git a/android/gradle/wrapper/gradle-wrapper.properties b/android/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 0000000..12b9e5c --- /dev/null +++ b/android/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,6 @@ +#Thu Jan 18 21:09:15 PST 2018 +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-4.1-all.zip diff --git a/android/gradlew b/android/gradlew new file mode 100755 index 0000000..9d82f78 --- /dev/null +++ b/android/gradlew @@ -0,0 +1,160 @@ +#!/usr/bin/env bash + +############################################################################## +## +## Gradle start up script for UN*X +## +############################################################################## + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS="" + +APP_NAME="Gradle" +APP_BASE_NAME=`basename "$0"` + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD="maximum" + +warn ( ) { + echo "$*" +} + +die ( ) { + echo + echo "$*" + echo + exit 1 +} + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +case "`uname`" in + CYGWIN* ) + cygwin=true + ;; + Darwin* ) + darwin=true + ;; + MINGW* ) + msys=true + ;; +esac + +# Attempt to set APP_HOME +# Resolve links: $0 may be a link +PRG="$0" +# Need this for relative symlinks. +while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG=`dirname "$PRG"`"/$link" + fi +done +SAVED="`pwd`" +cd "`dirname \"$PRG\"`/" >/dev/null +APP_HOME="`pwd -P`" +cd "$SAVED" >/dev/null + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD="java" + which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." +fi + +# Increase the maximum file descriptors if we can. +if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then + MAX_FD_LIMIT=`ulimit -H -n` + if [ $? -eq 0 ] ; then + if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then + MAX_FD="$MAX_FD_LIMIT" + fi + ulimit -n $MAX_FD + if [ $? -ne 0 ] ; then + warn "Could not set maximum file descriptor limit: $MAX_FD" + fi + else + warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" + fi +fi + +# For Darwin, add options to specify how the application appears in the dock +if $darwin; then + GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" +fi + +# For Cygwin, switch paths to Windows format before running java +if $cygwin ; then + APP_HOME=`cygpath --path --mixed "$APP_HOME"` + CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` + JAVACMD=`cygpath --unix "$JAVACMD"` + + # We build the pattern for arguments to be converted via cygpath + ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` + SEP="" + for dir in $ROOTDIRSRAW ; do + ROOTDIRS="$ROOTDIRS$SEP$dir" + SEP="|" + done + OURCYGPATTERN="(^($ROOTDIRS))" + # Add a user-defined pattern to the cygpath arguments + if [ "$GRADLE_CYGPATTERN" != "" ] ; then + OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" + fi + # Now convert the arguments - kludge to limit ourselves to /bin/sh + i=0 + for arg in "$@" ; do + CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` + CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option + + if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition + eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` + else + eval `echo args$i`="\"$arg\"" + fi + i=$((i+1)) + done + case $i in + (0) set -- ;; + (1) set -- "$args0" ;; + (2) set -- "$args0" "$args1" ;; + (3) set -- "$args0" "$args1" "$args2" ;; + (4) set -- "$args0" "$args1" "$args2" "$args3" ;; + (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; + (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; + (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; + (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; + (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; + esac +fi + +# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules +function splitJvmOpts() { + JVM_OPTS=("$@") +} +eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS +JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME" + +exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" diff --git a/android/gradlew.bat b/android/gradlew.bat new file mode 100644 index 0000000..aec9973 --- /dev/null +++ b/android/gradlew.bat @@ -0,0 +1,90 @@ +@if "%DEBUG%" == "" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS= + +set DIRNAME=%~dp0 +if "%DIRNAME%" == "" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if "%ERRORLEVEL%" == "0" goto init + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto init + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:init +@rem Get command-line arguments, handling Windowz variants + +if not "%OS%" == "Windows_NT" goto win9xME_args +if "%@eval[2+2]" == "4" goto 4NT_args + +:win9xME_args +@rem Slurp the command line arguments. +set CMD_LINE_ARGS= +set _SKIP=2 + +:win9xME_args_slurp +if "x%~1" == "x" goto execute + +set CMD_LINE_ARGS=%* +goto execute + +:4NT_args +@rem Get arguments from the 4NT Shell from JP Software +set CMD_LINE_ARGS=%$ + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% + +:end +@rem End local scope for the variables with windows NT shell +if "%ERRORLEVEL%"=="0" goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 +exit /b 1 + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/android/settings.gradle b/android/settings.gradle new file mode 100644 index 0000000..e7b4def --- /dev/null +++ b/android/settings.gradle @@ -0,0 +1 @@ +include ':app' diff --git a/index.ios.js b/index.js similarity index 70% rename from index.ios.js rename to index.js index 224c17c..fef8511 100644 --- a/index.ios.js +++ b/index.js @@ -1,6 +1,6 @@ import React from 'react'; import PropTypes from 'prop-types'; -import { NativeModules, requireNativeComponent, View, ViewPropTypes } from 'react-native'; +import { DeviceEventEmitter, NativeModules, requireNativeComponent, View, ViewPropTypes } from 'react-native'; const SketchManager = NativeModules.RNSketchManager || {}; @@ -42,9 +42,8 @@ export default class Sketch extends React.Component { imageData: null, }; - onChange = (event) => { + onChange = event => { const { imageData } = event.nativeEvent; - this.setState({ imageData }); this.props.onChange(imageData); }; @@ -54,14 +53,23 @@ export default class Sketch extends React.Component { this.props.onClear(); }; - clear = () => SketchManager.clearDrawing(); + clear = () => { + SketchManager.clearDrawing(); + } save = () => { if (!this.state.imageData) return Promise.reject('No image provided!'); - return SketchManager.saveDrawing(this.state.imageData, this.props.imageType); }; + componentWillMount() { + DeviceEventEmitter.addListener("onClear", this.onClear); + } + + componentWillUnmount() { + DeviceEventEmitter.removeListener("onClear", this.onClear); + } + render() { const { fillColor, strokeColor, strokeThickness, ...props } = this.props; @@ -79,4 +87,16 @@ export default class Sketch extends React.Component { } } -const RNSketch = requireNativeComponent('RNSketch', Sketch); +const RNSketch = requireNativeComponent('RNSketch', Sketch, { + nativeOnly: { + onChange: true, + onLayout: true, + testID: true, + nativeID: true, + importantForAccessibility: true, + accessibilityLiveRegion: true, + accessibilityComponentType: true, + accessibilityLabel: true, + renderToHardwareTextureAndroid: true, + }, +}); diff --git a/RNSketch.xcodeproj/project.pbxproj b/ios/RNSketch.xcodeproj/project.pbxproj similarity index 100% rename from RNSketch.xcodeproj/project.pbxproj rename to ios/RNSketch.xcodeproj/project.pbxproj diff --git a/RNSketch.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/ios/RNSketch.xcodeproj/project.xcworkspace/contents.xcworkspacedata similarity index 100% rename from RNSketch.xcodeproj/project.xcworkspace/contents.xcworkspacedata rename to ios/RNSketch.xcodeproj/project.xcworkspace/contents.xcworkspacedata diff --git a/RNSketch/RNSketch.h b/ios/RNSketch/RNSketch.h similarity index 100% rename from RNSketch/RNSketch.h rename to ios/RNSketch/RNSketch.h diff --git a/RNSketch/RNSketch.m b/ios/RNSketch/RNSketch.m similarity index 100% rename from RNSketch/RNSketch.m rename to ios/RNSketch/RNSketch.m diff --git a/RNSketch/RNSketchManager.h b/ios/RNSketch/RNSketchManager.h similarity index 100% rename from RNSketch/RNSketchManager.h rename to ios/RNSketch/RNSketchManager.h diff --git a/RNSketch/RNSketchManager.m b/ios/RNSketch/RNSketchManager.m similarity index 100% rename from RNSketch/RNSketchManager.m rename to ios/RNSketch/RNSketchManager.m diff --git a/package.json b/package.json index 3c37032..2b1ccb2 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "react-native-sketch", "version": "1.1.0", "description": "A react-native component for touch-based drawing", - "main": "index.ios.js", + "main": "index.js", "dependencies": { "prop-types": "^15.5.10" },