diff --git a/res/drawable/compose_background.xml b/res/drawable/compose_background_dark.xml
similarity index 64%
rename from res/drawable/compose_background.xml
rename to res/drawable/compose_background_dark.xml
index 18b651b7f8..c04badbf74 100644
--- a/res/drawable/compose_background.xml
+++ b/res/drawable/compose_background_dark.xml
@@ -5,10 +5,10 @@
+ android:color="@color/core_dark_70" />
+ android:color="@color/core_dark_85" />
diff --git a/res/drawable/compose_background_light.xml b/res/drawable/compose_background_light.xml
new file mode 100644
index 0000000000..b93c9edb7b
--- /dev/null
+++ b/res/drawable/compose_background_light.xml
@@ -0,0 +1,16 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/res/drawable/message_bubble_background_received_alone.xml b/res/drawable/message_bubble_background_received_alone.xml
new file mode 100644
index 0000000000..cda641b1da
--- /dev/null
+++ b/res/drawable/message_bubble_background_received_alone.xml
@@ -0,0 +1,13 @@
+
+
+ -
+
+
+
+
+
+
+
diff --git a/res/drawable/message_bubble_background_received_end.xml b/res/drawable/message_bubble_background_received_end.xml
new file mode 100644
index 0000000000..3e4e2c0562
--- /dev/null
+++ b/res/drawable/message_bubble_background_received_end.xml
@@ -0,0 +1,17 @@
+
+
+ -
+
+
+
+
+
+
+
diff --git a/res/drawable/message_bubble_background_received_middle.xml b/res/drawable/message_bubble_background_received_middle.xml
new file mode 100644
index 0000000000..e3888978ab
--- /dev/null
+++ b/res/drawable/message_bubble_background_received_middle.xml
@@ -0,0 +1,17 @@
+
+
+ -
+
+
+
+
+
+
+
diff --git a/res/drawable/message_bubble_background_received_start.xml b/res/drawable/message_bubble_background_received_start.xml
new file mode 100644
index 0000000000..4c30cc7565
--- /dev/null
+++ b/res/drawable/message_bubble_background_received_start.xml
@@ -0,0 +1,17 @@
+
+
+ -
+
+
+
+
+
+
+
diff --git a/res/drawable/message_bubble_background_sent_alone.xml b/res/drawable/message_bubble_background_sent_alone.xml
new file mode 100644
index 0000000000..6f19f4f16f
--- /dev/null
+++ b/res/drawable/message_bubble_background_sent_alone.xml
@@ -0,0 +1,13 @@
+
+
+ -
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/res/drawable/message_bubble_background_sent_end.xml b/res/drawable/message_bubble_background_sent_end.xml
new file mode 100644
index 0000000000..5bc4597c03
--- /dev/null
+++ b/res/drawable/message_bubble_background_sent_end.xml
@@ -0,0 +1,17 @@
+
+
+ -
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/res/drawable/message_bubble_background_sent_middle.xml b/res/drawable/message_bubble_background_sent_middle.xml
new file mode 100644
index 0000000000..aea4264539
--- /dev/null
+++ b/res/drawable/message_bubble_background_sent_middle.xml
@@ -0,0 +1,17 @@
+
+
+ -
+
+
+
+
+
+
+
diff --git a/res/drawable/message_bubble_background_sent_start.xml b/res/drawable/message_bubble_background_sent_start.xml
new file mode 100644
index 0000000000..4719d235f4
--- /dev/null
+++ b/res/drawable/message_bubble_background_sent_start.xml
@@ -0,0 +1,17 @@
+
+
+ -
+
+
+
+
+
+
+
diff --git a/res/drawable/sticky_date_header_background.xml b/res/drawable/sticky_date_header_background_dark.xml
similarity index 69%
rename from res/drawable/sticky_date_header_background.xml
rename to res/drawable/sticky_date_header_background_dark.xml
index e4fa232676..d5be2c288c 100644
--- a/res/drawable/sticky_date_header_background.xml
+++ b/res/drawable/sticky_date_header_background_dark.xml
@@ -4,5 +4,5 @@
android:shape="rectangle">
-
+
\ No newline at end of file
diff --git a/res/drawable/sticky_date_header_background_light.xml b/res/drawable/sticky_date_header_background_light.xml
new file mode 100644
index 0000000000..b015b381ba
--- /dev/null
+++ b/res/drawable/sticky_date_header_background_light.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/res/layout/conversation_fragment.xml b/res/layout/conversation_fragment.xml
index 41eac4b702..ab905ae024 100644
--- a/res/layout/conversation_fragment.xml
+++ b/res/layout/conversation_fragment.xml
@@ -28,7 +28,7 @@
style="@style/Signal.Text.Caption"
android:textColor="?attr/conversation_item_sticky_date_text_color"
android:textAllCaps="true"
- android:background="@drawable/sticky_date_header_background"
+ android:background="?attr/conversation_item_sticky_date_background"
android:elevation="9dp"
android:visibility="gone"
tools:text="March 1, 2015" />
diff --git a/res/layout/conversation_input_panel.xml b/res/layout/conversation_input_panel.xml
index 70e43f2207..c06879dc34 100644
--- a/res/layout/conversation_input_panel.xml
+++ b/res/layout/conversation_input_panel.xml
@@ -27,7 +27,7 @@
android:id="@+id/compose_bubble"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:background="@drawable/compose_background"
+ android:background="?attr/conversation_input_background"
android:clipChildren="false"
android:clipToPadding="false"
android:orientation="vertical">
diff --git a/res/layout/conversation_item_received.xml b/res/layout/conversation_item_received.xml
index 91870ed9aa..d5eee08bb9 100644
--- a/res/layout/conversation_item_received.xml
+++ b/res/layout/conversation_item_received.xml
@@ -20,6 +20,8 @@
android:layout_height="wrap_content"
android:layout_marginRight="@dimen/conversation_individual_right_gutter"
android:layout_marginEnd="@dimen/conversation_individual_right_gutter"
+ android:paddingLeft="8dp"
+ android:paddingStart="8dp"
android:clipToPadding="false"
android:clipChildren="false">
@@ -28,31 +30,28 @@
android:foreground="@drawable/contact_photo_background"
android:layout_width="36dp"
android:layout_height="36dp"
- android:layout_marginLeft="8dp"
- android:layout_marginRight="8dp"
android:layout_marginBottom="6dp"
android:layout_alignParentLeft="true"
+ android:layout_alignParentStart="true"
android:layout_alignParentBottom="true"
android:cropToPadding="true"
android:contentDescription="@string/conversation_item_received__contact_photo_description" />
-
-
-
+ android:clipChildren="false"
+ android:background="@color/white"
+ tools:backgroundTint="@color/conversation_blue">
-
-
-
+
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ app:footer_color="?conversation_item_sent_text_secondary_color"/>
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
+ android:layout_height="wrap_content"
+ android:orientation="horizontal">
+
+
+ android:layout_marginLeft="8dp"
+ android:layout_marginStart="8dp"
+ android:layout_marginRight="8dp"
+ android:layout_marginEnd="8dp"
+ android:layout_marginTop="8dp"
+ android:layout_marginBottom="8dp"
+ android:orientation="vertical"
+ android:layout_weight="1">
-
+
+ android:layout_marginBottom="2dp"
+ android:orientation="horizontal"
+ android:gravity="center_vertical"
+ android:visibility="gone"
+ tools:visibility="visible">
-
-
-
-
-
-
-
-
-
+
-
-
-
+ tools:text="The-Amazing-Spider-Man.cba" />
-
-
-
+ android:layout_height="wrap_content"
+ android:layout_marginRight="8dp"
+ style="@style/Signal.Text.Caption"
+ android:textColor="@color/core_light_90"
+ android:paddingTop="4dp"
+ android:textStyle="italic"
+ android:visibility="gone"
+ tools:text="Photo"
+ tools:visibility="visible" />
-
+
-
-
-
-
-
-
+ android:layout_height="match_parent">
-
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/res/values/attrs.xml b/res/values/attrs.xml
index 0b6db57e42..0390480837 100644
--- a/res/values/attrs.xml
+++ b/res/values/attrs.xml
@@ -28,8 +28,7 @@
-
-
+
@@ -77,7 +76,7 @@
-
+
diff --git a/res/values/themes.xml b/res/values/themes.xml
index 95936da31d..c35309cc06 100644
--- a/res/values/themes.xml
+++ b/res/values/themes.xml
@@ -146,8 +146,7 @@
- @color/core_white
- #22000000
- #ff111111
- - @color/core_light_02
- - @color/core_light_10
+ - @drawable/compose_background_light
- @drawable/ic_send_sms_insecure
- @drawable/ic_send_push
- @color/white
@@ -195,7 +194,7 @@
- @color/core_light_60
- @color/core_light_45
- @color/core_light_90
- - @color/core_light_02
+ - @drawable/sticky_date_header_background_light
- @color/core_light_60
- @color/core_light_45
@@ -295,7 +294,7 @@
- @color/core_dark_30
- @color/core_dark_55
- @color/core_dark_05
- - @color/core_dark_85
+ - @drawable/sticky_date_header_background_dark
- @color/core_dark_30
- @color/core_dark_60
@@ -319,8 +318,7 @@
- @color/black
- #22ffffff
- #ffeeeeee
- - @color/core_dark_85
- - @color/core_dark_70
+ - @drawable/compose_background_dark
- @drawable/ic_send_sms_insecure_dark
- @drawable/ic_send_push
- @color/black
diff --git a/src/org/thoughtcrime/securesms/ConversationItem.java b/src/org/thoughtcrime/securesms/ConversationItem.java
index 5cad022cfa..b6797811a8 100644
--- a/src/org/thoughtcrime/securesms/ConversationItem.java
+++ b/src/org/thoughtcrime/securesms/ConversationItem.java
@@ -110,16 +110,16 @@ public class ConversationItem extends LinearLayout
private Recipient recipient;
private GlideRequests glideRequests;
- protected CornerMaskingView bodyBubble;
- private QuoteView quoteView;
- private TextView bodyText;
- private ConversationItemFooter footer;
- private TextView groupSender;
- private TextView groupSenderProfileName;
- private View groupSenderHolder;
- private AvatarImageView contactPhoto;
- private AlertView alertView;
- private ViewGroup container;
+ protected ViewGroup bodyBubble;
+ private QuoteView quoteView;
+ private TextView bodyText;
+ private ConversationItemFooter footer;
+ private TextView groupSender;
+ private TextView groupSenderProfileName;
+ private View groupSenderHolder;
+ private AvatarImageView contactPhoto;
+ private AlertView alertView;
+ private ViewGroup container;
private @NonNull Set batchSelected = new HashSet<>();
private @NonNull Recipient conversationRecipient;
@@ -203,7 +203,9 @@ public class ConversationItem extends LinearLayout
this.recipient.addListener(this);
this.conversationRecipient.addListener(this);
- setMediaAttributes(messageRecord, nextMessageRecord, previousMessageRecord, conversationRecipient, groupThread);
+ setGutterSizes(messageRecord, groupThread);
+ setMessageShape(messageRecord, previousMessageRecord, nextMessageRecord, groupThread);
+ setMediaAttributes(messageRecord, previousMessageRecord, nextMessageRecord, conversationRecipient, groupThread);
setInteractionState(messageRecord, pulseHighlight);
setBodyText(messageRecord);
setBubbleState(messageRecord);
@@ -213,9 +215,7 @@ public class ConversationItem extends LinearLayout
setAuthor(messageRecord, previousMessageRecord, nextMessageRecord, groupThread);
setQuote(messageRecord, previousMessageRecord, nextMessageRecord, groupThread);
setMessageSpacing(context, messageRecord, nextMessageRecord);
- setGutterSizes(messageRecord, groupThread);
setFooter(messageRecord, nextMessageRecord, locale, groupThread);
- setMessageShape(messageRecord, previousMessageRecord, nextMessageRecord, groupThread);
}
@Override
@@ -414,6 +414,8 @@ public class ConversationItem extends LinearLayout
sharedContactStub.get().setOnClickListener(sharedContactClickListener);
sharedContactStub.get().setOnLongClickListener(passthroughClickListener);
+ setSharedContactCorners(messageRecord, previousRecord, nextRecord, isGroupThread);
+
ViewUtil.updateLayoutParams(bodyText, ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
footer.setVisibility(GONE);
} else if (hasAudio(messageRecord)) {
@@ -464,7 +466,7 @@ public class ConversationItem extends LinearLayout
mediaThumbnailStub.get().setOnClickListener(passthroughClickListener);
mediaThumbnailStub.get().showShade(TextUtils.isEmpty(messageRecord.getDisplayBody()));
- setThumbnailOutlineCorners(messageRecord, nextRecord, previousRecord, isGroupThread);
+ setThumbnailOutlineCorners(messageRecord, previousRecord, nextRecord, isGroupThread);
ViewUtil.updateLayoutParams(bodyText, ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
footer.setVisibility(VISIBLE);
@@ -537,6 +539,18 @@ public class ConversationItem extends LinearLayout
mediaThumbnailStub.get().setOutlineCorners(topLeft, topRight, bottomRight, bottomLeft);
}
+ private void setSharedContactCorners(@NonNull MessageRecord current, @NonNull Optional previous, @NonNull Optional next, boolean isGroupThread) {
+ if (isSingularMessage(current, previous, next, isGroupThread) || isEndOfMessageCluster(current, next, isGroupThread)) {
+ sharedContactStub.get().setSingularStyle();
+ } else {
+ if (current.isOutgoing()) {
+ sharedContactStub.get().setClusteredOutgoingStyle();
+ } else {
+ sharedContactStub.get().setClusteredIncomingStyle();
+ }
+ }
+ }
+
private void setContactPhoto(@NonNull Recipient recipient) {
if (contactPhoto == null) return;
@@ -621,18 +635,10 @@ public class ConversationItem extends LinearLayout
}
private void setGutterSizes(@NonNull MessageRecord current, boolean isGroupThread) {
- if (isGroupThread) {
- if (current.isOutgoing()) {
- ViewUtil.setLeftMargin(container, readDimen(R.dimen.conversation_group_left_gutter));
- } else {
- ViewUtil.setLeftMargin(bodyBubble, readDimen(R.dimen.conversation_group_left_gutter));
- }
- } else {
- if (current.isOutgoing()) {
- ViewUtil.setLeftMargin(container, readDimen(R.dimen.conversation_individual_left_gutter));
- } else {
- ViewUtil.setLeftMargin(bodyBubble, readDimen(R.dimen.conversation_individual_left_gutter));
- }
+ if (isGroupThread && current.isOutgoing()) {
+ ViewUtil.setLeftMargin(container, readDimen(R.dimen.conversation_group_left_gutter));
+ } else if (current.isOutgoing()) {
+ ViewUtil.setLeftMargin(container, readDimen(R.dimen.conversation_individual_left_gutter));
}
}
@@ -698,7 +704,7 @@ public class ConversationItem extends LinearLayout
if (!next.isPresent() || next.get().isUpdate() || !current.getRecipient().getAddress().equals(next.get().getRecipient().getAddress())) {
contactPhoto.setVisibility(VISIBLE);
} else {
- contactPhoto.setVisibility(GONE);
+ contactPhoto.setVisibility(INVISIBLE);
}
} else {
groupSenderHolder.setVisibility(GONE);
@@ -710,45 +716,22 @@ public class ConversationItem extends LinearLayout
}
private void setMessageShape(@NonNull MessageRecord current, @NonNull Optional previous, @NonNull Optional next, boolean isGroupThread) {
+ int background;
if (isSingularMessage(current, previous, next, isGroupThread)) {
- bodyBubble.setRadius(readDimen(R.dimen.message_corner_radius));
+ background = current.isOutgoing() ? R.drawable.message_bubble_background_sent_alone
+ : R.drawable.message_bubble_background_received_alone;
} else if (isStartOfMessageCluster(current, previous, isGroupThread)) {
- if (current.isOutgoing()) {
- bodyBubble.setRadii(readDimen(R.dimen.message_corner_radius),
- readDimen(R.dimen.message_corner_radius),
- readDimen(R.dimen.message_corner_collapse_radius),
- readDimen(R.dimen.message_corner_radius));
- } else {
- bodyBubble.setRadii(readDimen(R.dimen.message_corner_radius),
- readDimen(R.dimen.message_corner_radius),
- readDimen(R.dimen.message_corner_radius),
- readDimen(R.dimen.message_corner_collapse_radius));
- }
+ background = current.isOutgoing() ? R.drawable.message_bubble_background_sent_start
+ : R.drawable.message_bubble_background_received_start;
} else if (isEndOfMessageCluster(current, next, isGroupThread)) {
- if (current.isOutgoing()) {
- bodyBubble.setRadii(readDimen(R.dimen.message_corner_radius),
- readDimen(R.dimen.message_corner_collapse_radius),
- readDimen(R.dimen.message_corner_radius),
- readDimen(R.dimen.message_corner_radius));
- } else {
- bodyBubble.setRadii(readDimen(R.dimen.message_corner_collapse_radius),
- readDimen(R.dimen.message_corner_radius),
- readDimen(R.dimen.message_corner_radius),
- readDimen(R.dimen.message_corner_radius));
- }
+ background = current.isOutgoing() ? R.drawable.message_bubble_background_sent_end
+ : R.drawable.message_bubble_background_received_end;
} else {
- if (current.isOutgoing()) {
- bodyBubble.setRadii(readDimen(R.dimen.message_corner_radius),
- readDimen(R.dimen.message_corner_collapse_radius),
- readDimen(R.dimen.message_corner_collapse_radius),
- readDimen(R.dimen.message_corner_radius));
- } else {
- bodyBubble.setRadii(readDimen(R.dimen.message_corner_collapse_radius),
- readDimen(R.dimen.message_corner_radius),
- readDimen(R.dimen.message_corner_radius),
- readDimen(R.dimen.message_corner_collapse_radius));
- }
+ background = current.isOutgoing() ? R.drawable.message_bubble_background_sent_middle
+ : R.drawable.message_bubble_background_received_middle;
}
+
+ bodyBubble.setBackgroundResource(background);
}
private boolean isStartOfMessageCluster(@NonNull MessageRecord current, @NonNull Optional previous, boolean isGroupThread) {
diff --git a/src/org/thoughtcrime/securesms/components/ConversationItemThumbnail.java b/src/org/thoughtcrime/securesms/components/ConversationItemThumbnail.java
index 83148e460f..4d4356f908 100644
--- a/src/org/thoughtcrime/securesms/components/ConversationItemThumbnail.java
+++ b/src/org/thoughtcrime/securesms/components/ConversationItemThumbnail.java
@@ -48,6 +48,7 @@ public class ConversationItemThumbnail extends FrameLayout {
private ImageView shade;
private ConversationItemFooter footer;
private Paint outlinePaint;
+ private CornerMask cornerMask;
public ConversationItemThumbnail(Context context) {
super(context);
@@ -71,6 +72,7 @@ public class ConversationItemThumbnail extends FrameLayout {
this.shade = findViewById(R.id.conversation_thumbnail_shade);
this.footer = findViewById(R.id.conversation_thumbnail_footer);
this.outlinePaint = ThemeUtil.isDarkTheme(getContext()) ? DARK_THEME_OUTLINE_PAINT : LIGHT_THEME_OUTLINE_PAINT;
+ this.cornerMask = new CornerMask(this);
setTouchDelegate(thumbnail.getTouchDelegate());
@@ -87,8 +89,16 @@ public class ConversationItemThumbnail extends FrameLayout {
@SuppressWarnings("SuspiciousNameCombination")
@Override
protected void dispatchDraw(Canvas canvas) {
+ if (cornerMask.isLegacy()) {
+ cornerMask.mask(canvas);
+ }
+
super.dispatchDraw(canvas);
+ if (!cornerMask.isLegacy()) {
+ cornerMask.mask(canvas);
+ }
+
final float halfStrokeWidth = outlinePaint.getStrokeWidth() / 2;
bounds.left = halfStrokeWidth;
@@ -137,6 +147,8 @@ public class ConversationItemThumbnail extends FrameLayout {
radii[2] = radii[3] = topRight;
radii[4] = radii[5] = bottomRight;
radii[6] = radii[7] = bottomLeft;
+
+ cornerMask.setRadii(topLeft, topRight, bottomRight, bottomLeft);
}
public ConversationItemFooter getFooter() {
diff --git a/src/org/thoughtcrime/securesms/components/CornerMask.java b/src/org/thoughtcrime/securesms/components/CornerMask.java
new file mode 100644
index 0000000000..085df25574
--- /dev/null
+++ b/src/org/thoughtcrime/securesms/components/CornerMask.java
@@ -0,0 +1,88 @@
+package org.thoughtcrime.securesms.components;
+
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.Paint;
+import android.graphics.Path;
+import android.graphics.PorterDuff;
+import android.graphics.PorterDuffXfermode;
+import android.graphics.RectF;
+import android.os.Build;
+import android.support.annotation.NonNull;
+import android.view.View;
+
+public class CornerMask {
+
+ private final float[] radii = new float[8];
+ private final Paint clearPaint = new Paint();
+ private final Path outline = new Path();
+ private final Path corners = new Path();
+ private final RectF bounds = new RectF();
+
+ public CornerMask(@NonNull View view) {
+ if (isLegacy()) {
+ view.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
+ } else {
+ view.setLayerType(View.LAYER_TYPE_HARDWARE, null);
+ }
+
+ clearPaint.setColor(Color.BLACK);
+ clearPaint.setStyle(Paint.Style.FILL);
+ clearPaint.setAntiAlias(true);
+ clearPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
+ }
+
+ public void mask(Canvas canvas) {
+ bounds.left = 0;
+ bounds.top = 0;
+ bounds.right = canvas.getWidth();
+ bounds.bottom = canvas.getHeight();
+
+ corners.reset();
+ corners.addRoundRect(bounds, radii, Path.Direction.CW);
+
+ // Note: There's a bug in the P beta where most PorterDuff modes aren't working. But CLEAR does.
+ // So we find and inverse path and use Mode.CLEAR for versions that support Path.op().
+ // See issue https://issuetracker.google.com/issues/111394085.
+ if (!isLegacy()) {
+ outline.reset();
+ outline.addRect(bounds, Path.Direction.CW);
+ outline.op(corners, Path.Op.DIFFERENCE);
+ canvas.drawPath(outline, clearPaint);
+ } else {
+ corners.addRoundRect(bounds, radii, Path.Direction.CW);
+ canvas.clipPath(corners);
+ }
+ }
+
+ public boolean isLegacy() {
+ return Build.VERSION.SDK_INT < 19;
+ }
+
+ public void setRadius(int radius) {
+ setRadii(radius, radius, radius, radius);
+ }
+
+ public void setRadii(int topLeft, int topRight, int bottomRight, int bottomLeft) {
+ radii[0] = radii[1] = topLeft;
+ radii[2] = radii[3] = topRight;
+ radii[4] = radii[5] = bottomRight;
+ radii[6] = radii[7] = bottomLeft;
+ }
+
+ public void setTopLeftRadius(int radius) {
+ radii[0] = radii[1] = radius;
+ }
+
+ public void setTopRightRadius(int radius) {
+ radii[2] = radii[3] = radius;
+ }
+
+ public void setBottomRightRadius(int radius) {
+ radii[4] = radii[5] = radius;
+ }
+
+ public void setBottomLeftRadius(int radius) {
+ radii[6] = radii[7] = radius;
+ }
+}
diff --git a/src/org/thoughtcrime/securesms/components/QuoteView.java b/src/org/thoughtcrime/securesms/components/QuoteView.java
index c2dbcbc995..8222c1062a 100644
--- a/src/org/thoughtcrime/securesms/components/QuoteView.java
+++ b/src/org/thoughtcrime/securesms/components/QuoteView.java
@@ -3,6 +3,7 @@ package org.thoughtcrime.securesms.components;
import android.content.Context;
import android.content.res.TypedArray;
+import android.graphics.Canvas;
import android.graphics.Color;
import android.os.Build;
import android.support.annotation.NonNull;
@@ -40,25 +41,25 @@ public class QuoteView extends LinearLayout implements RecipientModifiedListener
private static final int MESSAGE_TYPE_OUTGOING = 1;
private static final int MESSAGE_TYPE_INCOMING = 2;
- private CornerMaskingView rootView;
- private View backgroundView;
- private TextView authorView;
- private TextView bodyView;
- private ImageView quoteBarView;
- private ImageView thumbnailView;
- private View attachmentVideoOverlayView;
- private ViewGroup attachmentContainerView;
- private TextView attachmentNameView;
- private ImageView dismissView;
+ private ViewGroup rootView;
+ private TextView authorView;
+ private TextView bodyView;
+ private ImageView quoteBarView;
+ private ImageView thumbnailView;
+ private View attachmentVideoOverlayView;
+ private ViewGroup attachmentContainerView;
+ private TextView attachmentNameView;
+ private ImageView dismissView;
- private long id;
- private Recipient author;
- private String body;
- private TextView mediaDescriptionText;
- private SlideDeck attachments;
- private int messageType;
- private int largeCornerRadius;
- private int smallCornerRadius;
+ private long id;
+ private Recipient author;
+ private String body;
+ private TextView mediaDescriptionText;
+ private SlideDeck attachments;
+ private int messageType;
+ private int largeCornerRadius;
+ private int smallCornerRadius;
+ private CornerMask cornerMask;
public QuoteView(Context context) {
@@ -86,7 +87,6 @@ public class QuoteView extends LinearLayout implements RecipientModifiedListener
inflate(getContext(), R.layout.quote_view, this);
this.rootView = findViewById(R.id.quote_root);
- this.backgroundView = findViewById(R.id.quote_background);
this.authorView = findViewById(R.id.quote_author);
this.bodyView = findViewById(R.id.quote_text);
this.quoteBarView = findViewById(R.id.quote_bar);
@@ -99,7 +99,8 @@ public class QuoteView extends LinearLayout implements RecipientModifiedListener
this.largeCornerRadius = getResources().getDimensionPixelSize(R.dimen.quote_corner_radius_large);
this.smallCornerRadius = getResources().getDimensionPixelSize(R.dimen.quote_corner_radius_bottom);
- rootView.setRadii(largeCornerRadius, largeCornerRadius, smallCornerRadius, smallCornerRadius);
+ cornerMask = new CornerMask(this);
+ cornerMask.setRadii(largeCornerRadius, largeCornerRadius, smallCornerRadius, smallCornerRadius);
if (attrs != null) {
TypedArray typedArray = getContext().getTheme().obtainStyledAttributes(attrs, R.styleable.QuoteView, 0, 0);
@@ -117,16 +118,31 @@ public class QuoteView extends LinearLayout implements RecipientModifiedListener
if (messageType == MESSAGE_TYPE_PREVIEW) {
int radius = getResources().getDimensionPixelOffset(R.dimen.quote_corner_radius_preview);
- rootView.setTopLeftRadius(radius);
- rootView.setTopRightRadius(radius);
+ cornerMask.setTopLeftRadius(radius);
+ cornerMask.setTopRightRadius(radius);
}
}
dismissView.setOnClickListener(view -> setVisibility(GONE));
- setWillNotDraw(false);
- if (Build.VERSION.SDK_INT < 18) {
- setLayerType(View.LAYER_TYPE_SOFTWARE, null);
+ if (cornerMask.isLegacy()) {
+ setWillNotDraw(false);
+ }
+ }
+
+ @Override
+ protected void onDraw(Canvas canvas) {
+ super.onDraw(canvas);
+ if (cornerMask.isLegacy()) {
+ cornerMask.mask(canvas);
+ }
+ }
+
+ @Override
+ protected void dispatchDraw(Canvas canvas) {
+ super.dispatchDraw(canvas);
+ if (!cornerMask.isLegacy()) {
+ cornerMask.mask(canvas);
}
}
@@ -145,8 +161,8 @@ public class QuoteView extends LinearLayout implements RecipientModifiedListener
}
public void setTopCornerSizes(boolean topLeftLarge, boolean topRightLarge) {
- rootView.setTopLeftRadius(topLeftLarge ? largeCornerRadius : smallCornerRadius);
- rootView.setTopRightRadius(topRightLarge ? largeCornerRadius : smallCornerRadius);
+ cornerMask.setTopLeftRadius(topLeftLarge ? largeCornerRadius : smallCornerRadius);
+ cornerMask.setTopRightRadius(topRightLarge ? largeCornerRadius : smallCornerRadius);
}
public void dismiss() {
@@ -177,7 +193,7 @@ public class QuoteView extends LinearLayout implements RecipientModifiedListener
// We use the raw color resource because Android 4.x was struggling with tints here
quoteBarView.setImageResource(author.getColor().toQuoteBarColorResource(getContext(), outgoing));
- backgroundView.setBackgroundColor(author.getColor().toQuoteBackgroundColor(getContext(), outgoing));
+ rootView.setBackgroundColor(author.getColor().toQuoteBackgroundColor(getContext(), outgoing));
}
private void setQuoteText(@Nullable String body, @NonNull SlideDeck attachments) {
diff --git a/src/org/thoughtcrime/securesms/components/SharedContactView.java b/src/org/thoughtcrime/securesms/components/SharedContactView.java
index 30af4c725c..94435e2405 100644
--- a/src/org/thoughtcrime/securesms/components/SharedContactView.java
+++ b/src/org/thoughtcrime/securesms/components/SharedContactView.java
@@ -2,6 +2,7 @@ package org.thoughtcrime.securesms.components;
import android.content.Context;
import android.content.res.TypedArray;
+import android.graphics.Canvas;
import android.graphics.Color;
import android.net.Uri;
import android.os.Build;
@@ -46,6 +47,9 @@ public class SharedContactView extends LinearLayout implements RecipientModified
private Locale locale;
private GlideRequests glideRequests;
private EventListener eventListener;
+ private CornerMask cornerMask;
+ private int bigCornerRadius;
+ private int smallCornerRadius;
private final Map activeRecipients = new HashMap<>();
@@ -79,6 +83,10 @@ public class SharedContactView extends LinearLayout implements RecipientModified
actionButtonView = findViewById(R.id.contact_action_button);
footer = findViewById(R.id.contact_footer);
+ cornerMask = new CornerMask(this);
+ bigCornerRadius = getResources().getDimensionPixelOffset(R.dimen.message_corner_radius);
+ smallCornerRadius = getResources().getDimensionPixelOffset(R.dimen.message_corner_collapse_radius);
+
if (attrs != null) {
TypedArray typedArray = getContext().getTheme().obtainStyledAttributes(attrs, R.styleable.SharedContactView, 0, 0);
int titleColor = typedArray.getInt(R.styleable.SharedContactView_contact_titleColor, Color.BLACK);
@@ -89,6 +97,26 @@ public class SharedContactView extends LinearLayout implements RecipientModified
numberView.setTextColor(captionColor);
footer.setColor(captionColor);
}
+
+ if (cornerMask.isLegacy()) {
+ setWillNotDraw(false);
+ }
+ }
+
+ @Override
+ protected void onDraw(Canvas canvas) {
+ super.onDraw(canvas);
+ if (cornerMask.isLegacy()) {
+ cornerMask.mask(canvas);
+ }
+ }
+
+ @Override
+ protected void dispatchDraw(Canvas canvas) {
+ super.dispatchDraw(canvas);
+ if (!cornerMask.isLegacy()) {
+ cornerMask.mask(canvas);
+ }
}
public void setContact(@NonNull Contact contact, @NonNull GlideRequests glideRequests, @NonNull Locale locale) {
@@ -104,6 +132,21 @@ public class SharedContactView extends LinearLayout implements RecipientModified
presentActionButtons(ContactUtil.getRecipients(getContext(), contact));
}
+ public void setSingularStyle() {
+ cornerMask.setBottomLeftRadius(bigCornerRadius);
+ cornerMask.setBottomRightRadius(bigCornerRadius);
+ }
+
+ public void setClusteredIncomingStyle() {
+ cornerMask.setBottomLeftRadius(smallCornerRadius);
+ cornerMask.setBottomRightRadius(bigCornerRadius);
+ }
+
+ public void setClusteredOutgoingStyle() {
+ cornerMask.setBottomLeftRadius(bigCornerRadius);
+ cornerMask.setBottomRightRadius(smallCornerRadius);
+ }
+
public void setEventListener(@NonNull EventListener eventListener) {
this.eventListener = eventListener;
}
diff --git a/src/org/thoughtcrime/securesms/util/ViewUtil.java b/src/org/thoughtcrime/securesms/util/ViewUtil.java
index b52cd6b192..8f606103c3 100644
--- a/src/org/thoughtcrime/securesms/util/ViewUtil.java
+++ b/src/org/thoughtcrime/securesms/util/ViewUtil.java
@@ -224,6 +224,7 @@ public class ViewUtil {
} else {
((ViewGroup.MarginLayoutParams) view.getLayoutParams()).rightMargin = margin;
}
+ view.forceLayout();
view.requestLayout();
}