Repository: AntennaPod/AntennaPod (language: java)

Issue:
Sort downloads by size
### Checklist

- [X] I have used the search function for [open](https://github.com/AntennaPod/AntennaPod/issues) **and** [closed](https://github.com/AntennaPod/AntennaPod/issues?q=is%3Aissue+is%3Aclosed) issues to see if someone else has already submitted the same feature request.
- [X] I will describe the problem with as much detail as possible.
- [X] This request contains only one single feature, **not** a list of multiple (related) features.

### App version

3.1.0

### Where did you get the app from

Google Play

### Problem you may be having, or feature you want

The Downloads pane supports sorting by date, duration and title, but it would be nice to be able to sort by size of the file, to see large episodes that are taking up space.

### Suggested solution

Add a new sort

### Screenshots / Drawings / Technical details

_No response_


Discussion hints:
Hey @Julian . I would like to work on this issue!! Is this still open?
Yes, it is still open :)
Great!! I would like to work on it then.

Pull request: Add sort downloads by size feature
I want to try to resolve #6642 .
Please make a review. I hope it helps.

Test command: ./gradlew :core:testFreeDebugUnitTest --tests "de.danoeh.antennapod.core.util.FeedItemPermutorsTest"

Fix patch:
diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/CompletedDownloadsFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/CompletedDownloadsFragment.java
index ba328adba71..730a3918988 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/CompletedDownloadsFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/fragment/CompletedDownloadsFragment.java
@@ -159,6 +159,7 @@ private void inflateSortMenu(MaterialToolbar toolbar) {
         menu.findItem(R.id.sort_random).setVisible(false);
         menu.findItem(R.id.sort_smart_shuffle).setVisible(false);
         menu.findItem(R.id.keep_sorted).setVisible(false);
+        menu.findItem(R.id.sort_size).setVisible(true);
     }
 
     @Override
diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/MenuItemToSortOrderConverter.java b/app/src/main/java/de/danoeh/antennapod/fragment/MenuItemToSortOrderConverter.java
index 51911b12281..d4150fbdb5f 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/MenuItemToSortOrderConverter.java
+++ b/app/src/main/java/de/danoeh/antennapod/fragment/MenuItemToSortOrderConverter.java
@@ -32,6 +32,10 @@ public static SortOrder convert(MenuItem item) {
             return SortOrder.SMART_SHUFFLE_OLD_NEW;
         } else if (itemId == R.id.sort_smart_shuffle_desc) {
             return SortOrder.SMART_SHUFFLE_NEW_OLD;
+        } else if (itemId == R.id.sort_size_small_large) {
+            return SortOrder.SIZE_SMALL_LARGE;
+        } else if (itemId == R.id.sort_size_large_small) {
+            return SortOrder.SIZE_LARGE_SMALL;
         }
 
         return null;
diff --git a/app/src/main/res/menu/sort_menu.xml b/app/src/main/res/menu/sort_menu.xml
index f0a22042b07..96ad4b9f6d7 100644
--- a/app/src/main/res/menu/sort_menu.xml
+++ b/app/src/main/res/menu/sort_menu.xml
@@ -75,6 +75,22 @@
                 android:title="@string/sort_new_old"/>
         </menu>
     </item>
+
+    <item
+        android:id="@+id/sort_size"
+        android:title="@string/size"
+        android:visible="false">
+
+        <menu>
+            <item
+                android:id="@+id/sort_size_small_large"
+                android:title="@string/sort_small_large"/>
+            <item
+                android:id="@+id/sort_size_large_small"
+                android:title="@string/sort_large_small"/>
+        </menu>
+    </item>
+
     <item
         android:id="@+id/keep_sorted"
         android:title="@string/keep_sorted"
