add getMoreInfo to SearchInfo

This commit is contained in:
Christian Schabesberger 2018-07-08 14:27:12 +02:00
parent 17e7214d25
commit d10f9a5f25
3 changed files with 175 additions and 152 deletions

View File

@ -54,7 +54,7 @@ dependencies {
exclude module: 'support-annotations' exclude module: 'support-annotations'
} }
implementation 'com.github.TeamNewPipe:NewPipeExtractor:bf1c771' implementation 'com.github.TeamNewPipe:NewPipeExtractor:39332a283b1c911'
testImplementation 'junit:junit:4.12' testImplementation 'junit:junit:4.12'
testImplementation 'org.mockito:mockito-core:2.8.9' testImplementation 'org.mockito:mockito-core:2.8.9'

View File

@ -38,10 +38,13 @@ import org.schabi.newpipe.extractor.NewPipe;
import org.schabi.newpipe.extractor.StreamingService; import org.schabi.newpipe.extractor.StreamingService;
import org.schabi.newpipe.extractor.exceptions.ParsingException; import org.schabi.newpipe.extractor.exceptions.ParsingException;
import org.schabi.newpipe.extractor.search.SearchEngine; import org.schabi.newpipe.extractor.search.SearchEngine;
import org.schabi.newpipe.extractor.search.SearchInfo;
import org.schabi.newpipe.extractor.search.SearchResult; import org.schabi.newpipe.extractor.search.SearchResult;
import org.schabi.newpipe.extractor.uih.SearchQIHandler;
import org.schabi.newpipe.fragments.BackPressable; import org.schabi.newpipe.fragments.BackPressable;
import org.schabi.newpipe.fragments.list.BaseListFragment; import org.schabi.newpipe.fragments.list.BaseListFragment;
import org.schabi.newpipe.local.history.HistoryRecordManager; import org.schabi.newpipe.local.history.HistoryRecordManager;
import org.schabi.newpipe.report.ErrorActivity;
import org.schabi.newpipe.report.UserAction; import org.schabi.newpipe.report.UserAction;
import org.schabi.newpipe.util.Constants; import org.schabi.newpipe.util.Constants;
import org.schabi.newpipe.util.AnimationUtils; import org.schabi.newpipe.util.AnimationUtils;
@ -56,7 +59,7 @@ import java.util.ArrayList;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.Queue; import java.util.Queue;
import java.util.concurrent.Callable; import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import icepick.State; import icepick.State;
@ -65,14 +68,13 @@ import io.reactivex.Observable;
import io.reactivex.android.schedulers.AndroidSchedulers; import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.CompositeDisposable; import io.reactivex.disposables.CompositeDisposable;
import io.reactivex.disposables.Disposable; import io.reactivex.disposables.Disposable;
import io.reactivex.functions.Consumer;
import io.reactivex.schedulers.Schedulers; import io.reactivex.schedulers.Schedulers;
import io.reactivex.subjects.PublishSubject; import io.reactivex.subjects.PublishSubject;
import static org.schabi.newpipe.util.AnimationUtils.animateView; import static org.schabi.newpipe.util.AnimationUtils.animateView;
public class SearchFragment public class SearchFragment
extends BaseListFragment<SearchResult, ListExtractor.InfoItemsPage> extends BaseListFragment<SearchInfo, ListExtractor.InfoItemsPage>
implements BackPressable { implements BackPressable {
/*////////////////////////////////////////////////////////////////////////// /*//////////////////////////////////////////////////////////////////////////
@ -92,19 +94,21 @@ public class SearchFragment
@State @State
protected int filterItemCheckedId = -1; protected int filterItemCheckedId = -1;
private SearchEngine.Filter filter = SearchEngine.Filter.ANY;
@State @State
protected int serviceId = Constants.NO_SERVICE_ID; protected int serviceId = Constants.NO_SERVICE_ID;
@State @State
protected String searchQuery; protected SearchQIHandler searchQuery;
@State @State
protected String lastSearchedQuery; protected SearchQIHandler lastSearchedQuery;
@State @State
protected boolean wasSearchFocused = false; protected boolean wasSearchFocused = false;
@State
List<String> contentFilter;
private int currentPage = 0; private StreamingService service;
private int currentNextPage = 0; private String currentPageUrl;
private String nextPageUrl;
private String contentCountry; private String contentCountry;
private boolean isSuggestionsEnabled = true; private boolean isSuggestionsEnabled = true;
private boolean isSearchHistoryEnabled = true; private boolean isSearchHistoryEnabled = true;
@ -130,11 +134,11 @@ public class SearchFragment
/*////////////////////////////////////////////////////////////////////////*/ /*////////////////////////////////////////////////////////////////////////*/
public static SearchFragment getInstance(int serviceId, String query) { public static SearchFragment getInstance(int serviceId, SearchQIHandler query) {
SearchFragment searchFragment = new SearchFragment(); SearchFragment searchFragment = new SearchFragment();
searchFragment.setQuery(serviceId, query); searchFragment.setQuery(serviceId, query);
if (!TextUtils.isEmpty(query)) { if (!TextUtils.isEmpty(query.getSearchString())) {
searchFragment.setSearchOnResume(); searchFragment.setSearchOnResume();
} }
@ -202,10 +206,19 @@ public class SearchFragment
if (DEBUG) Log.d(TAG, "onResume() called"); if (DEBUG) Log.d(TAG, "onResume() called");
super.onResume(); super.onResume();
if (!TextUtils.isEmpty(searchQuery)) { try {
service = NewPipe.getService(serviceId);
} catch (Exception e) {
ErrorActivity.reportError(getActivity(), e, getActivity().getClass(),
getActivity().findViewById(android.R.id.content),
ErrorActivity.ErrorInfo.make(UserAction.UI_ERROR,
"",
"", R.string.general_error));
}
if (!TextUtils.isEmpty(searchQuery.getSearchString())) {
if (wasLoading.getAndSet(false)) { if (wasLoading.getAndSet(false)) {
if (currentNextPage > currentPage) loadMoreItems(); search(searchQuery);
else search(searchQuery);
} else if (infoListAdapter.getItemsList().size() == 0) { } else if (infoListAdapter.getItemsList().size() == 0) {
if (savedState == null) { if (savedState == null) {
search(searchQuery); search(searchQuery);
@ -218,7 +231,7 @@ public class SearchFragment
if (suggestionDisposable == null || suggestionDisposable.isDisposed()) initSuggestionObserver(); if (suggestionDisposable == null || suggestionDisposable.isDisposed()) initSuggestionObserver();
if (TextUtils.isEmpty(searchQuery) || wasSearchFocused) { if (TextUtils.isEmpty(searchQuery.getSearchString()) || wasSearchFocused) {
showKeyboardSearch(); showKeyboardSearch();
showSuggestionsPanel(); showSuggestionsPanel();
} else { } else {
@ -247,7 +260,8 @@ public class SearchFragment
public void onActivityResult(int requestCode, int resultCode, Intent data) { public void onActivityResult(int requestCode, int resultCode, Intent data) {
switch (requestCode) { switch (requestCode) {
case ReCaptchaActivity.RECAPTCHA_REQUEST: case ReCaptchaActivity.RECAPTCHA_REQUEST:
if (resultCode == Activity.RESULT_OK && !TextUtils.isEmpty(searchQuery)) { if (resultCode == Activity.RESULT_OK
&& !TextUtils.isEmpty(searchQuery.getSearchString())) {
search(searchQuery); search(searchQuery);
} else Log.e(TAG, "ReCaptcha failed"); } else Log.e(TAG, "ReCaptcha failed");
break; break;
@ -282,20 +296,31 @@ public class SearchFragment
@Override @Override
public void writeTo(Queue<Object> objectsToSave) { public void writeTo(Queue<Object> objectsToSave) {
super.writeTo(objectsToSave); super.writeTo(objectsToSave);
objectsToSave.add(currentPage); objectsToSave.add(currentPageUrl);
objectsToSave.add(currentNextPage); objectsToSave.add(nextPageUrl);
} }
@Override @Override
public void readFrom(@NonNull Queue<Object> savedObjects) throws Exception { public void readFrom(@NonNull Queue<Object> savedObjects) throws Exception {
super.readFrom(savedObjects); super.readFrom(savedObjects);
currentPage = (int) savedObjects.poll(); currentPageUrl = (String) savedObjects.poll();
currentNextPage = (int) savedObjects.poll(); nextPageUrl = (String) savedObjects.poll();
} }
@Override @Override
public void onSaveInstanceState(Bundle bundle) { public void onSaveInstanceState(Bundle bundle) {
searchQuery = searchEditText != null ? searchEditText.getText().toString() : searchQuery; try {
searchQuery = searchEditText != null
? NewPipe.getService(serviceId).getSearchQIHFactory().fromQuery(
searchEditText.getText().toString())
: searchQuery;
} catch (Exception e) {
ErrorActivity.reportError(getActivity(), e, getActivity().getClass(),
getActivity().findViewById(android.R.id.content),
ErrorActivity.ErrorInfo.make(UserAction.UI_ERROR,
"",
"", R.string.general_error));
}
super.onSaveInstanceState(bundle); super.onSaveInstanceState(bundle);
} }
@ -305,8 +330,12 @@ public class SearchFragment
@Override @Override
public void reloadContent() { public void reloadContent() {
if (!TextUtils.isEmpty(searchQuery) || (searchEditText != null && !TextUtils.isEmpty(searchEditText.getText()))) { if (!TextUtils.isEmpty(searchQuery.getSearchString())
search(!TextUtils.isEmpty(searchQuery) ? searchQuery : searchEditText.getText().toString()); || (searchEditText != null && !TextUtils.isEmpty(searchEditText.getText()))) {
search(!TextUtils.isEmpty(searchQuery.getSearchString())
? searchQuery
: getSearchQuery(searchEditText.getText().toString(),
new ArrayList<>(0), ""));
} else { } else {
if (searchEditText != null) { if (searchEditText != null) {
searchEditText.setText(""); searchEditText.setText("");
@ -330,22 +359,20 @@ public class SearchFragment
supportActionBar.setDisplayHomeAsUpEnabled(true); supportActionBar.setDisplayHomeAsUpEnabled(true);
} }
inflater.inflate(R.menu.menu_search, menu); for(String filter : service.getSearchQIHFactory().getAvailableContentFilter()) {
menu.add(filter);
}
restoreFilterChecked(menu, filterItemCheckedId); restoreFilterChecked(menu, filterItemCheckedId);
} }
@Override @Override
public boolean onOptionsItemSelected(MenuItem item) { public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.menu_filter_all: List<String> contentFilter = new ArrayList<>(1);
case R.id.menu_filter_video: contentFilter.add(item.getTitle().toString());
case R.id.menu_filter_channel: changeContentFilter(item, contentFilter);
case R.id.menu_filter_playlist:
changeFilter(item, getFilterFromMenuId(item.getItemId())); return true;
return true;
default:
return super.onOptionsItemSelected(item);
}
} }
private void restoreFilterChecked(Menu menu, int itemId) { private void restoreFilterChecked(Menu menu, int itemId) {
@ -354,21 +381,8 @@ public class SearchFragment
if (item == null) return; if (item == null) return;
item.setChecked(true); item.setChecked(true);
filter = getFilterFromMenuId(itemId); contentFilter.clear();
} contentFilter.add(menu.getItem(itemId).getTitle().toString());
}
private SearchEngine.Filter getFilterFromMenuId(int itemId) {
switch (itemId) {
case R.id.menu_filter_video:
return SearchEngine.Filter.STREAM;
case R.id.menu_filter_channel:
return SearchEngine.Filter.CHANNEL;
case R.id.menu_filter_playlist:
return SearchEngine.Filter.PLAYLIST;
case R.id.menu_filter_all:
default:
return SearchEngine.Filter.ANY;
} }
} }
@ -380,9 +394,9 @@ public class SearchFragment
private void showSearchOnStart() { private void showSearchOnStart() {
if (DEBUG) Log.d(TAG, "showSearchOnStart() called, searchQuery → " + searchQuery+", lastSearchedQuery → " + lastSearchedQuery); if (DEBUG) Log.d(TAG, "showSearchOnStart() called, searchQuery → " + searchQuery+", lastSearchedQuery → " + lastSearchedQuery);
searchEditText.setText(searchQuery); searchEditText.setText(searchQuery.getSearchString());
if (TextUtils.isEmpty(searchQuery) || TextUtils.isEmpty(searchEditText.getText())) { if (TextUtils.isEmpty(searchQuery.getSearchString()) || TextUtils.isEmpty(searchEditText.getText())) {
searchToolbarContainer.setTranslationX(100); searchToolbarContainer.setTranslationX(100);
searchToolbarContainer.setAlpha(0f); searchToolbarContainer.setAlpha(0f);
searchToolbarContainer.setVisibility(View.VISIBLE); searchToolbarContainer.setVisibility(View.VISIBLE);
@ -396,47 +410,38 @@ public class SearchFragment
private void initSearchListeners() { private void initSearchListeners() {
if (DEBUG) Log.d(TAG, "initSearchListeners() called"); if (DEBUG) Log.d(TAG, "initSearchListeners() called");
searchClear.setOnClickListener(new View.OnClickListener() { searchClear.setOnClickListener(v -> {
@Override if (DEBUG) Log.d(TAG, "onClick() called with: v = [" + v + "]");
public void onClick(View v) { if (TextUtils.isEmpty(searchEditText.getText())) {
if (DEBUG) Log.d(TAG, "onClick() called with: v = [" + v + "]"); NavigationHelper.gotoMainFragment(getFragmentManager());
if (TextUtils.isEmpty(searchEditText.getText())) { return;
NavigationHelper.gotoMainFragment(getFragmentManager());
return;
}
searchEditText.setText("");
suggestionListAdapter.setItems(new ArrayList<SuggestionItem>());
showKeyboardSearch();
} }
searchEditText.setText("");
suggestionListAdapter.setItems(new ArrayList<>());
showKeyboardSearch();
}); });
TooltipCompat.setTooltipText(searchClear, getString(R.string.clear)); TooltipCompat.setTooltipText(searchClear, getString(R.string.clear));
searchEditText.setOnClickListener(new View.OnClickListener() { searchEditText.setOnClickListener(v -> {
@Override if (DEBUG) Log.d(TAG, "onClick() called with: v = [" + v + "]");
public void onClick(View v) { if (isSuggestionsEnabled && errorPanelRoot.getVisibility() != View.VISIBLE) {
if (DEBUG) Log.d(TAG, "onClick() called with: v = [" + v + "]"); showSuggestionsPanel();
if (isSuggestionsEnabled && errorPanelRoot.getVisibility() != View.VISIBLE) {
showSuggestionsPanel();
}
} }
}); });
searchEditText.setOnFocusChangeListener(new View.OnFocusChangeListener() { searchEditText.setOnFocusChangeListener((View v, boolean hasFocus) -> {
@Override if (DEBUG) Log.d(TAG, "onFocusChange() called with: v = [" + v + "], hasFocus = [" + hasFocus + "]");
public void onFocusChange(View v, boolean hasFocus) { if (isSuggestionsEnabled && hasFocus && errorPanelRoot.getVisibility() != View.VISIBLE) {
if (DEBUG) Log.d(TAG, "onFocusChange() called with: v = [" + v + "], hasFocus = [" + hasFocus + "]"); showSuggestionsPanel();
if (isSuggestionsEnabled && hasFocus && errorPanelRoot.getVisibility() != View.VISIBLE) {
showSuggestionsPanel();
}
} }
}); });
suggestionListAdapter.setListener(new SuggestionListAdapter.OnSuggestionItemSelected() { suggestionListAdapter.setListener(new SuggestionListAdapter.OnSuggestionItemSelected() {
@Override @Override
public void onSuggestionItemSelected(SuggestionItem item) { public void onSuggestionItemSelected(SuggestionItem item) {
search(item.query); search(getSearchQuery(item.query, new ArrayList<>(), ""));
searchEditText.setText(item.query); searchEditText.setText(item.query);
} }
@ -469,21 +474,22 @@ public class SearchFragment
} }
}; };
searchEditText.addTextChangedListener(textWatcher); searchEditText.addTextChangedListener(textWatcher);
searchEditText.setOnEditorActionListener(new TextView.OnEditorActionListener() { searchEditText.setOnEditorActionListener(
@Override (TextView v, int actionId, KeyEvent event) -> {
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) { if (DEBUG) {
if (DEBUG) { Log.d(TAG, "onEditorAction() called with: v = [" + v + "], actionId = [" + actionId + "], event = [" + event + "]");
Log.d(TAG, "onEditorAction() called with: v = [" + v + "], actionId = [" + actionId + "], event = [" + event + "]"); }
} if (event != null
if (event != null && (event.getKeyCode() == KeyEvent.KEYCODE_ENTER || event.getAction() == EditorInfo.IME_ACTION_SEARCH)) { && (event.getKeyCode() == KeyEvent.KEYCODE_ENTER
search(searchEditText.getText().toString()); || event.getAction() == EditorInfo.IME_ACTION_SEARCH)) {
return true; search(getSearchQuery(searchEditText.getText().toString(), new ArrayList<>(), ""));
} return true;
return false; }
} return false;
}); });
if (suggestionDisposable == null || suggestionDisposable.isDisposed()) initSuggestionObserver(); if (suggestionDisposable == null || suggestionDisposable.isDisposed())
initSuggestionObserver();
} }
private void unsetSearchListeners() { private void unsetSearchListeners() {
@ -513,7 +519,8 @@ public class SearchFragment
if (searchEditText == null) return; if (searchEditText == null) return;
if (searchEditText.requestFocus()) { if (searchEditText.requestFocus()) {
InputMethodManager imm = (InputMethodManager) activity.getSystemService(Context.INPUT_METHOD_SERVICE); InputMethodManager imm = (InputMethodManager) activity.getSystemService(
Context.INPUT_METHOD_SERVICE);
imm.showSoftInput(searchEditText, InputMethodManager.SHOW_IMPLICIT); imm.showSoftInput(searchEditText, InputMethodManager.SHOW_IMPLICIT);
} }
} }
@ -522,8 +529,10 @@ public class SearchFragment
if (DEBUG) Log.d(TAG, "hideKeyboardSearch() called"); if (DEBUG) Log.d(TAG, "hideKeyboardSearch() called");
if (searchEditText == null) return; if (searchEditText == null) return;
InputMethodManager imm = (InputMethodManager) activity.getSystemService(Context.INPUT_METHOD_SERVICE); InputMethodManager imm = (InputMethodManager) activity.getSystemService(
imm.hideSoftInputFromWindow(searchEditText.getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS); Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(searchEditText.getWindowToken(),
InputMethodManager.HIDE_NOT_ALWAYS);
searchEditText.clearFocus(); searchEditText.clearFocus();
} }
@ -557,7 +566,7 @@ public class SearchFragment
if (suggestionsPanel.getVisibility() == View.VISIBLE && infoListAdapter.getItemsList().size() > 0 && !isLoading.get()) { if (suggestionsPanel.getVisibility() == View.VISIBLE && infoListAdapter.getItemsList().size() > 0 && !isLoading.get()) {
hideSuggestionsPanel(); hideSuggestionsPanel();
hideKeyboardSearch(); hideKeyboardSearch();
searchEditText.setText(lastSearchedQuery); searchEditText.setText(lastSearchedQuery.getSearchString());
return true; return true;
} }
return false; return false;
@ -573,8 +582,10 @@ public class SearchFragment
final Observable<String> observable = suggestionPublisher final Observable<String> observable = suggestionPublisher
.debounce(SUGGESTIONS_DEBOUNCE, TimeUnit.MILLISECONDS) .debounce(SUGGESTIONS_DEBOUNCE, TimeUnit.MILLISECONDS)
.startWith(searchQuery != null ? searchQuery : "") .startWith(searchQuery != null
.filter(query -> isSuggestionsEnabled); ? searchQuery.getSearchString()
: "")
.filter(searchString -> isSuggestionsEnabled);
suggestionDisposable = observable suggestionDisposable = observable
.switchMap(query -> { .switchMap(query -> {
@ -645,35 +656,24 @@ public class SearchFragment
// no-op // no-op
} }
private void search(final String query) { private void search(final SearchQIHandler query) {
if (DEBUG) Log.d(TAG, "search() called with: query = [" + query + "]"); if (DEBUG) Log.d(TAG, "search() called with: query = [" + query + "]");
if (query.isEmpty()) return; if (query.getSearchString().isEmpty()) return;
try { try {
final StreamingService service = NewPipe.getServiceByUrl(query); final StreamingService service = NewPipe.getServiceByUrl(query.getUrl());
if (service != null) { if (service != null) {
showLoading(); showLoading();
disposables.add(Observable disposables.add(Observable
.fromCallable(new Callable<Intent>() { .fromCallable(() ->
@Override NavigationHelper.getIntentByLink(activity, service, query.getUrl()))
public Intent call() throws Exception {
return NavigationHelper.getIntentByLink(activity, service, query);
}
})
.subscribeOn(Schedulers.io()) .subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread()) .observeOn(AndroidSchedulers.mainThread())
.subscribe(new Consumer<Intent>() { .subscribe(intent -> {
@Override getFragmentManager().popBackStackImmediate();
public void accept(Intent intent) throws Exception { activity.startActivity(intent);
getFragmentManager().popBackStackImmediate(); }, throwable ->
activity.startActivity(intent); showError(getString(R.string.url_not_supported_toast), false)));
}
}, new Consumer<Throwable>() {
@Override
public void accept(Throwable throwable) throws Exception {
showError(getString(R.string.url_not_supported_toast), false);
}
}));
return; return;
} }
} catch (Exception e) { } catch (Exception e) {
@ -682,19 +682,19 @@ public class SearchFragment
lastSearchedQuery = query; lastSearchedQuery = query;
searchQuery = query; searchQuery = query;
currentPage = 0; currentPageUrl = "";
infoListAdapter.clearStreamItemList(); infoListAdapter.clearStreamItemList();
hideSuggestionsPanel(); hideSuggestionsPanel();
hideKeyboardSearch(); hideKeyboardSearch();
historyRecordManager.onSearched(serviceId, query) historyRecordManager.onSearched(serviceId, query.getSearchString())
.observeOn(AndroidSchedulers.mainThread()) .observeOn(AndroidSchedulers.mainThread())
.subscribe( .subscribe(
ignored -> {}, ignored -> {},
error -> showSnackBarError(error, UserAction.SEARCHED, error -> showSnackBarError(error, UserAction.SEARCHED,
NewPipe.getNameOfService(serviceId), query, 0) NewPipe.getNameOfService(serviceId), query.getSearchString(), 0)
); );
suggestionPublisher.onNext(query); suggestionPublisher.onNext(query.getSearchString());
startLoading(false); startLoading(false);
} }
@ -703,7 +703,8 @@ public class SearchFragment
super.startLoading(forceLoad); super.startLoading(forceLoad);
if (disposables != null) disposables.clear(); if (disposables != null) disposables.clear();
if (searchDisposable != null) searchDisposable.dispose(); if (searchDisposable != null) searchDisposable.dispose();
searchDisposable = ExtractorHelper.searchFor(serviceId, searchQuery, currentPage, contentCountry, filter) searchDisposable = ExtractorHelper.searchFor(serviceId,
searchQuery, currentPageUrl, contentCountry, contentFilter, "")
.subscribeOn(Schedulers.io()) .subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread()) .observeOn(AndroidSchedulers.mainThread())
.doOnEvent((searchResult, throwable) -> isLoading.set(false)) .doOnEvent((searchResult, throwable) -> isLoading.set(false))
@ -716,7 +717,8 @@ public class SearchFragment
showListFooter(true); showListFooter(true);
if (searchDisposable != null) searchDisposable.dispose(); if (searchDisposable != null) searchDisposable.dispose();
currentNextPage = currentPage + 1; currentNextPage = currentPage + 1;
searchDisposable = ExtractorHelper.getMoreSearchItems(serviceId, searchQuery, currentNextPage, contentCountry, filter) searchDisposable = ExtractorHelper.getMoreSearchItems(serviceId,
searchQuery, currentNextPage, contentCountry, filter)
.subscribeOn(Schedulers.io()) .subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread()) .observeOn(AndroidSchedulers.mainThread())
.doOnEvent((nextItemsResult, throwable) -> isLoading.set(false)) .doOnEvent((nextItemsResult, throwable) -> isLoading.set(false))
@ -739,21 +741,38 @@ public class SearchFragment
// Utils // Utils
//////////////////////////////////////////////////////////////////////////*/ //////////////////////////////////////////////////////////////////////////*/
private void changeFilter(MenuItem item, SearchEngine.Filter filter) { private void changeContentFilter(MenuItem item, List<String> contentFilter) {
this.filter = filter;
this.filterItemCheckedId = item.getItemId(); this.filterItemCheckedId = item.getItemId();
item.setChecked(true); item.setChecked(true);
if (!TextUtils.isEmpty(searchQuery)) { this.contentFilter = contentFilter;
searchQuery = getSearchQuery(searchQuery.getSearchString(), contentFilter, "");
if (!TextUtils.isEmpty(searchQuery.getSearchString())) {
search(searchQuery); search(searchQuery);
} }
} }
private void setQuery(int serviceId, String searchQuery) { private void setQuery(int serviceId, SearchQIHandler searchQuery) {
this.serviceId = serviceId; this.serviceId = serviceId;
this.searchQuery = searchQuery; this.searchQuery = searchQuery;
} }
private SearchQIHandler getSearchQuery(String searchString,
List<String> contentFilter,
String sortFilter) {
try {
return service.getSearchQIHFactory()
.fromQuery(searchString, contentFilter, sortFilter);
} catch (Exception e) {
ErrorActivity.reportError(getActivity(), e, getActivity().getClass(),
getActivity().findViewById(android.R.id.content),
ErrorActivity.ErrorInfo.make(UserAction.UI_ERROR,
"",
"", R.string.general_error));
}
}
/*////////////////////////////////////////////////////////////////////////// /*//////////////////////////////////////////////////////////////////////////
// Suggestion Results // Suggestion Results
//////////////////////////////////////////////////////////////////////////*/ //////////////////////////////////////////////////////////////////////////*/
@ -772,8 +791,11 @@ public class SearchFragment
if (DEBUG) Log.d(TAG, "onSuggestionError() called with: exception = [" + exception + "]"); if (DEBUG) Log.d(TAG, "onSuggestionError() called with: exception = [" + exception + "]");
if (super.onError(exception)) return; if (super.onError(exception)) return;
int errorId = exception instanceof ParsingException ? R.string.parsing_error : R.string.general_error; int errorId = exception instanceof ParsingException
onUnrecoverableError(exception, UserAction.GET_SUGGESTIONS, NewPipe.getNameOfService(serviceId), searchQuery, errorId); ? R.string.parsing_error
: R.string.general_error;
onUnrecoverableError(exception, UserAction.GET_SUGGESTIONS,
NewPipe.getNameOfService(serviceId), searchQuery, errorId);
} }
/*////////////////////////////////////////////////////////////////////////// /*//////////////////////////////////////////////////////////////////////////
@ -800,7 +822,8 @@ public class SearchFragment
@Override @Override
public void handleResult(@NonNull SearchResult result) { public void handleResult(@NonNull SearchResult result) {
if (!result.errors.isEmpty()) { if (!result.errors.isEmpty()) {
showSnackBarError(result.errors, UserAction.SEARCHED, NewPipe.getNameOfService(serviceId), searchQuery, 0); showSnackBarError(result.errors, UserAction.SEARCHED,
NewPipe.getNameOfService(serviceId), searchQuery, 0);
} }
lastSearchedQuery = searchQuery; lastSearchedQuery = searchQuery;
@ -825,7 +848,8 @@ public class SearchFragment
infoListAdapter.addInfoItemList(result.getItems()); infoListAdapter.addInfoItemList(result.getItems());
if (!result.getErrors().isEmpty()) { if (!result.getErrors().isEmpty()) {
showSnackBarError(result.getErrors(), UserAction.SEARCHED, NewPipe.getNameOfService(serviceId) showSnackBarError(result.getErrors(), UserAction.SEARCHED,
NewPipe.getNameOfService(serviceId)
, "\"" + searchQuery + "\" → page " + currentPage, 0); , "\"" + searchQuery + "\" → page " + currentPage, 0);
} }
super.handleNextItems(result); super.handleNextItems(result);
@ -839,8 +863,11 @@ public class SearchFragment
infoListAdapter.clearStreamItemList(); infoListAdapter.clearStreamItemList();
showEmptyState(); showEmptyState();
} else { } else {
int errorId = exception instanceof ParsingException ? R.string.parsing_error : R.string.general_error; int errorId = exception instanceof ParsingException
onUnrecoverableError(exception, UserAction.SEARCHED, NewPipe.getNameOfService(serviceId), searchQuery, errorId); ? R.string.parsing_error
: R.string.general_error;
onUnrecoverableError(exception, UserAction.SEARCHED,
NewPipe.getNameOfService(serviceId), searchQuery, errorId);
} }
return true; return true;

View File

@ -38,9 +38,11 @@ import org.schabi.newpipe.extractor.exceptions.ReCaptchaException;
import org.schabi.newpipe.extractor.kiosk.KioskInfo; import org.schabi.newpipe.extractor.kiosk.KioskInfo;
import org.schabi.newpipe.extractor.playlist.PlaylistInfo; import org.schabi.newpipe.extractor.playlist.PlaylistInfo;
import org.schabi.newpipe.extractor.search.SearchEngine; import org.schabi.newpipe.extractor.search.SearchEngine;
import org.schabi.newpipe.extractor.search.SearchInfo;
import org.schabi.newpipe.extractor.search.SearchResult; import org.schabi.newpipe.extractor.search.SearchResult;
import org.schabi.newpipe.extractor.services.youtube.YoutubeStreamExtractor; import org.schabi.newpipe.extractor.services.youtube.YoutubeStreamExtractor;
import org.schabi.newpipe.extractor.stream.StreamInfo; import org.schabi.newpipe.extractor.stream.StreamInfo;
import org.schabi.newpipe.extractor.uih.SearchQIHandler;
import org.schabi.newpipe.report.ErrorActivity; import org.schabi.newpipe.report.ErrorActivity;
import org.schabi.newpipe.report.UserAction; import org.schabi.newpipe.report.UserAction;
@ -66,29 +68,23 @@ public final class ExtractorHelper {
} }
} }
public static Single<SearchResult> searchFor(final int serviceId, public static Single<SearchInfo> searchFor(final int serviceId,
final String query, final SearchQIHandler query,
final int pageNumber, final String contentCountry) {
final String contentCountry,
final SearchEngine.Filter filter) {
checkServiceId(serviceId); checkServiceId(serviceId);
return Single.fromCallable(() -> return Single.fromCallable(() ->
SearchResult.getSearchResult(NewPipe.getService(serviceId).getSearchEngine(), SearchInfo.getInfo(NewPipe.getService(serviceId).getSearchExtractor(query, contentCountry)));
query, pageNumber, contentCountry, filter)
);
} }
public static Single<InfoItemsPage> getMoreSearchItems(final int serviceId, public static Single<InfoItemsPage> getMoreSearchItems(final int serviceId,
final String query, final SearchQIHandler query,
final int nextPageNumber, final String pageUrl,
final String searchLanguage, final String contentCountry) {
final SearchEngine.Filter filter) {
checkServiceId(serviceId); checkServiceId(serviceId);
return searchFor(serviceId, query, nextPageNumber, searchLanguage, filter) return Single.fromCallable(() ->
.map((@NonNull SearchResult searchResult) -> SearchInfo.get
new InfoItemsPage(searchResult.resultList, NewPipe.getService(serviceId).getSearchExtractor(query, contentCountry))
nextPageNumber + "",
searchResult.errors));
} }
public static Single<List<String>> suggestionsFor(final int serviceId, public static Single<List<String>> suggestionsFor(final int serviceId,