Merge pull request #689 from mapbox/icon-sprite-sheet-fix

[v6] Icon sprite sheet fix
This commit is contained in:
Nick Italiano
2017-10-26 16:25:04 -07:00
committed by GitHub
7 changed files with 63 additions and 23 deletions
+3
View File
@@ -0,0 +1,3 @@
jest.mock('react-native/Libraries/Image/resolveAssetSource', () => {
return () => ({ uri: `asset://test.png` });
});
+10
View File
@@ -24,6 +24,16 @@ describe('MapboxStyleSheet', () => {
});
});
it('should create asset image item for when we require images directly in JS', () => {
verifyStyleSheetsMatch({ fillPattern: 123 }, {
__MAPBOX_STYLESHEET__: true,
fillPattern: {
type: 'constant',
payload: { value: 'asset://test.png', image: true },
},
});
});
it('should create translate item', () => {
verifyStyleSheetsMatch({ fillTranslate: { x: 1, y: 2 } }, {
__MAPBOX_STYLESHEET__: true,
@@ -1,8 +1,10 @@
package com.mapbox.rctmgl.components.styles;
import android.net.Uri;
import android.support.annotation.NonNull;
import android.support.annotation.StringDef;
import com.facebook.common.util.UriUtil;
import com.facebook.react.bridge.ReadableMap;
import com.facebook.react.bridge.ReadableMapKeySetIterator;
import com.mapbox.mapboxsdk.maps.MapboxMap;
@@ -57,16 +59,20 @@ public class RCTMGLStyle {
}
public void addImage(String uriStr) {
if (uriStr == null || isTokenString(uriStr)) {
if (!shouldAddImage(uriStr)) {
return;
}
Map.Entry[] images = new Map.Entry[]{ new AbstractMap.SimpleEntry(uriStr, uriStr) };
DownloadMapImageTask task = new DownloadMapImageTask(mMap, null);
task.execute(images);
}
private boolean isTokenString(String str) {
return str.charAt(0) == '{' && str.charAt(str.length() - 1) == '}';
private boolean shouldAddImage(String uriStr) {
return uriStr != null && isValidURI(uriStr);
}
private boolean isValidURI(String str) {
Uri uri = Uri.parse(str);
return UriUtil.isLocalAssetUri(uri) || UriUtil.isNetworkUri(uri);
}
}
+13 -10
View File
@@ -53,7 +53,7 @@
} else if ([prop isEqualToString:@"fillTranslateAnchor"]) {
[self setFillTranslateAnchor:layer withReactStyleValue:styleValue];
} else if ([prop isEqualToString:@"fillPattern"]) {
if ([self _isTokenString:styleValue.payload[@"value"]]) {
if (![self _shouldAddImage:styleValue.payload[@"value"]]) {
[self setFillPattern:layer withReactStyleValue:styleValue];
} else {
[RCTMGLUtils fetchImage:_bridge url:styleValue.payload[@"value"] callback:^(NSError *error, UIImage *image) {
@@ -131,7 +131,7 @@
} else if ([prop isEqualToString:@"lineDasharrayTransition"]) {
[self setLineDasharrayTransition:layer withReactStyleValue:styleValue];
} else if ([prop isEqualToString:@"linePattern"]) {
if ([self _isTokenString:styleValue.payload[@"value"]]) {
if (![self _shouldAddImage:styleValue.payload[@"value"]]) {
[self setLinePattern:layer withReactStyleValue:styleValue];
} else {
[RCTMGLUtils fetchImage:_bridge url:styleValue.payload[@"value"] callback:^(NSError *error, UIImage *image) {
@@ -185,7 +185,7 @@
} else if ([prop isEqualToString:@"iconTextFitPadding"]) {
[self setIconTextFitPadding:layer withReactStyleValue:styleValue];
} else if ([prop isEqualToString:@"iconImage"]) {
if ([self _isTokenString:styleValue.payload[@"value"]]) {
if (![self _shouldAddImage:styleValue.payload[@"value"]]) {
[self setIconImage:layer withReactStyleValue:styleValue];
} else {
[RCTMGLUtils fetchImage:_bridge url:styleValue.payload[@"value"] callback:^(NSError *error, UIImage *image) {
@@ -392,7 +392,7 @@
} else if ([prop isEqualToString:@"fillExtrusionTranslateAnchor"]) {
[self setFillExtrusionTranslateAnchor:layer withReactStyleValue:styleValue];
} else if ([prop isEqualToString:@"fillExtrusionPattern"]) {
if ([self _isTokenString:styleValue.payload[@"value"]]) {
if (![self _shouldAddImage:styleValue.payload[@"value"]]) {
[self setFillExtrusionPattern:layer withReactStyleValue:styleValue];
} else {
[RCTMGLUtils fetchImage:_bridge url:styleValue.payload[@"value"] callback:^(NSError *error, UIImage *image) {
@@ -491,7 +491,7 @@
} else if ([prop isEqualToString:@"backgroundColorTransition"]) {
[self setBackgroundColorTransition:layer withReactStyleValue:styleValue];
} else if ([prop isEqualToString:@"backgroundPattern"]) {
if ([self _isTokenString:styleValue.payload[@"value"]]) {
if (![self _shouldAddImage:styleValue.payload[@"value"]]) {
[self setBackgroundPattern:layer withReactStyleValue:styleValue];
} else {
[RCTMGLUtils fetchImage:_bridge url:styleValue.payload[@"value"] callback:^(NSError *error, UIImage *image) {
@@ -1847,12 +1847,15 @@
- (BOOL)_isTokenString:(NSString *)str
- (BOOL)_shouldAddImage:(NSString *)str
{
if (str == nil) {
return false;
}
return [str hasPrefix:@"{"] && [str hasSuffix:@"}"];
return str != nil && [self _isValidURL:str];
}
- (BOOL)_isValidURL:(NSString *)str
{
NSURL *url = [NSURL URLWithString:str];
return [UIApplication.sharedApplication canOpenURL:url];
}
- (BOOL)_hasReactStyle:(NSDictionary *)reactStyle
+16 -2
View File
@@ -77,6 +77,21 @@ class MapStyleFunctionItem extends MapStyleItem {
}
}
function resolveImage (imageURL) {
let resolved = imageURL;
if (typeof imageURL === 'number') { // required from JS, local file resolve it's asset filepath
const res = resolveAssetSource(imageURL);
// we found a local uri
if (res.uri) {
resolved = res.uri;
}
}
return resolved;
}
function makeStyleValue (prop, value, extras = {}) {
let item;
@@ -93,8 +108,7 @@ function makeStyleValue (prop, value, extras = {}) {
} else if (styleMap[prop] === StyleTypes.Translation) {
item = new MapStyleTranslationItem(value.x, value.y, extraData);
} else if (styleMap[prop] === StyleTypes.Image) {
const res = resolveAssetSource(value) || {};
item = new MapStyleConstantItem(res.uri || value, { image: true, ...extraData });
item = new MapStyleConstantItem(resolveImage(value), { image: true, ...extraData });
} else {
item = new MapStyleConstantItem(value, extraData);
}
+2 -1
View File
@@ -63,7 +63,8 @@
"javascript/**/*.js"
],
"setupFiles": [
"./__tests__/__mocks__/react-native-mapbox-gl.mock.js"
"./__tests__/__mocks__/react-native-mapbox-gl.mock.js",
"./__tests__/__mocks__/react-native.mock.js"
],
"modulePathIgnorePatterns": [
"example",
+9 -6
View File
@@ -36,7 +36,7 @@
<% for (let i = 0; i < layer.properties.length; i++) { -%>
<%- ifOrElseIf(i) -%> ([prop isEqualToString:@"<%= layer.properties[i].name %>"]) {
<%_ if (layer.properties[i].image) { _%>
if ([self _isTokenString:styleValue.payload[@"value"]]) {
if (![self _shouldAddImage:styleValue.payload[@"value"]]) {
[self set<%- iosPropMethodName(layer, pascelCase(layer.properties[i].name)) -%>:layer withReactStyleValue:styleValue];
} else {
[RCTMGLUtils fetchImage:_bridge url:styleValue.payload[@"value"] callback:^(NSError *error, UIImage *image) {
@@ -88,12 +88,15 @@
<% } %>
<% } %>
- (BOOL)_isTokenString:(NSString *)str
- (BOOL)_shouldAddImage:(NSString *)str
{
if (str == nil) {
return false;
}
return [str hasPrefix:@"{"] && [str hasSuffix:@"}"];
return str != nil && [self _isValidURL:str];
}
- (BOOL)_isValidURL:(NSString *)str
{
NSURL *url = [NSURL URLWithString:str];
return [UIApplication.sharedApplication canOpenURL:url];
}
- (BOOL)_hasReactStyle:(NSDictionary *)reactStyle