Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions packages/react-native/Libraries/Image/Image.android.js
Original file line number Diff line number Diff line change
Expand Up @@ -256,14 +256,14 @@ if (ReactNativeFeatureFlags.reduceDefaultPropsInImage()) {
}

if (defaultSource_ != null && defaultSource_.uri != null) {
nativeProps.defaultSource = defaultSource_.uri;
nativeProps.defaultSource = defaultSource_;
}

if (
loadingIndicatorSource_ != null &&
loadingIndicatorSource_.uri != null
) {
nativeProps.loadingIndicatorSrc = loadingIndicatorSource_.uri;
nativeProps.loadingIndicatorSrc = loadingIndicatorSource_;
}

if (ariaLabel != null) {
Expand Down Expand Up @@ -395,9 +395,9 @@ if (ReactNativeFeatureFlags.reduceDefaultPropsInImage()) {
/* $FlowFixMe[prop-missing](>=0.78.0 site=react_native_android_fb) This issue was found
* when making Flow check .android.js files. */
headers: (source?.[0]?.headers || source?.headers: ?{[string]: string}),
defaultSource: defaultSource ? defaultSource.uri : null,
defaultSource: defaultSource ? defaultSource : null,
loadingIndicatorSrc: loadingIndicatorSource
? loadingIndicatorSource.uri
? loadingIndicatorSource
: null,
accessibilityLabel:
props['aria-label'] ?? props.accessibilityLabel ?? props.alt,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ type ImageHostComponentProps = Readonly<{
src?: ?ResolvedAssetSource | ?ReadonlyArray<?Readonly<{uri?: ?string, ...}>>,
headers?: ?{[string]: string},
defaultSource?: ?ImageSource | ?string,
loadingIndicatorSrc?: ?string,
loadingIndicatorSrc?: ?ImageSource | ?string,
}>;

interface NativeCommands {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,9 @@ describe('<Image>', () => {
root.getRenderedOutput({props: ['defaultSource']}).toJSX(),
).toEqual(
<rn-image
defaultSource-type="remote"
defaultSource-type="local"
defaultSource-scale="1"
defaultSource-size="{1, 1}"
defaultSource-uri="file://drawable-mdpi/packages_reactnative_libraries_image___tests___img_img1.png"
/>,
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -133,13 +133,13 @@ public constructor(
}

@ReactProp(name = "defaultSource")
public fun setDefaultSource(view: ReactImageView, source: String?) {
public fun setDefaultSource(view: ReactImageView, source: ReadableMap?) {
view.setDefaultSource(source)
}

// In JS this is Image.props.loadingIndicatorSource.uri
@ReactProp(name = "loadingIndicatorSrc")
public fun setLoadingIndicatorSource(view: ReactImageView, source: String?) {
public fun setLoadingIndicatorSource(view: ReactImageView, source: ReadableMap?) {
view.setLoadingIndicatorSource(source)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,9 +44,11 @@ import com.facebook.imagepipeline.request.ImageRequest
import com.facebook.imagepipeline.request.ImageRequest.RequestLevel
import com.facebook.imagepipeline.request.ImageRequestBuilder
import com.facebook.imagepipeline.request.Postprocessor
import com.facebook.react.BuildConfig
import com.facebook.react.bridge.ReactContext
import com.facebook.react.bridge.ReadableArray
import com.facebook.react.bridge.ReadableMap
import com.facebook.react.bridge.SoftAssertions
import com.facebook.react.common.annotations.UnstableReactNativeAPI
import com.facebook.react.common.annotations.VisibleForTesting
import com.facebook.react.common.build.ReactBuildConfig
Expand Down Expand Up @@ -281,29 +283,12 @@ public class ReactImageView(
} else if (sources.size() == 1) {
// Optimize for the case where we have just one uri, case in which we don't need the sizes
val source = checkNotNull(sources.getMap(0))
val cacheControl = computeCacheControl(source.getString("cache"))
var imageSource = ImageSource(context, source.getString("uri"), cacheControl = cacheControl)
if (Uri.EMPTY == imageSource.uri) {
warnImageSource(source.getString("uri"))
imageSource = getTransparentBitmapImageSource(context)
}
val imageSource = readableMapToImageSource(source, includeSize = false)
tmpSources.add(imageSource)
} else {
for (idx in 0 until sources.size()) {
val source = sources.getMap(idx) ?: continue
val cacheControl = computeCacheControl(source.getString("cache"))
var imageSource =
ImageSource(
context,
source.getString("uri"),
source.getDouble("width"),
source.getDouble("height"),
cacheControl,
)
if (Uri.EMPTY == imageSource.uri) {
warnImageSource(source.getString("uri"))
imageSource = getTransparentBitmapImageSource(context)
}
val imageSource = readableMapToImageSource(source, includeSize = true)
tmpSources.add(imageSource)
}
}
Expand Down Expand Up @@ -336,16 +321,36 @@ public class ReactImageView(
}
}

public fun setDefaultSource(name: String?) {
val newDefaultDrawable = ResourceDrawableIdHelper.getResourceDrawable(context, name)
public fun setDefaultSource(source: ReadableMap?) {
var newDefaultDrawable: Drawable? = null
if (source != null) {
val imageSource = readableMapToImageSource(source, false)
SoftAssertions.assertCondition(
!BuildConfig.DEBUG && !imageSource.isResource,
"ReactImageView: Only local resources can be used as default image. Uri: ${imageSource.uri}"
)

newDefaultDrawable = ResourceDrawableIdHelper.getResourceDrawable(context, imageSource.source)
}

if (defaultImageDrawable != newDefaultDrawable) {
defaultImageDrawable = newDefaultDrawable
isDirty = true
}
}

public fun setLoadingIndicatorSource(name: String?) {
val drawable = ResourceDrawableIdHelper.getResourceDrawable(context, name)
public fun setLoadingIndicatorSource(source: ReadableMap?) {
var drawable: Drawable? = null
if (source != null) {
val imageSource = readableMapToImageSource(source, false)
SoftAssertions.assertCondition(
!BuildConfig.DEBUG && !imageSource.isResource,
"ReactImageView: Only local resources can be used as default image. Uri: ${imageSource.uri}"
)

drawable = ResourceDrawableIdHelper.getResourceDrawable(context, imageSource.source)
}

val newLoadingIndicatorSource = drawable?.let { AutoRotateDrawable(it, 1000) }
if (loadingImageDrawable != newLoadingIndicatorSource) {
loadingImageDrawable = newLoadingIndicatorSource
Expand Down Expand Up @@ -555,6 +560,29 @@ public class ReactImageView(
private val isTiled: Boolean
get() = tileMode != TileMode.CLAMP

private fun readableMapToImageSource(source: ReadableMap, includeSize: Boolean = false): ImageSource {
val cacheControl = computeCacheControl(source.getString("cache"))
val uri = source.getString("uri")
var imageSource = if (includeSize) {
ImageSource(
context,
uri,
source.getDouble("width"),
source.getDouble("height"),
cacheControl,
)
} else {
ImageSource(context, uri, cacheControl = cacheControl)
}

if (Uri.EMPTY == imageSource.uri) {
warnImageSource(uri)
imageSource = getTransparentBitmapImageSource(context)
}

return imageSource
}

private fun setSourceImage() {
imageSource = null
if (sources.isEmpty()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,9 +66,8 @@ class ImageSource {
imageSourceResult["scale"] = scale;

folly::dynamic sizeResult = folly::dynamic::object();
sizeResult["width"] = size.width;
sizeResult["height"] = size.height;
imageSourceResult["size"] = sizeResult;
imageSourceResult["width"] = size.width;
imageSourceResult["height"] = size.height;

imageSourceResult["body"] = body;
imageSourceResult["method"] = method;
Expand Down
Loading