- read indicator, edit status and time for message in messages history
This commit is contained in:
@@ -38,6 +38,41 @@ data class VkConversation(
|
|||||||
fun isPinned(): Boolean = majorId > 0
|
fun isPinned(): Boolean = majorId > 0
|
||||||
fun isInUnread() = inRead - (lastMessageId ?: 0) < 0
|
fun isInUnread() = inRead - (lastMessageId ?: 0) < 0
|
||||||
fun isOutUnread() = outRead - (lastMessageId ?: 0) < 0
|
fun isOutUnread() = outRead - (lastMessageId ?: 0) < 0
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
val EMPTY: VkConversation = VkConversation(
|
||||||
|
id = -1,
|
||||||
|
localId = -1,
|
||||||
|
ownerId = null,
|
||||||
|
title = "...",
|
||||||
|
photo50 = null,
|
||||||
|
photo100 = null,
|
||||||
|
photo200 = null,
|
||||||
|
isCallInProgress = false,
|
||||||
|
isPhantom = false,
|
||||||
|
lastConversationMessageId = -1,
|
||||||
|
inReadCmId = -1,
|
||||||
|
outReadCmId = -1,
|
||||||
|
inRead = -1,
|
||||||
|
outRead = -1,
|
||||||
|
lastMessageId = null,
|
||||||
|
unreadCount = -1,
|
||||||
|
membersCount = null,
|
||||||
|
canChangePin = false,
|
||||||
|
canChangeInfo = false,
|
||||||
|
majorId = -1,
|
||||||
|
minorId = -1,
|
||||||
|
pinnedMessageId = null,
|
||||||
|
interactionType = -1,
|
||||||
|
interactionIds = emptyList(),
|
||||||
|
peerType = PeerType.USER,
|
||||||
|
lastMessage = null,
|
||||||
|
pinnedMessage = null,
|
||||||
|
user = null,
|
||||||
|
group = null
|
||||||
|
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun VkConversation.asEntity(): VkConversationEntity = VkConversationEntity(
|
fun VkConversation.asEntity(): VkConversationEntity = VkConversationEntity(
|
||||||
|
|||||||
@@ -38,11 +38,10 @@ data class VkMessage(
|
|||||||
|
|
||||||
fun isGroup() = fromId < 0
|
fun isGroup() = fromId < 0
|
||||||
|
|
||||||
fun isRead(conversation: VkConversation) =
|
fun isRead(conversation: VkConversation): Boolean = when {
|
||||||
if (isOut) {
|
id <= 0 -> false
|
||||||
conversation.outRead - id >= 0
|
isOut -> conversation.outRead - id >= 0
|
||||||
} else {
|
else -> conversation.inRead - id >= 0
|
||||||
conversation.inRead - id >= 0
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun hasAttachments(): Boolean = attachments.orEmpty().isNotEmpty()
|
fun hasAttachments(): Boolean = attachments.orEmpty().isNotEmpty()
|
||||||
|
|||||||
+66
-34
@@ -177,22 +177,22 @@ class MessagesHistoryViewModelImpl(
|
|||||||
|
|
||||||
val newMessage = message.asPresentation(
|
val newMessage = message.asPresentation(
|
||||||
resourceProvider = resourceProvider,
|
resourceProvider = resourceProvider,
|
||||||
showDate = false,
|
|
||||||
showName = false,
|
showName = false,
|
||||||
prevMessage = prevMessage,
|
prevMessage = prevMessage,
|
||||||
nextMessage = null,
|
nextMessage = null,
|
||||||
showTimeInActionMessages = userSettings.showTimeInActionMessages.value
|
showTimeInActionMessages = userSettings.showTimeInActionMessages.value,
|
||||||
|
conversation = screenState.value.conversation,
|
||||||
)
|
)
|
||||||
newMessages.add(0, newMessage)
|
newMessages.add(0, newMessage)
|
||||||
|
|
||||||
prevMessage?.let { prev ->
|
prevMessage?.let { prev ->
|
||||||
newMessages[1] = prev.asPresentation(
|
newMessages[1] = prev.asPresentation(
|
||||||
resourceProvider = resourceProvider,
|
resourceProvider = resourceProvider,
|
||||||
showDate = false,
|
|
||||||
showName = false,
|
showName = false,
|
||||||
prevMessage = prevMessage,
|
prevMessage = prevMessage,
|
||||||
nextMessage = messages.value.first(),
|
nextMessage = messages.value.first(),
|
||||||
showTimeInActionMessages = userSettings.showTimeInActionMessages.value
|
showTimeInActionMessages = userSettings.showTimeInActionMessages.value,
|
||||||
|
conversation = screenState.value.conversation
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -208,11 +208,11 @@ class MessagesHistoryViewModelImpl(
|
|||||||
?.let { index ->
|
?.let { index ->
|
||||||
val newMessage = message.asPresentation(
|
val newMessage = message.asPresentation(
|
||||||
resourceProvider = resourceProvider,
|
resourceProvider = resourceProvider,
|
||||||
showDate = false,
|
|
||||||
showName = false,
|
showName = false,
|
||||||
prevMessage = messages.value.getOrNull(index + 1),
|
prevMessage = messages.value.getOrNull(index + 1),
|
||||||
nextMessage = messages.value.getOrNull(index - 1),
|
nextMessage = messages.value.getOrNull(index - 1),
|
||||||
showTimeInActionMessages = userSettings.showTimeInActionMessages.value
|
showTimeInActionMessages = userSettings.showTimeInActionMessages.value,
|
||||||
|
conversation = screenState.value.conversation
|
||||||
)
|
)
|
||||||
|
|
||||||
val newMessages = screenState.value.messages.toMutableList()
|
val newMessages = screenState.value.messages.toMutableList()
|
||||||
@@ -227,7 +227,37 @@ class MessagesHistoryViewModelImpl(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun handleReadOutgoingEvent(event: LongPollEvent.VkMessageReadOutgoingEvent) {
|
private fun handleReadOutgoingEvent(event: LongPollEvent.VkMessageReadOutgoingEvent) {
|
||||||
|
if (event.peerId != screenState.value.conversationId) return
|
||||||
|
|
||||||
|
val messages = messages.value
|
||||||
|
val messageIndex =
|
||||||
|
messages.indexOfFirstOrNull { it.id == event.messageId }
|
||||||
|
|
||||||
|
if (messageIndex == null) { // диалога нет в списке
|
||||||
|
// pizdets
|
||||||
|
} else {
|
||||||
|
val newConversation = screenState.value.conversation.copy(
|
||||||
|
outRead = event.messageId
|
||||||
|
)
|
||||||
|
|
||||||
|
val uiMessages = messages.mapIndexed { index, item ->
|
||||||
|
item.asPresentation(
|
||||||
|
resourceProvider = resourceProvider,
|
||||||
|
showName = false,
|
||||||
|
prevMessage = messages.getOrNull(index + 1),
|
||||||
|
nextMessage = messages.getOrNull(index - 1),
|
||||||
|
showTimeInActionMessages = userSettings.showTimeInActionMessages.value,
|
||||||
|
conversation = newConversation
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
screenState.setValue { old ->
|
||||||
|
old.copy(
|
||||||
|
conversation = newConversation,
|
||||||
|
messages = uiMessages,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun loadMessagesHistory(offset: Int = currentOffset.value) {
|
private fun loadMessagesHistory(offset: Int = currentOffset.value) {
|
||||||
@@ -239,9 +269,7 @@ class MessagesHistoryViewModelImpl(
|
|||||||
offset = offset,
|
offset = offset,
|
||||||
).listenValue(viewModelScope) { state ->
|
).listenValue(viewModelScope) { state ->
|
||||||
state.processState(
|
state.processState(
|
||||||
error = { error ->
|
error = { error -> },
|
||||||
|
|
||||||
},
|
|
||||||
success = { response ->
|
success = { response ->
|
||||||
val messages = response.messages
|
val messages = response.messages
|
||||||
val fullMessages = if (offset == 0) {
|
val fullMessages = if (offset == 0) {
|
||||||
@@ -259,16 +287,6 @@ class MessagesHistoryViewModelImpl(
|
|||||||
messagesUseCase.storeMessages(messages)
|
messagesUseCase.storeMessages(messages)
|
||||||
conversationsUseCase.storeConversations(conversations)
|
conversationsUseCase.storeConversations(conversations)
|
||||||
|
|
||||||
val loadedMessages = fullMessages.mapIndexed { index, message ->
|
|
||||||
message.asPresentation(
|
|
||||||
resourceProvider = resourceProvider,
|
|
||||||
showDate = false,
|
|
||||||
showName = false,
|
|
||||||
prevMessage = messages.getOrNull(index + 1),
|
|
||||||
nextMessage = messages.getOrNull(index - 1),
|
|
||||||
showTimeInActionMessages = userSettings.showTimeInActionMessages.value
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
val itemsCountSufficient = messages.size == MESSAGES_LOAD_COUNT
|
val itemsCountSufficient = messages.size == MESSAGES_LOAD_COUNT
|
||||||
|
|
||||||
@@ -281,12 +299,25 @@ class MessagesHistoryViewModelImpl(
|
|||||||
conversations
|
conversations
|
||||||
.firstOrNull { it.id == screenState.value.conversationId }
|
.firstOrNull { it.id == screenState.value.conversationId }
|
||||||
?.let { conversation ->
|
?.let { conversation ->
|
||||||
|
screenState.setValue { old -> old.copy(conversation = conversation) }
|
||||||
newState = newState.copy(
|
newState = newState.copy(
|
||||||
title = conversation.extractTitle(
|
title = conversation.extractTitle(
|
||||||
useContactName = AppSettings.General.useContactNames,
|
useContactName = AppSettings.General.useContactNames,
|
||||||
resources = resourceProvider.resources
|
resources = resourceProvider.resources
|
||||||
),
|
),
|
||||||
avatar = conversation.extractAvatar()
|
avatar = conversation.extractAvatar(),
|
||||||
|
conversation = conversation
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
val loadedMessages = fullMessages.mapIndexed { index, message ->
|
||||||
|
message.asPresentation(
|
||||||
|
resourceProvider = resourceProvider,
|
||||||
|
showName = false,
|
||||||
|
prevMessage = messages.getOrNull(index + 1),
|
||||||
|
nextMessage = messages.getOrNull(index - 1),
|
||||||
|
showTimeInActionMessages = userSettings.showTimeInActionMessages.value,
|
||||||
|
conversation = screenState.value.conversation
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -350,18 +381,14 @@ class MessagesHistoryViewModelImpl(
|
|||||||
val newMessages = screenState.value.messages.toMutableList()
|
val newMessages = screenState.value.messages.toMutableList()
|
||||||
val newUiMessage = newMessage.asPresentation(
|
val newUiMessage = newMessage.asPresentation(
|
||||||
resourceProvider = resourceProvider,
|
resourceProvider = resourceProvider,
|
||||||
showDate = false,
|
|
||||||
showName = false,
|
showName = false,
|
||||||
prevMessage = messages.value.firstOrNull(),
|
prevMessage = messages.value.firstOrNull(),
|
||||||
nextMessage = null,
|
nextMessage = null,
|
||||||
showTimeInActionMessages = userSettings.showTimeInActionMessages.value
|
showTimeInActionMessages = userSettings.showTimeInActionMessages.value,
|
||||||
|
conversation = screenState.value.conversation
|
||||||
)
|
)
|
||||||
newMessages.add(0, newUiMessage)
|
newMessages.add(0, newUiMessage)
|
||||||
|
|
||||||
messages.setValue { old ->
|
|
||||||
listOf(newMessage).plus(old)
|
|
||||||
}
|
|
||||||
|
|
||||||
screenState.setValue { old ->
|
screenState.setValue { old ->
|
||||||
old.copy(
|
old.copy(
|
||||||
message = TextFieldValue(),
|
message = TextFieldValue(),
|
||||||
@@ -382,17 +409,22 @@ class MessagesHistoryViewModelImpl(
|
|||||||
sendingMessages -= newMessage
|
sendingMessages -= newMessage
|
||||||
},
|
},
|
||||||
success = { messageId ->
|
success = { messageId ->
|
||||||
sendingMessages += newMessage
|
sendingMessages -= newMessage
|
||||||
|
|
||||||
val messages = screenState.value.messages.toMutableList()
|
val uiMessages = screenState.value.messages.toMutableList()
|
||||||
|
messages.setValue { old ->
|
||||||
|
listOf(newMessage.copy(id = messageId)).plus(old)
|
||||||
|
}
|
||||||
|
|
||||||
messages.indexOfOrNull(newUiMessage)?.let { index ->
|
uiMessages.indexOfOrNull(newUiMessage)?.let { index ->
|
||||||
(messages[index] as? UiItem.Message)?.let { message ->
|
(uiMessages[index] as? UiItem.Message)?.let { message ->
|
||||||
messages[index] = message.copy(id = messageId)
|
uiMessages[index] = message
|
||||||
|
.copy(id = messageId)
|
||||||
|
.copy(isRead = newMessage.isRead(screenState.value.conversation))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
screenState.setValue { old -> old.copy(messages = messages) }
|
screenState.setValue { old -> old.copy(messages = uiMessages) }
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -511,11 +543,11 @@ class MessagesHistoryViewModelImpl(
|
|||||||
val uiMessages = messages.mapIndexed { index, item ->
|
val uiMessages = messages.mapIndexed { index, item ->
|
||||||
item.asPresentation(
|
item.asPresentation(
|
||||||
resourceProvider = resourceProvider,
|
resourceProvider = resourceProvider,
|
||||||
showDate = false,
|
|
||||||
showName = false,
|
showName = false,
|
||||||
prevMessage = messages.getOrNull(index + 1),
|
prevMessage = messages.getOrNull(index + 1),
|
||||||
nextMessage = messages.getOrNull(index - 1),
|
nextMessage = messages.getOrNull(index - 1),
|
||||||
showTimeInActionMessages = show
|
showTimeInActionMessages = show,
|
||||||
|
conversation = screenState.value.conversation
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+5
-2
@@ -4,6 +4,7 @@ import androidx.compose.runtime.Immutable
|
|||||||
import androidx.compose.ui.text.input.TextFieldValue
|
import androidx.compose.ui.text.input.TextFieldValue
|
||||||
import dev.meloda.fast.common.model.UiImage
|
import dev.meloda.fast.common.model.UiImage
|
||||||
import dev.meloda.fast.model.api.domain.VkAttachment
|
import dev.meloda.fast.model.api.domain.VkAttachment
|
||||||
|
import dev.meloda.fast.model.api.domain.VkConversation
|
||||||
|
|
||||||
@Immutable
|
@Immutable
|
||||||
data class MessagesHistoryScreenState(
|
data class MessagesHistoryScreenState(
|
||||||
@@ -18,7 +19,8 @@ data class MessagesHistoryScreenState(
|
|||||||
val isPaginating: Boolean,
|
val isPaginating: Boolean,
|
||||||
val isPaginationExhausted: Boolean,
|
val isPaginationExhausted: Boolean,
|
||||||
val actionMode: ActionMode,
|
val actionMode: ActionMode,
|
||||||
val chatImageUrl: String?
|
val chatImageUrl: String?,
|
||||||
|
val conversation: VkConversation
|
||||||
) {
|
) {
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
@@ -34,7 +36,8 @@ data class MessagesHistoryScreenState(
|
|||||||
isPaginating = false,
|
isPaginating = false,
|
||||||
isPaginationExhausted = false,
|
isPaginationExhausted = false,
|
||||||
actionMode = ActionMode.Record,
|
actionMode = ActionMode.Record,
|
||||||
chatImageUrl = null
|
chatImageUrl = null,
|
||||||
|
conversation = VkConversation.EMPTY
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-2
@@ -22,7 +22,8 @@ sealed class UiItem(
|
|||||||
val showAvatar: Boolean,
|
val showAvatar: Boolean,
|
||||||
val showName: Boolean,
|
val showName: Boolean,
|
||||||
val avatar: UiImage,
|
val avatar: UiImage,
|
||||||
val isEdited: Boolean
|
val isEdited: Boolean,
|
||||||
|
val isRead: Boolean
|
||||||
) : UiItem(id, conversationMessageId)
|
) : UiItem(id, conversationMessageId)
|
||||||
|
|
||||||
data class ActionMessage(
|
data class ActionMessage(
|
||||||
@@ -32,4 +33,3 @@ sealed class UiItem(
|
|||||||
val actionCmId: Int?
|
val actionCmId: Int?
|
||||||
) : UiItem(id, conversationMessageId)
|
) : UiItem(id, conversationMessageId)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+3
@@ -31,6 +31,7 @@ import dev.meloda.fast.messageshistory.model.UiItem
|
|||||||
fun IncomingMessageBubble(
|
fun IncomingMessageBubble(
|
||||||
modifier: Modifier = Modifier,
|
modifier: Modifier = Modifier,
|
||||||
message: UiItem.Message,
|
message: UiItem.Message,
|
||||||
|
animate: Boolean
|
||||||
) {
|
) {
|
||||||
val context = LocalContext.current
|
val context = LocalContext.current
|
||||||
|
|
||||||
@@ -80,6 +81,8 @@ fun IncomingMessageBubble(
|
|||||||
isOut = false,
|
isOut = false,
|
||||||
date = message.date,
|
date = message.date,
|
||||||
edited = message.isEdited,
|
edited = message.isEdited,
|
||||||
|
animate = animate,
|
||||||
|
isRead = message.isRead
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+60
-28
@@ -1,19 +1,32 @@
|
|||||||
package dev.meloda.fast.messageshistory.presentation
|
package dev.meloda.fast.messageshistory.presentation
|
||||||
|
|
||||||
import androidx.compose.animation.animateContentSize
|
import androidx.compose.animation.animateContentSize
|
||||||
|
import androidx.compose.animation.core.animateDpAsState
|
||||||
import androidx.compose.foundation.background
|
import androidx.compose.foundation.background
|
||||||
import androidx.compose.foundation.layout.Box
|
import androidx.compose.foundation.layout.Box
|
||||||
|
import androidx.compose.foundation.layout.Row
|
||||||
|
import androidx.compose.foundation.layout.Spacer
|
||||||
|
import androidx.compose.foundation.layout.defaultMinSize
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
|
import androidx.compose.foundation.layout.size
|
||||||
|
import androidx.compose.foundation.layout.width
|
||||||
import androidx.compose.foundation.layout.widthIn
|
import androidx.compose.foundation.layout.widthIn
|
||||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||||
|
import androidx.compose.material.icons.Icons
|
||||||
|
import androidx.compose.material.icons.rounded.Create
|
||||||
|
import androidx.compose.material3.Icon
|
||||||
import androidx.compose.material3.MaterialTheme
|
import androidx.compose.material3.MaterialTheme
|
||||||
import androidx.compose.material3.Text
|
import androidx.compose.material3.Text
|
||||||
import androidx.compose.material3.surfaceColorAtElevation
|
import androidx.compose.material3.surfaceColorAtElevation
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.runtime.getValue
|
||||||
|
import androidx.compose.runtime.remember
|
||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.draw.clip
|
import androidx.compose.ui.draw.clip
|
||||||
|
import androidx.compose.ui.res.painterResource
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
|
import dev.meloda.fast.ui.R as UiR
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun MessageBubble(
|
fun MessageBubble(
|
||||||
@@ -22,6 +35,8 @@ fun MessageBubble(
|
|||||||
isOut: Boolean,
|
isOut: Boolean,
|
||||||
date: String?,
|
date: String?,
|
||||||
edited: Boolean,
|
edited: Boolean,
|
||||||
|
animate: Boolean,
|
||||||
|
isRead: Boolean
|
||||||
) {
|
) {
|
||||||
val backgroundColor = if (!isOut) {
|
val backgroundColor = if (!isOut) {
|
||||||
MaterialTheme.colorScheme.surfaceColorAtElevation(2.dp)
|
MaterialTheme.colorScheme.surfaceColorAtElevation(2.dp)
|
||||||
@@ -45,44 +60,61 @@ fun MessageBubble(
|
|||||||
vertical = 6.dp
|
vertical = 6.dp
|
||||||
)
|
)
|
||||||
) {
|
) {
|
||||||
|
val minDateContainerWidth = remember(edited, isOut) {
|
||||||
|
val mainPart = if (edited) 50.dp else 30.dp
|
||||||
|
val readIndicatorPart = if (isOut) 14.dp else 0.dp
|
||||||
|
|
||||||
|
mainPart + readIndicatorPart
|
||||||
|
}
|
||||||
|
|
||||||
|
val dateContainerWidth by animateDpAsState(
|
||||||
|
targetValue = minDateContainerWidth,
|
||||||
|
label = "dateContainerWidth"
|
||||||
|
)
|
||||||
|
|
||||||
if (text != null) {
|
if (text != null) {
|
||||||
Text(
|
Text(
|
||||||
text = text,
|
text = text,
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.padding(2.dp)
|
.padding(2.dp)
|
||||||
.align(Alignment.Center)
|
.align(Alignment.Center)
|
||||||
.animateContentSize(),
|
.padding(end = 4.dp)
|
||||||
|
.padding(end = dateContainerWidth)
|
||||||
|
.padding(end = 4.dp)
|
||||||
|
.then(if (animate) Modifier.animateContentSize() else Modifier),
|
||||||
color = textColor
|
color = textColor
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Row(
|
||||||
|
modifier = Modifier
|
||||||
|
.align(Alignment.BottomEnd)
|
||||||
|
.defaultMinSize(minWidth = dateContainerWidth)
|
||||||
|
) {
|
||||||
|
if (edited) {
|
||||||
|
Icon(
|
||||||
|
imageVector = Icons.Rounded.Create,
|
||||||
|
contentDescription = null,
|
||||||
|
modifier = Modifier.size(14.dp)
|
||||||
|
)
|
||||||
|
Spacer(modifier = Modifier.width(4.dp))
|
||||||
|
}
|
||||||
|
Text(
|
||||||
|
text = date.orEmpty(),
|
||||||
|
style = MaterialTheme.typography.labelSmall,
|
||||||
|
)
|
||||||
|
Spacer(modifier = Modifier.width(4.dp))
|
||||||
|
|
||||||
// val dateContainerWidth by animateDpAsState(
|
if (isOut) {
|
||||||
// targetValue = if (edited) 50.dp else 30.dp,
|
Icon(
|
||||||
// label = "dateContainerWidth"
|
modifier = Modifier.size(14.dp),
|
||||||
// )
|
painter = painterResource(
|
||||||
|
if (isRead) UiR.drawable.round_done_all_24
|
||||||
// AnimatedVisibility(
|
else UiR.drawable.ic_round_done_24
|
||||||
// date != null,
|
),
|
||||||
// modifier = Modifier
|
contentDescription = null
|
||||||
// .width(dateContainerWidth)
|
)
|
||||||
// .align(Alignment.BottomEnd)
|
}
|
||||||
// ) {
|
}
|
||||||
// Row(modifier = Modifier.fillMaxWidth()) {
|
|
||||||
// if (edited) {
|
|
||||||
// Icon(
|
|
||||||
// imageVector = Icons.Rounded.Create,
|
|
||||||
// contentDescription = null,
|
|
||||||
// modifier = Modifier.size(14.dp)
|
|
||||||
// )
|
|
||||||
// Spacer(modifier = Modifier.width(4.dp))
|
|
||||||
// }
|
|
||||||
// Text(
|
|
||||||
// text = date.orEmpty(),
|
|
||||||
// style = MaterialTheme.typography.labelSmall
|
|
||||||
// )
|
|
||||||
// Spacer(modifier = Modifier.width(2.dp))
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+2
@@ -98,6 +98,7 @@ fun MessagesList(
|
|||||||
else Modifier
|
else Modifier
|
||||||
),
|
),
|
||||||
message = item,
|
message = item,
|
||||||
|
animate = enableAnimations
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
IncomingMessageBubble(
|
IncomingMessageBubble(
|
||||||
@@ -110,6 +111,7 @@ fun MessagesList(
|
|||||||
else Modifier
|
else Modifier
|
||||||
),
|
),
|
||||||
message = item,
|
message = item,
|
||||||
|
animate = enableAnimations
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+4
-14
@@ -3,12 +3,8 @@ package dev.meloda.fast.messageshistory.presentation
|
|||||||
import androidx.compose.foundation.layout.Arrangement
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Column
|
||||||
import androidx.compose.foundation.layout.Row
|
import androidx.compose.foundation.layout.Row
|
||||||
import androidx.compose.foundation.layout.Spacer
|
|
||||||
import androidx.compose.foundation.layout.fillMaxWidth
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
import androidx.compose.foundation.layout.height
|
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.material3.MaterialTheme
|
|
||||||
import androidx.compose.material3.Text
|
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
@@ -20,6 +16,7 @@ import dev.meloda.fast.messageshistory.model.UiItem
|
|||||||
fun OutgoingMessageBubble(
|
fun OutgoingMessageBubble(
|
||||||
modifier: Modifier = Modifier,
|
modifier: Modifier = Modifier,
|
||||||
message: UiItem.Message,
|
message: UiItem.Message,
|
||||||
|
animate: Boolean
|
||||||
) {
|
) {
|
||||||
Row(
|
Row(
|
||||||
modifier = modifier.fillMaxWidth(),
|
modifier = modifier.fillMaxWidth(),
|
||||||
@@ -37,18 +34,11 @@ fun OutgoingMessageBubble(
|
|||||||
modifier = Modifier,
|
modifier = Modifier,
|
||||||
text = message.text.orDots(),
|
text = message.text.orDots(),
|
||||||
isOut = true,
|
isOut = true,
|
||||||
date = null,
|
date = message.date,
|
||||||
edited = message.isEdited,
|
edited = message.isEdited,
|
||||||
)
|
animate = animate,
|
||||||
|
isRead = message.isRead
|
||||||
if (message.showDate) {
|
|
||||||
Spacer(modifier = Modifier.height(2.dp))
|
|
||||||
Text(
|
|
||||||
modifier = Modifier.padding(end = 12.dp),
|
|
||||||
text = message.date,
|
|
||||||
style = MaterialTheme.typography.labelSmall
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|||||||
+4
-3
@@ -90,8 +90,8 @@ fun VkConversation.extractTitle(
|
|||||||
}.parseString(resources).orDots()
|
}.parseString(resources).orDots()
|
||||||
|
|
||||||
fun VkMessage.asPresentation(
|
fun VkMessage.asPresentation(
|
||||||
|
conversation: VkConversation,
|
||||||
resourceProvider: ResourceProvider,
|
resourceProvider: ResourceProvider,
|
||||||
showDate: Boolean,
|
|
||||||
showName: Boolean,
|
showName: Boolean,
|
||||||
prevMessage: VkMessage?,
|
prevMessage: VkMessage?,
|
||||||
nextMessage: VkMessage?,
|
nextMessage: VkMessage?,
|
||||||
@@ -118,11 +118,12 @@ fun VkMessage.asPresentation(
|
|||||||
randomId = randomId,
|
randomId = randomId,
|
||||||
isInChat = isPeerChat(),
|
isInChat = isPeerChat(),
|
||||||
name = extractTitle(),
|
name = extractTitle(),
|
||||||
showDate = showDate,
|
showDate = true,
|
||||||
showAvatar = extractShowAvatar(nextMessage),
|
showAvatar = extractShowAvatar(nextMessage),
|
||||||
showName = showName && extractShowName(prevMessage),
|
showName = showName && extractShowName(prevMessage),
|
||||||
avatar = extractAvatar(),
|
avatar = extractAvatar(),
|
||||||
isEdited = updateTime != null
|
isEdited = updateTime != null,
|
||||||
|
isRead = isRead(conversation)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user