Improve link preview cards (#1330)

* improve card frame

* add placeholder for empty image

* improve layout, Pleroma compatibility, show author name as description fallback

* reset okhttp logging level

* remove unneeded statement
This commit is contained in:
Konrad Pozniak 2019-06-22 08:05:55 +02:00 committed by GitHub
parent e6d91c1cf3
commit b825f42c7a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 69 additions and 31 deletions

View File

@ -154,6 +154,7 @@ dependencies {
//Glide //Glide
implementation 'com.github.bumptech.glide:glide:4.9.0' implementation 'com.github.bumptech.glide:glide:4.9.0'
implementation 'com.github.bumptech.glide:okhttp3-integration:4.9.0' implementation 'com.github.bumptech.glide:okhttp3-integration:4.9.0'
implementation 'jp.wasabeef:glide-transformations:4.0.1'
//Add some useful extensions //Add some useful extensions
implementation 'androidx.core:core-ktx:1.2.0-alpha01' implementation 'androidx.core:core-ktx:1.2.0-alpha01'

View File

@ -17,6 +17,7 @@ import android.widget.TextView;
import android.widget.Toast; import android.widget.Toast;
import com.bumptech.glide.Glide; import com.bumptech.glide.Glide;
import com.bumptech.glide.load.resource.bitmap.CenterCrop;
import com.keylesspalace.tusky.R; import com.keylesspalace.tusky.R;
import com.keylesspalace.tusky.entity.Card; import com.keylesspalace.tusky.entity.Card;
import com.keylesspalace.tusky.entity.Status; import com.keylesspalace.tusky.entity.Status;
@ -31,6 +32,8 @@ import java.util.Date;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.recyclerview.widget.RecyclerView; import androidx.recyclerview.widget.RecyclerView;
import jp.wasabeef.glide.transformations.RoundedCornersTransformation;
class StatusDetailedViewHolder extends StatusBaseViewHolder { class StatusDetailedViewHolder extends StatusBaseViewHolder {
private TextView reblogs; private TextView reblogs;
private TextView favourites; private TextView favourites;
@ -152,20 +155,32 @@ class StatusDetailedViewHolder extends StatusBaseViewHolder {
final Card card = status.getCard(); final Card card = status.getCard();
cardView.setVisibility(View.VISIBLE); cardView.setVisibility(View.VISIBLE);
cardTitle.setText(card.getTitle()); cardTitle.setText(card.getTitle());
cardDescription.setText(card.getDescription()); if(TextUtils.isEmpty(card.getDescription()) && TextUtils.isEmpty(card.getAuthorName())) {
cardDescription.setVisibility(View.GONE);
} else {
cardDescription.setVisibility(View.VISIBLE);
if(TextUtils.isEmpty(card.getDescription())) {
cardDescription.setText(card.getAuthorName());
} else {
cardDescription.setText(card.getDescription());
}
}
cardUrl.setText(card.getUrl()); cardUrl.setText(card.getUrl());
if (card.getWidth() > 0 && card.getHeight() > 0 && !TextUtils.isEmpty(card.getImage())) { if (!TextUtils.isEmpty(card.getImage())) {
cardImage.setVisibility(View.VISIBLE);
RoundedCornersTransformation.CornerType cornertype;
if (card.getWidth() > card.getHeight()) { if (card.getWidth() > card.getHeight()) {
cardView.setOrientation(LinearLayout.VERTICAL); cardView.setOrientation(LinearLayout.VERTICAL);
cardImage.getLayoutParams().height = cardImage.getContext().getResources() cardImage.getLayoutParams().height = cardImage.getContext().getResources()
.getDimensionPixelSize(R.dimen.card_image_vertical_height); .getDimensionPixelSize(R.dimen.card_image_vertical_height);
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;
cornertype = RoundedCornersTransformation.CornerType.TOP;
} else { } else {
cardView.setOrientation(LinearLayout.HORIZONTAL); cardView.setOrientation(LinearLayout.HORIZONTAL);
cardImage.getLayoutParams().height = ViewGroup.LayoutParams.MATCH_PARENT; cardImage.getLayoutParams().height = ViewGroup.LayoutParams.MATCH_PARENT;
@ -173,17 +188,28 @@ class StatusDetailedViewHolder extends StatusBaseViewHolder {
.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;
cornertype = RoundedCornersTransformation.CornerType.LEFT;
} }
cardView.setClipToOutline(true); int radius = cardImage.getContext().getResources()
.getDimensionPixelSize(R.dimen.card_radius);
cardView.setClipToOutline(true);
Glide.with(cardImage) Glide.with(cardImage)
.load(card.getImage()) .load(card.getImage())
.centerCrop() .transform(new CenterCrop(), new RoundedCornersTransformation(radius, 0, cornertype))
.into(cardImage); .into(cardImage);
} else { } else {
cardImage.setVisibility(View.GONE); cardView.setOrientation(LinearLayout.HORIZONTAL);
cardImage.getLayoutParams().height = ViewGroup.LayoutParams.MATCH_PARENT;
cardImage.getLayoutParams().width = cardImage.getContext().getResources()
.getDimensionPixelSize(R.dimen.card_image_horizontal_width);
cardInfo.getLayoutParams().height = ViewGroup.LayoutParams.WRAP_CONTENT;
cardInfo.getLayoutParams().width = ViewGroup.LayoutParams.MATCH_PARENT;
cardImage.setImageResource(R.drawable.card_image_placeholder);
} }
cardView.setOnClickListener(v -> LinkHelper.openLink(card.getUrl(), v.getContext())); cardView.setOnClickListener(v -> LinkHelper.openLink(card.getUrl(), v.getContext()));

View File

@ -16,13 +16,17 @@
package com.keylesspalace.tusky.entity package com.keylesspalace.tusky.entity
import android.os.Parcelable import android.os.Parcelable
import android.text.Spanned
import com.google.gson.annotations.SerializedName
import kotlinx.android.parcel.Parcelize import kotlinx.android.parcel.Parcelize
import kotlinx.android.parcel.WriteWith
@Parcelize @Parcelize
data class Card( data class Card(
val url: String, val url: String,
val title: String, val title: @WriteWith<SpannedParceler>() Spanned,
val description: String, val description: @WriteWith<SpannedParceler>() Spanned,
@SerializedName("author_name") val authorName: String,
val image: String, val image: String,
val type: String, val type: String,
val width: Int, val width: Int,

View File

@ -130,7 +130,7 @@ data class Status(
data class Application ( data class Application (
val name: String, val name: String,
val website: String val website: String?
) )
companion object { companion object {

View File

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<corners android:radius="6dp" />
<stroke android:color="?attr/card_background_color" android:width="1dp" />
</shape>

View File

@ -1,6 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<corners android:radius="5dp" />
<stroke android:color="@color/text_color_tertiary_dark" android:width="1px" />
<padding android:bottom="1px" android:top="1px" android:left="1px" android:right="1px"/>
</shape>

View File

@ -1,6 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<corners android:radius="5dp" />
<stroke android:color="@color/text_color_tertiary_light" android:width="1px" />
<padding android:bottom="1px" android:top="1px" android:left="1px" android:right="1px"/>
</shape>

View File

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="48dp"
android:height="48dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="?android:attr/textColorTertiary"
android:pathData="M6,2A2,2 0 0,0 4,4V20A2,2 0 0,0 6,22H18A2,2 0 0,0 20,20V8L14,2H6M6,4H13V9H18V20H6V4M8,12V14H16V12H8M8,16V18H13V16H8Z" />
</vector>

View File

@ -134,8 +134,10 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="8dp" android:layout_marginTop="8dp"
android:background="?attr/card_background" android:background="@drawable/card_frame"
android:clipChildren="true" android:clipChildren="true"
android:foreground="?attr/selectableItemBackground"
android:minHeight="80dp"
android:orientation="vertical" android:orientation="vertical"
app:layout_constraintTop_toBottomOf="@+id/status_content" app:layout_constraintTop_toBottomOf="@+id/status_content"
tools:visibility="gone"> tools:visibility="gone">
@ -144,7 +146,10 @@
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"
android:background="?attr/card_image_background" /> android:layout_margin="1dp"
android:background="?attr/card_background_color"
android:importantForAccessibility="no"
android:scaleType="center" />
<LinearLayout <LinearLayout
android:id="@+id/card_info" android:id="@+id/card_info"
@ -164,7 +169,7 @@
android:ellipsize="end" android:ellipsize="end"
android:fontFamily="sans-serif-medium" android:fontFamily="sans-serif-medium"
android:lines="1" android:lines="1"
android:textColor="?android:textColorPrimary" android:textColor="?android:textColorSecondary"
android:textSize="?attr/status_text_medium" /> android:textSize="?attr/status_text_medium" />
<androidx.emoji.widget.EmojiTextView <androidx.emoji.widget.EmojiTextView

View File

@ -65,8 +65,7 @@
<item name="material_drawer_header_selection_text">@color/text_color_primary_dark</item> <item name="material_drawer_header_selection_text">@color/text_color_primary_dark</item>
<item name="material_drawer_header_selection_subtext">@color/text_color_secondary_dark</item> <item name="material_drawer_header_selection_subtext">@color/text_color_secondary_dark</item>
<item name="card_background">@drawable/card_frame_dark</item> <item name="card_background_color">@color/color_primary_dark</item>
<item name="card_image_background">@color/text_color_tertiary_dark</item>
<item name="play_indicator_drawable">@drawable/ic_play_indicator_dark</item> <item name="play_indicator_drawable">@drawable/ic_play_indicator_dark</item>

View File

@ -35,8 +35,7 @@
<attr name="compose_content_warning_bar_background" format="reference" /> <attr name="compose_content_warning_bar_background" format="reference" />
<attr name="compose_reply_content_background" format="reference|color" /> <attr name="compose_reply_content_background" format="reference|color" />
<attr name="report_status_background_color" format="reference|color" /> <attr name="report_status_background_color" format="reference|color" />
<attr name="card_background" format="reference|color" /> <attr name="card_background_color" format="reference|color" />
<attr name="card_image_background" format="reference|color" />
<attr name="compound_button_color" format="reference" /> <attr name="compound_button_color" format="reference" />
<attr name="autocomplete_divider_drawable" format="reference" /> <attr name="autocomplete_divider_drawable" format="reference" />

View File

@ -14,7 +14,7 @@
<dimen name="text_content_margin">16dp</dimen> <dimen name="text_content_margin">16dp</dimen>
<dimen name="status_sensitive_media_button_padding">5dp</dimen> <dimen name="status_sensitive_media_button_padding">5dp</dimen>
<dimen name="card_image_vertical_height">160dp</dimen> <dimen name="card_image_vertical_height">210dp</dimen>
<dimen name="card_image_horizontal_width">100dp</dimen> <dimen name="card_image_horizontal_width">100dp</dimen>
<dimen name="compose_activity_snackbar_elevation">16dp</dimen> <dimen name="compose_activity_snackbar_elevation">16dp</dimen>
@ -40,4 +40,6 @@
<dimen name="avatar_radius_36dp">4.5dp</dimen> <!-- 1/8 of 36dp --> <dimen name="avatar_radius_36dp">4.5dp</dimen> <!-- 1/8 of 36dp -->
<dimen name="avatar_radius_24dp">3dp</dimen> <!-- 1/8 of 24dp --> <dimen name="avatar_radius_24dp">3dp</dimen> <!-- 1/8 of 24dp -->
<dimen name="min_report_button_width">160dp</dimen> <dimen name="min_report_button_width">160dp</dimen>
<dimen name="card_radius">5dp</dimen>
</resources> </resources>

View File

@ -125,8 +125,7 @@
<item name="material_drawer_header_selection_subtext">@color/text_color_secondary_dark <item name="material_drawer_header_selection_subtext">@color/text_color_secondary_dark
</item> <!--Intentionally dark so it can be overlayed over the account's header image.--> </item> <!--Intentionally dark so it can be overlayed over the account's header image.-->
<item name="card_background">@drawable/card_frame_light</item> <item name="card_background_color">@color/color_primary_light</item>
<item name="card_image_background">@color/text_color_tertiary_light</item>
<item name="play_indicator_drawable">@drawable/ic_play_indicator_light</item> <item name="play_indicator_drawable">@drawable/ic_play_indicator_light</item>