First step towards implementing message replies

This commit is contained in:
Mario Danic 2019-12-26 03:05:52 +01:00 committed by Mario Đanić
parent 5e3d0312db
commit 8e80655729
9 changed files with 238 additions and 36 deletions

View File

@ -31,19 +31,20 @@ import android.text.TextUtils
import android.util.TypedValue import android.util.TypedValue
import android.view.View import android.view.View
import android.widget.ImageView import android.widget.ImageView
import android.widget.RelativeLayout
import android.widget.TextView import android.widget.TextView
import androidx.core.view.ViewCompat import androidx.core.view.ViewCompat
import androidx.emoji.widget.EmojiTextView import androidx.emoji.widget.EmojiTextView
import butterknife.BindView import butterknife.BindView
import butterknife.ButterKnife import butterknife.ButterKnife
import com.amulyakhare.textdrawable.TextDrawable import com.amulyakhare.textdrawable.TextDrawable
import com.google.android.flexbox.FlexboxLayout
import com.nextcloud.talk.R import com.nextcloud.talk.R
import com.nextcloud.talk.models.json.chat.ChatMessage import com.nextcloud.talk.models.json.chat.ChatMessage
import com.nextcloud.talk.utils.DisplayUtils import com.nextcloud.talk.utils.DisplayUtils
import com.nextcloud.talk.utils.TextMatchers import com.nextcloud.talk.utils.TextMatchers
import com.nextcloud.talk.utils.preferences.AppPreferences import com.nextcloud.talk.utils.preferences.AppPreferences
import com.stfalcon.chatkit.messages.MessageHolders import com.stfalcon.chatkit.messages.MessageHolders
import com.stfalcon.chatkit.utils.DateFormatter
import org.koin.core.KoinComponent import org.koin.core.KoinComponent
import org.koin.core.inject import org.koin.core.inject
@ -66,6 +67,34 @@ class MagicIncomingTextMessageViewHolder(incomingView: View) : MessageHolders
@BindView(R.id.messageTime) @BindView(R.id.messageTime)
var messageTimeView: TextView? = null var messageTimeView: TextView? = null
@JvmField
@BindView(R.id.quotedChatMessageView)
var quotedChatMessageView: RelativeLayout? = null
@JvmField
@BindView(R.id.quotedUserAvatar)
var quotedUserAvatar: ImageView? = null
@JvmField
@BindView(R.id.quotedMessageAuthor)
var quotedUserName: EmojiTextView? = null
@JvmField
@BindView(R.id.quotedMessageImage)
var quotedMessagePreview: ImageView? = null
@JvmField
@BindView(R.id.quotedMessage)
var quotedMessage: EmojiTextView? = null
@JvmField
@BindView(R.id.quotedMessageTime)
var quotedMessageTime: TextView? = null
@JvmField
@BindView(R.id.quoteColoredView)
var quoteColoredView: View? = null
val context: Context by inject() val context: Context by inject()
val appPreferences: AppPreferences by inject() val appPreferences: AppPreferences by inject()
@ -139,9 +168,6 @@ class MagicIncomingTextMessageViewHolder(incomingView: View) : MessageHolders
itemView.isSelected = false itemView.isSelected = false
messageTimeView!!.setTextColor(context.resources.getColor(R.color.warm_grey_four)) messageTimeView!!.setTextColor(context.resources.getColor(R.color.warm_grey_four))
val layoutParams = messageTimeView!!.layoutParams as FlexboxLayout.LayoutParams
layoutParams.isWrapBefore = false
var messageString: Spannable = SpannableString(message.text) var messageString: Spannable = SpannableString(message.text)
var textSize = context.resources.getDimension(R.dimen.chat_text_size) var textSize = context.resources.getDimension(R.dimen.chat_text_size)
@ -173,22 +199,45 @@ class MagicIncomingTextMessageViewHolder(incomingView: View) : MessageHolders
) )
} }
} else if (individualHashMap["type"] == "file") { } else if (individualHashMap["type"] == "file") {
itemView.setOnClickListener({ v -> itemView.setOnClickListener { v ->
val browserIntent = Intent(Intent.ACTION_VIEW, Uri.parse(individualHashMap["link"])) val browserIntent = Intent(Intent.ACTION_VIEW, Uri.parse(individualHashMap["link"]))
context.startActivity(browserIntent) context.startActivity(browserIntent)
}) }
} }
} }
} }
} else if (TextMatchers.isMessageWithSingleEmoticonOnly(message.text)) { } else if (TextMatchers.isMessageWithSingleEmoticonOnly(message.text)) {
textSize = (textSize * 2.5).toFloat() textSize = (textSize * 2.5).toFloat()
layoutParams.isWrapBefore = true
itemView.isSelected = true itemView.isSelected = true
messageAuthor!!.visibility = View.GONE messageAuthor!!.visibility = View.GONE
} }
messageText!!.setTextSize(TypedValue.COMPLEX_UNIT_PX, textSize) messageText!!.setTextSize(TypedValue.COMPLEX_UNIT_PX, textSize)
messageTimeView!!.layoutParams = layoutParams
messageText!!.text = messageString messageText!!.text = messageString
// parent message handling
message.parentMessage?.let { parentChatMessage ->
parentChatMessage.activeUser = message.activeUser
imageLoader.loadImage(quotedUserAvatar, parentChatMessage.user.avatar, null)
parentChatMessage.imageUrl?.let{
quotedMessagePreview?.visibility = View.VISIBLE
imageLoader.loadImage(quotedMessagePreview, it, null)
} ?: run {
quotedMessagePreview?.visibility = View.GONE
}
quotedUserName?.text = parentChatMessage.actorDisplayName
?: context.getText(R.string.nc_nick_guest)
quotedMessage?.text = parentChatMessage.text
quotedUserName?.setTextColor(context.resources.getColor(R.color.colorPrimary))
quotedMessageTime?.text = DateFormatter.format(parentChatMessage.createdAt, DateFormatter.Template.TIME)
quotedMessageTime?.setTextColor(context.resources.getColor(R.color.warm_grey_four))
quoteColoredView?.setBackgroundResource(R.color.colorPrimary)
quotedChatMessageView?.visibility = View.VISIBLE
} ?: run {
quotedChatMessageView?.visibility = View.GONE
}
} }
} }

