mirror of
https://github.com/nextcloud/talk-android
synced 2025-06-24 22:19:59 +01:00
Merge pull request #4327 from nextcloud/deck_card_is_shown_as_object
show deck card in messages
This commit is contained in:
commit
5bee52d182
@ -410,6 +410,15 @@ class ConversationItem(
|
||||
chatMessage?.getNullsafeActorDisplayName()
|
||||
)
|
||||
}
|
||||
} else if (MessageType.DECK_CARD == chatMessage?.getCalculateMessageType()) {
|
||||
return if (chatMessage?.actorId == chatMessage?.activeUser!!.userId) {
|
||||
sharedApplication!!.getString(R.string.nc_sent_deck_card_you)
|
||||
} else {
|
||||
String.format(
|
||||
sharedApplication!!.resources.getString(R.string.nc_sent_deck_card),
|
||||
chatMessage?.getNullsafeActorDisplayName()
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
return ""
|
||||
|
@ -0,0 +1,268 @@
|
||||
/*
|
||||
* Nextcloud Talk - Android Client
|
||||
*
|
||||
* SPDX-FileCopyrightText: 2024 Sowjanya Kota <sowjanya.kch@gmail.com>
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*/
|
||||
|
||||
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
|
||||
import android.widget.ImageView
|
||||
import androidx.core.content.ContextCompat
|
||||
import autodagger.AutoInjector
|
||||
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
|
||||
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.ItemCustomIncomingDeckCardMessageBinding
|
||||
import com.nextcloud.talk.extensions.loadBotsAvatar
|
||||
import com.nextcloud.talk.extensions.loadChangelogBotAvatar
|
||||
import com.nextcloud.talk.extensions.loadFederatedUserAvatar
|
||||
import com.nextcloud.talk.ui.theme.ViewThemeUtils
|
||||
import com.nextcloud.talk.utils.ApiUtils
|
||||
import com.nextcloud.talk.utils.DateUtils
|
||||
import com.nextcloud.talk.utils.message.MessageUtils
|
||||
import com.nextcloud.talk.utils.preferences.AppPreferences
|
||||
import com.stfalcon.chatkit.messages.MessageHolders
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.flow.first
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import javax.inject.Inject
|
||||
|
||||
@AutoInjector(NextcloudTalkApplication::class)
|
||||
class IncomingDeckCardViewHolder(incomingView: View, payload: Any) : MessageHolders
|
||||
.IncomingTextMessageViewHolder<ChatMessage>(incomingView, payload) {
|
||||
|
||||
private val binding: ItemCustomIncomingDeckCardMessageBinding =
|
||||
ItemCustomIncomingDeckCardMessageBinding.bind(itemView)
|
||||
|
||||
@Inject
|
||||
lateinit var context: Context
|
||||
|
||||
@Inject
|
||||
lateinit var appPreferences: AppPreferences
|
||||
|
||||
@Inject
|
||||
lateinit var viewThemeUtils: ViewThemeUtils
|
||||
|
||||
@Inject
|
||||
lateinit var messageUtils: MessageUtils
|
||||
|
||||
@Inject
|
||||
lateinit var dateUtils: DateUtils
|
||||
|
||||
@Inject
|
||||
lateinit var ncApi: NcApi
|
||||
|
||||
lateinit var message: ChatMessage
|
||||
|
||||
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)
|
||||
binding.messageTime.text = dateUtils.getLocalTimeStringFromTimestamp(message.timestamp)
|
||||
|
||||
setAvatarAndAuthorOnMessageItem(message)
|
||||
showDeckCard(message)
|
||||
|
||||
colorizeMessageBubble(message)
|
||||
|
||||
binding.cardView.findViewById<ImageView>(R.id.deckCardImage)?.let {
|
||||
viewThemeUtils.platform.colorImageView(it, ColorRole.SECONDARY)
|
||||
}
|
||||
|
||||
itemView.isSelected = false
|
||||
|
||||
// parent message handling
|
||||
setParentMessageDataOnMessageItem(message)
|
||||
|
||||
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(
|
||||
message,
|
||||
::clickOnReaction,
|
||||
::longClickOnReaction,
|
||||
binding.reactions,
|
||||
binding.messageTime.context,
|
||||
false,
|
||||
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.visibility = View.VISIBLE
|
||||
binding.cardDescription.visibility = View.VISIBLE
|
||||
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 setAvatarAndAuthorOnMessageItem(message: ChatMessage) {
|
||||
val author: String = message.actorDisplayName!!
|
||||
if (!TextUtils.isEmpty(author)) {
|
||||
binding.messageAuthor.visibility = View.VISIBLE
|
||||
binding.messageAuthor.text = author
|
||||
binding.messageUserAvatar.setOnClickListener {
|
||||
(payload as? MessagePayload)?.profileBottomSheet?.showFor(message, itemView.context)
|
||||
}
|
||||
} else {
|
||||
binding.messageAuthor.setText(R.string.nc_nick_guest)
|
||||
}
|
||||
|
||||
if (!message.isGrouped && !message.isOneToOneConversation && !message.isFormerOneToOneConversation) {
|
||||
setAvatarOnMessage(message)
|
||||
} else {
|
||||
if (message.isOneToOneConversation || message.isFormerOneToOneConversation) {
|
||||
binding.messageUserAvatar.visibility = View.GONE
|
||||
} else {
|
||||
binding.messageUserAvatar.visibility = View.INVISIBLE
|
||||
}
|
||||
binding.messageAuthor.visibility = View.GONE
|
||||
}
|
||||
}
|
||||
|
||||
private fun setAvatarOnMessage(message: ChatMessage) {
|
||||
binding.messageUserAvatar.visibility = View.VISIBLE
|
||||
if (message.actorType == "guests") {
|
||||
// do nothing, avatar is set
|
||||
} else if (message.actorType == "bots" && message.actorId == "changelog") {
|
||||
binding.messageUserAvatar.loadChangelogBotAvatar()
|
||||
} else if (message.actorType == "bots") {
|
||||
binding.messageUserAvatar.loadBotsAvatar()
|
||||
} else if (message.actorType == "federated_users") {
|
||||
binding.messageUserAvatar.loadFederatedUserAvatar(message)
|
||||
}
|
||||
}
|
||||
|
||||
private fun colorizeMessageBubble(message: ChatMessage) {
|
||||
viewThemeUtils.talk.themeIncomingMessageBubble(bubble, message.isGrouped, message.isDeleted)
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
fun assignCommonMessageInterface(commonMessageInterface: CommonMessageInterface) {
|
||||
this.commonMessageInterface = commonMessageInterface
|
||||
}
|
||||
|
||||
companion object {
|
||||
private val TAG = IncomingDeckCardViewHolder::class.java.simpleName
|
||||
}
|
||||
}
|
@ -0,0 +1,245 @@
|
||||
/*
|
||||
* Nextcloud Talk - Android Client
|
||||
*
|
||||
* SPDX-FileCopyrightText: 2024 Sowjanya Kota<sowjanya.kch@gmail.com>
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*/
|
||||
|
||||
package com.nextcloud.talk.adapters.messages
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.net.Uri
|
||||
import android.util.Log
|
||||
import android.view.View
|
||||
import android.widget.ImageView
|
||||
import androidx.appcompat.content.res.AppCompatResources
|
||||
import androidx.core.content.ContextCompat
|
||||
import autodagger.AutoInjector
|
||||
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
|
||||
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.ItemCustomOutcomingDeckCardMessageBinding
|
||||
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.DateUtils
|
||||
import com.nextcloud.talk.utils.message.MessageUtils
|
||||
import com.nextcloud.talk.utils.preferences.AppPreferences
|
||||
import com.stfalcon.chatkit.messages.MessageHolders
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.flow.first
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import javax.inject.Inject
|
||||
|
||||
@AutoInjector(NextcloudTalkApplication::class)
|
||||
class OutcomingDeckCardViewHolder(
|
||||
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)
|
||||
|
||||
binding.cardView.findViewById<ImageView>(R.id.deckCardImage)?.let {
|
||||
viewThemeUtils.platform.colorImageView(it, ColorRole.SECONDARY)
|
||||
}
|
||||
|
||||
itemView.isSelected = false
|
||||
|
||||
showDeckCard(message)
|
||||
|
||||
// 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
|
||||
|
||||
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(
|
||||
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"]
|
||||
}
|
||||
}
|
||||
}
|
||||
val cardDescription = String.format(
|
||||
context.resources.getString(R.string.deck_card_description),
|
||||
stackName,
|
||||
boardName
|
||||
)
|
||||
|
||||
binding.cardName.visibility = View.VISIBLE
|
||||
binding.cardDescription.visibility = View.VISIBLE
|
||||
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 = OutcomingDeckCardViewHolder::class.java.simpleName
|
||||
}
|
||||
}
|
@ -67,6 +67,10 @@ public class TalkMessagesListAdapter<M extends IMessage> extends MessagesListAda
|
||||
((CallStartedViewHolder) holder).assignCallStartedMessageInterface(chatActivity);
|
||||
} else if (holder instanceof TemporaryMessageViewHolder) {
|
||||
((TemporaryMessageViewHolder) holder).assignTemporaryMessageInterface(chatActivity);
|
||||
}else if (holder instanceof IncomingDeckCardViewHolder){
|
||||
((IncomingDeckCardViewHolder) holder).assignCommonMessageInterface(chatActivity);
|
||||
} else if(holder instanceof OutcomingDeckCardViewHolder){
|
||||
((OutcomingDeckCardViewHolder) holder).assignCommonMessageInterface(chatActivity);
|
||||
}
|
||||
|
||||
super.onBindViewHolder(holder, position);
|
||||
|
@ -83,6 +83,7 @@ import com.nextcloud.talk.activities.TakePhotoActivity
|
||||
import com.nextcloud.talk.adapters.messages.CallStartedMessageInterface
|
||||
import com.nextcloud.talk.adapters.messages.CallStartedViewHolder
|
||||
import com.nextcloud.talk.adapters.messages.CommonMessageInterface
|
||||
import com.nextcloud.talk.adapters.messages.IncomingDeckCardViewHolder
|
||||
import com.nextcloud.talk.adapters.messages.IncomingLinkPreviewMessageViewHolder
|
||||
import com.nextcloud.talk.adapters.messages.IncomingLocationMessageViewHolder
|
||||
import com.nextcloud.talk.adapters.messages.IncomingPollMessageViewHolder
|
||||
@ -96,6 +97,7 @@ import com.nextcloud.talk.adapters.messages.OutcomingPollMessageViewHolder
|
||||
import com.nextcloud.talk.adapters.messages.OutcomingPreviewMessageViewHolder
|
||||
import com.nextcloud.talk.adapters.messages.OutcomingTextMessageViewHolder
|
||||
import com.nextcloud.talk.adapters.messages.OutcomingVoiceMessageViewHolder
|
||||
import com.nextcloud.talk.adapters.messages.OutcomingDeckCardViewHolder
|
||||
import com.nextcloud.talk.adapters.messages.PreviewMessageInterface
|
||||
import com.nextcloud.talk.adapters.messages.PreviewMessageViewHolder
|
||||
import com.nextcloud.talk.adapters.messages.SystemMessageInterface
|
||||
@ -1291,6 +1293,18 @@ class ChatActivity :
|
||||
R.layout.item_custom_outcoming_link_preview_message,
|
||||
this
|
||||
)
|
||||
|
||||
messageHolders.registerContentType(
|
||||
CONTENT_TYPE_DECK_CARD,
|
||||
IncomingDeckCardViewHolder::class.java,
|
||||
payload,
|
||||
R.layout.item_custom_incoming_deck_card_message,
|
||||
OutcomingDeckCardViewHolder::class.java,
|
||||
payload,
|
||||
R.layout.item_custom_outcoming_deck_card_message,
|
||||
this
|
||||
)
|
||||
|
||||
return messageHolders
|
||||
}
|
||||
|
||||
@ -3517,6 +3531,7 @@ class ChatActivity :
|
||||
CONTENT_TYPE_UNREAD_NOTICE_MESSAGE -> message.id == "-1"
|
||||
CONTENT_TYPE_CALL_STARTED -> message.id == "-2"
|
||||
CONTENT_TYPE_TEMP -> message.id == "-3"
|
||||
CONTENT_TYPE_DECK_CARD -> message.isDeckCard()
|
||||
|
||||
else -> false
|
||||
}
|
||||
@ -3721,7 +3736,8 @@ class ChatActivity :
|
||||
private const val CONTENT_TYPE_VOICE_MESSAGE: Byte = 5
|
||||
private const val CONTENT_TYPE_POLL: Byte = 6
|
||||
private const val CONTENT_TYPE_LINK_PREVIEW: Byte = 7
|
||||
private const val CONTENT_TYPE_TEMP: Byte = 8
|
||||
private const val CONTENT_TYPE_DECK_CARD: Byte = 8
|
||||
private const val CONTENT_TYPE_TEMP: Byte = 9
|
||||
private const val NEW_MESSAGES_POPUP_BUBBLE_DELAY: Long = 200
|
||||
private const val GET_ROOM_INFO_DELAY_NORMAL: Long = 30000
|
||||
private const val GET_ROOM_INFO_DELAY_LOBBY: Long = 5000
|
||||
|
@ -131,9 +131,21 @@ data class ChatMessage(
|
||||
MessageType.SINGLE_LINK_MESSAGE,
|
||||
MessageType.SINGLE_NC_GEOLOCATION_MESSAGE,
|
||||
MessageType.VOICE_MESSAGE,
|
||||
MessageType.POLL_MESSAGE
|
||||
MessageType.POLL_MESSAGE,
|
||||
MessageType.DECK_CARD
|
||||
)
|
||||
|
||||
fun isDeckCard(): Boolean {
|
||||
if (messageParameters != null && messageParameters!!.size > 0) {
|
||||
for ((_, individualHashMap) in messageParameters!!) {
|
||||
if (isHashMapEntryEqualTo(individualHashMap, "type", "deck-card")) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
fun hasFileAttachment(): Boolean {
|
||||
if (messageParameters != null && messageParameters!!.size > 0) {
|
||||
for ((_, individualHashMap) in messageParameters!!) {
|
||||
@ -237,6 +249,8 @@ data class ChatMessage(
|
||||
MessageType.SINGLE_NC_GEOLOCATION_MESSAGE
|
||||
} else if (isPoll()) {
|
||||
MessageType.POLL_MESSAGE
|
||||
} else if (isDeckCard()) {
|
||||
MessageType.DECK_CARD
|
||||
} else {
|
||||
MessageType.REGULAR_TEXT_MESSAGE
|
||||
}
|
||||
@ -345,7 +359,8 @@ data class ChatMessage(
|
||||
SINGLE_NC_ATTACHMENT_MESSAGE,
|
||||
SINGLE_NC_GEOLOCATION_MESSAGE,
|
||||
POLL_MESSAGE,
|
||||
VOICE_MESSAGE
|
||||
VOICE_MESSAGE,
|
||||
DECK_CARD
|
||||
}
|
||||
|
||||
/**
|
||||
|
25
app/src/main/res/drawable/deck.xml
Normal file
25
app/src/main/res/drawable/deck.xml
Normal file
@ -0,0 +1,25 @@
|
||||
<!--
|
||||
~ Nextcloud Talk - Android Client
|
||||
~
|
||||
~ SPDX-FileCopyrightText: 2024 Sowjanya Kota <sowjanya.kch@gmail.com>
|
||||
~ SPDX-License-Identifier: GPL-3.0-or-later
|
||||
-->
|
||||
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="16dp"
|
||||
android:height="16dp"
|
||||
android:viewportWidth="16"
|
||||
android:viewportHeight="16">
|
||||
<path
|
||||
android:pathData="M2,7L14,7A1,1 0,0 1,15 8L15,14A1,1 0,0 1,14 15L2,15A1,1 0,0 1,1 14L1,8A1,1 0,0 1,2 7z"
|
||||
android:fillColor="#fff"/>
|
||||
<path
|
||||
android:pathData="M2.5,5L13.5,5A0.5,0.5 0,0 1,14 5.5L14,5.5A0.5,0.5 0,0 1,13.5 6L2.5,6A0.5,0.5 0,0 1,2 5.5L2,5.5A0.5,0.5 0,0 1,2.5 5z"
|
||||
android:fillColor="#fff"/>
|
||||
<path
|
||||
android:pathData="M3.5,3L12.5,3A0.5,0.5 0,0 1,13 3.5L13,3.5A0.5,0.5 0,0 1,12.5 4L3.5,4A0.5,0.5 0,0 1,3 3.5L3,3.5A0.5,0.5 0,0 1,3.5 3z"
|
||||
android:fillColor="#fff"/>
|
||||
<path
|
||||
android:pathData="M4.5,1L11.5,1A0.5,0.5 0,0 1,12 1.5L12,1.5A0.5,0.5 0,0 1,11.5 2L4.5,2A0.5,0.5 0,0 1,4 1.5L4,1.5A0.5,0.5 0,0 1,4.5 1z"
|
||||
android:fillColor="#fff"/>
|
||||
</vector>
|
@ -0,0 +1,119 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ Nextcloud Talk - Android Client
|
||||
~
|
||||
~ SPDX-FileCopyrightText: 2024 Sowjanya Kota <sowjanya.kch@gmail.com>
|
||||
~ SPDX-License-Identifier: GPL-3.0-or-later
|
||||
-->
|
||||
|
||||
<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"
|
||||
android:layout_marginTop="2dp"
|
||||
android:layout_marginRight="16dp"
|
||||
android:layout_marginBottom="2dp">
|
||||
|
||||
<ImageView
|
||||
android:id="@id/messageUserAvatar"
|
||||
android:layout_width="24dp"
|
||||
android:layout_height="24dp"
|
||||
android:layout_alignParentTop="true"
|
||||
android:layout_marginTop ="2dp"
|
||||
android:layout_marginEnd="8dp"
|
||||
android:contentDescription="@string/avatar" />
|
||||
|
||||
<com.google.android.flexbox.FlexboxLayout
|
||||
android:id="@id/bubble"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="@dimen/message_incoming_bubble_margin_right"
|
||||
android:layout_toEndOf="@id/messageUserAvatar"
|
||||
android:orientation="vertical"
|
||||
app:alignContent="stretch"
|
||||
app:alignItems="stretch"
|
||||
app:flexWrap="wrap">
|
||||
|
||||
<include
|
||||
android:id="@+id/message_quote"
|
||||
layout="@layout/item_message_quote"
|
||||
android:visibility="gone" />
|
||||
|
||||
<androidx.emoji2.widget.EmojiTextView
|
||||
android:id="@+id/messageAuthor"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="4dp"
|
||||
android:alpha="0.6"
|
||||
android:textAlignment="viewStart"
|
||||
android:textColor="@color/no_emphasis_text"
|
||||
android:textIsSelectable="false"
|
||||
android:textSize="12sp"
|
||||
tools:text="Jane Doe" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="4dp"
|
||||
android:orientation="horizontal"
|
||||
android:gravity="center_vertical">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/deckCardImage"
|
||||
android:layout_width="16dp"
|
||||
android:layout_height="16dp"
|
||||
android:contentDescription="@null"
|
||||
android:src="@drawable/deck" />
|
||||
|
||||
<androidx.emoji2.widget.EmojiTextView
|
||||
android:id="@+id/cardName"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="4dp"
|
||||
android:ellipsize="end"
|
||||
android:maxLines="1"
|
||||
android:textIsSelectable="false"
|
||||
android:textStyle="bold"
|
||||
android:visibility="gone"
|
||||
tools:text="Card Name"
|
||||
tools:visibility="visible" />
|
||||
</LinearLayout>
|
||||
|
||||
<androidx.emoji2.widget.EmojiTextView
|
||||
android:id="@+id/cardDescription"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:ellipsize="end"
|
||||
android:textAlignment="viewStart"
|
||||
android:maxLines="1"
|
||||
android:textIsSelectable="false"
|
||||
android:visibility="gone"
|
||||
android:layout_marginBottom="4dp"
|
||||
tools:text="Card Description"
|
||||
tools:visibility="visible" />
|
||||
|
||||
<TextView
|
||||
android:id="@id/messageTime"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:alpha="0.6"
|
||||
android:layout_gravity="end"
|
||||
android:textColor="@color/no_emphasis_text"
|
||||
android:textIsSelectable="false"
|
||||
tools:text="12:38" />
|
||||
</LinearLayout>
|
||||
|
||||
<include
|
||||
android:id="@+id/reactions"
|
||||
layout="@layout/reactions_inside_message" />
|
||||
|
||||
</com.google.android.flexbox.FlexboxLayout>
|
||||
</RelativeLayout>
|
@ -0,0 +1,113 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ Nextcloud Talk - Android Client
|
||||
~
|
||||
~ SPDX-FileCopyrightText: 2024 Sowjanya Kota <sowjanya.kch@gmail.com>
|
||||
~ SPDX-License-Identifier: GPL-3.0-or-later
|
||||
-->
|
||||
|
||||
<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"
|
||||
android:layout_marginTop="2dp"
|
||||
android:layout_marginRight="16dp"
|
||||
android:layout_marginBottom="2dp">
|
||||
|
||||
<com.google.android.flexbox.FlexboxLayout
|
||||
android:id="@id/bubble"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentEnd="true"
|
||||
android:layout_marginStart="@dimen/message_outcoming_bubble_margin_left"
|
||||
app:alignContent="stretch"
|
||||
app:alignItems="stretch"
|
||||
app:flexWrap="wrap"
|
||||
app:justifyContent="flex_end">
|
||||
|
||||
<include
|
||||
android:id="@+id/message_quote"
|
||||
layout="@layout/item_message_quote"
|
||||
android:visibility="gone" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="4dp"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/deckCardImage"
|
||||
android:layout_width="16dp"
|
||||
android:layout_height="16dp"
|
||||
android:contentDescription="@null"
|
||||
android:src="@drawable/deck" />
|
||||
|
||||
<androidx.emoji2.widget.EmojiTextView
|
||||
android:id="@+id/cardName"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="4dp"
|
||||
android:ellipsize="end"
|
||||
android:maxLines="1"
|
||||
android:textIsSelectable="false"
|
||||
android:textStyle="bold"
|
||||
android:visibility="gone"
|
||||
tools:text="Card Name"
|
||||
tools:visibility="visible" />
|
||||
</LinearLayout>
|
||||
|
||||
<androidx.emoji2.widget.EmojiTextView
|
||||
android:id="@+id/cardDescription"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:ellipsize="end"
|
||||
android:maxLines="1"
|
||||
android:textAlignment="viewStart"
|
||||
android:textIsSelectable="false"
|
||||
android:visibility="gone"
|
||||
tools:text="Card Description"
|
||||
tools:visibility="visible" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
android:layout_marginTop="4dp"
|
||||
android:layout_gravity="end"
|
||||
tools:ignore="UseCompoundDrawables">
|
||||
|
||||
<TextView
|
||||
android:id="@id/messageTime"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:alpha="0.6"
|
||||
android:textColor="@color/no_emphasis_text"
|
||||
android:textIsSelectable="false"
|
||||
tools:text="12:38" />
|
||||
<ImageView
|
||||
android:id="@+id/checkMark"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="@dimen/message_bubble_checkmark_height"
|
||||
android:layout_marginStart="4dp"
|
||||
android:contentDescription="@null"
|
||||
app:tint="@color/high_emphasis_text" />
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<include
|
||||
android:id="@+id/reactions"
|
||||
layout="@layout/reactions_inside_message" />
|
||||
|
||||
</com.google.android.flexbox.FlexboxLayout>
|
||||
</RelativeLayout>
|
@ -407,6 +407,7 @@ How to translate with transifex:
|
||||
<string name="nc_sent_poll" formatted="true">%1$s sent a poll.</string>
|
||||
<string name="nc_sent_location" formatted="true">%1$s sent a location.</string>
|
||||
<string name="nc_sent_voice" formatted="true">%1$s sent a voice message.</string>
|
||||
<string name="nc_sent_deck_card" formatted="true">%1$s sent a deck card</string>
|
||||
<string name="nc_sent_a_gif_you">You sent a GIF.</string>
|
||||
<string name="nc_sent_an_attachment_you">You sent an attachment.</string>
|
||||
<string name="nc_sent_an_audio_you">You sent an audio.</string>
|
||||
@ -415,6 +416,7 @@ How to translate with transifex:
|
||||
<string name="nc_sent_poll_you">You sent a poll.</string>
|
||||
<string name="nc_sent_location_you">You sent a location.</string>
|
||||
<string name="nc_sent_voice_you">You sent a voice message.</string>
|
||||
<string name="nc_sent_deck_card_you">You sent a deck card</string>
|
||||
<string name="nc_formatted_message" translatable="false">%1$s: %2$s</string>
|
||||
<string name="nc_message_quote_cancel_reply">Cancel reply</string>
|
||||
<!-- When translating to German, please use non-formal variant -->
|
||||
@ -515,7 +517,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>
|
||||
|
Loading…
Reference in New Issue
Block a user