mirror of
https://github.com/nextcloud/talk-android
synced 2025-03-07 06:39:45 +00:00
Work on Incoming and Outgoing deck card viewholder
Signed-off-by: sowjanyakch <sowjanya.kch@gmail.com>
This commit is contained in:
parent
66d2db20aa
commit
56b0b80316
@ -9,6 +9,8 @@ package com.nextcloud.talk.adapters.messages
|
|||||||
|
|
||||||
import android.annotation.SuppressLint
|
import android.annotation.SuppressLint
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
|
import android.content.Intent
|
||||||
|
import android.net.Uri
|
||||||
import android.text.TextUtils
|
import android.text.TextUtils
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
import android.view.View
|
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.application.NextcloudTalkApplication.Companion.sharedApplication
|
||||||
import com.nextcloud.talk.chat.ChatActivity
|
import com.nextcloud.talk.chat.ChatActivity
|
||||||
import com.nextcloud.talk.chat.data.model.ChatMessage
|
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.loadBotsAvatar
|
||||||
import com.nextcloud.talk.extensions.loadChangelogBotAvatar
|
import com.nextcloud.talk.extensions.loadChangelogBotAvatar
|
||||||
import com.nextcloud.talk.extensions.loadFederatedUserAvatar
|
import com.nextcloud.talk.extensions.loadFederatedUserAvatar
|
||||||
@ -43,8 +45,8 @@ import javax.inject.Inject
|
|||||||
class IncomingDeckCardViewHolder(incomingView: View, payload: Any) : MessageHolders
|
class IncomingDeckCardViewHolder(incomingView: View, payload: Any) : MessageHolders
|
||||||
.IncomingTextMessageViewHolder<ChatMessage>(incomingView, payload) {
|
.IncomingTextMessageViewHolder<ChatMessage>(incomingView, payload) {
|
||||||
|
|
||||||
private val binding: ItemCustomIncomingLinkPreviewMessageBinding =
|
private val binding: ItemCustomIncomingDeckCardMessageBinding =
|
||||||
ItemCustomIncomingLinkPreviewMessageBinding.bind(itemView)
|
ItemCustomIncomingDeckCardMessageBinding.bind(itemView)
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
lateinit var context: Context
|
lateinit var context: Context
|
||||||
@ -71,6 +73,7 @@ class IncomingDeckCardViewHolder(incomingView: View, payload: Any) : MessageHold
|
|||||||
var stackName: String? = null
|
var stackName: String? = null
|
||||||
var cardName: String? = null
|
var cardName: String? = null
|
||||||
var boardName: String? = null
|
var boardName: String? = null
|
||||||
|
var cardLink: String? = null
|
||||||
|
|
||||||
@SuppressLint("SetTextI18n")
|
@SuppressLint("SetTextI18n")
|
||||||
override fun onBind(message: ChatMessage) {
|
override fun onBind(message: ChatMessage) {
|
||||||
@ -90,11 +93,17 @@ class IncomingDeckCardViewHolder(incomingView: View, payload: Any) : MessageHold
|
|||||||
|
|
||||||
showDeckCard(message)
|
showDeckCard(message)
|
||||||
|
|
||||||
binding.referenceInclude.referenceWrapper.setOnLongClickListener { l: View? ->
|
binding.cardView.setOnLongClickListener { l: View? ->
|
||||||
commonMessageInterface.onOpenMessageActionsDialog(message)
|
commonMessageInterface.onOpenMessageActionsDialog(message)
|
||||||
true
|
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)
|
itemView.setTag(R.string.replyable_message_view_tag, message.replyable)
|
||||||
|
|
||||||
Reaction().showReactions(
|
Reaction().showReactions(
|
||||||
@ -116,9 +125,20 @@ class IncomingDeckCardViewHolder(incomingView: View, payload: Any) : MessageHold
|
|||||||
cardName = individualHashMap["name"]
|
cardName = individualHashMap["name"]
|
||||||
stackName = individualHashMap["stackname"]
|
stackName = individualHashMap["stackname"]
|
||||||
boardName = individualHashMap["boardname"]
|
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) {
|
private fun longClickOnReaction(chatMessage: ChatMessage) {
|
||||||
|
@ -7,14 +7,232 @@
|
|||||||
|
|
||||||
package com.nextcloud.talk.adapters.messages
|
package com.nextcloud.talk.adapters.messages
|
||||||
|
|
||||||
|
import android.annotation.SuppressLint
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import autodagger.AutoInjector
|
import autodagger.AutoInjector
|
||||||
import com.nextcloud.talk.application.NextcloudTalkApplication
|
import com.nextcloud.talk.application.NextcloudTalkApplication
|
||||||
import com.nextcloud.talk.chat.data.model.ChatMessage
|
import com.nextcloud.talk.chat.data.model.ChatMessage
|
||||||
|
import com.nextcloud.talk.databinding.ItemCustomOutcomingDeckCardMessageBinding
|
||||||
import com.stfalcon.chatkit.messages.MessageHolders
|
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)
|
@AutoInjector(NextcloudTalkApplication::class)
|
||||||
class OutgoingDeckCardViewHolder(
|
class OutgoingDeckCardViewHolder(
|
||||||
outcomingView: View
|
outcomingView: View
|
||||||
) : MessageHolders.OutcomingTextMessageViewHolder<ChatMessage>(outcomingView) {
|
) : 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
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -9,6 +9,7 @@
|
|||||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:id ="@+id/cardView"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginLeft="16dp"
|
android:layout_marginLeft="16dp"
|
||||||
@ -58,13 +59,13 @@
|
|||||||
android:orientation="horizontal">
|
android:orientation="horizontal">
|
||||||
|
|
||||||
<ImageView
|
<ImageView
|
||||||
android:id="@+id/referenceImage"
|
android:id="@+id/deckCardImage"
|
||||||
android:layout_width="24dp"
|
android:layout_width="24dp"
|
||||||
android:layout_height="24dp"
|
android:layout_height="24dp"
|
||||||
android:src="@drawable/baseline_assignment_24" />
|
android:src="@drawable/baseline_assignment_24" />
|
||||||
|
|
||||||
<androidx.emoji2.widget.EmojiTextView
|
<androidx.emoji2.widget.EmojiTextView
|
||||||
android:id="@+id/referenceName"
|
android:id="@+id/cardName"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginStart="10dp"
|
android:layout_marginStart="10dp"
|
||||||
@ -85,7 +86,7 @@
|
|||||||
android:orientation="vertical">
|
android:orientation="vertical">
|
||||||
|
|
||||||
<androidx.emoji2.widget.EmojiTextView
|
<androidx.emoji2.widget.EmojiTextView
|
||||||
android:id="@+id/referenceDescription"
|
android:id="@+id/cardDescription"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:ellipsize="end"
|
android:ellipsize="end"
|
||||||
@ -109,5 +110,9 @@
|
|||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
|
<include
|
||||||
|
android:id="@+id/reactions"
|
||||||
|
layout="@layout/reactions_inside_message" />
|
||||||
|
|
||||||
</com.google.android.flexbox.FlexboxLayout>
|
</com.google.android.flexbox.FlexboxLayout>
|
||||||
</RelativeLayout>
|
</RelativeLayout>
|
@ -8,6 +8,7 @@
|
|||||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:id="@+id/cardView"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginLeft="16dp"
|
android:layout_marginLeft="16dp"
|
||||||
@ -57,13 +58,13 @@
|
|||||||
android:orientation="horizontal">
|
android:orientation="horizontal">
|
||||||
|
|
||||||
<ImageView
|
<ImageView
|
||||||
android:id="@+id/referenceImage"
|
android:id="@+id/deckCardImage"
|
||||||
android:layout_width="24dp"
|
android:layout_width="24dp"
|
||||||
android:layout_height="24dp"
|
android:layout_height="24dp"
|
||||||
android:src="@drawable/baseline_assignment_24" />
|
android:src="@drawable/baseline_assignment_24" />
|
||||||
|
|
||||||
<androidx.emoji2.widget.EmojiTextView
|
<androidx.emoji2.widget.EmojiTextView
|
||||||
android:id="@+id/referenceName"
|
android:id="@+id/cardName"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginStart="10dp"
|
android:layout_marginStart="10dp"
|
||||||
@ -84,7 +85,7 @@
|
|||||||
android:orientation="vertical">
|
android:orientation="vertical">
|
||||||
|
|
||||||
<androidx.emoji2.widget.EmojiTextView
|
<androidx.emoji2.widget.EmojiTextView
|
||||||
android:id="@+id/referenceDescription"
|
android:id="@+id/cardDescription"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:ellipsize="end"
|
android:ellipsize="end"
|
||||||
@ -118,5 +119,9 @@
|
|||||||
app:layout_alignSelf="center"
|
app:layout_alignSelf="center"
|
||||||
app:tint="@color/high_emphasis_text" />
|
app:tint="@color/high_emphasis_text" />
|
||||||
|
|
||||||
|
<include
|
||||||
|
android:id="@+id/reactions"
|
||||||
|
layout="@layout/reactions_inside_message" />
|
||||||
|
|
||||||
</com.google.android.flexbox.FlexboxLayout>
|
</com.google.android.flexbox.FlexboxLayout>
|
||||||
</RelativeLayout>
|
</RelativeLayout>
|
||||||
|
@ -515,7 +515,7 @@ How to translate with transifex:
|
|||||||
<string name="typing_are_typing">are typing …</string>
|
<string name="typing_are_typing">are typing …</string>
|
||||||
<string name="typing_1_other">and 1 other is 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="typing_x_others">and %1$s others are typing …</string>
|
||||||
|
<string name="deck_card_description">%1$s in 2$s</string>
|
||||||
<!-- Upload -->
|
<!-- Upload -->
|
||||||
<string name="nc_add_file">Add to conversation</string>
|
<string name="nc_add_file">Add to conversation</string>
|
||||||
<string name="nc_upload_picture_from_cam">Take photo</string>
|
<string name="nc_upload_picture_from_cam">Take photo</string>
|
||||||
|
Loading…
Reference in New Issue
Block a user