Parse the message responses with the generated models · GetStream/stream-chat-android@5b96903 · GitHub
Skip to content

Commit 5b96903

Browse files
committed
Parse the message responses with the generated models
1 parent f196da7 commit 5b96903

21 files changed

Lines changed: 970 additions & 116 deletions

‎stream-chat-android-client/src/main/java/io/getstream/chat/android/client/api2/MoshiChatApi.kt‎

Lines changed: 14 additions & 7 deletions

‎stream-chat-android-client/src/main/java/io/getstream/chat/android/client/api2/endpoint/MessageApi.kt‎

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -17,23 +17,30 @@
1717
package io.getstream.chat.android.client.api2.endpoint
1818

1919
import io.getstream.chat.android.client.api.AuthenticatedApi
20-
import io.getstream.chat.android.client.api2.model.response.MessageResponse
2120
import io.getstream.chat.android.client.call.RetrofitCall
2221
import io.getstream.chat.android.network.models.CreateDraftResponse
22+
import io.getstream.chat.android.network.models.DeleteMessageResponse
23+
import io.getstream.chat.android.network.models.DeleteReactionResponse
24+
import io.getstream.chat.android.network.models.GetMessageResponse
2325
import io.getstream.chat.android.network.models.GetReactionsResponse
2426
import io.getstream.chat.android.network.models.GetRepliesResponse
2527
import io.getstream.chat.android.network.models.MessageActionRequest
28+
import io.getstream.chat.android.network.models.MessageActionResponse
2629
import io.getstream.chat.android.network.models.QueryDraftsRequest
2730
import io.getstream.chat.android.network.models.QueryDraftsResponse
2831
import io.getstream.chat.android.network.models.QueryReactionsRequest
2932
import io.getstream.chat.android.network.models.QueryReactionsResponse
3033
import io.getstream.chat.android.network.models.Response
3134
import io.getstream.chat.android.network.models.SendMessageRequest
35+
import io.getstream.chat.android.network.models.SendMessageResponse
3236
import io.getstream.chat.android.network.models.SendReactionRequest
3337
import io.getstream.chat.android.network.models.SendReactionResponse
3438
import io.getstream.chat.android.network.models.TranslateMessageRequest
39+
import io.getstream.chat.android.network.models.TranslateMessageResponse
3540
import io.getstream.chat.android.network.models.UpdateMessagePartialRequest
41+
import io.getstream.chat.android.network.models.UpdateMessagePartialResponse
3642
import io.getstream.chat.android.network.models.UpdateMessageRequest
43+
import io.getstream.chat.android.network.models.UpdateMessageResponse
3744
import retrofit2.http.Body
3845
import retrofit2.http.DELETE
3946
import retrofit2.http.GET
@@ -54,7 +61,7 @@ internal interface MessageApi {
5461
@Path("type") channelType: String,
5562
@Path("id") channelId: String,
5663
@Body message: SendMessageRequest,
57-
): RetrofitCall<MessageResponse>
64+
): RetrofitCall<SendMessageResponse>
5865

