package ml.puredark.hviewer.ui.adapters;
import android.content.Context;
import android.graphics.drawable.Animatable;
import android.graphics.drawable.BitmapDrawable;
import android.support.annotation.Nullable;
import android.support.v7.widget.OrientationHelper;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.StaggeredGridLayoutManager;
import android.text.Html;
import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.RatingBar;
import android.widget.RelativeLayout;
import android.widget.TextView;
import com.balysv.materialripple.MaterialRippleLayout;
import com.facebook.common.logging.FLog;
import com.facebook.drawee.controller.BaseControllerListener;
import com.facebook.drawee.view.SimpleDraweeView;
import com.facebook.imagepipeline.image.ImageInfo;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import butterknife.BindView;
import butterknife.ButterKnife;
import ml.puredark.hviewer.R;
import ml.puredark.hviewer.beans.Collection;
import ml.puredark.hviewer.beans.LocalCollection;
import ml.puredark.hviewer.beans.Site;
import ml.puredark.hviewer.dataholders.SiteTagHolder;
import ml.puredark.hviewer.helpers.Logger;
import ml.puredark.hviewer.helpers.SiteFlagHandler;
import ml.puredark.hviewer.http.ImageLoader;
import ml.puredark.hviewer.http.ImageSizeInputStreamProvider;
import ml.puredark.hviewer.ui.dataproviders.ListDataProvider;
import ml.puredark.hviewer.utils.DensityUtil;
import q.rorbin.fastimagesize.FastImageSize;
public class CollectionAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
public final static int TYPE_LIST = 1;
public final static int TYPE_GRID = 2;
public final static int TYPE_WATERFALL = 3;
private Context context;
private ListDataProvider<Collection> mProvider;
private OnItemClickListener mItemClickListener;
private CollectionTagAdapter.OnItemClickListener mTagClickListener;
private Site site;
private boolean isGrid = false;
private boolean waterfallAsList = false;
private boolean waterfallAsGrid = false;
private SiteTagHolder siteTagHolder;
private Map<Collection, Integer> storedHeights = new HashMap<>();
public CollectionAdapter(Context context, ListDataProvider<Collection> mProvider, SiteTagHolder siteTagHolder) {
this.mProvider = mProvider;
setHasStableIds(false);
this.context = context;
this.siteTagHolder = siteTagHolder;
}
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
if (viewType == TYPE_LIST) {
View v = LayoutInflater.from(parent.getContext())
.inflate(R.layout.item_collection, parent, false);
RecyclerView.ViewHolder vh = new CollectionViewHolder(v);
return vh;
} else if (viewType == TYPE_WATERFALL) {
View v = LayoutInflater.from(parent.getContext())
.inflate(R.layout.item_collection_waterfall, parent, false);
RecyclerView.ViewHolder vh = new CollectionWaterfallViewHolder(v);
return vh;
} else {
View v = LayoutInflater.from(parent.getContext())
.inflate(R.layout.item_collection_grid, parent, false);
RecyclerView.ViewHolder vh = new CollectionGridViewHolder(v);
return vh;
}
}
@Override
public void onBindViewHolder(RecyclerView.ViewHolder viewHolder, int position) {
Collection collection = mProvider.getItem(position);
Logger.d("CollectionAdapter", "collection.cover:" + collection.cover);
if (viewHolder instanceof CollectionViewHolder) {
CollectionViewHolder holder = (CollectionViewHolder) viewHolder;
String cookie = (site == null) ? "" : site.cookie;
if (collection instanceof LocalCollection) {
cookie = ((LocalCollection) collection).site.cookie;
}
ImageLoader.loadImageFromUrl(context, holder.ivCover, collection.cover, cookie, collection.referer);
holder.tvTitle.setText(collection.title);
holder.tvUploader.setText(collection.uploader);
holder.tvCategory.setText(collection.category);
holder.tvUploader.setVisibility(View.VISIBLE);
holder.tvCategory.setVisibility(View.VISIBLE);
if (collection.tags == null) {
CollectionTagAdapter adapter = new CollectionTagAdapter(new ListDataProvider<>(new ArrayList()));
adapter.setOnItemClickListener(mTagClickListener);
holder.rvTags.setAdapter(adapter);
} else {
if (TextUtils.isEmpty(collection.uploader)) {
holder.tvUploader.setVisibility(View.GONE);
} else if (TextUtils.isEmpty(collection.category)) {
holder.tvCategory.setVisibility(View.GONE);
}
CollectionTagAdapter adapter = new CollectionTagAdapter(new ListDataProvider<>(collection.tags));
adapter.setOnItemClickListener(mTagClickListener);
holder.rvTags.setAdapter(adapter);
}
holder.rbRating.setRating(collection.rating);
holder.tvSubmittime.setText(collection.datetime);
if (site != null) {
checkSiteFlags(position, site, collection);
} else if (collection instanceof LocalCollection) {
holder.layoutCover.setVisibility(View.VISIBLE);
holder.tvTitle.setVisibility(View.VISIBLE);
holder.rbRating.setVisibility(View.VISIBLE);
holder.rvTags.setVisibility(View.VISIBLE);
checkSiteFlags(holder, ((LocalCollection) collection).site);
checkSiteFlags(position, ((LocalCollection) collection).site, collection);
}
int emptySpaceCount = (collection.tags==null)? 1 : 0;
emptySpaceCount += (TextUtils.isEmpty(collection.uploader))? 1 : 0;
emptySpaceCount += (TextUtils.isEmpty(collection.category))? 1 : 0;
Logger.d("CollectionAdapter", "emptySpaceCount : " + emptySpaceCount);
switch (emptySpaceCount){
case 3:
case 2:
case 1:
holder.tvTitle.setMaxLines(2);
break;
case 0:
default:
holder.tvTitle.setMaxLines(1);
}
} else if (viewHolder instanceof CollectionGridViewHolder) {
CollectionGridViewHolder holder = (CollectionGridViewHolder) viewHolder;
String cookie = (site == null) ? "" : site.cookie;
if (collection instanceof LocalCollection) {
cookie = ((LocalCollection) collection).site.cookie;
}
if (TextUtils.isEmpty(collection.cover))
checkSiteFlags(position, site, collection);
else
ImageLoader.loadImageFromUrl(context, holder.ivCover, collection.cover, cookie, collection.referer);
} else if (viewHolder instanceof CollectionWaterfallViewHolder) {
CollectionWaterfallViewHolder holder = (CollectionWaterfallViewHolder) viewHolder;
String cookie = (site == null) ? "" : site.cookie;
if (collection instanceof LocalCollection) {
cookie = ((LocalCollection) collection).site.cookie;
}
waterfallCheckTextView(holder.tvTitle, collection.title);
waterfallCheckTextView(holder.tvUploader, collection.uploader);
waterfallCheckTextView(holder.tvCategory, collection.category);
waterfallCheckTextView(holder.tvSubmittime, collection.datetime);
Integer originHeightObj = storedHeights.get(collection);
int originHeight = (originHeightObj != null && originHeightObj > 0) ? originHeightObj.intValue() : DensityUtil.dp2px(context, 215);
holder.ivCover.getLayoutParams().height = originHeight;
holder.ivIcon.getLayoutParams().height = originHeight;
holder.tvDescription.getLayoutParams().height = originHeight;
holder.ivCover.requestLayout();
holder.ivIcon.requestLayout();
if (originHeightObj == null || originHeightObj <= 0) {
FastImageSize.with(collection.cover)
.customProvider(new ImageSizeInputStreamProvider(collection.referer, cookie))
.get(size -> {
int width = size[0];
int height = size[1];
final float factor = (float) height / width;
final int viewWidth = holder.ivCover.getWidth();
final int viewHeight = (int) (factor * viewWidth);
if (viewHeight > 0) {
if (holder.ivCover.getLayoutParams().height != viewHeight) {
holder.ivCover.getLayoutParams().height = viewHeight;
holder.ivIcon.getLayoutParams().height = viewHeight;
holder.ivCover.requestLayout();
holder.ivIcon.requestLayout();
}
storedHeights.put(collection, viewHeight);
}
});
}
if (site != null) {
checkSiteFlags(position, site, collection);
} else if (collection instanceof LocalCollection) {
holder.tvTitle.setVisibility(View.VISIBLE);
checkSiteFlags(holder, ((LocalCollection) collection).site);
checkSiteFlags(position, ((LocalCollection) collection).site, collection);
}
if (TextUtils.isEmpty(collection.cover) && !TextUtils.isEmpty(collection.description)) {
holder.ivIcon.setVisibility(View.GONE);
holder.ivCover.setVisibility(View.GONE);
holder.tvDescription.getLayoutParams().height = ViewGroup.LayoutParams.WRAP_CONTENT;
if (TextUtils.isEmpty(collection.description))
holder.tvDescription.setVisibility(View.GONE);
else {
holder.tvDescription.setVisibility(View.VISIBLE);
holder.tvDescription.setText(Html.fromHtml(collection.description, source -> new BitmapDrawable(), null));
}
holder.tvDescription.requestLayout();
originHeight = holder.tvDescription.getHeight();
storedHeights.put(collection, originHeight);
} else {
holder.ivIcon.setVisibility(View.VISIBLE);
holder.ivCover.setVisibility(View.VISIBLE);
holder.tvDescription.setVisibility(View.GONE);
if (!TextUtils.isEmpty(collection.cover))
ImageLoader.loadImageFromUrl(context, holder.ivCover, collection.cover, cookie, collection.referer, new BaseControllerListener<ImageInfo>() {
@Override
public void onFinalImageSet(String id, @Nullable ImageInfo imageInfo, @Nullable Animatable anim) {
super.onFinalImageSet(id, imageInfo, anim);
if (imageInfo == null) {
return;
}
holder.ivCover.post(() -> {
final float factor = (float) imageInfo.getHeight() / imageInfo.getWidth();
final int originWidth = holder.ivCover.getWidth();
final int originHeight = (int) (factor * originWidth);
if (originHeight > 0) {
if (holder.ivCover.getLayoutParams().height != originHeight) {
holder.ivCover.getLayoutParams().height = originHeight;
holder.ivIcon.getLayoutParams().height = originHeight;
holder.ivCover.requestLayout();
holder.ivIcon.requestLayout();
}
storedHeights.put(collection, originHeight);
}
});
}
@Override
public void onFailure(String id, Throwable throwable) {
FLog.e(getClass(), throwable, "Error loading %s", id);
}
});
}
}
}
private void waterfallCheckTextView(TextView textView, String text) {
if (TextUtils.isEmpty(text))
textView.setVisibility(View.GONE);
else {
textView.setVisibility(View.VISIBLE);
textView.setText(text);
}
}
private void checkSiteFlags(int position, Site site, Collection collection) {
if (site.hasFlag(Site.FLAG_PRELOAD_GALLERY) && !collection.preloaded) {
SiteFlagHandler.preloadGallery(context, this, position, site, collection, siteTagHolder);
}
}
private void checkSiteFlags(CollectionViewHolder holder, Site site) {
if (site.hasFlag(Site.FLAG_NO_COVER)) {
holder.layoutCover.setVisibility(View.GONE);
}
if (site.hasFlag(Site.FLAG_NO_TITLE)) {
holder.tvTitle.setVisibility(View.GONE);
if (holder.rvTags != null) {
holder.rvTags.setLayoutManager(new StaggeredGridLayoutManager(3, OrientationHelper.HORIZONTAL));
}
} else {
if (holder.rvTags != null) {
holder.rvTags.setLayoutManager(new StaggeredGridLayoutManager(2, OrientationHelper.HORIZONTAL));
}
}
if (site.hasFlag(Site.FLAG_NO_RATING)) {
holder.rbRating.setVisibility(View.GONE);
}
if (site.hasFlag(Site.FLAG_NO_TAG)) {
holder.rvTags.setVisibility(View.GONE);
holder.rvTags.setAdapter(
new CollectionTagAdapter(new ListDataProvider<>(new ArrayList()))
);
}
}
private void checkSiteFlags(CollectionWaterfallViewHolder holder, Site site) {
if (site.hasFlag(Site.FLAG_NO_TITLE)) {
holder.tvTitle.setVisibility(View.GONE);
}
holder.tvTitle.setMaxLines(2);
}
@Override
public int getItemCount() {
return (mProvider == null) ? 0 : mProvider.getCount();
}
@Override
public long getItemId(int position) {
return (mProvider == null) ? 0 : mProvider.getItem(position).getId();
}
@Override
public int getItemViewType(int position) {
return (isGrid) ? (waterfallAsGrid ? TYPE_WATERFALL : TYPE_GRID) : (waterfallAsList ? TYPE_WATERFALL : TYPE_LIST);
}
public void setOnItemClickListener(OnItemClickListener listener) {
this.mItemClickListener = listener;
}
public void setOnTagClickListener(CollectionTagAdapter.OnItemClickListener listener) {
this.mTagClickListener = listener;
}
public void setSite(Site site) {
this.site = site;
if (site != null && site.hasFlag(Site.FLAG_WATERFALL_AS_LIST))
waterfallAsList = true;
if (site != null && site.hasFlag(Site.FLAG_WATERFALL_AS_GRID))
waterfallAsGrid = true;
}
public ListDataProvider getDataProvider() {
return mProvider;
}
public void setDataProvider(ListDataProvider mProvider) {
this.mProvider = mProvider;
}
public void setIsGrid(boolean isGrid) {
this.isGrid = isGrid;
}
public interface OnItemClickListener {
void onItemClick(View v, int position);
boolean onItemLongClick(View v, int position);
}
public class CollectionViewHolder extends RecyclerView.ViewHolder {
@BindView(R.id.ripple_layout)
public MaterialRippleLayout rippleLayout;
@BindView(R.id.layout_cover)
public RelativeLayout layoutCover;
@BindView(R.id.iv_cover)
public ImageView ivCover;
@BindView(R.id.tv_title)
public TextView tvTitle;
@BindView(R.id.tv_uploader)
public TextView tvUploader;
@BindView(R.id.tv_category)
public TextView tvCategory;
@BindView(R.id.rv_tags)
public RecyclerView rvTags;
@BindView(R.id.rb_rating)
public RatingBar rbRating;
@BindView(R.id.tv_submittime)
public TextView tvSubmittime;
public CollectionViewHolder(View view) {
super(view);
ButterKnife.bind(this, view);
if (site != null)
checkSiteFlags(this, site);
view.setOnClickListener(v -> {
if (mItemClickListener != null && getAdapterPosition() >= 0 && getAdapterPosition() < getItemCount())
mItemClickListener.onItemClick(v, getAdapterPosition());
});
view.setOnLongClickListener(v -> {
if (mItemClickListener != null && getAdapterPosition() >= 0 && getAdapterPosition() < getItemCount())
return mItemClickListener.onItemLongClick(v, getAdapterPosition());
else
return false;
});
rippleLayout.setOnClickListener(v -> {
if (mItemClickListener != null && getAdapterPosition() >= 0 && getAdapterPosition() < getItemCount())
mItemClickListener.onItemClick(v, getAdapterPosition());
});
rippleLayout.setOnLongClickListener(v -> {
if (mItemClickListener != null && getAdapterPosition() >= 0 && getAdapterPosition() < getItemCount())
return mItemClickListener.onItemLongClick(v, getAdapterPosition());
else
return false;
});
}
}
public class CollectionGridViewHolder extends RecyclerView.ViewHolder {
@BindView(R.id.ripple_layout)
MaterialRippleLayout rippleLayout;
@BindView(R.id.iv_cover)
ImageView ivCover;
public CollectionGridViewHolder(View view) {
super(view);
ButterKnife.bind(this, view);
view.setOnClickListener(v -> {
if (mItemClickListener != null && getAdapterPosition() >= 0 && getAdapterPosition() < getItemCount())
mItemClickListener.onItemClick(v, getAdapterPosition());
});
view.setOnLongClickListener(v -> {
if (mItemClickListener != null && getAdapterPosition() >= 0 && getAdapterPosition() < getItemCount())
return mItemClickListener.onItemLongClick(v, getAdapterPosition());
else
return false;
});
rippleLayout.setOnClickListener(v -> {
if (mItemClickListener != null && getAdapterPosition() >= 0 && getAdapterPosition() < getItemCount())
mItemClickListener.onItemClick(v, getAdapterPosition());
});
rippleLayout.setOnLongClickListener(v -> {
if (mItemClickListener != null && getAdapterPosition() >= 0 && getAdapterPosition() < getItemCount())
return mItemClickListener.onItemLongClick(v, getAdapterPosition());
else
return false;
});
}
}
public class CollectionWaterfallViewHolder extends RecyclerView.ViewHolder {
@BindView(R.id.iv_icon)
ImageView ivIcon;
@BindView(R.id.iv_cover)
SimpleDraweeView ivCover;
@BindView(R.id.tv_description)
TextView tvDescription;
@BindView(R.id.tv_title)
TextView tvTitle;
@BindView(R.id.tv_submittime)
TextView tvSubmittime;
@BindView(R.id.tv_uploader)
TextView tvUploader;
@BindView(R.id.tv_category)
TextView tvCategory;
@BindView(R.id.ripple_layout)
MaterialRippleLayout rippleLayout;
public CollectionWaterfallViewHolder(View view) {
super(view);
ButterKnife.bind(this, view);
if (site != null)
checkSiteFlags(this, site);
view.setOnClickListener(v -> {
if (mItemClickListener != null && getAdapterPosition() >= 0 && getAdapterPosition() < getItemCount())
mItemClickListener.onItemClick(v, getAdapterPosition());
});
view.setOnLongClickListener(v -> {
if (mItemClickListener != null && getAdapterPosition() >= 0 && getAdapterPosition() < getItemCount())
return mItemClickListener.onItemLongClick(v, getAdapterPosition());
else
return false;
});
rippleLayout.setOnClickListener(v -> {
if (mItemClickListener != null && getAdapterPosition() >= 0 && getAdapterPosition() < getItemCount())
mItemClickListener.onItemClick(v, getAdapterPosition());
});
rippleLayout.setOnLongClickListener(v -> {
if (mItemClickListener != null && getAdapterPosition() >= 0 && getAdapterPosition() < getItemCount())
return mItemClickListener.onItemLongClick(v, getAdapterPosition());
else
return false;
});
}
}
}