From 2a2c4958358514ba5ca56ca4faafdd3bbb55767d Mon Sep 17 00:00:00 2001 From: ByteHamster Date: Mon, 2 Nov 2020 19:56:26 +0100 Subject: Added basic proof of concept for displaying folders --- .../de/test/antennapod/storage/DBReaderTest.java | 9 +-- .../danoeh/antennapod/adapter/NavListAdapter.java | 80 +++++++++++++++++---- .../antennapod/adapter/SubscriptionsAdapter.java | 5 +- .../antennapod/fragment/NavDrawerFragment.java | 84 +++++++++++++++++----- .../antennapod/fragment/SubscriptionFragment.java | 11 +-- 5 files changed, 144 insertions(+), 45 deletions(-) (limited to 'app/src') diff --git a/app/src/androidTest/java/de/test/antennapod/storage/DBReaderTest.java b/app/src/androidTest/java/de/test/antennapod/storage/DBReaderTest.java index 8811d9b31..4dd8a7427 100644 --- a/app/src/androidTest/java/de/test/antennapod/storage/DBReaderTest.java +++ b/app/src/androidTest/java/de/test/antennapod/storage/DBReaderTest.java @@ -11,6 +11,7 @@ import de.danoeh.antennapod.core.feed.Feed; import de.danoeh.antennapod.core.feed.FeedItem; import de.danoeh.antennapod.core.feed.FeedMedia; import de.danoeh.antennapod.core.storage.DBReader; +import de.danoeh.antennapod.core.storage.NavDrawerData; import de.danoeh.antennapod.core.storage.PodDBAdapter; import de.danoeh.antennapod.core.util.LongList; import org.junit.After; @@ -313,8 +314,8 @@ public class DBReaderTest { final int NUM_FEEDS = 10; final int NUM_ITEMS = 10; DBTestUtils.saveFeedlist(NUM_FEEDS, NUM_ITEMS, true); - DBReader.NavDrawerData navDrawerData = DBReader.getNavDrawerData(); - assertEquals(NUM_FEEDS, navDrawerData.feeds.size()); + NavDrawerData navDrawerData = DBReader.getNavDrawerData(); + assertEquals(NUM_FEEDS, navDrawerData.items.size()); assertEquals(0, navDrawerData.numNewItems); assertEquals(0, navDrawerData.queueSize); } @@ -342,8 +343,8 @@ public class DBReaderTest { adapter.close(); - DBReader.NavDrawerData navDrawerData = DBReader.getNavDrawerData(); - assertEquals(NUM_FEEDS, navDrawerData.feeds.size()); + NavDrawerData navDrawerData = DBReader.getNavDrawerData(); + assertEquals(NUM_FEEDS, navDrawerData.items.size()); assertEquals(NUM_NEW, navDrawerData.numNewItems); assertEquals(NUM_QUEUE, navDrawerData.queueSize); } 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 92ed7b052..300687e70 100644 --- a/app/src/main/java/de/danoeh/antennapod/adapter/NavListAdapter.java +++ b/app/src/main/java/de/danoeh/antennapod/adapter/NavListAdapter.java @@ -23,6 +23,8 @@ 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.core.util.ThemeUtils; import de.danoeh.antennapod.fragment.AddFeedFragment; import de.danoeh.antennapod.fragment.DownloadsFragment; import de.danoeh.antennapod.fragment.EpisodesFragment; @@ -56,7 +58,7 @@ public class NavListAdapter extends BaseAdapter */ public static final String SUBSCRIPTION_LIST_TAG = "SubscriptionList"; - private static List tags; + private static List 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(); } @@ -140,7 +142,7 @@ public class NavListAdapter extends BaseAdapter } public List getTags() { - return Collections.unmodifiableList(tags); + return Collections.unmodifiableList(fragmentTags); } @@ -157,7 +159,7 @@ public class NavListAdapter extends BaseAdapter public Object getItem(int position) { int viewType = getItemViewType(position); if (viewType == VIEW_TYPE_NAV) { - return getLabel(tags.get(position)); + return getLabel(fragmentTags.get(position)); } else if (viewType == VIEW_TYPE_SECTION_DIVIDER) { return ""; } else { @@ -167,12 +169,22 @@ public class NavListAdapter extends BaseAdapter @Override public long getItemId(int position) { - return position; + int viewType = getItemViewType(position); + if (viewType == VIEW_TYPE_SUBSCRIPTION) { + return itemAccess.getItem(position - getSubscriptionOffset()).id; + } else { + return -position - 1; //TODO + } + } + + @Override + public boolean hasStableIds() { + return true; } @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; @@ -187,7 +199,7 @@ public class NavListAdapter extends BaseAdapter } public int getSubscriptionOffset() { - return tags.size() > 0 ? tags.size() + 1 : 0; + return fragmentTags.size() > 0 ? fragmentTags.size() + 1 : 0; } @@ -200,7 +212,13 @@ public class NavListAdapter extends BaseAdapter } else if (viewType == VIEW_TYPE_SECTION_DIVIDER) { v = getSectionDividerView(convertView, parent); } else { - v = getFeedView(position, convertView, parent); + int itemPos = position - getSubscriptionOffset(); + NavDrawerData.DrawerItem item = itemAccess.getItem(itemPos); + if (item.type == NavDrawerData.DrawerItem.Type.FEED) { + v = getFeedView((NavDrawerData.FeedDrawerItem) item, convertView, parent); + } else { + v = getFolderView((NavDrawerData.FolderDrawerItem) item, convertView, parent); + } } if (v != null && viewType != VIEW_TYPE_SECTION_DIVIDER) { TypedValue typedValue = new TypedValue(); @@ -243,7 +261,7 @@ public class NavListAdapter extends BaseAdapter 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,7 +300,7 @@ public class NavListAdapter extends BaseAdapter } } - holder.image.setImageDrawable(getDrawable(tags.get(position))); + holder.image.setImageDrawable(getDrawable(fragmentTags.get(position))); return convertView; } @@ -311,13 +329,12 @@ public class NavListAdapter extends BaseAdapter return convertView; } - private View getFeedView(int position, View convertView, ViewGroup parent) { + private View getFeedView(NavDrawerData.FeedDrawerItem drawerItem, View convertView, ViewGroup parent) { + Feed feed = drawerItem.feed; Activity context = activity.get(); - if(context == null) { + if (context == null) { return null; } - int feedPos = position - getSubscriptionOffset(); - Feed feed = itemAccess.getItem(feedPos); FeedHolder holder; if (convertView == null) { @@ -364,6 +381,39 @@ public class NavListAdapter extends BaseAdapter } else { holder.count.setVisibility(View.GONE); } + convertView.setPadding(drawerItem.layer * 50, 0, 0, 0); // TODO + return convertView; + } + + private View getFolderView(NavDrawerData.FolderDrawerItem drawerItem, View convertView, ViewGroup parent) { + Activity context = activity.get(); + if (context == null) { + return null; + } + + 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(); + } + + holder.image.setImageResource(ThemeUtils.getDrawableFromAttr(context, R.attr.ic_folder)); + holder.title.setText(drawerItem.name); + holder.failure.setVisibility(View.GONE); + holder.count.setText("?"); + + convertView.setPadding(drawerItem.layer * 50, 0, 0, 0); // TODO return convertView; } @@ -382,7 +432,7 @@ public class NavListAdapter extends BaseAdapter public interface ItemAccess { int getCount(); - Feed getItem(int position); + NavDrawerData.DrawerItem getItem(int position); int getSelectedItemIndex(); int getQueueSize(); int getNumberOfNewItems(); 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 8c294a9c9..300cb9f57 100644 --- a/app/src/main/java/de/danoeh/antennapod/adapter/SubscriptionsAdapter.java +++ b/app/src/main/java/de/danoeh/antennapod/adapter/SubscriptionsAdapter.java @@ -23,6 +23,7 @@ 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.AddFeedFragment; import de.danoeh.antennapod.fragment.FeedItemlistFragment; import jp.shts.android.library.TriangleLabelView; @@ -63,7 +64,7 @@ public class SubscriptionsAdapter extends BaseAdapter implements AdapterView.OnI @Override public long getItemId(int position) { - return itemAccess.getItem(position).getId(); + return position; // TODO } @Override @@ -133,7 +134,7 @@ 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/NavDrawerFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/NavDrawerFragment.java index 4f99e8130..e64a4e11f 100644 --- a/app/src/main/java/de/danoeh/antennapod/fragment/NavDrawerFragment.java +++ b/app/src/main/java/de/danoeh/antennapod/fragment/NavDrawerFragment.java @@ -37,6 +37,7 @@ import de.danoeh.antennapod.core.preferences.UserPreferences; import de.danoeh.antennapod.core.service.playback.PlaybackService; 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.core.util.FeedItemUtil; import de.danoeh.antennapod.core.util.IntentUtils; import de.danoeh.antennapod.dialog.SubscriptionsFilterDialog; @@ -50,7 +51,11 @@ 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.Map; +import java.util.Set; public class NavDrawerFragment extends Fragment implements AdapterView.OnItemClickListener, AdapterView.OnItemLongClickListener, SharedPreferences.OnSharedPreferenceChangeListener { @@ -70,12 +75,14 @@ public class NavDrawerFragment extends Fragment implements AdapterView.OnItemCli NavListAdapter.SUBSCRIPTION_LIST_TAG }; - private DBReader.NavDrawerData navDrawerData; + private NavDrawerData navDrawerData; + private List flatItemList; private int selectedNavListIndex = -1; private int position = -1; private NavListAdapter navAdapter; private Disposable disposable; private ProgressBar progressBar; + private Set openFolders = new HashSet<>(); @Override public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @@ -107,9 +114,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 feeds = navDrawerData.feeds; - for (int i = 0; i < feeds.size(); i++) { - if (feeds.get(i).getId() == feedId) { + List 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; } @@ -149,8 +157,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! } @@ -161,7 +172,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(), @@ -300,17 +318,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; } @@ -368,6 +386,7 @@ public class NavDrawerFragment extends Fragment implements AdapterView.OnItemCli .subscribe( result -> { navDrawerData = result; + flatItemList = makeFlatDrawerData(navDrawerData.items); // TODO: This is the main thread! updateSelection(); // Selected item might be a feed navAdapter.notifyDataSetChanged(); progressBar.setVisibility(View.GONE); @@ -377,6 +396,20 @@ public class NavDrawerFragment extends Fragment implements AdapterView.OnItemCli }); } + private List makeFlatDrawerData(List items) { + List flatItems = new ArrayList<>(); + for (NavDrawerData.DrawerItem item : items) { + flatItems.add(item); + if (item.type == NavDrawerData.DrawerItem.Type.FOLDER) { + NavDrawerData.FolderDrawerItem folder = ((NavDrawerData.FolderDrawerItem) item); + if (openFolders.contains(folder.name)) { + flatItems.addAll(makeFlatDrawerData(((NavDrawerData.FolderDrawerItem) item).children)); + } + } + } + return flatItems; + } + @Override public void onItemClick(AdapterView parent, View view, int position, long id) { int viewType = parent.getAdapter().getItemViewType(position); @@ -391,14 +424,27 @@ public class NavDrawerFragment extends Fragment implements AdapterView.OnItemCli } } 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); + 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 { - Intent intent = new Intent(getActivity(), MainActivity.class); - intent.putExtra(MainActivity.EXTRA_FEED_ID, feedId); - startActivity(intent); + NavDrawerData.FolderDrawerItem folder = ((NavDrawerData.FolderDrawerItem) clickedItem); + if (openFolders.contains(folder.name)) { + openFolders.remove(folder.name); + } else { + openFolders.add(folder.name); + } + flatItemList = makeFlatDrawerData(navDrawerData.items); + navAdapter.notifyDataSetChanged(); } } } else if (UserPreferences.getSubscriptionsFilter().isEnabled() 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 7d3312e8e..7aa8a062b 100644 --- a/app/src/main/java/de/danoeh/antennapod/fragment/SubscriptionFragment.java +++ b/app/src/main/java/de/danoeh/antennapod/fragment/SubscriptionFragment.java @@ -45,6 +45,7 @@ import de.danoeh.antennapod.core.service.playback.PlaybackService; 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.FeedItemUtil; import de.danoeh.antennapod.core.util.IntentUtils; import de.danoeh.antennapod.core.util.download.AutoUpdateManager; @@ -71,7 +72,7 @@ public class SubscriptionFragment extends Fragment implements Toolbar.OnMenuItem private static final String PREF_NUM_COLUMNS = "columns"; private GridView subscriptionGridLayout; - private DBReader.NavDrawerData navDrawerData; + private NavDrawerData navDrawerData; private SubscriptionsAdapter subscriptionAdapter; private FloatingActionButton subscriptionAddButton; private ProgressBar progressBar; @@ -370,16 +371,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; } -- cgit v1.2.3