diff --git a/res/drawable/profile_picture_view_large_background.xml b/res/drawable/profile_picture_view_large_background.xml index bfc404e25f..c5f6d91a0d 100644 --- a/res/drawable/profile_picture_view_large_background.xml +++ b/res/drawable/profile_picture_view_large_background.xml @@ -3,7 +3,7 @@ xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle"> - + diff --git a/res/drawable/profile_picture_view_large_foreground.xml b/res/drawable/profile_picture_view_large_foreground.xml index 18cac49b38..7d6f94a2b4 100644 --- a/res/drawable/profile_picture_view_large_foreground.xml +++ b/res/drawable/profile_picture_view_large_foreground.xml @@ -7,5 +7,5 @@ - + \ No newline at end of file diff --git a/res/drawable/profile_picture_view_medium_background.xml b/res/drawable/profile_picture_view_medium_background.xml index 143223ac1b..2b379dec4e 100644 --- a/res/drawable/profile_picture_view_medium_background.xml +++ b/res/drawable/profile_picture_view_medium_background.xml @@ -3,7 +3,9 @@ xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle"> - + + + \ No newline at end of file diff --git a/res/drawable/profile_picture_view_medium_foreground.xml b/res/drawable/profile_picture_view_medium_foreground.xml index e62cfbe3fb..e05dd6aaba 100644 --- a/res/drawable/profile_picture_view_medium_foreground.xml +++ b/res/drawable/profile_picture_view_medium_foreground.xml @@ -7,5 +7,5 @@ - + \ No newline at end of file diff --git a/res/drawable/profile_picture_view_rss_medium_background.xml b/res/drawable/profile_picture_view_rss_medium_background.xml index 4d9a6a86d9..9496e53ed0 100644 --- a/res/drawable/profile_picture_view_rss_medium_background.xml +++ b/res/drawable/profile_picture_view_rss_medium_background.xml @@ -3,7 +3,9 @@ xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle"> - + + + \ No newline at end of file diff --git a/res/drawable/profile_picture_view_small_background.xml b/res/drawable/profile_picture_view_small_background.xml index 523316cf4e..d01f12f77a 100644 --- a/res/drawable/profile_picture_view_small_background.xml +++ b/res/drawable/profile_picture_view_small_background.xml @@ -3,7 +3,9 @@ xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle"> - + + + \ No newline at end of file diff --git a/res/drawable/profile_picture_view_small_foreground.xml b/res/drawable/profile_picture_view_small_foreground.xml index 98d2b0a4e7..6a46584bf8 100644 --- a/res/drawable/profile_picture_view_small_foreground.xml +++ b/res/drawable/profile_picture_view_small_foreground.xml @@ -7,5 +7,5 @@ - + \ No newline at end of file diff --git a/res/layout/activity_home.xml b/res/layout/activity_home.xml index 19cf1e4d37..53e3a9138d 100644 --- a/res/layout/activity_home.xml +++ b/res/layout/activity_home.xml @@ -34,8 +34,7 @@ android:layout_height="@dimen/small_profile_picture_size" android:layout_alignParentLeft="true" android:layout_centerVertical="true" - android:layout_marginLeft="9dp" - android:foreground="@drawable/circle_touch_highlight_background"/> + android:layout_marginLeft="9dp" /> + android:layout_marginTop="@dimen/medium_spacing" /> + + + + @@ -51,6 +60,11 @@ android:layout_height="match_parent" android:background="@drawable/profile_picture_view_medium_background" /> + + + + \ No newline at end of file diff --git a/res/values-notnight-v21/colors.xml b/res/values-notnight-v21/colors.xml index ba4b118eb6..ea63430e14 100644 --- a/res/values-notnight-v21/colors.xml +++ b/res/values-notnight-v21/colors.xml @@ -7,6 +7,8 @@ #000000 #f26f55 #606060 + #23000000 + #B0B0B0 #FCFCFC #DFDFDF #FCFCFC diff --git a/res/values/colors.xml b/res/values/colors.xml index 6039c28b69..ca2a48f500 100644 --- a/res/values/colors.xml +++ b/res/values/colors.xml @@ -7,6 +7,8 @@ #FFFFFF #FF453A #D8D8D8 + #23FFFFFF + #353535 #979797 #1B1B1B #0C0C0C @@ -29,6 +31,13 @@ #1B1B1B #212121 #FFCE3A + + + #5ff8b0 + #26cdb9 + #f3c615 + #fcac5a + @@ -108,11 +117,4 @@ #121212 #171717 - - #2bca81 - #ee7117 - #239edf - #bb35e9 - - diff --git a/src/org/thoughtcrime/securesms/loki/activities/SettingsActivity.kt b/src/org/thoughtcrime/securesms/loki/activities/SettingsActivity.kt index efd7836ffe..6f110b9ca7 100644 --- a/src/org/thoughtcrime/securesms/loki/activities/SettingsActivity.kt +++ b/src/org/thoughtcrime/securesms/loki/activities/SettingsActivity.kt @@ -52,10 +52,8 @@ import java.security.SecureRandom import java.util.* class SettingsActivity : PassphraseRequiredActionBarActivity() { - private var displayNameEditActionMode: ActionMode? = null set(value) { field = value; handleDisplayNameEditActionModeChanged() } - private lateinit var glide: GlideRequests private var displayNameToBeUploaded: String? = null private var profilePictureToBeUploaded: ByteArray? = null @@ -71,20 +69,17 @@ class SettingsActivity : PassphraseRequiredActionBarActivity() { // region Lifecycle override fun onCreate(savedInstanceState: Bundle?, isReady: Boolean) { super.onCreate(savedInstanceState, isReady) - setContentView(R.layout.activity_settings) - - val origUserDisplayName = DatabaseFactory.getLokiUserDatabase(this).getDisplayName(hexEncodedPublicKey) - + val displayName = DatabaseFactory.getLokiUserDatabase(this).getDisplayName(hexEncodedPublicKey) glide = GlideApp.with(this) profilePictureView.glide = glide profilePictureView.publicKey = hexEncodedPublicKey - profilePictureView.displayName = origUserDisplayName + profilePictureView.displayName = displayName profilePictureView.isLarge = true profilePictureView.update() profilePictureView.setOnClickListener { showEditProfilePictureUI() } ctnGroupNameSection.setOnClickListener { startActionMode(DisplayNameEditActionModeCallback()) } - btnGroupNameDisplay.text = origUserDisplayName + btnGroupNameDisplay.text = displayName publicKeyTextView.text = hexEncodedPublicKey copyButton.setOnClickListener { copyPublicKey() } shareButton.setOnClickListener { sharePublicKey() } @@ -106,12 +101,9 @@ class SettingsActivity : PassphraseRequiredActionBarActivity() { override fun onCreateOptionsMenu(menu: Menu): Boolean { menuInflater.inflate(R.menu.settings_general, menu) - - // Update UI mode menu icon. - // It uses three-level selector where each level corresponds to the related UiMode ordinal value. + // Update UI mode menu icon val uiMode = UiModeUtilities.getUserSelectedUiMode(this) menu.findItem(R.id.action_change_theme).icon!!.level = uiMode.ordinal - return true } diff --git a/src/org/thoughtcrime/securesms/loki/todo/AvatarPlaceholderGenerator.kt b/src/org/thoughtcrime/securesms/loki/todo/AvatarPlaceholderGenerator.kt index 9cea1618fd..70343f8434 100644 --- a/src/org/thoughtcrime/securesms/loki/todo/AvatarPlaceholderGenerator.kt +++ b/src/org/thoughtcrime/securesms/loki/todo/AvatarPlaceholderGenerator.kt @@ -11,11 +11,10 @@ import network.loki.messenger.R import java.util.* object AvatarPlaceholderGenerator { + private val tmpFloatArray = FloatArray(3) private const val EMPTY_LABEL = "0"; - private val tmpFloatArray = FloatArray(3) - fun generate(context: Context, pixelSize: Int, hashString: String, displayName: String?): BitmapDrawable { //TODO That should be replaced with a proper hash extraction code. val hash: Long @@ -26,7 +25,7 @@ object AvatarPlaceholderGenerator { } // Do not cache color array, it may be different depends on the current theme. - val colorArray = context.resources.getIntArray(R.array.user_pic_placeholder_primary) + val colorArray = context.resources.getIntArray(R.array.profile_picture_placeholder_colors) val colorPrimary = colorArray[(hash % colorArray.size).toInt()] val colorSecondary = changeColorHueBy(colorPrimary, 12f) @@ -43,7 +42,7 @@ object AvatarPlaceholderGenerator { val paint = Paint(Paint.ANTI_ALIAS_FLAG) paint.shader = LinearGradient(0f, 0f, 0f, pixelSize.toFloat(), colorPrimary, - colorSecondary, + colorPrimary, Shader.TileMode.REPEAT) canvas.drawCircle(pixelSize.toFloat() / 2, pixelSize.toFloat() / 2, pixelSize.toFloat() / 2, paint) diff --git a/src/org/thoughtcrime/securesms/loki/views/ProfilePictureView.kt b/src/org/thoughtcrime/securesms/loki/views/ProfilePictureView.kt index 686801056e..8186639c5f 100644 --- a/src/org/thoughtcrime/securesms/loki/views/ProfilePictureView.kt +++ b/src/org/thoughtcrime/securesms/loki/views/ProfilePictureView.kt @@ -1,7 +1,6 @@ package org.thoughtcrime.securesms.loki.views import android.content.Context -import android.text.TextUtils import android.util.AttributeSet import android.view.LayoutInflater import android.view.View @@ -9,7 +8,6 @@ import android.widget.ImageView import android.widget.RelativeLayout import androidx.annotation.DimenRes import com.bumptech.glide.load.engine.DiskCacheStrategy -import kotlinx.android.synthetic.main.view_conversation.view.* import kotlinx.android.synthetic.main.view_profile_picture.view.* import network.loki.messenger.R import org.thoughtcrime.securesms.contacts.avatars.ProfileContactPhoto @@ -79,10 +77,12 @@ class ProfilePictureView : RelativeLayout { users.remove(masterPublicKey) } val randomUsers = users.sorted() // Sort to provide a level of stability - publicKey = randomUsers.getOrNull(0) ?: "" - displayName = getUserDisplayName(randomUsers.getOrNull(0) ?: "") - additionalPublicKey = randomUsers.getOrNull(1) ?: "" - additionalDisplayName = getUserDisplayName(randomUsers.getOrNull(1) ?: "") + 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" } } else { @@ -101,7 +101,6 @@ class ProfilePictureView : RelativeLayout { singleModeImageViewContainer.visibility = if (additionalPublicKey == null && !isRSSFeed && !isLarge) View.VISIBLE else View.INVISIBLE largeSingleModeImageViewContainer.visibility = if (additionalPublicKey == null && !isRSSFeed && isLarge) View.VISIBLE else View.INVISIBLE rssImageView.visibility = if (isRSSFeed) View.VISIBLE else View.INVISIBLE - setProfilePictureIfNeeded( doubleModeImageView1, publicKey, @@ -124,21 +123,21 @@ class ProfilePictureView : RelativeLayout { R.dimen.large_profile_picture_size) } - private fun setProfilePictureIfNeeded(imageView: ImageView, hexEncodedPublicKey: String, displayName: String?, @DimenRes sizeResId: Int) { + private fun setProfilePictureIfNeeded(imageView: ImageView, publicKey: String, displayName: String?, @DimenRes sizeResId: Int) { glide.clear(imageView) - if (hexEncodedPublicKey.isNotEmpty()) { - val recipient = Recipient.from(context, Address.fromSerialized(hexEncodedPublicKey), false); + if (publicKey.isNotEmpty()) { + val recipient = Recipient.from(context, Address.fromSerialized(publicKey), false); val signalProfilePicture = recipient.contactPhoto - if (signalProfilePicture != null && (signalProfilePicture as? ProfileContactPhoto)?.avatarObject != "0" && (signalProfilePicture as? ProfileContactPhoto)?.avatarObject != "") { + if (signalProfilePicture != null && (signalProfilePicture as? ProfileContactPhoto)?.avatarObject != "0" + && (signalProfilePicture as? ProfileContactPhoto)?.avatarObject != "") { glide.load(signalProfilePicture).diskCacheStrategy(DiskCacheStrategy.ALL).circleCrop().into(imageView) } else { - val sizePx = resources.getDimensionPixelSize(sizeResId) - val masterHexEncodedPublicKey = TextSecurePreferences.getMasterHexEncodedPublicKey(context) - val hepk = if (recipient.isLocalNumber && masterHexEncodedPublicKey != null) masterHexEncodedPublicKey else hexEncodedPublicKey -// val jazzIcon = JazzIdenticonDrawable(size, size, hepk) + val sizeInPX = resources.getDimensionPixelSize(sizeResId) + val masterPublicKey = TextSecurePreferences.getMasterHexEncodedPublicKey(context) + val hepk = if (recipient.isLocalNumber && masterPublicKey != null) masterPublicKey else publicKey glide.load(AvatarPlaceholderGenerator.generate( context, - sizePx, + sizeInPX, hepk, displayName )).diskCacheStrategy(DiskCacheStrategy.ALL).circleCrop().into(imageView) diff --git a/src/org/thoughtcrime/securesms/loki/views/UserView.kt b/src/org/thoughtcrime/securesms/loki/views/UserView.kt index 3b11082264..96c1de080a 100644 --- a/src/org/thoughtcrime/securesms/loki/views/UserView.kt +++ b/src/org/thoughtcrime/securesms/loki/views/UserView.kt @@ -49,6 +49,13 @@ class UserView : LinearLayout { // region Updating fun bind(user: Recipient, glide: GlideRequests, actionIndicator: ActionIndicator, isSelected: Boolean = false) { + fun getUserDisplayName(publicKey: String?): String? { + if (publicKey == null || publicKey.isBlank()) { + return null + } else { + return DatabaseFactory.getLokiUserDatabase(context).getDisplayName(publicKey!!) + } + } val address = user.address.serialize() if (user.isGroupRecipient) { if ("Session Public Chat" == user.name || user.address.isRSSFeed) { @@ -58,15 +65,14 @@ class UserView : LinearLayout { profilePictureView.isRSSFeed = true } else { val threadID = GroupManager.getThreadIDFromGroupID(address, context) - val userKeys = MentionsManager.shared.userPublicKeyCache[threadID]?.toList() ?: listOf() - val sortedUserKeys = userKeys.sorted() // Sort to provide a level of stability - val userKey0 = sortedUserKeys.getOrNull(0) ?: "" - val userKey1 = sortedUserKeys.getOrNull(1) ?: "" - - profilePictureView.publicKey = userKey0 - profilePictureView.displayName = getUserDisplayName(userKey0) - profilePictureView.additionalPublicKey = userKey1 - profilePictureView.additionalDisplayName = getUserDisplayName(userKey1) + val users = MentionsManager.shared.userPublicKeyCache[threadID]?.toList() ?: listOf() + val randomUsers = users.sorted() // Sort to provide a level of stability + val pk = randomUsers.getOrNull(0) ?: "" + profilePictureView.publicKey = pk + profilePictureView.displayName = getUserDisplayName(pk) + val apk = randomUsers.getOrNull(1) ?: "" + profilePictureView.additionalPublicKey = apk + profilePictureView.additionalDisplayName = getUserDisplayName(apk) profilePictureView.isRSSFeed = false } } else { @@ -93,10 +99,5 @@ class UserView : LinearLayout { } } } - - private fun getUserDisplayName(publicKey: String?): String? { - if (TextUtils.isEmpty(publicKey)) return null - return DatabaseFactory.getLokiUserDatabase(context).getDisplayName(publicKey!!) - } // endregion } \ No newline at end of file diff --git a/src/org/thoughtcrime/securesms/notifications/SingleRecipientNotificationBuilder.java b/src/org/thoughtcrime/securesms/notifications/SingleRecipientNotificationBuilder.java index 29fab4e4c3..9abb67d1ba 100644 --- a/src/org/thoughtcrime/securesms/notifications/SingleRecipientNotificationBuilder.java +++ b/src/org/thoughtcrime/securesms/notifications/SingleRecipientNotificationBuilder.java @@ -14,19 +14,19 @@ import android.graphics.RectF; import android.graphics.drawable.Drawable; import android.net.Uri; import android.os.Build; +import android.text.SpannableStringBuilder; + import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.annotation.StringRes; import androidx.core.app.NotificationCompat; import androidx.core.app.NotificationCompat.Action; import androidx.core.app.RemoteInput; -import android.text.SpannableStringBuilder; import com.bumptech.glide.load.engine.DiskCacheStrategy; import org.thoughtcrime.securesms.contacts.avatars.ContactColors; import org.thoughtcrime.securesms.contacts.avatars.ContactPhoto; -import org.thoughtcrime.securesms.contacts.avatars.FallbackContactPhoto; import org.thoughtcrime.securesms.contacts.avatars.GeneratedContactPhoto; import org.thoughtcrime.securesms.logging.Log; import org.thoughtcrime.securesms.loki.todo.AvatarPlaceholderGenerator; @@ -93,10 +93,10 @@ public class SingleRecipientNotificationBuilder extends AbstractNotificationBuil .get()); } catch (InterruptedException | ExecutionException e) { Log.w(TAG, e); - setLargeIcon(obtainAvatarPlaceholderDrawable(context, recipient)); + setLargeIcon(getPlaceholderDrawable(context, recipient)); } } else { - setLargeIcon(obtainAvatarPlaceholderDrawable(context, recipient)); + setLargeIcon(getPlaceholderDrawable(context, recipient)); } } else { @@ -320,9 +320,7 @@ public class SingleRecipientNotificationBuilder extends AbstractNotificationBuil return content; } - private static Drawable obtainAvatarPlaceholderDrawable(Context context, Recipient recipient) { - //TODO Copied from ProfilePictureView#setProfilePictureIfNeeded - // Refactor this code to use the same recipient placeholder generator method across the app. + private static Drawable getPlaceholderDrawable(Context context, Recipient recipient) { String publicKey = recipient.getAddress().serialize(); String hepk = (recipient.isLocalNumber() && publicKey != null) ? TextSecurePreferences.getMasterHexEncodedPublicKey(context)