now we have 'All Episodes' and 'New Episodes'
This commit is contained in:
parent
09bd600f5c
commit
78768ae9d9
|
@ -73,6 +73,12 @@ public class MainActivityTest extends ActivityInstrumentationTestCase2<MainActiv
|
||||||
|
|
||||||
// all episodes
|
// all episodes
|
||||||
openNavDrawer();
|
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.clickOnText(solo.getString(R.string.new_episodes_label));
|
||||||
solo.waitForView(android.R.id.list);
|
solo.waitForView(android.R.id.list);
|
||||||
assertEquals(solo.getString(R.string.new_episodes_label), getActionbarTitle());
|
assertEquals(solo.getString(R.string.new_episodes_label), getActionbarTitle());
|
||||||
|
|
|
@ -79,7 +79,7 @@ public class PlaybackTest extends ActivityInstrumentationTestCase2<MainActivity>
|
||||||
private void startLocalPlayback() {
|
private void startLocalPlayback() {
|
||||||
assertTrue(solo.waitForActivity(MainActivity.class));
|
assertTrue(solo.waitForActivity(MainActivity.class));
|
||||||
openNavDrawer();
|
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.waitForView(android.R.id.list);
|
||||||
solo.clickOnView(solo.getView(R.id.butSecondaryAction));
|
solo.clickOnView(solo.getView(R.id.butSecondaryAction));
|
||||||
assertTrue(solo.waitForActivity(AudioplayerActivity.class));
|
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.storage.DBReader;
|
||||||
import de.danoeh.antennapod.core.util.StorageUtils;
|
import de.danoeh.antennapod.core.util.StorageUtils;
|
||||||
import de.danoeh.antennapod.fragment.AddFeedFragment;
|
import de.danoeh.antennapod.fragment.AddFeedFragment;
|
||||||
|
import de.danoeh.antennapod.fragment.EpisodesFragment;
|
||||||
import de.danoeh.antennapod.fragment.DownloadsFragment;
|
import de.danoeh.antennapod.fragment.DownloadsFragment;
|
||||||
import de.danoeh.antennapod.fragment.ExternalPlayerFragment;
|
import de.danoeh.antennapod.fragment.ExternalPlayerFragment;
|
||||||
import de.danoeh.antennapod.fragment.ItemlistFragment;
|
import de.danoeh.antennapod.fragment.ItemlistFragment;
|
||||||
|
@ -68,9 +69,10 @@ public class MainActivity extends ActionBarActivity implements NavDrawerActivity
|
||||||
|
|
||||||
public static final int POS_QUEUE = 0,
|
public static final int POS_QUEUE = 0,
|
||||||
POS_NEW = 1,
|
POS_NEW = 1,
|
||||||
POS_DOWNLOADS = 2,
|
POS_ALL_EPISODES = 2,
|
||||||
POS_HISTORY = 3,
|
POS_DOWNLOADS = 3,
|
||||||
POS_ADD = 4;
|
POS_HISTORY = 4,
|
||||||
|
POS_ADD = 5;
|
||||||
|
|
||||||
private Toolbar toolbar;
|
private Toolbar toolbar;
|
||||||
private ExternalPlayerFragment externalPlayerFragment;
|
private ExternalPlayerFragment externalPlayerFragment;
|
||||||
|
@ -211,6 +213,9 @@ public class MainActivity extends ActionBarActivity implements NavDrawerActivity
|
||||||
case POS_NEW:
|
case POS_NEW:
|
||||||
fragment = new NewEpisodesFragment();
|
fragment = new NewEpisodesFragment();
|
||||||
break;
|
break;
|
||||||
|
case POS_ALL_EPISODES:
|
||||||
|
fragment = new EpisodesFragment();
|
||||||
|
break;
|
||||||
case POS_QUEUE:
|
case POS_QUEUE:
|
||||||
fragment = new QueueFragment();
|
fragment = new QueueFragment();
|
||||||
break;
|
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_SECTION_DIVIDER = 1;
|
||||||
public static final int VIEW_TYPE_SUBSCRIPTION = 2;
|
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;
|
private final Drawable[] drawables;
|
||||||
|
|
||||||
|
@ -38,10 +44,16 @@ public class NavListAdapter extends BaseAdapter {
|
||||||
this.itemAccess = itemAccess;
|
this.itemAccess = itemAccess;
|
||||||
this.context = context;
|
this.context = context;
|
||||||
|
|
||||||
TypedArray ta = context.obtainStyledAttributes(new int[]{R.attr.stat_playlist, R.attr.ic_new,
|
TypedArray ta = context.obtainStyledAttributes(new int[]{
|
||||||
R.attr.av_download, R.attr.ic_history, R.attr.content_new});
|
R.attr.stat_playlist,
|
||||||
|
// TODO: wouldn't be bad to have a different icon for all/new episodes
|
||||||
|
R.attr.ic_new,
|
||||||
|
R.attr.ic_new,
|
||||||
|
R.attr.av_download,
|
||||||
|
R.attr.ic_history,
|
||||||
|
R.attr.content_new});
|
||||||
drawables = new Drawable[]{ta.getDrawable(0), ta.getDrawable(1), ta.getDrawable(2),
|
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();
|
ta.recycle();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
package de.danoeh.antennapod.adapter;
|
package de.danoeh.antennapod.adapter;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.graphics.Color;
|
|
||||||
import android.text.format.DateUtils;
|
import android.text.format.DateUtils;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
|
@ -12,11 +11,9 @@ import android.widget.ImageView;
|
||||||
import android.widget.ProgressBar;
|
import android.widget.ProgressBar;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
import com.nineoldandroids.view.ViewHelper;
|
|
||||||
import com.squareup.picasso.Picasso;
|
import com.squareup.picasso.Picasso;
|
||||||
|
|
||||||
import de.danoeh.antennapod.R;
|
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.FeedItem;
|
||||||
import de.danoeh.antennapod.core.feed.FeedMedia;
|
import de.danoeh.antennapod.core.feed.FeedMedia;
|
||||||
import de.danoeh.antennapod.core.storage.DownloadRequester;
|
import de.danoeh.antennapod.core.storage.DownloadRequester;
|
||||||
|
@ -142,13 +139,6 @@ public class NewEpisodesListAdapter extends BaseAdapter {
|
||||||
.fit()
|
.fit()
|
||||||
.into(holder.imageView);
|
.into(holder.imageView);
|
||||||
|
|
||||||
if (item.isRead()) {
|
|
||||||
// grey it out
|
|
||||||
ViewHelper.setAlpha(convertView, .2f);
|
|
||||||
} else {
|
|
||||||
ViewHelper.setAlpha(convertView, 1.0f);
|
|
||||||
}
|
|
||||||
|
|
||||||
return convertView;
|
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.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
|
||||||
|
*/
|
||||||
|
public class EpisodesFragment extends Fragment {
|
||||||
|
private static final String TAG = "EpisodesFragment";
|
||||||
|
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 = "PrefEpisodesFragment";
|
||||||
|
private static final String PREF_KEY_LIST_TOP = "list_top";
|
||||||
|
private static final String PREF_KEY_LIST_SELECTION = "list_selection";
|
||||||
|
|
||||||
|
private String prefName;
|
||||||
|
private 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 EpisodesFragment() {
|
||||||
|
// 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 EpisodesFragment(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.episodes_fragment);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected View onCreateViewHelper(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState, int fragmentResource) {
|
||||||
|
super.onCreateView(inflater, container, savedInstanceState);
|
||||||
|
((MainActivity) getActivity()).getSupportActionBar().setTitle(R.string.new_episodes_label);
|
||||||
|
|
||||||
|
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) {
|
||||||
|
EpisodesFragment.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,285 +1,46 @@
|
||||||
package de.danoeh.antennapod.fragment;
|
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.Bundle;
|
||||||
import android.os.Handler;
|
|
||||||
import android.os.Parcelable;
|
import android.os.Parcelable;
|
||||||
import android.support.v4.app.Fragment;
|
|
||||||
import android.support.v7.widget.SearchView;
|
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.Menu;
|
|
||||||
import android.view.MenuInflater;
|
|
||||||
import android.view.MenuItem;
|
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
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 com.mobeta.android.dslv.DragSortListView;
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.concurrent.atomic.AtomicReference;
|
|
||||||
|
|
||||||
import de.danoeh.antennapod.R;
|
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.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.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.FeedItemUndoToken;
|
||||||
import de.danoeh.antennapod.core.util.gui.UndoBarController;
|
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 EpisodesFragment {
|
||||||
|
|
||||||
private static final String TAG = "NewEpisodesFragment";
|
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_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 UndoBarController undoBarController;
|
||||||
|
|
||||||
private List<FeedItem> unreadItems;
|
public NewEpisodesFragment() {
|
||||||
private List<FeedItem> recentItems;
|
super(true, PREF_NAME);
|
||||||
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();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onResume() {
|
protected void resetViewState() {
|
||||||
super.onResume();
|
super.resetViewState();
|
||||||
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;
|
|
||||||
undoBarController = null;
|
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
|
@Override
|
||||||
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
|
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
|
||||||
super.onCreateView(inflater, container, savedInstanceState);
|
View root = super.onCreateViewHelper(inflater, container, savedInstanceState, R.layout.new_episodes_fragment);
|
||||||
((MainActivity) getActivity()).getSupportActionBar().setTitle(R.string.new_episodes_label);
|
|
||||||
|
|
||||||
View root = inflater.inflate(R.layout.new_episodes_fragment, container, false);
|
final DragSortListView listView = (DragSortListView) root.findViewById(android.R.id.list);
|
||||||
|
|
||||||
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()));
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
listView.setRemoveListener(new DragSortListView.RemoveListener() {
|
listView.setRemoveListener(new DragSortListView.RemoveListener() {
|
||||||
@Override
|
@Override
|
||||||
|
@ -307,191 +68,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;
|
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"
|
custom:showAsAction="collapseActionView"
|
||||||
android:icon="?attr/navigation_accept"/>
|
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>
|
</menu>
|
Loading…
Reference in New Issue