Browse Source

Move message holders to native view bindings

Signed-off-by: Andy Scherzinger <info@andy-scherzinger.de>
Andy Scherzinger 3 years ago
parent
commit
6ba541b6b1

+ 33 - 85
app/src/main/java/com/nextcloud/talk/adapters/messages/IncomingLocationMessageViewHolder.kt

@@ -3,8 +3,10 @@
  *
  *
  * @author Mario Danic
  * @author Mario Danic
  * @author Marcel Hibbe
  * @author Marcel Hibbe
- * Copyright (C) 2017-2018 Mario Danic <mario@lovelyhq.com>
+ * @author Andy Scherzinger
+ * Copyright (C) 2021 Andy Scherzinger <info@andy-scherzinger.de>
  * Copyright (C) 2021 Marcel Hibbe <dev@mhibbe.de>
  * Copyright (C) 2021 Marcel Hibbe <dev@mhibbe.de>
+ * Copyright (C) 2017-2018 Mario Danic <mario@lovelyhq.com>
  *
  *
  * This program is free software: you can redistribute it and/or modify
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * it under the terms of the GNU General Public License as published by
@@ -35,22 +37,16 @@ import android.view.MotionEvent
 import android.view.View
 import android.view.View
 import android.webkit.WebView
 import android.webkit.WebView
 import android.webkit.WebViewClient
 import android.webkit.WebViewClient
-import android.widget.ImageView
-import android.widget.RelativeLayout
-import android.widget.TextView
 import android.widget.Toast
 import android.widget.Toast
 import androidx.appcompat.content.res.AppCompatResources
 import androidx.appcompat.content.res.AppCompatResources
 import androidx.core.view.ViewCompat
 import androidx.core.view.ViewCompat
-import androidx.emoji.widget.EmojiTextView
 import autodagger.AutoInjector
 import autodagger.AutoInjector
-import butterknife.BindView
-import butterknife.ButterKnife
 import coil.load
 import coil.load
 import com.amulyakhare.textdrawable.TextDrawable
 import com.amulyakhare.textdrawable.TextDrawable
-import com.facebook.drawee.view.SimpleDraweeView
 import com.nextcloud.talk.R
 import com.nextcloud.talk.R
 import com.nextcloud.talk.application.NextcloudTalkApplication
 import com.nextcloud.talk.application.NextcloudTalkApplication
 import com.nextcloud.talk.application.NextcloudTalkApplication.Companion.sharedApplication
 import com.nextcloud.talk.application.NextcloudTalkApplication.Companion.sharedApplication
+import com.nextcloud.talk.databinding.ItemCustomIncomingLocationMessageBinding
 import com.nextcloud.talk.models.json.chat.ChatMessage
 import com.nextcloud.talk.models.json.chat.ChatMessage
 import com.nextcloud.talk.utils.ApiUtils
 import com.nextcloud.talk.utils.ApiUtils
 import com.nextcloud.talk.utils.DisplayUtils
 import com.nextcloud.talk.utils.DisplayUtils
@@ -62,6 +58,7 @@ import javax.inject.Inject
 @AutoInjector(NextcloudTalkApplication::class)
 @AutoInjector(NextcloudTalkApplication::class)
 class IncomingLocationMessageViewHolder(incomingView: View) : MessageHolders
 class IncomingLocationMessageViewHolder(incomingView: View) : MessageHolders
 .IncomingTextMessageViewHolder<ChatMessage>(incomingView) {
 .IncomingTextMessageViewHolder<ChatMessage>(incomingView) {
+    private val binding: ItemCustomIncomingLocationMessageBinding = ItemCustomIncomingLocationMessageBinding.bind(itemView)
 
 
     private val TAG = "LocMessageView"
     private val TAG = "LocMessageView"
 
 
@@ -70,42 +67,6 @@ class IncomingLocationMessageViewHolder(incomingView: View) : MessageHolders
     var locationName: String? = ""
     var locationName: String? = ""
     var locationGeoLink: String? = ""
     var locationGeoLink: String? = ""
 
 
-    @JvmField
-    @BindView(R.id.messageAuthor)
-    var messageAuthor: EmojiTextView? = null
-
-    @JvmField
-    @BindView(R.id.messageText)
-    var messageText: EmojiTextView? = null
-
-    @JvmField
-    @BindView(R.id.messageUserAvatar)
-    var messageUserAvatarView: SimpleDraweeView? = null
-
-    @JvmField
-    @BindView(R.id.messageTime)
-    var messageTimeView: TextView? = null
-
-    @JvmField
-    @BindView(R.id.quotedChatMessageView)
-    var quotedChatMessageView: RelativeLayout? = 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.quoteColoredView)
-    var quoteColoredView: View? = null
-
     @JvmField
     @JvmField
     @Inject
     @Inject
     var context: Context? = null
     var context: Context? = null
@@ -114,30 +75,19 @@ class IncomingLocationMessageViewHolder(incomingView: View) : MessageHolders
     @Inject
     @Inject
     var appPreferences: AppPreferences? = null
     var appPreferences: AppPreferences? = null
 
 
-    @JvmField
-    @BindView(R.id.webview)
-    var webview: WebView? = null
-
-    init {
-        ButterKnife.bind(
-            this,
-            itemView
-        )
-    }
-
     @SuppressLint("SetTextI18n", "SetJavaScriptEnabled", "ClickableViewAccessibility")
     @SuppressLint("SetTextI18n", "SetJavaScriptEnabled", "ClickableViewAccessibility")
     override fun onBind(message: ChatMessage) {
     override fun onBind(message: ChatMessage) {
         super.onBind(message)
         super.onBind(message)
         sharedApplication!!.componentApplication.inject(this)
         sharedApplication!!.componentApplication.inject(this)
         val author: String = message.actorDisplayName
         val author: String = message.actorDisplayName
         if (!TextUtils.isEmpty(author)) {
         if (!TextUtils.isEmpty(author)) {
-            messageAuthor!!.text = author
+            binding.messageAuthor.text = author
         } else {
         } else {
-            messageAuthor!!.setText(R.string.nc_nick_guest)
+            binding.messageAuthor.setText(R.string.nc_nick_guest)
         }
         }
 
 
         if (!message.isGrouped && !message.isOneToOneConversation) {
         if (!message.isGrouped && !message.isOneToOneConversation) {
-            messageUserAvatarView!!.visibility = View.VISIBLE
+            binding.messageUserAvatar.visibility = View.VISIBLE
             if (message.actorType == "guests") {
             if (message.actorType == "guests") {
                 // do nothing, avatar is set
                 // do nothing, avatar is set
             } else if (message.actorType == "bots" && message.actorId == "changelog") {
             } else if (message.actorType == "bots" && message.actorId == "changelog") {
@@ -145,7 +95,7 @@ class IncomingLocationMessageViewHolder(incomingView: View) : MessageHolders
                 layers[0] = AppCompatResources.getDrawable(context!!, R.drawable.ic_launcher_background)
                 layers[0] = AppCompatResources.getDrawable(context!!, R.drawable.ic_launcher_background)
                 layers[1] = AppCompatResources.getDrawable(context!!, R.drawable.ic_launcher_foreground)
                 layers[1] = AppCompatResources.getDrawable(context!!, R.drawable.ic_launcher_foreground)
                 val layerDrawable = LayerDrawable(layers)
                 val layerDrawable = LayerDrawable(layers)
-                messageUserAvatarView?.setImageDrawable(DisplayUtils.getRoundedDrawable(layerDrawable))
+                binding.messageUserAvatar.setImageDrawable(DisplayUtils.getRoundedDrawable(layerDrawable))
             } else if (message.actorType == "bots") {
             } else if (message.actorType == "bots") {
                 val drawable = TextDrawable.builder()
                 val drawable = TextDrawable.builder()
                     .beginConfig()
                     .beginConfig()
@@ -155,16 +105,16 @@ class IncomingLocationMessageViewHolder(incomingView: View) : MessageHolders
                         ">",
                         ">",
                         context!!.resources.getColor(R.color.black)
                         context!!.resources.getColor(R.color.black)
                     )
                     )
-                messageUserAvatarView!!.visibility = View.VISIBLE
-                messageUserAvatarView?.setImageDrawable(drawable)
+                binding.messageUserAvatar.visibility = View.VISIBLE
+                binding.messageUserAvatar.setImageDrawable(drawable)
             }
             }
         } else {
         } else {
             if (message.isOneToOneConversation) {
             if (message.isOneToOneConversation) {
-                messageUserAvatarView!!.visibility = View.GONE
+                binding.messageUserAvatar.visibility = View.GONE
             } else {
             } else {
-                messageUserAvatarView!!.visibility = View.INVISIBLE
+                binding.messageUserAvatar.visibility = View.INVISIBLE
             }
             }
-            messageAuthor!!.visibility = View.GONE
+            binding.messageAuthor.visibility = View.GONE
         }
         }
 
 
         val resources = itemView.resources
         val resources = itemView.resources
@@ -188,47 +138,45 @@ class IncomingLocationMessageViewHolder(incomingView: View) : MessageHolders
         )
         )
         ViewCompat.setBackground(bubble, bubbleDrawable)
         ViewCompat.setBackground(bubble, bubbleDrawable)
 
 
