@@ -30,8 +30,6 @@ open class ChatChannelListViewModel: ObservableObject, ChatChannelListController
30
30
/// Temporarly holding changes while message list is shown.
31
31
private var queuedChannelsChanges = LazyCachedMapCollection < ChatChannel > ( )
32
32
33
- private var messageSearchController : ChatMessageSearchController ?
34
-
35
33
private var timer : Timer ?
36
34
37
35
/// Controls loading the channels.
@@ -103,6 +101,13 @@ open class ChatChannelListViewModel: ObservableObject, ChatChannelListController
103
101
}
104
102
}
105
103
104
+ private let searchType : ChannelListSearchType
105
+ internal var channelListSearchController : ChatChannelListController ?
106
+ internal var messageSearchController : ChatMessageSearchController ?
107
+
108
+ @Published public var loadingSearchResults = false
109
+ @Published public var searchResults = [ ChannelSelectionInfo] ( )
110
+ @Published var hideTabBar = false
106
111
@Published public var searchText = " " {
107
112
didSet {
108
113
if searchText != oldValue {
@@ -111,10 +116,6 @@ open class ChatChannelListViewModel: ObservableObject, ChatChannelListController
111
116
}
112
117
}
113
118
114
- @Published public var loadingSearchResults = false
115
- @Published public var searchResults = [ ChannelSelectionInfo] ( )
116
- @Published var hideTabBar = false
117
-
118
119
public var isSearching : Bool {
119
120
!searchText. isEmpty
120
121
}
@@ -125,10 +126,13 @@ open class ChatChannelListViewModel: ObservableObject, ChatChannelListController
125
126
/// - channelListController: A controller providing the list of channels. If nil, a controller with default `ChannelListQuery` is created.
126
127
/// - selectedChannelId: The id of a channel to select. If the channel is not part of the channel list query, no channel is selected.
127
128
/// Consider using ``ChatChannelScreen`` for presenting channels what might not be part of the initial page of channels.
129
+ /// - searchType: The type of data the channel list should perform a search.
128
130
public init (
129
131
channelListController: ChatChannelListController ? = nil ,
130
- selectedChannelId: String ? = nil
132
+ selectedChannelId: String ? = nil ,
133
+ searchType: ChannelListSearchType = . channels
131
134
) {
135
+ self . searchType = searchType
132
136
self . selectedChannelId = selectedChannelId
133
137
if let channelListController = channelListController {
134
138
controller = channelListController
@@ -168,21 +172,13 @@ open class ChatChannelListViewModel: ObservableObject, ChatChannelListController
168
172
}
169
173
170
174
public func loadAdditionalSearchResults( index: Int ) {
171
- guard let messageSearchController = messageSearchController else {
172
- return
173
- }
174
-
175
- if index < messageSearchController. messages. count - 10 {
176
- return
177
- }
178
-
179
- if !loadingNextChannels {
180
- loadingNextChannels = true
181
- messageSearchController. loadNextMessages { [ weak self] _ in
182
- guard let self = self else { return }
183
- self . loadingNextChannels = false
184
- self . updateSearchResults ( )
185
- }
175
+ switch searchType {
176
+ case . channels:
177
+ loadAdditionalChannelSearchResults ( index: index)
178
+ case . messages:
179
+ loadAdditionalMessageSearchResults ( index: index)
180
+ default :
181
+ break
186
182
}
187
183
}
188
184
@@ -258,7 +254,7 @@ open class ChatChannelListViewModel: ObservableObject, ChatChannelListController
258
254
// MARK: - ChatMessageSearchControllerDelegate
259
255
260
256
public func controller( _ controller: ChatMessageSearchController , didChangeMessages changes: [ ListChange < ChatMessage > ] ) {
261
- updateSearchResults ( )
257
+ updateMessageSearchResults ( )
262
258
}
263
259
264
260
// MARK: - private
@@ -340,7 +336,93 @@ open class ChatChannelListViewModel: ObservableObject, ChatChannelListController
340
336
. filter { $0. id != chatClient. currentUserId }
341
337
}
342
338
343
- private func updateSearchResults( ) {
339
+ private func handleSearchTextChange( ) {
340
+ if searchText. isEmpty {
341
+ clearSearchResults ( )
342
+ return
343
+ }
344
+
345
+ switch searchType {
346
+ case . messages:
347
+ performMessageSearch ( )
348
+ case . channels:
349
+ performChannelSearch ( )
350
+ default :
351
+ break
352
+ }
353
+ }
354
+
355
+ private func loadAdditionalMessageSearchResults( index: Int ) {
356
+ guard let messageSearchController = messageSearchController else {
357
+ return
358
+ }
359
+
360
+ if index < messageSearchController. messages. count - 10 {
361
+ return
362
+ }
363
+
364
+ if !loadingNextChannels {
365
+ loadingNextChannels = true
366
+ messageSearchController. loadNextMessages { [ weak self] _ in
367
+ guard let self = self else { return }
368
+ self . loadingNextChannels = false
369
+ self . updateMessageSearchResults ( )
370
+ }
371
+ }
372
+ }
373
+
374
+ private func loadAdditionalChannelSearchResults( index: Int ) {
375
+ guard let channelListSearchController = self . channelListSearchController else {
376
+ return
377
+ }
378
+
379
+ if index < channelListSearchController. channels. count - 10 {
380
+ return
381
+ }
382
+
383
+ if !loadingNextChannels {
384
+ loadingNextChannels = true
385
+ channelListSearchController. loadNextChannels { [ weak self] _ in
386
+ guard let self = self else { return }
387
+ self . loadingNextChannels = false
388
+ self . updateChannelSearchResults ( )
389
+ }
390
+ }
391
+ }
392
+
393
+ private func performMessageSearch( ) {
394
+ guard let userId = chatClient. currentUserId else { return }
395
+ messageSearchController = chatClient. messageSearchController ( )
396
+ messageSearchController? . delegate = self
397
+ let query = MessageSearchQuery (
398
+ channelFilter: . containMembers( userIds: [ userId] ) ,
399
+ messageFilter: . autocomplete( . text, text: searchText)
400
+ )
401
+ loadingSearchResults = true
402
+ messageSearchController? . search ( query: query, completion: { [ weak self] _ in
403
+ self ? . loadingSearchResults = false
404
+ self ? . updateMessageSearchResults ( )
405
+ } )
406
+ }
407
+
408
+ private func performChannelSearch( ) {
409
+ guard let userId = chatClient. currentUserId else { return }
410
+ var query = ChannelListQuery (
411
+ filter: . and( [
412
+ . autocomplete( . name, text: searchText) ,
413
+ . containMembers( userIds: [ userId] )
414
+ ] )
415
+ )
416
+ query. options = [ ]
417
+ channelListSearchController = chatClient. channelListController ( query: query)
418
+ loadingSearchResults = true
419
+ channelListSearchController? . synchronize { [ weak self] _ in
420
+ self ? . loadingSearchResults = false
421
+ self ? . updateChannelSearchResults ( )
422
+ }
423
+ }
424
+
425
+ private func updateMessageSearchResults( ) {
344
426
guard let messageSearchController = messageSearchController else {
345
427
return
346
428
}
@@ -351,26 +433,28 @@ open class ChatChannelListViewModel: ObservableObject, ChatChannelListController
351
433
}
352
434
}
353
435
354
- private func handleSearchTextChange( ) {
355
- if !searchText. isEmpty {
356
- guard let userId = chatClient. currentUserId else { return }
357
- messageSearchController = chatClient. messageSearchController ( )
358
- messageSearchController? . delegate = self
359
- let query = MessageSearchQuery (
360
- channelFilter: . containMembers( userIds: [ userId] ) ,
361
- messageFilter: . autocomplete( . text, text: searchText)
362
- )
363
- loadingSearchResults = true
364
- messageSearchController? . search ( query: query, completion: { [ weak self] _ in
365
- self ? . loadingSearchResults = false
366
- self ? . updateSearchResults ( )
367
- } )
368
- } else {
369
- messageSearchController? . delegate = nil
370
- messageSearchController = nil
371
- searchResults = [ ]
372
- updateChannels ( )
436
+ private func updateChannelSearchResults( ) {
437
+ guard let channelListSearchController = self . channelListSearchController else {
438
+ return
373
439
}
440
+
441
+ searchResults = channelListSearchController. channels
442
+ . compactMap { channel in
443
+ ChannelSelectionInfo (
444
+ channel: channel,
445
+ message: channel. previewMessage,
446
+ searchType: . channels
447
+ )
448
+ }
449
+ }
450
+
451
+ private func clearSearchResults( ) {
452
+ messageSearchController? . delegate = nil
453
+ messageSearchController = nil
454
+ channelListSearchController? . delegate = nil
455
+ channelListSearchController = nil
456
+ searchResults = [ ]
457
+ updateChannels ( )
374
458
}
375
459
376
460
private func observeClientIdChange( ) {
@@ -491,3 +575,15 @@ public enum ChannelPopupType {
491
575
/// Shows the 'more actions' popup.
492
576
case moreActions( ChatChannel )
493
577
}
578
+
579
+ /// The type of data the channel list should perform a search.
580
+ public struct ChannelListSearchType : Equatable {
581
+ let type : String
582
+
583
+ private init ( type: String ) {
584
+ self . type = type
585
+ }
586
+
587
+ public static var channels = Self ( type: " channels " )
588
+ public static var messages = Self ( type: " messages " )
589
+ }
0 commit comments