Skip to content

Commit

Permalink
Load XML files on disk by default (#46371)
Browse files Browse the repository at this point in the history
Summary:
X-link: facebook/metro#1348

Pull Request resolved: #46371

## Internal

Vector drawable image support was added in D59530172 but importing vector drawable asset types was not supported out of the box. It required custom source transformers like the one added in D60021474. This is because Android cannot load vector drawable XML over the network. Vector drawables are compiled by AAPT as part of the build process. Even though Metro can serve XML, it would never load.

## Summary

This adds some minor checks in the `AssetSourceResolver` to only attempt loading XML asset types from disk on the Android platform. XML assets like vector drawables are precompiled and cannot be served over the network by Metro.

## Changelog

[Android] [Added] - Adds support for importing XML assets as images

Reviewed By: javache

Differential Revision: D62302929

fbshipit-source-id: 01e49ac5b0429d291318984128dfca2dc058149d
  • Loading branch information
Abbondanzo authored and facebook-github-bot committed Sep 9, 2024
1 parent 40f98b5 commit 2e80f5a
Show file tree
Hide file tree
Showing 4 changed files with 50 additions and 12 deletions.
2 changes: 1 addition & 1 deletion packages/assets/path-support.js
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ function getAndroidResourceIdentifier(asset: PackagerAsset): string {
.toLowerCase()
.replace(/\//g, '_') // Encode folder structure in file name
.replace(/([^a-z0-9_])/g, '') // Remove illegal chars
.replace(/^assets_/, ''); // Remove "assets_" prefix
.replace(/^(?:assets|assetsunstable_path)_/, ''); // Remove "assets_" or "assetsunstable_path_" prefix
}

function getBasePath(asset: PackagerAsset): string {
Expand Down
13 changes: 12 additions & 1 deletion packages/react-native/Libraries/Image/AssetSourceResolver.js
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,13 @@ function getAssetPathInDrawableFolder(asset: PackagerAsset): string {
return drawableFolder + '/' + fileName + '.' + asset.type;
}

/**
* Returns true if the asset can be loaded over the network.
*/
function assetSupportsNetworkLoads(asset: PackagerAsset): boolean {
return !(asset.type === 'xml' && Platform.OS === 'android');
}

class AssetSourceResolver {
serverUrl: ?string;
// where the jsbundle is being run from
Expand All @@ -67,7 +74,11 @@ class AssetSourceResolver {
}

isLoadedFromServer(): boolean {
return !!this.serverUrl;
return (
this.serverUrl != null &&
this.serverUrl !== '' &&
assetSupportsNetworkLoads(this.asset)
);
}

isLoadedFromFileSystem(): boolean {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,29 @@ describe('resolveAssetSource', () => {
},
);
});

it('respects query parameters', () => {
expectResolvesAsset(
{
__packager_asset: true,
fileSystemLocation: '/root/app/assets/module/a',
httpServerLocation: '/assets?unstable_path=./module/a',
width: 100,
height: 200,
scales: [1, 2, 3],
hash: '5b6f00f',
name: 'logo',
type: 'png',
},
{
__packager_asset: true,
width: 100,
height: 200,
uri: 'http://10.0.0.1:8081/assets?unstable_path=./module/a/logo@2x.png?platform=ios&hash=5b6f00f',
scale: 2,
},
);
});
});

describe('bundle was loaded from file on iOS', () => {
Expand Down
24 changes: 14 additions & 10 deletions packages/rn-tester/js/examples/Image/ImageExample.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,9 @@ import type {LayoutEvent} from 'react-native/Libraries/Types/CoreEventTypes';

import * as ReactNativeFeatureFlags from 'react-native/src/private/featureflags/ReactNativeFeatureFlags';

const ImageCapInsetsExample = require('./ImageCapInsetsExample');
const React = require('react');
const {
Image,
ImageBackground,
StyleSheet,
Text,
View,
} = require('react-native');
import ImageCapInsetsExample from './ImageCapInsetsExample';
import React from 'react';
import {Image, ImageBackground, StyleSheet, Text, View} from 'react-native';

const IMAGE1 =
'https://www.facebook.com/assets/fb_lite_messaging/E2EE-settings@3x.png';
Expand Down Expand Up @@ -618,7 +612,9 @@ class VectorDrawableExample extends React.Component<
return (
<View style={styles.flex}>
<Text>Enabled: {isEnabled ? 'true' : 'false'}</Text>
<Image source={{uri: 'ic_android'}} style={{height: 64, width: 64}} />
<View style={styles.vectorDrawableRow}>
<Image source={{uri: 'ic_android'}} style={styles.vectorDrawable} />
</View>
</View>
);
}
Expand Down Expand Up @@ -849,6 +845,14 @@ const styles = StyleSheet.create({
experimental_boxShadow: '80px 0px 10px 0px hotpink',
transform: 'rotate(-15deg)',
},
vectorDrawableRow: {
flexDirection: 'row',
gap: 8,
},
vectorDrawable: {
height: 64,
width: 64,
},
});

exports.displayName = (undefined: ?string);
Expand Down

0 comments on commit 2e80f5a

Please sign in to comment.