-        val messageParameters = message.messageParameters
-
         itemView.isSelected = false
         itemView.isSelected = false
-        messageTimeView!!.setTextColor(context?.resources!!.getColor(R.color.warm_grey_four))
+        binding.messageTime.setTextColor(context?.resources!!.getColor(R.color.warm_grey_four))
 
 
         val textSize = context?.resources!!.getDimension(R.dimen.chat_text_size)
         val textSize = context?.resources!!.getDimension(R.dimen.chat_text_size)
-        messageText!!.setTextSize(TypedValue.COMPLEX_UNIT_PX, textSize)
-        messageText!!.text = message.text
-        messageText!!.isEnabled = false
+        binding.messageText.setTextSize(TypedValue.COMPLEX_UNIT_PX, textSize)
+        binding.messageText.text = message.text
+        binding.messageText.isEnabled = false
 
 
         // parent message handling
         // parent message handling
-
         if (!message.isDeleted && message.parentMessage != null) {
         if (!message.isDeleted && message.parentMessage != null) {
             val parentChatMessage = message.parentMessage
             val parentChatMessage = message.parentMessage
             parentChatMessage.activeUser = message.activeUser
             parentChatMessage.activeUser = message.activeUser
             parentChatMessage.imageUrl?.let {
             parentChatMessage.imageUrl?.let {
-                quotedMessagePreview?.visibility = View.VISIBLE
-                quotedMessagePreview?.load(it) {
+                binding.messageQuote.quotedMessageImage.visibility = View.VISIBLE
+                binding.messageQuote.quotedMessageImage.load(it) {
                     addHeader(
                     addHeader(
                         "Authorization",
                         "Authorization",
                         ApiUtils.getCredentials(message.activeUser.username, message.activeUser.token)
                         ApiUtils.getCredentials(message.activeUser.username, message.activeUser.token)
                     )
                     )
                 }
                 }
             } ?: run {
             } ?: run {
-                quotedMessagePreview?.visibility = View.GONE
+                binding.messageQuote.quotedMessageImage.visibility = View.GONE
             }
             }
-            quotedUserName?.text = parentChatMessage.actorDisplayName
+            binding.messageQuote.quotedMessageAuthor.text = parentChatMessage.actorDisplayName
                 ?: context!!.getText(R.string.nc_nick_guest)
                 ?: context!!.getText(R.string.nc_nick_guest)
-            quotedMessage?.text = parentChatMessage.text
+            binding.messageQuote.quotedMessage.text = parentChatMessage.text
 
 
-            quotedUserName?.setTextColor(context!!.resources.getColor(R.color.textColorMaxContrast))
+            binding.messageQuote.quotedMessageAuthor
+                .setTextColor(context!!.resources.getColor(R.color.textColorMaxContrast))
 
 
             if (parentChatMessage.actorId?.equals(message.activeUser.userId) == true) {
             if (parentChatMessage.actorId?.equals(message.activeUser.userId) == true) {
-                quoteColoredView?.setBackgroundResource(R.color.colorPrimary)
+                binding.messageQuote.quoteColoredView.setBackgroundResource(R.color.colorPrimary)
             } else {
             } else {
-                quoteColoredView?.setBackgroundResource(R.color.textColorMaxContrast)
+                binding.messageQuote.quoteColoredView.setBackgroundResource(R.color.textColorMaxContrast)
             }
             }
 
 
-            quotedChatMessageView?.visibility = View.VISIBLE
+            binding.messageQuote.quotedChatMessageView.visibility = View.VISIBLE
         } else {
         } else {
-            quotedChatMessageView?.visibility = View.GONE
+            binding.messageQuote.quotedChatMessageView.visibility = View.GONE
         }
         }
 
 
         // geo-location
         // geo-location
@@ -245,9 +193,9 @@ class IncomingLocationMessageViewHolder(incomingView: View) : MessageHolders
             }
             }
         }
         }
 
 
