summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--app/build.gradle2
-rw-r--r--app/src/androidTest/java/de/test/antennapod/storage/DBWriterTest.java110
-rw-r--r--app/src/main/java/de/danoeh/antennapod/dialog/EpisodesApplyActionFragment.java225
-rw-r--r--app/src/main/java/de/danoeh/antennapod/fragment/CompletedDownloadsFragment.java2
-rw-r--r--app/src/main/java/de/danoeh/antennapod/fragment/QueueFragment.java2
-rw-r--r--app/src/main/java/de/danoeh/antennapod/menuhandler/FeedItemMenuHandler.java2
-rw-r--r--app/src/main/res/layout/downloaded_episodeslist_item.xml2
-rw-r--r--app/src/main/res/layout/episodes_apply_action_fragment.xml143
-rw-r--r--app/src/main/res/layout/simple_list_item_multiple_choice_on_start.xml33
-rw-r--r--app/src/main/res/menu/episodes_apply_action_speeddial.xml34
-rw-r--r--app/src/main/res/menu/opml_selection_options.xml4
-rw-r--r--app/src/main/res/values-w300dp/dimens-fabspeeddial.xml8
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/service/playback/PlaybackService.java2
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/storage/DBWriter.java67
-rw-r--r--core/src/main/res/drawable-hdpi/ic_check_box_grey600_24dp.pngbin278 -> 0 bytes
-rw-r--r--core/src/main/res/drawable-hdpi/ic_check_box_outline_blank_grey600_24dp.pngbin180 -> 0 bytes
-rw-r--r--core/src/main/res/drawable-hdpi/ic_check_box_outline_blank_white_24dp.pngbin170 -> 0 bytes
-rw-r--r--core/src/main/res/drawable-hdpi/ic_check_box_white_24dp.pngbin260 -> 0 bytes
-rw-r--r--core/src/main/res/drawable-hdpi/ic_indeterminate_check_box_grey600_24dp.pngbin179 -> 0 bytes
-rw-r--r--core/src/main/res/drawable-hdpi/ic_indeterminate_check_box_white_24dp.pngbin171 -> 0 bytes
-rw-r--r--core/src/main/res/drawable-mdpi/ic_check_box_grey600_24dp.pngbin193 -> 0 bytes
-rw-r--r--core/src/main/res/drawable-mdpi/ic_check_box_outline_blank_grey600_24dp.pngbin116 -> 0 bytes
-rw-r--r--core/src/main/res/drawable-mdpi/ic_check_box_outline_blank_white_24dp.pngbin113 -> 0 bytes
-rw-r--r--core/src/main/res/drawable-mdpi/ic_check_box_white_24dp.pngbin179 -> 0 bytes
-rw-r--r--core/src/main/res/drawable-mdpi/ic_indeterminate_check_box_grey600_24dp.pngbin118 -> 0 bytes
-rw-r--r--core/src/main/res/drawable-mdpi/ic_indeterminate_check_box_white_24dp.pngbin115 -> 0 bytes
-rw-r--r--core/src/main/res/drawable-xhdpi/ic_check_box_grey600_24dp.pngbin305 -> 0 bytes
-rw-r--r--core/src/main/res/drawable-xhdpi/ic_check_box_outline_blank_grey600_24dp.pngbin186 -> 0 bytes
-rw-r--r--core/src/main/res/drawable-xhdpi/ic_check_box_outline_blank_white_24dp.pngbin165 -> 0 bytes
-rw-r--r--core/src/main/res/drawable-xhdpi/ic_check_box_white_24dp.pngbin282 -> 0 bytes
-rw-r--r--core/src/main/res/drawable-xhdpi/ic_indeterminate_check_box_grey600_24dp.pngbin186 -> 0 bytes
-rw-r--r--core/src/main/res/drawable-xhdpi/ic_indeterminate_check_box_white_24dp.pngbin166 -> 0 bytes
-rw-r--r--core/src/main/res/drawable-xxhdpi/ic_check_box_grey600_24dp.pngbin415 -> 0 bytes
-rw-r--r--core/src/main/res/drawable-xxhdpi/ic_check_box_outline_blank_grey600_24dp.pngbin244 -> 0 bytes
-rw-r--r--core/src/main/res/drawable-xxhdpi/ic_check_box_outline_blank_white_24dp.pngbin214 -> 0 bytes
-rw-r--r--core/src/main/res/drawable-xxhdpi/ic_check_box_white_24dp.pngbin383 -> 0 bytes
-rw-r--r--core/src/main/res/drawable-xxhdpi/ic_indeterminate_check_box_grey600_24dp.pngbin247 -> 0 bytes
-rw-r--r--core/src/main/res/drawable-xxhdpi/ic_indeterminate_check_box_white_24dp.pngbin219 -> 0 bytes
-rw-r--r--core/src/main/res/drawable/ic_fab_edit.xml5
-rw-r--r--core/src/main/res/drawable/ic_remove_grey600.xml5
-rw-r--r--core/src/main/res/drawable/ic_remove_white.xml5
-rw-r--r--core/src/main/res/drawable/ic_select_all_grey600.xml9
-rw-r--r--core/src/main/res/drawable/ic_select_all_white.xml9
-rw-r--r--core/src/main/res/drawable/ic_select_none_grey600.xml11
-rw-r--r--core/src/main/res/drawable/ic_select_none_white.xml11
-rw-r--r--core/src/main/res/values/attrs.xml6
-rw-r--r--core/src/main/res/values/strings.xml27
-rw-r--r--core/src/main/res/values/styles.xml24
48 files changed, 518 insertions, 230 deletions
diff --git a/app/build.gradle b/app/build.gradle
index bcd7a381d..3299ab715 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -14,6 +14,7 @@ android {
minSdkVersion rootProject.ext.minSdkVersion
targetSdkVersion rootProject.ext.targetSdkVersion
multiDexEnabled true
+ vectorDrawables.useSupportLibrary true
// Version code schema:
// "1.2.3-SNAPSHOT" -> 1020300
// "1.2.3-RC4" -> 1020304
@@ -158,6 +159,7 @@ dependencies {
}
implementation "com.github.shts:TriangleLabelView:$triangleLabelViewVersion"
+ implementation 'com.leinardi.android:speed-dial:1.0.2' // 1.0.2 uses support 27.1.1 ; newer versions use 28.0.0;
implementation "com.github.AntennaPod:AntennaPod-AudioPlayer:$audioPlayerVersion"
diff --git a/app/src/androidTest/java/de/test/antennapod/storage/DBWriterTest.java b/app/src/androidTest/java/de/test/antennapod/storage/DBWriterTest.java
index b80482c53..27d76116d 100644
--- a/app/src/androidTest/java/de/test/antennapod/storage/DBWriterTest.java
+++ b/app/src/androidTest/java/de/test/antennapod/storage/DBWriterTest.java
@@ -7,6 +7,8 @@ import android.preference.PreferenceManager;
import android.test.InstrumentationTestCase;
import android.util.Log;
+import org.awaitility.Awaitility;
+
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
@@ -24,8 +26,7 @@ import de.danoeh.antennapod.core.preferences.UserPreferences;
import de.danoeh.antennapod.core.storage.DBReader;
import de.danoeh.antennapod.core.storage.DBWriter;
import de.danoeh.antennapod.core.storage.PodDBAdapter;
-
-import org.awaitility.Awaitility;
+import de.danoeh.antennapod.core.util.Consumer;
/**
* Test class for DBWriter
@@ -574,29 +575,16 @@ public class DBWriterTest extends InstrumentationTestCase {
public void testRemoveQueueItem() throws InterruptedException, ExecutionException, TimeoutException {
final int NUM_ITEMS = 10;
final Context context = getInstrumentation().getTargetContext();
- Feed feed = new Feed("url", null, "title");
- feed.setItems(new ArrayList<>());
- for (int i = 0; i < NUM_ITEMS; i++) {
- FeedItem item = new FeedItem(0, "title " + i, "id " + i, "link " + i, new Date(), FeedItem.PLAYED, feed);
- feed.getItems().add(item);
- }
-
- PodDBAdapter adapter = PodDBAdapter.getInstance();
- adapter.open();
- adapter.setCompleteFeed(feed);
- adapter.close();
+ Feed feed = createTestFeed(NUM_ITEMS);
- for (FeedItem item : feed.getItems()) {
- assertTrue(item.getId() != 0);
- }
for (int removeIndex = 0; removeIndex < NUM_ITEMS; removeIndex++) {
final FeedItem item = feed.getItems().get(removeIndex);
- adapter = PodDBAdapter.getInstance();
+ PodDBAdapter adapter = PodDBAdapter.getInstance();
adapter.open();
adapter.setQueue(feed.getItems());
adapter.close();
- DBWriter.removeQueueItem(context, item, false).get(TIMEOUT, TimeUnit.SECONDS);
+ DBWriter.removeQueueItem(context, false, item).get(TIMEOUT, TimeUnit.SECONDS);
adapter = PodDBAdapter.getInstance();
adapter.open();
Cursor queue = adapter.getQueueIDCursor();
@@ -616,6 +604,43 @@ public class DBWriterTest extends InstrumentationTestCase {
}
}
+ public void testRemoveQueueItemMultipleItems() throws InterruptedException, ExecutionException, TimeoutException {
+ // Setup test data
+ //
+ final int NUM_ITEMS = 5;
+ final int NUM_IN_QUEUE = NUM_ITEMS - 1; // the last one not in queue for boundary condition
+ final Context context = getInstrumentation().getTargetContext();
+ Feed feed = createTestFeed(NUM_ITEMS);
+
+ List<FeedItem> itemsToAdd = feed.getItems().subList(0, NUM_IN_QUEUE);
+ withPodDB(adapter -> adapter.setQueue(itemsToAdd) );
+
+ // Actual tests
+ //
+
+ // Use array rather than List to make codes more succinct
+ Long[] itemIds = toItemIds(feed.getItems()).toArray(new Long[0]);
+
+ DBWriter.removeQueueItem(context, false,
+ itemIds[1], itemIds[3]).get(TIMEOUT, TimeUnit.SECONDS);
+ assertQueueByItemIds("Average case - 2 items removed successfully",
+ itemIds[0], itemIds[2]);
+
+ DBWriter.removeQueueItem(context, false).get(TIMEOUT, TimeUnit.SECONDS);
+ assertQueueByItemIds("Boundary case - no items supplied. queue should see no change",
+ itemIds[0], itemIds[2]);
+
+ DBWriter.removeQueueItem(context, false,
+ itemIds[0], itemIds[4], -1L).get(TIMEOUT, TimeUnit.SECONDS);
+ assertQueueByItemIds("Boundary case - items not in queue ignored",
+ itemIds[2]);
+
+ DBWriter.removeQueueItem(context, false,
+ itemIds[2], -1L).get(TIMEOUT, TimeUnit.SECONDS);
+ assertQueueByItemIds("Boundary case - invalid itemIds ignored"); // the queue is empty
+
+ }
+
public void testMoveQueueItem() throws InterruptedException, ExecutionException, TimeoutException {
final int NUM_ITEMS = 10;
Feed feed = new Feed("url", null, "title");
@@ -713,4 +738,53 @@ public class DBWriterTest extends InstrumentationTestCase {
assertTrue(item.isPlayed());
}
}
+
+ private static Feed createTestFeed(int numItems) {
+ Feed feed = new Feed("url", null, "title");
+ feed.setItems(new ArrayList<>());
+ for (int i = 0; i < numItems; i++) {
+ FeedItem item = new FeedItem(0, "title " + i, "id " + i, "link " + i, new Date(), FeedItem.PLAYED, feed);
+ feed.getItems().add(item);
+ }
+
+ withPodDB(adapter -> adapter.setCompleteFeed(feed));
+
+ for (FeedItem item : feed.getItems()) {
+ assertTrue(item.getId() != 0);
+ }
+ return feed;
+ }
+
+ private static void withPodDB(Consumer<PodDBAdapter> action) {
+ PodDBAdapter adapter = PodDBAdapter.getInstance();
+ try {
+ adapter.open();
+ action.accept(adapter);
+ } finally {
+ adapter.close();
+ }
+ }
+
+ private static void assertQueueByItemIds(
+ String message,
+ long... itemIdsExpected
+ ) {
+ List<FeedItem> queue = DBReader.getQueue();
+ List<Long> itemIdsActualList = toItemIds(queue);
+ List<Long> itemIdsExpectedList = new ArrayList<Long>(itemIdsExpected.length);
+ for (long id : itemIdsExpected) {
+ itemIdsExpectedList.add(id);
+ }
+
+ assertEquals(message, itemIdsExpectedList, itemIdsActualList);
+ }
+
+ private static List<Long> toItemIds(List<FeedItem> items) {
+ List<Long> itemIds = new ArrayList<Long>(items.size());
+ for(FeedItem item : items) {
+ itemIds.add(item.getId());
+ }
+ return itemIds;
+ }
+
}
diff --git a/app/src/main/java/de/danoeh/antennapod/dialog/EpisodesApplyActionFragment.java b/app/src/main/java/de/danoeh/antennapod/dialog/EpisodesApplyActionFragment.java
index 07a64cde8..02071e355 100644
--- a/app/src/main/java/de/danoeh/antennapod/dialog/EpisodesApplyActionFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/dialog/EpisodesApplyActionFragment.java
@@ -4,9 +4,17 @@ import android.app.AlertDialog;
import android.content.res.TypedArray;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
+import android.support.annotation.IdRes;
+import android.support.annotation.NonNull;
+import android.support.annotation.PluralsRes;
+import android.support.annotation.StringRes;
+import android.support.design.widget.Snackbar;
import android.support.v4.app.ActivityCompat;
import android.support.v4.app.Fragment;
import android.support.v4.util.ArrayMap;
+import android.support.v7.app.ActionBar;
+import android.support.v7.app.AppCompatActivity;
+import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
@@ -14,11 +22,12 @@ import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
-import android.widget.Button;
import android.widget.ListView;
-import android.widget.Toast;
+
+import com.leinardi.android.speeddial.SpeedDialView;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Map;
@@ -35,22 +44,42 @@ public class EpisodesApplyActionFragment extends Fragment {
public static final String TAG = "EpisodeActionFragment";
- public static final int ACTION_QUEUE = 1;
- private static final int ACTION_MARK_PLAYED = 2;
- private static final int ACTION_MARK_UNPLAYED = 4;
- private static final int ACTION_DOWNLOAD = 8;
- public static final int ACTION_REMOVE = 16;
- private static final int ACTION_ALL = ACTION_QUEUE | ACTION_MARK_PLAYED | ACTION_MARK_UNPLAYED
- | ACTION_DOWNLOAD | ACTION_REMOVE;
+ public static final int ACTION_ADD_TO_QUEUE = 1;
+ private static final int ACTION_REMOVE_FROM_QUEUE = 2;
+ private static final int ACTION_MARK_PLAYED = 4;
+ private static final int ACTION_MARK_UNPLAYED = 8;
+ private static final int ACTION_DOWNLOAD = 16;
+ public static final int ACTION_DELETE = 32;
+ private static final int ACTION_ALL = ACTION_ADD_TO_QUEUE | ACTION_REMOVE_FROM_QUEUE
+ | ACTION_MARK_PLAYED | ACTION_MARK_UNPLAYED | ACTION_DOWNLOAD | ACTION_DELETE;
+
+ /**
+ * Specify an action (defined by #flag) 's UI bindings.
+ *
+ * Includes: the menu / action item and the actual logic
+ */
+ private class ActionBinding {
+ int flag;
+ @IdRes
+ final int actionItemId;
+ @NonNull
+ final Runnable action;
+
+ ActionBinding(int flag, @IdRes int actionItemId, @NonNull Runnable action) {
+ this.flag = flag;
+ this.actionItemId = actionItemId;
+ this.action = action;
+ }
+ }
+
+ private final List<? extends ActionBinding> actionBindings;
private ListView mListView;
private ArrayAdapter<String> mAdapter;
- private Button btnAddToQueue;
- private Button btnMarkAsPlayed;
- private Button btnMarkAsUnplayed;
- private Button btnDownload;
- private Button btnDelete;
+ private SpeedDialView mSpeedDialView;
+ @NonNull
+ private CharSequence actionBarTitleOriginal = "";
private final Map<Long,FeedItem> idMap = new ArrayMap<>();
private final List<FeedItem> episodes = new ArrayList<>();
@@ -60,6 +89,23 @@ public class EpisodesApplyActionFragment extends Fragment {
private MenuItem mSelectToggle;
+ public EpisodesApplyActionFragment() {
+ actionBindings = Arrays.asList(
+ new ActionBinding(ACTION_ADD_TO_QUEUE,
+ R.id.add_to_queue_batch, this::queueChecked),
+ new ActionBinding(ACTION_REMOVE_FROM_QUEUE,
+ R.id.remove_from_queue_batch, this::removeFromQueueChecked),
+ new ActionBinding(ACTION_MARK_PLAYED,
+ R.id.mark_read_batch, this::markedCheckedPlayed),
+ new ActionBinding(ACTION_MARK_UNPLAYED,
+ R.id.mark_unread_batch, this::markedCheckedUnplayed),
+ new ActionBinding(ACTION_DOWNLOAD,
+ R.id.download_batch, this::downloadChecked),
+ new ActionBinding(ACTION_DELETE,
+ R.id.delete_batch, this::deleteChecked)
+ );
+ }
+
public static EpisodesApplyActionFragment newInstance(List<FeedItem> items) {
return newInstance(items, ACTION_ALL);
}
@@ -124,57 +170,58 @@ public class EpisodesApplyActionFragment extends Fragment {
}
mAdapter = new ArrayAdapter<>(getActivity(),
- android.R.layout.simple_list_item_multiple_choice, titles);
+ R.layout.simple_list_item_multiple_choice_on_start, titles);
mListView.setAdapter(mAdapter);
- checkAll();
- int lastVisibleDiv = 0;
- btnAddToQueue = view.findViewById(R.id.btnAddToQueue);
- if((actions & ACTION_QUEUE) != 0) {
- btnAddToQueue.setOnClickListener(v -> queueChecked());
- lastVisibleDiv = R.id.divider1;
- } else {
- btnAddToQueue.setVisibility(View.GONE);
- view.findViewById(R.id.divider1).setVisibility(View.GONE);
- }
- btnMarkAsPlayed = view.findViewById(R.id.btnMarkAsPlayed);
- if((actions & ACTION_MARK_PLAYED) != 0) {
- btnMarkAsPlayed.setOnClickListener(v -> markedCheckedPlayed());
- lastVisibleDiv = R.id.divider2;
- } else {
- btnMarkAsPlayed.setVisibility(View.GONE);
- view.findViewById(R.id.divider2).setVisibility(View.GONE);
- }
- btnMarkAsUnplayed = view.findViewById(R.id.btnMarkAsUnplayed);
- if((actions & ACTION_MARK_UNPLAYED) != 0) {
- btnMarkAsUnplayed.setOnClickListener(v -> markedCheckedUnplayed());
- lastVisibleDiv = R.id.divider3;
- } else {
- btnMarkAsUnplayed.setVisibility(View.GONE);
- view.findViewById(R.id.divider3).setVisibility(View.GONE);
- }
- btnDownload = view.findViewById(R.id.btnDownload);
- if((actions & ACTION_DOWNLOAD) != 0) {
- btnDownload.setOnClickListener(v -> downloadChecked());
- lastVisibleDiv = R.id.divider4;
- } else {
- btnDownload.setVisibility(View.GONE);
- view.findViewById(R.id.divider4).setVisibility(View.GONE);
- }
- btnDelete = view.findViewById(R.id.btnDelete);
- if((actions & ACTION_REMOVE) != 0) {
- btnDelete.setOnClickListener(v -> deleteChecked());
- } else {
- btnDelete.setVisibility(View.GONE);
- if(lastVisibleDiv > 0) {
- view.findViewById(lastVisibleDiv).setVisibility(View.GONE);
+ saveActionBarTitle(); // needed when we dynamically change the title based on selection
+
+ // Init action UI (via a FAB Speed Dial)
+ mSpeedDialView = view.findViewById(R.id.fabSD);
+ mSpeedDialView.inflate(R.menu.episodes_apply_action_speeddial);
+
+ // show only specified actions, and bind speed dial UIs to the actual logic
+ for (ActionBinding binding : actionBindings) {
+ if ((actions & binding.flag) == 0) {
+ mSpeedDialView.removeActionItemById(binding.actionItemId);
}
}
+ mSpeedDialView.setOnActionSelectedListener(actionItem -> {
+ ActionBinding selectedBinding = null;
+ for (ActionBinding binding : actionBindings) {
+ if (actionItem.getId() == binding.actionItemId) {
+ selectedBinding = binding;
+ break;
+ }
+ }
+ if (selectedBinding != null) {
+ selectedBinding.action.run();
+ } else {
+ Log.e(TAG, "Unrecognized speed dial action item. Do nothing. id=" + actionItem.getId());
+ }
+ return true;
+ });
+
+ showSpeedDialIfAnyChecked();
+
return view;
}
@Override
+ public void onStop() {
+ restoreActionBarTitle(); // it might have been changed to "N selected". Restore original.
+ super.onStop();
+ }
+
+ private void showSpeedDialIfAnyChecked() {
+ mSpeedDialView.setVisibility(checkedIds.size() > 0 ? View.VISIBLE : View.GONE);
+ }
+
+ private void hideSpeedDial() {
+ mSpeedDialView.setVisibility(View.GONE);
+ }
+
+ @Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
super.onCreateOptionsMenu(menu, inflater);
inflater.inflate(R.menu.episodes_apply_action_options, menu);
@@ -196,11 +243,9 @@ public class EpisodesApplyActionFragment extends Fragment {
int[] icon = new int[1];
if (checkedIds.size() == episodes.size()) {
- icon[0] = R.attr.ic_check_box;
- } else if (checkedIds.size() == 0) {
- icon[0] = R.attr.ic_check_box_outline;
+ icon[0] = R.attr.ic_select_none;
} else {
- icon[0] = R.attr.ic_indeterminate_check_box;
+ icon[0] = R.attr.ic_select_all;
}
TypedArray a = getActivity().obtainStyledAttributes(icon);
@@ -212,7 +257,7 @@ public class EpisodesApplyActionFragment extends Fragment {
@Override
public boolean onOptionsItemSelected(MenuItem item) {
- int resId = 0;
+ @StringRes int resId = 0;
switch(item.getItemId()) {
case R.id.select_options:
return true;
@@ -272,7 +317,8 @@ public class EpisodesApplyActionFragment extends Fragment {
return true;
}
if(resId != 0) {
- Toast.makeText(getActivity(), resId, Toast.LENGTH_SHORT).show();
+ Snackbar.make(getActivity().findViewById(R.id.content), resId, Snackbar.LENGTH_SHORT)
+ .show();
return true;
} else {
return false;
@@ -410,21 +456,56 @@ public class EpisodesApplyActionFragment extends Fragment {
mListView.setItemChecked(i, checked);
}
ActivityCompat.invalidateOptionsMenu(EpisodesApplyActionFragment.this.getActivity());
+ showSpeedDialIfAnyChecked();
+ updateActionBarTitle();
+ }
+
+ private void saveActionBarTitle() {
+ ActionBar actionBar = ((AppCompatActivity) getActivity()).getSupportActionBar();
+ if (actionBar != null) {
+ CharSequence title = actionBar.getTitle();
+ if (title == null) {
+ title = "";
+ }
+ actionBarTitleOriginal = title;
+ }
+ }
+
+ private void restoreActionBarTitle() {
+ ActionBar actionBar = ((AppCompatActivity) getActivity()).getSupportActionBar();
+ if (actionBar != null) {
+ actionBar.setTitle(actionBarTitleOriginal);
+ }
+ }
+
+ private void updateActionBarTitle() {
+ ActionBar actionBar = ((AppCompatActivity) getActivity()).getSupportActionBar();
+ if (actionBar != null) {
+ CharSequence title = checkedIds.size() > 0 ?
+ getString(R.string.num_selected_label, checkedIds.size()) :
+ actionBarTitleOriginal;
+ actionBar.setTitle(title);
+ }
}
private void queueChecked() {
DBWriter.addQueueItem(getActivity(), true, checkedIds.toArray());
- close();
+ close(R.plurals.added_to_queue_batch_label, checkedIds.size());
+ }
+
+ private void removeFromQueueChecked() {
+ DBWriter.removeQueueItem(getActivity(), true, checkedIds.toArray());
+ close(R.plurals.removed_from_queue_batch_label, checkedIds.size());
}
private void markedCheckedPlayed() {
DBWriter.markItemPlayed(FeedItem.PLAYED, checkedIds.toArray());
- close();
+ close(R.plurals.marked_read_batch_label, checkedIds.size());
}
private void markedCheckedUnplayed() {
DBWriter.markItemPlayed(FeedItem.UNPLAYED, checkedIds.toArray());
- close();
+ close(R.plurals.marked_unread_batch_label, checkedIds.size());
}
private void downloadChecked() {
@@ -441,7 +522,7 @@ public class EpisodesApplyActionFragment extends Fragment {
e.printStackTrace();
DownloadRequestErrorDialogCreator.newRequestErrorDialog(getActivity(), e.getMessage());
}
- close();
+ close(R.plurals.downloading_batch_label, checkedIds.size());
}
private void deleteChecked() {
@@ -451,10 +532,18 @@ public class EpisodesApplyActionFragment extends Fragment {
DBWriter.deleteFeedMediaOfItem(getActivity(), episode.getMedia().getId());
}
}
- close();
+ close(R.plurals.deleted_episode_batch_label, checkedIds.size());
}
- private void close() {
+ private void close(@PluralsRes int msgId, int numItems) {
+ if (numItems > 0) {
+ Snackbar.make(getActivity().findViewById(R.id.content),
+ getResources().getQuantityString(msgId, numItems, numItems),
+ Snackbar.LENGTH_LONG
+ )
+ .setAction(android.R.string.ok, v -> {})
+ .show();
+ }
getActivity().getSupportFragmentManager().popBackStack();
}
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 ddf9044ab..b52fd444f 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/CompletedDownloadsFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/fragment/CompletedDownloadsFragment.java
@@ -149,7 +149,7 @@ public class CompletedDownloadsFragment extends ListFragment {
switch (item.getItemId()) {
case R.id.episode_actions:
EpisodesApplyActionFragment fragment = EpisodesApplyActionFragment
- .newInstance(items, EpisodesApplyActionFragment.ACTION_REMOVE | EpisodesApplyActionFragment.ACTION_QUEUE);
+ .newInstance(items, EpisodesApplyActionFragment.ACTION_DELETE | EpisodesApplyActionFragment.ACTION_ADD_TO_QUEUE);
((MainActivity) getActivity()).loadChildFragment(fragment);
return true;
default:
diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/QueueFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/QueueFragment.java
index 763bc487b..0e8f2f083 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/QueueFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/fragment/QueueFragment.java
@@ -431,7 +431,7 @@ public class QueueFragment extends Fragment {
final FeedItem item = queue.get(position);
final boolean isRead = item.isPlayed();
DBWriter.markItemPlayed(FeedItem.PLAYED, false, item.getId());
- DBWriter.removeQueueItem(getActivity(), item, true);
+ DBWriter.removeQueueItem(getActivity(), true, item);
Snackbar snackbar = Snackbar.make(root, getString(R.string.marked_as_read_label), Snackbar.LENGTH_LONG);
snackbar.setAction(getString(R.string.undo), v -> {
DBWriter.addQueueItemAt(getActivity(), item.getId(), position, false);
diff --git a/app/src/main/java/de/danoeh/antennapod/menuhandler/FeedItemMenuHandler.java b/app/src/main/java/de/danoeh/antennapod/menuhandler/FeedItemMenuHandler.java
index 321b9c7bb..3f8d88af7 100644
--- a/app/src/main/java/de/danoeh/antennapod/menuhandler/FeedItemMenuHandler.java
+++ b/app/src/main/java/de/danoeh/antennapod/menuhandler/FeedItemMenuHandler.java
@@ -199,7 +199,7 @@ public class FeedItemMenuHandler {
DBWriter.addQueueItem(context, selectedItem);
break;
case R.id.remove_from_queue_item:
- DBWriter.removeQueueItem(context, selectedItem, true);
+ DBWriter.removeQueueItem(context, true, selectedItem);
break;
case R.id.add_to_favorites_item:
DBWriter.addFavoriteItem(selectedItem);
diff --git a/app/src/main/res/layout/downloaded_episodeslist_item.xml b/app/src/main/res/layout/downloaded_episodeslist_item.xml
index 66ae6c180..65a08251f 100644
--- a/app/src/main/res/layout/downloaded_episodeslist_item.xml
+++ b/app/src/main/res/layout/downloaded_episodeslist_item.xml
@@ -92,7 +92,7 @@
android:layout_height="match_parent"
android:background="?attr/selectableItemBackground"
android:clickable="false"
- android:contentDescription="@string/remove_episode_lable"
+ android:contentDescription="@string/delete_episode_label"
android:focusable="false"
android:focusableInTouchMode="false"
android:src="?attr/content_discard"
diff --git a/app/src/main/res/layout/episodes_apply_action_fragment.xml b/app/src/main/res/layout/episodes_apply_action_fragment.xml
index e9a2e2e23..984e960d8 100644
--- a/app/src/main/res/layout/episodes_apply_action_fragment.xml
+++ b/app/src/main/res/layout/episodes_apply_action_fragment.xml
@@ -1,115 +1,50 @@
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
-
- <LinearLayout
- android:id="@+id/bottomBar"
- android:layout_width="match_parent"
- android:layout_height="68dp"
- android:layout_alignParentBottom="true"
- android:gravity="center_vertical"
- android:orientation="horizontal"
- android:padding="4dp">
-
- <Button
- android:id="@+id/btnAddToQueue"
- android:layout_width="0dp"
- android:layout_height="wrap_content"
- android:layout_weight="1"
- android:background="@android:color/transparent"
- android:drawableTop="?attr/content_new"
- android:text="@string/add_to_queue_label"
- android:textSize="10sp" />
-
- <View
- android:id="@+id/divider1"
- android:layout_width="1dp"
- android:layout_height="match_parent"
- android:layout_margin="4dp"
- android:background="?android:attr/listDivider"
- tools:background="@android:color/holo_red_dark" />
-
- <Button
- android:id="@+id/btnMarkAsPlayed"
- android:layout_width="0dp"
- android:layout_height="wrap_content"
- android:layout_weight="1"
- android:background="@android:color/transparent"
- android:drawableTop="?attr/navigation_accept"
- android:text="@string/mark_read_label"
- android:textSize="10sp" />
-
- <View
- android:id="@+id/divider2"
- android:layout_width="1dp"
- android:layout_height="match_parent"
- android:layout_margin="4dp"
- android:background="?android:attr/listDivider"
- tools:background="@android:color/holo_red_dark" />
-
- <Button
- android:id="@+id/btnMarkAsUnplayed"
- android:layout_width="0dp"
- android:layout_height="wrap_content"
- android:layout_weight="1"
- android:background="@android:color/transparent"
- android:drawableTop="?attr/navigation_cancel"
- android:text="@string/mark_unread_label"
- android:textSize="10sp" />
-
- <View
- android:id="@+id/divider3"
- android:layout_width="1dp"
- android:layout_height="match_parent"
- android:layout_margin="4dp"
- android:background="?android:attr/listDivider"
- tools:background="@android:color/holo_red_dark" />
-
- <Button
- android:id="@+id/btnDownload"
- android:layout_width="0dp"
- android:layout_height="wrap_content"
- android:layout_weight="1"
- android:background="@android:color/transparent"
- android:drawableTop="?attr/av_download"
- android:text="@string/download_label"
- android:textSize="10sp" />
-
- <View
- android:id="@+id/divider4"
- android:layout_width="1dp"
- android:layout_height="match_parent"
- android:layout_margin="4dp"
- android:background="?android:attr/listDivider"
- tools:background="@android:color/holo_red_dark" />
-
- <Button
- android:id="@+id/btnDelete"
- android:layout_width="0dp"
- android:layout_height="wrap_content"
- android:layout_weight="1"
- android:background="@android:color/transparent"
- android:drawableTop="?attr/content_discard"
- android:text="@string/remove_episode_lable"
- android:textSize="10sp" />
-
- </LinearLayout>
-
- <View
- android:id="@+id/divider"
- android:layout_width="match_parent"
- android:layout_height="1dp"
- android:layout_above="@id/bottomBar"
- android:background="?android:attr/listDivider"
- android:paddingBottom="4dp"
- tools:background="@android:color/holo_red_dark" />
-
<ListView
android:id="@android:id/list"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:layout_above="@id/divider"/>
+ android:layout_alignParentTop="true"
+ android:layout_marginTop="0dp" />
+
+ <com.leinardi.android.speeddial.SpeedDialOverlayLayout
+ android:id="@+id/fabSDOverlay"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent" />
+ <!-- The FAB SpeedDial
+ 1. MUST be placed at the bottom of the layout xml to ensure it is at the front,
+ clickable on Pre-Lollipop devices (that do not support elevation).
+ See: https://stackoverflow.com/a/2614402
+ 2. ScrollView is needed to ensure the vertical list of speed dials are
+ accessible when screen height is small, eg., landscape mode on most phones.
+ -->
+ <ScrollView
+ android:id="@+id/fabSDScrollCtr"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_alignParentBottom="true"
+ android:layout_alignParentEnd="true"
+ android:layout_alignParentRight="true"
+ android:elevation="@dimen/sd_close_elevation"
+ tools:ignore="UnusedAttribute">
+ <!-- android:elevation:
+ 1. Needs to match the speed dial's minimal elevation,
+ or the speed dial can't be clicked at all
+ -->
+ <com.leinardi.android.speeddial.SpeedDialView
+ android:id="@+id/fabSD"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ app:sdMainFabClosedSrc="@drawable/ic_fab_edit"
+ app:sdOverlayLayout="@id/fabSDOverlay"
+ android:layout_marginEnd="16dp"
+ android:layout_marginRight="16dp"
+ android:layout_marginBottom="16dp"
+ />
+ </ScrollView>
</RelativeLayout>
diff --git a/app/src/main/res/layout/simple_list_item_multiple_choice_on_start.xml b/app/src/main/res/layout/simple_list_item_multiple_choice_on_start.xml
new file mode 100644
index 000000000..3c03f71ea
--- /dev/null
+++ b/app/src/main/res/layout/simple_list_item_multiple_choice_on_start.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Based on simple_list_item_multiple_choice.xml
+ from The Android Open Source Project
+ This one puts the check box at the start of the view (rather than at the end).
+ -->
+<!-- Copyright (C) 2008 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<CheckedTextView xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@android:id/text1"
+ android:layout_width="match_parent"
+ android:layout_height="?android:attr/listPreferredItemHeightSmall"
+ android:textAppearance="?android:attr/textAppearanceListItemSmall"
+ android:gravity="center_vertical"
+ android:drawableStart="?android:attr/listChoiceIndicatorMultiple"
+ android:drawableLeft="?android:attr/listChoiceIndicatorMultiple"
+ android:paddingStart="?android:attr/listPreferredItemPaddingStart"
+ android:paddingLeft="?android:attr/listPreferredItemPaddingLeft"
+ android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
+ android:paddingRight="?android:attr/listPreferredItemPaddingRight"
+ />
diff --git a/app/src/main/res/menu/episodes_apply_action_speeddial.xml b/app/src/main/res/menu/episodes_apply_action_speeddial.xml
new file mode 100644
index 000000000..39083e41b
--- /dev/null
+++ b/app/src/main/res/menu/episodes_apply_action_speeddial.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="utf-8"?>
+<menu xmlns:android="http://schemas.android.com/apk/res/android">
+ <!-- the order is opposite of the typical menu:
+ catered to FAB speed dial, which somehow shows the item in reverse.
+ E.g., item @id/delete_batch is the first in the xml,
+ visually it will be shown at the bottom of the list of actions.
+ -->
+ <item android:id="@+id/delete_batch"
+ android:icon="?attr/content_discard"
+ android:title="@string/delete_episode_label"
+ />
+ <item android:id="@+id/download_batch"
+ android:icon="?attr/av_download"
+ android:title="@string/download_label"
+ />
+ <item android:id="@+id/mark_unread_batch"
+ android:icon="?attr/navigation_cancel"
+ android:title="@string/mark_unread_label"
+ />
+ <item
+ android:id="@+id/mark_read_batch"
+ android:icon="?attr/navigation_accept"
+ android:title="@string/mark_read_label"
+ />
+ <item android:id="@+id/remove_from_queue_batch"
+ android:icon="?attr/content_remove_from_queue"
+ android:title="@string/remove_from_queue_label"
+ />
+ <item
+ android:id="@+id/add_to_queue_batch"
+ android:icon="?attr/content_new"
+ android:title="@string/add_to_queue_label"
+ />
+</menu>
diff --git a/app/src/main/res/menu/opml_selection_options.xml b/app/src/main/res/menu/opml_selection_options.xml
index 26d2a0519..8b3310dc2 100644
--- a/app/src/main/res/menu/opml_selection_options.xml
+++ b/app/src/main/res/menu/opml_selection_options.xml
@@ -4,14 +4,14 @@
<item
android:id="@id/select_all_item"
- android:icon="?attr/ic_check_box_outline"
+ android:icon="?attr/ic_select_all"
android:title="@string/select_all_label"
custom:showAsAction="ifRoom">
</item>
<item
android:id="@id/deselect_all_item"
- android:icon="?attr/ic_check_box"
+ android:icon="?attr/ic_select_none"
android:title="@string/deselect_all_label"
custom:showAsAction="ifRoom">
</item>
diff --git a/app/src/main/res/values-w300dp/dimens-fabspeeddial.xml b/app/src/main/res/values-w300dp/dimens-fabspeeddial.xml
new file mode 100644
index 000000000..e531395c0
--- /dev/null
+++ b/app/src/main/res/values-w300dp/dimens-fabspeeddial.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- increase FAB speed dial label's max width if the screen is wide enough
+ (300dp ~ 1.875 inch, devices with 3.5-inch screens have a width of ~ 1.9in
+ so the setup is applicable for most phones)
+ -->
+ <dimen name="sd_label_max_width">240dp</dimen>
+</resources>
diff --git a/core/src/main/java/de/danoeh/antennapod/core/service/playback/PlaybackService.java b/core/src/main/java/de/danoeh/antennapod/core/service/playback/PlaybackService.java
index c31dbc83d..7fe93a162 100644
--- a/core/src/main/java/de/danoeh/antennapod/core/service/playback/PlaybackService.java
+++ b/core/src/main/java/de/danoeh/antennapod/core/service/playback/PlaybackService.java
@@ -898,7 +898,7 @@ public class PlaybackService extends MediaBrowserServiceCompat {
final List<FeedItem> queue = taskManager.getQueue();
if (QueueAccess.ItemListAccess(queue).contains(item.getId())) {
// don't know if it actually matters to not autodownload when smart mark as played is triggered
- DBWriter.removeQueueItem(PlaybackService.this, item, ended);
+ DBWriter.removeQueueItem(PlaybackService.this, ended, item);
}
} catch (InterruptedException e) {
e.printStackTrace();
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 ab55bd3c0..ad20bfa0a 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
@@ -7,7 +7,6 @@ import android.content.SharedPreferences;
import android.preference.PreferenceManager;
import android.util.Log;
-import io.reactivex.annotations.NonNull;
import org.shredzone.flattr4j.model.Flattr;
import java.io.File;
@@ -49,6 +48,7 @@ import de.danoeh.antennapod.core.util.flattr.FlattrStatus;
import de.danoeh.antennapod.core.util.flattr.FlattrThing;
import de.danoeh.antennapod.core.util.flattr.SimpleFlattrThing;
import de.greenrobot.event.EventBus;
+import io.reactivex.annotations.NonNull;
/**
* Provides methods for writing data to AntennaPod's database.
@@ -89,7 +89,7 @@ public class DBWriter {
boolean result = deleteFeedMediaSynchronous(context, media);
if (result && UserPreferences.shouldDeleteRemoveFromQueue()) {
- DBWriter.removeQueueItemSynchronous(context, media.getItem(), false);
+ DBWriter.removeQueueItemSynchronous(context, false, media.getItem().getId());
}
}
});
@@ -423,30 +423,58 @@ public class DBWriter {
/**
* Removes a FeedItem object from the queue.
- *
- * @param context A context that is used for opening a database connection.
- * @param item FeedItem that should be removed.
+ * @param context A context that is used for opening a database connection.
* @param performAutoDownload true if an auto-download process should be started after the operation.
+ * @param item FeedItem that should be removed.
*/
public static Future<?> removeQueueItem(final Context context,
- final FeedItem item, final boolean performAutoDownload) {
- return dbExec.submit(() -> removeQueueItemSynchronous(context, item, performAutoDownload));
+ final boolean performAutoDownload, final FeedItem item) {
+ return dbExec.submit(() -> removeQueueItemSynchronous(context, performAutoDownload, item.getId()));
+ }
+
+ public static Future<?> removeQueueItem(final Context context, final boolean performAutoDownload,
+ final long... itemIds) {
+ return dbExec.submit(() -> removeQueueItemSynchronous(context, performAutoDownload, itemIds));
}
private static void removeQueueItemSynchronous(final Context context,
- final FeedItem item, final boolean performAutoDownload) {
+ final boolean performAutoDownload,
+ final long... itemIds) {
+ if (itemIds.length < 1) {
+ return;
+ }
final PodDBAdapter adapter = PodDBAdapter.getInstance();
adapter.open();
final List<FeedItem> queue = DBReader.getQueue(adapter);
if (queue != null) {
- int position = queue.indexOf(item);
- if (position >= 0) {
- queue.remove(position);
+ boolean queueModified = false;
+ List<QueueEvent> events = new ArrayList<>();
+ List<FeedItem> updatedItems = new ArrayList<>();
+ for (long itemId : itemIds) {
+ int position = indexInItemList(queue, itemId);
+ if (position >= 0) {
+ final FeedItem item = DBReader.getFeedItem(itemId);
+ if (item == null) {
+ Log.e(TAG, "removeQueueItem - item in queue but somehow cannot be loaded." +
+ " Item ignored. It should never happen. id:" + itemId);
+ continue;
+ }
+ queue.remove(position);
+ item.removeTag(FeedItem.TAG_QUEUE);
+ events.add(QueueEvent.removed(item));
+ updatedItems.add(item);
+ queueModified = true;
+ } else {
+ Log.v(TAG, "removeQueueItem - item not in queue:" + itemId);
+ }
+ }
+ if (queueModified) {
adapter.setQueue(queue);
- item.removeTag(FeedItem.TAG_QUEUE);
- EventBus.getDefault().post(QueueEvent.removed(item));
- EventBus.getDefault().post(FeedItemEvent.updated(item));
+ for (QueueEvent event : events) {
+ EventBus.getDefault().post(event);
+ }
+ EventBus.getDefault().post(FeedItemEvent.updated(updatedItems));
} else {
Log.w(TAG, "Queue was not modified by call to removeQueueItem");
}
@@ -786,12 +814,17 @@ public class DBWriter {
}
private static boolean itemListContains(List<FeedItem> items, long itemId) {
- for (FeedItem item : items) {
+ return indexInItemList(items, itemId) >= 0;
+ }
+
+ private static int indexInItemList(List<FeedItem> items, long itemId) {
+ for (int i = 0; i < items.size(); i ++) {
+ FeedItem item = items.get(i);
if (item.getId() == itemId) {
- return true;
+ return i;
}
}
- return false;
+ return -1;
}
/**
diff --git a/core/src/main/res/drawable-hdpi/ic_check_box_grey600_24dp.png b/core/src/main/res/drawable-hdpi/ic_check_box_grey600_24dp.png
deleted file mode 100644
index 187a426a8..000000000
--- a/core/src/main/res/drawable-hdpi/ic_check_box_grey600_24dp.png
+++ /dev/null
Binary files differ
diff --git a/core/src/main/res/drawable-hdpi/ic_check_box_outline_blank_grey600_24dp.png b/core/src/main/res/drawable-hdpi/ic_check_box_outline_blank_grey600_24dp.png
deleted file mode 100644
index 076773bca..000000000
--- a/core/src/main/res/drawable-hdpi/ic_check_box_outline_blank_grey600_24dp.png
+++ /dev/null
Binary files differ
diff --git a/core/src/main/res/drawable-hdpi/ic_check_box_outline_blank_white_24dp.png b/core/src/main/res/drawable-hdpi/ic_check_box_outline_blank_white_24dp.png
deleted file mode 100644
index ecaf0d5be..000000000
--- a/core/src/main/res/drawable-hdpi/ic_check_box_outline_blank_white_24dp.png
+++ /dev/null
Binary files differ
diff --git a/core/src/main/res/drawable-hdpi/ic_check_box_white_24dp.png b/core/src/main/res/drawable-hdpi/ic_check_box_white_24dp.png
deleted file mode 100644
index 5ce64cc5f..000000000
--- a/core/src/main/res/drawable-hdpi/ic_check_box_white_24dp.png
+++ /dev/null
Binary files differ
diff --git a/core/src/main/res/drawable-hdpi/ic_indeterminate_check_box_grey600_24dp.png b/core/src/main/res/drawable-hdpi/ic_indeterminate_check_box_grey600_24dp.png
deleted file mode 100644
index e56fbf224..000000000
--- a/core/src/main/res/drawable-hdpi/ic_indeterminate_check_box_grey600_24dp.png
+++ /dev/null
Binary files differ
diff --git a/core/src/main/res/drawable-hdpi/ic_indeterminate_check_box_white_24dp.png b/core/src/main/res/drawable-hdpi/ic_indeterminate_check_box_white_24dp.png
deleted file mode 100644
index dccf44930..000000000
--- a/core/src/main/res/drawable-hdpi/ic_indeterminate_check_box_white_24dp.png
+++ /dev/null
Binary files differ
diff --git a/core/src/main/res/drawable-mdpi/ic_check_box_grey600_24dp.png b/core/src/main/res/drawable-mdpi/ic_check_box_grey600_24dp.png
deleted file mode 100644
index d5bdfa433..000000000
--- a/core/src/main/res/drawable-mdpi/ic_check_box_grey600_24dp.png
+++ /dev/null
Binary files differ
diff --git a/core/src/main/res/drawable-mdpi/ic_check_box_outline_blank_grey600_24dp.png b/core/src/main/res/drawable-mdpi/ic_check_box_outline_blank_grey600_24dp.png
deleted file mode 100644
index aefe5b6c1..000000000
--- a/core/src/main/res/drawable-mdpi/ic_check_box_outline_blank_grey600_24dp.png
+++ /dev/null
Binary files differ
diff --git a/core/src/main/res/drawable-mdpi/ic_check_box_outline_blank_white_24dp.png b/core/src/main/res/drawable-mdpi/ic_check_box_outline_blank_white_24dp.png
deleted file mode 100644
index a3a588c64..000000000
--- a/core/src/main/res/drawable-mdpi/ic_check_box_outline_blank_white_24dp.png
+++ /dev/null
Binary files differ
diff --git a/core/src/main/res/drawable-mdpi/ic_check_box_white_24dp.png b/core/src/main/res/drawable-mdpi/ic_check_box_white_24dp.png
deleted file mode 100644
index dc94cdbf4..000000000
--- a/core/src/main/res/drawable-mdpi/ic_check_box_white_24dp.png
+++ /dev/null
Binary files differ
diff --git a/core/src/main/res/drawable-mdpi/ic_indeterminate_check_box_grey600_24dp.png b/core/src/main/res/drawable-mdpi/ic_indeterminate_check_box_grey600_24dp.png
deleted file mode 100644
index 0e6ce58e3..000000000
--- a/core/src/main/res/drawable-mdpi/ic_indeterminate_check_box_grey600_24dp.png
+++ /dev/null
Binary files differ
diff --git a/core/src/main/res/drawable-mdpi/ic_indeterminate_check_box_white_24dp.png b/core/src/main/res/drawable-mdpi/ic_indeterminate_check_box_white_24dp.png
deleted file mode 100644
index c496b4648..000000000
--- a/core/src/main/res/drawable-mdpi/ic_indeterminate_check_box_white_24dp.png
+++ /dev/null
Binary files differ
diff --git a/core/src/main/res/drawable-xhdpi/ic_check_box_grey600_24dp.png b/core/src/main/res/drawable-xhdpi/ic_check_box_grey600_24dp.png
deleted file mode 100644
index e46ab71b4..000000000
--- a/core/src/main/res/drawable-xhdpi/ic_check_box_grey600_24dp.png
+++ /dev/null
Binary files differ
diff --git a/core/src/main/res/drawable-xhdpi/ic_check_box_outline_blank_grey600_24dp.png b/core/src/main/res/drawable-xhdpi/ic_check_box_outline_blank_grey600_24dp.png
deleted file mode 100644
index bb15a903a..000000000
--- a/core/src/main/res/drawable-xhdpi/ic_check_box_outline_blank_grey600_24dp.png
+++ /dev/null
Binary files differ
diff --git a/core/src/main/res/drawable-xhdpi/ic_check_box_outline_blank_white_24dp.png b/core/src/main/res/drawable-xhdpi/ic_check_box_outline_blank_white_24dp.png
deleted file mode 100644
index 336682497..000000000
--- a/core/src/main/res/drawable-xhdpi/ic_check_box_outline_blank_white_24dp.png
+++ /dev/null
Binary files differ
diff --git a/core/src/main/res/drawable-xhdpi/ic_check_box_white_24dp.png b/core/src/main/res/drawable-xhdpi/ic_check_box_white_24dp.png
deleted file mode 100644
index cdb4a3181..000000000
--- a/core/src/main/res/drawable-xhdpi/ic_check_box_white_24dp.png
+++ /dev/null
Binary files differ
diff --git a/core/src/main/res/drawable-xhdpi/ic_indeterminate_check_box_grey600_24dp.png b/core/src/main/res/drawable-xhdpi/ic_indeterminate_check_box_grey600_24dp.png
deleted file mode 100644
index 3b0d3aa1a..000000000
--- a/core/src/main/res/drawable-xhdpi/ic_indeterminate_check_box_grey600_24dp.png
+++ /dev/null
Binary files differ
diff --git a/core/src/main/res/drawable-xhdpi/ic_indeterminate_check_box_white_24dp.png b/core/src/main/res/drawable-xhdpi/ic_indeterminate_check_box_white_24dp.png
deleted file mode 100644
index 57e478e9f..000000000
--- a/core/src/main/res/drawable-xhdpi/ic_indeterminate_check_box_white_24dp.png
+++ /dev/null
Binary files differ
diff --git a/core/src/main/res/drawable-xxhdpi/ic_check_box_grey600_24dp.png b/core/src/main/res/drawable-xxhdpi/ic_check_box_grey600_24dp.png
deleted file mode 100644
index 7093f28d5..000000000
--- a/core/src/main/res/drawable-xxhdpi/ic_check_box_grey600_24dp.png
+++ /dev/null
Binary files differ
diff --git a/core/src/main/res/drawable-xxhdpi/ic_check_box_outline_blank_grey600_24dp.png b/core/src/main/res/drawable-xxhdpi/ic_check_box_outline_blank_grey600_24dp.png
deleted file mode 100644
index 050e6cd6c..000000000
--- a/core/src/main/res/drawable-xxhdpi/ic_check_box_outline_blank_grey600_24dp.png
+++ /dev/null
Binary files differ
diff --git a/core/src/main/res/drawable-xxhdpi/ic_check_box_outline_blank_white_24dp.png b/core/src/main/res/drawable-xxhdpi/ic_check_box_outline_blank_white_24dp.png
deleted file mode 100644
index 56d380575..000000000
--- a/core/src/main/res/drawable-xxhdpi/ic_check_box_outline_blank_white_24dp.png
+++ /dev/null
Binary files differ
diff --git a/core/src/main/res/drawable-xxhdpi/ic_check_box_white_24dp.png b/core/src/main/res/drawable-xxhdpi/ic_check_box_white_24dp.png
deleted file mode 100644
index ba9af5265..000000000
--- a/core/src/main/res/drawable-xxhdpi/ic_check_box_white_24dp.png
+++ /dev/null
Binary files differ
diff --git a/core/src/main/res/drawable-xxhdpi/ic_indeterminate_check_box_grey600_24dp.png b/core/src/main/res/drawable-xxhdpi/ic_indeterminate_check_box_grey600_24dp.png
deleted file mode 100644
index 2e7d39a5a..000000000
--- a/core/src/main/res/drawable-xxhdpi/ic_indeterminate_check_box_grey600_24dp.png
+++ /dev/null
Binary files differ
diff --git a/core/src/main/res/drawable-xxhdpi/ic_indeterminate_check_box_white_24dp.png b/core/src/main/res/drawable-xxhdpi/ic_indeterminate_check_box_white_24dp.png
deleted file mode 100644
index ec4981f5c..000000000
--- a/core/src/main/res/drawable-xxhdpi/ic_indeterminate_check_box_white_24dp.png
+++ /dev/null
Binary files differ
diff --git a/core/src/main/res/drawable/ic_fab_edit.xml b/core/src/main/res/drawable/ic_fab_edit.xml
new file mode 100644
index 000000000..cb2e394b0
--- /dev/null
+++ b/core/src/main/res/drawable/ic_fab_edit.xml
@@ -0,0 +1,5 @@
+<vector android:height="24dp"
+ android:viewportHeight="24.0" android:viewportWidth="24.0"
+ android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+ <path android:fillColor="#FFFFFFFF" android:pathData="M3,17.25V21h3.75L17.81,9.94l-3.75,-3.75L3,17.25zM20.71,7.04c0.39,-0.39 0.39,-1.02 0,-1.41l-2.34,-2.34c-0.39,-0.39 -1.02,-0.39 -1.41,0l-1.83,1.83 3.75,3.75 1.83,-1.83z"/>
+</vector>
diff --git a/core/src/main/res/drawable/ic_remove_grey600.xml b/core/src/main/res/drawable/ic_remove_grey600.xml
new file mode 100644
index 000000000..5a6b2af6b
--- /dev/null
+++ b/core/src/main/res/drawable/ic_remove_grey600.xml
@@ -0,0 +1,5 @@
+<vector android:height="24dp"
+ android:viewportHeight="24.0" android:viewportWidth="24.0"
+ android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+ <path android:fillColor="#FF757575" android:pathData="M19,13H5v-2h14v2z"/>
+</vector>
diff --git a/core/src/main/res/drawable/ic_remove_white.xml b/core/src/main/res/drawable/ic_remove_white.xml
new file mode 100644
index 000000000..d812091fb
--- /dev/null
+++ b/core/src/main/res/drawable/ic_remove_white.xml
@@ -0,0 +1,5 @@
+<vector android:height="24dp"
+ android:viewportHeight="24.0" android:viewportWidth="24.0"
+ android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+ <path android:fillColor="#FFFFFFFF" android:pathData="M19,13H5v-2h14v2z"/>
+</vector>
diff --git a/core/src/main/res/drawable/ic_select_all_grey600.xml b/core/src/main/res/drawable/ic_select_all_grey600.xml
new file mode 100644
index 000000000..96e9a2de5
--- /dev/null
+++ b/core/src/main/res/drawable/ic_select_all_grey600.xml
@@ -0,0 +1,9 @@
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24.0"
+ android:viewportHeight="24.0">
+ <path
+ android:fillColor="#FF757575"
+ android:pathData="M3,5h2L5,3c-1.1,0 -2,0.9 -2,2zM3,13h2v-2L3,11v2zM7,21h2v-2L7,19v2zM3,9h2L5,7L3,7v2zM13,3h-2v2h2L13,3zM19,3v2h2c0,-1.1 -0.9,-2 -2,-2zM5,21v-2L3,19c0,1.1 0.9,2 2,2zM3,17h2v-2L3,15v2zM9,3L7,3v2h2L9,3zM11,21h2v-2h-2v2zM19,13h2v-2h-2v2zM19,21c1.1,0 2,-0.9 2,-2h-2v2zM19,9h2L21,7h-2v2zM19,17h2v-2h-2v2zM15,21h2v-2h-2v2zM15,5h2L17,3h-2v2zM7,17h10L17,7L7,7v10zM9,9h6v6L9,15L9,9z"/>
+</vector>
diff --git a/core/src/main/res/drawable/ic_select_all_white.xml b/core/src/main/res/drawable/ic_select_all_white.xml
new file mode 100644
index 000000000..0fc49c923
--- /dev/null
+++ b/core/src/main/res/drawable/ic_select_all_white.xml
@@ -0,0 +1,9 @@
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24.0"
+ android:viewportHeight="24.0">
+ <path
+ android:fillColor="#FFFFFFFF"
+ android:pathData="M3,5h2L5,3c-1.1,0 -2,0.9 -2,2zM3,13h2v-2L3,11v2zM7,21h2v-2L7,19v2zM3,9h2L5,7L3,7v2zM13,3h-2v2h2L13,3zM19,3v2h2c0,-1.1 -0.9,-2 -2,-2zM5,21v-2L3,19c0,1.1 0.9,2 2,2zM3,17h2v-2L3,15v2zM9,3L7,3v2h2L9,3zM11,21h2v-2h-2v2zM19,13h2v-2h-2v2zM19,21c1.1,0 2,-0.9 2,-2h-2v2zM19,9h2L21,7h-2v2zM19,17h2v-2h-2v2zM15,21h2v-2h-2v2zM15,5h2L17,3h-2v2zM7,17h10L17,7L7,7v10zM9,9h6v6L9,15L9,9z"/>
+</vector>
diff --git a/core/src/main/res/drawable/ic_select_none_grey600.xml b/core/src/main/res/drawable/ic_select_none_grey600.xml
new file mode 100644
index 000000000..8057f73ca
--- /dev/null
+++ b/core/src/main/res/drawable/ic_select_none_grey600.xml
@@ -0,0 +1,11 @@
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24.0"
+ android:viewportHeight="24.0">
+ <path
+ android:fillColor="#FF757575"
+ android:pathData="m3,5l2,0l0,-2c-1.1,0 -2,0.9 -2,2zm0,8l2,0l0,-2l-2,0l0,2zm4,8l2,0l0,-2l-2,0l0,2zm-4,-12l2,0l0,-2l-2,0l0,2zm10,-6l-2,0l0,2l2,0l0,-2zm6,0l0,2l2,0c0,-1.1 -0.9,-2 -2,-2zm-14,18l0,-2l-2,0c0,1.1 0.9,2 2,2zm-2,-4l2,0l0,-2l-2,0l0,2zm6,-14l-2,0l0,2l2,0l0,-2zm2,18l2,0l0,-2l-2,0l0,2zm8,-8l2,0l0,-2l-2,0l0,2zm0,8c1.1,0 2,-0.9 2,-2l-2,0l0,2zm0,-12l2,0l0,-2l-2,0l0,2zm0,8l2,0l0,-2l-2,0l0,2zm-4,4l2,0l0,-2l-2,0l0,2zm0,-16l2,0l0,-2l-2,0l0,2z"/>
+ <path android:fillColor="#FF757575"
+ android:pathData="M17,8.41L15.59,7 12,10.59 8.41,7 7,8.41 10.59,12 7,15.59 8.41,17 12,13.41 15.59,17 17,15.59 13.41,12z"/>
+</vector>
diff --git a/core/src/main/res/drawable/ic_select_none_white.xml b/core/src/main/res/drawable/ic_select_none_white.xml
new file mode 100644
index 000000000..3e1f6b884
--- /dev/null
+++ b/core/src/main/res/drawable/ic_select_none_white.xml
@@ -0,0 +1,11 @@
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24.0"
+ android:viewportHeight="24.0">
+ <path
+ android:fillColor="#FFFFFFFF"
+ android:pathData="m3,5l2,0l0,-2c-1.1,0 -2,0.9 -2,2zm0,8l2,0l0,-2l-2,0l0,2zm4,8l2,0l0,-2l-2,0l0,2zm-4,-12l2,0l0,-2l-2,0l0,2zm10,-6l-2,0l0,2l2,0l0,-2zm6,0l0,2l2,0c0,-1.1 -0.9,-2 -2,-2zm-14,18l0,-2l-2,0c0,1.1 0.9,2 2,2zm-2,-4l2,0l0,-2l-2,0l0,2zm6,-14l-2,0l0,2l2,0l0,-2zm2,18l2,0l0,-2l-2,0l0,2zm8,-8l2,0l0,-2l-2,0l0,2zm0,8c1.1,0 2,-0.9 2,-2l-2,0l0,2zm0,-12l2,0l0,-2l-2,0l0,2zm0,8l2,0l0,-2l-2,0l0,2zm-4,4l2,0l0,-2l-2,0l0,2zm0,-16l2,0l0,-2l-2,0l0,2z"/>
+ <path android:fillColor="#FFFFFFFF"
+ android:pathData="M17,8.41L15.59,7 12,10.59 8.41,7 7,8.41 10.59,12 7,15.59 8.41,17 12,13.41 15.59,17 17,15.59 13.41,12z"/>
+</vector>
diff --git a/core/src/main/res/values/attrs.xml b/core/src/main/res/values/attrs.xml
index 48e55768e..5311d6cd2 100644
--- a/core/src/main/res/values/attrs.xml
+++ b/core/src/main/res/values/attrs.xml
@@ -12,6 +12,7 @@
<attr name="av_rewind" format="reference"/>
<attr name="content_discard" format="reference"/>
<attr name="content_new" format="reference"/>
+ <attr name="content_remove_from_queue" format="reference"/>
<attr name="storage" format="reference"/>
<attr name="statistics" format="reference"/>
<attr name="feed" format="reference"/>
@@ -47,9 +48,8 @@
<attr name="ic_sleep" format="reference"/>
<attr name="ic_sleep_off" format="reference"/>
<attr name="checkbox_multiple" format="reference"/>
- <attr name="ic_check_box" format="reference"/>
- <attr name="ic_check_box_outline" format="reference"/>
- <attr name="ic_indeterminate_check_box" format="reference"/>
+ <attr name="ic_select_all" format="reference"/>
+ <attr name="ic_select_none" format="reference"/>
<attr name="ic_sort" format="reference"/>
<attr name="ic_sd_storage" format="reference"/>
<attr name="ic_create_new_folder" format="reference"/>
diff --git a/core/src/main/res/values/strings.xml b/core/src/main/res/values/strings.xml
index 3b03f2af7..3d730516e 100644
--- a/core/src/main/res/values/strings.xml
+++ b/core/src/main/res/values/strings.xml
@@ -113,6 +113,7 @@
<item quantity="one">1 day after finishing</item>
<item quantity="other">%d days after finishing</item>
</plurals>
+ <string name="num_selected_label">%d selected</string>
<!-- 'Add Feed' Activity labels -->
<string name="feedurl_label">Feed URL</string>
@@ -165,6 +166,10 @@
<!-- actions on feeditems -->
<string name="download_label">Download</string>
+ <plurals name="downloading_batch_label">
+ <item quantity="one">Downloading %d episode.</item>
+ <item quantity="other">Downloading %d episodes.</item>
+ </plurals>
<string name="play_label">Play</string>
<string name="pause_label">Pause</string>
<string name="stop_label">Stop</string>
@@ -172,15 +177,35 @@
<string name="remove_label">Remove</string>
<string name="delete_label">Delete</string>
<string name="delete_failed">Unable to delete file. Rebooting the device could help.</string>
- <string name="remove_episode_lable">Remove Episode</string>
+ <string name="delete_episode_label">Delete Episode</string>
+ <plurals name="deleted_episode_batch_label">
+ <item quantity="one">%d episode deleted.</item>
+ <item quantity="other">%d episodes deleted.</item>
+ </plurals>
<string name="mark_as_seen_label">Mark as seen</string>
<string name="marked_as_seen_label">Marked as seen</string>
<string name="mark_read_label">Mark as played</string>
<string name="marked_as_read_label">Marked as played</string>
+ <plurals name="marked_read_batch_label">
+ <item quantity="one">%d episode marked as played.</item>
+ <item quantity="other">%d episodes marked as played.</item>
+ </plurals>
<string name="mark_unread_label">Mark as unplayed</string>
+ <plurals name="marked_unread_batch_label">
+ <item quantity="one">%d episode marked as unplayed.</item>
+ <item quantity="other">%d episodes marked as unplayed.</item>
+ </plurals>
<string name="add_to_queue_label">Add to Queue</string>
<string name="added_to_queue_label">Added to Queue</string>
+ <plurals name="added_to_queue_batch_label">
+ <item quantity="one">%d episode added to queue.</item>
+ <item quantity="other">%d episodes added to queue.</item>
+ </plurals>
<string name="remove_from_queue_label">Remove from Queue</string>
+ <plurals name="removed_from_queue_batch_label">
+ <item quantity="one">%d episode removed from queue.</item>
+ <item quantity="other">%d episodes removed from queue.</item>
+ </plurals>
<string name="add_to_favorite_label">Add to Favorites</string>
<string name="added_to_favorites">Added to Favorites</string>
<string name="remove_from_favorite_label">Remove from Favorites</string>
diff --git a/core/src/main/res/values/styles.xml b/core/src/main/res/values/styles.xml
index 363a69a63..e9a7a2f64 100644
--- a/core/src/main/res/values/styles.xml
+++ b/core/src/main/res/values/styles.xml
@@ -26,6 +26,7 @@
<item type="attr" name="av_rewind">@drawable/ic_fast_rewind_grey600_24dp</item>
<item type="attr" name="content_discard">@drawable/ic_delete_grey600_24dp</item>
<item type="attr" name="content_new">@drawable/ic_add_grey600_24dp</item>
+ <item type="attr" name="content_remove_from_queue">@drawable/ic_remove_grey600</item>
<item type="attr" name="feed">@drawable/ic_feed_grey600_24dp</item>
<item type="attr" name="location_web_site">@drawable/ic_web_grey600_24dp</item>
<item type="attr" name="navigation_accept">@drawable/ic_done_grey600_24dp</item>
@@ -60,9 +61,8 @@
<item type="attr" name="ic_filter">@drawable/ic_filter_grey600_24dp</item>
<item type="attr" name="ic_sleep">@drawable/ic_sleep_grey600_24dp</item>
<item type="attr" name="ic_sleep_off">@drawable/ic_sleep_off_grey600_24dp</item>
- <item type="attr" name="ic_check_box">@drawable/ic_check_box_grey600_24dp</item>
- <item type="attr" name="ic_check_box_outline">@drawable/ic_check_box_outline_blank_grey600_24dp</item>
- <item type="attr" name="ic_indeterminate_check_box">@drawable/ic_indeterminate_check_box_grey600_24dp</item>
+ <item type="attr" name="ic_select_all">@drawable/ic_select_all_grey600</item>
+ <item type="attr" name="ic_select_none">@drawable/ic_select_none_grey600</item>
<item type="attr" name="ic_sort">@drawable/ic_sort_grey600_24dp</item>
<item type="attr" name="ic_sd_storage">@drawable/ic_sd_storage_grey600_36dp</item>
<item type="attr" name="ic_create_new_folder">@drawable/ic_create_new_folder_grey600_24dp</item>
@@ -110,6 +110,7 @@
<item type="attr" name="av_rewind">@drawable/ic_fast_rewind_white_24dp</item>
<item type="attr" name="content_discard">@drawable/ic_delete_white_24dp</item>
<item type="attr" name="content_new">@drawable/ic_add_white_24dp</item>
+ <item type="attr" name="content_remove_from_queue">@drawable/ic_remove_white</item>
<item type="attr" name="feed">@drawable/ic_feed_white_24dp</item>
<item type="attr" name="location_web_site">@drawable/ic_web_white_24dp</item>
<item type="attr" name="navigation_accept">@drawable/ic_done_white_24dp</item>
@@ -144,9 +145,8 @@
<item type="attr" name="ic_filter">@drawable/ic_filter_white_24dp</item>
<item type="attr" name="ic_sleep">@drawable/ic_sleep_white_24dp</item>
<item type="attr" name="ic_sleep_off">@drawable/ic_sleep_off_white_24dp</item>
- <item type="attr" name="ic_check_box">@drawable/ic_check_box_white_24dp</item>
- <item type="attr" name="ic_check_box_outline">@drawable/ic_check_box_outline_blank_white_24dp</item>
- <item type="attr" name="ic_indeterminate_check_box">@drawable/ic_indeterminate_check_box_white_24dp</item>
+ <item type="attr" name="ic_select_all">@drawable/ic_select_all_white</item>
+ <item type="attr" name="ic_select_none">@drawable/ic_select_none_white</item>
<item type="attr" name="ic_sort">@drawable/ic_sort_white_24dp</item>
<item type="attr" name="ic_sd_storage">@drawable/ic_sd_storage_white_36dp</item>
<item type="attr" name="ic_create_new_folder">@drawable/ic_create_new_folder_white_24dp</item>
@@ -214,6 +214,7 @@
<item type="attr" name="av_rewind">@drawable/ic_fast_rewind_grey600_24dp</item>
<item type="attr" name="content_discard">@drawable/ic_delete_grey600_24dp</item>
<item type="attr" name="content_new">@drawable/ic_add_grey600_24dp</item>
+ <item type="attr" name="content_remove_from_queue">@drawable/ic_remove_grey600</item>
<item type="attr" name="feed">@drawable/ic_feed_grey600_24dp</item>
<item type="attr" name="location_web_site">@drawable/ic_web_grey600_24dp</item>
<item type="attr" name="navigation_accept">@drawable/ic_done_grey600_24dp</item>
@@ -248,9 +249,8 @@
<item type="attr" name="ic_filter">@drawable/ic_filter_grey600_24dp</item>
<item type="attr" name="ic_sleep">@drawable/ic_sleep_grey600_24dp</item>
<item type="attr" name="ic_sleep_off">@drawable/ic_sleep_off_grey600_24dp</item>
- <item type="attr" name="ic_check_box">@drawable/ic_check_box_grey600_24dp</item>
- <item type="attr" name="ic_check_box_outline">@drawable/ic_check_box_outline_blank_grey600_24dp</item>
- <item type="attr" name="ic_indeterminate_check_box">@drawable/ic_indeterminate_check_box_grey600_24dp</item>
+ <item type="attr" name="ic_select_all">@drawable/ic_select_all_grey600</item>
+ <item type="attr" name="ic_select_none">@drawable/ic_select_none_grey600</item>
<item type="attr" name="ic_sort">@drawable/ic_sort_grey600_24dp</item>
<item type="attr" name="ic_sd_storage">@drawable/ic_sd_storage_grey600_36dp</item>
<item type="attr" name="ic_create_new_folder">@drawable/ic_create_new_folder_grey600_24dp</item>
@@ -298,6 +298,7 @@
<item type="attr" name="content_discard">@drawable/ic_delete_white_24dp</item>
<item type="attr" name="content_new">@drawable/ic_add_white_24dp</item>
<item type="attr" name="feed">@drawable/ic_feed_white_24dp</item>
+ <item type="attr" name="content_remove_from_queue">@drawable/ic_remove_white</item>
<item type="attr" name="location_web_site">@drawable/ic_web_white_24dp</item>
<item type="attr" name="navigation_accept">@drawable/ic_done_white_24dp</item>
<item type="attr" name="navigation_cancel">@drawable/ic_cancel_white_24dp</item>
@@ -331,9 +332,8 @@
<item type="attr" name="ic_filter">@drawable/ic_filter_white_24dp</item>
<item type="attr" name="ic_sleep">@drawable/ic_sleep_white_24dp</item>
<item type="attr" name="ic_sleep_off">@drawable/ic_sleep_off_white_24dp</item>
- <item type="attr" name="ic_check_box">@drawable/ic_check_box_white_24dp</item>
- <item type="attr" name="ic_check_box_outline">@drawable/ic_check_box_outline_blank_white_24dp</item>
- <item type="attr" name="ic_indeterminate_check_box">@drawable/ic_indeterminate_check_box_white_24dp</item>
+ <item type="attr" name="ic_select_all">@drawable/ic_select_all_white</item>
+ <item type="attr" name="ic_select_none">@drawable/ic_select_none_white</item>
<item type="attr" name="ic_sort">@drawable/ic_sort_white_24dp</item>
<item type="attr" name="ic_sd_storage">@drawable/ic_sd_storage_white_36dp</item>
<item type="attr" name="ic_create_new_folder">@drawable/ic_create_new_folder_white_24dp</item>