Skip to content

Commit 8549a96

Browse files
committed
Handle comment reaction upserted & removed for Feed
1 parent d636366 commit 8549a96

File tree

15 files changed

+627
-491
lines changed

15 files changed

+627
-491
lines changed

stream-feeds-android-client/src/main/kotlin/io/getstream/feeds/android/client/api/model/ActivityData.kt

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -351,3 +351,27 @@ internal inline fun ActivityData.changeReactions(
351351

352352
return update(updated, ownReactions = updatedOwnReactions)
353353
}
354+
355+
internal fun ActivityData.removeCommentReaction(
356+
updated: CommentData,
357+
reaction: FeedsReactionData,
358+
currentUserId: String,
359+
): ActivityData =
360+
copy(
361+
comments =
362+
comments.updateIf({ it.id == updated.id }) { comment ->
363+
comment.removeReaction(updated, reaction, currentUserId)
364+
}
365+
)
366+
367+
internal fun ActivityData.upsertCommentReaction(
368+
updated: CommentData,
369+
reaction: FeedsReactionData,
370+
currentUserId: String,
371+
): ActivityData =
372+
copy(
373+
comments =
374+
comments.updateIf({ it.id == updated.id }) { comment ->
375+
comment.upsertReaction(updated, reaction, currentUserId)
376+
}
377+
)

stream-feeds-android-client/src/main/kotlin/io/getstream/feeds/android/client/api/model/CommentData.kt

Lines changed: 55 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
package io.getstream.feeds.android.client.api.model
1717

1818
import io.getstream.feeds.android.client.api.state.query.CommentsSortDataFields
19+
import io.getstream.feeds.android.client.internal.utils.upsert
1920
import io.getstream.feeds.android.network.models.Attachment
2021
import io.getstream.feeds.android.network.models.CommentResponse
2122
import java.util.Date
@@ -141,5 +142,57 @@ internal fun CommentResponse.toModel(): CommentData =
141142
* Updates the comment while preserving own reactions because "own" data from WS events is not
142143
* reliable.
143144
*/
144-
internal fun CommentData.update(updated: CommentData): CommentData =
145-
updated.copy(ownReactions = ownReactions)
145+
internal fun CommentData.update(
146+
updated: CommentData,
147+
ownReactions: List<FeedsReactionData> = this.ownReactions,
148+
): CommentData = updated.copy(ownReactions = ownReactions)
149+
150+
/**
151+
* Removes a reaction from the comment, updating the latest reactions, reaction groups, reaction
152+
* count, and own reactions.
153+
*
154+
* @param updated The updated comment data.
155+
* @param reaction The reaction to remove.
156+
* @param currentUserId The ID of the current user, used to determine if the reaction belongs to
157+
* them.
158+
* @return A new [CommentData] instance with the updated reactions and counts.
159+
*/
160+
internal fun CommentData.removeReaction(
161+
updated: CommentData,
162+
reaction: FeedsReactionData,
163+
currentUserId: String,
164+
): CommentData =
165+
changeReactions(updated, reaction, currentUserId) { filter { it.id != reaction.id } }
166+
167+
/**
168+
* Merges the receiver comment with [updated] and upserts the given [reaction] into own reactions if
169+
* it belongs to the current user.
170+
*
171+
* @param updated The updated comment data.
172+
* @param reaction The reaction to be added.
173+
* @param currentUserId The ID of the current user, used to determine if the reaction belongs to
174+
* them.
175+
* @return A new [CommentData] instance with the updated reactions and counts.
176+
*/
177+
internal fun CommentData.upsertReaction(
178+
updated: CommentData,
179+
reaction: FeedsReactionData,
180+
currentUserId: String,
181+
): CommentData =
182+
changeReactions(updated, reaction, currentUserId) { upsert(reaction, FeedsReactionData::id) }
183+
184+
internal inline fun CommentData.changeReactions(
185+
updated: CommentData,
186+
reaction: FeedsReactionData,
187+
currentUserId: String,
188+
updateOwnReactions: List<FeedsReactionData>.() -> List<FeedsReactionData>,
189+
): CommentData {
190+
val updatedOwnReactions =
191+
if (reaction.user.id == currentUserId) {
192+
this.ownReactions.updateOwnReactions()
193+
} else {
194+
this.ownReactions
195+
}
196+
197+
return update(updated, ownReactions = updatedOwnReactions)
198+
}

