Implement profile picture editing

pull/58/head
Niels Andriesse 5 years ago
parent fd14d66d4f
commit 15b4c6aacc

@ -197,6 +197,7 @@ dependencies {
}
implementation "com.jakewharton.rxbinding3:rxbinding:3.1.0"
implementation "com.github.tbruyelle:rxpermissions:0.10.2"
implementation "com.github.ybq:Android-SpinKit:1.4.0"
}
def canonicalVersionCode = 23

@ -24,7 +24,7 @@
android:id="@+id/profileButton"
android:layout_width="@dimen/small_profile_picture_size"
android:layout_height="@dimen/small_profile_picture_size"
android:layout_marginLeft="8dp"
android:layout_marginLeft="10dp"
android:layout_alignParentLeft="true"
android:layout_centerVertical="true" />

@ -1,258 +1,283 @@
<?xml version="1.0" encoding="utf-8"?>
<ScrollView
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:scrollbars="none">
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/default_session_background">
<LinearLayout
<ScrollView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/default_session_background"
android:orientation="vertical"
android:gravity="center_horizontal">
android:scrollbars="none">
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
<LinearLayout
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:minHeight="?attr/actionBarSize"
app:contentInsetLeft="20dp"
app:contentInsetRight="20dp"
android:theme="?attr/actionBarStyle">
android:layout_height="wrap_content"
android:orientation="vertical"
android:gravity="center_horizontal">
<LinearLayout
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center_vertical"
android:orientation="horizontal">
android:layout_height="?attr/actionBarSize"
android:minHeight="?attr/actionBarSize"
app:contentInsetLeft="20dp"
app:contentInsetRight="20dp"
android:theme="?attr/actionBarStyle">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center_vertical"
android:orientation="horizontal">
<ImageView
android:id="@+id/cancelButton"
android:layout_width="24dp"
android:layout_height="24dp"
android:src="@drawable/ic_close_white_24dp"
android:visibility="gone" />
<TextView
android:id="@+id/titleTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Settings"
android:textColor="@color/text"
android:textSize="@dimen/very_large_font_size"
android:fontFamily="sans-serif-medium" />
<View
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1" />
<ImageView
android:id="@+id/saveButton"
android:layout_width="24dp"
android:layout_height="24dp"
android:src="@drawable/ic_check_white_24dp"
android:visibility="gone" />
<ImageView
android:id="@+id/showQRCodeButton"
android:layout_width="24dp"
android:layout_height="24dp"
android:src="@drawable/ic_qr_code" />
</LinearLayout>
</android.support.v7.widget.Toolbar>
<org.thoughtcrime.securesms.loki.redesign.views.ProfilePictureView
android:id="@+id/profilePictureView"
android:layout_width="@dimen/large_profile_picture_size"
android:layout_height="@dimen/large_profile_picture_size"
android:layout_marginTop="@dimen/medium_spacing" />
<RelativeLayout
android:id="@+id/displayNameContainer"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="@dimen/large_spacing"
android:layout_marginTop="@dimen/small_spacing"
android:layout_marginRight="@dimen/large_spacing">
<ImageView
android:id="@+id/cancelButton"
android:layout_width="24dp"
android:layout_height="24dp"
android:src="@drawable/ic_close_white_24dp"
android:visibility="gone" />
<EditText
style="@style/SessionEditText"
android:id="@+id/displayNameEditText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:textAlignment="center"
android:paddingTop="12dp"
android:paddingBottom="12dp"
android:visibility="invisible"
android:hint="Enter a display name" />
<TextView
android:id="@+id/titleTextView"
android:id="@+id/displayNameTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Settings"
android:layout_centerInParent="true"
android:textColor="@color/text"
android:textSize="@dimen/very_large_font_size"
android:fontFamily="sans-serif-medium" />
android:textStyle="bold" />
<View
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1" />
</RelativeLayout>
<ImageView
android:id="@+id/saveButton"
android:layout_width="24dp"
android:layout_height="24dp"
android:src="@drawable/ic_check_white_24dp"
android:visibility="gone" />
<org.thoughtcrime.securesms.loki.redesign.views.SeparatorView
android:id="@+id/separatorView"
android:layout_width="match_parent"
android:layout_height="32dp"
android:layout_marginLeft="@dimen/large_spacing"
android:layout_marginTop="20dp"
android:layout_marginRight="@dimen/large_spacing"/>
<ImageView
android:id="@+id/showQRCodeButton"
android:layout_width="24dp"
android:layout_height="24dp"
android:src="@drawable/ic_qr_code" />
<TextView
android:id="@+id/publicKeyTextView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="@dimen/large_spacing"
android:layout_marginTop="@dimen/large_spacing"
android:layout_marginRight="@dimen/large_spacing"
android:textSize="@dimen/large_font_size"
android:textColor="@color/text"
android:fontFamily="@font/space_mono_regular"
android:textAlignment="center"
android:text="05987d601943c267879be41830888066c6a024cbdc9a548d06813924bf3372ea78" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="@dimen/large_spacing"
android:layout_marginTop="@dimen/large_spacing"
android:layout_marginRight="@dimen/large_spacing"
android:orientation="horizontal">
</android.support.v7.widget.Toolbar>
<Button
style="@style/MediumProminentOutlineButton"
android:id="@+id/copyButton"
android:layout_width="0dp"
android:layout_height="@dimen/medium_button_height"
android:layout_weight="1"
android:text="Copy" />
<org.thoughtcrime.securesms.loki.redesign.views.ProfilePictureView
android:id="@+id/profilePictureView"
android:layout_width="@dimen/large_profile_picture_size"
android:layout_height="@dimen/large_profile_picture_size"
android:layout_marginTop="@dimen/medium_spacing" />
<Button
style="@style/MediumUnimportantOutlineButton"
android:id="@+id/shareButton"
android:layout_width="0dp"
android:layout_height="@dimen/medium_button_height"
android:layout_weight="1"
android:layout_marginLeft="@dimen/medium_spacing"
android:text="Share" />
<RelativeLayout
android:id="@+id/displayNameContainer"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="@dimen/large_spacing"
android:layout_marginTop="@dimen/small_spacing"
android:layout_marginRight="@dimen/large_spacing">
<EditText
style="@style/SessionEditText"
android:id="@+id/displayNameEditText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:paddingTop="12dp"
android:paddingBottom="12dp"
android:visibility="invisible"
android:hint="Enter a display name" />
</LinearLayout>
<View
android:layout_width="match_parent"
android:layout_height="1px"
android:layout_marginTop="@dimen/large_spacing"
android:background="@color/separator" />
<TextView
android:id="@+id/displayNameTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:id="@+id/privacyButton"
android:layout_width="match_parent"
android:layout_height="@dimen/setting_button_height"
android:background="@drawable/setting_button_background"
android:textColor="@color/text"
android:textSize="@dimen/very_large_font_size"
android:textStyle="bold" />
android:textSize="@dimen/medium_font_size"
android:textStyle="bold"
android:gravity="center"
android:text="Privacy" />
</RelativeLayout>
<View
android:layout_width="match_parent"
android:layout_height="1px"
android:background="@color/separator" />
<org.thoughtcrime.securesms.loki.redesign.views.SeparatorView
android:id="@+id/separatorView"
android:layout_width="match_parent"
android:layout_height="32dp"
android:layout_marginLeft="@dimen/large_spacing"
android:layout_marginTop="20dp"
android:layout_marginRight="@dimen/large_spacing"/>
<TextView
android:id="@+id/notificationsButton"
android:layout_width="match_parent"
android:layout_height="@dimen/setting_button_height"
android:background="@drawable/setting_button_background"
android:textColor="@color/text"
android:textSize="@dimen/medium_font_size"
android:textStyle="bold"
android:gravity="center"
android:text="Notifications" />
<TextView
android:id="@+id/publicKeyTextView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="@dimen/large_spacing"
android:layout_marginTop="@dimen/large_spacing"
android:layout_marginRight="@dimen/large_spacing"
android:textSize="@dimen/large_font_size"
android:textColor="@color/text"
android:fontFamily="@font/space_mono_regular"
android:textAlignment="center"
android:text="05987d601943c267879be41830888066c6a024cbdc9a548d06813924bf3372ea78" />
<View
android:layout_width="match_parent"
android:layout_height="1px"
android:background="@color/separator" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="@dimen/large_spacing"
android:layout_marginTop="@dimen/large_spacing"
android:layout_marginRight="@dimen/large_spacing"
android:orientation="horizontal">
<Button
style="@style/MediumProminentOutlineButton"
android:id="@+id/copyButton"
android:layout_width="0dp"
android:layout_height="@dimen/medium_button_height"
android:layout_weight="1"
android:text="Copy" />
<Button
style="@style/MediumUnimportantOutlineButton"
android:id="@+id/shareButton"
android:layout_width="0dp"
android:layout_height="@dimen/medium_button_height"
android:layout_weight="1"
android:layout_marginLeft="@dimen/medium_spacing"
android:text="Share" />
<TextView
android:id="@+id/chatsButton"
android:layout_width="match_parent"
android:layout_height="@dimen/setting_button_height"
android:background="@drawable/setting_button_background"
android:textColor="@color/text"
android:textSize="@dimen/medium_font_size"
android:textStyle="bold"
android:gravity="center"
android:text="Chats" />
</LinearLayout>
<View
android:layout_width="match_parent"
android:layout_height="1px"
android:background="@color/separator" />
<View
android:layout_width="match_parent"
android:layout_height="1px"
android:layout_marginTop="@dimen/large_spacing"
android:background="@color/separator" />
<TextView
android:id="@+id/linkedDevicesButton"
android:layout_width="match_parent"
android:layout_height="@dimen/setting_button_height"
android:background="@drawable/setting_button_background"
android:textColor="@color/text"
android:textSize="@dimen/medium_font_size"
android:textStyle="bold"
android:gravity="center"
android:text="Linked Devices" />
<TextView
android:id="@+id/privacyButton"
android:layout_width="match_parent"
android:layout_height="@dimen/setting_button_height"
android:background="@drawable/setting_button_background"
android:textColor="@color/text"
android:textSize="@dimen/medium_font_size"
android:textStyle="bold"
android:gravity="center"
android:text="Privacy" />
<View
android:layout_width="match_parent"
android:layout_height="1px"
android:background="@color/separator" />
<View
android:layout_width="match_parent"
android:layout_height="1px"
android:background="@color/separator" />
<TextView
android:id="@+id/notificationsButton"
android:layout_width="match_parent"
android:layout_height="@dimen/setting_button_height"
android:background="@drawable/setting_button_background"
android:textColor="@color/text"
android:textSize="@dimen/medium_font_size"
android:textStyle="bold"
android:gravity="center"
android:text="Notifications" />
<View
android:layout_width="match_parent"
android:layout_height="1px"
android:background="@color/separator" />
<TextView
android:id="@+id/seedButton"
android:layout_width="match_parent"
android:layout_height="@dimen/setting_button_height"
android:background="@drawable/setting_button_background"
android:textColor="@color/text"
android:textSize="@dimen/medium_font_size"
android:textStyle="bold"
android:gravity="center"
android:text="Show Seed" />
<TextView
android:id="@+id/chatsButton"
android:layout_width="match_parent"
android:layout_height="@dimen/setting_button_height"
android:background="@drawable/setting_button_background"
android:textColor="@color/text"
android:textSize="@dimen/medium_font_size"
android:textStyle="bold"
android:gravity="center"
android:text="Chats" />
<View
android:layout_width="match_parent"
android:layout_height="1px"
android:background="@color/separator" />
<View
android:layout_width="match_parent"
android:layout_height="1px"
android:background="@color/separator" />
<TextView
android:id="@+id/linkedDevicesButton"
android:layout_width="match_parent"
android:layout_height="@dimen/setting_button_height"
android:background="@drawable/setting_button_background"
android:textColor="@color/text"
android:textSize="@dimen/medium_font_size"
android:textStyle="bold"
android:gravity="center"
android:text="Linked Devices" />
<View
android:layout_width="match_parent"
android:layout_height="1px"
android:background="@color/separator" />
<TextView
android:id="@+id/clearAllDataButton"
android:layout_width="match_parent"
android:layout_height="@dimen/setting_button_height"
android:background="@drawable/setting_button_background"
android:textColor="@color/destructive"
android:textSize="@dimen/medium_font_size"
android:textStyle="bold"
android:gravity="center"
android:text="Clear All Data" />
<View
android:layout_width="match_parent"
android:layout_height="1px"
android:layout_marginBottom="@dimen/large_spacing"
android:background="@color/separator" />
<TextView
android:id="@+id/seedButton"
android:layout_width="match_parent"
android:layout_height="@dimen/setting_button_height"
android:background="@drawable/setting_button_background"
android:textColor="@color/text"
android:textSize="@dimen/medium_font_size"
android:textStyle="bold"
android:gravity="center"
android:text="Show Seed" />
<View
android:layout_width="match_parent"
android:layout_height="1px"
android:background="@color/separator" />
</LinearLayout>
<TextView
android:id="@+id/clearAllDataButton"
android:layout_width="match_parent"
android:layout_height="@dimen/setting_button_height"
android:background="@drawable/setting_button_background"
android:textColor="@color/destructive"
android:textSize="@dimen/medium_font_size"
android:textStyle="bold"
android:gravity="center"
android:text="Clear All Data" />
<View
android:layout_width="match_parent"
android:layout_height="1px"
android:layout_marginBottom="@dimen/large_spacing"
android:background="@color/separator" />
</ScrollView>
<RelativeLayout
android:id="@+id/loader"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#A4000000"
android:visibility="gone"
android:alpha="0">
<com.github.ybq.android.spinkit.SpinKitView
style="@style/SpinKitView.Large.ThreeBounce"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:layout_centerInParent="true"
app:SpinKit_Color="@color/text" />
</LinearLayout>
</RelativeLayout>
</ScrollView>
</RelativeLayout>

