Skip to content

Commit a00a670

Browse files
committed
feat: use new text composer for RN SDK
1 parent 54ce9c6 commit a00a670

17 files changed

+420
-772
lines changed

package/src/components/AutoCompleteInput/AutoCompleteInput.tsx

Lines changed: 38 additions & 344 deletions
Large diffs are not rendered by default.

package/src/components/AutoCompleteInput/AutoCompleteSuggestionCommandIcon.tsx

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
import React from 'react';
22
import { StyleSheet, View } from 'react-native';
33

4-
import type { SuggestionCommand } from '../../contexts/suggestionsContext/SuggestionsContext';
4+
import { CommandVariants } from 'stream-chat';
5+
56
import { useTheme } from '../../contexts/themeContext/ThemeContext';
67
import { Flag, GiphyIcon, Imgur, Lightning, Mute, Sound, UserAdd, UserDelete } from '../../icons';
78

@@ -16,11 +17,7 @@ const styles = StyleSheet.create({
1617
},
1718
});
1819

19-
export const AutoCompleteSuggestionCommandIcon = ({
20-
name,
21-
}: {
22-
name: SuggestionCommand['name'];
23-
}) => {
20+
export const AutoCompleteSuggestionCommandIcon = ({ name }: { name: CommandVariants }) => {
2421
const {
2522
theme: {
2623
colors: { accent_blue, white },
Lines changed: 6 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,16 @@
11
import React from 'react';
22
import { StyleSheet, Text, View } from 'react-native';
33

4-
import type { SuggestionsContextValue } from '../../contexts/suggestionsContext/SuggestionsContext';
54
import { useTheme } from '../../contexts/themeContext/ThemeContext';
65
import { useTranslationContext } from '../../contexts/translationContext/TranslationContext';
76

87
import { Lightning } from '../../icons/Lightning';
98
import { Smile } from '../../icons/Smile';
109

11-
export type AutoCompleteSuggestionHeaderPropsWithContext = Pick<
12-
SuggestionsContextValue,
13-
'triggerType' | 'queryText'
14-
>;
10+
export type AutoCompleteSuggestionHeaderProps = {
11+
queryText: string;
12+
triggerType: string;
13+
};
1514

1615
const styles = StyleSheet.create({
1716
container: {
@@ -25,10 +24,10 @@ const styles = StyleSheet.create({
2524
},
2625
});
2726

28-
const AutoCompleteSuggestionHeaderWithContext = ({
27+
export const AutoCompleteSuggestionHeader = ({
2928
queryText,
3029
triggerType,
31-
}: AutoCompleteSuggestionHeaderPropsWithContext) => {
30+
}: AutoCompleteSuggestionHeaderProps) => {
3231
const { t } = useTranslationContext();
3332
const {
3433
theme: {
@@ -59,42 +58,10 @@ const AutoCompleteSuggestionHeaderWithContext = ({
5958
</Text>
6059
</View>
6160
);
62-
} else if (triggerType === 'mention') {
63-
return null;
6461
} else {
6562
return null;
6663
}
6764
};
6865

69-
const areEqual = (
70-
prevProps: AutoCompleteSuggestionHeaderPropsWithContext,
71-
nextProps: AutoCompleteSuggestionHeaderPropsWithContext,
72-
) => {
73-
const { queryText: prevQueryText, triggerType: prevType } = prevProps;
74-
const { queryText: nextQueryText, triggerType: nextType } = nextProps;
75-
76-
const typeEqual = prevType === nextType;
77-
if (!typeEqual) {
78-
return false;
79-
}
80-
81-
const valueEqual = prevQueryText === nextQueryText;
82-
if (!valueEqual) {
83-
return false;
84-
}
85-
return true;
86-
};
87-
88-
const MemoizedAutoCompleteSuggestionHeader = React.memo(
89-
AutoCompleteSuggestionHeaderWithContext,
90-
areEqual,
91-
) as typeof AutoCompleteSuggestionHeaderWithContext;
92-
93-
export type AutoCompleteSuggestionHeaderProps = AutoCompleteSuggestionHeaderPropsWithContext;
94-
95-
export const AutoCompleteSuggestionHeader = (props: AutoCompleteSuggestionHeaderProps) => (
96-
<MemoizedAutoCompleteSuggestionHeader {...props} />
97-
);
98-
9966
AutoCompleteSuggestionHeader.displayName =
10067
'AutoCompleteSuggestionHeader{messageInput{suggestions{Header}}}';
Lines changed: 96 additions & 102 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,110 @@
11
import React from 'react';
22
import { StyleSheet, Text, View } from 'react-native';
33

4+
import { CommandSuggestion, TextComposerSuggestion, UserSuggestion } from 'stream-chat';
5+
46
import { AutoCompleteSuggestionCommandIcon } from './AutoCompleteSuggestionCommandIcon';
57

6-
import type {
7-
Suggestion,
8-
SuggestionCommand,
9-
SuggestionsContextValue,
10-
SuggestionUser,
11-
} from '../../contexts/suggestionsContext/SuggestionsContext';
128
import { useTheme } from '../../contexts/themeContext/ThemeContext';
139
import type { Emoji } from '../../emoji-data';
1410
import { AtMentions } from '../../icons/AtMentions';
1511

1612
import { Avatar } from '../Avatar/Avatar';
1713

18-
export type AutoCompleteSuggestionItemPropsWithContext = Pick<
19-
SuggestionsContextValue,
20-
'triggerType'
21-
> & {
22-
itemProps: Suggestion;
14+
export type AutoCompleteSuggestionItemProps = {
15+
itemProps: TextComposerSuggestion;
16+
triggerType: string;
17+
};
18+
19+
export const MentionSuggestionItem = (item: UserSuggestion) => {
20+
const { id, image, name, online } = item;
21+
const {
22+
theme: {
23+
colors: { accent_blue, black },
24+
messageInput: {
25+
suggestions: {
26+
mention: { avatarSize, column, container: mentionContainer, name: nameStyle },
27+
},
28+
},
29+
},
30+
} = useTheme();
31+
return (
32+
<View style={[styles.container, mentionContainer]}>
33+
<Avatar image={image} name={name} online={online} size={avatarSize} />
34+
<View style={[styles.column, column]}>
35+
<Text style={[styles.name, { color: black }, nameStyle]} testID='mentions-item-name'>
36+
{name || id}
37+
</Text>
38+
</View>
39+
<AtMentions pathFill={accent_blue} />
40+
</View>
41+
);
42+
};
43+
44+
const EmojiSuggestionItem = (item: Emoji) => {
45+
const { unicode, name } = item;
46+
const {
47+
theme: {
48+
colors: { black },
49+
messageInput: {
50+
suggestions: {
51+
emoji: { container: emojiContainer, text },
52+
},
53+
},
54+
},
55+
} = useTheme();
56+
return (
57+
<View style={[styles.container, emojiContainer]}>
58+
<Text style={[styles.text, { color: black }, text]} testID='emojis-item-unicode'>
59+
{unicode}
60+
</Text>
61+
<Text style={[styles.text, { color: black }, text]} testID='emojis-item-name'>
62+
{` ${name}`}
63+
</Text>
64+
</View>
65+
);
66+
};
67+
68+
const CommandSuggestionItem = (item: CommandSuggestion) => {
69+
const { args, name } = item;
70+
const {
71+
theme: {
72+
colors: { black, grey },
73+
messageInput: {
74+
suggestions: {
75+
command: { args: argsStyle, container: commandContainer, title },
76+
},
77+
},
78+
},
79+
} = useTheme();
80+
81+
return (
82+
<View style={[styles.container, commandContainer]}>
83+
{name ? <AutoCompleteSuggestionCommandIcon name={name} /> : null}
84+
<Text style={[styles.title, { color: black }, title]} testID='commands-item-title'>
85+
{(name || '').replace(/^\w/, (char) => char.toUpperCase())}
86+
</Text>
87+
<Text style={[styles.args, { color: grey }, argsStyle]} testID='commands-item-args'>
88+
{`/${name} ${args}`}
89+
</Text>
90+
</View>
91+
);
92+
};
93+
94+
export const AutoCompleteSuggestionItem = ({
95+
itemProps,
96+
triggerType,
97+
}: AutoCompleteSuggestionItemProps) => {
98+
switch (triggerType) {
99+
case 'mention':
100+
return <MentionSuggestionItem {...(itemProps as UserSuggestion)} />;
101+
case 'emoji':
102+
return <EmojiSuggestionItem {...(itemProps as Emoji)} />;
103+
case 'command':
104+
return <CommandSuggestionItem {...itemProps} />;
105+
default:
106+
return null;
107+
}
23108
};
24109

25110
const styles = StyleSheet.create({
@@ -55,94 +140,3 @@ const styles = StyleSheet.create({
55140
paddingHorizontal: 8,
56141
},
57142
});
58-
59-
const AutoCompleteSuggestionItemWithContext = ({
60-
itemProps,
61-
triggerType,
62-
}: AutoCompleteSuggestionItemPropsWithContext) => {
63-
const {
64-
theme: {
65-
colors: { accent_blue, black, grey },
66-
messageInput: {
67-
suggestions: {
68-
command: { args: argsStyle, container: commandContainer, title },
69-
emoji: { container: emojiContainer, text },
70-
mention: { avatarSize, column, container: mentionContainer, name: nameStyle },
71-
},
72-
},
73-
},
74-
} = useTheme();
75-
76-
if (triggerType === 'mention') {
77-
const { id, image, name, online } = itemProps as SuggestionUser;
78-
return (
79-
<View style={[styles.container, mentionContainer]}>
80-
<Avatar image={image} name={name} online={online} size={avatarSize} />
81-
<View style={[styles.column, column]}>
82-
<Text style={[styles.name, { color: black }, nameStyle]} testID='mentions-item-name'>
83-
{name || id}
84-
</Text>
85-
</View>
86-
<AtMentions pathFill={accent_blue} />
87-
</View>
88-
);
89-
} else if (triggerType === 'emoji') {
90-
const { name, unicode } = itemProps as Emoji;
91-
return (
92-
<View style={[styles.container, emojiContainer]}>
93-
<Text style={[styles.text, { color: black }, text]} testID='emojis-item-unicode'>
94-
{unicode}
95-
</Text>
96-
<Text style={[styles.text, { color: black }, text]} testID='emojis-item-name'>
97-
{` ${name}`}
98-
</Text>
99-
</View>
100-
);
101-
} else if (triggerType === 'command') {
102-
const { args, name } = itemProps as SuggestionCommand;
103-
return (
104-
<View style={[styles.container, commandContainer]}>
105-
<AutoCompleteSuggestionCommandIcon name={name} />
106-
<Text style={[styles.title, { color: black }, title]} testID='commands-item-title'>
107-
{(name || '').replace(/^\w/, (char) => char.toUpperCase())}
108-
</Text>
109-
<Text style={[styles.args, { color: grey }, argsStyle]} testID='commands-item-args'>
110-
{`/${name} ${args}`}
111-
</Text>
112-
</View>
113-
);
114-
} else {
115-
return null;
116-
}
117-
};
118-
119-
const areEqual = (
120-
prevProps: AutoCompleteSuggestionItemPropsWithContext,
121-
nextProps: AutoCompleteSuggestionItemPropsWithContext,
122-
) => {
123-
const { itemProps: prevItemProps, triggerType: prevType } = prevProps;
124-
const { itemProps: nextItemProps, triggerType: nextType } = nextProps;
125-
const itemPropsEqual = prevItemProps === nextItemProps;
126-
if (!itemPropsEqual) {
127-
return false;
128-
}
129-
const typeEqual = prevType === nextType;
130-
if (!typeEqual) {
131-
return false;
132-
}
133-
return true;
134-
};
135-
136-
const MemoizedAutoCompleteSuggestionItem = React.memo(
137-
AutoCompleteSuggestionItemWithContext,
138-
areEqual,
139-
) as typeof AutoCompleteSuggestionItemWithContext;
140-
141-
export type AutoCompleteSuggestionItemProps = AutoCompleteSuggestionItemPropsWithContext;
142-
143-
export const AutoCompleteSuggestionItem = (props: AutoCompleteSuggestionItemProps) => (
144-
<MemoizedAutoCompleteSuggestionItem {...props} />
145-
);
146-
147-
AutoCompleteSuggestionItem.displayName =
148-
'AutoCompleteSuggestionItem{messageInput{suggestions{Item}}}';

0 commit comments

Comments
 (0)