Send only annotation changes over bridge

This commit is contained in:
Marius Petcu
2016-06-21 17:10:40 +03:00
parent d2a20c5a15
commit abfcaa1bdd
5 changed files with 89 additions and 28 deletions
+55 -7
View File
@@ -8,6 +8,10 @@ import {
findNodeHandle
} from 'react-native';
import cloneDeep from 'lodash/cloneDeep';
import clone from 'lodash/clone';
import isEqual from 'lodash/isEqual';
const { MapboxGLManager } = NativeModules;
const { mapStyles, userTrackingMode, userLocationVerticalAlignment, unknownResourceCount } = MapboxGLManager;
@@ -206,9 +210,6 @@ class MapView extends Component {
onTap: PropTypes.func,
contentInset: PropTypes.array,
userLocationVerticalAlignment: PropTypes.number,
onOfflineProgressDidChange: PropTypes.func,
onOfflineMaxAllowedMapboxTiles: PropTypes.func,
onOfflineDidRecieveError: PropTypes.func,
onChangeUserTrackingMode: PropTypes.func
};
@@ -231,10 +232,59 @@ class MapView extends Component {
compassIsHidden: false
};
componentWillReceiveProps(newProps) {
const oldKeys = clone(this._annotations);
const itemsToAdd = [];
const itemsToRemove = [];
newProps.annotations.forEach(annotation => {
const id = annotation.id;
if (!isEqual(this._annotations[id], annotation)) {
this._annotations[id] = cloneDeep(annotation);
itemsToAdd.push(annotation);
}
oldKeys[id] = null;
});
for (let key in oldKeys) {
if (oldKeys[key]) {
delete this._annotations[key];
itemsToRemove.push(key);
}
}
MapboxGLManager.spliceAnnotations(findNodeHandle(this), false, itemsToRemove, itemsToAdd);
}
_native = null;
onNativeComponentMount = (ref) => {
if (this._native === ref) { return; }
this._native = ref;
MapboxGLManager.spliceAnnotations(findNodeHandle(this), true, [], this.props.annotations);
let annotations = this.props.annotations.reduce((acc, annotation) => {
acc[annotation.id] = cloneDeep(annotation);
return acc;
}, {});
this._annotations = annotations;
};
setNativeProps(nativeProps) {
this._native && this._native.setNativeProps(nativeProps);
}
componentWillUnmount() {
this._native = null;
}
render() {
return (
<MapboxGLView
{...this.props}
ref={this.onNativeComponentMount}
onRegionChange={this._onRegionChange}
onRegionWillChange={this._onRegionWillChange}
onOpenAnnotation={this._onOpenAnnotation}
@@ -245,10 +295,8 @@ class MapView extends Component {
onFinishLoadingMap={this._onFinishLoadingMap}
onStartLoadingMap={this._onStartLoadingMap}
onLocateUserFailed={this._onLocateUserFailed}
onOfflineProgressDidChange={this._onOfflineProgressDidChange}
onOfflineMaxAllowedMapboxTiles={this._onOfflineMaxAllowedMapboxTiles}
onOfflineDidRecieveError={this._onOfflineDidRecieveError}
onChangeUserTrackingMode={this._onChangeUserTrackingMode} />
onChangeUserTrackingMode={this._onChangeUserTrackingMode}
/>
);
}
}
+1 -1
View File
@@ -40,7 +40,7 @@
- (void)selectAnnotation:(NSString*)selectedId animated:(BOOL)animated;
// Annotation management
- (void)addAnnotation:(NSObject *)annotation;
- (void)upsertAnnotation:(NSObject *)annotation;
- (void)removeAnnotation:(NSString*)selectedIdentifier;
- (void)removeAllAnnotations;
+9 -2
View File
@@ -101,7 +101,9 @@
_isChangingUserTracking = YES;
_map.userTrackingMode = _userTrackingMode;
_isChangingUserTracking = NO;
[_map addAnnotations:[_annotations allValues]];
for (NSString * annotationId in _annotations) {
[_map addAnnotation:_annotations[annotationId]];
}
[self addSubview:_map];
[self layoutSubviews];
@@ -122,14 +124,19 @@
// Annotation management
- (void)addAnnotation:(RCTMGLAnnotation *) annotation {
- (void)upsertAnnotation:(RCTMGLAnnotation *) annotation {
NSString * identifier = [annotation id];
if (!identifier || [identifier length] == 0) {
RCTLogError(@"field `id` is required on all annotations");
return;
}
RCTMGLAnnotation * oldAnnotation = [_annotations objectForKey:identifier];
[_annotations setObject:annotation forKey:identifier];
[_map addAnnotation:annotation];
if (oldAnnotation) {
[_map removeAnnotation:oldAnnotation];
}
}
- (void)removeAnnotation:(NSString*)selectedIdentifier
+22 -17
View File
@@ -73,23 +73,6 @@ RCT_CUSTOM_VIEW_PROPERTY(contentInset, UIEdgeInsetsMake, RCTMapboxGL)
view.contentInset = inset;
}
RCT_CUSTOM_VIEW_PROPERTY(annotations, CLLocationCoordinate2D, RCTMapboxGL)
{
if ([json isKindOfClass:[NSArray class]]) {
[view removeAllAnnotations];
id annotationObject;
NSEnumerator *enumerator = [json objectEnumerator];
while (annotationObject = [enumerator nextObject]) {
CLLocationCoordinate2D coordinate = [RCTConvert CLLocationCoordinate2D:annotationObject];
if (CLLocationCoordinate2DIsValid(coordinate)){
[view addAnnotation:convertToMGLAnnotation(annotationObject)];
}
}
}
}
// Constants
- (NSDictionary *)constantsToExport
@@ -306,6 +289,28 @@ RCT_EXPORT_METHOD(removePack:(NSString*)packName
// View methods
RCT_EXPORT_METHOD(spliceAnnotations:(nonnull NSNumber *)reactTag
deleteAll:(BOOL)deleteAll
toDelete:(nonnull NSArray<NSString *> *)toDelete
toAdd:(nonnull NSArray *)toAdd)
{
[_bridge.uiManager addUIBlock:^(RCTUIManager *uiManager, NSDictionary<NSNumber *, RCTMapboxGL *> *viewRegistry) {
RCTMapboxGL *mapView = viewRegistry[reactTag];
if (deleteAll) {
[mapView removeAllAnnotations];
} else {
for (NSString * key in toDelete) {
[mapView removeAnnotation:key];
}
}
for (NSObject * annotationObject in toAdd) {
[mapView upsertAnnotation:convertToMGLAnnotation(annotationObject)];
}
}];
}
RCT_EXPORT_METHOD(getCenterCoordinateZoomLevel:(nonnull NSNumber *)reactTag
callback:(RCTResponseSenderBlock)callback)
{
+2 -1
View File
@@ -33,6 +33,7 @@
"eslint-plugin-react": "^3.11.3"
},
"dependencies": {
"babel-eslint": "^4.1.6"
"babel-eslint": "^4.1.6",
"lodash": "^4.13.1"
}
}