Skip to content

Commit f3b2d21

Browse files
Merge pull request #536 from GetStream/vishal/custom-attachments
CRNS-239: Custom attachment docs and support
2 parents 730f688 + 99c59fc commit f3b2d21

File tree

7 files changed

+299
-63
lines changed

7 files changed

+299
-63
lines changed

CHANGELOG.md

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,17 @@
11
# Changelog
22

3-
## [3.0.0] (2021-02-23) 🎉
3+
## [3.1.0] (UNRELEASED)
4+
5+
- **🛑 BREAKING**: Removed a prop `handleOnPress` on `Input` component.
6+
- Added support for new props on `Input` component, which can be used on Channel component as prop to replace undelying input component ([reference](https://github.com/GetStream/stream-chat-react-native/wiki/Cookbook-v3.0#how-to-change-the-layout-of-messageinput-component))
7+
- closeAttachmentPicker (function)
8+
- openAttachmentPicker (function)
9+
- openCommandsPicker (function)
10+
- toggleAttachmentPicker (function)
11+
12+
- Added support for new prop on `Channel` component - `InputButtons`, to replace the extra buttons on the left on input box.
13+
14+
## [3.0.0] (2021-02-23)
415

516
Version 3.x is a major revamp of the SDK and comes with **many breaking changes**. The new implementation takes advantage of React Context along with many popular community libraries such as Reanimated V2 to deliver a superior chat experience. **Upgrading will require re-implementing** your integration but will yield performance and functional benefits. It is highly recommended you read the Cookbook and examine the SampleApp / TypeScriptMessaging apps before upgrading to understand what is required.
617

src/components/Channel/Channel.tsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ import { AttachButton as AttachButtonDefault } from '../MessageInput/AttachButto
5858
import { CommandsButton as CommandsButtonDefault } from '../MessageInput/CommandsButton';
5959
import { FileUploadPreview as FileUploadPreviewDefault } from '../MessageInput/FileUploadPreview';
6060
import { ImageUploadPreview as ImageUploadPreviewDefault } from '../MessageInput/ImageUploadPreview';
61+
import { InputButtons as InputButtonsDefault } from '../MessageInput/InputButtons';
6162
import { MoreOptionsButton as MoreOptionsButtonDefault } from '../MessageInput/MoreOptionsButton';
6263
import { SendButton as SendButtonDefault } from '../MessageInput/SendButton';
6364
import { ShowThreadMessageInChannelButton as ShowThreadMessageInChannelButtonDefault } from '../MessageInput/ShowThreadMessageInChannelButton';
@@ -433,6 +434,7 @@ const ChannelWithContext = <
433434
initialValue,
434435
InlineUnreadIndicator = InlineUnreadIndicatorDefault,
435436
Input,
437+
InputButtons = InputButtonsDefault,
436438
keyboardBehavior,
437439
KeyboardCompatibleView = KeyboardCompatibleViewDefault,
438440
keyboardVerticalOffset,
@@ -1415,6 +1417,7 @@ const ChannelWithContext = <
14151417
ImageUploadPreview,
14161418
initialValue,
14171419
Input,
1420+
InputButtons,
14181421
maxNumberOfFiles,
14191422
MoreOptionsButton,
14201423
numberOfLines,

src/components/Channel/hooks/useCreateInputMessageInputContext.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ export const useCreateInputMessageInputContext = <
3939
ImageUploadPreview,
4040
initialValue,
4141
Input,
42+
InputButtons,
4243
maxMessageLength,
4344
maxNumberOfFiles,
4445
MoreOptionsButton,
@@ -88,6 +89,7 @@ export const useCreateInputMessageInputContext = <
8889
ImageUploadPreview,
8990
initialValue,
9091
Input,
92+
InputButtons,
9193
maxMessageLength,
9294
maxNumberOfFiles,
9395
MoreOptionsButton,
Lines changed: 229 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,229 @@
1+
import React from 'react';
2+
import { StyleSheet, View } from 'react-native';
3+
4+
import {
5+
MessageInputContextValue,
6+
useMessageInputContext,
7+
} from '../../contexts/messageInputContext/MessageInputContext';
8+
import { useTheme } from '../../contexts/themeContext/ThemeContext';
9+
10+
import type {
11+
DefaultAttachmentType,
12+
DefaultChannelType,
13+
DefaultCommandType,
14+
DefaultEventType,
15+
DefaultMessageType,
16+
DefaultReactionType,
17+
DefaultUserType,
18+
UnknownType,
19+
} from '../../types/types';
20+
21+
const styles = StyleSheet.create({
22+
attachButtonContainer: { paddingRight: 10 },
23+
});
24+
25+
export type InputButtonsProps<
26+
At extends DefaultAttachmentType = DefaultAttachmentType,
27+
Ch extends UnknownType = DefaultChannelType,
28+
Co extends string = DefaultCommandType,
29+
Ev extends UnknownType = DefaultEventType,
30+
Me extends UnknownType = DefaultMessageType,
31+
Re extends UnknownType = DefaultReactionType,
32+
Us extends UnknownType = DefaultUserType
33+
> = Partial<InputButtonsWithContextProps<At, Ch, Co, Ev, Me, Re, Us>>;
34+
35+
export type InputButtonsWithContextProps<
36+
At extends DefaultAttachmentType = DefaultAttachmentType,
37+
Ch extends UnknownType = DefaultChannelType,
38+
Co extends string = DefaultCommandType,
39+
Ev extends UnknownType = DefaultEventType,
40+
Me extends UnknownType = DefaultMessageType,
41+
Re extends UnknownType = DefaultReactionType,
42+
Us extends UnknownType = DefaultUserType
43+
> = Pick<
44+
MessageInputContextValue<At, Ch, Co, Ev, Me, Re, Us>,
45+
| 'AttachButton'
46+
| 'CommandsButton'
47+
| 'giphyActive'
48+
| 'hasCommands'
49+
| 'hasFilePicker'
50+
| 'hasImagePicker'
51+
| 'MoreOptionsButton'
52+
| 'setShowMoreOptions'
53+
| 'showMoreOptions'
54+
| 'text'
55+
| 'uploadsEnabled'
56+
> & {
57+
closeAttachmentPicker?: () => void;
58+
openAttachmentPicker?: () => void;
59+
openCommandsPicker?: () => void;
60+
toggleAttachmentPicker?: () => void;
61+
};
62+
63+
export const InputButtonsWithContext = <
64+
At extends DefaultAttachmentType = DefaultAttachmentType,
65+
Ch extends UnknownType = DefaultChannelType,
66+
Co extends string = DefaultCommandType,
67+
Ev extends UnknownType = DefaultEventType,
68+
Me extends UnknownType = DefaultMessageType,
69+
Re extends UnknownType = DefaultReactionType,
70+
Us extends UnknownType = DefaultUserType
71+
>(
72+
props: InputButtonsWithContextProps<At, Ch, Co, Ev, Me, Re, Us>,
73+
) => {
74+
const {
75+
AttachButton,
76+
CommandsButton,
77+
giphyActive,
78+
hasCommands,
79+
hasFilePicker,
80+
hasImagePicker,
81+
MoreOptionsButton,
82+
openCommandsPicker,
83+
setShowMoreOptions,
84+
showMoreOptions,
85+
text,
86+
toggleAttachmentPicker,
87+
uploadsEnabled,
88+
} = props;
89+
90+
const {
91+
theme: {
92+
messageInput: { attachButtonContainer, commandsButtonContainer },
93+
},
94+
} = useTheme();
95+
96+
if (giphyActive) {
97+
return null;
98+
}
99+
100+
return !showMoreOptions &&
101+
(hasImagePicker || hasFilePicker) &&
102+
hasCommands ? (
103+
<MoreOptionsButton handleOnPress={() => setShowMoreOptions(true)} />
104+
) : (
105+
<>
106+
{(hasImagePicker || hasFilePicker) && uploadsEnabled !== false && (
107+
<View
108+
style={[
109+
hasCommands ? styles.attachButtonContainer : undefined,
110+
attachButtonContainer,
111+
]}
112+
>
113+
<AttachButton handleOnPress={toggleAttachmentPicker} />
114+
</View>
115+
)}
116+
{hasCommands && !text && (
117+
<View style={commandsButtonContainer}>
118+
<CommandsButton handleOnPress={openCommandsPicker} />
119+
</View>
120+
)}
121+
</>
122+
);
123+
};
124+
const areEqual = <
125+
At extends UnknownType = DefaultAttachmentType,
126+
Ch extends UnknownType = DefaultChannelType,
127+
Co extends string = DefaultCommandType,
128+
Ev extends UnknownType = DefaultEventType,
129+
Me extends UnknownType = DefaultMessageType,
130+
Re extends UnknownType = DefaultReactionType,
131+
Us extends UnknownType = DefaultUserType
132+
>(
133+
prevProps: InputButtonsWithContextProps<At, Ch, Co, Ev, Me, Re, Us>,
134+
nextProps: InputButtonsWithContextProps<At, Ch, Co, Ev, Me, Re, Us>,
135+
) => {
136+
const {
137+
hasCommands: prevHasCommands,
138+
hasFilePicker: prevHasFilePicker,
139+
hasImagePicker: prevHasImagePicker,
140+
showMoreOptions: prevShowMoreOptions,
141+
text: prevText,
142+
uploadsEnabled: prevUploadsEnabled,
143+
} = prevProps;
144+
145+
const {
146+
hasCommands: nextHasCommands,
147+
hasFilePicker: nextHasFilePicker,
148+
hasImagePicker: nextHasImagePicker,
149+
showMoreOptions: nextShowMoreOptions,
150+
text: nextText,
151+
uploadsEnabled: nextUploadsEnabled,
152+
} = nextProps;
153+
154+
if (prevHasImagePicker !== nextHasImagePicker) {
155+
return false;
156+
}
157+
158+
if (prevHasFilePicker !== nextHasFilePicker) {
159+
return false;
160+
}
161+
162+
if (prevHasCommands !== nextHasCommands) {
163+
return false;
164+
}
165+
166+
if (prevUploadsEnabled !== nextUploadsEnabled) {
167+
return false;
168+
}
169+
170+
if (prevShowMoreOptions !== nextShowMoreOptions) {
171+
return false;
172+
}
173+
174+
if ((!prevProps.text && nextText) || (prevText && !nextText)) {
175+
return false;
176+
}
177+
178+
return true;
179+
};
180+
181+
const MemoizedInputButtonsWithContext = React.memo(
182+
InputButtonsWithContext,
183+
areEqual,
184+
) as typeof InputButtonsWithContext;
185+
186+
export const InputButtons = <
187+
At extends DefaultAttachmentType = DefaultAttachmentType,
188+
Ch extends UnknownType = DefaultChannelType,
189+
Co extends string = DefaultCommandType,
190+
Ev extends UnknownType = DefaultEventType,
191+
Me extends UnknownType = DefaultMessageType,
192+
Re extends UnknownType = DefaultReactionType,
193+
Us extends UnknownType = DefaultUserType
194+
>(
195+
props: InputButtonsProps<At, Ch, Co, Ev, Me, Re, Us>,
196+
) => {
197+
const {
198+
AttachButton,
199+
CommandsButton,
200+
giphyActive,
201+
hasCommands,
202+
hasFilePicker,
203+
hasImagePicker,
204+
MoreOptionsButton,
205+
setShowMoreOptions,
206+
showMoreOptions,
207+
text,
208+
uploadsEnabled,
209+
} = useMessageInputContext<At, Ch, Co, Ev, Me, Re, Us>();
210+
211+
return (
212+
<MemoizedInputButtonsWithContext
213+
{...{
214+
AttachButton,
215+
CommandsButton,
216+
giphyActive,
217+
hasCommands,
218+
hasFilePicker,
219+
hasImagePicker,
220+
MoreOptionsButton,
221+
setShowMoreOptions,
222+
showMoreOptions,
223+
text,
224+
uploadsEnabled,
225+
}}
226+
{...props}
227+
/>
228+
);
229+
};

0 commit comments

Comments
 (0)