package com.duckduckgo.mobile.android.adapters;
import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.os.Handler;
import android.support.v4.app.FragmentManager;
import android.support.v4.view.ViewPager;
import android.support.v7.view.menu.MenuBuilder;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.FrameLayout;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.TextView;
import com.duckduckgo.mobile.android.DDGApplication;
import com.duckduckgo.mobile.android.R;
import com.duckduckgo.mobile.android.bus.BusProvider;
import com.duckduckgo.mobile.android.dialogs.InstructionDialogFragment;
import com.duckduckgo.mobile.android.download.AsyncImageView;
import com.duckduckgo.mobile.android.events.SourceFilterEvent;
import com.duckduckgo.mobile.android.events.feedEvents.FeedCancelCategoryFilterEvent;
import com.duckduckgo.mobile.android.events.feedEvents.FeedCancelSourceFilterEvent;
import com.duckduckgo.mobile.android.events.feedEvents.MainFeedItemSelectedEvent;
import com.duckduckgo.mobile.android.objects.FeedObject;
import com.duckduckgo.mobile.android.util.DDGControlVar;
import com.duckduckgo.mobile.android.util.DDGUtils;
import com.duckduckgo.mobile.android.util.OnboardingHelper;
import com.duckduckgo.mobile.android.util.PreferencesManager;
import com.duckduckgo.mobile.android.views.DDGOverflowMenu;
import com.duckduckgo.mobile.android.views.pageindicator.BannerOnboardingPageIndicator;
import com.squareup.picasso.Picasso;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
public class RecyclerMainFeedAdapter extends RecyclerView.Adapter<RecyclerMainFeedAdapter.BaseViewHolder> {
private static final String TAG = "MainFeedAdapter";
private static final int ITEM_TYPE_FEED = 0;
private static final int ITEM_TYPE_HEADER = 1;
private boolean isOnboardingBannerVisible = true;
private Context context;
private final LayoutInflater inflater;
private FragmentManager fragmentManager;
private OnboardingHelper onboardingHelper;
private DDGOverflowMenu feedMenu = null;
private Menu menu = null;
public List<FeedObject> data;
public abstract class BaseViewHolder extends RecyclerView.ViewHolder {
public BaseViewHolder(View itemView) {
super(itemView);
}
public abstract void attach();
public abstract void detach();
}
public class FeedViewHolder extends BaseViewHolder {
public final TextView textViewTitle;
public final FrameLayout frameCategoryContainer;
public final TextView textViewCategory;
public final FrameLayout frameMenuContainer;
public final ImageView imageViewMenu;
public final AsyncImageView imageViewBackground;
public final AsyncImageView imageViewFeedIcon; // Bottom Left Icon (Feed Source)
public FeedViewHolder(View v) {
super(v);
this.textViewTitle = (TextView) v.findViewById(R.id.feedTitleTextView);
this.frameCategoryContainer = (FrameLayout) v.findViewById(R.id.feedCategoryContainer);
this.textViewCategory = (TextView) v.findViewById(R.id.feedCategoryTextView);
this.frameMenuContainer = (FrameLayout) v.findViewById(R.id.feedMenuContainer);
this.imageViewMenu = (ImageView) v.findViewById(R.id.feedMenuImage);
this.imageViewBackground = (AsyncImageView) v.findViewById(R.id.feedItemBackground);
this.imageViewFeedIcon = (AsyncImageView) v.findViewById(R.id.feedItemSourceIcon);
}
@Override
public void attach() {
}
@Override
public void detach() {
}
}
public class HeaderViewHolder extends BaseViewHolder {
private final int SLIDE_TIME = 10000;
public final ViewPager viewPager;
public final BannerOnboardingPageIndicator pageIndicator;
public final Button instructionbutton;
public final ImageButton dismissImageButton;
final Handler handler;
final Runnable slideRunnable;
private boolean isRunning = false;
public HeaderViewHolder(View itemView) {
super(itemView);
instructionbutton = (Button) itemView.findViewById(R.id.instruction_button);
dismissImageButton = (ImageButton) itemView.findViewById(R.id.dismiss_image_button);
viewPager = (ViewPager) itemView.findViewById(R.id.view_pager);
viewPager.setAdapter(new OnboardingBannerAdapter());
viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
@Override
public void onPageScrolled(int i, float v, int i1) {
}
@Override
public void onPageSelected(int i) {
if(!isRunning) {
startSlidingViewPager();
}
}
@Override
public void onPageScrollStateChanged(int i) {
if(isRunning && i == ViewPager.SCROLL_STATE_DRAGGING) {
stopSlidingViewPager();
}
}
});
pageIndicator = (BannerOnboardingPageIndicator) itemView.findViewById(R.id.page_indicator);
pageIndicator.setViewPager(viewPager);
handler = new Handler();
slideRunnable = new Runnable() {
@Override
public void run() {
int nextItem = viewPager.getCurrentItem() + 1;
if(nextItem == viewPager.getAdapter().getCount()) nextItem = 0;
viewPager.setCurrentItem(nextItem, true);
handler.postDelayed(this, SLIDE_TIME);
}
};
}
@Override
public void attach() {
startSlidingViewPager();
}
@Override
public void detach() {
stopSlidingViewPager();
}
private void startSlidingViewPager() {
isRunning = true;
handler.postDelayed(slideRunnable, SLIDE_TIME);
}
private void stopSlidingViewPager() {
isRunning = false;
handler.removeCallbacks(slideRunnable);
}
}
public RecyclerMainFeedAdapter(Context context, FragmentManager fragmentManager) {
this.context = context;
this.fragmentManager = fragmentManager;
onboardingHelper = new OnboardingHelper(context);
isOnboardingBannerVisible = onboardingHelper.shouldShowOnboardingBanner();
inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
data = new ArrayList<>();
menu = new MenuBuilder(context);
((Activity)context).getMenuInflater().inflate(R.menu.feed, menu);
feedMenu = new DDGOverflowMenu(context);
}
@Override
public BaseViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
if(viewType == ITEM_TYPE_HEADER) return new HeaderViewHolder(inflater.inflate(R.layout.viewholder_feed_header, parent, false));
return new FeedViewHolder(inflater.inflate(R.layout.item_main_feed, parent, false));
}
@Override
public void onBindViewHolder(final BaseViewHolder holder, int position) {
if(position == 0 && isOnboardingBannerVisible) {
//that's the header;
final HeaderViewHolder headerHolder = (HeaderViewHolder) holder;
boolean isFirefoxDefault = onboardingHelper.isDefaultBrowserFirefox();
final boolean showFirefoxInstruction = isFirefoxDefault || PreferencesManager.isDDGAddedToHomeScreen();
headerHolder.instructionbutton.setText(
String.format(context.getString(R.string.add_to),
context.getString(showFirefoxInstruction ? R.string.browser_firefox : R.string.browser_chrome))
);
headerHolder.instructionbutton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
InstructionDialogFragment.newInstance(
showFirefoxInstruction ? InstructionDialogFragment.EXTRA_INSTRUCTION_FIREFOX : InstructionDialogFragment.EXTRA_INSTRUCTION_CHROME)
.show(fragmentManager, InstructionDialogFragment.TAG);
}
});
headerHolder.dismissImageButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
dismissOnboardingBanner();
}
});
return;
}
final FeedObject feed = getItem(position);//data.get(position - 1); //header
final FeedViewHolder feedHolder = (FeedViewHolder) holder;
URL feedUrl = null;
if (feed != null) {
final String feedId = feed.getId();
//Download the background image
if (feed.getImageUrl() != null && !feed.getImageUrl().equals("null")) {
Picasso.with(context)
.load(feed.getImageUrl())
.resize(DDGUtils.displayStats.feedItemWidth, DDGUtils.displayStats.feedItemHeight)
.centerCrop()
.placeholder(android.R.color.transparent)
.into(feedHolder.imageViewBackground);
}
final String feedType = feed.getType();
feedHolder.imageViewFeedIcon.setType(feedType); // stored source id in imageview
final View itemView = feedHolder.itemView;
final String sourceType = feedHolder.imageViewFeedIcon.getType();
feedHolder.imageViewFeedIcon.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if(DDGControlVar.targetSource!=null) {
DDGControlVar.targetSource=null;
BusProvider.getInstance().post(new FeedCancelSourceFilterEvent());
} else {
DDGControlVar.targetSource = sourceType;
DDGControlVar.hasUpdatedFeed = false;
BusProvider.getInstance().post(new SourceFilterEvent(itemView, sourceType, feed));
filterSource(sourceType);
}
}
});
//Set the Title
feedHolder.textViewTitle.setText(feed.getTitle());
// FIXME : it'd be good to reset color to default color for textview in layout XML
feedHolder.textViewTitle.setTextColor(context.getResources().getColor(R.color.feed_title));
if(DDGControlVar.readArticles.contains(feedId)){
feedHolder.textViewTitle.setTextColor(context.getResources().getColor(R.color.feed_title_viewed));
}
//set the category
//todo insert size
final String category = feed.getCategory();
feedHolder.textViewCategory.setText(category.toUpperCase());
feedHolder.frameCategoryContainer.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if(DDGControlVar.targetCategory!=null) {
DDGControlVar.targetCategory=null;
BusProvider.getInstance().post(new FeedCancelCategoryFilterEvent());
} else {
DDGControlVar.targetCategory = category;
filterCategory(category);
}
}
});
feedHolder.frameMenuContainer.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
showMenu(feedHolder.imageViewMenu, feed);
}
});
if (feed.getFeed() != null && !feed.getFeed().equals("null")) {
try {
feedUrl = new URL(feed.getFeed());
} catch (MalformedURLException e) {
e.printStackTrace();
}
if (feedUrl != null) {
String host = feedUrl.getHost();
if (host.indexOf(".") != host.lastIndexOf(".")) {
//Cut off the beginning, because we don't want/need it
host = host.substring(host.indexOf(".")+1);
}
Bitmap bitmap = DDGApplication.getImageCache().getBitmapFromCache("DUCKDUCKICO--" + feedType, false);
if(bitmap != null){
feedHolder.imageViewFeedIcon.setBitmap(bitmap);
}
}
feedHolder.itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
BusProvider.getInstance().post(new MainFeedItemSelectedEvent(feed));
}
});
feedHolder.itemView.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
showMenu(feedHolder.imageViewMenu, feed);
return true;
}
});
}
}
}
public FeedObject getItem(int position) {
int index = position;
if(isOnboardingBannerVisible) index -= 1;
return data.get(index);
}
@Override
public int getItemCount() {
int size = data.size();
if(isOnboardingBannerVisible) return size+ 1;
return size;
}
@Override
public int getItemViewType(int position) {
if(position == 0 && isOnboardingBannerVisible) return ITEM_TYPE_HEADER;
return ITEM_TYPE_FEED;
}
@Override
public void onViewAttachedToWindow(BaseViewHolder holder) {
super.onViewAttachedToWindow(holder);
holder.attach();
}
@Override
public void onViewDetachedFromWindow(BaseViewHolder holder) {
holder.detach();
super.onViewDetachedFromWindow(holder);
}
private void dismissOnboardingBanner() {
onboardingHelper.setOnboardingBannerDismissed();
isOnboardingBannerVisible = false;
notifyItemRemoved(0);
}
private void showMenu(View anchor, FeedObject feed) {
if(feedMenu==null) {
feedMenu = new DDGOverflowMenu(context);
}
if(!feedMenu.isShowing()) {
if(DDGApplication.getDB().isSaved(feed.getId())) {
menu.findItem(R.id.action_add_favorite).setVisible(false);
menu.findItem(R.id.action_remove_favorite).setVisible(true);
} else {
menu.findItem(R.id.action_add_favorite).setVisible(true);
menu.findItem(R.id.action_remove_favorite).setVisible(false);
}
feedMenu.setFeed(feed);
feedMenu.setMenu(menu);
feedMenu.showFeedMenu(anchor);
}
}
public void clear() {
data.clear();
notifyDataSetChanged();
}
public void addData(List<FeedObject> newData) {
this.data = (ArrayList) newData;
notifyDataSetChanged();
}
public void addSourceData(List<FeedObject> newSources) {
for(FeedObject newFeed : newSources) {
boolean isPresent = false;
for(FeedObject feed : data) {
if(feed.getId().equals(newFeed.getId())) {
isPresent = true;
}
}
if(!isPresent) {
data.add(newFeed);
notifyItemInserted(data.size());
}
}
}
public void filterCategory(String category) {
int i = data.size() - 1;
for(; i>=0; i--) {
if(!data.get(i).getCategory().equals(category)) {
data.remove(i);
notifyItemRemoved(i);
}
}
}
private void filterSource(String source) {
int i = data.size() - 1;
for(; i>=0; i--) {
if(!data.get(i).getType().equals(source)) {
data.remove(i);
notifyItemRemoved(i);
}
}
}
}