diff options
7 files changed, 149 insertions, 6 deletions
diff --git a/app/src/main/java/de/danoeh/antennapod/dialog/IntraFeedSortDialog.java b/app/src/main/java/de/danoeh/antennapod/dialog/IntraFeedSortDialog.java new file mode 100644 index 000000000..a554f8d76 --- /dev/null +++ b/app/src/main/java/de/danoeh/antennapod/dialog/IntraFeedSortDialog.java @@ -0,0 +1,51 @@ +package de.danoeh.antennapod.dialog; + +import android.content.Context; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.appcompat.app.AlertDialog; + +import de.danoeh.antennapod.R; +import de.danoeh.antennapod.core.feed.IntraFeedSortOrder; + +public abstract class IntraFeedSortDialog { + + @Nullable + protected IntraFeedSortOrder currentSortOrder; + @NonNull + protected Context context; + + public IntraFeedSortDialog(@NonNull Context context, @Nullable IntraFeedSortOrder sortOrder) { + this.context = context; + this.currentSortOrder = sortOrder; + } + + 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]; + for (int i = 0; i < valueStrs.length; i++) { + values[i] = IntraFeedSortOrder.valueOf(valueStrs[i]); + } + + int idxCurrentSort = -1; + for (int i = 0; i < values.length; i++) { + if (currentSortOrder == values[i]) { + idxCurrentSort = i; + break; + } + } + + AlertDialog.Builder builder = new AlertDialog.Builder(context); + builder.setTitle(R.string.sort); + builder.setSingleChoiceItems(items, idxCurrentSort, (dialog, idxNewSort) -> { + updateSort(values[idxNewSort]); + dialog.dismiss(); + }); + builder.setNegativeButton(R.string.cancel_label, null); + builder.create().show(); + } + + protected abstract void updateSort(@NonNull IntraFeedSortOrder 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 0c33dce5a..471651e88 100644 --- a/app/src/main/java/de/danoeh/antennapod/fragment/FeedItemlistFragment.java +++ b/app/src/main/java/de/danoeh/antennapod/fragment/FeedItemlistFragment.java @@ -5,10 +5,6 @@ import android.content.Context; import android.content.DialogInterface; import android.graphics.LightingColorFilter; import android.os.Bundle; -import androidx.annotation.NonNull; -import androidx.fragment.app.ListFragment; -import androidx.core.view.MenuItemCompat; -import androidx.appcompat.widget.SearchView; import android.util.Log; import android.view.ContextMenu; import android.view.LayoutInflater; @@ -23,12 +19,16 @@ import android.widget.ListView; import android.widget.RelativeLayout; import android.widget.TextView; +import androidx.annotation.NonNull; +import androidx.appcompat.widget.SearchView; +import androidx.core.view.MenuItemCompat; +import androidx.fragment.app.ListFragment; + import com.bumptech.glide.Glide; import com.bumptech.glide.request.RequestOptions; import com.joanzapata.iconify.Iconify; import com.joanzapata.iconify.widget.IconTextView; -import de.danoeh.antennapod.core.event.PlaybackPositionEvent; import org.apache.commons.lang3.Validate; import org.greenrobot.eventbus.EventBus; import org.greenrobot.eventbus.Subscribe; @@ -45,6 +45,7 @@ import de.danoeh.antennapod.core.dialog.DownloadRequestErrorDialogCreator; import de.danoeh.antennapod.core.event.DownloadEvent; import de.danoeh.antennapod.core.event.DownloaderUpdate; import de.danoeh.antennapod.core.event.FeedItemEvent; +import de.danoeh.antennapod.core.event.PlaybackPositionEvent; import de.danoeh.antennapod.core.feed.EventDistributor; import de.danoeh.antennapod.core.feed.Feed; import de.danoeh.antennapod.core.feed.FeedEvent; @@ -192,6 +193,7 @@ public class FeedItemlistFragment extends ListFragment { searchItem.setOnActionExpandListener(new MenuItem.OnActionExpandListener() { @Override public boolean onMenuItemActionExpand(MenuItem item) { + menu.findItem(R.id.sort_items).setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER); menu.findItem(R.id.filter_items).setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER); menu.findItem(R.id.episode_actions).setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER); menu.findItem(R.id.refresh_item).setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER); @@ -623,6 +625,7 @@ public class FeedItemlistFragment extends ListFragment { @NonNull private Optional<Feed> loadData() { + // TODO-2524: apply sorting, either at db level or here Feed feed = DBReader.getFeed(feedID); if (feed != null && feed.getItemFilter() != null) { DBReader.loadAdditionalFeedItemListData(feed.getItems()); 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 f7aae8cde..5e0d65d0c 100644 --- a/app/src/main/java/de/danoeh/antennapod/menuhandler/FeedMenuHandler.java +++ b/app/src/main/java/de/danoeh/antennapod/menuhandler/FeedMenuHandler.java @@ -7,6 +7,8 @@ import android.view.Menu; import android.view.MenuInflater; import android.view.MenuItem; +import androidx.annotation.NonNull; + import org.apache.commons.lang3.StringUtils; import java.util.Set; @@ -14,12 +16,14 @@ 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.dialog.FilterDialog; +import de.danoeh.antennapod.dialog.IntraFeedSortDialog; /** * Handles interactions with the FeedItemMenu. @@ -65,6 +69,9 @@ public class FeedMenuHandler { case R.id.refresh_complete_item: DBTasks.forceRefreshCompleteFeed(context, selectedFeed); break; + case R.id.sort_items: + showSortDialog(context, selectedFeed); + break; case R.id.filter_items: showFilterDialog(context, selectedFeed); break; @@ -108,4 +115,17 @@ public class FeedMenuHandler { filterDialog.openDialog(); } + + + private static void showSortDialog(Context context, Feed selectedFeed) { + IntraFeedSortDialog sortDialog = new IntraFeedSortDialog(context, selectedFeed.getSortOrder()) { + @Override + protected void updateSort(@NonNull IntraFeedSortOrder sortOrder) { + selectedFeed.setSortOrder(sortOrder); + // TODO-2524: update in db + } + }; + sortDialog.openDialog(); + } + } diff --git a/app/src/main/res/menu/feedlist.xml b/app/src/main/res/menu/feedlist.xml index fdd0e01bc..8ff569505 100644 --- a/app/src/main/res/menu/feedlist.xml +++ b/app/src/main/res/menu/feedlist.xml @@ -3,6 +3,13 @@ xmlns:custom="http://schemas.android.com/apk/res-auto"> <item + android:id="@+id/sort_items" + android:icon="?attr/ic_sort" + android:menuCategory="container" + android:title="@string/sort" + custom:showAsAction="always"> + </item> + <item android:id="@+id/filter_items" android:icon="?attr/ic_filter" android:menuCategory="container" 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 6a7c97b7b..8f3e3d1c3 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 @@ -1,9 +1,10 @@ package de.danoeh.antennapod.core.feed; import android.database.Cursor; -import androidx.annotation.Nullable; import android.text.TextUtils; +import androidx.annotation.Nullable; + import java.util.ArrayList; import java.util.Date; import java.util.List; @@ -87,6 +88,8 @@ 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; + @Nullable + private IntraFeedSortOrder sortOrder; /** * This constructor is used for restoring a feed from the database. @@ -523,6 +526,15 @@ public class Feed extends FeedFile implements ImageResource { } } + @Nullable + public IntraFeedSortOrder getSortOrder() { + return sortOrder; + } + + public void setSortOrder(@Nullable IntraFeedSortOrder sortOrder) { + this.sortOrder = sortOrder; + } + public boolean hasLastUpdateFailed() { return this.lastUpdateFailed; } 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 new file mode 100644 index 000000000..03a1b0e0c --- /dev/null +++ b/core/src/main/java/de/danoeh/antennapod/core/feed/IntraFeedSortOrder.java @@ -0,0 +1,31 @@ +package de.danoeh.antennapod.core.feed; + +/** + * 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); + + 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; + } + } +} diff --git a/core/src/main/res/values/arrays.xml b/core/src/main/res/values/arrays.xml index 5e7eab1ea..2dd985d6a 100644 --- a/core/src/main/res/values/arrays.xml +++ b/core/src/main/res/values/arrays.xml @@ -254,6 +254,25 @@ <item>is_favorite</item> </string-array> + <!-- sort for podcast screen, not for queue --> + <string-array name="feed_episodes_sort_options"> + <item>@string/sort_date_new_old</item> + <item>@string/sort_date_old_new</item> + <item>@string/sort_title_a_z</item> + <item>@string/sort_title_z_a</item> + <item>@string/sort_duration_short_long</item> + <item>@string/sort_duration_long_short</item> + </string-array> + + <string-array name="feed_episodes_sort_values"> + <item>DATE_NEW_OLD</item> + <item>DATE_OLD_NEW</item> + <item>EPISODE_TITLE_A_Z</item> + <item>EPISODE_TITLE_Z_A</item> + <item>DURATION_SHORT_LONG</item> + <item>DURATION_LONG_SHORT</item> + </string-array> + <string-array name="image_cache_size_options"> <item>20 MiB</item> <item>50 MiB</item> |