Work on Incoming and Outgoing deck card viewholder

Signed-off-by: sowjanyakch <sowjanya.kch@gmail.com>
This commit is contained in:
sowjanyakch 2024-10-09 22:07:36 +02:00
parent 66d2db20aa
commit 56b0b80316
No known key found for this signature in database
GPG Key ID: F7AA2A8B65B50220
5 changed files with 259 additions and 11 deletions

View File

@ -9,6 +9,8 @@ package com.nextcloud.talk.adapters.messages
import android.annotation.SuppressLint
import android.content.Context
import android.content.Intent
import android.net.Uri
import android.text.TextUtils
import android.util.Log
import android.view.View
@ -22,7 +24,7 @@ import com.nextcloud.talk.application.NextcloudTalkApplication
import com.nextcloud.talk.application.NextcloudTalkApplication.Companion.sharedApplication
import com.nextcloud.talk.chat.ChatActivity
import com.nextcloud.talk.chat.data.model.ChatMessage
import com.nextcloud.talk.databinding.ItemCustomIncomingLinkPreviewMessageBinding
import com.nextcloud.talk.databinding.ItemCustomIncomingDeckCardMessageBinding
import com.nextcloud.talk.extensions.loadBotsAvatar
import com.nextcloud.talk.extensions.loadChangelogBotAvatar
import com.nextcloud.talk.extensions.loadFederatedUserAvatar
@ -43,8 +45,8 @@ import javax.inject.Inject
class IncomingDeckCardViewHolder(incomingView: View, payload: Any) : MessageHolders
.IncomingTextMessageViewHolder<ChatMessage>(incomingView, payload) {
private val binding: ItemCustomIncomingLinkPreviewMessageBinding =
ItemCustomIncomingLinkPreviewMessageBinding.bind(itemView)
private val binding: ItemCustomIncomingDeckCardMessageBinding =
ItemCustomIncomingDeckCardMessageBinding.bind(itemView)
@Inject
lateinit var context: Context
@ -71,6 +73,7 @@ class IncomingDeckCardViewHolder(incomingView: View, payload: Any) : MessageHold
var stackName: String? = null
var cardName: String? = null
var boardName: String? = null
var cardLink: String? = null
@SuppressLint("SetTextI18n")
override fun onBind(message: ChatMessage) {
@ -90,11 +93,17 @@ class IncomingDeckCardViewHolder(incomingView: View, payload: Any) : MessageHold
showDeckCard(message)
binding.referenceInclude.referenceWrapper.setOnLongClickListener { l: View? ->
binding.cardView.setOnLongClickListener { l: View? ->
commonMessageInterface.onOpenMessageActionsDialog(message)
true
}
binding.cardView.setOnClickListener {
val browserIntent = Intent(Intent.ACTION_VIEW, Uri.parse(cardLink))
browserIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
context.startActivity(browserIntent)
}
itemView.setTag(R.string.replyable_message_view_tag, message.replyable)
Reaction().showReactions(
@ -116,9 +125,20 @@ class IncomingDeckCardViewHolder(incomingView: View, payload: Any) : MessageHold
cardName = individualHashMap["name"]
stackName = individualHashMap["stackname"]
boardName = individualHashMap["boardname"]
cardLink = individualHashMap["link"]
}
}
}
if (cardName?.isNotEmpty() == true) {
val cardDescription = String.format(
context.resources.getString(R.string.deck_card_description),
stackName,
boardName
)
binding.cardName.text = cardName
binding.cardDescription.text = cardDescription
}
}
private fun longClickOnReaction(chatMessage: ChatMessage) {

View File

@ -7,14 +7,232 @@
package com.nextcloud.talk.adapters.messages
import android.annotation.SuppressLint
import android.view.View
import autodagger.AutoInjector
import com.nextcloud.talk.application.NextcloudTalkApplication
import com.nextcloud.talk.chat.data.model.ChatMessage
import com.nextcloud.talk.databinding.ItemCustomOutcomingDeckCardMessageBinding
import com.stfalcon.chatkit.messages.MessageHolders
import javax.inject.Inject
import android.content.Context
import android.content.Intent
import android.net.Uri
import android.util.Log
import androidx.appcompat.content.res.AppCompatResources
import androidx.core.content.ContextCompat
import coil.load
import com.nextcloud.android.common.ui.theme.utils.ColorRole
import com.nextcloud.talk.R
import com.nextcloud.talk.api.NcApi
import com.nextcloud.talk.application.NextcloudTalkApplication.Companion.sharedApplication
import com.nextcloud.talk.chat.ChatActivity
import com.nextcloud.talk.models.json.chat.ReadStatus
import com.nextcloud.talk.ui.theme.ViewThemeUtils
import com.nextcloud.talk.utils.ApiUtils
import com.nextcloud.talk.utils.message.MessageUtils
import com.nextcloud.talk.utils.DateUtils
import com.nextcloud.talk.utils.preferences.AppPreferences
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
@AutoInjector(NextcloudTalkApplication::class)
class OutgoingDeckCardViewHolder(
outcomingView: View
) : MessageHolders.OutcomingTextMessageViewHolder<ChatMessage>(outcomingView) {
private val binding: ItemCustomOutcomingDeckCardMessageBinding = ItemCustomOutcomingDeckCardMessageBinding.bind(
itemView
)
@Inject
lateinit var context: Context
@Inject
lateinit var viewThemeUtils: ViewThemeUtils
@Inject
lateinit var messageUtils: MessageUtils
@Inject
lateinit var appPreferences: AppPreferences
@Inject
lateinit var ncApi: NcApi
lateinit var message: ChatMessage
@Inject
lateinit var dateUtils: DateUtils
lateinit var commonMessageInterface: CommonMessageInterface
var stackName: String? = null
var cardName: String? = null
var boardName: String? = null
var cardLink: String? = null
@SuppressLint("SetTextI18n")
override fun onBind(message: ChatMessage) {
super.onBind(message)
this.message = message
sharedApplication!!.componentApplication.inject(this)
viewThemeUtils.platform.colorTextView(binding.messageTime, ColorRole.ON_SURFACE_VARIANT)
binding.messageTime.text = dateUtils.getLocalTimeStringFromTimestamp(message.timestamp)
colorizeMessageBubble(message)
itemView.isSelected = false
// parent message handling
setParentMessageDataOnMessageItem(message)
val readStatusDrawableInt = when (message.readStatus) {
ReadStatus.READ -> R.drawable.ic_check_all
ReadStatus.SENT -> R.drawable.ic_check
else -> null
}
val readStatusContentDescriptionString = when (message.readStatus) {
ReadStatus.READ -> context.resources?.getString(R.string.nc_message_read)
ReadStatus.SENT -> context.resources?.getString(R.string.nc_message_sent)
else -> null
}
readStatusDrawableInt?.let { drawableInt ->
AppCompatResources.getDrawable(context, drawableInt)?.let {
binding.checkMark.setImageDrawable(it)
viewThemeUtils.talk.themeMessageCheckMark(binding.checkMark)
}
}
binding.checkMark.contentDescription = readStatusContentDescriptionString
showDeckCard(message)
binding.cardView.setOnClickListener {
val browserIntent = Intent(Intent.ACTION_VIEW, Uri.parse(cardLink))
browserIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
context.startActivity(browserIntent)
}
Reaction().showReactions(
message,
::clickOnReaction,
::longClickOnReaction,
binding.reactions,
binding.messageTime.context,
true,
viewThemeUtils
)
}
private fun showDeckCard(message: ChatMessage) {
if (message.messageParameters != null && message.messageParameters!!.size > 0) {
for (key in message.messageParameters!!.keys) {
val individualHashMap: Map<String?, String?> = message.messageParameters!![key]!!
if (individualHashMap["type"] == "deck-card") {
cardName = individualHashMap["name"]
stackName = individualHashMap["stackname"]
boardName = individualHashMap["boardname"]
cardLink = individualHashMap["link"]
}
}
}
if (cardName?.isNotEmpty() == true) {
val cardDescription = String.format(
context.resources.getString(R.string.deck_card_description),
stackName,
boardName
)
binding.cardName.text = cardName
binding.cardDescription.text = cardDescription
}
}
private fun longClickOnReaction(chatMessage: ChatMessage) {
commonMessageInterface.onLongClickReactions(chatMessage)
}
private fun clickOnReaction(chatMessage: ChatMessage, emoji: String) {
commonMessageInterface.onClickReaction(chatMessage, emoji)
}
private fun setParentMessageDataOnMessageItem(message: ChatMessage) {
if (message.parentMessageId != null && !message.isDeleted) {
CoroutineScope(Dispatchers.Main).launch {
try {
val chatActivity = commonMessageInterface as ChatActivity
val urlForChatting = ApiUtils.getUrlForChat(
chatActivity.chatApiVersion,
chatActivity.conversationUser?.baseUrl,
chatActivity.roomToken
)
val parentChatMessage = withContext(Dispatchers.IO) {
chatActivity.chatViewModel.getMessageById(
urlForChatting,
chatActivity.currentConversation!!,
message.parentMessageId!!
).first()
}
parentChatMessage.activeUser = message.activeUser
parentChatMessage.imageUrl?.let {
binding.messageQuote.quotedMessageImage.visibility = View.VISIBLE
binding.messageQuote.quotedMessageImage.load(it) {
addHeader(
"Authorization",
ApiUtils.getCredentials(message.activeUser!!.username, message.activeUser!!.token)!!
)
}
} ?: run {
binding.messageQuote.quotedMessageImage.visibility = View.GONE
}
binding.messageQuote.quotedMessageAuthor.text = parentChatMessage.actorDisplayName
?: context.getText(R.string.nc_nick_guest)
binding.messageQuote.quotedMessage.text = messageUtils
.enrichChatReplyMessageText(
binding.messageQuote.quotedMessage.context,
parentChatMessage,
true,
viewThemeUtils
)
binding.messageQuote.quotedMessageAuthor
.setTextColor(ContextCompat.getColor(context, R.color.textColorMaxContrast))
if (parentChatMessage.actorId?.equals(message.activeUser!!.userId) == true) {
viewThemeUtils.platform.colorViewBackground(
binding.messageQuote.quoteColoredView,
ColorRole.PRIMARY
)
} else {
binding.messageQuote.quoteColoredView.setBackgroundResource(R.color.textColorMaxContrast)
}
binding.messageQuote.quotedChatMessageView.visibility = View.VISIBLE
} catch (e: Exception) {
Log.d(TAG, "Error when processing parent message in view holder", e)
}
}
} else {
binding.messageQuote.quotedChatMessageView.visibility = View.GONE
}
}
private fun colorizeMessageBubble(message: ChatMessage) {
viewThemeUtils.talk.themeOutgoingMessageBubble(bubble, message.isGrouped, message.isDeleted)
}
fun assignCommonMessageInterface(commonMessageInterface: CommonMessageInterface) {
this.commonMessageInterface = commonMessageInterface
}
companion object {
private val TAG = OutgoingDeckCardViewHolder::class.java.simpleName
}
}

View File

@ -9,6 +9,7 @@
<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/cardView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="16dp"
@ -58,13 +59,13 @@
android:orientation="horizontal">
<ImageView
android:id="@+id/referenceImage"
android:id="@+id/deckCardImage"
android:layout_width="24dp"
android:layout_height="24dp"
android:src="@drawable/baseline_assignment_24" />
<androidx.emoji2.widget.EmojiTextView
android:id="@+id/referenceName"
android:id="@+id/cardName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
@ -85,7 +86,7 @@
android:orientation="vertical">
<androidx.emoji2.widget.EmojiTextView
android:id="@+id/referenceDescription"
android:id="@+id/cardDescription"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ellipsize="end"
@ -109,5 +110,9 @@
</LinearLayout>
<include
android:id="@+id/reactions"
layout="@layout/reactions_inside_message" />
</com.google.android.flexbox.FlexboxLayout>
</RelativeLayout>

View File

@ -8,6 +8,7 @@
<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/cardView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="16dp"
@ -57,13 +58,13 @@
android:orientation="horizontal">
<ImageView
android:id="@+id/referenceImage"
android:id="@+id/deckCardImage"
android:layout_width="24dp"
android:layout_height="24dp"
android:src="@drawable/baseline_assignment_24" />
<androidx.emoji2.widget.EmojiTextView
android:id="@+id/referenceName"
android:id="@+id/cardName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
@ -84,7 +85,7 @@
android:orientation="vertical">
<androidx.emoji2.widget.EmojiTextView
android:id="@+id/referenceDescription"
android:id="@+id/cardDescription"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ellipsize="end"
@ -118,5 +119,9 @@
app:layout_alignSelf="center"
app:tint="@color/high_emphasis_text" />
<include
android:id="@+id/reactions"
layout="@layout/reactions_inside_message" />
</com.google.android.flexbox.FlexboxLayout>
</RelativeLayout>

View File

@ -515,7 +515,7 @@ How to translate with transifex:
<string name="typing_are_typing">are typing …</string>
<string name="typing_1_other">and 1 other is typing …</string>
<string name="typing_x_others">and %1$s others are typing …</string>
<string name="deck_card_description">%1$s in 2$s</string>
<!-- Upload -->
<string name="nc_add_file">Add to conversation</string>
<string name="nc_upload_picture_from_cam">Take photo</string>