diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 91d9572f90..0306252e16 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -3,7 +3,7 @@ xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools"> - + { - if (recipient.getContactUri() != null) { - ContactsContract.QuickContact.showQuickContact(getContext(), AvatarImageView.this, recipient.getContactUri(), ContactsContract.QuickContact.MODE_LARGE, null); - } else { - getContext().startActivity(RecipientExporter.export(recipient).asAddContactIntent()); - } - }); - } else { - super.setOnClickListener(listener); - } - } - - private static class RecipientContactPhoto { - - private final @NonNull Recipient recipient; - private final @Nullable ContactPhoto contactPhoto; - private final boolean ready; - - RecipientContactPhoto(@NonNull Recipient recipient) { - this.recipient = recipient; - this.ready = !recipient.isResolving(); - this.contactPhoto = recipient.getContactPhoto(); - } - - public boolean equals(@Nullable RecipientContactPhoto other) { - if (other == null) return false; - - return other.recipient.equals(recipient) && - other.recipient.getColor().equals(recipient.getColor()) && - other.ready == ready && - Objects.equals(other.contactPhoto, contactPhoto); - } - } -} diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/ProfilePictureView.kt b/app/src/main/java/org/thoughtcrime/securesms/components/ProfilePictureView.kt index 571c778d4a..9511bddb6a 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/ProfilePictureView.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/components/ProfilePictureView.kt @@ -38,10 +38,13 @@ class ProfilePictureView @JvmOverloads constructor( var additionalDisplayName: String? = null private val profilePicturesCache = mutableMapOf() + private val resourcePadding by lazy { + context.resources.getDimensionPixelSize(R.dimen.normal_padding).toFloat() + } private val unknownRecipientDrawable by lazy { ResourceContactPhoto(R.drawable.ic_profile_default) - .asDrawable(context, ContactColors.UNKNOWN_COLOR.toConversationColor(context), false) } + .asDrawable(context, ContactColors.UNKNOWN_COLOR.toConversationColor(context), false, resourcePadding) } private val unknownOpenGroupDrawable by lazy { ResourceContactPhoto(R.drawable.ic_notification) - .asDrawable(context, ContactColors.UNKNOWN_COLOR.toConversationColor(context), false) } + .asDrawable(context, ContactColors.UNKNOWN_COLOR.toConversationColor(context), false, resourcePadding) } constructor(context: Context, sender: Recipient): this(context) { update(sender) diff --git a/app/src/main/java/org/thoughtcrime/securesms/notifications/SingleRecipientNotificationBuilder.java b/app/src/main/java/org/thoughtcrime/securesms/notifications/SingleRecipientNotificationBuilder.java index 6a0a8e0956..fb7abb7bd5 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/notifications/SingleRecipientNotificationBuilder.java +++ b/app/src/main/java/org/thoughtcrime/securesms/notifications/SingleRecipientNotificationBuilder.java @@ -28,7 +28,7 @@ import com.bumptech.glide.load.engine.DiskCacheStrategy; import org.session.libsession.avatars.ContactColors; import org.session.libsession.avatars.ContactPhoto; -import org.session.libsession.avatars.GeneratedContactPhoto; +import org.session.libsession.avatars.ResourceContactPhoto; import org.session.libsession.messaging.contacts.Contact; import org.session.libsession.utilities.NotificationPrivacyPreference; import org.session.libsession.utilities.TextSecurePreferences; @@ -60,6 +60,8 @@ public class SingleRecipientNotificationBuilder extends AbstractNotificationBuil private CharSequence contentTitle; private CharSequence contentText; + private static final Integer ICON_SIZE = 128; + public SingleRecipientNotificationBuilder(@NonNull Context context, @NonNull NotificationPrivacyPreference privacy) { super(context, privacy); @@ -108,7 +110,7 @@ public class SingleRecipientNotificationBuilder extends AbstractNotificationBuil } else { setContentTitle(context.getString(R.string.SingleRecipientNotificationBuilder_signal)); - setLargeIcon(new GeneratedContactPhoto("Unknown", R.drawable.ic_profile_default).asDrawable(context, ContactColors.UNKNOWN_COLOR.toConversationColor(context))); + setLargeIcon(AvatarPlaceholderGenerator.generate(context, ICON_SIZE, "", "Unknown")); } } @@ -330,7 +332,7 @@ public class SingleRecipientNotificationBuilder extends AbstractNotificationBuil private static Drawable getPlaceholderDrawable(Context context, Recipient recipient) { String publicKey = recipient.getAddress().serialize(); String displayName = recipient.getName(); - return AvatarPlaceholderGenerator.generate(context, 128, publicKey, displayName); + return AvatarPlaceholderGenerator.generate(context, ICON_SIZE, publicKey, displayName); } /** diff --git a/libsession/build.gradle b/libsession/build.gradle index 2856e88a2c..031555d41f 100644 --- a/libsession/build.gradle +++ b/libsession/build.gradle @@ -38,7 +38,6 @@ dependencies { androidTestImplementation 'androidx.test.ext:junit:1.1.5' androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1' implementation "com.github.bumptech.glide:glide:$glideVersion" - implementation 'com.amulyakhare:com.amulyakhare.textdrawable:1.0.1' implementation 'com.annimon:stream:1.1.8' implementation 'com.makeramen:roundedimageview:2.1.0' implementation 'com.esotericsoftware:kryo:5.1.1' diff --git a/libsession/src/main/java/org/session/libsession/avatars/FallbackContactPhoto.java b/libsession/src/main/java/org/session/libsession/avatars/FallbackContactPhoto.java index b2095c5980..9be08ea9ff 100644 --- a/libsession/src/main/java/org/session/libsession/avatars/FallbackContactPhoto.java +++ b/libsession/src/main/java/org/session/libsession/avatars/FallbackContactPhoto.java @@ -5,6 +5,6 @@ import android.graphics.drawable.Drawable; public interface FallbackContactPhoto { - public Drawable asDrawable(Context context, int color); public Drawable asDrawable(Context context, int color, boolean inverted); + public Drawable asDrawable(Context context, int color, boolean inverted, Float padding); } diff --git a/libsession/src/main/java/org/session/libsession/avatars/GeneratedContactPhoto.java b/libsession/src/main/java/org/session/libsession/avatars/GeneratedContactPhoto.java deleted file mode 100644 index 0f607d6e33..0000000000 --- a/libsession/src/main/java/org/session/libsession/avatars/GeneratedContactPhoto.java +++ /dev/null @@ -1,83 +0,0 @@ -package org.session.libsession.avatars; - -import android.content.Context; -import android.graphics.Color; -import android.graphics.Typeface; -import android.graphics.drawable.Drawable; -import android.graphics.drawable.LayerDrawable; -import android.text.TextUtils; - -import androidx.annotation.DrawableRes; -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; - -import com.amulyakhare.textdrawable.TextDrawable; - -import org.session.libsession.R; -import org.session.libsession.utilities.ThemeUtil; -import org.session.libsession.utilities.ViewUtil; - -import java.util.regex.Pattern; - -public class GeneratedContactPhoto implements FallbackContactPhoto { - - private static final Pattern PATTERN = Pattern.compile("[^\\p{L}\\p{Nd}\\p{S}]+"); - private static final Typeface TYPEFACE = Typeface.create("sans-serif-medium", Typeface.NORMAL); - - private final String name; - private final int fallbackResId; - - public GeneratedContactPhoto(@NonNull String name, @DrawableRes int fallbackResId) { - this.name = name; - this.fallbackResId = fallbackResId; - } - - @Override - public Drawable asDrawable(Context context, int color) { - return asDrawable(context, color,false); - } - - @Override - public Drawable asDrawable(Context context, int color, boolean inverted) { - int targetSize = context.getResources().getDimensionPixelSize(R.dimen.contact_photo_target_size); - String character = getAbbreviation(name); - - if (!TextUtils.isEmpty(character)) { - Drawable base = TextDrawable.builder() - .beginConfig() - .width(targetSize) - .height(targetSize) - .useFont(TYPEFACE) - .fontSize(ViewUtil.dpToPx(context, 24)) - .textColor(inverted ? color : Color.WHITE) - .endConfig() - .buildRound(character, inverted ? Color.WHITE : color); - - Drawable gradient = context.getResources().getDrawable(ThemeUtil.isDarkTheme(context) ? R.drawable.avatar_gradient_dark - : R.drawable.avatar_gradient_light); - return new LayerDrawable(new Drawable[] { base, gradient }); - } - - return new ResourceContactPhoto(fallbackResId).asDrawable(context, color, inverted); - } - - private @Nullable String getAbbreviation(String name) { - String[] parts = name.split(" "); - StringBuilder builder = new StringBuilder(); - int count = 0; - - for (int i = 0; i < parts.length && count < 2; i++) { - String cleaned = PATTERN.matcher(parts[i]).replaceFirst(""); - if (!TextUtils.isEmpty(cleaned)) { - builder.appendCodePoint(cleaned.codePointAt(0)); - count++; - } - } - - if (builder.length() == 0) { - return null; - } else { - return builder.toString(); - } - } -} diff --git a/libsession/src/main/java/org/session/libsession/avatars/ResourceContactPhoto.java b/libsession/src/main/java/org/session/libsession/avatars/ResourceContactPhoto.java index 2920b4b1ce..f76135e95a 100644 --- a/libsession/src/main/java/org/session/libsession/avatars/ResourceContactPhoto.java +++ b/libsession/src/main/java/org/session/libsession/avatars/ResourceContactPhoto.java @@ -4,13 +4,13 @@ import android.content.Context; import android.graphics.Color; import android.graphics.PorterDuff; import android.graphics.drawable.Drawable; +import android.graphics.drawable.GradientDrawable; import android.graphics.drawable.LayerDrawable; import android.widget.ImageView; import androidx.annotation.DrawableRes; import androidx.appcompat.content.res.AppCompatResources; -import com.amulyakhare.textdrawable.TextDrawable; import com.makeramen.roundedimageview.RoundedDrawable; import org.session.libsession.R; @@ -25,19 +25,33 @@ public class ResourceContactPhoto implements FallbackContactPhoto { } @Override - public Drawable asDrawable(Context context, int color) { - return asDrawable(context, color, false); + public Drawable asDrawable(Context context, int color, boolean inverted) { + return asDrawable(context, 0, false, 0f); } @Override - public Drawable asDrawable(Context context, int color, boolean inverted) { - Drawable background = TextDrawable.builder().buildRound(" ", inverted ? Color.WHITE : color); + public Drawable asDrawable(Context context, int color, boolean inverted, Float padding) { + // rounded colored background + GradientDrawable background = new GradientDrawable(); + background.setShape(GradientDrawable.OVAL); + background.setColor(inverted ? Color.WHITE : color); + + // resource image in the foreground RoundedDrawable foreground = (RoundedDrawable) RoundedDrawable.fromDrawable(AppCompatResources.getDrawable(context, resourceId)); - foreground.setScaleType(ImageView.ScaleType.CENTER_CROP); + if (foreground != null) { + if(padding == 0f){ + foreground.setScaleType(ImageView.ScaleType.CENTER_CROP); + } else { + // apply padding via a transparent border oterhwise things get misaligned + foreground.setScaleType(ImageView.ScaleType.FIT_CENTER); + foreground.setBorderColor(Color.TRANSPARENT); + foreground.setBorderWidth(padding); + } - if (inverted) { - foreground.setColorFilter(color, PorterDuff.Mode.SRC_ATOP); + if (inverted) { + foreground.setColorFilter(color, PorterDuff.Mode.SRC_ATOP); + } } Drawable gradient = AppCompatResources.getDrawable( diff --git a/libsession/src/main/java/org/session/libsession/avatars/TransparentContactPhoto.java b/libsession/src/main/java/org/session/libsession/avatars/TransparentContactPhoto.java index 56f2757e15..74d8e4ddc7 100644 --- a/libsession/src/main/java/org/session/libsession/avatars/TransparentContactPhoto.java +++ b/libsession/src/main/java/org/session/libsession/avatars/TransparentContactPhoto.java @@ -3,6 +3,8 @@ package org.session.libsession.avatars; import android.content.Context; import android.graphics.drawable.Drawable; +import androidx.core.content.ContextCompat; + import com.makeramen.roundedimageview.RoundedDrawable; public class TransparentContactPhoto implements FallbackContactPhoto { @@ -10,13 +12,13 @@ public class TransparentContactPhoto implements FallbackContactPhoto { public TransparentContactPhoto() {} @Override - public Drawable asDrawable(Context context, int color) { - return asDrawable(context, color, false); + public Drawable asDrawable(Context context, int color, boolean inverted) { + return asDrawable(context, color, inverted, 0f); } @Override - public Drawable asDrawable(Context context, int color, boolean inverted) { - return RoundedDrawable.fromDrawable(context.getResources().getDrawable(android.R.color.transparent)); + public Drawable asDrawable(Context context, int color, boolean inverted, Float padding) { + return RoundedDrawable.fromDrawable(ContextCompat.getDrawable(context, android.R.color.transparent)); } }