diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/AlbumThumbnailView.java b/app/src/main/java/org/thoughtcrime/securesms/components/AlbumThumbnailView.java index 5d25e43f3d..0ef243ca4e 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/AlbumThumbnailView.java +++ b/app/src/main/java/org/thoughtcrime/securesms/components/AlbumThumbnailView.java @@ -1,9 +1,8 @@ package org.thoughtcrime.securesms.components; import android.content.Context; -import android.graphics.Bitmap; -import android.graphics.drawable.Drawable; import android.util.AttributeSet; +import android.view.View; import android.view.ViewGroup; import android.widget.FrameLayout; import android.widget.TextView; @@ -29,13 +28,13 @@ public class AlbumThumbnailView extends FrameLayout { private int currentSizeClass; + private final int[] corners = new int[4]; + private ViewGroup albumCellContainer; private Stub transferControls; - private Drawable imageDrawable; private final SlideClickListener defaultThumbnailClickListener = (v, slide) -> { if (thumbnailClickListener != null) { - imageDrawable = ((ThumbnailView) v).getImageDrawable(); thumbnailClickListener.onClick(v, slide); } }; @@ -86,10 +85,7 @@ public class AlbumThumbnailView extends FrameLayout { } showSlides(glideRequests, slides); - } - - public @Nullable Drawable getDrawable() { - return imageDrawable; + applyCorners(); } public void setCellBackgroundColor(@ColorInt int color) { @@ -110,6 +106,15 @@ public class AlbumThumbnailView extends FrameLayout { downloadClickListener = listener; } + public void setRadii(int topLeft, int topRight, int bottomRight, int bottomLeft) { + corners[0] = topLeft; + corners[1] = topRight; + corners[2] = bottomRight; + corners[3] = bottomLeft; + + applyCorners(); + } + private void inflateLayout(int sizeClass) { albumCellContainer.removeAllViews(); @@ -132,6 +137,73 @@ public class AlbumThumbnailView extends FrameLayout { } } + private void applyCorners() { + if (currentSizeClass < 2) { + return; + } + + switch (currentSizeClass) { + case 2: + applyCornersForSizeClass2(); + break; + case 3: + applyCornersForSizeClass3(); + break; + case 4: + applyCornersForSizeClass4(); + break; + case 5: + applyCornersForSizeClass5(); + break; + default: + applyCornersForManySizeClass(); + } + } + + private ThumbnailView[] getCells() { + ThumbnailView one = findViewById(R.id.album_cell_1); + ThumbnailView two = findViewById(R.id.album_cell_2); + ThumbnailView three = findViewById(R.id.album_cell_3); + ThumbnailView four = findViewById(R.id.album_cell_4); + ThumbnailView five = findViewById(R.id.album_cell_5); + + return new ThumbnailView[]{one, two, three, four, five}; + } + + private void applyCornersForSizeClass2() { + ThumbnailView[] cells = getCells(); + cells[0].setRadii(corners[0], 0, 0, corners[3]); + cells[1].setRadii(0, corners[1], corners[2], 0); + } + + private void applyCornersForSizeClass3() { + ThumbnailView[] cells = getCells(); + cells[0].setRadii(corners[0], 0, 0, corners[3]); + cells[1].setRadii(0, corners[1], 0, 0); + cells[2].setRadii(0, 0, corners[2], 0); + } + + private void applyCornersForSizeClass4() { + ThumbnailView[] cells = getCells(); + cells[0].setRadii(corners[0], 0, 0, 0); + cells[1].setRadii(0, corners[1], 0, 0); + cells[2].setRadii(0, 0, 0, corners[3]); + cells[3].setRadii(0, 0, corners[2], 0); + } + + private void applyCornersForSizeClass5() { + ThumbnailView[] cells = getCells(); + cells[0].setRadii(corners[0], 0, 0, 0); + cells[1].setRadii(0, corners[1], 0, 0); + cells[2].setRadii(0, 0, 0, corners[3]); + cells[3].setRadii(0, 0, 0, 0); + cells[4].setRadii(0, 0, corners[2], 0); + } + + private void applyCornersForManySizeClass() { + applyCornersForSizeClass5(); + } + private void showSlides(@NonNull GlideRequests glideRequests, @NonNull List slides) { setSlide(glideRequests, slides.get(0), R.id.album_cell_1); setSlide(glideRequests, slides.get(1), R.id.album_cell_2); diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/ConversationItemThumbnail.kt b/app/src/main/java/org/thoughtcrime/securesms/components/ConversationItemThumbnail.kt index 611c1172eb..b31fca8dc4 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/ConversationItemThumbnail.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/components/ConversationItemThumbnail.kt @@ -2,7 +2,6 @@ package org.thoughtcrime.securesms.components import android.content.Context import android.graphics.Canvas -import android.graphics.drawable.Drawable import android.os.Bundle import android.os.Parcelable import android.util.AttributeSet @@ -131,14 +130,6 @@ class ConversationItemThumbnail @JvmOverloads constructor( state.applyState(thumbnail, album) } - fun getDrawable(): Drawable? { - return if (thumbnail.resolved()) { - thumbnail.get().imageDrawable - } else { - album.get().drawable - } - } - fun hideThumbnailView() { state = state.copy(thumbnailViewState = state.thumbnailViewState.copy(alpha = 0f)) state.thumbnailViewState.applyState(thumbnail) @@ -159,6 +150,22 @@ class ConversationItemThumbnail @JvmOverloads constructor( fun setCorners(topLeft: Int, topRight: Int, bottomRight: Int, bottomLeft: Int) { cornerMask.setRadii(topLeft, topRight, bottomRight, bottomLeft) + state = state.copy( + thumbnailViewState = state.thumbnailViewState.copy( + cornerTopLeft = topLeft, + cornerTopRight = topRight, + cornerBottomRight = bottomRight, + cornerBottomLeft = bottomLeft + ), + albumViewState = state.albumViewState.copy( + cornerTopLeft = topLeft, + cornerTopRight = topRight, + cornerBottomRight = bottomRight, + cornerBottomLeft = bottomLeft + ) + ) + + state.applyState(thumbnail, album) } fun setMinimumThumbnailWidth(@Px width: Int) { diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/ConversationItemThumbnailState.kt b/app/src/main/java/org/thoughtcrime/securesms/components/ConversationItemThumbnailState.kt index f24823465a..8ecb30e3b7 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/ConversationItemThumbnailState.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/components/ConversationItemThumbnailState.kt @@ -11,7 +11,7 @@ import org.thoughtcrime.securesms.mms.SlidesClickedListener import org.thoughtcrime.securesms.util.views.Stub /** - * Parcelizable state object for [ConversationItemThumbnail] + * Parcelable state object for [ConversationItemThumbnail] * This allows us to manage inputs for [ThumbnailView] and [AlbumThumbnailView] without * actually having them inflated. When the views are finally inflated, we 'apply' */ @@ -38,7 +38,11 @@ data class ConversationItemThumbnailState( private val minWidth: Int = -1, private val maxWidth: Int = -1, private val minHeight: Int = -1, - private val maxHeight: Int = -1 + private val maxHeight: Int = -1, + private val cornerTopLeft: Int = 0, + private val cornerTopRight: Int = 0, + private val cornerBottomRight: Int = 0, + private val cornerBottomLeft: Int = 0 ) : Parcelable { fun applyState(thumbnailView: Stub) { @@ -50,6 +54,7 @@ data class ConversationItemThumbnailState( thumbnailView.get().alpha = alpha thumbnailView.get().isFocusable = focusable thumbnailView.get().isClickable = clickable + thumbnailView.get().setRadii(cornerTopLeft, cornerTopRight, cornerBottomRight, cornerBottomLeft) thumbnailView.get().setThumbnailClickListener(clickListener) thumbnailView.get().setDownloadClickListener(downloadClickListener) thumbnailView.get().setOnLongClickListener(longClickListener) @@ -70,7 +75,11 @@ data class ConversationItemThumbnailState( @IgnoredOnParcel private val longClickListener: OnLongClickListener? = null, private val visibility: Int = View.GONE, - private val cellBackgroundColor: Int = Color.TRANSPARENT + private val cellBackgroundColor: Int = Color.TRANSPARENT, + private val cornerTopLeft: Int = 0, + private val cornerTopRight: Int = 0, + private val cornerBottomRight: Int = 0, + private val cornerBottomLeft: Int = 0 ) : Parcelable { fun applyState(albumView: Stub) { @@ -81,6 +90,7 @@ data class ConversationItemThumbnailState( albumView.get().isFocusable = focusable albumView.get().isClickable = clickable + albumView.get().setRadii(cornerTopLeft, cornerTopRight, cornerBottomRight, cornerBottomLeft) albumView.get().setThumbnailClickListener(clickListener) albumView.get().setDownloadClickListener(downloadClickListener) albumView.get().setOnLongClickListener(longClickListener) diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/ThumbnailView.java b/app/src/main/java/org/thoughtcrime/securesms/components/ThumbnailView.java index ef2f8a14b4..a973daa9fa 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/ThumbnailView.java +++ b/app/src/main/java/org/thoughtcrime/securesms/components/ThumbnailView.java @@ -529,6 +529,11 @@ public class ThumbnailView extends FrameLayout { invalidate(); } + public void setRadii(int topLeft, int topRight, int bottomRight, int bottomLeft) { + cornerMask.setRadii(topLeft, topRight, bottomRight, bottomLeft); + invalidate(); + } + private GlideRequest buildThumbnailGlideRequest(@NonNull GlideRequests glideRequests, @NonNull Slide slide) { GlideRequest request = applySizing(glideRequests.load(new DecryptableUri(Objects.requireNonNull(slide.getUri()))) .diskCacheStrategy(DiskCacheStrategy.RESOURCE) diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationItem.java b/app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationItem.java index c7618e3b09..072ca24a3e 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationItem.java +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationItem.java @@ -87,6 +87,7 @@ import org.thoughtcrime.securesms.components.Outliner; import org.thoughtcrime.securesms.components.PlaybackSpeedToggleTextView; import org.thoughtcrime.securesms.components.QuoteView; import org.thoughtcrime.securesms.components.SharedContactView; +import org.thoughtcrime.securesms.components.ThumbnailView; import org.thoughtcrime.securesms.components.emoji.EmojiTextView; import org.thoughtcrime.securesms.components.mention.MentionAnnotation; import org.thoughtcrime.securesms.contactshare.Contact; @@ -2393,8 +2394,8 @@ public final class ConversationItem extends RelativeLayout implements BindableCo mediaThumbnailStub.require().getCorners().getBottomRight(), mediaThumbnailStub.require().getCorners().getBottomLeft() )); - MediaPreviewCache.INSTANCE.setDrawable(mediaThumbnailStub.require().getDrawable()); - eventListener.goToMediaPreview(ConversationItem.this, mediaThumbnailStub.require(), args); + MediaPreviewCache.INSTANCE.setDrawable(((ThumbnailView) v).getImageDrawable()); + eventListener.goToMediaPreview(ConversationItem.this, v, args); } else if (slide.getUri() != null) { Log.i(TAG, "Clicked: " + slide.getUri() + " , " + slide.getContentType()); Uri publicUri = PartAuthority.getAttachmentPublicUri(slide.getUri());