Skip to content

Patch 2#39

Open
TheRealAshik wants to merge 6 commits intomainfrom
patch
Open

Patch 2#39
TheRealAshik wants to merge 6 commits intomainfrom
patch

Conversation

@TheRealAshik
Copy link
Copy Markdown
Contributor

Fix notifications deserialization and user click bugs (#38)

  • fix: resolve notification deserialization and user click issues
  • Make NotificationDto.body nullable to prevent silent deserialization exceptions on non-JSON data.
  • Extract senderId from DTO and map it to actorId in domain and UI models.
  • Update NotificationItem to pass the correct actorId to onUserClick instead of the display name.
  • fix: re-trigger CI build for Kilo Code Review
  • Make NotificationDto.body nullable to prevent silent deserialization exceptions on non-JSON data.
  • Extract senderId from DTO and map it to actorId in domain and UI models.
  • Update NotificationItem to pass the correct actorId to onUserClick instead of the display name.
  • fix: re-trigger CI build for Kilo Code Review again
  • Make NotificationDto.body nullable to prevent silent deserialization exceptions on non-JSON data.
  • Extract senderId from DTO and map it to actorId in domain and UI models.
  • Update NotificationItem to pass the correct actorId to onUserClick instead of the display name.

TheRealAshik and others added 6 commits April 7, 2026 10:38
* fix: resolve notification deserialization and user click issues

- Make `NotificationDto.body` nullable to prevent silent deserialization exceptions on non-JSON data.
- Extract `senderId` from DTO and map it to `actorId` in domain and UI models.
- Update `NotificationItem` to pass the correct `actorId` to `onUserClick` instead of the display name.

* fix: re-trigger CI build for Kilo Code Review

- Make `NotificationDto.body` nullable to prevent silent deserialization exceptions on non-JSON data.
- Extract `senderId` from DTO and map it to `actorId` in domain and UI models.
- Update `NotificationItem` to pass the correct `actorId` to `onUserClick` instead of the display name.

* fix: re-trigger CI build for Kilo Code Review again

- Make `NotificationDto.body` nullable to prevent silent deserialization exceptions on non-JSON data.
- Extract `senderId` from DTO and map it to `actorId` in domain and UI models.
- Update `NotificationItem` to pass the correct `actorId` to `onUserClick` instead of the display name.
@supabase
Copy link
Copy Markdown

supabase bot commented Apr 7, 2026

This pull request has been ignored for the connected project apqvyyphlrtmuyjnzmuq because there are no changes detected in supabase directory. You can change this behaviour in Project Integrations Settings ↗︎.


Preview Branches by Supabase.
Learn more about Supabase Branching ↗︎.

Copy link
Copy Markdown

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request implements real-time message reactions and enhances notification navigation by utilizing actor IDs. Key updates include a new reaction subscription in ChatSubscriptionDelegate, state management for incoming reactions in ChatViewModel, and schema adjustments for reaction types. Feedback identifies a logic error in reaction counting that ignores removals, suggests scoping reaction subscriptions to specific chats for efficiency, and recommends safer null-handling for actor IDs in the UI.

Comment on lines +432 to +437
current.updateById(reaction.messageId) { msg ->
val counts = msg.reactions.toMutableMap()
counts[reactionType] = (counts[reactionType] ?: 0) + 1
val userReaction = if (reaction.userId == currentUserId) reactionType else msg.userReaction
msg.copy(reactions = counts, userReaction = userReaction)
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

The logic for handling incoming real-time reactions is flawed. It assumes every reaction event is an addition and unconditionally increments the count with (counts[reactionType] ?: 0) + 1. This doesn't handle cases where a user removes a reaction, which will lead to incorrect reaction counts on other clients' devices. The real-time event should either contain information about whether it's an addition or removal, or the client should refetch the counts to ensure correctness. The current implementation will lead to UI inconsistencies.

}

reactionSubscriptionJob = viewModelScope.launch {
subscribeToMessageReactionsUseCase().collect { reaction ->
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The subscription to message reactions appears to be global rather than scoped to the current chat. Other subscriptions in this class, such as for messages and typing status, use the chatId. Subscribing to all reactions for the user could be inefficient if the volume of reactions is high, as the client would process events for chats that are not currently open. Consider scoping this subscription to the chatId if the backend supports it to improve performance.

Suggested change
subscribeToMessageReactionsUseCase().collect { reaction ->
subscribeToMessageReactionsUseCase(chatId).collect { reaction ->

contentDescription = "Avatar",
size = Sizes.IconGiant,
onClick = { onUserClick(actorNameString) }
onClick = { onUserClick(notification.actorId ?: "") }
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Passing an empty string to onUserClick when notification.actorId is null might lead to unexpected behavior, such as attempting to navigate to a profile with an empty ID. It would be safer to prevent the click action altogether if the ID is not available.

Suggested change
onClick = { onUserClick(notification.actorId ?: "") }
onClick = { notification.actorId?.let(onUserClick) }

style = MaterialTheme.typography.bodyLarge,
fontWeight = FontWeight.Bold,
modifier = Modifier.clickable(onClick = { onUserClick(actorNameString) })
modifier = Modifier.clickable(onClick = { onUserClick(notification.actorId ?: "") })
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Passing an empty string to onUserClick when notification.actorId is null might lead to unexpected behavior, such as attempting to navigate to a profile with an empty ID. It would be safer to prevent the click action altogether if the ID is not available.

Suggested change
modifier = Modifier.clickable(onClick = { onUserClick(notification.actorId ?: "") })
modifier = Modifier.clickable(onClick = { notification.actorId?.let(onUserClick) })

@SerialName("message_id") val messageId: String,
@SerialName("user_id") val userId: String,
@SerialName("reaction_emoji") val reactionEmoji: String,
@SerialName("reaction_type") val reactionEmoji: String,
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The property name reactionEmoji is now misleading as it's mapped to the reaction_type field in JSON. To improve code clarity and consistency with the backend schema, consider renaming the property to reactionType as well.

Suggested change
@SerialName("reaction_type") val reactionEmoji: String,
@SerialName("reaction_type") val reactionType: String,

@kilo-code-bot
Copy link
Copy Markdown

kilo-code-bot bot commented Apr 7, 2026

Code Review Summary

Status: No Issues Found | Recommendation: Merge

This PR successfully addresses several bugs:

  • Notification body nullable - Makes body nullable in NotificationDto to prevent silent deserialization exceptions
  • User click fix - Passes actorId instead of display name to onUserClick, fixing the navigation bug
  • Reaction column fix - Updates DTO field from reaction_emoji to reaction_type to match the database schema
  • Real-time reactions - Adds subscription for live reaction updates in the chat
  • Storage fallback - Adds SynapseConfig.IMGBB_API_KEY as fallback for image uploads
Files Reviewed (13 files)
  • app/src/main/kotlin/com/synapse/social/studioasinc/feature/inbox/inbox/ChatSubscriptionDelegate.kt
  • app/src/main/kotlin/com/synapse/social/studioasinc/feature/inbox/inbox/ChatViewModel.kt
  • app/src/main/kotlin/com/synapse/social/studioasinc/feature/inbox/inbox/components/ChatIntroHeader.kt
  • app/src/main/kotlin/com/synapse/social/studioasinc/feature/inbox/inbox/components/MessageBubble.kt
  • app/src/main/kotlin/com/synapse/social/studioasinc/feature/inbox/inbox/screens/ChatMessageList.kt
  • app/src/main/kotlin/com/synapse/social/studioasinc/feature/inbox/inbox/screens/ChatScreen.kt
  • app/src/main/kotlin/com/synapse/social/studioasinc/ui/notifications/NotificationItem.kt
  • app/src/main/kotlin/com/synapse/social/studioasinc/ui/notifications/NotificationsViewModel.kt
  • shared/src/commonMain/kotlin/com/synapse/social/studioasinc/shared/data/datasource/ChatReactionDataSource.kt
  • shared/src/commonMain/kotlin/com/synapse/social/studioasinc/shared/data/dto/chat/MessageReactionDto.kt
  • shared/src/commonMain/kotlin/com/synapse/social/studioasinc/shared/data/mapper/NotificationMapper.kt
  • shared/src/commonMain/kotlin/com/synapse/social/studioasinc/shared/data/model/NotificationDtos.kt
  • shared/src/commonMain/kotlin/com/synapse/social/studioasinc/shared/data/repository/StorageRepositoryImpl.kt
  • shared/src/commonMain/kotlin/com/synapse/social/studioasinc/shared/domain/model/Notification.kt

Reviewed by minimax-m2.5-20260211 · 513,289 tokens

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant