diff --git a/CHANGELOG.md b/CHANGELOG.md index 9ca6b8df..8b3ba053 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,7 +3,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). # Upcoming -### 🔄 Changed +### ✅ Added +- Factory method for customizing the search results view # [4.47.1](https://github.com/GetStream/stream-chat-swiftui/releases/tag/4.47.1) _January 29, 2024_ diff --git a/Sources/StreamChatSwiftUI/ChatChannelList/ChatChannelListView.swift b/Sources/StreamChatSwiftUI/ChatChannelList/ChatChannelListView.swift index 7ad4e100..d21b4a8f 100644 --- a/Sources/StreamChatSwiftUI/ChatChannelList/ChatChannelListView.swift +++ b/Sources/StreamChatSwiftUI/ChatChannelList/ChatChannelListView.swift @@ -208,8 +208,7 @@ public struct ChatChannelListContentView: View { ) if viewModel.isSearching { - SearchResultsView( - factory: viewFactory, + viewFactory.makeSearchResultsView( selectedChannel: $viewModel.selectedChannel, searchResults: viewModel.searchResults, loadingSearchResults: viewModel.loadingSearchResults, diff --git a/Sources/StreamChatSwiftUI/DefaultViewFactory.swift b/Sources/StreamChatSwiftUI/DefaultViewFactory.swift index d680853f..6d94fe63 100644 --- a/Sources/StreamChatSwiftUI/DefaultViewFactory.swift +++ b/Sources/StreamChatSwiftUI/DefaultViewFactory.swift @@ -145,6 +145,29 @@ extension ViewFactory { EmptyView() } + public func makeSearchResultsView( + selectedChannel: Binding, + searchResults: [ChannelSelectionInfo], + loadingSearchResults: Bool, + onlineIndicatorShown: @escaping (ChatChannel) -> Bool, + channelNaming: @escaping (ChatChannel) -> String, + imageLoader: @escaping (ChatChannel) -> UIImage, + onSearchResultTap: @escaping (ChannelSelectionInfo) -> Void, + onItemAppear: @escaping (Int) -> Void + ) -> some View { + SearchResultsView( + factory: self, + selectedChannel: selectedChannel, + searchResults: searchResults, + loadingSearchResults: loadingSearchResults, + onlineIndicatorShown: onlineIndicatorShown, + channelNaming: channelNaming, + imageLoader: imageLoader, + onSearchResultTap: onSearchResultTap, + onItemAppear: onItemAppear + ) + } + public func makeChannelListSearchResultItem( searchResult: ChannelSelectionInfo, onlineIndicatorShown: Bool, diff --git a/Sources/StreamChatSwiftUI/ViewFactory.swift b/Sources/StreamChatSwiftUI/ViewFactory.swift index 954df7ef..8efef483 100644 --- a/Sources/StreamChatSwiftUI/ViewFactory.swift +++ b/Sources/StreamChatSwiftUI/ViewFactory.swift @@ -148,6 +148,29 @@ public protocol ViewFactory: AnyObject { /// Creates the view always visible at the bottom of the channel list. /// - Returns: view shown at the bottom of the channel list. func makeChannelListStickyFooterView() -> ChannelListStickyFooterViewType + + associatedtype ChannelListSearchResultsViewType: View + /// Creates the view shown when the user is searching the channel list. + /// - Parameters: + /// - selectedChannel - binding of the selected channel. + /// - searchResults - the search results matching the user query. + /// - loadingSearchResults - whether search results are being loaded. + /// - onlineIndicatorShown - whether the online indicator is shown. + /// - channelNaming - closure for determining the channel name. + /// - imageLoader - closure for loading images for channels. + /// - onSearchResultTap - call when a search result is tapped. + /// - onItemAppear - call when an item appears on the screen. + /// - Returns: view shown in the channel list search results slot. + func makeSearchResultsView( + selectedChannel: Binding, + searchResults: [ChannelSelectionInfo], + loadingSearchResults: Bool, + onlineIndicatorShown: @escaping (ChatChannel) -> Bool, + channelNaming: @escaping (ChatChannel) -> String, + imageLoader: @escaping (ChatChannel) -> UIImage, + onSearchResultTap: @escaping (ChannelSelectionInfo) -> Void, + onItemAppear: @escaping (Int) -> Void + ) -> ChannelListSearchResultsViewType associatedtype ChannelListSearchResultItem: View /// Creates the search result item in the channel list. diff --git a/StreamChatSwiftUITests/Infrastructure/TestTools/ChatClient_Mock.swift b/StreamChatSwiftUITests/Infrastructure/TestTools/ChatClient_Mock.swift index 9e344f43..fabbe2a6 100644 --- a/StreamChatSwiftUITests/Infrastructure/TestTools/ChatClient_Mock.swift +++ b/StreamChatSwiftUITests/Infrastructure/TestTools/ChatClient_Mock.swift @@ -15,6 +15,7 @@ public extension ChatClient { config.customCDNClient = customCDNClient config.isLocalStorageEnabled = isLocalStorageEnabled config.isClientInActiveMode = false + config.maxAttachmentCountPerMessage = 10 return .init( config: config, diff --git a/StreamChatSwiftUITests/Tests/Utils/ViewFactory_Tests.swift b/StreamChatSwiftUITests/Tests/Utils/ViewFactory_Tests.swift index a2113efd..df21339f 100644 --- a/StreamChatSwiftUITests/Tests/Utils/ViewFactory_Tests.swift +++ b/StreamChatSwiftUITests/Tests/Utils/ViewFactory_Tests.swift @@ -99,6 +99,26 @@ class ViewFactory_Tests: StreamChatTestCase { // Then XCTAssert(view is MoreChannelActionsView) } + + func test_viewFactory_makeSearchResultsView() { + // Given + let viewFactory = DefaultViewFactory.shared + + // When + let view = viewFactory.makeSearchResultsView( + selectedChannel: .constant(nil), + searchResults: [], + loadingSearchResults: false, + onlineIndicatorShown: { _ in true }, + channelNaming: { _ in "Test" }, + imageLoader: { _ in UIImage(systemName: "person")! }, + onSearchResultTap: { _ in }, + onItemAppear: { _ in } + ) + + // Then + XCTAssert(view is SearchResultsView) + } func test_viewFactory_makeMessageAvatarView() { // Given