From f8de72f59f42da7f57a13d5552e25e3675060a24 Mon Sep 17 00:00:00 2001 From: Stypox Date: Fri, 31 Jul 2020 11:28:22 +0200 Subject: [PATCH 1/2] Improve search suggestion experience when remote ones can't be fetched Do not show anything in case of network error (it can simply be ignored). Show a snackbar otherwise, which still allows writing things into the search box. --- .../fragments/list/search/SearchFragment.java | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/fragments/list/search/SearchFragment.java b/app/src/main/java/org/schabi/newpipe/fragments/list/search/SearchFragment.java index 6817e459559..cae4975a4fe 100644 --- a/app/src/main/java/org/schabi/newpipe/fragments/list/search/SearchFragment.java +++ b/app/src/main/java/org/schabi/newpipe/fragments/list/search/SearchFragment.java @@ -52,6 +52,7 @@ import org.schabi.newpipe.util.DeviceUtils; import org.schabi.newpipe.util.AnimationUtils; import org.schabi.newpipe.util.Constants; +import org.schabi.newpipe.util.ExceptionUtils; import org.schabi.newpipe.util.ExtractorHelper; import org.schabi.newpipe.util.NavigationHelper; import org.schabi.newpipe.util.ServiceHelper; @@ -154,6 +155,7 @@ public class SearchFragment extends BaseListFragment 0 && !isLoading.get()) { hideSuggestionsPanel(); @@ -742,6 +746,13 @@ private void initSuggestionObserver() { final Observable> network = ExtractorHelper .suggestionsFor(serviceId, query) + .onErrorReturn(throwable -> { + if (!ExceptionUtils.isNetworkRelated(throwable)) { + showSnackBarError(throwable, UserAction.GET_SUGGESTIONS, + NewPipe.getNameOfService(serviceId), searchString, 0); + } + return new ArrayList<>(); + }) .toObservable() .map(strings -> { final List result = new ArrayList<>(); @@ -924,7 +935,7 @@ public void handleSuggestions(@NonNull final List suggestions) { suggestionsRecyclerView.smoothScrollToPosition(0); suggestionsRecyclerView.post(() -> suggestionListAdapter.setItems(suggestions)); - if (errorPanelRoot.getVisibility() == View.VISIBLE) { + if (suggestionsPanelVisible && errorPanelRoot.getVisibility() == View.VISIBLE) { hideLoading(); } } From 0062ff9cfabce706506f8651b1a2b8059f5e3a43 Mon Sep 17 00:00:00 2001 From: Stypox Date: Fri, 31 Jul 2020 11:40:29 +0200 Subject: [PATCH 2/2] Fix deprecations, warnings and useless null checks in SearchFragment --- .../fragments/list/search/SearchFragment.java | 106 ++++++++---------- 1 file changed, 47 insertions(+), 59 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/fragments/list/search/SearchFragment.java b/app/src/main/java/org/schabi/newpipe/fragments/list/search/SearchFragment.java index cae4975a4fe..64eaf3a3d00 100644 --- a/app/src/main/java/org/schabi/newpipe/fragments/list/search/SearchFragment.java +++ b/app/src/main/java/org/schabi/newpipe/fragments/list/search/SearchFragment.java @@ -79,7 +79,7 @@ import static java.util.Arrays.asList; import static org.schabi.newpipe.util.AnimationUtils.animateView; -public class SearchFragment extends BaseListFragment +public class SearchFragment extends BaseListFragment> implements BackPressable { /*////////////////////////////////////////////////////////////////////////// // Search @@ -134,7 +134,6 @@ public class SearchFragment extends BaseListFragment menuItemToFilterName; private StreamingService service; private Page nextPage; - private String contentCountry; private boolean isSuggestionsEnabled = true; private Disposable searchDisposable; @@ -206,8 +205,6 @@ public void onCreate(final Bundle savedInstanceState) { = PreferenceManager.getDefaultSharedPreferences(activity); isSuggestionsEnabled = preferences .getBoolean(getString(R.string.show_search_suggestions_key), true); - contentCountry = preferences.getString(getString(R.string.content_country_key), - getString(R.string.default_localization_key)); } @Override @@ -235,9 +232,7 @@ public void onPause() { if (suggestionDisposable != null) { suggestionDisposable.dispose(); } - if (disposables != null) { - disposables.clear(); - } + disposables.clear(); hideKeyboardSearch(); } @@ -251,8 +246,8 @@ public void onResume() { try { service = NewPipe.getService(serviceId); } catch (final Exception e) { - ErrorActivity.reportError(getActivity(), e, getActivity().getClass(), - getActivity().findViewById(android.R.id.content), + ErrorActivity.reportError(getActivity(), e, requireActivity().getClass(), + requireActivity().findViewById(android.R.id.content), ErrorActivity.ErrorInfo.make(UserAction.UI_ERROR, "", "", R.string.general_error)); @@ -305,26 +300,20 @@ public void onDestroy() { if (suggestionDisposable != null) { suggestionDisposable.dispose(); } - if (disposables != null) { - disposables.clear(); - } + disposables.clear(); } @Override public void onActivityResult(final int requestCode, final int resultCode, final Intent data) { - switch (requestCode) { - case ReCaptchaActivity.RECAPTCHA_REQUEST: - if (resultCode == Activity.RESULT_OK - && !TextUtils.isEmpty(searchString)) { - search(searchString, contentFilter, sortFilter); - } else { - Log.e(TAG, "ReCaptcha failed"); - } - break; - - default: - Log.e(TAG, "Request code from activity not supported [" + requestCode + "]"); - break; + if (requestCode == ReCaptchaActivity.RECAPTCHA_REQUEST) { + if (resultCode == Activity.RESULT_OK + && !TextUtils.isEmpty(searchString)) { + search(searchString, contentFilter, sortFilter); + } else { + Log.e(TAG, "ReCaptcha failed"); + } + } else { + Log.e(TAG, "Request code from activity not supported [" + requestCode + "]"); } } @@ -342,7 +331,7 @@ protected void initViews(final View rootView, final Bundle savedInstanceState) { @Override public int getMovementFlags(@NonNull final RecyclerView recyclerView, @NonNull final RecyclerView.ViewHolder viewHolder) { - return getSuggestionMovementFlags(recyclerView, viewHolder); + return getSuggestionMovementFlags(viewHolder); } @Override @@ -354,7 +343,7 @@ public boolean onMove(@NonNull final RecyclerView recyclerView, @Override public void onSwiped(@NonNull final RecyclerView.ViewHolder viewHolder, final int i) { - onSuggestionItemSwiped(viewHolder, i); + onSuggestionItemSwiped(viewHolder); } }).attachToRecyclerView(suggestionsRecyclerView); @@ -673,8 +662,7 @@ private void hideKeyboardSearch() { } private void showDeleteSuggestionDialog(final SuggestionItem item) { - if (activity == null || historyRecordManager == null || suggestionPublisher == null - || searchEditText == null || disposables == null) { + if (activity == null || historyRecordManager == null || searchEditText == null) { return; } final String query = item.query; @@ -802,21 +790,23 @@ protected void doInitialLoadLogic() { // no-op } - private void search(final String ss, final String[] cf, final String sf) { + private void search(final String theSearchString, + final String[] theContentFilter, + final String theSortFilter) { if (DEBUG) { - Log.d(TAG, "search() called with: query = [" + ss + "]"); + Log.d(TAG, "search() called with: query = [" + theSearchString + "]"); } - if (ss.isEmpty()) { + if (theSearchString.isEmpty()) { return; } try { - final StreamingService streamingService = NewPipe.getServiceByUrl(ss); + final StreamingService streamingService = NewPipe.getServiceByUrl(theSearchString); if (streamingService != null) { showLoading(); disposables.add(Observable - .fromCallable(() -> - NavigationHelper.getIntentByLink(activity, streamingService, ss)) + .fromCallable(() -> NavigationHelper.getIntentByLink(activity, + streamingService, theSearchString)) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(intent -> { @@ -831,29 +821,27 @@ private void search(final String ss, final String[] cf, final String sf) { } lastSearchedString = this.searchString; - this.searchString = ss; + this.searchString = theSearchString; infoListAdapter.clearStreamItemList(); hideSuggestionsPanel(); hideKeyboardSearch(); - historyRecordManager.onSearched(serviceId, ss) + disposables.add(historyRecordManager.onSearched(serviceId, theSearchString) .observeOn(AndroidSchedulers.mainThread()) .subscribe( ignored -> { }, error -> showSnackBarError(error, UserAction.SEARCHED, - NewPipe.getNameOfService(serviceId), ss, 0) - ); - suggestionPublisher.onNext(ss); + NewPipe.getNameOfService(serviceId), theSearchString, 0) + )); + suggestionPublisher.onNext(theSearchString); startLoading(false); } @Override public void startLoading(final boolean forceLoad) { super.startLoading(forceLoad); - if (disposables != null) { - disposables.clear(); - } + disposables.clear(); if (searchDisposable != null) { searchDisposable.dispose(); } @@ -892,8 +880,7 @@ protected void loadMoreItems() { @Override protected boolean hasMoreItems() { - // TODO: No way to tell if search has more items in the moment - return true; + return Page.isValid(nextPage); } @Override @@ -906,22 +893,25 @@ protected void onItemSelected(final InfoItem selectedItem) { // Utils //////////////////////////////////////////////////////////////////////////*/ - private void changeContentFilter(final MenuItem item, final List cf) { - this.filterItemCheckedId = item.getItemId(); + private void changeContentFilter(final MenuItem item, final List theContentFilter) { + filterItemCheckedId = item.getItemId(); item.setChecked(true); - this.contentFilter = new String[]{cf.get(0)}; + contentFilter = new String[]{theContentFilter.get(0)}; if (!TextUtils.isEmpty(searchString)) { - search(searchString, this.contentFilter, sortFilter); + search(searchString, contentFilter, sortFilter); } } - private void setQuery(final int sid, final String ss, final String[] cf, final String sf) { - this.serviceId = sid; - this.searchString = searchString; - this.contentFilter = cf; - this.sortFilter = sf; + private void setQuery(final int theServiceId, + final String theSearchString, + final String[] theContentFilter, + final String theSortFilter) { + serviceId = theServiceId; + searchString = theSearchString; + contentFilter = theContentFilter; + sortFilter = theSortFilter; } /*////////////////////////////////////////////////////////////////////////// @@ -1038,7 +1028,7 @@ private void handleSearchSuggestion() { } @Override - public void handleNextItems(final ListExtractor.InfoItemsPage result) { + public void handleNextItems(final ListExtractor.InfoItemsPage result) { showListFooter(false); infoListAdapter.addInfoItemList(result.getItems()); nextPage = result.getNextPage(); @@ -1077,8 +1067,7 @@ protected boolean onError(final Throwable exception) { // Suggestion item touch helper //////////////////////////////////////////////////////////////////////////*/ - public int getSuggestionMovementFlags(@NonNull final RecyclerView recyclerView, - @NonNull final RecyclerView.ViewHolder viewHolder) { + public int getSuggestionMovementFlags(@NonNull final RecyclerView.ViewHolder viewHolder) { final int position = viewHolder.getAdapterPosition(); if (position == RecyclerView.NO_POSITION) { return 0; @@ -1089,8 +1078,7 @@ public int getSuggestionMovementFlags(@NonNull final RecyclerView recyclerView, ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT) : 0; } - public void onSuggestionItemSwiped(@NonNull final RecyclerView.ViewHolder viewHolder, - final int i) { + public void onSuggestionItemSwiped(@NonNull final RecyclerView.ViewHolder viewHolder) { final int position = viewHolder.getAdapterPosition(); final String query = suggestionListAdapter.getItem(position).query; final Disposable onDelete = historyRecordManager.deleteSearchHistory(query)