Skip to content

Commit 5488259

Browse files
committed
fix: provideEmbeddedHeaders results in failing fetch for img
fix #533
1 parent 8f98f8a commit 5488259

File tree

9 files changed

+119
-101
lines changed

9 files changed

+119
-101
lines changed

packages/render-html/src/__mocks__/react-native.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,11 +32,11 @@ export class Image extends RNImage {
3232
* be extracted, it will use 640x360.
3333
*/
3434
static getSizeWithHeaders(uri, headers, success, failure) {
35-
getSizeWithHeaders(uri, headers, callback, failure);
35+
getSizeWithHeaders(uri, headers, success, failure);
3636
}
3737

38-
static getSize(uri, callback, failure) {
39-
getSizeWithHeaders(uri, undefined, callback, failure);
38+
static getSize(uri, success, failure) {
39+
getSizeWithHeaders(uri, undefined, success, failure);
4040
}
4141
}
4242

packages/render-html/src/__tests__/component.render-html.test.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -856,7 +856,9 @@ describe('RenderHTML', () => {
856856
expect(image.props.source.headers).toBe(headers);
857857
expect(getSizeWithHeaders).toHaveBeenCalledWith(
858858
'https://custom.domain/',
859-
headers
859+
headers,
860+
expect.anything(),
861+
expect.anything()
860862
);
861863
});
862864
});

packages/render-html/src/elements/getIMGState.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ interface GetStateProps<C> extends Omit<IMGElementStateBase, 'dimensions'> {
1414
error: Error | null;
1515
initialDimensions: ImageDimensions;
1616
objectFit: UseIMGElementStateProps['objectFit'];
17-
onError: (e: Error) => void;
17+
onError?: (e: Error) => void;
1818
}
1919

