Commit 847036a7 authored by Lucio Maciel's avatar Lucio Maciel

Refactor attachments

parent ea6c8083
This diff is collapsed.
package chat.rocket.android.chatroom.adapter package chat.rocket.android.chatroom.adapter
/*
import android.view.View import android.view.View
import chat.rocket.android.chatroom.uimodel.ActionsAttachmentUiModel import chat.rocket.android.chatroom.uimodel.ActionsAttachmentUiModel
import chat.rocket.android.emoji.EmojiReactionListener import chat.rocket.android.emoji.EmojiReactionListener
...@@ -40,4 +41,4 @@ class ActionsAttachmentViewHolder( ...@@ -40,4 +41,4 @@ class ActionsAttachmentViewHolder(
interface ActionAttachmentOnClickListener { interface ActionAttachmentOnClickListener {
fun onActionClicked(view: View, action: Action) fun onActionClicked(view: View, action: Action)
} }*/
\ No newline at end of file
...@@ -70,4 +70,4 @@ class ActionsListAdapter(actions: List<Action>, var actionAttachmentOnClickListe ...@@ -70,4 +70,4 @@ class ActionsListAdapter(actions: List<Action>, var actionAttachmentOnClickListe
val action = actions[position] val action = actions[position]
holder.bindAction(action) holder.bindAction(action)
} }
} }
\ No newline at end of file
package chat.rocket.android.chatroom.adapter package chat.rocket.android.chatroom.adapter
/*
import android.view.View import android.view.View
import androidx.core.view.isVisible import androidx.core.view.isVisible
import chat.rocket.android.chatroom.uimodel.AudioAttachmentUiModel import chat.rocket.android.chatroom.uimodel.AudioAttachmentUiModel
...@@ -30,4 +31,4 @@ class AudioAttachmentViewHolder(itemView: View, ...@@ -30,4 +31,4 @@ class AudioAttachmentViewHolder(itemView: View,
} }
} }
} }
} }*/
\ No newline at end of file
package chat.rocket.android.chatroom.adapter package chat.rocket.android.chatroom.adapter
/*
import android.content.Intent import android.content.Intent
import android.net.Uri import android.net.Uri
import android.view.View import android.view.View
...@@ -46,4 +47,4 @@ class AuthorAttachmentViewHolder(itemView: View, ...@@ -46,4 +47,4 @@ class AuthorAttachmentViewHolder(itemView: View,
} }
} }
} }
} }*/
\ No newline at end of file
...@@ -36,7 +36,7 @@ class ChatRoomAdapter( ...@@ -36,7 +36,7 @@ class ChatRoomAdapter(
val view = parent.inflate(R.layout.item_message) val view = parent.inflate(R.layout.item_message)
MessageViewHolder(view, actionsListener, reactionListener) MessageViewHolder(view, actionsListener, reactionListener)
} }
BaseUiModel.ViewType.IMAGE_ATTACHMENT -> { /*BaseUiModel.ViewType.IMAGE_ATTACHMENT -> {
val view = parent.inflate(R.layout.message_attachment) val view = parent.inflate(R.layout.message_attachment)
ImageAttachmentViewHolder(view, actionsListener, reactionListener) ImageAttachmentViewHolder(view, actionsListener, reactionListener)
} }
...@@ -47,12 +47,12 @@ class ChatRoomAdapter( ...@@ -47,12 +47,12 @@ class ChatRoomAdapter(
BaseUiModel.ViewType.VIDEO_ATTACHMENT -> { BaseUiModel.ViewType.VIDEO_ATTACHMENT -> {
val view = parent.inflate(R.layout.message_attachment) val view = parent.inflate(R.layout.message_attachment)
VideoAttachmentViewHolder(view, actionsListener, reactionListener) VideoAttachmentViewHolder(view, actionsListener, reactionListener)
} }*/
BaseUiModel.ViewType.URL_PREVIEW -> { BaseUiModel.ViewType.URL_PREVIEW -> {
val view = parent.inflate(R.layout.message_url_preview) val view = parent.inflate(R.layout.message_url_preview)
UrlPreviewViewHolder(view, actionsListener, reactionListener) UrlPreviewViewHolder(view, actionsListener, reactionListener)
} }
BaseUiModel.ViewType.MESSAGE_ATTACHMENT -> { /*BaseUiModel.ViewType.MESSAGE_ATTACHMENT -> {
val view = parent.inflate(R.layout.item_message_attachment) val view = parent.inflate(R.layout.item_message_attachment)
MessageAttachmentViewHolder(view, actionsListener, reactionListener) MessageAttachmentViewHolder(view, actionsListener, reactionListener)
} }
...@@ -67,6 +67,10 @@ class ChatRoomAdapter( ...@@ -67,6 +67,10 @@ class ChatRoomAdapter(
BaseUiModel.ViewType.GENERIC_FILE_ATTACHMENT -> { BaseUiModel.ViewType.GENERIC_FILE_ATTACHMENT -> {
val view = parent.inflate(R.layout.item_file_attachment) val view = parent.inflate(R.layout.item_file_attachment)
GenericFileAttachmentViewHolder(view, actionsListener, reactionListener) GenericFileAttachmentViewHolder(view, actionsListener, reactionListener)
}*/
BaseUiModel.ViewType.ATTACHMENT -> {
val view = parent.inflate(R.layout.item_message_attachment)
AttachmentViewHolder(view, actionsListener, reactionListener, actionAttachmentOnClickListener)
} }
BaseUiModel.ViewType.MESSAGE_REPLY -> { BaseUiModel.ViewType.MESSAGE_REPLY -> {
val view = parent.inflate(R.layout.item_message_reply) val view = parent.inflate(R.layout.item_message_reply)
...@@ -74,10 +78,10 @@ class ChatRoomAdapter( ...@@ -74,10 +78,10 @@ class ChatRoomAdapter(
actionSelectListener?.openDirectMessage(roomName, permalink) actionSelectListener?.openDirectMessage(roomName, permalink)
} }
} }
BaseUiModel.ViewType.ACTIONS_ATTACHMENT -> { /*BaseUiModel.ViewType.ACTIONS_ATTACHMENT -> {
val view = parent.inflate(R.layout.item_actions_attachment) val view = parent.inflate(R.layout.item_actions_attachment)
ActionsAttachmentViewHolder(view, actionsListener, reactionListener, actionAttachmentOnClickListener) ActionsAttachmentViewHolder(view, actionsListener, reactionListener, actionAttachmentOnClickListener)
} }*/
else -> { else -> {
throw InvalidParameterException("TODO - implement for ${viewType.toViewType()}") throw InvalidParameterException("TODO - implement for ${viewType.toViewType()}")
} }
...@@ -113,26 +117,28 @@ class ChatRoomAdapter( ...@@ -113,26 +117,28 @@ class ChatRoomAdapter(
when (holder) { when (holder) {
is MessageViewHolder -> is MessageViewHolder ->
holder.bind(dataSet[position] as MessageUiModel) holder.bind(dataSet[position] as MessageUiModel)
is ImageAttachmentViewHolder -> /*is ImageAttachmentViewHolder ->
holder.bind(dataSet[position] as ImageAttachmentUiModel) holder.bind(dataSet[position] as ImageAttachmentUiModel)
is AudioAttachmentViewHolder -> is AudioAttachmentViewHolder ->
holder.bind(dataSet[position] as AudioAttachmentUiModel) holder.bind(dataSet[position] as AudioAttachmentUiModel)
is VideoAttachmentViewHolder -> is VideoAttachmentViewHolder ->
holder.bind(dataSet[position] as VideoAttachmentUiModel) holder.bind(dataSet[position] as VideoAttachmentUiModel)*/
is UrlPreviewViewHolder -> is UrlPreviewViewHolder ->
holder.bind(dataSet[position] as UrlPreviewUiModel) holder.bind(dataSet[position] as UrlPreviewUiModel)
is MessageAttachmentViewHolder -> /*is MessageAttachmentViewHolder ->
holder.bind(dataSet[position] as MessageAttachmentUiModel) holder.bind(dataSet[position] as MessageAttachmentUiModel)
is AuthorAttachmentViewHolder -> is AuthorAttachmentViewHolder ->
holder.bind(dataSet[position] as AuthorAttachmentUiModel) holder.bind(dataSet[position] as AuthorAttachmentUiModel)
is ColorAttachmentViewHolder -> is ColorAttachmentViewHolder ->
holder.bind(dataSet[position] as ColorAttachmentUiModel) holder.bind(dataSet[position] as ColorAttachmentUiModel)
is GenericFileAttachmentViewHolder -> is GenericFileAttachmentViewHolder ->
holder.bind(dataSet[position] as GenericFileAttachmentUiModel) holder.bind(dataSet[position] as GenericFileAttachmentUiModel)*/
is MessageReplyViewHolder -> is MessageReplyViewHolder ->
holder.bind(dataSet[position] as MessageReplyUiModel) holder.bind(dataSet[position] as MessageReplyUiModel)
is ActionsAttachmentViewHolder -> /*is ActionsAttachmentViewHolder ->
holder.bind(dataSet[position] as ActionsAttachmentUiModel) holder.bind(dataSet[position] as ActionsAttachmentUiModel)*/
is AttachmentViewHolder ->
holder.bind(dataSet[position] as AttachmentUiModel)
} }
} }
...@@ -140,8 +146,7 @@ class ChatRoomAdapter( ...@@ -140,8 +146,7 @@ class ChatRoomAdapter(
val model = dataSet[position] val model = dataSet[position]
return when (model) { return when (model) {
is MessageUiModel -> model.messageId.hashCode().toLong() is MessageUiModel -> model.messageId.hashCode().toLong()
is BaseFileAttachmentUiModel -> model.id is AttachmentUiModel -> model.id
is AuthorAttachmentUiModel -> model.id
else -> return position.toLong() else -> return position.toLong()
} }
} }
......
package chat.rocket.android.chatroom.adapter package chat.rocket.android.chatroom.adapter
/*
import android.graphics.drawable.ColorDrawable 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
...@@ -30,11 +31,11 @@ class ColorAttachmentViewHolder(itemView: View, ...@@ -30,11 +31,11 @@ class ColorAttachmentViewHolder(itemView: View,
override fun bindViews(data: ColorAttachmentUiModel) { override fun bindViews(data: ColorAttachmentUiModel) {
with(itemView) { with(itemView) {
quote_bar.setColorFilter(data.color) quote_bar.setColorFilter(data.color)
if (data.text.isNotEmpty()) { if (data.text.isNullOrEmpty()) {
attachment_text.isVisible = false
} else {
attachment_text.isVisible = true attachment_text.isVisible = true
attachment_text.text = data.text attachment_text.text = data.text
} else {
attachment_text.isVisible = false
} }
if (data.fields.isNullOrEmpty()) { if (data.fields.isNullOrEmpty()) {
...@@ -46,4 +47,4 @@ class ColorAttachmentViewHolder(itemView: View, ...@@ -46,4 +47,4 @@ class ColorAttachmentViewHolder(itemView: View,
} }
} }
} }*/
\ No newline at end of file
package chat.rocket.android.chatroom.adapter package chat.rocket.android.chatroom.adapter
/*
import android.content.Intent import android.content.Intent
import android.view.View import android.view.View
import androidx.core.net.toUri import androidx.core.net.toUri
...@@ -28,4 +29,4 @@ class GenericFileAttachmentViewHolder(itemView: View, ...@@ -28,4 +29,4 @@ class GenericFileAttachmentViewHolder(itemView: View,
} }
} }
} }
} }*/
\ No newline at end of file
package chat.rocket.android.chatroom.adapter package chat.rocket.android.chatroom.adapter
/*
import android.view.View import android.view.View
import chat.rocket.android.chatroom.uimodel.ImageAttachmentUiModel import chat.rocket.android.chatroom.uimodel.ImageAttachmentUiModel
import chat.rocket.android.helper.ImageHelper import chat.rocket.android.helper.ImageHelper
...@@ -39,4 +40,4 @@ class ImageAttachmentViewHolder( ...@@ -39,4 +40,4 @@ class ImageAttachmentViewHolder(
} }
} }
} }
} }*/
\ No newline at end of file
package chat.rocket.android.chatroom.adapter package chat.rocket.android.chatroom.adapter
import android.animation.ValueAnimator /*import android.animation.ValueAnimator
import android.text.method.LinkMovementMethod import android.text.method.LinkMovementMethod
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
...@@ -9,7 +9,7 @@ import androidx.core.view.isVisible ...@@ -9,7 +9,7 @@ import androidx.core.view.isVisible
import chat.rocket.android.R import chat.rocket.android.R
import chat.rocket.android.chatroom.uimodel.MessageAttachmentUiModel import chat.rocket.android.chatroom.uimodel.MessageAttachmentUiModel
import chat.rocket.android.emoji.EmojiReactionListener import chat.rocket.android.emoji.EmojiReactionListener
import kotlinx.android.synthetic.main.item_message_attachment.view.* import kotlinx.android.synthetic.main.item_message_attachment_old.view.*
class MessageAttachmentViewHolder( class MessageAttachmentViewHolder(
itemView: View, itemView: View,
...@@ -104,4 +104,4 @@ class MessageAttachmentViewHolder( ...@@ -104,4 +104,4 @@ class MessageAttachmentViewHolder(
return lp.height == ViewGroup.LayoutParams.WRAP_CONTENT return lp.height == ViewGroup.LayoutParams.WRAP_CONTENT
} }
} }
} }*/
package chat.rocket.android.chatroom.adapter package chat.rocket.android.chatroom.adapter
/*
import android.view.View import android.view.View
import androidx.core.view.isVisible import androidx.core.view.isVisible
import chat.rocket.android.chatroom.uimodel.VideoAttachmentUiModel import chat.rocket.android.chatroom.uimodel.VideoAttachmentUiModel
...@@ -30,4 +31,4 @@ class VideoAttachmentViewHolder(itemView: View, ...@@ -30,4 +31,4 @@ class VideoAttachmentViewHolder(itemView: View,
} }
} }
} }
} }*/
\ No newline at end of file
package chat.rocket.android.chatroom.uimodel package chat.rocket.android.chatroom.uimodel
import chat.rocket.android.R /*import chat.rocket.android.R
import chat.rocket.core.model.Message import chat.rocket.core.model.Message
import chat.rocket.core.model.attachment.actions.Action import chat.rocket.core.model.attachment.actions.Action
import chat.rocket.core.model.attachment.actions.ActionsAttachment
data class ActionsAttachmentUiModel( data class ActionsAttachmentUiModel(
override val attachmentUrl: String, override val attachmentUrl: String,
...@@ -26,4 +25,4 @@ data class ActionsAttachmentUiModel( ...@@ -26,4 +25,4 @@ data class ActionsAttachmentUiModel(
get() = BaseUiModel.ViewType.ACTIONS_ATTACHMENT.viewType get() = BaseUiModel.ViewType.ACTIONS_ATTACHMENT.viewType
override val layoutId: Int override val layoutId: Int
get() = R.layout.item_actions_attachment get() = R.layout.item_actions_attachment
} }*/
\ No newline at end of file
package chat.rocket.android.chatroom.uimodel
import chat.rocket.android.R
import chat.rocket.core.model.Message
import chat.rocket.core.model.attachment.Attachment
import chat.rocket.core.model.attachment.actions.Action
data class AttachmentUiModel(
override val message: Message,
override val rawData: Attachment,
override val messageId: String,
override var reactions: List<ReactionUiModel>,
override var nextDownStreamMessage: BaseUiModel<*>? = null,
override var preview: Message?,
override var isTemporary: Boolean,
override var unread: Boolean?,
override var currentDayMarkerText: String,
override var showDayMarker: Boolean,
override var menuItemsToHide: MutableList<Int> = mutableListOf(),
val id: Long,
val title: CharSequence?,
val description: CharSequence?,
val authorName: CharSequence?,
val text: CharSequence?,
val color: Int?,
val imageUrl: String?,
val videoUrl: String?,
val audioUrl: String?,
val titleLink: String?,
val messageLink: String?,
val type: String?,
// TODO - attachments
val timestamp: CharSequence?,
val authorIcon: String?,
val authorLink: String?,
val fields: CharSequence?,
val buttonAlignment: String?,
val actions: List<Action>?
) : BaseUiModel<Attachment> {
override val viewType: Int
get() = BaseUiModel.ViewType.ATTACHMENT.viewType
override val layoutId: Int
get() = R.layout.item_message_attachment
val hasTitle: Boolean
get() = !title.isNullOrEmpty()
val hasDescription: Boolean
get() = !description.isNullOrEmpty()
val hasText: Boolean
get() = !text.isNullOrEmpty()
val hasImage: Boolean
get() = imageUrl.orEmpty().isNotEmpty()
val hasVideo: Boolean
get() = videoUrl.orEmpty().isNotEmpty()
val hasAudio: Boolean
get() = audioUrl.orEmpty().isNotEmpty()
val hasAudioOrVideo: Boolean
get() = hasAudio || hasVideo
val hasFile: Boolean
get() = type.orEmpty().contentEquals("file") && titleLink.orEmpty().isNotEmpty()
val hasTitleLink: Boolean
get() = titleLink.orEmpty().isNotEmpty()
val hasMedia: Boolean
get() = hasImage || hasAudioOrVideo || hasFile
val hasMessage: Boolean
get() = messageLink.orEmpty().isNotEmpty()
val hasAuthorName: Boolean
get() = !authorName.isNullOrEmpty()
val hasAuthorLink: Boolean
get() = authorLink.orEmpty().isNotEmpty()
val hasAuthorIcon: Boolean
get() = authorIcon.orEmpty().isNotEmpty()
val hasFields: Boolean
get() = !fields.isNullOrEmpty()
val hasActions: Boolean
get() = actions != null && actions.isNotEmpty()
}
package chat.rocket.android.chatroom.uimodel package chat.rocket.android.chatroom.uimodel
/*
import chat.rocket.android.R import chat.rocket.android.R
import chat.rocket.core.model.Message import chat.rocket.core.model.Message
import chat.rocket.core.model.attachment.AudioAttachment import chat.rocket.core.model.attachment.AudioAttachment
...@@ -24,4 +25,4 @@ data class AudioAttachmentUiModel( ...@@ -24,4 +25,4 @@ data class AudioAttachmentUiModel(
get() = BaseUiModel.ViewType.AUDIO_ATTACHMENT.viewType get() = BaseUiModel.ViewType.AUDIO_ATTACHMENT.viewType
override val layoutId: Int override val layoutId: Int
get() = R.layout.message_attachment get() = R.layout.message_attachment
} }*/
\ No newline at end of file
package chat.rocket.android.chatroom.uimodel package chat.rocket.android.chatroom.uimodel
/*
import chat.rocket.android.R import chat.rocket.android.R
import chat.rocket.core.model.Message import chat.rocket.core.model.Message
import chat.rocket.core.model.attachment.AuthorAttachment import chat.rocket.core.model.attachment.AuthorAttachment
...@@ -26,4 +27,4 @@ data class AuthorAttachmentUiModel( ...@@ -26,4 +27,4 @@ data class AuthorAttachmentUiModel(
get() = BaseUiModel.ViewType.AUTHOR_ATTACHMENT.viewType get() = BaseUiModel.ViewType.AUTHOR_ATTACHMENT.viewType
override val layoutId: Int override val layoutId: Int
get() = R.layout.item_author_attachment get() = R.layout.item_author_attachment
} }*/
\ No newline at end of file
...@@ -22,15 +22,16 @@ interface BaseUiModel<out T> { ...@@ -22,15 +22,16 @@ interface BaseUiModel<out T> {
MESSAGE(0), MESSAGE(0),
SYSTEM_MESSAGE(1), SYSTEM_MESSAGE(1),
URL_PREVIEW(2), URL_PREVIEW(2),
ATTACHMENT(3),/*
IMAGE_ATTACHMENT(3), IMAGE_ATTACHMENT(3),
VIDEO_ATTACHMENT(4), VIDEO_ATTACHMENT(4),
AUDIO_ATTACHMENT(5), AUDIO_ATTACHMENT(5),
MESSAGE_ATTACHMENT(6), MESSAGE_ATTACHMENT(6),
AUTHOR_ATTACHMENT(7), AUTHOR_ATTACHMENT(7),
COLOR_ATTACHMENT(8), COLOR_ATTACHMENT(8),
GENERIC_FILE_ATTACHMENT(9), GENERIC_FILE_ATTACHMENT(9),*/
MESSAGE_REPLY(10), MESSAGE_REPLY(10)
ACTIONS_ATTACHMENT(11) //ACTIONS_ATTACHMENT(11)
} }
} }
......
package chat.rocket.android.chatroom.uimodel package chat.rocket.android.chatroom.uimodel
/*
import chat.rocket.android.R import chat.rocket.android.R
import chat.rocket.core.model.Message import chat.rocket.core.model.Message
import chat.rocket.core.model.attachment.ColorAttachment import chat.rocket.core.model.attachment.ColorAttachment
...@@ -8,7 +9,7 @@ data class ColorAttachmentUiModel( ...@@ -8,7 +9,7 @@ data class ColorAttachmentUiModel(
override val attachmentUrl: String, override val attachmentUrl: String,
val id: Long, val id: Long,
val color: Int, val color: Int,
val text: CharSequence, val text: CharSequence?,
val fields: CharSequence? = null, val fields: CharSequence? = null,
override val message: Message, override val message: Message,
override val rawData: ColorAttachment, override val rawData: ColorAttachment,
...@@ -26,4 +27,4 @@ data class ColorAttachmentUiModel( ...@@ -26,4 +27,4 @@ data class ColorAttachmentUiModel(
get() = BaseUiModel.ViewType.COLOR_ATTACHMENT.viewType get() = BaseUiModel.ViewType.COLOR_ATTACHMENT.viewType
override val layoutId: Int override val layoutId: Int
get() = R.layout.item_color_attachment get() = R.layout.item_color_attachment
} }*/
\ No newline at end of file
package chat.rocket.android.chatroom.uimodel package chat.rocket.android.chatroom.uimodel
/*
import chat.rocket.android.R import chat.rocket.android.R
import chat.rocket.core.model.Message import chat.rocket.core.model.Message
import chat.rocket.core.model.attachment.GenericFileAttachment import chat.rocket.core.model.attachment.GenericFileAttachment
...@@ -24,4 +25,4 @@ data class GenericFileAttachmentUiModel( ...@@ -24,4 +25,4 @@ data class GenericFileAttachmentUiModel(
get() = BaseUiModel.ViewType.GENERIC_FILE_ATTACHMENT.viewType get() = BaseUiModel.ViewType.GENERIC_FILE_ATTACHMENT.viewType
override val layoutId: Int override val layoutId: Int
get() = R.layout.item_file_attachment get() = R.layout.item_file_attachment
} }*/
\ No newline at end of file
package chat.rocket.android.chatroom.uimodel package chat.rocket.android.chatroom.uimodel
/*
import chat.rocket.android.R import chat.rocket.android.R
import chat.rocket.core.model.Message import chat.rocket.core.model.Message
import chat.rocket.core.model.attachment.ImageAttachment import chat.rocket.core.model.attachment.ImageAttachment
...@@ -26,4 +27,4 @@ data class ImageAttachmentUiModel( ...@@ -26,4 +27,4 @@ data class ImageAttachmentUiModel(
get() = BaseUiModel.ViewType.IMAGE_ATTACHMENT.viewType get() = BaseUiModel.ViewType.IMAGE_ATTACHMENT.viewType
override val layoutId: Int override val layoutId: Int
get() = R.layout.message_attachment get() = R.layout.message_attachment
} }*/
\ No newline at end of file
package chat.rocket.android.chatroom.uimodel package chat.rocket.android.chatroom.uimodel
/*
import chat.rocket.android.R import chat.rocket.android.R
import chat.rocket.core.model.Message import chat.rocket.core.model.Message
...@@ -26,4 +27,4 @@ data class MessageAttachmentUiModel( ...@@ -26,4 +27,4 @@ data class MessageAttachmentUiModel(
override val layoutId: Int override val layoutId: Int
get() = R.layout.item_message_attachment get() = R.layout.item_message_attachment
} }*/
\ No newline at end of file
...@@ -39,16 +39,7 @@ import chat.rocket.core.model.Message ...@@ -39,16 +39,7 @@ import chat.rocket.core.model.Message
import chat.rocket.core.model.MessageType import chat.rocket.core.model.MessageType
import chat.rocket.core.model.ReadReceipt import chat.rocket.core.model.ReadReceipt
import chat.rocket.core.model.attachment.Attachment import chat.rocket.core.model.attachment.Attachment
import chat.rocket.core.model.attachment.AudioAttachment
import chat.rocket.core.model.attachment.AuthorAttachment
import chat.rocket.core.model.attachment.ColorAttachment
import chat.rocket.core.model.attachment.Field import chat.rocket.core.model.attachment.Field
import chat.rocket.core.model.attachment.FileAttachment
import chat.rocket.core.model.attachment.GenericFileAttachment
import chat.rocket.core.model.attachment.ImageAttachment
import chat.rocket.core.model.attachment.MessageAttachment
import chat.rocket.core.model.attachment.VideoAttachment
import chat.rocket.core.model.attachment.actions.ActionsAttachment
import chat.rocket.core.model.isSystemMessage import chat.rocket.core.model.isSystemMessage
import chat.rocket.core.model.url.Url import chat.rocket.core.model.url.Url
import kotlinx.coroutines.experimental.CommonPool import kotlinx.coroutines.experimental.CommonPool
...@@ -304,17 +295,60 @@ class UiModelMapper @Inject constructor( ...@@ -304,17 +295,60 @@ class UiModelMapper @Inject constructor(
} }
private fun mapAttachment(message: Message, attachment: Attachment): BaseUiModel<*>? { private fun mapAttachment(message: Message, attachment: Attachment): BaseUiModel<*>? {
return when (attachment) { return with(attachment) {
is FileAttachment -> mapFileAttachment(message, attachment) val content = stripMessageQuotes(message)
is MessageAttachment -> mapMessageAttachment(message, attachment) val id = attachmentId(message, attachment)
is AuthorAttachment -> mapAuthorAttachment(message, attachment)
is ColorAttachment -> mapColorAttachment(message, attachment) val localDateTime = DateTimeHelper.getLocalDateTime(message.timestamp)
is ActionsAttachment -> mapActionsAttachment(message, attachment) val dayMarkerText = DateTimeHelper.getFormattedDateForMessages(localDateTime, context)
else -> null val fieldsText = mapFields(fields)
val attachmentAuthor = attachment.authorName
val time = attachment.timestamp?.let { getTime(it) }
val imageUrl = attachmentUrl(attachment.imageUrl)
val videoUrl = attachmentUrl(attachment.videoUrl)
val audioUrl = attachmentUrl(attachment.audioUrl)
val titleLink = attachmentUrl(attachment.titleLink)
val attachmentTitle = attachmentTitle(attachment.title, imageUrl, videoUrl, audioUrl, titleLink)
val attachmentText = attachmentText(attachment)
val attachmentDescription = attachmentDescription(attachment)
AttachmentUiModel(
message = message,
rawData = this,
messageId = message.id,
reactions = getReactions(message),
preview = message.copy(message = content.message),
isTemporary = !message.synced,
unread = message.unread,
currentDayMarkerText = dayMarkerText,
showDayMarker = false,
id = id,
title = attachmentTitle,
description = attachmentDescription,
authorName = attachmentAuthor,
text = attachmentText,
color = color?.color,
imageUrl = imageUrl,
videoUrl = videoUrl,
audioUrl = audioUrl,
titleLink = titleLink,
type = type,
messageLink = messageLink,
timestamp = time,
authorIcon = authorIcon,
authorLink = authorLink,
fields = fieldsText,
buttonAlignment = buttonAlignment,
actions = actions
)
} }
} }
private fun mapActionsAttachment(message: Message, attachment: ActionsAttachment): BaseUiModel<*>? { /*private fun mapActionsAttachment(message: Message, attachment: ActionsAttachment): BaseUiModel<*>? {
return with(attachment) { return with(attachment) {
val content = stripMessageQuotes(message) val content = stripMessageQuotes(message)
...@@ -344,7 +378,7 @@ class UiModelMapper @Inject constructor( ...@@ -344,7 +378,7 @@ class UiModelMapper @Inject constructor(
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 mapFields(fields: List<Field>?): CharSequence? { private fun mapFields(fields: List<Field>?): CharSequence? {
return fields?.let { return fields?.let {
...@@ -364,7 +398,7 @@ class UiModelMapper @Inject constructor( ...@@ -364,7 +398,7 @@ class UiModelMapper @Inject constructor(
} }
} }
private fun mapAuthorAttachment(message: Message, attachment: AuthorAttachment): AuthorAttachmentUiModel { /*private fun mapAuthorAttachment(message: Message, attachment: AuthorAttachment): AuthorAttachmentUiModel {
return with(attachment) { return with(attachment) {
val content = stripMessageQuotes(message) val content = stripMessageQuotes(message)
...@@ -434,48 +468,47 @@ class UiModelMapper @Inject constructor( ...@@ -434,48 +468,47 @@ class UiModelMapper @Inject constructor(
showDayMarker = false, currentDayMarkerText = dayMarkerText) showDayMarker = false, currentDayMarkerText = dayMarkerText)
else -> null else -> null
} }
} }*/
private fun attachmentId(message: Message, attachment: Attachment): Long { private fun attachmentId(message: Message, attachment: Attachment): Long {
return "${message.id}_${attachment.url}".hashCode().toLong() return "${message.id}_${attachment.hashCode()}".hashCode().toLong()
} }
private fun attachmentTitle(attachment: FileAttachment): CharSequence { private fun attachmentTitle(title: String?, vararg url: String?): CharSequence {
return with(attachment) { title?.let { return it }
title?.let { return@with it }
val fileUrl = HttpUrl.parse(url) url.filterNotNull().forEach {
fileUrl?.let { val fileUrl = HttpUrl.parse(it)
return@with it.pathSegments().last() fileUrl?.let { httpUrl ->
return httpUrl.pathSegments().last()
} }
return@with ""
} }
}
private fun attachmentUrl(attachment: FileAttachment): String { return ""
return with(attachment) { }
if (url.startsWith("http")) return@with url
val fullUrl = "$baseUrl$url"
val httpUrl = HttpUrl.parse(fullUrl)
httpUrl?.let {
return@with it.newBuilder().apply {
addQueryParameter("rc_uid", token?.userId)
addQueryParameter("rc_token", token?.authToken)
}.build().toString()
}
// Fallback to baseUrl + url private fun attachmentUrl(url: String?): String? {
return@with fullUrl if (url.isNullOrEmpty()) return null
if (url!!.startsWith("http")) return url
val fullUrl = "$baseUrl$url"
val httpUrl = HttpUrl.parse(fullUrl)
httpUrl?.let {
return it.newBuilder().apply {
addQueryParameter("rc_uid", token?.userId)
addQueryParameter("rc_token", token?.authToken)
}.build().toString()
} }
// Fallback to baseUrl + url
return fullUrl
} }
private fun attachmentText(attachment: FileAttachment): String? { private fun attachmentText(attachment: Attachment): String? {
return attachment.text return attachment.text
} }
private fun attachmentDescription(attachment: FileAttachment): String? { private fun attachmentDescription(attachment: Attachment): String? {
return attachment.description return attachment.description
} }
......
package chat.rocket.android.chatroom.uimodel package chat.rocket.android.chatroom.uimodel
/*
import chat.rocket.android.R import chat.rocket.android.R
import chat.rocket.core.model.Message import chat.rocket.core.model.Message
import chat.rocket.core.model.attachment.VideoAttachment import chat.rocket.core.model.attachment.VideoAttachment
...@@ -24,4 +25,4 @@ data class VideoAttachmentUiModel( ...@@ -24,4 +25,4 @@ data class VideoAttachmentUiModel(
get() = BaseUiModel.ViewType.VIDEO_ATTACHMENT.viewType get() = BaseUiModel.ViewType.VIDEO_ATTACHMENT.viewType
override val layoutId: Int override val layoutId: Int
get() = R.layout.message_attachment get() = R.layout.message_attachment
} }*/
\ No newline at end of file
...@@ -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 = 9, version = 10,
exportSchema = true exportSchema = true
) )
abstract class RCDatabase : RoomDatabase() { abstract class RCDatabase : RoomDatabase() {
......
...@@ -7,16 +7,7 @@ import androidx.room.Index ...@@ -7,16 +7,7 @@ import androidx.room.Index
import androidx.room.PrimaryKey import androidx.room.PrimaryKey
import chat.rocket.android.util.extension.orFalse import chat.rocket.android.util.extension.orFalse
import chat.rocket.core.model.attachment.Attachment import chat.rocket.core.model.attachment.Attachment
import chat.rocket.core.model.attachment.AudioAttachment
import chat.rocket.core.model.attachment.AuthorAttachment
import chat.rocket.core.model.attachment.ColorAttachment
import chat.rocket.core.model.attachment.GenericFileAttachment
import chat.rocket.core.model.attachment.ImageAttachment
import chat.rocket.core.model.attachment.MessageAttachment
import chat.rocket.core.model.attachment.VideoAttachment
import chat.rocket.core.model.attachment.actions.ActionsAttachment
import chat.rocket.core.model.attachment.actions.ButtonAction import chat.rocket.core.model.attachment.actions.ButtonAction
import timber.log.Timber
@Entity(tableName = "attachments", @Entity(tableName = "attachments",
foreignKeys = [ foreignKeys = [
...@@ -116,149 +107,51 @@ data class AttachmentActionEntity( ...@@ -116,149 +107,51 @@ data class AttachmentActionEntity(
} }
fun Attachment.asEntity(msgId: String): List<BaseMessageEntity> { fun Attachment.asEntity(msgId: String): List<BaseMessageEntity> {
return when(this) { val attachmentId = "${msgId}_${hashCode()}"
is ImageAttachment -> listOf(asEntity(msgId))
is VideoAttachment -> listOf(asEntity(msgId))
is AudioAttachment -> listOf(asEntity(msgId))
is AuthorAttachment -> asEntity(msgId)
is ColorAttachment -> asEntity(msgId)
is MessageAttachment -> listOf(asEntity(msgId))
is GenericFileAttachment -> listOf(asEntity(msgId))
is ActionsAttachment -> asEntity(msgId)
else -> {
Timber.d("Missing conversion for: ${javaClass.canonicalName}")
emptyList()
}
}
}
fun ImageAttachment.asEntity(msgId: String): AttachmentEntity =
AttachmentEntity(
_id = "${msgId}_${hashCode()}",
messageId = msgId,
title = title,
description = description,
text = text,
titleLink = titleLink,
titleLinkDownload = titleLinkDownload.orFalse(),
imageUrl = url,
imageType = type,
imageSize = size
)
fun VideoAttachment.asEntity(msgId: String): AttachmentEntity =
AttachmentEntity(
_id = "${msgId}_${hashCode()}",
messageId = msgId,
title = title,
description = description,
text = text,
titleLink = titleLink,
titleLinkDownload = titleLinkDownload.orFalse(),
videoUrl = url,
videoType = type,
videoSize = size
)
fun AudioAttachment.asEntity(msgId: String): AttachmentEntity =
AttachmentEntity(
_id = "${msgId}_${hashCode()}",
messageId = msgId,
title = title,
description = description,
text = text,
titleLink = titleLink,
titleLinkDownload = titleLinkDownload.orFalse(),
audioUrl = url,
audioType = type,
audioSize = size
)
fun AuthorAttachment.asEntity(msgId: String): List<BaseMessageEntity> {
val list = mutableListOf<BaseMessageEntity>() val list = mutableListOf<BaseMessageEntity>()
val attachment = AttachmentEntity(
_id = "${msgId}_${hashCode()}",
messageId = msgId,
authorLink = url,
authorIcon = authorIcon,
authorName = authorName,
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
}
fun ColorAttachment.asEntity(msgId: String): List<BaseMessageEntity> { val entity = AttachmentEntity(
val list = mutableListOf<BaseMessageEntity>() _id = attachmentId,
val attachment = AttachmentEntity( messageId = msgId,
_id = "${msgId}_${hashCode()}", title = title,
messageId = msgId, type = type,
color = color.rawColor, description = description,
fallback = fallback, text = text,
hasFields = fields?.isNotEmpty() == true titleLink = titleLink,
titleLinkDownload = titleLinkDownload.orFalse(),
imageUrl = imageUrl,
imageType = imageType,
imageSize = imageSize,
videoUrl = videoUrl,
videoType = videoType,
videoSize = videoSize,
audioUrl = audioUrl,
audioType = audioType,
audioSize = audioSize,
authorLink = authorLink,
authorIcon = authorIcon,
authorName = authorName,
color = color?.rawColor,
fallback = fallback,
thumbUrl = thumbUrl,
messageLink = messageLink,
timestamp = timestamp,
buttonAlignment = buttonAlignment,
hasActions = actions?.isNotEmpty() == true,
hasFields = fields?.isNotEmpty() == true
) )
list.add(attachment) list.add(entity)
fields?.forEach { field -> fields?.forEach { field ->
val entity = AttachmentFieldEntity( val entity = AttachmentFieldEntity(
attachmentId = attachment._id, attachmentId = attachmentId,
title = field.title, title = field.title,
value = field.value value = field.value
) )
list.add(entity) list.add(entity)
} }
return list actions?.forEach { action ->
}
// TODO - how to model An message attachment with attachments???
fun MessageAttachment.asEntity(msgId: String): AttachmentEntity =
AttachmentEntity(
_id = "${msgId}_${hashCode()}",
messageId = msgId,
authorName = author,
authorIcon = icon,
text = text,
thumbUrl = thumbUrl,
color = color?.rawColor,
messageLink = url,
timestamp = timestamp
)
fun GenericFileAttachment.asEntity(msgId: String): AttachmentEntity =
AttachmentEntity(
_id = "${msgId}_${hashCode()}",
messageId = msgId,
title = title,
description = description,
text = text,
titleLink = titleLink,
titleLinkDownload = titleLinkDownload ?: false
)
fun ActionsAttachment.asEntity(msgId: String): List<BaseMessageEntity> {
val list = mutableListOf<BaseMessageEntity>()
val attachmentId = "${msgId}_${hashCode()}"
val attachment = AttachmentEntity(
_id = attachmentId,
messageId = msgId,
title = title,
hasActions = true,
buttonAlignment = buttonAlignment
)
list.add(attachment)
actions.forEach { action ->
when (action) { when (action) {
is ButtonAction -> AttachmentActionEntity( is ButtonAction -> AttachmentActionEntity(
attachmentId = attachmentId, attachmentId = attachmentId,
......
...@@ -35,7 +35,7 @@ object ImageHelper { ...@@ -35,7 +35,7 @@ object ImageHelper {
// TODO - implement a proper image viewer with a proper Transition // TODO - implement a proper image viewer with a proper Transition
// TODO - We should definitely write our own ImageViewer // TODO - We should definitely write our own ImageViewer
fun openImage(context: Context, imageUrl: String, imageName: String) { fun openImage(context: Context, imageUrl: String, imageName: String? = "") {
var imageViewer: ImageViewer? = null var imageViewer: ImageViewer? = null
val request = val request =
ImageRequestBuilder.newBuilderWithSource(imageUrl.toUri()) ImageRequestBuilder.newBuilderWithSource(imageUrl.toUri())
......
...@@ -12,18 +12,10 @@ import chat.rocket.common.model.SimpleUser ...@@ -12,18 +12,10 @@ import chat.rocket.common.model.SimpleUser
import chat.rocket.core.model.Message import chat.rocket.core.model.Message
import chat.rocket.core.model.Reactions import chat.rocket.core.model.Reactions
import chat.rocket.core.model.attachment.Attachment import chat.rocket.core.model.attachment.Attachment
import chat.rocket.core.model.attachment.AudioAttachment
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.DEFAULT_COLOR_STR 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.ImageAttachment
import chat.rocket.core.model.attachment.MessageAttachment
import chat.rocket.core.model.attachment.VideoAttachment
import chat.rocket.core.model.attachment.actions.Action import chat.rocket.core.model.attachment.actions.Action
import chat.rocket.core.model.attachment.actions.ActionsAttachment
import chat.rocket.core.model.attachment.actions.ButtonAction import chat.rocket.core.model.attachment.actions.ButtonAction
import chat.rocket.core.model.messageTypeOf import chat.rocket.core.model.messageTypeOf
import chat.rocket.core.model.url.Meta import chat.rocket.core.model.url.Meta
...@@ -141,44 +133,57 @@ class DatabaseMessageMapper(private val dbManager: DatabaseManager) { ...@@ -141,44 +133,57 @@ class DatabaseMessageMapper(private val dbManager: DatabaseManager) {
val list = mutableListOf<Attachment>() val list = mutableListOf<Attachment>()
attachments.forEach { attachment -> attachments.forEach { attachment ->
with(attachment) { with(attachment) {
when { val fields = if (hasFields) {
imageUrl != null -> { withContext(CommonPool) {
ImageAttachment(title, description, text, titleLink, titleLinkDownload, imageUrl, type, imageSize) dbManager.messageDao().getAttachmentFields(attachment._id)
} }.map { Field(it.title, it.value) }
videoUrl != null -> { } else {
VideoAttachment(title, description, text, titleLink, titleLinkDownload, videoUrl, type, videoSize) null
} }
audioUrl != null -> { val actions = if (hasActions) {
AudioAttachment(title, description, text, titleLink, titleLinkDownload, audioUrl, type, audioSize) withContext(CommonPool) {
} dbManager.messageDao().getAttachmentActions(attachment._id)
titleLink != null -> { }.mapNotNull { mapAction(it) }
GenericFileAttachment(title, description, text, titleLink, titleLink, titleLinkDownload) } else {
} null
text != null && color != null && fallback != null -> { }
ColorAttachment(Color.Custom(color), text, fallback)
} val attachment = Attachment(
text != null -> { title = title,
// TODO how to model message with attachments type = type,
MessageAttachment(authorName, authorIcon, text, thumbUrl, description = description,
color?.let { Color.Custom(it) }, messageLink, null, timestamp) authorName = authorName,
} text = text,
authorLink != null -> { thumbUrl = thumbUrl,
mapAuthorAttachment(this) color = color?.let { Color.Custom(color) },
} titleLink = titleLink,
hasFields -> { titleLinkDownload = titleLinkDownload,
mapColorAttachmentWithFields(this) imageUrl = imageUrl,
} imageType = imageType,
hasActions -> { imageSize = imageSize,
mapActionAttachment(this) videoUrl = videoUrl,
} videoType = videoType,
else -> null videoSize = videoSize,
}?.let { list.add(it) } audioUrl = audioUrl,
audioType = audioType,
audioSize = audioSize,
messageLink = messageLink,
attachments = null, // HOW TO MAP THIS
timestamp = timestamp,
authorIcon = authorIcon,
authorLink = authorLink,
fields = fields,
fallback = fallback,
buttonAlignment = if (actions != null && actions.isNotEmpty()) buttonAlignment ?: "vertical" else null,
actions = actions
)
list.add(attachment)
} }
} }
return list return list
} }
private suspend fun mapColorAttachmentWithFields(entity: AttachmentEntity): ColorAttachment { /*private suspend fun mapColorAttachmentWithFields(entity: AttachmentEntity): ColorAttachment {
val fields = withContext(CommonPool) { val fields = withContext(CommonPool) {
dbManager.messageDao().getAttachmentFields(entity._id) dbManager.messageDao().getAttachmentFields(entity._id)
}.map { Field(it.title, it.value) } }.map { Field(it.title, it.value) }
...@@ -199,7 +204,7 @@ class DatabaseMessageMapper(private val dbManager: DatabaseManager) { ...@@ -199,7 +204,7 @@ class DatabaseMessageMapper(private val dbManager: DatabaseManager) {
// TODO - remove the default "vertical" value from here... // TODO - remove the default "vertical" value from here...
ActionsAttachment(title, actions, buttonAlignment ?: "vertical") ActionsAttachment(title, actions, buttonAlignment ?: "vertical")
} }
} }*/
private fun mapAction(action: AttachmentActionEntity): Action? { private fun mapAction(action: AttachmentActionEntity): Action? {
return when (action.type) { return when (action.type) {
...@@ -210,12 +215,12 @@ class DatabaseMessageMapper(private val dbManager: DatabaseManager) { ...@@ -210,12 +215,12 @@ class DatabaseMessageMapper(private val dbManager: DatabaseManager) {
} }
} }
private suspend fun mapAuthorAttachment(attachment: AttachmentEntity): AuthorAttachment { /*private suspend fun mapAuthorAttachment(attachment: AttachmentEntity): AuthorAttachment {
val fields = withContext(CommonPool) { val fields = withContext(CommonPool) {
dbManager.messageDao().getAttachmentFields(attachment._id) dbManager.messageDao().getAttachmentFields(attachment._id)
}.map { Field(it.title, it.value) } }.map { Field(it.title, it.value) }
return with(attachment) { return with(attachment) {
AuthorAttachment(authorLink!!, authorIcon, authorName, fields) AuthorAttachment(authorLink!!, authorIcon, authorName, fields)
} }
} }*/
} }
\ No newline at end of file
...@@ -4,10 +4,12 @@ import android.net.Uri ...@@ -4,10 +4,12 @@ import android.net.Uri
import androidx.browser.customtabs.CustomTabsIntent import androidx.browser.customtabs.CustomTabsIntent
import androidx.core.content.res.ResourcesCompat import androidx.core.content.res.ResourcesCompat
import android.view.View import android.view.View
import androidx.core.view.isVisible
import chat.rocket.android.R import chat.rocket.android.R
import timber.log.Timber import timber.log.Timber
fun View.openTabbedUrl(url: String) { fun View.openTabbedUrl(url: String?) {
if (url == null) return
with(this) { with(this) {
val uri = url.ensureScheme() val uri = url.ensureScheme()
val tabsbuilder = CustomTabsIntent.Builder() val tabsbuilder = CustomTabsIntent.Builder()
...@@ -30,4 +32,27 @@ private fun String.ensureScheme(): Uri? { ...@@ -30,4 +32,27 @@ private fun String.ensureScheme(): Uri? {
} }
return Uri.parse(url.lowercaseUrl()) return Uri.parse(url.lowercaseUrl())
}
inline var List<View>.isVisible: Boolean
get() {
var visible = true
forEach { view ->
if (!view.isVisible) {
visible = false
}
}
return visible
}
set(value) {
forEach { view ->
view.isVisible = value
}
}
fun List<View>.setOnClickListener(listener: (v: View) -> Unit) {
forEach { view ->
view.setOnClickListener(listener)
}
} }
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/attachment_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:animateLayoutChanges="true"
android:background="?android:attr/selectableItemBackground"
android:clickable="true"
android:focusable="true"
android:paddingStart="@dimen/screen_edge_left_and_right_padding"
android:paddingTop="@dimen/message_item_top_and_bottom_padding"
android:paddingEnd="@dimen/screen_edge_left_and_right_padding"
android:paddingBottom="@dimen/message_item_top_and_bottom_padding">
<View
android:id="@+id/quote_bar"
android:layout_width="4dp"
android:layout_height="0dp"
android:layout_marginStart="56dp"
android:background="@drawable/quote_vertical_gray_bar"
app:layout_constraintBottom_toTopOf="@+id/text_view_more"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/text_sender"
style="@style/Sender.Name.TextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:textColor="@color/colorPrimary"
app:layout_constraintStart_toEndOf="@+id/quote_bar"
app:layout_constraintTop_toTopOf="parent"
tools:text="Ronald Perkins" />
<TextView
android:id="@+id/text_message_time"
style="@style/Timestamp.TextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
app:layout_constraintBottom_toBottomOf="@+id/text_sender"
app:layout_constraintStart_toEndOf="@+id/text_sender"
app:layout_constraintTop_toTopOf="@+id/text_sender"
tools:text="11:45 PM" />
<TextView
android:id="@+id/text_content"
style="@style/Message.Quote.TextView"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintBottom_toTopOf="@id/text_view_more"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="@+id/text_sender"
app:layout_constraintTop_toBottomOf="@+id/text_sender"
tools:text="This is a multiline chat message from Bertie that will take more than just one line of text. I have sure that everything is amazing!" />
<TextView
android:id="@+id/text_view_more"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:gravity="end"
android:textColor="@color/darkGray"
android:textSize="14sp"
app:layout_constraintEnd_toEndOf="@+id/text_content"
app:layout_constraintStart_toStartOf="@+id/quote_bar"
app:layout_constraintTop_toBottomOf="@+id/text_content"
tools:text="Visualizar mais" />
<include
layout="@layout/layout_reactions"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintStart_toStartOf="@+id/quote_bar"
app:layout_constraintTop_toBottomOf="@+id/text_view_more" />
</androidx.constraintlayout.widget.ConstraintLayout>
...@@ -10,7 +10,7 @@ buildscript { ...@@ -10,7 +10,7 @@ buildscript {
} }
dependencies { dependencies {
classpath 'com.android.tools.build:gradle:3.3.0-alpha12' classpath 'com.android.tools.build:gradle:3.2.1'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:${versions.kotlin}" classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:${versions.kotlin}"
classpath "org.jetbrains.dokka:dokka-gradle-plugin:${versions.dokka}" classpath "org.jetbrains.dokka:dokka-gradle-plugin:${versions.dokka}"
classpath 'com.google.gms:google-services:4.0.2' classpath 'com.google.gms:google-services:4.0.2'
......
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