feat: support avatar removal from shared library

This commit is contained in:
0x330a 2023-03-27 11:07:14 +11:00
parent 03d3199ed2
commit d3c55fad60
No known key found for this signature in database
GPG Key ID: 267811D6E6A2698C
6 changed files with 59 additions and 35 deletions

View File

@ -338,11 +338,7 @@ class Storage(context: Context, helper: SQLCipherOpenHelper, private val configF
// update pfp // update pfp
if (userPic == UserPic.DEFAULT) { if (userPic == UserPic.DEFAULT) {
// clear picture if userPic is null clearUserPic()
TextSecurePreferences.setProfileKey(context, null)
ProfileKeyUtil.setEncodedProfileKey(context, null)
profileManager.setProfileKey(context, recipient, null)
setUserProfilePictureURL(null)
} else if (userPic.key.isNotEmpty() && userPic.url.isNotEmpty() } else if (userPic.key.isNotEmpty() && userPic.url.isNotEmpty()
&& TextSecurePreferences.getProfilePictureURL(context) != userPic.url) { && TextSecurePreferences.getProfilePictureURL(context) != userPic.url) {
val profileKey = Base64.encodeBytes(userPic.key) val profileKey = Base64.encodeBytes(userPic.key)
@ -354,25 +350,25 @@ class Storage(context: Context, helper: SQLCipherOpenHelper, private val configF
private fun updateContacts(contacts: Contacts) { private fun updateContacts(contacts: Contacts) {
val extracted = contacts.all().toList() val extracted = contacts.all().toList()
val profileManager = SSKEnvironment.shared.profileManager addLibSessionContacts(extracted)
extracted.forEach { contact -> }
val address = fromSerialized(contact.id)
val recipient = Recipient.from(context, address, false)
setBlocked(listOf(recipient), contact.blocked, fromConfigUpdate = true)
setRecipientApproved(recipient, contact.approved)
setRecipientApprovedMe(recipient, contact.approvedMe)
profileManager.setName(context, recipient, contact.name)
profileManager.setNickname(context, recipient, contact.nickname)
if (contact.profilePicture != UserPic.DEFAULT) { override fun clearUserPic() {
val (url, key) = contact.profilePicture val userPublicKey = getUserPublicKey() ?: return
if (key.size != ProfileKeyUtil.PROFILE_KEY_BYTES) return@forEach val recipientDatabase = DatabaseComponent.get(context).recipientDatabase()
profileManager.setProfileKey(context, recipient, key) // would love to get rid of recipient and context from this
profileManager.setUnidentifiedAccessMode(context, recipient, Recipient.UnidentifiedAccessMode.UNKNOWN) val recipient = Recipient.from(context, fromSerialized(userPublicKey), false)
profileManager.setProfilePictureURL(context, recipient, url) // clear picture if userPic is null
} TextSecurePreferences.setProfileKey(context, null)
Log.d("Loki-DBG", "Updated contact $contact") TextSecurePreferences.setProfileAvatarId(context, 0)
} ProfileKeyUtil.setEncodedProfileKey(context, null)
SSKEnvironment.shared.profileManager.setProfileKey(context, recipient, null)
recipientDatabase.setProfileAvatar(recipient, null)
setUserProfilePictureURL(null)
Recipient.removeCached(fromSerialized(userPublicKey))
configFactory.user?.setPic(UserPic.DEFAULT)
ConfigurationMessageUtilities.forceSyncConfigurationNowIfNeeded(context)
} }
private fun updateConvoVolatile(convos: ConversationVolatileConfig) { private fun updateConvoVolatile(convos: ConversationVolatileConfig) {
@ -972,21 +968,37 @@ class Storage(context: Context, helper: SQLCipherOpenHelper, private val configF
} }
override fun addLibSessionContacts(contacts: List<LibSessionContact>) { override fun addLibSessionContacts(contacts: List<LibSessionContact>) {
val recipientDatabase = DatabaseComponent.get(context).recipientDatabase()
val threadDatabase = DatabaseComponent.get(context).threadDatabase()
val mappingDb = DatabaseComponent.get(context).blindedIdMappingDatabase() val mappingDb = DatabaseComponent.get(context).blindedIdMappingDatabase()
val moreContacts = contacts.filter { contact -> val moreContacts = contacts.filter { contact ->
val id = SessionId(contact.id) val id = SessionId(contact.id)
id.prefix != IdPrefix.BLINDED || mappingDb.getBlindedIdMapping(contact.id).none { it.sessionId != null } id.prefix != IdPrefix.BLINDED || mappingDb.getBlindedIdMapping(contact.id).none { it.sessionId != null }
} }
for (contact in moreContacts) { val profileManager = SSKEnvironment.shared.profileManager
moreContacts.forEach { contact ->
val address = fromSerialized(contact.id) val address = fromSerialized(contact.id)
val recipient = Recipient.from(context, address, true) val recipient = Recipient.from(context, address, false)
val (url, key) = contact.profilePicture.let { it.url to it.key } setBlocked(listOf(recipient), contact.blocked, fromConfigUpdate = true)
// set or clear the avatar setRecipientApproved(recipient, contact.approved)
recipientDatabase.setProfileAvatar(recipient, url) setRecipientApprovedMe(recipient, contact.approvedMe)
recipientDatabase.setProfileKey(recipient, key) if (contact.name.isNotEmpty()) {
profileManager.setName(context, recipient, contact.name)
} else {
profileManager.setName(context, recipient, null)
}
if (contact.nickname.isNotEmpty()) {
profileManager.setNickname(context, recipient, contact.nickname)
} else {
profileManager.setNickname(context, recipient, null)
}
if (contact.profilePicture != UserPic.DEFAULT) {
val (url, key) = contact.profilePicture
if (key.size != ProfileKeyUtil.PROFILE_KEY_BYTES) return@forEach
profileManager.setProfileKey(context, recipient, key)
profileManager.setUnidentifiedAccessMode(context, recipient, Recipient.UnidentifiedAccessMode.UNKNOWN)
profileManager.setProfilePictureURL(context, recipient, url)
}
Log.d("Loki-DBG", "Updated contact $contact")
} }
} }

View File

@ -93,7 +93,7 @@ public class RetrieveProfileAvatarJob extends BaseJob {
if (TextUtils.isEmpty(profileAvatar)) { if (TextUtils.isEmpty(profileAvatar)) {
Log.w(TAG, "Removing profile avatar for: " + recipient.getAddress().serialize()); Log.w(TAG, "Removing profile avatar for: " + recipient.getAddress().serialize());
AvatarHelper.delete(context, recipient.getAddress()); AvatarHelper.delete(context, recipient.getAddress());
database.setProfileAvatar(recipient, profileAvatar); database.setProfileAvatar(recipient, null);
return; return;
} }

View File

@ -30,6 +30,7 @@ import nl.komponents.kovenant.all
import nl.komponents.kovenant.ui.alwaysUi import nl.komponents.kovenant.ui.alwaysUi
import nl.komponents.kovenant.ui.successUi import nl.komponents.kovenant.ui.successUi
import org.session.libsession.avatars.AvatarHelper import org.session.libsession.avatars.AvatarHelper
import org.session.libsession.messaging.MessagingModuleConfiguration
import org.session.libsession.utilities.Address import org.session.libsession.utilities.Address
import org.session.libsession.utilities.ProfileKeyUtil import org.session.libsession.utilities.ProfileKeyUtil
import org.session.libsession.utilities.ProfilePictureUtilities import org.session.libsession.utilities.ProfilePictureUtilities
@ -92,7 +93,9 @@ class SettingsActivity : PassphraseRequiredActionBarActivity() {
profilePictureView.root.displayName = displayName profilePictureView.root.displayName = displayName
profilePictureView.root.isLarge = true profilePictureView.root.isLarge = true
profilePictureView.root.update() profilePictureView.root.update()
profilePictureView.root.setOnClickListener { showEditProfilePictureUI() } profilePictureView.root.setOnClickListener {
showEditProfilePictureUI()
}
ctnGroupNameSection.setOnClickListener { startActionMode(DisplayNameEditActionModeCallback()) } ctnGroupNameSection.setOnClickListener { startActionMode(DisplayNameEditActionModeCallback()) }
btnGroupNameDisplay.text = displayName btnGroupNameDisplay.text = displayName
publicKeyTextView.text = hexEncodedPublicKey publicKeyTextView.text = hexEncodedPublicKey
@ -270,6 +273,14 @@ class SettingsActivity : PassphraseRequiredActionBarActivity() {
push(intent) push(intent)
} }
private fun deleteProfilePicture() {
MessagingModuleConfiguration.shared.storage.clearUserPic()
with (binding.profilePictureView.root) {
recycle()
update()
}
}
private fun showEditProfilePictureUI() { private fun showEditProfilePictureUI() {
// Ask for an optional camera permission. // Ask for an optional camera permission.
Permissions.with(this) Permissions.with(this)

View File

@ -29,7 +29,7 @@ class ProfileManager(private val context: Context, private val configFactory: Co
contactUpdatedInternal(contact) contactUpdatedInternal(contact)
} }
override fun setName(context: Context, recipient: Recipient, name: String) { override fun setName(context: Context, recipient: Recipient, name: String?) {
// New API // New API
val sessionID = recipient.address.serialize() val sessionID = recipient.address.serialize()
val contactDatabase = DatabaseComponent.get(context).sessionContactDatabase() val contactDatabase = DatabaseComponent.get(context).sessionContactDatabase()

View File

@ -41,6 +41,7 @@ interface StorageProtocol {
fun getUserX25519KeyPair(): ECKeyPair fun getUserX25519KeyPair(): ECKeyPair
fun getUserProfile(): Profile fun getUserProfile(): Profile
fun setUserProfilePictureURL(newProfilePicture: String?) fun setUserProfilePictureURL(newProfilePicture: String?)
fun clearUserPic()
// Signal // Signal
fun getOrGenerateRegistrationID(): Int fun getOrGenerateRegistrationID(): Int

View File

@ -30,7 +30,7 @@ class SSKEnvironment(
} }
fun setNickname(context: Context, recipient: Recipient, nickname: String?) fun setNickname(context: Context, recipient: Recipient, nickname: String?)
fun setName(context: Context, recipient: Recipient, name: String) fun setName(context: Context, recipient: Recipient, name: String?)
fun setProfilePictureURL(context: Context, recipient: Recipient, profilePictureURL: String) fun setProfilePictureURL(context: Context, recipient: Recipient, profilePictureURL: String)
fun setProfileKey(context: Context, recipient: Recipient, profileKey: ByteArray?) fun setProfileKey(context: Context, recipient: Recipient, profileKey: ByteArray?)
fun setUnidentifiedAccessMode(context: Context, recipient: Recipient, unidentifiedAccessMode: Recipient.UnidentifiedAccessMode) fun setUnidentifiedAccessMode(context: Context, recipient: Recipient, unidentifiedAccessMode: Recipient.UnidentifiedAccessMode)