Fix rendering of link preview images (#2743)

* fix link previews in timelines rendering images incorrectly

* fix ripple effect when clicking on cards

* remove unnecessary line of code
This commit is contained in:
Konrad Pozniak 2022-11-04 19:22:53 +01:00 committed by GitHub
parent d17a0c43ab
commit f870445b54
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 46 additions and 34 deletions

View file

@ -29,9 +29,10 @@ import androidx.recyclerview.widget.RecyclerView;
import com.bumptech.glide.Glide; import com.bumptech.glide.Glide;
import com.bumptech.glide.RequestBuilder; import com.bumptech.glide.RequestBuilder;
import com.bumptech.glide.load.resource.bitmap.CenterCrop;
import com.bumptech.glide.load.resource.bitmap.GranularRoundedCorners;
import com.google.android.material.button.MaterialButton; import com.google.android.material.button.MaterialButton;
import com.google.android.material.imageview.ShapeableImageView;
import com.google.android.material.shape.CornerFamily;
import com.google.android.material.shape.ShapeAppearanceModel;
import com.keylesspalace.tusky.R; import com.keylesspalace.tusky.R;
import com.keylesspalace.tusky.ViewMediaActivity; import com.keylesspalace.tusky.ViewMediaActivity;
import com.keylesspalace.tusky.entity.Attachment; import com.keylesspalace.tusky.entity.Attachment;
@ -100,7 +101,7 @@ public abstract class StatusBaseViewHolder extends RecyclerView.ViewHolder {
private LinearLayout cardView; private LinearLayout cardView;
private LinearLayout cardInfo; private LinearLayout cardInfo;
private ImageView cardImage; private ShapeableImageView cardImage;
private TextView cardTitle; private TextView cardTitle;
private TextView cardDescription; private TextView cardDescription;
private TextView cardUrl; private TextView cardUrl;
@ -1056,13 +1057,9 @@ public abstract class StatusBaseViewHolder extends RecyclerView.ViewHolder {
// If media previews are disabled, show placeholder for cards as well // If media previews are disabled, show placeholder for cards as well
if (statusDisplayOptions.mediaPreviewEnabled() && !actionable.getSensitive() && !TextUtils.isEmpty(card.getImage())) { if (statusDisplayOptions.mediaPreviewEnabled() && !actionable.getSensitive() && !TextUtils.isEmpty(card.getImage())) {
int topLeftRadius = 0;
int topRightRadius = 0;
int bottomRightRadius = 0;
int bottomLeftRadius = 0;
int radius = cardImage.getContext().getResources() int radius = cardImage.getContext().getResources()
.getDimensionPixelSize(R.dimen.card_radius); .getDimensionPixelSize(R.dimen.card_radius);
ShapeAppearanceModel.Builder cardImageShape = ShapeAppearanceModel.builder();
if (card.getWidth() > card.getHeight()) { if (card.getWidth() > card.getHeight()) {
cardView.setOrientation(LinearLayout.VERTICAL); cardView.setOrientation(LinearLayout.VERTICAL);
@ -1072,8 +1069,8 @@ public abstract class StatusBaseViewHolder extends RecyclerView.ViewHolder {
cardImage.getLayoutParams().width = ViewGroup.LayoutParams.MATCH_PARENT; cardImage.getLayoutParams().width = ViewGroup.LayoutParams.MATCH_PARENT;
cardInfo.getLayoutParams().height = ViewGroup.LayoutParams.MATCH_PARENT; cardInfo.getLayoutParams().height = ViewGroup.LayoutParams.MATCH_PARENT;
cardInfo.getLayoutParams().width = ViewGroup.LayoutParams.WRAP_CONTENT; cardInfo.getLayoutParams().width = ViewGroup.LayoutParams.WRAP_CONTENT;
topLeftRadius = radius; cardImageShape.setTopLeftCorner(CornerFamily.ROUNDED, radius);
topRightRadius = radius; cardImageShape.setTopRightCorner(CornerFamily.ROUNDED, radius);
} else { } else {
cardView.setOrientation(LinearLayout.HORIZONTAL); cardView.setOrientation(LinearLayout.HORIZONTAL);
cardImage.getLayoutParams().height = ViewGroup.LayoutParams.MATCH_PARENT; cardImage.getLayoutParams().height = ViewGroup.LayoutParams.MATCH_PARENT;
@ -1081,19 +1078,21 @@ public abstract class StatusBaseViewHolder extends RecyclerView.ViewHolder {
.getDimensionPixelSize(R.dimen.card_image_horizontal_width); .getDimensionPixelSize(R.dimen.card_image_horizontal_width);
cardInfo.getLayoutParams().height = ViewGroup.LayoutParams.WRAP_CONTENT; cardInfo.getLayoutParams().height = ViewGroup.LayoutParams.WRAP_CONTENT;
cardInfo.getLayoutParams().width = ViewGroup.LayoutParams.MATCH_PARENT; cardInfo.getLayoutParams().width = ViewGroup.LayoutParams.MATCH_PARENT;
topLeftRadius = radius; cardImageShape.setTopLeftCorner(CornerFamily.ROUNDED, radius);
bottomLeftRadius = radius; cardImageShape.setBottomLeftCorner(CornerFamily.ROUNDED, radius);
} }
RequestBuilder<Drawable> builder = Glide.with(cardImage).load(card.getImage()); cardImage.setShapeAppearanceModel(cardImageShape.build());
cardImage.setScaleType(ImageView.ScaleType.CENTER_CROP);
RequestBuilder<Drawable> builder = Glide.with(cardImage.getContext())
.load(card.getImage())
.dontTransform();
if (statusDisplayOptions.useBlurhash() && !TextUtils.isEmpty(card.getBlurhash())) { if (statusDisplayOptions.useBlurhash() && !TextUtils.isEmpty(card.getBlurhash())) {
builder = builder.placeholder(decodeBlurHash(card.getBlurhash())); builder = builder.placeholder(decodeBlurHash(card.getBlurhash()));
} }
builder.transform( builder.into(cardImage);
new CenterCrop(),
new GranularRoundedCorners(topLeftRadius, topRightRadius, bottomRightRadius, bottomLeftRadius)
)
.into(cardImage);
} else if (statusDisplayOptions.useBlurhash() && !TextUtils.isEmpty(card.getBlurhash())) { } else if (statusDisplayOptions.useBlurhash() && !TextUtils.isEmpty(card.getBlurhash())) {
int radius = cardImage.getContext().getResources() int radius = cardImage.getContext().getResources()
.getDimensionPixelSize(R.dimen.card_radius); .getDimensionPixelSize(R.dimen.card_radius);
@ -1104,11 +1103,18 @@ public abstract class StatusBaseViewHolder extends RecyclerView.ViewHolder {
.getDimensionPixelSize(R.dimen.card_image_horizontal_width); .getDimensionPixelSize(R.dimen.card_image_horizontal_width);
cardInfo.getLayoutParams().height = ViewGroup.LayoutParams.WRAP_CONTENT; cardInfo.getLayoutParams().height = ViewGroup.LayoutParams.WRAP_CONTENT;
cardInfo.getLayoutParams().width = ViewGroup.LayoutParams.MATCH_PARENT; cardInfo.getLayoutParams().width = ViewGroup.LayoutParams.MATCH_PARENT;
Glide.with(cardImage).load(decodeBlurHash(card.getBlurhash()))
.transform( ShapeAppearanceModel cardImageShape = ShapeAppearanceModel.builder()
new CenterCrop(), .setTopLeftCorner(CornerFamily.ROUNDED, radius)
new GranularRoundedCorners(radius, 0, 0, radius) .setBottomLeftCorner(CornerFamily.ROUNDED, radius)
) .build();
cardImage.setShapeAppearanceModel(cardImageShape);
cardImage.setScaleType(ImageView.ScaleType.CENTER_CROP);
Glide.with(cardImage.getContext())
.load(decodeBlurHash(card.getBlurhash()))
.dontTransform()
.into(cardImage); .into(cardImage);
} else { } else {
cardView.setOrientation(LinearLayout.HORIZONTAL); cardView.setOrientation(LinearLayout.HORIZONTAL);
@ -1117,16 +1123,22 @@ public abstract class StatusBaseViewHolder extends RecyclerView.ViewHolder {
.getDimensionPixelSize(R.dimen.card_image_horizontal_width); .getDimensionPixelSize(R.dimen.card_image_horizontal_width);
cardInfo.getLayoutParams().height = ViewGroup.LayoutParams.WRAP_CONTENT; cardInfo.getLayoutParams().height = ViewGroup.LayoutParams.WRAP_CONTENT;
cardInfo.getLayoutParams().width = ViewGroup.LayoutParams.MATCH_PARENT; cardInfo.getLayoutParams().width = ViewGroup.LayoutParams.MATCH_PARENT;
cardImage.setImageResource(R.drawable.card_image_placeholder);
cardImage.setShapeAppearanceModel(new ShapeAppearanceModel());
cardImage.setScaleType(ImageView.ScaleType.CENTER);
Glide.with(cardImage.getContext())
.load(ContextCompat.getDrawable(cardImage.getContext(), R.drawable.card_image_placeholder))
.into(cardImage);
} }
View.OnClickListener visitLink = v -> listener.onViewUrl(card.getUrl()); View.OnClickListener visitLink = v -> listener.onViewUrl(card.getUrl());
View.OnClickListener openImage = v -> cardView.getContext().startActivity(ViewMediaActivity.newSingleImageIntent(cardView.getContext(), card.getEmbed_url()));
cardInfo.setOnClickListener(visitLink); cardView.setOnClickListener(visitLink);
// View embedded photos in our image viewer instead of opening the browser // View embedded photos in our image viewer instead of opening the browser
cardImage.setOnClickListener(card.getType().equals(Card.TYPE_PHOTO) && !TextUtils.isEmpty(card.getEmbed_url()) ? cardImage.setOnClickListener(card.getType().equals(Card.TYPE_PHOTO) && !TextUtils.isEmpty(card.getEmbedUrl()) ?
openImage : v -> cardView.getContext().startActivity(ViewMediaActivity.newSingleImageIntent(cardView.getContext(), card.getEmbedUrl())) :
visitLink); visitLink);
cardView.setClipToOutline(true); cardView.setClipToOutline(true);

View file

@ -27,7 +27,7 @@ data class Card(
val width: Int, val width: Int,
val height: Int, val height: Int,
val blurhash: String?, val blurhash: String?,
val embed_url: String? @SerializedName("embed_url") val embedUrl: String?
) { ) {
override fun hashCode() = url.hashCode() override fun hashCode() = url.hashCode()

View file

@ -172,7 +172,7 @@
app:layout_constraintTop_toBottomOf="@+id/button_toggle_content" app:layout_constraintTop_toBottomOf="@+id/button_toggle_content"
tools:visibility="gone"> tools:visibility="gone">
<ImageView <com.google.android.material.imageview.ShapeableImageView
android:id="@+id/card_image" android:id="@+id/card_image"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="300dp" android:layout_height="300dp"

View file

@ -144,7 +144,7 @@
app:layout_constraintTop_toBottomOf="@+id/status_content" app:layout_constraintTop_toBottomOf="@+id/status_content"
tools:visibility="gone"> tools:visibility="gone">
<ImageView <com.google.android.material.imageview.ShapeableImageView
android:id="@+id/card_image" android:id="@+id/card_image"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="300dp" android:layout_height="300dp"