New sort dialog (#6789)
This commit is contained in:
parent
c1712fe2f5
commit
2e76dc8d0c
@ -1,68 +0,0 @@
|
||||
package de.danoeh.antennapod.dialog;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
|
||||
|
||||
import de.danoeh.antennapod.R;
|
||||
import de.danoeh.antennapod.model.feed.SortOrder;
|
||||
|
||||
public abstract class IntraFeedSortDialog {
|
||||
|
||||
@Nullable
|
||||
protected SortOrder currentSortOrder;
|
||||
@NonNull
|
||||
protected Context context;
|
||||
|
||||
private final String[] sortItems;
|
||||
private final SortOrder[] sortValues;
|
||||
|
||||
public IntraFeedSortDialog(@NonNull Context context, @Nullable SortOrder sortOrder, @NonNull boolean isLocalFeed) {
|
||||
this.context = context;
|
||||
this.currentSortOrder = sortOrder;
|
||||
|
||||
if (isLocalFeed) {
|
||||
sortItems = context.getResources().getStringArray(R.array.local_feed_episodes_sort_options);
|
||||
final String[] localSortStringValues =
|
||||
context.getResources().getStringArray(R.array.local_feed_episodes_sort_values);
|
||||
sortValues = SortOrder.valuesOf(localSortStringValues);
|
||||
} else {
|
||||
sortItems = context.getResources().getStringArray(R.array.feed_episodes_sort_options);
|
||||
final String[] commonSortStringValues =
|
||||
context.getResources().getStringArray(R.array.feed_episodes_sort_values);
|
||||
sortValues = SortOrder.valuesOf(commonSortStringValues);
|
||||
}
|
||||
}
|
||||
|
||||
public void openDialog() {
|
||||
int idxCurrentSort = getCurrentSortOrderIndex();
|
||||
|
||||
MaterialAlertDialogBuilder builder =
|
||||
new MaterialAlertDialogBuilder(context)
|
||||
.setTitle(R.string.sort)
|
||||
.setSingleChoiceItems(sortItems, idxCurrentSort, (dialog, idxNewSort) -> {
|
||||
updateSort(sortValues[idxNewSort]);
|
||||
dialog.dismiss();
|
||||
})
|
||||
.setNegativeButton(R.string.cancel_label, null);
|
||||
builder.create().show();
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves index of currentSortOrder index in values array.
|
||||
* @return if currentSortOrder is found in array - returns index of that element,
|
||||
* otherwise returns 0, the default sort option;
|
||||
*/
|
||||
private int getCurrentSortOrderIndex() {
|
||||
for (int i = 0; i < sortValues.length; i++) {
|
||||
if (currentSortOrder == sortValues[i]) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
protected abstract void updateSort(@NonNull SortOrder sortOrder);
|
||||
}
|
@ -0,0 +1,102 @@
|
||||
package de.danoeh.antennapod.dialog;
|
||||
|
||||
import android.app.Dialog;
|
||||
import android.os.Bundle;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.FrameLayout;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import com.google.android.material.bottomsheet.BottomSheetBehavior;
|
||||
import com.google.android.material.bottomsheet.BottomSheetDialog;
|
||||
import com.google.android.material.bottomsheet.BottomSheetDialogFragment;
|
||||
import de.danoeh.antennapod.R;
|
||||
import de.danoeh.antennapod.databinding.SortDialogBinding;
|
||||
import de.danoeh.antennapod.databinding.SortDialogItemActiveBinding;
|
||||
import de.danoeh.antennapod.databinding.SortDialogItemBinding;
|
||||
import de.danoeh.antennapod.model.feed.SortOrder;
|
||||
|
||||
public class ItemSortDialog extends BottomSheetDialogFragment {
|
||||
protected SortOrder sortOrder;
|
||||
protected SortDialogBinding viewBinding;
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
|
||||
@Nullable Bundle savedInstanceState) {
|
||||
viewBinding = SortDialogBinding.inflate(inflater);
|
||||
populateList();
|
||||
return viewBinding.getRoot();
|
||||
}
|
||||
|
||||
private void populateList() {
|
||||
viewBinding.gridLayout.removeAllViews();
|
||||
onAddItem(R.string.episode_title, SortOrder.EPISODE_TITLE_A_Z, SortOrder.EPISODE_TITLE_Z_A, true);
|
||||
onAddItem(R.string.feed_title, SortOrder.FEED_TITLE_A_Z, SortOrder.FEED_TITLE_Z_A, true);
|
||||
onAddItem(R.string.duration, SortOrder.DURATION_SHORT_LONG, SortOrder.DURATION_LONG_SHORT, true);
|
||||
onAddItem(R.string.date, SortOrder.DATE_OLD_NEW, SortOrder.DATE_NEW_OLD, false);
|
||||
onAddItem(R.string.size, SortOrder.SIZE_SMALL_LARGE, SortOrder.SIZE_LARGE_SMALL, false);
|
||||
onAddItem(R.string.filename, SortOrder.EPISODE_FILENAME_A_Z, SortOrder.EPISODE_FILENAME_Z_A, true);
|
||||
onAddItem(R.string.random, SortOrder.RANDOM, SortOrder.RANDOM, true);
|
||||
onAddItem(R.string.smart_shuffle, SortOrder.SMART_SHUFFLE_OLD_NEW, SortOrder.SMART_SHUFFLE_NEW_OLD, false);
|
||||
}
|
||||
|
||||
protected void onAddItem(int title, SortOrder ascending, SortOrder descending, boolean ascendingIsDefault) {
|
||||
if (sortOrder == ascending || sortOrder == descending) {
|
||||
SortDialogItemActiveBinding item = SortDialogItemActiveBinding.inflate(
|
||||
getLayoutInflater(), viewBinding.gridLayout, false);
|
||||
SortOrder other;
|
||||
if (ascending == descending) {
|
||||
item.button.setText(title);
|
||||
other = ascending;
|
||||
} else if (sortOrder == ascending) {
|
||||
item.button.setText(getString(title) + "\u00A0▲");
|
||||
other = descending;
|
||||
} else {
|
||||
item.button.setText(getString(title) + "\u00A0▼");
|
||||
other = ascending;
|
||||
}
|
||||
item.button.setOnClickListener(v -> {
|
||||
sortOrder = other;
|
||||
populateList();
|
||||
onSelectionChanged();
|
||||
});
|
||||
viewBinding.gridLayout.addView(item.getRoot());
|
||||
} else {
|
||||
SortDialogItemBinding item = SortDialogItemBinding.inflate(
|
||||
getLayoutInflater(), viewBinding.gridLayout, false);
|
||||
item.button.setText(title);
|
||||
item.button.setOnClickListener(v -> {
|
||||
sortOrder = ascendingIsDefault ? ascending : descending;
|
||||
populateList();
|
||||
onSelectionChanged();
|
||||
});
|
||||
viewBinding.gridLayout.addView(item.getRoot());
|
||||
}
|
||||
}
|
||||
|
||||
protected void onSelectionChanged() {
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) {
|
||||
Dialog dialog = super.onCreateDialog(savedInstanceState);
|
||||
dialog.setOnShowListener(dialogInterface -> {
|
||||
BottomSheetDialog bottomSheetDialog = (BottomSheetDialog) dialogInterface;
|
||||
setupFullHeight(bottomSheetDialog);
|
||||
});
|
||||
return dialog;
|
||||
}
|
||||
|
||||
private void setupFullHeight(BottomSheetDialog bottomSheetDialog) {
|
||||
FrameLayout bottomSheet = bottomSheetDialog.findViewById(R.id.design_bottom_sheet);
|
||||
if (bottomSheet != null) {
|
||||
BottomSheetBehavior<FrameLayout> behavior = BottomSheetBehavior.from(bottomSheet);
|
||||
ViewGroup.LayoutParams layoutParams = bottomSheet.getLayoutParams();
|
||||
bottomSheet.setLayoutParams(layoutParams);
|
||||
behavior.setState(BottomSheetBehavior.STATE_EXPANDED);
|
||||
}
|
||||
}
|
||||
}
|
@ -6,15 +6,18 @@ import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import de.danoeh.antennapod.R;
|
||||
import de.danoeh.antennapod.core.storage.DBReader;
|
||||
import de.danoeh.antennapod.dialog.AllEpisodesFilterDialog;
|
||||
import de.danoeh.antennapod.dialog.ItemSortDialog;
|
||||
import de.danoeh.antennapod.event.FeedListUpdateEvent;
|
||||
import de.danoeh.antennapod.model.feed.FeedItem;
|
||||
import de.danoeh.antennapod.model.feed.FeedItemFilter;
|
||||
import de.danoeh.antennapod.model.feed.SortOrder;
|
||||
import de.danoeh.antennapod.storage.preferences.UserPreferences;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.greenrobot.eventbus.EventBus;
|
||||
import org.greenrobot.eventbus.Subscribe;
|
||||
|
||||
import java.util.ArrayList;
|
||||
@ -33,7 +36,6 @@ public class AllEpisodesFragment extends EpisodesListFragment {
|
||||
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
|
||||
final View root = super.onCreateView(inflater, container, savedInstanceState);
|
||||
toolbar.inflateMenu(R.menu.episodes);
|
||||
inflateSortMenu();
|
||||
toolbar.setTitle(R.string.episodes_label);
|
||||
updateToolbar();
|
||||
updateFilterUi();
|
||||
@ -42,18 +44,6 @@ public class AllEpisodesFragment extends EpisodesListFragment {
|
||||
return root;
|
||||
}
|
||||
|
||||
private void inflateSortMenu() {
|
||||
MenuItem sortItem = toolbar.getMenu().findItem(R.id.episodes_sort);
|
||||
getActivity().getMenuInflater().inflate(R.menu.sort_menu, sortItem.getSubMenu());
|
||||
|
||||
// Remove the sorting options that are not needed in this fragment
|
||||
toolbar.getMenu().findItem(R.id.sort_episode_title).setVisible(false);
|
||||
toolbar.getMenu().findItem(R.id.sort_feed_title).setVisible(false);
|
||||
toolbar.getMenu().findItem(R.id.sort_random).setVisible(false);
|
||||
toolbar.getMenu().findItem(R.id.sort_smart_shuffle).setVisible(false);
|
||||
toolbar.getMenu().findItem(R.id.keep_sorted).setVisible(false);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
protected List<FeedItem> loadData() {
|
||||
@ -105,21 +95,13 @@ public class AllEpisodesFragment extends EpisodesListFragment {
|
||||
}
|
||||
onFilterChanged(new AllEpisodesFilterDialog.AllEpisodesFilterChangedEvent(new HashSet<>(filter)));
|
||||
return true;
|
||||
} else {
|
||||
SortOrder sortOrder = MenuItemToSortOrderConverter.convert(item);
|
||||
if (sortOrder != null) {
|
||||
saveSortOrderAndRefresh(sortOrder);
|
||||
return true;
|
||||
}
|
||||
} else if (item.getItemId() == R.id.episodes_sort) {
|
||||
new AllEpisodesSortDialog().show(getChildFragmentManager().beginTransaction(), "SortDialog");
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private void saveSortOrderAndRefresh(SortOrder type) {
|
||||
UserPreferences.setAllEpisodesSortOrder(type);
|
||||
loadItems();
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onFilterChanged(AllEpisodesFilterDialog.AllEpisodesFilterChangedEvent event) {
|
||||
UserPreferences.setPrefFilterAllEpisodes(StringUtils.join(event.filterValues, ","));
|
||||
@ -140,4 +122,26 @@ public class AllEpisodesFragment extends EpisodesListFragment {
|
||||
toolbar.getMenu().findItem(R.id.action_favorites).setIcon(
|
||||
getFilter().showIsFavorite ? R.drawable.ic_star : R.drawable.ic_star_border);
|
||||
}
|
||||
|
||||
public static class AllEpisodesSortDialog extends ItemSortDialog {
|
||||
@Override
|
||||
public void onCreate(@Nullable Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
sortOrder = UserPreferences.getAllEpisodesSortOrder();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onAddItem(int title, SortOrder ascending, SortOrder descending, boolean ascendingIsDefault) {
|
||||
if (ascending == SortOrder.DATE_OLD_NEW || ascending == SortOrder.DURATION_SHORT_LONG) {
|
||||
super.onAddItem(title, ascending, descending, ascendingIsDefault);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onSelectionChanged() {
|
||||
super.onSelectionChanged();
|
||||
UserPreferences.setAllEpisodesSortOrder(sortOrder);
|
||||
EventBus.getDefault().post(new FeedListUpdateEvent(0));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -4,16 +4,14 @@ import android.os.Bundle;
|
||||
import android.util.Log;
|
||||
import android.view.ContextMenu;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuInflater;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ProgressBar;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import com.google.android.material.appbar.MaterialToolbar;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import com.google.android.material.appbar.MaterialToolbar;
|
||||
import com.google.android.material.snackbar.Snackbar;
|
||||
import com.leinardi.android.speeddial.SpeedDialView;
|
||||
import de.danoeh.antennapod.R;
|
||||
@ -25,6 +23,7 @@ import de.danoeh.antennapod.core.menuhandler.MenuItemUtils;
|
||||
import de.danoeh.antennapod.core.storage.DBReader;
|
||||
import de.danoeh.antennapod.core.util.FeedItemUtil;
|
||||
import de.danoeh.antennapod.core.util.download.FeedUpdateManager;
|
||||
import de.danoeh.antennapod.dialog.ItemSortDialog;
|
||||
import de.danoeh.antennapod.event.EpisodeDownloadEvent;
|
||||
import de.danoeh.antennapod.event.FeedItemEvent;
|
||||
import de.danoeh.antennapod.event.PlayerStatusEvent;
|
||||
@ -84,8 +83,6 @@ public class CompletedDownloadsFragment extends Fragment
|
||||
toolbar = root.findViewById(R.id.toolbar);
|
||||
toolbar.setTitle(R.string.downloads_label);
|
||||
toolbar.inflateMenu(R.menu.downloads_completed);
|
||||
inflateSortMenu(toolbar);
|
||||
|
||||
toolbar.setOnMenuItemClickListener(this);
|
||||
toolbar.setOnLongClickListener(v -> {
|
||||
recyclerView.scrollToPosition(5);
|
||||
@ -148,20 +145,6 @@ public class CompletedDownloadsFragment extends Fragment
|
||||
return root;
|
||||
}
|
||||
|
||||
private void inflateSortMenu(MaterialToolbar toolbar) {
|
||||
Menu menu = toolbar.getMenu();
|
||||
MenuItem downloadsItem = menu.findItem(R.id.downloads_sort);
|
||||
MenuInflater menuInflater = getActivity().getMenuInflater();
|
||||
menuInflater.inflate(R.menu.sort_menu, downloadsItem.getSubMenu());
|
||||
|
||||
// Remove the sorting options that are not needed in this fragment
|
||||
menu.findItem(R.id.sort_feed_title).setVisible(false);
|
||||
menu.findItem(R.id.sort_random).setVisible(false);
|
||||
menu.findItem(R.id.sort_smart_shuffle).setVisible(false);
|
||||
menu.findItem(R.id.keep_sorted).setVisible(false);
|
||||
menu.findItem(R.id.sort_size).setVisible(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSaveInstanceState(@NonNull Bundle outState) {
|
||||
outState.putBoolean(KEY_UP_ARROW, displayUpArrow);
|
||||
@ -204,21 +187,13 @@ public class CompletedDownloadsFragment extends Fragment
|
||||
} else if (item.getItemId() == R.id.action_search) {
|
||||
((MainActivity) getActivity()).loadChildFragment(SearchFragment.newInstance());
|
||||
return true;
|
||||
} else {
|
||||
SortOrder sortOrder = MenuItemToSortOrderConverter.convert(item);
|
||||
if (sortOrder != null) {
|
||||
setSortOrder(sortOrder);
|
||||
return true;
|
||||
}
|
||||
} else if (item.getItemId() == R.id.downloads_sort) {
|
||||
new DownloadsSortDialog().show(getChildFragmentManager(), "SortDialog");
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private void setSortOrder(SortOrder sortOrder) {
|
||||
UserPreferences.setDownloadsSortedOrder(sortOrder);
|
||||
loadItems();
|
||||
}
|
||||
|
||||
@Subscribe(sticky = true, threadMode = ThreadMode.MAIN)
|
||||
public void onEventMainThread(EpisodeDownloadEvent event) {
|
||||
Set<String> newRunningDownloads = new HashSet<>();
|
||||
@ -391,4 +366,27 @@ public class CompletedDownloadsFragment extends Fragment
|
||||
MenuItemUtils.setOnClickListeners(menu, CompletedDownloadsFragment.this::onContextItemSelected);
|
||||
}
|
||||
}
|
||||
|
||||
public static class DownloadsSortDialog extends ItemSortDialog {
|
||||
@Override
|
||||
public void onCreate(@Nullable Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
sortOrder = UserPreferences.getDownloadsSortedOrder();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onAddItem(int title, SortOrder ascending, SortOrder descending, boolean ascendingIsDefault) {
|
||||
if (ascending == SortOrder.DATE_OLD_NEW || ascending == SortOrder.DURATION_SHORT_LONG
|
||||
|| ascending == SortOrder.EPISODE_TITLE_A_Z || ascending == SortOrder.SIZE_SMALL_LARGE) {
|
||||
super.onAddItem(title, ascending, descending, ascendingIsDefault);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onSelectionChanged() {
|
||||
super.onSelectionChanged();
|
||||
UserPreferences.setDownloadsSortedOrder(sortOrder);
|
||||
EventBus.getDefault().post(DownloadLogEvent.listUpdated());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -22,24 +22,24 @@ import androidx.activity.result.ActivityResultLauncher;
|
||||
import androidx.activity.result.contract.ActivityResultContracts;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
|
||||
import androidx.appcompat.content.res.AppCompatResources;
|
||||
import com.google.android.material.appbar.MaterialToolbar;
|
||||
import androidx.documentfile.provider.DocumentFile;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import com.bumptech.glide.Glide;
|
||||
import com.bumptech.glide.request.RequestOptions;
|
||||
import com.google.android.material.appbar.AppBarLayout;
|
||||
import com.google.android.material.appbar.CollapsingToolbarLayout;
|
||||
import com.google.android.material.appbar.MaterialToolbar;
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
|
||||
import com.google.android.material.snackbar.Snackbar;
|
||||
import de.danoeh.antennapod.R;
|
||||
import de.danoeh.antennapod.activity.MainActivity;
|
||||
import de.danoeh.antennapod.core.storage.DBReader;
|
||||
import de.danoeh.antennapod.core.storage.DBTasks;
|
||||
import de.danoeh.antennapod.core.util.IntentUtils;
|
||||
import de.danoeh.antennapod.core.util.ShareUtils;
|
||||
import de.danoeh.antennapod.core.util.syndication.HtmlToPlainText;
|
||||
import de.danoeh.antennapod.dialog.EditUrlSettingsDialog;
|
||||
import de.danoeh.antennapod.menuhandler.FeedMenuHandler;
|
||||
import de.danoeh.antennapod.model.feed.Feed;
|
||||
import de.danoeh.antennapod.model.feed.FeedFunding;
|
||||
import de.danoeh.antennapod.ui.glide.FastBlurTransformation;
|
||||
@ -289,9 +289,11 @@ public class FeedInfoFragment extends Fragment implements MaterialToolbar.OnMenu
|
||||
R.string.please_wait_for_data, Toast.LENGTH_LONG);
|
||||
return false;
|
||||
}
|
||||
boolean handled = FeedMenuHandler.onOptionsItemClicked(getContext(), item, feed);
|
||||
|
||||
if (item.getItemId() == R.id.reconnect_local_folder) {
|
||||
if (item.getItemId() == R.id.visit_website_item) {
|
||||
IntentUtils.openInBrowser(getContext(), feed.getLink());
|
||||
} else if (item.getItemId() == R.id.share_item) {
|
||||
ShareUtils.shareFeedLink(getContext(), feed);
|
||||
} else if (item.getItemId() == R.id.reconnect_local_folder) {
|
||||
MaterialAlertDialogBuilder alert = new MaterialAlertDialogBuilder(getContext());
|
||||
alert.setMessage(R.string.reconnect_local_folder_warning);
|
||||
alert.setPositiveButton(android.R.string.ok, (dialog, which) -> {
|
||||
@ -303,10 +305,7 @@ public class FeedInfoFragment extends Fragment implements MaterialToolbar.OnMenu
|
||||
});
|
||||
alert.setNegativeButton(android.R.string.cancel, null);
|
||||
alert.show();
|
||||
return true;
|
||||
}
|
||||
|
||||
if (item.getItemId() == R.id.edit_feed_url_item) {
|
||||
} else if (item.getItemId() == R.id.edit_feed_url_item) {
|
||||
new EditUrlSettingsDialog(getActivity(), feed) {
|
||||
@Override
|
||||
protected void setUrl(String url) {
|
||||
@ -315,11 +314,10 @@ public class FeedInfoFragment extends Fragment implements MaterialToolbar.OnMenu
|
||||
txtvUrl.setCompoundDrawablesRelativeWithIntrinsicBounds(0, 0, R.drawable.ic_paperclip, 0);
|
||||
}
|
||||
}.show();
|
||||
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
||||
return handled;
|
||||
return true;
|
||||
}
|
||||
|
||||
private void addLocalFolderResult(final Uri uri) {
|
||||
|
@ -18,11 +18,11 @@ import android.widget.Toast;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.appcompat.content.res.AppCompatResources;
|
||||
import com.google.android.material.appbar.MaterialToolbar;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
import com.bumptech.glide.Glide;
|
||||
import com.bumptech.glide.request.RequestOptions;
|
||||
import com.google.android.material.appbar.MaterialToolbar;
|
||||
import com.google.android.material.snackbar.Snackbar;
|
||||
import com.joanzapata.iconify.Iconify;
|
||||
import com.leinardi.android.speeddial.SpeedDialView;
|
||||
@ -32,14 +32,18 @@ import de.danoeh.antennapod.adapter.EpisodeItemListAdapter;
|
||||
import de.danoeh.antennapod.core.feed.FeedEvent;
|
||||
import de.danoeh.antennapod.core.menuhandler.MenuItemUtils;
|
||||
import de.danoeh.antennapod.core.storage.DBReader;
|
||||
import de.danoeh.antennapod.core.storage.DBWriter;
|
||||
import de.danoeh.antennapod.core.util.FeedItemPermutors;
|
||||
import de.danoeh.antennapod.core.util.FeedItemUtil;
|
||||
import de.danoeh.antennapod.core.util.IntentUtils;
|
||||
import de.danoeh.antennapod.core.util.ShareUtils;
|
||||
import de.danoeh.antennapod.core.util.download.FeedUpdateManager;
|
||||
import de.danoeh.antennapod.core.util.gui.MoreContentListFooterUtil;
|
||||
import de.danoeh.antennapod.databinding.FeedItemListFragmentBinding;
|
||||
import de.danoeh.antennapod.databinding.MultiSelectSpeedDialBinding;
|
||||
import de.danoeh.antennapod.dialog.DownloadLogDetailsDialog;
|
||||
import de.danoeh.antennapod.dialog.FeedItemFilterDialog;
|
||||
import de.danoeh.antennapod.dialog.ItemSortDialog;
|
||||
import de.danoeh.antennapod.dialog.RemoveFeedDialog;
|
||||
import de.danoeh.antennapod.dialog.RenameItemDialog;
|
||||
import de.danoeh.antennapod.event.EpisodeDownloadEvent;
|
||||
@ -54,11 +58,11 @@ import de.danoeh.antennapod.event.playback.PlaybackPositionEvent;
|
||||
import de.danoeh.antennapod.fragment.actions.EpisodeMultiSelectActionHandler;
|
||||
import de.danoeh.antennapod.fragment.swipeactions.SwipeActions;
|
||||
import de.danoeh.antennapod.menuhandler.FeedItemMenuHandler;
|
||||
import de.danoeh.antennapod.menuhandler.FeedMenuHandler;
|
||||
import de.danoeh.antennapod.model.download.DownloadResult;
|
||||
import de.danoeh.antennapod.model.feed.Feed;
|
||||
import de.danoeh.antennapod.model.feed.FeedItem;
|
||||
import de.danoeh.antennapod.model.feed.FeedItemFilter;
|
||||
import de.danoeh.antennapod.model.feed.SortOrder;
|
||||
import de.danoeh.antennapod.storage.preferences.UserPreferences;
|
||||
import de.danoeh.antennapod.ui.glide.FastBlurTransformation;
|
||||
import de.danoeh.antennapod.view.ToolbarIconTintManager;
|
||||
@ -68,6 +72,7 @@ import io.reactivex.Observable;
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers;
|
||||
import io.reactivex.disposables.Disposable;
|
||||
import io.reactivex.schedulers.Schedulers;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.commons.lang3.Validate;
|
||||
import org.greenrobot.eventbus.EventBus;
|
||||
import org.greenrobot.eventbus.Subscribe;
|
||||
@ -75,6 +80,7 @@ import org.greenrobot.eventbus.ThreadMode;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
|
||||
/**
|
||||
* Displays a list of FeedItems.
|
||||
@ -240,8 +246,13 @@ public class FeedItemlistFragment extends Fragment implements AdapterView.OnItem
|
||||
return;
|
||||
}
|
||||
viewBinding.toolbar.getMenu().findItem(R.id.visit_website_item).setVisible(feed.getLink() != null);
|
||||
|
||||
FeedMenuHandler.onPrepareOptionsMenu(viewBinding.toolbar.getMenu(), feed);
|
||||
viewBinding.toolbar.getMenu().findItem(R.id.refresh_complete_item).setVisible(feed.isPaged());
|
||||
if (StringUtils.isBlank(feed.getLink())) {
|
||||
viewBinding.toolbar.getMenu().findItem(R.id.visit_website_item).setVisible(false);
|
||||
}
|
||||
if (feed.isLocalFeed()) {
|
||||
viewBinding.toolbar.getMenu().findItem(R.id.share_item).setVisible(false);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -260,26 +271,39 @@ public class FeedItemlistFragment extends Fragment implements AdapterView.OnItem
|
||||
R.string.please_wait_for_data, Toast.LENGTH_LONG);
|
||||
return true;
|
||||
}
|
||||
boolean feedMenuHandled = FeedMenuHandler.onOptionsItemClicked(getActivity(), item, feed);
|
||||
if (feedMenuHandled) {
|
||||
return true;
|
||||
}
|
||||
final int itemId = item.getItemId();
|
||||
if (itemId == R.id.rename_item) {
|
||||
if (item.getItemId() == R.id.visit_website_item) {
|
||||
IntentUtils.openInBrowser(getContext(), feed.getLink());
|
||||
} else if (item.getItemId() == R.id.share_item) {
|
||||
ShareUtils.shareFeedLink(getContext(), feed);
|
||||
} else if (item.getItemId() == R.id.refresh_item) {
|
||||
FeedUpdateManager.runOnceOrAsk(getContext(), feed);
|
||||
} else if (item.getItemId() == R.id.refresh_complete_item) {
|
||||
new Thread(() -> {
|
||||
feed.setNextPageLink(feed.getDownload_url());
|
||||
feed.setPageNr(0);
|
||||
try {
|
||||
DBWriter.resetPagedFeedPage(feed).get();
|
||||
FeedUpdateManager.runOnce(getContext(), feed);
|
||||
} catch (ExecutionException | InterruptedException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}).start();
|
||||
} else if (item.getItemId() == R.id.sort_items) {
|
||||
SingleFeedSortDialog.newInstance(feed).show(getChildFragmentManager(), "SortDialog");
|
||||
} else if (item.getItemId() == R.id.rename_item) {
|
||||
new RenameItemDialog(getActivity(), feed).show();
|
||||
return true;
|
||||
} else if (itemId == R.id.remove_feed) {
|
||||
} else if (item.getItemId() == R.id.remove_feed) {
|
||||
RemoveFeedDialog.show(getContext(), feed, () -> {
|
||||
((MainActivity) getActivity()).loadFragment(UserPreferences.getDefaultPage(), null);
|
||||
// Make sure fragment is hidden before actually starting to delete
|
||||
getActivity().getSupportFragmentManager().executePendingTransactions();
|
||||
});
|
||||
return true;
|
||||
} else if (itemId == R.id.action_search) {
|
||||
} else if (item.getItemId() == R.id.action_search) {
|
||||
((MainActivity) getActivity()).loadChildFragment(SearchFragment.newInstance(feed.getId(), feed.getTitle()));
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -592,4 +616,45 @@ public class FeedItemlistFragment extends Fragment implements AdapterView.OnItem
|
||||
MenuItemUtils.setOnClickListeners(menu, FeedItemlistFragment.this::onContextItemSelected);
|
||||
}
|
||||
}
|
||||
|
||||
public static class SingleFeedSortDialog extends ItemSortDialog {
|
||||
private static final String ARG_FEED_ID = "feedId";
|
||||
private static final String ARG_FEED_IS_LOCAL = "isLocal";
|
||||
private static final String ARG_SORT_ORDER = "sortOrder";
|
||||
|
||||
private static SingleFeedSortDialog newInstance(Feed feed) {
|
||||
Bundle bundle = new Bundle();
|
||||
bundle.putLong(ARG_FEED_ID, feed.getId());
|
||||
bundle.putBoolean(ARG_FEED_IS_LOCAL, feed.isLocalFeed());
|
||||
if (feed.getSortOrder() == null) {
|
||||
bundle.putString(ARG_SORT_ORDER, String.valueOf(SortOrder.DATE_NEW_OLD.code));
|
||||
} else {
|
||||
bundle.putString(ARG_SORT_ORDER, String.valueOf(feed.getSortOrder().code));
|
||||
}
|
||||
SingleFeedSortDialog dialog = new SingleFeedSortDialog();
|
||||
dialog.setArguments(bundle);
|
||||
return dialog;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate(@Nullable Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
sortOrder = SortOrder.fromCodeString(getArguments().getString(ARG_SORT_ORDER));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onAddItem(int title, SortOrder ascending, SortOrder descending, boolean ascendingIsDefault) {
|
||||
if (ascending == SortOrder.DATE_OLD_NEW || ascending == SortOrder.DURATION_SHORT_LONG
|
||||
|| ascending == SortOrder.EPISODE_TITLE_A_Z
|
||||
|| (getArguments().getBoolean(ARG_FEED_IS_LOCAL) && ascending == SortOrder.EPISODE_FILENAME_A_Z)) {
|
||||
super.onAddItem(title, ascending, descending, ascendingIsDefault);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onSelectionChanged() {
|
||||
super.onSelectionChanged();
|
||||
DBWriter.setFeedItemSortOrder(getArguments().getLong(ARG_FEED_ID), sortOrder);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -4,26 +4,25 @@ import android.content.Context;
|
||||
import android.content.SharedPreferences;
|
||||
import android.os.Bundle;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuInflater;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.CheckBox;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
|
||||
|
||||
import de.danoeh.antennapod.R;
|
||||
import de.danoeh.antennapod.activity.MainActivity;
|
||||
import de.danoeh.antennapod.core.storage.DBReader;
|
||||
import de.danoeh.antennapod.core.storage.DBWriter;
|
||||
import de.danoeh.antennapod.dialog.ItemSortDialog;
|
||||
import de.danoeh.antennapod.event.FeedListUpdateEvent;
|
||||
import de.danoeh.antennapod.model.feed.FeedItem;
|
||||
import de.danoeh.antennapod.model.feed.FeedItemFilter;
|
||||
import de.danoeh.antennapod.model.feed.SortOrder;
|
||||
import de.danoeh.antennapod.storage.preferences.UserPreferences;
|
||||
import org.greenrobot.eventbus.EventBus;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@ -42,8 +41,6 @@ public class InboxFragment extends EpisodesListFragment {
|
||||
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
|
||||
final View root = super.onCreateView(inflater, container, savedInstanceState);
|
||||
toolbar.inflateMenu(R.menu.inbox);
|
||||
inflateSortMenu();
|
||||
|
||||
toolbar.setTitle(R.string.inbox_label);
|
||||
prefs = getActivity().getSharedPreferences(PREF_NAME, Context.MODE_PRIVATE);
|
||||
updateToolbar();
|
||||
@ -83,13 +80,9 @@ public class InboxFragment extends EpisodesListFragment {
|
||||
showRemoveAllDialog();
|
||||
}
|
||||
return true;
|
||||
} else {
|
||||
SortOrder sortOrder = MenuItemToSortOrderConverter.convert(item);
|
||||
if (sortOrder != null) {
|
||||
UserPreferences.setInboxSortedOrder(sortOrder);
|
||||
loadItems();
|
||||
return true;
|
||||
}
|
||||
} else if (item.getItemId() == R.id.inbox_sort) {
|
||||
new InboxSortDialog().show(getChildFragmentManager(), "SortDialog");
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@ -118,20 +111,6 @@ public class InboxFragment extends EpisodesListFragment {
|
||||
((MainActivity) getActivity()).showSnackbarAbovePlayer(R.string.removed_all_inbox_msg, Toast.LENGTH_SHORT);
|
||||
}
|
||||
|
||||
private void inflateSortMenu() {
|
||||
Menu menu = toolbar.getMenu();
|
||||
MenuItem downloadsItem = menu.findItem(R.id.inbox_sort);
|
||||
MenuInflater menuInflater = getActivity().getMenuInflater();
|
||||
menuInflater.inflate(R.menu.sort_menu, downloadsItem.getSubMenu());
|
||||
|
||||
// Remove the sorting options that are not needed in this fragment
|
||||
toolbar.getMenu().findItem(R.id.sort_episode_title).setVisible(false);
|
||||
toolbar.getMenu().findItem(R.id.sort_feed_title).setVisible(false);
|
||||
toolbar.getMenu().findItem(R.id.sort_random).setVisible(false);
|
||||
toolbar.getMenu().findItem(R.id.sort_smart_shuffle).setVisible(false);
|
||||
toolbar.getMenu().findItem(R.id.keep_sorted).setVisible(false);
|
||||
}
|
||||
|
||||
private void showRemoveAllDialog() {
|
||||
MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(getContext());
|
||||
builder.setTitle(R.string.remove_all_inbox_label);
|
||||
@ -149,4 +128,26 @@ public class InboxFragment extends EpisodesListFragment {
|
||||
builder.setNegativeButton(R.string.cancel_label, null);
|
||||
builder.show();
|
||||
}
|
||||
|
||||
public static class InboxSortDialog extends ItemSortDialog {
|
||||
@Override
|
||||
public void onCreate(@Nullable Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
sortOrder = UserPreferences.getInboxSortedOrder();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onAddItem(int title, SortOrder ascending, SortOrder descending, boolean ascendingIsDefault) {
|
||||
if (ascending == SortOrder.DATE_OLD_NEW || ascending == SortOrder.DURATION_SHORT_LONG) {
|
||||
super.onAddItem(title, ascending, descending, ascendingIsDefault);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onSelectionChanged() {
|
||||
super.onSelectionChanged();
|
||||
UserPreferences.setInboxSortedOrder(sortOrder);
|
||||
EventBus.getDefault().post(new FeedListUpdateEvent(0));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,44 +0,0 @@
|
||||
package de.danoeh.antennapod.fragment;
|
||||
|
||||
import android.view.MenuItem;
|
||||
|
||||
import de.danoeh.antennapod.R;
|
||||
import de.danoeh.antennapod.model.feed.SortOrder;
|
||||
|
||||
public class MenuItemToSortOrderConverter {
|
||||
|
||||
public static SortOrder convert(MenuItem item) {
|
||||
final int itemId = item.getItemId();
|
||||
|
||||
if (itemId == R.id.sort_episode_title_asc) {
|
||||
return SortOrder.EPISODE_TITLE_A_Z;
|
||||
} else if (itemId == R.id.sort_episode_title_desc) {
|
||||
return SortOrder.EPISODE_TITLE_Z_A;
|
||||
} else if (itemId == R.id.sort_date_asc) {
|
||||
return SortOrder.DATE_OLD_NEW;
|
||||
} else if (itemId == R.id.sort_date_desc) {
|
||||
return SortOrder.DATE_NEW_OLD;
|
||||
} else if (itemId == R.id.sort_duration_asc) {
|
||||
return SortOrder.DURATION_SHORT_LONG;
|
||||
} else if (itemId == R.id.sort_duration_desc) {
|
||||
return SortOrder.DURATION_LONG_SHORT;
|
||||
} else if (itemId == R.id.sort_feed_title_asc) {
|
||||
return SortOrder.FEED_TITLE_A_Z;
|
||||
} else if (itemId == R.id.sort_feed_title_desc) {
|
||||
return SortOrder.FEED_TITLE_Z_A;
|
||||
} else if (itemId == R.id.sort_random) {
|
||||
return SortOrder.RANDOM;
|
||||
} else if (itemId == R.id.sort_smart_shuffle_asc) {
|
||||
return SortOrder.SMART_SHUFFLE_OLD_NEW;
|
||||
} else if (itemId == R.id.sort_smart_shuffle_desc) {
|
||||
return SortOrder.SMART_SHUFFLE_NEW_OLD;
|
||||
} else if (itemId == R.id.sort_size_small_large) {
|
||||
return SortOrder.SIZE_SMALL_LARGE;
|
||||
} else if (itemId == R.id.sort_size_large_small) {
|
||||
return SortOrder.SIZE_LARGE_SMALL;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
@ -10,7 +10,6 @@ import android.util.Log;
|
||||
import android.view.ContextMenu;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.MenuInflater;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
@ -18,6 +17,7 @@ import android.widget.CheckBox;
|
||||
import android.widget.ProgressBar;
|
||||
import android.widget.TextView;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.recyclerview.widget.ItemTouchHelper;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
@ -39,6 +39,7 @@ import de.danoeh.antennapod.core.storage.DBWriter;
|
||||
import de.danoeh.antennapod.core.util.Converter;
|
||||
import de.danoeh.antennapod.core.util.FeedItemUtil;
|
||||
import de.danoeh.antennapod.core.util.download.FeedUpdateManager;
|
||||
import de.danoeh.antennapod.dialog.ItemSortDialog;
|
||||
import de.danoeh.antennapod.event.EpisodeDownloadEvent;
|
||||
import de.danoeh.antennapod.event.FeedItemEvent;
|
||||
import de.danoeh.antennapod.event.FeedUpdateRunningEvent;
|
||||
@ -159,6 +160,8 @@ public class QueueFragment extends Fragment implements MaterialToolbar.OnMenuIte
|
||||
case MOVED:
|
||||
return;
|
||||
}
|
||||
recyclerAdapter.updateDragDropEnabled();
|
||||
refreshToolbarState();
|
||||
recyclerView.saveScrollPosition(QueueFragment.TAG);
|
||||
refreshInfoBar();
|
||||
}
|
||||
@ -258,8 +261,6 @@ public class QueueFragment extends Fragment implements MaterialToolbar.OnMenuIte
|
||||
boolean keepSorted = UserPreferences.isQueueKeepSorted();
|
||||
toolbar.getMenu().findItem(R.id.queue_lock).setChecked(UserPreferences.isQueueLocked());
|
||||
toolbar.getMenu().findItem(R.id.queue_lock).setVisible(!keepSorted);
|
||||
toolbar.getMenu().findItem(R.id.sort_random).setVisible(!keepSorted);
|
||||
toolbar.getMenu().findItem(R.id.keep_sorted).setChecked(keepSorted);
|
||||
}
|
||||
|
||||
@Subscribe(sticky = true, threadMode = ThreadMode.MAIN)
|
||||
@ -273,6 +274,9 @@ public class QueueFragment extends Fragment implements MaterialToolbar.OnMenuIte
|
||||
if (itemId == R.id.queue_lock) {
|
||||
toggleQueueLock();
|
||||
return true;
|
||||
} else if (itemId == R.id.queue_sort) {
|
||||
new QueueSortDialog().show(getChildFragmentManager().beginTransaction(), "SortDialog");
|
||||
return true;
|
||||
} else if (itemId == R.id.refresh_item) {
|
||||
FeedUpdateManager.runOnceOrAsk(requireContext());
|
||||
return true;
|
||||
@ -291,28 +295,9 @@ public class QueueFragment extends Fragment implements MaterialToolbar.OnMenuIte
|
||||
};
|
||||
conDialog.createNewDialog().show();
|
||||
return true;
|
||||
} else if (itemId == R.id.keep_sorted) {
|
||||
boolean keepSortedOld = UserPreferences.isQueueKeepSorted();
|
||||
boolean keepSortedNew = !keepSortedOld;
|
||||
UserPreferences.setQueueKeepSorted(keepSortedNew);
|
||||
if (keepSortedNew) {
|
||||
SortOrder sortOrder = UserPreferences.getQueueKeepSortedOrder();
|
||||
DBWriter.reorderQueue(sortOrder, true);
|
||||
}
|
||||
if (recyclerAdapter != null) {
|
||||
recyclerAdapter.updateDragDropEnabled();
|
||||
}
|
||||
refreshToolbarState();
|
||||
return true;
|
||||
} else if (itemId == R.id.action_search) {
|
||||
((MainActivity) getActivity()).loadChildFragment(SearchFragment.newInstance());
|
||||
return true;
|
||||
} else {
|
||||
SortOrder sortOrder = MenuItemToSortOrderConverter.convert(item);
|
||||
if (sortOrder != null) {
|
||||
setSortOrder(sortOrder);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@ -359,16 +344,6 @@ public class QueueFragment extends Fragment implements MaterialToolbar.OnMenuIte
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is called if the user clicks on a sort order menu item.
|
||||
*
|
||||
* @param sortOrder New sort order.
|
||||
*/
|
||||
private void setSortOrder(SortOrder sortOrder) {
|
||||
UserPreferences.setQueueKeepSortedOrder(sortOrder);
|
||||
DBWriter.reorderQueue(sortOrder, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onContextItemSelected(MenuItem item) {
|
||||
Log.d(TAG, "onContextItemSelected() called with: " + "item = [" + item + "]");
|
||||
@ -422,10 +397,6 @@ public class QueueFragment extends Fragment implements MaterialToolbar.OnMenuIte
|
||||
}
|
||||
((MainActivity) getActivity()).setupToolbarToggle(toolbar, displayUpArrow);
|
||||
toolbar.inflateMenu(R.menu.queue);
|
||||
|
||||
MenuItem queueItem = toolbar.getMenu().findItem(R.id.queue_sort);
|
||||
MenuInflater menuInflater = getActivity().getMenuInflater();
|
||||
menuInflater.inflate(R.menu.sort_menu, queueItem.getSubMenu());
|
||||
refreshToolbarState();
|
||||
progressBar = root.findViewById(R.id.progressBar);
|
||||
progressBar.setVisibility(View.VISIBLE);
|
||||
@ -567,6 +538,40 @@ public class QueueFragment extends Fragment implements MaterialToolbar.OnMenuIte
|
||||
swipeActions.attachTo(recyclerView);
|
||||
}
|
||||
|
||||
public static class QueueSortDialog extends ItemSortDialog {
|
||||
@Nullable
|
||||
@Override
|
||||
public View onCreateView(@NonNull LayoutInflater inflater,
|
||||
@Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
|
||||
if (UserPreferences.isQueueKeepSorted()) {
|
||||
sortOrder = UserPreferences.getQueueKeepSortedOrder();
|
||||
}
|
||||
View view = super.onCreateView(inflater, container, savedInstanceState);
|
||||
viewBinding.keepSortedCheckbox.setVisibility(View.VISIBLE);
|
||||
viewBinding.keepSortedCheckbox.setChecked(UserPreferences.isQueueKeepSorted());
|
||||
return view;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onAddItem(int title, SortOrder ascending, SortOrder descending, boolean ascendingIsDefault) {
|
||||
if (ascending != SortOrder.EPISODE_FILENAME_A_Z && ascending != SortOrder.SIZE_SMALL_LARGE) {
|
||||
super.onAddItem(title, ascending, descending, ascendingIsDefault);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onSelectionChanged() {
|
||||
super.onSelectionChanged();
|
||||
viewBinding.keepSortedCheckbox.setEnabled(sortOrder != SortOrder.RANDOM);
|
||||
if (sortOrder == SortOrder.RANDOM) {
|
||||
viewBinding.keepSortedCheckbox.setChecked(false);
|
||||
}
|
||||
UserPreferences.setQueueKeepSorted(viewBinding.keepSortedCheckbox.isChecked());
|
||||
UserPreferences.setQueueKeepSortedOrder(sortOrder);
|
||||
DBWriter.reorderQueue(sortOrder, true);
|
||||
}
|
||||
}
|
||||
|
||||
private class QueueSwipeActions extends SwipeActions {
|
||||
|
||||
// Position tracking whilst dragging
|
||||
|
@ -1,103 +1,32 @@
|
||||
package de.danoeh.antennapod.menuhandler;
|
||||
|
||||
import android.content.Context;
|
||||
import android.util.Log;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
import androidx.annotation.NonNull;
|
||||
import de.danoeh.antennapod.R;
|
||||
import de.danoeh.antennapod.core.storage.DBWriter;
|
||||
import de.danoeh.antennapod.core.util.IntentUtils;
|
||||
import de.danoeh.antennapod.core.util.ShareUtils;
|
||||
import de.danoeh.antennapod.core.util.download.FeedUpdateManager;
|
||||
import de.danoeh.antennapod.dialog.IntraFeedSortDialog;
|
||||
import de.danoeh.antennapod.model.feed.Feed;
|
||||
import de.danoeh.antennapod.model.feed.SortOrder;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import android.content.DialogInterface;
|
||||
import android.annotation.SuppressLint;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.util.Log;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import de.danoeh.antennapod.R;
|
||||
import de.danoeh.antennapod.core.dialog.ConfirmationDialog;
|
||||
import de.danoeh.antennapod.core.storage.DBWriter;
|
||||
import de.danoeh.antennapod.dialog.RemoveFeedDialog;
|
||||
import de.danoeh.antennapod.dialog.RenameItemDialog;
|
||||
import de.danoeh.antennapod.dialog.TagSettingsDialog;
|
||||
import de.danoeh.antennapod.model.feed.Feed;
|
||||
import io.reactivex.Observable;
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers;
|
||||
import io.reactivex.schedulers.Schedulers;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.Future;
|
||||
|
||||
/**
|
||||
* Handles interactions with the FeedItemMenu.
|
||||
*/
|
||||
public class FeedMenuHandler {
|
||||
|
||||
private FeedMenuHandler(){ }
|
||||
|
||||
public abstract class FeedMenuHandler {
|
||||
private static final String TAG = "FeedMenuHandler";
|
||||
|
||||
public static boolean onPrepareOptionsMenu(Menu menu, Feed selectedFeed) {
|
||||
if (selectedFeed == null) {
|
||||
return true;
|
||||
}
|
||||
|
||||
Log.d(TAG, "Preparing options menu");
|
||||
|
||||
menu.findItem(R.id.refresh_complete_item).setVisible(selectedFeed.isPaged());
|
||||
if (StringUtils.isBlank(selectedFeed.getLink())) {
|
||||
menu.findItem(R.id.visit_website_item).setVisible(false);
|
||||
}
|
||||
if (selectedFeed.isLocalFeed()) {
|
||||
// hide complete submenu "Share..." as both sub menu items are not visible
|
||||
menu.findItem(R.id.share_item).setVisible(false);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* NOTE: This method does not handle clicks on the 'remove feed' - item.
|
||||
*/
|
||||
public static boolean onOptionsItemClicked(final Context context, final MenuItem item, final Feed selectedFeed) {
|
||||
final int itemId = item.getItemId();
|
||||
if (itemId == R.id.refresh_item) {
|
||||
FeedUpdateManager.runOnceOrAsk(context, selectedFeed);
|
||||
} else if (itemId == R.id.refresh_complete_item) {
|
||||
new Thread(() -> {
|
||||
selectedFeed.setNextPageLink(selectedFeed.getDownload_url());
|
||||
selectedFeed.setPageNr(0);
|
||||
try {
|
||||
DBWriter.resetPagedFeedPage(selectedFeed).get();
|
||||
FeedUpdateManager.runOnce(context, selectedFeed);
|
||||
} catch (ExecutionException | InterruptedException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}).start();
|
||||
} else if (itemId == R.id.sort_items) {
|
||||
showSortDialog(context, selectedFeed);
|
||||
} else if (itemId == R.id.visit_website_item) {
|
||||
IntentUtils.openInBrowser(context, selectedFeed.getLink());
|
||||
} else if (itemId == R.id.share_item) {
|
||||
ShareUtils.shareFeedLink(context, selectedFeed);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private static void showSortDialog(Context context, Feed selectedFeed) {
|
||||
IntraFeedSortDialog sortDialog = new IntraFeedSortDialog(context, selectedFeed.getSortOrder(), selectedFeed.isLocalFeed()) {
|
||||
@Override
|
||||
protected void updateSort(@NonNull SortOrder sortOrder) {
|
||||
selectedFeed.setSortOrder(sortOrder);
|
||||
DBWriter.setFeedItemSortOrder(selectedFeed.getId(), sortOrder);
|
||||
}
|
||||
};
|
||||
sortDialog.openDialog();
|
||||
}
|
||||
|
||||
public static boolean onMenuItemClicked(@NonNull Fragment fragment, int menuItemId,
|
||||
@NonNull Feed selectedFeed, Runnable callback) {
|
||||
@NonNull Context context = fragment.requireContext();
|
||||
@ -131,5 +60,4 @@ public class FeedMenuHandler {
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
28
app/src/main/res/layout/sort_dialog.xml
Normal file
28
app/src/main/res/layout/sort_dialog.xml
Normal file
@ -0,0 +1,28 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout
|
||||
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="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:padding="16dp">
|
||||
|
||||
<androidx.gridlayout.widget.GridLayout
|
||||
android:id="@+id/gridLayout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
app:columnCount="2"
|
||||
app:rowOrderPreserved="false"
|
||||
app:useDefaultMargins="true"
|
||||
app:alignmentMode="alignBounds" />
|
||||
|
||||
<CheckBox
|
||||
android:id="@+id/keepSortedCheckbox"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:visibility="gone"
|
||||
android:text="@string/keep_sorted"
|
||||
tools:visibility="visible" />
|
||||
|
||||
</LinearLayout>
|
10
app/src/main/res/layout/sort_dialog_item.xml
Normal file
10
app/src/main/res/layout/sort_dialog_item.xml
Normal file
@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Button
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:id="@+id/button"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
app:layout_gravity="fill_horizontal|center_vertical"
|
||||
app:layout_columnWeight="1"
|
||||
style="@style/Widget.Material3.Button.OutlinedButton" />
|
10
app/src/main/res/layout/sort_dialog_item_active.xml
Normal file
10
app/src/main/res/layout/sort_dialog_item_active.xml
Normal file
@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Button
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:id="@+id/button"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
app:layout_gravity="fill_horizontal|center_vertical"
|
||||
app:layout_columnWeight="1"
|
||||
style="@style/Widget.Material3.Button.TonalButton" />
|
@ -24,8 +24,5 @@
|
||||
app:showAsAction="always" />
|
||||
<item
|
||||
android:id="@+id/downloads_sort"
|
||||
android:title="@string/sort">
|
||||
<menu></menu>
|
||||
</item>
|
||||
|
||||
android:title="@string/sort" />
|
||||
</menu>
|
||||
|
@ -33,8 +33,6 @@
|
||||
<item
|
||||
android:id="@+id/episodes_sort"
|
||||
android:title="@string/sort"
|
||||
custom:showAsAction="never">
|
||||
<menu />
|
||||
</item>
|
||||
custom:showAsAction="never" />
|
||||
|
||||
</menu>
|
||||
|
@ -17,9 +17,7 @@
|
||||
|
||||
<item
|
||||
android:id="@+id/inbox_sort"
|
||||
android:title="@string/sort">
|
||||
<menu></menu>
|
||||
</item>
|
||||
android:title="@string/sort" />
|
||||
|
||||
<item
|
||||
android:id="@+id/remove_all_inbox_item"
|
||||
|
@ -23,9 +23,7 @@
|
||||
|
||||
<item
|
||||
android:id="@+id/queue_sort"
|
||||
android:title="@string/sort">
|
||||
<menu></menu>
|
||||
</item>
|
||||
android:title="@string/sort" />
|
||||
|
||||
<item
|
||||
android:id="@+id/clear_queue"
|
||||
|
@ -1,99 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<menu xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<item
|
||||
android:id="@+id/sort_date"
|
||||
android:title="@string/date">
|
||||
|
||||
<menu>
|
||||
<item
|
||||
android:id="@+id/sort_date_asc"
|
||||
android:title="@string/sort_old_new"/>
|
||||
<item
|
||||
android:id="@+id/sort_date_desc"
|
||||
android:title="@string/sort_new_old"/>
|
||||
</menu>
|
||||
</item>
|
||||
|
||||
<item
|
||||
android:id="@+id/sort_duration"
|
||||
android:title="@string/duration">
|
||||
|
||||
<menu>
|
||||
<item
|
||||
android:id="@+id/sort_duration_asc"
|
||||
android:title="@string/sort_short_long"/>
|
||||
<item
|
||||
android:id="@+id/sort_duration_desc"
|
||||
android:title="@string/sort_long_short"/>
|
||||
</menu>
|
||||
</item>
|
||||
|
||||
<item
|
||||
android:id="@+id/sort_episode_title"
|
||||
android:title="@string/episode_title">
|
||||
|
||||
<menu>
|
||||
<item
|
||||
android:id="@+id/sort_episode_title_asc"
|
||||
android:title="@string/sort_a_z"/>
|
||||
<item
|
||||
android:id="@+id/sort_episode_title_desc"
|
||||
android:title="@string/sort_z_a"/>
|
||||
</menu>
|
||||
</item>
|
||||
|
||||
<item
|
||||
android:id="@+id/sort_feed_title"
|
||||
android:title="@string/feed_title">
|
||||
|
||||
<menu>
|
||||
<item
|
||||
android:id="@+id/sort_feed_title_asc"
|
||||
android:title="@string/sort_a_z"/>
|
||||
<item
|
||||
android:id="@+id/sort_feed_title_desc"
|
||||
android:title="@string/sort_z_a"/>
|
||||
</menu>
|
||||
</item>
|
||||
|
||||
<item
|
||||
android:id="@+id/sort_random"
|
||||
android:title="@string/random">
|
||||
</item>
|
||||
|
||||
<item
|
||||
android:id="@+id/sort_smart_shuffle"
|
||||
android:title="@string/smart_shuffle">
|
||||
|
||||
<menu>
|
||||
<item
|
||||
android:id="@+id/sort_smart_shuffle_asc"
|
||||
android:title="@string/sort_old_new"/>
|
||||
<item
|
||||
android:id="@+id/sort_smart_shuffle_desc"
|
||||
android:title="@string/sort_new_old"/>
|
||||
</menu>
|
||||
</item>
|
||||
|
||||
<item
|
||||
android:id="@+id/sort_size"
|
||||
android:title="@string/size"
|
||||
android:visible="false">
|
||||
|
||||
<menu>
|
||||
<item
|
||||
android:id="@+id/sort_size_small_large"
|
||||
android:title="@string/sort_small_large"/>
|
||||
<item
|
||||
android:id="@+id/sort_size_large_small"
|
||||
android:title="@string/sort_large_small"/>
|
||||
</menu>
|
||||
</item>
|
||||
|
||||
<item
|
||||
android:id="@+id/keep_sorted"
|
||||
android:title="@string/keep_sorted"
|
||||
android:checkable="true" />
|
||||
|
||||
</menu>
|
@ -246,48 +246,6 @@
|
||||
<item>DownloadsSection</item>
|
||||
</string-array>
|
||||
|
||||
<!-- sort for podcast screen, not for queue -->
|
||||
<string-array name="feed_episodes_sort_options">
|
||||
<item>@string/sort_date_new_old</item>
|
||||
<item>@string/sort_date_old_new</item>
|
||||
<item>@string/sort_title_a_z</item>
|
||||
<item>@string/sort_title_z_a</item>
|
||||
<item>@string/sort_duration_short_long</item>
|
||||
<item>@string/sort_duration_long_short</item>
|
||||
</string-array>
|
||||
|
||||
<!-- sort for local feed screen -->
|
||||
<string-array name="local_feed_episodes_sort_options">
|
||||
<item>@string/sort_date_new_old</item>
|
||||
<item>@string/sort_date_old_new</item>
|
||||
<item>@string/sort_title_a_z</item>
|
||||
<item>@string/sort_title_z_a</item>
|
||||
<item>@string/sort_duration_short_long</item>
|
||||
<item>@string/sort_duration_long_short</item>
|
||||
<item>@string/sort_filename_a_z</item>
|
||||
<item>@string/sort_filename_z_a</item>
|
||||
</string-array>
|
||||
|
||||
<string-array name="feed_episodes_sort_values">
|
||||
<item>DATE_NEW_OLD</item>
|
||||
<item>DATE_OLD_NEW</item>
|
||||
<item>EPISODE_TITLE_A_Z</item>
|
||||
<item>EPISODE_TITLE_Z_A</item>
|
||||
<item>DURATION_SHORT_LONG</item>
|
||||
<item>DURATION_LONG_SHORT</item>
|
||||
</string-array>
|
||||
|
||||
<string-array name="local_feed_episodes_sort_values">
|
||||
<item>DATE_NEW_OLD</item>
|
||||
<item>DATE_OLD_NEW</item>
|
||||
<item>EPISODE_TITLE_A_Z</item>
|
||||
<item>EPISODE_TITLE_Z_A</item>
|
||||
<item>DURATION_SHORT_LONG</item>
|
||||
<item>DURATION_LONG_SHORT</item>
|
||||
<item>EPISODE_FILENAME_A_Z</item>
|
||||
<item>EPISODE_FILENAME_Z_A</item>
|
||||
</string-array>
|
||||
|
||||
<string-array name="compact_notification_buttons_options">
|
||||
<item>@string/rewind_label</item>
|
||||
<item>@string/fast_forward_label</item>
|
||||
|
@ -767,25 +767,7 @@
|
||||
<string name="not_paused">Not paused</string>
|
||||
<string name="hide_played_episodes_label">Played</string>
|
||||
<string name="not_played">Not played</string>
|
||||
|
||||
<!-- Sort -->
|
||||
<string name="sort_title_a_z">Title (A \u2192 Z)</string>
|
||||
<string name="sort_title_z_a">Title (Z \u2192 A)</string>
|
||||
<string name="sort_date_new_old">Date (New \u2192 Old)</string>
|
||||
<string name="sort_date_old_new">Date (Old \u2192 New)</string>
|
||||
<string name="sort_duration_short_long">Duration (Short \u2192 Long)</string>
|
||||
<string name="sort_duration_long_short">Duration (Long \u2192 Short)</string>
|
||||
<string name="sort_filename_a_z">File Name (A \u2192 Z)</string>
|
||||
<string name="sort_filename_z_a">File Name (Z \u2192 A)</string>
|
||||
|
||||
<string name="sort_a_z">A \u2192 Z</string>
|
||||
<string name="sort_z_a">Z \u2192 A</string>
|
||||
<string name="sort_new_old">New \u2192 Old</string>
|
||||
<string name="sort_old_new">Old \u2192 New</string>
|
||||
<string name="sort_short_long">Short \u2192 Long</string>
|
||||
<string name="sort_long_short">Long \u2192 Short</string>
|
||||
<string name="sort_small_large">Small \u2192 Large</string>
|
||||
<string name="sort_large_small">Large \u2192 Small</string>
|
||||
<string name="filename">File name</string>
|
||||
|
||||
<!-- Share episode dialog -->
|
||||
<string name="share_playback_position_dialog_label">Include playback position</string>
|
||||
|
Loading…
x
Reference in New Issue
Block a user