2020
export function getIMGState(

packages/render-html/src/elements/img-types.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,3 +154,11 @@ export interface IMGElementStateError extends IMGElementStateBase {
154154
error: Error;
155155
type: 'error';
156156
}
157+
158+
/**
159+
* Partial image dimensions.
160+
*/
161+
export interface IncompleteImageDimensions {
162+
height: number | null;
163+
width: number | null;
164+
}

packages/render-html/src/elements/useIMGElementState.ts

Lines changed: 62 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,16 @@
1-
import { useEffect } from 'react';
2-
import { Image } from 'react-native';
3-
import type { UseIMGElementStateProps, IMGElementState } from './img-types';
4-
import useImageNaturalDimensions from './useImageNaturalDimensions';
5-
import useImageConcreteDimensions from './useImageConcreteDimensions';
1+
import { useEffect, useState } from 'react';
2+
import { Image, ImageURISource } from 'react-native';
3+
import {
4+
UseIMGElementStateProps,
5+
IMGElementState,
6+
IncompleteImageDimensions
7+
} from './img-types';
68
import defaultImageInitialDimensions from './defaultInitialImageDimensions';
9+
import useIMGNormalizedSource from './useIMGNormalizedSource';
710
import { ImageDimensions } from '../shared-types';
11+
import useImageConcreteDimensions from './useImageConcreteDimensions';
812
import { getIMGState } from './getIMGState';
9-
import useIMGNormalizedSource from './useIMGNormalizedSource';
13+
import useImageSpecifiedDimensions from './useImageSpecifiedDimensions';
1014

1115
function getImageSizeAsync({
1216
uri,
@@ -26,16 +30,47 @@ function getImageSizeAsync({
2630
});
2731
}
2832

29-
function useFetchedNaturalDimensions(props: UseIMGElementStateProps) {
33+
function useImageNaturalDimensions<P extends UseIMGElementStateProps>(props: {
34+
cachedNaturalDimensions?: ImageDimensions;
35+
source: ImageURISource;
36+
specifiedDimensions: IncompleteImageDimensions;
37+
}) {
3038
const { source, cachedNaturalDimensions } = props;
31-
const {
32-
error,
33-
flatStyle,
39+
const [naturalDimensions, setNaturalDimensions] = useState<
40+
P['cachedNaturalDimensions'] extends ImageDimensions
41+
? ImageDimensions
42+
: ImageDimensions | null
43+
>((cachedNaturalDimensions as any) || null);
44+
const { width: cachedNaturalWidth, height: cachedNaturalHeight } =
45+
cachedNaturalDimensions || {};
46+
const [error, setError] = useState<null | Error>(null);
47+
useEffect(
48+
function resetOnURIChange() {
49+
setNaturalDimensions(
50+
(cachedNaturalWidth != null && cachedNaturalHeight != null
51+
? { width: cachedNaturalWidth, height: cachedNaturalHeight }
52+
: null) as any
53+
);
54+
setError(null);
55+
},
56+
[cachedNaturalHeight, cachedNaturalWidth, source.uri]
57+
);
58+
return {
59+
onNaturalDimensions: setNaturalDimensions,
60+
onError: setError,
3461
naturalDimensions,
35-
specifiedDimensions,
36-
onError,
37-
onNaturalDimensions
38-
} = useImageNaturalDimensions(props);
62+
error
63+
};
64+
}
65+
66+
function useFetchedNaturalDimensions(props: {
67+
cachedNaturalDimensions?: ImageDimensions;
68+
source: ImageURISource;
69+
specifiedDimensions: IncompleteImageDimensions;
70+
}) {
71+
const { source, cachedNaturalDimensions } = props;
72+
const { error, naturalDimensions, onError, onNaturalDimensions } =
73+
useImageNaturalDimensions(props);
3974
const hasCachedDimensions = !!cachedNaturalDimensions;
4075
useEffect(
4176
function fetchPhysicalDimensions() {
@@ -58,8 +93,6 @@ function useFetchedNaturalDimensions(props: UseIMGElementStateProps) {
5893
]
5994
);
6095
return {
61-
specifiedDimensions,
62-
flatStyle,
6396
naturalDimensions,
6497
error,
6598
onError,
@@ -85,21 +118,27 @@ export default function useIMGElementState(
85118
contentWidth,
86119
computeMaxWidth,
87120
objectFit,
88-
initialDimensions = defaultImageInitialDimensions
121+
initialDimensions = defaultImageInitialDimensions,
122+
cachedNaturalDimensions
89123
} = props;
90-
const { naturalDimensions, specifiedDimensions, flatStyle, onError, error } =
91-
useFetchedNaturalDimensions(props);
124+
const { flatStyle, specifiedDimensions } = useImageSpecifiedDimensions(props);
125+
const nomalizedSource = useIMGNormalizedSource({
126+
specifiedDimensions,
127+
source
128+
});
129+
const { naturalDimensions, onError, error } = useFetchedNaturalDimensions({
130+
source: nomalizedSource,
131+
specifiedDimensions,
132+
cachedNaturalDimensions
133+
});
92134
const concreteDimensions = useImageConcreteDimensions({
93135
flatStyle,
94136
naturalDimensions,
95137
specifiedDimensions,
96138
computeMaxWidth,
97139
contentWidth
98140
});
99-
const nomalizedSource = useIMGNormalizedSource({
100-
concreteDimensions,
101-
source
102-
});
141+
103142
return getIMGState({
104143
error,
105144
alt,

packages/render-html/src/elements/useIMGElementStateWithCache.ts

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import type {
66
IMGElementStateSuccess
77
} from './img-types';
88
import useImageConcreteDimensions from './useImageConcreteDimensions';
9-
import useImageNaturalDimensions from './useImageNaturalDimensions';
9+
import useImageSpecifiedDimensions from './useImageSpecifiedDimensions';
1010
import useIMGNormalizedSource from './useIMGNormalizedSource';
1111

1212
/**
@@ -24,28 +24,28 @@ export default function useIMGElementStateWithCache(
2424
contentWidth,
2525
computeMaxWidth,
2626
objectFit,
27-
initialDimensions = defaultImageInitialDimensions
27+
initialDimensions = defaultImageInitialDimensions,
28+
cachedNaturalDimensions
2829
} = props;
29-
const { naturalDimensions, specifiedDimensions, flatStyle, error, onError } =
30-
useImageNaturalDimensions(props);
30+
const { flatStyle, specifiedDimensions } = useImageSpecifiedDimensions(props);
31+
const nomalizedSource = useIMGNormalizedSource({
32+
specifiedDimensions,
33+
source
34+
});
3135
const concreteDimensions = useImageConcreteDimensions({
3236
flatStyle,
33-
naturalDimensions,
37+
naturalDimensions: cachedNaturalDimensions,
3438
specifiedDimensions,
3539
computeMaxWidth,
3640
contentWidth
3741
});
38-
const nomalizedSource = useIMGNormalizedSource({
39-
concreteDimensions,
40-
source
41-
});
42+
4243
return getIMGState({
43-
error,
44+
error: null,
4445
concreteDimensions,
4546
containerStyle: flatStyle,
4647
initialDimensions,
4748
objectFit,
48-
onError,
4949
source: nomalizedSource,
5050
alt,
5151
altColor

packages/render-html/src/elements/useIMGNormalizedSource.ts

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,23 @@
11
import { useMemo, useRef } from 'react';
22
import { useSharedProps } from '../context/SharedPropsProvider';
3-
import { ImageDimensions } from '../shared-types';
4-
import { UseIMGElementStateProps } from './img-types';
3+
import {
4+
IncompleteImageDimensions,
5+
UseIMGElementStateProps
6+
} from './img-types';
57

68
export default function useIMGNormalizedSource({
79
source,
8-
concreteDimensions
10+
specifiedDimensions
911
}: Pick<UseIMGElementStateProps, 'source'> & {
10-
concreteDimensions: ImageDimensions | null;
12+
specifiedDimensions: IncompleteImageDimensions;
1113
}) {
12-
const cachedDimensions = useRef(concreteDimensions);
14+
const cachedDimensions = useRef(specifiedDimensions);
1315
const { provideEmbeddedHeaders } = useSharedProps();
1416
return useMemo(() => {
1517
if (source.uri && typeof provideEmbeddedHeaders === 'function') {
1618
const headers = provideEmbeddedHeaders(source.uri, 'img', {
17-
printWidth: cachedDimensions.current?.width,
18-
printHeight: cachedDimensions.current?.height
19+
printWidth: cachedDimensions.current?.width || undefined,
20+
printHeight: cachedDimensions.current?.height || undefined
1921
});
2022
if (headers) {
2123
return {

packages/render-html/src/elements/useImageConcreteDimensions.ts

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,16 @@
11
import { useMemo } from 'react';
2+
import { ImageStyle } from 'react-native';
23
import { ImageDimensions } from '../shared-types';
3-
import { UseIMGElementStateProps } from './img-types';
4-
import useImageNaturalDimensions from './useImageNaturalDimensions';
4+
import {
5+
IncompleteImageDimensions,
6+
UseIMGElementStateProps
7+
} from './img-types';
58

6-
export type ConcreteDimensionsProps = Pick<
7-
ReturnType<typeof useImageNaturalDimensions>,
8-
'flatStyle' | 'naturalDimensions' | 'specifiedDimensions'
9-
> &
10-
Pick<UseIMGElementStateProps, 'computeMaxWidth' | 'contentWidth'>;
9+
export type ConcreteDimensionsProps = {
10+
flatStyle: ImageStyle;
11+
naturalDimensions: ImageDimensions | null;
12+
specifiedDimensions: IncompleteImageDimensions;
13+
} & Pick<UseIMGElementStateProps, 'computeMaxWidth' | 'contentWidth'>;
1114

1215
function extractHorizontalSpace({
1316
marginHorizontal,

packages/render-html/src/elements/useImageNaturalDimensions.ts renamed to packages/render-html/src/elements/useImageSpecifiedDimensions.ts

Lines changed: 12 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,10 @@
1-
import { useState, useMemo, useEffect } from 'react';
2-
import { StyleSheet } from 'react-native';
3-
import { ImageDimensions } from '../shared-types';
1+
import { useMemo } from 'react';
2+
import {
3+
UseIMGElementStateProps,
4+
IncompleteImageDimensions
5+
} from './img-types';
46
import getDimensionsWithAspectRatio from './getDimensionsWithAspectRatio';
5-
import { UseIMGElementStateProps } from './img-types';
6-
7-
interface IncompleteImageDimensions {
8-
height: number | null;
9-
width: number | null;
10-
}
7+
import { StyleSheet } from 'react-native';
118

129
function normalizeSize(
1310
dimension: string | number | null | undefined,
@@ -71,26 +68,12 @@ function deriveSpecifiedDimensionsFromProps({
7168
);
7269
}
7370

74-
export default function useImageNaturalDimensions<
75-
P extends UseIMGElementStateProps
76-
>(props: P) {
77-
const {
78-
source,
79-
contentWidth,
80-
enableExperimentalPercentWidth,
81-
width,
82-
height,
83-
style,
84-
cachedNaturalDimensions
85-
} = props;
86-
const [naturalDimensions, setNaturalDimensions] = useState<
87-
P['cachedNaturalDimensions'] extends ImageDimensions
88-
? ImageDimensions
89-
: ImageDimensions | null
90-
>((cachedNaturalDimensions as any) || null);
71+
export default function useImageSpecifiedDimensions(
72+
props: UseIMGElementStateProps
73+
) {
74+
const { contentWidth, enableExperimentalPercentWidth, style, width, height } =
75+
props;
9176
const flatStyle = useMemo(() => StyleSheet.flatten(style) || {}, [style]);
92-
const { width: cachedNaturalWidth, height: cachedNaturalHeight } =
93-
cachedNaturalDimensions || {};
9477
const specifiedDimensions = useMemo(
9578
() =>
9679
deriveSpecifiedDimensionsFromProps({
@@ -102,24 +85,5 @@ export default function useImageNaturalDimensions<
10285
}),
10386
[contentWidth, enableExperimentalPercentWidth, flatStyle, height, width]
10487
);
105-
const [error, setError] = useState<null | Error>(null);
106-
useEffect(
107-
function resetOnURIChange() {
108-
setNaturalDimensions(
109-
(cachedNaturalWidth != null && cachedNaturalHeight != null
110-
? { width: cachedNaturalWidth, height: cachedNaturalHeight }
111-
: null) as any
112-
);
113-
setError(null);
114-
},
115-
[cachedNaturalHeight, cachedNaturalWidth, source.uri]
116-
);
117-
return {
118-
onNaturalDimensions: setNaturalDimensions,
119-
onError: setError,
120-
naturalDimensions,
121-
specifiedDimensions,
122-
flatStyle,
123-
error
124-
};
88+
return { flatStyle, specifiedDimensions };
12589
}

0 commit comments

Comments
 (0)