From ac13b7aa7b14e5e46971748ba2751c8bfa2bcf15 Mon Sep 17 00:00:00 2001 From: ByteHamster Date: Thu, 9 Apr 2020 12:33:31 +0200 Subject: Use a single search fragment for all searchers --- .../antennapod/discovery/CombinedSearcher.java | 21 +- .../antennapod/discovery/FyydPodcastSearcher.java | 5 + .../discovery/GpodnetPodcastSearcher.java | 5 + .../discovery/ItunesPodcastSearcher.java | 5 + .../antennapod/discovery/PodcastSearcher.java | 2 + .../discovery/PodcastSearcherRegistry.java | 13 +- .../antennapod/fragment/AddFeedFragment.java | 14 +- .../fragment/CombinedSearchFragment.java | 173 ---------------- .../antennapod/fragment/DiscoveryFragment.java | 143 ++++++++++++++ .../antennapod/fragment/FyydSearchFragment.java | 167 ---------------- .../antennapod/fragment/ItunesSearchFragment.java | 218 --------------------- .../antennapod/fragment/OnlineSearchFragment.java | 195 ++++++++++++++++++ .../fragment/QuickFeedDiscoveryFragment.java | 3 +- app/src/main/res/layout/fragment_itunes_search.xml | 1 - app/src/main/res/menu/itunes_search.xml | 13 -- app/src/main/res/menu/online_search.xml | 13 ++ 16 files changed, 400 insertions(+), 591 deletions(-) delete mode 100644 app/src/main/java/de/danoeh/antennapod/fragment/CombinedSearchFragment.java create mode 100644 app/src/main/java/de/danoeh/antennapod/fragment/DiscoveryFragment.java delete mode 100644 app/src/main/java/de/danoeh/antennapod/fragment/FyydSearchFragment.java delete mode 100644 app/src/main/java/de/danoeh/antennapod/fragment/ItunesSearchFragment.java create mode 100644 app/src/main/java/de/danoeh/antennapod/fragment/OnlineSearchFragment.java delete mode 100644 app/src/main/res/menu/itunes_search.xml create mode 100644 app/src/main/res/menu/online_search.xml (limited to 'app/src') diff --git a/app/src/main/java/de/danoeh/antennapod/discovery/CombinedSearcher.java b/app/src/main/java/de/danoeh/antennapod/discovery/CombinedSearcher.java index 287e20964..6c2a87c12 100644 --- a/app/src/main/java/de/danoeh/antennapod/discovery/CombinedSearcher.java +++ b/app/src/main/java/de/danoeh/antennapod/discovery/CombinedSearcher.java @@ -1,8 +1,7 @@ package de.danoeh.antennapod.discovery; -import android.content.Context; +import android.text.TextUtils; import android.util.Log; -import android.util.Pair; import io.reactivex.Single; import io.reactivex.SingleOnSubscribe; import io.reactivex.android.schedulers.AndroidSchedulers; @@ -19,7 +18,7 @@ import java.util.concurrent.CountDownLatch; public class CombinedSearcher implements PodcastSearcher { private static final String TAG = "CombinedSearcher"; - public CombinedSearcher(Context context) { + public CombinedSearcher() { } public Single> search(String query) { @@ -31,7 +30,7 @@ public class CombinedSearcher implements PodcastSearcher { PodcastSearcherRegistry.SearcherInfo searchProviderInfo = PodcastSearcherRegistry.getSearchProviders().get(i); PodcastSearcher searcher = searchProviderInfo.searcher; - if (searchProviderInfo.weight <= 0.00001f) { + if (searchProviderInfo.weight <= 0.00001f || searcher.getClass() == CombinedSearcher.class) { latch.countDown(); continue; } @@ -102,4 +101,18 @@ public class CombinedSearcher implements PodcastSearcher { public boolean urlNeedsLookup(String url) { return PodcastSearcherRegistry.urlNeedsLookup(url); } + + @Override + public String getName() { + ArrayList names = new ArrayList<>(); + for (int i = 0; i < PodcastSearcherRegistry.getSearchProviders().size(); i++) { + PodcastSearcherRegistry.SearcherInfo searchProviderInfo + = PodcastSearcherRegistry.getSearchProviders().get(i); + PodcastSearcher searcher = searchProviderInfo.searcher; + if (searchProviderInfo.weight > 0.00001f && searcher.getClass() != CombinedSearcher.class) { + names.add(searcher.getName()); + } + } + return TextUtils.join(", ", names); + } } diff --git a/app/src/main/java/de/danoeh/antennapod/discovery/FyydPodcastSearcher.java b/app/src/main/java/de/danoeh/antennapod/discovery/FyydPodcastSearcher.java index 856ca8569..5a93e6530 100644 --- a/app/src/main/java/de/danoeh/antennapod/discovery/FyydPodcastSearcher.java +++ b/app/src/main/java/de/danoeh/antennapod/discovery/FyydPodcastSearcher.java @@ -45,4 +45,9 @@ public class FyydPodcastSearcher implements PodcastSearcher { public boolean urlNeedsLookup(String url) { return false; } + + @Override + public String getName() { + return "Fyyd"; + } } diff --git a/app/src/main/java/de/danoeh/antennapod/discovery/GpodnetPodcastSearcher.java b/app/src/main/java/de/danoeh/antennapod/discovery/GpodnetPodcastSearcher.java index 46b3e5775..53237579f 100644 --- a/app/src/main/java/de/danoeh/antennapod/discovery/GpodnetPodcastSearcher.java +++ b/app/src/main/java/de/danoeh/antennapod/discovery/GpodnetPodcastSearcher.java @@ -43,4 +43,9 @@ public class GpodnetPodcastSearcher implements PodcastSearcher { public boolean urlNeedsLookup(String url) { return false; } + + @Override + public String getName() { + return "Gpodder.net"; + } } diff --git a/app/src/main/java/de/danoeh/antennapod/discovery/ItunesPodcastSearcher.java b/app/src/main/java/de/danoeh/antennapod/discovery/ItunesPodcastSearcher.java index ed1efaf73..796ec556f 100644 --- a/app/src/main/java/de/danoeh/antennapod/discovery/ItunesPodcastSearcher.java +++ b/app/src/main/java/de/danoeh/antennapod/discovery/ItunesPodcastSearcher.java @@ -96,4 +96,9 @@ public class ItunesPodcastSearcher implements PodcastSearcher { public boolean urlNeedsLookup(String url) { return url.contains("itunes.apple.com"); } + + @Override + public String getName() { + return "iTunes"; + } } diff --git a/app/src/main/java/de/danoeh/antennapod/discovery/PodcastSearcher.java b/app/src/main/java/de/danoeh/antennapod/discovery/PodcastSearcher.java index 3312e0d57..eeebd2ebf 100644 --- a/app/src/main/java/de/danoeh/antennapod/discovery/PodcastSearcher.java +++ b/app/src/main/java/de/danoeh/antennapod/discovery/PodcastSearcher.java @@ -11,4 +11,6 @@ public interface PodcastSearcher { Single lookupUrl(String resultUrl); boolean urlNeedsLookup(String resultUrl); + + String getName(); } diff --git a/app/src/main/java/de/danoeh/antennapod/discovery/PodcastSearcherRegistry.java b/app/src/main/java/de/danoeh/antennapod/discovery/PodcastSearcherRegistry.java index 32fa96d5d..3f738424b 100644 --- a/app/src/main/java/de/danoeh/antennapod/discovery/PodcastSearcherRegistry.java +++ b/app/src/main/java/de/danoeh/antennapod/discovery/PodcastSearcherRegistry.java @@ -15,8 +15,9 @@ public class PodcastSearcherRegistry { public static List getSearchProviders() { if (searchProviders == null) { searchProviders = new ArrayList<>(); - searchProviders.add(new SearcherInfo(new FyydPodcastSearcher(), 1.f)); + searchProviders.add(new SearcherInfo(new CombinedSearcher(), 1.f)); searchProviders.add(new SearcherInfo(new ItunesPodcastSearcher(), 1.f)); + searchProviders.add(new SearcherInfo(new FyydPodcastSearcher(), 1.f)); searchProviders.add(new SearcherInfo(new GpodnetPodcastSearcher(), 0.0f)); } return searchProviders; @@ -24,7 +25,8 @@ public class PodcastSearcherRegistry { public static Single lookupUrl(String url) { for (PodcastSearcherRegistry.SearcherInfo searchProviderInfo : getSearchProviders()) { - if (searchProviderInfo.searcher.urlNeedsLookup(url)) { + if (searchProviderInfo.searcher.getClass() != CombinedSearcher.class + && searchProviderInfo.searcher.urlNeedsLookup(url)) { return searchProviderInfo.searcher.lookupUrl(url); } } @@ -33,7 +35,8 @@ public class PodcastSearcherRegistry { public static boolean urlNeedsLookup(String url) { for (PodcastSearcherRegistry.SearcherInfo searchProviderInfo : getSearchProviders()) { - if (searchProviderInfo.searcher.urlNeedsLookup(url)) { + if (searchProviderInfo.searcher.getClass() != CombinedSearcher.class + && searchProviderInfo.searcher.urlNeedsLookup(url)) { return true; } } @@ -41,8 +44,8 @@ public class PodcastSearcherRegistry { } public static class SearcherInfo { - final PodcastSearcher searcher; - final float weight; + public final PodcastSearcher searcher; + public final float weight; public SearcherInfo(PodcastSearcher searcher, float weight) { this.searcher = searcher; diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/AddFeedFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/AddFeedFragment.java index 49b2ae7ac..046a39355 100644 --- a/app/src/main/java/de/danoeh/antennapod/fragment/AddFeedFragment.java +++ b/app/src/main/java/de/danoeh/antennapod/fragment/AddFeedFragment.java @@ -19,6 +19,9 @@ import de.danoeh.antennapod.R; import de.danoeh.antennapod.activity.MainActivity; import de.danoeh.antennapod.activity.OnlineFeedViewActivity; import de.danoeh.antennapod.activity.OpmlImportActivity; +import de.danoeh.antennapod.discovery.CombinedSearcher; +import de.danoeh.antennapod.discovery.FyydPodcastSearcher; +import de.danoeh.antennapod.discovery.ItunesPodcastSearcher; import de.danoeh.antennapod.fragment.gpodnet.GpodnetMainFragment; /** @@ -40,9 +43,9 @@ public class AddFeedFragment extends Fragment { ((AppCompatActivity) getActivity()).setSupportActionBar(root.findViewById(R.id.toolbar)); root.findViewById(R.id.btn_search_itunes).setOnClickListener(v - -> activity.loadChildFragment(new ItunesSearchFragment())); + -> activity.loadChildFragment(OnlineSearchFragment.newInstance(ItunesPodcastSearcher.class))); root.findViewById(R.id.btn_search_fyyd).setOnClickListener(v - -> activity.loadChildFragment(new FyydSearchFragment())); + -> activity.loadChildFragment(OnlineSearchFragment.newInstance(FyydPodcastSearcher.class))); root.findViewById(R.id.btn_search_gpodder).setOnClickListener(v -> activity.loadChildFragment(new GpodnetMainFragment())); @@ -99,12 +102,7 @@ public class AddFeedFragment extends Fragment { addUrl(query); return; } - - Bundle bundle = new Bundle(); - bundle.putString(CombinedSearchFragment.ARGUMENT_QUERY, query); - CombinedSearchFragment fragment = new CombinedSearchFragment(); - fragment.setArguments(bundle); - activity.loadChildFragment(fragment); + activity.loadChildFragment(OnlineSearchFragment.newInstance(CombinedSearcher.class, query)); } @Override diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/CombinedSearchFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/CombinedSearchFragment.java deleted file mode 100644 index b71a7e0cc..000000000 --- a/app/src/main/java/de/danoeh/antennapod/fragment/CombinedSearchFragment.java +++ /dev/null @@ -1,173 +0,0 @@ -package de.danoeh.antennapod.fragment; - -import android.content.Intent; -import android.os.Bundle; -import androidx.appcompat.app.AppCompatActivity; -import androidx.fragment.app.Fragment; -import androidx.core.view.MenuItemCompat; -import androidx.appcompat.widget.SearchView; -import android.util.Log; -import android.view.LayoutInflater; -import android.view.Menu; -import android.view.MenuInflater; -import android.view.MenuItem; -import android.view.View; -import android.view.ViewGroup; -import android.widget.Button; -import android.widget.GridView; -import android.widget.ProgressBar; -import android.widget.TextView; -import de.danoeh.antennapod.R; -import de.danoeh.antennapod.activity.OnlineFeedViewActivity; -import de.danoeh.antennapod.adapter.itunes.ItunesAdapter; -import de.danoeh.antennapod.discovery.CombinedSearcher; -import de.danoeh.antennapod.discovery.PodcastSearchResult; -import de.danoeh.antennapod.menuhandler.MenuItemUtils; -import io.reactivex.disposables.Disposable; - -import java.util.ArrayList; -import java.util.List; - -public class CombinedSearchFragment extends Fragment { - - private static final String TAG = "CombinedSearchFragment"; - public static final String ARGUMENT_QUERY = "query"; - - /** - * Adapter responsible with the search results - */ - private ItunesAdapter adapter; - private GridView gridView; - private ProgressBar progressBar; - private TextView txtvError; - private Button butRetry; - private TextView txtvEmpty; - - /** - * List of podcasts retreived from the search - */ - private List searchResults = new ArrayList<>(); - private Disposable disposable; - - /** - * Constructor - */ - public CombinedSearchFragment() { - // Required empty public constructor - } - - @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - setHasOptionsMenu(true); - } - - @Override - public View onCreateView(LayoutInflater inflater, ViewGroup container, - Bundle savedInstanceState) { - // Inflate the layout for this fragment - View root = inflater.inflate(R.layout.fragment_itunes_search, container, false); - ((AppCompatActivity) getActivity()).setSupportActionBar(root.findViewById(R.id.toolbar)); - gridView = root.findViewById(R.id.gridView); - adapter = new ItunesAdapter(getActivity(), new ArrayList<>()); - gridView.setAdapter(adapter); - - //Show information about the podcast when the list item is clicked - gridView.setOnItemClickListener((parent, view1, position, id) -> { - PodcastSearchResult podcast = searchResults.get(position); - Intent intent = new Intent(getActivity(), OnlineFeedViewActivity.class); - intent.putExtra(OnlineFeedViewActivity.ARG_FEEDURL, podcast.feedUrl); - startActivity(intent); - }); - progressBar = root.findViewById(R.id.progressBar); - txtvError = root.findViewById(R.id.txtvError); - butRetry = root.findViewById(R.id.butRetry); - txtvEmpty = root.findViewById(android.R.id.empty); - - return root; - } - - @Override - public void onDestroy() { - super.onDestroy(); - if (disposable != null) { - disposable.dispose(); - } - adapter = null; - } - - @Override - public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { - super.onCreateOptionsMenu(menu, inflater); - inflater.inflate(R.menu.itunes_search, menu); - MenuItem searchItem = menu.findItem(R.id.action_search); - final SearchView sv = (SearchView) MenuItemCompat.getActionView(searchItem); - sv.setQueryHint(getString(R.string.search_label)); - sv.setOnQueryTextListener(new SearchView.OnQueryTextListener() { - @Override - public boolean onQueryTextSubmit(String s) { - sv.clearFocus(); - search(s); - return true; - } - - @Override - public boolean onQueryTextChange(String s) { - return false; - } - }); - MenuItemCompat.setOnActionExpandListener(searchItem, new MenuItemCompat.OnActionExpandListener() { - @Override - public boolean onMenuItemActionExpand(MenuItem item) { - return true; - } - - @Override - public boolean onMenuItemActionCollapse(MenuItem item) { - getActivity().getSupportFragmentManager().popBackStack(); - return true; - } - }); - MenuItemCompat.expandActionView(searchItem); - - if (getArguments() != null && getArguments().getString(ARGUMENT_QUERY, null) != null) { - sv.setQuery(getArguments().getString(ARGUMENT_QUERY, null), true); - } - } - - private void search(String query) { - if (disposable != null) { - disposable.dispose(); - } - - showOnlyProgressBar(); - - CombinedSearcher searcher = new CombinedSearcher(getContext()); - disposable = searcher.search(query).subscribe(result -> { - searchResults = result; - progressBar.setVisibility(View.GONE); - - adapter.clear(); - adapter.addAll(searchResults); - adapter.notifyDataSetInvalidated(); - gridView.setVisibility(!searchResults.isEmpty() ? View.VISIBLE : View.GONE); - txtvEmpty.setVisibility(searchResults.isEmpty() ? View.VISIBLE : View.GONE); - - }, error -> { - Log.e(TAG, Log.getStackTraceString(error)); - progressBar.setVisibility(View.GONE); - txtvError.setText(error.toString()); - txtvError.setVisibility(View.VISIBLE); - butRetry.setOnClickListener(v -> search(query)); - butRetry.setVisibility(View.VISIBLE); - }); - } - - private void showOnlyProgressBar() { - gridView.setVisibility(View.GONE); - txtvError.setVisibility(View.GONE); - butRetry.setVisibility(View.GONE); - txtvEmpty.setVisibility(View.GONE); - progressBar.setVisibility(View.VISIBLE); - } -} diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/DiscoveryFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/DiscoveryFragment.java new file mode 100644 index 000000000..89d3c7af9 --- /dev/null +++ b/app/src/main/java/de/danoeh/antennapod/fragment/DiscoveryFragment.java @@ -0,0 +1,143 @@ +package de.danoeh.antennapod.fragment; + +import android.content.Intent; +import android.os.Bundle; +import android.util.Log; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.Button; +import android.widget.GridView; +import android.widget.ProgressBar; +import android.widget.TextView; +import androidx.annotation.NonNull; +import androidx.appcompat.app.AppCompatActivity; +import androidx.fragment.app.Fragment; +import de.danoeh.antennapod.R; +import de.danoeh.antennapod.activity.OnlineFeedViewActivity; +import de.danoeh.antennapod.adapter.itunes.ItunesAdapter; +import de.danoeh.antennapod.discovery.ItunesTopListLoader; +import de.danoeh.antennapod.discovery.PodcastSearchResult; +import io.reactivex.disposables.Disposable; + +import java.util.ArrayList; +import java.util.List; + +/** + * Searches iTunes store for top podcasts and displays results in a list. + */ +public class DiscoveryFragment extends Fragment { + + private static final String TAG = "ItunesSearchFragment"; + + /** + * Adapter responsible with the search results. + */ + private ItunesAdapter adapter; + private GridView gridView; + private ProgressBar progressBar; + private TextView txtvError; + private Button butRetry; + private TextView txtvEmpty; + + /** + * List of podcasts retreived from the search. + */ + private List searchResults; + private List topList; + private Disposable disposable; + + /** + * Replace adapter data with provided search results from SearchTask. + * @param result List of Podcast objects containing search results + */ + private void updateData(List result) { + this.searchResults = result; + adapter.clear(); + if (result != null && result.size() > 0) { + gridView.setVisibility(View.VISIBLE); + txtvEmpty.setVisibility(View.GONE); + for (PodcastSearchResult p : result) { + adapter.add(p); + } + adapter.notifyDataSetInvalidated(); + } else { + gridView.setVisibility(View.GONE); + txtvEmpty.setVisibility(View.VISIBLE); + } + } + + public DiscoveryFragment() { + // Required empty public constructor + } + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setHasOptionsMenu(true); + } + + @Override + public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + // Inflate the layout for this fragment + View root = inflater.inflate(R.layout.fragment_itunes_search, container, false); + ((AppCompatActivity) getActivity()).setSupportActionBar(root.findViewById(R.id.toolbar)); + gridView = root.findViewById(R.id.gridView); + adapter = new ItunesAdapter(getActivity(), new ArrayList<>()); + gridView.setAdapter(adapter); + + //Show information about the podcast when the list item is clicked + gridView.setOnItemClickListener((parent, view1, position, id) -> { + PodcastSearchResult podcast = searchResults.get(position); + if (podcast.feedUrl == null) { + return; + } + Intent intent = new Intent(getActivity(), OnlineFeedViewActivity.class); + intent.putExtra(OnlineFeedViewActivity.ARG_FEEDURL, podcast.feedUrl); + startActivity(intent); + }); + progressBar = root.findViewById(R.id.progressBar); + txtvError = root.findViewById(R.id.txtvError); + butRetry = root.findViewById(R.id.butRetry); + txtvEmpty = root.findViewById(android.R.id.empty); + + loadToplist(); + + return root; + } + + @Override + public void onDestroy() { + super.onDestroy(); + if (disposable != null) { + disposable.dispose(); + } + adapter = null; + } + + private void loadToplist() { + if (disposable != null) { + disposable.dispose(); + } + gridView.setVisibility(View.GONE); + txtvError.setVisibility(View.GONE); + butRetry.setVisibility(View.GONE); + txtvEmpty.setVisibility(View.GONE); + progressBar.setVisibility(View.VISIBLE); + + ItunesTopListLoader loader = new ItunesTopListLoader(getContext()); + disposable = loader.loadToplist(25).subscribe(podcasts -> { + progressBar.setVisibility(View.GONE); + topList = podcasts; + updateData(topList); + }, error -> { + Log.e(TAG, Log.getStackTraceString(error)); + progressBar.setVisibility(View.GONE); + txtvError.setText(error.toString()); + txtvError.setVisibility(View.VISIBLE); + butRetry.setOnClickListener(v -> loadToplist()); + butRetry.setVisibility(View.VISIBLE); + }); + } +} diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/FyydSearchFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/FyydSearchFragment.java deleted file mode 100644 index 6bd191af4..000000000 --- a/app/src/main/java/de/danoeh/antennapod/fragment/FyydSearchFragment.java +++ /dev/null @@ -1,167 +0,0 @@ -package de.danoeh.antennapod.fragment; - -import android.content.Intent; -import android.os.Bundle; -import androidx.appcompat.app.AppCompatActivity; -import androidx.fragment.app.Fragment; -import androidx.core.view.MenuItemCompat; -import androidx.appcompat.widget.SearchView; -import android.util.Log; -import android.view.LayoutInflater; -import android.view.Menu; -import android.view.MenuInflater; -import android.view.MenuItem; -import android.view.View; -import android.view.ViewGroup; -import android.widget.Button; -import android.widget.GridView; -import android.widget.ProgressBar; -import android.widget.TextView; -import de.danoeh.antennapod.R; -import de.danoeh.antennapod.activity.OnlineFeedViewActivity; -import de.danoeh.antennapod.adapter.itunes.ItunesAdapter; -import de.danoeh.antennapod.discovery.FyydPodcastSearcher; -import de.danoeh.antennapod.discovery.PodcastSearchResult; -import de.danoeh.antennapod.menuhandler.MenuItemUtils; -import io.reactivex.disposables.Disposable; - -import java.util.ArrayList; -import java.util.List; - -public class FyydSearchFragment extends Fragment { - - private static final String TAG = "FyydSearchFragment"; - - /** - * Adapter responsible with the search results - */ - private ItunesAdapter adapter; - private GridView gridView; - private ProgressBar progressBar; - private TextView txtvError; - private Button butRetry; - private TextView txtvEmpty; - - /** - * List of podcasts retreived from the search - */ - private List searchResults; - private Disposable disposable; - - /** - * Constructor - */ - public FyydSearchFragment() { - // Required empty public constructor - } - - @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - setHasOptionsMenu(true); - } - - @Override - public View onCreateView(LayoutInflater inflater, ViewGroup container, - Bundle savedInstanceState) { - // Inflate the layout for this fragment - View root = inflater.inflate(R.layout.fragment_itunes_search, container, false); - ((AppCompatActivity) getActivity()).setSupportActionBar(root.findViewById(R.id.toolbar)); - gridView = root.findViewById(R.id.gridView); - adapter = new ItunesAdapter(getActivity(), new ArrayList<>()); - gridView.setAdapter(adapter); - - //Show information about the podcast when the list item is clicked - gridView.setOnItemClickListener((parent, view1, position, id) -> { - PodcastSearchResult podcast = searchResults.get(position); - Intent intent = new Intent(getActivity(), OnlineFeedViewActivity.class); - intent.putExtra(OnlineFeedViewActivity.ARG_FEEDURL, podcast.feedUrl); - startActivity(intent); - }); - progressBar = root.findViewById(R.id.progressBar); - txtvError = root.findViewById(R.id.txtvError); - butRetry = root.findViewById(R.id.butRetry); - txtvEmpty = root.findViewById(android.R.id.empty); - - return root; - } - - @Override - public void onDestroy() { - super.onDestroy(); - if (disposable != null) { - disposable.dispose(); - } - adapter = null; - } - - @Override - public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { - super.onCreateOptionsMenu(menu, inflater); - inflater.inflate(R.menu.itunes_search, menu); - MenuItem searchItem = menu.findItem(R.id.action_search); - final SearchView sv = (SearchView) MenuItemCompat.getActionView(searchItem); - sv.setQueryHint(getString(R.string.search_fyyd_label)); - sv.setOnQueryTextListener(new SearchView.OnQueryTextListener() { - @Override - public boolean onQueryTextSubmit(String s) { - sv.clearFocus(); - search(s); - return true; - } - - @Override - public boolean onQueryTextChange(String s) { - return false; - } - }); - MenuItemCompat.setOnActionExpandListener(searchItem, new MenuItemCompat.OnActionExpandListener() { - @Override - public boolean onMenuItemActionExpand(MenuItem item) { - return true; - } - - @Override - public boolean onMenuItemActionCollapse(MenuItem item) { - getActivity().getSupportFragmentManager().popBackStack(); - return true; - } - }); - MenuItemCompat.expandActionView(searchItem); - } - - private void search(String query) { - if (disposable != null) { - disposable.dispose(); - } - showOnlyProgressBar(); - - FyydPodcastSearcher searcher = new FyydPodcastSearcher(); - disposable = searcher.search(query).subscribe(result -> { - searchResults = result; - progressBar.setVisibility(View.GONE); - - adapter.clear(); - adapter.addAll(searchResults); - adapter.notifyDataSetInvalidated(); - gridView.setVisibility(!searchResults.isEmpty() ? View.VISIBLE : View.GONE); - txtvEmpty.setVisibility(searchResults.isEmpty() ? View.VISIBLE : View.GONE); - - }, error -> { - Log.e(TAG, Log.getStackTraceString(error)); - progressBar.setVisibility(View.GONE); - txtvError.setText(error.toString()); - txtvError.setVisibility(View.VISIBLE); - butRetry.setOnClickListener(v -> search(query)); - butRetry.setVisibility(View.VISIBLE); - }); - } - - private void showOnlyProgressBar() { - gridView.setVisibility(View.GONE); - txtvError.setVisibility(View.GONE); - butRetry.setVisibility(View.GONE); - txtvEmpty.setVisibility(View.GONE); - progressBar.setVisibility(View.VISIBLE); - } -} diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/ItunesSearchFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/ItunesSearchFragment.java deleted file mode 100644 index 78096b39a..000000000 --- a/app/src/main/java/de/danoeh/antennapod/fragment/ItunesSearchFragment.java +++ /dev/null @@ -1,218 +0,0 @@ -package de.danoeh.antennapod.fragment; - -import android.content.Intent; -import android.os.Bundle; -import androidx.appcompat.app.AlertDialog; -import androidx.appcompat.app.AppCompatActivity; -import androidx.fragment.app.Fragment; -import androidx.core.view.MenuItemCompat; -import androidx.appcompat.widget.SearchView; -import androidx.annotation.NonNull; -import android.util.Log; -import android.view.LayoutInflater; -import android.view.Menu; -import android.view.MenuInflater; -import android.view.MenuItem; -import android.view.View; -import android.view.ViewGroup; -import android.widget.Button; -import android.widget.GridView; -import android.widget.ProgressBar; -import android.widget.TextView; - -import de.danoeh.antennapod.discovery.ItunesPodcastSearcher; -import de.danoeh.antennapod.discovery.ItunesTopListLoader; -import de.danoeh.antennapod.discovery.PodcastSearchResult; - -import java.util.ArrayList; -import java.util.List; - -import de.danoeh.antennapod.R; -import de.danoeh.antennapod.activity.OnlineFeedViewActivity; -import de.danoeh.antennapod.adapter.itunes.ItunesAdapter; -import de.danoeh.antennapod.menuhandler.MenuItemUtils; -import io.reactivex.disposables.Disposable; - -//Searches iTunes store for given string and displays results in a list -public class ItunesSearchFragment extends Fragment { - - private static final String TAG = "ItunesSearchFragment"; - - - /** - * Adapter responsible with the search results - */ - private ItunesAdapter adapter; - private GridView gridView; - private ProgressBar progressBar; - private TextView txtvError; - private Button butRetry; - private TextView txtvEmpty; - - /** - * List of podcasts retreived from the search - */ - private List searchResults; - private List topList; - private Disposable disposable; - - /** - * Replace adapter data with provided search results from SearchTask. - * @param result List of Podcast objects containing search results - */ - private void updateData(List result) { - this.searchResults = result; - adapter.clear(); - if (result != null && result.size() > 0) { - gridView.setVisibility(View.VISIBLE); - txtvEmpty.setVisibility(View.GONE); - for (PodcastSearchResult p : result) { - adapter.add(p); - } - adapter.notifyDataSetInvalidated(); - } else { - gridView.setVisibility(View.GONE); - txtvEmpty.setVisibility(View.VISIBLE); - } - } - - /** - * Constructor - */ - public ItunesSearchFragment() { - // Required empty public constructor - } - - @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - setHasOptionsMenu(true); - } - - @Override - public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, - Bundle savedInstanceState) { - // Inflate the layout for this fragment - View root = inflater.inflate(R.layout.fragment_itunes_search, container, false); - ((AppCompatActivity) getActivity()).setSupportActionBar(root.findViewById(R.id.toolbar)); - gridView = root.findViewById(R.id.gridView); - adapter = new ItunesAdapter(getActivity(), new ArrayList<>()); - gridView.setAdapter(adapter); - - //Show information about the podcast when the list item is clicked - gridView.setOnItemClickListener((parent, view1, position, id) -> { - PodcastSearchResult podcast = searchResults.get(position); - if (podcast.feedUrl == null) { - return; - } - Intent intent = new Intent(getActivity(), OnlineFeedViewActivity.class); - intent.putExtra(OnlineFeedViewActivity.ARG_FEEDURL, podcast.feedUrl); - startActivity(intent); - }); - progressBar = root.findViewById(R.id.progressBar); - txtvError = root.findViewById(R.id.txtvError); - butRetry = root.findViewById(R.id.butRetry); - txtvEmpty = root.findViewById(android.R.id.empty); - - loadToplist(); - - return root; - } - - @Override - public void onDestroy() { - super.onDestroy(); - if (disposable != null) { - disposable.dispose(); - } - adapter = null; - } - - @Override - public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { - super.onCreateOptionsMenu(menu, inflater); - inflater.inflate(R.menu.itunes_search, menu); - MenuItem searchItem = menu.findItem(R.id.action_search); - final SearchView sv = (SearchView) MenuItemCompat.getActionView(searchItem); - sv.setQueryHint(getString(R.string.search_itunes_label)); - sv.setOnQueryTextListener(new androidx.appcompat.widget.SearchView.OnQueryTextListener() { - @Override - public boolean onQueryTextSubmit(String s) { - sv.clearFocus(); - search(s); - return true; - } - - @Override - public boolean onQueryTextChange(String s) { - return false; - } - }); - MenuItemCompat.setOnActionExpandListener(searchItem, new MenuItemCompat.OnActionExpandListener() { - @Override - public boolean onMenuItemActionExpand(MenuItem item) { - return true; - } - - @Override - public boolean onMenuItemActionCollapse(MenuItem item) { - if (searchResults != null) { - searchResults = null; - updateData(topList); - } - return true; - } - }); - } - - private void loadToplist() { - if (disposable != null) { - disposable.dispose(); - } - gridView.setVisibility(View.GONE); - txtvError.setVisibility(View.GONE); - butRetry.setVisibility(View.GONE); - txtvEmpty.setVisibility(View.GONE); - progressBar.setVisibility(View.VISIBLE); - - ItunesTopListLoader loader = new ItunesTopListLoader(getContext()); - disposable = loader.loadToplist(25) - .subscribe(podcasts -> { - progressBar.setVisibility(View.GONE); - topList = podcasts; - updateData(topList); - }, error -> { - Log.e(TAG, Log.getStackTraceString(error)); - progressBar.setVisibility(View.GONE); - txtvError.setText(error.toString()); - txtvError.setVisibility(View.VISIBLE); - butRetry.setOnClickListener(v -> loadToplist()); - butRetry.setVisibility(View.VISIBLE); - }); - } - - private void search(String query) { - if (disposable != null) { - disposable.dispose(); - } - gridView.setVisibility(View.GONE); - txtvError.setVisibility(View.GONE); - butRetry.setVisibility(View.GONE); - txtvEmpty.setVisibility(View.GONE); - progressBar.setVisibility(View.VISIBLE); - - ItunesPodcastSearcher searcher = new ItunesPodcastSearcher(); - disposable = searcher.search(query).subscribe(podcasts -> { - progressBar.setVisibility(View.GONE); - updateData(podcasts); - }, error -> { - Log.e(TAG, Log.getStackTraceString(error)); - progressBar.setVisibility(View.GONE); - txtvError.setText(error.toString()); - txtvError.setVisibility(View.VISIBLE); - butRetry.setOnClickListener(v -> search(query)); - butRetry.setVisibility(View.VISIBLE); - }); - } - -} diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/OnlineSearchFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/OnlineSearchFragment.java new file mode 100644 index 000000000..d9c31f993 --- /dev/null +++ b/app/src/main/java/de/danoeh/antennapod/fragment/OnlineSearchFragment.java @@ -0,0 +1,195 @@ +package de.danoeh.antennapod.fragment; + +import android.content.Intent; +import android.os.Bundle; +import androidx.appcompat.app.AppCompatActivity; +import androidx.fragment.app.Fragment; +import androidx.core.view.MenuItemCompat; +import androidx.appcompat.widget.SearchView; +import android.util.Log; +import android.view.LayoutInflater; +import android.view.Menu; +import android.view.MenuInflater; +import android.view.MenuItem; +import android.view.View; +import android.view.ViewGroup; +import android.widget.Button; +import android.widget.GridView; +import android.widget.ProgressBar; +import android.widget.TextView; +import de.danoeh.antennapod.R; +import de.danoeh.antennapod.activity.OnlineFeedViewActivity; +import de.danoeh.antennapod.adapter.itunes.ItunesAdapter; +import de.danoeh.antennapod.discovery.PodcastSearchResult; +import de.danoeh.antennapod.discovery.PodcastSearcher; +import de.danoeh.antennapod.discovery.PodcastSearcherRegistry; +import io.reactivex.disposables.Disposable; + +import java.util.ArrayList; +import java.util.List; + +public class OnlineSearchFragment extends Fragment { + + private static final String TAG = "FyydSearchFragment"; + private static final String ARG_SEARCHER = "searcher"; + private static final String ARG_QUERY = "query"; + + /** + * Adapter responsible with the search results + */ + private ItunesAdapter adapter; + private PodcastSearcher searchProvider; + private GridView gridView; + private ProgressBar progressBar; + private TextView txtvError; + private Button butRetry; + private TextView txtvEmpty; + + /** + * List of podcasts retreived from the search + */ + private List searchResults; + private Disposable disposable; + + public static OnlineSearchFragment newInstance(Class searchProvider) { + return newInstance(searchProvider, null); + } + + public static OnlineSearchFragment newInstance(Class searchProvider, String query) { + OnlineSearchFragment fragment = new OnlineSearchFragment(); + Bundle arguments = new Bundle(); + arguments.putString(ARG_SEARCHER, searchProvider.getName()); + arguments.putString(ARG_QUERY, query); + fragment.setArguments(arguments); + return fragment; + } + + /** + * Constructor + */ + public OnlineSearchFragment() { + // Required empty public constructor + } + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setHasOptionsMenu(true); + + for (PodcastSearcherRegistry.SearcherInfo info : PodcastSearcherRegistry.getSearchProviders()) { + if (info.searcher.getClass().getName().equals(getArguments().getString(ARG_SEARCHER))) { + searchProvider = info.searcher; + break; + } + } + if (searchProvider == null) { + throw new IllegalArgumentException("Podcast searcher not found"); + } + } + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { + // Inflate the layout for this fragment + View root = inflater.inflate(R.layout.fragment_itunes_search, container, false); + ((AppCompatActivity) getActivity()).setSupportActionBar(root.findViewById(R.id.toolbar)); + gridView = root.findViewById(R.id.gridView); + adapter = new ItunesAdapter(getActivity(), new ArrayList<>()); + gridView.setAdapter(adapter); + + //Show information about the podcast when the list item is clicked + gridView.setOnItemClickListener((parent, view1, position, id) -> { + PodcastSearchResult podcast = searchResults.get(position); + Intent intent = new Intent(getActivity(), OnlineFeedViewActivity.class); + intent.putExtra(OnlineFeedViewActivity.ARG_FEEDURL, podcast.feedUrl); + startActivity(intent); + }); + progressBar = root.findViewById(R.id.progressBar); + txtvError = root.findViewById(R.id.txtvError); + butRetry = root.findViewById(R.id.butRetry); + txtvEmpty = root.findViewById(android.R.id.empty); + + txtvEmpty.setText(getString(R.string.search_powered_by, searchProvider.getName())); + return root; + } + + @Override + public void onDestroy() { + super.onDestroy(); + if (disposable != null) { + disposable.dispose(); + } + adapter = null; + } + + @Override + public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { + super.onCreateOptionsMenu(menu, inflater); + inflater.inflate(R.menu.online_search, menu); + MenuItem searchItem = menu.findItem(R.id.action_search); + final SearchView sv = (SearchView) MenuItemCompat.getActionView(searchItem); + sv.setQueryHint(getString(R.string.search_podcast_hint)); + sv.setOnQueryTextListener(new SearchView.OnQueryTextListener() { + @Override + public boolean onQueryTextSubmit(String s) { + sv.clearFocus(); + search(s); + return true; + } + + @Override + public boolean onQueryTextChange(String s) { + return false; + } + }); + searchItem.setOnActionExpandListener(new MenuItem.OnActionExpandListener() { + @Override + public boolean onMenuItemActionExpand(MenuItem item) { + return true; + } + + @Override + public boolean onMenuItemActionCollapse(MenuItem item) { + getActivity().getSupportFragmentManager().popBackStack(); + return true; + } + }); + searchItem.expandActionView(); + + if (getArguments().getString(ARG_QUERY, null) != null) { + sv.setQuery(getArguments().getString(ARG_QUERY, null), true); + } + + } + + private void search(String query) { + if (disposable != null) { + disposable.dispose(); + } + showOnlyProgressBar(); + disposable = searchProvider.search(query).subscribe(result -> { + searchResults = result; + progressBar.setVisibility(View.GONE); + adapter.clear(); + adapter.addAll(searchResults); + adapter.notifyDataSetInvalidated(); + gridView.setVisibility(!searchResults.isEmpty() ? View.VISIBLE : View.GONE); + txtvEmpty.setVisibility(searchResults.isEmpty() ? View.VISIBLE : View.GONE); + txtvEmpty.setText(getString(R.string.no_results_for_query, query)); + }, error -> { + Log.e(TAG, Log.getStackTraceString(error)); + progressBar.setVisibility(View.GONE); + txtvError.setText(error.toString()); + txtvError.setVisibility(View.VISIBLE); + butRetry.setOnClickListener(v -> search(query)); + butRetry.setVisibility(View.VISIBLE); + }); + } + + private void showOnlyProgressBar() { + gridView.setVisibility(View.GONE); + txtvError.setVisibility(View.GONE); + butRetry.setVisibility(View.GONE); + txtvEmpty.setVisibility(View.GONE); + progressBar.setVisibility(View.VISIBLE); + } +} diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/QuickFeedDiscoveryFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/QuickFeedDiscoveryFragment.java index c3f2dae3b..d6bcdd79c 100644 --- a/app/src/main/java/de/danoeh/antennapod/fragment/QuickFeedDiscoveryFragment.java +++ b/app/src/main/java/de/danoeh/antennapod/fragment/QuickFeedDiscoveryFragment.java @@ -3,7 +3,6 @@ package de.danoeh.antennapod.fragment; import android.content.Intent; import android.os.Bundle; import android.util.DisplayMetrics; -import androidx.appcompat.app.AlertDialog; import androidx.fragment.app.Fragment; import android.util.Log; import android.view.LayoutInflater; @@ -41,7 +40,7 @@ public class QuickFeedDiscoveryFragment extends Fragment implements AdapterView. View root = inflater.inflate(R.layout.quick_feed_discovery, container, false); View discoverMore = root.findViewById(R.id.discover_more); discoverMore.setOnClickListener(v -> - ((MainActivity) getActivity()).loadChildFragment(new ItunesSearchFragment())); + ((MainActivity) getActivity()).loadChildFragment(new DiscoveryFragment())); discoverGridLayout = root.findViewById(R.id.discover_grid); progressBar = root.findViewById(R.id.discover_progress_bar); diff --git a/app/src/main/res/layout/fragment_itunes_search.xml b/app/src/main/res/layout/fragment_itunes_search.xml index 0de57f62b..228bfb803 100644 --- a/app/src/main/res/layout/fragment_itunes_search.xml +++ b/app/src/main/res/layout/fragment_itunes_search.xml @@ -36,7 +36,6 @@ android:layout_height="match_parent" android:layout_centerInParent="true" android:gravity="center" - android:visibility="gone" android:text="@string/search_status_no_results" /> - - - - - - diff --git a/app/src/main/res/menu/online_search.xml b/app/src/main/res/menu/online_search.xml new file mode 100644 index 000000000..93d93157a --- /dev/null +++ b/app/src/main/res/menu/online_search.xml @@ -0,0 +1,13 @@ + + + + + + + -- cgit v1.2.3