Files
Schnappix/node_modules/expo-image/src/ExpoImage.tsx
T
2026-05-31 20:50:37 +02:00

125 lines
4.0 KiB
TypeScript

import { requireNativeViewManager } from 'expo-modules-core';
import React from 'react';
import { NativeSyntheticEvent, StyleSheet, Platform, processColor } from 'react-native';
import {
ImageErrorEventData,
ImageLoadEventData,
ImageNativeProps,
ImageProgressEventData,
} from './Image.types';
const NativeExpoImage = requireNativeViewManager('ExpoImage');
function withDeprecatedNativeEvent<NativeEvent>(
event: NativeSyntheticEvent<NativeEvent>
): NativeEvent {
Object.defineProperty(event.nativeEvent, 'nativeEvent', {
get() {
console.warn(
'[expo-image]: Accessing event payload through "nativeEvent" is deprecated, it is now part of the event object itself'
);
return event.nativeEvent;
},
});
return event.nativeEvent;
}
class ExpoImage extends React.PureComponent<ImageNativeProps> {
// NOTE(@kitten): native methods
startAnimating!: () => Promise<unknown> | unknown;
stopAnimating!: () => Promise<unknown> | unknown;
lockResourceAsync!: () => Promise<void>;
unlockResourceAsync!: () => Promise<void>;
reloadAsync!: () => Promise<void>;
onLoadStart = () => {
this.props.onLoadStart?.();
};
onLoad = (event: NativeSyntheticEvent<ImageLoadEventData>) => {
this.props.onLoad?.(withDeprecatedNativeEvent(event));
this.onLoadEnd();
};
onProgress = (event: NativeSyntheticEvent<ImageProgressEventData>) => {
this.props.onProgress?.(withDeprecatedNativeEvent(event));
};
onError = (event: NativeSyntheticEvent<ImageErrorEventData>) => {
this.props.onError?.(withDeprecatedNativeEvent(event));
this.onLoadEnd();
};
onLoadEnd = () => {
this.props.onLoadEnd?.();
};
render() {
const { style, accessibilityLabel, alt, ...props } = this.props;
const resolvedStyle = StyleSheet.flatten(style);
// Shadows behave different on iOS, Android & Web.
// Android uses the `elevation` prop, whereas iOS
// and web use the regular `shadow...` props.
if (Platform.OS === 'android') {
delete resolvedStyle.shadowColor;
delete resolvedStyle.shadowOffset;
delete resolvedStyle.shadowOpacity;
delete resolvedStyle.shadowRadius;
} else {
// @ts-expect-error
delete resolvedStyle.elevation;
}
// @ts-ignore
const backgroundColor = processColor(resolvedStyle.backgroundColor);
// On Android, we have to set the `backgroundColor` directly on the correct component.
// So we have to remove it from styles. Otherwise, the background color won't take into consideration the border-radius.
if (Platform.OS === 'android') {
delete resolvedStyle.backgroundColor;
}
const tintColor = processColor(props.tintColor || resolvedStyle.tintColor);
const borderColor = processColor(resolvedStyle.borderColor);
// @ts-ignore
const borderStartColor = processColor(resolvedStyle.borderStartColor);
// @ts-ignore
const borderEndColor = processColor(resolvedStyle.borderEndColor);
// @ts-ignore
const borderLeftColor = processColor(resolvedStyle.borderLeftColor);
// @ts-ignore
const borderRightColor = processColor(resolvedStyle.borderRightColor);
// @ts-ignore
const borderTopColor = processColor(resolvedStyle.borderTopColor);
// @ts-ignore
const borderBottomColor = processColor(resolvedStyle.borderBottomColor);
return (
<NativeExpoImage
{...props}
{...resolvedStyle}
accessibilityLabel={accessibilityLabel ?? alt}
style={resolvedStyle}
onLoadStart={this.onLoadStart}
onLoad={this.onLoad}
onProgress={this.onProgress}
onError={this.onError}
tintColor={tintColor}
borderColor={borderColor}
borderLeftColor={borderLeftColor}
borderRightColor={borderRightColor}
borderTopColor={borderTopColor}
borderBottomColor={borderBottomColor}
borderStartColor={borderStartColor}
borderEndColor={borderEndColor}
backgroundColor={backgroundColor}
ref={props.nativeViewRef}
/>
);
}
}
export default ExpoImage;