Generate placeholder avatars from two characters, re-fetch missed avatars (#856)

* feat: splitting names in the avatar generation

* fix: re-fetch avatars if initial downloads fail

* fix: remove shadowed name, add tests for common labels
This commit is contained in:
Harris
2022-03-15 09:24:15 +11:00
committed by GitHub
parent 11d49426d3
commit 6649a9a745
6 changed files with 66 additions and 18 deletions

View File

@@ -254,7 +254,7 @@ public class JobManager implements ConstraintObserver.Notifier {
public static class Builder {
private ExecutorFactory executorFactory = new DefaultExecutorFactory();
private int jobThreadCount = Math.max(2, Math.min(Runtime.getRuntime().availableProcessors() - 1, 4));
private int jobThreadCount = 1;
private Map<String, Job.Factory> jobFactories = new HashMap<>();
private Map<String, Constraint.Factory> constraintFactories = new HashMap<>();
private List<ConstraintObserver> constraintObservers = new ArrayList<>();

View File

@@ -84,7 +84,7 @@ public class RetrieveProfileAvatarJob extends BaseJob {
return;
}
if (Util.equals(profileAvatar, recipient.resolve().getProfileAvatar())) {
if (AvatarHelper.avatarFileExists(context, recipient.resolve().getAddress()) && Util.equals(profileAvatar, recipient.resolve().getProfileAvatar())) {
Log.w(TAG, "Already retrieved profile avatar: " + profileAvatar);
return;
}

View File

@@ -1,14 +1,20 @@
package org.thoughtcrime.securesms.util
import android.content.Context
import android.graphics.*
import android.graphics.Bitmap
import android.graphics.Canvas
import android.graphics.Color
import android.graphics.Paint
import android.graphics.Rect
import android.graphics.RectF
import android.graphics.Typeface
import android.graphics.drawable.BitmapDrawable
import android.text.TextPaint
import android.text.TextUtils
import network.loki.messenger.R
import java.math.BigInteger
import java.security.MessageDigest
import java.util.*
import java.util.Locale
object AvatarPlaceholderGenerator {
@@ -28,7 +34,7 @@ object AvatarPlaceholderGenerator {
val colorPrimary = colorArray[(hash % colorArray.size).toInt()]
val labelText = when {
!TextUtils.isEmpty(displayName) -> extractLabel(displayName!!.capitalize())
!TextUtils.isEmpty(displayName) -> extractLabel(displayName!!.capitalize(Locale.ROOT))
!TextUtils.isEmpty(hashString) -> extractLabel(hashString)
else -> EMPTY_LABEL
}
@@ -57,14 +63,19 @@ object AvatarPlaceholderGenerator {
return BitmapDrawable(context.resources, bitmap)
}
private fun extractLabel(content: String): String {
var content = content.trim()
if (content.isEmpty()) return EMPTY_LABEL
return if (content.length > 2 && content.startsWith("05")) {
content[2].toString().toUpperCase(Locale.ROOT)
fun extractLabel(content: String): String {
val trimmedContent = content.trim()
if (trimmedContent.isEmpty()) return EMPTY_LABEL
return if (trimmedContent.length > 2 && trimmedContent.startsWith("05")) {
trimmedContent[2].toString()
} else {
content.first().toString().toUpperCase(Locale.ROOT)
}
val splitWords = trimmedContent.split(Regex("\\W"))
if (splitWords.size < 2) {
trimmedContent.take(2)
} else {
splitWords.filter { word -> word.isNotEmpty() }.take(2).map { it.first() }.joinToString("")
}
}.uppercase()
}
private fun getSha512(input: String): String {

View File

@@ -0,0 +1,26 @@
package org.thoughtcrime.securesms.recipients
import org.junit.Assert.assertEquals
import org.junit.Test
import org.thoughtcrime.securesms.util.AvatarPlaceholderGenerator
class AvatarGeneratorTest {
@Test
fun testCommonAvatarFormats() {
val testNamesAndResults = mapOf(
"H " to "H",
"Test Name" to "TN",
"test name" to "TN",
"howdy partner" to "HP",
"testname" to "TE", //
"05aaapubkey" to "A", // pubkey values only return first non-05 character
"Test" to "TE"
)
testNamesAndResults.forEach { (test, expected) ->
val processed = AvatarPlaceholderGenerator.extractLabel(test)
assertEquals(expected, processed)
}
}
}