[ReactNative] Pick correct assets depending on device scale

This commit is contained in:
Alex Kotliarskyi 2015-04-22 16:31:13 -07:00
parent b2e8dc9834
commit ffb3026419
2 changed files with 52 additions and 2 deletions

View File

@ -56,6 +56,25 @@ describe('resolveAssetSource', () => {
}); });
}); });
it('picks matching scale', () => {
expectResolvesAsset({
__packager_asset: true,
fileSystemLocation: '/root/app/module/a',
httpServerLocation: '/assets/module/a',
width: 100,
height: 200,
scales: [1, 2, 3],
hash: '5b6f00f',
name: 'logo',
type: 'png',
}, {
isStatic: false,
width: 100,
height: 200,
uri: 'http://10.0.0.1:8081/assets/module/a/logo@2x.png?hash=5b6f00f',
});
});
it('does not change deprecated assets', () => { it('does not change deprecated assets', () => {
expectResolvesAsset({ expectResolvesAsset({
__packager_asset: true, __packager_asset: true,
@ -103,3 +122,14 @@ describe('resolveAssetSource', () => {
}); });
}); });
describe('resolveAssetSource.pickScale', () => {
it('picks matching scale', () => {
expect(resolveAssetSource.pickScale([1], 2)).toBe(1);
expect(resolveAssetSource.pickScale([1, 2, 3], 2)).toBe(2);
expect(resolveAssetSource.pickScale([1, 2], 3)).toBe(2);
expect(resolveAssetSource.pickScale([1, 2, 3, 4], 3.5)).toBe(4);
expect(resolveAssetSource.pickScale([3, 4], 2)).toBe(3);
expect(resolveAssetSource.pickScale([], 2)).toBe(1);
});
});

View File

@ -10,6 +10,7 @@
*/ */
'use strict'; 'use strict';
var PixelRatio = require('PixelRatio');
var SourceCode = require('NativeModules').SourceCode; var SourceCode = require('NativeModules').SourceCode;
var _serverURL; var _serverURL;
@ -28,6 +29,20 @@ function getServerURL() {
return _serverURL; return _serverURL;
} }
function pickScale(scales, deviceScale) {
// Packager guarantees that `scales` array is sorted
for (var i = 0; i < scales.length; i++) {
if (scales[i] >= deviceScale) {
return scales[i];
}
}
// If nothing matches, device scale is larger than any available
// scales, so we return the biggest one. Unless the array is empty,
// in which case we default to 1
return scales[scales.length - 1] || 1;
}
// TODO(frantic): // TODO(frantic):
// * Pick best scale and append @Nx to file path // * Pick best scale and append @Nx to file path
// * We are currently using httpServerLocation for both http and in-app bundle // * We are currently using httpServerLocation for both http and in-app bundle
@ -57,12 +72,16 @@ function resolveAssetSource(source) {
path = path.substr(1); path = path.substr(1);
} }
var scale = pickScale(source.scales, PixelRatio.get());
var scaleSuffix = scale === 1 ? '' : '@' + scale + 'x';
var fileName = source.name + scaleSuffix + '.' + source.type;
var serverURL = getServerURL(); var serverURL = getServerURL();
if (serverURL) { if (serverURL) {
return { return {
width: source.width, width: source.width,
height: source.height, height: source.height,
uri: serverURL + path + '/' + source.name + '.' + source.type + uri: serverURL + path + '/' + fileName +
'?hash=' + source.hash, '?hash=' + source.hash,
isStatic: false, isStatic: false,
}; };
@ -70,7 +89,7 @@ function resolveAssetSource(source) {
return { return {
width: source.width, width: source.width,
height: source.height, height: source.height,
uri: path + '/' + source.name + '.' + source.type, uri: path + '/' + fileName,
isStatic: true, isStatic: true,
}; };
} }
@ -79,3 +98,4 @@ function resolveAssetSource(source) {
} }
module.exports = resolveAssetSource; module.exports = resolveAssetSource;
module.exports.pickScale = pickScale;