diff --git a/core/src/main/java/de/danoeh/antennapod/core/util/FeedItemPermutors.java b/core/src/main/java/de/danoeh/antennapod/core/util/FeedItemPermutors.java
index 12377791e22..ec9c9e55e4e 100644
--- a/core/src/main/java/de/danoeh/antennapod/core/util/FeedItemPermutors.java
+++ b/core/src/main/java/de/danoeh/antennapod/core/util/FeedItemPermutors.java
@@ -72,6 +72,12 @@ public static Permutor<FeedItem> getPermutor(@NonNull SortOrder sortOrder) {
             case SMART_SHUFFLE_NEW_OLD:
                 permutor = (queue) -> smartShuffle(queue, false);
                 break;
+            case SIZE_SMALL_LARGE:
+                comparator = (f1, f2) -> Long.compare(size(f1), size(f2));
+                break;
+            case SIZE_LARGE_SMALL:
+                comparator = (f1, f2) -> Long.compare(size(f2), size(f1));
+                break;
         }
 
         if (comparator != null) {
@@ -97,6 +103,10 @@ private static int duration(@Nullable FeedItem item) {
         return (item != null && item.getMedia() != null) ? item.getMedia().getDuration() : 0;
     }
 
+    private static long size(@Nullable FeedItem item) {
+        return (item != null && item.getMedia() != null) ? item.getMedia().getSize() : 0;
+    }
+
     @NonNull
     private static String itemLink(@Nullable FeedItem item) {
         return (item != null && item.getLink() != null)
diff --git a/model/src/main/java/de/danoeh/antennapod/model/feed/SortOrder.java b/model/src/main/java/de/danoeh/antennapod/model/feed/SortOrder.java
index 1f9687b2ee6..08504b44545 100644
--- a/model/src/main/java/de/danoeh/antennapod/model/feed/SortOrder.java
+++ b/model/src/main/java/de/danoeh/antennapod/model/feed/SortOrder.java
@@ -20,6 +20,8 @@ public enum SortOrder {
     DURATION_LONG_SHORT(6, INTRA_FEED),
     EPISODE_FILENAME_A_Z(7, INTRA_FEED),
     EPISODE_FILENAME_Z_A(8, INTRA_FEED),
+    SIZE_SMALL_LARGE(9, INTRA_FEED),
+    SIZE_LARGE_SMALL(10, INTRA_FEED),
     FEED_TITLE_A_Z(101, INTER_FEED),
     FEED_TITLE_Z_A(102, INTER_FEED),
     RANDOM(103, INTER_FEED),
diff --git a/storage/database/src/main/java/de/danoeh/antennapod/storage/database/mapper/FeedItemSortQuery.java b/storage/database/src/main/java/de/danoeh/antennapod/storage/database/mapper/FeedItemSortQuery.java
index aae5154d3e9..d4404a08208 100644
--- a/storage/database/src/main/java/de/danoeh/antennapod/storage/database/mapper/FeedItemSortQuery.java
+++ b/storage/database/src/main/java/de/danoeh/antennapod/storage/database/mapper/FeedItemSortQuery.java
@@ -25,6 +25,12 @@ public static String generateFrom(SortOrder sortOrder) {
             case DURATION_LONG_SHORT:
                 sortQuery = PodDBAdapter.TABLE_NAME_FEED_MEDIA + "." + PodDBAdapter.KEY_DURATION + " " + "DESC";
                 break;
+            case SIZE_SMALL_LARGE:
+                sortQuery = PodDBAdapter.TABLE_NAME_FEED_MEDIA + "." + PodDBAdapter.KEY_SIZE + " " + "ASC";
+                break;
+            case SIZE_LARGE_SMALL:
+                sortQuery = PodDBAdapter.TABLE_NAME_FEED_MEDIA + "." + PodDBAdapter.KEY_SIZE + " " + "DESC";
+                break;
             default:
                 sortQuery = "";
                 break;
diff --git a/ui/i18n/src/main/res/values/strings.xml b/ui/i18n/src/main/res/values/strings.xml
index 0697a2f5374..73423f4b5cb 100644
--- a/ui/i18n/src/main/res/values/strings.xml
+++ b/ui/i18n/src/main/res/values/strings.xml
@@ -343,6 +343,7 @@
     <string name="feed_title">Podcast title</string>
     <string name="random">Random</string>
     <string name="smart_shuffle">Smart shuffle</string>
+    <string name="size">Size</string>
     <string name="clear_queue_confirmation_msg">Please confirm that you want to clear the queue of ALL of the episodes in it</string>
     <string name="time_left_label">Time left:\u0020</string>
 
@@ -771,6 +772,8 @@
     <string name="sort_old_new">Old \u2192 New</string>
     <string name="sort_short_long">Short \u2192 Long</string>
     <string name="sort_long_short">Long \u2192 Short</string>
+    <string name="sort_small_large">Small \u2192 Large</string>
+    <string name="sort_large_small">Large \u2192 Small</string>
 
     <!-- Share episode dialog -->
     <string name="share_playback_position_dialog_label">Include playback position</string>


Test patch:
diff --git a/core/src/test/java/de/danoeh/antennapod/core/util/FeedItemPermutorsTest.java b/core/src/test/java/de/danoeh/antennapod/core/util/FeedItemPermutorsTest.java
index 9c48f8df7eb..be4012cb6cc 100644
--- a/core/src/test/java/de/danoeh/antennapod/core/util/FeedItemPermutorsTest.java
+++ b/core/src/test/java/de/danoeh/antennapod/core/util/FeedItemPermutorsTest.java
@@ -112,6 +112,26 @@ public void testPermutorForRule_DURATION_DESC() {
         assertTrue(checkIdOrder(itemList, 3, 2, 1)); // after sorting
     }
 
+    @Test
+    public void testPermutorForRule_size_asc() {
+        Permutor<FeedItem> permutor = FeedItemPermutors.getPermutor(SortOrder.SIZE_SMALL_LARGE);
+
+        List<FeedItem> itemList = getTestList();
+        assertTrue(checkIdOrder(itemList, 1, 3, 2)); // before sorting
+        permutor.reorder(itemList);
+        assertTrue(checkIdOrder(itemList, 1, 2, 3)); // after sorting
+    }
+
+    @Test
+    public void testPermutorForRule_size_desc() {
+        Permutor<FeedItem> permutor = FeedItemPermutors.getPermutor(SortOrder.SIZE_LARGE_SMALL);
+
+        List<FeedItem> itemList = getTestList();
+        assertTrue(checkIdOrder(itemList, 1, 3, 2)); // before sorting
+        permutor.reorder(itemList);
+        assertTrue(checkIdOrder(itemList, 3, 2, 1)); // after sorting
+    }
+
     @Test
     public void testPermutorForRule_DURATION_DESC_NullMedia() {
         Permutor<FeedItem> permutor = FeedItemPermutors.getPermutor(SortOrder.DURATION_LONG_SHORT);
@@ -166,21 +186,21 @@ private List<FeedItem> getTestList() {
         calendar.set(2019, 0, 1);  // January 1st
         Feed feed1 = new Feed(null, null, "Feed title 1");
         FeedItem feedItem1 = new FeedItem(1, "Title 1", null, null, calendar.getTime(), 0, feed1);
-        FeedMedia feedMedia1 = new FeedMedia(0, feedItem1, 1000, 0, 0, null, null, null, true, null, 0, 0);
+        FeedMedia feedMedia1 = new FeedMedia(0, feedItem1, 1000, 0, 100, null, null, null, true, null, 0, 0);
         feedItem1.setMedia(feedMedia1);
         itemList.add(feedItem1);
 
         calendar.set(2019, 2, 1);  // March 1st
         Feed feed2 = new Feed(null, null, "Feed title 3");
         FeedItem feedItem2 = new FeedItem(3, "Title 3", null, null, calendar.getTime(), 0, feed2);
-        FeedMedia feedMedia2 = new FeedMedia(0, feedItem2, 3000, 0, 0, null, null, null, true, null, 0, 0);
+        FeedMedia feedMedia2 = new FeedMedia(0, feedItem2, 3000, 0, 300, null, null, null, true, null, 0, 0);
         feedItem2.setMedia(feedMedia2);
         itemList.add(feedItem2);
 
         calendar.set(2019, 1, 1);  // February 1st
         Feed feed3 = new Feed(null, null, "Feed title 2");
         FeedItem feedItem3 = new FeedItem(2, "Title 2", null, null, calendar.getTime(), 0, feed3);
-        FeedMedia feedMedia3 = new FeedMedia(0, feedItem3, 2000, 0, 0, null, null, null, true, null, 0, 0);
+        FeedMedia feedMedia3 = new FeedMedia(0, feedItem3, 2000, 0, 200, null, null, null, true, null, 0, 0);
         feedItem3.setMedia(feedMedia3);
         itemList.add(feedItem3);