Skip to content

Commit 1d8f8db

Browse files
Merge pull request #1123 from GetStream/vishal/resize-image-url-fix
fix: fixing logic for resizing image url
2 parents 001c9c8 + 1929dc5 commit 1d8f8db

File tree

7 files changed

+281
-190
lines changed

7 files changed

+281
-190
lines changed

package/package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@
8080
"path": "0.12.7",
8181
"react-art": "^17.0.2",
8282
"react-native-markdown-package": "1.8.1",
83+
"react-native-url-polyfill": "^1.3.0",
8384
"stream-chat": "6.0.0"
8485
},
8586
"peerDependencies": {
@@ -144,4 +145,4 @@
144145
"uuid": "8.3.2",
145146
"webpack": "4.44.2"
146147
}
147-
}
148+
}

package/src/components/Attachment/__tests__/buildGallery.test.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ describe('buildGallery', () => {
9797
it('thumbnail size should be smaller than the limits set by sizeConfig', () => {
9898
const bigImage = generateImageAttachment({
9999
image_url:
100-
'https://stream-io.cdn.com/23kn4k2j3n4k2n3k4n23?sig=34k23n4k23nk423&h=*&w=*&resize=*',
100+
'https://us-east.stream-io-cdn.com/23kn4k2j3n4k2n3k4n23?sig=34k23n4k23nk423&h=*&w=*&resize=*',
101101
original_height: 1200,
102102
original_width: 900,
103103
});
@@ -107,13 +107,13 @@ describe('buildGallery', () => {
107107
sizeConfig: defaultSizeConfig,
108108
});
109109
const t1 = tg1[0][0];
110-
expect(t1.url.includes(`h=${PixelRatio.getPixelSizeForLayoutSize(t1.height)}`)).toBe(true);
110+
expect(t1.url.includes(`&h=${PixelRatio.getPixelSizeForLayoutSize(t1.height)}`)).toBe(true);
111111
expect(t1.url.includes(`&w=${PixelRatio.getPixelSizeForLayoutSize(t1.width)}`)).toBe(true);
112112
expect(t1.url.includes(`&resize=clip`)).toBe(true);
113113

114114
const smallImage = generateImageAttachment({
115115
image_url:
116-
'https://stream-io.cdn.com/23kn4k2j3n4k2n3k4n23?sig=34k23n4k23nk423&h=*&w=*&resize=*',
116+
'https://us-east.stream-io-cdn.com/23kn4k2j3n4k2n3k4n23?sig=34k23n4k23nk423&h=*&w=*&resize=*',
117117
original_height: 30,
118118
original_width: 20,
119119
});
@@ -124,7 +124,7 @@ describe('buildGallery', () => {
124124
});
125125

126126
const t2 = tg2[0][0];
127-
expect(t2.url.includes(`h=*`)).toBe(true);
127+
expect(t2.url.includes(`&h=*`)).toBe(true);
128128
expect(t2.url.includes(`&w=*`)).toBe(true);
129129
expect(t2.url.includes(`&resize=*`)).toBe(true);
130130
});

package/src/components/Chat/Chat.tsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,15 @@ import {
1818
TranslationProvider,
1919
} from '../../contexts/translationContext/TranslationContext';
2020
import { useStreami18n } from '../../hooks/useStreami18n';
21+
import init from '../../init';
2122

2223
import { SDK } from '../../native';
2324
import type { DefaultStreamChatGenerics } from '../../types/types';
2425
import type { Streami18n } from '../../utils/Streami18n';
2526
import { version } from '../../version.json';
2627

28+
init();
29+
2730
export type ChatProps<
2831
StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics,
2932
> = Pick<ChatContextValue<StreamChatGenerics>, 'client'> & {

package/src/init.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
import { setupURLPolyfill } from 'react-native-url-polyfill';
2+
3+
export default () => {
4+
setupURLPolyfill();
5+
};
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
import { PixelRatio } from 'react-native';
2+
3+
import { getResizedImageUrl } from '../getResizedImageUrl';
4+
5+
describe('getResizedImageUrl', () => {
6+
it('should return same url if its not cloudfront cdn', () => {
7+
const testUrl = 'http://foo.com/blah_(wikipedia)#cite-1';
8+
9+
const resizedUrl = getResizedImageUrl({ height: 100, url: testUrl, width: 100 });
10+
expect(resizedUrl).toEqual(testUrl);
11+
});
12+
13+
it('should append given height, width and resize mode to url', () => {
14+
const testUrl = 'http://us-east.stream-io-cdn.com/blah';
15+
16+
const testConfigs = [
17+
{ height: 100, resize: 'scale', width: 100 },
18+
{ height: 200, resize: 'fill', width: 300 },
19+
{ height: 1000, resize: 'clip', width: 10 },
20+
];
21+
22+
testConfigs.forEach(({ height, resize, width }) => {
23+
const resizedUrl = getResizedImageUrl({ height, resize, url: testUrl, width });
24+
const parsedUrl = new URL(resizedUrl);
25+
expect(parsedUrl.searchParams.get('h')).toEqual(
26+
`${PixelRatio.getPixelSizeForLayoutSize(height)}`,
27+
);
28+
expect(parsedUrl.searchParams.get('w')).toEqual(
29+
`${PixelRatio.getPixelSizeForLayoutSize(width)}`,
30+
);
31+
expect(parsedUrl.searchParams.get('resize')).toEqual(resize);
32+
});
33+
});
34+
35+
it('should replace wildcards with given height, width and resize mode within url', () => {
36+
const testUrl = 'http://us-east.stream-io-cdn.com/blah?h=*&w=*&resize=*';
37+
38+
const testConfigs = [
39+
{ height: 100, resize: 'scale', width: 100 },
40+
{ height: 200, resize: 'fill', width: 300 },
41+
{ height: 1000, resize: 'clip', width: 10 },
42+
];
43+
44+
testConfigs.forEach(({ height, resize, width }) => {
45+
const resizedUrl = getResizedImageUrl({ height, resize, url: testUrl, width });
46+
const parsedUrl = new URL(resizedUrl);
47+
expect(parsedUrl.searchParams.get('h')).toEqual(
48+
`${PixelRatio.getPixelSizeForLayoutSize(height)}`,
49+
);
50+
expect(parsedUrl.searchParams.get('w')).toEqual(
51+
`${PixelRatio.getPixelSizeForLayoutSize(width)}`,
52+
);
53+
expect(parsedUrl.searchParams.get('resize')).toEqual(resize);
54+
});
55+
});
56+
});

package/src/utils/getResizedImageUrl.ts

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { PixelRatio } from 'react-native';
33
type GetResizedImageUrlParams = {
44
url: string;
55
height?: string | number;
6+
resize?: 'clip' | 'crop' | 'fill' | 'scale';
67
width?: string | number;
78
};
89

@@ -18,26 +19,27 @@ type GetResizedImageUrlParams = {
1819
*
1920
* @returns {string} Url of the image with given height and width.
2021
*/
21-
export function getResizedImageUrl({ height, url, width }: GetResizedImageUrlParams) {
22-
const isResizableUrl = url.includes('&h=*') && url.includes('&w=*') && url.includes('&resize=*');
23-
22+
export function getResizedImageUrl({
23+
height,
24+
resize = 'clip',
25+
url,
26+
width,
27+
}: GetResizedImageUrlParams) {
28+
// Check if url belongs to cloudfront CDN
29+
const isResizableUrl = url.includes('.stream-io-cdn.com');
2430
if (!isResizableUrl || (!height && !width)) return url;
2531

26-
let resizedUrl = url;
32+
const parsedUrl = new URL(url);
2733

2834
if (height) {
29-
resizedUrl = resizedUrl.replace(
30-
'h=*',
31-
`h=${PixelRatio.getPixelSizeForLayoutSize(Number(height))}`,
32-
);
35+
parsedUrl.searchParams.set('h', `${PixelRatio.getPixelSizeForLayoutSize(Number(height))}`);
3336
}
3437

3538
if (width) {
36-
resizedUrl = resizedUrl.replace(
37-
'w=*',
38-
`w=${PixelRatio.getPixelSizeForLayoutSize(Number(width))}`,
39-
);
39+
parsedUrl.searchParams.set('w', `${PixelRatio.getPixelSizeForLayoutSize(Number(width))}`);
4040
}
4141

42-
return resizedUrl.replace('resize=*', `resize=clip`);
42+
parsedUrl.searchParams.set('resize', `${resize}`);
43+
44+
return parsedUrl.toString();
4345
}

0 commit comments

Comments
 (0)