android: add reply-forward preview data foundation
Some checks are pending
CI / test (push) Has started running
Some checks are pending
CI / test (push) Has started running
This commit is contained in:
@@ -186,3 +186,12 @@
|
||||
### Step 29 - Core base / multi-select delete execution
|
||||
- Fixed multi-select delete behavior in `ChatViewModel`: `Delete` now applies to all selected messages, not only focused one.
|
||||
- Added explicit guard for `Delete for all` in multi-select mode (single-message only).
|
||||
|
||||
### Step 30 - Core base / reply-forward preview data foundation
|
||||
- Extended message DTO/Room/domain models with optional preview metadata:
|
||||
- `replyPreviewText`, `replyPreviewSenderName`
|
||||
- `forwardedFromDisplayName`
|
||||
- sender profile fields from API payload (`senderDisplayName`, `senderUsername`, `senderAvatarUrl`)
|
||||
- Added Room self-relation in `MessageLocalModel` to resolve reply preview fallback from referenced message.
|
||||
- Updated message mappers and repository/realtime temporary entity creation for new model fields.
|
||||
- Bumped Room schema version to `7`.
|
||||
|
||||
@@ -16,7 +16,7 @@ import ru.daemonlord.messenger.data.message.local.entity.MessageEntity
|
||||
MessageEntity::class,
|
||||
MessageAttachmentEntity::class,
|
||||
],
|
||||
version = 6,
|
||||
version = 7,
|
||||
exportSchema = false,
|
||||
)
|
||||
abstract class MessengerDatabase : RoomDatabase() {
|
||||
|
||||
@@ -10,10 +10,22 @@ data class MessageReadDto(
|
||||
val chatId: Long,
|
||||
@SerialName("sender_id")
|
||||
val senderId: Long,
|
||||
@SerialName("sender_display_name")
|
||||
val senderDisplayName: String? = null,
|
||||
@SerialName("sender_username")
|
||||
val senderUsername: String? = null,
|
||||
@SerialName("sender_avatar_url")
|
||||
val senderAvatarUrl: String? = null,
|
||||
@SerialName("reply_to_message_id")
|
||||
val replyToMessageId: Long? = null,
|
||||
@SerialName("reply_preview_text")
|
||||
val replyPreviewText: String? = null,
|
||||
@SerialName("reply_preview_sender_name")
|
||||
val replyPreviewSenderName: String? = null,
|
||||
@SerialName("forwarded_from_message_id")
|
||||
val forwardedFromMessageId: Long? = null,
|
||||
@SerialName("forwarded_from_display_name")
|
||||
val forwardedFromDisplayName: String? = null,
|
||||
val type: String,
|
||||
val text: String? = null,
|
||||
@SerialName("delivery_status")
|
||||
|
||||
@@ -29,8 +29,14 @@ data class MessageEntity(
|
||||
val senderAvatarUrl: String?,
|
||||
@ColumnInfo(name = "reply_to_message_id")
|
||||
val replyToMessageId: Long?,
|
||||
@ColumnInfo(name = "reply_preview_text")
|
||||
val replyPreviewText: String?,
|
||||
@ColumnInfo(name = "reply_preview_sender_name")
|
||||
val replyPreviewSenderName: String?,
|
||||
@ColumnInfo(name = "forwarded_from_message_id")
|
||||
val forwardedFromMessageId: Long?,
|
||||
@ColumnInfo(name = "forwarded_from_display_name")
|
||||
val forwardedFromDisplayName: String?,
|
||||
@ColumnInfo(name = "type")
|
||||
val type: String,
|
||||
@ColumnInfo(name = "text")
|
||||
|
||||
@@ -13,4 +13,9 @@ data class MessageLocalModel(
|
||||
entityColumn = "message_id",
|
||||
)
|
||||
val attachments: List<MessageAttachmentEntity>,
|
||||
@Relation(
|
||||
parentColumn = "reply_to_message_id",
|
||||
entityColumn = "id",
|
||||
)
|
||||
val replyToMessage: MessageEntity?,
|
||||
)
|
||||
|
||||
@@ -18,11 +18,14 @@ fun MessageReadDto.toEntity(): MessageEntity {
|
||||
id = id,
|
||||
chatId = chatId,
|
||||
senderId = senderId,
|
||||
senderDisplayName = null,
|
||||
senderUsername = null,
|
||||
senderAvatarUrl = null,
|
||||
senderDisplayName = senderDisplayName,
|
||||
senderUsername = senderUsername,
|
||||
senderAvatarUrl = senderAvatarUrl,
|
||||
replyToMessageId = replyToMessageId,
|
||||
replyPreviewText = replyPreviewText,
|
||||
replyPreviewSenderName = replyPreviewSenderName,
|
||||
forwardedFromMessageId = forwardedFromMessageId,
|
||||
forwardedFromDisplayName = forwardedFromDisplayName,
|
||||
type = type,
|
||||
text = text,
|
||||
status = deliveryStatus,
|
||||
@@ -33,6 +36,13 @@ fun MessageReadDto.toEntity(): MessageEntity {
|
||||
}
|
||||
|
||||
fun MessageLocalModel.toDomain(currentUserId: Long?): MessageItem {
|
||||
val resolvedReplyPreviewText = message.replyPreviewText
|
||||
?: replyToMessage?.text
|
||||
?: replyToMessage?.type?.let { "[$it]" }
|
||||
val resolvedReplyPreviewSenderName = message.replyPreviewSenderName
|
||||
?: replyToMessage?.senderDisplayName
|
||||
?: replyToMessage?.senderUsername?.takeIf { it.isNotBlank() }?.let { "@$it" }
|
||||
?: replyToMessage?.senderId?.let { "User #$it" }
|
||||
return MessageItem(
|
||||
id = message.id,
|
||||
chatId = message.chatId,
|
||||
@@ -45,7 +55,10 @@ fun MessageLocalModel.toDomain(currentUserId: Long?): MessageItem {
|
||||
isOutgoing = currentUserId != null && currentUserId == message.senderId,
|
||||
status = message.status,
|
||||
replyToMessageId = message.replyToMessageId,
|
||||
replyPreviewText = resolvedReplyPreviewText,
|
||||
replyPreviewSenderName = resolvedReplyPreviewSenderName,
|
||||
forwardedFromMessageId = message.forwardedFromMessageId,
|
||||
forwardedFromDisplayName = message.forwardedFromDisplayName,
|
||||
attachmentWaveform = message.attachmentWaveformJson.toWaveformOrNull(),
|
||||
attachments = attachments.map { it.toDomain() },
|
||||
)
|
||||
|
||||
@@ -122,7 +122,10 @@ class NetworkMessageRepository @Inject constructor(
|
||||
senderUsername = null,
|
||||
senderAvatarUrl = null,
|
||||
replyToMessageId = replyToMessageId,
|
||||
replyPreviewText = null,
|
||||
replyPreviewSenderName = null,
|
||||
forwardedFromMessageId = null,
|
||||
forwardedFromDisplayName = null,
|
||||
type = "text",
|
||||
text = text,
|
||||
status = "pending",
|
||||
@@ -208,7 +211,10 @@ class NetworkMessageRepository @Inject constructor(
|
||||
senderUsername = null,
|
||||
senderAvatarUrl = null,
|
||||
replyToMessageId = replyToMessageId,
|
||||
replyPreviewText = null,
|
||||
replyPreviewSenderName = null,
|
||||
forwardedFromMessageId = null,
|
||||
forwardedFromDisplayName = null,
|
||||
type = messageType,
|
||||
text = caption,
|
||||
status = "pending",
|
||||
|
||||
@@ -12,7 +12,10 @@ data class MessageItem(
|
||||
val isOutgoing: Boolean,
|
||||
val status: String?,
|
||||
val replyToMessageId: Long?,
|
||||
val replyPreviewText: String?,
|
||||
val replyPreviewSenderName: String?,
|
||||
val forwardedFromMessageId: Long?,
|
||||
val forwardedFromDisplayName: String?,
|
||||
val attachmentWaveform: List<Int>?,
|
||||
val attachments: List<MessageAttachment>,
|
||||
)
|
||||
|
||||
@@ -48,7 +48,10 @@ class HandleRealtimeEventsUseCase @Inject constructor(
|
||||
senderUsername = null,
|
||||
senderAvatarUrl = null,
|
||||
replyToMessageId = event.replyToMessageId,
|
||||
replyPreviewText = null,
|
||||
replyPreviewSenderName = null,
|
||||
forwardedFromMessageId = null,
|
||||
forwardedFromDisplayName = null,
|
||||
type = event.type ?: "text",
|
||||
text = event.text,
|
||||
status = null,
|
||||
|
||||
@@ -92,7 +92,10 @@ class MessageDaoTest {
|
||||
senderUsername = "user",
|
||||
senderAvatarUrl = null,
|
||||
replyToMessageId = null,
|
||||
replyPreviewText = null,
|
||||
replyPreviewSenderName = null,
|
||||
forwardedFromMessageId = null,
|
||||
forwardedFromDisplayName = null,
|
||||
type = "text",
|
||||
text = text,
|
||||
status = null,
|
||||
|
||||
@@ -66,7 +66,10 @@ class MessageActionStateTest {
|
||||
isOutgoing = true,
|
||||
status = "sent",
|
||||
replyToMessageId = null,
|
||||
replyPreviewText = null,
|
||||
replyPreviewSenderName = null,
|
||||
forwardedFromMessageId = null,
|
||||
forwardedFromDisplayName = null,
|
||||
attachmentWaveform = null,
|
||||
attachments = emptyList(),
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user