From f56a02d5138c7dc63d371de65e527b7b50f60255 Mon Sep 17 00:00:00 2001 From: orionlee Date: Thu, 24 Oct 2019 11:01:48 -0700 Subject: [PATCH] sort in Podcast screen - implement all the sorts --- .../dialog/IntraFeedSortDialog.java | 12 ++-- .../fragment/FeedItemlistFragment.java | 21 ++----- .../menuhandler/FeedMenuHandler.java | 4 +- .../de/danoeh/antennapod/core/feed/Feed.java | 22 +++++-- .../core/feed/IntraFeedSortOrder.java | 54 ---------------- .../antennapod/core/storage/DBUpgrader.java | 2 +- .../antennapod/core/storage/DBWriter.java | 3 +- .../antennapod/core/storage/PodDBAdapter.java | 8 +-- .../antennapod/core/util/SortOrder.java | 62 +++++++++++++++---- 9 files changed, 86 insertions(+), 102 deletions(-) delete mode 100644 core/src/main/java/de/danoeh/antennapod/core/feed/IntraFeedSortOrder.java diff --git a/app/src/main/java/de/danoeh/antennapod/dialog/IntraFeedSortDialog.java b/app/src/main/java/de/danoeh/antennapod/dialog/IntraFeedSortDialog.java index a554f8d76..2ee716c7c 100644 --- a/app/src/main/java/de/danoeh/antennapod/dialog/IntraFeedSortDialog.java +++ b/app/src/main/java/de/danoeh/antennapod/dialog/IntraFeedSortDialog.java @@ -7,16 +7,16 @@ import androidx.annotation.Nullable; import androidx.appcompat.app.AlertDialog; import de.danoeh.antennapod.R; -import de.danoeh.antennapod.core.feed.IntraFeedSortOrder; +import de.danoeh.antennapod.core.util.SortOrder; public abstract class IntraFeedSortDialog { @Nullable - protected IntraFeedSortOrder currentSortOrder; + protected SortOrder currentSortOrder; @NonNull protected Context context; - public IntraFeedSortDialog(@NonNull Context context, @Nullable IntraFeedSortOrder sortOrder) { + public IntraFeedSortDialog(@NonNull Context context, @Nullable SortOrder sortOrder) { this.context = context; this.currentSortOrder = sortOrder; } @@ -24,9 +24,9 @@ public abstract class IntraFeedSortDialog { public void openDialog() { final String[] items = context.getResources().getStringArray(R.array.feed_episodes_sort_options); final String[] valueStrs = context.getResources().getStringArray(R.array.feed_episodes_sort_values); - final IntraFeedSortOrder[] values = new IntraFeedSortOrder[valueStrs.length]; + final SortOrder[] values = new SortOrder[valueStrs.length]; for (int i = 0; i < valueStrs.length; i++) { - values[i] = IntraFeedSortOrder.valueOf(valueStrs[i]); + values[i] = SortOrder.valueOf(valueStrs[i]); } int idxCurrentSort = -1; @@ -47,5 +47,5 @@ public abstract class IntraFeedSortDialog { builder.create().show(); } - protected abstract void updateSort(@NonNull IntraFeedSortOrder sortOrder); + protected abstract void updateSort(@NonNull SortOrder sortOrder); } 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 415af83d5..88f48003f 100644 --- a/app/src/main/java/de/danoeh/antennapod/fragment/FeedItemlistFragment.java +++ b/app/src/main/java/de/danoeh/antennapod/fragment/FeedItemlistFragment.java @@ -34,7 +34,6 @@ import org.greenrobot.eventbus.EventBus; import org.greenrobot.eventbus.Subscribe; import org.greenrobot.eventbus.ThreadMode; -import java.util.Collections; import java.util.List; import de.danoeh.antennapod.R; @@ -53,7 +52,6 @@ import de.danoeh.antennapod.core.feed.FeedEvent; import de.danoeh.antennapod.core.feed.FeedItem; import de.danoeh.antennapod.core.feed.FeedItemFilter; import de.danoeh.antennapod.core.feed.FeedMedia; -import de.danoeh.antennapod.core.feed.IntraFeedSortOrder; import de.danoeh.antennapod.core.glide.ApGlideSettings; import de.danoeh.antennapod.core.glide.FastBlurTransformation; import de.danoeh.antennapod.core.service.download.DownloadService; @@ -65,7 +63,7 @@ import de.danoeh.antennapod.core.storage.DownloadRequester; import de.danoeh.antennapod.core.util.FeedItemUtil; import de.danoeh.antennapod.core.util.LongList; import de.danoeh.antennapod.core.util.Optional; -import de.danoeh.antennapod.core.util.comparator.FeedItemPubdateComparator; +import de.danoeh.antennapod.core.util.QueueSorter; import de.danoeh.antennapod.core.util.gui.MoreContentListFooterUtil; import de.danoeh.antennapod.dialog.EpisodesApplyActionFragment; import de.danoeh.antennapod.dialog.RenameFeedDialog; @@ -634,19 +632,10 @@ public class FeedItemlistFragment extends ListFragment { FeedItemFilter filter = feed.getItemFilter(); feed.setItems(filter.filter(feed.getItems())); } - IntraFeedSortOrder sortOrder = feed.getSortOrder(); - if (sortOrder != null) { - long tS = System.currentTimeMillis(); // TODO-2524: - if (sortOrder == IntraFeedSortOrder.DATE_OLD_NEW) { - List feedItems = feed.getItems(); - Collections.sort(feedItems, FeedItemPubdateComparator.ascending); - feed.setItems(feedItems); - } else { - System.err.println("DBG - to-implement: " + sortOrder); // TODO-2524: - } - long tE = System.currentTimeMillis(); - System.err.println("DBG - sort elapsed time: " + (tE -tS) + - "ms ; " + "num items: " + feed.getItems().size() + ", order: " + sortOrder); // TODO: 2524 + if (feed != null && feed.getSortOrder() != null) { + List feedItems = feed.getItems(); + QueueSorter.getPermutor(feed.getSortOrder()).reorder(feedItems); + feed.setItems(feedItems); } return Optional.ofNullable(feed); } diff --git a/app/src/main/java/de/danoeh/antennapod/menuhandler/FeedMenuHandler.java b/app/src/main/java/de/danoeh/antennapod/menuhandler/FeedMenuHandler.java index 53d95bd1c..e32deba27 100644 --- a/app/src/main/java/de/danoeh/antennapod/menuhandler/FeedMenuHandler.java +++ b/app/src/main/java/de/danoeh/antennapod/menuhandler/FeedMenuHandler.java @@ -16,12 +16,12 @@ import java.util.Set; import de.danoeh.antennapod.R; import de.danoeh.antennapod.core.dialog.ConfirmationDialog; import de.danoeh.antennapod.core.feed.Feed; -import de.danoeh.antennapod.core.feed.IntraFeedSortOrder; import de.danoeh.antennapod.core.storage.DBTasks; import de.danoeh.antennapod.core.storage.DBWriter; import de.danoeh.antennapod.core.storage.DownloadRequestException; import de.danoeh.antennapod.core.util.IntentUtils; import de.danoeh.antennapod.core.util.ShareUtils; +import de.danoeh.antennapod.core.util.SortOrder; import de.danoeh.antennapod.dialog.FilterDialog; import de.danoeh.antennapod.dialog.IntraFeedSortDialog; @@ -120,7 +120,7 @@ public class FeedMenuHandler { private static void showSortDialog(Context context, Feed selectedFeed) { IntraFeedSortDialog sortDialog = new IntraFeedSortDialog(context, selectedFeed.getSortOrder()) { @Override - protected void updateSort(@NonNull IntraFeedSortOrder sortOrder) { + protected void updateSort(@NonNull SortOrder sortOrder) { selectedFeed.setSortOrder(sortOrder); DBWriter.setFeedItemSortOrder(selectedFeed.getId(), sortOrder); } diff --git a/core/src/main/java/de/danoeh/antennapod/core/feed/Feed.java b/core/src/main/java/de/danoeh/antennapod/core/feed/Feed.java index 8821e8c0e..81df6d42a 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/feed/Feed.java +++ b/core/src/main/java/de/danoeh/antennapod/core/feed/Feed.java @@ -12,6 +12,7 @@ import java.util.List; import de.danoeh.antennapod.core.asynctask.ImageResource; import de.danoeh.antennapod.core.storage.DBWriter; import de.danoeh.antennapod.core.storage.PodDBAdapter; +import de.danoeh.antennapod.core.util.SortOrder; /** * Data Object for a whole feed @@ -89,8 +90,13 @@ public class Feed extends FeedFile implements ImageResource { * Contains property strings. If such a property applies to a feed item, it is not shown in the feed list */ private FeedItemFilter itemfilter; + + /** + * User-preferred sortOrder for display. + * Only those of scope {@link SortOrder.Scope#INTRA_FEED} is allowed. + */ @Nullable - private IntraFeedSortOrder sortOrder; + private SortOrder sortOrder; /** * This constructor is used for restoring a feed from the database. @@ -98,7 +104,7 @@ public class Feed extends FeedFile implements ImageResource { public Feed(long id, String lastUpdate, String title, String customTitle, String link, String description, String paymentLink, String author, String language, String type, String feedIdentifier, String imageUrl, String fileUrl, String downloadUrl, boolean downloaded, boolean paged, String nextPageLink, - String filter, @Nullable IntraFeedSortOrder sortOrder, boolean lastUpdateFailed) { + String filter, @Nullable SortOrder sortOrder, boolean lastUpdateFailed) { super(fileUrl, downloadUrl, downloaded); this.id = id; this.feedTitle = title; @@ -120,7 +126,7 @@ public class Feed extends FeedFile implements ImageResource { } else { this.itemfilter = new FeedItemFilter(new String[0]); } - this.sortOrder = sortOrder; + setSortOrder(sortOrder); this.lastUpdateFailed = lastUpdateFailed; } @@ -209,7 +215,7 @@ public class Feed extends FeedFile implements ImageResource { cursor.getInt(indexIsPaged) > 0, cursor.getString(indexNextPageLink), cursor.getString(indexHide), - IntraFeedSortOrder.fromCode(cursor.getInt(indexSortOrder)), + SortOrder.fromCode(cursor.getInt(indexSortOrder)), cursor.getInt(indexLastUpdateFailed) > 0 ); @@ -531,11 +537,15 @@ public class Feed extends FeedFile implements ImageResource { } @Nullable - public IntraFeedSortOrder getSortOrder() { + public SortOrder getSortOrder() { return sortOrder; } - public void setSortOrder(@Nullable IntraFeedSortOrder sortOrder) { + public void setSortOrder(@Nullable SortOrder sortOrder) { + if (sortOrder != null && sortOrder.scope != SortOrder.Scope.INTRA_FEED) { + throw new IllegalArgumentException("The specified sortOrder " + sortOrder + + " is invalid. Only those with INTRA_FEED scope are allowed."); + } this.sortOrder = sortOrder; } diff --git a/core/src/main/java/de/danoeh/antennapod/core/feed/IntraFeedSortOrder.java b/core/src/main/java/de/danoeh/antennapod/core/feed/IntraFeedSortOrder.java deleted file mode 100644 index c2bf3409d..000000000 --- a/core/src/main/java/de/danoeh/antennapod/core/feed/IntraFeedSortOrder.java +++ /dev/null @@ -1,54 +0,0 @@ -package de.danoeh.antennapod.core.feed; - -import androidx.annotation.Nullable; - -/** - * Provides sort orders to sort a list of episodes within a feed. - */ -public enum IntraFeedSortOrder { - DATE_OLD_NEW(1), - DATE_NEW_OLD(2), - EPISODE_TITLE_A_Z(3), - EPISODE_TITLE_Z_A(4), - DURATION_SHORT_LONG(5), - DURATION_LONG_SHORT(6); - - // The constant SHOULD NEVER be changed, as it is used in db DDLs - public static final int CODE_UNSPECIFIED = 0; - - public final int code; - - IntraFeedSortOrder(int code) { - this.code = code; - } - - /** - * Converts the string representation to its enum value. If the string value is unknown, - * the given default value is returned. - */ - public static IntraFeedSortOrder parseWithDefault(String value, IntraFeedSortOrder defaultValue) { - try { - return valueOf(value); - } catch (IllegalArgumentException e) { - return defaultValue; - } - } - - @Nullable - public static IntraFeedSortOrder fromCode(int code) { - if (code == CODE_UNSPECIFIED) { // sort order not specified - return null; - } - for (IntraFeedSortOrder sortOrder : values()) { - if (sortOrder.code == code) { - return sortOrder; - } - } - throw new IllegalArgumentException("Unsupported code: " + code); - } - - public static int toCode(@Nullable IntraFeedSortOrder sortOrder) { - return sortOrder != null ? sortOrder.code : CODE_UNSPECIFIED; - } - -} diff --git a/core/src/main/java/de/danoeh/antennapod/core/storage/DBUpgrader.java b/core/src/main/java/de/danoeh/antennapod/core/storage/DBUpgrader.java index ed91b5690..6c15be15d 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/storage/DBUpgrader.java +++ b/core/src/main/java/de/danoeh/antennapod/core/storage/DBUpgrader.java @@ -9,7 +9,7 @@ import android.util.Log; import de.danoeh.antennapod.core.feed.FeedItem; import static de.danoeh.antennapod.core.feed.FeedPreferences.SPEED_USE_GLOBAL; -import static de.danoeh.antennapod.core.feed.IntraFeedSortOrder.CODE_UNSPECIFIED; +import static de.danoeh.antennapod.core.util.SortOrder.CODE_UNSPECIFIED; class DBUpgrader { /** diff --git a/core/src/main/java/de/danoeh/antennapod/core/storage/DBWriter.java b/core/src/main/java/de/danoeh/antennapod/core/storage/DBWriter.java index a21ab694d..912c67da3 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/storage/DBWriter.java +++ b/core/src/main/java/de/danoeh/antennapod/core/storage/DBWriter.java @@ -31,7 +31,6 @@ import de.danoeh.antennapod.core.feed.FeedEvent; import de.danoeh.antennapod.core.feed.FeedItem; import de.danoeh.antennapod.core.feed.FeedMedia; import de.danoeh.antennapod.core.feed.FeedPreferences; -import de.danoeh.antennapod.core.feed.IntraFeedSortOrder; import de.danoeh.antennapod.core.gpoddernet.model.GpodnetEpisodeAction; import de.danoeh.antennapod.core.preferences.GpodnetPreferences; import de.danoeh.antennapod.core.preferences.PlaybackPreferences; @@ -950,7 +949,7 @@ public class DBWriter { * Set item sort order of the feed * */ - public static Future setFeedItemSortOrder(long feedId, @Nullable IntraFeedSortOrder sortOrder) { + public static Future setFeedItemSortOrder(long feedId, @Nullable SortOrder sortOrder) { return dbExec.submit(() -> { PodDBAdapter adapter = PodDBAdapter.getInstance(); adapter.open(); diff --git a/core/src/main/java/de/danoeh/antennapod/core/storage/PodDBAdapter.java b/core/src/main/java/de/danoeh/antennapod/core/storage/PodDBAdapter.java index 0ac596e67..755367147 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/storage/PodDBAdapter.java +++ b/core/src/main/java/de/danoeh/antennapod/core/storage/PodDBAdapter.java @@ -32,14 +32,14 @@ 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.feed.FeedPreferences; -import de.danoeh.antennapod.core.feed.IntraFeedSortOrder; import de.danoeh.antennapod.core.preferences.UserPreferences; import de.danoeh.antennapod.core.service.download.DownloadStatus; import de.danoeh.antennapod.core.util.LongIntMap; +import de.danoeh.antennapod.core.util.SortOrder; import static de.danoeh.antennapod.core.feed.FeedPreferences.SPEED_USE_GLOBAL; -import static de.danoeh.antennapod.core.feed.IntraFeedSortOrder.CODE_UNSPECIFIED; -import static de.danoeh.antennapod.core.feed.IntraFeedSortOrder.toCode; +import static de.danoeh.antennapod.core.util.SortOrder.CODE_UNSPECIFIED; +import static de.danoeh.antennapod.core.util.SortOrder.toCode; // TODO Remove media column from feeditem table @@ -423,7 +423,7 @@ public class PodDBAdapter { db.update(TABLE_NAME_FEEDS, values, KEY_ID + "=?", new String[]{String.valueOf(feedId)}); } - public void setFeedItemSortOrder(long feedId, @Nullable IntraFeedSortOrder sortOrder) { + public void setFeedItemSortOrder(long feedId, @Nullable SortOrder sortOrder) { ContentValues values = new ContentValues(); values.put(KEY_SORT_ORDER, toCode(sortOrder)); db.update(TABLE_NAME_FEEDS, values, KEY_ID + "=?", new String[]{String.valueOf(feedId)}); diff --git a/core/src/main/java/de/danoeh/antennapod/core/util/SortOrder.java b/core/src/main/java/de/danoeh/antennapod/core/util/SortOrder.java index ae6fceb47..b604e7f8e 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/util/SortOrder.java +++ b/core/src/main/java/de/danoeh/antennapod/core/util/SortOrder.java @@ -1,20 +1,43 @@ package de.danoeh.antennapod.core.util; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; + +import static de.danoeh.antennapod.core.util.SortOrder.Scope.INTER_FEED; +import static de.danoeh.antennapod.core.util.SortOrder.Scope.INTRA_FEED; + /** * Provides sort orders to sort a list of episodes. */ public enum SortOrder { - EPISODE_TITLE_A_Z, - EPISODE_TITLE_Z_A, - DATE_OLD_NEW, - DATE_NEW_OLD, - DURATION_SHORT_LONG, - DURATION_LONG_SHORT, - FEED_TITLE_A_Z, - FEED_TITLE_Z_A, - RANDOM, - SMART_SHUFFLE_OLD_NEW, - SMART_SHUFFLE_NEW_OLD; + DATE_OLD_NEW(1, INTRA_FEED), + DATE_NEW_OLD(2, INTRA_FEED), + EPISODE_TITLE_A_Z(3, INTRA_FEED), + EPISODE_TITLE_Z_A(4, INTRA_FEED), + DURATION_SHORT_LONG(5, INTRA_FEED), + DURATION_LONG_SHORT(6, INTRA_FEED), + FEED_TITLE_A_Z(101, INTER_FEED), + FEED_TITLE_Z_A(102, INTER_FEED), + RANDOM(103, INTER_FEED), + SMART_SHUFFLE_OLD_NEW(104, INTER_FEED), + SMART_SHUFFLE_NEW_OLD(105, INTER_FEED); + + public enum Scope { + INTRA_FEED, INTER_FEED; + } + + // The constant SHOULD NEVER be changed, as it is used in db DDLs + public static final int CODE_UNSPECIFIED = 0; + + public final int code; + + @NonNull + public final Scope scope; + + SortOrder(int code, @NonNull Scope scope) { + this.code = code; + this.scope = scope; + } /** * Converts the string representation to its enum value. If the string value is unknown, @@ -27,4 +50,21 @@ public enum SortOrder { return defaultValue; } } + + @Nullable + public static SortOrder fromCode(int code) { + if (code == CODE_UNSPECIFIED) { + return null; + } + for (SortOrder sortOrder : values()) { + if (sortOrder.code == code) { + return sortOrder; + } + } + throw new IllegalArgumentException("Unsupported code: " + code); + } + + public static int toCode(@Nullable SortOrder sortOrder) { + return sortOrder != null ? sortOrder.code : CODE_UNSPECIFIED; + } }