sort in Podcast screen - implement all the sorts

This commit is contained in:
orionlee 2019-10-24 11:01:48 -07:00
parent 05dfccacc3
commit f56a02d513
9 changed files with 86 additions and 102 deletions

View File

@ -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);
}

View File

@ -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<FeedItem> 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<FeedItem> feedItems = feed.getItems();
QueueSorter.getPermutor(feed.getSortOrder()).reorder(feedItems);
feed.setItems(feedItems);
}
return Optional.ofNullable(feed);
}

View File

@ -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);
}

View File

@ -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;
}

View File

@ -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;
}
}

View File

@ -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 {
/**

View File

@ -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();

View File

@ -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)});

View File

@ -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;
}
}