Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
f168626
Add 'PredefinedFilters' support in the LLC.
VelikovPetar Apr 28, 2026
017a2df
Merge branch 'develop' into feature/AND-1162_predefined_filters
VelikovPetar Apr 29, 2026
0b1210d
Add 'sort' parsing logic.
VelikovPetar Apr 29, 2026
9453c5a
Add 'sort' parsing logic.
VelikovPetar Apr 29, 2026
e27aa81
Propagate PredefinedFilter to QueryChannels plugins.
VelikovPetar Apr 29, 2026
e049f84
Add JSON -> FilterObject mapping.
VelikovPetar Apr 30, 2026
7a47eca
Add State/DB support for PredefinedFilter.
VelikovPetar May 4, 2026
c1730f1
Merge branch 'develop' into feature/AND-1162_predefined_filters
VelikovPetar May 4, 2026
e92f508
Simplify KDocs.
VelikovPetar May 4, 2026
932fe6e
Merge branch 'develop' into feature/AND-1162_predefined_filters
VelikovPetar May 5, 2026
c229606
Add UI support for PredefinedFilters.
VelikovPetar May 6, 2026
a61f5c5
Merge branch 'develop' into feature/AND-1162_predefined_filters
VelikovPetar May 6, 2026
71c9f16
Fix test.
VelikovPetar May 6, 2026
dffff3e
Migrate samples to use PredefinedFilters.
VelikovPetar May 6, 2026
ef5d14d
Remove TODOs.
VelikovPetar May 6, 2026
ff695e3
Merge branch 'develop' into feature/AND-1162_predefined_filters
VelikovPetar May 6, 2026
8528de8
Address PR remarks.
VelikovPetar May 7, 2026
4da1851
Use copy instead of creating new object.
VelikovPetar May 7, 2026
862f11f
Revert default search mode.
VelikovPetar May 8, 2026
2393640
Merge branch 'develop' into feature/AND-1162_predefined_filters
VelikovPetar May 11, 2026
1ff4411
Calculate fallback sort order based on predefined filter values.
VelikovPetar May 11, 2026
d2a71dd
Address PR remarks.
VelikovPetar May 11, 2026
624206b
Add queryFirstPage tests.
VelikovPetar May 11, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -662,7 +662,17 @@ public fun randomQueryChannelsSpec(
filter: FilterObject = NeutralFilterObject,
sort: QuerySorter<Channel> = QuerySortByField(),
cids: Set<String> = emptySet(),
): QueryChannelsSpec = QueryChannelsSpec(filter, sort).apply { this.cids = cids }
predefinedFilterName: String? = null,
predefinedFilterValues: Map<String, Any>? = null,
predefinedSortValues: Map<String, Any>? = null,
): QueryChannelsSpec = QueryChannelsSpec(
filter = filter,
querySort = sort,
cids = cids,
predefinedFilterName = predefinedFilterName,
predefinedFilterValues = predefinedFilterValues,
predefinedSortValues = predefinedSortValues,
)

public fun randomNotificationRemovedFromChannelEvent(
cid: String = randomCID(),
Expand Down
65 changes: 62 additions & 3 deletions stream-chat-android-client/api/stream-chat-android-client.api
Original file line number Diff line number Diff line change
Expand Up @@ -582,25 +582,45 @@ public class io/getstream/chat/android/client/api/models/QueryChannelRequest : i
}

