[Chat] user added/removed messages from service events (#542)
This commit is contained in:
Родитель
2b23425126
Коммит
2ece7bd9f8
|
@ -15,6 +15,7 @@ internal data class MessageInfoModel(
|
|||
val internalId: String? = null,
|
||||
val messageType: ChatMessageType?,
|
||||
val content: String?,
|
||||
val topic: String? = null,
|
||||
val participants: List<String> = emptyList(),
|
||||
val version: String? = null,
|
||||
val senderDisplayName: String? = null,
|
||||
|
@ -30,6 +31,7 @@ internal fun com.azure.android.communication.chat.models.ChatMessage.into(): Mes
|
|||
id = this.id,
|
||||
messageType = this.type.into(),
|
||||
content = this.content.message,
|
||||
topic = this.content.topic,
|
||||
participants = this.content.participants?.map { it.displayName }?.toList() ?: emptyList(),
|
||||
internalId = null,
|
||||
version = this.version,
|
||||
|
|
|
@ -15,9 +15,9 @@ internal data class ChatCompositeColors(
|
|||
val textColor: Color = Color(0xFF212121),
|
||||
val outlineColor: Color = Color(0xFFE1E1E1),
|
||||
val messageBackground: Color = Color(0xFFF1F1F1),
|
||||
val systemIconColor: Color = Color(0xFF919191),
|
||||
val messageBackgroundSelf: Color = Color(0xFFDEECF9),
|
||||
)
|
||||
|
||||
internal val ChatCompositeColorPalette = staticCompositionLocalOf {
|
||||
ChatCompositeColors()
|
||||
}
|
||||
|
|
|
@ -17,6 +17,7 @@ internal data class ChatCompositeDimensions(
|
|||
val messageAvatarSize: Dp = 24.dp,
|
||||
val messageUsernamePaddingEnd: Dp = 8.dp,
|
||||
val messagePadding: PaddingValues = PaddingValues(start = 10.dp, end = 10.dp, top = 8.dp, bottom = 8.dp),
|
||||
val systemMessagePadding: PaddingValues = PaddingValues(start = 20.dp, end = 5.dp, top = 10.dp, bottom = 10.dp),
|
||||
val typingIndicatorAreaHeight: Dp = 36.dp,
|
||||
val dateHeaderPadding: PaddingValues = PaddingValues(start = 0.dp, end = 0.dp, top = 16.dp, bottom = 0.dp)
|
||||
)
|
||||
|
|
|
@ -15,14 +15,17 @@ import androidx.compose.foundation.layout.PaddingValues
|
|||
import androidx.compose.foundation.layout.width
|
||||
|
||||
import androidx.compose.foundation.text.BasicText
|
||||
import androidx.compose.material.Icon
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.res.painterResource
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.viewinterop.AndroidView
|
||||
import androidx.core.text.HtmlCompat
|
||||
import com.azure.android.communication.ui.chat.R
|
||||
import com.azure.android.communication.ui.chat.presentation.style.ChatCompositeTheme
|
||||
import com.azure.android.communication.ui.chat.presentation.ui.viewmodel.MessageViewModel
|
||||
import com.azure.android.communication.ui.chat.presentation.ui.viewmodel.toViewModelList
|
||||
|
@ -54,16 +57,27 @@ internal fun MessageView(viewModel: MessageViewModel) {
|
|||
)
|
||||
}
|
||||
}
|
||||
|
||||
when (viewModel.message.messageType) {
|
||||
ChatMessageType.TEXT -> BasicChatMessage(viewModel)
|
||||
ChatMessageType.HTML -> BasicChatMessage(viewModel)
|
||||
ChatMessageType.TOPIC_UPDATED -> BasicText("Topic Updated")
|
||||
ChatMessageType.PARTICIPANT_ADDED -> UserJoinedMessage(viewModel)
|
||||
ChatMessageType.PARTICIPANT_REMOVED -> UserLeftMessage(viewModel)
|
||||
ChatMessageType.TOPIC_UPDATED -> SystemMessage(
|
||||
icon = R.drawable.azure_communication_ui_chat_ic_participant_removed_filled, /* TODO: update icon */
|
||||
stringResource = R.string.azure_communication_ui_chat_topic_updated,
|
||||
substitution = listOf(viewModel.message.topic ?: "Unknown")
|
||||
)
|
||||
ChatMessageType.PARTICIPANT_ADDED -> SystemMessage(
|
||||
icon = R.drawable.azure_communication_ui_chat_ic_participant_added_filled,
|
||||
stringResource = R.string.azure_communication_ui_chat_joined_chat,
|
||||
substitution = viewModel.message.participants
|
||||
)
|
||||
ChatMessageType.PARTICIPANT_REMOVED -> SystemMessage(
|
||||
icon = R.drawable.azure_communication_ui_chat_ic_participant_removed_filled,
|
||||
stringResource = R.string.azure_communication_ui_chat_left_chat,
|
||||
substitution = viewModel.message.participants
|
||||
)
|
||||
else -> {
|
||||
BasicText(
|
||||
text = "${viewModel.message.content} !TYPE NOT DETECTED!"
|
||||
text = "${viewModel.message.content} !TYPE NOT DETECTED!" ?: "Empty"
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -71,32 +85,19 @@ internal fun MessageView(viewModel: MessageViewModel) {
|
|||
}
|
||||
|
||||
@Composable
|
||||
private fun UserJoinedMessage(viewModel: MessageViewModel) {
|
||||
if (viewModel.message.participants.size <= 1) {
|
||||
BasicText(
|
||||
"${viewModel.message.participants.firstOrNull() ?: "Unknown"} joined the chat",
|
||||
style = ChatCompositeTheme.typography.systemMessage
|
||||
)
|
||||
} else {
|
||||
BasicText(
|
||||
"${viewModel.message.participants.joinToString(", ")} joined the chat",
|
||||
style = ChatCompositeTheme.typography.systemMessage
|
||||
)
|
||||
}
|
||||
}
|
||||
private fun SystemMessage(icon: Int, stringResource: Int, substitution: List<String>) {
|
||||
|
||||
@Composable
|
||||
private fun UserLeftMessage(viewModel: MessageViewModel) {
|
||||
if (viewModel.message.participants.size <= 1) {
|
||||
BasicText(
|
||||
"${viewModel.message.participants.firstOrNull() ?: "Unknown"} left the chat",
|
||||
style = ChatCompositeTheme.typography.systemMessage
|
||||
)
|
||||
} else {
|
||||
BasicText(
|
||||
"${viewModel.message.participants.joinToString(", ")} left the chat",
|
||||
style = ChatCompositeTheme.typography.systemMessage
|
||||
val text = LocalContext.current.getString(stringResource, substitution.joinToString(", "))
|
||||
Row(verticalAlignment = Alignment.CenterVertically) {
|
||||
Icon(
|
||||
painter = painterResource(id = icon),
|
||||
contentDescription = "Participant Added",
|
||||
modifier = Modifier.padding(
|
||||
ChatCompositeTheme.dimensions.systemMessagePadding
|
||||
),
|
||||
tint = ChatCompositeTheme.colors.systemIconColor
|
||||
)
|
||||
BasicText(text = text, style = ChatCompositeTheme.typography.systemMessage)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -3,16 +3,20 @@
|
|||
|
||||
package com.azure.android.communication.ui.chat.redux.middleware.repository
|
||||
|
||||
import com.azure.android.communication.ui.chat.models.MessageInfoModel
|
||||
import com.azure.android.communication.ui.chat.redux.Dispatch
|
||||
import com.azure.android.communication.ui.chat.redux.Middleware
|
||||
import com.azure.android.communication.ui.chat.redux.Store
|
||||
import com.azure.android.communication.ui.chat.redux.action.Action
|
||||
import com.azure.android.communication.ui.chat.redux.action.ChatAction
|
||||
import com.azure.android.communication.ui.chat.redux.action.NetworkAction
|
||||
import com.azure.android.communication.ui.chat.redux.action.ParticipantAction
|
||||
import com.azure.android.communication.ui.chat.redux.action.RepositoryAction
|
||||
import com.azure.android.communication.ui.chat.redux.middleware.sdk.ChatMiddleware
|
||||
import com.azure.android.communication.ui.chat.redux.state.ReduxState
|
||||
import com.azure.android.communication.ui.chat.repository.MessageRepositoryWriter
|
||||
import com.azure.android.communication.ui.chat.service.sdk.wrapper.ChatMessageType
|
||||
import org.threeten.bp.OffsetDateTime
|
||||
|
||||
internal interface MessageRepositoryMiddleware
|
||||
|
||||
|
@ -36,6 +40,8 @@ internal class MessageRepositoryMiddlewareImpl(
|
|||
is ChatAction.MessageReceived -> processNewMessage(action, store::dispatch)
|
||||
is ChatAction.MessageDeleted -> processDeletedMessage(action, store::dispatch)
|
||||
is ChatAction.MessageEdited -> processEditMessage(action, store::dispatch)
|
||||
is ParticipantAction.ParticipantsAdded -> processParticipantsAdded(action, store::dispatch)
|
||||
is ParticipantAction.ParticipantsRemoved -> processParticipantsRemoved(action, store::dispatch)
|
||||
is NetworkAction.Disconnected -> processNetworkDisconnected(store::dispatch)
|
||||
}
|
||||
|
||||
|
@ -72,6 +78,42 @@ internal class MessageRepositoryMiddlewareImpl(
|
|||
notifyUpdate(dispatch)
|
||||
}
|
||||
|
||||
var skipFirstParticipantsAddedMessage = true
|
||||
// Fake a message for Participant Added
|
||||
private fun processParticipantsAdded(action: ParticipantAction.ParticipantsAdded, dispatch: Dispatch) {
|
||||
// This comes through at start, but we don't want to pass it through
|
||||
// since it's also in the historical messages
|
||||
if (skipFirstParticipantsAddedMessage) {
|
||||
skipFirstParticipantsAddedMessage = false
|
||||
return
|
||||
}
|
||||
messageRepository.addLocalMessage(
|
||||
MessageInfoModel(
|
||||
id = "${messageRepository.getLastMessage()?.id?.toLong() ?: 0 + 1}",
|
||||
participants = action.participants.map { it.displayName ?: "" },
|
||||
content = null,
|
||||
createdOn = OffsetDateTime.now(),
|
||||
senderDisplayName = null,
|
||||
messageType = ChatMessageType.PARTICIPANT_ADDED
|
||||
)
|
||||
)
|
||||
notifyUpdate(dispatch)
|
||||
}
|
||||
|
||||
private fun processParticipantsRemoved(action: ParticipantAction.ParticipantsRemoved, dispatch: Dispatch) {
|
||||
messageRepository.addLocalMessage(
|
||||
MessageInfoModel(
|
||||
id = "${messageRepository.getLastMessage()?.id?.toLong() ?: 0 + 1}",
|
||||
participants = action.participants.map { it.displayName ?: "" },
|
||||
content = null,
|
||||
createdOn = OffsetDateTime.now(),
|
||||
senderDisplayName = null,
|
||||
messageType = ChatMessageType.PARTICIPANT_REMOVED
|
||||
)
|
||||
)
|
||||
notifyUpdate(dispatch)
|
||||
}
|
||||
|
||||
private fun processDeletedMessage(action: ChatAction.MessageDeleted, dispatch: Dispatch) {
|
||||
messageRepository.removeMessage(action.message)
|
||||
notifyUpdate(dispatch)
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="13dp"
|
||||
android:height="14dp"
|
||||
android:viewportWidth="13"
|
||||
android:viewportHeight="14">
|
||||
<path
|
||||
android:pathData="M4.222,12.957C1.555,12.653 0,10.803 0,9L0,8.5C0,7.672 0.672,7 1.5,7H3.6C3.438,7.317 3.306,7.651 3.207,8H1.5C1.224,8 1,8.224 1,8.5V9C1,10.128 1.882,11.333 3.502,11.8C3.694,12.216 3.937,12.604 4.222,12.957ZM7.626,4.069C7.707,3.81 7.75,3.535 7.75,3.25C7.75,1.731 6.519,0.5 5,0.5C3.481,0.5 2.25,1.731 2.25,3.25C2.25,4.537 3.134,5.617 4.327,5.917C4.642,5.551 5.004,5.226 5.405,4.953C5.275,4.984 5.139,5 5,5C4.034,5 3.25,4.216 3.25,3.25C3.25,2.283 4.034,1.5 5,1.5C5.966,1.5 6.75,2.283 6.75,3.25C6.75,3.731 6.556,4.167 6.241,4.484C6.676,4.288 7.14,4.147 7.626,4.069ZM8.5,14C10.985,14 13,11.985 13,9.5C13,7.015 10.985,5 8.5,5C6.015,5 4,7.015 4,9.5C4,11.985 6.015,14 8.5,14ZM8.5,7C8.776,7 9,7.224 9,7.5V9H10.5C10.776,9 11,9.224 11,9.5C11,9.776 10.776,10 10.5,10H9V11.5C9,11.776 8.776,12 8.5,12C8.224,12 8,11.776 8,11.5V10H6.5C6.224,10 6,9.776 6,9.5C6,9.224 6.224,9 6.5,9H8L8,7.5C8,7.224 8.224,7 8.5,7Z"
|
||||
android:fillColor="#919191"/>
|
||||
</vector>
|
|
@ -0,0 +1,9 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="13dp"
|
||||
android:height="14dp"
|
||||
android:viewportWidth="13"
|
||||
android:viewportHeight="14">
|
||||
<path
|
||||
android:pathData="M4.222,12.957C1.555,12.653 0,10.803 0,9L0,8.5C0,7.672 0.672,7 1.5,7H3.6C3.438,7.317 3.306,7.651 3.207,8H1.5C1.224,8 1,8.224 1,8.5V9C1,10.128 1.882,11.333 3.502,11.8C3.694,12.216 3.937,12.604 4.222,12.957ZM7.626,4.069C7.707,3.81 7.75,3.535 7.75,3.25C7.75,1.731 6.519,0.5 5,0.5C3.481,0.5 2.25,1.731 2.25,3.25C2.25,4.537 3.134,5.617 4.327,5.917C4.642,5.551 5.004,5.226 5.405,4.953C5.275,4.984 5.139,5 5,5C4.034,5 3.25,4.216 3.25,3.25C3.25,2.283 4.034,1.5 5,1.5C5.966,1.5 6.75,2.283 6.75,3.25C6.75,3.731 6.556,4.167 6.241,4.484C6.676,4.288 7.14,4.147 7.626,4.069ZM13,9.5C13,11.985 10.985,14 8.5,14C6.015,14 4,11.985 4,9.5C4,7.015 6.015,5 8.5,5C10.985,5 13,7.015 13,9.5ZM6.147,9.146L6.144,9.149C6.097,9.196 6.062,9.251 6.038,9.309C6.014,9.367 6,9.43 6,9.497L6,9.5L6,9.503C6,9.57 6.014,9.633 6.038,9.691C6.062,9.75 6.099,9.806 6.146,9.854L8.146,11.854C8.342,12.049 8.658,12.049 8.854,11.854C9.049,11.658 9.049,11.342 8.854,11.146L7.707,10H10.5C10.776,10 11,9.776 11,9.5C11,9.224 10.776,9 10.5,9H7.707L8.854,7.854C9.049,7.658 9.049,7.342 8.854,7.146C8.658,6.951 8.342,6.951 8.146,7.146L6.147,9.146Z"
|
||||
android:fillColor="#919191"/>
|
||||
</vector>
|
|
@ -12,6 +12,9 @@
|
|||
<string name="azure_communication_ui_chat_first_name_is_typing">%1$s is typing</string>
|
||||
<string name="azure_communication_ui_chat_two_names_are_typing">%1$s and %2$s are typing"</string>
|
||||
<string name="azure_communication_ui_chat_three_or_more_are_typing">%1$s, %2$s and %3$d %4$s are typing</string>
|
||||
<string name="azure_communication_ui_chat_joined_chat">%1$s joined the chat</string>
|
||||
<string name="azure_communication_ui_chat_left_chat">%1$s left the chat</string>
|
||||
<string name="azure_communication_ui_chat_topic_updated">Topic Updated: %1$s</string>
|
||||
<string name="azure_communication_ui_chat_message_today">Today</string>
|
||||
<string name="azure_communication_ui_chat_message_yesterday">Yesterday</string>
|
||||
</resources>
|
Загрузка…
Ссылка в новой задаче