@ -8,7 +8,6 @@ import android.support.annotation.Nullable;
import org.thoughtcrime.securesms.database.Address;
import org.thoughtcrime.securesms.profiles.AvatarHelper;
import org.thoughtcrime.securesms.util.Conversions;
import java.io.IOException;
import java.io.InputStream;
@ -17,7 +16,7 @@ import java.security.MessageDigest;
public class ProfileContactPhoto implements ContactPhoto {
private final @NonNull Address address;
private final @NonNull String avatarObject;
public final @NonNull String avatarObject;
public ProfileContactPhoto(@NonNull Address address, @NonNull String avatarObject) {
this.address = address;

@ -91,14 +91,14 @@ class RegisterActivity : BaseActionBarActivity() {
val hexEncodedPublicKey = keyPair!!.hexEncodedPublicKey
val characterCount = hexEncodedPublicKey.count()
var count = 0
val limit = 40
val limit = 32
fun animate() {
val numberOfIndexesToShuffle = (0 until (40 - count)).random()
val numberOfIndexesToShuffle = 32 - count
val indexesToShuffle = (0 until characterCount).shuffled().subList(0, numberOfIndexesToShuffle)
var mangledHexEncodedPublicKey = hexEncodedPublicKey
for (index in indexesToShuffle) {
try {
mangledHexEncodedPublicKey = mangledHexEncodedPublicKey.substring(0, index) + "0123456789abcdef________________".random() + mangledHexEncodedPublicKey.substring(index + 1, mangledHexEncodedPublicKey.count())
mangledHexEncodedPublicKey = mangledHexEncodedPublicKey.substring(0, index) + "0123456789abcdef__".random() + mangledHexEncodedPublicKey.substring(index + 1, mangledHexEncodedPublicKey.count())
} catch (exception: Exception) {
// Do nothing
}
@ -108,7 +108,7 @@ class RegisterActivity : BaseActionBarActivity() {
publicKeyTextView.text = mangledHexEncodedPublicKey
Handler().postDelayed({
animate()
}, 40)
}, 32)
} else {
publicKeyTextView.text = hexEncodedPublicKey
}

@ -1,30 +1,56 @@
package org.thoughtcrime.securesms.loki.redesign.activities
import android.animation.Animator
import android.animation.AnimatorListenerAdapter
import android.app.Activity
import android.content.ClipData
import android.content.ClipboardManager
import android.content.Context
import android.content.Intent
import android.net.Uri
import android.os.AsyncTask
import android.os.Bundle
import android.os.Handler
import android.os.Looper
import android.view.View
import android.view.inputmethod.InputMethodManager
import android.widget.LinearLayout
import android.widget.Toast
import kotlinx.android.synthetic.main.activity_settings.*
import network.loki.messenger.R
import nl.komponents.kovenant.Promise
import nl.komponents.kovenant.all
import nl.komponents.kovenant.deferred
import nl.komponents.kovenant.ui.alwaysUi
import org.thoughtcrime.securesms.ApplicationContext
import org.thoughtcrime.securesms.PassphraseRequiredActionBarActivity
import org.thoughtcrime.securesms.avatar.AvatarSelection
import org.thoughtcrime.securesms.crypto.ProfileKeyUtil
import org.thoughtcrime.securesms.database.Address
import org.thoughtcrime.securesms.database.DatabaseFactory
import org.thoughtcrime.securesms.loki.redesign.utilities.push
import org.thoughtcrime.securesms.loki.toPx
import org.thoughtcrime.securesms.mms.GlideApp
import org.thoughtcrime.securesms.mms.GlideRequests
import org.thoughtcrime.securesms.profiles.AvatarHelper
import org.thoughtcrime.securesms.profiles.ProfileMediaConstraints
import org.thoughtcrime.securesms.util.BitmapDecodingException
import org.thoughtcrime.securesms.util.BitmapUtil
import org.thoughtcrime.securesms.util.TextSecurePreferences
import org.whispersystems.signalservice.api.crypto.ProfileCipher
import org.whispersystems.signalservice.api.util.StreamDetails
import org.whispersystems.signalservice.loki.api.LokiStorageAPI
import java.io.ByteArrayInputStream
import java.io.File
import java.security.SecureRandom
class SettingsActivity : PassphraseRequiredActionBarActivity() {
private lateinit var glide: GlideRequests
private var isEditingDisplayName = false
set(value) { field = value; handleIsEditingDisplayNameChanged() }
private var displayNameToBeUploaded: String? = null
private var profilePictureToBeUploaded: ByteArray? = null
private var tempFile: File? = null
private val hexEncodedPublicKey: String
get() {
@ -50,6 +76,7 @@ class SettingsActivity : PassphraseRequiredActionBarActivity() {
profilePictureView.hexEncodedPublicKey = hexEncodedPublicKey
profilePictureView.isLarge = true
profilePictureView.update()
profilePictureView.setOnClickListener { showEditProfilePictureUI() }
// Set up display name container
displayNameContainer.setOnClickListener { showEditDisplayNameUI() }
// Set up display name text view
@ -61,6 +88,34 @@ class SettingsActivity : PassphraseRequiredActionBarActivity() {
// Set up share button
shareButton.setOnClickListener { sharePublicKey() }
}
public override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
when (requestCode) {
AvatarSelection.REQUEST_CODE_AVATAR -> {
if (resultCode != Activity.RESULT_OK) { return }
val outputFile = Uri.fromFile(File(cacheDir, "cropped"))
var inputFile: Uri? = data?.data
if (inputFile == null && tempFile != null) {
inputFile = Uri.fromFile(tempFile)
}
AvatarSelection.circularCropImage(this, inputFile, outputFile, R.string.CropImageActivity_profile_avatar)
}
AvatarSelection.REQUEST_CODE_CROP_IMAGE -> {
if (resultCode != Activity.RESULT_OK) { return }
AsyncTask.execute {
try {
profilePictureToBeUploaded = BitmapUtil.createScaledBytes(this@SettingsActivity, AvatarSelection.getResultUri(data), ProfileMediaConstraints()).bitmap
Handler(Looper.getMainLooper()).post {
updateProfile(true)
}
} catch (e: BitmapDecodingException) {
e.printStackTrace()
}
}
}
}
}
// endregion
// region Updating
@ -82,18 +137,62 @@ class SettingsActivity : PassphraseRequiredActionBarActivity() {
}
}
private fun updateProfile(isUpdatingDisplayName: Boolean, isUpdatingProfilePicture: Boolean) {
val displayName = displayNameToBeUploaded ?: TextSecurePreferences.getProfileName(this)
TextSecurePreferences.setProfileName(this, displayName)
val publicChatAPI = ApplicationContext.getInstance(this).lokiPublicChatAPI
if (publicChatAPI != null) {
val servers = DatabaseFactory.getLokiThreadDatabase(this).getAllPublicChatServers()
for (server in servers) {
publicChatAPI.setDisplayName(displayName, server)
private fun updateProfile(isUpdatingProfilePicture: Boolean) {
showLoader()
val promises = mutableListOf<Promise<*, Exception>>()
val displayName = displayNameToBeUploaded
if (displayName != null) {
val publicChatAPI = ApplicationContext.getInstance(this).lokiPublicChatAPI
if (publicChatAPI != null) {
val servers = DatabaseFactory.getLokiThreadDatabase(this).getAllPublicChatServers()
promises.addAll(servers.map { publicChatAPI.setDisplayName(displayName, it) })
}
TextSecurePreferences.setProfileName(this, displayName)
}
val profilePicture = profilePictureToBeUploaded
val encodedProfileKey = ProfileKeyUtil.generateEncodedProfileKey(this)
val profileKey = ProfileKeyUtil.getProfileKeyFromEncodedString(encodedProfileKey)
if (isUpdatingProfilePicture && profilePicture != null) {
val storageAPI = LokiStorageAPI.shared
val deferred = deferred<Unit, Exception>()
AsyncTask.execute {
val stream = StreamDetails(ByteArrayInputStream(profilePicture), "image/jpeg", profilePicture.size.toLong())
val (_, url) = storageAPI.uploadProfilePicture(storageAPI.server, profileKey, stream)
TextSecurePreferences.setProfileAvatarUrl(this, url)
deferred.resolve(Unit)
}
promises.add(deferred.promise)
}
all(promises).alwaysUi {
if (displayName != null) {
displayNameTextView.text = displayName
}
displayNameToBeUploaded = null
if (isUpdatingProfilePicture && profilePicture != null) {
AvatarHelper.setAvatar(this, Address.fromSerialized(TextSecurePreferences.getLocalNumber(this)), profilePicture)
TextSecurePreferences.setProfileAvatarId(this, SecureRandom().nextInt())
ProfileKeyUtil.setEncodedProfileKey(this, encodedProfileKey)
ApplicationContext.getInstance(this).updatePublicChatProfileAvatarIfNeeded()
profilePictureView.update()
}
profilePictureToBeUploaded = null
hideLoader()
}
displayNameTextView.text = displayName
displayNameToBeUploaded = null
}
private fun showLoader() {
loader.visibility = View.VISIBLE
loader.animate().setDuration(150).alpha(1.0f).start()
}
private fun hideLoader() {
loader.animate().setDuration(150).alpha(0.0f).setListener(object : AnimatorListenerAdapter() {
override fun onAnimationEnd(animation: Animator?) {
super.onAnimationEnd(animation)
loader.visibility = View.GONE
}
})
}
// endregion
@ -103,11 +202,19 @@ class SettingsActivity : PassphraseRequiredActionBarActivity() {
}
private fun saveDisplayName() {
val displayName = displayNameEditText.text.trim().toString()
// TODO: Validation
val displayName = displayNameEditText.text.toString().trim()
if (displayName.isEmpty()) {
return Toast.makeText(this, "Please pick a display name", Toast.LENGTH_SHORT).show()
}
if (!displayName.matches(Regex("[a-zA-Z0-9_]+"))) {
return Toast.makeText(this, "Please pick a display name that consists of only a-z, A-Z, 0-9 and _ characters", Toast.LENGTH_SHORT).show()
}
if (displayName.toByteArray().size > ProfileCipher.NAME_PADDED_LENGTH) {
return Toast.makeText(this, "Please pick a shorter display name", Toast.LENGTH_SHORT).show()
}
isEditingDisplayName = false
displayNameToBeUploaded = displayName
updateProfile(true, false)
updateProfile(false)
}
private fun showQRCode() {
@ -115,6 +222,10 @@ class SettingsActivity : PassphraseRequiredActionBarActivity() {
push(intent)
}
private fun showEditProfilePictureUI() {
tempFile = AvatarSelection.startAvatarSelection(this, false, true)
}
private fun showEditDisplayNameUI() {
isEditingDisplayName = true
}

@ -10,6 +10,7 @@ import android.widget.RelativeLayout
import com.bumptech.glide.load.engine.DiskCacheStrategy
import kotlinx.android.synthetic.main.view_profile_picture.view.*
import network.loki.messenger.R
import org.thoughtcrime.securesms.contacts.avatars.ProfileContactPhoto
import org.thoughtcrime.securesms.database.Address
import org.thoughtcrime.securesms.loki.JazzIdenticonDrawable
import org.thoughtcrime.securesms.mms.GlideRequests
@ -60,7 +61,7 @@ class ProfilePictureView : RelativeLayout {
glide.clear(imageView)
if (hexEncodedPublicKey.isNotEmpty()) {
val signalProfilePicture = Recipient.from(context, Address.fromSerialized(hexEncodedPublicKey), false).contactPhoto
if (signalProfilePicture != null) {
if (signalProfilePicture != null && (signalProfilePicture as? ProfileContactPhoto)?.avatarObject != "0") {
glide.load(signalProfilePicture).diskCacheStrategy(DiskCacheStrategy.ALL).circleCrop().into(imageView)
} else {
val size = resources.getDimensionPixelSize(sizeID)

@ -475,7 +475,7 @@ public class Recipient implements RecipientModifiedListener {
}
public synchronized @Nullable ContactPhoto getContactPhoto() {
if (isLocalNumber && profileAvatar != null) return new ProfileContactPhoto(address, String.valueOf(TextSecurePreferences.getProfileAvatarId(context)));
if (isLocalNumber) return new ProfileContactPhoto(address, String.valueOf(TextSecurePreferences.getProfileAvatarId(context)));
else if (isGroupRecipient() && groupAvatarId != null) return new GroupRecordContactPhoto(address, groupAvatarId);
else if (systemContactPhoto != null) return new SystemContactPhoto(address, systemContactPhoto, 0);
else if (profileAvatar != null) return new ProfileContactPhoto(address, profileAvatar);

Loading…
Cancel
Save