From ffb3026419561d0cc7518ea2f8e9c0b675a9ff23 Mon Sep 17 00:00:00 2001 From: Alex Kotliarskyi Date: Wed, 22 Apr 2015 16:31:13 -0700 Subject: [PATCH] [ReactNative] Pick correct assets depending on device scale --- .../__tests__/resolveAssetSource-test.js | 30 +++++++++++++++++++ Libraries/Image/resolveAssetSource.js | 24 +++++++++++++-- 2 files changed, 52 insertions(+), 2 deletions(-) diff --git a/Libraries/Image/__tests__/resolveAssetSource-test.js b/Libraries/Image/__tests__/resolveAssetSource-test.js index b385e29aa..26f3c9ea3 100644 --- a/Libraries/Image/__tests__/resolveAssetSource-test.js +++ b/Libraries/Image/__tests__/resolveAssetSource-test.js @@ -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', () => { expectResolvesAsset({ __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); + }); +}); diff --git a/Libraries/Image/resolveAssetSource.js b/Libraries/Image/resolveAssetSource.js index 2325e2c8c..da136e9a7 100644 --- a/Libraries/Image/resolveAssetSource.js +++ b/Libraries/Image/resolveAssetSource.js @@ -10,6 +10,7 @@ */ 'use strict'; +var PixelRatio = require('PixelRatio'); var SourceCode = require('NativeModules').SourceCode; var _serverURL; @@ -28,6 +29,20 @@ function getServerURL() { 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): // * Pick best scale and append @Nx to file path // * We are currently using httpServerLocation for both http and in-app bundle @@ -57,12 +72,16 @@ function resolveAssetSource(source) { 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(); if (serverURL) { return { width: source.width, height: source.height, - uri: serverURL + path + '/' + source.name + '.' + source.type + + uri: serverURL + path + '/' + fileName + '?hash=' + source.hash, isStatic: false, }; @@ -70,7 +89,7 @@ function resolveAssetSource(source) { return { width: source.width, height: source.height, - uri: path + '/' + source.name + '.' + source.type, + uri: path + '/' + fileName, isStatic: true, }; } @@ -79,3 +98,4 @@ function resolveAssetSource(source) { } module.exports = resolveAssetSource; +module.exports.pickScale = pickScale;