summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--app/src/androidTest/java/de/test/antennapod/dialogs/ShareDialogTest.java6
-rw-r--r--app/src/androidTest/java/de/test/antennapod/playback/PlaybackTest.java4
-rw-r--r--app/src/androidTest/java/de/test/antennapod/ui/NavigationDrawerTest.java4
-rw-r--r--app/src/androidTest/java/de/test/antennapod/ui/PreferencesTest.java4
-rw-r--r--app/src/main/java/de/danoeh/antennapod/activity/MainActivity.java8
-rw-r--r--app/src/main/java/de/danoeh/antennapod/adapter/NavListAdapter.java4
-rw-r--r--app/src/main/java/de/danoeh/antennapod/dialog/SwipeActionsDialog.java4
-rw-r--r--app/src/main/java/de/danoeh/antennapod/fragment/AllEpisodesFragment.java91
-rw-r--r--app/src/main/java/de/danoeh/antennapod/fragment/EpisodesFragment.java121
-rw-r--r--app/src/main/java/de/danoeh/antennapod/fragment/EpisodesListFragment.java174
-rw-r--r--app/src/main/java/de/danoeh/antennapod/fragment/FavoriteEpisodesFragment.java109
-rw-r--r--app/src/main/java/de/danoeh/antennapod/fragment/FeedItemlistFragment.java2
-rw-r--r--app/src/main/java/de/danoeh/antennapod/fragment/InboxFragment.java120
-rw-r--r--app/src/main/java/de/danoeh/antennapod/fragment/NavDrawerFragment.java4
-rw-r--r--app/src/main/java/de/danoeh/antennapod/fragment/PlaybackHistoryFragment.java118
-rw-r--r--app/src/main/java/de/danoeh/antennapod/fragment/swipeactions/SwipeActions.java4
-rw-r--r--app/src/main/res/layout/episodes_list_fragment.xml (renamed from app/src/main/res/layout/all_episodes_fragment.xml)9
-rw-r--r--app/src/main/res/layout/list_container_fragment.xml23
-rw-r--r--app/src/main/res/menu/episodes.xml10
-rw-r--r--model/src/main/java/de/danoeh/antennapod/model/feed/FeedItemFilter.java33
-rw-r--r--ui/i18n/src/main/res/values/strings.xml5
21 files changed, 265 insertions, 592 deletions
diff --git a/app/src/androidTest/java/de/test/antennapod/dialogs/ShareDialogTest.java b/app/src/androidTest/java/de/test/antennapod/dialogs/ShareDialogTest.java
index 3c32407a5..c68e13438 100644
--- a/app/src/androidTest/java/de/test/antennapod/dialogs/ShareDialogTest.java
+++ b/app/src/androidTest/java/de/test/antennapod/dialogs/ShareDialogTest.java
@@ -8,7 +8,7 @@ import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.platform.app.InstrumentationRegistry;
import de.danoeh.antennapod.R;
import de.danoeh.antennapod.activity.MainActivity;
-import de.danoeh.antennapod.fragment.EpisodesFragment;
+import de.danoeh.antennapod.fragment.AllEpisodesFragment;
import de.test.antennapod.EspressoTestUtils;
import de.test.antennapod.ui.UITestUtils;
import org.hamcrest.Matcher;
@@ -48,7 +48,7 @@ public class ShareDialogTest {
context = InstrumentationRegistry.getInstrumentation().getTargetContext();
EspressoTestUtils.clearPreferences();
EspressoTestUtils.clearDatabase();
- EspressoTestUtils.setLastNavFragment(EpisodesFragment.TAG);
+ EspressoTestUtils.setLastNavFragment(AllEpisodesFragment.TAG);
UITestUtils uiTestUtils = new UITestUtils(context);
uiTestUtils.setup();
uiTestUtils.addLocalFeedData(true);
@@ -57,8 +57,6 @@ public class ShareDialogTest {
openNavDrawer();
onDrawerItem(withText(R.string.episodes_label)).perform(click());
- onView(isRoot()).perform(waitForView(withText(R.string.all_episodes_short_label), 1000));
- onView(withText(R.string.all_episodes_short_label)).perform(click());
Matcher<View> allEpisodesMatcher;
allEpisodesMatcher = Matchers.allOf(withId(android.R.id.list), isDisplayed(), hasMinimumChildCount(2));
diff --git a/app/src/androidTest/java/de/test/antennapod/playback/PlaybackTest.java b/app/src/androidTest/java/de/test/antennapod/playback/PlaybackTest.java
index 67a660ae1..78cf59907 100644
--- a/app/src/androidTest/java/de/test/antennapod/playback/PlaybackTest.java
+++ b/app/src/androidTest/java/de/test/antennapod/playback/PlaybackTest.java
@@ -251,11 +251,9 @@ public class PlaybackTest {
protected void startLocalPlayback() {
openNavDrawer();
onDrawerItem(withText(R.string.episodes_label)).perform(click());
- onView(isRoot()).perform(waitForView(withText(R.string.all_episodes_short_label), 1000));
- onView(withText(R.string.all_episodes_short_label)).perform(click());
final List<FeedItem> episodes = DBReader.getRecentlyPublishedEpisodes(0, 10, FeedItemFilter.unfiltered());
- Matcher<View> allEpisodesMatcher = allOf(withId(android.R.id.list), isDisplayed(), hasMinimumChildCount(2));
+ Matcher<View> allEpisodesMatcher = allOf(withId(R.id.recyclerView), isDisplayed(), hasMinimumChildCount(2));
onView(isRoot()).perform(waitForView(allEpisodesMatcher, 1000));
onView(allEpisodesMatcher).perform(actionOnItemAtPosition(0, clickChildViewWithId(R.id.secondaryActionButton)));
diff --git a/app/src/androidTest/java/de/test/antennapod/ui/NavigationDrawerTest.java b/app/src/androidTest/java/de/test/antennapod/ui/NavigationDrawerTest.java
index 98d983a02..97c199e26 100644
--- a/app/src/androidTest/java/de/test/antennapod/ui/NavigationDrawerTest.java
+++ b/app/src/androidTest/java/de/test/antennapod/ui/NavigationDrawerTest.java
@@ -11,7 +11,7 @@ import de.danoeh.antennapod.activity.PreferenceActivity;
import de.danoeh.antennapod.fragment.CompletedDownloadsFragment;
import de.danoeh.antennapod.model.feed.Feed;
import de.danoeh.antennapod.core.preferences.UserPreferences;
-import de.danoeh.antennapod.fragment.EpisodesFragment;
+import de.danoeh.antennapod.fragment.AllEpisodesFragment;
import de.danoeh.antennapod.fragment.NavDrawerFragment;
import de.danoeh.antennapod.fragment.PlaybackHistoryFragment;
import de.danoeh.antennapod.fragment.QueueFragment;
@@ -148,7 +148,7 @@ public class NavigationDrawerTest {
List<String> hidden = UserPreferences.getHiddenDrawerItems();
assertEquals(2, hidden.size());
- assertTrue(hidden.contains(EpisodesFragment.TAG));
+ assertTrue(hidden.contains(AllEpisodesFragment.TAG));
assertTrue(hidden.contains(PlaybackHistoryFragment.TAG));
}
diff --git a/app/src/androidTest/java/de/test/antennapod/ui/PreferencesTest.java b/app/src/androidTest/java/de/test/antennapod/ui/PreferencesTest.java
index ef5719d6f..b8f2faa63 100644
--- a/app/src/androidTest/java/de/test/antennapod/ui/PreferencesTest.java
+++ b/app/src/androidTest/java/de/test/antennapod/ui/PreferencesTest.java
@@ -28,7 +28,7 @@ import de.danoeh.antennapod.core.storage.APNullCleanupAlgorithm;
import de.danoeh.antennapod.core.storage.APQueueCleanupAlgorithm;
import de.danoeh.antennapod.core.storage.EpisodeCleanupAlgorithm;
import de.danoeh.antennapod.core.storage.ExceptFavoriteCleanupAlgorithm;
-import de.danoeh.antennapod.fragment.EpisodesFragment;
+import de.danoeh.antennapod.fragment.AllEpisodesFragment;
import de.danoeh.antennapod.fragment.QueueFragment;
import de.danoeh.antennapod.fragment.SubscriptionFragment;
import de.test.antennapod.EspressoTestUtils;
@@ -521,7 +521,7 @@ public class PreferencesTest {
Awaitility.await().atMost(1000, MILLISECONDS)
.until(() -> UserPreferences.getBackButtonBehavior() == UserPreferences.BackButtonBehavior.GO_TO_PAGE);
Awaitility.await().atMost(1000, MILLISECONDS)
- .until(() -> UserPreferences.getBackButtonGoToPage().equals(EpisodesFragment.TAG));
+ .until(() -> UserPreferences.getBackButtonGoToPage().equals(AllEpisodesFragment.TAG));
clickPreference(R.string.pref_back_button_behavior_title);
onView(withText(R.string.back_button_go_to_page)).perform(click());
onView(withText(R.string.subscriptions_label)).perform(click());
diff --git a/app/src/main/java/de/danoeh/antennapod/activity/MainActivity.java b/app/src/main/java/de/danoeh/antennapod/activity/MainActivity.java
index fe5d8733a..837dcd731 100644
--- a/app/src/main/java/de/danoeh/antennapod/activity/MainActivity.java
+++ b/app/src/main/java/de/danoeh/antennapod/activity/MainActivity.java
@@ -37,6 +37,7 @@ import com.bumptech.glide.Glide;
import com.google.android.material.bottomsheet.BottomSheetBehavior;
import com.google.android.material.snackbar.Snackbar;
+import de.danoeh.antennapod.fragment.AllEpisodesFragment;
import de.danoeh.antennapod.fragment.CompletedDownloadsFragment;
import de.danoeh.antennapod.playback.cast.CastEnabledActivity;
import org.apache.commons.lang3.ArrayUtils;
@@ -54,7 +55,6 @@ import de.danoeh.antennapod.core.util.download.AutoUpdateManager;
import de.danoeh.antennapod.dialog.RatingDialog;
import de.danoeh.antennapod.fragment.AddFeedFragment;
import de.danoeh.antennapod.fragment.AudioPlayerFragment;
-import de.danoeh.antennapod.fragment.EpisodesFragment;
import de.danoeh.antennapod.fragment.InboxFragment;
import de.danoeh.antennapod.fragment.FeedItemlistFragment;
import de.danoeh.antennapod.fragment.NavDrawerFragment;
@@ -270,8 +270,8 @@ public class MainActivity extends CastEnabledActivity {
case InboxFragment.TAG:
fragment = new InboxFragment();
break;
- case EpisodesFragment.TAG:
- fragment = new EpisodesFragment();
+ case AllEpisodesFragment.TAG:
+ fragment = new AllEpisodesFragment();
break;
case CompletedDownloadsFragment.TAG:
fragment = new CompletedDownloadsFragment();
@@ -606,7 +606,7 @@ public class MainActivity extends CastEnabledActivity {
loadFragment(PlaybackHistoryFragment.TAG, null);
break;
case "EPISODES":
- loadFragment(EpisodesFragment.TAG, null);
+ loadFragment(AllEpisodesFragment.TAG, null);
break;
case "QUEUE":
loadFragment(QueueFragment.TAG, null);
diff --git a/app/src/main/java/de/danoeh/antennapod/adapter/NavListAdapter.java b/app/src/main/java/de/danoeh/antennapod/adapter/NavListAdapter.java
index aaf914ebc..c0fc07ff6 100644
--- a/app/src/main/java/de/danoeh/antennapod/adapter/NavListAdapter.java
+++ b/app/src/main/java/de/danoeh/antennapod/adapter/NavListAdapter.java
@@ -24,6 +24,7 @@ import com.bumptech.glide.request.RequestOptions;
import com.joanzapata.iconify.Iconify;
import de.danoeh.antennapod.R;
import de.danoeh.antennapod.activity.PreferenceActivity;
+import de.danoeh.antennapod.fragment.AllEpisodesFragment;
import de.danoeh.antennapod.fragment.CompletedDownloadsFragment;
import de.danoeh.antennapod.fragment.InboxFragment;
import de.danoeh.antennapod.model.feed.Feed;
@@ -31,7 +32,6 @@ import de.danoeh.antennapod.core.glide.ApGlideSettings;
import de.danoeh.antennapod.core.preferences.UserPreferences;
import de.danoeh.antennapod.core.storage.NavDrawerData;
import de.danoeh.antennapod.fragment.AddFeedFragment;
-import de.danoeh.antennapod.fragment.EpisodesFragment;
import de.danoeh.antennapod.fragment.NavDrawerFragment;
import de.danoeh.antennapod.fragment.PlaybackHistoryFragment;
import de.danoeh.antennapod.fragment.QueueFragment;
@@ -116,7 +116,7 @@ public class NavListAdapter extends RecyclerView.Adapter<NavListAdapter.Holder>
return R.drawable.ic_playlist_play;
case InboxFragment.TAG:
return R.drawable.ic_inbox;
- case EpisodesFragment.TAG:
+ case AllEpisodesFragment.TAG:
return R.drawable.ic_feed;
case CompletedDownloadsFragment.TAG:
return R.drawable.ic_download;
diff --git a/app/src/main/java/de/danoeh/antennapod/dialog/SwipeActionsDialog.java b/app/src/main/java/de/danoeh/antennapod/dialog/SwipeActionsDialog.java
index da4cfc1c0..fd0a32e03 100644
--- a/app/src/main/java/de/danoeh/antennapod/dialog/SwipeActionsDialog.java
+++ b/app/src/main/java/de/danoeh/antennapod/dialog/SwipeActionsDialog.java
@@ -22,8 +22,8 @@ import de.danoeh.antennapod.databinding.SwipeactionsDialogBinding;
import de.danoeh.antennapod.databinding.SwipeactionsPickerBinding;
import de.danoeh.antennapod.databinding.SwipeactionsPickerItemBinding;
import de.danoeh.antennapod.databinding.SwipeactionsRowBinding;
+import de.danoeh.antennapod.fragment.AllEpisodesFragment;
import de.danoeh.antennapod.fragment.CompletedDownloadsFragment;
-import de.danoeh.antennapod.fragment.EpisodesFragment;
import de.danoeh.antennapod.fragment.FeedItemlistFragment;
import de.danoeh.antennapod.fragment.InboxFragment;
import de.danoeh.antennapod.fragment.QueueFragment;
@@ -62,7 +62,7 @@ public class SwipeActionsDialog {
forFragment = context.getString(R.string.inbox_label);
keys = Stream.of(keys).filter(a -> !a.getId().equals(SwipeAction.TOGGLE_PLAYED)).toList();
break;
- case EpisodesFragment.TAG:
+ case AllEpisodesFragment.TAG:
forFragment = context.getString(R.string.episodes_label);
break;
case CompletedDownloadsFragment.TAG:
diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/AllEpisodesFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/AllEpisodesFragment.java
index 46a648e57..36e02929a 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/AllEpisodesFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/fragment/AllEpisodesFragment.java
@@ -3,37 +3,51 @@ package de.danoeh.antennapod.fragment;
import android.content.Context;
import android.content.SharedPreferences;
import android.os.Bundle;
-import android.view.Menu;
+import android.view.LayoutInflater;
import android.view.MenuItem;
import android.view.View;
+import android.view.ViewGroup;
import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
import com.joanzapata.iconify.Iconify;
import de.danoeh.antennapod.R;
-import de.danoeh.antennapod.core.storage.DBReader;
import de.danoeh.antennapod.dialog.AllEpisodesFilterDialog;
-import de.danoeh.antennapod.model.feed.FeedItem;
import de.danoeh.antennapod.model.feed.FeedItemFilter;
import org.apache.commons.lang3.StringUtils;
import org.greenrobot.eventbus.Subscribe;
-import java.util.List;
+import java.util.Collections;
/**
- * Like 'EpisodesFragment' except that it only shows new episodes and
- * supports swiping to mark as read.
+ * Shows all episodes (possibly filtered by user).
*/
public class AllEpisodesFragment extends EpisodesListFragment {
+ public static final String TAG = "EpisodesFragment";
private static final String PREF_NAME = "PrefAllEpisodesFragment";
private static final String PREF_FILTER = "filter";
- private FeedItemFilter feedItemFilter = new FeedItemFilter("");
+ @NonNull
+ @Override
+ public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
+ final View root = super.onCreateView(inflater, container, savedInstanceState);
+ toolbar.inflateMenu(R.menu.episodes);
+ toolbar.setTitle(R.string.episodes_label);
+ updateToolbar();
+ updateFilterUi();
+ speedDialView.removeActionItemById(R.id.mark_unread_batch);
+ speedDialView.removeActionItemById(R.id.remove_from_queue_batch);
+ speedDialView.removeActionItemById(R.id.delete_batch);
+ return root;
+ }
@Override
- public void onCreate(@Nullable Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
+ protected FeedItemFilter getFilter() {
SharedPreferences prefs = getActivity().getSharedPreferences(PREF_NAME, Context.MODE_PRIVATE);
- feedItemFilter = new FeedItemFilter(prefs.getString(PREF_FILTER, ""));
+ return new FeedItemFilter(prefs.getString(PREF_FILTER, ""));
+ }
+
+ @Override
+ protected String getFragmentTag() {
+ return TAG;
}
@Override
@@ -42,12 +56,16 @@ public class AllEpisodesFragment extends EpisodesListFragment {
}
@Override
- public boolean onOptionsItemSelected(MenuItem item) {
+ public boolean onMenuItemClick(MenuItem item) {
if (super.onOptionsItemSelected(item)) {
return true;
}
if (item.getItemId() == R.id.filter_items) {
- AllEpisodesFilterDialog.newInstance(feedItemFilter).show(getChildFragmentManager(), null);
+ AllEpisodesFilterDialog.newInstance(getFilter()).show(getChildFragmentManager(), null);
+ return true;
+ } else if (item.getItemId() == R.id.action_favorites) {
+ onFilterChanged(new AllEpisodesFilterDialog.AllEpisodesFilterChangedEvent(getFilter().showIsFavorite
+ ? Collections.emptySet() : Collections.singleton(FeedItemFilter.IS_FAVORITE)));
return true;
}
return false;
@@ -55,58 +73,23 @@ public class AllEpisodesFragment extends EpisodesListFragment {
@Subscribe
public void onFilterChanged(AllEpisodesFilterDialog.AllEpisodesFilterChangedEvent event) {
- feedItemFilter = new FeedItemFilter(event.filterValues.toArray(new String[0]));
SharedPreferences prefs = getActivity().getSharedPreferences(PREF_NAME, Context.MODE_PRIVATE);
prefs.edit().putString(PREF_FILTER, StringUtils.join(event.filterValues, ",")).apply();
+ updateFilterUi();
page = 1;
loadItems();
}
- @Override
- public void onPrepareOptionsMenu(@NonNull Menu menu) {
- super.onPrepareOptionsMenu(menu);
- menu.findItem(R.id.filter_items).setVisible(true);
- }
-
- @Override
- protected void onFragmentLoaded(List<FeedItem> episodes) {
- super.onFragmentLoaded(episodes);
-
- if (feedItemFilter.getValues().length > 0) {
+ private void updateFilterUi() {
+ swipeActions.setFilter(getFilter());
+ if (getFilter().getValues().length > 0) {
txtvInformation.setText("{md-info-outline} " + this.getString(R.string.filtered_label));
Iconify.addIcons(txtvInformation);
txtvInformation.setVisibility(View.VISIBLE);
+ emptyView.setMessage(R.string.no_all_episodes_filtered_label);
} else {
txtvInformation.setVisibility(View.GONE);
+ emptyView.setMessage(R.string.no_all_episodes_label);
}
}
-
- @Override
- protected boolean shouldUpdatedItemRemainInList(FeedItem item) {
- SharedPreferences prefs = getActivity().getSharedPreferences(PREF_NAME, Context.MODE_PRIVATE);
- FeedItemFilter feedItemFilter = new FeedItemFilter(prefs.getString(PREF_FILTER, ""));
-
- if (feedItemFilter.isShowDownloaded() && (!item.hasMedia() || !item.getMedia().isDownloaded())) {
- return false;
- }
-
- return true;
- }
-
- @NonNull
- @Override
- protected List<FeedItem> loadData() {
- return DBReader.getRecentlyPublishedEpisodes(0, page * EPISODES_PER_PAGE, feedItemFilter);
- }
-
- @NonNull
- @Override
- protected List<FeedItem> loadMoreData(int page) {
- return DBReader.getRecentlyPublishedEpisodes((page - 1) * EPISODES_PER_PAGE, EPISODES_PER_PAGE, feedItemFilter);
- }
-
- @Override
- protected int loadTotalItemCount() {
- return DBReader.getTotalEpisodeCount(feedItemFilter);
- }
}
diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/EpisodesFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/EpisodesFragment.java
deleted file mode 100644
index 951d42d73..000000000
--- a/app/src/main/java/de/danoeh/antennapod/fragment/EpisodesFragment.java
+++ /dev/null
@@ -1,121 +0,0 @@
-package de.danoeh.antennapod.fragment;
-
-import android.content.Context;
-import android.content.SharedPreferences;
-import android.os.Bundle;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-
-import androidx.annotation.NonNull;
-import androidx.appcompat.widget.Toolbar;
-import androidx.fragment.app.Fragment;
-import androidx.viewpager2.adapter.FragmentStateAdapter;
-import androidx.viewpager2.widget.ViewPager2;
-
-import com.google.android.material.tabs.TabLayout;
-import com.google.android.material.tabs.TabLayoutMediator;
-
-import de.danoeh.antennapod.R;
-import de.danoeh.antennapod.activity.MainActivity;
-import de.danoeh.antennapod.ui.common.PagedToolbarFragment;
-
-public class EpisodesFragment extends PagedToolbarFragment {
-
- public static final String TAG = "EpisodesFragment";
- private static final String PREF_LAST_TAB_POSITION = "tab_position";
- private static final String KEY_UP_ARROW = "up_arrow";
-
- private static final int POS_ALL_EPISODES = 0;
- private static final int POS_FAV_EPISODES = 1;
- private static final int TOTAL_COUNT = 2;
-
- private TabLayout tabLayout;
- private boolean displayUpArrow;
-
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setRetainInstance(true);
- }
-
- public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
- super.onCreateView(inflater, container, savedInstanceState);
- View rootView = inflater.inflate(R.layout.pager_fragment, container, false);
- Toolbar toolbar = rootView.findViewById(R.id.toolbar);
- toolbar.setTitle(R.string.episodes_label);
- toolbar.inflateMenu(R.menu.episodes);
- displayUpArrow = getParentFragmentManager().getBackStackEntryCount() != 0;
- if (savedInstanceState != null) {
- displayUpArrow = savedInstanceState.getBoolean(KEY_UP_ARROW);
- }
- ((MainActivity) getActivity()).setupToolbarToggle(toolbar, displayUpArrow);
-
- ViewPager2 viewPager = rootView.findViewById(R.id.viewpager);
- viewPager.setAdapter(new EpisodesPagerAdapter(this));
- viewPager.setOffscreenPageLimit(2);
- super.setupPagedToolbar(toolbar, viewPager);
-
- // Give the TabLayout the ViewPager
- tabLayout = rootView.findViewById(R.id.sliding_tabs);
-
- new TabLayoutMediator(tabLayout, viewPager, (tab, position) -> {
- switch (position) {
- case POS_ALL_EPISODES:
- tab.setText(R.string.all_episodes_short_label);
- break;
- case POS_FAV_EPISODES:
- tab.setText(R.string.favorite_episodes_label);
- break;
- default:
- break;
- }
- }).attach();
-
- // restore our last position
- SharedPreferences prefs = getActivity().getSharedPreferences(TAG, Context.MODE_PRIVATE);
- int lastPosition = prefs.getInt(PREF_LAST_TAB_POSITION, 0);
- viewPager.setCurrentItem(lastPosition, false);
-
- return rootView;
- }
-
- @Override
- public void onPause() {
- super.onPause();
- // save our tab selection
- SharedPreferences prefs = getActivity().getSharedPreferences(TAG, Context.MODE_PRIVATE);
- SharedPreferences.Editor editor = prefs.edit();
- editor.putInt(PREF_LAST_TAB_POSITION, tabLayout.getSelectedTabPosition());
- editor.apply();
- }
-
- @Override
- public void onSaveInstanceState(@NonNull Bundle outState) {
- outState.putBoolean(KEY_UP_ARROW, displayUpArrow);
- super.onSaveInstanceState(outState);
- }
-
- static class EpisodesPagerAdapter extends FragmentStateAdapter {
-
- EpisodesPagerAdapter(@NonNull Fragment fragment) {
- super(fragment);
- }
-
- @NonNull
- @Override
- public Fragment createFragment(int position) {
- switch (position) {
- case POS_ALL_EPISODES:
- return new AllEpisodesFragment();
- default:
- case POS_FAV_EPISODES:
- return new FavoriteEpisodesFragment();
- }
- }
-
- @Override
- public int getItemCount() {
- return TOTAL_COUNT;
- }
- }
-}
diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/EpisodesListFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/EpisodesListFragment.java
index 03dbc6ae4..f581a16f5 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/EpisodesListFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/fragment/EpisodesListFragment.java
@@ -2,18 +2,11 @@ package de.danoeh.antennapod.fragment;
import android.content.DialogInterface;
import android.os.Bundle;
-import android.view.ContextMenu;
-import android.view.KeyEvent;
-import androidx.annotation.NonNull;
-import androidx.core.util.Pair;
-import androidx.fragment.app.Fragment;
-import androidx.recyclerview.widget.RecyclerView;
-import androidx.recyclerview.widget.SimpleItemAnimator;
-import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
-
import android.os.Handler;
import android.os.Looper;
import android.util.Log;
+import android.view.ContextMenu;
+import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
@@ -21,57 +14,63 @@ import android.view.View;
import android.view.ViewGroup;
import android.widget.ProgressBar;
import android.widget.TextView;
-import android.widget.Toast;
-
+import androidx.annotation.NonNull;
+import androidx.appcompat.widget.Toolbar;
+import androidx.core.util.Pair;
+import androidx.fragment.app.Fragment;
+import androidx.recyclerview.widget.RecyclerView;
+import androidx.recyclerview.widget.SimpleItemAnimator;
+import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
import com.google.android.material.snackbar.Snackbar;
import com.leinardi.android.speeddial.SpeedDialView;
-import de.danoeh.antennapod.adapter.EpisodeItemListAdapter;
-import de.danoeh.antennapod.adapter.SelectableAdapter;
-import de.danoeh.antennapod.event.FeedListUpdateEvent;
-import de.danoeh.antennapod.event.playback.PlaybackPositionEvent;
-import de.danoeh.antennapod.event.PlayerStatusEvent;
-import de.danoeh.antennapod.event.UnreadItemsUpdateEvent;
-import de.danoeh.antennapod.core.menuhandler.MenuItemUtils;
-import de.danoeh.antennapod.fragment.actions.EpisodeMultiSelectActionHandler;
-import de.danoeh.antennapod.ui.common.PagedToolbarFragment;
-import de.danoeh.antennapod.view.EpisodeItemListRecyclerView;
-import de.danoeh.antennapod.view.viewholder.EpisodeItemViewHolder;
-import io.reactivex.Completable;
-import org.greenrobot.eventbus.EventBus;
-import org.greenrobot.eventbus.Subscribe;
-import org.greenrobot.eventbus.ThreadMode;
-
-import java.util.ArrayList;
-import java.util.List;
-
import de.danoeh.antennapod.R;
import de.danoeh.antennapod.activity.MainActivity;
+import de.danoeh.antennapod.adapter.EpisodeItemListAdapter;
import de.danoeh.antennapod.core.dialog.ConfirmationDialog;
import de.danoeh.antennapod.core.event.DownloadEvent;
import de.danoeh.antennapod.core.event.DownloaderUpdate;
-import de.danoeh.antennapod.event.FeedItemEvent;
-import de.danoeh.antennapod.model.feed.FeedItem;
+import de.danoeh.antennapod.core.menuhandler.MenuItemUtils;
import de.danoeh.antennapod.core.service.download.DownloadService;
-import de.danoeh.antennapod.core.storage.DBWriter;
+import de.danoeh.antennapod.core.storage.DBReader;
import de.danoeh.antennapod.core.util.FeedItemUtil;
import de.danoeh.antennapod.core.util.download.AutoUpdateManager;
+import de.danoeh.antennapod.event.FeedItemEvent;
+import de.danoeh.antennapod.event.FeedListUpdateEvent;
+import de.danoeh.antennapod.event.PlayerStatusEvent;
+import de.danoeh.antennapod.event.UnreadItemsUpdateEvent;
+import de.danoeh.antennapod.event.playback.PlaybackPositionEvent;
+import de.danoeh.antennapod.fragment.actions.EpisodeMultiSelectActionHandler;
+import de.danoeh.antennapod.fragment.swipeactions.SwipeActions;
import de.danoeh.antennapod.menuhandler.FeedItemMenuHandler;
+import de.danoeh.antennapod.model.feed.FeedItem;
+import de.danoeh.antennapod.model.feed.FeedItemFilter;
import de.danoeh.antennapod.view.EmptyViewHandler;
+import de.danoeh.antennapod.view.EpisodeItemListRecyclerView;
+import de.danoeh.antennapod.view.viewholder.EpisodeItemViewHolder;
+import io.reactivex.Completable;
import io.reactivex.Observable;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.Disposable;
import io.reactivex.schedulers.Schedulers;
+import org.greenrobot.eventbus.EventBus;
+import org.greenrobot.eventbus.Subscribe;
+import org.greenrobot.eventbus.ThreadMode;
+
+import java.util.ArrayList;
+import java.util.List;
/**
* Shows unread or recently published episodes
*/
-public abstract class EpisodesListFragment extends Fragment implements EpisodeItemListAdapter.OnSelectModeListener {
-
+public abstract class EpisodesListFragment extends Fragment
+ implements EpisodeItemListAdapter.OnSelectModeListener, Toolbar.OnMenuItemClickListener {
public static final String TAG = "EpisodesListFragment";
+ private static final String KEY_UP_ARROW = "up_arrow";
protected static final int EPISODES_PER_PAGE = 150;
protected int page = 1;
protected boolean isLoadingMore = false;
protected boolean hasMoreItems = true;
+ private boolean displayUpArrow;
EpisodeItemListRecyclerView recyclerView;
EpisodeItemListAdapter listAdapter;
@@ -79,6 +78,8 @@ public abstract class EpisodesListFragment extends Fragment implements EpisodeIt
View loadingMoreView;
EmptyViewHandler emptyView;
SpeedDialView speedDialView;
+ Toolbar toolbar;
+ SwipeActions swipeActions;
@NonNull
List<FeedItem> episodes = new ArrayList<>();
@@ -87,9 +88,6 @@ public abstract class EpisodesListFragment extends Fragment implements EpisodeIt
protected Disposable disposable;
protected TextView txtvInformation;
- String getPrefName() {
- return TAG;
- }
@Override
public void onStart() {
@@ -137,21 +135,6 @@ public abstract class EpisodesListFragment extends Fragment implements EpisodeIt
if (itemId == R.id.refresh_item) {
AutoUpdateManager.runImmediate(requireContext());
return true;
- } else if (itemId == R.id.remove_all_inbox_item) {
- ConfirmationDialog removeAllNewFlagsConfirmationDialog = new ConfirmationDialog(getActivity(),
- R.string.remove_all_inbox_label,
- R.string.remove_all_inbox_confirmation_msg) {
-
- @Override
- public void onConfirmButtonPressed(DialogInterface dialog) {
- dialog.dismiss();
- DBWriter.removeAllNewFlags();
- ((MainActivity) getActivity()).showSnackbarAbovePlayer(
- R.string.removed_all_inbox_msg, Toast.LENGTH_SHORT);
- }
- };
- removeAllNewFlagsConfirmationDialog.createNewDialog().show();
- return true;
} else if (itemId == R.id.action_search) {
((MainActivity) getActivity()).loadChildFragment(SearchFragment.newInstance());
return true;
@@ -180,13 +163,28 @@ public abstract class EpisodesListFragment extends Fragment implements EpisodeIt
@Override
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
super.onCreateView(inflater, container, savedInstanceState);
- View root = inflater.inflate(R.layout.all_episodes_fragment, container, false);
+ View root = inflater.inflate(R.layout.episodes_list_fragment, container, false);
txtvInformation = root.findViewById(R.id.txtvInformation);
+ toolbar = root.findViewById(R.id.toolbar);
+ toolbar.setOnMenuItemClickListener(this);
+ toolbar.setOnLongClickListener(v -> {
+ recyclerView.scrollToPosition(5);
+ recyclerView.post(() -> recyclerView.smoothScrollToPosition(0));
+ return false;
+ });
+ displayUpArrow = getParentFragmentManager().getBackStackEntryCount() != 0;
+ if (savedInstanceState != null) {
+ displayUpArrow = savedInstanceState.getBoolean(KEY_UP_ARROW);
+ }
+ ((MainActivity) getActivity()).setupToolbarToggle(toolbar, displayUpArrow);
recyclerView = root.findViewById(android.R.id.list);
recyclerView.setRecycledViewPool(((MainActivity) getActivity()).getRecycledViewPool());
setupLoadMoreScrollListener();
+ swipeActions = new SwipeActions(this, getFragmentTag()).attachTo(recyclerView);
+ swipeActions.setFilter(getFilter());
+
RecyclerView.ItemAnimator animator = recyclerView.getItemAnimator();
if (animator instanceof SimpleItemAnimator) {
((SimpleItemAnimator) animator).setSupportsChangeAnimations(false);
@@ -308,7 +306,7 @@ public abstract class EpisodesListFragment extends Fragment implements EpisodeIt
hasMoreItems = false;
}
episodes.addAll(data);
- onFragmentLoaded(episodes);
+ updateAdapterWithNewItems();
if (listAdapter.shouldSelectLazyLoadedItems()) {
listAdapter.setSelected(episodes.size() - data.size(), episodes.size(), true);
}
@@ -320,7 +318,7 @@ public abstract class EpisodesListFragment extends Fragment implements EpisodeIt
});
}
- protected void onFragmentLoaded(List<FeedItem> episodes) {
+ protected void updateAdapterWithNewItems() {
boolean restoreScrollPosition = listAdapter.getItemCount() == 0;
if (episodes.size() == 0) {
createRecycleAdapter(recyclerView, emptyView);
@@ -330,10 +328,6 @@ public abstract class EpisodesListFragment extends Fragment implements EpisodeIt
if (restoreScrollPosition) {
recyclerView.restoreScrollPosition(getPrefName());
}
- if (isUpdatingFeeds != updateRefreshMenuItemChecker.isRefreshing()
- && getParentFragment() instanceof PagedToolbarFragment) {
- ((PagedToolbarFragment) getParentFragment()).invalidateOptionsMenuIfActive(this);
- }
}
/**
@@ -385,7 +379,7 @@ public abstract class EpisodesListFragment extends Fragment implements EpisodeIt
int pos = FeedItemUtil.indexOfItemWithId(episodes, item.getId());
if (pos >= 0) {
episodes.remove(pos);
- if (shouldUpdatedItemRemainInList(item)) {
+ if (getFilter().matches(item)) {
episodes.add(pos, item);
listAdapter.notifyItemChangedCompat(pos);
} else {
@@ -425,16 +419,12 @@ public abstract class EpisodesListFragment extends Fragment implements EpisodeIt
}
}
- protected boolean shouldUpdatedItemRemainInList(FeedItem item) {
- return true;
- }
-
@Subscribe(sticky = true, threadMode = ThreadMode.MAIN)
public void onEventMainThread(DownloadEvent event) {
Log.d(TAG, "onEventMainThread() called with: " + "event = [" + event + "]");
DownloaderUpdate update = event.update;
- if (event.hasChangedFeedUpdateStatus(isUpdatingFeeds) && getParentFragment() instanceof PagedToolbarFragment) {
- ((PagedToolbarFragment) getParentFragment()).invalidateOptionsMenuIfActive(this);
+ if (event.hasChangedFeedUpdateStatus(isUpdatingFeeds)) {
+ updateToolbar();
}
if (update.mediaIds.length > 0) {
for (long mediaId : update.mediaIds) {
@@ -448,9 +438,8 @@ public abstract class EpisodesListFragment extends Fragment implements EpisodeIt
private void updateUi() {
loadItems();
- if (isUpdatingFeeds != updateRefreshMenuItemChecker.isRefreshing()
- && getParentFragment() instanceof PagedToolbarFragment) {
- ((PagedToolbarFragment) getParentFragment()).invalidateOptionsMenuIfActive(this);
+ if (isUpdatingFeeds != updateRefreshMenuItemChecker.isRefreshing()) {
+ updateToolbar();
}
}
@@ -481,32 +470,41 @@ public abstract class EpisodesListFragment extends Fragment implements EpisodeIt
loadingMoreView.setVisibility(View.GONE);
hasMoreItems = true;
episodes = data.first;
+ listAdapter.notifyDataSetChanged();
listAdapter.setTotalNumberOfItems(data.second);
- onFragmentLoaded(episodes);
- if (getParentFragment() instanceof PagedToolbarFragment) {
- ((PagedToolbarFragment) getParentFragment()).invalidateOptionsMenuIfActive(this);
- }
+ updateAdapterWithNewItems();
+ updateToolbar();
}, error -> Log.e(TAG, Log.getStackTraceString(error)));
}
@NonNull
- protected abstract List<FeedItem> loadData();
+ protected List<FeedItem> loadData() {
+ return DBReader.getRecentlyPublishedEpisodes(0, page * EPISODES_PER_PAGE, getFilter());
+ }
- /**
- * Load a new page of data as defined by {@link #page} and {@link #EPISODES_PER_PAGE}.
- * If the number of items returned is less than {@link #EPISODES_PER_PAGE},
- * it will be assumed that the underlying data is exhausted
- * and this method will not be called again.
- *
- * @return The items from the next page of data
- */
@NonNull
- protected abstract List<FeedItem> loadMoreData(int page);
+ protected List<FeedItem> loadMoreData(int page) {
+ return DBReader.getRecentlyPublishedEpisodes((page - 1) * EPISODES_PER_PAGE, EPISODES_PER_PAGE, getFilter());
+ }
- /**
- * Returns the total number of items that would be returned if {@link #loadMoreData} was called often enough.
- */
protected int loadTotalItemCount() {
- return SelectableAdapter.COUNT_AUTOMATICALLY;
+ return DBReader.getTotalEpisodeCount(getFilter());
+ }
+
+ protected abstract FeedItemFilter getFilter();
+
+ protected abstract String getFragmentTag();
+
+ protected abstract String getPrefName();
+
+ protected void updateToolbar() {
+ isUpdatingFeeds = MenuItemUtils.updateRefreshMenuItem(toolbar.getMenu(),
+ R.id.refresh_item, updateRefreshMenuItemChecker);
+ }
+
+ @Override
+ public void onSaveInstanceState(@NonNull Bundle outState) {
+ outState.putBoolean(KEY_UP_ARROW, displayUpArrow);
+ super.onSaveInstanceState(outState);
}
}
diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/FavoriteEpisodesFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/FavoriteEpisodesFragment.java
deleted file mode 100644
index 30eec8780..000000000
--- a/app/src/main/java/de/danoeh/antennapod/fragment/FavoriteEpisodesFragment.java
+++ /dev/null
@@ -1,109 +0,0 @@
-package de.danoeh.antennapod.fragment;
-
-import android.os.Bundle;
-import android.view.Menu;
-import androidx.annotation.NonNull;
-import com.google.android.material.snackbar.Snackbar;
-import androidx.recyclerview.widget.RecyclerView;
-import androidx.recyclerview.widget.ItemTouchHelper;
-import android.util.Log;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-
-import de.danoeh.antennapod.activity.MainActivity;
-import de.danoeh.antennapod.model.feed.FeedItemFilter;
-import de.danoeh.antennapod.view.viewholder.EpisodeItemViewHolder;
-import org.greenrobot.eventbus.Subscribe;
-
-import java.util.List;
-
-import de.danoeh.antennapod.R;
-import de.danoeh.antennapod.event.FavoritesEvent;
-import de.danoeh.antennapod.model.feed.FeedItem;
-import de.danoeh.antennapod.core.storage.DBReader;
-import de.danoeh.antennapod.core.storage.DBWriter;
-
-/**
- * Like 'EpisodesFragment' except that it only shows favorite episodes and
- * supports swiping to remove from favorites.
- */
-public class FavoriteEpisodesFragment extends EpisodesListFragment {
-
- private static final String TAG = "FavoriteEpisodesFrag";
- private static final String PREF_NAME = "PrefFavoriteEpisodesFragment";
-
- @Override
- protected String getPrefName() {
- return PREF_NAME;
- }
-
- @Subscribe
- public void onEvent(FavoritesEvent event) {
- Log.d(TAG, String.format("onEvent() called with: event = [%s]", event));
- loadItems();
- }
-
- @Override
- public void onPrepareOptionsMenu(@NonNull Menu menu) {
- super.onPrepareOptionsMenu(menu);
- menu.findItem(R.id.filter_items).setVisible(false);
- }
-
- @NonNull
- @Override
- public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
- View root = super.onCreateView(inflater, container, savedInstanceState);
- emptyView.setIcon(R.drawable.ic_star);
- emptyView.setTitle(R.string.no_fav_episodes_head_label);
- emptyView.setMessage(R.string.no_fav_episodes_label);
-
- ItemTouchHelper.SimpleCallback simpleItemTouchCallback = new ItemTouchHelper.SimpleCallback(0,
- ItemTouchHelper.LEFT) {
- @Override
- public boolean onMove(@NonNull RecyclerView recyclerView,
- @NonNull RecyclerView.ViewHolder viewHolder,
- @NonNull RecyclerView.ViewHolder target) {
- return false;
- }
-
- @Override
- public void onSwiped(@NonNull RecyclerView.ViewHolder viewHolder, int swipeDir) {
- EpisodeItemViewHolder holder = (EpisodeItemViewHolder) viewHolder;
- Log.d(TAG, String.format("remove(%s)", holder.getFeedItem().getId()));
-
- if (disposable != null) {
- disposable.dispose();
- }
- FeedItem item = holder.getFeedItem();
- if (item != null) {
- DBWriter.removeFavoriteItem(item);
-
- ((MainActivity) getActivity()).showSnackbarAbovePlayer(R.string.removed_item, Snackbar.LENGTH_LONG)
- .setAction(getString(R.string.undo), v -> DBWriter.addFavoriteItem(item));
- }
- }
- };
-
- ItemTouchHelper itemTouchHelper = new ItemTouchHelper(simpleItemTouchCallback);
- itemTouchHelper.attachToRecyclerView(recyclerView);
- return root;
- }
-
- @NonNull
- @Override
- protected List<FeedItem> loadData() {
- return DBReader.getFavoriteItemsList(0, page * EPISODES_PER_PAGE);
- }
-
- @NonNull
- @Override
- protected List<FeedItem> loadMoreData(int page) {
- return DBReader.getFavoriteItemsList((page - 1) * EPISODES_PER_PAGE, EPISODES_PER_PAGE);
- }
-
- @Override
- protected int loadTotalItemCount() {
- return DBReader.getTotalEpisodeCount(new FeedItemFilter(FeedItemFilter.IS_FAVORITE));
- }
-}
diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/FeedItemlistFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/FeedItemlistFragment.java
index 77d0c4555..d5dd51e93 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/FeedItemlistFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/fragment/FeedItemlistFragment.java
@@ -273,7 +273,7 @@ public class FeedItemlistFragment extends Fragment implements AdapterView.OnItem
new RenameItemDialog(getActivity(), feed).show();
return true;
} else if (itemId == R.id.remove_feed) {
- ((MainActivity) getActivity()).loadFragment(EpisodesFragment.TAG, null);
+ ((MainActivity) getActivity()).loadFragment(AllEpisodesFragment.TAG, null);
RemoveFeedDialog.show(getContext(), feed);
return true;
} else if (itemId == R.id.action_search) {
diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/InboxFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/InboxFragment.java
index 0ff0bd24a..6e5db0963 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/InboxFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/fragment/InboxFragment.java
@@ -1,116 +1,84 @@
package de.danoeh.antennapod.fragment;
+import android.content.DialogInterface;
import android.os.Bundle;
-import android.view.MenuItem;
-import android.widget.FrameLayout;
-import androidx.annotation.NonNull;
-import androidx.appcompat.widget.Toolbar;
import android.view.LayoutInflater;
+import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
-
-import java.util.List;
-
+import android.widget.Toast;
+import androidx.annotation.NonNull;
import de.danoeh.antennapod.R;
import de.danoeh.antennapod.activity.MainActivity;
-import de.danoeh.antennapod.core.event.DownloadEvent;
-import de.danoeh.antennapod.core.menuhandler.MenuItemUtils;
-import de.danoeh.antennapod.core.service.download.DownloadService;
-import de.danoeh.antennapod.fragment.swipeactions.SwipeActions;
-import de.danoeh.antennapod.model.feed.FeedItem;
+import de.danoeh.antennapod.core.dialog.ConfirmationDialog;
import de.danoeh.antennapod.core.storage.DBReader;
+import de.danoeh.antennapod.core.storage.DBWriter;
+import de.danoeh.antennapod.model.feed.FeedItem;
import de.danoeh.antennapod.model.feed.FeedItemFilter;
-import org.greenrobot.eventbus.Subscribe;
-import org.greenrobot.eventbus.ThreadMode;
+
+import java.util.List;
/**
* Like 'EpisodesFragment' except that it only shows new episodes and
* supports swiping to mark as read.
*/
-public class InboxFragment extends EpisodesListFragment implements Toolbar.OnMenuItemClickListener {
+public class InboxFragment extends EpisodesListFragment {
public static final String TAG = "NewEpisodesFragment";
private static final String PREF_NAME = "PrefNewEpisodesFragment";
- private static final String KEY_UP_ARROW = "up_arrow";
-
- private Toolbar toolbar;
- private boolean displayUpArrow;
- private volatile boolean isUpdatingFeeds;
-
- @Override
- protected String getPrefName() {
- return PREF_NAME;
- }
-
- @Override
- protected boolean shouldUpdatedItemRemainInList(FeedItem item) {
- return item.isNew();
- }
@NonNull
@Override
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
- View inboxContainer = View.inflate(getContext(), R.layout.list_container_fragment, null);
- View root = super.onCreateView(inflater, container, savedInstanceState);
- ((FrameLayout) inboxContainer.findViewById(R.id.listContent)).addView(root);
+ final View root = super.onCreateView(inflater, container, savedInstanceState);
+ toolbar.inflateMenu(R.menu.inbox);
+ toolbar.setTitle(R.string.inbox_label);
+ updateToolbar();
+ emptyView.setIcon(R.drawable.ic_inbox);
emptyView.setTitle(R.string.no_inbox_head_label);
emptyView.setMessage(R.string.no_inbox_label);
-
- toolbar = inboxContainer.findViewById(R.id.toolbar);
- toolbar.setOnMenuItemClickListener(this);
- toolbar.inflateMenu(R.menu.inbox);
- toolbar.setOnLongClickListener(v -> {
- recyclerView.scrollToPosition(5);
- recyclerView.post(() -> recyclerView.smoothScrollToPosition(0));
- return false;
- });
- displayUpArrow = getParentFragmentManager().getBackStackEntryCount() != 0;
- if (savedInstanceState != null) {
- displayUpArrow = savedInstanceState.getBoolean(KEY_UP_ARROW);
- }
- ((MainActivity) getActivity()).setupToolbarToggle(toolbar, displayUpArrow);
-
- SwipeActions swipeActions = new SwipeActions(this, TAG).attachTo(recyclerView);
- swipeActions.setFilter(new FeedItemFilter(FeedItemFilter.NEW));
-
speedDialView.removeActionItemById(R.id.mark_unread_batch);
speedDialView.removeActionItemById(R.id.remove_from_queue_batch);
speedDialView.removeActionItemById(R.id.delete_batch);
- return inboxContainer;
- }
-
- private final MenuItemUtils.UpdateRefreshMenuItemChecker updateRefreshMenuItemChecker =
- () -> DownloadService.isRunning && DownloadService.isDownloadingFeeds();
-
- private void updateToolbar() {
- isUpdatingFeeds = MenuItemUtils.updateRefreshMenuItem(toolbar.getMenu(),
- R.id.refresh_item, updateRefreshMenuItemChecker);
+ return root;
}
@Override
- public void onStart() {
- super.onStart();
- if (isUpdatingFeeds != updateRefreshMenuItemChecker.isRefreshing()) {
- updateToolbar();
- }
+ protected FeedItemFilter getFilter() {
+ return new FeedItemFilter(FeedItemFilter.NEW);
}
- @Subscribe(sticky = true, threadMode = ThreadMode.MAIN)
- public void onEventMainThread(DownloadEvent event) {
- super.onEventMainThread(event);
- if (event.hasChangedFeedUpdateStatus(isUpdatingFeeds)) {
- updateToolbar();
- }
+ @Override
+ protected String getFragmentTag() {
+ return TAG;
}
@Override
- public boolean onMenuItemClick(MenuItem item) {
- return super.onOptionsItemSelected(item);
+ protected String getPrefName() {
+ return PREF_NAME;
}
@Override
- public void onSaveInstanceState(@NonNull Bundle outState) {
- outState.putBoolean(KEY_UP_ARROW, displayUpArrow);
- super.onSaveInstanceState(outState);
+ public boolean onMenuItemClick(MenuItem item) {
+ if (super.onOptionsItemSelected(item)) {
+ return true;
+ }
+ if (item.getItemId() == R.id.remove_all_inbox_item) {
+ ConfirmationDialog removeAllNewFlagsConfirmationDialog = new ConfirmationDialog(getActivity(),
+ R.string.remove_all_inbox_label,
+ R.string.remove_all_inbox_confirmation_msg) {
+
+ @Override
+ public void onConfirmButtonPressed(DialogInterface dialog) {
+ dialog.dismiss();
+ DBWriter.removeAllNewFlags();
+ ((MainActivity) getActivity()).showSnackbarAbovePlayer(
+ R.string.removed_all_inbox_msg, Toast.LENGTH_SHORT);
+ }
+ };
+ removeAllNewFlagsConfirmationDialog.createNewDialog().show();
+ return true;
+ }
+ return false;
}
@NonNull
diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/NavDrawerFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/NavDrawerFragment.java
index 1561a984d..95f08a838 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/NavDrawerFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/fragment/NavDrawerFragment.java
@@ -67,7 +67,7 @@ public class NavDrawerFragment extends Fragment implements SharedPreferences.OnS
public static final String[] NAV_DRAWER_TAGS = {
QueueFragment.TAG,
InboxFragment.TAG,
- EpisodesFragment.TAG,
+ AllEpisodesFragment.TAG,
SubscriptionFragment.TAG,
CompletedDownloadsFragment.TAG,
PlaybackHistoryFragment.TAG,
@@ -173,7 +173,7 @@ public class NavDrawerFragment extends Fragment implements SharedPreferences.OnS
new RenameItemDialog(getActivity(), feed).show();
return true;
} else if (itemId == R.id.remove_feed) {
- ((MainActivity) getActivity()).loadFragment(EpisodesFragment.TAG, null);
+ ((MainActivity) getActivity()).loadFragment(AllEpisodesFragment.TAG, null);
RemoveFeedDialog.show(getContext(), feed);
return true;
}
diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/PlaybackHistoryFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/PlaybackHistoryFragment.java
index a22edbc76..3e9b2b5c7 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/PlaybackHistoryFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/fragment/PlaybackHistoryFragment.java
@@ -1,92 +1,59 @@
package de.danoeh.antennapod.fragment;
import android.os.Bundle;
-import android.view.ContextMenu;
import android.view.LayoutInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
-import android.widget.FrameLayout;
-
import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-import androidx.appcompat.widget.Toolbar;
-
import de.danoeh.antennapod.R;
-import de.danoeh.antennapod.activity.MainActivity;
-import de.danoeh.antennapod.adapter.EpisodeItemListAdapter;
-import de.danoeh.antennapod.core.menuhandler.MenuItemUtils;
-import de.danoeh.antennapod.event.playback.PlaybackHistoryEvent;
-import de.danoeh.antennapod.event.PlayerStatusEvent;
-import de.danoeh.antennapod.event.UnreadItemsUpdateEvent;
-import de.danoeh.antennapod.model.feed.FeedItem;
import de.danoeh.antennapod.core.storage.DBReader;
import de.danoeh.antennapod.core.storage.DBWriter;
+import de.danoeh.antennapod.event.playback.PlaybackHistoryEvent;
+import de.danoeh.antennapod.model.feed.FeedItem;
+import de.danoeh.antennapod.model.feed.FeedItemFilter;
import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;
import java.util.List;
-public class PlaybackHistoryFragment extends EpisodesListFragment implements Toolbar.OnMenuItemClickListener {
+public class PlaybackHistoryFragment extends EpisodesListFragment {
public static final String TAG = "PlaybackHistoryFragment";
- private static final String KEY_UP_ARROW = "up_arrow";
-
- private Toolbar toolbar;
- private boolean displayUpArrow;
-
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setRetainInstance(true);
- }
+ @NonNull
@Override
- public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
- @Nullable Bundle savedInstanceState) {
- View historyContainer = View.inflate(getContext(), R.layout.list_container_fragment, null);
- View root = super.onCreateView(inflater, container, savedInstanceState);
-
- ((FrameLayout) historyContainer.findViewById(R.id.listContent)).addView(root);
-
- toolbar = historyContainer.findViewById(R.id.toolbar);
- toolbar.setTitle(R.string.playback_history_label);
- toolbar.setOnMenuItemClickListener(this);
- toolbar.setOnLongClickListener(v -> {
- recyclerView.scrollToPosition(5);
- recyclerView.post(() -> recyclerView.smoothScrollToPosition(0));
- return false;
- });
- displayUpArrow = getParentFragmentManager().getBackStackEntryCount() != 0;
- if (savedInstanceState != null) {
- displayUpArrow = savedInstanceState.getBoolean(KEY_UP_ARROW);
- }
- ((MainActivity) getActivity()).setupToolbarToggle(toolbar, displayUpArrow);
+ public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
+ final View root = super.onCreateView(inflater, container, savedInstanceState);
toolbar.inflateMenu(R.menu.playback_history);
- refreshToolbarState();
-
- listAdapter = new PlaybackHistoryListAdapter((MainActivity) getActivity());
- recyclerView.setAdapter(listAdapter);
-
+ toolbar.setTitle(R.string.playback_history_label);
+ updateToolbar();
emptyView.setIcon(R.drawable.ic_history);
emptyView.setTitle(R.string.no_history_head_label);
emptyView.setMessage(R.string.no_history_label);
+ swipeActions.detach();
+ return root;
+ }
- return historyContainer;
+ @Override
+ protected FeedItemFilter getFilter() {
+ return FeedItemFilter.unfiltered();
}
@Override
- public void onSaveInstanceState(@NonNull Bundle outState) {
- outState.putBoolean(KEY_UP_ARROW, displayUpArrow);
- super.onSaveInstanceState(outState);
+ protected String getFragmentTag() {
+ return TAG;
}
- public void refreshToolbarState() {
- boolean hasHistory = episodes != null && !episodes.isEmpty();
- toolbar.getMenu().findItem(R.id.clear_history_item).setVisible(hasHistory);
+ @Override
+ protected String getPrefName() {
+ return TAG;
}
@Override
public boolean onMenuItemClick(MenuItem item) {
+ if (super.onOptionsItemSelected(item)) {
+ return true;
+ }
if (item.getItemId() == R.id.clear_history_item) {
DBWriter.clearPlaybackHistory();
return true;
@@ -94,43 +61,16 @@ public class PlaybackHistoryFragment extends EpisodesListFragment implements Too
return false;
}
- @Subscribe(threadMode = ThreadMode.MAIN)
- public void onHistoryUpdated(PlaybackHistoryEvent event) {
- loadItems();
- refreshToolbarState();
- }
-
- @Subscribe(threadMode = ThreadMode.MAIN)
- public void onPlayerStatusChanged(PlayerStatusEvent event) {
- loadItems();
- refreshToolbarState();
+ @Override
+ protected void updateToolbar() {
+ // Not calling super, as we do not have a refresh button that could be updated
+ toolbar.getMenu().findItem(R.id.clear_history_item).setVisible(!episodes.isEmpty());
}
- @Override
@Subscribe(threadMode = ThreadMode.MAIN)
- public void onUnreadItemsChanged(UnreadItemsUpdateEvent event) {
+ public void onHistoryUpdated(PlaybackHistoryEvent event) {
loadItems();
- refreshToolbarState();
- }
-
- @Override
- protected void onFragmentLoaded(List<FeedItem> episodes) {
- super.onFragmentLoaded(episodes);
- listAdapter.notifyDataSetChanged();
- refreshToolbarState();
- }
-
- private class PlaybackHistoryListAdapter extends EpisodeItemListAdapter {
-
- public PlaybackHistoryListAdapter(MainActivity mainActivity) {
- super(mainActivity);
- }
-
- @Override
- public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
- super.onCreateContextMenu(menu, v, menuInfo);
- MenuItemUtils.setOnClickListeners(menu, PlaybackHistoryFragment.this::onContextItemSelected);
- }
+ updateToolbar();
}
@NonNull
diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/swipeactions/SwipeActions.java b/app/src/main/java/de/danoeh/antennapod/fragment/swipeactions/SwipeActions.java
index be35f6503..afb79e497 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/swipeactions/SwipeActions.java
+++ b/app/src/main/java/de/danoeh/antennapod/fragment/swipeactions/SwipeActions.java
@@ -21,8 +21,8 @@ import java.util.List;
import de.danoeh.antennapod.R;
import de.danoeh.antennapod.dialog.SwipeActionsDialog;
+import de.danoeh.antennapod.fragment.AllEpisodesFragment;
import de.danoeh.antennapod.fragment.CompletedDownloadsFragment;
-import de.danoeh.antennapod.fragment.EpisodesFragment;
import de.danoeh.antennapod.fragment.InboxFragment;
import de.danoeh.antennapod.fragment.QueueFragment;
import de.danoeh.antennapod.model.feed.FeedItem;
@@ -106,7 +106,7 @@ public class SwipeActions extends ItemTouchHelper.SimpleCallback implements Life
defaultActions = SwipeAction.DELETE + "," + SwipeAction.DELETE;
break;
default:
- case EpisodesFragment.TAG:
+ case AllEpisodesFragment.TAG:
defaultActions = SwipeAction.MARK_FAV + "," + SwipeAction.START_DOWNLOAD;
break;
}
diff --git a/app/src/main/res/layout/all_episodes_fragment.xml b/app/src/main/res/layout/episodes_list_fragment.xml
index c1e7e6434..39a0c260a 100644
--- a/app/src/main/res/layout/all_episodes_fragment.xml
+++ b/app/src/main/res/layout/episodes_list_fragment.xml
@@ -6,11 +6,20 @@
android:layout_height="match_parent"
android:orientation="vertical">
+ <androidx.appcompat.widget.Toolbar
+ android:id="@+id/toolbar"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_alignParentTop="true"
+ android:minHeight="?attr/actionBarSize"
+ android:theme="?attr/actionBarTheme" />
+
<TextView
android:id="@+id/txtvInformation"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
+ android:layout_below="@id/toolbar"
android:paddingTop="2dp"
android:paddingBottom="2dp"
android:visibility="gone"
diff --git a/app/src/main/res/layout/list_container_fragment.xml b/app/src/main/res/layout/list_container_fragment.xml
deleted file mode 100644
index 1b6debb13..000000000
--- a/app/src/main/res/layout/list_container_fragment.xml
+++ /dev/null
@@ -1,23 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<RelativeLayout
- xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:app="http://schemas.android.com/apk/res-auto"
- android:layout_width="match_parent"
- android:layout_height="match_parent">
-
- <androidx.appcompat.widget.Toolbar
- android:id="@+id/toolbar"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_alignParentTop="true"
- android:minHeight="?attr/actionBarSize"
- android:theme="?attr/actionBarTheme"
- app:title="@string/inbox_label" />
-
- <FrameLayout
- android:id="@+id/listContent"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:layout_below="@+id/toolbar" />
-
-</RelativeLayout>
diff --git a/app/src/main/res/menu/episodes.xml b/app/src/main/res/menu/episodes.xml
index 4e6da923b..2841fc12f 100644
--- a/app/src/main/res/menu/episodes.xml
+++ b/app/src/main/res/menu/episodes.xml
@@ -21,7 +21,13 @@
android:icon="@drawable/ic_filter"
android:menuCategory="container"
android:title="@string/filter"
- android:visible="false"
- custom:showAsAction="ifRoom"/>
+ custom:showAsAction="always"/>
+
+ <item
+ android:id="@+id/action_favorites"
+ android:icon="@drawable/ic_star_border"
+ android:menuCategory="container"
+ android:title="@string/favorite_episodes_label"
+ custom:showAsAction="always"/>
</menu>
diff --git a/model/src/main/java/de/danoeh/antennapod/model/feed/FeedItemFilter.java b/model/src/main/java/de/danoeh/antennapod/model/feed/FeedItemFilter.java
index c9989e60a..460177d56 100644
--- a/model/src/main/java/de/danoeh/antennapod/model/feed/FeedItemFilter.java
+++ b/model/src/main/java/de/danoeh/antennapod/model/feed/FeedItemFilter.java
@@ -72,7 +72,36 @@ public class FeedItemFilter implements Serializable {
return properties.clone();
}
- public boolean isShowDownloaded() {
- return showDownloaded;
+ public boolean matches(FeedItem item) {
+ if (showNew && !item.isNew()) {
+ return false;
+ } else if (showPlayed && !item.isPlayed()) {
+ return false;
+ } else if (showUnplayed && item.isPlayed()) {
+ return false;
+ } else if (showPaused && !item.isInProgress()) {
+ return false;
+ } else if (showNotPaused && item.isInProgress()) {
+ return false;
+ } else if (showNew && !item.isNew()) {
+ return false;
+ } else if (showQueued && !item.isTagged(FeedItem.TAG_QUEUE)) {
+ return false;
+ } else if (showNotQueued && item.isTagged(FeedItem.TAG_QUEUE)) {
+ return false;
+ } else if (showDownloaded && !item.isDownloaded()) {
+ return false;
+ } else if (showNotDownloaded && item.isDownloaded()) {
+ return false;
+ } else if (showHasMedia && !item.hasMedia()) {
+ return false;
+ } else if (showNoMedia && item.hasMedia()) {
+ return false;
+ } else if (showIsFavorite && !item.isTagged(FeedItem.TAG_FAVORITE)) {
+ return false;
+ } else if (showNotFavorite && item.isTagged(FeedItem.TAG_FAVORITE)) {
+ return false;
+ }
+ return true;
}
}
diff --git a/ui/i18n/src/main/res/values/strings.xml b/ui/i18n/src/main/res/values/strings.xml
index 0242f75a2..35ccc9677 100644
--- a/ui/i18n/src/main/res/values/strings.xml
+++ b/ui/i18n/src/main/res/values/strings.xml
@@ -11,7 +11,6 @@
<string name="add_feed_label">Add Podcast</string>
<string name="episodes_label">Episodes</string>
<string name="queue_label">Queue</string>
- <string name="all_episodes_short_label">All</string>
<string name="inbox_label">Inbox</string>
<string name="favorite_episodes_label">Favorites</string>
<string name="settings_label">Settings</string>
@@ -233,7 +232,6 @@
<string name="visit_website_label">Visit Website</string>
<string name="skip_episode_label">Skip episode</string>
<string name="reset_position">Reset Playback Position</string>
- <string name="removed_item">Item removed</string>
<string name="no_items_selected">No items selected</string>
<!-- Download messages and labels -->
@@ -339,10 +337,9 @@
<string name="no_history_label">After you listen to an episode, it will appear here.</string>
<string name="no_all_episodes_head_label">No Episodes</string>
<string name="no_all_episodes_label">When you add a podcast, the episodes will be shown here.</string>
+ <string name="no_all_episodes_filtered_label">Try clearing the filter to see more episodes.</string>
<string name="no_inbox_head_label">No episodes in the inbox</string>
<string name="no_inbox_label">When new episodes arrive, they will be shown here. You can then decide if you are interested in them or not.</string>
- <string name="no_fav_episodes_head_label">No favorite episodes</string>
- <string name="no_fav_episodes_label">You can add episodes to the favorites by long-pressing them.</string>
<string name="no_subscriptions_head_label">No subscriptions</string>
<string name="no_subscriptions_label">To subscribe to a podcast, press the plus icon below.</string>