diff options
author | ByteHamster <info@bytehamster.com> | 2024-02-18 23:59:46 +0100 |
---|---|---|
committer | ByteHamster <info@bytehamster.com> | 2024-02-18 23:59:46 +0100 |
commit | 7a40a505f3700c5e2fe812cba9ef626579409c83 (patch) | |
tree | 139617b459e3f9ed6de50fc25a76e31f64ec4ee0 /app/src/main/java/de/danoeh/antennapod/fragment | |
parent | dc63386e8992f3430e82748282a7843c519a4865 (diff) | |
parent | 0d29e44de5ac97f2285aca241e4f4290c26ea0f9 (diff) | |
download | AntennaPod-7a40a505f3700c5e2fe812cba9ef626579409c83.zip |
Merge branch 'develop'
Diffstat (limited to 'app/src/main/java/de/danoeh/antennapod/fragment')
13 files changed, 369 insertions, 326 deletions
diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/AddFeedFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/AddFeedFragment.java index 29be41727..20cdd2718 100644 --- a/app/src/main/java/de/danoeh/antennapod/fragment/AddFeedFragment.java +++ b/app/src/main/java/de/danoeh/antennapod/fragment/AddFeedFragment.java @@ -147,6 +147,7 @@ public class AddFeedFragment extends Fragment { private void addUrl(String url) { Intent intent = new Intent(getActivity(), OnlineFeedViewActivity.class); intent.putExtra(OnlineFeedViewActivity.ARG_FEEDURL, url); + intent.putExtra(OnlineFeedViewActivity.ARG_WAS_MANUAL_URL, true); startActivity(intent); } diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/AllEpisodesFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/AllEpisodesFragment.java index 7061a69f3..ab5039ec2 100644 --- a/app/src/main/java/de/danoeh/antennapod/fragment/AllEpisodesFragment.java +++ b/app/src/main/java/de/danoeh/antennapod/fragment/AllEpisodesFragment.java @@ -1,20 +1,23 @@ package de.danoeh.antennapod.fragment; -import android.content.Context; -import android.content.SharedPreferences; import android.os.Bundle; import android.view.LayoutInflater; 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; @@ -26,48 +29,33 @@ import java.util.List; */ public class AllEpisodesFragment extends EpisodesListFragment { public static final String TAG = "EpisodesFragment"; - private static final String PREF_NAME = "PrefAllEpisodesFragment"; - private static final String PREF_FILTER = "filter"; - public static final String PREF_SORT = "prefEpisodesSort"; - private SharedPreferences prefs; + public static final String PREF_NAME = "PrefAllEpisodesFragment"; @NonNull @Override 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(); - prefs = getActivity().getSharedPreferences(PREF_NAME, Context.MODE_PRIVATE); txtvInformation.setOnClickListener( v -> AllEpisodesFilterDialog.newInstance(getFilter()).show(getChildFragmentManager(), null)); 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() { - return DBReader.getEpisodes(0, page * EPISODES_PER_PAGE, getFilter(), getSortOrder()); + return DBReader.getEpisodes(0, page * EPISODES_PER_PAGE, getFilter(), + UserPreferences.getAllEpisodesSortOrder()); } @NonNull @Override protected List<FeedItem> loadMoreData(int page) { - return DBReader.getEpisodes((page - 1) * EPISODES_PER_PAGE, EPISODES_PER_PAGE, getFilter(), getSortOrder()); + return DBReader.getEpisodes((page - 1) * EPISODES_PER_PAGE, EPISODES_PER_PAGE, getFilter(), + UserPreferences.getAllEpisodesSortOrder()); } @Override @@ -77,8 +65,7 @@ public class AllEpisodesFragment extends EpisodesListFragment { @Override protected FeedItemFilter getFilter() { - SharedPreferences prefs = getActivity().getSharedPreferences(PREF_NAME, Context.MODE_PRIVATE); - return new FeedItemFilter(prefs.getString(PREF_FILTER, "")); + return new FeedItemFilter(UserPreferences.getPrefFilterAllEpisodes()); } @Override @@ -108,24 +95,16 @@ 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) { - prefs.edit().putString(PREF_SORT, "" + type.code).apply(); - loadItems(); - } - @Subscribe public void onFilterChanged(AllEpisodesFilterDialog.AllEpisodesFilterChangedEvent event) { - prefs.edit().putString(PREF_FILTER, StringUtils.join(event.filterValues, ",")).apply(); + UserPreferences.setPrefFilterAllEpisodes(StringUtils.join(event.filterValues, ",")); updateFilterUi(); page = 1; loadItems(); @@ -144,7 +123,25 @@ public class AllEpisodesFragment extends EpisodesListFragment { getFilter().showIsFavorite ? R.drawable.ic_star : R.drawable.ic_star_border); } - private SortOrder getSortOrder() { - return SortOrder.fromCodeString(prefs.getString(PREF_SORT, "" + SortOrder.DATE_NEW_OLD.code)); + 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)); + } } } diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/AudioPlayerFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/AudioPlayerFragment.java index f2a53ab7e..8b25c0e6a 100644 --- a/app/src/main/java/de/danoeh/antennapod/fragment/AudioPlayerFragment.java +++ b/app/src/main/java/de/danoeh/antennapod/fragment/AudioPlayerFragment.java @@ -15,25 +15,16 @@ import android.widget.TextView; import androidx.annotation.NonNull; import androidx.annotation.Nullable; -import com.google.android.material.appbar.MaterialToolbar; import androidx.cardview.widget.CardView; import androidx.fragment.app.Fragment; import androidx.interpolator.view.animation.FastOutSlowInInterpolator; import androidx.viewpager2.adapter.FragmentStateAdapter; import androidx.viewpager2.widget.ViewPager2; +import com.google.android.material.appbar.MaterialToolbar; import com.google.android.material.bottomsheet.BottomSheetBehavior; import com.google.android.material.elevation.SurfaceColors; -import de.danoeh.antennapod.core.receiver.MediaButtonReceiver; -import de.danoeh.antennapod.core.util.playback.PlaybackController; -import de.danoeh.antennapod.dialog.MediaPlayerErrorDialog; -import de.danoeh.antennapod.event.playback.BufferUpdateEvent; -import de.danoeh.antennapod.event.playback.PlaybackServiceEvent; -import de.danoeh.antennapod.event.PlayerErrorEvent; -import de.danoeh.antennapod.event.playback.SleepTimerUpdatedEvent; -import de.danoeh.antennapod.event.playback.SpeedChangedEvent; -import de.danoeh.antennapod.playback.cast.CastEnabledActivity; import org.greenrobot.eventbus.EventBus; import org.greenrobot.eventbus.Subscribe; import org.greenrobot.eventbus.ThreadMode; @@ -44,23 +35,31 @@ import java.util.List; import de.danoeh.antennapod.R; import de.danoeh.antennapod.activity.MainActivity; -import de.danoeh.antennapod.event.FavoritesEvent; -import de.danoeh.antennapod.event.playback.PlaybackPositionEvent; -import de.danoeh.antennapod.model.feed.Chapter; -import de.danoeh.antennapod.event.UnreadItemsUpdateEvent; -import de.danoeh.antennapod.model.feed.FeedItem; -import de.danoeh.antennapod.model.feed.FeedMedia; import de.danoeh.antennapod.core.feed.util.PlaybackSpeedUtils; -import de.danoeh.antennapod.storage.preferences.UserPreferences; +import de.danoeh.antennapod.core.receiver.MediaButtonReceiver; import de.danoeh.antennapod.core.util.ChapterUtils; import de.danoeh.antennapod.core.util.Converter; import de.danoeh.antennapod.core.util.TimeSpeedConverter; -import de.danoeh.antennapod.model.playback.Playable; -import de.danoeh.antennapod.dialog.PlaybackControlsDialog; +import de.danoeh.antennapod.core.util.playback.PlaybackController; +import de.danoeh.antennapod.dialog.MediaPlayerErrorDialog; import de.danoeh.antennapod.dialog.SkipPreferenceDialog; import de.danoeh.antennapod.dialog.SleepTimerDialog; import de.danoeh.antennapod.dialog.VariableSpeedDialog; +import de.danoeh.antennapod.event.FavoritesEvent; +import de.danoeh.antennapod.event.PlayerErrorEvent; +import de.danoeh.antennapod.event.UnreadItemsUpdateEvent; +import de.danoeh.antennapod.event.playback.BufferUpdateEvent; +import de.danoeh.antennapod.event.playback.PlaybackPositionEvent; +import de.danoeh.antennapod.event.playback.PlaybackServiceEvent; +import de.danoeh.antennapod.event.playback.SleepTimerUpdatedEvent; +import de.danoeh.antennapod.event.playback.SpeedChangedEvent; import de.danoeh.antennapod.menuhandler.FeedItemMenuHandler; +import de.danoeh.antennapod.model.feed.Chapter; +import de.danoeh.antennapod.model.feed.FeedItem; +import de.danoeh.antennapod.model.feed.FeedMedia; +import de.danoeh.antennapod.model.playback.Playable; +import de.danoeh.antennapod.playback.cast.CastEnabledActivity; +import de.danoeh.antennapod.storage.preferences.UserPreferences; import de.danoeh.antennapod.ui.common.PlaybackSpeedIndicatorView; import de.danoeh.antennapod.view.ChapterSeekBar; import de.danoeh.antennapod.view.PlayButton; @@ -503,10 +502,6 @@ public class AudioPlayerFragment extends Fragment implements if (itemId == R.id.disable_sleeptimer_item || itemId == R.id.set_sleeptimer_item) { new SleepTimerDialog().show(getChildFragmentManager(), "SleepTimerDialog"); return true; - } else if (itemId == R.id.audio_controls) { - PlaybackControlsDialog dialog = PlaybackControlsDialog.newInstance(); - dialog.show(getChildFragmentManager(), "playback_controls"); - return true; } else if (itemId == R.id.open_feed_item) { if (feedItem != null) { Intent intent = MainActivity.getIntentToOpenFeed(getContext(), feedItem.getFeedId()); diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/CompletedDownloadsFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/CompletedDownloadsFragment.java index 730a39189..ec7a35466 100644 --- a/app/src/main/java/de/danoeh/antennapod/fragment/CompletedDownloadsFragment.java +++ b/app/src/main/java/de/danoeh/antennapod/fragment/CompletedDownloadsFragment.java @@ -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()); + } + } } diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/EpisodesListFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/EpisodesListFragment.java index 00d671d36..0cbc23a56 100644 --- a/app/src/main/java/de/danoeh/antennapod/fragment/EpisodesListFragment.java +++ b/app/src/main/java/de/danoeh/antennapod/fragment/EpisodesListFragment.java @@ -2,8 +2,6 @@ package de.danoeh.antennapod.fragment; import android.content.DialogInterface; import android.os.Bundle; -import android.os.Handler; -import android.os.Looper; import android.util.Log; import android.view.ContextMenu; import android.view.KeyEvent; @@ -13,6 +11,7 @@ import android.view.View; import android.view.ViewGroup; import android.widget.ProgressBar; import android.widget.TextView; + import androidx.annotation.NonNull; import androidx.appcompat.widget.Toolbar; import androidx.core.util.Pair; @@ -20,9 +19,19 @@ import androidx.fragment.app.Fragment; import androidx.recyclerview.widget.RecyclerView; import androidx.recyclerview.widget.SimpleItemAnimator; import androidx.swiperefreshlayout.widget.SwipeRefreshLayout; + import com.google.android.material.appbar.MaterialToolbar; import com.google.android.material.snackbar.Snackbar; import com.leinardi.android.speeddial.SpeedDialView; + +import org.greenrobot.eventbus.EventBus; +import org.greenrobot.eventbus.Subscribe; +import org.greenrobot.eventbus.ThreadMode; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + import de.danoeh.antennapod.R; import de.danoeh.antennapod.activity.MainActivity; import de.danoeh.antennapod.adapter.EpisodeItemListAdapter; @@ -51,13 +60,6 @@ import io.reactivex.Observable; import io.reactivex.android.schedulers.AndroidSchedulers; import io.reactivex.disposables.Disposable; import io.reactivex.schedulers.Schedulers; -import org.greenrobot.eventbus.EventBus; -import org.greenrobot.eventbus.Subscribe; -import org.greenrobot.eventbus.ThreadMode; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; /** * Shows unread or recently published episodes @@ -77,6 +79,7 @@ public abstract class EpisodesListFragment extends Fragment EmptyViewHandler emptyView; SpeedDialView speedDialView; MaterialToolbar toolbar; + SwipeRefreshLayout swipeRefreshLayout; SwipeActions swipeActions; private ProgressBar progressBar; @@ -180,13 +183,9 @@ public abstract class EpisodesListFragment extends Fragment ((SimpleItemAnimator) animator).setSupportsChangeAnimations(false); } - SwipeRefreshLayout swipeRefreshLayout = root.findViewById(R.id.swipeRefresh); + swipeRefreshLayout = root.findViewById(R.id.swipeRefresh); swipeRefreshLayout.setDistanceToTriggerSync(getResources().getInteger(R.integer.swipe_refresh_distance)); - swipeRefreshLayout.setOnRefreshListener(() -> { - FeedUpdateManager.runOnceOrAsk(requireContext()); - new Handler(Looper.getMainLooper()).postDelayed(() -> swipeRefreshLayout.setRefreshing(false), - getResources().getInteger(R.integer.swipe_to_refresh_duration_in_ms)); - }); + swipeRefreshLayout.setOnRefreshListener(() -> FeedUpdateManager.runOnceOrAsk(requireContext())); listAdapter = new EpisodeItemListAdapter((MainActivity) getActivity()) { @Override @@ -456,9 +455,7 @@ public abstract class EpisodesListFragment extends Fragment @Subscribe(sticky = true, threadMode = ThreadMode.MAIN) public void onEventMainThread(FeedUpdateRunningEvent event) { - if (toolbar.getMenu().findItem(R.id.refresh_item) != null) { - MenuItemUtils.updateRefreshMenuItem(toolbar.getMenu(), R.id.refresh_item, event.isFeedUpdateRunning); - } + swipeRefreshLayout.setRefreshing(event.isFeedUpdateRunning); } @Override diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/FeedInfoFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/FeedInfoFragment.java index b4fa77c75..f62bdaf84 100644 --- a/app/src/main/java/de/danoeh/antennapod/fragment/FeedInfoFragment.java +++ b/app/src/main/java/de/danoeh/antennapod/fragment/FeedInfoFragment.java @@ -22,25 +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 com.joanzapata.iconify.Iconify; 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; @@ -228,7 +227,8 @@ public class FeedInfoFragment extends Fragment implements MaterialToolbar.OnMenu txtvAuthorHeader.setText(feed.getAuthor()); } - txtvUrl.setText(feed.getDownload_url() + " {fa-paperclip}"); + txtvUrl.setText(feed.getDownload_url()); + txtvUrl.setCompoundDrawablesRelativeWithIntrinsicBounds(0, 0, R.drawable.ic_paperclip, 0); if (feed.getPaymentLinks() == null || feed.getPaymentLinks().size() == 0) { lblSupport.setVisibility(View.GONE); @@ -263,7 +263,6 @@ public class FeedInfoFragment extends Fragment implements MaterialToolbar.OnMenu txtvFundingUrl.setText(str.toString()); } - Iconify.addIcons(txtvUrl); refreshToolbarState(); } @@ -290,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) -> { @@ -304,23 +305,19 @@ 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) { feed.setDownload_url(url); - txtvUrl.setText(feed.getDownload_url() + " {fa-paperclip}"); - Iconify.addIcons(txtvUrl); + txtvUrl.setText(feed.getDownload_url()); + 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) { diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/FeedItemlistFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/FeedItemlistFragment.java index 1c949218a..8020235b9 100644 --- a/app/src/main/java/de/danoeh/antennapod/fragment/FeedItemlistFragment.java +++ b/app/src/main/java/de/danoeh/antennapod/fragment/FeedItemlistFragment.java @@ -4,8 +4,6 @@ import android.content.Context; import android.content.res.Configuration; import android.graphics.LightingColorFilter; import android.os.Bundle; -import android.os.Handler; -import android.os.Looper; import android.util.Log; import android.view.ContextMenu; import android.view.KeyEvent; @@ -15,31 +13,48 @@ import android.view.View; import android.view.ViewGroup; import android.widget.AdapterView; 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; + +import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.Validate; +import org.greenrobot.eventbus.EventBus; +import org.greenrobot.eventbus.Subscribe; +import org.greenrobot.eventbus.ThreadMode; + +import java.util.Collections; +import java.util.List; +import java.util.concurrent.ExecutionException; + import de.danoeh.antennapod.R; import de.danoeh.antennapod.activity.MainActivity; 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 +69,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,13 +83,6 @@ 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.Validate; -import org.greenrobot.eventbus.EventBus; -import org.greenrobot.eventbus.Subscribe; -import org.greenrobot.eventbus.ThreadMode; - -import java.util.Collections; -import java.util.List; /** * Displays a list of FeedItems. @@ -183,11 +191,7 @@ public class FeedItemlistFragment extends Fragment implements AdapterView.OnItem EventBus.getDefault().register(this); viewBinding.swipeRefresh.setDistanceToTriggerSync(getResources().getInteger(R.integer.swipe_refresh_distance)); - viewBinding.swipeRefresh.setOnRefreshListener(() -> { - FeedUpdateManager.runOnceOrAsk(requireContext(), feed); - new Handler(Looper.getMainLooper()).postDelayed(() -> viewBinding.swipeRefresh.setRefreshing(false), - getResources().getInteger(R.integer.swipe_to_refresh_duration_in_ms)); - }); + viewBinding.swipeRefresh.setOnRefreshListener(() -> FeedUpdateManager.runOnceOrAsk(requireContext(), feed)); loadItems(); @@ -240,8 +244,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 +269,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 @@ -407,8 +429,7 @@ public class FeedItemlistFragment extends Fragment implements AdapterView.OnItem if (!event.isFeedUpdateRunning) { nextPageLoader.getRoot().setVisibility(View.GONE); } - MenuItemUtils.updateRefreshMenuItem(viewBinding.toolbar.getMenu(), - R.id.refresh_item, event.isFeedUpdateRunning); + viewBinding.swipeRefresh.setRefreshing(event.isFeedUpdateRunning); } private void refreshHeaderView() { @@ -592,4 +613,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); + } + } } diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/InboxFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/InboxFragment.java index f8bcbb532..497409e70 100644 --- a/app/src/main/java/de/danoeh/antennapod/fragment/InboxFragment.java +++ b/app/src/main/java/de/danoeh/antennapod/fragment/InboxFragment.java @@ -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)); + } + } } diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/MenuItemToSortOrderConverter.java b/app/src/main/java/de/danoeh/antennapod/fragment/MenuItemToSortOrderConverter.java deleted file mode 100644 index d4150fbdb..000000000 --- a/app/src/main/java/de/danoeh/antennapod/fragment/MenuItemToSortOrderConverter.java +++ /dev/null @@ -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; - } - -} diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/NavDrawerFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/NavDrawerFragment.java index eeca181cf..636c0245b 100644 --- a/app/src/main/java/de/danoeh/antennapod/fragment/NavDrawerFragment.java +++ b/app/src/main/java/de/danoeh/antennapod/fragment/NavDrawerFragment.java @@ -382,7 +382,7 @@ public class NavDrawerFragment extends Fragment implements SharedPreferences.OnS } } else if (UserPreferences.getSubscriptionsFilter().isEnabled() && navAdapter.showSubscriptionList) { - SubscriptionsFilterDialog.showDialog(requireContext()); + new SubscriptionsFilterDialog().show(getChildFragmentManager(), "filter"); } } diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/QueueFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/QueueFragment.java index 80933023e..003ee23db 100644 --- a/app/src/main/java/de/danoeh/antennapod/fragment/QueueFragment.java +++ b/app/src/main/java/de/danoeh/antennapod/fragment/QueueFragment.java @@ -4,29 +4,36 @@ import android.content.Context; import android.content.DialogInterface; import android.content.SharedPreferences; import android.os.Bundle; -import android.os.Handler; -import android.os.Looper; 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; 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; import androidx.recyclerview.widget.SimpleItemAnimator; import androidx.swiperefreshlayout.widget.SwipeRefreshLayout; + import com.google.android.material.appbar.MaterialToolbar; import com.google.android.material.dialog.MaterialAlertDialogBuilder; import com.google.android.material.snackbar.Snackbar; import com.leinardi.android.speeddial.SpeedDialView; + +import org.greenrobot.eventbus.EventBus; +import org.greenrobot.eventbus.Subscribe; +import org.greenrobot.eventbus.ThreadMode; + +import java.util.List; + import de.danoeh.antennapod.R; import de.danoeh.antennapod.activity.MainActivity; import de.danoeh.antennapod.adapter.EpisodeItemListAdapter; @@ -39,6 +46,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; @@ -61,12 +69,6 @@ import io.reactivex.Observable; import io.reactivex.android.schedulers.AndroidSchedulers; import io.reactivex.disposables.Disposable; import io.reactivex.schedulers.Schedulers; -import org.greenrobot.eventbus.EventBus; -import org.greenrobot.eventbus.Subscribe; -import org.greenrobot.eventbus.ThreadMode; - -import java.util.List; -import java.util.Locale; /** * Shows all items in the queue. @@ -81,6 +83,7 @@ public class QueueFragment extends Fragment implements MaterialToolbar.OnMenuIte private QueueRecyclerAdapter recyclerAdapter; private EmptyViewHandler emptyView; private MaterialToolbar toolbar; + private SwipeRefreshLayout swipeRefreshLayout; private boolean displayUpArrow; private List<FeedItem> queue; @@ -159,6 +162,8 @@ public class QueueFragment extends Fragment implements MaterialToolbar.OnMenuIte case MOVED: return; } + recyclerAdapter.updateDragDropEnabled(); + refreshToolbarState(); recyclerView.saveScrollPosition(QueueFragment.TAG); refreshInfoBar(); } @@ -258,13 +263,11 @@ 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) public void onEventMainThread(FeedUpdateRunningEvent event) { - MenuItemUtils.updateRefreshMenuItem(toolbar.getMenu(), R.id.refresh_item, event.isFeedUpdateRunning); + swipeRefreshLayout.setRefreshing(event.isFeedUpdateRunning); } @Override @@ -273,6 +276,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 +297,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 +346,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 +399,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); @@ -454,13 +427,9 @@ public class QueueFragment extends Fragment implements MaterialToolbar.OnMenuIte recyclerAdapter.setOnSelectModeListener(this); recyclerView.setAdapter(recyclerAdapter); - SwipeRefreshLayout swipeRefreshLayout = root.findViewById(R.id.swipeRefresh); + swipeRefreshLayout = root.findViewById(R.id.swipeRefresh); swipeRefreshLayout.setDistanceToTriggerSync(getResources().getInteger(R.integer.swipe_refresh_distance)); - swipeRefreshLayout.setOnRefreshListener(() -> { - FeedUpdateManager.runOnceOrAsk(requireContext()); - new Handler(Looper.getMainLooper()).postDelayed(() -> swipeRefreshLayout.setRefreshing(false), - getResources().getInteger(R.integer.swipe_to_refresh_duration_in_ms)); - }); + swipeRefreshLayout.setOnRefreshListener(() -> FeedUpdateManager.runOnceOrAsk(requireContext())); emptyView = new EmptyViewHandler(getContext()); emptyView.attachToRecyclerView(recyclerView); @@ -507,9 +476,8 @@ public class QueueFragment extends Fragment implements MaterialToolbar.OnMenuIte } private void refreshInfoBar() { - String info = String.format(Locale.getDefault(), "%d%s", - queue.size(), getString(R.string.episodes_suffix)); - if (queue.size() > 0) { + String info = getResources().getQuantityString(R.plurals.num_episodes, queue.size(), queue.size()); + if (!queue.isEmpty()) { long timeLeft = 0; for (FeedItem item : queue) { float playbackSpeed = 1; @@ -567,6 +535,42 @@ 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(); + } + final View view = super.onCreateView(inflater, container, savedInstanceState); + viewBinding.keepSortedCheckbox.setVisibility(View.VISIBLE); + viewBinding.keepSortedCheckbox.setChecked(UserPreferences.isQueueKeepSorted()); + // Disable until something gets selected + viewBinding.keepSortedCheckbox.setEnabled(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 diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/SubscriptionFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/SubscriptionFragment.java index 93ed4c2c9..e86cd58b9 100644 --- a/app/src/main/java/de/danoeh/antennapod/fragment/SubscriptionFragment.java +++ b/app/src/main/java/de/danoeh/antennapod/fragment/SubscriptionFragment.java @@ -3,8 +3,6 @@ package de.danoeh.antennapod.fragment; import android.content.Context; import android.content.SharedPreferences; import android.os.Bundle; -import android.os.Handler; -import android.os.Looper; import android.util.Log; import android.view.ContextMenu; import android.view.LayoutInflater; @@ -81,6 +79,7 @@ public class SubscriptionFragment extends Fragment private EmptyViewHandler emptyView; private LinearLayout feedsFilteredMsg; private MaterialToolbar toolbar; + private SwipeRefreshLayout swipeRefreshLayout; private ProgressBar progressBar; private String displayedFolder = null; private boolean displayUpArrow; @@ -166,15 +165,12 @@ public class SubscriptionFragment extends Fragment }); feedsFilteredMsg = root.findViewById(R.id.feeds_filtered_message); - feedsFilteredMsg.setOnClickListener((l) -> SubscriptionsFilterDialog.showDialog(requireContext())); + feedsFilteredMsg.setOnClickListener((l) -> + new SubscriptionsFilterDialog().show(getChildFragmentManager(), "filter")); - SwipeRefreshLayout swipeRefreshLayout = root.findViewById(R.id.swipeRefresh); + swipeRefreshLayout = root.findViewById(R.id.swipeRefresh); swipeRefreshLayout.setDistanceToTriggerSync(getResources().getInteger(R.integer.swipe_refresh_distance)); - swipeRefreshLayout.setOnRefreshListener(() -> { - FeedUpdateManager.runOnceOrAsk(requireContext()); - new Handler(Looper.getMainLooper()).postDelayed(() -> swipeRefreshLayout.setRefreshing(false), - getResources().getInteger(R.integer.swipe_to_refresh_duration_in_ms)); - }); + swipeRefreshLayout.setOnRefreshListener(() -> FeedUpdateManager.runOnceOrAsk(requireContext())); speedDialView = root.findViewById(R.id.fabSD); speedDialView.setOverlayLayout(root.findViewById(R.id.fabSDOverlay)); @@ -211,7 +207,7 @@ public class SubscriptionFragment extends Fragment @Subscribe(sticky = true, threadMode = ThreadMode.MAIN) public void onEventMainThread(FeedUpdateRunningEvent event) { - MenuItemUtils.updateRefreshMenuItem(toolbar.getMenu(), R.id.refresh_item, event.isFeedUpdateRunning); + swipeRefreshLayout.setRefreshing(event.isFeedUpdateRunning); } @Override @@ -221,7 +217,7 @@ public class SubscriptionFragment extends Fragment FeedUpdateManager.runOnceOrAsk(requireContext()); return true; } else if (itemId == R.id.subscriptions_filter) { - SubscriptionsFilterDialog.showDialog(requireContext()); + new SubscriptionsFilterDialog().show(getChildFragmentManager(), "filter"); return true; } else if (itemId == R.id.subscriptions_sort) { FeedSortDialog.showDialog(requireContext()); diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/preferences/UserInterfacePreferencesFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/preferences/UserInterfacePreferencesFragment.java index 66f592af2..0f3320e98 100644 --- a/app/src/main/java/de/danoeh/antennapod/fragment/preferences/UserInterfacePreferencesFragment.java +++ b/app/src/main/java/de/danoeh/antennapod/fragment/preferences/UserInterfacePreferencesFragment.java @@ -1,8 +1,10 @@ package de.danoeh.antennapod.fragment.preferences; import android.content.Context; +import android.content.DialogInterface; import android.os.Build; import android.os.Bundle; +import android.widget.Button; import android.widget.ListView; import androidx.appcompat.app.AlertDialog; import androidx.core.app.ActivityCompat; @@ -64,14 +66,14 @@ public class UserInterfacePreferencesFragment extends PreferenceFragmentCompat { return true; }); - findPreference(UserPreferences.PREF_COMPACT_NOTIFICATION_BUTTONS) + findPreference(UserPreferences.PREF_FULL_NOTIFICATION_BUTTONS) .setOnPreferenceClickListener(preference -> { - showNotificationButtonsDialog(); + showFullNotificationButtonsDialog(); return true; }); findPreference(UserPreferences.PREF_FILTER_FEED) .setOnPreferenceClickListener((preference -> { - SubscriptionsFilterDialog.showDialog(requireContext()); + new SubscriptionsFilterDialog().show(getChildFragmentManager(), "filter"); return true; })); @@ -91,48 +93,85 @@ public class UserInterfacePreferencesFragment extends PreferenceFragmentCompat { } } - private void showNotificationButtonsDialog() { + + private void showFullNotificationButtonsDialog() { final Context context = getActivity(); - final List<Integer> preferredButtons = UserPreferences.getCompactNotificationButtons(); + + final List<Integer> preferredButtons = UserPreferences.getFullNotificationButtons(); final String[] allButtonNames = context.getResources().getStringArray( - R.array.compact_notification_buttons_options); + R.array.full_notification_buttons_options); + final int[] buttonIDs = {2, 3, 4}; + final int exactItems = 2; + final DialogInterface.OnClickListener completeListener = (dialog, which) -> + UserPreferences.setFullNotificationButtons(preferredButtons); + final String title = context.getResources().getString( + R.string.pref_full_notification_buttons_title); + + showNotificationButtonsDialog(preferredButtons, allButtonNames, buttonIDs, title, + exactItems, completeListener + ); + } + + private void showNotificationButtonsDialog(List<Integer> preferredButtons, + String[] allButtonNames, int[] buttonIds, String title, + int exactItems, DialogInterface.OnClickListener completeListener) { boolean[] checked = new boolean[allButtonNames.length]; // booleans default to false in java + final Context context = getActivity(); + + // Clear buttons that are not part of the setting anymore + for (int i = preferredButtons.size() - 1; i >= 0; i--) { + boolean isValid = false; + for (int j = 0; j < checked.length; j++) { + if (buttonIds[j] == preferredButtons.get(i)) { + isValid = true; + } + } + + if (!isValid) { + preferredButtons.remove(i); + } + } + for(int i=0; i < checked.length; i++) { - if(preferredButtons.contains(i)) { + if (preferredButtons.contains(buttonIds[i])) { checked[i] = true; } } MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(context); - builder.setTitle(String.format(context.getResources().getString( - R.string.pref_compact_notification_buttons_dialog_title), 2)); + builder.setTitle(title); builder.setMultiChoiceItems(allButtonNames, checked, (dialog, which, isChecked) -> { checked[which] = isChecked; if (isChecked) { - if (preferredButtons.size() < 2) { - preferredButtons.add(which); - } else { - // Only allow a maximum of two selections. This is because the notification - // on the lock screen can only display 3 buttons, and the play/pause button - // is always included. - checked[which] = false; - ListView selectionView = ((AlertDialog) dialog).getListView(); - selectionView.setItemChecked(which, false); - Snackbar.make( - selectionView, - String.format(context.getResources().getString( - R.string.pref_compact_notification_buttons_dialog_error), 2), - Snackbar.LENGTH_SHORT).show(); - } + preferredButtons.add(buttonIds[which]); } else { - preferredButtons.remove((Integer) which); + preferredButtons.remove((Integer) buttonIds[which]); } }); - builder.setPositiveButton(R.string.confirm_label, (dialog, which) -> - UserPreferences.setCompactNotificationButtons(preferredButtons)); + builder.setPositiveButton(R.string.confirm_label, null); builder.setNegativeButton(R.string.cancel_label, null); - builder.create().show(); + final AlertDialog dialog = builder.create(); + + dialog.show(); + + Button positiveButton = dialog.getButton(AlertDialog.BUTTON_POSITIVE); + + positiveButton.setOnClickListener(v -> { + if (preferredButtons.size() != exactItems) { + ListView selectionView = dialog.getListView(); + Snackbar.make( + selectionView, + String.format(context.getResources().getString( + R.string.pref_compact_notification_buttons_dialog_error_exact), exactItems), + Snackbar.LENGTH_SHORT).show(); + + } else { + completeListener.onClick(dialog, AlertDialog.BUTTON_POSITIVE); + dialog.cancel(); + } + } + ); } } |