Commit cb560bb4 authored by Lucio Maciel's avatar Lucio Maciel

Fixes on color attachments

parent 07c5c0bf
This diff is collapsed.
package chat.rocket.android.chatroom.adapter package chat.rocket.android.chatroom.adapter
import android.graphics.drawable.ColorDrawable
import android.graphics.drawable.Drawable import android.graphics.drawable.Drawable
import androidx.core.content.ContextCompat import androidx.core.content.ContextCompat
import android.text.method.LinkMovementMethod import android.text.method.LinkMovementMethod
import android.view.View import android.view.View
import androidx.core.view.isVisible
import androidx.core.widget.ImageViewCompat
import chat.rocket.android.R import chat.rocket.android.R
import chat.rocket.android.chatroom.uimodel.ColorAttachmentUiModel import chat.rocket.android.chatroom.uimodel.ColorAttachmentUiModel
import chat.rocket.android.emoji.EmojiReactionListener import chat.rocket.android.emoji.EmojiReactionListener
...@@ -15,8 +18,7 @@ class ColorAttachmentViewHolder(itemView: View, ...@@ -15,8 +18,7 @@ class ColorAttachmentViewHolder(itemView: View,
reactionListener: EmojiReactionListener? = null) reactionListener: EmojiReactionListener? = null)
: BaseViewHolder<ColorAttachmentUiModel>(itemView, listener, reactionListener) { : BaseViewHolder<ColorAttachmentUiModel>(itemView, listener, reactionListener) {
val drawable: Drawable? = ContextCompat.getDrawable(itemView.context, val drawable: Drawable = ColorDrawable(ContextCompat.getColor(itemView.context, R.color.quoteBar))
R.drawable.quote_vertical_gray_bar)
init { init {
with(itemView) { with(itemView) {
...@@ -27,9 +29,19 @@ class ColorAttachmentViewHolder(itemView: View, ...@@ -27,9 +29,19 @@ class ColorAttachmentViewHolder(itemView: View,
override fun bindViews(data: ColorAttachmentUiModel) { override fun bindViews(data: ColorAttachmentUiModel) {
with(itemView) { with(itemView) {
drawable?.let { quote_bar.setColorFilter(data.color)
quote_bar.background = drawable.mutate().apply { setTint(data.color) } if (data.text.isNotEmpty()) {
attachment_text.isVisible = true
attachment_text.text = data.text attachment_text.text = data.text
} else {
attachment_text.isVisible = false
}
if (data.fields.isNullOrEmpty()) {
text_fields.isVisible = false
} else {
text_fields.isVisible = true
text_fields.text = data.fields
} }
} }
} }
......
...@@ -9,6 +9,7 @@ data class ColorAttachmentUiModel( ...@@ -9,6 +9,7 @@ data class ColorAttachmentUiModel(
val id: Long, val id: Long,
val color: Int, val color: Int,
val text: CharSequence, val text: CharSequence,
val fields: CharSequence? = null,
override val message: Message, override val message: Message,
override val rawData: ColorAttachment, override val rawData: ColorAttachment,
override val messageId: String, override val messageId: String,
......
...@@ -42,6 +42,7 @@ import chat.rocket.core.model.attachment.Attachment ...@@ -42,6 +42,7 @@ import chat.rocket.core.model.attachment.Attachment
import chat.rocket.core.model.attachment.AudioAttachment import chat.rocket.core.model.attachment.AudioAttachment
import chat.rocket.core.model.attachment.AuthorAttachment import chat.rocket.core.model.attachment.AuthorAttachment
import chat.rocket.core.model.attachment.ColorAttachment import chat.rocket.core.model.attachment.ColorAttachment
import chat.rocket.core.model.attachment.Field
import chat.rocket.core.model.attachment.FileAttachment import chat.rocket.core.model.attachment.FileAttachment
import chat.rocket.core.model.attachment.GenericFileAttachment import chat.rocket.core.model.attachment.GenericFileAttachment
import chat.rocket.core.model.attachment.ImageAttachment import chat.rocket.core.model.attachment.ImageAttachment
...@@ -129,14 +130,14 @@ class UiModelMapper @Inject constructor( ...@@ -129,14 +130,14 @@ class UiModelMapper @Inject constructor(
withContext(CommonPool) { withContext(CommonPool) {
val list = ArrayList<BaseUiModel<*>>() val list = ArrayList<BaseUiModel<*>>()
message.urls?.forEach { message.urls?.forEach { url ->
val url = mapUrl(message, it) mapUrl(message, url)?.let { list.add(it) }
url?.let { list.add(url) }
} }
message.attachments?.forEach { message.attachments?.mapNotNull { attachment ->
val attachment = mapAttachment(message, it) mapAttachment(message, attachment)
attachment?.let { list.add(attachment) } }?.asReversed()?.let {
list.addAll(it)
} }
mapMessage(message).let { mapMessage(message).let {
...@@ -334,20 +335,18 @@ class UiModelMapper @Inject constructor( ...@@ -334,20 +335,18 @@ class UiModelMapper @Inject constructor(
val localDateTime = DateTimeHelper.getLocalDateTime(message.timestamp) val localDateTime = DateTimeHelper.getLocalDateTime(message.timestamp)
val dayMarkerText = DateTimeHelper.getFormattedDateForMessages(localDateTime, context) val dayMarkerText = DateTimeHelper.getFormattedDateForMessages(localDateTime, context)
val fieldsText = mapFields(fields)
ColorAttachmentUiModel(attachmentUrl = url, id = id, color = color.color, ColorAttachmentUiModel(attachmentUrl = url, id = id, color = color.color,
text = text, message = message, rawData = attachment, text = text, fields = fieldsText, message = message, rawData = attachment,
messageId = message.id, reactions = getReactions(message), messageId = message.id, reactions = getReactions(message),
preview = message.copy(message = content.message), unread = message.unread, preview = message.copy(message = content.message), unread = message.unread,
showDayMarker = false, currentDayMarkerText = dayMarkerText) showDayMarker = false, currentDayMarkerText = dayMarkerText)
} }
} }
private fun mapAuthorAttachment(message: Message, attachment: AuthorAttachment): AuthorAttachmentUiModel { private fun mapFields(fields: List<Field>?): CharSequence? {
return with(attachment) { return fields?.let {
val content = stripMessageQuotes(message)
val fieldsText = fields?.let {
buildSpannedString { buildSpannedString {
it.forEachIndexed { index, field -> it.forEachIndexed { index, field ->
bold { append(field.title) } bold { append(field.title) }
...@@ -362,6 +361,13 @@ class UiModelMapper @Inject constructor( ...@@ -362,6 +361,13 @@ class UiModelMapper @Inject constructor(
} }
} }
} }
}
private fun mapAuthorAttachment(message: Message, attachment: AuthorAttachment): AuthorAttachmentUiModel {
return with(attachment) {
val content = stripMessageQuotes(message)
val fieldsText = mapFields(fields)
val id = attachmentId(message, attachment) val id = attachmentId(message, attachment)
val localDateTime = DateTimeHelper.getLocalDateTime(message.timestamp) val localDateTime = DateTimeHelper.getLocalDateTime(message.timestamp)
......
...@@ -56,8 +56,8 @@ class DatabaseManager(val context: Application, ...@@ -56,8 +56,8 @@ class DatabaseManager(val context: Application,
fun userDao(): UserDao = database.userDao() fun userDao(): UserDao = database.userDao()
fun messageDao(): MessageDao = database.messageDao() fun messageDao(): MessageDao = database.messageDao()
fun clearUsersStatus() { suspend fun clearUsersStatus() {
launch(dbContext) { withContext(dbContext) {
userDao().clearStatus() userDao().clearStatus()
} }
} }
......
...@@ -23,7 +23,7 @@ import chat.rocket.android.db.model.UserEntity ...@@ -23,7 +23,7 @@ import chat.rocket.android.db.model.UserEntity
AttachmentFieldEntity::class, AttachmentActionEntity::class, UrlEntity::class, AttachmentFieldEntity::class, AttachmentActionEntity::class, UrlEntity::class,
ReactionEntity::class, MessagesSync::class ReactionEntity::class, MessagesSync::class
], ],
version = 8, version = 9,
exportSchema = true exportSchema = true
) )
abstract class RCDatabase : RoomDatabase() { abstract class RCDatabase : RoomDatabase() {
......
...@@ -69,6 +69,8 @@ data class AttachmentEntity( ...@@ -69,6 +69,8 @@ data class AttachmentEntity(
val timestamp: Long? = null, val timestamp: Long? = null,
@ColumnInfo(name = "has_actions") @ColumnInfo(name = "has_actions")
val hasActions: Boolean = false, val hasActions: Boolean = false,
@ColumnInfo(name = "has_fields")
val hasFields: Boolean = false,
@ColumnInfo(name = "button_alignment") @ColumnInfo(name = "button_alignment")
val buttonAlignment: String? = null val buttonAlignment: String? = null
) : BaseMessageEntity ) : BaseMessageEntity
...@@ -119,7 +121,7 @@ fun Attachment.asEntity(msgId: String): List<BaseMessageEntity> { ...@@ -119,7 +121,7 @@ fun Attachment.asEntity(msgId: String): List<BaseMessageEntity> {
is VideoAttachment -> listOf(asEntity(msgId)) is VideoAttachment -> listOf(asEntity(msgId))
is AudioAttachment -> listOf(asEntity(msgId)) is AudioAttachment -> listOf(asEntity(msgId))
is AuthorAttachment -> asEntity(msgId) is AuthorAttachment -> asEntity(msgId)
is ColorAttachment -> listOf(asEntity(msgId)) is ColorAttachment -> asEntity(msgId)
is MessageAttachment -> listOf(asEntity(msgId)) is MessageAttachment -> listOf(asEntity(msgId))
is GenericFileAttachment -> listOf(asEntity(msgId)) is GenericFileAttachment -> listOf(asEntity(msgId))
is ActionsAttachment -> asEntity(msgId) is ActionsAttachment -> asEntity(msgId)
...@@ -179,7 +181,8 @@ fun AuthorAttachment.asEntity(msgId: String): List<BaseMessageEntity> { ...@@ -179,7 +181,8 @@ fun AuthorAttachment.asEntity(msgId: String): List<BaseMessageEntity> {
messageId = msgId, messageId = msgId,
authorLink = url, authorLink = url,
authorIcon = authorIcon, authorIcon = authorIcon,
authorName = authorName authorName = authorName,
hasFields = fields?.isNotEmpty() == true
) )
list.add(attachment) list.add(attachment)
...@@ -195,13 +198,28 @@ fun AuthorAttachment.asEntity(msgId: String): List<BaseMessageEntity> { ...@@ -195,13 +198,28 @@ fun AuthorAttachment.asEntity(msgId: String): List<BaseMessageEntity> {
return list return list
} }
fun ColorAttachment.asEntity(msgId: String): AttachmentEntity = fun ColorAttachment.asEntity(msgId: String): List<BaseMessageEntity> {
AttachmentEntity( val list = mutableListOf<BaseMessageEntity>()
val attachment = AttachmentEntity(
_id = "${msgId}_${hashCode()}", _id = "${msgId}_${hashCode()}",
messageId = msgId, messageId = msgId,
color = color.rawColor, color = color.rawColor,
fallback = fallback fallback = fallback,
hasFields = fields?.isNotEmpty() == true
)
list.add(attachment)
fields?.forEach { field ->
val entity = AttachmentFieldEntity(
attachmentId = attachment._id,
title = field.title,
value = field.value
) )
list.add(entity)
}
return list
}
// TODO - how to model An message attachment with attachments??? // TODO - how to model An message attachment with attachments???
fun MessageAttachment.asEntity(msgId: String): AttachmentEntity = fun MessageAttachment.asEntity(msgId: String): AttachmentEntity =
......
...@@ -16,6 +16,7 @@ import chat.rocket.core.model.attachment.AudioAttachment ...@@ -16,6 +16,7 @@ import chat.rocket.core.model.attachment.AudioAttachment
import chat.rocket.core.model.attachment.AuthorAttachment import chat.rocket.core.model.attachment.AuthorAttachment
import chat.rocket.core.model.attachment.Color import chat.rocket.core.model.attachment.Color
import chat.rocket.core.model.attachment.ColorAttachment import chat.rocket.core.model.attachment.ColorAttachment
import chat.rocket.core.model.attachment.DEFAULT_COLOR_STR
import chat.rocket.core.model.attachment.Field import chat.rocket.core.model.attachment.Field
import chat.rocket.core.model.attachment.GenericFileAttachment import chat.rocket.core.model.attachment.GenericFileAttachment
import chat.rocket.core.model.attachment.ImageAttachment import chat.rocket.core.model.attachment.ImageAttachment
...@@ -61,7 +62,7 @@ class DatabaseMessageMapper(private val dbManager: DatabaseManager) { ...@@ -61,7 +62,7 @@ class DatabaseMessageMapper(private val dbManager: DatabaseManager) {
} }
val urls = this.urls?.let { mapUrl(it) } val urls = this.urls?.let { mapUrl(it) }
val reactions = this.reactions?.let { mapReactions(it) } val reactions = this.reactions?.let { mapReactions(it) }
val attachments = this.attachments?.let { mapAttachments(it) } val attachments = this.attachments?.let { mapAttachments(it).asReversed() }
val messageType = messageTypeOf(this.message.type) val messageType = messageTypeOf(this.message.type)
list.add(Message( list.add(Message(
...@@ -164,6 +165,9 @@ class DatabaseMessageMapper(private val dbManager: DatabaseManager) { ...@@ -164,6 +165,9 @@ class DatabaseMessageMapper(private val dbManager: DatabaseManager) {
authorLink != null -> { authorLink != null -> {
mapAuthorAttachment(this) mapAuthorAttachment(this)
} }
hasFields -> {
mapColorAttachmentWithFields(this)
}
hasActions -> { hasActions -> {
mapActionAttachment(this) mapActionAttachment(this)
} }
...@@ -174,6 +178,19 @@ class DatabaseMessageMapper(private val dbManager: DatabaseManager) { ...@@ -174,6 +178,19 @@ class DatabaseMessageMapper(private val dbManager: DatabaseManager) {
return list return list
} }
private suspend fun mapColorAttachmentWithFields(entity: AttachmentEntity): ColorAttachment {
val fields = withContext(CommonPool) {
dbManager.messageDao().getAttachmentFields(entity._id)
}.map { Field(it.title, it.value) }
return with(entity) {
ColorAttachment(
color = Color.Custom(color ?: DEFAULT_COLOR_STR),
text = text ?: "",
fallback = fallback,
fields = fields)
}
}
private suspend fun mapActionAttachment(attachment: AttachmentEntity): ActionsAttachment { private suspend fun mapActionAttachment(attachment: AttachmentEntity): ActionsAttachment {
val actions = withContext(CommonPool) { val actions = withContext(CommonPool) {
dbManager.messageDao().getAttachmentActions(attachment._id) dbManager.messageDao().getAttachmentActions(attachment._id)
......
...@@ -13,12 +13,13 @@ ...@@ -13,12 +13,13 @@
android:paddingEnd="@dimen/screen_edge_left_and_right_padding" android:paddingEnd="@dimen/screen_edge_left_and_right_padding"
android:paddingBottom="@dimen/message_item_top_and_bottom_padding"> android:paddingBottom="@dimen/message_item_top_and_bottom_padding">
<View <ImageView
android:id="@+id/quote_bar" android:id="@+id/quote_bar"
android:layout_width="4dp" android:layout_width="4dp"
android:layout_height="0dp" android:layout_height="0dp"
android:layout_marginStart="56dp" android:layout_marginStart="56dp"
android:background="@drawable/quote_vertical_gray_bar" android:src="@drawable/quote_vertical_gray_bar"
android:scaleType="fitXY"
app:layout_constraintBottom_toTopOf="@id/recycler_view_reactions" app:layout_constraintBottom_toTopOf="@id/recycler_view_reactions"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" /> app:layout_constraintTop_toTopOf="parent" />
...@@ -35,11 +36,24 @@ ...@@ -35,11 +36,24 @@
app:layout_constraintTop_toTopOf="parent" app:layout_constraintTop_toTopOf="parent"
tools:text="#5571 - User profile from SSO must not have password change option" /> tools:text="#5571 - User profile from SSO must not have password change option" />
<TextView
android:id="@+id/text_fields"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:visibility="gone"
android:layout_marginStart="8dp"
android:layout_marginTop="4dp"
app:layout_constraintTop_toBottomOf="@id/attachment_text"
app:layout_constraintStart_toEndOf="@id/quote_bar"
app:layout_constraintEnd_toEndOf="parent"
tools:visibility="visible"
tools:text="line1\nline2\n\nline3\nline4"/>
<include <include
layout="@layout/layout_reactions" layout="@layout/layout_reactions"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
app:layout_constraintStart_toStartOf="@id/quote_bar" app:layout_constraintStart_toStartOf="@id/quote_bar"
app:layout_constraintTop_toBottomOf="@id/attachment_text" /> app:layout_constraintTop_toBottomOf="@id/text_fields" />
</androidx.constraintlayout.widget.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment