Link cards
This commit is contained in:
@@ -16,6 +16,8 @@ public class Card extends BaseModel{
|
||||
@RequiredField
|
||||
public String url;
|
||||
@RequiredField
|
||||
public String title;
|
||||
@RequiredField
|
||||
public String description;
|
||||
@RequiredField
|
||||
public Type type;
|
||||
@@ -46,6 +48,7 @@ public class Card extends BaseModel{
|
||||
public String toString(){
|
||||
return "Card{"+
|
||||
"url='"+url+'\''+
|
||||
", title='"+title+'\''+
|
||||
", description='"+description+'\''+
|
||||
", type="+type+
|
||||
", authorName='"+authorName+'\''+
|
||||
|
||||
@@ -0,0 +1,101 @@
|
||||
package org.joinmastodon.android.ui.displayitems;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.net.Uri;
|
||||
import android.text.TextUtils;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
|
||||
import org.joinmastodon.android.R;
|
||||
import org.joinmastodon.android.fragments.BaseStatusListFragment;
|
||||
import org.joinmastodon.android.model.Card;
|
||||
import org.joinmastodon.android.model.Status;
|
||||
import org.joinmastodon.android.ui.drawables.BlurhashCrossfadeDrawable;
|
||||
import org.joinmastodon.android.ui.utils.UiUtils;
|
||||
|
||||
import me.grishka.appkit.imageloader.ImageLoaderViewHolder;
|
||||
import me.grishka.appkit.imageloader.requests.ImageLoaderRequest;
|
||||
import me.grishka.appkit.imageloader.requests.UrlImageLoaderRequest;
|
||||
|
||||
public class LinkCardStatusDisplayItem extends StatusDisplayItem{
|
||||
private final Status status;
|
||||
private final UrlImageLoaderRequest imgRequest;
|
||||
|
||||
public LinkCardStatusDisplayItem(String parentID, BaseStatusListFragment parentFragment, Status status){
|
||||
super(parentID, parentFragment);
|
||||
this.status=status;
|
||||
if(status.card.image!=null)
|
||||
imgRequest=new UrlImageLoaderRequest(status.card.image, 1000, 1000);
|
||||
else
|
||||
imgRequest=null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Type getType(){
|
||||
return Type.CARD;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getImageCount(){
|
||||
return imgRequest==null ? 0 : 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ImageLoaderRequest getImageRequest(int index){
|
||||
return imgRequest;
|
||||
}
|
||||
|
||||
public static class Holder extends StatusDisplayItem.Holder<LinkCardStatusDisplayItem> implements ImageLoaderViewHolder{
|
||||
private final TextView title, description, domain;
|
||||
private final ImageView photo;
|
||||
private BlurhashCrossfadeDrawable crossfadeDrawable=new BlurhashCrossfadeDrawable();
|
||||
private boolean didClear;
|
||||
|
||||
public Holder(Context context, ViewGroup parent){
|
||||
super(context, R.layout.display_item_link_card, parent);
|
||||
title=findViewById(R.id.title);
|
||||
description=findViewById(R.id.description);
|
||||
domain=findViewById(R.id.domain);
|
||||
photo=findViewById(R.id.photo);
|
||||
findViewById(R.id.inner).setOnClickListener(this::onClick);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBind(LinkCardStatusDisplayItem item){
|
||||
Card card=item.status.card;
|
||||
title.setText(card.title);
|
||||
description.setText(card.description);
|
||||
description.setVisibility(TextUtils.isEmpty(card.description) ? View.GONE : View.VISIBLE);
|
||||
domain.setText(Uri.parse(card.url).getHost());
|
||||
|
||||
photo.setImageDrawable(null);
|
||||
if(item.imgRequest!=null){
|
||||
crossfadeDrawable.setSize(card.width, card.height);
|
||||
crossfadeDrawable.setBlurhashDrawable(card.blurhashPlaceholder);
|
||||
crossfadeDrawable.setCrossfadeAlpha(item.status.spoilerRevealed ? 0f : 1f);
|
||||
photo.setImageDrawable(crossfadeDrawable);
|
||||
didClear=false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setImage(int index, Drawable drawable){
|
||||
crossfadeDrawable.setImageDrawable(drawable);
|
||||
if(didClear && item.status.spoilerRevealed)
|
||||
crossfadeDrawable.animateAlpha(0f);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clearImage(int index){
|
||||
crossfadeDrawable.setCrossfadeAlpha(1f);
|
||||
didClear=true;
|
||||
}
|
||||
|
||||
private void onClick(View v){
|
||||
UiUtils.launchWebBrowser(itemView.getContext(), item.status.card.url);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -55,6 +55,7 @@ public abstract class StatusDisplayItem{
|
||||
case VIDEO -> new VideoStatusDisplayItem.Holder(activity, parent);
|
||||
case POLL_OPTION -> new PollOptionStatusDisplayItem.Holder(activity, parent);
|
||||
case POLL_FOOTER -> new PollFooterStatusDisplayItem.Holder(activity, parent);
|
||||
case CARD -> new LinkCardStatusDisplayItem.Holder(activity, parent);
|
||||
case FOOTER -> new FooterStatusDisplayItem.Holder(activity, parent);
|
||||
default -> throw new UnsupportedOperationException();
|
||||
};
|
||||
@@ -96,6 +97,9 @@ public abstract class StatusDisplayItem{
|
||||
if(statusForContent.poll!=null){
|
||||
buildPollItems(parentID, fragment, statusForContent.poll, items);
|
||||
}
|
||||
if(statusForContent.card!=null){
|
||||
items.add(new LinkCardStatusDisplayItem(parentID, fragment, statusForContent));
|
||||
}
|
||||
items.add(new FooterStatusDisplayItem(parentID, fragment, statusForContent, accountID));
|
||||
return items;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
package org.joinmastodon.android.ui.views;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.TypedArray;
|
||||
import android.util.AttributeSet;
|
||||
import android.widget.FrameLayout;
|
||||
|
||||
import org.joinmastodon.android.R;
|
||||
|
||||
public class MaxWidthFrameLayout extends FrameLayout{
|
||||
private int maxWidth;
|
||||
|
||||
public MaxWidthFrameLayout(Context context){
|
||||
this(context, null);
|
||||
}
|
||||
|
||||
public MaxWidthFrameLayout(Context context, AttributeSet attrs){
|
||||
this(context, attrs, 0);
|
||||
}
|
||||
|
||||
public MaxWidthFrameLayout(Context context, AttributeSet attrs, int defStyle){
|
||||
super(context, attrs, defStyle);
|
||||
TypedArray ta=context.obtainStyledAttributes(attrs, R.styleable.MaxWidthFrameLayout);
|
||||
maxWidth=ta.getDimensionPixelSize(R.styleable.MaxWidthFrameLayout_android_maxWidth, Integer.MAX_VALUE);
|
||||
ta.recycle();
|
||||
}
|
||||
|
||||
public int getMaxWidth(){
|
||||
return maxWidth;
|
||||
}
|
||||
|
||||
public void setMaxWidth(int maxWidth){
|
||||
this.maxWidth=maxWidth;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec){
|
||||
if(MeasureSpec.getSize(widthMeasureSpec)>maxWidth){
|
||||
widthMeasureSpec=maxWidth | MeasureSpec.getMode(widthMeasureSpec);
|
||||
}
|
||||
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
|
||||
}
|
||||
}
|
||||
@@ -43,7 +43,7 @@ public class TabBar extends LinearLayout{
|
||||
}
|
||||
|
||||
private void onChildClick(View v){
|
||||
listener.accept(selectedTabID);
|
||||
listener.accept(v.getId());
|
||||
if(v.getId()==selectedTabID)
|
||||
return;
|
||||
findViewById(selectedTabID).setSelected(false);
|
||||
|
||||
Reference in New Issue
Block a user