From 1d9d5296a6c68a977fafd20b605512a63d488a39 Mon Sep 17 00:00:00 2001 From: IjzerenHein Date: Wed, 28 Sep 2016 23:03:28 +0200 Subject: [PATCH 001/199] Added support for taking snapshots on Android # Conflicts: # android/src/main/java/com/airbnb/android/react/maps/AirMapModule.java --- .../android/react/maps/AirMapModule.java | 126 ++++++++++++++++++ .../android/react/maps/MapsPackage.java | 2 +- components/MapView.js | 35 ++++- 3 files changed, 160 insertions(+), 3 deletions(-) create mode 100644 android/src/main/java/com/airbnb/android/react/maps/AirMapModule.java diff --git a/android/src/main/java/com/airbnb/android/react/maps/AirMapModule.java b/android/src/main/java/com/airbnb/android/react/maps/AirMapModule.java new file mode 100644 index 000000000..b68ef3efd --- /dev/null +++ b/android/src/main/java/com/airbnb/android/react/maps/AirMapModule.java @@ -0,0 +1,126 @@ +package com.airbnb.android.react.maps; + +import android.app.Activity; +import android.util.DisplayMetrics; +import android.util.Base64; +import android.graphics.Bitmap; +import android.net.Uri; +import android.view.View; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.OutputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; + +import com.facebook.react.bridge.ReactApplicationContext; +import com.facebook.react.bridge.ReactContextBaseJavaModule; +import com.facebook.react.bridge.ReadableMap; +import com.facebook.react.bridge.Promise; +import com.facebook.react.bridge.ReactMethod; +import com.facebook.react.uimanager.UIManagerModule; +import com.facebook.react.uimanager.UIBlock; +import com.facebook.react.uimanager.NativeViewHierarchyManager; + +import com.google.android.gms.maps.GoogleMap; + + +public class AirMapModule extends ReactContextBaseJavaModule { + + public AirMapModule(ReactApplicationContext reactContext) { + super(reactContext); + } + + @Override + public String getName() { + return "AirMapModule"; + } + + public Activity getActivity() { + return getCurrentActivity(); + } + + @ReactMethod + public void takeSnapshot(final int tag, final ReadableMap options, final Promise promise) { + + // Parse and verity options + final ReactApplicationContext context = getReactApplicationContext(); + final String format = options.hasKey("format") ? options.getString("format") : "png"; + final Bitmap.CompressFormat compressFormat = + format.equals("png") ? Bitmap.CompressFormat.PNG : + format.equals("jpg") ? Bitmap.CompressFormat.JPEG : null; + if (compressFormat == null) { + promise.reject("AIRMap.takeSnapshot", "Unsupported image format: " + format + ". Try one of: png | jpg | jpeg"); + return; + } + final double quality = options.hasKey("quality") ? options.getDouble("quality") : 1.0; + final DisplayMetrics displayMetrics = context.getResources().getDisplayMetrics(); + final Integer width = options.hasKey("width") ? (int)(displayMetrics.density * options.getDouble("width")) : 0; + final Integer height = options.hasKey("height") ? (int)(displayMetrics.density * options.getDouble("height")) : 0; + final String result = options.hasKey("result") ? options.getString("result") : "file"; + + // Add UI-block so we can get a valid reference to the map-view + UIManagerModule uiManager = context.getNativeModule(UIManagerModule.class); + uiManager.addUIBlock(new UIBlock() { + public void execute (NativeViewHierarchyManager nvhm) { + AirMapView view = (AirMapView) nvhm.resolveView(tag); + if (view == null) { + promise.reject("AirMapView not found"); + return; + } + if (view.map == null) { + promise.reject("AirMapView.map is not valid"); + return; + } + view.map.snapshot(new GoogleMap.SnapshotReadyCallback() { + public void onSnapshotReady(Bitmap snapshot) { + + // Convert image to requested width/height if neccesary + if (snapshot != null && width != 0 && height != 0 && (width != snapshot.getWidth() || height != snapshot.getHeight())) { + snapshot = Bitmap.createScaledBitmap(snapshot, width, height, true); + } + if (snapshot == null) { + promise.reject("Failed to generate bitmap"); + return; + } + + // Save the snapshot to disk + OutputStream outputStream = null; + try { + if ("file".equals(result)) { + File tempFile = File.createTempFile("AirMapSnapshot", "." + format, context.getCacheDir()); + outputStream = new FileOutputStream(tempFile); + snapshot.compress(compressFormat, (int)(100.0 * quality), outputStream); + outputStream.close(); + outputStream = null; + String uri = Uri.fromFile(tempFile).toString(); + promise.resolve(uri); + } + else if ("base64".equals(result)) { + outputStream = new ByteArrayOutputStream(); + snapshot.compress(compressFormat, (int)(100.0 * quality), outputStream); + outputStream.close(); + outputStream = null; + byte[] bytes = ((ByteArrayOutputStream) outputStream).toByteArray(); + String data = Base64.encodeToString(bytes, Base64.NO_WRAP); + promise.resolve(data); + } + } + catch (Exception e) { + promise.reject(e); + } + finally { + if (outputStream != null) { + try { + outputStream.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + } + }); + } + }); + } +} diff --git a/android/src/main/java/com/airbnb/android/react/maps/MapsPackage.java b/android/src/main/java/com/airbnb/android/react/maps/MapsPackage.java index 5480c16ab..bc80cbcba 100644 --- a/android/src/main/java/com/airbnb/android/react/maps/MapsPackage.java +++ b/android/src/main/java/com/airbnb/android/react/maps/MapsPackage.java @@ -21,7 +21,7 @@ public MapsPackage() { @Override public List createNativeModules(ReactApplicationContext reactContext) { - return Collections.emptyList(); + return Arrays.asList(new AirMapModule(reactContext)); } @Override diff --git a/components/MapView.js b/components/MapView.js index 50683cd5a..7fe57fd40 100644 --- a/components/MapView.js +++ b/components/MapView.js @@ -446,8 +446,39 @@ class MapView extends React.Component { } takeSnapshot(width, height, region, callback) { - const finalRegion = region || this.props.region || this.props.initialRegion; - this._runCommand('takeSnapshot', [width, height, finalRegion, callback]); + return new Promise((resolve, reject) => { + let options; + if (typeof width === 'object') { + options = width; + } + else { + options = { + width: width, + height: height, + region: region || this.props.region || this.props.initialRegion + }; + } + if (Platform.OS === 'android') { + NativeModules.AirMapModule.takeSnapshot(this._getHandle(), options).then((snapshot) => { + if (callback) callback(undefined, {uri: snapshot}); + resolve(snapshot); + }, (err) => { + if (callback) callback(err); + reject(err); + }); + } + else { + this._runCommand('takeSnapshot', [options.width, options.height, options.region, (err, snapshot) => { + if (callback) callback(err, snapshot); + if (err) { + reject(err); + } + else { + resolve(snapshot.uri); + } + }]); + } + }); } _uiManagerCommand(name) { From 38ce6d5c37fdae7b3e4cd971624af3d61a7f3ff8 Mon Sep 17 00:00:00 2001 From: IjzerenHein Date: Wed, 28 Sep 2016 23:28:12 +0200 Subject: [PATCH 002/199] Fixed eslint errors in MapView.js --- components/MapView.js | 40 +++++++++++++++++++++++----------------- 1 file changed, 23 insertions(+), 17 deletions(-) diff --git a/components/MapView.js b/components/MapView.js index 7fe57fd40..b71c99a8c 100644 --- a/components/MapView.js +++ b/components/MapView.js @@ -450,33 +450,39 @@ class MapView extends React.Component { let options; if (typeof width === 'object') { options = width; - } - else { + } else { options = { - width: width, - height: height, - region: region || this.props.region || this.props.initialRegion + width, + height, + region: region || this.props.region || this.props.initialRegion, }; } if (Platform.OS === 'android') { NativeModules.AirMapModule.takeSnapshot(this._getHandle(), options).then((snapshot) => { - if (callback) callback(undefined, {uri: snapshot}); + if (callback) { + callback(undefined, { + uri: snapshot, + }); + } resolve(snapshot); }, (err) => { if (callback) callback(err); reject(err); }); - } - else { - this._runCommand('takeSnapshot', [options.width, options.height, options.region, (err, snapshot) => { - if (callback) callback(err, snapshot); - if (err) { - reject(err); - } - else { - resolve(snapshot.uri); - } - }]); + } else { + this._runCommand('takeSnapshot', [ + options.width, + options.height, + options.region, + (err, snapshot) => { + if (callback) callback(err, snapshot); + if (err) { + reject(err); + } else { + resolve(snapshot.uri); + } + }, + ]); } }); } From 3334e167e7990ac987dc717b904c8e227beb1c52 Mon Sep 17 00:00:00 2001 From: IjzerenHein Date: Sat, 1 Oct 2016 17:32:28 +0200 Subject: [PATCH 003/199] Added Const definition for snapshot result & format on Android --- .../android/react/maps/AirMapModule.java | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/android/src/main/java/com/airbnb/android/react/maps/AirMapModule.java b/android/src/main/java/com/airbnb/android/react/maps/AirMapModule.java index b68ef3efd..08566d997 100644 --- a/android/src/main/java/com/airbnb/android/react/maps/AirMapModule.java +++ b/android/src/main/java/com/airbnb/android/react/maps/AirMapModule.java @@ -24,9 +24,13 @@ import com.google.android.gms.maps.GoogleMap; - public class AirMapModule extends ReactContextBaseJavaModule { + private static final String SNAPSHOT_RESULT_FILE = "file"; + private static final String SNAPSHOT_RESULT_BASE64 = "base64"; + private static final String SNAPSHOT_FORMAT_PNG = "png"; + private static final String SNAPSHOT_FORMAT_JPG = "jpg"; + public AirMapModule(ReactApplicationContext reactContext) { super(reactContext); } @@ -47,12 +51,8 @@ public void takeSnapshot(final int tag, final ReadableMap options, final Promise final ReactApplicationContext context = getReactApplicationContext(); final String format = options.hasKey("format") ? options.getString("format") : "png"; final Bitmap.CompressFormat compressFormat = - format.equals("png") ? Bitmap.CompressFormat.PNG : - format.equals("jpg") ? Bitmap.CompressFormat.JPEG : null; - if (compressFormat == null) { - promise.reject("AIRMap.takeSnapshot", "Unsupported image format: " + format + ". Try one of: png | jpg | jpeg"); - return; - } + format.equals(SNAPSHOT_FORMAT_PNG) ? Bitmap.CompressFormat.PNG : + format.equals(SNAPSHOT_FORMAT_JPG) ? Bitmap.CompressFormat.JPEG : null; final double quality = options.hasKey("quality") ? options.getDouble("quality") : 1.0; final DisplayMetrics displayMetrics = context.getResources().getDisplayMetrics(); final Integer width = options.hasKey("width") ? (int)(displayMetrics.density * options.getDouble("width")) : 0; @@ -87,7 +87,7 @@ public void onSnapshotReady(Bitmap snapshot) { // Save the snapshot to disk OutputStream outputStream = null; try { - if ("file".equals(result)) { + if (result.equals(SNAPSHOT_RESULT_FILE)) { File tempFile = File.createTempFile("AirMapSnapshot", "." + format, context.getCacheDir()); outputStream = new FileOutputStream(tempFile); snapshot.compress(compressFormat, (int)(100.0 * quality), outputStream); @@ -96,7 +96,7 @@ public void onSnapshotReady(Bitmap snapshot) { String uri = Uri.fromFile(tempFile).toString(); promise.resolve(uri); } - else if ("base64".equals(result)) { + else if (result.equals(SNAPSHOT_RESULT_BASE64)) { outputStream = new ByteArrayOutputStream(); snapshot.compress(compressFormat, (int)(100.0 * quality), outputStream); outputStream.close(); From 8da7db7ce6abc399fa7efd38b4c0867a2ef609e7 Mon Sep 17 00:00:00 2001 From: IjzerenHein Date: Sat, 1 Oct 2016 17:33:37 +0200 Subject: [PATCH 004/199] Implemented new takeSnapshot API for iOS # Conflicts: # components/MapView.js # ios/AirMaps/AIRMapManager.m --- components/MapView.js | 97 +++++++++++++++++++++++++------------ ios/AirMaps/AIRMapManager.m | 76 +++++++++++++++++++++-------- 2 files changed, 122 insertions(+), 51 deletions(-) diff --git a/components/MapView.js b/components/MapView.js index b71c99a8c..ce82b7390 100644 --- a/components/MapView.js +++ b/components/MapView.js @@ -445,46 +445,79 @@ class MapView extends React.Component { this._runCommand('fitToCoordinates', [coordinates, edgePadding, animated]); } - takeSnapshot(width, height, region, callback) { - return new Promise((resolve, reject) => { - let options; - if (typeof width === 'object') { - options = width; - } else { - options = { - width, - height, - region: region || this.props.region || this.props.initialRegion, - }; - } - if (Platform.OS === 'android') { - NativeModules.AirMapModule.takeSnapshot(this._getHandle(), options).then((snapshot) => { - if (callback) { - callback(undefined, { - uri: snapshot, - }); - } - resolve(snapshot); - }, (err) => { - if (callback) callback(err); - reject(err); - }); - } else { + /** + * Takes a snapshot of the map and saves it to a picture + * file or returns the image as a base64 encoded string. + * + * @param config Configuration options + * @param [config.width] Width of the rendered map-view (when omitted actual view width is used). + * @param [config.height] Height of the rendered map-view (when omitted actual height is used). + * @param [config.region] Region to render (Only supported on iOS). + * @param [config.format] Encoding format ('png', 'jpg') (default: 'png'). + * @param [config.quality] Compression quality (only used for jpg) (default: 1.0). + * @param [config.result] Result format ('file', 'base64') (default: 'file'). + * + * @return Promise Promise with either the file-uri or base64 encoded string + */ + takeSnapshot(args) { + // For the time being we support the legacy API on iOS. + // This will be removed in a future release and only the + // new Promise style API shall be supported. + if (Platform.OS === 'ios' && (arguments.length === 4)) { + console.warn('Old takeSnapshot API has been deprecated; will be removed in the near future'); //eslint-disable-line + const width = arguments[0]; // eslint-disable-line + const height = arguments[1]; // eslint-disable-line + const region = arguments[2]; // eslint-disable-line + const callback = arguments[3]; // eslint-disable-line + this._runCommand('takeSnapshot', [ + width || 0, + height || 0, + region || {}, + 'png', + 1, + 'legacy', + callback, + ]); + return undefined; + } + + // Sanitize inputs + const config = { + width: args.width || 0, + height: args.height || 0, + region: args.region || {}, + format: args.format || 'png', + quality: args.quality || 1.0, + result: args.result || 'file', + }; + if ((config.format !== 'png') && + (config.format !== 'jpg')) throw new Error('Invalid format specified'); + if ((config.result !== 'file') && + (config.result !== 'base64')) throw new Error('Invalid result specified'); + + // Call native function + if (Platform.OS === 'android') { + return NativeModules.AirMapModule.takeSnapshot(this._getHandle(), config); + } else if (Platform.OS === 'ios') { + return new Promise((resolve, reject) => { this._runCommand('takeSnapshot', [ - options.width, - options.height, - options.region, + config.width, + config.height, + config.region, + config.format, + config.quality, + config.result, (err, snapshot) => { - if (callback) callback(err, snapshot); if (err) { reject(err); } else { - resolve(snapshot.uri); + resolve(snapshot); } }, ]); - } - }); + }); + } + return Promise.reject('takeSnapshot not supported on this platform'); } _uiManagerCommand(name) { diff --git a/ios/AirMaps/AIRMapManager.m b/ios/AirMaps/AIRMapManager.m index c45711c3f..58cd31574 100644 --- a/ios/AirMaps/AIRMapManager.m +++ b/ios/AirMaps/AIRMapManager.m @@ -221,10 +221,13 @@ - (UIView *)view } RCT_EXPORT_METHOD(takeSnapshot:(nonnull NSNumber *)reactTag - withWidth:(nonnull NSNumber *)width - withHeight:(nonnull NSNumber *)height - withRegion:(MKCoordinateRegion)region - withCallback:(RCTResponseSenderBlock)callback) + width:(nonnull NSNumber *)width + height:(nonnull NSNumber *)height + region:(MKCoordinateRegion)region + format:(nonnull NSString *)format + quality:(nonnull NSNumber *)quality + result:(nonnull NSString *)result + callback:(RCTResponseSenderBlock)callback) { [self.bridge.uiManager addUIBlock:^(__unused RCTUIManager *uiManager, NSDictionary *viewRegistry) { id view = viewRegistry[reactTag]; @@ -234,25 +237,34 @@ - (UIView *)view AIRMap *mapView = (AIRMap *)view; MKMapSnapshotOptions *options = [[MKMapSnapshotOptions alloc] init]; - options.region = region; - options.size = CGSizeMake([width floatValue], [height floatValue]); + options.region = (region.center.latitude && region.center.longitude) ? region : mapView.region; + options.size = CGSizeMake( + ([width floatValue] == 0) ? mapView.bounds.size.width : [width floatValue], + ([height floatValue] == 0) ? mapView.bounds.size.height : [height floatValue] + ); options.scale = [[UIScreen mainScreen] scale]; MKMapSnapshotter *snapshotter = [[MKMapSnapshotter alloc] initWithOptions:options]; - - [self takeMapSnapshot:mapView withSnapshotter:snapshotter withCallback:callback]; - + [self takeMapSnapshot:mapView + snapshotter:snapshotter + format:format + quality:quality.floatValue + result:result + callback:callback]; } }]; } #pragma mark Take Snapshot - (void)takeMapSnapshot:(AIRMap *)mapView - withSnapshotter:(MKMapSnapshotter *) snapshotter - withCallback:(RCTResponseSenderBlock) callback { + snapshotter:(MKMapSnapshotter *) snapshotter + format:(NSString *)format + quality:(CGFloat) quality + result:(NSString *)result + callback:(RCTResponseSenderBlock) callback { NSTimeInterval timeStamp = [[NSDate date] timeIntervalSince1970]; - NSString *pathComponent = [NSString stringWithFormat:@"Documents/snapshot-%.20lf.png", timeStamp]; + NSString *pathComponent = [NSString stringWithFormat:@"Documents/snapshot-%.20lf.%@", timeStamp, format]; NSString *filePath = [NSHomeDirectory() stringByAppendingPathComponent: pathComponent]; [snapshotter startWithQueue:dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0) @@ -294,13 +306,39 @@ - (void)takeMapSnapshot:(AIRMap *)mapView UIImage *compositeImage = UIGraphicsGetImageFromCurrentImageContext(); - NSData *data = UIImagePNGRepresentation(compositeImage); - [data writeToFile:filePath atomically:YES]; - NSDictionary *snapshotData = @{ - @"uri": filePath, - @"data": [data base64EncodedStringWithOptions:NSDataBase64EncodingEndLineWithCarriageReturn] - }; - callback(@[[NSNull null], snapshotData]); + NSData *data; + if ([format isEqualToString:@"png"]) { + data = UIImagePNGRepresentation(compositeImage); + } + else if([format isEqualToString:@"jpg"]) { + data = UIImageJPEGRepresentation(compositeImage, quality); + } + + if ([result isEqualToString:@"file"]) { + [data writeToFile:filePath atomically:YES]; + callback(@[[NSNull null], filePath]); + } + else if ([result isEqualToString:@"base64"]) { + callback(@[[NSNull null], [data base64EncodedStringWithOptions:NSDataBase64EncodingEndLineWithCarriageReturn]]); + } + else if ([result isEqualToString:@"legacy"]) { + + // In the initial (iOS only) implementation of takeSnapshot, + // both the uri and the base64 encoded string were returned. + // Returning both is rarely useful and in fact causes a + // performance penalty when only the file URI is desired. + // In that case the base64 encoded string was always marshalled + // over the JS-bridge (which is quite slow). + // A new more flexible API was created to cover this. + // This code should be removed in a future release when the + // old API is fully deprecated. + [data writeToFile:filePath atomically:YES]; + NSDictionary *snapshotData = @{ + @"uri": filePath, + @"data": [data base64EncodedStringWithOptions:NSDataBase64EncodingEndLineWithCarriageReturn] + }; + callback(@[[NSNull null], snapshotData]); + } } UIGraphicsEndImageContext(); }]; From fe61cd179cee2958f64ba48bbebf418142c0ad9e Mon Sep 17 00:00:00 2001 From: IjzerenHein Date: Sat, 1 Oct 2016 17:34:03 +0200 Subject: [PATCH 005/199] Updated README with new Snapshot API --- README.md | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index db9a4dffa..57994b7e8 100644 --- a/README.md +++ b/README.md @@ -328,7 +328,6 @@ render() { ``` ### Take Snapshot of map -currently only for ios, android implementation WIP ```jsx getInitialState() { @@ -341,11 +340,19 @@ getInitialState() { } takeSnapshot () { - // arguments to 'takeSnapshot' are width, height, coordinates and callback - this.refs.map.takeSnapshot(300, 300, this.state.coordinate, (err, snapshot) => { - // snapshot contains image 'uri' - full path to image and 'data' - base64 encoded image - this.setState({ mapSnapshot: snapshot }) - }) + // 'takeSnapshot' takes a config object with the + // following options + const snapshot = this.refs.map.takeSnapshot({ + width: 300, // optional, when omitted the view-width is used + height: 300, // optional, when omitted the view-height is used + region: {..}, // iOS only, optional region to render + format: 'png', // image formats: 'png', 'jpg' (default: 'png') + quality: 0.8, // image quality: 0..1 (only relevant for jpg, default: 1) + result: 'file' // result types: 'file', 'base64' (default: 'file') + }); + snapshot.then((uri) => { + this.setState({ mapSnapshot: uri }); + }); } render() { From b12503c553b746fcf882de8af044769dd0adb8cb Mon Sep 17 00:00:00 2001 From: IjzerenHein Date: Tue, 1 Nov 2016 14:59:23 +0100 Subject: [PATCH 006/199] Improved code for takeSnapshot function (based on airbnb feedback) --- .../android/react/maps/AirMapModule.java | 68 ++++++++++--------- 1 file changed, 35 insertions(+), 33 deletions(-) diff --git a/android/src/main/java/com/airbnb/android/react/maps/AirMapModule.java b/android/src/main/java/com/airbnb/android/react/maps/AirMapModule.java index 08566d997..2cd1ba686 100644 --- a/android/src/main/java/com/airbnb/android/react/maps/AirMapModule.java +++ b/android/src/main/java/com/airbnb/android/react/maps/AirMapModule.java @@ -12,6 +12,9 @@ import java.io.OutputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; +import java.io.Closeable; + +import javax.annotation.Nullable; import com.facebook.react.bridge.ReactApplicationContext; import com.facebook.react.bridge.ReactContextBaseJavaModule; @@ -44,6 +47,14 @@ public Activity getActivity() { return getCurrentActivity(); } + public static void closeQuietly(Closeable closeable) { + if (closeable == null) return; + try { + closeable.close(); + } catch (IOException ignored) { + } + } + @ReactMethod public void takeSnapshot(final int tag, final ReadableMap options, final Promise promise) { @@ -73,50 +84,41 @@ public void execute (NativeViewHierarchyManager nvhm) { return; } view.map.snapshot(new GoogleMap.SnapshotReadyCallback() { - public void onSnapshotReady(Bitmap snapshot) { + public void onSnapshotReady(@Nullable Bitmap snapshot) { // Convert image to requested width/height if neccesary - if (snapshot != null && width != 0 && height != 0 && (width != snapshot.getWidth() || height != snapshot.getHeight())) { - snapshot = Bitmap.createScaledBitmap(snapshot, width, height, true); - } if (snapshot == null) { - promise.reject("Failed to generate bitmap"); + promise.reject("Failed to generate bitmap, snapshot = null"); return; } + if ((width != 0) && (height != 0) && (width != snapshot.getWidth() || height != snapshot.getHeight())) { + snapshot = Bitmap.createScaledBitmap(snapshot, width, height, true); + } // Save the snapshot to disk - OutputStream outputStream = null; - try { - if (result.equals(SNAPSHOT_RESULT_FILE)) { - File tempFile = File.createTempFile("AirMapSnapshot", "." + format, context.getCacheDir()); + if (result.equals(SNAPSHOT_RESULT_FILE)) { + File tempFile; + FileOutputStream outputStream; + try { + tempFile = File.createTempFile("AirMapSnapshot", "." + format, context.getCacheDir()); outputStream = new FileOutputStream(tempFile); - snapshot.compress(compressFormat, (int)(100.0 * quality), outputStream); - outputStream.close(); - outputStream = null; - String uri = Uri.fromFile(tempFile).toString(); - promise.resolve(uri); } - else if (result.equals(SNAPSHOT_RESULT_BASE64)) { - outputStream = new ByteArrayOutputStream(); - snapshot.compress(compressFormat, (int)(100.0 * quality), outputStream); - outputStream.close(); - outputStream = null; - byte[] bytes = ((ByteArrayOutputStream) outputStream).toByteArray(); - String data = Base64.encodeToString(bytes, Base64.NO_WRAP); - promise.resolve(data); + catch (Exception e) { + promise.reject(e); + return; } + snapshot.compress(compressFormat, (int)(100.0 * quality), outputStream); + closeQuietly(outputStream); + String uri = Uri.fromFile(tempFile).toString(); + promise.resolve(uri); } - catch (Exception e) { - promise.reject(e); - } - finally { - if (outputStream != null) { - try { - outputStream.close(); - } catch (IOException e) { - e.printStackTrace(); - } - } + else if (result.equals(SNAPSHOT_RESULT_BASE64)) { + ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + snapshot.compress(compressFormat, (int)(100.0 * quality), outputStream); + closeQuietly(outputStream); + byte[] bytes = outputStream.toByteArray(); + String data = Base64.encodeToString(bytes, Base64.NO_WRAP); + promise.resolve(data); } } }); From fd2219fe101940bf999969e6601127a35f30cc1a Mon Sep 17 00:00:00 2001 From: Peter Pistorius Date: Tue, 29 Nov 2016 18:53:22 +0100 Subject: [PATCH 007/199] Added more help to the Podfile. (#838) --- example/ios/Podfile | 1 + 1 file changed, 1 insertion(+) diff --git a/example/ios/Podfile b/example/ios/Podfile index 085aad454..4da2704b9 100644 --- a/example/ios/Podfile +++ b/example/ios/Podfile @@ -8,6 +8,7 @@ source 'https://github.com/CocoaPods/Specs.git' platform :ios, '8.0' use_frameworks! +# Change 'AirMapsExplorer' to match the target in your Xcode project. target 'AirMapsExplorer' do pod 'React', path: '../node_modules/react-native', :subspecs => [ 'Core', From f1b478bcd87686eead01809d17a1443dc37f384f Mon Sep 17 00:00:00 2001 From: Gilles Date: Wed, 30 Nov 2016 15:10:22 -0800 Subject: [PATCH 008/199] Add support for polygon holes for Apple Maps and Google Maps on iOS (#801) * Add support for polygon holes for Apple Maps and Google Maps on iOS * Add PropTypes for polygon holes * Add support for polygon holes in Polygon Creator example --- components/MapPolygon.js | 11 ++++ example/examples/PolygonCreator.js | 62 ++++++++++++++++++- ios/AirGoogleMaps/AIRGoogleMapPolygon.h | 1 + ios/AirGoogleMaps/AIRGoogleMapPolygon.m | 21 +++++++ .../AIRGoogleMapPolygonManager.m | 1 + ios/AirMaps/AIRMapPolygon.h | 4 +- ios/AirMaps/AIRMapPolygon.m | 22 ++++++- ios/AirMaps/AIRMapPolygonManager.m | 1 + ios/AirMaps/RCTConvert+MoreMapKit.m | 7 ++- 9 files changed, 124 insertions(+), 6 deletions(-) diff --git a/components/MapPolygon.js b/components/MapPolygon.js index d04b7e0e3..38c972e0c 100644 --- a/components/MapPolygon.js +++ b/components/MapPolygon.js @@ -21,6 +21,17 @@ const propTypes = { longitude: PropTypes.number.isRequired, })), + /** + * An array of array of coordinates to describe the polygon holes + */ + holes: PropTypes.arrayOf(PropTypes.arrayOf(PropTypes.shape({ + /** + * Latitude/Longitude coordinates + */ + latitude: PropTypes.number.isRequired, + longitude: PropTypes.number.isRequired, + }))), + /** * Callback that is called when the user presses on the polygon */ diff --git a/example/examples/PolygonCreator.js b/example/examples/PolygonCreator.js index 99b02809e..c0d1e44f5 100644 --- a/example/examples/PolygonCreator.js +++ b/example/examples/PolygonCreator.js @@ -31,6 +31,7 @@ class PolygonCreator extends React.Component { }, polygons: [], editing: null, + creatingHole: false, }; } @@ -39,19 +40,49 @@ class PolygonCreator extends React.Component { this.setState({ polygons: [...polygons, editing], editing: null, + creatingHole: false, }); } + createHole() { + const { editing, creatingHole } = this.state; + if (!creatingHole) { + this.setState({ + creatingHole: true, + editing: { + ...editing, + holes: [ + ...editing.holes, + [], + ], + }, + }); + } else { + const holes = [...editing.holes]; + if (holes[holes.length - 1].length === 0) { + holes.pop(); + this.setState({ + editing: { + ...editing, + holes, + }, + }); + } + this.setState({ creatingHole: false }); + } + } + onPress(e) { - const { editing } = this.state; + const { editing, creatingHole } = this.state; if (!editing) { this.setState({ editing: { id: id++, coordinates: [e.nativeEvent.coordinate], + holes: [], }, }); - } else { + } else if (!creatingHole) { this.setState({ editing: { ...editing, @@ -61,6 +92,22 @@ class PolygonCreator extends React.Component { ], }, }); + } else { + const holes = [...editing.holes]; + holes[holes.length - 1] = [ + ...holes[holes.length - 1], + e.nativeEvent.coordinate, + ]; + this.setState({ + editing: { + ...editing, + id: id++, // keep incrementing id to trigger display refresh + coordinates: [ + ...editing.coordinates, + ], + holes, + }, + }); } } @@ -88,6 +135,7 @@ class PolygonCreator extends React.Component { + {this.state.editing && ( + this.createHole()} + style={[styles.bubble, styles.button]} + > + {this.state.creatingHole ? 'Finish Hole' : 'Create Hole'} + + )} {this.state.editing && ( this.finish()} diff --git a/ios/AirGoogleMaps/AIRGoogleMapPolygon.h b/ios/AirGoogleMaps/AIRGoogleMapPolygon.h index 26f0236d8..12a207128 100644 --- a/ios/AirGoogleMaps/AIRGoogleMapPolygon.h +++ b/ios/AirGoogleMaps/AIRGoogleMapPolygon.h @@ -11,6 +11,7 @@ @property (nonatomic, strong) GMSPolygon *polygon; @property (nonatomic, strong) NSArray *coordinates; +@property (nonatomic, strong) NSArray *> *holes; @property (nonatomic, assign) UIColor *fillColor; @property (nonatomic, assign) double strokeWidth; diff --git a/ios/AirGoogleMaps/AIRGoogleMapPolygon.m b/ios/AirGoogleMaps/AIRGoogleMapPolygon.m index 8727cad37..ea31b5008 100644 --- a/ios/AirGoogleMaps/AIRGoogleMapPolygon.m +++ b/ios/AirGoogleMaps/AIRGoogleMapPolygon.m @@ -31,6 +31,27 @@ - (void)setCoordinates:(NSArray *)coordinates _polygon.path = path; } +- (void)setHoles:(NSArray *> *)holes +{ + _holes = holes; + + if (holes.count) + { + NSMutableArray *interiorPolygons = [NSMutableArray array]; + for(int h = 0; h < holes.count; h++) + { + GMSMutablePath *path = [GMSMutablePath path]; + for(int i = 0; i < holes[h].count; i++) + { + [path addCoordinate:holes[h][i].coordinate]; + } + [interiorPolygons addObject:path]; + } + + _polygon.holes = interiorPolygons; + } +} + -(void)setFillColor:(UIColor *)fillColor { _fillColor = fillColor; diff --git a/ios/AirGoogleMaps/AIRGoogleMapPolygonManager.m b/ios/AirGoogleMaps/AIRGoogleMapPolygonManager.m index 5e6c8d319..383bb6527 100644 --- a/ios/AirGoogleMaps/AIRGoogleMapPolygonManager.m +++ b/ios/AirGoogleMaps/AIRGoogleMapPolygonManager.m @@ -29,6 +29,7 @@ - (UIView *)view } RCT_EXPORT_VIEW_PROPERTY(coordinates, AIRMapCoordinateArray) +RCT_EXPORT_VIEW_PROPERTY(holes, AIRMapCoordinateArrayArray) RCT_EXPORT_VIEW_PROPERTY(fillColor, UIColor) RCT_EXPORT_VIEW_PROPERTY(strokeWidth, double) RCT_EXPORT_VIEW_PROPERTY(strokeColor, UIColor) diff --git a/ios/AirMaps/AIRMapPolygon.h b/ios/AirMaps/AIRMapPolygon.h index 7c471b04c..d028e67fb 100644 --- a/ios/AirMaps/AIRMapPolygon.h +++ b/ios/AirMaps/AIRMapPolygon.h @@ -22,8 +22,10 @@ @property (nonatomic, strong) MKPolygon *polygon; @property (nonatomic, strong) MKPolygonRenderer *renderer; +@property (nonatomic, strong) NSArray *interiorPolygons; @property (nonatomic, strong) NSArray *coordinates; +@property (nonatomic, strong) NSArray *> *holes; @property (nonatomic, strong) UIColor *fillColor; @property (nonatomic, strong) UIColor *strokeColor; @property (nonatomic, assign) CGFloat strokeWidth; @@ -41,4 +43,4 @@ - (BOOL)intersectsMapRect:(MKMapRect)mapRect; - (BOOL)canReplaceMapContent; -@end \ No newline at end of file +@end diff --git a/ios/AirMaps/AIRMapPolygon.m b/ios/AirMaps/AIRMapPolygon.m index e3784cf26..3ee378d0f 100644 --- a/ios/AirMaps/AIRMapPolygon.m +++ b/ios/AirMaps/AIRMapPolygon.m @@ -58,13 +58,31 @@ - (void)setCoordinates:(NSArray *)coordinates { { coords[i] = coordinates[i].coordinate; } - self.polygon = [MKPolygon polygonWithCoordinates:coords count:coordinates.count]; + self.polygon = [MKPolygon polygonWithCoordinates:coords count:coordinates.count interiorPolygons:_interiorPolygons]; // TODO: we could lazy-initialize the polygon, since we don't need it until the // polygon is in view. self.renderer = [[MKPolygonRenderer alloc] initWithPolygon:self.polygon]; [self update]; } +- (void)setHoles:(NSArray *> *)holes { + _holes = holes; + if (holes.count) + { + NSMutableArray *polygons = [NSMutableArray array]; + for(int h = 0; h < holes.count; h++) + { + CLLocationCoordinate2D coords[holes[h].count]; + for(int i = 0; i < holes[h].count; i++) + { + coords[i] = holes[h][i].coordinate; + } + [polygons addObject:[MKPolygon polygonWithCoordinates:coords count:holes[h].count]]; + } + _interiorPolygons = polygons; + } +} + - (void) update { if (!_renderer) return; @@ -157,4 +175,4 @@ - (BOOL)canReplaceMapContent -@end \ No newline at end of file +@end diff --git a/ios/AirMaps/AIRMapPolygonManager.m b/ios/AirMaps/AIRMapPolygonManager.m index bfc253f6c..1299dee12 100644 --- a/ios/AirMaps/AIRMapPolygonManager.m +++ b/ios/AirMaps/AIRMapPolygonManager.m @@ -34,6 +34,7 @@ - (UIView *)view } RCT_EXPORT_VIEW_PROPERTY(coordinates, AIRMapCoordinateArray) +RCT_EXPORT_VIEW_PROPERTY(holes, AIRMapCoordinateArrayArray) RCT_EXPORT_VIEW_PROPERTY(fillColor, UIColor) RCT_EXPORT_VIEW_PROPERTY(strokeColor, UIColor) RCT_EXPORT_VIEW_PROPERTY(strokeWidth, CGFloat) diff --git a/ios/AirMaps/RCTConvert+MoreMapKit.m b/ios/AirMaps/RCTConvert+MoreMapKit.m index 2292cb878..9f18553d1 100644 --- a/ios/AirMaps/RCTConvert+MoreMapKit.m +++ b/ios/AirMaps/RCTConvert+MoreMapKit.m @@ -24,4 +24,9 @@ + (AIRMapCoordinate *)AIRMapCoordinate:(id)json RCT_ARRAY_CONVERTER(AIRMapCoordinate) -@end \ No newline at end of file ++ (NSArray *> *)AIRMapCoordinateArrayArray:(id)json +{ + return RCTConvertArrayValue(@selector(AIRMapCoordinateArray:), json); +} + +@end From a39f1b2c84b47639c491207582a1d5fba1f99350 Mon Sep 17 00:00:00 2001 From: Sascha Knobloch Date: Tue, 6 Dec 2016 11:26:55 +0100 Subject: [PATCH 009/199] Update mapview.md (#855) --- docs/mapview.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/mapview.md b/docs/mapview.md index 3b11e6273..50d1ac4cb 100644 --- a/docs/mapview.md +++ b/docs/mapview.md @@ -27,7 +27,7 @@ | `loadingEnabled` | `Boolean` | `false` | If `true` a loading indicator will show while the map is loading. | `loadingIndicatorColor` | `Color` | `#606060` | Sets loading indicator color, default to `#606060`. | `loadingBackgroundColor` | `Color` | `#FFFFFF` | Sets loading background color, default to `#FFFFFF`. - +| `moveOnMarkerPress` | `Boolean` | `true` | `Android only` If `false` the map won't move when a marker is pressed. ## Events From 792406d93bb46ab9f85dfb8bf0d3130d5d0bd0b5 Mon Sep 17 00:00:00 2001 From: Kovacs Nicolas Date: Tue, 6 Dec 2016 11:27:36 +0100 Subject: [PATCH 010/199] Update installation (#847) Help fixing issue blank map on android --- docs/installation.md | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/docs/installation.md b/docs/installation.md index c14995999..71fccd75b 100644 --- a/docs/installation.md +++ b/docs/installation.md @@ -109,7 +109,7 @@ Source: https://developers.google.com/maps/documentation/android-api/signup ## Troubleshooting -If you have a blank map issue, ([#118](https://github.com/airbnb/react-native-maps/issues/118), [#176](https://github.com/airbnb/react-native-maps/issues/176)) try the following lines : +If you have a blank map issue, ([#118](https://github.com/airbnb/react-native-maps/issues/118), [#176](https://github.com/airbnb/react-native-maps/issues/176), [#684](https://github.com/airbnb/react-native-maps/issues/684)), try the following lines : ### On iOS: @@ -120,6 +120,19 @@ You have to link dependencies with rnpm and re-run the build: ### On Android: +1. Be sure to have `new MapsPackage()` in your `MainApplication.java` : + ``` + import com.airbnb.android.react.maps.MapsPackage; + ... + @Override + protected List getPackages() { + return Arrays.asList( + new MainReactPackage(), + new MapsPackage() + ); + } + ``` + 1. Set this Stylesheet in your map component ``` ... From 8e7f854e939a2be5488dc01489e25234b86d4ae3 Mon Sep 17 00:00:00 2001 From: Seph Soliman Date: Tue, 6 Dec 2016 20:44:52 +0100 Subject: [PATCH 011/199] Fixes #470. Support legalLabelInsets on Apple Maps (#840) * Fixes #470 for iOS and Apple Maps This will add support for `legalLabelInsets` prop on iOS with Apple Maps. Code is adapted from RN core. * Pluralize updateLegalLabelInset(s) for consistency * Removed arrow notation * Added legalLabelInsets example --- example/App.js | 2 + example/examples/LegalLabel.js | 113 +++++++++++++++++++++++++++++++++ ios/AirMaps/AIRMap.m | 20 ++++++ 3 files changed, 135 insertions(+) create mode 100644 example/examples/LegalLabel.js diff --git a/example/App.js b/example/App.js index abd02acd2..696682ba0 100644 --- a/example/App.js +++ b/example/App.js @@ -32,6 +32,7 @@ import CustomTiles from './examples/CustomTiles'; import ZIndexMarkers from './examples/ZIndexMarkers'; import StaticMap from './examples/StaticMap'; import MapStyle from './examples/MapStyle'; +import LegalLabel from './examples/LegalLabel'; const IOS = Platform.OS === 'ios'; const ANDROID = Platform.OS === 'android'; @@ -142,6 +143,7 @@ class App extends React.Component { [CustomTiles, 'Custom Tiles', true], [ZIndexMarkers, 'Position Markers with Z-index', true], [MapStyle, 'Customize the style of the map', true], + [LegalLabel, 'Reposition the legal label', true], ] // Filter out examples that are not yet supported for Google Maps on iOS. .filter(example => ANDROID || (IOS && (example[2] || !this.state.useGoogleMaps))) diff --git a/example/examples/LegalLabel.js b/example/examples/LegalLabel.js new file mode 100644 index 000000000..7715648f7 --- /dev/null +++ b/example/examples/LegalLabel.js @@ -0,0 +1,113 @@ +import React from 'react'; +import { + StyleSheet, + View, + Text, + Dimensions, +} from 'react-native'; + +import MapView from 'react-native-maps'; + +const screen = Dimensions.get('window'); + +class LegalLabel extends React.Component { + static propTypes = { + provider: MapView.ProviderPropType, + } + + render() { + const latlng = { + latitude: 37.78825, + longitude: -122.4324, + }; + + const ASPECT_RATIO = screen.width / screen.height; + const LATITUDE_DELTA = 0.0922; + const LONGITUDE_DELTA = LATITUDE_DELTA * ASPECT_RATIO; + + return ( + + + + + + + Username + + + + + Bio description lorem ipsum Ullamco exercitation + aliqua ullamco nostrud dolor et aliquip fugiat do + aute fugiat velit in aliqua sit. + + + + + + + Profile Photo + + + + + ); + } +} + +const padding = 10; +const photoSize = 80; +const mapHeight = screen.height - 130; +const styles = StyleSheet.create({ + bio: { + marginHorizontal: padding, + marginBottom: 0, + paddingVertical: padding / 2, + }, + bioText: { + fontSize: 16, + lineHeight: 16 * 1.5, + }, + username: { + paddingLeft: photoSize + padding + padding, + paddingTop: padding, + }, + usernameText: { + fontSize: 36, + lineHeight: 36, + }, + photo: { + padding: 2, + position: 'absolute', + top: mapHeight - (photoSize / 2), + left: padding, + borderRadius: 5, + borderWidth: StyleSheet.hairlineWidth, + backgroundColor: '#ccc', + width: photoSize, + height: photoSize, + }, + photoInner: { + alignItems: 'center', + justifyContent: 'center', + flex: 1, + }, + photoText: { + fontSize: 9, + textAlign: 'center', + }, + map: { + height: mapHeight, + }, +}); + +module.exports = LegalLabel; diff --git a/ios/AirMaps/AIRMap.m b/ios/AirMaps/AIRMap.m index 9efe1b4aa..9683bfd3a 100644 --- a/ios/AirMaps/AIRMap.m +++ b/ios/AirMaps/AIRMap.m @@ -381,6 +381,26 @@ - (void)cacheViewIfNeeded { [self updateScrollEnabled]; [self updateZoomEnabled]; + [self updateLegalLabelInsets]; + } +} + +- (void)updateLegalLabelInsets { + if (_legalLabel) { + dispatch_async(dispatch_get_main_queue(), ^{ + CGRect frame = _legalLabel.frame; + if (_legalLabelInsets.left) { + frame.origin.x = _legalLabelInsets.left; + } else if (_legalLabelInsets.right) { + frame.origin.x = self.frame.size.width - _legalLabelInsets.right - frame.size.width; + } + if (_legalLabelInsets.top) { + frame.origin.y = _legalLabelInsets.top; + } else if (_legalLabelInsets.bottom) { + frame.origin.y = self.frame.size.height - _legalLabelInsets.bottom - frame.size.height; + } + _legalLabel.frame = frame; + }); } } From e0e61ad0ca1ea392d1129825201fce43c50a7a1e Mon Sep 17 00:00:00 2001 From: gilbox Date: Tue, 6 Dec 2016 13:34:18 -0800 Subject: [PATCH 012/199] 0.12.0 --- CHANGELOG.md | 68 ++++++++++++++++++++++++++++++++ android/gradle.properties | 2 +- react-native-google-maps.podspec | 2 +- react-native-maps.podspec | 2 +- 4 files changed, 71 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 763902cc6..e3676445e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,7 +1,75 @@ # Change Log +## 0.12.0 (December 6, 2016) + +### Breaking Changes + +* [android] If we've disabled scrolling within the map, then don't capture the touch events + [#664](https://github.com/airbnb/react-native-maps/pull/664) + (@mikelambert) +* [android] Use latest Google Play Services + [#731](https://github.com/airbnb/react-native-maps/pull/731) + (@mlanter) +* [android] update google play services + [#805](https://github.com/airbnb/react-native-maps/pull/805) + (@lrivera) + +### Patches + +* [iOS] Support iOS SDK < 10 ( XCode < 8 ) + [#708](https://github.com/airbnb/react-native-maps/pull/708) + (@rops) +* [iOS] Added showsUserLocation property support for Google Maps + [#721](https://github.com/airbnb/react-native-maps/pull/721) + (@julien-rodrigues) +* [iOS] Added Google Maps Circle, Polygon, Polyline, MapType Support + [#722](https://github.com/airbnb/react-native-maps/pull/722) + (@unboundfire) +* [iOS] Fix Anchor point on Google Maps iOS + [#734](https://github.com/airbnb/react-native-maps/pull/734) + (@btoueg) +* [Google Maps iOS] Marker init with image props. + [#738](https://github.com/airbnb/react-native-maps/pull/738) + (@btoueg) +* [iOS] Fix dynamic imageSrc removal + [#737](https://github.com/airbnb/react-native-maps/pull/737) + (@btoueg) +* [iOS] implement fitToSuppliedMarkers and fitToCoordinates for google + [#750](https://github.com/airbnb/react-native-maps/pull/750) + (@gilbox) +* [iOS][android] Add onPress for polygons and polylines on iOS and Android + [#760](https://github.com/airbnb/react-native-maps/pull/760) + (@frankrowe) +* [iOS] Fix flicker of map pins on state change + [#728](https://github.com/airbnb/react-native-maps/pull/728) + (@mlanter) +* [iOS] Set region only when view has width&height + [#785](https://github.com/airbnb/react-native-maps/pull/785) + (@gilbox) +* [iOS] Implements animateToRegion for Google + [#779](https://github.com/airbnb/react-native-maps/pull/779) + (@btoueg) +* [iOS] Google Maps Custom Tile Support + [#770](https://github.com/airbnb/react-native-maps/pull/770) + (@unboundfire) +* [android] Map Styling for android + [#808](https://github.com/airbnb/react-native-maps/pull/808) + (@ali-alamine using @azt3k code) +* [iOS] IOS Google Map styling + [#817](https://github.com/airbnb/react-native-maps/pull/817) + (@ali-alamine using @azt3k code) +* [iOS] Add support for polygon holes for Apple Maps and Google Maps on iOS + [#801](https://github.com/airbnb/react-native-maps/pull/801) + (@therealgilles) +* [iOS] Fixes #470. Support legalLabelInsets on Apple Maps + [#840](https://github.com/airbnb/react-native-maps/pull/840) + (@scarlac) + ## 0.11.0 (October 16, 2016) +NOTE: `0.10.4` was released *after* this version, and it's possible +`0.11.0` does not include everything in `0.10.4`. (see #851) + ### Breaking Changes * Update example app for RN 0.35, fix Gmaps bug for 0.35 diff --git a/android/gradle.properties b/android/gradle.properties index ff024eb51..a6d6c4f56 100644 --- a/android/gradle.properties +++ b/android/gradle.properties @@ -1,5 +1,5 @@ VERSION_CODE=2 -VERSION_NAME=0.11.0 +VERSION_NAME=0.12.0 GROUP=com.airbnb.android POM_DESCRIPTION=React Native Map view component for Android diff --git a/react-native-google-maps.podspec b/react-native-google-maps.podspec index e306422cd..0ed52b808 100644 --- a/react-native-google-maps.podspec +++ b/react-native-google-maps.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = "react-native-google-maps" - s.version = "0.11.0" + s.version = "0.12.0" s.summary = "React Native Mapview component for iOS + Android" s.authors = { "intelligibabble" => "leland.m.richardson@gmail.com" } diff --git a/react-native-maps.podspec b/react-native-maps.podspec index 73607d2b0..df7164453 100644 --- a/react-native-maps.podspec +++ b/react-native-maps.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = "react-native-maps" - s.version = "0.11.0" + s.version = "0.12.0" s.summary = "React Native Mapview component for iOS + Android" s.authors = { "intelligibabble" => "leland.m.richardson@gmail.com" } From 0f05de9cc355e9e2702a29c2d10adda11400c07d Mon Sep 17 00:00:00 2001 From: gilbox Date: Tue, 6 Dec 2016 13:39:20 -0800 Subject: [PATCH 013/199] 0.12.1 --- CHANGELOG.md | 6 ++++++ android/gradle.properties | 2 +- package.json | 2 +- react-native-google-maps.podspec | 2 +- react-native-maps.podspec | 2 +- 5 files changed, 10 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e3676445e..6e9de4544 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,7 +1,13 @@ # Change Log +## 0.12.1 (December 6, 2016) + +This release only corrects the version in package.json. + ## 0.12.0 (December 6, 2016) +NOTE: This version was not published because package.json was not properly updated + ### Breaking Changes * [android] If we've disabled scrolling within the map, then don't capture the touch events diff --git a/android/gradle.properties b/android/gradle.properties index a6d6c4f56..2423c0458 100644 --- a/android/gradle.properties +++ b/android/gradle.properties @@ -1,5 +1,5 @@ VERSION_CODE=2 -VERSION_NAME=0.12.0 +VERSION_NAME=0.12.1 GROUP=com.airbnb.android POM_DESCRIPTION=React Native Map view component for Android diff --git a/package.json b/package.json index e611648f0..3967b5b80 100644 --- a/package.json +++ b/package.json @@ -3,7 +3,7 @@ "description": "React Native Mapview component for iOS + Android", "main": "index.js", "author": "Leland Richardson ", - "version": "0.11.0", + "version": "0.12.1", "scripts": { "start": "react-native start", "lint": "eslint ." diff --git a/react-native-google-maps.podspec b/react-native-google-maps.podspec index 0ed52b808..3e4ff9756 100644 --- a/react-native-google-maps.podspec +++ b/react-native-google-maps.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = "react-native-google-maps" - s.version = "0.12.0" + s.version = "0.12.1" s.summary = "React Native Mapview component for iOS + Android" s.authors = { "intelligibabble" => "leland.m.richardson@gmail.com" } diff --git a/react-native-maps.podspec b/react-native-maps.podspec index df7164453..ef9df382c 100644 --- a/react-native-maps.podspec +++ b/react-native-maps.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = "react-native-maps" - s.version = "0.12.0" + s.version = "0.12.1" s.summary = "React Native Mapview component for iOS + Android" s.authors = { "intelligibabble" => "leland.m.richardson@gmail.com" } From 6eb18321523b40fc652c3993475115432e500eb2 Mon Sep 17 00:00:00 2001 From: Diogo do Carmo Date: Wed, 7 Dec 2016 19:39:58 -0200 Subject: [PATCH 014/199] Update mapview.md (#866) * Update mapview.md Updated documentation to match the example here (https://github.com/airbnb/react-native-maps/blob/master/example/examples/FitToCoordinates.js) * Changed name from 'arguments' to 'options' --- docs/mapview.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/mapview.md b/docs/mapview.md index 50d1ac4cb..a10fbe58d 100644 --- a/docs/mapview.md +++ b/docs/mapview.md @@ -57,7 +57,7 @@ | `animateToCoordinate` | `region: Coordinate`, `duration: Number` | | `fitToElements` | `animated: Boolean` | | `fitToSuppliedMarkers` | `markerIDs: String[]` | If you need to use this in `ComponentDidMount`, make sure you put it in a timeout or it will cause performance problems. -| `fitToCoordinates` | `coordinates: Array, edgePadding: EdgePadding, animated: Boolean` | +| `fitToCoordinates` | `coordinates: Array, options: { edgePadding: EdgePadding, animated: Boolean }` | From 8d654fba132e7c0cf7018f6ae7206eb2540470af Mon Sep 17 00:00:00 2001 From: Arman Date: Fri, 9 Dec 2016 00:56:23 +0330 Subject: [PATCH 015/199] Added rotation attribute (#871) --- docs/marker.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/marker.md b/docs/marker.md index 60da4c0f7..dee0e019d 100644 --- a/docs/marker.md +++ b/docs/marker.md @@ -15,6 +15,7 @@ | `calloutAnchor` | `Point` | | Specifies the point in the marker image at which to anchor the callout when it is displayed. This is specified in the same coordinate system as the anchor. See the `anchor` prop for more details.

The default is the top middle of the image.

For ios, see the `calloutOffset` prop. | `flat` | `Boolean` | | Sets whether this marker should be flat against the map true or a billboard facing the camera false. | `identifier` | `String` | | An identifier used to reference this marker at a later date. +| `rotation` | `Float` | | A float number indicating marker's rotation angle. ## Events From 7869dfd277d59d8738f2d851d029a43c6bf5a3b9 Mon Sep 17 00:00:00 2001 From: Seph Soliman Date: Thu, 8 Dec 2016 22:41:21 +0100 Subject: [PATCH 016/199] Allow legalLabelInsets to be changed and animated (#873) * Allow legalLabelInsets to be changed and animated Updated example to include a button to animate the legal label. * Docs for legalLabelInsets prop While structurally identical to EdgePadding, they serve completely different purposes. Default left empty since it's an OS default (around {left: 10, bottom: 10}) * Spacing / linting --- docs/mapview.md | 10 +++++++++ example/examples/LegalLabel.js | 38 ++++++++++++++++++++++++++++++++-- ios/AirMaps/AIRMap.m | 6 ++++++ 3 files changed, 52 insertions(+), 2 deletions(-) diff --git a/docs/mapview.md b/docs/mapview.md index a10fbe58d..f05867bd2 100644 --- a/docs/mapview.md +++ b/docs/mapview.md @@ -28,6 +28,7 @@ | `loadingIndicatorColor` | `Color` | `#606060` | Sets loading indicator color, default to `#606060`. | `loadingBackgroundColor` | `Color` | `#FFFFFF` | Sets loading background color, default to `#FFFFFF`. | `moveOnMarkerPress` | `Boolean` | `true` | `Android only` If `false` the map won't move when a marker is pressed. +| `legalLabelInsets` | `EdgeInsets` | | If set, changes the position of the "Legal" label link from the OS default. **Note:** iOS only. ## Events @@ -103,3 +104,12 @@ type EdgePadding { left: Number } ``` + +``` +type EdgeInsets { + top: Number, + left: Number, + bottom: Number, + right: Number +} +``` \ No newline at end of file diff --git a/example/examples/LegalLabel.js b/example/examples/LegalLabel.js index 7715648f7..6d5894c85 100644 --- a/example/examples/LegalLabel.js +++ b/example/examples/LegalLabel.js @@ -3,7 +3,9 @@ import { StyleSheet, View, Text, + Animated, Dimensions, + TouchableOpacity, } from 'react-native'; import MapView from 'react-native-maps'; @@ -15,6 +17,34 @@ class LegalLabel extends React.Component { provider: MapView.ProviderPropType, } + state = { + _legalLabelPositionY: new Animated.Value(10), + legalLabelPositionY: 10, + } + + componentDidMount() { + this.state._legalLabelPositionY.addListener(({ value }) => { + this.setState({ + legalLabelPositionY: value, + }); + }); + } + + componentWillUnmount() { + this.state._legalLabelPositionY.removeAllListeners(); + } + + onPressAnimate = () => { + Animated.sequence([ + Animated.spring(this.state._legalLabelPositionY, { + toValue: 100, + }), + Animated.spring(this.state._legalLabelPositionY, { + toValue: 10, + }), + ]).start(); + } + render() { const latlng = { latitude: 37.78825, @@ -30,7 +60,7 @@ class LegalLabel extends React.Component { - Username + + Animate + @@ -84,6 +116,8 @@ const styles = StyleSheet.create({ usernameText: { fontSize: 36, lineHeight: 36, + color: 'blue', + textDecorationLine: 'underline', }, photo: { padding: 2, diff --git a/ios/AirMaps/AIRMap.m b/ios/AirMaps/AIRMap.m index 9683bfd3a..4c2d164c9 100644 --- a/ios/AirMaps/AIRMap.m +++ b/ios/AirMaps/AIRMap.m @@ -404,6 +404,12 @@ - (void)updateLegalLabelInsets { } } + +- (void)setLegalLabelInsets:(UIEdgeInsets)legalLabelInsets { + _legalLabelInsets = legalLabelInsets; + [self updateLegalLabelInsets]; +} + - (void)beginLoading { if ((!self.hasShownInitialLoading && self.loadingEnabled) || (self.cacheEnabled && self.cacheImageView.image == nil)) { self.loadingView.hidden = NO; From 5a7b55f5ff7a01ac14d334cae17790085f44d8d8 Mon Sep 17 00:00:00 2001 From: Spike Brehm Date: Fri, 9 Dec 2016 16:08:12 -0800 Subject: [PATCH 017/199] 0.12.2 --- CHANGELOG.md | 16 ++++++++++++++++ android/gradle.properties | 2 +- package.json | 2 +- react-native-google-maps.podspec | 2 +- react-native-maps.podspec | 2 +- 5 files changed, 20 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6e9de4544..9d92f700c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,21 @@ # Change Log +## 0.12.2 (December 9, 2016) + +* [Android] Added support for taking snapshots on Android + [#625](https://github.com/airbnb/react-native-maps/pull/625) + (@IjzerenHein) +* [iOS] Allow legalLabelInsets to be changed and animated + [#873](https://github.com/airbnb/react-native-maps/pull/873) + (@scarlac) +* Added rotation attribute documentation + [#](https://github.com/airbnb/react-native-maps/pull/) + (@Arman92) +* Update mapview.md documentation + [#866](https://github.com/airbnb/react-native-maps/pull/866) + (@dccarmo) + + ## 0.12.1 (December 6, 2016) This release only corrects the version in package.json. diff --git a/android/gradle.properties b/android/gradle.properties index 2423c0458..efa308fce 100644 --- a/android/gradle.properties +++ b/android/gradle.properties @@ -1,5 +1,5 @@ VERSION_CODE=2 -VERSION_NAME=0.12.1 +VERSION_NAME=0.12.2 GROUP=com.airbnb.android POM_DESCRIPTION=React Native Map view component for Android diff --git a/package.json b/package.json index 3967b5b80..c7f56595e 100644 --- a/package.json +++ b/package.json @@ -3,7 +3,7 @@ "description": "React Native Mapview component for iOS + Android", "main": "index.js", "author": "Leland Richardson ", - "version": "0.12.1", + "version": "0.12.2", "scripts": { "start": "react-native start", "lint": "eslint ." diff --git a/react-native-google-maps.podspec b/react-native-google-maps.podspec index 3e4ff9756..e32dda3be 100644 --- a/react-native-google-maps.podspec +++ b/react-native-google-maps.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = "react-native-google-maps" - s.version = "0.12.1" + s.version = "0.12.2" s.summary = "React Native Mapview component for iOS + Android" s.authors = { "intelligibabble" => "leland.m.richardson@gmail.com" } diff --git a/react-native-maps.podspec b/react-native-maps.podspec index ef9df382c..cb2cffa26 100644 --- a/react-native-maps.podspec +++ b/react-native-maps.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = "react-native-maps" - s.version = "0.12.1" + s.version = "0.12.2" s.summary = "React Native Mapview component for iOS + Android" s.authors = { "intelligibabble" => "leland.m.richardson@gmail.com" } From 3db28b8ae065d9509d7aff4a1cdd709b956db346 Mon Sep 17 00:00:00 2001 From: Spike Brehm Date: Fri, 9 Dec 2016 16:17:23 -0800 Subject: [PATCH 018/199] Update CHANGELOG; tweaks for 0.12.2 --- CHANGELOG.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9d92f700c..ab346a877 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ ## 0.12.2 (December 9, 2016) +### Patches + * [Android] Added support for taking snapshots on Android [#625](https://github.com/airbnb/react-native-maps/pull/625) (@IjzerenHein) @@ -9,7 +11,7 @@ [#873](https://github.com/airbnb/react-native-maps/pull/873) (@scarlac) * Added rotation attribute documentation - [#](https://github.com/airbnb/react-native-maps/pull/) + [#871](https://github.com/airbnb/react-native-maps/pull/871) (@Arman92) * Update mapview.md documentation [#866](https://github.com/airbnb/react-native-maps/pull/866) From 5de4dc7bc7b05d7e39f2da69a0b3decee7f2ba95 Mon Sep 17 00:00:00 2001 From: David Boyd Date: Sat, 17 Dec 2016 11:32:22 -0800 Subject: [PATCH 019/199] - Clarified what happens with "react-native link" command (#904) - Updated descriptions of getting and using Android API Keys. It works differently than when this was originally written. - Added fix for DexException - Added "import" in map component code --- docs/installation.md | 69 +++++++++++++++++++++++--------------------- 1 file changed, 36 insertions(+), 33 deletions(-) diff --git a/docs/installation.md b/docs/installation.md index 71fccd75b..512994d5e 100644 --- a/docs/installation.md +++ b/docs/installation.md @@ -6,10 +6,12 @@ First, download the library from npm: npm install react-native-maps --save ``` -Then you must install the native dependencies: You can use `rnpm` (now part of `react-native` core) to +Second, install the native dependencies: You can use `rnpm` (now part of `react-native` core via `link`) to add native dependencies automatically then continue the directions below depending on your target OS. - `$ react-native link` +``` +react-native link +``` >This installation should work in physical devices. For Genymotion, be sure to check Android installation about Google Play Services @@ -17,7 +19,7 @@ add native dependencies automatically then continue the directions below dependi ### Option 1: CocoaPods - Same as the included AirMapsExplorer example -1. Setup your `Podfile` like the included [example/ios/Podfile](../example/ios/Podfile) then run `pod install`. +1. Setup your `Podfile` like the included [example/ios/Podfile](../example/ios/Podfile), replace all references to `AirMapExplorer` with your project name, and then run `pod install`. (If you do not need `GoogleMaps` support for iOS, then you can probably completely skip this step.) 1. Open your project in Xcode workspace 1. Drag the following folder into your project: @@ -44,6 +46,8 @@ Now if you need `GoogleMaps` support you will also have to add a bunch of other After your `Podfile` is setup properly, run `pod install`. ### Option 3: Manually + >This was already done for you if you ran "react-native link" + 1. Open your project in Xcode, right click on `Libraries` and click `Add Files to "Your Project Name"` Look under `node_modules/react-native-maps/ios` and add `AIRMaps.xcodeproj`. 1. Add `libAIRMaps.a` to `Build Phases -> Link Binary With Libraries. @@ -60,6 +64,8 @@ After your `Podfile` is setup properly, run `pod install`. ## Android 1. In your `android/app/build.gradle` add: + >This step is not necessary if you ran "react-native link" + ```groovy ... dependencies { @@ -69,6 +75,8 @@ After your `Podfile` is setup properly, run `pod install`. ``` 1. In your `android/settings.gradle` add: + >This step is not necessary if you ran "react-native link" + ```groovy ... include ':react-native-maps' @@ -76,9 +84,9 @@ After your `Podfile` is setup properly, run `pod install`. ``` 1. Specify your Google Maps API Key: - > For development, it is recommended to use a ***Browser Key*** without referrer restrictions. Go to https://console.developers.google.com/apis/credentials to check your credentials. + > For development, you need to get a ***API Key***. Go to https://console.developers.google.com/apis/credentials to check your credentials. - Add your **Browser** API key to your manifest file (`android\app\src\main\AndroidManifest.xml`): + Add your API key to your manifest file (`android\app\src\main\AndroidManifest.xml`): ```xml @@ -87,18 +95,6 @@ After your `Podfile` is setup properly, run `pod install`. android:name="com.google.android.geo.API_KEY" android:value="Your Google maps API Key Here"/> - ``` - > If that doesn't work, try using an ***Android Key*** without referrer restrictions. Go to https://console.developers.google.com/apis/credentials to check your credentials. - - Add your **Android** API key to your manifest file: - - ```xml - - - - ``` > Note: As shown above, com.google.android.geo.API_KEY is the recommended metadata name for the API key. A key with this name can be used to authenticate to multiple Google Maps-based APIs on the Android platform, including the Google Maps Android API. For backwards compatibility, the API also supports the name com.google.android.maps.v2.API_KEY. This legacy name allows authentication to the Android Maps API v2 only. An application can specify only one of the API key metadata names. If both are specified, the API throws an exception. Source: https://developers.google.com/maps/documentation/android-api/signup @@ -115,12 +111,14 @@ If you have a blank map issue, ([#118](https://github.com/airbnb/react-native-ma You have to link dependencies with rnpm and re-run the build: -1. `rnpm link` +1. `react-native link` 1. `react-native run-ios` ### On Android: 1. Be sure to have `new MapsPackage()` in your `MainApplication.java` : + >This step is not necessary if you ran "react-native link" + ``` import com.airbnb.android.react.maps.MapsPackage; ... @@ -135,6 +133,7 @@ You have to link dependencies with rnpm and re-run the build: 1. Set this Stylesheet in your map component ``` + import MapView from 'react-native-maps'; ... const styles = StyleSheet.create({ container: { @@ -171,26 +170,30 @@ You have to link dependencies with rnpm and re-run the build: } } ``` -1. Run "android" and make sure every packages is updated. +1. Run "android" and make sure all packages are up-to-date. 1. If not installed yet, you have to install the following packages : - Extras / Google Play services - Extras / Google Repository - - Android 6.0 (API 23) / Google APIs Intel x86 Atom System Image Rev. 13 -1. Check manual installation steps -1. Generate your SHA1 key : - `keytool -list -v -keystore ~/.android/debug.keystore -alias androiddebugkey -storepass android -keypass android` - -1. Go to [Google API Console](https://console.developers.google.com/flows/enableapi?apiid=maps_android_backend) and select your project, or create one. -In `Overview -> Google Maps API -> Google Maps Android API ` -> Check if it's enabled -Create a new key by clicking on `Create credentials -> API Key -> Android Key`, enter the name of the API key and your SHA1 key, generated before, and create it. -Check installation step 4. - -1. Clean the cache : - `watchman watch-del-all` - `npm cache clean` + - Android 6.0 (API 23) / Google APIs Intel x86 Atom System Image Rev. 19 +1. Check manual installation steps if you didn't run "react-native link" +1. Go to [Google API Console](https://console.developers.google.com/flows/enableapi?apiid=maps_android_backend) and select your project, or create one. +Then, once enabled, select `Go to credentials`. +Select `Google Maps Android API` and create a new key. +Enter the name of the API key and create it. + +1. Clean the cache : + ``` + watchman watch-del-all + npm cache clean + ``` 1. When starting emulator, make sure you have enabled `Wipe user data`. 1. Run `react-native run-android` -1. At this step it should work, but if not, go to your [Google API Console](https://console.developers.google.com/flows/enableapi?apiid=maps_android_backend&keyType=CLIENT_SIDE_ANDROID&pli=1) and create a `Browser key` instead of a `Android key` and go to step 6. +1. If you encounter `com.android.dex.DexException: Multiple dex files define Landroid/support/v7/appcompat/R$anim`, then clear build folder. + ``` + cd android + gradlew clean + cd .. + ``` From f9246497a83526dc8f7a5359d06399419c34cdcc Mon Sep 17 00:00:00 2001 From: anami Date: Sat, 17 Dec 2016 19:32:49 +0000 Subject: [PATCH 020/199] Update marker.md to include the draggable prop. (#902) --- docs/marker.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/marker.md b/docs/marker.md index dee0e019d..4246befc3 100644 --- a/docs/marker.md +++ b/docs/marker.md @@ -16,6 +16,7 @@ | `flat` | `Boolean` | | Sets whether this marker should be flat against the map true or a billboard facing the camera false. | `identifier` | `String` | | An identifier used to reference this marker at a later date. | `rotation` | `Float` | | A float number indicating marker's rotation angle. +| `draggable` | `` | | This is a non-value based prop. Adding this allows the marker to be draggable (re-positioned). ## Events From 4a055c0d3bc5b7d1166e55e4322bba52c2de8b17 Mon Sep 17 00:00:00 2001 From: Ali Al Amine Date: Tue, 27 Dec 2016 20:23:03 +0200 Subject: [PATCH 021/199] [doc, android] Adding section to fix gradle problems (#910) * Updating the android installation docs This adds a method to fix the mismatch between the play-services in case the user wants to use a different version * Fix syntax for some versions of gradle Fixed some syntax as suggested by @Froelund as the previous one doesn't work on some versions of gradle. --- docs/installation.md | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/docs/installation.md b/docs/installation.md index 512994d5e..80c604ac5 100644 --- a/docs/installation.md +++ b/docs/installation.md @@ -73,6 +73,21 @@ After your `Podfile` is setup properly, run `pod install`. compile project(':react-native-maps') } ``` + + If you have a different play serivces than the one included in this library, use the following instead (switch 10.0.1 for the desired version): + + ```groovy + ... + dependencies { + ... + compile(project(':react-native-maps')){ + exclude group: 'com.google.android.gms', module: 'play-services-base' + exclude group: 'com.google.android.gms', module: 'play-services-maps' + } + compile 'com.google.android.gms:play-services-base:10.0.1' + compile 'com.google.android.gms:play-services-maps:10.0.1' + } + ``` 1. In your `android/settings.gradle` add: >This step is not necessary if you ran "react-native link" From a6d345d3c9644e787ce389916b20d717934e5d6f Mon Sep 17 00:00:00 2001 From: Javier Cuevas Date: Tue, 27 Dec 2016 19:23:34 +0100 Subject: [PATCH 022/199] =?UTF-8?q?Fix=20=E2=80=9CAnimating=20with=20MapVi?= =?UTF-8?q?ews=E2=80=9D=20example=20=E2=80=93=C2=A0fixes=20#763=20(#888)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- example/examples/AnimatedViews.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/example/examples/AnimatedViews.js b/example/examples/AnimatedViews.js index eea711905..884f11a37 100644 --- a/example/examples/AnimatedViews.js +++ b/example/examples/AnimatedViews.js @@ -191,7 +191,7 @@ class AnimatedViews extends React.Component { scale, translateY, markers, - region: new Animated.Region({ + region: new MapView.AnimatedRegion({ latitude: LATITUDE, longitude: LONGITUDE, latitudeDelta: LATITUDE_DELTA, @@ -220,7 +220,7 @@ class AnimatedViews extends React.Component { }).start(); } - onStartShouldSetPanResponder(e) { + onStartShouldSetPanResponder = (e) => { // we only want to move the view if they are starting the gesture on top // of the view, so this calculates that and returns true if so. If we return // false, the gesture should get passed to the map view appropriately. @@ -232,7 +232,7 @@ class AnimatedViews extends React.Component { return topOfTap < topOfMainWindow; } - onMoveShouldSetPanResponder(e) { + onMoveShouldSetPanResponder = (e) => { const { panY } = this.state; const { pageY } = e.nativeEvent; const topOfMainWindow = ITEM_PREVIEW_HEIGHT + panY.__getValue(); @@ -241,7 +241,7 @@ class AnimatedViews extends React.Component { return topOfTap < topOfMainWindow; } - onPanXChange({ value }) { + onPanXChange = ({ value }) => { const { index } = this.state; const newIndex = Math.floor(((-1 * value) + (SNAP_WIDTH / 2)) / SNAP_WIDTH); if (index !== newIndex) { @@ -249,7 +249,7 @@ class AnimatedViews extends React.Component { } } - onPanYChange({ value }) { + onPanYChange = ({ value }) => { const { canMoveHorizontal, region, scrollY, scrollX, markers, index } = this.state; const shouldBeMovable = Math.abs(value) < 2; if (shouldBeMovable !== canMoveHorizontal) { From 51d94da6030ab1c53eb80598f9217eb0f4545ec7 Mon Sep 17 00:00:00 2001 From: mlanter Date: Tue, 27 Dec 2016 13:23:49 -0500 Subject: [PATCH 023/199] [android crash] Fix exception when animating region during initialization (#901) --- .../com/airbnb/android/react/maps/AirMapView.java | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/android/src/main/java/com/airbnb/android/react/maps/AirMapView.java b/android/src/main/java/com/airbnb/android/react/maps/AirMapView.java index cb7e9fb6d..5d8de64af 100644 --- a/android/src/main/java/com/airbnb/android/react/maps/AirMapView.java +++ b/android/src/main/java/com/airbnb/android/react/maps/AirMapView.java @@ -479,13 +479,17 @@ public void updateExtraData(Object extraData) { } public void animateToRegion(LatLngBounds bounds, int duration) { - startMonitoringRegion(); - map.animateCamera(CameraUpdateFactory.newLatLngBounds(bounds, 0), duration, null); + if (map != null) { + startMonitoringRegion(); + map.animateCamera(CameraUpdateFactory.newLatLngBounds(bounds, 0), duration, null); + } } public void animateToCoordinate(LatLng coordinate, int duration) { - startMonitoringRegion(); - map.animateCamera(CameraUpdateFactory.newLatLng(coordinate), duration, null); + if (map != null) { + startMonitoringRegion(); + map.animateCamera(CameraUpdateFactory.newLatLng(coordinate), duration, null); + } } public void fitToElements(boolean animated) { From 1e71a21f39e7b88554852951f773c731c94680c9 Mon Sep 17 00:00:00 2001 From: Vjeran Crnjak Date: Tue, 27 Dec 2016 19:26:45 +0100 Subject: [PATCH 024/199] fixes Option 2 building (#900) * fixes Option 2 building - afaik `GMSMapStyle` is not present in 2.0.x * Update installation.md * Update installation.md --- docs/installation.md | 7 +++---- react-native-google-maps.podspec | 2 +- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/docs/installation.md b/docs/installation.md index 80c604ac5..a236fbda1 100644 --- a/docs/installation.md +++ b/docs/installation.md @@ -27,10 +27,9 @@ react-native link 1. If you need `GoogleMaps` support also drag this folder into your project: - `node_modules/react-native-maps/ios/AirGoogleMaps/` -### Option 2: CocoaPods -- Untested Way -NOTE: If you actually get this to work, please open an issue to let us know. -This is now considered the **old way** because it is untested and if it does work at all, it -will only work if you **don't** have `use_frameworks!` in your `Podfile` +### Option 2: CocoaPods +This is now considered the **old way** because it will only work if you **don't** have +`use_frameworks!` in your `Podfile`. To install using Cocoapods, simply insert the following line into your `Podfile`: diff --git a/react-native-google-maps.podspec b/react-native-google-maps.podspec index e32dda3be..8ec70ea43 100644 --- a/react-native-google-maps.podspec +++ b/react-native-google-maps.podspec @@ -12,5 +12,5 @@ Pod::Spec.new do |s| s.source_files = "ios/AirGoogleMaps/**/*.{h,m}" s.dependency 'React' - s.dependency 'GoogleMaps', '2.0.1' + s.dependency 'GoogleMaps', '2.1.1' end From 1af45a707e20c5e9187e24420b20f94baf0c8766 Mon Sep 17 00:00:00 2001 From: rajkumarpunchh Date: Thu, 5 Jan 2017 13:57:11 +0530 Subject: [PATCH 025/199] Fixed issue #751. https://github.com/airbnb/react-native-maps/issues/751 --- ios/AirMaps/AIRMapManager.m | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/ios/AirMaps/AIRMapManager.m b/ios/AirMaps/AIRMapManager.m index 4fedef3b8..2bb916970 100644 --- a/ios/AirMaps/AIRMapManager.m +++ b/ios/AirMaps/AIRMapManager.m @@ -158,7 +158,9 @@ - (UIView *)view } else { AIRMap *mapView = (AIRMap *)view; // TODO(lmr): we potentially want to include overlays here... and could concat the two arrays together. - [mapView showAnnotations:mapView.annotations animated:animated]; + dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 0.1 * NSEC_PER_SEC), dispatch_get_main_queue(), ^{ + [mapView showAnnotations:mapView.annotations animated:animated]; + }); } }]; } From d274eb48a98034295410ed498897f4ed384ceee8 Mon Sep 17 00:00:00 2001 From: James Ide Date: Fri, 30 Dec 2016 21:15:06 -0800 Subject: [PATCH 026/199] [RN 0.40] Update iOS header imports and JS SyntheticEvent import for RN 0.40 React Native 0.40 (coming soon) changes the way its iOS headers should be imported. The headers are now under a directory called "React" that is in the compiler's include path, hence the new import style. On the JS side, RN 0.40 now peer-depends on React 15.4.x which moved SyntheticEvent from `react/lib` to deep inside `react-native`, so update that import as well. Test Plan: Follow the setup instructions (https://github.com/airbnb/react-native-maps/blob/master/docs/examples-setup.md) and run the explorer app (notably verify that it compiles). --- example/examples/EventListener.js | 3 ++- example/ios/AirMapsExplorer/AppDelegate.m | 2 +- .../AirMapsExplorerTests.m | 4 ++-- example/package.json | 6 +++--- ios/AirGoogleMaps/AIRGMSMarker.h | 2 +- ios/AirGoogleMaps/AIRGoogleMap.h | 4 ++-- ios/AirGoogleMaps/AIRGoogleMap.m | 4 ++-- ios/AirGoogleMaps/AIRGoogleMapCallout.h | 2 +- ios/AirGoogleMaps/AIRGoogleMapCallout.m | 6 +++--- .../AIRGoogleMapCalloutManager.h | 2 +- .../AIRGoogleMapCalloutManager.m | 2 +- ios/AirGoogleMaps/AIRGoogleMapCircle.m | 2 +- ios/AirGoogleMaps/AIRGoogleMapCircleManager.h | 2 +- ios/AirGoogleMaps/AIRGoogleMapCircleManager.m | 4 ++-- ios/AirGoogleMaps/AIRGoogleMapManager.h | 2 +- ios/AirGoogleMaps/AIRGoogleMapManager.m | 18 ++++++++-------- ios/AirGoogleMaps/AIRGoogleMapMarker.h | 2 +- ios/AirGoogleMaps/AIRGoogleMapMarker.m | 8 +++---- ios/AirGoogleMaps/AIRGoogleMapMarkerManager.h | 2 +- ios/AirGoogleMaps/AIRGoogleMapMarkerManager.m | 4 ++-- .../AIRGoogleMapPolygonManager.h | 2 +- .../AIRGoogleMapPolygonManager.m | 12 +++++------ ios/AirGoogleMaps/AIRGoogleMapPolyline.m | 2 +- .../AIRGoogleMapPolylineManager.h | 2 +- .../AIRGoogleMapPolylineManager.m | 12 +++++------ .../AIRGoogleMapUrlTileManager.h | 2 +- ios/AirGoogleMaps/RCTConvert+GMSMapViewType.h | 2 +- ios/AirGoogleMaps/RCTConvert+GMSMapViewType.m | 2 +- ios/AirMaps/AIRMap.h | 4 ++-- ios/AirMaps/AIRMap.m | 4 ++-- ios/AirMaps/AIRMapCallout.h | 2 +- ios/AirMaps/AIRMapCalloutManager.h | 2 +- ios/AirMaps/AIRMapCalloutManager.m | 12 +++++------ ios/AirMaps/AIRMapCircle.h | 11 +++++----- ios/AirMaps/AIRMapCircle.m | 2 +- ios/AirMaps/AIRMapCircleManager.h | 2 +- ios/AirMaps/AIRMapCircleManager.m | 12 +++++------ ios/AirMaps/AIRMapManager.h | 2 +- ios/AirMaps/AIRMapManager.m | 21 +++++++++---------- ios/AirMaps/AIRMapMarker.h | 4 ++-- ios/AirMaps/AIRMapMarker.m | 12 +++++------ ios/AirMaps/AIRMapMarkerManager.h | 2 +- ios/AirMaps/AIRMapMarkerManager.m | 6 +++--- ios/AirMaps/AIRMapPolygon.h | 6 +++--- ios/AirMaps/AIRMapPolygon.m | 2 +- ios/AirMaps/AIRMapPolygonManager.h | 2 +- ios/AirMaps/AIRMapPolygonManager.m | 12 +++++------ ios/AirMaps/AIRMapPolyline.h | 8 +++---- ios/AirMaps/AIRMapPolyline.m | 2 +- ios/AirMaps/AIRMapPolylineManager.h | 2 +- ios/AirMaps/AIRMapPolylineManager.m | 12 +++++------ ios/AirMaps/AIRMapUrlTile.h | 6 +++--- ios/AirMaps/AIRMapUrlTile.m | 2 +- ios/AirMaps/AIRMapUrlTileManager.h | 2 +- ios/AirMaps/AIRMapUrlTileManager.m | 13 ++++++------ ios/AirMaps/RCTConvert+MoreMapKit.h | 2 +- ios/AirMaps/RCTConvert+MoreMapKit.m | 4 ++-- package.json | 4 ++-- 58 files changed, 146 insertions(+), 148 deletions(-) diff --git a/example/examples/EventListener.js b/example/examples/EventListener.js index 0f62fbc73..0876c621d 100644 --- a/example/examples/EventListener.js +++ b/example/examples/EventListener.js @@ -1,5 +1,4 @@ import React, { PropTypes } from 'react'; -import SyntheticEvent from 'react/lib/SyntheticEvent'; import { StyleSheet, View, @@ -7,6 +6,8 @@ import { Dimensions, ScrollView, } from 'react-native'; +// eslint-disable-next-line max-len +import SyntheticEvent from 'react-native/Libraries/Renderer/src/renderers/shared/stack/event/SyntheticEvent'; import MapView from 'react-native-maps'; import PriceMarker from './PriceMarker'; diff --git a/example/ios/AirMapsExplorer/AppDelegate.m b/example/ios/AirMapsExplorer/AppDelegate.m index 91ae54c48..6f006087f 100644 --- a/example/ios/AirMapsExplorer/AppDelegate.m +++ b/example/ios/AirMapsExplorer/AppDelegate.m @@ -9,7 +9,7 @@ #import "AppDelegate.h" -#import "RCTRootView.h" +#import #import diff --git a/example/ios/AirMapsExplorerTests/AirMapsExplorerTests.m b/example/ios/AirMapsExplorerTests/AirMapsExplorerTests.m index 31dab00aa..a93b699bd 100644 --- a/example/ios/AirMapsExplorerTests/AirMapsExplorerTests.m +++ b/example/ios/AirMapsExplorerTests/AirMapsExplorerTests.m @@ -10,8 +10,8 @@ #import #import -#import "RCTLog.h" -#import "RCTRootView.h" +#import +#import #define TIMEOUT_SECONDS 240 #define TEXT_TO_LOOK_FOR @"Welcome to React Native!" diff --git a/example/package.json b/example/package.json index a303d3cff..eca9884a4 100644 --- a/example/package.json +++ b/example/package.json @@ -9,9 +9,9 @@ "dev": "concurrently 'npm run watch' 'npm run packager'" }, "dependencies": { - "react": "^15.3.1", - "react-native": "^0.35.0", - "react-native-maps": "../" + "react": "~15.4.1", + "react-native": "^0.40.0", + "react-native-maps": "file:../" }, "devDependencies": { "concurrently": "^2.2.0", diff --git a/ios/AirGoogleMaps/AIRGMSMarker.h b/ios/AirGoogleMaps/AIRGMSMarker.h index baf89341d..89723ca2a 100644 --- a/ios/AirGoogleMaps/AIRGMSMarker.h +++ b/ios/AirGoogleMaps/AIRGMSMarker.h @@ -6,7 +6,7 @@ // #import -#import "UIView+React.h" +#import @class AIRGoogleMapMarker; diff --git a/ios/AirGoogleMaps/AIRGoogleMap.h b/ios/AirGoogleMaps/AIRGoogleMap.h index bf16a2ef4..925aa4746 100644 --- a/ios/AirGoogleMaps/AIRGoogleMap.h +++ b/ios/AirGoogleMaps/AIRGoogleMap.h @@ -6,10 +6,10 @@ // #import -#import "RCTComponent.h" +#import +#import #import #import -#import "RCTConvert+MapKit.h" #import "AIRGMSMarker.h" @interface AIRGoogleMap : GMSMapView diff --git a/ios/AirGoogleMaps/AIRGoogleMap.m b/ios/AirGoogleMaps/AIRGoogleMap.m index 50f148eb1..39c8bb3a6 100644 --- a/ios/AirGoogleMaps/AIRGoogleMap.m +++ b/ios/AirGoogleMaps/AIRGoogleMap.m @@ -13,8 +13,8 @@ #import "AIRGoogleMapUrlTile.h" #import #import -#import "RCTConvert+MapKit.h" -#import "UIView+React.h" +#import +#import id regionAsJSON(MKCoordinateRegion region) { return @{ diff --git a/ios/AirGoogleMaps/AIRGoogleMapCallout.h b/ios/AirGoogleMaps/AIRGoogleMapCallout.h index 61558e6bc..784bcf613 100644 --- a/ios/AirGoogleMaps/AIRGoogleMapCallout.h +++ b/ios/AirGoogleMaps/AIRGoogleMapCallout.h @@ -7,7 +7,7 @@ // #import -#import "RCTView.h" +#import @interface AIRGoogleMapCallout : UIView @property (nonatomic, assign) BOOL tooltip; diff --git a/ios/AirGoogleMaps/AIRGoogleMapCallout.m b/ios/AirGoogleMaps/AIRGoogleMapCallout.m index c64a6e03b..acc6b86b7 100644 --- a/ios/AirGoogleMaps/AIRGoogleMapCallout.m +++ b/ios/AirGoogleMaps/AIRGoogleMapCallout.m @@ -7,9 +7,9 @@ // #import "AIRGoogleMapCallout.h" -#import "RCTUtils.h" -#import "RCTView.h" -#import "RCTBridge.h" +#import +#import +#import @implementation AIRGoogleMapCallout @end diff --git a/ios/AirGoogleMaps/AIRGoogleMapCalloutManager.h b/ios/AirGoogleMaps/AIRGoogleMapCalloutManager.h index be0e1a72f..e5514087e 100644 --- a/ios/AirGoogleMaps/AIRGoogleMapCalloutManager.h +++ b/ios/AirGoogleMaps/AIRGoogleMapCalloutManager.h @@ -5,7 +5,7 @@ // Created by Gil Birman on 9/6/16. // // -#import "RCTViewManager.h" +#import @interface AIRGoogleMapCalloutManager : RCTViewManager diff --git a/ios/AirGoogleMaps/AIRGoogleMapCalloutManager.m b/ios/AirGoogleMaps/AIRGoogleMapCalloutManager.m index 9a2a20998..1828beb8a 100644 --- a/ios/AirGoogleMaps/AIRGoogleMapCalloutManager.m +++ b/ios/AirGoogleMaps/AIRGoogleMapCalloutManager.m @@ -8,7 +8,7 @@ #import "AIRGoogleMapCalloutManager.h" #import "AIRGoogleMapCallout.h" -#import "RCTView.h" +#import @implementation AIRGoogleMapCalloutManager RCT_EXPORT_MODULE() diff --git a/ios/AirGoogleMaps/AIRGoogleMapCircle.m b/ios/AirGoogleMaps/AIRGoogleMapCircle.m index 1698bee8c..28741b9f3 100644 --- a/ios/AirGoogleMaps/AIRGoogleMapCircle.m +++ b/ios/AirGoogleMaps/AIRGoogleMapCircle.m @@ -6,7 +6,7 @@ #import #import "AIRGoogleMapCircle.h" #import -#import "RCTUtils.h" +#import @implementation AIRGoogleMapCircle diff --git a/ios/AirGoogleMaps/AIRGoogleMapCircleManager.h b/ios/AirGoogleMaps/AIRGoogleMapCircleManager.h index 481b6d6c5..c1de72318 100644 --- a/ios/AirGoogleMaps/AIRGoogleMapCircleManager.h +++ b/ios/AirGoogleMaps/AIRGoogleMapCircleManager.h @@ -4,7 +4,7 @@ // Created by Nick Italiano on 10/24/16. // -#import "RCTViewManager.h" +#import @interface AIRGoogleMapCircleManager : RCTViewManager diff --git a/ios/AirGoogleMaps/AIRGoogleMapCircleManager.m b/ios/AirGoogleMaps/AIRGoogleMapCircleManager.m index 62a164d22..93afa145f 100644 --- a/ios/AirGoogleMaps/AIRGoogleMapCircleManager.m +++ b/ios/AirGoogleMaps/AIRGoogleMapCircleManager.m @@ -6,8 +6,8 @@ #import "AIRGoogleMapCircleManager.h" #import "AIRGoogleMapCircle.h" -#import "RCTBridge.h" -#import "UIView+React.h" +#import +#import @interface AIRGoogleMapCircleManager() diff --git a/ios/AirGoogleMaps/AIRGoogleMapManager.h b/ios/AirGoogleMaps/AIRGoogleMapManager.h index b726eae65..ac841c7bf 100644 --- a/ios/AirGoogleMaps/AIRGoogleMapManager.h +++ b/ios/AirGoogleMaps/AIRGoogleMapManager.h @@ -5,7 +5,7 @@ // Created by Gil Birman on 9/1/16. // -#import "RCTViewManager.h" +#import @interface AIRGoogleMapManager : RCTViewManager diff --git a/ios/AirGoogleMaps/AIRGoogleMapManager.m b/ios/AirGoogleMaps/AIRGoogleMapManager.m index a04186e7e..e306de1d8 100644 --- a/ios/AirGoogleMaps/AIRGoogleMapManager.m +++ b/ios/AirGoogleMaps/AIRGoogleMapManager.m @@ -7,18 +7,18 @@ #import "AIRGoogleMapManager.h" -#import "RCTViewManager.h" -#import "RCTBridge.h" -#import "RCTUIManager.h" -#import "RCTConvert+CoreLocation.h" -#import "RCTConvert+MapKit.h" +#import +#import +#import +#import +#import +#import +#import +#import +#import #import "RCTConvert+GMSMapViewType.h" -#import "RCTEventDispatcher.h" #import "AIRGoogleMap.h" -#import "UIView+React.h" #import "AIRMapMarker.h" -#import "RCTViewManager.h" -#import "RCTConvert.h" #import "AIRMapPolyline.h" #import "AIRMapPolygon.h" #import "AIRMapCircle.h" diff --git a/ios/AirGoogleMaps/AIRGoogleMapMarker.h b/ios/AirGoogleMaps/AIRGoogleMapMarker.h index 8f1018b05..ca6a5cc12 100644 --- a/ios/AirGoogleMaps/AIRGoogleMapMarker.h +++ b/ios/AirGoogleMaps/AIRGoogleMapMarker.h @@ -6,8 +6,8 @@ // #import +#import #import "AIRGMSMarker.h" -#import "RCTBridge.h" #import "AIRGoogleMap.h" #import "AIRGoogleMapCallout.h" diff --git a/ios/AirGoogleMaps/AIRGoogleMapMarker.m b/ios/AirGoogleMaps/AIRGoogleMapMarker.m index a3bbbffc0..4bb10dede 100644 --- a/ios/AirGoogleMaps/AIRGoogleMapMarker.m +++ b/ios/AirGoogleMaps/AIRGoogleMapMarker.m @@ -7,10 +7,10 @@ #import "AIRGoogleMapMarker.h" #import +#import +#import #import "AIRGMSMarker.h" #import "AIRGoogleMapCallout.h" -#import "RCTImageLoader.h" -#import "RCTUtils.h" #import "DummyView.h" CGRect unionRect(CGRect a, CGRect b) { @@ -186,14 +186,14 @@ - (void)setImageSrc:(NSString *)imageSrc if (_iconImageView) [_iconImageView removeFromSuperview]; return; } - + if (!_iconImageView) { // prevent glitch with marker (cf. https://github.com/airbnb/react-native-maps/issues/738) UIImageView *empyImageView = [[UIImageView alloc] init]; _iconImageView = empyImageView; [self iconViewInsertSubview:_iconImageView atIndex:0]; } - + _reloadImageCancellationBlock = [_bridge.imageLoader loadImageWithURLRequest:[RCTConvert NSURLRequest:_imageSrc] size:self.bounds.size scale:RCTScreenScale() diff --git a/ios/AirGoogleMaps/AIRGoogleMapMarkerManager.h b/ios/AirGoogleMaps/AIRGoogleMapMarkerManager.h index 657f6b044..f2698dcd0 100644 --- a/ios/AirGoogleMaps/AIRGoogleMapMarkerManager.h +++ b/ios/AirGoogleMaps/AIRGoogleMapMarkerManager.h @@ -5,7 +5,7 @@ // Created by Gil Birman on 9/2/16. // -#import "RCTViewManager.h" +#import @interface AIRGoogleMapMarkerManager : RCTViewManager diff --git a/ios/AirGoogleMaps/AIRGoogleMapMarkerManager.m b/ios/AirGoogleMaps/AIRGoogleMapMarkerManager.m index ee138c25f..0d29c3fac 100644 --- a/ios/AirGoogleMaps/AIRGoogleMapMarkerManager.m +++ b/ios/AirGoogleMaps/AIRGoogleMapMarkerManager.m @@ -8,8 +8,8 @@ #import "AIRGoogleMapMarkerManager.h" #import "AIRGoogleMapMarker.h" #import -#import "RCTConvert+MapKit.h" -#import "RCTUIManager.h" +#import +#import @implementation AIRGoogleMapMarkerManager diff --git a/ios/AirGoogleMaps/AIRGoogleMapPolygonManager.h b/ios/AirGoogleMaps/AIRGoogleMapPolygonManager.h index fd6040ca0..3380c61e3 100644 --- a/ios/AirGoogleMaps/AIRGoogleMapPolygonManager.h +++ b/ios/AirGoogleMaps/AIRGoogleMapPolygonManager.h @@ -4,7 +4,7 @@ // Created by Nick Italiano on 10/22/16. // -#import "RCTViewManager.h" +#import @interface AIRGoogleMapPolygonManager : RCTViewManager diff --git a/ios/AirGoogleMaps/AIRGoogleMapPolygonManager.m b/ios/AirGoogleMaps/AIRGoogleMapPolygonManager.m index 383bb6527..5c7ce2a66 100644 --- a/ios/AirGoogleMaps/AIRGoogleMapPolygonManager.m +++ b/ios/AirGoogleMaps/AIRGoogleMapPolygonManager.m @@ -5,13 +5,13 @@ // #import "AIRGoogleMapPolygonManager.h" -#import "RCTBridge.h" -#import "RCTConvert.h" -#import "RCTConvert+CoreLocation.h" +#import +#import +#import +#import +#import +#import #import "RCTConvert+MoreMapKit.h" -#import "RCTEventDispatcher.h" -#import "UIView+React.h" -#import "RCTViewManager.h" #import "AIRGoogleMapPolygon.h" @interface AIRGoogleMapPolygonManager() diff --git a/ios/AirGoogleMaps/AIRGoogleMapPolyline.m b/ios/AirGoogleMaps/AIRGoogleMapPolyline.m index c55621e97..009d90bfb 100644 --- a/ios/AirGoogleMaps/AIRGoogleMapPolyline.m +++ b/ios/AirGoogleMaps/AIRGoogleMapPolyline.m @@ -9,7 +9,7 @@ #import "AIRGoogleMapMarker.h" #import "AIRGoogleMapMarkerManager.h" #import -#import "RCTUtils.h" +#import @implementation AIRGoogleMapPolyline diff --git a/ios/AirGoogleMaps/AIRGoogleMapPolylineManager.h b/ios/AirGoogleMaps/AIRGoogleMapPolylineManager.h index 48aaf8527..82e7b8e20 100644 --- a/ios/AirGoogleMaps/AIRGoogleMapPolylineManager.h +++ b/ios/AirGoogleMaps/AIRGoogleMapPolylineManager.h @@ -4,7 +4,7 @@ // Created by Nick Italiano on 10/22/16. // -#import "RCTViewManager.h" +#import @interface AIRGoogleMapPolylineManager : RCTViewManager diff --git a/ios/AirGoogleMaps/AIRGoogleMapPolylineManager.m b/ios/AirGoogleMaps/AIRGoogleMapPolylineManager.m index 68817b138..8ccaa7080 100644 --- a/ios/AirGoogleMaps/AIRGoogleMapPolylineManager.m +++ b/ios/AirGoogleMaps/AIRGoogleMapPolylineManager.m @@ -6,13 +6,13 @@ #import "AIRGoogleMapPolylineManager.h" -#import "RCTBridge.h" -#import "RCTConvert.h" -#import "RCTConvert+CoreLocation.h" +#import +#import +#import +#import +#import +#import #import "RCTConvert+MoreMapKit.h" -#import "RCTEventDispatcher.h" -#import "UIView+React.h" -#import "RCTViewManager.h" #import "AIRGoogleMapPolyline.h" @interface AIRGoogleMapPolylineManager() diff --git a/ios/AirGoogleMaps/AIRGoogleMapUrlTileManager.h b/ios/AirGoogleMaps/AIRGoogleMapUrlTileManager.h index 3554837d4..affd718b4 100644 --- a/ios/AirGoogleMaps/AIRGoogleMapUrlTileManager.h +++ b/ios/AirGoogleMaps/AIRGoogleMapUrlTileManager.h @@ -4,7 +4,7 @@ // #import -#import "RCTViewManager.h" +#import @interface AIRGoogleMapUrlTileManager : RCTViewManager @end diff --git a/ios/AirGoogleMaps/RCTConvert+GMSMapViewType.h b/ios/AirGoogleMaps/RCTConvert+GMSMapViewType.h index a753f4331..7e02d66a0 100644 --- a/ios/AirGoogleMaps/RCTConvert+GMSMapViewType.h +++ b/ios/AirGoogleMaps/RCTConvert+GMSMapViewType.h @@ -6,7 +6,7 @@ #import #import -#import "RCTConvert.h" +#import @interface RCTConvert (GMSMapViewType) diff --git a/ios/AirGoogleMaps/RCTConvert+GMSMapViewType.m b/ios/AirGoogleMaps/RCTConvert+GMSMapViewType.m index 42053fb1d..bd339f30e 100644 --- a/ios/AirGoogleMaps/RCTConvert+GMSMapViewType.m +++ b/ios/AirGoogleMaps/RCTConvert+GMSMapViewType.m @@ -6,7 +6,7 @@ #import "RCTConvert+GMSMapViewType.h" #import -#import "RCTConvert.h" +#import @implementation RCTConvert (GMSMapViewType) RCT_ENUM_CONVERTER(GMSMapViewType, diff --git a/ios/AirMaps/AIRMap.h b/ios/AirMaps/AIRMap.h index 6b061fe42..fd4ed0f25 100644 --- a/ios/AirMaps/AIRMap.h +++ b/ios/AirMaps/AIRMap.h @@ -10,8 +10,8 @@ #import #import -#import "RCTConvert+MapKit.h" -#import "RCTComponent.h" +#import +#import #import "SMCalloutView.h" extern const CLLocationDegrees AIRMapDefaultSpan; diff --git a/ios/AirMaps/AIRMap.m b/ios/AirMaps/AIRMap.m index 4c2d164c9..1126c3825 100644 --- a/ios/AirMaps/AIRMap.m +++ b/ios/AirMaps/AIRMap.m @@ -9,9 +9,9 @@ #import "AIRMap.h" -#import "RCTEventDispatcher.h" +#import +#import #import "AIRMapMarker.h" -#import "UIView+React.h" #import "AIRMapPolyline.h" #import "AIRMapPolygon.h" #import "AIRMapCircle.h" diff --git a/ios/AirMaps/AIRMapCallout.h b/ios/AirMaps/AIRMapCallout.h index 876409f7f..6e53ce1d5 100644 --- a/ios/AirMaps/AIRMapCallout.h +++ b/ios/AirMaps/AIRMapCallout.h @@ -4,7 +4,7 @@ // #import -#import "RCTView.h" +#import @interface AIRMapCallout : RCTView diff --git a/ios/AirMaps/AIRMapCalloutManager.h b/ios/AirMaps/AIRMapCalloutManager.h index b5bbadff8..411739a8d 100644 --- a/ios/AirMaps/AIRMapCalloutManager.h +++ b/ios/AirMaps/AIRMapCalloutManager.h @@ -3,7 +3,7 @@ // Copyright (c) 2015 Facebook. All rights reserved. // -#import "RCTViewManager.h" +#import @interface AIRMapCalloutManager : RCTViewManager diff --git a/ios/AirMaps/AIRMapCalloutManager.m b/ios/AirMaps/AIRMapCalloutManager.m index fbd1804ea..bc1a8e7a3 100644 --- a/ios/AirMaps/AIRMapCalloutManager.m +++ b/ios/AirMaps/AIRMapCalloutManager.m @@ -9,13 +9,13 @@ #import "AIRMapCalloutManager.h" -#import "RCTBridge.h" -#import "RCTConvert.h" -#import "RCTConvert+CoreLocation.h" -#import "RCTEventDispatcher.h" -#import "UIView+React.h" +#import +#import +#import +#import +#import +#import #import "AIRMapMarker.h" -#import "RCTViewManager.h" #import "AIRMapCallout.h" @interface AIRMapCalloutManager() diff --git a/ios/AirMaps/AIRMapCircle.h b/ios/AirMaps/AIRMapCircle.h index dffacb246..44755a9ee 100644 --- a/ios/AirMaps/AIRMapCircle.h +++ b/ios/AirMaps/AIRMapCircle.h @@ -8,13 +8,12 @@ #import #import -#import "RCTConvert+MapKit.h" -#import "RCTComponent.h" +#import +#import +#import + #import "AIRMapCoordinate.h" #import "AIRMap.h" -#import "RCTView.h" - - @interface AIRMapCircle: MKAnnotationView @@ -42,4 +41,4 @@ - (BOOL)intersectsMapRect:(MKMapRect)mapRect; - (BOOL)canReplaceMapContent; -@end \ No newline at end of file +@end diff --git a/ios/AirMaps/AIRMapCircle.m b/ios/AirMaps/AIRMapCircle.m index 5e23c1155..540c4d437 100644 --- a/ios/AirMaps/AIRMapCircle.m +++ b/ios/AirMaps/AIRMapCircle.m @@ -4,7 +4,7 @@ // #import "AIRMapCircle.h" -#import "UIView+React.h" +#import @implementation AIRMapCircle { diff --git a/ios/AirMaps/AIRMapCircleManager.h b/ios/AirMaps/AIRMapCircleManager.h index a752c2d3c..55f52a0ca 100644 --- a/ios/AirMaps/AIRMapCircleManager.h +++ b/ios/AirMaps/AIRMapCircleManager.h @@ -3,7 +3,7 @@ // Copyright (c) 2015 Facebook. All rights reserved. // -#import "RCTViewManager.h" +#import @interface AIRMapCircleManager : RCTViewManager diff --git a/ios/AirMaps/AIRMapCircleManager.m b/ios/AirMaps/AIRMapCircleManager.m index 022e124a8..c7c4a2ac5 100644 --- a/ios/AirMaps/AIRMapCircleManager.m +++ b/ios/AirMaps/AIRMapCircleManager.m @@ -9,13 +9,13 @@ #import "AIRMapCircleManager.h" -#import "RCTBridge.h" -#import "RCTConvert.h" -#import "RCTConvert+CoreLocation.h" -#import "RCTEventDispatcher.h" -#import "UIView+React.h" +#import +#import +#import +#import +#import +#import #import "AIRMapMarker.h" -#import "RCTViewManager.h" #import "AIRMapCircle.h" @interface AIRMapCircleManager() diff --git a/ios/AirMaps/AIRMapManager.h b/ios/AirMaps/AIRMapManager.h index f3ffd4515..cc9a8c75b 100644 --- a/ios/AirMaps/AIRMapManager.h +++ b/ios/AirMaps/AIRMapManager.h @@ -7,7 +7,7 @@ * of patent rights can be found in the PATENTS file in the same directory. */ -#import "RCTViewManager.h" +#import @interface AIRMapManager : RCTViewManager diff --git a/ios/AirMaps/AIRMapManager.m b/ios/AirMaps/AIRMapManager.m index 4fedef3b8..e4ecadf39 100644 --- a/ios/AirMaps/AIRMapManager.m +++ b/ios/AirMaps/AIRMapManager.m @@ -7,19 +7,18 @@ * of patent rights can be found in the PATENTS file in the same directory. */ -#import "RCTViewManager.h" #import "AIRMapManager.h" -#import "RCTBridge.h" -#import "RCTUIManager.h" -#import "RCTConvert+CoreLocation.h" -#import "RCTConvert+MapKit.h" -#import "RCTEventDispatcher.h" +#import +#import +#import +#import +#import +#import +#import +#import #import "AIRMap.h" -#import "UIView+React.h" #import "AIRMapMarker.h" -#import "RCTViewManager.h" -#import "RCTConvert.h" #import "AIRMapPolyline.h" #import "AIRMapPolygon.h" #import "AIRMapCircle.h" @@ -307,7 +306,7 @@ - (void)takeMapSnapshot:(AIRMap *)mapView UIImage *compositeImage = UIGraphicsGetImageFromCurrentImageContext(); NSData *data; - if ([format isEqualToString:@"png"]) { + if ([format isEqualToString:@"png"]) { data = UIImagePNGRepresentation(compositeImage); } else if([format isEqualToString:@"jpg"]) { @@ -325,7 +324,7 @@ - (void)takeMapSnapshot:(AIRMap *)mapView // In the initial (iOS only) implementation of takeSnapshot, // both the uri and the base64 encoded string were returned. - // Returning both is rarely useful and in fact causes a + // Returning both is rarely useful and in fact causes a // performance penalty when only the file URI is desired. // In that case the base64 encoded string was always marshalled // over the JS-bridge (which is quite slow). diff --git a/ios/AirMaps/AIRMapMarker.h b/ios/AirMaps/AIRMapMarker.h index 187cbad0a..97440639f 100644 --- a/ios/AirMaps/AIRMapMarker.h +++ b/ios/AirMaps/AIRMapMarker.h @@ -13,8 +13,8 @@ #import #import -#import "RCTConvert+MapKit.h" -#import "RCTComponent.h" +#import +#import #import "AIRMap.h" #import "SMCalloutView.h" diff --git a/ios/AirMaps/AIRMapMarker.m b/ios/AirMaps/AIRMapMarker.m index 983f5fabe..2d7d086d4 100644 --- a/ios/AirMaps/AIRMapMarker.m +++ b/ios/AirMaps/AIRMapMarker.m @@ -9,11 +9,11 @@ #import "AIRMapMarker.h" -#import "RCTEventDispatcher.h" -#import "UIView+React.h" -#import "RCTBridge.h" -#import "RCTUtils.h" -#import "RCTImageLoader.h" +#import +#import +#import +#import +#import @implementation AIREmptyCalloutBackgroundView @end @@ -232,7 +232,7 @@ - (void)setImageSrc:(NSString *)imageSrc - (void)setPinColor:(UIColor *)pinColor { _pinColor = pinColor; - + if ([_pinView respondsToSelector:@selector(setPinTintColor:)]) { _pinView.pinTintColor = _pinColor; } diff --git a/ios/AirMaps/AIRMapMarkerManager.h b/ios/AirMaps/AIRMapMarkerManager.h index baea30735..1fc44601d 100644 --- a/ios/AirMaps/AIRMapMarkerManager.h +++ b/ios/AirMaps/AIRMapMarkerManager.h @@ -7,7 +7,7 @@ * of patent rights can be found in the PATENTS file in the same directory. */ -#import "RCTViewManager.h" +#import @interface AIRMapMarkerManager : RCTViewManager diff --git a/ios/AirMaps/AIRMapMarkerManager.m b/ios/AirMaps/AIRMapMarkerManager.m index ceecf0148..493d6cc2e 100644 --- a/ios/AirMaps/AIRMapMarkerManager.m +++ b/ios/AirMaps/AIRMapMarkerManager.m @@ -9,9 +9,9 @@ #import "AIRMapMarkerManager.h" -#import "RCTUIManager.h" -#import "RCTConvert+CoreLocation.h" -#import "UIView+React.h" +#import +#import +#import #import "AIRMapMarker.h" @interface AIRMapMarkerManager () diff --git a/ios/AirMaps/AIRMapPolygon.h b/ios/AirMaps/AIRMapPolygon.h index d028e67fb..33e752cf0 100644 --- a/ios/AirMaps/AIRMapPolygon.h +++ b/ios/AirMaps/AIRMapPolygon.h @@ -8,11 +8,11 @@ #import #import -#import "RCTConvert+MapKit.h" -#import "RCTComponent.h" +#import +#import +#import #import "AIRMapCoordinate.h" #import "AIRMap.h" -#import "RCTView.h" diff --git a/ios/AirMaps/AIRMapPolygon.m b/ios/AirMaps/AIRMapPolygon.m index 3ee378d0f..3ab7eb7c2 100644 --- a/ios/AirMaps/AIRMapPolygon.m +++ b/ios/AirMaps/AIRMapPolygon.m @@ -4,7 +4,7 @@ // #import "AIRMapPolygon.h" -#import "UIView+React.h" +#import @implementation AIRMapPolygon { diff --git a/ios/AirMaps/AIRMapPolygonManager.h b/ios/AirMaps/AIRMapPolygonManager.h index 6321e9d21..5dbfb6c04 100644 --- a/ios/AirMaps/AIRMapPolygonManager.h +++ b/ios/AirMaps/AIRMapPolygonManager.h @@ -3,7 +3,7 @@ // Copyright (c) 2015 Facebook. All rights reserved. // -#import "RCTViewManager.h" +#import @interface AIRMapPolygonManager : RCTViewManager diff --git a/ios/AirMaps/AIRMapPolygonManager.m b/ios/AirMaps/AIRMapPolygonManager.m index 1299dee12..a8177c180 100644 --- a/ios/AirMaps/AIRMapPolygonManager.m +++ b/ios/AirMaps/AIRMapPolygonManager.m @@ -9,14 +9,14 @@ #import "AIRMapPolygonManager.h" -#import "RCTBridge.h" -#import "RCTConvert.h" +#import +#import +#import +#import +#import +#import #import "RCTConvert+MoreMapKit.h" -#import "RCTConvert+CoreLocation.h" -#import "RCTEventDispatcher.h" -#import "UIView+React.h" #import "AIRMapMarker.h" -#import "RCTViewManager.h" #import "AIRMapPolygon.h" @interface AIRMapPolygonManager() diff --git a/ios/AirMaps/AIRMapPolyline.h b/ios/AirMaps/AIRMapPolyline.h index 2e5b4e30a..5629b1fd4 100644 --- a/ios/AirMaps/AIRMapPolyline.h +++ b/ios/AirMaps/AIRMapPolyline.h @@ -8,11 +8,11 @@ #import #import -#import "RCTConvert+MapKit.h" -#import "RCTComponent.h" +#import +#import +#import #import "AIRMapCoordinate.h" #import "AIRMap.h" -#import "RCTView.h" @interface AIRMapPolyline: MKAnnotationView @@ -40,4 +40,4 @@ - (BOOL)intersectsMapRect:(MKMapRect)mapRect; - (BOOL)canReplaceMapContent; -@end \ No newline at end of file +@end diff --git a/ios/AirMaps/AIRMapPolyline.m b/ios/AirMaps/AIRMapPolyline.m index 5b28167fd..8e07a63b3 100644 --- a/ios/AirMaps/AIRMapPolyline.m +++ b/ios/AirMaps/AIRMapPolyline.m @@ -4,7 +4,7 @@ // #import "AIRMapPolyline.h" -#import "UIView+React.h" +#import @implementation AIRMapPolyline { diff --git a/ios/AirMaps/AIRMapPolylineManager.h b/ios/AirMaps/AIRMapPolylineManager.h index a529a837a..aa5313b32 100644 --- a/ios/AirMaps/AIRMapPolylineManager.h +++ b/ios/AirMaps/AIRMapPolylineManager.h @@ -3,7 +3,7 @@ // Copyright (c) 2015 Facebook. All rights reserved. // -#import "RCTViewManager.h" +#import @interface AIRMapPolylineManager : RCTViewManager diff --git a/ios/AirMaps/AIRMapPolylineManager.m b/ios/AirMaps/AIRMapPolylineManager.m index 399b46d40..70ba3eb1f 100644 --- a/ios/AirMaps/AIRMapPolylineManager.m +++ b/ios/AirMaps/AIRMapPolylineManager.m @@ -9,14 +9,14 @@ #import "AIRMapPolylineManager.h" -#import "RCTBridge.h" -#import "RCTConvert.h" -#import "RCTConvert+CoreLocation.h" +#import +#import +#import +#import +#import +#import #import "RCTConvert+MoreMapKit.h" -#import "RCTEventDispatcher.h" -#import "UIView+React.h" #import "AIRMapMarker.h" -#import "RCTViewManager.h" #import "AIRMapPolyline.h" @interface AIRMapPolylineManager() diff --git a/ios/AirMaps/AIRMapUrlTile.h b/ios/AirMaps/AIRMapUrlTile.h index 184fe2231..509331414 100644 --- a/ios/AirMaps/AIRMapUrlTile.h +++ b/ios/AirMaps/AIRMapUrlTile.h @@ -10,11 +10,11 @@ #import #import -#import "RCTConvert+MapKit.h" -#import "RCTComponent.h" +#import +#import +#import #import "AIRMapCoordinate.h" #import "AIRMap.h" -#import "RCTView.h" @interface AIRMapUrlTile : MKAnnotationView diff --git a/ios/AirMaps/AIRMapUrlTile.m b/ios/AirMaps/AIRMapUrlTile.m index 5fbe1a3b8..fdefbf3bc 100644 --- a/ios/AirMaps/AIRMapUrlTile.m +++ b/ios/AirMaps/AIRMapUrlTile.m @@ -7,7 +7,7 @@ // #import "AIRMapUrlTile.h" -#import "UIView+React.h" +#import @implementation AIRMapUrlTile { BOOL _urlTemplateSet; diff --git a/ios/AirMaps/AIRMapUrlTileManager.h b/ios/AirMaps/AIRMapUrlTileManager.h index 6a79b2233..aaee4e431 100644 --- a/ios/AirMaps/AIRMapUrlTileManager.h +++ b/ios/AirMaps/AIRMapUrlTileManager.h @@ -7,7 +7,7 @@ // -#import "RCTViewManager.h" +#import @interface AIRMapUrlTileManager : RCTViewManager diff --git a/ios/AirMaps/AIRMapUrlTileManager.m b/ios/AirMaps/AIRMapUrlTileManager.m index decec5170..4ae4abffc 100644 --- a/ios/AirMaps/AIRMapUrlTileManager.m +++ b/ios/AirMaps/AIRMapUrlTileManager.m @@ -6,13 +6,13 @@ // Copyright © 2016. All rights reserved. // -#import "RCTBridge.h" -#import "RCTConvert.h" -#import "RCTConvert+CoreLocation.h" -#import "RCTEventDispatcher.h" -#import "UIView+React.h" +#import +#import +#import +#import +#import +#import #import "AIRMapMarker.h" -#import "RCTViewManager.h" #import "AIRMapUrlTile.h" #import "AIRMapUrlTileManager.h" @@ -35,4 +35,3 @@ - (UIView *)view RCT_EXPORT_VIEW_PROPERTY(urlTemplate, NSString) @end - diff --git a/ios/AirMaps/RCTConvert+MoreMapKit.h b/ios/AirMaps/RCTConvert+MoreMapKit.h index 96c99a599..2d2475890 100644 --- a/ios/AirMaps/RCTConvert+MoreMapKit.h +++ b/ios/AirMaps/RCTConvert+MoreMapKit.h @@ -5,7 +5,7 @@ #import #import -#import "RCTConvert.h" +#import @interface RCTConvert (MoreMapKit) diff --git a/ios/AirMaps/RCTConvert+MoreMapKit.m b/ios/AirMaps/RCTConvert+MoreMapKit.m index 9f18553d1..11f19a4a8 100644 --- a/ios/AirMaps/RCTConvert+MoreMapKit.m +++ b/ios/AirMaps/RCTConvert+MoreMapKit.m @@ -4,9 +4,9 @@ // #import "RCTConvert+MoreMapKit.h" -#import "AIRMapCoordinate.h" -#import "RCTConvert+CoreLocation.h" +#import +#import "AIRMapCoordinate.h" @implementation RCTConvert (MoreMapKit) diff --git a/package.json b/package.json index c7f56595e..83444baa6 100644 --- a/package.json +++ b/package.json @@ -22,8 +22,8 @@ "mapkit" ], "peerDependencies": { - "react": ">=15.3.1", - "react-native": ">=0.35" + "react": ">=15.4.0", + "react-native": ">=0.40" }, "devDependencies": { "babel-eslint": "^6.1.2", From 9c88e848a4c9740c3f45c8ac41edfd144cd0d9f0 Mon Sep 17 00:00:00 2001 From: James Ide Date: Thu, 5 Jan 2017 12:18:19 -0800 Subject: [PATCH 027/199] [Podfile] Update the example Podfile for RN 0.40 Tested it with Google Maps support. --- .../AirMapsExplorer.xcodeproj/project.pbxproj | 13 +++--- example/ios/Podfile | 36 +++------------ example/ios/Podfile.lock | 45 +++++++++++-------- 3 files changed, 39 insertions(+), 55 deletions(-) diff --git a/example/ios/AirMapsExplorer.xcodeproj/project.pbxproj b/example/ios/AirMapsExplorer.xcodeproj/project.pbxproj index decbbec68..df5a3a05b 100644 --- a/example/ios/AirMapsExplorer.xcodeproj/project.pbxproj +++ b/example/ios/AirMapsExplorer.xcodeproj/project.pbxproj @@ -32,7 +32,6 @@ 21E6570C1D77591A00B75EE5 /* MobileCoreServices.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 21E6570B1D77591A00B75EE5 /* MobileCoreServices.framework */; }; 21E6570E1D77591F00B75EE5 /* MapKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 21E6570D1D77591F00B75EE5 /* MapKit.framework */; }; 21E657101D77594C00B75EE5 /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 21E6570F1D77594C00B75EE5 /* AudioToolbox.framework */; }; - 3E4E0B5921E01BC4043FD8CD /* Pods_AirMapsExplorer.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3591658C00398534590C8751 /* Pods_AirMapsExplorer.framework */; }; 8620CC871DBD814A00B79BFE /* AIRGMSMarker.m in Sources */ = {isa = PBXBuildFile; fileRef = 8620CC6E1DBD814A00B79BFE /* AIRGMSMarker.m */; }; 8620CC881DBD814A00B79BFE /* AIRGoogleMap.m in Sources */ = {isa = PBXBuildFile; fileRef = 8620CC701DBD814A00B79BFE /* AIRGoogleMap.m */; }; 8620CC891DBD814A00B79BFE /* AIRGoogleMapCallout.m in Sources */ = {isa = PBXBuildFile; fileRef = 8620CC721DBD814A00B79BFE /* AIRGoogleMapCallout.m */; }; @@ -50,7 +49,7 @@ 8697D6251DBEE22B00DB7D0F /* AIRGoogleMapCircleManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 8697D6241DBEE22B00DB7D0F /* AIRGoogleMapCircleManager.m */; }; 86DE6F881DCE7D21002A5053 /* AIRGoogleMapUrlTile.m in Sources */ = {isa = PBXBuildFile; fileRef = 86DE6F871DCE7D21002A5053 /* AIRGoogleMapUrlTile.m */; }; 86DE6F8B1DCE8543002A5053 /* AIRGoogleMapURLTileManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 86DE6F8A1DCE8543002A5053 /* AIRGoogleMapURLTileManager.m */; }; - C9315A21AD5A149EB5B40F29 /* Pods_AirMapsExplorer.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 24EB66BA0860A4DCD4CA3D77 /* Pods_AirMapsExplorer.framework */; }; + A622B8115793E41C70169A8B /* libPods-AirMapsExplorer.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 0E5044A406006E7C2A53E05C /* libPods-AirMapsExplorer.a */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -66,6 +65,7 @@ /* Begin PBXFileReference section */ 008F07F21AC5B25A0029DE68 /* main.jsbundle */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = main.jsbundle; sourceTree = ""; }; 00E356EE1AD99517003FC87E /* AirMapsExplorerTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = AirMapsExplorerTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + 0E5044A406006E7C2A53E05C /* libPods-AirMapsExplorer.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-AirMapsExplorer.a"; sourceTree = BUILT_PRODUCTS_DIR; }; 13B07F961A680F5B00A75B9A /* AirMapsExplorer.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = AirMapsExplorer.app; sourceTree = BUILT_PRODUCTS_DIR; }; 13B07FAF1A68108700A75B9A /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AppDelegate.h; path = AirMapsExplorer/AppDelegate.h; sourceTree = ""; }; 13B07FB01A68108700A75B9A /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = AppDelegate.m; path = AirMapsExplorer/AppDelegate.m; sourceTree = ""; }; @@ -116,7 +116,6 @@ 21E6570B1D77591A00B75EE5 /* MobileCoreServices.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MobileCoreServices.framework; path = System/Library/Frameworks/MobileCoreServices.framework; sourceTree = SDKROOT; }; 21E6570D1D77591F00B75EE5 /* MapKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MapKit.framework; path = System/Library/Frameworks/MapKit.framework; sourceTree = SDKROOT; }; 21E6570F1D77594C00B75EE5 /* AudioToolbox.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AudioToolbox.framework; path = System/Library/Frameworks/AudioToolbox.framework; sourceTree = SDKROOT; }; - 3591658C00398534590C8751 /* Pods_AirMapsExplorer.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_AirMapsExplorer.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 8620CC6D1DBD814A00B79BFE /* AIRGMSMarker.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AIRGMSMarker.h; sourceTree = ""; }; 8620CC6E1DBD814A00B79BFE /* AIRGMSMarker.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AIRGMSMarker.m; sourceTree = ""; }; 8620CC6F1DBD814A00B79BFE /* AIRGoogleMap.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AIRGoogleMap.h; sourceTree = ""; }; @@ -147,12 +146,12 @@ 8697D6211DBEDE6100DB7D0F /* AIRGoogleMapCircle.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AIRGoogleMapCircle.m; sourceTree = ""; }; 8697D6231DBEE22B00DB7D0F /* AIRGoogleMapCircleManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AIRGoogleMapCircleManager.h; sourceTree = ""; }; 8697D6241DBEE22B00DB7D0F /* AIRGoogleMapCircleManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AIRGoogleMapCircleManager.m; sourceTree = ""; }; - BE5DE1E9AE25978F88CD940A /* Pods-AirMapsExplorer.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-AirMapsExplorer.debug.xcconfig"; path = "Pods/Target Support Files/Pods-AirMapsExplorer/Pods-AirMapsExplorer.debug.xcconfig"; sourceTree = ""; }; - E138AD0CDB08FE57B09B18F8 /* Pods-AirMapsExplorer.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-AirMapsExplorer.release.xcconfig"; path = "Pods/Target Support Files/Pods-AirMapsExplorer/Pods-AirMapsExplorer.release.xcconfig"; sourceTree = ""; }; 86DE6F861DCE7D21002A5053 /* AIRGoogleMapUrlTile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AIRGoogleMapUrlTile.h; sourceTree = ""; }; 86DE6F871DCE7D21002A5053 /* AIRGoogleMapUrlTile.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AIRGoogleMapUrlTile.m; sourceTree = ""; }; 86DE6F891DCE8543002A5053 /* AIRGoogleMapUrlTileManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AIRGoogleMapUrlTileManager.h; sourceTree = ""; }; 86DE6F8A1DCE8543002A5053 /* AIRGoogleMapURLTileManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AIRGoogleMapURLTileManager.m; sourceTree = ""; }; + BE5DE1E9AE25978F88CD940A /* Pods-AirMapsExplorer.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-AirMapsExplorer.debug.xcconfig"; path = "Pods/Target Support Files/Pods-AirMapsExplorer/Pods-AirMapsExplorer.debug.xcconfig"; sourceTree = ""; }; + E138AD0CDB08FE57B09B18F8 /* Pods-AirMapsExplorer.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-AirMapsExplorer.release.xcconfig"; path = "Pods/Target Support Files/Pods-AirMapsExplorer/Pods-AirMapsExplorer.release.xcconfig"; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -171,7 +170,7 @@ 21E6570E1D77591F00B75EE5 /* MapKit.framework in Frameworks */, 21E6570C1D77591A00B75EE5 /* MobileCoreServices.framework in Frameworks */, 21E6570A1D77591400B75EE5 /* SystemConfiguration.framework in Frameworks */, - 3E4E0B5921E01BC4043FD8CD /* Pods_AirMapsExplorer.framework in Frameworks */, + A622B8115793E41C70169A8B /* libPods-AirMapsExplorer.a in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -190,7 +189,7 @@ 21E6570D1D77591F00B75EE5 /* MapKit.framework */, 21E6570B1D77591A00B75EE5 /* MobileCoreServices.framework */, 21E657091D77591400B75EE5 /* SystemConfiguration.framework */, - 3591658C00398534590C8751 /* Pods_AirMapsExplorer.framework */, + 0E5044A406006E7C2A53E05C /* libPods-AirMapsExplorer.a */, ); name = Frameworks; sourceTree = ""; diff --git a/example/ios/Podfile b/example/ios/Podfile index 4da2704b9..80b14bdc1 100644 --- a/example/ios/Podfile +++ b/example/ios/Podfile @@ -1,18 +1,14 @@ -# You Podfile should look similar to this file. Whether you use_frameworks! or not, the following configuration should work. -# -# However if you DO NOT use_frameworks! and you prefer to install pods instead of -# dragging the AirMaps directory into your project, refer to the comments below (steps 1~4) - +# You Podfile should look similar to this file. React Native currently does not support use_frameworks! source 'https://github.com/CocoaPods/Specs.git' platform :ios, '8.0' -use_frameworks! # Change 'AirMapsExplorer' to match the target in your Xcode project. target 'AirMapsExplorer' do pod 'React', path: '../node_modules/react-native', :subspecs => [ 'Core', 'RCTActionSheet', + 'RCTAnimation', 'RCTGeolocation', 'RCTImage', 'RCTLinkingIOS', @@ -23,29 +19,9 @@ target 'AirMapsExplorer' do 'RCTWebSocket' ] -# when not using frameworks we can do this instead of including the source files in our project (1/4): -# pod 'react-native-maps', path: '../../' -# pod 'react-native-google-maps', path: '../../' # <~~ if you need GoogleMaps support on iOS - -# when not using frameworks we can remove this line (2/4): pod 'GoogleMaps' # <~~ remove this line if you do not want to support GoogleMaps on iOS -end -# when not using frameworks this might be necessary, but try without it first and see if `pod install` works (3/4): -# THIS IS ONLY NECESSARY IF YOU NEED GoogleMaps SUPPORT -# pre_install do |installer| - # # copied from https://github.com/CocoaPods/CocoaPods/issues/2926 - # # workaround for https://github.com/CocoaPods/CocoaPods/issues/3289 - # def installer.verify_no_static_framework_transitive_dependencies; end -# end - -# when not using frameworks (4/4): -# THIS IS ONLY NECESSARY IF YOU NEED GoogleMaps SUPPORT -# #Crud, this shouldn't be necessary, but https://github.com/CocoaPods/CocoaPods/issues/5429 -# post_install do |installer| -# installer.pods_project.targets.each do |target| -# target.build_configurations.each do |config| -# config.build_settings['CLANG_ENABLE_MODULES'] = 'NO' -# end -# end -# end +# when not using frameworks we can do this instead of including the source files in our project (1/4): +# pod 'react-native-maps', path: '../../' +# pod 'react-native-google-maps', path: '../../' # <~~ if you need GoogleMaps support on iOS +end diff --git a/example/ios/Podfile.lock b/example/ios/Podfile.lock index 1f4c2d9a6..5e689bb4a 100644 --- a/example/ios/Podfile.lock +++ b/example/ios/Podfile.lock @@ -1,34 +1,43 @@ PODS: - - GoogleMaps (2.1.0): - - GoogleMaps/Maps (= 2.1.0) - - GoogleMaps/Base (2.1.0) - - GoogleMaps/Maps (2.1.0): - - GoogleMaps/Base (= 2.1.0) - - React/Core (0.35.0) - - React/RCTActionSheet (0.35.0): + - GoogleMaps (2.1.1): + - GoogleMaps/Maps (= 2.1.1) + - GoogleMaps/Base (2.1.1) + - GoogleMaps/Maps (2.1.1): + - GoogleMaps/Base + - React/Core (0.40.0): + - React/cxxreact + - React/yoga + - React/cxxreact (0.40.0): + - React/jschelpers + - React/jschelpers (0.40.0) + - React/RCTActionSheet (0.40.0): - React/Core - - React/RCTGeolocation (0.35.0): + - React/RCTAnimation (0.40.0): - React/Core - - React/RCTImage (0.35.0): + - React/RCTGeolocation (0.40.0): + - React/Core + - React/RCTImage (0.40.0): - React/Core - React/RCTNetwork - - React/RCTLinkingIOS (0.35.0): + - React/RCTLinkingIOS (0.40.0): - React/Core - - React/RCTNetwork (0.35.0): + - React/RCTNetwork (0.40.0): - React/Core - - React/RCTSettings (0.35.0): + - React/RCTSettings (0.40.0): - React/Core - - React/RCTText (0.35.0): + - React/RCTText (0.40.0): - React/Core - - React/RCTVibration (0.35.0): + - React/RCTVibration (0.40.0): - React/Core - - React/RCTWebSocket (0.35.0): + - React/RCTWebSocket (0.40.0): - React/Core + - React/yoga (0.40.0) DEPENDENCIES: - GoogleMaps - React/Core (from `../node_modules/react-native`) - React/RCTActionSheet (from `../node_modules/react-native`) + - React/RCTAnimation (from `../node_modules/react-native`) - React/RCTGeolocation (from `../node_modules/react-native`) - React/RCTImage (from `../node_modules/react-native`) - React/RCTLinkingIOS (from `../node_modules/react-native`) @@ -43,9 +52,9 @@ EXTERNAL SOURCES: :path: "../node_modules/react-native" SPEC CHECKSUMS: - GoogleMaps: 06589b9a38097bce0cd6e90f0fd9b5e4b4a9344c - React: d80af5410aa500d0cb1bce2cc4493a584cf2ec92 + GoogleMaps: a5b5bbe47734e2443bde781a6aa64e69fdb6d785 + React: 6dfb2f72edb1d74a800127ae157af038646673ce -PODFILE CHECKSUM: be65689c848eff5d4099a483239b72acab62f6a4 +PODFILE CHECKSUM: ffbc20bd08f662256d501d07a70e77862684f702 COCOAPODS: 1.1.1 From 39e9e1e8ee6fc01e665162ef0635c4bebd700a0f Mon Sep 17 00:00:00 2001 From: Spike Brehm Date: Fri, 6 Jan 2017 17:39:55 -0800 Subject: [PATCH 028/199] Update CHANGELOG for 0.12.3 --- CHANGELOG.md | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index ab346a877..9454e2c6d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,37 @@ # Change Log +## 0.12.3 (January 6, 2017) + +### Patches + +* Fix "Animating with MapViews" example – fixes #763 + [#888](https://github.com/airbnb/react-native-maps/pull/888) + (@javiercr) +* [iOS] Fix "Option 2" method of building Google Maps + [#900](https://github.com/airbnb/react-native-maps/pull/900) + (@vjeranc) +* [Android] Fix exception when animating region during initialization + [#901](https://github.com/airbnb/react-native-maps/pull/901) + (@mlanter) +* Updated documentation + [#902](https://github.com/airbnb/react-native-maps/pull/902), + [#904](https://github.com/airbnb/react-native-maps/pull/904), + [#910](https://github.com/airbnb/react-native-maps/pull/910) + (@anami, @dboydor, @ali-alamine) +* + [#](https://github.com/airbnb/react-native-maps/pull/) + (@) +* + [#](https://github.com/airbnb/react-native-maps/pull/) + (@) +* + [#](https://github.com/airbnb/react-native-maps/pull/) + (@) +* + [#](https://github.com/airbnb/react-native-maps/pull/) + (@) + + ## 0.12.2 (December 9, 2016) ### Patches From f3d371213da32583f0b5ebb3d328a918a021b4d6 Mon Sep 17 00:00:00 2001 From: Spike Brehm Date: Fri, 6 Jan 2017 17:40:11 -0800 Subject: [PATCH 029/199] 0.12.3 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 83444baa6..c6caed556 100644 --- a/package.json +++ b/package.json @@ -3,7 +3,7 @@ "description": "React Native Mapview component for iOS + Android", "main": "index.js", "author": "Leland Richardson ", - "version": "0.12.2", + "version": "0.12.3", "scripts": { "start": "react-native start", "lint": "eslint ." From ff9bf142119bcdb24a2f91648afa987874c86a1b Mon Sep 17 00:00:00 2001 From: Spike Brehm Date: Fri, 6 Jan 2017 17:43:17 -0800 Subject: [PATCH 030/199] Update version in all the places --- android/gradle.properties | 2 +- react-native-google-maps.podspec | 2 +- react-native-maps.podspec | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/android/gradle.properties b/android/gradle.properties index efa308fce..dd20adf2b 100644 --- a/android/gradle.properties +++ b/android/gradle.properties @@ -1,5 +1,5 @@ VERSION_CODE=2 -VERSION_NAME=0.12.2 +VERSION_NAME=0.12.3 GROUP=com.airbnb.android POM_DESCRIPTION=React Native Map view component for Android diff --git a/react-native-google-maps.podspec b/react-native-google-maps.podspec index 8ec70ea43..3bac5a282 100644 --- a/react-native-google-maps.podspec +++ b/react-native-google-maps.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = "react-native-google-maps" - s.version = "0.12.2" + s.version = "0.12.3" s.summary = "React Native Mapview component for iOS + Android" s.authors = { "intelligibabble" => "leland.m.richardson@gmail.com" } diff --git a/react-native-maps.podspec b/react-native-maps.podspec index cb2cffa26..0b783ac2e 100644 --- a/react-native-maps.podspec +++ b/react-native-maps.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = "react-native-maps" - s.version = "0.12.2" + s.version = "0.12.3" s.summary = "React Native Mapview component for iOS + Android" s.authors = { "intelligibabble" => "leland.m.richardson@gmail.com" } From 67d958efdd0bdecd980a5081ac75c13336a6bf64 Mon Sep 17 00:00:00 2001 From: Spike Brehm Date: Fri, 6 Jan 2017 17:48:30 -0800 Subject: [PATCH 031/199] Update CHANGELOG for 0.13.0 --- CHANGELOG.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9454e2c6d..a4c8766a3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,19 @@ # Change Log +## 0.13.0 (January 6, 2017) + +### Breaking Changes + +* Update iOS header imports and JS SyntheticEvent import for RN 0.40 + [#923](https://github.com/airbnb/react-native-maps/pull/923) + (@ide) + +### Patches + +* Fix issue where callouts sometimes overlap or don't appear + [#936](https://github.com/airbnb/react-native-maps/pull/936) + (@RajkumarPunchh) + ## 0.12.3 (January 6, 2017) ### Patches From edec7e88d36ef50eede860720de908490cf99549 Mon Sep 17 00:00:00 2001 From: Spike Brehm Date: Fri, 6 Jan 2017 17:48:50 -0800 Subject: [PATCH 032/199] 0.13.0 --- android/gradle.properties | 2 +- package.json | 2 +- react-native-google-maps.podspec | 2 +- react-native-maps.podspec | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/android/gradle.properties b/android/gradle.properties index dd20adf2b..81ab2a1bd 100644 --- a/android/gradle.properties +++ b/android/gradle.properties @@ -1,5 +1,5 @@ VERSION_CODE=2 -VERSION_NAME=0.12.3 +VERSION_NAME=0.13.0 GROUP=com.airbnb.android POM_DESCRIPTION=React Native Map view component for Android diff --git a/package.json b/package.json index c6caed556..016a69c97 100644 --- a/package.json +++ b/package.json @@ -3,7 +3,7 @@ "description": "React Native Mapview component for iOS + Android", "main": "index.js", "author": "Leland Richardson ", - "version": "0.12.3", + "version": "0.13.0", "scripts": { "start": "react-native start", "lint": "eslint ." diff --git a/react-native-google-maps.podspec b/react-native-google-maps.podspec index 3bac5a282..6f6b28703 100644 --- a/react-native-google-maps.podspec +++ b/react-native-google-maps.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = "react-native-google-maps" - s.version = "0.12.3" + s.version = "0.13.0" s.summary = "React Native Mapview component for iOS + Android" s.authors = { "intelligibabble" => "leland.m.richardson@gmail.com" } diff --git a/react-native-maps.podspec b/react-native-maps.podspec index 0b783ac2e..601e4eb71 100644 --- a/react-native-maps.podspec +++ b/react-native-maps.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = "react-native-maps" - s.version = "0.12.3" + s.version = "0.13.0" s.summary = "React Native Mapview component for iOS + Android" s.authors = { "intelligibabble" => "leland.m.richardson@gmail.com" } From 4b3a2963a8125410d9158a5c4c1d6e595f619842 Mon Sep 17 00:00:00 2001 From: Spike Brehm Date: Fri, 6 Jan 2017 17:51:08 -0800 Subject: [PATCH 033/199] Remove cruft from CHANGELOG --- CHANGELOG.md | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a4c8766a3..0fc969558 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -32,18 +32,6 @@ [#904](https://github.com/airbnb/react-native-maps/pull/904), [#910](https://github.com/airbnb/react-native-maps/pull/910) (@anami, @dboydor, @ali-alamine) -* - [#](https://github.com/airbnb/react-native-maps/pull/) - (@) -* - [#](https://github.com/airbnb/react-native-maps/pull/) - (@) -* - [#](https://github.com/airbnb/react-native-maps/pull/) - (@) -* - [#](https://github.com/airbnb/react-native-maps/pull/) - (@) ## 0.12.2 (December 9, 2016) From a4565b933de8fdc86f67a0149408a7eeb613532b Mon Sep 17 00:00:00 2001 From: Stan Bershadskiy Date: Mon, 9 Jan 2017 12:36:34 -0500 Subject: [PATCH 034/199] add identifier to marker press event --- .../main/java/com/airbnb/android/react/maps/AirMapView.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/android/src/main/java/com/airbnb/android/react/maps/AirMapView.java b/android/src/main/java/com/airbnb/android/react/maps/AirMapView.java index 5d8de64af..ea316c195 100644 --- a/android/src/main/java/com/airbnb/android/react/maps/AirMapView.java +++ b/android/src/main/java/com/airbnb/android/react/maps/AirMapView.java @@ -149,13 +149,16 @@ public void onMapReady(final GoogleMap map) { @Override public boolean onMarkerClick(Marker marker) { WritableMap event; + AirMapMarker airMapMarker = markerMap.get(marker); event = makeClickEventData(marker.getPosition()); event.putString("action", "marker-press"); + event.putString("id", airMapMarker.getIdentifier()); manager.pushEvent(view, "onMarkerPress", event); event = makeClickEventData(marker.getPosition()); event.putString("action", "marker-press"); + event.putString("id", airMapMarker.getIdentifier()); manager.pushEvent(markerMap.get(marker), "onPress", event); // Return false to open the callout info window and center on the marker From f5bb3df969950a8b6454141decb4c338b95f5780 Mon Sep 17 00:00:00 2001 From: rajkumarpunchh Date: Thu, 12 Jan 2017 15:49:31 +0530 Subject: [PATCH 035/199] =?UTF-8?q?Fixed=20issue=20#286.=20onPress=20and?= =?UTF-8?q?=20onCalloutPress=20not=20doesn=E2=80=99t=20trigger=20on=20mark?= =?UTF-8?q?ers=20in=20iOS.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ios/AirMaps/AIRMapMarker.h | 1 + ios/AirMaps/AIRMapMarker.m | 51 +++++++++++++++++++++++++++++++ ios/AirMaps/AIRMapMarkerManager.m | 41 +------------------------ 3 files changed, 53 insertions(+), 40 deletions(-) diff --git a/ios/AirMaps/AIRMapMarker.h b/ios/AirMaps/AIRMapMarker.h index 97440639f..828357b70 100644 --- a/ios/AirMaps/AIRMapMarker.h +++ b/ios/AirMaps/AIRMapMarker.h @@ -48,6 +48,7 @@ - (BOOL)shouldShowCalloutView; - (void)showCalloutView; - (void)hideCalloutView; +- (void)addTapGestureRecognizer; @end diff --git a/ios/AirMaps/AIRMapMarker.m b/ios/AirMaps/AIRMapMarker.m index 2d7d086d4..9f40d06a6 100644 --- a/ios/AirMaps/AIRMapMarker.m +++ b/ios/AirMaps/AIRMapMarker.m @@ -71,6 +71,7 @@ - (MKAnnotationView *)getAnnotationView // In this case, we want to render a platform "default" marker. if (_pinView == nil) { _pinView = [[MKPinAnnotationView alloc] initWithAnnotation:self reuseIdentifier: nil]; + [self addGestureRecognizerToView:_pinView]; _pinView.annotation = self; } @@ -167,6 +168,56 @@ - (void)showCalloutView animated:YES]; } +#pragma mark - Tap Gesture & Events. + +- (void)addTapGestureRecognizer { + [self addGestureRecognizerToView:nil]; +} + +- (void)addGestureRecognizerToView:(UIView *)view { + if (!view) { + view = self; + } + UITapGestureRecognizer *tapGestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(_handleTap:)]; + // setting this to NO allows the parent MapView to continue receiving marker selection events + tapGestureRecognizer.cancelsTouchesInView = NO; + [view addGestureRecognizer:tapGestureRecognizer]; +} + +- (void)_handleTap:(UITapGestureRecognizer *)recognizer { + AIRMapMarker *marker = self; + if (!marker) return; + + if (marker.selected) { + CGPoint touchPoint = [recognizer locationInView:marker.map.calloutView]; + if ([marker.map.calloutView hitTest:touchPoint withEvent:nil]) { + + // the callout got clicked, not the marker + id event = @{ + @"action": @"callout-press", + }; + + if (marker.onCalloutPress) marker.onCalloutPress(event); + if (marker.calloutView && marker.calloutView.onPress) marker.calloutView.onPress(event); + if (marker.map.onCalloutPress) marker.map.onCalloutPress(event); + return; + } + } + + // the actual marker got clicked + id event = @{ + @"action": @"marker-press", + @"id": marker.identifier ?: @"unknown", + @"coordinate": @{ + @"latitude": @(marker.coordinate.latitude), + @"longitude": @(marker.coordinate.longitude) + } + }; + + if (marker.onPress) marker.onPress(event); + if (marker.map.onMarkerPress) marker.map.onMarkerPress(event); +} + - (void)hideCalloutView { // hide the callout view diff --git a/ios/AirMaps/AIRMapMarkerManager.m b/ios/AirMaps/AIRMapMarkerManager.m index 493d6cc2e..38a6d5a25 100644 --- a/ios/AirMaps/AIRMapMarkerManager.m +++ b/ios/AirMaps/AIRMapMarkerManager.m @@ -25,10 +25,7 @@ @implementation AIRMapMarkerManager - (UIView *)view { AIRMapMarker *marker = [AIRMapMarker new]; - UITapGestureRecognizer *tapGestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(_handleTap:)]; - // setting this to NO allows the parent MapView to continue receiving marker selection events - tapGestureRecognizer.cancelsTouchesInView = NO; - [marker addGestureRecognizer:tapGestureRecognizer]; + [marker addTapGestureRecognizer]; marker.bridge = self.bridge; return marker; } @@ -78,40 +75,4 @@ - (UIView *)view }]; } -#pragma mark - Events - -- (void)_handleTap:(UITapGestureRecognizer *)recognizer { - AIRMapMarker *marker = (AIRMapMarker *)recognizer.view; - if (!marker) return; - - if (marker.selected) { - CGPoint touchPoint = [recognizer locationInView:marker.map.calloutView]; - if ([marker.map.calloutView hitTest:touchPoint withEvent:nil]) { - - // the callout got clicked, not the marker - id event = @{ - @"action": @"callout-press", - }; - - if (marker.onCalloutPress) marker.onCalloutPress(event); - if (marker.calloutView && marker.calloutView.onPress) marker.calloutView.onPress(event); - if (marker.map.onCalloutPress) marker.map.onCalloutPress(event); - return; - } - } - - // the actual marker got clicked - id event = @{ - @"action": @"marker-press", - @"id": marker.identifier ?: @"unknown", - @"coordinate": @{ - @"latitude": @(marker.coordinate.latitude), - @"longitude": @(marker.coordinate.longitude) - } - }; - - if (marker.onPress) marker.onPress(event); - if (marker.map.onMarkerPress) marker.map.onMarkerPress(event); -} - @end From c3e05b58fa7c961948311443b7aa44e32df69820 Mon Sep 17 00:00:00 2001 From: Mike Zou Date: Thu, 12 Jan 2017 13:54:16 -0500 Subject: [PATCH 036/199] Update doc for polyline (#956) Fix the minor error: polygon => polyline --- docs/polyline.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/polyline.md b/docs/polyline.md index c542c4ce3..89ef9de25 100644 --- a/docs/polyline.md +++ b/docs/polyline.md @@ -4,7 +4,7 @@ | Prop | Type | Default | Note | |---|---|---|---| -| `coordinates` | `Array` | (Required) | An array of coordinates to describe the polygon +| `coordinates` | `Array` | (Required) | An array of coordinates to describe the polyline | `strokeWidth` | `Number` | `1` | The stroke width to use for the path. | `strokeColor` | `String` | `#000` | The stroke color to use for the path. | `lineCap` | `String` | `round` | The line cap style to apply to the open ends of the path. From 9384bb62c9733eb39e76dbd39fe916b0d58996d6 Mon Sep 17 00:00:00 2001 From: Nick Italiano Date: Sat, 31 Dec 2016 10:54:39 -0800 Subject: [PATCH 037/199] Added setNativeProps support to shape overlays --- components/MapCircle.js | 6 +- components/MapMarker.js | 4 + components/MapPolygon.js | 6 +- components/MapPolyline.js | 6 +- example/App.js | 2 + example/examples/SetNativePropsOverlays.js | 162 +++++++++++++++++++++ 6 files changed, 183 insertions(+), 3 deletions(-) create mode 100644 example/examples/SetNativePropsOverlays.js diff --git a/components/MapCircle.js b/components/MapCircle.js index 25c97a787..aab1ba8f1 100644 --- a/components/MapCircle.js +++ b/components/MapCircle.js @@ -125,10 +125,14 @@ const defaultProps = { }; class MapCircle extends React.Component { + setNativeProps(props) { + this.circle.setNativeProps(props); + } + render() { const AIRMapCircle = this.getAirComponent(); return ( - + { this.circle = ref; }} /> ); } } diff --git a/components/MapMarker.js b/components/MapMarker.js index 45ed6c300..72adbd767 100644 --- a/components/MapMarker.js +++ b/components/MapMarker.js @@ -212,6 +212,10 @@ class MapMarker extends React.Component { this.hideCallout = this.hideCallout.bind(this); } + setNativeProps(props) { + this.marker.setNativeProps(props); + } + showCallout() { this._runCommand('showCallout', []); } diff --git a/components/MapPolygon.js b/components/MapPolygon.js index 38c972e0c..7baea77db 100644 --- a/components/MapPolygon.js +++ b/components/MapPolygon.js @@ -140,10 +140,14 @@ const defaultProps = { }; class MapPolygon extends React.Component { + setNativeProps(props) { + this.polygon.setNativeProps(props); + } + render() { const AIRMapPolygon = this.getAirComponent(); return ( - + { this.polygon = ref; }} /> ); } } diff --git a/components/MapPolyline.js b/components/MapPolyline.js index 684e1d71d..35b4c6048 100644 --- a/components/MapPolyline.js +++ b/components/MapPolyline.js @@ -130,10 +130,14 @@ const defaultProps = { }; class MapPolyline extends React.Component { + setNativeProps(props) { + this.polyline.setNativeProps(props); + } + render() { const AIRMapPolyline = this.getAirComponent(); return ( - + { this.polyline = ref; }} /> ); } } diff --git a/example/App.js b/example/App.js index 696682ba0..0275f519e 100644 --- a/example/App.js +++ b/example/App.js @@ -33,6 +33,7 @@ import ZIndexMarkers from './examples/ZIndexMarkers'; import StaticMap from './examples/StaticMap'; import MapStyle from './examples/MapStyle'; import LegalLabel from './examples/LegalLabel'; +import SetNativePropsOverlays from './examples/SetNativePropsOverlays'; const IOS = Platform.OS === 'ios'; const ANDROID = Platform.OS === 'android'; @@ -144,6 +145,7 @@ class App extends React.Component { [ZIndexMarkers, 'Position Markers with Z-index', true], [MapStyle, 'Customize the style of the map', true], [LegalLabel, 'Reposition the legal label', true], + [SetNativePropsOverlays, 'Update native props', true], ] // Filter out examples that are not yet supported for Google Maps on iOS. .filter(example => ANDROID || (IOS && (example[2] || !this.state.useGoogleMaps))) diff --git a/example/examples/SetNativePropsOverlays.js b/example/examples/SetNativePropsOverlays.js new file mode 100644 index 000000000..2545c205b --- /dev/null +++ b/example/examples/SetNativePropsOverlays.js @@ -0,0 +1,162 @@ +import React from 'react'; +import { + StyleSheet, + View, + Text, + TouchableOpacity, + Dimensions, +} from 'react-native'; + +import MapView from 'react-native-maps'; + +const { width, height } = Dimensions.get('window'); + +const ASPECT_RATIO = width / height; +const LATITUDE = 37.78825; +const LONGITUDE = -122.4324; +const LATITUDE_DELTA = 0.0922; +const LONGITUDE_DELTA = LATITUDE_DELTA * ASPECT_RATIO; +const SPACE = 0.01; + +class SetNativePropsOverlays extends React.Component { + constructor(props) { + super(props); + + this.state = { + region: { + latitude: LATITUDE, + longitude: LONGITUDE, + latitudeDelta: LATITUDE_DELTA, + longitudeDelta: LONGITUDE_DELTA, + }, + circle: { + center: { + latitude: LATITUDE + SPACE, + longitude: LONGITUDE + SPACE, + }, + radius: 700, + }, + polygon: [ + { + latitude: LATITUDE + SPACE, + longitude: LONGITUDE + SPACE, + }, + { + latitude: LATITUDE - SPACE, + longitude: LONGITUDE - SPACE, + }, + { + latitude: LATITUDE - SPACE, + longitude: LONGITUDE + SPACE, + }, + ], + polyline: [ + { + latitude: LATITUDE + SPACE, + longitude: LONGITUDE - SPACE, + }, + { + latitude: LATITUDE - (2 * SPACE), + longitude: LONGITUDE + (2 * SPACE), + }, + { + latitude: LATITUDE - SPACE, + longitude: LONGITUDE - SPACE, + }, + { + latitude: LATITUDE - (2 * SPACE), + longitude: LONGITUDE - SPACE, + }, + ], + }; + } + + handleColorChange(color) { + const props = { strokeColor: color }; + this.circle.setNativeProps(props); + this.polygon.setNativeProps(props); + this.polyline.setNativeProps(props); + } + + render() { + const { region, circle, polygon, polyline } = this.state; + return ( + + + this.circle = ref} + center={circle.center} + radius={circle.radius} + fillColor="rgba(255, 255, 255, 0.6)" + strokeColor="green" + zIndex={3} + strokeWidth={3} + /> + this.polygon = ref} + coordinates={polygon} + fillColor="rgba(255, 255, 255, 0.6)" + strokeColor="green" + strokeWidth={2} + /> + this.polyline = ref} + coordinates={polyline} + strokeColor="green" + strokeWidth={3} + /> + + + this.handleColorChange('green')}> + + Green + + + this.handleColorChange('black')}> + + Black + + + this.handleColorChange('red')}> + + Red + + + + + ); + } +} + +SetNativePropsOverlays.propTypes = { + provider: MapView.ProviderPropType, +}; + +const styles = StyleSheet.create({ + container: { + ...StyleSheet.absoluteFillObject, + justifyContent: 'flex-end', + alignItems: 'center', + }, + map: { + ...StyleSheet.absoluteFillObject, + }, + bubble: { + flex: 1, + backgroundColor: 'rgba(255,255,255,0.7)', + paddingHorizontal: 18, + paddingVertical: 12, + borderRadius: 20, + }, + buttonContainer: { + flexDirection: 'row', + marginVertical: 20, + backgroundColor: 'transparent', + }, +}); + +module.exports = SetNativePropsOverlays; From fa4d9b05f4ceb2fb764451e70224b48095477e67 Mon Sep 17 00:00:00 2001 From: Nick Italiano Date: Sun, 1 Jan 2017 11:40:10 -0800 Subject: [PATCH 038/199] Added support to nest overlays in views and react components --- .../airbnb/android/react/maps/AirMapView.java | 5 +- example/App.js | 2 + example/examples/CustomOverlay.js | 116 ++++++++++++++++++ ios/AirGoogleMaps/AIRGoogleMap.m | 10 ++ ios/AirMaps/AIRMap.m | 10 ++ 5 files changed, 142 insertions(+), 1 deletion(-) create mode 100644 example/examples/CustomOverlay.js diff --git a/android/src/main/java/com/airbnb/android/react/maps/AirMapView.java b/android/src/main/java/com/airbnb/android/react/maps/AirMapView.java index 5d8de64af..d32942689 100644 --- a/android/src/main/java/com/airbnb/android/react/maps/AirMapView.java +++ b/android/src/main/java/com/airbnb/android/react/maps/AirMapView.java @@ -420,7 +420,10 @@ public void addFeature(View child, int index) { urlTileView.addToMap(map); features.add(index, urlTileView); } else { - // TODO(lmr): throw? User shouldn't be adding non-feature children. + ViewGroup children = (ViewGroup) child; + for (int i = 0; i < children.getChildCount(); i++) { + addFeature(children.getChildAt(i), index); + } } } diff --git a/example/App.js b/example/App.js index 0275f519e..43c39580a 100644 --- a/example/App.js +++ b/example/App.js @@ -34,6 +34,7 @@ import StaticMap from './examples/StaticMap'; import MapStyle from './examples/MapStyle'; import LegalLabel from './examples/LegalLabel'; import SetNativePropsOverlays from './examples/SetNativePropsOverlays'; +import CustomOverlay from './examples/CustomOverlay'; const IOS = Platform.OS === 'ios'; const ANDROID = Platform.OS === 'android'; @@ -146,6 +147,7 @@ class App extends React.Component { [MapStyle, 'Customize the style of the map', true], [LegalLabel, 'Reposition the legal label', true], [SetNativePropsOverlays, 'Update native props', true], + [CustomOverlay, 'Custom Overlay Component', true], ] // Filter out examples that are not yet supported for Google Maps on iOS. .filter(example => ANDROID || (IOS && (example[2] || !this.state.useGoogleMaps))) diff --git a/example/examples/CustomOverlay.js b/example/examples/CustomOverlay.js new file mode 100644 index 000000000..bebe1da25 --- /dev/null +++ b/example/examples/CustomOverlay.js @@ -0,0 +1,116 @@ +import React, { PropTypes } from 'react'; +import { + StyleSheet, + View, + Text, + TouchableOpacity, + Dimensions, +} from 'react-native'; + +import MapView from 'react-native-maps'; + +const { width, height } = Dimensions.get('window'); +const ASPECT_RATIO = width / height; +const LATITUDE = 37.78825; +const LONGITUDE = -122.4324; +const LATITUDE_DELTA = 0.0922; +const LONGITUDE_DELTA = LATITUDE_DELTA * ASPECT_RATIO; +const SPACE = 0.01; + +class XMarksTheSpot extends React.Component { + render() { + return ( + + + + + + + ); + } +} + +XMarksTheSpot.propTypes = { + coordinates: PropTypes.array, + center: PropTypes.object, + zIndex: PropTypes.number, +}; + +class CustomOverlay extends React.Component { + constructor(props) { + super(props); + + this.state = { + region: { + latitude: LATITUDE, + longitude: LONGITUDE, + latitudeDelta: LATITUDE_DELTA, + longitudeDelta: LONGITUDE_DELTA, + }, + coordinates: [ + { + longitude: -122.442753, + latitude: 37.798790, + }, + { + longitude: -122.424728, + latitude: 37.801232, + }, + { + longitude: -122.422497, + latitude: 37.790651, + }, + { + longitude: -122.440693, + latitude: 37.788209, + }, + ], + center: { + longitude: -122.4326648935676, + latitude: 37.79418561114521, + }, + }; + } + + render() { + const { coordinates, center, region } = this.state; + return ( + + + + + + ); + } +} + +CustomOverlay.propTypes = { + provider: MapView.ProviderPropType, +}; + +const styles = StyleSheet.create({ + container: { + ...StyleSheet.absoluteFillObject, + justifyContent: 'flex-end', + alignItems: 'center', + }, + map: { + ...StyleSheet.absoluteFillObject, + }, +}); + +module.exports = CustomOverlay; diff --git a/ios/AirGoogleMaps/AIRGoogleMap.m b/ios/AirGoogleMaps/AIRGoogleMap.m index 39c8bb3a6..e6d028c31 100644 --- a/ios/AirGoogleMaps/AIRGoogleMap.m +++ b/ios/AirGoogleMaps/AIRGoogleMap.m @@ -91,6 +91,11 @@ - (void)insertReactSubview:(id)subview atIndex:(NSInteger)atIndex AIRGoogleMapUrlTile *tile = (AIRGoogleMapUrlTile*)subview; tile.tileLayer.map = self; [self.tiles addObject:tile]; + } else { + NSArray> *childSubviews = [subview reactSubviews]; + for (int i = 0; i < childSubviews.count; i++) { + [self insertReactSubview:(UIView *)childSubviews[i] atIndex:atIndex]; + } } [_reactSubviews insertObject:(UIView *)subview atIndex:(NSUInteger) atIndex]; } @@ -122,6 +127,11 @@ - (void)removeReactSubview:(id)subview { AIRGoogleMapUrlTile *tile = (AIRGoogleMapUrlTile*)subview; tile.tileLayer.map = nil; [self.tiles removeObject:tile]; + } else { + NSArray> *childSubviews = [subview reactSubviews]; + for (int i = 0; i < childSubviews.count; i++) { + [self removeReactSubview:(UIView *)childSubviews[i]]; + } } [_reactSubviews removeObject:(UIView *)subview]; } diff --git a/ios/AirMaps/AIRMap.m b/ios/AirMaps/AIRMap.m index 1126c3825..e1b4d57ee 100644 --- a/ios/AirMaps/AIRMap.m +++ b/ios/AirMaps/AIRMap.m @@ -105,6 +105,11 @@ - (void)insertReactSubview:(id)subview atIndex:(NSInteger)atIndex [self addOverlay:(id)subview]; } else if ([subview isKindOfClass:[AIRMapUrlTile class]]) { [self addOverlay:(id)subview]; + } else { + NSArray> *childSubviews = [subview reactSubviews]; + for (int i = 0; i < childSubviews.count; i++) { + [self insertReactSubview:(UIView *)childSubviews[i] atIndex:atIndex]; + } } [_reactSubviews insertObject:(UIView *)subview atIndex:(NSUInteger) atIndex]; } @@ -125,6 +130,11 @@ - (void)removeReactSubview:(id)subview { [self removeOverlay:(id ) subview]; } else if ([subview isKindOfClass:[AIRMapUrlTile class]]) { [self removeOverlay:(id ) subview]; + } else { + NSArray> *childSubviews = [subview reactSubviews]; + for (int i = 0; i < childSubviews.count; i++) { + [self removeReactSubview:(UIView *)childSubviews[i]]; + } } [_reactSubviews removeObject:(UIView *)subview]; } From b03a27473a455809e7c195bbd005746d88243cd7 Mon Sep 17 00:00:00 2001 From: Nick Italiano Date: Mon, 2 Jan 2017 20:22:17 -0800 Subject: [PATCH 039/199] Added opacity prop to marker --- .../com/airbnb/android/react/maps/AirMapMarker.java | 10 ++++++++++ .../android/react/maps/AirMapMarkerManager.java | 7 +++++++ components/MapMarker.js | 5 +++++ example/examples/MarkerTypes.js | 11 +++++++++++ ios/AirGoogleMaps/AIRGoogleMapMarker.h | 1 + ios/AirGoogleMaps/AIRGoogleMapMarker.m | 5 +++++ ios/AirGoogleMaps/AIRGoogleMapMarkerManager.m | 1 + ios/AirMaps/AIRMapMarker.h | 1 + ios/AirMaps/AIRMapMarker.m | 5 +++++ ios/AirMaps/AIRMapMarkerManager.m | 1 + 10 files changed, 47 insertions(+) diff --git a/android/src/main/java/com/airbnb/android/react/maps/AirMapMarker.java b/android/src/main/java/com/airbnb/android/react/maps/AirMapMarker.java index de01d106e..4041d91ac 100644 --- a/android/src/main/java/com/airbnb/android/react/maps/AirMapMarker.java +++ b/android/src/main/java/com/airbnb/android/react/maps/AirMapMarker.java @@ -62,6 +62,7 @@ public class AirMapMarker extends AirMapFeature { private boolean flat = false; private boolean draggable = false; private int zIndex = 0; + private float opacity = 1.0f; private float calloutAnchorX; private float calloutAnchorY; @@ -182,6 +183,14 @@ public void setZIndex(int zIndex) { update(); } + public void setOpacity(float opacity) { + this.opacity = opacity; + if (marker != null) { + marker.setAlpha(opacity); + } + update(); + } + public void setMarkerHue(float markerHue) { this.markerHue = markerHue; update(); @@ -298,6 +307,7 @@ private MarkerOptions createMarkerOptions() { options.flat(flat); options.draggable(draggable); options.zIndex(zIndex); + options.alpha(opacity); options.icon(getIcon()); return options; } diff --git a/android/src/main/java/com/airbnb/android/react/maps/AirMapMarkerManager.java b/android/src/main/java/com/airbnb/android/react/maps/AirMapMarkerManager.java index f6da4c1cd..e035e1e14 100644 --- a/android/src/main/java/com/airbnb/android/react/maps/AirMapMarkerManager.java +++ b/android/src/main/java/com/airbnb/android/react/maps/AirMapMarkerManager.java @@ -124,6 +124,13 @@ public void setZIndex(AirMapMarker view, float zIndex) { view.setZIndex(integerZIndex); } + @Override + @ReactProp(name = "opacity", defaultFloat = 1.0f) + public void setOpacity(AirMapMarker view, float opacity) { + super.setOpacity(view, opacity); + view.setOpacity(opacity); + } + @Override public void addView(AirMapMarker parent, View child, int index) { // if an component is a child, then it is a callout view, NOT part of the diff --git a/components/MapMarker.js b/components/MapMarker.js index 72adbd767..be54e42db 100644 --- a/components/MapMarker.js +++ b/components/MapMarker.js @@ -48,6 +48,11 @@ const propTypes = { */ image: PropTypes.any, + /** + * Opacity level of view/image based markers + */ + opacity: PropTypes.number, + /** * If no custom marker view or custom image is provided, the platform default pin will be used, * which can be customized by this color. Ignored if a custom marker is being used. diff --git a/example/examples/MarkerTypes.js b/example/examples/MarkerTypes.js index 7bf3a6465..76685d782 100644 --- a/example/examples/MarkerTypes.js +++ b/example/examples/MarkerTypes.js @@ -62,6 +62,17 @@ class MarkerTypes extends React.Component { anchor={{ x: 0.84, y: 1 }} image={this.state.marker2 ? flagBlueImg : flagPinkImg} /> + this.setState({ marker2: !this.state.marker2 })} + coordinate={{ + latitude: LATITUDE + SPACE, + longitude: LONGITUDE - SPACE, + }} + centerOffset={{ x: -42, y: -60 }} + anchor={{ x: 0.84, y: 1 }} + opacity={0.6} + image={this.state.marker2 ? flagBlueImg : flagPinkImg} + />
); diff --git a/ios/AirGoogleMaps/AIRGoogleMapMarker.h b/ios/AirGoogleMaps/AIRGoogleMapMarker.h index ca6a5cc12..36190e7cb 100644 --- a/ios/AirGoogleMaps/AIRGoogleMapMarker.h +++ b/ios/AirGoogleMaps/AIRGoogleMapMarker.h @@ -28,6 +28,7 @@ @property (nonatomic, strong) UIColor *pinColor; @property (nonatomic, assign) CGPoint anchor; @property (nonatomic, assign) NSInteger zIndex; +@property (nonatomic, assign) double opacity; @property (nonatomic, assign) BOOL draggable; - (void)showCalloutView; diff --git a/ios/AirGoogleMaps/AIRGoogleMapMarker.m b/ios/AirGoogleMaps/AIRGoogleMapMarker.m index 4bb10dede..2c6080e9e 100644 --- a/ios/AirGoogleMaps/AIRGoogleMapMarker.m +++ b/ios/AirGoogleMaps/AIRGoogleMapMarker.m @@ -173,6 +173,11 @@ - (RCTBubblingEventBlock)onPress { return _realMarker.onPress; } +- (void)setOpacity:(double)opacity +{ + _realMarker.opacity = opacity; +} + - (void)setImageSrc:(NSString *)imageSrc { _imageSrc = imageSrc; diff --git a/ios/AirGoogleMaps/AIRGoogleMapMarkerManager.m b/ios/AirGoogleMaps/AIRGoogleMapMarkerManager.m index 0d29c3fac..fd16f58a6 100644 --- a/ios/AirGoogleMaps/AIRGoogleMapMarkerManager.m +++ b/ios/AirGoogleMaps/AIRGoogleMapMarkerManager.m @@ -36,6 +36,7 @@ - (UIView *)view RCT_EXPORT_VIEW_PROPERTY(anchor, CGPoint) RCT_EXPORT_VIEW_PROPERTY(zIndex, NSInteger) RCT_EXPORT_VIEW_PROPERTY(draggable, BOOL) +RCT_EXPORT_VIEW_PROPERTY(opacity, double) RCT_EXPORT_VIEW_PROPERTY(onDragStart, RCTDirectEventBlock) RCT_EXPORT_VIEW_PROPERTY(onDrag, RCTDirectEventBlock) RCT_EXPORT_VIEW_PROPERTY(onDragEnd, RCTDirectEventBlock) diff --git a/ios/AirMaps/AIRMapMarker.h b/ios/AirMaps/AIRMapMarker.h index 97440639f..f92a06789 100644 --- a/ios/AirMaps/AIRMapMarker.h +++ b/ios/AirMaps/AIRMapMarker.h @@ -33,6 +33,7 @@ @property (nonatomic, assign) CLLocationCoordinate2D coordinate; @property (nonatomic, strong) UIColor *pinColor; @property (nonatomic, assign) NSInteger zIndex; +@property (nonatomic, assign) double opacity; @property (nonatomic, copy) RCTBubblingEventBlock onPress; @property (nonatomic, copy) RCTDirectEventBlock onSelect; diff --git a/ios/AirMaps/AIRMapMarker.m b/ios/AirMaps/AIRMapMarker.m index 2d7d086d4..e26574706 100644 --- a/ios/AirMaps/AIRMapMarker.m +++ b/ios/AirMaps/AIRMapMarker.m @@ -203,6 +203,11 @@ - (BOOL)shouldUsePinView return self.reactSubviews.count == 0 && !self.imageSrc; } +- (void)setOpacity:(double)opacity +{ + [self setAlpha:opacity]; +} + - (void)setImageSrc:(NSString *)imageSrc { _imageSrc = imageSrc; diff --git a/ios/AirMaps/AIRMapMarkerManager.m b/ios/AirMaps/AIRMapMarkerManager.m index 493d6cc2e..3d8b16627 100644 --- a/ios/AirMaps/AIRMapMarkerManager.m +++ b/ios/AirMaps/AIRMapMarkerManager.m @@ -44,6 +44,7 @@ - (UIView *)view RCT_EXPORT_VIEW_PROPERTY(pinColor, UIColor) RCT_EXPORT_VIEW_PROPERTY(draggable, BOOL) RCT_EXPORT_VIEW_PROPERTY(zIndex, NSInteger) +RCT_EXPORT_VIEW_PROPERTY(opacity, double) RCT_EXPORT_VIEW_PROPERTY(onPress, RCTBubblingEventBlock) RCT_EXPORT_VIEW_PROPERTY(onSelect, RCTDirectEventBlock) From 106cc02b1bfdb60ba36735f759205beb7fd3d546 Mon Sep 17 00:00:00 2001 From: Nick Italiano Date: Sun, 15 Jan 2017 14:11:30 -0800 Subject: [PATCH 040/199] Lint --- example/examples/CustomOverlay.js | 37 ++----------------- .../examples/CustomOverlayXMarksTheSpot.js | 34 +++++++++++++++++ example/examples/SetNativePropsOverlays.js | 12 +++--- 3 files changed, 43 insertions(+), 40 deletions(-) create mode 100644 example/examples/CustomOverlayXMarksTheSpot.js diff --git a/example/examples/CustomOverlay.js b/example/examples/CustomOverlay.js index bebe1da25..c57f83ff7 100644 --- a/example/examples/CustomOverlay.js +++ b/example/examples/CustomOverlay.js @@ -1,13 +1,12 @@ -import React, { PropTypes } from 'react'; +import React from 'react'; import { StyleSheet, View, - Text, - TouchableOpacity, Dimensions, } from 'react-native'; import MapView from 'react-native-maps'; +import XMarksTheSpot from './CustomOverlayXMarksTheSpot'; const { width, height } = Dimensions.get('window'); const ASPECT_RATIO = width / height; @@ -15,36 +14,6 @@ const LATITUDE = 37.78825; const LONGITUDE = -122.4324; const LATITUDE_DELTA = 0.0922; const LONGITUDE_DELTA = LATITUDE_DELTA * ASPECT_RATIO; -const SPACE = 0.01; - -class XMarksTheSpot extends React.Component { - render() { - return ( - - - - - - - ); - } -} - -XMarksTheSpot.propTypes = { - coordinates: PropTypes.array, - center: PropTypes.object, - zIndex: PropTypes.number, -}; class CustomOverlay extends React.Component { constructor(props) { @@ -91,7 +60,7 @@ class CustomOverlay extends React.Component { style={styles.map} initialRegion={region} > - + ); diff --git a/example/examples/CustomOverlayXMarksTheSpot.js b/example/examples/CustomOverlayXMarksTheSpot.js new file mode 100644 index 000000000..ada19da9c --- /dev/null +++ b/example/examples/CustomOverlayXMarksTheSpot.js @@ -0,0 +1,34 @@ +import React, { PropTypes } from 'react'; +import { View } from 'react-native'; +import MapView from 'react-native-maps'; + +class XMarksTheSpot extends React.Component { + render() { + return ( + + + + + + + ); + } +} + +XMarksTheSpot.propTypes = { + coordinates: PropTypes.array, + center: PropTypes.object, + zIndex: PropTypes.number, +}; + +export default XMarksTheSpot; diff --git a/example/examples/SetNativePropsOverlays.js b/example/examples/SetNativePropsOverlays.js index 2545c205b..b0dac9a80 100644 --- a/example/examples/SetNativePropsOverlays.js +++ b/example/examples/SetNativePropsOverlays.js @@ -88,7 +88,7 @@ class SetNativePropsOverlays extends React.Component { initialRegion={region} > this.circle = ref} + ref={ref => { this.circle = ref; }} center={circle.center} radius={circle.radius} fillColor="rgba(255, 255, 255, 0.6)" @@ -97,31 +97,31 @@ class SetNativePropsOverlays extends React.Component { strokeWidth={3} /> this.polygon = ref} + ref={ref => { this.polygon = ref; }} coordinates={polygon} fillColor="rgba(255, 255, 255, 0.6)" strokeColor="green" strokeWidth={2} /> this.polyline = ref} + ref={ref => { this.polyline = ref; }} coordinates={polyline} strokeColor="green" strokeWidth={3} /> - this.handleColorChange('green')}> + { this.handleColorChange('green'); }}> Green - this.handleColorChange('black')}> + { this.handleColorChange('black'); }}> Black - this.handleColorChange('red')}> + { this.handleColorChange('red'); }}> Red From db7178667843241bc8768f9fe51a4667e9ddc8c1 Mon Sep 17 00:00:00 2001 From: Osman Hernandez Date: Wed, 18 Jan 2017 10:54:07 -0600 Subject: [PATCH 041/199] Update circle.md (#973) --- docs/circle.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/circle.md b/docs/circle.md index 78a850283..706237c18 100644 --- a/docs/circle.md +++ b/docs/circle.md @@ -9,6 +9,7 @@ | `strokeWidth` | `Number` | `1` | The stroke width to use for the path. | `strokeColor` | `String` | `#000` | The stroke color to use for the path. | `fillColor` | `String` | | The fill color to use for the path. +| `zIndex` | `Number` | 0 | The order in which this tile overlay is drawn with respect to other overlays. An overlay with a larger z-index is drawn over overlays with smaller z-indices. The order of overlays with the same z-index is arbitrary. The default zIndex is 0. (Android Only) | `lineCap` | `String` | `round` | The line cap style to apply to the open ends of the path. | `lineJoin` | `Array` | | The line join style to apply to corners of the path. | `miterLimit` | `Number` | | The limiting value that helps avoid spikes at junctions between connected line segments. The miter limit helps you avoid spikes in paths that use the `miter` `lineJoin` style. If the ratio of the miter length—that is, the diagonal length of the miter join—to the line thickness exceeds the miter limit, the joint is converted to a bevel join. The default miter limit is 10, which results in the conversion of miters whose angle at the joint is less than 11 degrees. From aafec80185a1b0ea5eb6cede99cdf39ea4c89c7f Mon Sep 17 00:00:00 2001 From: Paulo Cesar Date: Wed, 18 Jan 2017 13:56:35 -0300 Subject: [PATCH 042/199] Update mapview.md (#961) add non-optional `animated` parameter to the docs --- docs/mapview.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/mapview.md b/docs/mapview.md index f05867bd2..bfab08e7d 100644 --- a/docs/mapview.md +++ b/docs/mapview.md @@ -57,7 +57,7 @@ | `animateToRegion` | `region: Region`, `duration: Number` | | `animateToCoordinate` | `region: Coordinate`, `duration: Number` | | `fitToElements` | `animated: Boolean` | -| `fitToSuppliedMarkers` | `markerIDs: String[]` | If you need to use this in `ComponentDidMount`, make sure you put it in a timeout or it will cause performance problems. +| `fitToSuppliedMarkers` | `markerIDs: String[]`, `animated: Boolean` | If you need to use this in `ComponentDidMount`, make sure you put it in a timeout or it will cause performance problems. | `fitToCoordinates` | `coordinates: Array, options: { edgePadding: EdgePadding, animated: Boolean }` | @@ -112,4 +112,4 @@ type EdgeInsets { bottom: Number, right: Number } -``` \ No newline at end of file +``` From b42cca90b04d8660d0a94e9444d7e4df9b7a2b91 Mon Sep 17 00:00:00 2001 From: Vince Yuan Date: Thu, 19 Jan 2017 00:58:55 +0800 Subject: [PATCH 043/199] Update doc to show how to add GoogleMaps support for iOS. (#950) --- docs/installation.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/installation.md b/docs/installation.md index a236fbda1..5f85b14db 100644 --- a/docs/installation.md +++ b/docs/installation.md @@ -22,10 +22,10 @@ react-native link 1. Setup your `Podfile` like the included [example/ios/Podfile](../example/ios/Podfile), replace all references to `AirMapExplorer` with your project name, and then run `pod install`. (If you do not need `GoogleMaps` support for iOS, then you can probably completely skip this step.) 1. Open your project in Xcode workspace -1. Drag the following folder into your project: - - `node_modules/react-native-maps/ios/AirMaps/` -1. If you need `GoogleMaps` support also drag this folder into your project: - - `node_modules/react-native-maps/ios/AirGoogleMaps/` +1. If you need `GoogleMaps` support also + - Drag this folder `node_modules/react-native-maps/ios/AirGoogleMaps/` into your project, and choose `Create groups` in the popup window. + - In `AppDelegate.m`, add `@import GoogleMaps;` before `@implementation AppDelegate`. In `- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions`, add `[GMSServices provideAPIKey:@"YOUR_GOOGLE_MAP_API_KEY"];` + - In your project's `Build Settings` > `Header Search Paths`, double click the value field. In the popup, add `$(SRCROOT)/../node_modules/react-native-maps/ios/AirMaps` and change `non-recursive` to `recursive`. (Dragging the folder `node_modules/react-native-maps/ios/AirMaps/` into your project introduces duplicate symbols. We should not do it.) ### Option 2: CocoaPods This is now considered the **old way** because it will only work if you **don't** have From 98440253977a12075f914720b2d756ac2c04974b Mon Sep 17 00:00:00 2001 From: Marton Bodonyi Date: Thu, 19 Jan 2017 03:59:17 +1100 Subject: [PATCH 044/199] Add Android SDK Build tools 23.03 to troubleshooting (#945) This adds Android SDK Build-tools 23.0.3 to the troubleshooting section for Android. This is required because react-native documentation (https://facebook.github.io/react-native/docs/getting-started.html) only specifies a requirement of Build-tools 23.0.1. The build error if you don't have 23.0.3 installed is ``` A problem occurred configuring project ':app'. > A problem occurred configuring project ':react-native-maps'. > Failed to notify project evaluation listener. > failed to find Build Tools revision 23.0.3 > failed to find Build Tools revision 23.0.3 ``` --- docs/installation.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/installation.md b/docs/installation.md index 5f85b14db..10a3dfa20 100644 --- a/docs/installation.md +++ b/docs/installation.md @@ -189,6 +189,7 @@ You have to link dependencies with rnpm and re-run the build: - Extras / Google Play services - Extras / Google Repository - Android 6.0 (API 23) / Google APIs Intel x86 Atom System Image Rev. 19 + - Android SDK Build-tools 23.0.3 1. Check manual installation steps if you didn't run "react-native link" 1. Go to [Google API Console](https://console.developers.google.com/flows/enableapi?apiid=maps_android_backend) and select your project, or create one. Then, once enabled, select `Go to credentials`. From c55092808aa0d159a44119299cdbb792a7517518 Mon Sep 17 00:00:00 2001 From: Marton Bodonyi Date: Thu, 19 Jan 2017 04:01:18 +1100 Subject: [PATCH 045/199] Update installation.md (#947) Added troubleshooting step for enabling Use Host GPU checkbox in AVD settings. It appears that Google Maps requires Open GL to be enabled and working on devices for it to draw the map. See https://github.com/airbnb/react-native-maps/issues/942 --- docs/installation.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/installation.md b/docs/installation.md index 10a3dfa20..d73c4011e 100644 --- a/docs/installation.md +++ b/docs/installation.md @@ -212,3 +212,5 @@ Enter the name of the API key and create it. gradlew clean cd .. ``` + +1. If you are using Android Virtual Devices (AVD), ensure that `Use Host GPU` is checked in the settings for your virtual device. From de43e5d0a5733188a2ea908ba8dadabd9410e71a Mon Sep 17 00:00:00 2001 From: jschloer Date: Mon, 23 Jan 2017 13:41:58 -0500 Subject: [PATCH 046/199] Sets the map value for the AirMapUrlTile so that it can be updated properly. --- ios/AirMaps/AIRMap.m | 1 + 1 file changed, 1 insertion(+) diff --git a/ios/AirMaps/AIRMap.m b/ios/AirMaps/AIRMap.m index 1126c3825..286be275a 100644 --- a/ios/AirMaps/AIRMap.m +++ b/ios/AirMaps/AIRMap.m @@ -104,6 +104,7 @@ - (void)insertReactSubview:(id)subview atIndex:(NSInteger)atIndex } else if ([subview isKindOfClass:[AIRMapCircle class]]) { [self addOverlay:(id)subview]; } else if ([subview isKindOfClass:[AIRMapUrlTile class]]) { + ((AIRMapUrlTile *)subview).map = self; [self addOverlay:(id)subview]; } [_reactSubviews insertObject:(UIView *)subview atIndex:(NSUInteger) atIndex]; From 9d52855f84f016bff16dc5e014de8697dcedc84d Mon Sep 17 00:00:00 2001 From: Lucas Bento Date: Tue, 31 Jan 2017 22:26:09 -0200 Subject: [PATCH 047/199] Fix typo on Android installation (#1004) --- docs/installation.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/installation.md b/docs/installation.md index d73c4011e..195124e02 100644 --- a/docs/installation.md +++ b/docs/installation.md @@ -73,7 +73,7 @@ After your `Podfile` is setup properly, run `pod install`. } ``` - If you have a different play serivces than the one included in this library, use the following instead (switch 10.0.1 for the desired version): + If you have a different play services than the one included in this library, use the following instead (switch 10.0.1 for the desired version): ```groovy ... From eccf876d8717613692ef8ea55cbc713dcbe4aa3d Mon Sep 17 00:00:00 2001 From: alexbelyeu Date: Tue, 31 Jan 2017 19:26:24 -0500 Subject: [PATCH 048/199] Update installation.md (#989) The link to the instructions for having Google Play Services installed in your sim is now outdated and Genymotion recently provided easy steps to follow. --- docs/installation.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/installation.md b/docs/installation.md index 195124e02..5a394322f 100644 --- a/docs/installation.md +++ b/docs/installation.md @@ -114,7 +114,7 @@ After your `Podfile` is setup properly, run `pod install`. Source: https://developers.google.com/maps/documentation/android-api/signup 1. Ensure that you have Google Play Services installed: - * For Genymotion you can follow [these instructions](http://stackoverflow.com/a/20137324/1424349). + * For Genymotion you can follow [these instructions](https://www.genymotion.com/help/desktop/faq/#google-play-services). * For a physical device you need to search on Google for 'Google Play Services'. There will be a link that takes you to the Play Store and from there you will see a button to update it (do not search within the Play Store). ## Troubleshooting From 571fbb53cc6d22f3ff946246d08382ce572990ed Mon Sep 17 00:00:00 2001 From: gilbox Date: Mon, 21 Nov 2016 14:55:36 -0800 Subject: [PATCH 049/199] [android] Create example for marker not updating bug --- example/App.js | 2 + example/examples/BugMarkerWontUpdate.js | 134 ++++++++++++++++++ example/examples/MyLocationMapMarker.js | 179 ++++++++++++++++++++++++ example/package.json | 1 + 4 files changed, 316 insertions(+) create mode 100644 example/examples/BugMarkerWontUpdate.js create mode 100644 example/examples/MyLocationMapMarker.js diff --git a/example/App.js b/example/App.js index 43c39580a..dadbea056 100644 --- a/example/App.js +++ b/example/App.js @@ -35,6 +35,7 @@ import MapStyle from './examples/MapStyle'; import LegalLabel from './examples/LegalLabel'; import SetNativePropsOverlays from './examples/SetNativePropsOverlays'; import CustomOverlay from './examples/CustomOverlay'; +import BugMarkerWontUpdate from './examples/BugMarkerWontUpdate'; const IOS = Platform.OS === 'ios'; const ANDROID = Platform.OS === 'android'; @@ -148,6 +149,7 @@ class App extends React.Component { [LegalLabel, 'Reposition the legal label', true], [SetNativePropsOverlays, 'Update native props', true], [CustomOverlay, 'Custom Overlay Component', true], + [BugMarkerWontUpdate, 'BUG: Marker Won\'t Update (Android)', true], ] // Filter out examples that are not yet supported for Google Maps on iOS. .filter(example => ANDROID || (IOS && (example[2] || !this.state.useGoogleMaps))) diff --git a/example/examples/BugMarkerWontUpdate.js b/example/examples/BugMarkerWontUpdate.js new file mode 100644 index 000000000..8bf62ffca --- /dev/null +++ b/example/examples/BugMarkerWontUpdate.js @@ -0,0 +1,134 @@ +import React from 'react'; +import { + StyleSheet, + View, + Text, + Dimensions, + TouchableOpacity, +} from 'react-native'; +import MapView from 'react-native-maps'; +import MyLocationMapMarker from './MyLocationMapMarker'; + +const { width, height } = Dimensions.get('window'); + +const ASPECT_RATIO = width / height; +const LATITUDE = 37.78825; +const LONGITUDE = -122.4324; +const LATITUDE_DELTA = 0.0922; +const LONGITUDE_DELTA = LATITUDE_DELTA * ASPECT_RATIO; + +class BugMarkerWontUpdate extends React.Component { + constructor(props) { + super(props); + + this.state = { + region: { + latitude: LATITUDE, + longitude: LONGITUDE, + latitudeDelta: LATITUDE_DELTA, + longitudeDelta: LONGITUDE_DELTA, + }, + coordinate: { + latitude: LATITUDE, + longitude: LONGITUDE, + }, + amount: 0, + enableHack: false, + }; + } + + increment() { + this.setState({ amount: this.state.amount + 10 }); + } + + decrement() { + this.setState({ amount: this.state.amount - 10 }); + } + + toggleHack() { + this.setState({ enableHack: !this.state.enableHack }); + } + + render() { + return ( + + + + + + this.toggleHack()} + style={[styles.bubble, styles.button, styles.hackButton]} + > + + {this.state.enableHack ? 'Disable Hack' : 'Enable Hack'} + + + + + this.decrement()} + style={[styles.bubble, styles.button]} + > + - + + this.increment()} + style={[styles.bubble, styles.button]} + > + + + + + + ); + } +} + +BugMarkerWontUpdate.propTypes = { + provider: MapView.ProviderPropType, +}; + +const styles = StyleSheet.create({ + container: { + ...StyleSheet.absoluteFillObject, + justifyContent: 'flex-end', + alignItems: 'center', + }, + map: { + ...StyleSheet.absoluteFillObject, + }, + bubble: { + backgroundColor: 'rgba(255,255,255,0.7)', + paddingHorizontal: 18, + paddingVertical: 12, + borderRadius: 20, + }, + latlng: { + width: 200, + alignItems: 'stretch', + }, + button: { + width: 80, + paddingHorizontal: 12, + alignItems: 'center', + marginHorizontal: 10, + }, + hackButton: { + width: 200, + }, + buttonContainer: { + flexDirection: 'row', + marginVertical: 20, + backgroundColor: 'transparent', + }, +}); + +module.exports = BugMarkerWontUpdate; diff --git a/example/examples/MyLocationMapMarker.js b/example/examples/MyLocationMapMarker.js new file mode 100644 index 000000000..fff3f2b37 --- /dev/null +++ b/example/examples/MyLocationMapMarker.js @@ -0,0 +1,179 @@ +import React, { PropTypes } from 'react'; +import { + StyleSheet, + Text, + View, + PermissionsAndroid, + Platform, +} from 'react-native'; +import MapView from 'react-native-maps'; +import isEqual from 'lodash/isEqual'; + +const GEOLOCATION_OPTIONS = { enableHighAccuracy: true, timeout: 20000, maximumAge: 1000 }; +const ANCHOR = { x: 0.5, y: 0.5 }; + +const colorOfmyLocationMapMarker = 'blue'; + +const propTypes = { + ...MapView.Marker.propTypes, + // override this prop to make it optional + coordinate: PropTypes.shape({ + latitude: PropTypes.number.isRequired, + longitude: PropTypes.number.isRequired, + }), + children: PropTypes.node, + geolocationOptions: PropTypes.shape({ + enableHighAccuracy: PropTypes.bool, + timeout: PropTypes.number, + maximumAge: PropTypes.number, + }), + heading: PropTypes.number, + enableHack: PropTypes.bool, +}; + +const defaultProps = { + enableHack: false, + geolocationOptions: GEOLOCATION_OPTIONS, +}; + +export default class MyLocationMapMarker extends React.PureComponent { + constructor(props) { + super(props); + this.mounted = false; + this.state = { + myPosition: null, + }; + } + componentDidMount() { + this.mounted = true; + // If you supply a coordinate prop, we won't try to track location automatically + if (this.props.coordinate) return; + + if (Platform.OS === 'android') { + PermissionsAndroid.requestPermission(PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION) + .then(granted => { + if (granted && this.mounted) this.watchLocation(); + }); + } else { + this.watchLocation(); + } + } + watchLocation() { + // eslint-disable-next-line no-undef + this.watchID = navigator.geolocation.watchPosition((position) => { + const myLastPosition = this.state.myPosition; + const myPosition = position.coords; + if (!isEqual(myPosition, myLastPosition)) { + this.setState({ myPosition }); + } + }, null, this.props.geolocationOptions); + } + componentWillUnmount() { + this.mounted = false; + // eslint-disable-next-line no-undef + if (this.watchID) navigator.geolocation.clearWatch(this.watchID); + } + render() { + let { heading, coordinate } = this.props; + if (!coordinate) { + const { myPosition } = this.state; + if (!myPosition) return null; + coordinate = myPosition; + heading = myPosition.heading; + } + + const rotate = (typeof heading === 'number' && heading >= 0) ? `${heading}deg` : null; + + return ( + + + + {rotate && + + + + } + + + {this.props.enableHack && rotate} + + + + {this.props.children} + + ); + } +} + +const SIZE = 35; +const HALO_RADIUS = 6; +const ARROW_SIZE = 7; +const ARROW_DISTANCE = 6; +const HALO_SIZE = SIZE + HALO_RADIUS; +const HEADING_BOX_SIZE = HALO_SIZE + ARROW_SIZE + ARROW_DISTANCE; + +const styles = StyleSheet.create({ + mapMarker: { + zIndex: 1000, + }, + // The container is necessary to protect the markerHalo shadow from clipping + container: { + width: HEADING_BOX_SIZE, + height: HEADING_BOX_SIZE, + }, + heading: { + position: 'absolute', + top: 0, + left: 0, + width: HEADING_BOX_SIZE, + height: HEADING_BOX_SIZE, + alignItems: 'center', + }, + headingPointer: { + width: 0, + height: 0, + backgroundColor: 'transparent', + borderStyle: 'solid', + borderTopWidth: 0, + borderRightWidth: ARROW_SIZE * 0.75, + borderBottomWidth: ARROW_SIZE, + borderLeftWidth: ARROW_SIZE * 0.75, + borderTopColor: 'transparent', + borderRightColor: 'transparent', + borderBottomColor: colorOfmyLocationMapMarker, + borderLeftColor: 'transparent', + }, + markerHalo: { + position: 'absolute', + backgroundColor: 'white', + top: 0, + left: 0, + width: HALO_SIZE, + height: HALO_SIZE, + borderRadius: Math.ceil(HALO_SIZE / 2), + margin: (HEADING_BOX_SIZE - HALO_SIZE) / 2, + shadowColor: 'black', + shadowOpacity: 0.25, + shadowRadius: 2, + shadowOffset: { + height: 0, + width: 0, + }, + }, + marker: { + justifyContent: 'center', + backgroundColor: colorOfmyLocationMapMarker, + width: SIZE, + height: SIZE, + borderRadius: Math.ceil(SIZE / 2), + margin: (HEADING_BOX_SIZE - SIZE) / 2, + }, +}); + +MyLocationMapMarker.propTypes = propTypes; +MyLocationMapMarker.defaultProps = defaultProps; diff --git a/example/package.json b/example/package.json index eca9884a4..378bd5578 100644 --- a/example/package.json +++ b/example/package.json @@ -9,6 +9,7 @@ "dev": "concurrently 'npm run watch' 'npm run packager'" }, "dependencies": { + "lodash": "^4.17.2", "react": "~15.4.1", "react-native": "^0.40.0", "react-native-maps": "file:../" From 2ff4f8c9fbdc1f65fff318896f02f24178e7e748 Mon Sep 17 00:00:00 2001 From: Spike Brehm Date: Wed, 1 Feb 2017 16:14:57 -0800 Subject: [PATCH 050/199] Fix copyright in README --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 05ed75170..8322d0fcf 100644 --- a/README.md +++ b/README.md @@ -476,7 +476,7 @@ Good: License -------- - Copyright (c) 2015 Leland Richardson + Copyright (c) 2015 Airbnb Licensed under the The MIT License (MIT) (the "License"); you may not use this file except in compliance with the License. From b5e49c5dd5516a07bff1e8ad10bf8aabeb7f1514 Mon Sep 17 00:00:00 2001 From: Spike Brehm Date: Wed, 1 Feb 2017 16:28:19 -0800 Subject: [PATCH 051/199] Clean up MapView#_onLayout a bit. DRY it up and simplify. --- components/MapView.js | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/components/MapView.js b/components/MapView.js index 0195e694c..16755d68c 100644 --- a/components/MapView.js +++ b/components/MapView.js @@ -424,19 +424,15 @@ class MapView extends React.Component { } _onLayout(e) { - const { region, initialRegion, onLayout } = this.props; - const { isReady } = this.state; - const { layout } = e.nativeEvent; - if (!layout.width || !layout.height) return; - if (region && isReady && !this.__layoutCalled) { - this.__layoutCalled = true; - this.map.setNativeProps({ region }); - } else if (initialRegion && isReady && !this.__layoutCalled) { - this.__layoutCalled = true; - this.map.setNativeProps({ region: initialRegion }); + if (this.state.isReady && !this.__layoutCalled) { + const region = this.props.region || this.props.initialRegion; + if (region) { + this.__layoutCalled = true; + this.map.setNativeProps({ region }); + } } - if (onLayout) { - onLayout(e); + if (this.props.onLayout) { + this.props.onLayout(e); } } From 91bd30e32f7c882b5b24c331694e318eaebbf082 Mon Sep 17 00:00:00 2001 From: Spike Brehm Date: Wed, 1 Feb 2017 16:32:05 -0800 Subject: [PATCH 052/199] Add on layout.width/height check --- components/MapView.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/components/MapView.js b/components/MapView.js index 16755d68c..a4d316a72 100644 --- a/components/MapView.js +++ b/components/MapView.js @@ -424,6 +424,8 @@ class MapView extends React.Component { } _onLayout(e) { + const { layout } = e.nativeEvent; + if (!layout.width || !layout.height) return; if (this.state.isReady && !this.__layoutCalled) { const region = this.props.region || this.props.initialRegion; if (region) { From 80e8b77551224f1c8b17479a56f5a063bde79cbe Mon Sep 17 00:00:00 2001 From: Spike Brehm Date: Wed, 1 Feb 2017 17:58:08 -0800 Subject: [PATCH 053/199] Create `update-version` script to more easily update version Similar to `npm version`, but updates the version number in all the files we need to. Usage: ./scripts/update-version.js [major|minor|patch] It will: * Get current npm version. * Determine what type of version bump: major, minor, patch * Update the files: * package.json * android/gradle.properties * react-native-maps.podspec * react-native-google-maps.podspec * Make Git commit. * Create Git tag. --- package.json | 5 +- scripts/update-version.js | 105 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 109 insertions(+), 1 deletion(-) create mode 100755 scripts/update-version.js diff --git a/package.json b/package.json index 016a69c97..77f519ffd 100644 --- a/package.json +++ b/package.json @@ -27,12 +27,15 @@ }, "devDependencies": { "babel-eslint": "^6.1.2", + "commander": "^2.9.0", + "dedent": "^0.7.0", "eslint": "^3.3.1", "eslint-config-airbnb": "^10.0.1", "eslint-plugin-import": "^1.14.0", "eslint-plugin-jsx-a11y": "^2.1.0", "eslint-plugin-prefer-object-spread": "^1.1.0", - "eslint-plugin-react": "^6.1.2" + "eslint-plugin-react": "^6.1.2", + "semver": "^5.3.0" }, "rnpm": { "android": { diff --git a/scripts/update-version.js b/scripts/update-version.js new file mode 100755 index 000000000..8e949b08f --- /dev/null +++ b/scripts/update-version.js @@ -0,0 +1,105 @@ +#!/usr/bin/env node + +/* + +* Get current npm version. +* Determine what type of version bump: major, minor, patch +* Update the files: + * package.json + * android/gradle.properties + * react-native-maps.podspec + * react-native-google-maps.podspec +* Make Git commit. +* Create Git tag. + +*/ + +// TODO: update eslint-plugin-import so we can configure +// `import/no-extraneous-dependencies` to allow devDependencies in `scripts/`. + +const { exec } = require('child_process'); +// eslint-disable-next-line import/no-extraneous-dependencies +const commander = require('commander'); +// eslint-disable-next-line import/no-extraneous-dependencies +const dedent = require('dedent'); +// eslint-disable-next-line import/no-extraneous-dependencies +const semver = require('semver'); +const pkg = require('../package.json'); + +const versionTypes = ['major', 'minor', 'patch']; +const filesToUpdate = [ + 'package.json', + 'android/gradle.properties', + 'react-native-maps.podspec', + 'react-native-google-maps.podspec', +]; + +commander + .version(pkg.version) + .arguments('') + .action(versionType => { + if (!versionTypes.includes(versionType)) { + die(dedent`Version type "${versionType}" not recognized. + Supported values: ${versionTypes.map(v => `"${v}"`).join(', ')}.`); + } + bumpVersion(pkg.version, versionType).catch(err => { + process.stderr.write(`${err.stack}\n`); + }); + }); + +commander.parse(process.argv); + +function die(message) { + process.stderr.write(message); + process.exit(1); +} + +function doExec(cmdString) { + return new Promise((resolve, reject) => { + exec(cmdString, (err, stdout) => { + if (err) { + reject(err); + return; + } + resolve(stdout); + }); + }); +} + +function bumpVersion(currentVersion, versionType) { + const nextVersion = semver.inc(currentVersion, versionType); + process.stdout.write(`Updating version from ${currentVersion} to ${nextVersion}...\n`); + + return Promise.resolve() + .then(() => updateFiles(currentVersion, nextVersion)) + .then(() => createCommit(nextVersion)) + .then(() => createTag(nextVersion)) + ; +} + +function updateFiles(currentVersion, nextVersion) { + return Promise.all(filesToUpdate.map(relativePath => + updateVersionInFile(currentVersion, nextVersion, relativePath) + )); +} + +function createCommit(nextVersion) { + return doExec(`git commit -am ${nextVersion}`); +} + +function createTag(nextVersion) { + return doExec(`git tag v${nextVersion}`); +} + +function updateVersionInFile(currentVersion, nextVersion, relativePath) { + process.stdout.write(`-> ${relativePath}\n`); + return doExec(`sed -i '' 's/${ + escapeDots(currentVersion) + }/${ + escapeDots(nextVersion) + }/g' ./${relativePath}`); +} + +function escapeDots(version) { + return version.replace(/\./g, '\\.'); +} From bec405d55bdc1ae7bbf10e56c769e089d1a8f3e5 Mon Sep 17 00:00:00 2001 From: Martin Ledgard Date: Thu, 2 Feb 2017 20:43:51 +0000 Subject: [PATCH 054/199] update animateToCoordinate arguments (#1018) --- docs/mapview.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/mapview.md b/docs/mapview.md index bfab08e7d..ed8ecb71d 100644 --- a/docs/mapview.md +++ b/docs/mapview.md @@ -55,7 +55,7 @@ | Method Name | Arguments | Notes |---|---|---| | `animateToRegion` | `region: Region`, `duration: Number` | -| `animateToCoordinate` | `region: Coordinate`, `duration: Number` | +| `animateToCoordinate` | `coordinate: LatLng`, `duration: Number` | | `fitToElements` | `animated: Boolean` | | `fitToSuppliedMarkers` | `markerIDs: String[]`, `animated: Boolean` | If you need to use this in `ComponentDidMount`, make sure you put it in a timeout or it will cause performance problems. | `fitToCoordinates` | `coordinates: Array, options: { edgePadding: EdgePadding, animated: Boolean }` | From 88a7e0320862e076e81a73e96c73f44f6b529493 Mon Sep 17 00:00:00 2001 From: Cesar alonso Date: Thu, 2 Feb 2017 16:52:42 -0600 Subject: [PATCH 055/199] Add showsIndoorLevelPicker options for MapView --- .../java/com/airbnb/android/react/maps/AirMapManager.java | 7 ++++++- components/MapView.js | 8 ++++++++ docs/mapview.md | 1 + 3 files changed, 15 insertions(+), 1 deletion(-) diff --git a/android/src/main/java/com/airbnb/android/react/maps/AirMapManager.java b/android/src/main/java/com/airbnb/android/react/maps/AirMapManager.java index 75ed5777f..2f11319a5 100644 --- a/android/src/main/java/com/airbnb/android/react/maps/AirMapManager.java +++ b/android/src/main/java/com/airbnb/android/react/maps/AirMapManager.java @@ -93,7 +93,7 @@ public void setMapType(AirMapView view, @Nullable String mapType) { int typeId = MAP_TYPES.get(mapType); view.map.setMapType(typeId); } - + @ReactProp(name = "customMapStyleString") public void setMapStyle(AirMapView view, @Nullable String customMapStyleString) { view.map.setMapStyle(new MapStyleOptions(customMapStyleString)); @@ -135,6 +135,11 @@ public void setShowIndoors(AirMapView view, boolean showIndoors) { view.map.setIndoorEnabled(showIndoors); } + @ReactProp(name = "showsIndoorLevelPicker", defaultBoolean = false) + public void setShowsIndoorLevelPicker(AirMapView view, boolean showsIndoorLevelPicker) { + view.map.getUiSettings().setIndoorLevelPickerEnabled(showsIndoorLevelPicker); + } + @ReactProp(name = "showsCompass", defaultBoolean = false) public void setShowsCompass(AirMapView view, boolean showsCompass) { view.map.getUiSettings().setCompassEnabled(showsCompass); diff --git a/components/MapView.js b/components/MapView.js index 0195e694c..b857fcb1b 100644 --- a/components/MapView.js +++ b/components/MapView.js @@ -217,6 +217,14 @@ const propTypes = { */ showsIndoors: PropTypes.bool, + /** + * A Boolean indicating whether indoor level picker should be enabled. + * Default value is `false` + * + * @platform android + */ + showsIndoorLevelPicker: PropTypes.bool, + /** * The map type to be displayed. * diff --git a/docs/mapview.md b/docs/mapview.md index bfab08e7d..caa89403e 100644 --- a/docs/mapview.md +++ b/docs/mapview.md @@ -18,6 +18,7 @@ | `showsBuildings` | `Boolean` | `true` | A Boolean indicating whether the map displays extruded building information. | `showsTraffic` | `Boolean` | `true` | A Boolean value indicating whether the map displays traffic information. | `showsIndoors` | `Boolean` | `true` | A Boolean indicating whether indoor maps should be enabled. +| `showsIndoorLevelPicker` | `Boolean` | `false` | A Boolean indicating whether indoor level picker should be enabled. | `zoomEnabled` | `Boolean` | `true` | If `false` the user won't be able to pinch/zoom the map. | `rotateEnabled` | `Boolean` | `true` | If `false` the user won't be able to pinch/rotate the map. | `scrollEnabled` | `Boolean` | `true` | If `false` the user won't be able to change the map region being displayed. From 5c80a5c3998087e6d91535cae3268c597cf24f59 Mon Sep 17 00:00:00 2001 From: Gerardo Pacheco Date: Sun, 5 Feb 2017 20:08:54 +0100 Subject: [PATCH 056/199] [iOS] Added onPress support for Polygons on Google Maps --- components/MapPolygon.js | 6 ++++++ example/examples/EventListener.js | 1 + .../AirMapsExplorer.xcodeproj/project.pbxproj | 6 ++++++ ios/AirGoogleMaps/AIRGMSPolygon.h | 16 ++++++++++++++++ ios/AirGoogleMaps/AIRGMSPolygon.m | 12 ++++++++++++ ios/AirGoogleMaps/AIRGoogleMap.h | 1 + ios/AirGoogleMaps/AIRGoogleMap.m | 10 ++++++++++ ios/AirGoogleMaps/AIRGoogleMapManager.m | 5 +++++ ios/AirGoogleMaps/AIRGoogleMapPolygon.h | 8 +++++++- ios/AirGoogleMaps/AIRGoogleMapPolygon.m | 13 ++++++++++++- ios/AirGoogleMaps/AIRGoogleMapPolygonManager.m | 3 +++ 11 files changed, 79 insertions(+), 2 deletions(-) create mode 100644 ios/AirGoogleMaps/AIRGMSPolygon.h create mode 100644 ios/AirGoogleMaps/AIRGMSPolygon.m diff --git a/components/MapPolygon.js b/components/MapPolygon.js index 7baea77db..6901979db 100644 --- a/components/MapPolygon.js +++ b/components/MapPolygon.js @@ -37,6 +37,12 @@ const propTypes = { */ onPress: PropTypes.func, + /** + * Boolean to allow a polygon to be tappable and use the + * onPress function + */ + tappable: PropTypes.bool, + /** * The stroke width to use for the path. */ diff --git a/example/examples/EventListener.js b/example/examples/EventListener.js index 0876c621d..005894a0d 100644 --- a/example/examples/EventListener.js +++ b/example/examples/EventListener.js @@ -130,6 +130,7 @@ class EventListener extends React.Component { +#import "UIView+React.h" + +@class AIRGoogleMapPolygon; + +@interface AIRGMSPolygon : GMSPolygon +@property (nonatomic, strong) NSString *identifier; +@property (nonatomic, copy) RCTBubblingEventBlock onPress; +@end diff --git a/ios/AirGoogleMaps/AIRGMSPolygon.m b/ios/AirGoogleMaps/AIRGMSPolygon.m new file mode 100644 index 000000000..05de0b029 --- /dev/null +++ b/ios/AirGoogleMaps/AIRGMSPolygon.m @@ -0,0 +1,12 @@ +// +// AIRGMSPolygon.m +// AirMaps +// +// Created by Gerardo Pacheco 02/05/2017. +// + +#import "AIRGMSPolygon.h" + +@implementation AIRGMSPolygon + +@end diff --git a/ios/AirGoogleMaps/AIRGoogleMap.h b/ios/AirGoogleMaps/AIRGoogleMap.h index 925aa4746..1dcc830ec 100644 --- a/ios/AirGoogleMaps/AIRGoogleMap.h +++ b/ios/AirGoogleMaps/AIRGoogleMap.h @@ -40,6 +40,7 @@ @property (nonatomic, assign) BOOL showsUserLocation; - (BOOL)didTapMarker:(GMSMarker *)marker; +- (void)didTapPolygon:(GMSPolygon *)polygon; - (void)didTapAtCoordinate:(CLLocationCoordinate2D)coordinate; - (void)didLongPressAtCoordinate:(CLLocationCoordinate2D)coordinate; - (void)didChangeCameraPosition:(GMSCameraPosition *)position; diff --git a/ios/AirGoogleMaps/AIRGoogleMap.m b/ios/AirGoogleMaps/AIRGoogleMap.m index e6d028c31..1d0ecd252 100644 --- a/ios/AirGoogleMaps/AIRGoogleMap.m +++ b/ios/AirGoogleMaps/AIRGoogleMap.m @@ -170,6 +170,16 @@ - (BOOL)didTapMarker:(GMSMarker *)marker { return NO; } +- (void)didTapPolygon:(GMSOverlay *)polygon { + AIRGMSPolygon *airPolygon = (AIRGMSPolygon *)polygon; + + id event = @{@"action": @"polygon-press", + @"id": airPolygon.identifier ?: @"unknown", + }; + + if (airPolygon.onPress) airPolygon.onPress(event); +} + - (void)didTapAtCoordinate:(CLLocationCoordinate2D)coordinate { if (!self.onPress) return; self.onPress([self eventFromCoordinate:coordinate]); diff --git a/ios/AirGoogleMaps/AIRGoogleMapManager.m b/ios/AirGoogleMaps/AIRGoogleMapManager.m index e306de1d8..b903d6b3a 100644 --- a/ios/AirGoogleMaps/AIRGoogleMapManager.m +++ b/ios/AirGoogleMaps/AIRGoogleMapManager.m @@ -202,6 +202,11 @@ - (BOOL)mapView:(GMSMapView *)mapView didTapMarker:(GMSMarker *)marker { return [googleMapView didTapMarker:marker]; } +- (void)mapView:(GMSMapView *)mapView didTapOverlay:(GMSPolygon *)polygon { + AIRGoogleMap *googleMapView = (AIRGoogleMap *)mapView; + [googleMapView didTapPolygon:polygon]; +} + - (void)mapView:(GMSMapView *)mapView didTapAtCoordinate:(CLLocationCoordinate2D)coordinate { AIRGoogleMap *googleMapView = (AIRGoogleMap *)mapView; [googleMapView didTapAtCoordinate:coordinate]; diff --git a/ios/AirGoogleMaps/AIRGoogleMapPolygon.h b/ios/AirGoogleMaps/AIRGoogleMapPolygon.h index 12a207128..e7719ebee 100644 --- a/ios/AirGoogleMaps/AIRGoogleMapPolygon.h +++ b/ios/AirGoogleMaps/AIRGoogleMapPolygon.h @@ -5,18 +5,24 @@ // #import +#import +#import "AIRGMSPolygon.h" #import "AIRMapCoordinate.h" @interface AIRGoogleMapPolygon : UIView -@property (nonatomic, strong) GMSPolygon *polygon; +@property (nonatomic, weak) RCTBridge *bridge; +@property (nonatomic, strong) NSString *identifier; +@property (nonatomic, strong) AIRGMSPolygon *polygon; @property (nonatomic, strong) NSArray *coordinates; @property (nonatomic, strong) NSArray *> *holes; +@property (nonatomic, copy) RCTBubblingEventBlock onPress; @property (nonatomic, assign) UIColor *fillColor; @property (nonatomic, assign) double strokeWidth; @property (nonatomic, assign) UIColor *strokeColor; @property (nonatomic, assign) BOOL geodesic; @property (nonatomic, assign) int zIndex; +@property (nonatomic, assign) BOOL tappable; @end diff --git a/ios/AirGoogleMaps/AIRGoogleMapPolygon.m b/ios/AirGoogleMaps/AIRGoogleMapPolygon.m index ea31b5008..bbd5d99c9 100644 --- a/ios/AirGoogleMaps/AIRGoogleMapPolygon.m +++ b/ios/AirGoogleMaps/AIRGoogleMapPolygon.m @@ -5,6 +5,7 @@ // #import "AIRGoogleMapPolygon.h" +#import "AIRGMSPolygon.h" #import @implementation AIRGoogleMapPolygon @@ -12,7 +13,7 @@ @implementation AIRGoogleMapPolygon - (instancetype)init { if (self = [super init]) { - _polygon = [[GMSPolygon alloc] init]; + _polygon = [[AIRGMSPolygon alloc] init]; } return self; @@ -82,4 +83,14 @@ -(void)setZIndex:(int)zIndex _polygon.zIndex = zIndex; } +-(void)setTappable:(BOOL)tappable +{ + _tappable = tappable; + _polygon.tappable = tappable; +} + +- (void)setOnPress:(RCTBubblingEventBlock)onPress { + _polygon.onPress = onPress; +} + @end diff --git a/ios/AirGoogleMaps/AIRGoogleMapPolygonManager.m b/ios/AirGoogleMaps/AIRGoogleMapPolygonManager.m index 5c7ce2a66..a946d3b7a 100644 --- a/ios/AirGoogleMaps/AIRGoogleMapPolygonManager.m +++ b/ios/AirGoogleMaps/AIRGoogleMapPolygonManager.m @@ -25,6 +25,7 @@ @implementation AIRGoogleMapPolygonManager - (UIView *)view { AIRGoogleMapPolygon *polygon = [AIRGoogleMapPolygon new]; + polygon.bridge = self.bridge; return polygon; } @@ -35,5 +36,7 @@ - (UIView *)view RCT_EXPORT_VIEW_PROPERTY(strokeColor, UIColor) RCT_EXPORT_VIEW_PROPERTY(geodesic, BOOL) RCT_EXPORT_VIEW_PROPERTY(zIndex, int) +RCT_EXPORT_VIEW_PROPERTY(tappable, BOOL) +RCT_EXPORT_VIEW_PROPERTY(onPress, RCTBubblingEventBlock) @end From ada2961f2b5af89d9255200cbb88233f80db34e3 Mon Sep 17 00:00:00 2001 From: Spike Brehm Date: Mon, 6 Feb 2017 17:25:11 -0800 Subject: [PATCH 057/199] Integrate better with `npm version` --- package.json | 3 +- scripts/update-version.js | 101 +++++++++++++------------------------- 2 files changed, 36 insertions(+), 68 deletions(-) diff --git a/package.json b/package.json index 77f519ffd..0e788ec48 100644 --- a/package.json +++ b/package.json @@ -6,7 +6,8 @@ "version": "0.13.0", "scripts": { "start": "react-native start", - "lint": "eslint ." + "lint": "eslint .", + "preversion": "./scripts/update-version.js" }, "repository": { "type": "git", diff --git a/scripts/update-version.js b/scripts/update-version.js index 8e949b08f..f8f840ea7 100755 --- a/scripts/update-version.js +++ b/scripts/update-version.js @@ -1,59 +1,25 @@ #!/usr/bin/env node -/* - -* Get current npm version. -* Determine what type of version bump: major, minor, patch -* Update the files: - * package.json - * android/gradle.properties - * react-native-maps.podspec - * react-native-google-maps.podspec -* Make Git commit. -* Create Git tag. - +/** + * Script that runs as part of `npm version`. It updates any files that have a + * reference to the current package version: + * + * - android/gradle.properties + * - react-native-maps.podspec + * - react-native-google-maps.podspec + * + * And `git add`s them. */ -// TODO: update eslint-plugin-import so we can configure -// `import/no-extraneous-dependencies` to allow devDependencies in `scripts/`. - const { exec } = require('child_process'); -// eslint-disable-next-line import/no-extraneous-dependencies -const commander = require('commander'); -// eslint-disable-next-line import/no-extraneous-dependencies -const dedent = require('dedent'); -// eslint-disable-next-line import/no-extraneous-dependencies -const semver = require('semver'); const pkg = require('../package.json'); -const versionTypes = ['major', 'minor', 'patch']; const filesToUpdate = [ - 'package.json', 'android/gradle.properties', 'react-native-maps.podspec', 'react-native-google-maps.podspec', ]; -commander - .version(pkg.version) - .arguments('') - .action(versionType => { - if (!versionTypes.includes(versionType)) { - die(dedent`Version type "${versionType}" not recognized. - Supported values: ${versionTypes.map(v => `"${v}"`).join(', ')}.`); - } - bumpVersion(pkg.version, versionType).catch(err => { - process.stderr.write(`${err.stack}\n`); - }); - }); - -commander.parse(process.argv); - -function die(message) { - process.stderr.write(message); - process.exit(1); -} - function doExec(cmdString) { return new Promise((resolve, reject) => { exec(cmdString, (err, stdout) => { @@ -66,40 +32,41 @@ function doExec(cmdString) { }); } -function bumpVersion(currentVersion, versionType) { - const nextVersion = semver.inc(currentVersion, versionType); - process.stdout.write(`Updating version from ${currentVersion} to ${nextVersion}...\n`); +function updateVersionInFile(currentVersion, nextVersion, relativePath) { + process.stdout.write(`• ${relativePath}\n`); + return doExec(`sed -i '' 's/${ + escapeDots(currentVersion) + }/${ + escapeDots(nextVersion) + }/g' ./${relativePath}`); +} + +function escapeDots(version) { + return version.replace(/\./g, '\\.'); +} - return Promise.resolve() +function run() { + const currentVersion = pkg.version; + const nextVersion = process.env.npm_package_version; + + Promise.resolve() .then(() => updateFiles(currentVersion, nextVersion)) - .then(() => createCommit(nextVersion)) - .then(() => createTag(nextVersion)) - ; + .then(() => gitAdd()); } +// Tasks + function updateFiles(currentVersion, nextVersion) { + process.stdout.write(`Updating ${currentVersion} ➞ ${nextVersion}:\n`); return Promise.all(filesToUpdate.map(relativePath => updateVersionInFile(currentVersion, nextVersion, relativePath) )); } -function createCommit(nextVersion) { - return doExec(`git commit -am ${nextVersion}`); +function gitAdd() { + return doExec(`git add ${filesToUpdate.join(' ')}`); } -function createTag(nextVersion) { - return doExec(`git tag v${nextVersion}`); -} +// Do it. -function updateVersionInFile(currentVersion, nextVersion, relativePath) { - process.stdout.write(`-> ${relativePath}\n`); - return doExec(`sed -i '' 's/${ - escapeDots(currentVersion) - }/${ - escapeDots(nextVersion) - }/g' ./${relativePath}`); -} - -function escapeDots(version) { - return version.replace(/\./g, '\\.'); -} +run(); From fce2e66ad8b31edae3fbb0a726d5e4886012699d Mon Sep 17 00:00:00 2001 From: Spike Brehm Date: Mon, 6 Feb 2017 18:24:22 -0800 Subject: [PATCH 058/199] Remove unused dependencies --- package.json | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/package.json b/package.json index 0e788ec48..5741fe8bd 100644 --- a/package.json +++ b/package.json @@ -28,15 +28,12 @@ }, "devDependencies": { "babel-eslint": "^6.1.2", - "commander": "^2.9.0", - "dedent": "^0.7.0", "eslint": "^3.3.1", "eslint-config-airbnb": "^10.0.1", "eslint-plugin-import": "^1.14.0", "eslint-plugin-jsx-a11y": "^2.1.0", "eslint-plugin-prefer-object-spread": "^1.1.0", - "eslint-plugin-react": "^6.1.2", - "semver": "^5.3.0" + "eslint-plugin-react": "^6.1.2" }, "rnpm": { "android": { From 1c50e7fceadb9863979b9ec90b4d93d50814a428 Mon Sep 17 00:00:00 2001 From: "Rachel P.Y. Liao" Date: Mon, 20 Feb 2017 17:59:54 +0800 Subject: [PATCH 059/199] add customized user location annotation title --- components/MapView.js | 9 +++++++++ ios/AirMaps/AIRMap.h | 1 + ios/AirMaps/AIRMapManager.m | 8 ++++++++ 3 files changed, 18 insertions(+) diff --git a/components/MapView.js b/components/MapView.js index a4d316a72..4f93db019 100644 --- a/components/MapView.js +++ b/components/MapView.js @@ -86,6 +86,15 @@ const propTypes = { */ showsUserLocation: PropTypes.bool, + /** + * The title of the annotation for current user location. This only works if + * `showsUserLocation` is true. + * There is a default value `My Location` set by MapView. + * + * @platform ios + */ + userLocationAnnotationTitle: PropTypes.string, + /** * If `false` hide the button to move map to the current user's location. * Default value is `true`. diff --git a/ios/AirMaps/AIRMap.h b/ios/AirMaps/AIRMap.h index fd4ed0f25..5c9695466 100644 --- a/ios/AirMaps/AIRMap.h +++ b/ios/AirMaps/AIRMap.h @@ -24,6 +24,7 @@ extern const CGFloat AIRMapZoomBoundBuffer; @property (nonatomic, strong) UIImageView *cacheImageView; @property (nonatomic, strong) UIView *loadingView; +@property (nonatomic, copy) NSString *userLocationAnnotationTitle; @property (nonatomic, assign) BOOL followUserLocation; @property (nonatomic, assign) BOOL hasStartedRendering; @property (nonatomic, assign) BOOL cacheEnabled; diff --git a/ios/AirMaps/AIRMapManager.m b/ios/AirMaps/AIRMapManager.m index 91a7f3ef9..3a1e6e947 100644 --- a/ios/AirMaps/AIRMapManager.m +++ b/ios/AirMaps/AIRMapManager.m @@ -65,6 +65,7 @@ - (UIView *)view } RCT_EXPORT_VIEW_PROPERTY(showsUserLocation, BOOL) +RCT_EXPORT_VIEW_PROPERTY(userLocationAnnotationTitle, NSString) RCT_EXPORT_VIEW_PROPERTY(followsUserLocation, BOOL) RCT_EXPORT_VIEW_PROPERTY(showsPointsOfInterest, BOOL) RCT_EXPORT_VIEW_PROPERTY(showsBuildings, BOOL) @@ -491,7 +492,10 @@ - (void)mapView:(AIRMap *)mapView didSelectAnnotationView:(MKAnnotationView *)vi { if ([view.annotation isKindOfClass:[AIRMapMarker class]]) { [(AIRMapMarker *)view.annotation showCalloutView]; + } else if ([view.annotation isKindOfClass:[MKUserLocation class]] && mapView.userLocationAnnotationTitle != nil && view.annotation.title != mapView.userLocationAnnotationTitle) { + [(MKUserLocation*)view.annotation setTitle: mapView.userLocationAnnotationTitle]; } + } - (void)mapView:(AIRMap *)mapView didDeselectAnnotationView:(MKAnnotationView *)view { @@ -503,6 +507,10 @@ - (void)mapView:(AIRMap *)mapView didDeselectAnnotationView:(MKAnnotationView *) - (MKAnnotationView *)mapView:(__unused AIRMap *)mapView viewForAnnotation:(AIRMapMarker *)marker { if (![marker isKindOfClass:[AIRMapMarker class]]) { + if ([marker isKindOfClass:[MKUserLocation class]] && mapView.userLocationAnnotationTitle != nil) { + [(MKUserLocation*)marker setTitle: mapView.userLocationAnnotationTitle]; + return nil; + } return nil; } From 01564bd051bcebb86464c3afba7df012b7f2e687 Mon Sep 17 00:00:00 2001 From: "Rachel P.Y. Liao" Date: Mon, 20 Feb 2017 18:19:00 +0800 Subject: [PATCH 060/199] Update MapView doc --- docs/mapview.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/mapview.md b/docs/mapview.md index ed8ecb71d..53a5dcaae 100644 --- a/docs/mapview.md +++ b/docs/mapview.md @@ -10,6 +10,7 @@ | `liteMode` | `Boolean` | `false` | Enable lite mode. **Note**: Android only. | `mapType` | `String` | `"standard"` | The map type to be displayed.

- standard: standard road map (default)
- satellite: satellite view
- hybrid: satellite view with roads and points of interest overlayed
- terrain: (Android only) topographic view | `showsUserLocation` | `Boolean` | `false` | If `true` the app will ask for the user's location. **NOTE**: You need to add `NSLocationWhenInUseUsageDescription` key in Info.plist to enable geolocation, otherwise it is going to *fail silently*! +| `userLocationAnnotationTitle` | `String` | | The title of the annotation for current user location. This only works if `showsUserLocation` is true. There is a default value `My Location` set by MapView. **Note**: iOS only. | `followsUserLocation` | `Boolean` | `false` | If `true` the map will focus on the user's location. This only works if `showsUserLocation` is true and the user has shared their location. **Note**: iOS only. | `showsMyLocationButton` | `Boolean` | `true` | `Android only` If `false` hide the button to move map to the current user's location. | `showsPointsOfInterest` | `Boolean` | `true` | If `false` points of interest won't be displayed on the map. From bc85512af7f3424cf028b3279f2dc03f93c729a6 Mon Sep 17 00:00:00 2001 From: Yonah Forst Date: Fri, 3 Mar 2017 17:31:10 +0100 Subject: [PATCH 061/199] addresses #436 --- ios/AirMaps/AIRMapMarker.m | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ios/AirMaps/AIRMapMarker.m b/ios/AirMaps/AIRMapMarker.m index 608198c50..8be20784e 100644 --- a/ios/AirMaps/AIRMapMarker.m +++ b/ios/AirMaps/AIRMapMarker.m @@ -216,6 +216,8 @@ - (void)_handleTap:(UITapGestureRecognizer *)recognizer { if (marker.onPress) marker.onPress(event); if (marker.map.onMarkerPress) marker.map.onMarkerPress(event); + + [marker.map selectAnnotation:marker animated:NO]; } - (void)hideCalloutView From d53d93eb9eb44d38a8f7757274edda4293085873 Mon Sep 17 00:00:00 2001 From: Grey Vugrin Date: Sat, 4 Mar 2017 10:48:15 -0800 Subject: [PATCH 062/199] Improve documentation of customMapStyle (#1085) * Improve documentation of customMapStyle Readme addition described in https://github.com/airbnb/react-native-maps/issues/881. * Add customMapStyle prop to MapView doc --- README.md | 18 ++++++++++++++++++ docs/mapview.md | 1 + 2 files changed, 19 insertions(+) diff --git a/README.md b/README.md index 8322d0fcf..41139a4a0 100644 --- a/README.md +++ b/README.md @@ -190,6 +190,24 @@ render() { ); } ``` +For iOS, in addition to providing the `mapStyle` you will need to do the following + +```jsx +import MapView, { PROVIDER_GOOGLE } from 'react-native-maps' + +// ... + + +``` + +Then add the AirGoogleMaps directory: + +https://github.com/airbnb/react-native-maps/blob/1e71a21f39e7b88554852951f773c731c94680c9/docs/installation.md#ios + +An unoffical step-by-step guide is also available at https://gist.github.com/heron2014/e60fa003e9b117ce80d56bb1d5bfe9e0 ## Examples diff --git a/docs/mapview.md b/docs/mapview.md index ed8ecb71d..3c6dd08c4 100644 --- a/docs/mapview.md +++ b/docs/mapview.md @@ -9,6 +9,7 @@ | `initialRegion` | `Region` | | The initial region to be displayed by the map. Use this prop instead of `region` only if you don't want to control the viewport of the map besides the initial region.

Changing this prop after the component has mounted will not result in a region change.

This is similar to the `initialValue` prop of a text input. | `liteMode` | `Boolean` | `false` | Enable lite mode. **Note**: Android only. | `mapType` | `String` | `"standard"` | The map type to be displayed.

- standard: standard road map (default)
- satellite: satellite view
- hybrid: satellite view with roads and points of interest overlayed
- terrain: (Android only) topographic view +| `customMapStyle` | `Array` | | Adds custom styling to the map component. See [README](https://github.com/airbnb/react-native-maps#customizing-the-map-style) for more information. | `showsUserLocation` | `Boolean` | `false` | If `true` the app will ask for the user's location. **NOTE**: You need to add `NSLocationWhenInUseUsageDescription` key in Info.plist to enable geolocation, otherwise it is going to *fail silently*! | `followsUserLocation` | `Boolean` | `false` | If `true` the map will focus on the user's location. This only works if `showsUserLocation` is true and the user has shared their location. **Note**: iOS only. | `showsMyLocationButton` | `Boolean` | `true` | `Android only` If `false` hide the button to move map to the current user's location. From 536d11f8dd778900a9c5b53eea543a3b9d3907ba Mon Sep 17 00:00:00 2001 From: Guillaume DROULEZ Date: Tue, 7 Mar 2017 10:52:32 +0100 Subject: [PATCH 063/199] Crash in our App fix java.lang.NullPointerException: Attempt to invoke virtual method 'com.google.android.gms.maps.Projection com.google.android.gms.maps.GoogleMap.getProjection()' on a null object reference at com.airbnb.android.react.maps.AirMapView$13.run(AirMapView.java:643) at android.os.Handler.handleCallback(Handler.java:739) at android.os.Handler.dispatchMessage(Handler.java:95) at android.os.Looper.loop(Looper.java:135) at android.app.ActivityThread.main(ActivityThread.java:5289) at java.lang.reflect.Method.invoke(Native Method) at java.lang.reflect.Method.invoke(Method.java:372) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.ja va:899) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694) --- .../java/com/airbnb/android/react/maps/AirMapView.java | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/android/src/main/java/com/airbnb/android/react/maps/AirMapView.java b/android/src/main/java/com/airbnb/android/react/maps/AirMapView.java index 632e568bc..646b318be 100644 --- a/android/src/main/java/com/airbnb/android/react/maps/AirMapView.java +++ b/android/src/main/java/com/airbnb/android/react/maps/AirMapView.java @@ -41,6 +41,7 @@ import com.google.android.gms.maps.model.Marker; import com.google.android.gms.maps.model.Polygon; import com.google.android.gms.maps.model.Polyline; +import com.google.android.gms.maps.model.VisibleRegion; import java.util.ArrayList; import java.util.Arrays; @@ -646,9 +647,12 @@ public void stopMonitoringRegion() { @Override public void run() { - LatLngBounds bounds = map.getProjection().getVisibleRegion().latLngBounds; - if (lastBoundsEmitted == null || - LatLngBoundsUtils.BoundsAreDifferent(bounds, lastBoundsEmitted)) { + Projection projection = map.getProjection(); + VisibleRegion region = (projection != null) ? projection.getVisibleRegion() : null; + LatLngBounds bounds = (region != null) ? region.latLngBounds : null; + + if ((bounds != null) && + (lastBoundsEmitted == null || LatLngBoundsUtils.BoundsAreDifferent(bounds, lastBoundsEmitted))) { LatLng center = map.getCameraPosition().target; lastBoundsEmitted = bounds; eventDispatcher.dispatchEvent(new RegionChangeEvent(getId(), bounds, center, true)); From cbbea86127350ccbe58e780668ec4c7f56bdd940 Mon Sep 17 00:00:00 2001 From: Christian Mitchell Date: Wed, 8 Mar 2017 11:30:26 +1300 Subject: [PATCH 064/199] Updated Google play services and gradle build plugin (#1023) * Updated Gradle build version * Updated Google Play Services --- android/build.gradle | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/android/build.gradle b/android/build.gradle index d6e86e557..740017fad 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -18,7 +18,7 @@ buildscript { } } dependencies { - classpath 'com.android.tools.build:gradle:2.1.0' + classpath 'com.android.tools.build:gradle:2.2.3' } } @@ -39,12 +39,12 @@ allprojects { } android { - compileSdkVersion 23 + compileSdkVersion 25 buildToolsVersion "23.0.3" defaultConfig { minSdkVersion 16 - targetSdkVersion 23 + targetSdkVersion 25 } lintOptions { @@ -54,6 +54,6 @@ android { dependencies { compile "com.facebook.react:react-native:+" - compile "com.google.android.gms:play-services-base:9.8.0" - compile "com.google.android.gms:play-services-maps:9.8.0" + compile "com.google.android.gms:play-services-base:10.0.1" + compile "com.google.android.gms:play-services-maps:10.0.1" } From a2dfedfb36c164da9e15862a9f6ba75ee988008b Mon Sep 17 00:00:00 2001 From: allthetime Date: Tue, 7 Mar 2017 15:12:11 -0800 Subject: [PATCH 065/199] specify `react-native link` command (#1086) `react-native link react-native-maps` should be used instead of simply `react-native link` because it may break, or double, manual linkings, especially for libraries that that do not work with `react-native link` (gl-react-native for example) --- docs/installation.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/installation.md b/docs/installation.md index 5a394322f..49f37fd85 100644 --- a/docs/installation.md +++ b/docs/installation.md @@ -10,7 +10,7 @@ Second, install the native dependencies: You can use `rnpm` (now part of `react- add native dependencies automatically then continue the directions below depending on your target OS. ``` -react-native link +react-native link react-native-maps ``` >This installation should work in physical devices. For Genymotion, be sure to check Android installation about Google Play Services @@ -63,7 +63,7 @@ After your `Podfile` is setup properly, run `pod install`. ## Android 1. In your `android/app/build.gradle` add: - >This step is not necessary if you ran "react-native link" + >This step is not necessary if you ran "react-native link react-native-maps" ```groovy ... @@ -125,13 +125,13 @@ If you have a blank map issue, ([#118](https://github.com/airbnb/react-native-ma You have to link dependencies with rnpm and re-run the build: -1. `react-native link` +1. `react-native link react-native-maps` 1. `react-native run-ios` ### On Android: 1. Be sure to have `new MapsPackage()` in your `MainApplication.java` : - >This step is not necessary if you ran "react-native link" + >This step is not necessary if you ran "react-native link react-native-maps" ``` import com.airbnb.android.react.maps.MapsPackage; @@ -190,7 +190,7 @@ You have to link dependencies with rnpm and re-run the build: - Extras / Google Repository - Android 6.0 (API 23) / Google APIs Intel x86 Atom System Image Rev. 19 - Android SDK Build-tools 23.0.3 -1. Check manual installation steps if you didn't run "react-native link" +1. Check manual installation steps if you didn't run "react-native link react-native-maps" 1. Go to [Google API Console](https://console.developers.google.com/flows/enableapi?apiid=maps_android_backend) and select your project, or create one. Then, once enabled, select `Go to credentials`. Select `Google Maps Android API` and create a new key. From dfa01ccae99c56fef50b6f2746e4ff7c72d6424d Mon Sep 17 00:00:00 2001 From: Grey Vugrin Date: Tue, 7 Mar 2017 15:12:40 -0800 Subject: [PATCH 066/199] Mention rgba option for polygons in docs (#1084) * Mention rgba option for polygon colors Courtesy of https://github.com/airbnb/react-native-maps/issues/183 * Added rgba mention to circle doc --- docs/circle.md | 4 ++-- docs/polygon.md | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/circle.md b/docs/circle.md index 706237c18..70a5e078e 100644 --- a/docs/circle.md +++ b/docs/circle.md @@ -7,8 +7,8 @@ | `center` | `LatLng` | (Required) | The coordinate of the center of the circle | `radius` | `Number` | (Required) | The radius of the circle to be drawn (in meters) | `strokeWidth` | `Number` | `1` | The stroke width to use for the path. -| `strokeColor` | `String` | `#000` | The stroke color to use for the path. -| `fillColor` | `String` | | The fill color to use for the path. +| `strokeColor` | `String` | `#000`, `rgba(r,g,b,0.5)` | The stroke color to use for the path. +| `fillColor` | `String` | `#000`, `rgba(r,g,b,0.5)` | The fill color to use for the path. | `zIndex` | `Number` | 0 | The order in which this tile overlay is drawn with respect to other overlays. An overlay with a larger z-index is drawn over overlays with smaller z-indices. The order of overlays with the same z-index is arbitrary. The default zIndex is 0. (Android Only) | `lineCap` | `String` | `round` | The line cap style to apply to the open ends of the path. | `lineJoin` | `Array` | | The line join style to apply to corners of the path. diff --git a/docs/polygon.md b/docs/polygon.md index 875327a81..085b31a18 100644 --- a/docs/polygon.md +++ b/docs/polygon.md @@ -6,8 +6,8 @@ |---|---|---|---| | `coordinates` | `Array` | (Required) | An array of coordinates to describe the polygon | `strokeWidth` | `Number` | `1` | The stroke width to use for the path. -| `strokeColor` | `String` | `#000` | The stroke color to use for the path. -| `fillColor` | `String` | | The fill color to use for the path. +| `strokeColor` | `String` | `#000`, `rgba(r,g,b,0.5)` | The stroke color to use for the path. +| `fillColor` | `String` | `#000`, `rgba(r,g,b,0.5)` | The fill color to use for the path. | `lineCap` | `String` | `round` | The line cap style to apply to the open ends of the path. | `lineJoin` | `Array` | | The line join style to apply to corners of the path. | `miterLimit` | `Number` | | The limiting value that helps avoid spikes at junctions between connected line segments. The miter limit helps you avoid spikes in paths that use the `miter` `lineJoin` style. If the ratio of the miter length—that is, the diagonal length of the miter join—to the line thickness exceeds the miter limit, the joint is converted to a bevel join. The default miter limit is 10, which results in the conversion of miters whose angle at the joint is less than 11 degrees. From 4b712670a72be5dde157202bb141e5379fd005bf Mon Sep 17 00:00:00 2001 From: Evan Siroky Date: Tue, 7 Mar 2017 15:14:38 -0800 Subject: [PATCH 067/199] Add one more tip to Android installation troubleshooting (#1060) * Add one more tip to Android installation troubleshooting Add note about dealing with correcting the system image to use with the emulator. * reword a tip in the troubleshooting section --- docs/installation.md | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/docs/installation.md b/docs/installation.md index 49f37fd85..aefa6c5b6 100644 --- a/docs/installation.md +++ b/docs/installation.md @@ -22,7 +22,7 @@ react-native link react-native-maps 1. Setup your `Podfile` like the included [example/ios/Podfile](../example/ios/Podfile), replace all references to `AirMapExplorer` with your project name, and then run `pod install`. (If you do not need `GoogleMaps` support for iOS, then you can probably completely skip this step.) 1. Open your project in Xcode workspace -1. If you need `GoogleMaps` support also +1. If you need `GoogleMaps` support also - Drag this folder `node_modules/react-native-maps/ios/AirGoogleMaps/` into your project, and choose `Create groups` in the popup window. - In `AppDelegate.m`, add `@import GoogleMaps;` before `@implementation AppDelegate`. In `- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions`, add `[GMSServices provideAPIKey:@"YOUR_GOOGLE_MAP_API_KEY"];` - In your project's `Build Settings` > `Header Search Paths`, double click the value field. In the popup, add `$(SRCROOT)/../node_modules/react-native-maps/ios/AirMaps` and change `non-recursive` to `recursive`. (Dragging the folder `node_modules/react-native-maps/ios/AirMaps/` into your project introduces duplicate symbols. We should not do it.) @@ -72,9 +72,9 @@ After your `Podfile` is setup properly, run `pod install`. compile project(':react-native-maps') } ``` - + If you have a different play services than the one included in this library, use the following instead (switch 10.0.1 for the desired version): - + ```groovy ... dependencies { @@ -212,5 +212,7 @@ Enter the name of the API key and create it. gradlew clean cd .. ``` - + 1. If you are using Android Virtual Devices (AVD), ensure that `Use Host GPU` is checked in the settings for your virtual device. + +1. If using an emulator and the only thing that shows up on the screen is the message: `[APPNAME] won't run without Google Play services which are not supported by your device.`, you need to change the emulator CPU/ABI setting to a system image that includes Google APIs. These may need to be downloaded from the Android SDK Manager first. From 88e9aea7bfbecd72fdc6d3df86a74618d86b661e Mon Sep 17 00:00:00 2001 From: Alvaro Date: Wed, 8 Mar 2017 00:15:15 +0100 Subject: [PATCH 068/199] Improve documentation for fitToCoordinates (#1037) * added notes for fitToCoordinates call * Notes for fitToCoordinates set in correct box --- docs/mapview.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/mapview.md b/docs/mapview.md index 3c6dd08c4..5c80b87f9 100644 --- a/docs/mapview.md +++ b/docs/mapview.md @@ -57,9 +57,9 @@ |---|---|---| | `animateToRegion` | `region: Region`, `duration: Number` | | `animateToCoordinate` | `coordinate: LatLng`, `duration: Number` | -| `fitToElements` | `animated: Boolean` | +| `fitToElements` | `animated: Boolean` | | `fitToSuppliedMarkers` | `markerIDs: String[]`, `animated: Boolean` | If you need to use this in `ComponentDidMount`, make sure you put it in a timeout or it will cause performance problems. -| `fitToCoordinates` | `coordinates: Array, options: { edgePadding: EdgePadding, animated: Boolean }` | +| `fitToCoordinates` | `coordinates: Array, options: { edgePadding: EdgePadding, animated: Boolean }` | If called in `ComponentDidMount` in android, it will cause an exception. It is recommended to call it from the MapView `onLayout` event. From b7f33d0093970c4c6a6ca44a7b2b021713acdc39 Mon Sep 17 00:00:00 2001 From: David DiPanfilo Date: Mon, 13 Mar 2017 11:04:25 -0400 Subject: [PATCH 069/199] Update for dependency issues (#1092) * Update for dependency issues https://github.com/airbnb/react-native-maps/issues/1067 this is a common issue people are experiencing right now * Distinguish dependencies for React versions --- docs/installation.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/installation.md b/docs/installation.md index aefa6c5b6..9783b46a5 100644 --- a/docs/installation.md +++ b/docs/installation.md @@ -26,6 +26,8 @@ react-native link react-native-maps - Drag this folder `node_modules/react-native-maps/ios/AirGoogleMaps/` into your project, and choose `Create groups` in the popup window. - In `AppDelegate.m`, add `@import GoogleMaps;` before `@implementation AppDelegate`. In `- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions`, add `[GMSServices provideAPIKey:@"YOUR_GOOGLE_MAP_API_KEY"];` - In your project's `Build Settings` > `Header Search Paths`, double click the value field. In the popup, add `$(SRCROOT)/../node_modules/react-native-maps/ios/AirMaps` and change `non-recursive` to `recursive`. (Dragging the folder `node_modules/react-native-maps/ios/AirMaps/` into your project introduces duplicate symbols. We should not do it.) + +Note: We recommend using a version of React Native >= .40. Newer versions (>= .40) require `package.json` to be set to `"react-native-maps": "^0.13.0"`, while older versions require `"react-native-maps": "^0.12.4"`. ### Option 2: CocoaPods This is now considered the **old way** because it will only work if you **don't** have From a1f4762a4608021045f2a3a0f45cec4b7b554831 Mon Sep 17 00:00:00 2001 From: Matt Shen Date: Wed, 15 Mar 2017 21:37:45 +1100 Subject: [PATCH 070/199] issue#939, fix multiple-instance memory leak --- .../android/react/maps/AirMapManager.java | 8 +++++ .../airbnb/android/react/maps/AirMapView.java | 29 +++++++++++++++++-- 2 files changed, 35 insertions(+), 2 deletions(-) diff --git a/android/src/main/java/com/airbnb/android/react/maps/AirMapManager.java b/android/src/main/java/com/airbnb/android/react/maps/AirMapManager.java index 75ed5777f..0ecf26a41 100644 --- a/android/src/main/java/com/airbnb/android/react/maps/AirMapManager.java +++ b/android/src/main/java/com/airbnb/android/react/maps/AirMapManager.java @@ -302,4 +302,12 @@ void pushEvent(View view, String name, WritableMap data) { .receiveEvent(view.getId(), name, data); } + + + @Override + public void onDropViewInstance(AirMapView view) { + view.doDestroy(); + super.onDropViewInstance(view); + } + } diff --git a/android/src/main/java/com/airbnb/android/react/maps/AirMapView.java b/android/src/main/java/com/airbnb/android/react/maps/AirMapView.java index 632e568bc..ac78d9f6a 100644 --- a/android/src/main/java/com/airbnb/android/react/maps/AirMapView.java +++ b/android/src/main/java/com/airbnb/android/react/maps/AirMapView.java @@ -21,6 +21,7 @@ import android.widget.RelativeLayout; import com.facebook.react.bridge.LifecycleEventListener; +import com.facebook.react.bridge.ReactContext; import com.facebook.react.bridge.ReadableArray; import com.facebook.react.bridge.ReadableMap; import com.facebook.react.bridge.WritableMap; @@ -79,7 +80,9 @@ public class AirMapView extends MapView implements GoogleMap.InfoWindowAdapter, private final ScaleGestureDetector scaleDetector; private final GestureDetectorCompat gestureDetector; private final AirMapManager manager; + private LifecycleEventListener lifecycleListener; private boolean paused = false; + private boolean destroyed = false; private final ThemedReactContext context; private final EventDispatcher eventDispatcher; @@ -254,7 +257,7 @@ public void onCameraChange(CameraPosition position) { // updating location constantly, killing the battery, even though some other location-mgmt // module may // desire to shut-down location-services. - LifecycleEventListener lifecycleListener = new LifecycleEventListener() { + lifecycleListener = new LifecycleEventListener() { @Override public void onHostResume() { if (hasPermissions()) { @@ -273,11 +276,15 @@ public void onHostPause() { //noinspection MissingPermission map.setMyLocationEnabled(false); } - paused = true; + synchronized (AirMapView.this) { + AirMapView.this.onPause(); + paused = true; + } } @Override public void onHostDestroy() { + AirMapView.this.doDestroy(); } }; @@ -289,6 +296,24 @@ private boolean hasPermissions() { checkSelfPermission(getContext(), PERMISSIONS[1]) == PackageManager.PERMISSION_GRANTED; } + /* + onDestroy is final method so I can't override it. + */ + public synchronized void doDestroy() { + if (lifecycleListener != null && context != null) { + context.removeLifecycleEventListener(lifecycleListener); + lifecycleListener = null; + } + if(!paused) { + onPause(); + } + if (!destroyed) { + onDestroy(); + destroyed = true; + } + + } + public void setRegion(ReadableMap region) { if (region == null) return; From e326d323a91c09badcb6af7d48a50a21403b5556 Mon Sep 17 00:00:00 2001 From: Evan Siroky Date: Wed, 15 Mar 2017 17:32:14 -0700 Subject: [PATCH 071/199] Add iOS tip Add clarification to iOS options section that the advanced options may not be necessary. --- docs/installation.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/installation.md b/docs/installation.md index 9783b46a5..d3b6c331c 100644 --- a/docs/installation.md +++ b/docs/installation.md @@ -17,6 +17,8 @@ react-native link react-native-maps ## iOS +> These options may not be necessary if you ran "react-native link" + ### Option 1: CocoaPods - Same as the included AirMapsExplorer example 1. Setup your `Podfile` like the included [example/ios/Podfile](../example/ios/Podfile), replace all references to `AirMapExplorer` with your project name, and then run `pod install`. From 3c38a4067d1f73c6601e960e8a4470df9ce9e1f6 Mon Sep 17 00:00:00 2001 From: Janic Duplessis Date: Fri, 17 Mar 2017 18:40:45 -0400 Subject: [PATCH 072/199] Use local RCTConvert+Mapkit instead of the one in React Native --- .../AirMapsExplorer.xcodeproj/project.pbxproj | 12 ++++----- ios/AirGoogleMaps/AIRGoogleMap.h | 2 +- ios/AirGoogleMaps/AIRGoogleMap.m | 2 +- ios/AirGoogleMaps/AIRGoogleMapManager.m | 2 +- ios/AirGoogleMaps/AIRGoogleMapMarkerManager.m | 2 +- .../AIRGoogleMapPolygonManager.m | 2 +- .../AIRGoogleMapPolylineManager.m | 2 +- ios/AirMaps.xcodeproj/project.pbxproj | 13 +++++---- ios/AirMaps/AIRMap.h | 2 +- ios/AirMaps/AIRMapCircle.h | 2 +- ios/AirMaps/AIRMapManager.m | 2 +- ios/AirMaps/AIRMapMarker.h | 2 +- ios/AirMaps/AIRMapPolygon.h | 2 +- ios/AirMaps/AIRMapPolygonManager.m | 2 +- ios/AirMaps/AIRMapPolyline.h | 2 +- ios/AirMaps/AIRMapPolylineManager.m | 2 +- ios/AirMaps/AIRMapUrlTile.h | 2 +- ...nvert+MoreMapKit.h => RCTConvert+MapKit.h} | 8 ++++-- ...nvert+MoreMapKit.m => RCTConvert+MapKit.m} | 27 +++++++++++++++++-- 19 files changed, 58 insertions(+), 32 deletions(-) rename ios/AirMaps/{RCTConvert+MoreMapKit.h => RCTConvert+MapKit.h} (54%) rename ios/AirMaps/{RCTConvert+MoreMapKit.m => RCTConvert+MapKit.m} (57%) diff --git a/example/ios/AirMapsExplorer.xcodeproj/project.pbxproj b/example/ios/AirMapsExplorer.xcodeproj/project.pbxproj index df5a3a05b..01f6ca481 100644 --- a/example/ios/AirMapsExplorer.xcodeproj/project.pbxproj +++ b/example/ios/AirMapsExplorer.xcodeproj/project.pbxproj @@ -25,7 +25,7 @@ 2166AB341D82EC56007538D7 /* AIRMapPolyline.m in Sources */ = {isa = PBXBuildFile; fileRef = 2166AB121D82EC56007538D7 /* AIRMapPolyline.m */; }; 2166AB351D82EC56007538D7 /* AIRMapPolylineManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 2166AB141D82EC56007538D7 /* AIRMapPolylineManager.m */; }; 2166AB361D82EC56007538D7 /* SMCalloutView.m in Sources */ = {isa = PBXBuildFile; fileRef = 2166AB171D82EC56007538D7 /* SMCalloutView.m */; }; - 2166AB3E1D82EC56007538D7 /* RCTConvert+MoreMapKit.m in Sources */ = {isa = PBXBuildFile; fileRef = 2166AB281D82EC56007538D7 /* RCTConvert+MoreMapKit.m */; }; + 2166AB3E1D82EC56007538D7 /* RCTConvert+MapKit.m in Sources */ = {isa = PBXBuildFile; fileRef = 2166AB281D82EC56007538D7 /* RCTConvert+MapKit.m */; }; 21D346651D933B8C002BAD8A /* AIRMapUrlTile.m in Sources */ = {isa = PBXBuildFile; fileRef = 21D346621D933B8C002BAD8A /* AIRMapUrlTile.m */; }; 21D346661D933B8C002BAD8A /* AIRMapUrlTileManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 21D346641D933B8C002BAD8A /* AIRMapUrlTileManager.m */; }; 21E6570A1D77591400B75EE5 /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 21E657091D77591400B75EE5 /* SystemConfiguration.framework */; }; @@ -106,8 +106,8 @@ 2166AB141D82EC56007538D7 /* AIRMapPolylineManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AIRMapPolylineManager.m; sourceTree = ""; }; 2166AB161D82EC56007538D7 /* SMCalloutView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SMCalloutView.h; sourceTree = ""; }; 2166AB171D82EC56007538D7 /* SMCalloutView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SMCalloutView.m; sourceTree = ""; }; - 2166AB271D82EC56007538D7 /* RCTConvert+MoreMapKit.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "RCTConvert+MoreMapKit.h"; sourceTree = ""; }; - 2166AB281D82EC56007538D7 /* RCTConvert+MoreMapKit.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "RCTConvert+MoreMapKit.m"; sourceTree = ""; }; + 2166AB271D82EC56007538D7 /* RCTConvert+MapKit.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "RCTConvert+MapKit.h"; sourceTree = ""; }; + 2166AB281D82EC56007538D7 /* RCTConvert+MapKit.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "RCTConvert+MapKit.m"; sourceTree = ""; }; 21D346611D933B8C002BAD8A /* AIRMapUrlTile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AIRMapUrlTile.h; sourceTree = ""; }; 21D346621D933B8C002BAD8A /* AIRMapUrlTile.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AIRMapUrlTile.m; sourceTree = ""; }; 21D346631D933B8C002BAD8A /* AIRMapUrlTileManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AIRMapUrlTileManager.h; sourceTree = ""; }; @@ -242,8 +242,8 @@ 21D346631D933B8C002BAD8A /* AIRMapUrlTileManager.h */, 21D346641D933B8C002BAD8A /* AIRMapUrlTileManager.m */, 2166AB151D82EC56007538D7 /* Callout */, - 2166AB271D82EC56007538D7 /* RCTConvert+MoreMapKit.h */, - 2166AB281D82EC56007538D7 /* RCTConvert+MoreMapKit.m */, + 2166AB271D82EC56007538D7 /* RCTConvert+MapKit.h */, + 2166AB281D82EC56007538D7 /* RCTConvert+MapKit.m */, ); name = AirMaps; path = ../../ios/AirMaps; @@ -528,7 +528,7 @@ 8697D6221DBEDE6100DB7D0F /* AIRGoogleMapCircle.m in Sources */, 2166AB321D82EC56007538D7 /* AIRMapPolygon.m in Sources */, 13B07FBC1A68108700A75B9A /* AppDelegate.m in Sources */, - 2166AB3E1D82EC56007538D7 /* RCTConvert+MoreMapKit.m in Sources */, + 2166AB3E1D82EC56007538D7 /* RCTConvert+MapKit.m in Sources */, 8697D6251DBEE22B00DB7D0F /* AIRGoogleMapCircleManager.m in Sources */, 13B07FC11A68108700A75B9A /* main.m in Sources */, 86DE6F8B1DCE8543002A5053 /* AIRGoogleMapURLTileManager.m in Sources */, diff --git a/ios/AirGoogleMaps/AIRGoogleMap.h b/ios/AirGoogleMaps/AIRGoogleMap.h index 925aa4746..bf74e4047 100644 --- a/ios/AirGoogleMaps/AIRGoogleMap.h +++ b/ios/AirGoogleMaps/AIRGoogleMap.h @@ -7,10 +7,10 @@ #import #import -#import #import #import #import "AIRGMSMarker.h" +#import "RCTConvert+MapKit.h" @interface AIRGoogleMap : GMSMapView diff --git a/ios/AirGoogleMaps/AIRGoogleMap.m b/ios/AirGoogleMaps/AIRGoogleMap.m index e6d028c31..46c323b65 100644 --- a/ios/AirGoogleMaps/AIRGoogleMap.m +++ b/ios/AirGoogleMaps/AIRGoogleMap.m @@ -13,8 +13,8 @@ #import "AIRGoogleMapUrlTile.h" #import #import -#import #import +#import "RCTConvert+MapKit.h" id regionAsJSON(MKCoordinateRegion region) { return @{ diff --git a/ios/AirGoogleMaps/AIRGoogleMapManager.m b/ios/AirGoogleMaps/AIRGoogleMapManager.m index e306de1d8..092f4ef62 100644 --- a/ios/AirGoogleMaps/AIRGoogleMapManager.m +++ b/ios/AirGoogleMaps/AIRGoogleMapManager.m @@ -11,7 +11,6 @@ #import #import #import -#import #import #import #import @@ -24,6 +23,7 @@ #import "AIRMapCircle.h" #import "SMCalloutView.h" #import "AIRGoogleMapMarker.h" +#import "RCTConvert+MapKit.h" #import diff --git a/ios/AirGoogleMaps/AIRGoogleMapMarkerManager.m b/ios/AirGoogleMaps/AIRGoogleMapMarkerManager.m index fd16f58a6..ac2e44347 100644 --- a/ios/AirGoogleMaps/AIRGoogleMapMarkerManager.m +++ b/ios/AirGoogleMaps/AIRGoogleMapMarkerManager.m @@ -8,8 +8,8 @@ #import "AIRGoogleMapMarkerManager.h" #import "AIRGoogleMapMarker.h" #import -#import #import +#import "RCTConvert+MapKit.h" @implementation AIRGoogleMapMarkerManager diff --git a/ios/AirGoogleMaps/AIRGoogleMapPolygonManager.m b/ios/AirGoogleMaps/AIRGoogleMapPolygonManager.m index 5c7ce2a66..08c1125a0 100644 --- a/ios/AirGoogleMaps/AIRGoogleMapPolygonManager.m +++ b/ios/AirGoogleMaps/AIRGoogleMapPolygonManager.m @@ -11,7 +11,7 @@ #import #import #import -#import "RCTConvert+MoreMapKit.h" +#import "RCTConvert+MapKit.h" #import "AIRGoogleMapPolygon.h" @interface AIRGoogleMapPolygonManager() diff --git a/ios/AirGoogleMaps/AIRGoogleMapPolylineManager.m b/ios/AirGoogleMaps/AIRGoogleMapPolylineManager.m index 8ccaa7080..5fca4e902 100644 --- a/ios/AirGoogleMaps/AIRGoogleMapPolylineManager.m +++ b/ios/AirGoogleMaps/AIRGoogleMapPolylineManager.m @@ -12,7 +12,7 @@ #import #import #import -#import "RCTConvert+MoreMapKit.h" +#import "RCTConvert+MapKit.h" #import "AIRGoogleMapPolyline.h" @interface AIRGoogleMapPolylineManager() diff --git a/ios/AirMaps.xcodeproj/project.pbxproj b/ios/AirMaps.xcodeproj/project.pbxproj index 4be12b6bc..39b1256e2 100644 --- a/ios/AirMaps.xcodeproj/project.pbxproj +++ b/ios/AirMaps.xcodeproj/project.pbxproj @@ -20,8 +20,8 @@ 1125B2E41C4AD3DA007D0023 /* AIRMapPolygonManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 1125B2D21C4AD3DA007D0023 /* AIRMapPolygonManager.m */; }; 1125B2E51C4AD3DA007D0023 /* AIRMapPolyline.m in Sources */ = {isa = PBXBuildFile; fileRef = 1125B2D41C4AD3DA007D0023 /* AIRMapPolyline.m */; }; 1125B2E61C4AD3DA007D0023 /* AIRMapPolylineManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 1125B2D61C4AD3DA007D0023 /* AIRMapPolylineManager.m */; }; - 1125B2E71C4AD3DA007D0023 /* RCTConvert+MoreMapKit.m in Sources */ = {isa = PBXBuildFile; fileRef = 1125B2D91C4AD3DA007D0023 /* RCTConvert+MoreMapKit.m */; }; 1125B2F21C4AD445007D0023 /* SMCalloutView.m in Sources */ = {isa = PBXBuildFile; fileRef = 1125B2F11C4AD445007D0023 /* SMCalloutView.m */; }; + 19DABC7F1E7C9D3C00F41150 /* RCTConvert+MapKit.m in Sources */ = {isa = PBXBuildFile; fileRef = 19DABC7E1E7C9D3C00F41150 /* RCTConvert+MapKit.m */; }; DA6C26381C9E2AFE0035349F /* AIRMapUrlTile.m in Sources */ = {isa = PBXBuildFile; fileRef = DA6C26371C9E2AFE0035349F /* AIRMapUrlTile.m */; }; DA6C263E1C9E324A0035349F /* AIRMapUrlTileManager.m in Sources */ = {isa = PBXBuildFile; fileRef = DA6C263D1C9E324A0035349F /* AIRMapUrlTileManager.m */; }; /* End PBXBuildFile section */ @@ -65,11 +65,11 @@ 1125B2D41C4AD3DA007D0023 /* AIRMapPolyline.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = AIRMapPolyline.m; path = AirMaps/AIRMapPolyline.m; sourceTree = SOURCE_ROOT; }; 1125B2D51C4AD3DA007D0023 /* AIRMapPolylineManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AIRMapPolylineManager.h; path = AirMaps/AIRMapPolylineManager.h; sourceTree = SOURCE_ROOT; }; 1125B2D61C4AD3DA007D0023 /* AIRMapPolylineManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = AIRMapPolylineManager.m; path = AirMaps/AIRMapPolylineManager.m; sourceTree = SOURCE_ROOT; }; - 1125B2D81C4AD3DA007D0023 /* RCTConvert+MoreMapKit.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "RCTConvert+MoreMapKit.h"; path = "AirMaps/RCTConvert+MoreMapKit.h"; sourceTree = SOURCE_ROOT; }; - 1125B2D91C4AD3DA007D0023 /* RCTConvert+MoreMapKit.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "RCTConvert+MoreMapKit.m"; path = "AirMaps/RCTConvert+MoreMapKit.m"; sourceTree = SOURCE_ROOT; }; 1125B2F01C4AD445007D0023 /* SMCalloutView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SMCalloutView.h; path = AirMaps/Callout/SMCalloutView.h; sourceTree = SOURCE_ROOT; }; 1125B2F11C4AD445007D0023 /* SMCalloutView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = SMCalloutView.m; path = AirMaps/Callout/SMCalloutView.m; sourceTree = SOURCE_ROOT; }; 11FA5C511C4A1296003AC2EE /* libAirMaps.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libAirMaps.a; sourceTree = BUILT_PRODUCTS_DIR; }; + 19DABC7D1E7C9D3C00F41150 /* RCTConvert+MapKit.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "RCTConvert+MapKit.h"; sourceTree = ""; }; + 19DABC7E1E7C9D3C00F41150 /* RCTConvert+MapKit.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "RCTConvert+MapKit.m"; sourceTree = ""; }; DA6C26361C9E2AFE0035349F /* AIRMapUrlTile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AIRMapUrlTile.h; sourceTree = ""; }; DA6C26371C9E2AFE0035349F /* AIRMapUrlTile.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AIRMapUrlTile.m; sourceTree = ""; }; DA6C263C1C9E324A0035349F /* AIRMapUrlTileManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AIRMapUrlTileManager.h; sourceTree = ""; }; @@ -132,11 +132,10 @@ 1125B2D31C4AD3DA007D0023 /* AIRMapPolyline.h */, 1125B2D51C4AD3DA007D0023 /* AIRMapPolylineManager.h */, 1125B2D61C4AD3DA007D0023 /* AIRMapPolylineManager.m */, - 21B6E2D21D99B886007E664F /* AIRMapSnapshot.h */, 1125B2F01C4AD445007D0023 /* SMCalloutView.h */, 1125B2F11C4AD445007D0023 /* SMCalloutView.m */, - 1125B2D81C4AD3DA007D0023 /* RCTConvert+MoreMapKit.h */, - 1125B2D91C4AD3DA007D0023 /* RCTConvert+MoreMapKit.m */, + 19DABC7D1E7C9D3C00F41150 /* RCTConvert+MapKit.h */, + 19DABC7E1E7C9D3C00F41150 /* RCTConvert+MapKit.m */, DA6C26361C9E2AFE0035349F /* AIRMapUrlTile.h */, DA6C26371C9E2AFE0035349F /* AIRMapUrlTile.m */, DA6C263C1C9E324A0035349F /* AIRMapUrlTileManager.h */, @@ -207,10 +206,10 @@ 1125B2E01C4AD3DA007D0023 /* AIRMapManager.m in Sources */, 1125B2E61C4AD3DA007D0023 /* AIRMapPolylineManager.m in Sources */, 1125B2DD1C4AD3DA007D0023 /* AIRMapCircle.m in Sources */, + 19DABC7F1E7C9D3C00F41150 /* RCTConvert+MapKit.m in Sources */, 1125B2E51C4AD3DA007D0023 /* AIRMapPolyline.m in Sources */, DA6C263E1C9E324A0035349F /* AIRMapUrlTileManager.m in Sources */, 1125B2DA1C4AD3DA007D0023 /* AIRMap.m in Sources */, - 1125B2E71C4AD3DA007D0023 /* RCTConvert+MoreMapKit.m in Sources */, 1125B2DF1C4AD3DA007D0023 /* AIRMapCoordinate.m in Sources */, 1125B2F21C4AD445007D0023 /* SMCalloutView.m in Sources */, 1125B2E11C4AD3DA007D0023 /* AIRMapMarker.m in Sources */, diff --git a/ios/AirMaps/AIRMap.h b/ios/AirMaps/AIRMap.h index fd4ed0f25..9edf403a1 100644 --- a/ios/AirMaps/AIRMap.h +++ b/ios/AirMaps/AIRMap.h @@ -10,9 +10,9 @@ #import #import -#import #import #import "SMCalloutView.h" +#import "RCTConvert+MapKit.h" extern const CLLocationDegrees AIRMapDefaultSpan; extern const NSTimeInterval AIRMapRegionChangeObserveInterval; diff --git a/ios/AirMaps/AIRMapCircle.h b/ios/AirMaps/AIRMapCircle.h index 44755a9ee..7d7160e85 100644 --- a/ios/AirMaps/AIRMapCircle.h +++ b/ios/AirMaps/AIRMapCircle.h @@ -8,12 +8,12 @@ #import #import -#import #import #import #import "AIRMapCoordinate.h" #import "AIRMap.h" +#import "RCTConvert+MapKit.h" @interface AIRMapCircle: MKAnnotationView diff --git a/ios/AirMaps/AIRMapManager.m b/ios/AirMaps/AIRMapManager.m index 91a7f3ef9..0585ecf1b 100644 --- a/ios/AirMaps/AIRMapManager.m +++ b/ios/AirMaps/AIRMapManager.m @@ -13,7 +13,6 @@ #import #import #import -#import #import #import #import @@ -25,6 +24,7 @@ #import "SMCalloutView.h" #import "AIRMapUrlTile.h" #import "AIRMapSnapshot.h" +#import "RCTConvert+MapKit.h" #import diff --git a/ios/AirMaps/AIRMapMarker.h b/ios/AirMaps/AIRMapMarker.h index 6d6274a4a..bbcabf506 100644 --- a/ios/AirMaps/AIRMapMarker.h +++ b/ios/AirMaps/AIRMapMarker.h @@ -13,10 +13,10 @@ #import #import -#import #import #import "AIRMap.h" #import "SMCalloutView.h" +#import "RCTConvert+MapKit.h" @class RCTBridge; diff --git a/ios/AirMaps/AIRMapPolygon.h b/ios/AirMaps/AIRMapPolygon.h index 33e752cf0..15def9100 100644 --- a/ios/AirMaps/AIRMapPolygon.h +++ b/ios/AirMaps/AIRMapPolygon.h @@ -9,10 +9,10 @@ #import #import -#import #import #import "AIRMapCoordinate.h" #import "AIRMap.h" +#import "RCTConvert+MapKit.h" diff --git a/ios/AirMaps/AIRMapPolygonManager.m b/ios/AirMaps/AIRMapPolygonManager.m index a8177c180..e9be4936a 100644 --- a/ios/AirMaps/AIRMapPolygonManager.m +++ b/ios/AirMaps/AIRMapPolygonManager.m @@ -15,7 +15,7 @@ #import #import #import -#import "RCTConvert+MoreMapKit.h" +#import "RCTConvert+MapKit.h" #import "AIRMapMarker.h" #import "AIRMapPolygon.h" diff --git a/ios/AirMaps/AIRMapPolyline.h b/ios/AirMaps/AIRMapPolyline.h index 5629b1fd4..6fb5feadc 100644 --- a/ios/AirMaps/AIRMapPolyline.h +++ b/ios/AirMaps/AIRMapPolyline.h @@ -8,11 +8,11 @@ #import #import -#import #import #import #import "AIRMapCoordinate.h" #import "AIRMap.h" +#import "RCTConvert+MapKit.h" @interface AIRMapPolyline: MKAnnotationView diff --git a/ios/AirMaps/AIRMapPolylineManager.m b/ios/AirMaps/AIRMapPolylineManager.m index 70ba3eb1f..d00a9efac 100644 --- a/ios/AirMaps/AIRMapPolylineManager.m +++ b/ios/AirMaps/AIRMapPolylineManager.m @@ -15,7 +15,7 @@ #import #import #import -#import "RCTConvert+MoreMapKit.h" +#import "RCTConvert+MapKit.h" #import "AIRMapMarker.h" #import "AIRMapPolyline.h" diff --git a/ios/AirMaps/AIRMapUrlTile.h b/ios/AirMaps/AIRMapUrlTile.h index 509331414..a33be61d1 100644 --- a/ios/AirMaps/AIRMapUrlTile.h +++ b/ios/AirMaps/AIRMapUrlTile.h @@ -10,11 +10,11 @@ #import #import -#import #import #import #import "AIRMapCoordinate.h" #import "AIRMap.h" +#import "RCTConvert+MapKit.h" @interface AIRMapUrlTile : MKAnnotationView diff --git a/ios/AirMaps/RCTConvert+MoreMapKit.h b/ios/AirMaps/RCTConvert+MapKit.h similarity index 54% rename from ios/AirMaps/RCTConvert+MoreMapKit.h rename to ios/AirMaps/RCTConvert+MapKit.h index 2d2475890..28f60bf96 100644 --- a/ios/AirMaps/RCTConvert+MoreMapKit.h +++ b/ios/AirMaps/RCTConvert+MapKit.h @@ -7,6 +7,10 @@ #import #import -@interface RCTConvert (MoreMapKit) +@interface RCTConvert (MapKit) -@end \ No newline at end of file ++ (MKCoordinateSpan)MKCoordinateSpan:(id)json; ++ (MKCoordinateRegion)MKCoordinateRegion:(id)json; ++ (MKMapType)MKMapType:(id)json; + +@end diff --git a/ios/AirMaps/RCTConvert+MoreMapKit.m b/ios/AirMaps/RCTConvert+MapKit.m similarity index 57% rename from ios/AirMaps/RCTConvert+MoreMapKit.m rename to ios/AirMaps/RCTConvert+MapKit.m index 11f19a4a8..2e3b11602 100644 --- a/ios/AirMaps/RCTConvert+MoreMapKit.m +++ b/ios/AirMaps/RCTConvert+MapKit.m @@ -3,12 +3,35 @@ // Copyright (c) 2015 Facebook. All rights reserved. // -#import "RCTConvert+MoreMapKit.h" +#import "RCTConvert+MapKit.h" #import #import "AIRMapCoordinate.h" -@implementation RCTConvert (MoreMapKit) +@implementation RCTConvert (MapKit) + ++ (MKCoordinateSpan)MKCoordinateSpan:(id)json +{ + json = [self NSDictionary:json]; + return (MKCoordinateSpan){ + [self CLLocationDegrees:json[@"latitudeDelta"]], + [self CLLocationDegrees:json[@"longitudeDelta"]] + }; +} + ++ (MKCoordinateRegion)MKCoordinateRegion:(id)json +{ + return (MKCoordinateRegion){ + [self CLLocationCoordinate2D:json], + [self MKCoordinateSpan:json] + }; +} + +RCT_ENUM_CONVERTER(MKMapType, (@{ + @"standard": @(MKMapTypeStandard), + @"satellite": @(MKMapTypeSatellite), + @"hybrid": @(MKMapTypeHybrid), +}), MKMapTypeStandard, integerValue) // NOTE(lmr): // This is a bit of a hack, but I'm using this class to simply wrap From bb5acfd533f593077c1d2828432491f2b026bfcd Mon Sep 17 00:00:00 2001 From: Leland Richardson Date: Mon, 20 Mar 2017 14:57:24 -0700 Subject: [PATCH 073/199] Fix null activity crash --- .../android/react/maps/AirMapManager.java | 23 +++-------- .../airbnb/android/react/maps/AirMapView.java | 39 ++++++++++--------- 2 files changed, 26 insertions(+), 36 deletions(-) diff --git a/android/src/main/java/com/airbnb/android/react/maps/AirMapManager.java b/android/src/main/java/com/airbnb/android/react/maps/AirMapManager.java index 75ed5777f..086aead67 100644 --- a/android/src/main/java/com/airbnb/android/react/maps/AirMapManager.java +++ b/android/src/main/java/com/airbnb/android/react/maps/AirMapManager.java @@ -43,8 +43,6 @@ public class AirMapManager extends ViewGroupManager { "none", GoogleMap.MAP_TYPE_NONE ); - private ReactContext reactContext; - private final ReactApplicationContext appContext; protected GoogleMapOptions googleMapOptions; @@ -61,24 +59,15 @@ public String getName() { @Override protected AirMapView createViewInstance(ThemedReactContext context) { - reactContext = context; - - try { - MapsInitializer.initialize(this.appContext); - } catch (RuntimeException e) { - e.printStackTrace(); - emitMapError("Map initialize error", "map_init_error"); - } - - return new AirMapView(context, this.appContext.getCurrentActivity(), this, this.googleMapOptions); + return new AirMapView(context, this, googleMapOptions); } - private void emitMapError(String message, String type) { + private void emitMapError(ThemedReactContext context, String message, String type) { WritableMap error = Arguments.createMap(); error.putString("message", message); error.putString("type", type); - reactContext + context .getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class) .emit("onError", error); } @@ -297,9 +286,9 @@ public void updateExtraData(AirMapView view, Object extraData) { view.updateExtraData(extraData); } - void pushEvent(View view, String name, WritableMap data) { - reactContext.getJSModule(RCTEventEmitter.class) - .receiveEvent(view.getId(), name, data); + void pushEvent(ThemedReactContext context, View view, String name, WritableMap data) { + context.getJSModule(RCTEventEmitter.class) + .receiveEvent(view.getId(), name, data); } } diff --git a/android/src/main/java/com/airbnb/android/react/maps/AirMapView.java b/android/src/main/java/com/airbnb/android/react/maps/AirMapView.java index 632e568bc..65ba78fd9 100644 --- a/android/src/main/java/com/airbnb/android/react/maps/AirMapView.java +++ b/android/src/main/java/com/airbnb/android/react/maps/AirMapView.java @@ -83,14 +83,15 @@ public class AirMapView extends MapView implements GoogleMap.InfoWindowAdapter, private final ThemedReactContext context; private final EventDispatcher eventDispatcher; - public AirMapView(ThemedReactContext reactContext, Context appContext, AirMapManager manager, + public AirMapView(ThemedReactContext reactContext, AirMapManager manager, GoogleMapOptions googleMapOptions) { - super(appContext, googleMapOptions); + super(reactContext, googleMapOptions); this.manager = manager; this.context = reactContext; super.onCreate(null); + // TODO(lmr): what about onStart???? super.onResume(); super.getMapAsync(this); @@ -141,7 +142,7 @@ public void onMapReady(final GoogleMap map) { this.map.setInfoWindowAdapter(this); this.map.setOnMarkerDragListener(this); - manager.pushEvent(this, "onMapReady", new WritableNativeMap()); + manager.pushEvent(context, this, "onMapReady", new WritableNativeMap()); final AirMapView view = this; @@ -154,12 +155,12 @@ public boolean onMarkerClick(Marker marker) { event = makeClickEventData(marker.getPosition()); event.putString("action", "marker-press"); event.putString("id", airMapMarker.getIdentifier()); - manager.pushEvent(view, "onMarkerPress", event); + manager.pushEvent(context, view, "onMarkerPress", event); event = makeClickEventData(marker.getPosition()); event.putString("action", "marker-press"); event.putString("id", airMapMarker.getIdentifier()); - manager.pushEvent(markerMap.get(marker), "onPress", event); + manager.pushEvent(context, markerMap.get(marker), "onPress", event); // Return false to open the callout info window and center on the marker // https://developers.google.com/android/reference/com/google/android/gms/maps/GoogleMap.OnMarkerClickListener @@ -177,7 +178,7 @@ public boolean onMarkerClick(Marker marker) { public void onPolygonClick(Polygon polygon) { WritableMap event = makeClickEventData(polygon.getPoints().get(0)); event.putString("action", "polygon-press"); - manager.pushEvent(polygonMap.get(polygon), "onPress", event); + manager.pushEvent(context, polygonMap.get(polygon), "onPress", event); } }); @@ -186,7 +187,7 @@ public void onPolygonClick(Polygon polygon) { public void onPolylineClick(Polyline polyline) { WritableMap event = makeClickEventData(polyline.getPoints().get(0)); event.putString("action", "polyline-press"); - manager.pushEvent(polylineMap.get(polyline), "onPress", event); + manager.pushEvent(context, polylineMap.get(polyline), "onPress", event); } }); @@ -197,17 +198,17 @@ public void onInfoWindowClick(Marker marker) { event = makeClickEventData(marker.getPosition()); event.putString("action", "callout-press"); - manager.pushEvent(view, "onCalloutPress", event); + manager.pushEvent(context, view, "onCalloutPress", event); event = makeClickEventData(marker.getPosition()); event.putString("action", "callout-press"); AirMapMarker markerView = markerMap.get(marker); - manager.pushEvent(markerView, "onCalloutPress", event); + manager.pushEvent(context, markerView, "onCalloutPress", event); event = makeClickEventData(marker.getPosition()); event.putString("action", "callout-press"); AirMapCallout infoWindow = markerView.getCalloutView(); - if (infoWindow != null) manager.pushEvent(infoWindow, "onPress", event); + if (infoWindow != null) manager.pushEvent(context, infoWindow, "onPress", event); } }); @@ -216,7 +217,7 @@ public void onInfoWindowClick(Marker marker) { public void onMapClick(LatLng point) { WritableMap event = makeClickEventData(point); event.putString("action", "press"); - manager.pushEvent(view, "onPress", event); + manager.pushEvent(context, view, "onPress", event); } }); @@ -225,7 +226,7 @@ public void onMapClick(LatLng point) { public void onMapLongClick(LatLng point) { WritableMap event = makeClickEventData(point); event.putString("action", "long-press"); - manager.pushEvent(view, "onLongPress", makeClickEventData(point)); + manager.pushEvent(context, view, "onLongPress", makeClickEventData(point)); } }); @@ -661,31 +662,31 @@ public void run() { @Override public void onMarkerDragStart(Marker marker) { WritableMap event = makeClickEventData(marker.getPosition()); - manager.pushEvent(this, "onMarkerDragStart", event); + manager.pushEvent(context, this, "onMarkerDragStart", event); AirMapMarker markerView = markerMap.get(marker); event = makeClickEventData(marker.getPosition()); - manager.pushEvent(markerView, "onDragStart", event); + manager.pushEvent(context, markerView, "onDragStart", event); } @Override public void onMarkerDrag(Marker marker) { WritableMap event = makeClickEventData(marker.getPosition()); - manager.pushEvent(this, "onMarkerDrag", event); + manager.pushEvent(context, this, "onMarkerDrag", event); AirMapMarker markerView = markerMap.get(marker); event = makeClickEventData(marker.getPosition()); - manager.pushEvent(markerView, "onDrag", event); + manager.pushEvent(context, markerView, "onDrag", event); } @Override public void onMarkerDragEnd(Marker marker) { WritableMap event = makeClickEventData(marker.getPosition()); - manager.pushEvent(this, "onMarkerDragEnd", event); + manager.pushEvent(context, this, "onMarkerDragEnd", event); AirMapMarker markerView = markerMap.get(marker); event = makeClickEventData(marker.getPosition()); - manager.pushEvent(markerView, "onDragEnd", event); + manager.pushEvent(context, markerView, "onDragEnd", event); } private ProgressBar getMapLoadingProgressBar() { @@ -778,6 +779,6 @@ public void onPanDrag(MotionEvent ev) { Point point = new Point((int) ev.getX(), (int) ev.getY()); LatLng coords = this.map.getProjection().fromScreenLocation(point); WritableMap event = makeClickEventData(coords); - manager.pushEvent(this, "onPanDrag", event); + manager.pushEvent(context, this, "onPanDrag", event); } } From 4247d9be4b4ff291737e2f512be3bf8ed16e42da Mon Sep 17 00:00:00 2001 From: Leland Richardson Date: Tue, 21 Mar 2017 11:34:40 -0700 Subject: [PATCH 074/199] Fix abi splits on example app --- example/android/app/build.gradle | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/example/android/app/build.gradle b/example/android/app/build.gradle index c0fcb022f..f46e51f10 100644 --- a/example/android/app/build.gradle +++ b/example/android/app/build.gradle @@ -61,6 +61,8 @@ import com.android.build.OutputFile apply from: "react.gradle" +def enableSeparateBuildPerCPUArchitecture = false + /** * Run Proguard to shrink the Java bytecode in release builds. */ @@ -76,6 +78,17 @@ android { targetSdkVersion 23 versionCode 1 versionName "1.0" + ndk { + abiFilters "armeabi-v7a", "x86" + } + } + splits { + abi { + reset() + enable enableSeparateBuildPerCPUArchitecture + universalApk false // If true, also generate a universal APK + include "armeabi-v7a", "x86" + } } buildTypes { release { From 1e6dda7775ae2aaa84bfe4aae37bb1ace6147871 Mon Sep 17 00:00:00 2001 From: Gabriel Peal Date: Mon, 20 Mar 2017 17:19:36 -0700 Subject: [PATCH 075/199] Use provided as the gradle dependency This allows the library to compile but will use whichever RN the app is using and also allows it to pass POM verification on sonatype which doesn't allow non-explicit dependencies. --- android/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/android/build.gradle b/android/build.gradle index 740017fad..18f2808c4 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -53,7 +53,7 @@ android { } dependencies { - compile "com.facebook.react:react-native:+" + provided "com.facebook.react:react-native:+" compile "com.google.android.gms:play-services-base:10.0.1" compile "com.google.android.gms:play-services-maps:10.0.1" } From dad1d3403d7d40faa0b03f899232e88da61df6f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Markus=20G=C3=BCnther?= Date: Tue, 21 Mar 2017 21:57:17 +0100 Subject: [PATCH 076/199] Update the android buildToolsVersion to 25.0.0 When using the current android studio with the current SDKs you have the problem that your app is on version 25 and you can not create a APK without adjusting the buildToolsVersion in the build.gradle --- android/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/android/build.gradle b/android/build.gradle index 740017fad..48b3656d1 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -40,7 +40,7 @@ allprojects { android { compileSdkVersion 25 - buildToolsVersion "23.0.3" + buildToolsVersion "25.0.0" defaultConfig { minSdkVersion 16 From cc24997fc9b14ea8f87dc721ce43d9a7fe3420ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Markus=20G=C3=BCnther?= Date: Tue, 21 Mar 2017 22:11:13 +0100 Subject: [PATCH 077/199] Update the android SDK version to 25 in example --- example/android/app/build.gradle | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/example/android/app/build.gradle b/example/android/app/build.gradle index f46e51f10..5e58e57b5 100644 --- a/example/android/app/build.gradle +++ b/example/android/app/build.gradle @@ -69,8 +69,8 @@ def enableSeparateBuildPerCPUArchitecture = false def enableProguardInReleaseBuilds = false android { - compileSdkVersion 23 - buildToolsVersion "23.0.3" + compileSdkVersion 25 + buildToolsVersion "25.0.0" defaultConfig { applicationId "com.airbnb.android.react.maps.example" From e8bc08fd8e7e614174e2395a597d3b1727d65308 Mon Sep 17 00:00:00 2001 From: Leland Richardson Date: Tue, 21 Mar 2017 16:26:29 -0700 Subject: [PATCH 078/199] v0.13.1 --- CHANGELOG.md | 42 +++++++++++++++++++++++++++++++++++++++ android/gradle.properties | 4 ++-- package.json | 2 +- 3 files changed, 45 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0fc969558..adbe8bf60 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,47 @@ # Change Log +## 0.13.1 (March 21, 2017) + + +## Enhancements + +* Add id identifier to marker-press event on Android +[#1008](https://github.com/airbnb/react-native-maps/pull/1008) + (@stan229) + +* setNativeProps, marker opacity, nested components +[#940](https://github.com/airbnb/react-native-maps/pull/940) + (@unboundfire) + + +## Patches + +* Update the android buildToolsVersion to 25.0.0 +[#1152](https://github.com/airbnb/react-native-maps/pull/1152) + (@markusguenther) + +* use `provided` for RN gradle dependency +[#1151](https://github.com/airbnb/react-native-maps/pull/1151) + (@gpeal) + +* fix null activity crash +[#1150](https://github.com/airbnb/react-native-maps/pull/1150) + (@lelandrichardson) + +* Updated Google play services and gradle build plugin +[#1023](https://github.com/airbnb/react-native-maps/pull/1023) + (@chris-at-translate) + +* Sets the map value for the AirMapUrlTile so that it can be updated properly +[#992](https://github.com/airbnb/react-native-maps/pull/992) + (@jschloer) + +* onPress and onCalloutPress doesn't trigger on markers in iOS +[#954](https://github.com/airbnb/react-native-maps/pull/954) + (@RajkumarPunchh) + + + ## 0.13.0 (January 6, 2017) ### Breaking Changes diff --git a/android/gradle.properties b/android/gradle.properties index 81ab2a1bd..cfe4fd7d4 100644 --- a/android/gradle.properties +++ b/android/gradle.properties @@ -1,5 +1,5 @@ -VERSION_CODE=2 -VERSION_NAME=0.13.0 +VERSION_CODE=4 +VERSION_NAME=0.13.1 GROUP=com.airbnb.android POM_DESCRIPTION=React Native Map view component for Android diff --git a/package.json b/package.json index 5741fe8bd..42a006cea 100644 --- a/package.json +++ b/package.json @@ -3,7 +3,7 @@ "description": "React Native Mapview component for iOS + Android", "main": "index.js", "author": "Leland Richardson ", - "version": "0.13.0", + "version": "0.13.1", "scripts": { "start": "react-native start", "lint": "eslint .", From a2ef978f29abf7812a7ccf9bee8a52970117e3d1 Mon Sep 17 00:00:00 2001 From: David Stoker Date: Wed, 22 Mar 2017 19:03:03 -0400 Subject: [PATCH 079/199] Add `showsMyLocationButton` support for Google Maps on iOS --- docs/mapview.md | 2 +- ios/AirGoogleMaps/AIRGoogleMap.h | 1 + ios/AirGoogleMaps/AIRGoogleMap.m | 9 +++++++++ ios/AirGoogleMaps/AIRGoogleMapManager.m | 1 + 4 files changed, 12 insertions(+), 1 deletion(-) diff --git a/docs/mapview.md b/docs/mapview.md index 5c80b87f9..9a64583a4 100644 --- a/docs/mapview.md +++ b/docs/mapview.md @@ -12,7 +12,7 @@ | `customMapStyle` | `Array` | | Adds custom styling to the map component. See [README](https://github.com/airbnb/react-native-maps#customizing-the-map-style) for more information. | `showsUserLocation` | `Boolean` | `false` | If `true` the app will ask for the user's location. **NOTE**: You need to add `NSLocationWhenInUseUsageDescription` key in Info.plist to enable geolocation, otherwise it is going to *fail silently*! | `followsUserLocation` | `Boolean` | `false` | If `true` the map will focus on the user's location. This only works if `showsUserLocation` is true and the user has shared their location. **Note**: iOS only. -| `showsMyLocationButton` | `Boolean` | `true` | `Android only` If `false` hide the button to move map to the current user's location. +| `showsMyLocationButton` | `Boolean` | `true` | If `false` hide the button to move map to the current user's location. | `showsPointsOfInterest` | `Boolean` | `true` | If `false` points of interest won't be displayed on the map. | `showsCompass` | `Boolean` | `true` | If `false` compass won't be displayed on the map. | `showsScale` | `Boolean` | `true` | A Boolean indicating whether the map shows scale information. diff --git a/ios/AirGoogleMaps/AIRGoogleMap.h b/ios/AirGoogleMaps/AIRGoogleMap.h index 925aa4746..b9fde5a67 100644 --- a/ios/AirGoogleMaps/AIRGoogleMap.h +++ b/ios/AirGoogleMaps/AIRGoogleMap.h @@ -38,6 +38,7 @@ @property (nonatomic, assign) BOOL rotateEnabled; @property (nonatomic, assign) BOOL pitchEnabled; @property (nonatomic, assign) BOOL showsUserLocation; +@property (nonatomic, assign) BOOL showsMyLocationButton; - (BOOL)didTapMarker:(GMSMarker *)marker; - (void)didTapAtCoordinate:(CLLocationCoordinate2D)coordinate; diff --git a/ios/AirGoogleMaps/AIRGoogleMap.m b/ios/AirGoogleMaps/AIRGoogleMap.m index e6d028c31..21e2de132 100644 --- a/ios/AirGoogleMaps/AIRGoogleMap.m +++ b/ios/AirGoogleMaps/AIRGoogleMap.m @@ -272,6 +272,15 @@ - (BOOL)showsUserLocation { return self.myLocationEnabled; } +- (void)setShowsMyLocationButton:(BOOL)showsMyLocationButton { + self.settings.myLocationButton = showsMyLocationButton; +} + +- (BOOL)showsMyLocationButton { + return self.settings.myLocationButton; +} + + + (MKCoordinateRegion) makeGMSCameraPositionFromMap:(GMSMapView *)map andGMSCameraPosition:(GMSCameraPosition *)position { // solution from here: http://stackoverflow.com/a/16587735/1102215 GMSVisibleRegion visibleRegion = map.projection.visibleRegion; diff --git a/ios/AirGoogleMaps/AIRGoogleMapManager.m b/ios/AirGoogleMaps/AIRGoogleMapManager.m index e306de1d8..bde7883cf 100644 --- a/ios/AirGoogleMaps/AIRGoogleMapManager.m +++ b/ios/AirGoogleMaps/AIRGoogleMapManager.m @@ -56,6 +56,7 @@ - (UIView *)view RCT_EXPORT_VIEW_PROPERTY(scrollEnabled, BOOL) RCT_EXPORT_VIEW_PROPERTY(pitchEnabled, BOOL) RCT_EXPORT_VIEW_PROPERTY(showsUserLocation, BOOL) +RCT_EXPORT_VIEW_PROPERTY(showsMyLocationButton, BOOL) RCT_EXPORT_VIEW_PROPERTY(customMapStyleString, NSString) RCT_EXPORT_VIEW_PROPERTY(onPress, RCTBubblingEventBlock) RCT_EXPORT_VIEW_PROPERTY(onLongPress, RCTBubblingEventBlock) From edde484725993e365b6dbef7cc8bfdb627e3a90e Mon Sep 17 00:00:00 2001 From: Leland Richardson Date: Sun, 26 Mar 2017 13:05:56 -0700 Subject: [PATCH 080/199] Fix typos --- CHANGELOG.md | 2 +- .../main/java/com/airbnb/android/react/maps/MapsPackage.java | 2 +- docs/mapview.md | 2 +- ios/AirMaps/AIRMapManager.m | 2 +- ios/AirMaps/Callout/SMCalloutView.h | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index adbe8bf60..a6e3ab5c3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -322,7 +322,7 @@ Failed to build DependencyGraph: @providesModule naming collision: Duplicate module name: String.prototype.es6 Paths: /Users//node_modules/react-native-maps/example2/node_modules/react-native/packager/react-packager/src/Resolver/polyfills/String.prototype.es6.js collides with /Users//node_modules/react-native/packager/react-packager/src/Resolver/polyfills/String.prototype.es6.js -This error is caused by a @providesModule declaration with the same name accross two different files. +This error is caused by a @providesModule declaration with the same name across two different files. ``` 0.8.2 is identical to 0.8.1, except with the offending code removed from the NPM package. diff --git a/android/src/main/java/com/airbnb/android/react/maps/MapsPackage.java b/android/src/main/java/com/airbnb/android/react/maps/MapsPackage.java index bc80cbcba..e76f63aa2 100644 --- a/android/src/main/java/com/airbnb/android/react/maps/MapsPackage.java +++ b/android/src/main/java/com/airbnb/android/react/maps/MapsPackage.java @@ -14,7 +14,7 @@ public class MapsPackage implements ReactPackage { public MapsPackage(Activity activity) { - } // backwards compatability + } // backwards compatibility public MapsPackage() { } diff --git a/docs/mapview.md b/docs/mapview.md index f83bf1834..f242f636b 100644 --- a/docs/mapview.md +++ b/docs/mapview.md @@ -26,7 +26,7 @@ | `scrollEnabled` | `Boolean` | `true` | If `false` the user won't be able to change the map region being displayed. | `pitchEnabled` | `Boolean` | `true` | If `false` the user won't be able to adjust the camera’s pitch angle. | `toolbarEnabled` | `Boolean` | `true` | `Android only` If `false` will hide 'Navigate' and 'Open in Maps' buttons on marker press -| `cacheEnabled` | `Boolean` | `false` | If `true` map will be cached and displayed as a image instead of being interactable, for performance usage. +| `cacheEnabled` | `Boolean` | `false` | If `true` map will be cached and displayed as an image instead of being interactable, for performance usage. | `loadingEnabled` | `Boolean` | `false` | If `true` a loading indicator will show while the map is loading. | `loadingIndicatorColor` | `Color` | `#606060` | Sets loading indicator color, default to `#606060`. | `loadingBackgroundColor` | `Color` | `#FFFFFF` | Sets loading background color, default to `#FFFFFF`. diff --git a/ios/AirMaps/AIRMapManager.m b/ios/AirMaps/AIRMapManager.m index 8dcaaacb4..1e2c3f5ac 100644 --- a/ios/AirMaps/AIRMapManager.m +++ b/ios/AirMaps/AIRMapManager.m @@ -685,7 +685,7 @@ - (void)_regionChanged:(AIRMap *)mapView mapView.region = region; } - // Continously observe region changes + // Continuously observe region changes [self _emitRegionChangeEvent:mapView continuous:YES]; } diff --git a/ios/AirMaps/Callout/SMCalloutView.h b/ios/AirMaps/Callout/SMCalloutView.h index f0a41a49c..1281c3030 100644 --- a/ios/AirMaps/Callout/SMCalloutView.h +++ b/ios/AirMaps/Callout/SMCalloutView.h @@ -183,7 +183,7 @@ extern NSTimeInterval const kSMCalloutViewRepositionDelayForUIScrollView; Typically you would return @c kSMCalloutViewRepositionDelayForUIScrollView if you're repositioning by calling @c [UIScrollView @c setContentOffset:animated:]. @param calloutView the @c SMCalloutView to reposition - @param offset caluclated offset necessary to make everything visible + @param offset calculated offset necessary to make everything visible @returns @c NSTimeInterval to delay the repositioning */ - (NSTimeInterval)calloutView:(SMCalloutView *)calloutView delayForRepositionWithSize:(CGSize)offset; From 6cd30add6b95ae69f0fbdc2a14adfbc394ed2a1e Mon Sep 17 00:00:00 2001 From: Leland Richardson Date: Sun, 26 Mar 2017 15:53:40 -0700 Subject: [PATCH 081/199] Restructure project --- .babelrc | 14 + .bundle/config | 2 + .eslintrc | 3 +- .gitignore | 2 + .travis.yml | 3 +- Gemfile | 3 + example/ios/Gemfile.lock => Gemfile.lock | 51 ++-- android/build.gradle | 59 ---- build.gradle | 25 ++ example/android/app/build.gradle | 24 +- example/android/app/react.gradle | 97 ------- .../maps/example/ExampleApplication.java | 16 +- example/android/build.gradle | 24 -- example/android/gradle.properties | 19 -- example/android/settings.gradle | 2 - example/index.android.js | 11 - example/index.ios.js | 11 - example/index.js | 4 + .../AirMapsExplorer.xcodeproj/project.pbxproj | 258 ++---------------- example/ios/AirMapsExplorer/AppDelegate.m | 2 +- .../AppIcon.appiconset/Contents.json | 10 + example/ios/Gemfile | 2 - example/ios/Podfile | 9 +- example/ios/Podfile.lock | 79 ++++-- example/ios/bundler | 17 ++ example/ios/fuzzy_match | 17 ++ example/ios/pod | 17 ++ example/package.json | 24 -- example/scripts/.eslintrc | 6 - example/scripts/watch-and-copy-src.js | 51 ---- gradle/wrapper/gradle-wrapper.jar | Bin 0 -> 54208 bytes gradle/wrapper/gradle-wrapper.properties | 6 + example/android/gradlew => gradlew | 74 ++--- example/android/gradlew.bat => gradlew.bat | 14 +- index.js | 2 +- lib/android/build.gradle | 40 +++ .../android}/gradle-maven-push.gradle | 0 {android => lib/android}/gradle.properties | 0 .../gradle/wrapper/gradle-wrapper.jar | Bin .../gradle/wrapper/gradle-wrapper.properties | 0 {android => lib/android}/gradlew | 0 {android => lib/android}/gradlew.bat | 0 .../android}/src/main/AndroidManifest.xml | 0 .../android/react/maps/AirMapCallout.java | 0 .../react/maps/AirMapCalloutManager.java | 0 .../android/react/maps/AirMapCircle.java | 0 .../react/maps/AirMapCircleManager.java | 0 .../android/react/maps/AirMapFeature.java | 0 .../android/react/maps/AirMapLiteManager.java | 0 .../android/react/maps/AirMapManager.java | 0 .../android/react/maps/AirMapMarker.java | 0 .../react/maps/AirMapMarkerManager.java | 0 .../android/react/maps/AirMapModule.java | 0 .../android/react/maps/AirMapPolygon.java | 0 .../react/maps/AirMapPolygonManager.java | 0 .../android/react/maps/AirMapPolyline.java | 0 .../react/maps/AirMapPolylineManager.java | 0 .../android/react/maps/AirMapUrlTile.java | 0 .../react/maps/AirMapUrlTileManager.java | 0 .../airbnb/android/react/maps/AirMapView.java | 0 .../android/react/maps/LatLngBoundsUtils.java | 0 .../android/react/maps/MapsPackage.java | 0 .../android/react/maps/RegionChangeEvent.java | 0 .../react/maps/SizeReportingShadowNode.java | 0 .../components}/AnimatedRegion.js | 0 {components => lib/components}/MapCallout.js | 0 {components => lib/components}/MapCircle.js | 0 {components => lib/components}/MapMarker.js | 0 {components => lib/components}/MapPolygon.js | 0 {components => lib/components}/MapPolyline.js | 0 {components => lib/components}/MapUrlTile.js | 0 {components => lib/components}/MapView.js | 0 .../components}/ProviderConstants.js | 0 .../components}/decorateMapComponent.js | 0 {ios => lib/ios}/AirGoogleMaps/AIRGMSMarker.h | 0 {ios => lib/ios}/AirGoogleMaps/AIRGMSMarker.m | 0 .../ios}/AirGoogleMaps/AIRGMSPolygon.h | 0 .../ios}/AirGoogleMaps/AIRGMSPolygon.m | 0 {ios => lib/ios}/AirGoogleMaps/AIRGoogleMap.h | 0 {ios => lib/ios}/AirGoogleMaps/AIRGoogleMap.m | 0 .../ios}/AirGoogleMaps/AIRGoogleMapCallout.h | 0 .../ios}/AirGoogleMaps/AIRGoogleMapCallout.m | 0 .../AIRGoogleMapCalloutManager.h | 0 .../AIRGoogleMapCalloutManager.m | 0 .../ios}/AirGoogleMaps/AIRGoogleMapCircle.h | 0 .../ios}/AirGoogleMaps/AIRGoogleMapCircle.m | 0 .../AirGoogleMaps/AIRGoogleMapCircleManager.h | 0 .../AirGoogleMaps/AIRGoogleMapCircleManager.m | 0 .../ios}/AirGoogleMaps/AIRGoogleMapManager.h | 0 .../ios}/AirGoogleMaps/AIRGoogleMapManager.m | 0 .../ios}/AirGoogleMaps/AIRGoogleMapMarker.h | 0 .../ios}/AirGoogleMaps/AIRGoogleMapMarker.m | 0 .../AirGoogleMaps/AIRGoogleMapMarkerManager.h | 0 .../AirGoogleMaps/AIRGoogleMapMarkerManager.m | 0 .../ios}/AirGoogleMaps/AIRGoogleMapPolygon.h | 0 .../ios}/AirGoogleMaps/AIRGoogleMapPolygon.m | 0 .../AIRGoogleMapPolygonManager.h | 0 .../AIRGoogleMapPolygonManager.m | 0 .../ios}/AirGoogleMaps/AIRGoogleMapPolyline.h | 0 .../ios}/AirGoogleMaps/AIRGoogleMapPolyline.m | 0 .../AIRGoogleMapPolylineManager.h | 0 .../AIRGoogleMapPolylineManager.m | 0 .../AIRGoogleMapURLTileManager.m | 0 .../ios}/AirGoogleMaps/AIRGoogleMapUrlTile.h | 0 .../ios}/AirGoogleMaps/AIRGoogleMapUrlTile.m | 0 .../AIRGoogleMapUrlTileManager.h | 0 {ios => lib/ios}/AirGoogleMaps/DummyView.h | 0 {ios => lib/ios}/AirGoogleMaps/DummyView.m | 0 .../AirGoogleMaps/RCTConvert+GMSMapViewType.h | 0 .../AirGoogleMaps/RCTConvert+GMSMapViewType.m | 0 .../ios}/AirMaps.xcodeproj/project.pbxproj | 0 {ios => lib/ios}/AirMaps/AIRMap.h | 0 {ios => lib/ios}/AirMaps/AIRMap.m | 0 {ios => lib/ios}/AirMaps/AIRMapCallout.h | 0 {ios => lib/ios}/AirMaps/AIRMapCallout.m | 0 .../ios}/AirMaps/AIRMapCalloutManager.h | 0 .../ios}/AirMaps/AIRMapCalloutManager.m | 0 {ios => lib/ios}/AirMaps/AIRMapCircle.h | 0 {ios => lib/ios}/AirMaps/AIRMapCircle.m | 0 .../ios}/AirMaps/AIRMapCircleManager.h | 0 .../ios}/AirMaps/AIRMapCircleManager.m | 0 {ios => lib/ios}/AirMaps/AIRMapCoordinate.h | 0 {ios => lib/ios}/AirMaps/AIRMapCoordinate.m | 0 {ios => lib/ios}/AirMaps/AIRMapManager.h | 0 {ios => lib/ios}/AirMaps/AIRMapManager.m | 0 {ios => lib/ios}/AirMaps/AIRMapMarker.h | 0 {ios => lib/ios}/AirMaps/AIRMapMarker.m | 0 .../ios}/AirMaps/AIRMapMarkerManager.h | 0 .../ios}/AirMaps/AIRMapMarkerManager.m | 0 {ios => lib/ios}/AirMaps/AIRMapPolygon.h | 0 {ios => lib/ios}/AirMaps/AIRMapPolygon.m | 0 .../ios}/AirMaps/AIRMapPolygonManager.h | 0 .../ios}/AirMaps/AIRMapPolygonManager.m | 0 {ios => lib/ios}/AirMaps/AIRMapPolyline.h | 0 {ios => lib/ios}/AirMaps/AIRMapPolyline.m | 0 .../ios}/AirMaps/AIRMapPolylineManager.h | 0 .../ios}/AirMaps/AIRMapPolylineManager.m | 0 {ios => lib/ios}/AirMaps/AIRMapSnapshot.h | 0 {ios => lib/ios}/AirMaps/AIRMapUrlTile.h | 0 {ios => lib/ios}/AirMaps/AIRMapUrlTile.m | 0 .../ios}/AirMaps/AIRMapUrlTileManager.h | 0 .../ios}/AirMaps/AIRMapUrlTileManager.m | 0 .../ios}/AirMaps/Callout/SMCalloutView.h | 0 .../ios}/AirMaps/Callout/SMCalloutView.m | 0 {ios => lib/ios}/AirMaps/RCTConvert+MapKit.h | 0 {ios => lib/ios}/AirMaps/RCTConvert+MapKit.m | 0 package.json | 22 +- react-native-google-maps.podspec | 8 +- react-native-maps.podspec | 8 +- rn-cli.config.js | 11 + scripts/update-version.js | 6 +- settings.gradle | 7 + 152 files changed, 391 insertions(+), 669 deletions(-) create mode 100644 .babelrc create mode 100644 .bundle/config create mode 100644 Gemfile rename example/ios/Gemfile.lock => Gemfile.lock (64%) delete mode 100644 android/build.gradle create mode 100644 build.gradle delete mode 100644 example/android/app/react.gradle delete mode 100644 example/android/build.gradle delete mode 100644 example/android/gradle.properties delete mode 100644 example/android/settings.gradle delete mode 100644 example/index.android.js delete mode 100644 example/index.ios.js create mode 100644 example/index.js delete mode 100644 example/ios/Gemfile create mode 100755 example/ios/bundler create mode 100755 example/ios/fuzzy_match create mode 100755 example/ios/pod delete mode 100644 example/package.json delete mode 100644 example/scripts/.eslintrc delete mode 100644 example/scripts/watch-and-copy-src.js create mode 100644 gradle/wrapper/gradle-wrapper.jar create mode 100644 gradle/wrapper/gradle-wrapper.properties rename example/android/gradlew => gradlew (83%) rename example/android/gradlew.bat => gradlew.bat (88%) create mode 100644 lib/android/build.gradle rename {android => lib/android}/gradle-maven-push.gradle (100%) rename {android => lib/android}/gradle.properties (100%) rename {android => lib/android}/gradle/wrapper/gradle-wrapper.jar (100%) rename {android => lib/android}/gradle/wrapper/gradle-wrapper.properties (100%) rename {android => lib/android}/gradlew (100%) rename {android => lib/android}/gradlew.bat (100%) rename {android => lib/android}/src/main/AndroidManifest.xml (100%) rename {android => lib/android}/src/main/java/com/airbnb/android/react/maps/AirMapCallout.java (100%) rename {android => lib/android}/src/main/java/com/airbnb/android/react/maps/AirMapCalloutManager.java (100%) rename {android => lib/android}/src/main/java/com/airbnb/android/react/maps/AirMapCircle.java (100%) rename {android => lib/android}/src/main/java/com/airbnb/android/react/maps/AirMapCircleManager.java (100%) rename {android => lib/android}/src/main/java/com/airbnb/android/react/maps/AirMapFeature.java (100%) rename {android => lib/android}/src/main/java/com/airbnb/android/react/maps/AirMapLiteManager.java (100%) rename {android => lib/android}/src/main/java/com/airbnb/android/react/maps/AirMapManager.java (100%) rename {android => lib/android}/src/main/java/com/airbnb/android/react/maps/AirMapMarker.java (100%) rename {android => lib/android}/src/main/java/com/airbnb/android/react/maps/AirMapMarkerManager.java (100%) rename {android => lib/android}/src/main/java/com/airbnb/android/react/maps/AirMapModule.java (100%) rename {android => lib/android}/src/main/java/com/airbnb/android/react/maps/AirMapPolygon.java (100%) rename {android => lib/android}/src/main/java/com/airbnb/android/react/maps/AirMapPolygonManager.java (100%) rename {android => lib/android}/src/main/java/com/airbnb/android/react/maps/AirMapPolyline.java (100%) rename {android => lib/android}/src/main/java/com/airbnb/android/react/maps/AirMapPolylineManager.java (100%) rename {android => lib/android}/src/main/java/com/airbnb/android/react/maps/AirMapUrlTile.java (100%) rename {android => lib/android}/src/main/java/com/airbnb/android/react/maps/AirMapUrlTileManager.java (100%) rename {android => lib/android}/src/main/java/com/airbnb/android/react/maps/AirMapView.java (100%) rename {android => lib/android}/src/main/java/com/airbnb/android/react/maps/LatLngBoundsUtils.java (100%) rename {android => lib/android}/src/main/java/com/airbnb/android/react/maps/MapsPackage.java (100%) rename {android => lib/android}/src/main/java/com/airbnb/android/react/maps/RegionChangeEvent.java (100%) rename {android => lib/android}/src/main/java/com/airbnb/android/react/maps/SizeReportingShadowNode.java (100%) rename {components => lib/components}/AnimatedRegion.js (100%) rename {components => lib/components}/MapCallout.js (100%) rename {components => lib/components}/MapCircle.js (100%) rename {components => lib/components}/MapMarker.js (100%) rename {components => lib/components}/MapPolygon.js (100%) rename {components => lib/components}/MapPolyline.js (100%) rename {components => lib/components}/MapUrlTile.js (100%) rename {components => lib/components}/MapView.js (100%) rename {components => lib/components}/ProviderConstants.js (100%) rename {components => lib/components}/decorateMapComponent.js (100%) rename {ios => lib/ios}/AirGoogleMaps/AIRGMSMarker.h (100%) rename {ios => lib/ios}/AirGoogleMaps/AIRGMSMarker.m (100%) rename {ios => lib/ios}/AirGoogleMaps/AIRGMSPolygon.h (100%) rename {ios => lib/ios}/AirGoogleMaps/AIRGMSPolygon.m (100%) rename {ios => lib/ios}/AirGoogleMaps/AIRGoogleMap.h (100%) rename {ios => lib/ios}/AirGoogleMaps/AIRGoogleMap.m (100%) rename {ios => lib/ios}/AirGoogleMaps/AIRGoogleMapCallout.h (100%) rename {ios => lib/ios}/AirGoogleMaps/AIRGoogleMapCallout.m (100%) rename {ios => lib/ios}/AirGoogleMaps/AIRGoogleMapCalloutManager.h (100%) rename {ios => lib/ios}/AirGoogleMaps/AIRGoogleMapCalloutManager.m (100%) rename {ios => lib/ios}/AirGoogleMaps/AIRGoogleMapCircle.h (100%) rename {ios => lib/ios}/AirGoogleMaps/AIRGoogleMapCircle.m (100%) rename {ios => lib/ios}/AirGoogleMaps/AIRGoogleMapCircleManager.h (100%) rename {ios => lib/ios}/AirGoogleMaps/AIRGoogleMapCircleManager.m (100%) rename {ios => lib/ios}/AirGoogleMaps/AIRGoogleMapManager.h (100%) rename {ios => lib/ios}/AirGoogleMaps/AIRGoogleMapManager.m (100%) rename {ios => lib/ios}/AirGoogleMaps/AIRGoogleMapMarker.h (100%) rename {ios => lib/ios}/AirGoogleMaps/AIRGoogleMapMarker.m (100%) rename {ios => lib/ios}/AirGoogleMaps/AIRGoogleMapMarkerManager.h (100%) rename {ios => lib/ios}/AirGoogleMaps/AIRGoogleMapMarkerManager.m (100%) rename {ios => lib/ios}/AirGoogleMaps/AIRGoogleMapPolygon.h (100%) rename {ios => lib/ios}/AirGoogleMaps/AIRGoogleMapPolygon.m (100%) rename {ios => lib/ios}/AirGoogleMaps/AIRGoogleMapPolygonManager.h (100%) rename {ios => lib/ios}/AirGoogleMaps/AIRGoogleMapPolygonManager.m (100%) rename {ios => lib/ios}/AirGoogleMaps/AIRGoogleMapPolyline.h (100%) rename {ios => lib/ios}/AirGoogleMaps/AIRGoogleMapPolyline.m (100%) rename {ios => lib/ios}/AirGoogleMaps/AIRGoogleMapPolylineManager.h (100%) rename {ios => lib/ios}/AirGoogleMaps/AIRGoogleMapPolylineManager.m (100%) rename {ios => lib/ios}/AirGoogleMaps/AIRGoogleMapURLTileManager.m (100%) rename {ios => lib/ios}/AirGoogleMaps/AIRGoogleMapUrlTile.h (100%) rename {ios => lib/ios}/AirGoogleMaps/AIRGoogleMapUrlTile.m (100%) rename {ios => lib/ios}/AirGoogleMaps/AIRGoogleMapUrlTileManager.h (100%) rename {ios => lib/ios}/AirGoogleMaps/DummyView.h (100%) rename {ios => lib/ios}/AirGoogleMaps/DummyView.m (100%) rename {ios => lib/ios}/AirGoogleMaps/RCTConvert+GMSMapViewType.h (100%) rename {ios => lib/ios}/AirGoogleMaps/RCTConvert+GMSMapViewType.m (100%) rename {ios => lib/ios}/AirMaps.xcodeproj/project.pbxproj (100%) rename {ios => lib/ios}/AirMaps/AIRMap.h (100%) rename {ios => lib/ios}/AirMaps/AIRMap.m (100%) rename {ios => lib/ios}/AirMaps/AIRMapCallout.h (100%) rename {ios => lib/ios}/AirMaps/AIRMapCallout.m (100%) rename {ios => lib/ios}/AirMaps/AIRMapCalloutManager.h (100%) rename {ios => lib/ios}/AirMaps/AIRMapCalloutManager.m (100%) rename {ios => lib/ios}/AirMaps/AIRMapCircle.h (100%) rename {ios => lib/ios}/AirMaps/AIRMapCircle.m (100%) rename {ios => lib/ios}/AirMaps/AIRMapCircleManager.h (100%) rename {ios => lib/ios}/AirMaps/AIRMapCircleManager.m (100%) rename {ios => lib/ios}/AirMaps/AIRMapCoordinate.h (100%) rename {ios => lib/ios}/AirMaps/AIRMapCoordinate.m (100%) rename {ios => lib/ios}/AirMaps/AIRMapManager.h (100%) rename {ios => lib/ios}/AirMaps/AIRMapManager.m (100%) rename {ios => lib/ios}/AirMaps/AIRMapMarker.h (100%) rename {ios => lib/ios}/AirMaps/AIRMapMarker.m (100%) rename {ios => lib/ios}/AirMaps/AIRMapMarkerManager.h (100%) rename {ios => lib/ios}/AirMaps/AIRMapMarkerManager.m (100%) rename {ios => lib/ios}/AirMaps/AIRMapPolygon.h (100%) rename {ios => lib/ios}/AirMaps/AIRMapPolygon.m (100%) rename {ios => lib/ios}/AirMaps/AIRMapPolygonManager.h (100%) rename {ios => lib/ios}/AirMaps/AIRMapPolygonManager.m (100%) rename {ios => lib/ios}/AirMaps/AIRMapPolyline.h (100%) rename {ios => lib/ios}/AirMaps/AIRMapPolyline.m (100%) rename {ios => lib/ios}/AirMaps/AIRMapPolylineManager.h (100%) rename {ios => lib/ios}/AirMaps/AIRMapPolylineManager.m (100%) rename {ios => lib/ios}/AirMaps/AIRMapSnapshot.h (100%) rename {ios => lib/ios}/AirMaps/AIRMapUrlTile.h (100%) rename {ios => lib/ios}/AirMaps/AIRMapUrlTile.m (100%) rename {ios => lib/ios}/AirMaps/AIRMapUrlTileManager.h (100%) rename {ios => lib/ios}/AirMaps/AIRMapUrlTileManager.m (100%) rename {ios => lib/ios}/AirMaps/Callout/SMCalloutView.h (100%) rename {ios => lib/ios}/AirMaps/Callout/SMCalloutView.m (100%) rename {ios => lib/ios}/AirMaps/RCTConvert+MapKit.h (100%) rename {ios => lib/ios}/AirMaps/RCTConvert+MapKit.m (100%) create mode 100644 rn-cli.config.js create mode 100644 settings.gradle diff --git a/.babelrc b/.babelrc new file mode 100644 index 000000000..e4e14594b --- /dev/null +++ b/.babelrc @@ -0,0 +1,14 @@ +{ + "presets": ["react-native"], + "plugins": [ + [ + "module-resolver", + { + "alias": { + "react-native-maps": "./" + }, + "cwd": "babelrc" + } + ] + ] +} diff --git a/.bundle/config b/.bundle/config new file mode 100644 index 000000000..671243892 --- /dev/null +++ b/.bundle/config @@ -0,0 +1,2 @@ +--- +BUNDLE_BIN: "./examples/ios" diff --git a/.eslintrc b/.eslintrc index 5cfda8e5d..7b768ff92 100644 --- a/.eslintrc +++ b/.eslintrc @@ -11,6 +11,7 @@ "react/sort-comp": 0, "no-use-before-define": 0, "no-underscore-dangle": 0, - "import/no-unresolved": [2, { "ignore": ["react"] }] + "import/no-extraneous-dependencies": 0, + "import/no-unresolved": [2, { "ignore": ["^react-native-maps"] }] } } diff --git a/.gitignore b/.gitignore index a2f0b339f..dc4d6bb16 100644 --- a/.gitignore +++ b/.gitignore @@ -35,3 +35,5 @@ node_modules/ npm-debug.log Pods/ AirMapsExplorer.xcworkspace/ +lib/android/src/main/gen +example/android/app/src/main/gen diff --git a/.travis.yml b/.travis.yml index 5e075585c..34c6353e8 100644 --- a/.travis.yml +++ b/.travis.yml @@ -6,6 +6,5 @@ node_js: cache: directories: - node_modules - - example/node_modules -script: npm run lint +script: npm run ci diff --git a/Gemfile b/Gemfile new file mode 100644 index 000000000..e696ba58e --- /dev/null +++ b/Gemfile @@ -0,0 +1,3 @@ +source 'https://rubygems.org' +ruby '2.2.4' +gem 'cocoapods', '1.2.0' diff --git a/example/ios/Gemfile.lock b/Gemfile.lock similarity index 64% rename from example/ios/Gemfile.lock rename to Gemfile.lock index b8c6feba0..9265653cd 100644 --- a/example/ios/Gemfile.lock +++ b/Gemfile.lock @@ -1,43 +1,43 @@ GEM remote: https://rubygems.org/ specs: - CFPropertyList (2.3.3) - activesupport (4.2.7.1) + CFPropertyList (2.3.5) + activesupport (4.2.8) i18n (~> 0.7) - json (~> 1.7, >= 1.7.7) minitest (~> 5.1) thread_safe (~> 0.3, >= 0.3.4) tzinfo (~> 1.1) claide (1.0.1) - cocoapods (1.1.1) + cocoapods (1.2.0) activesupport (>= 4.0.2, < 5) claide (>= 1.0.1, < 2.0) - cocoapods-core (= 1.1.1) + cocoapods-core (= 1.2.0) cocoapods-deintegrate (>= 1.0.1, < 2.0) - cocoapods-downloader (>= 1.1.2, < 2.0) + cocoapods-downloader (>= 1.1.3, < 2.0) cocoapods-plugins (>= 1.0.0, < 2.0) cocoapods-search (>= 1.0.0, < 2.0) cocoapods-stats (>= 1.0.0, < 2.0) - cocoapods-trunk (>= 1.1.1, < 2.0) + cocoapods-trunk (>= 1.1.2, < 2.0) cocoapods-try (>= 1.1.0, < 2.0) colored (~> 1.2) escape (~> 0.0.4) fourflusher (~> 2.0.1) gh_inspector (~> 1.0) - molinillo (~> 0.5.1) + molinillo (~> 0.5.5) nap (~> 1.0) - xcodeproj (>= 1.3.3, < 2.0) - cocoapods-core (1.1.1) + ruby-macho (~> 0.2.5) + xcodeproj (>= 1.4.1, < 2.0) + cocoapods-core (1.2.0) activesupport (>= 4.0.2, < 5) fuzzy_match (~> 2.0.4) nap (~> 1.0) cocoapods-deintegrate (1.0.1) - cocoapods-downloader (1.1.2) + cocoapods-downloader (1.1.3) cocoapods-plugins (1.0.0) nap cocoapods-search (1.0.0) cocoapods-stats (1.0.0) - cocoapods-trunk (1.1.1) + cocoapods-trunk (1.1.2) nap (>= 0.8, < 2.0) netrc (= 0.7.8) cocoapods-try (1.1.0) @@ -45,29 +45,32 @@ GEM escape (0.0.4) fourflusher (2.0.1) fuzzy_match (2.0.4) - gh_inspector (1.0.2) - i18n (0.7.0) - json (1.8.3) - minitest (5.9.1) - molinillo (0.5.3) - nanaimo (0.2.2) + gh_inspector (1.0.3) + i18n (0.8.1) + minitest (5.10.1) + molinillo (0.5.7) + nanaimo (0.2.3) nap (1.1.0) netrc (0.7.8) - thread_safe (0.3.5) - tzinfo (1.2.2) + ruby-macho (0.2.6) + thread_safe (0.3.6) + tzinfo (1.2.3) thread_safe (~> 0.1) - xcodeproj (1.4.1) + xcodeproj (1.4.2) CFPropertyList (~> 2.3.3) activesupport (>= 3) claide (>= 1.0.1, < 2.0) colored (~> 1.2) - nanaimo (~> 0.2.0) + nanaimo (~> 0.2.3) PLATFORMS ruby DEPENDENCIES - cocoapods (~> 1.1.1) + cocoapods (= 1.2.0) + +RUBY VERSION + ruby 2.2.4p230 BUNDLED WITH - 1.10.6 + 1.14.6 diff --git a/android/build.gradle b/android/build.gradle deleted file mode 100644 index 806c85d48..000000000 --- a/android/build.gradle +++ /dev/null @@ -1,59 +0,0 @@ -// Top-level build file where you can add configuration options common to all sub-projects/modules. - -apply plugin: 'com.android.library' -apply from: 'gradle-maven-push.gradle' - -buildscript { - repositories { - mavenLocal() - jcenter() - maven { - // For developing the library outside the context of the example app, expect `react-native` - // to be installed at `./node_modules`. - url "$projectDir/../node_modules/react-native/android" - } - maven { - // For developing the example app. - url "$projectDir/../../react-native/android" - } - } - dependencies { - classpath 'com.android.tools.build:gradle:2.2.3' - } -} - -allprojects { - repositories { - mavenLocal() - jcenter() - maven { - // For developing the library outside the context of the example app, expect `react-native` - // to be installed at `./node_modules`. - url "$projectDir/../node_modules/react-native/android" - } - maven { - // For developing the example app. - url "$projectDir/../../react-native/android" - } - } -} - -android { - compileSdkVersion 25 - buildToolsVersion "25.0.0" - - defaultConfig { - minSdkVersion 16 - targetSdkVersion 25 - } - - lintOptions { - disable 'InvalidPackage' - } -} - -dependencies { - provided "com.facebook.react:react-native:+" - compile "com.google.android.gms:play-services-base:10.0.1" - compile "com.google.android.gms:play-services-maps:10.0.1" -} diff --git a/build.gradle b/build.gradle new file mode 100644 index 000000000..f89d2c594 --- /dev/null +++ b/build.gradle @@ -0,0 +1,25 @@ +// Top-level build file where you can add configuration options common to all sub-projects/modules. + +buildscript { + repositories { + jcenter() + } + dependencies { + classpath 'com.android.tools.build:gradle:2.3.0' + } +} + +allprojects { + repositories { + mavenLocal() + jcenter() + maven { + // All of React Native (JS, Obj-C sources, Android binaries) is installed from npm + url "$rootDir/node_modules/react-native/android" + } + } +} + +task clean(type: Delete) { + delete rootProject.buildDir +} diff --git a/example/android/app/build.gradle b/example/android/app/build.gradle index 5e58e57b5..c5bdebe4c 100644 --- a/example/android/app/build.gradle +++ b/example/android/app/build.gradle @@ -59,7 +59,22 @@ import com.android.build.OutputFile * ] */ -apply from: "react.gradle" +project.ext.react = [ + // the name of the generated asset file containing your JS bundle + bundleAssetName : "example.bundle", + + // the entry file for bundle generation + entryFile : "index.js", + + // the root of your project, i.e. where "package.json" lives + root : "../../../", + + // supply additional arguments to the packager + extraPackagerArgs: [] +] + + +apply from: "../../../node_modules/react-native/react.gradle" def enableSeparateBuildPerCPUArchitecture = false @@ -70,7 +85,7 @@ def enableProguardInReleaseBuilds = false android { compileSdkVersion 25 - buildToolsVersion "25.0.0" + buildToolsVersion "25.0.2" defaultConfig { applicationId "com.airbnb.android.react.maps.example" @@ -112,5 +127,8 @@ android { } dependencies { - compile project(':react-native-maps') + compile 'com.facebook.react:react-native:0.42.+' + compile 'com.android.support:appcompat-v7:25.1.1' + compile 'com.android.support:support-annotations:25.1.1' + compile project(':react-native-maps-lib') } diff --git a/example/android/app/react.gradle b/example/android/app/react.gradle deleted file mode 100644 index 11a4f8b87..000000000 --- a/example/android/app/react.gradle +++ /dev/null @@ -1,97 +0,0 @@ -import org.apache.tools.ant.taskdefs.condition.Os - -def config = project.hasProperty("react") ? project.react : []; - -def bundleAssetName = config.bundleAssetName ?: "index.android.bundle" -def entryFile = config.entryFile ?: "index.android.js" - -// because elvis operator -def elvisFile(thing) { - return thing ? file(thing) : null; -} - -def reactRoot = elvisFile(config.root) ?: file("../../") -def inputExcludes = config.inputExcludes ?: ["android/**", "ios/**"] - -void runBefore(String dependentTaskName, Task task) { - Task dependentTask = tasks.findByPath(dependentTaskName); - if (dependentTask != null) { - dependentTask.dependsOn task - } -} - -gradle.projectsEvaluated { - // Grab all build types and product flavors - def buildTypes = android.buildTypes.collect { type -> type.name } - def productFlavors = android.productFlavors.collect { flavor -> flavor.name } - - // When no product flavors defined, use empty - if (!productFlavors) productFlavors.add('') - - productFlavors.each { productFlavorName -> - buildTypes.each { buildTypeName -> - // Create variant and target names - def targetName = "${productFlavorName.capitalize()}${buildTypeName.capitalize()}" - def targetPath = productFlavorName ? - "${productFlavorName}/${buildTypeName}" : - "${buildTypeName}" - - // React js bundle directories - def jsBundleDirConfigName = "jsBundleDir${targetName}" - def jsBundleDir = elvisFile(config."$jsBundleDirConfigName") ?: - file("$buildDir/intermediates/assets/${targetPath}") - - def resourcesDirConfigName = "jsBundleDir${targetName}" - def resourcesDir = elvisFile(config."${resourcesDirConfigName}") ?: - file("$buildDir/intermediates/res/merged/${targetPath}") - def jsBundleFile = file("$jsBundleDir/$bundleAssetName") - - // Bundle task name for variant - def bundleJsAndAssetsTaskName = "bundle${targetName}JsAndAssets" - - def currentBundleTask = tasks.create( - name: bundleJsAndAssetsTaskName, - type: Exec) { - group = "react" - description = "bundle JS and assets for ${targetName}." - - // Create dirs if they are not there (e.g. the "clean" task just ran) - doFirst { - jsBundleDir.mkdirs() - resourcesDir.mkdirs() - } - - // Set up inputs and outputs so gradle can cache the result - inputs.files fileTree(dir: reactRoot, excludes: inputExcludes) - outputs.dir jsBundleDir - outputs.dir resourcesDir - - // Set up the call to the react-native cli - workingDir reactRoot - - // Set up dev mode - def devEnabled = !targetName.toLowerCase().contains("release") - if (Os.isFamily(Os.FAMILY_WINDOWS)) { - commandLine "cmd", "/c", "react-native", "bundle", "--platform", "android", "--dev", "${devEnabled}", - "--entry-file", entryFile, "--bundle-output", jsBundleFile, "--assets-dest", resourcesDir - } else { - commandLine "react-native", "bundle", "--platform", "android", "--dev", "${devEnabled}", - "--entry-file", entryFile, "--bundle-output", jsBundleFile, "--assets-dest", resourcesDir - } - - enabled config."bundleIn${targetName}" || - config."bundleIn${buildTypeName.capitalize()}" ?: - targetName.toLowerCase().contains("release") - } - - // Hook bundle${productFlavor}${buildType}JsAndAssets into the android build process - currentBundleTask.dependsOn("merge${targetName}Resources") - currentBundleTask.dependsOn("merge${targetName}Assets") - - runBefore("processArmeabi-v7a${targetName}Resources", currentBundleTask) - runBefore("processX86${targetName}Resources", currentBundleTask) - runBefore("processUniversal${targetName}Resources", currentBundleTask) - runBefore("process${targetName}Resources", currentBundleTask) - } - } -} diff --git a/example/android/app/src/main/java/com/airbnb/android/react/maps/example/ExampleApplication.java b/example/android/app/src/main/java/com/airbnb/android/react/maps/example/ExampleApplication.java index 1a7f6382f..30a52850a 100644 --- a/example/android/app/src/main/java/com/airbnb/android/react/maps/example/ExampleApplication.java +++ b/example/android/app/src/main/java/com/airbnb/android/react/maps/example/ExampleApplication.java @@ -7,16 +7,22 @@ import com.facebook.react.ReactNativeHost; import com.facebook.react.ReactPackage; import com.facebook.react.shell.MainReactPackage; +import com.facebook.soloader.SoLoader; import java.util.Arrays; import java.util.List; public class ExampleApplication extends Application implements ReactApplication { private final ReactNativeHost reactNativeHost = new ReactNativeHost(this) { - @Override protected boolean getUseDeveloperSupport() { + @Override public boolean getUseDeveloperSupport() { return BuildConfig.DEBUG; } + @Override + protected String getJSMainModuleName() { + return "example/index"; + } + @Override protected List getPackages() { return Arrays.asList( new MainReactPackage(), @@ -28,4 +34,10 @@ public class ExampleApplication extends Application implements ReactApplication public ReactNativeHost getReactNativeHost() { return reactNativeHost; } -} \ No newline at end of file + + @Override + public void onCreate() { + super.onCreate(); + SoLoader.init(this, /* native exopackage */ false); + } +} diff --git a/example/android/build.gradle b/example/android/build.gradle deleted file mode 100644 index b249b0409..000000000 --- a/example/android/build.gradle +++ /dev/null @@ -1,24 +0,0 @@ -// Top-level build file where you can add configuration options common to all sub-projects/modules. - -buildscript { - repositories { - jcenter() - } - dependencies { - classpath 'com.android.tools.build:gradle:2.2.1' - - // NOTE: Do not place your application dependencies here; they belong - // in the individual module build.gradle files - } -} - -allprojects { - repositories { - mavenLocal() - jcenter() - maven { - // All of React Native (JS, Obj-C sources, Android binaries) is installed from npm - url "$projectDir/../../node_modules/react-native/android" - } - } -} diff --git a/example/android/gradle.properties b/example/android/gradle.properties deleted file mode 100644 index c04c048e8..000000000 --- a/example/android/gradle.properties +++ /dev/null @@ -1,19 +0,0 @@ -# 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. -# Default value: -Xmx10248m -XX:MaxPermSize=256m -# org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8 - -# 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/example/android/settings.gradle b/example/android/settings.gradle deleted file mode 100644 index d9c3d2776..000000000 --- a/example/android/settings.gradle +++ /dev/null @@ -1,2 +0,0 @@ -include ':app', ':react-native-maps' -project(':react-native-maps').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-maps/android') diff --git a/example/index.android.js b/example/index.android.js deleted file mode 100644 index 3d259cfd3..000000000 --- a/example/index.android.js +++ /dev/null @@ -1,11 +0,0 @@ -import React from 'react'; -import { AppRegistry } from 'react-native'; -import App from './App'; - -class AirMapsExplorer extends React.Component { - render() { - return ; - } -} - -AppRegistry.registerComponent('AirMapsExplorer', () => AirMapsExplorer); diff --git a/example/index.ios.js b/example/index.ios.js deleted file mode 100644 index 3d259cfd3..000000000 --- a/example/index.ios.js +++ /dev/null @@ -1,11 +0,0 @@ -import React from 'react'; -import { AppRegistry } from 'react-native'; -import App from './App'; - -class AirMapsExplorer extends React.Component { - render() { - return ; - } -} - -AppRegistry.registerComponent('AirMapsExplorer', () => AirMapsExplorer); diff --git a/example/index.js b/example/index.js new file mode 100644 index 000000000..1fe6aeea0 --- /dev/null +++ b/example/index.js @@ -0,0 +1,4 @@ +import { AppRegistry } from 'react-native'; +import App from './App'; + +AppRegistry.registerComponent('AirMapsExplorer', () => App); diff --git a/example/ios/AirMapsExplorer.xcodeproj/project.pbxproj b/example/ios/AirMapsExplorer.xcodeproj/project.pbxproj index e2e276365..efeabceb4 100644 --- a/example/ios/AirMapsExplorer.xcodeproj/project.pbxproj +++ b/example/ios/AirMapsExplorer.xcodeproj/project.pbxproj @@ -11,45 +11,13 @@ 13B07FBD1A68108700A75B9A /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB11A68108700A75B9A /* LaunchScreen.xib */; }; 13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB51A68108700A75B9A /* Images.xcassets */; }; 13B07FC11A68108700A75B9A /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB71A68108700A75B9A /* main.m */; }; - 2166AB291D82EC56007538D7 /* AIRMap.m in Sources */ = {isa = PBXBuildFile; fileRef = 2166AAFC1D82EC56007538D7 /* AIRMap.m */; }; - 2166AB2A1D82EC56007538D7 /* AIRMapCallout.m in Sources */ = {isa = PBXBuildFile; fileRef = 2166AAFE1D82EC56007538D7 /* AIRMapCallout.m */; }; - 2166AB2B1D82EC56007538D7 /* AIRMapCalloutManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 2166AB001D82EC56007538D7 /* AIRMapCalloutManager.m */; }; - 2166AB2C1D82EC56007538D7 /* AIRMapCircle.m in Sources */ = {isa = PBXBuildFile; fileRef = 2166AB021D82EC56007538D7 /* AIRMapCircle.m */; }; - 2166AB2D1D82EC56007538D7 /* AIRMapCircleManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 2166AB041D82EC56007538D7 /* AIRMapCircleManager.m */; }; - 2166AB2E1D82EC56007538D7 /* AIRMapCoordinate.m in Sources */ = {isa = PBXBuildFile; fileRef = 2166AB061D82EC56007538D7 /* AIRMapCoordinate.m */; }; - 2166AB2F1D82EC56007538D7 /* AIRMapManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 2166AB081D82EC56007538D7 /* AIRMapManager.m */; }; - 2166AB301D82EC56007538D7 /* AIRMapMarker.m in Sources */ = {isa = PBXBuildFile; fileRef = 2166AB0A1D82EC56007538D7 /* AIRMapMarker.m */; }; - 2166AB311D82EC56007538D7 /* AIRMapMarkerManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 2166AB0C1D82EC56007538D7 /* AIRMapMarkerManager.m */; }; - 2166AB321D82EC56007538D7 /* AIRMapPolygon.m in Sources */ = {isa = PBXBuildFile; fileRef = 2166AB0E1D82EC56007538D7 /* AIRMapPolygon.m */; }; - 2166AB331D82EC56007538D7 /* AIRMapPolygonManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 2166AB101D82EC56007538D7 /* AIRMapPolygonManager.m */; }; - 2166AB341D82EC56007538D7 /* AIRMapPolyline.m in Sources */ = {isa = PBXBuildFile; fileRef = 2166AB121D82EC56007538D7 /* AIRMapPolyline.m */; }; - 2166AB351D82EC56007538D7 /* AIRMapPolylineManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 2166AB141D82EC56007538D7 /* AIRMapPolylineManager.m */; }; - 2166AB361D82EC56007538D7 /* SMCalloutView.m in Sources */ = {isa = PBXBuildFile; fileRef = 2166AB171D82EC56007538D7 /* SMCalloutView.m */; }; - 2166AB3E1D82EC56007538D7 /* RCTConvert+MapKit.m in Sources */ = {isa = PBXBuildFile; fileRef = 2166AB281D82EC56007538D7 /* RCTConvert+MapKit.m */; }; - 21D346651D933B8C002BAD8A /* AIRMapUrlTile.m in Sources */ = {isa = PBXBuildFile; fileRef = 21D346621D933B8C002BAD8A /* AIRMapUrlTile.m */; }; - 21D346661D933B8C002BAD8A /* AIRMapUrlTileManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 21D346641D933B8C002BAD8A /* AIRMapUrlTileManager.m */; }; 21E6570A1D77591400B75EE5 /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 21E657091D77591400B75EE5 /* SystemConfiguration.framework */; }; 21E6570C1D77591A00B75EE5 /* MobileCoreServices.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 21E6570B1D77591A00B75EE5 /* MobileCoreServices.framework */; }; 21E6570E1D77591F00B75EE5 /* MapKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 21E6570D1D77591F00B75EE5 /* MapKit.framework */; }; 21E657101D77594C00B75EE5 /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 21E6570F1D77594C00B75EE5 /* AudioToolbox.framework */; }; - 5647FBD81E47A82C0054FF00 /* AIRGMSPolygon.m in Sources */ = {isa = PBXBuildFile; fileRef = 5647FBD71E47A82C0054FF00 /* AIRGMSPolygon.m */; }; - 8620CC871DBD814A00B79BFE /* AIRGMSMarker.m in Sources */ = {isa = PBXBuildFile; fileRef = 8620CC6E1DBD814A00B79BFE /* AIRGMSMarker.m */; }; - 8620CC881DBD814A00B79BFE /* AIRGoogleMap.m in Sources */ = {isa = PBXBuildFile; fileRef = 8620CC701DBD814A00B79BFE /* AIRGoogleMap.m */; }; - 8620CC891DBD814A00B79BFE /* AIRGoogleMapCallout.m in Sources */ = {isa = PBXBuildFile; fileRef = 8620CC721DBD814A00B79BFE /* AIRGoogleMapCallout.m */; }; - 8620CC8A1DBD814A00B79BFE /* AIRGoogleMapCalloutManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 8620CC741DBD814A00B79BFE /* AIRGoogleMapCalloutManager.m */; }; - 8620CC8B1DBD814A00B79BFE /* AIRGoogleMapManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 8620CC761DBD814A00B79BFE /* AIRGoogleMapManager.m */; }; - 8620CC8C1DBD814A00B79BFE /* AIRGoogleMapMarker.m in Sources */ = {isa = PBXBuildFile; fileRef = 8620CC781DBD814A00B79BFE /* AIRGoogleMapMarker.m */; }; - 8620CC8D1DBD814A00B79BFE /* AIRGoogleMapMarkerManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 8620CC7A1DBD814A00B79BFE /* AIRGoogleMapMarkerManager.m */; }; - 8620CC8E1DBD814A00B79BFE /* AIRGoogleMapPolygon.m in Sources */ = {isa = PBXBuildFile; fileRef = 8620CC7C1DBD814A00B79BFE /* AIRGoogleMapPolygon.m */; }; - 8620CC8F1DBD814A00B79BFE /* AIRGoogleMapPolygonManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 8620CC7E1DBD814A00B79BFE /* AIRGoogleMapPolygonManager.m */; }; - 8620CC901DBD814A00B79BFE /* AIRGoogleMapPolyline.m in Sources */ = {isa = PBXBuildFile; fileRef = 8620CC801DBD814A00B79BFE /* AIRGoogleMapPolyline.m */; }; - 8620CC911DBD814A00B79BFE /* AIRGoogleMapPolylineManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 8620CC821DBD814A00B79BFE /* AIRGoogleMapPolylineManager.m */; }; - 8620CC921DBD814A00B79BFE /* DummyView.m in Sources */ = {isa = PBXBuildFile; fileRef = 8620CC841DBD814A00B79BFE /* DummyView.m */; }; - 8620CC931DBD814A00B79BFE /* RCTConvert+GMSMapViewType.m in Sources */ = {isa = PBXBuildFile; fileRef = 8620CC861DBD814A00B79BFE /* RCTConvert+GMSMapViewType.m */; }; - 8697D6221DBEDE6100DB7D0F /* AIRGoogleMapCircle.m in Sources */ = {isa = PBXBuildFile; fileRef = 8697D6211DBEDE6100DB7D0F /* AIRGoogleMapCircle.m */; }; - 8697D6251DBEE22B00DB7D0F /* AIRGoogleMapCircleManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 8697D6241DBEE22B00DB7D0F /* AIRGoogleMapCircleManager.m */; }; - 86DE6F881DCE7D21002A5053 /* AIRGoogleMapUrlTile.m in Sources */ = {isa = PBXBuildFile; fileRef = 86DE6F871DCE7D21002A5053 /* AIRGoogleMapUrlTile.m */; }; - 86DE6F8B1DCE8543002A5053 /* AIRGoogleMapURLTileManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 86DE6F8A1DCE8543002A5053 /* AIRGoogleMapURLTileManager.m */; }; + 8490F2161E8879FB000099F8 /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8490F2151E8879FB000099F8 /* CoreFoundation.framework */; }; + 8490F21A1E887A8F000099F8 /* CFNetwork.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8490F2191E887A8F000099F8 /* CFNetwork.framework */; }; + 8490F21C1E887AAC000099F8 /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8490F21B1E887AAC000099F8 /* Security.framework */; }; A622B8115793E41C70169A8B /* libPods-AirMapsExplorer.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 0E5044A406006E7C2A53E05C /* libPods-AirMapsExplorer.a */; }; /* End PBXBuildFile section */ @@ -79,80 +47,14 @@ 2166AAF41D823402007538D7 /* CoreText.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreText.framework; path = System/Library/Frameworks/CoreText.framework; sourceTree = SDKROOT; }; 2166AAF61D823407007538D7 /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; 2166AAF81D82E9D0007538D7 /* React.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = React.framework; path = "Pods/../build/Debug-iphoneos/React.framework"; sourceTree = ""; }; - 2166AAFB1D82EC56007538D7 /* AIRMap.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AIRMap.h; sourceTree = ""; }; - 2166AAFC1D82EC56007538D7 /* AIRMap.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AIRMap.m; sourceTree = ""; }; - 2166AAFD1D82EC56007538D7 /* AIRMapCallout.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AIRMapCallout.h; sourceTree = ""; }; - 2166AAFE1D82EC56007538D7 /* AIRMapCallout.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AIRMapCallout.m; sourceTree = ""; }; - 2166AAFF1D82EC56007538D7 /* AIRMapCalloutManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AIRMapCalloutManager.h; sourceTree = ""; }; - 2166AB001D82EC56007538D7 /* AIRMapCalloutManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AIRMapCalloutManager.m; sourceTree = ""; }; - 2166AB011D82EC56007538D7 /* AIRMapCircle.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AIRMapCircle.h; sourceTree = ""; }; - 2166AB021D82EC56007538D7 /* AIRMapCircle.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AIRMapCircle.m; sourceTree = ""; }; - 2166AB031D82EC56007538D7 /* AIRMapCircleManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AIRMapCircleManager.h; sourceTree = ""; }; - 2166AB041D82EC56007538D7 /* AIRMapCircleManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AIRMapCircleManager.m; sourceTree = ""; }; - 2166AB051D82EC56007538D7 /* AIRMapCoordinate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AIRMapCoordinate.h; sourceTree = ""; }; - 2166AB061D82EC56007538D7 /* AIRMapCoordinate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AIRMapCoordinate.m; sourceTree = ""; }; - 2166AB071D82EC56007538D7 /* AIRMapManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AIRMapManager.h; sourceTree = ""; }; - 2166AB081D82EC56007538D7 /* AIRMapManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AIRMapManager.m; sourceTree = ""; }; - 2166AB091D82EC56007538D7 /* AIRMapMarker.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AIRMapMarker.h; sourceTree = ""; }; - 2166AB0A1D82EC56007538D7 /* AIRMapMarker.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AIRMapMarker.m; sourceTree = ""; }; - 2166AB0B1D82EC56007538D7 /* AIRMapMarkerManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AIRMapMarkerManager.h; sourceTree = ""; }; - 2166AB0C1D82EC56007538D7 /* AIRMapMarkerManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AIRMapMarkerManager.m; sourceTree = ""; }; - 2166AB0D1D82EC56007538D7 /* AIRMapPolygon.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AIRMapPolygon.h; sourceTree = ""; }; - 2166AB0E1D82EC56007538D7 /* AIRMapPolygon.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AIRMapPolygon.m; sourceTree = ""; }; - 2166AB0F1D82EC56007538D7 /* AIRMapPolygonManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AIRMapPolygonManager.h; sourceTree = ""; }; - 2166AB101D82EC56007538D7 /* AIRMapPolygonManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AIRMapPolygonManager.m; sourceTree = ""; }; - 2166AB111D82EC56007538D7 /* AIRMapPolyline.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AIRMapPolyline.h; sourceTree = ""; }; - 2166AB121D82EC56007538D7 /* AIRMapPolyline.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AIRMapPolyline.m; sourceTree = ""; }; - 2166AB131D82EC56007538D7 /* AIRMapPolylineManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AIRMapPolylineManager.h; sourceTree = ""; }; - 2166AB141D82EC56007538D7 /* AIRMapPolylineManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AIRMapPolylineManager.m; sourceTree = ""; }; - 2166AB161D82EC56007538D7 /* SMCalloutView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SMCalloutView.h; sourceTree = ""; }; - 2166AB171D82EC56007538D7 /* SMCalloutView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SMCalloutView.m; sourceTree = ""; }; - 2166AB271D82EC56007538D7 /* RCTConvert+MapKit.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "RCTConvert+MapKit.h"; sourceTree = ""; }; - 2166AB281D82EC56007538D7 /* RCTConvert+MapKit.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "RCTConvert+MapKit.m"; sourceTree = ""; }; - 21D346611D933B8C002BAD8A /* AIRMapUrlTile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AIRMapUrlTile.h; sourceTree = ""; }; - 21D346621D933B8C002BAD8A /* AIRMapUrlTile.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AIRMapUrlTile.m; sourceTree = ""; }; - 21D346631D933B8C002BAD8A /* AIRMapUrlTileManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AIRMapUrlTileManager.h; sourceTree = ""; }; - 21D346641D933B8C002BAD8A /* AIRMapUrlTileManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AIRMapUrlTileManager.m; sourceTree = ""; }; 21E657091D77591400B75EE5 /* SystemConfiguration.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SystemConfiguration.framework; path = System/Library/Frameworks/SystemConfiguration.framework; sourceTree = SDKROOT; }; 21E6570B1D77591A00B75EE5 /* MobileCoreServices.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MobileCoreServices.framework; path = System/Library/Frameworks/MobileCoreServices.framework; sourceTree = SDKROOT; }; 21E6570D1D77591F00B75EE5 /* MapKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MapKit.framework; path = System/Library/Frameworks/MapKit.framework; sourceTree = SDKROOT; }; 21E6570F1D77594C00B75EE5 /* AudioToolbox.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AudioToolbox.framework; path = System/Library/Frameworks/AudioToolbox.framework; sourceTree = SDKROOT; }; - 5647FBD61E47A82C0054FF00 /* AIRGMSPolygon.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AIRGMSPolygon.h; sourceTree = ""; }; - 5647FBD71E47A82C0054FF00 /* AIRGMSPolygon.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AIRGMSPolygon.m; sourceTree = ""; }; - 8620CC6D1DBD814A00B79BFE /* AIRGMSMarker.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AIRGMSMarker.h; sourceTree = ""; }; - 8620CC6E1DBD814A00B79BFE /* AIRGMSMarker.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AIRGMSMarker.m; sourceTree = ""; }; - 8620CC6F1DBD814A00B79BFE /* AIRGoogleMap.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AIRGoogleMap.h; sourceTree = ""; }; - 8620CC701DBD814A00B79BFE /* AIRGoogleMap.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AIRGoogleMap.m; sourceTree = ""; }; - 8620CC711DBD814A00B79BFE /* AIRGoogleMapCallout.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AIRGoogleMapCallout.h; sourceTree = ""; }; - 8620CC721DBD814A00B79BFE /* AIRGoogleMapCallout.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AIRGoogleMapCallout.m; sourceTree = ""; }; - 8620CC731DBD814A00B79BFE /* AIRGoogleMapCalloutManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AIRGoogleMapCalloutManager.h; sourceTree = ""; }; - 8620CC741DBD814A00B79BFE /* AIRGoogleMapCalloutManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AIRGoogleMapCalloutManager.m; sourceTree = ""; }; - 8620CC751DBD814A00B79BFE /* AIRGoogleMapManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AIRGoogleMapManager.h; sourceTree = ""; }; - 8620CC761DBD814A00B79BFE /* AIRGoogleMapManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AIRGoogleMapManager.m; sourceTree = ""; }; - 8620CC771DBD814A00B79BFE /* AIRGoogleMapMarker.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AIRGoogleMapMarker.h; sourceTree = ""; }; - 8620CC781DBD814A00B79BFE /* AIRGoogleMapMarker.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AIRGoogleMapMarker.m; sourceTree = ""; }; - 8620CC791DBD814A00B79BFE /* AIRGoogleMapMarkerManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AIRGoogleMapMarkerManager.h; sourceTree = ""; }; - 8620CC7A1DBD814A00B79BFE /* AIRGoogleMapMarkerManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AIRGoogleMapMarkerManager.m; sourceTree = ""; }; - 8620CC7B1DBD814A00B79BFE /* AIRGoogleMapPolygon.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AIRGoogleMapPolygon.h; sourceTree = ""; }; - 8620CC7C1DBD814A00B79BFE /* AIRGoogleMapPolygon.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AIRGoogleMapPolygon.m; sourceTree = ""; }; - 8620CC7D1DBD814A00B79BFE /* AIRGoogleMapPolygonManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AIRGoogleMapPolygonManager.h; sourceTree = ""; }; - 8620CC7E1DBD814A00B79BFE /* AIRGoogleMapPolygonManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AIRGoogleMapPolygonManager.m; sourceTree = ""; }; - 8620CC7F1DBD814A00B79BFE /* AIRGoogleMapPolyline.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AIRGoogleMapPolyline.h; sourceTree = ""; }; - 8620CC801DBD814A00B79BFE /* AIRGoogleMapPolyline.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AIRGoogleMapPolyline.m; sourceTree = ""; }; - 8620CC811DBD814A00B79BFE /* AIRGoogleMapPolylineManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AIRGoogleMapPolylineManager.h; sourceTree = ""; }; - 8620CC821DBD814A00B79BFE /* AIRGoogleMapPolylineManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AIRGoogleMapPolylineManager.m; sourceTree = ""; }; - 8620CC831DBD814A00B79BFE /* DummyView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DummyView.h; sourceTree = ""; }; - 8620CC841DBD814A00B79BFE /* DummyView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DummyView.m; sourceTree = ""; }; - 8620CC851DBD814A00B79BFE /* RCTConvert+GMSMapViewType.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "RCTConvert+GMSMapViewType.h"; sourceTree = ""; }; - 8620CC861DBD814A00B79BFE /* RCTConvert+GMSMapViewType.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "RCTConvert+GMSMapViewType.m"; sourceTree = ""; }; - 8697D6201DBEDE6100DB7D0F /* AIRGoogleMapCircle.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AIRGoogleMapCircle.h; sourceTree = ""; }; - 8697D6211DBEDE6100DB7D0F /* AIRGoogleMapCircle.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AIRGoogleMapCircle.m; sourceTree = ""; }; - 8697D6231DBEE22B00DB7D0F /* AIRGoogleMapCircleManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AIRGoogleMapCircleManager.h; sourceTree = ""; }; - 8697D6241DBEE22B00DB7D0F /* AIRGoogleMapCircleManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AIRGoogleMapCircleManager.m; sourceTree = ""; }; - 86DE6F861DCE7D21002A5053 /* AIRGoogleMapUrlTile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AIRGoogleMapUrlTile.h; sourceTree = ""; }; - 86DE6F871DCE7D21002A5053 /* AIRGoogleMapUrlTile.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AIRGoogleMapUrlTile.m; sourceTree = ""; }; - 86DE6F891DCE8543002A5053 /* AIRGoogleMapUrlTileManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AIRGoogleMapUrlTileManager.h; sourceTree = ""; }; - 86DE6F8A1DCE8543002A5053 /* AIRGoogleMapURLTileManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AIRGoogleMapURLTileManager.m; sourceTree = ""; }; + 8490F2151E8879FB000099F8 /* CoreFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreFoundation.framework; path = System/Library/Frameworks/CoreFoundation.framework; sourceTree = SDKROOT; }; + 8490F2171E887A36000099F8 /* libicucore.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libicucore.tbd; path = usr/lib/libicucore.tbd; sourceTree = SDKROOT; }; + 8490F2191E887A8F000099F8 /* CFNetwork.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CFNetwork.framework; path = System/Library/Frameworks/CFNetwork.framework; sourceTree = SDKROOT; }; + 8490F21B1E887AAC000099F8 /* Security.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Security.framework; path = System/Library/Frameworks/Security.framework; sourceTree = SDKROOT; }; BE5DE1E9AE25978F88CD940A /* Pods-AirMapsExplorer.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-AirMapsExplorer.debug.xcconfig"; path = "Pods/Target Support Files/Pods-AirMapsExplorer/Pods-AirMapsExplorer.debug.xcconfig"; sourceTree = ""; }; E138AD0CDB08FE57B09B18F8 /* Pods-AirMapsExplorer.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-AirMapsExplorer.release.xcconfig"; path = "Pods/Target Support Files/Pods-AirMapsExplorer/Pods-AirMapsExplorer.release.xcconfig"; sourceTree = ""; }; /* End PBXFileReference section */ @@ -169,6 +71,9 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + 8490F21C1E887AAC000099F8 /* Security.framework in Frameworks */, + 8490F21A1E887A8F000099F8 /* CFNetwork.framework in Frameworks */, + 8490F2161E8879FB000099F8 /* CoreFoundation.framework in Frameworks */, 21E657101D77594C00B75EE5 /* AudioToolbox.framework in Frameworks */, 21E6570E1D77591F00B75EE5 /* MapKit.framework in Frameworks */, 21E6570C1D77591A00B75EE5 /* MobileCoreServices.framework in Frameworks */, @@ -183,6 +88,10 @@ 051AB288C799B62BE091B88A /* Frameworks */ = { isa = PBXGroup; children = ( + 8490F21B1E887AAC000099F8 /* Security.framework */, + 8490F2191E887A8F000099F8 /* CFNetwork.framework */, + 8490F2171E887A36000099F8 /* libicucore.tbd */, + 8490F2151E8879FB000099F8 /* CoreFoundation.framework */, 2166AAF81D82E9D0007538D7 /* React.framework */, 2166AAF61D823407007538D7 /* CoreGraphics.framework */, 2166AAF41D823402007538D7 /* CoreText.framework */, @@ -211,56 +120,6 @@ name = AirMapsExplorer; sourceTree = ""; }; - 2166AAFA1D82EC56007538D7 /* AirMaps */ = { - isa = PBXGroup; - children = ( - 2166AAFB1D82EC56007538D7 /* AIRMap.h */, - 2166AAFC1D82EC56007538D7 /* AIRMap.m */, - 2166AAFD1D82EC56007538D7 /* AIRMapCallout.h */, - 2166AAFE1D82EC56007538D7 /* AIRMapCallout.m */, - 2166AAFF1D82EC56007538D7 /* AIRMapCalloutManager.h */, - 2166AB001D82EC56007538D7 /* AIRMapCalloutManager.m */, - 2166AB011D82EC56007538D7 /* AIRMapCircle.h */, - 2166AB021D82EC56007538D7 /* AIRMapCircle.m */, - 2166AB031D82EC56007538D7 /* AIRMapCircleManager.h */, - 2166AB041D82EC56007538D7 /* AIRMapCircleManager.m */, - 2166AB051D82EC56007538D7 /* AIRMapCoordinate.h */, - 2166AB061D82EC56007538D7 /* AIRMapCoordinate.m */, - 2166AB071D82EC56007538D7 /* AIRMapManager.h */, - 2166AB081D82EC56007538D7 /* AIRMapManager.m */, - 2166AB091D82EC56007538D7 /* AIRMapMarker.h */, - 2166AB0A1D82EC56007538D7 /* AIRMapMarker.m */, - 2166AB0B1D82EC56007538D7 /* AIRMapMarkerManager.h */, - 2166AB0C1D82EC56007538D7 /* AIRMapMarkerManager.m */, - 2166AB0D1D82EC56007538D7 /* AIRMapPolygon.h */, - 2166AB0E1D82EC56007538D7 /* AIRMapPolygon.m */, - 2166AB0F1D82EC56007538D7 /* AIRMapPolygonManager.h */, - 2166AB101D82EC56007538D7 /* AIRMapPolygonManager.m */, - 2166AB111D82EC56007538D7 /* AIRMapPolyline.h */, - 2166AB121D82EC56007538D7 /* AIRMapPolyline.m */, - 2166AB131D82EC56007538D7 /* AIRMapPolylineManager.h */, - 2166AB141D82EC56007538D7 /* AIRMapPolylineManager.m */, - 21D346611D933B8C002BAD8A /* AIRMapUrlTile.h */, - 21D346621D933B8C002BAD8A /* AIRMapUrlTile.m */, - 21D346631D933B8C002BAD8A /* AIRMapUrlTileManager.h */, - 21D346641D933B8C002BAD8A /* AIRMapUrlTileManager.m */, - 2166AB151D82EC56007538D7 /* Callout */, - 2166AB271D82EC56007538D7 /* RCTConvert+MapKit.h */, - 2166AB281D82EC56007538D7 /* RCTConvert+MapKit.m */, - ); - name = AirMaps; - path = ../../ios/AirMaps; - sourceTree = ""; - }; - 2166AB151D82EC56007538D7 /* Callout */ = { - isa = PBXGroup; - children = ( - 2166AB161D82EC56007538D7 /* SMCalloutView.h */, - 2166AB171D82EC56007538D7 /* SMCalloutView.m */, - ); - path = Callout; - sourceTree = ""; - }; 2BAA8C4A80B44CFBB3F83458 /* Libraries */ = { isa = PBXGroup; children = ( @@ -271,8 +130,6 @@ 83CBB9F61A601CBA00E9B192 = { isa = PBXGroup; children = ( - 8620CC6C1DBD814A00B79BFE /* AirGoogleMaps */, - 2166AAFA1D82EC56007538D7 /* AirMaps */, 13B07FAE1A68108700A75B9A /* AirMapsExplorer */, 83CBBA001A601CBA00E9B192 /* Products */, 051AB288C799B62BE091B88A /* Frameworks */, @@ -292,50 +149,6 @@ name = Products; sourceTree = ""; }; - 8620CC6C1DBD814A00B79BFE /* AirGoogleMaps */ = { - isa = PBXGroup; - children = ( - 8620CC6D1DBD814A00B79BFE /* AIRGMSMarker.h */, - 5647FBD61E47A82C0054FF00 /* AIRGMSPolygon.h */, - 5647FBD71E47A82C0054FF00 /* AIRGMSPolygon.m */, - 8620CC6E1DBD814A00B79BFE /* AIRGMSMarker.m */, - 8620CC6F1DBD814A00B79BFE /* AIRGoogleMap.h */, - 8620CC701DBD814A00B79BFE /* AIRGoogleMap.m */, - 8620CC711DBD814A00B79BFE /* AIRGoogleMapCallout.h */, - 8620CC721DBD814A00B79BFE /* AIRGoogleMapCallout.m */, - 8620CC731DBD814A00B79BFE /* AIRGoogleMapCalloutManager.h */, - 8620CC741DBD814A00B79BFE /* AIRGoogleMapCalloutManager.m */, - 8620CC751DBD814A00B79BFE /* AIRGoogleMapManager.h */, - 8620CC761DBD814A00B79BFE /* AIRGoogleMapManager.m */, - 8620CC771DBD814A00B79BFE /* AIRGoogleMapMarker.h */, - 8620CC781DBD814A00B79BFE /* AIRGoogleMapMarker.m */, - 8620CC791DBD814A00B79BFE /* AIRGoogleMapMarkerManager.h */, - 8620CC7A1DBD814A00B79BFE /* AIRGoogleMapMarkerManager.m */, - 8620CC7B1DBD814A00B79BFE /* AIRGoogleMapPolygon.h */, - 8620CC7C1DBD814A00B79BFE /* AIRGoogleMapPolygon.m */, - 8620CC7D1DBD814A00B79BFE /* AIRGoogleMapPolygonManager.h */, - 8620CC7E1DBD814A00B79BFE /* AIRGoogleMapPolygonManager.m */, - 8620CC7F1DBD814A00B79BFE /* AIRGoogleMapPolyline.h */, - 8620CC801DBD814A00B79BFE /* AIRGoogleMapPolyline.m */, - 8620CC811DBD814A00B79BFE /* AIRGoogleMapPolylineManager.h */, - 8620CC821DBD814A00B79BFE /* AIRGoogleMapPolylineManager.m */, - 8620CC831DBD814A00B79BFE /* DummyView.h */, - 8620CC841DBD814A00B79BFE /* DummyView.m */, - 8620CC851DBD814A00B79BFE /* RCTConvert+GMSMapViewType.h */, - 8620CC861DBD814A00B79BFE /* RCTConvert+GMSMapViewType.m */, - 8697D6201DBEDE6100DB7D0F /* AIRGoogleMapCircle.h */, - 8697D6211DBEDE6100DB7D0F /* AIRGoogleMapCircle.m */, - 8697D6231DBEE22B00DB7D0F /* AIRGoogleMapCircleManager.h */, - 8697D6241DBEE22B00DB7D0F /* AIRGoogleMapCircleManager.m */, - 86DE6F861DCE7D21002A5053 /* AIRGoogleMapUrlTile.h */, - 86DE6F871DCE7D21002A5053 /* AIRGoogleMapUrlTile.m */, - 86DE6F891DCE8543002A5053 /* AIRGoogleMapUrlTileManager.h */, - 86DE6F8A1DCE8543002A5053 /* AIRGoogleMapURLTileManager.m */, - ); - name = AirGoogleMaps; - path = ../../ios/AirGoogleMaps; - sourceTree = ""; - }; C2ED0F349F22CC794F9BC33F /* Pods */ = { isa = PBXGroup; children = ( @@ -453,7 +266,7 @@ ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "../node_modules/react-native/packager/react-native-xcode.sh"; + shellScript = "../../node_modules/react-native/packager/react-native-xcode.sh"; }; 17E7BB4CEC38ABB7449E144E /* [CP] Embed Pods Frameworks */ = { isa = PBXShellScriptBuildPhase; @@ -514,43 +327,8 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 8620CC891DBD814A00B79BFE /* AIRGoogleMapCallout.m in Sources */, - 5647FBD81E47A82C0054FF00 /* AIRGMSPolygon.m in Sources */, - 8620CC8D1DBD814A00B79BFE /* AIRGoogleMapMarkerManager.m in Sources */, - 8620CC881DBD814A00B79BFE /* AIRGoogleMap.m in Sources */, - 2166AB2D1D82EC56007538D7 /* AIRMapCircleManager.m in Sources */, - 21D346651D933B8C002BAD8A /* AIRMapUrlTile.m in Sources */, - 2166AB2A1D82EC56007538D7 /* AIRMapCallout.m in Sources */, - 8620CC8E1DBD814A00B79BFE /* AIRGoogleMapPolygon.m in Sources */, - 8620CC8C1DBD814A00B79BFE /* AIRGoogleMapMarker.m in Sources */, - 8620CC8F1DBD814A00B79BFE /* AIRGoogleMapPolygonManager.m in Sources */, - 8620CC8A1DBD814A00B79BFE /* AIRGoogleMapCalloutManager.m in Sources */, - 8620CC8B1DBD814A00B79BFE /* AIRGoogleMapManager.m in Sources */, - 2166AB2C1D82EC56007538D7 /* AIRMapCircle.m in Sources */, - 8620CC871DBD814A00B79BFE /* AIRGMSMarker.m in Sources */, - 21D346661D933B8C002BAD8A /* AIRMapUrlTileManager.m in Sources */, - 8620CC931DBD814A00B79BFE /* RCTConvert+GMSMapViewType.m in Sources */, - 2166AB301D82EC56007538D7 /* AIRMapMarker.m in Sources */, - 8697D6221DBEDE6100DB7D0F /* AIRGoogleMapCircle.m in Sources */, - 2166AB321D82EC56007538D7 /* AIRMapPolygon.m in Sources */, 13B07FBC1A68108700A75B9A /* AppDelegate.m in Sources */, - 2166AB3E1D82EC56007538D7 /* RCTConvert+MapKit.m in Sources */, - 8697D6251DBEE22B00DB7D0F /* AIRGoogleMapCircleManager.m in Sources */, 13B07FC11A68108700A75B9A /* main.m in Sources */, - 86DE6F8B1DCE8543002A5053 /* AIRGoogleMapURLTileManager.m in Sources */, - 86DE6F881DCE7D21002A5053 /* AIRGoogleMapUrlTile.m in Sources */, - 2166AB331D82EC56007538D7 /* AIRMapPolygonManager.m in Sources */, - 8620CC901DBD814A00B79BFE /* AIRGoogleMapPolyline.m in Sources */, - 2166AB2B1D82EC56007538D7 /* AIRMapCalloutManager.m in Sources */, - 8620CC921DBD814A00B79BFE /* DummyView.m in Sources */, - 2166AB361D82EC56007538D7 /* SMCalloutView.m in Sources */, - 2166AB351D82EC56007538D7 /* AIRMapPolylineManager.m in Sources */, - 8620CC911DBD814A00B79BFE /* AIRGoogleMapPolylineManager.m in Sources */, - 2166AB291D82EC56007538D7 /* AIRMap.m in Sources */, - 2166AB2E1D82EC56007538D7 /* AIRMapCoordinate.m in Sources */, - 2166AB341D82EC56007538D7 /* AIRMapPolyline.m in Sources */, - 2166AB2F1D82EC56007538D7 /* AIRMapManager.m in Sources */, - 2166AB311D82EC56007538D7 /* AIRMapMarkerManager.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -623,6 +401,7 @@ baseConfigurationReference = BE5DE1E9AE25978F88CD940A /* Pods-AirMapsExplorer.debug.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ENABLE_MODULES = NO; DEAD_CODE_STRIPPING = NO; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", @@ -632,7 +411,6 @@ HEADER_SEARCH_PATHS = ( "$(inherited)", /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include, - "$(SRCROOT)/../node_modules/react-native/React/**", ); INFOPLIST_FILE = AirMapsExplorer/Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; @@ -646,6 +424,7 @@ baseConfigurationReference = E138AD0CDB08FE57B09B18F8 /* Pods-AirMapsExplorer.release.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ENABLE_MODULES = NO; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", "$(PROJECT_DIR)/build/Debug-iphoneos", @@ -654,7 +433,6 @@ HEADER_SEARCH_PATHS = ( "$(inherited)", /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include, - "$(SRCROOT)/../node_modules/react-native/React/**", ); INFOPLIST_FILE = AirMapsExplorer/Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; @@ -701,7 +479,6 @@ HEADER_SEARCH_PATHS = ( "$(inherited)", /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include, - "$(SRCROOT)/../node_modules/react-native/React/**", ); IPHONEOS_DEPLOYMENT_TARGET = 8.0; MTL_ENABLE_DEBUG_INFO = YES; @@ -741,7 +518,6 @@ HEADER_SEARCH_PATHS = ( "$(inherited)", /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include, - "$(SRCROOT)/../node_modules/react-native/React/**", ); IPHONEOS_DEPLOYMENT_TARGET = 8.0; MTL_ENABLE_DEBUG_INFO = NO; diff --git a/example/ios/AirMapsExplorer/AppDelegate.m b/example/ios/AirMapsExplorer/AppDelegate.m index 6f006087f..a3b8f5bb9 100644 --- a/example/ios/AirMapsExplorer/AppDelegate.m +++ b/example/ios/AirMapsExplorer/AppDelegate.m @@ -35,7 +35,7 @@ - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:( * on the same Wi-Fi network. */ - jsCodeLocation = [NSURL URLWithString:@"http://localhost:8081/index.ios.bundle?platform=ios&dev=true"]; + jsCodeLocation = [NSURL URLWithString:@"http://localhost:8081/example/index.bundle?platform=ios&dev=true"]; /** * OPTION 2 diff --git a/example/ios/AirMapsExplorer/Images.xcassets/AppIcon.appiconset/Contents.json b/example/ios/AirMapsExplorer/Images.xcassets/AppIcon.appiconset/Contents.json index 118c98f74..b8236c653 100644 --- a/example/ios/AirMapsExplorer/Images.xcassets/AppIcon.appiconset/Contents.json +++ b/example/ios/AirMapsExplorer/Images.xcassets/AppIcon.appiconset/Contents.json @@ -1,5 +1,15 @@ { "images" : [ + { + "idiom" : "iphone", + "size" : "20x20", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "20x20", + "scale" : "3x" + }, { "idiom" : "iphone", "size" : "29x29", diff --git a/example/ios/Gemfile b/example/ios/Gemfile deleted file mode 100644 index b9ec3be2d..000000000 --- a/example/ios/Gemfile +++ /dev/null @@ -1,2 +0,0 @@ -source 'https://rubygems.org' -gem 'cocoapods', '~>1.1.1' diff --git a/example/ios/Podfile b/example/ios/Podfile index 80b14bdc1..ec73199a4 100644 --- a/example/ios/Podfile +++ b/example/ios/Podfile @@ -5,7 +5,9 @@ platform :ios, '8.0' # Change 'AirMapsExplorer' to match the target in your Xcode project. target 'AirMapsExplorer' do - pod 'React', path: '../node_modules/react-native', :subspecs => [ + + pod 'Yoga', :path => '../../node_modules/react-native/ReactCommon/yoga/Yoga.podspec' + pod 'React', path: '../../node_modules/react-native', :subspecs => [ 'Core', 'RCTActionSheet', 'RCTAnimation', @@ -20,8 +22,7 @@ target 'AirMapsExplorer' do ] pod 'GoogleMaps' # <~~ remove this line if you do not want to support GoogleMaps on iOS + pod 'react-native-maps', path: '../../' + pod 'react-native-google-maps', path: '../../' # <~~ if you need GoogleMaps support on iOS -# when not using frameworks we can do this instead of including the source files in our project (1/4): -# pod 'react-native-maps', path: '../../' -# pod 'react-native-google-maps', path: '../../' # <~~ if you need GoogleMaps support on iOS end diff --git a/example/ios/Podfile.lock b/example/ios/Podfile.lock index 5e689bb4a..60339f2b0 100644 --- a/example/ios/Podfile.lock +++ b/example/ios/Podfile.lock @@ -4,57 +4,76 @@ PODS: - GoogleMaps/Base (2.1.1) - GoogleMaps/Maps (2.1.1): - GoogleMaps/Base - - React/Core (0.40.0): + - React (0.42.3): + - React/Core (= 0.42.3) + - react-native-google-maps (0.13.1): + - GoogleMaps (= 2.1.1) + - React + - react-native-maps (0.13.1): + - React + - React/Core (0.42.3): - React/cxxreact - - React/yoga - - React/cxxreact (0.40.0): + - Yoga (= 0.42.3.React) + - React/cxxreact (0.42.3): - React/jschelpers - - React/jschelpers (0.40.0) - - React/RCTActionSheet (0.40.0): + - React/jschelpers (0.42.3) + - React/RCTActionSheet (0.42.3): - React/Core - - React/RCTAnimation (0.40.0): + - React/RCTAnimation (0.42.3): - React/Core - - React/RCTGeolocation (0.40.0): + - React/RCTGeolocation (0.42.3): - React/Core - - React/RCTImage (0.40.0): + - React/RCTImage (0.42.3): - React/Core - React/RCTNetwork - - React/RCTLinkingIOS (0.40.0): + - React/RCTLinkingIOS (0.42.3): - React/Core - - React/RCTNetwork (0.40.0): + - React/RCTNetwork (0.42.3): - React/Core - - React/RCTSettings (0.40.0): + - React/RCTSettings (0.42.3): - React/Core - - React/RCTText (0.40.0): + - React/RCTText (0.42.3): - React/Core - - React/RCTVibration (0.40.0): + - React/RCTVibration (0.42.3): - React/Core - - React/RCTWebSocket (0.40.0): + - React/RCTWebSocket (0.42.3): - React/Core - - React/yoga (0.40.0) + - Yoga (0.42.3.React) DEPENDENCIES: - GoogleMaps - - React/Core (from `../node_modules/react-native`) - - React/RCTActionSheet (from `../node_modules/react-native`) - - React/RCTAnimation (from `../node_modules/react-native`) - - React/RCTGeolocation (from `../node_modules/react-native`) - - React/RCTImage (from `../node_modules/react-native`) - - React/RCTLinkingIOS (from `../node_modules/react-native`) - - React/RCTNetwork (from `../node_modules/react-native`) - - React/RCTSettings (from `../node_modules/react-native`) - - React/RCTText (from `../node_modules/react-native`) - - React/RCTVibration (from `../node_modules/react-native`) - - React/RCTWebSocket (from `../node_modules/react-native`) + - react-native-google-maps (from `../../`) + - react-native-maps (from `../../`) + - React/Core (from `../../node_modules/react-native`) + - React/RCTActionSheet (from `../../node_modules/react-native`) + - React/RCTAnimation (from `../../node_modules/react-native`) + - React/RCTGeolocation (from `../../node_modules/react-native`) + - React/RCTImage (from `../../node_modules/react-native`) + - React/RCTLinkingIOS (from `../../node_modules/react-native`) + - React/RCTNetwork (from `../../node_modules/react-native`) + - React/RCTSettings (from `../../node_modules/react-native`) + - React/RCTText (from `../../node_modules/react-native`) + - React/RCTVibration (from `../../node_modules/react-native`) + - React/RCTWebSocket (from `../../node_modules/react-native`) + - Yoga (from `../../node_modules/react-native/ReactCommon/yoga/Yoga.podspec`) EXTERNAL SOURCES: React: - :path: "../node_modules/react-native" + :path: "../../node_modules/react-native" + react-native-google-maps: + :path: "../../" + react-native-maps: + :path: "../../" + Yoga: + :path: "../../node_modules/react-native/ReactCommon/yoga/Yoga.podspec" SPEC CHECKSUMS: GoogleMaps: a5b5bbe47734e2443bde781a6aa64e69fdb6d785 - React: 6dfb2f72edb1d74a800127ae157af038646673ce + React: 35e039680feacd0563677d49ba410112d2748559 + react-native-google-maps: b2668747ec289759993dc2411a7078afafa8adea + react-native-maps: 326ddbaaea8f6044b1817fb028c40950c71cc38a + Yoga: 86ce777665c8259b94ef8dbea76b84634237f4ea -PODFILE CHECKSUM: ffbc20bd08f662256d501d07a70e77862684f702 +PODFILE CHECKSUM: 206f5482deac191368c01dd654d14fbd3e5d6b8f -COCOAPODS: 1.1.1 +COCOAPODS: 1.2.0 diff --git a/example/ios/bundler b/example/ios/bundler new file mode 100755 index 000000000..905387619 --- /dev/null +++ b/example/ios/bundler @@ -0,0 +1,17 @@ +#!/usr/bin/env ruby +# frozen_string_literal: true +# +# This file was generated by Bundler. +# +# The application 'bundler' is installed as part of a gem, and +# this file is here to facilitate running it. +# + +require "pathname" +ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../../Gemfile", + Pathname.new(__FILE__).realpath) + +require "rubygems" +require "bundler/setup" + +load Gem.bin_path("bundler", "bundler") diff --git a/example/ios/fuzzy_match b/example/ios/fuzzy_match new file mode 100755 index 000000000..f71547393 --- /dev/null +++ b/example/ios/fuzzy_match @@ -0,0 +1,17 @@ +#!/usr/bin/env ruby +# frozen_string_literal: true +# +# This file was generated by Bundler. +# +# The application 'fuzzy_match' is installed as part of a gem, and +# this file is here to facilitate running it. +# + +require "pathname" +ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../../Gemfile", + Pathname.new(__FILE__).realpath) + +require "rubygems" +require "bundler/setup" + +load Gem.bin_path("fuzzy_match", "fuzzy_match") diff --git a/example/ios/pod b/example/ios/pod new file mode 100755 index 000000000..3c4a4d04c --- /dev/null +++ b/example/ios/pod @@ -0,0 +1,17 @@ +#!/usr/bin/env ruby +# frozen_string_literal: true +# +# This file was generated by Bundler. +# +# The application 'pod' is installed as part of a gem, and +# this file is here to facilitate running it. +# + +require "pathname" +ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../../Gemfile", + Pathname.new(__FILE__).realpath) + +require "rubygems" +require "bundler/setup" + +load Gem.bin_path("cocoapods", "pod") diff --git a/example/package.json b/example/package.json deleted file mode 100644 index 378bd5578..000000000 --- a/example/package.json +++ /dev/null @@ -1,24 +0,0 @@ -{ - "name": "AirMapsExplorer", - "version": "0.0.1", - "private": true, - "scripts": { - "start": "react-native start", - "watch": "node ./scripts/watch-and-copy-src.js", - "packager": "sh ./node_modules/react-native/packager/packager.sh --root ./node_modules/react-native-maps", - "dev": "concurrently 'npm run watch' 'npm run packager'" - }, - "dependencies": { - "lodash": "^4.17.2", - "react": "~15.4.1", - "react-native": "^0.40.0", - "react-native-maps": "file:../" - }, - "devDependencies": { - "concurrently": "^2.2.0", - "fs-extra": "^0.30.0", - "minimatch": "^3.0.2", - "node-watch": "^0.4.0", - "rimraf": "^2.5.4" - } -} diff --git a/example/scripts/.eslintrc b/example/scripts/.eslintrc deleted file mode 100644 index 3c1eaf35a..000000000 --- a/example/scripts/.eslintrc +++ /dev/null @@ -1,6 +0,0 @@ -{ - "rules": { - // Scripts can import things in devDependencies - "import/no-extraneous-dependencies": [2, {"devDependencies": true}] - } -} diff --git a/example/scripts/watch-and-copy-src.js b/example/scripts/watch-and-copy-src.js deleted file mode 100644 index ed8684894..000000000 --- a/example/scripts/watch-and-copy-src.js +++ /dev/null @@ -1,51 +0,0 @@ -const path = require('path'); -const fs = require('fs-extra'); -const watch = require('node-watch'); -const rimraf = require('rimraf'); -const minimatch = require('minimatch'); - -function copyAndWatch(source, destination, fileGlob) { - console.log(`Cleaning "${destination}"`); - rimraf(destination, () => { - console.log(`Copying "${source}" to "${destination}"`); - fs.copy(source, destination, (err) => { - if (err) console.error(err); - }); - - console.log(`Watching "${source}"`); - watch(source, (filename) => { - const localPath = filename.split(source).pop(); - if (matchesFile(localPath, fileGlob)) { - const destinationPath = `${destination}${localPath}`; - console.log(`Copying "${filename}" to "${destinationPath}"`); - fs.copy(filename, destinationPath, (err) => { - if (err) console.error(err); - }); - } - }); - }); -} - -function matchesFile(filename, fileGlob) { - if (fileGlob == null) return true; - return minimatch(path.basename(filename), fileGlob); -} - -// JavaScript -copyAndWatch( - '../components', - 'node_modules/react-native-maps/components' -); - -// Android -copyAndWatch( - '../android', - 'node_modules/react-native-maps/android' -); - -// iOS -copyAndWatch( - '../ios', - 'node_modules/react-native-maps/ios', - '{*.m,*.h,*.swift}' -); diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000000000000000000000000000000000000..4f308ee0403a6fade6ba2b25249725652ed80a33 GIT binary patch literal 54208 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 literal 0 HcmV?d00001 diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 000000000..3b6c26cf7 --- /dev/null +++ b/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,6 @@ +#Thu Mar 02 17:03:11 PST 2017 +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-3.3-bin.zip diff --git a/example/android/gradlew b/gradlew similarity index 83% rename from example/android/gradlew rename to gradlew index 91a7e269e..4453ccea3 100755 --- a/example/android/gradlew +++ b/gradlew @@ -1,4 +1,4 @@ -#!/usr/bin/env bash +#!/usr/bin/env sh ############################################################################## ## @@ -6,12 +6,30 @@ ## ############################################################################## -# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -DEFAULT_JVM_OPTS="" +# 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 APP_NAME="Gradle" APP_BASE_NAME=`basename "$0"` +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS="" + # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD="maximum" @@ -30,6 +48,7 @@ die ( ) { cygwin=false msys=false darwin=false +nonstop=false case "`uname`" in CYGWIN* ) cygwin=true @@ -40,31 +59,11 @@ case "`uname`" in MINGW* ) msys=true ;; + NONSTOP* ) + nonstop=true + ;; esac -# For Cygwin, ensure paths are in UNIX format before anything is touched. -if $cygwin ; then - [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"` -fi - -# 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\"`/" >&- -APP_HOME="`pwd -P`" -cd "$SAVED" >&- - CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar # Determine the Java command to use to start the JVM. @@ -90,7 +89,7 @@ location of your Java installation." fi # Increase the maximum file descriptors if we can. -if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then +if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then MAX_FD_LIMIT=`ulimit -H -n` if [ $? -eq 0 ] ; then if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then @@ -114,6 +113,7 @@ fi 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` @@ -154,11 +154,19 @@ if $cygwin ; then 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=("$@") +# Escape application args +save ( ) { + for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done + echo " " } -eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS -JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME" +APP_ARGS=$(save "$@") + +# Collect all arguments for the java command, following the shell quoting and substitution rules +eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" + +# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong +if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then + cd "$(dirname "$0")" +fi -exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" +exec "$JAVACMD" "$@" diff --git a/example/android/gradlew.bat b/gradlew.bat similarity index 88% rename from example/android/gradlew.bat rename to gradlew.bat index aec99730b..e95643d6a 100644 --- a/example/android/gradlew.bat +++ b/gradlew.bat @@ -8,14 +8,14 @@ @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 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= + @rem Find java.exe if defined JAVA_HOME goto findJavaFromJavaHome @@ -46,10 +46,9 @@ echo location of your Java installation. goto fail :init -@rem Get command-line arguments, handling Windowz variants +@rem Get command-line arguments, handling Windows 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. @@ -60,11 +59,6 @@ set _SKIP=2 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 diff --git a/index.js b/index.js index b2d7d79e1..207d0119d 100644 --- a/index.js +++ b/index.js @@ -1,3 +1,3 @@ -import MapView from './components/MapView'; +import MapView from './lib/components/MapView'; module.exports = MapView; diff --git a/lib/android/build.gradle b/lib/android/build.gradle new file mode 100644 index 000000000..062f040ca --- /dev/null +++ b/lib/android/build.gradle @@ -0,0 +1,40 @@ +apply plugin: 'com.android.library' +apply from: 'gradle-maven-push.gradle' + +android { + compileSdkVersion 25 + buildToolsVersion "25.0.2" + + defaultConfig { + minSdkVersion 16 + targetSdkVersion 25 + } + + packagingOptions { + exclude 'META-INF/LICENSE' + exclude 'META-INF/DEPENDENCIES.txt' + exclude 'META-INF/LICENSE.txt' + exclude 'META-INF/NOTICE.txt' + exclude 'META-INF/NOTICE' + exclude 'META-INF/DEPENDENCIES' + exclude 'META-INF/notice.txt' + exclude 'META-INF/license.txt' + exclude 'META-INF/dependencies.txt' + exclude 'META-INF/LGPL2.1' + } + + lintOptions { + disable 'InvalidPackage' + } + + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_7 + targetCompatibility JavaVersion.VERSION_1_7 + } +} + +dependencies { + provided "com.facebook.react:react-native:+" + compile "com.google.android.gms:play-services-base:10.0.1" + compile "com.google.android.gms:play-services-maps:10.0.1" +} diff --git a/android/gradle-maven-push.gradle b/lib/android/gradle-maven-push.gradle similarity index 100% rename from android/gradle-maven-push.gradle rename to lib/android/gradle-maven-push.gradle diff --git a/android/gradle.properties b/lib/android/gradle.properties similarity index 100% rename from android/gradle.properties rename to lib/android/gradle.properties diff --git a/android/gradle/wrapper/gradle-wrapper.jar b/lib/android/gradle/wrapper/gradle-wrapper.jar similarity index 100% rename from android/gradle/wrapper/gradle-wrapper.jar rename to lib/android/gradle/wrapper/gradle-wrapper.jar diff --git a/android/gradle/wrapper/gradle-wrapper.properties b/lib/android/gradle/wrapper/gradle-wrapper.properties similarity index 100% rename from android/gradle/wrapper/gradle-wrapper.properties rename to lib/android/gradle/wrapper/gradle-wrapper.properties diff --git a/android/gradlew b/lib/android/gradlew similarity index 100% rename from android/gradlew rename to lib/android/gradlew diff --git a/android/gradlew.bat b/lib/android/gradlew.bat similarity index 100% rename from android/gradlew.bat rename to lib/android/gradlew.bat diff --git a/android/src/main/AndroidManifest.xml b/lib/android/src/main/AndroidManifest.xml similarity index 100% rename from android/src/main/AndroidManifest.xml rename to lib/android/src/main/AndroidManifest.xml diff --git a/android/src/main/java/com/airbnb/android/react/maps/AirMapCallout.java b/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapCallout.java similarity index 100% rename from android/src/main/java/com/airbnb/android/react/maps/AirMapCallout.java rename to lib/android/src/main/java/com/airbnb/android/react/maps/AirMapCallout.java diff --git a/android/src/main/java/com/airbnb/android/react/maps/AirMapCalloutManager.java b/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapCalloutManager.java similarity index 100% rename from android/src/main/java/com/airbnb/android/react/maps/AirMapCalloutManager.java rename to lib/android/src/main/java/com/airbnb/android/react/maps/AirMapCalloutManager.java diff --git a/android/src/main/java/com/airbnb/android/react/maps/AirMapCircle.java b/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapCircle.java similarity index 100% rename from android/src/main/java/com/airbnb/android/react/maps/AirMapCircle.java rename to lib/android/src/main/java/com/airbnb/android/react/maps/AirMapCircle.java diff --git a/android/src/main/java/com/airbnb/android/react/maps/AirMapCircleManager.java b/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapCircleManager.java similarity index 100% rename from android/src/main/java/com/airbnb/android/react/maps/AirMapCircleManager.java rename to lib/android/src/main/java/com/airbnb/android/react/maps/AirMapCircleManager.java diff --git a/android/src/main/java/com/airbnb/android/react/maps/AirMapFeature.java b/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapFeature.java similarity index 100% rename from android/src/main/java/com/airbnb/android/react/maps/AirMapFeature.java rename to lib/android/src/main/java/com/airbnb/android/react/maps/AirMapFeature.java diff --git a/android/src/main/java/com/airbnb/android/react/maps/AirMapLiteManager.java b/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapLiteManager.java similarity index 100% rename from android/src/main/java/com/airbnb/android/react/maps/AirMapLiteManager.java rename to lib/android/src/main/java/com/airbnb/android/react/maps/AirMapLiteManager.java diff --git a/android/src/main/java/com/airbnb/android/react/maps/AirMapManager.java b/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapManager.java similarity index 100% rename from android/src/main/java/com/airbnb/android/react/maps/AirMapManager.java rename to lib/android/src/main/java/com/airbnb/android/react/maps/AirMapManager.java diff --git a/android/src/main/java/com/airbnb/android/react/maps/AirMapMarker.java b/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapMarker.java similarity index 100% rename from android/src/main/java/com/airbnb/android/react/maps/AirMapMarker.java rename to lib/android/src/main/java/com/airbnb/android/react/maps/AirMapMarker.java diff --git a/android/src/main/java/com/airbnb/android/react/maps/AirMapMarkerManager.java b/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapMarkerManager.java similarity index 100% rename from android/src/main/java/com/airbnb/android/react/maps/AirMapMarkerManager.java rename to lib/android/src/main/java/com/airbnb/android/react/maps/AirMapMarkerManager.java diff --git a/android/src/main/java/com/airbnb/android/react/maps/AirMapModule.java b/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapModule.java similarity index 100% rename from android/src/main/java/com/airbnb/android/react/maps/AirMapModule.java rename to lib/android/src/main/java/com/airbnb/android/react/maps/AirMapModule.java diff --git a/android/src/main/java/com/airbnb/android/react/maps/AirMapPolygon.java b/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapPolygon.java similarity index 100% rename from android/src/main/java/com/airbnb/android/react/maps/AirMapPolygon.java rename to lib/android/src/main/java/com/airbnb/android/react/maps/AirMapPolygon.java diff --git a/android/src/main/java/com/airbnb/android/react/maps/AirMapPolygonManager.java b/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapPolygonManager.java similarity index 100% rename from android/src/main/java/com/airbnb/android/react/maps/AirMapPolygonManager.java rename to lib/android/src/main/java/com/airbnb/android/react/maps/AirMapPolygonManager.java diff --git a/android/src/main/java/com/airbnb/android/react/maps/AirMapPolyline.java b/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapPolyline.java similarity index 100% rename from android/src/main/java/com/airbnb/android/react/maps/AirMapPolyline.java rename to lib/android/src/main/java/com/airbnb/android/react/maps/AirMapPolyline.java diff --git a/android/src/main/java/com/airbnb/android/react/maps/AirMapPolylineManager.java b/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapPolylineManager.java similarity index 100% rename from android/src/main/java/com/airbnb/android/react/maps/AirMapPolylineManager.java rename to lib/android/src/main/java/com/airbnb/android/react/maps/AirMapPolylineManager.java diff --git a/android/src/main/java/com/airbnb/android/react/maps/AirMapUrlTile.java b/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapUrlTile.java similarity index 100% rename from android/src/main/java/com/airbnb/android/react/maps/AirMapUrlTile.java rename to lib/android/src/main/java/com/airbnb/android/react/maps/AirMapUrlTile.java diff --git a/android/src/main/java/com/airbnb/android/react/maps/AirMapUrlTileManager.java b/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapUrlTileManager.java similarity index 100% rename from android/src/main/java/com/airbnb/android/react/maps/AirMapUrlTileManager.java rename to lib/android/src/main/java/com/airbnb/android/react/maps/AirMapUrlTileManager.java diff --git a/android/src/main/java/com/airbnb/android/react/maps/AirMapView.java b/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapView.java similarity index 100% rename from android/src/main/java/com/airbnb/android/react/maps/AirMapView.java rename to lib/android/src/main/java/com/airbnb/android/react/maps/AirMapView.java diff --git a/android/src/main/java/com/airbnb/android/react/maps/LatLngBoundsUtils.java b/lib/android/src/main/java/com/airbnb/android/react/maps/LatLngBoundsUtils.java similarity index 100% rename from android/src/main/java/com/airbnb/android/react/maps/LatLngBoundsUtils.java rename to lib/android/src/main/java/com/airbnb/android/react/maps/LatLngBoundsUtils.java diff --git a/android/src/main/java/com/airbnb/android/react/maps/MapsPackage.java b/lib/android/src/main/java/com/airbnb/android/react/maps/MapsPackage.java similarity index 100% rename from android/src/main/java/com/airbnb/android/react/maps/MapsPackage.java rename to lib/android/src/main/java/com/airbnb/android/react/maps/MapsPackage.java diff --git a/android/src/main/java/com/airbnb/android/react/maps/RegionChangeEvent.java b/lib/android/src/main/java/com/airbnb/android/react/maps/RegionChangeEvent.java similarity index 100% rename from android/src/main/java/com/airbnb/android/react/maps/RegionChangeEvent.java rename to lib/android/src/main/java/com/airbnb/android/react/maps/RegionChangeEvent.java diff --git a/android/src/main/java/com/airbnb/android/react/maps/SizeReportingShadowNode.java b/lib/android/src/main/java/com/airbnb/android/react/maps/SizeReportingShadowNode.java similarity index 100% rename from android/src/main/java/com/airbnb/android/react/maps/SizeReportingShadowNode.java rename to lib/android/src/main/java/com/airbnb/android/react/maps/SizeReportingShadowNode.java diff --git a/components/AnimatedRegion.js b/lib/components/AnimatedRegion.js similarity index 100% rename from components/AnimatedRegion.js rename to lib/components/AnimatedRegion.js diff --git a/components/MapCallout.js b/lib/components/MapCallout.js similarity index 100% rename from components/MapCallout.js rename to lib/components/MapCallout.js diff --git a/components/MapCircle.js b/lib/components/MapCircle.js similarity index 100% rename from components/MapCircle.js rename to lib/components/MapCircle.js diff --git a/components/MapMarker.js b/lib/components/MapMarker.js similarity index 100% rename from components/MapMarker.js rename to lib/components/MapMarker.js diff --git a/components/MapPolygon.js b/lib/components/MapPolygon.js similarity index 100% rename from components/MapPolygon.js rename to lib/components/MapPolygon.js diff --git a/components/MapPolyline.js b/lib/components/MapPolyline.js similarity index 100% rename from components/MapPolyline.js rename to lib/components/MapPolyline.js diff --git a/components/MapUrlTile.js b/lib/components/MapUrlTile.js similarity index 100% rename from components/MapUrlTile.js rename to lib/components/MapUrlTile.js diff --git a/components/MapView.js b/lib/components/MapView.js similarity index 100% rename from components/MapView.js rename to lib/components/MapView.js diff --git a/components/ProviderConstants.js b/lib/components/ProviderConstants.js similarity index 100% rename from components/ProviderConstants.js rename to lib/components/ProviderConstants.js diff --git a/components/decorateMapComponent.js b/lib/components/decorateMapComponent.js similarity index 100% rename from components/decorateMapComponent.js rename to lib/components/decorateMapComponent.js diff --git a/ios/AirGoogleMaps/AIRGMSMarker.h b/lib/ios/AirGoogleMaps/AIRGMSMarker.h similarity index 100% rename from ios/AirGoogleMaps/AIRGMSMarker.h rename to lib/ios/AirGoogleMaps/AIRGMSMarker.h diff --git a/ios/AirGoogleMaps/AIRGMSMarker.m b/lib/ios/AirGoogleMaps/AIRGMSMarker.m similarity index 100% rename from ios/AirGoogleMaps/AIRGMSMarker.m rename to lib/ios/AirGoogleMaps/AIRGMSMarker.m diff --git a/ios/AirGoogleMaps/AIRGMSPolygon.h b/lib/ios/AirGoogleMaps/AIRGMSPolygon.h similarity index 100% rename from ios/AirGoogleMaps/AIRGMSPolygon.h rename to lib/ios/AirGoogleMaps/AIRGMSPolygon.h diff --git a/ios/AirGoogleMaps/AIRGMSPolygon.m b/lib/ios/AirGoogleMaps/AIRGMSPolygon.m similarity index 100% rename from ios/AirGoogleMaps/AIRGMSPolygon.m rename to lib/ios/AirGoogleMaps/AIRGMSPolygon.m diff --git a/ios/AirGoogleMaps/AIRGoogleMap.h b/lib/ios/AirGoogleMaps/AIRGoogleMap.h similarity index 100% rename from ios/AirGoogleMaps/AIRGoogleMap.h rename to lib/ios/AirGoogleMaps/AIRGoogleMap.h diff --git a/ios/AirGoogleMaps/AIRGoogleMap.m b/lib/ios/AirGoogleMaps/AIRGoogleMap.m similarity index 100% rename from ios/AirGoogleMaps/AIRGoogleMap.m rename to lib/ios/AirGoogleMaps/AIRGoogleMap.m diff --git a/ios/AirGoogleMaps/AIRGoogleMapCallout.h b/lib/ios/AirGoogleMaps/AIRGoogleMapCallout.h similarity index 100% rename from ios/AirGoogleMaps/AIRGoogleMapCallout.h rename to lib/ios/AirGoogleMaps/AIRGoogleMapCallout.h diff --git a/ios/AirGoogleMaps/AIRGoogleMapCallout.m b/lib/ios/AirGoogleMaps/AIRGoogleMapCallout.m similarity index 100% rename from ios/AirGoogleMaps/AIRGoogleMapCallout.m rename to lib/ios/AirGoogleMaps/AIRGoogleMapCallout.m diff --git a/ios/AirGoogleMaps/AIRGoogleMapCalloutManager.h b/lib/ios/AirGoogleMaps/AIRGoogleMapCalloutManager.h similarity index 100% rename from ios/AirGoogleMaps/AIRGoogleMapCalloutManager.h rename to lib/ios/AirGoogleMaps/AIRGoogleMapCalloutManager.h diff --git a/ios/AirGoogleMaps/AIRGoogleMapCalloutManager.m b/lib/ios/AirGoogleMaps/AIRGoogleMapCalloutManager.m similarity index 100% rename from ios/AirGoogleMaps/AIRGoogleMapCalloutManager.m rename to lib/ios/AirGoogleMaps/AIRGoogleMapCalloutManager.m diff --git a/ios/AirGoogleMaps/AIRGoogleMapCircle.h b/lib/ios/AirGoogleMaps/AIRGoogleMapCircle.h similarity index 100% rename from ios/AirGoogleMaps/AIRGoogleMapCircle.h rename to lib/ios/AirGoogleMaps/AIRGoogleMapCircle.h diff --git a/ios/AirGoogleMaps/AIRGoogleMapCircle.m b/lib/ios/AirGoogleMaps/AIRGoogleMapCircle.m similarity index 100% rename from ios/AirGoogleMaps/AIRGoogleMapCircle.m rename to lib/ios/AirGoogleMaps/AIRGoogleMapCircle.m diff --git a/ios/AirGoogleMaps/AIRGoogleMapCircleManager.h b/lib/ios/AirGoogleMaps/AIRGoogleMapCircleManager.h similarity index 100% rename from ios/AirGoogleMaps/AIRGoogleMapCircleManager.h rename to lib/ios/AirGoogleMaps/AIRGoogleMapCircleManager.h diff --git a/ios/AirGoogleMaps/AIRGoogleMapCircleManager.m b/lib/ios/AirGoogleMaps/AIRGoogleMapCircleManager.m similarity index 100% rename from ios/AirGoogleMaps/AIRGoogleMapCircleManager.m rename to lib/ios/AirGoogleMaps/AIRGoogleMapCircleManager.m diff --git a/ios/AirGoogleMaps/AIRGoogleMapManager.h b/lib/ios/AirGoogleMaps/AIRGoogleMapManager.h similarity index 100% rename from ios/AirGoogleMaps/AIRGoogleMapManager.h rename to lib/ios/AirGoogleMaps/AIRGoogleMapManager.h diff --git a/ios/AirGoogleMaps/AIRGoogleMapManager.m b/lib/ios/AirGoogleMaps/AIRGoogleMapManager.m similarity index 100% rename from ios/AirGoogleMaps/AIRGoogleMapManager.m rename to lib/ios/AirGoogleMaps/AIRGoogleMapManager.m diff --git a/ios/AirGoogleMaps/AIRGoogleMapMarker.h b/lib/ios/AirGoogleMaps/AIRGoogleMapMarker.h similarity index 100% rename from ios/AirGoogleMaps/AIRGoogleMapMarker.h rename to lib/ios/AirGoogleMaps/AIRGoogleMapMarker.h diff --git a/ios/AirGoogleMaps/AIRGoogleMapMarker.m b/lib/ios/AirGoogleMaps/AIRGoogleMapMarker.m similarity index 100% rename from ios/AirGoogleMaps/AIRGoogleMapMarker.m rename to lib/ios/AirGoogleMaps/AIRGoogleMapMarker.m diff --git a/ios/AirGoogleMaps/AIRGoogleMapMarkerManager.h b/lib/ios/AirGoogleMaps/AIRGoogleMapMarkerManager.h similarity index 100% rename from ios/AirGoogleMaps/AIRGoogleMapMarkerManager.h rename to lib/ios/AirGoogleMaps/AIRGoogleMapMarkerManager.h diff --git a/ios/AirGoogleMaps/AIRGoogleMapMarkerManager.m b/lib/ios/AirGoogleMaps/AIRGoogleMapMarkerManager.m similarity index 100% rename from ios/AirGoogleMaps/AIRGoogleMapMarkerManager.m rename to lib/ios/AirGoogleMaps/AIRGoogleMapMarkerManager.m diff --git a/ios/AirGoogleMaps/AIRGoogleMapPolygon.h b/lib/ios/AirGoogleMaps/AIRGoogleMapPolygon.h similarity index 100% rename from ios/AirGoogleMaps/AIRGoogleMapPolygon.h rename to lib/ios/AirGoogleMaps/AIRGoogleMapPolygon.h diff --git a/ios/AirGoogleMaps/AIRGoogleMapPolygon.m b/lib/ios/AirGoogleMaps/AIRGoogleMapPolygon.m similarity index 100% rename from ios/AirGoogleMaps/AIRGoogleMapPolygon.m rename to lib/ios/AirGoogleMaps/AIRGoogleMapPolygon.m diff --git a/ios/AirGoogleMaps/AIRGoogleMapPolygonManager.h b/lib/ios/AirGoogleMaps/AIRGoogleMapPolygonManager.h similarity index 100% rename from ios/AirGoogleMaps/AIRGoogleMapPolygonManager.h rename to lib/ios/AirGoogleMaps/AIRGoogleMapPolygonManager.h diff --git a/ios/AirGoogleMaps/AIRGoogleMapPolygonManager.m b/lib/ios/AirGoogleMaps/AIRGoogleMapPolygonManager.m similarity index 100% rename from ios/AirGoogleMaps/AIRGoogleMapPolygonManager.m rename to lib/ios/AirGoogleMaps/AIRGoogleMapPolygonManager.m diff --git a/ios/AirGoogleMaps/AIRGoogleMapPolyline.h b/lib/ios/AirGoogleMaps/AIRGoogleMapPolyline.h similarity index 100% rename from ios/AirGoogleMaps/AIRGoogleMapPolyline.h rename to lib/ios/AirGoogleMaps/AIRGoogleMapPolyline.h diff --git a/ios/AirGoogleMaps/AIRGoogleMapPolyline.m b/lib/ios/AirGoogleMaps/AIRGoogleMapPolyline.m similarity index 100% rename from ios/AirGoogleMaps/AIRGoogleMapPolyline.m rename to lib/ios/AirGoogleMaps/AIRGoogleMapPolyline.m diff --git a/ios/AirGoogleMaps/AIRGoogleMapPolylineManager.h b/lib/ios/AirGoogleMaps/AIRGoogleMapPolylineManager.h similarity index 100% rename from ios/AirGoogleMaps/AIRGoogleMapPolylineManager.h rename to lib/ios/AirGoogleMaps/AIRGoogleMapPolylineManager.h diff --git a/ios/AirGoogleMaps/AIRGoogleMapPolylineManager.m b/lib/ios/AirGoogleMaps/AIRGoogleMapPolylineManager.m similarity index 100% rename from ios/AirGoogleMaps/AIRGoogleMapPolylineManager.m rename to lib/ios/AirGoogleMaps/AIRGoogleMapPolylineManager.m diff --git a/ios/AirGoogleMaps/AIRGoogleMapURLTileManager.m b/lib/ios/AirGoogleMaps/AIRGoogleMapURLTileManager.m similarity index 100% rename from ios/AirGoogleMaps/AIRGoogleMapURLTileManager.m rename to lib/ios/AirGoogleMaps/AIRGoogleMapURLTileManager.m diff --git a/ios/AirGoogleMaps/AIRGoogleMapUrlTile.h b/lib/ios/AirGoogleMaps/AIRGoogleMapUrlTile.h similarity index 100% rename from ios/AirGoogleMaps/AIRGoogleMapUrlTile.h rename to lib/ios/AirGoogleMaps/AIRGoogleMapUrlTile.h diff --git a/ios/AirGoogleMaps/AIRGoogleMapUrlTile.m b/lib/ios/AirGoogleMaps/AIRGoogleMapUrlTile.m similarity index 100% rename from ios/AirGoogleMaps/AIRGoogleMapUrlTile.m rename to lib/ios/AirGoogleMaps/AIRGoogleMapUrlTile.m diff --git a/ios/AirGoogleMaps/AIRGoogleMapUrlTileManager.h b/lib/ios/AirGoogleMaps/AIRGoogleMapUrlTileManager.h similarity index 100% rename from ios/AirGoogleMaps/AIRGoogleMapUrlTileManager.h rename to lib/ios/AirGoogleMaps/AIRGoogleMapUrlTileManager.h diff --git a/ios/AirGoogleMaps/DummyView.h b/lib/ios/AirGoogleMaps/DummyView.h similarity index 100% rename from ios/AirGoogleMaps/DummyView.h rename to lib/ios/AirGoogleMaps/DummyView.h diff --git a/ios/AirGoogleMaps/DummyView.m b/lib/ios/AirGoogleMaps/DummyView.m similarity index 100% rename from ios/AirGoogleMaps/DummyView.m rename to lib/ios/AirGoogleMaps/DummyView.m diff --git a/ios/AirGoogleMaps/RCTConvert+GMSMapViewType.h b/lib/ios/AirGoogleMaps/RCTConvert+GMSMapViewType.h similarity index 100% rename from ios/AirGoogleMaps/RCTConvert+GMSMapViewType.h rename to lib/ios/AirGoogleMaps/RCTConvert+GMSMapViewType.h diff --git a/ios/AirGoogleMaps/RCTConvert+GMSMapViewType.m b/lib/ios/AirGoogleMaps/RCTConvert+GMSMapViewType.m similarity index 100% rename from ios/AirGoogleMaps/RCTConvert+GMSMapViewType.m rename to lib/ios/AirGoogleMaps/RCTConvert+GMSMapViewType.m diff --git a/ios/AirMaps.xcodeproj/project.pbxproj b/lib/ios/AirMaps.xcodeproj/project.pbxproj similarity index 100% rename from ios/AirMaps.xcodeproj/project.pbxproj rename to lib/ios/AirMaps.xcodeproj/project.pbxproj diff --git a/ios/AirMaps/AIRMap.h b/lib/ios/AirMaps/AIRMap.h similarity index 100% rename from ios/AirMaps/AIRMap.h rename to lib/ios/AirMaps/AIRMap.h diff --git a/ios/AirMaps/AIRMap.m b/lib/ios/AirMaps/AIRMap.m similarity index 100% rename from ios/AirMaps/AIRMap.m rename to lib/ios/AirMaps/AIRMap.m diff --git a/ios/AirMaps/AIRMapCallout.h b/lib/ios/AirMaps/AIRMapCallout.h similarity index 100% rename from ios/AirMaps/AIRMapCallout.h rename to lib/ios/AirMaps/AIRMapCallout.h diff --git a/ios/AirMaps/AIRMapCallout.m b/lib/ios/AirMaps/AIRMapCallout.m similarity index 100% rename from ios/AirMaps/AIRMapCallout.m rename to lib/ios/AirMaps/AIRMapCallout.m diff --git a/ios/AirMaps/AIRMapCalloutManager.h b/lib/ios/AirMaps/AIRMapCalloutManager.h similarity index 100% rename from ios/AirMaps/AIRMapCalloutManager.h rename to lib/ios/AirMaps/AIRMapCalloutManager.h diff --git a/ios/AirMaps/AIRMapCalloutManager.m b/lib/ios/AirMaps/AIRMapCalloutManager.m similarity index 100% rename from ios/AirMaps/AIRMapCalloutManager.m rename to lib/ios/AirMaps/AIRMapCalloutManager.m diff --git a/ios/AirMaps/AIRMapCircle.h b/lib/ios/AirMaps/AIRMapCircle.h similarity index 100% rename from ios/AirMaps/AIRMapCircle.h rename to lib/ios/AirMaps/AIRMapCircle.h diff --git a/ios/AirMaps/AIRMapCircle.m b/lib/ios/AirMaps/AIRMapCircle.m similarity index 100% rename from ios/AirMaps/AIRMapCircle.m rename to lib/ios/AirMaps/AIRMapCircle.m diff --git a/ios/AirMaps/AIRMapCircleManager.h b/lib/ios/AirMaps/AIRMapCircleManager.h similarity index 100% rename from ios/AirMaps/AIRMapCircleManager.h rename to lib/ios/AirMaps/AIRMapCircleManager.h diff --git a/ios/AirMaps/AIRMapCircleManager.m b/lib/ios/AirMaps/AIRMapCircleManager.m similarity index 100% rename from ios/AirMaps/AIRMapCircleManager.m rename to lib/ios/AirMaps/AIRMapCircleManager.m diff --git a/ios/AirMaps/AIRMapCoordinate.h b/lib/ios/AirMaps/AIRMapCoordinate.h similarity index 100% rename from ios/AirMaps/AIRMapCoordinate.h rename to lib/ios/AirMaps/AIRMapCoordinate.h diff --git a/ios/AirMaps/AIRMapCoordinate.m b/lib/ios/AirMaps/AIRMapCoordinate.m similarity index 100% rename from ios/AirMaps/AIRMapCoordinate.m rename to lib/ios/AirMaps/AIRMapCoordinate.m diff --git a/ios/AirMaps/AIRMapManager.h b/lib/ios/AirMaps/AIRMapManager.h similarity index 100% rename from ios/AirMaps/AIRMapManager.h rename to lib/ios/AirMaps/AIRMapManager.h diff --git a/ios/AirMaps/AIRMapManager.m b/lib/ios/AirMaps/AIRMapManager.m similarity index 100% rename from ios/AirMaps/AIRMapManager.m rename to lib/ios/AirMaps/AIRMapManager.m diff --git a/ios/AirMaps/AIRMapMarker.h b/lib/ios/AirMaps/AIRMapMarker.h similarity index 100% rename from ios/AirMaps/AIRMapMarker.h rename to lib/ios/AirMaps/AIRMapMarker.h diff --git a/ios/AirMaps/AIRMapMarker.m b/lib/ios/AirMaps/AIRMapMarker.m similarity index 100% rename from ios/AirMaps/AIRMapMarker.m rename to lib/ios/AirMaps/AIRMapMarker.m diff --git a/ios/AirMaps/AIRMapMarkerManager.h b/lib/ios/AirMaps/AIRMapMarkerManager.h similarity index 100% rename from ios/AirMaps/AIRMapMarkerManager.h rename to lib/ios/AirMaps/AIRMapMarkerManager.h diff --git a/ios/AirMaps/AIRMapMarkerManager.m b/lib/ios/AirMaps/AIRMapMarkerManager.m similarity index 100% rename from ios/AirMaps/AIRMapMarkerManager.m rename to lib/ios/AirMaps/AIRMapMarkerManager.m diff --git a/ios/AirMaps/AIRMapPolygon.h b/lib/ios/AirMaps/AIRMapPolygon.h similarity index 100% rename from ios/AirMaps/AIRMapPolygon.h rename to lib/ios/AirMaps/AIRMapPolygon.h diff --git a/ios/AirMaps/AIRMapPolygon.m b/lib/ios/AirMaps/AIRMapPolygon.m similarity index 100% rename from ios/AirMaps/AIRMapPolygon.m rename to lib/ios/AirMaps/AIRMapPolygon.m diff --git a/ios/AirMaps/AIRMapPolygonManager.h b/lib/ios/AirMaps/AIRMapPolygonManager.h similarity index 100% rename from ios/AirMaps/AIRMapPolygonManager.h rename to lib/ios/AirMaps/AIRMapPolygonManager.h diff --git a/ios/AirMaps/AIRMapPolygonManager.m b/lib/ios/AirMaps/AIRMapPolygonManager.m similarity index 100% rename from ios/AirMaps/AIRMapPolygonManager.m rename to lib/ios/AirMaps/AIRMapPolygonManager.m diff --git a/ios/AirMaps/AIRMapPolyline.h b/lib/ios/AirMaps/AIRMapPolyline.h similarity index 100% rename from ios/AirMaps/AIRMapPolyline.h rename to lib/ios/AirMaps/AIRMapPolyline.h diff --git a/ios/AirMaps/AIRMapPolyline.m b/lib/ios/AirMaps/AIRMapPolyline.m similarity index 100% rename from ios/AirMaps/AIRMapPolyline.m rename to lib/ios/AirMaps/AIRMapPolyline.m diff --git a/ios/AirMaps/AIRMapPolylineManager.h b/lib/ios/AirMaps/AIRMapPolylineManager.h similarity index 100% rename from ios/AirMaps/AIRMapPolylineManager.h rename to lib/ios/AirMaps/AIRMapPolylineManager.h diff --git a/ios/AirMaps/AIRMapPolylineManager.m b/lib/ios/AirMaps/AIRMapPolylineManager.m similarity index 100% rename from ios/AirMaps/AIRMapPolylineManager.m rename to lib/ios/AirMaps/AIRMapPolylineManager.m diff --git a/ios/AirMaps/AIRMapSnapshot.h b/lib/ios/AirMaps/AIRMapSnapshot.h similarity index 100% rename from ios/AirMaps/AIRMapSnapshot.h rename to lib/ios/AirMaps/AIRMapSnapshot.h diff --git a/ios/AirMaps/AIRMapUrlTile.h b/lib/ios/AirMaps/AIRMapUrlTile.h similarity index 100% rename from ios/AirMaps/AIRMapUrlTile.h rename to lib/ios/AirMaps/AIRMapUrlTile.h diff --git a/ios/AirMaps/AIRMapUrlTile.m b/lib/ios/AirMaps/AIRMapUrlTile.m similarity index 100% rename from ios/AirMaps/AIRMapUrlTile.m rename to lib/ios/AirMaps/AIRMapUrlTile.m diff --git a/ios/AirMaps/AIRMapUrlTileManager.h b/lib/ios/AirMaps/AIRMapUrlTileManager.h similarity index 100% rename from ios/AirMaps/AIRMapUrlTileManager.h rename to lib/ios/AirMaps/AIRMapUrlTileManager.h diff --git a/ios/AirMaps/AIRMapUrlTileManager.m b/lib/ios/AirMaps/AIRMapUrlTileManager.m similarity index 100% rename from ios/AirMaps/AIRMapUrlTileManager.m rename to lib/ios/AirMaps/AIRMapUrlTileManager.m diff --git a/ios/AirMaps/Callout/SMCalloutView.h b/lib/ios/AirMaps/Callout/SMCalloutView.h similarity index 100% rename from ios/AirMaps/Callout/SMCalloutView.h rename to lib/ios/AirMaps/Callout/SMCalloutView.h diff --git a/ios/AirMaps/Callout/SMCalloutView.m b/lib/ios/AirMaps/Callout/SMCalloutView.m similarity index 100% rename from ios/AirMaps/Callout/SMCalloutView.m rename to lib/ios/AirMaps/Callout/SMCalloutView.m diff --git a/ios/AirMaps/RCTConvert+MapKit.h b/lib/ios/AirMaps/RCTConvert+MapKit.h similarity index 100% rename from ios/AirMaps/RCTConvert+MapKit.h rename to lib/ios/AirMaps/RCTConvert+MapKit.h diff --git a/ios/AirMaps/RCTConvert+MapKit.m b/lib/ios/AirMaps/RCTConvert+MapKit.m similarity index 100% rename from ios/AirMaps/RCTConvert+MapKit.m rename to lib/ios/AirMaps/RCTConvert+MapKit.m diff --git a/package.json b/package.json index 42a006cea..70224da44 100644 --- a/package.json +++ b/package.json @@ -5,8 +5,17 @@ "author": "Leland Richardson ", "version": "0.13.1", "scripts": { - "start": "react-native start", - "lint": "eslint .", + "start": "node node_modules/react-native/local-cli/cli.js start", + "run:packager": "./node_modules/react-native/packager/packager.sh", + "run:ios": "react-native run-ios --project-path ./example/ios", + "start:android": "adb shell am start -n com.airbnb.android.react.maps.example/.MainActivity", + "run:android": "./gradlew installDebug && npm run start:android", + "lint": "eslint ./", + "build": "npm run build:js && npm run build:android && npm run build:ios", + "build:js": "exit 0", + "build:ios": "bundle install --binstubs ./examples/ios && bundle exec pod install --project-directory=./example/ios/", + "build:android": "./gradlew :react-native-maps:assembleDebug", + "ci": "npm run lint", "preversion": "./scripts/update-version.js" }, "repository": { @@ -28,12 +37,19 @@ }, "devDependencies": { "babel-eslint": "^6.1.2", + "babel-plugin-module-resolver": "^2.3.0", + "babel-preset-airbnb": "^1.1.1", + "babel-preset-react-native": "1.9.0", "eslint": "^3.3.1", "eslint-config-airbnb": "^10.0.1", "eslint-plugin-import": "^1.14.0", "eslint-plugin-jsx-a11y": "^2.1.0", "eslint-plugin-prefer-object-spread": "^1.1.0", - "eslint-plugin-react": "^6.1.2" + "eslint-plugin-react": "^6.1.2", + "gitbook-cli": "^2.3.0", + "lodash": "^4.17.2", + "react": "~15.4.1", + "react-native": "^0.42.0" }, "rnpm": { "android": { diff --git a/react-native-google-maps.podspec b/react-native-google-maps.podspec index 6f6b28703..632da81d5 100644 --- a/react-native-google-maps.podspec +++ b/react-native-google-maps.podspec @@ -1,6 +1,10 @@ +require 'json' + +package = JSON.parse(File.read(File.join(__dir__, 'package.json'))) + Pod::Spec.new do |s| s.name = "react-native-google-maps" - s.version = "0.13.0" + s.version = package['version'] s.summary = "React Native Mapview component for iOS + Android" s.authors = { "intelligibabble" => "leland.m.richardson@gmail.com" } @@ -9,7 +13,7 @@ Pod::Spec.new do |s| s.platform = :ios, "8.0" s.source = { :git => "https://github.com/airbnb/react-native-maps.git" } - s.source_files = "ios/AirGoogleMaps/**/*.{h,m}" + s.source_files = "lib/ios/AirGoogleMaps/**/*.{h,m}" s.dependency 'React' s.dependency 'GoogleMaps', '2.1.1' diff --git a/react-native-maps.podspec b/react-native-maps.podspec index 601e4eb71..387265989 100644 --- a/react-native-maps.podspec +++ b/react-native-maps.podspec @@ -1,6 +1,10 @@ +require 'json' + +package = JSON.parse(File.read(File.join(__dir__, 'package.json'))) + Pod::Spec.new do |s| s.name = "react-native-maps" - s.version = "0.13.0" + s.version = package['version'] s.summary = "React Native Mapview component for iOS + Android" s.authors = { "intelligibabble" => "leland.m.richardson@gmail.com" } @@ -9,7 +13,7 @@ Pod::Spec.new do |s| s.platform = :ios, "8.0" s.source = { :git => "https://github.com/airbnb/react-native-maps.git" } - s.source_files = "ios/AirMaps/**/*.{h,m}" + s.source_files = "lib/ios/AirMaps/**/*.{h,m}" s.dependency 'React' end diff --git a/rn-cli.config.js b/rn-cli.config.js new file mode 100644 index 000000000..d58725ef3 --- /dev/null +++ b/rn-cli.config.js @@ -0,0 +1,11 @@ +const config = { + /** + * Returns a regular expression for modules that should be ignored by the + * packager on a given platform. + */ + getBlacklistRE() { + return /_book\//; + }, +}; + +module.exports = config; diff --git a/scripts/update-version.js b/scripts/update-version.js index f8f840ea7..232cda449 100755 --- a/scripts/update-version.js +++ b/scripts/update-version.js @@ -5,8 +5,8 @@ * reference to the current package version: * * - android/gradle.properties - * - react-native-maps.podspec - * - react-native-google-maps.podspec + * x react-native-maps.podspec // <-- this is now dynamic + * x react-native-google-maps.podspec // <-- this is now dynamic * * And `git add`s them. */ @@ -16,8 +16,6 @@ const pkg = require('../package.json'); const filesToUpdate = [ 'android/gradle.properties', - 'react-native-maps.podspec', - 'react-native-google-maps.podspec', ]; function doExec(cmdString) { diff --git a/settings.gradle b/settings.gradle new file mode 100644 index 000000000..4196dd53b --- /dev/null +++ b/settings.gradle @@ -0,0 +1,7 @@ +rootProject.name = 'react-native-maps' + +include ":example-android" +project(":example-android").projectDir = file("./example/android/app") + +include ":react-native-maps-lib" +project(":react-native-maps-lib").projectDir = file("./lib/android") From a7426a84d7791918bd1777437aeeeb401b512fc1 Mon Sep 17 00:00:00 2001 From: Leland Richardson Date: Sun, 26 Mar 2017 16:20:27 -0700 Subject: [PATCH 082/199] Add android only note to showsIndoorLevelPicker --- docs/mapview.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/mapview.md b/docs/mapview.md index f242f636b..8e73a0773 100644 --- a/docs/mapview.md +++ b/docs/mapview.md @@ -20,7 +20,7 @@ | `showsBuildings` | `Boolean` | `true` | A Boolean indicating whether the map displays extruded building information. | `showsTraffic` | `Boolean` | `true` | A Boolean value indicating whether the map displays traffic information. | `showsIndoors` | `Boolean` | `true` | A Boolean indicating whether indoor maps should be enabled. -| `showsIndoorLevelPicker` | `Boolean` | `false` | A Boolean indicating whether indoor level picker should be enabled. +| `showsIndoorLevelPicker` | `Boolean` | `false` | A Boolean indicating whether indoor level picker should be enabled. **Note:** Android only. | `zoomEnabled` | `Boolean` | `true` | If `false` the user won't be able to pinch/zoom the map. | `rotateEnabled` | `Boolean` | `true` | If `false` the user won't be able to pinch/rotate the map. | `scrollEnabled` | `Boolean` | `true` | If `false` the user won't be able to change the map region being displayed. From f92b6e5e6b5c322374fcbfabf0c9b6c06ed25144 Mon Sep 17 00:00:00 2001 From: Leland Richardson Date: Sun, 26 Mar 2017 16:59:52 -0700 Subject: [PATCH 083/199] Address PR feedback from #1130 --- .../android/app/src/main/AndroidManifest.xml | 1 + lib/android/src/main/AndroidManifest.xml | 1 + .../airbnb/android/react/maps/AirMapView.java | 21 ++++++++++++------- 3 files changed, 15 insertions(+), 8 deletions(-) diff --git a/example/android/app/src/main/AndroidManifest.xml b/example/android/app/src/main/AndroidManifest.xml index 2742d5793..b111eef4a 100644 --- a/example/android/app/src/main/AndroidManifest.xml +++ b/example/android/app/src/main/AndroidManifest.xml @@ -1,6 +1,7 @@ + + diff --git a/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapView.java b/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapView.java index 0f4fb45d8..0c8604f26 100644 --- a/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapView.java +++ b/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapView.java @@ -1,6 +1,5 @@ package com.airbnb.android.react.maps; -import android.content.Context; import android.content.pm.PackageManager; import android.content.res.ColorStateList; import android.graphics.Bitmap; @@ -21,7 +20,6 @@ import android.widget.RelativeLayout; import com.facebook.react.bridge.LifecycleEventListener; -import com.facebook.react.bridge.ReactContext; import com.facebook.react.bridge.ReadableArray; import com.facebook.react.bridge.ReadableMap; import com.facebook.react.bridge.WritableMap; @@ -142,6 +140,9 @@ public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, @Override public void onMapReady(final GoogleMap map) { + if (destroyed) { + return; + } this.map = map; this.map.setInfoWindowAdapter(this); this.map.setOnMarkerDragListener(this); @@ -298,22 +299,26 @@ private boolean hasPermissions() { checkSelfPermission(getContext(), PERMISSIONS[1]) == PackageManager.PERMISSION_GRANTED; } + + /* onDestroy is final method so I can't override it. */ public synchronized void doDestroy() { + if (destroyed) { + return; + } + destroyed = true; + if (lifecycleListener != null && context != null) { context.removeLifecycleEventListener(lifecycleListener); lifecycleListener = null; } - if(!paused) { + if (!paused) { onPause(); + paused = true; } - if (!destroyed) { - onDestroy(); - destroyed = true; - } - + onDestroy(); } public void setRegion(ReadableMap region) { From 254eb1f2a72b037245d1218f201309068b969fc7 Mon Sep 17 00:00:00 2001 From: Leland Richardson Date: Sun, 26 Mar 2017 22:42:28 -0700 Subject: [PATCH 084/199] Upgrade GMS dependencies to 10.2.0 --- lib/android/build.gradle | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/android/build.gradle b/lib/android/build.gradle index 062f040ca..85cb5b4d2 100644 --- a/lib/android/build.gradle +++ b/lib/android/build.gradle @@ -35,6 +35,6 @@ android { dependencies { provided "com.facebook.react:react-native:+" - compile "com.google.android.gms:play-services-base:10.0.1" - compile "com.google.android.gms:play-services-maps:10.0.1" + compile "com.google.android.gms:play-services-base:10.2.0" + compile "com.google.android.gms:play-services-maps:10.2.0" } From 4926f5b53fac8e1ab9aaf877e81048e262dee8aa Mon Sep 17 00:00:00 2001 From: Janic Duplessis Date: Mon, 27 Mar 2017 18:24:24 -0400 Subject: [PATCH 085/199] Rename MapKit category to avoid conflicts with the one in RN --- lib/ios/AirGoogleMaps/AIRGoogleMap.h | 2 +- lib/ios/AirGoogleMaps/AIRGoogleMap.m | 2 +- lib/ios/AirGoogleMaps/AIRGoogleMapManager.m | 2 +- lib/ios/AirGoogleMaps/AIRGoogleMapMarkerManager.m | 2 +- lib/ios/AirGoogleMaps/AIRGoogleMapPolygonManager.m | 2 +- lib/ios/AirGoogleMaps/AIRGoogleMapPolylineManager.m | 2 +- lib/ios/AirMaps/AIRMap.h | 2 +- lib/ios/AirMaps/AIRMapCircle.h | 2 +- lib/ios/AirMaps/AIRMapManager.m | 2 +- lib/ios/AirMaps/AIRMapMarker.h | 2 +- lib/ios/AirMaps/AIRMapPolygon.h | 2 +- lib/ios/AirMaps/AIRMapPolygonManager.m | 2 +- lib/ios/AirMaps/AIRMapPolyline.h | 2 +- lib/ios/AirMaps/AIRMapPolylineManager.m | 2 +- lib/ios/AirMaps/AIRMapUrlTile.h | 2 +- lib/ios/AirMaps/{RCTConvert+MapKit.h => RCTConvert+AirMap.h} | 2 +- lib/ios/AirMaps/{RCTConvert+MapKit.m => RCTConvert+AirMap.m} | 4 ++-- 17 files changed, 18 insertions(+), 18 deletions(-) rename lib/ios/AirMaps/{RCTConvert+MapKit.h => RCTConvert+AirMap.h} (91%) rename lib/ios/AirMaps/{RCTConvert+MapKit.m => RCTConvert+AirMap.m} (95%) diff --git a/lib/ios/AirGoogleMaps/AIRGoogleMap.h b/lib/ios/AirGoogleMaps/AIRGoogleMap.h index 8006a804e..9e6ae8b79 100644 --- a/lib/ios/AirGoogleMaps/AIRGoogleMap.h +++ b/lib/ios/AirGoogleMaps/AIRGoogleMap.h @@ -10,7 +10,7 @@ #import #import #import "AIRGMSMarker.h" -#import "RCTConvert+MapKit.h" +#import "RCTConvert+AirMap.h" @interface AIRGoogleMap : GMSMapView diff --git a/lib/ios/AirGoogleMaps/AIRGoogleMap.m b/lib/ios/AirGoogleMaps/AIRGoogleMap.m index 8f51c26e7..ca15da04e 100644 --- a/lib/ios/AirGoogleMaps/AIRGoogleMap.m +++ b/lib/ios/AirGoogleMaps/AIRGoogleMap.m @@ -14,7 +14,7 @@ #import #import #import -#import "RCTConvert+MapKit.h" +#import "RCTConvert+AirMap.h" id regionAsJSON(MKCoordinateRegion region) { return @{ diff --git a/lib/ios/AirGoogleMaps/AIRGoogleMapManager.m b/lib/ios/AirGoogleMaps/AIRGoogleMapManager.m index 6e81c7e9b..785d58d4d 100644 --- a/lib/ios/AirGoogleMaps/AIRGoogleMapManager.m +++ b/lib/ios/AirGoogleMaps/AIRGoogleMapManager.m @@ -23,7 +23,7 @@ #import "AIRMapCircle.h" #import "SMCalloutView.h" #import "AIRGoogleMapMarker.h" -#import "RCTConvert+MapKit.h" +#import "RCTConvert+AirMap.h" #import diff --git a/lib/ios/AirGoogleMaps/AIRGoogleMapMarkerManager.m b/lib/ios/AirGoogleMaps/AIRGoogleMapMarkerManager.m index ac2e44347..8be4ba53e 100644 --- a/lib/ios/AirGoogleMaps/AIRGoogleMapMarkerManager.m +++ b/lib/ios/AirGoogleMaps/AIRGoogleMapMarkerManager.m @@ -9,7 +9,7 @@ #import "AIRGoogleMapMarker.h" #import #import -#import "RCTConvert+MapKit.h" +#import "RCTConvert+AirMap.h" @implementation AIRGoogleMapMarkerManager diff --git a/lib/ios/AirGoogleMaps/AIRGoogleMapPolygonManager.m b/lib/ios/AirGoogleMaps/AIRGoogleMapPolygonManager.m index 0dd8d54a0..59e239627 100644 --- a/lib/ios/AirGoogleMaps/AIRGoogleMapPolygonManager.m +++ b/lib/ios/AirGoogleMaps/AIRGoogleMapPolygonManager.m @@ -11,7 +11,7 @@ #import #import #import -#import "RCTConvert+MapKit.h" +#import "RCTConvert+AirMap.h" #import "AIRGoogleMapPolygon.h" @interface AIRGoogleMapPolygonManager() diff --git a/lib/ios/AirGoogleMaps/AIRGoogleMapPolylineManager.m b/lib/ios/AirGoogleMaps/AIRGoogleMapPolylineManager.m index 5fca4e902..acad1631b 100644 --- a/lib/ios/AirGoogleMaps/AIRGoogleMapPolylineManager.m +++ b/lib/ios/AirGoogleMaps/AIRGoogleMapPolylineManager.m @@ -12,7 +12,7 @@ #import #import #import -#import "RCTConvert+MapKit.h" +#import "RCTConvert+AirMap.h" #import "AIRGoogleMapPolyline.h" @interface AIRGoogleMapPolylineManager() diff --git a/lib/ios/AirMaps/AIRMap.h b/lib/ios/AirMaps/AIRMap.h index b74163cb9..18c9a0bc0 100644 --- a/lib/ios/AirMaps/AIRMap.h +++ b/lib/ios/AirMaps/AIRMap.h @@ -12,7 +12,7 @@ #import #import "SMCalloutView.h" -#import "RCTConvert+MapKit.h" +#import "RCTConvert+AirMap.h" extern const CLLocationDegrees AIRMapDefaultSpan; extern const NSTimeInterval AIRMapRegionChangeObserveInterval; diff --git a/lib/ios/AirMaps/AIRMapCircle.h b/lib/ios/AirMaps/AIRMapCircle.h index 7d7160e85..83a70f297 100644 --- a/lib/ios/AirMaps/AIRMapCircle.h +++ b/lib/ios/AirMaps/AIRMapCircle.h @@ -13,7 +13,7 @@ #import "AIRMapCoordinate.h" #import "AIRMap.h" -#import "RCTConvert+MapKit.h" +#import "RCTConvert+AirMap.h" @interface AIRMapCircle: MKAnnotationView diff --git a/lib/ios/AirMaps/AIRMapManager.m b/lib/ios/AirMaps/AIRMapManager.m index 1e2c3f5ac..619142bd6 100644 --- a/lib/ios/AirMaps/AIRMapManager.m +++ b/lib/ios/AirMaps/AIRMapManager.m @@ -24,7 +24,7 @@ #import "SMCalloutView.h" #import "AIRMapUrlTile.h" #import "AIRMapSnapshot.h" -#import "RCTConvert+MapKit.h" +#import "RCTConvert+AirMap.h" #import diff --git a/lib/ios/AirMaps/AIRMapMarker.h b/lib/ios/AirMaps/AIRMapMarker.h index bbcabf506..0613544a9 100644 --- a/lib/ios/AirMaps/AIRMapMarker.h +++ b/lib/ios/AirMaps/AIRMapMarker.h @@ -16,7 +16,7 @@ #import #import "AIRMap.h" #import "SMCalloutView.h" -#import "RCTConvert+MapKit.h" +#import "RCTConvert+AirMap.h" @class RCTBridge; diff --git a/lib/ios/AirMaps/AIRMapPolygon.h b/lib/ios/AirMaps/AIRMapPolygon.h index 15def9100..611d942e7 100644 --- a/lib/ios/AirMaps/AIRMapPolygon.h +++ b/lib/ios/AirMaps/AIRMapPolygon.h @@ -12,7 +12,7 @@ #import #import "AIRMapCoordinate.h" #import "AIRMap.h" -#import "RCTConvert+MapKit.h" +#import "RCTConvert+AirMap.h" diff --git a/lib/ios/AirMaps/AIRMapPolygonManager.m b/lib/ios/AirMaps/AIRMapPolygonManager.m index e9be4936a..543644e82 100644 --- a/lib/ios/AirMaps/AIRMapPolygonManager.m +++ b/lib/ios/AirMaps/AIRMapPolygonManager.m @@ -15,7 +15,7 @@ #import #import #import -#import "RCTConvert+MapKit.h" +#import "RCTConvert+AirMap.h" #import "AIRMapMarker.h" #import "AIRMapPolygon.h" diff --git a/lib/ios/AirMaps/AIRMapPolyline.h b/lib/ios/AirMaps/AIRMapPolyline.h index 6fb5feadc..6311c3248 100644 --- a/lib/ios/AirMaps/AIRMapPolyline.h +++ b/lib/ios/AirMaps/AIRMapPolyline.h @@ -12,7 +12,7 @@ #import #import "AIRMapCoordinate.h" #import "AIRMap.h" -#import "RCTConvert+MapKit.h" +#import "RCTConvert+AirMap.h" @interface AIRMapPolyline: MKAnnotationView diff --git a/lib/ios/AirMaps/AIRMapPolylineManager.m b/lib/ios/AirMaps/AIRMapPolylineManager.m index d00a9efac..e064b7c4b 100644 --- a/lib/ios/AirMaps/AIRMapPolylineManager.m +++ b/lib/ios/AirMaps/AIRMapPolylineManager.m @@ -15,7 +15,7 @@ #import #import #import -#import "RCTConvert+MapKit.h" +#import "RCTConvert+AirMap.h" #import "AIRMapMarker.h" #import "AIRMapPolyline.h" diff --git a/lib/ios/AirMaps/AIRMapUrlTile.h b/lib/ios/AirMaps/AIRMapUrlTile.h index a33be61d1..49963d3ee 100644 --- a/lib/ios/AirMaps/AIRMapUrlTile.h +++ b/lib/ios/AirMaps/AIRMapUrlTile.h @@ -14,7 +14,7 @@ #import #import "AIRMapCoordinate.h" #import "AIRMap.h" -#import "RCTConvert+MapKit.h" +#import "RCTConvert+AirMap.h" @interface AIRMapUrlTile : MKAnnotationView diff --git a/lib/ios/AirMaps/RCTConvert+MapKit.h b/lib/ios/AirMaps/RCTConvert+AirMap.h similarity index 91% rename from lib/ios/AirMaps/RCTConvert+MapKit.h rename to lib/ios/AirMaps/RCTConvert+AirMap.h index 28f60bf96..fc1059d91 100644 --- a/lib/ios/AirMaps/RCTConvert+MapKit.h +++ b/lib/ios/AirMaps/RCTConvert+AirMap.h @@ -7,7 +7,7 @@ #import #import -@interface RCTConvert (MapKit) +@interface RCTConvert (AirMap) + (MKCoordinateSpan)MKCoordinateSpan:(id)json; + (MKCoordinateRegion)MKCoordinateRegion:(id)json; diff --git a/lib/ios/AirMaps/RCTConvert+MapKit.m b/lib/ios/AirMaps/RCTConvert+AirMap.m similarity index 95% rename from lib/ios/AirMaps/RCTConvert+MapKit.m rename to lib/ios/AirMaps/RCTConvert+AirMap.m index 2e3b11602..cfdbb17ce 100644 --- a/lib/ios/AirMaps/RCTConvert+MapKit.m +++ b/lib/ios/AirMaps/RCTConvert+AirMap.m @@ -3,12 +3,12 @@ // Copyright (c) 2015 Facebook. All rights reserved. // -#import "RCTConvert+MapKit.h" +#import "RCTConvert+AirMap.h" #import #import "AIRMapCoordinate.h" -@implementation RCTConvert (MapKit) +@implementation RCTConvert (AirMap) + (MKCoordinateSpan)MKCoordinateSpan:(id)json { From 6553f68010f25c2237c60968be586a827bf2d3e6 Mon Sep 17 00:00:00 2001 From: Leland Richardson Date: Wed, 29 Mar 2017 16:45:44 -0700 Subject: [PATCH 086/199] Add postinstall script to disable modules for airgmaps --- example/ios/Podfile | 11 +++++++++++ example/ios/Podfile.lock | 2 +- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/example/ios/Podfile b/example/ios/Podfile index ec73199a4..6cff9aae8 100644 --- a/example/ios/Podfile +++ b/example/ios/Podfile @@ -26,3 +26,14 @@ target 'AirMapsExplorer' do pod 'react-native-google-maps', path: '../../' # <~~ if you need GoogleMaps support on iOS end + + +post_install do |installer| + installer.pods_project.targets.each do |target| + if target.name == "react-native-google-maps" + target.build_configurations.each do |config| + config.build_settings['CLANG_ENABLE_MODULES'] = 'No' + end + end + end +end diff --git a/example/ios/Podfile.lock b/example/ios/Podfile.lock index 60339f2b0..ff6774aa2 100644 --- a/example/ios/Podfile.lock +++ b/example/ios/Podfile.lock @@ -74,6 +74,6 @@ SPEC CHECKSUMS: react-native-maps: 326ddbaaea8f6044b1817fb028c40950c71cc38a Yoga: 86ce777665c8259b94ef8dbea76b84634237f4ea -PODFILE CHECKSUM: 206f5482deac191368c01dd654d14fbd3e5d6b8f +PODFILE CHECKSUM: 222d08e48f834b6a3de650b72786105af7a9d331 COCOAPODS: 1.2.0 From bf5f0a3f5ba51e8f5044f6f72680d71a677e7c26 Mon Sep 17 00:00:00 2001 From: Leland Richardson Date: Tue, 4 Apr 2017 18:19:39 -0700 Subject: [PATCH 087/199] Fix getResources() null crash in mapview --- .../airbnb/android/react/maps/AirMapView.java | 33 ++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) diff --git a/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapView.java b/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapView.java index 0c8604f26..772627e4a 100644 --- a/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapView.java +++ b/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapView.java @@ -1,5 +1,7 @@ package com.airbnb.android.react.maps; +import android.app.Activity; +import android.content.Context; import android.content.pm.PackageManager; import android.content.res.ColorStateList; import android.graphics.Bitmap; @@ -85,9 +87,38 @@ public class AirMapView extends MapView implements GoogleMap.InfoWindowAdapter, private final ThemedReactContext context; private final EventDispatcher eventDispatcher; + private static boolean contextHasBug(Context context) { + return context == null || + context.getResources() == null || + context.getResources().getConfiguration() == null; + } + + // We do this to fix this bug: + // https://github.com/airbnb/react-native-maps/issues/271 + // + // which conflicts with another bug regarding the passed in context: + // https://github.com/airbnb/react-native-maps/issues/1147 + // + // Doing this allows us to avoid both bugs. + private static Context getNonBuggyContext(ThemedReactContext reactContext) { + Context superContext = reactContext; + + if (contextHasBug(superContext)) { + // we have the bug! let's try to find a better context to use + if (!contextHasBug(reactContext.getCurrentActivity())) { + superContext = reactContext.getCurrentActivity(); + } else if (!contextHasBug(reactContext.getApplicationContext())) { + superContext = reactContext.getApplicationContext(); + } else { + // ¯\_(ツ)_/¯ + } + } + return superContext; + } + public AirMapView(ThemedReactContext reactContext, AirMapManager manager, GoogleMapOptions googleMapOptions) { - super(reactContext, googleMapOptions); + super(getNonBuggyContext(reactContext), googleMapOptions); this.manager = manager; this.context = reactContext; From 4849de52b2af70225c8bf3393fc3452f186acd07 Mon Sep 17 00:00:00 2001 From: Leland Richardson Date: Tue, 4 Apr 2017 18:41:01 -0700 Subject: [PATCH 088/199] v0.14.0 --- CHANGELOG.md | 43 +++++++++++++++++++++++++++++++++++ lib/android/gradle.properties | 2 +- package.json | 2 +- 3 files changed, 45 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a6e3ab5c3..5c13e5ba0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,48 @@ # Change Log +## 0.14.0 (April 4, 2017) + +## Enhancements + +* Restructure project #1164 + +* Add showsIndoorLevelPicker -> setIndoorLevelPickerEnabled to MapView #1019 +[#1188](https://github.com/airbnb/react-native-maps/pull/1188) + +* iOS - Added onPress support for Polygons on Google Maps +[#1024](https://github.com/airbnb/react-native-maps/pull/1024) + +* Add customized user location annotation text +[#1049](https://github.com/airbnb/react-native-maps/pull/1049) + +* iOS - Google Maps - Add `showsMyLocationButton` support +[#1157](https://github.com/airbnb/react-native-maps/pull/1157) + + +## Patches + +* Fix getResources() null crash in mapview +[#1188](https://github.com/airbnb/react-native-maps/pull/1188) + +* Rename MapKit category to avoid conflicts with the one in RN +[#1172](https://github.com/airbnb/react-native-maps/pull/1172) + +* Upgrade GMS dependencies to 10.2.0 +[#1169](https://github.com/airbnb/react-native-maps/pull/1169) + +* fix multiple-instance memory leak +[#1130](https://github.com/airbnb/react-native-maps/pull/1130) + +* fix onSelected event for markers with custom view +[#1079](https://github.com/airbnb/react-native-maps/pull/1079) + +* Crash in our App fix +[#1096](https://github.com/airbnb/react-native-maps/pull/1096) + +* Use local RCTConvert+MapKit instead of the one in React Native +[#1138](https://github.com/airbnb/react-native-maps/pull/1138) + + ## 0.13.1 (March 21, 2017) diff --git a/lib/android/gradle.properties b/lib/android/gradle.properties index cfe4fd7d4..9a87aa52e 100644 --- a/lib/android/gradle.properties +++ b/lib/android/gradle.properties @@ -1,5 +1,5 @@ VERSION_CODE=4 -VERSION_NAME=0.13.1 +VERSION_NAME=0.14.0 GROUP=com.airbnb.android POM_DESCRIPTION=React Native Map view component for Android diff --git a/package.json b/package.json index 70224da44..9bbc2e1dd 100644 --- a/package.json +++ b/package.json @@ -3,7 +3,7 @@ "description": "React Native Mapview component for iOS + Android", "main": "index.js", "author": "Leland Richardson ", - "version": "0.13.1", + "version": "0.14.0", "scripts": { "start": "node node_modules/react-native/local-cli/cli.js start", "run:packager": "./node_modules/react-native/packager/packager.sh", From 79cb8ebb2481dc96909fa3d25414078619dce4d0 Mon Sep 17 00:00:00 2001 From: ksincennes Date: Wed, 5 Apr 2017 15:35:00 -0600 Subject: [PATCH 089/199] Fixing memory issue and moving files --- .../java/com/airbnb/android/react/maps/AirMapGeoJSON.java | 0 .../com/airbnb/android/react/maps/AirMapGeoJSONManager.java | 0 .../main/java/com/airbnb/android/react/maps/AirMapView.java | 4 ++++ 3 files changed, 4 insertions(+) rename {android => lib/android}/src/main/java/com/airbnb/android/react/maps/AirMapGeoJSON.java (100%) rename {android => lib/android}/src/main/java/com/airbnb/android/react/maps/AirMapGeoJSONManager.java (100%) diff --git a/android/src/main/java/com/airbnb/android/react/maps/AirMapGeoJSON.java b/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapGeoJSON.java similarity index 100% rename from android/src/main/java/com/airbnb/android/react/maps/AirMapGeoJSON.java rename to lib/android/src/main/java/com/airbnb/android/react/maps/AirMapGeoJSON.java diff --git a/android/src/main/java/com/airbnb/android/react/maps/AirMapGeoJSONManager.java b/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapGeoJSONManager.java similarity index 100% rename from android/src/main/java/com/airbnb/android/react/maps/AirMapGeoJSONManager.java rename to lib/android/src/main/java/com/airbnb/android/react/maps/AirMapGeoJSONManager.java diff --git a/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapView.java b/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapView.java index e7735adde..9ef499e5c 100644 --- a/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapView.java +++ b/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapView.java @@ -503,6 +503,10 @@ public void removeFeatureAt(int index) { AirMapFeature feature = features.remove(index); if (feature instanceof AirMapMarker) { markerMap.remove(feature.getFeature()); + } else if(feature instanceof AirMapPolyline){ + polylineMap.remove(feature.getFeature()); + } else if(feature instanceof AirMapPolygon){ + polygonMap.remove(feature.getFeature()); } feature.removeFromMap(map); } From 4b861c949a079a393f48a485943d3a506a151ac0 Mon Sep 17 00:00:00 2001 From: Rob Hogan Date: Thu, 4 May 2017 20:23:41 +0100 Subject: [PATCH 090/199] pbxproj: RCTConvert+MapKit -> RCTConvert+AirMap (#1195) --- lib/ios/AirMaps.xcodeproj/project.pbxproj | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/lib/ios/AirMaps.xcodeproj/project.pbxproj b/lib/ios/AirMaps.xcodeproj/project.pbxproj index 39b1256e2..ac641aff7 100644 --- a/lib/ios/AirMaps.xcodeproj/project.pbxproj +++ b/lib/ios/AirMaps.xcodeproj/project.pbxproj @@ -21,7 +21,7 @@ 1125B2E51C4AD3DA007D0023 /* AIRMapPolyline.m in Sources */ = {isa = PBXBuildFile; fileRef = 1125B2D41C4AD3DA007D0023 /* AIRMapPolyline.m */; }; 1125B2E61C4AD3DA007D0023 /* AIRMapPolylineManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 1125B2D61C4AD3DA007D0023 /* AIRMapPolylineManager.m */; }; 1125B2F21C4AD445007D0023 /* SMCalloutView.m in Sources */ = {isa = PBXBuildFile; fileRef = 1125B2F11C4AD445007D0023 /* SMCalloutView.m */; }; - 19DABC7F1E7C9D3C00F41150 /* RCTConvert+MapKit.m in Sources */ = {isa = PBXBuildFile; fileRef = 19DABC7E1E7C9D3C00F41150 /* RCTConvert+MapKit.m */; }; + 19DABC7F1E7C9D3C00F41150 /* RCTConvert+AirMap.m in Sources */ = {isa = PBXBuildFile; fileRef = 19DABC7E1E7C9D3C00F41150 /* RCTConvert+AirMap.m */; }; DA6C26381C9E2AFE0035349F /* AIRMapUrlTile.m in Sources */ = {isa = PBXBuildFile; fileRef = DA6C26371C9E2AFE0035349F /* AIRMapUrlTile.m */; }; DA6C263E1C9E324A0035349F /* AIRMapUrlTileManager.m in Sources */ = {isa = PBXBuildFile; fileRef = DA6C263D1C9E324A0035349F /* AIRMapUrlTileManager.m */; }; /* End PBXBuildFile section */ @@ -68,8 +68,8 @@ 1125B2F01C4AD445007D0023 /* SMCalloutView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SMCalloutView.h; path = AirMaps/Callout/SMCalloutView.h; sourceTree = SOURCE_ROOT; }; 1125B2F11C4AD445007D0023 /* SMCalloutView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = SMCalloutView.m; path = AirMaps/Callout/SMCalloutView.m; sourceTree = SOURCE_ROOT; }; 11FA5C511C4A1296003AC2EE /* libAirMaps.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libAirMaps.a; sourceTree = BUILT_PRODUCTS_DIR; }; - 19DABC7D1E7C9D3C00F41150 /* RCTConvert+MapKit.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "RCTConvert+MapKit.h"; sourceTree = ""; }; - 19DABC7E1E7C9D3C00F41150 /* RCTConvert+MapKit.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "RCTConvert+MapKit.m"; sourceTree = ""; }; + 19DABC7D1E7C9D3C00F41150 /* RCTConvert+AirMap.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "RCTConvert+AirMap.h"; sourceTree = ""; }; + 19DABC7E1E7C9D3C00F41150 /* RCTConvert+AirMap.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "RCTConvert+AirMap.m"; sourceTree = ""; }; DA6C26361C9E2AFE0035349F /* AIRMapUrlTile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AIRMapUrlTile.h; sourceTree = ""; }; DA6C26371C9E2AFE0035349F /* AIRMapUrlTile.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AIRMapUrlTile.m; sourceTree = ""; }; DA6C263C1C9E324A0035349F /* AIRMapUrlTileManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AIRMapUrlTileManager.h; sourceTree = ""; }; @@ -134,8 +134,8 @@ 1125B2D61C4AD3DA007D0023 /* AIRMapPolylineManager.m */, 1125B2F01C4AD445007D0023 /* SMCalloutView.h */, 1125B2F11C4AD445007D0023 /* SMCalloutView.m */, - 19DABC7D1E7C9D3C00F41150 /* RCTConvert+MapKit.h */, - 19DABC7E1E7C9D3C00F41150 /* RCTConvert+MapKit.m */, + 19DABC7D1E7C9D3C00F41150 /* RCTConvert+AirMap.h */, + 19DABC7E1E7C9D3C00F41150 /* RCTConvert+AirMap.m */, DA6C26361C9E2AFE0035349F /* AIRMapUrlTile.h */, DA6C26371C9E2AFE0035349F /* AIRMapUrlTile.m */, DA6C263C1C9E324A0035349F /* AIRMapUrlTileManager.h */, @@ -206,7 +206,7 @@ 1125B2E01C4AD3DA007D0023 /* AIRMapManager.m in Sources */, 1125B2E61C4AD3DA007D0023 /* AIRMapPolylineManager.m in Sources */, 1125B2DD1C4AD3DA007D0023 /* AIRMapCircle.m in Sources */, - 19DABC7F1E7C9D3C00F41150 /* RCTConvert+MapKit.m in Sources */, + 19DABC7F1E7C9D3C00F41150 /* RCTConvert+AirMap.m in Sources */, 1125B2E51C4AD3DA007D0023 /* AIRMapPolyline.m in Sources */, DA6C263E1C9E324A0035349F /* AIRMapUrlTileManager.m in Sources */, 1125B2DA1C4AD3DA007D0023 /* AIRMap.m in Sources */, From fe906e51511fb70d6087411f4af25f7754c1d160 Mon Sep 17 00:00:00 2001 From: Samuel ROZE Date: Thu, 4 May 2017 15:24:47 -0400 Subject: [PATCH 091/199] Add the `lib` folder in the docs (#1293) --- docs/installation.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/installation.md b/docs/installation.md index d3b6c331c..c2e1dc488 100644 --- a/docs/installation.md +++ b/docs/installation.md @@ -25,9 +25,9 @@ react-native link react-native-maps (If you do not need `GoogleMaps` support for iOS, then you can probably completely skip this step.) 1. Open your project in Xcode workspace 1. If you need `GoogleMaps` support also - - Drag this folder `node_modules/react-native-maps/ios/AirGoogleMaps/` into your project, and choose `Create groups` in the popup window. + - Drag this folder `node_modules/react-native-maps/lib/ios/AirGoogleMaps/` into your project, and choose `Create groups` in the popup window. - In `AppDelegate.m`, add `@import GoogleMaps;` before `@implementation AppDelegate`. In `- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions`, add `[GMSServices provideAPIKey:@"YOUR_GOOGLE_MAP_API_KEY"];` - - In your project's `Build Settings` > `Header Search Paths`, double click the value field. In the popup, add `$(SRCROOT)/../node_modules/react-native-maps/ios/AirMaps` and change `non-recursive` to `recursive`. (Dragging the folder `node_modules/react-native-maps/ios/AirMaps/` into your project introduces duplicate symbols. We should not do it.) + - In your project's `Build Settings` > `Header Search Paths`, double click the value field. In the popup, add `$(SRCROOT)/../node_modules/react-native-maps/lib/ios/AirMaps` and change `non-recursive` to `recursive`. (Dragging the folder `node_modules/react-native-maps/lib/ios/AirMaps/` into your project introduces duplicate symbols. We should not do it.) Note: We recommend using a version of React Native >= .40. Newer versions (>= .40) require `package.json` to be set to `"react-native-maps": "^0.13.0"`, while older versions require `"react-native-maps": "^0.12.4"`. From 78a38cd67aef57b8da8e9a63848be87a5cfa6bb1 Mon Sep 17 00:00:00 2001 From: Todd Williams Date: Thu, 4 May 2017 12:25:56 -0700 Subject: [PATCH 092/199] Update path in android installation (#1249) I was having trouble compiling the android version but updating the project directory resolved it for me. --- docs/installation.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/installation.md b/docs/installation.md index c2e1dc488..31c69cf43 100644 --- a/docs/installation.md +++ b/docs/installation.md @@ -98,7 +98,7 @@ After your `Podfile` is setup properly, run `pod install`. ```groovy ... include ':react-native-maps' - project(':react-native-maps').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-maps/android') + project(':react-native-maps').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-maps/lib/android') ``` 1. Specify your Google Maps API Key: From 1478c04b228c3381b82c6e9738962c6ef872dc22 Mon Sep 17 00:00:00 2001 From: Sam Corcos Date: Thu, 4 May 2017 12:27:23 -0700 Subject: [PATCH 093/199] Update docs to specify how to access event data (#1178) resolves #1136 --- docs/mapview.md | 8 +++++--- docs/marker.md | 2 ++ 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/docs/mapview.md b/docs/mapview.md index 8e73a0773..3df5640c3 100644 --- a/docs/mapview.md +++ b/docs/mapview.md @@ -9,7 +9,7 @@ | `initialRegion` | `Region` | | The initial region to be displayed by the map. Use this prop instead of `region` only if you don't want to control the viewport of the map besides the initial region.

Changing this prop after the component has mounted will not result in a region change.

This is similar to the `initialValue` prop of a text input. | `liteMode` | `Boolean` | `false` | Enable lite mode. **Note**: Android only. | `mapType` | `String` | `"standard"` | The map type to be displayed.

- standard: standard road map (default)
- satellite: satellite view
- hybrid: satellite view with roads and points of interest overlayed
- terrain: (Android only) topographic view -| `customMapStyle` | `Array` | | Adds custom styling to the map component. See [README](https://github.com/airbnb/react-native-maps#customizing-the-map-style) for more information. +| `customMapStyle` | `Array` | | Adds custom styling to the map component. See [README](https://github.com/airbnb/react-native-maps#customizing-the-map-style) for more information. | `showsUserLocation` | `Boolean` | `false` | If `true` the app will ask for the user's location. **NOTE**: You need to add `NSLocationWhenInUseUsageDescription` key in Info.plist to enable geolocation, otherwise it is going to *fail silently*! | `userLocationAnnotationTitle` | `String` | | The title of the annotation for current user location. This only works if `showsUserLocation` is true. There is a default value `My Location` set by MapView. **Note**: iOS only. | `followsUserLocation` | `Boolean` | `false` | If `true` the map will focus on the user's location. This only works if `showsUserLocation` is true and the user has shared their location. **Note**: iOS only. @@ -36,6 +36,8 @@ ## Events +To access event data, you will need to use `e.nativeEvent`. For example, `onPress={e => console.log(e.nativeEvent)}` will log the entire event object to your console. + | Event Name | Returns | Notes |---|---|---| | `onRegionChange` | `Region` | Callback that is called continuously when the region changes, such as when a user is dragging the map. @@ -59,9 +61,9 @@ |---|---|---| | `animateToRegion` | `region: Region`, `duration: Number` | | `animateToCoordinate` | `coordinate: LatLng`, `duration: Number` | -| `fitToElements` | `animated: Boolean` | +| `fitToElements` | `animated: Boolean` | | `fitToSuppliedMarkers` | `markerIDs: String[]`, `animated: Boolean` | If you need to use this in `ComponentDidMount`, make sure you put it in a timeout or it will cause performance problems. -| `fitToCoordinates` | `coordinates: Array, options: { edgePadding: EdgePadding, animated: Boolean }` | If called in `ComponentDidMount` in android, it will cause an exception. It is recommended to call it from the MapView `onLayout` event. +| `fitToCoordinates` | `coordinates: Array, options: { edgePadding: EdgePadding, animated: Boolean }` | If called in `ComponentDidMount` in android, it will cause an exception. It is recommended to call it from the MapView `onLayout` event. diff --git a/docs/marker.md b/docs/marker.md index 4246befc3..16ad49f40 100644 --- a/docs/marker.md +++ b/docs/marker.md @@ -20,6 +20,8 @@ ## Events +To access event data, you will need to use `e.nativeEvent`. For example, `onPress={e => console.log(e.nativeEvent)}` will log the entire event object to your console. + | Event Name | Returns | Notes |---|---|---| | `onPress` | `{ coordinate: LatLng, position: Point }` | Callback that is called when the user presses on the marker From e4a657e568f8beb15cfd715aa49795e24df7c627 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Pomyka=C5=82a?= Date: Thu, 4 May 2017 21:27:56 +0200 Subject: [PATCH 094/199] Update installation.md (#1179) --- docs/installation.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/installation.md b/docs/installation.md index 31c69cf43..4edb9bfb1 100644 --- a/docs/installation.md +++ b/docs/installation.md @@ -203,7 +203,7 @@ Enter the name of the API key and create it. 1. Clean the cache : ``` watchman watch-del-all - npm cache clean + npm clean cache ``` 1. When starting emulator, make sure you have enabled `Wipe user data`. From 36a36917e4897c934b5bfe9cbaf1a63f87637e8e Mon Sep 17 00:00:00 2001 From: Yang Li Date: Fri, 5 May 2017 03:29:06 +0800 Subject: [PATCH 095/199] Add babelrc to npmignore (#1246) --- .npmignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.npmignore b/.npmignore index 33a9488b1..4ce7bc58b 100644 --- a/.npmignore +++ b/.npmignore @@ -1 +1,2 @@ example +.babelrc From 0eb1933e665348a315fbe2756ae962f112d96e75 Mon Sep 17 00:00:00 2001 From: Nathan Broadbent Date: Fri, 5 May 2017 02:29:36 +0700 Subject: [PATCH 096/199] Fixed path in `android/settings.gradle` (#1230) From 8f6d866c7b0dbd1b1373b2d821c4149373806677 Mon Sep 17 00:00:00 2001 From: Aaron Leonard Date: Thu, 4 May 2017 12:29:51 -0700 Subject: [PATCH 097/199] Update installation.md (#1226) Update the paths to the `android` and `ios` folders to match the new structure --- docs/installation.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/installation.md b/docs/installation.md index 4edb9bfb1..49cf6d447 100644 --- a/docs/installation.md +++ b/docs/installation.md @@ -52,7 +52,7 @@ After your `Podfile` is setup properly, run `pod install`. >This was already done for you if you ran "react-native link" 1. Open your project in Xcode, right click on `Libraries` and click `Add - Files to "Your Project Name"` Look under `node_modules/react-native-maps/ios` and add `AIRMaps.xcodeproj`. + Files to "Your Project Name"` Look under `node_modules/react-native-maps/lib/ios` and add `AIRMaps.xcodeproj`. 1. Add `libAIRMaps.a` to `Build Phases -> Link Binary With Libraries. 1. Click on `AIRMaps.xcodeproj` in `Libraries` and go the `Build Settings` tab. Double click the text to the right of `Header Search From 88a732fc518fcc0a5a58d03fff56de9761bc04a1 Mon Sep 17 00:00:00 2001 From: Golam Rabbani Date: Fri, 5 May 2017 01:31:29 +0600 Subject: [PATCH 098/199] small typo fixed (#1211) --- docs/installation.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/installation.md b/docs/installation.md index 49cf6d447..27614b6ff 100644 --- a/docs/installation.md +++ b/docs/installation.md @@ -213,7 +213,7 @@ Enter the name of the API key and create it. 1. If you encounter `com.android.dex.DexException: Multiple dex files define Landroid/support/v7/appcompat/R$anim`, then clear build folder. ``` cd android - gradlew clean + ./gradlew clean cd .. ``` From 1bbdcb7a2c10d55b0fc0944038fa18840b93c107 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adrian=20Caba=C5=82a?= Date: Thu, 4 May 2017 21:40:22 +0200 Subject: [PATCH 099/199] fixing code snippet (#1196) the path to project dir is no longer up-to-date From 0dcdebdfe20c292bcf6d66401afda1d559ee6f09 Mon Sep 17 00:00:00 2001 From: Felipe Lima Date: Mon, 8 May 2017 11:27:07 -0700 Subject: [PATCH 100/199] v0.15.0 (#1305) * Prepare for v0.15 release * Add changelog * Fix link to PR --- CHANGELOG.md | 5 +++++ build.gradle | 2 +- gradle/wrapper/gradle-wrapper.properties | 4 ++-- lib/android/build.gradle | 4 ++-- lib/android/gradle.properties | 2 +- package.json | 2 +- 6 files changed, 12 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5c13e5ba0..0af766a02 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,10 @@ # Change Log +## 0.15.0 (May 8, 2017) + +* iOS: [#1195]((https://github.com/airbnb/react-native-maps/pull/1195) Rename project file to fix iOS build error +* Android: Update Google Play Services to version `10.2.4` + ## 0.14.0 (April 4, 2017) ## Enhancements diff --git a/build.gradle b/build.gradle index f89d2c594..8a3e2453e 100644 --- a/build.gradle +++ b/build.gradle @@ -5,7 +5,7 @@ buildscript { jcenter() } dependencies { - classpath 'com.android.tools.build:gradle:2.3.0' + classpath 'com.android.tools.build:gradle:2.3.1' } } diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 3b6c26cf7..c21e471fc 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ -#Thu Mar 02 17:03:11 PST 2017 +#Mon May 08 11:03:28 PDT 2017 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-3.3-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-3.5-all.zip diff --git a/lib/android/build.gradle b/lib/android/build.gradle index 85cb5b4d2..434e63e72 100644 --- a/lib/android/build.gradle +++ b/lib/android/build.gradle @@ -35,6 +35,6 @@ android { dependencies { provided "com.facebook.react:react-native:+" - compile "com.google.android.gms:play-services-base:10.2.0" - compile "com.google.android.gms:play-services-maps:10.2.0" + compile "com.google.android.gms:play-services-base:10.2.4" + compile "com.google.android.gms:play-services-maps:10.2.4" } diff --git a/lib/android/gradle.properties b/lib/android/gradle.properties index 9a87aa52e..2d7a31b06 100644 --- a/lib/android/gradle.properties +++ b/lib/android/gradle.properties @@ -1,5 +1,5 @@ VERSION_CODE=4 -VERSION_NAME=0.14.0 +VERSION_NAME=0.15.0 GROUP=com.airbnb.android POM_DESCRIPTION=React Native Map view component for Android diff --git a/package.json b/package.json index 9bbc2e1dd..de8063b3b 100644 --- a/package.json +++ b/package.json @@ -3,7 +3,7 @@ "description": "React Native Mapview component for iOS + Android", "main": "index.js", "author": "Leland Richardson ", - "version": "0.14.0", + "version": "0.15.0", "scripts": { "start": "node node_modules/react-native/local-cli/cli.js start", "run:packager": "./node_modules/react-native/packager/packager.sh", From 7bba6f939f425865cf917fc3b65fdf63533dcbd1 Mon Sep 17 00:00:00 2001 From: frmdstryr Date: Thu, 11 May 2017 12:45:49 -0400 Subject: [PATCH 101/199] Fix overlay issues in Android introduced in 0.13.1 (#1311) * Update AirMapView.java * Update AirMapManager.java * Update AirMapView.java --- .../airbnb/android/react/maps/AirMapManager.java | 2 +- .../com/airbnb/android/react/maps/AirMapView.java | 15 +++++++++------ 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapManager.java b/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapManager.java index 3ac1f4de7..b6a975b77 100644 --- a/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapManager.java +++ b/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapManager.java @@ -59,7 +59,7 @@ public String getName() { @Override protected AirMapView createViewInstance(ThemedReactContext context) { - return new AirMapView(context, this, googleMapOptions); + return new AirMapView(context, this.appContext, this, googleMapOptions); } private void emitMapError(ThemedReactContext context, String message, String type) { diff --git a/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapView.java b/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapView.java index 772627e4a..3225bf1ff 100644 --- a/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapView.java +++ b/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapView.java @@ -22,6 +22,7 @@ import android.widget.RelativeLayout; import com.facebook.react.bridge.LifecycleEventListener; +import com.facebook.react.bridge.ReactApplicationContext; import com.facebook.react.bridge.ReadableArray; import com.facebook.react.bridge.ReadableMap; import com.facebook.react.bridge.WritableMap; @@ -100,10 +101,12 @@ private static boolean contextHasBug(Context context) { // https://github.com/airbnb/react-native-maps/issues/1147 // // Doing this allows us to avoid both bugs. - private static Context getNonBuggyContext(ThemedReactContext reactContext) { + private static Context getNonBuggyContext(ThemedReactContext reactContext, + ReactApplicationContext appContext) { Context superContext = reactContext; - - if (contextHasBug(superContext)) { + if (!contextHasBug(appContext.getCurrentActivity())) { + superContext = appContext.getCurrentActivity(); + } else if (contextHasBug(superContext)) { // we have the bug! let's try to find a better context to use if (!contextHasBug(reactContext.getCurrentActivity())) { superContext = reactContext.getCurrentActivity(); @@ -116,9 +119,9 @@ private static Context getNonBuggyContext(ThemedReactContext reactContext) { return superContext; } - public AirMapView(ThemedReactContext reactContext, AirMapManager manager, - GoogleMapOptions googleMapOptions) { - super(getNonBuggyContext(reactContext), googleMapOptions); + public AirMapView(ThemedReactContext reactContext, ReactApplicationContext appContext, AirMapManager manager, + GoogleMapOptions googleMapOptions) { + super(getNonBuggyContext(reactContext, appContext), googleMapOptions); this.manager = manager; this.context = reactContext; From 65d27913bbae2570c7e7b3dc28a55c8bfdd09d99 Mon Sep 17 00:00:00 2001 From: Ulydev Date: Thu, 11 May 2017 18:47:03 +0200 Subject: [PATCH 102/199] Update license date (#1316) --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 41139a4a0..13d793926 100644 --- a/README.md +++ b/README.md @@ -494,7 +494,7 @@ Good: License -------- - Copyright (c) 2015 Airbnb + Copyright (c) 2017 Airbnb Licensed under the The MIT License (MIT) (the "License"); you may not use this file except in compliance with the License. From ca7eee1b59182ea02fd0f92b1cbbdc9bff7b9b8c Mon Sep 17 00:00:00 2001 From: Christopher Dro Date: Thu, 11 May 2017 09:48:21 -0700 Subject: [PATCH 103/199] [rnpm] Fix sourceDir for Android (#1313) Overlooked this change closing out a few PR's last week. Follow up for #1200 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index de8063b3b..766c2a967 100644 --- a/package.json +++ b/package.json @@ -53,7 +53,7 @@ }, "rnpm": { "android": { - "sourceDir": "./android" + "sourceDir": "./lib/android" } } } From 535f599c5d823f5f6cfe9d1c78f147371156dcce Mon Sep 17 00:00:00 2001 From: Guilherme Pontes Date: Fri, 19 May 2017 18:45:48 +0200 Subject: [PATCH 104/199] [iOS] Added onPress support for Polyline on Google Maps (#1194) --- example/examples/EventListener.js | 1 + lib/components/MapPolyline.js | 5 +++++ lib/ios/AirGoogleMaps/AIRGMSPolyline.h | 16 ++++++++++++++++ lib/ios/AirGoogleMaps/AIRGMSPolyline.m | 11 +++++++++++ lib/ios/AirGoogleMaps/AIRGoogleMap.h | 1 + lib/ios/AirGoogleMaps/AIRGoogleMap.m | 10 ++++++++++ lib/ios/AirGoogleMaps/AIRGoogleMapPolyline.h | 9 ++++++++- lib/ios/AirGoogleMaps/AIRGoogleMapPolyline.m | 17 ++++++++++++++--- .../AirGoogleMaps/AIRGoogleMapPolylineManager.m | 3 +++ lib/ios/AirMaps.xcodeproj/project.pbxproj | 6 ++++++ 10 files changed, 75 insertions(+), 4 deletions(-) create mode 100644 lib/ios/AirGoogleMaps/AIRGMSPolyline.h create mode 100644 lib/ios/AirGoogleMaps/AIRGMSPolyline.m diff --git a/example/examples/EventListener.js b/example/examples/EventListener.js index 005894a0d..c8d3e937f 100644 --- a/example/examples/EventListener.js +++ b/example/examples/EventListener.js @@ -145,6 +145,7 @@ class EventListener extends React.Component { +#import "UIView+React.h" + +@class AIRGoogleMapPolyline; + +@interface AIRGMSPolyline : GMSPolyline +@property (nonatomic, strong) NSString *identifier; +@property (nonatomic, copy) RCTBubblingEventBlock onPress; +@end diff --git a/lib/ios/AirGoogleMaps/AIRGMSPolyline.m b/lib/ios/AirGoogleMaps/AIRGMSPolyline.m new file mode 100644 index 000000000..86e7ac055 --- /dev/null +++ b/lib/ios/AirGoogleMaps/AIRGMSPolyline.m @@ -0,0 +1,11 @@ +// +// AIRGMSPolyline.m +// AirMaps +// +// Created by Guilherme Pontes 04/05/2017. +// + +#import "AIRGMSPolyline.h" + +@implementation AIRGMSPolyline +@end diff --git a/lib/ios/AirGoogleMaps/AIRGoogleMap.h b/lib/ios/AirGoogleMaps/AIRGoogleMap.h index 9e6ae8b79..0e9554eb6 100644 --- a/lib/ios/AirGoogleMaps/AIRGoogleMap.h +++ b/lib/ios/AirGoogleMaps/AIRGoogleMap.h @@ -41,6 +41,7 @@ @property (nonatomic, assign) BOOL showsMyLocationButton; - (BOOL)didTapMarker:(GMSMarker *)marker; +- (void)didTapPolyline:(GMSPolyline *)polyline; - (void)didTapPolygon:(GMSPolygon *)polygon; - (void)didTapAtCoordinate:(CLLocationCoordinate2D)coordinate; - (void)didLongPressAtCoordinate:(CLLocationCoordinate2D)coordinate; diff --git a/lib/ios/AirGoogleMaps/AIRGoogleMap.m b/lib/ios/AirGoogleMaps/AIRGoogleMap.m index ca15da04e..ef73067b6 100644 --- a/lib/ios/AirGoogleMaps/AIRGoogleMap.m +++ b/lib/ios/AirGoogleMaps/AIRGoogleMap.m @@ -170,6 +170,16 @@ - (BOOL)didTapMarker:(GMSMarker *)marker { return NO; } +- (void)didTapPolyline:(GMSOverlay *)polyline { + AIRGMSPolyline *airPolyline = (AIRGMSPolyline *)polyline; + + id event = @{@"action": @"polyline-press", + @"id": airPolyline.identifier ?: @"unknown", + }; + + if (airPolyline.onPress) airPolyline.onPress(event); +} + - (void)didTapPolygon:(GMSOverlay *)polygon { AIRGMSPolygon *airPolygon = (AIRGMSPolygon *)polygon; diff --git a/lib/ios/AirGoogleMaps/AIRGoogleMapPolyline.h b/lib/ios/AirGoogleMaps/AIRGoogleMapPolyline.h index b127567a5..adebc40d6 100644 --- a/lib/ios/AirGoogleMaps/AIRGoogleMapPolyline.h +++ b/lib/ios/AirGoogleMaps/AIRGoogleMapPolyline.h @@ -5,18 +5,25 @@ // #import #import +#import +#import "AIRGMSPolyline.h" #import "AIRMapCoordinate.h" #import "AIRGoogleMapMarker.h" @interface AIRGoogleMapPolyline : UIView -@property (nonatomic, strong) GMSPolyline* polyline; +@property (nonatomic, weak) RCTBridge *bridge; +@property (nonatomic, strong) NSString *identifier; +@property (nonatomic, strong) AIRGMSPolyline *polyline; @property (nonatomic, strong) NSArray *coordinates; +@property (nonatomic, copy) RCTBubblingEventBlock onPress; + @property (nonatomic, strong) UIColor *strokeColor; @property (nonatomic, assign) double strokeWidth; @property (nonatomic, assign) UIColor *fillColor; @property (nonatomic, assign) BOOL geodesic; @property (nonatomic, assign) NSString *title; @property (nonatomic, assign) int zIndex; +@property (nonatomic, assign) BOOL tappable; @end diff --git a/lib/ios/AirGoogleMaps/AIRGoogleMapPolyline.m b/lib/ios/AirGoogleMaps/AIRGoogleMapPolyline.m index 009d90bfb..881f17be6 100644 --- a/lib/ios/AirGoogleMaps/AIRGoogleMapPolyline.m +++ b/lib/ios/AirGoogleMaps/AIRGoogleMapPolyline.m @@ -5,6 +5,7 @@ // #import #import "AIRGoogleMapPolyline.h" +#import "AIRGMSPolyline.h" #import "AIRMapCoordinate.h" #import "AIRGoogleMapMarker.h" #import "AIRGoogleMapMarkerManager.h" @@ -16,7 +17,7 @@ @implementation AIRGoogleMapPolyline - (instancetype)init { if (self = [super init]) { - _polyline = [[GMSPolyline alloc] init]; + _polyline = [[AIRGMSPolyline alloc] init]; } return self; } @@ -24,13 +25,13 @@ - (instancetype)init -(void)setCoordinates:(NSArray *)coordinates { _coordinates = coordinates; - + GMSMutablePath *path = [GMSMutablePath path]; for(int i = 0; i < coordinates.count; i++) { [path addCoordinate:coordinates[i].coordinate]; } - + _polyline.path = path; } @@ -70,4 +71,14 @@ -(void) setZIndex:(int)zIndex _polyline.zIndex = zIndex; } +-(void)setTappable:(BOOL)tappable +{ + _tappable = tappable; + _polyline.tappable = tappable; +} + +- (void)setOnPress:(RCTBubblingEventBlock)onPress { + _polyline.onPress = onPress; +} + @end diff --git a/lib/ios/AirGoogleMaps/AIRGoogleMapPolylineManager.m b/lib/ios/AirGoogleMaps/AIRGoogleMapPolylineManager.m index acad1631b..a7515c207 100644 --- a/lib/ios/AirGoogleMaps/AIRGoogleMapPolylineManager.m +++ b/lib/ios/AirGoogleMaps/AIRGoogleMapPolylineManager.m @@ -26,6 +26,7 @@ @implementation AIRGoogleMapPolylineManager - (UIView *)view { AIRGoogleMapPolyline *polyline = [AIRGoogleMapPolyline new]; + polyline.bridge = self.bridge; return polyline; } @@ -35,5 +36,7 @@ - (UIView *)view RCT_EXPORT_VIEW_PROPERTY(strokeWidth, double) RCT_EXPORT_VIEW_PROPERTY(geodesic, BOOL) RCT_EXPORT_VIEW_PROPERTY(zIndex, int) +RCT_EXPORT_VIEW_PROPERTY(tappable, BOOL) +RCT_EXPORT_VIEW_PROPERTY(onPress, RCTBubblingEventBlock) @end diff --git a/lib/ios/AirMaps.xcodeproj/project.pbxproj b/lib/ios/AirMaps.xcodeproj/project.pbxproj index ac641aff7..19a7213ff 100644 --- a/lib/ios/AirMaps.xcodeproj/project.pbxproj +++ b/lib/ios/AirMaps.xcodeproj/project.pbxproj @@ -22,6 +22,7 @@ 1125B2E61C4AD3DA007D0023 /* AIRMapPolylineManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 1125B2D61C4AD3DA007D0023 /* AIRMapPolylineManager.m */; }; 1125B2F21C4AD445007D0023 /* SMCalloutView.m in Sources */ = {isa = PBXBuildFile; fileRef = 1125B2F11C4AD445007D0023 /* SMCalloutView.m */; }; 19DABC7F1E7C9D3C00F41150 /* RCTConvert+AirMap.m in Sources */ = {isa = PBXBuildFile; fileRef = 19DABC7E1E7C9D3C00F41150 /* RCTConvert+AirMap.m */; }; + 9B0F3F7C1E9526A30001804F /* AIRGMSPolyline.m in Sources */ = {isa = PBXBuildFile; fileRef = 9B0F3F7B1E9526A30001804F /* AIRGMSPolyline.m */; }; DA6C26381C9E2AFE0035349F /* AIRMapUrlTile.m in Sources */ = {isa = PBXBuildFile; fileRef = DA6C26371C9E2AFE0035349F /* AIRMapUrlTile.m */; }; DA6C263E1C9E324A0035349F /* AIRMapUrlTileManager.m in Sources */ = {isa = PBXBuildFile; fileRef = DA6C263D1C9E324A0035349F /* AIRMapUrlTileManager.m */; }; /* End PBXBuildFile section */ @@ -70,6 +71,8 @@ 11FA5C511C4A1296003AC2EE /* libAirMaps.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libAirMaps.a; sourceTree = BUILT_PRODUCTS_DIR; }; 19DABC7D1E7C9D3C00F41150 /* RCTConvert+AirMap.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "RCTConvert+AirMap.h"; sourceTree = ""; }; 19DABC7E1E7C9D3C00F41150 /* RCTConvert+AirMap.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "RCTConvert+AirMap.m"; sourceTree = ""; }; + 9B0F3F7A1E9526460001804F /* AIRGMSPolyline.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AIRGMSPolyline.h; sourceTree = ""; }; + 9B0F3F7B1E9526A30001804F /* AIRGMSPolyline.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AIRGMSPolyline.m; sourceTree = ""; }; DA6C26361C9E2AFE0035349F /* AIRMapUrlTile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AIRMapUrlTile.h; sourceTree = ""; }; DA6C26371C9E2AFE0035349F /* AIRMapUrlTile.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AIRMapUrlTile.m; sourceTree = ""; }; DA6C263C1C9E324A0035349F /* AIRMapUrlTileManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AIRMapUrlTileManager.h; sourceTree = ""; }; @@ -140,6 +143,8 @@ DA6C26371C9E2AFE0035349F /* AIRMapUrlTile.m */, DA6C263C1C9E324A0035349F /* AIRMapUrlTileManager.h */, DA6C263D1C9E324A0035349F /* AIRMapUrlTileManager.m */, + 9B0F3F7A1E9526460001804F /* AIRGMSPolyline.h */, + 9B0F3F7B1E9526A30001804F /* AIRGMSPolyline.m */, ); path = AirMaps; sourceTree = ""; @@ -202,6 +207,7 @@ files = ( 1125B2E31C4AD3DA007D0023 /* AIRMapPolygon.m in Sources */, 1125B2E41C4AD3DA007D0023 /* AIRMapPolygonManager.m in Sources */, + 9B0F3F7C1E9526A30001804F /* AIRGMSPolyline.m in Sources */, 1125B2DB1C4AD3DA007D0023 /* AIRMapCallout.m in Sources */, 1125B2E01C4AD3DA007D0023 /* AIRMapManager.m in Sources */, 1125B2E61C4AD3DA007D0023 /* AIRMapPolylineManager.m in Sources */, From 76fa0b491effabcd861e4dc2f0cc0a7a76a9c6c8 Mon Sep 17 00:00:00 2001 From: Helge Silset Date: Fri, 19 May 2017 18:46:07 +0200 Subject: [PATCH 105/199] Update README: Use callback in `ref` attribute (#1345) `this.refs`/string as ref is deprecated. --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 13d793926..49d65ac72 100644 --- a/README.md +++ b/README.md @@ -405,7 +405,7 @@ getInitialState() { takeSnapshot () { // 'takeSnapshot' takes a config object with the // following options - const snapshot = this.refs.map.takeSnapshot({ + const snapshot = this.map.takeSnapshot({ width: 300, // optional, when omitted the view-width is used height: 300, // optional, when omitted the view-height is used region: {..}, // iOS only, optional region to render @@ -421,7 +421,7 @@ takeSnapshot () { render() { return ( - + { this.map = map }}> From 9676c9cf2ae049bf01a39cc8f4219566858d28e3 Mon Sep 17 00:00:00 2001 From: Taminder Bariana Date: Fri, 19 May 2017 09:47:09 -0700 Subject: [PATCH 106/199] Fixing reference to AirMapsExplorer in installation docs (#1328) --- docs/installation.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/installation.md b/docs/installation.md index 27614b6ff..12842d7c6 100644 --- a/docs/installation.md +++ b/docs/installation.md @@ -21,7 +21,7 @@ react-native link react-native-maps ### Option 1: CocoaPods - Same as the included AirMapsExplorer example -1. Setup your `Podfile` like the included [example/ios/Podfile](../example/ios/Podfile), replace all references to `AirMapExplorer` with your project name, and then run `pod install`. +1. Setup your `Podfile` like the included [example/ios/Podfile](../example/ios/Podfile), replace all references to `AirMapsExplorer` with your project name, and then run `pod install`. (If you do not need `GoogleMaps` support for iOS, then you can probably completely skip this step.) 1. Open your project in Xcode workspace 1. If you need `GoogleMaps` support also From 4ee7277ebf5c90c53c2d7d591f8f484ef2cd6d02 Mon Sep 17 00:00:00 2001 From: Yann Pringault Date: Fri, 19 May 2017 18:47:51 +0200 Subject: [PATCH 107/199] Add Marker rotation for Google Maps on iOS (#1326) --- docs/marker.md | 2 +- lib/ios/AirGoogleMaps/AIRGoogleMapMarker.h | 1 + lib/ios/AirGoogleMaps/AIRGoogleMapMarker.m | 8 ++++++++ lib/ios/AirGoogleMaps/AIRGoogleMapMarkerManager.m | 1 + 4 files changed, 11 insertions(+), 1 deletion(-) diff --git a/docs/marker.md b/docs/marker.md index 16ad49f40..4214e4d6e 100644 --- a/docs/marker.md +++ b/docs/marker.md @@ -15,7 +15,7 @@ | `calloutAnchor` | `Point` | | Specifies the point in the marker image at which to anchor the callout when it is displayed. This is specified in the same coordinate system as the anchor. See the `anchor` prop for more details.

The default is the top middle of the image.

For ios, see the `calloutOffset` prop. | `flat` | `Boolean` | | Sets whether this marker should be flat against the map true or a billboard facing the camera false. | `identifier` | `String` | | An identifier used to reference this marker at a later date. -| `rotation` | `Float` | | A float number indicating marker's rotation angle. +| `rotation` | `Float` | | A float number indicating marker's rotation angle, in degrees. | `draggable` | `` | | This is a non-value based prop. Adding this allows the marker to be draggable (re-positioned). ## Events diff --git a/lib/ios/AirGoogleMaps/AIRGoogleMapMarker.h b/lib/ios/AirGoogleMaps/AIRGoogleMapMarker.h index 36190e7cb..298884f7d 100644 --- a/lib/ios/AirGoogleMaps/AIRGoogleMapMarker.h +++ b/lib/ios/AirGoogleMaps/AIRGoogleMapMarker.h @@ -17,6 +17,7 @@ @property (nonatomic, strong) AIRGoogleMapCallout *calloutView; @property (nonatomic, strong) NSString *identifier; @property (nonatomic, assign) CLLocationCoordinate2D coordinate; +@property (nonatomic, assign) CLLocationDegrees rotation; @property (nonatomic, strong) AIRGMSMarker* realMarker; @property (nonatomic, copy) RCTBubblingEventBlock onPress; @property (nonatomic, copy) RCTDirectEventBlock onDragStart; diff --git a/lib/ios/AirGoogleMaps/AIRGoogleMapMarker.m b/lib/ios/AirGoogleMaps/AIRGoogleMapMarker.m index 2c6080e9e..c41be55bb 100644 --- a/lib/ios/AirGoogleMaps/AIRGoogleMapMarker.m +++ b/lib/ios/AirGoogleMaps/AIRGoogleMapMarker.m @@ -157,6 +157,14 @@ - (CLLocationCoordinate2D)coordinate { return _realMarker.position; } +- (void)setRotation:(CLLocationDegrees)rotation { + _realMarker.rotation = rotation; +} + +- (CLLocationDegrees)rotation { + return _realMarker.rotation; +} + - (void)setIdentifier:(NSString *)identifier { _realMarker.identifier = identifier; } diff --git a/lib/ios/AirGoogleMaps/AIRGoogleMapMarkerManager.m b/lib/ios/AirGoogleMaps/AIRGoogleMapMarkerManager.m index 8be4ba53e..b5572bf9d 100644 --- a/lib/ios/AirGoogleMaps/AIRGoogleMapMarkerManager.m +++ b/lib/ios/AirGoogleMaps/AIRGoogleMapMarkerManager.m @@ -28,6 +28,7 @@ - (UIView *)view RCT_EXPORT_VIEW_PROPERTY(identifier, NSString) RCT_EXPORT_VIEW_PROPERTY(coordinate, CLLocationCoordinate2D) +RCT_EXPORT_VIEW_PROPERTY(rotation, CLLocationDegrees) RCT_EXPORT_VIEW_PROPERTY(onPress, RCTBubblingEventBlock) RCT_REMAP_VIEW_PROPERTY(image, imageSrc, NSString) RCT_EXPORT_VIEW_PROPERTY(title, NSString) From 08127b40b68127c697fbb8491fd3a7225eed38ae Mon Sep 17 00:00:00 2001 From: yosimasu Date: Sat, 20 May 2017 00:48:07 +0800 Subject: [PATCH 108/199] fix compile error in rn version >= 0.40 (#1341) --- lib/ios/AirGoogleMaps/AIRGMSPolygon.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/ios/AirGoogleMaps/AIRGMSPolygon.h b/lib/ios/AirGoogleMaps/AIRGMSPolygon.h index 3466b3691..d41c87d5e 100644 --- a/lib/ios/AirGoogleMaps/AIRGMSPolygon.h +++ b/lib/ios/AirGoogleMaps/AIRGMSPolygon.h @@ -6,7 +6,7 @@ // #import -#import "UIView+React.h" +#import @class AIRGoogleMapPolygon; From 0aac50daa0bddecd5e932a324228191d9d02c3e6 Mon Sep 17 00:00:00 2001 From: Christopher Dro Date: Fri, 19 May 2017 13:39:21 -0700 Subject: [PATCH 109/199] v0.15.1 (#1347) --- CHANGELOG.md | 10 +++++++++- lib/android/gradle.properties | 2 +- package.json | 2 +- 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0af766a02..109ce6357 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,8 +1,16 @@ # Change Log +## 0.15.1 (May 19, 2017) + +* iOS: [#1341](https://github.com/airbnb/react-native-maps/pull/1341) Fix compile error in rn version >= 0.40 +* iOS: [#1194](https://github.com/airbnb/react-native-maps/pull/1194) Add onPress support for Google Maps Polyline +* iOS: [#1326](https://github.com/airbnb/react-native-maps/pull/1326) Add Marker rotation for Google Maps on iOS +* Android: [#1311](https://github.com/airbnb/react-native-maps/pull/1311) Fix overlay issue +* Common [#1313](https://github.com/airbnb/react-native-maps/pull/1313) Fix Android sourceDir for react-native-link + ## 0.15.0 (May 8, 2017) -* iOS: [#1195]((https://github.com/airbnb/react-native-maps/pull/1195) Rename project file to fix iOS build error +* iOS: [#1195](https://github.com/airbnb/react-native-maps/pull/1195) Rename project file to fix iOS build error * Android: Update Google Play Services to version `10.2.4` ## 0.14.0 (April 4, 2017) diff --git a/lib/android/gradle.properties b/lib/android/gradle.properties index 2d7a31b06..ee320ef1f 100644 --- a/lib/android/gradle.properties +++ b/lib/android/gradle.properties @@ -1,5 +1,5 @@ VERSION_CODE=4 -VERSION_NAME=0.15.0 +VERSION_NAME=0.15.1 GROUP=com.airbnb.android POM_DESCRIPTION=React Native Map view component for Android diff --git a/package.json b/package.json index 766c2a967..a188fad59 100644 --- a/package.json +++ b/package.json @@ -3,7 +3,7 @@ "description": "React Native Mapview component for iOS + Android", "main": "index.js", "author": "Leland Richardson ", - "version": "0.15.0", + "version": "0.15.1", "scripts": { "start": "node node_modules/react-native/local-cli/cli.js start", "run:packager": "./node_modules/react-native/packager/packager.sh", From 8b94984e5192c8083134e434e9740c204b62fcb2 Mon Sep 17 00:00:00 2001 From: Anton Petrov Date: Sat, 20 May 2017 18:46:32 +0300 Subject: [PATCH 110/199] Remove AIRGMSPolyline.h and AIRGMSPolyline.m references from AirMaps.xcodeproj (#1351) --- lib/ios/AirMaps.xcodeproj/project.pbxproj | 6 ------ 1 file changed, 6 deletions(-) diff --git a/lib/ios/AirMaps.xcodeproj/project.pbxproj b/lib/ios/AirMaps.xcodeproj/project.pbxproj index 19a7213ff..ac641aff7 100644 --- a/lib/ios/AirMaps.xcodeproj/project.pbxproj +++ b/lib/ios/AirMaps.xcodeproj/project.pbxproj @@ -22,7 +22,6 @@ 1125B2E61C4AD3DA007D0023 /* AIRMapPolylineManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 1125B2D61C4AD3DA007D0023 /* AIRMapPolylineManager.m */; }; 1125B2F21C4AD445007D0023 /* SMCalloutView.m in Sources */ = {isa = PBXBuildFile; fileRef = 1125B2F11C4AD445007D0023 /* SMCalloutView.m */; }; 19DABC7F1E7C9D3C00F41150 /* RCTConvert+AirMap.m in Sources */ = {isa = PBXBuildFile; fileRef = 19DABC7E1E7C9D3C00F41150 /* RCTConvert+AirMap.m */; }; - 9B0F3F7C1E9526A30001804F /* AIRGMSPolyline.m in Sources */ = {isa = PBXBuildFile; fileRef = 9B0F3F7B1E9526A30001804F /* AIRGMSPolyline.m */; }; DA6C26381C9E2AFE0035349F /* AIRMapUrlTile.m in Sources */ = {isa = PBXBuildFile; fileRef = DA6C26371C9E2AFE0035349F /* AIRMapUrlTile.m */; }; DA6C263E1C9E324A0035349F /* AIRMapUrlTileManager.m in Sources */ = {isa = PBXBuildFile; fileRef = DA6C263D1C9E324A0035349F /* AIRMapUrlTileManager.m */; }; /* End PBXBuildFile section */ @@ -71,8 +70,6 @@ 11FA5C511C4A1296003AC2EE /* libAirMaps.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libAirMaps.a; sourceTree = BUILT_PRODUCTS_DIR; }; 19DABC7D1E7C9D3C00F41150 /* RCTConvert+AirMap.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "RCTConvert+AirMap.h"; sourceTree = ""; }; 19DABC7E1E7C9D3C00F41150 /* RCTConvert+AirMap.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "RCTConvert+AirMap.m"; sourceTree = ""; }; - 9B0F3F7A1E9526460001804F /* AIRGMSPolyline.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AIRGMSPolyline.h; sourceTree = ""; }; - 9B0F3F7B1E9526A30001804F /* AIRGMSPolyline.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AIRGMSPolyline.m; sourceTree = ""; }; DA6C26361C9E2AFE0035349F /* AIRMapUrlTile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AIRMapUrlTile.h; sourceTree = ""; }; DA6C26371C9E2AFE0035349F /* AIRMapUrlTile.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AIRMapUrlTile.m; sourceTree = ""; }; DA6C263C1C9E324A0035349F /* AIRMapUrlTileManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AIRMapUrlTileManager.h; sourceTree = ""; }; @@ -143,8 +140,6 @@ DA6C26371C9E2AFE0035349F /* AIRMapUrlTile.m */, DA6C263C1C9E324A0035349F /* AIRMapUrlTileManager.h */, DA6C263D1C9E324A0035349F /* AIRMapUrlTileManager.m */, - 9B0F3F7A1E9526460001804F /* AIRGMSPolyline.h */, - 9B0F3F7B1E9526A30001804F /* AIRGMSPolyline.m */, ); path = AirMaps; sourceTree = ""; @@ -207,7 +202,6 @@ files = ( 1125B2E31C4AD3DA007D0023 /* AIRMapPolygon.m in Sources */, 1125B2E41C4AD3DA007D0023 /* AIRMapPolygonManager.m in Sources */, - 9B0F3F7C1E9526A30001804F /* AIRGMSPolyline.m in Sources */, 1125B2DB1C4AD3DA007D0023 /* AIRMapCallout.m in Sources */, 1125B2E01C4AD3DA007D0023 /* AIRMapManager.m in Sources */, 1125B2E61C4AD3DA007D0023 /* AIRMapPolylineManager.m in Sources */, From 8893578ca6197d0c0a3cacf5aea9c78bfb0a4b99 Mon Sep 17 00:00:00 2001 From: Christopher Dro Date: Sat, 20 May 2017 09:13:35 -0700 Subject: [PATCH 111/199] v0.15.2 (#1352) --- CHANGELOG.md | 4 ++++ lib/android/gradle.properties | 2 +- package.json | 2 +- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 109ce6357..5968b7e7b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Change Log +## 0.15.2 (May 20, 2017) + +* iOS: [#1351](https://github.com/airbnb/react-native-maps/pull/1351) Fix file references + ## 0.15.1 (May 19, 2017) * iOS: [#1341](https://github.com/airbnb/react-native-maps/pull/1341) Fix compile error in rn version >= 0.40 diff --git a/lib/android/gradle.properties b/lib/android/gradle.properties index ee320ef1f..65c67798d 100644 --- a/lib/android/gradle.properties +++ b/lib/android/gradle.properties @@ -1,5 +1,5 @@ VERSION_CODE=4 -VERSION_NAME=0.15.1 +VERSION_NAME=0.15.2 GROUP=com.airbnb.android POM_DESCRIPTION=React Native Map view component for Android diff --git a/package.json b/package.json index a188fad59..30ffc43e8 100644 --- a/package.json +++ b/package.json @@ -3,7 +3,7 @@ "description": "React Native Mapview component for iOS + Android", "main": "index.js", "author": "Leland Richardson ", - "version": "0.15.1", + "version": "0.15.2", "scripts": { "start": "node node_modules/react-native/local-cli/cli.js start", "run:packager": "./node_modules/react-native/packager/packager.sh", From fa2b6c274b6432a13e20018a3591e092f9cac411 Mon Sep 17 00:00:00 2001 From: Ryan Guest Date: Thu, 1 Jun 2017 07:32:50 -0700 Subject: [PATCH 112/199] Fix a couple typos (#1375) --- README.md | 2 +- .../main/java/com/airbnb/android/react/maps/AirMapModule.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 49d65ac72..91b22377b 100644 --- a/README.md +++ b/README.md @@ -207,7 +207,7 @@ Then add the AirGoogleMaps directory: https://github.com/airbnb/react-native-maps/blob/1e71a21f39e7b88554852951f773c731c94680c9/docs/installation.md#ios -An unoffical step-by-step guide is also available at https://gist.github.com/heron2014/e60fa003e9b117ce80d56bb1d5bfe9e0 +An unofficial step-by-step guide is also available at https://gist.github.com/heron2014/e60fa003e9b117ce80d56bb1d5bfe9e0 ## Examples diff --git a/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapModule.java b/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapModule.java index 2cd1ba686..80746a0f1 100644 --- a/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapModule.java +++ b/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapModule.java @@ -86,7 +86,7 @@ public void execute (NativeViewHierarchyManager nvhm) { view.map.snapshot(new GoogleMap.SnapshotReadyCallback() { public void onSnapshotReady(@Nullable Bitmap snapshot) { - // Convert image to requested width/height if neccesary + // Convert image to requested width/height if necessary if (snapshot == null) { promise.reject("Failed to generate bitmap, snapshot = null"); return; From d62f5ef5ae4edb065643dc1e675753b134e085e2 Mon Sep 17 00:00:00 2001 From: skylabvn Date: Thu, 1 Jun 2017 21:34:27 +0700 Subject: [PATCH 113/199] Fix import header for React Native 0.44.2 (#1362) --- lib/ios/AirGoogleMaps/AIRGMSPolyline.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/ios/AirGoogleMaps/AIRGMSPolyline.h b/lib/ios/AirGoogleMaps/AIRGMSPolyline.h index 64a3afb99..d7ee19783 100644 --- a/lib/ios/AirGoogleMaps/AIRGMSPolyline.h +++ b/lib/ios/AirGoogleMaps/AIRGMSPolyline.h @@ -6,7 +6,7 @@ // #import -#import "UIView+React.h" +#import @class AIRGoogleMapPolyline; From f6cfb362975b6fef24b07afb897d2659622d2d78 Mon Sep 17 00:00:00 2001 From: Thomas Bouder Date: Thu, 1 Jun 2017 19:47:47 +0200 Subject: [PATCH 114/199] Update from View.propTypes to ViewPropTypes to match RN v0.44.0 (#1323) * Upd from View.propTypes to ViewPropTypes * Rm View component --- lib/components/MapCallout.js | 4 ++-- lib/components/MapCircle.js | 4 ++-- lib/components/MapMarker.js | 4 ++-- lib/components/MapPolygon.js | 4 ++-- lib/components/MapPolyline.js | 4 ++-- lib/components/MapUrlTile.js | 4 ++-- lib/components/MapView.js | 6 +++--- 7 files changed, 15 insertions(+), 15 deletions(-) diff --git a/lib/components/MapCallout.js b/lib/components/MapCallout.js index cf4bb9cef..8989df40c 100644 --- a/lib/components/MapCallout.js +++ b/lib/components/MapCallout.js @@ -1,7 +1,7 @@ import React, { PropTypes } from 'react'; import { - View, StyleSheet, + ViewPropTypes, } from 'react-native'; import decorateMapComponent, { SUPPORTED, @@ -9,7 +9,7 @@ import decorateMapComponent, { } from './decorateMapComponent'; const propTypes = { - ...View.propTypes, + ...ViewPropTypes, tooltip: PropTypes.bool, onPress: PropTypes.func, }; diff --git a/lib/components/MapCircle.js b/lib/components/MapCircle.js index aab1ba8f1..a3371ca60 100644 --- a/lib/components/MapCircle.js +++ b/lib/components/MapCircle.js @@ -1,6 +1,6 @@ import React, { PropTypes } from 'react'; import { - View, + ViewPropTypes, } from 'react-native'; import decorateMapComponent, { USES_DEFAULT_IMPLEMENTATION, @@ -8,7 +8,7 @@ import decorateMapComponent, { } from './decorateMapComponent'; const propTypes = { - ...View.propTypes, + ...ViewPropTypes, /** * The coordinate of the center of the circle diff --git a/lib/components/MapMarker.js b/lib/components/MapMarker.js index be54e42db..0589979fa 100644 --- a/lib/components/MapMarker.js +++ b/lib/components/MapMarker.js @@ -1,11 +1,11 @@ import React, { PropTypes } from 'react'; import { - View, StyleSheet, Platform, NativeModules, Animated, findNodeHandle, + ViewPropTypes, } from 'react-native'; import resolveAssetSource from 'react-native/Libraries/Image/resolveAssetSource'; @@ -22,7 +22,7 @@ const viewConfig = { }; const propTypes = { - ...View.propTypes, + ...ViewPropTypes, // TODO(lmr): get rid of these? identifier: PropTypes.string, diff --git a/lib/components/MapPolygon.js b/lib/components/MapPolygon.js index 6901979db..f88648fca 100644 --- a/lib/components/MapPolygon.js +++ b/lib/components/MapPolygon.js @@ -1,6 +1,6 @@ import React, { PropTypes } from 'react'; import { - View, + ViewPropTypes, } from 'react-native'; import decorateMapComponent, { USES_DEFAULT_IMPLEMENTATION, @@ -8,7 +8,7 @@ import decorateMapComponent, { } from './decorateMapComponent'; const propTypes = { - ...View.propTypes, + ...ViewPropTypes, /** * An array of coordinates to describe the polygon diff --git a/lib/components/MapPolyline.js b/lib/components/MapPolyline.js index aa79f096b..b2ecdffc1 100644 --- a/lib/components/MapPolyline.js +++ b/lib/components/MapPolyline.js @@ -1,6 +1,6 @@ import React, { PropTypes } from 'react'; import { - View, + ViewPropTypes, } from 'react-native'; import decorateMapComponent, { USES_DEFAULT_IMPLEMENTATION, @@ -8,7 +8,7 @@ import decorateMapComponent, { } from './decorateMapComponent'; const propTypes = { - ...View.propTypes, + ...ViewPropTypes, /** * An array of coordinates to describe the polygon diff --git a/lib/components/MapUrlTile.js b/lib/components/MapUrlTile.js index cf2770334..bb1d26552 100644 --- a/lib/components/MapUrlTile.js +++ b/lib/components/MapUrlTile.js @@ -1,7 +1,7 @@ import React, { PropTypes } from 'react'; import { - View, + ViewPropTypes, } from 'react-native'; import decorateMapComponent, { @@ -10,7 +10,7 @@ import decorateMapComponent, { } from './decorateMapComponent'; const propTypes = { - ...View.propTypes, + ...ViewPropTypes, /** * The url template of the tile server. The patterns {x} {y} {z} will be replaced at runtime diff --git a/lib/components/MapView.js b/lib/components/MapView.js index f25003b84..0d8bf5450 100644 --- a/lib/components/MapView.js +++ b/lib/components/MapView.js @@ -2,12 +2,12 @@ import React, { PropTypes } from 'react'; import { EdgeInsetsPropType, Platform, - View, Animated, requireNativeComponent, NativeModules, ColorPropType, findNodeHandle, + ViewPropTypes, } from 'react-native'; import MapMarker from './MapMarker'; import MapPolyline from './MapPolyline'; @@ -45,7 +45,7 @@ const viewConfig = { }; const propTypes = { - ...View.propTypes, + ...ViewPropTypes, /** * When provider is "google", we will use GoogleMaps. * Any value other than "google" will default to using @@ -59,7 +59,7 @@ const propTypes = { * Used to style and layout the `MapView`. See `StyleSheet.js` and * `ViewStylePropTypes.js` for more info. */ - style: View.propTypes.style, + style: ViewPropTypes.style, /** * A json object that describes the style of the map. This is transformed to a string From 0c925244cf138905ca0a6d67894f0761c73eb28e Mon Sep 17 00:00:00 2001 From: Ryan Kaskel Date: Thu, 15 Jun 2017 17:34:23 +0100 Subject: [PATCH 115/199] [iOS - Google Maps] Fix animateToCoordinate and animateToRegion (#1115) * Add animateToCoordinate to Google Maps on iOS * Add animate to random coordinate button in example app * Fix animateToRegion duration for Google Maps on iOS --- example/examples/DisplayLatLng.js | 36 ++++++++++++++++----- lib/ios/AirGoogleMaps/AIRGoogleMapManager.m | 30 ++++++++++++++--- 2 files changed, 54 insertions(+), 12 deletions(-) diff --git a/example/examples/DisplayLatLng.js b/example/examples/DisplayLatLng.js index 573617d41..aa2dde2ac 100644 --- a/example/examples/DisplayLatLng.js +++ b/example/examples/DisplayLatLng.js @@ -43,15 +43,25 @@ class DisplayLatLng extends React.Component { this.map.animateToRegion(this.randomRegion()); } - randomRegion() { - const { region } = this.state; + animateRandomCoordinate() { + this.map.animateToCoordinate(this.randomCoordinate()); + } + + randomCoordinate() { + const region = this.state.region; return { - ...this.state.region, latitude: region.latitude + ((Math.random() - 0.5) * (region.latitudeDelta / 2)), longitude: region.longitude + ((Math.random() - 0.5) * (region.longitudeDelta / 2)), }; } + randomRegion() { + return { + ...this.state.region, + ...this.randomCoordinate(), + }; + } + render() { return ( @@ -74,13 +84,19 @@ class DisplayLatLng extends React.Component { onPress={() => this.jumpRandom()} style={[styles.bubble, styles.button]} > - Jump + Jump
this.animateRandom()} style={[styles.bubble, styles.button]} > - Animate + Animate (Region) + + this.animateRandomCoordinate()} + style={[styles.bubble, styles.button]} + > + Animate (Coordinate)
@@ -112,16 +128,20 @@ const styles = StyleSheet.create({ alignItems: 'stretch', }, button: { - width: 80, - paddingHorizontal: 12, + width: 100, + paddingHorizontal: 8, alignItems: 'center', - marginHorizontal: 10, + justifyContent: 'center', + marginHorizontal: 5, }, buttonContainer: { flexDirection: 'row', marginVertical: 20, backgroundColor: 'transparent', }, + buttonText: { + textAlign: 'center', + }, }); module.exports = DisplayLatLng; diff --git a/lib/ios/AirGoogleMaps/AIRGoogleMapManager.m b/lib/ios/AirGoogleMaps/AIRGoogleMapManager.m index 785d58d4d..6a3b92e90 100644 --- a/lib/ios/AirGoogleMaps/AIRGoogleMapManager.m +++ b/lib/ios/AirGoogleMaps/AIRGoogleMapManager.m @@ -26,6 +26,7 @@ #import "RCTConvert+AirMap.h" #import +#import static NSString *const RCTMapViewKey = @"MapView"; @@ -75,10 +76,31 @@ - (UIView *)view if (![view isKindOfClass:[AIRGoogleMap class]]) { RCTLogError(@"Invalid view returned from registry, expecting AIRGoogleMap, got: %@", view); } else { - [AIRGoogleMap animateWithDuration:duration/1000 animations:^{ - GMSCameraPosition* camera = [AIRGoogleMap makeGMSCameraPositionFromMap:(AIRGoogleMap *)view andMKCoordinateRegion:region]; - [(AIRGoogleMap *)view animateToCameraPosition:camera]; - }]; + // Core Animation must be used to control the animation's duration + // See http://stackoverflow.com/a/15663039/171744 + [CATransaction begin]; + [CATransaction setAnimationDuration:duration/1000]; + AIRGoogleMap *mapView = (AIRGoogleMap *)view; + GMSCameraPosition *camera = [AIRGoogleMap makeGMSCameraPositionFromMap:mapView andMKCoordinateRegion:region]; + [mapView animateToCameraPosition:camera]; + [CATransaction commit]; + } + }]; +} + +RCT_EXPORT_METHOD(animateToCoordinate:(nonnull NSNumber *)reactTag + withRegion:(CLLocationCoordinate2D)latlng + withDuration:(CGFloat)duration) +{ + [self.bridge.uiManager addUIBlock:^(__unused RCTUIManager *uiManager, NSDictionary *viewRegistry) { + id view = viewRegistry[reactTag]; + if (![view isKindOfClass:[AIRGoogleMap class]]) { + RCTLogError(@"Invalid view returned from registry, expecting AIRGoogleMap, got: %@", view); + } else { + [CATransaction begin]; + [CATransaction setAnimationDuration:duration/1000]; + [(AIRGoogleMap *)view animateToLocation:latlng]; + [CATransaction commit]; } }]; } From 8f30c8a209fadf473ce4661779eef24d74c2220a Mon Sep 17 00:00:00 2001 From: Chaitanya Bhagvan Date: Sat, 17 Jun 2017 23:48:30 +0530 Subject: [PATCH 116/199] Fixes google map null pointer exception (#1403) AirMapView doDestroy is called before LifecycleEventListener onHostPause. This fixes https://github.com/airbnb/react-native-maps/issues/1358 --- .../main/java/com/airbnb/android/react/maps/AirMapView.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapView.java b/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapView.java index 3225bf1ff..725270ac6 100644 --- a/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapView.java +++ b/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapView.java @@ -314,7 +314,9 @@ public void onHostPause() { map.setMyLocationEnabled(false); } synchronized (AirMapView.this) { - AirMapView.this.onPause(); + if(!destroyed) { + AirMapView.this.onPause(); + } paused = true; } } From d2b7b380c26c433244f5ea633dfec8914dde910b Mon Sep 17 00:00:00 2001 From: Felipe Lima Date: Tue, 20 Jun 2017 13:25:22 -0700 Subject: [PATCH 117/199] [Android] Code cleanup step I - reformatting (#1415) * Reformat code to match code style settings * Example app reformatting --- .idea/codeStyleSettings.xml | 265 +++ build.gradle | 2 +- example/android/app/build.gradle | 6 +- .../react/maps/example/MainActivity.java | 18 +- gradle/wrapper/gradle-wrapper.properties | 2 +- lib/android/build.gradle | 2 +- .../android/react/maps/AirMapCallout.java | 24 +- .../react/maps/AirMapCalloutManager.java | 80 +- .../android/react/maps/AirMapCircle.java | 150 +- .../react/maps/AirMapCircleManager.java | 88 +- .../android/react/maps/AirMapFeature.java | 12 +- .../android/react/maps/AirMapLiteManager.java | 18 +- .../android/react/maps/AirMapManager.java | 548 +++--- .../android/react/maps/AirMapMarker.java | 758 ++++---- .../react/maps/AirMapMarkerManager.java | 350 ++-- .../android/react/maps/AirMapModule.java | 207 ++- .../android/react/maps/AirMapPolygon.java | 162 +- .../react/maps/AirMapPolygonManager.java | 104 +- .../android/react/maps/AirMapPolyline.java | 146 +- .../react/maps/AirMapPolylineManager.java | 96 +- .../android/react/maps/AirMapUrlTile.java | 141 +- .../react/maps/AirMapUrlTileManager.java | 64 +- .../airbnb/android/react/maps/AirMapView.java | 1537 +++++++++-------- .../android/react/maps/LatLngBoundsUtils.java | 80 +- .../android/react/maps/MapsPackage.java | 74 +- .../android/react/maps/RegionChangeEvent.java | 72 +- .../react/maps/SizeReportingShadowNode.java | 16 +- 27 files changed, 2644 insertions(+), 2378 deletions(-) create mode 100644 .idea/codeStyleSettings.xml diff --git a/.idea/codeStyleSettings.xml b/.idea/codeStyleSettings.xml new file mode 100644 index 000000000..b6cfecda9 --- /dev/null +++ b/.idea/codeStyleSettings.xml @@ -0,0 +1,265 @@ + + + + + + \ No newline at end of file diff --git a/build.gradle b/build.gradle index 8a3e2453e..588e5cb99 100644 --- a/build.gradle +++ b/build.gradle @@ -5,7 +5,7 @@ buildscript { jcenter() } dependencies { - classpath 'com.android.tools.build:gradle:2.3.1' + classpath 'com.android.tools.build:gradle:2.3.2' } } diff --git a/example/android/app/build.gradle b/example/android/app/build.gradle index c5bdebe4c..7c63b3b43 100644 --- a/example/android/app/build.gradle +++ b/example/android/app/build.gradle @@ -85,7 +85,7 @@ def enableProguardInReleaseBuilds = false android { compileSdkVersion 25 - buildToolsVersion "25.0.2" + buildToolsVersion "25.0.3" defaultConfig { applicationId "com.airbnb.android.react.maps.example" @@ -128,7 +128,7 @@ android { dependencies { compile 'com.facebook.react:react-native:0.42.+' - compile 'com.android.support:appcompat-v7:25.1.1' - compile 'com.android.support:support-annotations:25.1.1' + compile 'com.android.support:appcompat-v7:25.3.0' + compile 'com.android.support:support-annotations:25.3.0' compile project(':react-native-maps-lib') } diff --git a/example/android/app/src/main/java/com/airbnb/android/react/maps/example/MainActivity.java b/example/android/app/src/main/java/com/airbnb/android/react/maps/example/MainActivity.java index eec2349a4..12149c20e 100644 --- a/example/android/app/src/main/java/com/airbnb/android/react/maps/example/MainActivity.java +++ b/example/android/app/src/main/java/com/airbnb/android/react/maps/example/MainActivity.java @@ -4,14 +4,12 @@ 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 String getMainComponentName() { - return "AirMapsExplorer"; - } - + /** + * Returns the name of the main component registered from JavaScript. + * This is used to schedule rendering of the component. + */ + @Override + protected String getMainComponentName() { + return "AirMapsExplorer"; + } } diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index c21e471fc..e5fa88cc4 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-3.5-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-4.0-all.zip diff --git a/lib/android/build.gradle b/lib/android/build.gradle index 434e63e72..326ab4bfa 100644 --- a/lib/android/build.gradle +++ b/lib/android/build.gradle @@ -3,7 +3,7 @@ apply from: 'gradle-maven-push.gradle' android { compileSdkVersion 25 - buildToolsVersion "25.0.2" + buildToolsVersion "25.0.3" defaultConfig { minSdkVersion 16 diff --git a/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapCallout.java b/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapCallout.java index c434c9c12..6f96e15da 100644 --- a/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapCallout.java +++ b/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapCallout.java @@ -5,19 +5,19 @@ import com.facebook.react.views.view.ReactViewGroup; public class AirMapCallout extends ReactViewGroup { - private boolean tooltip = false; - public int width; - public int height; + private boolean tooltip = false; + public int width; + public int height; - public AirMapCallout(Context context) { - super(context); - } + public AirMapCallout(Context context) { + super(context); + } - public void setTooltip(boolean tooltip) { - this.tooltip = tooltip; - } + public void setTooltip(boolean tooltip) { + this.tooltip = tooltip; + } - public boolean getTooltip() { - return this.tooltip; - } + public boolean getTooltip() { + return this.tooltip; + } } diff --git a/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapCalloutManager.java b/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapCalloutManager.java index 359e6847b..b63ea29ff 100644 --- a/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapCalloutManager.java +++ b/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapCalloutManager.java @@ -12,45 +12,45 @@ public class AirMapCalloutManager extends ViewGroupManager { - @Override - public String getName() { - return "AIRMapCallout"; - } - - @Override - public AirMapCallout createViewInstance(ThemedReactContext context) { - return new AirMapCallout(context); - } - - @ReactProp(name = "tooltip", defaultBoolean = false) - public void setTooltip(AirMapCallout view, boolean tooltip) { - view.setTooltip(tooltip); - } - - @Override - @Nullable - public Map getExportedCustomDirectEventTypeConstants() { - return MapBuilder.of("onPress", MapBuilder.of("registrationName", "onPress")); - } - - @Override - public LayoutShadowNode createShadowNodeInstance() { - // we use a custom shadow node that emits the width/height of the view - // after layout with the updateExtraData method. Without this, we can't generate - // a bitmap of the appropriate width/height of the rendered view. - return new SizeReportingShadowNode(); - } - - @Override - public void updateExtraData(AirMapCallout view, Object extraData) { - // This method is called from the shadow node with the width/height of the rendered - // marker view. - //noinspection unchecked - Map data = (Map) extraData; - float width = data.get("width"); - float height = data.get("height"); - view.width = (int) width; - view.height = (int) height; - } + @Override + public String getName() { + return "AIRMapCallout"; + } + + @Override + public AirMapCallout createViewInstance(ThemedReactContext context) { + return new AirMapCallout(context); + } + + @ReactProp(name = "tooltip", defaultBoolean = false) + public void setTooltip(AirMapCallout view, boolean tooltip) { + view.setTooltip(tooltip); + } + + @Override + @Nullable + public Map getExportedCustomDirectEventTypeConstants() { + return MapBuilder.of("onPress", MapBuilder.of("registrationName", "onPress")); + } + + @Override + public LayoutShadowNode createShadowNodeInstance() { + // we use a custom shadow node that emits the width/height of the view + // after layout with the updateExtraData method. Without this, we can't generate + // a bitmap of the appropriate width/height of the rendered view. + return new SizeReportingShadowNode(); + } + + @Override + public void updateExtraData(AirMapCallout view, Object extraData) { + // This method is called from the shadow node with the width/height of the rendered + // marker view. + //noinspection unchecked + Map data = (Map) extraData; + float width = data.get("width"); + float height = data.get("height"); + view.width = (int) width; + view.height = (int) height; + } } diff --git a/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapCircle.java b/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapCircle.java index e428b04f6..a70d9146a 100644 --- a/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapCircle.java +++ b/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapCircle.java @@ -9,92 +9,92 @@ public class AirMapCircle extends AirMapFeature { - private CircleOptions circleOptions; - private Circle circle; - - private LatLng center; - private double radius; - private int strokeColor; - private int fillColor; - private float strokeWidth; - private float zIndex; - - public AirMapCircle(Context context) { - super(context); + private CircleOptions circleOptions; + private Circle circle; + + private LatLng center; + private double radius; + private int strokeColor; + private int fillColor; + private float strokeWidth; + private float zIndex; + + public AirMapCircle(Context context) { + super(context); + } + + public void setCenter(LatLng center) { + this.center = center; + if (circle != null) { + circle.setCenter(this.center); } + } - public void setCenter(LatLng center) { - this.center = center; - if (circle != null) { - circle.setCenter(this.center); - } + public void setRadius(double radius) { + this.radius = radius; + if (circle != null) { + circle.setRadius(this.radius); } + } - public void setRadius(double radius) { - this.radius = radius; - if (circle != null) { - circle.setRadius(this.radius); - } + public void setFillColor(int color) { + this.fillColor = color; + if (circle != null) { + circle.setFillColor(color); } + } - public void setFillColor(int color) { - this.fillColor = color; - if (circle != null) { - circle.setFillColor(color); - } + public void setStrokeColor(int color) { + this.strokeColor = color; + if (circle != null) { + circle.setStrokeColor(color); } + } - public void setStrokeColor(int color) { - this.strokeColor = color; - if (circle != null) { - circle.setStrokeColor(color); - } + public void setStrokeWidth(float width) { + this.strokeWidth = width; + if (circle != null) { + circle.setStrokeWidth(width); } + } - public void setStrokeWidth(float width) { - this.strokeWidth = width; - if (circle != null) { - circle.setStrokeWidth(width); - } + public void setZIndex(float zIndex) { + this.zIndex = zIndex; + if (circle != null) { + circle.setZIndex(zIndex); } + } - public void setZIndex(float zIndex) { - this.zIndex = zIndex; - if (circle != null) { - circle.setZIndex(zIndex); - } - } - - public CircleOptions getCircleOptions() { - if (circleOptions == null) { - circleOptions = createCircleOptions(); - } - return circleOptions; - } - - private CircleOptions createCircleOptions() { - CircleOptions options = new CircleOptions(); - options.center(center); - options.radius(radius); - options.fillColor(fillColor); - options.strokeColor(strokeColor); - options.strokeWidth(strokeWidth); - options.zIndex(zIndex); - return options; - } - - @Override - public Object getFeature() { - return circle; - } - - @Override - public void addToMap(GoogleMap map) { - circle = map.addCircle(getCircleOptions()); - } - - @Override - public void removeFromMap(GoogleMap map) { - circle.remove(); + public CircleOptions getCircleOptions() { + if (circleOptions == null) { + circleOptions = createCircleOptions(); } + return circleOptions; + } + + private CircleOptions createCircleOptions() { + CircleOptions options = new CircleOptions(); + options.center(center); + options.radius(radius); + options.fillColor(fillColor); + options.strokeColor(strokeColor); + options.strokeWidth(strokeWidth); + options.zIndex(zIndex); + return options; + } + + @Override + public Object getFeature() { + return circle; + } + + @Override + public void addToMap(GoogleMap map) { + circle = map.addCircle(getCircleOptions()); + } + + @Override + public void removeFromMap(GoogleMap map) { + circle.remove(); + } } diff --git a/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapCircleManager.java b/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapCircleManager.java index c0eaf8f14..c8eabf2d1 100644 --- a/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapCircleManager.java +++ b/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapCircleManager.java @@ -14,59 +14,59 @@ import com.google.android.gms.maps.model.LatLng; public class AirMapCircleManager extends ViewGroupManager { - private final DisplayMetrics metrics; + private final DisplayMetrics metrics; - public AirMapCircleManager(ReactApplicationContext reactContext) { - super(); - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) { - metrics = new DisplayMetrics(); - ((WindowManager) reactContext.getSystemService(Context.WINDOW_SERVICE)) - .getDefaultDisplay() - .getRealMetrics(metrics); - } else { - metrics = reactContext.getResources().getDisplayMetrics(); - } + public AirMapCircleManager(ReactApplicationContext reactContext) { + super(); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) { + metrics = new DisplayMetrics(); + ((WindowManager) reactContext.getSystemService(Context.WINDOW_SERVICE)) + .getDefaultDisplay() + .getRealMetrics(metrics); + } else { + metrics = reactContext.getResources().getDisplayMetrics(); } + } - @Override - public String getName() { - return "AIRMapCircle"; - } + @Override + public String getName() { + return "AIRMapCircle"; + } - @Override - public AirMapCircle createViewInstance(ThemedReactContext context) { - return new AirMapCircle(context); - } + @Override + public AirMapCircle createViewInstance(ThemedReactContext context) { + return new AirMapCircle(context); + } - @ReactProp(name = "center") - public void setCenter(AirMapCircle view, ReadableMap center) { - view.setCenter(new LatLng(center.getDouble("latitude"), center.getDouble("longitude"))); - } + @ReactProp(name = "center") + public void setCenter(AirMapCircle view, ReadableMap center) { + view.setCenter(new LatLng(center.getDouble("latitude"), center.getDouble("longitude"))); + } - @ReactProp(name = "radius", defaultDouble = 0) - public void setRadius(AirMapCircle view, double radius) { - view.setRadius(radius); - } + @ReactProp(name = "radius", defaultDouble = 0) + public void setRadius(AirMapCircle view, double radius) { + view.setRadius(radius); + } - @ReactProp(name = "strokeWidth", defaultFloat = 1f) - public void setStrokeWidth(AirMapCircle view, float widthInPoints) { - float widthInScreenPx = metrics.density * widthInPoints; // done for parity with iOS - view.setStrokeWidth(widthInScreenPx); - } + @ReactProp(name = "strokeWidth", defaultFloat = 1f) + public void setStrokeWidth(AirMapCircle view, float widthInPoints) { + float widthInScreenPx = metrics.density * widthInPoints; // done for parity with iOS + view.setStrokeWidth(widthInScreenPx); + } - @ReactProp(name = "fillColor", defaultInt = Color.RED, customType = "Color") - public void setFillColor(AirMapCircle view, int color) { - view.setFillColor(color); - } + @ReactProp(name = "fillColor", defaultInt = Color.RED, customType = "Color") + public void setFillColor(AirMapCircle view, int color) { + view.setFillColor(color); + } - @ReactProp(name = "strokeColor", defaultInt = Color.RED, customType = "Color") - public void setStrokeColor(AirMapCircle view, int color) { - view.setStrokeColor(color); - } + @ReactProp(name = "strokeColor", defaultInt = Color.RED, customType = "Color") + public void setStrokeColor(AirMapCircle view, int color) { + view.setStrokeColor(color); + } - @ReactProp(name = "zIndex", defaultFloat = 1.0f) - public void setZIndex(AirMapCircle view, float zIndex) { - view.setZIndex(zIndex); - } + @ReactProp(name = "zIndex", defaultFloat = 1.0f) + public void setZIndex(AirMapCircle view, float zIndex) { + view.setZIndex(zIndex); + } } diff --git a/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapFeature.java b/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapFeature.java index 1c15ade5f..70484c1a4 100644 --- a/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapFeature.java +++ b/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapFeature.java @@ -6,13 +6,13 @@ import com.google.android.gms.maps.GoogleMap; public abstract class AirMapFeature extends ReactViewGroup { - public AirMapFeature(Context context) { - super(context); - } + public AirMapFeature(Context context) { + super(context); + } - public abstract void addToMap(GoogleMap map); + public abstract void addToMap(GoogleMap map); - public abstract void removeFromMap(GoogleMap map); + public abstract void removeFromMap(GoogleMap map); - public abstract Object getFeature(); + public abstract Object getFeature(); } diff --git a/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapLiteManager.java b/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapLiteManager.java index 62495c5e4..619e36435 100644 --- a/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapLiteManager.java +++ b/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapLiteManager.java @@ -5,16 +5,16 @@ public class AirMapLiteManager extends AirMapManager { - private static final String REACT_CLASS = "AIRMapLite"; + private static final String REACT_CLASS = "AIRMapLite"; - @Override - public String getName() { - return REACT_CLASS; - } + @Override + public String getName() { + return REACT_CLASS; + } - public AirMapLiteManager(ReactApplicationContext context) { - super(context); - this.googleMapOptions = new GoogleMapOptions().liteMode(true); - } + public AirMapLiteManager(ReactApplicationContext context) { + super(context); + this.googleMapOptions = new GoogleMapOptions().liteMode(true); + } } diff --git a/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapManager.java b/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapManager.java index b6a975b77..404f6a127 100644 --- a/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapManager.java +++ b/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapManager.java @@ -4,7 +4,6 @@ import com.facebook.react.bridge.Arguments; import com.facebook.react.bridge.ReactApplicationContext; -import com.facebook.react.bridge.ReactContext; import com.facebook.react.bridge.ReadableArray; import com.facebook.react.bridge.ReadableMap; import com.facebook.react.bridge.WritableMap; @@ -17,7 +16,6 @@ import com.facebook.react.uimanager.events.RCTEventEmitter; import com.google.android.gms.maps.GoogleMap; import com.google.android.gms.maps.GoogleMapOptions; -import com.google.android.gms.maps.MapsInitializer; import com.google.android.gms.maps.model.LatLng; import com.google.android.gms.maps.model.LatLngBounds; import com.google.android.gms.maps.model.MapStyleOptions; @@ -28,280 +26,280 @@ public class AirMapManager extends ViewGroupManager { - private static final String REACT_CLASS = "AIRMap"; - private static final int ANIMATE_TO_REGION = 1; - private static final int ANIMATE_TO_COORDINATE = 2; - private static final int FIT_TO_ELEMENTS = 3; - private static final int FIT_TO_SUPPLIED_MARKERS = 4; - private static final int FIT_TO_COORDINATES = 5; - - private final Map MAP_TYPES = MapBuilder.of( - "standard", GoogleMap.MAP_TYPE_NORMAL, - "satellite", GoogleMap.MAP_TYPE_SATELLITE, - "hybrid", GoogleMap.MAP_TYPE_HYBRID, - "terrain", GoogleMap.MAP_TYPE_TERRAIN, - "none", GoogleMap.MAP_TYPE_NONE - ); - - private final ReactApplicationContext appContext; - - protected GoogleMapOptions googleMapOptions; - - public AirMapManager(ReactApplicationContext context) { - this.appContext = context; - this.googleMapOptions = new GoogleMapOptions(); - } - - @Override - public String getName() { - return REACT_CLASS; - } - - @Override - protected AirMapView createViewInstance(ThemedReactContext context) { - return new AirMapView(context, this.appContext, this, googleMapOptions); - } - - private void emitMapError(ThemedReactContext context, String message, String type) { - WritableMap error = Arguments.createMap(); - error.putString("message", message); - error.putString("type", type); - - context - .getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class) - .emit("onError", error); - } - - @ReactProp(name = "region") - public void setRegion(AirMapView view, ReadableMap region) { - view.setRegion(region); - } - - @ReactProp(name = "mapType") - public void setMapType(AirMapView view, @Nullable String mapType) { - int typeId = MAP_TYPES.get(mapType); - view.map.setMapType(typeId); - } - - @ReactProp(name = "customMapStyleString") - public void setMapStyle(AirMapView view, @Nullable String customMapStyleString) { - view.map.setMapStyle(new MapStyleOptions(customMapStyleString)); - } - - @ReactProp(name = "showsUserLocation", defaultBoolean = false) - public void setShowsUserLocation(AirMapView view, boolean showUserLocation) { - view.setShowsUserLocation(showUserLocation); - } - - @ReactProp(name = "showsMyLocationButton", defaultBoolean = true) - public void setShowsMyLocationButton(AirMapView view, boolean showMyLocationButton) { - view.setShowsMyLocationButton(showMyLocationButton); - } - - @ReactProp(name = "toolbarEnabled", defaultBoolean = true) - public void setToolbarEnabled(AirMapView view, boolean toolbarEnabled) { - view.setToolbarEnabled(toolbarEnabled); - } - - // This is a private prop to improve performance of panDrag by disabling it when the callback is not set - @ReactProp(name = "handlePanDrag", defaultBoolean = false) - public void setHandlePanDrag(AirMapView view, boolean handlePanDrag) { - view.setHandlePanDrag(handlePanDrag); - } - - @ReactProp(name = "showsTraffic", defaultBoolean = false) - public void setShowTraffic(AirMapView view, boolean showTraffic) { - view.map.setTrafficEnabled(showTraffic); - } - - @ReactProp(name = "showsBuildings", defaultBoolean = false) - public void setShowBuildings(AirMapView view, boolean showBuildings) { - view.map.setBuildingsEnabled(showBuildings); - } - - @ReactProp(name = "showsIndoors", defaultBoolean = false) - public void setShowIndoors(AirMapView view, boolean showIndoors) { - view.map.setIndoorEnabled(showIndoors); - } - - @ReactProp(name = "showsIndoorLevelPicker", defaultBoolean = false) - public void setShowsIndoorLevelPicker(AirMapView view, boolean showsIndoorLevelPicker) { - view.map.getUiSettings().setIndoorLevelPickerEnabled(showsIndoorLevelPicker); - } - - @ReactProp(name = "showsCompass", defaultBoolean = false) - public void setShowsCompass(AirMapView view, boolean showsCompass) { - view.map.getUiSettings().setCompassEnabled(showsCompass); - } - - @ReactProp(name = "scrollEnabled", defaultBoolean = false) - public void setScrollEnabled(AirMapView view, boolean scrollEnabled) { - view.map.getUiSettings().setScrollGesturesEnabled(scrollEnabled); - } - - @ReactProp(name = "zoomEnabled", defaultBoolean = false) - public void setZoomEnabled(AirMapView view, boolean zoomEnabled) { - view.map.getUiSettings().setZoomGesturesEnabled(zoomEnabled); - } - - @ReactProp(name = "rotateEnabled", defaultBoolean = false) - public void setRotateEnabled(AirMapView view, boolean rotateEnabled) { - view.map.getUiSettings().setRotateGesturesEnabled(rotateEnabled); - } - - @ReactProp(name = "cacheEnabled", defaultBoolean = false) - public void setCacheEnabled(AirMapView view, boolean cacheEnabled) { - view.setCacheEnabled(cacheEnabled); - } - - @ReactProp(name = "loadingEnabled", defaultBoolean = false) - public void setLoadingEnabled(AirMapView view, boolean loadingEnabled) { - view.enableMapLoading(loadingEnabled); - } - - @ReactProp(name = "moveOnMarkerPress", defaultBoolean = true) - public void setMoveOnMarkerPress(AirMapView view, boolean moveOnPress) { - view.setMoveOnMarkerPress(moveOnPress); - } - - @ReactProp(name = "loadingBackgroundColor", customType = "Color") - public void setLoadingBackgroundColor(AirMapView view, @Nullable Integer loadingBackgroundColor) { - view.setLoadingBackgroundColor(loadingBackgroundColor); - } - - @ReactProp(name = "loadingIndicatorColor", customType = "Color") - public void setLoadingIndicatorColor(AirMapView view, @Nullable Integer loadingIndicatorColor) { - view.setLoadingIndicatorColor(loadingIndicatorColor); - } - - @ReactProp(name = "pitchEnabled", defaultBoolean = false) - public void setPitchEnabled(AirMapView view, boolean pitchEnabled) { - view.map.getUiSettings().setTiltGesturesEnabled(pitchEnabled); - } - - @Override - public void receiveCommand(AirMapView view, int commandId, @Nullable ReadableArray args) { - Integer duration; - Double lat; - Double lng; - Double lngDelta; - Double latDelta; - ReadableMap region; - - switch (commandId) { - case ANIMATE_TO_REGION: - region = args.getMap(0); - duration = args.getInt(1); - lng = region.getDouble("longitude"); - lat = region.getDouble("latitude"); - lngDelta = region.getDouble("longitudeDelta"); - latDelta = region.getDouble("latitudeDelta"); - LatLngBounds bounds = new LatLngBounds( - new LatLng(lat - latDelta / 2, lng - lngDelta / 2), // southwest - new LatLng(lat + latDelta / 2, lng + lngDelta / 2) // northeast - ); - view.animateToRegion(bounds, duration); - break; - - case ANIMATE_TO_COORDINATE: - region = args.getMap(0); - duration = args.getInt(1); - lng = region.getDouble("longitude"); - lat = region.getDouble("latitude"); - view.animateToCoordinate(new LatLng(lat, lng), duration); - break; - - case FIT_TO_ELEMENTS: - view.fitToElements(args.getBoolean(0)); - break; - - case FIT_TO_SUPPLIED_MARKERS: - view.fitToSuppliedMarkers(args.getArray(0), args.getBoolean(1)); - break; - case FIT_TO_COORDINATES: - view.fitToCoordinates(args.getArray(0), args.getMap(1), args.getBoolean(2)); - break; - } - } - - @Override - @Nullable - public Map getExportedCustomDirectEventTypeConstants() { - Map> map = MapBuilder.of( - "onMapReady", MapBuilder.of("registrationName", "onMapReady"), - "onPress", MapBuilder.of("registrationName", "onPress"), - "onLongPress", MapBuilder.of("registrationName", "onLongPress"), - "onMarkerPress", MapBuilder.of("registrationName", "onMarkerPress"), - "onMarkerSelect", MapBuilder.of("registrationName", "onMarkerSelect"), - "onMarkerDeselect", MapBuilder.of("registrationName", "onMarkerDeselect"), - "onCalloutPress", MapBuilder.of("registrationName", "onCalloutPress") - ); - - map.putAll(MapBuilder.of( - "onMarkerDragStart", MapBuilder.of("registrationName", "onMarkerDragStart"), - "onMarkerDrag", MapBuilder.of("registrationName", "onMarkerDrag"), - "onMarkerDragEnd", MapBuilder.of("registrationName", "onMarkerDragEnd"), - "onPanDrag", MapBuilder.of("registrationName", "onPanDrag") - )); - - return map; - } - - @Override - @Nullable - public Map getCommandsMap() { - return MapBuilder.of( - "animateToRegion", ANIMATE_TO_REGION, - "animateToCoordinate", ANIMATE_TO_COORDINATE, - "fitToElements", FIT_TO_ELEMENTS, - "fitToSuppliedMarkers", FIT_TO_SUPPLIED_MARKERS, - "fitToCoordinates", FIT_TO_COORDINATES + private static final String REACT_CLASS = "AIRMap"; + private static final int ANIMATE_TO_REGION = 1; + private static final int ANIMATE_TO_COORDINATE = 2; + private static final int FIT_TO_ELEMENTS = 3; + private static final int FIT_TO_SUPPLIED_MARKERS = 4; + private static final int FIT_TO_COORDINATES = 5; + + private final Map MAP_TYPES = MapBuilder.of( + "standard", GoogleMap.MAP_TYPE_NORMAL, + "satellite", GoogleMap.MAP_TYPE_SATELLITE, + "hybrid", GoogleMap.MAP_TYPE_HYBRID, + "terrain", GoogleMap.MAP_TYPE_TERRAIN, + "none", GoogleMap.MAP_TYPE_NONE + ); + + private final ReactApplicationContext appContext; + + protected GoogleMapOptions googleMapOptions; + + public AirMapManager(ReactApplicationContext context) { + this.appContext = context; + this.googleMapOptions = new GoogleMapOptions(); + } + + @Override + public String getName() { + return REACT_CLASS; + } + + @Override + protected AirMapView createViewInstance(ThemedReactContext context) { + return new AirMapView(context, this.appContext, this, googleMapOptions); + } + + private void emitMapError(ThemedReactContext context, String message, String type) { + WritableMap error = Arguments.createMap(); + error.putString("message", message); + error.putString("type", type); + + context + .getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class) + .emit("onError", error); + } + + @ReactProp(name = "region") + public void setRegion(AirMapView view, ReadableMap region) { + view.setRegion(region); + } + + @ReactProp(name = "mapType") + public void setMapType(AirMapView view, @Nullable String mapType) { + int typeId = MAP_TYPES.get(mapType); + view.map.setMapType(typeId); + } + + @ReactProp(name = "customMapStyleString") + public void setMapStyle(AirMapView view, @Nullable String customMapStyleString) { + view.map.setMapStyle(new MapStyleOptions(customMapStyleString)); + } + + @ReactProp(name = "showsUserLocation", defaultBoolean = false) + public void setShowsUserLocation(AirMapView view, boolean showUserLocation) { + view.setShowsUserLocation(showUserLocation); + } + + @ReactProp(name = "showsMyLocationButton", defaultBoolean = true) + public void setShowsMyLocationButton(AirMapView view, boolean showMyLocationButton) { + view.setShowsMyLocationButton(showMyLocationButton); + } + + @ReactProp(name = "toolbarEnabled", defaultBoolean = true) + public void setToolbarEnabled(AirMapView view, boolean toolbarEnabled) { + view.setToolbarEnabled(toolbarEnabled); + } + + // This is a private prop to improve performance of panDrag by disabling it when the callback + // is not set + @ReactProp(name = "handlePanDrag", defaultBoolean = false) + public void setHandlePanDrag(AirMapView view, boolean handlePanDrag) { + view.setHandlePanDrag(handlePanDrag); + } + + @ReactProp(name = "showsTraffic", defaultBoolean = false) + public void setShowTraffic(AirMapView view, boolean showTraffic) { + view.map.setTrafficEnabled(showTraffic); + } + + @ReactProp(name = "showsBuildings", defaultBoolean = false) + public void setShowBuildings(AirMapView view, boolean showBuildings) { + view.map.setBuildingsEnabled(showBuildings); + } + + @ReactProp(name = "showsIndoors", defaultBoolean = false) + public void setShowIndoors(AirMapView view, boolean showIndoors) { + view.map.setIndoorEnabled(showIndoors); + } + + @ReactProp(name = "showsIndoorLevelPicker", defaultBoolean = false) + public void setShowsIndoorLevelPicker(AirMapView view, boolean showsIndoorLevelPicker) { + view.map.getUiSettings().setIndoorLevelPickerEnabled(showsIndoorLevelPicker); + } + + @ReactProp(name = "showsCompass", defaultBoolean = false) + public void setShowsCompass(AirMapView view, boolean showsCompass) { + view.map.getUiSettings().setCompassEnabled(showsCompass); + } + + @ReactProp(name = "scrollEnabled", defaultBoolean = false) + public void setScrollEnabled(AirMapView view, boolean scrollEnabled) { + view.map.getUiSettings().setScrollGesturesEnabled(scrollEnabled); + } + + @ReactProp(name = "zoomEnabled", defaultBoolean = false) + public void setZoomEnabled(AirMapView view, boolean zoomEnabled) { + view.map.getUiSettings().setZoomGesturesEnabled(zoomEnabled); + } + + @ReactProp(name = "rotateEnabled", defaultBoolean = false) + public void setRotateEnabled(AirMapView view, boolean rotateEnabled) { + view.map.getUiSettings().setRotateGesturesEnabled(rotateEnabled); + } + + @ReactProp(name = "cacheEnabled", defaultBoolean = false) + public void setCacheEnabled(AirMapView view, boolean cacheEnabled) { + view.setCacheEnabled(cacheEnabled); + } + + @ReactProp(name = "loadingEnabled", defaultBoolean = false) + public void setLoadingEnabled(AirMapView view, boolean loadingEnabled) { + view.enableMapLoading(loadingEnabled); + } + + @ReactProp(name = "moveOnMarkerPress", defaultBoolean = true) + public void setMoveOnMarkerPress(AirMapView view, boolean moveOnPress) { + view.setMoveOnMarkerPress(moveOnPress); + } + + @ReactProp(name = "loadingBackgroundColor", customType = "Color") + public void setLoadingBackgroundColor(AirMapView view, @Nullable Integer loadingBackgroundColor) { + view.setLoadingBackgroundColor(loadingBackgroundColor); + } + + @ReactProp(name = "loadingIndicatorColor", customType = "Color") + public void setLoadingIndicatorColor(AirMapView view, @Nullable Integer loadingIndicatorColor) { + view.setLoadingIndicatorColor(loadingIndicatorColor); + } + + @ReactProp(name = "pitchEnabled", defaultBoolean = false) + public void setPitchEnabled(AirMapView view, boolean pitchEnabled) { + view.map.getUiSettings().setTiltGesturesEnabled(pitchEnabled); + } + + @Override + public void receiveCommand(AirMapView view, int commandId, @Nullable ReadableArray args) { + Integer duration; + Double lat; + Double lng; + Double lngDelta; + Double latDelta; + ReadableMap region; + + switch (commandId) { + case ANIMATE_TO_REGION: + region = args.getMap(0); + duration = args.getInt(1); + lng = region.getDouble("longitude"); + lat = region.getDouble("latitude"); + lngDelta = region.getDouble("longitudeDelta"); + latDelta = region.getDouble("latitudeDelta"); + LatLngBounds bounds = new LatLngBounds( + new LatLng(lat - latDelta / 2, lng - lngDelta / 2), // southwest + new LatLng(lat + latDelta / 2, lng + lngDelta / 2) // northeast ); - } - - @Override - public LayoutShadowNode createShadowNodeInstance() { - // A custom shadow node is needed in order to pass back the width/height of the map to the - // view manager so that it can start applying camera moves with bounds. - return new SizeReportingShadowNode(); - } - - @Override - public void addView(AirMapView parent, View child, int index) { - parent.addFeature(child, index); - } - - @Override - public int getChildCount(AirMapView view) { - return view.getFeatureCount(); - } - - @Override - public View getChildAt(AirMapView view, int index) { - return view.getFeatureAt(index); - } - - @Override - public void removeViewAt(AirMapView parent, int index) { - parent.removeFeatureAt(index); - } - - @Override - public void updateExtraData(AirMapView view, Object extraData) { - view.updateExtraData(extraData); - } - - void pushEvent(ThemedReactContext context, View view, String name, WritableMap data) { - context.getJSModule(RCTEventEmitter.class) - .receiveEvent(view.getId(), name, data); - } - - + view.animateToRegion(bounds, duration); + break; + + case ANIMATE_TO_COORDINATE: + region = args.getMap(0); + duration = args.getInt(1); + lng = region.getDouble("longitude"); + lat = region.getDouble("latitude"); + view.animateToCoordinate(new LatLng(lat, lng), duration); + break; + + case FIT_TO_ELEMENTS: + view.fitToElements(args.getBoolean(0)); + break; + + case FIT_TO_SUPPLIED_MARKERS: + view.fitToSuppliedMarkers(args.getArray(0), args.getBoolean(1)); + break; + case FIT_TO_COORDINATES: + view.fitToCoordinates(args.getArray(0), args.getMap(1), args.getBoolean(2)); + break; + } + } + + @Override + @Nullable + public Map getExportedCustomDirectEventTypeConstants() { + Map> map = MapBuilder.of( + "onMapReady", MapBuilder.of("registrationName", "onMapReady"), + "onPress", MapBuilder.of("registrationName", "onPress"), + "onLongPress", MapBuilder.of("registrationName", "onLongPress"), + "onMarkerPress", MapBuilder.of("registrationName", "onMarkerPress"), + "onMarkerSelect", MapBuilder.of("registrationName", "onMarkerSelect"), + "onMarkerDeselect", MapBuilder.of("registrationName", "onMarkerDeselect"), + "onCalloutPress", MapBuilder.of("registrationName", "onCalloutPress") + ); - @Override - public void onDropViewInstance(AirMapView view) { - view.doDestroy(); - super.onDropViewInstance(view); - } + map.putAll(MapBuilder.of( + "onMarkerDragStart", MapBuilder.of("registrationName", "onMarkerDragStart"), + "onMarkerDrag", MapBuilder.of("registrationName", "onMarkerDrag"), + "onMarkerDragEnd", MapBuilder.of("registrationName", "onMarkerDragEnd"), + "onPanDrag", MapBuilder.of("registrationName", "onPanDrag") + )); + + return map; + } + + @Override + @Nullable + public Map getCommandsMap() { + return MapBuilder.of( + "animateToRegion", ANIMATE_TO_REGION, + "animateToCoordinate", ANIMATE_TO_COORDINATE, + "fitToElements", FIT_TO_ELEMENTS, + "fitToSuppliedMarkers", FIT_TO_SUPPLIED_MARKERS, + "fitToCoordinates", FIT_TO_COORDINATES + ); + } + + @Override + public LayoutShadowNode createShadowNodeInstance() { + // A custom shadow node is needed in order to pass back the width/height of the map to the + // view manager so that it can start applying camera moves with bounds. + return new SizeReportingShadowNode(); + } + + @Override + public void addView(AirMapView parent, View child, int index) { + parent.addFeature(child, index); + } + + @Override + public int getChildCount(AirMapView view) { + return view.getFeatureCount(); + } + + @Override + public View getChildAt(AirMapView view, int index) { + return view.getFeatureAt(index); + } + + @Override + public void removeViewAt(AirMapView parent, int index) { + parent.removeFeatureAt(index); + } + + @Override + public void updateExtraData(AirMapView view, Object extraData) { + view.updateExtraData(extraData); + } + + void pushEvent(ThemedReactContext context, View view, String name, WritableMap data) { + context.getJSModule(RCTEventEmitter.class) + .receiveEvent(view.getId(), name, data); + } + + + @Override + public void onDropViewInstance(AirMapView view) { + view.doDestroy(); + super.onDropViewInstance(view); + } } diff --git a/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapMarker.java b/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapMarker.java index 4041d91ac..52c4dcd08 100644 --- a/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapMarker.java +++ b/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapMarker.java @@ -36,395 +36,395 @@ public class AirMapMarker extends AirMapFeature { - private MarkerOptions markerOptions; - private Marker marker; - private int width; - private int height; - private String identifier; - - private LatLng position; - private String title; - private String snippet; - - private boolean anchorIsSet; - private float anchorX; - private float anchorY; - - private AirMapCallout calloutView; - private View wrappedCalloutView; - private final Context context; - - private float markerHue = 0.0f; // should be between 0 and 360 - private BitmapDescriptor iconBitmapDescriptor; - private Bitmap iconBitmap; - - private float rotation = 0.0f; - private boolean flat = false; - private boolean draggable = false; - private int zIndex = 0; - private float opacity = 1.0f; - - private float calloutAnchorX; - private float calloutAnchorY; - private boolean calloutAnchorIsSet; - - private boolean hasCustomMarkerView = false; - - private final DraweeHolder logoHolder; - private DataSource> dataSource; - private final ControllerListener mLogoControllerListener = - new BaseControllerListener() { - @Override - public void onFinalImageSet( - String id, - @Nullable final ImageInfo imageInfo, - @Nullable Animatable animatable) { - CloseableReference imageReference = null; - try { - imageReference = dataSource.getResult(); - if (imageReference != null) { - CloseableImage image = imageReference.get(); - if (image != null && image instanceof CloseableStaticBitmap) { - CloseableStaticBitmap closeableStaticBitmap = (CloseableStaticBitmap) image; - Bitmap bitmap = closeableStaticBitmap.getUnderlyingBitmap(); - if (bitmap != null) { - bitmap = bitmap.copy(Bitmap.Config.ARGB_8888, true); - iconBitmap = bitmap; - iconBitmapDescriptor = BitmapDescriptorFactory.fromBitmap(bitmap); - } - } - } - } finally { - dataSource.close(); - if (imageReference != null) { - CloseableReference.closeSafely(imageReference); - } - } - update(); + private MarkerOptions markerOptions; + private Marker marker; + private int width; + private int height; + private String identifier; + + private LatLng position; + private String title; + private String snippet; + + private boolean anchorIsSet; + private float anchorX; + private float anchorY; + + private AirMapCallout calloutView; + private View wrappedCalloutView; + private final Context context; + + private float markerHue = 0.0f; // should be between 0 and 360 + private BitmapDescriptor iconBitmapDescriptor; + private Bitmap iconBitmap; + + private float rotation = 0.0f; + private boolean flat = false; + private boolean draggable = false; + private int zIndex = 0; + private float opacity = 1.0f; + + private float calloutAnchorX; + private float calloutAnchorY; + private boolean calloutAnchorIsSet; + + private boolean hasCustomMarkerView = false; + + private final DraweeHolder logoHolder; + private DataSource> dataSource; + private final ControllerListener mLogoControllerListener = + new BaseControllerListener() { + @Override + public void onFinalImageSet( + String id, + @Nullable final ImageInfo imageInfo, + @Nullable Animatable animatable) { + CloseableReference imageReference = null; + try { + imageReference = dataSource.getResult(); + if (imageReference != null) { + CloseableImage image = imageReference.get(); + if (image != null && image instanceof CloseableStaticBitmap) { + CloseableStaticBitmap closeableStaticBitmap = (CloseableStaticBitmap) image; + Bitmap bitmap = closeableStaticBitmap.getUnderlyingBitmap(); + if (bitmap != null) { + bitmap = bitmap.copy(Bitmap.Config.ARGB_8888, true); + iconBitmap = bitmap; + iconBitmapDescriptor = BitmapDescriptorFactory.fromBitmap(bitmap); } - }; - - public AirMapMarker(Context context) { - super(context); - this.context = context; - logoHolder = DraweeHolder.create(createDraweeHierarchy(), context); - logoHolder.onAttach(); - } - - private GenericDraweeHierarchy createDraweeHierarchy() { - return new GenericDraweeHierarchyBuilder(getResources()) - .setActualImageScaleType(ScalingUtils.ScaleType.FIT_CENTER) - .setFadeDuration(0) - .build(); - } - - public void setCoordinate(ReadableMap coordinate) { - position = new LatLng(coordinate.getDouble("latitude"), coordinate.getDouble("longitude")); - if (marker != null) { - marker.setPosition(position); - } - update(); - } - - public void setIdentifier(String identifier) { - this.identifier = identifier; - update(); - } - - public String getIdentifier() { - return this.identifier; - } - - public void setTitle(String title) { - this.title = title; - if (marker != null) { - marker.setTitle(title); - } - update(); - } - - public void setSnippet(String snippet) { - this.snippet = snippet; - if (marker != null) { - marker.setSnippet(snippet); - } - update(); - } - - public void setRotation(float rotation) { - this.rotation = rotation; - if (marker != null) { - marker.setRotation(rotation); - } - update(); - } - - public void setFlat(boolean flat) { - this.flat = flat; - if (marker != null) { - marker.setFlat(flat); - } - update(); - } - - public void setDraggable(boolean draggable) { - this.draggable = draggable; - if (marker != null) { - marker.setDraggable(draggable); - } - update(); - } - - public void setZIndex(int zIndex) { - this.zIndex = zIndex; - if (marker != null) { - marker.setZIndex(zIndex); - } - update(); - } - - public void setOpacity(float opacity) { - this.opacity = opacity; - if (marker != null) { - marker.setAlpha(opacity); - } - update(); - } - - public void setMarkerHue(float markerHue) { - this.markerHue = markerHue; - update(); - } - - public void setAnchor(double x, double y) { - anchorIsSet = true; - anchorX = (float) x; - anchorY = (float) y; - if (marker != null) { - marker.setAnchor(anchorX, anchorY); - } - update(); - } - - public void setCalloutAnchor(double x, double y) { - calloutAnchorIsSet = true; - calloutAnchorX = (float) x; - calloutAnchorY = (float) y; - if (marker != null) { - marker.setInfoWindowAnchor(calloutAnchorX, calloutAnchorY); - } - update(); - } - - public void setImage(String uri) { - if (uri == null) { - iconBitmapDescriptor = null; - update(); - } else if (uri.startsWith("http://") || uri.startsWith("https://") || - uri.startsWith("file://")) { - ImageRequest imageRequest = ImageRequestBuilder - .newBuilderWithSource(Uri.parse(uri)) - .build(); - - ImagePipeline imagePipeline = Fresco.getImagePipeline(); - dataSource = imagePipeline.fetchDecodedImage(imageRequest, this); - DraweeController controller = Fresco.newDraweeControllerBuilder() - .setImageRequest(imageRequest) - .setControllerListener(mLogoControllerListener) - .setOldController(logoHolder.getController()) - .build(); - logoHolder.setController(controller); - } else { - iconBitmapDescriptor = getBitmapDescriptorByName(uri); - update(); - } - } - - public MarkerOptions getMarkerOptions() { - if (markerOptions == null) { - markerOptions = createMarkerOptions(); - } - return markerOptions; - } - - @Override - public void addView(View child, int index) { - super.addView(child, index); - // if children are added, it means we are rendering a custom marker - if (!(child instanceof AirMapCallout)) { - hasCustomMarkerView = true; - } - update(); - } - - @Override - public Object getFeature() { - return marker; - } - - @Override - public void addToMap(GoogleMap map) { - marker = map.addMarker(getMarkerOptions()); - } - - @Override - public void removeFromMap(GoogleMap map) { - marker.remove(); - marker = null; - } - - private BitmapDescriptor getIcon() { - if (hasCustomMarkerView) { - // creating a bitmap from an arbitrary view - if (iconBitmapDescriptor != null) { - Bitmap viewBitmap = createDrawable(); - int width = Math.max(iconBitmap.getWidth(), viewBitmap.getWidth()); - int height = Math.max(iconBitmap.getHeight(), viewBitmap.getHeight()); - Bitmap combinedBitmap = Bitmap.createBitmap(width, height, iconBitmap.getConfig()); - Canvas canvas = new Canvas(combinedBitmap); - canvas.drawBitmap(iconBitmap, 0, 0, null); - canvas.drawBitmap(viewBitmap, 0, 0, null); - return BitmapDescriptorFactory.fromBitmap(combinedBitmap); - } else { - return BitmapDescriptorFactory.fromBitmap(createDrawable()); + } } - } else if (iconBitmapDescriptor != null) { - // use local image as a marker - return iconBitmapDescriptor; - } else { - // render the default marker pin - return BitmapDescriptorFactory.defaultMarker(this.markerHue); - } - } - - private MarkerOptions createMarkerOptions() { - MarkerOptions options = new MarkerOptions().position(position); - if (anchorIsSet) options.anchor(anchorX, anchorY); - if (calloutAnchorIsSet) options.infoWindowAnchor(calloutAnchorX, calloutAnchorY); - options.title(title); - options.snippet(snippet); - options.rotation(rotation); - options.flat(flat); - options.draggable(draggable); - options.zIndex(zIndex); - options.alpha(opacity); - options.icon(getIcon()); - return options; - } - - public void update() { - if (marker == null) { - return; - } - - marker.setIcon(getIcon()); - - if (anchorIsSet) { - marker.setAnchor(anchorX, anchorY); - } else { - marker.setAnchor(0.5f, 1.0f); - } - - if (calloutAnchorIsSet) { - marker.setInfoWindowAnchor(calloutAnchorX, calloutAnchorY); - } else { - marker.setInfoWindowAnchor(0.5f, 0); - } - } - - public void update(int width, int height) { - this.width = width; - this.height = height; - update(); - } - - private Bitmap createDrawable() { - int width = this.width <= 0 ? 100 : this.width; - int height = this.height <= 0 ? 100 : this.height; - this.buildDrawingCache(); - Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888); - - Canvas canvas = new Canvas(bitmap); - this.draw(canvas); - - return bitmap; - } - - public void setCalloutView(AirMapCallout view) { - this.calloutView = view; - } - - public AirMapCallout getCalloutView() { - return this.calloutView; - } - - public View getCallout() { - if (this.calloutView == null) return null; - - if (this.wrappedCalloutView == null) { - this.wrapCalloutView(); - } - - if (this.calloutView.getTooltip()) { - return this.wrappedCalloutView; - } else { - return null; - } - } - - public View getInfoContents() { - if (this.calloutView == null) return null; - - if (this.wrappedCalloutView == null) { - this.wrapCalloutView(); - } - - if (this.calloutView.getTooltip()) { - return null; - } else { - return this.wrappedCalloutView; + } finally { + dataSource.close(); + if (imageReference != null) { + CloseableReference.closeSafely(imageReference); + } + } + update(); } + }; + + public AirMapMarker(Context context) { + super(context); + this.context = context; + logoHolder = DraweeHolder.create(createDraweeHierarchy(), context); + logoHolder.onAttach(); + } + + private GenericDraweeHierarchy createDraweeHierarchy() { + return new GenericDraweeHierarchyBuilder(getResources()) + .setActualImageScaleType(ScalingUtils.ScaleType.FIT_CENTER) + .setFadeDuration(0) + .build(); + } + + public void setCoordinate(ReadableMap coordinate) { + position = new LatLng(coordinate.getDouble("latitude"), coordinate.getDouble("longitude")); + if (marker != null) { + marker.setPosition(position); + } + update(); + } + + public void setIdentifier(String identifier) { + this.identifier = identifier; + update(); + } + + public String getIdentifier() { + return this.identifier; + } + + public void setTitle(String title) { + this.title = title; + if (marker != null) { + marker.setTitle(title); + } + update(); + } + + public void setSnippet(String snippet) { + this.snippet = snippet; + if (marker != null) { + marker.setSnippet(snippet); + } + update(); + } + + public void setRotation(float rotation) { + this.rotation = rotation; + if (marker != null) { + marker.setRotation(rotation); + } + update(); + } + + public void setFlat(boolean flat) { + this.flat = flat; + if (marker != null) { + marker.setFlat(flat); + } + update(); + } + + public void setDraggable(boolean draggable) { + this.draggable = draggable; + if (marker != null) { + marker.setDraggable(draggable); + } + update(); + } + + public void setZIndex(int zIndex) { + this.zIndex = zIndex; + if (marker != null) { + marker.setZIndex(zIndex); + } + update(); + } + + public void setOpacity(float opacity) { + this.opacity = opacity; + if (marker != null) { + marker.setAlpha(opacity); + } + update(); + } + + public void setMarkerHue(float markerHue) { + this.markerHue = markerHue; + update(); + } + + public void setAnchor(double x, double y) { + anchorIsSet = true; + anchorX = (float) x; + anchorY = (float) y; + if (marker != null) { + marker.setAnchor(anchorX, anchorY); + } + update(); + } + + public void setCalloutAnchor(double x, double y) { + calloutAnchorIsSet = true; + calloutAnchorX = (float) x; + calloutAnchorY = (float) y; + if (marker != null) { + marker.setInfoWindowAnchor(calloutAnchorX, calloutAnchorY); + } + update(); + } + + public void setImage(String uri) { + if (uri == null) { + iconBitmapDescriptor = null; + update(); + } else if (uri.startsWith("http://") || uri.startsWith("https://") || + uri.startsWith("file://")) { + ImageRequest imageRequest = ImageRequestBuilder + .newBuilderWithSource(Uri.parse(uri)) + .build(); + + ImagePipeline imagePipeline = Fresco.getImagePipeline(); + dataSource = imagePipeline.fetchDecodedImage(imageRequest, this); + DraweeController controller = Fresco.newDraweeControllerBuilder() + .setImageRequest(imageRequest) + .setControllerListener(mLogoControllerListener) + .setOldController(logoHolder.getController()) + .build(); + logoHolder.setController(controller); + } else { + iconBitmapDescriptor = getBitmapDescriptorByName(uri); + update(); + } + } + + public MarkerOptions getMarkerOptions() { + if (markerOptions == null) { + markerOptions = createMarkerOptions(); + } + return markerOptions; + } + + @Override + public void addView(View child, int index) { + super.addView(child, index); + // if children are added, it means we are rendering a custom marker + if (!(child instanceof AirMapCallout)) { + hasCustomMarkerView = true; + } + update(); + } + + @Override + public Object getFeature() { + return marker; + } + + @Override + public void addToMap(GoogleMap map) { + marker = map.addMarker(getMarkerOptions()); + } + + @Override + public void removeFromMap(GoogleMap map) { + marker.remove(); + marker = null; + } + + private BitmapDescriptor getIcon() { + if (hasCustomMarkerView) { + // creating a bitmap from an arbitrary view + if (iconBitmapDescriptor != null) { + Bitmap viewBitmap = createDrawable(); + int width = Math.max(iconBitmap.getWidth(), viewBitmap.getWidth()); + int height = Math.max(iconBitmap.getHeight(), viewBitmap.getHeight()); + Bitmap combinedBitmap = Bitmap.createBitmap(width, height, iconBitmap.getConfig()); + Canvas canvas = new Canvas(combinedBitmap); + canvas.drawBitmap(iconBitmap, 0, 0, null); + canvas.drawBitmap(viewBitmap, 0, 0, null); + return BitmapDescriptorFactory.fromBitmap(combinedBitmap); + } else { + return BitmapDescriptorFactory.fromBitmap(createDrawable()); + } + } else if (iconBitmapDescriptor != null) { + // use local image as a marker + return iconBitmapDescriptor; + } else { + // render the default marker pin + return BitmapDescriptorFactory.defaultMarker(this.markerHue); + } + } + + private MarkerOptions createMarkerOptions() { + MarkerOptions options = new MarkerOptions().position(position); + if (anchorIsSet) options.anchor(anchorX, anchorY); + if (calloutAnchorIsSet) options.infoWindowAnchor(calloutAnchorX, calloutAnchorY); + options.title(title); + options.snippet(snippet); + options.rotation(rotation); + options.flat(flat); + options.draggable(draggable); + options.zIndex(zIndex); + options.alpha(opacity); + options.icon(getIcon()); + return options; + } + + public void update() { + if (marker == null) { + return; + } + + marker.setIcon(getIcon()); + + if (anchorIsSet) { + marker.setAnchor(anchorX, anchorY); + } else { + marker.setAnchor(0.5f, 1.0f); + } + + if (calloutAnchorIsSet) { + marker.setInfoWindowAnchor(calloutAnchorX, calloutAnchorY); + } else { + marker.setInfoWindowAnchor(0.5f, 0); + } + } + + public void update(int width, int height) { + this.width = width; + this.height = height; + update(); + } + + private Bitmap createDrawable() { + int width = this.width <= 0 ? 100 : this.width; + int height = this.height <= 0 ? 100 : this.height; + this.buildDrawingCache(); + Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888); + + Canvas canvas = new Canvas(bitmap); + this.draw(canvas); + + return bitmap; + } + + public void setCalloutView(AirMapCallout view) { + this.calloutView = view; + } + + public AirMapCallout getCalloutView() { + return this.calloutView; + } + + public View getCallout() { + if (this.calloutView == null) return null; + + if (this.wrappedCalloutView == null) { + this.wrapCalloutView(); + } + + if (this.calloutView.getTooltip()) { + return this.wrappedCalloutView; + } else { + return null; + } + } + + public View getInfoContents() { + if (this.calloutView == null) return null; + + if (this.wrappedCalloutView == null) { + this.wrapCalloutView(); + } + + if (this.calloutView.getTooltip()) { + return null; + } else { + return this.wrappedCalloutView; + } + } + + private void wrapCalloutView() { + // some hackery is needed to get the arbitrary infowindow view to render centered, and + // with only the width/height that it needs. + if (this.calloutView == null || this.calloutView.getChildCount() == 0) { + return; } - private void wrapCalloutView() { - // some hackery is needed to get the arbitrary infowindow view to render centered, and - // with only the width/height that it needs. - if (this.calloutView == null || this.calloutView.getChildCount() == 0) { - return; - } + LinearLayout LL = new LinearLayout(context); + LL.setOrientation(LinearLayout.VERTICAL); + LL.setLayoutParams(new LinearLayout.LayoutParams( + this.calloutView.width, + this.calloutView.height, + 0f + )); - LinearLayout LL = new LinearLayout(context); - LL.setOrientation(LinearLayout.VERTICAL); - LL.setLayoutParams(new LinearLayout.LayoutParams( - this.calloutView.width, - this.calloutView.height, - 0f - )); + LinearLayout LL2 = new LinearLayout(context); + LL2.setOrientation(LinearLayout.HORIZONTAL); + LL2.setLayoutParams(new LinearLayout.LayoutParams( + this.calloutView.width, + this.calloutView.height, + 0f + )); - LinearLayout LL2 = new LinearLayout(context); - LL2.setOrientation(LinearLayout.HORIZONTAL); - LL2.setLayoutParams(new LinearLayout.LayoutParams( - this.calloutView.width, - this.calloutView.height, - 0f - )); + LL.addView(LL2); + LL2.addView(this.calloutView); - LL.addView(LL2); - LL2.addView(this.calloutView); + this.wrappedCalloutView = LL; + } - this.wrappedCalloutView = LL; - } + private int getDrawableResourceByName(String name) { + return getResources().getIdentifier( + name, + "drawable", + getContext().getPackageName()); + } - private int getDrawableResourceByName(String name) { - return getResources().getIdentifier( - name, - "drawable", - getContext().getPackageName()); - } - - private BitmapDescriptor getBitmapDescriptorByName(String name) { - return BitmapDescriptorFactory.fromResource(getDrawableResourceByName(name)); - } + private BitmapDescriptor getBitmapDescriptorByName(String name) { + return BitmapDescriptorFactory.fromResource(getDrawableResourceByName(name)); + } } diff --git a/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapMarkerManager.java b/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapMarkerManager.java index e035e1e14..3aef3148c 100644 --- a/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapMarkerManager.java +++ b/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapMarkerManager.java @@ -19,46 +19,46 @@ public class AirMapMarkerManager extends ViewGroupManager { - private static final int SHOW_INFO_WINDOW = 1; - private static final int HIDE_INFO_WINDOW = 2; - - public AirMapMarkerManager() { - } - - @Override - public String getName() { - return "AIRMapMarker"; - } - - @Override - public AirMapMarker createViewInstance(ThemedReactContext context) { - return new AirMapMarker(context); - } - - @ReactProp(name = "coordinate") - public void setCoordinate(AirMapMarker view, ReadableMap map) { - view.setCoordinate(map); - } - - @ReactProp(name = "title") - public void setTitle(AirMapMarker view, String title) { - view.setTitle(title); - } - - @ReactProp(name = "identifier") - public void setIdentifier(AirMapMarker view, String identifier) { - view.setIdentifier(identifier); - } - - @ReactProp(name = "description") - public void setDescription(AirMapMarker view, String description) { - view.setSnippet(description); - } - - // NOTE(lmr): - // android uses normalized coordinate systems for this, and is provided through the - // `anchor` property and `calloutAnchor` instead. Perhaps some work could be done - // to normalize iOS and android to use just one of the systems. + private static final int SHOW_INFO_WINDOW = 1; + private static final int HIDE_INFO_WINDOW = 2; + + public AirMapMarkerManager() { + } + + @Override + public String getName() { + return "AIRMapMarker"; + } + + @Override + public AirMapMarker createViewInstance(ThemedReactContext context) { + return new AirMapMarker(context); + } + + @ReactProp(name = "coordinate") + public void setCoordinate(AirMapMarker view, ReadableMap map) { + view.setCoordinate(map); + } + + @ReactProp(name = "title") + public void setTitle(AirMapMarker view, String title) { + view.setTitle(title); + } + + @ReactProp(name = "identifier") + public void setIdentifier(AirMapMarker view, String identifier) { + view.setIdentifier(identifier); + } + + @ReactProp(name = "description") + public void setDescription(AirMapMarker view, String description) { + view.setSnippet(description); + } + + // NOTE(lmr): + // android uses normalized coordinate systems for this, and is provided through the + // `anchor` property and `calloutAnchor` instead. Perhaps some work could be done + // to normalize iOS and android to use just one of the systems. // @ReactProp(name = "centerOffset") // public void setCenterOffset(AirMapMarker view, ReadableMap map) { // @@ -69,143 +69,143 @@ public void setDescription(AirMapMarker view, String description) { // // } - @ReactProp(name = "anchor") - public void setAnchor(AirMapMarker view, ReadableMap map) { - // should default to (0.5, 1) (bottom middle) - double x = map != null && map.hasKey("x") ? map.getDouble("x") : 0.5; - double y = map != null && map.hasKey("y") ? map.getDouble("y") : 1.0; - view.setAnchor(x, y); - } - - @ReactProp(name = "calloutAnchor") - public void setCalloutAnchor(AirMapMarker view, ReadableMap map) { - // should default to (0.5, 0) (top middle) - double x = map != null && map.hasKey("x") ? map.getDouble("x") : 0.5; - double y = map != null && map.hasKey("y") ? map.getDouble("y") : 0.0; - view.setCalloutAnchor(x, y); - } - - @ReactProp(name = "image") - public void setImage(AirMapMarker view, @Nullable String source) { - view.setImage(source); - } + @ReactProp(name = "anchor") + public void setAnchor(AirMapMarker view, ReadableMap map) { + // should default to (0.5, 1) (bottom middle) + double x = map != null && map.hasKey("x") ? map.getDouble("x") : 0.5; + double y = map != null && map.hasKey("y") ? map.getDouble("y") : 1.0; + view.setAnchor(x, y); + } + + @ReactProp(name = "calloutAnchor") + public void setCalloutAnchor(AirMapMarker view, ReadableMap map) { + // should default to (0.5, 0) (top middle) + double x = map != null && map.hasKey("x") ? map.getDouble("x") : 0.5; + double y = map != null && map.hasKey("y") ? map.getDouble("y") : 0.0; + view.setCalloutAnchor(x, y); + } + + @ReactProp(name = "image") + public void setImage(AirMapMarker view, @Nullable String source) { + view.setImage(source); + } // public void setImage(AirMapMarker view, ReadableMap image) { // view.setImage(image); // } - @ReactProp(name = "pinColor", defaultInt = Color.RED, customType = "Color") - public void setPinColor(AirMapMarker view, int pinColor) { - float[] hsv = new float[3]; - Color.colorToHSV(pinColor, hsv); - // NOTE: android only supports a hue - view.setMarkerHue(hsv[0]); - } - - @ReactProp(name = "rotation", defaultFloat = 0.0f) - public void setMarkerRotation(AirMapMarker view, float rotation) { - view.setRotation(rotation); - } - - @ReactProp(name = "flat", defaultBoolean = false) - public void setFlat(AirMapMarker view, boolean flat) { - view.setFlat(flat); - } - - @ReactProp(name = "draggable", defaultBoolean = false) - public void setDraggable(AirMapMarker view, boolean draggable) { - view.setDraggable(draggable); - } - - @Override - @ReactProp(name = "zIndex", defaultFloat = 0.0f) - public void setZIndex(AirMapMarker view, float zIndex) { - super.setZIndex(view, zIndex); - int integerZIndex = Math.round(zIndex); - view.setZIndex(integerZIndex); - } - - @Override - @ReactProp(name = "opacity", defaultFloat = 1.0f) - public void setOpacity(AirMapMarker view, float opacity) { - super.setOpacity(view, opacity); - view.setOpacity(opacity); - } - - @Override - public void addView(AirMapMarker parent, View child, int index) { - // if an component is a child, then it is a callout view, NOT part of the - // marker. - if (child instanceof AirMapCallout) { - parent.setCalloutView((AirMapCallout) child); - } else { - super.addView(parent, child, index); - parent.update(); - } - } - - @Override - public void removeViewAt(AirMapMarker parent, int index) { - super.removeViewAt(parent, index); - parent.update(); - } - - @Override - @Nullable - public Map getCommandsMap() { - return MapBuilder.of( - "showCallout", SHOW_INFO_WINDOW, - "hideCallout", HIDE_INFO_WINDOW - ); - } - - @Override - public void receiveCommand(AirMapMarker view, int commandId, @Nullable ReadableArray args) { - switch (commandId) { - case SHOW_INFO_WINDOW: - ((Marker) view.getFeature()).showInfoWindow(); - break; - - case HIDE_INFO_WINDOW: - ((Marker) view.getFeature()).hideInfoWindow(); - break; - } - } - - @Override - @Nullable - public Map getExportedCustomDirectEventTypeConstants() { - Map> map = MapBuilder.of( - "onPress", MapBuilder.of("registrationName", "onPress"), - "onCalloutPress", MapBuilder.of("registrationName", "onCalloutPress"), - "onDragStart", MapBuilder.of("registrationName", "onDragStart"), - "onDrag", MapBuilder.of("registrationName", "onDrag"), - "onDragEnd", MapBuilder.of("registrationName", "onDragEnd") - ); - - map.putAll(MapBuilder.of( - "onDragStart", MapBuilder.of("registrationName", "onDragStart"), - "onDrag", MapBuilder.of("registrationName", "onDrag"), - "onDragEnd", MapBuilder.of("registrationName", "onDragEnd") - )); - - return map; - } - - @Override - public LayoutShadowNode createShadowNodeInstance() { - // we use a custom shadow node that emits the width/height of the view - // after layout with the updateExtraData method. Without this, we can't generate - // a bitmap of the appropriate width/height of the rendered view. - return new SizeReportingShadowNode(); - } - - @Override - public void updateExtraData(AirMapMarker view, Object extraData) { - // This method is called from the shadow node with the width/height of the rendered - // marker view. - HashMap data = (HashMap) extraData; - float width = data.get("width"); - float height = data.get("height"); - view.update((int) width, (int) height); - } + @ReactProp(name = "pinColor", defaultInt = Color.RED, customType = "Color") + public void setPinColor(AirMapMarker view, int pinColor) { + float[] hsv = new float[3]; + Color.colorToHSV(pinColor, hsv); + // NOTE: android only supports a hue + view.setMarkerHue(hsv[0]); + } + + @ReactProp(name = "rotation", defaultFloat = 0.0f) + public void setMarkerRotation(AirMapMarker view, float rotation) { + view.setRotation(rotation); + } + + @ReactProp(name = "flat", defaultBoolean = false) + public void setFlat(AirMapMarker view, boolean flat) { + view.setFlat(flat); + } + + @ReactProp(name = "draggable", defaultBoolean = false) + public void setDraggable(AirMapMarker view, boolean draggable) { + view.setDraggable(draggable); + } + + @Override + @ReactProp(name = "zIndex", defaultFloat = 0.0f) + public void setZIndex(AirMapMarker view, float zIndex) { + super.setZIndex(view, zIndex); + int integerZIndex = Math.round(zIndex); + view.setZIndex(integerZIndex); + } + + @Override + @ReactProp(name = "opacity", defaultFloat = 1.0f) + public void setOpacity(AirMapMarker view, float opacity) { + super.setOpacity(view, opacity); + view.setOpacity(opacity); + } + + @Override + public void addView(AirMapMarker parent, View child, int index) { + // if an component is a child, then it is a callout view, NOT part of the + // marker. + if (child instanceof AirMapCallout) { + parent.setCalloutView((AirMapCallout) child); + } else { + super.addView(parent, child, index); + parent.update(); + } + } + + @Override + public void removeViewAt(AirMapMarker parent, int index) { + super.removeViewAt(parent, index); + parent.update(); + } + + @Override + @Nullable + public Map getCommandsMap() { + return MapBuilder.of( + "showCallout", SHOW_INFO_WINDOW, + "hideCallout", HIDE_INFO_WINDOW + ); + } + + @Override + public void receiveCommand(AirMapMarker view, int commandId, @Nullable ReadableArray args) { + switch (commandId) { + case SHOW_INFO_WINDOW: + ((Marker) view.getFeature()).showInfoWindow(); + break; + + case HIDE_INFO_WINDOW: + ((Marker) view.getFeature()).hideInfoWindow(); + break; + } + } + + @Override + @Nullable + public Map getExportedCustomDirectEventTypeConstants() { + Map> map = MapBuilder.of( + "onPress", MapBuilder.of("registrationName", "onPress"), + "onCalloutPress", MapBuilder.of("registrationName", "onCalloutPress"), + "onDragStart", MapBuilder.of("registrationName", "onDragStart"), + "onDrag", MapBuilder.of("registrationName", "onDrag"), + "onDragEnd", MapBuilder.of("registrationName", "onDragEnd") + ); + + map.putAll(MapBuilder.of( + "onDragStart", MapBuilder.of("registrationName", "onDragStart"), + "onDrag", MapBuilder.of("registrationName", "onDrag"), + "onDragEnd", MapBuilder.of("registrationName", "onDragEnd") + )); + + return map; + } + + @Override + public LayoutShadowNode createShadowNodeInstance() { + // we use a custom shadow node that emits the width/height of the view + // after layout with the updateExtraData method. Without this, we can't generate + // a bitmap of the appropriate width/height of the rendered view. + return new SizeReportingShadowNode(); + } + + @Override + public void updateExtraData(AirMapMarker view, Object extraData) { + // This method is called from the shadow node with the width/height of the rendered + // marker view. + HashMap data = (HashMap) extraData; + float width = data.get("width"); + float height = data.get("height"); + view.update((int) width, (int) height); + } } diff --git a/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapModule.java b/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapModule.java index 80746a0f1..1a096255e 100644 --- a/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapModule.java +++ b/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapModule.java @@ -1,128 +1,127 @@ package com.airbnb.android.react.maps; import android.app.Activity; -import android.util.DisplayMetrics; -import android.util.Base64; import android.graphics.Bitmap; import android.net.Uri; -import android.view.View; - -import java.io.File; -import java.io.FileOutputStream; -import java.io.OutputStream; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.Closeable; - -import javax.annotation.Nullable; +import android.util.Base64; +import android.util.DisplayMetrics; +import com.facebook.react.bridge.Promise; import com.facebook.react.bridge.ReactApplicationContext; import com.facebook.react.bridge.ReactContextBaseJavaModule; -import com.facebook.react.bridge.ReadableMap; -import com.facebook.react.bridge.Promise; import com.facebook.react.bridge.ReactMethod; -import com.facebook.react.uimanager.UIManagerModule; -import com.facebook.react.uimanager.UIBlock; +import com.facebook.react.bridge.ReadableMap; import com.facebook.react.uimanager.NativeViewHierarchyManager; - +import com.facebook.react.uimanager.UIBlock; +import com.facebook.react.uimanager.UIManagerModule; import com.google.android.gms.maps.GoogleMap; -public class AirMapModule extends ReactContextBaseJavaModule { - - private static final String SNAPSHOT_RESULT_FILE = "file"; - private static final String SNAPSHOT_RESULT_BASE64 = "base64"; - private static final String SNAPSHOT_FORMAT_PNG = "png"; - private static final String SNAPSHOT_FORMAT_JPG = "jpg"; - - public AirMapModule(ReactApplicationContext reactContext) { - super(reactContext); - } +import java.io.ByteArrayOutputStream; +import java.io.Closeable; +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; - @Override - public String getName() { - return "AirMapModule"; - } +import javax.annotation.Nullable; - public Activity getActivity() { - return getCurrentActivity(); - } +public class AirMapModule extends ReactContextBaseJavaModule { - public static void closeQuietly(Closeable closeable) { - if (closeable == null) return; - try { - closeable.close(); - } catch (IOException ignored) { - } + private static final String SNAPSHOT_RESULT_FILE = "file"; + private static final String SNAPSHOT_RESULT_BASE64 = "base64"; + private static final String SNAPSHOT_FORMAT_PNG = "png"; + private static final String SNAPSHOT_FORMAT_JPG = "jpg"; + + public AirMapModule(ReactApplicationContext reactContext) { + super(reactContext); + } + + @Override + public String getName() { + return "AirMapModule"; + } + + public Activity getActivity() { + return getCurrentActivity(); + } + + public static void closeQuietly(Closeable closeable) { + if (closeable == null) return; + try { + closeable.close(); + } catch (IOException ignored) { } + } - @ReactMethod - public void takeSnapshot(final int tag, final ReadableMap options, final Promise promise) { + @ReactMethod + public void takeSnapshot(final int tag, final ReadableMap options, final Promise promise) { - // Parse and verity options - final ReactApplicationContext context = getReactApplicationContext(); - final String format = options.hasKey("format") ? options.getString("format") : "png"; - final Bitmap.CompressFormat compressFormat = - format.equals(SNAPSHOT_FORMAT_PNG) ? Bitmap.CompressFormat.PNG : + // Parse and verity options + final ReactApplicationContext context = getReactApplicationContext(); + final String format = options.hasKey("format") ? options.getString("format") : "png"; + final Bitmap.CompressFormat compressFormat = + format.equals(SNAPSHOT_FORMAT_PNG) ? Bitmap.CompressFormat.PNG : format.equals(SNAPSHOT_FORMAT_JPG) ? Bitmap.CompressFormat.JPEG : null; - final double quality = options.hasKey("quality") ? options.getDouble("quality") : 1.0; - final DisplayMetrics displayMetrics = context.getResources().getDisplayMetrics(); - final Integer width = options.hasKey("width") ? (int)(displayMetrics.density * options.getDouble("width")) : 0; - final Integer height = options.hasKey("height") ? (int)(displayMetrics.density * options.getDouble("height")) : 0; - final String result = options.hasKey("result") ? options.getString("result") : "file"; - - // Add UI-block so we can get a valid reference to the map-view - UIManagerModule uiManager = context.getNativeModule(UIManagerModule.class); - uiManager.addUIBlock(new UIBlock() { - public void execute (NativeViewHierarchyManager nvhm) { - AirMapView view = (AirMapView) nvhm.resolveView(tag); - if (view == null) { - promise.reject("AirMapView not found"); - return; - } - if (view.map == null) { - promise.reject("AirMapView.map is not valid"); - return; - } - view.map.snapshot(new GoogleMap.SnapshotReadyCallback() { - public void onSnapshotReady(@Nullable Bitmap snapshot) { + final double quality = options.hasKey("quality") ? options.getDouble("quality") : 1.0; + final DisplayMetrics displayMetrics = context.getResources().getDisplayMetrics(); + final Integer width = + options.hasKey("width") ? (int) (displayMetrics.density * options.getDouble("width")) : 0; + final Integer height = + options.hasKey("height") ? (int) (displayMetrics.density * options.getDouble("height")) : 0; + final String result = options.hasKey("result") ? options.getString("result") : "file"; + + // Add UI-block so we can get a valid reference to the map-view + UIManagerModule uiManager = context.getNativeModule(UIManagerModule.class); + uiManager.addUIBlock(new UIBlock() { + public void execute(NativeViewHierarchyManager nvhm) { + AirMapView view = (AirMapView) nvhm.resolveView(tag); + if (view == null) { + promise.reject("AirMapView not found"); + return; + } + if (view.map == null) { + promise.reject("AirMapView.map is not valid"); + return; + } + view.map.snapshot(new GoogleMap.SnapshotReadyCallback() { + public void onSnapshotReady(@Nullable Bitmap snapshot) { - // Convert image to requested width/height if necessary - if (snapshot == null) { - promise.reject("Failed to generate bitmap, snapshot = null"); - return; - } - if ((width != 0) && (height != 0) && (width != snapshot.getWidth() || height != snapshot.getHeight())) { - snapshot = Bitmap.createScaledBitmap(snapshot, width, height, true); - } + // Convert image to requested width/height if necessary + if (snapshot == null) { + promise.reject("Failed to generate bitmap, snapshot = null"); + return; + } + if ((width != 0) && (height != 0) && + (width != snapshot.getWidth() || height != snapshot.getHeight())) { + snapshot = Bitmap.createScaledBitmap(snapshot, width, height, true); + } - // Save the snapshot to disk - if (result.equals(SNAPSHOT_RESULT_FILE)) { - File tempFile; - FileOutputStream outputStream; - try { - tempFile = File.createTempFile("AirMapSnapshot", "." + format, context.getCacheDir()); - outputStream = new FileOutputStream(tempFile); - } - catch (Exception e) { - promise.reject(e); - return; - } - snapshot.compress(compressFormat, (int)(100.0 * quality), outputStream); - closeQuietly(outputStream); - String uri = Uri.fromFile(tempFile).toString(); - promise.resolve(uri); - } - else if (result.equals(SNAPSHOT_RESULT_BASE64)) { - ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); - snapshot.compress(compressFormat, (int)(100.0 * quality), outputStream); - closeQuietly(outputStream); - byte[] bytes = outputStream.toByteArray(); - String data = Base64.encodeToString(bytes, Base64.NO_WRAP); - promise.resolve(data); - } - } - }); + // Save the snapshot to disk + if (result.equals(SNAPSHOT_RESULT_FILE)) { + File tempFile; + FileOutputStream outputStream; + try { + tempFile = + File.createTempFile("AirMapSnapshot", "." + format, context.getCacheDir()); + outputStream = new FileOutputStream(tempFile); + } catch (Exception e) { + promise.reject(e); + return; + } + snapshot.compress(compressFormat, (int) (100.0 * quality), outputStream); + closeQuietly(outputStream); + String uri = Uri.fromFile(tempFile).toString(); + promise.resolve(uri); + } else if (result.equals(SNAPSHOT_RESULT_BASE64)) { + ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + snapshot.compress(compressFormat, (int) (100.0 * quality), outputStream); + closeQuietly(outputStream); + byte[] bytes = outputStream.toByteArray(); + String data = Base64.encodeToString(bytes, Base64.NO_WRAP); + promise.resolve(data); } + } }); - } + } + }); + } } diff --git a/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapPolygon.java b/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapPolygon.java index 226bc241c..41257b32e 100644 --- a/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapPolygon.java +++ b/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapPolygon.java @@ -14,99 +14,99 @@ public class AirMapPolygon extends AirMapFeature { - private PolygonOptions polygonOptions; - private Polygon polygon; - - private List coordinates; - private int strokeColor; - private int fillColor; - private float strokeWidth; - private boolean geodesic; - private float zIndex; - - public AirMapPolygon(Context context) { - super(context); + private PolygonOptions polygonOptions; + private Polygon polygon; + + private List coordinates; + private int strokeColor; + private int fillColor; + private float strokeWidth; + private boolean geodesic; + private float zIndex; + + public AirMapPolygon(Context context) { + super(context); + } + + public void setCoordinates(ReadableArray coordinates) { + // it's kind of a bummer that we can't run map() or anything on the ReadableArray + this.coordinates = new ArrayList<>(coordinates.size()); + for (int i = 0; i < coordinates.size(); i++) { + ReadableMap coordinate = coordinates.getMap(i); + this.coordinates.add(i, + new LatLng(coordinate.getDouble("latitude"), coordinate.getDouble("longitude"))); } - - public void setCoordinates(ReadableArray coordinates) { - // it's kind of a bummer that we can't run map() or anything on the ReadableArray - this.coordinates = new ArrayList<>(coordinates.size()); - for (int i = 0; i < coordinates.size(); i++) { - ReadableMap coordinate = coordinates.getMap(i); - this.coordinates.add(i, - new LatLng(coordinate.getDouble("latitude"), coordinate.getDouble("longitude"))); - } - if (polygon != null) { - polygon.setPoints(this.coordinates); - } - } - - public void setFillColor(int color) { - this.fillColor = color; - if (polygon != null) { - polygon.setFillColor(color); - } - } - - public void setStrokeColor(int color) { - this.strokeColor = color; - if (polygon != null) { - polygon.setStrokeColor(color); - } - } - - public void setStrokeWidth(float width) { - this.strokeWidth = width; - if (polygon != null) { - polygon.setStrokeWidth(width); - } - } - - public void setGeodesic(boolean geodesic) { - this.geodesic = geodesic; - if (polygon != null) { - polygon.setGeodesic(geodesic); - } + if (polygon != null) { + polygon.setPoints(this.coordinates); } + } - public void setZIndex(float zIndex) { - this.zIndex = zIndex; - if (polygon != null) { - polygon.setZIndex(zIndex); - } + public void setFillColor(int color) { + this.fillColor = color; + if (polygon != null) { + polygon.setFillColor(color); } + } - public PolygonOptions getPolygonOptions() { - if (polygonOptions == null) { - polygonOptions = createPolygonOptions(); - } - return polygonOptions; + public void setStrokeColor(int color) { + this.strokeColor = color; + if (polygon != null) { + polygon.setStrokeColor(color); } + } - private PolygonOptions createPolygonOptions() { - PolygonOptions options = new PolygonOptions(); - options.addAll(coordinates); - options.fillColor(fillColor); - options.strokeColor(strokeColor); - options.strokeWidth(strokeWidth); - options.geodesic(geodesic); - options.zIndex(zIndex); - return options; + public void setStrokeWidth(float width) { + this.strokeWidth = width; + if (polygon != null) { + polygon.setStrokeWidth(width); } + } - @Override - public Object getFeature() { - return polygon; + public void setGeodesic(boolean geodesic) { + this.geodesic = geodesic; + if (polygon != null) { + polygon.setGeodesic(geodesic); } + } - @Override - public void addToMap(GoogleMap map) { - polygon = map.addPolygon(getPolygonOptions()); - polygon.setClickable(true); + public void setZIndex(float zIndex) { + this.zIndex = zIndex; + if (polygon != null) { + polygon.setZIndex(zIndex); } + } - @Override - public void removeFromMap(GoogleMap map) { - polygon.remove(); + public PolygonOptions getPolygonOptions() { + if (polygonOptions == null) { + polygonOptions = createPolygonOptions(); } + return polygonOptions; + } + + private PolygonOptions createPolygonOptions() { + PolygonOptions options = new PolygonOptions(); + options.addAll(coordinates); + options.fillColor(fillColor); + options.strokeColor(strokeColor); + options.strokeWidth(strokeWidth); + options.geodesic(geodesic); + options.zIndex(zIndex); + return options; + } + + @Override + public Object getFeature() { + return polygon; + } + + @Override + public void addToMap(GoogleMap map) { + polygon = map.addPolygon(getPolygonOptions()); + polygon.setClickable(true); + } + + @Override + public void removeFromMap(GoogleMap map) { + polygon.remove(); + } } diff --git a/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapPolygonManager.java b/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapPolygonManager.java index 3eaa0e550..6f1605758 100644 --- a/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapPolygonManager.java +++ b/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapPolygonManager.java @@ -13,71 +13,71 @@ import com.facebook.react.uimanager.ViewGroupManager; import com.facebook.react.uimanager.annotations.ReactProp; -import java.util.HashMap; import java.util.Map; + import javax.annotation.Nullable; public class AirMapPolygonManager extends ViewGroupManager { - private final DisplayMetrics metrics; + private final DisplayMetrics metrics; - public AirMapPolygonManager(ReactApplicationContext reactContext) { - super(); - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) { - metrics = new DisplayMetrics(); - ((WindowManager) reactContext.getSystemService(Context.WINDOW_SERVICE)) - .getDefaultDisplay() - .getRealMetrics(metrics); - } else { - metrics = reactContext.getResources().getDisplayMetrics(); - } + public AirMapPolygonManager(ReactApplicationContext reactContext) { + super(); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) { + metrics = new DisplayMetrics(); + ((WindowManager) reactContext.getSystemService(Context.WINDOW_SERVICE)) + .getDefaultDisplay() + .getRealMetrics(metrics); + } else { + metrics = reactContext.getResources().getDisplayMetrics(); } + } - @Override - public String getName() { - return "AIRMapPolygon"; - } + @Override + public String getName() { + return "AIRMapPolygon"; + } - @Override - public AirMapPolygon createViewInstance(ThemedReactContext context) { - return new AirMapPolygon(context); - } + @Override + public AirMapPolygon createViewInstance(ThemedReactContext context) { + return new AirMapPolygon(context); + } - @ReactProp(name = "coordinates") - public void setCoordinate(AirMapPolygon view, ReadableArray coordinates) { - view.setCoordinates(coordinates); - } + @ReactProp(name = "coordinates") + public void setCoordinate(AirMapPolygon view, ReadableArray coordinates) { + view.setCoordinates(coordinates); + } - @ReactProp(name = "strokeWidth", defaultFloat = 1f) - public void setStrokeWidth(AirMapPolygon view, float widthInPoints) { - float widthInScreenPx = metrics.density * widthInPoints; // done for parity with iOS - view.setStrokeWidth(widthInScreenPx); - } + @ReactProp(name = "strokeWidth", defaultFloat = 1f) + public void setStrokeWidth(AirMapPolygon view, float widthInPoints) { + float widthInScreenPx = metrics.density * widthInPoints; // done for parity with iOS + view.setStrokeWidth(widthInScreenPx); + } - @ReactProp(name = "fillColor", defaultInt = Color.RED, customType = "Color") - public void setFillColor(AirMapPolygon view, int color) { - view.setFillColor(color); - } + @ReactProp(name = "fillColor", defaultInt = Color.RED, customType = "Color") + public void setFillColor(AirMapPolygon view, int color) { + view.setFillColor(color); + } - @ReactProp(name = "strokeColor", defaultInt = Color.RED, customType = "Color") - public void setStrokeColor(AirMapPolygon view, int color) { - view.setStrokeColor(color); - } + @ReactProp(name = "strokeColor", defaultInt = Color.RED, customType = "Color") + public void setStrokeColor(AirMapPolygon view, int color) { + view.setStrokeColor(color); + } - @ReactProp(name = "geodesic", defaultBoolean = false) - public void setGeodesic(AirMapPolygon view, boolean geodesic) { - view.setGeodesic(geodesic); - } + @ReactProp(name = "geodesic", defaultBoolean = false) + public void setGeodesic(AirMapPolygon view, boolean geodesic) { + view.setGeodesic(geodesic); + } - @ReactProp(name = "zIndex", defaultFloat = 1.0f) - public void setZIndex(AirMapPolygon view, float zIndex) { - view.setZIndex(zIndex); - } + @ReactProp(name = "zIndex", defaultFloat = 1.0f) + public void setZIndex(AirMapPolygon view, float zIndex) { + view.setZIndex(zIndex); + } - @Override - @Nullable - public Map getExportedCustomDirectEventTypeConstants() { - return MapBuilder.of( - "onPress", MapBuilder.of("registrationName", "onPress") - ); - } + @Override + @Nullable + public Map getExportedCustomDirectEventTypeConstants() { + return MapBuilder.of( + "onPress", MapBuilder.of("registrationName", "onPress") + ); + } } diff --git a/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapPolyline.java b/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapPolyline.java index 9a15fdc99..488e2972f 100644 --- a/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapPolyline.java +++ b/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapPolyline.java @@ -14,89 +14,89 @@ public class AirMapPolyline extends AirMapFeature { - private PolylineOptions polylineOptions; - private Polyline polyline; - - private List coordinates; - private int color; - private float width; - private boolean geodesic; - private float zIndex; - - public AirMapPolyline(Context context) { - super(context); - } - - public void setCoordinates(ReadableArray coordinates) { - this.coordinates = new ArrayList<>(coordinates.size()); - for (int i = 0; i < coordinates.size(); i++) { - ReadableMap coordinate = coordinates.getMap(i); - this.coordinates.add(i, - new LatLng(coordinate.getDouble("latitude"), coordinate.getDouble("longitude"))); - } - if (polyline != null) { - polyline.setPoints(this.coordinates); - } - } - - public void setColor(int color) { - this.color = color; - if (polyline != null) { - polyline.setColor(color); - } + private PolylineOptions polylineOptions; + private Polyline polyline; + + private List coordinates; + private int color; + private float width; + private boolean geodesic; + private float zIndex; + + public AirMapPolyline(Context context) { + super(context); + } + + public void setCoordinates(ReadableArray coordinates) { + this.coordinates = new ArrayList<>(coordinates.size()); + for (int i = 0; i < coordinates.size(); i++) { + ReadableMap coordinate = coordinates.getMap(i); + this.coordinates.add(i, + new LatLng(coordinate.getDouble("latitude"), coordinate.getDouble("longitude"))); } - - public void setWidth(float width) { - this.width = width; - if (polyline != null) { - polyline.setWidth(width); - } - } - - public void setZIndex(float zIndex) { - this.zIndex = zIndex; - if (polyline != null) { - polyline.setZIndex(zIndex); - } - } - - public void setGeodesic(boolean geodesic) { - this.geodesic = geodesic; - if (polyline != null) { - polyline.setGeodesic(geodesic); - } + if (polyline != null) { + polyline.setPoints(this.coordinates); } + } - public PolylineOptions getPolylineOptions() { - if (polylineOptions == null) { - polylineOptions = createPolylineOptions(); - } - return polylineOptions; + public void setColor(int color) { + this.color = color; + if (polyline != null) { + polyline.setColor(color); } + } - private PolylineOptions createPolylineOptions() { - PolylineOptions options = new PolylineOptions(); - options.addAll(coordinates); - options.color(color); - options.width(width); - options.geodesic(geodesic); - options.zIndex(zIndex); - return options; + public void setWidth(float width) { + this.width = width; + if (polyline != null) { + polyline.setWidth(width); } + } - @Override - public Object getFeature() { - return polyline; + public void setZIndex(float zIndex) { + this.zIndex = zIndex; + if (polyline != null) { + polyline.setZIndex(zIndex); } + } - @Override - public void addToMap(GoogleMap map) { - polyline = map.addPolyline(getPolylineOptions()); - polyline.setClickable(true); + public void setGeodesic(boolean geodesic) { + this.geodesic = geodesic; + if (polyline != null) { + polyline.setGeodesic(geodesic); } + } - @Override - public void removeFromMap(GoogleMap map) { - polyline.remove(); + public PolylineOptions getPolylineOptions() { + if (polylineOptions == null) { + polylineOptions = createPolylineOptions(); } + return polylineOptions; + } + + private PolylineOptions createPolylineOptions() { + PolylineOptions options = new PolylineOptions(); + options.addAll(coordinates); + options.color(color); + options.width(width); + options.geodesic(geodesic); + options.zIndex(zIndex); + return options; + } + + @Override + public Object getFeature() { + return polyline; + } + + @Override + public void addToMap(GoogleMap map) { + polyline = map.addPolyline(getPolylineOptions()); + polyline.setClickable(true); + } + + @Override + public void removeFromMap(GoogleMap map) { + polyline.remove(); + } } diff --git a/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapPolylineManager.java b/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapPolylineManager.java index c5afc61e0..be80acfbc 100644 --- a/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapPolylineManager.java +++ b/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapPolylineManager.java @@ -13,66 +13,66 @@ import com.facebook.react.uimanager.ViewGroupManager; import com.facebook.react.uimanager.annotations.ReactProp; -import java.util.HashMap; import java.util.Map; + import javax.annotation.Nullable; public class AirMapPolylineManager extends ViewGroupManager { - private final DisplayMetrics metrics; + private final DisplayMetrics metrics; - public AirMapPolylineManager(ReactApplicationContext reactContext) { - super(); - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) { - metrics = new DisplayMetrics(); - ((WindowManager) reactContext.getSystemService(Context.WINDOW_SERVICE)) - .getDefaultDisplay() - .getRealMetrics(metrics); - } else { - metrics = reactContext.getResources().getDisplayMetrics(); - } + public AirMapPolylineManager(ReactApplicationContext reactContext) { + super(); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) { + metrics = new DisplayMetrics(); + ((WindowManager) reactContext.getSystemService(Context.WINDOW_SERVICE)) + .getDefaultDisplay() + .getRealMetrics(metrics); + } else { + metrics = reactContext.getResources().getDisplayMetrics(); } + } - @Override - public String getName() { - return "AIRMapPolyline"; - } + @Override + public String getName() { + return "AIRMapPolyline"; + } - @Override - public AirMapPolyline createViewInstance(ThemedReactContext context) { - return new AirMapPolyline(context); - } + @Override + public AirMapPolyline createViewInstance(ThemedReactContext context) { + return new AirMapPolyline(context); + } - @ReactProp(name = "coordinates") - public void setCoordinate(AirMapPolyline view, ReadableArray coordinates) { - view.setCoordinates(coordinates); - } + @ReactProp(name = "coordinates") + public void setCoordinate(AirMapPolyline view, ReadableArray coordinates) { + view.setCoordinates(coordinates); + } - @ReactProp(name = "strokeWidth", defaultFloat = 1f) - public void setStrokeWidth(AirMapPolyline view, float widthInPoints) { - float widthInScreenPx = metrics.density * widthInPoints; // done for parity with iOS - view.setWidth(widthInScreenPx); - } + @ReactProp(name = "strokeWidth", defaultFloat = 1f) + public void setStrokeWidth(AirMapPolyline view, float widthInPoints) { + float widthInScreenPx = metrics.density * widthInPoints; // done for parity with iOS + view.setWidth(widthInScreenPx); + } - @ReactProp(name = "strokeColor", defaultInt = Color.RED, customType = "Color") - public void setStrokeColor(AirMapPolyline view, int color) { - view.setColor(color); - } + @ReactProp(name = "strokeColor", defaultInt = Color.RED, customType = "Color") + public void setStrokeColor(AirMapPolyline view, int color) { + view.setColor(color); + } - @ReactProp(name = "geodesic", defaultBoolean = false) - public void setGeodesic(AirMapPolyline view, boolean geodesic) { - view.setGeodesic(geodesic); - } + @ReactProp(name = "geodesic", defaultBoolean = false) + public void setGeodesic(AirMapPolyline view, boolean geodesic) { + view.setGeodesic(geodesic); + } - @ReactProp(name = "zIndex", defaultFloat = 1.0f) - public void setZIndex(AirMapPolyline view, float zIndex) { - view.setZIndex(zIndex); - } + @ReactProp(name = "zIndex", defaultFloat = 1.0f) + public void setZIndex(AirMapPolyline view, float zIndex) { + view.setZIndex(zIndex); + } - @Override - @Nullable - public Map getExportedCustomDirectEventTypeConstants() { - return MapBuilder.of( - "onPress", MapBuilder.of("registrationName", "onPress") - ); - } + @Override + @Nullable + public Map getExportedCustomDirectEventTypeConstants() { + return MapBuilder.of( + "onPress", MapBuilder.of("registrationName", "onPress") + ); + } } diff --git a/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapUrlTile.java b/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapUrlTile.java index 691c2fd3c..ae51a63b4 100644 --- a/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapUrlTile.java +++ b/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapUrlTile.java @@ -12,89 +12,90 @@ public class AirMapUrlTile extends AirMapFeature { - class AIRMapUrlTileProvider extends UrlTileProvider - { - private String urlTemplate; - public AIRMapUrlTileProvider(int width, int height, String urlTemplate) { - super(width, height); - this.urlTemplate = urlTemplate; - } - @Override - public synchronized URL getTileUrl(int x, int y, int zoom) { - - String s = this.urlTemplate - .replace("{x}", Integer.toString(x)) - .replace("{y}", Integer.toString(y)) - .replace("{z}", Integer.toString(zoom)); - URL url = null; - try { - url = new URL(s); - } catch (MalformedURLException e) { - throw new AssertionError(e); - } - return url; - } - - public void setUrlTemplate(String urlTemplate) { - this.urlTemplate = urlTemplate; - } - } - - private TileOverlayOptions tileOverlayOptions; - private TileOverlay tileOverlay; - private AIRMapUrlTileProvider tileProvider; - + class AIRMapUrlTileProvider extends UrlTileProvider { private String urlTemplate; - private float zIndex; - public AirMapUrlTile(Context context) { - super(context); + public AIRMapUrlTileProvider(int width, int height, String urlTemplate) { + super(width, height); + this.urlTemplate = urlTemplate; } - public void setUrlTemplate(String urlTemplate) { - this.urlTemplate = urlTemplate; - if (tileProvider != null) { - tileProvider.setUrlTemplate(urlTemplate); - } - if (tileOverlay != null) { - tileOverlay.clearTileCache(); - } + @Override + public synchronized URL getTileUrl(int x, int y, int zoom) { + + String s = this.urlTemplate + .replace("{x}", Integer.toString(x)) + .replace("{y}", Integer.toString(y)) + .replace("{z}", Integer.toString(zoom)); + URL url = null; + try { + url = new URL(s); + } catch (MalformedURLException e) { + throw new AssertionError(e); + } + return url; } - public void setZIndex(float zIndex) { - this.zIndex = zIndex; - if (tileOverlay != null) { - tileOverlay.setZIndex(zIndex); - } + public void setUrlTemplate(String urlTemplate) { + this.urlTemplate = urlTemplate; } + } - public TileOverlayOptions getTileOverlayOptions() { - if (tileOverlayOptions == null) { - tileOverlayOptions = createTileOverlayOptions(); - } - return tileOverlayOptions; - } + private TileOverlayOptions tileOverlayOptions; + private TileOverlay tileOverlay; + private AIRMapUrlTileProvider tileProvider; - private TileOverlayOptions createTileOverlayOptions() { - TileOverlayOptions options = new TileOverlayOptions(); - options.zIndex(zIndex); - this.tileProvider = new AIRMapUrlTileProvider(256, 256, this.urlTemplate); - options.tileProvider(this.tileProvider); - return options; - } + private String urlTemplate; + private float zIndex; - @Override - public Object getFeature() { - return tileOverlay; + public AirMapUrlTile(Context context) { + super(context); + } + + public void setUrlTemplate(String urlTemplate) { + this.urlTemplate = urlTemplate; + if (tileProvider != null) { + tileProvider.setUrlTemplate(urlTemplate); } + if (tileOverlay != null) { + tileOverlay.clearTileCache(); + } + } - @Override - public void addToMap(GoogleMap map) { - this.tileOverlay = map.addTileOverlay(getTileOverlayOptions()); + public void setZIndex(float zIndex) { + this.zIndex = zIndex; + if (tileOverlay != null) { + tileOverlay.setZIndex(zIndex); } + } - @Override - public void removeFromMap(GoogleMap map) { - tileOverlay.remove(); + public TileOverlayOptions getTileOverlayOptions() { + if (tileOverlayOptions == null) { + tileOverlayOptions = createTileOverlayOptions(); } + return tileOverlayOptions; + } + + private TileOverlayOptions createTileOverlayOptions() { + TileOverlayOptions options = new TileOverlayOptions(); + options.zIndex(zIndex); + this.tileProvider = new AIRMapUrlTileProvider(256, 256, this.urlTemplate); + options.tileProvider(this.tileProvider); + return options; + } + + @Override + public Object getFeature() { + return tileOverlay; + } + + @Override + public void addToMap(GoogleMap map) { + this.tileOverlay = map.addTileOverlay(getTileOverlayOptions()); + } + + @Override + public void removeFromMap(GoogleMap map) { + tileOverlay.remove(); + } } diff --git a/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapUrlTileManager.java b/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapUrlTileManager.java index 7ea0726dc..68bf07342 100644 --- a/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapUrlTileManager.java +++ b/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapUrlTileManager.java @@ -11,38 +11,38 @@ import com.facebook.react.uimanager.annotations.ReactProp; public class AirMapUrlTileManager extends ViewGroupManager { - private DisplayMetrics metrics; - - public AirMapUrlTileManager(ReactApplicationContext reactContext) { - super(); - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) { - metrics = new DisplayMetrics(); - ((WindowManager) reactContext.getSystemService(Context.WINDOW_SERVICE)) - .getDefaultDisplay() - .getRealMetrics(metrics); - } else { - metrics = reactContext.getResources().getDisplayMetrics(); - } - } - - @Override - public String getName() { - return "AIRMapUrlTile"; - } - - @Override - public AirMapUrlTile createViewInstance(ThemedReactContext context) { - return new AirMapUrlTile(context); - } - - @ReactProp(name = "urlTemplate") - public void setUrlTemplate(AirMapUrlTile view, String urlTemplate) { - view.setUrlTemplate(urlTemplate); - } - - @ReactProp(name = "zIndex", defaultFloat = -1.0f) - public void setZIndex(AirMapUrlTile view, float zIndex) { - view.setZIndex(zIndex); + private DisplayMetrics metrics; + + public AirMapUrlTileManager(ReactApplicationContext reactContext) { + super(); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) { + metrics = new DisplayMetrics(); + ((WindowManager) reactContext.getSystemService(Context.WINDOW_SERVICE)) + .getDefaultDisplay() + .getRealMetrics(metrics); + } else { + metrics = reactContext.getResources().getDisplayMetrics(); } + } + + @Override + public String getName() { + return "AIRMapUrlTile"; + } + + @Override + public AirMapUrlTile createViewInstance(ThemedReactContext context) { + return new AirMapUrlTile(context); + } + + @ReactProp(name = "urlTemplate") + public void setUrlTemplate(AirMapUrlTile view, String urlTemplate) { + view.setUrlTemplate(urlTemplate); + } + + @ReactProp(name = "zIndex", defaultFloat = -1.0f) + public void setZIndex(AirMapUrlTile view, float zIndex) { + view.setZIndex(zIndex); + } } diff --git a/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapView.java b/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapView.java index 725270ac6..11e578634 100644 --- a/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapView.java +++ b/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapView.java @@ -1,6 +1,5 @@ package com.airbnb.android.react.maps; -import android.app.Activity; import android.content.Context; import android.content.pm.PackageManager; import android.content.res.ColorStateList; @@ -54,801 +53,807 @@ import static android.support.v4.content.PermissionChecker.checkSelfPermission; public class AirMapView extends MapView implements GoogleMap.InfoWindowAdapter, - GoogleMap.OnMarkerDragListener, OnMapReadyCallback { - public GoogleMap map; - private ProgressBar mapLoadingProgressBar; - private RelativeLayout mapLoadingLayout; - private ImageView cacheImageView; - private Boolean isMapLoaded = false; - private Integer loadingBackgroundColor = null; - private Integer loadingIndicatorColor = null; - private final int baseMapPadding = 50; - - private LatLngBounds boundsToMove; - private boolean showUserLocation = false; - private boolean isMonitoringRegion = false; - private boolean isTouchDown = false; - private boolean handlePanDrag = false; - private boolean moveOnMarkerPress = true; - private boolean cacheEnabled = false; - - private static final String[] PERMISSIONS = new String[] { - "android.permission.ACCESS_FINE_LOCATION", "android.permission.ACCESS_COARSE_LOCATION"}; - - private final List features = new ArrayList<>(); - private final Map markerMap = new HashMap<>(); - private final Map polylineMap = new HashMap<>(); - private final Map polygonMap = new HashMap<>(); - private final ScaleGestureDetector scaleDetector; - private final GestureDetectorCompat gestureDetector; - private final AirMapManager manager; - private LifecycleEventListener lifecycleListener; - private boolean paused = false; - private boolean destroyed = false; - private final ThemedReactContext context; - private final EventDispatcher eventDispatcher; - - private static boolean contextHasBug(Context context) { - return context == null || - context.getResources() == null || - context.getResources().getConfiguration() == null; - } - - // We do this to fix this bug: - // https://github.com/airbnb/react-native-maps/issues/271 - // - // which conflicts with another bug regarding the passed in context: - // https://github.com/airbnb/react-native-maps/issues/1147 - // - // Doing this allows us to avoid both bugs. - private static Context getNonBuggyContext(ThemedReactContext reactContext, - ReactApplicationContext appContext) { - Context superContext = reactContext; - if (!contextHasBug(appContext.getCurrentActivity())) { - superContext = appContext.getCurrentActivity(); - } else if (contextHasBug(superContext)) { - // we have the bug! let's try to find a better context to use - if (!contextHasBug(reactContext.getCurrentActivity())) { - superContext = reactContext.getCurrentActivity(); - } else if (!contextHasBug(reactContext.getApplicationContext())) { - superContext = reactContext.getApplicationContext(); - } else { - // ¯\_(ツ)_/¯ - } - } - return superContext; - } - - public AirMapView(ThemedReactContext reactContext, ReactApplicationContext appContext, AirMapManager manager, - GoogleMapOptions googleMapOptions) { - super(getNonBuggyContext(reactContext, appContext), googleMapOptions); - - this.manager = manager; - this.context = reactContext; - - super.onCreate(null); - // TODO(lmr): what about onStart???? - super.onResume(); - super.getMapAsync(this); - - final AirMapView view = this; - scaleDetector = - new ScaleGestureDetector(reactContext, new ScaleGestureDetector.SimpleOnScaleGestureListener() { - @Override - public boolean onScaleBegin(ScaleGestureDetector detector) { - view.startMonitoringRegion(); - return true; // stop recording this gesture. let mapview handle it. - } - }); - - gestureDetector = - new GestureDetectorCompat(reactContext, new GestureDetector.SimpleOnGestureListener() { - @Override - public boolean onDoubleTap(MotionEvent e) { - view.startMonitoringRegion(); - return false; - } - - @Override - public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, - float distanceY) { - if (handlePanDrag) { - onPanDrag(e2); - } - view.startMonitoringRegion(); - return false; - } - }); - - this.addOnLayoutChangeListener(new OnLayoutChangeListener() { - @Override public void onLayoutChange(View v, int left, int top, int right, int bottom, - int oldLeft, int oldTop, int oldRight, int oldBottom) { - if (!paused) { - AirMapView.this.cacheView(); - } - } - }); - - eventDispatcher = reactContext.getNativeModule(UIManagerModule.class).getEventDispatcher(); - } - - @Override - public void onMapReady(final GoogleMap map) { - if (destroyed) { - return; - } - this.map = map; - this.map.setInfoWindowAdapter(this); - this.map.setOnMarkerDragListener(this); - - manager.pushEvent(context, this, "onMapReady", new WritableNativeMap()); - - final AirMapView view = this; - - map.setOnMarkerClickListener(new GoogleMap.OnMarkerClickListener() { - @Override - public boolean onMarkerClick(Marker marker) { - WritableMap event; - AirMapMarker airMapMarker = markerMap.get(marker); - - event = makeClickEventData(marker.getPosition()); - event.putString("action", "marker-press"); - event.putString("id", airMapMarker.getIdentifier()); - manager.pushEvent(context, view, "onMarkerPress", event); - - event = makeClickEventData(marker.getPosition()); - event.putString("action", "marker-press"); - event.putString("id", airMapMarker.getIdentifier()); - manager.pushEvent(context, markerMap.get(marker), "onPress", event); - - // Return false to open the callout info window and center on the marker - // https://developers.google.com/android/reference/com/google/android/gms/maps/GoogleMap.OnMarkerClickListener - if (view.moveOnMarkerPress) { - return false; - } else { - marker.showInfoWindow(); - return true; - } - } - }); - - map.setOnPolygonClickListener(new GoogleMap.OnPolygonClickListener() { - @Override - public void onPolygonClick(Polygon polygon) { - WritableMap event = makeClickEventData(polygon.getPoints().get(0)); - event.putString("action", "polygon-press"); - manager.pushEvent(context, polygonMap.get(polygon), "onPress", event); - } - }); - - map.setOnPolylineClickListener(new GoogleMap.OnPolylineClickListener() { - @Override - public void onPolylineClick(Polyline polyline) { - WritableMap event = makeClickEventData(polyline.getPoints().get(0)); - event.putString("action", "polyline-press"); - manager.pushEvent(context, polylineMap.get(polyline), "onPress", event); - } - }); - - map.setOnInfoWindowClickListener(new GoogleMap.OnInfoWindowClickListener() { - @Override - public void onInfoWindowClick(Marker marker) { - WritableMap event; - - event = makeClickEventData(marker.getPosition()); - event.putString("action", "callout-press"); - manager.pushEvent(context, view, "onCalloutPress", event); - - event = makeClickEventData(marker.getPosition()); - event.putString("action", "callout-press"); - AirMapMarker markerView = markerMap.get(marker); - manager.pushEvent(context, markerView, "onCalloutPress", event); - - event = makeClickEventData(marker.getPosition()); - event.putString("action", "callout-press"); - AirMapCallout infoWindow = markerView.getCalloutView(); - if (infoWindow != null) manager.pushEvent(context, infoWindow, "onPress", event); - } - }); - - map.setOnMapClickListener(new GoogleMap.OnMapClickListener() { - @Override - public void onMapClick(LatLng point) { - WritableMap event = makeClickEventData(point); - event.putString("action", "press"); - manager.pushEvent(context, view, "onPress", event); - } - }); - - map.setOnMapLongClickListener(new GoogleMap.OnMapLongClickListener() { - @Override - public void onMapLongClick(LatLng point) { - WritableMap event = makeClickEventData(point); - event.putString("action", "long-press"); - manager.pushEvent(context, view, "onLongPress", makeClickEventData(point)); - } - }); - - map.setOnCameraChangeListener(new GoogleMap.OnCameraChangeListener() { - @Override - public void onCameraChange(CameraPosition position) { - LatLngBounds bounds = map.getProjection().getVisibleRegion().latLngBounds; - LatLng center = position.target; - lastBoundsEmitted = bounds; - eventDispatcher.dispatchEvent(new RegionChangeEvent(getId(), bounds, center, isTouchDown)); - view.stopMonitoringRegion(); - } - }); - - map.setOnMapLoadedCallback(new GoogleMap.OnMapLoadedCallback() { - @Override public void onMapLoaded() { - isMapLoaded = true; - AirMapView.this.cacheView(); - } - }); - - // We need to be sure to disable location-tracking when app enters background, in-case some - // other module - // has acquired a wake-lock and is controlling location-updates, otherwise, location-manager - // will be left - // updating location constantly, killing the battery, even though some other location-mgmt - // module may - // desire to shut-down location-services. - lifecycleListener = new LifecycleEventListener() { - @Override - public void onHostResume() { - if (hasPermissions()) { - //noinspection MissingPermission - map.setMyLocationEnabled(showUserLocation); - } - synchronized (AirMapView.this) { - AirMapView.this.onResume(); - paused = false; + GoogleMap.OnMarkerDragListener, OnMapReadyCallback { + public GoogleMap map; + private ProgressBar mapLoadingProgressBar; + private RelativeLayout mapLoadingLayout; + private ImageView cacheImageView; + private Boolean isMapLoaded = false; + private Integer loadingBackgroundColor = null; + private Integer loadingIndicatorColor = null; + private final int baseMapPadding = 50; + + private LatLngBounds boundsToMove; + private boolean showUserLocation = false; + private boolean isMonitoringRegion = false; + private boolean isTouchDown = false; + private boolean handlePanDrag = false; + private boolean moveOnMarkerPress = true; + private boolean cacheEnabled = false; + + private static final String[] PERMISSIONS = new String[]{ + "android.permission.ACCESS_FINE_LOCATION", "android.permission.ACCESS_COARSE_LOCATION"}; + + private final List features = new ArrayList<>(); + private final Map markerMap = new HashMap<>(); + private final Map polylineMap = new HashMap<>(); + private final Map polygonMap = new HashMap<>(); + private final ScaleGestureDetector scaleDetector; + private final GestureDetectorCompat gestureDetector; + private final AirMapManager manager; + private LifecycleEventListener lifecycleListener; + private boolean paused = false; + private boolean destroyed = false; + private final ThemedReactContext context; + private final EventDispatcher eventDispatcher; + + private static boolean contextHasBug(Context context) { + return context == null || + context.getResources() == null || + context.getResources().getConfiguration() == null; + } + + // We do this to fix this bug: + // https://github.com/airbnb/react-native-maps/issues/271 + // + // which conflicts with another bug regarding the passed in context: + // https://github.com/airbnb/react-native-maps/issues/1147 + // + // Doing this allows us to avoid both bugs. + private static Context getNonBuggyContext(ThemedReactContext reactContext, + ReactApplicationContext appContext) { + Context superContext = reactContext; + if (!contextHasBug(appContext.getCurrentActivity())) { + superContext = appContext.getCurrentActivity(); + } else if (contextHasBug(superContext)) { + // we have the bug! let's try to find a better context to use + if (!contextHasBug(reactContext.getCurrentActivity())) { + superContext = reactContext.getCurrentActivity(); + } else if (!contextHasBug(reactContext.getApplicationContext())) { + superContext = reactContext.getApplicationContext(); + } else { + // ¯\_(ツ)_/¯ + } + } + return superContext; + } + + public AirMapView(ThemedReactContext reactContext, ReactApplicationContext appContext, + AirMapManager manager, + GoogleMapOptions googleMapOptions) { + super(getNonBuggyContext(reactContext, appContext), googleMapOptions); + + this.manager = manager; + this.context = reactContext; + + super.onCreate(null); + // TODO(lmr): what about onStart???? + super.onResume(); + super.getMapAsync(this); + + final AirMapView view = this; + scaleDetector = + new ScaleGestureDetector(reactContext, + new ScaleGestureDetector.SimpleOnScaleGestureListener() { + @Override + public boolean onScaleBegin(ScaleGestureDetector detector) { + view.startMonitoringRegion(); + return true; // stop recording this gesture. let mapview handle it. + } + }); + + gestureDetector = + new GestureDetectorCompat(reactContext, new GestureDetector.SimpleOnGestureListener() { + @Override + public boolean onDoubleTap(MotionEvent e) { + view.startMonitoringRegion(); + return false; } - } - @Override - public void onHostPause() { - if (hasPermissions()) { - //noinspection MissingPermission - map.setMyLocationEnabled(false); - } - synchronized (AirMapView.this) { - if(!destroyed) { - AirMapView.this.onPause(); - } - paused = true; + @Override + public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, + float distanceY) { + if (handlePanDrag) { + onPanDrag(e2); } - } - - @Override - public void onHostDestroy() { - AirMapView.this.doDestroy(); - } - }; - - context.addLifecycleEventListener(lifecycleListener); - } - - private boolean hasPermissions() { - return checkSelfPermission(getContext(), PERMISSIONS[0]) == PackageManager.PERMISSION_GRANTED || - checkSelfPermission(getContext(), PERMISSIONS[1]) == PackageManager.PERMISSION_GRANTED; - } - - - - /* - onDestroy is final method so I can't override it. - */ - public synchronized void doDestroy() { - if (destroyed) { - return; - } - destroyed = true; + view.startMonitoringRegion(); + return false; + } + }); - if (lifecycleListener != null && context != null) { - context.removeLifecycleEventListener(lifecycleListener); - lifecycleListener = null; - } + this.addOnLayoutChangeListener(new OnLayoutChangeListener() { + @Override public void onLayoutChange(View v, int left, int top, int right, int bottom, + int oldLeft, int oldTop, int oldRight, int oldBottom) { if (!paused) { - onPause(); - paused = true; - } - onDestroy(); - } - - public void setRegion(ReadableMap region) { - if (region == null) return; - - Double lng = region.getDouble("longitude"); - Double lat = region.getDouble("latitude"); - Double lngDelta = region.getDouble("longitudeDelta"); - Double latDelta = region.getDouble("latitudeDelta"); - LatLngBounds bounds = new LatLngBounds( - new LatLng(lat - latDelta / 2, lng - lngDelta / 2), // southwest - new LatLng(lat + latDelta / 2, lng + lngDelta / 2) // northeast - ); - if (super.getHeight() <= 0 || super.getWidth() <= 0) { - // in this case, our map has not been laid out yet, so we save the bounds in a local - // variable, and make a guess of zoomLevel 10. Not to worry, though: as soon as layout - // occurs, we will move the camera to the saved bounds. Note that if we tried to move - // to the bounds now, it would trigger an exception. - map.moveCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(lat, lng), 10)); - boundsToMove = bounds; - } else { - map.moveCamera(CameraUpdateFactory.newLatLngBounds(bounds, 0)); - boundsToMove = null; - } - } - - public void setShowsUserLocation(boolean showUserLocation) { - this.showUserLocation = showUserLocation; // hold onto this for lifecycle handling - if (hasPermissions()) { - //noinspection MissingPermission - map.setMyLocationEnabled(showUserLocation); - } - } - - public void setShowsMyLocationButton(boolean showMyLocationButton) { - if (hasPermissions()) { - map.getUiSettings().setMyLocationButtonEnabled(showMyLocationButton); - } - } - - public void setToolbarEnabled(boolean toolbarEnabled) { - if (hasPermissions()) { - map.getUiSettings().setMapToolbarEnabled(toolbarEnabled); - } - } - - public void setCacheEnabled(boolean cacheEnabled) { - this.cacheEnabled = cacheEnabled; - this.cacheView(); - } - - public void enableMapLoading(boolean loadingEnabled) { - if (loadingEnabled && !this.isMapLoaded) { - this.getMapLoadingLayoutView().setVisibility(View.VISIBLE); - } - } - - public void setMoveOnMarkerPress(boolean moveOnPress) { - this.moveOnMarkerPress = moveOnPress; - } - - public void setLoadingBackgroundColor(Integer loadingBackgroundColor) { - this.loadingBackgroundColor = loadingBackgroundColor; - - if (this.mapLoadingLayout != null) { - if (loadingBackgroundColor == null) { - this.mapLoadingLayout.setBackgroundColor(Color.WHITE); - } else { - this.mapLoadingLayout.setBackgroundColor(this.loadingBackgroundColor); - } - } - } - - public void setLoadingIndicatorColor(Integer loadingIndicatorColor) { - this.loadingIndicatorColor = loadingIndicatorColor; - if (this.mapLoadingProgressBar != null) { - Integer color = loadingIndicatorColor; - if (color == null) { - color = Color.parseColor("#606060"); - } - - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { - ColorStateList progressTintList = ColorStateList.valueOf(loadingIndicatorColor); - ColorStateList secondaryProgressTintList = ColorStateList.valueOf(loadingIndicatorColor); - ColorStateList indeterminateTintList = ColorStateList.valueOf(loadingIndicatorColor); - - this.mapLoadingProgressBar.setProgressTintList(progressTintList); - this.mapLoadingProgressBar.setSecondaryProgressTintList(secondaryProgressTintList); - this.mapLoadingProgressBar.setIndeterminateTintList(indeterminateTintList); - } else { - PorterDuff.Mode mode = PorterDuff.Mode.SRC_IN; - if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.GINGERBREAD_MR1) { - mode = PorterDuff.Mode.MULTIPLY; - } - if (this.mapLoadingProgressBar.getIndeterminateDrawable() != null) - this.mapLoadingProgressBar.getIndeterminateDrawable().setColorFilter(color, mode); - if (this.mapLoadingProgressBar.getProgressDrawable() != null) - this.mapLoadingProgressBar.getProgressDrawable().setColorFilter(color, mode); - } - } - } - - public void setHandlePanDrag(boolean handlePanDrag) { - this.handlePanDrag = handlePanDrag; - } - - public void addFeature(View child, int index) { - // Our desired API is to pass up annotations/overlays as children to the mapview component. - // This is where we intercept them and do the appropriate underlying mapview action. - if (child instanceof AirMapMarker) { - AirMapMarker annotation = (AirMapMarker) child; - annotation.addToMap(map); - features.add(index, annotation); - Marker marker = (Marker) annotation.getFeature(); - markerMap.put(marker, annotation); - } else if (child instanceof AirMapPolyline) { - AirMapPolyline polylineView = (AirMapPolyline) child; - polylineView.addToMap(map); - features.add(index, polylineView); - Polyline polyline = (Polyline) polylineView.getFeature(); - polylineMap.put(polyline, polylineView); - } else if (child instanceof AirMapPolygon) { - AirMapPolygon polygonView = (AirMapPolygon) child; - polygonView.addToMap(map); - features.add(index, polygonView); - Polygon polygon = (Polygon) polygonView.getFeature(); - polygonMap.put(polygon, polygonView); - } else if (child instanceof AirMapCircle) { - AirMapCircle circleView = (AirMapCircle) child; - circleView.addToMap(map); - features.add(index, circleView); - } else if (child instanceof AirMapUrlTile) { - AirMapUrlTile urlTileView = (AirMapUrlTile) child; - urlTileView.addToMap(map); - features.add(index, urlTileView); - } else { - ViewGroup children = (ViewGroup) child; - for (int i = 0; i < children.getChildCount(); i++) { - addFeature(children.getChildAt(i), index); - } - } - } - - public int getFeatureCount() { - return features.size(); - } - - public View getFeatureAt(int index) { - return features.get(index); - } - - public void removeFeatureAt(int index) { - AirMapFeature feature = features.remove(index); - if (feature instanceof AirMapMarker) { - markerMap.remove(feature.getFeature()); + AirMapView.this.cacheView(); } - feature.removeFromMap(map); - } - - public WritableMap makeClickEventData(LatLng point) { - WritableMap event = new WritableNativeMap(); - - WritableMap coordinate = new WritableNativeMap(); - coordinate.putDouble("latitude", point.latitude); - coordinate.putDouble("longitude", point.longitude); - event.putMap("coordinate", coordinate); - - Projection projection = map.getProjection(); - Point screenPoint = projection.toScreenLocation(point); - - WritableMap position = new WritableNativeMap(); - position.putDouble("x", screenPoint.x); - position.putDouble("y", screenPoint.y); - event.putMap("position", position); - - return event; - } - - public void updateExtraData(Object extraData) { - // if boundsToMove is not null, we now have the MapView's width/height, so we can apply - // a proper camera move - if (boundsToMove != null) { - HashMap data = (HashMap) extraData; - float width = data.get("width"); - float height = data.get("height"); - map.moveCamera( - CameraUpdateFactory.newLatLngBounds( - boundsToMove, - (int) width, - (int) height, - 0 - ) - ); - boundsToMove = null; - } - } - - public void animateToRegion(LatLngBounds bounds, int duration) { - if (map != null) { - startMonitoringRegion(); - map.animateCamera(CameraUpdateFactory.newLatLngBounds(bounds, 0), duration, null); - } - } - - public void animateToCoordinate(LatLng coordinate, int duration) { - if (map != null) { - startMonitoringRegion(); - map.animateCamera(CameraUpdateFactory.newLatLng(coordinate), duration, null); - } - } - - public void fitToElements(boolean animated) { - LatLngBounds.Builder builder = new LatLngBounds.Builder(); + } + }); - boolean addedPosition = false; + eventDispatcher = reactContext.getNativeModule(UIManagerModule.class).getEventDispatcher(); + } - for (AirMapFeature feature : features) { - if (feature instanceof AirMapMarker) { - Marker marker = (Marker) feature.getFeature(); - builder.include(marker.getPosition()); - addedPosition = true; - } - // TODO(lmr): may want to include shapes / etc. - } - if (addedPosition) { - LatLngBounds bounds = builder.build(); - CameraUpdate cu = CameraUpdateFactory.newLatLngBounds(bounds, baseMapPadding); - if (animated) { - startMonitoringRegion(); - map.animateCamera(cu); - } else { - map.moveCamera(cu); - } - } + @Override + public void onMapReady(final GoogleMap map) { + if (destroyed) { + return; } + this.map = map; + this.map.setInfoWindowAdapter(this); + this.map.setOnMarkerDragListener(this); - public void fitToSuppliedMarkers(ReadableArray markerIDsArray, boolean animated) { - LatLngBounds.Builder builder = new LatLngBounds.Builder(); - - String[] markerIDs = new String[markerIDsArray.size()]; - for (int i = 0; i < markerIDsArray.size(); i++) { - markerIDs[i] = markerIDsArray.getString(i); - } - - boolean addedPosition = false; + manager.pushEvent(context, this, "onMapReady", new WritableNativeMap()); - List markerIDList = Arrays.asList(markerIDs); + final AirMapView view = this; - for (AirMapFeature feature : features) { - if (feature instanceof AirMapMarker) { - String identifier = ((AirMapMarker)feature).getIdentifier(); - Marker marker = (Marker)feature.getFeature(); - if (markerIDList.contains(identifier)) { - builder.include(marker.getPosition()); - addedPosition = true; - } - } - } - - if (addedPosition) { - LatLngBounds bounds = builder.build(); - CameraUpdate cu = CameraUpdateFactory.newLatLngBounds(bounds, baseMapPadding); - if (animated) { - startMonitoringRegion(); - map.animateCamera(cu); - } else { - map.moveCamera(cu); - } - } - } + map.setOnMarkerClickListener(new GoogleMap.OnMarkerClickListener() { + @Override + public boolean onMarkerClick(Marker marker) { + WritableMap event; + AirMapMarker airMapMarker = markerMap.get(marker); - public void fitToCoordinates(ReadableArray coordinatesArray, ReadableMap edgePadding, boolean animated) { - LatLngBounds.Builder builder = new LatLngBounds.Builder(); - - for (int i = 0; i < coordinatesArray.size(); i++) { - ReadableMap latLng = coordinatesArray.getMap(i); - Double lat = latLng.getDouble("latitude"); - Double lng = latLng.getDouble("longitude"); - builder.include(new LatLng(lat, lng)); - } - - LatLngBounds bounds = builder.build(); - CameraUpdate cu = CameraUpdateFactory.newLatLngBounds(bounds, baseMapPadding); - - if (edgePadding != null) { - map.setPadding(edgePadding.getInt("left"), edgePadding.getInt("top"), edgePadding.getInt("right"), edgePadding.getInt("bottom")); - } + event = makeClickEventData(marker.getPosition()); + event.putString("action", "marker-press"); + event.putString("id", airMapMarker.getIdentifier()); + manager.pushEvent(context, view, "onMarkerPress", event); - if (animated) { - startMonitoringRegion(); - map.animateCamera(cu); + event = makeClickEventData(marker.getPosition()); + event.putString("action", "marker-press"); + event.putString("id", airMapMarker.getIdentifier()); + manager.pushEvent(context, markerMap.get(marker), "onPress", event); + + // Return false to open the callout info window and center on the marker + // https://developers.google.com/android/reference/com/google/android/gms/maps/GoogleMap + // .OnMarkerClickListener + if (view.moveOnMarkerPress) { + return false; } else { - map.moveCamera(cu); - } - map.setPadding(0, 0, 0, 0); // Without this, the Google logo is moved up by the value of edgePadding.bottom - } - - // InfoWindowAdapter interface - - @Override - public View getInfoWindow(Marker marker) { - AirMapMarker markerView = markerMap.get(marker); - return markerView.getCallout(); - } - - @Override - public View getInfoContents(Marker marker) { - AirMapMarker markerView = markerMap.get(marker); - return markerView.getInfoContents(); - } - - @Override - public boolean dispatchTouchEvent(MotionEvent ev) { - scaleDetector.onTouchEvent(ev); - gestureDetector.onTouchEvent(ev); - - int action = MotionEventCompat.getActionMasked(ev); - - switch (action) { - case (MotionEvent.ACTION_DOWN): - this.getParent().requestDisallowInterceptTouchEvent( - map != null && map.getUiSettings().isScrollGesturesEnabled()); - isTouchDown = true; - break; - case (MotionEvent.ACTION_MOVE): - startMonitoringRegion(); - break; - case (MotionEvent.ACTION_UP): - // Clear this regardless, since isScrollGesturesEnabled() may have been updated - this.getParent().requestDisallowInterceptTouchEvent(false); - isTouchDown = false; - break; - } - super.dispatchTouchEvent(ev); - return true; - } - - // Timer Implementation - - public void startMonitoringRegion() { - if (isMonitoringRegion) return; - timerHandler.postDelayed(timerRunnable, 100); - isMonitoringRegion = true; - } + marker.showInfoWindow(); + return true; + } + } + }); + + map.setOnPolygonClickListener(new GoogleMap.OnPolygonClickListener() { + @Override + public void onPolygonClick(Polygon polygon) { + WritableMap event = makeClickEventData(polygon.getPoints().get(0)); + event.putString("action", "polygon-press"); + manager.pushEvent(context, polygonMap.get(polygon), "onPress", event); + } + }); + + map.setOnPolylineClickListener(new GoogleMap.OnPolylineClickListener() { + @Override + public void onPolylineClick(Polyline polyline) { + WritableMap event = makeClickEventData(polyline.getPoints().get(0)); + event.putString("action", "polyline-press"); + manager.pushEvent(context, polylineMap.get(polyline), "onPress", event); + } + }); + + map.setOnInfoWindowClickListener(new GoogleMap.OnInfoWindowClickListener() { + @Override + public void onInfoWindowClick(Marker marker) { + WritableMap event; - public void stopMonitoringRegion() { - if (!isMonitoringRegion) return; - timerHandler.removeCallbacks(timerRunnable); - isMonitoringRegion = false; - } - - private LatLngBounds lastBoundsEmitted; - - Handler timerHandler = new Handler(); - Runnable timerRunnable = new Runnable() { - - @Override - public void run() { - - Projection projection = map.getProjection(); - VisibleRegion region = (projection != null) ? projection.getVisibleRegion() : null; - LatLngBounds bounds = (region != null) ? region.latLngBounds : null; - - if ((bounds != null) && - (lastBoundsEmitted == null || LatLngBoundsUtils.BoundsAreDifferent(bounds, lastBoundsEmitted))) { - LatLng center = map.getCameraPosition().target; - lastBoundsEmitted = bounds; - eventDispatcher.dispatchEvent(new RegionChangeEvent(getId(), bounds, center, true)); - } - - timerHandler.postDelayed(this, 100); - } - }; - - @Override - public void onMarkerDragStart(Marker marker) { - WritableMap event = makeClickEventData(marker.getPosition()); - manager.pushEvent(context, this, "onMarkerDragStart", event); - - AirMapMarker markerView = markerMap.get(marker); event = makeClickEventData(marker.getPosition()); - manager.pushEvent(context, markerView, "onDragStart", event); - } - - @Override - public void onMarkerDrag(Marker marker) { - WritableMap event = makeClickEventData(marker.getPosition()); - manager.pushEvent(context, this, "onMarkerDrag", event); + event.putString("action", "callout-press"); + manager.pushEvent(context, view, "onCalloutPress", event); - AirMapMarker markerView = markerMap.get(marker); event = makeClickEventData(marker.getPosition()); - manager.pushEvent(context, markerView, "onDrag", event); - } - - @Override - public void onMarkerDragEnd(Marker marker) { - WritableMap event = makeClickEventData(marker.getPosition()); - manager.pushEvent(context, this, "onMarkerDragEnd", event); - + event.putString("action", "callout-press"); AirMapMarker markerView = markerMap.get(marker); - event = makeClickEventData(marker.getPosition()); - manager.pushEvent(context, markerView, "onDragEnd", event); - } + manager.pushEvent(context, markerView, "onCalloutPress", event); - private ProgressBar getMapLoadingProgressBar() { - if (this.mapLoadingProgressBar == null) { - this.mapLoadingProgressBar = new ProgressBar(getContext()); - this.mapLoadingProgressBar.setIndeterminate(true); + event = makeClickEventData(marker.getPosition()); + event.putString("action", "callout-press"); + AirMapCallout infoWindow = markerView.getCalloutView(); + if (infoWindow != null) manager.pushEvent(context, infoWindow, "onPress", event); + } + }); + + map.setOnMapClickListener(new GoogleMap.OnMapClickListener() { + @Override + public void onMapClick(LatLng point) { + WritableMap event = makeClickEventData(point); + event.putString("action", "press"); + manager.pushEvent(context, view, "onPress", event); + } + }); + + map.setOnMapLongClickListener(new GoogleMap.OnMapLongClickListener() { + @Override + public void onMapLongClick(LatLng point) { + WritableMap event = makeClickEventData(point); + event.putString("action", "long-press"); + manager.pushEvent(context, view, "onLongPress", makeClickEventData(point)); + } + }); + + map.setOnCameraChangeListener(new GoogleMap.OnCameraChangeListener() { + @Override + public void onCameraChange(CameraPosition position) { + LatLngBounds bounds = map.getProjection().getVisibleRegion().latLngBounds; + LatLng center = position.target; + lastBoundsEmitted = bounds; + eventDispatcher.dispatchEvent(new RegionChangeEvent(getId(), bounds, center, isTouchDown)); + view.stopMonitoringRegion(); + } + }); + + map.setOnMapLoadedCallback(new GoogleMap.OnMapLoadedCallback() { + @Override public void onMapLoaded() { + isMapLoaded = true; + AirMapView.this.cacheView(); + } + }); + + // We need to be sure to disable location-tracking when app enters background, in-case some + // other module + // has acquired a wake-lock and is controlling location-updates, otherwise, location-manager + // will be left + // updating location constantly, killing the battery, even though some other location-mgmt + // module may + // desire to shut-down location-services. + lifecycleListener = new LifecycleEventListener() { + @Override + public void onHostResume() { + if (hasPermissions()) { + //noinspection MissingPermission + map.setMyLocationEnabled(showUserLocation); } - if (this.loadingIndicatorColor != null) { - this.setLoadingIndicatorColor(this.loadingIndicatorColor); + synchronized (AirMapView.this) { + AirMapView.this.onResume(); + paused = false; } - return this.mapLoadingProgressBar; - } - - private RelativeLayout getMapLoadingLayoutView() { - if (this.mapLoadingLayout == null) { - this.mapLoadingLayout = new RelativeLayout(getContext()); - this.mapLoadingLayout.setBackgroundColor(Color.LTGRAY); - this.addView(this.mapLoadingLayout, - new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, - ViewGroup.LayoutParams.MATCH_PARENT)); + } - RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams( - RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT); - params.addRule(RelativeLayout.CENTER_IN_PARENT); - this.mapLoadingLayout.addView(this.getMapLoadingProgressBar(), params); - - this.mapLoadingLayout.setVisibility(View.INVISIBLE); + @Override + public void onHostPause() { + if (hasPermissions()) { + //noinspection MissingPermission + map.setMyLocationEnabled(false); } - this.setLoadingBackgroundColor(this.loadingBackgroundColor); - return this.mapLoadingLayout; - } - - private ImageView getCacheImageView() { - if (this.cacheImageView == null) { - this.cacheImageView = new ImageView(getContext()); - this.addView(this.cacheImageView, - new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT)); - this.cacheImageView.setVisibility(View.INVISIBLE); + synchronized (AirMapView.this) { + if (!destroyed) { + AirMapView.this.onPause(); + } + paused = true; } - return this.cacheImageView; - } + } - private void removeCacheImageView() { - if (this.cacheImageView != null) { - ((ViewGroup)this.cacheImageView.getParent()).removeView(this.cacheImageView); - this.cacheImageView = null; - } - } + @Override + public void onHostDestroy() { + AirMapView.this.doDestroy(); + } + }; - private void removeMapLoadingProgressBar() { - if (this.mapLoadingProgressBar != null) { - ((ViewGroup)this.mapLoadingProgressBar.getParent()).removeView(this.mapLoadingProgressBar); - this.mapLoadingProgressBar = null; - } - } + context.addLifecycleEventListener(lifecycleListener); + } + + private boolean hasPermissions() { + return checkSelfPermission(getContext(), PERMISSIONS[0]) == PackageManager.PERMISSION_GRANTED || + checkSelfPermission(getContext(), PERMISSIONS[1]) == PackageManager.PERMISSION_GRANTED; + } + + + /* + onDestroy is final method so I can't override it. + */ + public synchronized void doDestroy() { + if (destroyed) { + return; + } + destroyed = true; + + if (lifecycleListener != null && context != null) { + context.removeLifecycleEventListener(lifecycleListener); + lifecycleListener = null; + } + if (!paused) { + onPause(); + paused = true; + } + onDestroy(); + } + + public void setRegion(ReadableMap region) { + if (region == null) return; + + Double lng = region.getDouble("longitude"); + Double lat = region.getDouble("latitude"); + Double lngDelta = region.getDouble("longitudeDelta"); + Double latDelta = region.getDouble("latitudeDelta"); + LatLngBounds bounds = new LatLngBounds( + new LatLng(lat - latDelta / 2, lng - lngDelta / 2), // southwest + new LatLng(lat + latDelta / 2, lng + lngDelta / 2) // northeast + ); + if (super.getHeight() <= 0 || super.getWidth() <= 0) { + // in this case, our map has not been laid out yet, so we save the bounds in a local + // variable, and make a guess of zoomLevel 10. Not to worry, though: as soon as layout + // occurs, we will move the camera to the saved bounds. Note that if we tried to move + // to the bounds now, it would trigger an exception. + map.moveCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(lat, lng), 10)); + boundsToMove = bounds; + } else { + map.moveCamera(CameraUpdateFactory.newLatLngBounds(bounds, 0)); + boundsToMove = null; + } + } + + public void setShowsUserLocation(boolean showUserLocation) { + this.showUserLocation = showUserLocation; // hold onto this for lifecycle handling + if (hasPermissions()) { + //noinspection MissingPermission + map.setMyLocationEnabled(showUserLocation); + } + } + + public void setShowsMyLocationButton(boolean showMyLocationButton) { + if (hasPermissions()) { + map.getUiSettings().setMyLocationButtonEnabled(showMyLocationButton); + } + } + + public void setToolbarEnabled(boolean toolbarEnabled) { + if (hasPermissions()) { + map.getUiSettings().setMapToolbarEnabled(toolbarEnabled); + } + } + + public void setCacheEnabled(boolean cacheEnabled) { + this.cacheEnabled = cacheEnabled; + this.cacheView(); + } + + public void enableMapLoading(boolean loadingEnabled) { + if (loadingEnabled && !this.isMapLoaded) { + this.getMapLoadingLayoutView().setVisibility(View.VISIBLE); + } + } + + public void setMoveOnMarkerPress(boolean moveOnPress) { + this.moveOnMarkerPress = moveOnPress; + } + + public void setLoadingBackgroundColor(Integer loadingBackgroundColor) { + this.loadingBackgroundColor = loadingBackgroundColor; + + if (this.mapLoadingLayout != null) { + if (loadingBackgroundColor == null) { + this.mapLoadingLayout.setBackgroundColor(Color.WHITE); + } else { + this.mapLoadingLayout.setBackgroundColor(this.loadingBackgroundColor); + } + } + } + + public void setLoadingIndicatorColor(Integer loadingIndicatorColor) { + this.loadingIndicatorColor = loadingIndicatorColor; + if (this.mapLoadingProgressBar != null) { + Integer color = loadingIndicatorColor; + if (color == null) { + color = Color.parseColor("#606060"); + } + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { + ColorStateList progressTintList = ColorStateList.valueOf(loadingIndicatorColor); + ColorStateList secondaryProgressTintList = ColorStateList.valueOf(loadingIndicatorColor); + ColorStateList indeterminateTintList = ColorStateList.valueOf(loadingIndicatorColor); + + this.mapLoadingProgressBar.setProgressTintList(progressTintList); + this.mapLoadingProgressBar.setSecondaryProgressTintList(secondaryProgressTintList); + this.mapLoadingProgressBar.setIndeterminateTintList(indeterminateTintList); + } else { + PorterDuff.Mode mode = PorterDuff.Mode.SRC_IN; + if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.GINGERBREAD_MR1) { + mode = PorterDuff.Mode.MULTIPLY; + } + if (this.mapLoadingProgressBar.getIndeterminateDrawable() != null) + this.mapLoadingProgressBar.getIndeterminateDrawable().setColorFilter(color, mode); + if (this.mapLoadingProgressBar.getProgressDrawable() != null) + this.mapLoadingProgressBar.getProgressDrawable().setColorFilter(color, mode); + } + } + } + + public void setHandlePanDrag(boolean handlePanDrag) { + this.handlePanDrag = handlePanDrag; + } + + public void addFeature(View child, int index) { + // Our desired API is to pass up annotations/overlays as children to the mapview component. + // This is where we intercept them and do the appropriate underlying mapview action. + if (child instanceof AirMapMarker) { + AirMapMarker annotation = (AirMapMarker) child; + annotation.addToMap(map); + features.add(index, annotation); + Marker marker = (Marker) annotation.getFeature(); + markerMap.put(marker, annotation); + } else if (child instanceof AirMapPolyline) { + AirMapPolyline polylineView = (AirMapPolyline) child; + polylineView.addToMap(map); + features.add(index, polylineView); + Polyline polyline = (Polyline) polylineView.getFeature(); + polylineMap.put(polyline, polylineView); + } else if (child instanceof AirMapPolygon) { + AirMapPolygon polygonView = (AirMapPolygon) child; + polygonView.addToMap(map); + features.add(index, polygonView); + Polygon polygon = (Polygon) polygonView.getFeature(); + polygonMap.put(polygon, polygonView); + } else if (child instanceof AirMapCircle) { + AirMapCircle circleView = (AirMapCircle) child; + circleView.addToMap(map); + features.add(index, circleView); + } else if (child instanceof AirMapUrlTile) { + AirMapUrlTile urlTileView = (AirMapUrlTile) child; + urlTileView.addToMap(map); + features.add(index, urlTileView); + } else { + ViewGroup children = (ViewGroup) child; + for (int i = 0; i < children.getChildCount(); i++) { + addFeature(children.getChildAt(i), index); + } + } + } + + public int getFeatureCount() { + return features.size(); + } + + public View getFeatureAt(int index) { + return features.get(index); + } + + public void removeFeatureAt(int index) { + AirMapFeature feature = features.remove(index); + if (feature instanceof AirMapMarker) { + markerMap.remove(feature.getFeature()); + } + feature.removeFromMap(map); + } + + public WritableMap makeClickEventData(LatLng point) { + WritableMap event = new WritableNativeMap(); + + WritableMap coordinate = new WritableNativeMap(); + coordinate.putDouble("latitude", point.latitude); + coordinate.putDouble("longitude", point.longitude); + event.putMap("coordinate", coordinate); + + Projection projection = map.getProjection(); + Point screenPoint = projection.toScreenLocation(point); + + WritableMap position = new WritableNativeMap(); + position.putDouble("x", screenPoint.x); + position.putDouble("y", screenPoint.y); + event.putMap("position", position); + + return event; + } + + public void updateExtraData(Object extraData) { + // if boundsToMove is not null, we now have the MapView's width/height, so we can apply + // a proper camera move + if (boundsToMove != null) { + HashMap data = (HashMap) extraData; + float width = data.get("width"); + float height = data.get("height"); + map.moveCamera( + CameraUpdateFactory.newLatLngBounds( + boundsToMove, + (int) width, + (int) height, + 0 + ) + ); + boundsToMove = null; + } + } + + public void animateToRegion(LatLngBounds bounds, int duration) { + if (map != null) { + startMonitoringRegion(); + map.animateCamera(CameraUpdateFactory.newLatLngBounds(bounds, 0), duration, null); + } + } + + public void animateToCoordinate(LatLng coordinate, int duration) { + if (map != null) { + startMonitoringRegion(); + map.animateCamera(CameraUpdateFactory.newLatLng(coordinate), duration, null); + } + } + + public void fitToElements(boolean animated) { + LatLngBounds.Builder builder = new LatLngBounds.Builder(); + + boolean addedPosition = false; + + for (AirMapFeature feature : features) { + if (feature instanceof AirMapMarker) { + Marker marker = (Marker) feature.getFeature(); + builder.include(marker.getPosition()); + addedPosition = true; + } + // TODO(lmr): may want to include shapes / etc. + } + if (addedPosition) { + LatLngBounds bounds = builder.build(); + CameraUpdate cu = CameraUpdateFactory.newLatLngBounds(bounds, baseMapPadding); + if (animated) { + startMonitoringRegion(); + map.animateCamera(cu); + } else { + map.moveCamera(cu); + } + } + } + + public void fitToSuppliedMarkers(ReadableArray markerIDsArray, boolean animated) { + LatLngBounds.Builder builder = new LatLngBounds.Builder(); + + String[] markerIDs = new String[markerIDsArray.size()]; + for (int i = 0; i < markerIDsArray.size(); i++) { + markerIDs[i] = markerIDsArray.getString(i); + } + + boolean addedPosition = false; + + List markerIDList = Arrays.asList(markerIDs); + + for (AirMapFeature feature : features) { + if (feature instanceof AirMapMarker) { + String identifier = ((AirMapMarker) feature).getIdentifier(); + Marker marker = (Marker) feature.getFeature(); + if (markerIDList.contains(identifier)) { + builder.include(marker.getPosition()); + addedPosition = true; + } + } + } + + if (addedPosition) { + LatLngBounds bounds = builder.build(); + CameraUpdate cu = CameraUpdateFactory.newLatLngBounds(bounds, baseMapPadding); + if (animated) { + startMonitoringRegion(); + map.animateCamera(cu); + } else { + map.moveCamera(cu); + } + } + } + + public void fitToCoordinates(ReadableArray coordinatesArray, ReadableMap edgePadding, + boolean animated) { + LatLngBounds.Builder builder = new LatLngBounds.Builder(); + + for (int i = 0; i < coordinatesArray.size(); i++) { + ReadableMap latLng = coordinatesArray.getMap(i); + Double lat = latLng.getDouble("latitude"); + Double lng = latLng.getDouble("longitude"); + builder.include(new LatLng(lat, lng)); + } + + LatLngBounds bounds = builder.build(); + CameraUpdate cu = CameraUpdateFactory.newLatLngBounds(bounds, baseMapPadding); + + if (edgePadding != null) { + map.setPadding(edgePadding.getInt("left"), edgePadding.getInt("top"), + edgePadding.getInt("right"), edgePadding.getInt("bottom")); + } + + if (animated) { + startMonitoringRegion(); + map.animateCamera(cu); + } else { + map.moveCamera(cu); + } + map.setPadding(0, 0, 0, + 0); // Without this, the Google logo is moved up by the value of edgePadding.bottom + } + + // InfoWindowAdapter interface - private void removeMapLoadingLayoutView() { - this.removeMapLoadingProgressBar(); - if (this.mapLoadingLayout != null) { - ((ViewGroup)this.mapLoadingLayout.getParent()).removeView(this.mapLoadingLayout); - this.mapLoadingLayout = null; - } + @Override + public View getInfoWindow(Marker marker) { + AirMapMarker markerView = markerMap.get(marker); + return markerView.getCallout(); + } + + @Override + public View getInfoContents(Marker marker) { + AirMapMarker markerView = markerMap.get(marker); + return markerView.getInfoContents(); + } + + @Override + public boolean dispatchTouchEvent(MotionEvent ev) { + scaleDetector.onTouchEvent(ev); + gestureDetector.onTouchEvent(ev); + + int action = MotionEventCompat.getActionMasked(ev); + + switch (action) { + case (MotionEvent.ACTION_DOWN): + this.getParent().requestDisallowInterceptTouchEvent( + map != null && map.getUiSettings().isScrollGesturesEnabled()); + isTouchDown = true; + break; + case (MotionEvent.ACTION_MOVE): + startMonitoringRegion(); + break; + case (MotionEvent.ACTION_UP): + // Clear this regardless, since isScrollGesturesEnabled() may have been updated + this.getParent().requestDisallowInterceptTouchEvent(false); + isTouchDown = false; + break; } + super.dispatchTouchEvent(ev); + return true; + } + + // Timer Implementation - private void cacheView() { - if (this.cacheEnabled) { - final ImageView cacheImageView = this.getCacheImageView(); - final RelativeLayout mapLoadingLayout = this.getMapLoadingLayoutView(); - cacheImageView.setVisibility(View.INVISIBLE); - mapLoadingLayout.setVisibility(View.VISIBLE); - if (this.isMapLoaded) { - this.map.snapshot(new GoogleMap.SnapshotReadyCallback() { - @Override public void onSnapshotReady(Bitmap bitmap) { - cacheImageView.setImageBitmap(bitmap); - cacheImageView.setVisibility(View.VISIBLE); - mapLoadingLayout.setVisibility(View.INVISIBLE); - } - }); - } - } - else { - this.removeCacheImageView(); - if (this.isMapLoaded) { - this.removeMapLoadingLayoutView(); - } - } - } + public void startMonitoringRegion() { + if (isMonitoringRegion) return; + timerHandler.postDelayed(timerRunnable, 100); + isMonitoringRegion = true; + } + + public void stopMonitoringRegion() { + if (!isMonitoringRegion) return; + timerHandler.removeCallbacks(timerRunnable); + isMonitoringRegion = false; + } + + private LatLngBounds lastBoundsEmitted; + + Handler timerHandler = new Handler(); + Runnable timerRunnable = new Runnable() { - public void onPanDrag(MotionEvent ev) { - Point point = new Point((int) ev.getX(), (int) ev.getY()); - LatLng coords = this.map.getProjection().fromScreenLocation(point); - WritableMap event = makeClickEventData(coords); - manager.pushEvent(context, this, "onPanDrag", event); - } + @Override + public void run() { + + Projection projection = map.getProjection(); + VisibleRegion region = (projection != null) ? projection.getVisibleRegion() : null; + LatLngBounds bounds = (region != null) ? region.latLngBounds : null; + + if ((bounds != null) && + (lastBoundsEmitted == null || + LatLngBoundsUtils.BoundsAreDifferent(bounds, lastBoundsEmitted))) { + LatLng center = map.getCameraPosition().target; + lastBoundsEmitted = bounds; + eventDispatcher.dispatchEvent(new RegionChangeEvent(getId(), bounds, center, true)); + } + + timerHandler.postDelayed(this, 100); + } + }; + + @Override + public void onMarkerDragStart(Marker marker) { + WritableMap event = makeClickEventData(marker.getPosition()); + manager.pushEvent(context, this, "onMarkerDragStart", event); + + AirMapMarker markerView = markerMap.get(marker); + event = makeClickEventData(marker.getPosition()); + manager.pushEvent(context, markerView, "onDragStart", event); + } + + @Override + public void onMarkerDrag(Marker marker) { + WritableMap event = makeClickEventData(marker.getPosition()); + manager.pushEvent(context, this, "onMarkerDrag", event); + + AirMapMarker markerView = markerMap.get(marker); + event = makeClickEventData(marker.getPosition()); + manager.pushEvent(context, markerView, "onDrag", event); + } + + @Override + public void onMarkerDragEnd(Marker marker) { + WritableMap event = makeClickEventData(marker.getPosition()); + manager.pushEvent(context, this, "onMarkerDragEnd", event); + + AirMapMarker markerView = markerMap.get(marker); + event = makeClickEventData(marker.getPosition()); + manager.pushEvent(context, markerView, "onDragEnd", event); + } + + private ProgressBar getMapLoadingProgressBar() { + if (this.mapLoadingProgressBar == null) { + this.mapLoadingProgressBar = new ProgressBar(getContext()); + this.mapLoadingProgressBar.setIndeterminate(true); + } + if (this.loadingIndicatorColor != null) { + this.setLoadingIndicatorColor(this.loadingIndicatorColor); + } + return this.mapLoadingProgressBar; + } + + private RelativeLayout getMapLoadingLayoutView() { + if (this.mapLoadingLayout == null) { + this.mapLoadingLayout = new RelativeLayout(getContext()); + this.mapLoadingLayout.setBackgroundColor(Color.LTGRAY); + this.addView(this.mapLoadingLayout, + new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, + ViewGroup.LayoutParams.MATCH_PARENT)); + + RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams( + RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT); + params.addRule(RelativeLayout.CENTER_IN_PARENT); + this.mapLoadingLayout.addView(this.getMapLoadingProgressBar(), params); + + this.mapLoadingLayout.setVisibility(View.INVISIBLE); + } + this.setLoadingBackgroundColor(this.loadingBackgroundColor); + return this.mapLoadingLayout; + } + + private ImageView getCacheImageView() { + if (this.cacheImageView == null) { + this.cacheImageView = new ImageView(getContext()); + this.addView(this.cacheImageView, + new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, + ViewGroup.LayoutParams.MATCH_PARENT)); + this.cacheImageView.setVisibility(View.INVISIBLE); + } + return this.cacheImageView; + } + + private void removeCacheImageView() { + if (this.cacheImageView != null) { + ((ViewGroup) this.cacheImageView.getParent()).removeView(this.cacheImageView); + this.cacheImageView = null; + } + } + + private void removeMapLoadingProgressBar() { + if (this.mapLoadingProgressBar != null) { + ((ViewGroup) this.mapLoadingProgressBar.getParent()).removeView(this.mapLoadingProgressBar); + this.mapLoadingProgressBar = null; + } + } + + private void removeMapLoadingLayoutView() { + this.removeMapLoadingProgressBar(); + if (this.mapLoadingLayout != null) { + ((ViewGroup) this.mapLoadingLayout.getParent()).removeView(this.mapLoadingLayout); + this.mapLoadingLayout = null; + } + } + + private void cacheView() { + if (this.cacheEnabled) { + final ImageView cacheImageView = this.getCacheImageView(); + final RelativeLayout mapLoadingLayout = this.getMapLoadingLayoutView(); + cacheImageView.setVisibility(View.INVISIBLE); + mapLoadingLayout.setVisibility(View.VISIBLE); + if (this.isMapLoaded) { + this.map.snapshot(new GoogleMap.SnapshotReadyCallback() { + @Override public void onSnapshotReady(Bitmap bitmap) { + cacheImageView.setImageBitmap(bitmap); + cacheImageView.setVisibility(View.VISIBLE); + mapLoadingLayout.setVisibility(View.INVISIBLE); + } + }); + } + } else { + this.removeCacheImageView(); + if (this.isMapLoaded) { + this.removeMapLoadingLayoutView(); + } + } + } + + public void onPanDrag(MotionEvent ev) { + Point point = new Point((int) ev.getX(), (int) ev.getY()); + LatLng coords = this.map.getProjection().fromScreenLocation(point); + WritableMap event = makeClickEventData(coords); + manager.pushEvent(context, this, "onPanDrag", event); + } } diff --git a/lib/android/src/main/java/com/airbnb/android/react/maps/LatLngBoundsUtils.java b/lib/android/src/main/java/com/airbnb/android/react/maps/LatLngBoundsUtils.java index ed1058c88..d32e0dc72 100644 --- a/lib/android/src/main/java/com/airbnb/android/react/maps/LatLngBoundsUtils.java +++ b/lib/android/src/main/java/com/airbnb/android/react/maps/LatLngBoundsUtils.java @@ -4,44 +4,44 @@ import com.google.android.gms.maps.model.LatLngBounds; public class LatLngBoundsUtils { - public static boolean BoundsAreDifferent(LatLngBounds a, LatLngBounds b) { - LatLng centerA = a.getCenter(); - double latA = centerA.latitude; - double lngA = centerA.longitude; - double latDeltaA = a.northeast.latitude - a.southwest.latitude; - double lngDeltaA = a.northeast.longitude - a.southwest.longitude; - - LatLng centerB = b.getCenter(); - double latB = centerB.latitude; - double lngB = centerB.longitude; - double latDeltaB = b.northeast.latitude - b.southwest.latitude; - double lngDeltaB = b.northeast.longitude - b.southwest.longitude; - - double latEps = LatitudeEpsilon(a, b); - double lngEps = LongitudeEpsilon(a, b); - - return - different(latA, latB, latEps) || - different(lngA, lngB, lngEps) || - different(latDeltaA, latDeltaB, latEps) || - different(lngDeltaA, lngDeltaB, lngEps); - } - - private static boolean different(double a, double b, double epsilon) { - return Math.abs(a - b) > epsilon; - } - - private static double LatitudeEpsilon(LatLngBounds a, LatLngBounds b) { - double sizeA = a.northeast.latitude - a.southwest.latitude; // something mod 180? - double sizeB = b.northeast.latitude - b.southwest.latitude; // something mod 180? - double size = Math.min(Math.abs(sizeA), Math.abs(sizeB)); - return size / 2560; - } - - private static double LongitudeEpsilon(LatLngBounds a, LatLngBounds b) { - double sizeA = a.northeast.longitude - a.southwest.longitude; - double sizeB = b.northeast.longitude - b.southwest.longitude; - double size = Math.min(Math.abs(sizeA), Math.abs(sizeB)); - return size / 2560; - } + public static boolean BoundsAreDifferent(LatLngBounds a, LatLngBounds b) { + LatLng centerA = a.getCenter(); + double latA = centerA.latitude; + double lngA = centerA.longitude; + double latDeltaA = a.northeast.latitude - a.southwest.latitude; + double lngDeltaA = a.northeast.longitude - a.southwest.longitude; + + LatLng centerB = b.getCenter(); + double latB = centerB.latitude; + double lngB = centerB.longitude; + double latDeltaB = b.northeast.latitude - b.southwest.latitude; + double lngDeltaB = b.northeast.longitude - b.southwest.longitude; + + double latEps = LatitudeEpsilon(a, b); + double lngEps = LongitudeEpsilon(a, b); + + return + different(latA, latB, latEps) || + different(lngA, lngB, lngEps) || + different(latDeltaA, latDeltaB, latEps) || + different(lngDeltaA, lngDeltaB, lngEps); + } + + private static boolean different(double a, double b, double epsilon) { + return Math.abs(a - b) > epsilon; + } + + private static double LatitudeEpsilon(LatLngBounds a, LatLngBounds b) { + double sizeA = a.northeast.latitude - a.southwest.latitude; // something mod 180? + double sizeB = b.northeast.latitude - b.southwest.latitude; // something mod 180? + double size = Math.min(Math.abs(sizeA), Math.abs(sizeB)); + return size / 2560; + } + + private static double LongitudeEpsilon(LatLngBounds a, LatLngBounds b) { + double sizeA = a.northeast.longitude - a.southwest.longitude; + double sizeB = b.northeast.longitude - b.southwest.longitude; + double size = Math.min(Math.abs(sizeA), Math.abs(sizeB)); + return size / 2560; + } } diff --git a/lib/android/src/main/java/com/airbnb/android/react/maps/MapsPackage.java b/lib/android/src/main/java/com/airbnb/android/react/maps/MapsPackage.java index e76f63aa2..da59849b3 100644 --- a/lib/android/src/main/java/com/airbnb/android/react/maps/MapsPackage.java +++ b/lib/android/src/main/java/com/airbnb/android/react/maps/MapsPackage.java @@ -13,41 +13,41 @@ import java.util.List; public class MapsPackage implements ReactPackage { - public MapsPackage(Activity activity) { - } // backwards compatibility - - public MapsPackage() { - } - - @Override - public List createNativeModules(ReactApplicationContext reactContext) { - return Arrays.asList(new AirMapModule(reactContext)); - } - - @Override - public List> createJSModules() { - return Collections.emptyList(); - } - - @Override - public List createViewManagers(ReactApplicationContext reactContext) { - AirMapCalloutManager calloutManager = new AirMapCalloutManager(); - AirMapMarkerManager annotationManager = new AirMapMarkerManager(); - AirMapPolylineManager polylineManager = new AirMapPolylineManager(reactContext); - AirMapPolygonManager polygonManager = new AirMapPolygonManager(reactContext); - AirMapCircleManager circleManager = new AirMapCircleManager(reactContext); - AirMapManager mapManager = new AirMapManager(reactContext); - AirMapLiteManager mapLiteManager = new AirMapLiteManager(reactContext); - AirMapUrlTileManager tileManager = new AirMapUrlTileManager(reactContext); - - return Arrays.asList( - calloutManager, - annotationManager, - polylineManager, - polygonManager, - circleManager, - mapManager, - mapLiteManager, - tileManager); - } + public MapsPackage(Activity activity) { + } // backwards compatibility + + public MapsPackage() { + } + + @Override + public List createNativeModules(ReactApplicationContext reactContext) { + return Arrays.asList(new AirMapModule(reactContext)); + } + + @Override + public List> createJSModules() { + return Collections.emptyList(); + } + + @Override + public List createViewManagers(ReactApplicationContext reactContext) { + AirMapCalloutManager calloutManager = new AirMapCalloutManager(); + AirMapMarkerManager annotationManager = new AirMapMarkerManager(); + AirMapPolylineManager polylineManager = new AirMapPolylineManager(reactContext); + AirMapPolygonManager polygonManager = new AirMapPolygonManager(reactContext); + AirMapCircleManager circleManager = new AirMapCircleManager(reactContext); + AirMapManager mapManager = new AirMapManager(reactContext); + AirMapLiteManager mapLiteManager = new AirMapLiteManager(reactContext); + AirMapUrlTileManager tileManager = new AirMapUrlTileManager(reactContext); + + return Arrays.asList( + calloutManager, + annotationManager, + polylineManager, + polygonManager, + circleManager, + mapManager, + mapLiteManager, + tileManager); + } } diff --git a/lib/android/src/main/java/com/airbnb/android/react/maps/RegionChangeEvent.java b/lib/android/src/main/java/com/airbnb/android/react/maps/RegionChangeEvent.java index 28a3b322b..43b1f678e 100644 --- a/lib/android/src/main/java/com/airbnb/android/react/maps/RegionChangeEvent.java +++ b/lib/android/src/main/java/com/airbnb/android/react/maps/RegionChangeEvent.java @@ -8,40 +8,40 @@ import com.google.android.gms.maps.model.LatLngBounds; public class RegionChangeEvent extends Event { - private final LatLngBounds bounds; - private final LatLng center; - private final boolean continuous; - - public RegionChangeEvent(int id, LatLngBounds bounds, LatLng center, boolean continuous) { - super(id); - this.bounds = bounds; - this.center = center; - this.continuous = continuous; - } - - @Override - public String getEventName() { - return "topChange"; - } - - @Override - public boolean canCoalesce() { - return false; - } - - @Override - public void dispatch(RCTEventEmitter rctEventEmitter) { - - WritableMap event = new WritableNativeMap(); - event.putBoolean("continuous", continuous); - - WritableMap region = new WritableNativeMap(); - region.putDouble("latitude", center.latitude); - region.putDouble("longitude", center.longitude); - region.putDouble("latitudeDelta", bounds.northeast.latitude - bounds.southwest.latitude); - region.putDouble("longitudeDelta", bounds.northeast.longitude - bounds.southwest.longitude); - event.putMap("region", region); - - rctEventEmitter.receiveEvent(getViewTag(), getEventName(), event); - } + private final LatLngBounds bounds; + private final LatLng center; + private final boolean continuous; + + public RegionChangeEvent(int id, LatLngBounds bounds, LatLng center, boolean continuous) { + super(id); + this.bounds = bounds; + this.center = center; + this.continuous = continuous; + } + + @Override + public String getEventName() { + return "topChange"; + } + + @Override + public boolean canCoalesce() { + return false; + } + + @Override + public void dispatch(RCTEventEmitter rctEventEmitter) { + + WritableMap event = new WritableNativeMap(); + event.putBoolean("continuous", continuous); + + WritableMap region = new WritableNativeMap(); + region.putDouble("latitude", center.latitude); + region.putDouble("longitude", center.longitude); + region.putDouble("latitudeDelta", bounds.northeast.latitude - bounds.southwest.latitude); + region.putDouble("longitudeDelta", bounds.northeast.longitude - bounds.southwest.longitude); + event.putMap("region", region); + + rctEventEmitter.receiveEvent(getViewTag(), getEventName(), event); + } } diff --git a/lib/android/src/main/java/com/airbnb/android/react/maps/SizeReportingShadowNode.java b/lib/android/src/main/java/com/airbnb/android/react/maps/SizeReportingShadowNode.java index 40ace480f..bf6c29d65 100644 --- a/lib/android/src/main/java/com/airbnb/android/react/maps/SizeReportingShadowNode.java +++ b/lib/android/src/main/java/com/airbnb/android/react/maps/SizeReportingShadowNode.java @@ -18,14 +18,14 @@ // which sends the width/height of the view after layout occurs. public class SizeReportingShadowNode extends LayoutShadowNode { - @Override - public void onCollectExtraUpdates(UIViewOperationQueue uiViewOperationQueue) { - super.onCollectExtraUpdates(uiViewOperationQueue); + @Override + public void onCollectExtraUpdates(UIViewOperationQueue uiViewOperationQueue) { + super.onCollectExtraUpdates(uiViewOperationQueue); - Map data = new HashMap<>(); - data.put("width", getLayoutWidth()); - data.put("height", getLayoutHeight()); + Map data = new HashMap<>(); + data.put("width", getLayoutWidth()); + data.put("height", getLayoutHeight()); - uiViewOperationQueue.enqueueUpdateExtraData(getReactTag(), data); - } + uiViewOperationQueue.enqueueUpdateExtraData(getReactTag(), data); + } } From d57edd2a095552999a961f210e610f0746f1470b Mon Sep 17 00:00:00 2001 From: Gabriel Peal Date: Tue, 27 Jun 2017 14:16:17 -0700 Subject: [PATCH 118/199] Allow react 16.0.0-alpha --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 30ffc43e8..ee92d4ab6 100644 --- a/package.json +++ b/package.json @@ -32,7 +32,7 @@ "mapkit" ], "peerDependencies": { - "react": ">=15.4.0", + "react": ">=15.4.0 || ^16.0.0-alpha", "react-native": ">=0.40" }, "devDependencies": { From ee1e7094be0eef6b5d01be64603d095841fff7fb Mon Sep 17 00:00:00 2001 From: Gabriel Peal Date: Tue, 27 Jun 2017 15:53:58 -0700 Subject: [PATCH 119/199] Use prop-types and add supprort for RN 0.45 --- .jscodeshiftignore | 9 +++++++++ example/android/app/build.gradle | 2 +- example/examples/EventListener.js | 2 +- lib/components/MapCallout.js | 3 ++- lib/components/MapCircle.js | 3 ++- lib/components/MapMarker.js | 3 ++- lib/components/MapPolygon.js | 3 ++- lib/components/MapPolyline.js | 3 ++- lib/components/MapUrlTile.js | 3 ++- lib/components/MapView.js | 3 ++- lib/components/decorateMapComponent.js | 2 +- package.json | 8 +++++--- 12 files changed, 31 insertions(+), 13 deletions(-) create mode 100644 .jscodeshiftignore diff --git a/.jscodeshiftignore b/.jscodeshiftignore new file mode 100644 index 000000000..a78536177 --- /dev/null +++ b/.jscodeshiftignore @@ -0,0 +1,9 @@ +# To run a codeshift on the react-native-maps library, cd to the root dir and run: +# jscodeshift -t PATH_TO_TRANSFORM . --ignore-config .jscodeshiftignore +.idea +android +docs +example +gradle +node_modules +scripts \ No newline at end of file diff --git a/example/android/app/build.gradle b/example/android/app/build.gradle index 7c63b3b43..7a8e8b7dd 100644 --- a/example/android/app/build.gradle +++ b/example/android/app/build.gradle @@ -127,7 +127,7 @@ android { } dependencies { - compile 'com.facebook.react:react-native:0.42.+' + compile 'com.facebook.react:react-native:0.45.+' compile 'com.android.support:appcompat-v7:25.3.0' compile 'com.android.support:support-annotations:25.3.0' compile project(':react-native-maps-lib') diff --git a/example/examples/EventListener.js b/example/examples/EventListener.js index c8d3e937f..19a393063 100644 --- a/example/examples/EventListener.js +++ b/example/examples/EventListener.js @@ -7,7 +7,7 @@ import { ScrollView, } from 'react-native'; // eslint-disable-next-line max-len -import SyntheticEvent from 'react-native/Libraries/Renderer/src/renderers/shared/stack/event/SyntheticEvent'; +import SyntheticEvent from 'react-native/Libraries/Renderer/src/renderers/shared/shared/event/SyntheticEvent'; import MapView from 'react-native-maps'; import PriceMarker from './PriceMarker'; diff --git a/lib/components/MapCallout.js b/lib/components/MapCallout.js index 8989df40c..226b52fe2 100644 --- a/lib/components/MapCallout.js +++ b/lib/components/MapCallout.js @@ -1,4 +1,5 @@ -import React, { PropTypes } from 'react'; +import PropTypes from 'prop-types'; +import React from 'react'; import { StyleSheet, ViewPropTypes, diff --git a/lib/components/MapCircle.js b/lib/components/MapCircle.js index a3371ca60..acf066b24 100644 --- a/lib/components/MapCircle.js +++ b/lib/components/MapCircle.js @@ -1,4 +1,5 @@ -import React, { PropTypes } from 'react'; +import PropTypes from 'prop-types'; +import React from 'react'; import { ViewPropTypes, } from 'react-native'; diff --git a/lib/components/MapMarker.js b/lib/components/MapMarker.js index 0589979fa..6e2b8585d 100644 --- a/lib/components/MapMarker.js +++ b/lib/components/MapMarker.js @@ -1,4 +1,5 @@ -import React, { PropTypes } from 'react'; +import PropTypes from 'prop-types'; +import React from 'react'; import { StyleSheet, Platform, diff --git a/lib/components/MapPolygon.js b/lib/components/MapPolygon.js index f88648fca..27f2aa322 100644 --- a/lib/components/MapPolygon.js +++ b/lib/components/MapPolygon.js @@ -1,4 +1,5 @@ -import React, { PropTypes } from 'react'; +import PropTypes from 'prop-types'; +import React from 'react'; import { ViewPropTypes, } from 'react-native'; diff --git a/lib/components/MapPolyline.js b/lib/components/MapPolyline.js index b2ecdffc1..af1573eff 100644 --- a/lib/components/MapPolyline.js +++ b/lib/components/MapPolyline.js @@ -1,4 +1,5 @@ -import React, { PropTypes } from 'react'; +import PropTypes from 'prop-types'; +import React from 'react'; import { ViewPropTypes, } from 'react-native'; diff --git a/lib/components/MapUrlTile.js b/lib/components/MapUrlTile.js index bb1d26552..f61c1e0d3 100644 --- a/lib/components/MapUrlTile.js +++ b/lib/components/MapUrlTile.js @@ -1,4 +1,5 @@ -import React, { PropTypes } from 'react'; +import PropTypes from 'prop-types'; +import React from 'react'; import { ViewPropTypes, diff --git a/lib/components/MapView.js b/lib/components/MapView.js index 0d8bf5450..a6660719a 100644 --- a/lib/components/MapView.js +++ b/lib/components/MapView.js @@ -1,4 +1,5 @@ -import React, { PropTypes } from 'react'; +import PropTypes from 'prop-types'; +import React from 'react'; import { EdgeInsetsPropType, Platform, diff --git a/lib/components/decorateMapComponent.js b/lib/components/decorateMapComponent.js index e655c4c33..168d4f122 100644 --- a/lib/components/decorateMapComponent.js +++ b/lib/components/decorateMapComponent.js @@ -1,4 +1,4 @@ -import { PropTypes } from 'react'; +import PropTypes from 'prop-types'; import { requireNativeComponent, NativeModules, diff --git a/package.json b/package.json index ee92d4ab6..275ea4349 100644 --- a/package.json +++ b/package.json @@ -33,7 +33,8 @@ ], "peerDependencies": { "react": ">=15.4.0 || ^16.0.0-alpha", - "react-native": ">=0.40" + "react-native": ">=0.40", + "prop-types": "^15.5.10" }, "devDependencies": { "babel-eslint": "^6.1.2", @@ -48,8 +49,9 @@ "eslint-plugin-react": "^6.1.2", "gitbook-cli": "^2.3.0", "lodash": "^4.17.2", - "react": "~15.4.1", - "react-native": "^0.42.0" + "prop-types": "^15.5.10", + "react": "^16.0.0-alpha.12", + "react-native": "^0.45.1" }, "rnpm": { "android": { From 8a5a8d1decb0666da4f4845bb5ff753967c5df29 Mon Sep 17 00:00:00 2001 From: Gabriel Peal Date: Tue, 27 Jun 2017 16:09:58 -0700 Subject: [PATCH 120/199] Upgraded ios deps --- example/ios/Podfile.lock | 46 ++++++++++++++++++---------------------- examples/ios/bundler | 17 +++++++++++++++ examples/ios/fuzzy_match | 17 +++++++++++++++ examples/ios/pod | 17 +++++++++++++++ examples/ios/sandbox-pod | 17 +++++++++++++++ examples/ios/xcodeproj | 17 +++++++++++++++ 6 files changed, 106 insertions(+), 25 deletions(-) create mode 100755 examples/ios/bundler create mode 100755 examples/ios/fuzzy_match create mode 100755 examples/ios/pod create mode 100755 examples/ios/sandbox-pod create mode 100755 examples/ios/xcodeproj diff --git a/example/ios/Podfile.lock b/example/ios/Podfile.lock index ff6774aa2..3cf7f4d85 100644 --- a/example/ios/Podfile.lock +++ b/example/ios/Podfile.lock @@ -4,41 +4,37 @@ PODS: - GoogleMaps/Base (2.1.1) - GoogleMaps/Maps (2.1.1): - GoogleMaps/Base - - React (0.42.3): - - React/Core (= 0.42.3) - - react-native-google-maps (0.13.1): + - React (0.45.1): + - React/Core (= 0.45.1) + - react-native-google-maps (0.15.2): - GoogleMaps (= 2.1.1) - React - - react-native-maps (0.13.1): + - react-native-maps (0.15.2): - React - - React/Core (0.42.3): - - React/cxxreact - - Yoga (= 0.42.3.React) - - React/cxxreact (0.42.3): - - React/jschelpers - - React/jschelpers (0.42.3) - - React/RCTActionSheet (0.42.3): + - React/Core (0.45.1): + - Yoga (= 0.45.1.React) + - React/RCTActionSheet (0.45.1): - React/Core - - React/RCTAnimation (0.42.3): + - React/RCTAnimation (0.45.1): - React/Core - - React/RCTGeolocation (0.42.3): + - React/RCTGeolocation (0.45.1): - React/Core - - React/RCTImage (0.42.3): + - React/RCTImage (0.45.1): - React/Core - React/RCTNetwork - - React/RCTLinkingIOS (0.42.3): + - React/RCTLinkingIOS (0.45.1): - React/Core - - React/RCTNetwork (0.42.3): + - React/RCTNetwork (0.45.1): - React/Core - - React/RCTSettings (0.42.3): + - React/RCTSettings (0.45.1): - React/Core - - React/RCTText (0.42.3): + - React/RCTText (0.45.1): - React/Core - - React/RCTVibration (0.42.3): + - React/RCTVibration (0.45.1): - React/Core - - React/RCTWebSocket (0.42.3): + - React/RCTWebSocket (0.45.1): - React/Core - - Yoga (0.42.3.React) + - Yoga (0.45.1.React) DEPENDENCIES: - GoogleMaps @@ -69,10 +65,10 @@ EXTERNAL SOURCES: SPEC CHECKSUMS: GoogleMaps: a5b5bbe47734e2443bde781a6aa64e69fdb6d785 - React: 35e039680feacd0563677d49ba410112d2748559 - react-native-google-maps: b2668747ec289759993dc2411a7078afafa8adea - react-native-maps: 326ddbaaea8f6044b1817fb028c40950c71cc38a - Yoga: 86ce777665c8259b94ef8dbea76b84634237f4ea + React: 0c9191a8b0c843d7004f950ac6b5f6cba9d125c7 + react-native-google-maps: d0b8772eb76e1615ea32c73bc9d573360b8c0817 + react-native-maps: fe2e4680b4d3fcfd84d636ccedd470fe358d55e1 + Yoga: 89c8738d42a0b46a113acb4e574336d61cba2985 PODFILE CHECKSUM: 222d08e48f834b6a3de650b72786105af7a9d331 diff --git a/examples/ios/bundler b/examples/ios/bundler new file mode 100755 index 000000000..905387619 --- /dev/null +++ b/examples/ios/bundler @@ -0,0 +1,17 @@ +#!/usr/bin/env ruby +# frozen_string_literal: true +# +# This file was generated by Bundler. +# +# The application 'bundler' is installed as part of a gem, and +# this file is here to facilitate running it. +# + +require "pathname" +ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../../Gemfile", + Pathname.new(__FILE__).realpath) + +require "rubygems" +require "bundler/setup" + +load Gem.bin_path("bundler", "bundler") diff --git a/examples/ios/fuzzy_match b/examples/ios/fuzzy_match new file mode 100755 index 000000000..f71547393 --- /dev/null +++ b/examples/ios/fuzzy_match @@ -0,0 +1,17 @@ +#!/usr/bin/env ruby +# frozen_string_literal: true +# +# This file was generated by Bundler. +# +# The application 'fuzzy_match' is installed as part of a gem, and +# this file is here to facilitate running it. +# + +require "pathname" +ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../../Gemfile", + Pathname.new(__FILE__).realpath) + +require "rubygems" +require "bundler/setup" + +load Gem.bin_path("fuzzy_match", "fuzzy_match") diff --git a/examples/ios/pod b/examples/ios/pod new file mode 100755 index 000000000..3c4a4d04c --- /dev/null +++ b/examples/ios/pod @@ -0,0 +1,17 @@ +#!/usr/bin/env ruby +# frozen_string_literal: true +# +# This file was generated by Bundler. +# +# The application 'pod' is installed as part of a gem, and +# this file is here to facilitate running it. +# + +require "pathname" +ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../../Gemfile", + Pathname.new(__FILE__).realpath) + +require "rubygems" +require "bundler/setup" + +load Gem.bin_path("cocoapods", "pod") diff --git a/examples/ios/sandbox-pod b/examples/ios/sandbox-pod new file mode 100755 index 000000000..c76cfd0a5 --- /dev/null +++ b/examples/ios/sandbox-pod @@ -0,0 +1,17 @@ +#!/usr/bin/env ruby +# frozen_string_literal: true +# +# This file was generated by Bundler. +# +# The application 'sandbox-pod' is installed as part of a gem, and +# this file is here to facilitate running it. +# + +require "pathname" +ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../../Gemfile", + Pathname.new(__FILE__).realpath) + +require "rubygems" +require "bundler/setup" + +load Gem.bin_path("cocoapods", "sandbox-pod") diff --git a/examples/ios/xcodeproj b/examples/ios/xcodeproj new file mode 100755 index 000000000..3c3452c17 --- /dev/null +++ b/examples/ios/xcodeproj @@ -0,0 +1,17 @@ +#!/usr/bin/env ruby +# frozen_string_literal: true +# +# This file was generated by Bundler. +# +# The application 'xcodeproj' is installed as part of a gem, and +# this file is here to facilitate running it. +# + +require "pathname" +ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../../Gemfile", + Pathname.new(__FILE__).realpath) + +require "rubygems" +require "bundler/setup" + +load Gem.bin_path("xcodeproj", "xcodeproj") From 0a8f6ce7ec2aaeaddfab48a55ce4562328409987 Mon Sep 17 00:00:00 2001 From: Gabriel Peal Date: Tue, 27 Jun 2017 16:25:03 -0700 Subject: [PATCH 121/199] Added BatchedBridge --- example/ios/Podfile | 3 ++- example/ios/Podfile.lock | 9 ++++++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/example/ios/Podfile b/example/ios/Podfile index 6cff9aae8..656f283e1 100644 --- a/example/ios/Podfile +++ b/example/ios/Podfile @@ -18,7 +18,8 @@ target 'AirMapsExplorer' do 'RCTSettings', 'RCTText', 'RCTVibration', - 'RCTWebSocket' + 'RCTWebSocket', + 'BatchedBridge' ] pod 'GoogleMaps' # <~~ remove this line if you do not want to support GoogleMaps on iOS diff --git a/example/ios/Podfile.lock b/example/ios/Podfile.lock index 3cf7f4d85..3eec18fee 100644 --- a/example/ios/Podfile.lock +++ b/example/ios/Podfile.lock @@ -11,8 +11,14 @@ PODS: - React - react-native-maps (0.15.2): - React + - React/BatchedBridge (0.45.1): + - React/Core + - React/cxxreact_legacy - React/Core (0.45.1): - Yoga (= 0.45.1.React) + - React/cxxreact_legacy (0.45.1): + - React/jschelpers_legacy + - React/jschelpers_legacy (0.45.1) - React/RCTActionSheet (0.45.1): - React/Core - React/RCTAnimation (0.45.1): @@ -40,6 +46,7 @@ DEPENDENCIES: - GoogleMaps - react-native-google-maps (from `../../`) - react-native-maps (from `../../`) + - React/BatchedBridge (from `../../node_modules/react-native`) - React/Core (from `../../node_modules/react-native`) - React/RCTActionSheet (from `../../node_modules/react-native`) - React/RCTAnimation (from `../../node_modules/react-native`) @@ -70,6 +77,6 @@ SPEC CHECKSUMS: react-native-maps: fe2e4680b4d3fcfd84d636ccedd470fe358d55e1 Yoga: 89c8738d42a0b46a113acb4e574336d61cba2985 -PODFILE CHECKSUM: 222d08e48f834b6a3de650b72786105af7a9d331 +PODFILE CHECKSUM: 8b3eb68ef6553bf1fcb8a467e0e63000b37ec692 COCOAPODS: 1.2.0 From 153e83def147395041e18709c40c7f19633de2c2 Mon Sep 17 00:00:00 2001 From: Gabriel Peal Date: Tue, 27 Jun 2017 16:54:34 -0700 Subject: [PATCH 122/199] v0.15.3 --- CHANGELOG.md | 8 ++++++++ lib/android/gradle.properties | 2 +- package.json | 2 +- 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5968b7e7b..50b2027bc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,13 @@ # Change Log +## 0.15.3 (June 27, 2017) + +* iOS: [#1362](https://github.com/airbnb/react-native-maps/pull/1362) Updates for React 0.43-0.45 and React 16. +* JS: [#1323](https://github.com/airbnb/react-native-maps/pull/1323) Updates for React 0.43-0.45 and React 16. +* Android/iOS/JS: [#1440](https://github.com/airbnb/react-native-maps/pull/1440) Updates for React 0.43-0.45 and React 16. +* iOS: [#1115](https://github.com/airbnb/react-native-maps/pull/1115) Fix animateToCoordinate and animateToRegion +* Android: [#1403](https://github.com/airbnb/react-native-maps/pull/1403) Fix an NPE + ## 0.15.2 (May 20, 2017) * iOS: [#1351](https://github.com/airbnb/react-native-maps/pull/1351) Fix file references diff --git a/lib/android/gradle.properties b/lib/android/gradle.properties index 65c67798d..1a5d3021b 100644 --- a/lib/android/gradle.properties +++ b/lib/android/gradle.properties @@ -1,5 +1,5 @@ VERSION_CODE=4 -VERSION_NAME=0.15.2 +VERSION_NAME=0.15.3 GROUP=com.airbnb.android POM_DESCRIPTION=React Native Map view component for Android diff --git a/package.json b/package.json index 275ea4349..7cb48301b 100644 --- a/package.json +++ b/package.json @@ -3,7 +3,7 @@ "description": "React Native Mapview component for iOS + Android", "main": "index.js", "author": "Leland Richardson ", - "version": "0.15.2", + "version": "0.15.3", "scripts": { "start": "node node_modules/react-native/local-cli/cli.js start", "run:packager": "./node_modules/react-native/packager/packager.sh", From 5e6d74e3039197d98dbfe95604dae783946080fc Mon Sep 17 00:00:00 2001 From: foysal Date: Wed, 5 Jul 2017 20:49:34 +0200 Subject: [PATCH 123/199] updates npm cache clean command (#1450) latest version of npm seems to be missing the command ```npm clean cache``` but ```npm cache clean``` seems to work. Might help copy-pasters like me. --- docs/installation.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/installation.md b/docs/installation.md index 12842d7c6..52063bef9 100644 --- a/docs/installation.md +++ b/docs/installation.md @@ -203,7 +203,7 @@ Enter the name of the API key and create it. 1. Clean the cache : ``` watchman watch-del-all - npm clean cache + npm cache clean ``` 1. When starting emulator, make sure you have enabled `Wipe user data`. From eb9eb0fe9549949dfbc7f51001dab52c98126909 Mon Sep 17 00:00:00 2001 From: Jacob Morris Date: Thu, 6 Jul 2017 04:50:23 +1000 Subject: [PATCH 124/199] Reference install solution in issue #718 in install docs (#1448) --- docs/installation.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/installation.md b/docs/installation.md index 52063bef9..ad9d4b383 100644 --- a/docs/installation.md +++ b/docs/installation.md @@ -123,6 +123,8 @@ Source: https://developers.google.com/maps/documentation/android-api/signup ## Troubleshooting +If you get the error `duplicate symbols for architecture x86_64` when building for iOS, you may need to reconfigure your linking and Podfile as [described in detail in this comment on issue #718](https://github.com/airbnb/react-native-maps/issues/718#issuecomment-295585410) + If you have a blank map issue, ([#118](https://github.com/airbnb/react-native-maps/issues/118), [#176](https://github.com/airbnb/react-native-maps/issues/176), [#684](https://github.com/airbnb/react-native-maps/issues/684)), try the following lines : ### On iOS: From 045ec7eee5f90d06b00f1eb624453d6a7d02df92 Mon Sep 17 00:00:00 2001 From: foyarash Date: Wed, 5 Jul 2017 21:43:45 +0200 Subject: [PATCH 125/199] Add minZoom and maxZoom properties for android and ios (#1360) * Add minZoom and maxZoom properties for android and ios * Add min/max zoom level properties to AIRMap.h * Fix assignation for zoom levels for gmaps ios * Resolve conflicts, fix potential nil value on ios * Resolve conflicts --- .../android/react/maps/AirMapManager.java | 10 ++ lib/components/MapView.js | 10 ++ lib/ios/AirGoogleMaps/AIRGoogleMap.m | 7 + lib/ios/AirGoogleMaps/AIRGoogleMapManager.m | 2 + lib/ios/AirMaps/AIRMap.h | 2 + lib/ios/AirMaps/AIRMapManager.h | 16 ++ lib/ios/AirMaps/AIRMapManager.m | 169 ++++++++++++++++++ 7 files changed, 216 insertions(+) diff --git a/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapManager.java b/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapManager.java index 404f6a127..e8f98a766 100644 --- a/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapManager.java +++ b/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapManager.java @@ -178,6 +178,16 @@ public void setPitchEnabled(AirMapView view, boolean pitchEnabled) { view.map.getUiSettings().setTiltGesturesEnabled(pitchEnabled); } + @ReactProp(name = "minZoomLevel") + public void setMinZoomLevel(AirMapView view, float minZoomLevel) { + view.map.setMinZoomPreference(minZoomLevel); + } + + @ReactProp(name = "maxZoomLevel") + public void setMaxZoomLevel(AirMapView view, float maxZoomLevel) { + view.map.setMaxZoomPreference(maxZoomLevel); + } + @Override public void receiveCommand(AirMapView view, int commandId, @Nullable ReadableArray args) { Integer duration; diff --git a/lib/components/MapView.js b/lib/components/MapView.js index a6660719a..2e8ba4e84 100644 --- a/lib/components/MapView.js +++ b/lib/components/MapView.js @@ -385,6 +385,16 @@ const propTypes = { */ onMarkerDragEnd: PropTypes.func, + /** + * Minimum zoom value for the map, must be between 0 and 20 + */ + minZoomLevel: PropTypes.number, + + /** + * Maximum zoom value for the map, must be between 0 and 20 + */ + maxZoomLevel: PropTypes.number, + }; class MapView extends React.Component { diff --git a/lib/ios/AirGoogleMaps/AIRGoogleMap.m b/lib/ios/AirGoogleMaps/AIRGoogleMap.m index ef73067b6..f87d34c63 100644 --- a/lib/ios/AirGoogleMaps/AIRGoogleMap.m +++ b/lib/ios/AirGoogleMaps/AIRGoogleMap.m @@ -300,6 +300,13 @@ - (BOOL)showsMyLocationButton { return self.settings.myLocationButton; } +- (void)setMinZoomLevel:(CGFloat)minZoomLevel { + [self setMinZoom:minZoomLevel maxZoom:self.maxZoom ]; +} + +- (void)setMaxZoomLevel:(CGFloat)maxZoomLevel { + [self setMinZoom:self.minZoom maxZoom:maxZoomLevel ]; +} + (MKCoordinateRegion) makeGMSCameraPositionFromMap:(GMSMapView *)map andGMSCameraPosition:(GMSCameraPosition *)position { // solution from here: http://stackoverflow.com/a/16587735/1102215 diff --git a/lib/ios/AirGoogleMaps/AIRGoogleMapManager.m b/lib/ios/AirGoogleMaps/AIRGoogleMapManager.m index 6a3b92e90..c482305b8 100644 --- a/lib/ios/AirGoogleMaps/AIRGoogleMapManager.m +++ b/lib/ios/AirGoogleMaps/AIRGoogleMapManager.m @@ -66,6 +66,8 @@ - (UIView *)view RCT_EXPORT_VIEW_PROPERTY(onRegionChange, RCTDirectEventBlock) RCT_EXPORT_VIEW_PROPERTY(onRegionChangeComplete, RCTDirectEventBlock) RCT_EXPORT_VIEW_PROPERTY(mapType, GMSMapViewType) +RCT_EXPORT_VIEW_PROPERTY(minZoomLevel, CGFloat) +RCT_EXPORT_VIEW_PROPERTY(maxZoomLevel, CGFloat) RCT_EXPORT_METHOD(animateToRegion:(nonnull NSNumber *)reactTag withRegion:(MKCoordinateRegion)region diff --git a/lib/ios/AirMaps/AIRMap.h b/lib/ios/AirMaps/AIRMap.h index 18c9a0bc0..4a88617e6 100644 --- a/lib/ios/AirMaps/AIRMap.h +++ b/lib/ios/AirMaps/AIRMap.h @@ -37,6 +37,8 @@ extern const CGFloat AIRMapZoomBoundBuffer; @property (nonatomic, assign) UIEdgeInsets legalLabelInsets; @property (nonatomic, strong) NSTimer *regionChangeObserveTimer; @property (nonatomic, assign) MKCoordinateRegion initialRegion; +@property (nonatomic, assign) CGFloat minZoomLevel; +@property (nonatomic, assign) CGFloat maxZoomLevel; @property (nonatomic, assign) CLLocationCoordinate2D pendingCenter; @property (nonatomic, assign) MKCoordinateSpan pendingSpan; diff --git a/lib/ios/AirMaps/AIRMapManager.h b/lib/ios/AirMaps/AIRMapManager.h index cc9a8c75b..29df98bfc 100644 --- a/lib/ios/AirMaps/AIRMapManager.h +++ b/lib/ios/AirMaps/AIRMapManager.h @@ -8,7 +8,23 @@ */ #import +#import "AIRMap.h" + +#define MERCATOR_RADIUS 85445659.44705395 +#define MERCATOR_OFFSET 268435456 +#define MAX_GOOGLE_LEVELS 20 @interface AIRMapManager : RCTViewManager + +- (void)setCenterCoordinate:(CLLocationCoordinate2D)centerCoordinate + zoomLevel:(double)zoomLevel + animated:(BOOL)animated + mapView:(AIRMap *)mapView; + +- (MKCoordinateRegion)coordinateRegionWithMapView:(AIRMap *)mapView + centerCoordinate:(CLLocationCoordinate2D)centerCoordinate + andZoomLevel:(double)zoomLevel; +- (double) zoomLevel:(AIRMap *)mapView; + @end diff --git a/lib/ios/AirMaps/AIRMapManager.m b/lib/ios/AirMaps/AIRMapManager.m index 619142bd6..8ea247244 100644 --- a/lib/ios/AirMaps/AIRMapManager.m +++ b/lib/ios/AirMaps/AIRMapManager.m @@ -97,6 +97,9 @@ - (UIView *)view RCT_EXPORT_VIEW_PROPERTY(onMarkerDragEnd, RCTDirectEventBlock) RCT_EXPORT_VIEW_PROPERTY(onCalloutPress, RCTDirectEventBlock) RCT_EXPORT_VIEW_PROPERTY(initialRegion, MKCoordinateRegion) +RCT_EXPORT_VIEW_PROPERTY(minZoomLevel, CGFloat) +RCT_EXPORT_VIEW_PROPERTY(maxZoomLevel, CGFloat) + RCT_CUSTOM_VIEW_PROPERTY(region, MKCoordinateRegion, AIRMap) { @@ -625,11 +628,19 @@ - (void)mapView:(AIRMap *)mapView regionWillChangeAnimated:(__unused BOOL)animat - (void)mapView:(AIRMap *)mapView regionDidChangeAnimated:(__unused BOOL)animated { + CGFloat zoomLevel = [self zoomLevel:mapView]; [mapView.regionChangeObserveTimer invalidate]; mapView.regionChangeObserveTimer = nil; [self _regionChanged:mapView]; + if (mapView.minZoomLevel != nil && zoomLevel < mapView.minZoomLevel) { + [self setCenterCoordinate:[mapView centerCoordinate] zoomLevel:mapView.minZoomLevel animated:TRUE mapView:mapView]; + } + else if (mapView.maxZoomLevel != nil && zoomLevel > mapView.maxZoomLevel) { + [self setCenterCoordinate:[mapView centerCoordinate] zoomLevel:mapView.maxZoomLevel animated:TRUE mapView:mapView]; + } + // Don't send region did change events until map has // started rendering, as these won't represent the final location if (mapView.hasStartedRendering) { @@ -665,6 +676,7 @@ - (void)_regionChanged:(AIRMap *)mapView BOOL needZoom = NO; CGFloat newLongitudeDelta = 0.0f; MKCoordinateRegion region = mapView.region; + CGFloat zoomLevel = [self zoomLevel:mapView]; // On iOS 7, it's possible that we observe invalid locations during initialization of the map. // Filter those out. if (!CLLocationCoordinate2DIsValid(region.center)) { @@ -759,4 +771,161 @@ - (double)metersFromPixel:(NSUInteger)px atPoint:(CGPoint)pt forMap:(AIRMap *)ma return MKMetersBetweenMapPoints(MKMapPointForCoordinate(coordA), MKMapPointForCoordinate(coordB)); } ++ (double)longitudeToPixelSpaceX:(double)longitude +{ + return round(MERCATOR_OFFSET + MERCATOR_RADIUS * longitude * M_PI / 180.0); +} + ++ (double)latitudeToPixelSpaceY:(double)latitude +{ + if (latitude == 90.0) { + return 0; + } else if (latitude == -90.0) { + return MERCATOR_OFFSET * 2; + } else { + return round(MERCATOR_OFFSET - MERCATOR_RADIUS * logf((1 + sinf(latitude * M_PI / 180.0)) / (1 - sinf(latitude * M_PI / 180.0))) / 2.0); + } +} + ++ (double)pixelSpaceXToLongitude:(double)pixelX +{ + return ((round(pixelX) - MERCATOR_OFFSET) / MERCATOR_RADIUS) * 180.0 / M_PI; +} + ++ (double)pixelSpaceYToLatitude:(double)pixelY +{ + return (M_PI / 2.0 - 2.0 * atan(exp((round(pixelY) - MERCATOR_OFFSET) / MERCATOR_RADIUS))) * 180.0 / M_PI; +} + +#pragma mark - +#pragma mark Helper methods + +- (MKCoordinateSpan)coordinateSpanWithMapView:(AIRMap *)mapView + centerCoordinate:(CLLocationCoordinate2D)centerCoordinate + andZoomLevel:(double)zoomLevel +{ + // convert center coordiate to pixel space + double centerPixelX = [AIRMapManager longitudeToPixelSpaceX:centerCoordinate.longitude]; + double centerPixelY = [AIRMapManager latitudeToPixelSpaceY:centerCoordinate.latitude]; + + // determine the scale value from the zoom level + double zoomExponent = 20 - zoomLevel; + double zoomScale = pow(2, zoomExponent); + + // scale the map’s size in pixel space + CGSize mapSizeInPixels = mapView.bounds.size; + double scaledMapWidth = mapSizeInPixels.width * zoomScale; + double scaledMapHeight = mapSizeInPixels.height * zoomScale; + + // figure out the position of the top-left pixel + double topLeftPixelX = centerPixelX - (scaledMapWidth / 2); + double topLeftPixelY = centerPixelY - (scaledMapHeight / 2); + + // find delta between left and right longitudes + CLLocationDegrees minLng = [AIRMapManager pixelSpaceXToLongitude:topLeftPixelX]; + CLLocationDegrees maxLng = [AIRMapManager pixelSpaceXToLongitude:topLeftPixelX + scaledMapWidth]; + CLLocationDegrees longitudeDelta = maxLng - minLng; + + // find delta between top and bottom latitudes + CLLocationDegrees minLat = [AIRMapManager pixelSpaceYToLatitude:topLeftPixelY]; + CLLocationDegrees maxLat = [AIRMapManager pixelSpaceYToLatitude:topLeftPixelY + scaledMapHeight]; + CLLocationDegrees latitudeDelta = -1 * (maxLat - minLat); + + // create and return the lat/lng span + MKCoordinateSpan span = MKCoordinateSpanMake(latitudeDelta, longitudeDelta); + return span; +} + +#pragma mark - +#pragma mark Public methods + +- (void)setCenterCoordinate:(CLLocationCoordinate2D)centerCoordinate + zoomLevel:(double)zoomLevel + animated:(BOOL)animated + mapView:(AIRMap *)mapView +{ + // clamp large numbers to 28 + zoomLevel = MIN(zoomLevel, 28); + + // use the zoom level to compute the region + MKCoordinateSpan span = [self coordinateSpanWithMapView:mapView centerCoordinate:centerCoordinate andZoomLevel:zoomLevel]; + MKCoordinateRegion region = MKCoordinateRegionMake(centerCoordinate, span); + + // set the region like normal + [mapView setRegion:region animated:animated]; +} + +//KMapView cannot display tiles that cross the pole (as these would involve wrapping the map from top to bottom, something that a Mercator projection just cannot do). +-(MKCoordinateRegion)coordinateRegionWithMapView:(AIRMap *)mapView + centerCoordinate:(CLLocationCoordinate2D)centerCoordinate + andZoomLevel:(double)zoomLevel +{ + // clamp lat/long values to appropriate ranges + centerCoordinate.latitude = MIN(MAX(-90.0, centerCoordinate.latitude), 90.0); + centerCoordinate.longitude = fmod(centerCoordinate.longitude, 180.0); + + // convert center coordiate to pixel space + double centerPixelX = [AIRMapManager longitudeToPixelSpaceX:centerCoordinate.longitude]; + double centerPixelY = [AIRMapManager latitudeToPixelSpaceY:centerCoordinate.latitude]; + + // determine the scale value from the zoom level + double zoomExponent = 20 - zoomLevel; + double zoomScale = pow(2, zoomExponent); + + // scale the map’s size in pixel space + CGSize mapSizeInPixels = mapView.bounds.size; + double scaledMapWidth = mapSizeInPixels.width * zoomScale; + double scaledMapHeight = mapSizeInPixels.height * zoomScale; + + // figure out the position of the left pixel + double topLeftPixelX = centerPixelX - (scaledMapWidth / 2); + + // find delta between left and right longitudes + CLLocationDegrees minLng = [AIRMapManager pixelSpaceXToLongitude:topLeftPixelX]; + CLLocationDegrees maxLng = [AIRMapManager pixelSpaceXToLongitude:topLeftPixelX + scaledMapWidth]; + CLLocationDegrees longitudeDelta = maxLng - minLng; + + // if we’re at a pole then calculate the distance from the pole towards the equator + // as MKMapView doesn’t like drawing boxes over the poles + double topPixelY = centerPixelY - (scaledMapHeight / 2); + double bottomPixelY = centerPixelY + (scaledMapHeight / 2); + BOOL adjustedCenterPoint = NO; + if (topPixelY > MERCATOR_OFFSET * 2) { + topPixelY = centerPixelY - scaledMapHeight; + bottomPixelY = MERCATOR_OFFSET * 2; + adjustedCenterPoint = YES; + } + + // find delta between top and bottom latitudes + CLLocationDegrees minLat = [AIRMapManager pixelSpaceYToLatitude:topPixelY]; + CLLocationDegrees maxLat = [AIRMapManager pixelSpaceYToLatitude:bottomPixelY]; + CLLocationDegrees latitudeDelta = -1 * (maxLat - minLat); + + // create and return the lat/lng span + MKCoordinateSpan span = MKCoordinateSpanMake(latitudeDelta, longitudeDelta); + MKCoordinateRegion region = MKCoordinateRegionMake(centerCoordinate, span); + // once again, MKMapView doesn’t like drawing boxes over the poles + // so adjust the center coordinate to the center of the resulting region + if (adjustedCenterPoint) { + region.center.latitude = [AIRMapManager pixelSpaceYToLatitude:((bottomPixelY + topPixelY) / 2.0)]; + } + + return region; +} + +- (double) zoomLevel:(AIRMap *)mapView { + MKCoordinateRegion region = mapView.region; + + double centerPixelX = [AIRMapManager longitudeToPixelSpaceX: region.center.longitude]; + double topLeftPixelX = [AIRMapManager longitudeToPixelSpaceX: region.center.longitude - region.span.longitudeDelta / 2]; + + double scaledMapWidth = (centerPixelX - topLeftPixelX) * 2; + CGSize mapSizeInPixels = mapView.bounds.size; + double zoomScale = scaledMapWidth / mapSizeInPixels.width; + double zoomExponent = log(zoomScale) / log(2); + double zoomLevel = 20 - zoomExponent; + + return zoomLevel; +} + @end From 8a86e9899dc5674516e5fea374ae307d59732bdc Mon Sep 17 00:00:00 2001 From: Yann Pringault Date: Thu, 6 Jul 2017 18:26:40 +0200 Subject: [PATCH 126/199] Add onMapReady callback (#1369) * Add onMapReady callback Fix #246 * Call onMapReady when state has changed * Add onMapReady callback on iOS --- docs/mapview.md | 1 + lib/components/MapView.js | 11 +++++++++-- lib/ios/AirGoogleMaps/AIRGoogleMap.h | 2 ++ lib/ios/AirGoogleMaps/AIRGoogleMap.m | 4 ++++ lib/ios/AirGoogleMaps/AIRGoogleMapManager.m | 6 ++++++ lib/ios/AirMaps/AIRMap.h | 1 + lib/ios/AirMaps/AIRMapManager.m | 3 +++ 7 files changed, 26 insertions(+), 2 deletions(-) diff --git a/docs/mapview.md b/docs/mapview.md index 3df5640c3..e8b86aee6 100644 --- a/docs/mapview.md +++ b/docs/mapview.md @@ -40,6 +40,7 @@ To access event data, you will need to use `e.nativeEvent`. For example, `onPres | Event Name | Returns | Notes |---|---|---| +| `onMapReady` | | Callback that is called once the map is fully loaded. | `onRegionChange` | `Region` | Callback that is called continuously when the region changes, such as when a user is dragging the map. | `onRegionChangeComplete` | `Region` | Callback that is called once when the region changes, such as when the user is done moving the map. | `onPress` | `{ coordinate: LatLng, position: Point }` | Callback that is called when user taps on the map. diff --git a/lib/components/MapView.js b/lib/components/MapView.js index 2e8ba4e84..e3763f8f3 100644 --- a/lib/components/MapView.js +++ b/lib/components/MapView.js @@ -318,6 +318,11 @@ const propTypes = { */ legalLabelInsets: EdgeInsetsPropType, + /** + * Callback that is called once the map is fully loaded. + */ + onMapReady: PropTypes.func, + /** * Callback that is called continuously when the user is dragging the map. */ @@ -441,14 +446,16 @@ class MapView extends React.Component { } _onMapReady() { - const { region, initialRegion } = this.props; + const { region, initialRegion, onMapReady } = this.props; if (region) { this.map.setNativeProps({ region }); } else if (initialRegion) { this.map.setNativeProps({ region: initialRegion }); } this._updateStyle(); - this.setState({ isReady: true }); + this.setState({ isReady: true }, () => { + if (onMapReady) onMapReady(); + }); } _onLayout(e) { diff --git a/lib/ios/AirGoogleMaps/AIRGoogleMap.h b/lib/ios/AirGoogleMaps/AIRGoogleMap.h index 0e9554eb6..0d47b72b1 100644 --- a/lib/ios/AirGoogleMaps/AIRGoogleMap.h +++ b/lib/ios/AirGoogleMaps/AIRGoogleMap.h @@ -18,6 +18,7 @@ @property (nonatomic, assign) MKCoordinateRegion initialRegion; @property (nonatomic, assign) MKCoordinateRegion region; @property (nonatomic, assign) NSString *customMapStyleString; +@property (nonatomic, copy) RCTBubblingEventBlock onMapReady; @property (nonatomic, copy) RCTBubblingEventBlock onPress; @property (nonatomic, copy) RCTBubblingEventBlock onLongPress; @property (nonatomic, copy) RCTBubblingEventBlock onMarkerPress; @@ -40,6 +41,7 @@ @property (nonatomic, assign) BOOL showsUserLocation; @property (nonatomic, assign) BOOL showsMyLocationButton; +- (void)didFinishTileRendering; - (BOOL)didTapMarker:(GMSMarker *)marker; - (void)didTapPolyline:(GMSPolyline *)polyline; - (void)didTapPolygon:(GMSPolygon *)polygon; diff --git a/lib/ios/AirGoogleMaps/AIRGoogleMap.m b/lib/ios/AirGoogleMaps/AIRGoogleMap.m index f87d34c63..48b5ff446 100644 --- a/lib/ios/AirGoogleMaps/AIRGoogleMap.m +++ b/lib/ios/AirGoogleMaps/AIRGoogleMap.m @@ -155,6 +155,10 @@ - (void)setRegion:(MKCoordinateRegion)region { self.camera = [AIRGoogleMap makeGMSCameraPositionFromMap:self andMKCoordinateRegion:region]; } +- (void)didFinishTileRendering { + if (self.onMapReady) self.onMapReady(@{}); +} + - (BOOL)didTapMarker:(GMSMarker *)marker { AIRGMSMarker *airMarker = (AIRGMSMarker *)marker; diff --git a/lib/ios/AirGoogleMaps/AIRGoogleMapManager.m b/lib/ios/AirGoogleMaps/AIRGoogleMapManager.m index c482305b8..53157e99a 100644 --- a/lib/ios/AirGoogleMaps/AIRGoogleMapManager.m +++ b/lib/ios/AirGoogleMaps/AIRGoogleMapManager.m @@ -59,6 +59,7 @@ - (UIView *)view RCT_EXPORT_VIEW_PROPERTY(showsUserLocation, BOOL) RCT_EXPORT_VIEW_PROPERTY(showsMyLocationButton, BOOL) RCT_EXPORT_VIEW_PROPERTY(customMapStyleString, NSString) +RCT_EXPORT_VIEW_PROPERTY(onMapReady, RCTBubblingEventBlock) RCT_EXPORT_VIEW_PROPERTY(onPress, RCTBubblingEventBlock) RCT_EXPORT_VIEW_PROPERTY(onLongPress, RCTBubblingEventBlock) RCT_EXPORT_VIEW_PROPERTY(onChange, RCTBubblingEventBlock) @@ -222,6 +223,11 @@ - (UIView *)view } +- (void)mapViewDidFinishTileRendering:(GMSMapView *)mapView { + AIRGoogleMap *googleMapView = (AIRGoogleMap *)mapView; + [googleMapView didFinishTileRendering]; +} + - (BOOL)mapView:(GMSMapView *)mapView didTapMarker:(GMSMarker *)marker { AIRGoogleMap *googleMapView = (AIRGoogleMap *)mapView; return [googleMapView didTapMarker:marker]; diff --git a/lib/ios/AirMaps/AIRMap.h b/lib/ios/AirMaps/AIRMap.h index 4a88617e6..48a07ddb2 100644 --- a/lib/ios/AirMaps/AIRMap.h +++ b/lib/ios/AirMaps/AIRMap.h @@ -46,6 +46,7 @@ extern const CGFloat AIRMapZoomBoundBuffer; @property (nonatomic, assign) BOOL ignoreRegionChanges; +@property (nonatomic, copy) RCTBubblingEventBlock onMapReady; @property (nonatomic, copy) RCTBubblingEventBlock onChange; @property (nonatomic, copy) RCTBubblingEventBlock onPress; @property (nonatomic, copy) RCTBubblingEventBlock onPanDrag; diff --git a/lib/ios/AirMaps/AIRMapManager.m b/lib/ios/AirMaps/AIRMapManager.m index 8ea247244..e99249ace 100644 --- a/lib/ios/AirMaps/AIRMapManager.m +++ b/lib/ios/AirMaps/AIRMapManager.m @@ -85,6 +85,7 @@ - (UIView *)view RCT_EXPORT_VIEW_PROPERTY(minDelta, CGFloat) RCT_EXPORT_VIEW_PROPERTY(legalLabelInsets, UIEdgeInsets) RCT_EXPORT_VIEW_PROPERTY(mapType, MKMapType) +RCT_EXPORT_VIEW_PROPERTY(onMapReady, RCTBubblingEventBlock) RCT_EXPORT_VIEW_PROPERTY(onChange, RCTBubblingEventBlock) RCT_EXPORT_VIEW_PROPERTY(onPanDrag, RCTBubblingEventBlock) RCT_EXPORT_VIEW_PROPERTY(onPress, RCTBubblingEventBlock) @@ -662,6 +663,8 @@ - (void)mapViewDidFinishRenderingMap:(AIRMap *)mapView fullyRendered:(BOOL)fully { [mapView finishLoading]; [mapView cacheViewIfNeeded]; + + mapView.onMapReady(@{}); } #pragma mark Private From 3202602d2becb1a0cfeea2e8ca839d6f5cb0c82d Mon Sep 17 00:00:00 2001 From: Frank Rowe Date: Thu, 6 Jul 2017 12:27:22 -0400 Subject: [PATCH 127/199] add MKTileOverlayRenderer (#1357) --- lib/ios/AirMaps/AIRMapManager.m | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/ios/AirMaps/AIRMapManager.m b/lib/ios/AirMaps/AIRMapManager.m index e99249ace..41b124aae 100644 --- a/lib/ios/AirMaps/AIRMapManager.m +++ b/lib/ios/AirMaps/AIRMapManager.m @@ -482,6 +482,8 @@ - (MKOverlayRenderer *)mapView:(MKMapView *)mapView rendererForOverlay:(id Date: Tue, 18 Jul 2017 16:41:52 +1000 Subject: [PATCH 128/199] Handle Android RN 0.47 breaking change (#1481) --- .../main/java/com/airbnb/android/react/maps/MapsPackage.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/android/src/main/java/com/airbnb/android/react/maps/MapsPackage.java b/lib/android/src/main/java/com/airbnb/android/react/maps/MapsPackage.java index da59849b3..6ecc55165 100644 --- a/lib/android/src/main/java/com/airbnb/android/react/maps/MapsPackage.java +++ b/lib/android/src/main/java/com/airbnb/android/react/maps/MapsPackage.java @@ -24,7 +24,7 @@ public List createNativeModules(ReactApplicationContext reactConte return Arrays.asList(new AirMapModule(reactContext)); } - @Override + // Deprecated RN 0.47 public List> createJSModules() { return Collections.emptyList(); } From 32350e26cf7c2be6031dbabf23b8e27cd7269c00 Mon Sep 17 00:00:00 2001 From: Sagi Kedmi Date: Sun, 23 Jul 2017 12:46:57 +0300 Subject: [PATCH 129/199] Remove caret from "react": "^16.0.0-alpha.12" `npm install` / `yarn install` auto updates to `16.0.0-alpha.13` which breaks the proptypes import. Removing caret to prevent auto update to `alpha.13`. For more information: https://github.com/facebook/react-native/issues/14454 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 7cb48301b..332063dbb 100644 --- a/package.json +++ b/package.json @@ -50,7 +50,7 @@ "gitbook-cli": "^2.3.0", "lodash": "^4.17.2", "prop-types": "^15.5.10", - "react": "^16.0.0-alpha.12", + "react": "16.0.0-alpha.12", "react-native": "^0.45.1" }, "rnpm": { From 7f182ddc9c209bd9f9dbd27f7f93c5e5f14e6a5e Mon Sep 17 00:00:00 2001 From: Mike Lambert Date: Thu, 27 Jul 2017 12:49:18 -0400 Subject: [PATCH 130/199] Attempt to fix crashes. A variant of https://github.com/airbnb/react-native-maps/pull/1403 but for another lifecycle method, as proposed by @Nelrohd. (#1464) --- .../main/java/com/airbnb/android/react/maps/AirMapView.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapView.java b/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapView.java index 11e578634..c1606eebb 100644 --- a/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapView.java +++ b/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapView.java @@ -304,7 +304,9 @@ public void onHostResume() { map.setMyLocationEnabled(showUserLocation); } synchronized (AirMapView.this) { - AirMapView.this.onResume(); + if (!destroyed) { + AirMapView.this.onResume(); + } paused = false; } } From dd1b8aa9499769dda008cbba464ea9b7a5c21369 Mon Sep 17 00:00:00 2001 From: Benjamin Dobell Date: Fri, 28 Jul 2017 02:50:59 +1000 Subject: [PATCH 131/199] Zoom level fixes (#1485) --- lib/ios/AirMaps/AIRMap.h | 1 + lib/ios/AirMaps/AIRMap.m | 4 ++++ lib/ios/AirMaps/AIRMapManager.h | 1 - lib/ios/AirMaps/AIRMapManager.m | 12 ++++++------ 4 files changed, 11 insertions(+), 7 deletions(-) diff --git a/lib/ios/AirMaps/AIRMap.h b/lib/ios/AirMaps/AIRMap.h index 48a07ddb2..1d5f92cdc 100644 --- a/lib/ios/AirMaps/AIRMap.h +++ b/lib/ios/AirMaps/AIRMap.h @@ -17,6 +17,7 @@ extern const CLLocationDegrees AIRMapDefaultSpan; extern const NSTimeInterval AIRMapRegionChangeObserveInterval; extern const CGFloat AIRMapZoomBoundBuffer; +extern const NSInteger AIRMapMaxZoomLevel; @interface AIRMap: MKMapView diff --git a/lib/ios/AirMaps/AIRMap.m b/lib/ios/AirMaps/AIRMap.m index a9db64ab4..647be4b8a 100644 --- a/lib/ios/AirMaps/AIRMap.m +++ b/lib/ios/AirMaps/AIRMap.m @@ -21,6 +21,7 @@ const CLLocationDegrees AIRMapDefaultSpan = 0.005; const NSTimeInterval AIRMapRegionChangeObserveInterval = 0.1; const CGFloat AIRMapZoomBoundBuffer = 0.01; +const NSInteger AIRMapMaxZoomLevel = 20; @interface MKMapView (UIGestureRecognizer) @@ -79,6 +80,9 @@ - (instancetype)init // be identical to the built-in callout view (which has a private API) self.calloutView = [SMCalloutView platformCalloutView]; self.calloutView.delegate = self; + + self.minZoomLevel = 0; + self.maxZoomLevel = AIRMapMaxZoomLevel; } return self; } diff --git a/lib/ios/AirMaps/AIRMapManager.h b/lib/ios/AirMaps/AIRMapManager.h index 29df98bfc..1d73b405e 100644 --- a/lib/ios/AirMaps/AIRMapManager.h +++ b/lib/ios/AirMaps/AIRMapManager.h @@ -12,7 +12,6 @@ #define MERCATOR_RADIUS 85445659.44705395 #define MERCATOR_OFFSET 268435456 -#define MAX_GOOGLE_LEVELS 20 @interface AIRMapManager : RCTViewManager diff --git a/lib/ios/AirMaps/AIRMapManager.m b/lib/ios/AirMaps/AIRMapManager.m index 41b124aae..76aef88fe 100644 --- a/lib/ios/AirMaps/AIRMapManager.m +++ b/lib/ios/AirMaps/AIRMapManager.m @@ -637,10 +637,10 @@ - (void)mapView:(AIRMap *)mapView regionDidChangeAnimated:(__unused BOOL)animate [self _regionChanged:mapView]; - if (mapView.minZoomLevel != nil && zoomLevel < mapView.minZoomLevel) { + if (zoomLevel < mapView.minZoomLevel) { [self setCenterCoordinate:[mapView centerCoordinate] zoomLevel:mapView.minZoomLevel animated:TRUE mapView:mapView]; } - else if (mapView.maxZoomLevel != nil && zoomLevel > mapView.maxZoomLevel) { + else if (zoomLevel > mapView.maxZoomLevel) { [self setCenterCoordinate:[mapView centerCoordinate] zoomLevel:mapView.maxZoomLevel animated:TRUE mapView:mapView]; } @@ -814,7 +814,7 @@ - (MKCoordinateSpan)coordinateSpanWithMapView:(AIRMap *)mapView double centerPixelY = [AIRMapManager latitudeToPixelSpaceY:centerCoordinate.latitude]; // determine the scale value from the zoom level - double zoomExponent = 20 - zoomLevel; + double zoomExponent = AIRMapMaxZoomLevel - zoomLevel; double zoomScale = pow(2, zoomExponent); // scale the map’s size in pixel space @@ -850,7 +850,7 @@ - (void)setCenterCoordinate:(CLLocationCoordinate2D)centerCoordinate mapView:(AIRMap *)mapView { // clamp large numbers to 28 - zoomLevel = MIN(zoomLevel, 28); + zoomLevel = MIN(zoomLevel, AIRMapMaxZoomLevel); // use the zoom level to compute the region MKCoordinateSpan span = [self coordinateSpanWithMapView:mapView centerCoordinate:centerCoordinate andZoomLevel:zoomLevel]; @@ -874,7 +874,7 @@ -(MKCoordinateRegion)coordinateRegionWithMapView:(AIRMap *)mapView double centerPixelY = [AIRMapManager latitudeToPixelSpaceY:centerCoordinate.latitude]; // determine the scale value from the zoom level - double zoomExponent = 20 - zoomLevel; + double zoomExponent = AIRMapMaxZoomLevel - zoomLevel; double zoomScale = pow(2, zoomExponent); // scale the map’s size in pixel space @@ -928,7 +928,7 @@ - (double) zoomLevel:(AIRMap *)mapView { CGSize mapSizeInPixels = mapView.bounds.size; double zoomScale = scaledMapWidth / mapSizeInPixels.width; double zoomExponent = log(zoomScale) / log(2); - double zoomLevel = 20 - zoomExponent; + double zoomLevel = AIRMapMaxZoomLevel - zoomExponent; return zoomLevel; } From db0d617c0e13a549c5d99b1758a00b6988db6e7b Mon Sep 17 00:00:00 2001 From: Matt Shen Date: Fri, 28 Jul 2017 02:54:50 +1000 Subject: [PATCH 132/199] skip region monitoring if map object is null (#1443) This happen if google play services version is lower than required --- .../main/java/com/airbnb/android/react/maps/AirMapView.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapView.java b/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapView.java index c1606eebb..cfe581bd0 100644 --- a/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapView.java +++ b/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapView.java @@ -701,13 +701,13 @@ public boolean dispatchTouchEvent(MotionEvent ev) { // Timer Implementation public void startMonitoringRegion() { - if (isMonitoringRegion) return; + if (map == null || isMonitoringRegion) return; timerHandler.postDelayed(timerRunnable, 100); isMonitoringRegion = true; } public void stopMonitoringRegion() { - if (!isMonitoringRegion) return; + if (map == null || !isMonitoringRegion) return; timerHandler.removeCallbacks(timerRunnable); isMonitoringRegion = false; } From 3235a341ccb74f1b156ee19eed69656ff5de40d0 Mon Sep 17 00:00:00 2001 From: Nikolay Radkov Date: Thu, 27 Jul 2017 19:57:19 +0300 Subject: [PATCH 133/199] Fix crashing the application when a user presses on the map and the Google Play Services need to be updated or at the moment of the process of updating (#1469) --- .../airbnb/android/react/maps/AirMapView.java | 24 ++++++++++--------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapView.java b/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapView.java index cfe581bd0..c8b016ce1 100644 --- a/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapView.java +++ b/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapView.java @@ -720,18 +720,20 @@ public void stopMonitoringRegion() { @Override public void run() { - Projection projection = map.getProjection(); - VisibleRegion region = (projection != null) ? projection.getVisibleRegion() : null; - LatLngBounds bounds = (region != null) ? region.latLngBounds : null; - - if ((bounds != null) && - (lastBoundsEmitted == null || - LatLngBoundsUtils.BoundsAreDifferent(bounds, lastBoundsEmitted))) { - LatLng center = map.getCameraPosition().target; - lastBoundsEmitted = bounds; - eventDispatcher.dispatchEvent(new RegionChangeEvent(getId(), bounds, center, true)); + if (map != null) { + Projection projection = map.getProjection(); + VisibleRegion region = (projection != null) ? projection.getVisibleRegion() : null; + LatLngBounds bounds = (region != null) ? region.latLngBounds : null; + + if ((bounds != null) && + (lastBoundsEmitted == null || + LatLngBoundsUtils.BoundsAreDifferent(bounds, lastBoundsEmitted))) { + LatLng center = map.getCameraPosition().target; + lastBoundsEmitted = bounds; + eventDispatcher.dispatchEvent(new RegionChangeEvent(getId(), bounds, center, true)); + } } - + timerHandler.postDelayed(this, 100); } }; From 28388a73e209ae30083e466dd3dc64fe1c441d2c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oliver=20B=C3=B8ving?= Date: Thu, 27 Jul 2017 19:10:06 +0200 Subject: [PATCH 134/199] Fix timing function used in AnimatedRegion.spring (#1479) --- lib/components/AnimatedRegion.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/components/AnimatedRegion.js b/lib/components/AnimatedRegion.js index 29356ca9e..ad18c5e07 100644 --- a/lib/components/AnimatedRegion.js +++ b/lib/components/AnimatedRegion.js @@ -111,25 +111,25 @@ export default class AnimatedMapRegion extends AnimatedWithChildren { spring(config) { var animations = []; config.hasOwnProperty('latitude') && - animations.push(Animated.timing(this.latitude, { + animations.push(Animated.spring(this.latitude, { ...config, toValue: config.latitude })); config.hasOwnProperty('longitude') && - animations.push(Animated.timing(this.longitude, { + animations.push(Animated.spring(this.longitude, { ...config, toValue: config.longitude })); config.hasOwnProperty('latitudeDelta') && - animations.push(Animated.timing(this.latitudeDelta, { + animations.push(Animated.spring(this.latitudeDelta, { ...config, toValue: config.latitudeDelta })); config.hasOwnProperty('longitudeDelta') && - animations.push(Animated.timing(this.longitudeDelta, { + animations.push(Animated.spring(this.longitudeDelta, { ...config, toValue: config.longitudeDelta })); From 80a570e26bf479af0fbe4c106480440ac332637f Mon Sep 17 00:00:00 2001 From: Matt Shen Date: Tue, 1 Aug 2017 15:49:28 +1000 Subject: [PATCH 135/199] fix rare android crashes when map size is 0 --- .../airbnb/android/react/maps/AirMapView.java | 21 ++++++++++--------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapView.java b/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapView.java index c8b016ce1..bc52506cf 100644 --- a/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapView.java +++ b/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapView.java @@ -541,16 +541,17 @@ public void updateExtraData(Object extraData) { // a proper camera move if (boundsToMove != null) { HashMap data = (HashMap) extraData; - float width = data.get("width"); - float height = data.get("height"); - map.moveCamera( - CameraUpdateFactory.newLatLngBounds( - boundsToMove, - (int) width, - (int) height, - 0 - ) - ); + int width = data.get("width") == null ? 0 : data.get("width").intValue(); + int height = data.get("height") == null ? 0 : data.get("height").intValue(); + + //fix for https://github.com/airbnb/react-native-maps/issues/245, + //it's not guaranteed the passed-in height and width would be greater than 0. + if (width <= 0 || height <= 0) { + map.moveCamera(CameraUpdateFactory.newLatLngBounds(boundsToMove, 0)); + } else { + map.moveCamera(CameraUpdateFactory.newLatLngBounds(boundsToMove, width, height, 0)); + } + boundsToMove = null; } } From 6357776523cf1d423f8d579b079bdfdecb7b24e6 Mon Sep 17 00:00:00 2001 From: Andre Shonubi Date: Wed, 9 Aug 2017 17:53:45 -0400 Subject: [PATCH 136/199] Document MapView min/max zoom properties (#1538) --- docs/mapview.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/mapview.md b/docs/mapview.md index e8b86aee6..a73e123b8 100644 --- a/docs/mapview.md +++ b/docs/mapview.md @@ -22,6 +22,8 @@ | `showsIndoors` | `Boolean` | `true` | A Boolean indicating whether indoor maps should be enabled. | `showsIndoorLevelPicker` | `Boolean` | `false` | A Boolean indicating whether indoor level picker should be enabled. **Note:** Android only. | `zoomEnabled` | `Boolean` | `true` | If `false` the user won't be able to pinch/zoom the map. +| `minZoomLevel` | `Number` | `0` | Minimum zoom value for the map, must be between 0 and 20 +| `maxZoomLevel` | `Number` | `20` | Maximum zoom value for the map, must be between 0 and 20 | `rotateEnabled` | `Boolean` | `true` | If `false` the user won't be able to pinch/rotate the map. | `scrollEnabled` | `Boolean` | `true` | If `false` the user won't be able to change the map region being displayed. | `pitchEnabled` | `Boolean` | `true` | If `false` the user won't be able to adjust the camera’s pitch angle. From 4cc4e45f6275ade05c7e0da3141e4a5d3983b6dc Mon Sep 17 00:00:00 2001 From: Christopher Dro Date: Wed, 9 Aug 2017 15:07:10 -0700 Subject: [PATCH 137/199] v0.16.0 --- CHANGELOG.md | 7 +++++++ lib/android/gradle.properties | 2 +- package.json | 2 +- 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 50b2027bc..45c5bd082 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,12 @@ # Change Log +## 0.16.0 (August 9, 2017) +* Android: [#1481](https://github.com/airbnb/react-native-maps/pull/#1481) Handle Android RN 0.47 breaking change +* iOS: [#1357](https://github.com/airbnb/react-native-maps/pull/1357) add MKTileOverlayRenderer +* iOS: [#1369](https://github.com/airbnb/react-native-maps/pull/1369) Add onMapReady callback +* Android/iOS/JS: [#1360](https://github.com/airbnb/react-native-maps/pull/1360) Add minZoom and maxZoom properties for android and ios +* JS: [#1479](https://github.com/airbnb/react-native-maps/pull/1479) Fix timing function used in AnimatedRegion.spring + ## 0.15.3 (June 27, 2017) * iOS: [#1362](https://github.com/airbnb/react-native-maps/pull/1362) Updates for React 0.43-0.45 and React 16. diff --git a/lib/android/gradle.properties b/lib/android/gradle.properties index 1a5d3021b..ddc39b69d 100644 --- a/lib/android/gradle.properties +++ b/lib/android/gradle.properties @@ -1,5 +1,5 @@ VERSION_CODE=4 -VERSION_NAME=0.15.3 +VERSION_NAME=0.16.0 GROUP=com.airbnb.android POM_DESCRIPTION=React Native Map view component for Android diff --git a/package.json b/package.json index 7cb48301b..408db6b03 100644 --- a/package.json +++ b/package.json @@ -3,7 +3,7 @@ "description": "React Native Mapview component for iOS + Android", "main": "index.js", "author": "Leland Richardson ", - "version": "0.15.3", + "version": "0.16.0", "scripts": { "start": "node node_modules/react-native/local-cli/cli.js start", "run:packager": "./node_modules/react-native/packager/packager.sh", From 7006e3afee2cb82e20a1bd3c10ce5e163a3c448c Mon Sep 17 00:00:00 2001 From: sandinosaso Date: Fri, 11 Aug 2017 00:43:08 -0300 Subject: [PATCH 138/199] Adds support to animateToBearing and animateToViewingAngle functions on IOS. --- docs/mapview.md | 2 ++ example/examples/DisplayLatLng.js | 24 ++++++++++++++ lib/components/MapView.js | 8 +++++ lib/ios/AirGoogleMaps/AIRGoogleMapManager.m | 36 +++++++++++++++++++++ 4 files changed, 70 insertions(+) diff --git a/docs/mapview.md b/docs/mapview.md index a73e123b8..8cc1d8291 100644 --- a/docs/mapview.md +++ b/docs/mapview.md @@ -64,6 +64,8 @@ To access event data, you will need to use `e.nativeEvent`. For example, `onPres |---|---|---| | `animateToRegion` | `region: Region`, `duration: Number` | | `animateToCoordinate` | `coordinate: LatLng`, `duration: Number` | +| `animateToBearing` | `bearing: Number`, `duration: Number` | +| `animateToViewingAngle` | `angle: Number`, `duration: Number` | | `fitToElements` | `animated: Boolean` | | `fitToSuppliedMarkers` | `markerIDs: String[]`, `animated: Boolean` | If you need to use this in `ComponentDidMount`, make sure you put it in a timeout or it will cause performance problems. | `fitToCoordinates` | `coordinates: Array, options: { edgePadding: EdgePadding, animated: Boolean }` | If called in `ComponentDidMount` in android, it will cause an exception. It is recommended to call it from the MapView `onLayout` event. diff --git a/example/examples/DisplayLatLng.js b/example/examples/DisplayLatLng.js index aa2dde2ac..688427b35 100644 --- a/example/examples/DisplayLatLng.js +++ b/example/examples/DisplayLatLng.js @@ -47,6 +47,18 @@ class DisplayLatLng extends React.Component { this.map.animateToCoordinate(this.randomCoordinate()); } + animateToRandomBearing() { + this.map.animateToBearing(this.getRandomFloat(-360, 360)); + } + + animateToRandomViewingAngle() { + this.map.animateToViewingAngle(this.getRandomFloat(0, 90)); + } + + getRandomFloat(min, max) { + return (Math.random() * (max - min)) + min; + } + randomCoordinate() { const region = this.state.region; return { @@ -98,6 +110,18 @@ class DisplayLatLng extends React.Component { > Animate (Coordinate) + this.animateToRandomBearing()} + style={[styles.bubble, styles.button]} + > + Animate (Bearing) + + this.animateToRandomViewingAngle()} + style={[styles.bubble, styles.button]} + > + Animate (View Angle) + ); diff --git a/lib/components/MapView.js b/lib/components/MapView.js index e3763f8f3..19256b85c 100644 --- a/lib/components/MapView.js +++ b/lib/components/MapView.js @@ -492,6 +492,14 @@ class MapView extends React.Component { this._runCommand('animateToCoordinate', [latLng, duration || 500]); } + animateToBearing(bearing, duration) { + this._runCommand('animateToBearing', [bearing, duration || 500]); + } + + animateToViewingAngle(angle, duration) { + this._runCommand('animateToViewingAngle', [angle, duration || 500]); + } + fitToElements(animated) { this._runCommand('fitToElements', [animated]); } diff --git a/lib/ios/AirGoogleMaps/AIRGoogleMapManager.m b/lib/ios/AirGoogleMaps/AIRGoogleMapManager.m index 53157e99a..c1531b5a7 100644 --- a/lib/ios/AirGoogleMaps/AIRGoogleMapManager.m +++ b/lib/ios/AirGoogleMaps/AIRGoogleMapManager.m @@ -108,6 +108,42 @@ - (UIView *)view }]; } +RCT_EXPORT_METHOD(animateToViewingAngle:(nonnull NSNumber *)reactTag + withAngle:(double)angle + withDuration:(CGFloat)duration) +{ + [self.bridge.uiManager addUIBlock:^(__unused RCTUIManager *uiManager, NSDictionary *viewRegistry) { + id view = viewRegistry[reactTag]; + if (![view isKindOfClass:[AIRGoogleMap class]]) { + RCTLogError(@"Invalid view returned from registry, expecting AIRGoogleMap, got: %@", view); + } else { + [CATransaction begin]; + [CATransaction setAnimationDuration:duration/1000]; + AIRGoogleMap *mapView = (AIRGoogleMap *)view; + [mapView animateToViewingAngle:angle]; + [CATransaction commit]; + } + }]; +} + +RCT_EXPORT_METHOD(animateToBearing:(nonnull NSNumber *)reactTag + withBearing:(CGFloat)bearing + withDuration:(CGFloat)duration) +{ + [self.bridge.uiManager addUIBlock:^(__unused RCTUIManager *uiManager, NSDictionary *viewRegistry) { + id view = viewRegistry[reactTag]; + if (![view isKindOfClass:[AIRGoogleMap class]]) { + RCTLogError(@"Invalid view returned from registry, expecting AIRGoogleMap, got: %@", view); + } else { + [CATransaction begin]; + [CATransaction setAnimationDuration:duration/1000]; + AIRGoogleMap *mapView = (AIRGoogleMap *)view; + [mapView animateToBearing:bearing]; + [CATransaction commit]; + } + }]; +} + RCT_EXPORT_METHOD(fitToElements:(nonnull NSNumber *)reactTag animated:(BOOL)animated) { From c9c52ab9ccb0e8f446f457be54e04f151b6a2f47 Mon Sep 17 00:00:00 2001 From: Eugene Hauptmann Date: Tue, 15 Aug 2017 08:35:08 -0700 Subject: [PATCH 139/199] fix `Archive` configuration for iOS builds (#1550) --- example/ios/Podfile | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/example/ios/Podfile b/example/ios/Podfile index 656f283e1..66771a383 100644 --- a/example/ios/Podfile +++ b/example/ios/Podfile @@ -36,5 +36,9 @@ post_install do |installer| config.build_settings['CLANG_ENABLE_MODULES'] = 'No' end end + + if target.name == "React" + target.remove_from_project + end end end From fd8dc08ffaa0fadbaa73d9e29033a16f808e318f Mon Sep 17 00:00:00 2001 From: foyarash Date: Tue, 15 Aug 2017 17:37:10 +0200 Subject: [PATCH 140/199] Fix initial region native prop (#1546) * Fix initial region bug * Remove useless change --- lib/components/MapView.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/components/MapView.js b/lib/components/MapView.js index e3763f8f3..f9b974aec 100644 --- a/lib/components/MapView.js +++ b/lib/components/MapView.js @@ -450,7 +450,7 @@ class MapView extends React.Component { if (region) { this.map.setNativeProps({ region }); } else if (initialRegion) { - this.map.setNativeProps({ region: initialRegion }); + this.map.setNativeProps({ initialRegion }); } this._updateStyle(); this.setState({ isReady: true }, () => { From b908c08ac2367652249918f4f5694eaf17a1eac2 Mon Sep 17 00:00:00 2001 From: "Wanseob (Eric) Kim" Date: Tue, 15 Aug 2017 11:35:13 -0700 Subject: [PATCH 141/199] Issue1176 improve ios marker performance by X100 (#1187) * Issue1176 attempt to fix UI lag success by re-using UIImage * Now use NSMutableDictionary instead of single UIImage * appearAnimation happen at init rather than setIcon * Init NSMutableDictionary * Remove reference to other app --- lib/ios/AirGoogleMaps/AIRGoogleMapMarker.m | 80 +++++----------------- lib/ios/AirGoogleMaps/GlobalVars.h | 22 ++++++ lib/ios/AirGoogleMaps/GlobalVars.m | 54 +++++++++++++++ 3 files changed, 92 insertions(+), 64 deletions(-) create mode 100644 lib/ios/AirGoogleMaps/GlobalVars.h create mode 100644 lib/ios/AirGoogleMaps/GlobalVars.m diff --git a/lib/ios/AirGoogleMaps/AIRGoogleMapMarker.m b/lib/ios/AirGoogleMaps/AIRGoogleMapMarker.m index c41be55bb..9d96dfafc 100644 --- a/lib/ios/AirGoogleMaps/AIRGoogleMapMarker.m +++ b/lib/ios/AirGoogleMaps/AIRGoogleMapMarker.m @@ -12,6 +12,7 @@ #import "AIRGMSMarker.h" #import "AIRGoogleMapCallout.h" #import "DummyView.h" +#import "GlobalVars.h" CGRect unionRect(CGRect a, CGRect b) { return CGRectMake( @@ -36,6 +37,7 @@ - (instancetype)init if ((self = [super init])) { _realMarker = [[AIRGMSMarker alloc] init]; _realMarker.fakeMarker = self; + _realMarker.appearAnimation = kGMSMarkerAnimationPop; } return self; } @@ -92,6 +94,18 @@ - (void)insertReactSubview:(id)subview atIndex:(NSInteger)atIndex [super insertReactSubview:(UIView*)dummySubview atIndex:atIndex]; } +- (void)setIcon:(UIImage*)image { + CGImageRef cgref = [image CGImage]; + CIImage *cim = [image CIImage]; + + if (cim == nil && cgref == NULL) { + // image does not contain image data + _realMarker.icon = [GMSMarker markerImageWithColor:UIColor.blueColor]; + } else { + _realMarker.icon = image; + } +} + - (void)removeReactSubview:(id)dummySubview { UIView* subview = ((DummyView*)dummySubview).view; @@ -188,70 +202,8 @@ - (void)setOpacity:(double)opacity - (void)setImageSrc:(NSString *)imageSrc { - _imageSrc = imageSrc; - - if (_reloadImageCancellationBlock) { - _reloadImageCancellationBlock(); - _reloadImageCancellationBlock = nil; - } - - if (!_imageSrc) { - if (_iconImageView) [_iconImageView removeFromSuperview]; - return; - } - - if (!_iconImageView) { - // prevent glitch with marker (cf. https://github.com/airbnb/react-native-maps/issues/738) - UIImageView *empyImageView = [[UIImageView alloc] init]; - _iconImageView = empyImageView; - [self iconViewInsertSubview:_iconImageView atIndex:0]; - } - - _reloadImageCancellationBlock = [_bridge.imageLoader loadImageWithURLRequest:[RCTConvert NSURLRequest:_imageSrc] - size:self.bounds.size - scale:RCTScreenScale() - clipped:YES - resizeMode:RCTResizeModeCenter - progressBlock:nil - partialLoadBlock:nil - completionBlock:^(NSError *error, UIImage *image) { - if (error) { - // TODO(lmr): do something with the error? - NSLog(@"%@", error); - } - dispatch_async(dispatch_get_main_queue(), ^{ - - // TODO(gil): This way allows different image sizes - if (_iconImageView) [_iconImageView removeFromSuperview]; - - // ... but this way is more efficient? -// if (_iconImageView) { -// [_iconImageView setImage:image]; -// return; -// } - - UIImageView *imageView = [[UIImageView alloc] initWithImage:image]; - - // TODO: w,h or pixel density could be a prop. - float density = 1; - float w = image.size.width/density; - float h = image.size.height/density; - CGRect bounds = CGRectMake(0, 0, w, h); - - imageView.contentMode = UIViewContentModeScaleAspectFit; - [imageView setFrame:bounds]; - - // NOTE: sizeToFit doesn't work instead. Not sure why. - // TODO: Doing it this way is not ideal because it causes things to reshuffle - // when the image loads IF the image is larger than the UIView. - // Shouldn't required images have size info automatically via RN? - CGRect selfBounds = unionRect(bounds, self.bounds); - [self setFrame:selfBounds]; - - _iconImageView = imageView; - [self iconViewInsertSubview:imageView atIndex:0]; - }); - }]; + UIImage * image = [[GlobalVars sharedInstance] getSharedUIImage:imageSrc]; + [self setIcon:image]; } - (void)setTitle:(NSString *)title { diff --git a/lib/ios/AirGoogleMaps/GlobalVars.h b/lib/ios/AirGoogleMaps/GlobalVars.h new file mode 100644 index 000000000..86c3555f7 --- /dev/null +++ b/lib/ios/AirGoogleMaps/GlobalVars.h @@ -0,0 +1,22 @@ +// +// GlobalVars.h +// +// Created by Eric Kim on 2017-04-04. +// Copyright © 2017 Apply Digital. All rights reserved. +// + +#import +#import + +@interface GlobalVars : NSObject +{ + NSMutableDictionary *dict; +} + ++ (GlobalVars *)sharedInstance; + +- (UIImage *)getSharedUIImage:(NSString *)imageSrc; + +@property(strong, nonatomic, readwrite) NSMutableDictionary *dict; + +@end diff --git a/lib/ios/AirGoogleMaps/GlobalVars.m b/lib/ios/AirGoogleMaps/GlobalVars.m new file mode 100644 index 000000000..7a541dab4 --- /dev/null +++ b/lib/ios/AirGoogleMaps/GlobalVars.m @@ -0,0 +1,54 @@ +// +// GlobalVars.m +// +// Created by Eric Kim on 2017-04-04. +// Copyright © 2017 Apply Digital. All rights reserved. +// + +#import "GlobalVars.h" + +@implementation GlobalVars + +@synthesize dict = _dict; + ++ (GlobalVars *)sharedInstance { + static dispatch_once_t onceToken; + static GlobalVars *instance = nil; + dispatch_once(&onceToken, ^{ + instance = [[GlobalVars alloc] init]; + }); + return instance; +} + +- (UIImage *)getSharedUIImage:(NSString *)imageSrc { + + UIImage* cachedImage = dict[imageSrc]; + + CGImageRef cgref = [cachedImage CGImage]; + CIImage *cim = [cachedImage CIImage]; + + if (cim == nil && cgref == NULL) { + UIImage *newImage; + if ([imageSrc hasPrefix:@"http://"] || [imageSrc hasPrefix:@"https://"]){ + NSURL *url = [NSURL URLWithString:imageSrc]; + NSData *data = [NSData dataWithContentsOfURL:url]; + newImage = [UIImage imageWithData:data scale:[UIScreen mainScreen].scale]; + } else { + newImage = [UIImage imageWithContentsOfFile:imageSrc]; + } + dict[imageSrc] = newImage; + return newImage; + } else { + return cachedImage; + } +} + +- (id)init { + self = [super init]; + if (self) { + dict = [[NSMutableDictionary alloc] init]; + } + return self; +} + +@end From 75a38eab271b83d37a7f4089de806acac1a4865d Mon Sep 17 00:00:00 2001 From: Ben Speakman Date: Tue, 15 Aug 2017 19:36:25 +0100 Subject: [PATCH 142/199] Add legalNotice constant (#1458) --- .../com/airbnb/android/react/maps/AirMapModule.java | 11 +++++++++++ lib/ios/AirGoogleMaps/AIRGoogleMapManager.m | 3 +++ 2 files changed, 14 insertions(+) diff --git a/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapModule.java b/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapModule.java index 1a096255e..bd1fb6ed0 100644 --- a/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapModule.java +++ b/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapModule.java @@ -15,6 +15,7 @@ import com.facebook.react.uimanager.UIBlock; import com.facebook.react.uimanager.UIManagerModule; import com.google.android.gms.maps.GoogleMap; +import com.google.android.gms.common.GoogleApiAvailability; import java.io.ByteArrayOutputStream; import java.io.Closeable; @@ -22,6 +23,9 @@ import java.io.FileOutputStream; import java.io.IOException; +import java.util.Map; +import java.util.HashMap; + import javax.annotation.Nullable; public class AirMapModule extends ReactContextBaseJavaModule { @@ -40,6 +44,13 @@ public String getName() { return "AirMapModule"; } + @Override + public Map getConstants() { + final Map constants = new HashMap<>(); + constants.put("legalNotice", GoogleApiAvailability.getInstance().getOpenSourceSoftwareLicenseInfo(getReactApplicationContext())); + return constants; + } + public Activity getActivity() { return getCurrentActivity(); } diff --git a/lib/ios/AirGoogleMaps/AIRGoogleMapManager.m b/lib/ios/AirGoogleMaps/AIRGoogleMapManager.m index 53157e99a..086822b73 100644 --- a/lib/ios/AirGoogleMaps/AIRGoogleMapManager.m +++ b/lib/ios/AirGoogleMaps/AIRGoogleMapManager.m @@ -222,6 +222,9 @@ - (UIView *)view }]; } +- (NSDictionary *)constantsToExport { + return @{ @"legalNotice": [GMSServices openSourceLicenseInfo] }; +} - (void)mapViewDidFinishTileRendering:(GMSMapView *)mapView { AIRGoogleMap *googleMapView = (AIRGoogleMap *)mapView; From 971d91e522d7ad517a0d944b57c873483b78f9e2 Mon Sep 17 00:00:00 2001 From: foyarash Date: Tue, 15 Aug 2017 20:39:50 +0200 Subject: [PATCH 143/199] Update marker component (#1428) --- lib/components/MapMarker.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/components/MapMarker.js b/lib/components/MapMarker.js index 6e2b8585d..b81bab87a 100644 --- a/lib/components/MapMarker.js +++ b/lib/components/MapMarker.js @@ -257,7 +257,7 @@ class MapMarker extends React.Component { let image; if (this.props.image) { image = resolveAssetSource(this.props.image) || {}; - image = image.uri; + image = image.uri || this.props.image; } const AIRMapMarker = this.getAirComponent(); From a3b15c6466570bb58cc23b4868bb7124e891e020 Mon Sep 17 00:00:00 2001 From: Guilherme Pontes Date: Tue, 15 Aug 2017 20:41:53 +0200 Subject: [PATCH 144/199] Enhance Podfile. (#1252) --- example/ios/Podfile | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/example/ios/Podfile b/example/ios/Podfile index 66771a383..fd01b85a0 100644 --- a/example/ios/Podfile +++ b/example/ios/Podfile @@ -5,9 +5,10 @@ platform :ios, '8.0' # Change 'AirMapsExplorer' to match the target in your Xcode project. target 'AirMapsExplorer' do + rn_path = '../../node_modules/react-native' - pod 'Yoga', :path => '../../node_modules/react-native/ReactCommon/yoga/Yoga.podspec' - pod 'React', path: '../../node_modules/react-native', :subspecs => [ + pod 'Yoga', path: "#{rn_path}/ReactCommon/yoga/Yoga.podspec" + pod 'React', path: rn_path, subspecs: [ 'Core', 'RCTActionSheet', 'RCTAnimation', @@ -22,16 +23,14 @@ target 'AirMapsExplorer' do 'BatchedBridge' ] - pod 'GoogleMaps' # <~~ remove this line if you do not want to support GoogleMaps on iOS + pod 'GoogleMaps' # Remove this line if you don't want to support GoogleMaps on iOS pod 'react-native-maps', path: '../../' - pod 'react-native-google-maps', path: '../../' # <~~ if you need GoogleMaps support on iOS - + pod 'react-native-google-maps', path: '../../' # If you need GoogleMaps support on iOS end - post_install do |installer| installer.pods_project.targets.each do |target| - if target.name == "react-native-google-maps" + if target.name == 'react-native-google-maps' target.build_configurations.each do |config| config.build_settings['CLANG_ENABLE_MODULES'] = 'No' end From f953252223c119d61522d9923197b79575458a81 Mon Sep 17 00:00:00 2001 From: Christopher Dro Date: Tue, 15 Aug 2017 11:47:11 -0700 Subject: [PATCH 145/199] v0.16.1 --- CHANGELOG.md | 8 +++++++- lib/android/gradle.properties | 2 +- package.json | 2 +- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 45c5bd082..5ae94159d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,7 +1,13 @@ # Change Log +## 0.16.1 (August 15, 2017) +* Android: [#1428](https://github.com/airbnb/react-native-maps/pull/#1428) Add ability to load marker image from drawable +* iOS: [#1187](https://github.com/airbnb/react-native-maps/pull/1187) Improve marker performance +* iOS/Android: [#1458](https://github.com/airbnb/react-native-maps/pull/1458) Add Google Maps legalNotice constant +* JS: [#1546](https://github.com/airbnb/react-native-maps/pull/1546) Fix initial region native prop + ## 0.16.0 (August 9, 2017) -* Android: [#1481](https://github.com/airbnb/react-native-maps/pull/#1481) Handle Android RN 0.47 breaking change +* Android: [#1481](https://github.com/airbnb/react-native-maps/pull/1481) Handle Android RN 0.47 breaking change * iOS: [#1357](https://github.com/airbnb/react-native-maps/pull/1357) add MKTileOverlayRenderer * iOS: [#1369](https://github.com/airbnb/react-native-maps/pull/1369) Add onMapReady callback * Android/iOS/JS: [#1360](https://github.com/airbnb/react-native-maps/pull/1360) Add minZoom and maxZoom properties for android and ios diff --git a/lib/android/gradle.properties b/lib/android/gradle.properties index ddc39b69d..04d072cc5 100644 --- a/lib/android/gradle.properties +++ b/lib/android/gradle.properties @@ -1,5 +1,5 @@ VERSION_CODE=4 -VERSION_NAME=0.16.0 +VERSION_NAME=0.16.1 GROUP=com.airbnb.android POM_DESCRIPTION=React Native Map view component for Android diff --git a/package.json b/package.json index 408db6b03..104be9b04 100644 --- a/package.json +++ b/package.json @@ -3,7 +3,7 @@ "description": "React Native Mapview component for iOS + Android", "main": "index.js", "author": "Leland Richardson ", - "version": "0.16.0", + "version": "0.16.1", "scripts": { "start": "node node_modules/react-native/local-cli/cli.js start", "run:packager": "./node_modules/react-native/packager/packager.sh", From 4376c97304b47033bbd3562aeff8da451a4f520d Mon Sep 17 00:00:00 2001 From: foyarash Date: Thu, 17 Aug 2017 18:38:38 +0200 Subject: [PATCH 146/199] Fix initial region android (#1563) * Fix initial region on android * Fix initial region for android --- .../com/airbnb/android/react/maps/AirMapManager.java | 5 +++++ .../java/com/airbnb/android/react/maps/AirMapView.java | 10 +++++++++- lib/components/MapView.js | 5 ++++- 3 files changed, 18 insertions(+), 2 deletions(-) diff --git a/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapManager.java b/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapManager.java index e8f98a766..9ba6295cd 100644 --- a/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapManager.java +++ b/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapManager.java @@ -75,6 +75,11 @@ public void setRegion(AirMapView view, ReadableMap region) { view.setRegion(region); } + @ReactProp(name = "initialRegion") + public void setInitialRegion(AirMapView view, ReadableMap initialRegion) { + view.setInitialRegion(initialRegion); + } + @ReactProp(name = "mapType") public void setMapType(AirMapView view, @Nullable String mapType) { int typeId = MAP_TYPES.get(mapType); diff --git a/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapView.java b/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapView.java index c8b016ce1..14983dc79 100644 --- a/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapView.java +++ b/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapView.java @@ -70,6 +70,7 @@ public class AirMapView extends MapView implements GoogleMap.InfoWindowAdapter, private boolean handlePanDrag = false; private boolean moveOnMarkerPress = true; private boolean cacheEnabled = false; + private boolean initialRegionSet = false; private static final String[] PERMISSIONS = new String[]{ "android.permission.ACCESS_FINE_LOCATION", "android.permission.ACCESS_COARSE_LOCATION"}; @@ -360,6 +361,13 @@ public synchronized void doDestroy() { onDestroy(); } + public void setInitialRegion(ReadableMap initialRegion) { + if (!initialRegionSet && initialRegion != null) { + setRegion(initialRegion); + initialRegionSet = true; + } + } + public void setRegion(ReadableMap region) { if (region == null) return; @@ -733,7 +741,7 @@ public void run() { eventDispatcher.dispatchEvent(new RegionChangeEvent(getId(), bounds, center, true)); } } - + timerHandler.postDelayed(this, 100); } }; diff --git a/lib/components/MapView.js b/lib/components/MapView.js index f9b974aec..a0f3fa02c 100644 --- a/lib/components/MapView.js +++ b/lib/components/MapView.js @@ -462,10 +462,13 @@ class MapView extends React.Component { const { layout } = e.nativeEvent; if (!layout.width || !layout.height) return; if (this.state.isReady && !this.__layoutCalled) { - const region = this.props.region || this.props.initialRegion; + const { region, initialRegion } = this.props; if (region) { this.__layoutCalled = true; this.map.setNativeProps({ region }); + } else if (initialRegion) { + this.__layoutCalled = true; + this.map.setNativeProps({ initialRegion }); } } if (this.props.onLayout) { From cbdeeafca8f7fc38a398ac105bda94713342c5ae Mon Sep 17 00:00:00 2001 From: Christopher Dro Date: Thu, 17 Aug 2017 09:50:54 -0700 Subject: [PATCH 147/199] Revert "Issue1176 improve ios marker performance by X100 (#1187)" This reverts commit b908c08ac2367652249918f4f5694eaf17a1eac2. --- lib/ios/AirGoogleMaps/AIRGoogleMapMarker.m | 80 +++++++++++++++++----- lib/ios/AirGoogleMaps/GlobalVars.h | 22 ------ lib/ios/AirGoogleMaps/GlobalVars.m | 54 --------------- 3 files changed, 64 insertions(+), 92 deletions(-) delete mode 100644 lib/ios/AirGoogleMaps/GlobalVars.h delete mode 100644 lib/ios/AirGoogleMaps/GlobalVars.m diff --git a/lib/ios/AirGoogleMaps/AIRGoogleMapMarker.m b/lib/ios/AirGoogleMaps/AIRGoogleMapMarker.m index 9d96dfafc..c41be55bb 100644 --- a/lib/ios/AirGoogleMaps/AIRGoogleMapMarker.m +++ b/lib/ios/AirGoogleMaps/AIRGoogleMapMarker.m @@ -12,7 +12,6 @@ #import "AIRGMSMarker.h" #import "AIRGoogleMapCallout.h" #import "DummyView.h" -#import "GlobalVars.h" CGRect unionRect(CGRect a, CGRect b) { return CGRectMake( @@ -37,7 +36,6 @@ - (instancetype)init if ((self = [super init])) { _realMarker = [[AIRGMSMarker alloc] init]; _realMarker.fakeMarker = self; - _realMarker.appearAnimation = kGMSMarkerAnimationPop; } return self; } @@ -94,18 +92,6 @@ - (void)insertReactSubview:(id)subview atIndex:(NSInteger)atIndex [super insertReactSubview:(UIView*)dummySubview atIndex:atIndex]; } -- (void)setIcon:(UIImage*)image { - CGImageRef cgref = [image CGImage]; - CIImage *cim = [image CIImage]; - - if (cim == nil && cgref == NULL) { - // image does not contain image data - _realMarker.icon = [GMSMarker markerImageWithColor:UIColor.blueColor]; - } else { - _realMarker.icon = image; - } -} - - (void)removeReactSubview:(id)dummySubview { UIView* subview = ((DummyView*)dummySubview).view; @@ -202,8 +188,70 @@ - (void)setOpacity:(double)opacity - (void)setImageSrc:(NSString *)imageSrc { - UIImage * image = [[GlobalVars sharedInstance] getSharedUIImage:imageSrc]; - [self setIcon:image]; + _imageSrc = imageSrc; + + if (_reloadImageCancellationBlock) { + _reloadImageCancellationBlock(); + _reloadImageCancellationBlock = nil; + } + + if (!_imageSrc) { + if (_iconImageView) [_iconImageView removeFromSuperview]; + return; + } + + if (!_iconImageView) { + // prevent glitch with marker (cf. https://github.com/airbnb/react-native-maps/issues/738) + UIImageView *empyImageView = [[UIImageView alloc] init]; + _iconImageView = empyImageView; + [self iconViewInsertSubview:_iconImageView atIndex:0]; + } + + _reloadImageCancellationBlock = [_bridge.imageLoader loadImageWithURLRequest:[RCTConvert NSURLRequest:_imageSrc] + size:self.bounds.size + scale:RCTScreenScale() + clipped:YES + resizeMode:RCTResizeModeCenter + progressBlock:nil + partialLoadBlock:nil + completionBlock:^(NSError *error, UIImage *image) { + if (error) { + // TODO(lmr): do something with the error? + NSLog(@"%@", error); + } + dispatch_async(dispatch_get_main_queue(), ^{ + + // TODO(gil): This way allows different image sizes + if (_iconImageView) [_iconImageView removeFromSuperview]; + + // ... but this way is more efficient? +// if (_iconImageView) { +// [_iconImageView setImage:image]; +// return; +// } + + UIImageView *imageView = [[UIImageView alloc] initWithImage:image]; + + // TODO: w,h or pixel density could be a prop. + float density = 1; + float w = image.size.width/density; + float h = image.size.height/density; + CGRect bounds = CGRectMake(0, 0, w, h); + + imageView.contentMode = UIViewContentModeScaleAspectFit; + [imageView setFrame:bounds]; + + // NOTE: sizeToFit doesn't work instead. Not sure why. + // TODO: Doing it this way is not ideal because it causes things to reshuffle + // when the image loads IF the image is larger than the UIView. + // Shouldn't required images have size info automatically via RN? + CGRect selfBounds = unionRect(bounds, self.bounds); + [self setFrame:selfBounds]; + + _iconImageView = imageView; + [self iconViewInsertSubview:imageView atIndex:0]; + }); + }]; } - (void)setTitle:(NSString *)title { diff --git a/lib/ios/AirGoogleMaps/GlobalVars.h b/lib/ios/AirGoogleMaps/GlobalVars.h deleted file mode 100644 index 86c3555f7..000000000 --- a/lib/ios/AirGoogleMaps/GlobalVars.h +++ /dev/null @@ -1,22 +0,0 @@ -// -// GlobalVars.h -// -// Created by Eric Kim on 2017-04-04. -// Copyright © 2017 Apply Digital. All rights reserved. -// - -#import -#import - -@interface GlobalVars : NSObject -{ - NSMutableDictionary *dict; -} - -+ (GlobalVars *)sharedInstance; - -- (UIImage *)getSharedUIImage:(NSString *)imageSrc; - -@property(strong, nonatomic, readwrite) NSMutableDictionary *dict; - -@end diff --git a/lib/ios/AirGoogleMaps/GlobalVars.m b/lib/ios/AirGoogleMaps/GlobalVars.m deleted file mode 100644 index 7a541dab4..000000000 --- a/lib/ios/AirGoogleMaps/GlobalVars.m +++ /dev/null @@ -1,54 +0,0 @@ -// -// GlobalVars.m -// -// Created by Eric Kim on 2017-04-04. -// Copyright © 2017 Apply Digital. All rights reserved. -// - -#import "GlobalVars.h" - -@implementation GlobalVars - -@synthesize dict = _dict; - -+ (GlobalVars *)sharedInstance { - static dispatch_once_t onceToken; - static GlobalVars *instance = nil; - dispatch_once(&onceToken, ^{ - instance = [[GlobalVars alloc] init]; - }); - return instance; -} - -- (UIImage *)getSharedUIImage:(NSString *)imageSrc { - - UIImage* cachedImage = dict[imageSrc]; - - CGImageRef cgref = [cachedImage CGImage]; - CIImage *cim = [cachedImage CIImage]; - - if (cim == nil && cgref == NULL) { - UIImage *newImage; - if ([imageSrc hasPrefix:@"http://"] || [imageSrc hasPrefix:@"https://"]){ - NSURL *url = [NSURL URLWithString:imageSrc]; - NSData *data = [NSData dataWithContentsOfURL:url]; - newImage = [UIImage imageWithData:data scale:[UIScreen mainScreen].scale]; - } else { - newImage = [UIImage imageWithContentsOfFile:imageSrc]; - } - dict[imageSrc] = newImage; - return newImage; - } else { - return cachedImage; - } -} - -- (id)init { - self = [super init]; - if (self) { - dict = [[NSMutableDictionary alloc] init]; - } - return self; -} - -@end From fad3aabba4c65047ae7c8d12019ec0818b9556be Mon Sep 17 00:00:00 2001 From: Christopher Dro Date: Thu, 17 Aug 2017 09:55:00 -0700 Subject: [PATCH 148/199] v0.16.2 --- CHANGELOG.md | 4 ++++ lib/android/gradle.properties | 2 +- package.json | 2 +- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5ae94159d..f9ae8057e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Change Log +## 0.16.2 (August 17, 2017) +* Android: [#1563](https://github.com/airbnb/react-native-maps/pull/#1563) Add missing native method for setting initial region +* iOS: [#1187](https://github.com/airbnb/react-native-maps/pull/1187) Reverted due to build issues + ## 0.16.1 (August 15, 2017) * Android: [#1428](https://github.com/airbnb/react-native-maps/pull/#1428) Add ability to load marker image from drawable * iOS: [#1187](https://github.com/airbnb/react-native-maps/pull/1187) Improve marker performance diff --git a/lib/android/gradle.properties b/lib/android/gradle.properties index 04d072cc5..9b4cf86c9 100644 --- a/lib/android/gradle.properties +++ b/lib/android/gradle.properties @@ -1,5 +1,5 @@ VERSION_CODE=4 -VERSION_NAME=0.16.1 +VERSION_NAME=0.16.2 GROUP=com.airbnb.android POM_DESCRIPTION=React Native Map view component for Android diff --git a/package.json b/package.json index 104be9b04..6914f242b 100644 --- a/package.json +++ b/package.json @@ -3,7 +3,7 @@ "description": "React Native Mapview component for iOS + Android", "main": "index.js", "author": "Leland Richardson ", - "version": "0.16.1", + "version": "0.16.2", "scripts": { "start": "node node_modules/react-native/local-cli/cli.js start", "run:packager": "./node_modules/react-native/packager/packager.sh", From af3ff1efba5c28e2f808572d1aa84a5dbdc15021 Mon Sep 17 00:00:00 2001 From: sandinosaso Date: Sat, 26 Aug 2017 20:18:32 -0300 Subject: [PATCH 149/199] Add support for AirMap (Native IOS Maps) as suggested on the PR comments. --- lib/ios/AirMaps/AIRMapManager.m | 42 +++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/lib/ios/AirMaps/AIRMapManager.m b/lib/ios/AirMaps/AIRMapManager.m index 76aef88fe..a1970bbbe 100644 --- a/lib/ios/AirMaps/AIRMapManager.m +++ b/lib/ios/AirMaps/AIRMapManager.m @@ -152,6 +152,48 @@ - (UIView *)view }]; } +RCT_EXPORT_METHOD(animateToViewingAngle:(nonnull NSNumber *)reactTag + withAngle:(double)angle + withDuration:(CGFloat)duration) +{ + [self.bridge.uiManager addUIBlock:^(__unused RCTUIManager *uiManager, NSDictionary *viewRegistry) { + id view = viewRegistry[reactTag]; + if (![view isKindOfClass:[AIRMap class]]) { + RCTLogError(@"Invalid view returned from registry, expecting AIRMap, got: %@", view); + } else { + AIRMap *mapView = (AIRMap *)view; + + MKMapCamera *mapCamera = [[mapView camera] copy]; + [mapCamera setPitch:angle]; + + [AIRMap animateWithDuration:duration/1000 animations:^{ + [mapView setCamera:mapCamera animated:YES]; + }]; + } + }]; +} + +RCT_EXPORT_METHOD(animateToBearing:(nonnull NSNumber *)reactTag + withBearing:(CGFloat)bearing + withDuration:(CGFloat)duration) +{ + [self.bridge.uiManager addUIBlock:^(__unused RCTUIManager *uiManager, NSDictionary *viewRegistry) { + id view = viewRegistry[reactTag]; + if (![view isKindOfClass:[AIRMap class]]) { + RCTLogError(@"Invalid view returned from registry, expecting AIRMap, got: %@", view); + } else { + AIRMap *mapView = (AIRMap *)view; + + MKMapCamera *mapCamera = [[mapView camera] copy]; + [mapCamera setHeading:bearing]; + + [AIRMap animateWithDuration:duration/1000 animations:^{ + [mapView setCamera:mapCamera animated:YES]; + }]; + } + }]; +} + RCT_EXPORT_METHOD(fitToElements:(nonnull NSNumber *)reactTag animated:(BOOL)animated) { From 725af03f92aea866a1632ddc737a265e43173321 Mon Sep 17 00:00:00 2001 From: Myck Date: Mon, 28 Aug 2017 18:30:19 +0200 Subject: [PATCH 150/199] fixe mistakes on circle.md (#1584) lineJoin : wrong type lineCap : add other values --- docs/circle.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/circle.md b/docs/circle.md index 70a5e078e..992ac4567 100644 --- a/docs/circle.md +++ b/docs/circle.md @@ -10,8 +10,8 @@ | `strokeColor` | `String` | `#000`, `rgba(r,g,b,0.5)` | The stroke color to use for the path. | `fillColor` | `String` | `#000`, `rgba(r,g,b,0.5)` | The fill color to use for the path. | `zIndex` | `Number` | 0 | The order in which this tile overlay is drawn with respect to other overlays. An overlay with a larger z-index is drawn over overlays with smaller z-indices. The order of overlays with the same z-index is arbitrary. The default zIndex is 0. (Android Only) -| `lineCap` | `String` | `round` | The line cap style to apply to the open ends of the path. -| `lineJoin` | `Array` | | The line join style to apply to corners of the path. +| `lineCap` | `String` | `round` | The line cap style to apply to the open ends of the path. Other values : `butt`, `square` +| `lineJoin` | `String` | | The line join style to apply to corners of the path. possible value: `miter`, `round`, `bevel` | `miterLimit` | `Number` | | The limiting value that helps avoid spikes at junctions between connected line segments. The miter limit helps you avoid spikes in paths that use the `miter` `lineJoin` style. If the ratio of the miter length—that is, the diagonal length of the miter join—to the line thickness exceeds the miter limit, the joint is converted to a bevel join. The default miter limit is 10, which results in the conversion of miters whose angle at the joint is less than 11 degrees. | `geodesic` | `Boolean` | | Boolean to indicate whether to draw each segment of the line as a geodesic as opposed to straight lines on the Mercator projection. A geodesic is the shortest path between two points on the Earth's surface. The geodesic curve is constructed assuming the Earth is a sphere. | `lineDashPhase` | `Number` | `0` | (iOS only) The offset (in points) at which to start drawing the dash pattern. Use this property to start drawing a dashed line partway through a segment or gap. For example, a phase value of 6 for the patter 5-2-3-2 would cause drawing to begin in the middle of the first gap. From a71356819cf63f55f752571779830f6525e2981b Mon Sep 17 00:00:00 2001 From: paulmasters Date: Mon, 28 Aug 2017 17:39:14 +0100 Subject: [PATCH 151/199] Fall back to View.propTypes if ViewPropTypes is not available (#1473) (#1474) --- lib/components/MapView.js | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/lib/components/MapView.js b/lib/components/MapView.js index a0f3fa02c..e984b9bb1 100644 --- a/lib/components/MapView.js +++ b/lib/components/MapView.js @@ -8,6 +8,7 @@ import { NativeModules, ColorPropType, findNodeHandle, + View, ViewPropTypes, } from 'react-native'; import MapMarker from './MapMarker'; @@ -45,8 +46,11 @@ const viewConfig = { }, }; +// if ViewPropTypes is not defined fall back to View.propType (to support RN < 0.44) +const viewPropTypes = ViewPropTypes || View.propTypes; + const propTypes = { - ...ViewPropTypes, + ...viewPropTypes, /** * When provider is "google", we will use GoogleMaps. * Any value other than "google" will default to using @@ -60,7 +64,7 @@ const propTypes = { * Used to style and layout the `MapView`. See `StyleSheet.js` and * `ViewStylePropTypes.js` for more info. */ - style: ViewPropTypes.style, + style: viewPropTypes.style, /** * A json object that describes the style of the map. This is transformed to a string From a0c8af09090a8d834bafd0ee4e5078ac55b66454 Mon Sep 17 00:00:00 2001 From: Jessy Musoko Date: Fri, 4 Aug 2017 23:13:36 +0200 Subject: [PATCH 152/199] Added [iOS / Google Maps] support for showsIndoorLevelPicker. --- lib/ios/AirGoogleMaps/AIRGoogleMap.h | 1 + lib/ios/AirGoogleMaps/AIRGoogleMap.m | 8 ++++++++ lib/ios/AirGoogleMaps/AIRGoogleMapManager.m | 1 + 3 files changed, 10 insertions(+) diff --git a/lib/ios/AirGoogleMaps/AIRGoogleMap.h b/lib/ios/AirGoogleMaps/AIRGoogleMap.h index 0d47b72b1..d2a8e3e6f 100644 --- a/lib/ios/AirGoogleMaps/AIRGoogleMap.h +++ b/lib/ios/AirGoogleMaps/AIRGoogleMap.h @@ -40,6 +40,7 @@ @property (nonatomic, assign) BOOL pitchEnabled; @property (nonatomic, assign) BOOL showsUserLocation; @property (nonatomic, assign) BOOL showsMyLocationButton; +@property (nonatomic, assign) BOOL showsIndoorLevelPicker; - (void)didFinishTileRendering; - (BOOL)didTapMarker:(GMSMarker *)marker; diff --git a/lib/ios/AirGoogleMaps/AIRGoogleMap.m b/lib/ios/AirGoogleMaps/AIRGoogleMap.m index 48b5ff446..f10238531 100644 --- a/lib/ios/AirGoogleMaps/AIRGoogleMap.m +++ b/lib/ios/AirGoogleMaps/AIRGoogleMap.m @@ -312,6 +312,14 @@ - (void)setMaxZoomLevel:(CGFloat)maxZoomLevel { [self setMinZoom:self.minZoom maxZoom:maxZoomLevel ]; } +- (void)setShowsIndoorLevelPicker:(BOOL)showsIndoorLevelPicker { + self.settings.indoorPicker = showsIndoorLevelPicker; +} + +- (BOOL)showsIndoorLevelPicker { + return self.settings.indoorPicker; +} + + (MKCoordinateRegion) makeGMSCameraPositionFromMap:(GMSMapView *)map andGMSCameraPosition:(GMSCameraPosition *)position { // solution from here: http://stackoverflow.com/a/16587735/1102215 GMSVisibleRegion visibleRegion = map.projection.visibleRegion; diff --git a/lib/ios/AirGoogleMaps/AIRGoogleMapManager.m b/lib/ios/AirGoogleMaps/AIRGoogleMapManager.m index 086822b73..54ff10b10 100644 --- a/lib/ios/AirGoogleMaps/AIRGoogleMapManager.m +++ b/lib/ios/AirGoogleMaps/AIRGoogleMapManager.m @@ -58,6 +58,7 @@ - (UIView *)view RCT_EXPORT_VIEW_PROPERTY(pitchEnabled, BOOL) RCT_EXPORT_VIEW_PROPERTY(showsUserLocation, BOOL) RCT_EXPORT_VIEW_PROPERTY(showsMyLocationButton, BOOL) +RCT_EXPORT_VIEW_PROPERTY(showsIndoorLevelPicker, BOOL) RCT_EXPORT_VIEW_PROPERTY(customMapStyleString, NSString) RCT_EXPORT_VIEW_PROPERTY(onMapReady, RCTBubblingEventBlock) RCT_EXPORT_VIEW_PROPERTY(onPress, RCTBubblingEventBlock) From c56d699f3c69841a3520cd2bad4af805279e448a Mon Sep 17 00:00:00 2001 From: Jessy Date: Mon, 28 Aug 2017 20:05:02 +0200 Subject: [PATCH 153/199] Updated "showsIndoorLevelPicker" documentation. --- docs/mapview.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/mapview.md b/docs/mapview.md index a73e123b8..f11094725 100644 --- a/docs/mapview.md +++ b/docs/mapview.md @@ -20,7 +20,7 @@ | `showsBuildings` | `Boolean` | `true` | A Boolean indicating whether the map displays extruded building information. | `showsTraffic` | `Boolean` | `true` | A Boolean value indicating whether the map displays traffic information. | `showsIndoors` | `Boolean` | `true` | A Boolean indicating whether indoor maps should be enabled. -| `showsIndoorLevelPicker` | `Boolean` | `false` | A Boolean indicating whether indoor level picker should be enabled. **Note:** Android only. +| `showsIndoorLevelPicker` | `Boolean` | `false` | A Boolean indicating whether indoor level picker should be enabled. **Note:** Google Maps only (either Android or iOS with `PROVIDER_GOOGLE`). | `zoomEnabled` | `Boolean` | `true` | If `false` the user won't be able to pinch/zoom the map. | `minZoomLevel` | `Number` | `0` | Minimum zoom value for the map, must be between 0 and 20 | `maxZoomLevel` | `Number` | `20` | Maximum zoom value for the map, must be between 0 and 20 From c184189adfd3c9fcdbef49449e3e5aa4926ac473 Mon Sep 17 00:00:00 2001 From: Paito Anderson Date: Mon, 28 Aug 2017 23:21:21 -0400 Subject: [PATCH 154/199] Added Typescript Definitions --- index.d.ts | 159 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 159 insertions(+) create mode 100644 index.d.ts diff --git a/index.d.ts b/index.d.ts new file mode 100644 index 000000000..d885759b2 --- /dev/null +++ b/index.d.ts @@ -0,0 +1,159 @@ +import * as React from 'react'; + +declare module "react-native-maps" { + + export type ProviderType = 'google'; + export type MapType = 'standard' | 'satellite' | 'hybrid' | 'terrain' | 'none'; + export type LineCapType = 'butt' | 'round' | 'square'; + export type LineJoinType = 'miter' | 'round' | 'bevel'; + + export interface MapViewProperties { + provider?: ProviderType; + style?: any; + customMapStyle?: any[]; + customMapStyleString?: string; + showsUserLocation?: boolean; + userLocationAnnotationTitle?: string; + showsMyLocationButton?: boolean; + followsUserLocation?: boolean; + showsPointsOfInterest?: boolean; + showsCompass?: boolean; + zoomEnabled?: boolean; + rotateEnabled?: boolean; + cacheEnabled?: boolean; + loadingEnabled?: boolean; + loadingBackgroundColor?: any; + loadingIndicatorColor?: any; + scrollEnabled?: boolean; + pitchEnabled?: boolean; + toolbarEnabled?: boolean; + moveOnMarkerPress?: boolean; + showsScale?: boolean; + showsBuildings?: boolean; + showsTraffic?: boolean; + showsIndoors?: boolean; + showsIndoorLevelPicker?: boolean; + mapType?: MapType; + region?: { latitude: number; longitude: number; latitudeDelta: number; longitudeDelta: number; }; + initialRegion?: { latitude: number; longitude: number; latitudeDelta: number; longitudeDelta: number; }; + liteMode?: boolean; + maxDelta?: number; + minDelta?: number; + legalLabelInsets?: any; + onChange?: Function; + onMapReady?: Function; + onRegionChange?: Function; + onRegionChangeComplete?: Function; + onPress?: Function; + onLayout?: Function; + onLongPress?: Function; + onPanDrag?: Function; + onMarkerPress?: Function; + onMarkerSelect?: Function; + onMarkerDeselect?: Function; + onCalloutPress?: Function; + onMarkerDragStart?: Function; + onMarkerDrag?: Function; + onMarkerDragEnd?: Function; + minZoomLevel?: number; + maxZoomLevel?: number; + } + + export interface MarkerProperties { + identifier?: string; + reuseIdentifier?: string; + title?: string; + description?: string; + image?: any; + opacity?: number; + pinColor?: string; + coordinate: { latitude: number; longitude: number }; + centerOffset?: { x: number; y: number }; + calloutOffset?: { x: number; y: number }; + anchor?: { x: number; y: number }; + calloutAnchor?: { x: number; y: number }; + flat?: boolean; + draggable?: boolean; + onPress?: Function; + onSelect?: Function; + onDeselect?: Function; + onCalloutPress?: Function; + onDragStart?: Function; + onDrag?: Function; + onDragEnd?: Function; + } + + export interface MapPolylineProperties { + coordinates?: { latitude: number; longitude: number; }[]; + onPress?: Function; + tappable?: boolean; + fillColor?: string; + strokeWidth?: number; + strokeColor?: string; + zIndex?: number; + lineCap?: LineCapType; + lineJoin?: LineJoinType; + miterLimit?: number; + geodesic?: boolean; + lineDashPhase?: number; + lineDashPattern?: number[]; + } + + export interface MapPolygonProperties { + coordinates?: { latitude: number; longitude: number; }[]; + holes?: { latitude: number; longitude: number; }[][]; + onPress?: Function; + tappable?: boolean; + strokeWidth?: number; + strokeColor?: string; + fillColor?: string; + zIndex?: number; + lineCap?: LineCapType; + lineJoin?: LineJoinType; + miterLimit?: number; + geodesic?: boolean; + lineDashPhase?: number; + lineDashPattern?: number[]; + } + + export interface MapCircleProperties { + center: { latitude: number; longitude: number }; + radius: number; + onPress?: Function; + strokeWidth?: number; + strokeColor?: string; + fillColor?: string; + zIndex?: number; + lineCap?: LineCapType; + lineJoin?: LineJoinType; + miterLimit?: number; + lineDashPhase?: number; + lineDashPattern?: number[]; + } + + export interface MapUrlTitleProperties { + urlTemplate: string; + zIndex?: number; + } + + export interface MapCalloutProperties { + tooltip?: boolean; + onPress?: Function; + } + + class MapView extends React.Component { + static Animated: any; + static AnimatedRegion: any; + } + + namespace MapView { + class Marker extends React.Component {} + class Polyline extends React.Component {} + class Polygon extends React.Component {} + class Circle extends React.Component {} + class UrlTile extends React.Component {} + class Callout extends React.Component {} + } + + export default MapView; +} From 3611c22ff3802682b604b5d8ba33f37f2213bdb9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Peter=20Hagstr=C3=B6m?= Date: Tue, 29 Aug 2017 18:25:13 +0200 Subject: [PATCH 155/199] Set initial region on view (#1579) --- lib/ios/AirMaps/AIRMapManager.m | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/lib/ios/AirMaps/AIRMapManager.m b/lib/ios/AirMaps/AIRMapManager.m index 76aef88fe..8ddd98c55 100644 --- a/lib/ios/AirMaps/AIRMapManager.m +++ b/lib/ios/AirMaps/AIRMapManager.m @@ -97,7 +97,17 @@ - (UIView *)view RCT_EXPORT_VIEW_PROPERTY(onMarkerDrag, RCTDirectEventBlock) RCT_EXPORT_VIEW_PROPERTY(onMarkerDragEnd, RCTDirectEventBlock) RCT_EXPORT_VIEW_PROPERTY(onCalloutPress, RCTDirectEventBlock) -RCT_EXPORT_VIEW_PROPERTY(initialRegion, MKCoordinateRegion) +RCT_CUSTOM_VIEW_PROPERTY(initialRegion, MKCoordinateRegion, AIRMap) +{ + if (json == nil) return; + + // don't emit region change events when we are setting the initialRegion + BOOL originalIgnore = view.ignoreRegionChanges; + view.ignoreRegionChanges = YES; + [view setInitialRegion:[RCTConvert MKCoordinateRegion:json]]; + view.ignoreRegionChanges = originalIgnore; +} + RCT_EXPORT_VIEW_PROPERTY(minZoomLevel, CGFloat) RCT_EXPORT_VIEW_PROPERTY(maxZoomLevel, CGFloat) @@ -665,7 +675,7 @@ - (void)mapViewDidFinishRenderingMap:(AIRMap *)mapView fullyRendered:(BOOL)fully { [mapView finishLoading]; [mapView cacheViewIfNeeded]; - + mapView.onMapReady(@{}); } From 605ec9a7a4351fccd1dcd6ce43af35ab2381dd2c Mon Sep 17 00:00:00 2001 From: Tikhon Botchkarev Date: Fri, 1 Sep 2017 18:11:22 -0400 Subject: [PATCH 156/199] Remove legalNotice from android AirMapModule As per https://developers.google.com/android/reference/com/google/android/gms/common/GooglePlayServicesUtil this information does not need to be displayed in app. --- .../main/java/com/airbnb/android/react/maps/AirMapModule.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapModule.java b/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapModule.java index bd1fb6ed0..dfc71d6d9 100644 --- a/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapModule.java +++ b/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapModule.java @@ -47,7 +47,7 @@ public String getName() { @Override public Map getConstants() { final Map constants = new HashMap<>(); - constants.put("legalNotice", GoogleApiAvailability.getInstance().getOpenSourceSoftwareLicenseInfo(getReactApplicationContext())); + constants.put("legalNotice", "This license information is displayed in Settings > Google > Open Source on any device running Google Play services."); return constants; } From ddf858bdf1813ca20a231f3ef0dff5dbe4fbfedc Mon Sep 17 00:00:00 2001 From: Paito Anderson Date: Sat, 2 Sep 2017 19:43:17 -0400 Subject: [PATCH 157/199] Added missing satellite option for iOS Google Maps (#1603) --- lib/ios/AirGoogleMaps/RCTConvert+GMSMapViewType.m | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/ios/AirGoogleMaps/RCTConvert+GMSMapViewType.m b/lib/ios/AirGoogleMaps/RCTConvert+GMSMapViewType.m index bd339f30e..cfceba559 100644 --- a/lib/ios/AirGoogleMaps/RCTConvert+GMSMapViewType.m +++ b/lib/ios/AirGoogleMaps/RCTConvert+GMSMapViewType.m @@ -13,6 +13,7 @@ @implementation RCTConvert (GMSMapViewType) ( @{ @"standard": @(kGMSTypeNormal), + @"satellite": @(kGMSTypeSatellite), @"hybrid": @(kGMSTypeHybrid), @"terrain": @(kGMSTypeTerrain), @"none": @(kGMSTypeNone) From e6a3f7aedc12cbb5584cb7df638e8ee0c8847aef Mon Sep 17 00:00:00 2001 From: Daniel Merrill Date: Sat, 2 Sep 2017 17:17:58 -0700 Subject: [PATCH 158/199] [MapView] revert initialRegion change (#1613) Reverts JS changes made in #1563 which broke initialRegion on iOS, causing the map to display a region centered around 0, 0. --- lib/components/MapView.js | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/lib/components/MapView.js b/lib/components/MapView.js index e984b9bb1..53db49548 100644 --- a/lib/components/MapView.js +++ b/lib/components/MapView.js @@ -466,13 +466,10 @@ class MapView extends React.Component { const { layout } = e.nativeEvent; if (!layout.width || !layout.height) return; if (this.state.isReady && !this.__layoutCalled) { - const { region, initialRegion } = this.props; + const region = this.props.region || this.props.initialRegion; if (region) { this.__layoutCalled = true; this.map.setNativeProps({ region }); - } else if (initialRegion) { - this.__layoutCalled = true; - this.map.setNativeProps({ initialRegion }); } } if (this.props.onLayout) { From 0916cdff2764a29d0817d3ccc45541ecf411fa1c Mon Sep 17 00:00:00 2001 From: Christopher Dro Date: Sat, 2 Sep 2017 17:23:22 -0700 Subject: [PATCH 159/199] Revert "[MapView] revert initialRegion change (#1613)" This reverts commit e6a3f7aedc12cbb5584cb7df638e8ee0c8847aef. --- lib/components/MapView.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/lib/components/MapView.js b/lib/components/MapView.js index 53db49548..e984b9bb1 100644 --- a/lib/components/MapView.js +++ b/lib/components/MapView.js @@ -466,10 +466,13 @@ class MapView extends React.Component { const { layout } = e.nativeEvent; if (!layout.width || !layout.height) return; if (this.state.isReady && !this.__layoutCalled) { - const region = this.props.region || this.props.initialRegion; + const { region, initialRegion } = this.props; if (region) { this.__layoutCalled = true; this.map.setNativeProps({ region }); + } else if (initialRegion) { + this.__layoutCalled = true; + this.map.setNativeProps({ initialRegion }); } } if (this.props.onLayout) { From daf62e6c4a592b2f84c4f7effb4540ac5225d427 Mon Sep 17 00:00:00 2001 From: Christopher Dro Date: Sat, 2 Sep 2017 17:27:31 -0700 Subject: [PATCH 160/199] Bump 0.16.3 --- CHANGELOG.md | 4 ++++ lib/android/gradle.properties | 2 +- package.json | 2 +- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f9ae8057e..c00583d5e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Change Log +## 0.16.3 (September 2, 2017) +* iOS: [#1603](https://github.com/airbnb/react-native-maps/pull/1603) Added missing satellite option for iOS Google Maps +* iOS: [#1579](https://github.com/airbnb/react-native-maps/pull/1579) Set initial region on view + ## 0.16.2 (August 17, 2017) * Android: [#1563](https://github.com/airbnb/react-native-maps/pull/#1563) Add missing native method for setting initial region * iOS: [#1187](https://github.com/airbnb/react-native-maps/pull/1187) Reverted due to build issues diff --git a/lib/android/gradle.properties b/lib/android/gradle.properties index 9b4cf86c9..c49d0997b 100644 --- a/lib/android/gradle.properties +++ b/lib/android/gradle.properties @@ -1,5 +1,5 @@ VERSION_CODE=4 -VERSION_NAME=0.16.2 +VERSION_NAME=0.16.3 GROUP=com.airbnb.android POM_DESCRIPTION=React Native Map view component for Android diff --git a/package.json b/package.json index 6914f242b..e8db38a4a 100644 --- a/package.json +++ b/package.json @@ -3,7 +3,7 @@ "description": "React Native Mapview component for iOS + Android", "main": "index.js", "author": "Leland Richardson ", - "version": "0.16.2", + "version": "0.16.3", "scripts": { "start": "node node_modules/react-native/local-cli/cli.js start", "run:packager": "./node_modules/react-native/packager/packager.sh", From ecfc89b6151c03f90a379c4a580c0a3de851f802 Mon Sep 17 00:00:00 2001 From: sandinosaso Date: Sun, 27 Aug 2017 13:00:00 -0300 Subject: [PATCH 161/199] Add support for animateToViewingAngle and animateToBearing for Android --- .../android/react/maps/AirMapManager.java | 24 ++++++++++++++++--- .../airbnb/android/react/maps/AirMapView.java | 20 ++++++++++++++++ 2 files changed, 41 insertions(+), 3 deletions(-) diff --git a/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapManager.java b/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapManager.java index e8f98a766..58824dd0c 100644 --- a/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapManager.java +++ b/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapManager.java @@ -29,9 +29,11 @@ public class AirMapManager extends ViewGroupManager { private static final String REACT_CLASS = "AIRMap"; private static final int ANIMATE_TO_REGION = 1; private static final int ANIMATE_TO_COORDINATE = 2; - private static final int FIT_TO_ELEMENTS = 3; - private static final int FIT_TO_SUPPLIED_MARKERS = 4; - private static final int FIT_TO_COORDINATES = 5; + private static final int ANIMATE_TO_VIEWING_ANGLE = 3; + private static final int ANIMATE_TO_BEARING = 4; + private static final int FIT_TO_ELEMENTS = 5; + private static final int FIT_TO_SUPPLIED_MARKERS = 6; + private static final int FIT_TO_COORDINATES = 7; private final Map MAP_TYPES = MapBuilder.of( "standard", GoogleMap.MAP_TYPE_NORMAL, @@ -195,6 +197,8 @@ public void receiveCommand(AirMapView view, int commandId, @Nullable ReadableArr Double lng; Double lngDelta; Double latDelta; + float bearing; + float angle; ReadableMap region; switch (commandId) { @@ -220,6 +224,18 @@ public void receiveCommand(AirMapView view, int commandId, @Nullable ReadableArr view.animateToCoordinate(new LatLng(lat, lng), duration); break; + case ANIMATE_TO_VIEWING_ANGLE: + angle = (float)args.getDouble(0); + duration = args.getInt(1); + view.animateToViewingAngle(angle, duration); + break; + + case ANIMATE_TO_BEARING: + bearing = (float)args.getDouble(0); + duration = args.getInt(1); + view.animateToBearing(bearing, duration); + break; + case FIT_TO_ELEMENTS: view.fitToElements(args.getBoolean(0)); break; @@ -262,6 +278,8 @@ public Map getCommandsMap() { return MapBuilder.of( "animateToRegion", ANIMATE_TO_REGION, "animateToCoordinate", ANIMATE_TO_COORDINATE, + "animateToViewingAngle", ANIMATE_TO_VIEWING_ANGLE, + "animateToBearing", ANIMATE_TO_BEARING, "fitToElements", FIT_TO_ELEMENTS, "fitToSuppliedMarkers", FIT_TO_SUPPLIED_MARKERS, "fitToCoordinates", FIT_TO_COORDINATES diff --git a/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapView.java b/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapView.java index c8b016ce1..9d3f572a9 100644 --- a/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapView.java +++ b/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapView.java @@ -562,6 +562,26 @@ public void animateToRegion(LatLngBounds bounds, int duration) { } } + public void animateToViewingAngle(float angle, int duration) { + if (map != null) { + startMonitoringRegion(); + CameraPosition cameraPosition = new CameraPosition.Builder(map.getCameraPosition()) + .tilt(angle) + .build(); + map.animateCamera(CameraUpdateFactory.newCameraPosition(cameraPosition), duration, null); + } + } + + public void animateToBearing(float bearing, int duration) { + if (map != null) { + startMonitoringRegion(); + CameraPosition cameraPosition = new CameraPosition.Builder(map.getCameraPosition()) + .bearing(bearing) + .build(); + map.animateCamera(CameraUpdateFactory.newCameraPosition(cameraPosition), duration, null); + } + } + public void animateToCoordinate(LatLng coordinate, int duration) { if (map != null) { startMonitoringRegion(); From 6885fda900f1fc152de1bac5908e25bd98b59c32 Mon Sep 17 00:00:00 2001 From: Carlo Date: Wed, 13 Sep 2017 18:24:55 -0700 Subject: [PATCH 162/199] [MapMarker] fix android release crash on custom marker (#1643) --- .../main/java/com/airbnb/android/react/maps/AirMapMarker.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapMarker.java b/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapMarker.java index 52c4dcd08..cb0274bfa 100644 --- a/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapMarker.java +++ b/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapMarker.java @@ -2,6 +2,7 @@ import android.content.Context; import android.graphics.Bitmap; +import android.graphics.BitmapFactory; import android.graphics.Canvas; import android.graphics.drawable.Animatable; import android.net.Uri; @@ -236,6 +237,9 @@ public void setImage(String uri) { logoHolder.setController(controller); } else { iconBitmapDescriptor = getBitmapDescriptorByName(uri); + if (iconBitmapDescriptor != null) { + iconBitmap = BitmapFactory.decodeResource(getResources(), getDrawableResourceByName(uri)); + } update(); } } From 6ad2eca39d7e4033be246d3f61f9cd5d17281944 Mon Sep 17 00:00:00 2001 From: Christopher Dro Date: Wed, 13 Sep 2017 18:27:10 -0700 Subject: [PATCH 163/199] v0.16.4 --- CHANGELOG.md | 3 +++ lib/android/gradle.properties | 2 +- package.json | 2 +- 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c00583d5e..5952fe825 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,8 @@ # Change Log +## 0.16.4 (September 13, 2017) +* Android: [#1643](https://github.com/airbnb/react-native-maps/pull/1643) [MapMarker] fix android release crash on custom marker + ## 0.16.3 (September 2, 2017) * iOS: [#1603](https://github.com/airbnb/react-native-maps/pull/1603) Added missing satellite option for iOS Google Maps * iOS: [#1579](https://github.com/airbnb/react-native-maps/pull/1579) Set initial region on view diff --git a/lib/android/gradle.properties b/lib/android/gradle.properties index c49d0997b..a6b4e78ee 100644 --- a/lib/android/gradle.properties +++ b/lib/android/gradle.properties @@ -1,5 +1,5 @@ VERSION_CODE=4 -VERSION_NAME=0.16.3 +VERSION_NAME=0.16.4 GROUP=com.airbnb.android POM_DESCRIPTION=React Native Map view component for Android diff --git a/package.json b/package.json index e8db38a4a..11f1004fb 100644 --- a/package.json +++ b/package.json @@ -3,7 +3,7 @@ "description": "React Native Mapview component for iOS + Android", "main": "index.js", "author": "Leland Richardson ", - "version": "0.16.3", + "version": "0.16.4", "scripts": { "start": "node node_modules/react-native/local-cli/cli.js start", "run:packager": "./node_modules/react-native/packager/packager.sh", From 86e79df9f65a448cfe195c0a2ebfdab652b96c2e Mon Sep 17 00:00:00 2001 From: Paito Anderson Date: Sun, 8 Oct 2017 22:25:27 -0400 Subject: [PATCH 164/199] Update index.d.ts --- index.d.ts | 151 ++++++++++++++++++++++++++--------------------------- 1 file changed, 74 insertions(+), 77 deletions(-) diff --git a/index.d.ts b/index.d.ts index d885759b2..9a770c3fc 100644 --- a/index.d.ts +++ b/index.d.ts @@ -1,65 +1,68 @@ import * as React from 'react'; -declare module "react-native-maps" { +interface MapViewProps { + provider?: 'google'; + style: any; + customMapStyle?: any[]; + customMapStyleString?: string; + showsUserLocation?: boolean; + userLocationAnnotationTitle?: string; + showsMyLocationButton?: boolean; + followsUserLocation?: boolean; + showsPointsOfInterest?: boolean; + showsCompass?: boolean; + zoomEnabled?: boolean; + rotateEnabled?: boolean; + cacheEnabled?: boolean; + loadingEnabled?: boolean; + loadingBackgroundColor?: any; + loadingIndicatorColor?: any; + scrollEnabled?: boolean; + pitchEnabled?: boolean; + toolbarEnabled?: boolean; + moveOnMarkerPress?: boolean; + showsScale?: boolean; + showsBuildings?: boolean; + showsTraffic?: boolean; + showsIndoors?: boolean; + showsIndoorLevelPicker?: boolean; + mapType?: 'standard' | 'satellite' | 'hybrid' | 'terrain' | 'none'; + region?: { latitude: number; longitude: number; latitudeDelta: number; longitudeDelta: number; }; + initialRegion?: { latitude: number; longitude: number; latitudeDelta: number; longitudeDelta: number; }; + liteMode?: boolean; + maxDelta?: number; + minDelta?: number; + legalLabelInsets?: any; + onChange?: Function; + onMapReady?: Function; + onRegionChange?: Function; + onRegionChangeComplete?: Function; + onPress?: Function; + onLayout?: Function; + onLongPress?: Function; + onPanDrag?: Function; + onMarkerPress?: Function; + onMarkerSelect?: Function; + onMarkerDeselect?: Function; + onCalloutPress?: Function; + onMarkerDragStart?: Function; + onMarkerDrag?: Function; + onMarkerDragEnd?: Function; + minZoomLevel?: number; + maxZoomLevel?: number; +} - export type ProviderType = 'google'; - export type MapType = 'standard' | 'satellite' | 'hybrid' | 'terrain' | 'none'; - export type LineCapType = 'butt' | 'round' | 'square'; - export type LineJoinType = 'miter' | 'round' | 'bevel'; +declare class MapView extends React.Component { + static Animated: any; + static AnimatedRegion: any; +} - export interface MapViewProperties { - provider?: ProviderType; - style?: any; - customMapStyle?: any[]; - customMapStyleString?: string; - showsUserLocation?: boolean; - userLocationAnnotationTitle?: string; - showsMyLocationButton?: boolean; - followsUserLocation?: boolean; - showsPointsOfInterest?: boolean; - showsCompass?: boolean; - zoomEnabled?: boolean; - rotateEnabled?: boolean; - cacheEnabled?: boolean; - loadingEnabled?: boolean; - loadingBackgroundColor?: any; - loadingIndicatorColor?: any; - scrollEnabled?: boolean; - pitchEnabled?: boolean; - toolbarEnabled?: boolean; - moveOnMarkerPress?: boolean; - showsScale?: boolean; - showsBuildings?: boolean; - showsTraffic?: boolean; - showsIndoors?: boolean; - showsIndoorLevelPicker?: boolean; - mapType?: MapType; - region?: { latitude: number; longitude: number; latitudeDelta: number; longitudeDelta: number; }; - initialRegion?: { latitude: number; longitude: number; latitudeDelta: number; longitudeDelta: number; }; - liteMode?: boolean; - maxDelta?: number; - minDelta?: number; - legalLabelInsets?: any; - onChange?: Function; - onMapReady?: Function; - onRegionChange?: Function; - onRegionChangeComplete?: Function; - onPress?: Function; - onLayout?: Function; - onLongPress?: Function; - onPanDrag?: Function; - onMarkerPress?: Function; - onMarkerSelect?: Function; - onMarkerDeselect?: Function; - onCalloutPress?: Function; - onMarkerDragStart?: Function; - onMarkerDrag?: Function; - onMarkerDragEnd?: Function; - minZoomLevel?: number; - maxZoomLevel?: number; - } +declare namespace MapView { + + type LineCapType = 'butt' | 'round' | 'square'; + type LineJoinType = 'miter' | 'round' | 'bevel'; - export interface MarkerProperties { + interface MarkerProps { identifier?: string; reuseIdentifier?: string; title?: string; @@ -81,9 +84,10 @@ declare module "react-native-maps" { onDragStart?: Function; onDrag?: Function; onDragEnd?: Function; + zIndex?: number; } - export interface MapPolylineProperties { + interface MapPolylineProps { coordinates?: { latitude: number; longitude: number; }[]; onPress?: Function; tappable?: boolean; @@ -99,7 +103,7 @@ declare module "react-native-maps" { lineDashPattern?: number[]; } - export interface MapPolygonProperties { + interface MapPolygonProps { coordinates?: { latitude: number; longitude: number; }[]; holes?: { latitude: number; longitude: number; }[][]; onPress?: Function; @@ -116,7 +120,7 @@ declare module "react-native-maps" { lineDashPattern?: number[]; } - export interface MapCircleProperties { + interface MapCircleProps { center: { latitude: number; longitude: number }; radius: number; onPress?: Function; @@ -131,29 +135,22 @@ declare module "react-native-maps" { lineDashPattern?: number[]; } - export interface MapUrlTitleProperties { + interface MapUrlTitleProps { urlTemplate: string; zIndex?: number; } - export interface MapCalloutProperties { + interface MapCalloutProps { tooltip?: boolean; onPress?: Function; } - class MapView extends React.Component { - static Animated: any; - static AnimatedRegion: any; - } - - namespace MapView { - class Marker extends React.Component {} - class Polyline extends React.Component {} - class Polygon extends React.Component {} - class Circle extends React.Component {} - class UrlTile extends React.Component {} - class Callout extends React.Component {} - } - - export default MapView; + export class Marker extends React.Component {} + export class Polyline extends React.Component {} + export class Polygon extends React.Component {} + export class Circle extends React.Component {} + export class UrlTile extends React.Component {} + export class Callout extends React.Component {} } + +export = MapView; From 9fd1055c2b1321ed1b830cd5de6434a5a06f773a Mon Sep 17 00:00:00 2001 From: Christopher Dro Date: Wed, 11 Oct 2017 11:42:27 -0700 Subject: [PATCH 165/199] v0.17.0 --- CHANGELOG.md | 8 ++++++++ lib/android/gradle.properties | 2 +- package.json | 2 +- 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5952fe825..5678d8052 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,13 @@ # Change Log +## 0.17.0 (October 11, 2017) +* iOS: [#1527](https://github.com/airbnb/react-native-maps/pull/1527) Added [iOS / Google Maps] support for showsIndoorLevelPicker +* iOS/Android: [#1544](https://github.com/airbnb/react-native-maps/pull/1544) Adds support to animateToBearing and animateToViewingAngle ( IOS + Android ) +* JS: [#1503](https://github.com/airbnb/react-native-maps/pull/1503) Remove caret from "react": "^16.0.0-alpha.12 +* Android: [#1521](https://github.com/airbnb/react-native-maps/pull/1521) Fix rare android crashes when map size is 0 +* Common: [#1610](https://github.com/airbnb/react-native-maps/pull/1610) Added Typescript Definitions +* Android: [#1612](https://github.com/airbnb/react-native-maps/pull/1612) Remove legalNotice from android AirMapModule + ## 0.16.4 (September 13, 2017) * Android: [#1643](https://github.com/airbnb/react-native-maps/pull/1643) [MapMarker] fix android release crash on custom marker diff --git a/lib/android/gradle.properties b/lib/android/gradle.properties index a6b4e78ee..7047e93ba 100644 --- a/lib/android/gradle.properties +++ b/lib/android/gradle.properties @@ -1,5 +1,5 @@ VERSION_CODE=4 -VERSION_NAME=0.16.4 +VERSION_NAME=0.17.0 GROUP=com.airbnb.android POM_DESCRIPTION=React Native Map view component for Android diff --git a/package.json b/package.json index a50930ab8..66e8be298 100644 --- a/package.json +++ b/package.json @@ -3,7 +3,7 @@ "description": "React Native Mapview component for iOS + Android", "main": "index.js", "author": "Leland Richardson ", - "version": "0.16.4", + "version": "0.17.0", "scripts": { "start": "node node_modules/react-native/local-cli/cli.js start", "run:packager": "./node_modules/react-native/packager/packager.sh", From a427a81434689253784bfb899278c23ee4723324 Mon Sep 17 00:00:00 2001 From: Michel Albers Date: Wed, 25 Oct 2017 13:26:39 +0200 Subject: [PATCH 166/199] Workaround for "GoogleMapsBase not found" issue --- react-native-google-maps.podspec | 1 + 1 file changed, 1 insertion(+) diff --git a/react-native-google-maps.podspec b/react-native-google-maps.podspec index 632da81d5..487cc2320 100644 --- a/react-native-google-maps.podspec +++ b/react-native-google-maps.podspec @@ -14,6 +14,7 @@ Pod::Spec.new do |s| s.source = { :git => "https://github.com/airbnb/react-native-maps.git" } s.source_files = "lib/ios/AirGoogleMaps/**/*.{h,m}" + s.compiler_flags = '-fno-modules' s.dependency 'React' s.dependency 'GoogleMaps', '2.1.1' From 5edaaf47c2132d1283e4453de7e7fd61d6434f69 Mon Sep 17 00:00:00 2001 From: Thibault Malbranche Date: Tue, 31 Oct 2017 16:33:10 +0100 Subject: [PATCH 167/199] Fix React Native 0.49 requiresMainQueueSetup --- lib/ios/AirGoogleMaps/AIRGoogleMapManager.m | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/lib/ios/AirGoogleMaps/AIRGoogleMapManager.m b/lib/ios/AirGoogleMaps/AIRGoogleMapManager.m index 12d63e104..867b41803 100644 --- a/lib/ios/AirGoogleMaps/AIRGoogleMapManager.m +++ b/lib/ios/AirGoogleMaps/AIRGoogleMapManager.m @@ -263,6 +263,10 @@ - (NSDictionary *)constantsToExport { return @{ @"legalNotice": [GMSServices openSourceLicenseInfo] }; } ++ (BOOL)requiresMainQueueSetup { + return YES; +} + - (void)mapViewDidFinishTileRendering:(GMSMapView *)mapView { AIRGoogleMap *googleMapView = (AIRGoogleMap *)mapView; [googleMapView didFinishTileRendering]; From 1c47c657b8b3052a576eba76a7ecf33ae08b3bf9 Mon Sep 17 00:00:00 2001 From: Bramus! Date: Tue, 28 Nov 2017 19:13:15 +0100 Subject: [PATCH 168/199] Allow fitToCoordinates to be called without options parameter (#1817) Right now it's not possible to call `fitToCoordinates` without an `options` parameter, even though defaults are defined in the function body. This commit set the default value of the `options` parameter of to an empty object, allowing one to call the function without it _(and with respect for the defaults)_. --- lib/components/MapView.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/components/MapView.js b/lib/components/MapView.js index 123d34f60..e88727c13 100644 --- a/lib/components/MapView.js +++ b/lib/components/MapView.js @@ -515,7 +515,7 @@ class MapView extends React.Component { this._runCommand('fitToSuppliedMarkers', [markers, animated]); } - fitToCoordinates(coordinates = [], options) { + fitToCoordinates(coordinates = [], options = {}) { const { edgePadding = { top: 0, right: 0, bottom: 0, left: 0 }, animated = true, From 3c3fc5c07871ba236d0f0beff53716311e6fa6aa Mon Sep 17 00:00:00 2001 From: Daniel Cohen Gindi Date: Tue, 28 Nov 2017 20:15:17 +0200 Subject: [PATCH 169/199] Fixed onMapReady event on iOS to resemble onMapReady on Android (Closes #1793) (#1797) Also: Closes #1776, Closes #1696, Closes #1680, Closes #1605) Probably closes more issues related to iOS, panning and scrolling. --- lib/ios/AirGoogleMaps/AIRGoogleMap.h | 2 +- lib/ios/AirGoogleMaps/AIRGoogleMap.m | 2 +- lib/ios/AirGoogleMaps/AIRGoogleMapManager.m | 18 ++++++++++-------- lib/ios/AirMaps/AIRMapManager.m | 14 ++++++++++---- 4 files changed, 22 insertions(+), 14 deletions(-) diff --git a/lib/ios/AirGoogleMaps/AIRGoogleMap.h b/lib/ios/AirGoogleMaps/AIRGoogleMap.h index d2a8e3e6f..fa0293ae3 100644 --- a/lib/ios/AirGoogleMaps/AIRGoogleMap.h +++ b/lib/ios/AirGoogleMaps/AIRGoogleMap.h @@ -42,7 +42,7 @@ @property (nonatomic, assign) BOOL showsMyLocationButton; @property (nonatomic, assign) BOOL showsIndoorLevelPicker; -- (void)didFinishTileRendering; +- (void)didPrepareMap; - (BOOL)didTapMarker:(GMSMarker *)marker; - (void)didTapPolyline:(GMSPolyline *)polyline; - (void)didTapPolygon:(GMSPolygon *)polygon; diff --git a/lib/ios/AirGoogleMaps/AIRGoogleMap.m b/lib/ios/AirGoogleMaps/AIRGoogleMap.m index f10238531..4c1976fe7 100644 --- a/lib/ios/AirGoogleMaps/AIRGoogleMap.m +++ b/lib/ios/AirGoogleMaps/AIRGoogleMap.m @@ -155,7 +155,7 @@ - (void)setRegion:(MKCoordinateRegion)region { self.camera = [AIRGoogleMap makeGMSCameraPositionFromMap:self andMKCoordinateRegion:region]; } -- (void)didFinishTileRendering { +- (void)didPrepareMap { if (self.onMapReady) self.onMapReady(@{}); } diff --git a/lib/ios/AirGoogleMaps/AIRGoogleMapManager.m b/lib/ios/AirGoogleMaps/AIRGoogleMapManager.m index 867b41803..559b6be3d 100644 --- a/lib/ios/AirGoogleMaps/AIRGoogleMapManager.m +++ b/lib/ios/AirGoogleMaps/AIRGoogleMapManager.m @@ -32,7 +32,10 @@ @interface AIRGoogleMapManager() - +{ + BOOL didCallOnMapReady; +} + @end @implementation AIRGoogleMapManager @@ -263,13 +266,12 @@ - (NSDictionary *)constantsToExport { return @{ @"legalNotice": [GMSServices openSourceLicenseInfo] }; } -+ (BOOL)requiresMainQueueSetup { - return YES; -} - -- (void)mapViewDidFinishTileRendering:(GMSMapView *)mapView { - AIRGoogleMap *googleMapView = (AIRGoogleMap *)mapView; - [googleMapView didFinishTileRendering]; +- (void)mapViewDidStartTileRendering:(GMSMapView *)mapView { + if (didCallOnMapReady) return; + didCallOnMapReady = YES; + + AIRGoogleMap *googleMapView = (AIRGoogleMap *)mapView; + [googleMapView didPrepareMap]; } - (BOOL)mapView:(GMSMapView *)mapView didTapMarker:(GMSMarker *)marker { diff --git a/lib/ios/AirMaps/AIRMapManager.m b/lib/ios/AirMaps/AIRMapManager.m index 483834369..1124c440c 100644 --- a/lib/ios/AirMaps/AIRMapManager.m +++ b/lib/ios/AirMaps/AIRMapManager.m @@ -36,7 +36,10 @@ @interface AIRMapManager() @end @implementation AIRMapManager - +{ + BOOL didCallOnMapReady; +} + RCT_EXPORT_MODULE() - (UIView *)view @@ -708,6 +711,12 @@ - (void)mapView:(AIRMap *)mapView regionDidChangeAnimated:(__unused BOOL)animate - (void)mapViewWillStartRenderingMap:(AIRMap *)mapView { + if (!didCallOnMapReady) + { + didCallOnMapReady = YES; + mapView.onMapReady(@{}); + } + mapView.hasStartedRendering = YES; [mapView beginLoading]; [self _emitRegionChangeEvent:mapView continuous:NO]; @@ -716,9 +725,6 @@ - (void)mapViewWillStartRenderingMap:(AIRMap *)mapView - (void)mapViewDidFinishRenderingMap:(AIRMap *)mapView fullyRendered:(BOOL)fullyRendered { [mapView finishLoading]; - [mapView cacheViewIfNeeded]; - - mapView.onMapReady(@{}); } #pragma mark Private From d11a778133b0f9663e3f6ac3eb887103c107b95e Mon Sep 17 00:00:00 2001 From: John Date: Wed, 29 Nov 2017 02:16:38 +0800 Subject: [PATCH 170/199] Update Podfile (#1816) fix `The name of the given podspec `yoga` doesn't match the expected one `Yoga`` --- example/ios/Podfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/example/ios/Podfile b/example/ios/Podfile index fd01b85a0..37326fb7d 100644 --- a/example/ios/Podfile +++ b/example/ios/Podfile @@ -7,7 +7,7 @@ platform :ios, '8.0' target 'AirMapsExplorer' do rn_path = '../../node_modules/react-native' - pod 'Yoga', path: "#{rn_path}/ReactCommon/yoga/Yoga.podspec" + pod 'yoga', path: "#{rn_path}/ReactCommon/yoga/yoga.podspec" pod 'React', path: rn_path, subspecs: [ 'Core', 'RCTActionSheet', From be1b6ded3913d09fe8462cdec741171ce9d939b4 Mon Sep 17 00:00:00 2001 From: androidseb Date: Tue, 28 Nov 2017 13:21:34 -0500 Subject: [PATCH 171/199] fixed the MapView onMarkerPress callback not sending the ID of the marker (#1741) --- lib/components/MapView.js | 9 +++++++++ lib/ios/AirGoogleMaps/AIRGoogleMapManager.m | 2 +- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/lib/components/MapView.js b/lib/components/MapView.js index e88727c13..eec576291 100644 --- a/lib/components/MapView.js +++ b/lib/components/MapView.js @@ -415,6 +415,7 @@ class MapView extends React.Component { }; this._onMapReady = this._onMapReady.bind(this); + this._onMarkerPress = this._onMarkerPress.bind(this); this._onChange = this._onChange.bind(this); this._onLayout = this._onLayout.bind(this); } @@ -480,6 +481,12 @@ class MapView extends React.Component { } } + _onMarkerPress(event) { + if (this.props.onMarkerPress) { + this.props.onMarkerPress(event.nativeEvent); + } + } + _onChange(event) { this.__lastRegion = event.nativeEvent.region; if (event.nativeEvent.continuous) { @@ -638,6 +645,7 @@ class MapView extends React.Component { ...this.props, region: null, initialRegion: null, + onMarkerPress: this._onMarkerPress, onChange: this._onChange, onMapReady: this._onMapReady, onLayout: this._onLayout, @@ -652,6 +660,7 @@ class MapView extends React.Component { style: this.props.style, region: null, initialRegion: null, + onMarkerPress: this._onMarkerPress, onChange: this._onChange, onMapReady: this._onMapReady, onLayout: this._onLayout, diff --git a/lib/ios/AirGoogleMaps/AIRGoogleMapManager.m b/lib/ios/AirGoogleMaps/AIRGoogleMapManager.m index 559b6be3d..043841305 100644 --- a/lib/ios/AirGoogleMaps/AIRGoogleMapManager.m +++ b/lib/ios/AirGoogleMaps/AIRGoogleMapManager.m @@ -67,7 +67,7 @@ - (UIView *)view RCT_EXPORT_VIEW_PROPERTY(onPress, RCTBubblingEventBlock) RCT_EXPORT_VIEW_PROPERTY(onLongPress, RCTBubblingEventBlock) RCT_EXPORT_VIEW_PROPERTY(onChange, RCTBubblingEventBlock) -RCT_EXPORT_VIEW_PROPERTY(onMarkerPress, RCTDirectEventBlock) +RCT_EXPORT_VIEW_PROPERTY(onMarkerPress, RCTBubblingEventBlock) RCT_EXPORT_VIEW_PROPERTY(onRegionChange, RCTDirectEventBlock) RCT_EXPORT_VIEW_PROPERTY(onRegionChangeComplete, RCTDirectEventBlock) RCT_EXPORT_VIEW_PROPERTY(mapType, GMSMapViewType) From 89e96788043ecb37b764101cdc56976c37222428 Mon Sep 17 00:00:00 2001 From: Paito Anderson Date: Tue, 28 Nov 2017 13:22:29 -0500 Subject: [PATCH 172/199] Added style prop to MapCalloutProps in Typings (#1759) * Added style prop to MapCalloutProps in Typings Fixes @marcmo issue in #1687 * Update index.d.ts Added style on MapView.Marker --- index.d.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/index.d.ts b/index.d.ts index 9a770c3fc..75e976ee1 100644 --- a/index.d.ts +++ b/index.d.ts @@ -85,6 +85,7 @@ declare namespace MapView { onDrag?: Function; onDragEnd?: Function; zIndex?: number; + style?: any; } interface MapPolylineProps { @@ -143,6 +144,7 @@ declare namespace MapView { interface MapCalloutProps { tooltip?: boolean; onPress?: Function; + style?: any; } export class Marker extends React.Component {} From 15ba9cbd6d4bf0d4abe3fdf00d23cd9cacb45a76 Mon Sep 17 00:00:00 2001 From: ashour Date: Tue, 28 Nov 2017 20:23:11 +0200 Subject: [PATCH 173/199] Added explicit instructions to copy `AirGoogleMaps` files (#1734) If the files are not copied during dragging the folder, your iOS project will fail to build --- docs/installation.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/installation.md b/docs/installation.md index ad9d4b383..acd1f4657 100644 --- a/docs/installation.md +++ b/docs/installation.md @@ -25,10 +25,10 @@ react-native link react-native-maps (If you do not need `GoogleMaps` support for iOS, then you can probably completely skip this step.) 1. Open your project in Xcode workspace 1. If you need `GoogleMaps` support also - - Drag this folder `node_modules/react-native-maps/lib/ios/AirGoogleMaps/` into your project, and choose `Create groups` in the popup window. + - Drag this folder `node_modules/react-native-maps/lib/ios/AirGoogleMaps/` into your project, and choose `Create groups` and `Copy items if needed` in the popup window. - In `AppDelegate.m`, add `@import GoogleMaps;` before `@implementation AppDelegate`. In `- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions`, add `[GMSServices provideAPIKey:@"YOUR_GOOGLE_MAP_API_KEY"];` - In your project's `Build Settings` > `Header Search Paths`, double click the value field. In the popup, add `$(SRCROOT)/../node_modules/react-native-maps/lib/ios/AirMaps` and change `non-recursive` to `recursive`. (Dragging the folder `node_modules/react-native-maps/lib/ios/AirMaps/` into your project introduces duplicate symbols. We should not do it.) - + Note: We recommend using a version of React Native >= .40. Newer versions (>= .40) require `package.json` to be set to `"react-native-maps": "^0.13.0"`, while older versions require `"react-native-maps": "^0.12.4"`. ### Option 2: CocoaPods @@ -195,7 +195,7 @@ You have to link dependencies with rnpm and re-run the build: - Extras / Google Play services - Extras / Google Repository - Android 6.0 (API 23) / Google APIs Intel x86 Atom System Image Rev. 19 - - Android SDK Build-tools 23.0.3 + - Android SDK Build-tools 23.0.3 1. Check manual installation steps if you didn't run "react-native link react-native-maps" 1. Go to [Google API Console](https://console.developers.google.com/flows/enableapi?apiid=maps_android_backend) and select your project, or create one. Then, once enabled, select `Go to credentials`. From 8ec93e4c4ecf8752b60cd43346959ebac1de82d2 Mon Sep 17 00:00:00 2001 From: Seivan Heidari Date: Tue, 28 Nov 2017 19:23:23 +0100 Subject: [PATCH 174/199] Update CHANGELOG.md (#1720) Ignore this if the changelog is generated from commits or something. --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5678d8052..f61819749 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,7 +5,7 @@ * iOS/Android: [#1544](https://github.com/airbnb/react-native-maps/pull/1544) Adds support to animateToBearing and animateToViewingAngle ( IOS + Android ) * JS: [#1503](https://github.com/airbnb/react-native-maps/pull/1503) Remove caret from "react": "^16.0.0-alpha.12 * Android: [#1521](https://github.com/airbnb/react-native-maps/pull/1521) Fix rare android crashes when map size is 0 -* Common: [#1610](https://github.com/airbnb/react-native-maps/pull/1610) Added Typescript Definitions +* Common: [#1601](https://github.com/airbnb/react-native-maps/pull/1610) Added Typescript Definitions * Android: [#1612](https://github.com/airbnb/react-native-maps/pull/1612) Remove legalNotice from android AirMapModule ## 0.16.4 (September 13, 2017) From e4ecbd3ecee89836431cc0e8e13bf7742709b6b7 Mon Sep 17 00:00:00 2001 From: "A.T" Date: Tue, 28 Nov 2017 19:23:47 +0100 Subject: [PATCH 175/199] Fixed Podfile (#1718) --- .../AirMapsExplorer.xcodeproj/project.pbxproj | 8 +++++++- example/ios/Podfile | 4 ---- example/ios/Podfile.lock | 20 +++++++++---------- 3 files changed, 17 insertions(+), 15 deletions(-) diff --git a/example/ios/AirMapsExplorer.xcodeproj/project.pbxproj b/example/ios/AirMapsExplorer.xcodeproj/project.pbxproj index efeabceb4..21d588c64 100644 --- a/example/ios/AirMapsExplorer.xcodeproj/project.pbxproj +++ b/example/ios/AirMapsExplorer.xcodeproj/project.pbxproj @@ -289,9 +289,12 @@ files = ( ); inputPaths = ( + "${SRCROOT}/Pods/Target Support Files/Pods-AirMapsExplorer/Pods-AirMapsExplorer-resources.sh", + "${PODS_ROOT}/GoogleMaps/Maps/Frameworks/GoogleMaps.framework/Versions/A/Resources/GoogleMaps.bundle", ); name = "[CP] Copy Pods Resources"; outputPaths = ( + "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; @@ -304,13 +307,16 @@ files = ( ); inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", ); name = "[CP] Check Pods Manifest.lock"; outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-AirMapsExplorer-checkManifestLockResult.txt", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n"; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; showEnvVarsInLog = 0; }; /* End PBXShellScriptBuildPhase section */ diff --git a/example/ios/Podfile b/example/ios/Podfile index 37326fb7d..aeefe611a 100644 --- a/example/ios/Podfile +++ b/example/ios/Podfile @@ -35,9 +35,5 @@ post_install do |installer| config.build_settings['CLANG_ENABLE_MODULES'] = 'No' end end - - if target.name == "React" - target.remove_from_project - end end end diff --git a/example/ios/Podfile.lock b/example/ios/Podfile.lock index 3eec18fee..6fc414fe3 100644 --- a/example/ios/Podfile.lock +++ b/example/ios/Podfile.lock @@ -6,10 +6,10 @@ PODS: - GoogleMaps/Base - React (0.45.1): - React/Core (= 0.45.1) - - react-native-google-maps (0.15.2): + - react-native-google-maps (0.17.0): - GoogleMaps (= 2.1.1) - React - - react-native-maps (0.15.2): + - react-native-maps (0.17.0): - React - React/BatchedBridge (0.45.1): - React/Core @@ -62,21 +62,21 @@ DEPENDENCIES: EXTERNAL SOURCES: React: - :path: "../../node_modules/react-native" + :path: ../../node_modules/react-native react-native-google-maps: - :path: "../../" + :path: ../../ react-native-maps: - :path: "../../" + :path: ../../ Yoga: - :path: "../../node_modules/react-native/ReactCommon/yoga/Yoga.podspec" + :path: ../../node_modules/react-native/ReactCommon/yoga/Yoga.podspec SPEC CHECKSUMS: GoogleMaps: a5b5bbe47734e2443bde781a6aa64e69fdb6d785 React: 0c9191a8b0c843d7004f950ac6b5f6cba9d125c7 - react-native-google-maps: d0b8772eb76e1615ea32c73bc9d573360b8c0817 - react-native-maps: fe2e4680b4d3fcfd84d636ccedd470fe358d55e1 + react-native-google-maps: 73a7f74a00d36c74df41388ebb8394ceba81ef0e + react-native-maps: ee0bb36520eb49dfc2bf11754a486a4fa5c5f883 Yoga: 89c8738d42a0b46a113acb4e574336d61cba2985 -PODFILE CHECKSUM: 8b3eb68ef6553bf1fcb8a467e0e63000b37ec692 +PODFILE CHECKSUM: c069397afd4c9ecf6886b7c00e7d7264dced43a4 -COCOAPODS: 1.2.0 +COCOAPODS: 1.3.1 From ae228ae09442ccb7fa7bfcaf035b7f82cd4eac4a Mon Sep 17 00:00:00 2001 From: Hein Rutjes Date: Tue, 28 Nov 2017 19:28:39 +0100 Subject: [PATCH 176/199] Added support for new Android camera movement APIs (#1710) `OnCameraChangeListener` is deprecated and should no longer be used. This PR adds support for new more powerful APIs and removes the old hacky region detection code. This fixes various issues and paves the way for distinguishing between gestures and manual/programatic animations the same time. https://developers.google.com/android/reference/com/google/android/gms/maps/GoogleMap.OnCameraChangeListener --- .../airbnb/android/react/maps/AirMapView.java | 104 +++++------------- .../android/react/maps/RegionChangeEvent.java | 5 +- 2 files changed, 28 insertions(+), 81 deletions(-) diff --git a/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapView.java b/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapView.java index 836fe0e35..fa2f63646 100644 --- a/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapView.java +++ b/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapView.java @@ -13,7 +13,6 @@ import android.support.v4.view.MotionEventCompat; import android.view.GestureDetector; import android.view.MotionEvent; -import android.view.ScaleGestureDetector; import android.view.View; import android.view.ViewGroup; import android.widget.ImageView; @@ -65,12 +64,12 @@ public class AirMapView extends MapView implements GoogleMap.InfoWindowAdapter, private LatLngBounds boundsToMove; private boolean showUserLocation = false; - private boolean isMonitoringRegion = false; - private boolean isTouchDown = false; private boolean handlePanDrag = false; private boolean moveOnMarkerPress = true; private boolean cacheEnabled = false; private boolean initialRegionSet = false; + private LatLngBounds cameraLastIdleBounds; + private int cameraMoveReason = 0; private static final String[] PERMISSIONS = new String[]{ "android.permission.ACCESS_FINE_LOCATION", "android.permission.ACCESS_COARSE_LOCATION"}; @@ -79,7 +78,6 @@ public class AirMapView extends MapView implements GoogleMap.InfoWindowAdapter, private final Map markerMap = new HashMap<>(); private final Map polylineMap = new HashMap<>(); private final Map polygonMap = new HashMap<>(); - private final ScaleGestureDetector scaleDetector; private final GestureDetectorCompat gestureDetector; private final AirMapManager manager; private LifecycleEventListener lifecycleListener; @@ -133,23 +131,9 @@ public AirMapView(ThemedReactContext reactContext, ReactApplicationContext appCo super.getMapAsync(this); final AirMapView view = this; - scaleDetector = - new ScaleGestureDetector(reactContext, - new ScaleGestureDetector.SimpleOnScaleGestureListener() { - @Override - public boolean onScaleBegin(ScaleGestureDetector detector) { - view.startMonitoringRegion(); - return true; // stop recording this gesture. let mapview handle it. - } - }); gestureDetector = new GestureDetectorCompat(reactContext, new GestureDetector.SimpleOnGestureListener() { - @Override - public boolean onDoubleTap(MotionEvent e) { - view.startMonitoringRegion(); - return false; - } @Override public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, @@ -157,7 +141,6 @@ public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, if (handlePanDrag) { onPanDrag(e2); } - view.startMonitoringRegion(); return false; } }); @@ -272,14 +255,32 @@ public void onMapLongClick(LatLng point) { } }); - map.setOnCameraChangeListener(new GoogleMap.OnCameraChangeListener() { + map.setOnCameraMoveStartedListener(new GoogleMap.OnCameraMoveStartedListener() { + @Override + public void onCameraMoveStarted(int reason) { + cameraMoveReason = reason; + } + }); + + map.setOnCameraMoveListener(new GoogleMap.OnCameraMoveListener() { @Override - public void onCameraChange(CameraPosition position) { + public void onCameraMove() { LatLngBounds bounds = map.getProjection().getVisibleRegion().latLngBounds; - LatLng center = position.target; - lastBoundsEmitted = bounds; - eventDispatcher.dispatchEvent(new RegionChangeEvent(getId(), bounds, center, isTouchDown)); - view.stopMonitoringRegion(); + cameraLastIdleBounds = null; + eventDispatcher.dispatchEvent(new RegionChangeEvent(getId(), bounds, true)); + } + }); + + map.setOnCameraIdleListener(new GoogleMap.OnCameraIdleListener() { + @Override + public void onCameraIdle() { + LatLngBounds bounds = map.getProjection().getVisibleRegion().latLngBounds; + if ((cameraMoveReason != 0) && + ((cameraLastIdleBounds == null) || + LatLngBoundsUtils.BoundsAreDifferent(bounds, cameraLastIdleBounds))) { + cameraLastIdleBounds = bounds; + eventDispatcher.dispatchEvent(new RegionChangeEvent(getId(), bounds, false)); + } } }); @@ -566,14 +567,12 @@ public void updateExtraData(Object extraData) { public void animateToRegion(LatLngBounds bounds, int duration) { if (map != null) { - startMonitoringRegion(); map.animateCamera(CameraUpdateFactory.newLatLngBounds(bounds, 0), duration, null); } } public void animateToViewingAngle(float angle, int duration) { if (map != null) { - startMonitoringRegion(); CameraPosition cameraPosition = new CameraPosition.Builder(map.getCameraPosition()) .tilt(angle) .build(); @@ -583,7 +582,6 @@ public void animateToViewingAngle(float angle, int duration) { public void animateToBearing(float bearing, int duration) { if (map != null) { - startMonitoringRegion(); CameraPosition cameraPosition = new CameraPosition.Builder(map.getCameraPosition()) .bearing(bearing) .build(); @@ -593,7 +591,6 @@ public void animateToBearing(float bearing, int duration) { public void animateToCoordinate(LatLng coordinate, int duration) { if (map != null) { - startMonitoringRegion(); map.animateCamera(CameraUpdateFactory.newLatLng(coordinate), duration, null); } } @@ -615,7 +612,6 @@ public void fitToElements(boolean animated) { LatLngBounds bounds = builder.build(); CameraUpdate cu = CameraUpdateFactory.newLatLngBounds(bounds, baseMapPadding); if (animated) { - startMonitoringRegion(); map.animateCamera(cu); } else { map.moveCamera(cu); @@ -650,7 +646,6 @@ public void fitToSuppliedMarkers(ReadableArray markerIDsArray, boolean animated) LatLngBounds bounds = builder.build(); CameraUpdate cu = CameraUpdateFactory.newLatLngBounds(bounds, baseMapPadding); if (animated) { - startMonitoringRegion(); map.animateCamera(cu); } else { map.moveCamera(cu); @@ -678,7 +673,6 @@ public void fitToCoordinates(ReadableArray coordinatesArray, ReadableMap edgePad } if (animated) { - startMonitoringRegion(); map.animateCamera(cu); } else { map.moveCamera(cu); @@ -703,7 +697,6 @@ public View getInfoContents(Marker marker) { @Override public boolean dispatchTouchEvent(MotionEvent ev) { - scaleDetector.onTouchEvent(ev); gestureDetector.onTouchEvent(ev); int action = MotionEventCompat.getActionMasked(ev); @@ -712,61 +705,16 @@ public boolean dispatchTouchEvent(MotionEvent ev) { case (MotionEvent.ACTION_DOWN): this.getParent().requestDisallowInterceptTouchEvent( map != null && map.getUiSettings().isScrollGesturesEnabled()); - isTouchDown = true; - break; - case (MotionEvent.ACTION_MOVE): - startMonitoringRegion(); break; case (MotionEvent.ACTION_UP): // Clear this regardless, since isScrollGesturesEnabled() may have been updated this.getParent().requestDisallowInterceptTouchEvent(false); - isTouchDown = false; break; } super.dispatchTouchEvent(ev); return true; } - // Timer Implementation - - public void startMonitoringRegion() { - if (map == null || isMonitoringRegion) return; - timerHandler.postDelayed(timerRunnable, 100); - isMonitoringRegion = true; - } - - public void stopMonitoringRegion() { - if (map == null || !isMonitoringRegion) return; - timerHandler.removeCallbacks(timerRunnable); - isMonitoringRegion = false; - } - - private LatLngBounds lastBoundsEmitted; - - Handler timerHandler = new Handler(); - Runnable timerRunnable = new Runnable() { - - @Override - public void run() { - - if (map != null) { - Projection projection = map.getProjection(); - VisibleRegion region = (projection != null) ? projection.getVisibleRegion() : null; - LatLngBounds bounds = (region != null) ? region.latLngBounds : null; - - if ((bounds != null) && - (lastBoundsEmitted == null || - LatLngBoundsUtils.BoundsAreDifferent(bounds, lastBoundsEmitted))) { - LatLng center = map.getCameraPosition().target; - lastBoundsEmitted = bounds; - eventDispatcher.dispatchEvent(new RegionChangeEvent(getId(), bounds, center, true)); - } - } - - timerHandler.postDelayed(this, 100); - } - }; - @Override public void onMarkerDragStart(Marker marker) { WritableMap event = makeClickEventData(marker.getPosition()); diff --git a/lib/android/src/main/java/com/airbnb/android/react/maps/RegionChangeEvent.java b/lib/android/src/main/java/com/airbnb/android/react/maps/RegionChangeEvent.java index 43b1f678e..675eb4106 100644 --- a/lib/android/src/main/java/com/airbnb/android/react/maps/RegionChangeEvent.java +++ b/lib/android/src/main/java/com/airbnb/android/react/maps/RegionChangeEvent.java @@ -9,13 +9,11 @@ public class RegionChangeEvent extends Event { private final LatLngBounds bounds; - private final LatLng center; private final boolean continuous; - public RegionChangeEvent(int id, LatLngBounds bounds, LatLng center, boolean continuous) { + public RegionChangeEvent(int id, LatLngBounds bounds, boolean continuous) { super(id); this.bounds = bounds; - this.center = center; this.continuous = continuous; } @@ -36,6 +34,7 @@ public void dispatch(RCTEventEmitter rctEventEmitter) { event.putBoolean("continuous", continuous); WritableMap region = new WritableNativeMap(); + LatLng center = bounds.getCenter(); region.putDouble("latitude", center.latitude); region.putDouble("longitude", center.longitude); region.putDouble("latitudeDelta", bounds.northeast.latitude - bounds.southwest.latitude); From 1713d1a7226a82b7eec0dc795f22457e249bf238 Mon Sep 17 00:00:00 2001 From: Nick McIntosh Date: Wed, 29 Nov 2017 05:34:06 +1100 Subject: [PATCH 177/199] Enable control of Google Maps Marker tracksViewChanges property. (#1705) Fixes issue #1031, enabling use of custom marker images and views in Google Maps on iOS and android. As detailed in the Google Maps Marker documentation (kudos to @hughvidos), map markers track view changes by default. This has meant however that custom marker images or views on iOS and android, when using Google Maps, cause high continuous CPU load. The recommended use of tracksViewChanges is to enable when the marker is being rendered or animated, then to disable it. An example of use of tracksViewChanges would be to set it to false once onMapReady has fired. This can be accomplished by toggling a state property (e.g. `initialized`), and passing it to the child map markers in their `tracksViewChanges` prop. Markers would then render correctly on map load; CPU use falls off once the tracking ceases. --- lib/components/MapMarker.js | 12 +++++++++++- lib/ios/AirGoogleMaps/AIRGoogleMapMarker.h | 1 + lib/ios/AirGoogleMaps/AIRGoogleMapMarker.m | 9 +++++++++ lib/ios/AirGoogleMaps/AIRGoogleMapMarkerManager.m | 1 + 4 files changed, 22 insertions(+), 1 deletion(-) diff --git a/lib/components/MapMarker.js b/lib/components/MapMarker.js index b81bab87a..ecacc0a43 100644 --- a/lib/components/MapMarker.js +++ b/lib/components/MapMarker.js @@ -165,6 +165,14 @@ const propTypes = { draggable: PropTypes.bool, + /** + * Sets whether this marker should track view changes true. + * + * @platform ios + */ + + tracksViewChanges: PropTypes.bool, + /** * Callback that is called when the user presses on the marker */ @@ -264,7 +272,9 @@ class MapMarker extends React.Component { return ( { this.marker = ref; }} + ref={ref => { + this.marker = ref; + }} {...this.props} image={image} style={[styles.marker, this.props.style]} diff --git a/lib/ios/AirGoogleMaps/AIRGoogleMapMarker.h b/lib/ios/AirGoogleMaps/AIRGoogleMapMarker.h index 298884f7d..1cb4d2659 100644 --- a/lib/ios/AirGoogleMaps/AIRGoogleMapMarker.h +++ b/lib/ios/AirGoogleMaps/AIRGoogleMapMarker.h @@ -31,6 +31,7 @@ @property (nonatomic, assign) NSInteger zIndex; @property (nonatomic, assign) double opacity; @property (nonatomic, assign) BOOL draggable; +@property (nonatomic, assign) BOOL tracksViewChanges; - (void)showCalloutView; - (void)hideCalloutView; diff --git a/lib/ios/AirGoogleMaps/AIRGoogleMapMarker.m b/lib/ios/AirGoogleMaps/AIRGoogleMapMarker.m index c41be55bb..42cf016a9 100644 --- a/lib/ios/AirGoogleMaps/AIRGoogleMapMarker.m +++ b/lib/ios/AirGoogleMaps/AIRGoogleMapMarker.m @@ -36,6 +36,7 @@ - (instancetype)init if ((self = [super init])) { _realMarker = [[AIRGMSMarker alloc] init]; _realMarker.fakeMarker = self; + _realMarker.tracksViewChanges = true; } return self; } @@ -295,4 +296,12 @@ - (BOOL)draggable { return _realMarker.draggable; } +- (void)setTracksViewChanges:(BOOL)tracksViewChanges { + _realMarker.tracksViewChanges = tracksViewChanges; +} + +- (BOOL)tracksViewChanges { + return _realMarker.tracksViewChanges; +} + @end diff --git a/lib/ios/AirGoogleMaps/AIRGoogleMapMarkerManager.m b/lib/ios/AirGoogleMaps/AIRGoogleMapMarkerManager.m index b5572bf9d..6b9c8f64b 100644 --- a/lib/ios/AirGoogleMaps/AIRGoogleMapMarkerManager.m +++ b/lib/ios/AirGoogleMaps/AIRGoogleMapMarkerManager.m @@ -37,6 +37,7 @@ - (UIView *)view RCT_EXPORT_VIEW_PROPERTY(anchor, CGPoint) RCT_EXPORT_VIEW_PROPERTY(zIndex, NSInteger) RCT_EXPORT_VIEW_PROPERTY(draggable, BOOL) +RCT_EXPORT_VIEW_PROPERTY(tracksViewChanges, BOOL) RCT_EXPORT_VIEW_PROPERTY(opacity, double) RCT_EXPORT_VIEW_PROPERTY(onDragStart, RCTDirectEventBlock) RCT_EXPORT_VIEW_PROPERTY(onDrag, RCTDirectEventBlock) From 9b6946ab66de989d908fec4a7dba213cb95e44d2 Mon Sep 17 00:00:00 2001 From: Hein Rutjes Date: Tue, 28 Nov 2017 19:42:41 +0100 Subject: [PATCH 178/199] Added new iOS `mutedStandard` map-type (#1824) * Added new iOS `mutedStandard` map-type * Update MapView.js --- docs/mapview.md | 2 +- index.d.ts | 2 +- lib/components/MapView.js | 1 + lib/ios/AirMaps/RCTConvert+AirMap.m | 3 +++ 4 files changed, 6 insertions(+), 2 deletions(-) diff --git a/docs/mapview.md b/docs/mapview.md index 2aa6a7086..6bd430839 100644 --- a/docs/mapview.md +++ b/docs/mapview.md @@ -8,7 +8,7 @@ | `region` | `Region` | | The region to be displayed by the map.

The region is defined by the center coordinates and the span of coordinates to display. | `initialRegion` | `Region` | | The initial region to be displayed by the map. Use this prop instead of `region` only if you don't want to control the viewport of the map besides the initial region.

Changing this prop after the component has mounted will not result in a region change.

This is similar to the `initialValue` prop of a text input. | `liteMode` | `Boolean` | `false` | Enable lite mode. **Note**: Android only. -| `mapType` | `String` | `"standard"` | The map type to be displayed.

- standard: standard road map (default)
- satellite: satellite view
- hybrid: satellite view with roads and points of interest overlayed
- terrain: (Android only) topographic view +| `mapType` | `String` | `"standard"` | The map type to be displayed.

- standard: standard road map (default)
- satellite: satellite view
- hybrid: satellite view with roads and points of interest overlayed
- terrain: (Android only) topographic view
- standardMuted: more subtle, makes markers/lines pop more (iOS only) | `customMapStyle` | `Array` | | Adds custom styling to the map component. See [README](https://github.com/airbnb/react-native-maps#customizing-the-map-style) for more information. | `showsUserLocation` | `Boolean` | `false` | If `true` the app will ask for the user's location. **NOTE**: You need to add `NSLocationWhenInUseUsageDescription` key in Info.plist to enable geolocation, otherwise it is going to *fail silently*! | `userLocationAnnotationTitle` | `String` | | The title of the annotation for current user location. This only works if `showsUserLocation` is true. There is a default value `My Location` set by MapView. **Note**: iOS only. diff --git a/index.d.ts b/index.d.ts index 75e976ee1..bdc2075e4 100644 --- a/index.d.ts +++ b/index.d.ts @@ -26,7 +26,7 @@ interface MapViewProps { showsTraffic?: boolean; showsIndoors?: boolean; showsIndoorLevelPicker?: boolean; - mapType?: 'standard' | 'satellite' | 'hybrid' | 'terrain' | 'none'; + mapType?: 'standard' | 'satellite' | 'hybrid' | 'terrain' | 'none' | 'mutedStandard'; region?: { latitude: number; longitude: number; latitudeDelta: number; longitudeDelta: number; }; initialRegion?: { latitude: number; longitude: number; latitudeDelta: number; longitudeDelta: number; }; liteMode?: boolean; diff --git a/lib/components/MapView.js b/lib/components/MapView.js index eec576291..63eba2cc9 100644 --- a/lib/components/MapView.js +++ b/lib/components/MapView.js @@ -32,6 +32,7 @@ const MAP_TYPES = { HYBRID: 'hybrid', TERRAIN: 'terrain', NONE: 'none', + MUTEDSTANDARD: 'mutedStandard', }; const GOOGLE_MAPS_ONLY_TYPES = [ diff --git a/lib/ios/AirMaps/RCTConvert+AirMap.m b/lib/ios/AirMaps/RCTConvert+AirMap.m index cfdbb17ce..42c916193 100644 --- a/lib/ios/AirMaps/RCTConvert+AirMap.m +++ b/lib/ios/AirMaps/RCTConvert+AirMap.m @@ -31,6 +31,9 @@ + (MKCoordinateRegion)MKCoordinateRegion:(id)json @"standard": @(MKMapTypeStandard), @"satellite": @(MKMapTypeSatellite), @"hybrid": @(MKMapTypeHybrid), + @"satelliteFlyover": @(MKMapTypeSatelliteFlyover), + @"hybridFlyover": @(MKMapTypeHybridFlyover), + @"mutedStandard": @(MKMapTypeMutedStandard) }), MKMapTypeStandard, integerValue) // NOTE(lmr): From 07994f0a4c604247147ca40067bc06c27d4cc74e Mon Sep 17 00:00:00 2001 From: brunsy Date: Wed, 29 Nov 2017 07:46:11 +1300 Subject: [PATCH 179/199] added missing parameters to google map screenshot (#1774) --- lib/ios/AirGoogleMaps/AIRGoogleMapManager.m | 63 +++++++++++++++------ 1 file changed, 47 insertions(+), 16 deletions(-) diff --git a/lib/ios/AirGoogleMaps/AIRGoogleMapManager.m b/lib/ios/AirGoogleMaps/AIRGoogleMapManager.m index 043841305..8358bb188 100644 --- a/lib/ios/AirGoogleMaps/AIRGoogleMapManager.m +++ b/lib/ios/AirGoogleMaps/AIRGoogleMapManager.m @@ -231,34 +231,65 @@ - (UIView *)view withWidth:(nonnull NSNumber *)width withHeight:(nonnull NSNumber *)height withRegion:(MKCoordinateRegion)region + format:(nonnull NSString *)format + quality:(nonnull NSNumber *)quality + result:(nonnull NSString *)result withCallback:(RCTResponseSenderBlock)callback) { + NSTimeInterval timeStamp = [[NSDate date] timeIntervalSince1970]; + NSString *pathComponent = [NSString stringWithFormat:@"Documents/snapshot-%.20lf.%@", timeStamp, format]; + NSString *filePath = [NSHomeDirectory() stringByAppendingPathComponent: pathComponent]; + [self.bridge.uiManager addUIBlock:^(__unused RCTUIManager *uiManager, NSDictionary *viewRegistry) { id view = viewRegistry[reactTag]; if (![view isKindOfClass:[AIRGoogleMap class]]) { - RCTLogError(@"Invalid view returned from registry, expecting AIRMap, got: %@", view); + RCTLogError(@"Invalid view returned from registry, expecting AIRMap, got: %@", view); } else { AIRGoogleMap *mapView = (AIRGoogleMap *)view; - + // TODO: currently we are ignoring width, height, region - + UIGraphicsBeginImageContextWithOptions(mapView.frame.size, YES, 0.0f); [mapView.layer renderInContext:UIGraphicsGetCurrentContext()]; UIImage *image = UIGraphicsGetImageFromCurrentImageContext(); - UIGraphicsEndImageContext(); - - NSTimeInterval timeStamp = [[NSDate date] timeIntervalSince1970]; - NSString *pathComponent = [NSString stringWithFormat:@"Documents/snapshot-%.20lf.png", timeStamp]; - NSString *filePath = [NSHomeDirectory() stringByAppendingPathComponent: pathComponent]; - - NSData *data = UIImagePNGRepresentation(image); - [data writeToFile:filePath atomically:YES]; - NSDictionary *snapshotData = @{ - @"uri": filePath, - @"data": [data base64EncodedStringWithOptions:NSDataBase64EncodingEndLineWithCarriageReturn] - }; - callback(@[[NSNull null], snapshotData]); + + NSData *data; + if ([format isEqualToString:@"png"]) { + data = UIImagePNGRepresentation(image); + + } + else if([format isEqualToString:@"jpg"]) { + data = UIImageJPEGRepresentation(image, quality.floatValue); + } + + if ([result isEqualToString:@"file"]) { + [data writeToFile:filePath atomically:YES]; + callback(@[[NSNull null], filePath]); + } + else if ([result isEqualToString:@"base64"]) { + callback(@[[NSNull null], [data base64EncodedStringWithOptions:NSDataBase64EncodingEndLineWithCarriageReturn]]); + } + else if ([result isEqualToString:@"legacy"]) { + + // In the initial (iOS only) implementation of takeSnapshot, + // both the uri and the base64 encoded string were returned. + // Returning both is rarely useful and in fact causes a + // performance penalty when only the file URI is desired. + // In that case the base64 encoded string was always marshalled + // over the JS-bridge (which is quite slow). + // A new more flexible API was created to cover this. + // This code should be removed in a future release when the + // old API is fully deprecated. + [data writeToFile:filePath atomically:YES]; + NSDictionary *snapshotData = @{ + @"uri": filePath, + @"data": [data base64EncodedStringWithOptions:NSDataBase64EncodingEndLineWithCarriageReturn] + }; + callback(@[[NSNull null], snapshotData]); + } + } + UIGraphicsEndImageContext(); }]; } From 94be5dcdb29a15528b9d2d5b8e6187bb83a467b5 Mon Sep 17 00:00:00 2001 From: Mark Rickert Date: Tue, 28 Nov 2017 12:32:27 -0700 Subject: [PATCH 180/199] Fixes issue running on ReactNative 0.42.3 - 'MapMarker' has no propType for native prop 'AIRMapMarker.testId' of native type 'String' (#1792) * Be less specific about react-native version for android * Relax play services dependencies as well * Fixes issue with ReactNative 0.42.3 * Update MapMarker.js * Make all components use ViewPropTypes || View.propTypes --- lib/components/MapCallout.js | 6 +++++- lib/components/MapCircle.js | 6 +++++- lib/components/MapMarker.js | 6 +++++- lib/components/MapPolygon.js | 6 +++++- lib/components/MapPolyline.js | 6 +++++- lib/components/MapUrlTile.js | 6 +++++- lib/components/MapView.js | 2 +- 7 files changed, 31 insertions(+), 7 deletions(-) diff --git a/lib/components/MapCallout.js b/lib/components/MapCallout.js index 226b52fe2..2ef73a096 100644 --- a/lib/components/MapCallout.js +++ b/lib/components/MapCallout.js @@ -3,14 +3,18 @@ import React from 'react'; import { StyleSheet, ViewPropTypes, + View, } from 'react-native'; import decorateMapComponent, { SUPPORTED, USES_DEFAULT_IMPLEMENTATION, } from './decorateMapComponent'; +// if ViewPropTypes is not defined fall back to View.propType (to support RN < 0.44) +const viewPropTypes = ViewPropTypes || View.propTypes; + const propTypes = { - ...ViewPropTypes, + ...viewPropTypes, tooltip: PropTypes.bool, onPress: PropTypes.func, }; diff --git a/lib/components/MapCircle.js b/lib/components/MapCircle.js index acf066b24..c0c23a5ad 100644 --- a/lib/components/MapCircle.js +++ b/lib/components/MapCircle.js @@ -2,14 +2,18 @@ import PropTypes from 'prop-types'; import React from 'react'; import { ViewPropTypes, + View, } from 'react-native'; import decorateMapComponent, { USES_DEFAULT_IMPLEMENTATION, SUPPORTED, } from './decorateMapComponent'; +// if ViewPropTypes is not defined fall back to View.propType (to support RN < 0.44) +const viewPropTypes = ViewPropTypes || View.propTypes; + const propTypes = { - ...ViewPropTypes, + ...viewPropTypes, /** * The coordinate of the center of the circle diff --git a/lib/components/MapMarker.js b/lib/components/MapMarker.js index ecacc0a43..a2f809f58 100644 --- a/lib/components/MapMarker.js +++ b/lib/components/MapMarker.js @@ -7,6 +7,7 @@ import { Animated, findNodeHandle, ViewPropTypes, + View, } from 'react-native'; import resolveAssetSource from 'react-native/Libraries/Image/resolveAssetSource'; @@ -22,8 +23,11 @@ const viewConfig = { }, }; +// if ViewPropTypes is not defined fall back to View.propType (to support RN < 0.44) +const viewPropTypes = ViewPropTypes || View.propTypes; + const propTypes = { - ...ViewPropTypes, + ...viewPropTypes, // TODO(lmr): get rid of these? identifier: PropTypes.string, diff --git a/lib/components/MapPolygon.js b/lib/components/MapPolygon.js index 27f2aa322..c6daeae86 100644 --- a/lib/components/MapPolygon.js +++ b/lib/components/MapPolygon.js @@ -2,14 +2,18 @@ import PropTypes from 'prop-types'; import React from 'react'; import { ViewPropTypes, + View, } from 'react-native'; import decorateMapComponent, { USES_DEFAULT_IMPLEMENTATION, SUPPORTED, } from './decorateMapComponent'; +// if ViewPropTypes is not defined fall back to View.propType (to support RN < 0.44) +const viewPropTypes = ViewPropTypes || View.propTypes; + const propTypes = { - ...ViewPropTypes, + ...viewPropTypes, /** * An array of coordinates to describe the polygon diff --git a/lib/components/MapPolyline.js b/lib/components/MapPolyline.js index af1573eff..2bdfe8d26 100644 --- a/lib/components/MapPolyline.js +++ b/lib/components/MapPolyline.js @@ -2,14 +2,18 @@ import PropTypes from 'prop-types'; import React from 'react'; import { ViewPropTypes, + View, } from 'react-native'; import decorateMapComponent, { USES_DEFAULT_IMPLEMENTATION, SUPPORTED, } from './decorateMapComponent'; +// if ViewPropTypes is not defined fall back to View.propType (to support RN < 0.44) +const viewPropTypes = ViewPropTypes || View.propTypes; + const propTypes = { - ...ViewPropTypes, + ...viewPropTypes, /** * An array of coordinates to describe the polygon diff --git a/lib/components/MapUrlTile.js b/lib/components/MapUrlTile.js index f61c1e0d3..a2b49e960 100644 --- a/lib/components/MapUrlTile.js +++ b/lib/components/MapUrlTile.js @@ -3,6 +3,7 @@ import React from 'react'; import { ViewPropTypes, + View, } from 'react-native'; import decorateMapComponent, { @@ -10,8 +11,11 @@ import decorateMapComponent, { SUPPORTED, } from './decorateMapComponent'; +// if ViewPropTypes is not defined fall back to View.propType (to support RN < 0.44) +const viewPropTypes = ViewPropTypes || View.propTypes; + const propTypes = { - ...ViewPropTypes, + ...viewPropTypes, /** * The url template of the tile server. The patterns {x} {y} {z} will be replaced at runtime diff --git a/lib/components/MapView.js b/lib/components/MapView.js index 63eba2cc9..611701ca1 100644 --- a/lib/components/MapView.js +++ b/lib/components/MapView.js @@ -8,8 +8,8 @@ import { NativeModules, ColorPropType, findNodeHandle, - View, ViewPropTypes, + View, } from 'react-native'; import MapMarker from './MapMarker'; import MapPolyline from './MapPolyline'; From bf40f069f11a1b173a8de44c85fc7808026c8fa2 Mon Sep 17 00:00:00 2001 From: Peter Juras Date: Tue, 28 Nov 2017 21:36:04 +0100 Subject: [PATCH 181/199] Add mapPadding property (#1750) * Add mapPadding property * Fix trailing whitespace in MapView comments --- .../android/react/maps/AirMapManager.java | 29 +++++++++++++++++++ lib/components/MapView.js | 9 ++++++ lib/ios/AirGoogleMaps/AIRGoogleMap.h | 1 + lib/ios/AirGoogleMaps/AIRGoogleMap.m | 7 +++++ lib/ios/AirGoogleMaps/AIRGoogleMapManager.m | 1 + 5 files changed, 47 insertions(+) diff --git a/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapManager.java b/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapManager.java index 6749e9a85..91413f84c 100644 --- a/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapManager.java +++ b/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapManager.java @@ -93,6 +93,35 @@ public void setMapStyle(AirMapView view, @Nullable String customMapStyleString) view.map.setMapStyle(new MapStyleOptions(customMapStyleString)); } + @ReactProp(name = "mapPadding") + public void setMapPadding(AirMapView view, @Nullable ReadableMap padding) { + int left = 0; + int top = 0; + int right = 0; + int bottom = 0; + double density = (double) view.getResources().getDisplayMetrics().density; + + if (padding != null) { + if (padding.hasKey("left")) { + left = (int) (padding.getDouble("left") * density); + } + + if (padding.hasKey("top")) { + top = (int) (padding.getDouble("top") * density); + } + + if (padding.hasKey("right")) { + right = (int) (padding.getDouble("right") * density); + } + + if (padding.hasKey("bottom")) { + bottom = (int) (padding.getDouble("bottom") * density); + } + } + + view.map.setPadding(left, top, right, bottom); + } + @ReactProp(name = "showsUserLocation", defaultBoolean = false) public void setShowsUserLocation(AirMapView view, boolean showUserLocation) { view.setShowsUserLocation(showUserLocation); diff --git a/lib/components/MapView.js b/lib/components/MapView.js index 611701ca1..9ebf171a7 100644 --- a/lib/components/MapView.js +++ b/lib/components/MapView.js @@ -303,6 +303,15 @@ const propTypes = { */ liteMode: PropTypes.bool, + /** + * (Google Maps only) + * + * Padding that is used by the Google Map View to position + * the camera, legal labels and buttons + * + */ + mapPadding: EdgeInsetsPropType, + /** * Maximum size of area that can be displayed. * diff --git a/lib/ios/AirGoogleMaps/AIRGoogleMap.h b/lib/ios/AirGoogleMaps/AIRGoogleMap.h index fa0293ae3..29f71a3a4 100644 --- a/lib/ios/AirGoogleMaps/AIRGoogleMap.h +++ b/lib/ios/AirGoogleMaps/AIRGoogleMap.h @@ -18,6 +18,7 @@ @property (nonatomic, assign) MKCoordinateRegion initialRegion; @property (nonatomic, assign) MKCoordinateRegion region; @property (nonatomic, assign) NSString *customMapStyleString; +@property (nonatomic, assign) UIEdgeInsets mapPadding; @property (nonatomic, copy) RCTBubblingEventBlock onMapReady; @property (nonatomic, copy) RCTBubblingEventBlock onPress; @property (nonatomic, copy) RCTBubblingEventBlock onLongPress; diff --git a/lib/ios/AirGoogleMaps/AIRGoogleMap.m b/lib/ios/AirGoogleMaps/AIRGoogleMap.m index 4c1976fe7..c7c57663e 100644 --- a/lib/ios/AirGoogleMaps/AIRGoogleMap.m +++ b/lib/ios/AirGoogleMaps/AIRGoogleMap.m @@ -219,6 +219,13 @@ - (void)idleAtCameraPosition:(GMSCameraPosition *)position { if (self.onChange) self.onChange(event); // complete } +- (void)setMapPadding:(UIEdgeInsets)mapPadding { + self.padding = mapPadding; +} + +- (UIEdgeInsets)mapPadding { + return self.padding; +} - (void)setScrollEnabled:(BOOL)scrollEnabled { self.settings.scrollGestures = scrollEnabled; diff --git a/lib/ios/AirGoogleMaps/AIRGoogleMapManager.m b/lib/ios/AirGoogleMaps/AIRGoogleMapManager.m index 8358bb188..99e16d77c 100644 --- a/lib/ios/AirGoogleMaps/AIRGoogleMapManager.m +++ b/lib/ios/AirGoogleMaps/AIRGoogleMapManager.m @@ -63,6 +63,7 @@ - (UIView *)view RCT_EXPORT_VIEW_PROPERTY(showsMyLocationButton, BOOL) RCT_EXPORT_VIEW_PROPERTY(showsIndoorLevelPicker, BOOL) RCT_EXPORT_VIEW_PROPERTY(customMapStyleString, NSString) +RCT_EXPORT_VIEW_PROPERTY(mapPadding, UIEdgeInsets) RCT_EXPORT_VIEW_PROPERTY(onMapReady, RCTBubblingEventBlock) RCT_EXPORT_VIEW_PROPERTY(onPress, RCTBubblingEventBlock) RCT_EXPORT_VIEW_PROPERTY(onLongPress, RCTBubblingEventBlock) From d23dd6131cadbbec531eb67a03389da679814995 Mon Sep 17 00:00:00 2001 From: Andre Shonubi Date: Tue, 28 Nov 2017 15:38:25 -0500 Subject: [PATCH 182/199] Add support to set map boundaries (#1587) * Add setMapBoundaries method iOS * Add setMapBoundaries method android * Add setMapBoundaries method to MapView component * Update MapView docs * Add note to setMapBoundaries method --- docs/mapview.md | 1 + .../android/react/maps/AirMapManager.java | 14 +++++++++++--- .../airbnb/android/react/maps/AirMapView.java | 18 ++++++++++++++++++ lib/components/MapView.js | 4 ++++ lib/ios/AirGoogleMaps/AIRGoogleMapManager.m | 18 ++++++++++++++++++ 5 files changed, 52 insertions(+), 3 deletions(-) diff --git a/docs/mapview.md b/docs/mapview.md index 6bd430839..86ddbff0f 100644 --- a/docs/mapview.md +++ b/docs/mapview.md @@ -66,6 +66,7 @@ To access event data, you will need to use `e.nativeEvent`. For example, `onPres | `animateToCoordinate` | `coordinate: LatLng`, `duration: Number` | | `animateToBearing` | `bearing: Number`, `duration: Number` | | `animateToViewingAngle` | `angle: Number`, `duration: Number` | +| `setMapBoundaries` | `northEast: LatLng`, `southWest: LatLng` | `GoogleMaps only` | `fitToElements` | `animated: Boolean` | | `fitToSuppliedMarkers` | `markerIDs: String[]`, `animated: Boolean` | If you need to use this in `ComponentDidMount`, make sure you put it in a timeout or it will cause performance problems. | `fitToCoordinates` | `coordinates: Array, options: { edgePadding: EdgePadding, animated: Boolean }` | If called in `ComponentDidMount` in android, it will cause an exception. It is recommended to call it from the MapView `onLayout` event. diff --git a/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapManager.java b/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapManager.java index 91413f84c..9022b1efc 100644 --- a/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapManager.java +++ b/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapManager.java @@ -34,6 +34,8 @@ public class AirMapManager extends ViewGroupManager { private static final int FIT_TO_ELEMENTS = 5; private static final int FIT_TO_SUPPLIED_MARKERS = 6; private static final int FIT_TO_COORDINATES = 7; + private static final int SET_MAP_BOUNDARIES = 8; + private final Map MAP_TYPES = MapBuilder.of( "standard", GoogleMap.MAP_TYPE_NORMAL, @@ -263,13 +265,13 @@ public void receiveCommand(AirMapView view, int commandId, @Nullable ReadableArr duration = args.getInt(1); view.animateToViewingAngle(angle, duration); break; - + case ANIMATE_TO_BEARING: bearing = (float)args.getDouble(0); duration = args.getInt(1); view.animateToBearing(bearing, duration); break; - + case FIT_TO_ELEMENTS: view.fitToElements(args.getBoolean(0)); break; @@ -277,9 +279,14 @@ public void receiveCommand(AirMapView view, int commandId, @Nullable ReadableArr case FIT_TO_SUPPLIED_MARKERS: view.fitToSuppliedMarkers(args.getArray(0), args.getBoolean(1)); break; + case FIT_TO_COORDINATES: view.fitToCoordinates(args.getArray(0), args.getMap(1), args.getBoolean(2)); break; + + case SET_MAP_BOUNDARIES: + view.setMapBoundaries(args.getMap(0), args.getMap(1)); + break; } } @@ -316,7 +323,8 @@ public Map getCommandsMap() { "animateToBearing", ANIMATE_TO_BEARING, "fitToElements", FIT_TO_ELEMENTS, "fitToSuppliedMarkers", FIT_TO_SUPPLIED_MARKERS, - "fitToCoordinates", FIT_TO_COORDINATES + "fitToCoordinates", FIT_TO_COORDINATES, + "setMapBoundaries", SET_MAP_BOUNDARIES ); } diff --git a/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapView.java b/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapView.java index fa2f63646..aece720a8 100644 --- a/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapView.java +++ b/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapView.java @@ -681,6 +681,24 @@ public void fitToCoordinates(ReadableArray coordinatesArray, ReadableMap edgePad 0); // Without this, the Google logo is moved up by the value of edgePadding.bottom } + public void setMapBoundaries(ReadableMap northEast, ReadableMap southWest) { + LatLngBounds.Builder builder = new LatLngBounds.Builder(); + + Double latNE = northEast.getDouble("latitude"); + Double lngNE = northEast.getDouble("longitude"); + builder.include(new LatLng(latNE, lngNE)); + + Double latSW = southWest.getDouble("latitude"); + Double lngSW = southWest.getDouble("longitude"); + builder.include(new LatLng(latSW, lngSW)); + + LatLngBounds bounds = builder.build(); + + if (map != null) { + map.setLatLngBoundsForCameraTarget(bounds); + } + } + // InfoWindowAdapter interface @Override diff --git a/lib/components/MapView.js b/lib/components/MapView.js index 9ebf171a7..74742e018 100644 --- a/lib/components/MapView.js +++ b/lib/components/MapView.js @@ -541,6 +541,10 @@ class MapView extends React.Component { this._runCommand('fitToCoordinates', [coordinates, edgePadding, animated]); } + setMapBoundaries(northEast, southWest) { + this._runCommand('setMapBoundaries', [northEast, southWest]); + } + /** * Takes a snapshot of the map and saves it to a picture * file or returns the image as a base64 encoded string. diff --git a/lib/ios/AirGoogleMaps/AIRGoogleMapManager.m b/lib/ios/AirGoogleMaps/AIRGoogleMapManager.m index 99e16d77c..5045deb75 100644 --- a/lib/ios/AirGoogleMaps/AIRGoogleMapManager.m +++ b/lib/ios/AirGoogleMaps/AIRGoogleMapManager.m @@ -294,6 +294,24 @@ - (UIView *)view }]; } +RCT_EXPORT_METHOD(setMapBoundaries:(nonnull NSNumber *)reactTag + northEast:(CLLocationCoordinate2D)northEast + southWest:(CLLocationCoordinate2D)southWest) +{ + [self.bridge.uiManager addUIBlock:^(__unused RCTUIManager *uiManager, NSDictionary *viewRegistry) { + id view = viewRegistry[reactTag]; + if (![view isKindOfClass:[AIRGoogleMap class]]) { + RCTLogError(@"Invalid view returned from registry, expecting AIRGoogleMap, got: %@", view); + } else { + AIRGoogleMap *mapView = (AIRGoogleMap *)view; + + GMSCoordinateBounds *bounds = [[GMSCoordinateBounds alloc] initWithCoordinate:northEast coordinate:southWest]; + + mapView.cameraTargetBounds = bounds; + } + }]; +} + - (NSDictionary *)constantsToExport { return @{ @"legalNotice": [GMSServices openSourceLicenseInfo] }; } From 42eba66eaf410b16d62734ffcb8307d6eff75fb4 Mon Sep 17 00:00:00 2001 From: abiduzz420 Date: Wed, 29 Nov 2017 02:10:14 +0530 Subject: [PATCH 183/199] Blank map issue, Google Maps API not enabled (#1706) You need to enable Google maps API in the google developer console for android/ios --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 91b22377b..e11e91b88 100644 --- a/README.md +++ b/README.md @@ -452,6 +452,7 @@ Pass an array of coordinates to focus a map region on said coordinates. * Make sure that you have [properly installed](docs/installation.md) react-native-maps. * Check in the logs if there is more informations about the issue. * Try setting the style of the MapView to an absolute position with top, left, right and bottom values set. +* Make sure you have enabled Google Maps API in ![Google developer console](https://console.developers.google.com/apis/library) ```javascript const styles = StyleSheet.create({ From fe2dc2bbadf01fbf522e04d89b6ba14a6d7539d5 Mon Sep 17 00:00:00 2001 From: Christopher Dro Date: Tue, 28 Nov 2017 15:11:08 -0800 Subject: [PATCH 184/199] v0.18.0 --- CHANGELOG.md | 16 ++++++++++++++++ example/ios/Podfile.lock | 4 ++-- lib/android/gradle.properties | 2 +- package.json | 2 +- 4 files changed, 20 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f61819749..a5829365b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,21 @@ # Change Log +## 0.18.0 (November 28, 2017) +* Android/iOS: [#1587](https://github.com/airbnb/react-native-maps/pull/1750) Add support to set map boundaries +* Android/iOS: [#1750](https://github.com/airbnb/react-native-maps/pull/1750) Add mapPadding property +* Common: [#1792](https://github.com/airbnb/react-native-maps/pull/1792) Make all components use ViewPropTypes || View.propTypes +* iOS: [#1774](https://github.com/airbnb/react-native-maps/pull/1774) Added missing parameters to google map screenshot +* iOS: [#1824](https://github.com/airbnb/react-native-maps/pull/1824) Add new iOS `mutedStandard` map-type +* iOS: [#1705](https://github.com/airbnb/react-native-maps/pull/1705) Enable control of Google Maps Marker tracksViewChanges property. +* Android: [#1710](https://github.com/airbnb/react-native-maps/pull/1710) Added support for new Android camera movement APIs +* iOS: [#1741](https://github.com/airbnb/react-native-maps/pull/1741) Fixed iOS google MapView.onMarkerPress not receiving the marker identifier +* iOS: [#1816](https://github.com/airbnb/react-native-maps/pull/1816) Fix The name of the given podspec ‘yoga' doesn't match the expected one ‘Yoga' +* iOS: [#1797](https://github.com/airbnb/react-native-maps/pull/1797) Fixed onMapReady event on iOS to resemble onMapReady on Android +* Common: [#1817](https://github.com/airbnb/react-native-maps/pull/1817) Allow fitToCoordinates to be called without options parameter + +## 0.17.1 (October 18, 2017) +* Common: [#1687](https://github.com/airbnb/react-native-maps/pull/1687) Fixed TypeScript definitions + ## 0.17.0 (October 11, 2017) * iOS: [#1527](https://github.com/airbnb/react-native-maps/pull/1527) Added [iOS / Google Maps] support for showsIndoorLevelPicker * iOS/Android: [#1544](https://github.com/airbnb/react-native-maps/pull/1544) Adds support to animateToBearing and animateToViewingAngle ( IOS + Android ) diff --git a/example/ios/Podfile.lock b/example/ios/Podfile.lock index 6fc414fe3..a9e02a814 100644 --- a/example/ios/Podfile.lock +++ b/example/ios/Podfile.lock @@ -6,10 +6,10 @@ PODS: - GoogleMaps/Base - React (0.45.1): - React/Core (= 0.45.1) - - react-native-google-maps (0.17.0): + - react-native-google-maps (0.18.0): - GoogleMaps (= 2.1.1) - React - - react-native-maps (0.17.0): + - react-native-maps (0.18.0): - React - React/BatchedBridge (0.45.1): - React/Core diff --git a/lib/android/gradle.properties b/lib/android/gradle.properties index 7047e93ba..774b8a1d0 100644 --- a/lib/android/gradle.properties +++ b/lib/android/gradle.properties @@ -1,5 +1,5 @@ VERSION_CODE=4 -VERSION_NAME=0.17.0 +VERSION_NAME=0.18.0 GROUP=com.airbnb.android POM_DESCRIPTION=React Native Map view component for Android diff --git a/package.json b/package.json index 66e8be298..65fb9221d 100644 --- a/package.json +++ b/package.json @@ -3,7 +3,7 @@ "description": "React Native Mapview component for iOS + Android", "main": "index.js", "author": "Leland Richardson ", - "version": "0.17.0", + "version": "0.18.0", "scripts": { "start": "node node_modules/react-native/local-cli/cli.js start", "run:packager": "./node_modules/react-native/packager/packager.sh", From 59ed7812e1e9312215ce8659781b8ce26f18d2a8 Mon Sep 17 00:00:00 2001 From: Christopher Dro Date: Tue, 28 Nov 2017 17:58:41 -0800 Subject: [PATCH 185/199] [AirMapManager] Update MapBuilder for getCommandsMap to support all entries (#1828) Related to https://github.com/airbnb/react-native-maps/pull/1587 --- .../android/react/maps/AirMapManager.java | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapManager.java b/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapManager.java index 9022b1efc..03e4597bb 100644 --- a/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapManager.java +++ b/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapManager.java @@ -102,7 +102,7 @@ public void setMapPadding(AirMapView view, @Nullable ReadableMap padding) { int right = 0; int bottom = 0; double density = (double) view.getResources().getDisplayMetrics().density; - + if (padding != null) { if (padding.hasKey("left")) { left = (int) (padding.getDouble("left") * density); @@ -312,20 +312,25 @@ public Map getExportedCustomDirectEventTypeConstants() { return map; } - - @Override + @Nullable + @Override public Map getCommandsMap() { - return MapBuilder.of( + Map map = MapBuilder.of( "animateToRegion", ANIMATE_TO_REGION, "animateToCoordinate", ANIMATE_TO_COORDINATE, "animateToViewingAngle", ANIMATE_TO_VIEWING_ANGLE, "animateToBearing", ANIMATE_TO_BEARING, "fitToElements", FIT_TO_ELEMENTS, "fitToSuppliedMarkers", FIT_TO_SUPPLIED_MARKERS, - "fitToCoordinates", FIT_TO_COORDINATES, - "setMapBoundaries", SET_MAP_BOUNDARIES + "fitToCoordinates", FIT_TO_COORDINATES ); + + map.putAll(MapBuilder.of( + "setMapBoundaries", SET_MAP_BOUNDARIES + )); + + return map; } @Override @@ -365,7 +370,6 @@ void pushEvent(ThemedReactContext context, View view, String name, WritableMap d .receiveEvent(view.getId(), name, data); } - @Override public void onDropViewInstance(AirMapView view) { view.doDestroy(); From a31758a12887857216ef1c82951d57f9e6964539 Mon Sep 17 00:00:00 2001 From: Christopher Dro Date: Tue, 28 Nov 2017 18:05:42 -0800 Subject: [PATCH 186/199] v0.18.1 --- CHANGELOG.md | 3 +++ example/ios/Podfile.lock | 4 ++-- lib/android/gradle.properties | 2 +- package.json | 2 +- 4 files changed, 7 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a5829365b..13beb9b3f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,8 @@ # Change Log +## 0.18.1 (November 28, 2017) +* Android: [#1828](https://github.com/airbnb/react-native-maps/pull/1828) [AirMapManager] Update MapBuilder for getCommandsMap to support all entires + ## 0.18.0 (November 28, 2017) * Android/iOS: [#1587](https://github.com/airbnb/react-native-maps/pull/1750) Add support to set map boundaries * Android/iOS: [#1750](https://github.com/airbnb/react-native-maps/pull/1750) Add mapPadding property diff --git a/example/ios/Podfile.lock b/example/ios/Podfile.lock index a9e02a814..83163ff9b 100644 --- a/example/ios/Podfile.lock +++ b/example/ios/Podfile.lock @@ -6,10 +6,10 @@ PODS: - GoogleMaps/Base - React (0.45.1): - React/Core (= 0.45.1) - - react-native-google-maps (0.18.0): + - react-native-google-maps (0.18.1): - GoogleMaps (= 2.1.1) - React - - react-native-maps (0.18.0): + - react-native-maps (0.18.1): - React - React/BatchedBridge (0.45.1): - React/Core diff --git a/lib/android/gradle.properties b/lib/android/gradle.properties index 774b8a1d0..64c92ca15 100644 --- a/lib/android/gradle.properties +++ b/lib/android/gradle.properties @@ -1,5 +1,5 @@ VERSION_CODE=4 -VERSION_NAME=0.18.0 +VERSION_NAME=0.18.1 GROUP=com.airbnb.android POM_DESCRIPTION=React Native Map view component for Android diff --git a/package.json b/package.json index 65fb9221d..d159c5e34 100644 --- a/package.json +++ b/package.json @@ -3,7 +3,7 @@ "description": "React Native Mapview component for iOS + Android", "main": "index.js", "author": "Leland Richardson ", - "version": "0.18.0", + "version": "0.18.1", "scripts": { "start": "node node_modules/react-native/local-cli/cli.js start", "run:packager": "./node_modules/react-native/packager/packager.sh", From 458959bbaf1bec5ed51d0ed2994b2e67931bdad2 Mon Sep 17 00:00:00 2001 From: Hein Rutjes Date: Wed, 29 Nov 2017 18:23:04 +0100 Subject: [PATCH 187/199] Update mapview.md (#1830) There was a typo in the new iOS mapType `mutedStandard`. It should have been `mutedStandard` instead of `standardMuted` --- docs/mapview.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/mapview.md b/docs/mapview.md index 86ddbff0f..6d3227b4a 100644 --- a/docs/mapview.md +++ b/docs/mapview.md @@ -8,7 +8,7 @@ | `region` | `Region` | | The region to be displayed by the map.

The region is defined by the center coordinates and the span of coordinates to display. | `initialRegion` | `Region` | | The initial region to be displayed by the map. Use this prop instead of `region` only if you don't want to control the viewport of the map besides the initial region.

Changing this prop after the component has mounted will not result in a region change.

This is similar to the `initialValue` prop of a text input. | `liteMode` | `Boolean` | `false` | Enable lite mode. **Note**: Android only. -| `mapType` | `String` | `"standard"` | The map type to be displayed.

- standard: standard road map (default)
- satellite: satellite view
- hybrid: satellite view with roads and points of interest overlayed
- terrain: (Android only) topographic view
- standardMuted: more subtle, makes markers/lines pop more (iOS only) +| `mapType` | `String` | `"standard"` | The map type to be displayed.

- standard: standard road map (default)
- satellite: satellite view
- hybrid: satellite view with roads and points of interest overlayed
- terrain: (Android only) topographic view
- mutedStandard: more subtle, makes markers/lines pop more (iOS only) | `customMapStyle` | `Array` | | Adds custom styling to the map component. See [README](https://github.com/airbnb/react-native-maps#customizing-the-map-style) for more information. | `showsUserLocation` | `Boolean` | `false` | If `true` the app will ask for the user's location. **NOTE**: You need to add `NSLocationWhenInUseUsageDescription` key in Info.plist to enable geolocation, otherwise it is going to *fail silently*! | `userLocationAnnotationTitle` | `String` | | The title of the annotation for current user location. This only works if `showsUserLocation` is true. There is a default value `My Location` set by MapView. **Note**: iOS only. From 76b7c369e477cced0a9bb1033459885f19a633b4 Mon Sep 17 00:00:00 2001 From: Christopher Dro Date: Wed, 29 Nov 2017 10:05:19 -0800 Subject: [PATCH 188/199] [AirMapView] Null check map instance on view methods (#1835) --- .../airbnb/android/react/maps/AirMapView.java | 45 ++++++++++--------- 1 file changed, 24 insertions(+), 21 deletions(-) diff --git a/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapView.java b/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapView.java index aece720a8..8de9290c8 100644 --- a/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapView.java +++ b/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapView.java @@ -566,36 +566,35 @@ public void updateExtraData(Object extraData) { } public void animateToRegion(LatLngBounds bounds, int duration) { - if (map != null) { - map.animateCamera(CameraUpdateFactory.newLatLngBounds(bounds, 0), duration, null); - } + if (map == null) return; + map.animateCamera(CameraUpdateFactory.newLatLngBounds(bounds, 0), duration, null); } public void animateToViewingAngle(float angle, int duration) { - if (map != null) { - CameraPosition cameraPosition = new CameraPosition.Builder(map.getCameraPosition()) - .tilt(angle) - .build(); - map.animateCamera(CameraUpdateFactory.newCameraPosition(cameraPosition), duration, null); - } + if (map == null) return; + + CameraPosition cameraPosition = new CameraPosition.Builder(map.getCameraPosition()) + .tilt(angle) + .build(); + map.animateCamera(CameraUpdateFactory.newCameraPosition(cameraPosition), duration, null); } public void animateToBearing(float bearing, int duration) { - if (map != null) { - CameraPosition cameraPosition = new CameraPosition.Builder(map.getCameraPosition()) - .bearing(bearing) - .build(); - map.animateCamera(CameraUpdateFactory.newCameraPosition(cameraPosition), duration, null); - } + if (map == null) return; + CameraPosition cameraPosition = new CameraPosition.Builder(map.getCameraPosition()) + .bearing(bearing) + .build(); + map.animateCamera(CameraUpdateFactory.newCameraPosition(cameraPosition), duration, null); } public void animateToCoordinate(LatLng coordinate, int duration) { - if (map != null) { - map.animateCamera(CameraUpdateFactory.newLatLng(coordinate), duration, null); - } + if (map == null) return; + map.animateCamera(CameraUpdateFactory.newLatLng(coordinate), duration, null); } public void fitToElements(boolean animated) { + if (map == null) return; + LatLngBounds.Builder builder = new LatLngBounds.Builder(); boolean addedPosition = false; @@ -620,6 +619,8 @@ public void fitToElements(boolean animated) { } public void fitToSuppliedMarkers(ReadableArray markerIDsArray, boolean animated) { + if (map == null) return; + LatLngBounds.Builder builder = new LatLngBounds.Builder(); String[] markerIDs = new String[markerIDsArray.size()]; @@ -655,6 +656,8 @@ public void fitToSuppliedMarkers(ReadableArray markerIDsArray, boolean animated) public void fitToCoordinates(ReadableArray coordinatesArray, ReadableMap edgePadding, boolean animated) { + if (map == null) return; + LatLngBounds.Builder builder = new LatLngBounds.Builder(); for (int i = 0; i < coordinatesArray.size(); i++) { @@ -682,6 +685,8 @@ public void fitToCoordinates(ReadableArray coordinatesArray, ReadableMap edgePad } public void setMapBoundaries(ReadableMap northEast, ReadableMap southWest) { + if (map == null) return; + LatLngBounds.Builder builder = new LatLngBounds.Builder(); Double latNE = northEast.getDouble("latitude"); @@ -694,9 +699,7 @@ public void setMapBoundaries(ReadableMap northEast, ReadableMap southWest) { LatLngBounds bounds = builder.build(); - if (map != null) { - map.setLatLngBoundsForCameraTarget(bounds); - } + map.setLatLngBoundsForCameraTarget(bounds); } // InfoWindowAdapter interface From bb3301e2d8e6955c6e7f236d02c1fc91e9c136ed Mon Sep 17 00:00:00 2001 From: Christopher Dro Date: Wed, 29 Nov 2017 10:07:56 -0800 Subject: [PATCH 189/199] v0.18.2 --- CHANGELOG.md | 3 +++ example/ios/Podfile.lock | 4 ++-- lib/android/gradle.properties | 2 +- package.json | 2 +- 4 files changed, 7 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 13beb9b3f..1b3bddcdf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,8 @@ # Change Log +## 0.18.2 (November 29, 2017) +* Android: [#1835](https://github.com/airbnb/react-native-maps/pull/1835) [AirMapView] Null check map instance on view methods + ## 0.18.1 (November 28, 2017) * Android: [#1828](https://github.com/airbnb/react-native-maps/pull/1828) [AirMapManager] Update MapBuilder for getCommandsMap to support all entires diff --git a/example/ios/Podfile.lock b/example/ios/Podfile.lock index 83163ff9b..b906a3476 100644 --- a/example/ios/Podfile.lock +++ b/example/ios/Podfile.lock @@ -6,10 +6,10 @@ PODS: - GoogleMaps/Base - React (0.45.1): - React/Core (= 0.45.1) - - react-native-google-maps (0.18.1): + - react-native-google-maps (0.18.2): - GoogleMaps (= 2.1.1) - React - - react-native-maps (0.18.1): + - react-native-maps (0.18.2): - React - React/BatchedBridge (0.45.1): - React/Core diff --git a/lib/android/gradle.properties b/lib/android/gradle.properties index 64c92ca15..96333559e 100644 --- a/lib/android/gradle.properties +++ b/lib/android/gradle.properties @@ -1,5 +1,5 @@ VERSION_CODE=4 -VERSION_NAME=0.18.1 +VERSION_NAME=0.18.2 GROUP=com.airbnb.android POM_DESCRIPTION=React Native Map view component for Android diff --git a/package.json b/package.json index d159c5e34..941305239 100644 --- a/package.json +++ b/package.json @@ -3,7 +3,7 @@ "description": "React Native Mapview component for iOS + Android", "main": "index.js", "author": "Leland Richardson ", - "version": "0.18.1", + "version": "0.18.2", "scripts": { "start": "node node_modules/react-native/local-cli/cli.js start", "run:packager": "./node_modules/react-native/packager/packager.sh", From 1b78d58b5205b28aaf072de0ed0cd9abd2acb062 Mon Sep 17 00:00:00 2001 From: androidseb Date: Thu, 30 Nov 2017 19:10:18 -0500 Subject: [PATCH 190/199] fixed the Google Maps crash on iOS with most recent versions of react-native (#1839) [AirGoogleMapManager] Use RCTDirectEventBlock for onMarkerPress --- lib/ios/AirGoogleMaps/AIRGoogleMapManager.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/ios/AirGoogleMaps/AIRGoogleMapManager.m b/lib/ios/AirGoogleMaps/AIRGoogleMapManager.m index 5045deb75..5e6ef9c34 100644 --- a/lib/ios/AirGoogleMaps/AIRGoogleMapManager.m +++ b/lib/ios/AirGoogleMaps/AIRGoogleMapManager.m @@ -68,7 +68,7 @@ - (UIView *)view RCT_EXPORT_VIEW_PROPERTY(onPress, RCTBubblingEventBlock) RCT_EXPORT_VIEW_PROPERTY(onLongPress, RCTBubblingEventBlock) RCT_EXPORT_VIEW_PROPERTY(onChange, RCTBubblingEventBlock) -RCT_EXPORT_VIEW_PROPERTY(onMarkerPress, RCTBubblingEventBlock) +RCT_EXPORT_VIEW_PROPERTY(onMarkerPress, RCTDirectEventBlock) RCT_EXPORT_VIEW_PROPERTY(onRegionChange, RCTDirectEventBlock) RCT_EXPORT_VIEW_PROPERTY(onRegionChangeComplete, RCTDirectEventBlock) RCT_EXPORT_VIEW_PROPERTY(mapType, GMSMapViewType) From e53c7ec28e85d7dbf9de5e16e4bb3b2636b85466 Mon Sep 17 00:00:00 2001 From: Christopher Dro Date: Thu, 30 Nov 2017 16:12:01 -0800 Subject: [PATCH 191/199] v0.18.3 --- CHANGELOG.md | 3 +++ example/ios/Podfile.lock | 4 ++-- lib/android/gradle.properties | 2 +- package.json | 2 +- 4 files changed, 7 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1b3bddcdf..109091a39 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,8 @@ # Change Log +## 0.18.3 (November 30, 2017) +* Android: [#1839](https://github.com/airbnb/react-native-maps/pull/1839) [AirGoogleMapManager] Use RCTDirectEventBlock for onMarkerPress + ## 0.18.2 (November 29, 2017) * Android: [#1835](https://github.com/airbnb/react-native-maps/pull/1835) [AirMapView] Null check map instance on view methods diff --git a/example/ios/Podfile.lock b/example/ios/Podfile.lock index b906a3476..b17a261de 100644 --- a/example/ios/Podfile.lock +++ b/example/ios/Podfile.lock @@ -6,10 +6,10 @@ PODS: - GoogleMaps/Base - React (0.45.1): - React/Core (= 0.45.1) - - react-native-google-maps (0.18.2): + - react-native-google-maps (0.18.3): - GoogleMaps (= 2.1.1) - React - - react-native-maps (0.18.2): + - react-native-maps (0.18.3): - React - React/BatchedBridge (0.45.1): - React/Core diff --git a/lib/android/gradle.properties b/lib/android/gradle.properties index 96333559e..e4ea9f69d 100644 --- a/lib/android/gradle.properties +++ b/lib/android/gradle.properties @@ -1,5 +1,5 @@ VERSION_CODE=4 -VERSION_NAME=0.18.2 +VERSION_NAME=0.18.3 GROUP=com.airbnb.android POM_DESCRIPTION=React Native Map view component for Android diff --git a/package.json b/package.json index 941305239..06d3a97bc 100644 --- a/package.json +++ b/package.json @@ -3,7 +3,7 @@ "description": "React Native Mapview component for iOS + Android", "main": "index.js", "author": "Leland Richardson ", - "version": "0.18.2", + "version": "0.18.3", "scripts": { "start": "node node_modules/react-native/local-cli/cli.js start", "run:packager": "./node_modules/react-native/packager/packager.sh", From 0059c18b058130de08c670f3a56281a7fc8736a2 Mon Sep 17 00:00:00 2001 From: dseipp Date: Wed, 6 Dec 2017 09:37:43 -0500 Subject: [PATCH 192/199] update GoogleMaps dependency to 2.5.0 (#1854) this is to resolve compile error: Property 'cameraTargetBounds' not found on object of type 'AIRGoogleMap *' --- react-native-google-maps.podspec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/react-native-google-maps.podspec b/react-native-google-maps.podspec index 487cc2320..51dc01da1 100644 --- a/react-native-google-maps.podspec +++ b/react-native-google-maps.podspec @@ -17,5 +17,5 @@ Pod::Spec.new do |s| s.compiler_flags = '-fno-modules' s.dependency 'React' - s.dependency 'GoogleMaps', '2.1.1' + s.dependency 'GoogleMaps', '2.5.0' end From 90d1b5eceb891a31a143ad3e74b0630b8ca011da Mon Sep 17 00:00:00 2001 From: ksincennes Date: Tue, 12 Dec 2017 13:57:43 -0700 Subject: [PATCH 193/199] Create MapGeoJson.js --- lib/components/MapGeoJson.js | 159 +++++++++++++++++++++++++++++++++++ 1 file changed, 159 insertions(+) create mode 100644 lib/components/MapGeoJson.js diff --git a/lib/components/MapGeoJson.js b/lib/components/MapGeoJson.js new file mode 100644 index 000000000..7099f856a --- /dev/null +++ b/lib/components/MapGeoJson.js @@ -0,0 +1,159 @@ +import React, { PropTypes } from 'react'; +import { + View, +} from 'react-native'; + +import resolveAssetSource from 'react-native/Libraries/Image/resolveAssetSource'; +import decorateMapComponent, { + USES_DEFAULT_IMPLEMENTATION, + NOT_SUPPORTED, +} from './decorateMapComponent'; + +const propTypes = { + ...View.propTypes, + + /** + * string representation of the goeJSON + */ + geoJSON: PropTypes.string, + + /** + * Callback that is called when the user presses on the polygon + */ + onPress: PropTypes.func, + + /** + * The stroke width to use for the path. + */ + strokeWidth: PropTypes.number, + + /** + * The stroke color to use for the path. + */ + strokeColor: PropTypes.string, + + /** + * The fill color to use for the path. + */ + fillColor: PropTypes.string, + color: PropTypes.string, + + styles: PropTypes.string, + byProp: PropTypes.bool, + title: PropTypes.string, + icon: PropTypes.any, + snippet: PropTypes.string, + infoWindowAnchor: PropTypes.shape({ + /** + * Offset to the callout + */ + U: PropTypes.number.isRequired, + V: PropTypes.number.isRequired, + }), + + anchor: PropTypes.shape({ + /** + * Offset to the callout + */ + U: PropTypes.number.isRequired, + V: PropTypes.number.isRequired, + }), + + /** + * The order in which this tile overlay is drawn with respect to other overlays. An overlay + * with a larger z-index is drawn over overlays with smaller z-indices. The order of overlays + * with the same z-index is arbitrary. The default zIndex is 0. + * + * @platform android + */ + zIndex: PropTypes.number, + visible: PropTypes.bool, + draggable: PropTypes.bool, + flat: PropTypes.bool, + clickable: PropTypes.bool, + + + /** + * The limiting value that helps avoid spikes at junctions between connected line segments. + * The miter limit helps you avoid spikes in paths that use the `miter` `lineJoin` style. If + * the ratio of the miter length—that is, the diagonal length of the miter join—to the line + * thickness exceeds the miter limit, the joint is converted to a bevel join. The default + * miter limit is 10, which results in the conversion of miters whose angle at the joint + * is less than 11 degrees. + * + * @platform ios + */ + miterLimit: PropTypes.number, + + /** + * Boolean to indicate whether to draw each segment of the line as a geodesic as opposed to + * straight lines on the Mercator projection. A geodesic is the shortest path between two + * points on the Earth's surface. The geodesic curve is constructed assuming the Earth is + * a sphere. + * + * @platform android + */ + geodesic: PropTypes.bool, + + /** + * The offset (in points) at which to start drawing the dash pattern. + * + * Use this property to start drawing a dashed line partway through a segment or gap. For + * example, a phase value of 6 for the patter 5-2-3-2 would cause drawing to begin in the + * middle of the first gap. + * + * The default value of this property is 0. + * + * @platform ios + */ + lineDashPhase: PropTypes.number, + + /** + * An array of numbers specifying the dash pattern to use for the path. + * + * The array contains one or more numbers that indicate the lengths (measured in points) of the + * line segments and gaps in the pattern. The values in the array alternate, starting with the + * first line segment length, followed by the first gap length, followed by the second line + * segment length, and so on. + * + * This property is set to `null` by default, which indicates no line dash pattern. + * + * @platform ios + */ + lineDashPattern: PropTypes.arrayOf(PropTypes.number), + onPress: PropTypes.func, +}; + +const defaultProps = { + strokeWidth: 1, + onPress() {}, +}; + +class MapGeoJson extends React.Component { + render() { + let icon; + if (this.props.icon) { + icon = resolveAssetSource(this.props.icon) || {}; + icon = icon.uri; + } + const AIRMapGeoJSON = this.getAirComponent(); + return ( + + ); + } +} + +MapGeoJson.propTypes = propTypes; +MapGeoJson.defaultProps = defaultProps; + +module.exports = decorateMapComponent(MapGeoJson, { + componentType: 'GeoJSON', + providers: { + google: { + ios: NOT_SUPPORTED, + android: USES_DEFAULT_IMPLEMENTATION, + }, + }, +}); From ba705c833ba5040f487da5cd399dbf21b85190d1 Mon Sep 17 00:00:00 2001 From: ksincennes Date: Tue, 12 Dec 2017 13:58:29 -0700 Subject: [PATCH 194/199] Delete MapGeoJson.js --- components/MapGeoJson.js | 159 --------------------------------------- 1 file changed, 159 deletions(-) delete mode 100644 components/MapGeoJson.js diff --git a/components/MapGeoJson.js b/components/MapGeoJson.js deleted file mode 100644 index 7099f856a..000000000 --- a/components/MapGeoJson.js +++ /dev/null @@ -1,159 +0,0 @@ -import React, { PropTypes } from 'react'; -import { - View, -} from 'react-native'; - -import resolveAssetSource from 'react-native/Libraries/Image/resolveAssetSource'; -import decorateMapComponent, { - USES_DEFAULT_IMPLEMENTATION, - NOT_SUPPORTED, -} from './decorateMapComponent'; - -const propTypes = { - ...View.propTypes, - - /** - * string representation of the goeJSON - */ - geoJSON: PropTypes.string, - - /** - * Callback that is called when the user presses on the polygon - */ - onPress: PropTypes.func, - - /** - * The stroke width to use for the path. - */ - strokeWidth: PropTypes.number, - - /** - * The stroke color to use for the path. - */ - strokeColor: PropTypes.string, - - /** - * The fill color to use for the path. - */ - fillColor: PropTypes.string, - color: PropTypes.string, - - styles: PropTypes.string, - byProp: PropTypes.bool, - title: PropTypes.string, - icon: PropTypes.any, - snippet: PropTypes.string, - infoWindowAnchor: PropTypes.shape({ - /** - * Offset to the callout - */ - U: PropTypes.number.isRequired, - V: PropTypes.number.isRequired, - }), - - anchor: PropTypes.shape({ - /** - * Offset to the callout - */ - U: PropTypes.number.isRequired, - V: PropTypes.number.isRequired, - }), - - /** - * The order in which this tile overlay is drawn with respect to other overlays. An overlay - * with a larger z-index is drawn over overlays with smaller z-indices. The order of overlays - * with the same z-index is arbitrary. The default zIndex is 0. - * - * @platform android - */ - zIndex: PropTypes.number, - visible: PropTypes.bool, - draggable: PropTypes.bool, - flat: PropTypes.bool, - clickable: PropTypes.bool, - - - /** - * The limiting value that helps avoid spikes at junctions between connected line segments. - * The miter limit helps you avoid spikes in paths that use the `miter` `lineJoin` style. If - * the ratio of the miter length—that is, the diagonal length of the miter join—to the line - * thickness exceeds the miter limit, the joint is converted to a bevel join. The default - * miter limit is 10, which results in the conversion of miters whose angle at the joint - * is less than 11 degrees. - * - * @platform ios - */ - miterLimit: PropTypes.number, - - /** - * Boolean to indicate whether to draw each segment of the line as a geodesic as opposed to - * straight lines on the Mercator projection. A geodesic is the shortest path between two - * points on the Earth's surface. The geodesic curve is constructed assuming the Earth is - * a sphere. - * - * @platform android - */ - geodesic: PropTypes.bool, - - /** - * The offset (in points) at which to start drawing the dash pattern. - * - * Use this property to start drawing a dashed line partway through a segment or gap. For - * example, a phase value of 6 for the patter 5-2-3-2 would cause drawing to begin in the - * middle of the first gap. - * - * The default value of this property is 0. - * - * @platform ios - */ - lineDashPhase: PropTypes.number, - - /** - * An array of numbers specifying the dash pattern to use for the path. - * - * The array contains one or more numbers that indicate the lengths (measured in points) of the - * line segments and gaps in the pattern. The values in the array alternate, starting with the - * first line segment length, followed by the first gap length, followed by the second line - * segment length, and so on. - * - * This property is set to `null` by default, which indicates no line dash pattern. - * - * @platform ios - */ - lineDashPattern: PropTypes.arrayOf(PropTypes.number), - onPress: PropTypes.func, -}; - -const defaultProps = { - strokeWidth: 1, - onPress() {}, -}; - -class MapGeoJson extends React.Component { - render() { - let icon; - if (this.props.icon) { - icon = resolveAssetSource(this.props.icon) || {}; - icon = icon.uri; - } - const AIRMapGeoJSON = this.getAirComponent(); - return ( - - ); - } -} - -MapGeoJson.propTypes = propTypes; -MapGeoJson.defaultProps = defaultProps; - -module.exports = decorateMapComponent(MapGeoJson, { - componentType: 'GeoJSON', - providers: { - google: { - ios: NOT_SUPPORTED, - android: USES_DEFAULT_IMPLEMENTATION, - }, - }, -}); From 3125ffe6261d5cea4b4427e90f6e47131a65ad0d Mon Sep 17 00:00:00 2001 From: ksincennes Date: Tue, 12 Dec 2017 14:12:16 -0700 Subject: [PATCH 195/199] Update AirMapView.java adding bracket --- .../src/main/java/com/airbnb/android/react/maps/AirMapView.java | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapView.java b/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapView.java index 2dd7dab98..7b7fc27e9 100644 --- a/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapView.java +++ b/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapView.java @@ -685,6 +685,7 @@ public void fitToSuppliedMarkers(ReadableArray markerIDsArray, boolean animated) } } } + } public void fitToCoordinates(ReadableArray coordinatesArray, ReadableMap edgePadding, From 73d72faf49781b5089dbce5cc49ab47f382b78c1 Mon Sep 17 00:00:00 2001 From: ksincennes Date: Tue, 12 Dec 2017 14:18:08 -0700 Subject: [PATCH 196/199] Update build.gradle fix missing dependency --- lib/android/build.gradle | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/android/build.gradle b/lib/android/build.gradle index 326ab4bfa..fde55416f 100644 --- a/lib/android/build.gradle +++ b/lib/android/build.gradle @@ -37,4 +37,5 @@ dependencies { provided "com.facebook.react:react-native:+" compile "com.google.android.gms:play-services-base:10.2.4" compile "com.google.android.gms:play-services-maps:10.2.4" + compile "com.google.maps.android:android-maps-utils:0.4+" } From e43d74f05995d9182f3dc9844292b04be3fb6a81 Mon Sep 17 00:00:00 2001 From: ksincennes Date: Tue, 12 Dec 2017 14:21:16 -0700 Subject: [PATCH 197/199] Update MapsPackage.java add missing line --- .../src/main/java/com/airbnb/android/react/maps/MapsPackage.java | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/android/src/main/java/com/airbnb/android/react/maps/MapsPackage.java b/lib/android/src/main/java/com/airbnb/android/react/maps/MapsPackage.java index c60a9f740..ce8aa4d11 100644 --- a/lib/android/src/main/java/com/airbnb/android/react/maps/MapsPackage.java +++ b/lib/android/src/main/java/com/airbnb/android/react/maps/MapsPackage.java @@ -36,6 +36,7 @@ public List createViewManagers(ReactApplicationContext reactContext AirMapPolylineManager polylineManager = new AirMapPolylineManager(reactContext); AirMapPolygonManager polygonManager = new AirMapPolygonManager(reactContext); AirMapCircleManager circleManager = new AirMapCircleManager(reactContext); + AirMapGeoJSONManager geoJsonManager = new AirMapGeoJSONManager(reactContext); AirMapManager mapManager = new AirMapManager(reactContext); AirMapLiteManager mapLiteManager = new AirMapLiteManager(reactContext); AirMapUrlTileManager tileManager = new AirMapUrlTileManager(reactContext); From 6ebf09a1b76d872987ae111a50ef0b0390e332d2 Mon Sep 17 00:00:00 2001 From: Kim Booker Date: Wed, 13 Dec 2017 14:55:35 -0700 Subject: [PATCH 198/199] Changing components.default back to components[PROVIDER_DEFAULT] --- lib/components/decorateMapComponent.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/components/decorateMapComponent.js b/lib/components/decorateMapComponent.js index 9228495bd..168d4f122 100644 --- a/lib/components/decorateMapComponent.js +++ b/lib/components/decorateMapComponent.js @@ -48,8 +48,8 @@ export default function decorateMapComponent(Component, { componentType, provide if (components[provider]) return components[provider]; if (provider === PROVIDER_DEFAULT) { - components.default = getDefaultComponent(); - return components.default; + components[PROVIDER_DEFAULT] = getDefaultComponent(); + return components[PROVIDER_DEFAULT]; } const providerInfo = providers[provider]; @@ -62,8 +62,8 @@ export default function decorateMapComponent(Component, { componentType, provide components[provider] = requireNativeComponent(componentName, Component); } } else { // (platformSupport === USES_DEFAULT_IMPLEMENTATION) - if (!components.default) components.default = getDefaultComponent(); - components[provider] = components.default; + if (!components[PROVIDER_DEFAULT]) components[PROVIDER_DEFAULT] = getDefaultComponent(); + components[provider] = components[PROVIDER_DEFAULT]; } return components[provider]; From 78c2c9bc46cf99a5ffef3d96ab56077e52e1e3f9 Mon Sep 17 00:00:00 2001 From: Kim Booker Date: Thu, 11 Jan 2018 11:48:23 -0700 Subject: [PATCH 199/199] Somehow we lost this --- .../airbnb/android/react/maps/AirMapView.java | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapView.java b/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapView.java index 7b7fc27e9..9858b7d80 100644 --- a/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapView.java +++ b/lib/android/src/main/java/com/airbnb/android/react/maps/AirMapView.java @@ -201,21 +201,21 @@ public boolean onMarkerClick(Marker marker) { }); map.setOnPolygonClickListener(new GoogleMap.OnPolygonClickListener() { - @Override - public void onPolygonClick(Polygon polygon) { - WritableMap event = makeClickEventData(polygon.getPoints().get(0)); - event.putString("action", "polygon-press"); - manager.pushEvent(context, polygonMap.get(polygon), "onPress", event); - } + @Override + public void onPolygonClick (Polygon polygon) { + WritableMap event = makePolygonClickEventData(polygon); + event.putString("action", "press"); + manager.pushEvent(context, view, "onPress", event); + } }); - map.setOnPolylineClickListener(new GoogleMap.OnPolylineClickListener() { - @Override - public void onPolylineClick(Polyline polyline) { - WritableMap event = makeClickEventData(polyline.getPoints().get(0)); - event.putString("action", "polyline-press"); - manager.pushEvent(context, polylineMap.get(polyline), "onPress", event); - } + map.setOnPolylineClickListener(new GoogleMap.OnPolylineClickListener(){ + @Override + public void onPolylineClick(Polyline polyline) { + WritableMap event = makeLineClickEventData(polyline); + event.putString("action", "press"); + manager.pushEvent(context, view, "onPress", event); + } }); map.setOnInfoWindowClickListener(new GoogleMap.OnInfoWindowClickListener() {