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 ffb411991a2..e05ac45d0e3 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 @@ -48,23 +48,17 @@ import io.getstream.chat.android.client.api2.mapping.DtoMapping import io.getstream.chat.android.client.api2.mapping.EventMapping import io.getstream.chat.android.client.api2.mapping.toFilterDomainWithFields import io.getstream.chat.android.client.api2.model.dto.UpstreamPushPreferenceInputDto -import io.getstream.chat.android.client.api2.model.requests.AcceptInviteRequest -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.FlagMessageRequest import io.getstream.chat.android.client.api2.model.requests.FlagRequest import io.getstream.chat.android.client.api2.model.requests.FlagUserRequest -import io.getstream.chat.android.client.api2.model.requests.InviteMembersRequest import io.getstream.chat.android.client.api2.model.requests.MuteUserRequest import io.getstream.chat.android.client.api2.model.requests.PinnedMessagesRequest import io.getstream.chat.android.client.api2.model.requests.QueryBannedUsersRequest import io.getstream.chat.android.client.api2.model.requests.QueryDraftMessagesRequest -import io.getstream.chat.android.client.api2.model.requests.RejectInviteRequest -import io.getstream.chat.android.client.api2.model.requests.RemoveMembersRequest 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.UpdateChannelRequest import io.getstream.chat.android.client.api2.model.requests.UpdateLiveLocationRequest import io.getstream.chat.android.client.api2.model.requests.UpdateMessageRequest import io.getstream.chat.android.client.api2.model.requests.UpsertPushPreferencesRequest @@ -134,6 +128,8 @@ import io.getstream.chat.android.network.models.AddUserGroupMembersRequest import io.getstream.chat.android.network.models.AddUserGroupMembersResponse import io.getstream.chat.android.network.models.BlockUsersRequest import io.getstream.chat.android.network.models.CastPollVoteRequest +import io.getstream.chat.android.network.models.ChannelInputRequest +import io.getstream.chat.android.network.models.ChannelMemberRequest import io.getstream.chat.android.network.models.CreateDeviceRequest import io.getstream.chat.android.network.models.CreateGuestRequest import io.getstream.chat.android.network.models.CreatePollOptionRequest @@ -150,6 +146,7 @@ import io.getstream.chat.android.network.models.MarkDeliveredRequest import io.getstream.chat.android.network.models.MarkReadRequest import io.getstream.chat.android.network.models.MarkUnreadRequest import io.getstream.chat.android.network.models.MessageActionRequest +import io.getstream.chat.android.network.models.MessageRequest import io.getstream.chat.android.network.models.MuteChannelRequest import io.getstream.chat.android.network.models.PollOptionInput import io.getstream.chat.android.network.models.PollOptionRequest @@ -166,6 +163,7 @@ import io.getstream.chat.android.network.models.SendReactionRequest import io.getstream.chat.android.network.models.SortParamRequest import io.getstream.chat.android.network.models.UnblockUsersRequest import io.getstream.chat.android.network.models.UpdateChannelPartialRequest +import io.getstream.chat.android.network.models.UpdateChannelRequest import io.getstream.chat.android.network.models.UpdateMemberPartialRequest import io.getstream.chat.android.network.models.UpdateMessagePartialRequest import io.getstream.chat.android.network.models.UpdatePollOptionRequest @@ -1082,8 +1080,8 @@ constructor( channelId = channelId, body = with(dtoMapping) { UpdateChannelRequest( - extraData, - updateMessage?.toDto(), + data = ChannelInputRequest(custom = extraData), + message = updateMessage?.toMessageRequest(), ) }, ).map(this::flattenChannel) @@ -1141,7 +1139,7 @@ constructor( return channelApi.rejectInvite( channelType = channelType, channelId = channelId, - body = RejectInviteRequest(), + body = UpdateChannelRequest(rejectInvite = true), ).map(this::flattenChannel) } @@ -1153,7 +1151,10 @@ constructor( return channelApi.acceptInvite( channelType = channelType, channelId = channelId, - body = AcceptInviteRequest.create(userId = userId, message = message), + body = UpdateChannelRequest( + acceptInvite = true, + message = message?.let { MessageRequest(text = it) }, + ), ).map(this::flattenChannel) } @@ -1222,12 +1223,12 @@ constructor( channelType = channelType, channelId = channelId, body = with(dtoMapping) { - AddMembersRequest( - add_members = members.map { it.toDto() }, - message = systemMessage?.toDto(), - hide_history = hideHistory, - hide_history_before = hideHistoryBefore, - skip_push = skipPush, + UpdateChannelRequest( + addMembers = members.map { it.toChannelMemberRequest() }, + message = systemMessage?.toMessageRequest(), + hideHistory = hideHistory, + hideHistoryBefore = hideHistoryBefore, + skipPush = skipPush, ) }, ).map(this::flattenChannel) @@ -1244,10 +1245,10 @@ constructor( channelType = channelType, channelId = channelId, body = with(dtoMapping) { - RemoveMembersRequest( - members, - systemMessage?.toDto(), - skipPush, + UpdateChannelRequest( + removeMembers = members, + message = systemMessage?.toMessageRequest(), + skipPush = skipPush, ) }, ).map(this::flattenChannel) @@ -1264,10 +1265,10 @@ constructor( channelType = channelType, channelId = channelId, body = with(dtoMapping) { - InviteMembersRequest( - members, - systemMessage?.toDto(), - skipPush, + UpdateChannelRequest( + invites = members.map { ChannelMemberRequest(userId = it) }, + message = systemMessage?.toMessageRequest(), + skipPush = skipPush, ) }, ).map(this::flattenChannel) diff --git a/stream-chat-android-client/src/main/java/io/getstream/chat/android/client/api2/endpoint/ChannelApi.kt b/stream-chat-android-client/src/main/java/io/getstream/chat/android/client/api2/endpoint/ChannelApi.kt index 23e1658c067..24f71400005 100644 --- a/stream-chat-android-client/src/main/java/io/getstream/chat/android/client/api2/endpoint/ChannelApi.kt +++ b/stream-chat-android-client/src/main/java/io/getstream/chat/android/client/api2/endpoint/ChannelApi.kt @@ -19,15 +19,9 @@ 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.AcceptInviteRequest -import io.getstream.chat.android.client.api2.model.requests.AddMembersRequest -import io.getstream.chat.android.client.api2.model.requests.InviteMembersRequest import io.getstream.chat.android.client.api2.model.requests.PinnedMessagesRequest import io.getstream.chat.android.client.api2.model.requests.QueryChannelRequest -import io.getstream.chat.android.client.api2.model.requests.RejectInviteRequest -import io.getstream.chat.android.client.api2.model.requests.RemoveMembersRequest import io.getstream.chat.android.client.api2.model.requests.TruncateChannelRequest -import io.getstream.chat.android.client.api2.model.requests.UpdateChannelRequest import io.getstream.chat.android.client.api2.model.requests.UpdateMemberPartialResponse import io.getstream.chat.android.client.api2.model.response.ChannelResponse import io.getstream.chat.android.client.api2.model.response.EventResponse @@ -44,6 +38,7 @@ import io.getstream.chat.android.network.models.QueryChannelsRequest import io.getstream.chat.android.network.models.Response import io.getstream.chat.android.network.models.SendEventRequest import io.getstream.chat.android.network.models.UpdateChannelPartialRequest +import io.getstream.chat.android.network.models.UpdateChannelRequest import io.getstream.chat.android.network.models.UpdateMemberPartialRequest import retrofit2.http.Body import retrofit2.http.DELETE @@ -115,35 +110,35 @@ internal interface ChannelApi { fun acceptInvite( @Path("type") channelType: String, @Path("id") channelId: String, - @Body body: AcceptInviteRequest, + @Body body: UpdateChannelRequest, ): RetrofitCall @POST("/channels/{type}/{id}") fun rejectInvite( @Path("type") channelType: String, @Path("id") channelId: String, - @Body body: RejectInviteRequest, + @Body body: UpdateChannelRequest, ): RetrofitCall @POST("/channels/{type}/{id}") fun addMembers( @Path("type") channelType: String, @Path("id") channelId: String, - @Body body: AddMembersRequest, + @Body body: UpdateChannelRequest, ): RetrofitCall @POST("/channels/{type}/{id}") fun removeMembers( @Path("type") channelType: String, @Path("id") channelId: String, - @Body body: RemoveMembersRequest, + @Body body: UpdateChannelRequest, ): RetrofitCall @POST("/channels/{type}/{id}") fun inviteMembers( @Path("type") channelType: String, @Path("id") channelId: String, - @Body body: InviteMembersRequest, + @Body body: UpdateChannelRequest, ): RetrofitCall @PATCH("/channels/{type}/{id}/member/{user_id}") diff --git a/stream-chat-android-client/src/main/java/io/getstream/chat/android/client/api2/mapping/DtoMapping.kt b/stream-chat-android-client/src/main/java/io/getstream/chat/android/client/api2/mapping/DtoMapping.kt index e5ab8e9f9f9..b35c1dcfba4 100644 --- a/stream-chat-android-client/src/main/java/io/getstream/chat/android/client/api2/mapping/DtoMapping.kt +++ b/stream-chat-android-client/src/main/java/io/getstream/chat/android/client/api2/mapping/DtoMapping.kt @@ -50,13 +50,17 @@ import io.getstream.chat.android.models.Reaction import io.getstream.chat.android.models.User import io.getstream.chat.android.models.UserGroup import io.getstream.chat.android.models.UserTransformer +import io.getstream.chat.android.network.models.ChannelMemberRequest import io.getstream.chat.android.network.models.DeliveryReceiptsResponse +import io.getstream.chat.android.network.models.MessageRequest import io.getstream.chat.android.network.models.PrivacySettingsResponse import io.getstream.chat.android.network.models.ReactionRequest import io.getstream.chat.android.network.models.ReadReceiptsResponse +import io.getstream.chat.android.network.models.SharedLocation import io.getstream.chat.android.network.models.TypingIndicatorsResponse import io.getstream.chat.android.network.models.UserRequest +@Suppress("TooManyFunctions") internal class DtoMapping( private val messageTransformer: MessageTransformer, private val userTransformer: UserTransformer, @@ -170,6 +174,89 @@ internal class DtoMapping( end_at = endAt, ) + /** + * Maps the domain [Attachment] to the generated network Attachment model. + */ + internal fun Attachment.toRequest(): io.getstream.chat.android.network.models.Attachment { + // OpenAPI Attachment doesn't declare file_size/image/mime_type/name; fold them into `custom` + // so the custom-flattening adapter writes them at the JSON root. + val custom = extraData.toMutableMap() + image?.let { custom["image"] = it } + name?.let { custom["name"] = it } + mimeType?.let { custom["mime_type"] = it } + custom["file_size"] = fileSize + return io.getstream.chat.android.network.models.Attachment( + assetUrl = assetUrl, + authorName = authorName, + fallback = fallback, + imageUrl = imageUrl, + ogScrapeUrl = ogUrl, + text = text, + thumbUrl = thumbUrl, + title = title, + titleLink = titleLink, + authorLink = authorLink, + type = type, + originalHeight = originalHeight, + originalWidth = originalWidth, + custom = custom, + actions = null, + fields = null, + ) + } + + /** + * Maps the domain [MemberData] to the generated network [ChannelMemberRequest] model. + */ + internal fun MemberData.toChannelMemberRequest(): ChannelMemberRequest = ChannelMemberRequest( + userId = userId, + channelRole = null, + user = null, + custom = extraData, + ) + + /** + * Maps the domain [Location] to the generated network [SharedLocation] model. + */ + internal fun Location.toSharedLocation(): SharedLocation = SharedLocation( + // The spec types these coordinates as a 32-bit float although the backend stores float64, so + // this narrows and loses sub-meter precision. Revert once the spec says double. + latitude = latitude.toFloat(), + longitude = longitude.toFloat(), + createdByDeviceId = deviceId, + endAt = endAt, + ) + + /** + * Transforms the domain [Message] to the generated network [MessageRequest] model. + */ + internal fun Message.toMessageRequest(): MessageRequest = + messageTransformer.transform(this) + .run { + val upstreamType = if (type in supportedUpstreamMessageTypes) type else "" + MessageRequest( + id = id, + text = text, + type = MessageRequest.Type.fromString(upstreamType), + attachments = attachments.map { it.toRequest() }, + mentionedUsers = mentionedUsersIds, + mentionedHere = mentionedHere, + mentionedChannel = mentionedChannel, + mentionedGroupIds = mentionedGroups.map(UserGroup::id), + mentionedRoles = mentionedRoles, + parentId = parentId, + pinExpires = pinExpires, + pinned = pinned, + pinnedAt = pinnedAt, + quotedMessageId = replyMessageId, + showInChannel = showInChannel, + silent = silent, + restrictedVisibility = restrictedVisibility, + sharedLocation = sharedLocation?.toSharedLocation(), + custom = extraData, + ) + } + internal fun DraftMessage.toDto(): UpstreamMessageDto = UpstreamMessageDto( attachments = attachments.map { it.toDto() }, cid = cid, diff --git a/stream-chat-android-client/src/main/java/io/getstream/chat/android/client/api2/model/requests/AcceptInviteRequest.kt b/stream-chat-android-client/src/main/java/io/getstream/chat/android/client/api2/model/requests/AcceptInviteRequest.kt deleted file mode 100644 index 32db14c4d33..00000000000 --- a/stream-chat-android-client/src/main/java/io/getstream/chat/android/client/api2/model/requests/AcceptInviteRequest.kt +++ /dev/null @@ -1,41 +0,0 @@ -/* - * 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.api2.model.requests - -import com.squareup.moshi.JsonClass - -@JsonClass(generateAdapter = true) -internal data class AcceptInviteRequest( - val user: AcceptInviteUser, - val message: AcceptInviteMessage, - val accept_invite: Boolean = true, -) { - @JsonClass(generateAdapter = true) - data class AcceptInviteUser(val id: String) - - @JsonClass(generateAdapter = true) - data class AcceptInviteMessage(val text: String?) - - companion object { - fun create(userId: String, message: String?): AcceptInviteRequest { - return AcceptInviteRequest( - user = AcceptInviteUser(userId), - message = AcceptInviteMessage(message), - ) - } - } -} diff --git a/stream-chat-android-client/src/main/java/io/getstream/chat/android/client/api2/model/requests/UpdateChannelRequest.kt b/stream-chat-android-client/src/main/java/io/getstream/chat/android/client/api2/model/requests/UpdateChannelRequest.kt deleted file mode 100644 index bf183decc7d..00000000000 --- a/stream-chat-android-client/src/main/java/io/getstream/chat/android/client/api2/model/requests/UpdateChannelRequest.kt +++ /dev/null @@ -1,26 +0,0 @@ -/* - * 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.api2.model.requests - -import com.squareup.moshi.JsonClass -import io.getstream.chat.android.client.api2.model.dto.UpstreamMessageDto - -@JsonClass(generateAdapter = true) -internal data class UpdateChannelRequest( - val data: Map, - val message: UpstreamMessageDto?, -) diff --git a/stream-chat-android-client/src/main/java/io/getstream/chat/android/client/parser2/MoshiChatParser.kt b/stream-chat-android-client/src/main/java/io/getstream/chat/android/client/parser2/MoshiChatParser.kt index f037b5cb971..5f87abd802b 100644 --- a/stream-chat-android-client/src/main/java/io/getstream/chat/android/client/parser2/MoshiChatParser.kt +++ b/stream-chat-android-client/src/main/java/io/getstream/chat/android/client/parser2/MoshiChatParser.kt @@ -31,6 +31,9 @@ import io.getstream.chat.android.client.events.ConnectedEvent import io.getstream.chat.android.client.extensions.internal.enrichIfNeeded import io.getstream.chat.android.client.parser.ChatParser import io.getstream.chat.android.client.parser2.adapters.AttachmentDtoAdapter +import io.getstream.chat.android.client.parser2.adapters.AttachmentRequestAdapter +import io.getstream.chat.android.client.parser2.adapters.ChannelInputRequestAdapter +import io.getstream.chat.android.client.parser2.adapters.ChannelMemberRequestAdapter import io.getstream.chat.android.client.parser2.adapters.CreatePollOptionRequestAdapter import io.getstream.chat.android.client.parser2.adapters.CreatePollRequestAdapter import io.getstream.chat.android.client.parser2.adapters.DownstreamChannelDtoAdapter @@ -46,6 +49,7 @@ import io.getstream.chat.android.client.parser2.adapters.DownstreamUserDtoAdapte import io.getstream.chat.android.client.parser2.adapters.EventAdapterFactory import io.getstream.chat.android.client.parser2.adapters.EventRequestAdapter import io.getstream.chat.android.client.parser2.adapters.ExactDateAdapter +import io.getstream.chat.android.client.parser2.adapters.MessageRequestAdapter import io.getstream.chat.android.client.parser2.adapters.PollOptionInputAdapter import io.getstream.chat.android.client.parser2.adapters.PollOptionRequestAdapter import io.getstream.chat.android.client.parser2.adapters.UpdatePollOptionRequestAdapter @@ -59,7 +63,9 @@ import io.getstream.chat.android.client.parser2.adapters.UserRequestAdapter import io.getstream.chat.android.client.socket.ErrorResponse import io.getstream.chat.android.client.socket.SocketErrorMessage import io.getstream.chat.android.network.infrastructure.Serializer +import io.getstream.chat.android.network.models.ConfigOverridesRequest import io.getstream.chat.android.network.models.CreatePollRequest +import io.getstream.chat.android.network.models.MessageRequest import io.getstream.chat.android.network.models.UpdatePollRequest import retrofit2.Retrofit import retrofit2.converter.moshi.MoshiConverterFactory @@ -84,6 +90,10 @@ internal class MoshiChatParser( .add(DownstreamUserDtoAdapter) .add(UpstreamUserDtoAdapter) .add(UserRequestAdapter) + .add(AttachmentRequestAdapter) + .add(MessageRequestAdapter) + .add(ChannelMemberRequestAdapter) + .add(ChannelInputRequestAdapter) .add(DownstreamMemberDtoAdapter) .add(UpstreamMemberDtoAdapter) .add(UpstreamMemberDataDtoAdapter) @@ -107,6 +117,18 @@ internal class MoshiChatParser( UpdatePollRequest.VotingVisibility::class.java, UpdatePollRequest.VotingVisibility.VotingVisibilityAdapter(), ) + .add( + MessageRequest.Type::class.java, + MessageRequest.Type.TypeAdapter(), + ) + .add( + ConfigOverridesRequest.BlocklistBehavior::class.java, + ConfigOverridesRequest.BlocklistBehavior.BlocklistBehaviorAdapter(), + ) + .add( + ConfigOverridesRequest.PushLevel::class.java, + ConfigOverridesRequest.PushLevel.PushLevelAdapter(), + ) .build() } diff --git a/stream-chat-android-client/src/main/java/io/getstream/chat/android/client/parser2/adapters/AttachmentRequestAdapter.kt b/stream-chat-android-client/src/main/java/io/getstream/chat/android/client/parser2/adapters/AttachmentRequestAdapter.kt new file mode 100644 index 00000000000..108c05eec2a --- /dev/null +++ b/stream-chat-android-client/src/main/java/io/getstream/chat/android/client/parser2/adapters/AttachmentRequestAdapter.kt @@ -0,0 +1,42 @@ +/* + * 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.parser2.adapters + +import com.squareup.moshi.FromJson +import com.squareup.moshi.JsonAdapter +import com.squareup.moshi.JsonReader +import com.squareup.moshi.JsonWriter +import com.squareup.moshi.ToJson +import io.getstream.chat.android.network.models.Attachment + +// The generated Attachment carries custom data in a `custom` field that must be flattened to the +// JSON root on the wire; extraDataPropertyName matches its @Json(name = "custom"). +internal object AttachmentRequestAdapter : + CustomObjectDtoAdapter(Attachment::class, extraDataPropertyName = "custom") { + + @FromJson + @Suppress("UNUSED_PARAMETER") + fun fromJson(jsonReader: JsonReader): Attachment = error("Can't parse this from Json") + + @ToJson + fun toJson( + jsonWriter: JsonWriter, + request: Attachment?, + mapAdapter: JsonAdapter>, + requestAdapter: JsonAdapter, + ) = serializeWithExtraData(jsonWriter, request, mapAdapter, requestAdapter) +} diff --git a/stream-chat-android-client/src/main/java/io/getstream/chat/android/client/parser2/adapters/ChannelInputRequestAdapter.kt b/stream-chat-android-client/src/main/java/io/getstream/chat/android/client/parser2/adapters/ChannelInputRequestAdapter.kt new file mode 100644 index 00000000000..1c0d205ee7a --- /dev/null +++ b/stream-chat-android-client/src/main/java/io/getstream/chat/android/client/parser2/adapters/ChannelInputRequestAdapter.kt @@ -0,0 +1,42 @@ +/* + * 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.parser2.adapters + +import com.squareup.moshi.FromJson +import com.squareup.moshi.JsonAdapter +import com.squareup.moshi.JsonReader +import com.squareup.moshi.JsonWriter +import com.squareup.moshi.ToJson +import io.getstream.chat.android.network.models.ChannelInputRequest + +// The generated ChannelInputRequest carries channel custom data in a `custom` field that must be +// flattened to the JSON root on the wire; extraDataPropertyName matches its @Json(name = "custom"). +internal object ChannelInputRequestAdapter : + CustomObjectDtoAdapter(ChannelInputRequest::class, extraDataPropertyName = "custom") { + + @FromJson + @Suppress("UNUSED_PARAMETER") + fun fromJson(jsonReader: JsonReader): ChannelInputRequest = error("Can't parse this from Json") + + @ToJson + fun toJson( + jsonWriter: JsonWriter, + request: ChannelInputRequest?, + mapAdapter: JsonAdapter>, + requestAdapter: JsonAdapter, + ) = serializeWithExtraData(jsonWriter, request, mapAdapter, requestAdapter) +} diff --git a/stream-chat-android-client/src/main/java/io/getstream/chat/android/client/parser2/adapters/ChannelMemberRequestAdapter.kt b/stream-chat-android-client/src/main/java/io/getstream/chat/android/client/parser2/adapters/ChannelMemberRequestAdapter.kt new file mode 100644 index 00000000000..92139910f6f --- /dev/null +++ b/stream-chat-android-client/src/main/java/io/getstream/chat/android/client/parser2/adapters/ChannelMemberRequestAdapter.kt @@ -0,0 +1,42 @@ +/* + * 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.parser2.adapters + +import com.squareup.moshi.FromJson +import com.squareup.moshi.JsonAdapter +import com.squareup.moshi.JsonReader +import com.squareup.moshi.JsonWriter +import com.squareup.moshi.ToJson +import io.getstream.chat.android.network.models.ChannelMemberRequest + +// The generated ChannelMemberRequest carries custom data in a `custom` field that must be flattened to the +// JSON root on the wire; extraDataPropertyName matches its @Json(name = "custom"). +internal object ChannelMemberRequestAdapter : + CustomObjectDtoAdapter(ChannelMemberRequest::class, extraDataPropertyName = "custom") { + + @FromJson + @Suppress("UNUSED_PARAMETER") + fun fromJson(jsonReader: JsonReader): ChannelMemberRequest = error("Can't parse this from Json") + + @ToJson + fun toJson( + jsonWriter: JsonWriter, + request: ChannelMemberRequest?, + mapAdapter: JsonAdapter>, + requestAdapter: JsonAdapter, + ) = serializeWithExtraData(jsonWriter, request, mapAdapter, requestAdapter) +} diff --git a/stream-chat-android-client/src/main/java/io/getstream/chat/android/client/parser2/adapters/MessageRequestAdapter.kt b/stream-chat-android-client/src/main/java/io/getstream/chat/android/client/parser2/adapters/MessageRequestAdapter.kt new file mode 100644 index 00000000000..28f5cb8210e --- /dev/null +++ b/stream-chat-android-client/src/main/java/io/getstream/chat/android/client/parser2/adapters/MessageRequestAdapter.kt @@ -0,0 +1,42 @@ +/* + * 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.parser2.adapters + +import com.squareup.moshi.FromJson +import com.squareup.moshi.JsonAdapter +import com.squareup.moshi.JsonReader +import com.squareup.moshi.JsonWriter +import com.squareup.moshi.ToJson +import io.getstream.chat.android.network.models.MessageRequest + +// The generated MessageRequest carries custom data in a `custom` field that must be flattened to the +// JSON root on the wire; extraDataPropertyName matches its @Json(name = "custom"). +internal object MessageRequestAdapter : + CustomObjectDtoAdapter(MessageRequest::class, extraDataPropertyName = "custom") { + + @FromJson + @Suppress("UNUSED_PARAMETER") + fun fromJson(jsonReader: JsonReader): MessageRequest = error("Can't parse this from Json") + + @ToJson + fun toJson( + jsonWriter: JsonWriter, + request: MessageRequest?, + mapAdapter: JsonAdapter>, + requestAdapter: JsonAdapter, + ) = serializeWithExtraData(jsonWriter, request, mapAdapter, requestAdapter) +} diff --git a/stream-chat-android-client/src/main/java/io/getstream/chat/android/client/api2/model/requests/InviteMembersRequest.kt b/stream-chat-android-client/src/main/java/io/getstream/chat/android/network/models/Action.kt similarity index 51% rename from stream-chat-android-client/src/main/java/io/getstream/chat/android/client/api2/model/requests/InviteMembersRequest.kt rename to stream-chat-android-client/src/main/java/io/getstream/chat/android/network/models/Action.kt index c3645062005..3488c5447c6 100644 --- a/stream-chat-android-client/src/main/java/io/getstream/chat/android/client/api2/model/requests/InviteMembersRequest.kt +++ b/stream-chat-android-client/src/main/java/io/getstream/chat/android/network/models/Action.kt @@ -14,14 +14,34 @@ * limitations under the License. */ -package io.getstream.chat.android.client.api2.model.requests +@file:Suppress( + "ArrayInDataClass", + "EnumEntryName", + "RemoveRedundantQualifierName", + "UnusedImport", +) + +package io.getstream.chat.android.network.models + +import com.squareup.moshi.Json + +/** + * + */ +@com.squareup.moshi.JsonClass(generateAdapter = true) +internal data class Action( + @Json(name = "name") + internal val name: String, + + @Json(name = "text") + internal val text: String, + + @Json(name = "type") + internal val type: String, -import com.squareup.moshi.JsonClass -import io.getstream.chat.android.client.api2.model.dto.UpstreamMessageDto + @Json(name = "style") + internal val style: String? = null, -@JsonClass(generateAdapter = true) -internal data class InviteMembersRequest( - val invites: List, - val message: UpstreamMessageDto?, - val skip_push: Boolean?, + @Json(name = "value") + internal val value: String? = null, ) diff --git a/stream-chat-android-client/src/main/java/io/getstream/chat/android/network/models/Attachment.kt b/stream-chat-android-client/src/main/java/io/getstream/chat/android/network/models/Attachment.kt new file mode 100644 index 00000000000..5291640bd04 --- /dev/null +++ b/stream-chat-android-client/src/main/java/io/getstream/chat/android/network/models/Attachment.kt @@ -0,0 +1,98 @@ +/* + * 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. + */ + +@file:Suppress( + "ArrayInDataClass", + "EnumEntryName", + "RemoveRedundantQualifierName", + "UnusedImport", +) + +package io.getstream.chat.android.network.models + +import com.squareup.moshi.Json + +/** + * An attachment is a message object that represents a file uploaded by a user. + */ +@com.squareup.moshi.JsonClass(generateAdapter = true) +internal data class Attachment( + @Json(name = "custom") + internal val custom: Map = emptyMap(), + + @Json(name = "asset_url") + internal val assetUrl: String? = null, + + @Json(name = "author_icon") + internal val authorIcon: String? = null, + + @Json(name = "author_link") + internal val authorLink: String? = null, + + @Json(name = "author_name") + internal val authorName: String? = null, + + @Json(name = "color") + internal val color: String? = null, + + @Json(name = "fallback") + internal val fallback: String? = null, + + @Json(name = "footer") + internal val footer: String? = null, + + @Json(name = "footer_icon") + internal val footerIcon: String? = null, + + @Json(name = "image_url") + internal val imageUrl: String? = null, + + @Json(name = "og_scrape_url") + internal val ogScrapeUrl: String? = null, + + @Json(name = "original_height") + internal val originalHeight: Int? = null, + + @Json(name = "original_width") + internal val originalWidth: Int? = null, + + @Json(name = "pretext") + internal val pretext: String? = null, + + @Json(name = "text") + internal val text: String? = null, + + @Json(name = "thumb_url") + internal val thumbUrl: String? = null, + + @Json(name = "title") + internal val title: String? = null, + + @Json(name = "title_link") + internal val titleLink: String? = null, + + @Json(name = "type") + internal val type: String? = null, + + @Json(name = "actions") + internal val actions: List? = emptyList(), + + @Json(name = "fields") + internal val fields: List? = emptyList(), + + @Json(name = "giphy") + internal val giphy: io.getstream.chat.android.network.models.Images? = null, +) diff --git a/stream-chat-android-client/src/main/java/io/getstream/chat/android/network/models/ChannelInputRequest.kt b/stream-chat-android-client/src/main/java/io/getstream/chat/android/network/models/ChannelInputRequest.kt new file mode 100644 index 00000000000..ac5495acf6b --- /dev/null +++ b/stream-chat-android-client/src/main/java/io/getstream/chat/android/network/models/ChannelInputRequest.kt @@ -0,0 +1,62 @@ +/* + * 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. + */ + +@file:Suppress( + "ArrayInDataClass", + "EnumEntryName", + "RemoveRedundantQualifierName", + "UnusedImport", +) + +package io.getstream.chat.android.network.models + +import com.squareup.moshi.Json + +/** + * + */ +@com.squareup.moshi.JsonClass(generateAdapter = true) +internal data class ChannelInputRequest( + @Json(name = "auto_translation_enabled") + internal val autoTranslationEnabled: Boolean? = null, + + @Json(name = "auto_translation_language") + internal val autoTranslationLanguage: String? = null, + + @Json(name = "disabled") + internal val disabled: Boolean? = null, + + @Json(name = "frozen") + internal val frozen: Boolean? = null, + + @Json(name = "team") + internal val team: String? = null, + + @Json(name = "invites") + internal val invites: List? = emptyList(), + + @Json(name = "members") + internal val members: List? = emptyList(), + + @Json(name = "config_overrides") + internal val configOverrides: io.getstream.chat.android.network.models.ConfigOverridesRequest? = null, + + @Json(name = "created_by") + internal val createdBy: io.getstream.chat.android.network.models.UserRequest? = null, + + @Json(name = "custom") + internal val custom: Map? = emptyMap(), +) diff --git a/stream-chat-android-client/src/main/java/io/getstream/chat/android/network/models/ChannelMemberRequest.kt b/stream-chat-android-client/src/main/java/io/getstream/chat/android/network/models/ChannelMemberRequest.kt new file mode 100644 index 00000000000..f4a987a9b4a --- /dev/null +++ b/stream-chat-android-client/src/main/java/io/getstream/chat/android/network/models/ChannelMemberRequest.kt @@ -0,0 +1,44 @@ +/* + * 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. + */ + +@file:Suppress( + "ArrayInDataClass", + "EnumEntryName", + "RemoveRedundantQualifierName", + "UnusedImport", +) + +package io.getstream.chat.android.network.models + +import com.squareup.moshi.Json + +/** + * + */ +@com.squareup.moshi.JsonClass(generateAdapter = true) +internal data class ChannelMemberRequest( + @Json(name = "user_id") + internal val userId: String, + + @Json(name = "channel_role") + internal val channelRole: String? = null, + + @Json(name = "custom") + internal val custom: Map? = emptyMap(), + + @Json(name = "user") + internal val user: io.getstream.chat.android.network.models.UserResponse? = null, +) diff --git a/stream-chat-android-client/src/main/java/io/getstream/chat/android/network/models/ChatPreferences.kt b/stream-chat-android-client/src/main/java/io/getstream/chat/android/network/models/ChatPreferences.kt new file mode 100644 index 00000000000..5a181c15fe9 --- /dev/null +++ b/stream-chat-android-client/src/main/java/io/getstream/chat/android/network/models/ChatPreferences.kt @@ -0,0 +1,56 @@ +/* + * 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. + */ + +@file:Suppress( + "ArrayInDataClass", + "EnumEntryName", + "RemoveRedundantQualifierName", + "UnusedImport", +) + +package io.getstream.chat.android.network.models + +import com.squareup.moshi.Json + +/** + * + */ +@com.squareup.moshi.JsonClass(generateAdapter = true) +internal data class ChatPreferences( + @Json(name = "channel_mentions") + internal val channelMentions: String? = null, + + @Json(name = "default_preference") + internal val defaultPreference: String? = null, + + @Json(name = "direct_mentions") + internal val directMentions: String? = null, + + @Json(name = "distinct_channel_messages") + internal val distinctChannelMessages: String? = null, + + @Json(name = "group_mentions") + internal val groupMentions: String? = null, + + @Json(name = "here_mentions") + internal val hereMentions: String? = null, + + @Json(name = "role_mentions") + internal val roleMentions: String? = null, + + @Json(name = "thread_replies") + internal val threadReplies: String? = null, +) diff --git a/stream-chat-android-client/src/main/java/io/getstream/chat/android/network/models/ConfigOverridesRequest.kt b/stream-chat-android-client/src/main/java/io/getstream/chat/android/network/models/ConfigOverridesRequest.kt new file mode 100644 index 00000000000..bc0fabbaff7 --- /dev/null +++ b/stream-chat-android-client/src/main/java/io/getstream/chat/android/network/models/ConfigOverridesRequest.kt @@ -0,0 +1,154 @@ +/* + * 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. + */ + +@file:Suppress( + "ArrayInDataClass", + "EnumEntryName", + "RemoveRedundantQualifierName", + "UnusedImport", +) + +package io.getstream.chat.android.network.models + +import com.squareup.moshi.FromJson +import com.squareup.moshi.Json +import com.squareup.moshi.JsonAdapter +import com.squareup.moshi.JsonReader +import com.squareup.moshi.JsonWriter +import com.squareup.moshi.ToJson + +/** + * Channel configuration overrides + */ +@com.squareup.moshi.JsonClass(generateAdapter = true) +internal data class ConfigOverridesRequest( + @Json(name = "blocklist") + internal val blocklist: String? = null, + + @Json(name = "blocklist_behavior") + internal val blocklistBehavior: BlocklistBehavior? = null, + + @Json(name = "count_messages") + internal val countMessages: Boolean? = null, + + @Json(name = "max_message_length") + internal val maxMessageLength: Int? = null, + + @Json(name = "push_level") + internal val pushLevel: PushLevel? = null, + + @Json(name = "quotes") + internal val quotes: Boolean? = null, + + @Json(name = "reactions") + internal val reactions: Boolean? = null, + + @Json(name = "replies") + internal val replies: Boolean? = null, + + @Json(name = "shared_locations") + internal val sharedLocations: Boolean? = null, + + @Json(name = "typing_events") + internal val typingEvents: Boolean? = null, + + @Json(name = "uploads") + internal val uploads: Boolean? = null, + + @Json(name = "url_enrichment") + internal val urlEnrichment: Boolean? = null, + + @Json(name = "user_message_reminders") + internal val userMessageReminders: Boolean? = null, + + @Json(name = "commands") + internal val commands: List? = emptyList(), + + @Json(name = "chat_preferences") + internal val chatPreferences: io.getstream.chat.android.network.models.ChatPreferences? = null, + + @Json(name = "grants") + internal val grants: Map>? = emptyMap(), +) { + + /** + * BlocklistBehavior Enum + */ + internal sealed class BlocklistBehavior(internal val value: String) { + override fun toString(): String = value + + internal companion object { + internal fun fromString(s: String): BlocklistBehavior = when (s) { + "block" -> Block + "flag" -> Flag + else -> Unknown(s) + } + } + internal object Block : BlocklistBehavior("block") + internal object Flag : BlocklistBehavior("flag") + internal data class Unknown(val unknownValue: String) : BlocklistBehavior(unknownValue) + + internal class BlocklistBehaviorAdapter : JsonAdapter() { + @FromJson + override fun fromJson(reader: JsonReader): BlocklistBehavior? { + val s = reader.nextString() ?: return null + return BlocklistBehavior.fromString(s) + } + + @ToJson + override fun toJson(writer: JsonWriter, value: BlocklistBehavior?) { + writer.value(value?.value) + } + } + } + + /** + * PushLevel Enum + */ + internal sealed class PushLevel(internal val value: String) { + override fun toString(): String = value + + internal companion object { + internal fun fromString(s: String): PushLevel = when (s) { + "all" -> All + "all_mentions" -> AllMentions + "direct_mentions" -> DirectMentions + "mentions" -> Mentions + "none" -> None + else -> Unknown(s) + } + } + internal object All : PushLevel("all") + internal object AllMentions : PushLevel("all_mentions") + internal object DirectMentions : PushLevel("direct_mentions") + internal object Mentions : PushLevel("mentions") + internal object None : PushLevel("none") + internal data class Unknown(val unknownValue: String) : PushLevel(unknownValue) + + internal class PushLevelAdapter : JsonAdapter() { + @FromJson + override fun fromJson(reader: JsonReader): PushLevel? { + val s = reader.nextString() ?: return null + return PushLevel.fromString(s) + } + + @ToJson + override fun toJson(writer: JsonWriter, value: PushLevel?) { + writer.value(value?.value) + } + } + } +} diff --git a/stream-chat-android-client/src/main/java/io/getstream/chat/android/client/api2/model/requests/RemoveMembersRequest.kt b/stream-chat-android-client/src/main/java/io/getstream/chat/android/network/models/Field.kt similarity index 57% rename from stream-chat-android-client/src/main/java/io/getstream/chat/android/client/api2/model/requests/RemoveMembersRequest.kt rename to stream-chat-android-client/src/main/java/io/getstream/chat/android/network/models/Field.kt index 7f8f2cfecf0..0666ccd2e09 100644 --- a/stream-chat-android-client/src/main/java/io/getstream/chat/android/client/api2/model/requests/RemoveMembersRequest.kt +++ b/stream-chat-android-client/src/main/java/io/getstream/chat/android/network/models/Field.kt @@ -14,14 +14,28 @@ * limitations under the License. */ -package io.getstream.chat.android.client.api2.model.requests +@file:Suppress( + "ArrayInDataClass", + "EnumEntryName", + "RemoveRedundantQualifierName", + "UnusedImport", +) + +package io.getstream.chat.android.network.models + +import com.squareup.moshi.Json + +/** + * + */ +@com.squareup.moshi.JsonClass(generateAdapter = true) +internal data class Field( + @Json(name = "short") + internal val short: Boolean, -import com.squareup.moshi.JsonClass -import io.getstream.chat.android.client.api2.model.dto.UpstreamMessageDto + @Json(name = "title") + internal val title: String, -@JsonClass(generateAdapter = true) -internal data class RemoveMembersRequest( - val remove_members: List, - val message: UpstreamMessageDto?, - val skip_push: Boolean?, + @Json(name = "value") + internal val value: String, ) diff --git a/stream-chat-android-client/src/main/java/io/getstream/chat/android/client/api2/model/requests/AddMembersRequest.kt b/stream-chat-android-client/src/main/java/io/getstream/chat/android/network/models/ImageData.kt similarity index 51% rename from stream-chat-android-client/src/main/java/io/getstream/chat/android/client/api2/model/requests/AddMembersRequest.kt rename to stream-chat-android-client/src/main/java/io/getstream/chat/android/network/models/ImageData.kt index b6a448bb064..9475e528c05 100644 --- a/stream-chat-android-client/src/main/java/io/getstream/chat/android/client/api2/model/requests/AddMembersRequest.kt +++ b/stream-chat-android-client/src/main/java/io/getstream/chat/android/network/models/ImageData.kt @@ -14,18 +14,34 @@ * limitations under the License. */ -package io.getstream.chat.android.client.api2.model.requests - -import com.squareup.moshi.JsonClass -import io.getstream.chat.android.client.api2.model.dto.UpstreamMemberDataDto -import io.getstream.chat.android.client.api2.model.dto.UpstreamMessageDto -import java.util.Date - -@JsonClass(generateAdapter = true) -internal data class AddMembersRequest( - val add_members: List, - val message: UpstreamMessageDto?, - val hide_history: Boolean?, - val hide_history_before: Date?, - val skip_push: Boolean?, +@file:Suppress( + "ArrayInDataClass", + "EnumEntryName", + "RemoveRedundantQualifierName", + "UnusedImport", +) + +package io.getstream.chat.android.network.models + +import com.squareup.moshi.Json + +/** + * + */ +@com.squareup.moshi.JsonClass(generateAdapter = true) +internal data class ImageData( + @Json(name = "frames") + internal val frames: String, + + @Json(name = "height") + internal val height: String, + + @Json(name = "size") + internal val size: String, + + @Json(name = "url") + internal val url: String, + + @Json(name = "width") + internal val width: String, ) diff --git a/stream-chat-android-client/src/main/java/io/getstream/chat/android/network/models/Images.kt b/stream-chat-android-client/src/main/java/io/getstream/chat/android/network/models/Images.kt new file mode 100644 index 00000000000..0635509a40e --- /dev/null +++ b/stream-chat-android-client/src/main/java/io/getstream/chat/android/network/models/Images.kt @@ -0,0 +1,53 @@ +/* + * 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. + */ + +@file:Suppress( + "ArrayInDataClass", + "EnumEntryName", + "RemoveRedundantQualifierName", + "UnusedImport", +) + +package io.getstream.chat.android.network.models + +import com.squareup.moshi.Json + +/** + * + */ +@com.squareup.moshi.JsonClass(generateAdapter = true) +internal data class Images( + @Json(name = "fixed_height") + internal val fixedHeight: io.getstream.chat.android.network.models.ImageData, + + @Json(name = "fixed_height_downsampled") + internal val fixedHeightDownsampled: io.getstream.chat.android.network.models.ImageData, + + @Json(name = "fixed_height_still") + internal val fixedHeightStill: io.getstream.chat.android.network.models.ImageData, + + @Json(name = "fixed_width") + internal val fixedWidth: io.getstream.chat.android.network.models.ImageData, + + @Json(name = "fixed_width_downsampled") + internal val fixedWidthDownsampled: io.getstream.chat.android.network.models.ImageData, + + @Json(name = "fixed_width_still") + internal val fixedWidthStill: io.getstream.chat.android.network.models.ImageData, + + @Json(name = "original") + internal val original: io.getstream.chat.android.network.models.ImageData, +) diff --git a/stream-chat-android-client/src/main/java/io/getstream/chat/android/network/models/MessageRequest.kt b/stream-chat-android-client/src/main/java/io/getstream/chat/android/network/models/MessageRequest.kt new file mode 100644 index 00000000000..d4abaf89d04 --- /dev/null +++ b/stream-chat-android-client/src/main/java/io/getstream/chat/android/network/models/MessageRequest.kt @@ -0,0 +1,134 @@ +/* + * 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. + */ + +@file:Suppress( + "ArrayInDataClass", + "EnumEntryName", + "RemoveRedundantQualifierName", + "UnusedImport", +) + +package io.getstream.chat.android.network.models + +import com.squareup.moshi.FromJson +import com.squareup.moshi.Json +import com.squareup.moshi.JsonAdapter +import com.squareup.moshi.JsonReader +import com.squareup.moshi.JsonWriter +import com.squareup.moshi.ToJson + +/** + * Message data for creating or updating a message + */ +@com.squareup.moshi.JsonClass(generateAdapter = true) +internal data class MessageRequest( + @Json(name = "id") + internal val id: String? = null, + + @Json(name = "mentioned_channel") + internal val mentionedChannel: Boolean? = null, + + @Json(name = "mentioned_here") + internal val mentionedHere: Boolean? = null, + + @Json(name = "mml") + internal val mml: String? = null, + + @Json(name = "parent_id") + internal val parentId: String? = null, + + @Json(name = "pin_expires") + internal val pinExpires: java.util.Date? = null, + + @Json(name = "pinned") + internal val pinned: Boolean? = null, + + @Json(name = "pinned_at") + internal val pinnedAt: java.util.Date? = null, + + @Json(name = "poll_id") + internal val pollId: String? = null, + + @Json(name = "quoted_message_id") + internal val quotedMessageId: String? = null, + + @Json(name = "show_in_channel") + internal val showInChannel: Boolean? = null, + + @Json(name = "silent") + internal val silent: Boolean? = null, + + @Json(name = "text") + internal val text: String? = null, + + @Json(name = "type") + internal val type: Type? = null, + + @Json(name = "attachments") + internal val attachments: List? = emptyList(), + + @Json(name = "mentioned_group_ids") + internal val mentionedGroupIds: List? = emptyList(), + + @Json(name = "mentioned_roles") + internal val mentionedRoles: List? = emptyList(), + + @Json(name = "mentioned_users") + internal val mentionedUsers: List? = emptyList(), + + @Json(name = "restricted_visibility") + internal val restrictedVisibility: List? = emptyList(), + + @Json(name = "custom") + internal val custom: Map? = emptyMap(), + + @Json(name = "shared_location") + internal val sharedLocation: io.getstream.chat.android.network.models.SharedLocation? = null, +) { + + /** + * Type Enum + */ + internal sealed class Type(internal val value: String) { + override fun toString(): String = value + + internal companion object { + internal fun fromString(s: String): Type = when (s) { + "''" -> Empty + "regular" -> Regular + "system" -> System + else -> Unknown(s) + } + } + internal object Empty : Type("''") + internal object Regular : Type("regular") + internal object System : Type("system") + internal data class Unknown(val unknownValue: String) : Type(unknownValue) + + internal class TypeAdapter : JsonAdapter() { + @FromJson + override fun fromJson(reader: JsonReader): Type? { + val s = reader.nextString() ?: return null + return Type.fromString(s) + } + + @ToJson + override fun toJson(writer: JsonWriter, value: Type?) { + writer.value(value?.value) + } + } + } +} diff --git a/stream-chat-android-client/src/main/java/io/getstream/chat/android/client/api2/model/requests/RejectInviteRequest.kt b/stream-chat-android-client/src/main/java/io/getstream/chat/android/network/models/SharedLocation.kt similarity index 51% rename from stream-chat-android-client/src/main/java/io/getstream/chat/android/client/api2/model/requests/RejectInviteRequest.kt rename to stream-chat-android-client/src/main/java/io/getstream/chat/android/network/models/SharedLocation.kt index 7a64b2269c8..3c1bbdd0276 100644 --- a/stream-chat-android-client/src/main/java/io/getstream/chat/android/client/api2/model/requests/RejectInviteRequest.kt +++ b/stream-chat-android-client/src/main/java/io/getstream/chat/android/network/models/SharedLocation.kt @@ -14,11 +14,31 @@ * limitations under the License. */ -package io.getstream.chat.android.client.api2.model.requests +@file:Suppress( + "ArrayInDataClass", + "EnumEntryName", + "RemoveRedundantQualifierName", + "UnusedImport", +) + +package io.getstream.chat.android.network.models + +import com.squareup.moshi.Json + +/** + * + */ +@com.squareup.moshi.JsonClass(generateAdapter = true) +internal data class SharedLocation( + @Json(name = "latitude") + internal val latitude: Float, + + @Json(name = "longitude") + internal val longitude: Float, -import com.squareup.moshi.JsonClass + @Json(name = "created_by_device_id") + internal val createdByDeviceId: String? = null, -@JsonClass(generateAdapter = true) -internal data class RejectInviteRequest( - val reject_invite: Boolean = true, + @Json(name = "end_at") + internal val endAt: java.util.Date? = null, ) diff --git a/stream-chat-android-client/src/main/java/io/getstream/chat/android/network/models/UpdateChannelRequest.kt b/stream-chat-android-client/src/main/java/io/getstream/chat/android/network/models/UpdateChannelRequest.kt new file mode 100644 index 00000000000..01ecce46018 --- /dev/null +++ b/stream-chat-android-client/src/main/java/io/getstream/chat/android/network/models/UpdateChannelRequest.kt @@ -0,0 +1,80 @@ +/* + * 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. + */ + +@file:Suppress( + "ArrayInDataClass", + "EnumEntryName", + "RemoveRedundantQualifierName", + "UnusedImport", +) + +package io.getstream.chat.android.network.models + +import com.squareup.moshi.Json + +/** + * + */ +@com.squareup.moshi.JsonClass(generateAdapter = true) +internal data class UpdateChannelRequest( + @Json(name = "accept_invite") + internal val acceptInvite: Boolean? = null, + + @Json(name = "cooldown") + internal val cooldown: Int? = null, + + @Json(name = "hide_history") + internal val hideHistory: Boolean? = null, + + @Json(name = "hide_history_before") + internal val hideHistoryBefore: java.util.Date? = null, + + @Json(name = "reject_invite") + internal val rejectInvite: Boolean? = null, + + @Json(name = "skip_push") + internal val skipPush: Boolean? = null, + + @Json(name = "add_filter_tags") + internal val addFilterTags: List? = emptyList(), + + @Json(name = "add_members") + internal val addMembers: List? = emptyList(), + + @Json(name = "add_moderators") + internal val addModerators: List? = emptyList(), + + @Json(name = "assign_roles") + internal val assignRoles: List? = emptyList(), + + @Json(name = "demote_moderators") + internal val demoteModerators: List? = emptyList(), + + @Json(name = "invites") + internal val invites: List? = emptyList(), + + @Json(name = "remove_filter_tags") + internal val removeFilterTags: List? = emptyList(), + + @Json(name = "remove_members") + internal val removeMembers: List? = emptyList(), + + @Json(name = "data") + internal val data: io.getstream.chat.android.network.models.ChannelInputRequest? = null, + + @Json(name = "message") + internal val message: io.getstream.chat.android.network.models.MessageRequest? = null, +) diff --git a/stream-chat-android-client/src/main/java/io/getstream/chat/android/network/models/UserResponse.kt b/stream-chat-android-client/src/main/java/io/getstream/chat/android/network/models/UserResponse.kt new file mode 100644 index 00000000000..d018da2fb43 --- /dev/null +++ b/stream-chat-android-client/src/main/java/io/getstream/chat/android/network/models/UserResponse.kt @@ -0,0 +1,86 @@ +/* + * 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. + */ + +@file:Suppress( + "ArrayInDataClass", + "EnumEntryName", + "RemoveRedundantQualifierName", + "UnusedImport", +) + +package io.getstream.chat.android.network.models + +import com.squareup.moshi.Json + +/** + * User response object + */ +@com.squareup.moshi.JsonClass(generateAdapter = true) +internal data class UserResponse( + @Json(name = "banned") + internal val banned: Boolean, + + @Json(name = "created_at") + internal val createdAt: java.util.Date, + + @Json(name = "id") + internal val id: String, + + @Json(name = "language") + internal val language: String, + + @Json(name = "online") + internal val online: Boolean, + + @Json(name = "role") + internal val role: String, + + @Json(name = "updated_at") + internal val updatedAt: java.util.Date, + + @Json(name = "blocked_user_ids") + internal val blockedUserIds: List = emptyList(), + + @Json(name = "teams") + internal val teams: List = emptyList(), + + @Json(name = "custom") + internal val custom: Map = emptyMap(), + + @Json(name = "avg_response_time") + internal val avgResponseTime: Int? = null, + + @Json(name = "deactivated_at") + internal val deactivatedAt: java.util.Date? = null, + + @Json(name = "deleted_at") + internal val deletedAt: java.util.Date? = null, + + @Json(name = "image") + internal val image: String? = null, + + @Json(name = "last_active") + internal val lastActive: java.util.Date? = null, + + @Json(name = "name") + internal val name: String? = null, + + @Json(name = "revoke_tokens_issued_before") + internal val revokeTokensIssuedBefore: java.util.Date? = null, + + @Json(name = "teams_role") + internal val teamsRole: Map? = emptyMap(), +) diff --git a/stream-chat-android-client/src/test/java/io/getstream/chat/android/client/api2/MoshiChatApiTest.kt b/stream-chat-android-client/src/test/java/io/getstream/chat/android/client/api2/MoshiChatApiTest.kt index aacee4f8a2d..7a9b1f40126 100644 --- a/stream-chat-android-client/src/test/java/io/getstream/chat/android/client/api2/MoshiChatApiTest.kt +++ b/stream-chat-android-client/src/test/java/io/getstream/chat/android/client/api2/MoshiChatApiTest.kt @@ -44,14 +44,12 @@ import io.getstream.chat.android.client.api2.model.dto.DownstreamLocationDto import io.getstream.chat.android.client.api2.model.dto.DownstreamPushPreferenceDto import io.getstream.chat.android.client.api2.model.dto.UpstreamChatPreferencesDto import io.getstream.chat.android.client.api2.model.dto.UpstreamPushPreferenceInputDto -import io.getstream.chat.android.client.api2.model.requests.AcceptInviteRequest import io.getstream.chat.android.client.api2.model.requests.BanUserRequest import io.getstream.chat.android.client.api2.model.requests.FlagMessageRequest import io.getstream.chat.android.client.api2.model.requests.FlagUserRequest import io.getstream.chat.android.client.api2.model.requests.MuteUserRequest import io.getstream.chat.android.client.api2.model.requests.PinnedMessagesRequest import io.getstream.chat.android.client.api2.model.requests.QueryBannedUsersRequest -import io.getstream.chat.android.client.api2.model.requests.RejectInviteRequest import io.getstream.chat.android.client.api2.model.requests.UpdateLiveLocationRequest import io.getstream.chat.android.client.api2.model.requests.UpdateMemberPartialResponse import io.getstream.chat.android.client.api2.model.requests.UpsertPushPreferencesRequest @@ -152,6 +150,7 @@ import io.getstream.chat.android.network.models.MarkDeliveredRequest import io.getstream.chat.android.network.models.MarkReadRequest import io.getstream.chat.android.network.models.MarkUnreadRequest import io.getstream.chat.android.network.models.MessageActionRequest +import io.getstream.chat.android.network.models.MessageRequest import io.getstream.chat.android.network.models.MuteChannelRequest import io.getstream.chat.android.network.models.PollOptionInput import io.getstream.chat.android.network.models.PollOptionRequest @@ -170,6 +169,7 @@ import io.getstream.chat.android.network.models.SortParamRequest import io.getstream.chat.android.network.models.UnblockUsersRequest import io.getstream.chat.android.network.models.UnblockUsersResponse import io.getstream.chat.android.network.models.UpdateChannelPartialRequest +import io.getstream.chat.android.network.models.UpdateChannelRequest import io.getstream.chat.android.network.models.UpdateMemberPartialRequest import io.getstream.chat.android.network.models.UpdateMessagePartialRequest import io.getstream.chat.android.network.models.UpdatePollOptionRequest @@ -1407,7 +1407,7 @@ internal class MoshiChatApiTest { val channelId = randomString() val result = sut.rejectInvite(channelType, channelId).await() // then - val expectedBody = RejectInviteRequest() + val expectedBody = UpdateChannelRequest(rejectInvite = true) result `should be instance of` expected verify(api, times(1)).rejectInvite(channelType, channelId, expectedBody) } @@ -1430,7 +1430,10 @@ internal class MoshiChatApiTest { sut.setConnection(userId = userId, connectionId = connectionId) val result = sut.acceptInvite(channelType, channelId, message).await() // then - val expectedBody = AcceptInviteRequest.create(userId, message) + val expectedBody = UpdateChannelRequest( + acceptInvite = true, + message = MessageRequest(text = message), + ) result `should be instance of` expected verify(api, times(1)).acceptInvite(channelType, channelId, expectedBody) } diff --git a/stream-chat-android-client/src/test/java/io/getstream/chat/android/client/parser2/UpdateChannelRequestAdapterTest.kt b/stream-chat-android-client/src/test/java/io/getstream/chat/android/client/parser2/UpdateChannelRequestAdapterTest.kt new file mode 100644 index 00000000000..9787426c641 --- /dev/null +++ b/stream-chat-android-client/src/test/java/io/getstream/chat/android/client/parser2/UpdateChannelRequestAdapterTest.kt @@ -0,0 +1,61 @@ +/* + * 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.parser2 + +import io.getstream.chat.android.client.parser2.testdata.UpdateChannelRequestTestData +import org.junit.jupiter.api.Assertions +import org.junit.jupiter.api.Test + +internal class UpdateChannelRequestAdapterTest { + private val parser = ParserFactory.createMoshiChatParser() + + @Test + fun `Serialize UpdateChannelRequest for rejectInvite`() { + val json = parser.toJson(UpdateChannelRequestTestData.rejectInviteRequest) + Assertions.assertEquals(UpdateChannelRequestTestData.rejectInviteJson, json) + } + + @Test + fun `Serialize UpdateChannelRequest for addMembers with nested member and message`() { + val json = parser.toJson(UpdateChannelRequestTestData.addMembersRequest) + Assertions.assertEquals(UpdateChannelRequestTestData.addMembersJson, json) + } + + @Test + fun `Serialize UpdateChannelRequest for updateChannel with channel data`() { + val json = parser.toJson(UpdateChannelRequestTestData.updateChannelRequest) + Assertions.assertEquals(UpdateChannelRequestTestData.updateChannelJson, json) + } + + @Test + fun `Serialize UpdateChannelRequest for acceptInvite`() { + val json = parser.toJson(UpdateChannelRequestTestData.acceptInviteRequest) + Assertions.assertEquals(UpdateChannelRequestTestData.acceptInviteJson, json) + } + + @Test + fun `Serialize UpdateChannelRequest for removeMembers`() { + val json = parser.toJson(UpdateChannelRequestTestData.removeMembersRequest) + Assertions.assertEquals(UpdateChannelRequestTestData.removeMembersJson, json) + } + + @Test + fun `Serialize UpdateChannelRequest for inviteMembers`() { + val json = parser.toJson(UpdateChannelRequestTestData.inviteMembersRequest) + Assertions.assertEquals(UpdateChannelRequestTestData.inviteMembersJson, json) + } +} diff --git a/stream-chat-android-client/src/test/java/io/getstream/chat/android/client/parser2/testdata/UpdateChannelRequestTestData.kt b/stream-chat-android-client/src/test/java/io/getstream/chat/android/client/parser2/testdata/UpdateChannelRequestTestData.kt new file mode 100644 index 00000000000..41f2b55d868 --- /dev/null +++ b/stream-chat-android-client/src/test/java/io/getstream/chat/android/client/parser2/testdata/UpdateChannelRequestTestData.kt @@ -0,0 +1,83 @@ +/* + * 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.parser2.testdata + +import io.getstream.chat.android.network.models.ChannelInputRequest +import io.getstream.chat.android.network.models.ChannelMemberRequest +import io.getstream.chat.android.network.models.MessageRequest +import io.getstream.chat.android.network.models.UpdateChannelRequest + +internal object UpdateChannelRequestTestData { + + private const val EMPTY_LISTS = + """"add_filter_tags":[],"add_members":[],"add_moderators":[],"assign_roles":[],""" + + """"demote_moderators":[],"invites":[],"remove_filter_tags":[],"remove_members":[]""" + + val updateChannelRequest = UpdateChannelRequest( + data = ChannelInputRequest(custom = mapOf("probe_key" to "probe_value")), + ) + const val updateChannelJson = + """{$EMPTY_LISTS,"data":{"invites":[],"members":[],"probe_key":"probe_value"}}""" + + val acceptInviteRequest = UpdateChannelRequest( + acceptInvite = true, + message = MessageRequest(text = "accepting"), + ) + const val acceptInviteJson = + """{"accept_invite":true,$EMPTY_LISTS,"message":{"text":"accepting","attachments":[],""" + + """"mentioned_group_ids":[],"mentioned_roles":[],"mentioned_users":[],"restricted_visibility":[]}}""" + + val removeMembersRequest = UpdateChannelRequest( + removeMembers = listOf("han"), + skipPush = true, + ) + const val removeMembersJson = + """{"skip_push":true,"add_filter_tags":[],"add_members":[],"add_moderators":[],"assign_roles":[],""" + + """"demote_moderators":[],"invites":[],"remove_filter_tags":[],"remove_members":["han"]}""" + + val inviteMembersRequest = UpdateChannelRequest( + invites = listOf(ChannelMemberRequest(userId = "han")), + skipPush = true, + ) + const val inviteMembersJson = + """{"skip_push":true,"add_filter_tags":[],"add_members":[],"add_moderators":[],"assign_roles":[],""" + + """"demote_moderators":[],"invites":[{"user_id":"han"}],"remove_filter_tags":[],"remove_members":[]}""" + + val rejectInviteRequest = UpdateChannelRequest(rejectInvite = true) + const val rejectInviteJson = + """{"reject_invite":true,"add_filter_tags":[],"add_members":[],"add_moderators":[],""" + + """"assign_roles":[],"demote_moderators":[],"invites":[],"remove_filter_tags":[],""" + + """"remove_members":[]}""" + + val addMembersRequest = UpdateChannelRequest( + addMembers = listOf( + ChannelMemberRequest(userId = "u1", channelRole = "moderator", custom = mapOf("k" to "v")), + ), + message = MessageRequest( + text = "added", + type = MessageRequest.Type.System, + custom = mapOf("mk" to "mv"), + ), + skipPush = true, + ) + const val addMembersJson = + """{"skip_push":true,"add_filter_tags":[],"add_members":[{"user_id":"u1","channel_role":"moderator",""" + + """"k":"v"}],"add_moderators":[],"assign_roles":[],"demote_moderators":[],"invites":[],""" + + """"remove_filter_tags":[],"remove_members":[],"message":{"text":"added","type":"system",""" + + """"attachments":[],"mentioned_group_ids":[],"mentioned_roles":[],"mentioned_users":[],""" + + """"restricted_visibility":[],"mk":"mv"}}""" +}