Add remove avatar

This commit is contained in:
Andrew 2023-05-22 14:53:58 +09:30 committed by GitHub
parent 8f55ac93f8
commit a8e77659b3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 72 additions and 25 deletions

View File

@ -2,10 +2,7 @@ package org.thoughtcrime.securesms.preferences
import android.Manifest import android.Manifest
import android.app.Activity import android.app.Activity
import android.content.ClipData import android.content.*
import android.content.ClipboardManager
import android.content.Context
import android.content.Intent
import android.net.Uri import android.net.Uri
import android.os.AsyncTask import android.os.AsyncTask
import android.os.Bundle import android.os.Bundle
@ -19,6 +16,7 @@ import android.view.MenuItem
import android.view.View import android.view.View
import android.view.inputmethod.InputMethodManager import android.view.inputmethod.InputMethodManager
import android.widget.Toast import android.widget.Toast
import androidx.appcompat.app.AlertDialog
import androidx.core.view.isVisible import androidx.core.view.isVisible
import network.loki.messenger.BuildConfig import network.loki.messenger.BuildConfig
import network.loki.messenger.R import network.loki.messenger.R
@ -35,6 +33,7 @@ import org.session.libsession.utilities.SSKEnvironment.ProfileManagerProtocol
import org.session.libsession.utilities.TextSecurePreferences import org.session.libsession.utilities.TextSecurePreferences
import org.thoughtcrime.securesms.PassphraseRequiredActionBarActivity import org.thoughtcrime.securesms.PassphraseRequiredActionBarActivity
import org.thoughtcrime.securesms.avatar.AvatarSelection import org.thoughtcrime.securesms.avatar.AvatarSelection
import org.thoughtcrime.securesms.components.ProfilePictureView
import org.thoughtcrime.securesms.home.PathActivity import org.thoughtcrime.securesms.home.PathActivity
import org.thoughtcrime.securesms.messagerequests.MessageRequestsActivity import org.thoughtcrime.securesms.messagerequests.MessageRequestsActivity
import org.thoughtcrime.securesms.mms.GlideApp import org.thoughtcrime.securesms.mms.GlideApp
@ -57,8 +56,6 @@ class SettingsActivity : PassphraseRequiredActionBarActivity() {
private var displayNameEditActionMode: ActionMode? = null private var displayNameEditActionMode: ActionMode? = null
set(value) { field = value; handleDisplayNameEditActionModeChanged() } set(value) { field = value; handleDisplayNameEditActionModeChanged() }
private lateinit var glide: GlideRequests private lateinit var glide: GlideRequests
private var displayNameToBeUploaded: String? = null
private var profilePictureToBeUploaded: ByteArray? = null
private var tempFile: File? = null private var tempFile: File? = null
private val hexEncodedPublicKey: String private val hexEncodedPublicKey: String
@ -79,11 +76,7 @@ class SettingsActivity : PassphraseRequiredActionBarActivity() {
val displayName = TextSecurePreferences.getProfileName(this) ?: hexEncodedPublicKey val displayName = TextSecurePreferences.getProfileName(this) ?: hexEncodedPublicKey
glide = GlideApp.with(this) glide = GlideApp.with(this)
with(binding) { with(binding) {
profilePictureView.root.glide = glide setupProfilePictureView(profilePictureView.root)
profilePictureView.root.publicKey = hexEncodedPublicKey
profilePictureView.root.displayName = displayName
profilePictureView.root.isLarge = true
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
@ -105,6 +98,14 @@ class SettingsActivity : PassphraseRequiredActionBarActivity() {
} }
} }
private fun setupProfilePictureView(view: ProfilePictureView) {
view.glide = glide
view.publicKey = hexEncodedPublicKey
view.displayName = TextSecurePreferences.getProfileName(this) ?: hexEncodedPublicKey
view.isLarge = true
view.update()
}
override fun onSaveInstanceState(outState: Bundle) { override fun onSaveInstanceState(outState: Bundle) {
super.onSaveInstanceState(outState) super.onSaveInstanceState(outState)
val scrollBundle = SparseArray<Parcelable>() val scrollBundle = SparseArray<Parcelable>()
@ -154,9 +155,9 @@ class SettingsActivity : PassphraseRequiredActionBarActivity() {
} }
AsyncTask.execute { AsyncTask.execute {
try { try {
profilePictureToBeUploaded = BitmapUtil.createScaledBytes(this@SettingsActivity, AvatarSelection.getResultUri(data), ProfileMediaConstraints()).bitmap val profilePictureToBeUploaded = BitmapUtil.createScaledBytes(this@SettingsActivity, AvatarSelection.getResultUri(data), ProfileMediaConstraints()).bitmap
Handler(Looper.getMainLooper()).post { Handler(Looper.getMainLooper()).post {
updateProfile(true) updateProfile(true, profilePictureToBeUploaded)
} }
} catch (e: BitmapDecodingException) { } catch (e: BitmapDecodingException) {
e.printStackTrace() e.printStackTrace()
@ -190,23 +191,30 @@ class SettingsActivity : PassphraseRequiredActionBarActivity() {
} }
} }
private fun updateProfile(isUpdatingProfilePicture: Boolean) { private fun updateProfile(
isUpdatingProfilePicture: Boolean,
profilePicture: ByteArray? = null,
displayName: String? = null
) {
binding.loader.isVisible = true binding.loader.isVisible = true
val promises = mutableListOf<Promise<*, Exception>>() val promises = mutableListOf<Promise<*, Exception>>()
val displayName = displayNameToBeUploaded
if (displayName != null) { if (displayName != null) {
TextSecurePreferences.setProfileName(this, displayName) TextSecurePreferences.setProfileName(this, displayName)
} }
val profilePicture = profilePictureToBeUploaded
val encodedProfileKey = ProfileKeyUtil.generateEncodedProfileKey(this) val encodedProfileKey = ProfileKeyUtil.generateEncodedProfileKey(this)
if (isUpdatingProfilePicture && profilePicture != null) { if (isUpdatingProfilePicture) {
promises.add(ProfilePictureUtilities.upload(profilePicture, encodedProfileKey, this)) if (profilePicture != null) {
promises.add(ProfilePictureUtilities.upload(profilePicture, encodedProfileKey, this))
} else {
TextSecurePreferences.setLastProfilePictureUpload(this, System.currentTimeMillis())
TextSecurePreferences.setProfilePictureURL(this, null)
}
} }
val compoundPromise = all(promises) val compoundPromise = all(promises)
compoundPromise.successUi { // Do this on the UI thread so that it happens before the alwaysUi clause below compoundPromise.successUi { // Do this on the UI thread so that it happens before the alwaysUi clause below
if (isUpdatingProfilePicture && profilePicture != null) { if (isUpdatingProfilePicture) {
AvatarHelper.setAvatar(this, Address.fromSerialized(TextSecurePreferences.getLocalNumber(this)!!), profilePicture) AvatarHelper.setAvatar(this, Address.fromSerialized(TextSecurePreferences.getLocalNumber(this)!!), profilePicture)
TextSecurePreferences.setProfileAvatarId(this, SecureRandom().nextInt()) TextSecurePreferences.setProfileAvatarId(this, profilePicture?.let { SecureRandom().nextInt() } ?: 0 )
TextSecurePreferences.setLastProfilePictureUpload(this, Date().time) TextSecurePreferences.setLastProfilePictureUpload(this, Date().time)
ProfileKeyUtil.setEncodedProfileKey(this, encodedProfileKey) ProfileKeyUtil.setEncodedProfileKey(this, encodedProfileKey)
} }
@ -218,12 +226,10 @@ class SettingsActivity : PassphraseRequiredActionBarActivity() {
if (displayName != null) { if (displayName != null) {
binding.btnGroupNameDisplay.text = displayName binding.btnGroupNameDisplay.text = displayName
} }
if (isUpdatingProfilePicture && profilePicture != null) { if (isUpdatingProfilePicture) {
binding.profilePictureView.root.recycle() // Clear the cached image before updating binding.profilePictureView.root.recycle() // Clear the cached image before updating
binding.profilePictureView.root.update() binding.profilePictureView.root.update()
} }
displayNameToBeUploaded = null
profilePictureToBeUploaded = null
binding.loader.isVisible = false binding.loader.isVisible = false
} }
} }
@ -244,8 +250,7 @@ class SettingsActivity : PassphraseRequiredActionBarActivity() {
Toast.makeText(this, R.string.activity_settings_display_name_too_long_error, Toast.LENGTH_SHORT).show() Toast.makeText(this, R.string.activity_settings_display_name_too_long_error, Toast.LENGTH_SHORT).show()
return false return false
} }
displayNameToBeUploaded = displayName updateProfile(false, displayName = displayName)
updateProfile(false)
return true return true
} }
@ -255,6 +260,28 @@ class SettingsActivity : PassphraseRequiredActionBarActivity() {
} }
private fun showEditProfilePictureUI() { private fun showEditProfilePictureUI() {
AlertDialog.Builder(this)
.setTitle(R.string.activity_settings_set_display_picture)
.setView(R.layout.dialog_change_avatar)
.setPositiveButton(R.string.activity_settings_upload) { _, _ ->
startAvatarSelection()
}
.setNegativeButton(R.string.cancel) { _, _ -> }
.apply {
if (TextSecurePreferences.getProfileAvatarId(context) != 0) {
setNeutralButton(R.string.activity_settings_remove) { _, _ -> removeAvatar() }
}
}
.show().apply {
findViewById<ProfilePictureView>(R.id.profile_picture_view)?.let(::setupProfilePictureView)
}
}
private fun removeAvatar() {
updateProfile(true)
}
private fun startAvatarSelection() {
// Ask for an optional camera permission. // Ask for an optional camera permission.
Permissions.with(this) Permissions.with(this)
.request(Manifest.permission.CAMERA) .request(Manifest.permission.CAMERA)

View File

@ -0,0 +1,17 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
android:orientation="vertical"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_height="wrap_content"
android:layout_width="match_parent">
<include layout="@layout/view_profile_picture"
android:layout_margin="30dp"
android:id="@+id/profile_picture_view"
android:layout_gravity="center"
android:layout_width="@dimen/large_profile_picture_size"
android:layout_height="@dimen/large_profile_picture_size"
android:layout_marginTop="@dimen/medium_spacing"
android:contentDescription="@string/AccessibilityId_profile_picture" />
</FrameLayout>

View File

@ -769,6 +769,9 @@
<string name="activity_join_public_chat_scan_qr_code_explanation">Scan the QR code of the open group you\'d like to join</string> <string name="activity_join_public_chat_scan_qr_code_explanation">Scan the QR code of the open group you\'d like to join</string>
<string name="fragment_enter_chat_url_edit_text_hint">Enter an open group URL</string> <string name="fragment_enter_chat_url_edit_text_hint">Enter an open group URL</string>
<string name="activity_settings_title">Settings</string> <string name="activity_settings_title">Settings</string>
<string name="activity_settings_set_display_picture">Set display picture</string>
<string name="activity_settings_upload">Upload</string>
<string name="activity_settings_remove">Remove</string>
<string name="activity_settings_display_name_edit_text_hint">Enter a display name</string> <string name="activity_settings_display_name_edit_text_hint">Enter a display name</string>
<string name="activity_settings_display_name_missing_error">Please pick a display name</string> <string name="activity_settings_display_name_missing_error">Please pick a display name</string>
<string name="activity_settings_display_name_too_long_error">Please pick a shorter display name</string> <string name="activity_settings_display_name_too_long_error">Please pick a shorter display name</string>