stream-feeds-android-client/src/main/kotlin/io/getstream/feeds/android/client/internal/state/ActivityImpl.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,7 @@ internal class ActivityImpl(
164164
.addCommentReaction(commentId, request)
165165
.onSuccess { (reaction, comment) ->
166166
subscriptionManager.onEvent(
167-
StateUpdateEvent.CommentReactionAdded(comment, reaction)
167+
StateUpdateEvent.CommentReactionAdded(fid.rawValue, comment, reaction)
168168
)
169169
}
170170
.map { it.first }
@@ -178,7 +178,7 @@ internal class ActivityImpl(
178178
.deleteCommentReaction(commentId, type)
179179
.onSuccess { (reaction, comment) ->
180180
subscriptionManager.onEvent(
181-
StateUpdateEvent.CommentReactionDeleted(comment, reaction)
181+
StateUpdateEvent.CommentReactionDeleted(fid.rawValue, comment, reaction)
182182
)
183183
}
184184
.map { it.first }

stream-feeds-android-client/src/main/kotlin/io/getstream/feeds/android/client/internal/state/FeedImpl.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -406,7 +406,7 @@ internal class FeedImpl(
406406
.addCommentReaction(commentId, request)
407407
.onSuccess { (reaction, comment) ->
408408
subscriptionManager.onEvent(
409-
StateUpdateEvent.CommentReactionAdded(comment, reaction)
409+
StateUpdateEvent.CommentReactionAdded(fid.rawValue, comment, reaction)
410410
)
411411
}
412412
.map { it.first }
@@ -420,7 +420,7 @@ internal class FeedImpl(
420420
.deleteCommentReaction(commentId = commentId, type = type)
421421
.onSuccess { (reaction, comment) ->
422422
subscriptionManager.onEvent(
423-
StateUpdateEvent.CommentReactionDeleted(comment, reaction)
423+
StateUpdateEvent.CommentReactionDeleted(fid.rawValue, comment, reaction)
424424
)
425425
}
426426
.map { it.first }

stream-feeds-android-client/src/main/kotlin/io/getstream/feeds/android/client/internal/state/FeedStateImpl.kt

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,11 +36,13 @@ import io.getstream.feeds.android.client.api.model.addComment
3636
import io.getstream.feeds.android.client.api.model.castVote
3737
import io.getstream.feeds.android.client.api.model.deleteBookmark
3838
import io.getstream.feeds.android.client.api.model.removeComment
39+
import io.getstream.feeds.android.client.api.model.removeCommentReaction
3940
import io.getstream.feeds.android.client.api.model.removeReaction
4041
import io.getstream.feeds.android.client.api.model.removeVote
4142
import io.getstream.feeds.android.client.api.model.setClosed
4243
import io.getstream.feeds.android.client.api.model.update
4344
import io.getstream.feeds.android.client.api.model.upsertBookmark
45+
import io.getstream.feeds.android.client.api.model.upsertCommentReaction
4446
import io.getstream.feeds.android.client.api.model.upsertReaction
4547
import io.getstream.feeds.android.client.api.state.FeedState
4648
import io.getstream.feeds.android.client.api.state.query.ActivitiesQueryConfig
@@ -223,6 +225,22 @@ internal class FeedStateImpl(
223225
}
224226
}
225227

228+
override fun onCommentReactionRemoved(comment: CommentData, reaction: FeedsReactionData) {
229+
_activities.update { current ->
230+
current.updateIf({ it.id == comment.objectId }) { activity ->
231+
activity.removeCommentReaction(comment, reaction, currentUserId)
232+
}
233+
}
234+
}
235+
236+
override fun onCommentReactionUpserted(comment: CommentData, reaction: FeedsReactionData) {
237+
_activities.update { current ->
238+
current.updateIf({ it.id == comment.objectId }) { activity ->
239+
activity.upsertCommentReaction(comment, reaction, currentUserId)
240+
}
241+
}
242+
}
243+
226244
override fun onFeedDeleted() {
227245
_activities.update { emptyList() }
228246
_feed.update { null }
@@ -426,6 +444,12 @@ internal interface FeedStateUpdates {
426444
/** Handles updates to the feed state when a comment is removed. */
427445
fun onCommentRemoved(comment: CommentData)
428446

447+
/** Handles updates to the feed state when a comment reaction is removed. */
448+
fun onCommentReactionRemoved(comment: CommentData, reaction: FeedsReactionData)
449+
450+
/** Handles updates to the feed state when a comment reaction is added or updated. */
451+
fun onCommentReactionUpserted(comment: CommentData, reaction: FeedsReactionData)
452+
429453
/** Handles updates to the feed state when the feed is deleted. */
430454
fun onFeedDeleted()
431455

stream-feeds-android-client/src/main/kotlin/io/getstream/feeds/android/client/internal/state/event/StateUpdateEvent.kt

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -120,14 +120,23 @@ internal sealed interface StateUpdateEvent {
120120

121121
data class CommentUpdated(val comment: CommentData) : StateUpdateEvent
122122

123-
data class CommentReactionAdded(val comment: CommentData, val reaction: FeedsReactionData) :
124-
StateUpdateEvent
123+
data class CommentReactionAdded(
124+
val fid: String,
125+
val comment: CommentData,
126+
val reaction: FeedsReactionData,
127+
) : StateUpdateEvent
125128

126-
data class CommentReactionDeleted(val comment: CommentData, val reaction: FeedsReactionData) :
127-
StateUpdateEvent
129+
data class CommentReactionDeleted(
130+
val fid: String,
131+
val comment: CommentData,
132+
val reaction: FeedsReactionData,
133+
) : StateUpdateEvent
128134

129-
data class CommentReactionUpdated(val comment: CommentData, val reaction: FeedsReactionData) :
130-
StateUpdateEvent
135+
data class CommentReactionUpdated(
136+
val fid: String,
137+
val comment: CommentData,
138+
val reaction: FeedsReactionData,
139+
) : StateUpdateEvent
131140

132141
data class FeedUpdated(val feed: FeedData) : StateUpdateEvent
133142

@@ -210,13 +219,13 @@ internal fun WSEvent.toModel(): StateUpdateEvent? =
210219
is CommentDeletedEvent -> StateUpdateEvent.CommentDeleted(fid, comment.toModel())
211220

212221
is CommentReactionAddedEvent ->
213-
StateUpdateEvent.CommentReactionAdded(comment.toModel(), reaction.toModel())
222+
StateUpdateEvent.CommentReactionAdded(fid, comment.toModel(), reaction.toModel())
214223

215224
is CommentReactionDeletedEvent ->
216-
StateUpdateEvent.CommentReactionDeleted(comment.toModel(), reaction.toModel())
225+
StateUpdateEvent.CommentReactionDeleted(fid, comment.toModel(), reaction.toModel())
217226

218227
is CommentReactionUpdatedEvent ->
219-
StateUpdateEvent.CommentReactionUpdated(comment.toModel(), reaction.toModel())
228+
StateUpdateEvent.CommentReactionUpdated(fid, comment.toModel(), reaction.toModel())
220229

221230
is FeedUpdatedEvent -> StateUpdateEvent.FeedUpdated(feed.toModel())
222231

stream-feeds-android-client/src/main/kotlin/io/getstream/feeds/android/client/internal/state/event/handler/FeedEventHandler.kt

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,24 @@ internal class FeedEventHandler(private val fid: FeedId, private val state: Feed
123123
}
124124
}
125125

126+
is StateUpdateEvent.CommentReactionAdded -> {
127+
if (event.fid == fid.rawValue) {
128+
state.onCommentReactionUpserted(event.comment, event.reaction)
129+
}
130+
}
131+
132+
is StateUpdateEvent.CommentReactionDeleted -> {
133+
if (event.fid == fid.rawValue) {
134+
state.onCommentReactionRemoved(event.comment, event.reaction)
135+
}
136+
}
137+
138+
is StateUpdateEvent.CommentReactionUpdated -> {
139+
if (event.fid == fid.rawValue) {
140+
state.onCommentReactionUpserted(event.comment, event.reaction)
141+
}
142+
}
143+
126144
is StateUpdateEvent.FeedDeleted -> {
127145
if (event.fid == fid.rawValue) {
128146
state.onFeedDeleted()

0 commit comments

Comments
 (0)