|
@@ -0,0 +1,207 @@
|
|
|
+/*
|
|
|
+ * Nextcloud Talk application
|
|
|
+ *
|
|
|
+ * @author Mario Danic
|
|
|
+ * @author Marcel Hibbe
|
|
|
+ * Copyright (C) 2022 Marcel Hibbe <dev@mhibbe.de>
|
|
|
+ * Copyright (C) 2017-2019 Mario Danic <mario@lovelyhq.com>
|
|
|
+ *
|
|
|
+ * 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.annotation.SuppressLint
|
|
|
+import android.content.Context
|
|
|
+import android.graphics.drawable.Drawable
|
|
|
+import android.graphics.drawable.LayerDrawable
|
|
|
+import android.os.Build
|
|
|
+import android.text.TextUtils
|
|
|
+import android.view.View
|
|
|
+import androidx.core.content.ContextCompat
|
|
|
+import androidx.core.content.res.ResourcesCompat
|
|
|
+import autodagger.AutoInjector
|
|
|
+import coil.load
|
|
|
+import com.amulyakhare.textdrawable.TextDrawable
|
|
|
+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.databinding.ItemCustomIncomingLinkPreviewMessageBinding
|
|
|
+import com.nextcloud.talk.models.json.chat.ChatMessage
|
|
|
+import com.nextcloud.talk.ui.theme.ViewThemeUtils
|
|
|
+import com.nextcloud.talk.utils.ApiUtils
|
|
|
+import com.nextcloud.talk.utils.DisplayUtils
|
|
|
+import com.nextcloud.talk.utils.preferences.AppPreferences
|
|
|
+import com.stfalcon.chatkit.messages.MessageHolders
|
|
|
+import javax.inject.Inject
|
|
|
+
|
|
|
+@AutoInjector(NextcloudTalkApplication::class)
|
|
|
+class IncomingLinkPreviewMessageViewHolder(incomingView: View, payload: Any) : MessageHolders
|
|
|
+.IncomingTextMessageViewHolder<ChatMessage>(incomingView, payload) {
|
|
|
+
|
|
|
+ private val binding: ItemCustomIncomingLinkPreviewMessageBinding =
|
|
|
+ ItemCustomIncomingLinkPreviewMessageBinding.bind(itemView)
|
|
|
+
|
|
|
+ @Inject
|
|
|
+ lateinit var context: Context
|
|
|
+
|
|
|
+ @Inject
|
|
|
+ lateinit var appPreferences: AppPreferences
|
|
|
+
|
|
|
+ @Inject
|
|
|
+ lateinit var viewThemeUtils: ViewThemeUtils
|
|
|
+
|
|
|
+ @Inject
|
|
|
+ lateinit var ncApi: NcApi
|
|
|
+
|
|
|
+ lateinit var message: ChatMessage
|
|
|
+
|
|
|
+ lateinit var reactionsInterface: ReactionsInterface
|
|
|
+
|
|
|
+ @SuppressLint("SetTextI18n")
|
|
|
+ override fun onBind(message: ChatMessage) {
|
|
|
+ super.onBind(message)
|
|
|
+ this.message = message
|
|
|
+ sharedApplication!!.componentApplication.inject(this)
|
|
|
+
|
|
|
+ setAvatarAndAuthorOnMessageItem(message)
|
|
|
+
|
|
|
+ colorizeMessageBubble(message)
|
|
|
+
|
|
|
+ itemView.isSelected = false
|
|
|
+
|
|
|
+ // parent message handling
|
|
|
+ setParentMessageDataOnMessageItem(message)
|
|
|
+
|
|
|
+ LinkPreview().showLink(
|
|
|
+ message,
|
|
|
+ ncApi,
|
|
|
+ binding.referenceInclude,
|
|
|
+ context
|
|
|
+ )
|
|
|
+
|
|
|
+ Reaction().showReactions(
|
|
|
+ message,
|
|
|
+ binding.reactions,
|
|
|
+ binding.messageTime.context,
|
|
|
+ false,
|
|
|
+ viewThemeUtils
|
|
|
+ )
|
|
|
+ binding.reactions.reactionsEmojiWrapper.setOnClickListener {
|
|
|
+ reactionsInterface.onClickReactions(message)
|
|
|
+ }
|
|
|
+ binding.reactions.reactionsEmojiWrapper.setOnLongClickListener { l: View? ->
|
|
|
+ reactionsInterface.onLongClickReactions(message)
|
|
|
+ true
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private fun setAvatarAndAuthorOnMessageItem(message: ChatMessage) {
|
|
|
+ val author: String = message.actorDisplayName!!
|
|
|
+ if (!TextUtils.isEmpty(author)) {
|
|
|
+ binding.messageAuthor.text = author
|
|
|
+ binding.messageUserAvatar.setOnClickListener {
|
|
|
+ (payload as? MessagePayload)?.profileBottomSheet?.showFor(message.actorId!!, itemView.context)
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ binding.messageAuthor.setText(R.string.nc_nick_guest)
|
|
|
+ }
|
|
|
+
|
|
|
+ if (!message.isGrouped && !message.isOneToOneConversation) {
|
|
|
+ setAvatarOnMessage(message)
|
|
|
+ } else {
|
|
|
+ if (message.isOneToOneConversation) {
|
|
|
+ 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") {
|
|
|
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
|
|
+ val layers = arrayOfNulls<Drawable>(2)
|
|
|
+ layers[0] = ContextCompat.getDrawable(context, R.drawable.ic_launcher_background)
|
|
|
+ layers[1] = ContextCompat.getDrawable(context, R.drawable.ic_launcher_foreground)
|
|
|
+ val layerDrawable = LayerDrawable(layers)
|
|
|
+ binding.messageUserAvatar.setImageDrawable(DisplayUtils.getRoundedDrawable(layerDrawable))
|
|
|
+ } else {
|
|
|
+ binding.messageUserAvatar.setImageResource(R.mipmap.ic_launcher)
|
|
|
+ }
|
|
|
+ } else if (message.actorType == "bots") {
|
|
|
+ val drawable = TextDrawable.builder()
|
|
|
+ .beginConfig()
|
|
|
+ .bold()
|
|
|
+ .endConfig()
|
|
|
+ .buildRound(
|
|
|
+ ">",
|
|
|
+ ResourcesCompat.getColor(context.resources, R.color.black, null)
|
|
|
+ )
|
|
|
+ binding.messageUserAvatar.visibility = View.VISIBLE
|
|
|
+ binding.messageUserAvatar.setImageDrawable(drawable)
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private fun colorizeMessageBubble(message: ChatMessage) {
|
|
|
+ viewThemeUtils.talk.themeIncomingMessageBubble(bubble, message.isGrouped, message.isDeleted)
|
|
|
+ }
|
|
|
+
|
|
|
+ private fun setParentMessageDataOnMessageItem(message: ChatMessage) {
|
|
|
+ if (!message.isDeleted && message.parentMessage != null) {
|
|
|
+ val parentChatMessage = message.parentMessage
|
|
|
+ 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 = parentChatMessage.text
|
|
|
+
|
|
|
+ binding.messageQuote.quotedMessageAuthor
|
|
|
+ .setTextColor(ContextCompat.getColor(context, R.color.textColorMaxContrast))
|
|
|
+
|
|
|
+ if (parentChatMessage.actorId?.equals(message.activeUser!!.userId) == true) {
|
|
|
+ viewThemeUtils.platform.colorPrimaryView(binding.messageQuote.quoteColoredView)
|
|
|
+ } else {
|
|
|
+ binding.messageQuote.quoteColoredView.setBackgroundResource(R.color.textColorMaxContrast)
|
|
|
+ }
|
|
|
+
|
|
|
+ binding.messageQuote.quotedChatMessageView.visibility = View.VISIBLE
|
|
|
+ } else {
|
|
|
+ binding.messageQuote.quotedChatMessageView.visibility = View.GONE
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ fun assignReactionInterface(reactionsInterface: ReactionsInterface) {
|
|
|
+ this.reactionsInterface = reactionsInterface
|
|
|
+ }
|
|
|
+
|
|
|
+ companion object {
|
|
|
+ private val TAG = IncomingLinkPreviewMessageViewHolder::class.java.simpleName
|
|
|
+ }
|
|
|
+}
|