diff --git a/stream-chat-android-client/api/stream-chat-android-client.api b/stream-chat-android-client/api/stream-chat-android-client.api index 7196a0c105b..34ece10efe4 100644 --- a/stream-chat-android-client/api/stream-chat-android-client.api +++ b/stream-chat-android-client/api/stream-chat-android-client.api @@ -16,6 +16,7 @@ public final class io/getstream/chat/android/client/ChatClient { public final fun addSocketListener (Lio/getstream/chat/android/client/socket/SocketListener;)V public final fun appSettings ()Lio/getstream/result/call/Call; public final fun banUser (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/Integer;)Lio/getstream/result/call/Call; + public final fun blockUser (Ljava/lang/String;)Lio/getstream/result/call/Call; public final fun castPollVote (Ljava/lang/String;Ljava/lang/String;Lio/getstream/chat/android/models/Option;)Lio/getstream/result/call/Call; public final fun channel (Ljava/lang/String;)Lio/getstream/chat/android/client/channel/ChannelClient; public final fun channel (Ljava/lang/String;Ljava/lang/String;)Lio/getstream/chat/android/client/channel/ChannelClient; @@ -122,6 +123,7 @@ public final class io/getstream/chat/android/client/ChatClient { public final fun queryBannedUsers (Lio/getstream/chat/android/models/FilterObject;Lio/getstream/chat/android/models/querysort/QuerySorter;Ljava/lang/Integer;Ljava/lang/Integer;Ljava/util/Date;Ljava/util/Date;Ljava/util/Date;)Lio/getstream/result/call/Call; public final fun queryBannedUsers (Lio/getstream/chat/android/models/FilterObject;Lio/getstream/chat/android/models/querysort/QuerySorter;Ljava/lang/Integer;Ljava/lang/Integer;Ljava/util/Date;Ljava/util/Date;Ljava/util/Date;Ljava/util/Date;)Lio/getstream/result/call/Call; public static synthetic fun queryBannedUsers$default (Lio/getstream/chat/android/client/ChatClient;Lio/getstream/chat/android/models/FilterObject;Lio/getstream/chat/android/models/querysort/QuerySorter;Ljava/lang/Integer;Ljava/lang/Integer;Ljava/util/Date;Ljava/util/Date;Ljava/util/Date;Ljava/util/Date;ILjava/lang/Object;)Lio/getstream/result/call/Call; + public final fun queryBlockedUsers ()Lio/getstream/result/call/Call; public final fun queryChannel (Ljava/lang/String;Ljava/lang/String;Lio/getstream/chat/android/client/api/models/QueryChannelRequest;Z)Lio/getstream/result/call/Call; public static synthetic fun queryChannel$default (Lio/getstream/chat/android/client/ChatClient;Ljava/lang/String;Ljava/lang/String;Lio/getstream/chat/android/client/api/models/QueryChannelRequest;ZILjava/lang/Object;)Lio/getstream/result/call/Call; public final fun queryChannels (Lio/getstream/chat/android/client/api/models/QueryChannelsRequest;)Lio/getstream/result/call/Call; @@ -182,6 +184,7 @@ public final class io/getstream/chat/android/client/ChatClient { public final fun truncateChannel (Ljava/lang/String;Ljava/lang/String;Lio/getstream/chat/android/models/Message;)Lio/getstream/result/call/Call; public static synthetic fun truncateChannel$default (Lio/getstream/chat/android/client/ChatClient;Ljava/lang/String;Ljava/lang/String;Lio/getstream/chat/android/models/Message;ILjava/lang/Object;)Lio/getstream/result/call/Call; public final fun unbanUser (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Lio/getstream/result/call/Call; + public final fun unblockUser (Ljava/lang/String;)Lio/getstream/result/call/Call; public final fun unflagMessage (Ljava/lang/String;)Lio/getstream/result/call/Call; public final fun unflagUser (Ljava/lang/String;)Lio/getstream/result/call/Call; public final fun unmuteChannel (Ljava/lang/String;Ljava/lang/String;)Lio/getstream/result/call/Call; diff --git a/stream-chat-android-client/src/main/java/io/getstream/chat/android/client/ChatClient.kt b/stream-chat-android-client/src/main/java/io/getstream/chat/android/client/ChatClient.kt index 5439322ba80..8f3c2693110 100644 --- a/stream-chat-android-client/src/main/java/io/getstream/chat/android/client/ChatClient.kt +++ b/stream-chat-android-client/src/main/java/io/getstream/chat/android/client/ChatClient.kt @@ -171,6 +171,7 @@ import io.getstream.chat.android.models.Thread import io.getstream.chat.android.models.UploadAttachmentsNetworkType import io.getstream.chat.android.models.UploadedFile import io.getstream.chat.android.models.User +import io.getstream.chat.android.models.UserBlock import io.getstream.chat.android.models.VideoCallInfo import io.getstream.chat.android.models.VideoCallToken import io.getstream.chat.android.models.Vote @@ -2026,6 +2027,7 @@ internal constructor( Result.Success(channels.first()) } } + is Result.Failure -> result } } @@ -2447,6 +2449,36 @@ internal constructor( return updateUsers(listOf(user)).map { it.first() } } + /** + * Block a user by ID. + * + * @param userId the ID of the user that will be blocked. + * + * @return a list of [UserBlock] which will contain the block that just occured. + */ + @CheckResult + public fun blockUser(userId: String): Call { + return api.blockUser(userId) + } + + /** + * Unblock a user by ID. + * + * @param userId the user ID of the user that will be unblocked. + */ + @CheckResult + public fun unblockUser(userId: String): Call { + return api.unblockUser(userId) + } + + /** + * Return na list of blocked users. + */ + @CheckResult + public fun queryBlockedUsers(): Call> { + return api.queryBlockedUsers() + } + /** * Updates specific user fields retaining the custom data fields which were set previously. * diff --git a/stream-chat-android-client/src/main/java/io/getstream/chat/android/client/api/ChatApi.kt b/stream-chat-android-client/src/main/java/io/getstream/chat/android/client/api/ChatApi.kt index f3ab888c654..ee072845168 100644 --- a/stream-chat-android-client/src/main/java/io/getstream/chat/android/client/api/ChatApi.kt +++ b/stream-chat-android-client/src/main/java/io/getstream/chat/android/client/api/ChatApi.kt @@ -46,6 +46,7 @@ import io.getstream.chat.android.models.SearchMessagesResult import io.getstream.chat.android.models.Thread import io.getstream.chat.android.models.UploadedFile import io.getstream.chat.android.models.User +import io.getstream.chat.android.models.UserBlock import io.getstream.chat.android.models.VideoCallInfo import io.getstream.chat.android.models.VideoCallToken import io.getstream.chat.android.models.Vote @@ -215,6 +216,15 @@ internal interface ChatApi { @CheckResult fun updateUsers(users: List): Call> + @CheckResult + fun blockUser(userId: String): Call + + @CheckResult + fun unblockUser(userId: String): Call + + @CheckResult + fun queryBlockedUsers(): Call> + @CheckResult fun partialUpdateUser( id: String, diff --git a/stream-chat-android-client/src/main/java/io/getstream/chat/android/client/api2/MoshiChatApi.kt b/stream-chat-android-client/src/main/java/io/getstream/chat/android/client/api2/MoshiChatApi.kt index e0ea4aee6a5..510dd455826 100644 --- a/stream-chat-android-client/src/main/java/io/getstream/chat/android/client/api2/MoshiChatApi.kt +++ b/stream-chat-android-client/src/main/java/io/getstream/chat/android/client/api2/MoshiChatApi.kt @@ -51,6 +51,7 @@ import io.getstream.chat.android.client.api2.model.requests.AcceptInviteRequest import io.getstream.chat.android.client.api2.model.requests.AddDeviceRequest import io.getstream.chat.android.client.api2.model.requests.AddMembersRequest import io.getstream.chat.android.client.api2.model.requests.BanUserRequest +import io.getstream.chat.android.client.api2.model.requests.BlockUserRequest import io.getstream.chat.android.client.api2.model.requests.FlagMessageRequest import io.getstream.chat.android.client.api2.model.requests.FlagRequest import io.getstream.chat.android.client.api2.model.requests.FlagUserRequest @@ -77,6 +78,7 @@ import io.getstream.chat.android.client.api2.model.requests.SendEventRequest import io.getstream.chat.android.client.api2.model.requests.SendMessageRequest import io.getstream.chat.android.client.api2.model.requests.SyncHistoryRequest import io.getstream.chat.android.client.api2.model.requests.TruncateChannelRequest +import io.getstream.chat.android.client.api2.model.requests.UnblockUserRequest import io.getstream.chat.android.client.api2.model.requests.UpdateChannelPartialRequest import io.getstream.chat.android.client.api2.model.requests.UpdateChannelRequest import io.getstream.chat.android.client.api2.model.requests.UpdateCooldownRequest @@ -119,6 +121,7 @@ import io.getstream.chat.android.models.SearchMessagesResult import io.getstream.chat.android.models.Thread import io.getstream.chat.android.models.UploadedFile import io.getstream.chat.android.models.User +import io.getstream.chat.android.models.UserBlock import io.getstream.chat.android.models.VideoCallInfo import io.getstream.chat.android.models.VideoCallToken import io.getstream.chat.android.models.Vote @@ -817,6 +820,28 @@ constructor( } } + override fun blockUser(userId: String): Call { + return userApi.blockUser( + body = BlockUserRequest(userId), + ).map { response -> + response.block.toDomain() + } + } + + override fun queryBlockedUsers(): Call> { + return userApi.queryBlockedUsers().map { + it.blocks.toDomain() + } + } + + override fun unblockUser(userId: String): Call { + return userApi.unblockUser( + body = UnblockUserRequest(userId), + ).map { + it.block.toDomain() + } + } + override fun partialUpdateUser(id: String, set: Map, unset: List): Call { return userApi.partialUpdateUsers( connectionId = connectionId, diff --git a/stream-chat-android-client/src/main/java/io/getstream/chat/android/client/api2/endpoint/UserApi.kt b/stream-chat-android-client/src/main/java/io/getstream/chat/android/client/api2/endpoint/UserApi.kt index 69725f4f9ad..a88857e9d60 100644 --- a/stream-chat-android-client/src/main/java/io/getstream/chat/android/client/api2/endpoint/UserApi.kt +++ b/stream-chat-android-client/src/main/java/io/getstream/chat/android/client/api2/endpoint/UserApi.kt @@ -19,9 +19,14 @@ package io.getstream.chat.android.client.api2.endpoint import io.getstream.chat.android.client.api.AuthenticatedApi import io.getstream.chat.android.client.api.QueryParams import io.getstream.chat.android.client.api2.UrlQueryPayload +import io.getstream.chat.android.client.api2.model.requests.BlockUserRequest import io.getstream.chat.android.client.api2.model.requests.PartialUpdateUsersRequest import io.getstream.chat.android.client.api2.model.requests.QueryUsersRequest +import io.getstream.chat.android.client.api2.model.requests.UnblockUserRequest import io.getstream.chat.android.client.api2.model.requests.UpdateUsersRequest +import io.getstream.chat.android.client.api2.model.response.BlockUserResponse +import io.getstream.chat.android.client.api2.model.response.QueryBlockedUsersResponse +import io.getstream.chat.android.client.api2.model.response.UnblockUserResponse import io.getstream.chat.android.client.api2.model.response.UpdateUsersResponse import io.getstream.chat.android.client.api2.model.response.UsersResponse import io.getstream.chat.android.client.call.RetrofitCall @@ -39,6 +44,16 @@ internal interface UserApi { @Body body: UpdateUsersRequest, ): RetrofitCall + @POST("/users/block") + @JvmSuppressWildcards + fun blockUser(@Body body: BlockUserRequest): RetrofitCall + + @POST("/users/unblock") + fun unblockUser(@Body body: UnblockUserRequest): RetrofitCall + + @GET + fun queryBlockedUsers(): RetrofitCall + @PATCH("/users") @JvmSuppressWildcards // See issue: https://github.com/square/retrofit/issues/3275 fun partialUpdateUsers( diff --git a/stream-chat-android-client/src/main/java/io/getstream/chat/android/client/api2/mapping/UserMapping.kt b/stream-chat-android-client/src/main/java/io/getstream/chat/android/client/api2/mapping/UserMapping.kt index f1bff7cfc0a..185dc1123fa 100644 --- a/stream-chat-android-client/src/main/java/io/getstream/chat/android/client/api2/mapping/UserMapping.kt +++ b/stream-chat-android-client/src/main/java/io/getstream/chat/android/client/api2/mapping/UserMapping.kt @@ -19,10 +19,12 @@ package io.getstream.chat.android.client.api2.mapping import io.getstream.chat.android.client.api2.model.dto.DeviceDto import io.getstream.chat.android.client.api2.model.dto.DownstreamChannelMuteDto import io.getstream.chat.android.client.api2.model.dto.DownstreamMuteDto +import io.getstream.chat.android.client.api2.model.dto.DownstreamUserBlockDto import io.getstream.chat.android.client.api2.model.dto.DownstreamUserDto import io.getstream.chat.android.client.api2.model.dto.UpstreamUserDto import io.getstream.chat.android.models.Device import io.getstream.chat.android.models.User +import io.getstream.chat.android.models.UserBlock internal fun User.toDto(): UpstreamUserDto = UpstreamUserDto( @@ -61,3 +63,11 @@ internal fun DownstreamUserDto.toDomain(): User = channelMutes = channel_mutes.orEmpty().map(DownstreamChannelMuteDto::toDomain), extraData = extraData.toMutableMap(), ) + +internal fun DownstreamUserBlockDto.toDomain(): UserBlock = UserBlock( + blockedBy = blocked_by_user_id, + userId = blocked_user_id, + blockedAt = created_at, +) + +internal fun List.toDomain(): List = map { it.toDomain() } diff --git a/stream-chat-android-client/src/main/java/io/getstream/chat/android/client/api2/model/dto/UserDtos.kt b/stream-chat-android-client/src/main/java/io/getstream/chat/android/client/api2/model/dto/UserDtos.kt index af612079407..b517e522a23 100644 --- a/stream-chat-android-client/src/main/java/io/getstream/chat/android/client/api2/model/dto/UserDtos.kt +++ b/stream-chat-android-client/src/main/java/io/getstream/chat/android/client/api2/model/dto/UserDtos.kt @@ -84,3 +84,10 @@ internal data class PartialUpdateUserDto( val set: Map, val unset: List, ) + +@JsonClass(generateAdapter = true) +internal data class DownstreamUserBlockDto( + val blocked_by_user_id: String, + val blocked_user_id: String, + val created_at: Date, +) diff --git a/stream-chat-android-client/src/main/java/io/getstream/chat/android/client/api2/model/requests/BlockUserRequest.kt b/stream-chat-android-client/src/main/java/io/getstream/chat/android/client/api2/model/requests/BlockUserRequest.kt new file mode 100644 index 00000000000..dfc58987cce --- /dev/null +++ b/stream-chat-android-client/src/main/java/io/getstream/chat/android/client/api2/model/requests/BlockUserRequest.kt @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2014-2024 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.api2.model.requests + +import com.squareup.moshi.JsonClass + +@JsonClass(generateAdapter = true) +internal data class BlockUserRequest( + val blocked_user_id: String, +) diff --git a/stream-chat-android-client/src/main/java/io/getstream/chat/android/client/api2/model/requests/UnblockUserRequest.kt b/stream-chat-android-client/src/main/java/io/getstream/chat/android/client/api2/model/requests/UnblockUserRequest.kt new file mode 100644 index 00000000000..c8a42ed44ff --- /dev/null +++ b/stream-chat-android-client/src/main/java/io/getstream/chat/android/client/api2/model/requests/UnblockUserRequest.kt @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2014-2024 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.api2.model.requests + +import com.squareup.moshi.JsonClass + +@JsonClass(generateAdapter = true) +internal data class UnblockUserRequest( + val blocked_user_id: String, +) diff --git a/stream-chat-android-client/src/main/java/io/getstream/chat/android/client/api2/model/response/BlockUserResponse.kt b/stream-chat-android-client/src/main/java/io/getstream/chat/android/client/api2/model/response/BlockUserResponse.kt new file mode 100644 index 00000000000..e84da303583 --- /dev/null +++ b/stream-chat-android-client/src/main/java/io/getstream/chat/android/client/api2/model/response/BlockUserResponse.kt @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2014-2024 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.api2.model.response + +import com.squareup.moshi.JsonClass +import io.getstream.chat.android.client.api2.model.dto.DownstreamUserBlockDto + +@JsonClass(generateAdapter = true) +internal data class BlockUserResponse( + val block: DownstreamUserBlockDto, +) diff --git a/stream-chat-android-client/src/main/java/io/getstream/chat/android/client/api2/model/response/QueryBlockedUsersResponse.kt b/stream-chat-android-client/src/main/java/io/getstream/chat/android/client/api2/model/response/QueryBlockedUsersResponse.kt new file mode 100644 index 00000000000..12da753dd34 --- /dev/null +++ b/stream-chat-android-client/src/main/java/io/getstream/chat/android/client/api2/model/response/QueryBlockedUsersResponse.kt @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2014-2024 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.api2.model.response + +import com.squareup.moshi.JsonClass +import io.getstream.chat.android.client.api2.model.dto.DownstreamUserBlockDto + +@JsonClass(generateAdapter = true) +internal data class QueryBlockedUsersResponse( + val blocks: List, +) diff --git a/stream-chat-android-client/src/main/java/io/getstream/chat/android/client/api2/model/response/UnblockUserResponse.kt b/stream-chat-android-client/src/main/java/io/getstream/chat/android/client/api2/model/response/UnblockUserResponse.kt new file mode 100644 index 00000000000..918d28db836 --- /dev/null +++ b/stream-chat-android-client/src/main/java/io/getstream/chat/android/client/api2/model/response/UnblockUserResponse.kt @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2014-2024 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.api2.model.response + +import com.squareup.moshi.JsonClass +import io.getstream.chat.android.client.api2.model.dto.DownstreamUserBlockDto + +@JsonClass(generateAdapter = true) +internal data class UnblockUserResponse( + val block: DownstreamUserBlockDto, +) diff --git a/stream-chat-android-core/api/stream-chat-android-core.api b/stream-chat-android-core/api/stream-chat-android-core.api index 374e6819753..15ebf9bdffe 100644 --- a/stream-chat-android-core/api/stream-chat-android-core.api +++ b/stream-chat-android-core/api/stream-chat-android-core.api @@ -1861,6 +1861,21 @@ public final class io/getstream/chat/android/models/User$Builder { public final fun withUpdatedAt (Ljava/util/Date;)Lio/getstream/chat/android/models/User$Builder; } +public final class io/getstream/chat/android/models/UserBlock { + public fun (Ljava/lang/String;Ljava/lang/String;Ljava/util/Date;)V + public final fun component1 ()Ljava/lang/String; + public final fun component2 ()Ljava/lang/String; + public final fun component3 ()Ljava/util/Date; + public final fun copy (Ljava/lang/String;Ljava/lang/String;Ljava/util/Date;)Lio/getstream/chat/android/models/UserBlock; + public static synthetic fun copy$default (Lio/getstream/chat/android/models/UserBlock;Ljava/lang/String;Ljava/lang/String;Ljava/util/Date;ILjava/lang/Object;)Lio/getstream/chat/android/models/UserBlock; + public fun equals (Ljava/lang/Object;)Z + public final fun getBlockedAt ()Ljava/util/Date; + public final fun getBlockedBy ()Ljava/lang/String; + public final fun getUserId ()Ljava/lang/String; + public fun hashCode ()I + public fun toString ()Ljava/lang/String; +} + public abstract interface class io/getstream/chat/android/models/UserEntity { public abstract fun getUser ()Lio/getstream/chat/android/models/User; public abstract fun getUserId ()Ljava/lang/String; diff --git a/stream-chat-android-core/src/main/java/io/getstream/chat/android/models/UserBlock.kt b/stream-chat-android-core/src/main/java/io/getstream/chat/android/models/UserBlock.kt new file mode 100644 index 00000000000..2e62ccd1354 --- /dev/null +++ b/stream-chat-android-core/src/main/java/io/getstream/chat/android/models/UserBlock.kt @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2014-2024 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.models + +import java.util.Date + +/** + * Represents a user block. + * + * @param blockedBy who is the initiator of the block (usually will contain the ID of the current user) + * @param userId the ID of the blocked user. + * @param blockedAt when the action happened + */ +public data class UserBlock( + val blockedBy: String, + val userId: String, + val blockedAt: Date, +)