package org.getlantern.firetweet.adapter;
import android.content.Context;
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import android.support.v4.util.Pair;
import android.support.v7.widget.CardView;
import android.support.v7.widget.RecyclerView.Adapter;
import android.support.v7.widget.RecyclerView.ViewHolder;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import org.getlantern.firetweet.Constants;
import org.getlantern.firetweet.R;
import org.getlantern.firetweet.adapter.iface.IStatusesAdapter;
import org.getlantern.firetweet.app.FiretweetApplication;
import org.getlantern.firetweet.fragment.support.UserFragment;
import org.getlantern.firetweet.model.ParcelableMedia;
import org.getlantern.firetweet.model.ParcelableStatus;
import org.getlantern.firetweet.util.AsyncTwitterWrapper;
import org.getlantern.firetweet.util.ImageLoadingHandler;
import org.getlantern.firetweet.util.MediaLoaderWrapper;
import org.getlantern.firetweet.util.SharedPreferencesWrapper;
import org.getlantern.firetweet.util.StatusAdapterLinkClickHandler;
import org.getlantern.firetweet.util.ThemeUtils;
import org.getlantern.firetweet.util.FiretweetLinkify;
import org.getlantern.firetweet.util.FiretweetLinkify.HighlightStyle;
import org.getlantern.firetweet.util.Utils;
import org.getlantern.firetweet.view.CardMediaContainer.PreviewStyle;
import org.getlantern.firetweet.view.ShapedImageView.ShapeStyle;
import org.getlantern.firetweet.view.holder.GapViewHolder;
import org.getlantern.firetweet.view.holder.LoadIndicatorViewHolder;
import org.getlantern.firetweet.view.holder.StatusViewHolder;
/**
* Created by mariotaku on 14/11/19.
*/
public abstract class AbsStatusesAdapter<D> extends Adapter<ViewHolder> implements Constants,
IStatusesAdapter<D> {
public static final int ITEM_VIEW_TYPE_LOAD_INDICATOR = 0;
public static final int ITEM_VIEW_TYPE_GAP = 1;
public static final int ITEM_VIEW_TYPE_STATUS = 2;
private final Context mContext;
private final LayoutInflater mInflater;
private final MediaLoaderWrapper mImageLoader;
private final ImageLoadingHandler mLoadingHandler;
private final AsyncTwitterWrapper mTwitterWrapper;
private final FiretweetLinkify mLinkify;
private StatusAdapterListener mStatusAdapterListener;
private final int mCardBackgroundColor;
private final int mTextSize;
@ShapeStyle
private final int mProfileImageStyle;
@PreviewStyle
private final int mMediaPreviewStyle;
@HighlightStyle
private final int mLinkHighlightingStyle;
private final boolean mCompactCards;
private final boolean mNameFirst;
private final boolean mDisplayMediaPreview;
private final boolean mDisplayProfileImage;
private final boolean mSensitiveContentEnabled;
private final boolean mHideCardActions;
private boolean mLoadMoreSupported;
private boolean mLoadMoreIndicatorVisible;
private boolean mShowInReplyTo;
private boolean mShowAccountsColor;
public AbsStatusesAdapter(Context context, boolean compact) {
mContext = context;
final FiretweetApplication app = FiretweetApplication.getInstance(context);
mCardBackgroundColor = ThemeUtils.getCardBackgroundColor(context);
mInflater = LayoutInflater.from(context);
mImageLoader = app.getMediaLoaderWrapper();
mLoadingHandler = new ImageLoadingHandler(R.id.media_preview_progress);
mTwitterWrapper = app.getTwitterWrapper();
final SharedPreferencesWrapper preferences = SharedPreferencesWrapper.getInstance(context,
SHARED_PREFERENCES_NAME, Context.MODE_PRIVATE);
mTextSize = preferences.getInt(KEY_TEXT_SIZE, context.getResources().getInteger(R.integer.default_text_size));
mCompactCards = compact;
mProfileImageStyle = Utils.getProfileImageStyle(preferences.getString(KEY_PROFILE_IMAGE_STYLE, null));
mMediaPreviewStyle = Utils.getMediaPreviewStyle(preferences.getString(KEY_MEDIA_PREVIEW_STYLE, null));
mLinkHighlightingStyle = Utils.getLinkHighlightingStyleInt(preferences.getString(KEY_LINK_HIGHLIGHT_OPTION, null));
mNameFirst = preferences.getBoolean(KEY_NAME_FIRST, true);
mDisplayProfileImage = preferences.getBoolean(KEY_DISPLAY_PROFILE_IMAGE, true);
mDisplayMediaPreview = preferences.getBoolean(KEY_MEDIA_PREVIEW, false);
mSensitiveContentEnabled = preferences.getBoolean(KEY_DISPLAY_SENSITIVE_CONTENTS, false);
mHideCardActions = preferences.getBoolean(KEY_HIDE_CARD_ACTIONS, false);
mLinkify = new FiretweetLinkify(new StatusAdapterLinkClickHandler<>(this));
setShowInReplyTo(true);
}
public abstract D getData();
public abstract void setData(D data);
@Override
public boolean shouldShowAccountsColor() {
return mShowAccountsColor;
}
@Override
public final MediaLoaderWrapper getImageLoader() {
return mImageLoader;
}
@Override
public final Context getContext() {
return mContext;
}
@Override
public final ImageLoadingHandler getImageLoadingHandler() {
return mLoadingHandler;
}
@Override
public final int getProfileImageStyle() {
return mProfileImageStyle;
}
@Override
public final int getMediaPreviewStyle() {
return mMediaPreviewStyle;
}
@Override
public final AsyncTwitterWrapper getTwitterWrapper() {
return mTwitterWrapper;
}
@Override
public final float getTextSize() {
return mTextSize;
}
@Override
public boolean isLoadMoreIndicatorVisible() {
return mLoadMoreIndicatorVisible;
}
@Override
public boolean isLoadMoreSupported() {
return mLoadMoreSupported;
}
@Override
public void setLoadMoreSupported(boolean supported) {
mLoadMoreSupported = supported;
if (!supported) {
mLoadMoreIndicatorVisible = false;
}
notifyDataSetChanged();
}
@Override
public void setLoadMoreIndicatorVisible(boolean enabled) {
if (mLoadMoreIndicatorVisible == enabled) return;
mLoadMoreIndicatorVisible = enabled && mLoadMoreSupported;
notifyDataSetChanged();
}
@Override
public FiretweetLinkify getFiretweetLinkify() {
return mLinkify;
}
@Override
public boolean isMediaPreviewEnabled() {
return mDisplayMediaPreview;
}
@Override
public int getLinkHighlightingStyle() {
return mLinkHighlightingStyle;
}
@Override
public boolean isNameFirst() {
return mNameFirst;
}
@Override
public boolean isSensitiveContentEnabled() {
return mSensitiveContentEnabled;
}
@Override
public boolean isCardActionsHidden() {
return mHideCardActions;
}
@Override
public boolean isProfileImageEnabled() {
return mDisplayProfileImage;
}
@Override
public final void onStatusClick(StatusViewHolder holder, int position) {
if (mStatusAdapterListener != null) {
mStatusAdapterListener.onStatusClick(holder, position);
}
}
@Override
public void onMediaClick(StatusViewHolder holder, final ParcelableMedia media, int position) {
if (mStatusAdapterListener != null) {
mStatusAdapterListener.onMediaClick(holder, media, position);
}
}
@Override
public void onUserProfileClick(final StatusViewHolder holder, final int position) {
final ParcelableStatus status = getStatus(position);
if (status == null) return;
final Context context = getContext();
final View profileImageView = holder.getProfileImageView();
final View profileTypeView = holder.getProfileTypeView();
if (context instanceof FragmentActivity) {
final Bundle options = Utils.makeSceneTransitionOption((FragmentActivity) context,
new Pair<>(profileImageView, UserFragment.TRANSITION_NAME_PROFILE_IMAGE),
new Pair<>(profileTypeView, UserFragment.TRANSITION_NAME_PROFILE_TYPE));
Utils.openUserProfile(context, status.account_id, status.user_id, status.user_screen_name, options);
} else {
Utils.openUserProfile(context, status.account_id, status.user_id, status.user_screen_name, null);
}
}
public boolean isShowInReplyTo() {
return mShowInReplyTo;
}
public void setShowInReplyTo(boolean showInReplyTo) {
if (mShowInReplyTo == showInReplyTo) return;
mShowInReplyTo = showInReplyTo;
notifyDataSetChanged();
}
public boolean isStatus(int position) {
return position < getStatusesCount();
}
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
switch (viewType) {
case ITEM_VIEW_TYPE_STATUS: {
final View view;
if (mCompactCards) {
view = mInflater.inflate(R.layout.card_item_status_compact, parent, false);
final View itemContent = view.findViewById(R.id.item_content);
itemContent.setBackgroundColor(mCardBackgroundColor);
} else {
view = mInflater.inflate(R.layout.card_item_status, parent, false);
final CardView cardView = (CardView) view.findViewById(R.id.card);
cardView.setCardBackgroundColor(mCardBackgroundColor);
}
final StatusViewHolder holder = new StatusViewHolder(this, view);
holder.setOnClickListeners();
holder.setupViewOptions();
return holder;
}
case ITEM_VIEW_TYPE_GAP: {
final View view = mInflater.inflate(R.layout.card_item_gap, parent, false);
return new GapViewHolder(this, view);
}
case ITEM_VIEW_TYPE_LOAD_INDICATOR: {
final View view = mInflater.inflate(R.layout.card_item_load_indicator, parent, false);
return new LoadIndicatorViewHolder(view);
}
}
throw new IllegalStateException("Unknown view type " + viewType);
}
@Override
public void onBindViewHolder(ViewHolder holder, int position) {
switch (holder.getItemViewType()) {
case ITEM_VIEW_TYPE_STATUS: {
bindStatus(((StatusViewHolder) holder), position);
break;
}
}
}
@Override
public int getItemViewType(int position) {
if (position == getStatusesCount()) {
return ITEM_VIEW_TYPE_LOAD_INDICATOR;
} else if (isGapItem(position)) {
return ITEM_VIEW_TYPE_GAP;
}
return ITEM_VIEW_TYPE_STATUS;
}
@Override
public final int getItemCount() {
return getStatusesCount() + (mLoadMoreIndicatorVisible ? 1 : 0);
}
@Override
public final void onGapClick(ViewHolder holder, int position) {
if (mStatusAdapterListener != null) {
mStatusAdapterListener.onGapClick((GapViewHolder) holder, position);
}
}
@Override
public void onItemActionClick(ViewHolder holder, int id, int position) {
if (mStatusAdapterListener != null) {
mStatusAdapterListener.onStatusActionClick((StatusViewHolder) holder, id, position);
}
}
@Override
public void onItemMenuClick(ViewHolder holder, View menuView, int position) {
if (mStatusAdapterListener != null) {
mStatusAdapterListener.onStatusMenuClick((StatusViewHolder) holder, menuView, position);
}
}
public void setListener(StatusAdapterListener listener) {
mStatusAdapterListener = listener;
}
public void setShowAccountsColor(boolean showAccountsColor) {
if (mShowAccountsColor == showAccountsColor) return;
mShowAccountsColor = showAccountsColor;
notifyDataSetChanged();
}
protected abstract void bindStatus(StatusViewHolder holder, int position);
public static interface StatusAdapterListener {
void onGapClick(GapViewHolder holder, int position);
void onMediaClick(StatusViewHolder holder, ParcelableMedia media, int position);
void onStatusActionClick(StatusViewHolder holder, int id, int position);
void onStatusClick(StatusViewHolder holder, int position);
void onStatusMenuClick(StatusViewHolder holder, View menuView, int position);
}
}