public final class io/getstream/chat/android/client/api/models/QueryChannelsRequest : io/getstream/chat/android/client/api/models/ChannelRequest {
public fun <init> (Lio/getstream/chat/android/models/FilterObject;I)V
public fun <init> (Lio/getstream/chat/android/models/FilterObject;II)V
public fun <init> (Lio/getstream/chat/android/models/FilterObject;IILio/getstream/chat/android/models/querysort/QuerySorter;)V
public fun <init> (Lio/getstream/chat/android/models/FilterObject;IILio/getstream/chat/android/models/querysort/QuerySorter;Ljava/lang/Integer;)V
public fun <init> (Lio/getstream/chat/android/models/FilterObject;IILio/getstream/chat/android/models/querysort/QuerySorter;Ljava/lang/Integer;Ljava/lang/Integer;)V
public synthetic fun <init> (Lio/getstream/chat/android/models/FilterObject;IILio/getstream/chat/android/models/querysort/QuerySorter;Ljava/lang/Integer;Ljava/lang/Integer;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
public fun <init> (Lio/getstream/chat/android/models/FilterObject;IILio/getstream/chat/android/models/querysort/QuerySorter;Ljava/lang/Integer;Ljava/lang/Integer;Ljava/lang/String;)V
public fun <init> (Lio/getstream/chat/android/models/FilterObject;IILio/getstream/chat/android/models/querysort/QuerySorter;Ljava/lang/Integer;Ljava/lang/Integer;Ljava/lang/String;Ljava/util/Map;)V
public fun <init> (Lio/getstream/chat/android/models/FilterObject;IILio/getstream/chat/android/models/querysort/QuerySorter;Ljava/lang/Integer;Ljava/lang/Integer;Ljava/lang/String;Ljava/util/Map;Ljava/util/Map;)V
public synthetic fun <init> (Lio/getstream/chat/android/models/FilterObject;IILio/getstream/chat/android/models/querysort/QuerySorter;Ljava/lang/Integer;Ljava/lang/Integer;Ljava/lang/String;Ljava/util/Map;Ljava/util/Map;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
public fun <init> (Ljava/lang/String;I)V
public fun <init> (Ljava/lang/String;ILjava/util/Map;)V
public fun <init> (Ljava/lang/String;ILjava/util/Map;Ljava/util/Map;)V
public fun <init> (Ljava/lang/String;ILjava/util/Map;Ljava/util/Map;I)V
public fun <init> (Ljava/lang/String;ILjava/util/Map;Ljava/util/Map;ILjava/lang/Integer;)V
public fun <init> (Ljava/lang/String;ILjava/util/Map;Ljava/util/Map;ILjava/lang/Integer;Ljava/lang/Integer;)V
public synthetic fun <init> (Ljava/lang/String;ILjava/util/Map;Ljava/util/Map;ILjava/lang/Integer;Ljava/lang/Integer;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
public final fun component1 ()Lio/getstream/chat/android/models/FilterObject;
public final fun component2 ()I
public final fun component3 ()I
public final fun component4 ()Lio/getstream/chat/android/models/querysort/QuerySorter;
public final fun component5 ()Ljava/lang/Integer;
public final fun component6 ()Ljava/lang/Integer;
public final fun copy (Lio/getstream/chat/android/models/FilterObject;IILio/getstream/chat/android/models/querysort/QuerySorter;Ljava/lang/Integer;Ljava/lang/Integer;)Lio/getstream/chat/android/client/api/models/QueryChannelsRequest;
public static synthetic fun copy$default (Lio/getstream/chat/android/client/api/models/QueryChannelsRequest;Lio/getstream/chat/android/models/FilterObject;IILio/getstream/chat/android/models/querysort/QuerySorter;Ljava/lang/Integer;Ljava/lang/Integer;ILjava/lang/Object;)Lio/getstream/chat/android/client/api/models/QueryChannelsRequest;
public final fun component7 ()Ljava/lang/String;
public final fun component8 ()Ljava/util/Map;
public final fun component9 ()Ljava/util/Map;
public final fun copy (Lio/getstream/chat/android/models/FilterObject;IILio/getstream/chat/android/models/querysort/QuerySorter;Ljava/lang/Integer;Ljava/lang/Integer;Ljava/lang/String;Ljava/util/Map;Ljava/util/Map;)Lio/getstream/chat/android/client/api/models/QueryChannelsRequest;
public static synthetic fun copy$default (Lio/getstream/chat/android/client/api/models/QueryChannelsRequest;Lio/getstream/chat/android/models/FilterObject;IILio/getstream/chat/android/models/querysort/QuerySorter;Ljava/lang/Integer;Ljava/lang/Integer;Ljava/lang/String;Ljava/util/Map;Ljava/util/Map;ILjava/lang/Object;)Lio/getstream/chat/android/client/api/models/QueryChannelsRequest;
public fun equals (Ljava/lang/Object;)Z
public final fun getFilter ()Lio/getstream/chat/android/models/FilterObject;
public final fun getFilterValues ()Ljava/util/Map;
public final fun getLimit ()I
public final fun getMemberLimit ()Ljava/lang/Integer;
public final fun getMessageLimit ()Ljava/lang/Integer;
public final fun getOffset ()I
public final fun getPredefinedFilter ()Ljava/lang/String;
public fun getPresence ()Z
public final fun getQuerySort ()Lio/getstream/chat/android/models/querysort/QuerySorter;
public final fun getSort ()Ljava/util/List;
public final fun getSortValues ()Ljava/util/Map;
public fun getState ()Z
public fun getWatch ()Z
public fun hashCode ()I
Expand Down Expand Up @@ -3051,6 +3071,34 @@ public final class io/getstream/chat/android/client/internal/offline/repository/
public fun toString ()Ljava/lang/String;
}

public final class io/getstream/chat/android/client/internal/state/plugin/QueryChannelsIdentifier$Predefined : io/getstream/chat/android/client/internal/state/plugin/QueryChannelsIdentifier {
public fun <init> (Ljava/lang/String;Ljava/util/Map;Ljava/util/Map;)V
public final fun component1 ()Ljava/lang/String;
public final fun component2 ()Ljava/util/Map;
public final fun component3 ()Ljava/util/Map;
public final fun copy (Ljava/lang/String;Ljava/util/Map;Ljava/util/Map;)Lio/getstream/chat/android/client/internal/state/plugin/QueryChannelsIdentifier$Predefined;
public static synthetic fun copy$default (Lio/getstream/chat/android/client/internal/state/plugin/QueryChannelsIdentifier$Predefined;Ljava/lang/String;Ljava/util/Map;Ljava/util/Map;ILjava/lang/Object;)Lio/getstream/chat/android/client/internal/state/plugin/QueryChannelsIdentifier$Predefined;
public fun equals (Ljava/lang/Object;)Z
public final fun getFilterValues ()Ljava/util/Map;
public final fun getName ()Ljava/lang/String;
public final fun getSortValues ()Ljava/util/Map;
public fun hashCode ()I
public fun toString ()Ljava/lang/String;
}

public final class io/getstream/chat/android/client/internal/state/plugin/QueryChannelsIdentifier$Standard : io/getstream/chat/android/client/internal/state/plugin/QueryChannelsIdentifier {
public fun <init> (Lio/getstream/chat/android/models/FilterObject;Lio/getstream/chat/android/models/querysort/QuerySorter;)V
public final fun component1 ()Lio/getstream/chat/android/models/FilterObject;
public final fun component2 ()Lio/getstream/chat/android/models/querysort/QuerySorter;
public final fun copy (Lio/getstream/chat/android/models/FilterObject;Lio/getstream/chat/android/models/querysort/QuerySorter;)Lio/getstream/chat/android/client/internal/state/plugin/QueryChannelsIdentifier$Standard;
public static synthetic fun copy$default (Lio/getstream/chat/android/client/internal/state/plugin/QueryChannelsIdentifier$Standard;Lio/getstream/chat/android/models/FilterObject;Lio/getstream/chat/android/models/querysort/QuerySorter;ILjava/lang/Object;)Lio/getstream/chat/android/client/internal/state/plugin/QueryChannelsIdentifier$Standard;
public fun equals (Ljava/lang/Object;)Z
public final fun getFilter ()Lio/getstream/chat/android/models/FilterObject;
public final fun getSort ()Lio/getstream/chat/android/models/querysort/QuerySorter;
public fun hashCode ()I
public fun toString ()Ljava/lang/String;
}

public final class io/getstream/chat/android/client/logger/ChatLogLevel : java/lang/Enum {
public static final field ALL Lio/getstream/chat/android/client/logger/ChatLogLevel;
public static final field DEBUG Lio/getstream/chat/android/client/logger/ChatLogLevel;
Expand Down Expand Up @@ -3275,13 +3323,24 @@ public final class io/getstream/chat/android/client/query/CreateChannelParams {

public final class io/getstream/chat/android/client/query/QueryChannelsSpec {
public fun <init> (Lio/getstream/chat/android/models/FilterObject;Lio/getstream/chat/android/models/querysort/QuerySorter;)V
public fun <init> (Lio/getstream/chat/android/models/FilterObject;Lio/getstream/chat/android/models/querysort/QuerySorter;Ljava/util/Set;Ljava/lang/String;Ljava/util/Map;Ljava/util/Map;)V
public synthetic fun <init> (Lio/getstream/chat/android/models/FilterObject;Lio/getstream/chat/android/models/querysort/QuerySorter;Ljava/util/Set;Ljava/lang/String;Ljava/util/Map;Ljava/util/Map;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
public final fun component1 ()Lio/getstream/chat/android/models/FilterObject;
public final fun component2 ()Lio/getstream/chat/android/models/querysort/QuerySorter;
public final fun component3 ()Ljava/util/Set;
public final fun component4 ()Ljava/lang/String;
public final fun component5 ()Ljava/util/Map;
public final fun component6 ()Ljava/util/Map;
public final fun copy (Lio/getstream/chat/android/models/FilterObject;Lio/getstream/chat/android/models/querysort/QuerySorter;)Lio/getstream/chat/android/client/query/QueryChannelsSpec;
public final fun copy (Lio/getstream/chat/android/models/FilterObject;Lio/getstream/chat/android/models/querysort/QuerySorter;Ljava/util/Set;Ljava/lang/String;Ljava/util/Map;Ljava/util/Map;)Lio/getstream/chat/android/client/query/QueryChannelsSpec;
public static synthetic fun copy$default (Lio/getstream/chat/android/client/query/QueryChannelsSpec;Lio/getstream/chat/android/models/FilterObject;Lio/getstream/chat/android/models/querysort/QuerySorter;ILjava/lang/Object;)Lio/getstream/chat/android/client/query/QueryChannelsSpec;
public static synthetic fun copy$default (Lio/getstream/chat/android/client/query/QueryChannelsSpec;Lio/getstream/chat/android/models/FilterObject;Lio/getstream/chat/android/models/querysort/QuerySorter;Ljava/util/Set;Ljava/lang/String;Ljava/util/Map;Ljava/util/Map;ILjava/lang/Object;)Lio/getstream/chat/android/client/query/QueryChannelsSpec;
public fun equals (Ljava/lang/Object;)Z
public final fun getCids ()Ljava/util/Set;
public final fun getFilter ()Lio/getstream/chat/android/models/FilterObject;
public final fun getPredefinedFilterName ()Ljava/lang/String;
public final fun getPredefinedFilterValues ()Ljava/util/Map;
public final fun getPredefinedSortValues ()Ljava/util/Map;
public final fun getQuerySort ()Lio/getstream/chat/android/models/querysort/QuerySorter;
public fun hashCode ()I
public final fun setCids (Ljava/util/Set;)V
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ import io.getstream.chat.android.client.api.models.GetThreadOptions
import io.getstream.chat.android.client.api.models.PinnedMessagesPagination
import io.getstream.chat.android.client.api.models.QueryChannelRequest
import io.getstream.chat.android.client.api.models.QueryChannelsRequest
import io.getstream.chat.android.client.api.models.QueryChannelsResult
import io.getstream.chat.android.client.api.models.QueryThreadsRequest
import io.getstream.chat.android.client.api.models.QueryUsersRequest
import io.getstream.chat.android.client.api.models.SendActionRequest
Expand Down Expand Up @@ -2973,7 +2974,7 @@ internal constructor(
*/
@CheckResult
@InternalStreamChatApi
public fun queryChannelsInternal(request: QueryChannelsRequest): Call<List<Channel>> {
public fun queryChannelsInternal(request: QueryChannelsRequest): Call<QueryChannelsResult> {
return api.queryChannels(request)
}

Expand Down Expand Up @@ -3001,7 +3002,7 @@ internal constructor(
this.watch = false
this.state = state
}
when (val result = api.queryChannels(request).await()) {
when (val result = api.queryChannels(request).map { it.channels }.await()) {
is Result.Success -> {
val channels = result.value
if (channels.isEmpty()) {
Expand Down Expand Up @@ -3112,7 +3113,7 @@ internal constructor(
@CheckResult
public fun queryChannels(request: QueryChannelsRequest): Call<List<Channel>> {
logger.d { "[queryChannels] offset: ${request.offset}, limit: ${request.limit}" }
return queryChannelsInternal(request = request).doOnStart(userScope) {
return api.queryChannels(request).doOnStart(userScope) {
plugins.forEach { listener ->
logger.v { "[queryChannels] #doOnStart; plugin: ${listener::class.qualifiedName}" }
listener.onQueryChannelsRequest(request)
Expand All @@ -3124,6 +3125,8 @@ internal constructor(
}
}.precondition(plugins) {
onQueryChannelsPrecondition(request)
}.map {
it.channels
}.share(userScope) {
QueryChannelsIdentifier(request)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import io.getstream.chat.android.client.api.models.GetThreadOptions
import io.getstream.chat.android.client.api.models.PinnedMessagesPagination
import io.getstream.chat.android.client.api.models.QueryChannelRequest
import io.getstream.chat.android.client.api.models.QueryChannelsRequest
import io.getstream.chat.android.client.api.models.QueryChannelsResult
import io.getstream.chat.android.client.api.models.QueryThreadsRequest
import io.getstream.chat.android.client.api.models.QueryUsersRequest
import io.getstream.chat.android.client.api.models.SendActionRequest
Expand Down Expand Up @@ -285,7 +286,7 @@ internal interface ChatApi {
): Call<List<Message>>

@CheckResult
fun queryChannels(query: QueryChannelsRequest): Call<List<Channel>>
fun queryChannels(query: QueryChannelsRequest): Call<QueryChannelsResult>

@CheckResult
fun updateUsers(users: List<User>): Call<List<User>>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import io.getstream.chat.android.client.api.ChatApi
import io.getstream.chat.android.client.api.models.PinnedMessagesPagination
import io.getstream.chat.android.client.api.models.QueryChannelRequest
import io.getstream.chat.android.client.api.models.QueryChannelsRequest
import io.getstream.chat.android.client.api.models.QueryChannelsResult
import io.getstream.chat.android.client.api2.optimisation.hash.ChannelQueryKey
import io.getstream.chat.android.client.api2.optimisation.hash.GetNewerRepliesHash
import io.getstream.chat.android.client.api2.optimisation.hash.GetPinnedMessagesHash
Expand Down Expand Up @@ -133,7 +134,7 @@ internal class DistinctChatApi(
}
}

override fun queryChannels(query: QueryChannelsRequest): Call<List<Channel>> {
override fun queryChannels(query: QueryChannelsRequest): Call<QueryChannelsResult> {
val uniqueKey = query.hashCode()
StreamLog.d(TAG) { "[queryChannels] query: $query, uniqueKey: $uniqueKey" }
return getOrCreate(uniqueKey) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import io.getstream.chat.android.client.api.ChatApi
import io.getstream.chat.android.client.api.models.PinnedMessagesPagination
import io.getstream.chat.android.client.api.models.QueryChannelRequest
import io.getstream.chat.android.client.api.models.QueryChannelsRequest
import io.getstream.chat.android.client.api.models.QueryChannelsResult
import io.getstream.chat.android.models.BannedUser
import io.getstream.chat.android.models.BannedUsersSort
import io.getstream.chat.android.models.Channel
Expand Down Expand Up @@ -77,7 +78,7 @@ internal class DistinctChatApiEnabler(
return getApi().getPinnedMessages(channelType, channelId, limit, sort, pagination)
}

override fun queryChannels(query: QueryChannelsRequest): Call<List<Channel>> {
override fun queryChannels(query: QueryChannelsRequest): Call<QueryChannelsResult> {
return getApi().queryChannels(query)
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/*
* Copyright (c) 2014-2026 Stream.io Inc. All rights reserved.
*
* Licensed under the Stream License;
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://github.com/GetStream/stream-chat-android/blob/main/LICENSE
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package io.getstream.chat.android.client.api.models

import io.getstream.chat.android.core.internal.InternalStreamChatApi
import io.getstream.chat.android.models.Channel
import io.getstream.chat.android.models.FilterObject
import io.getstream.chat.android.models.querysort.QuerySorter

/**
* Represents a predefined filter parsed by the backend.
*
* @param filter The parsed filter specification.
* @param sort The parsed sort specification, or locally calculated fallback if null.
*/
@InternalStreamChatApi
public data class PredefinedFilter(
val filter: FilterObject,
val sort: QuerySorter<Channel>,
)
Loading
Loading