From 0f5f4d9e35c80cf56b28d64d8f548d6eaa826415 Mon Sep 17 00:00:00 2001 From: ByteHamster Date: Sat, 6 Aug 2022 11:30:58 +0200 Subject: [PATCH] Move common code of list fragments to EpisodesListFragment --- .../fragment/AllEpisodesFragment.java | 131 +++---------- .../fragment/EpisodesListFragment.java | 174 +++++++++--------- .../antennapod/fragment/InboxFragment.java | 140 ++++++-------- .../fragment/PlaybackHistoryFragment.java | 122 ++++-------- ...ragment.xml => episodes_list_fragment.xml} | 9 + .../res/layout/list_container_fragment.xml | 23 --- app/src/main/res/menu/episodes.xml | 1 - .../antennapod/model/feed/FeedItemFilter.java | 4 - 8 files changed, 201 insertions(+), 403 deletions(-) rename app/src/main/res/layout/{all_episodes_fragment.xml => episodes_list_fragment.xml} (89%) delete mode 100644 app/src/main/res/layout/list_container_fragment.xml 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 b054cee14..de11818b5 100644 --- a/app/src/main/java/de/danoeh/antennapod/fragment/AllEpisodesFragment.java +++ b/app/src/main/java/de/danoeh/antennapod/fragment/AllEpisodesFragment.java @@ -7,80 +7,47 @@ import android.view.LayoutInflater; import android.view.MenuItem; import android.view.View; import android.view.ViewGroup; -import android.widget.FrameLayout; import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import androidx.appcompat.widget.Toolbar; import com.joanzapata.iconify.Iconify; import de.danoeh.antennapod.R; -import de.danoeh.antennapod.activity.MainActivity; -import de.danoeh.antennapod.core.event.DownloadEvent; -import de.danoeh.antennapod.core.menuhandler.MenuItemUtils; -import de.danoeh.antennapod.core.service.download.DownloadService; -import de.danoeh.antennapod.core.storage.DBReader; import de.danoeh.antennapod.dialog.AllEpisodesFilterDialog; -import de.danoeh.antennapod.fragment.swipeactions.SwipeActions; -import de.danoeh.antennapod.model.feed.FeedItem; import de.danoeh.antennapod.model.feed.FeedItemFilter; import org.apache.commons.lang3.StringUtils; import org.greenrobot.eventbus.Subscribe; -import org.greenrobot.eventbus.ThreadMode; import java.util.Collections; -import java.util.List; /** * Shows all episodes (possibly filtered by user). */ -public class AllEpisodesFragment extends EpisodesListFragment implements Toolbar.OnMenuItemClickListener { +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"; - private static final String KEY_UP_ARROW = "up_arrow"; - private Toolbar toolbar; - private boolean displayUpArrow; - private volatile boolean isUpdatingFeeds; - private SwipeActions swipeActions; - - private FeedItemFilter feedItemFilter = new FeedItemFilter(""); - - @Override - public void onCreate(@Nullable Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - SharedPreferences prefs = getActivity().getSharedPreferences(PREF_NAME, Context.MODE_PRIVATE); - feedItemFilter = new FeedItemFilter(prefs.getString(PREF_FILTER, "")); - } @NonNull @Override public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { - View appEpisodesContainer = View.inflate(getContext(), R.layout.list_container_fragment, null); - View root = super.onCreateView(inflater, container, savedInstanceState); - ((FrameLayout) appEpisodesContainer.findViewById(R.id.listContent)).addView(root); - - toolbar = appEpisodesContainer.findViewById(R.id.toolbar); - toolbar.setOnMenuItemClickListener(this); + final View root = super.onCreateView(inflater, container, savedInstanceState); toolbar.inflateMenu(R.menu.episodes); toolbar.setTitle(R.string.episodes_label); - toolbar.setOnLongClickListener(v -> { - recyclerView.scrollToPosition(5); - recyclerView.post(() -> recyclerView.smoothScrollToPosition(0)); - return false; - }); updateToolbar(); - displayUpArrow = getParentFragmentManager().getBackStackEntryCount() != 0; - if (savedInstanceState != null) { - displayUpArrow = savedInstanceState.getBoolean(KEY_UP_ARROW); - } - ((MainActivity) getActivity()).setupToolbarToggle(toolbar, displayUpArrow); - - swipeActions = new SwipeActions(this, TAG).attachTo(recyclerView); - swipeActions.setFilter(feedItemFilter); - + updateFilterUi(); speedDialView.removeActionItemById(R.id.mark_unread_batch); speedDialView.removeActionItemById(R.id.remove_from_queue_batch); speedDialView.removeActionItemById(R.id.delete_batch); - return appEpisodesContainer; + return root; + } + + @Override + protected FeedItemFilter getFilter() { + SharedPreferences prefs = getActivity().getSharedPreferences(PREF_NAME, Context.MODE_PRIVATE); + return new FeedItemFilter(prefs.getString(PREF_FILTER, "")); + } + + @Override + protected String getFragmentTag() { + return TAG; } @Override @@ -94,10 +61,10 @@ public class AllEpisodesFragment extends EpisodesListFragment implements Toolbar return true; } if (item.getItemId() == R.id.filter_items) { - AllEpisodesFilterDialog.newInstance(feedItemFilter).show(getChildFragmentManager(), null); + AllEpisodesFilterDialog.newInstance(getFilter()).show(getChildFragmentManager(), null); return true; } else if (item.getItemId() == R.id.action_favorites) { - onFilterChanged(new AllEpisodesFilterDialog.AllEpisodesFilterChangedEvent(feedItemFilter.showIsFavorite + onFilterChanged(new AllEpisodesFilterDialog.AllEpisodesFilterChangedEvent(getFilter().showIsFavorite ? Collections.emptySet() : Collections.singleton(FeedItemFilter.IS_FAVORITE))); return true; } @@ -106,19 +73,16 @@ public class AllEpisodesFragment extends EpisodesListFragment implements Toolbar @Subscribe public void onFilterChanged(AllEpisodesFilterDialog.AllEpisodesFilterChangedEvent event) { - feedItemFilter = new FeedItemFilter(event.filterValues.toArray(new String[0])); SharedPreferences prefs = getActivity().getSharedPreferences(PREF_NAME, Context.MODE_PRIVATE); prefs.edit().putString(PREF_FILTER, StringUtils.join(event.filterValues, ",")).apply(); + updateFilterUi(); page = 1; - swipeActions.setFilter(feedItemFilter); loadItems(); } - @Override - protected void onFragmentLoaded(List episodes) { - super.onFragmentLoaded(episodes); - - if (feedItemFilter.getValues().length > 0) { + private void updateFilterUi() { + swipeActions.setFilter(getFilter()); + if (getFilter().getValues().length > 0) { txtvInformation.setText("{md-info-outline} " + this.getString(R.string.filtered_label)); Iconify.addIcons(txtvInformation); txtvInformation.setVisibility(View.VISIBLE); @@ -126,57 +90,4 @@ public class AllEpisodesFragment extends EpisodesListFragment implements Toolbar txtvInformation.setVisibility(View.GONE); } } - - private final MenuItemUtils.UpdateRefreshMenuItemChecker updateRefreshMenuItemChecker = - () -> DownloadService.isRunning && DownloadService.isDownloadingFeeds(); - - private void updateToolbar() { - isUpdatingFeeds = MenuItemUtils.updateRefreshMenuItem(toolbar.getMenu(), - R.id.refresh_item, updateRefreshMenuItemChecker); - toolbar.getMenu().findItem(R.id.filter_items).setVisible(true); - } - - @Override - public void onStart() { - super.onStart(); - if (isUpdatingFeeds != updateRefreshMenuItemChecker.isRefreshing()) { - updateToolbar(); - } - } - - @Subscribe(sticky = true, threadMode = ThreadMode.MAIN) - public void onEventMainThread(DownloadEvent event) { - super.onEventMainThread(event); - if (event.hasChangedFeedUpdateStatus(isUpdatingFeeds)) { - updateToolbar(); - } - } - - @Override - protected boolean shouldUpdatedItemRemainInList(FeedItem item) { - return feedItemFilter.matches(item); - } - - @Override - public void onSaveInstanceState(@NonNull Bundle outState) { - outState.putBoolean(KEY_UP_ARROW, displayUpArrow); - super.onSaveInstanceState(outState); - } - - @NonNull - @Override - protected List loadData() { - return DBReader.getRecentlyPublishedEpisodes(0, page * EPISODES_PER_PAGE, feedItemFilter); - } - - @NonNull - @Override - protected List loadMoreData(int page) { - return DBReader.getRecentlyPublishedEpisodes((page - 1) * EPISODES_PER_PAGE, EPISODES_PER_PAGE, feedItemFilter); - } - - @Override - protected int loadTotalItemCount() { - return DBReader.getTotalEpisodeCount(feedItemFilter); - } } 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 03dbc6ae4..f581a16f5 100644 --- a/app/src/main/java/de/danoeh/antennapod/fragment/EpisodesListFragment.java +++ b/app/src/main/java/de/danoeh/antennapod/fragment/EpisodesListFragment.java @@ -2,18 +2,11 @@ package de.danoeh.antennapod.fragment; import android.content.DialogInterface; import android.os.Bundle; -import android.view.ContextMenu; -import android.view.KeyEvent; -import androidx.annotation.NonNull; -import androidx.core.util.Pair; -import androidx.fragment.app.Fragment; -import androidx.recyclerview.widget.RecyclerView; -import androidx.recyclerview.widget.SimpleItemAnimator; -import androidx.swiperefreshlayout.widget.SwipeRefreshLayout; - 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.Menu; import android.view.MenuItem; @@ -21,22 +14,44 @@ import android.view.View; import android.view.ViewGroup; import android.widget.ProgressBar; import android.widget.TextView; -import android.widget.Toast; - +import androidx.annotation.NonNull; +import androidx.appcompat.widget.Toolbar; +import androidx.core.util.Pair; +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.snackbar.Snackbar; import com.leinardi.android.speeddial.SpeedDialView; +import de.danoeh.antennapod.R; +import de.danoeh.antennapod.activity.MainActivity; import de.danoeh.antennapod.adapter.EpisodeItemListAdapter; -import de.danoeh.antennapod.adapter.SelectableAdapter; +import de.danoeh.antennapod.core.dialog.ConfirmationDialog; +import de.danoeh.antennapod.core.event.DownloadEvent; +import de.danoeh.antennapod.core.event.DownloaderUpdate; +import de.danoeh.antennapod.core.menuhandler.MenuItemUtils; +import de.danoeh.antennapod.core.service.download.DownloadService; +import de.danoeh.antennapod.core.storage.DBReader; +import de.danoeh.antennapod.core.util.FeedItemUtil; +import de.danoeh.antennapod.core.util.download.AutoUpdateManager; +import de.danoeh.antennapod.event.FeedItemEvent; import de.danoeh.antennapod.event.FeedListUpdateEvent; -import de.danoeh.antennapod.event.playback.PlaybackPositionEvent; import de.danoeh.antennapod.event.PlayerStatusEvent; import de.danoeh.antennapod.event.UnreadItemsUpdateEvent; -import de.danoeh.antennapod.core.menuhandler.MenuItemUtils; +import de.danoeh.antennapod.event.playback.PlaybackPositionEvent; import de.danoeh.antennapod.fragment.actions.EpisodeMultiSelectActionHandler; -import de.danoeh.antennapod.ui.common.PagedToolbarFragment; +import de.danoeh.antennapod.fragment.swipeactions.SwipeActions; +import de.danoeh.antennapod.menuhandler.FeedItemMenuHandler; +import de.danoeh.antennapod.model.feed.FeedItem; +import de.danoeh.antennapod.model.feed.FeedItemFilter; +import de.danoeh.antennapod.view.EmptyViewHandler; import de.danoeh.antennapod.view.EpisodeItemListRecyclerView; import de.danoeh.antennapod.view.viewholder.EpisodeItemViewHolder; import io.reactivex.Completable; +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; @@ -44,34 +59,18 @@ import org.greenrobot.eventbus.ThreadMode; import java.util.ArrayList; import java.util.List; -import de.danoeh.antennapod.R; -import de.danoeh.antennapod.activity.MainActivity; -import de.danoeh.antennapod.core.dialog.ConfirmationDialog; -import de.danoeh.antennapod.core.event.DownloadEvent; -import de.danoeh.antennapod.core.event.DownloaderUpdate; -import de.danoeh.antennapod.event.FeedItemEvent; -import de.danoeh.antennapod.model.feed.FeedItem; -import de.danoeh.antennapod.core.service.download.DownloadService; -import de.danoeh.antennapod.core.storage.DBWriter; -import de.danoeh.antennapod.core.util.FeedItemUtil; -import de.danoeh.antennapod.core.util.download.AutoUpdateManager; -import de.danoeh.antennapod.menuhandler.FeedItemMenuHandler; -import de.danoeh.antennapod.view.EmptyViewHandler; -import io.reactivex.Observable; -import io.reactivex.android.schedulers.AndroidSchedulers; -import io.reactivex.disposables.Disposable; -import io.reactivex.schedulers.Schedulers; - /** * Shows unread or recently published episodes */ -public abstract class EpisodesListFragment extends Fragment implements EpisodeItemListAdapter.OnSelectModeListener { - +public abstract class EpisodesListFragment extends Fragment + implements EpisodeItemListAdapter.OnSelectModeListener, Toolbar.OnMenuItemClickListener { public static final String TAG = "EpisodesListFragment"; + private static final String KEY_UP_ARROW = "up_arrow"; protected static final int EPISODES_PER_PAGE = 150; protected int page = 1; protected boolean isLoadingMore = false; protected boolean hasMoreItems = true; + private boolean displayUpArrow; EpisodeItemListRecyclerView recyclerView; EpisodeItemListAdapter listAdapter; @@ -79,6 +78,8 @@ public abstract class EpisodesListFragment extends Fragment implements EpisodeIt View loadingMoreView; EmptyViewHandler emptyView; SpeedDialView speedDialView; + Toolbar toolbar; + SwipeActions swipeActions; @NonNull List episodes = new ArrayList<>(); @@ -87,9 +88,6 @@ public abstract class EpisodesListFragment extends Fragment implements EpisodeIt protected Disposable disposable; protected TextView txtvInformation; - String getPrefName() { - return TAG; - } @Override public void onStart() { @@ -137,21 +135,6 @@ public abstract class EpisodesListFragment extends Fragment implements EpisodeIt if (itemId == R.id.refresh_item) { AutoUpdateManager.runImmediate(requireContext()); return true; - } else if (itemId == R.id.remove_all_inbox_item) { - ConfirmationDialog removeAllNewFlagsConfirmationDialog = new ConfirmationDialog(getActivity(), - R.string.remove_all_inbox_label, - R.string.remove_all_inbox_confirmation_msg) { - - @Override - public void onConfirmButtonPressed(DialogInterface dialog) { - dialog.dismiss(); - DBWriter.removeAllNewFlags(); - ((MainActivity) getActivity()).showSnackbarAbovePlayer( - R.string.removed_all_inbox_msg, Toast.LENGTH_SHORT); - } - }; - removeAllNewFlagsConfirmationDialog.createNewDialog().show(); - return true; } else if (itemId == R.id.action_search) { ((MainActivity) getActivity()).loadChildFragment(SearchFragment.newInstance()); return true; @@ -180,13 +163,28 @@ public abstract class EpisodesListFragment extends Fragment implements EpisodeIt @Override public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { super.onCreateView(inflater, container, savedInstanceState); - View root = inflater.inflate(R.layout.all_episodes_fragment, container, false); + View root = inflater.inflate(R.layout.episodes_list_fragment, container, false); txtvInformation = root.findViewById(R.id.txtvInformation); + toolbar = root.findViewById(R.id.toolbar); + toolbar.setOnMenuItemClickListener(this); + toolbar.setOnLongClickListener(v -> { + recyclerView.scrollToPosition(5); + recyclerView.post(() -> recyclerView.smoothScrollToPosition(0)); + return false; + }); + displayUpArrow = getParentFragmentManager().getBackStackEntryCount() != 0; + if (savedInstanceState != null) { + displayUpArrow = savedInstanceState.getBoolean(KEY_UP_ARROW); + } + ((MainActivity) getActivity()).setupToolbarToggle(toolbar, displayUpArrow); recyclerView = root.findViewById(android.R.id.list); recyclerView.setRecycledViewPool(((MainActivity) getActivity()).getRecycledViewPool()); setupLoadMoreScrollListener(); + swipeActions = new SwipeActions(this, getFragmentTag()).attachTo(recyclerView); + swipeActions.setFilter(getFilter()); + RecyclerView.ItemAnimator animator = recyclerView.getItemAnimator(); if (animator instanceof SimpleItemAnimator) { ((SimpleItemAnimator) animator).setSupportsChangeAnimations(false); @@ -308,7 +306,7 @@ public abstract class EpisodesListFragment extends Fragment implements EpisodeIt hasMoreItems = false; } episodes.addAll(data); - onFragmentLoaded(episodes); + updateAdapterWithNewItems(); if (listAdapter.shouldSelectLazyLoadedItems()) { listAdapter.setSelected(episodes.size() - data.size(), episodes.size(), true); } @@ -320,7 +318,7 @@ public abstract class EpisodesListFragment extends Fragment implements EpisodeIt }); } - protected void onFragmentLoaded(List episodes) { + protected void updateAdapterWithNewItems() { boolean restoreScrollPosition = listAdapter.getItemCount() == 0; if (episodes.size() == 0) { createRecycleAdapter(recyclerView, emptyView); @@ -330,10 +328,6 @@ public abstract class EpisodesListFragment extends Fragment implements EpisodeIt if (restoreScrollPosition) { recyclerView.restoreScrollPosition(getPrefName()); } - if (isUpdatingFeeds != updateRefreshMenuItemChecker.isRefreshing() - && getParentFragment() instanceof PagedToolbarFragment) { - ((PagedToolbarFragment) getParentFragment()).invalidateOptionsMenuIfActive(this); - } } /** @@ -385,7 +379,7 @@ public abstract class EpisodesListFragment extends Fragment implements EpisodeIt int pos = FeedItemUtil.indexOfItemWithId(episodes, item.getId()); if (pos >= 0) { episodes.remove(pos); - if (shouldUpdatedItemRemainInList(item)) { + if (getFilter().matches(item)) { episodes.add(pos, item); listAdapter.notifyItemChangedCompat(pos); } else { @@ -425,16 +419,12 @@ public abstract class EpisodesListFragment extends Fragment implements EpisodeIt } } - protected boolean shouldUpdatedItemRemainInList(FeedItem item) { - return true; - } - @Subscribe(sticky = true, threadMode = ThreadMode.MAIN) public void onEventMainThread(DownloadEvent event) { Log.d(TAG, "onEventMainThread() called with: " + "event = [" + event + "]"); DownloaderUpdate update = event.update; - if (event.hasChangedFeedUpdateStatus(isUpdatingFeeds) && getParentFragment() instanceof PagedToolbarFragment) { - ((PagedToolbarFragment) getParentFragment()).invalidateOptionsMenuIfActive(this); + if (event.hasChangedFeedUpdateStatus(isUpdatingFeeds)) { + updateToolbar(); } if (update.mediaIds.length > 0) { for (long mediaId : update.mediaIds) { @@ -448,9 +438,8 @@ public abstract class EpisodesListFragment extends Fragment implements EpisodeIt private void updateUi() { loadItems(); - if (isUpdatingFeeds != updateRefreshMenuItemChecker.isRefreshing() - && getParentFragment() instanceof PagedToolbarFragment) { - ((PagedToolbarFragment) getParentFragment()).invalidateOptionsMenuIfActive(this); + if (isUpdatingFeeds != updateRefreshMenuItemChecker.isRefreshing()) { + updateToolbar(); } } @@ -481,32 +470,41 @@ public abstract class EpisodesListFragment extends Fragment implements EpisodeIt loadingMoreView.setVisibility(View.GONE); hasMoreItems = true; episodes = data.first; + listAdapter.notifyDataSetChanged(); listAdapter.setTotalNumberOfItems(data.second); - onFragmentLoaded(episodes); - if (getParentFragment() instanceof PagedToolbarFragment) { - ((PagedToolbarFragment) getParentFragment()).invalidateOptionsMenuIfActive(this); - } + updateAdapterWithNewItems(); + updateToolbar(); }, error -> Log.e(TAG, Log.getStackTraceString(error))); } @NonNull - protected abstract List loadData(); + protected List loadData() { + return DBReader.getRecentlyPublishedEpisodes(0, page * EPISODES_PER_PAGE, getFilter()); + } - /** - * Load a new page of data as defined by {@link #page} and {@link #EPISODES_PER_PAGE}. - * If the number of items returned is less than {@link #EPISODES_PER_PAGE}, - * it will be assumed that the underlying data is exhausted - * and this method will not be called again. - * - * @return The items from the next page of data - */ @NonNull - protected abstract List loadMoreData(int page); + protected List loadMoreData(int page) { + return DBReader.getRecentlyPublishedEpisodes((page - 1) * EPISODES_PER_PAGE, EPISODES_PER_PAGE, getFilter()); + } - /** - * Returns the total number of items that would be returned if {@link #loadMoreData} was called often enough. - */ protected int loadTotalItemCount() { - return SelectableAdapter.COUNT_AUTOMATICALLY; + return DBReader.getTotalEpisodeCount(getFilter()); + } + + protected abstract FeedItemFilter getFilter(); + + protected abstract String getFragmentTag(); + + protected abstract String getPrefName(); + + protected void updateToolbar() { + isUpdatingFeeds = MenuItemUtils.updateRefreshMenuItem(toolbar.getMenu(), + R.id.refresh_item, updateRefreshMenuItemChecker); + } + + @Override + public void onSaveInstanceState(@NonNull Bundle outState) { + outState.putBoolean(KEY_UP_ARROW, displayUpArrow); + super.onSaveInstanceState(outState); } } 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 0ff0bd24a..6e5db0963 100644 --- a/app/src/main/java/de/danoeh/antennapod/fragment/InboxFragment.java +++ b/app/src/main/java/de/danoeh/antennapod/fragment/InboxFragment.java @@ -1,116 +1,84 @@ package de.danoeh.antennapod.fragment; +import android.content.DialogInterface; import android.os.Bundle; -import android.view.MenuItem; -import android.widget.FrameLayout; -import androidx.annotation.NonNull; -import androidx.appcompat.widget.Toolbar; import android.view.LayoutInflater; +import android.view.MenuItem; import android.view.View; import android.view.ViewGroup; - -import java.util.List; - +import android.widget.Toast; +import androidx.annotation.NonNull; import de.danoeh.antennapod.R; import de.danoeh.antennapod.activity.MainActivity; -import de.danoeh.antennapod.core.event.DownloadEvent; -import de.danoeh.antennapod.core.menuhandler.MenuItemUtils; -import de.danoeh.antennapod.core.service.download.DownloadService; -import de.danoeh.antennapod.fragment.swipeactions.SwipeActions; -import de.danoeh.antennapod.model.feed.FeedItem; +import de.danoeh.antennapod.core.dialog.ConfirmationDialog; import de.danoeh.antennapod.core.storage.DBReader; +import de.danoeh.antennapod.core.storage.DBWriter; +import de.danoeh.antennapod.model.feed.FeedItem; import de.danoeh.antennapod.model.feed.FeedItemFilter; -import org.greenrobot.eventbus.Subscribe; -import org.greenrobot.eventbus.ThreadMode; + +import java.util.List; /** * Like 'EpisodesFragment' except that it only shows new episodes and * supports swiping to mark as read. */ -public class InboxFragment extends EpisodesListFragment implements Toolbar.OnMenuItemClickListener { +public class InboxFragment extends EpisodesListFragment { public static final String TAG = "NewEpisodesFragment"; private static final String PREF_NAME = "PrefNewEpisodesFragment"; - private static final String KEY_UP_ARROW = "up_arrow"; - private Toolbar toolbar; - private boolean displayUpArrow; - private volatile boolean isUpdatingFeeds; + @NonNull + @Override + public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { + final View root = super.onCreateView(inflater, container, savedInstanceState); + toolbar.inflateMenu(R.menu.inbox); + toolbar.setTitle(R.string.inbox_label); + updateToolbar(); + emptyView.setIcon(R.drawable.ic_inbox); + emptyView.setTitle(R.string.no_inbox_head_label); + emptyView.setMessage(R.string.no_inbox_label); + speedDialView.removeActionItemById(R.id.mark_unread_batch); + speedDialView.removeActionItemById(R.id.remove_from_queue_batch); + speedDialView.removeActionItemById(R.id.delete_batch); + return root; + } + + @Override + protected FeedItemFilter getFilter() { + return new FeedItemFilter(FeedItemFilter.NEW); + } + + @Override + protected String getFragmentTag() { + return TAG; + } @Override protected String getPrefName() { return PREF_NAME; } - @Override - protected boolean shouldUpdatedItemRemainInList(FeedItem item) { - return item.isNew(); - } - - @NonNull - @Override - public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { - View inboxContainer = View.inflate(getContext(), R.layout.list_container_fragment, null); - View root = super.onCreateView(inflater, container, savedInstanceState); - ((FrameLayout) inboxContainer.findViewById(R.id.listContent)).addView(root); - emptyView.setTitle(R.string.no_inbox_head_label); - emptyView.setMessage(R.string.no_inbox_label); - - toolbar = inboxContainer.findViewById(R.id.toolbar); - toolbar.setOnMenuItemClickListener(this); - toolbar.inflateMenu(R.menu.inbox); - toolbar.setOnLongClickListener(v -> { - recyclerView.scrollToPosition(5); - recyclerView.post(() -> recyclerView.smoothScrollToPosition(0)); - return false; - }); - displayUpArrow = getParentFragmentManager().getBackStackEntryCount() != 0; - if (savedInstanceState != null) { - displayUpArrow = savedInstanceState.getBoolean(KEY_UP_ARROW); - } - ((MainActivity) getActivity()).setupToolbarToggle(toolbar, displayUpArrow); - - SwipeActions swipeActions = new SwipeActions(this, TAG).attachTo(recyclerView); - swipeActions.setFilter(new FeedItemFilter(FeedItemFilter.NEW)); - - speedDialView.removeActionItemById(R.id.mark_unread_batch); - speedDialView.removeActionItemById(R.id.remove_from_queue_batch); - speedDialView.removeActionItemById(R.id.delete_batch); - return inboxContainer; - } - - private final MenuItemUtils.UpdateRefreshMenuItemChecker updateRefreshMenuItemChecker = - () -> DownloadService.isRunning && DownloadService.isDownloadingFeeds(); - - private void updateToolbar() { - isUpdatingFeeds = MenuItemUtils.updateRefreshMenuItem(toolbar.getMenu(), - R.id.refresh_item, updateRefreshMenuItemChecker); - } - - @Override - public void onStart() { - super.onStart(); - if (isUpdatingFeeds != updateRefreshMenuItemChecker.isRefreshing()) { - updateToolbar(); - } - } - - @Subscribe(sticky = true, threadMode = ThreadMode.MAIN) - public void onEventMainThread(DownloadEvent event) { - super.onEventMainThread(event); - if (event.hasChangedFeedUpdateStatus(isUpdatingFeeds)) { - updateToolbar(); - } - } - @Override public boolean onMenuItemClick(MenuItem item) { - return super.onOptionsItemSelected(item); - } + if (super.onOptionsItemSelected(item)) { + return true; + } + if (item.getItemId() == R.id.remove_all_inbox_item) { + ConfirmationDialog removeAllNewFlagsConfirmationDialog = new ConfirmationDialog(getActivity(), + R.string.remove_all_inbox_label, + R.string.remove_all_inbox_confirmation_msg) { - @Override - public void onSaveInstanceState(@NonNull Bundle outState) { - outState.putBoolean(KEY_UP_ARROW, displayUpArrow); - super.onSaveInstanceState(outState); + @Override + public void onConfirmButtonPressed(DialogInterface dialog) { + dialog.dismiss(); + DBWriter.removeAllNewFlags(); + ((MainActivity) getActivity()).showSnackbarAbovePlayer( + R.string.removed_all_inbox_msg, Toast.LENGTH_SHORT); + } + }; + removeAllNewFlagsConfirmationDialog.createNewDialog().show(); + return true; + } + return false; } @NonNull diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/PlaybackHistoryFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/PlaybackHistoryFragment.java index a22edbc76..3e9b2b5c7 100644 --- a/app/src/main/java/de/danoeh/antennapod/fragment/PlaybackHistoryFragment.java +++ b/app/src/main/java/de/danoeh/antennapod/fragment/PlaybackHistoryFragment.java @@ -1,92 +1,59 @@ package de.danoeh.antennapod.fragment; import android.os.Bundle; -import android.view.ContextMenu; import android.view.LayoutInflater; import android.view.MenuItem; import android.view.View; import android.view.ViewGroup; -import android.widget.FrameLayout; - import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import androidx.appcompat.widget.Toolbar; - import de.danoeh.antennapod.R; -import de.danoeh.antennapod.activity.MainActivity; -import de.danoeh.antennapod.adapter.EpisodeItemListAdapter; -import de.danoeh.antennapod.core.menuhandler.MenuItemUtils; -import de.danoeh.antennapod.event.playback.PlaybackHistoryEvent; -import de.danoeh.antennapod.event.PlayerStatusEvent; -import de.danoeh.antennapod.event.UnreadItemsUpdateEvent; -import de.danoeh.antennapod.model.feed.FeedItem; import de.danoeh.antennapod.core.storage.DBReader; import de.danoeh.antennapod.core.storage.DBWriter; +import de.danoeh.antennapod.event.playback.PlaybackHistoryEvent; +import de.danoeh.antennapod.model.feed.FeedItem; +import de.danoeh.antennapod.model.feed.FeedItemFilter; import org.greenrobot.eventbus.Subscribe; import org.greenrobot.eventbus.ThreadMode; import java.util.List; -public class PlaybackHistoryFragment extends EpisodesListFragment implements Toolbar.OnMenuItemClickListener { +public class PlaybackHistoryFragment extends EpisodesListFragment { public static final String TAG = "PlaybackHistoryFragment"; - private static final String KEY_UP_ARROW = "up_arrow"; - - private Toolbar toolbar; - private boolean displayUpArrow; + @NonNull @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - setRetainInstance(true); - } - - @Override - public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, - @Nullable Bundle savedInstanceState) { - View historyContainer = View.inflate(getContext(), R.layout.list_container_fragment, null); - View root = super.onCreateView(inflater, container, savedInstanceState); - - ((FrameLayout) historyContainer.findViewById(R.id.listContent)).addView(root); - - toolbar = historyContainer.findViewById(R.id.toolbar); - toolbar.setTitle(R.string.playback_history_label); - toolbar.setOnMenuItemClickListener(this); - toolbar.setOnLongClickListener(v -> { - recyclerView.scrollToPosition(5); - recyclerView.post(() -> recyclerView.smoothScrollToPosition(0)); - return false; - }); - displayUpArrow = getParentFragmentManager().getBackStackEntryCount() != 0; - if (savedInstanceState != null) { - displayUpArrow = savedInstanceState.getBoolean(KEY_UP_ARROW); - } - ((MainActivity) getActivity()).setupToolbarToggle(toolbar, displayUpArrow); + public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { + final View root = super.onCreateView(inflater, container, savedInstanceState); toolbar.inflateMenu(R.menu.playback_history); - refreshToolbarState(); - - listAdapter = new PlaybackHistoryListAdapter((MainActivity) getActivity()); - recyclerView.setAdapter(listAdapter); - + toolbar.setTitle(R.string.playback_history_label); + updateToolbar(); emptyView.setIcon(R.drawable.ic_history); emptyView.setTitle(R.string.no_history_head_label); emptyView.setMessage(R.string.no_history_label); - - return historyContainer; + swipeActions.detach(); + return root; } @Override - public void onSaveInstanceState(@NonNull Bundle outState) { - outState.putBoolean(KEY_UP_ARROW, displayUpArrow); - super.onSaveInstanceState(outState); + protected FeedItemFilter getFilter() { + return FeedItemFilter.unfiltered(); } - public void refreshToolbarState() { - boolean hasHistory = episodes != null && !episodes.isEmpty(); - toolbar.getMenu().findItem(R.id.clear_history_item).setVisible(hasHistory); + @Override + protected String getFragmentTag() { + return TAG; + } + + @Override + protected String getPrefName() { + return TAG; } @Override public boolean onMenuItemClick(MenuItem item) { + if (super.onOptionsItemSelected(item)) { + return true; + } if (item.getItemId() == R.id.clear_history_item) { DBWriter.clearPlaybackHistory(); return true; @@ -94,43 +61,16 @@ public class PlaybackHistoryFragment extends EpisodesListFragment implements Too return false; } + @Override + protected void updateToolbar() { + // Not calling super, as we do not have a refresh button that could be updated + toolbar.getMenu().findItem(R.id.clear_history_item).setVisible(!episodes.isEmpty()); + } + @Subscribe(threadMode = ThreadMode.MAIN) public void onHistoryUpdated(PlaybackHistoryEvent event) { loadItems(); - refreshToolbarState(); - } - - @Subscribe(threadMode = ThreadMode.MAIN) - public void onPlayerStatusChanged(PlayerStatusEvent event) { - loadItems(); - refreshToolbarState(); - } - - @Override - @Subscribe(threadMode = ThreadMode.MAIN) - public void onUnreadItemsChanged(UnreadItemsUpdateEvent event) { - loadItems(); - refreshToolbarState(); - } - - @Override - protected void onFragmentLoaded(List episodes) { - super.onFragmentLoaded(episodes); - listAdapter.notifyDataSetChanged(); - refreshToolbarState(); - } - - private class PlaybackHistoryListAdapter extends EpisodeItemListAdapter { - - public PlaybackHistoryListAdapter(MainActivity mainActivity) { - super(mainActivity); - } - - @Override - public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) { - super.onCreateContextMenu(menu, v, menuInfo); - MenuItemUtils.setOnClickListeners(menu, PlaybackHistoryFragment.this::onContextItemSelected); - } + updateToolbar(); } @NonNull diff --git a/app/src/main/res/layout/all_episodes_fragment.xml b/app/src/main/res/layout/episodes_list_fragment.xml similarity index 89% rename from app/src/main/res/layout/all_episodes_fragment.xml rename to app/src/main/res/layout/episodes_list_fragment.xml index c1e7e6434..39a0c260a 100644 --- a/app/src/main/res/layout/all_episodes_fragment.xml +++ b/app/src/main/res/layout/episodes_list_fragment.xml @@ -6,11 +6,20 @@ android:layout_height="match_parent" android:orientation="vertical"> + + - - - - - - - diff --git a/app/src/main/res/menu/episodes.xml b/app/src/main/res/menu/episodes.xml index d4a80829b..2841fc12f 100644 --- a/app/src/main/res/menu/episodes.xml +++ b/app/src/main/res/menu/episodes.xml @@ -21,7 +21,6 @@ android:icon="@drawable/ic_filter" android:menuCategory="container" android:title="@string/filter" - android:visible="false" custom:showAsAction="always"/>