add getMoreInfo to SearchInfo
This commit is contained in:
parent
17e7214d25
commit
d10f9a5f25
3 changed files with 175 additions and 152 deletions
|
@ -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'
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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,
|
||||||
|
|
Loading…
Reference in a new issue