Merge pull request #748 from TomHennen/new_and_all_episodes
New and all episodes fixes AntennaPod/AntennaPod#741 and fixes AntennaPod/AntennaPod#742
This commit is contained in:
commit
beabcf4302
|
@ -73,6 +73,12 @@ public class MainActivityTest extends ActivityInstrumentationTestCase2<MainActiv
|
|||
|
||||
// all episodes
|
||||
openNavDrawer();
|
||||
solo.clickOnText(solo.getString(R.string.all_episodes_label));
|
||||
solo.waitForView(android.R.id.list);
|
||||
assertEquals(solo.getString(R.string.all_episodes_label), getActionbarTitle());
|
||||
|
||||
// new episodes
|
||||
openNavDrawer();
|
||||
solo.clickOnText(solo.getString(R.string.new_episodes_label));
|
||||
solo.waitForView(android.R.id.list);
|
||||
assertEquals(solo.getString(R.string.new_episodes_label), getActionbarTitle());
|
||||
|
|
|
@ -79,7 +79,7 @@ public class PlaybackTest extends ActivityInstrumentationTestCase2<MainActivity>
|
|||
private void startLocalPlayback() {
|
||||
assertTrue(solo.waitForActivity(MainActivity.class));
|
||||
openNavDrawer();
|
||||
solo.clickOnText(solo.getString(R.string.new_episodes_label));
|
||||
solo.clickOnText(solo.getString(R.string.all_episodes_label));
|
||||
solo.waitForView(android.R.id.list);
|
||||
solo.clickOnView(solo.getView(R.id.butSecondaryAction));
|
||||
assertTrue(solo.waitForActivity(AudioplayerActivity.class));
|
||||
|
|
|
@ -34,6 +34,7 @@ import de.danoeh.antennapod.core.preferences.UserPreferences;
|
|||
import de.danoeh.antennapod.core.storage.DBReader;
|
||||
import de.danoeh.antennapod.core.util.StorageUtils;
|
||||
import de.danoeh.antennapod.fragment.AddFeedFragment;
|
||||
import de.danoeh.antennapod.fragment.AllEpisodesFragment;
|
||||
import de.danoeh.antennapod.fragment.DownloadsFragment;
|
||||
import de.danoeh.antennapod.fragment.ExternalPlayerFragment;
|
||||
import de.danoeh.antennapod.fragment.ItemlistFragment;
|
||||
|
@ -69,9 +70,10 @@ public class MainActivity extends ActionBarActivity implements NavDrawerActivity
|
|||
|
||||
public static final int POS_QUEUE = 0,
|
||||
POS_NEW = 1,
|
||||
POS_DOWNLOADS = 2,
|
||||
POS_HISTORY = 3,
|
||||
POS_ADD = 4;
|
||||
POS_ALL_EPISODES = 2,
|
||||
POS_DOWNLOADS = 3,
|
||||
POS_HISTORY = 4,
|
||||
POS_ADD = 5;
|
||||
|
||||
private Toolbar toolbar;
|
||||
private ExternalPlayerFragment externalPlayerFragment;
|
||||
|
@ -224,6 +226,9 @@ public class MainActivity extends ActionBarActivity implements NavDrawerActivity
|
|||
case POS_NEW:
|
||||
fragment = new NewEpisodesFragment();
|
||||
break;
|
||||
case POS_ALL_EPISODES:
|
||||
fragment = new AllEpisodesFragment();
|
||||
break;
|
||||
case POS_QUEUE:
|
||||
fragment = new QueueFragment();
|
||||
break;
|
||||
|
|
|
@ -25,7 +25,13 @@ public class NavListAdapter extends BaseAdapter {
|
|||
public static final int VIEW_TYPE_SECTION_DIVIDER = 1;
|
||||
public static final int VIEW_TYPE_SUBSCRIPTION = 2;
|
||||
|
||||
public static final int[] NAV_TITLES = {R.string.queue_label, R.string.new_episodes_label, R.string.downloads_label, R.string.playback_history_label, R.string.add_feed_label};
|
||||
public static final int[] NAV_TITLES = {
|
||||
R.string.queue_label,
|
||||
R.string.new_episodes_label,
|
||||
R.string.all_episodes_label,
|
||||
R.string.downloads_label,
|
||||
R.string.playback_history_label,
|
||||
R.string.add_feed_label};
|
||||
|
||||
private final Drawable[] drawables;
|
||||
|
||||
|
@ -38,10 +44,15 @@ public class NavListAdapter extends BaseAdapter {
|
|||
this.itemAccess = itemAccess;
|
||||
this.context = context;
|
||||
|
||||
TypedArray ta = context.obtainStyledAttributes(new int[]{R.attr.stat_playlist, R.attr.ic_new,
|
||||
R.attr.av_download, R.attr.ic_history, R.attr.content_new});
|
||||
TypedArray ta = context.obtainStyledAttributes(new int[]{
|
||||
R.attr.stat_playlist,
|
||||
R.attr.ic_new,
|
||||
R.attr.feed,
|
||||
R.attr.av_download,
|
||||
R.attr.ic_history,
|
||||
R.attr.content_new});
|
||||
drawables = new Drawable[]{ta.getDrawable(0), ta.getDrawable(1), ta.getDrawable(2),
|
||||
ta.getDrawable(3), ta.getDrawable(4)};
|
||||
ta.getDrawable(3), ta.getDrawable(4), ta.getDrawable(5)};
|
||||
ta.recycle();
|
||||
}
|
||||
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
package de.danoeh.antennapod.adapter;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Color;
|
||||
import android.text.format.DateUtils;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
|
@ -12,11 +11,9 @@ import android.widget.ImageView;
|
|||
import android.widget.ProgressBar;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.nineoldandroids.view.ViewHelper;
|
||||
import com.squareup.picasso.Picasso;
|
||||
|
||||
import de.danoeh.antennapod.R;
|
||||
import de.danoeh.antennapod.core.feed.EventDistributor;
|
||||
import de.danoeh.antennapod.core.feed.FeedItem;
|
||||
import de.danoeh.antennapod.core.feed.FeedMedia;
|
||||
import de.danoeh.antennapod.core.storage.DownloadRequester;
|
||||
|
@ -142,13 +139,6 @@ public class NewEpisodesListAdapter extends BaseAdapter {
|
|||
.fit()
|
||||
.into(holder.imageView);
|
||||
|
||||
if (item.isRead()) {
|
||||
// grey it out
|
||||
ViewHelper.setAlpha(convertView, .2f);
|
||||
} else {
|
||||
ViewHelper.setAlpha(convertView, 1.0f);
|
||||
}
|
||||
|
||||
return convertView;
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,457 @@
|
|||
package de.danoeh.antennapod.fragment;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.SharedPreferences;
|
||||
import android.os.AsyncTask;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.support.v4.app.Fragment;
|
||||
import android.support.v7.widget.SearchView;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuInflater;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.AdapterView;
|
||||
import android.widget.ProgressBar;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.mobeta.android.dslv.DragSortListView;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
import de.danoeh.antennapod.R;
|
||||
import de.danoeh.antennapod.activity.MainActivity;
|
||||
import de.danoeh.antennapod.adapter.DefaultActionButtonCallback;
|
||||
import de.danoeh.antennapod.adapter.NewEpisodesListAdapter;
|
||||
import de.danoeh.antennapod.core.asynctask.DownloadObserver;
|
||||
import de.danoeh.antennapod.core.dialog.ConfirmationDialog;
|
||||
import de.danoeh.antennapod.core.feed.EventDistributor;
|
||||
import de.danoeh.antennapod.core.feed.Feed;
|
||||
import de.danoeh.antennapod.core.feed.FeedItem;
|
||||
import de.danoeh.antennapod.core.feed.FeedMedia;
|
||||
import de.danoeh.antennapod.core.service.download.DownloadService;
|
||||
import de.danoeh.antennapod.core.service.download.Downloader;
|
||||
import de.danoeh.antennapod.core.storage.DBReader;
|
||||
import de.danoeh.antennapod.core.storage.DBTasks;
|
||||
import de.danoeh.antennapod.core.storage.DBWriter;
|
||||
import de.danoeh.antennapod.core.storage.DownloadRequester;
|
||||
import de.danoeh.antennapod.core.util.QueueAccess;
|
||||
import de.danoeh.antennapod.menuhandler.MenuItemUtils;
|
||||
import de.danoeh.antennapod.menuhandler.NavDrawerActivity;
|
||||
|
||||
/**
|
||||
* Shows unread or recently published episodes
|
||||
*/
|
||||
public class AllEpisodesFragment extends Fragment {
|
||||
private static final String TAG = "AllEpisodesFragment";
|
||||
private static final int EVENTS = EventDistributor.DOWNLOAD_HANDLED |
|
||||
EventDistributor.DOWNLOAD_QUEUED |
|
||||
EventDistributor.QUEUE_UPDATE |
|
||||
EventDistributor.UNREAD_ITEMS_UPDATE |
|
||||
EventDistributor.PLAYER_STATUS_UPDATE;
|
||||
|
||||
private static final int RECENT_EPISODES_LIMIT = 150;
|
||||
private static final String DEFAULT_PREF_NAME = "PrefAllEpisodesFragment";
|
||||
private static final String PREF_KEY_LIST_TOP = "list_top";
|
||||
private static final String PREF_KEY_LIST_SELECTION = "list_selection";
|
||||
|
||||
private String prefName;
|
||||
protected DragSortListView listView;
|
||||
private NewEpisodesListAdapter listAdapter;
|
||||
private TextView txtvEmpty;
|
||||
private ProgressBar progLoading;
|
||||
|
||||
private List<FeedItem> unreadItems;
|
||||
private List<FeedItem> recentItems;
|
||||
private QueueAccess queueAccess;
|
||||
private List<Downloader> downloaderList;
|
||||
|
||||
private boolean itemsLoaded = false;
|
||||
private boolean viewsCreated = false;
|
||||
private boolean showOnlyNewEpisodes = false;
|
||||
|
||||
private AtomicReference<MainActivity> activity = new AtomicReference<MainActivity>();
|
||||
|
||||
private DownloadObserver downloadObserver = null;
|
||||
|
||||
private boolean isUpdatingFeeds;
|
||||
|
||||
public AllEpisodesFragment() {
|
||||
// by default we show all the episodes
|
||||
this(false, DEFAULT_PREF_NAME);
|
||||
}
|
||||
|
||||
// this is only going to be called by our sub-class.
|
||||
// The Android docs say to avoid non-default constructors
|
||||
// but I think this will be OK since it will only be invoked
|
||||
// from a fragment via a default constructor
|
||||
protected AllEpisodesFragment(boolean showOnlyNewEpisodes, String prefName) {
|
||||
this.showOnlyNewEpisodes = showOnlyNewEpisodes;
|
||||
this.prefName = prefName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setRetainInstance(true);
|
||||
setHasOptionsMenu(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
startItemLoader();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStart() {
|
||||
super.onStart();
|
||||
EventDistributor.getInstance().register(contentUpdate);
|
||||
this.activity.set((MainActivity) getActivity());
|
||||
if (downloadObserver != null) {
|
||||
downloadObserver.setActivity(getActivity());
|
||||
downloadObserver.onResume();
|
||||
}
|
||||
if (viewsCreated && itemsLoaded) {
|
||||
onFragmentLoaded();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPause() {
|
||||
super.onPause();
|
||||
saveScrollPosition();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStop() {
|
||||
super.onStop();
|
||||
EventDistributor.getInstance().unregister(contentUpdate);
|
||||
stopItemLoader();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAttach(Activity activity) {
|
||||
super.onAttach(activity);
|
||||
this.activity.set((MainActivity) getActivity());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroyView() {
|
||||
super.onDestroyView();
|
||||
resetViewState();
|
||||
}
|
||||
|
||||
private void saveScrollPosition() {
|
||||
SharedPreferences prefs = getActivity().getSharedPreferences(prefName, Context.MODE_PRIVATE);
|
||||
SharedPreferences.Editor editor = prefs.edit();
|
||||
View v = listView.getChildAt(0);
|
||||
int top = (v == null) ? 0 : (v.getTop() - listView.getPaddingTop());
|
||||
editor.putInt(PREF_KEY_LIST_SELECTION, listView.getFirstVisiblePosition());
|
||||
editor.putInt(PREF_KEY_LIST_TOP, top);
|
||||
editor.commit();
|
||||
}
|
||||
|
||||
private void restoreScrollPosition() {
|
||||
SharedPreferences prefs = getActivity().getSharedPreferences(prefName, Context.MODE_PRIVATE);
|
||||
int listSelection = prefs.getInt(PREF_KEY_LIST_SELECTION, 0);
|
||||
int top = prefs.getInt(PREF_KEY_LIST_TOP, 0);
|
||||
if (listSelection > 0 || top > 0) {
|
||||
listView.setSelectionFromTop(listSelection, top);
|
||||
// restore once, then forget
|
||||
SharedPreferences.Editor editor = prefs.edit();
|
||||
editor.putInt(PREF_KEY_LIST_SELECTION, 0);
|
||||
editor.putInt(PREF_KEY_LIST_TOP, 0);
|
||||
editor.commit();
|
||||
}
|
||||
}
|
||||
|
||||
protected void resetViewState() {
|
||||
listAdapter = null;
|
||||
activity.set(null);
|
||||
viewsCreated = false;
|
||||
if (downloadObserver != null) {
|
||||
downloadObserver.onPause();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private final MenuItemUtils.UpdateRefreshMenuItemChecker updateRefreshMenuItemChecker = new MenuItemUtils.UpdateRefreshMenuItemChecker() {
|
||||
@Override
|
||||
public boolean isRefreshing() {
|
||||
return DownloadService.isRunning && DownloadRequester.getInstance().isDownloadingFeeds();
|
||||
}
|
||||
};
|
||||
|
||||
@Override
|
||||
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
|
||||
super.onCreateOptionsMenu(menu, inflater);
|
||||
if (itemsLoaded && !MenuItemUtils.isActivityDrawerOpen((NavDrawerActivity) getActivity())) {
|
||||
inflater.inflate(R.menu.new_episodes, menu);
|
||||
|
||||
final SearchView sv = new SearchView(getActivity());
|
||||
MenuItemUtils.addSearchItem(menu, sv);
|
||||
sv.setQueryHint(getString(R.string.search_hint));
|
||||
sv.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
|
||||
@Override
|
||||
public boolean onQueryTextSubmit(String s) {
|
||||
sv.clearFocus();
|
||||
((MainActivity) getActivity()).loadChildFragment(SearchFragment.newInstance(s));
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onQueryTextChange(String s) {
|
||||
return false;
|
||||
}
|
||||
});
|
||||
isUpdatingFeeds = MenuItemUtils.updateRefreshMenuItem(menu, R.id.refresh_item, updateRefreshMenuItemChecker);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPrepareOptionsMenu(Menu menu) {
|
||||
super.onPrepareOptionsMenu(menu);
|
||||
if (itemsLoaded && !MenuItemUtils.isActivityDrawerOpen((NavDrawerActivity) getActivity())) {
|
||||
menu.findItem(R.id.mark_all_read_item).setVisible(unreadItems != null && !unreadItems.isEmpty());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
if (!super.onOptionsItemSelected(item)) {
|
||||
switch (item.getItemId()) {
|
||||
case R.id.refresh_item:
|
||||
List<Feed> feeds = ((MainActivity) getActivity()).getFeeds();
|
||||
if (feeds != null) {
|
||||
DBTasks.refreshAllFeeds(getActivity(), feeds);
|
||||
}
|
||||
return true;
|
||||
case R.id.mark_all_read_item:
|
||||
ConfirmationDialog conDialog = new ConfirmationDialog(getActivity(),
|
||||
R.string.mark_all_read_label,
|
||||
R.string.mark_all_read_confirmation_msg) {
|
||||
|
||||
@Override
|
||||
public void onConfirmButtonPressed(
|
||||
DialogInterface dialog) {
|
||||
dialog.dismiss();
|
||||
DBWriter.markAllItemsRead(getActivity());
|
||||
Toast.makeText(getActivity(), R.string.mark_all_read_msg, Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
};
|
||||
conDialog.createNewDialog().show();
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
|
||||
return onCreateViewHelper(inflater, container, savedInstanceState,
|
||||
R.layout.all_episodes_fragment, R.string.all_episodes_label);
|
||||
}
|
||||
|
||||
protected View onCreateViewHelper(LayoutInflater inflater,
|
||||
ViewGroup container,
|
||||
Bundle savedInstanceState,
|
||||
int fragmentResource,
|
||||
int titleString) {
|
||||
super.onCreateView(inflater, container, savedInstanceState);
|
||||
((MainActivity) getActivity()).getSupportActionBar().setTitle(titleString);
|
||||
|
||||
View root = inflater.inflate(fragmentResource, container, false);
|
||||
|
||||
listView = (DragSortListView) root.findViewById(android.R.id.list);
|
||||
txtvEmpty = (TextView) root.findViewById(android.R.id.empty);
|
||||
progLoading = (ProgressBar) root.findViewById(R.id.progLoading);
|
||||
|
||||
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
|
||||
@Override
|
||||
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
|
||||
FeedItem item = (FeedItem) listAdapter.getItem(position - listView.getHeaderViewsCount());
|
||||
if (item != null) {
|
||||
((MainActivity) getActivity()).loadChildFragment(ItemFragment.newInstance(item.getId()));
|
||||
}
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
if (!itemsLoaded) {
|
||||
progLoading.setVisibility(View.VISIBLE);
|
||||
txtvEmpty.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
viewsCreated = true;
|
||||
|
||||
if (itemsLoaded && activity.get() != null) {
|
||||
onFragmentLoaded();
|
||||
}
|
||||
|
||||
return root;
|
||||
}
|
||||
|
||||
private void onFragmentLoaded() {
|
||||
if (listAdapter == null) {
|
||||
listAdapter = new NewEpisodesListAdapter(activity.get(), itemAccess, new DefaultActionButtonCallback(activity.get()));
|
||||
listView.setAdapter(listAdapter);
|
||||
listView.setEmptyView(txtvEmpty);
|
||||
downloadObserver = new DownloadObserver(activity.get(), new Handler(), downloadObserverCallback);
|
||||
downloadObserver.onResume();
|
||||
}
|
||||
listAdapter.notifyDataSetChanged();
|
||||
restoreScrollPosition();
|
||||
getActivity().supportInvalidateOptionsMenu();
|
||||
updateShowOnlyEpisodesListViewState();
|
||||
}
|
||||
|
||||
private DownloadObserver.Callback downloadObserverCallback = new DownloadObserver.Callback() {
|
||||
@Override
|
||||
public void onContentChanged() {
|
||||
if (listAdapter != null) {
|
||||
listAdapter.notifyDataSetChanged();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDownloadDataAvailable(List<Downloader> downloaderList) {
|
||||
AllEpisodesFragment.this.downloaderList = downloaderList;
|
||||
if (listAdapter != null) {
|
||||
listAdapter.notifyDataSetChanged();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
private NewEpisodesListAdapter.ItemAccess itemAccess = new NewEpisodesListAdapter.ItemAccess() {
|
||||
|
||||
@Override
|
||||
public int getCount() {
|
||||
if (itemsLoaded) {
|
||||
return (showOnlyNewEpisodes) ? unreadItems.size() : recentItems.size();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FeedItem getItem(int position) {
|
||||
if (itemsLoaded) {
|
||||
return (showOnlyNewEpisodes) ? unreadItems.get(position) : recentItems.get(position);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemDownloadProgressPercent(FeedItem item) {
|
||||
if (downloaderList != null) {
|
||||
for (Downloader downloader : downloaderList) {
|
||||
if (downloader.getDownloadRequest().getFeedfileType() == FeedMedia.FEEDFILETYPE_FEEDMEDIA
|
||||
&& downloader.getDownloadRequest().getFeedfileId() == item.getMedia().getId()) {
|
||||
return downloader.getDownloadRequest().getProgressPercent();
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isInQueue(FeedItem item) {
|
||||
if (itemsLoaded) {
|
||||
return queueAccess.contains(item.getId());
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
|
||||
private EventDistributor.EventListener contentUpdate = new EventDistributor.EventListener() {
|
||||
@Override
|
||||
public void update(EventDistributor eventDistributor, Integer arg) {
|
||||
if ((arg & EVENTS) != 0) {
|
||||
startItemLoader();
|
||||
if (isUpdatingFeeds != updateRefreshMenuItemChecker.isRefreshing()) {
|
||||
getActivity().supportInvalidateOptionsMenu();
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
private void updateShowOnlyEpisodesListViewState() {
|
||||
if (showOnlyNewEpisodes) {
|
||||
listView.setEmptyView(null);
|
||||
txtvEmpty.setVisibility(View.GONE);
|
||||
} else {
|
||||
listView.setEmptyView(txtvEmpty);
|
||||
}
|
||||
}
|
||||
|
||||
private ItemLoader itemLoader;
|
||||
|
||||
private void startItemLoader() {
|
||||
if (itemLoader != null) {
|
||||
itemLoader.cancel(true);
|
||||
}
|
||||
itemLoader = new ItemLoader();
|
||||
itemLoader.execute();
|
||||
}
|
||||
|
||||
protected void stopItemLoader() {
|
||||
if (itemLoader != null) {
|
||||
itemLoader.cancel(true);
|
||||
}
|
||||
}
|
||||
|
||||
private class ItemLoader extends AsyncTask<Void, Void, Object[]> {
|
||||
|
||||
@Override
|
||||
protected void onPreExecute() {
|
||||
super.onPreExecute();
|
||||
if (viewsCreated && !itemsLoaded) {
|
||||
listView.setVisibility(View.GONE);
|
||||
txtvEmpty.setVisibility(View.GONE);
|
||||
progLoading.setVisibility(View.VISIBLE);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Object[] doInBackground(Void... params) {
|
||||
Context context = activity.get();
|
||||
if (context != null) {
|
||||
return new Object[]{DBReader.getUnreadItemsList(context),
|
||||
DBReader.getRecentlyPublishedEpisodes(context, RECENT_EPISODES_LIMIT),
|
||||
QueueAccess.IDListAccess(DBReader.getQueueIDList(context))};
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(Object[] lists) {
|
||||
super.onPostExecute(lists);
|
||||
listView.setVisibility(View.VISIBLE);
|
||||
progLoading.setVisibility(View.GONE);
|
||||
|
||||
if (lists != null) {
|
||||
unreadItems = (List<FeedItem>) lists[0];
|
||||
recentItems = (List<FeedItem>) lists[1];
|
||||
queueAccess = (QueueAccess) lists[2];
|
||||
itemsLoaded = true;
|
||||
if (viewsCreated && activity.get() != null) {
|
||||
onFragmentLoaded();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,290 +1,50 @@
|
|||
package de.danoeh.antennapod.fragment;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.SharedPreferences;
|
||||
import android.os.AsyncTask;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.os.Parcelable;
|
||||
import android.support.v4.app.Fragment;
|
||||
import android.support.v7.widget.SearchView;
|
||||
import android.util.Log;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuInflater;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.AdapterView;
|
||||
import android.widget.ProgressBar;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.mobeta.android.dslv.DragSortListView;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
import de.danoeh.antennapod.R;
|
||||
import de.danoeh.antennapod.activity.MainActivity;
|
||||
import de.danoeh.antennapod.adapter.DefaultActionButtonCallback;
|
||||
import de.danoeh.antennapod.adapter.NewEpisodesListAdapter;
|
||||
import de.danoeh.antennapod.core.asynctask.DownloadObserver;
|
||||
import de.danoeh.antennapod.core.dialog.ConfirmationDialog;
|
||||
import de.danoeh.antennapod.core.feed.EventDistributor;
|
||||
import de.danoeh.antennapod.core.feed.Feed;
|
||||
import de.danoeh.antennapod.core.feed.FeedItem;
|
||||
import de.danoeh.antennapod.core.feed.FeedMedia;
|
||||
import de.danoeh.antennapod.core.preferences.UserPreferences;
|
||||
import de.danoeh.antennapod.core.service.download.DownloadService;
|
||||
import de.danoeh.antennapod.core.service.download.Downloader;
|
||||
import de.danoeh.antennapod.core.storage.DBReader;
|
||||
import de.danoeh.antennapod.core.storage.DBTasks;
|
||||
import de.danoeh.antennapod.core.storage.DBWriter;
|
||||
import de.danoeh.antennapod.core.storage.DownloadRequester;
|
||||
import de.danoeh.antennapod.core.util.QueueAccess;
|
||||
import de.danoeh.antennapod.core.util.gui.FeedItemUndoToken;
|
||||
import de.danoeh.antennapod.core.util.gui.UndoBarController;
|
||||
import de.danoeh.antennapod.menuhandler.MenuItemUtils;
|
||||
import de.danoeh.antennapod.menuhandler.NavDrawerActivity;
|
||||
|
||||
/**
|
||||
* Shows unread or recently published episodes
|
||||
* Like 'EpisodesFragment' except that it only shows new episodes and
|
||||
* supports swiping to mark as read.
|
||||
*/
|
||||
public class NewEpisodesFragment extends Fragment {
|
||||
public class NewEpisodesFragment extends AllEpisodesFragment {
|
||||
|
||||
private static final String TAG = "NewEpisodesFragment";
|
||||
private static final int EVENTS = EventDistributor.DOWNLOAD_HANDLED |
|
||||
EventDistributor.DOWNLOAD_QUEUED |
|
||||
EventDistributor.QUEUE_UPDATE |
|
||||
EventDistributor.UNREAD_ITEMS_UPDATE |
|
||||
EventDistributor.PLAYER_STATUS_UPDATE;
|
||||
|
||||
private static final int RECENT_EPISODES_LIMIT = 150;
|
||||
private static final String PREF_NAME = "PrefNewEpisodesFragment";
|
||||
private static final String PREF_EPISODE_FILTER_BOOL = "newEpisodeFilterEnabled";
|
||||
private static final String PREF_KEY_LIST_TOP = "list_top";
|
||||
private static final String PREF_KEY_LIST_SELECTION = "list_selection";
|
||||
|
||||
private DragSortListView listView;
|
||||
private NewEpisodesListAdapter listAdapter;
|
||||
private TextView txtvEmpty;
|
||||
private ProgressBar progLoading;
|
||||
|
||||
private UndoBarController undoBarController;
|
||||
|
||||
private List<FeedItem> unreadItems;
|
||||
private List<FeedItem> recentItems;
|
||||
private QueueAccess queueAccess;
|
||||
private List<Downloader> downloaderList;
|
||||
|
||||
private boolean itemsLoaded = false;
|
||||
private boolean viewsCreated = false;
|
||||
private boolean showOnlyNewEpisodes = false;
|
||||
|
||||
private AtomicReference<MainActivity> activity = new AtomicReference<MainActivity>();
|
||||
|
||||
private DownloadObserver downloadObserver = null;
|
||||
|
||||
private boolean isUpdatingFeeds;
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setRetainInstance(true);
|
||||
setHasOptionsMenu(true);
|
||||
|
||||
updateShowOnlyEpisodes();
|
||||
public NewEpisodesFragment() {
|
||||
super(true, PREF_NAME);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
startItemLoader();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStart() {
|
||||
super.onStart();
|
||||
EventDistributor.getInstance().register(contentUpdate);
|
||||
this.activity.set((MainActivity) getActivity());
|
||||
if (downloadObserver != null) {
|
||||
downloadObserver.setActivity(getActivity());
|
||||
downloadObserver.onResume();
|
||||
}
|
||||
if (viewsCreated && itemsLoaded) {
|
||||
onFragmentLoaded();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPause() {
|
||||
super.onPause();
|
||||
saveScrollPosition();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStop() {
|
||||
super.onStop();
|
||||
EventDistributor.getInstance().unregister(contentUpdate);
|
||||
stopItemLoader();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAttach(Activity activity) {
|
||||
super.onAttach(activity);
|
||||
this.activity.set((MainActivity) getActivity());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroyView() {
|
||||
super.onDestroyView();
|
||||
resetViewState();
|
||||
}
|
||||
|
||||
private void saveScrollPosition() {
|
||||
SharedPreferences prefs = getActivity().getSharedPreferences(PREF_NAME, Context.MODE_PRIVATE);
|
||||
SharedPreferences.Editor editor = prefs.edit();
|
||||
View v = listView.getChildAt(0);
|
||||
int top = (v == null) ? 0 : (v.getTop() - listView.getPaddingTop());
|
||||
editor.putInt(PREF_KEY_LIST_SELECTION, listView.getFirstVisiblePosition());
|
||||
editor.putInt(PREF_KEY_LIST_TOP, top);
|
||||
editor.commit();
|
||||
}
|
||||
|
||||
private void restoreScrollPosition() {
|
||||
SharedPreferences prefs = getActivity().getSharedPreferences(PREF_NAME, Context.MODE_PRIVATE);
|
||||
int listSelection = prefs.getInt(PREF_KEY_LIST_SELECTION, 0);
|
||||
int top = prefs.getInt(PREF_KEY_LIST_TOP, 0);
|
||||
if(listSelection > 0 || top > 0) {
|
||||
listView.setSelectionFromTop(listSelection, top);
|
||||
// restore once, then forget
|
||||
SharedPreferences.Editor editor = prefs.edit();
|
||||
editor.putInt(PREF_KEY_LIST_SELECTION, 0);
|
||||
editor.putInt(PREF_KEY_LIST_TOP, 0);
|
||||
editor.commit();
|
||||
}
|
||||
}
|
||||
|
||||
private void resetViewState() {
|
||||
listAdapter = null;
|
||||
activity.set(null);
|
||||
viewsCreated = false;
|
||||
protected void resetViewState() {
|
||||
super.resetViewState();
|
||||
undoBarController = null;
|
||||
if (downloadObserver != null) {
|
||||
downloadObserver.onPause();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private final MenuItemUtils.UpdateRefreshMenuItemChecker updateRefreshMenuItemChecker = new MenuItemUtils.UpdateRefreshMenuItemChecker() {
|
||||
@Override
|
||||
public boolean isRefreshing() {
|
||||
return DownloadService.isRunning && DownloadRequester.getInstance().isDownloadingFeeds();
|
||||
}
|
||||
};
|
||||
|
||||
@Override
|
||||
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
|
||||
super.onCreateOptionsMenu(menu, inflater);
|
||||
if (itemsLoaded && !MenuItemUtils.isActivityDrawerOpen((NavDrawerActivity) getActivity())) {
|
||||
inflater.inflate(R.menu.new_episodes, menu);
|
||||
|
||||
final SearchView sv = new SearchView(getActivity());
|
||||
MenuItemUtils.addSearchItem(menu, sv);
|
||||
sv.setQueryHint(getString(R.string.search_hint));
|
||||
sv.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
|
||||
@Override
|
||||
public boolean onQueryTextSubmit(String s) {
|
||||
sv.clearFocus();
|
||||
((MainActivity) getActivity()).loadChildFragment(SearchFragment.newInstance(s));
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onQueryTextChange(String s) {
|
||||
return false;
|
||||
}
|
||||
});
|
||||
isUpdatingFeeds = MenuItemUtils.updateRefreshMenuItem(menu, R.id.refresh_item, updateRefreshMenuItemChecker);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPrepareOptionsMenu(Menu menu) {
|
||||
super.onPrepareOptionsMenu(menu);
|
||||
if (itemsLoaded && !MenuItemUtils.isActivityDrawerOpen((NavDrawerActivity) getActivity())) {
|
||||
menu.findItem(R.id.mark_all_read_item).setVisible(unreadItems != null && !unreadItems.isEmpty());
|
||||
menu.findItem(R.id.episode_filter_item).setChecked(showOnlyNewEpisodes);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
if (!super.onOptionsItemSelected(item)) {
|
||||
switch (item.getItemId()) {
|
||||
case R.id.refresh_item:
|
||||
List<Feed> feeds = ((MainActivity) getActivity()).getFeeds();
|
||||
if (feeds != null) {
|
||||
DBTasks.refreshAllFeeds(getActivity(), feeds);
|
||||
}
|
||||
return true;
|
||||
case R.id.mark_all_read_item:
|
||||
ConfirmationDialog conDialog = new ConfirmationDialog(getActivity(),
|
||||
R.string.mark_all_read_label,
|
||||
R.string.mark_all_read_confirmation_msg) {
|
||||
|
||||
@Override
|
||||
public void onConfirmButtonPressed(
|
||||
DialogInterface dialog) {
|
||||
dialog.dismiss();
|
||||
DBWriter.markAllItemsRead(getActivity());
|
||||
Toast.makeText(getActivity(), R.string.mark_all_read_msg, Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
};
|
||||
conDialog.createNewDialog().show();
|
||||
return true;
|
||||
case R.id.episode_filter_item:
|
||||
boolean newVal = !item.isChecked();
|
||||
setShowOnlyNewEpisodes(newVal);
|
||||
item.setChecked(newVal);
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
|
||||
super.onCreateView(inflater, container, savedInstanceState);
|
||||
((MainActivity) getActivity()).getSupportActionBar().setTitle(R.string.new_episodes_label);
|
||||
|
||||
View root = inflater.inflate(R.layout.new_episodes_fragment, container, false);
|
||||
|
||||
listView = (DragSortListView) root.findViewById(android.R.id.list);
|
||||
txtvEmpty = (TextView) root.findViewById(android.R.id.empty);
|
||||
progLoading = (ProgressBar) root.findViewById(R.id.progLoading);
|
||||
|
||||
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
|
||||
@Override
|
||||
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
|
||||
FeedItem item = (FeedItem) listAdapter.getItem(position - listView.getHeaderViewsCount());
|
||||
if (item != null) {
|
||||
((MainActivity) getActivity()).loadChildFragment(ItemFragment.newInstance(item.getId()));
|
||||
}
|
||||
|
||||
}
|
||||
});
|
||||
View root = super.onCreateViewHelper(inflater, container, savedInstanceState,
|
||||
R.layout.new_episodes_fragment, R.string.new_episodes_label);
|
||||
|
||||
listView.setRemoveListener(new DragSortListView.RemoveListener() {
|
||||
@Override
|
||||
public void remove(int which) {
|
||||
Log.d(TAG, "remove("+which+")");
|
||||
Log.d(TAG, "remove(" + which + ")");
|
||||
stopItemLoader();
|
||||
FeedItem item = (FeedItem) listView.getAdapter().getItem(which);
|
||||
DBWriter.markItemRead(getActivity(), item.getId(), true);
|
||||
|
@ -307,191 +67,6 @@ public class NewEpisodesFragment extends Fragment {
|
|||
}
|
||||
}
|
||||
});
|
||||
|
||||
final int secondColor = (UserPreferences.getTheme() == R.style.Theme_AntennaPod_Dark) ? R.color.swipe_refresh_secondary_color_dark : R.color.swipe_refresh_secondary_color_light;
|
||||
|
||||
if (!itemsLoaded) {
|
||||
progLoading.setVisibility(View.VISIBLE);
|
||||
txtvEmpty.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
viewsCreated = true;
|
||||
|
||||
if (itemsLoaded && activity.get() != null) {
|
||||
onFragmentLoaded();
|
||||
}
|
||||
|
||||
return root;
|
||||
}
|
||||
|
||||
private void onFragmentLoaded() {
|
||||
if (listAdapter == null) {
|
||||
listAdapter = new NewEpisodesListAdapter(activity.get(), itemAccess, new DefaultActionButtonCallback(activity.get()));
|
||||
listView.setAdapter(listAdapter);
|
||||
listView.setEmptyView(txtvEmpty);
|
||||
downloadObserver = new DownloadObserver(activity.get(), new Handler(), downloadObserverCallback);
|
||||
downloadObserver.onResume();
|
||||
}
|
||||
listAdapter.notifyDataSetChanged();
|
||||
restoreScrollPosition();
|
||||
getActivity().supportInvalidateOptionsMenu();
|
||||
updateShowOnlyEpisodesListViewState();
|
||||
}
|
||||
|
||||
private DownloadObserver.Callback downloadObserverCallback = new DownloadObserver.Callback() {
|
||||
@Override
|
||||
public void onContentChanged() {
|
||||
if (listAdapter != null) {
|
||||
listAdapter.notifyDataSetChanged();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDownloadDataAvailable(List<Downloader> downloaderList) {
|
||||
NewEpisodesFragment.this.downloaderList = downloaderList;
|
||||
if (listAdapter != null) {
|
||||
listAdapter.notifyDataSetChanged();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
private NewEpisodesListAdapter.ItemAccess itemAccess = new NewEpisodesListAdapter.ItemAccess() {
|
||||
|
||||
@Override
|
||||
public int getCount() {
|
||||
if (itemsLoaded) {
|
||||
return (showOnlyNewEpisodes) ? unreadItems.size() : recentItems.size();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FeedItem getItem(int position) {
|
||||
if (itemsLoaded) {
|
||||
return (showOnlyNewEpisodes) ? unreadItems.get(position) : recentItems.get(position);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemDownloadProgressPercent(FeedItem item) {
|
||||
if (downloaderList != null) {
|
||||
for (Downloader downloader : downloaderList) {
|
||||
if (downloader.getDownloadRequest().getFeedfileType() == FeedMedia.FEEDFILETYPE_FEEDMEDIA
|
||||
&& downloader.getDownloadRequest().getFeedfileId() == item.getMedia().getId()) {
|
||||
return downloader.getDownloadRequest().getProgressPercent();
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isInQueue(FeedItem item) {
|
||||
if (itemsLoaded) {
|
||||
return queueAccess.contains(item.getId());
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
|
||||
private EventDistributor.EventListener contentUpdate = new EventDistributor.EventListener() {
|
||||
@Override
|
||||
public void update(EventDistributor eventDistributor, Integer arg) {
|
||||
if ((arg & EVENTS) != 0) {
|
||||
startItemLoader();
|
||||
if (isUpdatingFeeds != updateRefreshMenuItemChecker.isRefreshing()) {
|
||||
getActivity().supportInvalidateOptionsMenu();
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
private void updateShowOnlyEpisodes() {
|
||||
SharedPreferences prefs = getActivity().getSharedPreferences(PREF_NAME, Context.MODE_PRIVATE);
|
||||
showOnlyNewEpisodes = prefs.getBoolean(PREF_EPISODE_FILTER_BOOL, true);
|
||||
}
|
||||
|
||||
private void setShowOnlyNewEpisodes(boolean newVal) {
|
||||
showOnlyNewEpisodes = newVal;
|
||||
SharedPreferences prefs = getActivity().getSharedPreferences(PREF_NAME, Context.MODE_PRIVATE);
|
||||
SharedPreferences.Editor editor = prefs.edit();
|
||||
editor.putBoolean(PREF_EPISODE_FILTER_BOOL, showOnlyNewEpisodes);
|
||||
editor.commit();
|
||||
if (itemsLoaded && viewsCreated) {
|
||||
listAdapter.notifyDataSetChanged();
|
||||
activity.get().supportInvalidateOptionsMenu();
|
||||
updateShowOnlyEpisodesListViewState();
|
||||
}
|
||||
}
|
||||
|
||||
private void updateShowOnlyEpisodesListViewState() {
|
||||
if (showOnlyNewEpisodes) {
|
||||
listView.setEmptyView(null);
|
||||
txtvEmpty.setVisibility(View.GONE);
|
||||
} else {
|
||||
listView.setEmptyView(txtvEmpty);
|
||||
}
|
||||
}
|
||||
|
||||
private ItemLoader itemLoader;
|
||||
|
||||
private void startItemLoader() {
|
||||
if (itemLoader != null) {
|
||||
itemLoader.cancel(true);
|
||||
}
|
||||
itemLoader = new ItemLoader();
|
||||
itemLoader.execute();
|
||||
}
|
||||
|
||||
private void stopItemLoader() {
|
||||
if (itemLoader != null) {
|
||||
itemLoader.cancel(true);
|
||||
}
|
||||
}
|
||||
|
||||
private class ItemLoader extends AsyncTask<Void, Void, Object[]> {
|
||||
|
||||
@Override
|
||||
protected void onPreExecute() {
|
||||
super.onPreExecute();
|
||||
if (viewsCreated && !itemsLoaded) {
|
||||
listView.setVisibility(View.GONE);
|
||||
txtvEmpty.setVisibility(View.GONE);
|
||||
progLoading.setVisibility(View.VISIBLE);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Object[] doInBackground(Void... params) {
|
||||
Context context = activity.get();
|
||||
if (context != null) {
|
||||
return new Object[]{DBReader.getUnreadItemsList(context),
|
||||
DBReader.getRecentlyPublishedEpisodes(context, RECENT_EPISODES_LIMIT),
|
||||
QueueAccess.IDListAccess(DBReader.getQueueIDList(context))};
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(Object[] lists) {
|
||||
super.onPostExecute(lists);
|
||||
listView.setVisibility(View.VISIBLE);
|
||||
progLoading.setVisibility(View.GONE);
|
||||
|
||||
if (lists != null) {
|
||||
unreadItems = (List<FeedItem>) lists[0];
|
||||
recentItems = (List<FeedItem>) lists[1];
|
||||
queueAccess = (QueueAccess) lists[2];
|
||||
itemsLoaded = true;
|
||||
if (viewsCreated && activity.get() != null) {
|
||||
onFragmentLoaded();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,52 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:dslv="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:orientation="vertical"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<com.mobeta.android.dslv.DragSortListView
|
||||
android:id="@android:id/list"
|
||||
android:scrollbarStyle="outsideOverlay"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:paddingTop="@dimen/list_vertical_padding"
|
||||
android:paddingBottom="@dimen/list_vertical_padding"
|
||||
android:clipToPadding="false"
|
||||
dslv:collapsed_height="2dp"
|
||||
dslv:drag_enabled="false"
|
||||
dslv:drag_scroll_start="0.33"
|
||||
dslv:float_alpha="0.6"
|
||||
dslv:max_drag_scroll_speed="0.5"
|
||||
dslv:remove_enabled="true"
|
||||
dslv:remove_mode="flingRemove"
|
||||
dslv:slide_shuffle_speed="0.3"
|
||||
dslv:sort_enabled="false"
|
||||
dslv:track_drag_sort="false"
|
||||
dslv:float_background_color="?attr/dragview_float_background"
|
||||
dslv:use_default_controller="true"
|
||||
tools:background="@android:color/holo_green_dark"/>
|
||||
|
||||
<TextView
|
||||
android:id="@id/android:empty"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_gravity="center"
|
||||
android:gravity="center"
|
||||
android:text="@string/no_items_label"/>
|
||||
|
||||
<ProgressBar
|
||||
android:id="@+id/progLoading"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:indeterminateOnly="true"
|
||||
android:visibility="gone"
|
||||
tools:visibility="visible"
|
||||
tools:layout_width="match_parent"
|
||||
tools:layout_height="64dp"
|
||||
tools:background="@android:color/holo_red_light"/>
|
||||
|
||||
</FrameLayout>
|
|
@ -17,11 +17,4 @@
|
|||
custom:showAsAction="collapseActionView"
|
||||
android:icon="?attr/navigation_accept"/>
|
||||
|
||||
<item
|
||||
android:id="@+id/episode_filter_item"
|
||||
android:title="@string/episode_filter_label"
|
||||
android:menuCategory="container"
|
||||
android:checkable="true"
|
||||
custom:showAsAction="collapseActionView"/>
|
||||
|
||||
</menu>
|
|
@ -350,6 +350,19 @@ public class Feed extends FeedFile implements FlattrThing, PicassoImageResource
|
|||
return false;
|
||||
}
|
||||
|
||||
public FeedItem getMostRecentItem() {
|
||||
// we could sort, but we don't need to, a simple search is fine...
|
||||
Date mostRecentDate = new Date(0);
|
||||
FeedItem mostRecentItem = null;
|
||||
for (FeedItem item : items) {
|
||||
if (item.getPubDate().after(mostRecentDate)) {
|
||||
mostRecentDate = item.getPubDate();
|
||||
mostRecentItem = item;
|
||||
}
|
||||
}
|
||||
return mostRecentItem;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getTypeAsInt() {
|
||||
return FEEDFILETYPE_FEED;
|
||||
|
|
|
@ -560,7 +560,7 @@ public final class DBTasks {
|
|||
/**
|
||||
* Adds new Feeds to the database or updates the old versions if they already exists. If another Feed with the same
|
||||
* identifying value already exists, this method will add new FeedItems from the new Feed to the existing Feed.
|
||||
* These FeedItems will be marked as unread.
|
||||
* These FeedItems will be marked as unread with the exception of the most recent FeedItem.
|
||||
* <p/>
|
||||
* This method can update multiple feeds at once. Submitting a feed twice in the same method call can result in undefined behavior.
|
||||
* <p/>
|
||||
|
@ -586,12 +586,16 @@ public final class DBTasks {
|
|||
final Feed savedFeed = searchFeedByIdentifyingValueOrID(context, adapter,
|
||||
newFeed);
|
||||
if (savedFeed == null) {
|
||||
if (BuildConfig.DEBUG)
|
||||
Log.d(TAG,
|
||||
"Found no existing Feed with title "
|
||||
+ newFeed.getTitle() + ". Adding as new one."
|
||||
);
|
||||
Log.d(TAG, "Found no existing Feed with title "
|
||||
+ newFeed.getTitle() + ". Adding as new one.");
|
||||
|
||||
// Add a new Feed
|
||||
// all new feeds will have the most recent item marked as unplayed
|
||||
FeedItem mostRecent = newFeed.getMostRecentItem();
|
||||
if (mostRecent != null) {
|
||||
mostRecent.setRead(false);
|
||||
}
|
||||
|
||||
newFeedsList.add(newFeed);
|
||||
resultFeeds[feedIdx] = newFeed;
|
||||
} else {
|
||||
|
|
Loading…
Reference in New Issue