Fix: image onLoad props (#2317)

# Summary
Change data structure returned from the Image onLoad event.
Add fix in new arch for returned sizes.

## Test Plan

Manually test in both architectures and platforms.

### What's required for testing (prerequisites)?

### What are the steps to reproduce (after prerequisites)?

## Compatibility

| OS      | Implemented |
| ------- | :---------: |
| iOS     |           |
| Android |        |

---------

Co-authored-by: Jakub Grzywacz <jakub.grzywacz@swmansion.com>
This commit is contained in:
Bohdan Artiukhov
2024-07-02 09:33:25 +02:00
committed by GitHub
parent e16a1519ba
commit 9faa387a98
5 changed files with 42 additions and 30 deletions
+8 -7
View File
@@ -7,12 +7,15 @@ export default function Test1442() {
} }
function TestRNImage() { function TestRNImage() {
const [state, setState] = useState<ImageLoadEventData['source']>(); const [state, setState] = useState<ImageLoadEventData>();
console.log(`${Platform.OS} state:`, state); console.log(`${Platform.OS} state:`, state);
return ( return (
<RNImage <RNImage
style={{width: state?.width || '100%', height: state?.height || '100%'}} style={{
width: state?.source?.width || '100%',
height: state?.source?.height || '100%',
}}
source={{ source={{
uri: 'https://image-placeholder.com/images/actual-size/75x75.png', uri: 'https://image-placeholder.com/images/actual-size/75x75.png',
}} }}
@@ -27,15 +30,13 @@ function TestRNImage() {
); );
} }
function TestWithStrictSize(): React.JSX.Element { function TestWithStrictSize(): React.JSX.Element {
const [state, setState] = useState< const [state, setState] = useState<ImageLoadEventData | undefined>();
ImageLoadEventData['source'] | undefined
>();
console.log(`${Platform.OS} state:`, state); console.log(`${Platform.OS} state:`, state);
return ( return (
<Svg> <Svg>
<Image <Image
width={state?.width || '100%'} width={state?.source?.width || '100%'}
height={state?.height || '100%'} height={state?.source?.height || '100%'}
href={'https://image-placeholder.com/images/actual-size/75x75.png'} href={'https://image-placeholder.com/images/actual-size/75x75.png'}
onLoad={e => { onLoad={e => {
setState(e.nativeEvent); setState(e.nativeEvent);
@@ -42,6 +42,9 @@ public class SvgLoadEvent extends Event<SvgLoadEvent> {
eventData.putDouble("width", width); eventData.putDouble("width", width);
eventData.putDouble("height", height); eventData.putDouble("height", height);
eventData.putString("uri", uri); eventData.putString("uri", uri);
return eventData;
WritableMap event = Arguments.createMap();
event.putMap("source", eventData);
return event;
} }
} }
+23 -16
View File
@@ -133,10 +133,14 @@ using namespace facebook::react;
// See for more info: T46311063. // See for more info: T46311063.
return; return;
} }
auto imageSource = _state->getData().getImageSource(); auto imageSource = _state->getData().getImageSource();
imageSource.size = {image.size.width, image.size.height}; imageSource.size = {image.size.width, image.size.height};
static_cast<const RNSVGImageEventEmitter &>(*_eventEmitter).onLoad({imageSource.size.width, imageSource.size.height, imageSource.uri}); if (_eventEmitter != nullptr) {
static_cast<const RNSVGImageEventEmitter &>(*_eventEmitter).onLoad({.source = {
.width = imageSource.size.width * imageSource.scale,
.height = imageSource.size.height * imageSource.scale,
.uri = imageSource.uri, }});
}
dispatch_async(dispatch_get_main_queue(), ^{ dispatch_async(dispatch_get_main_queue(), ^{
self->_image = CGImageRetain(image.CGImage); self->_image = CGImageRetain(image.CGImage);
self->_imageSize = CGSizeMake(CGImageGetWidth(self->_image), CGImageGetHeight(self->_image)); self->_imageSize = CGSizeMake(CGImageGetWidth(self->_image), CGImageGetHeight(self->_image));
@@ -203,18 +207,21 @@ using namespace facebook::react;
_reloadImageCancellationBlock = [[self.bridge moduleForName:@"ImageLoader"] _reloadImageCancellationBlock = [[self.bridge moduleForName:@"ImageLoader"]
loadImageWithURLRequest:src.request loadImageWithURLRequest:src.request
callback:^(NSError *error, UIImage *image) { callback:^(NSError *error, UIImage *image) {
dispatch_async(dispatch_get_main_queue(), ^{ dispatch_async(dispatch_get_main_queue(), ^{
self->_image = CGImageRetain(image.CGImage); self->_image = CGImageRetain(image.CGImage);
self->_imageSize = CGSizeMake(CGImageGetWidth(self->_image), CGImageGetHeight(self->_image)); self->_imageSize = CGSizeMake(CGImageGetWidth(self->_image), CGImageGetHeight(self->_image));
RCTImageSource *sourceLoaded = [src imageSourceWithSize:image.size scale:image.scale]; if (self->_onLoad) {
self->_onLoad(@{ RCTImageSource *sourceLoaded = [src imageSourceWithSize:image.size scale:image.scale];
@"width" : @(sourceLoaded.size.width), NSDictionary *dict = @{
@"height" : @(sourceLoaded.size.height), @"uri" : sourceLoaded.request.URL.absoluteString,
@"uri" : sourceLoaded.request.URL.absoluteString @"width" : @(sourceLoaded.size.width),
}); @"height" : @(sourceLoaded.size.height),
[self invalidate]; };
}); self->_onLoad(@{@"source" : dict});
}]; }
[self invalidate];
});
}];
#endif // RCT_NEW_ARCH_ENABLED #endif // RCT_NEW_ARCH_ENABLED
} }
+2 -3
View File
@@ -3,15 +3,14 @@ import type {
ImageProps as RNImageProps, ImageProps as RNImageProps,
NativeMethods, NativeMethods,
NativeSyntheticEvent, NativeSyntheticEvent,
ImageLoadEventData,
} from 'react-native'; } from 'react-native';
import { Image } from 'react-native'; import { Image } from 'react-native';
import { alignEnum, meetOrSliceTypes } from '../lib/extract/extractViewBox'; import { alignEnum, meetOrSliceTypes } from '../lib/extract/extractViewBox';
import { withoutXY } from '../lib/extract/extractProps'; import { withoutXY } from '../lib/extract/extractProps';
import type { CommonPathProps, NumberProp } from '../lib/extract/types'; import type { CommonPathProps, NumberProp } from '../lib/extract/types';
import Shape from './Shape'; import Shape from './Shape';
import RNSVGImage, { import RNSVGImage from '../fabric/ImageNativeComponent';
type ImageLoadEventData,
} from '../fabric/ImageNativeComponent';
const spacesRegExp = /\s+/; const spacesRegExp = /\s+/;
+5 -3
View File
@@ -16,9 +16,11 @@ import type { UnsafeMixed } from './codegenUtils';
import { NumberProp } from '../lib/extract/types'; import { NumberProp } from '../lib/extract/types';
export type ImageLoadEventData = { export type ImageLoadEventData = {
width: Float; source: {
height: Float; width: Float;
uri: string; height: Float;
uri: string;
};
}; };
interface SvgNodeCommonProps { interface SvgNodeCommonProps {