Skip to content

Commit dbb440c

Browse files
Merge pull request #457 from GetStream/vishal/autocomplete-fix
Fixing mentions issue and adding `autocompleteSuggestionsLimit` prop
2 parents 533f6db + 6456afe commit dbb440c

File tree

2 files changed

+46
-27
lines changed

2 files changed

+46
-27
lines changed

src/components/MessageInput/MessageInput.tsx

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,10 @@ export type MessageInputProps<
164164
* Defaults to and accepts same props as: https://github.com/GetStream/stream-chat-react-native/blob/master/src/components/Attachment/FileIcon.tsx
165165
*/
166166
AttachmentFileIcon?: React.ComponentType<FileIconProps>;
167+
/**
168+
* Max number of suggestions to display in list. Defaults to 10.
169+
*/
170+
autocompleteSuggestionsLimit?: number;
167171
/**
168172
* Compress image with quality (from 0 to 1, where 1 is best quality).
169173
* On iOS, values larger than 0.8 don't produce a noticeable quality increase in most images,
@@ -215,6 +219,7 @@ export type MessageInputProps<
215219
ImageUploadPreview?: React.ComponentType<ImageUploadPreviewProps>;
216220
/** Initial value to set on input */
217221
initialValue?: string;
222+
218223
/**
219224
* Custom UI component for AutoCompleteInput.
220225
* Defaults to and accepts same props as: https://github.com/GetStream/stream-chat-react-native/blob/master/src/components/AutoCompleteInput/AutoCompleteInput.tsx
@@ -309,6 +314,7 @@ export const MessageInput = <
309314
hasImagePicker = true,
310315
ImageUploadPreview = ImageUploadPreviewDefault,
311316
initialValue,
317+
autocompleteSuggestionsLimit = 10,
312318
Input,
313319
maxNumberOfFiles = 10,
314320
onChangeText: onChangeTextProp,
@@ -615,6 +621,7 @@ export const MessageInput = <
615621

616622
const triggerSettings = channel
617623
? ACITriggerSettings<At, Ch, Co, Ev, Me, Re, Us>({
624+
autocompleteSuggestionsLimit,
618625
channel,
619626
onMentionSelectItem: onSelectItem,
620627
t,

src/utils/utils.ts

Lines changed: 39 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import type {
66
ChannelMemberResponse,
77
UserResponse,
88
} from 'stream-chat';
9-
9+
import type { DebouncedFunc } from 'lodash';
1010
import type { CommandsItemProps } from '../components/AutoCompleteInput/CommandsItem';
1111
import type { MentionsItemProps } from '../components/AutoCompleteInput/MentionsItem';
1212
import type {
@@ -101,7 +101,6 @@ const getMembers = <
101101
const members = (channel.state.members as unknown) as ChannelMemberResponse<
102102
Us
103103
>[];
104-
105104
return members && Object.values(members).length
106105
? (Object.values(members).filter((member) => member.user) as Array<
107106
ChannelMemberResponse<Us> & { user: UserResponse<Us> }
@@ -149,6 +148,19 @@ const getMembersAndWatchers = <
149148
}, {} as { [key: string]: SuggestionUser<Us> }),
150149
);
151150
};
151+
type QueryMembersFunction<
152+
At extends UnknownType = DefaultAttachmentType,
153+
Ch extends UnknownType = DefaultChannelType,
154+
Co extends string = DefaultCommandType,
155+
Ev extends UnknownType = DefaultEventType,
156+
Me extends UnknownType = DefaultMessageType,
157+
Re extends UnknownType = DefaultReactionType,
158+
Us extends UnknownType = DefaultUserType
159+
> = (
160+
channel: Channel<At, Ch, Co, Ev, Me, Re, Us>,
161+
query: SuggestionUser<Us>['name'],
162+
onReady?: (users: SuggestionUser<Us>[]) => void,
163+
) => Promise<void>;
152164

153165
// TODO: test to see if this function works as it integrated a debounce function
154166
const queryMembers = async <
@@ -164,27 +176,24 @@ const queryMembers = async <
164176
query: SuggestionUser<Us>['name'],
165177
onReady?: (users: SuggestionUser<Us>[]) => void,
166178
): Promise<void> => {
167-
await debounce(
168-
async () => {
169-
if (typeof query === 'string') {
170-
const response = (await ((channel as unknown) as Channel).queryMembers({
171-
name: { $autocomplete: query },
172-
})) as ChannelMemberAPIResponse<Us>;
173-
174-
const users: SuggestionUser<Us>[] = [];
175-
response.members.forEach(
176-
(member) => isUserResponse(member.user) && users.push(member.user),
177-
);
178-
if (onReady && users) {
179-
onReady(users);
180-
}
181-
}
182-
},
183-
200,
184-
{ leading: false, trailing: true },
185-
);
179+
if (typeof query === 'string') {
180+
const response = (await ((channel as unknown) as Channel).queryMembers({
181+
name: { $autocomplete: query },
182+
})) as ChannelMemberAPIResponse<Us>;
183+
184+
const users: SuggestionUser<Us>[] = [];
185+
response.members.forEach(
186+
(member) => isUserResponse(member.user) && users.push(member.user),
187+
);
188+
if (onReady && users) {
189+
onReady(users);
190+
}
191+
}
186192
};
187-
193+
export const queryMembersDebounced = debounce(queryMembers, 200, {
194+
leading: false,
195+
trailing: true,
196+
});
188197
export const isMentionTrigger = (trigger: Trigger): trigger is '@' =>
189198
trigger === '@';
190199

@@ -223,7 +232,7 @@ export type TriggerSettings<
223232
data: SuggestionUser<Us>[],
224233
q: SuggestionUser<Us>['name'],
225234
) => void,
226-
) => SuggestionUser<Us>[] | Promise<void>;
235+
) => SuggestionUser<Us>[] | Promise<void> | void;
227236
output: (
228237
entity: SuggestionUser<Us>,
229238
) => {
@@ -246,6 +255,7 @@ export type ACITriggerSettingsParams<
246255
> = {
247256
channel: Channel<At, Ch, Co, Ev, Me, Re, Us>;
248257
onMentionSelectItem: (item: SuggestionUser<Us>) => void;
258+
autocompleteSuggestionsLimit?: number;
249259
} & Pick<TranslationContextValue, 't'>;
250260

251261
/**
@@ -271,6 +281,7 @@ export const ACITriggerSettings = <
271281
channel,
272282
onMentionSelectItem,
273283
t = (msg: string) => msg,
284+
autocompleteSuggestionsLimit = 10,
274285
}: ACITriggerSettingsParams<At, Ch, Co, Ev, Me, Re, Us>): TriggerSettings<
275286
Co,
276287
Us
@@ -300,7 +311,7 @@ export const ACITriggerSettings = <
300311
return 0;
301312
});
302313

303-
const result = selectedCommands.slice(0, 10);
314+
const result = selectedCommands.slice(0, autocompleteSuggestionsLimit);
304315

305316
if (onReady) {
306317
onReady(result, query);
@@ -343,16 +354,17 @@ export const ACITriggerSettings = <
343354
return false;
344355
});
345356

346-
const data = matchingUsers.slice(0, 10);
357+
const data = matchingUsers.slice(0, autocompleteSuggestionsLimit);
347358

348359
if (onReady) {
349360
onReady(data, query);
350361
}
351362

352363
return data;
353364
}
354-
355-
return queryMembers(channel, query, (data) => {
365+
return (queryMembersDebounced as DebouncedFunc<
366+
QueryMembersFunction<At, Ch, Co, Ev, Me, Re, Us>
367+
>)(channel, query, (data) => {
356368
if (onReady) {
357369
onReady(data, query);
358370
}

0 commit comments

Comments
 (0)