2020-05-11 08:19:26 +02:00
|
|
|
package org.thoughtcrime.securesms.loki.views
|
2019-12-17 14:27:59 +01:00
|
|
|
|
|
|
|
import android.content.Context
|
2019-12-17 15:15:13 +01:00
|
|
|
import android.graphics.Typeface
|
2019-12-17 14:27:59 +01:00
|
|
|
import android.util.AttributeSet
|
|
|
|
import android.view.LayoutInflater
|
2019-12-17 15:15:13 +01:00
|
|
|
import android.view.View
|
2019-12-17 14:27:59 +01:00
|
|
|
import android.widget.LinearLayout
|
2019-12-18 11:36:09 +01:00
|
|
|
import kotlinx.android.synthetic.main.view_conversation.view.*
|
2019-12-17 14:27:59 +01:00
|
|
|
import network.loki.messenger.R
|
|
|
|
import org.thoughtcrime.securesms.database.model.ThreadRecord
|
2020-05-30 00:53:00 +02:00
|
|
|
import org.thoughtcrime.securesms.loki.utilities.MentionManagerUtilities.populateUserPublicKeyCacheIfNeeded
|
2020-05-11 08:19:26 +02:00
|
|
|
import org.thoughtcrime.securesms.loki.utilities.MentionUtilities.highlightMentions
|
2019-12-19 11:15:58 +01:00
|
|
|
import org.thoughtcrime.securesms.mms.GlideRequests
|
2019-12-17 15:15:13 +01:00
|
|
|
import org.thoughtcrime.securesms.util.DateUtils
|
2020-07-16 03:20:39 +02:00
|
|
|
import org.thoughtcrime.securesms.util.TextSecurePreferences
|
2020-05-07 09:59:41 +02:00
|
|
|
import org.whispersystems.signalservice.loki.protocol.mentions.MentionsManager
|
2019-12-17 15:15:13 +01:00
|
|
|
import java.util.*
|
2019-12-17 14:27:59 +01:00
|
|
|
|
|
|
|
class ConversationView : LinearLayout {
|
2019-12-17 15:15:13 +01:00
|
|
|
var thread: ThreadRecord? = null
|
2019-12-17 14:27:59 +01:00
|
|
|
|
|
|
|
// region Lifecycle
|
2019-12-17 16:24:42 +01:00
|
|
|
constructor(context: Context) : super(context) {
|
|
|
|
setUpViewHierarchy()
|
2019-12-17 14:27:59 +01:00
|
|
|
}
|
|
|
|
|
2019-12-17 16:24:42 +01:00
|
|
|
constructor(context: Context, attrs: AttributeSet) : super(context, attrs) {
|
|
|
|
setUpViewHierarchy()
|
|
|
|
}
|
2019-12-17 14:27:59 +01:00
|
|
|
|
2019-12-17 16:24:42 +01:00
|
|
|
constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int) : super(context, attrs, defStyleAttr) {
|
|
|
|
setUpViewHierarchy()
|
|
|
|
}
|
2019-12-17 14:27:59 +01:00
|
|
|
|
2019-12-17 16:24:42 +01:00
|
|
|
constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int, defStyleRes: Int) : super(context, attrs, defStyleAttr, defStyleRes) {
|
|
|
|
setUpViewHierarchy()
|
|
|
|
}
|
2019-12-17 14:27:59 +01:00
|
|
|
|
2019-12-17 16:24:42 +01:00
|
|
|
private fun setUpViewHierarchy() {
|
2020-08-24 07:33:01 +02:00
|
|
|
val inflater = context.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater
|
2019-12-18 11:36:09 +01:00
|
|
|
val contentView = inflater.inflate(R.layout.view_conversation, null)
|
2019-12-17 16:24:42 +01:00
|
|
|
addView(contentView)
|
|
|
|
}
|
2019-12-17 14:27:59 +01:00
|
|
|
// endregion
|
|
|
|
|
|
|
|
// region Updating
|
2019-12-19 11:15:58 +01:00
|
|
|
fun bind(thread: ThreadRecord, isTyping: Boolean, glide: GlideRequests) {
|
2019-12-17 15:15:13 +01:00
|
|
|
this.thread = thread
|
2020-07-16 03:20:39 +02:00
|
|
|
populateUserPublicKeyCacheIfNeeded(thread.threadId, context) // FIXME: This is a bad place to do this
|
|
|
|
if (thread.recipient.isBlocked) {
|
|
|
|
accentView.setBackgroundResource(R.color.destructive)
|
|
|
|
accentView.visibility = View.VISIBLE
|
|
|
|
} else {
|
|
|
|
accentView.setBackgroundResource(R.color.accent)
|
|
|
|
accentView.visibility = if (thread.unreadCount > 0) View.VISIBLE else View.INVISIBLE
|
|
|
|
}
|
2019-12-17 16:24:42 +01:00
|
|
|
if (thread.recipient.isGroupRecipient) {
|
2020-02-06 01:58:30 +01:00
|
|
|
if ("Session Public Chat" == thread.recipient.name) {
|
2020-07-15 06:26:20 +02:00
|
|
|
profilePictureView.publicKey = ""
|
2020-07-16 03:20:39 +02:00
|
|
|
profilePictureView.additionalPublicKey = null
|
2020-02-06 01:58:30 +01:00
|
|
|
profilePictureView.isRSSFeed = true
|
|
|
|
} else {
|
2020-07-16 03:20:39 +02:00
|
|
|
val users = MentionsManager.shared.userPublicKeyCache[thread.threadId]?.toMutableList() ?: mutableListOf()
|
|
|
|
users.remove(TextSecurePreferences.getLocalNumber(context))
|
|
|
|
val masterPublicKey = TextSecurePreferences.getMasterHexEncodedPublicKey(context)
|
|
|
|
if (masterPublicKey != null) {
|
|
|
|
users.remove(masterPublicKey)
|
|
|
|
}
|
2020-02-06 01:58:30 +01:00
|
|
|
val randomUsers = users.sorted() // Sort to provide a level of stability
|
2020-07-15 06:26:20 +02:00
|
|
|
profilePictureView.publicKey = randomUsers.getOrNull(0) ?: ""
|
|
|
|
profilePictureView.additionalPublicKey = randomUsers.getOrNull(1) ?: ""
|
2020-02-06 01:58:30 +01:00
|
|
|
profilePictureView.isRSSFeed = thread.recipient.name == "Loki News" || thread.recipient.name == "Session Updates"
|
|
|
|
}
|
2019-12-17 16:24:42 +01:00
|
|
|
} else {
|
2020-07-15 06:26:20 +02:00
|
|
|
profilePictureView.publicKey = thread.recipient.address.toString()
|
|
|
|
profilePictureView.additionalPublicKey = null
|
2019-12-17 16:24:42 +01:00
|
|
|
profilePictureView.isRSSFeed = false
|
|
|
|
}
|
2019-12-19 11:15:58 +01:00
|
|
|
profilePictureView.glide = glide
|
2019-12-17 16:24:42 +01:00
|
|
|
profilePictureView.update()
|
2020-01-17 05:00:36 +01:00
|
|
|
val senderDisplayName = if (thread.recipient.isLocalNumber) context.getString(R.string.note_to_self) else if (!thread.recipient.name.isNullOrEmpty()) thread.recipient.name else thread.recipient.address.toString()
|
2020-08-14 11:26:56 +02:00
|
|
|
btnGroupNameDisplay.text = senderDisplayName
|
2019-12-17 15:15:13 +01:00
|
|
|
timestampTextView.text = DateUtils.getBriefRelativeTimeSpanString(context, Locale.getDefault(), thread.date)
|
2020-01-16 01:48:49 +01:00
|
|
|
muteIndicatorImageView.visibility = if (thread.recipient.isMuted) VISIBLE else GONE
|
2019-12-17 15:15:13 +01:00
|
|
|
val rawSnippet = thread.getDisplayBody(context)
|
|
|
|
val snippet = highlightMentions(rawSnippet, thread.threadId, context)
|
|
|
|
snippetTextView.text = snippet
|
|
|
|
snippetTextView.typeface = if (thread.unreadCount > 0) Typeface.DEFAULT_BOLD else Typeface.DEFAULT
|
2019-12-19 11:15:58 +01:00
|
|
|
snippetTextView.visibility = if (isTyping) View.GONE else View.VISIBLE
|
|
|
|
if (isTyping) {
|
|
|
|
typingIndicatorView.startAnimation()
|
|
|
|
} else {
|
|
|
|
typingIndicatorView.stopAnimation()
|
|
|
|
}
|
|
|
|
typingIndicatorView.visibility = if (isTyping) View.VISIBLE else View.GONE
|
|
|
|
statusIndicatorImageView.visibility = View.VISIBLE
|
|
|
|
when {
|
|
|
|
!thread.isOutgoing || thread.isVerificationStatusChange -> statusIndicatorImageView.visibility = View.GONE
|
|
|
|
thread.isFailed -> statusIndicatorImageView.setImageResource(R.drawable.ic_error)
|
|
|
|
thread.isPending -> statusIndicatorImageView.setImageResource(R.drawable.ic_circle_dot_dot_dot)
|
|
|
|
thread.isRemoteRead -> statusIndicatorImageView.setImageResource(R.drawable.ic_filled_circle_check)
|
|
|
|
else -> statusIndicatorImageView.setImageResource(R.drawable.ic_circle_check)
|
|
|
|
}
|
2019-12-17 14:27:59 +01:00
|
|
|
}
|
|
|
|
// endregion
|
|
|
|
}
|