package de.luhmer.owncloudnewsreader.adapter;
import android.content.SharedPreferences;
import android.os.AsyncTask;
import android.preference.PreferenceManager;
import android.support.v4.app.FragmentActivity;
import android.support.v4.content.ContextCompat;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.text.style.ForegroundColorSpan;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import org.apache.commons.lang3.time.StopWatch;
import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import de.luhmer.owncloudnewsreader.R;
import de.luhmer.owncloudnewsreader.SettingsActivity;
import de.luhmer.owncloudnewsreader.database.DatabaseConnectionOrm;
import de.luhmer.owncloudnewsreader.database.model.RssItem;
import de.luhmer.owncloudnewsreader.events.podcast.PodcastCompletedEvent;
import de.luhmer.owncloudnewsreader.events.podcast.UpdatePodcastStatusEvent;
import de.luhmer.owncloudnewsreader.helper.AsyncTaskHelper;
import de.luhmer.owncloudnewsreader.helper.PostDelayHandler;
import de.luhmer.owncloudnewsreader.interfaces.IPlayPausePodcastClicked;
import de.luhmer.owncloudnewsreader.model.CurrentRssViewDataHolder;
public class NewsListRecyclerAdapter extends RecyclerView.Adapter {
private static final String TAG = "NewsListRecyclerAdapter";
private final int VIEW_ITEM = 1;
private final int VIEW_PROG = 0;
private long idOfCurrentlyPlayedPodcast = -1;
private List<RssItem> lazyList;
private int titleLineCount;
private DatabaseConnectionOrm dbConn;
private ForegroundColorSpan bodyForegroundColor;
private PostDelayHandler pDelayHandler;
private FragmentActivity activity;
private HashSet<Long> stayUnreadItems = new HashSet<>();
private int totalItemCount = 0;
private int cachedPages = 1;
public int getTotalItemCount() {
return totalItemCount;
}
public int getCachedPages() {
return cachedPages;
}
public void setTotalItemCount(int totalItemCount) {
this.totalItemCount = totalItemCount;
}
public void setCachedPages(int cachedPages) {
this.cachedPages = cachedPages;
}
private IPlayPausePodcastClicked playPausePodcastClicked;
private boolean loading = false;
// The minimum amount of items to have below your current scroll position
// before loading more.
private int visibleThreshold = 5;
public NewsListRecyclerAdapter(FragmentActivity activity, RecyclerView recyclerView, IPlayPausePodcastClicked playPausePodcastClicked) {
this.activity = activity;
this.playPausePodcastClicked = playPausePodcastClicked;
pDelayHandler = new PostDelayHandler(activity);
bodyForegroundColor = new ForegroundColorSpan(ContextCompat.getColor(activity, android.R.color.secondary_text_dark));
dbConn = new DatabaseConnectionOrm(activity);
SharedPreferences mPrefs = PreferenceManager.getDefaultSharedPreferences(activity);
titleLineCount = Integer.parseInt(mPrefs.getString(SettingsActivity.SP_TITLE_LINES_COUNT, "2"));
setHasStableIds(true);
EventBus.getDefault().register(this);
if (recyclerView.getLayoutManager() instanceof LinearLayoutManager) {
final LinearLayoutManager linearLayoutManager = (LinearLayoutManager) recyclerView
.getLayoutManager();
recyclerView
.addOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrolled(RecyclerView recyclerView,
int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
int adapterTotalItemCount = linearLayoutManager.getItemCount();
int lastVisibleItem = linearLayoutManager
.findLastVisibleItemPosition();
if (!loading && adapterTotalItemCount <= (lastVisibleItem + visibleThreshold) &&
adapterTotalItemCount < totalItemCount) {
Log.v(TAG, "start load more task...");
// End has been reached
// Do something
lazyList.add(null);
notifyItemInserted(lazyList.size() - 1);
new LoadMoreItemsAsyncTask().execute();
loading = true;
}
}
});
}
}
@Subscribe
public void onEvent(UpdatePodcastStatusEvent podcast) {
if (podcast.isPlaying()) {
if (podcast.getRssItemId() != idOfCurrentlyPlayedPodcast) {
idOfCurrentlyPlayedPodcast = podcast.getRssItemId();
notifyDataSetChanged();
Log.v(TAG, "Updating Listview - Podcast started");
}
} else if (idOfCurrentlyPlayedPodcast != -1) {
idOfCurrentlyPlayedPodcast = -1;
notifyDataSetChanged();
Log.v(TAG, "Updating Listview - Podcast paused");
}
}
@Subscribe
public void onEvent(PodcastCompletedEvent podcastCompletedEvent) {
idOfCurrentlyPlayedPodcast = -1;
notifyDataSetChanged();
Log.v(TAG, "Updating Listview - Podcast completed");
}
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
if (viewType == VIEW_PROG) {
View v = LayoutInflater.from(parent.getContext()).inflate(
R.layout.progressbar_item, parent, false);
return new ProgressViewHolder(v);
} else {
SharedPreferences mPrefs = PreferenceManager.getDefaultSharedPreferences(activity);
Integer layout = 0;
switch (Integer.parseInt(mPrefs.getString(SettingsActivity.SP_FEED_LIST_LAYOUT, "0"))) {
case 0:
layout = R.layout.subscription_detail_list_item_simple;
break;
case 1:
layout = R.layout.subscription_detail_list_item_extended;
break;
case 3:
layout = R.layout.subscription_detail_list_item_extended;
break;
case 2:
layout = R.layout.subscription_detail_list_item_extended_webview;
break;
}
View view = LayoutInflater.from(parent.getContext()).inflate(layout, parent, false);
final ViewHolder holder = new ViewHolder(view, titleLineCount);
holder.starImageView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
toggleStarredStateOfItem(holder);
}
});
return holder;
}
}
@Override
public void onBindViewHolder(final RecyclerView.ViewHolder viewHolder, int position) {
if(viewHolder instanceof ProgressViewHolder) {
((ProgressViewHolder) viewHolder).progressBar.setIndeterminate(true);
} else {
final ViewHolder holder = (ViewHolder) viewHolder;
RssItem item = lazyList.get(position);
holder.setRssItem(item);
holder.setStayUnread(stayUnreadItems.contains(item.getId()));
holder.setClickListener((RecyclerItemClickListener) activity);
//Podcast stuff
if (DatabaseConnectionOrm.ALLOWED_PODCASTS_TYPES.contains(item.getEnclosureMime())) {
final boolean isPlaying = idOfCurrentlyPlayedPodcast == item.getId();
//Enable podcast buttons in view
holder.flPlayPausePodcastWrapper.setVisibility(View.VISIBLE);
holder.setPlaying(isPlaying);
holder.setDownloadPodcastProgressbar();
holder.flPlayPausePodcastWrapper.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (holder.isPlaying()) {
playPausePodcastClicked.pausePodcast();
} else {
playPausePodcastClicked.openPodcast(holder.getRssItem());
}
}
});
} else {
holder.flPlayPausePodcastWrapper.setVisibility(View.GONE);
}
}
}
@Override
public void onViewDetachedFromWindow(RecyclerView.ViewHolder holder) {
if(holder instanceof ViewHolder)
EventBus.getDefault().unregister(holder);
}
@Override
public void onViewAttachedToWindow(RecyclerView.ViewHolder holder) {
if(holder instanceof ViewHolder)
EventBus.getDefault().register(holder);
}
public void ChangeReadStateOfItem(ViewHolder viewHolder, boolean isChecked) {
RssItem rssItem = viewHolder.getRssItem();
if (rssItem.getRead_temp() != isChecked) { //Only perform database operations if really needed
rssItem.setRead_temp(isChecked);
dbConn.updateRssItem(rssItem);
pDelayHandler.DelayTimer();
viewHolder.setReadState(isChecked);
//notifyItemChanged(viewHolder.getAdapterPosition());
stayUnreadItems.add(rssItem.getId());
}
}
public void toggleReadStateOfItem(ViewHolder viewHolder) {
RssItem rssItem = viewHolder.getRssItem();
boolean isRead = !rssItem.getRead_temp();
ChangeReadStateOfItem(viewHolder, isRead);
}
public void toggleStarredStateOfItem(ViewHolder viewHolder) {
RssItem rssItem = viewHolder.getRssItem();
boolean isStarred = !rssItem.getStarred_temp();
rssItem.setStarred_temp(isStarred);
if (isStarred) {
ChangeReadStateOfItem(viewHolder, true);
} else {
dbConn.updateRssItem(rssItem);
pDelayHandler.DelayTimer();
}
viewHolder.setStarred(isStarred);
}
@Override
public int getItemViewType(int position) {
return lazyList.get(position) != null ? VIEW_ITEM : VIEW_PROG; //(position < (cachedPages * DatabaseConnectionOrm.PageSize)) ? VIEW_ITEM : VIEW_PROG;
}
@Override
public int getItemCount() {
//return totalItemCount;
return lazyList != null ? lazyList.size() : 0;
}
@Override
public long getItemId(int position) {
if (lazyList != null) {
RssItem item = lazyList.get(position);
return item != null ? item.getId() : 0;
}
return 0;
}
private List<RssItem> refreshAdapterData() {
List<RssItem> rssItems = new ArrayList<>();
DatabaseConnectionOrm dbConn = new DatabaseConnectionOrm(activity);
for(int i = 0; i < cachedPages; i++) {
rssItems.addAll(dbConn.getCurrentRssItemView(i));
}
return rssItems;
}
public void updateAdapterData(List<RssItem> rssItems) {
cachedPages = 1;
if (this.lazyList != null) {
//this.lazyList.close();
}
//new ReloadAdapterAsyncTask().execute();
totalItemCount = ((Long) dbConn.getCurrentRssItemViewCount()).intValue();
lazyList = rssItems;
notifyDataSetChanged();
loading = false;
}
public interface IOnRefreshFinished {
void OnRefreshFinished();
}
public void refreshAdapterDataAsync(IOnRefreshFinished listener) {
AsyncTaskHelper.StartAsyncTask(new RefreshDataAsyncTask(listener));
}
private class RefreshDataAsyncTask extends AsyncTask<Void, Void, List<RssItem>> {
private IOnRefreshFinished listener;
public RefreshDataAsyncTask(IOnRefreshFinished listener) {
this.listener = listener;
}
@Override
protected void onPreExecute() {
loading = true;
super.onPreExecute();
}
@Override
protected List<RssItem> doInBackground(Void... params) {
StopWatch sw = new StopWatch();
sw.start();
List<RssItem> rssItems = refreshAdapterData();
sw.stop();
Log.v(TAG, "Time needed (refreshing adapter): " + sw.toString());
return rssItems;
}
@Override
protected void onPostExecute(List<RssItem> rssItems) {
lazyList = rssItems;
notifyDataSetChanged();
loading = false;
listener.OnRefreshFinished();
super.onPostExecute(rssItems);
}
}
private class LoadMoreItemsAsyncTask extends AsyncTask<Void, Void, List<RssItem>> {
@Override
protected List<RssItem> doInBackground(Void... params) {
StopWatch sw = new StopWatch();
sw.start();
DatabaseConnectionOrm dbConn = new DatabaseConnectionOrm(activity);
List<RssItem> items = dbConn.getCurrentRssItemView(cachedPages++);
/*
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}*/
sw.stop();
Log.v(TAG, "Time needed (loading more): " + sw.toString());
return items;
}
@Override
protected void onPostExecute(List<RssItem> rssItems) {
int prevSize = lazyList.size();
lazyList.remove(prevSize - 1);
lazyList.addAll(rssItems);
notifyItemRangeInserted(prevSize, rssItems.size());
loading = false;
super.onPostExecute(rssItems);
}
}
private class ReloadAdapterAsyncTask extends AsyncTask<Void, Void, CurrentRssViewDataHolder> {
@Override
protected CurrentRssViewDataHolder doInBackground(Void... params) {
StopWatch sw = new StopWatch();
sw.start();
List<RssItem> list = dbConn.getCurrentRssItemView(0);
CurrentRssViewDataHolder holder = new CurrentRssViewDataHolder();
holder.maxCount = dbConn.getCurrentRssItemViewCount();
holder.rssItems = list;
sw.stop();
Log.v(TAG, "Reloaded CurrentRssView - time taken: " + sw.toString());
return holder;
}
@Override
protected void onPostExecute(CurrentRssViewDataHolder holder) {
lazyList = holder.rssItems;
totalItemCount = holder.maxCount.intValue();
cachedPages = 1;
notifyDataSetChanged();
}
}
}