Skip to content

Commit 90c87da

Browse files
authored
Merge pull request #1201 from GetStream/santhosh/giphy-size-customisation-crns-514
feat: add giphy size customisation [CRNS-514]
2 parents 3d0cbb5 + ec6691b commit 90c87da

File tree

13 files changed

+176
-46
lines changed

13 files changed

+176
-46
lines changed
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
The Giphy version to render - check the keys of the [Image Object](https://developers.giphy.com/docs/api/schema#image-object) for possible values.
2+
3+
| Type | Default |
4+
| ------ | -------------- |
5+
| string | 'fixed_height' |

docusaurus/docs/reactnative/contexts/messages_context.mdx

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import ForceAlignMessages from '../common-content/core-components/channel/props/
2323
import FormatDate from '../common-content/core-components/channel/props/format_date.mdx';
2424
import Gallery from '../common-content/core-components/channel/props/gallery.mdx';
2525
import Giphy from '../common-content/core-components/channel/props/giphy.mdx';
26+
import GiphyVersion from '../common-content/core-components/channel/props/giphy_version.mdx';
2627
import HandleBlock from '../common-content/core-components/channel/props/handle_block.mdx';
2728
import HandleCopy from '../common-content/core-components/channel/props/handle_copy.mdx';
2829
import HandleDelete from '../common-content/core-components/channel/props/handle_delete.mdx';
@@ -291,6 +292,10 @@ Upserts a given message in local channel state. Please note that this function d
291292

292293
<Giphy />
293294

295+
### <div class="label description">_forwarded from [Channel](../core-components/channel.mdx#giphyversion)_ props</div> giphyVersion {#giphyversion}
296+
297+
<GiphyVersion />
298+
294299
### <div class="label description">_forwarded from [Channel](../core-components/channel.mdx#inlinedateseparator)_ props</div> InlineDateSeparator {#inlinedateseparator}
295300

296301
<InlineDateSeparator />

docusaurus/docs/reactnative/core-components/channel.mdx

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ import FormatDate from '../common-content/core-components/channel/props/format_d
4949
import Gallery from '../common-content/core-components/channel/props/gallery.mdx';
5050
import Giphy from '../common-content/core-components/channel/props/giphy.mdx';
5151
import GiphyEnabled from '../common-content/core-components/channel/props/giphy_enabled.mdx';
52+
import GiphyVersion from '../common-content/core-components/channel/props/giphy_version.mdx';
5253
import HandleBlock from '../common-content/core-components/channel/props/handle_block.mdx';
5354
import HandleCopy from '../common-content/core-components/channel/props/handle_copy.mdx';
5455
import HandleDelete from '../common-content/core-components/channel/props/handle_delete.mdx';
@@ -436,6 +437,10 @@ The max allowable is 255, which when reached displays as `255+`.
436437
| ------ | ------- |
437438
| number | 255 |
438439

440+
### giphyVersion
441+
442+
<GiphyVersion />
443+
439444
### handleBlock
440445

441446
<HandleBlock />

package/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@
7979
"react-art": "^17.0.2",
8080
"react-native-markdown-package": "1.8.1",
8181
"react-native-url-polyfill": "^1.3.0",
82-
"stream-chat": "6.0.0"
82+
"stream-chat": "6.2.0"
8383
},
8484
"peerDependencies": {
8585
"react-native-svg": "^12.1.0"

package/src/components/Attachment/Attachment.tsx

Lines changed: 29 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,13 @@ export type AttachmentPropsWithContext<
2020
StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics,
2121
> = Pick<
2222
MessagesContextValue<StreamChatGenerics>,
23-
'AttachmentActions' | 'Card' | 'FileAttachment' | 'Gallery' | 'Giphy' | 'UrlPreview'
23+
| 'AttachmentActions'
24+
| 'Card'
25+
| 'FileAttachment'
26+
| 'Gallery'
27+
| 'giphyVersion'
28+
| 'Giphy'
29+
| 'UrlPreview'
2430
> & {
2531
/**
2632
* The attachment to render
@@ -33,12 +39,21 @@ const AttachmentWithContext = <
3339
>(
3440
props: AttachmentPropsWithContext<StreamChatGenerics>,
3541
) => {
36-
const { attachment, AttachmentActions, Card, FileAttachment, Gallery, Giphy, UrlPreview } = props;
42+
const {
43+
attachment,
44+
AttachmentActions,
45+
Card,
46+
FileAttachment,
47+
Gallery,
48+
Giphy,
49+
giphyVersion,
50+
UrlPreview,
51+
} = props;
3752

3853
const hasAttachmentActions = !!attachment.actions?.length;
3954

4055
if (attachment.type === 'giphy' || attachment.type === 'imgur') {
41-
return <Giphy attachment={attachment} />;
56+
return <Giphy attachment={attachment} giphyVersion={giphyVersion} />;
4257
}
4358

4459
if (
@@ -107,7 +122,13 @@ export type AttachmentProps<
107122
> = Partial<
108123
Pick<
109124
MessagesContextValue<StreamChatGenerics>,
110-
'AttachmentActions' | 'Card' | 'FileAttachment' | 'Gallery' | 'Giphy' | 'UrlPreview'
125+
| 'AttachmentActions'
126+
| 'Card'
127+
| 'FileAttachment'
128+
| 'Gallery'
129+
| 'Giphy'
130+
| 'giphyVersion'
131+
| 'UrlPreview'
111132
>
112133
> &
113134
Pick<AttachmentPropsWithContext<StreamChatGenerics>, 'attachment'>;
@@ -127,6 +148,7 @@ export const Attachment = <
127148
FileAttachment: PropFileAttachment,
128149
Gallery: PropGallery,
129150
Giphy: PropGiphy,
151+
giphyVersion: PropGiphyVersion,
130152
UrlPreview: PropUrlPreview,
131153
} = props;
132154

@@ -136,6 +158,7 @@ export const Attachment = <
136158
FileAttachment: ContextFileAttachment,
137159
Gallery: ContextGallery,
138160
Giphy: ContextGiphy,
161+
giphyVersion: ContextGiphyVersion,
139162
UrlPreview: ContextUrlPreview,
140163
} = useMessagesContext<StreamChatGenerics>();
141164

@@ -150,6 +173,7 @@ export const Attachment = <
150173
const Gallery = PropGallery || ContextGallery || GalleryDefault;
151174
const Giphy = PropGiphy || ContextGiphy || GiphyDefault;
152175
const UrlPreview = PropUrlPreview || ContextUrlPreview || CardDefault;
176+
const giphyVersion = PropGiphyVersion || ContextGiphyVersion;
153177

154178
return (
155179
<MemoizedAttachment
@@ -160,6 +184,7 @@ export const Attachment = <
160184
FileAttachment,
161185
Gallery,
162186
Giphy,
187+
giphyVersion,
163188
UrlPreview,
164189
}}
165190
/>

package/src/components/Attachment/Giphy.tsx

Lines changed: 55 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,15 @@ import type { DefaultStreamChatGenerics } from '../../types/types';
1818
import { makeImageCompatibleUrl } from '../../utils/utils';
1919

2020
const styles = StyleSheet.create({
21-
buttonContainer: { alignItems: 'center', borderTopWidth: 1, flex: 1, justifyContent: 'center' },
21+
actionsRow: {
22+
flexDirection: 'row',
23+
},
24+
buttonContainer: {
25+
alignItems: 'center',
26+
borderTopWidth: 1,
27+
flex: 1,
28+
justifyContent: 'center',
29+
},
2230
cancel: {
2331
fontSize: 14,
2432
fontWeight: '600',
@@ -29,8 +37,10 @@ const styles = StyleSheet.create({
2937
width: 270,
3038
},
3139
giphy: {
40+
alignSelf: 'center',
3241
borderRadius: 2,
3342
height: 170,
43+
maxWidth: 270,
3444
width: 270,
3545
},
3646
giphyContainer: {
@@ -53,7 +63,10 @@ const styles = StyleSheet.create({
5363
left: 8,
5464
position: 'absolute',
5565
},
56-
giphyMaskText: { fontSize: 13, fontWeight: '600' },
66+
giphyMaskText: {
67+
fontSize: 13,
68+
fontWeight: '600',
69+
},
5770
header: {
5871
alignItems: 'center',
5972
display: 'flex',
@@ -62,16 +75,16 @@ const styles = StyleSheet.create({
6275
padding: 8,
6376
width: '60%',
6477
},
65-
margin: {
66-
margin: 1,
67-
},
68-
row: { flexDirection: 'row' },
6978
selectionContainer: {
7079
borderBottomLeftRadius: 8,
7180
borderWidth: 1,
7281
overflow: 'hidden',
7382
width: 272,
7483
},
84+
selectionImageContainer: {
85+
alignSelf: 'center',
86+
margin: 1,
87+
},
7588
send: {
7689
fontSize: 14,
7790
fontWeight: '600',
@@ -98,7 +111,7 @@ export type GiphyPropsWithContext<
98111
MessageContextValue<StreamChatGenerics>,
99112
'handleAction' | 'onLongPress' | 'onPress' | 'onPressIn' | 'preventPress'
100113
> &
101-
Pick<MessagesContextValue<StreamChatGenerics>, 'additionalTouchableProps'> & {
114+
Pick<MessagesContextValue<StreamChatGenerics>, 'giphyVersion' | 'additionalTouchableProps'> & {
102115
attachment: Attachment<StreamChatGenerics>;
103116
};
104117

@@ -117,11 +130,11 @@ const GiphyWithContext = <
117130
preventPress,
118131
} = props;
119132

120-
const { actions, image_url, thumb_url, title, type } = attachment;
133+
const { actions, giphy: giphyData, image_url, thumb_url, title, type } = attachment;
121134

122135
const {
123136
theme: {
124-
colors: { accent_blue, black, grey, grey_dark, grey_gainsboro, white },
137+
colors: { accent_blue, black, grey, grey_dark, grey_gainsboro, label_bg_transparent, white },
125138
messageSimple: {
126139
giphy: {
127140
buttonContainer,
@@ -142,7 +155,15 @@ const GiphyWithContext = <
142155
},
143156
} = useTheme();
144157

145-
const uri = image_url || thumb_url;
158+
let uri = image_url || thumb_url;
159+
const giphyDimensions: { height?: number; width?: number } = {};
160+
161+
if (type === 'giphy' && giphyData) {
162+
const giphyVersionInfo = giphyData[props.giphyVersion];
163+
uri = giphyVersionInfo.url;
164+
giphyDimensions.height = parseFloat(giphyVersionInfo.height);
165+
giphyDimensions.width = parseFloat(giphyVersionInfo.width);
166+
}
146167

147168
if (!uri) return null;
148169

@@ -161,15 +182,15 @@ const GiphyWithContext = <
161182
style={[styles.giphyHeaderTitle, giphyHeaderTitle, { color: grey_dark }]}
162183
>{`/giphy ${title}`}</Text>
163184
</View>
164-
<View style={styles.margin}>
185+
<View style={styles.selectionImageContainer}>
165186
<Image
166-
resizeMode='cover'
187+
resizeMode='contain'
167188
source={{ uri: makeImageCompatibleUrl(uri) }}
168-
style={[styles.giphy, giphy]}
189+
style={[styles.giphy, giphyDimensions, giphy]}
169190
/>
170191
</View>
171192
<View>
172-
<View style={styles.row}>
193+
<View style={styles.actionsRow}>
173194
<TouchableOpacity
174195
onPress={() => {
175196
if (actions?.[2].name && actions?.[2].value && handleAction) {
@@ -238,18 +259,24 @@ const GiphyWithContext = <
238259
});
239260
}
240261
}}
241-
style={[styles.container, container]}
242262
testID='giphy-attachment'
243263
{...additionalTouchableProps}
244264
>
245-
<View>
265+
<View style={[styles.container, container]}>
246266
<Image
247-
resizeMode='cover'
267+
resizeMode='contain'
248268
source={{ uri: makeImageCompatibleUrl(uri) }}
249-
style={[styles.giphy, giphy]}
269+
style={[styles.giphy, giphyDimensions, giphy]}
270+
testID='giphy-attachment-image'
250271
/>
251272
<View style={[styles.giphyMask, giphyMask]}>
252-
<View style={[styles.giphyContainer, { backgroundColor: grey_dark }, giphyContainer]}>
273+
<View
274+
style={[
275+
styles.giphyContainer,
276+
{ backgroundColor: label_bg_transparent },
277+
giphyContainer,
278+
]}
279+
>
253280
<Lightning height={16} pathFill={white} width={16} />
254281
<Text style={[styles.giphyMaskText, { color: white }, giphyMaskText]}>
255282
{type?.toUpperCase()}
@@ -267,9 +294,11 @@ const areEqual = <StreamChatGenerics extends DefaultStreamChatGenerics = Default
267294
) => {
268295
const {
269296
attachment: { actions: prevActions, image_url: prevImageUrl, thumb_url: prevThumbUrl },
297+
giphyVersion: prevGiphyVersion,
270298
} = prevProps;
271299
const {
272300
attachment: { actions: nextActions, image_url: nextImageUrl, thumb_url: nextThumbUrl },
301+
giphyVersion: nextGiphyVersion,
273302
} = nextProps;
274303

275304
const imageUrlEqual = prevImageUrl === nextImageUrl;
@@ -278,6 +307,9 @@ const areEqual = <StreamChatGenerics extends DefaultStreamChatGenerics = Default
278307
const thumbUrlEqual = prevThumbUrl === nextThumbUrl;
279308
if (!thumbUrlEqual) return false;
280309

310+
const giphyVersionEqual = prevGiphyVersion === nextGiphyVersion;
311+
if (!giphyVersionEqual) return false;
312+
281313
const actionsEqual =
282314
Array.isArray(prevActions) === Array.isArray(nextActions) &&
283315
((Array.isArray(prevActions) &&
@@ -294,8 +326,8 @@ const MemoizedGiphy = React.memo(GiphyWithContext, areEqual) as typeof GiphyWith
294326
export type GiphyProps<
295327
StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics,
296328
> = Partial<
297-
Pick<MessageContextValue<StreamChatGenerics>, 'onLongPress' | 'onPressIn'> &
298-
Pick<MessagesContextValue<StreamChatGenerics>, 'additionalTouchableProps'>
329+
Pick<MessageContextValue<StreamChatGenerics>, 'isMyMessage' | 'onLongPress' | 'onPressIn'> &
330+
Pick<MessagesContextValue<StreamChatGenerics>, 'giphyVersion' | 'additionalTouchableProps'>
299331
> & {
300332
attachment: Attachment<StreamChatGenerics>;
301333
};
@@ -310,12 +342,13 @@ export const Giphy = <
310342
) => {
311343
const { handleAction, onLongPress, onPress, onPressIn, preventPress } =
312344
useMessageContext<StreamChatGenerics>();
313-
const { additionalTouchableProps } = useMessagesContext<StreamChatGenerics>();
345+
const { additionalTouchableProps, giphyVersion } = useMessagesContext<StreamChatGenerics>();
314346

315347
return (
316348
<MemoizedGiphy
317349
{...{
318350
additionalTouchableProps,
351+
giphyVersion,
319352
handleAction,
320353
onLongPress,
321354
onPress,

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

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,47 @@ describe('Attachment', () => {
7171
});
7272
});
7373

74+
it('"giphy" attachment size should be customisable', async () => {
75+
const attachment = generateGiphyAttachment();
76+
attachment.giphy = {
77+
fixed_height: {
78+
height: '200',
79+
url: 'https://media1.giphy.com/media/test/fixed_height.gif',
80+
width: '375',
81+
},
82+
original: {
83+
height: '256',
84+
url: 'https://media1.giphy.com/media/test/original.gif',
85+
width: '480',
86+
},
87+
};
88+
const { getByTestId: getByTestIdFixedHeight } = render(
89+
getAttachmentComponent({ attachment, giphyVersion: 'fixed_height' }),
90+
);
91+
const { getByTestId: getByTestIdOriginal } = render(
92+
getAttachmentComponent({ attachment, giphyVersion: 'original' }),
93+
);
94+
await waitFor(() => {
95+
const checkImageProps = (imageProps, specificSizedGiphyData) => {
96+
let imageStyle = imageProps.style;
97+
if (Array.isArray(imageStyle)) {
98+
imageStyle = Object.assign({}, ...imageStyle);
99+
}
100+
expect(imageStyle.height).toBe(parseFloat(specificSizedGiphyData.height));
101+
expect(imageStyle.width).toBe(parseFloat(specificSizedGiphyData.width));
102+
expect(imageProps.source.uri).toBe(specificSizedGiphyData.url);
103+
};
104+
checkImageProps(
105+
getByTestIdFixedHeight('giphy-attachment-image').props,
106+
attachment.giphy.fixed_height,
107+
);
108+
checkImageProps(
109+
getByTestIdOriginal('giphy-attachment-image').props,
110+
attachment.giphy.original,
111+
);
112+
});
113+
});
114+
74115
it('should render UrlPreview component if attachment has title_link or og_scrape_url', async () => {
75116
const attachment = generateImageAttachment({
76117
og_scrape_url: uuidv4(),

0 commit comments

Comments
 (0)