@@ -30,8 +30,6 @@ open class ChatChannelListViewModel: ObservableObject, ChatChannelListController
3030 /// Temporarly holding changes while message list is shown.
3131 private var queuedChannelsChanges = LazyCachedMapCollection < ChatChannel > ( )
3232
33- private var messageSearchController : ChatMessageSearchController ?
34-
3533 private var timer : Timer ?
3634
3735 /// Controls loading the channels.
@@ -103,6 +101,13 @@ open class ChatChannelListViewModel: ObservableObject, ChatChannelListController
103101 }
104102 }
105103
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
106111 @Published public var searchText = " " {
107112 didSet {
108113 if searchText != oldValue {
@@ -111,10 +116,6 @@ open class ChatChannelListViewModel: ObservableObject, ChatChannelListController
111116 }
112117 }
113118
114- @Published public var loadingSearchResults = false
115- @Published public var searchResults = [ ChannelSelectionInfo] ( )
116- @Published var hideTabBar = false
117-
118119 public var isSearching : Bool {
119120 !searchText. isEmpty
120121 }
@@ -125,10 +126,13 @@ open class ChatChannelListViewModel: ObservableObject, ChatChannelListController
125126 /// - channelListController: A controller providing the list of channels. If nil, a controller with default `ChannelListQuery` is created.
126127 /// - selectedChannelId: The id of a channel to select. If the channel is not part of the channel list query, no channel is selected.
127128 /// 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.
128130 public init (
129131 channelListController: ChatChannelListController ? = nil ,
130- selectedChannelId: String ? = nil
132+ selectedChannelId: String ? = nil ,
133+ searchType: ChannelListSearchType = . channels
131134 ) {
135+ self . searchType = searchType
132136 self . selectedChannelId = selectedChannelId
133137 if let channelListController = channelListController {
134138 controller = channelListController
@@ -168,21 +172,13 @@ open class ChatChannelListViewModel: ObservableObject, ChatChannelListController
168172 }
169173
170174 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
186182 }
187183 }
188184
@@ -258,7 +254,7 @@ open class ChatChannelListViewModel: ObservableObject, ChatChannelListController
258254 // MARK: - ChatMessageSearchControllerDelegate
259255
260256 public func controller( _ controller: ChatMessageSearchController , didChangeMessages changes: [ ListChange < ChatMessage > ] ) {
261- updateSearchResults ( )
257+ updateMessageSearchResults ( )
262258 }
263259
264260 // MARK: - private
@@ -340,7 +336,93 @@ open class ChatChannelListViewModel: ObservableObject, ChatChannelListController
340336 . filter { $0. id != chatClient. currentUserId }
341337 }
342338
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( ) {
344426 guard let messageSearchController = messageSearchController else {
345427 return
346428 }
@@ -351,26 +433,28 @@ open class ChatChannelListViewModel: ObservableObject, ChatChannelListController
351433 }
352434 }
353435
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
373439 }
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 ( )
374458 }
375459
376460 private func observeClientIdChange( ) {
@@ -491,3 +575,15 @@ public enum ChannelPopupType {
491575 /// Shows the 'more actions' popup.
492576 case moreActions( ChatChannel )
493577}
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