Add sort option to episodes screen (#6286)
This commit is contained in:
parent
50eb1e9cf9
commit
25ddd73f24
|
@ -13,6 +13,7 @@ import androidx.test.rule.ActivityTestRule;
|
|||
|
||||
import de.danoeh.antennapod.core.receiver.MediaButtonReceiver;
|
||||
import de.danoeh.antennapod.model.feed.FeedItemFilter;
|
||||
import de.danoeh.antennapod.model.feed.SortOrder;
|
||||
import de.danoeh.antennapod.playback.base.PlayerStatus;
|
||||
import org.awaitility.Awaitility;
|
||||
import org.hamcrest.Matcher;
|
||||
|
@ -252,7 +253,8 @@ public class PlaybackTest {
|
|||
openNavDrawer();
|
||||
onDrawerItem(withText(R.string.episodes_label)).perform(click());
|
||||
|
||||
final List<FeedItem> episodes = DBReader.getRecentlyPublishedEpisodes(0, 10, FeedItemFilter.unfiltered());
|
||||
final List<FeedItem> episodes = DBReader.getRecentlyPublishedEpisodes(0, 10,
|
||||
FeedItemFilter.unfiltered(), SortOrder.DATE_NEW_OLD);
|
||||
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)));
|
||||
|
@ -287,7 +289,8 @@ public class PlaybackTest {
|
|||
uiTestUtils.addLocalFeedData(true);
|
||||
DBWriter.clearQueue().get();
|
||||
activityTestRule.launchActivity(new Intent());
|
||||
final List<FeedItem> episodes = DBReader.getRecentlyPublishedEpisodes(0, 10, FeedItemFilter.unfiltered());
|
||||
final List<FeedItem> episodes = DBReader.getRecentlyPublishedEpisodes(0, 10,
|
||||
FeedItemFilter.unfiltered(), SortOrder.DATE_NEW_OLD);
|
||||
|
||||
startLocalPlayback();
|
||||
FeedMedia media = episodes.get(0).getMedia();
|
||||
|
|
|
@ -9,13 +9,17 @@ import android.view.View;
|
|||
import android.view.ViewGroup;
|
||||
import androidx.annotation.NonNull;
|
||||
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 de.danoeh.antennapod.model.feed.SortOrder;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.greenrobot.eventbus.Subscribe;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Shows all episodes (possibly filtered by user).
|
||||
|
@ -24,20 +28,55 @@ 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";
|
||||
public static final String PREF_SORT = "prefEpisodesSort";
|
||||
private SharedPreferences prefs;
|
||||
|
||||
@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);
|
||||
inflateSortMenu();
|
||||
toolbar.setTitle(R.string.episodes_label);
|
||||
updateToolbar();
|
||||
updateFilterUi();
|
||||
prefs = getActivity().getSharedPreferences(PREF_NAME, Context.MODE_PRIVATE);
|
||||
txtvInformation.setOnClickListener(
|
||||
v -> AllEpisodesFilterDialog.newInstance(getFilter()).show(getChildFragmentManager(), null));
|
||||
return root;
|
||||
}
|
||||
|
||||
private void inflateSortMenu() {
|
||||
MenuItem sortItem = toolbar.getMenu().findItem(R.id.episodes_sort);
|
||||
getActivity().getMenuInflater().inflate(R.menu.sort_menu, sortItem.getSubMenu());
|
||||
|
||||
// Remove the sorting options that are not needed in this fragment
|
||||
toolbar.getMenu().findItem(R.id.sort_episode_title).setVisible(false);
|
||||
toolbar.getMenu().findItem(R.id.sort_feed_title).setVisible(false);
|
||||
toolbar.getMenu().findItem(R.id.sort_random).setVisible(false);
|
||||
toolbar.getMenu().findItem(R.id.sort_smart_shuffle).setVisible(false);
|
||||
toolbar.getMenu().findItem(R.id.keep_sorted).setVisible(false);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
protected List<FeedItem> loadData() {
|
||||
return DBReader.getRecentlyPublishedEpisodes(0, page * EPISODES_PER_PAGE,
|
||||
getFilter(), getSortOrder());
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
protected List<FeedItem> loadMoreData(int page) {
|
||||
return DBReader.getRecentlyPublishedEpisodes((page - 1) * EPISODES_PER_PAGE,
|
||||
EPISODES_PER_PAGE, getFilter(), getSortOrder());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int loadTotalItemCount() {
|
||||
return DBReader.getTotalEpisodeCount(getFilter());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected FeedItemFilter getFilter() {
|
||||
SharedPreferences prefs = getActivity().getSharedPreferences(PREF_NAME, Context.MODE_PRIVATE);
|
||||
|
@ -71,13 +110,23 @@ public class AllEpisodesFragment extends EpisodesListFragment {
|
|||
}
|
||||
onFilterChanged(new AllEpisodesFilterDialog.AllEpisodesFilterChangedEvent(new HashSet<>(filter)));
|
||||
return true;
|
||||
} else {
|
||||
SortOrder sortOrder = MenuItemToSortOrderConverter.convert(item);
|
||||
if (sortOrder != null) {
|
||||
saveSortOrderAndRefresh(sortOrder);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private void saveSortOrderAndRefresh(SortOrder type) {
|
||||
prefs.edit().putString(PREF_SORT, "" + type.code).apply();
|
||||
loadItems();
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onFilterChanged(AllEpisodesFilterDialog.AllEpisodesFilterChangedEvent event) {
|
||||
SharedPreferences prefs = getActivity().getSharedPreferences(PREF_NAME, Context.MODE_PRIVATE);
|
||||
prefs.edit().putString(PREF_FILTER, StringUtils.join(event.filterValues, ",")).apply();
|
||||
updateFilterUi();
|
||||
page = 1;
|
||||
|
@ -96,4 +145,8 @@ public class AllEpisodesFragment extends EpisodesListFragment {
|
|||
toolbar.getMenu().findItem(R.id.action_favorites).setIcon(
|
||||
getFilter().showIsFavorite ? R.drawable.ic_star : R.drawable.ic_star_border);
|
||||
}
|
||||
|
||||
private SortOrder getSortOrder() {
|
||||
return SortOrder.fromCodeString(prefs.getString(PREF_SORT, "" + SortOrder.DATE_NEW_OLD.code));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -31,7 +31,6 @@ import de.danoeh.antennapod.core.event.DownloadEvent;
|
|||
import de.danoeh.antennapod.core.event.DownloaderUpdate;
|
||||
import de.danoeh.antennapod.core.menuhandler.MenuItemUtils;
|
||||
import de.danoeh.antennapod.core.service.download.DownloadService;
|
||||
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;
|
||||
|
@ -442,18 +441,12 @@ public abstract class EpisodesListFragment extends Fragment
|
|||
}
|
||||
|
||||
@NonNull
|
||||
protected List<FeedItem> loadData() {
|
||||
return DBReader.getRecentlyPublishedEpisodes(0, page * EPISODES_PER_PAGE, getFilter());
|
||||
}
|
||||
protected abstract List<FeedItem> loadData();
|
||||
|
||||
@NonNull
|
||||
protected List<FeedItem> loadMoreData(int page) {
|
||||
return DBReader.getRecentlyPublishedEpisodes((page - 1) * EPISODES_PER_PAGE, EPISODES_PER_PAGE, getFilter());
|
||||
}
|
||||
protected abstract List<FeedItem> loadMoreData(int page);
|
||||
|
||||
protected int loadTotalItemCount() {
|
||||
return DBReader.getTotalEpisodeCount(getFilter());
|
||||
}
|
||||
protected abstract int loadTotalItemCount();
|
||||
|
||||
protected abstract FeedItemFilter getFilter();
|
||||
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
android:icon="@drawable/ic_filter"
|
||||
android:menuCategory="container"
|
||||
android:title="@string/filter"
|
||||
custom:showAsAction="always"/>
|
||||
custom:showAsAction="ifRoom"/>
|
||||
|
||||
<item
|
||||
android:id="@+id/action_favorites"
|
||||
|
@ -30,4 +30,11 @@
|
|||
android:title="@string/favorite_episodes_label"
|
||||
custom:showAsAction="always"/>
|
||||
|
||||
<item
|
||||
android:id="@+id/episodes_sort"
|
||||
android:title="@string/sort"
|
||||
custom:showAsAction="never">
|
||||
<menu />
|
||||
</item>
|
||||
|
||||
</menu>
|
||||
|
|
|
@ -18,6 +18,7 @@ import de.danoeh.antennapod.core.export.ExportWriter;
|
|||
import de.danoeh.antennapod.model.feed.Feed;
|
||||
import de.danoeh.antennapod.model.feed.FeedItem;
|
||||
import de.danoeh.antennapod.core.storage.DBReader;
|
||||
import de.danoeh.antennapod.model.feed.SortOrder;
|
||||
|
||||
/** Writes saved favorites to file. */
|
||||
public class FavoritesWriter implements ExportWriter {
|
||||
|
@ -43,7 +44,7 @@ public class FavoritesWriter implements ExportWriter {
|
|||
String feedTemplate = IOUtils.toString(feedTemplateStream, UTF_8);
|
||||
|
||||
List<FeedItem> allFavorites = DBReader.getRecentlyPublishedEpisodes(0, Integer.MAX_VALUE,
|
||||
new FeedItemFilter(FeedItemFilter.IS_FAVORITE));
|
||||
new FeedItemFilter(FeedItemFilter.IS_FAVORITE), SortOrder.DATE_NEW_OLD);
|
||||
Map<Long, List<FeedItem>> favoriteByFeed = getFeedMap(allFavorites);
|
||||
|
||||
writer.append(templateParts[0]);
|
||||
|
|
|
@ -52,6 +52,7 @@ import de.danoeh.antennapod.event.playback.PlaybackServiceEvent;
|
|||
import de.danoeh.antennapod.event.PlayerErrorEvent;
|
||||
import de.danoeh.antennapod.event.playback.SleepTimerUpdatedEvent;
|
||||
import de.danoeh.antennapod.model.feed.FeedItemFilter;
|
||||
import de.danoeh.antennapod.model.feed.SortOrder;
|
||||
import de.danoeh.antennapod.playback.base.PlaybackServiceMediaPlayer;
|
||||
import de.danoeh.antennapod.playback.base.PlayerStatus;
|
||||
import de.danoeh.antennapod.playback.cast.CastPsmp;
|
||||
|
@ -417,7 +418,7 @@ public class PlaybackService extends MediaBrowserServiceCompat {
|
|||
} else if (parentId.equals(getResources().getString(R.string.episodes_label))) {
|
||||
feedItems = DBReader.getRecentlyPublishedEpisodes(0,
|
||||
MAX_ANDROID_AUTO_EPISODES_PER_FEED,
|
||||
new FeedItemFilter(FeedItemFilter.UNPLAYED));
|
||||
new FeedItemFilter(FeedItemFilter.UNPLAYED), SortOrder.DATE_NEW_OLD);
|
||||
} else if (parentId.startsWith("FeedId:")) {
|
||||
long feedId = Long.parseLong(parentId.split(":")[1]);
|
||||
feedItems = DBReader.getFeedItemList(DBReader.getFeed(feedId));
|
||||
|
|
|
@ -366,12 +366,12 @@ public final class DBReader {
|
|||
* @param filter The filter describing which episodes to filter out.
|
||||
*/
|
||||
@NonNull
|
||||
public static List<FeedItem> getRecentlyPublishedEpisodes(int offset, int limit, FeedItemFilter filter) {
|
||||
public static List<FeedItem> getRecentlyPublishedEpisodes(int offset, int limit,
|
||||
FeedItemFilter filter, SortOrder sortOrder) {
|
||||
Log.d(TAG, "getRecentlyPublishedEpisodes() called with: offset=" + offset + ", limit=" + limit);
|
||||
|
||||
PodDBAdapter adapter = PodDBAdapter.getInstance();
|
||||
adapter.open();
|
||||
try (Cursor cursor = adapter.getRecentlyPublishedItemsCursor(offset, limit, filter)) {
|
||||
try (Cursor cursor = adapter.getRecentlyPublishedItemsCursor(offset, limit, filter, sortOrder)) {
|
||||
List<FeedItem> items = extractItemlistFromCursor(adapter, cursor);
|
||||
loadAdditionalFeedItemListData(items);
|
||||
return items;
|
||||
|
|
|
@ -45,6 +45,8 @@ import org.apache.commons.io.FileUtils;
|
|||
import static de.danoeh.antennapod.model.feed.FeedPreferences.SPEED_USE_GLOBAL;
|
||||
import static de.danoeh.antennapod.model.feed.SortOrder.toCodeString;
|
||||
|
||||
import de.danoeh.antennapod.storage.database.mapper.FeedItemSortQuery;
|
||||
|
||||
/**
|
||||
* Implements methods for accessing the database
|
||||
*/
|
||||
|
@ -1059,11 +1061,13 @@ public class PodDBAdapter {
|
|||
return db.rawQuery(query, null);
|
||||
}
|
||||
|
||||
public final Cursor getRecentlyPublishedItemsCursor(int offset, int limit, FeedItemFilter filter) {
|
||||
public final Cursor getRecentlyPublishedItemsCursor(int offset, int limit,
|
||||
FeedItemFilter filter, SortOrder sortOrder) {
|
||||
String orderByQuery = FeedItemSortQuery.generateFrom(sortOrder);
|
||||
String filterQuery = FeedItemFilterQuery.generateFrom(filter);
|
||||
String whereClause = "".equals(filterQuery) ? "" : " WHERE " + filterQuery;
|
||||
final String query = SELECT_FEED_ITEMS_AND_MEDIA + whereClause
|
||||
+ " ORDER BY " + KEY_PUBDATE + " DESC LIMIT " + offset + ", " + limit;
|
||||
+ "ORDER BY " + orderByQuery + " LIMIT " + offset + ", " + limit;
|
||||
return db.rawQuery(query, null);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue