From c6655472fa2819e7070722919bf869cf2d0ce708 Mon Sep 17 00:00:00 2001 From: Toomas Vahter Date: Wed, 18 Dec 2024 12:44:13 +0200 Subject: [PATCH] Add additional sorting and filter keys for member list query (#3535) * Add member list filtering keys: FilterKey.channelRole and FilterKey.email * Add member list sorting key: ChannelMemberListSortingKey.channelRole * Encode MemberRole.member as channel_member and MemberRole.moderator as channel_moderator --- CHANGELOG.md | 2 ++ Sources/StreamChat/Models/Member.swift | 12 ++++++++++++ .../StreamChat/Query/ChannelMemberListQuery.swift | 8 ++++++++ Sources/StreamChat/Query/Filter.swift | 1 + .../Query/Sorting/ChannelMemberListSortingKey.swift | 5 ++++- .../Query/MemberListFilterScope_Tests.swift | 2 ++ .../Sorting/ChannelMemberListSortingKey_Tests.swift | 4 +++- 7 files changed, 32 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a9082b9ade6..68b2add74ed 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,6 +18,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). - Add `ChannelListSortingKey.pinnedAt` - Add `ChatChannel.membership.pinnedAt` - Add `ChatChannel.isPinned` +- Add member list filtering keys: `FilterKey.channelRole` and `FilterKey.email` [#3535](https://github.com/GetStream/stream-chat-swift/pull/3535) +- Add member list sorting key: `ChannelMemberListSortingKey.channelRole` [#3535](https://github.com/GetStream/stream-chat-swift/pull/3535) ### 🐞 Fixed - End background task before starting a new one [#3528](https://github.com/GetStream/stream-chat-swift/pull/3528) diff --git a/Sources/StreamChat/Models/Member.swift b/Sources/StreamChat/Models/Member.swift index d7126c48638..25d12c3cd14 100644 --- a/Sources/StreamChat/Models/Member.swift +++ b/Sources/StreamChat/Models/Member.swift @@ -159,6 +159,18 @@ public extension MemberRole { self = MemberRole(rawValue: value) } } + + func encode(to encoder: any Encoder) throws { + var container = encoder.singleValueContainer() + switch self { + case .member: + try container.encode("channel_member") + case .moderator: + try container.encode("channel_moderator") + default: + try container.encode(rawValue) + } + } } /// The member information when adding a member to a channel. diff --git a/Sources/StreamChat/Query/ChannelMemberListQuery.swift b/Sources/StreamChat/Query/ChannelMemberListQuery.swift index 72f1c773eec..293909ec790 100644 --- a/Sources/StreamChat/Query/ChannelMemberListQuery.swift +++ b/Sources/StreamChat/Query/ChannelMemberListQuery.swift @@ -24,6 +24,14 @@ public extension FilterKey where Scope: AnyMemberListFilterScope { /// Filter key matching the name of the user /// Supported operators: `equal`, `notEqual`, `in`, `notIn`, `autocomplete`, `query` static var name: FilterKey { "name" } + + /// Filter key matching the email of the user + /// Supported operators: `equal`, `in`, `autocomplete` + static var email: FilterKey { "user.email" } + + /// Filter key matching the channel role of the user + /// Supported operators: `equal` + static var channelRole: FilterKey { "channel_role" } /// Filter key matching the banned status /// Supported operators: `equal` diff --git a/Sources/StreamChat/Query/Filter.swift b/Sources/StreamChat/Query/Filter.swift index 869bda0dd15..4c0d6076b08 100644 --- a/Sources/StreamChat/Query/Filter.swift +++ b/Sources/StreamChat/Query/Filter.swift @@ -80,6 +80,7 @@ extension Filter: FilterValue {} extension ChannelId: FilterValue {} extension ChannelType: FilterValue {} +extension MemberRole: FilterValue {} extension UserRole: FilterValue {} extension AttachmentType: FilterValue {} extension Optional: FilterValue where Wrapped == TeamId {} diff --git a/Sources/StreamChat/Query/Sorting/ChannelMemberListSortingKey.swift b/Sources/StreamChat/Query/Sorting/ChannelMemberListSortingKey.swift index 51dccd9a55a..aa3bb07c58f 100644 --- a/Sources/StreamChat/Query/Sorting/ChannelMemberListSortingKey.swift +++ b/Sources/StreamChat/Query/Sorting/ChannelMemberListSortingKey.swift @@ -16,13 +16,16 @@ public enum ChannelMemberListSortingKey: String, SortingKey { /// /// - Warning: This option is heavy for the backend and can slow down API requests' response time. If there's no explicit requirement for this sorting option consider using a different one. case name = "user.name" + + /// Sort channel members by their channel role. + case channelRole = "channelRoleRaw" public func encode(to encoder: Encoder) throws { var container = encoder.singleValueContainer() let value: String switch self { - /// Sort channel members by date they were created. + case .channelRole: value = "channel_role" case .createdAt: value = "created_at" case .name: value = "name" case .userId: value = "user_id" diff --git a/Tests/StreamChatTests/Query/MemberListFilterScope_Tests.swift b/Tests/StreamChatTests/Query/MemberListFilterScope_Tests.swift index 2e3d887956e..88b559e6ebc 100644 --- a/Tests/StreamChatTests/Query/MemberListFilterScope_Tests.swift +++ b/Tests/StreamChatTests/Query/MemberListFilterScope_Tests.swift @@ -12,6 +12,8 @@ final class MemberListFilterScope_Tests: XCTestCase { func test_filterKeys_matchChannelCodingKeys() { // Member specific coding keys XCTAssertEqual(Key.isModerator.rawValue, "is_moderator") + XCTAssertEqual(Key.email.rawValue, "user.email") + XCTAssertEqual(Key.channelRole.rawValue, "channel_role") // User-related coding keys XCTAssertEqual(Key.id.rawValue, UserPayloadsCodingKeys.id.rawValue) diff --git a/Tests/StreamChatTests/Query/Sorting/ChannelMemberListSortingKey_Tests.swift b/Tests/StreamChatTests/Query/Sorting/ChannelMemberListSortingKey_Tests.swift index d075123dcab..9f8b4ebf6ac 100644 --- a/Tests/StreamChatTests/Query/Sorting/ChannelMemberListSortingKey_Tests.swift +++ b/Tests/StreamChatTests/Query/Sorting/ChannelMemberListSortingKey_Tests.swift @@ -11,7 +11,7 @@ final class ChannelMemberListSortingKey_Tests: XCTestCase { func test_sortDescriptor_keyPaths_areValid() throws { // Put all `ChannelMemberListSortingKey`s in an array // We don't use `CaseIterable` since we only need this for tests - let sortingKeys: [ChannelMemberListSortingKey] = [.createdAt, .name, .userId] + let sortingKeys: [ChannelMemberListSortingKey] = [.createdAt, .name, .channelRole, .userId] // Iterate over keys... for key in sortingKeys { @@ -24,6 +24,8 @@ final class ChannelMemberListSortingKey_Tests: XCTestCase { ChannelMemberListSortingKey.name.rawValue, NSExpression(forKeyPath: \MemberDTO.user.name).keyPath ) + case .channelRole: + XCTAssertEqual(key.rawValue, KeyPath.string(\MemberDTO.channelRoleRaw)) case .userId: XCTAssertEqual(key.rawValue, NSExpression(forKeyPath: \MemberDTO.user.id).keyPath) }