session-android/app/src/main/java/org/thoughtcrime/securesms/loki/views/ProfilePictureView.kt

176 lines
7.5 KiB
Kotlin
Raw Normal View History

2020-05-11 08:19:26 +02:00
package org.thoughtcrime.securesms.loki.views
2019-12-17 16:24:42 +01:00
import android.content.Context
import android.util.AttributeSet
import android.view.LayoutInflater
import android.view.View
2019-12-19 11:15:58 +01:00
import android.widget.ImageView
2019-12-17 16:24:42 +01:00
import android.widget.RelativeLayout
import androidx.annotation.DimenRes
2019-12-19 11:15:58 +01:00
import com.bumptech.glide.load.engine.DiskCacheStrategy
import kotlinx.android.synthetic.main.view_profile_picture.view.*
2019-12-17 16:24:42 +01:00
import network.loki.messenger.R
2021-02-02 05:40:43 +01:00
import org.session.libsession.messaging.avatars.ProfileContactPhoto
2021-04-26 05:12:05 +02:00
import org.session.libsession.messaging.mentions.MentionsManager
2021-01-13 07:11:30 +01:00
import org.session.libsession.messaging.threads.Address
import org.session.libsession.messaging.threads.recipients.Recipient
2021-01-19 00:48:02 +01:00
import org.session.libsession.utilities.TextSecurePreferences
import org.thoughtcrime.securesms.database.DatabaseFactory
import org.thoughtcrime.securesms.loki.utilities.AvatarPlaceholderGenerator
import org.thoughtcrime.securesms.mms.GlideRequests
2019-12-17 16:24:42 +01:00
2020-01-06 06:05:57 +01:00
// TODO: Look into a better way of handling different sizes. Maybe an enum (with associated values) encapsulating the different modes?
2020-01-06 04:26:52 +01:00
2019-12-17 16:24:42 +01:00
class ProfilePictureView : RelativeLayout {
2019-12-19 11:15:58 +01:00
lateinit var glide: GlideRequests
2020-07-15 06:26:20 +02:00
var publicKey: String? = null
var displayName: String? = null
2020-07-15 06:26:20 +02:00
var additionalPublicKey: String? = null
var additionalDisplayName: String? = null
2019-12-17 16:24:42 +01:00
var isRSSFeed = false
2020-01-06 04:26:52 +01:00
var isLarge = false
private val imagesCached = mutableSetOf<String>()
2019-12-17 16:24:42 +01:00
// region Lifecycle
constructor(context: Context) : super(context) {
setUpViewHierarchy()
}
constructor(context: Context, attrs: AttributeSet) : super(context, attrs) {
setUpViewHierarchy()
}
constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int) : super(context, attrs, defStyleAttr) {
setUpViewHierarchy()
}
constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int, defStyleRes: Int) : super(context, attrs, defStyleAttr, defStyleRes) {
setUpViewHierarchy()
}
private fun setUpViewHierarchy() {
2020-08-25 15:52:42 +02:00
val inflater = context.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater
val contentView = inflater.inflate(R.layout.view_profile_picture, null)
2019-12-17 16:24:42 +01:00
addView(contentView)
}
// endregion
2019-12-17 16:24:42 +01:00
// region Updating
fun update(recipient: Recipient, threadID: Long) {
fun getUserDisplayName(publicKey: String?): String? {
if (publicKey == null || publicKey.isBlank()) {
return null
} else {
2020-09-12 00:52:44 +02:00
var result = DatabaseFactory.getLokiUserDatabase(context).getDisplayName(publicKey)
val publicChat = DatabaseFactory.getLokiThreadDatabase(context).getPublicChat(threadID)
if (result == null && publicChat != null) {
result = DatabaseFactory.getLokiUserDatabase(context).getServerDisplayName(publicChat.id, publicKey)
}
2020-09-18 01:19:47 +02:00
return result ?: publicKey
}
}
2020-10-28 05:04:47 +01:00
fun isOpenGroupWithProfilePicture(recipient: Recipient): Boolean {
return recipient.isOpenGroupRecipient && recipient.groupAvatarId != null
2020-09-25 13:11:55 +02:00
}
2020-10-28 05:04:47 +01:00
if (recipient.isGroupRecipient && !isOpenGroupWithProfilePicture(recipient)) {
val users = MentionsManager.shared.userPublicKeyCache[threadID]?.toMutableList() ?: mutableListOf()
users.remove(TextSecurePreferences.getLocalNumber(context))
val randomUsers = users.sorted().toMutableList() // Sort to provide a level of stability
if (users.count() == 1) {
2021-01-19 00:48:02 +01:00
val userPublicKey = TextSecurePreferences.getLocalNumber(context)!!
randomUsers.add(0, userPublicKey) // Ensure the current user is at the back visually
}
val pk = randomUsers.getOrNull(0) ?: ""
publicKey = pk
displayName = getUserDisplayName(pk)
val apk = randomUsers.getOrNull(1) ?: ""
additionalPublicKey = apk
additionalDisplayName = getUserDisplayName(apk)
isRSSFeed = recipient.name == "Loki News" ||
recipient.name == "Session Updates" ||
recipient.name == "Session Public Chat"
} else {
publicKey = recipient.address.toString()
2020-09-17 03:39:34 +02:00
displayName = getUserDisplayName(publicKey)
additionalPublicKey = null
isRSSFeed = false
}
update()
}
2019-12-17 16:24:42 +01:00
fun update() {
2020-07-15 06:26:20 +02:00
val publicKey = publicKey ?: return
val additionalPublicKey = additionalPublicKey
doubleModeImageViewContainer.visibility = if (additionalPublicKey != null && !isRSSFeed) {
setProfilePictureIfNeeded(
doubleModeImageView1,
publicKey,
displayName,
R.dimen.small_profile_picture_size)
setProfilePictureIfNeeded(
doubleModeImageView2,
additionalPublicKey,
additionalDisplayName,
R.dimen.small_profile_picture_size)
View.VISIBLE
} else {
glide.clear(doubleModeImageView1)
glide.clear(doubleModeImageView2)
View.INVISIBLE
}
singleModeImageViewContainer.visibility = if (additionalPublicKey == null && !isRSSFeed && !isLarge) {
setProfilePictureIfNeeded(
singleModeImageView,
publicKey,
displayName,
R.dimen.medium_profile_picture_size)
View.VISIBLE
} else {
glide.clear(singleModeImageView)
View.INVISIBLE
}
largeSingleModeImageViewContainer.visibility = if (additionalPublicKey == null && !isRSSFeed && isLarge) {
setProfilePictureIfNeeded(
largeSingleModeImageView,
publicKey,
displayName,
R.dimen.large_profile_picture_size)
View.VISIBLE
} else {
glide.clear(largeSingleModeImageView)
View.INVISIBLE
}
2020-01-23 00:25:22 +01:00
rssImageView.visibility = if (isRSSFeed) View.VISIBLE else View.INVISIBLE
}
2020-09-09 05:57:22 +02:00
private fun setProfilePictureIfNeeded(imageView: ImageView, publicKey: String, displayName: String?, @DimenRes sizeResId: Int) {
if (publicKey.isNotEmpty()) {
val recipient = Recipient.from(context, Address.fromSerialized(publicKey), false)
2021-04-26 06:14:39 +02:00
if (imagesCached.contains(publicKey)) return
val signalProfilePicture = recipient.contactPhoto
2020-09-09 05:57:22 +02:00
if (signalProfilePicture != null && (signalProfilePicture as? ProfileContactPhoto)?.avatarObject != "0"
&& (signalProfilePicture as? ProfileContactPhoto)?.avatarObject != "") {
glide.clear(imageView)
glide.load(signalProfilePicture).diskCacheStrategy(DiskCacheStrategy.AUTOMATIC).circleCrop().into(imageView)
2021-04-26 06:14:39 +02:00
imagesCached.add(publicKey)
2019-12-19 11:15:58 +01:00
} else {
2020-09-09 05:57:22 +02:00
val sizeInPX = resources.getDimensionPixelSize(sizeResId)
glide.clear(imageView)
glide.load(AvatarPlaceholderGenerator.generate(
context,
2020-09-09 05:57:22 +02:00
sizeInPX,
2021-02-18 05:12:30 +01:00
publicKey,
displayName
)).diskCacheStrategy(DiskCacheStrategy.ALL).circleCrop().into(imageView)
2021-04-26 06:14:39 +02:00
imagesCached.add(publicKey)
2019-12-19 11:15:58 +01:00
}
} else {
imageView.setImageDrawable(null)
2019-12-19 11:15:58 +01:00
}
2019-12-17 16:24:42 +01:00
}
fun recycle() {
imagesCached.clear()
}
2019-12-17 16:24:42 +01:00
// endregion
}