mirror of
https://github.com/AntennaPod/AntennaPod.git
synced 2025-10-29 11:49:33 +00:00
Add more explicit feature to archive feeds (#8022)
This commit is contained in:
parent
6510bea11d
commit
23d862185d
@ -130,7 +130,7 @@ public class FeedItemMenuHandler {
|
||||
setItemVisibility(menu, R.id.download_item, canDownload);
|
||||
setItemVisibility(menu, R.id.transcript_item, canShowTranscript);
|
||||
|
||||
if (selectedItems.size() == 1 && selectedItems.get(0).getFeed().getState() != Feed.STATE_SUBSCRIBED) {
|
||||
if (selectedItems.size() == 1 && selectedItems.get(0).getFeed().getState() == Feed.STATE_NOT_SUBSCRIBED) {
|
||||
setItemVisibility(menu, R.id.mark_read_item, false);
|
||||
}
|
||||
|
||||
@ -193,7 +193,7 @@ public class FeedItemMenuHandler {
|
||||
} else if (menuItemId == R.id.mark_read_item) {
|
||||
selectedItem.setPlayed(true);
|
||||
DBWriter.markItemPlayed(selectedItem, FeedItem.PLAYED, true);
|
||||
if (!selectedItem.getFeed().isLocalFeed() && selectedItem.getFeed().getState() == Feed.STATE_SUBSCRIBED
|
||||
if (!selectedItem.getFeed().isLocalFeed() && selectedItem.getFeed().getState() != Feed.STATE_NOT_SUBSCRIBED
|
||||
&& SynchronizationSettings.isProviderConnected()) {
|
||||
FeedMedia media = selectedItem.getMedia();
|
||||
// not all items have media, Gpodder only cares about those that do
|
||||
@ -211,7 +211,7 @@ public class FeedItemMenuHandler {
|
||||
selectedItem.setPlayed(false);
|
||||
DBWriter.markItemPlayed(selectedItem, FeedItem.UNPLAYED, false);
|
||||
if (!selectedItem.getFeed().isLocalFeed() && selectedItem.getMedia() != null
|
||||
&& selectedItem.getFeed().getState() == Feed.STATE_SUBSCRIBED) {
|
||||
&& selectedItem.getFeed().getState() != Feed.STATE_NOT_SUBSCRIBED) {
|
||||
SynchronizationQueue.getInstance().enqueueEpisodeAction(
|
||||
new EpisodeAction.Builder(selectedItem, EpisodeAction.NEW)
|
||||
.currentTimestamp()
|
||||
|
||||
@ -69,6 +69,7 @@ public class SearchFragment extends Fragment implements EpisodeItemListAdapter.O
|
||||
private static final String ARG_QUERY = "query";
|
||||
private static final String ARG_FEED = "feed";
|
||||
private static final String ARG_FEED_NAME = "feedName";
|
||||
private static final String ARG_ARCHIVED = "archived";
|
||||
private static final int SEARCH_DEBOUNCE_INTERVAL = 1500;
|
||||
|
||||
private EpisodeItemListAdapter adapter;
|
||||
@ -117,6 +118,12 @@ public class SearchFragment extends Fragment implements EpisodeItemListAdapter.O
|
||||
return fragment;
|
||||
}
|
||||
|
||||
public static SearchFragment newInstanceArchive() {
|
||||
SearchFragment fragment = newInstance();
|
||||
fragment.getArguments().putBoolean(ARG_ARCHIVED, true);
|
||||
return fragment;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
@ -198,10 +205,10 @@ public class SearchFragment extends Fragment implements EpisodeItemListAdapter.O
|
||||
chip = layout.findViewById(R.id.feed_title_chip);
|
||||
chip.setOnCloseIconClickListener(v -> {
|
||||
getArguments().putLong(ARG_FEED, 0);
|
||||
getArguments().putBoolean(ARG_ARCHIVED, false);
|
||||
searchWithProgressBar();
|
||||
});
|
||||
chip.setVisibility((getArguments().getLong(ARG_FEED, 0) == 0) ? View.GONE : View.VISIBLE);
|
||||
chip.setText(getArguments().getString(ARG_FEED_NAME, ""));
|
||||
updateChipVisibility();
|
||||
if (getArguments().getString(ARG_QUERY, null) != null) {
|
||||
search();
|
||||
}
|
||||
@ -377,6 +384,17 @@ public class SearchFragment extends Fragment implements EpisodeItemListAdapter.O
|
||||
search();
|
||||
}
|
||||
|
||||
private void updateChipVisibility() {
|
||||
chip.setVisibility(View.GONE);
|
||||
if (getArguments().getBoolean(ARG_ARCHIVED, false)) {
|
||||
chip.setVisibility(View.VISIBLE);
|
||||
chip.setText(R.string.archive_feed_label_noun);
|
||||
} else if (getArguments().getLong(ARG_FEED, 0) != 0) {
|
||||
chip.setVisibility(View.VISIBLE);
|
||||
chip.setText(getArguments().getString(ARG_FEED_NAME, ""));
|
||||
}
|
||||
}
|
||||
|
||||
private void search() {
|
||||
if (disposableFeeds != null) {
|
||||
disposableFeeds.dispose();
|
||||
@ -386,7 +404,7 @@ public class SearchFragment extends Fragment implements EpisodeItemListAdapter.O
|
||||
}
|
||||
long feed = getArguments().getLong(ARG_FEED, 0);
|
||||
boolean isSearchingFeed = feed != 0;
|
||||
chip.setVisibility(isSearchingFeed ? View.VISIBLE : View.GONE);
|
||||
updateChipVisibility();
|
||||
adapterFeeds.setEndButton(R.string.search_online, isSearchingFeed ? null : this::searchOnline);
|
||||
|
||||
String query = searchView.getQuery().toString();
|
||||
@ -394,11 +412,12 @@ public class SearchFragment extends Fragment implements EpisodeItemListAdapter.O
|
||||
emptyViewHandler.setTitle(R.string.type_to_search);
|
||||
return;
|
||||
}
|
||||
final int state = getArguments().getBoolean(ARG_ARCHIVED, false) ? Feed.STATE_ARCHIVED : Feed.STATE_SUBSCRIBED;
|
||||
if (feed != 0) {
|
||||
// Search within a feed
|
||||
adapterFeeds.updateData(Collections.emptyList());
|
||||
} else {
|
||||
disposableFeeds = Observable.fromCallable(() -> DBReader.searchFeeds(query))
|
||||
disposableFeeds = Observable.fromCallable(() -> DBReader.searchFeeds(query, state))
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(results -> {
|
||||
@ -407,7 +426,7 @@ public class SearchFragment extends Fragment implements EpisodeItemListAdapter.O
|
||||
emptyViewHandler.setTitle(getString(R.string.no_results_for_query, query));
|
||||
}, error -> Log.e(TAG, Log.getStackTraceString(error)));
|
||||
}
|
||||
disposableEpisodes = Observable.fromCallable(() -> DBReader.searchFeedItems(feed, query))
|
||||
disposableEpisodes = Observable.fromCallable(() -> DBReader.searchFeedItems(feed, query, state))
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(results -> {
|
||||
|
||||
@ -44,6 +44,7 @@ import org.greenrobot.eventbus.Subscribe;
|
||||
import org.greenrobot.eventbus.ThreadMode;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@ -167,6 +168,8 @@ public class NavDrawerFragment extends Fragment implements SharedPreferences.OnS
|
||||
menu.setHeaderTitle(contextPressedItem.asFeed().getTitle());
|
||||
inflater.inflate(R.menu.nav_feed_context, menu);
|
||||
// episodes are not loaded, so we cannot check if the podcast has new or unplayed ones!
|
||||
} else if (FeedPreferences.TAG_UNTAGGED.equals(contextPressedItem.asTag().getTitle())) {
|
||||
return;
|
||||
} else {
|
||||
menu.setHeaderTitle(contextPressedItem.asTag().getTitle());
|
||||
inflater.inflate(R.menu.nav_folder_context, menu);
|
||||
@ -190,14 +193,8 @@ public class NavDrawerFragment extends Fragment implements SharedPreferences.OnS
|
||||
|
||||
private boolean onFeedContextMenuClicked(Feed feed, MenuItem item) {
|
||||
final int itemId = item.getItemId();
|
||||
if (itemId == R.id.remove_feed) {
|
||||
RemoveFeedDialog.show(getContext(), feed, () -> {
|
||||
if (String.valueOf(feed.getId()).equals(getLastNavFragment(getContext()))) {
|
||||
((MainActivity) getActivity()).loadFragment(UserPreferences.getDefaultPage(), null);
|
||||
// Make sure fragment is hidden before actually starting to delete
|
||||
getActivity().getSupportFragmentManager().executePendingTransactions();
|
||||
}
|
||||
});
|
||||
if (itemId == R.id.remove_archive_feed) {
|
||||
new RemoveFeedDialogClose(Collections.singletonList(feed)).show(getParentFragmentManager(), null);
|
||||
return true;
|
||||
}
|
||||
if (FeedMenuHandler.onMenuItemClicked(this, itemId, feed, null)) {
|
||||
@ -206,6 +203,26 @@ public class NavDrawerFragment extends Fragment implements SharedPreferences.OnS
|
||||
return super.onContextItemSelected(item);
|
||||
}
|
||||
|
||||
public static class RemoveFeedDialogClose extends RemoveFeedDialog {
|
||||
public RemoveFeedDialogClose(@NonNull List<Feed> feeds) {
|
||||
super(feeds);
|
||||
}
|
||||
|
||||
public RemoveFeedDialogClose() {
|
||||
super();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onRemoveButtonPressed() {
|
||||
if (String.valueOf(feeds.get(0).getId()).equals(getLastNavFragment(getContext()))) {
|
||||
// Make sure fragment is hidden before actually starting to delete
|
||||
((MainActivity) getActivity()).loadFragment(UserPreferences.getDefaultPage(), null);
|
||||
getActivity().getSupportFragmentManager().executePendingTransactions();
|
||||
}
|
||||
super.onRemoveButtonPressed();
|
||||
}
|
||||
}
|
||||
|
||||
private boolean onTagContextMenuClicked(NavDrawerData.TagItem drawerItem, MenuItem item) {
|
||||
final int itemId = item.getItemId();
|
||||
if (itemId == R.id.rename_folder_item) {
|
||||
@ -361,7 +378,7 @@ public class NavDrawerFragment extends Fragment implements SharedPreferences.OnS
|
||||
.putStringSet(PREF_OPEN_FOLDERS, openFolders)
|
||||
.apply();
|
||||
|
||||
disposable = Observable.fromCallable(() -> makeFlatDrawerData(navDrawerData.feeds,
|
||||
disposable = Observable.fromCallable(() -> makeFlatDrawerData(
|
||||
navDrawerData.tags, navDrawerData.feedCounters))
|
||||
.subscribeOn(Schedulers.computation())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
@ -408,9 +425,10 @@ public class NavDrawerFragment extends Fragment implements SharedPreferences.OnS
|
||||
disposable = Observable.fromCallable(
|
||||
() -> {
|
||||
NavDrawerData data = DBReader.getNavDrawerData(UserPreferences.getSubscriptionsFilter(),
|
||||
UserPreferences.getFeedOrder(), UserPreferences.getFeedCounterSetting());
|
||||
UserPreferences.getFeedOrder(), UserPreferences.getFeedCounterSetting(),
|
||||
Feed.STATE_SUBSCRIBED);
|
||||
reclaimableSpace = EpisodeCleanupAlgorithmFactory.build().getReclaimableItems();
|
||||
return new Pair<>(data, makeFlatDrawerData(data.feeds, data.tags, data.feedCounters));
|
||||
return new Pair<>(data, makeFlatDrawerData(data.tags, data.feedCounters));
|
||||
})
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
@ -426,14 +444,20 @@ public class NavDrawerFragment extends Fragment implements SharedPreferences.OnS
|
||||
});
|
||||
}
|
||||
|
||||
private List<DrawerItem> makeFlatDrawerData(List<Feed> feeds, List<NavDrawerData.TagItem> tags,
|
||||
private List<DrawerItem> makeFlatDrawerData(List<NavDrawerData.TagItem> tags,
|
||||
@Nullable java.util.Map<Long, Integer> feedCounters) {
|
||||
List<DrawerItem> flatItems = new ArrayList<>();
|
||||
for (Feed feed : feeds) {
|
||||
flatItems.add(new DrawerItem(feed, feedCounter(feed, feedCounters), 0));
|
||||
}
|
||||
for (NavDrawerData.TagItem tag : tags) {
|
||||
if (FeedPreferences.TAG_ROOT.equals(tag.getTitle())) {
|
||||
for (Feed feed : tag.getFeeds()) {
|
||||
flatItems.add(new DrawerItem(feed, feedCounter(feed, feedCounters), 0));
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
for (NavDrawerData.TagItem tag : tags) {
|
||||
if (FeedPreferences.TAG_ROOT.equals(tag.getTitle())
|
||||
|| FeedPreferences.TAG_UNTAGGED.equals(tag.getTitle())) {
|
||||
continue;
|
||||
}
|
||||
DrawerItem tagItem = new DrawerItem(tag);
|
||||
|
||||
@ -22,6 +22,7 @@ import com.bumptech.glide.load.resource.bitmap.RoundedCorners;
|
||||
import com.bumptech.glide.request.RequestOptions;
|
||||
import de.danoeh.antennapod.R;
|
||||
import de.danoeh.antennapod.model.feed.Feed;
|
||||
import de.danoeh.antennapod.model.feed.FeedPreferences;
|
||||
import de.danoeh.antennapod.storage.database.NavDrawerData;
|
||||
import de.danoeh.antennapod.storage.preferences.UserPreferences;
|
||||
import de.danoeh.antennapod.ui.common.ImagePlaceholder;
|
||||
@ -271,6 +272,9 @@ public class NavListAdapter extends RecyclerView.Adapter<NavListAdapter.Holder>
|
||||
if (tag.isOpen()) {
|
||||
holder.count.setVisibility(View.GONE);
|
||||
}
|
||||
if (FeedPreferences.TAG_UNTAGGED.equals(tag.getTitle())) {
|
||||
holder.title.setText(R.string.tag_untagged);
|
||||
}
|
||||
Glide.with(context).clear(holder.image);
|
||||
holder.image.setImageResource(R.drawable.ic_tag);
|
||||
holder.failure.setVisibility(View.GONE);
|
||||
|
||||
@ -268,7 +268,7 @@ public class ItemFragment extends Fragment {
|
||||
viewBinding.txtvPublished.setText(pubDateStr);
|
||||
viewBinding.txtvPublished.setContentDescription(DateFormatter.formatForAccessibility(item.getPubDate()));
|
||||
}
|
||||
if (item.getFeed().getState() != Feed.STATE_SUBSCRIBED) {
|
||||
if (item.getFeed().getState() == Feed.STATE_NOT_SUBSCRIBED) {
|
||||
viewBinding.nonSubscribedWarningLabel.setVisibility(View.VISIBLE);
|
||||
viewBinding.nonSubscribedWarningLabel.setOnClickListener(v -> openPodcast());
|
||||
}
|
||||
@ -349,12 +349,12 @@ public class ItemFragment extends Fragment {
|
||||
if (item == null) {
|
||||
return;
|
||||
}
|
||||
if (item.getFeed().getState() == Feed.STATE_SUBSCRIBED) {
|
||||
Fragment fragment = FeedItemlistFragment.newInstance(item.getFeedId());
|
||||
((MainActivity) getActivity()).loadChildFragment(fragment);
|
||||
} else {
|
||||
if (item.getFeed().getState() == Feed.STATE_NOT_SUBSCRIBED) {
|
||||
startActivity(new OnlineFeedviewActivityStarter(getContext(), item.getFeed().getDownloadUrl())
|
||||
.getIntent());
|
||||
} else {
|
||||
Fragment fragment = FeedItemlistFragment.newInstance(item.getFeedId());
|
||||
((MainActivity) getActivity()).loadChildFragment(fragment);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -181,10 +181,10 @@ public class ItemPagerFragment extends Fragment implements MaterialToolbar.OnMen
|
||||
if (item == null) {
|
||||
return;
|
||||
}
|
||||
if (item.getFeed().getState() == Feed.STATE_SUBSCRIBED) {
|
||||
new MainActivityStarter(getContext()).withOpenFeed(item.getFeedId()).withClearTop().start();
|
||||
} else {
|
||||
if (item.getFeed().getState() == Feed.STATE_NOT_SUBSCRIBED) {
|
||||
startActivity(new OnlineFeedviewActivityStarter(getContext(), item.getFeed().getDownloadUrl()).getIntent());
|
||||
} else {
|
||||
new MainActivityStarter(getContext()).withOpenFeed(item.getFeedId()).withClearTop().start();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -244,17 +244,7 @@ public class FeedInfoFragment extends Fragment implements MaterialToolbar.OnMenu
|
||||
viewBinding.supportUrl.setText(str.toString());
|
||||
}
|
||||
|
||||
if (feed.getState() == Feed.STATE_SUBSCRIBED) {
|
||||
long feedId = getArguments().getLong(EXTRA_FEED_ID);
|
||||
getParentFragmentManager().beginTransaction().replace(R.id.statisticsFragmentContainer,
|
||||
FeedStatisticsFragment.newInstance(feedId, false), "feed_statistics_fragment")
|
||||
.commitAllowingStateLoss();
|
||||
|
||||
viewBinding.statisticsButton.setOnClickListener(view -> {
|
||||
StatisticsFragment fragment = new StatisticsFragment();
|
||||
((MainActivity) getActivity()).loadChildFragment(fragment, TransitionEffect.SLIDE);
|
||||
});
|
||||
} else {
|
||||
if (feed.getState() == Feed.STATE_NOT_SUBSCRIBED) {
|
||||
viewBinding.statisticsHeading.setVisibility(View.GONE);
|
||||
viewBinding.statisticsFragmentContainer.setVisibility(View.GONE);
|
||||
viewBinding.supportHeadingLabel.setVisibility(View.GONE);
|
||||
@ -268,6 +258,16 @@ public class FeedInfoFragment extends Fragment implements MaterialToolbar.OnMenu
|
||||
getActivity().finish();
|
||||
startActivity(mainActivityStarter.getIntent());
|
||||
});
|
||||
} else {
|
||||
long feedId = getArguments().getLong(EXTRA_FEED_ID);
|
||||
getParentFragmentManager().beginTransaction().replace(R.id.statisticsFragmentContainer,
|
||||
FeedStatisticsFragment.newInstance(feedId, false), "feed_statistics_fragment")
|
||||
.commitAllowingStateLoss();
|
||||
|
||||
viewBinding.statisticsButton.setOnClickListener(view -> {
|
||||
StatisticsFragment fragment = new StatisticsFragment();
|
||||
((MainActivity) getActivity()).loadChildFragment(fragment, TransitionEffect.SLIDE);
|
||||
});
|
||||
}
|
||||
|
||||
refreshToolbarState();
|
||||
|
||||
@ -288,9 +288,11 @@ public class FeedItemlistFragment extends Fragment implements AdapterView.OnItem
|
||||
viewBinding.toolbar.getMenu().findItem(R.id.sort_items).setVisible(false);
|
||||
viewBinding.toolbar.getMenu().findItem(R.id.refresh_item).setVisible(false);
|
||||
viewBinding.toolbar.getMenu().findItem(R.id.rename_item).setVisible(false);
|
||||
viewBinding.toolbar.getMenu().findItem(R.id.remove_feed).setVisible(false);
|
||||
viewBinding.toolbar.getMenu().findItem(R.id.remove_archive_feed).setVisible(false);
|
||||
viewBinding.toolbar.getMenu().findItem(R.id.remove_all_inbox_item).setVisible(false);
|
||||
viewBinding.toolbar.getMenu().findItem(R.id.action_search).setVisible(false);
|
||||
} else if (feed.getState() == Feed.STATE_ARCHIVED) {
|
||||
viewBinding.toolbar.getMenu().findItem(R.id.sort_items).setVisible(false);
|
||||
}
|
||||
}
|
||||
|
||||
@ -330,12 +332,8 @@ public class FeedItemlistFragment extends Fragment implements AdapterView.OnItem
|
||||
} else if (item.getItemId() == R.id.sort_items) {
|
||||
SingleFeedSortDialog.newInstance(feed).show(getChildFragmentManager(), "SortDialog");
|
||||
return true;
|
||||
} 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();
|
||||
});
|
||||
} else if (item.getItemId() == R.id.remove_archive_feed) {
|
||||
new RemoveFeedDialogClose(Collections.singletonList(feed)).show(getParentFragmentManager(), null);
|
||||
return true;
|
||||
} else if (item.getItemId() == R.id.action_search) {
|
||||
((MainActivity) getActivity()).loadChildFragment(SearchFragment.newInstance(feed.getId(), feed.getTitle()));
|
||||
@ -347,6 +345,24 @@ public class FeedItemlistFragment extends Fragment implements AdapterView.OnItem
|
||||
return FeedMenuHandler.onMenuItemClicked(this, item.getItemId(), feed, showRemovedAllSnackbar);
|
||||
}
|
||||
|
||||
public static class RemoveFeedDialogClose extends RemoveFeedDialog {
|
||||
public RemoveFeedDialogClose(@NonNull List<Feed> feeds) {
|
||||
super(feeds);
|
||||
}
|
||||
|
||||
public RemoveFeedDialogClose() {
|
||||
super();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onRemoveButtonPressed() {
|
||||
// Make sure fragment is hidden before actually starting to delete
|
||||
((MainActivity) getActivity()).loadFragment(UserPreferences.getDefaultPage(), null);
|
||||
getActivity().getSupportFragmentManager().executePendingTransactions();
|
||||
super.onRemoveButtonPressed();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onContextItemSelected(@NonNull MenuItem item) {
|
||||
FeedItem selectedItem = adapter.getLongPressedItem();
|
||||
@ -497,7 +513,8 @@ public class FeedItemlistFragment extends Fragment implements AdapterView.OnItem
|
||||
} else {
|
||||
viewBinding.header.txtvFailure.setVisibility(View.GONE);
|
||||
}
|
||||
if (!feed.getPreferences().getKeepUpdated() && feed.getState() == Feed.STATE_SUBSCRIBED) {
|
||||
if ((!feed.getPreferences().getKeepUpdated() && feed.getState() != Feed.STATE_NOT_SUBSCRIBED)
|
||||
|| feed.getState() == Feed.STATE_ARCHIVED) {
|
||||
viewBinding.header.txtvUpdatesDisabled.setText(R.string.updates_disabled_label);
|
||||
viewBinding.header.txtvUpdatesDisabled.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
@ -506,7 +523,7 @@ public class FeedItemlistFragment extends Fragment implements AdapterView.OnItem
|
||||
viewBinding.header.txtvTitle.setText(feed.getTitle());
|
||||
viewBinding.header.txtvAuthor.setText(feed.getAuthor());
|
||||
viewBinding.header.descriptionContainer.setVisibility(View.GONE);
|
||||
if (feed.getState() != Feed.STATE_SUBSCRIBED) {
|
||||
if (feed.getState() == Feed.STATE_NOT_SUBSCRIBED) {
|
||||
viewBinding.header.descriptionContainer.setVisibility(View.VISIBLE);
|
||||
viewBinding.header.headerDescriptionLabel.setText(HtmlToPlainText.getPlainText(feed.getDescription()));
|
||||
viewBinding.header.subscribeNagLabel.setVisibility(
|
||||
@ -524,13 +541,16 @@ public class FeedItemlistFragment extends Fragment implements AdapterView.OnItem
|
||||
} else {
|
||||
viewBinding.header.txtvInformation.setVisibility(View.GONE);
|
||||
}
|
||||
boolean isSubscribed = feed.getState() == Feed.STATE_SUBSCRIBED;
|
||||
viewBinding.header.butShowInfo.setVisibility(isSubscribed ? View.VISIBLE : View.GONE);
|
||||
viewBinding.header.butFilter.setVisibility(isSubscribed ? View.VISIBLE : View.GONE);
|
||||
viewBinding.header.butShowSettings.setVisibility(isSubscribed ? View.VISIBLE : View.GONE);
|
||||
viewBinding.header.butSubscribe.setVisibility(isSubscribed ? View.GONE : View.VISIBLE);
|
||||
boolean isNotSubscribed = feed.getState() == Feed.STATE_NOT_SUBSCRIBED;
|
||||
boolean isArchived = feed.getState() == Feed.STATE_ARCHIVED;
|
||||
boolean showSettingsButtons = !isNotSubscribed && !isArchived;
|
||||
viewBinding.header.butShowInfo.setVisibility(!isNotSubscribed ? View.VISIBLE : View.GONE);
|
||||
viewBinding.header.butFilter.setVisibility(showSettingsButtons ? View.VISIBLE : View.GONE);
|
||||
viewBinding.header.butShowSettings.setVisibility(showSettingsButtons ? View.VISIBLE : View.GONE);
|
||||
viewBinding.header.butSubscribe.setVisibility(isNotSubscribed ? View.VISIBLE : View.GONE);
|
||||
viewBinding.header.butRestore.setVisibility(isArchived ? View.VISIBLE : View.GONE);
|
||||
|
||||
if (!isSubscribed && feed.getLastRefreshAttempt() < System.currentTimeMillis() - 1000L * 3600 * 24) {
|
||||
if (isNotSubscribed && feed.getLastRefreshAttempt() < System.currentTimeMillis() - 1000L * 3600 * 24) {
|
||||
FeedUpdateManager.getInstance().runOnce(getContext(), feed, true);
|
||||
}
|
||||
}
|
||||
@ -551,6 +571,12 @@ public class FeedItemlistFragment extends Fragment implements AdapterView.OnItem
|
||||
getActivity().finish();
|
||||
startActivity(mainActivityStarter.getIntent());
|
||||
});
|
||||
viewBinding.header.butRestore.setOnClickListener(v -> {
|
||||
if (feed == null) {
|
||||
return;
|
||||
}
|
||||
DBWriter.setFeedState(getContext(), feed, Feed.STATE_SUBSCRIBED);
|
||||
});
|
||||
viewBinding.header.butShowSettings.setOnClickListener(v -> {
|
||||
if (feed == null) {
|
||||
return;
|
||||
@ -749,7 +775,7 @@ public class FeedItemlistFragment extends Fragment implements AdapterView.OnItem
|
||||
@Override
|
||||
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
|
||||
super.onCreateContextMenu(menu, v, menuInfo);
|
||||
if (!inActionMode() && feed.getState() == Feed.STATE_SUBSCRIBED) {
|
||||
if (!inActionMode() && feed.getState() != Feed.STATE_NOT_SUBSCRIBED) {
|
||||
menu.findItem(R.id.multi_select).setVisible(true);
|
||||
}
|
||||
MenuItemUtils.setOnClickListeners(menu, FeedItemlistFragment.this::onContextItemSelected);
|
||||
|
||||
@ -1,84 +1,167 @@
|
||||
package de.danoeh.antennapod.ui.screen.feed;
|
||||
|
||||
import android.app.ProgressDialog;
|
||||
import android.animation.ValueAnimator;
|
||||
import android.app.Dialog;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.os.Bundle;
|
||||
import android.text.Html;
|
||||
import android.util.Log;
|
||||
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.animation.OvershootInterpolator;
|
||||
import android.widget.FrameLayout;
|
||||
import android.widget.LinearLayout;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import com.google.android.material.bottomsheet.BottomSheetBehavior;
|
||||
import com.google.android.material.bottomsheet.BottomSheetDialog;
|
||||
import com.google.android.material.bottomsheet.BottomSheetDialogFragment;
|
||||
import de.danoeh.antennapod.R;
|
||||
import de.danoeh.antennapod.ui.common.ConfirmationDialog;
|
||||
import de.danoeh.antennapod.databinding.RemoveFeedDialogBinding;
|
||||
import de.danoeh.antennapod.model.feed.Feed;
|
||||
import de.danoeh.antennapod.storage.database.DBWriter;
|
||||
import io.reactivex.rxjava3.core.Completable;
|
||||
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers;
|
||||
import io.reactivex.rxjava3.core.Completable;
|
||||
import io.reactivex.rxjava3.disposables.Disposable;
|
||||
import io.reactivex.rxjava3.schedulers.Schedulers;
|
||||
|
||||
public class RemoveFeedDialog {
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class RemoveFeedDialog extends BottomSheetDialogFragment {
|
||||
private static final String TAG = "RemoveFeedDialog";
|
||||
private static final String ARGUMENT_FEEDS = "feeds";
|
||||
|
||||
public static void show(Context context, Feed feed, @Nullable Runnable callback) {
|
||||
List<Feed> feeds = Collections.singletonList(feed);
|
||||
String message = getMessageId(context, feeds);
|
||||
showDialog(context, feeds, message, callback);
|
||||
protected List<Feed> feeds;
|
||||
private RemoveFeedDialogBinding binding;
|
||||
private Disposable disposable;
|
||||
|
||||
public RemoveFeedDialog() {
|
||||
// Required empty public constructor
|
||||
}
|
||||
|
||||
public static void show(Context context, List<Feed> feeds) {
|
||||
String message = getMessageId(context, feeds);
|
||||
showDialog(context, feeds, message, null);
|
||||
public RemoveFeedDialog(List<Feed> feeds) {
|
||||
Bundle args = new Bundle();
|
||||
args.putSerializable(ARGUMENT_FEEDS, new ArrayList<>(feeds));
|
||||
setArguments(args);
|
||||
}
|
||||
|
||||
private static void showDialog(Context context, List<Feed> feeds, String message, @Nullable Runnable callback) {
|
||||
ConfirmationDialog dialog = new ConfirmationDialog(context, R.string.remove_feed_label, message) {
|
||||
@Override
|
||||
public void onConfirmButtonPressed(DialogInterface clickedDialog) {
|
||||
@Nullable
|
||||
@Override
|
||||
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
|
||||
@Nullable Bundle savedInstanceState) {
|
||||
binding = RemoveFeedDialogBinding.inflate(inflater, container, false);
|
||||
if (getArguments() == null || !getArguments().containsKey(ARGUMENT_FEEDS)) {
|
||||
Log.e(TAG, "No feeds specified");
|
||||
dismiss();
|
||||
return binding.getRoot();
|
||||
}
|
||||
feeds = (List<Feed>) getArguments().getSerializable(ARGUMENT_FEEDS);
|
||||
if (feeds.size() == 1) {
|
||||
binding.selectionText.setText(feeds.get(0).getTitle());
|
||||
} else {
|
||||
binding.selectionText.setText(getResources()
|
||||
.getQuantityString(R.plurals.num_subscriptions, feeds.size(), feeds.size()));
|
||||
}
|
||||
boolean allArchived = true;
|
||||
for (Feed feed : feeds) {
|
||||
if (feed.getState() != Feed.STATE_ARCHIVED) {
|
||||
allArchived = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (allArchived) {
|
||||
binding.archiveButton.setVisibility(View.GONE);
|
||||
binding.explanationArchiveText.setVisibility(View.GONE);
|
||||
}
|
||||
binding.explanationArchiveText.setText(Html.fromHtml(getString(R.string.feed_delete_explanation_archive)));
|
||||
binding.explanationDeleteText.setText(Html.fromHtml(getString(R.string.feed_delete_explanation_delete)));
|
||||
binding.cancelButton.setOnClickListener(v -> dismiss());
|
||||
binding.removeButton.setOnClickListener(v -> showRemoveConfirm());
|
||||
binding.removeConfirmButton.setOnClickListener(v -> onRemoveButtonPressed());
|
||||
binding.archiveButton.setOnClickListener(v -> onArchiveButtonPressed());
|
||||
return binding.getRoot();
|
||||
}
|
||||
|
||||
if (callback != null) {
|
||||
callback.run();
|
||||
}
|
||||
@Override
|
||||
public void onDestroyView() {
|
||||
super.onDestroyView();
|
||||
if (disposable != null) {
|
||||
disposable.dispose();
|
||||
disposable = null;
|
||||
}
|
||||
binding = null;
|
||||
}
|
||||
|
||||
clickedDialog.dismiss();
|
||||
@NonNull
|
||||
@Override
|
||||
public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) {
|
||||
Dialog dialog = super.onCreateDialog(savedInstanceState);
|
||||
dialog.setOnShowListener(dialogInterface -> {
|
||||
BottomSheetDialog bottomSheetDialog = (BottomSheetDialog) dialogInterface;
|
||||
setupFullHeight(bottomSheetDialog);
|
||||
});
|
||||
return dialog;
|
||||
}
|
||||
|
||||
ProgressDialog progressDialog = new ProgressDialog(context);
|
||||
progressDialog.setMessage(context.getString(R.string.feed_remover_msg));
|
||||
progressDialog.setIndeterminate(true);
|
||||
progressDialog.setCancelable(false);
|
||||
progressDialog.show();
|
||||
private void setupFullHeight(BottomSheetDialog bottomSheetDialog) {
|
||||
FrameLayout bottomSheet = bottomSheetDialog.findViewById(com.google.android.material.R.id.design_bottom_sheet);
|
||||
if (bottomSheet != null) {
|
||||
BottomSheetBehavior<FrameLayout> behavior = BottomSheetBehavior.from(bottomSheet);
|
||||
ViewGroup.LayoutParams layoutParams = bottomSheet.getLayoutParams();
|
||||
bottomSheet.setLayoutParams(layoutParams);
|
||||
behavior.setState(BottomSheetBehavior.STATE_EXPANDED);
|
||||
}
|
||||
}
|
||||
|
||||
Completable.fromAction(() -> {
|
||||
protected void onRemoveButtonPressed() {
|
||||
Context context = getContext();
|
||||
if (context == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
binding.progressBar.setVisibility(View.VISIBLE);
|
||||
binding.removeConfirmButton.setVisibility(View.GONE);
|
||||
binding.archiveButton.setVisibility(View.GONE);
|
||||
binding.cancelButton.setVisibility(View.GONE);
|
||||
|
||||
disposable = Completable.fromAction(
|
||||
() -> {
|
||||
for (Feed feed : feeds) {
|
||||
DBWriter.deleteFeed(context, feed.getId()).get();
|
||||
}
|
||||
})
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(
|
||||
() -> {
|
||||
Log.d(TAG, "Feed(s) deleted");
|
||||
progressDialog.dismiss();
|
||||
}, error -> {
|
||||
Log.e(TAG, Log.getStackTraceString(error));
|
||||
progressDialog.dismiss();
|
||||
});
|
||||
}
|
||||
};
|
||||
dialog.createNewDialog().show();
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(
|
||||
() -> {
|
||||
Log.d(TAG, "Feed(s) deleted");
|
||||
dismiss();
|
||||
}, error -> {
|
||||
Log.e(TAG, Log.getStackTraceString(error));
|
||||
dismiss();
|
||||
});
|
||||
}
|
||||
|
||||
private static String getMessageId(Context context, List<Feed> feeds) {
|
||||
if (feeds.size() == 1) {
|
||||
if (feeds.get(0).isLocalFeed()) {
|
||||
return context.getString(R.string.feed_delete_confirmation_local_msg, feeds.get(0).getTitle());
|
||||
} else {
|
||||
return context.getString(R.string.feed_delete_confirmation_msg, feeds.get(0).getTitle());
|
||||
}
|
||||
} else {
|
||||
return context.getString(R.string.feed_delete_confirmation_msg_batch);
|
||||
private void onArchiveButtonPressed() {
|
||||
dismiss();
|
||||
for (Feed feed : feeds) {
|
||||
DBWriter.setFeedState(getContext(), feed, Feed.STATE_ARCHIVED);
|
||||
}
|
||||
}
|
||||
|
||||
private void showRemoveConfirm() {
|
||||
binding.removeButton.setVisibility(View.GONE);
|
||||
binding.removeConfirmButton.setVisibility(View.VISIBLE);
|
||||
LinearLayout.LayoutParams params = (LinearLayout.LayoutParams) binding.removeConfirmButton.getLayoutParams();
|
||||
ValueAnimator animator = ValueAnimator.ofFloat(1.0f, 2.0f);
|
||||
animator.addUpdateListener(animation -> {
|
||||
params.weight = (float) animation.getAnimatedValue();
|
||||
binding.removeConfirmButton.setLayoutParams(params);
|
||||
});
|
||||
animator.setDuration(400);
|
||||
animator.setInterpolator(new OvershootInterpolator(3.0f));
|
||||
animator.start();
|
||||
}
|
||||
}
|
||||
|
||||
@ -14,12 +14,14 @@ import androidx.recyclerview.widget.GridLayoutManager;
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
|
||||
import de.danoeh.antennapod.R;
|
||||
import de.danoeh.antennapod.databinding.EditTagsDialogBinding;
|
||||
import de.danoeh.antennapod.model.feed.Feed;
|
||||
import de.danoeh.antennapod.model.feed.FeedCounter;
|
||||
import de.danoeh.antennapod.model.feed.FeedOrder;
|
||||
import de.danoeh.antennapod.model.feed.FeedPreferences;
|
||||
import de.danoeh.antennapod.storage.database.DBReader;
|
||||
import de.danoeh.antennapod.storage.database.DBWriter;
|
||||
import de.danoeh.antennapod.storage.database.NavDrawerData;
|
||||
import de.danoeh.antennapod.storage.preferences.UserPreferences;
|
||||
import de.danoeh.antennapod.ui.SimpleChipAdapter;
|
||||
import de.danoeh.antennapod.ui.view.ItemOffsetDecoration;
|
||||
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers;
|
||||
@ -76,6 +78,8 @@ public class TagSettingsDialog extends DialogFragment {
|
||||
};
|
||||
viewBinding.tagsRecycler.setAdapter(adapter);
|
||||
viewBinding.rootFolderCheckbox.setChecked(commonTags.contains(FeedPreferences.TAG_ROOT));
|
||||
viewBinding.rootFolderCheckbox.setVisibility(UserPreferences.isBottomNavigationEnabled()
|
||||
? View.GONE : View.VISIBLE);
|
||||
|
||||
viewBinding.newTagTextInput.setEndIconOnClickListener(v ->
|
||||
addTag(viewBinding.newTagEditText.getText().toString().trim()));
|
||||
@ -109,10 +113,12 @@ public class TagSettingsDialog extends DialogFragment {
|
||||
private void loadTags() {
|
||||
Observable.fromCallable(
|
||||
() -> {
|
||||
NavDrawerData data = DBReader.getNavDrawerData(null, FeedOrder.ALPHABETICAL, FeedCounter.SHOW_NONE);
|
||||
NavDrawerData data = DBReader.getNavDrawerData(null, FeedOrder.ALPHABETICAL, FeedCounter.SHOW_NONE,
|
||||
Feed.STATE_SUBSCRIBED);
|
||||
List<String> folders = new ArrayList<>();
|
||||
for (NavDrawerData.TagItem item : data.tags) {
|
||||
if (!FeedPreferences.TAG_ROOT.equals(item.getTitle())) {
|
||||
if (!FeedPreferences.TAG_ROOT.equals(item.getTitle())
|
||||
&& !FeedPreferences.TAG_UNTAGGED.equals(item.getTitle())) {
|
||||
folders.add(item.getTitle());
|
||||
}
|
||||
}
|
||||
@ -131,7 +137,7 @@ public class TagSettingsDialog extends DialogFragment {
|
||||
}
|
||||
|
||||
private void addTag(String name) {
|
||||
if (TextUtils.isEmpty(name) || displayedTags.contains(name)) {
|
||||
if (TextUtils.isEmpty(name) || displayedTags.contains(name) || FeedPreferences.TAG_UNTAGGED.equals(name)) {
|
||||
return;
|
||||
}
|
||||
displayedTags.add(name);
|
||||
|
||||
@ -103,7 +103,10 @@ public class SubscriptionsSection extends HomeSection {
|
||||
Collections.sort(statisticsData, (item1, item2) ->
|
||||
Long.compare(item2.timePlayed, item1.timePlayed));
|
||||
List<Feed> feeds = new ArrayList<>();
|
||||
for (int i = 0; i < statisticsData.size() && i < NUM_FEEDS; i++) {
|
||||
for (int i = 0; i < statisticsData.size() && feeds.size() < NUM_FEEDS; i++) {
|
||||
if (statisticsData.get(i).feed.getState() != Feed.STATE_SUBSCRIBED) {
|
||||
continue;
|
||||
}
|
||||
feeds.add(statisticsData.get(i).feed);
|
||||
}
|
||||
listAdapter.setDummyViews(0);
|
||||
|
||||
@ -235,10 +235,10 @@ public class OnlineFeedViewActivity extends AppCompatActivity {
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(subscribedFeed -> {
|
||||
if (subscribedFeed.getState() == Feed.STATE_SUBSCRIBED) {
|
||||
openFeed(subscribedFeed.getId());
|
||||
} else {
|
||||
if (subscribedFeed.getState() == Feed.STATE_NOT_SUBSCRIBED) {
|
||||
showFeedFragment(subscribedFeed.getId());
|
||||
} else {
|
||||
openFeed(subscribedFeed.getId());
|
||||
}
|
||||
}, error -> Log.e(TAG, Log.getStackTraceString(error)), () -> startFeedDownload(url));
|
||||
return null;
|
||||
|
||||
@ -514,10 +514,10 @@ public class AudioPlayerFragment extends Fragment implements
|
||||
if (feed == null) {
|
||||
return;
|
||||
}
|
||||
if (feed.getState() == Feed.STATE_SUBSCRIBED) {
|
||||
new MainActivityStarter(getContext()).withOpenFeed(feed.getId()).withClearTop().start();
|
||||
} else {
|
||||
if (feed.getState() == Feed.STATE_NOT_SUBSCRIBED) {
|
||||
startActivity(new OnlineFeedviewActivityStarter(getContext(), feed.getDownloadUrl()).getIntent());
|
||||
} else {
|
||||
new MainActivityStarter(getContext()).withOpenFeed(feed.getId()).withClearTop().start();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -167,10 +167,10 @@ public class CoverFragment extends Fragment {
|
||||
if (feed == null) {
|
||||
return;
|
||||
}
|
||||
if (feed.getState() == Feed.STATE_SUBSCRIBED) {
|
||||
new MainActivityStarter(getContext()).withOpenFeed(feed.getId()).withClearTop().start();
|
||||
} else {
|
||||
if (feed.getState() == Feed.STATE_NOT_SUBSCRIBED) {
|
||||
startActivity(new OnlineFeedviewActivityStarter(getContext(), feed.getDownloadUrl()).getIntent());
|
||||
} else {
|
||||
new MainActivityStarter(getContext()).withOpenFeed(feed.getId()).withClearTop().start();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -58,8 +58,9 @@ public abstract class FeedMenuHandler {
|
||||
.show(fragment.getChildFragmentManager(), TagSettingsDialog.TAG);
|
||||
} else if (menuItemId == R.id.rename_item) {
|
||||
new RenameFeedDialog(fragment.getActivity(), selectedFeed).show();
|
||||
} else if (menuItemId == R.id.remove_feed) {
|
||||
RemoveFeedDialog.show(context, selectedFeed, null);
|
||||
} else if (menuItemId == R.id.remove_archive_feed) {
|
||||
new RemoveFeedDialog(Collections.singletonList(selectedFeed))
|
||||
.show(fragment.getChildFragmentManager(), null);
|
||||
} else if (menuItemId == R.id.share_feed) {
|
||||
ShareUtils.shareFeedLink(context, selectedFeed);
|
||||
} else {
|
||||
|
||||
@ -34,8 +34,8 @@ public class FeedMultiSelectActionHandler {
|
||||
}
|
||||
|
||||
public void handleAction(int id) {
|
||||
if (id == R.id.remove_feed) {
|
||||
RemoveFeedDialog.show(activity, selectedItems);
|
||||
if (id == R.id.remove_archive_feed) {
|
||||
new RemoveFeedDialog(selectedItems).show(activity.getSupportFragmentManager(), null);
|
||||
} else if (id == R.id.notify_new_episodes) {
|
||||
notifyNewEpisodesPrefHandler();
|
||||
} else if (id == R.id.keep_updated) {
|
||||
|
||||
@ -48,6 +48,7 @@ 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.Locale;
|
||||
|
||||
@ -62,7 +63,7 @@ public class SubscriptionFragment extends Fragment
|
||||
private static final String PREF_NUM_COLUMNS = "columns";
|
||||
private static final String PREF_LAST_TAG = "last_tag";
|
||||
private static final String KEY_UP_ARROW = "up_arrow";
|
||||
private static final String ARGUMENT_FOLDER = "folder";
|
||||
private static final String ARGUMENT_STATE = "state";
|
||||
|
||||
private static final int MIN_NUM_COLUMNS = 1;
|
||||
private static final int[] COLUMN_CHECKBOX_IDS = {
|
||||
@ -92,11 +93,12 @@ public class SubscriptionFragment extends Fragment
|
||||
private FloatingSelectMenu floatingSelectMenu;
|
||||
private RecyclerView.ItemDecoration itemDecoration;
|
||||
private List<Feed> feeds;
|
||||
private int stateToShow = Feed.STATE_SUBSCRIBED;
|
||||
|
||||
public static SubscriptionFragment newInstance(String folderTitle) {
|
||||
public static SubscriptionFragment newInstance(int state) {
|
||||
SubscriptionFragment fragment = new SubscriptionFragment();
|
||||
Bundle args = new Bundle();
|
||||
args.putString(ARGUMENT_FOLDER, folderTitle);
|
||||
args.putInt(ARGUMENT_STATE, state);
|
||||
fragment.setArguments(args);
|
||||
return fragment;
|
||||
}
|
||||
@ -105,6 +107,9 @@ public class SubscriptionFragment extends Fragment
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
prefs = requireActivity().getSharedPreferences(PREFS, Context.MODE_PRIVATE);
|
||||
if (getArguments() != null) {
|
||||
stateToShow = getArguments().getInt(ARGUMENT_STATE, Feed.STATE_SUBSCRIBED);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -172,6 +177,14 @@ public class SubscriptionFragment extends Fragment
|
||||
|
||||
floatingSelectMenu = root.findViewById(R.id.floatingSelectMenu);
|
||||
floatingSelectMenu.inflate(R.menu.nav_feed_action_speeddial);
|
||||
if (stateToShow == Feed.STATE_ARCHIVED) {
|
||||
toolbar.setTitle(R.string.archive_feed_label_noun);
|
||||
floatingSelectMenu.getMenu().removeItem(R.id.keep_updated);
|
||||
floatingSelectMenu.getMenu().removeItem(R.id.notify_new_episodes);
|
||||
floatingSelectMenu.getMenu().removeItem(R.id.autodownload);
|
||||
floatingSelectMenu.getMenu().removeItem(R.id.autoDeleteDownload);
|
||||
floatingSelectMenu.getMenu().removeItem(R.id.playback_speed);
|
||||
}
|
||||
floatingSelectMenu.setOnMenuItemClickListener(menuItem -> {
|
||||
new FeedMultiSelectActionHandler(getActivity(), subscriptionAdapter.getSelectedItems())
|
||||
.handleAction(menuItem.getItemId());
|
||||
@ -195,7 +208,11 @@ public class SubscriptionFragment extends Fragment
|
||||
loadSubscriptionsAndTags();
|
||||
}
|
||||
};
|
||||
tagAdapter.setSelectedTag(prefs.getString(PREF_LAST_TAG, FeedPreferences.TAG_ROOT));
|
||||
if (stateToShow == Feed.STATE_SUBSCRIBED) {
|
||||
tagAdapter.setSelectedTag(prefs.getString(PREF_LAST_TAG, FeedPreferences.TAG_ROOT));
|
||||
} else {
|
||||
tagAdapter.setSelectedTag(FeedPreferences.TAG_ROOT);
|
||||
}
|
||||
tagsRecycler.setAdapter(tagAdapter);
|
||||
return root;
|
||||
}
|
||||
@ -250,7 +267,11 @@ public class SubscriptionFragment extends Fragment
|
||||
setColumnNumber(5);
|
||||
return true;
|
||||
} else if (itemId == R.id.action_search) {
|
||||
((MainActivity) getActivity()).loadChildFragment(SearchFragment.newInstance());
|
||||
if (stateToShow == Feed.STATE_ARCHIVED) {
|
||||
((MainActivity) getActivity()).loadChildFragment(SearchFragment.newInstanceArchive());
|
||||
} else {
|
||||
((MainActivity) getActivity()).loadChildFragment(SearchFragment.newInstance());
|
||||
}
|
||||
return true;
|
||||
} else if (itemId == R.id.action_statistics) {
|
||||
((MainActivity) getActivity()).loadChildFragment(new StatisticsFragment());
|
||||
@ -259,6 +280,10 @@ public class SubscriptionFragment extends Fragment
|
||||
item.setChecked(!item.isChecked());
|
||||
UserPreferences.setShouldShowSubscriptionTitle(item.isChecked());
|
||||
subscriptionAdapter.notifyDataSetChanged();
|
||||
} else if (itemId == R.id.show_archive) {
|
||||
Fragment fragment = SubscriptionFragment.newInstance(Feed.STATE_ARCHIVED);
|
||||
((MainActivity) getActivity()).loadChildFragment(fragment);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@ -303,7 +328,9 @@ public class SubscriptionFragment extends Fragment
|
||||
public void onPause() {
|
||||
super.onPause();
|
||||
scrollPosition = getScrollPosition();
|
||||
prefs.edit().putString(PREF_LAST_TAG, tagAdapter.getSelectedTag()).apply();
|
||||
if (stateToShow == Feed.STATE_SUBSCRIBED) {
|
||||
prefs.edit().putString(PREF_LAST_TAG, tagAdapter.getSelectedTag()).apply();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -327,16 +354,19 @@ public class SubscriptionFragment extends Fragment
|
||||
() -> {
|
||||
NavDrawerData navDrawerData = DBReader.getNavDrawerData(
|
||||
UserPreferences.getSubscriptionsFilter(),
|
||||
UserPreferences.getFeedOrder(), UserPreferences.getFeedCounterSetting());
|
||||
List<NavDrawerData.TagItem> tags = DBReader.getAllTags();
|
||||
UserPreferences.getFeedOrder(), UserPreferences.getFeedCounterSetting(),
|
||||
stateToShow);
|
||||
List<NavDrawerData.TagItem> tags = DBReader.getAllTags(stateToShow);
|
||||
return new Pair<>(navDrawerData, tags);
|
||||
})
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(
|
||||
result -> {
|
||||
List<Feed> openedFolderFeeds = result.first.feeds;
|
||||
if (!FeedPreferences.TAG_ROOT.equals(tagAdapter.getSelectedTag())) {
|
||||
List<Feed> openedFolderFeeds = Collections.emptyList();
|
||||
if (FeedPreferences.TAG_ROOT.equals(tagAdapter.getSelectedTag())) {
|
||||
openedFolderFeeds = result.first.feeds;
|
||||
} else {
|
||||
for (NavDrawerData.TagItem tag : result.first.tags) { // Filtered list
|
||||
if (tag.getTitle().equals(tagAdapter.getSelectedTag())) {
|
||||
openedFolderFeeds = tag.getFeeds();
|
||||
@ -359,7 +389,15 @@ public class SubscriptionFragment extends Fragment
|
||||
emptyView.updateVisibility();
|
||||
if (tagAdapter != null) {
|
||||
tagAdapter.setTags(result.second);
|
||||
tagsRecycler.setVisibility(result.second.size() > 1 ? View.VISIBLE : View.GONE);
|
||||
boolean shouldShowTags = false;
|
||||
for (NavDrawerData.TagItem tag : result.second) {
|
||||
if (!FeedPreferences.TAG_ROOT.equals(tag.getTitle())
|
||||
&& !FeedPreferences.TAG_UNTAGGED.equals(tag.getTitle())) {
|
||||
shouldShowTags = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
tagsRecycler.setVisibility(shouldShowTags ? View.VISIBLE : View.GONE);
|
||||
}
|
||||
}, error -> {
|
||||
Log.e(TAG, Log.getStackTraceString(error));
|
||||
|
||||
@ -58,6 +58,9 @@ public class SubscriptionTagAdapter extends RecyclerView.Adapter<SubscriptionTag
|
||||
NavDrawerData.TagItem tag = tags.get(position);
|
||||
if (FeedPreferences.TAG_ROOT.equals(tag.getTitle())) {
|
||||
holder.chip.setText(R.string.tag_all);
|
||||
} else if (FeedPreferences
|
||||
.TAG_UNTAGGED.equals(tag.getTitle())) {
|
||||
holder.chip.setText(R.string.tag_untagged);
|
||||
} else {
|
||||
String title = tag.getTitle();
|
||||
if (title.length() > 20) {
|
||||
@ -91,7 +94,9 @@ public class SubscriptionTagAdapter extends RecyclerView.Adapter<SubscriptionTag
|
||||
|
||||
@Override
|
||||
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
|
||||
if (longPressedItem == null || FeedPreferences.TAG_ROOT.equals(longPressedItem.getTitle())) {
|
||||
if (longPressedItem == null
|
||||
|| FeedPreferences.TAG_ROOT.equals(longPressedItem.getTitle())
|
||||
|| FeedPreferences.TAG_UNTAGGED.equals(longPressedItem.getTitle())) {
|
||||
return;
|
||||
}
|
||||
MenuInflater inflater = activityRef.get().getMenuInflater();
|
||||
|
||||
@ -37,6 +37,15 @@
|
||||
android:layout_marginVertical="4dp"
|
||||
tools:visibility="visible" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/butRestore"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/restore_archive_label"
|
||||
android:visibility="gone"
|
||||
android:layout_marginVertical="4dp"
|
||||
tools:visibility="visible" />
|
||||
|
||||
<ImageButton
|
||||
android:id="@+id/butShowInfo"
|
||||
android:layout_width="48dp"
|
||||
|
||||
106
app/src/main/res/layout/remove_feed_dialog.xml
Normal file
106
app/src/main/res/layout/remove_feed_dialog.xml
Normal file
@ -0,0 +1,106 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<ScrollView
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:paddingLeft="24dp"
|
||||
android:paddingTop="24dp"
|
||||
android:paddingRight="24dp"
|
||||
android:paddingBottom="8dp">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/title"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/remove_archive_feed_label"
|
||||
android:textAppearance="@style/TextAppearance.Material3.HeadlineSmall"
|
||||
android:layout_marginBottom="16dp" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/selectionText"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:textAppearance="@style/TextAppearance.Material3.BodyMedium"
|
||||
android:layout_marginBottom="8dp" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/explanationDeleteText"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/feed_delete_explanation_delete"
|
||||
android:textAppearance="@style/TextAppearance.Material3.BodyMedium"
|
||||
android:layout_marginBottom="8dp" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/explanationArchiveText"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/feed_delete_explanation_archive"
|
||||
android:textAppearance="@style/TextAppearance.Material3.BodyMedium"
|
||||
android:layout_marginBottom="16dp" />
|
||||
|
||||
<ProgressBar
|
||||
android:id="@+id/progressBar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:visibility="gone"
|
||||
android:indeterminate="true"
|
||||
style="?android:attr/progressBarStyle" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<com.google.android.material.button.MaterialButton
|
||||
android:id="@+id/cancelButton"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:layout_marginEnd="8dp"
|
||||
android:paddingHorizontal="8dp"
|
||||
android:text="@string/cancel_label"
|
||||
style="@style/Widget.Material3.Button.OutlinedButton" />
|
||||
|
||||
<com.google.android.material.button.MaterialButton
|
||||
android:id="@+id/removeButton"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:layout_marginEnd="8dp"
|
||||
android:paddingHorizontal="8dp"
|
||||
android:text="@string/remove_feed_label"
|
||||
style="@style/Widget.Material3.Button.OutlinedButton" />
|
||||
|
||||
<com.google.android.material.button.MaterialButton
|
||||
android:id="@+id/removeConfirmButton"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:layout_marginEnd="8dp"
|
||||
android:paddingHorizontal="8dp"
|
||||
android:text="@string/remove_feed_label"
|
||||
android:backgroundTint="?attr/colorError"
|
||||
android:textColor="?attr/colorOnError"
|
||||
android:visibility="gone"
|
||||
style="@style/Widget.Material3.Button.OutlinedButton" />
|
||||
|
||||
<com.google.android.material.button.MaterialButton
|
||||
android:id="@+id/archiveButton"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:paddingHorizontal="8dp"
|
||||
android:text="@string/archive_feed_label_verb"
|
||||
style="@style/Widget.Material3.Button" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</ScrollView>
|
||||
@ -56,10 +56,10 @@
|
||||
custom:showAsAction="never" />
|
||||
|
||||
<item
|
||||
android:id="@+id/remove_feed"
|
||||
android:id="@+id/remove_archive_feed"
|
||||
android:icon="@drawable/ic_delete"
|
||||
android:menuCategory="container"
|
||||
android:title="@string/remove_feed_label"
|
||||
android:title="@string/remove_archive_feed_label"
|
||||
android:visible="true"
|
||||
custom:showAsAction="collapseActionView">
|
||||
</item>
|
||||
|
||||
@ -1,9 +1,9 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<menu xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item
|
||||
android:id="@+id/remove_feed"
|
||||
android:id="@+id/remove_archive_feed"
|
||||
android:menuCategory="container"
|
||||
android:title="@string/remove_feed_label"
|
||||
android:title="@string/remove_archive_feed_label"
|
||||
android:icon="@drawable/ic_delete"/>
|
||||
<item
|
||||
android:id="@+id/keep_updated"
|
||||
|
||||
@ -17,9 +17,9 @@
|
||||
android:title="@string/rename_feed_label" />
|
||||
|
||||
<item
|
||||
android:id="@+id/remove_feed"
|
||||
android:id="@+id/remove_archive_feed"
|
||||
android:menuCategory="container"
|
||||
android:title="@string/remove_feed_label" />
|
||||
android:title="@string/remove_archive_feed_label" />
|
||||
|
||||
<item
|
||||
android:id="@+id/share_feed"
|
||||
|
||||
@ -59,4 +59,9 @@
|
||||
android:title="@string/pref_show_subscription_title"
|
||||
android:checkable="true"
|
||||
custom:showAsAction="never" />
|
||||
|
||||
<item
|
||||
android:id="@+id/show_archive"
|
||||
android:title="@string/archive_feed_label_noun"
|
||||
custom:showAsAction="never" />
|
||||
</menu>
|
||||
|
||||
@ -19,6 +19,7 @@ public class Feed {
|
||||
public static final int FEEDFILETYPE_FEED = 0;
|
||||
public static final int STATE_SUBSCRIBED = 0;
|
||||
public static final int STATE_NOT_SUBSCRIBED = 1;
|
||||
public static final int STATE_ARCHIVED = 2;
|
||||
public static final String TYPE_RSS2 = "rss";
|
||||
public static final String TYPE_ATOM1 = "atom";
|
||||
public static final String PREFIX_LOCAL_FOLDER = "antennapod_local:";
|
||||
|
||||
@ -120,7 +120,7 @@ public class FeedItemFilter implements Serializable {
|
||||
&& item.getMedia().getLastPlayedTimeHistory().getTime() == 0) {
|
||||
return false;
|
||||
} else if (!includeNotSubscribed && item.getFeed() != null
|
||||
&& item.getFeed().getState() != Feed.STATE_SUBSCRIBED) {
|
||||
&& item.getFeed().getState() == Feed.STATE_NOT_SUBSCRIBED) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
||||
@ -14,6 +14,7 @@ public class FeedPreferences implements Serializable {
|
||||
|
||||
public static final float SPEED_USE_GLOBAL = -1;
|
||||
public static final String TAG_ROOT = "#root";
|
||||
public static final String TAG_UNTAGGED = "#untagged";
|
||||
public static final String TAG_SEPARATOR = "\u001e";
|
||||
|
||||
public enum AutoDeleteAction {
|
||||
|
||||
@ -59,7 +59,7 @@ public class ItunesTopListLoader {
|
||||
Set<String> subscribedPodcastsSet = new HashSet<>();
|
||||
for (Feed subscribedFeed : subscribedFeeds) {
|
||||
if (subscribedFeed.getTitle() != null && subscribedFeed.getAuthor() != null
|
||||
&& subscribedFeed.getState() == Feed.STATE_SUBSCRIBED) {
|
||||
&& subscribedFeed.getState() != Feed.STATE_NOT_SUBSCRIBED) {
|
||||
subscribedPodcastsSet.add(subscribedFeed.getTitle().trim());
|
||||
}
|
||||
}
|
||||
|
||||
@ -114,7 +114,7 @@ public class MediaDownloadedHandler implements Runnable {
|
||||
FeedMedia.FEEDFILETYPE_FEEDMEDIA, false, DownloadError.ERROR_DB_ACCESS_ERROR, e.getMessage());
|
||||
}
|
||||
|
||||
if (item != null && item.getFeed().getState() == Feed.STATE_SUBSCRIBED) {
|
||||
if (item != null && item.getFeed().getState() != Feed.STATE_NOT_SUBSCRIBED) {
|
||||
SynchronizationQueue.getInstance().enqueueEpisodeAction(
|
||||
new EpisodeAction.Builder(item, EpisodeAction.DOWNLOAD)
|
||||
.currentTimestamp()
|
||||
|
||||
@ -342,7 +342,8 @@ public class DbReaderTest {
|
||||
final int numItems = 10;
|
||||
DbTestUtils.saveFeedlist(numFeeds, numItems, true);
|
||||
NavDrawerData navDrawerData = DBReader.getNavDrawerData(
|
||||
UserPreferences.getSubscriptionsFilter(), FeedOrder.COUNTER, FeedCounter.SHOW_NEW);
|
||||
UserPreferences.getSubscriptionsFilter(), FeedOrder.COUNTER, FeedCounter.SHOW_NEW,
|
||||
Feed.STATE_SUBSCRIBED);
|
||||
assertEquals(numFeeds, navDrawerData.feeds.size());
|
||||
assertEquals(0, navDrawerData.numNewItems);
|
||||
assertEquals(0, navDrawerData.queueSize);
|
||||
@ -372,7 +373,8 @@ public class DbReaderTest {
|
||||
adapter.close();
|
||||
|
||||
NavDrawerData navDrawerData = DBReader.getNavDrawerData(
|
||||
UserPreferences.getSubscriptionsFilter(), FeedOrder.COUNTER, FeedCounter.SHOW_NEW);
|
||||
UserPreferences.getSubscriptionsFilter(), FeedOrder.COUNTER, FeedCounter.SHOW_NEW,
|
||||
Feed.STATE_SUBSCRIBED);
|
||||
assertEquals(numFeeds, navDrawerData.feeds.size());
|
||||
assertEquals(numNew, navDrawerData.numNewItems);
|
||||
assertEquals(numQueue, navDrawerData.queueSize);
|
||||
|
||||
@ -113,7 +113,7 @@ public class SynchronizationQueueImpl extends SynchronizationQueue {
|
||||
return;
|
||||
}
|
||||
if (media.getItem() == null || media.getItem().getFeed().isLocalFeed()
|
||||
|| media.getItem().getFeed().getState() != Feed.STATE_SUBSCRIBED) {
|
||||
|| media.getItem().getFeed().getState() == Feed.STATE_NOT_SUBSCRIBED) {
|
||||
return;
|
||||
}
|
||||
if (media.getStartPosition() < 0 || (!completed && media.getStartPosition() >= media.getPosition())) {
|
||||
|
||||
@ -1885,7 +1885,7 @@ public class PlaybackService extends MediaBrowserServiceCompat {
|
||||
return;
|
||||
}
|
||||
|
||||
List<FeedItem> results = DBReader.searchFeedItems(0, query);
|
||||
List<FeedItem> results = DBReader.searchFeedItems(0, query, Feed.STATE_SUBSCRIBED);
|
||||
if (results.size() > 0 && results.get(0).getMedia() != null) {
|
||||
FeedMedia media = results.get(0).getMedia();
|
||||
startPlaying(media, false);
|
||||
|
||||
@ -666,17 +666,22 @@ public final class DBReader {
|
||||
*/
|
||||
@NonNull
|
||||
public static NavDrawerData getNavDrawerData(@Nullable SubscriptionsFilter subscriptionsFilter,
|
||||
FeedOrder feedOrder, FeedCounter feedCounter) {
|
||||
FeedOrder feedOrder, FeedCounter feedCounter, int feedState) {
|
||||
PodDBAdapter adapter = PodDBAdapter.getInstance();
|
||||
adapter.open();
|
||||
|
||||
final Map<Long, Integer> feedCounters = adapter.getFeedCounters(feedCounter);
|
||||
List<Feed> feeds = getFeedList();
|
||||
|
||||
List<Feed> allFeeds = getFeedList();
|
||||
List<Feed> typeFilteredFeeds = new ArrayList<>();
|
||||
for (Feed feed : allFeeds) {
|
||||
if (feed.getState() == feedState) {
|
||||
typeFilteredFeeds.add(feed);
|
||||
}
|
||||
}
|
||||
if (subscriptionsFilter == null) {
|
||||
subscriptionsFilter = new SubscriptionsFilter("");
|
||||
}
|
||||
feeds = SubscriptionsFilterExecutor.filter(feeds, feedCounters, subscriptionsFilter);
|
||||
List<Feed> feeds = SubscriptionsFilterExecutor.filter(typeFilteredFeeds, feedCounters, subscriptionsFilter);
|
||||
|
||||
Comparator<Feed> comparator;
|
||||
switch (feedOrder) {
|
||||
@ -737,8 +742,13 @@ public final class DBReader {
|
||||
final int numNewItems = getTotalEpisodeCount(new FeedItemFilter(FeedItemFilter.NEW));
|
||||
final int numDownloadedItems = getTotalEpisodeCount(new FeedItemFilter(FeedItemFilter.DOWNLOADED));
|
||||
|
||||
NavDrawerData.TagItem untaggedTag = new NavDrawerData.TagItem(FeedPreferences.TAG_UNTAGGED);
|
||||
Map<String, NavDrawerData.TagItem> tags = new HashMap<>();
|
||||
for (Feed feed : feeds) {
|
||||
if (feed.getPreferences().getTags().isEmpty() || (feed.getPreferences().getTags().size()) == 1
|
||||
&& feed.getPreferences().getTags().contains(FeedPreferences.TAG_ROOT)) {
|
||||
untaggedTag.addFeed(feed, 0);
|
||||
}
|
||||
for (String tag : feed.getPreferences().getTags()) {
|
||||
if (!tags.containsKey(tag)) {
|
||||
tags.put(tag, new NavDrawerData.TagItem(tag));
|
||||
@ -750,16 +760,31 @@ public final class DBReader {
|
||||
List<NavDrawerData.TagItem> tagsSorted = new ArrayList<>(tags.values());
|
||||
Collections.sort(tagsSorted, (o1, o2) -> o1.getTitle().compareToIgnoreCase(o2.getTitle()));
|
||||
|
||||
if (!untaggedTag.getFeeds().isEmpty()) {
|
||||
tagsSorted.add(0, untaggedTag);
|
||||
}
|
||||
|
||||
NavDrawerData result = new NavDrawerData(feeds, tagsSorted,
|
||||
queueSize, numNewItems, numDownloadedItems, feedCounters);
|
||||
adapter.close();
|
||||
return result;
|
||||
}
|
||||
|
||||
public static List<NavDrawerData.TagItem> getAllTags() {
|
||||
public static List<NavDrawerData.TagItem> getAllTags(int feedState) {
|
||||
Map<String, NavDrawerData.TagItem> tags = new HashMap<>();
|
||||
List<Feed> feeds = getFeedList();
|
||||
List<Feed> allFeeds = getFeedList();
|
||||
List<Feed> feeds = new ArrayList<>();
|
||||
for (Feed feed : allFeeds) {
|
||||
if (feed.getState() == feedState) {
|
||||
feeds.add(feed);
|
||||
}
|
||||
}
|
||||
NavDrawerData.TagItem untaggedTag = new NavDrawerData.TagItem(FeedPreferences.TAG_UNTAGGED);
|
||||
for (Feed feed : feeds) {
|
||||
if (feed.getPreferences().getTags().isEmpty() || (feed.getPreferences().getTags().size()) == 1
|
||||
&& feed.getPreferences().getTags().contains(FeedPreferences.TAG_ROOT)) {
|
||||
untaggedTag.addFeed(feed, 0);
|
||||
}
|
||||
for (String tag : feed.getPreferences().getTags()) {
|
||||
if (FeedPreferences.TAG_ROOT.equals(tag)) {
|
||||
continue;
|
||||
@ -772,6 +797,9 @@ public final class DBReader {
|
||||
}
|
||||
List<NavDrawerData.TagItem> tagsSorted = new ArrayList<>(tags.values());
|
||||
Collections.sort(tagsSorted, (o1, o2) -> o1.getTitle().compareToIgnoreCase(o2.getTitle()));
|
||||
if (!untaggedTag.getFeeds().isEmpty()) {
|
||||
tagsSorted.add(0, untaggedTag);
|
||||
}
|
||||
// Root tag here means "all feeds", this is different from the nav drawer.
|
||||
NavDrawerData.TagItem rootTag = new NavDrawerData.TagItem(FeedPreferences.TAG_ROOT);
|
||||
for (Feed feed : feeds) {
|
||||
@ -781,10 +809,10 @@ public final class DBReader {
|
||||
return tagsSorted;
|
||||
}
|
||||
|
||||
public static List<FeedItem> searchFeedItems(final long feedId, final String query) {
|
||||
public static List<FeedItem> searchFeedItems(final long feedId, final String query, int state) {
|
||||
PodDBAdapter adapter = PodDBAdapter.getInstance();
|
||||
adapter.open();
|
||||
try (FeedItemCursor searchResult = new FeedItemCursor(adapter.searchItems(feedId, query))) {
|
||||
try (FeedItemCursor searchResult = new FeedItemCursor(adapter.searchItems(feedId, query, state))) {
|
||||
List<FeedItem> items = extractItemlistFromCursor(searchResult);
|
||||
loadAdditionalFeedItemListData(items);
|
||||
return items;
|
||||
@ -793,10 +821,10 @@ public final class DBReader {
|
||||
}
|
||||
}
|
||||
|
||||
public static List<Feed> searchFeeds(final String query) {
|
||||
public static List<Feed> searchFeeds(final String query, int state) {
|
||||
PodDBAdapter adapter = PodDBAdapter.getInstance();
|
||||
adapter.open();
|
||||
try (FeedCursor cursor = new FeedCursor(adapter.searchFeeds(query))) {
|
||||
try (FeedCursor cursor = new FeedCursor(adapter.searchFeeds(query, state))) {
|
||||
List<Feed> items = new ArrayList<>();
|
||||
while (cursor.moveToNext()) {
|
||||
items.add(cursor.getFeed());
|
||||
|
||||
@ -151,7 +151,7 @@ public class DBWriter {
|
||||
// Do full update of this feed to get rid of the item
|
||||
FeedUpdateManager.getInstance().runOnce(context, media.getItem().getFeed());
|
||||
} else {
|
||||
if (media.getItem().getFeed().getState() == Feed.STATE_SUBSCRIBED) {
|
||||
if (media.getItem().getFeed().getState() != Feed.STATE_NOT_SUBSCRIBED) {
|
||||
SynchronizationQueue.getInstance().enqueueEpisodeAction(
|
||||
new EpisodeAction.Builder(media.getItem(), EpisodeAction.DELETE)
|
||||
.currentTimestamp()
|
||||
@ -184,7 +184,7 @@ public class DBWriter {
|
||||
adapter.removeFeed(feed);
|
||||
adapter.close();
|
||||
|
||||
if (!feed.isLocalFeed() && feed.getState() == Feed.STATE_SUBSCRIBED) {
|
||||
if (!feed.isLocalFeed() && feed.getState() != Feed.STATE_NOT_SUBSCRIBED) {
|
||||
SynchronizationQueue.getInstance().enqueueFeedRemoved(feed.getDownloadUrl());
|
||||
}
|
||||
EventBus.getDefault().post(new FeedListUpdateEvent(feed));
|
||||
@ -726,7 +726,7 @@ public class DBWriter {
|
||||
adapter.close();
|
||||
|
||||
for (Feed feed : feeds) {
|
||||
if (!feed.isLocalFeed() && feed.getState() == Feed.STATE_SUBSCRIBED) {
|
||||
if (!feed.isLocalFeed() && feed.getState() != Feed.STATE_NOT_SUBSCRIBED) {
|
||||
SynchronizationQueue.getInstance().enqueueFeedAdded(feed.getDownloadUrl());
|
||||
}
|
||||
}
|
||||
|
||||
@ -128,7 +128,7 @@ public abstract class FeedDatabaseWriter {
|
||||
oldItem.setItemIdentifier(item.getItemIdentifier());
|
||||
|
||||
if (oldItem.isPlayed() && oldItem.getMedia() != null
|
||||
&& savedFeed.getState() == Feed.STATE_SUBSCRIBED) {
|
||||
&& savedFeed.getState() != Feed.STATE_NOT_SUBSCRIBED) {
|
||||
EpisodeAction action = new EpisodeAction.Builder(oldItem, EpisodeAction.PLAY)
|
||||
.currentTimestamp()
|
||||
.started(oldItem.getMedia().getDuration() / 1000)
|
||||
|
||||
@ -1263,7 +1263,7 @@ public class PodDBAdapter {
|
||||
+ JOIN_FEED_ITEM_AND_MEDIA
|
||||
+ " INNER JOIN " + TABLE_NAME_FEEDS
|
||||
+ " ON " + TABLE_NAME_FEED_ITEMS + "." + KEY_FEED + "=" + TABLE_NAME_FEEDS + "." + KEY_ID
|
||||
+ " WHERE " + TABLE_NAME_FEEDS + "." + KEY_STATE + "=" + Feed.STATE_SUBSCRIBED
|
||||
+ " WHERE " + TABLE_NAME_FEEDS + "." + KEY_STATE + "!=" + Feed.STATE_NOT_SUBSCRIBED
|
||||
+ " GROUP BY " + TABLE_NAME_FEEDS + "." + KEY_ID;
|
||||
return db.rawQuery(query, null);
|
||||
}
|
||||
@ -1404,8 +1404,8 @@ public class PodDBAdapter {
|
||||
*
|
||||
* @return A cursor with all search results in SEL_FI_EXTRA selection.
|
||||
*/
|
||||
public Cursor searchItems(long feedID, String searchQuery) {
|
||||
String[] queryWords = prepareSearchQuery(searchQuery);
|
||||
public Cursor searchItems(long feedID, String searchQuery, int state) {
|
||||
final String[] queryWords = prepareSearchQuery(searchQuery);
|
||||
|
||||
String queryFeedId;
|
||||
if (feedID != 0) {
|
||||
@ -1416,8 +1416,11 @@ public class PodDBAdapter {
|
||||
queryFeedId = "1 = 1";
|
||||
}
|
||||
|
||||
String queryStart = SELECT_FEED_ITEMS_AND_MEDIA_WITH_DESCRIPTION
|
||||
+ " WHERE " + queryFeedId + " AND " + SELECT_WHERE_FEED_IS_SUBSCRIBED + " AND (";
|
||||
String queryStart = SELECT_FEED_ITEMS_AND_MEDIA_WITH_DESCRIPTION + " WHERE " + queryFeedId;
|
||||
if (state == Feed.STATE_SUBSCRIBED && feedID == 0) {
|
||||
queryStart += " AND " + SELECT_WHERE_FEED_IS_SUBSCRIBED;
|
||||
}
|
||||
queryStart += " AND (";
|
||||
StringBuilder sb = new StringBuilder(queryStart);
|
||||
|
||||
for (int i = 0; i < queryWords.length; i++) {
|
||||
@ -1443,11 +1446,10 @@ public class PodDBAdapter {
|
||||
*
|
||||
* @return A cursor with all search results in SEL_FI_EXTRA selection.
|
||||
*/
|
||||
public Cursor searchFeeds(String searchQuery) {
|
||||
String[] queryWords = prepareSearchQuery(searchQuery);
|
||||
|
||||
public Cursor searchFeeds(String searchQuery, int state) {
|
||||
final String[] queryWords = prepareSearchQuery(searchQuery);
|
||||
String queryStart = "SELECT " + KEYS_FEED + " FROM " + TABLE_NAME_FEEDS
|
||||
+ " WHERE " + KEY_STATE + " = " + Feed.STATE_SUBSCRIBED;
|
||||
+ " WHERE " + KEY_STATE + " = " + state;
|
||||
StringBuilder sb = new StringBuilder(queryStart);
|
||||
|
||||
for (int i = 0; i < queryWords.length; i++) {
|
||||
|
||||
@ -37,7 +37,7 @@ public abstract class SubscriptionsFilterExecutor {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (filter.hideNonSubscribedFeeds && item.getState() != Feed.STATE_SUBSCRIBED) {
|
||||
if (filter.hideNonSubscribedFeeds && item.getState() == Feed.STATE_NOT_SUBSCRIBED) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
@ -175,6 +175,10 @@
|
||||
<item quantity="one">%d episode</item>
|
||||
<item quantity="other">%d episodes</item>
|
||||
</plurals>
|
||||
<plurals name="num_subscriptions">
|
||||
<item quantity="one">%d subscription</item>
|
||||
<item quantity="other">%d subscriptions</item>
|
||||
</plurals>
|
||||
<string name="episode_notification">Episode notifications</string>
|
||||
<string name="episode_notification_summary">Show a notification when a new episode is released</string>
|
||||
<plurals name="new_episode_notification_message">
|
||||
@ -196,14 +200,16 @@
|
||||
<string name="show_info_label">Show information</string>
|
||||
<string name="show_feed_settings_label">Show podcast settings</string>
|
||||
<string name="feed_settings_label">Podcast settings</string>
|
||||
<string name="rename_feed_label">Rename podcast</string>
|
||||
<string name="remove_feed_label">Remove podcast</string>
|
||||
<string name="rename_feed_label">Rename</string>
|
||||
<string name="archive_feed_label_verb">Archive</string>
|
||||
<string name="archive_feed_label_noun">Archive</string>
|
||||
<string name="restore_archive_label">Restore</string>
|
||||
<string name="remove_archive_feed_label">Delete / archive</string>
|
||||
<string name="remove_feed_label">Delete</string>
|
||||
<string name="share_label">Share</string>
|
||||
<string name="share_file_label">Share file</string>
|
||||
<string name="feed_delete_confirmation_msg">Please confirm that you want to delete the podcast \"%1$s\", ALL its episodes (including downloaded episodes), playback history, and its statistics.</string>
|
||||
<string name="feed_delete_confirmation_msg_batch">Please confirm that you want to remove the selected podcasts, ALL their episodes (including downloaded episodes), playback history, and its statistics.</string>
|
||||
<string name="feed_delete_confirmation_local_msg">Please confirm that you want to remove the podcast \"%1$s\", its playback history, and its statistics. The files in the local source folder will not be deleted.</string>
|
||||
<string name="feed_remover_msg">Removing podcast</string>
|
||||
<string name="feed_delete_explanation_delete"><![CDATA[<b>Deleting</b> will remove ALL its episodes including downloads, playback history, and statistics.]]></string>
|
||||
<string name="feed_delete_explanation_archive"><![CDATA[<b>Archiving</b> will hide it from the subscription list and avoid it getting updates. Downloads, statistics and playback state are kept.]]></string>
|
||||
<string name="load_complete_feed">Refresh complete podcast</string>
|
||||
<string name="multi_select">Multi select</string>
|
||||
<string name="select_all_above">Select all above</string>
|
||||
@ -757,6 +763,7 @@
|
||||
<string name="feed_tags_summary">Change the tags of this podcast to help organize your subscriptions</string>
|
||||
<string name="feed_folders_include_root">Show above tags (side navigation only)</string>
|
||||
<string name="tag_all">All</string>
|
||||
<string name="tag_untagged">Untagged</string>
|
||||
<string name="multi_feed_common_tags_info">Only common tags from all selected subscriptions are shown. Other tags stay unaffected.</string>
|
||||
<string name="auto_download_inbox_category">Automatically download episodes from the inbox</string>
|
||||
<string name="episode_filters_label">Episode filter</string>
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user