Merge pull request #3471 from Royosef/DisplaySearchSuggestion

Display search suggestion: did you mean & showing result for
This commit is contained in:
Tobias Groza 2020-07-07 20:57:02 +02:00 committed by GitHub
commit f4a4172369
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 76 additions and 8 deletions

View file

@ -7,6 +7,7 @@ import android.content.SharedPreferences;
import android.os.Bundle; import android.os.Bundle;
import android.preference.PreferenceManager; import android.preference.PreferenceManager;
import android.text.Editable; import android.text.Editable;
import android.text.Html;
import android.text.TextUtils; import android.text.TextUtils;
import android.text.TextWatcher; import android.text.TextWatcher;
import android.util.Log; import android.util.Log;
@ -71,6 +72,7 @@ import io.reactivex.disposables.Disposable;
import io.reactivex.schedulers.Schedulers; import io.reactivex.schedulers.Schedulers;
import io.reactivex.subjects.PublishSubject; import io.reactivex.subjects.PublishSubject;
import static android.text.Html.escapeHtml;
import static androidx.recyclerview.widget.ItemTouchHelper.Callback.makeMovementFlags; import static androidx.recyclerview.widget.ItemTouchHelper.Callback.makeMovementFlags;
import static java.util.Arrays.asList; import static java.util.Arrays.asList;
import static org.schabi.newpipe.util.AnimationUtils.animateView; import static org.schabi.newpipe.util.AnimationUtils.animateView;
@ -118,6 +120,12 @@ public class SearchFragment extends BaseListFragment<SearchInfo, ListExtractor.I
@State @State
String lastSearchedString; String lastSearchedString;
@State
String searchSuggestion;
@State
boolean isCorrectedSearch;
@State @State
boolean wasSearchFocused = false; boolean wasSearchFocused = false;
@ -143,6 +151,8 @@ public class SearchFragment extends BaseListFragment<SearchInfo, ListExtractor.I
private EditText searchEditText; private EditText searchEditText;
private View searchClear; private View searchClear;
private TextView correctSuggestion;
private View suggestionsPanel; private View suggestionsPanel;
private RecyclerView suggestionsRecyclerView; private RecyclerView suggestionsRecyclerView;
@ -257,6 +267,8 @@ public class SearchFragment extends BaseListFragment<SearchInfo, ListExtractor.I
} }
} }
handleSearchSuggestion();
if (suggestionDisposable == null || suggestionDisposable.isDisposed()) { if (suggestionDisposable == null || suggestionDisposable.isDisposed()) {
initSuggestionObserver(); initSuggestionObserver();
} }
@ -345,6 +357,8 @@ public class SearchFragment extends BaseListFragment<SearchInfo, ListExtractor.I
searchToolbarContainer = activity.findViewById(R.id.toolbar_search_container); searchToolbarContainer = activity.findViewById(R.id.toolbar_search_container);
searchEditText = searchToolbarContainer.findViewById(R.id.toolbar_search_edit_text); searchEditText = searchToolbarContainer.findViewById(R.id.toolbar_search_edit_text);
searchClear = searchToolbarContainer.findViewById(R.id.toolbar_search_clear); searchClear = searchToolbarContainer.findViewById(R.id.toolbar_search_clear);
correctSuggestion = rootView.findViewById(R.id.correct_suggestion);
} }
/*////////////////////////////////////////////////////////////////////////// /*//////////////////////////////////////////////////////////////////////////
@ -497,6 +511,8 @@ public class SearchFragment extends BaseListFragment<SearchInfo, ListExtractor.I
return; return;
} }
correctSuggestion.setVisibility(View.GONE);
searchEditText.setText(""); searchEditText.setText("");
suggestionListAdapter.setItems(new ArrayList<>()); suggestionListAdapter.setItems(new ArrayList<>());
showKeyboardSearch(); showKeyboardSearch();
@ -554,11 +570,13 @@ public class SearchFragment extends BaseListFragment<SearchInfo, ListExtractor.I
textWatcher = new TextWatcher() { textWatcher = new TextWatcher() {
@Override @Override
public void beforeTextChanged(final CharSequence s, final int start, public void beforeTextChanged(final CharSequence s, final int start,
final int count, final int after) { } final int count, final int after) {
}
@Override @Override
public void onTextChanged(final CharSequence s, final int start, public void onTextChanged(final CharSequence s, final int start,
final int before, final int count) { } final int before, final int count) {
}
@Override @Override
public void afterTextChanged(final Editable s) { public void afterTextChanged(final Editable s) {
@ -688,10 +706,6 @@ public class SearchFragment extends BaseListFragment<SearchInfo, ListExtractor.I
return false; return false;
} }
public void giveSearchEditTextFocus() {
showKeyboardSearch();
}
private void initSuggestionObserver() { private void initSuggestionObserver() {
if (DEBUG) { if (DEBUG) {
Log.d(TAG, "initSuggestionObserver() called"); Log.d(TAG, "initSuggestionObserver() called");
@ -961,6 +975,11 @@ public class SearchFragment extends BaseListFragment<SearchInfo, ListExtractor.I
NewPipe.getNameOfService(serviceId), searchString, 0); NewPipe.getNameOfService(serviceId), searchString, 0);
} }
searchSuggestion = result.getSearchSuggestion();
isCorrectedSearch = result.isCorrectedSearch();
handleSearchSuggestion();
lastSearchedString = searchString; lastSearchedString = searchString;
nextPageUrl = result.getNextPageUrl(); nextPageUrl = result.getNextPageUrl();
currentPageUrl = result.getUrl(); currentPageUrl = result.getUrl();
@ -978,6 +997,37 @@ public class SearchFragment extends BaseListFragment<SearchInfo, ListExtractor.I
super.handleResult(result); super.handleResult(result);
} }
private void handleSearchSuggestion() {
if (TextUtils.isEmpty(searchSuggestion)) {
correctSuggestion.setVisibility(View.GONE);
} else {
final String helperText = getString(isCorrectedSearch
? R.string.search_showing_result_for
: R.string.did_you_mean);
final String highlightedSearchSuggestion =
"<b><i>" + escapeHtml(searchSuggestion) + "</i></b>";
correctSuggestion.setText(
Html.fromHtml(String.format(helperText, highlightedSearchSuggestion)));
correctSuggestion.setOnClickListener(v -> {
correctSuggestion.setVisibility(View.GONE);
search(searchSuggestion, contentFilter, sortFilter);
searchEditText.setText(searchSuggestion);
});
correctSuggestion.setOnLongClickListener(v -> {
searchEditText.setText(searchSuggestion);
searchEditText.setSelection(searchSuggestion.length());
showKeyboardSearch();
return true;
});
correctSuggestion.setVisibility(View.VISIBLE);
}
}
@Override @Override
public void handleNextItems(final ListExtractor.InfoItemsPage result) { public void handleNextItems(final ListExtractor.InfoItemsPage result) {
showListFooter(false); showListFooter(false);

View file

@ -6,13 +6,25 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent"> android:layout_height="match_parent">
<TextView
android:id="@+id/correct_suggestion"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignTop="@id/error_panel"
android:background="?attr/selectableItemBackground"
android:padding="10dp"
android:textColor="@color/background_title_color"
android:textSize="@dimen/search_suggestion_text_size"
tools:text="Showing results for lorem ipsum dolor sit amet consectetur adipisci elit" />
<androidx.recyclerview.widget.RecyclerView <androidx.recyclerview.widget.RecyclerView
android:id="@+id/items_list" android:id="@+id/items_list"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:layout_below="@+id/correct_suggestion"
android:scrollbars="vertical" android:scrollbars="vertical"
app:layoutManager="LinearLayoutManager" app:layoutManager="LinearLayoutManager"
tools:listitem="@layout/list_stream_item"/> tools:listitem="@layout/list_stream_item" />
<ProgressBar <ProgressBar
android:id="@+id/loading_progress_bar" android:id="@+id/loading_progress_bar"
@ -58,6 +70,7 @@
android:background="?android:attr/windowBackground" android:background="?android:attr/windowBackground"
android:focusable="true" android:focusable="true"
android:focusableInTouchMode="true" android:focusableInTouchMode="true"
android:orientation="vertical"
android:visibility="gone" android:visibility="gone"
tools:background="@android:color/transparent" tools:background="@android:color/transparent"
tools:visibility="visible"> tools:visibility="visible">
@ -68,7 +81,7 @@
android:layout_height="match_parent" android:layout_height="match_parent"
android:scrollbars="vertical" android:scrollbars="vertical"
app:layoutManager="LinearLayoutManager" app:layoutManager="LinearLayoutManager"
tools:listitem="@layout/item_search_suggestion"/> tools:listitem="@layout/item_search_suggestion" />
</LinearLayout> </LinearLayout>
<!--ERROR PANEL--> <!--ERROR PANEL-->

View file

@ -51,4 +51,6 @@
<!-- File picker dimensions --> <!-- File picker dimensions -->
<dimen name="file_picker_items_text_size">16sp</dimen> <dimen name="file_picker_items_text_size">16sp</dimen>
<dimen name="search_suggestion_text_size">14sp</dimen>
</resources> </resources>

View file

@ -21,4 +21,5 @@
<!-- Paddings & Margins --> <!-- Paddings & Margins -->
<dimen name="video_item_detail_like_margin">10dp</dimen> <dimen name="video_item_detail_like_margin">10dp</dimen>
<dimen name="search_suggestion_text_size">14sp</dimen>
</resources> </resources>

View file

@ -115,4 +115,5 @@
<dimen name="feed_group_carousel_top_bottom_margin">2dp</dimen> <dimen name="feed_group_carousel_top_bottom_margin">2dp</dimen>
<dimen name="feed_group_carousel_between_items_margin">4dp</dimen> <dimen name="feed_group_carousel_between_items_margin">4dp</dimen>
<dimen name="search_suggestion_text_size">16sp</dimen>
</resources> </resources>

View file

@ -16,6 +16,7 @@
<string name="search">Search</string> <string name="search">Search</string>
<string name="settings">Settings</string> <string name="settings">Settings</string>
<string name="did_you_mean">Did you mean: %1$s?</string> <string name="did_you_mean">Did you mean: %1$s?</string>
<string name="search_showing_result_for">Showing results for: %s</string>
<string name="share_dialog_title">Share with</string> <string name="share_dialog_title">Share with</string>
<string name="choose_browser">Choose browser</string> <string name="choose_browser">Choose browser</string>
<string name="screen_rotation">rotation</string> <string name="screen_rotation">rotation</string>