-        webview?.settings?.javaScriptEnabled = true
+        binding.webview.settings?.javaScriptEnabled = true
 
 
-        webview?.webViewClient = object : WebViewClient() {
+        binding.webview.webViewClient = object : WebViewClient() {
             override fun shouldOverrideUrlLoading(view: WebView?, url: String?): Boolean {
             override fun shouldOverrideUrlLoading(view: WebView?, url: String?): Boolean {
                 return if (url != null && (url.startsWith("http://") || url.startsWith("https://"))
                 return if (url != null && (url.startsWith("http://") || url.startsWith("https://"))
                 ) {
                 ) {
@@ -268,9 +216,9 @@ class IncomingLocationMessageViewHolder(incomingView: View) : MessageHolders
         urlStringBuffer.append("&locationName=" + URLEncoder.encode(locationName))
         urlStringBuffer.append("&locationName=" + URLEncoder.encode(locationName))
         urlStringBuffer.append("&locationGeoLink=" + URLEncoder.encode(locationGeoLink))
         urlStringBuffer.append("&locationGeoLink=" + URLEncoder.encode(locationGeoLink))
 
 
-        webview?.loadUrl(urlStringBuffer.toString())
+        binding.webview.loadUrl(urlStringBuffer.toString())
 
 
-        webview?.setOnTouchListener(object : View.OnTouchListener {
+        binding.webview.setOnTouchListener(object : View.OnTouchListener {
             override fun onTouch(v: View?, event: MotionEvent?): Boolean {
             override fun onTouch(v: View?, event: MotionEvent?): Boolean {
                 when (event?.action) {
                 when (event?.action) {
                     MotionEvent.ACTION_UP -> openGeoLink()
                     MotionEvent.ACTION_UP -> openGeoLink()

+ 45 - 0
app/src/main/java/com/nextcloud/talk/adapters/messages/IncomingPreviewMessageViewHolder.java

@@ -0,0 +1,45 @@
+/*
+ * Nextcloud Talk application
+ *
+ * @author Andy Scherzinger
+ * Copyright (C) 2021 Andy Scherzinger <info@andy-scherzinger.de>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+package com.nextcloud.talk.adapters.messages;
+
+import android.view.View;
+import android.widget.ProgressBar;
+
+import com.nextcloud.talk.databinding.ItemCustomIncomingPreviewMessageBinding;
+
+import androidx.emoji.widget.EmojiTextView;
+
+public class IncomingPreviewMessageViewHolder extends MagicPreviewMessageViewHolder {
+    private final ItemCustomIncomingPreviewMessageBinding binding;
+
+    public IncomingPreviewMessageViewHolder(View itemView) {
+        super(itemView);
+        binding = ItemCustomIncomingPreviewMessageBinding.bind(itemView);
+    }
+
+    public EmojiTextView getMessageText()  {
+        return binding.messageText;
+    }
+
+    public ProgressBar getProgressBar() {
+        return binding.progressBar;
+    }
+}

+ 31 - 73
app/src/main/java/com/nextcloud/talk/adapters/messages/MagicIncomingTextMessageViewHolder.kt

@@ -2,6 +2,8 @@
  * Nextcloud Talk application
  * Nextcloud Talk application
  *
  *
  * @author Mario Danic
  * @author Mario Danic
+ * @author Andy Scherzinger
+ * Copyright (C) 2021 Andy Scherzinger <info@andy-scherzinger.de>
  * Copyright (C) 2017-2018 Mario Danic <mario@lovelyhq.com>
  * Copyright (C) 2017-2018 Mario Danic <mario@lovelyhq.com>
  *
  *
  * This program is free software: you can redistribute it and/or modify
  * This program is free software: you can redistribute it and/or modify
@@ -30,20 +32,14 @@ import android.text.SpannableString
 import android.text.TextUtils
 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.RelativeLayout
-import android.widget.TextView
 import androidx.core.view.ViewCompat
 import androidx.core.view.ViewCompat
-import androidx.emoji.widget.EmojiTextView
 import autodagger.AutoInjector
 import autodagger.AutoInjector
-import butterknife.BindView
-import butterknife.ButterKnife
 import coil.load
 import coil.load
 import com.amulyakhare.textdrawable.TextDrawable
 import com.amulyakhare.textdrawable.TextDrawable
-import com.facebook.drawee.view.SimpleDraweeView
 import com.nextcloud.talk.R
 import com.nextcloud.talk.R
 import com.nextcloud.talk.application.NextcloudTalkApplication
 import com.nextcloud.talk.application.NextcloudTalkApplication
 import com.nextcloud.talk.application.NextcloudTalkApplication.Companion.sharedApplication
 import com.nextcloud.talk.application.NextcloudTalkApplication.Companion.sharedApplication
+import com.nextcloud.talk.databinding.ItemCustomIncomingTextMessageBinding
 import com.nextcloud.talk.models.json.chat.ChatMessage
 import com.nextcloud.talk.models.json.chat.ChatMessage
 import com.nextcloud.talk.ui.recyclerview.MessageSwipeCallback
 import com.nextcloud.talk.ui.recyclerview.MessageSwipeCallback
 import com.nextcloud.talk.utils.ApiUtils
 import com.nextcloud.talk.utils.ApiUtils
@@ -57,41 +53,7 @@ import javax.inject.Inject
 class MagicIncomingTextMessageViewHolder(itemView: View) : MessageHolders
 class MagicIncomingTextMessageViewHolder(itemView: View) : MessageHolders
 .IncomingTextMessageViewHolder<ChatMessage>(itemView) {
 .IncomingTextMessageViewHolder<ChatMessage>(itemView) {
 
 
-    @JvmField
-    @BindView(R.id.messageAuthor)
-    var messageAuthor: EmojiTextView? = null
-
-    @JvmField
-    @BindView(R.id.messageText)
-    var messageText: EmojiTextView? = null
-
-    @JvmField
-    @BindView(R.id.messageUserAvatar)
-    var messageUserAvatarView: SimpleDraweeView? = null
-
-    @JvmField
-    @BindView(R.id.messageTime)
-    var messageTimeView: TextView? = null
-
-    @JvmField
-    @BindView(R.id.quotedChatMessageView)
-    var quotedChatMessageView: RelativeLayout? = 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.quoteColoredView)
-    var quoteColoredView: View? = null
+    private val binding: ItemCustomIncomingTextMessageBinding = ItemCustomIncomingTextMessageBinding.bind(itemView)
 
 
     @JvmField
     @JvmField
     @Inject
     @Inject
@@ -106,13 +68,13 @@ class MagicIncomingTextMessageViewHolder(itemView: View) : MessageHolders
         sharedApplication!!.componentApplication.inject(this)
         sharedApplication!!.componentApplication.inject(this)
         val author: String = message.actorDisplayName
         val author: String = message.actorDisplayName
         if (!TextUtils.isEmpty(author)) {
         if (!TextUtils.isEmpty(author)) {
-            messageAuthor!!.text = author
+            binding.messageAuthor.text = author
         } else {
         } else {
-            messageAuthor!!.setText(R.string.nc_nick_guest)
+            binding.messageAuthor.setText(R.string.nc_nick_guest)
         }
         }
 
 
         if (!message.isGrouped && !message.isOneToOneConversation) {
         if (!message.isGrouped && !message.isOneToOneConversation) {
-            messageUserAvatarView!!.visibility = View.VISIBLE
+            binding.messageUserAvatar.visibility = View.VISIBLE
             if (message.actorType == "guests") {
             if (message.actorType == "guests") {
                 // do nothing, avatar is set
                 // do nothing, avatar is set
             } else if (message.actorType == "bots" && message.actorId == "changelog") {
             } else if (message.actorType == "bots" && message.actorId == "changelog") {
@@ -120,7 +82,7 @@ class MagicIncomingTextMessageViewHolder(itemView: View) : MessageHolders
                 layers[0] = context?.getDrawable(R.drawable.ic_launcher_background)
                 layers[0] = context?.getDrawable(R.drawable.ic_launcher_background)
                 layers[1] = context?.getDrawable(R.drawable.ic_launcher_foreground)
                 layers[1] = context?.getDrawable(R.drawable.ic_launcher_foreground)
                 val layerDrawable = LayerDrawable(layers)
                 val layerDrawable = LayerDrawable(layers)
-                messageUserAvatarView?.setImageDrawable(DisplayUtils.getRoundedDrawable(layerDrawable))
+                binding.messageUserAvatar.setImageDrawable(DisplayUtils.getRoundedDrawable(layerDrawable))
             } else if (message.actorType == "bots") {
             } else if (message.actorType == "bots") {
                 val drawable = TextDrawable.builder()
                 val drawable = TextDrawable.builder()
                     .beginConfig()
                     .beginConfig()
@@ -130,16 +92,16 @@ class MagicIncomingTextMessageViewHolder(itemView: View) : MessageHolders
                         ">",
                         ">",
                         context!!.resources.getColor(R.color.black)
                         context!!.resources.getColor(R.color.black)
                     )
                     )
-                messageUserAvatarView!!.visibility = View.VISIBLE
-                messageUserAvatarView?.setImageDrawable(drawable)
+                binding.messageUserAvatar.visibility = View.VISIBLE
+                binding.messageUserAvatar.setImageDrawable(drawable)
             }
             }
         } else {
         } else {
             if (message.isOneToOneConversation) {
             if (message.isOneToOneConversation) {
-                messageUserAvatarView!!.visibility = View.GONE
+                binding.messageUserAvatar.visibility = View.GONE
             } else {
             } else {
-                messageUserAvatarView!!.visibility = View.INVISIBLE
+                binding.messageUserAvatar.visibility = View.INVISIBLE
             }
             }
-            messageAuthor!!.visibility = View.GONE
+            binding.messageAuthor.visibility = View.GONE
         }
         }
 
 
         val resources = itemView.resources
         val resources = itemView.resources
@@ -166,7 +128,7 @@ class MagicIncomingTextMessageViewHolder(itemView: View) : MessageHolders
         val messageParameters = message.messageParameters
         val messageParameters = message.messageParameters
 
 
         itemView.isSelected = false
         itemView.isSelected = false
-        messageTimeView!!.setTextColor(context?.resources!!.getColor(R.color.warm_grey_four))
+        binding.messageTime.setTextColor(context?.resources!!.getColor(R.color.warm_grey_four))
 
 
         var messageString: Spannable = SpannableString(message.text)
         var messageString: Spannable = SpannableString(message.text)
 
 
@@ -183,7 +145,7 @@ class MagicIncomingTextMessageViewHolder(itemView: View) : MessageHolders
                     ) {
                     ) {
                         if (individualHashMap["id"] == message.activeUser!!.userId) {
                         if (individualHashMap["id"] == message.activeUser!!.userId) {
                             messageString = DisplayUtils.searchAndReplaceWithMentionSpan(
                             messageString = DisplayUtils.searchAndReplaceWithMentionSpan(
-                                messageText!!.context,
+                                binding.messageText.context,
                                 messageString,
                                 messageString,
                                 individualHashMap["id"]!!,
                                 individualHashMap["id"]!!,
                                 individualHashMap["name"]!!,
                                 individualHashMap["name"]!!,
@@ -193,7 +155,7 @@ class MagicIncomingTextMessageViewHolder(itemView: View) : MessageHolders
                             )
                             )
                         } else {
                         } else {
                             messageString = DisplayUtils.searchAndReplaceWithMentionSpan(
                             messageString = DisplayUtils.searchAndReplaceWithMentionSpan(
-                                messageText!!.context,
+                                binding.messageText.context,
                                 messageString,
                                 messageString,
                                 individualHashMap["id"]!!,
                                 individualHashMap["id"]!!,
                                 individualHashMap["name"]!!,
                                 individualHashMap["name"]!!,
@@ -213,49 +175,45 @@ class MagicIncomingTextMessageViewHolder(itemView: View) : MessageHolders
         } else if (TextMatchers.isMessageWithSingleEmoticonOnly(message.text)) {
         } else if (TextMatchers.isMessageWithSingleEmoticonOnly(message.text)) {
             textSize = (textSize * 2.5).toFloat()
             textSize = (textSize * 2.5).toFloat()
             itemView.isSelected = true
             itemView.isSelected = true
-            messageAuthor!!.visibility = View.GONE
+            binding.messageAuthor.visibility = View.GONE
         }
         }
 
 
-        messageText!!.setTextSize(TypedValue.COMPLEX_UNIT_PX, textSize)
-        messageText!!.text = messageString
+        binding.messageText.setTextSize(TypedValue.COMPLEX_UNIT_PX, textSize)
+        binding.messageText.text = messageString
 
 
         // parent message handling
         // parent message handling
-
         if (!message.isDeleted && message.parentMessage != null) {
         if (!message.isDeleted && message.parentMessage != null) {
-            var parentChatMessage = message.parentMessage
+            val parentChatMessage = message.parentMessage
             parentChatMessage.activeUser = message.activeUser
             parentChatMessage.activeUser = message.activeUser
             parentChatMessage.imageUrl?.let {
             parentChatMessage.imageUrl?.let {
-                quotedMessagePreview?.visibility = View.VISIBLE
-                quotedMessagePreview?.load(it) {
+                binding.messageQuote.quotedMessageImage.visibility = View.VISIBLE
+                binding.messageQuote.quotedMessageImage.load(it) {
                     addHeader(
                     addHeader(
                         "Authorization",
                         "Authorization",
                         ApiUtils.getCredentials(message.activeUser.username, message.activeUser.token)
                         ApiUtils.getCredentials(message.activeUser.username, message.activeUser.token)
                     )
                     )
                 }
                 }
             } ?: run {
             } ?: run {
-                quotedMessagePreview?.visibility = View.GONE
+                binding.messageQuote.quotedMessageImage.visibility = View.GONE
             }
             }
-            quotedUserName?.text = parentChatMessage.actorDisplayName
+            binding.messageQuote.quotedMessageAuthor.text = parentChatMessage.actorDisplayName
                 ?: context!!.getText(R.string.nc_nick_guest)
                 ?: context!!.getText(R.string.nc_nick_guest)
-            quotedMessage?.text = parentChatMessage.text
+            binding.messageQuote.quotedMessage.text = parentChatMessage.text
 
 
-            quotedUserName?.setTextColor(context!!.resources.getColor(R.color.textColorMaxContrast))
+            binding.messageQuote.quotedMessageAuthor
+                .setTextColor(context!!.resources.getColor(R.color.textColorMaxContrast))
 
 
             if (parentChatMessage.actorId?.equals(message.activeUser.userId) == true) {
             if (parentChatMessage.actorId?.equals(message.activeUser.userId) == true) {
-                quoteColoredView?.setBackgroundResource(R.color.colorPrimary)
+                binding.messageQuote.quoteColoredView.setBackgroundResource(R.color.colorPrimary)
             } else {
             } else {
-                quoteColoredView?.setBackgroundResource(R.color.textColorMaxContrast)
+                binding.messageQuote.quoteColoredView.setBackgroundResource(R.color.textColorMaxContrast)
             }
             }
 
 
-            quotedChatMessageView?.visibility = View.VISIBLE
+            binding.messageQuote.quotedChatMessageView.visibility = View.VISIBLE
         } else {
         } else {
-            quotedChatMessageView?.visibility = View.GONE
+            binding.messageQuote.quotedChatMessageView.visibility = View.GONE
         }
         }
 
 
         itemView.setTag(MessageSwipeCallback.REPLYABLE_VIEW_TAG, message.isReplyable)
         itemView.setTag(MessageSwipeCallback.REPLYABLE_VIEW_TAG, message.isReplyable)
     }
     }
-
-    init {
-        ButterKnife.bind(this, itemView)
-    }
 }
 }

+ 24 - 63
app/src/main/java/com/nextcloud/talk/adapters/messages/MagicOutcomingTextMessageViewHolder.kt

@@ -2,6 +2,8 @@
  * Nextcloud Talk application
  * Nextcloud Talk application
  *
  *
  * @author Mario Danic
  * @author Mario Danic
+ * @author Andy Scherzinger
+ * Copyright (C) 2021 Andy Scherzinger <info@andy-scherzinger.de>
  * Copyright (C) 2017-2018 Mario Danic <mario@lovelyhq.com>
  * Copyright (C) 2017-2018 Mario Danic <mario@lovelyhq.com>
  *
  *
  * This program is free software: you can redistribute it and/or modify
  * This program is free software: you can redistribute it and/or modify
@@ -27,19 +29,14 @@ import android.text.Spannable
 import android.text.SpannableString
 import android.text.SpannableString
 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 androidx.core.view.ViewCompat
 import androidx.core.view.ViewCompat
-import androidx.emoji.widget.EmojiTextView
 import autodagger.AutoInjector
 import autodagger.AutoInjector
-import butterknife.BindView
-import butterknife.ButterKnife
 import coil.load
 import coil.load
 import com.google.android.flexbox.FlexboxLayout
 import com.google.android.flexbox.FlexboxLayout
 import com.nextcloud.talk.R
 import com.nextcloud.talk.R
 import com.nextcloud.talk.application.NextcloudTalkApplication
 import com.nextcloud.talk.application.NextcloudTalkApplication
 import com.nextcloud.talk.application.NextcloudTalkApplication.Companion.sharedApplication
 import com.nextcloud.talk.application.NextcloudTalkApplication.Companion.sharedApplication
+import com.nextcloud.talk.databinding.ItemCustomOutcomingTextMessageBinding
 import com.nextcloud.talk.models.json.chat.ChatMessage
 import com.nextcloud.talk.models.json.chat.ChatMessage
 import com.nextcloud.talk.models.json.chat.ReadStatus
 import com.nextcloud.talk.models.json.chat.ReadStatus
 import com.nextcloud.talk.ui.recyclerview.MessageSwipeCallback
 import com.nextcloud.talk.ui.recyclerview.MessageSwipeCallback
@@ -53,57 +50,21 @@ import javax.inject.Inject
 
 
 @AutoInjector(NextcloudTalkApplication::class)
 @AutoInjector(NextcloudTalkApplication::class)
 class MagicOutcomingTextMessageViewHolder(itemView: View) : OutcomingTextMessageViewHolder<ChatMessage>(itemView) {
 class MagicOutcomingTextMessageViewHolder(itemView: View) : OutcomingTextMessageViewHolder<ChatMessage>(itemView) {
-    @JvmField
-    @BindView(R.id.messageText)
-    var messageText: EmojiTextView? = null
-
-    @JvmField
-    @BindView(R.id.messageTime)
-    var messageTimeView: TextView? = null
-
-    @JvmField
-    @BindView(R.id.quotedChatMessageView)
-    var quotedChatMessageView: RelativeLayout? = 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.quoteColoredView)
-    var quoteColoredView: View? = null
-
-    @JvmField
-    @BindView(R.id.checkMark)
-    var checkMark: ImageView? = null
+    private val binding: ItemCustomOutcomingTextMessageBinding = ItemCustomOutcomingTextMessageBinding.bind(itemView)
+    private val realView: View = itemView
 
 
     @JvmField
     @JvmField
     @Inject
     @Inject
     var context: Context? = null
     var context: Context? = null
 
 
-    private val realView: View
-
-    init {
-        ButterKnife.bind(this, itemView)
-        this.realView = itemView
-    }
-
     override fun onBind(message: ChatMessage) {
     override fun onBind(message: ChatMessage) {
         super.onBind(message)
         super.onBind(message)
         sharedApplication!!.componentApplication.inject(this)
         sharedApplication!!.componentApplication.inject(this)
         val messageParameters: HashMap<String, HashMap<String, String>>? = message.messageParameters
         val messageParameters: HashMap<String, HashMap<String, String>>? = message.messageParameters
         var messageString: Spannable = SpannableString(message.text)
         var messageString: Spannable = SpannableString(message.text)
         realView.isSelected = false
         realView.isSelected = false
-        messageTimeView!!.setTextColor(context!!.resources.getColor(R.color.white60))
-        val layoutParams = messageTimeView!!.layoutParams as FlexboxLayout.LayoutParams
+        binding.messageTime.setTextColor(context!!.resources.getColor(R.color.white60))
+        val layoutParams = binding.messageTime.layoutParams as FlexboxLayout.LayoutParams
         layoutParams.isWrapBefore = false
         layoutParams.isWrapBefore = false
         var textSize = context!!.resources.getDimension(R.dimen.chat_text_size)
         var textSize = context!!.resources.getDimension(R.dimen.chat_text_size)
         if (messageParameters != null && messageParameters.size > 0) {
         if (messageParameters != null && messageParameters.size > 0) {
@@ -115,7 +76,7 @@ class MagicOutcomingTextMessageViewHolder(itemView: View) : OutcomingTextMessage
                         ) || individualHashMap["type"] == "call"
                         ) || individualHashMap["type"] == "call"
                     ) {
                     ) {
                         messageString = searchAndReplaceWithMentionSpan(
                         messageString = searchAndReplaceWithMentionSpan(
-                            messageText!!.context,
+                            binding.messageText.context,
                             messageString,
                             messageString,
                             individualHashMap["id"]!!,
                             individualHashMap["id"]!!,
                             individualHashMap["name"]!!,
                             individualHashMap["name"]!!,
@@ -136,7 +97,7 @@ class MagicOutcomingTextMessageViewHolder(itemView: View) : OutcomingTextMessage
         } 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
             layoutParams.isWrapBefore = true
-            messageTimeView!!.setTextColor(context!!.resources.getColor(R.color.warm_grey_four))
+            binding.messageTime.setTextColor(context!!.resources.getColor(R.color.warm_grey_four))
             realView.isSelected = true
             realView.isSelected = true
         }
         }
         val resources = sharedApplication!!.resources
         val resources = sharedApplication!!.resources
@@ -162,9 +123,9 @@ class MagicOutcomingTextMessageViewHolder(itemView: View) : OutcomingTextMessage
             )
             )
             ViewCompat.setBackground(bubble, bubbleDrawable)
             ViewCompat.setBackground(bubble, bubbleDrawable)
         }
         }
-        messageText!!.setTextSize(TypedValue.COMPLEX_UNIT_PX, textSize)
-        messageTimeView!!.layoutParams = layoutParams
-        messageText!!.text = messageString
+        binding.messageText.setTextSize(TypedValue.COMPLEX_UNIT_PX, textSize)
+        binding.messageTime.layoutParams = layoutParams
+        binding.messageText.text = messageString
 
 
         // parent message handling
         // parent message handling
 
 
@@ -172,27 +133,27 @@ class MagicOutcomingTextMessageViewHolder(itemView: View) : OutcomingTextMessage
             var parentChatMessage = message.parentMessage
             var parentChatMessage = message.parentMessage
             parentChatMessage.activeUser = message.activeUser
             parentChatMessage.activeUser = message.activeUser
             parentChatMessage.imageUrl?.let {
             parentChatMessage.imageUrl?.let {
-                quotedMessagePreview?.visibility = View.VISIBLE
-                quotedMessagePreview?.load(it) {
+                binding.messageQuote.quotedMessageImage.visibility = View.VISIBLE
+                binding.messageQuote.quotedMessageImage.load(it) {
                     addHeader(
                     addHeader(
                         "Authorization",
                         "Authorization",
                         ApiUtils.getCredentials(message.activeUser.username, message.activeUser.token)
                         ApiUtils.getCredentials(message.activeUser.username, message.activeUser.token)
                     )
                     )
                 }
                 }
             } ?: run {
             } ?: run {
-                quotedMessagePreview?.visibility = View.GONE
+                binding.messageQuote.quotedMessageImage.visibility = View.GONE
             }
             }
-            quotedUserName?.text = parentChatMessage.actorDisplayName
+            binding.messageQuote.quotedMessageAuthor.text = parentChatMessage.actorDisplayName
                 ?: context!!.getText(R.string.nc_nick_guest)
                 ?: 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))
+            binding.messageQuote.quotedMessage.text = parentChatMessage.text
+            binding.messageQuote.quotedMessage.setTextColor(context!!.resources.getColor(R.color.nc_outcoming_text_default))
+            binding.messageQuote.quotedMessageAuthor.setTextColor(context!!.resources.getColor(R.color.nc_grey))
 
 
-            quoteColoredView?.setBackgroundResource(R.color.white)
+            binding.messageQuote.quoteColoredView.setBackgroundResource(R.color.white)
 
 
-            quotedChatMessageView?.visibility = View.VISIBLE
+            binding.messageQuote.quotedChatMessageView.visibility = View.VISIBLE
         } else {
         } else {
-            quotedChatMessageView?.visibility = View.GONE
+            binding.messageQuote.quotedChatMessageView.visibility = View.GONE
         }
         }
 
 
         val readStatusDrawableInt = when (message.readStatus) {
         val readStatusDrawableInt = when (message.readStatus) {
@@ -210,11 +171,11 @@ class MagicOutcomingTextMessageViewHolder(itemView: View) : OutcomingTextMessage
         readStatusDrawableInt?.let { drawableInt ->
         readStatusDrawableInt?.let { drawableInt ->
             context?.resources?.getDrawable(drawableInt, null)?.let {
             context?.resources?.getDrawable(drawableInt, null)?.let {
                 it.setColorFilter(context?.resources!!.getColor(R.color.white60), PorterDuff.Mode.SRC_ATOP)
                 it.setColorFilter(context?.resources!!.getColor(R.color.white60), PorterDuff.Mode.SRC_ATOP)
-                checkMark?.setImageDrawable(it)
+                binding.checkMark.setImageDrawable(it)
             }
             }
         }
         }
 
 
-        checkMark?.setContentDescription(readStatusContentDescriptionString)
+        binding.checkMark.setContentDescription(readStatusContentDescriptionString)
 
 
         itemView.setTag(MessageSwipeCallback.REPLYABLE_VIEW_TAG, message.isReplyable)
         itemView.setTag(MessageSwipeCallback.REPLYABLE_VIEW_TAG, message.isReplyable)
     }
     }

+ 23 - 25
app/src/main/java/com/nextcloud/talk/adapters/messages/MagicPreviewMessageViewHolder.java

@@ -3,8 +3,10 @@
  *
  *
  * @author Mario Danic
  * @author Mario Danic
  * @author Marcel Hibbe
  * @author Marcel Hibbe
- * Copyright (C) 2017-2018 Mario Danic <mario@lovelyhq.com>
+ * @author Andy Scherzinger
+ * Copyright (C) 2021 Andy Scherzinger <info@andy-scherzinger.de>
  * Copyright (C) 2021 Marcel Hibbe <dev@mhibbe.de>
  * Copyright (C) 2021 Marcel Hibbe <dev@mhibbe.de>
+ * Copyright (C) 2017-2018 Mario Danic <mario@lovelyhq.com>
  *
  *
  * This program is free software: you can redistribute it and/or modify
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * it under the terms of the GNU General Public License as published by
@@ -35,6 +37,7 @@ import android.util.Log;
 import android.view.Gravity;
 import android.view.Gravity;
 import android.view.View;
 import android.view.View;
 import android.widget.PopupMenu;
 import android.widget.PopupMenu;
+import android.widget.ProgressBar;
 
 
 import com.google.common.util.concurrent.ListenableFuture;
 import com.google.common.util.concurrent.ListenableFuture;
 import com.nextcloud.talk.R;
 import com.nextcloud.talk.R;
@@ -45,6 +48,7 @@ import com.nextcloud.talk.application.NextcloudTalkApplication;
 import com.nextcloud.talk.components.filebrowser.models.BrowserFile;
 import com.nextcloud.talk.components.filebrowser.models.BrowserFile;
 import com.nextcloud.talk.components.filebrowser.models.DavResponse;
 import com.nextcloud.talk.components.filebrowser.models.DavResponse;
 import com.nextcloud.talk.components.filebrowser.webdav.ReadFilesystemOperation;
 import com.nextcloud.talk.components.filebrowser.webdav.ReadFilesystemOperation;
+import com.nextcloud.talk.databinding.ItemCustomIncomingPreviewMessageBinding;
 import com.nextcloud.talk.jobs.DownloadFileToCacheWorker;
 import com.nextcloud.talk.jobs.DownloadFileToCacheWorker;
 import com.nextcloud.talk.models.database.CapabilitiesUtil;
 import com.nextcloud.talk.models.database.CapabilitiesUtil;
 import com.nextcloud.talk.models.database.UserEntity;
 import com.nextcloud.talk.models.database.UserEntity;
@@ -70,8 +74,6 @@ import androidx.work.OneTimeWorkRequest;
 import androidx.work.WorkInfo;
 import androidx.work.WorkInfo;
 import androidx.work.WorkManager;
 import androidx.work.WorkManager;
 import autodagger.AutoInjector;
 import autodagger.AutoInjector;
-import butterknife.BindView;
-import butterknife.ButterKnife;
 import io.reactivex.Single;
 import io.reactivex.Single;
 import io.reactivex.SingleObserver;
 import io.reactivex.SingleObserver;
 import io.reactivex.annotations.NonNull;
 import io.reactivex.annotations.NonNull;
@@ -82,15 +84,10 @@ import okhttp3.OkHttpClient;
 import static com.nextcloud.talk.ui.recyclerview.MessageSwipeCallback.REPLYABLE_VIEW_TAG;
 import static com.nextcloud.talk.ui.recyclerview.MessageSwipeCallback.REPLYABLE_VIEW_TAG;
 
 
 @AutoInjector(NextcloudTalkApplication.class)
 @AutoInjector(NextcloudTalkApplication.class)
-public class MagicPreviewMessageViewHolder extends MessageHolders.IncomingImageMessageViewHolder<ChatMessage> {
+public abstract class MagicPreviewMessageViewHolder extends MessageHolders.IncomingImageMessageViewHolder<ChatMessage> {
 
 
     private static final String TAG = "PreviewMsgViewHolder";
     private static final String TAG = "PreviewMsgViewHolder";
 
 
-    @BindView(R.id.messageText)
-    EmojiTextView messageText;
-
-    View progressBar;
-
     @Inject
     @Inject
     Context context;
     Context context;
 
 
@@ -99,8 +96,6 @@ public class MagicPreviewMessageViewHolder extends MessageHolders.IncomingImageM
 
 
     public MagicPreviewMessageViewHolder(View itemView) {
     public MagicPreviewMessageViewHolder(View itemView) {
         super(itemView);
         super(itemView);
-        ButterKnife.bind(this, itemView);
-        progressBar = itemView.findViewById(R.id.progress_bar);
         NextcloudTalkApplication.Companion.getSharedApplication().getComponentApplication().inject(this);
         NextcloudTalkApplication.Companion.getSharedApplication().getComponentApplication().inject(this);
     }
     }
 
 
@@ -131,7 +126,7 @@ public class MagicPreviewMessageViewHolder extends MessageHolders.IncomingImageM
 
 
         if (message.getMessageType() == ChatMessage.MessageType.SINGLE_NC_ATTACHMENT_MESSAGE) {
         if (message.getMessageType() == ChatMessage.MessageType.SINGLE_NC_ATTACHMENT_MESSAGE) {
             String fileName = message.getSelectedIndividualHashMap().get("name");
             String fileName = message.getSelectedIndividualHashMap().get("name");
-            messageText.setText(fileName);
+            getMessageText().setText(fileName);
             if (message.getSelectedIndividualHashMap().containsKey("mimetype")) {
             if (message.getSelectedIndividualHashMap().containsKey("mimetype")) {
                 String mimetype = message.getSelectedIndividualHashMap().get("mimetype");
                 String mimetype = message.getSelectedIndividualHashMap().get("mimetype");
                 int drawableResourceId = DrawableUtils.INSTANCE.getDrawableResourceIdForMimeType(mimetype);
                 int drawableResourceId = DrawableUtils.INSTANCE.getDrawableResourceIdForMimeType(mimetype);
@@ -165,7 +160,7 @@ public class MagicPreviewMessageViewHolder extends MessageHolders.IncomingImageM
             try {
             try {
                 for (WorkInfo workInfo : workers.get()) {
                 for (WorkInfo workInfo : workers.get()) {
                     if (workInfo.getState() == WorkInfo.State.RUNNING || workInfo.getState() == WorkInfo.State.ENQUEUED) {
                     if (workInfo.getState() == WorkInfo.State.RUNNING || workInfo.getState() == WorkInfo.State.ENQUEUED) {
-                        progressBar.setVisibility(View.VISIBLE);
+                        getProgressBar().setVisibility(View.VISIBLE);
 
 
                         String mimetype = message.getSelectedIndividualHashMap().get("mimetype");
                         String mimetype = message.getSelectedIndividualHashMap().get("mimetype");
 
 
@@ -178,11 +173,11 @@ public class MagicPreviewMessageViewHolder extends MessageHolders.IncomingImageM
                 Log.e(TAG, "Error when checking if worker already exists", e);
                 Log.e(TAG, "Error when checking if worker already exists", e);
             }
             }
         } else if (message.getMessageType() == ChatMessage.MessageType.SINGLE_LINK_GIPHY_MESSAGE) {
         } else if (message.getMessageType() == ChatMessage.MessageType.SINGLE_LINK_GIPHY_MESSAGE) {
-            messageText.setText("GIPHY");
-            DisplayUtils.setClickableString("GIPHY", "https://giphy.com", messageText);
+            getMessageText().setText("GIPHY");
+            DisplayUtils.setClickableString("GIPHY", "https://giphy.com", getMessageText());
         } else if (message.getMessageType() == ChatMessage.MessageType.SINGLE_LINK_TENOR_MESSAGE) {
         } else if (message.getMessageType() == ChatMessage.MessageType.SINGLE_LINK_TENOR_MESSAGE) {
-            messageText.setText("Tenor");
-            DisplayUtils.setClickableString("Tenor", "https://tenor.com", messageText);
+            getMessageText().setText("Tenor");
+            DisplayUtils.setClickableString("Tenor", "https://tenor.com", getMessageText());
         } else {
         } else {
             if (message.getMessageType().equals(ChatMessage.MessageType.SINGLE_LINK_IMAGE_MESSAGE)) {
             if (message.getMessageType().equals(ChatMessage.MessageType.SINGLE_LINK_IMAGE_MESSAGE)) {
                 image.setOnClickListener(v -> {
                 image.setOnClickListener(v -> {
@@ -193,12 +188,16 @@ public class MagicPreviewMessageViewHolder extends MessageHolders.IncomingImageM
             } else {
             } else {
                 image.setOnClickListener(null);
                 image.setOnClickListener(null);
             }
             }
-            messageText.setText("");
+            getMessageText().setText("");
         }
         }
 
 
         itemView.setTag(REPLYABLE_VIEW_TAG, message.isReplyable());
         itemView.setTag(REPLYABLE_VIEW_TAG, message.isReplyable());
     }
     }
 
 
+    public abstract EmojiTextView getMessageText();
+
+    public abstract ProgressBar getProgressBar();
+
     private void openOrDownloadFile(ChatMessage message) {
     private void openOrDownloadFile(ChatMessage message) {
         String filename = message.getSelectedIndividualHashMap().get("name");
         String filename = message.getSelectedIndividualHashMap().get("name");
         String mimetype = message.getSelectedIndividualHashMap().get("mimetype");
         String mimetype = message.getSelectedIndividualHashMap().get("mimetype");
@@ -388,7 +387,7 @@ public class MagicPreviewMessageViewHolder extends MessageHolders.IncomingImageM
 
 
         WorkManager.getInstance().enqueue(downloadWorker);
         WorkManager.getInstance().enqueue(downloadWorker);
 
 
-        progressBar.setVisibility(View.VISIBLE);
+        getProgressBar().setVisibility(View.VISIBLE);
 
 
         WorkManager.getInstance(context).getWorkInfoByIdLiveData(downloadWorker.getId()).observeForever(workInfo -> {
         WorkManager.getInstance(context).getWorkInfoByIdLiveData(downloadWorker.getId()).observeForever(workInfo -> {
             updateViewsByProgress(fileName, mimetype, workInfo);
             updateViewsByProgress(fileName, mimetype, workInfo);
@@ -400,7 +399,7 @@ public class MagicPreviewMessageViewHolder extends MessageHolders.IncomingImageM
             case RUNNING:
             case RUNNING:
                 int progress = workInfo.getProgress().getInt(DownloadFileToCacheWorker.PROGRESS, -1);
                 int progress = workInfo.getProgress().getInt(DownloadFileToCacheWorker.PROGRESS, -1);
                 if (progress > -1) {
                 if (progress > -1) {
-                    messageText.setText(String.format(context.getResources().getString(R.string.filename_progress), fileName, progress));
+                    getMessageText().setText(String.format(context.getResources().getString(R.string.filename_progress), fileName, progress));
                 }
                 }
                 break;
                 break;
 
 
@@ -411,13 +410,13 @@ public class MagicPreviewMessageViewHolder extends MessageHolders.IncomingImageM
                     Log.d(TAG, "file " + fileName + " was downloaded but it's not opened because view is not shown on" +
                     Log.d(TAG, "file " + fileName + " was downloaded but it's not opened because view is not shown on" +
                             " screen");
                             " screen");
                 }
                 }
-                messageText.setText(fileName);
-                progressBar.setVisibility(View.GONE);
+                getMessageText().setText(fileName);
+                getProgressBar().setVisibility(View.GONE);
                 break;
                 break;
 
 
             case FAILED:
             case FAILED:
-                messageText.setText(fileName);
-                progressBar.setVisibility(View.GONE);
+                getMessageText().setText(fileName);
+                getProgressBar().setVisibility(View.GONE);
                 break;
                 break;
             default:
             default:
                 // do nothing
                 // do nothing
@@ -486,6 +485,5 @@ public class MagicPreviewMessageViewHolder extends MessageHolders.IncomingImageM
                         Log.e(TAG, "Error reading file information", e);
                         Log.e(TAG, "Error reading file information", e);
                     }
                     }
                 });
                 });
-
     }
     }
 }
 }

+ 26 - 71
app/src/main/java/com/nextcloud/talk/adapters/messages/OutcomingLocationMessageViewHolder.kt

@@ -33,21 +33,16 @@ import android.view.MotionEvent
 import android.view.View
 import android.view.View
 import android.webkit.WebView
 import android.webkit.WebView
 import android.webkit.WebViewClient
 import android.webkit.WebViewClient
-import android.widget.ImageView
-import android.widget.RelativeLayout
-import android.widget.TextView
 import android.widget.Toast
 import android.widget.Toast
 import androidx.appcompat.content.res.AppCompatResources
 import androidx.appcompat.content.res.AppCompatResources
 import androidx.core.view.ViewCompat
 import androidx.core.view.ViewCompat
-import androidx.emoji.widget.EmojiTextView
 import autodagger.AutoInjector
 import autodagger.AutoInjector
-import butterknife.BindView
-import butterknife.ButterKnife
 import coil.load
 import coil.load
 import com.google.android.flexbox.FlexboxLayout
 import com.google.android.flexbox.FlexboxLayout
 import com.nextcloud.talk.R
 import com.nextcloud.talk.R
 import com.nextcloud.talk.application.NextcloudTalkApplication
 import com.nextcloud.talk.application.NextcloudTalkApplication
 import com.nextcloud.talk.application.NextcloudTalkApplication.Companion.sharedApplication
 import com.nextcloud.talk.application.NextcloudTalkApplication.Companion.sharedApplication
+import com.nextcloud.talk.databinding.ItemCustomOutcomingLocationMessageBinding
 import com.nextcloud.talk.models.json.chat.ChatMessage
 import com.nextcloud.talk.models.json.chat.ChatMessage
 import com.nextcloud.talk.models.json.chat.ReadStatus
 import com.nextcloud.talk.models.json.chat.ReadStatus
 import com.nextcloud.talk.utils.ApiUtils
 import com.nextcloud.talk.utils.ApiUtils
@@ -59,6 +54,9 @@ import javax.inject.Inject
 @AutoInjector(NextcloudTalkApplication::class)
 @AutoInjector(NextcloudTalkApplication::class)
 class OutcomingLocationMessageViewHolder(incomingView: View) : MessageHolders
 class OutcomingLocationMessageViewHolder(incomingView: View) : MessageHolders
 .OutcomingTextMessageViewHolder<ChatMessage>(incomingView) {
 .OutcomingTextMessageViewHolder<ChatMessage>(incomingView) {
+    private val binding: ItemCustomOutcomingLocationMessageBinding =
+        ItemCustomOutcomingLocationMessageBinding.bind(itemView)
+    private val realView: View = itemView
 
 
     private val TAG = "LocMessageView"
     private val TAG = "LocMessageView"
 
 
@@ -67,56 +65,18 @@ class OutcomingLocationMessageViewHolder(incomingView: View) : MessageHolders
     var locationName: String? = ""
     var locationName: String? = ""
     var locationGeoLink: String? = ""
     var locationGeoLink: String? = ""
 
 
-    @JvmField
-    @BindView(R.id.messageText)
-    var messageText: EmojiTextView? = null
-
-    @JvmField
-    @BindView(R.id.messageTime)
-    var messageTimeView: TextView? = null
-
-    @JvmField
-    @BindView(R.id.quotedChatMessageView)
-    var quotedChatMessageView: RelativeLayout? = 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.quoteColoredView)
-    var quoteColoredView: View? = null
-
-    @JvmField
-    @BindView(R.id.checkMark)
-    var checkMark: ImageView? = null
-
     @JvmField
     @JvmField
     @Inject
     @Inject
     var context: Context? = null
     var context: Context? = null
 
 
-    @JvmField
-    @BindView(R.id.webview)
-    var webview: WebView? = null
-
-    private val realView: View
-
     @SuppressLint("SetTextI18n", "SetJavaScriptEnabled", "ClickableViewAccessibility")
     @SuppressLint("SetTextI18n", "SetJavaScriptEnabled", "ClickableViewAccessibility")
     override fun onBind(message: ChatMessage) {
     override fun onBind(message: ChatMessage) {
         super.onBind(message)
         super.onBind(message)
         sharedApplication!!.componentApplication.inject(this)
         sharedApplication!!.componentApplication.inject(this)
 
 
         realView.isSelected = false
         realView.isSelected = false
-        messageTimeView!!.setTextColor(context!!.resources.getColor(R.color.white60))
-        val layoutParams = messageTimeView!!.layoutParams as FlexboxLayout.LayoutParams
+        binding.messageTime.setTextColor(context!!.resources.getColor(R.color.white60))
+        val layoutParams = binding.messageTime.layoutParams as FlexboxLayout.LayoutParams
         layoutParams.isWrapBefore = false
         layoutParams.isWrapBefore = false
 
 
         val textSize = context!!.resources.getDimension(R.dimen.chat_text_size)
         val textSize = context!!.resources.getDimension(R.dimen.chat_text_size)
@@ -144,10 +104,10 @@ class OutcomingLocationMessageViewHolder(incomingView: View) : MessageHolders
             )
             )
             ViewCompat.setBackground(bubble, bubbleDrawable)
             ViewCompat.setBackground(bubble, bubbleDrawable)
         }
         }
-        messageText!!.setTextSize(TypedValue.COMPLEX_UNIT_PX, textSize)
-        messageTimeView!!.layoutParams = layoutParams
-        messageText!!.text = message.text
-        messageText!!.isEnabled = false
+        binding.messageText.setTextSize(TypedValue.COMPLEX_UNIT_PX, textSize)
+        binding.messageTime.layoutParams = layoutParams
+        binding.messageText.text = message.text
+        binding.messageText.isEnabled = false
 
 
         // parent message handling
         // parent message handling
 
 
@@ -155,27 +115,27 @@ class OutcomingLocationMessageViewHolder(incomingView: View) : MessageHolders
             val parentChatMessage = message.parentMessage
             val parentChatMessage = message.parentMessage
             parentChatMessage.activeUser = message.activeUser
             parentChatMessage.activeUser = message.activeUser
             parentChatMessage.imageUrl?.let {
             parentChatMessage.imageUrl?.let {
-                quotedMessagePreview?.visibility = View.VISIBLE
-                quotedMessagePreview?.load(it) {
+                binding.messageQuote.quotedMessageImage.visibility = View.VISIBLE
+                binding.messageQuote.quotedMessageImage.load(it) {
                     addHeader(
                     addHeader(
                         "Authorization",
                         "Authorization",
                         ApiUtils.getCredentials(message.activeUser.username, message.activeUser.token)
                         ApiUtils.getCredentials(message.activeUser.username, message.activeUser.token)
                     )
                     )
                 }
                 }
             } ?: run {
             } ?: run {
-                quotedMessagePreview?.visibility = View.GONE
+                binding.messageQuote.quotedMessageImage.visibility = View.GONE
             }
             }
-            quotedUserName?.text = parentChatMessage.actorDisplayName
+            binding.messageQuote.quotedMessageAuthor.text = parentChatMessage.actorDisplayName
                 ?: context!!.getText(R.string.nc_nick_guest)
                 ?: 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))
+            binding.messageQuote.quotedMessage.text = parentChatMessage.text
+            binding.messageQuote.quotedMessage.setTextColor(context!!.resources.getColor(R.color.nc_outcoming_text_default))
+            binding.messageQuote.quotedMessageAuthor.setTextColor(context!!.resources.getColor(R.color.nc_grey))
 
 
-            quoteColoredView?.setBackgroundResource(R.color.white)
+            binding.messageQuote.quoteColoredView.setBackgroundResource(R.color.white)
 
 
-            quotedChatMessageView?.visibility = View.VISIBLE
+            binding.messageQuote.quotedChatMessageView.visibility = View.VISIBLE
         } else {
         } else {
-            quotedChatMessageView?.visibility = View.GONE
+            binding.messageQuote.quotedChatMessageView.visibility = View.GONE
         }
         }
 
 
         val readStatusDrawableInt = when (message.readStatus) {
         val readStatusDrawableInt = when (message.readStatus) {
@@ -193,11 +153,11 @@ class OutcomingLocationMessageViewHolder(incomingView: View) : MessageHolders
         readStatusDrawableInt?.let { drawableInt ->
         readStatusDrawableInt?.let { drawableInt ->
             AppCompatResources.getDrawable(context!!, drawableInt)?.let {
             AppCompatResources.getDrawable(context!!, drawableInt)?.let {
                 it.setColorFilter(context?.resources!!.getColor(R.color.white60), PorterDuff.Mode.SRC_ATOP)
                 it.setColorFilter(context?.resources!!.getColor(R.color.white60), PorterDuff.Mode.SRC_ATOP)
-                checkMark?.setImageDrawable(it)
+                binding.checkMark.setImageDrawable(it)
             }
             }
         }
         }
 
 
-        checkMark?.setContentDescription(readStatusContentDescriptionString)
+        binding.checkMark.setContentDescription(readStatusContentDescriptionString)
 
 
         // geo-location
         // geo-location
 
 
@@ -213,9 +173,9 @@ class OutcomingLocationMessageViewHolder(incomingView: View) : MessageHolders
             }
             }
         }
         }
 
 
-        webview?.settings?.javaScriptEnabled = true
+        binding.webview.settings?.javaScriptEnabled = true
 
 
-        webview?.webViewClient = object : WebViewClient() {
+        binding.webview.webViewClient = object : WebViewClient() {
             override fun shouldOverrideUrlLoading(view: WebView?, url: String?): Boolean {
             override fun shouldOverrideUrlLoading(view: WebView?, url: String?): Boolean {
                 return if (url != null && (url.startsWith("http://") || url.startsWith("https://"))
                 return if (url != null && (url.startsWith("http://") || url.startsWith("https://"))
                 ) {
                 ) {
@@ -242,9 +202,9 @@ class OutcomingLocationMessageViewHolder(incomingView: View) : MessageHolders
         urlStringBuffer.append("&locationName=" + URLEncoder.encode(locationName))
         urlStringBuffer.append("&locationName=" + URLEncoder.encode(locationName))
         urlStringBuffer.append("&locationGeoLink=" + URLEncoder.encode(locationGeoLink))
         urlStringBuffer.append("&locationGeoLink=" + URLEncoder.encode(locationGeoLink))
 
 
-        webview?.loadUrl(urlStringBuffer.toString())
+        binding.webview.loadUrl(urlStringBuffer.toString())
 
 
-        webview?.setOnTouchListener(object : View.OnTouchListener {
+        binding.webview.setOnTouchListener(object : View.OnTouchListener {
             override fun onTouch(v: View?, event: MotionEvent?): Boolean {
             override fun onTouch(v: View?, event: MotionEvent?): Boolean {
                 when (event?.action) {
                 when (event?.action) {
                     MotionEvent.ACTION_UP -> openGeoLink()
                     MotionEvent.ACTION_UP -> openGeoLink()
@@ -270,9 +230,4 @@ class OutcomingLocationMessageViewHolder(incomingView: View) : MessageHolders
     private fun addMarkerToGeoLink(locationGeoLink: String): String {
     private fun addMarkerToGeoLink(locationGeoLink: String): String {
         return locationGeoLink.replace("geo:", "geo:0,0?q=")
         return locationGeoLink.replace("geo:", "geo:0,0?q=")
     }
     }
-
-    init {
-        ButterKnife.bind(this, itemView)
-        this.realView = itemView
-    }
 }
 }

+ 45 - 0
app/src/main/java/com/nextcloud/talk/adapters/messages/OutcomingPreviewMessageViewHolder.java

@@ -0,0 +1,45 @@
+/*
+ * Nextcloud Talk application
+ *
+ * @author Andy Scherzinger
+ * Copyright (C) 2021 Andy Scherzinger <info@andy-scherzinger.de>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+package com.nextcloud.talk.adapters.messages;
+
+import android.view.View;
+import android.widget.ProgressBar;
+
+import com.nextcloud.talk.databinding.ItemCustomOutcomingPreviewMessageBinding;
+
+import androidx.emoji.widget.EmojiTextView;
+
+public class OutcomingPreviewMessageViewHolder extends MagicPreviewMessageViewHolder {
+    private final ItemCustomOutcomingPreviewMessageBinding binding;
+
+    public OutcomingPreviewMessageViewHolder(View itemView) {
+        super(itemView);
+        binding = ItemCustomOutcomingPreviewMessageBinding.bind(itemView);
+    }
+
+    public EmojiTextView getMessageText()  {
+        return binding.messageText;
+    }
+
+    public ProgressBar getProgressBar() {
+        return binding.progressBar;
+    }
+}

+ 5 - 12
app/src/main/java/com/nextcloud/talk/controllers/ChatController.kt

@@ -79,12 +79,13 @@ import com.google.android.flexbox.FlexboxLayout
 import com.nextcloud.talk.R
 import com.nextcloud.talk.R
 import com.nextcloud.talk.activities.MagicCallActivity
 import com.nextcloud.talk.activities.MagicCallActivity
 import com.nextcloud.talk.adapters.messages.IncomingLocationMessageViewHolder
 import com.nextcloud.talk.adapters.messages.IncomingLocationMessageViewHolder
+import com.nextcloud.talk.adapters.messages.IncomingPreviewMessageViewHolder
 import com.nextcloud.talk.adapters.messages.MagicIncomingTextMessageViewHolder
 import com.nextcloud.talk.adapters.messages.MagicIncomingTextMessageViewHolder
 import com.nextcloud.talk.adapters.messages.MagicOutcomingTextMessageViewHolder
 import com.nextcloud.talk.adapters.messages.MagicOutcomingTextMessageViewHolder
-import com.nextcloud.talk.adapters.messages.MagicPreviewMessageViewHolder
 import com.nextcloud.talk.adapters.messages.MagicSystemMessageViewHolder
 import com.nextcloud.talk.adapters.messages.MagicSystemMessageViewHolder
 import com.nextcloud.talk.adapters.messages.MagicUnreadNoticeMessageViewHolder
 import com.nextcloud.talk.adapters.messages.MagicUnreadNoticeMessageViewHolder
 import com.nextcloud.talk.adapters.messages.OutcomingLocationMessageViewHolder
 import com.nextcloud.talk.adapters.messages.OutcomingLocationMessageViewHolder
+import com.nextcloud.talk.adapters.messages.OutcomingPreviewMessageViewHolder
 import com.nextcloud.talk.adapters.messages.TalkMessagesListAdapter
 import com.nextcloud.talk.adapters.messages.TalkMessagesListAdapter
 import com.nextcloud.talk.api.NcApi
 import com.nextcloud.talk.api.NcApi
 import com.nextcloud.talk.application.NextcloudTalkApplication
 import com.nextcloud.talk.application.NextcloudTalkApplication
@@ -400,23 +401,15 @@ class ChatController(args: Bundle) :
             )
             )
 
 
             messageHolders.setIncomingImageConfig(
             messageHolders.setIncomingImageConfig(
-                MagicPreviewMessageViewHolder::class.java,
+                IncomingPreviewMessageViewHolder::class.java,
                 R.layout.item_custom_incoming_preview_message
                 R.layout.item_custom_incoming_preview_message
             )
             )
+
             messageHolders.setOutcomingImageConfig(
             messageHolders.setOutcomingImageConfig(
-                MagicPreviewMessageViewHolder::class.java,
+                OutcomingPreviewMessageViewHolder::class.java,
                 R.layout.item_custom_outcoming_preview_message
                 R.layout.item_custom_outcoming_preview_message
             )
             )
 
 
-            // messageHolders.setIncomingLocationConfig(
-            //     LocationMessageViewHolder::class.java,
-            //     R.layout.item_custom_location_message
-            // )
-            // messageHolders.setOutcomingLocationConfig(
-            //     LocationMessageViewHolder::class.java,
-            //     R.layout.item_custom_location_message
-            // )
-
             messageHolders.registerContentType(
             messageHolders.registerContentType(
                 CONTENT_TYPE_SYSTEM_MESSAGE,
                 CONTENT_TYPE_SYSTEM_MESSAGE,
                 MagicSystemMessageViewHolder::class.java,
                 MagicSystemMessageViewHolder::class.java,

+ 9 - 5
app/src/main/res/layout/item_custom_incoming_location_message.xml

@@ -3,8 +3,10 @@
   ~
   ~
   ~ @author Mario Danic
   ~ @author Mario Danic
   ~ @author Marcel Hibbe
   ~ @author Marcel Hibbe
-  ~ Copyright (C) 2017-2018 Mario Danic <mario@lovelyhq.com>
+  ~ @author Andy Scherzinger
+  ~ Copyright (C) 2021 Andy Scherzinger <info@andy-scherzinger.de>
   ~ Copyright (C) 2021 Marcel Hibbe <dev@mhibbe.de>
   ~ Copyright (C) 2021 Marcel Hibbe <dev@mhibbe.de>
+  ~ Copyright (C) 2017-2018 Mario Danic <mario@lovelyhq.com>
   ~
   ~
   ~ This program is free software: you can redistribute it and/or modify
   ~ This program is free software: you can redistribute it and/or modify
   ~ it under the terms of the GNU General Public License as published by
   ~ it under the terms of the GNU General Public License as published by
@@ -49,13 +51,15 @@
             app:flexWrap="wrap"
             app:flexWrap="wrap"
             app:justifyContent="flex_end">
             app:justifyContent="flex_end">
 
 
-                <include layout="@layout/item_message_quote" android:visibility="gone"/>
+                <include
+                    android:id="@+id/message_quote"
+                    layout="@layout/item_message_quote"
+                    android:visibility="gone" />
 
 
                 <WebView
                 <WebView
                     android:id="@+id/webview"
                     android:id="@+id/webview"
                     android:layout_width="400dp"
                     android:layout_width="400dp"
-                    android:layout_height="200dp"
-                    />
+                    android:layout_height="200dp" />
 
 
                 <androidx.emoji.widget.EmojiTextView
                 <androidx.emoji.widget.EmojiTextView
                     android:id="@+id/messageAuthor"
                     android:id="@+id/messageAuthor"
@@ -84,4 +88,4 @@
                     app:layout_alignSelf="center" />
                     app:layout_alignSelf="center" />
 
 
         </com.google.android.flexbox.FlexboxLayout>
         </com.google.android.flexbox.FlexboxLayout>
-</RelativeLayout>
+</RelativeLayout>

+ 6 - 1
app/src/main/res/layout/item_custom_incoming_text_message.xml

@@ -2,6 +2,8 @@
   ~ Nextcloud Talk application
   ~ Nextcloud Talk application
   ~
   ~
   ~ @author Mario Danic
   ~ @author Mario Danic
+  ~ @author Andy Scherzinger
+  ~ Copyright (C) 2021 Andy Scherzinger <info@andy-scherzinger.de>
   ~ Copyright (C) 2017-2018 Mario Danic <mario@lovelyhq.com>
   ~ Copyright (C) 2017-2018 Mario Danic <mario@lovelyhq.com>
   ~
   ~
   ~ This program is free software: you can redistribute it and/or modify
   ~ This program is free software: you can redistribute it and/or modify
@@ -47,7 +49,10 @@
         app:flexWrap="wrap"
         app:flexWrap="wrap"
         app:justifyContent="flex_end">
         app:justifyContent="flex_end">
 
 
-        <include layout="@layout/item_message_quote" android:visibility="gone"/>
+        <include
+            android:id="@+id/message_quote"
+            layout="@layout/item_message_quote"
+            android:visibility="gone" />
 
 
         <androidx.emoji.widget.EmojiTextView
         <androidx.emoji.widget.EmojiTextView
             android:id="@+id/messageAuthor"
             android:id="@+id/messageAuthor"

+ 5 - 3
app/src/main/res/layout/item_custom_outcoming_location_message.xml

@@ -41,13 +41,15 @@
         app:flexWrap="wrap"
         app:flexWrap="wrap"
         app:justifyContent="flex_end">
         app:justifyContent="flex_end">
 
 
-        <include layout="@layout/item_message_quote" android:visibility="gone"/>
+        <include
+            android:id="@+id/message_quote"
+            layout="@layout/item_message_quote"
+            android:visibility="gone" />
 
 
         <WebView
         <WebView
             android:id="@+id/webview"
             android:id="@+id/webview"
             android:layout_width="400dp"
             android:layout_width="400dp"
-            android:layout_height="200dp"
-            />
+            android:layout_height="200dp" />
 
 
         <androidx.emoji.widget.EmojiTextView
         <androidx.emoji.widget.EmojiTextView
             android:id="@id/messageText"
             android:id="@id/messageText"

+ 4 - 1
app/src/main/res/layout/item_custom_outcoming_text_message.xml

@@ -41,7 +41,10 @@
         app:flexWrap="wrap"
         app:flexWrap="wrap"
         app:justifyContent="flex_end">
         app:justifyContent="flex_end">
 
 
-        <include layout="@layout/item_message_quote" android:visibility="gone"/>
+        <include
+            android:id="@+id/message_quote"
+            layout="@layout/item_message_quote"
+            android:visibility="gone" />
 
 
         <androidx.emoji.widget.EmojiTextView
         <androidx.emoji.widget.EmojiTextView
             android:id="@id/messageText"
             android:id="@id/messageText"