5966
@POST("/channels/{type}/{id}/draft")
6067
fun createDraftMessage(
@@ -77,7 +84,7 @@ internal interface MessageApi {
7784
fun queryDrafts(@Body body: QueryDraftsRequest): RetrofitCall<QueryDraftsResponse>
7885

7986
@GET("/messages/{id}")
80-
fun getMessage(@Path("id") messageId: String): RetrofitCall<MessageResponse>
87+
fun getMessage(@Path("id") messageId: String): RetrofitCall<GetMessageResponse>
8188

8289
/**
8390
* [REST documentation]()https://getstream.io/chat/docs/rest/#messages-updatemessage)
@@ -86,7 +93,7 @@ internal interface MessageApi {
8693
fun updateMessage(
8794
@Path("id") messageId: String,
8895
@Body message: UpdateMessageRequest,
89-
): RetrofitCall<MessageResponse>
96+
): RetrofitCall<UpdateMessageResponse>
9097

9198
/**
9299
* [Rest documentation](https://getstream.io/chat/docs/rest/#messages-updatemessagepartial-request)
@@ -95,20 +102,20 @@ internal interface MessageApi {
95102
fun partialUpdateMessage(
96103
@Path("id") messageId: String,
97104
@Body body: UpdateMessagePartialRequest,
98-
): RetrofitCall<MessageResponse>
105+
): RetrofitCall<UpdateMessagePartialResponse>
99106

100107
@DELETE("/messages/{id}")
101108
fun deleteMessage(
102109
@Path("id") messageId: String,
103110
@Query("hard") hard: Boolean?,
104111
@Query("delete_for_me") deleteForMe: Boolean?,
105-
): RetrofitCall<MessageResponse>
112+
): RetrofitCall<DeleteMessageResponse>
106113

107114
@POST("/messages/{id}/action")
108115
fun sendAction(
109116
@Path("id") messageId: String,
110117
@Body request: MessageActionRequest,
111-
): RetrofitCall<MessageResponse>
118+
): RetrofitCall<MessageActionResponse>
112119

113120
@POST("/messages/{id}/reaction")
114121
fun sendReaction(
@@ -120,7 +127,7 @@ internal interface MessageApi {
120127
fun deleteReaction(
121128
@Path("id") messageId: String,
122129
@Path("type") reactionType: String,
123-
): RetrofitCall<MessageResponse>
130+
): RetrofitCall<DeleteReactionResponse>
124131

125132
@GET("/messages/{id}/reactions")
126133
fun getReactions(
@@ -139,7 +146,7 @@ internal interface MessageApi {
139146
fun translate(
140147
@Path("messageId") messageId: String,
141148
@Body request: TranslateMessageRequest,
142-
): RetrofitCall<MessageResponse>
149+
): RetrofitCall<TranslateMessageResponse>
143150

144151
@GET("/messages/{parent_id}/replies")
145152
fun getReplies(

‎stream-chat-android-client/src/main/java/io/getstream/chat/android/client/api2/mapping/DomainMapping.kt‎

Lines changed: 72 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -112,8 +112,10 @@ import io.getstream.chat.android.network.models.DeviceResponse
112112
import io.getstream.chat.android.network.models.DraftResponse
113113
import io.getstream.chat.android.network.models.FullUserResponse
114114
import io.getstream.chat.android.network.models.GetApplicationResponse
115+
import io.getstream.chat.android.network.models.GetMessageResponse
115116
import io.getstream.chat.android.network.models.GetOGResponse
116117
import io.getstream.chat.android.network.models.MessageResponse
118+
import io.getstream.chat.android.network.models.MessageWithChannelResponse
117119
import io.getstream.chat.android.network.models.ModerationV2Response
118120
import io.getstream.chat.android.network.models.OwnUserResponse
119121
import io.getstream.chat.android.network.models.PendingMessageResponse
@@ -145,7 +147,6 @@ import io.getstream.chat.android.network.models.UserResponseCommonFields
145147
import io.getstream.chat.android.network.models.UserResponsePrivacyFields
146148
import io.getstream.chat.android.network.models.WrappedUnreadCountsResponse
147149
import java.util.Date
148-
import io.getstream.chat.android.client.api2.model.response.MessageResponse as MessageEnvelope
149150
import io.getstream.chat.android.network.models.ChannelMute as ChannelMuteResponse
150151
import io.getstream.chat.android.network.models.Command as CommandDto
151152
import io.getstream.chat.android.network.models.FileUploadConfig as UploadConfigDto
@@ -416,15 +417,6 @@ internal class DomainMapping(
416417
pushPreferences = pushPreferences,
417418
)
418419

419-
/**
420-
* Transforms [MessageEnvelope] to [PendingMessage].
421-
*/
422-
internal fun MessageEnvelope.toDomain(): PendingMessage =
423-
PendingMessage(
424-
message = message.toDomain(),
425-
metadata = pending_message_metadata.orEmpty(),
426-
)
427-
428420
/**
429421
* Maps the reactions of one message, dropping any that the response attributes to another message.
430422
*/
@@ -555,6 +547,76 @@ internal class DomainMapping(
555547
sharedLocation = sharedLocation,
556548
)
557549

550+
/**
551+
* Transforms the generated [GetMessageResponse] into a [PendingMessage]. Its metadata stays empty: the backend
552+
* only sends it to server-side callers.
553+
*/
554+
internal fun GetMessageResponse.toPendingMessage(): PendingMessage =
555+
PendingMessage(message = message.toDomain(), metadata = emptyMap())
556+
557+
/**
558+
* Transforms the generated [MessageWithChannelResponse] into a domain [Message], with the channel info of the
559+
* channel it carries.
560+
*/
561+
internal fun MessageWithChannelResponse.toDomain(): Message = toMessageResponse().toDomain(channel.toChannelInfo())
562+
563+
/**
564+
* The [MessageResponse] this response extends: every field but the channel, so it maps through the same message
565+
* mapper.
566+
*/
567+
internal fun MessageWithChannelResponse.toMessageResponse(): MessageResponse = MessageResponse(
568+
cid = cid,
569+
createdAt = createdAt,
570+
deletedReplyCount = deletedReplyCount,
571+
html = html,
572+
id = id,
573+
mentionedChannel = mentionedChannel,
574+
mentionedHere = mentionedHere,
575+
pinned = pinned,
576+
replyCount = replyCount,
577+
shadowed = shadowed,
578+
silent = silent,
579+
text = text,
580+
type = type,
581+
updatedAt = updatedAt,
582+
attachments = attachments,
583+
latestReactions = latestReactions,
584+
mentionedUsers = mentionedUsers,
585+
ownReactions = ownReactions,
586+
restrictedVisibility = restrictedVisibility,
587+
custom = custom,
588+
reactionCounts = reactionCounts,
589+
reactionScores = reactionScores,
590+
user = user,
591+
command = command,
592+
deletedAt = deletedAt,
593+
deletedForMe = deletedForMe,
594+
messageTextUpdatedAt = messageTextUpdatedAt,
595+
mml = mml,
596+
parentId = parentId,
597+
pinExpires = pinExpires,
598+
pinnedAt = pinnedAt,
599+
pollId = pollId,
600+
quotedMessageId = quotedMessageId,
601+
showInChannel = showInChannel,
602+
mentionedGroupIds = mentionedGroupIds,
603+
mentionedGroups = mentionedGroups,
604+
mentionedRoles = mentionedRoles,
605+
threadParticipants = threadParticipants,
606+
draft = draft,
607+
i18n = i18n,
608+
imageLabels = imageLabels,
609+
member = member,
610+
mentionedChannelMembers = mentionedChannelMembers,
611+
moderation = moderation,
612+
pinnedBy = pinnedBy,
613+
poll = poll,
614+
quotedMessage = quotedMessage,
615+
reactionGroups = reactionGroups,
616+
reminder = reminder,
617+
sharedLocation = sharedLocation,
618+
)
619+
558620
// V1 moderation is injected into the message custom data by the auto-mod bounce path rather than
559621
// declared on the payload, so it arrives flattened at the root and has to be read back out.
560622
private fun MessageResponse.moderationDetailsFromCustom(): MessageModerationDetails? {

‎stream-chat-android-client/src/main/java/io/getstream/chat/android/client/parser2/MoshiChatParser.kt‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ import io.getstream.chat.android.client.parser2.adapters.GetOGResponseAdapter
5151
import io.getstream.chat.android.client.parser2.adapters.MemberUserRequestAdapter
5252
import io.getstream.chat.android.client.parser2.adapters.MessageRequestAdapter
5353
import io.getstream.chat.android.client.parser2.adapters.MessageResponseAdapter
54+
import io.getstream.chat.android.client.parser2.adapters.MessageWithChannelResponseAdapter
5455
import io.getstream.chat.android.client.parser2.adapters.NetworkAttachmentAdapter
5556
import io.getstream.chat.android.client.parser2.adapters.NullCollectionsAsEmptyFactory
5657
import io.getstream.chat.android.client.parser2.adapters.OwnUserResponseAdapter
@@ -117,6 +118,7 @@ internal class MoshiChatParser(
117118
.add(MessageRequestAdapter)
118119
.add(MessageResponseAdapter)
119120
.add(SearchResultMessageAdapter)
121+
.add(MessageWithChannelResponseAdapter)
120122
.add(ChannelMemberRequestAdapter)
121123
.add(ChannelInputAdapter)
122124
.add(ChannelInputRequestAdapter)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
/*
2+
* Copyright (c) 2014-2026 Stream.io Inc. All rights reserved.
3+
*
4+
* Licensed under the Stream License;
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://github.com/GetStream/stream-chat-android/blob/main/LICENSE
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package io.getstream.chat.android.client.parser2.adapters
18+
19+
import com.squareup.moshi.FromJson
20+
import com.squareup.moshi.JsonAdapter
21+
import com.squareup.moshi.JsonReader
22+
import com.squareup.moshi.JsonWriter
23+
import com.squareup.moshi.ToJson
24+
import io.getstream.chat.android.network.models.MessageWithChannelResponse
25+
26+
// Downstream (read-only) adapter for the generated MessageWithChannelResponse: collects root-level custom fields
27+
// into `custom`, matching the wire's flattened extra data, like MessageResponseAdapter.
28+
internal object MessageWithChannelResponseAdapter :
29+
CustomObjectDtoAdapter<MessageWithChannelResponse>(
30+
MessageWithChannelResponse::class,
31+
extraDataPropertyName = "custom",
32+
alsoKeepInExtraData = GENERATED_MESSAGE_EXTRA_DATA_KEYS,
33+
) {
34+
35+
@FromJson
36+
fun fromJson(
37+
jsonReader: JsonReader,
38+
mapAdapter: JsonAdapter<MutableMap<String, Any>>,
39+
valueAdapter: JsonAdapter<MessageWithChannelResponse>,
40+
): MessageWithChannelResponse? = parseWithExtraData(jsonReader, mapAdapter, valueAdapter)
41+
42+
@ToJson
43+
fun toJson(jsonWriter: JsonWriter, value: MessageWithChannelResponse?) {
44+
if (value != null) error("Can't convert this to Json")
45+
jsonWriter.nullValue()
46+
}
47+
}
Lines changed: 44 additions & 0 deletions

0 commit comments

Comments
 (0)