Replace old episode multi-select with new multi-select. (#5253)
This commit is contained in:
parent
323f1f6142
commit
00bf2db0a4
@ -106,5 +106,5 @@ workflows:
|
||||
branchBaseCommit=`git merge-base origin/develop HEAD`
|
||||
echo "Comparing to $branchBaseCommit"
|
||||
curl -s -L https://github.com/ByteHamster/android-xml-formatter/releases/download/1.1.0/android-xml-formatter.jar > android-xml-formatter.jar
|
||||
git diff --name-only $branchBaseCommit | { grep "res/layout/" || true; } | xargs java -jar android-xml-formatter.jar
|
||||
git diff --name-only $branchBaseCommit --diff-filter=AM | { grep "res/layout/" || true; } | xargs java -jar android-xml-formatter.jar
|
||||
test $(git diff | wc -l) -eq 0 || (echo -e "\n\n===== Found XML code style violations! See output below how to fix them. =====\n\n" && git --no-pager diff --color=always && false)
|
||||
|
@ -44,7 +44,7 @@ public class QueueRecyclerAdapter extends EpisodeItemListAdapter {
|
||||
return false;
|
||||
};
|
||||
|
||||
if (!dragDropEnabled) {
|
||||
if (!dragDropEnabled || inActionMode()) {
|
||||
holder.dragHandle.setVisibility(View.GONE);
|
||||
holder.dragHandle.setOnTouchListener(null);
|
||||
holder.coverHolder.setOnTouchListener(null);
|
||||
@ -63,11 +63,17 @@ public class QueueRecyclerAdapter extends EpisodeItemListAdapter {
|
||||
inflater.inflate(R.menu.queue_context, menu);
|
||||
super.onCreateContextMenu(menu, v, menuInfo);
|
||||
|
||||
final boolean keepSorted = UserPreferences.isQueueKeepSorted();
|
||||
if (getItem(0).getId() == getLongPressedItem().getId() || keepSorted) {
|
||||
if (!inActionMode()) {
|
||||
menu.findItem(R.id.multi_select).setVisible(true);
|
||||
final boolean keepSorted = UserPreferences.isQueueKeepSorted();
|
||||
if (getItem(0).getId() == getLongPressedItem().getId() || keepSorted) {
|
||||
menu.findItem(R.id.move_to_top_item).setVisible(false);
|
||||
}
|
||||
if (getItem(getItemCount() - 1).getId() == getLongPressedItem().getId() || keepSorted) {
|
||||
menu.findItem(R.id.move_to_bottom_item).setVisible(false);
|
||||
}
|
||||
} else {
|
||||
menu.findItem(R.id.move_to_top_item).setVisible(false);
|
||||
}
|
||||
if (getItem(getItemCount() - 1).getId() == getLongPressedItem().getId() || keepSorted) {
|
||||
menu.findItem(R.id.move_to_bottom_item).setVisible(false);
|
||||
}
|
||||
}
|
||||
|
@ -1,466 +0,0 @@
|
||||
package de.danoeh.antennapod.dialog;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.util.Log;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ArrayAdapter;
|
||||
import android.widget.ListView;
|
||||
import androidx.annotation.IdRes;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.PluralsRes;
|
||||
import androidx.annotation.StringRes;
|
||||
import androidx.appcompat.app.AlertDialog;
|
||||
import androidx.appcompat.widget.Toolbar;
|
||||
import androidx.collection.ArrayMap;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import com.google.android.material.snackbar.Snackbar;
|
||||
import com.leinardi.android.speeddial.SpeedDialView;
|
||||
import de.danoeh.antennapod.R;
|
||||
import de.danoeh.antennapod.activity.MainActivity;
|
||||
import de.danoeh.antennapod.core.dialog.DownloadRequestErrorDialogCreator;
|
||||
import de.danoeh.antennapod.model.feed.FeedItem;
|
||||
import de.danoeh.antennapod.core.storage.DBWriter;
|
||||
import de.danoeh.antennapod.core.storage.DownloadRequestException;
|
||||
import de.danoeh.antennapod.core.storage.DownloadRequester;
|
||||
import de.danoeh.antennapod.core.util.FeedItemPermutors;
|
||||
import de.danoeh.antennapod.core.util.LongList;
|
||||
import de.danoeh.antennapod.model.feed.SortOrder;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class EpisodesApplyActionFragment extends Fragment implements Toolbar.OnMenuItemClickListener {
|
||||
|
||||
public static final String TAG = "EpisodeActionFragment";
|
||||
|
||||
public static final int ACTION_ADD_TO_QUEUE = 1;
|
||||
public static final int ACTION_REMOVE_FROM_QUEUE = 2;
|
||||
private static final int ACTION_MARK_PLAYED = 4;
|
||||
private static final int ACTION_MARK_UNPLAYED = 8;
|
||||
public static final int ACTION_DOWNLOAD = 16;
|
||||
public static final int ACTION_DELETE = 32;
|
||||
public 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 static 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 final Map<Long, FeedItem> idMap = new ArrayMap<>();
|
||||
private final List<FeedItem> episodes = new ArrayList<>();
|
||||
private int actions;
|
||||
private final List<String> titles = new ArrayList<>();
|
||||
private final LongList checkedIds = new LongList();
|
||||
|
||||
private ListView mListView;
|
||||
private ArrayAdapter<String> mAdapter;
|
||||
private SpeedDialView mSpeedDialView;
|
||||
private Toolbar toolbar;
|
||||
|
||||
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, int actions) {
|
||||
EpisodesApplyActionFragment f = new EpisodesApplyActionFragment();
|
||||
f.episodes.addAll(items);
|
||||
for (FeedItem episode : items) {
|
||||
f.idMap.put(episode.getId(), episode);
|
||||
}
|
||||
f.actions = actions;
|
||||
return f;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setRetainInstance(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
||||
Bundle savedInstanceState) {
|
||||
View view = inflater.inflate(R.layout.episodes_apply_action_fragment, container, false);
|
||||
|
||||
toolbar = view.findViewById(R.id.toolbar);
|
||||
toolbar.inflateMenu(R.menu.episodes_apply_action_options);
|
||||
toolbar.setNavigationOnClickListener(v -> getParentFragmentManager().popBackStack());
|
||||
toolbar.setOnMenuItemClickListener(this);
|
||||
refreshToolbarState();
|
||||
|
||||
mListView = view.findViewById(android.R.id.list);
|
||||
mListView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
|
||||
mListView.setOnItemClickListener((listView, view1, position, rowId) -> {
|
||||
long id = episodes.get(position).getId();
|
||||
if (checkedIds.contains(id)) {
|
||||
checkedIds.remove(id);
|
||||
} else {
|
||||
checkedIds.add(id);
|
||||
}
|
||||
refreshCheckboxes();
|
||||
});
|
||||
mListView.setOnItemLongClickListener((adapterView, view12, position, id) -> {
|
||||
new AlertDialog.Builder(getActivity())
|
||||
.setItems(R.array.batch_long_press_options, (dialogInterface, item) -> {
|
||||
int direction;
|
||||
if (item == 0) {
|
||||
direction = -1;
|
||||
} else {
|
||||
direction = 1;
|
||||
}
|
||||
|
||||
int currentPosition = position + direction;
|
||||
while (currentPosition >= 0 && currentPosition < episodes.size()) {
|
||||
long id1 = episodes.get(currentPosition).getId();
|
||||
if (!checkedIds.contains(id1)) {
|
||||
checkedIds.add(id1);
|
||||
}
|
||||
currentPosition += direction;
|
||||
}
|
||||
refreshCheckboxes();
|
||||
}).show();
|
||||
return true;
|
||||
});
|
||||
|
||||
titles.clear();
|
||||
for (FeedItem episode : episodes) {
|
||||
titles.add(episode.getTitle());
|
||||
}
|
||||
|
||||
mAdapter = new ArrayAdapter<>(getActivity(),
|
||||
R.layout.simple_list_item_multiple_choice_on_start, titles);
|
||||
mListView.setAdapter(mAdapter);
|
||||
|
||||
// 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.setOnChangeListener(new SpeedDialView.OnChangeListener() {
|
||||
@Override
|
||||
public boolean onMainActionSelected() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onToggleChanged(boolean open) {
|
||||
if (open && checkedIds.size() == 0) {
|
||||
((MainActivity) getActivity()).showSnackbarAbovePlayer(R.string.no_items_selected,
|
||||
Snackbar.LENGTH_SHORT);
|
||||
mSpeedDialView.close();
|
||||
}
|
||||
}
|
||||
});
|
||||
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;
|
||||
});
|
||||
refreshCheckboxes();
|
||||
return view;
|
||||
}
|
||||
|
||||
public void refreshToolbarState() {
|
||||
MenuItem selectAllItem = toolbar.getMenu().findItem(R.id.select_toggle);
|
||||
if (checkedIds.size() == episodes.size()) {
|
||||
selectAllItem.setIcon(R.drawable.ic_select_none);
|
||||
selectAllItem.setTitle(R.string.deselect_all_label);
|
||||
} else {
|
||||
selectAllItem.setIcon(R.drawable.ic_select_all);
|
||||
selectAllItem.setTitle(R.string.select_all_label);
|
||||
}
|
||||
}
|
||||
|
||||
private static final Map<Integer, SortOrder> menuItemIdToSortOrder;
|
||||
static {
|
||||
Map<Integer, SortOrder> map = new ArrayMap<>();
|
||||
map.put(R.id.sort_title_a_z, SortOrder.EPISODE_TITLE_A_Z);
|
||||
map.put(R.id.sort_title_z_a, SortOrder.EPISODE_TITLE_Z_A);
|
||||
map.put(R.id.sort_date_new_old, SortOrder.DATE_NEW_OLD);
|
||||
map.put(R.id.sort_date_old_new, SortOrder.DATE_OLD_NEW);
|
||||
map.put(R.id.sort_duration_long_short, SortOrder.DURATION_LONG_SHORT);
|
||||
map.put(R.id.sort_duration_short_long, SortOrder.DURATION_SHORT_LONG);
|
||||
menuItemIdToSortOrder = Collections.unmodifiableMap(map);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onMenuItemClick(MenuItem item) {
|
||||
@StringRes int resId = 0;
|
||||
switch (item.getItemId()) {
|
||||
case R.id.select_options:
|
||||
return true;
|
||||
case R.id.select_toggle:
|
||||
if (checkedIds.size() == episodes.size()) {
|
||||
checkNone();
|
||||
} else {
|
||||
checkAll();
|
||||
}
|
||||
return true;
|
||||
case R.id.check_all:
|
||||
checkAll();
|
||||
resId = R.string.selected_all_label;
|
||||
break;
|
||||
case R.id.check_none:
|
||||
checkNone();
|
||||
resId = R.string.deselected_all_label;
|
||||
break;
|
||||
case R.id.check_played:
|
||||
checkPlayed(true);
|
||||
resId = R.string.selected_played_label;
|
||||
break;
|
||||
case R.id.check_unplayed:
|
||||
checkPlayed(false);
|
||||
resId = R.string.selected_unplayed_label;
|
||||
break;
|
||||
case R.id.check_downloaded:
|
||||
checkDownloaded(true);
|
||||
resId = R.string.selected_downloaded_label;
|
||||
break;
|
||||
case R.id.check_not_downloaded:
|
||||
checkDownloaded(false);
|
||||
resId = R.string.selected_not_downloaded_label;
|
||||
break;
|
||||
case R.id.check_queued:
|
||||
checkQueued(true);
|
||||
resId = R.string.selected_queued_label;
|
||||
break;
|
||||
case R.id.check_not_queued:
|
||||
checkQueued(false);
|
||||
resId = R.string.selected_not_queued_label;
|
||||
break;
|
||||
case R.id.check_has_media:
|
||||
checkWithMedia();
|
||||
resId = R.string.selected_has_media_label;
|
||||
break;
|
||||
default: // handle various sort options
|
||||
SortOrder sortOrder = menuItemIdToSortOrder.get(item.getItemId());
|
||||
if (sortOrder != null) {
|
||||
sort(sortOrder);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if (resId != 0) {
|
||||
((MainActivity) getActivity()).showSnackbarAbovePlayer(resId, Snackbar.LENGTH_SHORT);
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private void sort(@NonNull SortOrder sortOrder) {
|
||||
FeedItemPermutors.getPermutor(sortOrder)
|
||||
.reorder(episodes);
|
||||
refreshTitles();
|
||||
refreshCheckboxes();
|
||||
}
|
||||
|
||||
private void checkAll() {
|
||||
for (FeedItem episode : episodes) {
|
||||
if (!checkedIds.contains(episode.getId())) {
|
||||
checkedIds.add(episode.getId());
|
||||
}
|
||||
}
|
||||
refreshCheckboxes();
|
||||
}
|
||||
|
||||
private void checkNone() {
|
||||
checkedIds.clear();
|
||||
refreshCheckboxes();
|
||||
}
|
||||
|
||||
private void checkPlayed(boolean isPlayed) {
|
||||
for (FeedItem episode : episodes) {
|
||||
if (episode.isPlayed() == isPlayed) {
|
||||
if (!checkedIds.contains(episode.getId())) {
|
||||
checkedIds.add(episode.getId());
|
||||
}
|
||||
} else {
|
||||
if (checkedIds.contains(episode.getId())) {
|
||||
checkedIds.remove(episode.getId());
|
||||
}
|
||||
}
|
||||
}
|
||||
refreshCheckboxes();
|
||||
}
|
||||
|
||||
private void checkDownloaded(boolean isDownloaded) {
|
||||
for (FeedItem episode : episodes) {
|
||||
if (episode.hasMedia() && episode.getMedia().isDownloaded() == isDownloaded) {
|
||||
if (!checkedIds.contains(episode.getId())) {
|
||||
checkedIds.add(episode.getId());
|
||||
}
|
||||
} else {
|
||||
if (checkedIds.contains(episode.getId())) {
|
||||
checkedIds.remove(episode.getId());
|
||||
}
|
||||
}
|
||||
}
|
||||
refreshCheckboxes();
|
||||
}
|
||||
|
||||
private void checkQueued(boolean isQueued) {
|
||||
for (FeedItem episode : episodes) {
|
||||
if (episode.isTagged(FeedItem.TAG_QUEUE) == isQueued) {
|
||||
checkedIds.add(episode.getId());
|
||||
} else {
|
||||
checkedIds.remove(episode.getId());
|
||||
}
|
||||
}
|
||||
refreshCheckboxes();
|
||||
}
|
||||
|
||||
private void checkWithMedia() {
|
||||
for (FeedItem episode : episodes) {
|
||||
if (episode.hasMedia()) {
|
||||
checkedIds.add(episode.getId());
|
||||
} else {
|
||||
checkedIds.remove(episode.getId());
|
||||
}
|
||||
}
|
||||
refreshCheckboxes();
|
||||
}
|
||||
|
||||
private void refreshTitles() {
|
||||
titles.clear();
|
||||
for (FeedItem episode : episodes) {
|
||||
titles.add(episode.getTitle());
|
||||
}
|
||||
mAdapter.notifyDataSetChanged();
|
||||
}
|
||||
|
||||
private void refreshCheckboxes() {
|
||||
for (int i = 0; i < episodes.size(); i++) {
|
||||
FeedItem episode = episodes.get(i);
|
||||
boolean checked = checkedIds.contains(episode.getId());
|
||||
mListView.setItemChecked(i, checked);
|
||||
}
|
||||
refreshToolbarState();
|
||||
toolbar.setTitle(getResources().getQuantityString(R.plurals.num_selected_label,
|
||||
checkedIds.size(), checkedIds.size()));
|
||||
}
|
||||
|
||||
private void queueChecked() {
|
||||
// Check if an episode actually contains any media files before adding it to queue
|
||||
LongList toQueue = new LongList(checkedIds.size());
|
||||
for (FeedItem episode : episodes) {
|
||||
if (checkedIds.contains(episode.getId()) && episode.hasMedia()) {
|
||||
toQueue.add(episode.getId());
|
||||
}
|
||||
}
|
||||
DBWriter.addQueueItem(getActivity(), true, toQueue.toArray());
|
||||
close(R.plurals.added_to_queue_batch_label, toQueue.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(R.plurals.marked_read_batch_label, checkedIds.size());
|
||||
}
|
||||
|
||||
private void markedCheckedUnplayed() {
|
||||
DBWriter.markItemPlayed(FeedItem.UNPLAYED, checkedIds.toArray());
|
||||
close(R.plurals.marked_unread_batch_label, checkedIds.size());
|
||||
}
|
||||
|
||||
private void downloadChecked() {
|
||||
// download the check episodes in the same order as they are currently displayed
|
||||
List<FeedItem> toDownload = new ArrayList<>(checkedIds.size());
|
||||
for (FeedItem episode : episodes) {
|
||||
if (checkedIds.contains(episode.getId()) && episode.hasMedia() && !episode.getFeed().isLocalFeed()) {
|
||||
toDownload.add(episode);
|
||||
}
|
||||
}
|
||||
try {
|
||||
DownloadRequester.getInstance().downloadMedia(getActivity(), true, toDownload.toArray(new FeedItem[0]));
|
||||
} catch (DownloadRequestException e) {
|
||||
e.printStackTrace();
|
||||
DownloadRequestErrorDialogCreator.newRequestErrorDialog(getActivity(), e.getMessage());
|
||||
}
|
||||
close(R.plurals.downloading_batch_label, toDownload.size());
|
||||
}
|
||||
|
||||
private void deleteChecked() {
|
||||
int countHasMedia = 0;
|
||||
int countNoMedia = 0;
|
||||
for (long id : checkedIds.toArray()) {
|
||||
FeedItem episode = idMap.get(id);
|
||||
if (episode.hasMedia() && episode.getMedia().isDownloaded()) {
|
||||
countHasMedia++;
|
||||
DBWriter.deleteFeedMediaOfItem(getActivity(), episode.getMedia().getId());
|
||||
} else {
|
||||
countNoMedia++;
|
||||
}
|
||||
}
|
||||
closeMore(R.plurals.deleted_multi_episode_batch_label, countNoMedia, countHasMedia);
|
||||
}
|
||||
|
||||
private void close(@PluralsRes int msgId, int numItems) {
|
||||
((MainActivity) getActivity()).showSnackbarAbovePlayer(
|
||||
getResources().getQuantityString(msgId, numItems, numItems), Snackbar.LENGTH_LONG);
|
||||
getActivity().getSupportFragmentManager().popBackStack();
|
||||
}
|
||||
|
||||
private void closeMore(@PluralsRes int msgId, int countNoMedia, int countHasMedia) {
|
||||
((MainActivity) getActivity()).showSnackbarAbovePlayer(
|
||||
getResources().getQuantityString(msgId,
|
||||
(countHasMedia + countNoMedia),
|
||||
(countHasMedia + countNoMedia), countHasMedia),
|
||||
Snackbar.LENGTH_LONG);
|
||||
getActivity().getSupportFragmentManager().popBackStack();
|
||||
}
|
||||
}
|
@ -2,6 +2,7 @@ package de.danoeh.antennapod.fragment;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.util.Log;
|
||||
import android.view.ContextMenu;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
@ -12,6 +13,10 @@ import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.appcompat.widget.Toolbar;
|
||||
import androidx.fragment.app.Fragment;
|
||||
|
||||
import com.google.android.material.snackbar.Snackbar;
|
||||
import com.leinardi.android.speeddial.SpeedDialView;
|
||||
|
||||
import de.danoeh.antennapod.R;
|
||||
import de.danoeh.antennapod.activity.MainActivity;
|
||||
import de.danoeh.antennapod.adapter.EpisodeItemListAdapter;
|
||||
@ -22,13 +27,13 @@ import de.danoeh.antennapod.core.event.FeedItemEvent;
|
||||
import de.danoeh.antennapod.core.event.PlaybackPositionEvent;
|
||||
import de.danoeh.antennapod.core.event.PlayerStatusEvent;
|
||||
import de.danoeh.antennapod.core.event.UnreadItemsUpdateEvent;
|
||||
import de.danoeh.antennapod.fragment.actions.EpisodeMultiSelectActionHandler;
|
||||
import de.danoeh.antennapod.model.feed.FeedItem;
|
||||
import de.danoeh.antennapod.core.service.download.DownloadService;
|
||||
import de.danoeh.antennapod.core.storage.DBReader;
|
||||
import de.danoeh.antennapod.core.storage.DownloadRequester;
|
||||
import de.danoeh.antennapod.core.util.FeedItemUtil;
|
||||
import de.danoeh.antennapod.core.util.download.AutoUpdateManager;
|
||||
import de.danoeh.antennapod.dialog.EpisodesApplyActionFragment;
|
||||
import de.danoeh.antennapod.menuhandler.FeedItemMenuHandler;
|
||||
import de.danoeh.antennapod.menuhandler.MenuItemUtils;
|
||||
import de.danoeh.antennapod.view.EmptyViewHandler;
|
||||
@ -45,13 +50,11 @@ import org.greenrobot.eventbus.ThreadMode;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import static de.danoeh.antennapod.dialog.EpisodesApplyActionFragment.ACTION_ADD_TO_QUEUE;
|
||||
import static de.danoeh.antennapod.dialog.EpisodesApplyActionFragment.ACTION_DELETE;
|
||||
|
||||
/**
|
||||
* Displays all completed downloads and provides a button to delete them.
|
||||
*/
|
||||
public class CompletedDownloadsFragment extends Fragment {
|
||||
public class CompletedDownloadsFragment extends Fragment implements
|
||||
EpisodeItemListAdapter.OnEndSelectModeListener {
|
||||
|
||||
private static final String TAG = CompletedDownloadsFragment.class.getSimpleName();
|
||||
|
||||
@ -64,6 +67,8 @@ public class CompletedDownloadsFragment extends Fragment {
|
||||
|
||||
private boolean isUpdatingFeeds = false;
|
||||
|
||||
private SpeedDialView speedDialView;
|
||||
|
||||
@Override
|
||||
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
|
||||
@Nullable Bundle savedInstanceState) {
|
||||
@ -74,9 +79,39 @@ public class CompletedDownloadsFragment extends Fragment {
|
||||
recyclerView = root.findViewById(R.id.recyclerView);
|
||||
recyclerView.setRecycledViewPool(((MainActivity) getActivity()).getRecycledViewPool());
|
||||
adapter = new CompletedDownloadsListAdapter((MainActivity) getActivity());
|
||||
adapter.setOnEndSelectModeListener(this);
|
||||
recyclerView.setAdapter(adapter);
|
||||
progressBar = root.findViewById(R.id.progLoading);
|
||||
|
||||
speedDialView = root.findViewById(R.id.fabSD);
|
||||
speedDialView.inflate(R.menu.episodes_apply_action_speeddial);
|
||||
speedDialView.removeActionItemById(R.id.download_batch);
|
||||
speedDialView.removeActionItemById(R.id.mark_read_batch);
|
||||
speedDialView.removeActionItemById(R.id.mark_unread_batch);
|
||||
speedDialView.removeActionItemById(R.id.remove_from_queue_batch);
|
||||
speedDialView.setOnChangeListener(new SpeedDialView.OnChangeListener() {
|
||||
@Override
|
||||
public boolean onMainActionSelected() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onToggleChanged(boolean open) {
|
||||
if (open && adapter.getSelectedCount() == 0) {
|
||||
((MainActivity) getActivity()).showSnackbarAbovePlayer(R.string.no_items_selected,
|
||||
Snackbar.LENGTH_SHORT);
|
||||
speedDialView.close();
|
||||
}
|
||||
}
|
||||
});
|
||||
speedDialView.setOnActionSelectedListener(actionItem -> {
|
||||
new EpisodeMultiSelectActionHandler(((MainActivity) getActivity()), adapter.getSelectedItems())
|
||||
.handleAction(actionItem.getId());
|
||||
onEndSelectMode();
|
||||
adapter.endSelectMode();
|
||||
return true;
|
||||
});
|
||||
|
||||
addEmptyView();
|
||||
EventBus.getDefault().register(this);
|
||||
return root;
|
||||
@ -105,17 +140,12 @@ public class CompletedDownloadsFragment extends Fragment {
|
||||
@Override
|
||||
public void onPrepareOptionsMenu(@NonNull Menu menu) {
|
||||
menu.findItem(R.id.clear_logs_item).setVisible(false);
|
||||
menu.findItem(R.id.episode_actions).setVisible(items.size() > 0);
|
||||
isUpdatingFeeds = MenuItemUtils.updateRefreshMenuItem(menu, R.id.refresh_item, updateRefreshMenuItemChecker);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
if (item.getItemId() == R.id.episode_actions) {
|
||||
((MainActivity) requireActivity())
|
||||
.loadChildFragment(EpisodesApplyActionFragment.newInstance(items, ACTION_DELETE | ACTION_ADD_TO_QUEUE));
|
||||
return true;
|
||||
} else if (item.getItemId() == R.id.refresh_item) {
|
||||
if (item.getItemId() == R.id.refresh_item) {
|
||||
AutoUpdateManager.runImmediate(requireContext());
|
||||
return true;
|
||||
}
|
||||
@ -140,6 +170,13 @@ public class CompletedDownloadsFragment extends Fragment {
|
||||
Log.i(TAG, "Selected item at current position was null, ignoring selection");
|
||||
return super.onContextItemSelected(item);
|
||||
}
|
||||
if (item.getItemId() == R.id.multi_select) {
|
||||
speedDialView.setVisibility(View.VISIBLE);
|
||||
}
|
||||
if (adapter.onContextItemSelected(item)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return FeedItemMenuHandler.onMenuItemClicked(this, item.getItemId(), selectedItem);
|
||||
}
|
||||
|
||||
@ -151,7 +188,6 @@ public class CompletedDownloadsFragment extends Fragment {
|
||||
emptyView.attachToRecyclerView(recyclerView);
|
||||
}
|
||||
|
||||
|
||||
@Subscribe(threadMode = ThreadMode.MAIN)
|
||||
public void onEventMainThread(FeedItemEvent event) {
|
||||
Log.d(TAG, "onEventMainThread() called with: " + "event = [" + event + "]");
|
||||
@ -221,6 +257,12 @@ public class CompletedDownloadsFragment extends Fragment {
|
||||
}, error -> Log.e(TAG, Log.getStackTraceString(error)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onEndSelectMode() {
|
||||
speedDialView.close();
|
||||
speedDialView.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
private static class CompletedDownloadsListAdapter extends EpisodeItemListAdapter {
|
||||
|
||||
public CompletedDownloadsListAdapter(MainActivity mainActivity) {
|
||||
@ -232,5 +274,13 @@ public class CompletedDownloadsFragment extends Fragment {
|
||||
DeleteActionButton actionButton = new DeleteActionButton(getItem(pos));
|
||||
actionButton.configure(holder.secondaryActionButton, holder.secondaryActionIcon, getActivity());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
|
||||
super.onCreateContextMenu(menu, v, menuInfo);
|
||||
if (!inActionMode()) {
|
||||
menu.findItem(R.id.multi_select).setVisible(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -164,7 +164,6 @@ public class DownloadLogFragment extends ListFragment {
|
||||
|
||||
@Override
|
||||
public void onPrepareOptionsMenu(@NonNull Menu menu) {
|
||||
menu.findItem(R.id.episode_actions).setVisible(false);
|
||||
menu.findItem(R.id.clear_logs_item).setVisible(!downloadLog.isEmpty());
|
||||
isUpdatingFeeds = MenuItemUtils.updateRefreshMenuItem(menu, R.id.refresh_item, updateRefreshMenuItemChecker);
|
||||
}
|
||||
|
@ -24,8 +24,11 @@ import androidx.recyclerview.widget.SimpleItemAnimator;
|
||||
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
|
||||
|
||||
import com.google.android.material.snackbar.Snackbar;
|
||||
import com.leinardi.android.speeddial.SpeedDialView;
|
||||
|
||||
import de.danoeh.antennapod.R;
|
||||
import de.danoeh.antennapod.activity.MainActivity;
|
||||
import de.danoeh.antennapod.adapter.EpisodeItemListAdapter;
|
||||
import de.danoeh.antennapod.adapter.QueueRecyclerAdapter;
|
||||
import de.danoeh.antennapod.core.dialog.ConfirmationDialog;
|
||||
import de.danoeh.antennapod.core.event.DownloadEvent;
|
||||
@ -35,6 +38,7 @@ import de.danoeh.antennapod.core.event.PlaybackPositionEvent;
|
||||
import de.danoeh.antennapod.core.event.PlayerStatusEvent;
|
||||
import de.danoeh.antennapod.core.event.QueueEvent;
|
||||
import de.danoeh.antennapod.core.event.UnreadItemsUpdateEvent;
|
||||
import de.danoeh.antennapod.fragment.actions.EpisodeMultiSelectActionHandler;
|
||||
import de.danoeh.antennapod.model.feed.FeedItem;
|
||||
import de.danoeh.antennapod.core.feed.util.PlaybackSpeedUtils;
|
||||
import de.danoeh.antennapod.core.preferences.UserPreferences;
|
||||
@ -46,7 +50,6 @@ import de.danoeh.antennapod.core.util.Converter;
|
||||
import de.danoeh.antennapod.core.util.FeedItemUtil;
|
||||
import de.danoeh.antennapod.model.feed.SortOrder;
|
||||
import de.danoeh.antennapod.core.util.download.AutoUpdateManager;
|
||||
import de.danoeh.antennapod.dialog.EpisodesApplyActionFragment;
|
||||
import de.danoeh.antennapod.menuhandler.FeedItemMenuHandler;
|
||||
import de.danoeh.antennapod.menuhandler.MenuItemUtils;
|
||||
import de.danoeh.antennapod.view.EmptyViewHandler;
|
||||
@ -63,14 +66,11 @@ import org.greenrobot.eventbus.ThreadMode;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
||||
import static de.danoeh.antennapod.dialog.EpisodesApplyActionFragment.ACTION_DELETE;
|
||||
import static de.danoeh.antennapod.dialog.EpisodesApplyActionFragment.ACTION_DOWNLOAD;
|
||||
import static de.danoeh.antennapod.dialog.EpisodesApplyActionFragment.ACTION_REMOVE_FROM_QUEUE;
|
||||
|
||||
/**
|
||||
* Shows all items in the queue.
|
||||
*/
|
||||
public class QueueFragment extends Fragment implements Toolbar.OnMenuItemClickListener {
|
||||
public class QueueFragment extends Fragment implements Toolbar.OnMenuItemClickListener,
|
||||
EpisodeItemListAdapter.OnEndSelectModeListener {
|
||||
public static final String TAG = "QueueFragment";
|
||||
private static final String KEY_UP_ARROW = "up_arrow";
|
||||
|
||||
@ -93,6 +93,8 @@ public class QueueFragment extends Fragment implements Toolbar.OnMenuItemClickLi
|
||||
private ItemTouchHelper itemTouchHelper;
|
||||
private SharedPreferences prefs;
|
||||
|
||||
private SpeedDialView speedDialView;
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
@ -277,11 +279,6 @@ public class QueueFragment extends Fragment implements Toolbar.OnMenuItemClickLi
|
||||
};
|
||||
conDialog.createNewDialog().show();
|
||||
return true;
|
||||
case R.id.episode_actions:
|
||||
((MainActivity) requireActivity()).loadChildFragment(
|
||||
EpisodesApplyActionFragment.newInstance(queue,
|
||||
ACTION_DELETE | ACTION_REMOVE_FROM_QUEUE | ACTION_DOWNLOAD));
|
||||
return true;
|
||||
case R.id.queue_sort_episode_title_asc:
|
||||
setSortOrder(SortOrder.EPISODE_TITLE_A_Z);
|
||||
return true;
|
||||
@ -402,6 +399,15 @@ public class QueueFragment extends Fragment implements Toolbar.OnMenuItemClickLi
|
||||
Log.i(TAG, "Selected item no longer exist, ignoring selection");
|
||||
return super.onContextItemSelected(item);
|
||||
}
|
||||
if (item.getItemId() == R.id.multi_select) {
|
||||
speedDialView.setVisibility(View.VISIBLE);
|
||||
refreshToolbarState();
|
||||
infoBar.setVisibility(View.GONE);
|
||||
// Do not return: Let adapter handle its actions, too.
|
||||
}
|
||||
if (recyclerAdapter.onContextItemSelected(item)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
switch(item.getItemId()) {
|
||||
case R.id.move_to_top_item:
|
||||
@ -419,7 +425,6 @@ public class QueueFragment extends Fragment implements Toolbar.OnMenuItemClickLi
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
|
||||
super.onCreateView(inflater, container, savedInstanceState);
|
||||
@ -538,6 +543,33 @@ public class QueueFragment extends Fragment implements Toolbar.OnMenuItemClickLi
|
||||
progLoading = root.findViewById(R.id.progLoading);
|
||||
progLoading.setVisibility(View.VISIBLE);
|
||||
|
||||
speedDialView = root.findViewById(R.id.fabSD);
|
||||
speedDialView.inflate(R.menu.episodes_apply_action_speeddial);
|
||||
speedDialView.removeActionItemById(R.id.mark_read_batch);
|
||||
speedDialView.removeActionItemById(R.id.mark_unread_batch);
|
||||
speedDialView.removeActionItemById(R.id.add_to_queue_batch);
|
||||
speedDialView.setOnChangeListener(new SpeedDialView.OnChangeListener() {
|
||||
@Override
|
||||
public boolean onMainActionSelected() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onToggleChanged(boolean open) {
|
||||
if (open && recyclerAdapter.getSelectedCount() == 0) {
|
||||
((MainActivity) getActivity()).showSnackbarAbovePlayer(R.string.no_items_selected,
|
||||
Snackbar.LENGTH_SHORT);
|
||||
speedDialView.close();
|
||||
}
|
||||
}
|
||||
});
|
||||
speedDialView.setOnActionSelectedListener(actionItem -> {
|
||||
new EpisodeMultiSelectActionHandler(((MainActivity) getActivity()), recyclerAdapter.getSelectedItems())
|
||||
.handleAction(actionItem.getId());
|
||||
onEndSelectMode();
|
||||
recyclerAdapter.endSelectMode();
|
||||
return true;
|
||||
});
|
||||
return root;
|
||||
}
|
||||
|
||||
@ -552,6 +584,7 @@ public class QueueFragment extends Fragment implements Toolbar.OnMenuItemClickLi
|
||||
if (recyclerAdapter == null) {
|
||||
MainActivity activity = (MainActivity) getActivity();
|
||||
recyclerAdapter = new QueueRecyclerAdapter(activity, itemTouchHelper);
|
||||
recyclerAdapter.setOnEndSelectModeListener(this);
|
||||
recyclerView.setAdapter(recyclerAdapter);
|
||||
emptyView.updateAdapter(recyclerAdapter);
|
||||
}
|
||||
@ -615,4 +648,11 @@ public class QueueFragment extends Fragment implements Toolbar.OnMenuItemClickLi
|
||||
}
|
||||
}, error -> Log.e(TAG, Log.getStackTraceString(error)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onEndSelectMode() {
|
||||
speedDialView.close();
|
||||
speedDialView.setVisibility(View.GONE);
|
||||
infoBar.setVisibility(View.VISIBLE);
|
||||
}
|
||||
}
|
||||
|
@ -1,59 +0,0 @@
|
||||
<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">
|
||||
|
||||
<androidx.appcompat.widget.Toolbar
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:minHeight="?attr/actionBarSize"
|
||||
android:theme="?attr/actionBarTheme"
|
||||
android:layout_alignParentTop="true"
|
||||
app:navigationIcon="?homeAsUpIndicator"
|
||||
android:id="@+id/toolbar"/>
|
||||
|
||||
<ListView
|
||||
android:id="@android:id/list"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_below="@id/toolbar"
|
||||
android:layout_marginTop="0dp" />
|
||||
|
||||
<com.leinardi.android.speeddial.SpeedDialOverlayLayout
|
||||
android:id="@+id/fabSDOverlay"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:importantForAccessibility="no"
|
||||
android:layout_below="@id/toolbar" />
|
||||
<!-- 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_open_elevation"
|
||||
tools:ignore="UnusedAttribute" >
|
||||
|
||||
<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"
|
||||
android:accessibilityTraversalBefore="@android:id/list"
|
||||
android:contentDescription="@string/apply_action" />
|
||||
</ScrollView>
|
||||
|
||||
</RelativeLayout>
|
@ -21,6 +21,9 @@
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="bottom|right"
|
||||
android:layout_alignParentBottom="true"
|
||||
android:layout_alignParentEnd="true"
|
||||
android:layout_alignParentRight="true"
|
||||
android:elevation="@dimen/sd_open_elevation">
|
||||
|
||||
<com.leinardi.android.speeddial.SpeedDialView
|
||||
|
@ -1,42 +1,44 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent" xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools">
|
||||
<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">
|
||||
|
||||
<androidx.appcompat.widget.Toolbar
|
||||
android:id="@+id/toolbar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:minHeight="?attr/actionBarSize"
|
||||
android:theme="?attr/actionBarTheme"
|
||||
android:layout_alignParentTop="true"
|
||||
app:title="@string/queue_label"
|
||||
android:id="@+id/toolbar"/>
|
||||
app:title="@string/queue_label" />
|
||||
|
||||
<TextView
|
||||
android:layout_below="@id/toolbar"
|
||||
android:id="@+id/info_bar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_below="@id/toolbar"
|
||||
android:textSize="12sp"
|
||||
android:layout_marginTop="-8dp"
|
||||
android:layout_marginLeft="72dp"
|
||||
android:layout_marginStart="72dp"
|
||||
android:layout_marginBottom="4dp"
|
||||
tools:text="12 Episodes - Time remaining: 12 hours"/>
|
||||
tools:text="12 Episodes - Time remaining: 12 hours" />
|
||||
|
||||
<View
|
||||
android:id="@+id/divider"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="1dp"
|
||||
android:layout_below="@id/info_bar"
|
||||
android:background="?android:attr/listDivider"/>
|
||||
android:background="?android:attr/listDivider" />
|
||||
|
||||
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
|
||||
android:id="@+id/swipeRefresh"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_below="@id/divider">
|
||||
android:id="@+id/swipeRefresh"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_below="@id/divider">
|
||||
|
||||
<de.danoeh.antennapod.view.EpisodeItemListRecyclerView
|
||||
android:id="@+id/recyclerView"
|
||||
@ -54,4 +56,7 @@
|
||||
android:indeterminateOnly="true"
|
||||
android:visibility="gone" />
|
||||
|
||||
<include
|
||||
layout="@layout/multi_select_speed_dial" />
|
||||
|
||||
</RelativeLayout>
|
||||
|
@ -1,29 +1,33 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
<RelativeLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<androidx.appcompat.widget.Toolbar
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:minHeight="?attr/actionBarSize"
|
||||
android:theme="?attr/actionBarTheme"
|
||||
android:layout_alignParentTop="true"
|
||||
android:id="@+id/toolbar"/>
|
||||
android:id="@+id/toolbar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:minHeight="?attr/actionBarSize"
|
||||
android:theme="?attr/actionBarTheme"
|
||||
android:layout_alignParentTop="true" />
|
||||
|
||||
<de.danoeh.antennapod.view.EpisodeItemListRecyclerView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:paddingHorizontal="@dimen/additional_horizontal_spacing"
|
||||
android:layout_below="@id/toolbar"
|
||||
android:id="@+id/recyclerView"/>
|
||||
android:id="@+id/recyclerView"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:paddingHorizontal="@dimen/additional_horizontal_spacing"
|
||||
android:layout_below="@id/toolbar" />
|
||||
|
||||
<ProgressBar
|
||||
android:id="@+id/progLoading"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_centerInParent="true"
|
||||
android:indeterminateOnly="true"
|
||||
android:visibility="gone"/>
|
||||
android:id="@+id/progLoading"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_centerInParent="true"
|
||||
android:indeterminateOnly="true"
|
||||
android:visibility="gone" />
|
||||
|
||||
<include
|
||||
layout="@layout/multi_select_speed_dial" />
|
||||
|
||||
</RelativeLayout>
|
||||
|
@ -1,13 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<menu xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
<item
|
||||
android:id="@+id/episode_actions"
|
||||
android:menuCategory="container"
|
||||
android:title="@string/multi_select"
|
||||
android:icon="@drawable/ic_check_multiple"
|
||||
android:visible="false"
|
||||
app:showAsAction="ifRoom" />
|
||||
<item
|
||||
android:id="@+id/clear_logs_item"
|
||||
android:menuCategory="container"
|
||||
|
@ -1,58 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<menu xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
|
||||
<item
|
||||
android:id="@+id/sort"
|
||||
android:icon="@drawable/ic_sort"
|
||||
android:title="@string/sort"
|
||||
app:showAsAction="always">
|
||||
<menu>
|
||||
<item android:id="@+id/sort_title_a_z"
|
||||
android:title="@string/sort_title_a_z"/>
|
||||
<item android:id="@+id/sort_title_z_a"
|
||||
android:title="@string/sort_title_z_a"/>
|
||||
<item android:id="@+id/sort_date_new_old"
|
||||
android:title="@string/sort_date_new_old"/>
|
||||
<item android:id="@+id/sort_date_old_new"
|
||||
android:title="@string/sort_date_old_new"/>
|
||||
<item android:id="@+id/sort_duration_short_long"
|
||||
android:title="@string/sort_duration_short_long"/>
|
||||
<item android:id="@+id/sort_duration_long_short"
|
||||
android:title="@string/sort_duration_long_short"/>
|
||||
</menu>
|
||||
</item>
|
||||
|
||||
<item
|
||||
android:id="@+id/select_options"
|
||||
android:icon="@drawable/ic_filter"
|
||||
android:title="@string/filter"
|
||||
app:showAsAction="always">
|
||||
|
||||
<menu>
|
||||
<item android:id="@+id/check_all"
|
||||
android:title="@string/all_label"/>
|
||||
<item android:id="@+id/check_none"
|
||||
android:title="@string/select_none_label"/>
|
||||
<item android:id="@+id/check_played"
|
||||
android:title="@string/played_label"/>
|
||||
<item android:id="@+id/check_unplayed"
|
||||
android:title="@string/unplayed_label"/>
|
||||
<item android:id="@+id/check_downloaded"
|
||||
android:title="@string/downloaded_label"/>
|
||||
<item android:id="@+id/check_not_downloaded"
|
||||
android:title="@string/not_downloaded_label"/>
|
||||
<item android:id="@+id/check_queued"
|
||||
android:title="@string/queued_label"/>
|
||||
<item android:id="@+id/check_not_queued"
|
||||
android:title="@string/not_queued_label"/>
|
||||
<item android:id="@+id/check_has_media"
|
||||
android:title="@string/has_media"/>
|
||||
</menu>
|
||||
</item>
|
||||
|
||||
<item
|
||||
android:id="@+id/select_toggle"
|
||||
android:title="@string/select_all_label"
|
||||
app:showAsAction="always"/>
|
||||
</menu>
|
@ -1,11 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<menu xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item
|
||||
android:id="@+id/multi_select"
|
||||
android:menuCategory="container"
|
||||
android:title="@string/multi_select"
|
||||
android:visible="false"/>
|
||||
|
||||
<item
|
||||
android:id="@id/skip_episode_item"
|
||||
android:menuCategory="container"
|
||||
@ -75,4 +69,10 @@
|
||||
android:id="@+id/share_item"
|
||||
android:menuCategory="container"
|
||||
android:title="@string/share_label" />
|
||||
|
||||
<item
|
||||
android:id="@+id/multi_select"
|
||||
android:menuCategory="container"
|
||||
android:title="@string/multi_select"
|
||||
android:visible="false" />
|
||||
</menu>
|
@ -115,10 +115,4 @@
|
||||
android:title="@string/clear_queue_label"
|
||||
custom:showAsAction="collapseActionView"
|
||||
android:icon="@drawable/ic_check"/>
|
||||
|
||||
<item
|
||||
android:id="@+id/episode_actions"
|
||||
custom:showAsAction="collapseActionView"
|
||||
android:title="@string/multi_select" />
|
||||
|
||||
</menu>
|
||||
|
@ -1,5 +0,0 @@
|
||||
<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="?attr/action_icon_color" android:pathData="M20,16V10H22V16A2,2 0 0,1 20,18H8C6.89,18 6,17.1 6,16V4C6,2.89 6.89,2 8,2H16V4H8V16H20M10.91,7.08L14,10.17L20.59,3.58L22,5L14,13L9.5,8.5L10.91,7.08M16,20V22H4A2,2 0 0,1 2,20V7H4V20H16Z"/>
|
||||
</vector>
|
@ -314,11 +314,6 @@
|
||||
<item>continue</item>
|
||||
</string-array>
|
||||
|
||||
<string-array name="batch_long_press_options">
|
||||
<item>@string/select_all_above</item>
|
||||
<item>@string/select_all_below</item>
|
||||
</string-array>
|
||||
|
||||
<string-array name="back_button_behavior_options">
|
||||
<item>@string/back_button_default</item>
|
||||
<item>@string/back_button_go_to_page</item>
|
||||
|
@ -727,24 +727,6 @@
|
||||
<string name="unable_to_start_system_file_manager">Unable to start system file manager</string>
|
||||
|
||||
<string name="filter">Filter</string>
|
||||
|
||||
<!-- Episodes apply actions -->
|
||||
<string name="all_label">All</string>
|
||||
<string name="selected_all_label">Selected all Episodes</string>
|
||||
<string name="select_none_label">None</string>
|
||||
<string name="deselected_all_label">Deselected all Episodes</string>
|
||||
<string name="played_label">Played</string>
|
||||
<string name="selected_played_label">Selected played Episodes</string>
|
||||
<string name="unplayed_label">Unplayed</string>
|
||||
<string name="selected_unplayed_label">Selected unplayed Episodes</string>
|
||||
<string name="downloaded_label">Downloaded</string>
|
||||
<string name="selected_downloaded_label">Selected downloaded Episodes</string>
|
||||
<string name="not_downloaded_label">Not downloaded</string>
|
||||
<string name="selected_not_downloaded_label">Selected not downloaded Episodes</string>
|
||||
<string name="selected_queued_label">Selected queued Episodes</string>
|
||||
<string name="selected_not_queued_label">Selected not queued Episodes</string>
|
||||
<string name="selected_has_media_label">Selected episodes with media</string>
|
||||
|
||||
<string name="hide_is_favorite_label">Is favorite</string>
|
||||
<string name="not_favorite">Not favorite</string>
|
||||
<string name="hide_downloaded_episodes_label">Downloaded</string>
|
||||
|
Loading…
x
Reference in New Issue
Block a user