Skip to content

Commit

Permalink
Reducing changes
Browse files Browse the repository at this point in the history
  • Loading branch information
kidroca committed Jan 5, 2023
1 parent 33cb405 commit 38634e0
Show file tree
Hide file tree
Showing 6 changed files with 54 additions and 140 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ exports[`components/Image prop "defaultSource" does not override "height" and "w
exports[`components/Image prop "defaultSource" sets "height" and "width" styles if missing 1`] = `
<div
class="css-view-175oi2r r-flexBasis-1mlwlqe r-overflow-1udh08x r-zIndex-417010"
style="height: 10px; width: 20px;"
style="width: 20px; height: 10px;"
>
<div
class="css-view-175oi2r r-backgroundColor-1niwhzg r-backgroundPosition-vvn4in r-backgroundRepeat-u6sd8q r-bottom-1p0dtai r-height-1pi2tsx r-left-1d2f490 r-position-u8s1d r-right-zchlnj r-top-ipm5af r-width-13qz1uu r-zIndex-1wyyakw r-backgroundSize-4gszlv"
Expand Down Expand Up @@ -329,14 +329,14 @@ exports[`components/Image prop "style" removes other unsupported View styles 1`]
>
<div
class="css-view-175oi2r r-backgroundColor-1niwhzg r-backgroundPosition-vvn4in r-backgroundRepeat-u6sd8q r-bottom-1p0dtai r-height-1pi2tsx r-left-1d2f490 r-position-u8s1d r-right-zchlnj r-top-ipm5af r-width-13qz1uu r-zIndex-1wyyakw r-backgroundSize-4gszlv"
style="filter: url(#tint-98);"
style="filter: url(#tint-97);"
/>
<svg
style="position: absolute; height: 0px; visibility: hidden; width: 0px;"
>
<defs>
<filter
id="tint-98"
id="tint-97"
>
<feflood
flood-color="blue"
Expand Down Expand Up @@ -378,7 +378,7 @@ exports[`components/Image prop "style" supports "tintcolor" property (convert to
>
<div
class="css-view-175oi2r r-backgroundColor-1niwhzg r-backgroundPosition-vvn4in r-backgroundRepeat-u6sd8q r-bottom-1p0dtai r-height-1pi2tsx r-left-1d2f490 r-position-u8s1d r-right-zchlnj r-top-ipm5af r-width-13qz1uu r-zIndex-1wyyakw r-backgroundSize-4gszlv"
style="background-image: url(https://google.com/favicon.ico); filter: url(#tint-96);"
style="background-image: url(https://google.com/favicon.ico); filter: url(#tint-95);"
/>
<img
alt=""
Expand All @@ -391,7 +391,7 @@ exports[`components/Image prop "style" supports "tintcolor" property (convert to
>
<defs>
<filter
id="tint-96"
id="tint-95"
>
<feflood
flood-color="red"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -174,14 +174,12 @@ describe('components/Image', () => {
});

test('is called on update if "headers" are modified', () => {
const onLoadStartStub = jest.fn();
const onLoadStub = jest.fn();
const onLoadEndStub = jest.fn();
const { rerender } = render(
<Image
onLoad={onLoadStub}
onLoadEnd={onLoadEndStub}
onLoadStart={onLoadStartStub}
source={{
uri: 'https://test.com/img.jpg',
headers: { 'x-custom-header': 'abc123' }
Expand All @@ -193,7 +191,6 @@ describe('components/Image', () => {
<Image
onLoad={onLoadStub}
onLoadEnd={onLoadEndStub}
onLoadStart={onLoadStartStub}
source={{
uri: 'https://test.com/img.jpg',
headers: { 'x-custom-header': '123abc' }
Expand Down Expand Up @@ -260,14 +257,12 @@ describe('components/Image', () => {
// This test verifies that when source is declared in-line and the parent component
// re-renders we aren't restarting the load process because the source is structurally equal
test('is not called on update when "headers" and "uri" are not modified', () => {
const onLoadStartStub = jest.fn();
const onLoadStub = jest.fn();
const onLoadEndStub = jest.fn();
const { rerender } = render(
<Image
onLoad={onLoadStub}
onLoadEnd={onLoadEndStub}
onLoadStart={onLoadStartStub}
source={{
uri: 'https://test.com/img.jpg',
width: 1,
Expand All @@ -281,7 +276,6 @@ describe('components/Image', () => {
<Image
onLoad={onLoadStub}
onLoadEnd={onLoadEndStub}
onLoadStart={onLoadStartStub}
source={{
uri: 'https://test.com/img.jpg',
width: 1,
Expand All @@ -297,15 +291,11 @@ describe('components/Image', () => {

test('is not called for default source', () => {
jest.useFakeTimers();
const onLoadStartStub = jest.fn();
const onLoadStub = jest.fn();
const onLoadEndStub = jest.fn();
render(
<Image
defaultSource="https://test.com/img-2.jpg"
onLoad={onLoadStub}
onLoadEnd={onLoadEndStub}
onLoadStart={onLoadStartStub}
source="https://test.com/img.jpg"
/>
);
Expand Down Expand Up @@ -340,7 +330,6 @@ describe('components/Image', () => {
null,
'',
{},
[],
{ uri: '' },
{ uri: 'https://google.com' },
{ uri: 'https://google.com', headers: { 'x-custom-header': 'abc123' } }
Expand Down Expand Up @@ -484,7 +473,7 @@ describe('components/Image', () => {
test('it still loads the image if source object is changed', () => {
ImageLoader.load.mockImplementation(() => {});

const releaseSpy = jest.spyOn(ImageLoader, 'release');
const releaseSpy = jest.spyOn(ImageLoader, 'abort');

const uri = 'https://google.com/favicon.ico';
const { rerender } = render(<Image source={{ uri }} />);
Expand Down
61 changes: 16 additions & 45 deletions packages/react-native-web/src/exports/Image/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,8 @@
* @flow
*/

import type { ImageResult, ImageSource } from '../../modules/ImageLoader';
import type {
ImageLoadingProps,
ImageProps,
Source,
SourceState
} from './types';
import type { ImageSource } from '../../modules/ImageLoader';
import type { ImageProps, Source } from './types';

import * as React from 'react';
import createElement from '../createElement';
Expand Down Expand Up @@ -100,11 +95,6 @@ function getFlatStyle(style, blurRadius, filterId) {
return [flatStyle, resizeMode, _filter, tintColor];
}

function resolveAssetDimensions(source: ImageSource) {
const { height, width } = source;
return { height, width };
}

function resolveSource(source: ?Source): ImageSource {
let resolvedSource = { uri: '' };

Expand Down Expand Up @@ -132,16 +122,8 @@ function resolveSource(source: ?Source): ImageSource {
resolvedSource = { uri, width: asset.width, height: asset.height };
} else if (typeof source === 'string') {
resolvedSource.uri = source;
} else if (Array.isArray(source)) {
if (process.env.NODE_ENV !== 'production') {
console.warn(
'The <Image> component does not support multiple sources passed as array, falling back to the first source in the list',
{ source }
);
}

return resolveSource(source[0]);
} else if (source && typeof source.uri === 'string') {
// $FlowFixMe
const { uri, width, height, headers } = source;
resolvedSource = { uri, width, height, headers };
}
Expand All @@ -159,19 +141,6 @@ function resolveSource(source: ?Source): ImageSource {
return resolvedSource;
}

function getSourceToDisplay(main: SourceState, fallback: SourceState) {
if (main.status === LOADED) return main.source;

// If there's no fallback URI, it's safe to use the main source URI
if (main.status === LOADING && !fallback.source.uri) {
// But it should not be used when the image would be loaded with custom headers
// Because the actual URI is only set (as a local blob url) after loading
if (!main.source.headers) return main.source;
}

return fallback.source;
}

interface ImageStatics {
getSize: (
uri: string,
Expand Down Expand Up @@ -212,7 +181,9 @@ const Image: React.AbstractComponent<
}
}

// Don't raise load events for the fallback source
// Only the main source is supposed to trigger onLoad/start/end events
// It would be ambiguous to trigger the same `onLoad` event when default source loads
// That's why we don't pass `onLoad` props for the fallback source hook
const fallbackSource = useSource({ onError }, defaultSource);
const mainSource = useSource(
{ onLoad, onLoadStart, onLoadEnd, onError },
Expand All @@ -222,15 +193,17 @@ const Image: React.AbstractComponent<
const hasTextAncestor = React.useContext(TextAncestorContext);
const hiddenImageRef = React.useRef(null);
const filterRef = React.useRef(_filterId++);
const shouldDisplaySource =
mainSource.status === LOADED ||
(mainSource.status === LOADING && defaultSource == null);
const [flatStyle, _resizeMode, filter, tintColor] = getFlatStyle(
style,
blurRadius,
filterRef.current
);
const resizeMode = props.resizeMode || _resizeMode || 'cover';
const availableSource = getSourceToDisplay(mainSource, fallbackSource);
const displayImageUri = ImageLoader.resolveUri(availableSource.uri);
const imageSizeStyle = resolveAssetDimensions(availableSource);
const selected = shouldDisplaySource ? mainSource : fallbackSource;
const displayImageUri = selected.source.uri;
const backgroundImage = displayImageUri ? `url("${displayImageUri}")` : null;
const backgroundSize = getBackgroundSize();

Expand Down Expand Up @@ -283,7 +256,7 @@ const Image: React.AbstractComponent<
style={[
styles.root,
hasTextAncestor && styles.inline,
imageSizeStyle,
{ width: selected.source.width, height: selected.source.height },
flatStyle
]}
>
Expand Down Expand Up @@ -326,10 +299,7 @@ ImageWithStatics.queryCache = function (uris) {
/**
* Image loading/state management hook
*/
const useSource = (
callbacks: ImageLoadingProps,
source: ?Source
): SourceState => {
const useSource = (callbacks, source: ?Source) => {
const [resolvedSource, setResolvedSource] = React.useState<ImageSource>(() =>
resolveSource(source)
);
Expand Down Expand Up @@ -369,8 +339,9 @@ const useSource = (
return;
}

// $FlowFixMe
const { onLoad, onLoadStart, onLoadEnd, onError } = callbackRefs.current;
function handleLoad(result: ImageResult) {
function handleLoad(result) {
if (onLoad) onLoad({ nativeEvent: result });
if (onLoadEnd) onLoadEnd();

Expand Down Expand Up @@ -398,7 +369,7 @@ const useSource = (
const requestId = ImageLoader.load(resolvedSource, handleLoad, handleError);

// Release resources on unmount or after starting a new request
return () => ImageLoader.release(requestId);
return () => ImageLoader.abort(requestId);
}, [resolvedSource]);

return { status, source: result };
Expand Down
22 changes: 6 additions & 16 deletions packages/react-native-web/src/exports/Image/types.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
* @flow
*/

import type { ImageResult, ImageSource } from '../../modules/ImageLoader';
import type { ColorValue, GenericStyleProp } from '../../types';
import type { ViewProps } from '../View/types';

Expand Down Expand Up @@ -103,26 +102,17 @@ export type ImageStyle = {
tintColor?: ColorValue
};

export type SourceState = {
status: 'IDLE' | 'LOADING' | 'LOADED' | 'ERRORED',
source: ImageSource
};

export type ImageLoadingProps = {|
onLoad?: (e: { nativeEvent: ImageResult }) => void,
onLoadStart?: () => void,
onLoadEnd?: () => void,
onError?: ({ nativeEvent: { error: string } }) => void,
onProgress?: (e: any) => void
|};

export type ImageProps = {
...$Exact<ViewProps>,
...ImageLoadingProps,
...ViewProps,
blurRadius?: number,
defaultSource?: Source,
draggable?: boolean,
onError?: (e: any) => void,
onLayout?: (e: any) => void,
onLoad?: (e: any) => void,
onLoadEnd?: (e: any) => void,
onLoadStart?: (e: any) => void,
onProgress?: (e: any) => void,
resizeMode?: ResizeMode,
source?: Source,
style?: GenericStyleProp<ImageStyle>
Expand Down
Loading

0 comments on commit 38634e0

Please sign in to comment.