Skip to content

Commit

Permalink
Polish thumbnail animation.
Browse files Browse the repository at this point in the history
  • Loading branch information
alex-signal authored and greyson-signal committed Feb 14, 2023
1 parent 417db23 commit c027203
Show file tree
Hide file tree
Showing 5 changed files with 117 additions and 22 deletions.
Original file line number Diff line number Diff line change
@@ -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;
Expand All @@ -29,13 +28,13 @@ public class AlbumThumbnailView extends FrameLayout {

private int currentSizeClass;

private final int[] corners = new int[4];

private ViewGroup albumCellContainer;
private Stub<TransferControlView> transferControls;
private Drawable imageDrawable;

private final SlideClickListener defaultThumbnailClickListener = (v, slide) -> {
if (thumbnailClickListener != null) {
imageDrawable = ((ThumbnailView) v).getImageDrawable();
thumbnailClickListener.onClick(v, slide);
}
};
Expand Down Expand Up @@ -86,10 +85,7 @@ public void setSlides(@NonNull GlideRequests glideRequests, @NonNull List<Slide>
}

showSlides(glideRequests, slides);
}

public @Nullable Drawable getDrawable() {
return imageDrawable;
applyCorners();
}

public void setCellBackgroundColor(@ColorInt int color) {
Expand All @@ -110,6 +106,15 @@ public void setDownloadClickListener(@Nullable SlidesClickedListener listener) {
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();

Expand All @@ -132,6 +137,73 @@ private void inflateLayout(int sizeClass) {
}
}

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<Slide> slides) {
setSlide(glideRequests, slides.get(0), R.id.album_cell_1);
setSlide(glideRequests, slides.get(1), R.id.album_cell_2);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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)
Expand All @@ -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) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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'
*/
Expand All @@ -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<ThumbnailView>) {
Expand All @@ -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)
Expand All @@ -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<AlbumThumbnailView>) {
Expand All @@ -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)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -529,6 +529,11 @@ protected void setRadius(int radius) {
invalidate();
}

public void setRadii(int topLeft, int topRight, int bottomRight, int bottomLeft) {
cornerMask.setRadii(topLeft, topRight, bottomRight, bottomLeft);
invalidate();
}

private GlideRequest<Drawable> buildThumbnailGlideRequest(@NonNull GlideRequests glideRequests, @NonNull Slide slide) {
GlideRequest<Drawable> request = applySizing(glideRequests.load(new DecryptableUri(Objects.requireNonNull(slide.getUri())))
.diskCacheStrategy(DiskCacheStrategy.RESOURCE)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@
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;
Expand Down Expand Up @@ -2393,8 +2394,8 @@ public void onClick(final View v, final Slide slide) {
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());
Expand Down

0 comments on commit c027203

Please sign in to comment.