Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Made preferences searchable #7586

Merged
merged 27 commits into from
Jan 30, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
683d981
Removed dead code
litetex Dec 24, 2021
12acaf2
Added credit to the project which inspired the preference search
litetex Dec 24, 2021
f3be89b
Abstracted methods for the Android keyboard
litetex Dec 24, 2021
4a061f2
Code cleanup
litetex Dec 24, 2021
12a78a8
Added preference search "framework"
litetex Dec 24, 2021
07fb319
Applied code changes for preference search framework
litetex Dec 24, 2021
8fc935b
Added resource files
litetex Dec 24, 2021
22db417
Moved reset-reCAPTCHA-cookie to cache tab and made it read-only
litetex Dec 24, 2021
7fc0a38
Fine tuning
litetex Dec 24, 2021
52542e0
Added fuzzy searching + Some minor code refactoring
litetex Dec 24, 2021
0f45c69
Code cleanup + indexing improvements
litetex Dec 26, 2021
d593148
Code rework
litetex Dec 27, 2021
6b23df0
Made debug settings searchable (debug only)
litetex Dec 29, 2021
658168e
Fixed some sonar warnings
litetex Dec 29, 2021
bebd2b4
Removed unused import
litetex Dec 29, 2021
c5a0624
Fixed variable name
litetex Dec 29, 2021
8bbc3e5
Fixed gitignore and commited missing file
litetex Dec 29, 2021
ce4dd33
Fixed problems with Android's lifecycle (restore)
litetex Dec 31, 2021
9b2c86a
Improved documentation
litetex Dec 31, 2021
37cd713
Moved ``FuzzyScore`` to original Apache package
litetex Jan 9, 2022
b16e972
Improved doc
litetex Jan 9, 2022
e2f449f
Code improvements
litetex Jan 9, 2022
03bb212
Removed breadcrumbs customization
litetex Jan 9, 2022
7067ebd
Fixed imports
litetex Jan 9, 2022
f55e8ea
Use ViewBinding
litetex Jan 9, 2022
82de35d
Use view binding inside ``PreferenceViewHolder``
litetex Jan 24, 2022
8a069b4
Code cleanup
litetex Jan 25, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ captures/
*~
.weblate
*.class
**/debug/
**/release/
app/debug/
app/release/

# vscode / eclipse files
*.classpath
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package org.schabi.newpipe.settings;

import android.content.Intent;

import leakcanary.LeakCanary;

/**
* Build variant dependent (BVD) leak canary API implementation for the debug settings fragment.
* This class is loaded via reflection by
* {@link DebugSettingsFragment.DebugSettingsBVDLeakCanaryAPI}.
*/
@SuppressWarnings("unused") // Class is used but loaded via reflection
public class DebugSettingsBVDLeakCanary
implements DebugSettingsFragment.DebugSettingsBVDLeakCanaryAPI {

@Override
public Intent getNewLeakDisplayActivityIntent() {
return LeakCanary.INSTANCE.newLeakDisplayActivityIntent();
}
}

This file was deleted.

148 changes: 148 additions & 0 deletions app/src/main/java/org/apache/commons/text/similarity/FuzzyScore.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.text.similarity;

import java.util.Locale;

/**
* A matching algorithm that is similar to the searching algorithms implemented in editors such
* as Sublime Text, TextMate, Atom and others.
*
* <p>
* One point is given for every matched character. Subsequent matches yield two bonus points.
* A higher score indicates a higher similarity.
* </p>
*
* <p>
* This code has been adapted from Apache Commons Lang 3.3.
* </p>
*
* @since 1.0
*
* Note: This class was forked from
* <a href="https://git.io/JyYJg">
* apache/commons-text (8cfdafc) FuzzyScore.java
* </a>
*/
public class FuzzyScore {

/**
* Locale used to change the case of text.
*/
private final Locale locale;


/**
* This returns a {@link Locale}-specific {@link FuzzyScore}.
*
* @param locale The string matching logic is case insensitive.
A {@link Locale} is necessary to normalize both Strings to lower case.
* @throws IllegalArgumentException
* This is thrown if the {@link Locale} parameter is {@code null}.
*/
public FuzzyScore(final Locale locale) {
if (locale == null) {
throw new IllegalArgumentException("Locale must not be null");
}
this.locale = locale;
}

/**
* Find the Fuzzy Score which indicates the similarity score between two
* Strings.
*
* <pre>
* score.fuzzyScore(null, null) = IllegalArgumentException
* score.fuzzyScore("not null", null) = IllegalArgumentException
* score.fuzzyScore(null, "not null") = IllegalArgumentException
* score.fuzzyScore("", "") = 0
* score.fuzzyScore("Workshop", "b") = 0
* score.fuzzyScore("Room", "o") = 1
* score.fuzzyScore("Workshop", "w") = 1
* score.fuzzyScore("Workshop", "ws") = 2
* score.fuzzyScore("Workshop", "wo") = 4
* score.fuzzyScore("Apache Software Foundation", "asf") = 3
* </pre>
*
* @param term a full term that should be matched against, must not be null
* @param query the query that will be matched against a term, must not be
* null
* @return result score
* @throws IllegalArgumentException if the term or query is {@code null}
*/
public Integer fuzzyScore(final CharSequence term, final CharSequence query) {
if (term == null || query == null) {
throw new IllegalArgumentException("CharSequences must not be null");
}

// fuzzy logic is case insensitive. We normalize the Strings to lower
// case right from the start. Turning characters to lower case
// via Character.toLowerCase(char) is unfortunately insufficient
// as it does not accept a locale.
final String termLowerCase = term.toString().toLowerCase(locale);
final String queryLowerCase = query.toString().toLowerCase(locale);

// the resulting score
int score = 0;

// the position in the term which will be scanned next for potential
// query character matches
int termIndex = 0;

// index of the previously matched character in the term
int previousMatchingCharacterIndex = Integer.MIN_VALUE;

for (int queryIndex = 0; queryIndex < queryLowerCase.length(); queryIndex++) {
final char queryChar = queryLowerCase.charAt(queryIndex);

boolean termCharacterMatchFound = false;
for (; termIndex < termLowerCase.length()
&& !termCharacterMatchFound; termIndex++) {
final char termChar = termLowerCase.charAt(termIndex);

if (queryChar == termChar) {
// simple character matches result in one point
score++;

// subsequent character matches further improve
// the score.
if (previousMatchingCharacterIndex + 1 == termIndex) {
score += 2;
}

previousMatchingCharacterIndex = termIndex;

// we can leave the nested loop. Every character in the
// query can match at most one character in the term.
termCharacterMatchFound = true;
}
}
}

return score;
}

/**
* Gets the locale.
*
* @return The locale
*/
public Locale getLocale() {
return locale;
}

}
6 changes: 5 additions & 1 deletion app/src/main/java/org/schabi/newpipe/about/AboutActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,11 @@ class AboutActivity : AppCompatActivity() {
SoftwareComponent(
"RxJava", "2016 - 2020", "RxJava Contributors",
"https://github.com/ReactiveX/RxJava", StandardLicenses.APACHE2
)
),
SoftwareComponent(
"SearchPreference", "2018", "ByteHamster",
"https://github.com/ByteHamster/SearchPreference", StandardLicenses.MIT
),
)
private const val POS_ABOUT = 0
private const val POS_LICENSE = 1
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@
import android.view.ViewGroup;
import android.view.animation.DecelerateInterpolator;
import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.InputMethodManager;
import android.widget.EditText;
import android.widget.TextView;

