Skip to content

Commit ef73888

Browse files
guhungryTrancever
authored andcommitted
feat: BREAKING Use promise instead of callback (#29)
1 parent f6a8fc0 commit ef73888

File tree

6 files changed

+56
-53
lines changed

6 files changed

+56
-53
lines changed

README.md

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,15 +21,25 @@ or
2121

2222
`react-native link @react-native-community/image-editor`
2323

24-
## Api reference
24+
## Usage
25+
26+
Start by importing the library:
2527

2628
```javascript
27-
static cropImage(uri, cropData, success, failure)
29+
import ImageEditor from "@react-native-community/image-editor";
2830
```
2931

30-
Crop the image specified by the URI param. If URI points to a remote image, it will be downloaded automatically. If the image cannot be loaded/downloaded, the failure callback will be called.
32+
### Crop image
33+
34+
Crop the image specified by the URI param. If URI points to a remote image, it will be downloaded automatically. If the image cannot be loaded/downloaded, the promise will be rejected.
35+
36+
If the cropping process is successful, the resultant cropped image will be stored in the cache path, and the URI returned in the promise will point to the image in the cache path. Remember to delete the cropped image from the cache path when you are done with it.
3137

32-
If the cropping process is successful, the resultant cropped image will be stored in the ImageStore, and the URI returned in the success callback will point to the image in the store. Remember to delete the cropped image from the ImageStore when you are done with it.
38+
```javascript
39+
ImageEditor.cropImage(uri, cropData).then(url => {
40+
console.log("Cropped image uri", url);
41+
})
42+
```
3343

3444
### cropData
3545
| Property | Required | Description |

android/src/main/java/com/reactnativecommunity/imageeditor/ImageEditorModule.java

Lines changed: 12 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,8 @@
3737
import android.text.TextUtils;
3838

3939
import com.facebook.common.logging.FLog;
40-
import com.facebook.react.bridge.Callback;
4140
import com.facebook.react.bridge.GuardedAsyncTask;
41+
import com.facebook.react.bridge.Promise;
4242
import com.facebook.react.bridge.ReactApplicationContext;
4343
import com.facebook.react.bridge.ReactContext;
4444
import com.facebook.react.bridge.ReactContextBaseJavaModule;
@@ -150,25 +150,23 @@ public boolean accept(File dir, String filename) {
150150
}
151151

152152
/**
153-
* Crop an image. If all goes well, the success callback will be called with the file:// URI of
153+
* Crop an image. If all goes well, the promise will be resolved with the file:// URI of
154154
* the new image as the only argument. This is a temporary file - consider using
155155
* CameraRollManager.saveImageWithTag to save it in the gallery.
156156
*
157-
* @param uri the MediaStore URI of the image to crop
157+
* @param uri the URI of the image to crop
158158
* @param options crop parameters specified as {@code {offset: {x, y}, size: {width, height}}}.
159159
* Optionally this also contains {@code {targetSize: {width, height}}}. If this is
160160
* specified, the cropped image will be resized to that size.
161161
* All units are in pixels (not DPs).
162-
* @param success callback to be invoked when the image has been cropped; the only argument that
163-
* is passed to this callback is the file:// URI of the new image
164-
* @param error callback to be invoked when an error occurs (e.g. can't create file etc.)
162+
* @param promise Promise to be resolved when the image has been cropped; the only argument that
163+
* is passed to this is the file:// URI of the new image
165164
*/
166165
@ReactMethod
167166
public void cropImage(
168167
String uri,
169168
ReadableMap options,
170-
final Callback success,
171-
final Callback error) {
169+
Promise promise) {
172170
ReadableMap offset = options.hasKey("offset") ? options.getMap("offset") : null;
173171
ReadableMap size = options.hasKey("size") ? options.getMap("size") : null;
174172
if (offset == null || size == null ||
@@ -187,8 +185,7 @@ public void cropImage(
187185
(int) offset.getDouble("y"),
188186
(int) size.getDouble("width"),
189187
(int) size.getDouble("height"),
190-
success,
191-
error);
188+
promise);
192189
if (options.hasKey("displaySize")) {
193190
ReadableMap targetSize = options.getMap("displaySize");
194191
cropTask.setTargetSize(
@@ -207,8 +204,7 @@ private static class CropTask extends GuardedAsyncTask<Void, Void> {
207204
final int mHeight;
208205
int mTargetWidth = 0;
209206
int mTargetHeight = 0;
210-
final Callback mSuccess;
211-
final Callback mError;
207+
final Promise mPromise;
212208

213209
private CropTask(
214210
ReactContext context,
@@ -217,8 +213,7 @@ private CropTask(
217213
int y,
218214
int width,
219215
int height,
220-
Callback success,
221-
Callback error) {
216+
Promise promise) {
222217
super(context);
223218
if (x < 0 || y < 0 || width <= 0 || height <= 0) {
224219
throw new JSApplicationIllegalArgumentException(String.format(
@@ -230,8 +225,7 @@ private CropTask(
230225
mY = y;
231226
mWidth = width;
232227
mHeight = height;
233-
mSuccess = success;
234-
mError = error;
228+
mPromise = promise;
235229
}
236230

237231
public void setTargetSize(int width, int height) {
@@ -284,9 +278,9 @@ protected void doInBackgroundGuarded(Void... params) {
284278
copyExif(mContext, Uri.parse(mUri), tempFile);
285279
}
286280

287-
mSuccess.invoke(Uri.fromFile(tempFile).toString());
281+
mPromise.resolve(Uri.fromFile(tempFile).toString());
288282
} catch (Exception e) {
289-
mError.invoke(e.getMessage());
283+
mPromise.reject(e);
290284
}
291285
}
292286

example/src/App.js

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ export default class SquareImageCropper extends React.Component<
6565
async _fetchRandomPhoto() {
6666
this.setState({
6767
randomPhoto: {
68-
uri: `http://placeimg.com/${DEFAULT_IMAGE_WIDTH}/${DEFAULT_IMAGE_HEIGHT}/tech`,
68+
uri: `http://placeimg.com/${DEFAULT_IMAGE_WIDTH}/${DEFAULT_IMAGE_HEIGHT}/tech?${new Date().getTime()}`,
6969
height: DEFAULT_IMAGE_HEIGHT,
7070
width: DEFAULT_IMAGE_WIDTH,
7171
},
@@ -150,13 +150,19 @@ export default class SquareImageCropper extends React.Component<
150150
);
151151
}
152152

153-
_crop() {
154-
ImageEditor.cropImage(
155-
this.state.randomPhoto.uri,
156-
this._transformData,
157-
croppedImageURI => this.setState({croppedImageURI}),
158-
cropError => this.setState({cropError}),
159-
);
153+
async _crop() {
154+
try {
155+
const croppedImageURI = await ImageEditor.cropImage(
156+
this.state.randomPhoto.uri,
157+
this._transformData,
158+
);
159+
160+
if (croppedImageURI) {
161+
this.setState({croppedImageURI});
162+
}
163+
} catch (cropError) {
164+
this.setState({cropError});
165+
}
160166
}
161167

162168
_reset() {

ios/RNCImageEditor.m

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,8 @@ @implementation RNCImageEditor
4242
*/
4343
RCT_EXPORT_METHOD(cropImage:(NSURLRequest *)imageRequest
4444
cropData:(NSDictionary *)cropData
45-
successCallback:(RCTResponseSenderBlock)successCallback
46-
errorCallback:(RCTResponseErrorBlock)errorCallback)
45+
resolve:(RCTPromiseResolveBlock)resolve
46+
reject:(RCTPromiseRejectBlock)reject)
4747
{
4848
CGRect rect = {
4949
[RCTConvert CGPoint:cropData[@"offset"]],
@@ -52,7 +52,7 @@ @implementation RNCImageEditor
5252

5353
[_bridge.imageLoader loadImageWithURLRequest:imageRequest callback:^(NSError *error, UIImage *image) {
5454
if (error) {
55-
errorCallback(error);
55+
reject(@(error.code).stringValue, error.description, error);
5656
return;
5757
}
5858

@@ -79,11 +79,11 @@ @implementation RNCImageEditor
7979
NSString *uri = [RNCImageUtils writeImage:imageData toPath:path error:&writeError];
8080

8181
if (writeError != nil) {
82-
errorCallback(writeError);
82+
reject(@(writeError.code).stringValue, writeError.description, writeError);
8383
return;
8484
}
8585

86-
successCallback(@[uri]);
86+
resolve(uri);
8787
}];
8888
}
8989

lib/ImageEditor.js

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -51,22 +51,17 @@ class ImageEditor {
5151
/**
5252
* Crop the image specified by the URI param. If URI points to a remote
5353
* image, it will be downloaded automatically. If the image cannot be
54-
* loaded/downloaded, the failure callback will be called. On Android, a
54+
* loaded/downloaded, the promise will be rejected. On Android, a
5555
* downloaded image may be cached in external storage, a publicly accessible
5656
* location, if it has more available space than internal storage.
5757
*
5858
* If the cropping process is successful, the resultant cropped image
59-
* will be stored in the ImageStore, and the URI returned in the success
60-
* callback will point to the image in the store. Remember to delete the
61-
* cropped image from the ImageStore when you are done with it.
59+
* will be stored in the Cache Path, and the URI returned in the promise
60+
* will point to the image in the cache path. Remember to delete the
61+
* cropped image from the cache path when you are done with it.
6262
*/
63-
static cropImage(
64-
uri: string,
65-
cropData: ImageCropData,
66-
success: (uri: string) => void,
67-
failure: (error: Object) => void,
68-
) {
69-
RNCImageEditor.cropImage(uri, cropData, success, failure);
63+
static cropImage(uri: string, cropData: ImageCropData): Promise<string> {
64+
return RNCImageEditor.cropImage(uri, cropData);
7065
}
7166
}
7267

typings/index.d.ts

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -35,21 +35,19 @@ declare class ImageEditor {
3535
/**
3636
* Crop the image specified by the URI param. If URI points to a remote
3737
* image, it will be downloaded automatically. If the image cannot be
38-
* loaded/downloaded, the failure callback will be called. On Android, a
38+
* loaded/downloaded, the promise will be rejected. On Android, a
3939
* downloaded image may be cached in external storage, a publicly accessible
4040
* location, if it has more available space than internal storage.
4141
*
4242
* If the cropping process is successful, the resultant cropped image
43-
* will be stored in the ImageStore, and the URI returned in the success
44-
* callback will point to the image in the store. Remember to delete the
45-
* cropped image from the ImageStore when you are done with it.
43+
* will be stored in the Cache Path, and the URI returned in the promise
44+
* will point to the image in the cache path. Remember to delete the
45+
* cropped image from the cache path when you are done with it.
4646
*/
4747
static cropImage: (
4848
uri: string,
4949
cropData: ImageCropData,
50-
success: (uri: string) => void,
51-
failure: (error: Object) => void,
52-
) => void
50+
) => Promise<string>
5351
}
5452

5553
export default ImageEditor

0 commit comments

Comments
 (0)