View File

@ -24,8 +24,11 @@ import android.content.Intent
import android.net.Uri import android.net.Uri
import android.text.Spannable import android.text.Spannable
import android.text.SpannableString import android.text.SpannableString
import android.util.Log
import android.util.TypedValue import android.util.TypedValue
import android.view.View import android.view.View
import android.widget.ImageView
import android.widget.RelativeLayout
import android.widget.TextView import android.widget.TextView
import androidx.core.view.ViewCompat import androidx.core.view.ViewCompat
import androidx.emoji.widget.EmojiTextView import androidx.emoji.widget.EmojiTextView
@ -39,6 +42,7 @@ import com.nextcloud.talk.utils.DisplayUtils.getMessageSelector
import com.nextcloud.talk.utils.DisplayUtils.searchAndReplaceWithMentionSpan import com.nextcloud.talk.utils.DisplayUtils.searchAndReplaceWithMentionSpan
import com.nextcloud.talk.utils.TextMatchers import com.nextcloud.talk.utils.TextMatchers
import com.stfalcon.chatkit.messages.MessageHolders.OutcomingTextMessageViewHolder import com.stfalcon.chatkit.messages.MessageHolders.OutcomingTextMessageViewHolder
import com.stfalcon.chatkit.utils.DateFormatter
import org.koin.core.KoinComponent import org.koin.core.KoinComponent
import org.koin.core.inject import org.koin.core.inject
import java.util.* import java.util.*
@ -50,6 +54,35 @@ class MagicOutcomingTextMessageViewHolder(itemView: View) : OutcomingTextMessage
@JvmField @JvmField
@BindView(R.id.messageTime) @BindView(R.id.messageTime)
var messageTimeView: TextView? = null var messageTimeView: TextView? = null
@JvmField
@BindView(R.id.quotedChatMessageView)
var quotedChatMessageView: RelativeLayout? = null
@JvmField
@BindView(R.id.quotedUserAvatar)
var quotedUserAvatar: ImageView? = null
@JvmField
@BindView(R.id.quotedMessageAuthor)
var quotedUserName: EmojiTextView? = null
@JvmField
@BindView(R.id.quotedMessageImage)
var quotedMessagePreview: ImageView? = null
@JvmField
@BindView(R.id.quotedMessage)
var quotedMessage: EmojiTextView? = null
@JvmField
@BindView(R.id.quotedMessageTime)
var quotedMessageTime: TextView? = null
@JvmField
@BindView(R.id.quoteColoredView)
var quoteColoredView: View? = null
val context: Context by inject() val context: Context by inject()
private val realView: View private val realView: View
override fun onBind(message: ChatMessage) { override fun onBind(message: ChatMessage) {
@ -107,6 +140,33 @@ class MagicOutcomingTextMessageViewHolder(itemView: View) : OutcomingTextMessage
messageText!!.setTextSize(TypedValue.COMPLEX_UNIT_PX, textSize) messageText!!.setTextSize(TypedValue.COMPLEX_UNIT_PX, textSize)
messageTimeView!!.layoutParams = layoutParams messageTimeView!!.layoutParams = layoutParams
messageText!!.text = messageString messageText!!.text = messageString
// parent message handling
message.parentMessage?.let { parentChatMessage ->
parentChatMessage.activeUser = message.activeUser
imageLoader.loadImage(quotedUserAvatar, parentChatMessage.user.avatar, null)
parentChatMessage.imageUrl?.let{
quotedMessagePreview?.visibility = View.VISIBLE
imageLoader.loadImage(quotedMessagePreview, it, null)
} ?: run {
quotedMessagePreview?.visibility = View.GONE
}
quotedUserName?.text = parentChatMessage.actorDisplayName
?: context.getText(R.string.nc_nick_guest)
quotedMessage?.text = parentChatMessage.text
quotedMessage?.setTextColor(context.resources.getColor(R.color.nc_outcoming_text_default))
quotedUserName?.setTextColor(context.resources.getColor(R.color.nc_grey))
quotedMessageTime?.text = DateFormatter.format(parentChatMessage.createdAt, DateFormatter.Template.TIME)
quotedMessageTime?.setTextColor(context.resources.getColor(R.color.white60))
quoteColoredView?.setBackgroundResource(R.color.white)
quotedChatMessageView?.visibility = View.VISIBLE
} ?: run {
quotedChatMessageView?.visibility = View.GONE
}
} }
init { init {

View File

@ -67,8 +67,6 @@ public class ChatMessage implements IMessage, MessageContentType, MessageContent
@Ignore @Ignore
public boolean isLinkPreviewAllowed; public boolean isLinkPreviewAllowed;
@JsonIgnore @JsonIgnore
public Long internalUserId = null;
@JsonIgnore
public String internalMessageId = null; public String internalMessageId = null;
@JsonIgnore @JsonIgnore
public String internalConversationId = null; public String internalConversationId = null;
@ -97,6 +95,8 @@ public class ChatMessage implements IMessage, MessageContentType, MessageContent
public SystemMessageType systemMessageType; public SystemMessageType systemMessageType;
@JsonField(name = "isReplyable") @JsonField(name = "isReplyable")
public boolean replyable; public boolean replyable;
@JsonField(name = "parent")
public ChatMessage parentMessage;
@JsonIgnore @JsonIgnore
@Ignore @Ignore

View File

@ -22,28 +22,17 @@
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
xmlns:tools="http://schemas.android.com/tools"
android:layout_marginStart="16dp" android:layout_marginStart="16dp"
android:layout_marginTop="2dp" android:layout_marginTop="2dp"
android:layout_marginEnd="16dp" android:layout_marginEnd="16dp"
android:layout_marginBottom="2dp"> android:layout_marginBottom="2dp">
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toEndOf="@id/messageUserAvatar">
<ImageView
android:id="@id/image"
android:layout_width="@dimen/minimum_file_preview_size"
android:layout_height="@dimen/minimum_file_preview_size"
android:adjustViewBounds="true"
android:scaleType="fitCenter" />
<com.google.android.flexbox.FlexboxLayout <com.google.android.flexbox.FlexboxLayout
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_below="@id/image" android:layout_toEndOf="@+id/messageUserAvatar"
android:layout_alignStart="@+id/image"
android:layout_marginTop="8dp" android:layout_marginTop="8dp"
android:layout_marginBottom="8dp" android:layout_marginBottom="8dp"
android:orientation="vertical" android:orientation="vertical"
@ -52,6 +41,17 @@
app:flexWrap="wrap" app:flexWrap="wrap"
app:justifyContent="flex_end"> app:justifyContent="flex_end">
<ImageView
android:id="@id/image"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:adjustViewBounds="true"
android:scaleType="centerInside"
app:layout_flexGrow="1"
app:layout_wrapBefore="true"
app:layout_alignSelf="flex_start"
tools:src="@tools:sample/backgrounds/scenic"/>
<androidx.emoji.widget.EmojiTextView <androidx.emoji.widget.EmojiTextView
android:id="@id/messageText" android:id="@id/messageText"
android:layout_width="wrap_content" android:layout_width="wrap_content"
@ -76,7 +76,6 @@
</com.google.android.flexbox.FlexboxLayout> </com.google.android.flexbox.FlexboxLayout>
</RelativeLayout>
<ImageView <ImageView
android:id="@id/messageUserAvatar" android:id="@id/messageUserAvatar"

View File

@ -46,6 +46,8 @@
app:flexWrap="wrap" app:flexWrap="wrap"
app:justifyContent="flex_end"> app:justifyContent="flex_end">
<include layout="@layout/item_message_quote" android:visibility="gone"/>
<androidx.emoji.widget.EmojiTextView <androidx.emoji.widget.EmojiTextView
android:id="@+id/messageAuthor" android:id="@+id/messageAuthor"
android:layout_width="match_parent" android:layout_width="match_parent"

View File

@ -20,34 +20,37 @@
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="wrap_content" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
xmlns:tools="http://schemas.android.com/tools"
android:layout_marginStart="16dp" android:layout_marginStart="16dp"
android:layout_marginTop="2dp" android:layout_marginTop="2dp"
android:layout_marginEnd="16dp" android:layout_marginEnd="16dp"
android:layout_marginBottom="2dp"> android:layout_marginBottom="2dp">
<ImageView
android:id="@id/image"
android:layout_width="@dimen/minimum_file_preview_size"
android:layout_height="@dimen/minimum_file_preview_size"
android:layout_alignParentEnd="true"
android:adjustViewBounds="true"
android:scaleType="fitCenter" />
<com.google.android.flexbox.FlexboxLayout <com.google.android.flexbox.FlexboxLayout
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_below="@id/image"
android:layout_alignStart="@+id/image"
android:layout_marginTop="8dp" android:layout_marginTop="8dp"
android:layout_marginBottom="8dp" android:layout_marginBottom="8dp"
android:orientation="vertical" android:orientation="vertical"
android:layout_alignParentEnd="true"
app:alignContent="stretch" app:alignContent="stretch"
app:alignItems="stretch" app:alignItems="stretch"
app:flexWrap="wrap" app:flexWrap="wrap"
app:justifyContent="flex_end"> app:justifyContent="flex_end">
<ImageView
android:id="@id/image"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:adjustViewBounds="true"
android:scaleType="centerInside"
app:layout_flexGrow="1"
app:layout_wrapBefore="true"
app:layout_alignSelf="flex_start"
tools:src="@tools:sample/backgrounds/scenic"/>
<androidx.emoji.widget.EmojiTextView <androidx.emoji.widget.EmojiTextView
android:id="@id/messageText" android:id="@id/messageText"
android:layout_width="wrap_content" android:layout_width="wrap_content"
@ -66,6 +69,7 @@
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_alignParentEnd="true" android:layout_alignParentEnd="true"
android:layout_marginStart="8dp"
android:textColor="@color/warm_grey_four" android:textColor="@color/warm_grey_four"
app:layout_alignSelf="center" /> app:layout_alignSelf="center" />
</com.google.android.flexbox.FlexboxLayout> </com.google.android.flexbox.FlexboxLayout>

View File

@ -38,6 +38,8 @@
app:flexWrap="wrap" app:flexWrap="wrap"
app:justifyContent="flex_end"> app:justifyContent="flex_end">
<include layout="@layout/item_message_quote" android:visibility="gone"/>
<androidx.emoji.widget.EmojiTextView <androidx.emoji.widget.EmojiTextView
android:id="@id/messageText" android:id="@id/messageText"
android:layout_width="wrap_content" android:layout_width="wrap_content"

View File

@ -0,0 +1,87 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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/quotedChatMessageView"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<View
android:id="@+id/quoteColoredView"
android:layout_width="2dp"
android:layout_height="match_parent"
android:layout_alignBottom="@id/flexboxQuoted"
android:layout_alignParentStart="true"
android:layout_marginEnd="4dp"
android:background="@color/colorPrimary"></View>
<ImageView
android:id="@+id/quotedUserAvatar"
android:layout_width="16dp"
android:layout_height="16dp"
android:layout_alignParentTop="true"
android:layout_toEndOf="@id/quoteColoredView"
android:layout_marginEnd="4dp"
tools:src="@tools:sample/avatars[0]" />
<androidx.emoji.widget.EmojiTextView
android:id="@+id/quotedMessageAuthor"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBottom="@id/quotedUserAvatar"
android:layout_toEndOf="@id/quotedUserAvatar"
android:ellipsize="end"
android:layout_marginEnd="8dp"
android:textSize="12sp"
tools:text="Mario" />
<com.google.android.flexbox.FlexboxLayout
android:id="@+id/flexboxQuoted"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/quotedUserAvatar"
android:layout_alignStart="@id/quotedUserAvatar"
android:layout_marginTop="4dp"
android:orientation="vertical"
app:alignContent="stretch"
app:alignItems="stretch"
app:flexWrap="wrap"
app:justifyContent="flex_end">
<ImageView
android:id="@+id/quotedMessageImage"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:adjustViewBounds="true"
android:scaleType="centerInside"
app:layout_alignSelf="flex_start"
app:layout_flexGrow="1"
app:layout_wrapBefore="true"
tools:src="@tools:sample/backgrounds/scenic" />
<androidx.emoji.widget.EmojiTextView
android:id="@+id/quotedMessage"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="14sp"
android:layout_below="@id/quotedMessageImage"
android:layout_alignStart="@id/quotedUserAvatar"
android:lineSpacingMultiplier="1.2"
app:layout_alignSelf="flex_start"
app:layout_flexGrow="1"
app:layout_wrapBefore="true"
tools:text="Hello, this is me!" />
<TextView
android:id="@+id/quotedMessageTime"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:textSize="12sp"
app:layout_alignSelf="center"
tools:text="16:08" />
/>
</com.google.android.flexbox.FlexboxLayout>
</RelativeLayout>

View File

@ -19,7 +19,6 @@
--> -->
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="@dimen/rv_item_view_height" android:layout_height="@dimen/rv_item_view_height"
android:layout_margin="@dimen/double_margin_between_elements" android:layout_margin="@dimen/double_margin_between_elements"