summaryrefslogtreecommitdiff
path: root/app/src/main/java/de/danoeh
diff options
context:
space:
mode:
Diffstat (limited to 'app/src/main/java/de/danoeh')
-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.java254
-rw-r--r--app/src/main/java/de/danoeh/antennapod/adapter/SubscriptionsAdapter.java59
-rw-r--r--app/src/main/java/de/danoeh/antennapod/fragment/FeedSettingsFragment.java26
-rw-r--r--app/src/main/java/de/danoeh/antennapod/fragment/NavDrawerFragment.java172
-rw-r--r--app/src/main/java/de/danoeh/antennapod/fragment/SubscriptionFragment.java11
6 files changed, 349 insertions, 206 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..8bfcf66cc 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,20 @@
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.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 +23,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 +31,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 +44,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 +57,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 +97,7 @@ public class NavListAdapter extends BaseAdapter
showSubscriptionList = false;
}
- tags = newTags;
+ fragmentTags = newTags;
notifyDataSetChanged();
}
@@ -140,12 +141,11 @@ public class NavListAdapter extends BaseAdapter
}
public List<String> getTags() {
- return Collections.unmodifiableList(tags);
+ return Collections.unmodifiableList(fragmentTags);
}
-
@Override
- public int getCount() {
+ public int getItemCount() {
int baseCount = getSubscriptionOffset();
if (showSubscriptionList) {
baseCount += itemAccess.getCount();
@@ -154,25 +154,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; //TODO
}
}
@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 +174,68 @@ 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;
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);
+ } 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);
+ activity.get().getTheme().resolveAttribute(R.attr.drawer_activated_color, typedValue, true);
+ holder.itemView.setBackgroundResource(typedValue.resourceId);
} else {
- v.getContext().getTheme().resolveAttribute(android.R.attr.windowBackground, typedValue, true);
- v.setBackgroundResource(typedValue.resourceId);
+ activity.get().getTheme().resolveAttribute(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();
+ 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) {
@@ -282,58 +274,43 @@ public class NavListAdapter extends BaseAdapter
}
}
- 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;
+ 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());
+ holder.itemView.setPadding(item.getLayer() * 50, 0, 0, 0); // TODO
}
- 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 +323,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 +332,86 @@ 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);
+ }
+ }
+
+ 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 {
int getCount();
- Feed getItem(int position);
+
+ NavDrawerData.DrawerItem getItem(int position);
+
int getSelectedItemIndex();
+
int getQueueSize();
+
int getNumberOfNewItems();
+
int getNumberOfDownloadedItems();
+
int getReclaimableItems();
+
int getFeedCounter(long feedId);
+
int getFeedCounterSum();
+
+ void onItemClick(int position);
+
+ boolean onItemLongClick(int position);
}
}
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..1d85cdaff 100644
--- a/app/src/main/java/de/danoeh/antennapod/adapter/SubscriptionsAdapter.java
+++ b/app/src/main/java/de/danoeh/antennapod/adapter/SubscriptionsAdapter.java
@@ -21,7 +21,9 @@ 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.ui.common.ThemeUtils;
import jp.shts.android.library.TriangleLabelView;
/**
@@ -60,7 +62,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 +85,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 +100,43 @@ 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);
+ }
}
static class Holder {
@@ -130,7 +147,9 @@ public class SubscriptionsAdapter extends BaseAdapter implements AdapterView.OnI
public interface ItemAccess {
int getCount();
- Feed getItem(int position);
+
+ NavDrawerData.DrawerItem getItem(int position);
+
int getFeedCounter(long feedId);
}
}
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..c000107a7 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/FeedSettingsFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/fragment/FeedSettingsFragment.java
@@ -9,6 +9,7 @@ import android.view.View;
import android.view.ViewGroup;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
+import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.widget.Toolbar;
import androidx.fragment.app.Fragment;
import androidx.preference.ListPreference;
@@ -27,6 +28,7 @@ import de.danoeh.antennapod.core.feed.VolumeAdaptionSetting;
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.databinding.EditTextDialogBinding;
import de.danoeh.antennapod.dialog.AuthenticationDialog;
import de.danoeh.antennapod.dialog.EpisodeFilterDialog;
import de.danoeh.antennapod.dialog.FeedPreferenceSkipDialog;
@@ -39,6 +41,8 @@ import org.greenrobot.eventbus.EventBus;
import java.text.DecimalFormat;
import java.text.DecimalFormatSymbols;
+import java.util.Arrays;
+import java.util.HashSet;
import java.util.Locale;
import static de.danoeh.antennapod.core.feed.FeedPreferences.SPEED_USE_GLOBAL;
@@ -105,6 +109,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 +165,7 @@ public class FeedSettingsFragment extends Fragment {
setupPlaybackSpeedPreference();
setupFeedAutoSkipPreference();
setupEpisodeNotificationPreference();
+ setupTags();
updateAutoDeleteSummary();
updateVolumeReductionValue();
@@ -395,6 +401,26 @@ public class FeedSettingsFragment extends Fragment {
}
}
+ private void setupTags() {
+ findPreference(PREF_TAGS).setOnPreferenceClickListener(preference -> {
+ EditTextDialogBinding alertViewBinding = EditTextDialogBinding.inflate(getLayoutInflater());
+ alertViewBinding.urlEditText.setText(feed.getPreferences().getTagsAsString());
+ new AlertDialog.Builder(getContext())
+ .setView(alertViewBinding.getRoot())
+ .setTitle(R.string.feed_folders_label)
+ .setPositiveButton(android.R.string.ok, (d, input) -> {
+ String foldersString = alertViewBinding.urlEditText.getText().toString();
+ feedPreferences.getTags().clear();
+ feedPreferences.getTags().addAll(new HashSet<>(Arrays.asList(
+ foldersString.split(FeedPreferences.TAG_SEPARATOR))));
+ DBWriter.setFeedPreferences(feedPreferences);
+ })
+ .setNegativeButton(R.string.cancel_label, null)
+ .show();
+ 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..e8c04336f 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/NavDrawerFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/fragment/NavDrawerFragment.java
@@ -13,14 +13,16 @@ 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 +36,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,10 +49,12 @@ 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";
@VisibleForTesting
@@ -66,12 +71,14 @@ public class NavDrawerFragment extends Fragment implements AdapterView.OnItemCli
NavListAdapter.SUBSCRIPTION_LIST_TAG
};
- private DBReader.NavDrawerData navDrawerData;
+ private NavDrawerData navDrawerData;
+ private List<NavDrawerData.DrawerItem> flatItemList;
private int selectedNavListIndex = -1;
private int position = -1;
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,
@@ -80,11 +87,11 @@ public class NavDrawerFragment extends Fragment implements AdapterView.OnItemCli
View root = inflater.inflate(R.layout.nav_list, container, false);
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);
+ navList.setLayoutManager(new LinearLayoutManager(getContext()));
registerForContextMenu(navList);
updateSelection();
@@ -103,9 +110,10 @@ public class NavDrawerFragment extends Fragment implements AdapterView.OnItemCli
} 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) {
+ List<NavDrawerData.DrawerItem> items = flatItemList;
+ for (int i = 0; i < items.size(); i++) {
+ if (items.get(i).type == NavDrawerData.DrawerItem.Type.FEED
+ && ((NavDrawerData.FeedDrawerItem) items.get(i)).feed.getId() == feedId) {
selectedNavListIndex = navAdapter.getSubscriptionOffset() + i;
break;
}
@@ -145,8 +153,11 @@ public class NavDrawerFragment extends Fragment implements AdapterView.OnItemCli
}
MenuInflater inflater = getActivity().getMenuInflater();
inflater.inflate(R.menu.nav_feed_context, menu);
- Feed feed = navDrawerData.feeds.get(position - navAdapter.getSubscriptionOffset());
- menu.setHeaderTitle(feed.getTitle());
+
+ NavDrawerData.DrawerItem drawerItem = flatItemList.get(position - navAdapter.getSubscriptionOffset());
+ if (drawerItem.type == NavDrawerData.DrawerItem.Type.FEED) {
+ menu.setHeaderTitle(((NavDrawerData.FeedDrawerItem) drawerItem).feed.getTitle());
+ }
// episodes are not loaded, so we cannot check if the podcast has new or unplayed ones!
}
@@ -157,7 +168,14 @@ public class NavDrawerFragment extends Fragment implements AdapterView.OnItemCli
if (position < 0) {
return false;
}
- Feed feed = navDrawerData.feeds.get(position - navAdapter.getSubscriptionOffset());
+ NavDrawerData.DrawerItem drawerItem = flatItemList.get(position - navAdapter.getSubscriptionOffset());
+ if (drawerItem.type == NavDrawerData.DrawerItem.Type.FEED) {
+ return onFeedContextMenuClicked(((NavDrawerData.FeedDrawerItem) drawerItem).feed, item);
+ }
+ 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(),
@@ -270,17 +288,17 @@ 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;
}
@@ -328,15 +346,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.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();
+ NavDrawerData.DrawerItem clickedItem = flatItemList.get(pos);
+
+ if (clickedItem.type == NavDrawerData.DrawerItem.Type.FEED) {
+ long feedId = ((NavDrawerData.FeedDrawerItem) clickedItem).feed.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);
+ }
+ } else {
+ NavDrawerData.FolderDrawerItem folder = ((NavDrawerData.FolderDrawerItem) clickedItem);
+ if (openFolders.contains(folder.name)) {
+ openFolders.remove(folder.name);
+ } else {
+ openFolders.add(folder.name);
+ }
+
+ 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.getTags().size()) {
+ showDrawerPreferencesDialog();
+ return true;
+ } else {
+ NavDrawerFragment.this.position = position;
+ return false;
+ }
+ }
};
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;
+ navDrawerData = result.first;
+ flatItemList = result.second;
updateSelection(); // Selected item might be a feed
navAdapter.notifyDataSetChanged();
progressBar.setVisibility(View.GONE); // Stays hidden once there is something in the list
@@ -346,45 +431,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) {
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..3c529d941 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/SubscriptionFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/fragment/SubscriptionFragment.java
@@ -44,6 +44,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;
@@ -77,7 +78,7 @@ public class SubscriptionFragment extends Fragment implements Toolbar.OnMenuItem
R.id.subscription_num_columns_5};
private GridView subscriptionGridLayout;
- private DBReader.NavDrawerData navDrawerData;
+ private NavDrawerData navDrawerData;
private SubscriptionsAdapter subscriptionAdapter;
private FloatingActionButton subscriptionAddButton;
private ProgressBar progressBar;
@@ -360,16 +361,16 @@ public class SubscriptionFragment extends Fragment implements Toolbar.OnMenuItem
@Override
public int getCount() {
if (navDrawerData != null) {
- return navDrawerData.feeds.size();
+ return navDrawerData.items.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 (navDrawerData != null && 0 <= position && position < navDrawerData.items.size()) {
+ return navDrawerData.items.get(position);
} else {
return null;
}