1+ import debounce from 'lodash.debounce' ;
2+ import { ChannelOptions , ChannelSort , StateStore , UserOptions } from 'stream-chat' ;
13import type {
24 Channel ,
35 ChannelFilters ,
@@ -10,15 +12,15 @@ import type {
1012 UserResponse ,
1113 UserSort ,
1214} from 'stream-chat' ;
13- import { StateStore } from 'stream-chat' ;
1415import type { DefaultStreamChatGenerics } from '../../types' ;
15- import debounce from 'lodash.debounce' ;
1616import type { DebouncedFunc } from 'lodash' ;
1717
1818// eslint-disable-next-line @typescript-eslint/ban-types
1919export type SearchSourceType = 'channels' | 'users' | 'messages' | ( string & { } ) ;
2020export type QueryReturnValue < T > = { items : T [ ] ; next ?: string } ;
21-
21+ export type DebounceOptions = {
22+ debounceMs : number ;
23+ } ;
2224type DebouncedExecQueryFunction = DebouncedFunc < ( searchString ?: string ) => Promise < void > > ;
2325
2426// eslint-disable-next-line @typescript-eslint/no-explicit-any
@@ -28,14 +30,13 @@ export interface SearchSource<T = any> {
2830 readonly isLoading : boolean ;
2931 readonly items : T [ ] | undefined ;
3032 readonly lastQueryError : Error | undefined ;
31- // loadMore(): Promise<void>;
3233 readonly next : string | undefined ;
3334 readonly offset : number | undefined ;
3435 resetState ( ) : void ;
3536 search ( text ?: string ) : Promise < void > ;
3637 searchDebounced : DebouncedExecQueryFunction ;
3738 readonly searchQuery : string ;
38- setDebounceOptions ( debounceMs : number ) : void ;
39+ setDebounceOptions ( options : DebounceOptions ) : void ;
3940 readonly state : StateStore < SearchSourceState < T > > ;
4041 readonly type : SearchSourceType ;
4142}
@@ -118,7 +119,7 @@ export abstract class BaseSearchSource<T> implements SearchSource<T> {
118119
119120 protected abstract filterQueryResults ( items : T [ ] ) : T [ ] | Promise < T [ ] > ;
120121
121- setDebounceOptions = ( debounceMs : number ) => {
122+ setDebounceOptions = ( { debounceMs } : DebounceOptions ) => {
122123 this . searchDebounced = debounce ( this . executeQuery , debounceMs ) ;
123124 } ;
124125
@@ -188,6 +189,9 @@ export class UserSearchSource<
188189> extends BaseSearchSource < UserResponse < StreamChatGenerics > > {
189190 readonly type = 'users' ;
190191 private client : StreamChat < StreamChatGenerics > ;
192+ filters : UserFilters < StreamChatGenerics > | undefined ;
193+ sort : UserSort < StreamChatGenerics > | undefined ;
194+ searchOptions : Omit < UserOptions , 'limit' | 'offset' > | undefined ;
191195
192196 constructor ( client : StreamChat < StreamChatGenerics > , options ?: SearchSourceOptions ) {
193197 super ( options ) ;
@@ -197,9 +201,10 @@ export class UserSearchSource<
197201 protected async query ( searchQuery : string ) {
198202 const filters = {
199203 $or : [ { id : { $autocomplete : searchQuery } } , { name : { $autocomplete : searchQuery } } ] ,
204+ ...this . filters ,
200205 } as UserFilters < StreamChatGenerics > ;
201- const sort = { id : 1 } as UserSort < StreamChatGenerics > ;
202- const options = { limit : this . pageSize , offset : this . offset } ;
206+ const sort = { id : 1 , ... this . sort } as UserSort < StreamChatGenerics > ;
207+ const options = { ... this . searchOptions , limit : this . pageSize , offset : this . offset } ;
203208 const { users } = await this . client . queryUsers ( filters , sort , options ) ;
204209 return { items : users } ;
205210 }
@@ -214,6 +219,9 @@ export class ChannelSearchSource<
214219> extends BaseSearchSource < Channel < StreamChatGenerics > > {
215220 readonly type = 'channels' ;
216221 private client : StreamChat < StreamChatGenerics > ;
222+ filters : ChannelFilters < StreamChatGenerics > | undefined ;
223+ sort : ChannelSort < StreamChatGenerics > | undefined ;
224+ searchOptions : Omit < ChannelOptions , 'limit' | 'offset' > | undefined ;
217225
218226 constructor ( client : StreamChat < StreamChatGenerics > , options ?: SearchSourceOptions ) {
219227 super ( options ) ;
@@ -224,9 +232,10 @@ export class ChannelSearchSource<
224232 const filters = {
225233 members : { $in : [ this . client . userID ] } ,
226234 name : { $autocomplete : searchQuery } ,
235+ ...this . filters ,
227236 } as ChannelFilters < StreamChatGenerics > ;
228- const sort = { } ;
229- const options = { limit : this . pageSize , offset : this . offset } ;
237+ const sort = this . sort ?? { } ;
238+ const options = { ... this . searchOptions , limit : this . pageSize , offset : this . offset } ;
230239 const items = await this . client . queryChannels ( filters , sort , options ) ;
231240 return { items } ;
232241 }
@@ -241,6 +250,12 @@ export class MessageSearchSource<
241250> extends BaseSearchSource < MessageResponse < StreamChatGenerics > > {
242251 readonly type = 'messages' ;
243252 private client : StreamChat < StreamChatGenerics > ;
253+ messageSearchChannelFilters : ChannelFilters < StreamChatGenerics > | undefined ;
254+ messageSearchFilters : MessageFilters < StreamChatGenerics > | undefined ;
255+ messageSearchSort : SearchMessageSort < StreamChatGenerics > | undefined ;
256+ channelQueryFilters : ChannelFilters < StreamChatGenerics > | undefined ;
257+ channelQuerySort : ChannelSort < StreamChatGenerics > | undefined ;
258+ channelQueryOptions : Omit < ChannelOptions , 'limit' | 'offset' > | undefined ;
244259
245260 constructor ( client : StreamChat < StreamChatGenerics > , options ?: SearchSourceOptions ) {
246261 super ( options ) ;
@@ -252,14 +267,19 @@ export class MessageSearchSource<
252267
253268 const channelFilters : ChannelFilters < StreamChatGenerics > = {
254269 members : { $in : [ this . client . userID ] } ,
270+ ...this . messageSearchChannelFilters ,
255271 } as ChannelFilters < StreamChatGenerics > ;
256272
257273 const messageFilters : MessageFilters < StreamChatGenerics > = {
258274 text : searchQuery ,
259- type : 'regular' , // todo: type: 'reply'
275+ type : 'regular' , // todo: type: 'reply' resp. do not filter by type and allow to jump to a message in a thread
276+ ...this . messageSearchFilters ,
260277 } as MessageFilters < StreamChatGenerics > ;
261278
262- const sort : SearchMessageSort < StreamChatGenerics > = { created_at : - 1 } ;
279+ const sort : SearchMessageSort < StreamChatGenerics > = {
280+ created_at : - 1 ,
281+ ...this . messageSearchSort ,
282+ } ;
263283
264284 const options = {
265285 limit : this . pageSize ,
@@ -269,6 +289,7 @@ export class MessageSearchSource<
269289
270290 const { next, results } = await this . client . search ( channelFilters , messageFilters , options ) ;
271291 const items = results . map ( ( { message } ) => message ) ;
292+
272293 const cids = Array . from (
273294 items . reduce ( ( acc , message ) => {
274295 if ( message . cid && ! this . client . activeChannels [ message . cid ] ) acc . add ( message . cid ) ;
@@ -280,10 +301,13 @@ export class MessageSearchSource<
280301 await this . client . queryChannels (
281302 {
282303 cid : { $in : cids } ,
304+ ...this . channelQueryFilters ,
283305 } as ChannelFilters < StreamChatGenerics > ,
284306 {
285307 last_message_at : - 1 ,
308+ ...this . channelQuerySort ,
286309 } ,
310+ this . channelQueryOptions ,
287311 ) ;
288312 }
289313
0 commit comments