Update chat colors.

This commit is contained in:
Alex Hart
2021-05-03 11:34:41 -03:00
committed by Greyson Parrelli
parent 36fe150678
commit bcc5d485ab
164 changed files with 5817 additions and 1476 deletions

View File

@@ -26,6 +26,8 @@ import org.thoughtcrime.securesms.contacts.avatars.ContactColors;
import org.thoughtcrime.securesms.contacts.avatars.ContactPhoto;
import org.thoughtcrime.securesms.contacts.avatars.GeneratedContactPhoto;
import org.thoughtcrime.securesms.contacts.avatars.ProfileContactPhoto;
import org.thoughtcrime.securesms.conversation.colors.ChatColors;
import org.thoughtcrime.securesms.conversation.colors.ChatColorsPalette;
import org.thoughtcrime.securesms.mms.GlideApp;
import org.thoughtcrime.securesms.mms.GlideRequest;
import org.thoughtcrime.securesms.recipients.Recipient;
@@ -172,12 +174,8 @@ public final class AvatarUtil {
private static Drawable getFallback(@NonNull Context context, @NonNull Recipient recipient) {
String name = Optional.fromNullable(recipient.getDisplayName(context)).or("");
MaterialColor fallbackColor = recipient.getColor();
ChatColors fallbackColor = recipient.getChatColors();
if (fallbackColor == ContactColors.UNKNOWN_COLOR && !TextUtils.isEmpty(name)) {
fallbackColor = ContactColors.generateFor(name);
}
return new GeneratedContactPhoto(name, R.drawable.ic_profile_outline_40).asDrawable(context, fallbackColor.toAvatarColor(context));
return new GeneratedContactPhoto(name, R.drawable.ic_profile_outline_40).asDrawable(context, fallbackColor);
}
}

View File

@@ -23,6 +23,7 @@ import org.thoughtcrime.securesms.contacts.avatars.FallbackContactPhoto;
import org.thoughtcrime.securesms.contacts.avatars.FallbackPhoto80dp;
import org.thoughtcrime.securesms.contacts.avatars.GeneratedContactPhoto;
import org.thoughtcrime.securesms.contacts.avatars.SystemContactPhoto;
import org.thoughtcrime.securesms.conversation.colors.ChatColors;
import org.thoughtcrime.securesms.dependencies.ApplicationDependencies;
import org.thoughtcrime.securesms.keyvalue.SignalStore;
import org.thoughtcrime.securesms.mms.GlideApp;
@@ -177,9 +178,9 @@ public final class ConversationShortcutPhoto implements Key {
photoSource = R.drawable.ic_profile_80;
}
FallbackContactPhoto photo = recipient.isSelf() || recipient.isGroup() ? new FallbackPhoto80dp(photoSource, recipient.getColor().toAvatarColor(context))
FallbackContactPhoto photo = recipient.isSelf() || recipient.isGroup() ? new FallbackPhoto80dp(photoSource, recipient.getChatColors())
: new ShortcutGeneratedContactPhoto(recipient.getDisplayName(context), photoSource, ViewUtil.dpToPx(80), ViewUtil.dpToPx(28));
Bitmap toWrap = DrawableUtil.toBitmap(photo.asDrawable(context, recipient.getColor().toAvatarColor(context)), ViewUtil.dpToPx(80), ViewUtil.dpToPx(80));
Bitmap toWrap = DrawableUtil.toBitmap(photo.asDrawable(context, recipient.getChatColors()), ViewUtil.dpToPx(80), ViewUtil.dpToPx(80));
Bitmap wrapped = DrawableUtil.wrapBitmapForShortcutInfo(toWrap);
toWrap.recycle();
@@ -198,8 +199,8 @@ public final class ConversationShortcutPhoto implements Key {
}
@Override
protected Drawable newFallbackDrawable(@NonNull Context context, int color, boolean inverted) {
return new FallbackPhoto80dp(getFallbackResId(), color).asDrawable(context, -1);
protected Drawable newFallbackDrawable(@NonNull Context context, @NonNull ChatColors chatColors, boolean inverted) {
return new FallbackPhoto80dp(getFallbackResId(), chatColors).asDrawable(context, chatColors);
}
}
}

