Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,6 @@ import io.getstream.chat.android.client.api2.model.requests.QueryGroupedChannels
import io.getstream.chat.android.client.api2.model.requests.QueryPollVotesRequest
import io.getstream.chat.android.client.api2.model.requests.QueryPollsRequest
import io.getstream.chat.android.client.api2.model.requests.QueryRemindersRequest
import io.getstream.chat.android.client.api2.model.requests.ReactionRequest
import io.getstream.chat.android.client.api2.model.requests.RejectInviteRequest
import io.getstream.chat.android.client.api2.model.requests.ReminderRequest
import io.getstream.chat.android.client.api2.model.requests.RemoveMembersRequest
Expand Down Expand Up @@ -166,6 +165,7 @@ import io.getstream.chat.android.network.models.MarkReadRequest
import io.getstream.chat.android.network.models.MarkUnreadRequest
import io.getstream.chat.android.network.models.MuteChannelRequest
import io.getstream.chat.android.network.models.QueryReactionsRequest
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
Expand Down Expand Up @@ -445,10 +445,10 @@ constructor(
override fun sendReaction(reaction: Reaction, enforceUnique: Boolean, skipPush: Boolean): Call<Reaction> {
return messageApi.sendReaction(
messageId = reaction.messageId,
request = ReactionRequest(
request = SendReactionRequest(
reaction = with(dtoMapping) { reaction.toDto() },
enforce_unique = enforceUnique,
skip_push = skipPush,
enforceUnique = enforceUnique,
skipPush = skipPush,
),
).mapDomain { response ->
response.reaction.toDomain()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ import io.getstream.chat.android.client.api.AuthenticatedApi
import io.getstream.chat.android.client.api2.model.requests.PartialUpdateMessageRequest
import io.getstream.chat.android.client.api2.model.requests.QueryDraftMessagesRequest
import io.getstream.chat.android.client.api2.model.requests.QueryDraftsRequest
import io.getstream.chat.android.client.api2.model.requests.ReactionRequest
import io.getstream.chat.android.client.api2.model.requests.SendActionRequest
import io.getstream.chat.android.client.api2.model.requests.SendMessageRequest
import io.getstream.chat.android.client.api2.model.requests.UpdateMessageRequest
Expand All @@ -35,6 +34,7 @@ import io.getstream.chat.android.client.api2.model.response.TranslateMessageRequ
import io.getstream.chat.android.client.call.RetrofitCall
import io.getstream.chat.android.network.models.QueryReactionsRequest
import io.getstream.chat.android.network.models.Response
import io.getstream.chat.android.network.models.SendReactionRequest
import retrofit2.http.Body
import retrofit2.http.DELETE
import retrofit2.http.GET
Expand Down Expand Up @@ -119,7 +119,7 @@ internal interface MessageApi {
@POST("/messages/{id}/reaction")
fun sendReaction(
@Path("id") messageId: String,
@Body request: ReactionRequest,
@Body request: SendReactionRequest,
): RetrofitCall<ReactionResponse>

@DELETE("/messages/{id}/reaction/{type}")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@ import io.getstream.chat.android.client.api2.model.dto.UpstreamMemberDataDto
import io.getstream.chat.android.client.api2.model.dto.UpstreamMemberDto
import io.getstream.chat.android.client.api2.model.dto.UpstreamMessageDto
import io.getstream.chat.android.client.api2.model.dto.UpstreamMuteDto
import io.getstream.chat.android.client.api2.model.dto.UpstreamReactionDto
import io.getstream.chat.android.client.api2.model.dto.UpstreamUserDto
import io.getstream.chat.android.client.events.ConnectedEvent
import io.getstream.chat.android.models.Attachment
Expand All @@ -51,6 +50,7 @@ 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.ReactionRequest

internal class DtoMapping(
private val messageTransformer: MessageTransformer,
Expand Down Expand Up @@ -202,18 +202,14 @@ internal class DtoMapping(
)

/**
* Maps the domain [Reaction] model to a network [UpstreamReactionDto].
* Maps the domain [Reaction] model to a network [ReactionRequest].
*/
internal fun Reaction.toDto(): UpstreamReactionDto = UpstreamReactionDto(
created_at = createdAt,
message_id = messageId,
score = score,
internal fun Reaction.toDto(): ReactionRequest = ReactionRequest(
type = type,
updated_at = updatedAt,
user = user?.toDto(),
user_id = userId,
emoji_code = emojiCode,
extraData = extraData,
createdAt = createdAt,
score = score,
updatedAt = updatedAt,
custom = if (emojiCode != null) extraData + ("emoji_code" to emojiCode) else extraData,
)

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,31 +20,6 @@ import com.squareup.moshi.JsonClass
import io.getstream.chat.android.core.internal.StreamHandsOff
import java.util.Date

/**
* See [io.getstream.chat.android.client.parser2.adapters.UpstreamReactionDtoAdapter] for
* special [extraData] handling.
*/
@StreamHandsOff(
reason = "Field names can't be changed because [CustomObjectDtoAdapter] class uses reflections to add/remove " +
"content of [extraData] map",
)
@JsonClass(generateAdapter = true)
internal data class UpstreamReactionDto(
val created_at: Date?,
val message_id: String,
val score: Int,
val type: String,
val updated_at: Date?,
val user: UpstreamUserDto?,
val user_id: String,
// Note: This is not contextually a top-level field in the API, it should be inside `reaction.extraData`.
// But for convenience, we make it a top-level field here, because when serialized, it will be top-level in the
// JSON string.
val emoji_code: String?,

val extraData: Map<String, Any>,
) : ExtraDataDto

/**
* See [io.getstream.chat.android.client.parser2.adapters.DownstreamReactionDtoAdapter] for
* special [extraData] handling.
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -16,28 +16,35 @@

package io.getstream.chat.android.client.parser2.adapters

import com.squareup.moshi.Json
import com.squareup.moshi.JsonAdapter
import com.squareup.moshi.JsonReader
import com.squareup.moshi.JsonWriter
import kotlin.reflect.KClass
import kotlin.reflect.full.findAnnotation
import kotlin.reflect.full.primaryConstructor

/**
* Base class for implementing Moshi adapters that support our API's dynamic
* JSON models.
*
* [extraDataPropertyName] names the property that holds the overflow map (`extraData` or `custom`).
*/
internal open class CustomObjectDtoAdapter<Value : Any>(private val kClass: KClass<Value>) {

private companion object {
private const val EXTRA_DATA = "extraData"
}
internal open class CustomObjectDtoAdapter<Value : Any>(
private val kClass: KClass<Value>,
private val extraDataPropertyName: String = "extraData",
) {

/**
* Names of the declared properties that are inside the [Value] type being
* handled. These will not be copied into extraData when parsing with
* [parseWithExtraData].
* Wire-format names of the declared properties on [Value]. These will not be copied into the
* overflow map when parsing with [parseWithExtraData]. Reads `@Json(name = ...)` first so
* camelCase properties map to their snake_case wire names, falling back to the Kotlin
* parameter name when `@Json` is absent.
*/
private val memberNames: List<String> by lazy {
kClass.members.map { member -> member.name }.minus(EXTRA_DATA)
kClass.primaryConstructor?.parameters.orEmpty().mapNotNull { param ->
(param.findAnnotation<Json>()?.name ?: param.name)?.takeIf { it != extraDataPropertyName }
}
}

/**
Expand All @@ -60,9 +67,9 @@ internal open class CustomObjectDtoAdapter<Value : Any>(private val kClass: KCla

val extraData = mutableMapOf<String, Any>()

// Save the value of the literal "extraData" field at the root of the object, if present
map[EXTRA_DATA]?.let { explicitExtraData ->
extraData[EXTRA_DATA] = explicitExtraData
// Save the value of the literal extraData field at the root of the object, if present
map[extraDataPropertyName]?.let { explicitExtraData ->
extraData[extraDataPropertyName] = explicitExtraData
}

// Save the values of non-member fields as extra data
Expand All @@ -72,8 +79,8 @@ internal open class CustomObjectDtoAdapter<Value : Any>(private val kClass: KCla
}
}

// Replace original "extraData" with the newly collected values
map[EXTRA_DATA] = extraData
// Replace original extraData with the newly collected values
map[extraDataPropertyName] = extraData

// Parse output value object from the transformed Map
return valueAdapter.fromJsonValue(map)!!
Expand All @@ -99,14 +106,14 @@ internal open class CustomObjectDtoAdapter<Value : Any>(private val kClass: KCla
// Convert input value into a Map
val map: MutableMap<String, Any?> = valueAdapter.toJsonValue(value) as MutableMap<String, Any?>

// Grab real "extraData" property's value
val extraData = map[EXTRA_DATA] as Map<String, Any?>
// Grab real extraData property's value
val extraData = map[extraDataPropertyName] as? Map<String, Any?>

// Remove literal "extraData" field from Map
map.remove(EXTRA_DATA)
// Remove literal extraData field from Map
map.remove(extraDataPropertyName)

// Merge all values from "extraData" property back into the Map as top level fields
map.putAll(extraData)
// Merge all values from the extraData property back into the Map as top level fields
extraData?.let(map::putAll)

// Write Map to output
mapAdapter.toJson(jsonWriter, map)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import com.squareup.moshi.JsonReader
import com.squareup.moshi.JsonWriter
import com.squareup.moshi.ToJson
import io.getstream.chat.android.client.api2.model.dto.DownstreamReactionDto
import io.getstream.chat.android.client.api2.model.dto.UpstreamReactionDto
import io.getstream.chat.android.network.models.ReactionRequest

internal object DownstreamReactionDtoAdapter :
CustomObjectDtoAdapter<DownstreamReactionDto>(DownstreamReactionDto::class) {
Expand All @@ -40,17 +40,17 @@ internal object DownstreamReactionDtoAdapter :
}

internal object UpstreamReactionDtoAdapter :
CustomObjectDtoAdapter<UpstreamReactionDto>(UpstreamReactionDto::class) {
CustomObjectDtoAdapter<ReactionRequest>(ReactionRequest::class, extraDataPropertyName = "custom") {

@FromJson
@Suppress("UNUSED_PARAMETER")
fun fromJson(jsonReader: JsonReader): UpstreamReactionDto = error("Can't parse this from Json")
fun fromJson(jsonReader: JsonReader): ReactionRequest = error("Can't parse this from Json")

@ToJson
fun toJson(
jsonWriter: JsonWriter,
message: UpstreamReactionDto?,
reaction: ReactionRequest?,
mapAdapter: JsonAdapter<MutableMap<String, Any?>>,
messageAdapter: JsonAdapter<UpstreamReactionDto>,
) = serializeWithExtraData(jsonWriter, message, mapAdapter, messageAdapter)
reactionAdapter: JsonAdapter<ReactionRequest>,
) = serializeWithExtraData(jsonWriter, reaction, mapAdapter, reactionAdapter)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
/*
* 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
import kotlin.collections.Map

/**
* Represents user reaction to a message
*/

@com.squareup.moshi.JsonClass(generateAdapter = true)
internal data class ReactionRequest(
@Json(name = "type")
val type: kotlin.String,

@Json(name = "created_at")
val createdAt: java.util.Date? = null,

@Json(name = "score")
val score: kotlin.Int? = null,

@Json(name = "updated_at")
val updatedAt: java.util.Date? = null,

@Json(name = "custom")
val custom: kotlin.collections.Map<kotlin.String, Any?>? = emptyMap(),
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/*
* 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 SendReactionRequest(
@Json(name = "reaction")
val reaction: ReactionRequest,

@Json(name = "enforce_unique")
val enforceUnique: kotlin.Boolean? = null,

@Json(name = "skip_push")
val skipPush: kotlin.Boolean? = null,
)
Loading
Loading