Expand All @@ -34,7 +33,6 @@
import androidx.appcompat.app.ActionBar;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.widget.TooltipCompat;
import androidx.core.content.ContextCompat;
import androidx.core.text.HtmlCompat;
import androidx.preference.PreferenceManager;
import androidx.recyclerview.widget.ItemTouchHelper;
Expand Down Expand Up @@ -65,6 +63,7 @@
import org.schabi.newpipe.util.Constants;
import org.schabi.newpipe.util.DeviceUtils;
import org.schabi.newpipe.util.ExtractorHelper;
import org.schabi.newpipe.util.KeyboardUtil;
import org.schabi.newpipe.util.NavigationHelper;
import org.schabi.newpipe.util.ServiceHelper;

Expand Down Expand Up @@ -670,31 +669,15 @@ private void showKeyboardSearch() {
if (DEBUG) {
Log.d(TAG, "showKeyboardSearch() called");
}
if (searchEditText == null) {
return;
}

if (searchEditText.requestFocus()) {
final InputMethodManager imm = ContextCompat.getSystemService(activity,
InputMethodManager.class);
imm.showSoftInput(searchEditText, InputMethodManager.SHOW_FORCED);
}
KeyboardUtil.showKeyboard(activity, searchEditText);
}

private void hideKeyboardSearch() {
if (DEBUG) {
Log.d(TAG, "hideKeyboardSearch() called");
}
if (searchEditText == null) {
return;
}

final InputMethodManager imm = ContextCompat.getSystemService(activity,
InputMethodManager.class);
imm.hideSoftInputFromWindow(searchEditText.getWindowToken(),
InputMethodManager.RESULT_UNCHANGED_SHOWN);

searchEditText.clearFocus();
KeyboardUtil.hideKeyboard(activity, searchEditText);
}

private void showDeleteSuggestionDialog(final SuggestionItem item) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

import android.content.ActivityNotFoundException;
import android.content.Intent;
import android.os.Build;
import android.os.Bundle;
import android.provider.Settings;
import android.widget.Toast;
Expand All @@ -15,14 +14,10 @@
import org.schabi.newpipe.util.ThemeHelper;

public class AppearanceSettingsFragment extends BasePreferenceFragment {
private static final boolean CAPTIONING_SETTINGS_ACCESSIBLE =
Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT;

private String captionSettingsKey;

@Override
public void onCreatePreferences(final Bundle savedInstanceState, final String rootKey) {
addPreferencesFromResource(R.xml.appearance_settings);
addPreferencesFromResourceRegistry();

final String themeKey = getString(R.string.theme_key);
// the key of the active theme when settings were opened (or recreated after theme change)
Expand Down Expand Up @@ -51,16 +46,11 @@ public void onCreatePreferences(final Bundle savedInstanceState, final String ro
} else {
removePreference(nightThemeKey);
}

captionSettingsKey = getString(R.string.caption_settings_key);
if (!CAPTIONING_SETTINGS_ACCESSIBLE) {
removePreference(captionSettingsKey);
litetex marked this conversation as resolved.
Show resolved Hide resolved
}
}

@Override
public boolean onPreferenceTreeClick(final Preference preference) {
if (preference.getKey().equals(captionSettingsKey) && CAPTIONING_SETTINGS_ACCESSIBLE) {
if (preference.getKey().equals(getString(R.string.caption_settings_key))) {
try {
startActivity(new Intent(Settings.ACTION_CAPTIONING_SETTINGS));
} catch (final ActivityNotFoundException e) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,11 @@ public void onCreate(@Nullable final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}

protected void addPreferencesFromResourceRegistry() {
addPreferencesFromResource(
SettingsResourceRegistry.getInstance().getPreferencesResId(this.getClass()));
}

@Override
public void onViewCreated(@NonNull final View rootView,
@Nullable final Bundle savedInstanceState) {
Expand Down
Loading