View File

@@ -0,0 +1,24 @@
package org.thoughtcrime.securesms.util
import android.graphics.Canvas
import android.graphics.drawable.Drawable
import android.graphics.drawable.LayerDrawable
/**
* Class which wraps a given drawable to perform some custom drawing / masking / whatever.
*
* We extend LayerDrawable here to take advantage of it's overrides and mechanisms, but explicitly
* abstract out the draw method to allow overrides to do whatever they want.
*/
private class CustomDrawWrapper(
private val wrapped: Drawable,
private val drawFn: (wrapped: Drawable, canvas: Canvas) -> Unit
) : LayerDrawable(arrayOf(wrapped)) {
override fun draw(canvas: Canvas) {
drawFn(wrapped, canvas)
}
}
fun Drawable.customizeOnDraw(customDrawFn: (wrapped: Drawable, canvas: Canvas) -> Unit): Drawable {
return CustomDrawWrapper(this, customDrawFn)
}

View File

@@ -0,0 +1,236 @@
package org.thoughtcrime.securesms.util;
import android.graphics.Path;
import android.graphics.Rect;
import android.graphics.RectF;
import android.os.Build;
import android.view.View;
import android.view.ViewGroup;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.recyclerview.widget.RecyclerView;
import org.signal.core.util.logging.Log;
import org.thoughtcrime.securesms.components.CornerMask;
import java.util.Objects;
/**
* Describes the position, size, and corner masking of a given view relative to a parent.
*/
public final class Projection {
private final float x;
private final float y;
private final int width;
private final int height;
private final Corners corners;
private final Path path;
private final RectF rect;
public Projection(float x, float y, int width, int height, @Nullable Corners corners) {
this.x = x;
this.y = y;
this.width = width;
this.height = height;
this.corners = corners;
this.path = new Path();
rect = new RectF();
rect.set(x, y, x + width, y + height);
if (corners != null) {
path.addRoundRect(rect, corners.toRadii(), Path.Direction.CW);
} else {
path.addRect(rect, Path.Direction.CW);
}
}
public float getX() {
return x;
}
public float getY() {
return y;
}
public int getWidth() {
return width;
}
public int getHeight() {
return height;
}
public @Nullable Corners getCorners() {
return corners;
}
public @NonNull Path getPath() {
return path;
}
public void applyToPath(@NonNull Path path) {
if (corners == null) {
path.addRect(rect, Path.Direction.CW);
} else {
if (Build.VERSION.SDK_INT >= 21) {
path.addRoundRect(rect, corners.toRadii(), Path.Direction.CW);
} else {
path.op(path, Path.Op.UNION);
}
}
}
@Override public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
final Projection that = (Projection) o;
return Float.compare(that.x, x) == 0 &&
Float.compare(that.y, y) == 0 &&
width == that.width &&
height == that.height &&
Objects.equals(corners, that.corners);
}
@Override public int hashCode() {
return Objects.hash(x, y, width, height, corners);
}
public @NonNull Projection translateX(float xTranslation) {
return new Projection(x + xTranslation, y, width, height, corners);
}
public @NonNull Projection withDimensions(int width, int height) {
return new Projection(x, y, width, height, corners);
}
public @NonNull Projection withHeight(int height) {
return new Projection(x, y, width, height, corners);
}
public static @NonNull Projection relativeToParent(@NonNull ViewGroup parent, @NonNull View view, @Nullable Corners corners) {
Rect viewBounds = new Rect();
view.getDrawingRect(viewBounds);
parent.offsetDescendantRectToMyCoords(view, viewBounds);
return new Projection(viewBounds.left, viewBounds.top, view.getWidth(), view.getHeight(), corners);
}
public static @NonNull Projection relativeToViewRoot(@NonNull View view, @Nullable Corners corners) {
Rect viewBounds = new Rect();
ViewGroup root = (ViewGroup) view.getRootView();
view.getDrawingRect(viewBounds);
root.offsetDescendantRectToMyCoords(view, viewBounds);
return new Projection(viewBounds.left, viewBounds.top, view.getWidth(), view.getHeight(), corners);
}
public static @NonNull Projection relativeToViewWithCommonRoot(@NonNull View toProject, @NonNull View viewWithCommonRoot, @Nullable Corners corners) {
Rect viewBounds = new Rect();
ViewGroup root = (ViewGroup) toProject.getRootView();
toProject.getDrawingRect(viewBounds);
root.offsetDescendantRectToMyCoords(toProject, viewBounds);
root.offsetRectIntoDescendantCoords(viewWithCommonRoot, viewBounds);
return new Projection(viewBounds.left, viewBounds.top, toProject.getWidth(), toProject.getHeight(), corners);
}
public static @NonNull Projection translateFromRootToDescendantCoords(@NonNull Projection rootProjection, @NonNull View descendant) {
Rect viewBounds = new Rect();
viewBounds.set((int) rootProjection.x, (int) rootProjection.y, (int) rootProjection.x + rootProjection.width, (int) rootProjection.y + rootProjection.height);
((ViewGroup) descendant.getRootView()).offsetRectIntoDescendantCoords(descendant, viewBounds);
return new Projection(viewBounds.left, viewBounds.top, rootProjection.width, rootProjection.height, rootProjection.corners);
}
public static @NonNull Projection translateFromDescendantToParentCoords(@NonNull Projection descendantProjection, @NonNull View descendant, @NonNull ViewGroup parent) {
Rect viewBounds = new Rect();
viewBounds.set((int) descendantProjection.x, (int) descendantProjection.y, (int) descendantProjection.x + descendantProjection.width, (int) descendantProjection.y + descendantProjection.height);
parent.offsetDescendantRectToMyCoords(descendant, viewBounds);
return new Projection(viewBounds.left, viewBounds.top, descendantProjection.width, descendantProjection.height, descendantProjection.corners);
}
public static final class Corners {
private final float topLeft;
private final float topRight;
private final float bottomRight;
private final float bottomLeft;
public Corners(float topLeft, float topRight, float bottomRight, float bottomLeft) {
this.topLeft = topLeft;
this.topRight = topRight;
this.bottomRight = bottomRight;
this.bottomLeft = bottomLeft;
}
public Corners(float[] radii) {
this.topLeft = radii[0];
this.topRight = radii[2];
this.bottomRight = radii[4];
this.bottomLeft = radii[6];
}
public Corners(float radius) {
this(radius, radius, radius, radius);
}
public float getTopLeft() {
return topLeft;
}
public float getTopRight() {
return topRight;
}
public float getBottomLeft() {
return bottomLeft;
}
public float getBottomRight() {
return bottomRight;
}
public float[] toRadii() {
float[] radii = new float[8];
radii[0] = radii[1] = topLeft;
radii[2] = radii[3] = topRight;
radii[4] = radii[5] = bottomRight;
radii[6] = radii[7] = bottomLeft;
return radii;
}
@Override public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
final Corners corners = (Corners) o;
return Float.compare(corners.topLeft, topLeft) == 0 &&
Float.compare(corners.topRight, topRight) == 0 &&
Float.compare(corners.bottomRight, bottomRight) == 0 &&
Float.compare(corners.bottomLeft, bottomLeft) == 0;
}
@Override public int hashCode() {
return Objects.hash(topLeft, topRight, bottomRight, bottomLeft);
}
@Override public String toString() {
return "Corners{" +
"topLeft=" + topLeft +
", topRight=" + topRight +
", bottomRight=" + bottomRight +
", bottomLeft=" + bottomLeft +
'}';
}
}
}

View File

@@ -407,6 +407,10 @@ public class Util {
return elements[new SecureRandom().nextInt(elements.length)];
}
public static <T> T getRandomElement(List<T> elements) {
return elements.get(new SecureRandom().nextInt(elements.size()));
}
public static boolean equals(@Nullable Object a, @Nullable Object b) {
return a == b || (a != null && a.equals(b));
}