summaryrefslogtreecommitdiff
path: root/app/src/main/java/de
diff options
context:
space:
mode:
Diffstat (limited to 'app/src/main/java/de')
-rw-r--r--app/src/main/java/de/danoeh/antennapod/adapter/CoverLoader.java33
-rw-r--r--app/src/main/java/de/danoeh/antennapod/adapter/NavListAdapter.java286
-rw-r--r--app/src/main/java/de/danoeh/antennapod/adapter/SubscriptionsAdapter.java67
-rw-r--r--app/src/main/java/de/danoeh/antennapod/dialog/TagSettingsDialog.java116
-rw-r--r--app/src/main/java/de/danoeh/antennapod/fragment/FeedSettingsFragment.java10
-rw-r--r--app/src/main/java/de/danoeh/antennapod/fragment/NavDrawerFragment.java250
-rw-r--r--app/src/main/java/de/danoeh/antennapod/fragment/SubscriptionFragment.java86
7 files changed, 531 insertions, 317 deletions
diff --git a/app/src/main/java/de/danoeh/antennapod/adapter/CoverLoader.java b/app/src/main/java/de/danoeh/antennapod/adapter/CoverLoader.java
index d782d4ed5..aeaf526be 100644
--- a/app/src/main/java/de/danoeh/antennapod/adapter/CoverLoader.java
+++ b/app/src/main/java/de/danoeh/antennapod/adapter/CoverLoader.java
@@ -21,6 +21,7 @@ import de.danoeh.antennapod.activity.MainActivity;
import de.danoeh.antennapod.core.glide.ApGlideSettings;
public class CoverLoader {
+ private int resource = 0;
private String uri;
private String fallbackUri;
private TextView txtvPlaceholder;
@@ -37,6 +38,11 @@ public class CoverLoader {
return this;
}
+ public CoverLoader withResource(int resource) {
+ this.resource = resource;
+ return this;
+ }
+
public CoverLoader withFallbackUri(String uri) {
fallbackUri = uri;
return this;
@@ -66,6 +72,12 @@ public class CoverLoader {
}
public void load() {
+ if (resource != 0) {
+ imgvCover.setImageResource(resource);
+ CoverTarget.setPlaceholderVisibility(txtvPlaceholder, textAndImageCombined);
+ return;
+ }
+
RequestOptions options = new RequestOptions()
.diskCacheStrategy(ApGlideSettings.AP_DISK_CACHE_STRATEGY)
.fitCenter()
@@ -106,15 +118,7 @@ public class CoverLoader {
@Override
public void onResourceReady(@NonNull Drawable resource, @Nullable Transition<? super Drawable> transition) {
- TextView txtvPlaceholder = placeholder.get();
- if (txtvPlaceholder != null) {
- if (textAndImageCombined) {
- int bgColor = txtvPlaceholder.getContext().getResources().getColor(R.color.feed_text_bg);
- txtvPlaceholder.setBackgroundColor(bgColor);
- } else {
- txtvPlaceholder.setVisibility(View.INVISIBLE);
- }
- }
+ setPlaceholderVisibility(placeholder.get(), textAndImageCombined);
ImageView ivCover = cover.get();
ivCover.setImageDrawable(resource);
}
@@ -124,5 +128,16 @@ public class CoverLoader {
ImageView ivCover = cover.get();
ivCover.setImageDrawable(placeholder);
}
+
+ static void setPlaceholderVisibility(TextView placeholder, boolean textAndImageCombined) {
+ if (placeholder != null) {
+ if (textAndImageCombined) {
+ int bgColor = placeholder.getContext().getResources().getColor(R.color.feed_text_bg);
+ placeholder.setBackgroundColor(bgColor);
+ } else {
+ placeholder.setVisibility(View.INVISIBLE);
+ }
+ }
+ }
}
} \ No newline at end of file
diff --git a/app/src/main/java/de/danoeh/antennapod/adapter/NavListAdapter.java b/app/src/main/java/de/danoeh/antennapod/adapter/NavListAdapter.java
index 7c8943f36..de3242b1a 100644
--- a/app/src/main/java/de/danoeh/antennapod/adapter/NavListAdapter.java
+++ b/app/src/main/java/de/danoeh/antennapod/adapter/NavListAdapter.java
@@ -1,20 +1,21 @@
package de.danoeh.antennapod.adapter;
import android.app.Activity;
-import android.content.Context;
import android.content.SharedPreferences;
import android.content.res.TypedArray;
import android.graphics.drawable.Drawable;
+import android.view.ContextMenu;
+import android.view.LayoutInflater;
+import androidx.annotation.NonNull;
import androidx.preference.PreferenceManager;
import android.util.TypedValue;
-import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
-import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.TextView;
import androidx.appcompat.app.AlertDialog;
+import androidx.recyclerview.widget.RecyclerView;
import com.bumptech.glide.Glide;
import com.bumptech.glide.request.RequestOptions;
import com.joanzapata.iconify.Iconify;
@@ -23,6 +24,7 @@ import de.danoeh.antennapod.R;
import de.danoeh.antennapod.core.feed.Feed;
import de.danoeh.antennapod.core.glide.ApGlideSettings;
import de.danoeh.antennapod.core.preferences.UserPreferences;
+import de.danoeh.antennapod.core.storage.NavDrawerData;
import de.danoeh.antennapod.fragment.AddFeedFragment;
import de.danoeh.antennapod.fragment.DownloadsFragment;
import de.danoeh.antennapod.fragment.EpisodesFragment;
@@ -30,6 +32,7 @@ import de.danoeh.antennapod.fragment.NavDrawerFragment;
import de.danoeh.antennapod.fragment.PlaybackHistoryFragment;
import de.danoeh.antennapod.fragment.QueueFragment;
import de.danoeh.antennapod.fragment.SubscriptionFragment;
+import de.danoeh.antennapod.ui.common.ThemeUtils;
import org.apache.commons.lang3.ArrayUtils;
import java.lang.ref.WeakReference;
@@ -42,10 +45,9 @@ import java.util.List;
/**
* BaseAdapter for the navigation drawer
*/
-public class NavListAdapter extends BaseAdapter
+public class NavListAdapter extends RecyclerView.Adapter<NavListAdapter.Holder>
implements SharedPreferences.OnSharedPreferenceChangeListener {
- private static final int VIEW_TYPE_COUNT = 3;
public static final int VIEW_TYPE_NAV = 0;
public static final int VIEW_TYPE_SECTION_DIVIDER = 1;
private static final int VIEW_TYPE_SUBSCRIPTION = 2;
@@ -56,7 +58,7 @@ public class NavListAdapter extends BaseAdapter
*/
public static final String SUBSCRIPTION_LIST_TAG = "SubscriptionList";
- private static List<String> tags;
+ private static List<String> fragmentTags;
private static String[] titles;
private final ItemAccess itemAccess;
@@ -96,7 +98,7 @@ public class NavListAdapter extends BaseAdapter
showSubscriptionList = false;
}
- tags = newTags;
+ fragmentTags = newTags;
notifyDataSetChanged();
}
@@ -133,19 +135,18 @@ public class NavListAdapter extends BaseAdapter
default:
return null;
}
- TypedArray ta = context.obtainStyledAttributes(new int[] { icon } );
+ TypedArray ta = context.obtainStyledAttributes(new int[] { icon });
Drawable result = ta.getDrawable(0);
ta.recycle();
return result;
}
- public List<String> getTags() {
- return Collections.unmodifiableList(tags);
+ public List<String> getFragmentTags() {
+ return Collections.unmodifiableList(fragmentTags);
}
-
@Override
- public int getCount() {
+ public int getItemCount() {
int baseCount = getSubscriptionOffset();
if (showSubscriptionList) {
baseCount += itemAccess.getCount();
@@ -154,25 +155,18 @@ public class NavListAdapter extends BaseAdapter
}
@Override
- public Object getItem(int position) {
+ public long getItemId(int position) {
int viewType = getItemViewType(position);
- if (viewType == VIEW_TYPE_NAV) {
- return getLabel(tags.get(position));
- } else if (viewType == VIEW_TYPE_SECTION_DIVIDER) {
- return "";
+ if (viewType == VIEW_TYPE_SUBSCRIPTION) {
+ return itemAccess.getItem(position - getSubscriptionOffset()).id;
} else {
- return itemAccess.getItem(position);
+ return -position - 1; // IDs are >0
}
}
@Override
- public long getItemId(int position) {
- return position;
- }
-
- @Override
public int getItemViewType(int position) {
- if (0 <= position && position < tags.size()) {
+ if (0 <= position && position < fragmentTags.size()) {
return VIEW_TYPE_NAV;
} else if (position < getSubscriptionOffset()) {
return VIEW_TYPE_SECTION_DIVIDER;
@@ -181,69 +175,67 @@ public class NavListAdapter extends BaseAdapter
}
}
- @Override
- public int getViewTypeCount() {
- return VIEW_TYPE_COUNT;
- }
-
public int getSubscriptionOffset() {
- return tags.size() > 0 ? tags.size() + 1 : 0;
+ return fragmentTags.size() > 0 ? fragmentTags.size() + 1 : 0;
}
+ @NonNull
+ @Override
+ public Holder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
+ LayoutInflater inflater = LayoutInflater.from(activity.get());
+ if (viewType == VIEW_TYPE_NAV) {
+ return new NavHolder(inflater.inflate(R.layout.nav_listitem, parent, false));
+ } else if (viewType == VIEW_TYPE_SECTION_DIVIDER) {
+ return new DividerHolder(inflater.inflate(R.layout.nav_section_item, parent, false));
+ } else {
+ return new FeedHolder(inflater.inflate(R.layout.nav_listitem, parent, false));
+ }
+ }
@Override
- public View getView(int position, View convertView, ViewGroup parent) {
+ public void onBindViewHolder(@NonNull Holder holder, int position) {
int viewType = getItemViewType(position);
- View v;
+
+ holder.itemView.setOnCreateContextMenuListener(null);
if (viewType == VIEW_TYPE_NAV) {
- v = getNavView((String) getItem(position), position, convertView, parent);
+ bindNavView(getLabel(fragmentTags.get(position)), position, (NavHolder) holder);
} else if (viewType == VIEW_TYPE_SECTION_DIVIDER) {
- v = getSectionDividerView(convertView, parent);
+ bindSectionDivider((DividerHolder) holder);
} else {
- v = getFeedView(position, convertView, parent);
+ int itemPos = position - getSubscriptionOffset();
+ NavDrawerData.DrawerItem item = itemAccess.getItem(itemPos);
+ bindListItem(item, (FeedHolder) holder);
+ if (item.type == NavDrawerData.DrawerItem.Type.FEED) {
+ bindFeedView((NavDrawerData.FeedDrawerItem) item, (FeedHolder) holder);
+ holder.itemView.setOnCreateContextMenuListener(itemAccess);
+ } else {
+ bindFolderView((NavDrawerData.FolderDrawerItem) item, (FeedHolder) holder);
+ }
}
- if (v != null && viewType != VIEW_TYPE_SECTION_DIVIDER) {
+ if (viewType != VIEW_TYPE_SECTION_DIVIDER) {
TypedValue typedValue = new TypedValue();
- if (position == itemAccess.getSelectedItemIndex()) {
- v.getContext().getTheme().resolveAttribute(R.attr.drawer_activated_color, typedValue, true);
- v.setBackgroundResource(typedValue.resourceId);
- } else {
- v.getContext().getTheme().resolveAttribute(android.R.attr.windowBackground, typedValue, true);
- v.setBackgroundResource(typedValue.resourceId);
- }
+ activity.get().getTheme().resolveAttribute(itemAccess.isSelected(position)
+ ? R.attr.drawer_activated_color : android.R.attr.windowBackground, typedValue, true);
+ holder.itemView.setBackgroundResource(typedValue.resourceId);
+
+ holder.itemView.setOnClickListener(v -> itemAccess.onItemClick(position));
+ holder.itemView.setOnLongClickListener(v -> itemAccess.onItemLongClick(position));
}
- return v;
}
- private View getNavView(String title, int position, View convertView, ViewGroup parent) {
+ private void bindNavView(String title, int position, NavHolder holder) {
Activity context = activity.get();
- if(context == null) {
- return null;
- }
- NavHolder holder;
- if (convertView == null) {
- holder = new NavHolder();
- LayoutInflater inflater = (LayoutInflater) context
- .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
-
- convertView = inflater.inflate(R.layout.nav_listitem, parent, false);
-
- holder.image = convertView.findViewById(R.id.imgvCover);
- holder.title = convertView.findViewById(R.id.txtvTitle);
- holder.count = convertView.findViewById(R.id.txtvCount);
- convertView.setTag(holder);
- } else {
- holder = (NavHolder) convertView.getTag();
+ if (context == null) {
+ return;
}
-
holder.title.setText(title);
// reset for re-use
holder.count.setVisibility(View.GONE);
holder.count.setOnClickListener(null);
- String tag = tags.get(position);
+ String tag = fragmentTags.get(position);
if (tag.equals(QueueFragment.TAG)) {
int queueSize = itemAccess.getQueueSize();
if (queueSize > 0) {
@@ -262,78 +254,64 @@ public class NavListAdapter extends BaseAdapter
holder.count.setText(NumberFormat.getInstance().format(sum));
holder.count.setVisibility(View.VISIBLE);
}
- } else if(tag.equals(DownloadsFragment.TAG) && UserPreferences.isEnableAutodownload()) {
+ } else if (tag.equals(DownloadsFragment.TAG) && UserPreferences.isEnableAutodownload()) {
int epCacheSize = UserPreferences.getEpisodeCacheSize();
// don't count episodes that can be reclaimed
- int spaceUsed = itemAccess.getNumberOfDownloadedItems() -
- itemAccess.getReclaimableItems();
+ int spaceUsed = itemAccess.getNumberOfDownloadedItems()
+ - itemAccess.getReclaimableItems();
if (epCacheSize > 0 && spaceUsed >= epCacheSize) {
holder.count.setText("{md-disc-full 150%}");
Iconify.addIcons(holder.count);
holder.count.setVisibility(View.VISIBLE);
holder.count.setOnClickListener(v ->
- new AlertDialog.Builder(context)
+ new AlertDialog.Builder(context)
.setTitle(R.string.episode_cache_full_title)
.setMessage(R.string.episode_cache_full_message)
- .setPositiveButton(android.R.string.ok, (dialog, which) -> {})
+ .setPositiveButton(android.R.string.ok, (dialog, which) -> { })
.show()
);
}
}
- holder.image.setImageDrawable(getDrawable(tags.get(position)));
-
- return convertView;
+ holder.image.setImageDrawable(getDrawable(fragmentTags.get(position)));
}
- private View getSectionDividerView(View convertView, ViewGroup parent) {
+ private void bindSectionDivider(DividerHolder holder) {
Activity context = activity.get();
- if(context == null) {
- return null;
+ if (context == null) {
+ return;
}
- LayoutInflater inflater = (LayoutInflater) context
- .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
-
- convertView = inflater.inflate(R.layout.nav_section_item, parent, false);
- TextView feedsFilteredMsg = convertView.findViewById(R.id.nav_feeds_filtered_message);
if (UserPreferences.getSubscriptionsFilter().isEnabled() && showSubscriptionList) {
- convertView.setEnabled(true);
- feedsFilteredMsg.setText("{md-info-outline} " + context.getString(R.string.subscriptions_are_filtered));
- Iconify.addIcons(feedsFilteredMsg);
- feedsFilteredMsg.setVisibility(View.VISIBLE);
+ holder.itemView.setEnabled(true);
+ holder.feedsFilteredMsg.setText("{md-info-outline} "
+ + context.getString(R.string.subscriptions_are_filtered));
+ Iconify.addIcons(holder.feedsFilteredMsg);
+ holder.feedsFilteredMsg.setVisibility(View.VISIBLE);
} else {
- convertView.setEnabled(false);
- feedsFilteredMsg.setVisibility(View.GONE);
+ holder.itemView.setEnabled(false);
+ holder.feedsFilteredMsg.setVisibility(View.GONE);
}
+ }
- return convertView;
+ private void bindListItem(NavDrawerData.DrawerItem item, FeedHolder holder) {
+ if (item.getCounter() > 0) {
+ holder.count.setVisibility(View.VISIBLE);
+ holder.count.setText(NumberFormat.getInstance().format(item.getCounter()));
+ } else {
+ holder.count.setVisibility(View.GONE);
+ }
+ holder.title.setText(item.getTitle());
+ int padding = (int) (activity.get().getResources().getDimension(R.dimen.thumbnail_length_navlist) / 2);
+ holder.itemView.setPadding(item.getLayer() * padding, 0, 0, 0);
}
- private View getFeedView(int position, View convertView, ViewGroup parent) {
+ private void bindFeedView(NavDrawerData.FeedDrawerItem drawerItem, FeedHolder holder) {
+ Feed feed = drawerItem.feed;
Activity context = activity.get();
- if(context == null) {
- return null;
- }
- int feedPos = position - getSubscriptionOffset();
- Feed feed = itemAccess.getItem(feedPos);
-
- FeedHolder holder;
- if (convertView == null) {
- holder = new FeedHolder();
- LayoutInflater inflater = (LayoutInflater) context
- .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
-
- convertView = inflater.inflate(R.layout.nav_listitem, parent, false);
-
- holder.image = convertView.findViewById(R.id.imgvCover);
- holder.title = convertView.findViewById(R.id.txtvTitle);
- holder.failure = convertView.findViewById(R.id.itxtvFailure);
- holder.count = convertView.findViewById(R.id.txtvCount);
- convertView.setTag(holder);
- } else {
- holder = (FeedHolder) convertView.getTag();
+ if (context == null) {
+ return;
}
Glide.with(context)
@@ -346,9 +324,7 @@ public class NavListAdapter extends BaseAdapter
.dontAnimate())
.into(holder.image);
- holder.title.setText(feed.getTitle());
-
- if(feed.hasLastUpdateFailed()) {
+ if (feed.hasLastUpdateFailed()) {
RelativeLayout.LayoutParams p = (RelativeLayout.LayoutParams) holder.title.getLayoutParams();
p.addRule(RelativeLayout.LEFT_OF, R.id.itxtvFailure);
holder.failure.setVisibility(View.VISIBLE);
@@ -357,39 +333,87 @@ public class NavListAdapter extends BaseAdapter
p.addRule(RelativeLayout.LEFT_OF, R.id.txtvCount);
holder.failure.setVisibility(View.GONE);
}
- int counter = itemAccess.getFeedCounter(feed.getId());
- if(counter > 0) {
- holder.count.setVisibility(View.VISIBLE);
- holder.count.setText(NumberFormat.getInstance().format(counter));
- } else {
+ }
+
+ private void bindFolderView(NavDrawerData.FolderDrawerItem folder, FeedHolder holder) {
+ Activity context = activity.get();
+ if (context == null) {
+ return;
+ }
+ if (folder.isOpen) {
holder.count.setVisibility(View.GONE);
}
- return convertView;
+ Glide.with(context).clear(holder.image);
+ holder.image.setImageResource(ThemeUtils.getDrawableFromAttr(context, R.attr.ic_folder));
+ holder.failure.setVisibility(View.GONE);
}
- static class NavHolder {
- ImageView image;
- TextView title;
- TextView count;
+ static class Holder extends RecyclerView.ViewHolder {
+ public Holder(@NonNull View itemView) {
+ super(itemView);
+ }
}
- static class FeedHolder {
- ImageView image;
- TextView title;
- IconTextView failure;
- TextView count;
+ static class DividerHolder extends Holder {
+ final TextView feedsFilteredMsg;
+
+ public DividerHolder(@NonNull View itemView) {
+ super(itemView);
+ feedsFilteredMsg = itemView.findViewById(R.id.nav_feeds_filtered_message);
+ }
}
- public interface ItemAccess {
+ static class NavHolder extends Holder {
+ final ImageView image;
+ final TextView title;
+ final TextView count;
+
+ public NavHolder(@NonNull View itemView) {
+ super(itemView);
+ image = itemView.findViewById(R.id.imgvCover);
+ title = itemView.findViewById(R.id.txtvTitle);
+ count = itemView.findViewById(R.id.txtvCount);
+ }
+ }
+
+ static class FeedHolder extends Holder {
+ final ImageView image;
+ final TextView title;
+ final IconTextView failure;
+ final TextView count;
+
+ public FeedHolder(@NonNull View itemView) {
+ super(itemView);
+ image = itemView.findViewById(R.id.imgvCover);
+ title = itemView.findViewById(R.id.txtvTitle);
+ failure = itemView.findViewById(R.id.itxtvFailure);
+ count = itemView.findViewById(R.id.txtvCount);
+ }
+ }
+
+ public interface ItemAccess extends View.OnCreateContextMenuListener {
int getCount();
- Feed getItem(int position);
- int getSelectedItemIndex();
+
+ NavDrawerData.DrawerItem getItem(int position);
+
+ boolean isSelected(int position);
+
int getQueueSize();
+
int getNumberOfNewItems();
+
int getNumberOfDownloadedItems();
+
int getReclaimableItems();
- int getFeedCounter(long feedId);
+
int getFeedCounterSum();
+
+ void onItemClick(int position);
+
+ boolean onItemLongClick(int position);
+
+ @Override
+ void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo);
}
}
diff --git a/app/src/main/java/de/danoeh/antennapod/adapter/SubscriptionsAdapter.java b/app/src/main/java/de/danoeh/antennapod/adapter/SubscriptionsAdapter.java
index f7d6358de..fc97cace5 100644
--- a/app/src/main/java/de/danoeh/antennapod/adapter/SubscriptionsAdapter.java
+++ b/app/src/main/java/de/danoeh/antennapod/adapter/SubscriptionsAdapter.java
@@ -21,17 +21,16 @@ import de.danoeh.antennapod.R;
import de.danoeh.antennapod.activity.MainActivity;
import de.danoeh.antennapod.core.feed.Feed;
import de.danoeh.antennapod.core.feed.LocalFeedUpdater;
+import de.danoeh.antennapod.core.storage.NavDrawerData;
import de.danoeh.antennapod.fragment.FeedItemlistFragment;
+import de.danoeh.antennapod.fragment.SubscriptionFragment;
+import de.danoeh.antennapod.ui.common.ThemeUtils;
import jp.shts.android.library.TriangleLabelView;
/**
* Adapter for subscriptions
*/
public class SubscriptionsAdapter extends BaseAdapter implements AdapterView.OnItemClickListener {
-
- /** placeholder object that indicates item should be added */
- public static final Object ADD_ITEM_OBJ = new Object();
-
/** the position in the view that holds the add item; 0 is the first, -1 is the last position */
private static final String TAG = "SubscriptionsAdapter";
@@ -60,7 +59,7 @@ public class SubscriptionsAdapter extends BaseAdapter implements AdapterView.OnI
@Override
public long getItemId(int position) {
- return itemAccess.getItem(position).getId();
+ return ((NavDrawerData.DrawerItem) getItem(position)).id;
}
@Override
@@ -83,11 +82,13 @@ public class SubscriptionsAdapter extends BaseAdapter implements AdapterView.OnI
holder = (Holder) convertView.getTag();
}
- final Feed feed = (Feed) getItem(position);
- if (feed == null) return null;
+ final NavDrawerData.DrawerItem drawerItem = (NavDrawerData.DrawerItem) getItem(position);
+ if (drawerItem == null) {
+ return null;
+ }
- holder.feedTitle.setText(feed.getTitle());
- holder.imageView.setContentDescription(feed.getTitle());
+ holder.feedTitle.setText(drawerItem.getTitle());
+ holder.imageView.setContentDescription(drawerItem.getTitle());
holder.feedTitle.setVisibility(View.VISIBLE);
// Fix TriangleLabelView corner for RTL
@@ -96,30 +97,46 @@ public class SubscriptionsAdapter extends BaseAdapter implements AdapterView.OnI
holder.count.setCorner(TriangleLabelView.Corner.TOP_LEFT);
}
- int count = itemAccess.getFeedCounter(feed.getId());
- if(count > 0) {
- holder.count.setPrimaryText(
- NumberFormat.getInstance().format(itemAccess.getFeedCounter(feed.getId())));
+ if (drawerItem.getCounter() > 0) {
+ holder.count.setPrimaryText(NumberFormat.getInstance().format(drawerItem.getCounter()));
holder.count.setVisibility(View.VISIBLE);
} else {
holder.count.setVisibility(View.GONE);
}
- boolean textAndImageCombined = feed.isLocalFeed()
- && LocalFeedUpdater.getDefaultIconUrl(convertView.getContext()).equals(feed.getImageUrl());
- new CoverLoader(mainActivityRef.get())
- .withUri(feed.getImageUrl())
- .withPlaceholderView(holder.feedTitle, textAndImageCombined)
- .withCoverView(holder.imageView)
- .load();
-
+ if (drawerItem.type == NavDrawerData.DrawerItem.Type.FEED) {
+ Feed feed = ((NavDrawerData.FeedDrawerItem) drawerItem).feed;
+ boolean textAndImageCombined = feed.isLocalFeed()
+ && LocalFeedUpdater.getDefaultIconUrl(convertView.getContext()).equals(feed.getImageUrl());
+ new CoverLoader(mainActivityRef.get())
+ .withUri(feed.getImageUrl())
+ .withPlaceholderView(holder.feedTitle, textAndImageCombined)
+ .withCoverView(holder.imageView)
+ .load();
+ } else {
+ new CoverLoader(mainActivityRef.get())
+ .withResource(ThemeUtils.getDrawableFromAttr(mainActivityRef.get(), R.attr.ic_folder))
+ .withPlaceholderView(holder.feedTitle, true)
+ .withCoverView(holder.imageView)
+ .load();
+ }
return convertView;
}
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
- Fragment fragment = FeedItemlistFragment.newInstance(getItemId(position));
- mainActivityRef.get().loadChildFragment(fragment);
+ final NavDrawerData.DrawerItem drawerItem = (NavDrawerData.DrawerItem) getItem(position);
+ if (drawerItem == null) {
+ return;
+ }
+ if (drawerItem.type == NavDrawerData.DrawerItem.Type.FEED) {
+ Feed feed = ((NavDrawerData.FeedDrawerItem) drawerItem).feed;
+ Fragment fragment = FeedItemlistFragment.newInstance(feed.getId());
+ mainActivityRef.get().loadChildFragment(fragment);
+ } else if (drawerItem.type == NavDrawerData.DrawerItem.Type.FOLDER) {
+ Fragment fragment = SubscriptionFragment.newInstance(drawerItem.getTitle());
+ mainActivityRef.get().loadChildFragment(fragment);
+ }
}
static class Holder {
@@ -130,7 +147,7 @@ public class SubscriptionsAdapter extends BaseAdapter implements AdapterView.OnI
public interface ItemAccess {
int getCount();
- Feed getItem(int position);
- int getFeedCounter(long feedId);
+
+ NavDrawerData.DrawerItem getItem(int position);
}
}
diff --git a/app/src/main/java/de/danoeh/antennapod/dialog/TagSettingsDialog.java b/app/src/main/java/de/danoeh/antennapod/dialog/TagSettingsDialog.java
new file mode 100644
index 000000000..24a0cc192
--- /dev/null
+++ b/app/src/main/java/de/danoeh/antennapod/dialog/TagSettingsDialog.java
@@ -0,0 +1,116 @@
+package de.danoeh.antennapod.dialog;
+
+import android.app.Dialog;
+import android.os.Bundle;
+import android.text.TextUtils;
+import android.view.ViewGroup;
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.appcompat.app.AlertDialog;
+import androidx.fragment.app.DialogFragment;
+import androidx.recyclerview.widget.GridLayoutManager;
+import androidx.recyclerview.widget.RecyclerView;
+import com.google.android.material.chip.Chip;
+import de.danoeh.antennapod.R;
+import de.danoeh.antennapod.core.feed.FeedPreferences;
+import de.danoeh.antennapod.core.storage.DBWriter;
+import de.danoeh.antennapod.databinding.EditTagsDialogBinding;
+import de.danoeh.antennapod.view.ItemOffsetDecoration;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class TagSettingsDialog extends DialogFragment {
+ public static final String TAG = "TagSettingsDialog";
+ private static final String ARG_FEED_PREFERENCES = "feed_preferences";
+ private List<String> displayedTags;
+
+ public static TagSettingsDialog newInstance(FeedPreferences preferences) {
+ TagSettingsDialog fragment = new TagSettingsDialog();
+ Bundle args = new Bundle();
+ args.putSerializable(ARG_FEED_PREFERENCES, preferences);
+ fragment.setArguments(args);
+ return fragment;
+ }
+
+ @NonNull
+ @Override
+ public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) {
+ FeedPreferences preferences = (FeedPreferences) getArguments().getSerializable(ARG_FEED_PREFERENCES);
+ displayedTags = new ArrayList<>(preferences.getTags());
+ displayedTags.remove(FeedPreferences.TAG_ROOT);
+
+ EditTagsDialogBinding viewBinding = EditTagsDialogBinding.inflate(getLayoutInflater());
+ viewBinding.tagsRecycler.setLayoutManager(new GridLayoutManager(getContext(), 2));
+ viewBinding.tagsRecycler.addItemDecoration(new ItemOffsetDecoration(getContext(), 4));
+ TagSelectionAdapter adapter = new TagSelectionAdapter();
+ adapter.setHasStableIds(true);
+ viewBinding.tagsRecycler.setAdapter(adapter);
+ viewBinding.rootFolderCheckbox.setChecked(preferences.getTags().contains(FeedPreferences.TAG_ROOT));
+
+
+ viewBinding.newTagButton.setOnClickListener(v -> {
+ String name = viewBinding.newTagEditText.getText().toString().trim();
+ if (TextUtils.isEmpty(name) || displayedTags.contains(name)) {
+ return;
+ }
+ displayedTags.add(name);
+ viewBinding.newTagEditText.setText("");
+ adapter.notifyDataSetChanged();
+ });
+
+ AlertDialog.Builder dialog = new AlertDialog.Builder(getContext());
+ dialog.setView(viewBinding.getRoot());
+ dialog.setTitle(R.string.feed_folders_label);
+ dialog.setPositiveButton(android.R.string.ok, (d, input) -> {
+ preferences.getTags().clear();
+ preferences.getTags().addAll(displayedTags);
+ if (viewBinding.rootFolderCheckbox.isChecked()) {
+ preferences.getTags().add(FeedPreferences.TAG_ROOT);
+ }
+ DBWriter.setFeedPreferences(preferences);
+ });
+ dialog.setNegativeButton(R.string.cancel_label, null);
+ return dialog.create();
+ }
+
+ public class TagSelectionAdapter extends RecyclerView.Adapter<TagSelectionAdapter.ViewHolder> {
+
+ @Override
+ @NonNull
+ public TagSelectionAdapter.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
+ Chip chip = new Chip(getContext());
+ chip.setCloseIconVisible(true);
+ chip.setCloseIconResource(R.drawable.ic_delete_black);
+ return new TagSelectionAdapter.ViewHolder(chip);
+ }
+
+ @Override
+ public void onBindViewHolder(@NonNull TagSelectionAdapter.ViewHolder holder, int position) {
+ holder.chip.setText(displayedTags.get(position));
+ holder.chip.setOnCloseIconClickListener(v -> {
+ displayedTags.remove(position);
+ notifyDataSetChanged();
+ });
+ }
+
+ @Override
+ public int getItemCount() {
+ return displayedTags.size();
+ }
+
+ @Override
+ public long getItemId(int position) {
+ return displayedTags.get(position).hashCode();
+ }
+
+ public class ViewHolder extends RecyclerView.ViewHolder {
+ Chip chip;
+
+ ViewHolder(Chip itemView) {
+ super(itemView);
+ chip = itemView;
+ }
+ }
+ }
+}
diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/FeedSettingsFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/FeedSettingsFragment.java
index e24c89478..11fb68ec3 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/FeedSettingsFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/fragment/FeedSettingsFragment.java
@@ -30,6 +30,7 @@ import de.danoeh.antennapod.core.storage.DBWriter;
import de.danoeh.antennapod.dialog.AuthenticationDialog;
import de.danoeh.antennapod.dialog.EpisodeFilterDialog;
import de.danoeh.antennapod.dialog.FeedPreferenceSkipDialog;
+import de.danoeh.antennapod.dialog.TagSettingsDialog;
import io.reactivex.Maybe;
import io.reactivex.MaybeOnSubscribe;
import io.reactivex.android.schedulers.AndroidSchedulers;
@@ -105,6 +106,7 @@ public class FeedSettingsFragment extends Fragment {
private static final CharSequence PREF_CATEGORY_AUTO_DOWNLOAD = "autoDownloadCategory";
private static final String PREF_FEED_PLAYBACK_SPEED = "feedPlaybackSpeed";
private static final String PREF_AUTO_SKIP = "feedAutoSkip";
+ private static final String PREF_TAGS = "tags";
private static final DecimalFormat SPEED_FORMAT =
new DecimalFormat("0.00", DecimalFormatSymbols.getInstance(Locale.US));
@@ -160,6 +162,7 @@ public class FeedSettingsFragment extends Fragment {
setupPlaybackSpeedPreference();
setupFeedAutoSkipPreference();
setupEpisodeNotificationPreference();
+ setupTags();
updateAutoDeleteSummary();
updateVolumeReductionValue();
@@ -395,6 +398,13 @@ public class FeedSettingsFragment extends Fragment {
}
}
+ private void setupTags() {
+ findPreference(PREF_TAGS).setOnPreferenceClickListener(preference -> {
+ TagSettingsDialog.newInstance(feedPreferences).show(getChildFragmentManager(), TagSettingsDialog.TAG);
+ return true;
+ });
+ }
+
private void setupEpisodeNotificationPreference() {
SwitchPreferenceCompat pref = findPreference("episodeNotification");
diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/NavDrawerFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/NavDrawerFragment.java
index be74678d3..209bc62e5 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/NavDrawerFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/fragment/NavDrawerFragment.java
@@ -12,15 +12,16 @@ import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
-import android.widget.AdapterView;
-import android.widget.ListView;
import android.widget.ProgressBar;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.VisibleForTesting;
import androidx.appcompat.app.AlertDialog;
+import androidx.core.util.Pair;
import androidx.fragment.app.Fragment;
+import androidx.recyclerview.widget.LinearLayoutManager;
+import androidx.recyclerview.widget.RecyclerView;
import com.google.android.material.bottomsheet.BottomSheetBehavior;
import de.danoeh.antennapod.R;
import de.danoeh.antennapod.activity.MainActivity;
@@ -34,6 +35,7 @@ import de.danoeh.antennapod.core.feed.Feed;
import de.danoeh.antennapod.core.preferences.UserPreferences;
import de.danoeh.antennapod.core.storage.DBReader;
import de.danoeh.antennapod.core.storage.DBWriter;
+import de.danoeh.antennapod.core.storage.NavDrawerData;
import de.danoeh.antennapod.dialog.RemoveFeedDialog;
import de.danoeh.antennapod.dialog.SubscriptionsFilterDialog;
import de.danoeh.antennapod.dialog.RenameFeedDialog;
@@ -46,12 +48,15 @@ import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;
+import java.util.ArrayList;
+import java.util.HashSet;
import java.util.List;
+import java.util.Set;
-public class NavDrawerFragment extends Fragment implements AdapterView.OnItemClickListener,
- AdapterView.OnItemLongClickListener, SharedPreferences.OnSharedPreferenceChangeListener {
+public class NavDrawerFragment extends Fragment implements SharedPreferences.OnSharedPreferenceChangeListener {
@VisibleForTesting
public static final String PREF_LAST_FRAGMENT_TAG = "prefLastFragmentTag";
+ private static final String PREF_OPEN_FOLDERS = "prefOpenFolders";
@VisibleForTesting
public static final String PREF_NAME = "NavDrawerPrefs";
public static final String TAG = "NavDrawerFragment";
@@ -66,12 +71,13 @@ public class NavDrawerFragment extends Fragment implements AdapterView.OnItemCli
NavListAdapter.SUBSCRIPTION_LIST_TAG
};
- private DBReader.NavDrawerData navDrawerData;
- private int selectedNavListIndex = -1;
- private int position = -1;
+ private NavDrawerData navDrawerData;
+ private List<NavDrawerData.DrawerItem> flatItemList;
+ private NavDrawerData.DrawerItem contextPressedItem = null;
private NavListAdapter navAdapter;
private Disposable disposable;
private ProgressBar progressBar;
+ private Set<String> openFolders = new HashSet<>();
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
@@ -79,40 +85,21 @@ public class NavDrawerFragment extends Fragment implements AdapterView.OnItemCli
super.onCreateView(inflater, container, savedInstanceState);
View root = inflater.inflate(R.layout.nav_list, container, false);
+ SharedPreferences preferences = getContext().getSharedPreferences(PREF_NAME, Context.MODE_PRIVATE);
+ openFolders = new HashSet<>(preferences.getStringSet(PREF_OPEN_FOLDERS, new HashSet<>())); // Must not modify
+
progressBar = root.findViewById(R.id.progressBar);
- ListView navList = root.findViewById(R.id.nav_list);
+ RecyclerView navList = root.findViewById(R.id.nav_list);
navAdapter = new NavListAdapter(itemAccess, getActivity());
+ navAdapter.setHasStableIds(true);
navList.setAdapter(navAdapter);
- navList.setOnItemClickListener(this);
- navList.setOnItemLongClickListener(this);
- registerForContextMenu(navList);
- updateSelection();
+ navList.setLayoutManager(new LinearLayoutManager(getContext()));
root.findViewById(R.id.nav_settings).setOnClickListener(v ->
startActivity(new Intent(getActivity(), PreferenceActivity.class)));
- getContext().getSharedPreferences(PREF_NAME, Context.MODE_PRIVATE)
- .registerOnSharedPreferenceChangeListener(this);
- return root;
- }
- private void updateSelection() {
- String lastNavFragment = getLastNavFragment(getContext());
- int tagIndex = navAdapter.getTags().indexOf(lastNavFragment);
- if (tagIndex >= 0) {
- selectedNavListIndex = tagIndex;
- } else if (StringUtils.isNumeric(lastNavFragment)) { // last fragment was not a list, but a feed
- long feedId = Long.parseLong(lastNavFragment);
- if (navDrawerData != null) {
- List<Feed> feeds = navDrawerData.feeds;
- for (int i = 0; i < feeds.size(); i++) {
- if (feeds.get(i).getId() == feedId) {
- selectedNavListIndex = navAdapter.getSubscriptionOffset() + i;
- break;
- }
- }
- }
- }
- navAdapter.notifyDataSetChanged();
+ preferences.registerOnSharedPreferenceChangeListener(this);
+ return root;
}
@Override
@@ -135,29 +122,25 @@ public class NavDrawerFragment extends Fragment implements AdapterView.OnItemCli
@Override
public void onCreateContextMenu(@NonNull ContextMenu menu, @NonNull View v, ContextMenu.ContextMenuInfo menuInfo) {
super.onCreateContextMenu(menu, v, menuInfo);
- if (v.getId() != R.id.nav_list) {
- return;
- }
- AdapterView.AdapterContextMenuInfo adapterInfo = (AdapterView.AdapterContextMenuInfo) menuInfo;
- int position = adapterInfo.position;
- if (position < navAdapter.getSubscriptionOffset()) {
- return;
+ if (contextPressedItem.type != NavDrawerData.DrawerItem.Type.FEED) {
+ return; // Should actually never happen because the context menu is not set up for other items
}
+
MenuInflater inflater = getActivity().getMenuInflater();
inflater.inflate(R.menu.nav_feed_context, menu);
- Feed feed = navDrawerData.feeds.get(position - navAdapter.getSubscriptionOffset());
- menu.setHeaderTitle(feed.getTitle());
+ menu.setHeaderTitle(((NavDrawerData.FeedDrawerItem) contextPressedItem).feed.getTitle());
// episodes are not loaded, so we cannot check if the podcast has new or unplayed ones!
}
@Override
public boolean onContextItemSelected(@NonNull MenuItem item) {
- final int position = this.position;
- this.position = -1; // reset
- if (position < 0) {
- return false;
+ if (contextPressedItem.type == NavDrawerData.DrawerItem.Type.FEED) {
+ return onFeedContextMenuClicked(((NavDrawerData.FeedDrawerItem) contextPressedItem).feed, item);
}
- Feed feed = navDrawerData.feeds.get(position - navAdapter.getSubscriptionOffset());
+ return false;
+ }
+
+ private boolean onFeedContextMenuClicked(Feed feed, MenuItem item) {
switch (item.getItemId()) {
case R.id.remove_all_new_flags_item:
ConfirmationDialog removeAllNewFlagsConfirmationDialog = new ConfirmationDialog(getContext(),
@@ -189,13 +172,7 @@ public class NavDrawerFragment extends Fragment implements AdapterView.OnItemCli
return true;
case R.id.remove_item:
RemoveFeedDialog.show(getContext(), feed, () -> {
- if (selectedNavListIndex == position) {
- if (getActivity() instanceof MainActivity) {
- ((MainActivity) getActivity()).loadFragment(EpisodesFragment.TAG, null);
- } else {
- showMainActivity(EpisodesFragment.TAG);
- }
- }
+ ((MainActivity) getActivity()).loadFragment(EpisodesFragment.TAG, null);
});
return true;
default:
@@ -203,12 +180,6 @@ public class NavDrawerFragment extends Fragment implements AdapterView.OnItemCli
}
}
- private void showMainActivity(String tag) {
- Intent intent = new Intent(getActivity(), MainActivity.class);
- intent.putExtra(MainActivity.EXTRA_FRAGMENT_TAG, tag);
- startActivity(intent);
- }
-
@Subscribe(threadMode = ThreadMode.MAIN)
public void onUnreadItemsChanged(UnreadItemsUpdateEvent event) {
loadData();
@@ -261,7 +232,7 @@ public class NavDrawerFragment extends Fragment implements AdapterView.OnItemCli
});
builder.setPositiveButton(R.string.confirm_label, (dialog, which) -> {
UserPreferences.setHiddenDrawerItems(hiddenDrawerItems);
- updateSelection();
+ navAdapter.notifyDataSetChanged(); // Update selection
});
builder.setNegativeButton(R.string.cancel_label, null);
builder.create().show();
@@ -270,25 +241,39 @@ public class NavDrawerFragment extends Fragment implements AdapterView.OnItemCli
private final NavListAdapter.ItemAccess itemAccess = new NavListAdapter.ItemAccess() {
@Override
public int getCount() {
- if (navDrawerData != null) {
- return navDrawerData.feeds.size();
+ if (flatItemList != null) {
+ return flatItemList.size();
} else {
return 0;
}
}
@Override
- public Feed getItem(int position) {
- if (navDrawerData != null && 0 <= position && position < navDrawerData.feeds.size()) {
- return navDrawerData.feeds.get(position);
+ public NavDrawerData.DrawerItem getItem(int position) {
+ if (flatItemList != null && 0 <= position && position < flatItemList.size()) {
+ return flatItemList.get(position);
} else {
return null;
}
}
@Override
- public int getSelectedItemIndex() {
- return selectedNavListIndex;
+ public boolean isSelected(int position) {
+ String lastNavFragment = getLastNavFragment(getContext());
+ if (position < navAdapter.getSubscriptionOffset()) {
+ return navAdapter.getFragmentTags().get(position).equals(lastNavFragment);
+ } else if (StringUtils.isNumeric(lastNavFragment)) { // last fragment was not a list, but a feed
+ long feedId = Long.parseLong(lastNavFragment);
+ if (navDrawerData != null) {
+ NavDrawerData.DrawerItem itemToCheck = flatItemList.get(
+ position - navAdapter.getSubscriptionOffset());
+ if (itemToCheck.type == NavDrawerData.DrawerItem.Type.FEED) {
+ // When the same feed is displayed multiple times, it should be highlighted multiple times.
+ return ((NavDrawerData.FeedDrawerItem) itemToCheck).feed.getId() == feedId;
+ }
+ }
+ }
+ return false;
}
@Override
@@ -312,11 +297,6 @@ public class NavDrawerFragment extends Fragment implements AdapterView.OnItemCli
}
@Override
- public int getFeedCounter(long feedId) {
- return navDrawerData != null ? navDrawerData.feedCounters.get(feedId) : 0;
- }
-
- @Override
public int getFeedCounterSum() {
if (navDrawerData == null) {
return 0;
@@ -328,16 +308,82 @@ public class NavDrawerFragment extends Fragment implements AdapterView.OnItemCli
return sum;
}
+ @Override
+ public void onItemClick(int position) {
+ int viewType = navAdapter.getItemViewType(position);
+ if (viewType != NavListAdapter.VIEW_TYPE_SECTION_DIVIDER) {
+ if (position < navAdapter.getSubscriptionOffset()) {
+ String tag = navAdapter.getFragmentTags().get(position);
+ ((MainActivity) getActivity()).loadFragment(tag, null);
+ ((MainActivity) getActivity()).getBottomSheet().setState(BottomSheetBehavior.STATE_COLLAPSED);
+ } else {
+ int pos = position - navAdapter.getSubscriptionOffset();
+ NavDrawerData.DrawerItem clickedItem = flatItemList.get(pos);
+
+ if (clickedItem.type == NavDrawerData.DrawerItem.Type.FEED) {
+ long feedId = ((NavDrawerData.FeedDrawerItem) clickedItem).feed.getId();
+ ((MainActivity) getActivity()).loadFeedFragmentById(feedId, null);
+ ((MainActivity) getActivity()).getBottomSheet()
+ .setState(BottomSheetBehavior.STATE_COLLAPSED);
+ } else {
+ NavDrawerData.FolderDrawerItem folder = ((NavDrawerData.FolderDrawerItem) clickedItem);
+ if (openFolders.contains(folder.name)) {
+ openFolders.remove(folder.name);
+ } else {
+ openFolders.add(folder.name);
+ }
+
+ getContext().getSharedPreferences(PREF_NAME, Context.MODE_PRIVATE)
+ .edit()
+ .putStringSet(PREF_OPEN_FOLDERS, openFolders)
+ .apply();
+
+ disposable = Observable.fromCallable(() -> makeFlatDrawerData(navDrawerData.items, 0))
+ .subscribeOn(Schedulers.computation())
+ .observeOn(AndroidSchedulers.mainThread())
+ .subscribe(
+ result -> {
+ flatItemList = result;
+ navAdapter.notifyDataSetChanged();
+ }, error -> Log.e(TAG, Log.getStackTraceString(error)));
+ }
+ }
+ } else if (UserPreferences.getSubscriptionsFilter().isEnabled()
+ && navAdapter.showSubscriptionList) {
+ SubscriptionsFilterDialog.showDialog(requireContext());
+ }
+ }
+
+ @Override
+ public boolean onItemLongClick(int position) {
+ if (position < navAdapter.getFragmentTags().size()) {
+ showDrawerPreferencesDialog();
+ return true;
+ } else {
+ contextPressedItem = flatItemList.get(position - navAdapter.getSubscriptionOffset());
+ return false;
+ }
+ }
+
+ @Override
+ public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
+ NavDrawerFragment.this.onCreateContextMenu(menu, v, menuInfo);
+ }
};
private void loadData() {
- disposable = Observable.fromCallable(DBReader::getNavDrawerData)
+ progressBar.setVisibility(View.VISIBLE);
+ disposable = Observable.fromCallable(
+ () -> {
+ NavDrawerData data = DBReader.getNavDrawerData();
+ return new Pair<>(data, makeFlatDrawerData(data.items, 0));
+ })
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(
result -> {
- navDrawerData = result;
- updateSelection(); // Selected item might be a feed
+ navDrawerData = result.first;
+ flatItemList = result.second;
navAdapter.notifyDataSetChanged();
progressBar.setVisibility(View.GONE); // Stays hidden once there is something in the list
}, error -> {
@@ -346,45 +392,20 @@ public class NavDrawerFragment extends Fragment implements AdapterView.OnItemCli
});
}
- @Override
- public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
- int viewType = parent.getAdapter().getItemViewType(position);
- if (viewType != NavListAdapter.VIEW_TYPE_SECTION_DIVIDER) {
- if (position < navAdapter.getSubscriptionOffset()) {
- String tag = navAdapter.getTags().get(position);
- if (getActivity() instanceof MainActivity) {
- ((MainActivity) getActivity()).loadFragment(tag, null);
- ((MainActivity) getActivity()).getBottomSheet().setState(BottomSheetBehavior.STATE_COLLAPSED);
- } else {
- showMainActivity(tag);
- }
- } else {
- int pos = position - navAdapter.getSubscriptionOffset();
- long feedId = navDrawerData.feeds.get(pos).getId();
- if (getActivity() instanceof MainActivity) {
- ((MainActivity) getActivity()).loadFeedFragmentById(feedId, null);
- ((MainActivity) getActivity()).getBottomSheet().setState(BottomSheetBehavior.STATE_COLLAPSED);
- } else {
- Intent intent = new Intent(getActivity(), MainActivity.class);
- intent.putExtra(MainActivity.EXTRA_FEED_ID, feedId);
- startActivity(intent);
+ private List<NavDrawerData.DrawerItem> makeFlatDrawerData(List<NavDrawerData.DrawerItem> items, int layer) {
+ List<NavDrawerData.DrawerItem> flatItems = new ArrayList<>();
+ for (NavDrawerData.DrawerItem item : items) {
+ item.setLayer(layer);
+ flatItems.add(item);
+ if (item.type == NavDrawerData.DrawerItem.Type.FOLDER) {
+ NavDrawerData.FolderDrawerItem folder = ((NavDrawerData.FolderDrawerItem) item);
+ folder.isOpen = openFolders.contains(folder.name);
+ if (folder.isOpen) {
+ flatItems.addAll(makeFlatDrawerData(((NavDrawerData.FolderDrawerItem) item).children, layer + 1));
}
}
- } else if (UserPreferences.getSubscriptionsFilter().isEnabled()
- && navAdapter.showSubscriptionList) {
- SubscriptionsFilterDialog.showDialog(requireContext());
- }
- }
-
- @Override
- public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {
- if (position < navAdapter.getTags().size()) {
- showDrawerPreferencesDialog();
- return true;
- } else {
- this.position = position;
- return false;
}
+ return flatItems;
}
public static void saveLastNavFragment(Context context, String tag) {
@@ -409,8 +430,7 @@ public class NavDrawerFragment extends Fragment implements AdapterView.OnItemCli
@Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
if (PREF_LAST_FRAGMENT_TAG.equals(key)) {
- updateSelection();
- navAdapter.notifyDataSetChanged();
+ navAdapter.notifyDataSetChanged(); // Update selection
}
}
}
diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/SubscriptionFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/SubscriptionFragment.java
index 9bbc03fba..58cfece14 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/SubscriptionFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/fragment/SubscriptionFragment.java
@@ -28,6 +28,7 @@ import android.widget.TextView;
import com.google.android.material.floatingactionbutton.FloatingActionButton;
import com.joanzapata.iconify.Iconify;
+import java.util.List;
import java.util.Locale;
import java.util.concurrent.Callable;
@@ -44,6 +45,7 @@ import de.danoeh.antennapod.core.service.download.DownloadService;
import de.danoeh.antennapod.core.storage.DBReader;
import de.danoeh.antennapod.core.storage.DBWriter;
import de.danoeh.antennapod.core.storage.DownloadRequester;
+import de.danoeh.antennapod.core.storage.NavDrawerData;
import de.danoeh.antennapod.core.util.download.AutoUpdateManager;
import de.danoeh.antennapod.dialog.RemoveFeedDialog;
import de.danoeh.antennapod.dialog.SubscriptionsFilterDialog;
@@ -68,6 +70,7 @@ public class SubscriptionFragment extends Fragment implements Toolbar.OnMenuItem
private static final String PREFS = "SubscriptionFragment";
private static final String PREF_NUM_COLUMNS = "columns";
private static final String KEY_UP_ARROW = "up_arrow";
+ private static final String ARGUMENT_FOLDER = "folder";
private static final int MIN_NUM_COLUMNS = 2;
private static final int[] COLUMN_CHECKBOX_IDS = {
@@ -77,21 +80,30 @@ public class SubscriptionFragment extends Fragment implements Toolbar.OnMenuItem
R.id.subscription_num_columns_5};
private GridView subscriptionGridLayout;
- private DBReader.NavDrawerData navDrawerData;
+ private List<NavDrawerData.DrawerItem> listItems;
private SubscriptionsAdapter subscriptionAdapter;
private FloatingActionButton subscriptionAddButton;
private ProgressBar progressBar;
private EmptyViewHandler emptyView;
private TextView feedsFilteredMsg;
private Toolbar toolbar;
+ private String displayedFolder = null;
- private int mPosition = -1;
+ private Feed selectedFeed = null;
private boolean isUpdatingFeeds = false;
private boolean displayUpArrow;
private Disposable disposable;
private SharedPreferences prefs;
+ public static SubscriptionFragment newInstance(String folderTitle) {
+ SubscriptionFragment fragment = new SubscriptionFragment();
+ Bundle args = new Bundle();
+ args.putString(ARGUMENT_FOLDER, folderTitle);
+ fragment.setArguments(args);
+ return fragment;
+ }
+
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
@@ -119,6 +131,13 @@ public class SubscriptionFragment extends Fragment implements Toolbar.OnMenuItem
}
refreshToolbarState();
+ if (getArguments() != null) {
+ displayedFolder = getArguments().getString(ARGUMENT_FOLDER, null);
+ if (displayedFolder != null) {
+ toolbar.setTitle(displayedFolder);
+ }
+ }
+
subscriptionGridLayout = root.findViewById(R.id.subscriptions_grid);
subscriptionGridLayout.setNumColumns(prefs.getInt(PREF_NUM_COLUMNS, getDefaultNumOfColumns()));
registerForContextMenu(subscriptionGridLayout);
@@ -231,12 +250,23 @@ public class SubscriptionFragment extends Fragment implements Toolbar.OnMenuItem
disposable.dispose();
}
emptyView.hide();
- disposable = Observable.fromCallable(DBReader::getNavDrawerData)
+ disposable = Observable.fromCallable(
+ () -> {
+ NavDrawerData data = DBReader.getNavDrawerData();
+ List<NavDrawerData.DrawerItem> items = data.items;
+ for (NavDrawerData.DrawerItem item : items) {
+ if (item.type == NavDrawerData.DrawerItem.Type.FOLDER
+ && item.getTitle().equals(displayedFolder)) {
+ return ((NavDrawerData.FolderDrawerItem) item).children;
+ }
+ }
+ return items;
+ })
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(
result -> {
- navDrawerData = result;
+ listItems = result;
subscriptionAdapter.notifyDataSetChanged();
emptyView.updateVisibility();
progressBar.setVisibility(View.GONE); // Keep hidden to avoid flickering while refreshing
@@ -264,37 +294,24 @@ public class SubscriptionFragment extends Fragment implements Toolbar.OnMenuItem
AdapterView.AdapterContextMenuInfo adapterInfo = (AdapterView.AdapterContextMenuInfo) menuInfo;
int position = adapterInfo.position;
- Object selectedObject = subscriptionAdapter.getItem(position);
- if (selectedObject.equals(SubscriptionsAdapter.ADD_ITEM_OBJ)) {
- mPosition = position;
- return;
- }
-
- Feed feed = (Feed) selectedObject;
-
- MenuInflater inflater = requireActivity().getMenuInflater();
- inflater.inflate(R.menu.nav_feed_context, menu);
+ NavDrawerData.DrawerItem selectedObject = (NavDrawerData.DrawerItem) subscriptionAdapter.getItem(position);
- menu.setHeaderTitle(feed.getTitle());
-
- mPosition = position;
+ if (selectedObject.type == NavDrawerData.DrawerItem.Type.FEED) {
+ MenuInflater inflater = requireActivity().getMenuInflater();
+ inflater.inflate(R.menu.nav_feed_context, menu);
+ selectedFeed = ((NavDrawerData.FeedDrawerItem) selectedObject).feed;
+ }
+ menu.setHeaderTitle(selectedObject.getTitle());
}
@Override
public boolean onContextItemSelected(MenuItem item) {
- final int position = mPosition;
- mPosition = -1; // reset
- if (position < 0) {
- return false;
- }
-
- Object selectedObject = subscriptionAdapter.getItem(position);
- if (selectedObject.equals(SubscriptionsAdapter.ADD_ITEM_OBJ)) {
- // this is the add object, do nothing
+ if (selectedFeed == null) {
return false;
}
- Feed feed = (Feed) selectedObject;
+ Feed feed = selectedFeed;
+ selectedFeed = null;
switch (item.getItemId()) {
case R.id.remove_all_new_flags_item:
displayConfirmationDialog(
@@ -359,25 +376,20 @@ public class SubscriptionFragment extends Fragment implements Toolbar.OnMenuItem
private final SubscriptionsAdapter.ItemAccess itemAccess = new SubscriptionsAdapter.ItemAccess() {
@Override
public int getCount() {
- if (navDrawerData != null) {
- return navDrawerData.feeds.size();
+ if (listItems != null) {
+ return listItems.size();
} else {
return 0;
}
}
@Override
- public Feed getItem(int position) {
- if (navDrawerData != null && 0 <= position && position < navDrawerData.feeds.size()) {
- return navDrawerData.feeds.get(position);
+ public NavDrawerData.DrawerItem getItem(int position) {
+ if (listItems != null && 0 <= position && position < listItems.size()) {
+ return listItems.get(position);
} else {
return null;
}
}
-
- @Override
- public int getFeedCounter(long feedId) {
- return navDrawerData != null ? navDrawerData.feedCounters.get(feedId) : 0;
- }
};
}